Add decoder demos. Use -c (mpeg2|h264|vc1) to select the codec.
[profile/ivi/gstreamer-vaapi.git] / tests / test-decode.c
1 /*
2  *  test-decode.c - Test GstVaapiDecoder
3  *
4  *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
19  */
20
21 #include <string.h>
22 #include <gst/vaapi/gstvaapidisplay_x11.h>
23 #include <gst/vaapi/gstvaapiwindow_x11.h>
24 #include <gst/vaapi/gstvaapidecoder.h>
25 #include <gst/vaapi/gstvaapidecoder_ffmpeg.h>
26 #include <gst/vaapi/gstvaapisurface.h>
27 #include "test-mpeg2.h"
28 #include "test-h264.h"
29 #include "test-vc1.h"
30
31 /* Default timeout to wait for the first decoded frame (10 ms) */
32 /* Defined to -1 if the application indefintely waits for the decoded frame */
33 #define TIMEOUT -1
34
35 typedef void (*GetVideoDataFunc)(const guchar **data, guint *size);
36
37 typedef struct _CodecDefs CodecDefs;
38 struct _CodecDefs {
39     const gchar        *codec_str;
40     GstVaapiCodec       codec;
41     GetVideoDataFunc    get_video_data;
42 };
43
44 static const CodecDefs g_codec_defs[] = {
45     { "mpeg2",  GST_VAAPI_CODEC_MPEG2,  mpeg2_get_video_data    },
46     { "h264",   GST_VAAPI_CODEC_H264,   h264_get_video_data     },
47     { "vc1",    GST_VAAPI_CODEC_VC1,    vc1_get_video_data      },
48     { NULL, }
49 };
50
51 static const CodecDefs *
52 get_codec_defs(const gchar *codec_str)
53 {
54     const CodecDefs *c;
55     for (c = g_codec_defs; c->codec_str; c++)
56         if (strcmp(codec_str, c->codec_str) == 0)
57             return c;
58     return NULL;
59 }
60
61 static inline void pause(void)
62 {
63     g_print("Press any key to continue...\n");
64     getchar();
65 }
66
67 static gchar *g_codec_str;
68
69 static GOptionEntry g_options[] = {
70     { "codec", 'c',
71       0,
72       G_OPTION_ARG_STRING, &g_codec_str,
73       "codec to test", NULL },
74     { NULL, }
75 };
76
77 int
78 main(int argc, char *argv[])
79 {
80     GOptionContext       *options;
81     GstVaapiDisplay      *display;
82     GstVaapiWindow       *window;
83     GstVaapiDecoder      *decoder;
84     GstVaapiDecoderStatus status;
85     const CodecDefs      *codec;
86     GstVaapiSurfaceProxy *proxy;
87     const guchar         *vdata;
88     guint                 vdata_size;
89
90     static const guint win_width  = 640;
91     static const guint win_height = 480;
92
93     gst_init(&argc, &argv);
94
95     options = g_option_context_new(" - test-decode options");
96     g_option_context_add_main_entries(options, g_options, NULL);
97     g_option_context_parse(options, &argc, &argv, NULL);
98     g_option_context_free(options);
99
100     if (!g_codec_str)
101         g_codec_str = g_strdup("h264");
102
103     g_print("Test %s decode\n", g_codec_str);
104     codec = get_codec_defs(g_codec_str);
105     if (!codec)
106         g_error("no %s codec data found", g_codec_str);
107
108     display = gst_vaapi_display_x11_new(NULL);
109     if (!display)
110         g_error("could not create VA display");
111
112     window = gst_vaapi_window_x11_new(display, win_width, win_height);
113     if (!window)
114         g_error("could not create window");
115
116     codec->get_video_data(&vdata, &vdata_size);
117     decoder = gst_vaapi_decoder_ffmpeg_new(display, codec->codec);
118     if (!decoder)
119         g_error("could not create FFmpeg decoder");
120
121     if (!gst_vaapi_decoder_put_buffer_data(decoder, vdata, vdata_size))
122         g_error("could not send video data to the decoder");
123     if (0 && !gst_vaapi_decoder_put_buffer(decoder, NULL))
124         g_error("could not send EOS to the decoder");
125
126     if (TIMEOUT < 0) {
127         proxy = gst_vaapi_decoder_get_surface(decoder, &status);
128         if (!proxy)
129             g_error("could not get decoded surface");
130     }
131     else {
132         proxy = gst_vaapi_decoder_timed_get_surface(decoder, TIMEOUT, &status);
133         if (!proxy)
134             g_warning("Could not get decoded surface after %d us", TIMEOUT);
135     }
136
137     gst_vaapi_window_show(window);
138
139     if (!gst_vaapi_window_put_surface(window, proxy->surface, NULL, NULL,
140                                       GST_VAAPI_PICTURE_STRUCTURE_FRAME))
141         g_error("could not render surface");
142
143     pause();
144
145     g_object_unref(proxy);
146     g_object_unref(decoder);
147     g_object_unref(window);
148     g_object_unref(display);
149     g_free(g_codec_str);
150     gst_deinit();
151     return 0;
152 }