Skip to content

Commit

Permalink
avcodec: Refactor common nvdec hwaccel logic
Browse files Browse the repository at this point in the history
The 'simple' hwaccels (not h.264 and hevc) all use the same bitstream
management and reference lookup logic so let's refactor all that into
common functions.

I verified that casting a signed int -1 to unsigned char produces 255
according to the C language specification.
  • Loading branch information
philipl committed Nov 20, 2017
1 parent 16d67fa commit 4c7b023
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 146 deletions.
46 changes: 46 additions & 0 deletions libavcodec/nvdec.c
Expand Up @@ -475,6 +475,36 @@ int ff_nvdec_end_frame(AVCodecContext *avctx)
return ret;
}

int ff_nvdec_simple_end_frame(AVCodecContext *avctx)
{
NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
int ret = ff_nvdec_end_frame(avctx);
ctx->bitstream = NULL;
return ret;
}

int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer,
uint32_t size)
{
NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
void *tmp;

tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
(ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
if (!tmp)
return AVERROR(ENOMEM);
ctx->slice_offsets = tmp;

if (!ctx->bitstream)
ctx->bitstream = (uint8_t*)buffer;

ctx->slice_offsets[ctx->nb_slices] = buffer - ctx->bitstream;
ctx->bitstream_len += size;
ctx->nb_slices++;

return 0;
}

int ff_nvdec_frame_params(AVCodecContext *avctx,
AVBufferRef *hw_frames_ctx,
int dpb_size)
Expand Down Expand Up @@ -520,3 +550,19 @@ int ff_nvdec_frame_params(AVCodecContext *avctx,

return 0;
}

int ff_nvdec_get_ref_idx(AVFrame *frame)
{
FrameDecodeData *fdd;
NVDECFrame *cf;

if (!frame || !frame->private_ref)
return -1;

fdd = (FrameDecodeData*)frame->private_ref->data;
cf = (NVDECFrame*)fdd->hwaccel_priv;
if (!cf)
return -1;

return cf->idx;
}
4 changes: 4 additions & 0 deletions libavcodec/nvdec.h
Expand Up @@ -58,8 +58,12 @@ int ff_nvdec_decode_init(AVCodecContext *avctx);
int ff_nvdec_decode_uninit(AVCodecContext *avctx);
int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame);
int ff_nvdec_end_frame(AVCodecContext *avctx);
int ff_nvdec_simple_end_frame(AVCodecContext *avctx);
int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer,
uint32_t size);
int ff_nvdec_frame_params(AVCodecContext *avctx,
AVBufferRef *hw_frames_ctx,
int dpb_size);
int ff_nvdec_get_ref_idx(AVFrame *frame);

#endif /* AVCODEC_NVDEC_H */
53 changes: 4 additions & 49 deletions libavcodec/nvdec_mpeg12.c
Expand Up @@ -25,22 +25,6 @@
#include "nvdec.h"
#include "decode.h"

static int get_ref_idx(AVFrame *frame)
{
FrameDecodeData *fdd;
NVDECFrame *cf;

if (!frame || !frame->private_ref)
return -1;

fdd = (FrameDecodeData*)frame->private_ref->data;
cf = (NVDECFrame*)fdd->hwaccel_priv;
if (!cf)
return -1;

return cf->idx;
}

static int nvdec_mpeg12_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
{
MpegEncContext *s = avctx->priv_data;
Expand Down Expand Up @@ -71,8 +55,8 @@ static int nvdec_mpeg12_start_frame(AVCodecContext *avctx, const uint8_t *buffer
s->pict_type == AV_PICTURE_TYPE_P,

.CodecSpecific.mpeg2 = {
.ForwardRefIdx = get_ref_idx(s->last_picture.f),
.BackwardRefIdx = get_ref_idx(s->next_picture.f),
.ForwardRefIdx = ff_nvdec_get_ref_idx(s->last_picture.f),
.BackwardRefIdx = ff_nvdec_get_ref_idx(s->next_picture.f),

.picture_coding_type = s->pict_type,
.full_pel_forward_vector = s->full_pel[0],
Expand All @@ -99,35 +83,6 @@ static int nvdec_mpeg12_start_frame(AVCodecContext *avctx, const uint8_t *buffer
return 0;
}

static int nvdec_mpeg12_end_frame(AVCodecContext *avctx)
{
NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
int ret = ff_nvdec_end_frame(avctx);
ctx->bitstream = NULL;
return ret;
}

static int nvdec_mpeg12_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
{
NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
void *tmp;

tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
(ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
if (!tmp)
return AVERROR(ENOMEM);
ctx->slice_offsets = tmp;

if (!ctx->bitstream)
ctx->bitstream = (uint8_t*)buffer;

ctx->slice_offsets[ctx->nb_slices] = buffer - ctx->bitstream;
ctx->bitstream_len += size;
ctx->nb_slices++;

return 0;
}

static int nvdec_mpeg12_frame_params(AVCodecContext *avctx,
AVBufferRef *hw_frames_ctx)
{
Expand All @@ -142,8 +97,8 @@ AVHWAccel ff_mpeg2_nvdec_hwaccel = {
.id = AV_CODEC_ID_MPEG2VIDEO,
.pix_fmt = AV_PIX_FMT_CUDA,
.start_frame = nvdec_mpeg12_start_frame,
.end_frame = nvdec_mpeg12_end_frame,
.decode_slice = nvdec_mpeg12_decode_slice,
.end_frame = ff_nvdec_simple_end_frame,
.decode_slice = ff_nvdec_simple_decode_slice,
.frame_params = nvdec_mpeg12_frame_params,
.init = ff_nvdec_decode_init,
.uninit = ff_nvdec_decode_uninit,
Expand Down
55 changes: 6 additions & 49 deletions libavcodec/nvdec_vc1.c
Expand Up @@ -25,20 +25,6 @@
#include "decode.h"
#include "vc1.h"

static int get_ref_idx(AVFrame *frame)
{
FrameDecodeData *fdd;
NVDECFrame *cf;

if (!frame || !frame->private_ref)
return -1;

fdd = (FrameDecodeData*)frame->private_ref->data;
cf = (NVDECFrame*)fdd->hwaccel_priv;

return cf->idx;
}

static int nvdec_vc1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
{
VC1Context *v = avctx->priv_data;
Expand Down Expand Up @@ -73,8 +59,8 @@ static int nvdec_vc1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, u
s->pict_type == AV_PICTURE_TYPE_P,

.CodecSpecific.vc1 = {
.ForwardRefIdx = get_ref_idx(s->last_picture.f),
.BackwardRefIdx = get_ref_idx(s->next_picture.f),
.ForwardRefIdx = ff_nvdec_get_ref_idx(s->last_picture.f),
.BackwardRefIdx = ff_nvdec_get_ref_idx(s->next_picture.f),
.FrameWidth = cur_frame->width,
.FrameHeight = cur_frame->height,

Expand Down Expand Up @@ -117,35 +103,6 @@ static int nvdec_vc1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, u
return 0;
}

static int nvdec_vc1_end_frame(AVCodecContext *avctx)
{
NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
int ret = ff_nvdec_end_frame(avctx);
ctx->bitstream = NULL;
return ret;
}

static int nvdec_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
{
NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
void *tmp;

tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
(ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
if (!tmp)
return AVERROR(ENOMEM);
ctx->slice_offsets = tmp;

if (!ctx->bitstream)
ctx->bitstream = (uint8_t*)buffer;

ctx->slice_offsets[ctx->nb_slices] = buffer - ctx->bitstream;
ctx->bitstream_len += size;
ctx->nb_slices++;

return 0;
}

static int nvdec_vc1_frame_params(AVCodecContext *avctx,
AVBufferRef *hw_frames_ctx)
{
Expand All @@ -159,8 +116,8 @@ AVHWAccel ff_vc1_nvdec_hwaccel = {
.id = AV_CODEC_ID_VC1,
.pix_fmt = AV_PIX_FMT_CUDA,
.start_frame = nvdec_vc1_start_frame,
.end_frame = nvdec_vc1_end_frame,
.decode_slice = nvdec_vc1_decode_slice,
.end_frame = ff_nvdec_simple_end_frame,
.decode_slice = ff_nvdec_simple_decode_slice,
.frame_params = nvdec_vc1_frame_params,
.init = ff_nvdec_decode_init,
.uninit = ff_nvdec_decode_uninit,
Expand All @@ -174,8 +131,8 @@ AVHWAccel ff_wmv3_nvdec_hwaccel = {
.id = AV_CODEC_ID_WMV3,
.pix_fmt = AV_PIX_FMT_CUDA,
.start_frame = nvdec_vc1_start_frame,
.end_frame = nvdec_vc1_end_frame,
.decode_slice = nvdec_vc1_decode_slice,
.end_frame = ff_nvdec_simple_end_frame,
.decode_slice = ff_nvdec_simple_decode_slice,
.frame_params = nvdec_vc1_frame_params,
.init = ff_nvdec_decode_init,
.uninit = ff_nvdec_decode_uninit,
Expand Down
53 changes: 5 additions & 48 deletions libavcodec/nvdec_vp9.c
Expand Up @@ -28,20 +28,6 @@
#include "internal.h"
#include "vp9shared.h"

static unsigned char get_ref_idx(AVFrame *frame)
{
FrameDecodeData *fdd;
NVDECFrame *cf;

if (!frame || !frame->private_ref)
return 255;

fdd = (FrameDecodeData*)frame->private_ref->data;
cf = (NVDECFrame*)fdd->hwaccel_priv;

return cf->idx;
}

static int nvdec_vp9_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
{
VP9SharedContext *h = avctx->priv_data;
Expand Down Expand Up @@ -72,9 +58,9 @@ static int nvdec_vp9_start_frame(AVCodecContext *avctx, const uint8_t *buffer, u
.width = cur_frame->width,
.height = cur_frame->height,

.LastRefIdx = get_ref_idx(h->refs[h->h.refidx[0]].f),
.GoldenRefIdx = get_ref_idx(h->refs[h->h.refidx[1]].f),
.AltRefIdx = get_ref_idx(h->refs[h->h.refidx[2]].f),
.LastRefIdx = ff_nvdec_get_ref_idx(h->refs[h->h.refidx[0]].f),
.GoldenRefIdx = ff_nvdec_get_ref_idx(h->refs[h->h.refidx[1]].f),
.AltRefIdx = ff_nvdec_get_ref_idx(h->refs[h->h.refidx[2]].f),

.profile = h->h.profile,
.frameContextIdx = h->h.framectxid,
Expand Down Expand Up @@ -176,35 +162,6 @@ static int nvdec_vp9_start_frame(AVCodecContext *avctx, const uint8_t *buffer, u
return 0;
}

static int nvdec_vp9_end_frame(AVCodecContext *avctx)
{
NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
int ret = ff_nvdec_end_frame(avctx);
ctx->bitstream = NULL;
return ret;
}

static int nvdec_vp9_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
{
NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
void *tmp;

tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
(ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
if (!tmp)
return AVERROR(ENOMEM);
ctx->slice_offsets = tmp;

if (!ctx->bitstream)
ctx->bitstream = (uint8_t*)buffer;

ctx->slice_offsets[ctx->nb_slices] = buffer - ctx->bitstream;
ctx->bitstream_len += size;
ctx->nb_slices++;

return 0;
}

static int nvdec_vp9_frame_params(AVCodecContext *avctx,
AVBufferRef *hw_frames_ctx)
{
Expand All @@ -218,8 +175,8 @@ AVHWAccel ff_vp9_nvdec_hwaccel = {
.id = AV_CODEC_ID_VP9,
.pix_fmt = AV_PIX_FMT_CUDA,
.start_frame = nvdec_vp9_start_frame,
.end_frame = nvdec_vp9_end_frame,
.decode_slice = nvdec_vp9_decode_slice,
.end_frame = ff_nvdec_simple_end_frame,
.decode_slice = ff_nvdec_simple_decode_slice,
.frame_params = nvdec_vp9_frame_params,
.init = ff_nvdec_decode_init,
.uninit = ff_nvdec_decode_uninit,
Expand Down

0 comments on commit 4c7b023

Please sign in to comment.