29 #include <nsIRunnable.h>
30 #include <nsINetUtil.h>
31 #include <nsIWritablePropertyBag.h>
33 #include <nsAutoPtr.h>
34 #include <nsThreadUtils.h>
52 static PRLogModuleInfo* gGStreamerMediacoreUtils =
53 PR_NewLogModule(
"sbGStreamerMediacoreUtils");
56 if (gGStreamerMediacoreUtils) \
57 PR_LOG(gGStreamerMediacoreUtils, PR_LOG_WARNING, args)
60 if (gGStreamerMediacoreUtils) \
61 PR_LOG(gGStreamerMediacore, PR_LOG_DEBUG, args)
107 #define SB_GN_PROP_EXTENDEDDATA "http://gracenote.com/pos/1.0#extendedData"
108 #define SB_GN_PROP_TAGID "http://gracenote.com/pos/1.0#tagId"
117 rv =
property->GetId(
id);
118 NS_ENSURE_SUCCESS(rv,PR_FALSE);
120 rv =
property->GetValue(value);
121 NS_ENSURE_SUCCESS(rv,PR_FALSE);
124 #define TAG_CONVERT_STRING(sbname,gstname) \
125 if (id == NS_LITERAL_STRING (sbname)) { \
126 NS_ConvertUTF16toUTF8 utf8value(value); \
127 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, (gchar *)gstname, \
128 utf8value.BeginReading(), NULL); \
132 #define TAG_CONVERT_UINT(sbname,gstname) \
133 if (id == NS_LITERAL_STRING (sbname)) { \
134 unsigned int gstvalue = value.ToInteger(&rv); \
135 NS_ENSURE_SUCCESS (rv, PR_FALSE); \
136 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, (gchar *)gstname, \
159 int year = value.ToInteger(&rv);
160 NS_ENSURE_SUCCESS (rv, PR_FALSE);
163 g_date_set_year (date, year);
164 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, (gchar *)GST_TAG_DATE,
171 int durationMillis = value.ToInteger(&rv);
172 guint64 durationNanos;
173 NS_ENSURE_SUCCESS (rv, PR_FALSE);
174 durationNanos = durationMillis * GST_MSECOND;
175 gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, (gchar *)GST_TAG_DURATION,
176 durationNanos, NULL);
195 nsCOMPtr<nsISimpleEnumerator> propertyEnum;
200 if (properties == nsnull)
203 tags = gst_tag_list_new();
204 rv = properties->Enumerate(getter_AddRefs(propertyEnum));
205 NS_ENSURE_SUCCESS(rv, NULL);
207 while (NS_SUCCEEDED (propertyEnum->HasMoreElements(&more)) && more) {
208 nsCOMPtr<nsISupports>
next;
209 if (NS_SUCCEEDED(propertyEnum->GetNext(getter_AddRefs(next))) && next) {
210 nsCOMPtr<sbIProperty> property(do_QueryInterface(next));
214 LOG((
"Failed to convert property to tag"));
224 const gchar *
tag, gpointer user_data)
229 #define PROPERTY_CONVERT_STRING(propname, tagname) \
230 if (!strcmp(tag, tagname)) { \
232 if (gst_tag_list_get_string (taglist, tag, &tagvalue)) { \
233 propArray->AppendProperty(NS_LITERAL_STRING (propname), \
234 NS_ConvertUTF8toUTF16(tagvalue)); \
240 #define PROPERTY_CONVERT_UINT(propname, tagname, scale) \
241 if (!strcmp(tag, tagname)) { \
243 if (gst_tag_list_get_uint (taglist, tag, &tagvalue)) { \
244 nsString stringVal; \
245 stringVal.AppendInt(tagvalue / scale); \
246 propArray->AppendProperty(NS_LITERAL_STRING (propname), \
270 nsCOMPtr<sbIMutablePropertyArray> proparray = do_CreateInstance(
271 "@songbirdnest.com/Songbird/Properties/MutablePropertyArray;1", &rv);
272 NS_ENSURE_SUCCESS (rv, rv);
276 nsCOMPtr<sbIPropertyArray> props = do_QueryInterface(proparray, &rv);
277 NS_ENSURE_SUCCESS (rv, rv);
279 NS_ADDREF(*aPropertyArray = props);
291 gst_message_ref(msg);
301 mHandler->HandleMessage(mMessage);
306 GstMessage *mMessage;
307 nsRefPtr<sbGStreamerMessageHandler> mHandler;
325 NS_DispatchToMainThread(
event);
343 "mediacore.error.resource_not_found"},
346 "mediacore.error.read_failed"},
349 "mediacore.error.write_failed"},
352 "mediacore.error.read_open_failed"},
355 "mediacore.error.write_open_failed"},
358 "mediacore.error.rw_open_failed"},
361 "mediacore.error.close_failed"},
364 "mediacore.error.seek_failed"},
367 "mediacore.error.out_of_space"},
372 static const struct errMap CoreErrorMap[] = {
375 static const struct errMap LibraryErrorMap[] = {
382 "mediacore.error.type_not_found"},
385 "mediacore.error.wrong_type"},
388 "mediacore.error.codec_not_found"},
391 "mediacore.error.decode_for_transcode_failed" },
394 "mediacore.error.decode_failed"},
397 "mediacore.error.encode_failed"},
400 "mediacore.error.failure_during_transcode"},
403 "mediacore.error.failure"},
406 "mediacore.error.decrypt"},
414 nsString errorMessage;
415 nsRefPtr<sbMediacoreError> error;
417 const char *stringName = NULL;
421 NS_ENSURE_TRUE (error, NS_ERROR_OUT_OF_MEMORY);
423 const struct errMap *map = NULL;
426 if (gerror->domain == GST_CORE_ERROR) {
428 mapLength = NS_ARRAY_LENGTH(CoreErrorMap);
430 else if (gerror->domain == GST_LIBRARY_ERROR) {
431 map = LibraryErrorMap;
432 mapLength = NS_ARRAY_LENGTH(LibraryErrorMap);
436 if (gerror->domain == GST_RESOURCE_ERROR) {
438 mapLength = NS_ARRAY_LENGTH(ResourceErrorMap);
440 else if (gerror->domain == GST_STREAM_ERROR) {
442 mapLength = NS_ARRAY_LENGTH(StreamErrorMap);
449 for (
int i = 0;
i < mapLength;
i++) {
466 if (bestMatch == -1 && match != -1) {
470 if (bestMatch != -1) {
478 nsTArray<nsString> params;
479 if (aResource.IsEmpty()) {
480 params.AppendElement(bundle.
Get(
"mediacore.error.unknown_resource"));
484 nsCOMPtr<nsINetUtil> netUtil =
485 do_CreateInstance(
"@mozilla.org/network/util;1", &rv);
486 NS_ENSURE_SUCCESS(rv, rv);
487 nsCString unescapedResource;
488 rv = netUtil->UnescapeString(NS_ConvertUTF16toUTF8(aResource),
489 nsINetUtil::ESCAPE_ALL, unescapedResource);
490 NS_ENSURE_SUCCESS(rv, rv);
492 params.AppendElement(NS_ConvertUTF8toUTF16(unescapedResource));
495 errorMessage = bundle.
Format(stringName, params);
498 if (errorMessage.IsEmpty()) {
501 CopyUTF8toUTF16(nsDependentCString(gerror->message), errorMessage);
504 rv = error->Init(errorCode, errorMessage);
505 NS_ENSURE_SUCCESS (rv, rv);
507 NS_ADDREF (*_retval = error);
521 const GList *templates;
523 GstElementFactory * factory;
527 if (!GST_IS_ELEMENT_FACTORY (feature))
530 factory = GST_ELEMENT_FACTORY (feature);
532 klass = gst_element_factory_get_klass (factory);
534 if (strstr (klass, data->
type) == NULL) {
541 name = gst_plugin_feature_get_name (feature);
542 if (strstr (name,
"ffmux") != NULL ||
543 strstr (name,
"ffenc") != NULL)
546 templates = gst_element_factory_get_static_pad_templates (factory);
547 for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
548 GstStaticPadTemplate *templ = (GstStaticPadTemplate *)(walk->data);
551 if (templ->direction == GST_PAD_SRC) {
552 GstCaps *template_caps = gst_static_caps_get (&templ->static_caps);
555 intersect = gst_caps_intersect (template_caps, data->
srccaps);
556 gst_caps_unref (template_caps);
558 if (!gst_caps_is_empty (intersect)) {
560 gst_caps_unref (intersect);
563 gst_caps_unref (intersect);
576 caps = gst_caps_from_string (srcCapsString);
581 gst_caps_unref(caps);
591 GstElementFactory *bestfactory = NULL;
597 data.
type = typeName;
599 list = gst_default_registry_feature_filter (
602 for (walk = list; walk; walk = g_list_next (walk)) {
603 GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
604 guint rank = gst_plugin_feature_get_rank (GST_PLUGIN_FEATURE (factory));
607 if (!bestfactory || rank > bestrank) {
608 bestfactory = factory;
616 return gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (bestfactory));
623 G_TYPE_STRING,
"GN TagID",
"Gracenote Tag ID", NULL);
625 G_TYPE_STRING,
"GN ExtData",
"Gracenote Extended Data", NULL);
631 nsCOMPtr<nsISimpleEnumerator> enumerator;
632 nsresult rv = props->GetEnumerator (getter_AddRefs (enumerator));
633 NS_ENSURE_SUCCESS (rv, rv);
636 while (NS_SUCCEEDED (enumerator->HasMoreElements (&hasMore)) && hasMore) {
637 nsCOMPtr<nsISupports>
next;
638 rv = enumerator->GetNext (getter_AddRefs (next));
639 NS_ENSURE_SUCCESS (rv, rv);
641 nsCOMPtr<nsIProperty>
property = do_QueryInterface (next, &rv);
642 NS_ENSURE_SUCCESS (rv, rv);
644 nsString propertyName;
645 rv =
property->GetName (propertyName);
646 NS_ENSURE_SUCCESS (rv, rv);
648 nsCOMPtr<nsIVariant> propertyVariant;
649 rv =
property->GetValue (getter_AddRefs (propertyVariant));
650 NS_ENSURE_SUCCESS (rv, rv);
652 NS_ConvertUTF16toUTF8 propertyNameUTF8 (propertyName);
654 GParamSpec *paramSpec = g_object_class_find_property (
655 G_OBJECT_GET_CLASS (element),
656 propertyNameUTF8.BeginReading());
659 LOG((
"No such property %s on element", propertyNameUTF8.BeginReading()));
660 return NS_ERROR_FAILURE;
663 PRUint16 variantType;
664 rv = propertyVariant->GetDataType(&variantType);
665 NS_ENSURE_SUCCESS (rv, rv);
667 GValue propertyValue = { 0 };
668 if (paramSpec->value_type == G_TYPE_INT)
671 rv = propertyVariant->GetAsInt32 (&val);
672 NS_ENSURE_SUCCESS (rv, rv);
673 g_value_init (&propertyValue, G_TYPE_INT);
674 g_value_set_int (&propertyValue, val);
676 else if (paramSpec->value_type == G_TYPE_UINT)
679 rv = propertyVariant->GetAsUint32 (&val);
680 NS_ENSURE_SUCCESS (rv, rv);
681 g_value_init (&propertyValue, G_TYPE_UINT);
682 g_value_set_uint (&propertyValue, val);
684 else if (paramSpec->value_type == G_TYPE_UINT64)
687 rv = propertyVariant->GetAsUint64 (&val);
688 NS_ENSURE_SUCCESS (rv, rv);
689 g_value_init (&propertyValue, G_TYPE_UINT64);
690 g_value_set_uint64 (&propertyValue, val);
692 else if (paramSpec->value_type == G_TYPE_INT64)
695 rv = propertyVariant->GetAsInt64 (&val);
696 NS_ENSURE_SUCCESS (rv, rv);
697 g_value_init (&propertyValue, G_TYPE_INT64);
698 g_value_set_int64 (&propertyValue, val);
700 else if (paramSpec->value_type == G_TYPE_BOOLEAN)
703 rv = propertyVariant->GetAsBool (&val);
704 NS_ENSURE_SUCCESS (rv, rv);
705 g_value_init (&propertyValue, G_TYPE_BOOLEAN);
706 g_value_set_boolean (&propertyValue, val);
708 else if (paramSpec->value_type == G_TYPE_FLOAT)
711 rv = propertyVariant->GetAsFloat (&val);
712 NS_ENSURE_SUCCESS (rv, rv);
713 g_value_init (&propertyValue, G_TYPE_FLOAT);
714 g_value_set_float (&propertyValue, val);
716 else if (paramSpec->value_type == G_TYPE_DOUBLE)
719 rv = propertyVariant->GetAsDouble (&val);
720 NS_ENSURE_SUCCESS (rv, rv);
721 g_value_init (&propertyValue, G_TYPE_DOUBLE);
722 g_value_set_float (&propertyValue, val);
724 else if (paramSpec->value_type == G_TYPE_STRING)
727 rv = propertyVariant->GetAsACString(val);
728 NS_ENSURE_SUCCESS (rv, rv);
729 g_value_init (&propertyValue, G_TYPE_STRING);
730 g_value_set_string (&propertyValue, val.BeginReading());
732 else if (G_TYPE_IS_ENUM (paramSpec->value_type))
735 rv = propertyVariant->GetAsUint32 (&val);
736 NS_ENSURE_SUCCESS (rv, rv);
737 g_value_init (&propertyValue, paramSpec->value_type);
738 g_value_set_enum (&propertyValue, val);
741 LOG((
"Unsupported property type"));
742 return NS_ERROR_FAILURE;
745 g_object_set_property (G_OBJECT (element),
746 propertyNameUTF8.BeginReading(),
748 g_value_unset (&propertyValue);
798 nsCString result(aMimeType);
800 for (
unsigned int i = 0;
i < NS_ARRAY_LENGTH (sb_gst_caps_map);
i++) {
801 if (sb_gst_caps_map[
i].
map_type == aType &&
802 aMimeType.EqualsLiteral(sb_gst_caps_map[
i].
mime_type))
804 result.AssignLiteral(sb_gst_caps_map[i].
gst_name);
818 GstCaps *caps = gst_caps_from_string(name.BeginReading());
826 NS_ENSURE_ARG_POINTER(aCaps);
827 GstStructure *structure = gst_caps_get_structure (aCaps, 0);
828 NS_ENSURE_STATE(structure);
831 const gchar *capsName = gst_structure_get_name (structure);
832 NS_ENSURE_STATE(capsName);
835 if (!strcmp(capsName,
"video/quicktime")) {
836 const gchar *variant = gst_structure_get_string (structure,
"variant");
838 if (!strcmp(variant,
"3gpp"))
839 aMimeType.AssignLiteral(
"video/3gpp");
840 else if (!strcmp(variant,
"iso"))
841 aMimeType.AssignLiteral(
"video/mp4");
843 aMimeType.AssignLiteral(
"video/quicktime");
847 aMimeType.AssignLiteral(
"video/quicktime");
851 else if (!strcmp(capsName,
"audio/mpeg")) {
853 if (gst_structure_get_int (structure,
"mpegversion", &mpegversion) &&
855 aMimeType.AssignLiteral(
"audio/aac");
858 aMimeType.AssignLiteral(
"audio/mpeg");
863 for (
unsigned int i = 0;
i < NS_ARRAY_LENGTH (sb_gst_caps_map);
i++)
865 if (!strcmp(capsName, sb_gst_caps_map[
i].
gst_name)) {
866 aMimeType.AssignLiteral(sb_gst_caps_map[
i].
mime_type);
872 aMimeType.AssignLiteral(capsName);
883 const gchar * fieldname = g_quark_to_string(aFieldId);
887 static_cast<nsIWritablePropertyBag2 *>(aUserData),
888 NS_ConvertASCIItoUTF16(fieldname),
890 NS_ENSURE_SUCCESS(rv, FALSE);
898 const GstStructure * aStructure,
899 const gchar *
const aDesiredFieldList[],
900 PRUint32 aFieldCount)
906 if (aDesiredFieldList) {
907 for (PRUint32
i = 0;
i < aFieldCount;
i++) {
908 const gchar * fieldname = aDesiredFieldList[
i];
909 const GValue *
value = gst_structure_get_value(aStructure, fieldname);
914 NS_ConvertASCIItoUTF16(fieldname),
916 NS_ENSURE_SUCCESS(rv, rv);
923 NS_ENSURE_TRUE(aFieldCount == 0, NS_ERROR_INVALID_ARG);
925 gboolean ok = gst_structure_foreach(aStructure,
_OnEachGValue, aPropertyBag);
926 NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
934 const nsAString & aProperty,
937 NS_ENSURE_ARG_POINTER(aPropertyBag);
940 GType type = G_VALUE_TYPE(aValue);
941 const gchar *asGstr = NULL;
948 asGboolean = g_value_get_boolean (aValue);
949 rv = aPropertyBag->SetPropertyAsBool(aProperty, asGboolean);
950 NS_ENSURE_SUCCESS (rv, rv);
954 asGint = g_value_get_int (aValue);
955 rv = aPropertyBag->SetPropertyAsInt32(aProperty, asGint);
956 NS_ENSURE_SUCCESS (rv, rv);
960 asGuint = g_value_get_uint (aValue);
961 rv = aPropertyBag->SetPropertyAsUint32(aProperty, asGuint);
962 NS_ENSURE_SUCCESS (rv, rv);
966 asGstr = g_value_get_string (aValue);
967 NS_ENSURE_TRUE(asGstr, NS_ERROR_UNEXPECTED);
968 rv = aPropertyBag->SetPropertyAsACString(aProperty, nsCString(asGstr));
969 NS_ENSURE_SUCCESS (rv, rv);
976 if (type == GST_TYPE_BUFFER) {
977 const GstBuffer * asGstBuffer = gst_value_get_buffer(aValue);
978 NS_ENSURE_TRUE(asGstBuffer, NS_ERROR_UNEXPECTED);
981 nsCOMPtr<nsIWritableVariant> asVariant =
982 do_CreateInstance(
"@mozilla.org/variant;1", &rv);
983 NS_ENSURE_SUCCESS (rv, rv);
984 rv = asVariant->SetAsArray(nsIDataType::VTYPE_UINT8,
986 GST_BUFFER_SIZE(asGstBuffer),
987 GST_BUFFER_DATA(asGstBuffer));
988 NS_ENSURE_SUCCESS (rv, rv);
992 nsCOMPtr<nsIWritablePropertyBag> bagV1 =
993 do_QueryInterface(aPropertyBag, &rv);
994 NS_ENSURE_SUCCESS (rv, rv);
995 rv = bagV1->SetProperty(aProperty, asVariant);
996 NS_ENSURE_SUCCESS (rv, rv);
1001 const gchar *typeName = g_type_name(type);
1002 LOG((
"Unexpected GType [%u %s] for [%s]",
1005 NS_LossyConvertUTF16toASCII(aProperty).
get()));
1006 #endif // #ifdef PR_LOGGING
1007 NS_ENSURE_TRUE(PR_FALSE, NS_ERROR_ILLEGAL_VALUE);
1018 GstPad *current = pad;
1019 g_object_ref(current);
1021 while (GST_IS_GHOST_PAD (current)) {
1022 ghost = GST_GHOST_PAD (current);
1023 GstPad *padToRelease = current;
1024 current = gst_ghost_pad_get_target (ghost);
1025 g_object_unref (padToRelease);
#define SB_PROPERTY_TOTALDISCS
#define SB_PROPERTY_ORIGINURL
nsString Get(const nsAString &aKey, const nsAString &aDefault=SBVoidString())
nsString Format(const nsAString &aKey, nsTArray< nsString > &aParams, const nsAString &aDefault=SBVoidString())
#define SB_PROPERTY_TOTALTRACKS
#define SB_PROPERTY_BITRATE
GStreamer::pipelineOp_t gstPipelineOp
An interface to carry around arrays of nsIProperty instances Note that implementations of the interfa...
const char * sbErrorMessageName
#define SB_PROPERTY_GENRE
this _dialogInput val(dateText)
NS_DECL_ISUPPORTS sbGstMessageEvent(GstMessage *msg, sbGStreamerMessageHandler *handler)
#define SB_PROPERTY_DURATION
#define SB_PROPERTY_COPYRIGHT
#define SB_PROPERTY_DISCNUMBER
ExtensionSchemeMatcher prototype match
#define SB_PROPERTY_ARTISTNAME
enum sbGstCapsMapType map_type
Songbird String Bundle Definitions.
StringArrayEnumerator prototype hasMore
#define SB_PROPERTY_ALBUMNAME
#define SB_PROPERTY_COMPOSERNAME
#define SB_PROPERTY_TRACKNAME
#define SB_PROPERTY_COMMENT
dataSBGenres SBProperties tag
#define SB_PROPERTY_COPYRIGHTURL
An interface to carry around arrays of nsIProperty instances. Users of this interface should only QI ...
_getSelectedPageStyle s i
virtual PRBool HandleSynchronousMessage(GstMessage *message)=0
#define SB_PROPERTY_TRACKNUMBER