1 // MediaParserGst.h: gstreamer media parsers, for Gnash
2 //
3 //   Copyright (C) 2008, 2009, 2010, 2011, 2012
4 //   Free Software Foundation, Inc.
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 
20 #ifndef GNASH_MEDIAPARSER_GST_H
21 #define GNASH_MEDIAPARSER_GST_H
22 
23 #include <deque>
24 #include <memory>
25 #include <queue>
26 #include <gst/gst.h>
27 #include <boost/optional.hpp>
28 #include <boost/utility.hpp> // noncopyable
29 
30 #include "MediaParser.h" // for inheritance
31 #include "ClockTime.h"
32 #include "Id3Info.h"
33 
34 // Forward declaration
35 namespace gnash {
36 	class IOChannel;
37 }
38 
39 namespace gnash {
40 namespace media {
41 namespace gst {
42 
43 /// Class to hold extra info found in any stream by the parser.
44 struct ExtraInfoGst : public AudioInfo::ExtraInfo, VideoInfo::ExtraInfo,
45 	boost::noncopyable
46 {
ExtraInfoGstExtraInfoGst47     ExtraInfoGst(GstCaps* gstcaps)
48     :
49         caps(gstcaps)
50     {
51         gst_caps_ref(caps);
52     }
53 
~ExtraInfoGstExtraInfoGst54     ~ExtraInfoGst()
55     {
56         gst_caps_unref(caps);
57     }
58 
59     GstCaps* caps;
60 };
61 
62 /// Class to hold GstBuffer. Takes ownership.
63 struct EncodedExtraGstData : public EncodedExtraData, boost::noncopyable
64 {
EncodedExtraGstDataEncodedExtraGstData65     EncodedExtraGstData(GstBuffer* buf)
66     : buffer(buf)
67     {
68         gst_buffer_ref(buffer);
69     }
~EncodedExtraGstDataEncodedExtraGstData70     ~EncodedExtraGstData()
71     {
72         gst_buffer_unref(buffer);
73     }
74 
75     GstBuffer* buffer;
76 };
77 
78 
79 /// Simple timer used for probe timeout (deprecated)
80 //
81 /// @deprecated probe-on-construction requirement for MediaParser was drop,
82 ///             so no use for this class anymore
83 ///
84 class SimpleTimer : public boost::noncopyable
85 {
86 public:
SimpleTimer()87     SimpleTimer()
88         : _start_time(clocktime::getTicks())
89     {
90     }
91 
expired()92     bool expired() const
93     {
94         return (clocktime::getTicks() - _start_time) > 1000;
95     }
96 
97 private:
98     std::uint64_t _start_time;
99 };
100 
101 
102 
103 /// Gstreamer based MediaParser
104 class MediaParserGst: public MediaParser
105 {
106 public:
107 
108     /// Construct a Gstreamer-based media parser for given stream
109     //
110     /// Can throw a MediaException if input format couldn't be detected
111     ///
112     MediaParserGst(std::unique_ptr<IOChannel> stream);
113 
114     ~MediaParserGst();
115 
116     // See dox in MediaParser.h
117     bool seek(std::uint32_t&);
118 
119     // See dox in MediaParser.h
120     bool parseNextChunk();
121 
122     // See dox in MediaParser.h
123     virtual std::uint64_t getBytesLoaded() const;
124 
125     virtual boost::optional<Id3Info> getId3Info() const;
126 
127     void rememberAudioFrame(EncodedAudioFrame* frame);
128     void rememberVideoFrame(EncodedVideoFrame* frame);
129 
130 private:
131     void link_to_fakesink(GstPad* pad);
132 
133     static void cb_typefound (GstElement *typefind, guint probability,
134                               GstCaps *caps, gpointer data);
135 
136     static void cb_pad_added(GstElement* element,
137         GstPad* new_pad, gpointer user_data);
138     static void cb_no_more_pads (GstElement* element, gpointer data);
139 
140     static GstFlowReturn cb_chain_func_audio (GstPad *pad, GstBuffer *buffer);
141     static GstFlowReturn cb_chain_func_video (GstPad *pad, GstBuffer *buffer);
142 
143     bool pushGstBuffer();
144     bool emitEncodedFrames();
145 
146 
147     GstElement* _bin;
148     GstPad* _srcpad;
149     GstPad* _audiosink;
150     GstPad* _videosink;
151 
152     bool _demux_probe_ended;
153 
154     std::deque<EncodedAudioFrame*> _enc_audio_frames;
155     std::deque<EncodedVideoFrame*> _enc_video_frames;
156 };
157 
158 
159 } // gnash.media.gst namespace
160 } // gnash.media namespace
161 } // namespace gnash
162 
163 #endif // __MEDIAPARSER_GST_H__
164