On 2016-12-18 11:36:30 +0100, Anton Khirnov wrote:
> Calling ff_h264_field_end() when the per-field state is not properly
> initialized leads to all kinds of undefined behaviour.
> 
> CC: libav-sta...@libav.org
> Bug-Id: 977 978 992
> ---
>  libavcodec/h264_picture.c | 1 +
>  libavcodec/h264_slice.c   | 4 ++--
>  libavcodec/h264dec.c      | 3 ++-
>  libavcodec/h264dec.h      | 5 +++++
>  4 files changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c
> index e22852a..24ba79d 100644
> --- a/libavcodec/h264_picture.c
> +++ b/libavcodec/h264_picture.c
> @@ -194,6 +194,7 @@ int ff_h264_field_end(H264Context *h, H264SliceContext 
> *sl, int in_setup)
>      emms_c();
>  
>      h->current_slice = 0;
> +    h->field_started = 0;
>  
>      return err;
>  }
> diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
> index 1b91088..db7628c 100644
> --- a/libavcodec/h264_slice.c
> +++ b/libavcodec/h264_slice.c
> @@ -1884,9 +1884,8 @@ int ff_h264_queue_decode_slice(H264Context *h, const 
> H2645NAL *nal)
>                  sl = h->slice_ctx;
>              }
>  
> -            if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {
> +            if (h->field_started)
>                  ff_h264_field_end(h, sl, 1);
> -            }
>  
>              h->current_slice = 0;
>              if (!h->first_field) {
> @@ -1902,6 +1901,7 @@ int ff_h264_queue_decode_slice(H264Context *h, const 
> H2645NAL *nal)
>              ret = h264_field_start(h, sl, nal);
>              if (ret < 0)
>                  return ret;
> +            h->field_started = 1;
>          }
>      }
>  
> diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
> index 330a74d..62bb036 100644
> --- a/libavcodec/h264dec.c
> +++ b/libavcodec/h264dec.c
> @@ -757,7 +757,8 @@ out:
>  
>      if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS) ||
>          (h->mb_y >= h->mb_height && h->mb_height)) {
> -        ff_h264_field_end(h, &h->slice_ctx[0], 0);
> +        if (h->field_started)
> +            ff_h264_field_end(h, &h->slice_ctx[0], 0);
>  
>          *got_frame = 0;
>          if (h->output_frame->buf[0]) {
> diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h
> index f934fc4..2ffe4de 100644
> --- a/libavcodec/h264dec.h
> +++ b/libavcodec/h264dec.h
> @@ -509,6 +509,11 @@ typedef struct H264Context {
>       * slices) anymore */
>      int setup_finished;
>  
> +    /* This is set to 1 if h264_field_start() has been called successfully,
> +     * so all per-field state is properly initialized and we can decode
> +     * the slice data */
> +    int field_started;
> +
>      AVFrame *output_frame;
>  
>      int enable_er;

looks ok

Janne
_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to