if (!s->sao || !s->deblock)
goto fail;
- s->skip_flag = av_malloc(sps->min_cb_height * sps->min_cb_width);
+ s->skip_flag = av_malloc_array(sps->min_cb_height, sps->min_cb_width);
s->tab_ct_depth = av_malloc_array(sps->min_cb_height, sps->min_cb_width);
if (!s->skip_flag || !s->tab_ct_depth)
goto fail;
s->cbf_luma = av_malloc_array(sps->min_tb_width, sps->min_tb_height);
s->tab_ipm = av_mallocz(min_pu_size);
- s->is_pcm = av_malloc((sps->min_pu_width + 1) * (sps->min_pu_height + 1));
+ s->is_pcm = av_malloc_array(sps->min_pu_width + 1, sps->min_pu_height + 1);
if (!s->tab_ipm || !s->cbf_luma || !s->is_pcm)
goto fail;
luma_log2_weight_denom = get_ue_golomb_long(gb);
if (luma_log2_weight_denom < 0 || luma_log2_weight_denom > 7)
av_log(s->avctx, AV_LOG_ERROR, "luma_log2_weight_denom %d is invalid\n", luma_log2_weight_denom);
- s->sh.luma_log2_weight_denom = av_clip_c(luma_log2_weight_denom, 0, 7);
+ s->sh.luma_log2_weight_denom = av_clip(luma_log2_weight_denom, 0, 7);
if (s->sps->chroma_format_idc != 0) {
int delta = get_se_golomb(gb);
s->sh.chroma_log2_weight_denom = av_clip(s->sh.luma_log2_weight_denom + delta, 0, 7);
return 0;
}
-static int get_buffer_sao(HEVCContext *s, AVFrame *frame, const HEVCSPS *sps)
-{
- int ret, i;
-
- frame->width = s->avctx->coded_width + 2;
- frame->height = s->avctx->coded_height + 2;
- if ((ret = ff_get_buffer(s->avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
- return ret;
- for (i = 0; frame->data[i]; i++) {
- int offset = frame->linesize[i] + (1 << sps->pixel_shift);
- frame->data[i] += offset;
- }
- frame->width = s->avctx->coded_width;
- frame->height = s->avctx->coded_height;
-
- return 0;
-}
-
static int set_sps(HEVCContext *s, const HEVCSPS *sps)
{
- int ret;
+ #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL)
+ enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts;
+ int ret, i;
unsigned int num = 0, den = 0;
pic_arrays_free(s);
s->avctx->coded_height = sps->height;
s->avctx->width = sps->output_width;
s->avctx->height = sps->output_height;
- s->avctx->pix_fmt = sps->pix_fmt;
s->avctx->has_b_frames = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics;
+ if (sps->pix_fmt == AV_PIX_FMT_YUV420P || sps->pix_fmt == AV_PIX_FMT_YUVJ420P) {
+#if CONFIG_HEVC_DXVA2_HWACCEL
+ *fmt++ = AV_PIX_FMT_DXVA2_VLD;
+#endif
+ }
+
+ *fmt++ = sps->pix_fmt;
+ *fmt = AV_PIX_FMT_NONE;
+
+ ret = ff_thread_get_format(s->avctx, pix_fmts);
+ if (ret < 0)
+ goto fail;
+ s->avctx->pix_fmt = ret;
+
ff_set_sar(s->avctx, sps->vui.sar);
if (sps->vui.video_signal_type_present_flag)
ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth);
ff_videodsp_init (&s->vdsp, sps->bit_depth);
- if (sps->sao_enabled) {
- av_frame_unref(s->tmp_frame);
- ret = get_buffer_sao(s, s->tmp_frame, sps);
- s->sao_frame = s->tmp_frame;
+ for (i = 0; i < 3; i++) {
+ av_freep(&s->sao_pixel_buffer_h[i]);
+ av_freep(&s->sao_pixel_buffer_v[i]);
+ }
+
+ if (sps->sao_enabled && !s->avctx->hwaccel) {
+ int c_count = (sps->chroma_format_idc != 0) ? 3 : 1;
+ int c_idx;
+
+ for(c_idx = 0; c_idx < c_count; c_idx++) {
+ int w = sps->width >> sps->hshift[c_idx];
+ int h = sps->height >> sps->vshift[c_idx];
+ s->sao_pixel_buffer_h[c_idx] =
+ av_malloc((w * 2 * sps->ctb_height) <<
+ sps->pixel_shift);
+ s->sao_pixel_buffer_v[c_idx] =
+ av_malloc((h * 2 * sps->ctb_width) <<
+ sps->pixel_shift);
+ }
}
s->sps = sps;
sh->colour_plane_id = get_bits(gb, 2);
if (!IS_IDR(s)) {
- int short_term_ref_pic_set_sps_flag, poc;
+ int poc;
sh->pic_order_cnt_lsb = get_bits(gb, s->sps->log2_max_poc_lsb);
poc = ff_hevc_compute_poc(s, sh->pic_order_cnt_lsb);
}
s->poc = poc;
- short_term_ref_pic_set_sps_flag = get_bits1(gb);
- if (!short_term_ref_pic_set_sps_flag) {
+ sh->short_term_ref_pic_set_sps_flag = get_bits1(gb);
+ if (!sh->short_term_ref_pic_set_sps_flag) {
+ int pos = get_bits_left(gb);
ret = ff_hevc_decode_short_term_rps(s, &sh->slice_rps, s->sps, 1);
if (ret < 0)
return ret;
+ sh->short_term_ref_pic_set_size = pos - get_bits_left(gb);
sh->short_term_rps = &sh->slice_rps;
} else {
int numbits, rps_idx;
if (s->sps->sao_enabled) {
sh->slice_sample_adaptive_offset_flag[0] = get_bits1(gb);
- sh->slice_sample_adaptive_offset_flag[1] =
- sh->slice_sample_adaptive_offset_flag[2] = get_bits1(gb);
+ if (s->sps->chroma_format_idc) {
+ sh->slice_sample_adaptive_offset_flag[1] =
+ sh->slice_sample_adaptive_offset_flag[2] = get_bits1(gb);
+ }
} else {
sh->slice_sample_adaptive_offset_flag[0] = 0;
sh->slice_sample_adaptive_offset_flag[1] = 0;
}
}
- for (c_idx = 0; c_idx < 3; c_idx++) {
+ for (c_idx = 0; c_idx < (s->sps->chroma_format_idc ? 3 : 1); c_idx++) {
int log2_sao_offset_scale = c_idx == 0 ? s->pps->log2_sao_offset_scale_luma :
s->pps->log2_sao_offset_scale_chroma;
if (cbf_luma)
ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0);
- if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) {
+ if (s->sps->chroma_format_idc && (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3)) {
int trafo_size_h = 1 << (log2_trafo_size_c + s->sps->hshift[1]);
int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]);
lc->tu.cross_pf = (s->pps->cross_component_prediction_enabled_flag && cbf_luma &&
s->hevcdsp.transform_add[log2_trafo_size_c-2](dst, coeffs, stride);
}
}
- } else if (blk_idx == 3) {
+ } else if (s->sps->chroma_format_idc && blk_idx == 3) {
int trafo_size_h = 1 << (log2_trafo_size + 1);
int trafo_size_v = 1 << (log2_trafo_size + s->sps->vshift[1]);
for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {
log2_trafo_size, scan_idx_c, 2);
}
}
- } else if (lc->cu.pred_mode == MODE_INTRA) {
+ } else if (s->sps->chroma_format_idc && lc->cu.pred_mode == MODE_INTRA) {
if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) {
int trafo_size_h = 1 << (log2_trafo_size_c + s->sps->hshift[1]);
int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]);
inter_split;
}
- if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) {
+ if (s->sps->chroma_format_idc && (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3)) {
if (trafo_depth == 0 || cbf_cb[0]) {
cbf_cb[0] = ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
if (s->sps->chroma_format_idc == 2 && (!split_transform_flag || log2_trafo_size == 3)) {
return ret;
s->hevcdsp.put_pcm(dst0, stride0, cb_size, cb_size, &gb, s->sps->pcm.bit_depth);
- s->hevcdsp.put_pcm(dst1, stride1,
- cb_size >> s->sps->hshift[1],
- cb_size >> s->sps->vshift[1],
- &gb, s->sps->pcm.bit_depth_chroma);
- s->hevcdsp.put_pcm(dst2, stride2,
- cb_size >> s->sps->hshift[2],
- cb_size >> s->sps->vshift[2],
- &gb, s->sps->pcm.bit_depth_chroma);
+ if (s->sps->chroma_format_idc) {
+ s->hevcdsp.put_pcm(dst1, stride1,
+ cb_size >> s->sps->hshift[1],
+ cb_size >> s->sps->vshift[1],
+ &gb, s->sps->pcm.bit_depth_chroma);
+ s->hevcdsp.put_pcm(dst2, stride2,
+ cb_size >> s->sps->hshift[2],
+ cb_size >> s->sps->vshift[2],
+ &gb, s->sps->pcm.bit_depth_chroma);
+ }
+
return 0;
}
s->sh.luma_weight_l0[current_mv.ref_idx[0]],
s->sh.luma_offset_l0[current_mv.ref_idx[0]]);
- chroma_mc_uni(s, dst1, s->frame->linesize[1], ref0->frame->data[1], ref0->frame->linesize[1],
- 0, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
- s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0]);
- chroma_mc_uni(s, dst2, s->frame->linesize[2], ref0->frame->data[2], ref0->frame->linesize[2],
- 0, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
- s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1]);
+ if (s->sps->chroma_format_idc) {
+ chroma_mc_uni(s, dst1, s->frame->linesize[1], ref0->frame->data[1], ref0->frame->linesize[1],
+ 0, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
+ s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0]);
+ chroma_mc_uni(s, dst2, s->frame->linesize[2], ref0->frame->data[2], ref0->frame->linesize[2],
+ 0, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
+ s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1], s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1]);
+ }
} else if (current_mv.pred_flag == PF_L1) {
int x0_c = x0 >> s->sps->hshift[1];
int y0_c = y0 >> s->sps->vshift[1];
s->sh.luma_weight_l1[current_mv.ref_idx[1]],
s->sh.luma_offset_l1[current_mv.ref_idx[1]]);
- chroma_mc_uni(s, dst1, s->frame->linesize[1], ref1->frame->data[1], ref1->frame->linesize[1],
- 1, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
- s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0]);
+ if (s->sps->chroma_format_idc) {
+ chroma_mc_uni(s, dst1, s->frame->linesize[1], ref1->frame->data[1], ref1->frame->linesize[1],
+ 1, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
+ s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0]);
- chroma_mc_uni(s, dst2, s->frame->linesize[2], ref1->frame->data[2], ref1->frame->linesize[2],
- 1, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
- s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1]);
+ chroma_mc_uni(s, dst2, s->frame->linesize[2], ref1->frame->data[2], ref1->frame->linesize[2],
+ 1, x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv,
+ s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1], s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1]);
+ }
} else if (current_mv.pred_flag == PF_BI) {
int x0_c = x0 >> s->sps->hshift[1];
int y0_c = y0 >> s->sps->vshift[1];
¤t_mv.mv[0], x0, y0, nPbW, nPbH,
ref1->frame, ¤t_mv.mv[1], ¤t_mv);
- chroma_mc_bi(s, dst1, s->frame->linesize[1], ref0->frame, ref1->frame,
- x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 0);
+ if (s->sps->chroma_format_idc) {
+ chroma_mc_bi(s, dst1, s->frame->linesize[1], ref0->frame, ref1->frame,
+ x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 0);
- chroma_mc_bi(s, dst2, s->frame->linesize[2], ref0->frame, ref1->frame,
- x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 1);
+ chroma_mc_bi(s, dst2, s->frame->linesize[2], ref0->frame, ref1->frame,
+ x0_c, y0_c, nPbW_c, nPbH_c, ¤t_mv, 1);
+ }
}
}
int startheader, cmpt = 0;
int i, j, res = 0;
+ if (!ret || !arg) {
+ av_free(ret);
+ av_free(arg);
+ return AVERROR(ENOMEM);
+ }
+
if (!s->sList[1]) {
ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1);
return 0;
fail:
- if (s->ref && s->threads_type == FF_THREAD_FRAME)
- ff_thread_report_progress(&s->ref->tf, INT_MAX, 0);
+ if (s->ref)
+ ff_hevc_unref_frame(s, s->ref, ~0);
s->ref = NULL;
return ret;
}
}
}
- if (s->threads_number > 1 && s->sh.num_entry_point_offsets > 0)
- ctb_addr_ts = hls_slice_data_wpp(s, nal->data, nal->size);
- 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->sh.first_slice_in_pic_flag && s->avctx->hwaccel) {
+ ret = s->avctx->hwaccel->start_frame(s->avctx, NULL, 0);
+ if (ret < 0)
+ goto fail;
}
- if (ctb_addr_ts < 0) {
- ret = ctb_addr_ts;
- goto fail;
+ if (s->avctx->hwaccel) {
+ ret = s->avctx->hwaccel->decode_slice(s->avctx, nal->raw_data, nal->raw_size);
+ if (ret < 0)
+ goto fail;
+ } else {
+ if (s->threads_number > 1 && s->sh.num_entry_point_offsets > 0)
+ ctb_addr_ts = hls_slice_data_wpp(s, nal->data, nal->size);
+ 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 (ctb_addr_ts < 0) {
+ ret = ctb_addr_ts;
+ goto fail;
+ }
}
break;
case NAL_EOS_NUT:
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));
+ if (!s->skipped_bytes_pos_nal[s->nals_allocated])
+ goto fail;
s->nals_allocated = new_size;
}
s->skipped_bytes_pos_size = s->skipped_bytes_pos_size_nal[s->nb_nals];
if (ret < 0)
return ret;
- /* verify the SEI checksum */
- if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded &&
- s->is_md5) {
- ret = verify_md5(s, s->ref->frame);
- if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) {
- ff_hevc_unref_frame(s, s->ref, ~0);
- return ret;
+ if (avctx->hwaccel) {
+ if (s->ref && avctx->hwaccel->end_frame(avctx) < 0)
+ av_log(avctx, AV_LOG_ERROR,
+ "hardware accelerator failed to decode picture\n");
+ } else {
+ /* verify the SEI checksum */
+ if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded &&
+ s->is_md5) {
+ ret = verify_md5(s, s->ref->frame);
+ if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) {
+ ff_hevc_unref_frame(s, s->ref, ~0);
+ return ret;
+ }
}
}
s->is_md5 = 0;
dst->flags = src->flags;
dst->sequence = src->sequence;
+ if (src->hwaccel_picture_private) {
+ dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
+ if (!dst->hwaccel_priv_buf)
+ goto fail;
+ dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
+ }
+
return 0;
fail:
ff_hevc_unref_frame(s, dst, ~0);
av_freep(&s->cabac_state);
- av_frame_free(&s->tmp_frame);
+ for (i = 0; i < 3; i++) {
+ av_freep(&s->sao_pixel_buffer_h[i]);
+ av_freep(&s->sao_pixel_buffer_v[i]);
+ }
av_frame_free(&s->output_frame);
for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
if (!s->cabac_state)
goto fail;
- s->tmp_frame = av_frame_alloc();
- if (!s->tmp_frame)
- goto fail;
-
s->output_frame = av_frame_alloc();
if (!s->output_frame)
goto fail;