58#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58, 78, 100)
59 const int n = avformat_index_get_entries_count(&st);
60 if(st.nb_frames <= 0 || n < st.nb_frames)
64 int gap = 0, maxGap = 0;
65 for(
int i = 0; i < n; i++)
67 const AVIndexEntry* e = avformat_index_get_entry(
const_cast<AVStream*
>(&st), i);
68 if(e && (e->flags & AVINDEX_KEYFRAME))
71 maxGap = std::max(maxGap, gap);
81 return {FrameAccess::LongGop, n};
82 maxGap = std::max(maxGap, gap);
83 return {fromGap(maxGap), maxGap};
94 AVFormatContext* fmt{};
95 if(!url || avformat_open_input(&fmt, url,
nullptr,
nullptr) != 0)
97 AVPacket* pkt = av_packet_alloc();
100 avformat_close_input(&fmt);
107 for(
unsigned i = 0; i < fmt->nb_streams && video < 0; i++)
108 if(fmt->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
115 int seen = 0, keys = 0, gap = 0, maxGap = 0;
117 while(seen < max_packets && av_read_frame(fmt, pkt) >= 0)
119 if(video < 0 && pkt->stream_index <
int(fmt->nb_streams)
120 && fmt->streams[pkt->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
121 video = pkt->stream_index;
123 if(pkt->stream_index == video)
126 timed |= pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE;
127 if(pkt->flags & AV_PKT_FLAG_KEY)
130 maxGap = std::max(maxGap, gap);
139 av_packet_unref(pkt);
146 av_packet_free(&pkt);
147 avformat_close_input(&fmt);
152 maxGap = std::max(maxGap, gap);
155 return {FrameAccess::Sequential, maxGap};
157 return {FrameAccess::LongGop, maxGap};
158 return {fromGap(maxGap), maxGap};
169 using namespace keyframe_probe;
171 return {FrameAccess::Sequential, -1};
175 if(fmt.iformat && (fmt.iformat->flags & AVFMT_NOTIMESTAMPS))
176 return {FrameAccess::Sequential, -1};
178 if(
auto desc = avcodec_descriptor_get(st.codecpar->codec_id);
179 desc && (desc->props & AV_CODEC_PROP_INTRA_ONLY))
180 return {FrameAccess::EveryFrame, 0};
182 if(
auto p = fromIndex(st); p.access != FrameAccess::Unknown)
185 return fromPackets(url);
FrameAccessProbe classifyFrameAccess(AVFormatContext &fmt, AVStream &st, const char *url) noexcept
Definition FrameAccess.hpp:167
FrameAccessProbe fromIndex(const AVStream &st) noexcept
Longest non-keyframe run from an index that lists every frame.
Definition FrameAccess.hpp:56