34 #include <sbIGStreamerService.h>
35 #include <sbIMediaItem.h>
36 #include <sbIMediaInspector.h>
37 #include <sbIMediaFormatMutable.h>
39 #include <nsIWritablePropertyBag2.h>
40 #include <nsServiceManagerUtils.h>
41 #include <nsThreadUtils.h>
45 #define GST_MEDIA_INSPECTOR_TIMEOUT (2000)
47 #define GST_TYPE_PROPERTY "gst_type"
54 static PRLogModuleInfo* gGStreamerMediaInspector = PR_NewLogModule(
"sbGStreamerMediaInspector");
55 #define LOG(args) PR_LOG(gGStreamerMediaInspector, PR_LOG_WARNING, args)
56 #define TRACE(args) PR_LOG(gGStreamerMediaInspector, PR_LOG_DEBUG, args)
80 sbGStreamerMediaInspector::sbGStreamerMediaInspector() :
85 mTooComplexForCurrentImplementation(PR_FALSE),
89 mAudioDecoderSink(NULL),
90 mVideoDecoderSink(NULL),
95 TRACE((
"%s[%p]", __FUNCTION__,
this));
98 sbGStreamerMediaInspector::~sbGStreamerMediaInspector()
100 TRACE((
"%s[%p]", __FUNCTION__,
this));
107 sbGStreamerMediaInspector::GetCanCancel(PRBool *aCanCancel)
109 TRACE((
"%s[%p]", __FUNCTION__,
this));
110 NS_ENSURE_ARG_POINTER(aCanCancel);
112 *aCanCancel = PR_TRUE;
117 sbGStreamerMediaInspector::Cancel()
119 TRACE((
"%s[%p]", __FUNCTION__,
this));
122 nsresult rv = StopPipeline();
123 NS_ENSURE_SUCCESS (rv, rv);
131 sbGStreamerMediaInspector::GetStatus(PRUint16 *aStatus)
133 TRACE((
"%s[%p]", __FUNCTION__,
this));
134 NS_ENSURE_ARG_POINTER(aStatus);
142 sbGStreamerMediaInspector::GetBlocked(PRBool *aBlocked)
144 TRACE((
"%s[%p]", __FUNCTION__,
this));
145 NS_ENSURE_ARG_POINTER(aBlocked);
147 *aBlocked = PR_FALSE;
153 sbGStreamerMediaInspector::GetStatusText(nsAString& aText)
155 TRACE((
"%s[%p]", __FUNCTION__,
this));
156 nsresult rv = NS_ERROR_FAILURE;
161 NS_LITERAL_STRING(
"mediacore.gstreamer.inspect.failed"));
165 NS_LITERAL_STRING(
"mediacore.gstreamer.inspect.succeeded"));
169 NS_LITERAL_STRING(
"mediacore.gstreamer.inspect.running"));
172 NS_NOTREACHED(
"Status is invalid");
179 sbGStreamerMediaInspector::GetTitleText(nsAString& aText)
181 TRACE((
"%s[%p]", __FUNCTION__,
this));
183 NS_LITERAL_STRING(
"mediacore.gstreamer.inspect.title"));
187 sbGStreamerMediaInspector::GetProgress(PRUint32* aProgress)
189 TRACE((
"%s[%p]", __FUNCTION__,
this));
190 NS_ENSURE_ARG_POINTER(aProgress);
197 sbGStreamerMediaInspector::GetTotal(PRUint32* aTotal)
199 TRACE((
"%s[%p]", __FUNCTION__,
this));
200 NS_ENSURE_ARG_POINTER(aTotal);
209 sbGStreamerMediaInspector::GetErrorCount(PRUint32* aErrorCount)
211 TRACE((
"%s[%p]", __FUNCTION__,
this));
212 NS_ENSURE_ARG_POINTER(aErrorCount);
213 NS_ASSERTION(NS_IsMainThread(),
214 "sbIJobProgress::GetErrorCount is main thread only!");
216 *aErrorCount = mErrorMessages.Length();
224 TRACE((
"%s[%p]", __FUNCTION__,
this));
225 NS_ENSURE_ARG_POINTER(aMessages);
226 NS_ASSERTION(NS_IsMainThread(),
227 "sbIJobProgress::GetProgress is main thread only!");
231 nsCOMPtr<nsIStringEnumerator> enumerator =
233 NS_ENSURE_TRUE(enumerator, NS_ERROR_OUT_OF_MEMORY);
235 enumerator.forget(aMessages);
242 TRACE((
"%s[%p]", __FUNCTION__,
this));
243 NS_ENSURE_ARG_POINTER(aListener);
244 NS_ASSERTION(NS_IsMainThread(),
245 "sbGStreamerMediaInspector::AddJobProgressListener is main thread only!");
247 PRInt32 index = mProgressListeners.IndexOf(aListener);
250 return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA;
252 PRBool
succeeded = mProgressListeners.AppendObject(aListener);
253 NS_ENSURE_TRUE(succeeded, NS_ERROR_FAILURE);
259 sbGStreamerMediaInspector::RemoveJobProgressListener(
262 TRACE((
"%s[%p]", __FUNCTION__,
this));
263 NS_ENSURE_ARG_POINTER(aListener);
264 NS_ASSERTION(NS_IsMainThread(),
265 "sbGStreamerMediaInspector::RemoveJobProgressListener is main thread only!");
267 PRInt32 indexToRemove = mProgressListeners.IndexOf(aListener);
268 if (indexToRemove < 0) {
274 PRBool succeeded = mProgressListeners.RemoveObjectAt(indexToRemove);
275 NS_ENSURE_TRUE(succeeded, NS_ERROR_FAILURE);
282 sbGStreamerMediaInspector::OnJobProgress()
284 TRACE((
"%s[%p]", __FUNCTION__,
this));
285 NS_ASSERTION(NS_IsMainThread(),
286 "sbGStreamerMediaInspector::OnJobProgress is main thread only!");
289 for (PRInt32
i = mProgressListeners.Count() - 1;
i >= 0; --
i) {
291 mProgressListeners[
i]->OnJobProgress(
this);
297 sbGStreamerMediaInspector::HandleErrorMessage(GstMessage *
message)
299 TRACE((
"%s[%p]", __FUNCTION__,
this));
300 GError *gerror = NULL;
305 gst_message_parse_error(message, &gerror, &debug);
307 mErrorMessages.AppendElement(
308 NS_ConvertUTF8toUTF16(nsDependentCString(gerror->message)));
310 g_error_free (gerror);
313 nsresult rv = CompleteInspection();
314 NS_ENSURE_SUCCESS (rv, );
323 sbGStreamerMediaInspector::GetMediaFormat(
sbIMediaFormat **_retval)
325 TRACE((
"%s[%p]", __FUNCTION__,
this));
326 NS_ENSURE_ARG_POINTER (_retval);
329 nsresult rv = CallQueryInterface(mMediaFormat.get(), _retval);
330 NS_ENSURE_SUCCESS (rv, rv);
333 return NS_ERROR_NOT_AVAILABLE;
340 sbGStreamerMediaInspector::InspectMediaURI(
const nsAString & aURI,
343 TRACE((
"%s[%p]", __FUNCTION__,
this));
344 NS_ENSURE_ARG_POINTER (_retval);
346 nsresult rv = NS_ERROR_UNEXPECTED;
347 PRBool processed = PR_FALSE;
348 PRBool isMainThread = NS_IsMainThread();
350 nsCOMPtr<nsIThread>
target;
352 rv = NS_GetMainThread(getter_AddRefs(target));
353 NS_ENSURE_SUCCESS(rv, rv);
356 NS_ASSERTION(!isMainThread,
357 "Synchronous InspectMedia is background-thread only");
362 rv = InspectMediaURIAsync (aURI);
363 NS_ENSURE_SUCCESS(rv, rv);
365 while (PR_AtomicAdd (&mFinished, 0) == 0)
374 if (isMainThread && target) {
375 rv = target->ProcessNextEvent(PR_FALSE, &processed);
376 NS_ENSURE_SUCCESS(rv, rv);
383 if (mIsPaused && mMediaFormat) {
384 rv = CallQueryInterface(mMediaFormat.get(), _retval);
385 NS_ENSURE_SUCCESS (rv, rv);
392 return NS_ERROR_NOT_AVAILABLE;
397 sbGStreamerMediaInspector::InspectMedia(
sbIMediaItem *aMediaItem,
400 TRACE((
"%s[%p]", __FUNCTION__,
this));
401 NS_ENSURE_ARG_POINTER (aMediaItem);
402 NS_ENSURE_ARG_POINTER (_retval);
408 nsresult rv = aMediaItem->GetProperty(
410 NS_ENSURE_SUCCESS (rv, rv);
413 return InspectMediaURI(sourceURI, _retval);
417 sbGStreamerMediaInspector::InspectMediaURIAsync(
const nsAString & aURI)
419 TRACE((
"%s[%p]", __FUNCTION__,
this));
424 nsresult rv = StartTimeoutTimer();
425 NS_ENSURE_SUCCESS (rv, rv);
430 rv = PausePipeline();
431 NS_ENSURE_SUCCESS (rv, rv);
437 sbGStreamerMediaInspector::InspectMediaAsync(
sbIMediaItem *aMediaItem)
439 TRACE((
"%s[%p]", __FUNCTION__,
this));
440 NS_ENSURE_ARG_POINTER (aMediaItem);
446 nsresult rv = aMediaItem->GetProperty(
448 NS_ENSURE_SUCCESS (rv, rv);
451 return InspectMediaURIAsync(sourceURI);
455 sbGStreamerMediaInspector::CompleteInspection()
457 nsresult rv = StopTimeoutTimer();
458 NS_ENSURE_SUCCESS (rv, rv);
462 rv = ProcessPipelineForInfo();
463 NS_ENSURE_SUCCESS (rv, rv);
479 NS_ENSURE_SUCCESS (rv, rv);
485 sbGStreamerMediaInspector::StartTimeoutTimer()
487 TRACE((
"%s[%p]", __FUNCTION__,
this));
493 NS_ENSURE_SUCCESS(rv, rv);
495 mTimeoutTimer->InitWithCallback(
this,
497 nsITimer::TYPE_ONE_SHOT);
503 sbGStreamerMediaInspector::StopTimeoutTimer()
505 TRACE((
"%s[%p]", __FUNCTION__,
this));
507 mTimeoutTimer->Cancel();
508 mTimeoutTimer = nsnull;
517 sbGStreamerMediaInspector::Notify(nsITimer *aTimer)
519 TRACE((
"%s[%p]", __FUNCTION__,
this));
520 NS_ENSURE_ARG_POINTER(aTimer);
522 nsresult rv = CompleteInspection();
523 NS_ENSURE_SUCCESS (rv, rv);
531 sbGStreamerMediaInspector::StopPipeline()
533 TRACE((
"%s[%p]", __FUNCTION__,
this));
536 rv = sbGStreamerPipeline::StopPipeline();
537 NS_ENSURE_SUCCESS (rv, rv);
540 rv = OnJobProgress();
541 NS_ENSURE_SUCCESS (rv, rv);
543 rv = CleanupPipeline();
544 NS_ENSURE_SUCCESS (rv, rv);
550 sbGStreamerMediaInspector::CleanupPipeline()
554 g_object_unref (mDecodeBin);
558 g_object_unref (mVideoSrc);
562 g_object_unref (mAudioSrc);
565 if (mAudioDecoderSink) {
566 g_object_unref (mAudioDecoderSink);
567 mAudioDecoderSink = NULL;
569 if (mVideoDecoderSink) {
570 g_object_unref (mVideoDecoderSink);
571 mVideoDecoderSink = NULL;
574 g_object_unref (mDemuxerSink);
582 sbGStreamerMediaInspector::ResetStatus()
585 mFinished = PR_FALSE;
586 mIsPaused = PR_FALSE;
587 mTooComplexForCurrentImplementation = PR_FALSE;
591 sbGStreamerMediaInspector::BuildPipeline()
593 TRACE((
"%s[%p]", __FUNCTION__,
this));
611 mPipeline = gst_pipeline_new (
"media-inspector-pipeline");
613 nsCString
uri = NS_ConvertUTF16toUTF8 (mSourceURI);
614 GstElement *src = gst_element_make_from_uri (GST_URI_SRC,
615 uri.BeginReading(),
"uri-source");
619 return NS_ERROR_FAILURE;
622 mDecodeBin = gst_element_factory_make (
"decodebin2", NULL);
624 gst_object_ref (mDecodeBin);
625 gst_object_sink (mDecodeBin);
630 g_signal_connect (mDecodeBin,
"pad-added",
631 G_CALLBACK (decodebin_pad_added_cb),
this);
633 gst_bin_add_many (GST_BIN (
mPipeline), src, mDecodeBin, NULL);
635 GstPad *srcpad = gst_element_get_pad (src,
"src");
636 GstPad *sinkpad = gst_element_get_pad (mDecodeBin,
"sink");
638 gst_pad_link (srcpad, sinkpad);
640 g_object_unref (srcpad);
641 g_object_unref (sinkpad);
649 sbGStreamerMediaInspector::PadAdded(GstPad *srcpad)
651 TRACE((
"%s[%p]", __FUNCTION__,
this));
658 sbGstCaps caps = gst_pad_get_caps (srcpad);
659 GstStructure *structure = gst_caps_get_structure (caps, 0);
660 const gchar *
name = gst_structure_get_name (structure);
661 bool isVideo = g_str_has_prefix (name,
"video/");
662 bool isAudio = g_str_has_prefix (name,
"audio/");
664 if (isAudio && !mAudioSrc) {
665 GstElement *queue = gst_element_factory_make (
"queue",
"audio-queue");
666 GstElement *fakesink = gst_element_factory_make (
"fakesink",
"audio-sink");
668 gst_bin_add_many (GST_BIN (
mPipeline), queue, fakesink, NULL);
669 gst_element_sync_state_with_parent (queue);
670 gst_element_sync_state_with_parent (fakesink);
672 GstPad *sinkpad = gst_element_get_pad (queue,
"sink");
674 gst_pad_link (srcpad, sinkpad);
675 g_object_unref (sinkpad);
677 gst_element_link (queue, fakesink);
679 GstPad *fakesinkpad = gst_element_get_pad (fakesink,
"sink");
680 gst_pad_add_event_probe (fakesinkpad,
681 G_CALLBACK (fakesink_audio_event_cb),
this);
683 g_object_unref (fakesinkpad);
685 mAudioSrc = GST_PAD (gst_object_ref (srcpad));
687 else if (isVideo && !mVideoSrc) {
688 GstElement *queue = gst_element_factory_make (
"queue",
"video-queue");
689 GstElement *fakesink = gst_element_factory_make (
"fakesink",
"video-sink");
691 gst_bin_add_many (GST_BIN (
mPipeline), queue, fakesink, NULL);
692 gst_element_sync_state_with_parent (queue);
693 gst_element_sync_state_with_parent (fakesink);
695 GstPad *sinkpad = gst_element_get_pad (queue,
"sink");
697 gst_pad_link (srcpad, sinkpad);
698 g_object_unref (sinkpad);
700 gst_element_link (queue, fakesink);
702 GstPad *fakesinkpad = gst_element_get_pad (fakesink,
"sink");
703 gst_pad_add_event_probe (fakesinkpad,
704 G_CALLBACK (fakesink_video_event_cb),
this);
706 g_object_unref (fakesinkpad);
708 mVideoSrc = GST_PAD (gst_object_ref (srcpad));
718 sbGStreamerMediaInspector::FakesinkEvent(GstPad *srcpad, GstEvent *
event,
721 TRACE((
"%s[%p]", __FUNCTION__,
this));
724 if ((isAudio && mAudioBitRate) || (!isAudio && mVideoBitRate))
729 switch (GST_EVENT_TYPE (event)) {
730 case GST_EVENT_TAG: {
731 GstTagList *list = NULL;
733 gst_event_parse_tag (event, &list);
734 if (list && !gst_tag_list_is_empty (list)) {
735 gst_tag_list_get_uint (list, GST_TAG_BITRATE, &bitrate);
737 gst_tag_list_get_uint (list, GST_TAG_NOMINAL_BITRATE, &bitrate);
747 mAudioBitRate = bitrate;
749 mVideoBitRate = bitrate;
756 sbGStreamerMediaInspector::HandleStateChangeMessage(GstMessage *message)
758 TRACE((
"%s[%p]", __FUNCTION__,
this));
764 if (GST_IS_PIPELINE (message->src))
766 GstState oldstate, newstate, pendingstate;
767 gst_message_parse_state_changed (message,
768 &oldstate, &newstate, &pendingstate);
770 if (pendingstate == GST_STATE_VOID_PENDING &&
771 newstate == GST_STATE_PAUSED)
774 nsresult rv = CompleteInspection();
775 NS_ENSURE_SUCCESS (rv, );
781 sbGStreamerMediaInspector::ProcessPipelineForInfo()
783 TRACE((
"%s[%p]", __FUNCTION__,
this));
790 GstIterator *it = gst_bin_iterate_recurse (GST_BIN (mDecodeBin));
791 gboolean
done = FALSE;
796 switch (gst_iterator_next (it, &element)) {
797 case GST_ITERATOR_OK:
798 rv = InspectorateElement (GST_ELEMENT (element));
799 gst_object_unref (element);
800 if (NS_FAILED (rv)) {
804 case GST_ITERATOR_DONE:
807 case GST_ITERATOR_RESYNC:
808 gst_iterator_resync (it);
810 case GST_ITERATOR_ERROR:
812 rv = NS_ERROR_FAILURE;
817 gst_iterator_free (it);
819 NS_ENSURE_SUCCESS (rv, rv);
823 GstElement *audioDecoder = GST_ELEMENT (gst_pad_get_parent (audioSrcPad));
824 GstElementFactory *factory = gst_element_get_factory (audioDecoder);
825 const gchar *klass = gst_element_factory_get_klass (factory);
827 if (strstr (klass,
"Decoder")) {
829 mAudioDecoderSink = gst_element_get_pad (audioDecoder,
"sink");
832 g_object_unref (audioSrcPad);
833 g_object_unref (audioDecoder);
838 GstElement *videoDecoder = GST_ELEMENT (gst_pad_get_parent (videoSrcPad));
839 GstElementFactory *factory = gst_element_get_factory (videoDecoder);
840 const gchar *klass = gst_element_factory_get_klass (factory);
842 if (strstr (klass,
"Decoder")) {
844 mVideoDecoderSink = gst_element_get_pad (videoDecoder,
"sink");
847 g_object_unref (videoSrcPad);
848 g_object_unref (videoDecoder);
851 nsCOMPtr<sbIMediaFormatAudio> audioFormat;
852 nsCOMPtr<sbIMediaFormatVideo> videoFormat;
853 nsCOMPtr<sbIMediaFormatContainerMutable> containerFormat;
855 if (mTooComplexForCurrentImplementation) {
860 NS_ENSURE_SUCCESS (rv, rv);
862 containerFormat->SetContainerType(NS_LITERAL_STRING(
"video/x-too-complex"));
864 else if (mDemuxerSink) {
869 NS_ENSURE_SUCCESS (rv, rv);
871 sbGstCaps caps = gst_pad_get_negotiated_caps (mDemuxerSink);
872 GstStructure *structure = gst_caps_get_structure (caps, 0);
876 NS_ENSURE_SUCCESS (rv, rv);
878 rv = containerFormat->SetContainerType (NS_ConvertUTF8toUTF16(mimeType));
879 NS_ENSURE_SUCCESS (rv, rv);
882 rv = ProcessContainerProperties(containerFormat, structure);
883 NS_ENSURE_SUCCESS (rv, rv);
887 rv = ProcessVideo(getter_AddRefs(videoFormat));
888 NS_ENSURE_SUCCESS (rv, rv);
892 rv = ProcessAudio(getter_AddRefs(audioFormat));
893 NS_ENSURE_SUCCESS (rv, rv);
897 NS_ENSURE_SUCCESS (rv, rv);
899 rv = mMediaFormat->SetContainer (containerFormat);
900 NS_ENSURE_SUCCESS (rv, rv);
901 rv = mMediaFormat->SetAudioStream (audioFormat);
902 NS_ENSURE_SUCCESS (rv, rv);
903 rv = mMediaFormat->SetVideoStream (videoFormat);
913 GstStructure *structure = gst_caps_get_structure (caps, 0);
916 if (gst_structure_get_int (structure,
"width", &width) &&
917 gst_structure_get_int (structure,
"height", &height))
919 rv = format->SetVideoWidth (width);
920 NS_ENSURE_SUCCESS (rv, rv);
921 rv = format->SetVideoHeight (height);
922 NS_ENSURE_SUCCESS (rv, rv);
925 const GValue* framerate = gst_structure_get_value(structure,
"framerate");
926 gint framerateN, framerateD;
928 framerateN = gst_value_get_fraction_numerator(framerate);
929 framerateD = gst_value_get_fraction_denominator(framerate);
937 rv = format->SetVideoFrameRate (framerateN, framerateD);
938 NS_ENSURE_SUCCESS (rv, rv);
940 const GValue* par = gst_structure_get_value(structure,
"pixel-aspect-ratio");
943 parN = gst_value_get_fraction_numerator(par);
944 parD = gst_value_get_fraction_denominator(par);
952 rv = format->SetVideoPAR (parN, parD);
953 NS_ENSURE_SUCCESS (rv, rv);
959 sbGStreamerMediaInspector::ProcessContainerProperties (
961 GstStructure *aStructure)
963 TRACE((
"%s[%p]", __FUNCTION__,
this));
965 NS_ENSURE_ARG_POINTER (aContainerFormat);
966 NS_ENSURE_ARG_POINTER (aStructure);
969 const gchar *name = gst_structure_get_name (aStructure);
970 nsCOMPtr<nsIWritablePropertyBag2> writableBag =
971 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/sbpropertybag;1", &rv);
972 NS_ENSURE_SUCCESS (rv, rv);
975 NS_ENSURE_SUCCESS (rv, rv);
977 if ( !strcmp (name,
"video/mpeg")) {
978 gboolean systemstream;
979 if ( gst_structure_get_boolean (aStructure,
"systemstream",
981 rv = writableBag->SetPropertyAsBool (
982 NS_LITERAL_STRING(
"systemstream"), systemstream);
983 NS_ENSURE_SUCCESS (rv, rv);
989 query = gst_query_new_duration (GST_FORMAT_TIME);
990 gboolean res = gst_element_query (
mPipeline, query);
994 gst_query_parse_duration (query, NULL, &duration);
996 gst_query_unref (query);
997 rv = writableBag->SetPropertyAsInt64 (
998 NS_LITERAL_STRING(
"duration"), duration);
999 NS_ENSURE_SUCCESS (rv, rv);
1003 rv = aContainerFormat->SetProperties (writableBag);
1004 NS_ENSURE_SUCCESS (rv, rv);
1010 sbGStreamerMediaInspector::ProcessVideoProperties (
1012 GstStructure *aStructure)
1014 TRACE((
"%s[%p]", __FUNCTION__,
this));
1016 NS_ENSURE_ARG_POINTER (aVideoFormat);
1017 NS_ENSURE_ARG_POINTER (aStructure);
1020 const gchar *name = gst_structure_get_name (aStructure);
1021 nsCOMPtr<nsIWritablePropertyBag2> writableBag =
1022 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/sbpropertybag;1", &rv);
1023 NS_ENSURE_SUCCESS (rv, rv);
1026 NS_ENSURE_SUCCESS (rv, rv);
1028 if ( !strcmp (name,
"video/mpeg")) {
1030 if ( gst_structure_get_int (aStructure,
"mpegversion", &mpegversion)) {
1031 rv = writableBag->SetPropertyAsInt32 (
1032 NS_LITERAL_STRING(
"mpegversion"), mpegversion);
1033 NS_ENSURE_SUCCESS (rv, rv);
1036 if (mpegversion == 4) {
1038 if ( gst_structure_get_int (aStructure,
"profile-level-id",
1040 rv = writableBag->SetPropertyAsInt32 (
1041 NS_LITERAL_STRING(
"profile-level-id"), levelid);
1042 NS_ENSURE_SUCCESS (rv, rv);
1047 else if ( !strcmp (name,
"video/x-h264")) {
1050 else if ( !strcmp (name,
"image/jpeg")) {
1051 gboolean interlaced;
1052 if ( gst_structure_get_boolean (aStructure,
"interlaced", &interlaced)) {
1053 rv = writableBag->SetPropertyAsBool (
1054 NS_LITERAL_STRING(
"interlaced"), interlaced);
1055 NS_ENSURE_SUCCESS (rv, rv);
1058 else if ( !strcmp (name,
"video/x-wmv")) {
1060 if ( gst_structure_get_int (aStructure,
"wmvversion", &wmvversion)) {
1061 rv = writableBag->SetPropertyAsInt32 (
1062 NS_LITERAL_STRING(
"wmvversion"), wmvversion);
1063 NS_ENSURE_SUCCESS (rv, rv);
1067 else if ( !strcmp (name,
"video/x-pn-realvideo")) {
1069 if ( gst_structure_get_int (aStructure,
"rmversion", &rmversion)) {
1070 rv = writableBag->SetPropertyAsInt32 (
1071 NS_LITERAL_STRING(
"rmversion"), rmversion);
1072 NS_ENSURE_SUCCESS (rv, rv);
1076 rv = aVideoFormat->SetProperties (writableBag);
1077 NS_ENSURE_SUCCESS (rv, rv);
1085 TRACE((
"%s[%p]", __FUNCTION__,
this));
1087 NS_ENSURE_ARG_POINTER (aVideoFormat);
1088 NS_ENSURE_STATE (mVideoSrc);
1091 nsCOMPtr<sbIMediaFormatVideoMutable> format =
1093 NS_ENSURE_SUCCESS (rv, rv);
1097 sbGstCaps caps = gst_pad_get_negotiated_caps (mVideoSrc);
1098 rv = ProcessVideoCaps(format, caps);
1099 NS_ENSURE_SUCCESS (rv, rv);
1101 rv = format->SetBitRate(mVideoBitRate);
1102 NS_ENSURE_SUCCESS (rv, rv);
1104 if (mVideoDecoderSink) {
1110 sbGstCaps videoCaps = gst_pad_get_negotiated_caps (mVideoDecoderSink);
1111 GstStructure *structure = gst_caps_get_structure (videoCaps, 0);
1115 NS_ENSURE_SUCCESS (rv, rv);
1117 rv = format->SetVideoType (NS_ConvertUTF8toUTF16(mimeType));
1118 NS_ENSURE_SUCCESS (rv, rv);
1121 rv = ProcessVideoProperties(format, structure);
1122 NS_ENSURE_SUCCESS (rv, rv);
1128 rv = format->SetVideoType (NS_LITERAL_STRING (
"video/x-raw"));
1129 NS_ENSURE_SUCCESS (rv, rv);
1134 rv = CallQueryInterface(format.get(), aVideoFormat);
1135 NS_ENSURE_SUCCESS (rv, rv);
1142 sbGStreamerMediaInspector::ProcessAudioProperties (
1144 GstStructure *aStructure)
1146 TRACE((
"%s[%p]", __FUNCTION__,
this));
1148 NS_ENSURE_ARG_POINTER (aAudioFormat);
1149 NS_ENSURE_ARG_POINTER (aStructure);
1152 const gchar *name = gst_structure_get_name (aStructure);
1153 nsCOMPtr<nsIWritablePropertyBag2> writableBag =
1154 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/sbpropertybag;1", &rv);
1155 NS_ENSURE_SUCCESS (rv, rv);
1158 NS_ENSURE_SUCCESS (rv, rv);
1160 if ( !strcmp (name,
"audio/mpeg")) {
1162 if ( gst_structure_get_int (aStructure,
"mpegversion", &mpegversion)) {
1163 rv = writableBag->SetPropertyAsInt32 (
1164 NS_LITERAL_STRING(
"mpegversion"), mpegversion);
1165 NS_ENSURE_SUCCESS (rv, rv);
1168 if (mpegversion == 1) {
1170 if ( gst_structure_get_int (aStructure,
"layer",
1172 rv = writableBag->SetPropertyAsInt32 (
1173 NS_LITERAL_STRING(
"layer"), layer);
1174 NS_ENSURE_SUCCESS (rv, rv);
1177 else if (mpegversion == 2 || mpegversion == 4) {
1182 else if ( !strcmp (name,
"audio/x-adpcm")) {
1183 const gchar *layout = gst_structure_get_string (aStructure,
"layout");
1185 rv = writableBag->SetPropertyAsAString (
1186 NS_LITERAL_STRING(
"layout"), NS_ConvertUTF8toUTF16(layout));
1187 NS_ENSURE_SUCCESS (rv, rv);
1190 else if ( !strcmp (name,
"audio/x-wma")) {
1192 if (gst_structure_get_int (aStructure,
"wmaversion", &wmaversion)) {
1193 rv = writableBag->SetPropertyAsInt32 (
1194 NS_LITERAL_STRING(
"wmaversion"), wmaversion);
1195 NS_ENSURE_SUCCESS (rv, rv);
1199 else if ( !strcmp (name,
"audio/x-pn-realaudio")) {
1201 if (gst_structure_get_int (aStructure,
"raversion", &raversion)) {
1202 rv = writableBag->SetPropertyAsInt32 (
1203 NS_LITERAL_STRING(
"raversion"), raversion);
1204 NS_ENSURE_SUCCESS (rv, rv);
1213 static const gchar *
const INTERESTING_AUDIO_PROPS [] = {
1225 INTERESTING_AUDIO_PROPS,
1226 NS_ARRAY_LENGTH(INTERESTING_AUDIO_PROPS));
1227 NS_ENSURE_SUCCESS (rv, rv);
1229 rv = aAudioFormat->SetProperties (writableBag);
1230 NS_ENSURE_SUCCESS (rv, rv);
1238 TRACE((
"%s[%p]", __FUNCTION__,
this));
1240 NS_ENSURE_ARG_POINTER (aAudioFormat);
1241 NS_ENSURE_STATE (mAudioSrc);
1244 nsCOMPtr<sbIMediaFormatAudioMutable> format =
1246 NS_ENSURE_SUCCESS (rv, rv);
1250 sbGstCaps caps = gst_pad_get_negotiated_caps (mAudioSrc);
1251 GstStructure *structure = gst_caps_get_structure (caps, 0);
1253 gint rate, channels;
1254 if (gst_structure_get_int (structure,
"rate", &rate)) {
1255 format->SetSampleRate (rate);
1257 if (gst_structure_get_int (structure,
"channels", &channels)) {
1258 format->SetChannels (channels);
1261 rv = format->SetBitRate(mAudioBitRate);
1262 NS_ENSURE_SUCCESS (rv, rv);
1264 if (mAudioDecoderSink) {
1270 sbGstCaps audioCaps = gst_pad_get_negotiated_caps (mAudioDecoderSink);
1271 structure = gst_caps_get_structure (audioCaps, 0);
1275 NS_ENSURE_SUCCESS (rv, rv);
1277 rv = format->SetAudioType (NS_ConvertUTF8toUTF16(mimeType));
1278 NS_ENSURE_SUCCESS (rv, rv);
1284 format->SetAudioType (NS_LITERAL_STRING (
"audio/x-raw"));
1288 rv = ProcessAudioProperties(format, structure);
1289 NS_ENSURE_SUCCESS (rv, rv);
1291 rv = CallQueryInterface(format.get(), aAudioFormat);
1292 NS_ENSURE_SUCCESS (rv, rv);
1298 sbGStreamerMediaInspector::InspectorateElement (GstElement *element)
1300 TRACE((
"%s[%p]", __FUNCTION__,
this));
1302 GstElementFactory *factory = gst_element_get_factory (element);
1304 const gchar *klass = gst_element_factory_get_klass (factory);
1306 if (strstr (klass,
"Demuxer")) {
1310 mTooComplexForCurrentImplementation = PR_TRUE;
1313 mDemuxerSink = gst_element_get_pad (element,
"sink");
1321 sbGStreamerMediaInspector::fakesink_audio_event_cb (GstPad * pad,
1324 nsresult rv = inspector->FakesinkEvent(pad, event, PR_TRUE);
1325 NS_ENSURE_SUCCESS (rv, );
1329 sbGStreamerMediaInspector::fakesink_video_event_cb (GstPad * pad,
1332 nsresult rv = inspector->FakesinkEvent(pad, event, PR_FALSE);
1333 NS_ENSURE_SUCCESS (rv, );
1337 sbGStreamerMediaInspector::decodebin_pad_added_cb (GstElement * uridecodebin,
1340 nsresult rv = inspector->PadAdded(pad);
1341 NS_ENSURE_SUCCESS (rv, );
function succeeded(ch, cx, status, data)
Generic interface for exposing long running jobs to the UI.
const unsigned short STATUS_SUCCEEDED
Constant indicating that the job has completed.
virtual void HandleErrorMessage(GstMessage *message)
const sbCreateProxiedComponent do_ProxiedCreateInstance(const nsCID &aCID, nsresult *error=0)
const unsigned short STATUS_RUNNING
Constant indicating that the job is active.
virtual void HandleStateChangeMessage(GstMessage *message)
Songbird String Bundle Definitions.
nsresult SBGetLocalizedString(nsAString &aString, const nsAString &aKey, const nsAString &aDefault, class nsIStringBundle *aStringBundle)
void SetPipelineOp(GStreamer::pipelineOp_t aPipelineOp)
Implemented to receive notifications from sbIJobProgress interfaces.
#define SB_PROPERTY_CONTENTURL
const unsigned short STATUS_FAILED
Constant indicating that the job has completed with errors.
_getSelectedPageStyle s i