[FFmpeg-devel] Key Frame Marking

Jeff Downs heydowns
Fri Oct 12 05:35:57 CEST 2007

compute_pkt_fields in libavformat/utils.c sets an outgoing AVPacket's 
flags to contain the key frame flag if either the stream codec is intra 
only (~line 650) or if the stream's parser indicates that the current 
picture type is FF_I_TYPE (~line 729).

Problem is if a codec is both intra only and uses a parser that doesn't 
set ParserContext.pict_type. Because a parser is in use, the packet flags 
are cleared at the end of compute_pkt_fields. Keyframe flag is not 
restored because pict_type is always 0.

Case in point here is mjpeg.  Packets from mjpeg streams (in my case, 
inside AVI) never get the keyframe flag set due to this. There may be 
other codecs like this; I didn't check.

The attached patch moves the setting of key frame flag based on intra-only 
codec to the end of compute_pkt_fields and gives it priority over looking 
at the parser since any outgoing frame for intra only codec should have 
keyframe set.

-------------- next part --------------
Index: libavformat/utils.c
--- libavformat/utils.c	(revision 10712)
+++ libavformat/utils.c	(working copy)
@@ -647,9 +647,6 @@
             pkt->dts += offset;
-    if(is_intra_only(st->codec))
-        pkt->flags |= PKT_FLAG_KEY;
     /* do we have a video B frame ? */
     delay= st->codec->has_b_frames;
     presentation_delayed = 0;
@@ -726,7 +723,9 @@
 //    av_log(NULL, AV_LOG_ERROR, "OUTdelayed:%d/%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64"\n", presentation_delayed, delay, pkt->pts, pkt->dts, st->cur_dts);
     /* update flags */
-    if (pc) {
+    if(is_intra_only(st->codec))
+        pkt->flags |= PKT_FLAG_KEY;
+    else if (pc) {
         pkt->flags = 0;
         /* key frame computation */
             if (pc->pict_type == FF_I_TYPE)

More information about the ffmpeg-devel mailing list