summaryrefslogtreecommitdiff
path: root/tests/test-subpicture.c
diff options
context:
space:
mode:
authorThibault Saunier <thibault.saunier@collabora.com>2011-10-14 13:00:12 -0300
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2011-12-12 15:08:42 +0100
commitbb72c5555586ef0cf148cb353936f2f28024fd40 (patch)
tree5a1d88d45270c153883aa4aefd7370c740c8882b /tests/test-subpicture.c
parentcbf81d7d51db8acb7d788263578fa58906d9ac92 (diff)
tests: add test for subpictures.
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
Diffstat (limited to 'tests/test-subpicture.c')
-rw-r--r--tests/test-subpicture.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/tests/test-subpicture.c b/tests/test-subpicture.c
new file mode 100644
index 00000000..ee01709c
--- /dev/null
+++ b/tests/test-subpicture.c
@@ -0,0 +1,207 @@
+/*
+ * test-subpicture.c - Test GstVaapiSubpicture
+ *
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <string.h>
+#include <gst/vaapi/gstvaapidisplay_x11.h>
+#include <gst/vaapi/gstvaapiwindow_x11.h>
+#include <gst/vaapi/gstvaapidecoder.h>
+#include <gst/vaapi/gstvaapidecoder_ffmpeg.h>
+#include <gst/vaapi/gstvaapisurface.h>
+#include "test-h264.h"
+#include "test-subpicture-data.h"
+
+typedef void (*GetVideoInfoFunc)(VideoDecodeInfo *info);
+
+typedef struct _CodecDefs CodecDefs;
+struct _CodecDefs {
+ const gchar *codec_str;
+ GetVideoInfoFunc get_video_info;
+};
+
+static const CodecDefs g_codec_defs[] = {
+#define INIT_FUNCS(CODEC) { #CODEC, CODEC##_get_video_info }
+ INIT_FUNCS(h264),
+#undef INIT_FUNCS
+ { NULL, }
+};
+
+static const CodecDefs *
+get_codec_defs(const gchar *codec_str)
+{
+ const CodecDefs *c;
+ for (c = g_codec_defs; c->codec_str; c++)
+ if (strcmp(codec_str, c->codec_str) == 0)
+ return c;
+ return NULL;
+}
+
+static inline void pause(void)
+{
+ g_print("Press any key to continue...\n");
+ getchar();
+}
+
+static gchar *g_codec_str;
+
+static GOptionEntry g_options[] = {
+ { "codec", 'c',
+ 0,
+ G_OPTION_ARG_STRING, &g_codec_str,
+ "codec to test", NULL },
+ { NULL, }
+};
+
+int
+main(int argc, char *argv[])
+{
+ GOptionContext *options;
+ GstVaapiDisplay *display;
+ GstVaapiWindow *window;
+ GstVaapiDecoder *decoder;
+ GstCaps *decoder_caps;
+ GstStructure *structure;
+ GstVaapiDecoderStatus status;
+ const CodecDefs *codec;
+ GstBuffer *buffer;
+ GstVaapiSurfaceProxy *proxy;
+ VideoDecodeInfo info;
+ VideoSubpictureInfo subinfo;
+ GstVaapiImage *subtitle_image;
+ GstVaapiSubpicture *subpicture;
+ GstCaps *argbcaps;
+ GstVaapiRectangle sub_rect;
+
+ static const guint win_width = 640;
+ static const guint win_height = 480;
+
+ gst_init(&argc, &argv);
+
+ options = g_option_context_new(" - test-decode options");
+ g_option_context_add_main_entries(options, g_options, NULL);
+ g_option_context_parse(options, &argc, &argv, NULL);
+ g_option_context_free(options);
+
+ if (!g_codec_str)
+ g_codec_str = g_strdup("h264");
+
+ g_print("Test %s decode\n", g_codec_str);
+ codec = get_codec_defs(g_codec_str);
+ if (!codec)
+ g_error("no %s codec data found", g_codec_str);
+
+ display = gst_vaapi_display_x11_new(NULL);
+ if (!display)
+ g_error("could not create VA display");
+
+ window = gst_vaapi_window_x11_new(display, win_width, win_height);
+ if (!window)
+ g_error("could not create window");
+
+ codec->get_video_info(&info);
+ decoder_caps = gst_vaapi_profile_get_caps(info.profile);
+ if (!decoder_caps)
+ g_error("could not create decoder caps");
+
+ structure = gst_caps_get_structure(decoder_caps, 0);
+ if (info.width > 0 && info.height > 0)
+ gst_structure_set(
+ structure,
+ "width", G_TYPE_INT, info.width,
+ "height", G_TYPE_INT, info.height,
+ NULL
+ );
+
+ decoder = gst_vaapi_decoder_ffmpeg_new(display, decoder_caps);
+ if (!decoder)
+ g_error("could not create FFmpeg decoder");
+ gst_caps_unref(decoder_caps);
+
+ buffer = gst_buffer_new();
+ if (!buffer)
+ g_error("could not create encoded data buffer");
+ gst_buffer_set_data(buffer, (guchar *)info.data, info.data_size);
+
+ if (!gst_vaapi_decoder_put_buffer(decoder, buffer))
+ g_error("could not send video data to the decoder");
+ gst_buffer_unref(buffer);
+
+ if (!gst_vaapi_decoder_put_buffer(decoder, NULL))
+ g_error("could not send EOS to the decoder");
+
+ proxy = gst_vaapi_decoder_get_surface(decoder, &status);
+ if (!proxy)
+ g_error("could not get decoded surface (decoder status %d)", status);
+
+ subpicture_get_info (&subinfo);
+
+ /* Adding subpicture */
+ argbcaps = gst_caps_new_simple ("video/x-raw-rgb",
+ "endianness", G_TYPE_INT, 1,
+ "bpp", G_TYPE_INT, 32,
+ "width", G_TYPE_INT, subinfo.width,
+ "height", G_TYPE_INT, subinfo.height,
+ NULL);
+
+ buffer = gst_buffer_new ();
+ gst_buffer_set_data(buffer, (guchar *)subinfo.data, subinfo.data_size);
+ gst_buffer_set_caps (buffer, argbcaps);
+
+ subtitle_image = gst_vaapi_image_new (display,
+ GST_VAAPI_IMAGE_RGBA, subinfo.width, subinfo.height);
+
+ gst_vaapi_image_update_from_buffer (subtitle_image, buffer);
+
+ subpicture = gst_vaapi_subpicture_new (subtitle_image);
+
+ /* We position it as a subtitle, centered at the bottom. */
+ sub_rect.x = (win_width - subinfo.width) / 2;
+ sub_rect.y = win_height - subinfo.height - 10;
+ sub_rect.height = subinfo.height;
+ sub_rect.width = subinfo.height;
+
+ if (!gst_vaapi_surface_associate_subpicture (
+ GST_VAAPI_SURFACE_PROXY_SURFACE(proxy),
+ subpicture,
+ NULL,
+ &sub_rect))
+ g_error("could not associate subpicture");
+
+ gst_vaapi_window_show(window);
+
+ if (!gst_vaapi_window_put_surface(window,
+ GST_VAAPI_SURFACE_PROXY_SURFACE(proxy),
+ NULL,
+ NULL,
+ GST_VAAPI_PICTURE_STRUCTURE_FRAME))
+ g_error("could not render surface");
+
+ pause();
+
+ gst_buffer_unref(buffer);
+ g_object_unref(proxy);
+ g_object_unref(decoder);
+ g_object_unref(window);
+ g_object_unref(display);
+ g_free(g_codec_str);
+ gst_deinit();
+ return 0;
+}