---
The rebuilding of the table is to add a default pixfmt - we don't necessarily
have any of the stream available here, so it uses the "normal" pixfmt for the
profile. (And even if we did have the stream using it would require a lot more
effort.)
Some of the error returns aren't quite right, that needs to be sorted out once
the previous patch is finished.
libavcodec/vaapi_decode.c | 111 ++++++++++++++++++++++++++++++++++------------
libavcodec/vaapi_decode.h | 2 +
libavcodec/vaapi_h264.c | 2 +
libavcodec/vaapi_hevc.c | 2 +
libavcodec/vaapi_mpeg2.c | 2 +
libavcodec/vaapi_mpeg4.c | 4 ++
libavcodec/vaapi_vc1.c | 4 ++
libavcodec/vaapi_vp8.c | 2 +
8 files changed, 101 insertions(+), 28 deletions(-)
diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index a63c4c62e..82e919858 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -235,49 +235,54 @@ static const struct {
enum AVCodecID codec_id;
int codec_profile;
VAProfile va_profile;
+ enum AVPixelFormat default_pix_fmt;
} vaapi_profile_map[] = {
-#define MAP(c, p, v) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, VAProfile ## v }
- MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple ),
- MAP(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main ),
- MAP(H263, UNKNOWN, H263Baseline),
- MAP(MPEG4, MPEG4_SIMPLE, MPEG4Simple ),
+#define MAP(c, p, v, f) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, \
+ VAProfile ## v, AV_PIX_FMT_ ## f }
+ MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple, YUV420P ),
+ MAP(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main, YUV420P ),
+ MAP(H263, UNKNOWN, H263Baseline, YUV420P ),
+ MAP(MPEG4, MPEG4_SIMPLE, MPEG4Simple, YUV420P ),
MAP(MPEG4, MPEG4_ADVANCED_SIMPLE,
- MPEG4AdvancedSimple),
- MAP(MPEG4, MPEG4_MAIN, MPEG4Main ),
+ MPEG4AdvancedSimple, YUV420P ),
+ MAP(MPEG4, MPEG4_MAIN, MPEG4Main, YUV420P ),
MAP(H264, H264_CONSTRAINED_BASELINE,
- H264ConstrainedBaseline),
- MAP(H264, H264_BASELINE, H264Baseline),
- MAP(H264, H264_MAIN, H264Main ),
- MAP(H264, H264_HIGH, H264High ),
+ H264ConstrainedBaseline, YUV420P ),
+ MAP(H264, H264_BASELINE, H264Baseline, YUV420P ),
+ MAP(H264, H264_MAIN, H264Main, YUV420P ),
+ MAP(H264, H264_HIGH, H264High, YUV420P ),
#if VA_CHECK_VERSION(0, 37, 0)
- MAP(HEVC, HEVC_MAIN, HEVCMain ),
- MAP(HEVC, HEVC_MAIN_10, HEVCMain10 ),
+ MAP(HEVC, HEVC_MAIN, HEVCMain, YUV420P ),
+ MAP(HEVC, HEVC_MAIN_10, HEVCMain10, YUV420P10 ),
#endif
- MAP(WMV3, VC1_SIMPLE, VC1Simple ),
- MAP(WMV3, VC1_MAIN, VC1Main ),
- MAP(WMV3, VC1_COMPLEX, VC1Advanced ),
- MAP(WMV3, VC1_ADVANCED, VC1Advanced ),
- MAP(VC1, VC1_SIMPLE, VC1Simple ),
- MAP(VC1, VC1_MAIN, VC1Main ),
- MAP(VC1, VC1_COMPLEX, VC1Advanced ),
- MAP(VC1, VC1_ADVANCED, VC1Advanced ),
+ MAP(WMV3, VC1_SIMPLE, VC1Simple, YUV420P ),
+ MAP(WMV3, VC1_MAIN, VC1Main, YUV420P ),
+ MAP(WMV3, VC1_COMPLEX, VC1Advanced, YUV420P ),
+ MAP(WMV3, VC1_ADVANCED, VC1Advanced, YUV420P ),
+ MAP(VC1, VC1_SIMPLE, VC1Simple, YUV420P ),
+ MAP(VC1, VC1_MAIN, VC1Main, YUV420P ),
+ MAP(VC1, VC1_COMPLEX, VC1Advanced, YUV420P ),
+ MAP(VC1, VC1_ADVANCED, VC1Advanced, YUV420P ),
#if VA_CHECK_VERSION(0, 35, 0)
- MAP(VP8, UNKNOWN, VP8Version0_3 ),
+ MAP(VP8, UNKNOWN, VP8Version0_3, YUV420P ),
#endif
#if VA_CHECK_VERSION(0, 38, 0)
- MAP(VP9, VP9_0, VP9Profile0 ),
+ MAP(VP9, VP9_0, VP9Profile0, YUV420P ),
+#endif
+#if VA_CHECK_VERSION(0, 39, 0)
+ MAP(VP9, VP9_2, VP9Profile2, YUV420P10 ),
#endif
#undef MAP
};
-static int vaapi_decode_make_config(AVCodecContext *avctx)
+static int vaapi_decode_make_config(AVCodecContext *avctx,
+ VAAPIDecodeContext *ctx)
{
- VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
-
AVVAAPIHWConfig *hwconfig = NULL;
AVHWFramesConstraints *constraints = NULL;
VAStatus vas;
int err, i, j;
+ enum AVPixelFormat default_pix_fmt;
const AVCodecDescriptor *codec_desc;
VAProfile profile, *profile_list = NULL;
int profile_count, exact_match, alt_profile;
@@ -317,6 +322,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx)
vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
profile_match = 1;
profile = vaapi_profile_map[i].va_profile;
+ default_pix_fmt = vaapi_profile_map[i].default_pix_fmt;
for (j = 0; j < profile_count; j++) {
if (profile == profile_list[j]) {
exact_match = profile_match;
@@ -327,6 +333,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx)
if (exact_match)
break;
alt_profile = vaapi_profile_map[i].codec_profile;
+ default_pix_fmt = vaapi_profile_map[i].default_pix_fmt;
}
}
av_freep(&profile_list);
@@ -412,7 +419,10 @@ static int vaapi_decode_make_config(AVCodecContext *avctx)
// when 10-bit streams are decoded to 8-bit surfaces, for example)
// then just take the first format on the list.
ctx->surface_format = constraints->valid_sw_formats[0];
- sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
+ if (avctx->sw_pix_fmt != AV_PIX_FMT_NONE)
+ sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
+ else
+ sw_desc = av_pix_fmt_desc_get(default_pix_fmt);
for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
desc = av_pix_fmt_desc_get(constraints->valid_sw_formats[i]);
if (desc->nb_components != sw_desc->nb_components ||
@@ -543,7 +553,7 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
} else {
#endif
- err = vaapi_decode_make_config(avctx);
+ err = vaapi_decode_make_config(avctx, ctx);
if (err)
goto fail;
@@ -632,3 +642,48 @@ int ff_vaapi_decode_uninit(AVCodecContext *avctx)
return 0;
}
+
+int ff_vaapi_decode_probe_hw(AVCodecContext *avctx,
+ AVHWFramesContext *hw_frames)
+{
+ VAAPIDecodeContext *ctx;
+ int err;
+
+ ctx = av_mallocz(sizeof(*ctx));
+ if (!ctx) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ ctx->device = hw_frames->device_ctx;
+ ctx->hwctx = ctx->device->hwctx;
+
+ if (ctx->device->type != AV_HWDEVICE_TYPE_VAAPI) {
+ err = AVERROR(ENODEV);
+ goto fail;
+ }
+
+ err = vaapi_decode_make_config(avctx, ctx);
+ if (err)
+ goto fail;
+
+ if (avctx->coded_width && avctx->coded_height) {
+ hw_frames->width = avctx->coded_width;
+ hw_frames->height = avctx->coded_height;
+ } else {
+ // Not ideal, but if we don't have the stream size information then
+ // there is little else we can do.
+ hw_frames->width = FFALIGN(avctx->width, 16);
+ hw_frames->height = FFALIGN(avctx->height, 16);
+ }
+
+ hw_frames->format = AV_PIX_FMT_VAAPI;
+ hw_frames->sw_format = ctx->surface_format;
+
+ hw_frames->initial_pool_size = ctx->surface_count;
+
+ err = 0;
+fail:
+ av_freep(&ctx);
+ return err;
+}
diff --git a/libavcodec/vaapi_decode.h b/libavcodec/vaapi_decode.h
index 0ff400e34..01da60801 100644
--- a/libavcodec/vaapi_decode.h
+++ b/libavcodec/vaapi_decode.h
@@ -96,4 +96,6 @@ int ff_vaapi_decode_cancel(AVCodecContext *avctx,
int ff_vaapi_decode_init(AVCodecContext *avctx);
int ff_vaapi_decode_uninit(AVCodecContext *avctx);
+int ff_vaapi_decode_probe_hw(AVCodecContext *avctx, AVHWFramesContext
*hw_frames);
+
#endif /* AVCODEC_VAAPI_DECODE_H */
diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
index f76552300..5193a4642 100644
--- a/libavcodec/vaapi_h264.c
+++ b/libavcodec/vaapi_h264.c
@@ -393,6 +393,7 @@ AVHWAccel ff_h264_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.pix_fmt = AV_PIX_FMT_VAAPI,
+ .device_type = AV_HWDEVICE_TYPE_VAAPI,
.start_frame = &vaapi_h264_start_frame,
.end_frame = &vaapi_h264_end_frame,
.decode_slice = &vaapi_h264_decode_slice,
@@ -401,4 +402,5 @@ AVHWAccel ff_h264_vaapi_hwaccel = {
.uninit = &ff_vaapi_decode_uninit,
.priv_data_size = sizeof(VAAPIDecodeContext),
.caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+ .probe_hw = &ff_vaapi_decode_probe_hw,
};
diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
index 4b4d8782a..9d3811863 100644
--- a/libavcodec/vaapi_hevc.c
+++ b/libavcodec/vaapi_hevc.c
@@ -428,6 +428,7 @@ AVHWAccel ff_hevc_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_HEVC,
.pix_fmt = AV_PIX_FMT_VAAPI,
+ .device_type = AV_HWDEVICE_TYPE_VAAPI,
.start_frame = vaapi_hevc_start_frame,
.end_frame = vaapi_hevc_end_frame,
.decode_slice = vaapi_hevc_decode_slice,
@@ -436,4 +437,5 @@ AVHWAccel ff_hevc_vaapi_hwaccel = {
.uninit = ff_vaapi_decode_uninit,
.priv_data_size = sizeof(VAAPIDecodeContext),
.caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+ .probe_hw = &ff_vaapi_decode_probe_hw,
};
diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c
index a14d115fb..2b09d9194 100644
--- a/libavcodec/vaapi_mpeg2.c
+++ b/libavcodec/vaapi_mpeg2.c
@@ -178,6 +178,7 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_MPEG2VIDEO,
.pix_fmt = AV_PIX_FMT_VAAPI,
+ .device_type = AV_HWDEVICE_TYPE_VAAPI,
.start_frame = &vaapi_mpeg2_start_frame,
.end_frame = &vaapi_mpeg2_end_frame,
.decode_slice = &vaapi_mpeg2_decode_slice,
@@ -186,4 +187,5 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = {
.uninit = &ff_vaapi_decode_uninit,
.priv_data_size = sizeof(VAAPIDecodeContext),
.caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+ .probe_hw = &ff_vaapi_decode_probe_hw,
};
diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c
index b4819b804..8db594170 100644
--- a/libavcodec/vaapi_mpeg4.c
+++ b/libavcodec/vaapi_mpeg4.c
@@ -194,6 +194,7 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_MPEG4,
.pix_fmt = AV_PIX_FMT_VAAPI,
+ .device_type = AV_HWDEVICE_TYPE_VAAPI,
.start_frame = &vaapi_mpeg4_start_frame,
.end_frame = &vaapi_mpeg4_end_frame,
.decode_slice = &vaapi_mpeg4_decode_slice,
@@ -202,6 +203,7 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = {
.uninit = &ff_vaapi_decode_uninit,
.priv_data_size = sizeof(VAAPIDecodeContext),
.caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+ .probe_hw = &ff_vaapi_decode_probe_hw,
};
#endif
@@ -211,6 +213,7 @@ AVHWAccel ff_h263_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H263,
.pix_fmt = AV_PIX_FMT_VAAPI,
+ .device_type = AV_HWDEVICE_TYPE_VAAPI,
.start_frame = &vaapi_mpeg4_start_frame,
.end_frame = &vaapi_mpeg4_end_frame,
.decode_slice = &vaapi_mpeg4_decode_slice,
@@ -219,5 +222,6 @@ AVHWAccel ff_h263_vaapi_hwaccel = {
.uninit = &ff_vaapi_decode_uninit,
.priv_data_size = sizeof(VAAPIDecodeContext),
.caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+ .probe_hw = &ff_vaapi_decode_probe_hw,
};
#endif
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index 42634f2ba..1854657e0 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -393,6 +393,7 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_WMV3,
.pix_fmt = AV_PIX_FMT_VAAPI,
+ .device_type = AV_HWDEVICE_TYPE_VAAPI,
.start_frame = &vaapi_vc1_start_frame,
.end_frame = &vaapi_vc1_end_frame,
.decode_slice = &vaapi_vc1_decode_slice,
@@ -401,6 +402,7 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = {
.uninit = &ff_vaapi_decode_uninit,
.priv_data_size = sizeof(VAAPIDecodeContext),
.caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+ .probe_hw = &ff_vaapi_decode_probe_hw,
};
#endif
@@ -409,6 +411,7 @@ AVHWAccel ff_vc1_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_VC1,
.pix_fmt = AV_PIX_FMT_VAAPI,
+ .device_type = AV_HWDEVICE_TYPE_VAAPI,
.start_frame = &vaapi_vc1_start_frame,
.end_frame = &vaapi_vc1_end_frame,
.decode_slice = &vaapi_vc1_decode_slice,
@@ -417,4 +420,5 @@ AVHWAccel ff_vc1_vaapi_hwaccel = {
.uninit = &ff_vaapi_decode_uninit,
.priv_data_size = sizeof(VAAPIDecodeContext),
.caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+ .probe_hw = &ff_vaapi_decode_probe_hw,
};
diff --git a/libavcodec/vaapi_vp8.c b/libavcodec/vaapi_vp8.c
index 1ba5c7ec9..6e5ffdeb6 100644
--- a/libavcodec/vaapi_vp8.c
+++ b/libavcodec/vaapi_vp8.c
@@ -225,6 +225,7 @@ AVHWAccel ff_vp8_vaapi_hwaccel = {
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_VP8,
.pix_fmt = AV_PIX_FMT_VAAPI,
+ .device_type = AV_HWDEVICE_TYPE_VAAPI,
.start_frame = &vaapi_vp8_start_frame,
.end_frame = &vaapi_vp8_end_frame,
.decode_slice = &vaapi_vp8_decode_slice,
@@ -233,4 +234,5 @@ AVHWAccel ff_vp8_vaapi_hwaccel = {
.uninit = &ff_vaapi_decode_uninit,
.priv_data_size = sizeof(VAAPIDecodeContext),
.caps_internal = HWACCEL_CAP_ASYNC_SAFE,
+ .probe_hw = &ff_vaapi_decode_probe_hw,
};
--
2.11.0
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel