mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-04-08 16:54:03 +02:00
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>
This commit is contained in:
parent
fcc1022611
commit
ce083282f0
@ -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…
x
Reference in New Issue
Block a user