|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef VideoUtils_h |
|
8 #define VideoUtils_h |
|
9 |
|
10 #include "mozilla/Attributes.h" |
|
11 #include "mozilla/ReentrantMonitor.h" |
|
12 #include "mozilla/CheckedInt.h" |
|
13 |
|
14 #if !(defined(XP_WIN) || defined(XP_MACOSX) || defined(LINUX)) || \ |
|
15 defined(MOZ_ASAN) |
|
16 // For MEDIA_THREAD_STACK_SIZE |
|
17 #include "nsIThreadManager.h" |
|
18 #endif |
|
19 #include "nsThreadUtils.h" |
|
20 #include "prtime.h" |
|
21 #include "AudioSampleFormat.h" |
|
22 |
|
23 using mozilla::CheckedInt64; |
|
24 using mozilla::CheckedUint64; |
|
25 using mozilla::CheckedInt32; |
|
26 using mozilla::CheckedUint32; |
|
27 |
|
28 struct nsIntSize; |
|
29 struct nsIntRect; |
|
30 |
|
31 // This file contains stuff we'd rather put elsewhere, but which is |
|
32 // dependent on other changes which we don't want to wait for. We plan to |
|
33 // remove this file in the near future. |
|
34 |
|
35 |
|
36 // This belongs in xpcom/monitor/Monitor.h, once we've made |
|
37 // mozilla::Monitor non-reentrant. |
|
38 namespace mozilla { |
|
39 |
|
40 /** |
|
41 * ReentrantMonitorConditionallyEnter |
|
42 * |
|
43 * Enters the supplied monitor only if the conditional value |aEnter| is true. |
|
44 * E.g. Used to allow unmonitored read access on the decode thread, |
|
45 * and monitored access on all other threads. |
|
46 */ |
|
47 class MOZ_STACK_CLASS ReentrantMonitorConditionallyEnter |
|
48 { |
|
49 public: |
|
50 ReentrantMonitorConditionallyEnter(bool aEnter, |
|
51 ReentrantMonitor &aReentrantMonitor) : |
|
52 mReentrantMonitor(nullptr) |
|
53 { |
|
54 MOZ_COUNT_CTOR(ReentrantMonitorConditionallyEnter); |
|
55 if (aEnter) { |
|
56 mReentrantMonitor = &aReentrantMonitor; |
|
57 NS_ASSERTION(mReentrantMonitor, "null monitor"); |
|
58 mReentrantMonitor->Enter(); |
|
59 } |
|
60 } |
|
61 ~ReentrantMonitorConditionallyEnter(void) |
|
62 { |
|
63 if (mReentrantMonitor) { |
|
64 mReentrantMonitor->Exit(); |
|
65 } |
|
66 MOZ_COUNT_DTOR(ReentrantMonitorConditionallyEnter); |
|
67 } |
|
68 private: |
|
69 // Restrict to constructor and destructor defined above. |
|
70 ReentrantMonitorConditionallyEnter(); |
|
71 ReentrantMonitorConditionallyEnter(const ReentrantMonitorConditionallyEnter&); |
|
72 ReentrantMonitorConditionallyEnter& operator =(const ReentrantMonitorConditionallyEnter&); |
|
73 static void* operator new(size_t) CPP_THROW_NEW; |
|
74 static void operator delete(void*); |
|
75 |
|
76 ReentrantMonitor* mReentrantMonitor; |
|
77 }; |
|
78 |
|
79 // Shuts down a thread asynchronously. |
|
80 class ShutdownThreadEvent : public nsRunnable |
|
81 { |
|
82 public: |
|
83 ShutdownThreadEvent(nsIThread* aThread) : mThread(aThread) {} |
|
84 ~ShutdownThreadEvent() {} |
|
85 NS_IMETHOD Run() MOZ_OVERRIDE { |
|
86 mThread->Shutdown(); |
|
87 mThread = nullptr; |
|
88 return NS_OK; |
|
89 } |
|
90 private: |
|
91 nsCOMPtr<nsIThread> mThread; |
|
92 }; |
|
93 |
|
94 class MediaResource; |
|
95 |
|
96 namespace dom { |
|
97 class TimeRanges; |
|
98 } |
|
99 |
|
100 // Estimates the buffered ranges of a MediaResource using a simple |
|
101 // (byteOffset/length)*duration method. Probably inaccurate, but won't |
|
102 // do file I/O, and can be used when we don't have detailed knowledge |
|
103 // of the byte->time mapping of a resource. aDurationUsecs is the duration |
|
104 // of the media in microseconds. Estimated buffered ranges are stored in |
|
105 // aOutBuffered. Ranges are 0-normalized, i.e. in the range of (0,duration]. |
|
106 void GetEstimatedBufferedTimeRanges(mozilla::MediaResource* aStream, |
|
107 int64_t aDurationUsecs, |
|
108 mozilla::dom::TimeRanges* aOutBuffered); |
|
109 |
|
110 // Converts from number of audio frames (aFrames) to microseconds, given |
|
111 // the specified audio rate (aRate). Stores result in aOutUsecs. Returns true |
|
112 // if the operation succeeded, or false if there was an integer overflow |
|
113 // while calulating the conversion. |
|
114 CheckedInt64 FramesToUsecs(int64_t aFrames, uint32_t aRate); |
|
115 |
|
116 // Converts from microseconds (aUsecs) to number of audio frames, given the |
|
117 // specified audio rate (aRate). Stores the result in aOutFrames. Returns |
|
118 // true if the operation succeeded, or false if there was an integer |
|
119 // overflow while calulating the conversion. |
|
120 CheckedInt64 UsecsToFrames(int64_t aUsecs, uint32_t aRate); |
|
121 |
|
122 // Number of microseconds per second. 1e6. |
|
123 static const int64_t USECS_PER_S = 1000000; |
|
124 |
|
125 // Number of microseconds per millisecond. |
|
126 static const int64_t USECS_PER_MS = 1000; |
|
127 |
|
128 // Converts seconds to milliseconds. |
|
129 #define MS_TO_SECONDS(s) ((double)(s) / (PR_MSEC_PER_SEC)) |
|
130 |
|
131 // Converts from seconds to microseconds. Returns failure if the resulting |
|
132 // integer is too big to fit in an int64_t. |
|
133 nsresult SecondsToUsecs(double aSeconds, int64_t& aOutUsecs); |
|
134 |
|
135 // The maximum height and width of the video. Used for |
|
136 // sanitizing the memory allocation of the RGB buffer. |
|
137 // The maximum resolution we anticipate encountering in the |
|
138 // wild is 2160p - 3840x2160 pixels. |
|
139 static const int32_t MAX_VIDEO_WIDTH = 4000; |
|
140 static const int32_t MAX_VIDEO_HEIGHT = 3000; |
|
141 |
|
142 // Scales the display rect aDisplay by aspect ratio aAspectRatio. |
|
143 // Note that aDisplay must be validated by IsValidVideoRegion() |
|
144 // before being used! |
|
145 void ScaleDisplayByAspectRatio(nsIntSize& aDisplay, float aAspectRatio); |
|
146 |
|
147 // The amount of virtual memory reserved for thread stacks. |
|
148 #if (defined(XP_WIN) || defined(XP_MACOSX) || defined(LINUX)) && \ |
|
149 !defined(MOZ_ASAN) |
|
150 #define MEDIA_THREAD_STACK_SIZE (128 * 1024) |
|
151 #else |
|
152 // All other platforms use their system defaults. |
|
153 #define MEDIA_THREAD_STACK_SIZE nsIThreadManager::DEFAULT_STACK_SIZE |
|
154 #endif |
|
155 |
|
156 // Downmix multichannel Audio samples to Stereo. |
|
157 // Input are the buffer contains multichannel data, |
|
158 // the number of channels and the number of frames. |
|
159 int DownmixAudioToStereo(mozilla::AudioDataValue* buffer, |
|
160 int channels, |
|
161 uint32_t frames); |
|
162 |
|
163 bool IsVideoContentType(const nsCString& aContentType); |
|
164 |
|
165 // Returns true if it's safe to use aPicture as the picture to be |
|
166 // extracted inside a frame of size aFrame, and scaled up to and displayed |
|
167 // at a size of aDisplay. You should validate the frame, picture, and |
|
168 // display regions before using them to display video frames. |
|
169 bool IsValidVideoRegion(const nsIntSize& aFrame, const nsIntRect& aPicture, |
|
170 const nsIntSize& aDisplay); |
|
171 |
|
172 } // end namespace mozilla |
|
173 |
|
174 #endif |