Merge commit 'a8cbe5a0ccebf60a8a8b0aba5d5716dd54c1595c'
authorHendrik Leppkes <h.leppkes@gmail.com>
Thu, 17 Nov 2016 14:17:21 +0000 (15:17 +0100)
committerHendrik Leppkes <h.leppkes@gmail.com>
Thu, 17 Nov 2016 14:17:21 +0000 (15:17 +0100)
* commit 'a8cbe5a0ccebf60a8a8b0aba5d5716dd54c1595c':
  h264_ps: export actual height in MBs as SPS.mb_height

Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
1  2 
libavcodec/h264_ps.c
libavcodec/h264_ps.h
libavcodec/h264_slice.c

@@@ -467,15 -441,17 +467,22 @@@ int ff_h264_decode_seq_parameter_set(Ge
      sps->mb_height                      = get_ue_golomb(gb) + 1;
  
      sps->frame_mbs_only_flag = get_bits1(gb);
+     if (sps->mb_height >= INT_MAX / 2) {
+         av_log(avctx, AV_LOG_ERROR, "height overflow\n");
+         goto fail;
+     }
+     sps->mb_height *= 2 - sps->frame_mbs_only_flag;
 +    if (!sps->frame_mbs_only_flag)
 +        sps->mb_aff = get_bits1(gb);
 +    else
 +        sps->mb_aff = 0;
 +
      if ((unsigned)sps->mb_width  >= INT_MAX / 16 ||
-         (unsigned)sps->mb_height >= INT_MAX / (16 * (2 - sps->frame_mbs_only_flag)) ||
+         (unsigned)sps->mb_height >= INT_MAX / 16 ||
          av_image_check_size(16 * sps->mb_width,
-                             16 * sps->mb_height * (2 - sps->frame_mbs_only_flag), 0, avctx)) {
+                             16 * sps->mb_height, 0, avctx)) {
          av_log(avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
          goto fail;
      }
          unsigned int crop_right  = get_ue_golomb(gb);
          unsigned int crop_top    = get_ue_golomb(gb);
          unsigned int crop_bottom = get_ue_golomb(gb);
-         int height = 16 * sps->mb_height * (2 - sps->frame_mbs_only_flag);
 +        int width  = 16 * sps->mb_width;
++        int height = 16 * sps->mb_height;
  
          if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
              av_log(avctx, AV_LOG_DEBUG, "discarding sps cropping, original "
Simple merge
@@@ -992,51 -904,16 +992,51 @@@ static int h264_slice_header_init(H264C
      h->context_initialized = 1;
  
      return 0;
 +fail:
 +    ff_h264_free_tables(h);
 +    h->context_initialized = 0;
 +    return ret;
 +}
 +
 +static enum AVPixelFormat non_j_pixfmt(enum AVPixelFormat a)
 +{
 +    switch (a) {
 +    case AV_PIX_FMT_YUVJ420P: return AV_PIX_FMT_YUV420P;
 +    case AV_PIX_FMT_YUVJ422P: return AV_PIX_FMT_YUV422P;
 +    case AV_PIX_FMT_YUVJ444P: return AV_PIX_FMT_YUV444P;
 +    default:
 +        return a;
 +    }
  }
  
 -static int h264_init_ps(H264Context *h, const H264SliceContext *sl)
 +static int h264_init_ps(H264Context *h, const H264SliceContext *sl, int first_slice)
  {
      const SPS *sps;
 -    int needs_reinit = 0, ret;
 +    int needs_reinit = 0, must_reinit, ret;
 +
 +    if (first_slice) {
 +        av_buffer_unref(&h->ps.pps_ref);
 +        h->ps.pps = NULL;
 +        h->ps.pps_ref = av_buffer_ref(h->ps.pps_list[sl->pps_id]);
 +        if (!h->ps.pps_ref)
 +            return AVERROR(ENOMEM);
 +        h->ps.pps = (const PPS*)h->ps.pps_ref->data;
 +    }
  
 -    h->ps.pps = (const PPS*)h->ps.pps_list[sl->pps_id]->data;
      if (h->ps.sps != (const SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data) {
 -        h->ps.sps = (SPS*)h->ps.sps_list[h->ps.pps->sps_id]->data;
 +        av_buffer_unref(&h->ps.sps_ref);
 +        h->ps.sps = NULL;
 +        h->ps.sps_ref = av_buffer_ref(h->ps.sps_list[h->ps.pps->sps_id]);
 +        if (!h->ps.sps_ref)
 +            return AVERROR(ENOMEM);
 +        h->ps.sps = (const SPS*)h->ps.sps_ref->data;
 +
 +        if (h->mb_width  != h->ps.sps->mb_width ||
-             h->mb_height != h->ps.sps->mb_height * (2 - h->ps.sps->frame_mbs_only_flag) ||
++            h->mb_height != h->ps.sps->mb_height ||
 +            h->cur_bit_depth_luma    != h->ps.sps->bit_depth_luma ||
 +            h->cur_chroma_format_idc != h->ps.sps->chroma_format_idc
 +        )
 +            needs_reinit = 1;
  
          if (h->bit_depth_luma    != h->ps.sps->bit_depth_luma ||
              h->chroma_format_idc != h->ps.sps->chroma_format_idc)
      }
      sps = h->ps.sps;
  
 -    h->avctx->profile = ff_h264_get_profile(sps);
 -    h->avctx->level   = sps->level_idc;
 -    h->avctx->refs    = sps->ref_frame_count;
 +    must_reinit = (h->context_initialized &&
 +                    (   16*sps->mb_width != h->avctx->coded_width
-                      || 16*sps->mb_height * (2 - sps->frame_mbs_only_flag) != h->avctx->coded_height
++                     || 16*sps->mb_height != h->avctx->coded_height
 +                     || h->cur_bit_depth_luma    != sps->bit_depth_luma
 +                     || h->cur_chroma_format_idc != sps->chroma_format_idc
 +                     || h->mb_width  != sps->mb_width
-                      || h->mb_height != sps->mb_height * (2 - sps->frame_mbs_only_flag)
++                     || h->mb_height != sps->mb_height
 +                    ));
 +    if (h->avctx->pix_fmt == AV_PIX_FMT_NONE
 +        || (non_j_pixfmt(h->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h, 0))))
 +        must_reinit = 1;
 +
 +    if (first_slice && av_cmp_q(sps->sar, h->avctx->sample_aspect_ratio))
 +        must_reinit = 1;
  
 -    if (h->mb_width  != sps->mb_width ||
 -        h->mb_height != sps->mb_height)
 -        needs_reinit = 1;
 +    if (!h->setup_finished) {
 +        h->avctx->profile = ff_h264_get_profile(sps);
 +        h->avctx->level   = sps->level_idc;
 +        h->avctx->refs    = sps->ref_frame_count;
  
 -    h->mb_width  = sps->mb_width;
 -    h->mb_height = sps->mb_height;
 -    h->mb_num    = h->mb_width * h->mb_height;
 -    h->mb_stride = h->mb_width + 1;
 +        h->mb_width  = sps->mb_width;
-         h->mb_height = sps->mb_height * (2 - sps->frame_mbs_only_flag);
++        h->mb_height = sps->mb_height;
 +        h->mb_num    = h->mb_width * h->mb_height;
 +        h->mb_stride = h->mb_width + 1;
  
 -    h->b_stride = h->mb_width * 4;
 +        h->b_stride = h->mb_width * 4;
  
 -    h->chroma_y_shift = sps->chroma_format_idc <= 1; // 400 uses yuv420p
 +        h->chroma_y_shift = sps->chroma_format_idc <= 1; // 400 uses yuv420p
  
 -    h->width  = 16 * h->mb_width;
 -    h->height = 16 * h->mb_height;
 +        h->width  = 16 * h->mb_width;
 +        h->height = 16 * h->mb_height;
  
 -    ret = init_dimensions(h);
 -    if (ret < 0)
 -        return ret;
 +        ret = init_dimensions(h);
 +        if (ret < 0)
 +            return ret;
  
 -    if (sps->video_signal_type_present_flag) {
 -        h->avctx->color_range = sps->full_range ? AVCOL_RANGE_JPEG
 -            : AVCOL_RANGE_MPEG;
 -        if (sps->colour_description_present_flag) {
 -            if (h->avctx->colorspace != sps->colorspace)
 -                needs_reinit = 1;
 -            h->avctx->color_primaries = sps->color_primaries;
 -            h->avctx->color_trc       = sps->color_trc;
 -            h->avctx->colorspace      = sps->colorspace;
 +        if (sps->video_signal_type_present_flag) {
 +            h->avctx->color_range = sps->full_range > 0 ? AVCOL_RANGE_JPEG
 +                                                        : AVCOL_RANGE_MPEG;
 +            if (sps->colour_description_present_flag) {
 +                if (h->avctx->colorspace != sps->colorspace)
 +                    needs_reinit = 1;
 +                h->avctx->color_primaries = sps->color_primaries;
 +                h->avctx->color_trc       = sps->color_trc;
 +                h->avctx->colorspace      = sps->colorspace;
 +            }
          }
      }