Bug 775319 - Determine the sample format at compile time for all media code. r=kinetik

This commit is contained in:
Paul Adenot 2012-08-16 18:10:36 -07:00
parent 967b36e8ae
commit ee3a886b03
8 changed files with 118 additions and 133 deletions

View File

@ -4144,6 +4144,8 @@ MOZ_CUBEB=
MOZ_VORBIS=
MOZ_TREMOR=
MOZ_WAVE=1
MOZ_SAMPLE_TYPE_FLOAT32=
MOZ_SAMPLE_TYPE_S16LE=
MOZ_MEDIA=
MOZ_OPUS=1
MOZ_WEBM=1
@ -5192,6 +5194,19 @@ fi
AC_SUBST(MOZ_WEBRTC)
case "$target_cpu" in
arm*)
MOZ_SAMPLE_TYPE_S16LE=1
AC_DEFINE(MOZ_SAMPLE_TYPE_S16LE)
AC_SUBST(MOZ_SAMPLE_TYPE_S16LE)
;;
*)
MOZ_SAMPLE_TYPE_FLOAT32=1
AC_DEFINE(MOZ_SAMPLE_TYPE_FLOAT32)
AC_SUBST(MOZ_SAMPLE_TYPE_FLOAT32)
;;
esac
dnl ========================================================
dnl = Enable Raw Codecs
dnl ========================================================
@ -5220,14 +5235,6 @@ if test -n "$MOZ_OGG"; then
MOZ_SYDNEYAUDIO=1
MOZ_CUBEB=1
MOZ_MEDIA=1
case "$target_cpu" in
arm*)
MOZ_TREMOR=1
;;
*)
MOZ_VORBIS=1
;;
esac
dnl Checks for __attribute__(aligned()) directive
AC_CACHE_CHECK([__attribute__ ((aligned ())) support],
@ -5367,14 +5374,11 @@ if test "$MOZ_WEBM"; then
MOZ_SYDNEYAUDIO=1
MOZ_CUBEB=1
MOZ_MEDIA=1
case "$target_cpu" in
arm*)
MOZ_TREMOR=1
;;
*)
if test "$MOZ_SAMPLE_TYPE_FLOAT32"; then
MOZ_VORBIS=1
;;
esac
else
MOZ_TREMOR=1
fi
fi
if test -n "$MOZ_VP8" -a -z "$MOZ_NATIVE_LIBVPX"; then

View File

@ -116,8 +116,7 @@ nsHTMLAudioElement::MozSetup(PRUint32 aChannels, PRUint32 aRate)
}
mAudioStream = nsAudioStream::AllocateStream();
nsresult rv = mAudioStream->Init(aChannels, aRate,
nsAudioStream::FORMAT_FLOAT32);
nsresult rv = mAudioStream->Init(aChannels, aRate);
if (NS_FAILED(rv)) {
mAudioStream->Shutdown();
mAudioStream = nullptr;
@ -169,7 +168,30 @@ nsHTMLAudioElement::MozWriteAudio(const JS::Value& aData, JSContext* aCx, PRUint
// Don't write more than can be written without blocking.
PRUint32 writeLen = NS_MIN(mAudioStream->Available(), dataLength / mChannels);
nsresult rv = mAudioStream->Write(JS_GetFloat32ArrayData(tsrc, aCx), writeLen);
float* frames = JS_GetFloat32ArrayData(tsrc, aCx);
#ifdef MOZ_SAMPLE_TYPE_S16LE
// Convert the samples back to integers as we are using fixed point audio in
// the nsAudioStream.
nsAutoArrayPtr<short> shortsArray(new short[writeLen * mChannels]);
// Hard clip the samples.
for (PRUint32 i = 0; i < writeLen * mChannels; ++i) {
float scaled_value = floorf(0.5 + 32768 * frames[i]);
if (frames[i] < 0.0) {
shortsArray[i] = (scaled_value < -32768.0) ?
-32768 :
short(scaled_value);
} else {
shortsArray[i] = (scaled_value > 32767.0) ?
32767 :
short(scaled_value);
}
}
nsresult rv = mAudioStream->Write(shortsArray, writeLen);
#else
nsresult rv = mAudioStream->Write(frames, writeLen);
#endif
if (NS_FAILED(rv)) {
return rv;
}

View File

@ -1150,8 +1150,7 @@ MediaStreamGraphImpl::CreateOrDestroyAudioStreams(GraphTime aAudioOutputStartTim
audioOutputStream->mBlockedAudioTime = 0;
audioOutputStream->mStream = nsAudioStream::AllocateStream();
audioOutputStream->mStream->Init(audio->GetChannels(),
tracks->GetRate(),
audio->GetFirstFrameFormat());
tracks->GetRate());
audioOutputStream->mTrackID = tracks->GetID();
}
}

View File

@ -60,7 +60,7 @@ class nsNativeAudioStream : public nsAudioStream
~nsNativeAudioStream();
nsNativeAudioStream();
nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat);
nsresult Init(PRInt32 aNumChannels, PRInt32 aRate);
void Shutdown();
nsresult Write(const void* aBuf, PRUint32 aFrames);
PRUint32 Available();
@ -95,7 +95,7 @@ class nsRemotedAudioStream : public nsAudioStream
nsRemotedAudioStream();
~nsRemotedAudioStream();
nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat);
nsresult Init(PRInt32 aNumChannels, PRInt32 aRate);
void Shutdown();
nsresult Write(const void* aBuf, PRUint32 aFrames);
PRUint32 Available();
@ -422,11 +422,11 @@ nsNativeAudioStream::~nsNativeAudioStream()
NS_IMPL_THREADSAFE_ISUPPORTS0(nsNativeAudioStream)
nsresult nsNativeAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat)
nsresult nsNativeAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate)
{
mRate = aRate;
mChannels = aNumChannels;
mFormat = aFormat;
mFormat = MOZ_AUDIO_DATA_FORMAT;
if (sa_stream_create_pcm(reinterpret_cast<sa_stream_t**>(&mAudioHandle),
NULL,
@ -474,16 +474,7 @@ nsresult nsNativeAudioStream::Write(const void* aBuf, PRUint32 aFrames)
if (s_data) {
double scaled_volume = GetVolumeScale() * mVolume;
switch (mFormat) {
case FORMAT_U8: {
const PRUint8* buf = static_cast<const PRUint8*>(aBuf);
PRInt32 volume = PRInt32((1 << 16) * scaled_volume);
for (PRUint32 i = 0; i < samples; ++i) {
s_data[i] = short(((PRInt32(buf[i]) - 128) * volume) >> 8);
}
break;
}
case FORMAT_S16_LE: {
#ifdef MOZ_SAMPLE_TYPE_S16LE
const short* buf = static_cast<const short*>(aBuf);
PRInt32 volume = PRInt32((1 << 16) * scaled_volume);
for (PRUint32 i = 0; i < samples; ++i) {
@ -493,10 +484,8 @@ nsresult nsNativeAudioStream::Write(const void* aBuf, PRUint32 aFrames)
#endif
s_data[i] = short((PRInt32(s) * volume) >> 16);
}
break;
}
case FORMAT_FLOAT32: {
const float* buf = static_cast<const float*>(aBuf);
#else /* MOZ_SAMPLE_TYPE_FLOAT32 */
const SampleType* buf = static_cast<const SampleType*>(aBuf);
for (PRUint32 i = 0; i < samples; ++i) {
float scaled_value = floorf(0.5 + 32768 * buf[i] * scaled_volume);
if (buf[i] < 0.0) {
@ -509,8 +498,7 @@ nsresult nsNativeAudioStream::Write(const void* aBuf, PRUint32 aFrames)
short(scaled_value);
}
}
break;
}
#endif
}
if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle),
@ -521,7 +509,6 @@ nsresult nsNativeAudioStream::Write(const void* aBuf, PRUint32 aFrames)
mInError = true;
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
@ -644,26 +631,12 @@ NS_IMPL_THREADSAFE_ISUPPORTS0(nsRemotedAudioStream)
nsresult
nsRemotedAudioStream::Init(PRInt32 aNumChannels,
PRInt32 aRate,
SampleFormat aFormat)
PRInt32 aRate)
{
mRate = aRate;
mChannels = aNumChannels;
mFormat = aFormat;
switch (mFormat) {
case FORMAT_U8: {
mBytesPerFrame = sizeof(PRUint8) * mChannels;
break;
}
case FORMAT_S16_LE: {
mBytesPerFrame = sizeof(short) * mChannels;
break;
}
case FORMAT_FLOAT32: {
mBytesPerFrame = sizeof(float) * mChannels;
}
}
mFormat = MOZ_AUDIO_DATA_FORMAT;
mBytesPerFrame = sizeof(SampleType) * mChannels;
nsCOMPtr<nsIRunnable> event = new AudioInitEvent(this);
NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
@ -861,7 +834,7 @@ class nsBufferedAudioStream : public nsAudioStream
nsBufferedAudioStream();
~nsBufferedAudioStream();
nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat);
nsresult Init(PRInt32 aNumChannels, PRInt32 aRate);
void Shutdown();
nsresult Write(const void* aBuf, PRUint32 aFrames);
PRUint32 Available();
@ -963,7 +936,7 @@ nsBufferedAudioStream::~nsBufferedAudioStream()
NS_IMPL_THREADSAFE_ISUPPORTS0(nsBufferedAudioStream)
nsresult
nsBufferedAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat)
nsBufferedAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate)
{
cubeb* cubebContext = GetCubebContext();
@ -973,23 +946,17 @@ nsBufferedAudioStream::Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aF
mRate = aRate;
mChannels = aNumChannels;
mFormat = aFormat;
mFormat = MOZ_AUDIO_DATA_FORMAT;
cubeb_stream_params params;
params.rate = aRate;
params.channels = aNumChannels;
switch (aFormat) {
case FORMAT_S16_LE:
params.format = CUBEB_SAMPLE_S16LE;
mBytesPerFrame = sizeof(short) * aNumChannels;
break;
case FORMAT_FLOAT32:
#ifdef MOZ_SAMPLE_TYPE_S16LE
params.format = CUBEB_SAMPLE_S16NE;
#else /* MOZ_SAMPLE_TYPE_FLOAT32 */
params.format = CUBEB_SAMPLE_FLOAT32NE;
#endif
mBytesPerFrame = sizeof(float) * aNumChannels;
break;
default:
return NS_ERROR_FAILURE;
}
{
cubeb_stream* stream;
@ -1221,8 +1188,7 @@ nsBufferedAudioStream::DataCallback(void* aBuffer, long aFrames)
output += input_size[i];
} else {
// Adjust volume as each sample is copied out.
switch (mFormat) {
case FORMAT_S16_LE: {
#ifdef MOZ_SAMPLE_TYPE_S16LE
PRInt32 volume = PRInt32(1 << 16) * scaled_volume;
const short* src = static_cast<const short*>(input[i]);
@ -1230,21 +1196,14 @@ nsBufferedAudioStream::DataCallback(void* aBuffer, long aFrames)
for (PRUint32 j = 0; j < input_size[i] / (mBytesPerFrame / mChannels); ++j) {
dst[j] = short((PRInt32(src[j]) * volume) >> 16);
}
output += input_size[i];
break;
}
case FORMAT_FLOAT32: {
#else /* MOZ_SAMPLE_TYPE_FLOAT32 */
const float* src = static_cast<const float*>(input[i]);
float* dst = reinterpret_cast<float*>(output);
for (PRUint32 j = 0; j < input_size[i] / (mBytesPerFrame / mChannels); ++j) {
dst[j] = src[j] * scaled_volume;
}
#endif
output += input_size[i];
break;
}
default:
return -1;
}
}
}

View File

@ -11,6 +11,14 @@
#include "nsIThread.h"
#include "nsAutoPtr.h"
#ifdef MOZ_SAMPLE_TYPE_S16LE
#define MOZ_AUDIO_DATA_FORMAT (nsAudioStream::FORMAT_S16_LE)
typedef short SampleType;
#else
#define MOZ_AUDIO_DATA_FORMAT (nsAudioStream::FORMAT_FLOAT32)
typedef float SampleType;
#endif
// Access to a single instance of this class must be synchronized by
// callers, or made from a single thread. One exception is that access to
// GetPosition, GetPositionInFrames, SetVolume, and Get{Rate,Channels,Format}
@ -28,8 +36,7 @@ public:
nsAudioStream()
: mRate(0),
mChannels(0),
mFormat(FORMAT_S16_LE)
mChannels(0)
{}
virtual ~nsAudioStream();
@ -56,7 +63,7 @@ public:
// (22050Hz, 44100Hz, etc).
// Unsafe to call with a monitor held due to synchronous event execution
// on the main thread, which may attempt to acquire any held monitor.
virtual nsresult Init(PRInt32 aNumChannels, PRInt32 aRate, SampleFormat aFormat) = 0;
virtual nsresult Init(PRInt32 aNumChannels, PRInt32 aRate) = 0;
// Closes the stream. All future use of the stream is an error.
// Unsafe to call with a monitor held due to synchronous event execution
@ -106,7 +113,7 @@ public:
int GetRate() { return mRate; }
int GetChannels() { return mChannels; }
SampleFormat GetFormat() { return mFormat; }
SampleFormat GetFormat() { return MOZ_AUDIO_DATA_FORMAT; }
protected:
nsCOMPtr<nsIThread> mAudioPlaybackThread;

View File

@ -53,29 +53,25 @@ public:
bool mHasVideo;
};
#ifdef MOZ_TREMOR
#ifdef MOZ_SAMPLE_TYPE_S16LE
#include <ogg/os_types.h>
typedef ogg_int32_t VorbisPCMValue;
typedef short AudioDataValue;
#define MOZ_AUDIO_DATA_FORMAT (nsAudioStream::FORMAT_S16_LE)
#define MOZ_CLIP_TO_15(x) ((x)<-32768?-32768:(x)<=32767?(x):32767)
// Convert the output of vorbis_synthesis_pcmout to a AudioDataValue
#define MOZ_CONVERT_VORBIS_SAMPLE(x) \
(static_cast<AudioDataValue>(MOZ_CLIP_TO_15((x)>>9)))
// Convert a AudioDataValue to a float for the Audio API
#define MOZ_CONVERT_AUDIO_SAMPLE(x) ((x)*(1.F/32768))
#define MOZ_SAMPLE_TYPE_S16LE 1
#else /*MOZ_VORBIS*/
#else /* MOZ_SAMPLE_TYPE_FLOAT32 */
typedef float VorbisPCMValue;
typedef float AudioDataValue;
#define MOZ_AUDIO_DATA_FORMAT (nsAudioStream::FORMAT_FLOAT32)
#define MOZ_CONVERT_VORBIS_SAMPLE(x) (x)
#define MOZ_CONVERT_AUDIO_SAMPLE(x) (x)
#define MOZ_SAMPLE_TYPE_FLOAT32 1
#endif

View File

@ -1008,7 +1008,7 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
// are unsafe to call with the decoder monitor held are documented as such
// in nsAudioStream.h.
nsRefPtr<nsAudioStream> audioStream = nsAudioStream::AllocateStream();
audioStream->Init(channels, rate, MOZ_AUDIO_DATA_FORMAT);
audioStream->Init(channels, rate);
{
// We must hold the monitor while setting mAudioStream or whenever we query

View File

@ -297,9 +297,7 @@ AudioParent::AudioParent(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat)
{
mStream = nsAudioStream::AllocateStream();
NS_ASSERTION(mStream, "AudioStream allocation failed.");
if (NS_FAILED(mStream->Init(aNumChannels,
aRate,
(nsAudioStream::SampleFormat) aFormat))) {
if (NS_FAILED(mStream->Init(aNumChannels, aRate))) {
NS_WARNING("AudioStream initialization failed.");
mStream = nullptr;
return;