source: trunk/src/3rdparty/phonon/gstreamer/phononsrc.cpp

Last change on this file was 561, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 8.7 KB
Line 
1/* This file is part of the KDE project.
2
3Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
5This library is free software: you can redistribute it and/or modify
6it under the terms of the GNU Lesser General Public License as published by
7the Free Software Foundation, either version 2.1 or 3 of the License.
8
9This library is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU Lesser General Public License for more details.
13
14You should have received a copy of the GNU Lesser General Public License
15along with this library. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <gst/gst.h>
19#include <gst/base/gstbasesrc.h>
20#include "phononsrc.h"
21#include "streamreader.h"
22
23QT_BEGIN_NAMESPACE
24
25namespace Phonon
26{
27namespace Gstreamer
28{
29
30static GstStaticPadTemplate srctemplate =
31 GST_STATIC_PAD_TEMPLATE ("src",
32 GST_PAD_SRC,
33 GST_PAD_ALWAYS,
34 GST_STATIC_CAPS_ANY);
35
36GST_DEBUG_CATEGORY_STATIC (phonon_src_debug);
37
38// PhononSrc args
39enum
40{
41 ARG_0,
42 ARG_PHONONSRC
43};
44
45static void phonon_src_finalize (GObject * object);
46
47static void phonon_src_set_property (GObject * object, guint prop_id,
48 const GValue * value, GParamSpec * pspec);
49static void phonon_src_get_property (GObject * object, guint prop_id,
50 GValue * value, GParamSpec * pspec);
51
52static gboolean phonon_src_start (GstBaseSrc * basesrc);
53static gboolean phonon_src_stop (GstBaseSrc * basesrc);
54
55static gboolean phonon_src_is_seekable (GstBaseSrc * src);
56static gboolean phonon_src_get_size (GstBaseSrc * src, guint64 * size);
57static GstFlowReturn phonon_src_create (GstBaseSrc * src, guint64 offset,
58 guint length, GstBuffer ** buffer);
59
60static void _do_init (GType filesrc_type)
61{
62 Q_UNUSED(filesrc_type);
63 GST_DEBUG_CATEGORY_INIT (phonon_src_debug, "phononsrc", 0, "QIODevice element");
64}
65
66GST_BOILERPLATE_FULL (PhononSrc, phonon_src, GstBaseSrc, GST_TYPE_BASE_SRC, _do_init)
67
68// Register element details
69static void phonon_src_base_init (gpointer g_class) {
70 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
71 static gchar longname[] = "Phonon Stream Source",
72 klass[] = "Source/File",
73 description[] = "Read from a Phonon StreamInterface",
74 author[] = "Nokia Corporation and/or its subsidiary(-ies) <qt-info@nokia.com>";
75 GstElementDetails details = GST_ELEMENT_DETAILS (longname,
76 klass,
77 description,
78 author);
79 gst_element_class_set_details (gstelement_class, &details);
80 gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&srctemplate));
81}
82
83static void phonon_src_class_init (PhononSrcClass * klass)
84{
85 GObjectClass *gobject_class;
86 GstElementClass *gstelement_class;
87 GstBaseSrcClass *gstbasesrc_class;
88
89 gobject_class = G_OBJECT_CLASS (klass);
90 gstelement_class = GST_ELEMENT_CLASS (klass);
91 gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
92
93 gobject_class->set_property = phonon_src_set_property;
94 gobject_class->get_property = phonon_src_get_property;
95
96 g_object_class_install_property (gobject_class, ARG_PHONONSRC,
97 g_param_spec_pointer ("iodevice", "A Phonon StreamReader",
98 "A Phonon::GStreamer::StreamReader to read from", GParamFlags(G_PARAM_READWRITE)));
99
100 gobject_class->finalize = GST_DEBUG_FUNCPTR (phonon_src_finalize);
101
102 gstbasesrc_class->start = GST_DEBUG_FUNCPTR (phonon_src_start);
103 gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (phonon_src_stop);
104 gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (phonon_src_is_seekable);
105 gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (phonon_src_get_size);
106 gstbasesrc_class->create = GST_DEBUG_FUNCPTR (phonon_src_create);
107}
108
109static void phonon_src_init (PhononSrc * src, PhononSrcClass * g_class)
110{
111 Q_UNUSED(g_class);
112#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
113 src->device = 0;
114#else
115 Q_UNUSED(src);
116#endif
117}
118
119static void phonon_src_finalize (GObject * object)
120{
121#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
122 PhononSrc *src;
123 src = GST_PHONON_SRC (object);
124 delete src->device;
125 src->device = 0;
126#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
127 G_OBJECT_CLASS (parent_class)->finalize (object);
128}
129
130#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
131static gboolean phonon_src_set_device(PhononSrc * src, StreamReader* device)
132{
133 GstState state;
134 // The element must be stopped in order to do this
135 GST_OBJECT_LOCK (src);
136 state = GST_STATE (src);
137
138 if (state != GST_STATE_READY && state != GST_STATE_NULL)
139 goto wrong_state;
140
141 GST_OBJECT_UNLOCK (src);
142
143 src->device = device;
144 g_object_notify (G_OBJECT (src), "iodevice");
145 return TRUE;
146
147 // Error
148wrong_state:
149 {
150 //GST_DEBUG_OBJECT (src, "setting location in wrong state");
151 GST_OBJECT_UNLOCK (src);
152 return FALSE;
153 }
154}
155#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
156
157static void phonon_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
158{
159 PhononSrc *src;
160 g_return_if_fail (GST_IS_PHONON_SRC (object));
161 src = GST_PHONON_SRC (object);
162
163 switch (prop_id) {
164#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
165 case ARG_PHONONSRC:
166 {
167 StreamReader *dev = (StreamReader*)(g_value_get_pointer(value));
168 if (dev)
169 phonon_src_set_device(src, dev);
170 break;
171 }
172#else
173 Q_UNUSED(value);
174#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
175 default:
176 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
177 break;
178 }
179}
180
181static void phonon_src_get_property (GObject * object, guint prop_id, GValue * value,
182 GParamSpec * pspec)
183{
184 PhononSrc *src;
185 g_return_if_fail (GST_IS_PHONON_SRC (object));
186 src = GST_PHONON_SRC (object);
187
188 switch (prop_id) {
189#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
190 case ARG_PHONONSRC:
191 g_value_set_pointer(value, src->device);
192 break;
193#else //QT_NO_PHONON_ABSTRACTMEDIASTREAM
194 Q_UNUSED(value);
195#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
196 default:
197 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
198 break;
199 }
200}
201
202static GstFlowReturn phonon_src_create_read (PhononSrc * src, guint64 offset, guint length, GstBuffer ** buffer)
203{
204#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
205 Q_ASSERT(src->device);
206 if (!src->device)
207 return GST_FLOW_ERROR;
208
209 GstBuffer *buf = gst_buffer_new_and_alloc (length);
210 GST_BUFFER_SIZE (buf) = length;
211 GST_BUFFER_OFFSET (buf) = offset;
212 GST_BUFFER_OFFSET_END (buf) = offset + length;
213
214 bool success = src->device->read(offset, length, (char*)GST_BUFFER_DATA (buf));
215 //GST_LOG_OBJECT (src, "Reading %d bytes", length);
216
217 if (success) {
218 *buffer = buf;
219 return GST_FLOW_OK;
220 }
221
222 gst_mini_object_unref(GST_MINI_OBJECT(buf));
223 return GST_FLOW_ERROR;
224#else //QT_NO_PHONON_ABSTRACTMEDIASTREAM
225 Q_UNUSED(src);
226 Q_UNUSED(offset);
227 Q_UNUSED(length);
228 Q_UNUSED(buffer);
229 return GST_FLOW_ERROR;
230#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
231}
232
233static GstFlowReturn phonon_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** buffer)
234{
235 PhononSrc *src;
236 GstFlowReturn ret;
237 src = GST_PHONON_SRC (basesrc);
238 ret = phonon_src_create_read (src, offset, length, buffer);
239 return ret;
240}
241
242static gboolean phonon_src_is_seekable (GstBaseSrc * basesrc)
243{
244 PhononSrc *src = GST_PHONON_SRC (basesrc);
245#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
246 if (src->device)
247 return src->device->streamSeekable();
248#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
249 return false;
250}
251
252static gboolean phonon_src_get_size (GstBaseSrc * basesrc, guint64 * size)
253{
254#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
255 PhononSrc *src;
256 src = GST_PHONON_SRC (basesrc);
257 if (src->device && src->device->streamSeekable()) {
258 *size = src->device->streamSize();
259 return TRUE;
260 }
261#endif //QT_NO_PHONON_ABSTRACTMEDIASTREAM
262 *size = 0;
263 return FALSE;
264}
265
266// Necessary to go to READY state
267static gboolean phonon_src_start (GstBaseSrc * basesrc)
268{
269 Q_UNUSED(basesrc);
270 // Opening the device is handled by the frontend
271 // We can only assume it is already open
272 return TRUE;
273}
274
275static gboolean phonon_src_stop (GstBaseSrc * basesrc)
276{
277 Q_UNUSED(basesrc);
278 // Closing the device is handled by the frontend
279 return TRUE;
280}
281
282}
283} //namespace Phonon::Gstreamer
284
285QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.