[FFmpeg-devel] [PATCH 2/4] avcodec/diracdec: do not use AVFrame.display_picture_number for decoding

Marton Balint cus at passwd.hu
Sat Jan 28 20:15:21 EET 2023


Signed-off-by: Marton Balint <cus at passwd.hu>
---
 libavcodec/diracdec.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index a5cad29597..22a2925188 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -77,6 +77,7 @@ typedef struct {
     uint8_t *hpel[3][4];
     uint8_t *hpel_base[3][4];
     int reference;
+    unsigned picture_number;
 } DiracFrame;
 
 typedef struct {
@@ -252,13 +253,13 @@ static inline int divide3(int x)
     return (int)((x+1U)*21845 + 10922) >> 16;
 }
 
-static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum)
+static DiracFrame *remove_frame(DiracFrame *framelist[], unsigned picnum)
 {
     DiracFrame *remove_pic = NULL;
     int i, remove_idx = -1;
 
     for (i = 0; framelist[i]; i++)
-        if (framelist[i]->avframe->display_picture_number == picnum) {
+        if (framelist[i]->picture_number == picnum) {
             remove_pic = framelist[i];
             remove_idx = i;
         }
@@ -2002,7 +2003,7 @@ static int dirac_decode_picture_header(DiracContext *s)
     GetBitContext *gb = &s->gb;
 
     /* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */
-    picnum = s->current_picture->avframe->display_picture_number = get_bits_long(gb, 32);
+    picnum = s->current_picture->picture_number = get_bits_long(gb, 32);
 
 
     av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum);
@@ -2021,9 +2022,9 @@ static int dirac_decode_picture_header(DiracContext *s)
         /* Jordi: this is needed if the referenced picture hasn't yet arrived */
         for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++)
             if (s->ref_frames[j]
-                && FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum) < refdist) {
+                && FFABS(s->ref_frames[j]->picture_number - refnum) < refdist) {
                 s->ref_pics[i] = s->ref_frames[j];
-                refdist = FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum);
+                refdist = FFABS(s->ref_frames[j]->picture_number - refnum);
             }
 
         if (!s->ref_pics[i] || refdist)
@@ -2062,7 +2063,7 @@ static int dirac_decode_picture_header(DiracContext *s)
         /* if reference array is full, remove the oldest as per the spec */
         while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) {
             av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n");
-            remove_frame(s->ref_frames, s->ref_frames[0]->avframe->display_picture_number)->reference &= DELAYED_PIC_REF;
+            remove_frame(s->ref_frames, s->ref_frames[0]->picture_number)->reference &= DELAYED_PIC_REF;
         }
     }
 
@@ -2090,7 +2091,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
 
     /* find frame with lowest picture number */
     for (i = 1; s->delay_frames[i]; i++)
-        if (s->delay_frames[i]->avframe->display_picture_number < out->avframe->display_picture_number) {
+        if (s->delay_frames[i]->picture_number < out->picture_number) {
             out     = s->delay_frames[i];
             out_idx = i;
         }
@@ -2102,6 +2103,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
         out->reference ^= DELAYED_PIC_REF;
         if((ret = av_frame_ref(picture, out->avframe)) < 0)
             return ret;
+        picture->display_picture_number = out->picture_number;
         *got_frame = 1;
     }
 
@@ -2318,19 +2320,19 @@ static int dirac_decode_frame(AVCodecContext *avctx, AVFrame *picture,
     if (!s->current_picture)
         return buf_size;
 
-    if (s->current_picture->avframe->display_picture_number > s->frame_number) {
+    if (s->current_picture->picture_number > s->frame_number) {
         DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);
 
         s->current_picture->reference |= DELAYED_PIC_REF;
 
         if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {
-            int min_num = s->delay_frames[0]->avframe->display_picture_number;
+            unsigned min_num = s->delay_frames[0]->picture_number;
             /* Too many delayed frames, so we display the frame with the lowest pts */
             av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");
 
             for (i = 1; s->delay_frames[i]; i++)
-                if (s->delay_frames[i]->avframe->display_picture_number < min_num)
-                    min_num = s->delay_frames[i]->avframe->display_picture_number;
+                if (s->delay_frames[i]->picture_number < min_num)
+                    min_num = s->delay_frames[i]->picture_number;
 
             delayed_frame = remove_frame(s->delay_frames, min_num);
             add_frame(s->delay_frames, MAX_DELAY, s->current_picture);
@@ -2340,18 +2342,19 @@ static int dirac_decode_frame(AVCodecContext *avctx, AVFrame *picture,
             delayed_frame->reference ^= DELAYED_PIC_REF;
             if((ret = av_frame_ref(picture, delayed_frame->avframe)) < 0)
                 return ret;
+            s->frame_number = delayed_frame->picture_number + 1LL;
+            picture->display_picture_number = delayed_frame->picture_number;
             *got_frame = 1;
         }
-    } else if (s->current_picture->avframe->display_picture_number == s->frame_number) {
+    } else if (s->current_picture->picture_number == s->frame_number) {
         /* The right frame at the right time :-) */
         if((ret = av_frame_ref(picture, s->current_picture->avframe)) < 0)
             return ret;
+        s->frame_number = s->current_picture->picture_number + 1LL;
+        picture->display_picture_number = s->current_picture->picture_number;
         *got_frame = 1;
     }
 
-    if (*got_frame)
-        s->frame_number = picture->display_picture_number + 1LL;
-
     return buf_idx;
 }
 
-- 
2.35.3



More information about the ffmpeg-devel mailing list