diff options
author | Mickaƫl Raulet <mraulet@insa-rennes.fr> | 2013-10-21 11:49:35 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-10-22 20:20:40 +0200 |
commit | 0c8aba3842a718eb9139fc88b7b60dc79e127bd7 (patch) | |
tree | 5f688a62b6e74e920f54450cc4a313ebcfe06877 /libavcodec | |
parent | e146c326b91297ff900db632eb0dba30289e9ee6 (diff) | |
download | ffmpeg-0c8aba3842a718eb9139fc88b7b60dc79e127bd7.tar.gz |
hevc: add wavefront parallel processing
cherry picked from commit b971f2c8fdc60f8bab605a6e8060492eb548a53a
cherry picked from commit e57b0a2c915ce6b8a9d57b8292f6581f0680842e
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/hevc.c | 346 | ||||
-rw-r--r-- | libavcodec/hevc.h | 38 | ||||
-rw-r--r-- | libavcodec/hevc_cabac.c | 102 | ||||
-rw-r--r-- | libavcodec/hevc_filter.c | 8 | ||||
-rw-r--r-- | libavcodec/hevc_mvs.c | 13 | ||||
-rw-r--r-- | libavcodec/hevc_ps.c | 16 | ||||
-rw-r--r-- | libavcodec/hevc_refs.c | 3 | ||||
-rw-r--r-- | libavcodec/hevc_sei.c | 8 | ||||
-rw-r--r-- | libavcodec/hevcpred_template.c | 2 |
9 files changed, 415 insertions, 121 deletions
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index cdf0237c23..58a95ad131 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -23,6 +23,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/atomic.h" #include "libavutil/attributes.h" #include "libavutil/common.h" #include "libavutil/internal.h" @@ -70,6 +71,10 @@ static void pic_arrays_free(HEVCContext *s) av_freep(&s->horizontal_bs); av_freep(&s->vertical_bs); + av_freep(&s->sh.entry_point_offset); + av_freep(&s->sh.size); + av_freep(&s->sh.offset); + av_buffer_pool_uninit(&s->tab_mvf_pool); av_buffer_pool_uninit(&s->rpl_tab_pool); } @@ -284,9 +289,9 @@ static int decode_lt_rps(HEVCContext *s, LongTermRPS *rps, GetBitContext *gb) static int hls_slice_header(HEVCContext *s) { - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; SliceHeader *sh = &s->sh; - int i, ret; + int i, j, ret; // Coded parameters sh->first_slice_in_pic_flag = get_bits1(gb); @@ -590,10 +595,33 @@ static int hls_slice_header(HEVCContext *s) sh->num_entry_point_offsets = get_ue_golomb_long(gb); if (sh->num_entry_point_offsets > 0) { int offset_len = get_ue_golomb_long(gb) + 1; - - for (i = 0; i < sh->num_entry_point_offsets; i++) - skip_bits(gb, offset_len); - } + int segments = offset_len >> 4; + int rest = (offset_len & 15); + av_freep(&sh->entry_point_offset); + av_freep(&sh->offset); + av_freep(&sh->size); + sh->entry_point_offset = av_malloc(sh->num_entry_point_offsets * sizeof(int)); + sh->offset = av_malloc(sh->num_entry_point_offsets * sizeof(int)); + sh->size = av_malloc(sh->num_entry_point_offsets * sizeof(int)); + for (i = 0; i < sh->num_entry_point_offsets; i++) { + int val = 0; + for (j = 0; j < segments; j++) { + val <<= 16; + val += get_bits(gb, 16); + } + if (rest) { + val <<= rest; + val += get_bits(gb, rest); + } + sh->entry_point_offset[i] = val + 1; // +1; // +1 to get the size + } + if (s->threads_number > 1 && (s->pps->num_tile_rows > 1 || s->pps->num_tile_columns > 1)) { + s->enable_parallel_tiles = 0; // TODO: you can enable tiles in parallel here + s->threads_number = 1; + } else + s->enable_parallel_tiles = 0; + } else + s->enable_parallel_tiles = 0; } if (s->pps->slice_header_extension_present_flag) { @@ -606,10 +634,10 @@ static int hls_slice_header(HEVCContext *s) sh->slice_qp = 26 + s->pps->pic_init_qp_minus26 + sh->slice_qp_delta; sh->slice_ctb_addr_rs = sh->slice_segment_addr; - s->HEVClc.first_qp_group = !s->sh.dependent_slice_segment_flag; + s->HEVClc->first_qp_group = !s->sh.dependent_slice_segment_flag; if (!s->pps->cu_qp_delta_enabled_flag) - s->HEVClc.qp_y = ((s->sh.slice_qp + 52 + 2 * s->sps->qp_bd_offset) % + s->HEVClc->qp_y = ((s->sh.slice_qp + 52 + 2 * s->sps->qp_bd_offset) % (52 + s->sps->qp_bd_offset)) - s->sps->qp_bd_offset; s->slice_initialized = 1; @@ -633,7 +661,7 @@ do { \ static void hls_sao_param(HEVCContext *s, int rx, int ry) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int sao_merge_left_flag = 0; int sao_merge_up_flag = 0; int shift = s->sps->bit_depth - FFMIN(s->sps->bit_depth, 10); @@ -705,7 +733,7 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry) static void hls_transform_unit(HEVCContext *s, int x0, int y0, int xBase, int yBase, int cb_xBase, int cb_yBase, int log2_cb_size, int log2_trafo_size, int trafo_depth, int blk_idx) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int scan_idx = SCAN_DIAG; int scan_idx_c = SCAN_DIAG; @@ -791,7 +819,7 @@ static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_si static void hls_transform_tree(HEVCContext *s, int x0, int y0, int xBase, int yBase, int cb_xBase, int cb_yBase, int log2_cb_size, int log2_trafo_size, int trafo_depth, int blk_idx) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; uint8_t split_transform_flag; if (trafo_depth > 0 && log2_trafo_size == 2) { @@ -889,7 +917,7 @@ static void hls_transform_tree(HEVCContext *s, int x0, int y0, int xBase, int yB static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size) { //TODO: non-4:2:0 support - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; GetBitContext gb; int cb_size = 1 << log2_cb_size; int stride0 = s->frame->linesize[0]; @@ -900,7 +928,7 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size) uint8_t *dst2 = &s->frame->data[2][(y0 >> s->sps->vshift[2]) * stride2 + ((x0 >> s->sps->hshift[2]) << s->sps->pixel_shift)]; int length = cb_size * cb_size * s->sps->pcm.bit_depth + ((cb_size * cb_size) >> 1) * s->sps->pcm.bit_depth; - const uint8_t *pcm = skip_bytes(&s->HEVClc.cc, (length + 7) >> 3); + const uint8_t *pcm = skip_bytes(&s->HEVClc->cc, (length + 7) >> 3); int ret; ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size, @@ -933,7 +961,7 @@ static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size) static void luma_mc(HEVCContext *s, int16_t *dst, ptrdiff_t dststride, AVFrame *ref, const Mv *mv, int x_off, int y_off, int block_w, int block_h) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; uint8_t *src = ref->data[0]; ptrdiff_t srcstride = ref->linesize[0]; int pic_width = s->sps->width; @@ -979,7 +1007,7 @@ static void luma_mc(HEVCContext *s, int16_t *dst, ptrdiff_t dststride, AVFrame * static void chroma_mc(HEVCContext *s, int16_t *dst1, int16_t *dst2, ptrdiff_t dststride, AVFrame *ref, const Mv *mv, int x_off, int y_off, int block_w, int block_h) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; uint8_t *src1 = ref->data[1]; uint8_t *src2 = ref->data[2]; ptrdiff_t src1stride = ref->linesize[1]; @@ -1030,7 +1058,8 @@ static void hevc_await_progress(HEVCContext *s, HEVCFrame *ref, int y = (mv->y >> 2) + y0; //ff_thread_await_progress(&ref->tf, FFMIN(s->height, y), 0); - ff_thread_await_progress(&ref->tf, INT_MAX, 0); + if (s->threads_type == FF_THREAD_FRAME ) + ff_thread_await_progress(&ref->tf, INT_MAX, 0); } static void hls_prediction_unit(HEVCContext *s, int x0, int y0, int nPbW, int nPbH, int log2_cb_size, int partIdx) @@ -1038,7 +1067,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, int nPbW, int nP #define POS(c_idx, x, y) \ &s->frame->data[c_idx][((y) >> s->sps->vshift[c_idx]) * s->frame->linesize[c_idx] + \ (((x) >> s->sps->hshift[c_idx]) << s->sps->pixel_shift)] - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int merge_idx = 0; enum InterPredIdc inter_pred_idc = PRED_L0; struct MvField current_mv = {{{ 0 }}}; @@ -1288,7 +1317,7 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, int nPbW, int nP static int luma_intra_pred_mode(HEVCContext *s, int x0, int y0, int pu_size, int prev_intra_luma_pred_flag) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int x_pu = x0 >> s->sps->log2_min_pu_size; int y_pu = y0 >> s->sps->log2_min_pu_size; int pic_width_in_min_pu = s->sps->width >> s->sps->log2_min_pu_size; @@ -1386,7 +1415,7 @@ static av_always_inline void set_ct_depth(HEVCContext *s, int x0, int y0, static void intra_prediction_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; static const uint8_t intra_chroma_table[4] = {0, 26, 10, 1}; uint8_t prev_intra_luma_pred_flag[4]; int split = lc->cu.part_mode == PART_NxN; @@ -1425,7 +1454,7 @@ static void intra_prediction_unit(HEVCContext *s, int x0, int y0, int log2_cb_si static void intra_prediction_unit_default_value(HEVCContext *s, int x0, int y0, int log2_cb_size) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int pb_size = 1 << log2_cb_size; int size_in_pus = pb_size >> s->sps->log2_min_pu_size; int pic_width_in_min_pu = s->sps->width >> s->sps->log2_min_pu_size; @@ -1446,7 +1475,7 @@ static void intra_prediction_unit_default_value(HEVCContext *s, int x0, int y0, static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) { int cb_size = 1 << log2_cb_size; - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int log2_min_cb_size = s->sps->log2_min_coding_block_size; int length = cb_size >> log2_min_cb_size; int pic_width_in_ctb = s->sps->width >> log2_min_cb_size; @@ -1595,7 +1624,7 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) static int hls_coding_quadtree(HEVCContext *s, int x0, int y0, int log2_cb_size, int cb_depth) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int ret; lc->ct.depth = cb_depth; @@ -1663,7 +1692,7 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0, int log2_cb_size, static void hls_decode_neighbour(HEVCContext *s, int x_ctb, int y_ctb, int ctb_addr_ts) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int ctb_size = 1 << s->sps->log2_ctb_size; int ctb_addr_rs = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts]; int ctb_addr_in_slice = ctb_addr_rs - s->sh.slice_addr; @@ -1716,8 +1745,9 @@ static void hls_decode_neighbour(HEVCContext *s, int x_ctb, int y_ctb, int ctb_a lc->ctb_up_left_flag = ((x_ctb > 0) && (y_ctb > 0) && (ctb_addr_in_slice-1 >= s->sps->ctb_width) && (s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs-1 - s->sps->ctb_width]])); } -static int hls_slice_data(HEVCContext *s) +static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread) { + HEVCContext *s = avctxt->priv_data; int ctb_size = 1 << s->sps->log2_ctb_size; int more_data = 1; int x_ctb = 0; @@ -1755,13 +1785,175 @@ static int hls_slice_data(HEVCContext *s) return ctb_addr_ts; } +static int hls_slice_data(HEVCContext *s) +{ + int arg[2]; + int ret[2]; + + arg[0] = 0; + arg[1] = 1; + + s->avctx->execute(s->avctx, hls_decode_entry, arg, ret , 1, sizeof(int)); + return ret[0]; +} +static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int job, int self_id) +{ + HEVCContext *s1 = avctxt->priv_data, *s; + HEVCLocalContext *lc; + int ctb_size = 1<< s1->sps->log2_ctb_size; + int more_data = 1; + int *ctb_row_p = input_ctb_row; + int ctb_row = ctb_row_p[job]; + int ctb_addr_rs = s1->sh.slice_ctb_addr_rs + ctb_row * ((s1->sps->width + ctb_size - 1) >> s1->sps->log2_ctb_size); + int ctb_addr_ts = s1->pps->ctb_addr_rs_to_ts[ctb_addr_rs]; + int thread = ctb_row % s1->threads_number; + int ret; + + s = s1->sList[self_id]; + lc = s->HEVClc; + + if(ctb_row) { + ret = init_get_bits8(&lc->gb, s->data + s->sh.offset[ctb_row - 1], s->sh.size[ctb_row - 1]); + + if (ret < 0) + return ret; + ff_init_cabac_decoder(&lc->cc, s->data + s->sh.offset[(ctb_row)-1], s->sh.size[ctb_row - 1]); + } + + while(more_data && ctb_addr_ts < s->sps->ctb_size) { + int x_ctb = (ctb_addr_rs % s->sps->ctb_width) << s->sps->log2_ctb_size; + int y_ctb = (ctb_addr_rs / s->sps->ctb_width) << s->sps->log2_ctb_size; + + hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts); + + ff_thread_await_progress2(s->avctx, ctb_row, thread, SHIFT_CTB_WPP); + + if (avpriv_atomic_int_get(&s1->wpp_err)){ + ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP); + return 0; + } + + ff_hevc_cabac_init(s, ctb_addr_ts); + hls_sao_param(s, x_ctb >> s->sps->log2_ctb_size, y_ctb >> s->sps->log2_ctb_size); + more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->sps->log2_ctb_size, 0); + + if (more_data < 0) + return more_data; + + ctb_addr_ts++; + + ff_hevc_save_states(s, ctb_addr_ts); + ff_thread_report_progress2(s->avctx, ctb_row, thread, 1); + ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size); + + if (!more_data && (x_ctb+ctb_size) < s->sps->width && ctb_row != s->sh.num_entry_point_offsets) { + avpriv_atomic_int_set(&s1->wpp_err, 1); + ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); + return 0; + } + + if ((x_ctb+ctb_size) >= s->sps->width && (y_ctb+ctb_size) >= s->sps->height ) { + ff_hevc_hls_filter(s, x_ctb, y_ctb); + ff_thread_report_progress2(s->avctx, ctb_row , thread, SHIFT_CTB_WPP); + return ctb_addr_ts; + } + ctb_addr_rs = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts]; + x_ctb+=ctb_size; + + if(x_ctb >= s->sps->width) { + break; + } + } + ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); + + return 0; +} + +static int hls_slice_data_wpp(HEVCContext *s, const uint8_t *nal, int length) +{ + HEVCLocalContext *lc = s->HEVClc; + int *ret = av_malloc((s->sh.num_entry_point_offsets + 1) * sizeof(int)); + int *arg = av_malloc((s->sh.num_entry_point_offsets + 1) * sizeof(int)); + int offset; + int startheader, cmpt = 0; + int i, j, res = 0; + + + if (!s->sList[1]) { + ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1); + + + for (i = 1; i < s->threads_number; i++) { + s->sList[i] = av_malloc(sizeof(HEVCContext)); + memcpy(s->sList[i], s, sizeof(HEVCContext)); + s->HEVClcList[i] = av_malloc(sizeof(HEVCLocalContext)); + s->HEVClcList[i]->edge_emu_buffer = av_malloc((MAX_PB_SIZE + 7) * s->frame->linesize[0]); + s->sList[i]->HEVClc = s->HEVClcList[i]; + } + } + + offset = (lc->gb.index >> 3); + + for (j = 0, cmpt = 0, startheader = offset + s->sh.entry_point_offset[0]; j < s->skipped_bytes; j++) { + if (s->skipped_bytes_pos[j] >= offset && s->skipped_bytes_pos[j] < startheader) { + startheader--; + cmpt++; + } + } + + for (i = 1; i < s->sh.num_entry_point_offsets; i++) { + offset += (s->sh.entry_point_offset[i - 1] - cmpt); + for (j = 0, cmpt = 0, startheader = offset + + s->sh.entry_point_offset[i]; j < s->skipped_bytes; j++) { + if (s->skipped_bytes_pos[j] >= offset && s->skipped_bytes_pos[j] < startheader) { + startheader--; + cmpt++; + } + } + s->sh.size[i - 1] = s->sh.entry_point_offset[i] - cmpt; + s->sh.offset[i - 1] = offset; + + } + if (s->sh.num_entry_point_offsets != 0) { + offset += s->sh.entry_point_offset[s->sh.num_entry_point_offsets - 1] - cmpt; + s->sh.size[s->sh.num_entry_point_offsets - 1] = length - offset; + s->sh.offset[s->sh.num_entry_point_offsets - 1] = offset; + + } + s->data = nal; + + for (i = 1; i < s->threads_number; i++) { + s->sList[i]->HEVClc->first_qp_group = 1; + s->sList[i]->HEVClc->qp_y = s->sList[0]->HEVClc->qp_y; + memcpy(s->sList[i], s, sizeof(HEVCContext)); + s->sList[i]->HEVClc = s->HEVClcList[i]; + } + + avpriv_atomic_int_set(&s->wpp_err, 0); + ff_reset_entries(s->avctx); + + for (i = 0; i <= s->sh.num_entry_point_offsets; i++) { + arg[i] = i; + ret[i] = 0; + } + + if (s->pps->entropy_coding_sync_enabled_flag) + s->avctx->execute2(s->avctx, (void *) hls_decode_entry_wpp, arg, ret, s->sh.num_entry_point_offsets + 1); + + for (i = 0; i <= s->sh.num_entry_point_offsets; i++) + res += ret[i]; + av_free(ret); + av_free(arg); + return res; +} + /** * @return AVERROR_INVALIDDATA if the packet is not a valid NAL unit, * 0 if the unit should be skipped, 1 otherwise */ static int hls_nal_unit(HEVCContext *s) { - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; int nuh_layer_id; if (get_bits1(gb) != 0) @@ -1812,7 +2004,7 @@ static void restore_tqb_pixels(HEVCContext *s) static int hevc_frame_start(HEVCContext *s) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int pic_width_in_min_pu = s->sps->width >> s->sps->log2_min_pu_size; int pic_height_in_min_pu = s->sps->height >> s->sps->log2_min_pu_size; int pic_width_in_min_tu = s->sps->width >> s->sps->log2_min_transform_block_size; @@ -1857,7 +2049,7 @@ static int hevc_frame_start(HEVCContext *s) return 0; fail: - if (s->ref) + if (s->ref && s->threads_type == FF_THREAD_FRAME) ff_thread_report_progress(&s->ref->tf, INT_MAX, 0); s->ref = NULL; return ret; @@ -1865,7 +2057,7 @@ fail: static int decode_nal_unit(HEVCContext *s, const uint8_t *nal, int length) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; GetBitContext *gb = &lc->gb; int ctb_addr_ts; int ret; @@ -1967,7 +2159,11 @@ static int decode_nal_unit(HEVCContext *s, const uint8_t *nal, int length) } } - ctb_addr_ts = hls_slice_data(s); + if (s->threads_number > 1 && s->sh.num_entry_point_offsets > 0) + ctb_addr_ts = hls_slice_data_wpp(s, nal, length); + else + ctb_addr_ts = hls_slice_data(s); + if (ctb_addr_ts >= (s->sps->ctb_width * s->sps->ctb_height)) { s->is_decoded = 1; if ((s->pps->transquant_bypass_enable_flag || @@ -1996,12 +2192,13 @@ static int decode_nal_unit(HEVCContext *s, const uint8_t *nal, int length) /* FIXME: This is adapted from ff_h264_decode_nal, avoiding duplication between these functions would be nice. */ -static int extract_rbsp(const uint8_t *src, int length, +static int extract_rbsp(HEVCContext *s, const uint8_t *src, int length, HEVCNAL *nal) { int i, si, di; uint8_t *dst; + s->skipped_bytes = 0; #define STARTCODE_TEST \ if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \ if (src[i + 2] != 3) { \ @@ -2073,6 +2270,16 @@ static int extract_rbsp(const uint8_t *src, int length, dst[di++] = 0; si += 3; + s->skipped_bytes++; + if (s->skipped_bytes_pos_size < s->skipped_bytes) { + s->skipped_bytes_pos_size *= 2; + av_reallocp_array(&s->skipped_bytes_pos, + s->skipped_bytes_pos_size, + sizeof(*s->skipped_bytes_pos)); + if (!s->skipped_bytes_pos) + return NULL; + } + s->skipped_bytes_pos[s->skipped_bytes-1] = di - 1; continue; } else // next start code goto nsc; @@ -2144,17 +2351,30 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) } s->nals = tmp; memset(s->nals + s->nals_allocated, 0, (new_size - s->nals_allocated) * sizeof(*tmp)); + av_reallocp_array(&s->skipped_bytes_nal, new_size, sizeof(*s->skipped_bytes_nal)); + av_reallocp_array(&s->skipped_bytes_pos_size_nal, new_size, sizeof(*s->skipped_bytes_pos_size_nal)); + av_reallocp_array(&s->skipped_bytes_pos_nal, new_size, sizeof(*s->skipped_bytes_pos_nal)); + s->skipped_bytes_pos_size_nal[s->nals_allocated] = 1024; // initial buffer size + s->skipped_bytes_pos_nal[s->nals_allocated] = av_malloc_array(s->skipped_bytes_pos_size_nal[s->nals_allocated], sizeof(*s->skipped_bytes_pos)); s->nals_allocated = new_size; } - nal = &s->nals[s->nb_nals++]; + s->skipped_bytes_pos_size = s->skipped_bytes_pos_size_nal[s->nb_nals]; + s->skipped_bytes_pos = s->skipped_bytes_pos_nal[s->nb_nals]; + nal = &s->nals[s->nb_nals]; + + consumed = extract_rbsp(s, buf, extract_length, nal); + + s->skipped_bytes_nal[s->nb_nals] = s->skipped_bytes; + s->skipped_bytes_pos_size_nal[s->nb_nals] = s->skipped_bytes_pos_size; + s->skipped_bytes_pos_nal[s->nb_nals++] = s->skipped_bytes_pos; + - consumed = extract_rbsp(buf, extract_length, nal); if (consumed < 0) { ret = consumed; goto fail; } - ret = init_get_bits8(&s->HEVClc.gb, nal->data, nal->size); + ret = init_get_bits8(&s->HEVClc->gb, nal->data, nal->size); if (ret < 0) goto fail; hls_nal_unit(s); @@ -2168,7 +2388,11 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) /* parse the NAL units */ for (i = 0; i < s->nb_nals; i++) { - int ret = decode_nal_unit(s, s->nals[i].data, s->nals[i].size); + int ret; + s->skipped_bytes = s->skipped_bytes_nal[i]; + s->skipped_bytes_pos = s->skipped_bytes_pos_nal[i]; + + ret = decode_nal_unit(s, s->nals[i].data, s->nals[i].size); if (ret < 0) { av_log(s->avctx, AV_LOG_WARNING, "Error parsing NAL unit #%d.\n", i); if (s->avctx->err_recognition & AV_EF_EXPLODE) @@ -2177,7 +2401,7 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) } fail: - if (s->ref) + if (s->ref && s->threads_type == FF_THREAD_FRAME) ff_thread_report_progress(&s->ref->tf, INT_MAX, 0); return ret; @@ -2337,7 +2561,7 @@ fail: static av_cold int hevc_decode_free(AVCodecContext *avctx) { HEVCContext *s = avctx->priv_data; - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int i; pic_arrays_free(s); @@ -2345,6 +2569,15 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) av_freep(&lc->edge_emu_buffer); av_freep(&s->md5_ctx); + for(i=0; i < s->nals_allocated; i++) { + av_freep(&s->skipped_bytes_pos_nal[i]); + } + av_freep(&s->skipped_bytes_pos_size_nal); + av_freep(&s->skipped_bytes_nal); + av_freep(&s->skipped_bytes_pos_nal); + + av_freep(&s->cabac_state); + av_frame_free(&s->tmp_frame); av_frame_free(&s->output_frame); @@ -2360,6 +2593,21 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++) av_buffer_unref(&s->pps_list[i]); + av_freep(&s->sh.entry_point_offset); + av_freep(&s->sh.offset); + av_freep(&s->sh.size); + + for (i = 1; i < s->threads_number; i++) { + lc = s->HEVClcList[i]; + if (lc) { + av_freep(&lc->edge_emu_buffer); + + av_freep(&s->HEVClcList[i]); + av_freep(&s->sList[i]); + } + } + av_freep(&s->HEVClcList[0]); + for (i = 0; i < s->nals_allocated; i++) av_freep(&s->nals[i].rbsp_buffer); av_freep(&s->nals); @@ -2375,6 +2623,16 @@ static av_cold int hevc_init_context(AVCodecContext *avctx) s->avctx = avctx; + s->HEVClc = av_mallocz(sizeof(HEVCLocalContext)); + if (!s->HEVClc) + goto fail; + s->HEVClcList[0] = s->HEVClc; + s->sList[0] = s; + + s->cabac_state = av_malloc(HEVC_CONTEXTS); + if (!s->cabac_state) + goto fail; + s->tmp_frame = av_frame_alloc(); if (!s->tmp_frame) goto fail; @@ -2454,6 +2712,8 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->is_nalff = s0->is_nalff; s->nal_length_size = s0->nal_length_size; + s->threads_number = s0->threads_number; + s->threads_type = s0->threads_type; if (s0->eos) { s->seq_decode = (s->seq_decode + 1) & 0xff; @@ -2538,6 +2798,13 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) if (ret < 0) return ret; + s->enable_parallel_tiles = 0; + + if(avctx->active_thread_type & FF_THREAD_SLICE) + s->threads_number = avctx->thread_count; + else + s->threads_number = 1; + if (avctx->extradata_size > 0 && avctx->extradata) { ret = hevc_decode_extradata(s); if (ret < 0) { @@ -2546,6 +2813,11 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) } } + if((avctx->active_thread_type & FF_THREAD_FRAME) && avctx->thread_count > 1) + s->threads_type = FF_THREAD_FRAME; + else + s->threads_type = FF_THREAD_SLICE; + return 0; } @@ -2598,5 +2870,5 @@ AVCodec ff_hevc_decoder = { .flush = hevc_decode_flush, .update_thread_context = hevc_update_thread_context, .init_thread_copy = hevc_init_thread_copy, - .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_FRAME_THREADS | CODEC_CAP_EXPERIMENTAL, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS | CODEC_CAP_EXPERIMENTAL, }; diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 000ccd46d6..01db69b74b 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -39,6 +39,9 @@ #define MAX_DPB_SIZE 16 // A.4.1 #define MAX_REFS 16 +#define MAX_NB_THREADS 16 +#define SHIFT_CTB_WPP 2 + /** * 7.4.2.1 */ @@ -563,6 +566,9 @@ typedef struct SliceHeader { uint8_t slice_loop_filter_across_slices_enabled_flag; + int *entry_point_offset; + int * offset; + int * size; int num_entry_point_offsets; uint8_t luma_log2_weight_denom; @@ -705,14 +711,6 @@ typedef struct HEVCFrame { AVBufferRef *rpl_buf; } HEVCFrame; -typedef struct FilterData { - int x; - int y; - int size; - int slice_or_tiles_left_boundary; - int slice_or_tiles_up_boundary; -} FilterData; - typedef struct HEVCNAL { uint8_t *rbsp_buffer; int rbsp_buffer_size; @@ -745,20 +743,24 @@ typedef struct HEVCLocalContext { PredictionUnit pu; NeighbourAvailable na; DECLARE_ALIGNED(16, int16_t, mc_buffer[(MAX_PB_SIZE + 7) * MAX_PB_SIZE]); - FilterData *save_boundary_strengths; - int nb_saved; } HEVCLocalContext; typedef struct HEVCContext { const AVClass *c; // needed by private avoptions AVCodecContext *avctx; - HEVCLocalContext HEVClc; + struct HEVCContext *sList[MAX_NB_THREADS]; + + HEVCLocalContext *HEVClcList[MAX_NB_THREADS]; + HEVCLocalContext *HEVClc; + + uint8_t threads_type; + uint8_t threads_number; int width; int height; - uint8_t cabac_state[HEVC_CONTEXTS]; + uint8_t *cabac_state; AVFrame *frame; AVFrame *sao_frame; @@ -826,6 +828,18 @@ typedef struct HEVCContext { uint16_t seq_decode; uint16_t seq_output; + int enable_parallel_tiles; + int wpp_err; + int skipped_bytes; + int *skipped_bytes_pos; + int skipped_bytes_pos_size; + + int *skipped_bytes_nal; + int **skipped_bytes_pos_nal; + int *skipped_bytes_pos_size_nal; + + uint8_t *data; + HEVCNAL *nals; int nb_nals; int nals_allocated; diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index e6cbf1a4ce..2f6d0addde 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -507,13 +507,13 @@ void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts) ((ctb_addr_ts % s->sps->ctb_width) == 2 || (s->sps->ctb_width == 2 && (ctb_addr_ts % s->sps->ctb_width) == 0))) { - memcpy(s->cabac_state, s->HEVClc.cabac_state, HEVC_CONTEXTS); + memcpy(s->cabac_state, s->HEVClc->cabac_state, HEVC_CONTEXTS); } } static void load_states(HEVCContext *s) { - memcpy(s->HEVClc.cabac_state, s->cabac_state, HEVC_CONTEXTS); + memcpy(s->HEVClc->cabac_state, s->cabac_state, HEVC_CONTEXTS); } static void cabac_reinit(HEVCLocalContext *lc) @@ -523,10 +523,10 @@ static void cabac_reinit(HEVCLocalContext *lc) static void cabac_init_decoder(HEVCContext *s) { - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; skip_bits(gb, 1); align_get_bits(gb); - ff_init_cabac_decoder(&s->HEVClc.cc, + ff_init_cabac_decoder(&s->HEVClc->cc, gb->buffer + get_bits_count(gb) / 8, (get_bits_left(gb) + 7) / 8); } @@ -548,7 +548,7 @@ static void cabac_init_state(HEVCContext *s) pre ^= pre >> 31; if (pre > 124) pre = 124 + (pre & 1); - s->HEVClc.cabac_state[i] = pre; + s->HEVClc->cabac_state[i] = pre; } } @@ -572,13 +572,19 @@ void ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) } else { if (s->pps->tiles_enabled_flag && (s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1])) { - cabac_reinit(&s->HEVClc); + if (s->threads_number == 1) + cabac_reinit(s->HEVClc); + else + cabac_init_decoder(s); cabac_init_state(s); } if (s->pps->entropy_coding_sync_enabled_flag) { if ((ctb_addr_ts % s->sps->ctb_width) == 0) { - get_cabac_terminate(&s->HEVClc.cc); - cabac_reinit(&s->HEVClc); + get_cabac_terminate(&s->HEVClc->cc); + if (s->threads_number == 1) + cabac_reinit(s->HEVClc); + else + cabac_init_decoder(s); if (s->sps->ctb_width == 1) cabac_init_state(s); @@ -589,7 +595,7 @@ void ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) } } -#define GET_CABAC(ctx) get_cabac(&s->HEVClc.cc, &s->HEVClc.cabac_state[ctx]) +#define GET_CABAC(ctx) get_cabac(&s->HEVClc->cc, &s->HEVClc->cabac_state[ctx]) int ff_hevc_sao_merge_flag_decode(HEVCContext *s) { @@ -601,7 +607,7 @@ int ff_hevc_sao_type_idx_decode(HEVCContext *s) if (!GET_CABAC(elem_offset[SAO_TYPE_IDX])) return 0; - if (!get_cabac_bypass(&s->HEVClc.cc)) + if (!get_cabac_bypass(&s->HEVClc->cc)) return SAO_BAND; return SAO_EDGE; } @@ -609,10 +615,10 @@ int ff_hevc_sao_type_idx_decode(HEVCContext *s) int ff_hevc_sao_band_position_decode(HEVCContext *s) { int i; - int value = get_cabac_bypass(&s->HEVClc.cc); + int value = get_cabac_bypass(&s->HEVClc->cc); for (i = 0; i < 4; i++) - value = (value << 1) | get_cabac_bypass(&s->HEVClc.cc); + value = (value << 1) | get_cabac_bypass(&s->HEVClc->cc); return value; } @@ -621,26 +627,26 @@ int ff_hevc_sao_offset_abs_decode(HEVCContext *s) int i = 0; int length = (1 << (FFMIN(s->sps->bit_depth, 10) - 5)) - 1; - while (i < length && get_cabac_bypass(&s->HEVClc.cc)) + while (i < length && get_cabac_bypass(&s->HEVClc->cc)) i++; return i; } int ff_hevc_sao_offset_sign_decode(HEVCContext *s) { - return get_cabac_bypass(&s->HEVClc.cc); + return get_cabac_bypass(&s->HEVClc->cc); } int ff_hevc_sao_eo_class_decode(HEVCContext *s) { - int ret = (get_cabac_bypass(&s->HEVClc.cc) << 1); - ret |= get_cabac_bypass(&s->HEVClc.cc); + int ret = (get_cabac_bypass(&s->HEVClc->cc) << 1); + ret |= get_cabac_bypass(&s->HEVClc->cc); return ret; } int ff_hevc_end_of_slice_flag_decode(HEVCContext *s) { - return get_cabac_terminate(&s->HEVClc.cc); + return get_cabac_terminate(&s->HEVClc->cc); } int ff_hevc_cu_transquant_bypass_flag_decode(HEVCContext *s) @@ -655,9 +661,9 @@ int ff_hevc_skip_flag_decode(HEVCContext *s, int x0, int y0, int x_cb, int y_cb) int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1); int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1); - if (s->HEVClc.ctb_left_flag || x0b) + if (s->HEVClc->ctb_left_flag || x0b) inc = SAMPLE_CTB(s->skip_flag, x_cb-1, y_cb); - if (s->HEVClc.ctb_up_flag || y0b) + if (s->HEVClc->ctb_up_flag || y0b) inc += SAMPLE_CTB(s->skip_flag, x_cb, y_cb-1); return GET_CABAC(elem_offset[SKIP_FLAG] + inc); @@ -675,7 +681,7 @@ int ff_hevc_cu_qp_delta_abs(HEVCContext *s) } if (prefix_val >= 5) { int k = 0; - while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc.cc)) { + while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) { suffix_val += 1 << k; k++; } @@ -683,14 +689,14 @@ int ff_hevc_cu_qp_delta_abs(HEVCContext *s) av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k); while (k--) - suffix_val += get_cabac_bypass(&s->HEVClc.cc) << k; + suffix_val += get_cabac_bypass(&s->HEVClc->cc) << k; } return prefix_val + suffix_val; } int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s) { - return get_cabac_bypass(&s->HEVClc.cc); + return get_cabac_bypass(&s->HEVClc->cc); } int ff_hevc_pred_mode_decode(HEVCContext *s) @@ -706,9 +712,9 @@ int ff_hevc_split_coding_unit_flag_decode(HEVCContext *s, int ct_depth, int x0, int x_cb = x0 >> s->sps->log2_min_coding_block_size; int y_cb = y0 >> s->sps->log2_min_coding_block_size; - if (s->HEVClc.ctb_left_flag || x0b) + if (s->HEVClc->ctb_left_flag || x0b) depth_left = s->tab_ct_depth[(y_cb)*s->sps->min_cb_width + x_cb-1]; - if (s->HEVClc.ctb_up_flag || y0b) + if (s->HEVClc->ctb_up_flag || y0b) depth_top = s->tab_ct_depth[(y_cb-1)*s->sps->min_cb_width + x_cb]; inc += (depth_left > ct_depth); @@ -721,7 +727,7 @@ int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size) if (GET_CABAC(elem_offset[PART_MODE])) // 1 return PART_2Nx2N; if (log2_cb_size == s->sps->log2_min_coding_block_size) { - if (s->HEVClc.cu.pred_mode == MODE_INTRA) // 0 + if (s->HEVClc->cu.pred_mode == MODE_INTRA) // 0 return PART_NxN; if (GET_CABAC(elem_offset[PART_MODE] + 1)) // 01 return PART_2NxN; @@ -741,21 +747,21 @@ int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size) if (GET_CABAC(elem_offset[PART_MODE] + 1)) { // 01X, 01XX if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 011 return PART_2NxN; - if (get_cabac_bypass(&s->HEVClc.cc)) // 0101 + if (get_cabac_bypass(&s->HEVClc->cc)) // 0101 return PART_2NxnD; return PART_2NxnU; // 0100 } if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 001 return PART_Nx2N; - if (get_cabac_bypass(&s->HEVClc.cc)) // 0001 + if (get_cabac_bypass(&s->HEVClc->cc)) // 0001 return PART_nRx2N; return PART_nLx2N; // 0000 } int ff_hevc_pcm_flag_decode(HEVCContext *s) { - return get_cabac_terminate(&s->HEVClc.cc); + return get_cabac_terminate(&s->HEVClc->cc); } int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCContext *s) @@ -766,7 +772,7 @@ int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCContext *s) int ff_hevc_mpm_idx_decode(HEVCContext *s) { int i = 0; - while (i < 2 && get_cabac_bypass(&s->HEVClc.cc)) + while (i < 2 && get_cabac_bypass(&s->HEVClc->cc)) i++; return i; } @@ -774,10 +780,10 @@ int ff_hevc_mpm_idx_decode(HEVCContext *s) int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCContext *s) { int i; - int value = get_cabac_bypass(&s->HEVClc.cc); + int value = get_cabac_bypass(&s->HEVClc->cc); for (i = 0; i < 4; i++) - value = (value << 1) | get_cabac_bypass(&s->HEVClc.cc); + value = (value << 1) | get_cabac_bypass(&s->HEVClc->cc); return value; } @@ -787,8 +793,8 @@ int ff_hevc_intra_chroma_pred_mode_decode(HEVCContext *s) if (!GET_CABAC(elem_offset[INTRA_CHROMA_PRED_MODE])) return 4; - ret = (get_cabac_bypass(&s->HEVClc.cc) << 1); - ret |= get_cabac_bypass(&s->HEVClc.cc); + ret = (get_cabac_bypass(&s->HEVClc->cc) << 1); + ret |= get_cabac_bypass(&s->HEVClc->cc); return ret; } @@ -797,7 +803,7 @@ int ff_hevc_merge_idx_decode(HEVCContext *s) int i = GET_CABAC(elem_offset[MERGE_IDX]); if (i != 0) { - while (i < s->sh.max_num_merge_cand-1 && get_cabac_bypass(&s->HEVClc.cc)) + while (i < s->sh.max_num_merge_cand-1 && get_cabac_bypass(&s->HEVClc->cc)) i++; } return i; @@ -812,7 +818,7 @@ int ff_hevc_inter_pred_idc_decode(HEVCContext *s, int nPbW, int nPbH) { if (nPbW + nPbH == 12) return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4); - if (GET_CABAC(elem_offset[INTER_PRED_IDC] + s->HEVClc.ct.depth)) + if (GET_CABAC(elem_offset[INTER_PRED_IDC] + s->HEVClc->ct.depth)) return PRED_BI; return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4); @@ -827,7 +833,7 @@ int ff_hevc_ref_idx_lx_decode(HEVCContext *s, int num_ref_idx_lx) while (i < max_ctx && GET_CABAC(elem_offset[REF_IDX_L0] + i)) i++; if (i == 2) { - while (i < max && get_cabac_bypass(&s->HEVClc.cc)) + while (i < max && get_cabac_bypass(&s->HEVClc->cc)) i++; } @@ -859,20 +865,20 @@ static av_always_inline int mvd_decode(HEVCContext *s) int ret = 2; int k = 1; - while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc.cc)) { + while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) { ret += 1 << k; k++; } if (k == CABAC_MAX_BIN) av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k); while (k--) - ret += get_cabac_bypass(&s->HEVClc.cc) << k; - return get_cabac_bypass_sign(&s->HEVClc.cc, -ret); + ret += get_cabac_bypass(&s->HEVClc->cc) << k; + return get_cabac_bypass_sign(&s->HEVClc->cc, -ret); } static av_always_inline int mvd_sign_flag_decode(HEVCContext *s) { - return get_cabac_bypass_sign(&s->HEVClc.cc, -1); + return get_cabac_bypass_sign(&s->HEVClc->cc, -1); } int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size) @@ -929,10 +935,10 @@ static av_always_inline int last_significant_coeff_suffix_decode(HEVCContext *s, { int i; int length = (last_significant_coeff_prefix >> 1) - 1; - int value = get_cabac_bypass(&s->HEVClc.cc); + int value = get_cabac_bypass(&s->HEVClc->cc); for (i = 1; i < length; i++) - value = (value << 1) | get_cabac_bypass(&s->HEVClc.cc); + value = (value << 1) | get_cabac_bypass(&s->HEVClc->cc); return value; } @@ -1021,18 +1027,18 @@ static av_always_inline int coeff_abs_level_remaining_decode(HEVCContext *s, int int last_coeff_abs_level_remaining; int i; - while (prefix < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc.cc)) + while (prefix < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) prefix++; if (prefix == CABAC_MAX_BIN) av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", prefix); if (prefix < 3) { for (i = 0; i < rc_rice_param; i++) - suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc.cc); + suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc->cc); last_coeff_abs_level_remaining = (prefix << rc_rice_param) + suffix; } else { int prefix_minus3 = prefix - 3; for (i = 0; i < prefix_minus3 + rc_rice_param; i++) - suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc.cc); + suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc->cc); last_coeff_abs_level_remaining = (((1 << prefix_minus3) + 3 - 1) << rc_rice_param) + suffix; } @@ -1045,7 +1051,7 @@ static av_always_inline int coeff_sign_flag_decode(HEVCContext *s, uint8_t nb) int ret = 0; for (i = 0; i < nb; i++) - ret = (ret << 1) | get_cabac_bypass(&s->HEVClc.cc); + ret = (ret << 1) | get_cabac_bypass(&s->HEVClc->cc); return ret; } @@ -1058,7 +1064,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, x_c = (scan_x_cg[offset >> 4] << 2) + scan_x_off[n]; \ y_c = (scan_y_cg[offset >> 4] << 2) + scan_y_off[n]; \ } while (0) - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int transform_skip_flag = 0; int last_significant_coeff_x, last_significant_coeff_y; @@ -1394,7 +1400,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, void ff_hevc_hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int x = abs_mvd_greater0_flag_decode(s); int y = abs_mvd_greater0_flag_decode(s); diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c index d67cdd5cba..84e21dcaa9 100644 --- a/libavcodec/hevc_filter.c +++ b/libavcodec/hevc_filter.c @@ -73,7 +73,7 @@ static int chroma_tc(HEVCContext *s, int qp_y, int c_idx, int tc_offset) static int get_qPy_pred(HEVCContext *s, int xC, int yC, int xBase, int yBase, int log2_cb_size) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int ctb_size_mask = (1 << s->sps->log2_ctb_size) - 1; int MinCuQpDeltaSizeMask = (1 << (s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth)) - 1; int xQgBase = xBase - ( xBase & MinCuQpDeltaSizeMask ); @@ -153,11 +153,11 @@ void ff_hevc_set_qPy(HEVCContext *s, int xC, int yC, int xBase, int yBase, int l { int qp_y = get_qPy_pred(s, xC, yC, xBase, yBase, log2_cb_size); - if (s->HEVClc.tu.cu_qp_delta != 0) { + if (s->HEVClc->tu.cu_qp_delta != 0) { int off = s->sps->qp_bd_offset; - s->HEVClc.qp_y = ((qp_y + s->HEVClc.tu.cu_qp_delta + 52 + 2 * off) % (52 + off)) - off; + s->HEVClc->qp_y = ((qp_y + s->HEVClc->tu.cu_qp_delta + 52 + 2 * off) % (52 + off)) - off; } else - s->HEVClc.qp_y = qp_y; + s->HEVClc->qp_y = qp_y; } static int get_qPy(HEVCContext *s, int xC, int yC) diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c index 701510903b..0b9286bd7b 100644 --- a/libavcodec/hevc_mvs.c +++ b/libavcodec/hevc_mvs.c @@ -40,7 +40,7 @@ static const uint8_t l0_l1_cand_idx[12][2] = { void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0, int nPbW, int nPbH) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1); int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1); @@ -98,7 +98,7 @@ static int check_prediction_block_available(HEVCContext *s, int log2_cb_size, int x0, int y0, int nPbW, int nPbH, int xA1, int yA1, int partIdx) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; if (lc->cu.x < xA1 && lc->cu.y < yA1 && (lc->cu.x + (1 << log2_cb_size)) > xA1 && @@ -272,7 +272,8 @@ static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0, xPRb = x0 + nPbW; yPRb = y0 + nPbH; - ff_thread_await_progress(&ref->tf, INT_MAX, 0); + if (s->threads_type == FF_THREAD_FRAME ) + ff_thread_await_progress(&ref->tf, INT_MAX, 0); if (tab_mvf && y0 >> s->sps->log2_ctb_size == yPRb >> s->sps->log2_ctb_size && yPRb < s->sps->height && @@ -322,7 +323,7 @@ static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0, int singleMCLFlag, int part_idx, struct MvField mergecandlist[]) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; RefPicList *refPicList = s->ref->refPicList; MvField *tab_mvf = s->ref->tab_mvf; @@ -707,7 +708,7 @@ void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW, struct MvField mergecand_list[MRG_MAX_NUM_CANDS] = { { { { 0 } } } }; int nPbW2 = nPbW; int nPbH2 = nPbH; - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; if (s->pps->log2_parallel_merge_level > 2 && nCS == 8) { singleMCLFlag = 1; @@ -794,7 +795,7 @@ void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW, int merge_idx, MvField *mv, int mvp_lx_flag, int LX) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; MvField *tab_mvf = s->ref->tab_mvf; int isScaledFlag_L0 = 0; int availableFlagLXA0 = 0; diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 20cb4eb4c3..3c13411f25 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -72,7 +72,7 @@ static const AVRational vui_sar[] = { int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps, const HEVCSPS *sps, int is_slice_header) { - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; uint8_t rps_predict = 0; int delta_poc; int k0 = 0; @@ -253,7 +253,7 @@ static void decode_hrd(HEVCContext *s) int ff_hevc_decode_nal_vps(HEVCContext *s) { int i,j; - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; int vps_id = 0; VPS *vps; @@ -289,7 +289,7 @@ int ff_hevc_decode_nal_vps(HEVCContext *s) goto err; } - if (decode_profile_tier_level(&s->HEVClc, &vps->ptl, vps->vps_max_sub_layers) < 0) { + if (decode_profile_tier_level(s->HEVClc, &vps->ptl, vps->vps_max_sub_layers) < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error decoding profile tier level.\n"); goto err; } @@ -347,7 +347,7 @@ err: static void decode_vui(HEVCContext *s, HEVCSPS *sps) { VUI *vui = &sps->vui; - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; int sar_present; av_log(s->avctx, AV_LOG_DEBUG, "Decoding VUI\n"); @@ -469,7 +469,7 @@ static void set_default_scaling_list_data(ScalingList *sl) static int scaling_list_data(HEVCContext *s, ScalingList *sl) { - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; uint8_t scaling_list_pred_mode_flag[4][6]; int32_t scaling_list_dc_coef[2][6]; @@ -525,7 +525,7 @@ static int scaling_list_data(HEVCContext *s, ScalingList *sl) int ff_hevc_decode_nal_sps(HEVCContext *s) { const AVPixFmtDescriptor *desc; - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; int ret = 0; int sps_id = 0; int log2_diff_max_min_transform_block_size; @@ -559,7 +559,7 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) } skip_bits1(gb); // temporal_id_nesting_flag - if (decode_profile_tier_level(&s->HEVClc, &sps->ptl, sps->max_sub_layers) < 0) { + if (decode_profile_tier_level(s->HEVClc, &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; @@ -888,7 +888,7 @@ static void hevc_pps_free(void *opaque, uint8_t *data) int ff_hevc_decode_nal_pps(HEVCContext *s) { - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; HEVCSPS *sps = NULL; int pic_area_in_ctbs, pic_area_in_min_cbs, pic_area_in_min_tbs; int log2_diff_ctb_min_tb_size; diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index c4a3b461c1..ed17d2ac92 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -351,7 +351,8 @@ static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc) frame->sequence = s->seq_decode; frame->flags = 0; - ff_thread_report_progress(&frame->tf, INT_MAX, 0); + if (s->threads_type == FF_THREAD_FRAME) + ff_thread_report_progress(&frame->tf, INT_MAX, 0); return frame; } diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index abdbc001e1..1a964477de 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -31,7 +31,7 @@ static void decode_nal_sei_decoded_picture_hash(HEVCContext *s, int payload_size uint8_t hash_type; //uint16_t picture_crc; //uint32_t picture_checksum; - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; hash_type = get_bits(gb, 8); @@ -79,7 +79,7 @@ static void decode_nal_sei_frame_packing_arrangement(HEVCLocalContext *lc) static int decode_nal_sei_message(HEVCContext *s) { - GetBitContext *gb = &s->HEVClc.gb; + GetBitContext *gb = &s->HEVClc->gb; int payload_type = 0; int payload_size = 0; @@ -99,7 +99,7 @@ static int decode_nal_sei_message(HEVCContext *s) if (payload_type == 256 /*&& s->decode_checksum_sei*/) decode_nal_sei_decoded_picture_hash(s, payload_size); else if (payload_type == 45) - decode_nal_sei_frame_packing_arrangement(&s->HEVClc); + decode_nal_sei_frame_packing_arrangement(s->HEVClc); else { av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type); skip_bits(gb, 8*payload_size); @@ -124,6 +124,6 @@ int ff_hevc_decode_nal_sei(HEVCContext *s) { do { decode_nal_sei_message(s); - } while (more_rbsp_data(&s->HEVClc.gb)); + } while (more_rbsp_data(&s->HEVClc->gb)); return 0; } diff --git a/libavcodec/hevcpred_template.c b/libavcodec/hevcpred_template.c index 30f7a51181..969750675c 100644 --- a/libavcodec/hevcpred_template.c +++ b/libavcodec/hevcpred_template.c @@ -65,7 +65,7 @@ static void FUNC(intra_pred)(HEVCContext *s, int x0, int y0, int log2_size, int for (i = (start); i < (start) + (length); i++) \ if (!IS_INTRA(-1, i)) \ ptr[i] = ptr[i - 1] - HEVCLocalContext *lc = &s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; int i; int hshift = s->sps->hshift[c_idx]; int vshift = s->sps->vshift[c_idx]; |