libs: dec: h265: add 422 chroma format support.

Add main-422-10 profile which support 422 chroma format stream.
Currently, this feature is only supported by media-driver in Icelake.

https://bugzilla.gnome.org/show_bug.cgi?id=797143
This commit is contained in:
Wangfei 2018-09-20 09:57:33 +08:00 committed by Víctor Manuel Jáquez Leal
parent 37a756fd91
commit 619abbdeb4
12 changed files with 128 additions and 50 deletions

View file

@ -1053,8 +1053,7 @@ get_profile (GstVaapiDecoderH265 * decoder, GstH265SPS * sps, guint dpb_size)
GstVaapiProfile profile, profiles[3];
guint i, n_profiles = 0;
profile =
gst_vaapi_utils_h265_get_profile (sps->profile_tier_level.profile_idc);
profile = gst_vaapi_utils_h265_get_profile (sps);
if (!profile) {
/* HACK: This is a work-around to identify some main profile streams having wrong profile_idc.
* There are some wrongly encoded main profile streams(eg: ENTP_C_LG_3.bin) which doesn't

View file

@ -132,6 +132,10 @@ static const GstVaapiProfileMap gst_vaapi_profiles[] = {
{GST_VAAPI_PROFILE_H265_MAIN10, VAProfileHEVCMain10,
"video/x-h265", "main-10"},
#endif
#if VA_CHECK_VERSION(1,2,0)
{GST_VAAPI_PROFILE_H265_MAIN_422_10, VAProfileHEVCMain422_10,
"video/x-h265", "main-422-10"},
#endif
#if VA_CHECK_VERSION(0,38,0)
{GST_VAAPI_PROFILE_VP9_0, VAProfileVP9Profile0,
"video/x-vp9", "profile0"},
@ -330,6 +334,8 @@ gst_vaapi_profile_from_codec_data_h265 (GstBuffer * buffer)
return GST_VAAPI_PROFILE_H265_MAIN10;
case 3:
return GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE;
case 4:
return GST_VAAPI_PROFILE_H265_MAIN_422_10;
}
return 0;
}

View file

@ -131,6 +131,8 @@ typedef enum {
* H.265 main 10 profile [A.3.3]
* @GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE:
* H.265 main still picture profile [A.3.4]
* @GST_VAAPI_PROFILE_H265_MAIN_422_10:
* H.265 main still picture profile [A.3.5]
* @GST_VAAPI_PROFILE_VP9_0:
* VP9 prfile 0, bitdepth=8, 420
* @GST_VAAPI_PROFILE_VP9_1:
@ -175,6 +177,7 @@ typedef enum {
GST_VAAPI_PROFILE_H265_MAIN10 = GST_VAAPI_MAKE_PROFILE(H265,2),
GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE =
GST_VAAPI_MAKE_PROFILE(H265,3),
GST_VAAPI_PROFILE_H265_MAIN_422_10 = GST_VAAPI_MAKE_PROFILE(H265,4),
GST_VAAPI_PROFILE_VP9_0 = GST_VAAPI_MAKE_PROFILE(VP9,1),
GST_VAAPI_PROFILE_VP9_1 = GST_VAAPI_MAKE_PROFILE(VP9,2),
GST_VAAPI_PROFILE_VP9_2 = GST_VAAPI_MAKE_PROFILE(VP9,3),

View file

@ -340,6 +340,20 @@ gst_vaapi_surface_new (GstVaapiDisplay * display,
if (!surface)
return NULL;
/* first try a recent version of vaCreateSurface, and later use as
* fallback its old version */
#if VA_CHECK_VERSION(0,34,0)
{
GstVideoInfo vi;
GstVideoFormat surface_format;
surface_format = gst_vaapi_video_format_from_chroma (chroma_type);
gst_video_info_set_format (&vi, surface_format, width, height);
if (gst_vaapi_surface_create_full (surface, &vi, 0))
return surface;
}
#endif
if (!gst_vaapi_surface_create (surface, chroma_type, width, height))
goto error;
return surface;

View file

@ -228,6 +228,9 @@ string_of_VAProfile (VAProfile profile)
MAP (H264MultiviewHigh);
MAP (H264StereoHigh);
#endif
#if VA_CHECK_VERSION(1,2,0)
MAP (HEVCMain422_10);
#endif
#if VA_CHECK_VERSION(0,37,1)
MAP (HEVCMain);
MAP (HEVCMain10);

View file

@ -132,11 +132,11 @@ gst_vaapi_utils_h265_get_profile_score (GstVaapiProfile profile)
/** Returns GstVaapiProfile from H.265 profile_idc value */
GstVaapiProfile
gst_vaapi_utils_h265_get_profile (guint8 profile_idc)
gst_vaapi_utils_h265_get_profile (GstH265SPS * sps)
{
GstVaapiProfile profile;
switch (profile_idc) {
switch (sps->profile_tier_level.profile_idc) {
case GST_H265_PROFILE_IDC_MAIN:
profile = GST_VAAPI_PROFILE_H265_MAIN;
break;
@ -146,6 +146,19 @@ gst_vaapi_utils_h265_get_profile (guint8 profile_idc)
case GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE:
profile = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE;
break;
case GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION:
if (sps->profile_tier_level.max_12bit_constraint_flag == 1
&& sps->profile_tier_level.max_10bit_constraint_flag == 1
&& sps->profile_tier_level.max_8bit_constraint_flag == 0
&& sps->profile_tier_level.max_422chroma_constraint_flag == 1
&& sps->profile_tier_level.max_420chroma_constraint_flag == 0
&& sps->profile_tier_level.max_monochrome_constraint_flag == 0
&& sps->profile_tier_level.intra_constraint_flag == 0
&& sps->profile_tier_level.one_picture_only_constraint_flag == 0
&& sps->profile_tier_level.lower_bit_rate_constraint_flag == 1) {
profile = GST_VAAPI_PROFILE_H265_MAIN_422_10;
break;
}
default:
g_debug ("unsupported profile_idc value");
profile = GST_VAAPI_PROFILE_UNKNOWN;
@ -170,6 +183,9 @@ gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile)
case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE:
profile_idc = GST_H265_PROFILE_MAIN_STILL_PICTURE;
break;
case GST_VAAPI_PROFILE_H265_MAIN_422_10:
profile_idc = GST_H265_PROFILE_MAIN_422_10;
break;
default:
g_debug ("unsupported GstVaapiProfile value");
profile_idc = 0;

View file

@ -63,7 +63,7 @@ typedef struct {
/* Returns GstVaapiProfile from H.265 profile_idc value */
G_GNUC_INTERNAL
GstVaapiProfile
gst_vaapi_utils_h265_get_profile (guint8 profile_idc);
gst_vaapi_utils_h265_get_profile (GstH265SPS * sps);
/* Returns H.265 profile_idc value from GstVaapiProfile */
G_GNUC_INTERNAL

View file

@ -274,6 +274,35 @@ gst_vaapi_video_format_get_score (GstVideoFormat format)
return m ? (m - &gst_vaapi_video_formats[0]) : G_MAXUINT;
}
/**
* gst_vaapi_video_format_from_chroma:
* @chroma_type: a #GstVaapiChromaType
*
* Returns the "preferred" pixel format that matches with
* @chroma_type.
*
* Returns: the preferred pixel format for @chroma_type
**/
GstVideoFormat
gst_vaapi_video_format_from_chroma (guint chroma_type)
{
switch (chroma_type) {
case GST_VAAPI_CHROMA_TYPE_YUV422:
return GST_VIDEO_FORMAT_YUY2;
case GST_VAAPI_CHROMA_TYPE_YUV400:
return GST_VIDEO_FORMAT_GRAY8;
case GST_VAAPI_CHROMA_TYPE_YUV420:
case GST_VAAPI_CHROMA_TYPE_RGB32: /* GstVideoGLTextureUploadMeta */
return GST_VIDEO_FORMAT_NV12;
case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP:
return GST_VIDEO_FORMAT_P010_10LE;
case GST_VAAPI_CHROMA_TYPE_YUV444:
return GST_VIDEO_FORMAT_AYUV;
default:
return GST_VIDEO_FORMAT_UNKNOWN;
}
}
/**
* gst_vaapi_video_format_get_best_native:
* @format: a #GstVideoFormat
@ -293,17 +322,5 @@ gst_vaapi_video_format_get_best_native (GstVideoFormat format)
return GST_VIDEO_FORMAT_NV12;
chroma_type = gst_vaapi_video_format_get_chroma_type (format);
switch (chroma_type) {
case GST_VAAPI_CHROMA_TYPE_YUV422:
return GST_VIDEO_FORMAT_YUY2;
case GST_VAAPI_CHROMA_TYPE_YUV400:
return GST_VIDEO_FORMAT_GRAY8;
case GST_VAAPI_CHROMA_TYPE_YUV420:
case GST_VAAPI_CHROMA_TYPE_RGB32: /* GstVideoGLTextureUploadMeta */
return GST_VIDEO_FORMAT_NV12;
case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP:
return GST_VIDEO_FORMAT_P010_10LE;
default:
return GST_VIDEO_FORMAT_UNKNOWN;
};
return gst_vaapi_video_format_from_chroma (chroma_type);
}

View file

@ -53,6 +53,9 @@ gst_vaapi_video_format_get_chroma_type (GstVideoFormat format);
guint
gst_vaapi_video_format_get_score (GstVideoFormat format);
GstVideoFormat
gst_vaapi_video_format_from_chroma (guint chroma);
GstVideoFormat
gst_vaapi_video_format_get_best_native (GstVideoFormat format);

View file

@ -87,7 +87,7 @@ static const char gst_vaapidecode_src_caps_str[] =
#if (USE_GLX || USE_EGL)
GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS ";"
#endif
GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, P010_10LE }") ";"
GST_VIDEO_CAPS_MAKE("{ NV12, I420, YV12, YUY2, UYVY, P010_10LE }") ";"
GST_VAAPI_MAKE_DMABUF_CAPS;
static GstStaticPadTemplate gst_vaapidecode_src_factory =

View file

@ -1253,51 +1253,70 @@ no_valid_gl_display:
#endif
}
static GArray *
extract_allowed_surface_formats (GstVaapiDisplay * display, GArray * formats)
{
guint i;
GArray *out_formats;
out_formats =
g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), formats->len);
if (!out_formats)
return NULL;
for (i = 0; i < formats->len; i++) {
const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
GstVaapiChromaType chroma_type;
GstVaapiSurface *surface;
GstVaapiImage *image;
if (format == GST_VIDEO_FORMAT_UNKNOWN)
continue;
chroma_type = gst_vaapi_video_format_get_chroma_type (format);
if (chroma_type == 0)
continue;
surface = gst_vaapi_surface_new (display, chroma_type, 64, 64);
if (!surface)
continue;
image = gst_vaapi_image_new (display, format, 64, 64);
if (!image) {
gst_vaapi_object_unref (surface);
continue;
}
if (gst_vaapi_surface_put_image (surface, image))
g_array_append_val (out_formats, format);
gst_vaapi_object_unref (image);
gst_vaapi_object_unref (surface);
}
if (out_formats->len == 0) {
g_array_unref (out_formats);
return NULL;
}
return out_formats;
}
static gboolean
ensure_allowed_raw_caps (GstVaapiPluginBase * plugin)
{
GArray *formats, *out_formats;
GstVaapiSurface *surface;
GstVaapiDisplay *display;
guint i;
GstCaps *out_caps;
gboolean ret = FALSE;
if (plugin->allowed_raw_caps)
return TRUE;
out_formats = formats = NULL;
surface = NULL;
out_formats = NULL;
display = gst_object_ref (plugin->display);
formats = gst_vaapi_display_get_image_formats (display);
if (!formats)
goto bail;
out_formats =
g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), formats->len);
out_formats = extract_allowed_surface_formats (display, formats);
if (!out_formats)
goto bail;
surface =
gst_vaapi_surface_new (display, GST_VAAPI_CHROMA_TYPE_YUV420, 64, 64);
if (!surface)
goto bail;
for (i = 0; i < formats->len; i++) {
const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
GstVaapiImage *image;
if (format == GST_VIDEO_FORMAT_UNKNOWN)
continue;
image = gst_vaapi_image_new (display, format, 64, 64);
if (!image)
continue;
if (gst_vaapi_surface_put_image (surface, image))
g_array_append_val (out_formats, format);
gst_vaapi_object_unref (image);
}
out_caps = gst_vaapi_video_format_new_template_caps_from_list (out_formats);
if (!out_caps)
goto bail;
@ -1311,8 +1330,6 @@ bail:
g_array_unref (formats);
if (out_formats)
g_array_unref (out_formats);
if (surface)
gst_vaapi_object_unref (surface);
gst_object_unref (display);
return ret;

View file

@ -105,7 +105,7 @@ gst_vaapi_caps_feature_contains (const GstCaps * caps,
#define GST_VAAPI_MAKE_SURFACE_CAPS \
GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \
GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, P010_10LE }")
GST_CAPS_FEATURE_MEMORY_VAAPI_SURFACE, "{ ENCODED, NV12, I420, YV12, YUY2, UYVY, P010_10LE }")
#define GST_VAAPI_MAKE_GLTEXUPLOAD_CAPS \
GST_VIDEO_CAPS_MAKE_WITH_FEATURES( \