$(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-wayland-@GST_MAJORMINOR@.la
endif
-test_codecs_source_c = \
+test_utils_dec_source_c = \
+ decoder.c \
test-h264.c \
test-jpeg.c \
test-mpeg2.c \
test-mpeg4.c \
test-vc1.c \
$(NULL)
-test_codecs_source_h = $(test_codecs_source_c:%.c=%.h) test-decode.h
+test_utils_dec_source_h = $(test_utils_dec_source_c:%.c=%.h) test-decode.h
-test_utils_source_c = image.c output.c $(test_codecs_source_c)
-test_utils_source_h = image.h output.h $(test_codecs_source_h)
+test_utils_source_c = image.c output.c
+test_utils_source_h = image.h output.h
-noinst_LTLIBRARIES = libutils.la
+noinst_LTLIBRARIES = libutils.la libutils_dec.la
libutils_la_SOURCES = $(test_utils_source_c)
libutils_la_CFLAGS = $(TEST_CFLAGS)
+libutils_dec_la_SOURCES = $(test_utils_dec_source_c)
+libutils_dec_la_CFLAGS = $(TEST_CFLAGS)
-test_decode_SOURCES = test-decode.c $(test_codecs_source_c)
+test_decode_SOURCES = test-decode.c
test_decode_CFLAGS = $(TEST_CFLAGS)
-test_decode_LDADD = libutils.la $(TEST_LIBS)
+test_decode_LDADD = libutils.la libutils_dec.la $(TEST_LIBS)
test_display_SOURCES = test-display.c
test_display_CFLAGS = $(TEST_CFLAGS)
test_textures_LDADD = libutils.la $(TEST_LIBS)
EXTRA_DIST = \
- test-subpicture-data.h \
- $(test_utils_source_h) \
+ test-subpicture-data.h \
+ $(test_utils_dec_source_h) \
+ $(test_utils_source_h) \
$(NULL)
# Extra clean files so that maintainer-clean removes *everything*
--- /dev/null
+/*
+ * decoder.h - Decoder utilities for the tests
+ *
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include <gst/vaapi/gstvaapidecoder_h264.h>
+#include <gst/vaapi/gstvaapidecoder_jpeg.h>
+#include <gst/vaapi/gstvaapidecoder_mpeg2.h>
+#include <gst/vaapi/gstvaapidecoder_mpeg4.h>
+#include <gst/vaapi/gstvaapidecoder_vc1.h>
+#include "decoder.h"
+#include "test-jpeg.h"
+#include "test-mpeg2.h"
+#include "test-mpeg4.h"
+#include "test-h264.h"
+#include "test-vc1.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(jpeg),
+ INIT_FUNCS(mpeg2),
+ INIT_FUNCS(mpeg4),
+ INIT_FUNCS(h264),
+ INIT_FUNCS(vc1),
+#undef INIT_FUNCS
+ { NULL, }
+};
+
+static const CodecDefs *
+find_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;
+}
+
+#define CODEC_DEFS_KEY "codec-defs"
+
+static inline const CodecDefs *
+get_codec_defs(GstVaapiDecoder *decoder)
+{
+ return g_object_get_data(G_OBJECT(decoder), CODEC_DEFS_KEY);
+}
+
+static inline void
+set_codec_defs(GstVaapiDecoder *decoder, const CodecDefs *c)
+{
+ g_object_set_data(G_OBJECT(decoder), CODEC_DEFS_KEY, (gpointer)c);
+}
+
+GstVaapiDecoder *
+decoder_new(GstVaapiDisplay *display, const gchar *codec_name)
+{
+ GstVaapiDecoder *decoder;
+ const CodecDefs *codec;
+ GstCaps *caps;
+ VideoDecodeInfo info;
+
+ if (!codec_name)
+ codec_name = "h264";
+
+ codec = find_codec_defs(codec_name);
+ if (!codec) {
+ GST_ERROR("failed to find %s codec data", codec_name);
+ return NULL;
+ }
+
+ codec->get_video_info(&info);
+ caps = gst_vaapi_profile_get_caps(info.profile);
+ if (!caps) {
+ GST_ERROR("failed to create decoder caps");
+ return NULL;
+ }
+
+ if (info.width > 0 && info.height > 0)
+ gst_caps_set_simple(caps,
+ "width", G_TYPE_INT, info.width,
+ "height", G_TYPE_INT, info.height,
+ NULL);
+
+ switch (gst_vaapi_profile_get_codec(info.profile)) {
+ case GST_VAAPI_CODEC_H264:
+ decoder = gst_vaapi_decoder_h264_new(display, caps);
+ break;
+#if USE_JPEG_DECODER
+ case GST_VAAPI_CODEC_JPEG:
+ decoder = gst_vaapi_decoder_jpeg_new(display, caps);
+ break;
+#endif
+ case GST_VAAPI_CODEC_MPEG2:
+ decoder = gst_vaapi_decoder_mpeg2_new(display, caps);
+ break;
+ case GST_VAAPI_CODEC_MPEG4:
+ decoder = gst_vaapi_decoder_mpeg4_new(display, caps);
+ break;
+ case GST_VAAPI_CODEC_VC1:
+ decoder = gst_vaapi_decoder_vc1_new(display, caps);
+ break;
+ default:
+ decoder = NULL;
+ break;
+ }
+ gst_caps_unref(caps);
+ if (!decoder) {
+ GST_ERROR("failed to create %s decoder", codec->codec_str);
+ return NULL;
+ }
+
+ set_codec_defs(decoder, codec);
+ return decoder;
+}
+
+gboolean
+decoder_put_buffers(GstVaapiDecoder *decoder)
+{
+ const CodecDefs *codec;
+ VideoDecodeInfo info;
+ GstBuffer *buffer;
+ gboolean success;
+
+ g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), FALSE);
+
+ codec = get_codec_defs(decoder);
+ g_return_val_if_fail(codec != NULL, FALSE);
+
+ buffer = gst_buffer_new();
+ if (!buffer) {
+ GST_ERROR("failed to create encoded data buffer");
+ return FALSE;
+ }
+
+ codec->get_video_info(&info);
+ gst_buffer_set_data(buffer, (guchar *)info.data, info.data_size);
+
+ success = gst_vaapi_decoder_put_buffer(decoder, buffer);
+ gst_buffer_unref(buffer);
+ if (!success) {
+ GST_ERROR("failed to send video data to the decoder");
+ return FALSE;
+ }
+
+ if (!gst_vaapi_decoder_put_buffer(decoder, NULL)) {
+ GST_ERROR("failed to submit <end-of-stream> to the decoder");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+GstVaapiSurface *
+decoder_get_surface(GstVaapiDecoder *decoder)
+{
+ GstVaapiSurface *surface;
+ GstVaapiSurfaceProxy *proxy;
+ GstVaapiDecoderStatus status;
+
+ g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
+
+ status = gst_vaapi_decoder_get_surface(decoder, &proxy);
+ if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
+ GST_ERROR("failed to get decoded surface (decoder status %d)", status);
+ return NULL;
+ }
+
+ /* Note: we only have a single I-frame to decode, so this is fine
+ to just release the surface proxy right away */
+ surface = gst_vaapi_surface_proxy_get_surface(proxy);
+ gst_vaapi_surface_proxy_unref(proxy);
+ return surface;
+}
+
+const gchar *
+decoder_get_codec_name(GstVaapiDecoder *decoder)
+{
+ const CodecDefs *codec;
+
+ g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
+
+ codec = get_codec_defs(decoder);
+ g_return_val_if_fail(codec != NULL, FALSE);
+
+ return codec->codec_str;
+}
--- /dev/null
+/*
+ * decoder.h - Decoder utilities for the tests
+ *
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef DECODER_H
+#define DECODER_H
+
+#include <gst/vaapi/gstvaapidecoder.h>
+
+GstVaapiDecoder *
+decoder_new(GstVaapiDisplay *display, const gchar *codec_name);
+
+gboolean
+decoder_put_buffers(GstVaapiDecoder *decoder);
+
+GstVaapiSurface *
+decoder_get_surface(GstVaapiDecoder *decoder);
+
+const gchar *
+decoder_get_codec_name(GstVaapiDecoder *decoder);
+
+#endif /* DECODER_H */
#include "config.h"
#include <string.h>
-#include <gst/vaapi/gstvaapidecoder.h>
#include <gst/vaapi/gstvaapisurface.h>
-#include <gst/vaapi/gstvaapidecoder_h264.h>
-#include <gst/vaapi/gstvaapidecoder_jpeg.h>
-#include <gst/vaapi/gstvaapidecoder_mpeg2.h>
-#include <gst/vaapi/gstvaapidecoder_mpeg4.h>
-#include <gst/vaapi/gstvaapidecoder_vc1.h>
-#include "test-jpeg.h"
-#include "test-mpeg2.h"
-#include "test-mpeg4.h"
-#include "test-h264.h"
-#include "test-vc1.h"
+#include "decoder.h"
#include "output.h"
/* Set to 1 to check display cache works (shared VA display) */
#define CHECK_DISPLAY_CACHE 1
-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(jpeg),
- INIT_FUNCS(mpeg2),
- INIT_FUNCS(mpeg4),
- INIT_FUNCS(h264),
- INIT_FUNCS(vc1),
-#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");
GstVaapiDisplay *display, *display2;
GstVaapiWindow *window;
GstVaapiDecoder *decoder;
- GstCaps *decoder_caps;
- GstStructure *structure;
- GstVaapiDecoderStatus status;
- const CodecDefs *codec;
- GstBuffer *buffer;
- GstVaapiSurfaceProxy *proxy;
- VideoDecodeInfo info;
+ GstVaapiSurface *surface;
static const guint win_width = 640;
static const guint win_height = 480;
if (!video_output_init(&argc, argv, g_options))
g_error("failed to initialize video output subsystem");
- 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);
+ g_print("Test decode\n");
display = video_output_create_display(NULL);
if (!display)
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
- );
-
- switch (gst_vaapi_profile_get_codec(info.profile)) {
- case GST_VAAPI_CODEC_H264:
- decoder = gst_vaapi_decoder_h264_new(display, decoder_caps);
- break;
-#if USE_JPEG_DECODER
- case GST_VAAPI_CODEC_JPEG:
- decoder = gst_vaapi_decoder_jpeg_new(display, decoder_caps);
- break;
-#endif
- case GST_VAAPI_CODEC_MPEG2:
- decoder = gst_vaapi_decoder_mpeg2_new(display, decoder_caps);
- break;
- case GST_VAAPI_CODEC_MPEG4:
- decoder = gst_vaapi_decoder_mpeg4_new(display, decoder_caps);
- break;
- case GST_VAAPI_CODEC_VC1:
- decoder = gst_vaapi_decoder_vc1_new(display, decoder_caps);
- break;
- default:
- decoder = NULL;
- break;
- }
+ decoder = decoder_new(display, g_codec_str);
if (!decoder)
g_error("could not create 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);
+ g_print("Decode %s sample frame\n", decoder_get_codec_name(decoder));
- if (!gst_vaapi_decoder_put_buffer(decoder, NULL))
- g_error("could not send EOS to the decoder");
+ if (!decoder_put_buffers(decoder))
+ g_error("could not fill decoder with sample data");
- status = gst_vaapi_decoder_get_surface(decoder, &proxy);
- if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
- g_error("could not get decoded surface (decoder status %d)", status);
+ surface = decoder_get_surface(decoder);
+ if (!surface)
+ g_error("could not get decoded surface");
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))
+ if (!gst_vaapi_window_put_surface(window, surface, NULL, NULL,
+ GST_VAAPI_PICTURE_STRUCTURE_FRAME))
g_error("could not render surface");
pause();
- gst_vaapi_surface_proxy_unref(proxy);
g_object_unref(decoder);
g_object_unref(window);
g_object_unref(display);