tests: inforce gstreamer code-style

This commit is contained in:
Víctor Manuel Jáquez Leal 2016-04-29 12:48:44 +02:00
parent 018ea8b2fc
commit 74ebee5339
18 changed files with 8345 additions and 8445 deletions

View file

@ -24,170 +24,172 @@
#include <gst/vaapi/gstvaapidisplay.h> #include <gst/vaapi/gstvaapidisplay.h>
#include "codec.h" #include "codec.h"
typedef struct { typedef struct
const gchar *codec_str; {
GstVaapiCodec codec; const gchar *codec_str;
const gchar *caps_str; GstVaapiCodec codec;
const gchar *caps_str;
} CodecMap; } CodecMap;
static const CodecMap g_codec_map[] = { static const CodecMap g_codec_map[] = {
{ "h264", GST_VAAPI_CODEC_H264, {"h264", GST_VAAPI_CODEC_H264,
"video/x-h264" }, "video/x-h264"},
{ "jpeg", GST_VAAPI_CODEC_JPEG, {"jpeg", GST_VAAPI_CODEC_JPEG,
"image/jpeg" }, "image/jpeg"},
{ "mpeg2", GST_VAAPI_CODEC_MPEG2, {"mpeg2", GST_VAAPI_CODEC_MPEG2,
"video/mpeg, mpegversion=2" }, "video/mpeg, mpegversion=2"},
{ "mpeg4", GST_VAAPI_CODEC_MPEG4, {"mpeg4", GST_VAAPI_CODEC_MPEG4,
"video/mpeg, mpegversion=4" }, "video/mpeg, mpegversion=4"},
{ "wmv3", GST_VAAPI_CODEC_VC1, {"wmv3", GST_VAAPI_CODEC_VC1,
"video/x-wmv, wmvversion=3" }, "video/x-wmv, wmvversion=3"},
{ "vc1", GST_VAAPI_CODEC_VC1, {"vc1", GST_VAAPI_CODEC_VC1,
"video/x-wmv, wmvversion=3, format=(string)WVC1" }, "video/x-wmv, wmvversion=3, format=(string)WVC1"},
{ NULL, } {NULL,}
}; };
static const CodecMap * static const CodecMap *
get_codec_map(GstVaapiCodec codec) get_codec_map (GstVaapiCodec codec)
{ {
const CodecMap *m; const CodecMap *m;
if (codec) { if (codec) {
for (m = g_codec_map; m->codec_str != NULL; m++) { for (m = g_codec_map; m->codec_str != NULL; m++) {
if (m->codec == codec) if (m->codec == codec)
return m; return m;
}
} }
return NULL; }
return NULL;
} }
const gchar * const gchar *
string_from_codec(GstVaapiCodec codec) string_from_codec (GstVaapiCodec codec)
{ {
const CodecMap * const m = get_codec_map(codec); const CodecMap *const m = get_codec_map (codec);
return m ? m->codec_str : NULL; return m ? m->codec_str : NULL;
} }
GstCaps * GstCaps *
caps_from_codec(GstVaapiCodec codec) caps_from_codec (GstVaapiCodec codec)
{ {
const CodecMap * const m = get_codec_map(codec); const CodecMap *const m = get_codec_map (codec);
return m ? gst_caps_from_string(m->caps_str) : NULL; return m ? gst_caps_from_string (m->caps_str) : NULL;
} }
GstVaapiCodec GstVaapiCodec
identify_codec_from_string(const gchar *codec_str) identify_codec_from_string (const gchar * codec_str)
{ {
const CodecMap *m; const CodecMap *m;
if (codec_str) { if (codec_str) {
for (m = g_codec_map; m->codec_str != NULL; m++) { for (m = g_codec_map; m->codec_str != NULL; m++) {
if (g_ascii_strcasecmp(m->codec_str, codec_str) == 0) if (g_ascii_strcasecmp (m->codec_str, codec_str) == 0)
return m->codec; return m->codec;
}
} }
return 0; }
return 0;
} }
typedef struct { typedef struct
GMappedFile *file; {
guint8 *data; GMappedFile *file;
guint size; guint8 *data;
guint probability; guint size;
GstCaps *caps; guint probability;
GstTypeFind type_find; GstCaps *caps;
GstTypeFind type_find;
} CodecIdentifier; } CodecIdentifier;
static const guint8 * static const guint8 *
codec_identifier_peek(gpointer data, gint64 offset, guint size) codec_identifier_peek (gpointer data, gint64 offset, guint size)
{ {
CodecIdentifier * const cip = data; CodecIdentifier *const cip = data;
if (offset >= 0 && offset + size <= cip->size) if (offset >= 0 && offset + size <= cip->size)
return cip->data + offset; return cip->data + offset;
if (offset < 0 && ((gint)cip->size + offset) >= 0) if (offset < 0 && ((gint) cip->size + offset) >= 0)
return &cip->data[cip->size + offset]; return &cip->data[cip->size + offset];
return NULL; return NULL;
} }
static void static void
codec_identifier_suggest(gpointer data, guint probability, GstCaps *caps) codec_identifier_suggest (gpointer data, guint probability, GstCaps * caps)
{ {
CodecIdentifier * const cip = data; CodecIdentifier *const cip = data;
if (cip->probability < probability) { if (cip->probability < probability) {
cip->probability = probability; cip->probability = probability;
gst_caps_replace(&cip->caps, caps); gst_caps_replace (&cip->caps, caps);
} }
} }
static void static void
codec_identifier_free(CodecIdentifier *cip) codec_identifier_free (CodecIdentifier * cip)
{ {
if (!cip) if (!cip)
return; return;
if (cip->file) { if (cip->file) {
g_mapped_file_unref(cip->file); g_mapped_file_unref (cip->file);
cip->file = NULL; cip->file = NULL;
} }
gst_caps_replace(&cip->caps, NULL); gst_caps_replace (&cip->caps, NULL);
g_slice_free(CodecIdentifier, cip); g_slice_free (CodecIdentifier, cip);
} }
static CodecIdentifier * static CodecIdentifier *
codec_identifier_new(const gchar *filename) codec_identifier_new (const gchar * filename)
{ {
CodecIdentifier *cip; CodecIdentifier *cip;
GstTypeFind *tfp; GstTypeFind *tfp;
cip = g_slice_new0(CodecIdentifier); cip = g_slice_new0 (CodecIdentifier);
if (!cip) if (!cip)
return NULL; return NULL;
cip->file = g_mapped_file_new(filename, FALSE, NULL); cip->file = g_mapped_file_new (filename, FALSE, NULL);
if (!cip->file) if (!cip->file)
goto error; goto error;
cip->size = g_mapped_file_get_length(cip->file); cip->size = g_mapped_file_get_length (cip->file);
cip->data = (guint8 *)g_mapped_file_get_contents(cip->file); cip->data = (guint8 *) g_mapped_file_get_contents (cip->file);
if (!cip->data) if (!cip->data)
goto error; goto error;
tfp = &cip->type_find; tfp = &cip->type_find;
tfp->peek = codec_identifier_peek; tfp->peek = codec_identifier_peek;
tfp->suggest = codec_identifier_suggest; tfp->suggest = codec_identifier_suggest;
tfp->data = cip; tfp->data = cip;
return cip; return cip;
error: error:
codec_identifier_free(cip); codec_identifier_free (cip);
return NULL; return NULL;
} }
GstVaapiCodec GstVaapiCodec
identify_codec(const gchar *filename) identify_codec (const gchar * filename)
{ {
CodecIdentifier *cip; CodecIdentifier *cip;
GList *type_list, *l; GList *type_list, *l;
guint32 codec = 0; guint32 codec = 0;
cip = codec_identifier_new(filename); cip = codec_identifier_new (filename);
if (!cip) if (!cip)
return 0; return 0;
type_list = gst_type_find_factory_get_list(); type_list = gst_type_find_factory_get_list ();
for (l = type_list; l != NULL; l = l->next) { for (l = type_list; l != NULL; l = l->next) {
GstTypeFindFactory * const factory = GST_TYPE_FIND_FACTORY(l->data); GstTypeFindFactory *const factory = GST_TYPE_FIND_FACTORY (l->data);
gst_type_find_factory_call_function(factory, &cip->type_find); gst_type_find_factory_call_function (factory, &cip->type_find);
} }
g_list_free(type_list); g_list_free (type_list);
if (cip->probability >= GST_TYPE_FIND_LIKELY) if (cip->probability >= GST_TYPE_FIND_LIKELY)
codec = gst_vaapi_profile_get_codec( codec =
gst_vaapi_profile_from_caps(cip->caps)); gst_vaapi_profile_get_codec (gst_vaapi_profile_from_caps (cip->caps));
codec_identifier_free(cip); codec_identifier_free (cip);
return codec; return codec;
} }

View file

@ -34,169 +34,169 @@
#include "test-h264.h" #include "test-h264.h"
#include "test-vc1.h" #include "test-vc1.h"
typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info); typedef void (*GetVideoInfoFunc) (VideoDecodeInfo * info);
typedef struct _CodecDefs CodecDefs; typedef struct _CodecDefs CodecDefs;
struct _CodecDefs { struct _CodecDefs
const gchar *codec_str; {
GetVideoInfoFunc get_video_info; const gchar *codec_str;
GetVideoInfoFunc get_video_info;
}; };
static const CodecDefs g_codec_defs[] = { static const CodecDefs g_codec_defs[] = {
#define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info } #define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info }
INIT_FUNCS(jpeg), INIT_FUNCS (jpeg),
INIT_FUNCS(mpeg2), INIT_FUNCS (mpeg2),
INIT_FUNCS(mpeg4), INIT_FUNCS (mpeg4),
INIT_FUNCS(h264), INIT_FUNCS (h264),
INIT_FUNCS(vc1), INIT_FUNCS (vc1),
#undef INIT_FUNCS #undef INIT_FUNCS
{ NULL, } {NULL,}
}; };
static const CodecDefs * static const CodecDefs *
find_codec_defs(const gchar *codec_str) find_codec_defs (const gchar * codec_str)
{ {
const CodecDefs *c; const CodecDefs *c;
for (c = g_codec_defs; c->codec_str; c++) for (c = g_codec_defs; c->codec_str; c++)
if (strcmp(codec_str, c->codec_str) == 0) if (strcmp (codec_str, c->codec_str) == 0)
return c; return c;
return NULL; return NULL;
} }
static inline const CodecDefs * static inline const CodecDefs *
get_codec_defs(GstVaapiDecoder *decoder) get_codec_defs (GstVaapiDecoder * decoder)
{ {
return gst_vaapi_decoder_get_user_data(decoder); return gst_vaapi_decoder_get_user_data (decoder);
} }
static inline void static inline void
set_codec_defs(GstVaapiDecoder *decoder, const CodecDefs *c) set_codec_defs (GstVaapiDecoder * decoder, const CodecDefs * c)
{ {
gst_vaapi_decoder_set_user_data(decoder, (gpointer)c); gst_vaapi_decoder_set_user_data (decoder, (gpointer) c);
} }
GstVaapiDecoder * GstVaapiDecoder *
decoder_new(GstVaapiDisplay *display, const gchar *codec_name) decoder_new (GstVaapiDisplay * display, const gchar * codec_name)
{ {
GstVaapiDecoder *decoder; GstVaapiDecoder *decoder;
const CodecDefs *codec; const CodecDefs *codec;
GstCaps *caps; GstCaps *caps;
VideoDecodeInfo info; VideoDecodeInfo info;
if (!codec_name) if (!codec_name)
codec_name = "h264"; codec_name = "h264";
codec = find_codec_defs(codec_name); codec = find_codec_defs (codec_name);
if (!codec) { if (!codec) {
GST_ERROR("failed to find %s codec data", codec_name); GST_ERROR ("failed to find %s codec data", codec_name);
return NULL; return NULL;
} }
codec->get_video_info(&info); codec->get_video_info (&info);
caps = gst_vaapi_profile_get_caps(info.profile); caps = gst_vaapi_profile_get_caps (info.profile);
if (!caps) { if (!caps) {
GST_ERROR("failed to create decoder caps"); GST_ERROR ("failed to create decoder caps");
return NULL; return NULL;
} }
if (info.width > 0 && info.height > 0) if (info.width > 0 && info.height > 0)
gst_caps_set_simple(caps, gst_caps_set_simple (caps,
"width", G_TYPE_INT, info.width, "width", G_TYPE_INT, info.width,
"height", G_TYPE_INT, info.height, "height", G_TYPE_INT, info.height, NULL);
NULL);
switch (gst_vaapi_profile_get_codec(info.profile)) { switch (gst_vaapi_profile_get_codec (info.profile)) {
case GST_VAAPI_CODEC_H264: case GST_VAAPI_CODEC_H264:
decoder = gst_vaapi_decoder_h264_new(display, caps); decoder = gst_vaapi_decoder_h264_new (display, caps);
break; break;
#if USE_JPEG_DECODER #if USE_JPEG_DECODER
case GST_VAAPI_CODEC_JPEG: case GST_VAAPI_CODEC_JPEG:
decoder = gst_vaapi_decoder_jpeg_new(display, caps); decoder = gst_vaapi_decoder_jpeg_new (display, caps);
break; break;
#endif #endif
case GST_VAAPI_CODEC_MPEG2: case GST_VAAPI_CODEC_MPEG2:
decoder = gst_vaapi_decoder_mpeg2_new(display, caps); decoder = gst_vaapi_decoder_mpeg2_new (display, caps);
break; break;
case GST_VAAPI_CODEC_MPEG4: case GST_VAAPI_CODEC_MPEG4:
decoder = gst_vaapi_decoder_mpeg4_new(display, caps); decoder = gst_vaapi_decoder_mpeg4_new (display, caps);
break; break;
case GST_VAAPI_CODEC_VC1: case GST_VAAPI_CODEC_VC1:
decoder = gst_vaapi_decoder_vc1_new(display, caps); decoder = gst_vaapi_decoder_vc1_new (display, caps);
break; break;
default: default:
decoder = NULL; decoder = NULL;
break; break;
} }
gst_caps_unref(caps); gst_caps_unref (caps);
if (!decoder) { if (!decoder) {
GST_ERROR("failed to create %s decoder", codec->codec_str); GST_ERROR ("failed to create %s decoder", codec->codec_str);
return NULL; return NULL;
} }
set_codec_defs(decoder, codec); set_codec_defs (decoder, codec);
return decoder; return decoder;
} }
gboolean gboolean
decoder_put_buffers(GstVaapiDecoder *decoder) decoder_put_buffers (GstVaapiDecoder * decoder)
{ {
const CodecDefs *codec; const CodecDefs *codec;
VideoDecodeInfo info; VideoDecodeInfo info;
GstBuffer *buffer; GstBuffer *buffer;
gboolean success; gboolean success;
g_return_val_if_fail(decoder != NULL, FALSE); g_return_val_if_fail (decoder != NULL, FALSE);
codec = get_codec_defs(decoder); codec = get_codec_defs (decoder);
g_return_val_if_fail(codec != NULL, FALSE); g_return_val_if_fail (codec != NULL, FALSE);
codec->get_video_info(&info); codec->get_video_info (&info);
buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
(guchar *)info.data, info.data_size, 0, info.data_size, NULL, NULL); (guchar *) info.data, info.data_size, 0, info.data_size, NULL, NULL);
if (!buffer) { if (!buffer) {
GST_ERROR("failed to create encoded data buffer"); GST_ERROR ("failed to create encoded data buffer");
return FALSE; return FALSE;
} }
success = gst_vaapi_decoder_put_buffer(decoder, buffer); success = gst_vaapi_decoder_put_buffer (decoder, buffer);
gst_buffer_unref(buffer); gst_buffer_unref (buffer);
if (!success) { if (!success) {
GST_ERROR("failed to send video data to the decoder"); GST_ERROR ("failed to send video data to the decoder");
return FALSE; return FALSE;
} }
if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) { if (!gst_vaapi_decoder_put_buffer (decoder, NULL)) {
GST_ERROR("failed to submit <end-of-stream> to the decoder"); GST_ERROR ("failed to submit <end-of-stream> to the decoder");
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
GstVaapiSurfaceProxy * GstVaapiSurfaceProxy *
decoder_get_surface(GstVaapiDecoder *decoder) decoder_get_surface (GstVaapiDecoder * decoder)
{ {
GstVaapiSurfaceProxy *proxy; GstVaapiSurfaceProxy *proxy;
GstVaapiDecoderStatus status; GstVaapiDecoderStatus status;
g_return_val_if_fail(decoder != NULL, NULL); g_return_val_if_fail (decoder != NULL, NULL);
status = gst_vaapi_decoder_get_surface(decoder, &proxy); status = gst_vaapi_decoder_get_surface (decoder, &proxy);
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) { if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
GST_ERROR("failed to get decoded surface (decoder status %d)", status); GST_ERROR ("failed to get decoded surface (decoder status %d)", status);
return NULL; return NULL;
} }
return proxy; return proxy;
} }
const gchar * const gchar *
decoder_get_codec_name(GstVaapiDecoder *decoder) decoder_get_codec_name (GstVaapiDecoder * decoder)
{ {
const CodecDefs *codec; const CodecDefs *codec;
g_return_val_if_fail(decoder != NULL, NULL); g_return_val_if_fail (decoder != NULL, NULL);
codec = get_codec_defs(decoder); codec = get_codec_defs (decoder);
g_return_val_if_fail(codec != NULL, FALSE); g_return_val_if_fail (codec != NULL, FALSE);
return codec->codec_str; return codec->codec_str;
} }

View file

@ -25,460 +25,376 @@
#include "image.h" #include "image.h"
static gboolean static gboolean
image_draw_rectangle( image_draw_rectangle (GstVaapiImage * image,
GstVaapiImage *image, gint x, gint y, guint width, guint height, guint32 color, guint32 flags);
gint x,
gint y,
guint width,
guint height,
guint32 color,
guint32 flags
);
static gboolean static gboolean
image_draw_color_rectangles( image_draw_color_rectangles (GstVaapiImage * image,
GstVaapiImage *image, guint width, guint height, const guint32 colors[4], guint32 flags)
guint width,
guint height,
const guint32 colors[4],
guint32 flags
)
{ {
const guint w = width / 2; const guint w = width / 2;
const guint h = height / 2; const guint h = height / 2;
if (!image_draw_rectangle(image, 0, 0, w, h, colors[0], flags)) if (!image_draw_rectangle (image, 0, 0, w, h, colors[0], flags))
return FALSE; return FALSE;
if (!image_draw_rectangle(image, w, 0, w, h, colors[1], flags)) if (!image_draw_rectangle (image, w, 0, w, h, colors[1], flags))
return FALSE; return FALSE;
if (!image_draw_rectangle(image, 0, h, w, h, colors[2], flags)) if (!image_draw_rectangle (image, 0, h, w, h, colors[2], flags))
return FALSE; return FALSE;
if (!image_draw_rectangle(image, w, h, w, h, colors[3], flags)) if (!image_draw_rectangle (image, w, h, w, h, colors[3], flags))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
GstVaapiImage * GstVaapiImage *
image_generate( image_generate (GstVaapiDisplay * display,
GstVaapiDisplay *display, GstVideoFormat format, guint width, guint height)
GstVideoFormat format,
guint width,
guint height
)
{ {
return image_generate_full(display, format, width, height, 0); return image_generate_full (display, format, width, height, 0);
} }
GstVaapiImage * GstVaapiImage *
image_generate_full( image_generate_full (GstVaapiDisplay * display,
GstVaapiDisplay *display, GstVideoFormat format, guint width, guint height, guint32 flags)
GstVideoFormat format,
guint width,
guint height,
guint32 flags
)
{ {
GstVaapiImage *image; GstVaapiImage *image;
static const guint32 rgb_colors[4] = static const guint32 rgb_colors[4] =
{ 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000 }; { 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff000000 };
static const guint32 bgr_colors[4] = static const guint32 bgr_colors[4] =
{ 0xff000000, 0xff0000ff, 0xff00ff00, 0xffff0000 }; { 0xff000000, 0xff0000ff, 0xff00ff00, 0xffff0000 };
static const guint32 inv_colors[4] = static const guint32 inv_colors[4] =
{ 0xffdeadc0, 0xffdeadc0, 0xffdeadc0, 0xffdeadc0 }; { 0xffdeadc0, 0xffdeadc0, 0xffdeadc0, 0xffdeadc0 };
image = gst_vaapi_image_new(display, format, width, height); image = gst_vaapi_image_new (display, format, width, height);
if (!image) if (!image)
return NULL; return NULL;
if (flags) { if (flags) {
if (!image_draw_color_rectangles(image, width, height, if (!image_draw_color_rectangles (image, width, height,
((flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) ? ((flags & GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD) ?
rgb_colors : inv_colors), rgb_colors : inv_colors),
GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)) GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD))
goto error; goto error;
if (!image_draw_color_rectangles(image, width, height, if (!image_draw_color_rectangles (image, width, height,
((flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) ? ((flags & GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) ?
bgr_colors : inv_colors), bgr_colors : inv_colors),
GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)) GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD))
goto error; goto error;
} } else if (!image_draw_color_rectangles (image, width, height, rgb_colors, 0))
else if (!image_draw_color_rectangles(image, width, height, rgb_colors, 0)) goto error;
goto error; return image;
return image;
error: error:
gst_vaapi_object_unref(image); gst_vaapi_object_unref (image);
return NULL; return NULL;
} }
typedef void (*DrawRectFunc)( typedef void (*DrawRectFunc) (guchar * pixels[3],
guchar *pixels[3], guint stride[3], gint x, gint y, guint width, guint height, guint32 color);
guint stride[3],
gint x,
gint y,
guint width,
guint height,
guint32 color
);
static void draw_rect_ARGB( static void
guchar *pixels[3], draw_rect_ARGB (guchar * pixels[3],
guint stride[3], guint stride[3], gint x, gint y, guint width, guint height, guint32 color)
gint x,
gint y,
guint width,
guint height,
guint32 color
)
{ {
guint i, j; guint i, j;
color = GUINT32_TO_BE(color); color = GUINT32_TO_BE (color);
for (j = 0; j < height; j++) { for (j = 0; j < height; j++) {
guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4); guint32 *p = (guint32 *) (pixels[0] + (y + j) * stride[0] + x * 4);
for (i = 0; i < width; i++) for (i = 0; i < width; i++)
p[i] = color; p[i] = color;
}
}
static void
draw_rect_BGRA (guchar * pixels[3],
guint stride[3], gint x, gint y, guint width, guint height, guint32 color)
{
// Converts ARGB color to BGRA
color = GUINT32_SWAP_LE_BE (color);
draw_rect_ARGB (pixels, stride, x, y, width, height, color);
}
static void
draw_rect_RGBA (guchar * pixels[3],
guint stride[3], gint x, gint y, guint width, guint height, guint32 color)
{
// Converts ARGB color to RGBA
color = ((color >> 24) & 0xff) | ((color & 0xffffff) << 8);
draw_rect_ARGB (pixels, stride, x, y, width, height, color);
}
static void
draw_rect_ABGR (guchar * pixels[3],
guint stride[3], gint x, gint y, guint width, guint height, guint32 color)
{
// Converts ARGB color to ABGR
color = ((color & 0xff00ff00) |
((color >> 16) & 0xff) | ((color & 0xff) << 16));
draw_rect_ARGB (pixels, stride, x, y, width, height, color);
}
static void
draw_rect_NV12 ( // Y, UV planes
guchar * pixels[3],
guint stride[3], gint x, gint y, guint width, guint height, guint32 color)
{
const guchar Y = color >> 16;
const guchar Cb = color >> 8;
const guchar Cr = color;
guchar *dst;
guint i, j;
dst = pixels[0] + y * stride[0] + x;
for (j = 0; j < height; j++, dst += stride[0])
for (i = 0; i < width; i++)
dst[i] = Y;
x /= 2;
y /= 2;
width /= 2;
height /= 2;
dst = pixels[1] + y * stride[1] + x * 2;
for (j = 0; j < height; j++, dst += stride[1])
for (i = 0; i < width; i++) {
dst[2 * i + 0] = Cb;
dst[2 * i + 1] = Cr;
} }
} }
static void draw_rect_BGRA( static void
guchar *pixels[3], draw_rect_YV12 ( // Y, V, U planes
guint stride[3], guchar * pixels[3],
gint x, guint stride[3], gint x, gint y, guint width, guint height, guint32 color)
gint y,
guint width,
guint height,
guint32 color
)
{ {
// Converts ARGB color to BGRA const guchar Y = color >> 16;
color = GUINT32_SWAP_LE_BE(color); const guchar Cb = color >> 8;
const guchar Cr = color;
guchar *pY, *pU, *pV;
guint i, j;
draw_rect_ARGB(pixels, stride, x, y, width, height, color); pY = pixels[0] + y * stride[0] + x;
} for (j = 0; j < height; j++, pY += stride[0])
for (i = 0; i < width; i++)
pY[i] = Y;
static void draw_rect_RGBA( x /= 2;
guchar *pixels[3], y /= 2;
guint stride[3], width /= 2;
gint x, height /= 2;
gint y,
guint width,
guint height,
guint32 color
)
{
// Converts ARGB color to RGBA
color = ((color >> 24) & 0xff) | ((color & 0xffffff) << 8);
draw_rect_ARGB(pixels, stride, x, y, width, height, color); pV = pixels[1] + y * stride[1] + x;
} pU = pixels[2] + y * stride[2] + x;
for (j = 0; j < height; j++, pU += stride[1], pV += stride[2])
static void draw_rect_ABGR( for (i = 0; i < width; i++) {
guchar *pixels[3], pU[i] = Cb;
guint stride[3], pV[i] = Cr;
gint x,
gint y,
guint width,
guint height,
guint32 color
)
{
// Converts ARGB color to ABGR
color = ((color & 0xff00ff00) |
((color >> 16) & 0xff) |
((color & 0xff) << 16));
draw_rect_ARGB(pixels, stride, x, y, width, height, color);
}
static void draw_rect_NV12( // Y, UV planes
guchar *pixels[3],
guint stride[3],
gint x,
gint y,
guint width,
guint height,
guint32 color
)
{
const guchar Y = color >> 16;
const guchar Cb = color >> 8;
const guchar Cr = color;
guchar *dst;
guint i, j;
dst = pixels[0] + y * stride[0] + x;
for (j = 0; j < height; j++, dst += stride[0])
for (i = 0; i < width; i++)
dst[i] = Y;
x /= 2;
y /= 2;
width /= 2;
height /= 2;
dst = pixels[1] + y * stride[1] + x * 2;
for (j = 0; j < height; j++, dst += stride[1])
for (i = 0; i < width; i++) {
dst[2*i + 0] = Cb;
dst[2*i + 1] = Cr;
}
}
static void draw_rect_YV12( // Y, V, U planes
guchar *pixels[3],
guint stride[3],
gint x,
gint y,
guint width,
guint height,
guint32 color
)
{
const guchar Y = color >> 16;
const guchar Cb = color >> 8;
const guchar Cr = color;
guchar *pY, *pU, *pV;
guint i, j;
pY = pixels[0] + y * stride[0] + x;
for (j = 0; j < height; j++, pY += stride[0])
for (i = 0; i < width; i++)
pY[i] = Y;
x /= 2;
y /= 2;
width /= 2;
height /= 2;
pV = pixels[1] + y * stride[1] + x;
pU = pixels[2] + y * stride[2] + x;
for (j = 0; j < height; j++, pU += stride[1], pV += stride[2])
for (i = 0; i < width; i++) {
pU[i] = Cb;
pV[i] = Cr;
}
}
static void draw_rect_I420( // Y, U, V planes
guchar *pixels[3],
guint stride[3],
gint x,
gint y,
guint width,
guint height,
guint32 color
)
{
guchar *new_pixels[3] = { pixels[0], pixels[2], pixels[1] };
guint new_stride[3] = { stride[0], stride[2], stride[1] };
draw_rect_YV12(new_pixels, new_stride, x, y, width, height, color);
}
static void draw_rect_YUV422(guchar *pixels[3], guint stride[3],
gint x, gint y, guint width, guint height, guint32 color)
{
guint i, j;
width /= 2;
for (j = 0; j < height; j++) {
guint32 * const p = (guint32 *)
(pixels[0] + (y + j) * stride[0] + x * 2);
for (i = 0; i < width; i++)
p[i] = color;
} }
} }
static void draw_rect_YUY2(guchar *pixels[3], guint stride[3], static void
draw_rect_I420 ( // Y, U, V planes
guchar * pixels[3],
guint stride[3], gint x, gint y, guint width, guint height, guint32 color)
{
guchar *new_pixels[3] = { pixels[0], pixels[2], pixels[1] };
guint new_stride[3] = { stride[0], stride[2], stride[1] };
draw_rect_YV12 (new_pixels, new_stride, x, y, width, height, color);
}
static void
draw_rect_YUV422 (guchar * pixels[3], guint stride[3],
gint x, gint y, guint width, guint height, guint32 color) gint x, gint y, guint width, guint height, guint32 color)
{ {
const guchar Y = color >> 16; guint i, j;
const guchar Cb = color >> 8;
const guchar Cr = color;
color = (Y << 24) | (Cb << 16) | (Y << 8) | Cr; width /= 2;
draw_rect_YUV422(pixels, stride, x, y, width, height, GUINT32_TO_BE(color)); for (j = 0; j < height; j++) {
guint32 *const p = (guint32 *)
(pixels[0] + (y + j) * stride[0] + x * 2);
for (i = 0; i < width; i++)
p[i] = color;
}
} }
static void draw_rect_UYVY(guchar *pixels[3], guint stride[3], static void
draw_rect_YUY2 (guchar * pixels[3], guint stride[3],
gint x, gint y, guint width, guint height, guint32 color) gint x, gint y, guint width, guint height, guint32 color)
{ {
const guchar Y = color >> 16; const guchar Y = color >> 16;
const guchar Cb = color >> 8; const guchar Cb = color >> 8;
const guchar Cr = color; const guchar Cr = color;
color = (Cb << 24) | (Y << 16) | (Cr << 8) | Y; color = (Y << 24) | (Cb << 16) | (Y << 8) | Cr;
draw_rect_YUV422(pixels, stride, x, y, width, height, GUINT32_TO_BE(color)); draw_rect_YUV422 (pixels, stride, x, y, width, height, GUINT32_TO_BE (color));
} }
static void draw_rect_AYUV( static void
guchar *pixels[3], draw_rect_UYVY (guchar * pixels[3], guint stride[3],
guint stride[3], gint x, gint y, guint width, guint height, guint32 color)
gint x,
gint y,
guint width,
guint height,
guint32 color
)
{ {
guint i, j; const guchar Y = color >> 16;
const guchar Cb = color >> 8;
const guchar Cr = color;
color = color | 0xff000000; color = (Cb << 24) | (Y << 16) | (Cr << 8) | Y;
draw_rect_YUV422 (pixels, stride, x, y, width, height, GUINT32_TO_BE (color));
for (j = 0; j < height; j++) {
guint32 *p = (guint32 *)(pixels[0] + (y + j) * stride[0] + x * 4);
for (i = 0; i < width; i++)
p[i] = color;
}
} }
static inline guint32 argb2yuv(guint32 color) static void
draw_rect_AYUV (guchar * pixels[3],
guint stride[3], gint x, gint y, guint width, guint height, guint32 color)
{ {
const gint32 r = (color >> 16) & 0xff; guint i, j;
const gint32 g = (color >> 8) & 0xff;
const gint32 b = (color ) & 0xff;
const guint32 y = (( 306 * r + 601 * g + 116 * b) >> 10); color = color | 0xff000000;
const guint32 u = ((-172 * r - 339 * g + 512 * b) >> 10) + 128;
const guint32 v = (( 512 * r - 428 * g - 83 * b) >> 10) + 128;
return (y << 16) | (u << 8) | v; for (j = 0; j < height; j++) {
guint32 *p = (guint32 *) (pixels[0] + (y + j) * stride[0] + x * 4);
for (i = 0; i < width; i++)
p[i] = color;
}
}
static inline guint32
argb2yuv (guint32 color)
{
const gint32 r = (color >> 16) & 0xff;
const gint32 g = (color >> 8) & 0xff;
const gint32 b = (color) & 0xff;
const guint32 y = ((306 * r + 601 * g + 116 * b) >> 10);
const guint32 u = ((-172 * r - 339 * g + 512 * b) >> 10) + 128;
const guint32 v = ((512 * r - 428 * g - 83 * b) >> 10) + 128;
return (y << 16) | (u << 8) | v;
} }
gboolean gboolean
image_draw_rectangle( image_draw_rectangle (GstVaapiImage * image,
GstVaapiImage *image, gint x, gint y, guint width, guint height, guint32 color, guint32 flags)
gint x,
gint y,
guint width,
guint height,
guint32 color,
guint32 flags
)
{ {
const GstVideoFormat image_format = gst_vaapi_image_get_format(image); const GstVideoFormat image_format = gst_vaapi_image_get_format (image);
const guint image_width = gst_vaapi_image_get_width(image); const guint image_width = gst_vaapi_image_get_width (image);
const guint image_height = gst_vaapi_image_get_height(image); const guint image_height = gst_vaapi_image_get_height (image);
GstVaapiDisplay *display; GstVaapiDisplay *display;
guchar *pixels[3]; guchar *pixels[3];
guint stride[3]; guint stride[3];
DrawRectFunc draw_rect = NULL; DrawRectFunc draw_rect = NULL;
guint i; guint i;
static const struct { static const struct
GstVideoFormat format; {
DrawRectFunc draw_rect; GstVideoFormat format;
} DrawRectFunc draw_rect;
map[] = { }
map[] = {
#define _(FORMAT) { GST_VIDEO_FORMAT_##FORMAT, draw_rect_##FORMAT } #define _(FORMAT) { GST_VIDEO_FORMAT_##FORMAT, draw_rect_##FORMAT }
_(ARGB), _(ARGB),
_(BGRA), _(BGRA),
_(RGBA), _(RGBA), _(ABGR), _(NV12), _(YV12), _(I420), _(YUY2), _(UYVY), _(AYUV),
_(ABGR),
_(NV12),
_(YV12),
_(I420),
_(YUY2),
_(UYVY),
_(AYUV),
#undef _ #undef _
{ 0, } {
}; 0,}
};
for (i = 0; !draw_rect && map[i].format; i++) for (i = 0; !draw_rect && map[i].format; i++)
if (map[i].format == image_format) if (map[i].format == image_format)
draw_rect = map[i].draw_rect; draw_rect = map[i].draw_rect;
if (!draw_rect) if (!draw_rect)
return FALSE; return FALSE;
if (x < 0) if (x < 0)
x = 0; x = 0;
if (y < 0) if (y < 0)
y = 0; y = 0;
if (width > image_width - x) if (width > image_width - x)
width = image_width - x; width = image_width - x;
if (height > image_height - y) if (height > image_height - y)
height = image_height - y; height = image_height - y;
display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(image)); display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (image));
if (!display) if (!display)
return FALSE; return FALSE;
if (!gst_vaapi_image_map(image)) if (!gst_vaapi_image_map (image))
return FALSE; return FALSE;
for (i = 0; i < gst_vaapi_image_get_plane_count(image); i++) { for (i = 0; i < gst_vaapi_image_get_plane_count (image); i++) {
pixels[i] = gst_vaapi_image_get_plane(image, i); pixels[i] = gst_vaapi_image_get_plane (image, i);
stride[i] = gst_vaapi_image_get_pitch(image, i); stride[i] = gst_vaapi_image_get_pitch (image, i);
switch (flags) { switch (flags) {
case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
pixels[i] += stride[i]; pixels[i] += stride[i];
// fall-through // fall-through
case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD: case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
stride[i] *= 2; stride[i] *= 2;
break; break;
}
} }
}
if (flags) if (flags)
y /= 2, height /= 2; y /= 2, height /= 2;
if (gst_vaapi_video_format_is_yuv(image_format)) if (gst_vaapi_video_format_is_yuv (image_format))
color = argb2yuv(color); color = argb2yuv (color);
draw_rect(pixels, stride, x, y, width, height, color); draw_rect (pixels, stride, x, y, width, height, color);
return gst_vaapi_image_unmap(image); return gst_vaapi_image_unmap (image);
} }
gboolean gboolean
image_upload(GstVaapiImage *image, GstVaapiSurface *surface) image_upload (GstVaapiImage * image, GstVaapiSurface * surface)
{ {
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVideoFormat format; GstVideoFormat format;
GstVaapiImage *surface_image; GstVaapiImage *surface_image;
GstVaapiSubpicture *subpicture; GstVaapiSubpicture *subpicture;
gboolean success; gboolean success;
display = gst_vaapi_object_get_display(GST_VAAPI_OBJECT(surface)); display = gst_vaapi_object_get_display (GST_VAAPI_OBJECT (surface));
if (!display) if (!display)
return FALSE; return FALSE;
format = gst_vaapi_image_get_format(image); format = gst_vaapi_image_get_format (image);
if (!format) if (!format)
return FALSE; return FALSE;
if (gst_vaapi_surface_put_image(surface, image)) if (gst_vaapi_surface_put_image (surface, image))
return TRUE;
surface_image = gst_vaapi_surface_derive_image(surface);
if (surface_image) {
success = gst_vaapi_image_copy(surface_image, image);
gst_vaapi_object_unref(surface_image);
if (success)
return TRUE;
}
g_print("could not upload %s image to surface\n",
gst_vaapi_video_format_to_string(format));
if (!gst_vaapi_display_has_subpicture_format(display, format, NULL))
return FALSE;
g_print("trying as a subpicture\n");
subpicture = gst_vaapi_subpicture_new(image, 0);
if (!subpicture)
g_error("could not create VA subpicture");
if (!gst_vaapi_surface_associate_subpicture(surface, subpicture,
NULL, NULL))
g_error("could not associate subpicture to surface");
/* The surface holds a reference to the subpicture. This is safe */
gst_vaapi_object_unref(subpicture);
return TRUE; return TRUE;
surface_image = gst_vaapi_surface_derive_image (surface);
if (surface_image) {
success = gst_vaapi_image_copy (surface_image, image);
gst_vaapi_object_unref (surface_image);
if (success)
return TRUE;
}
g_print ("could not upload %s image to surface\n",
gst_vaapi_video_format_to_string (format));
if (!gst_vaapi_display_has_subpicture_format (display, format, NULL))
return FALSE;
g_print ("trying as a subpicture\n");
subpicture = gst_vaapi_subpicture_new (image, 0);
if (!subpicture)
g_error ("could not create VA subpicture");
if (!gst_vaapi_surface_associate_subpicture (surface, subpicture, NULL, NULL))
g_error ("could not associate subpicture to surface");
/* The surface holds a reference to the subpicture. This is safe */
gst_vaapi_object_unref (subpicture);
return TRUE;
} }

View file

@ -48,34 +48,30 @@
static const VideoOutputInfo *g_video_output; static const VideoOutputInfo *g_video_output;
static const VideoOutputInfo g_video_outputs[] = { static const VideoOutputInfo g_video_outputs[] = {
/* Video outputs are sorted in test order for automatic characterisation */ /* Video outputs are sorted in test order for automatic characterisation */
#if USE_WAYLAND #if USE_WAYLAND
{ "wayland", {"wayland",
gst_vaapi_display_wayland_new, gst_vaapi_display_wayland_new,
gst_vaapi_window_wayland_new gst_vaapi_window_wayland_new},
},
#endif #endif
#if USE_X11 #if USE_X11
{ "x11", {"x11",
gst_vaapi_display_x11_new, gst_vaapi_display_x11_new,
gst_vaapi_window_x11_new, gst_vaapi_window_x11_new,
gst_vaapi_pixmap_x11_new gst_vaapi_pixmap_x11_new},
},
#endif #endif
#if USE_GLX #if USE_GLX
{ "glx", {"glx",
gst_vaapi_display_glx_new, gst_vaapi_display_glx_new,
gst_vaapi_window_glx_new, gst_vaapi_window_glx_new,
gst_vaapi_pixmap_x11_new gst_vaapi_pixmap_x11_new},
},
#endif #endif
#if USE_DRM #if USE_DRM
{ "drm", {"drm",
gst_vaapi_display_drm_new, gst_vaapi_display_drm_new,
gst_vaapi_window_drm_new gst_vaapi_window_drm_new},
},
#endif #endif
{ NULL, } {NULL,}
}; };
static gchar *g_output_name; static gchar *g_output_name;
@ -86,163 +82,164 @@ static gboolean g_egl_mode = FALSE;
static guint g_gles_version; static guint g_gles_version;
static GOptionEntry g_options[] = { static GOptionEntry g_options[] = {
{ "list-outputs", 0, {"list-outputs", 0,
0, 0,
G_OPTION_ARG_NONE, &g_list_outputs, G_OPTION_ARG_NONE, &g_list_outputs,
"list video outputs", NULL }, "list video outputs", NULL},
{ "output", 'o', {"output", 'o',
0, 0,
G_OPTION_ARG_STRING, &g_output_name, G_OPTION_ARG_STRING, &g_output_name,
"video output name", NULL }, "video output name", NULL},
{ "fullscreen", 'f', {"fullscreen", 'f',
0, 0,
G_OPTION_ARG_NONE, &g_fullscreen, G_OPTION_ARG_NONE, &g_fullscreen,
"fullscreen mode", NULL }, "fullscreen mode", NULL},
{ "egl", 0, {"egl", 0,
0, 0,
G_OPTION_ARG_NONE, &g_egl_mode, G_OPTION_ARG_NONE, &g_egl_mode,
"enable EGL rendering", NULL }, "enable EGL rendering", NULL},
{ "gles-version", 0, {"gles-version", 0,
0, 0,
G_OPTION_ARG_INT, &g_gles_version, G_OPTION_ARG_INT, &g_gles_version,
"OpenGL|ES version (in --egl mode)", NULL }, "OpenGL|ES version (in --egl mode)", NULL},
{ NULL, } {NULL,}
}; };
static void static void
list_outputs(void) list_outputs (void)
{ {
const VideoOutputInfo *o; const VideoOutputInfo *o;
g_print("Video outputs:"); g_print ("Video outputs:");
for (o = g_video_outputs; o->name != NULL; o++) for (o = g_video_outputs; o->name != NULL; o++)
g_print(" %s", o->name); g_print (" %s", o->name);
g_print("\n"); g_print ("\n");
} }
gboolean gboolean
video_output_init(int *argc, char *argv[], GOptionEntry *options) video_output_init (int *argc, char *argv[], GOptionEntry * options)
{ {
GOptionContext *ctx; GOptionContext *ctx;
gboolean success; gboolean success;
#if !GLIB_CHECK_VERSION(2,31,0) #if !GLIB_CHECK_VERSION(2,31,0)
if (!g_thread_supported()) if (!g_thread_supported ())
g_thread_init(NULL); g_thread_init (NULL);
#endif #endif
ctx = g_option_context_new("- test options"); ctx = g_option_context_new ("- test options");
if (!ctx) if (!ctx)
return FALSE; return FALSE;
g_option_context_add_group(ctx, gst_init_get_option_group()); g_option_context_add_group (ctx, gst_init_get_option_group ());
g_option_context_add_main_entries(ctx, g_options, NULL); g_option_context_add_main_entries (ctx, g_options, NULL);
if (options) if (options)
g_option_context_add_main_entries(ctx, options, NULL); g_option_context_add_main_entries (ctx, options, NULL);
success = g_option_context_parse(ctx, argc, &argv, NULL); success = g_option_context_parse (ctx, argc, &argv, NULL);
g_option_context_free(ctx); g_option_context_free (ctx);
if (g_list_outputs) { if (g_list_outputs) {
list_outputs(); list_outputs ();
exit(0); exit (0);
} }
return success; return success;
} }
void void
video_output_exit(void) video_output_exit (void)
{ {
g_free(g_output_name); g_free (g_output_name);
gst_deinit(); gst_deinit ();
} }
const VideoOutputInfo * const VideoOutputInfo *
video_output_lookup(const gchar *output_name) video_output_lookup (const gchar * output_name)
{ {
const VideoOutputInfo *o; const VideoOutputInfo *o;
if (!output_name) if (!output_name)
return NULL;
for (o = g_video_outputs; o->name != NULL; o++) {
if (g_ascii_strcasecmp(o->name, output_name) == 0)
return o;
}
return NULL; return NULL;
for (o = g_video_outputs; o->name != NULL; o++) {
if (g_ascii_strcasecmp (o->name, output_name) == 0)
return o;
}
return NULL;
} }
GstVaapiDisplay * GstVaapiDisplay *
video_output_create_display(const gchar *display_name) video_output_create_display (const gchar * display_name)
{ {
const VideoOutputInfo *o = g_video_output; const VideoOutputInfo *o = g_video_output;
GstVaapiDisplay *egl_display, *display = NULL; GstVaapiDisplay *egl_display, *display = NULL;
if (!o) { if (!o) {
if (g_output_name) if (g_output_name)
o = video_output_lookup(g_output_name); o = video_output_lookup (g_output_name);
else { else {
for (o = g_video_outputs; o->name != NULL; o++) { for (o = g_video_outputs; o->name != NULL; o++) {
display = o->create_display(display_name); display = o->create_display (display_name);
if (display) { if (display) {
if (gst_vaapi_display_get_display(display)) if (gst_vaapi_display_get_display (display))
break; break;
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
display = NULL; display = NULL;
}
}
} }
if (!o || !o->name) }
return NULL;
g_print("Using %s video output\n", o->name);
g_video_output = o;
} }
if (!o || !o->name)
return NULL;
g_print ("Using %s video output\n", o->name);
g_video_output = o;
}
if (!display) if (!display)
display = o->create_display(display_name); display = o->create_display (display_name);
if (g_egl_mode) { if (g_egl_mode) {
#if USE_EGL #if USE_EGL
egl_display = gst_vaapi_display_egl_new (display, g_gles_version); egl_display = gst_vaapi_display_egl_new (display, g_gles_version);
#else #else
egl_display = NULL; egl_display = NULL;
g_print("error: unsupported EGL renderering mode\n"); g_print ("error: unsupported EGL renderering mode\n");
#endif #endif
gst_vaapi_display_unref (display); gst_vaapi_display_unref (display);
if (!egl_display) if (!egl_display)
return NULL; return NULL;
display = egl_display; display = egl_display;
} }
return display; return display;
} }
GstVaapiWindow * GstVaapiWindow *
video_output_create_window(GstVaapiDisplay *display, guint width, guint height) video_output_create_window (GstVaapiDisplay * display, guint width,
guint height)
{ {
GstVaapiWindow *window; GstVaapiWindow *window;
if (!g_video_output) if (!g_video_output)
return NULL; return NULL;
#if USE_EGL #if USE_EGL
if (g_egl_mode) if (g_egl_mode)
window = gst_vaapi_window_egl_new(display, width, height); window = gst_vaapi_window_egl_new (display, width, height);
else else
#endif #endif
window = g_video_output->create_window(display, width, height); window = g_video_output->create_window (display, width, height);
if (!window) if (!window)
return NULL; return NULL;
/* Force fullscreen mode, should this be requested by the user */ /* Force fullscreen mode, should this be requested by the user */
if (g_fullscreen) if (g_fullscreen)
gst_vaapi_window_set_fullscreen(window, TRUE); gst_vaapi_window_set_fullscreen (window, TRUE);
return window; return window;
} }
GstVaapiPixmap * GstVaapiPixmap *
video_output_create_pixmap(GstVaapiDisplay *display, GstVideoFormat format, video_output_create_pixmap (GstVaapiDisplay * display, GstVideoFormat format,
guint width, guint height) guint width, guint height)
{ {
if (!g_video_output || !g_video_output->create_pixmap) if (!g_video_output || !g_video_output->create_pixmap)
return NULL; return NULL;
return g_video_output->create_pixmap(display, format, width, height); return g_video_output->create_pixmap (display, format, width, height);
} }

File diff suppressed because it is too large Load diff

View file

@ -31,115 +31,114 @@
/* Set to 1 to check display cache works (shared VA display) */ /* Set to 1 to check display cache works (shared VA display) */
#define CHECK_DISPLAY_CACHE 1 #define CHECK_DISPLAY_CACHE 1
static inline void pause(void) static inline void
pause (void)
{ {
g_print("Press any key to continue...\n"); g_print ("Press any key to continue...\n");
getchar(); getchar ();
} }
static gchar *g_codec_str; static gchar *g_codec_str;
static gboolean g_use_pixmap; static gboolean g_use_pixmap;
static GOptionEntry g_options[] = { static GOptionEntry g_options[] = {
{ "codec", 'c', {"codec", 'c',
0, 0,
G_OPTION_ARG_STRING, &g_codec_str, G_OPTION_ARG_STRING, &g_codec_str,
"codec to test", NULL }, "codec to test", NULL},
{ "pixmap", 0, {"pixmap", 0,
0, 0,
G_OPTION_ARG_NONE, &g_use_pixmap, G_OPTION_ARG_NONE, &g_use_pixmap,
"use render-to-pixmap", NULL }, "use render-to-pixmap", NULL},
{ NULL, } {NULL,}
}; };
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
GstVaapiDisplay *display, *display2; GstVaapiDisplay *display, *display2;
GstVaapiWindow *window; GstVaapiWindow *window;
GstVaapiPixmap *pixmap = NULL; GstVaapiPixmap *pixmap = NULL;
GstVaapiDecoder *decoder; GstVaapiDecoder *decoder;
GstVaapiSurfaceProxy *proxy; GstVaapiSurfaceProxy *proxy;
GstVaapiSurface *surface; GstVaapiSurface *surface;
const GstVaapiRectangle *crop_rect; const GstVaapiRectangle *crop_rect;
static const guint win_width = 640; static const guint win_width = 640;
static const guint win_height = 480; static const guint win_height = 480;
if (!video_output_init(&argc, argv, g_options)) if (!video_output_init (&argc, argv, g_options))
g_error("failed to initialize video output subsystem"); g_error ("failed to initialize video output subsystem");
g_print("Test decode\n"); g_print ("Test decode\n");
display = video_output_create_display(NULL); display = video_output_create_display (NULL);
if (!display) if (!display)
g_error("could not create VA display"); g_error ("could not create VA display");
if (CHECK_DISPLAY_CACHE) if (CHECK_DISPLAY_CACHE)
display2 = video_output_create_display(NULL); display2 = video_output_create_display (NULL);
else else
display2 = gst_vaapi_display_ref(display); display2 = gst_vaapi_display_ref (display);
if (!display2) if (!display2)
g_error("could not create second VA display"); g_error ("could not create second VA display");
window = video_output_create_window(display, win_width, win_height); window = video_output_create_window (display, win_width, win_height);
if (!window) if (!window)
g_error("could not create window"); g_error ("could not create window");
decoder = decoder_new(display, g_codec_str); decoder = decoder_new (display, g_codec_str);
if (!decoder) if (!decoder)
g_error("could not create decoder"); g_error ("could not create decoder");
g_print("Decode %s sample frame\n", decoder_get_codec_name(decoder)); g_print ("Decode %s sample frame\n", decoder_get_codec_name (decoder));
if (!decoder_put_buffers(decoder)) if (!decoder_put_buffers (decoder))
g_error("could not fill decoder with sample data"); g_error ("could not fill decoder with sample data");
proxy = decoder_get_surface(decoder); proxy = decoder_get_surface (decoder);
if (!proxy) if (!proxy)
g_error("could not get decoded surface"); g_error ("could not get decoded surface");
surface = gst_vaapi_surface_proxy_get_surface(proxy); surface = gst_vaapi_surface_proxy_get_surface (proxy);
crop_rect = gst_vaapi_surface_proxy_get_crop_rect(proxy); crop_rect = gst_vaapi_surface_proxy_get_crop_rect (proxy);
gst_vaapi_window_show(window); gst_vaapi_window_show (window);
if (g_use_pixmap) { if (g_use_pixmap) {
guint width, height; guint width, height;
if (crop_rect) { if (crop_rect) {
width = crop_rect->width; width = crop_rect->width;
height = crop_rect->height; height = crop_rect->height;
} } else
else gst_vaapi_surface_get_size (surface, &width, &height);
gst_vaapi_surface_get_size(surface, &width, &height);
pixmap = video_output_create_pixmap(display, GST_VIDEO_FORMAT_xRGB, pixmap = video_output_create_pixmap (display, GST_VIDEO_FORMAT_xRGB,
width, height); width, height);
if (!pixmap) if (!pixmap)
g_error("could not create pixmap"); g_error ("could not create pixmap");
if (!gst_vaapi_pixmap_put_surface(pixmap, surface, crop_rect, if (!gst_vaapi_pixmap_put_surface (pixmap, surface, crop_rect,
GST_VAAPI_PICTURE_STRUCTURE_FRAME))
g_error("could not render to pixmap");
if (!gst_vaapi_window_put_pixmap(window, pixmap, NULL, NULL))
g_error("could not render pixmap");
}
else if (!gst_vaapi_window_put_surface(window, surface, crop_rect, NULL,
GST_VAAPI_PICTURE_STRUCTURE_FRAME)) GST_VAAPI_PICTURE_STRUCTURE_FRAME))
g_error("could not render surface"); g_error ("could not render to pixmap");
pause(); if (!gst_vaapi_window_put_pixmap (window, pixmap, NULL, NULL))
g_error ("could not render pixmap");
} else if (!gst_vaapi_window_put_surface (window, surface, crop_rect, NULL,
GST_VAAPI_PICTURE_STRUCTURE_FRAME))
g_error ("could not render surface");
if (pixmap) pause ();
gst_vaapi_pixmap_unref(pixmap);
gst_vaapi_surface_proxy_unref(proxy); if (pixmap)
gst_vaapi_decoder_unref(decoder); gst_vaapi_pixmap_unref (pixmap);
gst_vaapi_window_unref(window); gst_vaapi_surface_proxy_unref (proxy);
gst_vaapi_display_unref(display); gst_vaapi_decoder_unref (decoder);
gst_vaapi_display_unref(display2); gst_vaapi_window_unref (window);
g_free(g_codec_str); gst_vaapi_display_unref (display);
video_output_exit(); gst_vaapi_display_unref (display2);
return 0; g_free (g_codec_str);
video_output_exit ();
return 0;
} }

View file

@ -54,514 +54,512 @@
#define CHECK_DISPLAY_CACHE 1 #define CHECK_DISPLAY_CACHE 1
static void static void
print_value(const GValue *value, const gchar *name) print_value (const GValue * value, const gchar * name)
{ {
gchar *value_string; gchar *value_string;
value_string = g_strdup_value_contents(value); value_string = g_strdup_value_contents (value);
if (!value_string) if (!value_string)
return; return;
g_print(" %s: %s\n", name, value_string); g_print (" %s: %s\n", name, value_string);
g_free(value_string); g_free (value_string);
} }
static void static void
print_profiles(GArray *profiles, const gchar *name) print_profiles (GArray * profiles, const gchar * name)
{ {
GstVaapiCodec codec; GstVaapiCodec codec;
const gchar *codec_name, *profile_name; const gchar *codec_name, *profile_name;
guint i; guint i;
g_print("%u %s caps\n", profiles->len, name); g_print ("%u %s caps\n", profiles->len, name);
for (i = 0; i < profiles->len; i++) { for (i = 0; i < profiles->len; i++) {
const GstVaapiProfile profile = const GstVaapiProfile profile =
g_array_index(profiles, GstVaapiProfile, i); g_array_index (profiles, GstVaapiProfile, i);
codec = gst_vaapi_profile_get_codec(profile); codec = gst_vaapi_profile_get_codec (profile);
if (!codec) if (!codec)
continue; continue;
codec_name = gst_vaapi_codec_get_name(codec); codec_name = gst_vaapi_codec_get_name (codec);
if (!codec_name) if (!codec_name)
continue; continue;
profile_name = gst_vaapi_profile_get_name(profile); profile_name = gst_vaapi_profile_get_name (profile);
if (!profile_name) if (!profile_name)
continue; continue;
g_print(" %s: %s profile\n", codec_name, profile_name); g_print (" %s: %s profile\n", codec_name, profile_name);
} }
} }
static void static void
print_format_yuv(const VAImageFormat *va_format) print_format_yuv (const VAImageFormat * va_format)
{ {
const guint32 fourcc = va_format->fourcc; const guint32 fourcc = va_format->fourcc;
g_print(" fourcc '%c%c%c%c'", g_print (" fourcc '%c%c%c%c'",
fourcc & 0xff, fourcc & 0xff,
(fourcc >> 8) & 0xff, (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff);
(fourcc >> 16) & 0xff,
(fourcc >> 24) & 0xff);
} }
static void static void
print_format_rgb(const VAImageFormat *va_format) print_format_rgb (const VAImageFormat * va_format)
{ {
g_print(" %d bits per pixel, %s endian,", g_print (" %d bits per pixel, %s endian,",
va_format->bits_per_pixel, va_format->bits_per_pixel,
va_format->byte_order == VA_MSB_FIRST ? "big" : "little"); va_format->byte_order == VA_MSB_FIRST ? "big" : "little");
g_print(" %s masks", va_format->alpha_mask ? "rgba" : "rgb"); g_print (" %s masks", va_format->alpha_mask ? "rgba" : "rgb");
g_print(" 0x%08x 0x%08x 0x%08x", g_print (" 0x%08x 0x%08x 0x%08x",
va_format->red_mask, va_format->green_mask, va_format->blue_mask); va_format->red_mask, va_format->green_mask, va_format->blue_mask);
if (va_format->alpha_mask) if (va_format->alpha_mask)
g_print(" 0x%08x", va_format->alpha_mask); g_print (" 0x%08x", va_format->alpha_mask);
} }
static void static void
print_formats(GArray *formats, const gchar *name) print_formats (GArray * formats, const gchar * name)
{ {
guint i; guint i;
g_print("%u %s caps\n", formats->len, name); g_print ("%u %s caps\n", formats->len, name);
for (i = 0; i < formats->len; i++) { for (i = 0; i < formats->len; i++) {
const GstVideoFormat format = g_array_index(formats, GstVideoFormat, i); const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
const VAImageFormat *va_format; const VAImageFormat *va_format;
g_print(" %s:", gst_vaapi_video_format_to_string(format)); g_print (" %s:", gst_vaapi_video_format_to_string (format));
va_format = gst_vaapi_video_format_to_va_format(format); va_format = gst_vaapi_video_format_to_va_format (format);
if (!va_format) if (!va_format)
g_error("could not determine VA format"); g_error ("could not determine VA format");
if (gst_vaapi_video_format_is_yuv(format)) if (gst_vaapi_video_format_is_yuv (format))
print_format_yuv(va_format); print_format_yuv (va_format);
else else
print_format_rgb(va_format); print_format_rgb (va_format);
g_print("\n"); g_print ("\n");
} }
} }
typedef struct _GstVaapiDisplayProperty GstVaapiDisplayProperty; typedef struct _GstVaapiDisplayProperty GstVaapiDisplayProperty;
struct _GstVaapiDisplayProperty { struct _GstVaapiDisplayProperty
const gchar *name; {
GValue value; const gchar *name;
GValue value;
}; };
static void static void
gst_vaapi_display_property_free(GstVaapiDisplayProperty *prop) gst_vaapi_display_property_free (GstVaapiDisplayProperty * prop)
{ {
if (!prop) if (!prop)
return; return;
g_value_unset(&prop->value); g_value_unset (&prop->value);
g_slice_free(GstVaapiDisplayProperty, prop); g_slice_free (GstVaapiDisplayProperty, prop);
} }
static GstVaapiDisplayProperty * static GstVaapiDisplayProperty *
gst_vaapi_display_property_new(const gchar *name) gst_vaapi_display_property_new (const gchar * name)
{ {
GstVaapiDisplayProperty *prop; GstVaapiDisplayProperty *prop;
prop = g_slice_new0(GstVaapiDisplayProperty); prop = g_slice_new0 (GstVaapiDisplayProperty);
if (!prop) if (!prop)
return NULL; return NULL;
prop->name = name; prop->name = name;
return prop; return prop;
} }
static void static void
free_property_cb(gpointer data, gpointer user_data) free_property_cb (gpointer data, gpointer user_data)
{ {
gst_vaapi_display_property_free(data); gst_vaapi_display_property_free (data);
} }
static void static void
dump_properties(GstVaapiDisplay *display) dump_properties (GstVaapiDisplay * display)
{ {
GstVaapiDisplayProperty *prop; GstVaapiDisplayProperty *prop;
GPtrArray *properties; GPtrArray *properties;
guint i; guint i;
static const gchar *g_properties[] = { static const gchar *g_properties[] = {
GST_VAAPI_DISPLAY_PROP_RENDER_MODE, GST_VAAPI_DISPLAY_PROP_RENDER_MODE,
GST_VAAPI_DISPLAY_PROP_ROTATION, GST_VAAPI_DISPLAY_PROP_ROTATION,
GST_VAAPI_DISPLAY_PROP_HUE, GST_VAAPI_DISPLAY_PROP_HUE,
GST_VAAPI_DISPLAY_PROP_SATURATION, GST_VAAPI_DISPLAY_PROP_SATURATION,
GST_VAAPI_DISPLAY_PROP_BRIGHTNESS, GST_VAAPI_DISPLAY_PROP_BRIGHTNESS,
GST_VAAPI_DISPLAY_PROP_CONTRAST, GST_VAAPI_DISPLAY_PROP_CONTRAST,
NULL NULL
}; };
properties = g_ptr_array_new(); properties = g_ptr_array_new ();
if (!properties) if (!properties)
return; return;
for (i = 0; g_properties[i] != NULL; i++) { for (i = 0; g_properties[i] != NULL; i++) {
const gchar * const name = g_properties[i]; const gchar *const name = g_properties[i];
if (!gst_vaapi_display_has_property(display, name)) if (!gst_vaapi_display_has_property (display, name))
continue; continue;
prop = gst_vaapi_display_property_new(name);
if (!prop) {
GST_ERROR("failed to allocate GstVaapiDisplayProperty");
goto end;
}
if (!gst_vaapi_display_get_property(display, name, &prop->value)) { prop = gst_vaapi_display_property_new (name);
GST_ERROR("failed to get property '%s'", name); if (!prop) {
goto end; GST_ERROR ("failed to allocate GstVaapiDisplayProperty");
} goto end;
g_ptr_array_add(properties, prop);
} }
g_print("%u properties\n", properties->len); if (!gst_vaapi_display_get_property (display, name, &prop->value)) {
for (i = 0; i < properties->len; i++) { GST_ERROR ("failed to get property '%s'", name);
prop = g_ptr_array_index(properties, i); goto end;
print_value(&prop->value, prop->name);
} }
g_ptr_array_add (properties, prop);
}
g_print ("%u properties\n", properties->len);
for (i = 0; i < properties->len; i++) {
prop = g_ptr_array_index (properties, i);
print_value (&prop->value, prop->name);
}
end: end:
if (properties) { if (properties) {
g_ptr_array_foreach(properties, free_property_cb, NULL); g_ptr_array_foreach (properties, free_property_cb, NULL);
g_ptr_array_free(properties, TRUE); g_ptr_array_free (properties, TRUE);
} }
} }
static void static void
dump_info(GstVaapiDisplay *display) dump_info (GstVaapiDisplay * display)
{ {
GArray *profiles, *formats; GArray *profiles, *formats;
profiles = gst_vaapi_display_get_decode_profiles(display); profiles = gst_vaapi_display_get_decode_profiles (display);
if (!profiles) if (!profiles)
g_error("could not get VA decode profiles"); g_error ("could not get VA decode profiles");
print_profiles(profiles, "decoders"); print_profiles (profiles, "decoders");
g_array_unref(profiles); g_array_unref (profiles);
profiles = gst_vaapi_display_get_encode_profiles(display); profiles = gst_vaapi_display_get_encode_profiles (display);
if (!profiles) if (!profiles)
g_error("could not get VA encode profiles"); g_error ("could not get VA encode profiles");
print_profiles(profiles, "encoders"); print_profiles (profiles, "encoders");
g_array_unref(profiles); g_array_unref (profiles);
formats = gst_vaapi_display_get_image_formats(display); formats = gst_vaapi_display_get_image_formats (display);
if (!formats) if (!formats)
g_error("could not get VA image formats"); g_error ("could not get VA image formats");
print_formats(formats, "image"); print_formats (formats, "image");
g_array_unref(formats); g_array_unref (formats);
formats = gst_vaapi_display_get_subpicture_formats(display); formats = gst_vaapi_display_get_subpicture_formats (display);
if (!formats) if (!formats)
g_error("could not get VA subpicture formats"); g_error ("could not get VA subpicture formats");
print_formats(formats, "subpicture"); print_formats (formats, "subpicture");
g_array_unref(formats); g_array_unref (formats);
dump_properties(display); dump_properties (display);
} }
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
GstVaapiDisplay *display, *display2; GstVaapiDisplay *display, *display2;
guint width, height, par_n, par_d; guint width, height, par_n, par_d;
gst_init(&argc, &argv); gst_init (&argc, &argv);
#if USE_DRM #if USE_DRM
g_print("#\n"); g_print ("#\n");
g_print("# Create display with gst_vaapi_display_drm_new()\n"); g_print ("# Create display with gst_vaapi_display_drm_new()\n");
g_print("#\n"); g_print ("#\n");
{ {
display = gst_vaapi_display_drm_new(NULL); display = gst_vaapi_display_drm_new (NULL);
if (!display) if (!display)
g_error("could not create Gst/VA display"); g_error ("could not create Gst/VA display");
dump_info(display); dump_info (display);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
} }
g_print("\n"); g_print ("\n");
g_print("#\n"); g_print ("#\n");
g_print("# Create display with gst_vaapi_display_drm_new_with_device()\n"); g_print ("# Create display with gst_vaapi_display_drm_new_with_device()\n");
g_print("#\n"); g_print ("#\n");
{ {
int drm_device; int drm_device;
drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC); drm_device = open (DRM_DEVICE_PATH, O_RDWR | O_CLOEXEC);
if (drm_device < 0) if (drm_device < 0)
g_error("could not open DRM device"); g_error ("could not open DRM device");
display = gst_vaapi_display_drm_new_with_device(drm_device); display = gst_vaapi_display_drm_new_with_device (drm_device);
if (!display) if (!display)
g_error("could not create Gst/VA display"); g_error ("could not create Gst/VA display");
dump_info(display); dump_info (display);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
close(drm_device); close (drm_device);
} }
g_print("\n"); g_print ("\n");
g_print("#\n"); g_print ("#\n");
g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayDRM()]\n"); g_print
g_print("#\n"); ("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayDRM()]\n");
{ g_print ("#\n");
int drm_device; {
VADisplay va_display; int drm_device;
VADisplay va_display;
drm_device = open(DRM_DEVICE_PATH, O_RDWR|O_CLOEXEC); drm_device = open (DRM_DEVICE_PATH, O_RDWR | O_CLOEXEC);
if (drm_device < 0) if (drm_device < 0)
g_error("could not open DRM device"); g_error ("could not open DRM device");
va_display = vaGetDisplayDRM(drm_device); va_display = vaGetDisplayDRM (drm_device);
if (!va_display) if (!va_display)
g_error("could not create VA display"); g_error ("could not create VA display");
display = gst_vaapi_display_new_with_display(va_display); display = gst_vaapi_display_new_with_display (va_display);
if (!display) if (!display)
g_error("could not create Gst/VA display"); g_error ("could not create Gst/VA display");
dump_info(display); dump_info (display);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
close(drm_device); close (drm_device);
} }
g_print("\n"); g_print ("\n");
#endif #endif
#if USE_X11 #if USE_X11
g_print("#\n"); g_print ("#\n");
g_print("# Create display with gst_vaapi_display_x11_new()\n"); g_print ("# Create display with gst_vaapi_display_x11_new()\n");
g_print("#\n"); g_print ("#\n");
{ {
display = gst_vaapi_display_x11_new(NULL); display = gst_vaapi_display_x11_new (NULL);
if (!display) if (!display)
g_error("could not create Gst/VA display"); g_error ("could not create Gst/VA display");
if (CHECK_DISPLAY_CACHE) { if (CHECK_DISPLAY_CACHE) {
display2 = gst_vaapi_display_x11_new(NULL); display2 = gst_vaapi_display_x11_new (NULL);
/* Check for the same X11 display */ /* Check for the same X11 display */
g_assert(gst_vaapi_display_x11_get_display( g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11
GST_VAAPI_DISPLAY_X11(display)) == (display)) ==
gst_vaapi_display_x11_get_display( gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2)));
GST_VAAPI_DISPLAY_X11(display2)));
/* Check for the same VA display */ /* Check for the same VA display */
g_assert(gst_vaapi_display_get_display(display) == g_assert (gst_vaapi_display_get_display (display) ==
gst_vaapi_display_get_display(display2)); gst_vaapi_display_get_display (display2));
gst_vaapi_display_unref(display2); gst_vaapi_display_unref (display2);
#if USE_GLX #if USE_GLX
display2 = gst_vaapi_display_glx_new(NULL); display2 = gst_vaapi_display_glx_new (NULL);
/* Check for the different X11 display */ /* Check for the different X11 display */
/* XXX: it is also desired to cache underlying X11 displays */ /* XXX: it is also desired to cache underlying X11 displays */
g_assert(gst_vaapi_display_x11_get_display( g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11
GST_VAAPI_DISPLAY_X11(display)) != (display)) !=
gst_vaapi_display_x11_get_display( gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2)));
GST_VAAPI_DISPLAY_X11(display2)));
/* Check for different VA display */ /* Check for different VA display */
g_assert(gst_vaapi_display_get_display(display) != g_assert (gst_vaapi_display_get_display (display) !=
gst_vaapi_display_get_display(display2)); gst_vaapi_display_get_display (display2));
gst_vaapi_display_unref(display2); gst_vaapi_display_unref (display2);
#endif #endif
}
gst_vaapi_display_get_size(display, &width, &height);
g_print("Display size: %ux%u\n", width, height);
gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d);
g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d);
dump_info(display);
gst_vaapi_display_unref(display);
} }
g_print("\n");
g_print("#\n"); gst_vaapi_display_get_size (display, &width, &height);
g_print("# Create display with gst_vaapi_display_x11_new_with_display()\n"); g_print ("Display size: %ux%u\n", width, height);
g_print("#\n");
{
Display *x11_display;
x11_display = XOpenDisplay(NULL); gst_vaapi_display_get_pixel_aspect_ratio (display, &par_n, &par_d);
if (!x11_display) g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d);
g_error("could not create X11 display");
display = gst_vaapi_display_x11_new_with_display(x11_display); dump_info (display);
if (!display) gst_vaapi_display_unref (display);
g_error("could not create Gst/VA display"); }
g_print ("\n");
if (CHECK_DISPLAY_CACHE) { g_print ("#\n");
display2 = gst_vaapi_display_x11_new_with_display(x11_display); g_print ("# Create display with gst_vaapi_display_x11_new_with_display()\n");
g_print ("#\n");
{
Display *x11_display;
/* Check for the same VA display */ x11_display = XOpenDisplay (NULL);
g_assert(gst_vaapi_display_get_display(display) == if (!x11_display)
gst_vaapi_display_get_display(display2)); g_error ("could not create X11 display");
gst_vaapi_display_unref(display2); display = gst_vaapi_display_x11_new_with_display (x11_display);
} if (!display)
g_error ("could not create Gst/VA display");
dump_info(display); if (CHECK_DISPLAY_CACHE) {
gst_vaapi_display_unref(display); display2 = gst_vaapi_display_x11_new_with_display (x11_display);
XCloseDisplay(x11_display);
/* Check for the same VA display */
g_assert (gst_vaapi_display_get_display (display) ==
gst_vaapi_display_get_display (display2));
gst_vaapi_display_unref (display2);
} }
g_print("\n");
g_print("#\n"); dump_info (display);
g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplay()]\n"); gst_vaapi_display_unref (display);
g_print("#\n"); XCloseDisplay (x11_display);
{ }
Display *x11_display; g_print ("\n");
VADisplay va_display;
x11_display = XOpenDisplay(NULL); g_print ("#\n");
if (!x11_display) g_print
g_error("could not create X11 display"); ("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplay()]\n");
g_print ("#\n");
{
Display *x11_display;
VADisplay va_display;
va_display = vaGetDisplay(x11_display); x11_display = XOpenDisplay (NULL);
if (!va_display) if (!x11_display)
g_error("could not create VA display"); g_error ("could not create X11 display");
display = gst_vaapi_display_new_with_display(va_display); va_display = vaGetDisplay (x11_display);
if (!display) if (!va_display)
g_error("could not create Gst/VA display"); g_error ("could not create VA display");
dump_info(display); display = gst_vaapi_display_new_with_display (va_display);
gst_vaapi_display_unref(display); if (!display)
XCloseDisplay(x11_display); g_error ("could not create Gst/VA display");
}
g_print("\n"); dump_info (display);
gst_vaapi_display_unref (display);
XCloseDisplay (x11_display);
}
g_print ("\n");
#endif #endif
#if USE_GLX #if USE_GLX
g_print("#\n"); g_print ("#\n");
g_print("# Create display with gst_vaapi_display_glx_new()\n"); g_print ("# Create display with gst_vaapi_display_glx_new()\n");
g_print("#\n"); g_print ("#\n");
{ {
display = gst_vaapi_display_glx_new(NULL); display = gst_vaapi_display_glx_new (NULL);
if (!display) if (!display)
g_error("could not create Gst/VA display"); g_error ("could not create Gst/VA display");
if (CHECK_DISPLAY_CACHE) { if (CHECK_DISPLAY_CACHE) {
display2 = gst_vaapi_display_glx_new(NULL); display2 = gst_vaapi_display_glx_new (NULL);
/* Check for the same X11 display */ /* Check for the same X11 display */
g_assert(gst_vaapi_display_x11_get_display( g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11
GST_VAAPI_DISPLAY_X11(display)) == (display)) ==
gst_vaapi_display_x11_get_display( gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2)));
GST_VAAPI_DISPLAY_X11(display2)));
/* Check for the same VA display */ /* Check for the same VA display */
g_assert(gst_vaapi_display_get_display(display) == g_assert (gst_vaapi_display_get_display (display) ==
gst_vaapi_display_get_display(display2)); gst_vaapi_display_get_display (display2));
gst_vaapi_display_unref(display2); gst_vaapi_display_unref (display2);
display2 = gst_vaapi_display_x11_new(NULL); display2 = gst_vaapi_display_x11_new (NULL);
/* Check for the same X11 display */ /* Check for the same X11 display */
g_assert(gst_vaapi_display_x11_get_display( g_assert (gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11
GST_VAAPI_DISPLAY_X11(display)) == (display)) ==
gst_vaapi_display_x11_get_display( gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display2)));
GST_VAAPI_DISPLAY_X11(display2)));
/* Check for the same VA display */ /* Check for the same VA display */
g_assert(gst_vaapi_display_get_display(display) == g_assert (gst_vaapi_display_get_display (display) ==
gst_vaapi_display_get_display(display2)); gst_vaapi_display_get_display (display2));
gst_vaapi_display_unref(display2); gst_vaapi_display_unref (display2);
}
gst_vaapi_display_get_size(display, &width, &height);
g_print("Display size: %ux%u\n", width, height);
gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d);
g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d);
dump_info(display);
gst_vaapi_display_unref(display);
} }
g_print("\n");
g_print("#\n"); gst_vaapi_display_get_size (display, &width, &height);
g_print("# Create display with gst_vaapi_display_glx_new_with_display()\n"); g_print ("Display size: %ux%u\n", width, height);
g_print("#\n");
{
Display *x11_display;
x11_display = XOpenDisplay(NULL); gst_vaapi_display_get_pixel_aspect_ratio (display, &par_n, &par_d);
if (!x11_display) g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d);
g_error("could not create X11 display");
display = gst_vaapi_display_glx_new_with_display(x11_display); dump_info (display);
if (!display) gst_vaapi_display_unref (display);
g_error("could not create Gst/VA display"); }
g_print ("\n");
dump_info(display); g_print ("#\n");
gst_vaapi_display_unref(display); g_print ("# Create display with gst_vaapi_display_glx_new_with_display()\n");
XCloseDisplay(x11_display); g_print ("#\n");
} {
g_print("\n"); Display *x11_display;
x11_display = XOpenDisplay (NULL);
if (!x11_display)
g_error ("could not create X11 display");
display = gst_vaapi_display_glx_new_with_display (x11_display);
if (!display)
g_error ("could not create Gst/VA display");
dump_info (display);
gst_vaapi_display_unref (display);
XCloseDisplay (x11_display);
}
g_print ("\n");
#ifdef HAVE_VA_VA_GLX_H #ifdef HAVE_VA_VA_GLX_H
g_print("#\n"); g_print ("#\n");
g_print("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n"); g_print
g_print("#\n"); ("# Create display with gst_vaapi_display_new_with_display() [vaGetDisplayGLX()]\n");
{ g_print ("#\n");
Display *x11_display; {
VADisplay va_display; Display *x11_display;
VADisplay va_display;
x11_display = XOpenDisplay(NULL); x11_display = XOpenDisplay (NULL);
if (!x11_display) if (!x11_display)
g_error("could not create X11 display"); g_error ("could not create X11 display");
va_display = vaGetDisplayGLX(x11_display); va_display = vaGetDisplayGLX (x11_display);
if (!va_display) if (!va_display)
g_error("could not create VA display"); g_error ("could not create VA display");
display = gst_vaapi_display_new_with_display(va_display); display = gst_vaapi_display_new_with_display (va_display);
if (!display) if (!display)
g_error("could not create Gst/VA display"); g_error ("could not create Gst/VA display");
dump_info(display); dump_info (display);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
XCloseDisplay(x11_display); XCloseDisplay (x11_display);
} }
g_print("\n"); g_print ("\n");
#endif #endif
#endif #endif
#if USE_WAYLAND #if USE_WAYLAND
g_print("#\n"); g_print ("#\n");
g_print("# Create display with gst_vaapi_display_wayland_new()\n"); g_print ("# Create display with gst_vaapi_display_wayland_new()\n");
g_print("#\n"); g_print ("#\n");
{ {
display = gst_vaapi_display_wayland_new(NULL); display = gst_vaapi_display_wayland_new (NULL);
if (!display) if (!display)
g_error("could not create Gst/VA display"); g_error ("could not create Gst/VA display");
gst_vaapi_display_get_size(display, &width, &height); gst_vaapi_display_get_size (display, &width, &height);
g_print("Display size: %ux%u\n", width, height); g_print ("Display size: %ux%u\n", width, height);
gst_vaapi_display_get_pixel_aspect_ratio(display, &par_n, &par_d); gst_vaapi_display_get_pixel_aspect_ratio (display, &par_n, &par_d);
g_print("Pixel aspect ratio: %u/%u\n", par_n, par_d); g_print ("Pixel aspect ratio: %u/%u\n", par_n, par_d);
dump_info(display); dump_info (display);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
} }
g_print("\n"); g_print ("\n");
#endif #endif
gst_deinit(); gst_deinit ();
return 0; return 0;
} }

View file

@ -38,419 +38,418 @@ static gchar *g_deinterlace_str;
static gchar *g_deinterlace_flags_str; static gchar *g_deinterlace_flags_str;
static GOptionEntry g_options[] = { static GOptionEntry g_options[] = {
{ "src-format", 's', {"src-format", 's',
0, 0,
G_OPTION_ARG_STRING, &g_src_format_str, G_OPTION_ARG_STRING, &g_src_format_str,
"source surface format", NULL }, "source surface format", NULL},
{ "crop-rect", 'c', {"crop-rect", 'c',
0, 0,
G_OPTION_ARG_STRING, &g_crop_rect_str, G_OPTION_ARG_STRING, &g_crop_rect_str,
"cropping rectangle", NULL }, "cropping rectangle", NULL},
{ "denoise", 0, {"denoise", 0,
0, 0,
G_OPTION_ARG_STRING, &g_denoise_str, G_OPTION_ARG_STRING, &g_denoise_str,
"set noise reduction level", NULL }, "set noise reduction level", NULL},
{ "sharpen", 0, {"sharpen", 0,
0, 0,
G_OPTION_ARG_STRING, &g_sharpen_str, G_OPTION_ARG_STRING, &g_sharpen_str,
"set sharpening level", NULL }, "set sharpening level", NULL},
{ "deinterlace", 0, {"deinterlace", 0,
0, 0,
G_OPTION_ARG_STRING, &g_deinterlace_str, G_OPTION_ARG_STRING, &g_deinterlace_str,
"enable deinterlacing", NULL }, "enable deinterlacing", NULL},
{ "deinterlace-flags", 0, {"deinterlace-flags", 0,
0, 0,
G_OPTION_ARG_STRING, &g_deinterlace_flags_str, G_OPTION_ARG_STRING, &g_deinterlace_flags_str,
"deinterlacing flags", NULL }, "deinterlacing flags", NULL},
{ NULL, } {NULL,}
}; };
#define APP_ERROR app_error_quark() #define APP_ERROR app_error_quark()
static GQuark static GQuark
app_error_quark(void) app_error_quark (void)
{ {
static gsize g_quark; static gsize g_quark;
if (g_once_init_enter(&g_quark)) { if (g_once_init_enter (&g_quark)) {
gsize quark = (gsize)g_quark_from_static_string("AppError"); gsize quark = (gsize) g_quark_from_static_string ("AppError");
g_once_init_leave(&g_quark, quark); g_once_init_leave (&g_quark, quark);
} }
return g_quark; return g_quark;
} }
typedef enum { typedef enum
APP_ERROR_NONE, {
APP_ERROR_CREATE_TEST_SURFACE, APP_ERROR_NONE,
APP_ERROR_CREATE_TEST_SURFACE,
} AppError; } AppError;
static inline void static inline void
pause(void) pause (void)
{ {
g_print("Press any key to continue...\n"); g_print ("Press any key to continue...\n");
getchar(); getchar ();
} }
static GstVaapiSurface * static GstVaapiSurface *
create_test_surface(GstVaapiDisplay *display, guint width, guint height, create_test_surface (GstVaapiDisplay * display, guint width, guint height,
guint flags, GError **error_ptr) guint flags, GError ** error_ptr)
{ {
GstVideoFormat format = GST_VIDEO_FORMAT_I420; GstVideoFormat format = GST_VIDEO_FORMAT_I420;
GstVaapiSurface *surface = NULL; GstVaapiSurface *surface = NULL;
GstVaapiImage *image = NULL; GstVaapiImage *image = NULL;
GError *error = NULL; GError *error = NULL;
if (g_src_format_str) { if (g_src_format_str) {
format = gst_video_format_from_string(g_src_format_str); format = gst_video_format_from_string (g_src_format_str);
if (format == GST_VIDEO_FORMAT_UNKNOWN) if (format == GST_VIDEO_FORMAT_UNKNOWN)
goto error_invalid_format; goto error_invalid_format;
} }
surface = gst_vaapi_surface_new_with_format(display, format, width, height); surface = gst_vaapi_surface_new_with_format (display, format, width, height);
if (!surface) if (!surface)
goto error_create_surface; goto error_create_surface;
image = image_generate_full(display, format, width, height, flags); image = image_generate_full (display, format, width, height, flags);
if (!image) if (!image)
goto error_create_image; goto error_create_image;
if (!image_upload(image, surface)) if (!image_upload (image, surface))
goto error_upload_image; goto error_upload_image;
gst_vaapi_object_unref(image); gst_vaapi_object_unref (image);
return surface; return surface;
/* ERRORS */ /* ERRORS */
error_invalid_format: error_invalid_format:
error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, error = g_error_new (APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE,
"unknown format %s", g_src_format_str); "unknown format %s", g_src_format_str);
goto error_cleanup; goto error_cleanup;
error_create_surface: error_create_surface:
error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, error = g_error_new (APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE,
"unsupported format %s", gst_vaapi_video_format_to_string(format)); "unsupported format %s", gst_vaapi_video_format_to_string (format));
goto error_cleanup; goto error_cleanup;
error_create_image: error_create_image:
error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, error = g_error_new (APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE,
"unsupported %s image", gst_vaapi_video_format_to_string(format)); "unsupported %s image", gst_vaapi_video_format_to_string (format));
goto error_cleanup; goto error_cleanup;
error_upload_image: error_upload_image:
error = g_error_new(APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE, error = g_error_new (APP_ERROR, APP_ERROR_CREATE_TEST_SURFACE,
"failed to upload %s image", gst_vaapi_video_format_to_string(format)); "failed to upload %s image", gst_vaapi_video_format_to_string (format));
goto error_cleanup; goto error_cleanup;
error_cleanup: error_cleanup:
if (image) if (image)
gst_vaapi_object_unref(image); gst_vaapi_object_unref (image);
if (surface) if (surface)
gst_vaapi_object_unref(surface); gst_vaapi_object_unref (surface);
if (error_ptr) if (error_ptr)
*error_ptr = error; *error_ptr = error;
else else
g_error_free(error); g_error_free (error);
return NULL; return NULL;
} }
static void static void
dump_operation(GstVaapiFilterOpInfo *op_info) dump_operation (GstVaapiFilterOpInfo * op_info)
{ {
GParamSpec * const pspec = op_info->pspec; GParamSpec *const pspec = op_info->pspec;
GValue value = G_VALUE_INIT; GValue value = G_VALUE_INIT;
gchar *value_str; gchar *value_str;
if (!op_info) if (!op_info)
return; return;
g_print(" %s: ", g_param_spec_get_name(pspec)); g_print (" %s: ", g_param_spec_get_name (pspec));
g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec)); g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
g_param_value_set_default(pspec, &value); g_param_value_set_default (pspec, &value);
value_str = g_strdup_value_contents(&value); value_str = g_strdup_value_contents (&value);
g_print("%s (default: %s)\n", G_VALUE_TYPE_NAME(&value), g_print ("%s (default: %s)\n", G_VALUE_TYPE_NAME (&value),
value_str ? value_str : "<unknown>"); value_str ? value_str : "<unknown>");
g_free(value_str); g_free (value_str);
} }
static void static void
dump_operations(GstVaapiFilter *filter) dump_operations (GstVaapiFilter * filter)
{ {
GPtrArray * const ops = gst_vaapi_filter_get_operations(filter); GPtrArray *const ops = gst_vaapi_filter_get_operations (filter);
guint i; guint i;
if (!ops) if (!ops)
return; return;
g_print("%u operations\n", ops->len); g_print ("%u operations\n", ops->len);
for (i = 0; i < ops->len; i++) for (i = 0; i < ops->len; i++)
dump_operation(g_ptr_array_index(ops, i)); dump_operation (g_ptr_array_index (ops, i));
g_ptr_array_unref(ops); g_ptr_array_unref (ops);
} }
static void static void
dump_formats(GstVaapiFilter *filter) dump_formats (GstVaapiFilter * filter)
{ {
GArray * const formats = gst_vaapi_filter_get_formats(filter); GArray *const formats = gst_vaapi_filter_get_formats (filter);
guint i; guint i;
if (!formats) if (!formats)
return; return;
g_print("%u formats\n", formats->len); g_print ("%u formats\n", formats->len);
for (i = 0; i < formats->len; i++) { for (i = 0; i < formats->len; i++) {
GstVideoFormat format = g_array_index(formats, GstVideoFormat, i); GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
g_print(" %s\n", gst_vaapi_video_format_to_string(format)); g_print (" %s\n", gst_vaapi_video_format_to_string (format));
} }
g_array_unref(formats); g_array_unref (formats);
} }
static gboolean static gboolean
parse_double(const gchar *str, gdouble *out_value_ptr) parse_double (const gchar * str, gdouble * out_value_ptr)
{ {
gchar *endptr = NULL; gchar *endptr = NULL;
gdouble out_value; gdouble out_value;
g_return_val_if_fail(out_value_ptr != NULL, FALSE); g_return_val_if_fail (out_value_ptr != NULL, FALSE);
errno = 0; errno = 0;
out_value = g_ascii_strtod(str, &endptr); out_value = g_ascii_strtod (str, &endptr);
if (!endptr || *endptr != '\0' || errno == ERANGE) if (!endptr || *endptr != '\0' || errno == ERANGE)
return FALSE;
*out_value_ptr = out_value;
return TRUE;
}
static gboolean
parse_crop_rect(const gchar *str, GstVaapiRectangle *crop_rect)
{
if (str) {
// Format: <WIDTH> 'x' <HEIGHT>
if (sscanf(str, "%ux%u", &crop_rect->width, &crop_rect->height) == 2) {
crop_rect->x = 0;
crop_rect->y = 0;
return TRUE;
}
// Format: '('? <X> ',' <Y> ')'? <WIDTH> 'x' <HEIGHT>
if (sscanf(str, "(%d,%d):%ux%u", &crop_rect->x, &crop_rect->y,
&crop_rect->width, &crop_rect->height) == 4 ||
sscanf(str, "%d,%d:%ux%u", &crop_rect->x, &crop_rect->y,
&crop_rect->width, &crop_rect->height) == 4)
return TRUE;
}
return FALSE; return FALSE;
*out_value_ptr = out_value;
return TRUE;
} }
static gboolean static gboolean
parse_enum(const gchar *str, GType type, gint default_value, parse_crop_rect (const gchar * str, GstVaapiRectangle * crop_rect)
gint *out_value_ptr)
{ {
gint out_value = default_value; if (str) {
// Format: <WIDTH> 'x' <HEIGHT>
g_return_val_if_fail(out_value_ptr != NULL, FALSE); if (sscanf (str, "%ux%u", &crop_rect->width, &crop_rect->height) == 2) {
crop_rect->x = 0;
if (str) { crop_rect->y = 0;
const GEnumValue *enum_value; return TRUE;
GEnumClass * const enum_class = g_type_class_ref(type);
if (!enum_class)
return FALSE;
enum_value = g_enum_get_value_by_nick(enum_class, str);
if (enum_value)
out_value = enum_value->value;
g_type_class_unref(enum_class);
if (!enum_value)
return FALSE;
} }
*out_value_ptr = out_value; // Format: '('? <X> ',' <Y> ')'? <WIDTH> 'x' <HEIGHT>
return TRUE; if (sscanf (str, "(%d,%d):%ux%u", &crop_rect->x, &crop_rect->y,
&crop_rect->width, &crop_rect->height) == 4 ||
sscanf (str, "%d,%d:%ux%u", &crop_rect->x, &crop_rect->y,
&crop_rect->width, &crop_rect->height) == 4)
return TRUE;
}
return FALSE;
} }
static gboolean static gboolean
parse_flags(const gchar *str, GType type, guint *out_value_ptr) parse_enum (const gchar * str, GType type, gint default_value,
gint * out_value_ptr)
{ {
gchar **tokens = NULL; gint out_value = default_value;
gint i, value, out_value = 0;
gboolean success = FALSE;
g_return_val_if_fail(out_value_ptr != NULL, FALSE); g_return_val_if_fail (out_value_ptr != NULL, FALSE);
if (str) { if (str) {
tokens = g_strsplit(str, ",", 32); const GEnumValue *enum_value;
if (!tokens) GEnumClass *const enum_class = g_type_class_ref (type);
return FALSE;
for (i = 0; tokens[i] != NULL; i++) { if (!enum_class)
if (!parse_enum(tokens[i], type, 0, &value)) return FALSE;
goto end;
out_value |= value; enum_value = g_enum_get_value_by_nick (enum_class, str);
} if (enum_value)
out_value = enum_value->value;
g_type_class_unref (enum_class);
if (!enum_value)
return FALSE;
}
*out_value_ptr = out_value;
return TRUE;
}
static gboolean
parse_flags (const gchar * str, GType type, guint * out_value_ptr)
{
gchar **tokens = NULL;
gint i, value, out_value = 0;
gboolean success = FALSE;
g_return_val_if_fail (out_value_ptr != NULL, FALSE);
if (str) {
tokens = g_strsplit (str, ",", 32);
if (!tokens)
return FALSE;
for (i = 0; tokens[i] != NULL; i++) {
if (!parse_enum (tokens[i], type, 0, &value))
goto end;
out_value |= value;
} }
*out_value_ptr = out_value; }
success = TRUE; *out_value_ptr = out_value;
success = TRUE;
end: end:
g_strfreev(tokens); g_strfreev (tokens);
return success; return success;
} }
static inline gboolean static inline gboolean
parse_deinterlace(const gchar *str, GstVaapiDeinterlaceMethod *deinterlace_ptr) parse_deinterlace (const gchar * str,
GstVaapiDeinterlaceMethod * deinterlace_ptr)
{ {
g_return_val_if_fail(deinterlace_ptr != NULL, FALSE); g_return_val_if_fail (deinterlace_ptr != NULL, FALSE);
if (!str) { if (!str) {
*deinterlace_ptr = GST_VAAPI_DEINTERLACE_METHOD_NONE; *deinterlace_ptr = GST_VAAPI_DEINTERLACE_METHOD_NONE;
return TRUE; return TRUE;
} }
return parse_enum(str, GST_VAAPI_TYPE_DEINTERLACE_METHOD, return parse_enum (str, GST_VAAPI_TYPE_DEINTERLACE_METHOD,
GST_VAAPI_DEINTERLACE_METHOD_NONE, (gint *)deinterlace_ptr); GST_VAAPI_DEINTERLACE_METHOD_NONE, (gint *) deinterlace_ptr);
} }
static inline gboolean static inline gboolean
parse_deinterlace_flags(const gchar *str, guint *deinterlace_flags_ptr) parse_deinterlace_flags (const gchar * str, guint * deinterlace_flags_ptr)
{ {
return parse_flags(str, GST_VAAPI_TYPE_DEINTERLACE_FLAGS, return parse_flags (str, GST_VAAPI_TYPE_DEINTERLACE_FLAGS,
deinterlace_flags_ptr); deinterlace_flags_ptr);
} }
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiWindow *window; GstVaapiWindow *window;
GstVaapiSurface *src_surface, *dst_surface; GstVaapiSurface *src_surface, *dst_surface;
GstVaapiFilter *filter = NULL; GstVaapiFilter *filter = NULL;
GstVaapiFilterStatus status; GstVaapiFilterStatus status;
GstVaapiDeinterlaceMethod deinterlace_method; GstVaapiDeinterlaceMethod deinterlace_method;
guint deinterlace_flags = 0; guint deinterlace_flags = 0;
guint filter_flags = 0; guint filter_flags = 0;
guint surface_flags = 0; guint surface_flags = 0;
gdouble denoise_level, sharpen_level; gdouble denoise_level, sharpen_level;
GError *error = NULL; GError *error = NULL;
static const guint src_width = 320; static const guint src_width = 320;
static const guint src_height = 240; static const guint src_height = 240;
static const guint dst_width = 480; static const guint dst_width = 480;
static const guint dst_height = 360; static const guint dst_height = 360;
static const guint win_width = 640; static const guint win_width = 640;
static const guint win_height = 480; static const guint win_height = 480;
if (!video_output_init(&argc, argv, g_options)) if (!video_output_init (&argc, argv, g_options))
g_error("failed to initialize video output subsystem"); g_error ("failed to initialize video output subsystem");
if (g_denoise_str && !parse_double(g_denoise_str, &denoise_level)) if (g_denoise_str && !parse_double (g_denoise_str, &denoise_level))
g_error("failed to parse noise reduction level"); g_error ("failed to parse noise reduction level");
if (g_sharpen_str && !parse_double(g_sharpen_str, &sharpen_level)) if (g_sharpen_str && !parse_double (g_sharpen_str, &sharpen_level))
g_error("failed to parse sharpening level"); g_error ("failed to parse sharpening level");
if (!parse_deinterlace(g_deinterlace_str, &deinterlace_method)) if (!parse_deinterlace (g_deinterlace_str, &deinterlace_method))
g_error("failed to parse deinterlace method `%s'", g_deinterlace_str); g_error ("failed to parse deinterlace method `%s'", g_deinterlace_str);
if (!parse_deinterlace_flags(g_deinterlace_flags_str, &deinterlace_flags)) if (!parse_deinterlace_flags (g_deinterlace_flags_str, &deinterlace_flags))
g_error("failed to parse deinterlace flags `%s'", g_error ("failed to parse deinterlace flags `%s'", g_deinterlace_flags_str);
g_deinterlace_flags_str);
display = video_output_create_display(NULL); display = video_output_create_display (NULL);
if (!display) if (!display)
g_error("failed to create VA display"); g_error ("failed to create VA display");
window = video_output_create_window(display, win_width, win_height); window = video_output_create_window (display, win_width, win_height);
if (!window) if (!window)
g_error("failed to create window"); g_error ("failed to create window");
filter = gst_vaapi_filter_new(display); filter = gst_vaapi_filter_new (display);
if (!filter) if (!filter)
g_error("failed to create video processing pipeline"); g_error ("failed to create video processing pipeline");
dump_operations(filter); dump_operations (filter);
dump_formats(filter); dump_formats (filter);
if (g_crop_rect_str) { if (g_crop_rect_str) {
GstVaapiRectangle crop_rect; GstVaapiRectangle crop_rect;
if (!parse_crop_rect(g_crop_rect_str, &crop_rect)) if (!parse_crop_rect (g_crop_rect_str, &crop_rect))
g_error("failed to parse cropping rectangle"); g_error ("failed to parse cropping rectangle");
printf("Frame cropping: (%d,%d), size %ux%u\n", printf ("Frame cropping: (%d,%d), size %ux%u\n",
crop_rect.x, crop_rect.y, crop_rect.width, crop_rect.height); crop_rect.x, crop_rect.y, crop_rect.width, crop_rect.height);
if (!gst_vaapi_filter_set_cropping_rectangle(filter, &crop_rect)) if (!gst_vaapi_filter_set_cropping_rectangle (filter, &crop_rect))
g_error("failed to set cropping rectangle"); g_error ("failed to set cropping rectangle");
} }
if (g_denoise_str) { if (g_denoise_str) {
printf("Noise reduction level: %f\n", denoise_level); printf ("Noise reduction level: %f\n", denoise_level);
if (!gst_vaapi_filter_set_denoising_level(filter, denoise_level)) if (!gst_vaapi_filter_set_denoising_level (filter, denoise_level))
g_error("failed to set denoising level"); g_error ("failed to set denoising level");
} }
if (g_sharpen_str) { if (g_sharpen_str) {
printf("Sharpening level: %f\n", sharpen_level); printf ("Sharpening level: %f\n", sharpen_level);
if (!gst_vaapi_filter_set_sharpening_level(filter, sharpen_level)) if (!gst_vaapi_filter_set_sharpening_level (filter, sharpen_level))
g_error("failed to set sharpening level"); g_error ("failed to set sharpening level");
} }
if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE) { if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE) {
printf("Enable deinterlacing: %s\n", g_deinterlace_str); printf ("Enable deinterlacing: %s\n", g_deinterlace_str);
if (!gst_vaapi_filter_set_deinterlacing(filter, deinterlace_method, if (!gst_vaapi_filter_set_deinterlacing (filter, deinterlace_method,
deinterlace_flags)) deinterlace_flags))
g_error("failed to set deinterlacing method"); g_error ("failed to set deinterlacing method");
} } else if (deinterlace_flags) {
else if (deinterlace_flags) { if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD)
if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD) filter_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
filter_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; else
else filter_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
filter_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; }
}
if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE || if (deinterlace_method != GST_VAAPI_DEINTERLACE_METHOD_NONE ||
deinterlace_flags) { deinterlace_flags) {
if (!(deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD)) if (!(deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD))
surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD | surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD |
GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
else if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD) else if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD)
surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD; surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
else else
surface_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; surface_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
} }
src_surface = create_test_surface(display, src_width, src_height, src_surface = create_test_surface (display, src_width, src_height,
surface_flags, &error); surface_flags, &error);
if (!src_surface) if (!src_surface)
g_error("failed to create source VA surface: %s", error->message); g_error ("failed to create source VA surface: %s", error->message);
dst_surface = gst_vaapi_surface_new(display, GST_VAAPI_CHROMA_TYPE_YUV420, dst_surface = gst_vaapi_surface_new (display, GST_VAAPI_CHROMA_TYPE_YUV420,
dst_width, dst_height); dst_width, dst_height);
if (!dst_surface) if (!dst_surface)
g_error("failed to create target VA surface"); g_error ("failed to create target VA surface");
status = gst_vaapi_filter_process(filter, src_surface, dst_surface, status = gst_vaapi_filter_process (filter, src_surface, dst_surface,
filter_flags); filter_flags);
if (status != GST_VAAPI_FILTER_STATUS_SUCCESS) if (status != GST_VAAPI_FILTER_STATUS_SUCCESS)
g_error("failed to process video filters"); g_error ("failed to process video filters");
gst_vaapi_window_show(window); gst_vaapi_window_show (window);
if (!gst_vaapi_window_put_surface(window, dst_surface, NULL, NULL, if (!gst_vaapi_window_put_surface (window, dst_surface, NULL, NULL,
GST_VAAPI_PICTURE_STRUCTURE_FRAME)) GST_VAAPI_PICTURE_STRUCTURE_FRAME))
g_error("failed to render target surface"); g_error ("failed to render target surface");
pause(); pause ();
gst_vaapi_filter_unref(filter); gst_vaapi_filter_unref (filter);
gst_vaapi_object_unref(dst_surface); gst_vaapi_object_unref (dst_surface);
gst_vaapi_object_unref(src_surface); gst_vaapi_object_unref (src_surface);
gst_vaapi_window_unref(window); gst_vaapi_window_unref (window);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
video_output_exit(); video_output_exit ();
g_free(g_src_format_str); g_free (g_src_format_str);
g_free(g_crop_rect_str); g_free (g_crop_rect_str);
g_free(g_denoise_str); g_free (g_denoise_str);
g_free(g_sharpen_str); g_free (g_sharpen_str);
g_free(g_deinterlace_str); g_free (g_deinterlace_str);
g_free(g_deinterlace_flags_str); g_free (g_deinterlace_flags_str);
return 0; return 0;
} }

File diff suppressed because it is too large Load diff

View file

@ -2071,11 +2071,12 @@ static const guchar jpeg_clip[JPEG_CLIP_DATA_SIZE] = {
0xd9 0xd9
}; };
void jpeg_get_video_info(VideoDecodeInfo *info) void
jpeg_get_video_info (VideoDecodeInfo * info)
{ {
info->profile = GST_VAAPI_PROFILE_JPEG_BASELINE; info->profile = GST_VAAPI_PROFILE_JPEG_BASELINE;
info->width = JPEG_CLIP_WIDTH; info->width = JPEG_CLIP_WIDTH;
info->height = JPEG_CLIP_HEIGHT; info->height = JPEG_CLIP_HEIGHT;
info->data = jpeg_clip; info->data = jpeg_clip;
info->data_size = JPEG_CLIP_DATA_SIZE; info->data_size = JPEG_CLIP_DATA_SIZE;
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1421,7 +1421,8 @@ static const guint32 text[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000 0x00000000, 0x00000000, 0x00000000, 0x00000000
}; };
void subpicture_get_info(VideoSubpictureInfo *info) void
subpicture_get_info (VideoSubpictureInfo * info)
{ {
info->width = SUBPICTURE_WIDTH; info->width = SUBPICTURE_WIDTH;
info->height = SUBPICTURE_HEIGHT; info->height = SUBPICTURE_HEIGHT;

View file

@ -27,146 +27,147 @@
#include "output.h" #include "output.h"
#include "test-subpicture-data.h" #include "test-subpicture-data.h"
static inline void pause(void) static inline void
pause (void)
{ {
g_print("Press any key to continue...\n"); g_print ("Press any key to continue...\n");
getchar(); getchar ();
} }
static gchar *g_codec_str; static gchar *g_codec_str;
static gdouble g_global_alpha = 1.0; static gdouble g_global_alpha = 1.0;
static GOptionEntry g_options[] = { static GOptionEntry g_options[] = {
{ "codec", 'c', {"codec", 'c',
0, 0,
G_OPTION_ARG_STRING, &g_codec_str, G_OPTION_ARG_STRING, &g_codec_str,
"codec to test", NULL }, "codec to test", NULL},
{ "global-alpha", 'g', {"global-alpha", 'g',
0, 0,
G_OPTION_ARG_DOUBLE, &g_global_alpha, G_OPTION_ARG_DOUBLE, &g_global_alpha,
"global-alpha value", NULL }, "global-alpha value", NULL},
{ NULL, } {NULL,}
}; };
static void static void
upload_subpicture(GstBuffer *buffer, const VideoSubpictureInfo *subinfo) upload_subpicture (GstBuffer * buffer, const VideoSubpictureInfo * subinfo)
{ {
const guint32 * const src = subinfo->data; const guint32 *const src = subinfo->data;
guint i, len = subinfo->data_size / 4; guint i, len = subinfo->data_size / 4;
GstMapInfo map_info; GstMapInfo map_info;
guint32 *dst; guint32 *dst;
if (!gst_buffer_map(buffer, &map_info, GST_MAP_WRITE)) if (!gst_buffer_map (buffer, &map_info, GST_MAP_WRITE))
return; return;
dst = (guint32 *)map_info.data; dst = (guint32 *) map_info.data;
/* Convert from RGBA source to ARGB */ /* Convert from RGBA source to ARGB */
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
const guint32 rgba = src[i]; const guint32 rgba = src[i];
dst[i] = (rgba >> 8) | (rgba << 24); dst[i] = (rgba >> 8) | (rgba << 24);
} }
gst_buffer_unmap(buffer, &map_info); gst_buffer_unmap (buffer, &map_info);
} }
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiWindow *window; GstVaapiWindow *window;
GstVaapiDecoder *decoder; GstVaapiDecoder *decoder;
GstVaapiSurfaceProxy *proxy; GstVaapiSurfaceProxy *proxy;
GstVaapiSurface *surface; GstVaapiSurface *surface;
GstBuffer *buffer; GstBuffer *buffer;
VideoSubpictureInfo subinfo; VideoSubpictureInfo subinfo;
GstVaapiRectangle subrect; GstVaapiRectangle subrect;
GstVideoOverlayRectangle *overlay; GstVideoOverlayRectangle *overlay;
GstVideoOverlayComposition *compo; GstVideoOverlayComposition *compo;
guint flags = 0; guint flags = 0;
static const guint win_width = 640; static const guint win_width = 640;
static const guint win_height = 480; static const guint win_height = 480;
if (!video_output_init(&argc, argv, g_options)) if (!video_output_init (&argc, argv, g_options))
g_error("failed to initialize video output subsystem"); g_error ("failed to initialize video output subsystem");
if (g_global_alpha != 1.0) if (g_global_alpha != 1.0)
flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA; flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA;
g_print("Test subpicture\n"); g_print ("Test subpicture\n");
display = video_output_create_display(NULL); display = video_output_create_display (NULL);
if (!display) if (!display)
g_error("could not create VA display"); g_error ("could not create VA display");
window = video_output_create_window(display, win_width, win_height); window = video_output_create_window (display, win_width, win_height);
if (!window) if (!window)
g_error("could not create window"); g_error ("could not create window");
decoder = decoder_new(display, g_codec_str); decoder = decoder_new (display, g_codec_str);
if (!decoder) if (!decoder)
g_error("could not create decoder"); g_error ("could not create decoder");
if (!decoder_put_buffers(decoder)) if (!decoder_put_buffers (decoder))
g_error("could not fill decoder with sample data"); g_error ("could not fill decoder with sample data");
proxy = decoder_get_surface(decoder); proxy = decoder_get_surface (decoder);
if (!proxy) if (!proxy)
g_error("could not get decoded surface"); g_error ("could not get decoded surface");
surface = gst_vaapi_surface_proxy_get_surface(proxy); surface = gst_vaapi_surface_proxy_get_surface (proxy);
subpicture_get_info(&subinfo); subpicture_get_info (&subinfo);
buffer = gst_buffer_new_and_alloc(subinfo.data_size); buffer = gst_buffer_new_and_alloc (subinfo.data_size);
upload_subpicture(buffer, &subinfo); upload_subpicture (buffer, &subinfo);
/* We position the subpicture at the bottom center */ /* We position the subpicture at the bottom center */
subrect.x = (gst_vaapi_surface_get_width(surface) - subinfo.width) / 2; subrect.x = (gst_vaapi_surface_get_width (surface) - subinfo.width) / 2;
subrect.y = gst_vaapi_surface_get_height(surface) - subinfo.height - 10; subrect.y = gst_vaapi_surface_get_height (surface) - subinfo.height - 10;
subrect.height = subinfo.height; subrect.height = subinfo.height;
subrect.width = subinfo.width; subrect.width = subinfo.width;
{ {
GstVideoMeta * const vmeta = GstVideoMeta *const vmeta =
gst_buffer_add_video_meta(buffer, GST_VIDEO_FRAME_FLAG_NONE, gst_buffer_add_video_meta (buffer, GST_VIDEO_FRAME_FLAG_NONE,
GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB, GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB,
subinfo.width, subinfo.height); subinfo.width, subinfo.height);
if (!vmeta) if (!vmeta)
g_error("could not create video meta"); g_error ("could not create video meta");
overlay = gst_video_overlay_rectangle_new_raw(buffer, overlay = gst_video_overlay_rectangle_new_raw (buffer,
subrect.x, subrect.y, subrect.width, subrect.height, flags); subrect.x, subrect.y, subrect.width, subrect.height, flags);
} }
if (!overlay) if (!overlay)
g_error("could not create video overlay"); g_error ("could not create video overlay");
gst_buffer_unref(buffer); gst_buffer_unref (buffer);
if (flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA) if (flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA)
gst_video_overlay_rectangle_set_global_alpha(overlay, g_global_alpha); gst_video_overlay_rectangle_set_global_alpha (overlay, g_global_alpha);
compo = gst_video_overlay_composition_new(overlay); compo = gst_video_overlay_composition_new (overlay);
if (!compo) if (!compo)
g_error("could not create video overlay composition"); g_error ("could not create video overlay composition");
gst_video_overlay_rectangle_unref(overlay); gst_video_overlay_rectangle_unref (overlay);
if (!gst_vaapi_surface_set_subpictures_from_composition(surface, compo, if (!gst_vaapi_surface_set_subpictures_from_composition (surface, compo,
FALSE)) FALSE))
g_error("could not create subpictures from video overlay compoition"); g_error ("could not create subpictures from video overlay compoition");
gst_vaapi_window_show(window); gst_vaapi_window_show (window);
if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL,
GST_VAAPI_PICTURE_STRUCTURE_FRAME)) GST_VAAPI_PICTURE_STRUCTURE_FRAME))
g_error("could not render surface"); g_error ("could not render surface");
pause(); pause ();
gst_video_overlay_composition_unref(compo); gst_video_overlay_composition_unref (compo);
gst_vaapi_surface_proxy_unref(proxy); gst_vaapi_surface_proxy_unref (proxy);
gst_vaapi_decoder_unref(decoder); gst_vaapi_decoder_unref (decoder);
gst_vaapi_window_unref(window); gst_vaapi_window_unref (window);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
g_free(g_codec_str); g_free (g_codec_str);
video_output_exit(); video_output_exit ();
return 0; return 0;
} }

View file

@ -29,78 +29,78 @@
#define MAX_SURFACES 4 #define MAX_SURFACES 4
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiSurface *surface; GstVaapiSurface *surface;
GstVaapiID surface_id; GstVaapiID surface_id;
GstVaapiSurface *surfaces[MAX_SURFACES]; GstVaapiSurface *surfaces[MAX_SURFACES];
GstVaapiVideoPool *pool; GstVaapiVideoPool *pool;
gint i; gint i;
static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
static const guint width = 320; static const guint width = 320;
static const guint height = 240; static const guint height = 240;
if (!video_output_init(&argc, argv, NULL)) if (!video_output_init (&argc, argv, NULL))
g_error("failed to initialize video output subsystem"); g_error ("failed to initialize video output subsystem");
display = video_output_create_display(NULL); display = video_output_create_display (NULL);
if (!display) if (!display)
g_error("could not create Gst/VA display"); g_error ("could not create Gst/VA display");
surface = gst_vaapi_surface_new(display, chroma_type, width, height); surface = gst_vaapi_surface_new (display, chroma_type, width, height);
if (!surface)
g_error ("could not create Gst/VA surface");
surface_id = gst_vaapi_surface_get_id (surface);
g_print ("created surface %" GST_VAAPI_ID_FORMAT "\n",
GST_VAAPI_ID_ARGS (surface_id));
gst_vaapi_object_unref (surface);
pool = gst_vaapi_surface_pool_new (display, GST_VIDEO_FORMAT_ENCODED,
width, height);
if (!pool)
g_error ("could not create Gst/VA surface pool");
for (i = 0; i < MAX_SURFACES; i++) {
surface = gst_vaapi_video_pool_get_object (pool);
if (!surface) if (!surface)
g_error("could not create Gst/VA surface"); g_error ("could not allocate Gst/VA surface from pool");
g_print ("created surface %" GST_VAAPI_ID_FORMAT " from pool\n",
GST_VAAPI_ID_ARGS (gst_vaapi_surface_get_id (surface)));
surfaces[i] = surface;
}
surface_id = gst_vaapi_surface_get_id(surface); /* Check the pool doesn't return the last free'd surface */
g_print("created surface %" GST_VAAPI_ID_FORMAT "\n", surface = gst_vaapi_object_ref (surfaces[1]);
GST_VAAPI_ID_ARGS(surface_id));
gst_vaapi_object_unref(surface); for (i = 0; i < 2; i++)
gst_vaapi_video_pool_put_object (pool, surfaces[i]);
pool = gst_vaapi_surface_pool_new(display, GST_VIDEO_FORMAT_ENCODED, for (i = 0; i < 2; i++) {
width, height); surfaces[i] = gst_vaapi_video_pool_get_object (pool);
if (!pool) if (!surfaces[i])
g_error("could not create Gst/VA surface pool"); g_error ("could not re-allocate Gst/VA surface%d from pool", i);
g_print ("created surface %" GST_VAAPI_ID_FORMAT " from pool (realloc)\n",
GST_VAAPI_ID_ARGS (gst_vaapi_surface_get_id (surfaces[i])));
}
for (i = 0; i < MAX_SURFACES; i++) { if (surface == surfaces[0])
surface = gst_vaapi_video_pool_get_object(pool); g_error ("Gst/VA pool doesn't queue free surfaces");
if (!surface)
g_error("could not allocate Gst/VA surface from pool");
g_print("created surface %" GST_VAAPI_ID_FORMAT " from pool\n",
GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surface)));
surfaces[i] = surface;
}
/* Check the pool doesn't return the last free'd surface */ for (i = MAX_SURFACES - 1; i >= 0; i--) {
surface = gst_vaapi_object_ref(surfaces[1]); if (!surfaces[i])
continue;
gst_vaapi_video_pool_put_object (pool, surfaces[i]);
surfaces[i] = NULL;
}
for (i = 0; i < 2; i++) /* Unref in random order to check objects are correctly refcounted */
gst_vaapi_video_pool_put_object(pool, surfaces[i]); gst_vaapi_display_unref (display);
gst_vaapi_video_pool_unref (pool);
for (i = 0; i < 2; i++) { gst_vaapi_object_unref (surface);
surfaces[i] = gst_vaapi_video_pool_get_object(pool); video_output_exit ();
if (!surfaces[i]) return 0;
g_error("could not re-allocate Gst/VA surface%d from pool", i);
g_print("created surface %" GST_VAAPI_ID_FORMAT " from pool (realloc)\n",
GST_VAAPI_ID_ARGS(gst_vaapi_surface_get_id(surfaces[i])));
}
if (surface == surfaces[0])
g_error("Gst/VA pool doesn't queue free surfaces");
for (i = MAX_SURFACES - 1; i >= 0; i--) {
if (!surfaces[i])
continue;
gst_vaapi_video_pool_put_object(pool, surfaces[i]);
surfaces[i] = NULL;
}
/* Unref in random order to check objects are correctly refcounted */
gst_vaapi_display_unref(display);
gst_vaapi_video_pool_unref(pool);
gst_vaapi_object_unref(surface);
video_output_exit();
return 0;
} }

View file

@ -28,167 +28,152 @@
#include <gst/vaapi/gstvaapiimage.h> #include <gst/vaapi/gstvaapiimage.h>
#include "image.h" #include "image.h"
static inline void pause(void) static inline void
pause (void)
{ {
g_print("Press any key to continue...\n"); g_print ("Press any key to continue...\n");
getchar(); getchar ();
} }
static inline guint gl_get_current_texture_2d(void) static inline guint
gl_get_current_texture_2d (void)
{ {
GLint texture; GLint texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture); glGetIntegerv (GL_TEXTURE_BINDING_2D, &texture);
return (guint)texture; return (guint) texture;
} }
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiWindow *window; GstVaapiWindow *window;
GstVaapiWindowGLX *glx_window; GstVaapiWindowGLX *glx_window;
GstVaapiSurface *surface; GstVaapiSurface *surface;
GstVaapiImage *image; GstVaapiImage *image;
GstVaapiTexture *textures[2]; GstVaapiTexture *textures[2];
GstVaapiTexture *texture; GstVaapiTexture *texture;
GLuint texture_id; GLuint texture_id;
GstVaapiRectangle src_rect; GstVaapiRectangle src_rect;
GstVaapiRectangle dst_rect; GstVaapiRectangle dst_rect;
guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
static const guint width = 320; static const guint width = 320;
static const guint height = 240; static const guint height = 240;
static const guint win_width = 640; static const guint win_width = 640;
static const guint win_height = 480; static const guint win_height = 480;
gst_init(&argc, &argv); gst_init (&argc, &argv);
display = gst_vaapi_display_glx_new(NULL); display = gst_vaapi_display_glx_new (NULL);
if (!display) if (!display)
g_error("could not create VA display"); g_error ("could not create VA display");
surface = gst_vaapi_surface_new(display, chroma_type, width, height); surface = gst_vaapi_surface_new (display, chroma_type, width, height);
if (!surface) if (!surface)
g_error("could not create VA surface"); g_error ("could not create VA surface");
image = image_generate(display, GST_VIDEO_FORMAT_NV12, width, height); image = image_generate (display, GST_VIDEO_FORMAT_NV12, width, height);
if (!image) if (!image)
g_error("could not create VA image"); g_error ("could not create VA image");
if (!image_upload(image, surface)) if (!image_upload (image, surface))
g_error("could not upload VA image to surface"); g_error ("could not upload VA image to surface");
window = gst_vaapi_window_glx_new(display, win_width, win_height); window = gst_vaapi_window_glx_new (display, win_width, win_height);
if (!window) if (!window)
g_error("could not create window"); g_error ("could not create window");
glx_window = GST_VAAPI_WINDOW_GLX(window); glx_window = GST_VAAPI_WINDOW_GLX (window);
gst_vaapi_window_show(window); gst_vaapi_window_show (window);
if (!gst_vaapi_window_glx_make_current(glx_window)) if (!gst_vaapi_window_glx_make_current (glx_window))
g_error("coult not bind GL context"); g_error ("coult not bind GL context");
g_print("#\n"); g_print ("#\n");
g_print("# Create texture with gst_vaapi_texture_glx_new()\n"); g_print ("# Create texture with gst_vaapi_texture_glx_new()\n");
g_print("#\n"); g_print ("#\n");
{ {
texture = gst_vaapi_texture_glx_new( texture = gst_vaapi_texture_glx_new (display,
display, GL_TEXTURE_2D, GL_RGBA, width, height);
GL_TEXTURE_2D, if (!texture)
GL_RGBA, g_error ("could not create VA texture");
width,
height
);
if (!texture)
g_error("could not create VA texture");
textures[0] = texture; textures[0] = texture;
texture_id = gst_vaapi_texture_get_id(texture); texture_id = gst_vaapi_texture_get_id (texture);
if (!gst_vaapi_texture_put_surface(texture, surface, NULL, flags)) if (!gst_vaapi_texture_put_surface (texture, surface, NULL, flags))
g_error("could not transfer VA surface to texture"); g_error ("could not transfer VA surface to texture");
if (!gst_vaapi_window_glx_put_texture(glx_window, texture, NULL, NULL)) if (!gst_vaapi_window_glx_put_texture (glx_window, texture, NULL, NULL))
g_error("could not render texture into the window"); g_error ("could not render texture into the window");
} }
g_print("#\n"); g_print ("#\n");
g_print("# Create texture with gst_vaapi_texture_glx_new_wrapped()\n"); g_print ("# Create texture with gst_vaapi_texture_glx_new_wrapped()\n");
g_print("#\n"); g_print ("#\n");
{ {
const GLenum target = GL_TEXTURE_2D; const GLenum target = GL_TEXTURE_2D;
const GLenum format = GL_BGRA; const GLenum format = GL_BGRA;
glEnable(target); glEnable (target);
glGenTextures(1, &texture_id); glGenTextures (1, &texture_id);
glBindTexture(target, texture_id); glBindTexture (target, texture_id);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
glTexImage2D( glTexImage2D (target,
target, 0, GL_RGBA8, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
0, glDisable (target);
GL_RGBA8,
width, height,
0,
format,
GL_UNSIGNED_BYTE,
NULL
);
glDisable(target);
texture = gst_vaapi_texture_glx_new_wrapped( texture = gst_vaapi_texture_glx_new_wrapped (display,
display, texture_id, target, format);
texture_id, if (!texture)
target, g_error ("could not create VA texture");
format
);
if (!texture)
g_error("could not create VA texture");
if (texture_id != gst_vaapi_texture_get_id(texture)) if (texture_id != gst_vaapi_texture_get_id (texture))
g_error("invalid texture id"); g_error ("invalid texture id");
if (gl_get_current_texture_2d() != texture_id) if (gl_get_current_texture_2d () != texture_id)
g_error("gst_vaapi_texture_glx_new_wrapped() altered texture bindings"); g_error ("gst_vaapi_texture_glx_new_wrapped() altered texture bindings");
textures[1] = texture; textures[1] = texture;
if (!gst_vaapi_texture_put_surface(texture, surface, NULL, flags)) if (!gst_vaapi_texture_put_surface (texture, surface, NULL, flags))
g_error("could not transfer VA surface to texture"); g_error ("could not transfer VA surface to texture");
if (gl_get_current_texture_2d() != texture_id) if (gl_get_current_texture_2d () != texture_id)
g_error("gst_vaapi_texture_put_surface() altered texture bindings"); g_error ("gst_vaapi_texture_put_surface() altered texture bindings");
src_rect.x = 0; src_rect.x = 0;
src_rect.y = 0; src_rect.y = 0;
src_rect.width = width; src_rect.width = width;
src_rect.height = height; src_rect.height = height;
dst_rect.x = win_width/2; dst_rect.x = win_width / 2;
dst_rect.y = win_height/2; dst_rect.y = win_height / 2;
dst_rect.width = win_width/2; dst_rect.width = win_width / 2;
dst_rect.height = win_height/2; dst_rect.height = win_height / 2;
if (!gst_vaapi_window_glx_put_texture(glx_window, texture, if (!gst_vaapi_window_glx_put_texture (glx_window, texture,
&src_rect, &dst_rect)) &src_rect, &dst_rect))
g_error("could not render texture into the window"); g_error ("could not render texture into the window");
if (gl_get_current_texture_2d() != texture_id) if (gl_get_current_texture_2d () != texture_id)
g_error("gst_vaapi_window_glx_put_texture() altered texture bindings"); g_error ("gst_vaapi_window_glx_put_texture() altered texture bindings");
} }
gst_vaapi_window_glx_swap_buffers(glx_window); gst_vaapi_window_glx_swap_buffers (glx_window);
pause(); pause ();
gst_vaapi_texture_unref(textures[0]); gst_vaapi_texture_unref (textures[0]);
gst_vaapi_texture_unref(textures[1]); gst_vaapi_texture_unref (textures[1]);
glDeleteTextures(1, &texture_id); glDeleteTextures (1, &texture_id);
gst_vaapi_window_unref(window); gst_vaapi_window_unref (window);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
gst_deinit(); gst_deinit ();
return 0; return 0;
} }

File diff suppressed because it is too large Load diff

View file

@ -44,199 +44,195 @@
#include "image.h" #include "image.h"
static inline void static inline void
pause(void) pause (void)
{ {
g_print("Press any key to continue...\n"); g_print ("Press any key to continue...\n");
getchar(); getchar ();
} }
static GstVaapiSurface * static GstVaapiSurface *
create_test_surface(GstVaapiDisplay *display, guint width, guint height) create_test_surface (GstVaapiDisplay * display, guint width, guint height)
{ {
GstVaapiImage *image = NULL; GstVaapiImage *image = NULL;
GstVaapiSurface *surface; GstVaapiSurface *surface;
guint i; guint i;
static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420; static const GstVaapiChromaType chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
static const GstVideoFormat image_formats[] = { static const GstVideoFormat image_formats[] = {
GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_NV12,
GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_YV12,
GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_I420,
GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_AYUV,
GST_VIDEO_FORMAT_ARGB, GST_VIDEO_FORMAT_ARGB,
GST_VIDEO_FORMAT_BGRA, GST_VIDEO_FORMAT_BGRA,
GST_VIDEO_FORMAT_RGBA, GST_VIDEO_FORMAT_RGBA,
GST_VIDEO_FORMAT_ABGR, GST_VIDEO_FORMAT_ABGR,
GST_VIDEO_FORMAT_UNKNOWN GST_VIDEO_FORMAT_UNKNOWN
}; };
surface = gst_vaapi_surface_new(display, chroma_type, width, height); surface = gst_vaapi_surface_new (display, chroma_type, width, height);
if (!surface) if (!surface)
g_error("could not create Gst/VA surface"); g_error ("could not create Gst/VA surface");
for (i = 0; image_formats[i] != GST_VIDEO_FORMAT_UNKNOWN; i++) { for (i = 0; image_formats[i] != GST_VIDEO_FORMAT_UNKNOWN; i++) {
const GstVideoFormat format = image_formats[i]; const GstVideoFormat format = image_formats[i];
image = image_generate(display, format, width, height); image = image_generate (display, format, width, height);
if (!image)
break;
if (image_upload(image, surface))
break;
}
if (!image) if (!image)
g_error("could not create Gst/VA image"); break;
if (image_upload (image, surface))
break;
}
if (!image)
g_error ("could not create Gst/VA image");
if (!gst_vaapi_surface_sync(surface)) if (!gst_vaapi_surface_sync (surface))
g_error("could not complete image upload"); g_error ("could not complete image upload");
gst_vaapi_object_unref(image); gst_vaapi_object_unref (image);
return surface; return surface;
} }
int int
main(int argc, char *argv[]) main (int argc, char *argv[])
{ {
GstVaapiDisplay *display; GstVaapiDisplay *display;
GstVaapiWindow *window; GstVaapiWindow *window;
GstVaapiSurface *surface; GstVaapiSurface *surface;
guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME; guint flags = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
static const guint width = 320; static const guint width = 320;
static const guint height = 240; static const guint height = 240;
static const guint win_width = 640; static const guint win_width = 640;
static const guint win_height = 480; static const guint win_height = 480;
gst_init(&argc, &argv); gst_init (&argc, &argv);
#if USE_DRM #if USE_DRM
display = gst_vaapi_display_drm_new(NULL); display = gst_vaapi_display_drm_new (NULL);
if (!display) if (!display)
g_error("could not create Gst/VA (DRM) display"); g_error ("could not create Gst/VA (DRM) display");
surface = create_test_surface(display, width, height); surface = create_test_surface (display, width, height);
if (!surface) if (!surface)
g_error("could not create Gst/VA surface"); g_error ("could not create Gst/VA surface");
g_print("#\n"); g_print ("#\n");
g_print("# Create window with gst_vaapi_window_drm_new()\n"); g_print ("# Create window with gst_vaapi_window_drm_new()\n");
g_print("#\n"); g_print ("#\n");
{ {
window = gst_vaapi_window_drm_new(display, win_width, win_height); window = gst_vaapi_window_drm_new (display, win_width, win_height);
if (!window) if (!window)
g_error("could not create dummy window"); g_error ("could not create dummy window");
gst_vaapi_window_show(window); gst_vaapi_window_show (window);
if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL, flags))
g_error("could not render surface"); g_error ("could not render surface");
pause(); pause ();
gst_vaapi_window_unref(window); gst_vaapi_window_unref (window);
} }
gst_vaapi_object_unref(surface); gst_vaapi_object_unref (surface);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
#endif #endif
#if USE_X11 #if USE_X11
display = gst_vaapi_display_x11_new(NULL); display = gst_vaapi_display_x11_new (NULL);
if (!display) if (!display)
g_error("could not create Gst/VA display"); g_error ("could not create Gst/VA display");
surface = create_test_surface(display, width, height); surface = create_test_surface (display, width, height);
if (!surface) if (!surface)
g_error("could not create Gst/VA surface"); g_error ("could not create Gst/VA surface");
g_print("#\n"); g_print ("#\n");
g_print("# Create window with gst_vaapi_window_x11_new()\n"); g_print ("# Create window with gst_vaapi_window_x11_new()\n");
g_print("#\n"); g_print ("#\n");
{ {
window = gst_vaapi_window_x11_new(display, win_width, win_height); window = gst_vaapi_window_x11_new (display, win_width, win_height);
if (!window) if (!window)
g_error("could not create window"); g_error ("could not create window");
gst_vaapi_window_show(window); gst_vaapi_window_show (window);
if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL, flags))
g_error("could not render surface"); g_error ("could not render surface");
pause(); pause ();
gst_vaapi_window_unref(window); gst_vaapi_window_unref (window);
} }
g_print("#\n"); g_print ("#\n");
g_print("# Create window with gst_vaapi_window_x11_new_with_xid()\n"); g_print ("# Create window with gst_vaapi_window_x11_new_with_xid()\n");
g_print("#\n"); g_print ("#\n");
{ {
Display * const dpy = gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(display)); Display *const dpy =
Window rootwin, win; gst_vaapi_display_x11_get_display (GST_VAAPI_DISPLAY_X11 (display));
int screen; Window rootwin, win;
unsigned long white_pixel, black_pixel; int screen;
unsigned long white_pixel, black_pixel;
screen = DefaultScreen(dpy); screen = DefaultScreen (dpy);
rootwin = RootWindow(dpy, screen); rootwin = RootWindow (dpy, screen);
white_pixel = WhitePixel(dpy, screen); white_pixel = WhitePixel (dpy, screen);
black_pixel = BlackPixel(dpy, screen); black_pixel = BlackPixel (dpy, screen);
win = XCreateSimpleWindow( win = XCreateSimpleWindow (dpy,
dpy, rootwin, 0, 0, win_width, win_height, 0, black_pixel, white_pixel);
rootwin, if (!win)
0, 0, win_width, win_height, g_error ("could not create X window");
0, black_pixel,
white_pixel
);
if (!win)
g_error("could not create X window");
window = gst_vaapi_window_x11_new_with_xid(display, win); window = gst_vaapi_window_x11_new_with_xid (display, win);
if (!window) if (!window)
g_error("could not create window"); g_error ("could not create window");
gst_vaapi_window_show(window); gst_vaapi_window_show (window);
if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL, flags))
g_error("could not render surface"); g_error ("could not render surface");
pause(); pause ();
gst_vaapi_window_unref(window); gst_vaapi_window_unref (window);
XUnmapWindow(dpy, win); XUnmapWindow (dpy, win);
XDestroyWindow(dpy, win); XDestroyWindow (dpy, win);
} }
gst_vaapi_object_unref(surface); gst_vaapi_object_unref (surface);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
#endif #endif
#if USE_WAYLAND #if USE_WAYLAND
display = gst_vaapi_display_wayland_new(NULL); display = gst_vaapi_display_wayland_new (NULL);
if (!display) if (!display)
g_error("could not create Gst/VA (Wayland) display"); g_error ("could not create Gst/VA (Wayland) display");
surface = create_test_surface(display, width, height); surface = create_test_surface (display, width, height);
if (!surface) if (!surface)
g_error("could not create Gst/VA surface"); g_error ("could not create Gst/VA surface");
g_print("#\n"); g_print ("#\n");
g_print("# Create window with gst_vaapi_window_wayland_new()\n"); g_print ("# Create window with gst_vaapi_window_wayland_new()\n");
g_print("#\n"); g_print ("#\n");
{ {
window = gst_vaapi_window_wayland_new(display, win_width, win_height); window = gst_vaapi_window_wayland_new (display, win_width, win_height);
if (!window) if (!window)
g_error("could not create window"); g_error ("could not create window");
gst_vaapi_window_show(window); gst_vaapi_window_show (window);
if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL, flags)) if (!gst_vaapi_window_put_surface (window, surface, NULL, NULL, flags))
g_error("could not render surface"); g_error ("could not render surface");
pause(); pause ();
gst_vaapi_window_unref(window); gst_vaapi_window_unref (window);
} }
gst_vaapi_object_unref(surface); gst_vaapi_object_unref (surface);
gst_vaapi_display_unref(display); gst_vaapi_display_unref (display);
#endif #endif
gst_deinit(); gst_deinit ();
return 0; return 0;
} }