mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 19:20:35 +00:00
Add new video format API.
Leverage GstVideoFormat utilities from core GStreamer to provide an adaptation layer to VA image formats.
This commit is contained in:
parent
42e46cd9d1
commit
430598cf00
5 changed files with 391 additions and 1 deletions
|
@ -8,6 +8,7 @@
|
|||
|
||||
<chapter>
|
||||
<title>gst-plugins-vaapi Library</title>
|
||||
<xi:include href="xml/videoformat.xml"/>
|
||||
<xi:include href="xml/gstvaapitypes.xml"/>
|
||||
<xi:include href="xml/gstvaapidisplay.xml"/>
|
||||
<xi:include href="xml/gstvaapidisplay_x11.xml"/>
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
<SECTION>
|
||||
<FILE>videoformat</FILE>
|
||||
<TITLE>GstVideoFormat</TITLE>
|
||||
gst_video_format_from_caps
|
||||
gst_video_format_from_structure
|
||||
gst_video_format_from_va_format
|
||||
gst_video_format_get_score
|
||||
gst_video_format_is_rgb
|
||||
gst_video_format_is_yuv
|
||||
gst_video_format_to_caps
|
||||
gst_video_format_to_va_format
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gstvaapisurfacepool</FILE>
|
||||
<TITLE>GstVaapiSurfacePool</TITLE>
|
||||
|
|
|
@ -70,6 +70,7 @@ libgstvaapi_source_c = \
|
|||
gstvaapivalue.c \
|
||||
gstvaapivideopool.c \
|
||||
gstvaapiwindow.c \
|
||||
video-format.c \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_source_h = \
|
||||
|
@ -94,6 +95,7 @@ libgstvaapi_source_h = \
|
|||
gstvaapivalue.h \
|
||||
gstvaapivideopool.h \
|
||||
gstvaapiwindow.h \
|
||||
video-format.h \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_source_priv_h = \
|
||||
|
@ -227,7 +229,7 @@ libgstvaapi_@GST_API_VERSION@_la_LIBADD = \
|
|||
libgstvaapi_@GST_API_VERSION@_la_LDFLAGS = \
|
||||
$(GST_ALL_LDFLAGS) \
|
||||
$(GST_VAAPI_LT_LDFLAGS) \
|
||||
-export-symbols-regex "^gst_.*vaapi.*" \
|
||||
-export-symbols-regex "^gst_(.*vaapi|video_format).*" \
|
||||
$(NULL)
|
||||
|
||||
libgstvaapi_drm_@GST_API_VERSION@_la_SOURCES = \
|
||||
|
|
317
gst-libs/gst/vaapi/video-format.c
Normal file
317
gst-libs/gst/vaapi/video-format.c
Normal file
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* video-format.c - Video format abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:videoformat
|
||||
* @short_description: Video format abstraction
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <gst/video/video.h>
|
||||
#include "gstvaapicompat.h"
|
||||
#include "video-format.h"
|
||||
|
||||
typedef struct _GstVideoFormatMap GstVideoFormatMap;
|
||||
struct _GstVideoFormatMap {
|
||||
GstVideoFormat format;
|
||||
const char *caps_str;
|
||||
VAImageFormat va_format;
|
||||
};
|
||||
|
||||
#if GST_CHECK_VERSION(1,0,0)
|
||||
# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \
|
||||
GST_VIDEO_CAPS_MAKE(#FORMAT)
|
||||
# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \
|
||||
GST_VIDEO_CAPS_MAKE(#FORMAT)
|
||||
#else
|
||||
# define GST_VIDEO_CAPS_MAKE_YUV(FORMAT) \
|
||||
GST_VIDEO_CAPS_YUV(#FORMAT)
|
||||
# define GST_VIDEO_CAPS_MAKE_RGB(FORMAT) \
|
||||
GST_VIDEO_CAPS_##FORMAT
|
||||
#endif
|
||||
|
||||
#define DEF_YUV(FORMAT, FOURCC, ENDIAN, BPP) \
|
||||
{ G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \
|
||||
GST_VIDEO_CAPS_MAKE_YUV(FORMAT), \
|
||||
{ VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, }, }
|
||||
#define DEF_RGB(FORMAT, FOURCC, ENDIAN, BPP, DEPTH, R,G,B,A) \
|
||||
{ G_PASTE(GST_VIDEO_FORMAT_,FORMAT), \
|
||||
GST_VIDEO_CAPS_MAKE_RGB(FORMAT), \
|
||||
{ VA_FOURCC FOURCC, VA_##ENDIAN##_FIRST, BPP, DEPTH, R,G,B,A }, }
|
||||
|
||||
/* Image formats, listed in HW order preference */
|
||||
static const GstVideoFormatMap gst_video_formats[] = {
|
||||
DEF_YUV(NV12, ('N','V','1','2'), LSB, 12),
|
||||
DEF_YUV(YV12, ('Y','V','1','2'), LSB, 12),
|
||||
DEF_YUV(I420, ('I','4','2','0'), LSB, 12),
|
||||
DEF_YUV(AYUV, ('A','Y','U','V'), LSB, 32),
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
DEF_RGB(ARGB, ('A','R','G','B'), MSB, 32,
|
||||
32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
|
||||
DEF_RGB(ABGR, ('A','B','G','R'), MSB, 32,
|
||||
32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
|
||||
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
DEF_RGB(BGRA, ('B','G','R','A'), LSB, 32,
|
||||
32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000),
|
||||
DEF_RGB(RGBA, ('R','G','B','A'), LSB, 32,
|
||||
32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000),
|
||||
#endif
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
#undef DEF_RGB
|
||||
#undef DEF_YUV
|
||||
|
||||
static inline gboolean
|
||||
va_format_is_rgb(const VAImageFormat *va_format)
|
||||
{
|
||||
return va_format->depth != 0;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
va_format_is_yuv(const VAImageFormat *va_format)
|
||||
{
|
||||
return va_format->depth == 0;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
va_format_is_same_rgb(const VAImageFormat *fmt1, const VAImageFormat *fmt2)
|
||||
{
|
||||
return (fmt1->byte_order == fmt2->byte_order &&
|
||||
fmt1->red_mask == fmt2->red_mask &&
|
||||
fmt1->green_mask == fmt2->green_mask &&
|
||||
fmt1->blue_mask == fmt2->blue_mask &&
|
||||
fmt1->alpha_mask == fmt2->alpha_mask);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
va_format_is_same(const VAImageFormat *fmt1, const VAImageFormat *fmt2)
|
||||
{
|
||||
if (fmt1->fourcc != fmt2->fourcc)
|
||||
return FALSE;
|
||||
return va_format_is_rgb(fmt1) ? va_format_is_same_rgb(fmt1, fmt2) : TRUE;
|
||||
}
|
||||
|
||||
static const GstVideoFormatMap *
|
||||
get_map(GstVideoFormat format)
|
||||
{
|
||||
const GstVideoFormatMap *m;
|
||||
|
||||
for (m = gst_video_formats; m->format; m++) {
|
||||
if (m->format == format)
|
||||
return m;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_format_is_rgb:
|
||||
* @format: a #GstVideoFormat
|
||||
*
|
||||
* Checks whether the format is an RGB format.
|
||||
*
|
||||
* Return value: %TRUE if @format is RGB format
|
||||
*/
|
||||
#if GST_CHECK_VERSION(1,0,0)
|
||||
gboolean
|
||||
gst_video_format_is_rgb(GstVideoFormat format)
|
||||
{
|
||||
const GstVideoFormatMap * const m = get_map(format);
|
||||
|
||||
return m && va_format_is_rgb(&m->va_format);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* gst_video_format_is_yuv:
|
||||
* @format: a #GstVideoFormat
|
||||
*
|
||||
* Checks whether the format is an YUV format.
|
||||
*
|
||||
* Return value: %TRUE if @format is YUV format
|
||||
*/
|
||||
#if GST_CHECK_VERSION(1,0,0)
|
||||
gboolean
|
||||
gst_video_format_is_yuv(GstVideoFormat format)
|
||||
{
|
||||
const GstVideoFormatMap * const m = get_map(format);
|
||||
|
||||
return m && va_format_is_yuv(&m->va_format);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* gst_video_format_from_caps:
|
||||
* @caps: a #GstCaps
|
||||
*
|
||||
* Converts @caps into the corresponding #GstVideoFormat. If the
|
||||
* image format cannot be represented by #GstVideoFormat, then
|
||||
* zero is returned.
|
||||
*
|
||||
* Return value: the #GstVideoFormat describing the @caps
|
||||
*/
|
||||
GstVideoFormat
|
||||
gst_video_format_from_caps(GstCaps *caps)
|
||||
{
|
||||
GstStructure *structure;
|
||||
|
||||
if (!caps)
|
||||
return 0;
|
||||
|
||||
structure = gst_caps_get_structure(caps, 0);
|
||||
if (!structure)
|
||||
return 0;
|
||||
return gst_video_format_from_structure(structure);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_format_from_structure:
|
||||
* @structure: a #GstStructure
|
||||
*
|
||||
* Converts @structure into the corresponding #GstVideoFormat. If
|
||||
* the image format cannot be represented by #GstVideoFormat,
|
||||
* then zero is returned.
|
||||
*
|
||||
* Return value: the #GstVideoFormat describing the @structure
|
||||
*/
|
||||
GstVideoFormat
|
||||
gst_video_format_from_structure(GstStructure *structure)
|
||||
{
|
||||
#if GST_CHECK_VERSION(1,0,0)
|
||||
const gchar * format = gst_structure_get_string(structure, "format");
|
||||
if (format)
|
||||
return gst_video_format_from_string(format);
|
||||
return GST_VIDEO_FORMAT_UNKNOWN;
|
||||
#else
|
||||
const GstVideoFormatMap *m;
|
||||
VAImageFormat *va_format, va_formats[2];
|
||||
gint endian, rmask, gmask, bmask, amask = 0;
|
||||
guint32 fourcc;
|
||||
|
||||
/* Check for YUV format */
|
||||
if (gst_structure_get_fourcc(structure, "format", &fourcc))
|
||||
return gst_video_format_from_fourcc(fourcc);
|
||||
|
||||
/* Check for RGB format */
|
||||
gst_structure_get_int(structure, "endianness", &endian);
|
||||
gst_structure_get_int(structure, "red_mask", &rmask);
|
||||
gst_structure_get_int(structure, "green_mask", &gmask);
|
||||
gst_structure_get_int(structure, "blue_mask", &bmask);
|
||||
gst_structure_get_int(structure, "alpha_mask", &amask);
|
||||
|
||||
va_format = &va_formats[0];
|
||||
va_format->byte_order = endian == G_BIG_ENDIAN ? VA_MSB_FIRST : VA_LSB_FIRST;
|
||||
va_format->red_mask = rmask;
|
||||
va_format->green_mask = gmask;
|
||||
va_format->blue_mask = bmask;
|
||||
va_format->alpha_mask = amask;
|
||||
|
||||
va_format = &va_formats[1];
|
||||
va_format->byte_order = endian == G_BIG_ENDIAN ? VA_LSB_FIRST : VA_MSB_FIRST;
|
||||
va_format->red_mask = GUINT32_SWAP_LE_BE(rmask);
|
||||
va_format->green_mask = GUINT32_SWAP_LE_BE(gmask);
|
||||
va_format->blue_mask = GUINT32_SWAP_LE_BE(bmask);
|
||||
va_format->alpha_mask = GUINT32_SWAP_LE_BE(amask);
|
||||
|
||||
for (m = gst_video_formats; m->format; m++) {
|
||||
if (va_format_is_rgb(&m->va_format) &&
|
||||
(va_format_is_same_rgb(&m->va_format, &va_formats[0]) ||
|
||||
va_format_is_same_rgb(&m->va_format, &va_formats[1])))
|
||||
return m->format;
|
||||
}
|
||||
return GST_VIDEO_FORMAT_UNKNOWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_format_to_caps:
|
||||
* @format: a #GstVideoFormat
|
||||
*
|
||||
* Converts a #GstVideoFormat into the corresponding #GstCaps. If
|
||||
* no matching caps were found, %NULL is returned.
|
||||
*
|
||||
* Return value: the newly allocated #GstCaps, or %NULL if none was found
|
||||
*/
|
||||
GstCaps *
|
||||
gst_video_format_to_caps(GstVideoFormat format)
|
||||
{
|
||||
const GstVideoFormatMap * const m = get_map(format);
|
||||
|
||||
return m ? gst_caps_from_string(m->caps_str) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_format_from_va_format:
|
||||
* @va_format: a #VAImageFormat
|
||||
*
|
||||
* Converts a VA image format into the corresponding #GstVideoFormat.
|
||||
* If the image format cannot be represented by #GstVideoFormat,
|
||||
* then zero is returned.
|
||||
*
|
||||
* Return value: the #GstVideoFormat describing the @va_format
|
||||
*/
|
||||
GstVideoFormat
|
||||
gst_video_format_from_va_format(const VAImageFormat *va_format)
|
||||
{
|
||||
const GstVideoFormatMap *m;
|
||||
|
||||
for (m = gst_video_formats; m->format; m++) {
|
||||
if (va_format_is_same(&m->va_format, va_format))
|
||||
return m->format;
|
||||
}
|
||||
return GST_VIDEO_FORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_format_to_va_format:
|
||||
* @format: a #GstVideoFormat
|
||||
*
|
||||
* Converts a #GstVideoFormat into the corresponding VA image
|
||||
* format. If no matching VA image format was found, %NULL is returned
|
||||
* and this error must be reported to be fixed.
|
||||
*
|
||||
* Return value: the VA image format, or %NULL if none was found
|
||||
*/
|
||||
const VAImageFormat *
|
||||
gst_video_format_to_va_format(GstVideoFormat format)
|
||||
{
|
||||
const GstVideoFormatMap * const m = get_map(format);
|
||||
|
||||
return m ? &m->va_format : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_video_format_get_score:
|
||||
* @format: a #GstVideoFormat
|
||||
*
|
||||
* Determines how "native" is this @format. The lower is the returned
|
||||
* score, the best format this is for the underlying hardware.
|
||||
*
|
||||
* Return value: the @format score, or %G_MAXUINT if none was found
|
||||
*/
|
||||
guint
|
||||
gst_video_format_get_score(GstVideoFormat format)
|
||||
{
|
||||
const GstVideoFormatMap * const m = get_map(format);
|
||||
|
||||
return m ? (m - &gst_video_formats[0]) : G_MAXUINT;
|
||||
}
|
57
gst-libs/gst/vaapi/video-format.h
Normal file
57
gst-libs/gst/vaapi/video-format.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* video-format.h - Video format abstraction
|
||||
*
|
||||
* Copyright (C) 2010-2011 Splitted-Desktop Systems
|
||||
* Copyright (C) 2011-2013 Intel Corporation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef GST_VAAPI_VIDEO_FORMAT_H
|
||||
#define GST_VAAPI_VIDEO_FORMAT_H
|
||||
|
||||
#include <gst/gstvalue.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean
|
||||
gst_video_format_is_rgb(GstVideoFormat format);
|
||||
|
||||
gboolean
|
||||
gst_video_format_is_yuv(GstVideoFormat format);
|
||||
|
||||
GstVideoFormat
|
||||
gst_video_format_from_structure(GstStructure *structure);
|
||||
|
||||
GstVideoFormat
|
||||
gst_video_format_from_caps(GstCaps *caps);
|
||||
|
||||
GstCaps *
|
||||
gst_video_format_to_caps(GstVideoFormat format);
|
||||
|
||||
GstVideoFormat
|
||||
gst_video_format_from_va_format(const VAImageFormat *va_format);
|
||||
|
||||
const VAImageFormat *
|
||||
gst_video_format_to_va_format(GstVideoFormat format);
|
||||
|
||||
guint
|
||||
gst_video_format_get_score(GstVideoFormat format);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_VIDEO_FORMAT_H */
|
Loading…
Reference in a new issue