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