2010-04-02 07:03:07 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2010-04-02 07:03:07 +04:00
|
|
|
|
2010-04-27 12:53:44 +04:00
|
|
|
#ifndef VideoUtils_h
|
|
|
|
#define VideoUtils_h
|
|
|
|
|
2013-05-30 00:43:41 +04:00
|
|
|
#include "mozilla/Attributes.h"
|
2011-04-29 23:21:57 +04:00
|
|
|
#include "mozilla/ReentrantMonitor.h"
|
2012-05-14 23:50:20 +04:00
|
|
|
#include "mozilla/CheckedInt.h"
|
2010-04-02 07:03:07 +04:00
|
|
|
|
2013-09-06 00:25:17 +04:00
|
|
|
#if !(defined(XP_WIN) || defined(XP_MACOSX) || defined(LINUX)) || \
|
|
|
|
defined(MOZ_ASAN)
|
|
|
|
// For MEDIA_THREAD_STACK_SIZE
|
2011-07-27 07:28:03 +04:00
|
|
|
#include "nsIThreadManager.h"
|
2013-09-06 00:25:17 +04:00
|
|
|
#endif
|
2012-03-28 04:04:20 +04:00
|
|
|
#include "nsThreadUtils.h"
|
2013-06-10 19:30:00 +04:00
|
|
|
#include "prtime.h"
|
2013-09-26 23:06:59 +04:00
|
|
|
#include "AudioSampleFormat.h"
|
2011-06-24 02:08:54 +04:00
|
|
|
|
2012-02-22 16:28:06 +04:00
|
|
|
using mozilla::CheckedInt64;
|
|
|
|
using mozilla::CheckedUint64;
|
|
|
|
using mozilla::CheckedInt32;
|
|
|
|
using mozilla::CheckedUint32;
|
|
|
|
|
2013-09-06 00:25:17 +04:00
|
|
|
struct nsIntSize;
|
2014-02-04 05:49:21 +04:00
|
|
|
struct nsIntRect;
|
2013-09-06 00:25:17 +04:00
|
|
|
|
2010-04-02 07:03:07 +04:00
|
|
|
// This file contains stuff we'd rather put elsewhere, but which is
|
|
|
|
// dependent on other changes which we don't want to wait for. We plan to
|
|
|
|
// remove this file in the near future.
|
|
|
|
|
|
|
|
|
|
|
|
// This belongs in xpcom/monitor/Monitor.h, once we've made
|
|
|
|
// mozilla::Monitor non-reentrant.
|
|
|
|
namespace mozilla {
|
|
|
|
|
2012-12-07 03:27:08 +04:00
|
|
|
/**
|
|
|
|
* ReentrantMonitorConditionallyEnter
|
|
|
|
*
|
|
|
|
* Enters the supplied monitor only if the conditional value |aEnter| is true.
|
|
|
|
* E.g. Used to allow unmonitored read access on the decode thread,
|
|
|
|
* and monitored access on all other threads.
|
|
|
|
*/
|
2013-04-12 07:20:09 +04:00
|
|
|
class MOZ_STACK_CLASS ReentrantMonitorConditionallyEnter
|
2012-12-07 03:27:08 +04:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
ReentrantMonitorConditionallyEnter(bool aEnter,
|
|
|
|
ReentrantMonitor &aReentrantMonitor) :
|
|
|
|
mReentrantMonitor(nullptr)
|
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(ReentrantMonitorConditionallyEnter);
|
|
|
|
if (aEnter) {
|
|
|
|
mReentrantMonitor = &aReentrantMonitor;
|
|
|
|
NS_ASSERTION(mReentrantMonitor, "null monitor");
|
|
|
|
mReentrantMonitor->Enter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
~ReentrantMonitorConditionallyEnter(void)
|
|
|
|
{
|
|
|
|
if (mReentrantMonitor) {
|
|
|
|
mReentrantMonitor->Exit();
|
|
|
|
}
|
|
|
|
MOZ_COUNT_DTOR(ReentrantMonitorConditionallyEnter);
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
// Restrict to constructor and destructor defined above.
|
|
|
|
ReentrantMonitorConditionallyEnter();
|
|
|
|
ReentrantMonitorConditionallyEnter(const ReentrantMonitorConditionallyEnter&);
|
|
|
|
ReentrantMonitorConditionallyEnter& operator =(const ReentrantMonitorConditionallyEnter&);
|
|
|
|
static void* operator new(size_t) CPP_THROW_NEW;
|
|
|
|
static void operator delete(void*);
|
|
|
|
|
|
|
|
ReentrantMonitor* mReentrantMonitor;
|
|
|
|
};
|
|
|
|
|
2012-03-28 04:04:20 +04:00
|
|
|
// Shuts down a thread asynchronously.
|
2013-11-04 02:45:19 +04:00
|
|
|
class ShutdownThreadEvent : public nsRunnable
|
2012-03-28 04:04:20 +04:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
ShutdownThreadEvent(nsIThread* aThread) : mThread(aThread) {}
|
|
|
|
~ShutdownThreadEvent() {}
|
2013-05-30 00:43:41 +04:00
|
|
|
NS_IMETHOD Run() MOZ_OVERRIDE {
|
2012-03-28 04:04:20 +04:00
|
|
|
mThread->Shutdown();
|
2012-07-30 18:20:58 +04:00
|
|
|
mThread = nullptr;
|
2012-03-28 04:04:20 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
nsCOMPtr<nsIThread> mThread;
|
|
|
|
};
|
|
|
|
|
2012-09-03 02:56:29 +04:00
|
|
|
class MediaResource;
|
2010-08-13 06:28:15 +04:00
|
|
|
|
2013-03-02 23:14:44 +04:00
|
|
|
namespace dom {
|
|
|
|
class TimeRanges;
|
|
|
|
}
|
2012-09-03 02:56:29 +04:00
|
|
|
|
|
|
|
// Estimates the buffered ranges of a MediaResource using a simple
|
|
|
|
// (byteOffset/length)*duration method. Probably inaccurate, but won't
|
|
|
|
// do file I/O, and can be used when we don't have detailed knowledge
|
|
|
|
// of the byte->time mapping of a resource. aDurationUsecs is the duration
|
|
|
|
// of the media in microseconds. Estimated buffered ranges are stored in
|
|
|
|
// aOutBuffered. Ranges are 0-normalized, i.e. in the range of (0,duration].
|
|
|
|
void GetEstimatedBufferedTimeRanges(mozilla::MediaResource* aStream,
|
|
|
|
int64_t aDurationUsecs,
|
2013-03-02 23:14:44 +04:00
|
|
|
mozilla::dom::TimeRanges* aOutBuffered);
|
2012-09-03 02:56:29 +04:00
|
|
|
|
2011-09-27 07:31:18 +04:00
|
|
|
// Converts from number of audio frames (aFrames) to microseconds, given
|
2011-09-30 03:34:37 +04:00
|
|
|
// the specified audio rate (aRate). Stores result in aOutUsecs. Returns true
|
|
|
|
// if the operation succeeded, or false if there was an integer overflow
|
2010-08-13 06:28:15 +04:00
|
|
|
// while calulating the conversion.
|
2012-08-22 19:56:38 +04:00
|
|
|
CheckedInt64 FramesToUsecs(int64_t aFrames, uint32_t aRate);
|
2010-08-13 06:28:15 +04:00
|
|
|
|
2011-09-27 07:31:18 +04:00
|
|
|
// Converts from microseconds (aUsecs) to number of audio frames, given the
|
|
|
|
// specified audio rate (aRate). Stores the result in aOutFrames. Returns
|
2011-09-30 03:34:37 +04:00
|
|
|
// true if the operation succeeded, or false if there was an integer
|
2010-08-13 06:28:15 +04:00
|
|
|
// overflow while calulating the conversion.
|
2012-08-22 19:56:38 +04:00
|
|
|
CheckedInt64 UsecsToFrames(int64_t aUsecs, uint32_t aRate);
|
2011-04-14 02:12:23 +04:00
|
|
|
|
|
|
|
// Number of microseconds per second. 1e6.
|
2012-08-22 19:56:38 +04:00
|
|
|
static const int64_t USECS_PER_S = 1000000;
|
2011-04-14 02:12:23 +04:00
|
|
|
|
|
|
|
// Number of microseconds per millisecond.
|
2012-08-22 19:56:38 +04:00
|
|
|
static const int64_t USECS_PER_MS = 1000;
|
2010-08-13 06:28:15 +04:00
|
|
|
|
2013-06-10 19:30:00 +04:00
|
|
|
// Converts seconds to milliseconds.
|
2013-06-19 22:35:04 +04:00
|
|
|
#define MS_TO_SECONDS(s) ((double)(s) / (PR_MSEC_PER_SEC))
|
2013-06-10 19:30:00 +04:00
|
|
|
|
2014-04-01 07:39:04 +04:00
|
|
|
// Converts from seconds to microseconds. Returns failure if the resulting
|
|
|
|
// integer is too big to fit in an int64_t.
|
|
|
|
nsresult SecondsToUsecs(double aSeconds, int64_t& aOutUsecs);
|
|
|
|
|
2011-06-24 02:08:54 +04:00
|
|
|
// The maximum height and width of the video. Used for
|
|
|
|
// sanitizing the memory allocation of the RGB buffer.
|
|
|
|
// The maximum resolution we anticipate encountering in the
|
|
|
|
// wild is 2160p - 3840x2160 pixels.
|
2012-08-22 19:56:38 +04:00
|
|
|
static const int32_t MAX_VIDEO_WIDTH = 4000;
|
|
|
|
static const int32_t MAX_VIDEO_HEIGHT = 3000;
|
2011-06-24 02:08:54 +04:00
|
|
|
|
|
|
|
// Scales the display rect aDisplay by aspect ratio aAspectRatio.
|
2014-02-04 05:49:21 +04:00
|
|
|
// Note that aDisplay must be validated by IsValidVideoRegion()
|
2011-06-24 02:08:54 +04:00
|
|
|
// before being used!
|
|
|
|
void ScaleDisplayByAspectRatio(nsIntSize& aDisplay, float aAspectRatio);
|
|
|
|
|
2011-07-27 07:28:03 +04:00
|
|
|
// The amount of virtual memory reserved for thread stacks.
|
2012-06-03 23:43:09 +04:00
|
|
|
#if (defined(XP_WIN) || defined(XP_MACOSX) || defined(LINUX)) && \
|
|
|
|
!defined(MOZ_ASAN)
|
2011-07-27 07:28:03 +04:00
|
|
|
#define MEDIA_THREAD_STACK_SIZE (128 * 1024)
|
|
|
|
#else
|
|
|
|
// All other platforms use their system defaults.
|
|
|
|
#define MEDIA_THREAD_STACK_SIZE nsIThreadManager::DEFAULT_STACK_SIZE
|
|
|
|
#endif
|
|
|
|
|
2013-09-26 23:06:59 +04:00
|
|
|
// Downmix multichannel Audio samples to Stereo.
|
|
|
|
// Input are the buffer contains multichannel data,
|
|
|
|
// the number of channels and the number of frames.
|
|
|
|
int DownmixAudioToStereo(mozilla::AudioDataValue* buffer,
|
|
|
|
int channels,
|
|
|
|
uint32_t frames);
|
|
|
|
|
2013-11-04 02:45:19 +04:00
|
|
|
bool IsVideoContentType(const nsCString& aContentType);
|
|
|
|
|
2014-02-04 05:49:21 +04:00
|
|
|
// Returns true if it's safe to use aPicture as the picture to be
|
|
|
|
// extracted inside a frame of size aFrame, and scaled up to and displayed
|
|
|
|
// at a size of aDisplay. You should validate the frame, picture, and
|
|
|
|
// display regions before using them to display video frames.
|
|
|
|
bool IsValidVideoRegion(const nsIntSize& aFrame, const nsIntRect& aPicture,
|
|
|
|
const nsIntSize& aDisplay);
|
|
|
|
|
2014-05-06 04:12:05 +04:00
|
|
|
// Template to automatically set a variable to a value on scope exit.
|
|
|
|
// Useful for unsetting flags, etc.
|
|
|
|
template<typename T>
|
|
|
|
class AutoSetOnScopeExit {
|
|
|
|
public:
|
|
|
|
AutoSetOnScopeExit(T& aVar, T aValue)
|
|
|
|
: mVar(aVar)
|
|
|
|
, mValue(aValue)
|
|
|
|
{}
|
|
|
|
~AutoSetOnScopeExit() {
|
|
|
|
mVar = mValue;
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
T& mVar;
|
|
|
|
const T mValue;
|
|
|
|
};
|
|
|
|
|
2013-11-04 02:45:19 +04:00
|
|
|
} // end namespace mozilla
|
|
|
|
|
2010-04-02 07:03:07 +04:00
|
|
|
#endif
|