mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +00:00
libs: video-format: Refine the video format mapping.
Improve the mapping between va format and gst format. The new map will be generated dynamically, based on the query result of image format in VA driver. Also consider the ambiguity of RGB color format in LSB mode.
This commit is contained in:
parent
a90daabb84
commit
32bf6f1e09
3 changed files with 301 additions and 62 deletions
|
@ -675,6 +675,11 @@ ensure_image_formats (GstVaapiDisplay * display)
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc));
|
GST_DEBUG (" %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (formats[i].fourcc));
|
||||||
|
|
||||||
|
if (!gst_vaapi_video_format_create_map (formats, n)) {
|
||||||
|
GST_ERROR ("fail to create map between gst video format and vaImageFormat");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
append_formats (priv->image_formats, formats, NULL, n);
|
append_formats (priv->image_formats, formats, NULL, n);
|
||||||
g_array_sort (priv->image_formats, compare_yuv_formats);
|
g_array_sort (priv->image_formats, compare_yuv_formats);
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
|
@ -906,6 +911,12 @@ gst_vaapi_display_create (GstVaapiDisplay * display,
|
||||||
GST_INFO_OBJECT (display, "new display addr=%p", display);
|
GST_INFO_OBJECT (display, "new display addr=%p", display);
|
||||||
g_free (priv->display_name);
|
g_free (priv->display_name);
|
||||||
priv->display_name = g_strdup (info.display_name);
|
priv->display_name = g_strdup (info.display_name);
|
||||||
|
|
||||||
|
if (!ensure_image_formats (display)) {
|
||||||
|
gst_vaapi_display_destroy (display);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,59 +38,128 @@
|
||||||
# define VIDEO_VA_ENDIANESS VA_LSB_FIRST
|
# define VIDEO_VA_ENDIANESS VA_LSB_FIRST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct _GstVideoFormatMapMap
|
||||||
{
|
{
|
||||||
GstVideoFormat format;
|
GstVideoFormat format;
|
||||||
GstVaapiChromaType chroma_type;
|
GstVaapiChromaType chroma_type;
|
||||||
VAImageFormat va_format;
|
VAImageFormat va_format;
|
||||||
} GstVideoFormatMap;
|
} GstVideoFormatMap;
|
||||||
|
|
||||||
#define DEF_YUV(FORMAT, FOURCC, BPP, SUB) \
|
#define VA_BYTE_ORDER_NOT_CARE 0
|
||||||
|
|
||||||
|
#define DEF_YUV(BYTE_ORDER, FORMAT, FOURCC, BPP, SUB) \
|
||||||
{ G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \
|
{ G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \
|
||||||
G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB), \
|
G_PASTE(GST_VAAPI_CHROMA_TYPE_YUV,SUB), \
|
||||||
{ VA_FOURCC FOURCC, VIDEO_VA_ENDIANESS, BPP, }, }
|
{ VA_FOURCC FOURCC, BYTE_ORDER, BPP, }, }
|
||||||
|
|
||||||
#define DEF_RGB(FORMAT, FOURCC, BPP, DEPTH, R,G,B,A) \
|
#define DEF_RGB(BYTE_ORDER, FORMAT, FOURCC, BPP, DEPTH, R,G,B,A) \
|
||||||
{ G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \
|
{ G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \
|
||||||
G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP), \
|
G_PASTE(GST_VAAPI_CHROMA_TYPE_RGB,BPP), \
|
||||||
{ VA_FOURCC FOURCC, VIDEO_VA_ENDIANESS, BPP, DEPTH, R,G,B,A }, }
|
{ VA_FOURCC FOURCC, BYTE_ORDER, BPP, DEPTH, R, G, B, A }, }
|
||||||
|
|
||||||
/* Image formats, listed in HW order preference */
|
/* Image formats, listed in HW order preference */
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
static const GstVideoFormatMap gst_vaapi_video_formats[] = {
|
static const GstVideoFormatMap gst_vaapi_video_default_formats[] = {
|
||||||
|
/* LSB and MSB video formats definitions are unclear and ambiguous.
|
||||||
|
*
|
||||||
|
* For MSB, there is no ambiguity: same order in define, memory and
|
||||||
|
* CPU. For example,
|
||||||
|
*
|
||||||
|
* RGBA is RGBA in memory and RGBA with channel mask R:0xFF0000
|
||||||
|
* G:0x00FF0000 B:0x0000FF00 A:0x000000FF in CPU.
|
||||||
|
*
|
||||||
|
* For LSB, CPU's perspective and memory's perspective are
|
||||||
|
* different. For example,
|
||||||
|
*
|
||||||
|
* RGBA in LSB, from CPU's perspective, it's RGBA order in memory,
|
||||||
|
* but when it is stored in memory, because CPU's little
|
||||||
|
* endianness, it will be re-ordered, with mask R:0x000000FF
|
||||||
|
* G:0x0000FF00 B:0x00FF0000 A:0xFF000000. In other words, from
|
||||||
|
* memory's perspective, RGBA LSB is equal as ABGR MSB.
|
||||||
|
*
|
||||||
|
* These definitions are mixed used all over the media system and we
|
||||||
|
* need to correct the mapping form VA video format to GStreamer
|
||||||
|
* video format in both manners, especially for RGB format.
|
||||||
|
*/
|
||||||
|
|
||||||
/* YUV formats */
|
/* YUV formats */
|
||||||
DEF_YUV (NV12, ('N', 'V', '1', '2'), 12, 420),
|
DEF_YUV (VA_BYTE_ORDER_NOT_CARE, NV12, ('N', 'V', '1', '2'), 12, 420),
|
||||||
DEF_YUV (YV12, ('Y', 'V', '1', '2'), 12, 420),
|
DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YV12, ('Y', 'V', '1', '2'), 12, 420),
|
||||||
DEF_YUV (I420, ('I', '4', '2', '0'), 12, 420),
|
DEF_YUV (VA_BYTE_ORDER_NOT_CARE, I420, ('I', '4', '2', '0'), 12, 420),
|
||||||
DEF_YUV (YUY2, ('Y', 'U', 'Y', '2'), 16, 422),
|
DEF_YUV (VA_BYTE_ORDER_NOT_CARE, YUY2, ('Y', 'U', 'Y', '2'), 16, 422),
|
||||||
DEF_YUV (UYVY, ('U', 'Y', 'V', 'Y'), 16, 422),
|
DEF_YUV (VA_BYTE_ORDER_NOT_CARE, UYVY, ('U', 'Y', 'V', 'Y'), 16, 422),
|
||||||
DEF_YUV (Y210, ('Y', '2', '1', '0'), 32, 422_10BPP),
|
|
||||||
DEF_YUV (Y410, ('Y', '4', '1', '0'), 32, 444_10BPP),
|
DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y444, ('4', '4', '4', 'P'), 24, 444),
|
||||||
DEF_YUV (AYUV, ('A', 'Y', 'U', 'V'), 32, 444),
|
DEF_YUV (VA_BYTE_ORDER_NOT_CARE, GRAY8, ('Y', '8', '0', '0'), 8, 400),
|
||||||
DEF_YUV (Y444, ('4', '4', '4', 'P'), 24, 444),
|
|
||||||
DEF_YUV (GRAY8, ('Y', '8', '0', '0'), 8, 400),
|
DEF_YUV (VA_LSB_FIRST, P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP),
|
||||||
DEF_YUV (P010_10LE, ('P', '0', '1', '0'), 24, 420_10BPP),
|
/* AYUV is a clear defined format by doc */
|
||||||
|
DEF_YUV (VA_LSB_FIRST, VUYA, ('A', 'Y', 'U', 'V'), 32, 444),
|
||||||
|
|
||||||
|
DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y210, ('Y', '2', '1', '0'), 32, 422_10BPP),
|
||||||
|
DEF_YUV (VA_BYTE_ORDER_NOT_CARE, Y410, ('Y', '4', '1', '0'), 32, 444_10BPP),
|
||||||
|
|
||||||
/* RGB formats */
|
/* RGB formats */
|
||||||
DEF_RGB (ARGB, ('A', 'R', 'G', 'B'), 32,
|
DEF_RGB (VA_LSB_FIRST, ARGB, ('A', 'R', 'G', 'B'), 32, 32, 0x0000ff00,
|
||||||
32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
|
0x00ff0000, 0xff000000, 0x000000ff),
|
||||||
DEF_RGB (ABGR, ('A', 'B', 'G', 'R'), 32,
|
DEF_RGB (VA_LSB_FIRST, ARGB, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00,
|
||||||
32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
|
0x00ff0000, 0xff000000, 0x000000ff),
|
||||||
DEF_RGB (xRGB, ('X', 'R', 'G', 'B'), 32,
|
DEF_RGB (VA_MSB_FIRST, ARGB, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000,
|
||||||
24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000),
|
0x0000ff00, 0x000000ff, 0xff000000),
|
||||||
DEF_RGB (xBGR, ('X', 'B', 'G', 'R'), 32,
|
|
||||||
24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000),
|
DEF_RGB (VA_LSB_FIRST, xRGB, ('X', 'R', 'G', 'B'), 32, 24, 0x0000ff00,
|
||||||
DEF_RGB (BGRA, ('B', 'G', 'R', 'A'), 32,
|
0x00ff0000, 0xff000000, 0x00000000),
|
||||||
32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
|
DEF_RGB (VA_LSB_FIRST, xRGB, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00,
|
||||||
DEF_RGB (RGBA, ('R', 'G', 'B', 'A'), 32,
|
0x00ff0000, 0xff000000, 0x00000000),
|
||||||
32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
|
DEF_RGB (VA_MSB_FIRST, xRGB, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000,
|
||||||
DEF_RGB (BGRx, ('B', 'G', 'R', 'X'), 32,
|
0x0000ff00, 0x000000ff, 0x00000000),
|
||||||
24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000),
|
|
||||||
DEF_RGB (RGBx, ('R', 'G', 'B', 'X'), 32,
|
DEF_RGB (VA_LSB_FIRST, RGBA, ('R', 'G', 'B', 'A'), 32, 32, 0x000000ff,
|
||||||
24, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000),
|
0x0000ff00, 0x00ff0000, 0xff000000),
|
||||||
DEF_RGB (RGB16, ('R', 'G', '1', '6'), 16,
|
DEF_RGB (VA_LSB_FIRST, RGBA, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff,
|
||||||
16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000),
|
0x0000ff00, 0x00ff0000, 0xff000000),
|
||||||
DEF_RGB (RGB, ('R', 'G', '2', '4'), 32,
|
DEF_RGB (VA_MSB_FIRST, RGBA, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000,
|
||||||
24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000),
|
0x00ff0000, 0x0000ff00, 0x000000ff),
|
||||||
|
|
||||||
|
DEF_RGB (VA_LSB_FIRST, RGBx, ('R', 'G', 'B', 'X'), 32, 24, 0x000000ff,
|
||||||
|
0x0000ff00, 0x00ff0000, 0x00000000),
|
||||||
|
DEF_RGB (VA_LSB_FIRST, RGBx, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff,
|
||||||
|
0x0000ff00, 0x00ff0000, 0x00000000),
|
||||||
|
DEF_RGB (VA_MSB_FIRST, RGBx, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000,
|
||||||
|
0x00ff0000, 0x0000ff00, 0x00000000),
|
||||||
|
|
||||||
|
DEF_RGB (VA_LSB_FIRST, ABGR, ('A', 'B', 'G', 'R'), 32, 32, 0xff000000,
|
||||||
|
0x00ff0000, 0x0000ff00, 0x000000ff),
|
||||||
|
DEF_RGB (VA_LSB_FIRST, ABGR, ('R', 'G', 'B', 'A'), 32, 32, 0xff000000,
|
||||||
|
0x00ff0000, 0x0000ff00, 0x000000ff),
|
||||||
|
DEF_RGB (VA_MSB_FIRST, ABGR, ('A', 'B', 'G', 'R'), 32, 32, 0x000000ff,
|
||||||
|
0x0000ff00, 0x00ff0000, 0xff000000),
|
||||||
|
|
||||||
|
DEF_RGB (VA_LSB_FIRST, xBGR, ('X', 'B', 'G', 'R'), 32, 24, 0xff000000,
|
||||||
|
0x00ff0000, 0x0000ff00, 0x00000000),
|
||||||
|
DEF_RGB (VA_LSB_FIRST, xBGR, ('R', 'G', 'B', 'X'), 32, 24, 0xff000000,
|
||||||
|
0x00ff0000, 0x0000ff00, 0x00000000),
|
||||||
|
DEF_RGB (VA_MSB_FIRST, xBGR, ('X', 'B', 'G', 'R'), 32, 24, 0x000000ff,
|
||||||
|
0x0000ff00, 0x00ff0000, 0x00000000),
|
||||||
|
|
||||||
|
DEF_RGB (VA_LSB_FIRST, BGRA, ('B', 'G', 'R', 'A'), 32, 32, 0x00ff0000,
|
||||||
|
0x0000ff00, 0x000000ff, 0xff000000),
|
||||||
|
DEF_RGB (VA_LSB_FIRST, BGRA, ('A', 'R', 'G', 'B'), 32, 32, 0x00ff0000,
|
||||||
|
0x0000ff00, 0x000000ff, 0xff000000),
|
||||||
|
DEF_RGB (VA_MSB_FIRST, BGRA, ('B', 'G', 'R', 'A'), 32, 32, 0x0000ff00,
|
||||||
|
0x00ff0000, 0xff000000, 0x000000ff),
|
||||||
|
|
||||||
|
DEF_RGB (VA_LSB_FIRST, BGRx, ('B', 'G', 'R', 'X'), 32, 24, 0x00ff0000,
|
||||||
|
0x0000ff00, 0x000000ff, 0x00000000),
|
||||||
|
DEF_RGB (VA_LSB_FIRST, BGRx, ('X', 'R', 'G', 'B'), 32, 24, 0x00ff0000,
|
||||||
|
0x0000ff00, 0x000000ff, 0x00000000),
|
||||||
|
DEF_RGB (VA_MSB_FIRST, BGRx, ('B', 'G', 'R', 'X'), 32, 24, 0x0000ff00,
|
||||||
|
0x00ff0000, 0xff000000, 0x00000000),
|
||||||
|
|
||||||
|
DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB16, ('R', 'G', '1', '6'), 16, 16,
|
||||||
|
0x0000f800, 0x000007e0, 0x0000001f, 0x00000000),
|
||||||
|
DEF_RGB (VA_BYTE_ORDER_NOT_CARE, RGB, ('R', 'G', '2', '4'), 32, 24,
|
||||||
|
0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000),
|
||||||
{0,}
|
{0,}
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
@ -98,6 +167,8 @@ static const GstVideoFormatMap gst_vaapi_video_formats[] = {
|
||||||
#undef DEF_RGB
|
#undef DEF_RGB
|
||||||
#undef DEF_YUV
|
#undef DEF_YUV
|
||||||
|
|
||||||
|
static GArray *gst_vaapi_video_formats_map;
|
||||||
|
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
va_format_is_rgb (const VAImageFormat * va_format)
|
va_format_is_rgb (const VAImageFormat * va_format)
|
||||||
{
|
{
|
||||||
|
@ -113,8 +184,7 @@ va_format_is_yuv (const VAImageFormat * va_format)
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
va_format_is_same_rgb (const VAImageFormat * fmt1, const VAImageFormat * fmt2)
|
va_format_is_same_rgb (const VAImageFormat * fmt1, const VAImageFormat * fmt2)
|
||||||
{
|
{
|
||||||
return (fmt1->byte_order == fmt2->byte_order &&
|
return (fmt1->red_mask == fmt2->red_mask &&
|
||||||
fmt1->red_mask == fmt2->red_mask &&
|
|
||||||
fmt1->green_mask == fmt2->green_mask &&
|
fmt1->green_mask == fmt2->green_mask &&
|
||||||
fmt1->blue_mask == fmt2->blue_mask &&
|
fmt1->blue_mask == fmt2->blue_mask &&
|
||||||
fmt1->alpha_mask == fmt2->alpha_mask);
|
fmt1->alpha_mask == fmt2->alpha_mask);
|
||||||
|
@ -125,21 +195,89 @@ va_format_is_same (const VAImageFormat * fmt1, const VAImageFormat * fmt2)
|
||||||
{
|
{
|
||||||
if (fmt1->fourcc != fmt2->fourcc)
|
if (fmt1->fourcc != fmt2->fourcc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
if (fmt1->byte_order != VA_BYTE_ORDER_NOT_CARE &&
|
||||||
|
fmt2->byte_order != VA_BYTE_ORDER_NOT_CARE &&
|
||||||
|
fmt1->byte_order != fmt2->byte_order)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return va_format_is_rgb (fmt1) ? va_format_is_same_rgb (fmt1, fmt2) : TRUE;
|
return va_format_is_rgb (fmt1) ? va_format_is_same_rgb (fmt1, fmt2) : TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GstVideoFormatMap *
|
static const GstVideoFormatMap *
|
||||||
get_map (GstVideoFormat format)
|
get_map_in_default_by_gst_format (GstVideoFormat format)
|
||||||
{
|
{
|
||||||
const GstVideoFormatMap *m;
|
const GstVideoFormatMap *m;
|
||||||
|
for (m = gst_vaapi_video_default_formats; m->format; m++) {
|
||||||
for (m = gst_vaapi_video_formats; m->format; m++) {
|
|
||||||
if (m->format == format)
|
if (m->format == format)
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const GstVideoFormatMap *
|
||||||
|
get_map_in_default_by_va_format (const VAImageFormat * va_format)
|
||||||
|
{
|
||||||
|
const GstVideoFormatMap *m, *n;
|
||||||
|
|
||||||
|
n = NULL;
|
||||||
|
for (m = gst_vaapi_video_default_formats; m->format; m++) {
|
||||||
|
if (va_format_is_same (&m->va_format, va_format)) {
|
||||||
|
/* Should not map to VAImageFormat to same GstVideoFormat */
|
||||||
|
g_assert (n == NULL);
|
||||||
|
n = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GstVideoFormatMap *
|
||||||
|
get_map_by_gst_format (const GArray * formats, GstVideoFormat format)
|
||||||
|
{
|
||||||
|
const GstVideoFormatMap *entry;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < formats->len; i++) {
|
||||||
|
entry = &g_array_index (formats, GstVideoFormatMap, i);
|
||||||
|
if (entry->format == format)
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GstVideoFormatMap *
|
||||||
|
get_map_by_va_format (const VAImageFormat * va_format)
|
||||||
|
{
|
||||||
|
const GArray *formats = gst_vaapi_video_formats_map;
|
||||||
|
const GstVideoFormatMap *entry;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < formats->len; i++) {
|
||||||
|
entry = &g_array_index (formats, GstVideoFormatMap, i);
|
||||||
|
if (va_format_is_same (&entry->va_format, va_format))
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static guint
|
||||||
|
get_fmt_score_in_default (GstVideoFormat format)
|
||||||
|
{
|
||||||
|
const GstVideoFormatMap *const m = get_map_in_default_by_gst_format (format);
|
||||||
|
|
||||||
|
return m ? (m - &gst_vaapi_video_default_formats[0]) : G_MAXUINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
video_format_compare_by_score (gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
const GstVideoFormatMap *m1 = (GstVideoFormatMap *) a;
|
||||||
|
const GstVideoFormatMap *m2 = (GstVideoFormatMap *) b;
|
||||||
|
|
||||||
|
return ((gint) get_fmt_score_in_default (m1->format) -
|
||||||
|
(gint) get_fmt_score_in_default (m2->format));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_video_format_to_string:
|
* gst_vaapi_video_format_to_string:
|
||||||
* @format: a #GstVideoFormat
|
* @format: a #GstVideoFormat
|
||||||
|
@ -166,8 +304,8 @@ gst_vaapi_video_format_to_string (GstVideoFormat format)
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_video_format_is_rgb (GstVideoFormat format)
|
gst_vaapi_video_format_is_rgb (GstVideoFormat format)
|
||||||
{
|
{
|
||||||
const GstVideoFormatMap *const m = get_map (format);
|
const GstVideoFormatMap *const m =
|
||||||
|
get_map_by_gst_format (gst_vaapi_video_formats_map, format);
|
||||||
return m && va_format_is_rgb (&m->va_format);
|
return m && va_format_is_rgb (&m->va_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,8 +320,8 @@ gst_vaapi_video_format_is_rgb (GstVideoFormat format)
|
||||||
gboolean
|
gboolean
|
||||||
gst_vaapi_video_format_is_yuv (GstVideoFormat format)
|
gst_vaapi_video_format_is_yuv (GstVideoFormat format)
|
||||||
{
|
{
|
||||||
const GstVideoFormatMap *const m = get_map (format);
|
const GstVideoFormatMap *const m =
|
||||||
|
get_map_by_gst_format (gst_vaapi_video_formats_map, format);
|
||||||
return m && va_format_is_yuv (&m->va_format);
|
return m && va_format_is_yuv (&m->va_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,12 +337,15 @@ gst_vaapi_video_format_is_yuv (GstVideoFormat format)
|
||||||
GstVideoFormat
|
GstVideoFormat
|
||||||
gst_vaapi_video_format_from_va_fourcc (guint32 fourcc)
|
gst_vaapi_video_format_from_va_fourcc (guint32 fourcc)
|
||||||
{
|
{
|
||||||
|
const GArray *map = gst_vaapi_video_formats_map;
|
||||||
const GstVideoFormatMap *m;
|
const GstVideoFormatMap *m;
|
||||||
|
guint i;
|
||||||
|
|
||||||
/* Note: VA fourcc values are now standardized and shall represent
|
/* Note: VA fourcc values are now standardized and shall represent
|
||||||
a unique format. The associated VAImageFormat is just a hint to
|
a unique format. The associated VAImageFormat is just a hint to
|
||||||
determine RGBA component ordering */
|
determine RGBA component ordering */
|
||||||
for (m = gst_vaapi_video_formats; m->format; m++) {
|
for (i = 0; i < map->len; i++) {
|
||||||
|
m = &g_array_index (map, GstVideoFormatMap, i);
|
||||||
if (m->va_format.fourcc == fourcc)
|
if (m->va_format.fourcc == fourcc)
|
||||||
return m->format;
|
return m->format;
|
||||||
}
|
}
|
||||||
|
@ -224,13 +365,8 @@ gst_vaapi_video_format_from_va_fourcc (guint32 fourcc)
|
||||||
GstVideoFormat
|
GstVideoFormat
|
||||||
gst_vaapi_video_format_from_va_format (const VAImageFormat * va_format)
|
gst_vaapi_video_format_from_va_format (const VAImageFormat * va_format)
|
||||||
{
|
{
|
||||||
const GstVideoFormatMap *m;
|
const GstVideoFormatMap *const m = get_map_by_va_format (va_format);
|
||||||
|
return m ? m->format : GST_VIDEO_FORMAT_UNKNOWN;
|
||||||
for (m = gst_vaapi_video_formats; m->format; m++) {
|
|
||||||
if (va_format_is_same (&m->va_format, va_format))
|
|
||||||
return m->format;
|
|
||||||
}
|
|
||||||
return GST_VIDEO_FORMAT_UNKNOWN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -246,8 +382,8 @@ gst_vaapi_video_format_from_va_format (const VAImageFormat * va_format)
|
||||||
const VAImageFormat *
|
const VAImageFormat *
|
||||||
gst_vaapi_video_format_to_va_format (GstVideoFormat format)
|
gst_vaapi_video_format_to_va_format (GstVideoFormat format)
|
||||||
{
|
{
|
||||||
const GstVideoFormatMap *const m = get_map (format);
|
const GstVideoFormatMap *const m =
|
||||||
|
get_map_by_gst_format (gst_vaapi_video_formats_map, format);
|
||||||
return m ? &m->va_format : NULL;
|
return m ? &m->va_format : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,8 +400,8 @@ gst_vaapi_video_format_to_va_format (GstVideoFormat format)
|
||||||
guint
|
guint
|
||||||
gst_vaapi_video_format_get_chroma_type (GstVideoFormat format)
|
gst_vaapi_video_format_get_chroma_type (GstVideoFormat format)
|
||||||
{
|
{
|
||||||
const GstVideoFormatMap *const m = get_map (format);
|
const GstVideoFormatMap *const m =
|
||||||
|
get_map_by_gst_format (gst_vaapi_video_formats_map, format);
|
||||||
return m ? m->chroma_type : 0;
|
return m ? m->chroma_type : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,9 +417,7 @@ gst_vaapi_video_format_get_chroma_type (GstVideoFormat format)
|
||||||
guint
|
guint
|
||||||
gst_vaapi_video_format_get_score (GstVideoFormat format)
|
gst_vaapi_video_format_get_score (GstVideoFormat format)
|
||||||
{
|
{
|
||||||
const GstVideoFormatMap *const m = get_map (format);
|
return get_fmt_score_in_default (format);
|
||||||
|
|
||||||
return m ? (m - &gst_vaapi_video_formats[0]) : G_MAXUINT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -336,7 +470,98 @@ gst_vaapi_video_format_get_best_native (GstVideoFormat format)
|
||||||
|
|
||||||
if (format == GST_VIDEO_FORMAT_ENCODED)
|
if (format == GST_VIDEO_FORMAT_ENCODED)
|
||||||
return GST_VIDEO_FORMAT_NV12;
|
return GST_VIDEO_FORMAT_NV12;
|
||||||
|
|
||||||
chroma_type = gst_vaapi_video_format_get_chroma_type (format);
|
chroma_type = gst_vaapi_video_format_get_chroma_type (format);
|
||||||
return gst_vaapi_video_format_from_chroma (chroma_type);
|
return gst_vaapi_video_format_from_chroma (chroma_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ImageFormatsData
|
||||||
|
{
|
||||||
|
VAImageFormat *formats;
|
||||||
|
guint n;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
video_format_create_map_once (gpointer data)
|
||||||
|
{
|
||||||
|
const GstVideoFormatMap *src_entry, *entry;
|
||||||
|
guint i;
|
||||||
|
VAImageFormat *formats = ((struct ImageFormatsData *) data)->formats;
|
||||||
|
guint n = ((struct ImageFormatsData *) data)->n;
|
||||||
|
GArray *array = NULL;
|
||||||
|
|
||||||
|
if (formats == NULL || n == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
array = g_array_new (FALSE, TRUE, sizeof (GstVideoFormatMap));
|
||||||
|
if (array == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
src_entry = get_map_in_default_by_va_format (&formats[i]);
|
||||||
|
if (src_entry) {
|
||||||
|
entry = get_map_by_gst_format (array, src_entry->format);
|
||||||
|
if (entry && !va_format_is_same (&entry->va_format, &formats[i])) {
|
||||||
|
GST_INFO ("va_format1 with fourcc %" GST_FOURCC_FORMAT
|
||||||
|
" byte order: %d, BPP: %d, depth %d, red mask 0x%4x,"
|
||||||
|
" green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x"
|
||||||
|
" conflict with va_foramt2 fourcc %" GST_FOURCC_FORMAT
|
||||||
|
" byte order: %d, BPP: %d, depth %d, red mask 0x%4x,"
|
||||||
|
" green mask 0x%4x, blue mask 0x%4x, alpha mask 0x%4x."
|
||||||
|
" Both map to the same GST format: %s, which is not"
|
||||||
|
" allowed, va_format1 will be skipped",
|
||||||
|
GST_FOURCC_ARGS (entry->va_format.fourcc),
|
||||||
|
entry->va_format.byte_order, entry->va_format.bits_per_pixel,
|
||||||
|
entry->va_format.depth, entry->va_format.red_mask,
|
||||||
|
entry->va_format.green_mask, entry->va_format.blue_mask,
|
||||||
|
entry->va_format.alpha_mask,
|
||||||
|
GST_FOURCC_ARGS (formats[i].fourcc),
|
||||||
|
formats[i].byte_order, formats[i].bits_per_pixel, formats[i].depth,
|
||||||
|
formats[i].red_mask, formats[i].green_mask, formats[i].blue_mask,
|
||||||
|
formats[i].alpha_mask, gst_video_format_to_string (entry->format));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
g_array_append_val (array, (*src_entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (va_format_is_rgb (&formats[i])) {
|
||||||
|
GST_LOG ("%s to map RGB va_format with fourcc: %"
|
||||||
|
GST_FOURCC_FORMAT
|
||||||
|
", byte order: %d BPP: %d, depth %d, red mask %4x,"
|
||||||
|
" green mask %4x, blue mask %4x, alpha mask %4x to %s gstreamer"
|
||||||
|
" video format", src_entry ? "succeed" : "failed",
|
||||||
|
GST_FOURCC_ARGS (formats[i].fourcc), formats[i].byte_order,
|
||||||
|
formats[i].bits_per_pixel, formats[i].depth, formats[i].red_mask,
|
||||||
|
formats[i].green_mask, formats[i].blue_mask, formats[i].alpha_mask,
|
||||||
|
src_entry ? gst_video_format_to_string (src_entry->format) : "any");
|
||||||
|
} else {
|
||||||
|
GST_LOG ("%s to map YUV va format with fourcc: %"
|
||||||
|
GST_FOURCC_FORMAT ", byte order: %d BPP: %d to %s gstreamer"
|
||||||
|
" video format", src_entry ? "succeed" : "failed",
|
||||||
|
GST_FOURCC_ARGS (formats[i].fourcc), formats[i].byte_order,
|
||||||
|
formats[i].bits_per_pixel,
|
||||||
|
src_entry ? gst_video_format_to_string (src_entry->format) : "any");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_array_sort (array, video_format_compare_by_score);
|
||||||
|
gst_vaapi_video_formats_map = array;
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_vaapi_video_format_new_map:
|
||||||
|
* @formats: all #VAImageFormat need to map
|
||||||
|
* @n: the number of VAImageFormat
|
||||||
|
*
|
||||||
|
* Return: True if create successfully.
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_video_format_create_map (VAImageFormat * formats, guint n)
|
||||||
|
{
|
||||||
|
static GOnce once = G_ONCE_INIT;
|
||||||
|
struct ImageFormatsData data = { formats, n };
|
||||||
|
|
||||||
|
g_once (&once, video_format_create_map_once, &data);
|
||||||
|
|
||||||
|
return once.retval != NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -59,6 +59,9 @@ gst_vaapi_video_format_from_chroma (guint chroma);
|
||||||
GstVideoFormat
|
GstVideoFormat
|
||||||
gst_vaapi_video_format_get_best_native (GstVideoFormat format);
|
gst_vaapi_video_format_get_best_native (GstVideoFormat format);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_vaapi_video_format_create_map (VAImageFormat * formats, guint n);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* GST_VAAPI_VIDEO_FORMAT_H */
|
#endif /* GST_VAAPI_VIDEO_FORMAT_H */
|
||||||
|
|
Loading…
Reference in a new issue