37 #include <nsIFileURL.h>
38 #include <nsIMutableArray.h>
40 #include <nsIVariant.h>
41 #include <nsIWritablePropertyBag.h>
42 #include <nsIWritablePropertyBag2.h>
45 #include <sbIDevice.h>
46 #include <sbIDeviceCapabilities.h>
47 #include <sbIMediaFormatMutable.h>
48 #include <sbITranscodeError.h>
49 #include <sbITranscodeManager.h>
50 #include <sbITranscodeProfile.h>
53 #include <nsArrayUtils.h>
54 #include <nsCOMArray.h>
55 #include <nsComponentManagerUtils.h>
56 #include <nsNetUtil.h>
68 # pragma warning (push)
69 # pragma warning (disable: 4244)
73 # pragma warning (pop)
91 static PRLogModuleInfo* gGstTranscodeConfiguratorLog = nsnull;
92 #define TRACE(args) PR_LOG(gGstTranscodeConfiguratorLog, PR_LOG_DEBUG, args)
93 #define LOG(args) PR_LOG(gGstTranscodeConfiguratorLog, PR_LOG_WARN, args)
95 #define __FUNCTION__ __PRETTY_FUNCTION__
117 TRACE((
"%s", __FUNCTION__));
118 NS_ENSURE_ARG_POINTER(aRange);
119 NS_ENSURE_ARG_POINTER(_retval);
123 PRInt32 result = PR_INT32_MIN, max = PR_INT32_MIN;
124 rv = aRange->GetValueCount(&count);
125 NS_ENSURE_SUCCESS(rv, rv);
127 for (PRUint32
i = 0;
i <
count; ++
i) {
130 NS_ENSURE_SUCCESS(rv, rv);
131 if ((result < aTarget || v < result) && v >= aTarget) {
138 if (result >= aTarget) {
144 return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA;
150 rv = aRange->GetMin(&min);
151 rv |= aRange->GetStep(&step);
152 rv |= aRange->GetMax(&max);
153 NS_ENSURE_SUCCESS(rv, rv);
154 NS_ENSURE_TRUE(step > 0, NS_ERROR_UNEXPECTED);
157 return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA;
164 *_retval = min + (aTarget - min + step - 1) / step * step;
176 : mQuality(-HUGE_VAL),
177 mVideoBitrate(PR_INT32_MIN)
180 if (!gGstTranscodeConfiguratorLog) {
181 gGstTranscodeConfiguratorLog =
182 PR_NewLogModule(
"sbGStreamerTranscodeDeviceConfigurator");
185 TRACE((
"%s[%p]", __FUNCTION__,
this));
203 const nsACString& aMimeType,
204 nsIArray *aAttributes,
205 GstCaps** aResultCaps)
207 TRACE((
"%s", __FUNCTION__));
208 NS_ENSURE_ARG_POINTER(aAttributes);
209 NS_ENSURE_ARG_POINTER(aResultCaps);
213 nsCOMPtr<nsISimpleEnumerator> attrsEnum;
214 rv = aAttributes->Enumerate(getter_AddRefs(attrsEnum));
215 NS_ENSURE_SUCCESS(rv, rv);
219 GstStructure* capsStruct = gst_caps_get_structure(caps.get(), 0);
222 while (NS_SUCCEEDED(rv = attrsEnum->HasMoreElements(&hasMore)) && hasMore) {
223 nsCOMPtr<nsISupports> attrSupports;
224 rv = attrsEnum->GetNext(getter_AddRefs(attrSupports));
225 NS_ENSURE_SUCCESS(rv, rv);
226 nsCOMPtr<sbITranscodeProfileAttribute> attr =
227 do_QueryInterface(attrSupports, &rv);
228 NS_ENSURE_SUCCESS(rv, rv);
230 rv = attr->GetName(attrName);
231 NS_ENSURE_SUCCESS(rv, rv);
232 nsCOMPtr<nsIVariant> attrValue;
233 rv = attr->GetValue(getter_AddRefs(attrValue));
234 NS_ENSURE_SUCCESS(rv, rv);
236 rv = attrValue->GetDataType(&attrType);
237 NS_ENSURE_SUCCESS(rv, rv);
239 case nsIDataType::VTYPE_INT8:
case nsIDataType::VTYPE_UINT8:
240 case nsIDataType::VTYPE_INT16:
case nsIDataType::VTYPE_UINT16:
241 case nsIDataType::VTYPE_INT32:
case nsIDataType::VTYPE_UINT32:
242 case nsIDataType::VTYPE_INT64:
case nsIDataType::VTYPE_UINT64:
245 rv = attrValue->GetAsInt32(&intValue);
246 NS_ENSURE_SUCCESS(rv, rv);
247 gst_structure_set(capsStruct,
248 NS_LossyConvertUTF16toASCII(attrName).
get(),
254 case nsIDataType::VTYPE_UTF8STRING:
255 case nsIDataType::VTYPE_DOMSTRING:
256 case nsIDataType::VTYPE_CSTRING:
257 case nsIDataType::VTYPE_ASTRING:
259 nsCString stringValue;
260 rv = attrValue->GetAsACString(stringValue);
261 NS_ENSURE_SUCCESS (rv, rv);
263 gst_structure_set(capsStruct,
264 NS_LossyConvertUTF16toASCII(attrName).
get(),
266 stringValue.BeginReading(),
271 NS_NOTYETIMPLEMENTED(
"Unknown attribute type");
274 NS_ENSURE_SUCCESS(rv, rv);
276 *aResultCaps = caps.forget();
283 TRACE((
"%s[%p]", __FUNCTION__,
this));
284 NS_ENSURE_ARG_POINTER(aProfile);
290 rv = aProfile->GetType(&type);
291 NS_ENSURE_SUCCESS(rv, rv);
296 return NS_ERROR_NOT_IMPLEMENTED;
303 rv = aProfile->GetContainerFormat(capsName);
304 NS_ENSURE_SUCCESS(rv, rv);
305 if (!capsName.IsEmpty()) {
306 nsCOMPtr<nsIArray> attrs;
307 rv = aProfile->GetContainerAttributes(getter_AddRefs(attrs));
308 NS_ENSURE_SUCCESS(rv, rv);
310 GstCaps* caps = NULL;
312 NS_LossyConvertUTF16toASCII(capsName),
315 NS_ENSURE_SUCCESS(rv, rv);
318 if (!muxerCodecName) {
323 gst_caps_unref(caps);
324 if (!muxerCodecName) {
325 TRACE((
"%s: no muxer available for %s",
327 NS_LossyConvertUTF16toASCII(capsName).
get()));
328 return NS_ERROR_UNEXPECTED;
330 elementNames.
muxer = muxerCodecName;
334 rv = aProfile->GetAudioCodec(capsName);
335 NS_ENSURE_SUCCESS(rv, rv);
336 if (!capsName.IsEmpty()) {
337 nsCOMPtr<nsIArray> attrs;
338 rv = aProfile->GetAudioAttributes(getter_AddRefs(attrs));
339 NS_ENSURE_SUCCESS(rv, rv);
341 GstCaps* caps = NULL;
343 NS_LossyConvertUTF16toASCII(capsName),
346 NS_ENSURE_SUCCESS(rv, rv);
349 gst_caps_unref(caps);
351 TRACE((
"%s: no audio encoder available for %s",
353 NS_LossyConvertUTF16toASCII(capsName).
get()));
354 return NS_ERROR_UNEXPECTED;
360 rv = aProfile->GetVideoCodec(capsName);
361 NS_ENSURE_SUCCESS(rv, rv);
362 if (!capsName.IsEmpty()) {
363 nsCOMPtr<nsIArray> attrs;
364 rv = aProfile->GetVideoAttributes(getter_AddRefs(attrs));
365 NS_ENSURE_SUCCESS(rv, rv);
367 GstCaps* caps = NULL;
369 NS_LossyConvertUTF16toASCII(capsName),
372 NS_ENSURE_SUCCESS(rv, rv);
375 gst_caps_unref(caps);
377 TRACE((
"%s: no video encoder available for %s",
379 NS_LossyConvertUTF16toASCII(capsName).
get()));
380 return NS_ERROR_UNEXPECTED;
386 NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
402 rv = SetQuality(0.5);
403 NS_ENSURE_SUCCESS(rv, rv);
408 nsCOMPtr<nsIVariant> qualityVar;
409 rv =
mDevice->GetPreference(NS_LITERAL_STRING(
"transcode.quality.video"),
410 getter_AddRefs(qualityVar));
412 rv = SetQuality(quality);
413 NS_ENSURE_SUCCESS(rv, rv);
416 PRUint16 variantType;
417 rv = qualityVar->GetDataType(&variantType);
418 NS_ENSURE_SUCCESS(rv, rv);
419 switch (variantType) {
420 case nsIDataType::VTYPE_EMPTY:
421 case nsIDataType::VTYPE_VOID:
424 rv = qualityVar->GetAsDouble(&quality);
425 NS_ENSURE_SUCCESS(rv, rv);
428 rv = SetQuality(quality);
429 NS_ENSURE_SUCCESS(rv, rv);
430 TRACE((
"%s: set quality to %f", __FUNCTION__, quality));
445 TRACE((
"%s[%p]", __FUNCTION__,
this));
451 NS_PRECONDITION(
mDevice,
"SelectProfile called with no device set!");
452 NS_PRECONDITION(
mQuality != -HUGE_VAL,
"quality is not set!");
457 nsCOMPtr<sbITranscodeEncoderProfile> selectedProfile;
459 PRUint32 selectedPriority = 0;
461 nsCOMPtr<sbIVideoFormatType> selectedFormat;
464 nsCOMPtr<nsIArray> profilesArray;
466 NS_ENSURE_SUCCESS(rv, rv);
467 nsCOMPtr<nsISimpleEnumerator> profilesEnum;
468 rv = profilesArray->Enumerate(getter_AddRefs(profilesEnum));
469 NS_ENSURE_SUCCESS(rv, rv);
472 nsCOMPtr<sbIDeviceCapabilities> caps;
473 rv =
mDevice->GetCapabilities(getter_AddRefs(caps));
474 NS_ENSURE_SUCCESS(rv, rv);
477 PRUint32 mimeTypesCount;
486 rv2 =
mDevice->GetName(deviceName);
487 if (NS_FAILED(rv2)) {
491 nsTArray<nsString> detailParams;
492 detailParams.AppendElement(deviceName);
496 NS_LITERAL_STRING(
"transcode.error.device_no_video.withoutitem"),
501 NS_ENSURE_SUCCESS(rv2, rv2);
503 NS_ENSURE_SUCCESS(rv, rv);
507 PRBool hasMoreProfiles;
508 while (NS_SUCCEEDED(profilesEnum->HasMoreElements(&hasMoreProfiles)) &&
511 nsCOMPtr<nsISupports> profileSupports;
512 rv = profilesEnum->GetNext(getter_AddRefs(profileSupports));
513 NS_ENSURE_SUCCESS(rv, rv);
515 nsCOMPtr<sbITranscodeEncoderProfile> profile =
516 do_QueryInterface(profileSupports, &rv);
517 NS_ENSURE_SUCCESS(rv, rv);
521 rv = profile->GetEncoderProfilePriority(
mQuality, &priority);
522 NS_ENSURE_SUCCESS(rv, rv);
523 if (priority <= selectedPriority) {
527 for (PRUint32 mimeTypeIndex = 0;
528 mimeTypeIndex < mimeTypesCount;
535 PRUint32 formatTypeCount;
536 rv = caps->GetPreferredFormatTypes(
538 NS_ConvertASCIItoUTF16(mimeTypes[mimeTypeIndex]),
541 NS_ENSURE_SUCCESS(rv, rv);
545 for (PRUint32 formatIndex = 0;
546 formatIndex < formatTypeCount;
549 nsCOMPtr<sbIVideoFormatType> format = do_QueryInterface(
550 formatTypes[formatIndex], &rv);
551 if (NS_FAILED(rv) || !format) {
557 nsCString formatContainer;
558 rv = format->GetContainerType(formatContainer);
559 NS_ENSURE_SUCCESS(rv, rv);
560 nsString encoderContainer;
561 rv = profile->GetContainerFormat(encoderContainer);
562 NS_ENSURE_SUCCESS(rv, rv);
564 if (!encoderContainer.Equals(NS_ConvertUTF8toUTF16(formatContainer))) {
570 nsString encoderAudioCodec;
571 rv = profile->GetAudioCodec(encoderAudioCodec);
572 NS_ENSURE_SUCCESS(rv, rv);
573 nsCOMPtr<sbIDevCapAudioStream> audioCaps;
574 rv = format->GetAudioStream(getter_AddRefs(audioCaps));
575 NS_ENSURE_SUCCESS(rv, rv);
577 if (!encoderAudioCodec.IsEmpty()) {
584 nsCString formatAudioCodec;
585 rv = audioCaps->GetType(formatAudioCodec);
586 NS_ENSURE_SUCCESS(rv, rv);
587 if (!encoderAudioCodec.Equals(NS_ConvertUTF8toUTF16(formatAudioCodec))) {
595 nsString encoderVideoCodec;
596 rv = profile->GetVideoCodec(encoderVideoCodec);
597 NS_ENSURE_SUCCESS(rv, rv);
598 nsCOMPtr<sbIDevCapVideoStream> videoCaps;
599 rv = format->GetVideoStream(getter_AddRefs(videoCaps));
600 NS_ENSURE_SUCCESS(rv, rv);
602 if (!encoderVideoCodec.IsEmpty()) {
609 nsCString formatVideoCodec;
610 rv = videoCaps->GetType(formatVideoCodec);
611 NS_ENSURE_SUCCESS(rv, rv);
612 if (!encoderVideoCodec.Equals(NS_ConvertUTF8toUTF16(formatVideoCodec))) {
620 selectedProfile = profile;
621 selectedFormat = format;
622 rv = profile->GetEncoderProfilePriority(
mQuality, &selectedPriority);
623 NS_ENSURE_SUCCESS(rv, rv);
633 TRACE((
"%s: no suitable encoder profile found", __FUNCTION__));
636 rv =
mDevice->GetName(deviceName);
641 nsTArray<nsString> detailParams;
642 detailParams.AppendElement(deviceName);
646 NS_LITERAL_STRING(
"transcode.error.no_profile.withoutitem"),
651 NS_ENSURE_SUCCESS(rv, rv);
652 return NS_ERROR_FAILURE;
657 PRBool success =
mElementNames.Get(selectedProfile, &elementNames);
658 NS_ENSURE_TRUE(success, NS_ERROR_UNEXPECTED);
663 NS_ENSURE_SUCCESS(rv, rv);
665 TRACE((
"%s: profile selected, using muxer [%s] audio [%s] video [%s] extension [%s]",
667 elementNames.
muxer.get(),
693 TRACE((
"%s[%p]", __FUNCTION__,
this));
695 "attempted to set audio properties without selecting profile");
697 "attempted to set audio properties without selected output format");
703 NS_ENSURE_SUCCESS(rv, rv);
708 NS_ENSURE_SUCCESS(rv, rv);
711 rv =
mInputFormat->GetAudioStream(getter_AddRefs(inputFormat));
712 NS_ENSURE_SUCCESS(rv, rv);
715 nsCOMPtr<sbIDevCapAudioStream> outputCaps;
717 NS_ENSURE_SUCCESS(rv, rv);
721 nsCOMPtr<sbIDevCapRange> sampleRateRange;
722 rv = outputCaps->GetSupportedSampleRates(getter_AddRefs(sampleRateRange));
723 NS_ENSURE_SUCCESS(rv, rv);
725 rv = inputFormat->GetSampleRate(&sampleRate);
726 NS_ENSURE_SUCCESS(rv, rv);
727 rv = sampleRateRange->IsValueInRange(sampleRate, &isInRange);
728 if (NS_FAILED(rv) || !isInRange) {
731 NS_ENSURE_SUCCESS(rv, rv);
733 rv = audioFormat->SetSampleRate(sampleRate);
734 NS_ENSURE_SUCCESS(rv, rv);
736 nsCOMPtr<sbIDevCapRange> channelsRange;
737 rv = outputCaps->GetSupportedChannels(getter_AddRefs(channelsRange));
738 NS_ENSURE_SUCCESS(rv, rv);
740 rv = inputFormat->GetChannels(&channels);
741 NS_ENSURE_SUCCESS(rv, rv);
742 rv = channelsRange->IsValueInRange(channels, &isInRange);
743 if (NS_FAILED(rv) || !isInRange) {
747 if (NS_SUCCEEDED(rv)) {
748 channels = newChannels;
752 channels = (channels < 2 ? 1 : 2);
755 rv = audioFormat->SetChannels(channels);
756 NS_ENSURE_SUCCESS(rv, rv);
764 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/sbpropertybag;1", &rv);
765 NS_ENSURE_SUCCESS(rv, rv);
768 nsCOMPtr<nsIWritablePropertyBag> writableBag =
770 NS_ENSURE_SUCCESS(rv, rv);
772 nsCOMPtr<nsIArray> propsSrc;
774 NS_ENSURE_SUCCESS(rv, rv);
777 NS_ENSURE_SUCCESS(rv, rv);
791 TRACE((
"%s[%p]", __FUNCTION__,
this));
793 "DetermineIdealOutputSize called without selected profile");
795 "DetermineIdealOutputSize called without selected format");
797 "DetermineIdealOutputSize called without input format");
806 rv =
mInputFormat->GetVideoStream(getter_AddRefs(inputFormat));
807 NS_ENSURE_SUCCESS(rv, rv);
808 NS_ENSURE_TRUE(inputFormat, NS_ERROR_FAILURE);
810 rv = inputFormat->GetVideoFrameRate(&num, &denom);
811 NS_ENSURE_SUCCESS(rv, rv);
813 nsCOMPtr<sbIDevCapVideoStream> videoCaps;
815 NS_ENSURE_SUCCESS(rv, rv);
816 NS_ENSURE_TRUE(videoCaps, NS_ERROR_FAILURE);
818 PRBool isFrameRatesRange;
819 rv = videoCaps->GetDoesSupportFrameRateRange(&isFrameRatesRange);
820 NS_ENSURE_SUCCESS(rv, rv);
822 if (isFrameRatesRange) {
823 nsCOMPtr<sbIDevCapFraction> minFrameRate;
824 rv = videoCaps->GetMinimumSupportedFrameRate(
825 getter_AddRefs(minFrameRate));
826 NS_ENSURE_SUCCESS(rv, rv);
827 rv = minFrameRate->GetNumerator(&num);
828 NS_ENSURE_SUCCESS(rv, rv);
829 rv = minFrameRate->GetDenominator(&denom);
830 NS_ENSURE_SUCCESS(rv, rv);
833 nsCOMPtr<sbIDevCapFraction> maxFrameRate;
834 rv = videoCaps->GetMaximumSupportedFrameRate(
835 getter_AddRefs(maxFrameRate));
836 NS_ENSURE_SUCCESS(rv, rv);
837 rv = maxFrameRate->GetNumerator(&num);
838 NS_ENSURE_SUCCESS(rv, rv);
839 rv = maxFrameRate->GetDenominator(&denom);
840 NS_ENSURE_SUCCESS(rv, rv);
843 if (inputFrameRate >= minFrameRateFraction &&
844 inputFrameRate <= maxFrameRateFraction)
846 outputFrameRate = inputFrameRate;
848 else if (inputFrameRate < minFrameRateFraction) {
849 outputFrameRate = minFrameRateFraction;
851 else if (inputFrameRate > maxFrameRateFraction) {
852 outputFrameRate = maxFrameRateFraction;
856 nsCOMPtr<nsIArray> frameRatesRange;
857 rv = videoCaps->GetSupportedFrameRates(getter_AddRefs(frameRatesRange));
858 NS_ENSURE_SUCCESS(rv, rv);
861 rv = frameRatesRange->GetLength(&length);
862 NS_ENSURE_SUCCESS(rv, rv);
864 for (PRUint32
i = 0;
i < length;
i++) {
865 nsCOMPtr<sbIDevCapFraction> curFraction =
866 do_QueryElementAt(frameRatesRange,
i, &rv);
867 NS_ENSURE_SUCCESS(rv, rv);
870 rv = curFraction->GetNumerator(&num);
871 NS_ENSURE_SUCCESS(rv, rv);
872 rv = curFraction->GetDenominator(&denom);
873 NS_ENSURE_SUCCESS(rv, rv);
877 double lastDifference = fabs(outputFrameRate - inputFrameRate);
878 double difference = fabs(candidate - inputFrameRate);
879 if (difference < lastDifference) {
880 outputFrameRate = candidate;
894 rv =
mInputFormat->GetVideoStream(getter_AddRefs(inputFormat));
895 NS_ENSURE_SUCCESS(rv, rv);
897 return NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA;
900 rv = inputFormat->GetVideoWidth(&input.
width);
901 NS_ENSURE_SUCCESS(rv, rv);
902 rv = inputFormat->GetVideoHeight(&input.
height);
903 NS_ENSURE_SUCCESS(rv, rv);
905 nsCOMPtr<sbIDevCapVideoStream> outputCaps;
907 NS_ENSURE_SUCCESS(rv, rv);
908 NS_ENSURE_TRUE(outputCaps, NS_ERROR_FAILURE);
913 rv = inputFormat->GetVideoPAR(&num, &denom);
914 NS_ENSURE_SUCCESS(rv, rv);
919 PRBool supportsPARRange;
920 rv = outputCaps->GetDoesSupportPARRange(&supportsPARRange);
921 NS_ENSURE_SUCCESS(rv, rv);
923 if (supportsPARRange) {
925 nsCOMPtr<sbIDevCapFraction> minPARFraction;
926 rv = outputCaps->GetMinimumSupportedPAR(getter_AddRefs(minPARFraction));
927 NS_ENSURE_SUCCESS(rv, rv);
928 rv = minPARFraction->GetNumerator(&num);
929 NS_ENSURE_SUCCESS(rv, rv);
930 rv = minPARFraction->GetDenominator(&denom);
931 NS_ENSURE_SUCCESS(rv, rv);
934 nsCOMPtr<sbIDevCapFraction> maxPARFraction;
935 rv = outputCaps->GetMaximumSupportedPAR(getter_AddRefs(maxPARFraction));
936 NS_ENSURE_SUCCESS(rv, rv);
937 rv = maxPARFraction->GetNumerator(&num);
938 NS_ENSURE_SUCCESS(rv, rv);
939 rv = maxPARFraction->GetDenominator(&denom);
940 NS_ENSURE_SUCCESS(rv, rv);
945 if (inputPAR >= minPAR && inputPAR <= maxPAR) {
948 else if (inputPAR < minPAR) {
951 else if (inputPAR > maxPAR) {
956 nsCOMPtr<nsIArray> parRanges;
957 rv = outputCaps->GetSupportedPARs(getter_AddRefs(parRanges));
958 NS_ENSURE_SUCCESS(rv, rv);
959 NS_ENSURE_TRUE(parRanges, NS_ERROR_UNEXPECTED);
961 PRUint32
count, index;
962 rv = parRanges->GetLength(&count);
963 NS_ENSURE_SUCCESS(rv, rv);
965 for (index = 0; index <
count; index++) {
966 nsCOMPtr<sbIDevCapFraction> curFraction =
967 do_QueryElementAt(parRanges, index, &rv);
968 NS_ENSURE_SUCCESS(rv, rv);
970 rv = curFraction->GetNumerator(&num);
971 NS_ENSURE_SUCCESS(rv, rv);
972 rv = curFraction->GetDenominator(&denom);
973 NS_ENSURE_SUCCESS(rv, rv);
976 if (inputPAR.
IsEqual(curPARFraction)) {
982 if (index >= count) {
994 PRBool hasRange = PR_TRUE;
995 std::vector<PRInt32> widths, heights;
997 nsCOMPtr<sbIDevCapRange>
range;
998 rv = outputCaps->GetSupportedWidths(getter_AddRefs(range));
999 NS_ENSURE_SUCCESS(rv, rv);
1002 rv = range->GetValueCount(&count);
1003 NS_ENSURE_SUCCESS(rv, rv);
1005 for (PRUint32
i = 0;
i <
count; ++
i) {
1007 rv = range->GetValue(
i, &v);
1008 NS_ENSURE_SUCCESS(rv, rv);
1009 widths.push_back(v);
1011 std::sort(widths.begin(), widths.end());
1015 PRInt32
min, step, max;
1016 rv = range->GetMin(&min);
1017 rv |= range->GetStep(&step);
1018 rv |= range->GetMax(&max);
1019 NS_ENSURE_SUCCESS(rv, rv);
1020 for (PRInt32 v = min; v <= max; v += step) {
1021 widths.push_back(v);
1026 hasRange = PR_FALSE;
1029 rv = outputCaps->GetSupportedHeights(getter_AddRefs(range));
1030 NS_ENSURE_SUCCESS(rv, rv);
1033 rv = range->GetValueCount(&count);
1034 NS_ENSURE_SUCCESS(rv, rv);
1036 for (PRUint32
i = 0;
i <
count; ++
i) {
1038 rv = range->GetValue(
i, &v);
1039 NS_ENSURE_SUCCESS(rv, rv);
1040 heights.push_back(v);
1042 std::sort(heights.begin(), heights.end());
1046 PRInt32
min, step, max;
1047 rv = range->GetMin(&min);
1048 rv |= range->GetStep(&step);
1049 rv |= range->GetMax(&max);
1050 NS_ENSURE_SUCCESS(rv, rv);
1051 for (PRInt32 v = min; v <= max; v += step) {
1052 heights.push_back(v);
1057 hasRange = PR_FALSE;
1064 if (output.
width < widths.front()) {
1065 output.
width = widths.front();
1068 if (output.
height < heights.front()) {
1069 output.
height = heights.front();
1077 std::vector<PRInt32>::const_iterator it;
1078 it = std::lower_bound(widths.begin(), widths.end(), output.
width);
1079 if (it == widths.end()) {
1083 it = std::lower_bound(heights.begin(), heights.end(), output.
height);
1084 if (it == heights.end()) {
1099 nsCOMPtr<nsIArray> explicitSizes;
1100 rv = outputCaps->GetSupportedExplicitSizes(getter_AddRefs(explicitSizes));
1101 NS_ENSURE_SUCCESS(rv, rv);
1102 nsCOMPtr<nsISimpleEnumerator> sizeEnum;
1103 rv = explicitSizes->Enumerate(getter_AddRefs(sizeEnum));
1104 NS_ENSURE_SUCCESS(rv, rv);
1106 while (NS_SUCCEEDED(rv = sizeEnum->HasMoreElements(&hasMore)) && hasMore) {
1107 nsCOMPtr<nsISupports> supports;
1108 rv = sizeEnum->GetNext(getter_AddRefs(supports));
1109 NS_ENSURE_SUCCESS(rv, rv);
1110 nsCOMPtr<sbIImageSize> size = do_QueryInterface(supports, &rv);
1111 NS_ENSURE_SUCCESS(rv, rv);
1113 rv = size->GetWidth(&width);
1114 NS_ENSURE_SUCCESS(rv, rv);
1115 rv = size->GetHeight(&height);
1116 NS_ENSURE_SUCCESS(rv, rv);
1117 if (width < input.
width || height < input.
height) {
1121 if (width > output.
width && height > output.
height) {
1128 NS_ENSURE_SUCCESS(rv, rv);
1129 if (output.
width != PR_INT32_MAX || output.
height != PR_INT32_MAX) {
1141 rv = explicitSizes->Enumerate(getter_AddRefs(sizeEnum));
1142 NS_ENSURE_SUCCESS(rv, rv);
1143 Dimensions result, best(0, 0), selected(0, 0), maxSize;
1144 while (NS_SUCCEEDED(rv = sizeEnum->HasMoreElements(&hasMore)) && hasMore) {
1145 nsCOMPtr<nsISupports> supports;
1146 rv = sizeEnum->GetNext(getter_AddRefs(supports));
1147 NS_ENSURE_SUCCESS(rv, rv);
1148 nsCOMPtr<sbIImageSize> size = do_QueryInterface(supports);
1149 NS_ENSURE_SUCCESS(rv, rv);
1150 rv = size->GetWidth(&maxSize.
width);
1151 NS_ENSURE_SUCCESS(rv, rv);
1152 rv = size->GetHeight(&maxSize.
height);
1153 NS_ENSURE_SUCCESS(rv, rv);
1155 if (result.
width > best.width) {
1160 NS_ENSURE_SUCCESS(rv, rv);
1161 if (best.width < 1) {
1163 return NS_ERROR_FAILURE;
1175 TRACE((
"%s", __FUNCTION__));
1202 TRACE((
"%s[%p]", __FUNCTION__,
this));
1205 "FinalizeOutputSize needs dimensions");
1207 "FinalizeOutputSize called with no profile selected");
1209 "FinalizeOutputSize called with no output format");
1220 NS_ENSURE_SUCCESS(rv, rv);
1221 double maxBitrate = q1BPP * pixelsPerSecond;
1222 TRACE((
"%s: max bitrate %f for bpp %f", __FUNCTION__, maxBitrate, q1BPP));
1225 nsCOMPtr<sbIDevCapVideoStream> videoCaps;
1227 NS_ENSURE_SUCCESS(rv, rv);
1228 NS_ENSURE_TRUE(videoCaps, NS_ERROR_FAILURE);
1230 nsCOMPtr<sbIDevCapRange> videoBitrateRange;
1231 rv = videoCaps->GetSupportedBitRates(getter_AddRefs(videoBitrateRange));
1232 NS_ENSURE_SUCCESS(rv, rv);
1234 static_cast<PRInt32>(maxBitrate),
1236 NS_ENSURE_SUCCESS(rv, rv);
1247 "attempting to set video properties with no output dimensions!");
1249 "attempting to set video properties with no video bitrate!");
1252 nsCOMPtr<sbIMediaFormatVideoMutable>
videoFormat =
1254 NS_ENSURE_SUCCESS(rv, rv);
1258 NS_ENSURE_SUCCESS(rv, rv);
1260 NS_ENSURE_SUCCESS(rv, rv);
1263 NS_ENSURE_SUCCESS(rv, rv);
1266 NS_ENSURE_SUCCESS(rv, rv);
1268 NS_ENSURE_SUCCESS(rv, rv);
1272 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/sbpropertybag;1", &rv);
1273 NS_ENSURE_SUCCESS(rv, rv);
1277 nsCOMPtr<nsIWritablePropertyBag> writableBag =
1279 NS_ENSURE_SUCCESS(rv, rv);
1281 nsCOMPtr<nsIArray> propsSrc;
1283 NS_ENSURE_SUCCESS(rv, rv);
1286 NS_ENSURE_SUCCESS(rv, rv);
1289 "setVideoProperties failed to set video format");
1291 "setVideoProperties failed to set video properties");
1303 nsIWritablePropertyBag * aDstBag,
1306 NS_ENSURE_ARG_POINTER(aSrcProps);
1307 NS_ENSURE_ARG_POINTER(aDstBag);
1311 nsCOMPtr<nsISimpleEnumerator> propsEnum;
1312 rv = aSrcProps->Enumerate(getter_AddRefs(propsEnum));
1313 NS_ENSURE_SUCCESS(rv, rv);
1315 while (NS_SUCCEEDED(rv = propsEnum->HasMoreElements(&hasMore)) && hasMore) {
1316 nsCOMPtr<nsISupports> supports;
1317 rv = propsEnum->GetNext(getter_AddRefs(supports));
1318 NS_ENSURE_SUCCESS(rv, rv);
1319 nsCOMPtr<sbITranscodeProfileProperty> prop =
1320 do_QueryInterface(supports, &rv);
1321 NS_ENSURE_SUCCESS(rv, rv);
1323 rv = prop->GetHidden(&hidden);
1324 NS_ENSURE_SUCCESS(rv, rv);
1329 rv = prop->GetPropertyName(propName);
1330 NS_ENSURE_SUCCESS(rv, rv);
1333 nsCOMPtr<nsIVariant>
value;
1334 rv = prop->GetValue(getter_AddRefs(value));
1335 NS_ENSURE_SUCCESS(rv, rv);
1337 rv = value->GetDataType(&dataType);
1338 NS_ENSURE_SUCCESS(rv, rv);
1341 rv = prop->GetMapping(mapping);
1342 NS_ENSURE_SUCCESS(rv, rv);
1343 if (!mapping.IsEmpty()) {
1344 if (aIsVideo && mapping.Equals(
"bitrate", CaseInsensitiveCompare)) {
1346 NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
1348 else if (!aIsVideo && mapping.Equals(
"bitrate", CaseInsensitiveCompare)) {
1349 double audioBitrate;
1351 NS_ENSURE_SUCCESS(rv, rv);
1353 NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
1355 else if (mapping.Equals(
"quality", CaseInsensitiveCompare)) {
1357 NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
1359 else if (mapping.Equals(
"video-quality", CaseInsensitiveCompare)) {
1361 NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
1364 TRACE((
"%s[%p]: mapping %s not implemented",
1365 __FUNCTION__,
this, mapping.get()));
1366 return NS_ERROR_NOT_IMPLEMENTED;
1371 nsCString scaleString;
1372 rv = prop->GetScale(scaleString);
1373 NS_ENSURE_SUCCESS(rv, rv);
1374 if (!scaleString.IsEmpty()) {
1377 NS_ENSURE_SUCCESS(rv, rv);
1379 rv = value->GetAsDouble(&val);
1380 NS_ENSURE_SUCCESS(rv, rv);
1382 nsCOMPtr<nsIWritableVariant> var = do_QueryInterface(value, &rv);
1383 NS_ENSURE_SUCCESS(rv, rv);
1384 rv = var->SetAsDouble(val);
1385 NS_ENSURE_SUCCESS(rv, rv);
1390 case nsIDataType::VTYPE_INT32: {
1391 nsCOMPtr<nsIWritableVariant> var = do_QueryInterface(value, &rv);
1392 NS_ENSURE_SUCCESS(rv, rv);
1394 rv = var->GetAsInt32(&val);
1395 NS_ENSURE_SUCCESS(rv, rv);
1396 nsCOMPtr<nsIVariant>
limit;
1397 rv = prop->GetValueMax(getter_AddRefs(limit));
1398 if (NS_SUCCEEDED(rv) && limit) {
1400 rv = limit->GetAsInt32(&maxInt);
1401 if (NS_SUCCEEDED(rv) && val > maxInt) {
1405 rv = prop->GetValueMin(getter_AddRefs(limit));
1406 if (NS_SUCCEEDED(rv) && limit) {
1408 rv = limit->GetAsInt32(&minInt);
1409 if (NS_SUCCEEDED(rv) && val < minInt) {
1413 rv = var->SetAsInt32(val);
1414 NS_ENSURE_SUCCESS(rv, rv);
1419 rv = aDstBag->SetProperty(propName, value);
1420 NS_ENSURE_SUCCESS(rv, rv);
1422 NS_ENSURE_SUCCESS(rv, rv);
1430 TRACE((
"%s[%p]", __FUNCTION__,
this));
1441 NS_ENSURE_TRUE(initSuccess, NS_ERROR_OUT_OF_MEMORY);
1446 nsCOMPtr<nsISimpleEnumerator> dirEnum;
1448 nsCOMPtr<nsIURI> profilesDirURI;
1449 rv = NS_NewURI(getter_AddRefs(profilesDirURI),
1450 NS_LITERAL_STRING(
"resource://app/gstreamer/encode-profiles"));
1451 NS_ENSURE_SUCCESS(rv, rv);
1453 nsCOMPtr<nsIFileURL> profilesDirFileURL =
1454 do_QueryInterface(profilesDirURI, &rv);
1455 NS_ENSURE_SUCCESS(rv, rv);
1457 nsCOMPtr<nsIFile> profilesDir;
1458 rv = profilesDirFileURL->GetFile(getter_AddRefs(profilesDir));
1459 NS_ENSURE_SUCCESS(rv, rv);
1461 nsCOMPtr<nsIMutableArray>
array =
1462 do_CreateInstance(
"@songbirdnest.com/moz/xpcom/threadsafe-array;1", &rv);
1463 NS_ENSURE_SUCCESS(rv, rv);
1465 nsCOMPtr<sbITranscodeProfileLoader> profileLoader =
1466 do_CreateInstance(
"@songbirdnest.com/Songbird/Transcode/ProfileLoader;1",
1468 NS_ENSURE_SUCCESS (rv, rv);
1470 rv = profilesDir->GetDirectoryEntries(getter_AddRefs(dirEnum));
1471 NS_ENSURE_SUCCESS (rv, rv);
1474 rv = dirEnum->HasMoreElements(&hasMoreElements);
1475 NS_ENSURE_SUCCESS(rv, rv);
1476 if (!hasMoreElements)
1479 nsCOMPtr<nsIFile>
file;
1480 rv = dirEnum->GetNext(getter_AddRefs(file));
1481 NS_ENSURE_SUCCESS(rv, rv);
1483 nsCOMPtr<sbITranscodeProfile> profile;
1485 rv = profileLoader->LoadProfile(file, getter_AddRefs(profile));
1489 nsCOMPtr<sbITranscodeEncoderProfile> encoderProfile =
1490 do_QueryInterface(profile);
1491 NS_ENSURE_TRUE(encoderProfile, NS_ERROR_NO_INTERFACE);
1493 if (NS_FAILED(rv)) {
1498 rv = array->AppendElement(encoderProfile, PR_FALSE);
1499 NS_ENSURE_SUCCESS (rv, rv);
1503 NS_ENSURE_SUCCESS (rv, rv);
1512 sbGStreamerTranscodeDeviceConfigurator::GetQuality(
double *aQuality)
1514 TRACE((
"%s[%p]", __FUNCTION__,
this));
1515 NS_ENSURE_ARG_POINTER(aQuality);
1521 sbGStreamerTranscodeDeviceConfigurator::SetQuality(
double aQuality)
1523 TRACE((
"%s[%p]", __FUNCTION__,
this));
1525 NS_ERROR_ALREADY_INITIALIZED);
1533 sbGStreamerTranscodeDeviceConfigurator::GetDevice(
sbIDevice * *aDevice)
1535 TRACE((
"%s[%p]", __FUNCTION__,
this));
1536 NS_ENSURE_ARG_POINTER(aDevice);
1537 NS_IF_ADDREF(*aDevice =
mDevice);
1541 sbGStreamerTranscodeDeviceConfigurator::SetDevice(
sbIDevice * aDevice)
1543 TRACE((
"%s[%p]", __FUNCTION__,
this));
1545 NS_ERROR_ALREADY_INITIALIZED);
1558 TRACE((
"%s[%p]", __FUNCTION__,
this));
1560 NS_ENSURE_TRUE(
mDevice, NS_ERROR_NOT_INITIALIZED);
1562 NS_ERROR_ALREADY_INITIALIZED);
1568 NS_ENSURE_SUCCESS(rv, rv);
1572 NS_ENSURE_SUCCESS(rv, rv);
1583 TRACE((
"%s[%p]", __FUNCTION__,
this));
1585 NS_ENSURE_TRUE(
mInputFormat, NS_ERROR_NOT_INITIALIZED);
1587 NS_ERROR_ALREADY_INITIALIZED);
1594 NS_ENSURE_SUCCESS(rv, rv);
1599 NS_ENSURE_SUCCESS(rv, rv);
1602 NS_ENSURE_SUCCESS(rv, rv);
1603 if (NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA == rv) {
1610 NS_ENSURE_SUCCESS(rv, rv);
1613 NS_ENSURE_SUCCESS(rv, rv);
readonly attribute AString audioEncoder
The audio encoder to use. The name is specific to the transcoder (for example, this may be a gstreame...
nsresult MakeCapsFromAttributes(enum sbGstCapsMapType aType, const nsACString &aMimeType, nsIArray *aAttributes, GstCaps **aResultCaps)
Dimensions mOutputDimensions
NS_IMETHOD DetermineOutputType()
readonly attribute AString videoEncoder
The video encoder to use. The name is specific to the transcoder (for example, this may be a gstreame...
NS_IMETHOD GetAvailableProfiles(nsIArray **aProfiles)
static nsresult GetDevCapRangeUpper(sbIDevCapRange *aRange, PRInt32 aTarget, PRInt32 *_retval)
nsresult SB_NewTranscodeError(const nsAString &aMessageWithItem, const nsAString &aMessageWithoutItem, const nsAString &aDetails, const nsAString &aUri, sbIMediaItem *aMediaItem, sbITranscodeError **_retval)
nsresult sbFractionFromString(nsAString const &aString, sbFraction &aFraction)
sbFraction mVideoFrameRate
nsresult DetermineOutputVideoBitrate()
nsDataHashtable< nsISupportsHashKey, EncoderProfileData > mElementNames
nsresult SetAudioProperties()
readonly attribute sbIMediaFormatAudio audioFormat
The basic audio format for data that is not specific to a particular codec.
virtual ~sbGStreamerTranscodeDeviceConfigurator()
Songbird Variant Utility Definitions.
PRUint32 Numerator() const
const unsigned long TRANSCODE_TYPE_AUDIO_VIDEO
const PRUint32 CONTENT_VIDEO
nsCOMPtr< sbITranscodeEncoderProfile > mSelectedProfile
readonly attribute sbIMediaFormatVideo videoFormat
The basic video format for data that is not specific to a particular codec.
nsresult CopyPropertiesIntoBag(nsIArray *aSrcProps, nsIWritablePropertyBag *aDstBag, PRBool aIsVideo)
nsCOMPtr< sbITranscodeError > mLastError
nsCOMPtr< sbIMediaFormat > mInputFormat
this _dialogInput val(dateText)
nsCOMPtr< nsIArray > mAvailableProfiles
CONFIGURATE_STATE mConfigurateState
PRUint32 Denominator() const
nsCOMPtr< sbIVideoFormatType > mSelectedFormat
nsCOMPtr< sbIMediaFormatVideo > mVideoFormat
nsCOMPtr< nsIWritablePropertyBag2 > mAudioEncoderProperties
nsCOMPtr< sbIDevice > mDevice
sbGStreamerTranscodeDeviceConfigurator()
SimpleArrayEnumerator prototype hasMoreElements
static Dimensions GetMaximumFit(const Dimensions &aInput, const Dimensions &aMaximum)
bool IsEqual(sbFraction const &aOther) const
StringArrayEnumerator prototype hasMore
nsCOMPtr< nsIURI > mInputUri
long GetValue(in unsigned long aIndex)
nsCOMPtr< nsIWritablePropertyBag2 > mVideoEncoderProperties
NS_IMPL_ISUPPORTS_INHERITED2(sbGStreamerTranscodeDeviceConfigurator, sbTranscodingConfigurator, sbIDeviceTranscodingConfigurator, sbPIGstTranscodingConfigurator)
attribute sbIMediaFormat inputFormat
The input format to use when configuring the transcode profile.
nsresult SetVideoProperties()
nsresult EnsureProfileAvailable(sbITranscodeEncoderProfile *aProfile)
nsCOMPtr< sbIMediaFormatAudio > mAudioFormat
_getSelectedPageStyle s i
nsresult DetermineOutputDimensions()