tests: add decoder helpers.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 10 Jan 2013 10:22:38 +0000 (11:22 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Fri, 11 Jan 2013 14:32:17 +0000 (15:32 +0100)
tests/Makefile.am
tests/decoder.c [new file with mode: 0644]
tests/decoder.h [new file with mode: 0644]
tests/test-decode.c

index fc258eed1ac310a45137062e2a41981f17bc2d4b..afe894db88bd07146c6e6d55d847971b5006e2bf 100644 (file)
@@ -57,25 +57,28 @@ TEST_LIBS   += \
        $(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)
@@ -98,8 +101,9 @@ test_textures_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*
diff --git a/tests/decoder.c b/tests/decoder.c
new file mode 100644 (file)
index 0000000..17e2ad8
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ *  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;
+}
diff --git a/tests/decoder.h b/tests/decoder.h
new file mode 100644 (file)
index 0000000..7ab9571
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  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 */
index f855a146adca4b6e2cea64f745301176195e78ef..4afed15c126fd8775893c8a73342c197cdf0ab5e 100644 (file)
 
 #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");
@@ -90,13 +51,7 @@ main(int argc, char *argv[])
     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;
@@ -104,13 +59,7 @@ main(int argc, char *argv[])
     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)
@@ -127,74 +76,27 @@ main(int argc, char *argv[])
     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);