sbGStreamerVideoTranscode.h
Go to the documentation of this file.
1 /*
2  *=BEGIN SONGBIRD GPL
3  *
4  * This file is part of the Songbird web player.
5  *
6  * Copyright(c) 2005-2009 POTI, Inc.
7  * http://www.songbirdnest.com
8  *
9  * This file may be licensed under the terms of of the
10  * GNU General Public License Version 2 (the ``GPL'').
11  *
12  * Software distributed under the License is distributed
13  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
14  * express or implied. See the GPL for the specific language
15  * governing rights and limitations.
16  *
17  * You should have received a copy of the GPL along with this
18  * program. If not, go to http://www.gnu.org/licenses/gpl.html
19  * or write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  *
22  *=END SONGBIRD GPL
23  */
24 
25 #ifndef _SB_GSTREAMER_VIDEO_TRANSCODE_H_
26 #define _SB_GSTREAMER_VIDEO_TRANSCODE_H_
27 
28 #include <nsAutoLock.h>
29 #include <nsCOMPtr.h>
30 #include <nsCOMArray.h>
31 #include <nsITimer.h>
32 #include <nsTArray.h>
33 #include <nsStringGlue.h>
34 
35 #include <gst/gst.h>
36 
37 #include "sbITranscodeVideoJob.h"
38 #include "sbIJobProgress.h"
39 #include "sbIJobCancelable.h"
40 #include "sbITranscodingConfigurator.h"
41 #include "sbITranscodeError.h"
42 #include "sbIMediaFormatMutable.h"
43 
44 #include "sbGStreamerPipeline.h"
45 #include "sbJobUtils.h"
46 
47 // {227551a3-24dc-42e7-9ab6-9525e989edfd}
48 #define SB_GSTREAMER_VIDEO_TRANSCODE_CID \
49  { 0x227551a3, 0x24dc, 0x42e7, \
50  { 0x9a, 0xb6, 0x95, 0x25, 0xe9, 0x89, 0xed, 0xfd } }
51 
52 #define SB_GSTREAMER_VIDEO_TRANSCODE_CONTRACTID \
53  "@songbirdnest.com/Songbird/Mediacore/Transcode/GStreamerVideo;1"
54 #define SB_GSTREAMER_VIDEO_TRANSCODE_CLASSNAME "GStreamerVideoTranscode"
55 
56 
58  public sbITranscodeVideoJob,
59  public sbIJobProgressTime,
60  public sbIJobCancelable,
61  public nsITimerCallback
62 {
63 public:
65  NS_DECL_NSICLASSINFO
66  NS_DECL_SBITRANSCODEVIDEOJOB
67  NS_DECL_SBIJOBPROGRESS
68  NS_DECL_SBIJOBPROGRESSTIME
69  NS_DECL_SBIJOBCANCELABLE
70  NS_DECL_NSITIMERCALLBACK
71 
73 
74  virtual nsresult BuildPipeline();
75  NS_IMETHOD PlayPipeline();
76  NS_IMETHOD StopPipeline();
77 
78 private:
79  virtual ~sbGStreamerVideoTranscoder();
80 
81  nsresult OnJobProgress();
82 
83  void HandleErrorMessage(GstMessage *message);
84  void HandleEOSMessage(GstMessage *message);
85 
86  GstClockTime QueryPosition();
87  GstClockTime QueryDuration();
88 
89  nsresult StartProgressReporting();
90  nsresult StopProgressReporting();
91 
92  void AsyncStopPipeline();
93 
94  /* Build initial, partial, transcoding pipeline. The bulk of the pipeline is
95  built dynamically when the pipeline is started via a call to Transcode().
96  */
97  nsresult BuildTranscodePipeline (const gchar *pipelineName);
98 
99  /* Clean up references to things that were in a pipeline after we're done
100  with the pipeline.
101  After this is called, the object is reusable via a new call to Transcode()
102  */
103  nsresult CleanupPipeline();
104 
105  /* Clean up references to pads inside the pipeline */
106  void CleanupPads();
107 
108  /* Clear the status and any error messages. Called at the start of a
109  transcode attempt, to ensure that the status is set correctly and that
110  any errors resulting are as a result of _this_ transcode attempt */
111  nsresult ClearStatus();
112 
113  /* Initialize the configurator object to decide on what format and other
114  details to transcode to. */
115  nsresult InitializeConfigurator ();
116 
117  /* Helper function to set an sbIMediaFormatVideo from some GStreamer caps */
118  nsresult SetVideoFormatFromCaps (sbIMediaFormatVideoMutable *format,
119  GstCaps *caps);
120 
121  /* Helper function to set an sbIMediaFormatAudio from some GStreamer caps */
122  nsresult SetAudioFormatFromCaps (sbIMediaFormatAudioMutable *format,
123  GstCaps *caps);
124 
125  /* Call to send an error event, and shut down the pipeline, if a fatal error
126  is encountered during transcoding pipeline setup. The errorName is looked
127  up in the properties for localisation */
128  void TranscodingFatalError (const char *errorName);
129 
130  /* Static helpers that simply forward to the relevant instance methods */
131  static void decodebin_pad_added_cb (GstElement *element, GstPad *pad,
132  sbGStreamerVideoTranscoder *transcoder);
133  static void decodebin_no_more_pads_cb (
134  GstElement *element,
135  sbGStreamerVideoTranscoder *transcoder);
136  static void pad_blocked_cb (GstPad *pad, gboolean blocked,
137  sbGStreamerVideoTranscoder *transcoder);
138  static void pad_notify_caps_cb (GObject *obj, GParamSpec *pspec,
139  sbGStreamerVideoTranscoder *transcoder);
140 
141  /* Called when the decoder finds and decodes a stream.
142  Used to find which streams we're interested in using for our transcoded
143  output.
144  */
145  nsresult DecoderPadAdded(GstElement *uridecodebin, GstPad *pad);
146 
147  /* Called when the decoder does not expect to find any more streams.
148  We will ignore any additional streams found after this.
149  Here, we set things up to wait until data is actually flowing on all
150  streams via pad blocks. */
151  nsresult DecoderNoMorePads(GstElement *uridecodebin);
152 
153  /* Called when pad block has fired. */
154  nsresult PadBlocked (GstPad *pad, gboolean blocked);
155 
156  /* Called when we're notified that a pad's caps have been set */
157  nsresult PadNotifyCaps (GstPad *pad);
158 
159  /* Check if we have caps on all our pads yet, and continue on to build the
160  full pipeline if so */
161  nsresult CheckForAllCaps ();
162 
163  /* Helper to get the proper caps from a pad */
164  GstCaps *GetCapsFromPad (GstPad *pad);
165 
166  /* Actually build the rest of the pipeline! */
167  nsresult BuildRemainderOfPipeline();
168 
169  /* Add the audio bin (buffering, conversion, and encoding). Link to
170  'inputAudioSrcPad', which is the pad provided by the decodebin.
171  The src pad from the audio bin is returned in 'outputAudioSrcPad' */
172  nsresult AddAudioBin (GstPad *inputAudioSrcPad, GstPad **outputAudioSrcPad);
173 
174  /* Build the actual audio bin. If needed, the input caps (i.e. the caps of the
175  decoded data from the decoder) are provided in 'inputAudioCaps'.
176  Return the new bin in 'audioBin' */
177  nsresult BuildAudioBin (GstCaps *inputAudioCaps, GstElement **audioBin);
178 
179  /* Add the video bin (buffering, conversion, and encoding). Link to
180  'inputVideoSrcPad', which is the pad provided by the decodebin.
181  The src pad from the video bin is returned in 'outputVideoSrcPad' */
182  nsresult AddVideoBin (GstPad *inputVideoSrcPad, GstPad **outputVideoSrcPad);
183 
184  /* Build the actual video bin. If needed, the input caps (i.e. the caps of the
185  decoded data from the decoder) are provided in 'inputVideoCaps'.
186  Return the new bin in 'videoBin' */
187  nsresult BuildVideoBin (GstCaps *inputVideoCaps, GstElement **videoBin);
188 
189  /* Add a muxer, if required. Return the src pad that should be used (whether
190  that's a muxer src pad, or actually the src pad directly from the audio
191  or video encoder) in 'muxerSrcPad'.
192  Pads to link to it are passed in 'audioPad' and 'videoPad' either of which
193  might be NULL.
194  */
195  nsresult AddMuxer (GstPad **muxerSrcPad, GstPad *audioPad, GstPad *videoPad);
196 
197  /* Add an appropriate sink for the data. Link it to 'muxerSrcPad' */
198  nsresult AddSink (GstPad *muxerSrcPad);
199 
200  /* Create an appropriate sink based on the destination URI set. Return it
201  in 'sink' (not initially connected to anything) */
202  nsresult CreateSink (GstElement **sink);
203 
204  /* Get a pad (either an existing pad, or a newly-requested one) from 'element'
205  that is potentially compatible with 'pad' */
206  GstPad * GetCompatiblePad (GstElement *element, GstPad *pad);
207 
208  /* Get a pad (either an existing pad or a new request pad) from element's
209  pad template 'templ' */
210  GstPad * GetPadFromTemplate (GstElement *element, GstPadTemplate *templ);
211 
212  /* Helper function to configure the videobox element, based on input
213  caps, and specified output geometry */
214  void ConfigureVideoBox (GstElement *videobox, GstCaps *aInputVideoCaps,
215  gint outputWidth, gint outputHeight, gint outputParN, gint outputParD);
216 
217  /* Set the metadata on any tag setters in the pipeline */
218  nsresult SetMetadataOnTagSetters();
219 
220  /* Helper to add an image to a tag list for metadata */
221  nsresult AddImageToTagList(GstTagList *aTags, nsIInputStream *aStream);
222 
223  /* Create a caps object based on the configurator data for raw audio */
224  nsresult GetRawAudioCaps(GstCaps **aResultCaps);
225 
226  nsCOMPtr<sbIPropertyArray> mMetadata;
227  nsCOMPtr<nsIInputStream> mImageStream;
228  nsCOMPtr<sbITranscodingConfigurator> mConfigurator;
229 
230  /* Transcoding input: URI only */
231  nsString mSourceURI;
232 
233  /* Transcoding output: Stream takes precedence if non-NULL */
234  nsString mDestURI;
235  nsCOMPtr<nsIOutputStream> mDestStream;
236 
237  PRUint16 mStatus;
238  nsTArray<nsCOMPtr<sbITranscodeError> > mErrors;
239 
240  nsCOMArray<sbIJobProgressListener> mProgressListeners;
241  nsCOMPtr<nsITimer> mProgressTimer;
242 
243  PRBool mPipelineBuilt;
244  PRBool mWaitingForCaps;
245 
246  GstPad *mAudioSrc;
247  GstPad *mVideoSrc;
248  GstPad *mAudioQueueSrc;
249  GstPad *mVideoQueueSrc;
250 
251  // Booleans to track whether we'll use audio/video/muxer
252  PRBool mUseAudio;
253  PRBool mUseVideo;
254  PRBool mUseMuxer;
255 
256  // Lock to prevent trying to build the pipeline concurrently from multiple
257  // threads.
258  PRLock *mBuildLock;
259 
260 protected:
261  /* additional members */
262 };
263 
264 #endif // _SB_GSTREAMER_TRANSCODE_H_
An object capable of transcoding a source URI to a destination file.
Songbird Job Utility Definitions.
Generic interface extending sbIJobProgress that can track expected time, etc in addition to abstract ...
NS_DECL_ISUPPORTS NS_DECL_NSICLASSINFO NS_DECL_SBITRANSCODEVIDEOJOB NS_DECL_SBIJOBPROGRESS NS_DECL_SBIJOBPROGRESSTIME NS_DECL_SBIJOBCANCELABLE NS_DECL_NSITIMERCALLBACK sbGStreamerVideoTranscoder()
GstMessage * message
readonly attribute boolean blocked
If true, progress of job is blocked (e.g., due to locked resource).
nsITimerCallback