Since the VDPAU pixel format does not distinguish between different VDPAU video surface chroma types, we need another way to pass this data to the application.
Originally VDPAU in libavcodec only supported decoding to 8-bits YUV with 4:2:0 chroma sampling. Correspondingly, applications assumed that libavcodec expected VDP_CHROMA_TYPE_420 video surfaces for output. However some of the new HEVC profiles proposed for addition to VDPAU would require different depth and/or sampling: http://lists.freedesktop.org/archives/vdpau/2014-July/000167.html To preserve backward binary compatibility with existing applications, a new av_vdpau_bind_context() flag shall be introduced if/when new chroma type is actually introduced in the code base - or a major version bump of libavcodec. Note: There could also be a higher-level helper to allocate a VDPAU video surface, or even to allocate a surface and associate it with an AVFrame. This is left for further study. In any case, the chroma type and frame sizes are usually required by the application before any surface is allocated (that affects at least both avconv and VLC). --- doc/APIchanges | 3 +++ libavcodec/vdpau.c | 44 ++++++++++++++++++++++++++++++++++++++++---- libavcodec/vdpau.h | 20 ++++++++++++++++++++ libavcodec/version.h | 2 +- 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 6348b9a..98748c2 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2014-08-09 API changes, most recent first: +2014-09-xx - xxxxxxx - lavc 56.4.0 - vdpau.h + Add av_vdpau_get_surface_parameters(). + 2014-09-xx - xxxxxxx - lavc 56.3.0 - vdpau.h Add AV_VDPAU_FLAG_IGNORE_LEVEL flag to av_vdpau_bind_context(). diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index ae06d7d..cd58a15 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -64,6 +64,40 @@ static int vdpau_error(VdpStatus status) } } +int av_vdpau_get_surface_parameters(AVCodecContext *avctx, VdpChromaType *type, + uint32_t *width, uint32_t *height) +{ + /* XXX: only 8-bits YCbCr 4:2:0 is supported yet */ + VdpChromaType t = VDP_CHROMA_TYPE_420; + uint32_t w = avctx->coded_width; + uint32_t h = avctx->coded_width; + + /* See <vdpau/vdpau.h> for per-type alignment constraints. */ + switch (t) + { + case VDP_CHROMA_TYPE_420: + w = (w + 1) & ~1; + h = (h + 3) & ~3; + break; + case VDP_CHROMA_TYPE_422: + w = (w + 1) & ~1; + h = (h + 1) & ~1; + break; + case VDP_CHROMA_TYPE_444: + h = (h + 1) & ~1; + break; + } + + if (type) + *type = t; + if (width) + *width = w; + if (height) + *height = h; + + return 0; +} + int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, int level, uint32_t surfaces) { @@ -76,9 +110,9 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, VdpStatus status; VdpBool supported; uint32_t max_level, max_mb, max_width, max_height; - /* See vdpau/vdpau.h for alignment constraints. */ - uint32_t width = (avctx->coded_width + 1) & ~1; - uint32_t height = (avctx->coded_height + 3) & ~3; + VdpChromaType type; + uint32_t width; + uint32_t height; vdctx->device = hwctx->device; vdctx->get_proc_address = hwctx->get_proc_address; @@ -105,7 +139,9 @@ int ff_vdpau_common_init(AVCodecContext *avctx, VdpDecoderProfile profile, else surface_query_caps = func; - status = surface_query_caps(vdctx->device, VDP_CHROMA_TYPE_420, &supported, + av_vdpau_get_surface_parameters(avctx, &type, &width, &height); + + status = surface_query_caps(vdctx->device, type, &supported, &max_width, &max_height); if (status != VDP_STATUS_OK) return vdpau_error(status); diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h index e19f3c8..94b98fc 100644 --- a/libavcodec/vdpau.h +++ b/libavcodec/vdpau.h @@ -168,6 +168,26 @@ int av_vdpau_bind_context(AVCodecContext *avctx, VdpDevice device, #define AV_VDPAU_FLAG_IGNORE_LEVEL (1 << 0) /** + * Gets the parameters to create an adequate VDPAU video surface for the codec + * context using VDPAU hardware decoding acceleration. + * + * @note Behavior is undefined if the context was not succesfully bound to a + * VDPAU device using av_vdpau_bind_context(). + * + * @param avctx the codec context being used for decoding the stream + * @param type storage space for the VDPAU video surface chroma type + * (or NULL to ignore) + * @param width storage space for the VDPAU video surface pixel width + * (or NULL to ignore) + * @param height storage space for the VDPAU video surface pixel height + * (or NULL to ignore) + * + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_vdpau_get_surface_parameters(AVCodecContext *avctx, VdpChromaType *type, + uint32_t *width, uint32_t *height); + +/** * Allocate an AVVDPAUContext. * * @return Newly-allocated AVVDPAUContext or NULL on failure. diff --git a/libavcodec/version.h b/libavcodec/version.h index d9c4500..2535818 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 56 -#define LIBAVCODEC_VERSION_MINOR 3 +#define LIBAVCODEC_VERSION_MINOR 4 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ -- 1.8.1.5 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
