[FFmpeg-devel] [PATCH 2/2] Add decode support for VDPAU VP9.

Philip Langdale philipl at overt.org
Mon Oct 21 18:54:36 EEST 2019


On Mon, 21 Oct 2019 18:01:38 +0530
ManojGuptaBonda <mbonda at nvidia.com> wrote:

> Populate the codec specific params that need to be passed to
> VDPAU.
> ---
>  libavcodec/vdpau_vp9.c | 155
> ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 153
> insertions(+), 2 deletions(-)
> 
> diff --git a/libavcodec/vdpau_vp9.c b/libavcodec/vdpau_vp9.c
> index d8f629d135..f1ee4ac5e0 100644
> --- a/libavcodec/vdpau_vp9.c
> +++ b/libavcodec/vdpau_vp9.c
> @@ -21,7 +21,7 @@
>   */
>  
>  #include <vdpau/vdpau.h>
> -
> +#include "libavutil/pixdesc.h"
>  #include "avcodec.h"
>  #include "internal.h"
>  #include "vp9data.h"
> @@ -33,7 +33,134 @@
>  static int vdpau_vp9_start_frame(AVCodecContext *avctx,
>                                    const uint8_t *buffer, uint32_t
> size) {
> -    return 0;
> +    VP9Context *s = avctx->priv_data;
> +    VP9SharedContext *h = &(s->s);
> +    const AVPixFmtDescriptor *pixdesc =
> av_pix_fmt_desc_get(avctx->sw_pix_fmt);
> +    if (!pixdesc) {
> +        return AV_PIX_FMT_NONE;
> +    }
> +
> +    VP9Frame pic = h->frames[CUR_FRAME];
> +    struct vdpau_picture_context *pic_ctx =
> pic.hwaccel_picture_private;
> +    int i;
> +
> +    VdpPictureInfoVP9 *info = &pic_ctx->info.vp9;
> +
> +    info->width = avctx->width;
> +    info->height = avctx->height;
> +    /*  fill LvPictureInfoVP9 struct */
> +    info->lastReference  = VDP_INVALID_HANDLE;
> +    info->goldenReference = VDP_INVALID_HANDLE;
> +    info->altReference = VDP_INVALID_HANDLE;
> +
> +    if (h->refs[h->h.refidx[0]].f &&
> h->refs[h->h.refidx[0]].f->private_ref) {
> +        info->lastReference               =
> ff_vdpau_get_surface_id(h->refs[h->h.refidx[0]].f);
> +    }
> +    if (h->refs[h->h.refidx[1]].f &&
> h->refs[h->h.refidx[1]].f->private_ref) {
> +        info->goldenReference             =
> ff_vdpau_get_surface_id(h->refs[h->h.refidx[1]].f);
> +    }
> +    if (h->refs[h->h.refidx[2]].f &&
> h->refs[h->h.refidx[2]].f->private_ref) {
> +        info->altReference                =
> ff_vdpau_get_surface_id(h->refs[h->h.refidx[2]].f);
> +    }
> +
> +    info->profile                  = h->h.profile;
> +    info->frameContextIdx          = h->h.framectxid;
> +    info->keyFrame                 = h->h.keyframe;
> +    info->showFrame                = !h->h.invisible;
> +    info->errorResilient           = h->h.errorres;
> +    info->frameParallelDecoding    = h->h.parallelmode;
> +
> +    info->subSamplingX             = pixdesc->log2_chroma_w;
> +    info->subSamplingY             = pixdesc->log2_chroma_h;
> +
> +    info->intraOnly                = h->h.intraonly;
> +    info->allowHighPrecisionMv     = h->h.keyframe ? 0 :
> h->h.highprecisionmvs;
> +    info->refreshEntropyProbs      = h->h.refreshctx;
> +
> +    info->bitDepthMinus8Luma       = pixdesc->comp[0].depth - 8;
> +    info->bitDepthMinus8Chroma     = pixdesc->comp[1].depth - 8;
> +
> +    info->loopFilterLevel          = h->h.filter.level;
> +    info->loopFilterSharpness      = h->h.filter.sharpness;
> +    info->modeRefLfEnabled         = h->h.lf_delta.enabled;
> +
> +    info->log2TileColumns          = h->h.tiling.log2_tile_cols;
> +    info->log2TileRows             = h->h.tiling.log2_tile_rows;
> +
> +    info->segmentEnabled           = h->h.segmentation.enabled;
> +    info->segmentMapUpdate         = h->h.segmentation.update_map;
> +    info->segmentMapTemporalUpdate = h->h.segmentation.temporal;
> +    info->segmentFeatureMode       = h->h.segmentation.absolute_vals;
> +
> +    info->qpYAc                    = h->h.yac_qi;
> +    info->qpYDc                    = h->h.ydc_qdelta;
> +    info->qpChDc                   = h->h.uvdc_qdelta;
> +    info->qpChAc                   = h->h.uvac_qdelta;
> +
> +    info->resetFrameContext        = h->h.resetctx;
> +    info->mcompFilterType          = h->h.filtermode ^
> (h->h.filtermode <= 1);
> +    info->uncompressedHeaderSize   = h->h.uncompressed_header_size;
> +    info->compressedHeaderSize     = h->h.compressed_header_size;
> +    info->refFrameSignBias[0]      = 0;
> +
> +
> +    for (i = 0; i < FF_ARRAY_ELEMS(info->mbModeLfDelta); i++)
> +        info->mbModeLfDelta[i] = h->h.lf_delta.mode[i];
> +
> +    for (i = 0; i < FF_ARRAY_ELEMS(info->mbRefLfDelta); i++)
> +        info->mbRefLfDelta[i] = h->h.lf_delta.ref[i];
> +
> +    for (i = 0; i < FF_ARRAY_ELEMS(info->mbSegmentTreeProbs); i++)
> +        info->mbSegmentTreeProbs[i] = h->h.segmentation.prob[i];
> +
> +    for (i = 0; i < FF_ARRAY_ELEMS(info->activeRefIdx); i++) {
> +        info->activeRefIdx[i] = h->h.refidx[i];
> +        info->segmentPredProbs[i] = h->h.segmentation.pred_prob[i];
> +        info->refFrameSignBias[i + 1] = h->h.signbias[i];
> +    }
> +
> +    for (i = 0; i < FF_ARRAY_ELEMS(info->segmentFeatureEnable); i++)
> {
> +        info->segmentFeatureEnable[i][0] =
> h->h.segmentation.feat[i].q_enabled;
> +        info->segmentFeatureEnable[i][1] =
> h->h.segmentation.feat[i].lf_enabled;
> +        info->segmentFeatureEnable[i][2] =
> h->h.segmentation.feat[i].ref_enabled;
> +        info->segmentFeatureEnable[i][3] =
> h->h.segmentation.feat[i].skip_enabled; +
> +        info->segmentFeatureData[i][0] =
> h->h.segmentation.feat[i].q_val;
> +        info->segmentFeatureData[i][1] =
> h->h.segmentation.feat[i].lf_val;
> +        info->segmentFeatureData[i][2] =
> h->h.segmentation.feat[i].ref_val;
> +        info->segmentFeatureData[i][3] = 0;
> +    }
> +
> +    switch (avctx->colorspace) {
> +    default:
> +    case AVCOL_SPC_UNSPECIFIED:
> +        info->colorSpace = 0;
> +        break;
> +    case AVCOL_SPC_BT470BG:
> +        info->colorSpace = 1;
> +        break;
> +    case AVCOL_SPC_BT709:
> +        info->colorSpace = 2;
> +        break;
> +    case AVCOL_SPC_SMPTE170M:
> +        info->colorSpace = 3;
> +        break;
> +    case AVCOL_SPC_SMPTE240M:
> +        info->colorSpace = 4;
> +        break;
> +    case AVCOL_SPC_BT2020_NCL:
> +        info->colorSpace = 5;
> +        break;
> +    case AVCOL_SPC_RESERVED:
> +        info->colorSpace = 6;
> +        break;
> +    case AVCOL_SPC_RGB:
> +        info->colorSpace = 7;
> +        break;
> +    }
> +
> +    return ff_vdpau_common_start_frame(pic_ctx, buffer, size);
> +
>  }
>  
>  static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
> @@ -41,11 +168,35 @@ static const uint8_t start_code_prefix[3] = {
> 0x00, 0x00, 0x01 }; static int vdpau_vp9_decode_slice(AVCodecContext
> *avctx, const uint8_t *buffer, uint32_t size)
>  {
> +    VP9SharedContext *h = avctx->priv_data;
> +    VP9Frame pic = h->frames[CUR_FRAME];
> +    struct vdpau_picture_context *pic_ctx =
> pic.hwaccel_picture_private; +
> +    int val;
> +
> +    val = ff_vdpau_add_buffer(pic_ctx, start_code_prefix, 3);
> +    if (val)
> +        return val;
> +
> +    val = ff_vdpau_add_buffer(pic_ctx, buffer, size);
> +    if (val)
> +        return val;
> +
>      return 0;
>  }

As we discussed directly, the start code requirement needs to be
documented and explained. It's not in the current vdpau docs and wasn't
necessary for nvdec.

>  static int vdpau_vp9_end_frame(AVCodecContext *avctx)
>  {
> +    VP9SharedContext *h = avctx->priv_data;
> +    VP9Frame pic = h->frames[CUR_FRAME];
> +    struct vdpau_picture_context *pic_ctx =
> pic.hwaccel_picture_private; +
> +    int val;
> +
> +    val = ff_vdpau_common_end_frame(avctx, pic.tf.f, pic_ctx);
> +    if (val < 0)
> +        return val;
> +
>      return 0;
>  }
>  

I'm happy to merge this after addressing the comments.

Thanks,

--phil


More information about the ffmpeg-devel mailing list