1 /* GST123 - GStreamer based command line media player
2 * Copyright (C) 2012 Stefan Westerfeld
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20 #include "typefinder.h"
21 #include <unistd.h>
22 #include <string>
23
24 using std::string;
25
26 namespace Gst123
27 {
28
TypeFinder(const string & filename)29 TypeFinder::TypeFinder (const string& filename)
30 {
31 done = false;
32
33 m_probability = 0;
34 g_mutex_init (&mutex);
35 g_cond_init (&cond);
36
37 run (filename);
38 }
39
~TypeFinder()40 TypeFinder::~TypeFinder()
41 {
42 g_cond_clear (&cond);
43 g_mutex_clear (&mutex);
44 }
45
46 void
typefound(const string & type,guint probability)47 TypeFinder::typefound (const string& type, guint probability)
48 {
49 size_t split_pos = type.find ('/');
50 if (split_pos != string::npos)
51 {
52 m_type = type.substr (0, split_pos);
53 m_subtype = type.substr (split_pos + 1);
54 m_probability = probability;
55 }
56
57 g_mutex_lock (&mutex);
58 done = true;
59 g_cond_signal (&cond);
60 g_mutex_unlock (&mutex);
61 }
62
63 void
cb_typefound(GstElement * typefind,guint probability,GstCaps * caps,gpointer data)64 TypeFinder::cb_typefound (GstElement *typefind,
65 guint probability,
66 GstCaps *caps,
67 gpointer data)
68 {
69 TypeFinder *self = (TypeFinder *) data;
70
71 gchar *type = gst_caps_to_string (caps);
72 self->typefound (type, probability);
73 g_free (type);
74 }
75
76 void
run(const string & filename)77 TypeFinder::run (const string& filename)
78 {
79 /* create a new pipeline to hold the elements */
80 GstElement *pipeline = gst_pipeline_new ("pipe");
81
82 /* create file source and typefind element */
83 GstElement *filesrc = gst_element_factory_make ("filesrc", "source");
84 g_object_set (G_OBJECT (filesrc), "location", filename.c_str(), NULL);
85
86 GstElement *typefind = gst_element_factory_make ("typefind", "typefinder");
87 g_signal_connect (typefind, "have-type", G_CALLBACK (cb_typefound), this);
88
89 GstElement *fakesink = gst_element_factory_make ("fakesink", "sink");
90
91 /* setup */
92 gst_bin_add_many (GST_BIN (pipeline), filesrc, typefind, fakesink, NULL);
93 gst_element_link_many (filesrc, typefind, fakesink, NULL);
94 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
95
96 g_mutex_lock (&mutex);
97 gint64 end_time = g_get_monotonic_time() + 500 * G_TIME_SPAN_MILLISECOND;
98 while (!done)
99 {
100 if (!g_cond_wait_until (&cond, &mutex, end_time))
101 {
102 // timeout occurred
103 break;
104 }
105 }
106 g_mutex_unlock (&mutex);
107
108 /* unset */
109 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
110 gst_object_unref (GST_OBJECT (pipeline));
111 }
112
113 }
114