Browse code

avcodec/h264_slice: Check picture structure before setting the related fields

This might fix a hypothetical race condition

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit f111831ed61103f9fa8fdda41473a23da016bdaa)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Conflicts:

libavcodec/h264_slice.c

Conflicts:

libavcodec/h264.c

Michael Niedermayer authored on 2015/02/07 10:22:44
Showing 1 changed files
... ...
@@ -3148,7 +3148,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
3148 3148
     int must_reinit;
3149 3149
     int needs_reinit = 0;
3150 3150
     int first_slice = h == h0 && !h0->current_slice;
3151
-    int frame_num;
3151
+    int frame_num, picture_structure, droppable;
3152 3152
     PPS *pps;
3153 3153
 
3154 3154
     h->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;
... ...
@@ -3342,37 +3342,32 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
3342 3342
             return AVERROR_INVALIDDATA;
3343 3343
         }
3344 3344
     }
3345
-    h->frame_num = frame_num;
3346 3345
 
3347 3346
     h->mb_mbaff        = 0;
3348 3347
     h->mb_aff_frame    = 0;
3349 3348
     last_pic_structure = h0->picture_structure;
3350 3349
     last_pic_droppable = h0->droppable;
3351
-    h->droppable       = h->nal_ref_idc == 0;
3350
+    droppable          = h->nal_ref_idc == 0;
3352 3351
     if (h->sps.frame_mbs_only_flag) {
3353
-        h->picture_structure = PICT_FRAME;
3352
+        picture_structure = PICT_FRAME;
3354 3353
     } else {
3355 3354
         if (!h->sps.direct_8x8_inference_flag && slice_type == AV_PICTURE_TYPE_B) {
3356 3355
             av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");
3357 3356
             return -1;
3358 3357
         }
3359 3358
         if (get_bits1(&h->gb)) { // field_pic_flag
3360
-            h->picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag
3359
+            picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag
3361 3360
         } else {
3362
-            h->picture_structure = PICT_FRAME;
3361
+            picture_structure = PICT_FRAME;
3363 3362
             h->mb_aff_frame      = h->sps.mb_aff;
3364 3363
         }
3365 3364
     }
3366
-    h->mb_field_decoding_flag = h->picture_structure != PICT_FRAME;
3367
-
3368
-    if (h0->current_slice != 0) {
3369
-        if (last_pic_structure != h->picture_structure ||
3370
-            last_pic_droppable != h->droppable) {
3365
+    if (h0->current_slice) {
3366
+        if (last_pic_structure != picture_structure ||
3367
+            last_pic_droppable != droppable) {
3371 3368
             av_log(h->avctx, AV_LOG_ERROR,
3372 3369
                    "Changing field mode (%d -> %d) between slices is not allowed\n",
3373 3370
                    last_pic_structure, h->picture_structure);
3374
-            h->picture_structure = last_pic_structure;
3375
-            h->droppable         = last_pic_droppable;
3376 3371
             return AVERROR_INVALIDDATA;
3377 3372
         } else if (!h0->cur_pic_ptr) {
3378 3373
             av_log(h->avctx, AV_LOG_ERROR,
... ...
@@ -3380,7 +3375,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
3380 3380
                    h0->current_slice + 1);
3381 3381
             return AVERROR_INVALIDDATA;
3382 3382
         }
3383
-    } else {
3383
+    }
3384
+
3385
+    h->picture_structure = picture_structure;
3386
+    h->droppable         = droppable;
3387
+    h->frame_num         = frame_num;
3388
+    h->mb_field_decoding_flag = picture_structure != PICT_FRAME;
3389
+
3390
+    if (h0->current_slice == 0) {
3384 3391
         /* Shorten frame num gaps so we don't have to allocate reference
3385 3392
          * frames just to throw them away */
3386 3393
         if (h->frame_num != h->prev_frame_num) {