2 * Copyright (C) 2012 Smart TV Alliance
3 * Author: Thiago Sousa Santos <thiago.sousa.santos@collabora.com>, Collabora Ltd.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * SECTION:element-mssdemux
26 * Demuxes a Microsoft's Smooth Streaming manifest into its audio and/or video streams.
35 #include "gst/gst-i18n-plugin.h"
41 #include "gstmssdemux.h"
43 GST_DEBUG_CATEGORY (mssdemux_debug);
45 static GstStaticPadTemplate gst_mss_demux_sink_template =
46 GST_STATIC_PAD_TEMPLATE ("sink",
49 GST_STATIC_CAPS ("application/vnd.ms-sstr+xml")
52 static GstStaticPadTemplate gst_mss_demux_videosrc_template =
53 GST_STATIC_PAD_TEMPLATE ("video_%02u",
58 static GstStaticPadTemplate gst_mss_demux_audiosrc_template =
59 GST_STATIC_PAD_TEMPLATE ("audio_%02u",
64 GST_BOILERPLATE (GstMssDemux, gst_mss_demux, GstMssDemux, GST_TYPE_ELEMENT);
66 static void gst_mss_demux_dispose (GObject * object);
67 static GstStateChangeReturn
68 gst_mss_demux_change_state (GstElement * element, GstStateChange transition);
69 static GstFlowReturn gst_mss_demux_chain (GstPad * pad, GstBuffer * buffer);
70 static GstFlowReturn gst_mss_demux_event (GstPad * pad, GstEvent * event);
72 static void gst_mss_demux_process_manifest (GstMssDemux * mssdemux);
75 gst_mss_demux_base_init (gpointer klass)
77 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
79 gst_element_class_add_static_pad_template (element_class,
80 &gst_mss_demux_sink_template);
81 gst_element_class_add_static_pad_template (element_class,
82 &gst_mss_demux_videosrc_template);
83 gst_element_class_add_static_pad_template (element_class,
84 &gst_mss_demux_audiosrc_template);
85 gst_element_class_set_details_simple (element_class, "Smooth Streaming "
87 "Parse and demultiplex a Smooth Streaming manifest into audio and video "
88 "streams", "Thiago Santos <thiago.sousa.santos@collabora.com>");
90 GST_DEBUG_CATEGORY_INIT (mssdemux_debug, "mssdemux", 0, "mssdemux plugin");
94 gst_mss_demux_class_init (GstMssDemuxClass * klass)
96 GObjectClass *gobject_class;
97 GstElementClass *gstelement_class;
99 gobject_class = (GObjectClass *) klass;
100 gstelement_class = (GstElementClass *) klass;
102 parent_class = g_type_class_peek_parent (klass);
104 gobject_class->dispose = gst_mss_demux_dispose;
106 gstelement_class->change_state =
107 GST_DEBUG_FUNCPTR (gst_mss_demux_change_state);
111 gst_mss_demux_init (GstMssDemux * mssdemux, GstMssDemuxClass * klass)
114 gst_pad_new_from_static_template (&gst_mss_demux_sink_template, "sink");
115 gst_pad_set_chain_function (mssdemux->sinkpad,
116 GST_DEBUG_FUNCPTR (gst_mss_demux_chain));
117 gst_pad_set_event_function (mssdemux->sinkpad,
118 GST_DEBUG_FUNCPTR (gst_mss_demux_event));
119 gst_element_add_pad (GST_ELEMENT_CAST (mssdemux), mssdemux->sinkpad);
123 gst_mss_demux_reset (GstMssDemux * mssdemux)
125 if (mssdemux->manifest_buffer) {
126 gst_buffer_unref (mssdemux->manifest_buffer);
128 if (mssdemux->manifest) {
129 gst_mss_manifest_free (mssdemux->manifest);
134 gst_mss_demux_dispose (GObject * object)
136 /* GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (object); */
138 G_OBJECT_CLASS (parent_class)->dispose (object);
141 static GstStateChangeReturn
142 gst_mss_demux_change_state (GstElement * element, GstStateChange transition)
144 GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (element);
145 GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
147 switch (transition) {
148 case GST_STATE_CHANGE_PAUSED_TO_READY:
150 case GST_STATE_CHANGE_READY_TO_NULL:
151 gst_mss_demux_reset (mssdemux);
157 result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
159 switch (transition) {
160 case GST_STATE_CHANGE_PAUSED_TO_READY:{
171 gst_mss_demux_chain (GstPad * pad, GstBuffer * buffer)
173 GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (GST_PAD_PARENT (pad));
174 if (mssdemux->manifest_buffer == NULL)
175 mssdemux->manifest_buffer = buffer;
177 mssdemux->manifest_buffer =
178 gst_buffer_join (mssdemux->manifest_buffer, buffer);
184 gst_mss_demux_event (GstPad * pad, GstEvent * event)
186 GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (GST_PAD_PARENT (pad));
187 gboolean forward = TRUE;
190 switch (GST_EVENT_TYPE (event)) {
192 if (mssdemux->manifest_buffer == NULL) {
193 GST_WARNING_OBJECT (mssdemux, "Received EOS without a manifest.");
197 gst_mss_demux_process_manifest (mssdemux);
205 ret = gst_pad_event_default (pad, event);
207 gst_event_unref (event);
214 gst_mss_demux_process_manifest (GstMssDemux * mssdemux)
216 g_return_if_fail (mssdemux->manifest_buffer != NULL);
217 g_return_if_fail (mssdemux->manifest == NULL);
219 mssdemux->manifest = gst_mss_manifest_new (mssdemux->manifest_buffer);