summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarinarayan Bhatta2014-06-04 05:33:09 -0500
committerHarinarayan Bhatta2014-06-04 05:33:09 -0500
commitf37124789d9e76de31fbd309296f3a4abb4440a6 (patch)
tree417400e4c0a217d1c8193893fb2181c153db1e4d
parent5100105cc46208025af3dbb7944c70b24c3faf0e (diff)
downloadexample-applications-f37124789d9e76de31fbd309296f3a4abb4440a6.tar.gz
example-applications-f37124789d9e76de31fbd309296f3a4abb4440a6.tar.xz
example-applications-f37124789d9e76de31fbd309296f3a4abb4440a6.zip
Adding gstreamer test application to test trick play modes
Signed-off-by: Harinarayan Bhatta <harinarayan@ti.com>
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac25
-rw-r--r--gst/Makefile.am8
-rw-r--r--gst/gsttestplayer.c384
4 files changed, 417 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 126b679..2397706 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1 +1 @@
SUBDIRS = vpe drm-tests thermal messageq/messageq_ipc_linux SUBDIRS = vpe drm-tests thermal messageq/messageq_ipc_linux gst
diff --git a/configure.ac b/configure.ac
index 1d8ee0f..e65333e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,6 +6,9 @@ AC_INIT(example-apps, 0.1, https://git.ti.com/glsdk/example-applications)
6AC_CONFIG_SRCDIR([Makefile.am]) 6AC_CONFIG_SRCDIR([Makefile.am])
7AC_CONFIG_HEADERS([config.h]) 7AC_CONFIG_HEADERS([config.h])
8 8
9dnl required versions of gstreamer and plugins-base
10GST_REQUIRED=0.10.30
11
9#Initialize automake 12#Initialize automake
10AM_INIT_AUTOMAKE([foreign dist-bzip2]) 13AM_INIT_AUTOMAKE([foreign dist-bzip2])
11AM_MAINTAINER_MODE 14AM_MAINTAINER_MODE
@@ -37,11 +40,31 @@ AM_CONDITIONAL(ENABLE_CAIRO, [test "x$HAVE_CAIRO" = xyes])
37 40
38PKG_CHECK_MODULES(GTHREAD, gthread-2.0) 41PKG_CHECK_MODULES(GTHREAD, gthread-2.0)
39 42
43dnl Check for the required version of GStreamer core (and gst-plugins-base)
44dnl This will export GST_CFLAGS and GST_LIBS variables for use in Makefile.am
45PKG_CHECK_MODULES(GST, [
46 gstreamer-0.10 >= $GST_REQUIRED
47 gstreamer-base-0.10 >= $GST_REQUIRED
48 gstreamer-plugins-base-0.10 >= $GST_REQUIRED
49 gstreamer-plugins-bad-0.10
50], [
51 AC_SUBST(GST_CFLAGS)
52 AC_SUBST(GST_LIBS)
53], [
54 AC_MSG_ERROR([
55 You need to install or upgrade the GStreamer development
56 packages on your system. On debian-based systems these are
57 libgstreamer0.10-dev and libgstreamer-plugins-base0.10-dev.
58 on RPM-based systems gstreamer0.10-devel, libgstreamer0.10-devel
59 or similar. The minimum version required is $GST_REQUIRED.
60 ])
61])
62
40# Checks for header files. 63# Checks for header files.
41 64
42# Checks for typedefs, structures, and compiler characteristics. 65# Checks for typedefs, structures, and compiler characteristics.
43 66
44# Checks for library functions. 67# Checks for library functions.
45 68
46AC_CONFIG_FILES([Makefile vpe/Makefile drm-tests/Makefile thermal/Makefile messageq/messageq_ipc_linux/Makefile]) 69AC_CONFIG_FILES([Makefile vpe/Makefile drm-tests/Makefile thermal/Makefile messageq/messageq_ipc_linux/Makefile gst/Makefile])
47AC_OUTPUT 70AC_OUTPUT
diff --git a/gst/Makefile.am b/gst/Makefile.am
new file mode 100644
index 0000000..67144c2
--- /dev/null
+++ b/gst/Makefile.am
@@ -0,0 +1,8 @@
1
2noinst_PROGRAMS = gsttestplayer
3
4gsttestplayer_SOURCES = gsttestplayer.c
5gsttestplayer_CFLAGS = $(GST_CFLAGS)
6gsttestplayer_LDADD = $(GST_LIBS)
7
8
diff --git a/gst/gsttestplayer.c b/gst/gsttestplayer.c
new file mode 100644
index 0000000..5de21cc
--- /dev/null
+++ b/gst/gsttestplayer.c
@@ -0,0 +1,384 @@
1/*
2 * GStreamer
3 * Copyright (c) 2014, Texas Instruments Incorporated
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation
8 * version 2.1 of the License.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif /* */
23
24#define _GNU_SOURCE
25#include <features.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <errno.h>
29#include <sys/types.h>
30#include <sys/time.h>
31#include <unistd.h>
32#include <string.h>
33#include <ctype.h>
34
35#include <gst/gst.h>
36static int sigtermed = 0;
37
38#define MAX_PIPELINES 16
39static GstElement *p[MAX_PIPELINES];
40static void
41my_signal_handler (int signum)
42{
43 if (signum == SIGINT) {
44 sigtermed = 1;
45 }
46}
47
48static void
49pad_added_cb (GstElement * element, GstPad * pad, void *data)
50{
51 GstElement *parse = GST_ELEMENT (data);
52 GstPad *sinkpad;
53 gchar *theName = GST_PAD_NAME (pad);
54 printf ("pad added:%s\n", theName);
55 if (strstr (theName, "video") != NULL) {
56 sinkpad = gst_element_get_static_pad (parse, "sink");
57 gst_pad_link (pad, sinkpad);
58 gst_object_unref (sinkpad);
59 } else
60 printf ("not linking audio pad\n");
61}
62
63static const char *sinkname = "kmssink";
64static gboolean use_vpe = TRUE;
65static gboolean use_scaling = TRUE;
66static gint scale_w = 800, scale_h = 480;
67static gboolean use_avsync = TRUE;
68static GstElement *
69create_pipeline (char *arg)
70{
71 GstElement *src1;
72 GstElement *demux;
73 GstElement *vdecode, *h264parse, *pipeline, *filter;
74 GstElement *vqueue;
75 GstElement *queue, *vsink;
76 GstCaps *filtercaps;
77 const char *decoder_name, *parser_name, *demux_name;
78 if (NULL != strcasestr (arg, ".mkv"))
79 demux_name = "matroskademux";
80
81 else if (NULL != strcasestr (arg, ".mp4"))
82 demux_name = "qtdemux";
83
84 else if (NULL != strcasestr (arg, ".asf"))
85 demux_name = "asfdemux";
86
87 else if (NULL != strcasestr (arg, ".wmv"))
88 demux_name = "asfdemux";
89
90 else if (NULL != strcasestr (arg, ".ts"))
91 demux_name = "mpegtsdemux";
92
93 else
94 demux_name = "identity";
95 if (NULL != strcasestr (arg, "264")) {
96 decoder_name = use_vpe ? "ducatih264decvpe" : "ducatih264dec";
97 parser_name = "h264parse";
98 }
99
100 else if (NULL != strcasestr (arg, "mpeg2")) {
101 decoder_name = use_vpe ? "ducatimpeg2decvpe" : "ducatimpeg2dec";
102 parser_name = "mpegvideoparse";
103 }
104
105 else if (NULL != strcasestr (arg, "mpeg4")) {
106 decoder_name = use_vpe ? "ducatimpeg4decvpe" : "ducatimpeg4dec";
107 parser_name = "mpeg4videoparse";
108 }
109
110 else {
111 decoder_name = use_vpe ? "ducativc1decvpe" : "ducativc1dec";
112 parser_name = "identity";
113 }
114 printf ("Creating pipeline with %s->%s->%s\n", demux_name, parser_name,
115 decoder_name);
116 pipeline = gst_pipeline_new ("my-pipeline");
117 src1 = gst_element_factory_make ("filesrc", "src1");
118 if (src1 == NULL)
119 printf ("Could not create 'src1' element\r\n");
120 demux = gst_element_factory_make (demux_name, "demux");
121 if (demux == NULL)
122 printf ("Could not create 'demux' element\r\n");
123 vdecode = gst_element_factory_make (decoder_name, "vdecode");
124 if (vdecode == NULL)
125 printf ("Could not create 'omx_h264dec1' element\r\n");
126 h264parse = gst_element_factory_make (parser_name, "h264parse");
127 if (h264parse == NULL)
128 printf ("Could not create 'h264parse' element\r\n");
129 vsink = gst_element_factory_make (sinkname, "kmssink");
130 if (vsink == NULL)
131 printf ("Could not create '%s' element\r\n", sinkname);
132 queue = gst_element_factory_make ("queue", "queue");
133 if (queue == NULL)
134 printf ("Could not create 'queue' element\r\n");
135 vqueue = gst_element_factory_make ("queue", "vqueue");
136 if (vqueue == NULL)
137 printf ("Could not create 'queue' element\r\n");
138 filter =
139 gst_element_factory_make (use_scaling ? "capsfilter" : "identity",
140 "filter");
141 if (filter == NULL)
142 printf ("Could not create 'capsfilter' element\r\n");
143 filtercaps =
144 gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC,
145 GST_MAKE_FOURCC ('N', 'V', '1', '2'), "width", G_TYPE_INT, scale_w,
146 "height", G_TYPE_INT, scale_h, NULL);
147 g_object_set (G_OBJECT (filter), "caps", filtercaps, NULL);
148 gst_caps_unref (filtercaps);
149 printf ("set locaticn to : %s\n", arg);
150
151 // ================= Add capabilities and properties
152 // g_object_set(G_OBJECT (scaler), "num-input-buffers", 24, NULL);
153 // g_object_set(G_OBJECT (scaler), "num-output-buffers", 12, NULL);
154 // g_object_set(G_OBJECT (vdecode), "max-reorder-frames", 4, NULL);
155 g_object_set (G_OBJECT (src1), "location", arg, NULL);
156 g_object_set (G_OBJECT (vsink), "sync", use_avsync, NULL);
157
158 // ================= Put pipeline together
159 gst_bin_add_many (GST_BIN (pipeline), src1, demux, h264parse, vdecode,
160 vsink, filter, vqueue, queue, NULL);
161 gst_element_link_many (src1, demux, NULL);
162 gst_element_link_many (h264parse, queue, vdecode, vqueue, filter,
163 vsink, NULL);
164 if (!g_signal_connect (demux, "pad-added", G_CALLBACK (pad_added_cb),
165 (void *) h264parse))
166 printf ("Cannot connect pad-added cb\r\n");
167
168 // ================= Run
169 printf ("Set Play Mode ...\r\n");
170 gst_element_set_state (pipeline, GST_STATE_PLAYING);
171
172#if 0
173 {
174 GstClock *clk = gst_pipeline_get_clock (GST_PIPELINE (pipeline));
175 if (clk) {
176 printf ("Pipeline clock is %s\n", GST_OBJECT_NAME (clk));
177 gst_object_unref (clk);
178 }
179 }
180
181#endif /* */
182 return pipeline;
183}
184
185gint
186main (gint argc, gchar * argv[])
187{
188 FILE *in = stdin;
189 fd_set f;
190 char *line = NULL;
191 char linebuf[1024];
192 char *args[10];
193 int n, i, time, j, rate;
194 GstEvent *seek_event;
195 if (SIG_ERR == signal (SIGINT, my_signal_handler))
196 exit (1);
197
198 if (argc > 1 && (0 == strcmp ("-h", argv[1])
199 || 0 == strcmp ("--help", argv[1]))) {
200 printf ("Usage: %s <options>\n", argv[0]);
201 printf (" -s <sinkname> Specify the video sink name to be used, default: kmssink\n");
202 printf (" -n Do not use VPE, implies no scaling\n");
203 printf (" -r <width>x<height> Resize the output to widthxheight, no scaling if left blank\n");
204 printf (" -a Play with no A/V Sync\n");
205 printf (" -c <cmds file> Non-interactive mode, reading commands from <cmds file>\n");
206 }
207
208 /* Init GStreamer */
209 gst_init (&argc, &argv);
210
211 for (i = 1; i < argc; i++) {
212 if (0 == strcmp ("-s", argv[i])) {
213 sinkname = argv[i + 1];
214 i++;
215 }
216 if (0 == strcmp ("-n", argv[i])) {
217 use_vpe = FALSE;
218 use_scaling = FALSE;
219 printf ("Not using VPE...\n");
220 }
221 if (0 == strcmp ("-r", argv[i])) {
222 if ((i + 1) < argc
223 && 2 == sscanf (argv[i + 1], "%dx%d", &scale_w, &scale_h)) {
224 printf ("Scaling output to %dx%d\n", scale_w, scale_h);
225 } else {
226 use_scaling = FALSE;
227 printf ("Not using Scaling...\n");
228 }
229 }
230 if (0 == strcmp ("-a", argv[i])) {
231 use_avsync = FALSE;
232 printf ("No A/V Sync, playing as fast as possible...\n");
233 }
234 if (0 == strcmp ("-c", argv[i]) && (i + 1) < argc) {
235 in = fopen (argv[i + 1], "r");
236 if (!in) {
237 printf
238 ("cannot open %s to read in commands, reverting to interactive mode\n",
239 argv[i + 1]);
240 in = stdin;
241 }
242 i++;
243 }
244 }
245 printf ("Using videosink=%s\n", sinkname);
246
247// To detect memory leaks
248 if (!gst_alloc_trace_available ()) {
249 printf ("Trace not available (recompile with trace enabled).\n");
250 } else {
251 gst_alloc_trace_set_flags_all (GST_ALLOC_TRACE_LIVE |
252 GST_ALLOC_TRACE_MEM_LIVE);
253 gst_alloc_trace_print_live ();
254 }
255 while (!sigtermed) {
256 if (in == stdin) {
257 fflush (stdout);
258 FD_ZERO (&f);
259 FD_SET (0, &f);
260 }
261 printf ("<Enter ip> ");
262 line = fgets (linebuf, 1023, in);
263 if (!line)
264 continue;
265 line[1023] = '\0';
266 n = 0;
267 while (*line) {
268 args[n++] = line;
269 while (!isspace (*line))
270 line++;
271 if (!(*line))
272 break;
273 *line = '\0';
274 line++;
275 while (isspace (*line))
276 line++;
277 }
278 if (3 == n && 0 == strcmp ("start", args[0])) {
279 i = atoi (args[1]);
280 printf ("Starting pipeline %d\n", i);
281 p[i] = create_pipeline (args[2]);
282 }
283
284 else if (2 == n && 0 == strcmp ("stop", args[0])) {
285 i = atoi (args[1]);
286 if (p[i]) {
287 gst_element_set_state (p[i], GST_STATE_NULL);
288 gst_object_unref (p[i]);
289 p[i] = NULL;
290 }
291 }
292
293 else if (2 == n && 0 == strcmp ("pause", args[0])) {
294 i = atoi (args[1]);
295 if (p[i])
296 gst_element_set_state (p[i], GST_STATE_PAUSED);
297 }
298
299 else if (2 == n && 0 == strcmp ("resume", args[0])) {
300 i = atoi (args[1]);
301 if (p[i])
302 gst_element_set_state (p[i], GST_STATE_PLAYING);
303 }
304
305 else if (3 <= n && 0 == strcmp ("seek", args[0])) {
306 i = atoi (args[1]);
307 time = atoi (args[2]);
308 rate = (n == 3) ? 1 : atoi (args[3]);
309 if (p[i]) {
310 if (rate == 1) {
311 gst_element_seek_simple (p[i], GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
312 time * GST_SECOND);
313 } else {
314 if (rate > 1) {
315 seek_event =
316 gst_event_new_seek (rate, GST_FORMAT_TIME,
317 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET,
318 time * GST_SECOND, GST_SEEK_TYPE_NONE, 0);
319 } else {
320 seek_event =
321 gst_event_new_seek (rate, GST_FORMAT_TIME,
322 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET,
323 0, GST_SEEK_TYPE_SET, time * GST_SECOND);
324 }
325 gst_element_send_event (p[i], seek_event);
326 }
327 }
328 }
329
330 else if (2 == n && 0 == strcmp ("step", args[0])) {
331 i = atoi (args[1]);
332 rate = atoi (args[2]);
333 if (p[i]) {
334 gst_element_send_event (p[i],
335 gst_event_new_step (GST_FORMAT_BUFFERS, 1, rate, TRUE, FALSE));
336 }
337 }
338
339 else if (2 == n && 0 == strcmp ("sleep", args[0])) {
340 sleep (atoi (args[1]));
341 }
342
343 else if (2 == n && 0 == strcmp ("rewind", args[0])) {
344 if (in != stdin) {
345 rewind (in);
346 j = atoi (args[1]);
347 while (--j)
348 fgets (linebuf, 1023, in);
349 }
350 }
351
352 else if (1 == n && 0 == strcmp ("exit", args[0])) {
353 break;
354 }
355
356 else if (1 == n && 0 == strcmp ("help", args[0])) {
357 printf ("Commands available:\n");
358 printf (" start <instance num> <filename>\n");
359 printf (" stop <instance num>\n");
360 printf (" pause <instance num>\n");
361 printf (" resume <instance num>\n");
362 printf
363 (" seek <instance num> <seek to time in seconds> <optional: playback speed>\n");
364 printf (" sleep <sleep time in seconds>\n");
365 printf
366 (" rewind <line number> <rewind command file go to line number>\n");
367 printf (" exit\n");
368 }
369 }
370 for (i = 0; i < MAX_PIPELINES; i++) {
371 if (p[i]) {
372 gst_element_set_state (p[i], GST_STATE_NULL);
373 gst_object_unref (p[i]);
374 p[i] = NULL;
375 }
376 }
377 sleep (1);
378 gst_alloc_trace_print_live ();
379 {
380 char command[256];
381 sprintf (command, "ls -l //proc//%d//fd//", getpid ());
382 system (command);
383 } return 0;
384}