changeset 5768:09b557fcfafb libavcodec

Modify unreference_pic implementation with PAFF in mind. patch by Jeff Downs, heydowns a borg d com original thread: Subject: [FFmpeg-devel] [PATCH] Implement PAFF in H.264 Date: 18/09/07 20:30
author andoma
date Thu, 04 Oct 2007 06:35:46 +0000
parents 32b404ec4c19
children 59049863494c
files h264.c
diffstat 1 files changed, 27 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/h264.c	Thu Oct 04 06:33:26 2007 +0000
+++ b/h264.c	Thu Oct 04 06:35:46 2007 +0000
@@ -3093,9 +3093,22 @@
     }
 }
 
-static inline void unreference_pic(H264Context *h, Picture *pic){
+/**
+ * Mark a picture as no longer needed for reference. The refmask
+ * argument allows unreferencing of individual fields or the whole frame.
+ * If the picture becomes entirely unreferenced, but is being held for
+ * display purposes, it is marked as such.
+ * @param refmask mask of fields to unreference; the mask is bitwise
+ *                anded with the reference marking of pic
+ * @return non-zero if pic becomes entirely unreferenced (except possibly
+ *         for display purposes) zero if one of the fields remains in
+ *         reference
+ */
+static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){
     int i;
-    pic->reference=0;
+    if (pic->reference &= refmask) {
+        return 0;
+    } else {
     if(pic == h->delayed_output_pic)
         pic->reference=DELAYED_PIC_REF;
     else{
@@ -3105,6 +3118,8 @@
                 break;
             }
     }
+        return 1;
+    }
 }
 
 /**
@@ -3115,14 +3130,14 @@
 
     for(i=0; i<16; i++){
         if (h->long_ref[i] != NULL) {
-            unreference_pic(h, h->long_ref[i]);
+            unreference_pic(h, h->long_ref[i], 0);
             h->long_ref[i]= NULL;
         }
     }
     h->long_ref_count=0;
 
     for(i=0; i<h->short_ref_count; i++){
-        unreference_pic(h, h->short_ref[i]);
+        unreference_pic(h, h->short_ref[i], 0);
         h->short_ref[i]= NULL;
     }
     h->short_ref_count=0;
@@ -3234,13 +3249,13 @@
         case MMCO_SHORT2UNUSED:
             pic= remove_short(h, mmco[i].short_pic_num);
             if(pic)
-                unreference_pic(h, pic);
+                unreference_pic(h, pic, 0);
             else if(s->avctx->debug&FF_DEBUG_MMCO)
                 av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_short() failure\n");
             break;
         case MMCO_SHORT2LONG:
             pic= remove_long(h, mmco[i].long_arg);
-            if(pic) unreference_pic(h, pic);
+            if(pic) unreference_pic(h, pic, 0);
 
             h->long_ref[ mmco[i].long_arg ]= remove_short(h, mmco[i].short_pic_num);
             if (h->long_ref[ mmco[i].long_arg ]){
@@ -3251,13 +3266,13 @@
         case MMCO_LONG2UNUSED:
             pic= remove_long(h, mmco[i].long_arg);
             if(pic)
-                unreference_pic(h, pic);
+                unreference_pic(h, pic, 0);
             else if(s->avctx->debug&FF_DEBUG_MMCO)
                 av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_long() failure\n");
             break;
         case MMCO_LONG:
             pic= remove_long(h, mmco[i].long_arg);
-            if(pic) unreference_pic(h, pic);
+            if(pic) unreference_pic(h, pic, 0);
 
             h->long_ref[ mmco[i].long_arg ]= s->current_picture_ptr;
             h->long_ref[ mmco[i].long_arg ]->long_ref=1;
@@ -3270,17 +3285,17 @@
             // just remove the long term which index is greater than new max
             for(j = mmco[i].long_arg; j<16; j++){
                 pic = remove_long(h, j);
-                if (pic) unreference_pic(h, pic);
+                if (pic) unreference_pic(h, pic, 0);
             }
             break;
         case MMCO_RESET:
             while(h->short_ref_count){
                 pic= remove_short(h, h->short_ref[0]->frame_num);
-                if(pic) unreference_pic(h, pic);
+                if(pic) unreference_pic(h, pic, 0);
             }
             for(j = 0; j < 16; j++) {
                 pic= remove_long(h, j);
-                if(pic) unreference_pic(h, pic);
+                if(pic) unreference_pic(h, pic, 0);
             }
             break;
         default: assert(0);
@@ -3290,7 +3305,7 @@
     if(!current_is_long){
         pic= remove_short(h, s->current_picture_ptr->frame_num);
         if(pic){
-            unreference_pic(h, pic);
+            unreference_pic(h, pic, 0);
             av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");
         }