1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "VideoUtils.h"
6 #include "MediaResource.h"
7 #include "mozilla/dom/TimeRanges.h"
8 #include "nsMathUtils.h"
10 #include "ImageContainer.h"
16 using layers::PlanarYCbCrImage
;
18 // Converts from number of audio frames to microseconds, given the specified
20 CheckedInt64
FramesToUsecs(int64_t aFrames
, uint32_t aRate
) {
21 return (CheckedInt64(aFrames
) * USECS_PER_S
) / aRate
;
24 // Converts from microseconds to number of audio frames, given the specified
26 CheckedInt64
UsecsToFrames(int64_t aUsecs
, uint32_t aRate
) {
27 return (CheckedInt64(aUsecs
) * aRate
) / USECS_PER_S
;
30 static int32_t ConditionDimension(float aValue
)
32 // This will exclude NaNs and too-big values.
33 if (aValue
> 1.0 && aValue
<= INT32_MAX
)
34 return int32_t(NS_round(aValue
));
38 void ScaleDisplayByAspectRatio(nsIntSize
& aDisplay
, float aAspectRatio
)
40 if (aAspectRatio
> 1.0) {
41 // Increase the intrinsic width
42 aDisplay
.width
= ConditionDimension(aAspectRatio
* aDisplay
.width
);
44 // Increase the intrinsic height
45 aDisplay
.height
= ConditionDimension(aDisplay
.height
/ aAspectRatio
);
49 static int64_t BytesToTime(int64_t offset
, int64_t length
, int64_t durationUs
) {
50 NS_ASSERTION(length
> 0, "Must have positive length");
51 double r
= double(offset
) / double(length
);
54 return int64_t(double(durationUs
) * r
);
57 void GetEstimatedBufferedTimeRanges(mozilla::MediaResource
* aStream
,
58 int64_t aDurationUsecs
,
59 mozilla::dom::TimeRanges
* aOutBuffered
)
61 // Nothing to cache if the media takes 0us to play.
62 if (aDurationUsecs
<= 0 || !aStream
|| !aOutBuffered
)
65 // Special case completely cached files. This also handles local files.
66 if (aStream
->IsDataCachedToEndOfResource(0)) {
67 aOutBuffered
->Add(0, double(aDurationUsecs
) / USECS_PER_S
);
71 int64_t totalBytes
= aStream
->GetLength();
73 // If we can't determine the total size, pretend that we have nothing
74 // buffered. This will put us in a state of eternally-low-on-undecoded-data
75 // which is not great, but about the best we can do.
79 int64_t startOffset
= aStream
->GetNextCachedData(0);
80 while (startOffset
>= 0) {
81 int64_t endOffset
= aStream
->GetCachedDataEnd(startOffset
);
82 // Bytes [startOffset..endOffset] are cached.
83 NS_ASSERTION(startOffset
>= 0, "Integer underflow in GetBuffered");
84 NS_ASSERTION(endOffset
>= 0, "Integer underflow in GetBuffered");
86 int64_t startUs
= BytesToTime(startOffset
, totalBytes
, aDurationUsecs
);
87 int64_t endUs
= BytesToTime(endOffset
, totalBytes
, aDurationUsecs
);
88 if (startUs
!= endUs
) {
89 aOutBuffered
->Add(double(startUs
) / USECS_PER_S
,
90 double(endUs
) / USECS_PER_S
);
92 startOffset
= aStream
->GetNextCachedData(endOffset
);
98 IsVideoContentType(const nsCString
& aContentType
)
100 NS_NAMED_LITERAL_CSTRING(video
, "video");
101 if (FindInReadable(video
, aContentType
)) {
108 IsValidVideoRegion(const nsIntSize
& aFrame
, const nsIntRect
& aPicture
,
109 const nsIntSize
& aDisplay
)
112 aFrame
.width
<= PlanarYCbCrImage::MAX_DIMENSION
&&
113 aFrame
.height
<= PlanarYCbCrImage::MAX_DIMENSION
&&
114 aFrame
.width
* aFrame
.height
<= MAX_VIDEO_WIDTH
* MAX_VIDEO_HEIGHT
&&
115 aFrame
.width
* aFrame
.height
!= 0 &&
116 aPicture
.width
<= PlanarYCbCrImage::MAX_DIMENSION
&&
117 aPicture
.x
< PlanarYCbCrImage::MAX_DIMENSION
&&
118 aPicture
.x
+ aPicture
.width
< PlanarYCbCrImage::MAX_DIMENSION
&&
119 aPicture
.height
<= PlanarYCbCrImage::MAX_DIMENSION
&&
120 aPicture
.y
< PlanarYCbCrImage::MAX_DIMENSION
&&
121 aPicture
.y
+ aPicture
.height
< PlanarYCbCrImage::MAX_DIMENSION
&&
122 aPicture
.width
* aPicture
.height
<= MAX_VIDEO_WIDTH
* MAX_VIDEO_HEIGHT
&&
123 aPicture
.width
* aPicture
.height
!= 0 &&
124 aDisplay
.width
<= PlanarYCbCrImage::MAX_DIMENSION
&&
125 aDisplay
.height
<= PlanarYCbCrImage::MAX_DIMENSION
&&
126 aDisplay
.width
* aDisplay
.height
<= MAX_VIDEO_WIDTH
* MAX_VIDEO_HEIGHT
&&
127 aDisplay
.width
* aDisplay
.height
!= 0;
130 } // end namespace mozilla