vdpau: common support for managing the VdpDecoder in avcodec

Using the not so new init and uninit callbacks, avcodec can now take
care of creating and destroying the VDPAU decoder instance.

The application is still responsible for creating the VDPAU device
and allocating video surfaces - this is necessary to keep video
surfaces on the GPU all the way to the output. But the application
will no longer needs to care about any codec-specific aspects.

Signed-off-by: Anton Khirnov <anton@khirnov.net>
pull/87/head
Rémi Denis-Courmont 10 years ago committed by Anton Khirnov
parent fcc1022611
commit ce083282f0
  1. 64
      libavcodec/vdpau.c
  2. 32
      libavcodec/vdpau_internal.h

@ -22,7 +22,9 @@
*/
#include <limits.h>
#include "libavutil/avassert.h"
#include "avcodec.h"
#include "internal.h"
#include "h264.h"
#include "vc1.h"
@ -62,6 +64,68 @@ static int vdpau_error(VdpStatus status)
}
}
int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
int level)
{
VDPAUHWContext *hwctx = avctx->hwaccel_context;
VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
VdpDecoderCreate *create;
void *func;
VdpStatus status;
/* See vdpau/vdpau.h for alignment constraints. */
uint32_t width = (avctx->coded_width + 1) & ~1;
uint32_t height = (avctx->coded_height + 3) & ~3;
if (hwctx->context.decoder != VDP_INVALID_HANDLE) {
vdctx->decoder = hwctx->context.decoder;
vdctx->render = hwctx->context.render;
vdctx->device = VDP_INVALID_HANDLE;
return 0; /* Decoder created by user */
}
vdctx->device = hwctx->device;
vdctx->get_proc_address = hwctx->get_proc_address;
status = vdctx->get_proc_address(vdctx->device, VDP_FUNC_ID_DECODER_CREATE,
&func);
if (status != VDP_STATUS_OK)
return vdpau_error(status);
else
create = func;
status = vdctx->get_proc_address(vdctx->device, VDP_FUNC_ID_DECODER_RENDER,
&func);
if (status != VDP_STATUS_OK)
return vdpau_error(status);
else
vdctx->render = func;
status = create(vdctx->device, profile, width, height, avctx->refs,
&vdctx->decoder);
return vdpau_error(status);
}
int ff_vdpau_common_uninit(AVCodecContext *avctx)
{
VDPAUContext *vdctx = avctx->internal->hwaccel_priv_data;
VdpDecoderDestroy *destroy;
void *func;
VdpStatus status;
if (vdctx->device == VDP_INVALID_HANDLE)
return 0; /* Decoder created and destroyed by user */
status = vdctx->get_proc_address(vdctx->device,
VDP_FUNC_ID_DECODER_DESTROY, &func);
if (status != VDP_STATUS_OK)
return vdpau_error(status);
else
destroy = func;
status = destroy(vdctx->decoder);
return vdpau_error(status);
}
int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic_ctx,
av_unused const uint8_t *buffer,
av_unused uint32_t size)

@ -48,6 +48,34 @@ union AVVDPAUPictureInfo {
#include "vdpau.h"
#endif
typedef struct VDPAUHWContext {
AVVDPAUContext context;
VdpDevice device;
VdpGetProcAddress *get_proc_address;
} VDPAUHWContext;
typedef struct VDPAUContext {
/**
* VDPAU device handle
*/
VdpDevice device;
/**
* VDPAU decoder handle
*/
VdpDecoder decoder;
/**
* VDPAU device driver
*/
VdpGetProcAddress *get_proc_address;
/**
* VDPAU decoder render callback
*/
VdpDecoderRender *render;
} VDPAUContext;
struct vdpau_picture_context {
/**
* VDPAU picture information.
@ -70,6 +98,10 @@ struct vdpau_picture_context {
VdpBitstreamBuffer *bitstream_buffers;
};
int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
int level);
int ff_vdpau_common_uninit(AVCodecContext *avctx);
int ff_vdpau_common_start_frame(struct vdpau_picture_context *pic,
const uint8_t *buffer, uint32_t size);
int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,

Loading…
Cancel
Save