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

Reply via email to