On Thu, 11 Sep 2014 18:08:15 +0300, =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?=
<[email protected]> wrote:
> 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.
> ---
> libavcodec/vdpau.c | 69
> ++++++++++++++++++++++++++++++++++++++++++++-
> libavcodec/vdpau.h | 9 ++++++
> libavcodec/vdpau_internal.h | 26 +++++++++++++++++
> 3 files changed, 103 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
> index d96b71c..2639272 100644
> --- a/libavcodec/vdpau.c
> +++ b/libavcodec/vdpau.c
> @@ -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,66 @@ static int ff_vdpau_error(VdpStatus status)
> }
> }
>
> +static void *ff_vdpau_get_proc_address(AVCodecContext *avctx, VdpFuncId id)
No ff_ prefix for static functions. And I don't see what this function
accomplishes anyway -- you could just as well call the get_proc_address()
callback directly.
> +{
> + struct vdpau_context *vdctx = avctx->internal->hwaccel_priv_data;
> + void *ret;
> +
> + av_assert0(vdctx->device != VDP_INVALID_HANDLE);
> +
> + if (vdctx->get_proc_address(vdctx->device, id, &ret) != VDP_STATUS_OK)
> + ret = NULL;
> + return ret;
> +}
> +
> +int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile,
> + int level, uint32_t surfaces)
> +{
> + AVVDPAUContext *hwctx = avctx->hwaccel_context;
> + struct vdpau_context *vdctx = avctx->internal->hwaccel_priv_data;
> + VdpDecoderCreate *create;
> + VdpStatus status;
> + uint32_t width = (avctx->coded_width + 1) & ~1;
> + uint32_t height = (avctx->coded_height + 3) & ~3;
Why different rounding?
> +
> + vdctx->device = hwctx->device;
> + vdctx->get_proc_address = hwctx->get_proc_address;
> +
> + if (hwctx->device == VDP_INVALID_HANDLE) {
> + vdctx->decoder = hwctx->decoder;
> + vdctx->render = hwctx->render;
> + return 0; /* Decoder created by user */
> + }
> +
> + create = ff_vdpau_get_proc_address(avctx, VDP_FUNC_ID_DECODER_CREATE);
> + vdctx->render = ff_vdpau_get_proc_address(avctx,
> + VDP_FUNC_ID_DECODER_RENDER);
> + if (create == NULL || vdctx->render == NULL)
> + return AVERROR(ENOSYS);
> +
> + status = create(vdctx->device, profile, width, height, surfaces,
> + &vdctx->decoder);
> +
> + return ff_vdpau_error(status);
> +}
> +
> +int ff_vdpau_common_uninit(AVCodecContext *avctx)
> +{
> + struct vdpau_context *vdctx = avctx->internal->hwaccel_priv_data;
> + VdpDecoderDestroy *destroy;
> + VdpStatus status;
> +
> + if (vdctx->device == VDP_INVALID_HANDLE)
> + return 0; /* Decoder created and destroyed by user */
> +
> + destroy = ff_vdpau_get_proc_address(avctx, VDP_FUNC_ID_DECODER_DESTROY);
> + if (destroy == NULL)
> + return AVERROR(ENOSYS);
> +
> + status = destroy(vdctx->decoder);
> + return ff_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)
> @@ -170,7 +232,12 @@ do { \
>
> AVVDPAUContext *av_vdpau_alloc_context(void)
> {
> - return av_mallocz(sizeof(AVVDPAUContext));
> + AVVDPAUContext *hwctx = av_mallocz(sizeof(AVVDPAUContext));
> + if (!hwctx)
> + return NULL;
> +
> + hwctx->device = VDP_INVALID_HANDLE;
> + return hwctx;
> }
>
> /* @}*/
> diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
> index 75cb1bf..b246768 100644
> --- a/libavcodec/vdpau.h
> +++ b/libavcodec/vdpau.h
> @@ -128,6 +128,15 @@ typedef struct AVVDPAUContext {
> attribute_deprecated
> VdpBitstreamBuffer *bitstream_buffers;
> #endif
> + /*****************************************************************
> + * No fields below this line are part of the public API. They
> + * may not be used outside of libavcodec and can be changed and
> + * removed at will.
> + * No new public fields will be added to this structure.
> + *****************************************************************
> + */
> + VdpDevice device;
> + VdpGetProcAddress *get_proc_address;
Eh? Aren't those supposed to be set by the caller?
And if they are really private, they have no place here and must live in
vdpau_context.
> } AVVDPAUContext;
>
> /**
> diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h
> index 3f55ee7..cefc0a1 100644
> --- a/libavcodec/vdpau_internal.h
> +++ b/libavcodec/vdpau_internal.h
> @@ -48,6 +48,28 @@ union AVVDPAUPictureInfo {
> #include "vdpau.h"
> #endif
>
> +struct vdpau_context {
Proper naming please, camelcased with typedeffed struct.
--
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel