[FFmpeg-devel] [PATCH] Implement PAFF in H.264

Jeff Downs heydowns
Tue Sep 25 21:51:11 CEST 2007


On Mon, 24 Sep 2007, Jeff Downs wrote:

> On Mon, 24 Sep 2007, Michael Niedermayer wrote:
> > 
> > IMHO the AVFrame.reference code should be fixed first unless this turns
> > out to be very complex to fix
> >
> 
> OK.  I took a second look at how Picture.reference is used in mpegvideo.c 
> and h264.c.  For current SVN (no PAFF), its not too difficult to fix 
> (replace use of reference = 1 with 4 as suggested).
> 
> 
> When PAFF is considered, two problems present:
> 
> First, a place to store a second field's "is a reference" flag is needed, 
> separate from the reference marking of the first field in a pair.
> 
> Would using s->dropable for this be an acceptable solution? Or should 
> I continue with current_picture.reference?
> 
> This way:
> 
> s->dropable == current field or frame needs reference marking when 
> complete.
> 
> current_picture.(_ptr->)reference == PICT_XXX, or 4, as dictated by 
> and set in reference picture marking process and delayed picture holding.
> 
> 
> Second, MPV_frame_start forces a value of 3 onto reference for ref frames. 
> This could be solved by replacing "3" with s->picture_structure. But that 
> doesn't really make complete sense for mpeg2.
> 
> Another option is to let MPV_frame_start still set 3, but override in 
> h264 with picture_structure.
> 
> Another option still is to override with zero, and then let the frame end 
> processing (ref marking and pic output) take total control of the 
> reference variable handling. This is good because it isolates reference 
> handling to one area.
> 

Attached is a patch that cleans up handling of Picture.reference in h264 
using some of the above-described approach.

I decided to change MPV_frame_start to use s->picture_structure for 
reference in h264 case because it was already testing for h264 there 
anyway. This prepares for PAFF implementation.

This also makes current_picture.reference necessarily == 
current_picture_ptr->reference and updates any tests of either to have 
field references in mind.

If ok, I will update PAFF implementation based on this.

	-Jeff
-------------- next part --------------
Index: libavcodec/h264.c
===================================================================
--- libavcodec/h264.c	(revision 10573)
+++ libavcodec/h264.c	(working copy)
@@ -38,6 +38,12 @@
 //#undef NDEBUG
 #include <assert.h>
 
+/*
+ * Value of Picture.reference when Picture is not a reference picture, but
+ * is held for delayed output.
+ */
+#define DELAYED_PIC_REF 4
+
 static VLC coeff_token_vlc[4];
 static VLC chroma_dc_coeff_token_vlc;
 
@@ -3091,11 +3097,11 @@
     int i;
     pic->reference=0;
     if(pic == h->delayed_output_pic)
-        pic->reference=1;
+        pic->reference=DELAYED_PIC_REF;
     else{
         for(i = 0; h->delayed_pic[i]; i++)
             if(pic == h->delayed_pic[i]){
-                pic->reference=1;
+                pic->reference=DELAYED_PIC_REF;
                 break;
             }
     }
@@ -3542,7 +3548,6 @@
     unsigned int slice_type, tmp, i;
     int default_ref_list_done = 0;
 
-    s->current_picture.reference= h->nal_ref_idc != 0;
     s->dropable= h->nal_ref_idc == 0;
 
     first_mb_in_slice= get_ue_golomb(&s->gb);
@@ -3652,14 +3657,6 @@
         }
     }
 
-    if(h0->current_slice == 0){
-        if(frame_start(h) < 0)
-            return -1;
-    }
-    if(h != h0)
-        clone_slice(h, h0);
-
-    s->current_picture_ptr->frame_num= //FIXME frame_num cleanup
     h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num);
 
     h->mb_mbaff = 0;
@@ -3675,6 +3672,16 @@
             h->mb_aff_frame = h->sps.mb_aff;
         }
     }
+
+    if(h0->current_slice == 0){
+        if(frame_start(h) < 0)
+            return -1;
+    }
+    if(h != h0)
+        clone_slice(h, h0);
+
+    s->current_picture_ptr->frame_num= h->frame_num; //FIXME frame_num cleanup
+
     assert(s->mb_num == s->mb_width * s->mb_height);
     if(first_mb_in_slice << h->mb_aff_frame >= s->mb_num ||
        first_mb_in_slice                    >= s->mb_num){
@@ -3763,7 +3770,7 @@
     else
         h->use_weight = 0;
 
-    if(s->current_picture.reference)
+    if(h->nal_ref_idc)
         decode_ref_pic_marking(h0, &s->gb);
 
     if(FRAME_MBAFF)
@@ -3863,7 +3870,7 @@
                );
     }
 
-    if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !s->current_picture.reference){
+    if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !h->nal_ref_idc){
         s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab;
         s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab;
     }else{
@@ -7361,12 +7368,11 @@
 
         h->prev_frame_num_offset= h->frame_num_offset;
         h->prev_frame_num= h->frame_num;
-        if(s->current_picture_ptr->reference){
+        if(s->current_picture_ptr->reference & s->picture_structure){
             h->prev_poc_msb= h->poc_msb;
             h->prev_poc_lsb= h->poc_lsb;
+            execute_ref_pic_marking(h, h->mmco, h->mmco_index);
         }
-        if(s->current_picture_ptr->reference)
-            execute_ref_pic_marking(h, h->mmco, h->mmco_index);
 
         ff_er_frame_end(s);
 
@@ -7392,7 +7398,7 @@
 
         h->delayed_pic[pics++] = cur;
         if(cur->reference == 0)
-            cur->reference = 1;
+            cur->reference = DELAYED_PIC_REF;
 
         cross_idr = 0;
         for(i=0; h->delayed_pic[i]; i++)
@@ -7433,7 +7439,7 @@
             *data_size = 0;
         else
             *data_size = sizeof(AVFrame);
-        if(prev && prev != out && prev->reference == 1)
+        if(prev && prev != out && prev->reference == DELAYED_PIC_REF)
             prev->reference = 0;
         h->delayed_output_pic = out;
 #endif
Index: libavcodec/mpegvideo.c
===================================================================
--- libavcodec/mpegvideo.c	(revision 10573)
+++ libavcodec/mpegvideo.c	(working copy)
@@ -907,8 +907,13 @@
             pic= (AVFrame*)&s->picture[i];
         }
 
-        pic->reference= (s->pict_type != B_TYPE || s->codec_id == CODEC_ID_H264)
-                        && !s->dropable ? 3 : 0;
+        pic->reference= 0;
+        if (!s->dropable){
+            if (s->codec_id == CODEC_ID_H264)
+                pic->reference = s->picture_structure;
+            else if (s->pict_type != B_TYPE)
+                pic->reference = 3;
+        }
 
         pic->coded_picture_number= s->coded_picture_number++;
 



More information about the ffmpeg-devel mailing list