1 /*
2 Copyright (C) 2012 Openismus GmbH
3 @author Mathias Hasselmann <mathias@openismus.com>
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published
7 by the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program 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
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "discoverer.h"
19
20 #include <QGlib/Error>
21 #include <QGst/Caps>
22
23 #include <gst/pbutils/gstdiscoverer.h>
24
25 namespace QGst {
26
wrapStreamInfoList(GList * input,bool increaseRef)27 static QList<DiscovererStreamInfoPtr> wrapStreamInfoList(GList *input, bool increaseRef)
28 {
29 QList<DiscovererStreamInfoPtr> output;
30
31 while(input) {
32 output += DiscovererStreamInfoPtr::wrap(GST_DISCOVERER_STREAM_INFO(input->data), increaseRef);
33 input = g_list_delete_link(input, input);
34 }
35
36 return output;
37 }
38
previous() const39 DiscovererStreamInfoPtr DiscovererStreamInfo::previous() const
40 {
41 return DiscovererStreamInfoPtr::wrap(gst_discoverer_stream_info_get_previous(object<GstDiscovererStreamInfo>()), false);
42 }
43
next() const44 DiscovererStreamInfoPtr DiscovererStreamInfo::next() const
45 {
46 return DiscovererStreamInfoPtr::wrap(gst_discoverer_stream_info_get_next(object<GstDiscovererStreamInfo>()), false);
47 }
48
streamTypeNick() const49 QString DiscovererStreamInfo::streamTypeNick() const
50 {
51 return QString::fromUtf8(gst_discoverer_stream_info_get_stream_type_nick(object<GstDiscovererStreamInfo>()));
52 }
53
caps() const54 CapsPtr DiscovererStreamInfo::caps() const
55 {
56 return CapsPtr::wrap(gst_discoverer_stream_info_get_caps(object<GstDiscovererStreamInfo>()), false);
57 }
58
tags() const59 TagList DiscovererStreamInfo::tags() const
60 {
61 return gst_discoverer_stream_info_get_tags(object<GstDiscovererStreamInfo>());
62 }
63
misc() const64 Structure DiscovererStreamInfo::misc() const
65 {
66 const GstStructure *const misc = gst_discoverer_stream_info_get_misc(object<GstDiscovererStreamInfo>());
67 return misc ? Structure(misc) : Structure();
68 }
69
streams() const70 QList<DiscovererStreamInfoPtr> DiscovererContainerInfo::streams() const
71 {
72 return wrapStreamInfoList(gst_discoverer_container_info_get_streams(object<GstDiscovererContainerInfo>()), false);
73 }
74
channels() const75 uint DiscovererAudioInfo::channels() const
76 {
77 return gst_discoverer_audio_info_get_channels(object<GstDiscovererAudioInfo>());
78 }
79
sampleRate() const80 uint DiscovererAudioInfo::sampleRate() const
81 {
82 return gst_discoverer_audio_info_get_sample_rate(object<GstDiscovererAudioInfo>());
83 }
84
depth() const85 uint DiscovererAudioInfo::depth() const
86 {
87 return gst_discoverer_audio_info_get_depth(object<GstDiscovererAudioInfo>());
88 }
89
bitrate() const90 uint DiscovererAudioInfo::bitrate() const
91 {
92 return gst_discoverer_audio_info_get_bitrate(object<GstDiscovererAudioInfo>());
93 }
94
maxBitrate() const95 uint DiscovererAudioInfo::maxBitrate() const
96 {
97 return gst_discoverer_audio_info_get_max_bitrate(object<GstDiscovererAudioInfo>());
98 }
99
language() const100 QString DiscovererAudioInfo::language() const
101 {
102 return QString::fromUtf8(gst_discoverer_audio_info_get_language(object<GstDiscovererAudioInfo>()));
103 }
104
width() const105 uint DiscovererVideoInfo::width() const
106 {
107 return gst_discoverer_video_info_get_width(object<GstDiscovererVideoInfo>());
108 }
109
height() const110 uint DiscovererVideoInfo::height() const
111 {
112 return gst_discoverer_video_info_get_height(object<GstDiscovererVideoInfo>());
113 }
114
depth() const115 uint DiscovererVideoInfo::depth() const
116 {
117 return gst_discoverer_video_info_get_depth(object<GstDiscovererVideoInfo>());
118 }
119
framerate() const120 Fraction DiscovererVideoInfo::framerate() const
121 {
122 return Fraction(gst_discoverer_video_info_get_framerate_num(object<GstDiscovererVideoInfo>()),
123 gst_discoverer_video_info_get_framerate_denom(object<GstDiscovererVideoInfo>()));
124 }
125
pixelAspectRatio() const126 Fraction DiscovererVideoInfo::pixelAspectRatio() const
127 {
128 return Fraction(gst_discoverer_video_info_get_par_num(object<GstDiscovererVideoInfo>()),
129 gst_discoverer_video_info_get_par_denom(object<GstDiscovererVideoInfo>()));
130 }
131
bitrate() const132 uint DiscovererVideoInfo::bitrate() const
133 {
134 return gst_discoverer_video_info_get_bitrate(object<GstDiscovererVideoInfo>());
135 }
136
maxBitrate() const137 uint DiscovererVideoInfo::maxBitrate() const
138 {
139 return gst_discoverer_video_info_get_max_bitrate(object<GstDiscovererVideoInfo>());
140 }
141
isInterlaced() const142 bool DiscovererVideoInfo::isInterlaced() const
143 {
144 return gst_discoverer_video_info_is_interlaced(object<GstDiscovererVideoInfo>());
145 }
146
isImage() const147 bool DiscovererVideoInfo::isImage() const
148 {
149 return gst_discoverer_video_info_is_image(object<GstDiscovererVideoInfo>());
150 }
151
language() const152 QString DiscovererSubtitleInfo::language() const
153 {
154 return QString::fromUtf8(gst_discoverer_subtitle_info_get_language(object<GstDiscovererSubtitleInfo>()));
155 }
156
uri() const157 QUrl DiscovererInfo::uri() const
158 {
159 return QUrl::fromEncoded(gst_discoverer_info_get_uri(object<GstDiscovererInfo>()));
160 }
161
result() const162 DiscovererResult DiscovererInfo::result() const
163 {
164 return DiscovererResult(gst_discoverer_info_get_result(object<GstDiscovererInfo>()));
165 }
166
duration() const167 ClockTime DiscovererInfo::duration() const
168 {
169 return gst_discoverer_info_get_duration(object<GstDiscovererInfo>());
170 }
171
seekable() const172 bool DiscovererInfo::seekable() const
173 {
174 return gst_discoverer_info_get_seekable(object<GstDiscovererInfo>());
175 }
176
misc() const177 Structure DiscovererInfo::misc() const
178 {
179 const GstStructure *const misc = gst_discoverer_info_get_misc(object<GstDiscovererInfo>());
180 return misc ? Structure(misc) : Structure();
181 }
182
tags() const183 TagList DiscovererInfo::tags() const
184 {
185 return gst_discoverer_info_get_tags(object<GstDiscovererInfo>());
186 }
187
streamInfo() const188 DiscovererStreamInfoPtr DiscovererInfo::streamInfo() const
189 {
190 return DiscovererStreamInfoPtr::wrap(gst_discoverer_info_get_stream_info(object<GstDiscovererInfo>()), false);
191 }
192
streams() const193 QList<DiscovererStreamInfoPtr> DiscovererInfo::streams() const
194 {
195 return wrapStreamInfoList(gst_discoverer_info_get_stream_list(object<GstDiscovererInfo>()), false);
196 }
197
streams(QGlib::Type streamType) const198 QList<DiscovererStreamInfoPtr> DiscovererInfo::streams(QGlib::Type streamType) const
199 {
200 return wrapStreamInfoList(gst_discoverer_info_get_streams(object<GstDiscovererInfo>(), streamType), false);
201 }
202
audioStreams() const203 QList<DiscovererStreamInfoPtr> DiscovererInfo::audioStreams() const
204 {
205 return wrapStreamInfoList(gst_discoverer_info_get_audio_streams(object<GstDiscovererInfo>()), false);
206 }
207
videoStreams() const208 QList<DiscovererStreamInfoPtr> DiscovererInfo::videoStreams() const
209 {
210 return wrapStreamInfoList(gst_discoverer_info_get_video_streams(object<GstDiscovererInfo>()), false);
211 }
212
subtitleStreams() const213 QList<DiscovererStreamInfoPtr> DiscovererInfo::subtitleStreams() const
214 {
215 return wrapStreamInfoList(gst_discoverer_info_get_subtitle_streams(object<GstDiscovererInfo>()), false);
216 }
217
containerStreams() const218 QList<DiscovererStreamInfoPtr> DiscovererInfo::containerStreams() const
219 {
220 return wrapStreamInfoList(gst_discoverer_info_get_container_streams(object<GstDiscovererInfo>()), false);
221 }
222
create(ClockTime timeout)223 DiscovererPtr Discoverer::create(ClockTime timeout)
224 {
225 GError *error = NULL;
226 GstDiscoverer *discoverer = gst_discoverer_new(timeout, &error);
227 if (error) {
228 throw QGlib::Error(error);
229 }
230 if (discoverer) {
231 g_object_ref_sink(discoverer);
232 }
233 return DiscovererPtr::wrap(discoverer, false);
234 }
235
start()236 void Discoverer::start()
237 {
238 gst_discoverer_start(object<GstDiscoverer>());
239 }
240
stop()241 void Discoverer::stop()
242 {
243 gst_discoverer_stop(object<GstDiscoverer>());
244 }
245
discoverUriAsync(const char * uri)246 bool Discoverer::discoverUriAsync(const char *uri)
247 {
248 return gst_discoverer_discover_uri_async(object<GstDiscoverer>(), uri);
249 }
250
discoverUri(const char * uri)251 DiscovererInfoPtr Discoverer::discoverUri(const char *uri)
252 {
253 GError *error = NULL;
254 GstDiscovererInfo *info = gst_discoverer_discover_uri(object<GstDiscoverer>(), uri, &error);
255 if (error) {
256 throw QGlib::Error(error);
257 }
258 return DiscovererInfoPtr::wrap(info, false);
259 }
260
operator <<(QDebug debug,DiscovererResult result)261 QDebug operator<<(QDebug debug, DiscovererResult result)
262 {
263 switch(result) {
264 case DiscovererOk:
265 return debug << "QGst::DiscovererOk";
266 case DiscovererUriInvalid:
267 return debug << "QGst::DiscovererUriInvalid";
268 case DiscovererError:
269 return debug << "QGst::DiscovererError";
270 case DiscovererTimeout:
271 return debug << "QGst::DiscovererTimeout";
272 case DiscovererBusy:
273 return debug << "QGst::DiscovererBusy";
274 case DiscovererMissingPlugins:
275 return debug << "QGst::DiscovererMissingPlugins";
276 }
277
278 return (debug.nospace() << "QGst::DiscovererResult(" << uint(result) << ")").maybeSpace();
279 }
280
281 template <typename T>
282 static const char *typeName();
283
284 template <typename T>
285 static QDebug printStreamInfoDetails(QDebug debug, const T &);
286
287 template <>
typeName()288 const char *typeName<DiscovererStreamInfoPtr>()
289 {
290 return "QGst::DiscovererStreamInfoPtr";
291 }
292
293 template <>
typeName()294 const char *typeName<DiscovererContainerInfoPtr>()
295 {
296 return "QGst::DiscovererContainerInfoPtr";
297 }
298
299 template <>
typeName()300 const char *typeName<DiscovererAudioInfoPtr>()
301 {
302 return "QGst::DiscovererAudioInfoPtr";
303 }
304
305 template <>
typeName()306 const char *typeName<DiscovererVideoInfoPtr>()
307 {
308 return "QGst::DiscovererVideoInfoPtr";
309 }
310
311 template <>
typeName()312 const char *typeName<DiscovererSubtitleInfoPtr>()
313 {
314 return "QGst::DiscovererSubtitleInfoPtr";
315 }
316
317 template <>
printStreamInfoDetails(QDebug debug,const DiscovererStreamInfoPtr &)318 QDebug printStreamInfoDetails(QDebug debug, const DiscovererStreamInfoPtr &)
319 {
320 return debug;
321 }
322
323 template <>
printStreamInfoDetails(QDebug debug,const DiscovererContainerInfoPtr & info)324 QDebug printStreamInfoDetails(QDebug debug, const DiscovererContainerInfoPtr &info)
325 {
326 return debug.nospace()
327 << ", streams=" << info->streams();
328 }
329
330 template <>
printStreamInfoDetails(QDebug debug,const DiscovererAudioInfoPtr & info)331 QDebug printStreamInfoDetails(QDebug debug, const DiscovererAudioInfoPtr &info)
332 {
333 return debug.nospace()
334 << ", channels=" << info->channels()
335 << ", sampleRate=" << info->sampleRate()
336 << ", depth=" << info->depth()
337 << ", bitrate=" << info->bitrate()
338 << ", maxBitrate=" << info->maxBitrate()
339 << ", language=" << info->language();
340 }
341
342 template <>
printStreamInfoDetails(QDebug debug,const DiscovererVideoInfoPtr & info)343 QDebug printStreamInfoDetails(QDebug debug, const DiscovererVideoInfoPtr &info)
344 {
345 return debug.nospace()
346 << ", width=" << info->width()
347 << ", height=" << info->height()
348 << ", depth=" << info->depth()
349 << ", framerate=" << info->framerate()
350 << ", pixelAspectRatio=" << info->pixelAspectRatio()
351 << ", bitrate=" << info->bitrate()
352 << ", maxBitrate=" << info->maxBitrate()
353 << ", isInterlaced=" << info->isInterlaced()
354 << ", isImage=" << info->isImage();
355 }
356
357 template <>
printStreamInfoDetails(QDebug debug,const DiscovererSubtitleInfoPtr & info)358 QDebug printStreamInfoDetails(QDebug debug, const DiscovererSubtitleInfoPtr &info)
359 {
360 return debug.nospace()
361 << ", language=" << info->language();
362 }
363
364 template <typename T>
printStreamInfo(QDebug debug,const T & info)365 static QDebug printStreamInfo(QDebug debug, const T &info)
366 {
367 debug.nospace() << typeName<T>() << "(";
368
369 if (info) {
370 debug.nospace() << info->streamTypeNick()
371 << ", caps=" << info->caps();
372 debug.nospace() << ", tags=" << info->tags();
373 debug.nospace() << ", misc=" << info->misc();
374 debug.nospace() << ", hasPrevious=" << !info->previous().isNull();
375 debug.nospace() << ", hasNext=" << !info->next().isNull();
376 debug = printStreamInfoDetails(debug, info);
377 } else {
378 debug << "<null>";
379 }
380
381 return (debug << ")").maybeSpace();
382 }
383
operator <<(QDebug debug,const DiscovererStreamInfoPtr & info)384 QDebug operator<<(QDebug debug, const DiscovererStreamInfoPtr &info)
385 {
386 if (const DiscovererContainerInfoPtr containerInfo = info.dynamicCast<DiscovererContainerInfo>()) {
387 return printStreamInfo(debug, containerInfo);
388 }
389 if (const DiscovererAudioInfoPtr audioInfo = info.dynamicCast<DiscovererAudioInfo>()) {
390 return printStreamInfo(debug, audioInfo);
391 }
392 if (const DiscovererVideoInfoPtr videoInfo = info.dynamicCast<DiscovererVideoInfo>()) {
393 return printStreamInfo(debug, videoInfo);
394 }
395 if (const DiscovererSubtitleInfoPtr subtitleInfo = info.dynamicCast<DiscovererSubtitleInfo>()) {
396 return printStreamInfo(debug, subtitleInfo);
397 }
398
399 return printStreamInfo(debug, info);
400 }
401
operator <<(QDebug debug,const DiscovererInfoPtr & info)402 QDebug operator<<(QDebug debug, const DiscovererInfoPtr &info)
403 {
404 debug.nospace() << "QGst::DiscovererInfoPtr(";
405
406 if (info) {
407 debug.nospace() << "result=" << info->result()
408 << ", uri=" << info->uri()
409 << ", duration=" << info->duration()
410 << ", seekable=" << info->seekable()
411 << ", misc=" << info->misc();
412 debug.nospace() << ", tags=" << info->tags();
413 debug.nospace() << ", streamInfo=" << info->streamInfo();
414 debug.nospace() << ", streams=" << info->streams();
415 debug.nospace() << ", audioStreams=" << info->audioStreams();
416 debug.nospace() << ", videoStreams=" << info->videoStreams();
417 debug.nospace() << ", subtitleStreams=" << info->subtitleStreams();
418 debug.nospace() << ", containerStreams=" << info->containerStreams();
419 } else {
420 debug << "<null>";
421 }
422
423 return (debug << ")").maybeSpace();
424 }
425
426 } // namespace QGst
427