Merge mozilla-central and inbound

This commit is contained in:
Ed Morley 2014-08-18 15:32:03 +01:00
commit d8b6306ec3
59 changed files with 563 additions and 432 deletions

View File

@ -119,7 +119,7 @@ CATEGORIES = {
},
'disabled': {
'short': 'Disabled',
'long': 'These commands are unavailable for your current context, run "mach <command>" to see why.',
'long': 'The disabled commands are hidden by default. Use -v to display them. These commands are unavailable for your current context, run "mach <command>" to see why.',
'priority': 0,
}
}

View File

@ -441,7 +441,8 @@ DecoderTraits::CanHandleMediaType(const char* aMIMEType,
}
#endif
#ifdef MOZ_WMF
if (IsWMFSupportedType(nsDependentCString(aMIMEType))) {
if (!Preferences::GetBool("media.fragmented-mp4.exposed", false) &&
IsWMFSupportedType(nsDependentCString(aMIMEType))) {
if (!aHaveRequestedCodecs) {
return CANPLAY_MAYBE;
}

View File

@ -255,7 +255,9 @@ bool MediaDecoderStateMachine::HasFutureAudio() {
// we've completely decoded all audio (but not finished playing it yet
// as per 1).
return !mAudioCompleted &&
(AudioDecodedUsecs() > LOW_AUDIO_USECS * mPlaybackRate || AudioQueue().IsFinished());
(AudioDecodedUsecs() >
mLowAudioThresholdUsecs * mPlaybackRate ||
AudioQueue().IsFinished());
}
bool MediaDecoderStateMachine::HaveNextFrameData() {

View File

@ -229,9 +229,9 @@ public:
// Decode thread.
virtual already_AddRefed<MediaDataDecoder>
CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE {
CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE {
BlankAudioDataCreator* creator = new BlankAudioDataCreator(
aConfig.channel_count, aConfig.samples_per_second);
@ -241,6 +241,13 @@ public:
aCallback);
return decoder.forget();
}
virtual bool
SupportsAudioMimeType(const char* aMimeType) MOZ_OVERRIDE
{
return true;
}
};
PlatformDecoderModule* CreateBlankDecoderModule()

View File

@ -288,6 +288,14 @@ MP4Reader::ExtractCryptoInitData(nsTArray<uint8_t>& aInitData)
}
}
bool
MP4Reader::IsSupportedAudioMimeType(const char* aMimeType)
{
return (!strcmp(aMimeType, "audio/mpeg") ||
!strcmp(aMimeType, "audio/mp4a-latm")) &&
mPlatform->SupportsAudioMimeType(aMimeType);
}
nsresult
MP4Reader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags)
@ -296,13 +304,6 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
bool ok = mDemuxer->Init();
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
mInfo.mAudio.mHasAudio = mAudio.mActive = mDemuxer->HasValidAudio();
const AudioDecoderConfig& audio = mDemuxer->AudioConfig();
// If we have audio, we *only* allow AAC to be decoded.
if (mInfo.mAudio.mHasAudio && strcmp(audio.mime_type, "audio/mp4a-latm")) {
return NS_ERROR_FAILURE;
}
mInfo.mVideo.mHasVideo = mVideo.mActive = mDemuxer->HasValidVideo();
const VideoDecoderConfig& video = mDemuxer->VideoConfig();
// If we have video, we *only* allow H.264 to be decoded.
@ -370,14 +371,18 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
NS_ENSURE_TRUE(mPlatform, NS_ERROR_FAILURE);
}
if (HasAudio()) {
if (mDemuxer->HasValidAudio()) {
const AudioDecoderConfig& audio = mDemuxer->AudioConfig();
mInfo.mAudio.mHasAudio = mAudio.mActive = true;
if (mInfo.mAudio.mHasAudio && !IsSupportedAudioMimeType(audio.mime_type)) {
return NS_ERROR_FAILURE;
}
mInfo.mAudio.mRate = audio.samples_per_second;
mInfo.mAudio.mChannels = audio.channel_count;
mAudio.mCallback = new DecoderCallback(this, kAudio);
mAudio.mDecoder = mPlatform->CreateAACDecoder(audio,
mAudio.mTaskQueue,
mAudio.mCallback);
mAudio.mDecoder = mPlatform->CreateAudioDecoder(audio,
mAudio.mTaskQueue,
mAudio.mCallback);
NS_ENSURE_TRUE(mAudio.mDecoder != nullptr, NS_ERROR_FAILURE);
nsresult rv = mAudio.mDecoder->Init();
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -87,6 +87,7 @@ private:
void Flush(mp4_demuxer::TrackType aTrack);
void DrainComplete(mp4_demuxer::TrackType aTrack);
void UpdateIndex();
bool IsSupportedAudioMimeType(const char* aMimeType);
void NotifyResourcesStatusChanged();
bool IsWaitingOnCodecResource();
bool IsWaitingOnCDMResource();

View File

@ -153,4 +153,10 @@ PlatformDecoderModule::Create()
return nullptr;
}
bool
PlatformDecoderModule::SupportsAudioMimeType(const char* aMimeType)
{
return !strcmp(aMimeType, "audio/mp4a-latm");
}
} // namespace mozilla

View File

@ -35,8 +35,8 @@ class CDMProxy;
typedef int64_t Microseconds;
// The PlatformDecoderModule interface is used by the MP4Reader to abstract
// access to the H264 and AAC decoders provided by various platforms. It
// may be extended to support other codecs in future. Each platform (Windows,
// access to the H264 and Audio (AAC/MP3) decoders provided by various platforms.
// It may be extended to support other codecs in future. Each platform (Windows,
// MacOSX, Linux, B2G etc) must implement a PlatformDecoderModule to provide
// access to its decoders in order to get decompressed H.264/AAC from the
// MP4Reader.
@ -103,7 +103,7 @@ public:
MediaTaskQueue* aVideoTaskQueue,
MediaDataDecoderCallback* aCallback) = 0;
// Creates an AAC decoder with the specified properties.
// Creates an Audio decoder with the specified properties.
// Asynchronous decoding of audio should be done in runnables dispatched to
// aAudioTaskQueue. If the task queue isn't needed, the decoder should
// not hold a reference to it.
@ -114,9 +114,14 @@ public:
// It is safe to store a reference to aConfig.
// This is called on the decode task queue.
virtual already_AddRefed<MediaDataDecoder>
CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) = 0;
CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) = 0;
// An audio decoder module must support AAC by default.
// If more audio codec is to be supported, SupportsAudioMimeType will have
// to be extended
virtual bool SupportsAudioMimeType(const char* aMimeType);
virtual ~PlatformDecoderModule() {}

View File

@ -37,13 +37,20 @@ AppleATDecoder::AppleATDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
, mHaveOutput(false)
{
MOZ_COUNT_CTOR(AppleATDecoder);
LOG("Creating Apple AudioToolbox AAC decoder");
LOG("Creating Apple AudioToolbox Audio decoder");
LOG("Audio Decoder configuration: %s %d Hz %d channels %d bits per channel",
mConfig.mime_type,
mConfig.samples_per_second,
mConfig.channel_count,
mConfig.bits_per_sample);
// TODO: Verify aConfig.mime_type.
if (!strcmp(aConfig.mime_type, "audio/mpeg")) {
mFileType = kAudioFileMP3Type;
} else if (!strcmp(aConfig.mime_type, "audio/mp4a-latm")) {
mFileType = kAudioFileAAC_ADTSType;
} else {
mFileType = 0;
}
}
AppleATDecoder::~AppleATDecoder()
@ -80,12 +87,15 @@ _SampleCallback(void* aDecoder,
nsresult
AppleATDecoder::Init()
{
LOG("Initializing Apple AudioToolbox AAC decoder");
AudioFileTypeID fileType = kAudioFileAAC_ADTSType;
if (!mFileType) {
NS_ERROR("Non recognised format");
return NS_ERROR_FAILURE;
}
LOG("Initializing Apple AudioToolbox Audio decoder");
OSStatus rv = AudioFileStreamOpen(this,
_MetadataCallback,
_SampleCallback,
fileType,
mFileType,
&mStream);
if (rv) {
NS_ERROR("Couldn't open AudioFileStream");

View File

@ -53,6 +53,7 @@ private:
int64_t mSamplePosition;
bool mHaveOutput;
AudioStreamBasicDescription mOutputFormat;
AudioFileTypeID mFileType;
void SetupDecoder();
void SubmitSample(nsAutoPtr<mp4_demuxer::MP4Sample> aSample);

View File

@ -87,13 +87,19 @@ AppleDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aCo
}
already_AddRefed<MediaDataDecoder>
AppleDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
AppleDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
{
nsRefPtr<MediaDataDecoder> decoder =
new AppleATDecoder(aConfig, aAudioTaskQueue, aCallback);
return decoder.forget();
}
bool
AppleDecoderModule::SupportsAudioMimeType(const char* aMimeType)
{
return !strcmp(aMimeType, "audio/mp4a-latm") || !strcmp(aMimeType, "audio/mpeg");
}
} // namespace mozilla

View File

@ -34,9 +34,11 @@ public:
// Decode thread.
virtual already_AddRefed<MediaDataDecoder>
CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
virtual bool SupportsAudioMimeType(const char* aMimeType) MOZ_OVERRIDE;
static void Init();
private:

View File

@ -4,7 +4,7 @@
* 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/. */
#include "EMEAACDecoder.h"
#include "EMEAudioDecoder.h"
#include "mp4_demuxer/DecoderData.h"
#include "mozilla/EMELog.h"
#include "gmp-audio-host.h"
@ -18,10 +18,10 @@
namespace mozilla {
EMEAACDecoder::EMEAACDecoder(CDMProxy* aProxy,
const AudioDecoderConfig& aConfig,
MediaTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback)
EMEAudioDecoder::EMEAudioDecoder(CDMProxy* aProxy,
const AudioDecoderConfig& aConfig,
MediaTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback)
: mAudioRate(0)
, mAudioBytesPerSample(0)
, mAudioChannels(0)
@ -34,17 +34,17 @@ EMEAACDecoder::EMEAACDecoder(CDMProxy* aProxy,
, mConfig(aConfig)
, mTaskQueue(aTaskQueue)
, mCallback(aCallback)
, mMonitor("EMEAACDecoder")
, mMonitor("EMEAudioDecoder")
, mFlushComplete(false)
{
}
EMEAACDecoder::~EMEAACDecoder()
EMEAudioDecoder::~EMEAudioDecoder()
{
}
nsresult
EMEAACDecoder::Init()
EMEAudioDecoder::Init()
{
// Note: this runs on the decode task queue.
@ -65,7 +65,7 @@ EMEAACDecoder::Init()
}
nsresult
EMEAACDecoder::Input(MP4Sample* aSample)
EMEAudioDecoder::Input(MP4Sample* aSample)
{
MOZ_ASSERT(!IsOnGMPThread()); // Runs on the decode task queue.
@ -77,7 +77,7 @@ EMEAACDecoder::Input(MP4Sample* aSample)
}
nsresult
EMEAACDecoder::Flush()
EMEAudioDecoder::Flush()
{
MOZ_ASSERT(!IsOnGMPThread()); // Runs on the decode task queue.
@ -87,7 +87,7 @@ EMEAACDecoder::Flush()
}
nsRefPtr<nsIRunnable> task;
task = NS_NewRunnableMethod(this, &EMEAACDecoder::GmpFlush);
task = NS_NewRunnableMethod(this, &EMEAudioDecoder::GmpFlush);
nsresult rv = mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
@ -102,34 +102,34 @@ EMEAACDecoder::Flush()
}
nsresult
EMEAACDecoder::Drain()
EMEAudioDecoder::Drain()
{
MOZ_ASSERT(!IsOnGMPThread()); // Runs on the decode task queue.
nsRefPtr<nsIRunnable> task;
task = NS_NewRunnableMethod(this, &EMEAACDecoder::GmpDrain);
task = NS_NewRunnableMethod(this, &EMEAudioDecoder::GmpDrain);
nsresult rv = mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
EMEAACDecoder::Shutdown()
EMEAudioDecoder::Shutdown()
{
MOZ_ASSERT(!IsOnGMPThread()); // Runs on the decode task queue.
nsRefPtr<nsIRunnable> task;
task = NS_NewRunnableMethod(this, &EMEAACDecoder::GmpShutdown);
task = NS_NewRunnableMethod(this, &EMEAudioDecoder::GmpShutdown);
nsresult rv = mGMPThread->Dispatch(task, NS_DISPATCH_SYNC);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
void
EMEAACDecoder::Decoded(const nsTArray<int16_t>& aPCM,
uint64_t aTimeStamp,
uint32_t aChannels,
uint32_t aRate)
EMEAudioDecoder::Decoded(const nsTArray<int16_t>& aPCM,
uint64_t aTimeStamp,
uint32_t aChannels,
uint32_t aRate)
{
MOZ_ASSERT(IsOnGMPThread());
@ -192,21 +192,21 @@ EMEAACDecoder::Decoded(const nsTArray<int16_t>& aPCM,
}
void
EMEAACDecoder::InputDataExhausted()
EMEAudioDecoder::InputDataExhausted()
{
MOZ_ASSERT(IsOnGMPThread());
mCallback->InputExhausted();
}
void
EMEAACDecoder::DrainComplete()
EMEAudioDecoder::DrainComplete()
{
MOZ_ASSERT(IsOnGMPThread());
mCallback->DrainComplete();
}
void
EMEAACDecoder::ResetComplete()
EMEAudioDecoder::ResetComplete()
{
MOZ_ASSERT(IsOnGMPThread());
mMustRecaptureAudioPosition = true;
@ -218,23 +218,23 @@ EMEAACDecoder::ResetComplete()
}
void
EMEAACDecoder::Error(GMPErr aErr)
EMEAudioDecoder::Error(GMPErr aErr)
{
MOZ_ASSERT(IsOnGMPThread());
EME_LOG("EMEAACDecoder::Error");
EME_LOG("EMEAudioDecoder::Error");
mCallback->Error();
GmpShutdown();
}
void
EMEAACDecoder::Terminated()
EMEAudioDecoder::Terminated()
{
MOZ_ASSERT(IsOnGMPThread());
GmpShutdown();
}
nsresult
EMEAACDecoder::GmpInit()
EMEAudioDecoder::GmpInit()
{
MOZ_ASSERT(IsOnGMPThread());
@ -266,7 +266,7 @@ EMEAACDecoder::GmpInit()
}
nsresult
EMEAACDecoder::GmpInput(MP4Sample* aSample)
EMEAudioDecoder::GmpInput(MP4Sample* aSample)
{
MOZ_ASSERT(IsOnGMPThread());
nsAutoPtr<MP4Sample> sample(aSample);
@ -296,7 +296,7 @@ EMEAACDecoder::GmpInput(MP4Sample* aSample)
}
void
EMEAACDecoder::GmpFlush()
EMEAudioDecoder::GmpFlush()
{
MOZ_ASSERT(IsOnGMPThread());
if (!mGMP || NS_FAILED(mGMP->Reset())) {
@ -308,7 +308,7 @@ EMEAACDecoder::GmpFlush()
}
void
EMEAACDecoder::GmpDrain()
EMEAudioDecoder::GmpDrain()
{
MOZ_ASSERT(IsOnGMPThread());
if (!mGMP || NS_FAILED(mGMP->Drain())) {
@ -317,7 +317,7 @@ EMEAACDecoder::GmpDrain()
}
void
EMEAACDecoder::GmpShutdown()
EMEAudioDecoder::GmpShutdown()
{
MOZ_ASSERT(IsOnGMPThread());
if (!mGMP) {

View File

@ -16,18 +16,18 @@
namespace mozilla {
class EMEAACDecoder : public MediaDataDecoder
, public GMPAudioDecoderProxyCallback
class EMEAudioDecoder : public MediaDataDecoder
, public GMPAudioDecoderProxyCallback
{
typedef mp4_demuxer::MP4Sample MP4Sample;
typedef mp4_demuxer::AudioDecoderConfig AudioDecoderConfig;
public:
EMEAACDecoder(CDMProxy* aProxy,
const AudioDecoderConfig& aConfig,
MediaTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback);
EMEAudioDecoder(CDMProxy* aProxy,
const AudioDecoderConfig& aConfig,
MediaTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback);
~EMEAACDecoder();
~EMEAudioDecoder();
// MediaDataDecoder implementation.
virtual nsresult Init() MOZ_OVERRIDE;
@ -51,7 +51,7 @@ private:
class DeliverSample : public nsRunnable {
public:
DeliverSample(EMEAACDecoder* aDecoder,
DeliverSample(EMEAudioDecoder* aDecoder,
mp4_demuxer::MP4Sample* aSample)
: mDecoder(aDecoder)
, mSample(aSample)
@ -62,13 +62,13 @@ private:
return NS_OK;
}
private:
nsRefPtr<EMEAACDecoder> mDecoder;
nsRefPtr<EMEAudioDecoder> mDecoder;
nsAutoPtr<mp4_demuxer::MP4Sample> mSample;
};
class InitTask : public nsRunnable {
public:
InitTask(EMEAACDecoder* aDecoder)
InitTask(EMEAudioDecoder* aDecoder)
: mDecoder(aDecoder)
{}
NS_IMETHOD Run() {
@ -76,7 +76,7 @@ private:
return NS_OK;
}
nsresult mResult;
EMEAACDecoder* mDecoder;
EMEAudioDecoder* mDecoder;
};
nsresult GmpInit();
@ -114,4 +114,4 @@ private:
} // namespace mozilla
#endif
#endif

View File

@ -19,7 +19,7 @@
#include "SharedThreadPool.h"
#include "mozilla/EMELog.h"
#include "EMEH264Decoder.h"
#include "EMEAACDecoder.h"
#include "EMEAudioDecoder.h"
#include <string>
namespace mozilla {
@ -227,21 +227,21 @@ EMEDecoderModule::CreateH264Decoder(const VideoDecoderConfig& aConfig,
}
already_AddRefed<MediaDataDecoder>
EMEDecoderModule::CreateAACDecoder(const AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
EMEDecoderModule::CreateAudioDecoder(const AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
{
if (mCDMDecodesAudio) {
nsRefPtr<MediaDataDecoder> decoder(new EMEAACDecoder(mProxy,
aConfig,
aAudioTaskQueue,
aCallback));
nsRefPtr<MediaDataDecoder> decoder(new EMEAudioDecoder(mProxy,
aConfig,
aAudioTaskQueue,
aCallback));
return decoder.forget();
}
nsRefPtr<MediaDataDecoder> decoder(mPDM->CreateAACDecoder(aConfig,
aAudioTaskQueue,
aCallback));
nsRefPtr<MediaDataDecoder> decoder(mPDM->CreateAudioDecoder(aConfig,
aAudioTaskQueue,
aCallback));
if (!decoder) {
return nullptr;
}

View File

@ -42,9 +42,9 @@ public:
// Decode thread.
virtual already_AddRefed<MediaDataDecoder>
CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
private:
nsRefPtr<CDMProxy> mProxy;

View File

@ -5,13 +5,13 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS += [
'EMEAACDecoder.h',
'EMEAudioDecoder.h',
'EMEDecoderModule.h',
'EMEH264Decoder.h',
]
UNIFIED_SOURCES += [
'EMEAACDecoder.cpp',
'EMEAudioDecoder.cpp',
'EMEDecoderModule.cpp',
'EMEH264Decoder.cpp',
]

View File

@ -7,7 +7,7 @@
#include "MediaTaskQueue.h"
#include "FFmpegRuntimeLinker.h"
#include "FFmpegAACDecoder.h"
#include "FFmpegAudioDecoder.h"
#define MAX_CHANNELS 16
@ -16,16 +16,17 @@ typedef mp4_demuxer::MP4Sample MP4Sample;
namespace mozilla
{
FFmpegAACDecoder<LIBAV_VER>::FFmpegAACDecoder(
FFmpegAudioDecoder<LIBAV_VER>::FFmpegAudioDecoder(
MediaTaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback,
const mp4_demuxer::AudioDecoderConfig& aConfig)
: FFmpegDataDecoder(aTaskQueue, AV_CODEC_ID_AAC), mCallback(aCallback)
: FFmpegDataDecoder(aTaskQueue, GetCodecId(aConfig.mime_type))
, mCallback(aCallback)
{
MOZ_COUNT_CTOR(FFmpegAACDecoder);
MOZ_COUNT_CTOR(FFmpegAudioDecoder);
}
nsresult
FFmpegAACDecoder<LIBAV_VER>::Init()
FFmpegAudioDecoder<LIBAV_VER>::Init()
{
nsresult rv = FFmpegDataDecoder::Init();
NS_ENSURE_SUCCESS(rv, rv);
@ -34,24 +35,44 @@ FFmpegAACDecoder<LIBAV_VER>::Init()
}
static AudioDataValue*
CopyAndPackAudio(AVFrame* aFrame, uint32_t aNumChannels, uint32_t aNumSamples)
CopyAndPackAudio(AVFrame* aFrame, uint32_t aNumChannels, uint32_t aNumAFrames)
{
MOZ_ASSERT(aNumChannels <= MAX_CHANNELS);
nsAutoArrayPtr<AudioDataValue> audio(
new AudioDataValue[aNumChannels * aNumSamples]);
AudioDataValue** data = reinterpret_cast<AudioDataValue**>(aFrame->data);
new AudioDataValue[aNumChannels * aNumAFrames]);
if (aFrame->format == AV_SAMPLE_FMT_FLT) {
// Audio data already packed. No need to do anything other than copy it
// into a buffer we own.
memcpy(audio, data[0], aNumChannels * aNumSamples * sizeof(AudioDataValue));
memcpy(audio, aFrame->data[0],
aNumChannels * aNumAFrames * sizeof(AudioDataValue));
} else if (aFrame->format == AV_SAMPLE_FMT_FLTP) {
// Planar audio data. Pack it into something we can understand.
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
for (uint32_t sample = 0; sample < aNumSamples; sample++) {
audio[sample * aNumChannels + channel] = data[channel][sample];
AudioDataValue* tmp = audio;
AudioDataValue** data = reinterpret_cast<AudioDataValue**>(aFrame->data);
for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
*tmp++ = data[channel][frame];
}
}
} else if (aFrame->format == AV_SAMPLE_FMT_S16) {
// Audio data already packed. Need to convert from S16 to 32 bits Float
AudioDataValue* tmp = audio;
int16_t* data = reinterpret_cast<int16_t**>(aFrame->data)[0];
for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
*tmp++ = AudioSampleToFloat(*data++);
}
}
} else if (aFrame->format == AV_SAMPLE_FMT_S16P) {
// Planar audio data. Convert it from S16 to 32 bits float
// and pack it into something we can understand.
AudioDataValue* tmp = audio;
int16_t** data = reinterpret_cast<int16_t**>(aFrame->data);
for (uint32_t frame = 0; frame < aNumAFrames; frame++) {
for (uint32_t channel = 0; channel < aNumChannels; channel++) {
*tmp++ = AudioSampleToFloat(data[channel][frame]);
}
}
}
@ -60,7 +81,7 @@ CopyAndPackAudio(AVFrame* aFrame, uint32_t aNumChannels, uint32_t aNumSamples)
}
void
FFmpegAACDecoder<LIBAV_VER>::DecodePacket(MP4Sample* aSample)
FFmpegAudioDecoder<LIBAV_VER>::DecodePacket(MP4Sample* aSample)
{
AVPacket packet;
av_init_packet(&packet);
@ -107,24 +128,38 @@ FFmpegAACDecoder<LIBAV_VER>::DecodePacket(MP4Sample* aSample)
}
nsresult
FFmpegAACDecoder<LIBAV_VER>::Input(MP4Sample* aSample)
FFmpegAudioDecoder<LIBAV_VER>::Input(MP4Sample* aSample)
{
mTaskQueue->Dispatch(NS_NewRunnableMethodWithArg<nsAutoPtr<MP4Sample> >(
this, &FFmpegAACDecoder::DecodePacket, nsAutoPtr<MP4Sample>(aSample)));
this, &FFmpegAudioDecoder::DecodePacket, nsAutoPtr<MP4Sample>(aSample)));
return NS_OK;
}
nsresult
FFmpegAACDecoder<LIBAV_VER>::Drain()
FFmpegAudioDecoder<LIBAV_VER>::Drain()
{
mCallback->DrainComplete();
return NS_OK;
}
FFmpegAACDecoder<LIBAV_VER>::~FFmpegAACDecoder()
AVCodecID
FFmpegAudioDecoder<LIBAV_VER>::GetCodecId(const char* aMimeType)
{
MOZ_COUNT_DTOR(FFmpegAACDecoder);
if (!strcmp(aMimeType, "audio/mpeg")) {
return AV_CODEC_ID_MP3;
}
if (!strcmp(aMimeType, "audio/mp4a-latm")) {
return AV_CODEC_ID_AAC;
}
return AV_CODEC_ID_NONE;
}
FFmpegAudioDecoder<LIBAV_VER>::~FFmpegAudioDecoder()
{
MOZ_COUNT_DTOR(FFmpegAudioDecoder);
}
} // namespace mozilla

View File

@ -13,22 +13,23 @@
namespace mozilla
{
template <int V> class FFmpegAACDecoder
template <int V> class FFmpegAudioDecoder
{
};
template <>
class FFmpegAACDecoder<LIBAV_VER> : public FFmpegDataDecoder<LIBAV_VER>
class FFmpegAudioDecoder<LIBAV_VER> : public FFmpegDataDecoder<LIBAV_VER>
{
public:
FFmpegAACDecoder(MediaTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback,
const mp4_demuxer::AudioDecoderConfig& aConfig);
virtual ~FFmpegAACDecoder();
FFmpegAudioDecoder(MediaTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback,
const mp4_demuxer::AudioDecoderConfig& aConfig);
virtual ~FFmpegAudioDecoder();
virtual nsresult Init() MOZ_OVERRIDE;
virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE;
virtual nsresult Drain() MOZ_OVERRIDE;
static AVCodecID GetCodecId(const char* aMimeType);
private:
void DecodePacket(mp4_demuxer::MP4Sample* aSample);

View File

@ -108,8 +108,10 @@ FFmpegDataDecoder<LIBAV_VER>::Init()
if (mCodecContext->codec_type == AVMEDIA_TYPE_AUDIO &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLT &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLTP) {
NS_WARNING("FFmpeg AAC decoder outputs unsupported audio format.");
mCodecContext->sample_fmt != AV_SAMPLE_FMT_FLTP &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16 &&
mCodecContext->sample_fmt != AV_SAMPLE_FMT_S16P) {
NS_WARNING("FFmpeg audio decoder outputs unsupported audio format.");
return NS_ERROR_FAILURE;
}

View File

@ -8,7 +8,7 @@
#define __FFmpegDecoderModule_h__
#include "PlatformDecoderModule.h"
#include "FFmpegAACDecoder.h"
#include "FFmpegAudioDecoder.h"
#include "FFmpegH264Decoder.h"
namespace mozilla
@ -39,14 +39,19 @@ public:
}
virtual already_AddRefed<MediaDataDecoder>
CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE
CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE
{
nsRefPtr<MediaDataDecoder> decoder =
new FFmpegAACDecoder<V>(aAudioTaskQueue, aCallback, aConfig);
new FFmpegAudioDecoder<V>(aAudioTaskQueue, aCallback, aConfig);
return decoder.forget();
}
virtual bool SupportsAudioMimeType(const char* aMimeType) MOZ_OVERRIDE
{
return FFmpegAudioDecoder<V>::GetCodecId(aMimeType) != AV_CODEC_ID_NONE;
}
};
} // namespace mozilla

View File

@ -18,6 +18,8 @@ extern "C" {
#if LIBAVCODEC_VERSION_MAJOR < 55
#define AV_CODEC_ID_H264 CODEC_ID_H264
#define AV_CODEC_ID_AAC CODEC_ID_AAC
#define AV_CODEC_ID_MP3 CODEC_ID_MP3
#define AV_CODEC_ID_NONE CODEC_ID_NONE
typedef CodecID AVCodecID;
#endif

View File

@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
'../FFmpegAACDecoder.cpp',
'../FFmpegAudioDecoder.cpp',
'../FFmpegDataDecoder.cpp',
'../FFmpegDecoderModule.cpp',
'../FFmpegH264Decoder.cpp',

View File

@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
'../FFmpegAACDecoder.cpp',
'../FFmpegAudioDecoder.cpp',
'../FFmpegDataDecoder.cpp',
'../FFmpegDecoderModule.cpp',
'../FFmpegH264Decoder.cpp',

View File

@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
'../FFmpegAACDecoder.cpp',
'../FFmpegAudioDecoder.cpp',
'../FFmpegDataDecoder.cpp',
'../FFmpegDecoderModule.cpp',
'../FFmpegH264Decoder.cpp',

View File

@ -48,9 +48,9 @@ GonkDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aCon
}
already_AddRefed<MediaDataDecoder>
GonkDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
GonkDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
{
nsRefPtr<MediaDataDecoder> decoder =
new GonkMediaDataDecoder(new GonkAudioDecoderManager(aConfig), aAudioTaskQueue,

View File

@ -29,9 +29,9 @@ public:
// Decode thread.
virtual already_AddRefed<MediaDataDecoder>
CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
static void Init();
};

View File

@ -81,9 +81,9 @@ WMFDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConf
}
already_AddRefed<MediaDataDecoder>
WMFDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
WMFDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback)
{
nsRefPtr<MediaDataDecoder> decoder =
new WMFMediaDataDecoder(new WMFAudioMFTManager(aConfig),

View File

@ -30,9 +30,9 @@ public:
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
virtual already_AddRefed<MediaDataDecoder>
CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
// Called on main thread.
static void Init();

View File

@ -309,9 +309,28 @@ MediaEngineWebRTCVideoSource::ChooseCapability(
// FIXME: expose expected capture delay?
}
}
// Same resolution, maybe better format or FPS match
if (mCapability.width == cap.width && mCapability.height == cap.height) {
// FPS too low
if (cap.maxFPS < (uint32_t) aPrefs.mMinFPS) {
continue;
}
// Better match
if (cap.maxFPS < mCapability.maxFPS) {
mCapability = cap;
} else if (cap.maxFPS == mCapability.maxFPS) {
// Resolution and FPS the same, check format
if (cap.rawType == webrtc::RawVideoType::kVideoI420
|| cap.rawType == webrtc::RawVideoType::kVideoYUY2
|| cap.rawType == webrtc::RawVideoType::kVideoYV12) {
mCapability = cap;
}
}
}
}
LOG(("chose cap %dx%d @%dfps",
mCapability.width, mCapability.height, mCapability.maxFPS));
LOG(("chose cap %dx%d @%dfps codec %d raw %d",
mCapability.width, mCapability.height, mCapability.maxFPS,
mCapability.codecType, mCapability.rawType));
#endif
}

View File

@ -31,15 +31,18 @@ CreateFileTask::CreateFileTask(FileSystemBase* aFileSystem,
ErrorResult& aRv)
: FileSystemTaskBase(aFileSystem)
, mTargetRealPath(aPath)
, mBlobData(aBlobData)
, mReplace(replace)
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
MOZ_ASSERT(aFileSystem);
GetOutputBufferSize();
if (mBlobData) {
nsresult rv = mBlobData->GetInternalStream(getter_AddRefs(mBlobStream));
NS_WARN_IF(NS_FAILED(rv));
if (aBlobData) {
if (FileSystemUtils::IsParentProcess()) {
nsresult rv = aBlobData->GetInternalStream(getter_AddRefs(mBlobStream));
NS_WARN_IF(NS_FAILED(rv));
} else {
mBlobData = aBlobData;
}
}
mArrayData.SwapElements(aArrayData);
nsCOMPtr<nsIGlobalObject> globalObject =
@ -74,16 +77,17 @@ CreateFileTask::CreateFileTask(FileSystemBase* aFileSystem,
}
BlobParent* bp = static_cast<BlobParent*>(static_cast<PBlobParent*>(data));
mBlobData = bp->GetBlob();
MOZ_ASSERT(mBlobData, "mBlobData should not be null.");
nsresult rv = mBlobData->GetInternalStream(getter_AddRefs(mBlobStream));
nsCOMPtr<nsIDOMBlob> blobData = bp->GetBlob();
MOZ_ASSERT(blobData, "blobData should not be null.");
nsresult rv = blobData->GetInternalStream(getter_AddRefs(mBlobStream));
NS_WARN_IF(NS_FAILED(rv));
}
CreateFileTask::~CreateFileTask()
{
MOZ_ASSERT(!mPromise || NS_IsMainThread(),
"mPromise should be released on main thread!");
MOZ_ASSERT((!mPromise && !mBlobData) || NS_IsMainThread(),
"mPromise and mBlobData should be released on main thread!");
if (mBlobStream) {
mBlobStream->Close();
}
@ -283,6 +287,7 @@ CreateFileTask::HandlerCallback()
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
if (mFileSystem->IsShutdown()) {
mPromise = nullptr;
mBlobData = nullptr;
return;
}
@ -291,12 +296,14 @@ CreateFileTask::HandlerCallback()
mErrorValue);
mPromise->MaybeRejectBrokenly(domError);
mPromise = nullptr;
mBlobData = nullptr;
return;
}
nsCOMPtr<nsIDOMFile> file = new DOMFile(mTargetFileImpl);
mPromise->MaybeResolve(file);
mPromise = nullptr;
mBlobData = nullptr;
}
void

View File

@ -66,7 +66,10 @@ private:
static uint32_t sOutputBufferSize;
nsRefPtr<Promise> mPromise;
nsString mTargetRealPath;
// Not thread-safe and should be released on main thread.
nsCOMPtr<nsIDOMBlob> mBlobData;
nsCOMPtr<nsIInputStream> mBlobStream;
InfallibleTArray<uint8_t> mArrayData;
bool mReplace;

View File

@ -15,7 +15,7 @@ class nsIURI;
class nsHyphenator
{
public:
nsHyphenator(nsIURI *aURI);
explicit nsHyphenator(nsIURI *aURI);
NS_INLINE_DECL_REFCOUNTING(nsHyphenator)

View File

@ -131,7 +131,7 @@ public:
/**
* Class constructor.
*/
nsBufferDecoderSupport(uint32_t aMaxLengthFactor);
explicit nsBufferDecoderSupport(uint32_t aMaxLengthFactor);
/**
* Class destructor.
@ -242,7 +242,7 @@ public:
/**
* Class constructor.
*/
nsOneByteDecoderSupport(uMappingTable * aMappingTable);
explicit nsOneByteDecoderSupport(uMappingTable * aMappingTable);
/**
* Class destructor.
@ -353,7 +353,7 @@ public:
/**
* Class constructor.
*/
nsEncoderSupport(uint32_t aMaxLengthFactor);
explicit nsEncoderSupport(uint32_t aMaxLengthFactor);
/**
* Class destructor.

View File

@ -28,7 +28,7 @@ public:
/**
* Class constructor.
*/
nsUnicodeToGBK(uint32_t aMaxLengthFactor = 2);
explicit nsUnicodeToGBK(uint32_t aMaxLengthFactor = 2);
virtual ~nsUnicodeToGBK() {}
protected:

View File

@ -7,6 +7,7 @@
#define GreekCasing_h_
#include <stdint.h>
#include "mozilla/Attributes.h"
namespace mozilla {
@ -45,7 +46,7 @@ public:
{
}
State(const GreekStates& aState)
MOZ_IMPLICIT State(const GreekStates& aState)
: mState(aState)
{
}

View File

@ -241,7 +241,7 @@ IrishCasing::UpperCase(uint32_t aCh, State& aState,
uint8_t stateEntry = sUppercaseStateTable[cls][aState];
aMarkPos = !!(stateEntry & kMarkPositionFlag);
aAction = (stateEntry & kActionMask) >> kActionShift;
aState = (stateEntry & kNextStateMask);
aState = State(stateEntry & kNextStateMask);
return ToUpperCase(aCh);
}

View File

@ -7,6 +7,7 @@
#define IrishCasing_h_
#include <stdint.h>
#include "mozilla/Attributes.h"
namespace mozilla {
@ -62,7 +63,7 @@ public:
{
}
State(const IrishStates& aState)
MOZ_IMPLICIT State(const IrishStates& aState)
: mState(aState)
{
}
@ -78,7 +79,7 @@ public:
}
private:
State(uint8_t aState)
explicit State(uint8_t aState)
: mState(IrishStates(aState))
{
}

View File

@ -553,8 +553,8 @@ jit::EliminateDeadCode(MIRGenerator *mir, MIRGraph &graph)
!inst->isControlInstruction())
{
inst = block->discardAt(inst);
} else if (!inst->isRecoveredOnBailout() && !inst->hasLiveDefUses() &&
inst->canRecoverOnBailout())
} else if (!inst->isRecoveredOnBailout() && !inst->isGuard() &&
!inst->hasLiveDefUses() && inst->canRecoverOnBailout())
{
inst->setRecoveredOnBailout();
inst++;

View File

@ -5294,6 +5294,7 @@ IonBuilder::makeCallHelper(JSFunction *target, CallInfo &callInfo, bool cloneAtC
// MCall accordingly.
types::TemporaryTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
if (thisTypes &&
thisTypes->getKnownMIRType() == MIRType_Object &&
thisTypes->isDOMClass() &&
testShouldDOMCall(thisTypes, target, JSJitInfo::Method))
{

View File

@ -67,7 +67,7 @@ sndio_mainloop(void *arg)
#define MAXFDS 8
struct pollfd pfds[MAXFDS];
cubeb_stream *s = arg;
int n, nfds, revents, state;
int n, nfds, revents, state = CUBEB_STATE_STARTED;
size_t start = 0, end = 0;
long nfr;
@ -271,7 +271,7 @@ static int
sndio_get_min_latency(cubeb * ctx, cubeb_stream_params params, uint32_t * latency_ms)
{
// XXX Not yet implemented.
latency_ms = 40;
*latency_ms = 40;
return CUBEB_OK;
}
@ -342,9 +342,10 @@ sndio_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
}
int
sndio_stream_set_volume(cubeb_stream * stm, float panning)
sndio_stream_set_panning(cubeb_stream * stm, float panning)
{
assert(0 && "not implemented");
assert(false && "not implemented");
return CUBEB_OK;
}
static struct cubeb_ops const sndio_ops = {

View File

@ -8,6 +8,7 @@
#include "mp4_demuxer/DecoderData.h"
#include "media/stagefright/MetaData.h"
#include "media/stagefright/MediaBuffer.h"
#include "media/stagefright/MediaDefs.h"
#include "media/stagefright/Utils.h"
#include "mozilla/ArrayUtils.h"
#include "include/ESDS.h"
@ -159,7 +160,7 @@ bool
AudioDecoderConfig::IsValid()
{
return channel_count > 0 && samples_per_second > 0 && frequency_index > 0 &&
aac_profile > 0;
(mime_type != MEDIA_MIMETYPE_AUDIO_AAC || aac_profile > 0);
}
void

View File

@ -4,6 +4,7 @@
#include "include/MPEG4Extractor.h"
#include "media/stagefright/DataSource.h"
#include "media/stagefright/MediaDefs.h"
#include "media/stagefright/MediaSource.h"
#include "media/stagefright/MetaData.h"
#include "mp4_demuxer/Adts.h"
@ -168,10 +169,12 @@ MP4Demuxer::DemuxAudioSample()
}
sample->Update();
if (!Adts::ConvertEsdsToAdts(mAudioConfig.channel_count,
mAudioConfig.frequency_index,
mAudioConfig.aac_profile, sample)) {
return nullptr;
if (!strcmp(mAudioConfig.mime_type, MEDIA_MIMETYPE_AUDIO_AAC)) {
if (!Adts::ConvertEsdsToAdts(mAudioConfig.channel_count,
mAudioConfig.frequency_index,
mAudioConfig.aac_profile, sample)) {
return nullptr;
}
}
return sample.forget();

View File

@ -2302,10 +2302,7 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
if (objectTypeIndication == 0x6b) {
// The media subtype is MP3 audio
// Our software MP3 audio decoder may not be able to handle
// packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED
ALOGE("MP3 track in MP4/3GPP file is not supported");
return ERROR_UNSUPPORTED;
mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
}
const uint8_t *csd;

View File

@ -206,7 +206,7 @@ CaptureInputPin::CheckMediaType ( IN const MediaType * pMediaType)
}
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _moduleId,
"CheckMediaType width:%d height:%d Compression:0x%x\n",
"CheckMediaType width:%d height:%d Compression:0x%x",
pvi->bmiHeader.biWidth,pvi->bmiHeader.biHeight,
pvi->bmiHeader.biCompression);
@ -259,7 +259,7 @@ CaptureInputPin::CheckMediaType ( IN const MediaType * pMediaType)
}
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _moduleId,
"CheckMediaType width:%d height:%d Compression:0x%x\n",
"CheckMediaType width:%d height:%d Compression:0x%x",
pvi->bmiHeader.biWidth,pvi->bmiHeader.biHeight,
pvi->bmiHeader.biCompression);

View File

@ -132,7 +132,7 @@ int32_t VideoCaptureDS::Init(const int32_t id, const char* deviceUniqueIdUTF8)
// Temporary connect here.
// This is done so that no one else can use the capture device.
if (SetCameraOutput(_requestedCapability) != 0)
if (SetCameraOutputIfNeeded(_requestedCapability) != 0)
{
return -1;
}
@ -154,15 +154,11 @@ int32_t VideoCaptureDS::StartCapture(
{
CriticalSectionScoped cs(&_apiCs);
if (capability != _requestedCapability)
if (SetCameraOutputIfNeeded(capability) != 0)
{
DisconnectGraph();
if (SetCameraOutput(capability) != 0)
{
return -1;
}
return -1;
}
HRESULT hr = _mediaControl->Run();
if (FAILED(hr))
{
@ -186,6 +182,7 @@ int32_t VideoCaptureDS::StopCapture()
}
return 0;
}
bool VideoCaptureDS::CaptureStarted()
{
OAFilterState state = 0;
@ -200,6 +197,7 @@ bool VideoCaptureDS::CaptureStarted()
return state == State_Running;
}
int32_t VideoCaptureDS::CaptureSettings(
VideoCaptureCapability& settings)
{
@ -207,16 +205,13 @@ int32_t VideoCaptureDS::CaptureSettings(
return 0;
}
int32_t VideoCaptureDS::SetCameraOutput(
const VideoCaptureCapability& requestedCapability)
int32_t VideoCaptureDS::SetCameraOutputIfNeeded(
const VideoCaptureCapability& requestedCapability)
{
// Get the best matching capability
VideoCaptureCapability capability;
int32_t capabilityIndex;
// Store the new requested size
_requestedCapability = requestedCapability;
// Match the requested capability with the supported.
if ((capabilityIndex = _dsInfo.GetBestMatchedCapability(_deviceUniqueId,
_requestedCapability,
@ -224,6 +219,16 @@ int32_t VideoCaptureDS::SetCameraOutput(
{
return -1;
}
if (capability != _activeCapability) {
DisconnectGraph();
// Store the new mode the camera actually selected
_activeCapability = capability;
} else {
// Camera selected the same mode, nothing to do
return 0;
}
//Reduce the frame rate if possible.
if (capability.maxFPS > requestedCapability.maxFPS)
{
@ -232,9 +237,17 @@ int32_t VideoCaptureDS::SetCameraOutput(
{
capability.maxFPS = 30;
}
// Store the new expected capture delay
_captureDelay = capability.expectedCaptureDelay;
return SetCameraOutput(capability, capabilityIndex);
}
int32_t VideoCaptureDS::SetCameraOutput(
const VideoCaptureCapability& capability,
int32_t capabilityIndex)
{
// Convert it to the windows capability index since they are not nexessary
// the same
VideoCaptureCapabilityWindows windowsCapability;

View File

@ -53,13 +53,17 @@ protected:
virtual ~VideoCaptureDS();
// Help functions
int32_t
SetCameraOutput(const VideoCaptureCapability& requestedCapability);
SetCameraOutputIfNeeded(const VideoCaptureCapability& requestedCapability);
int32_t
SetCameraOutput(const VideoCaptureCapability& requestedCapability,
int32_t capabilityIndex);
int32_t DisconnectGraph();
HRESULT VideoCaptureDS::ConnectDVCamera();
DeviceInfoDS _dsInfo;
VideoCaptureCapability _activeCapability;
IBaseFilter* _captureFilter;
IGraphBuilder* _graphBuilder;

View File

@ -265,7 +265,7 @@ CacheFile::Init(const nsACString &aKey,
mOpeningFile = true;
mListener = aCallback;
rv = CacheFileIOManager::OpenFile(mKey, flags, true, this);
rv = CacheFileIOManager::OpenFile(mKey, flags, this);
if (NS_FAILED(rv)) {
mListener = nullptr;
mOpeningFile = false;
@ -330,6 +330,13 @@ CacheFile::OnChunkRead(nsresult aResult, CacheFileChunk *aChunk)
nsresult
CacheFile::OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk)
{
// In case the chunk was reused, made dirty and released between calls to
// CacheFileChunk::Write() and CacheFile::OnChunkWritten(), we must write
// the chunk to the disk again. When the chunk is unused and is dirty simply
// addref and release (outside the lock) the chunk which ensures that
// CacheFile::DeactivateChunk() will be called again.
nsRefPtr<CacheFileChunk> deactivateChunkAgain;
CacheFileAutoLock lock(this);
nsresult rv;
@ -367,6 +374,14 @@ CacheFile::OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk)
return NS_OK;
}
if (aChunk->IsDirty()) {
LOG(("CacheFile::OnChunkWritten() - Unused chunk is dirty. We must go "
"through deactivation again. [this=%p, chunk=%p]", this, aChunk));
deactivateChunkAgain = aChunk;
return NS_OK;
}
bool keepChunk = false;
if (NS_SUCCEEDED(aResult)) {
keepChunk = ShouldCacheChunk(aChunk->Index());
@ -1594,7 +1609,12 @@ CacheFile::QueueChunkListener(uint32_t aIndex,
MOZ_ASSERT(aCallback);
ChunkListenerItem *item = new ChunkListenerItem();
item->mTarget = NS_GetCurrentThread();
item->mTarget = CacheFileIOManager::IOTarget();
if (!item->mTarget) {
LOG(("CacheFile::QueueChunkListener() - Cannot get Cache I/O thread! Using "
"main thread for callback."));
item->mTarget = do_GetMainThread();
}
item->mCallback = aCallback;
ChunkListeners *listeners;

View File

@ -201,7 +201,7 @@ CacheFileChunk::Read(CacheFileHandle *aHandle, uint32_t aLen,
DoMemoryReport(MemorySize());
rv = CacheFileIOManager::Read(aHandle, mIndex * kChunkSize, mRWBuf, aLen,
true, this);
this);
if (NS_WARN_IF(NS_FAILED(rv))) {
rv = mIndex ? NS_ERROR_FILE_CORRUPTED : NS_ERROR_FILE_NOT_FOUND;
SetError(rv);
@ -267,7 +267,14 @@ CacheFileChunk::WaitForUpdate(CacheFileChunkListener *aCallback)
#endif
ChunkListenerItem *item = new ChunkListenerItem();
item->mTarget = NS_GetCurrentThread();
item->mTarget = CacheFileIOManager::IOTarget();
if (!item->mTarget) {
LOG(("CacheFileChunk::WaitForUpdate() - Cannot get Cache I/O thread! Using "
"main thread for callback."));
item->mTarget = do_GetMainThread();
}
item->mCallback = aCallback;
MOZ_ASSERT(item->mTarget);
item->mCallback = aCallback;
mUpdateListeners.AppendElement(item);

View File

@ -550,22 +550,13 @@ protected:
class OpenFileEvent : public nsRunnable {
public:
OpenFileEvent(const nsACString &aKey,
uint32_t aFlags, bool aResultOnAnyThread,
OpenFileEvent(const nsACString &aKey, uint32_t aFlags,
CacheFileIOListener *aCallback)
: mFlags(aFlags)
, mResultOnAnyThread(aResultOnAnyThread)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
, mKey(aKey)
{
MOZ_COUNT_CTOR(OpenFileEvent);
if (!aResultOnAnyThread) {
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
MOZ_ASSERT(mTarget);
}
mIOMan = CacheFileIOManager::gInstance;
MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aKey.BeginReading());
@ -581,53 +572,38 @@ protected:
public:
NS_IMETHOD Run()
{
if (mResultOnAnyThread || mTarget) {
mRV = NS_OK;
nsresult rv = NS_OK;
if (!(mFlags & CacheFileIOManager::SPECIAL_FILE)) {
SHA1Sum sum;
sum.update(mKey.BeginReading(), mKey.Length());
sum.finish(mHash);
if (!(mFlags & CacheFileIOManager::SPECIAL_FILE)) {
SHA1Sum sum;
sum.update(mKey.BeginReading(), mKey.Length());
sum.finish(mHash);
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::open-background");
if (!mIOMan) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
if (mFlags & CacheFileIOManager::SPECIAL_FILE) {
rv = mIOMan->OpenSpecialFileInternal(mKey, mFlags,
getter_AddRefs(mHandle));
} else {
rv = mIOMan->OpenFileInternal(&mHash, mKey, mFlags,
getter_AddRefs(mHandle));
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this),
"net::cache::open-background");
if (NS_SUCCEEDED(mRV)) {
if (!mIOMan) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
if (mFlags & CacheFileIOManager::SPECIAL_FILE) {
mRV = mIOMan->OpenSpecialFileInternal(mKey, mFlags,
getter_AddRefs(mHandle));
} else {
mRV = mIOMan->OpenFileInternal(&mHash, mKey, mFlags,
getter_AddRefs(mHandle));
}
mIOMan = nullptr;
if (mHandle) {
MOZ_EVENT_TRACER_NAME_OBJECT(mHandle.get(), mKey.get());
if (mHandle->Key().IsEmpty()) {
mHandle->Key() = mKey;
}
}
mIOMan = nullptr;
if (mHandle) {
MOZ_EVENT_TRACER_NAME_OBJECT(mHandle.get(), mKey.get());
if (mHandle->Key().IsEmpty()) {
mHandle->Key() = mKey;
}
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-background");
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::open-result");
if (mTarget) {
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
return target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
}
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-background");
if (!mTarget) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::open-result");
mCallback->OnFileOpened(mHandle, mRV);
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-result");
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::open-result");
mCallback->OnFileOpened(mHandle, rv);
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-result");
return NS_OK;
}
@ -635,33 +611,24 @@ public:
protected:
SHA1Sum::Hash mHash;
uint32_t mFlags;
bool mResultOnAnyThread;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsRefPtr<CacheFileIOManager> mIOMan;
nsRefPtr<CacheFileHandle> mHandle;
nsresult mRV;
nsCString mKey;
};
class ReadEvent : public nsRunnable {
public:
ReadEvent(CacheFileHandle *aHandle, int64_t aOffset, char *aBuf,
int32_t aCount, bool aResultOnAnyThread, CacheFileIOListener *aCallback)
int32_t aCount, CacheFileIOListener *aCallback)
: mHandle(aHandle)
, mOffset(aOffset)
, mBuf(aBuf)
, mCount(aCount)
, mResultOnAnyThread(aResultOnAnyThread)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(ReadEvent);
if (!aResultOnAnyThread) {
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
}
MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aHandle->Key().get());
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::read-background");
}
@ -675,30 +642,20 @@ protected:
public:
NS_IMETHOD Run()
{
if (mResultOnAnyThread || mTarget) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-background");
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->ReadInternal(
mHandle, mOffset, mBuf, mCount);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-background");
nsresult rv;
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::read-result");
if (mTarget) {
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
return target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-background");
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
rv = CacheFileIOManager::gInstance->ReadInternal(
mHandle, mOffset, mBuf, mCount);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-background");
if (!mTarget && mCallback) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-result");
mCallback->OnDataRead(mHandle, mBuf, mRV);
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-result");
}
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-result");
mCallback->OnDataRead(mHandle, mBuf, rv);
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-result");
return NS_OK;
}
@ -708,10 +665,7 @@ protected:
int64_t mOffset;
char *mBuf;
int32_t mCount;
bool mResultOnAnyThread;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsresult mRV;
};
class WriteEvent : public nsRunnable {
@ -724,10 +678,8 @@ public:
, mCount(aCount)
, mValidate(aValidate)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(WriteEvent);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aHandle->Key().get());
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::write-background");
@ -746,30 +698,26 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-background");
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->WriteInternal(
mHandle, mOffset, mBuf, mCount, mValidate);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-background");
nsresult rv;
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::write-result");
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-background");
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-result");
if (mCallback) {
mCallback->OnDataWritten(mHandle, mBuf, mRV);
} else {
free(const_cast<char *>(mBuf));
mBuf = nullptr;
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-result");
rv = CacheFileIOManager::gInstance->WriteInternal(
mHandle, mOffset, mBuf, mCount, mValidate);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-background");
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-result");
if (mCallback) {
mCallback->OnDataWritten(mHandle, mBuf, rv);
} else {
free(const_cast<char *>(mBuf));
mBuf = nullptr;
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-result");
return NS_OK;
}
@ -780,8 +728,6 @@ protected:
int32_t mCount;
bool mValidate;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsresult mRV;
};
class DoomFileEvent : public nsRunnable {
@ -790,10 +736,8 @@ public:
CacheFileIOListener *aCallback)
: mCallback(aCallback)
, mHandle(aHandle)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(DoomFileEvent);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aHandle->Key().get());
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
@ -808,26 +752,22 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->DoomFileInternal(mHandle);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
nsresult rv;
MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
if (mCallback) {
mCallback->OnFileDoomed(mHandle, mRV);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
rv = CacheFileIOManager::gInstance->DoomFileInternal(mHandle);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
if (mCallback) {
mCallback->OnFileDoomed(mHandle, rv);
}
MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
return NS_OK;
}
@ -835,7 +775,6 @@ protected:
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsRefPtr<CacheFileHandle> mHandle;
nsresult mRV;
};
class DoomFileByKeyEvent : public nsRunnable {
@ -843,7 +782,6 @@ public:
DoomFileByKeyEvent(const nsACString &aKey,
CacheFileIOListener *aCallback)
: mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(DoomFileByKeyEvent);
@ -851,9 +789,7 @@ public:
sum.update(aKey.BeginReading(), aKey.Length());
sum.finish(mHash);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
mIOMan = CacheFileIOManager::gInstance;
MOZ_ASSERT(mTarget);
}
protected:
@ -865,31 +801,26 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
if (!mIOMan) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = mIOMan->DoomFileByKeyInternal(&mHash, false);
mIOMan = nullptr;
}
nsresult rv;
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
if (!mIOMan) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
if (mCallback) {
mCallback->OnFileDoomed(nullptr, mRV);
}
rv = mIOMan->DoomFileByKeyInternal(&mHash, false);
mIOMan = nullptr;
}
if (mCallback) {
mCallback->OnFileDoomed(nullptr, rv);
}
return NS_OK;
}
protected:
SHA1Sum::Hash mHash;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsRefPtr<CacheFileIOManager> mIOMan;
nsresult mRV;
};
class ReleaseNSPRHandleEvent : public nsRunnable {
@ -928,10 +859,8 @@ public:
, mTruncatePos(aTruncatePos)
, mEOFPos(aEOFPos)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(TruncateSeekSetEOFEvent);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
}
protected:
@ -943,22 +872,19 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->TruncateSeekSetEOFInternal(
mHandle, mTruncatePos, mEOFPos);
}
nsresult rv;
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
if (mCallback) {
mCallback->OnEOFSet(mHandle, mRV);
}
rv = CacheFileIOManager::gInstance->TruncateSeekSetEOFInternal(
mHandle, mTruncatePos, mEOFPos);
}
if (mCallback) {
mCallback->OnEOFSet(mHandle, rv);
}
return NS_OK;
}
@ -967,8 +893,6 @@ protected:
int64_t mTruncatePos;
int64_t mEOFPos;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsresult mRV;
};
class RenameFileEvent : public nsRunnable {
@ -978,10 +902,8 @@ public:
: mHandle(aHandle)
, mNewName(aNewName)
, mCallback(aCallback)
, mRV(NS_ERROR_FAILURE)
{
MOZ_COUNT_CTOR(RenameFileEvent);
mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
}
protected:
@ -993,22 +915,19 @@ protected:
public:
NS_IMETHOD Run()
{
if (mTarget) {
if (mHandle->IsClosed()) {
mRV = NS_ERROR_NOT_INITIALIZED;
} else {
mRV = CacheFileIOManager::gInstance->RenameFileInternal(mHandle,
mNewName);
}
nsresult rv;
nsCOMPtr<nsIEventTarget> target;
mTarget.swap(target);
target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
if (mHandle->IsClosed()) {
rv = NS_ERROR_NOT_INITIALIZED;
} else {
if (mCallback) {
mCallback->OnFileRenamed(mHandle, mRV);
}
rv = CacheFileIOManager::gInstance->RenameFileInternal(mHandle,
mNewName);
}
if (mCallback) {
mCallback->OnFileRenamed(mHandle, rv);
}
return NS_OK;
}
@ -1016,8 +935,6 @@ protected:
nsRefPtr<CacheFileHandle> mHandle;
nsCString mNewName;
nsCOMPtr<CacheFileIOListener> mCallback;
nsCOMPtr<nsIEventTarget> mTarget;
nsresult mRV;
};
class InitIndexEntryEvent : public nsRunnable {
@ -1604,8 +1521,7 @@ CacheFileIOManager::Notify(nsITimer * aTimer)
// static
nsresult
CacheFileIOManager::OpenFile(const nsACString &aKey,
uint32_t aFlags, bool aResultOnAnyThread,
CacheFileIOListener *aCallback)
uint32_t aFlags, CacheFileIOListener *aCallback)
{
LOG(("CacheFileIOManager::OpenFile() [key=%s, flags=%d, listener=%p]",
PromiseFlatCString(aKey).get(), aFlags, aCallback));
@ -1618,7 +1534,7 @@ CacheFileIOManager::OpenFile(const nsACString &aKey,
}
bool priority = aFlags & CacheFileIOManager::PRIORITY;
nsRefPtr<OpenFileEvent> ev = new OpenFileEvent(aKey, aFlags, aResultOnAnyThread, aCallback);
nsRefPtr<OpenFileEvent> ev = new OpenFileEvent(aKey, aFlags, aCallback);
rv = ioMan->mIOThread->Dispatch(ev, priority
? CacheIOThread::OPEN_PRIORITY
: CacheIOThread::OPEN);
@ -1874,7 +1790,7 @@ CacheFileIOManager::CloseHandleInternal(CacheFileHandle *aHandle)
// static
nsresult
CacheFileIOManager::Read(CacheFileHandle *aHandle, int64_t aOffset,
char *aBuf, int32_t aCount, bool aResultOnAnyThread,
char *aBuf, int32_t aCount,
CacheFileIOListener *aCallback)
{
LOG(("CacheFileIOManager::Read() [handle=%p, offset=%lld, count=%d, "
@ -1888,7 +1804,7 @@ CacheFileIOManager::Read(CacheFileHandle *aHandle, int64_t aOffset,
}
nsRefPtr<ReadEvent> ev = new ReadEvent(aHandle, aOffset, aBuf, aCount,
aResultOnAnyThread, aCallback);
aCallback);
rv = ioMan->mIOThread->Dispatch(ev, aHandle->IsPriority()
? CacheIOThread::READ_PRIORITY
: CacheIOThread::READ);

View File

@ -241,10 +241,9 @@ public:
static nsresult ShutdownMetadataWriteScheduling();
static nsresult OpenFile(const nsACString &aKey,
uint32_t aFlags, bool aResultOnAnyThread,
CacheFileIOListener *aCallback);
uint32_t aFlags, CacheFileIOListener *aCallback);
static nsresult Read(CacheFileHandle *aHandle, int64_t aOffset,
char *aBuf, int32_t aCount, bool aResultOnAnyThread,
char *aBuf, int32_t aCount,
CacheFileIOListener *aCallback);
static nsresult Write(CacheFileHandle *aHandle, int64_t aOffset,
const char *aBuf, int32_t aCount, bool aValidate,

View File

@ -539,8 +539,14 @@ CacheFileInputStream::NotifyListener()
MOZ_ASSERT(mCallback);
if (!mCallbackTarget)
mCallbackTarget = NS_GetCurrentThread();
if (!mCallbackTarget) {
mCallbackTarget = CacheFileIOManager::IOTarget();
if (!mCallbackTarget) {
LOG(("CacheFileInputStream::NotifyListener() - Cannot get Cache I/O "
"thread! Using main thread for callback."));
mCallbackTarget = do_GetMainThread();
}
}
nsCOMPtr<nsIInputStreamCallback> asyncCallback =
NS_NewInputStreamReadyEvent(mCallback, mCallbackTarget);

View File

@ -206,7 +206,7 @@ CacheFileMetadata::ReadMetadata(CacheFileMetadataListener *aListener)
"offset=%lld, filesize=%lld [this=%p]", offset, size, this));
mListener = aListener;
rv = CacheFileIOManager::Read(mHandle, offset, mBuf, mBufSize, true, this);
rv = CacheFileIOManager::Read(mHandle, offset, mBuf, mBufSize, this);
if (NS_FAILED(rv)) {
LOG(("CacheFileMetadata::ReadMetadata() - CacheFileIOManager::Read() failed"
" synchronously, creating empty metadata. [this=%p, rv=0x%08x]",
@ -661,7 +661,7 @@ CacheFileMetadata::OnDataRead(CacheFileHandle *aHandle, char *aBuf,
LOG(("CacheFileMetadata::OnDataRead() - We need to read %d more bytes to "
"have full metadata. [this=%p]", missing, this));
rv = CacheFileIOManager::Read(mHandle, realOffset, mBuf, missing, true, this);
rv = CacheFileIOManager::Read(mHandle, realOffset, mBuf, missing, this);
if (NS_FAILED(rv)) {
LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
"failed synchronously, creating empty metadata. [this=%p, "

View File

@ -419,8 +419,14 @@ CacheFileOutputStream::NotifyListener()
MOZ_ASSERT(mCallback);
if (!mCallbackTarget)
mCallbackTarget = NS_GetCurrentThread();
if (!mCallbackTarget) {
mCallbackTarget = CacheFileIOManager::IOTarget();
if (!mCallbackTarget) {
LOG(("CacheFileOutputStream::NotifyListener() - Cannot get Cache I/O "
"thread! Using main thread for callback."));
mCallbackTarget = do_GetMainThread();
}
}
nsCOMPtr<nsIOutputStreamCallback> asyncCallback =
NS_NewOutputStreamReadyEvent(mCallback, mCallbackTarget);

View File

@ -1565,7 +1565,6 @@ CacheIndex::WriteIndexToDisk()
rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kTempIndexName),
CacheFileIOManager::SPECIAL_FILE |
CacheFileIOManager::CREATE,
true,
mIndexFileOpener);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::WriteIndexToDisk() - Can't open file [rv=0x%08x]", rv));
@ -2011,7 +2010,6 @@ CacheIndex::ReadIndexFromDisk()
rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kIndexName),
CacheFileIOManager::SPECIAL_FILE |
CacheFileIOManager::OPEN,
true,
mIndexFileOpener);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() "
@ -2024,7 +2022,6 @@ CacheIndex::ReadIndexFromDisk()
rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kJournalName),
CacheFileIOManager::SPECIAL_FILE |
CacheFileIOManager::OPEN,
true,
mJournalFileOpener);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() "
@ -2036,7 +2033,6 @@ CacheIndex::ReadIndexFromDisk()
rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kTempIndexName),
CacheFileIOManager::SPECIAL_FILE |
CacheFileIOManager::OPEN,
true,
mTmpFileOpener);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() "
@ -2077,7 +2073,7 @@ CacheIndex::StartReadingIndex()
mRWBufPos = std::min(mRWBufSize,
static_cast<uint32_t>(mIndexHandle->FileSize()));
rv = CacheFileIOManager::Read(mIndexHandle, 0, mRWBuf, mRWBufPos, true, this);
rv = CacheFileIOManager::Read(mIndexHandle, 0, mRWBuf, mRWBufPos, this);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::StartReadingIndex() - CacheFileIOManager::Read() failed "
"synchronously [rv=0x%08x]", rv));
@ -2202,7 +2198,7 @@ CacheIndex::ParseRecords()
mRWBufPos = pos + toRead;
rv = CacheFileIOManager::Read(mIndexHandle, fileOffset, mRWBuf + pos, toRead,
true, this);
this);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ParseRecords() - CacheFileIOManager::Read() failed "
"synchronously [rv=0x%08x]", rv));
@ -2240,7 +2236,7 @@ CacheIndex::StartReadingJournal()
mRWBufPos = std::min(mRWBufSize,
static_cast<uint32_t>(mJournalHandle->FileSize()));
rv = CacheFileIOManager::Read(mJournalHandle, 0, mRWBuf, mRWBufPos, true, this);
rv = CacheFileIOManager::Read(mJournalHandle, 0, mRWBuf, mRWBufPos, this);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::StartReadingJournal() - CacheFileIOManager::Read() failed"
" synchronously [rv=0x%08x]", rv));
@ -2315,7 +2311,7 @@ CacheIndex::ParseJournal()
mRWBufPos = pos + toRead;
rv = CacheFileIOManager::Read(mJournalHandle, fileOffset, mRWBuf + pos,
toRead, true, this);
toRead, this);
if (NS_FAILED(rv)) {
LOG(("CacheIndex::ParseJournal() - CacheFileIOManager::Read() failed "
"synchronously [rv=0x%08x]", rv));

View File

@ -1495,9 +1495,11 @@ CacheStorageService::CheckStorageEntry(CacheStorage const* aStorage,
namespace { // anon
class CacheEntryDoomByKeyCallback : public CacheFileIOListener
, public nsIRunnable
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIRUNNABLE
explicit CacheEntryDoomByKeyCallback(nsICacheEntryDoomCallback* aCallback)
: mCallback(aCallback) { }
@ -1513,6 +1515,7 @@ private:
NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) { return NS_OK; }
nsCOMPtr<nsICacheEntryDoomCallback> mCallback;
nsresult mResult;
};
CacheEntryDoomByKeyCallback::~CacheEntryDoomByKeyCallback()
@ -1527,11 +1530,23 @@ NS_IMETHODIMP CacheEntryDoomByKeyCallback::OnFileDoomed(CacheFileHandle *aHandle
if (!mCallback)
return NS_OK;
mCallback->OnCacheEntryDoomed(aResult);
mResult = aResult;
if (NS_IsMainThread()) {
Run();
} else {
NS_DispatchToMainThread(this);
}
return NS_OK;
}
NS_IMPL_ISUPPORTS(CacheEntryDoomByKeyCallback, CacheFileIOListener);
NS_IMETHODIMP CacheEntryDoomByKeyCallback::Run()
{
mCallback->OnCacheEntryDoomed(mResult);
return NS_OK;
}
NS_IMPL_ISUPPORTS(CacheEntryDoomByKeyCallback, CacheFileIOListener, nsIRunnable);
} // anon
@ -1603,8 +1618,22 @@ CacheStorageService::DoomStorageEntry(CacheStorage const* aStorage,
return NS_OK;
}
if (aCallback)
aCallback->OnCacheEntryDoomed(NS_ERROR_NOT_AVAILABLE);
class Callback : public nsRunnable
{
public:
Callback(nsICacheEntryDoomCallback* aCallback) : mCallback(aCallback) { }
NS_IMETHODIMP Run()
{
mCallback->OnCacheEntryDoomed(NS_ERROR_NOT_AVAILABLE);
return NS_OK;
}
nsCOMPtr<nsICacheEntryDoomCallback> mCallback;
};
if (aCallback) {
nsRefPtr<nsRunnable> callback = new Callback(aCallback);
return NS_DispatchToMainThread(callback);
}
return NS_OK;
}
@ -1700,7 +1729,7 @@ CacheStorageService::DoomStorageEntries(nsCSubstring const& aContextKey,
if (aCallback) {
nsRefPtr<nsRunnable> callback = new Callback(aCallback);
return NS_DispatchToCurrentThread(callback);
return NS_DispatchToMainThread(callback);
}
return NS_OK;

View File

@ -4,25 +4,33 @@ function run_test()
var storage = getCacheStorage("disk");
var mc = new MultipleCallbacks(4, function() {
syncWithCacheIOThread(function() {
// Method asyncVisitStorage() gets the data from index on Cache I/O thread
// with INDEX priority, so it is ensured that index contains information
// about all pending writes. However, OpenCallback emulates network latency
// by postponing the writes using do_execute_soon. We must do the same here
// to make sure that all writes are posted to Cache I/O thread before we
// visit the storage.
do_execute_soon(function() {
syncWithCacheIOThread(function() {
var expectedConsumption = newCacheBackEndUsed()
? 4096
: 48;
var expectedConsumption = newCacheBackEndUsed()
? 4096
: 48;
storage.asyncVisitStorage(
// Test should store 4 entries
new VisitCallback(4, expectedConsumption, ["http://a/", "http://b/", "http://c/", "http://d/"], function() {
storage.asyncVisitStorage(
// Still 4 entries expected, now don't walk them
new VisitCallback(4, expectedConsumption, null, function() {
finish_cache2_test();
}),
false
);
}),
true
);
storage.asyncVisitStorage(
// Test should store 4 entries
new VisitCallback(4, expectedConsumption, ["http://a/", "http://b/", "http://c/", "http://d/"], function() {
storage.asyncVisitStorage(
// Still 4 entries expected, now don't walk them
new VisitCallback(4, expectedConsumption, null, function() {
finish_cache2_test();
}),
false
);
}),
true
);
});
});
}, !newCacheBackEndUsed());

View File

@ -22,10 +22,12 @@ function run_test()
asyncOpenCacheEntry("http://read/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, LoadContextInfo.default,
new OpenCallback(NEW|WAITFORWRITE, "", payload, function(entry) {
var is = entry.openInputStream(0);
do_check_eq(is.available(), kChunkSize + 10);
var payloadCheck = read_stream(is, kChunkSize + 10);
do_check_true(payloadCheck == payload); // not using do_check_eq since logger will fail for the 1/4MB string
finish_cache2_test();
pumpReadStream(is, function(read) {
do_check_eq(read.length, kChunkSize + 10);
is.close();
do_check_true(read == payload); // not using do_check_eq since logger will fail for the 1/4MB string
finish_cache2_test();
});
})
);

View File

@ -85,7 +85,7 @@ class CommandAction(argparse.Action):
"""
if namespace.help:
# -h or --help is in the global arguments.
self._handle_main_help(parser)
self._handle_main_help(parser, namespace.verbose)
sys.exit(0)
elif values:
command = values[0].lower()
@ -96,7 +96,7 @@ class CommandAction(argparse.Action):
# Make sure args[0] is indeed a command.
self._handle_subcommand_help(parser, args[0])
else:
self._handle_main_help(parser)
self._handle_main_help(parser, namespace.verbose)
sys.exit(0)
elif '-h' in args or '--help' in args:
# -h or --help is in the command arguments.
@ -146,11 +146,10 @@ class CommandAction(argparse.Action):
command_namespace, extra = subparser.parse_known_args(args)
setattr(namespace, 'command_args', command_namespace)
if extra:
raise UnrecognizedArgumentError(command, extra)
def _handle_main_help(self, parser):
def _handle_main_help(self, parser, verbose):
# Since we don't need full sub-parser support for the main help output,
# we create groups in the ArgumentParser and populate each group with
# arguments corresponding to command names. This has the side-effect
@ -197,9 +196,10 @@ class CommandAction(argparse.Action):
if disabled_commands and 'disabled' in r.categories:
title, description, _priority = r.categories['disabled']
group = parser.add_argument_group(title, description)
for c in disabled_commands:
group.add_argument(c['command'], help=c['description'],
action='store_true')
if verbose == True:
for c in disabled_commands:
group.add_argument(c['command'], help=c['description'],
action='store_true')
parser.print_help()