diff options
author | gcocherel <gildas.cocherel@laposte.net> | 2013-11-21 11:25:32 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-11-22 01:29:02 +0100 |
commit | 36658c978f5d7df2ce556075946f3a80f7eca753 (patch) | |
tree | e519bb5ee4a878d5897d70b095ab1e9ba9c37b76 | |
parent | 7c98c834e0a2855d5c612fd22f6f2826c1116a9a (diff) | |
download | ffmpeg-36658c978f5d7df2ce556075946f3a80f7eca753.tar.gz |
hevc : update hevc_ps.c
(cherry picked from commit 088f2eb1ae42bffc63c2cee4e7eba8f47056043b)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/hevc.c | 15 | ||||
-rw-r--r-- | libavcodec/hevc.h | 33 | ||||
-rw-r--r-- | libavcodec/hevc_ps.c | 89 |
3 files changed, 77 insertions, 60 deletions
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index ec04f8081b..26b0c5f42b 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -325,7 +325,7 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps) } s->sps = sps; - s->vps = s->vps_list[s->sps->vps_id]; + s->vps = (HEVCVPS*) s->vps_list[s->sps->vps_id]->data; return 0; fail: @@ -365,7 +365,6 @@ static int hls_slice_header(HEVCContext *s) if (s->sps != (HEVCSPS*)s->sps_list[s->pps->sps_id]->data) { s->sps = (HEVCSPS*)s->sps_list[s->pps->sps_id]->data; - ff_hevc_clear_refs(s); ret = set_sps(s, s->sps); if (ret < 0) @@ -2655,7 +2654,7 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) } for (i = 0; i < FF_ARRAY_ELEMS(s->vps_list); i++) - av_freep(&s->vps_list[i]); + av_buffer_unref(&s->vps_list[i]); for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++) av_buffer_unref(&s->sps_list[i]); for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++) @@ -2669,7 +2668,6 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) lc = s->HEVClcList[i]; if (lc) { av_freep(&lc->edge_emu_buffer); - av_freep(&s->HEVClcList[i]); av_freep(&s->sList[i]); } @@ -2755,6 +2753,15 @@ static int hevc_update_thread_context(AVCodecContext *dst, } } + for (i = 0; i < FF_ARRAY_ELEMS(s->vps_list); i++) { + av_buffer_unref(&s->vps_list[i]); + if (s0->vps_list[i]) { + s->vps_list[i] = av_buffer_ref(s0->vps_list[i]); + if (!s->vps_list[i]) + return AVERROR(ENOMEM); + } + } + for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++) { av_buffer_unref(&s->sps_list[i]); if (s0->sps_list[i]) { diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index b8200b8a1d..74673a9f1a 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -330,12 +330,21 @@ typedef struct VUI { int log2_max_mv_length_vertical; } VUI; +typedef struct ProfileTierLevel { + int profile_space; + uint8_t tier_flag; + int profile_idc; + int profile_compatibility_flag[32]; + int level_idc; + int progressive_source_flag; + int interlaced_source_flag; + int non_packed_constraint_flag; + int frame_only_constraint_flag; +} ProfileTierLevel; + typedef struct PTL { - int general_profile_space; - uint8_t general_tier_flag; - int general_profile_idc; - int general_profile_compatibility_flag[32]; - int general_level_idc; + ProfileTierLevel general_PTL; + ProfileTierLevel sub_layer_PTL[MAX_SUB_LAYERS]; uint8_t sub_layer_profile_present_flag[MAX_SUB_LAYERS]; uint8_t sub_layer_level_present_flag[MAX_SUB_LAYERS]; @@ -365,6 +374,8 @@ typedef struct HEVCVPS { uint8_t vps_poc_proportional_to_timing_flag; int vps_num_ticks_poc_diff_one; ///< vps_num_ticks_poc_diff_one_minus1 + 1 int vps_num_hrd_parameters; + + int vps_extension_flag; } HEVCVPS; typedef struct ScalingList { @@ -757,12 +768,12 @@ typedef struct HEVCLocalContext { typedef struct HEVCContext { const AVClass *c; // needed by private avoptions - AVCodecContext *avctx; + AVCodecContext *avctx; - struct HEVCContext *sList[MAX_NB_THREADS]; + struct HEVCContext *sList[MAX_NB_THREADS]; - HEVCLocalContext *HEVClcList[MAX_NB_THREADS]; - HEVCLocalContext *HEVClc; + HEVCLocalContext *HEVClcList[MAX_NB_THREADS]; + HEVCLocalContext *HEVClc; uint8_t threads_type; uint8_t threads_number; @@ -783,7 +794,7 @@ typedef struct HEVCContext { HEVCVPS *vps; const HEVCSPS *sps; HEVCPPS *pps; - HEVCVPS *vps_list[MAX_VPS_COUNT]; + AVBufferRef *vps_list[MAX_VPS_COUNT]; AVBufferRef *sps_list[MAX_SPS_COUNT]; AVBufferRef *pps_list[MAX_PPS_COUNT]; @@ -982,14 +993,12 @@ int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s); int ff_hevc_cu_qp_delta_abs(HEVCContext *s); void ff_hevc_hls_filter(HEVCContext *s, int x, int y); void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size); - void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, int log2_trafo_size, enum ScanType scan_idx, int c_idx); void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size); -void ff_hevc_pps_free(HEVCPPS **ppps); extern const uint8_t ff_hevc_qpel_extra_before[4]; extern const uint8_t ff_hevc_qpel_extra_after[4]; diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 7f52671713..16eeab40cd 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -24,7 +24,6 @@ */ #include "libavutil/imgutils.h" - #include "golomb.h" #include "hevc.h" @@ -192,65 +191,58 @@ int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps, return 0; } -static int decode_profile_tier_level(HEVCContext *s, PTL *ptl, - int max_num_sub_layers) + +static int decode_profile_tier_level(HEVCContext *s, ProfileTierLevel *ptl) { - int i, j; + int i; HEVCLocalContext *lc = s->HEVClc; GetBitContext *gb = &lc->gb; - ptl->general_profile_space = get_bits(gb, 2); - ptl->general_tier_flag = get_bits1(gb); - ptl->general_profile_idc = get_bits(gb, 5); - if (ptl->general_profile_idc == 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 == 1) av_log(s->avctx, AV_LOG_DEBUG, "Main profile bitstream\n"); - else if (ptl->general_profile_idc == 2) + else if (ptl->profile_idc == 2) av_log(s->avctx, AV_LOG_DEBUG, "Main10 profile bitstream\n"); else - av_log(s->avctx, AV_LOG_WARNING, "No profile indication! (%d)\n", ptl->general_profile_idc); + av_log(s->avctx, AV_LOG_WARNING, "No profile indication! (%d)\n", ptl->profile_idc); for (i = 0; i < 32; i++) - ptl->general_profile_compatibility_flag[i] = get_bits1(gb); - skip_bits1(gb); // general_progressive_source_flag - skip_bits1(gb); // general_interlaced_source_flag - skip_bits1(gb); // general_non_packed_constraint_flag - skip_bits1(gb); // general_frame_only_constraint_flag + ptl->profile_compatibility_flag[i] = get_bits1(gb); + ptl->progressive_source_flag = get_bits1(gb); + ptl->interlaced_source_flag = get_bits1(gb); + ptl->non_packed_constraint_flag = get_bits1(gb); + ptl->frame_only_constraint_flag = get_bits1(gb); if (get_bits(gb, 16) != 0) // XXX_reserved_zero_44bits[0..15] return -1; if (get_bits(gb, 16) != 0) // XXX_reserved_zero_44bits[16..31] return -1; if (get_bits(gb, 12) != 0) // XXX_reserved_zero_44bits[32..43] return -1; + ptl->level_idc = get_bits(gb, 8); + return 0; +} + +static int parse_ptl(HEVCContext *s, PTL *ptl, int max_num_sub_layers) +{ + int i; + HEVCLocalContext *lc = s->HEVClc; + GetBitContext *gb = &lc->gb; + decode_profile_tier_level(s, &ptl->general_PTL); - ptl->general_level_idc = get_bits(gb, 8); for (i = 0; i < max_num_sub_layers - 1; i++) { ptl->sub_layer_profile_present_flag[i] = get_bits1(gb); ptl->sub_layer_level_present_flag[i] = get_bits1(gb); } - if (max_num_sub_layers - 1 > 0) + if (max_num_sub_layers - 1> 0) for (i = max_num_sub_layers - 1; i < 8; i++) - skip_bits(gb, 2); // reserved_zero_2bits[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]) { - ptl->sub_layer_profile_space[i] = get_bits(gb, 2); - ptl->sub_layer_tier_flag[i] = get_bits(gb, 1); - ptl->sub_layer_profile_idc[i] = get_bits(gb, 5); - for (j = 0; j < 32; j++) - ptl->sub_layer_profile_compatibility_flags[i][j] = get_bits1(gb); - skip_bits1(gb); // sub_layer_progressive_source_flag - skip_bits1(gb); // sub_layer_interlaced_source_flag - skip_bits1(gb); // sub_layer_non_packed_constraint_flag - skip_bits1(gb); // sub_layer_frame_only_constraint_flag - - if (get_bits(gb, 16) != 0) // sub_layer_reserved_zero_44bits[0..15] - return -1; - if (get_bits(gb, 16) != 0) // sub_layer_reserved_zero_44bits[16..31] - return -1; - if (get_bits(gb, 12) != 0) // sub_layer_reserved_zero_44bits[32..43] - return -1; + decode_profile_tier_level(s, &ptl->sub_layer_PTL[i]); + ptl->sub_layer_PTL[i].level_idc = get_bits(gb, 8); } - if (ptl->sub_layer_level_present_flag[i]) - ptl->sub_layer_level_idc[i] = get_bits(gb, 8); } return 0; } @@ -336,10 +328,14 @@ int ff_hevc_decode_nal_vps(HEVCContext *s) GetBitContext *gb = &s->HEVClc->gb; int vps_id = 0; HEVCVPS *vps; + AVBufferRef *vps_buf = av_buffer_allocz(sizeof(*vps)); + + if (!vps_buf) + return AVERROR(ENOMEM); + vps = (HEVCVPS*)vps_buf->data; av_log(s->avctx, AV_LOG_DEBUG, "Decoding VPS\n"); - vps = av_mallocz(sizeof(*vps)); if (!vps) return AVERROR(ENOMEM); @@ -369,7 +365,7 @@ int ff_hevc_decode_nal_vps(HEVCContext *s) goto err; } - if (decode_profile_tier_level(s, &vps->ptl, vps->vps_max_sub_layers) < 0) { + if (parse_ptl(s, &vps->ptl, vps->vps_max_sub_layers) < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error decoding profile tier level.\n"); goto err; } @@ -416,14 +412,16 @@ int ff_hevc_decode_nal_vps(HEVCContext *s) decode_hrd(s, common_inf_present, vps->vps_max_sub_layers); } } - get_bits1(gb); /* vps_extension_flag */ - av_free(s->vps_list[vps_id]); - s->vps_list[vps_id] = vps; + vps->vps_extension_flag = get_bits1(gb); + + av_buffer_unref(&s->vps_list[vps_id]); + s->vps_list[vps_id] = vps_buf; + return 0; err: - av_free(vps); + av_buffer_unref(&vps_buf); return AVERROR_INVALIDDATA; } @@ -510,9 +508,12 @@ static void decode_vui(HEVCContext *s, HEVCSPS *sps) } vui->vui_timing_info_present_flag = get_bits1(gb); + if (vui->vui_timing_info_present_flag) { vui->vui_num_units_in_tick = get_bits(gb, 32); vui->vui_time_scale = get_bits(gb, 32); + s->avctx->time_base.num = vui->vui_num_units_in_tick; + s->avctx->time_base.den = vui->vui_time_scale; 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); @@ -654,8 +655,8 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) } skip_bits1(gb); // temporal_id_nesting_flag - if (decode_profile_tier_level(s, &sps->ptl, - sps->max_sub_layers) < 0) { + + if (parse_ptl(s, &sps->ptl, sps->max_sub_layers) < 0) { av_log(s->avctx, AV_LOG_ERROR, "error decoding profile tier level\n"); ret = AVERROR_INVALIDDATA; goto err; |