Quoting Hendrik Leppkes (2015-01-24 15:14:05)
> ---
> libavcodec/hevc.c | 35 +++++++++++++++++++++++++++++++++--
> libavcodec/hevc.h | 3 +++
> libavcodec/hevc_refs.c | 16 ++++++++++++++++
> 3 files changed, 52 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
> index 4e17322..c140e85 100644
> --- a/libavcodec/hevc.c
> +++ b/libavcodec/hevc.c
> @@ -385,6 +385,8 @@ static int decode_lt_rps(HEVCContext *s, LongTermRPS
> *rps, GetBitContext *gb)
>
> static int set_sps(HEVCContext *s, const HEVCSPS *sps)
> {
> + #define HWACCEL_MAX (0)
> + enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts;
> int ret;
> unsigned int num = 0, den = 0;
>
> @@ -397,9 +399,13 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps)
> 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;
>
> + *fmt++ = sps->pix_fmt;
> + *fmt = AV_PIX_FMT_NONE;
> +
> + s->avctx->pix_fmt = ff_get_format(s->avctx, pix_fmts);
You need to check this for failure (AV_PIX_FMT_NONE)
> +
> ff_set_sar(s->avctx, sps->vui.sar);
>
> if (sps->vui.video_signal_type_present_flag)
> @@ -422,7 +428,7 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps)
> 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)
> @@ -2571,6 +2577,17 @@ static int decode_nal_unit(HEVCContext *s, const
> HEVCNAL *nal)
> }
> }
>
> + 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 (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;
> @@ -2584,6 +2601,7 @@ static int decode_nal_unit(HEVCContext *s, const
> HEVCNAL *nal)
> ret = ctb_addr_ts;
> goto fail;
> }
> + }
> break;
> case NAL_EOS_NUT:
> case NAL_EOB_NUT:
> @@ -2889,6 +2907,11 @@ static int hevc_decode_frame(AVCodecContext *avctx,
> void *data, int *got_output,
> if (ret < 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) {
> @@ -2898,6 +2921,7 @@ static int hevc_decode_frame(AVCodecContext *avctx,
> void *data, int *got_output,
> return ret;
> }
> }
> + }
> s->is_md5 = 0;
>
> if (s->is_decoded) {
> @@ -2939,6 +2963,13 @@ static int hevc_ref_frame(HEVCContext *s, HEVCFrame
> *dst, HEVCFrame *src)
> 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);
> diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
> index b78b164..333ea46 100644
> --- a/libavcodec/hevc.h
> +++ b/libavcodec/hevc.h
> @@ -676,6 +676,9 @@ typedef struct HEVCFrame {
> AVBufferRef *rpl_tab_buf;
> AVBufferRef *rpl_buf;
>
> + AVBufferRef *hwaccel_priv_buf;
> + void *hwaccel_picture_private;
> +
> /**
> * A sequence counter, so that old frames are output first
> * after a POC reset
> diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
> index 658ead7..a981827 100644
> --- a/libavcodec/hevc_refs.c
> +++ b/libavcodec/hevc_refs.c
> @@ -46,6 +46,9 @@ void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame,
> int flags)
> frame->refPicList = NULL;
>
> frame->collocated_ref = NULL;
> +
> + av_buffer_unref(&frame->hwaccel_priv_buf);
> + frame->hwaccel_picture_private = NULL;
> }
> }
>
> @@ -105,6 +108,17 @@ static HEVCFrame *alloc_frame(HEVCContext *s)
> for (j = 0; j < frame->ctb_count; j++)
> frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data;
>
> + if (s->avctx->hwaccel) {
> + const AVHWAccel *hwaccel = s->avctx->hwaccel;
> + assert(!frame->hwaccel_picture_private);
I think we want to use av_assertx everywhere now
Otherwise looks ok
--
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel