diff options
author | Thibault Saunier <thibault.saunier@collabora.com> | 2011-10-14 13:00:12 -0300 |
---|---|---|
committer | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2011-12-12 15:08:42 +0100 |
commit | bb72c5555586ef0cf148cb353936f2f28024fd40 (patch) | |
tree | 5a1d88d45270c153883aa4aefd7370c740c8882b /tests/test-subpicture.c | |
parent | cbf81d7d51db8acb7d788263578fa58906d9ac92 (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.c | 207 |
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; +} |