sbDeviceCapsCompatibility.cpp
Go to the documentation of this file.
1 /* vim: set sw=2 :miv */
2 /*
3  *=BEGIN SONGBIRD GPL
4  *
5  * This file is part of the Songbird web player.
6  *
7  * Copyright(c) 2005-2009 POTI, Inc.
8  * http://www.songbirdnest.com
9  *
10  * This file may be licensed under the terms of of the
11  * GNU General Public License Version 2 (the ``GPL'').
12  *
13  * Software distributed under the License is distributed
14  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
15  * express or implied. See the GPL for the specific language
16  * governing rights and limitations.
17  *
18  * You should have received a copy of the GPL along with this
19  * program. If not, go to http://www.gnu.org/licenses/gpl.html
20  * or write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  *
23  *=END SONGBIRD GPL
24  */
25 
27 
28 #include <nsArrayUtils.h>
29 
30 #include <sbFraction.h>
31 #include <sbIDeviceCapabilities.h>
32 #include <sbIMediaInspector.h>
33 #include <sbMemoryUtils.h>
34 
39 #ifdef PR_LOGGING
40 static PRLogModuleInfo* gDeviceCapsCompatibilityLog =
41  PR_NewLogModule("sbDeviceCapsCompatibility");
42 #define LOG(args) PR_LOG(gDeviceCapsCompatibilityLog, PR_LOG_WARNING, args)
43 #define TRACE(args) PR_LOG(gDeviceCapsCompatibilityLog, PR_LOG_DEBUG, args)
44 #else /* PR_LOGGING */
45 #define LOG(args) /* nothing */
46 #define TRACE(args) /* nothing */
47 #endif /* PR_LOGGING */
48 
51 
53  : mDeviceCapabilities(nsnull),
54  mMediaFormat(nsnull),
55  mMediaVideoStream(nsnull),
56  mMediaAudioStream(nsnull),
57  mMediaVideoWidth(0),
58  mMediaVideoHeight(0),
59  mMediaVideoBitRate(0),
60  mMediaVideoSampleRate(0),
61  mMediaVideoPARNumerator(0),
62  mMediaVideoPARDenominator(0),
63  mMediaVideoFRNumerator(0),
64  mMediaVideoFRDenominator(0),
65  mMediaAudioBitRate(0),
66  mMediaAudioSampleRate(0),
67  mMediaAudioChannels(0),
68  mContentType(0)
69 {
70  TRACE(("%s[%p]", __FUNCTION__, this));
71 }
72 
73 sbDeviceCapsCompatibility::~sbDeviceCapsCompatibility()
74 {
75  TRACE(("%s[%p]", __FUNCTION__, this));
76  /* destructor code */
77 }
78 
79 // Compare nsString to nsCString
80 static inline PRBool
81 StringEqualsToCString(nsAString& string1, nsACString& string2)
82 {
83  return string1.Equals(NS_ConvertUTF8toUTF16(string2).BeginReading());
84 }
85 
86 /* sbIDeviceCapsCompatibility interface implementation */
87 
88 NS_IMETHODIMP
89 sbDeviceCapsCompatibility::Initialize(
90  sbIDeviceCapabilities* aDeviceCapabilities,
91  sbIMediaFormat* aMediaFormat,
92  PRUint32 aContentType)
93 {
94  TRACE(("%s[%p]", __FUNCTION__, this));
95  NS_ENSURE_ARG_POINTER(aDeviceCapabilities);
96  NS_ENSURE_ARG_POINTER(aMediaFormat);
97 
98  nsresult rv;
99 
100  mDeviceCapabilities = aDeviceCapabilities;
101  mMediaFormat = aMediaFormat;
102  mContentType = aContentType;
103 
104  // Get the audio and video streams
105  rv = mMediaFormat->GetVideoStream(getter_AddRefs(mMediaVideoStream));
106  NS_ENSURE_SUCCESS(rv, rv);
107 
108  rv = mMediaFormat->GetAudioStream(getter_AddRefs(mMediaAudioStream));
109  NS_ENSURE_SUCCESS(rv, rv);
110 
111  return NS_OK;
112 }
113 
114 NS_IMETHODIMP
115 sbDeviceCapsCompatibility::Compare(PRBool* aCompatible)
116 {
117  TRACE(("%s[%p]", __FUNCTION__, this));
118  NS_ENSURE_ARG_POINTER(aCompatible);
119  NS_ENSURE_TRUE(mDeviceCapabilities, NS_ERROR_NOT_INITIALIZED);
120  NS_ENSURE_TRUE(mMediaFormat, NS_ERROR_NOT_INITIALIZED);
121 
122  nsresult rv;
123  *aCompatible = PR_FALSE;
124 
125  switch (mContentType) {
127  rv = CompareAudioFormat(aCompatible);
128  NS_ENSURE_SUCCESS(rv, rv);
129  break;
131  rv = CompareVideoFormat(aCompatible);
132  NS_ENSURE_SUCCESS(rv, rv);
133  break;
135  rv = CompareImageFormat(aCompatible);
136  NS_ENSURE_SUCCESS(rv, rv);
137  break;
138  default:
139  NS_WARNING("sbDeviceCapsCompatibility::Compare: "
140  "unknown content type for comparison");
141  break;
142  }
143 
144  return NS_OK;
145 }
146 
147 nsresult
148 sbDeviceCapsCompatibility::CompareAudioFormat(PRBool* aCompatible)
149 {
150  TRACE(("%s[%p]", __FUNCTION__, this));
151  NS_ENSURE_ARG_POINTER(aCompatible);
152  NS_ENSURE_TRUE(mDeviceCapabilities, NS_ERROR_NOT_INITIALIZED);
153  NS_ENSURE_TRUE(mMediaFormat, NS_ERROR_NOT_INITIALIZED);
154 
155  nsresult rv;
156  *aCompatible = PR_FALSE;
157 
158  // Retrieve all the properties of the format we're comparing to
159  // Get container type
160  nsCOMPtr<sbIMediaFormatContainer> mediaContainer;
161  rv = mMediaFormat->GetContainer(getter_AddRefs(mediaContainer));
162  NS_ENSURE_SUCCESS(rv, rv);
163  NS_ENSURE_TRUE(mediaContainer, NS_OK);
164 
165  rv = mediaContainer->GetContainerType(mMediaContainerType);
166  NS_ENSURE_SUCCESS(rv, rv);
167 
168  if (!mMediaAudioStream) {
169  // Since we're only comparing audio, if we don't have audio, reject.
170  return NS_OK;
171  }
172 
173  // Retrive all the audio properties if available
174  // Get Audio type
175  rv = mMediaAudioStream->GetAudioType(mMediaAudioType);
176  NS_ENSURE_SUCCESS(rv, rv);
177 
178  // Get Audio bit rate
179  rv = mMediaAudioStream->GetBitRate(&mMediaAudioBitRate);
180  NS_ENSURE_SUCCESS(rv, rv);
181 
182  // Get Audio sample rate
183  rv = mMediaAudioStream->GetSampleRate(&mMediaAudioSampleRate);
184  NS_ENSURE_SUCCESS(rv, rv);
185 
186  // Get Audio channels
187  rv = mMediaAudioStream->GetChannels(&mMediaAudioChannels);
188  NS_ENSURE_SUCCESS(rv, rv);
189 
190  // TODO: Get additional audio properties
191 
192  // Get supported mime types
193  PRUint32 mimeTypesLength;
194  char **mimeTypes;
195  rv = mDeviceCapabilities->GetSupportedMimeTypes(mContentType,
196  &mimeTypesLength,
197  &mimeTypes);
198 
199  if (NS_SUCCEEDED(rv) && mimeTypesLength > 0) {
200  sbAutoNSArray<char*> autoMimeTypes(mimeTypes, mimeTypesLength);
201  for (PRUint32 mimeTypeIndex = 0;
202  mimeTypeIndex < mimeTypesLength;
203  ++mimeTypeIndex)
204  {
205  NS_ConvertASCIItoUTF16 mimeType(mimeTypes[mimeTypeIndex]);
206 
207  nsISupports** formatTypes;
208  PRUint32 formatTypeCount;
209  rv = mDeviceCapabilities->GetFormatTypes(mContentType,
210  mimeType,
211  &formatTypeCount,
212  &formatTypes);
213  NS_ENSURE_SUCCESS(rv, rv);
214  sbAutoFreeXPCOMPointerArray<nsISupports> freeFormats(formatTypeCount,
215  formatTypes);
216 
217  for (PRUint32 formatIndex = 0;
218  formatIndex < formatTypeCount;
219  formatIndex++)
220  {
221  nsCOMPtr<sbIAudioFormatType> audioFormat =
222  do_QueryInterface(formatTypes[formatIndex], &rv);
223  if (NS_SUCCEEDED(rv) && audioFormat) {
224  // Compare container type
225  nsCString deviceContainerType;
226  rv = audioFormat->GetContainerFormat(deviceContainerType);
227  NS_ENSURE_SUCCESS(rv, rv);
228 
229  // Container type not equal
230  if (!StringEqualsToCString(mMediaContainerType, deviceContainerType)) {
231  LOG(("Not match! media container type: %s, device container type: %s",
232  NS_ConvertUTF16toUTF8(mMediaContainerType).BeginReading(),
233  deviceContainerType.BeginReading()));
234  continue;
235  }
236 
237  // Compare audio type
238  nsCString deviceAudioCodec;
239  rv = audioFormat->GetAudioCodec(deviceAudioCodec);
240  NS_ENSURE_SUCCESS(rv, rv);
241 
242  // Audio codec not equal. Not compatible.
243  if (!StringEqualsToCString(mMediaAudioType, deviceAudioCodec)) {
244  LOG(("Not match! media audio type: %s, device audio type: %s",
245  NS_ConvertUTF16toUTF8(mMediaAudioType).BeginReading(),
246  deviceAudioCodec.BeginReading()));
247  continue;
248  }
249 
250  // Audio bit rate could be unknown in the media file.
251  if (mMediaAudioBitRate) {
252  nsCOMPtr<sbIDevCapRange> deviceSupportedBitRates;
253  rv = audioFormat->GetSupportedBitrates(
254  getter_AddRefs(deviceSupportedBitRates));
255  NS_ENSURE_SUCCESS(rv, rv);
256 
257  rv = deviceSupportedBitRates->IsValueInRange(mMediaAudioBitRate,
258  aCompatible);
259  NS_ENSURE_SUCCESS(rv, rv);
260  if (!(*aCompatible))
261  continue;
262  }
263 
264  // Compare audio sample rates
265  nsCOMPtr<sbIDevCapRange> deviceSupportedSampleRates;
266  rv = audioFormat->GetSupportedSampleRates(
267  getter_AddRefs(deviceSupportedSampleRates));
268  NS_ENSURE_SUCCESS(rv, rv);
269 
270  rv = deviceSupportedSampleRates->IsValueInRange(mMediaAudioSampleRate,
271  aCompatible);
272  NS_ENSURE_SUCCESS(rv, rv);
273  if (!(*aCompatible))
274  continue;
275 
276  // Compare audio channels
277  nsCOMPtr<sbIDevCapRange> deviceSupportedChannels;
278  rv = audioFormat->GetSupportedChannels(
279  getter_AddRefs(deviceSupportedChannels));
280  NS_ENSURE_SUCCESS(rv, rv);
281 
282  rv = deviceSupportedChannels->IsValueInRange(mMediaAudioChannels,
283  aCompatible);
284  NS_ENSURE_SUCCESS(rv, rv);
285  if (!(*aCompatible))
286  continue;
287 
288  // Getting this far means we got a match and have set aCompatible.
289  return NS_OK;
290  }
291  }
292  }
293  }
294 
295  return NS_OK;
296 }
297 
298 nsresult
299 sbDeviceCapsCompatibility::CompareImageFormat(PRBool* aCompatible)
300 {
301  return NS_ERROR_NOT_IMPLEMENTED;
302 }
303 
304 nsresult
305 sbDeviceCapsCompatibility::CompareVideoFormat(PRBool* aCompatible)
306 {
307  TRACE(("%s[%p]", __FUNCTION__, this));
308  NS_ENSURE_ARG_POINTER(aCompatible);
309  NS_ENSURE_TRUE(mDeviceCapabilities, NS_ERROR_NOT_INITIALIZED);
310  NS_ENSURE_TRUE(mMediaFormat, NS_ERROR_NOT_INITIALIZED);
311  NS_ENSURE_TRUE(mMediaVideoStream, NS_ERROR_NOT_INITIALIZED);
312 
313  nsresult rv;
314  *aCompatible = PR_FALSE;
315 
316  // Retrive all the video properties
317  // Get video container type
318  nsCOMPtr<sbIMediaFormatContainer> mediaContainer;
319  rv = mMediaFormat->GetContainer(getter_AddRefs(mediaContainer));
320  NS_ENSURE_SUCCESS(rv, rv);
321  NS_ENSURE_TRUE(mediaContainer, NS_OK);
322 
323  rv = mediaContainer->GetContainerType(mMediaContainerType);
324  NS_ENSURE_SUCCESS(rv, rv);
325 
326  // Get video type
327  rv = mMediaVideoStream->GetVideoType(mMediaVideoType);
328  NS_ENSURE_SUCCESS(rv, rv);
329 
330  // Get video width and height
331  rv = mMediaVideoStream->GetVideoWidth(&mMediaVideoWidth);
332  NS_ENSURE_SUCCESS(rv, rv);
333 
334  rv = mMediaVideoStream->GetVideoHeight(&mMediaVideoHeight);
335  NS_ENSURE_SUCCESS(rv, rv);
336 
337  // Get video bit rate
338  rv = mMediaVideoStream->GetBitRate(&mMediaVideoBitRate);
339  NS_ENSURE_SUCCESS(rv, rv);
340 
341  // Get video PAR (Pixel aspect ratio)
342  rv = mMediaVideoStream->GetVideoPAR(&mMediaVideoPARNumerator,
343  &mMediaVideoPARDenominator);
344  NS_ENSURE_SUCCESS(rv, rv);
345 
346  // Get video frame rate
347  rv = mMediaVideoStream->GetVideoFrameRate(&mMediaVideoFRNumerator,
348  &mMediaVideoFRDenominator);
349  NS_ENSURE_SUCCESS(rv, rv);
350 
351  // TODO: Get additional Video properties
352 
353  // Retrive all the audio properties if available
354  if (mMediaAudioStream) {
355  // Get Audio type
356  rv = mMediaAudioStream->GetAudioType(mMediaAudioType);
357  NS_ENSURE_SUCCESS(rv, rv);
358 
359  // Get Audio bit rate
360  rv = mMediaAudioStream->GetBitRate(&mMediaAudioBitRate);
361  NS_ENSURE_SUCCESS(rv, rv);
362 
363  // Get Audio sample rate
364  rv = mMediaAudioStream->GetSampleRate(&mMediaAudioSampleRate);
365  NS_ENSURE_SUCCESS(rv, rv);
366 
367  // Get Audio channels
368  rv = mMediaAudioStream->GetChannels(&mMediaAudioChannels);
369  NS_ENSURE_SUCCESS(rv, rv);
370 
371  // TODO: Get additional audio properties
372  }
373 
374  // Get supported mime types
375  PRUint32 mimeTypesLength;
376  char **mimeTypes;
377  rv = mDeviceCapabilities->GetSupportedMimeTypes(mContentType,
378  &mimeTypesLength,
379  &mimeTypes);
380 
381  if (NS_SUCCEEDED(rv) && mimeTypesLength > 0) {
382  sbAutoNSArray<char*> autoMimeTypes(mimeTypes, mimeTypesLength);
383  for (PRUint32 mimeTypeIndex = 0;
384  mimeTypeIndex < mimeTypesLength;
385  ++mimeTypeIndex) {
386  NS_ConvertASCIItoUTF16 mimeType(mimeTypes[mimeTypeIndex]);
387 
388  nsISupports** formatTypes;
389  PRUint32 formatTypeCount;
390  rv = mDeviceCapabilities->GetFormatTypes(mContentType,
391  mimeType,
392  &formatTypeCount,
393  &formatTypes);
394  NS_ENSURE_SUCCESS(rv, rv);
395  sbAutoFreeXPCOMPointerArray<nsISupports> freeFormats(formatTypeCount,
396  formatTypes);
397 
398  for (PRUint32 formatIndex = 0;
399  formatIndex < formatTypeCount;
400  formatIndex++)
401  {
402  nsCOMPtr<sbIVideoFormatType> videoFormat = do_QueryInterface(
403  formatTypes[formatIndex], &rv);
404  if (NS_SUCCEEDED(rv) && videoFormat) {
405  // Compare container type
406  nsCString deviceContainerType;
407  rv = videoFormat->GetContainerType(deviceContainerType);
408  NS_ENSURE_SUCCESS(rv, rv);
409 
410  // Container type not equal
411  if (!StringEqualsToCString(mMediaContainerType, deviceContainerType)) {
412  LOG(("Not match! media container type: %s, device container type: %s",
413  NS_ConvertUTF16toUTF8(mMediaContainerType).BeginReading(),
414  deviceContainerType.BeginReading()));
415  continue;
416  }
417 
418  // Get device video stream
419  nsCOMPtr<sbIDevCapVideoStream> videoStream;
420  rv = videoFormat->GetVideoStream(getter_AddRefs(videoStream));
421  NS_ENSURE_SUCCESS(rv, rv);
422 
423  // Skip to the next format
424  if (!videoStream) {
425  LOG(("%s[%p] -- Empty video stream for supported video format",
426  __FUNCTION__, this));
427  continue;
428  }
429 
430  rv = CompareVideoStream(videoStream, aCompatible);
431  NS_ENSURE_SUCCESS(rv, rv);
432  if (!(*aCompatible)) {
433  LOG(("%s[%p] Video stream incompatible", __FUNCTION__, this));
434  continue;
435  }
436 
437  if (mMediaAudioStream) {
438  // Get device audio stream
439  nsCOMPtr<sbIDevCapAudioStream> audioStream;
440  rv = videoFormat->GetAudioStream(getter_AddRefs(audioStream));
441  NS_ENSURE_SUCCESS(rv, rv);
442 
443  // Skip to the next format
444  if (!audioStream) {
445  LOG(("%s[%p] -- Empty audio stream for supported video format",
446  __FUNCTION__, this));
447  continue;
448  }
449 
450  rv = CompareAudioStream(audioStream, aCompatible);
451  NS_ENSURE_SUCCESS(rv, rv);
452  if (!(*aCompatible)) {
453  LOG(("%s[%p] Audio stream incompatible", __FUNCTION__, this));
454  continue;
455  }
456  }
457 
458  // Getting this far means we got a match and have set aCompatible.
459  LOG(("%s[%p] Stream is compatible", __FUNCTION__, this));
460  return NS_OK;
461  }
462  }
463  }
464  }
465 
466  return NS_OK;
467 }
468 
469 nsresult
470 sbDeviceCapsCompatibility::CompareVideoStream(
471  sbIDevCapVideoStream* aVideoStream,
472  PRBool* aCompatible)
473 {
474  TRACE(("%s[%p]", __FUNCTION__, this));
475  NS_ENSURE_ARG_POINTER(aVideoStream);
476  NS_ENSURE_ARG_POINTER(aCompatible);
477  NS_ENSURE_TRUE(mMediaVideoStream, NS_ERROR_NOT_INITIALIZED);
478 
479  nsresult rv;
480  *aCompatible = PR_FALSE;
481 
482  // Compare video type
483  nsCString deviceVideoType;
484  rv = aVideoStream->GetType(deviceVideoType);
485  NS_ENSURE_SUCCESS(rv, rv);
486 
487  // Video type not equal. Not compatible.
488  if (!StringEqualsToCString(mMediaVideoType, deviceVideoType)) {
489  LOG(("Not match! media video type: %s, device video type: %s",
490  NS_ConvertUTF16toUTF8(mMediaVideoType).BeginReading(),
491  deviceVideoType.BeginReading()));
492  return NS_OK;
493  }
494 
495  rv = CompareVideoWidthAndHeight(aVideoStream, aCompatible);
496  NS_ENSURE_SUCCESS(rv, rv);
497  if (!(*aCompatible))
498  return NS_OK;
499 
500  // Video bit rate could be unknown in the media file.
501  if (mMediaVideoBitRate) {
502  rv = CompareVideoBitRate(aVideoStream, aCompatible);
503  NS_ENSURE_SUCCESS(rv, rv);
504  if (!(*aCompatible))
505  return NS_OK;
506  }
507 
508  rv = CompareVideoPAR(aVideoStream, aCompatible);
509  NS_ENSURE_SUCCESS(rv, rv);
510  if (!(*aCompatible))
511  return NS_OK;
512 
513  rv = CompareVideoFrameRate(aVideoStream, aCompatible);
514  NS_ENSURE_SUCCESS(rv, rv);
515  if (!(*aCompatible))
516  return NS_OK;
517 
518  // TODO:Insert the comparison for additional properties here
519 
520  // Compatible and return.
521  return NS_OK;
522 }
523 
524 nsresult
525 sbDeviceCapsCompatibility::CompareAudioStream(
526  sbIDevCapAudioStream* aAudioStream,
527  PRBool *aCompatible)
528 {
529  TRACE(("%s[%p]", __FUNCTION__, this));
530  NS_ENSURE_ARG_POINTER(aAudioStream);
531  NS_ENSURE_ARG_POINTER(aCompatible);
532  NS_ENSURE_TRUE(mMediaAudioStream, NS_ERROR_NOT_INITIALIZED);
533 
534  nsresult rv;
535  *aCompatible = PR_FALSE;
536 
537  // Compare audio type
538  nsCString deviceAudioType;
539  rv = aAudioStream->GetType(deviceAudioType);
540  NS_ENSURE_SUCCESS(rv, rv);
541 
542  // Audio type not equal. Not compatible.
543  if (!StringEqualsToCString(mMediaAudioType, deviceAudioType)) {
544  LOG(("Not match! media audio type: %s, device audio type: %s",
545  NS_ConvertUTF16toUTF8(mMediaAudioType).BeginReading(),
546  deviceAudioType.BeginReading()));
547  return NS_OK;
548  }
549 
550  // Audio bit rate could be unknown in the media file.
551  if (mMediaAudioBitRate) {
552  rv = CompareAudioBitRate(aAudioStream, aCompatible);
553  NS_ENSURE_SUCCESS(rv, rv);
554  if (!(*aCompatible))
555  return NS_OK;
556  }
557 
558  rv = CompareAudioSampleRate(aAudioStream, aCompatible);
559  NS_ENSURE_SUCCESS(rv, rv);
560  if (!(*aCompatible))
561  return NS_OK;
562 
563  rv = CompareAudioChannels(aAudioStream, aCompatible);
564  NS_ENSURE_SUCCESS(rv, rv);
565  if (!(*aCompatible))
566  return NS_OK;
567 
568  // TODO:Insert the comparison for additional properties here
569 
570  // Compatible and return.
571  return NS_OK;
572 }
573 
574 #ifdef PR_LOGGING
575 static nsresult GetDevCapRangeValues(sbIDevCapRange *aCapRange,
576  PRInt32 *aMin,
577  PRInt32 *aMax,
578  PRInt32 *aStep)
579 {
580  NS_ENSURE_ARG_POINTER(aCapRange);
581  NS_ENSURE_ARG_POINTER(aMin);
582  NS_ENSURE_ARG_POINTER(aMax);
583  NS_ENSURE_ARG_POINTER(aStep);
584 
585  nsresult rv = aCapRange->GetMin(aMin);
586  NS_ENSURE_SUCCESS(rv, rv);
587 
588  rv = aCapRange->GetMax(aMax);
589  NS_ENSURE_SUCCESS(rv, rv);
590 
591  rv = aCapRange->GetStep(aStep);
592  NS_ENSURE_SUCCESS(rv, rv);
593 
594  return NS_OK;
595 }
596 #endif
597 
598 nsresult
599 sbDeviceCapsCompatibility::CompareVideoWidthAndHeight(
600  sbIDevCapVideoStream* aVideoStream,
601  PRBool* aCompatible)
602 {
603  TRACE(("%s[%p]", __FUNCTION__, this));
604  NS_ENSURE_ARG_POINTER(aVideoStream);
605  NS_ENSURE_ARG_POINTER(aCompatible);
606 
607  nsresult rv;
608 
609  // Get supported widths and heights from device capabilities
610  nsCOMPtr<sbIDevCapRange> deviceSupportedWidths;
611  rv = aVideoStream->GetSupportedWidths(
612  getter_AddRefs(deviceSupportedWidths));
613  NS_ENSURE_SUCCESS(rv, rv);
614 
615  nsCOMPtr<sbIDevCapRange> deviceSupportedHeights;
616  rv = aVideoStream->GetSupportedHeights(
617  getter_AddRefs(deviceSupportedHeights));
618  NS_ENSURE_SUCCESS(rv, rv);
619 
620  // Compare width and height
621  if (deviceSupportedWidths && deviceSupportedHeights) {
622  PRBool inRange = PR_FALSE;
623  rv = deviceSupportedWidths->IsValueInRange(mMediaVideoWidth, &inRange);
624  NS_ENSURE_SUCCESS(rv, rv);
625 
626  // Video width not in range. Not compatible.
627  if (!inRange) {
628 #ifdef PR_LOGGING
629  PRInt32 min, max, step;
630  rv = GetDevCapRangeValues(deviceSupportedWidths, &min, &max, &step);
631  NS_ENSURE_SUCCESS(rv, rv);
632  LOG(("media video width (%d) not in supported range "
633  "(min: %d, max: %d, step: %d)",
634  mMediaVideoWidth, min, max, step));
635 #endif
636  return NS_OK;
637  }
638 
639  rv = deviceSupportedHeights->IsValueInRange(mMediaVideoHeight, &inRange);
640  NS_ENSURE_SUCCESS(rv, rv);
641 
642  if (!inRange) {
643 #ifdef PR_LOGGING
644  PRInt32 min, max, step;
645  rv = GetDevCapRangeValues(deviceSupportedHeights, &min, &max, &step);
646  NS_ENSURE_SUCCESS(rv, rv);
647  LOG(("media video height (%d) not in supported range "
648  "(min: %d, max: %d, step: %d)",
649  mMediaVideoWidth, min, max, step));
650 #endif
651  return NS_OK;
652  }
653 
654  *aCompatible = inRange;
655  }
656  // Fall back to the array of supported sizes.
657  else {
658  nsCOMPtr<nsIArray> deviceSupportedExplicitSizes;
659  rv = aVideoStream->GetSupportedExplicitSizes(
660  getter_AddRefs(deviceSupportedExplicitSizes));
661  NS_ENSURE_SUCCESS(rv, rv);
662 
663  PRUint32 length;
664  rv = deviceSupportedExplicitSizes->GetLength(&length);
665  NS_ENSURE_SUCCESS(rv, rv);
666  NS_ASSERTION(length > 0, "supported sizes must not be empty!");
667 
668  if (length > 1) {
669  PRBool match = PR_FALSE;
670  for (PRUint32 index = 0; index < length; ++index) {
671  nsCOMPtr<sbIImageSize> supportedSize =
672  do_QueryElementAt(deviceSupportedExplicitSizes, index, &rv);
673  NS_ENSURE_SUCCESS(rv, rv);
674 
675  PRInt32 width, height;
676  rv = supportedSize->GetWidth(&width);
677  NS_ENSURE_SUCCESS(rv, rv);
678  rv = supportedSize->GetHeight(&height);
679  NS_ENSURE_SUCCESS(rv, rv);
680 
681  // Match. Compatible.
682  if (mMediaVideoWidth == width && mMediaVideoHeight == height) {
683  match = PR_TRUE;
684  break;
685  }
686 
687  LOG(("media video width/height (%d/%d) not equal to explicit "
688  "size item[%d] (width: %d, height: %d)",
689  mMediaVideoWidth, mMediaVideoHeight, index, width, height));
690  }
691 
692  if (!match) {
693  LOG(("media video width/height not in device explicit size array!"));
694  return NS_OK;
695  }
696 
697  *aCompatible = match;
698  }
699  // Single entry means 'recommended' size and arbitrary dimensions
700  // are supported.
701  else if (length == 1)
702  *aCompatible = PR_TRUE;
703  }
704  return NS_OK;
705 }
706 
707 nsresult
708 sbDeviceCapsCompatibility::CompareVideoBitRate(
709  sbIDevCapVideoStream* aVideoStream,
710  PRBool* aCompatible)
711 {
712  TRACE(("%s[%p]", __FUNCTION__, this));
713  NS_ENSURE_ARG_POINTER(aVideoStream);
714  NS_ENSURE_ARG_POINTER(aCompatible);
715 
716  nsresult rv;
717  *aCompatible = PR_FALSE;
718 
719  // Compare video bit rate
720  nsCOMPtr<sbIDevCapRange> deviceSupportedBitRates;
721  rv = aVideoStream->GetSupportedBitRates(
722  getter_AddRefs(deviceSupportedBitRates));
723  NS_ENSURE_SUCCESS(rv, rv);
724 
725  rv = deviceSupportedBitRates->IsValueInRange(mMediaVideoBitRate, aCompatible);
726  NS_ENSURE_SUCCESS(rv, rv);
727 
728 #ifdef PR_LOGGING
729  if (!(*aCompatible)) {
730  PRInt32 min, max, step;
731  rv = GetDevCapRangeValues(deviceSupportedBitRates, &min, &max, &step);
732  NS_ENSURE_SUCCESS(rv, rv);
733  LOG(("media video bit rate (%d) not in supported range "
734  "(min: %d, max: %d, step: %d)",
735  mMediaVideoBitRate, min, max, step));
736  }
737 #endif
738 
739  return NS_OK;
740 }
741 
742 nsresult
743 sbDeviceCapsCompatibility::CompareVideoPAR(sbIDevCapVideoStream *aVideoStream,
744  PRBool *aCompatible)
745 {
746  TRACE(("%s[%p]", __FUNCTION__, this));
747  NS_ENSURE_ARG_POINTER(aVideoStream);
748  NS_ENSURE_ARG_POINTER(aCompatible);
749 
750  nsresult rv;
751  *aCompatible = PR_FALSE;
752 
753  // Compare video PAR.
754  PRBool isRange = PR_FALSE;
755  rv = aVideoStream->GetDoesSupportPARRange(&isRange);
756  NS_ENSURE_SUCCESS(rv, rv);
757 
758  PRUint32 numerator, denominator;
759  sbFraction videoParFraction(mMediaVideoPARNumerator,
760  mMediaVideoPARDenominator);
761 
762  if (isRange) {
763  // Decide to use either the min par or the max par value.
764  nsCOMPtr<sbIDevCapFraction> minSupportedPAR;
765  rv = aVideoStream->GetMinimumSupportedPAR(getter_AddRefs(minSupportedPAR));
766  NS_ENSURE_SUCCESS(rv, rv);
767  rv = minSupportedPAR->GetNumerator(&numerator);
768  NS_ENSURE_SUCCESS(rv, rv);
769  rv = minSupportedPAR->GetDenominator(&denominator);
770  NS_ENSURE_SUCCESS(rv, rv);
771  sbFraction minPARFraction(numerator, denominator);
772 
773  nsCOMPtr<sbIDevCapFraction> maxSupportedPAR;
774  rv = aVideoStream->GetMaximumSupportedPAR(getter_AddRefs(maxSupportedPAR));
775  NS_ENSURE_SUCCESS(rv, rv);
776  rv = maxSupportedPAR->GetNumerator(&numerator);
777  NS_ENSURE_SUCCESS(rv, rv);
778  rv = maxSupportedPAR->GetDenominator(&denominator);
779  NS_ENSURE_SUCCESS(rv, rv);
780  sbFraction maxPARFraction(numerator, denominator);
781 
782  if (videoParFraction >= minPARFraction &&
783  videoParFraction <= maxPARFraction)
784  {
785  *aCompatible = PR_TRUE;
786  }
787  else {
788  LOG(("media video PAR (%d/%d) not in min/max range of supported PARS!"
789  "min=(%d/%d) max=(%d/%d)",
790  mMediaVideoPARNumerator, mMediaVideoPARDenominator,
791  minPARFraction.Numerator(), minPARFraction.Denominator(),
792  maxPARFraction.Numerator(), maxPARFraction.Denominator()));
793  }
794  }
795  else {
796  nsCOMPtr<nsIArray> supportedPARsArray;
797  rv = aVideoStream->GetSupportedPARs(getter_AddRefs(supportedPARsArray));
798  NS_ENSURE_SUCCESS(rv, rv);
799 
800  PRUint32 length;
801  rv = supportedPARsArray->GetLength(&length);
802  NS_ENSURE_SUCCESS(rv, rv);
803 
804  for (PRUint32 i = 0; i < length; i++) {
805  nsCOMPtr<sbIDevCapFraction> curPARFraction =
806  do_QueryElementAt(supportedPARsArray, i, &rv);
807  NS_ENSURE_SUCCESS(rv, rv);
808 
809  rv = curPARFraction->GetNumerator(&numerator);
810  NS_ENSURE_SUCCESS(rv, rv);
811  rv = curPARFraction->GetDenominator(&denominator);
812  NS_ENSURE_SUCCESS(rv, rv);
813 
814  // Match
815  if (videoParFraction == sbFraction(numerator, denominator)) {
816  *aCompatible = PR_TRUE;
817  break;
818  }
819 
820  LOG(("media video PAR (%d/%d) not equal to supported PAR item[%d] (%d/%d)",
821  mMediaVideoPARNumerator, mMediaVideoPARDenominator, i,
822  numerator, denominator));
823  }
824  }
825 
826 #ifdef PR_LOGGING
827  if (!(*aCompatible)) {
828  LOG(("media video PAR not in device supported array!"));
829  }
830 #endif
831 
832  return NS_OK;
833 }
834 
835 nsresult
836 sbDeviceCapsCompatibility::CompareVideoFrameRate(
837  sbIDevCapVideoStream* aVideoStream,
838  PRBool* aCompatible)
839 {
840  TRACE(("%s[%p]", __FUNCTION__, this));
841  NS_ENSURE_ARG_POINTER(aVideoStream);
842  NS_ENSURE_ARG_POINTER(aCompatible);
843 
844  nsresult rv;
845  *aCompatible = PR_FALSE;
846 
847  // Compare frame rates.
848  PRBool isRange = PR_FALSE;
849  rv = aVideoStream->GetDoesSupportFrameRateRange(&isRange);
850  NS_ENSURE_SUCCESS(rv, rv);
851 
852  PRUint32 numerator, denominator;
853  sbFraction videoFrameRateFraction(mMediaVideoFRNumerator,
854  mMediaVideoFRDenominator);
855 
856  if (isRange) {
857  // Decide to use either the min or the max frame rate value.
858  nsCOMPtr<sbIDevCapFraction> minSupportedFR;
859  rv = aVideoStream->GetMinimumSupportedFrameRate(
860  getter_AddRefs(minSupportedFR));
861  NS_ENSURE_SUCCESS(rv, rv);
862  rv = minSupportedFR->GetNumerator(&numerator);
863  NS_ENSURE_SUCCESS(rv, rv);
864  rv = minSupportedFR->GetDenominator(&denominator);
865  NS_ENSURE_SUCCESS(rv, rv);
866  sbFraction minFRFraction(numerator, denominator);
867 
868  nsCOMPtr<sbIDevCapFraction> maxSupportedFR;
869  rv = aVideoStream->GetMaximumSupportedFrameRate(
870  getter_AddRefs(maxSupportedFR));
871  NS_ENSURE_SUCCESS(rv, rv);
872  rv = maxSupportedFR->GetNumerator(&numerator);
873  NS_ENSURE_SUCCESS(rv, rv);
874  rv = maxSupportedFR->GetDenominator(&denominator);
875  NS_ENSURE_SUCCESS(rv, rv);
876  sbFraction maxFRFraction(numerator, denominator);
877 
878  if (videoFrameRateFraction >= minFRFraction &&
879  videoFrameRateFraction <= maxFRFraction)
880  {
881  *aCompatible = PR_TRUE;
882  }
883  else {
884  LOG(("media video frame rate (%d/%d) not in min/max range of "
885  "supported frame rates! min=(%d/%d) max=(%d/%d)",
886  mMediaVideoPARNumerator, mMediaVideoPARDenominator,
887  minFRFraction.Numerator(), minFRFraction.Denominator(),
888  maxFRFraction.Numerator(), maxFRFraction.Denominator()));
889  }
890  }
891  else {
892  nsCOMPtr<nsIArray> supportedFrameRatesFraction;
893  rv = aVideoStream->GetSupportedFrameRates(
894  getter_AddRefs(supportedFrameRatesFraction));
895  NS_ENSURE_SUCCESS(rv, rv);
896 
897  PRUint32 length;
898  rv = supportedFrameRatesFraction->GetLength(&length);
899  NS_ENSURE_SUCCESS(rv, rv);
900 
901  for (PRUint32 i = 0; i < length; i++) {
902  nsCOMPtr<sbIDevCapFraction> curFrameRateFraction =
903  do_QueryElementAt(supportedFrameRatesFraction, i, &rv);
904  NS_ENSURE_SUCCESS(rv, rv);
905 
906  rv = curFrameRateFraction->GetNumerator(&numerator);
907  NS_ENSURE_SUCCESS(rv, rv);
908  rv = curFrameRateFraction->GetDenominator(&denominator);
909  NS_ENSURE_SUCCESS(rv, rv);
910 
911  // Match
912  if (videoFrameRateFraction == sbFraction(numerator, denominator)) {
913  *aCompatible = PR_TRUE;
914  break;
915  }
916 
917  LOG(("media video frame rate (%d/%d) not equal to supported "
918  "frame rate item[%d] (%d/%d)",
919  mMediaVideoPARNumerator, mMediaVideoPARDenominator, i,
920  numerator, denominator));
921  }
922  }
923 
924 #ifdef PR_LOGGING
925  if (!(*aCompatible)) {
926  LOG(("media video frame rate not in device supported array!"));
927  }
928 #endif
929 
930  return NS_OK;
931 }
932 
933 nsresult
934 sbDeviceCapsCompatibility::CompareAudioBitRate(
935  sbIDevCapAudioStream* aAudioStream,
936  PRBool* aCompatible)
937 {
938  TRACE(("%s[%p]", __FUNCTION__, this));
939  NS_ENSURE_ARG_POINTER(aAudioStream);
940  NS_ENSURE_ARG_POINTER(aCompatible);
941 
942  nsresult rv;
943  *aCompatible = PR_FALSE;
944 
945  // Compare audio bit rate
946  nsCOMPtr<sbIDevCapRange> deviceSupportedBitRates;
947  rv = aAudioStream->GetSupportedBitRates(
948  getter_AddRefs(deviceSupportedBitRates));
949  NS_ENSURE_SUCCESS(rv, rv);
950 
951  rv = deviceSupportedBitRates->IsValueInRange(mMediaAudioBitRate, aCompatible);
952  NS_ENSURE_SUCCESS(rv, rv);
953 
954 #ifdef PR_LOGGING
955  if (!(*aCompatible)) {
956  PRInt32 min, max, step;
957  rv = GetDevCapRangeValues(deviceSupportedBitRates, &min, &max, &step);
958  NS_ENSURE_SUCCESS(rv, rv);
959  LOG(("media audio bit rate (%d) not in supported range "
960  "(min: %d, max: %d, step: %d)",
961  mMediaAudioBitRate, min, max, step));
962  }
963 #endif
964 
965  return NS_OK;
966 }
967 
968 nsresult
969 sbDeviceCapsCompatibility::CompareAudioSampleRate(
970  sbIDevCapAudioStream* aAudioStream,
971  PRBool* aCompatible)
972 {
973  TRACE(("%s[%p]", __FUNCTION__, this));
974  NS_ENSURE_ARG_POINTER(aAudioStream);
975  NS_ENSURE_ARG_POINTER(aCompatible);
976 
977  nsresult rv;
978  *aCompatible = PR_FALSE;
979 
980  // Compare audio sample bit
981  nsCOMPtr<sbIDevCapRange> deviceSupportedSampleRates;
982  rv = aAudioStream->GetSupportedSampleRates(
983  getter_AddRefs(deviceSupportedSampleRates));
984  NS_ENSURE_SUCCESS(rv, rv);
985 
986  rv = deviceSupportedSampleRates->IsValueInRange(mMediaAudioSampleRate,
987  aCompatible);
988  NS_ENSURE_SUCCESS(rv, rv);
989 
990 #ifdef PR_LOGGING
991  if (!(*aCompatible)) {
992  PRInt32 min, max, step;
993  rv = GetDevCapRangeValues(deviceSupportedSampleRates, &min, &max, &step);
994  NS_ENSURE_SUCCESS(rv, rv);
995  LOG(("media audio sample rate (%d) not in supported range "
996  "(min: %d, max: %d, step: %d)",
997  mMediaAudioSampleRate, min, max, step));
998  }
999 #endif
1000 
1001  return NS_OK;
1002 }
1003 
1004 nsresult
1005 sbDeviceCapsCompatibility::CompareAudioChannels(
1006  sbIDevCapAudioStream* aAudioStream,
1007  PRBool* aCompatible)
1008 {
1009  TRACE(("%s[%p]", __FUNCTION__, this));
1010  NS_ENSURE_ARG_POINTER(aAudioStream);
1011  NS_ENSURE_ARG_POINTER(aCompatible);
1012 
1013  nsresult rv;
1014  *aCompatible = PR_FALSE;
1015 
1016  // Compare audio channels
1017  nsCOMPtr<sbIDevCapRange> deviceSupportedChannels;
1018  rv = aAudioStream->GetSupportedChannels(
1019  getter_AddRefs(deviceSupportedChannels));
1020  NS_ENSURE_SUCCESS(rv, rv);
1021 
1022  rv = deviceSupportedChannels->IsValueInRange(mMediaAudioChannels,
1023  aCompatible);
1024  NS_ENSURE_SUCCESS(rv, rv);
1025 
1026 #ifdef PR_LOGGING
1027  if (!(*aCompatible)) {
1028  PRInt32 min, max, step;
1029  rv = GetDevCapRangeValues(deviceSupportedChannels, &min, &max, &step);
1030  NS_ENSURE_SUCCESS(rv, rv);
1031  LOG(("media audio channel (%d) not in supported range "
1032  "(min: %d, max: %d, step: %d)",
1033  mMediaAudioChannels, min, max, step));
1034  }
1035 #endif
1036 
1037  return NS_OK;
1038 }
return NS_OK
[UNIMPLEMENTED UNTIL AFTER 0.3]
function width(ele) rect(ele).width
#define LOG(args)
NS_IMPL_THREADSAFE_ISUPPORTS1(sbDeviceCapsCompatibility, sbIDeviceCapsCompatibility) sbDeviceCapsCompatibility
ExtensionSchemeMatcher prototype match
static PRBool StringEqualsToCString(nsAString &string1, nsACString &string2)
_updateDatepicker height
This service determines if a media file is compatible with a particular device.
#define TRACE(args)
#define min(a, b)
_getSelectedPageStyle s i