[FFmpeg-soc] [soc]: r649 - dirac/libavcodec/dirac.c

marco subversion at mplayerhq.hu
Thu Aug 9 15:55:51 CEST 2007


Author: marco
Date: Thu Aug  9 15:55:51 2007
New Revision: 649

Log:
reorder frames so they will be displayed in the right order

Modified:
   dirac/libavcodec/dirac.c

Modified: dirac/libavcodec/dirac.c
==============================================================================
--- dirac/libavcodec/dirac.c	(original)
+++ dirac/libavcodec/dirac.c	Thu Aug  9 15:55:51 2007
@@ -2465,7 +2465,8 @@ static int decode_frame(AVCodecContext *
 
     s->picture.display_picture_number = s->picnum;
 
-    if (s->picture.reference) {
+    if (s->picture.reference
+        || s->picture.display_picture_number != avctx->frame_number) {
         if (s->refcnt + 1 == REFFRAME_CNT) {
             av_log(avctx, AV_LOG_ERROR, "reference picture buffer overrun\n");
             return -1;
@@ -2474,6 +2475,17 @@ static int decode_frame(AVCodecContext *
         s->refframes[s->refcnt++] = s->picture;
     }
 
+    /* Retire frames that were reordered and displayed if they are no
+       reference frames either.  */
+    for (i = 0; i < s->refcnt; i++) {
+        AVFrame *f = &s->refframes[i];
+
+        if (f->reference == 0
+            && f->display_picture_number < avctx->frame_number) {
+            s->retireframe[s->retirecnt++] = f->display_picture_number;
+        }
+    }
+
     for (i = 0; i < s->retirecnt; i++) {
         AVFrame *f;
         int idx, j;
@@ -2486,6 +2498,12 @@ static int decode_frame(AVCodecContext *
         }
 
         f = &s->refframes[idx];
+        /* Do not retire frames that were not displayed yet.  */
+        if (f->display_picture_number >= avctx->frame_number) {
+            f->reference = 0;
+            continue;
+        }
+
         if (f->data[0] != NULL)
             avctx->release_buffer(avctx, f);
         s->refcnt--;
@@ -2495,10 +2513,30 @@ static int decode_frame(AVCodecContext *
         }
     }
 
-    *data_size = sizeof(AVFrame);
-    *picture = s->picture;
+    if (s->picture.display_picture_number > avctx->frame_number) {
+        int idx;
 
-    if (s->picture.reference)
+        if (!s->picture.reference) {
+            /* This picture needs to be shown at a later time.  */
+            s->refframes[s->refcnt++] = s->picture;
+        }
+
+        idx = reference_frame_idx(avctx, avctx->frame_number);
+        if (idx == -1) {
+            /* The frame is not yet decoded.  */
+            *data_size = 0;
+        } else {
+            *data_size = sizeof(AVFrame);
+            *picture = s->refframes[idx];
+        }
+    } else {
+        /* The right frame at the right time :-) */
+        *data_size = sizeof(AVFrame);
+        *picture = s->picture;
+    }
+
+    if (s->picture.reference
+        || s->picture.display_picture_number < avctx->frame_number)
         avcodec_get_frame_defaults(&s->picture);
 
     return buf_size;



More information about the FFmpeg-soc mailing list