Merge commit 'fd124d8357b1becfde3ac8d5e3320127cf97a5b7'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 9 Jul 2015 02:19:42 +0000 (04:19 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 9 Jul 2015 02:50:00 +0000 (04:50 +0200)
* commit 'fd124d8357b1becfde3ac8d5e3320127cf97a5b7':
  hevc_ps: split the code for parsing the SPS and exporting it into the context

Conflicts:
libavcodec/hevc.c
libavcodec/hevc_ps.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/hevc.c
libavcodec/hevc.h
libavcodec/hevc_ps.c

@@@ -519,9 -592,9 +519,9 @@@ static int hls_slice_header(HEVCContex
              s->poc = poc;
  
              sh->short_term_ref_pic_set_sps_flag = get_bits1(gb);
 +            pos = get_bits_left(gb);
              if (!sh->short_term_ref_pic_set_sps_flag) {
-                 ret = ff_hevc_decode_short_term_rps(s, &sh->slice_rps, s->sps, 1);
 -                int pos = get_bits_left(gb);
+                 ret = ff_hevc_decode_short_term_rps(gb, s->avctx, &sh->slice_rps, s->sps, 1);
                  if (ret < 0)
                      return ret;
  
@@@ -920,12 -861,23 +920,25 @@@ typedef struct HEVCContext 
      int sei_display_orientation_present;
      int sei_anticlockwise_rotation;
      int sei_hflip, sei_vflip;
 +
 +    int picture_struct;
  } HEVCContext;
  
- int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
-                                   const HEVCSPS *sps, int is_slice_header);
+ int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,
+                                   ShortTermRPS *rps, const HEVCSPS *sps, int is_slice_header);
+ /**
+  * Parse the SPS from the bitstream into the provided HEVCSPS struct.
+  *
+  * @param sps_id the SPS id will be written here
+  * @param apply_defdispwin if set 1, the default display window from the VUI
+  *                         will be applied to the video dimensions
+  * @param vps_list if non-NULL, this function will validate that the SPS refers
+  *                 to an existing VPS
+  */
+ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
+                       int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx);
  int ff_hevc_decode_nal_vps(HEVCContext *s);
  int ff_hevc_decode_nal_sps(HEVCContext *s);
  int ff_hevc_decode_nal_pps(HEVCContext *s);
@@@ -144,12 -139,6 +141,12 @@@ int ff_hevc_decode_short_term_rps(GetBi
  
          delta_rps_sign = get_bits1(gb);
          abs_delta_rps  = get_ue_golomb_long(gb) + 1;
-             av_log(s->avctx, AV_LOG_ERROR,
 +        if (abs_delta_rps < 1 || abs_delta_rps > 32768) {
++            av_log(avctx, AV_LOG_ERROR,
 +                   "Invalid value of abs_delta_rps: %d\n",
 +                   abs_delta_rps);
 +            return AVERROR_INVALIDDATA;
 +        }
          delta_rps      = (1 - (delta_rps_sign << 1)) * abs_delta_rps;
          for (i = 0; i <= rps_ridx->num_delta_pocs; i++) {
              int used = rps->used[k] = get_bits1(gb);
  }
  
  
- static int decode_profile_tier_level(HEVCContext *s, PTLCommon *ptl)
 -static void decode_profile_tier_level(GetBitContext *gb, AVCodecContext *avctx,
++static int decode_profile_tier_level(GetBitContext *gb, AVCodecContext *avctx,
+                                       PTLCommon *ptl)
  {
      int i;
-     HEVCLocalContext *lc = s->HEVClc;
-     GetBitContext *gb = &lc->gb;
  
 +    if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 16 + 16 + 12)
 +        return -1;
 +
      ptl->profile_space = get_bits(gb, 2);
      ptl->tier_flag     = get_bits1(gb);
      ptl->profile_idc   = get_bits(gb, 5);
      if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN)
-         av_log(s->avctx, AV_LOG_DEBUG, "Main profile bitstream\n");
+         av_log(avctx, AV_LOG_DEBUG, "Main profile bitstream\n");
      else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_10)
-         av_log(s->avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n");
+         av_log(avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n");
      else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE)
-         av_log(s->avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n");
+         av_log(avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n");
 +    else if (ptl->profile_idc == FF_PROFILE_HEVC_REXT)
-         av_log(s->avctx, AV_LOG_DEBUG, "Range Extension profile bitstream\n");
++        av_log(avctx, AV_LOG_DEBUG, "Range Extension profile bitstream\n");
      else
-         av_log(s->avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc);
+         av_log(avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc);
  
      for (i = 0; i < 32; i++)
          ptl->profile_compatibility_flag[i] = get_bits1(gb);
      skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]
      skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]
      skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]
 +
 +    return 0;
  }
  
- static int parse_ptl(HEVCContext *s, PTL *ptl, int max_num_sub_layers)
 -static void parse_ptl(GetBitContext *gb, AVCodecContext *avctx,
++static int parse_ptl(GetBitContext *gb, AVCodecContext *avctx,
+                       PTL *ptl, int max_num_sub_layers)
  {
      int i;
-     HEVCLocalContext *lc = s->HEVClc;
-     GetBitContext *gb = &lc->gb;
-     if (decode_profile_tier_level(s, &ptl->general_ptl) < 0 ||
 -    decode_profile_tier_level(gb, avctx, &ptl->general_ptl);
++    if (decode_profile_tier_level(gb, avctx, &ptl->general_ptl) < 0 ||
 +        get_bits_left(gb) < 8 + 8*2) {
-         av_log(s->avctx, AV_LOG_ERROR, "PTL information too short\n");
++        av_log(avctx, AV_LOG_ERROR, "PTL information too short\n");
 +        return -1;
 +    }
 +
      ptl->general_ptl.level_idc = get_bits(gb, 8);
  
      for (i = 0; i < max_num_sub_layers - 1; i++) {
          for (i = max_num_sub_layers - 1; i < 8; i++)
              skip_bits(gb, 2); // reserved_zero_2bits[i]
      for (i = 0; i < max_num_sub_layers - 1; i++) {
 -        if (ptl->sub_layer_profile_present_flag[i])
 -            decode_profile_tier_level(gb, avctx, &ptl->sub_layer_ptl[i]);
 -        if (ptl->sub_layer_level_present_flag[i])
 -            ptl->sub_layer_ptl[i].level_idc = get_bits(gb, 8);
 +        if (ptl->sub_layer_profile_present_flag[i] &&
-             decode_profile_tier_level(s, &ptl->sub_layer_ptl[i]) < 0) {
-             av_log(s->avctx, AV_LOG_ERROR,
++            decode_profile_tier_level(gb, avctx, &ptl->sub_layer_ptl[i]) < 0) {
++            av_log(avctx, AV_LOG_ERROR,
 +                   "PTL information for sublayer %i too short\n", i);
 +            return -1;
 +        }
 +        if (ptl->sub_layer_level_present_flag[i]) {
 +            if (get_bits_left(gb) < 8) {
-                 av_log(s->avctx, AV_LOG_ERROR,
++                av_log(avctx, AV_LOG_ERROR,
 +                       "Not enough data for sublayer %i level_idc\n", i);
 +                return -1;
 +            } else
 +                ptl->sub_layer_ptl[i].level_idc = get_bits(gb, 8);
 +        }
      }
 +
 +    return 0;
  }
  
- static void decode_sublayer_hrd(HEVCContext *s, unsigned int nb_cpb,
+ static void decode_sublayer_hrd(GetBitContext *gb, unsigned int nb_cpb,
                                  int subpic_params_present)
  {
-     GetBitContext *gb = &s->HEVClc->gb;
      int i;
  
      for (i = 0; i < nb_cpb; i++) {
      }
  }
  
- static int decode_hrd(HEVCContext *s, int common_inf_present,
 -static void decode_hrd(GetBitContext *gb, int common_inf_present,
++static int decode_hrd(GetBitContext *gb, int common_inf_present,
                         int max_sublayers)
  {
-     GetBitContext *gb = &s->HEVClc->gb;
      int nal_params_present = 0, vcl_params_present = 0;
      int subpic_params_present = 0;
      int i;
          else
              low_delay = get_bits1(gb);
  
 -        if (!low_delay)
 +        if (!low_delay) {
              nb_cpb = get_ue_golomb_long(gb) + 1;
-                 av_log(s->avctx, AV_LOG_ERROR, "nb_cpb %d invalid\n", nb_cpb);
 +            if (nb_cpb < 1 || nb_cpb > 32) {
++                av_log(NULL, AV_LOG_ERROR, "nb_cpb %d invalid\n", nb_cpb);
 +                return AVERROR_INVALIDDATA;
 +            }
 +        }
  
          if (nal_params_present)
-             decode_sublayer_hrd(s, nb_cpb, subpic_params_present);
+             decode_sublayer_hrd(gb, nb_cpb, subpic_params_present);
          if (vcl_params_present)
-             decode_sublayer_hrd(s, nb_cpb, subpic_params_present);
+             decode_sublayer_hrd(gb, nb_cpb, subpic_params_present);
      }
 +    return 0;
  }
  
  int ff_hevc_decode_nal_vps(HEVCContext *s)
          goto err;
      }
  
-     if (parse_ptl(s, &vps->ptl, vps->vps_max_sub_layers) < 0)
 -    parse_ptl(gb, s->avctx, &vps->ptl, vps->vps_max_sub_layers);
++    if (parse_ptl(gb, s->avctx, &vps->ptl, vps->vps_max_sub_layers) < 0)
 +        goto err;
  
      vps->vps_sub_layer_ordering_info_present_flag = get_bits1(gb);
  
@@@ -518,14 -453,13 +511,14 @@@ err
      return AVERROR_INVALIDDATA;
  }
  
- static void decode_vui(HEVCContext *s, HEVCSPS *sps)
+ static void decode_vui(GetBitContext *gb, AVCodecContext *avctx,
+                        int apply_defdispwin, HEVCSPS *sps)
  {
      VUI *vui          = &sps->vui;
-     GetBitContext *gb = &s->HEVClc->gb;
 -    int sar_present;
 +    GetBitContext backup;
 +    int sar_present, alt = 0;
  
-     av_log(s->avctx, AV_LOG_DEBUG, "Decoding VUI\n");
+     av_log(avctx, AV_LOG_DEBUG, "Decoding VUI\n");
  
      sar_present = get_bits1(gb);
      if (sar_present) {
      vui->field_seq_flag                = get_bits1(gb);
      vui->frame_field_info_present_flag = get_bits1(gb);
  
 -    vui->default_display_window_flag = get_bits1(gb);
 +    if (get_bits_left(gb) >= 68 && show_bits_long(gb, 21) == 0x100000) {
 +        vui->default_display_window_flag = 0;
-         av_log(s->avctx, AV_LOG_WARNING, "Invalid default display window\n");
++        av_log(avctx, AV_LOG_WARNING, "Invalid default display window\n");
 +    } else
 +        vui->default_display_window_flag = get_bits1(gb);
 +    // Backup context in case an alternate header is detected
 +    memcpy(&backup, gb, sizeof(backup));
 +
      if (vui->default_display_window_flag) {
          //TODO: * 2 is only valid for 420
          vui->def_disp_win.left_offset   = get_ue_golomb_long(gb) * 2;
      }
  
      vui->vui_timing_info_present_flag = get_bits1(gb);
 +
      if (vui->vui_timing_info_present_flag) {
-             av_log(s->avctx, AV_LOG_WARNING,
 +        if( get_bits_left(gb) < 66) {
 +            // The alternate syntax seem to have timing info located
 +            // at where def_disp_win is normally located
++            av_log(avctx, AV_LOG_WARNING,
 +                   "Strange VUI timing information, retrying...\n");
 +            vui->default_display_window_flag = 0;
 +            memset(&vui->def_disp_win, 0, sizeof(vui->def_disp_win));
 +            memcpy(gb, &backup, sizeof(backup));
 +            alt = 1;
 +        }
          vui->vui_num_units_in_tick               = get_bits_long(gb, 32);
          vui->vui_time_scale                      = get_bits_long(gb, 32);
-             av_log(s->avctx, AV_LOG_INFO, "Retry got %i/%i fps\n",
 +        if (alt) {
++            av_log(avctx, AV_LOG_INFO, "Retry got %i/%i fps\n",
 +                   vui->vui_time_scale, vui->vui_num_units_in_tick);
 +        }
          vui->vui_poc_proportional_to_timing_flag = get_bits1(gb);
          if (vui->vui_poc_proportional_to_timing_flag)
              vui->vui_num_ticks_poc_diff_one_minus1 = get_ue_golomb_long(gb);
@@@ -671,25 -583,19 +664,24 @@@ static void set_default_scaling_list_da
      memcpy(sl->sl[2][4], default_scaling_list_inter, 64);
      memcpy(sl->sl[2][5], default_scaling_list_inter, 64);
      memcpy(sl->sl[3][0], default_scaling_list_intra, 64);
 -    memcpy(sl->sl[3][1], default_scaling_list_inter, 64);
 +    memcpy(sl->sl[3][1], default_scaling_list_intra, 64);
 +    memcpy(sl->sl[3][2], default_scaling_list_intra, 64);
 +    memcpy(sl->sl[3][3], default_scaling_list_inter, 64);
 +    memcpy(sl->sl[3][4], default_scaling_list_inter, 64);
 +    memcpy(sl->sl[3][5], default_scaling_list_inter, 64);
  }
  
- static int scaling_list_data(HEVCContext *s, ScalingList *sl, HEVCSPS *sps)
 -static int scaling_list_data(GetBitContext *gb, AVCodecContext *avctx, ScalingList *sl)
++static int scaling_list_data(GetBitContext *gb, AVCodecContext *avctx, ScalingList *sl, HEVCSPS *sps)
  {
-     GetBitContext *gb = &s->HEVClc->gb;
 -    uint8_t scaling_list_pred_mode_flag[4][6];
 +    uint8_t scaling_list_pred_mode_flag;
      int32_t scaling_list_dc_coef[2][6];
 -    int size_id, matrix_id, i, pos;
 +    int size_id, matrix_id, pos;
 +    int i;
  
      for (size_id = 0; size_id < 4; size_id++)
 -        for (matrix_id = 0; matrix_id < (size_id == 3 ? 2 : 6); matrix_id++) {
 -            scaling_list_pred_mode_flag[size_id][matrix_id] = get_bits1(gb);
 -            if (!scaling_list_pred_mode_flag[size_id][matrix_id]) {
 +        for (matrix_id = 0; matrix_id < 6; matrix_id += ((size_id == 3) ? 3 : 1)) {
 +            scaling_list_pred_mode_flag = get_bits1(gb);
 +            if (!scaling_list_pred_mode_flag) {
                  unsigned int delta = get_ue_golomb_long(gb);
                  /* Only need to handle non-zero delta. Zero means default,
                   * which should already be in the arrays. */
@@@ -795,12 -677,11 +777,12 @@@ int ff_hevc_parse_sps(HEVCSPS *sps, Get
  
      skip_bits1(gb); // temporal_id_nesting_flag
  
-     if (parse_ptl(s, &sps->ptl, sps->max_sub_layers) < 0)
 -    parse_ptl(gb, avctx, &sps->ptl, sps->max_sub_layers);
++    if ((ret = parse_ptl(gb, avctx, &sps->ptl, sps->max_sub_layers)) < 0)
 +        goto err;
  
-     sps_id = get_ue_golomb_long(gb);
-     if (sps_id >= MAX_SPS_COUNT) {
-         av_log(s->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", sps_id);
+     *sps_id = get_ue_golomb_long(gb);
+     if (*sps_id >= MAX_SPS_COUNT) {
+         av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", *sps_id);
          ret = AVERROR_INVALIDDATA;
          goto err;
      }
  
      sps->bit_depth   = get_ue_golomb_long(gb) + 8;
      bit_depth_chroma = get_ue_golomb_long(gb) + 8;
 -    if (bit_depth_chroma != sps->bit_depth) {
 +    if (sps->chroma_format_idc && bit_depth_chroma != sps->bit_depth) {
-         av_log(s->avctx, AV_LOG_ERROR,
+         av_log(avctx, AV_LOG_ERROR,
                 "Luma bit depth (%d) is different from chroma bit depth (%d), "
                 "this is unsupported.\n",
                 sps->bit_depth, bit_depth_chroma);
          goto err;
      }
  
 -    if (sps->chroma_format_idc == 1) {
 -        switch (sps->bit_depth) {
 -        case 8:  sps->pix_fmt = AV_PIX_FMT_YUV420P;   break;
 -        case 9:  sps->pix_fmt = AV_PIX_FMT_YUV420P9;  break;
 -        case 10: sps->pix_fmt = AV_PIX_FMT_YUV420P10; break;
 -        default:
 -            av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
 -                   sps->bit_depth);
 -            ret = AVERROR_PATCHWELCOME;
 -            goto err;
 -        }
 -    } else {
 +    switch (sps->bit_depth) {
 +    case 8:
 +        if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY8;
 +        if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P;
 +        if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P;
 +        if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P;
 +       break;
 +    case 9:
 +        if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
 +        if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P9;
 +        if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P9;
 +        if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P9;
 +        break;
 +    case 10:
 +        if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
 +        if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P10;
 +        if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P10;
 +        if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P10;
 +        break;
 +    case 12:
 +        if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
 +        if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P12;
 +        if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P12;
 +        if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12;
 +        break;
 +    default:
-         av_log(s->avctx, AV_LOG_ERROR,
+         av_log(avctx, AV_LOG_ERROR,
 -               "non-4:2:0 support is currently unspecified.\n");
 -        return AVERROR_PATCHWELCOME;
 +               "4:2:0, 4:2:2, 4:4:4 supports are currently specified for 8, 10 and 12 bits.\n");
 +        ret = AVERROR_PATCHWELCOME;
 +        goto err;
      }
  
      desc = av_pix_fmt_desc_get(sps->pix_fmt);
      sps->log2_max_trafo_size                 = log2_diff_max_min_transform_block_size +
                                                 sps->log2_min_tb_size;
  
 -    if (sps->log2_min_tb_size >= sps->log2_min_cb_size) {
 +    if (sps->log2_min_cb_size < 3 || sps->log2_min_cb_size > 30) {
-         av_log(s->avctx, AV_LOG_ERROR, "Invalid value %d for log2_min_cb_size", sps->log2_min_cb_size);
++        av_log(avctx, AV_LOG_ERROR, "Invalid value %d for log2_min_cb_size", sps->log2_min_cb_size);
 +        ret = AVERROR_INVALIDDATA;
 +        goto err;
 +    }
 +
 +    if (sps->log2_diff_max_min_coding_block_size > 30) {
-         av_log(s->avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_coding_block_size", sps->log2_diff_max_min_coding_block_size);
++        av_log(avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_coding_block_size", sps->log2_diff_max_min_coding_block_size);
 +        ret = AVERROR_INVALIDDATA;
 +        goto err;
 +    }
 +
 +    if (sps->log2_min_tb_size >= sps->log2_min_cb_size || sps->log2_min_tb_size < 2) {
-         av_log(s->avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size");
+         av_log(avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size");
          ret = AVERROR_INVALIDDATA;
          goto err;
      }
-         av_log(s->avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_transform_block_size", log2_diff_max_min_transform_block_size);
 +
 +    if (log2_diff_max_min_transform_block_size < 0 || log2_diff_max_min_transform_block_size > 30) {
++        av_log(avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_transform_block_size", log2_diff_max_min_transform_block_size);
 +        ret = AVERROR_INVALIDDATA;
 +        goto err;
 +    }
 +
      sps->max_transform_hierarchy_depth_inter = get_ue_golomb_long(gb);
      sps->max_transform_hierarchy_depth_intra = get_ue_golomb_long(gb);
  
          set_default_scaling_list_data(&sps->scaling_list);
  
          if (get_bits1(gb)) {
-             ret = scaling_list_data(s, &sps->scaling_list, sps);
 -            ret = scaling_list_data(gb, avctx, &sps->scaling_list);
++            ret = scaling_list_data(gb, avctx, &sps->scaling_list, sps);
              if (ret < 0)
                  goto err;
          }
      sps->long_term_ref_pics_present_flag = get_bits1(gb);
      if (sps->long_term_ref_pics_present_flag) {
          sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb);
-             av_log(s->avctx, AV_LOG_ERROR, "num_long_term_ref_pics_sps %d is out of range.\n",
 +        if (sps->num_long_term_ref_pics_sps > 31U) {
++            av_log(avctx, AV_LOG_ERROR, "num_long_term_ref_pics_sps %d is out of range.\n",
 +                   sps->num_long_term_ref_pics_sps);
 +            goto err;
 +        }
          for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
              sps->lt_ref_pic_poc_lsb_sps[i]       = get_bits(gb, sps->log2_max_poc_lsb);
              sps->used_by_curr_pic_lt_sps_flag[i] = get_bits1(gb);
      sps->vui.sar = (AVRational){0, 1};
      vui_present = get_bits1(gb);
      if (vui_present)
-         decode_vui(s, sps);
+         decode_vui(gb, avctx, apply_defdispwin, sps);
 -    skip_bits1(gb); // sps_extension_flag
  
-                 av_log(s->avctx, AV_LOG_WARNING,
 +    if (get_bits1(gb)) { // sps_extension_flag
 +        int sps_extension_flag[1];
 +        for (i = 0; i < 1; i++)
 +            sps_extension_flag[i] = get_bits1(gb);
 +        skip_bits(gb, 7); //sps_extension_7bits = get_bits(gb, 7);
 +        if (sps_extension_flag[0]) {
 +            int extended_precision_processing_flag;
 +            int high_precision_offsets_enabled_flag;
 +            int cabac_bypass_alignment_enabled_flag;
 +
 +            sps->transform_skip_rotation_enabled_flag = get_bits1(gb);
 +            sps->transform_skip_context_enabled_flag  = get_bits1(gb);
 +            sps->implicit_rdpcm_enabled_flag = get_bits1(gb);
 +
 +            sps->explicit_rdpcm_enabled_flag = get_bits1(gb);
 +
 +            extended_precision_processing_flag = get_bits1(gb);
 +            if (extended_precision_processing_flag)
-                 av_log(s->avctx, AV_LOG_WARNING,
++                av_log(avctx, AV_LOG_WARNING,
 +                   "extended_precision_processing_flag not yet implemented\n");
 +
 +            sps->intra_smoothing_disabled_flag       = get_bits1(gb);
 +            high_precision_offsets_enabled_flag  = get_bits1(gb);
 +            if (high_precision_offsets_enabled_flag)
-                 av_log(s->avctx, AV_LOG_WARNING,
++                av_log(avctx, AV_LOG_WARNING,
 +                   "high_precision_offsets_enabled_flag not yet implemented\n");
 +
 +            sps->persistent_rice_adaptation_enabled_flag = get_bits1(gb);
 +
 +            cabac_bypass_alignment_enabled_flag  = get_bits1(gb);
 +            if (cabac_bypass_alignment_enabled_flag)
-     if (s->apply_defdispwin) {
++                av_log(avctx, AV_LOG_WARNING,
 +                   "cabac_bypass_alignment_enabled_flag not yet implemented\n");
 +        }
 +    }
+     if (apply_defdispwin) {
          sps->output_window.left_offset   += sps->vui.def_disp_win.left_offset;
          sps->output_window.right_offset  += sps->vui.def_disp_win.right_offset;
          sps->output_window.top_offset    += sps->vui.def_disp_win.top_offset;
                           (sps->output_window.left_offset + sps->output_window.right_offset);
      sps->output_height = sps->height -
                           (sps->output_window.top_offset + sps->output_window.bottom_offset);
 -    if (sps->output_width <= 0 || sps->output_height <= 0) {
 +    if (sps->width  <= sps->output_window.left_offset + (int64_t)sps->output_window.right_offset  ||
 +        sps->height <= sps->output_window.top_offset  + (int64_t)sps->output_window.bottom_offset) {
-         av_log(s->avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",
+         av_log(avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",
                 sps->output_width, sps->output_height);
-         if (s->avctx->err_recognition & AV_EF_EXPLODE) {
+         if (avctx->err_recognition & AV_EF_EXPLODE) {
              ret = AVERROR_INVALIDDATA;
              goto err;
          }
-         av_log(s->avctx, AV_LOG_WARNING,
+         av_log(avctx, AV_LOG_WARNING,
                 "Displaying the whole video surface.\n");
 -        sps->output_window.left_offset   =
 -        sps->output_window.right_offset  =
 -        sps->output_window.top_offset    =
 -        sps->output_window.bottom_offset = 0;
 +        memset(&sps->pic_conf_win, 0, sizeof(sps->pic_conf_win));
 +        memset(&sps->output_window, 0, sizeof(sps->output_window));
          sps->output_width               = sps->width;
          sps->output_height              = sps->height;
      }
                           sps->log2_diff_max_min_coding_block_size;
      sps->log2_min_pu_size = sps->log2_min_cb_size - 1;
  
-         av_log(s->avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
 +    if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {
-         av_log(s->avctx,
++        av_log(avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
 +        goto err;
 +    }
 +    if (sps->log2_ctb_size < 4) {
-         avpriv_request_sample(s->avctx, "log2_ctb_size %d", sps->log2_ctb_size);
++        av_log(avctx,
 +               AV_LOG_ERROR,
 +               "log2_ctb_size %d differs from the bounds of any known profile\n",
 +               sps->log2_ctb_size);
++        avpriv_request_sample(avctx, "log2_ctb_size %d", sps->log2_ctb_size);
 +        goto err;
 +    }
 +
      sps->ctb_width  = (sps->width  + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
      sps->ctb_height = (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
      sps->ctb_size   = sps->ctb_width * sps->ctb_height;
  
      sps->qp_bd_offset = 6 * (sps->bit_depth - 8);
  
 -    if (sps->width  & ((1 << sps->log2_min_cb_size) - 1) ||
 -        sps->height & ((1 << sps->log2_min_cb_size) - 1)) {
 +    if (av_mod_uintp2(sps->width, sps->log2_min_cb_size) ||
 +        av_mod_uintp2(sps->height, sps->log2_min_cb_size)) {
-         av_log(s->avctx, AV_LOG_ERROR, "Invalid coded frame dimensions.\n");
+         av_log(avctx, AV_LOG_ERROR, "Invalid coded frame dimensions.\n");
          goto err;
      }
  
 -    if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {
 -        av_log(avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
 -        goto err;
 -    }
      if (sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_size) {
-         av_log(s->avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_inter out of range: %d\n",
+         av_log(avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_inter out of range: %d\n",
                 sps->max_transform_hierarchy_depth_inter);
          goto err;
      }
          goto err;
      }
  
-         av_log(s->avctx, AV_LOG_ERROR,
 +    if (get_bits_left(gb) < 0) {
 -    ret = ff_hevc_parse_sps(sps, &s->HEVClc.gb, &sps_id,
++        av_log(avctx, AV_LOG_ERROR,
 +               "Overread SPS by %d bits\n", -get_bits_left(gb));
 +        goto err;
 +    }
 +
+     return 0;
+ err:
+     return ret;
+ }
+ int ff_hevc_decode_nal_sps(HEVCContext *s)
+ {
+     HEVCSPS *sps;
+     AVBufferRef *sps_buf = av_buffer_allocz(sizeof(*sps));
+     unsigned int sps_id;
+     int ret;
+     if (!sps_buf)
+         return AVERROR(ENOMEM);
+     sps = (HEVCSPS*)sps_buf->data;
+     av_log(s->avctx, AV_LOG_DEBUG, "Decoding SPS\n");
++    ret = ff_hevc_parse_sps(sps, &s->HEVClc->gb, &sps_id,
+                             s->apply_defdispwin,
+                             s->vps_list, s->avctx);
+     if (ret < 0) {
+         av_buffer_unref(&sps_buf);
+         return ret;
+     }
      if (s->avctx->debug & FF_DEBUG_BITSTREAM) {
          av_log(s->avctx, AV_LOG_DEBUG,
                 "Parsed SPS: id %d; coded wxh: %dx%d; "
@@@ -1436,7 -1209,7 +1441,7 @@@ int ff_hevc_decode_nal_pps(HEVCContext 
      pps->scaling_list_data_present_flag = get_bits1(gb);
      if (pps->scaling_list_data_present_flag) {
          set_default_scaling_list_data(&pps->scaling_list);
-         ret = scaling_list_data(s, &pps->scaling_list, sps);
 -        ret = scaling_list_data(gb, s->avctx, &pps->scaling_list);
++        ret = scaling_list_data(gb, s->avctx, &pps->scaling_list, sps);
          if (ret < 0)
              goto err;
      }