]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/hevc_refs.c
avcodec/avcodec: Free frame_thread_encoder on avcodec_open2() error
[ffmpeg] / libavcodec / hevc_refs.c
index 7cf3a5572579056eb40738841f4fab7bf202ba83..4f6d985ae604fc46b000bc72bbc82630c449c00b 100644 (file)
@@ -358,23 +358,15 @@ int ff_hevc_slice_rpl(HEVCContext *s)
     return 0;
 }
 
-static HEVCFrame *find_ref_idx(HEVCContext *s, int poc)
+static HEVCFrame *find_ref_idx(HEVCContext *s, int poc, uint8_t use_msb)
 {
+    int mask = use_msb ? ~0 : (1 << s->ps.sps->log2_max_poc_lsb) - 1;
     int i;
-    int LtMask = (1 << s->ps.sps->log2_max_poc_lsb) - 1;
-
-    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
-        HEVCFrame *ref = &s->DPB[i];
-        if (ref->frame->buf[0] && (ref->sequence == s->seq_decode)) {
-            if ((ref->poc & LtMask) == poc)
-                return ref;
-        }
-    }
 
     for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
         HEVCFrame *ref = &s->DPB[i];
         if (ref->frame->buf[0] && ref->sequence == s->seq_decode) {
-            if (ref->poc == poc || (ref->poc & LtMask) == poc)
+            if ((ref->poc & mask) == poc)
                 return ref;
         }
     }
@@ -394,7 +386,7 @@ static void mark_ref(HEVCFrame *frame, int flag)
 static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
 {
     HEVCFrame *frame;
-    int i, x, y;
+    int i, y;
 
     frame = alloc_frame(s);
     if (!frame)
@@ -407,11 +399,11 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
                        frame->frame->buf[i]->size);
         } else {
             for (i = 0; frame->frame->data[i]; i++)
-                for (y = 0; y < (s->ps.sps->height >> s->ps.sps->vshift[i]); y++)
-                    for (x = 0; x < (s->ps.sps->width >> s->ps.sps->hshift[i]); x++) {
-                        AV_WN16(frame->frame->data[i] + y * frame->frame->linesize[i] + 2 * x,
-                                1 << (s->ps.sps->bit_depth - 1));
-                    }
+                for (y = 0; y < (s->ps.sps->height >> s->ps.sps->vshift[i]); y++) {
+                    uint8_t *dst = frame->frame->data[i] + y * frame->frame->linesize[i];
+                    AV_WN16(dst, 1 << (s->ps.sps->bit_depth - 1));
+                    av_memcpy_backptr(dst + 2, 2, 2*(s->ps.sps->width >> s->ps.sps->hshift[i]) - 2);
+                }
         }
     }
 
@@ -427,9 +419,9 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
 
 /* add a reference with the given poc to the list and mark it as used in DPB */
 static int add_candidate_ref(HEVCContext *s, RefPicList *list,
-                             int poc, int ref_flag)
+                             int poc, int ref_flag, uint8_t use_msb)
 {
-    HEVCFrame *ref = find_ref_idx(s, poc);
+    HEVCFrame *ref = find_ref_idx(s, poc, use_msb);
 
     if (ref == s->ref || list->nb_refs >= HEVC_MAX_REFS)
         return AVERROR_INVALIDDATA;
@@ -485,7 +477,7 @@ int ff_hevc_frame_rps(HEVCContext *s)
         else
             list = ST_CURR_AFT;
 
-        ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF);
+        ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF, 1);
         if (ret < 0)
             goto fail;
     }
@@ -495,7 +487,7 @@ int ff_hevc_frame_rps(HEVCContext *s)
         int poc  = long_rps->poc[i];
         int list = long_rps->used[i] ? LT_CURR : LT_FOLL;
 
-        ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF);
+        ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF, long_rps->poc_msb_present[i]);
         if (ret < 0)
             goto fail;
     }