uint8_t luma_weight_l1_flag[16];
uint8_t chroma_weight_l1_flag[16];
- s->sh.luma_log2_weight_denom = get_ue_golomb_long(gb);
+ s->sh.luma_log2_weight_denom = av_clip_c(get_ue_golomb_long(gb), 0, 7);
if (s->sps->chroma_format_idc != 0) {
int delta = get_se_golomb(gb);
s->sh.chroma_log2_weight_denom = av_clip_c(s->sh.luma_log2_weight_denom + delta, 0, 7);
static int set_sps(HEVCContext *s, const HEVCSPS *sps)
{
+ #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL)
+ enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts;
int ret;
unsigned int num = 0, den = 0;
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_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) {
+ if (sps->sao_enabled && !s->avctx->hwaccel) {
av_frame_unref(s->tmp_frame);
ret = ff_get_buffer(s->avctx, s->tmp_frame, AV_GET_BUFFER_FLAG_REF);
if (ret < 0)
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;
fail:
if (s->ref)
- ff_thread_report_progress(&s->ref->tf, INT_MAX, 0);
+ ff_hevc_unref_frame(s, s->ref, ~0);
s->ref = NULL;
return ret;
}
-static int decode_nal_unit(HEVCContext *s, const uint8_t *nal, int length)
+static int decode_nal_unit(HEVCContext *s, const HEVCNAL *nal)
{
HEVCLocalContext *lc = &s->HEVClc;
GetBitContext *gb = &lc->gb;
int ctb_addr_ts, ret;
- ret = init_get_bits8(gb, nal, length);
+ ret = init_get_bits8(gb, nal->data, nal->size);
if (ret < 0)
return ret;
}
}
- 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 ||
- (s->sps->pcm.loop_filter_disable_flag && s->sps->pcm_enabled_flag)) &&
- s->sps->sao_enabled)
- restore_tqb_pixels(s);
+ 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 {
+ 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 ||
+ (s->sps->pcm.loop_filter_disable_flag && s->sps->pcm_enabled_flag)) &&
+ s->sps->sao_enabled)
+ restore_tqb_pixels(s);
+ }
+
+ if (ctb_addr_ts < 0) {
+ ret = ctb_addr_ts;
+ goto fail;
+ }
}
break;
case NAL_EOS_NUT:
#endif /* HAVE_FAST_UNALIGNED */
if (i >= length - 1) { // no escaped 0
- nal->data = src;
- nal->size = length;
+ nal->data =
+ nal->raw_data = src;
+ nal->size =
+ nal->raw_size = length;
return length;
}
nal->data = dst;
nal->size = di;
+ nal->raw_data = src;
+ nal->raw_size = si;
return si;
}
/* 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 = decode_nal_unit(s, &s->nals[i]);
if (ret < 0) {
av_log(s->avctx, AV_LOG_WARNING,
"Error parsing NAL unit #%d.\n", i);
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);