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

Reply via email to