]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264_refs.c
eamad: release the reference frame on video size changes
[ffmpeg] / libavcodec / h264_refs.c
index 6794bf3c9f003916e8afacf7455bc67882fc692b..0e00c4f94b94c407183110bfc8f132145d19d93a 100644 (file)
@@ -301,7 +301,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
 
 void ff_h264_fill_mbaff_ref_list(H264Context *h){
     int list, i, j;
-    for(list=0; list<2; list++){ //FIXME try list_count
+    for(list=0; list<h->list_count; list++){
         for(i=0; i<h->ref_count[list]; i++){
             Picture *frame = &h->ref_list[list][i];
             Picture *field = &h->ref_list[list][16+2*i];
@@ -479,10 +479,9 @@ static void print_long_term(H264Context *h) {
 
 void ff_generate_sliding_window_mmcos(H264Context *h) {
     MpegEncContext * const s = &h->s;
-    av_assert0(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count);
 
     h->mmco_index= 0;
-    if(h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count &&
+    if(h->short_ref_count && h->long_ref_count + h->short_ref_count >= h->sps.ref_frame_count &&
             !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->f.reference)) {
         h->mmco[0].opcode= MMCO_SHORT2UNUSED;
         h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num;
@@ -499,7 +498,7 @@ void ff_generate_sliding_window_mmcos(H264Context *h) {
 int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
     MpegEncContext * const s = &h->s;
     int i, av_uninit(j);
-    int current_ref_assigned=0;
+    int current_ref_assigned=0, err=0;
     Picture *av_uninit(pic);
 
     if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0)
@@ -516,8 +515,10 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
             pic = find_short(h, frame_num, &j);
             if(!pic){
                 if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg]
-                   || h->long_ref[mmco[i].long_arg]->frame_num != frame_num)
-                av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
+                   || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) {
+                    av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
+                    err = AVERROR_INVALIDDATA;
+                }
                 continue;
             }
         }
@@ -609,10 +610,12 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
                                              "assignment for second field "
                                              "in complementary field pair "
                                              "(first field is long term)\n");
+            err = AVERROR_INVALIDDATA;
         } else {
             pic= remove_short(h, s->current_picture_ptr->frame_num, 0);
             if(pic){
                 av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");
+                err = AVERROR_INVALIDDATA;
             }
 
             if(h->short_ref_count)
@@ -634,6 +637,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
                "number of reference frames (%d+%d) exceeds max (%d; probably "
                "corrupt input), discarding one\n",
                h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count);
+        err = AVERROR_INVALIDDATA;
 
         if (h->long_ref_count && !h->short_ref_count) {
             for (i = 0; i < 16; ++i)
@@ -650,7 +654,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
 
     print_short_term(h);
     print_long_term(h);
-    return 0;
+    return h->s.avctx->error_recognition >= FF_ER_EXPLODE ? err : 0;
 }
 
 int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){