From 50da64b073d0b0680e70d495a3761c9782d44207 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Mon, 18 Aug 2014 11:37:30 +0200 Subject: [PATCH 01/17] Bug 1054176 : fix cubeb sndio build after bug 1027713 r=kinetik --- media/libcubeb/src/cubeb_sndio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/media/libcubeb/src/cubeb_sndio.c b/media/libcubeb/src/cubeb_sndio.c index 751b7f6c42e..8e7c532eda0 100644 --- a/media/libcubeb/src/cubeb_sndio.c +++ b/media/libcubeb/src/cubeb_sndio.c @@ -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 = { From f82402f48301e2adb3ce4cd188b4eaedde75afaf Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Mon, 18 Aug 2014 11:38:08 +0200 Subject: [PATCH 02/17] Bug 1054176 - fix some warnings about unitialized values and bad assign r=kinetik --- media/libcubeb/src/cubeb_sndio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/media/libcubeb/src/cubeb_sndio.c b/media/libcubeb/src/cubeb_sndio.c index 8e7c532eda0..e0d789d01e6 100644 --- a/media/libcubeb/src/cubeb_sndio.c +++ b/media/libcubeb/src/cubeb_sndio.c @@ -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; } From 08dad282970ea81d5cfd23a3a805cf331bdb007c Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Mon, 18 Aug 2014 12:03:46 +0300 Subject: [PATCH 03/17] Bug 833143, Don't GC in nsXREDirProvider::DoShutdown(), r=billm,bsmedberg --HG-- extra : rebase_source : 4f60a43e760916232d6879493f81c11dff9f903d --- toolkit/xre/nsXREDirProvider.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index 94e15bfa1d9..32632c9f529 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -882,19 +882,6 @@ nsXREDirProvider::DoShutdown() obsSvc->NotifyObservers(nullptr, "profile-change-net-teardown", kShutdownPersist); obsSvc->NotifyObservers(nullptr, "profile-change-teardown", kShutdownPersist); - // Phase 2c: Now that things are torn down, force JS GC so that things which depend on - // resources which are about to go away in "profile-before-change" are destroyed first. - - nsCOMPtr rtsvc - (do_GetService("@mozilla.org/js/xpc/RuntimeService;1")); - if (rtsvc) - { - JSRuntime *rt = nullptr; - rtsvc->GetRuntime(&rt); - if (rt) - ::JS_GC(rt); - } - // Phase 3: Notify observers of a profile change obsSvc->NotifyObservers(nullptr, "profile-before-change", kShutdownPersist); obsSvc->NotifyObservers(nullptr, "profile-before-change2", kShutdownPersist); From 1f9e94c4fcc0940ea41f545842a279de75dfb3a6 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Mon, 18 Aug 2014 12:03:55 +0200 Subject: [PATCH 04/17] Bug 1054359 - Add is-object check to IonBuilder::makeCallHelper. r=efaust --- js/src/jit/IonBuilder.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 17bb9cebde0..a069b417b6a 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -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)) { From 7c86c5f08572923253604eaa05d646d848184764 Mon Sep 17 00:00:00 2001 From: Hannes Verschore Date: Mon, 18 Aug 2014 13:52:12 +0200 Subject: [PATCH 05/17] Bug 1054974 - Don't recover instructions which have the Guard flag, r=nbp --- js/src/jit/IonAnalysis.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index a758547124f..c9f5cb9be0e 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -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++; From c4f269369f5332863ff0cedeec703b5e48bc330c Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Mon, 18 Aug 2014 14:13:15 +0100 Subject: [PATCH 06/17] Backed out changeset 006353e45fa7 (bug 833143) for robocop crashes; CLOSED TREE --- toolkit/xre/nsXREDirProvider.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp index 32632c9f529..94e15bfa1d9 100644 --- a/toolkit/xre/nsXREDirProvider.cpp +++ b/toolkit/xre/nsXREDirProvider.cpp @@ -882,6 +882,19 @@ nsXREDirProvider::DoShutdown() obsSvc->NotifyObservers(nullptr, "profile-change-net-teardown", kShutdownPersist); obsSvc->NotifyObservers(nullptr, "profile-change-teardown", kShutdownPersist); + // Phase 2c: Now that things are torn down, force JS GC so that things which depend on + // resources which are about to go away in "profile-before-change" are destroyed first. + + nsCOMPtr rtsvc + (do_GetService("@mozilla.org/js/xpc/RuntimeService;1")); + if (rtsvc) + { + JSRuntime *rt = nullptr; + rtsvc->GetRuntime(&rt); + if (rt) + ::JS_GC(rt); + } + // Phase 3: Notify observers of a profile change obsSvc->NotifyObservers(nullptr, "profile-before-change", kShutdownPersist); obsSvc->NotifyObservers(nullptr, "profile-before-change2", kShutdownPersist); From 04f67aa5ce143d6b5b7b61ca2b60b6c27000edb8 Mon Sep 17 00:00:00 2001 From: Anthony Jones Date: Thu, 17 Jul 2014 15:52:14 +1200 Subject: [PATCH 07/17] Bug 1022501 - Fix Windows falsely reporting support for MP3 in fragmented MP4. r=cpearce --HG-- extra : rebase_source : 5cd91bb97d4e2e35b88407c0b3cecdae9bfbd793 --- content/media/DecoderTraits.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/media/DecoderTraits.cpp b/content/media/DecoderTraits.cpp index 30e5db2b80a..9cbcedeea71 100644 --- a/content/media/DecoderTraits.cpp +++ b/content/media/DecoderTraits.cpp @@ -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; } From ad96318c23bc6a18abee480ef2181fc0f1c5f642 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Fri, 15 Aug 2014 16:25:06 +1000 Subject: [PATCH 08/17] Bug 1022501 - Add MP3 support to MP4 demuxer. r=edwin --HG-- rename : content/media/fmp4/eme/EMEAACDecoder.cpp => content/media/fmp4/eme/EMEAudioDecoder.cpp rename : content/media/fmp4/eme/EMEAACDecoder.h => content/media/fmp4/eme/EMEAudioDecoder.h rename : content/media/fmp4/ffmpeg/FFmpegAACDecoder.cpp => content/media/fmp4/ffmpeg/FFmpegAudioDecoder.cpp rename : content/media/fmp4/ffmpeg/FFmpegAACDecoder.h => content/media/fmp4/ffmpeg/FFmpegAudioDecoder.h extra : rebase_source : 964077ffa7abd11a5da586bfcdee2ee98d4bc210 --- content/media/fmp4/BlankDecoderModule.cpp | 13 +++- content/media/fmp4/MP4Reader.cpp | 27 ++++--- content/media/fmp4/MP4Reader.h | 1 + content/media/fmp4/PlatformDecoderModule.cpp | 6 ++ content/media/fmp4/PlatformDecoderModule.h | 17 +++-- content/media/fmp4/apple/AppleATDecoder.cpp | 20 +++-- content/media/fmp4/apple/AppleATDecoder.h | 1 + .../media/fmp4/apple/AppleDecoderModule.cpp | 12 ++- content/media/fmp4/apple/AppleDecoderModule.h | 8 +- ...{EMEAACDecoder.cpp => EMEAudioDecoder.cpp} | 60 +++++++-------- .../{EMEAACDecoder.h => EMEAudioDecoder.h} | 24 +++--- content/media/fmp4/eme/EMEDecoderModule.cpp | 22 +++--- content/media/fmp4/eme/EMEDecoderModule.h | 6 +- content/media/fmp4/eme/moz.build | 4 +- ...gAACDecoder.cpp => FFmpegAudioDecoder.cpp} | 73 ++++++++++++++----- ...FmpegAACDecoder.h => FFmpegAudioDecoder.h} | 13 ++-- .../media/fmp4/ffmpeg/FFmpegDataDecoder.cpp | 6 +- .../media/fmp4/ffmpeg/FFmpegDecoderModule.h | 15 ++-- content/media/fmp4/ffmpeg/FFmpegLibs.h | 2 + content/media/fmp4/ffmpeg/libav53/moz.build | 2 +- content/media/fmp4/ffmpeg/libav54/moz.build | 2 +- content/media/fmp4/ffmpeg/libav55/moz.build | 2 +- content/media/fmp4/gonk/GonkDecoderModule.cpp | 6 +- content/media/fmp4/gonk/GonkDecoderModule.h | 6 +- content/media/fmp4/wmf/WMFDecoderModule.cpp | 6 +- content/media/fmp4/wmf/WMFDecoderModule.h | 6 +- media/libstagefright/binding/DecoderData.cpp | 3 +- media/libstagefright/binding/mp4_demuxer.cpp | 11 ++- .../media/libstagefright/MPEG4Extractor.cpp | 5 +- 29 files changed, 234 insertions(+), 145 deletions(-) rename content/media/fmp4/eme/{EMEAACDecoder.cpp => EMEAudioDecoder.cpp} (84%) rename content/media/fmp4/eme/{EMEAACDecoder.h => EMEAudioDecoder.h} (85%) rename content/media/fmp4/ffmpeg/{FFmpegAACDecoder.cpp => FFmpegAudioDecoder.cpp} (54%) rename content/media/fmp4/ffmpeg/{FFmpegAACDecoder.h => FFmpegAudioDecoder.h} (68%) diff --git a/content/media/fmp4/BlankDecoderModule.cpp b/content/media/fmp4/BlankDecoderModule.cpp index 637d8fdf267..25d8b63311e 100644 --- a/content/media/fmp4/BlankDecoderModule.cpp +++ b/content/media/fmp4/BlankDecoderModule.cpp @@ -229,9 +229,9 @@ public: // Decode thread. virtual already_AddRefed - 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() diff --git a/content/media/fmp4/MP4Reader.cpp b/content/media/fmp4/MP4Reader.cpp index 5f2f536ffa4..7341564fccf 100644 --- a/content/media/fmp4/MP4Reader.cpp +++ b/content/media/fmp4/MP4Reader.cpp @@ -288,6 +288,14 @@ MP4Reader::ExtractCryptoInitData(nsTArray& 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); diff --git a/content/media/fmp4/MP4Reader.h b/content/media/fmp4/MP4Reader.h index 6bc00ad18b3..6fa9cbe2278 100644 --- a/content/media/fmp4/MP4Reader.h +++ b/content/media/fmp4/MP4Reader.h @@ -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(); diff --git a/content/media/fmp4/PlatformDecoderModule.cpp b/content/media/fmp4/PlatformDecoderModule.cpp index c19b03bceed..cd145b5a6ad 100644 --- a/content/media/fmp4/PlatformDecoderModule.cpp +++ b/content/media/fmp4/PlatformDecoderModule.cpp @@ -153,4 +153,10 @@ PlatformDecoderModule::Create() return nullptr; } +bool +PlatformDecoderModule::SupportsAudioMimeType(const char* aMimeType) +{ + return !strcmp(aMimeType, "audio/mp4a-latm"); +} + } // namespace mozilla diff --git a/content/media/fmp4/PlatformDecoderModule.h b/content/media/fmp4/PlatformDecoderModule.h index 9c677139a8e..d8bf178eafd 100644 --- a/content/media/fmp4/PlatformDecoderModule.h +++ b/content/media/fmp4/PlatformDecoderModule.h @@ -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 - 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() {} diff --git a/content/media/fmp4/apple/AppleATDecoder.cpp b/content/media/fmp4/apple/AppleATDecoder.cpp index bef1b05dc66..67322751b06 100644 --- a/content/media/fmp4/apple/AppleATDecoder.cpp +++ b/content/media/fmp4/apple/AppleATDecoder.cpp @@ -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"); diff --git a/content/media/fmp4/apple/AppleATDecoder.h b/content/media/fmp4/apple/AppleATDecoder.h index b236a1974d9..6c84a907663 100644 --- a/content/media/fmp4/apple/AppleATDecoder.h +++ b/content/media/fmp4/apple/AppleATDecoder.h @@ -53,6 +53,7 @@ private: int64_t mSamplePosition; bool mHaveOutput; AudioStreamBasicDescription mOutputFormat; + AudioFileTypeID mFileType; void SetupDecoder(); void SubmitSample(nsAutoPtr aSample); diff --git a/content/media/fmp4/apple/AppleDecoderModule.cpp b/content/media/fmp4/apple/AppleDecoderModule.cpp index eb037bae915..fc4919c7fa6 100644 --- a/content/media/fmp4/apple/AppleDecoderModule.cpp +++ b/content/media/fmp4/apple/AppleDecoderModule.cpp @@ -87,13 +87,19 @@ AppleDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aCo } already_AddRefed -AppleDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, - MediaTaskQueue* aAudioTaskQueue, - MediaDataDecoderCallback* aCallback) +AppleDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aAudioTaskQueue, + MediaDataDecoderCallback* aCallback) { nsRefPtr 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 diff --git a/content/media/fmp4/apple/AppleDecoderModule.h b/content/media/fmp4/apple/AppleDecoderModule.h index 21943f808ee..639ec8a730e 100644 --- a/content/media/fmp4/apple/AppleDecoderModule.h +++ b/content/media/fmp4/apple/AppleDecoderModule.h @@ -34,9 +34,11 @@ public: // Decode thread. virtual already_AddRefed - 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: diff --git a/content/media/fmp4/eme/EMEAACDecoder.cpp b/content/media/fmp4/eme/EMEAudioDecoder.cpp similarity index 84% rename from content/media/fmp4/eme/EMEAACDecoder.cpp rename to content/media/fmp4/eme/EMEAudioDecoder.cpp index fa32b5e1395..94aec13b8a2 100644 --- a/content/media/fmp4/eme/EMEAACDecoder.cpp +++ b/content/media/fmp4/eme/EMEAudioDecoder.cpp @@ -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 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 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 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& aPCM, - uint64_t aTimeStamp, - uint32_t aChannels, - uint32_t aRate) +EMEAudioDecoder::Decoded(const nsTArray& aPCM, + uint64_t aTimeStamp, + uint32_t aChannels, + uint32_t aRate) { MOZ_ASSERT(IsOnGMPThread()); @@ -192,21 +192,21 @@ EMEAACDecoder::Decoded(const nsTArray& 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 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) { diff --git a/content/media/fmp4/eme/EMEAACDecoder.h b/content/media/fmp4/eme/EMEAudioDecoder.h similarity index 85% rename from content/media/fmp4/eme/EMEAACDecoder.h rename to content/media/fmp4/eme/EMEAudioDecoder.h index 9232cdbaa92..2d4bcb7b857 100644 --- a/content/media/fmp4/eme/EMEAACDecoder.h +++ b/content/media/fmp4/eme/EMEAudioDecoder.h @@ -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 mDecoder; + nsRefPtr mDecoder; nsAutoPtr 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 \ No newline at end of file +#endif diff --git a/content/media/fmp4/eme/EMEDecoderModule.cpp b/content/media/fmp4/eme/EMEDecoderModule.cpp index 65c6d9f555c..968e12d90b0 100644 --- a/content/media/fmp4/eme/EMEDecoderModule.cpp +++ b/content/media/fmp4/eme/EMEDecoderModule.cpp @@ -19,7 +19,7 @@ #include "SharedThreadPool.h" #include "mozilla/EMELog.h" #include "EMEH264Decoder.h" -#include "EMEAACDecoder.h" +#include "EMEAudioDecoder.h" #include namespace mozilla { @@ -227,21 +227,21 @@ EMEDecoderModule::CreateH264Decoder(const VideoDecoderConfig& aConfig, } already_AddRefed -EMEDecoderModule::CreateAACDecoder(const AudioDecoderConfig& aConfig, - MediaTaskQueue* aAudioTaskQueue, - MediaDataDecoderCallback* aCallback) +EMEDecoderModule::CreateAudioDecoder(const AudioDecoderConfig& aConfig, + MediaTaskQueue* aAudioTaskQueue, + MediaDataDecoderCallback* aCallback) { if (mCDMDecodesAudio) { - nsRefPtr decoder(new EMEAACDecoder(mProxy, - aConfig, - aAudioTaskQueue, - aCallback)); + nsRefPtr decoder(new EMEAudioDecoder(mProxy, + aConfig, + aAudioTaskQueue, + aCallback)); return decoder.forget(); } - nsRefPtr decoder(mPDM->CreateAACDecoder(aConfig, - aAudioTaskQueue, - aCallback)); + nsRefPtr decoder(mPDM->CreateAudioDecoder(aConfig, + aAudioTaskQueue, + aCallback)); if (!decoder) { return nullptr; } diff --git a/content/media/fmp4/eme/EMEDecoderModule.h b/content/media/fmp4/eme/EMEDecoderModule.h index afe0212f35b..89ec4597ec9 100644 --- a/content/media/fmp4/eme/EMEDecoderModule.h +++ b/content/media/fmp4/eme/EMEDecoderModule.h @@ -42,9 +42,9 @@ public: // Decode thread. virtual already_AddRefed - 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 mProxy; diff --git a/content/media/fmp4/eme/moz.build b/content/media/fmp4/eme/moz.build index d22505cf61f..19f484899fa 100644 --- a/content/media/fmp4/eme/moz.build +++ b/content/media/fmp4/eme/moz.build @@ -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', ] diff --git a/content/media/fmp4/ffmpeg/FFmpegAACDecoder.cpp b/content/media/fmp4/ffmpeg/FFmpegAudioDecoder.cpp similarity index 54% rename from content/media/fmp4/ffmpeg/FFmpegAACDecoder.cpp rename to content/media/fmp4/ffmpeg/FFmpegAudioDecoder.cpp index 4c224b5583e..fcac1b13144 100644 --- a/content/media/fmp4/ffmpeg/FFmpegAACDecoder.cpp +++ b/content/media/fmp4/ffmpeg/FFmpegAudioDecoder.cpp @@ -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::FFmpegAACDecoder( +FFmpegAudioDecoder::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::Init() +FFmpegAudioDecoder::Init() { nsresult rv = FFmpegDataDecoder::Init(); NS_ENSURE_SUCCESS(rv, rv); @@ -34,24 +35,44 @@ FFmpegAACDecoder::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 audio( - new AudioDataValue[aNumChannels * aNumSamples]); - - AudioDataValue** data = reinterpret_cast(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(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(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(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::DecodePacket(MP4Sample* aSample) +FFmpegAudioDecoder::DecodePacket(MP4Sample* aSample) { AVPacket packet; av_init_packet(&packet); @@ -107,24 +128,38 @@ FFmpegAACDecoder::DecodePacket(MP4Sample* aSample) } nsresult -FFmpegAACDecoder::Input(MP4Sample* aSample) +FFmpegAudioDecoder::Input(MP4Sample* aSample) { mTaskQueue->Dispatch(NS_NewRunnableMethodWithArg >( - this, &FFmpegAACDecoder::DecodePacket, nsAutoPtr(aSample))); + this, &FFmpegAudioDecoder::DecodePacket, nsAutoPtr(aSample))); return NS_OK; } nsresult -FFmpegAACDecoder::Drain() +FFmpegAudioDecoder::Drain() { mCallback->DrainComplete(); return NS_OK; } -FFmpegAACDecoder::~FFmpegAACDecoder() +AVCodecID +FFmpegAudioDecoder::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::~FFmpegAudioDecoder() +{ + MOZ_COUNT_DTOR(FFmpegAudioDecoder); } } // namespace mozilla diff --git a/content/media/fmp4/ffmpeg/FFmpegAACDecoder.h b/content/media/fmp4/ffmpeg/FFmpegAudioDecoder.h similarity index 68% rename from content/media/fmp4/ffmpeg/FFmpegAACDecoder.h rename to content/media/fmp4/ffmpeg/FFmpegAudioDecoder.h index 446a4082f14..9f7bfa6b9ad 100644 --- a/content/media/fmp4/ffmpeg/FFmpegAACDecoder.h +++ b/content/media/fmp4/ffmpeg/FFmpegAudioDecoder.h @@ -13,22 +13,23 @@ namespace mozilla { -template class FFmpegAACDecoder +template class FFmpegAudioDecoder { }; template <> -class FFmpegAACDecoder : public FFmpegDataDecoder +class FFmpegAudioDecoder : public FFmpegDataDecoder { 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); diff --git a/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp b/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp index 1388c880859..89fdc3ec25e 100644 --- a/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp +++ b/content/media/fmp4/ffmpeg/FFmpegDataDecoder.cpp @@ -108,8 +108,10 @@ FFmpegDataDecoder::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; } diff --git a/content/media/fmp4/ffmpeg/FFmpegDecoderModule.h b/content/media/fmp4/ffmpeg/FFmpegDecoderModule.h index b3f9bf9161c..6f54f18fb27 100644 --- a/content/media/fmp4/ffmpeg/FFmpegDecoderModule.h +++ b/content/media/fmp4/ffmpeg/FFmpegDecoderModule.h @@ -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 - 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 decoder = - new FFmpegAACDecoder(aAudioTaskQueue, aCallback, aConfig); + new FFmpegAudioDecoder(aAudioTaskQueue, aCallback, aConfig); return decoder.forget(); } + + virtual bool SupportsAudioMimeType(const char* aMimeType) MOZ_OVERRIDE + { + return FFmpegAudioDecoder::GetCodecId(aMimeType) != AV_CODEC_ID_NONE; + } }; } // namespace mozilla diff --git a/content/media/fmp4/ffmpeg/FFmpegLibs.h b/content/media/fmp4/ffmpeg/FFmpegLibs.h index 22050d58860..aad71552f21 100644 --- a/content/media/fmp4/ffmpeg/FFmpegLibs.h +++ b/content/media/fmp4/ffmpeg/FFmpegLibs.h @@ -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 diff --git a/content/media/fmp4/ffmpeg/libav53/moz.build b/content/media/fmp4/ffmpeg/libav53/moz.build index 25650064b75..d9053cff4a1 100644 --- a/content/media/fmp4/ffmpeg/libav53/moz.build +++ b/content/media/fmp4/ffmpeg/libav53/moz.build @@ -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', diff --git a/content/media/fmp4/ffmpeg/libav54/moz.build b/content/media/fmp4/ffmpeg/libav54/moz.build index 25650064b75..d9053cff4a1 100644 --- a/content/media/fmp4/ffmpeg/libav54/moz.build +++ b/content/media/fmp4/ffmpeg/libav54/moz.build @@ -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', diff --git a/content/media/fmp4/ffmpeg/libav55/moz.build b/content/media/fmp4/ffmpeg/libav55/moz.build index 234f4e24fe0..5d48e219aef 100644 --- a/content/media/fmp4/ffmpeg/libav55/moz.build +++ b/content/media/fmp4/ffmpeg/libav55/moz.build @@ -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', diff --git a/content/media/fmp4/gonk/GonkDecoderModule.cpp b/content/media/fmp4/gonk/GonkDecoderModule.cpp index 022fd303505..d1f739da6e1 100644 --- a/content/media/fmp4/gonk/GonkDecoderModule.cpp +++ b/content/media/fmp4/gonk/GonkDecoderModule.cpp @@ -48,9 +48,9 @@ GonkDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aCon } already_AddRefed -GonkDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, - MediaTaskQueue* aAudioTaskQueue, - MediaDataDecoderCallback* aCallback) +GonkDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aAudioTaskQueue, + MediaDataDecoderCallback* aCallback) { nsRefPtr decoder = new GonkMediaDataDecoder(new GonkAudioDecoderManager(aConfig), aAudioTaskQueue, diff --git a/content/media/fmp4/gonk/GonkDecoderModule.h b/content/media/fmp4/gonk/GonkDecoderModule.h index 95c0e08a4cf..edda66f4d08 100644 --- a/content/media/fmp4/gonk/GonkDecoderModule.h +++ b/content/media/fmp4/gonk/GonkDecoderModule.h @@ -29,9 +29,9 @@ public: // Decode thread. virtual already_AddRefed - 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(); }; diff --git a/content/media/fmp4/wmf/WMFDecoderModule.cpp b/content/media/fmp4/wmf/WMFDecoderModule.cpp index 55d3deb38dd..00f390e2fe2 100644 --- a/content/media/fmp4/wmf/WMFDecoderModule.cpp +++ b/content/media/fmp4/wmf/WMFDecoderModule.cpp @@ -81,9 +81,9 @@ WMFDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConf } already_AddRefed -WMFDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, - MediaTaskQueue* aAudioTaskQueue, - MediaDataDecoderCallback* aCallback) +WMFDecoderModule::CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aAudioTaskQueue, + MediaDataDecoderCallback* aCallback) { nsRefPtr decoder = new WMFMediaDataDecoder(new WMFAudioMFTManager(aConfig), diff --git a/content/media/fmp4/wmf/WMFDecoderModule.h b/content/media/fmp4/wmf/WMFDecoderModule.h index d92d1281b41..b2f2b58e79e 100644 --- a/content/media/fmp4/wmf/WMFDecoderModule.h +++ b/content/media/fmp4/wmf/WMFDecoderModule.h @@ -30,9 +30,9 @@ public: MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE; virtual already_AddRefed - 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(); diff --git a/media/libstagefright/binding/DecoderData.cpp b/media/libstagefright/binding/DecoderData.cpp index 32c1d5e1cef..69673d4cea7 100644 --- a/media/libstagefright/binding/DecoderData.cpp +++ b/media/libstagefright/binding/DecoderData.cpp @@ -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 diff --git a/media/libstagefright/binding/mp4_demuxer.cpp b/media/libstagefright/binding/mp4_demuxer.cpp index 5daf7dd75bf..c7200909441 100644 --- a/media/libstagefright/binding/mp4_demuxer.cpp +++ b/media/libstagefright/binding/mp4_demuxer.cpp @@ -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(); diff --git a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp index e5038812f8d..a8eff237d03 100644 --- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp @@ -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; From 9a0ee87e8d5df7084cb2b991f82e78b69c73ffd7 Mon Sep 17 00:00:00 2001 From: Yuan Xulei Date: Mon, 18 Aug 2014 12:00:06 +0800 Subject: [PATCH 09/17] Bug 1043843 - Avoid accessing nsIDOMBlob from worker thread. r=dhylands --HG-- extra : rebase_source : e5199d8023a59d19546c5d1739ac59cb78caf322 --- dom/filesystem/CreateFileTask.cpp | 25 ++++++++++++++++--------- dom/filesystem/CreateFileTask.h | 3 +++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/dom/filesystem/CreateFileTask.cpp b/dom/filesystem/CreateFileTask.cpp index 0b366902cc9..2f3ef2479e8 100644 --- a/dom/filesystem/CreateFileTask.cpp +++ b/dom/filesystem/CreateFileTask.cpp @@ -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 globalObject = @@ -74,16 +77,17 @@ CreateFileTask::CreateFileTask(FileSystemBase* aFileSystem, } BlobParent* bp = static_cast(static_cast(data)); - mBlobData = bp->GetBlob(); - MOZ_ASSERT(mBlobData, "mBlobData should not be null."); - nsresult rv = mBlobData->GetInternalStream(getter_AddRefs(mBlobStream)); + nsCOMPtr 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 file = new DOMFile(mTargetFileImpl); mPromise->MaybeResolve(file); mPromise = nullptr; + mBlobData = nullptr; } void diff --git a/dom/filesystem/CreateFileTask.h b/dom/filesystem/CreateFileTask.h index bbba9b94022..b187c871730 100644 --- a/dom/filesystem/CreateFileTask.h +++ b/dom/filesystem/CreateFileTask.h @@ -66,7 +66,10 @@ private: static uint32_t sOutputBufferSize; nsRefPtr mPromise; nsString mTargetRealPath; + + // Not thread-safe and should be released on main thread. nsCOMPtr mBlobData; + nsCOMPtr mBlobStream; InfallibleTArray mArrayData; bool mReplace; From 506ed304e6298a100d99e293ed2779d4f2978071 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Mon, 18 Aug 2014 18:09:19 +1000 Subject: [PATCH 10/17] Bug 1045591 - Fix media element's autoplay for audio-only stream. r=cpearce --HG-- extra : rebase_source : 6aa73fd12d362a5eabe6362f8b9c86b41f959f5d --- content/media/MediaDecoderStateMachine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/media/MediaDecoderStateMachine.cpp b/content/media/MediaDecoderStateMachine.cpp index f69cf4ae32f..d34b52d8ee8 100644 --- a/content/media/MediaDecoderStateMachine.cpp +++ b/content/media/MediaDecoderStateMachine.cpp @@ -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() { From 4132506134e7202f89fca446fd37bf24a6bbb6e7 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 11 Aug 2014 18:31:24 +0200 Subject: [PATCH 11/17] Bug 1051987 - By default, hide the disabled commands. They are eating the display for no value. $ ./mach -v help bring them back. r=jmaher From 7c2de97792113d3415acf2cfa1591fa05c5b07a8 Mon Sep 17 00:00:00 2001 display for no value. $ ./mach -v help bring them back. --- build/mach_bootstrap.py | 2 +- python/mach/mach/dispatcher.py | 14 +++++++------- python/mach/mach/main.py | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) --- build/mach_bootstrap.py | 2 +- python/mach/mach/dispatcher.py | 14 +++++++------- python/mach/mach/main.py | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/build/mach_bootstrap.py b/build/mach_bootstrap.py index b19401ee4e3..8066cc29bfd 100644 --- a/build/mach_bootstrap.py +++ b/build/mach_bootstrap.py @@ -119,7 +119,7 @@ CATEGORIES = { }, 'disabled': { 'short': 'Disabled', - 'long': 'These commands are unavailable for your current context, run "mach " 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 " to see why.', 'priority': 0, } } diff --git a/python/mach/mach/dispatcher.py b/python/mach/mach/dispatcher.py index f28043d318b..da9662259fb 100644 --- a/python/mach/mach/dispatcher.py +++ b/python/mach/mach/dispatcher.py @@ -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() diff --git a/python/mach/mach/main.py b/python/mach/mach/main.py index 97ebdeb3137..26e14dea3a7 100644 --- a/python/mach/mach/main.py +++ b/python/mach/mach/main.py @@ -595,6 +595,9 @@ To see more help for a specific command, run: action='store_true', default=False, help='Do not prefix log lines with times. By default, mach will ' 'prefix each output line with the time since command start.') + global_group.add_argument('--show-disabled', dest='show_disabled', + action='store_true', default=False, + help='Hide the display of disabled options.') global_group.add_argument('-h', '--help', dest='help', action='store_true', default=False, help='Show this help message.') From 5cf3fe66c513347d1ed178986c76045045b06625 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 18 Aug 2014 15:33:51 +0200 Subject: [PATCH 12/17] Bug 1051987 - Remove useless option which wasn't supposed to go in the commit --HG-- extra : amend_source : 83ccc90a5ee1b0a41640d2b1451208add8dc2c5d --- python/mach/mach/main.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/python/mach/mach/main.py b/python/mach/mach/main.py index 26e14dea3a7..97ebdeb3137 100644 --- a/python/mach/mach/main.py +++ b/python/mach/mach/main.py @@ -595,9 +595,6 @@ To see more help for a specific command, run: action='store_true', default=False, help='Do not prefix log lines with times. By default, mach will ' 'prefix each output line with the time since command start.') - global_group.add_argument('--show-disabled', dest='show_disabled', - action='store_true', default=False, - help='Hide the display of disabled options.') global_group.add_argument('-h', '--help', dest='help', action='store_true', default=False, help='Show this help message.') From 36090c9d4b496ec3742892bab279181c7e0196c3 Mon Sep 17 00:00:00 2001 From: Gian-Carlo Pascutto Date: Mon, 18 Aug 2014 14:06:01 +0200 Subject: [PATCH 13/17] Bug 929431 - Improve matching of camera capabilities to WebRTC restraints. r=jesup --- .../media/webrtc/MediaEngineWebRTCVideo.cpp | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/content/media/webrtc/MediaEngineWebRTCVideo.cpp b/content/media/webrtc/MediaEngineWebRTCVideo.cpp index 4e0ca21096e..738b9bb9f51 100644 --- a/content/media/webrtc/MediaEngineWebRTCVideo.cpp +++ b/content/media/webrtc/MediaEngineWebRTCVideo.cpp @@ -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 } From 67c25804555183d998e0fc19f09d857796b68e7f Mon Sep 17 00:00:00 2001 From: Gian-Carlo Pascutto Date: Mon, 18 Aug 2014 14:06:01 +0200 Subject: [PATCH 14/17] Bug 929431 - Remove spurious newlines from the logging. r=jesup --- .../webrtc/modules/video_capture/windows/sink_filter_ds.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/windows/sink_filter_ds.cc b/media/webrtc/trunk/webrtc/modules/video_capture/windows/sink_filter_ds.cc index d305f5d3a74..ef982b28904 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/windows/sink_filter_ds.cc +++ b/media/webrtc/trunk/webrtc/modules/video_capture/windows/sink_filter_ds.cc @@ -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); From 4ddc2a5161039e8b6fe5eb8955de40d5df5e2fe5 Mon Sep 17 00:00:00 2001 From: Gian-Carlo Pascutto Date: Mon, 18 Aug 2014 14:06:02 +0200 Subject: [PATCH 15/17] Bug 929431 - Don't reinitialize DirectShow if it's not actually needed. r=jesup --- .../video_capture/windows/video_capture_ds.cc | 39 ++++++++++++------- .../video_capture/windows/video_capture_ds.h | 8 +++- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.cc b/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.cc index 047d9efc408..9bae75b37de 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.cc +++ b/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.cc @@ -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; diff --git a/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.h b/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.h index 1f6193dc32b..ab4f69157bc 100644 --- a/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.h +++ b/media/webrtc/trunk/webrtc/modules/video_capture/windows/video_capture_ds.h @@ -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; From bb35753e9670e2f2f16ee971192562370b44bed3 Mon Sep 17 00:00:00 2001 From: Michal Novotny Date: Mon, 18 Aug 2014 15:36:27 +0200 Subject: [PATCH 16/17] Bug 1042192 - Use Cache2 I/O thread for callbacks from CacheFileIOManager, r=sworkman --- netwerk/cache2/CacheFile.cpp | 24 +- netwerk/cache2/CacheFileChunk.cpp | 11 +- netwerk/cache2/CacheFileIOManager.cpp | 290 +++++++----------- netwerk/cache2/CacheFileIOManager.h | 5 +- netwerk/cache2/CacheFileInputStream.cpp | 10 +- netwerk/cache2/CacheFileMetadata.cpp | 4 +- netwerk/cache2/CacheFileOutputStream.cpp | 10 +- netwerk/cache2/CacheIndex.cpp | 12 +- netwerk/cache2/CacheStorageService.cpp | 39 ++- netwerk/test/unit/test_cache2-05-visit.js | 42 ++- .../unit/test_cache2-23-read-over-chunk.js | 10 +- 11 files changed, 223 insertions(+), 234 deletions(-) diff --git a/netwerk/cache2/CacheFile.cpp b/netwerk/cache2/CacheFile.cpp index a5766fb6045..4b99363e43e 100644 --- a/netwerk/cache2/CacheFile.cpp +++ b/netwerk/cache2/CacheFile.cpp @@ -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 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; diff --git a/netwerk/cache2/CacheFileChunk.cpp b/netwerk/cache2/CacheFileChunk.cpp index cb5b3858241..ede21b407e4 100644 --- a/netwerk/cache2/CacheFileChunk.cpp +++ b/netwerk/cache2/CacheFileChunk.cpp @@ -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); diff --git a/netwerk/cache2/CacheFileIOManager.cpp b/netwerk/cache2/CacheFileIOManager.cpp index 8aee3b27e7d..8ff79a6405c 100644 --- a/netwerk/cache2/CacheFileIOManager.cpp +++ b/netwerk/cache2/CacheFileIOManager.cpp @@ -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(NS_GetCurrentThread()); - MOZ_ASSERT(mTarget); - } - mIOMan = CacheFileIOManager::gInstance; MOZ_EVENT_TRACER_NAME_OBJECT(static_cast(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(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(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(this), "net::cache::open-background"); - - MOZ_EVENT_TRACER_WAIT(static_cast(this), "net::cache::open-result"); - - if (mTarget) { - nsCOMPtr target; - mTarget.swap(target); - return target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL); - } } + MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::open-background"); - if (!mTarget) { - MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::open-result"); - mCallback->OnFileOpened(mHandle, mRV); - MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::open-result"); - } + MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::open-result"); + mCallback->OnFileOpened(mHandle, rv); + MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::open-result"); return NS_OK; } @@ -635,33 +611,24 @@ public: protected: SHA1Sum::Hash mHash; uint32_t mFlags; - bool mResultOnAnyThread; nsCOMPtr mCallback; - nsCOMPtr mTarget; nsRefPtr mIOMan; nsRefPtr 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(NS_GetCurrentThread()); - } - MOZ_EVENT_TRACER_NAME_OBJECT(static_cast(this), aHandle->Key().get()); MOZ_EVENT_TRACER_WAIT(static_cast(this), "net::cache::read-background"); } @@ -675,30 +642,20 @@ protected: public: NS_IMETHOD Run() { - if (mResultOnAnyThread || mTarget) { - MOZ_EVENT_TRACER_EXEC(static_cast(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(this), "net::cache::read-background"); + nsresult rv; - MOZ_EVENT_TRACER_WAIT(static_cast(this), "net::cache::read-result"); - - if (mTarget) { - nsCOMPtr target; - mTarget.swap(target); - return target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL); - } + MOZ_EVENT_TRACER_EXEC(static_cast(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(this), "net::cache::read-background"); - if (!mTarget && mCallback) { - MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::read-result"); - mCallback->OnDataRead(mHandle, mBuf, mRV); - MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::read-result"); - } + MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::read-result"); + mCallback->OnDataRead(mHandle, mBuf, rv); + MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::read-result"); return NS_OK; } @@ -708,10 +665,7 @@ protected: int64_t mOffset; char *mBuf; int32_t mCount; - bool mResultOnAnyThread; nsCOMPtr mCallback; - nsCOMPtr 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(NS_GetCurrentThread()); MOZ_EVENT_TRACER_NAME_OBJECT(static_cast(this), aHandle->Key().get()); MOZ_EVENT_TRACER_WAIT(static_cast(this), "net::cache::write-background"); @@ -746,30 +698,26 @@ protected: public: NS_IMETHOD Run() { - if (mTarget) { - MOZ_EVENT_TRACER_EXEC(static_cast(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(this), "net::cache::write-background"); + nsresult rv; - MOZ_EVENT_TRACER_WAIT(static_cast(this), "net::cache::write-result"); - nsCOMPtr target; - mTarget.swap(target); - target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL); + MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::write-background"); + if (mHandle->IsClosed()) { + rv = NS_ERROR_NOT_INITIALIZED; } else { - MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::write-result"); - if (mCallback) { - mCallback->OnDataWritten(mHandle, mBuf, mRV); - } else { - free(const_cast(mBuf)); - mBuf = nullptr; - } - MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::write-result"); + rv = CacheFileIOManager::gInstance->WriteInternal( + mHandle, mOffset, mBuf, mCount, mValidate); } + MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::write-background"); + + MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::write-result"); + if (mCallback) { + mCallback->OnDataWritten(mHandle, mBuf, rv); + } else { + free(const_cast(mBuf)); + mBuf = nullptr; + } + MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::write-result"); + return NS_OK; } @@ -780,8 +728,6 @@ protected: int32_t mCount; bool mValidate; nsCOMPtr mCallback; - nsCOMPtr 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(NS_GetCurrentThread()); MOZ_EVENT_TRACER_NAME_OBJECT(static_cast(this), aHandle->Key().get()); MOZ_EVENT_TRACER_WAIT(static_cast(this), "net::cache::doom-background"); @@ -808,26 +752,22 @@ protected: public: NS_IMETHOD Run() { - if (mTarget) { - MOZ_EVENT_TRACER_EXEC(static_cast(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(this), "net::cache::doom-background"); + nsresult rv; - MOZ_EVENT_TRACER_WAIT(static_cast(this), "net::cache::doom-result"); - nsCOMPtr target; - mTarget.swap(target); - target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL); + MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::doom-background"); + if (mHandle->IsClosed()) { + rv = NS_ERROR_NOT_INITIALIZED; } else { - MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::doom-result"); - if (mCallback) { - mCallback->OnFileDoomed(mHandle, mRV); - } - MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::doom-result"); + rv = CacheFileIOManager::gInstance->DoomFileInternal(mHandle); } + MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::doom-background"); + + MOZ_EVENT_TRACER_EXEC(static_cast(this), "net::cache::doom-result"); + if (mCallback) { + mCallback->OnFileDoomed(mHandle, rv); + } + MOZ_EVENT_TRACER_DONE(static_cast(this), "net::cache::doom-result"); + return NS_OK; } @@ -835,7 +775,6 @@ protected: nsCOMPtr mCallback; nsCOMPtr mTarget; nsRefPtr 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(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 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 mCallback; - nsCOMPtr mTarget; nsRefPtr 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(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 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 mCallback; - nsCOMPtr 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(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 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 mHandle; nsCString mNewName; nsCOMPtr mCallback; - nsCOMPtr 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 ev = new OpenFileEvent(aKey, aFlags, aResultOnAnyThread, aCallback); + nsRefPtr 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 ev = new ReadEvent(aHandle, aOffset, aBuf, aCount, - aResultOnAnyThread, aCallback); + aCallback); rv = ioMan->mIOThread->Dispatch(ev, aHandle->IsPriority() ? CacheIOThread::READ_PRIORITY : CacheIOThread::READ); diff --git a/netwerk/cache2/CacheFileIOManager.h b/netwerk/cache2/CacheFileIOManager.h index 2ca76ec9497..d44048db221 100644 --- a/netwerk/cache2/CacheFileIOManager.h +++ b/netwerk/cache2/CacheFileIOManager.h @@ -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, diff --git a/netwerk/cache2/CacheFileInputStream.cpp b/netwerk/cache2/CacheFileInputStream.cpp index 4c3cfd8d4cf..20e6e58b31d 100644 --- a/netwerk/cache2/CacheFileInputStream.cpp +++ b/netwerk/cache2/CacheFileInputStream.cpp @@ -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 asyncCallback = NS_NewInputStreamReadyEvent(mCallback, mCallbackTarget); diff --git a/netwerk/cache2/CacheFileMetadata.cpp b/netwerk/cache2/CacheFileMetadata.cpp index 624bdb7b08b..e8d2266c472 100644 --- a/netwerk/cache2/CacheFileMetadata.cpp +++ b/netwerk/cache2/CacheFileMetadata.cpp @@ -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, " diff --git a/netwerk/cache2/CacheFileOutputStream.cpp b/netwerk/cache2/CacheFileOutputStream.cpp index 048a21fe324..802259549f5 100644 --- a/netwerk/cache2/CacheFileOutputStream.cpp +++ b/netwerk/cache2/CacheFileOutputStream.cpp @@ -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 asyncCallback = NS_NewOutputStreamReadyEvent(mCallback, mCallbackTarget); diff --git a/netwerk/cache2/CacheIndex.cpp b/netwerk/cache2/CacheIndex.cpp index cc5d405794e..b1bc6c00636 100644 --- a/netwerk/cache2/CacheIndex.cpp +++ b/netwerk/cache2/CacheIndex.cpp @@ -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(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(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)); diff --git a/netwerk/cache2/CacheStorageService.cpp b/netwerk/cache2/CacheStorageService.cpp index d070feae35c..d67bd8554a0 100644 --- a/netwerk/cache2/CacheStorageService.cpp +++ b/netwerk/cache2/CacheStorageService.cpp @@ -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 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 mCallback; + }; + + if (aCallback) { + nsRefPtr callback = new Callback(aCallback); + return NS_DispatchToMainThread(callback); + } return NS_OK; } @@ -1700,7 +1729,7 @@ CacheStorageService::DoomStorageEntries(nsCSubstring const& aContextKey, if (aCallback) { nsRefPtr callback = new Callback(aCallback); - return NS_DispatchToCurrentThread(callback); + return NS_DispatchToMainThread(callback); } return NS_OK; diff --git a/netwerk/test/unit/test_cache2-05-visit.js b/netwerk/test/unit/test_cache2-05-visit.js index 733e0861815..55016227101 100644 --- a/netwerk/test/unit/test_cache2-05-visit.js +++ b/netwerk/test/unit/test_cache2-05-visit.js @@ -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()); diff --git a/netwerk/test/unit/test_cache2-23-read-over-chunk.js b/netwerk/test/unit/test_cache2-23-read-over-chunk.js index e48f34556e8..e74d5e97c73 100644 --- a/netwerk/test/unit/test_cache2-23-read-over-chunk.js +++ b/netwerk/test/unit/test_cache2-23-read-over-chunk.js @@ -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(); + }); }) ); From bd13535bf2ac503f0ba57a33ee1d129389110e78 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Mon, 18 Aug 2014 09:53:43 -0400 Subject: [PATCH 17/17] Bug 1053605 - Fix the bad implicit constructors in intl/; r=smontagu --- intl/hyphenation/nsHyphenator.h | 2 +- intl/uconv/nsUCSupport.h | 6 +++--- intl/uconv/ucvcn/nsUnicodeToGBK.h | 2 +- intl/unicharutil/util/GreekCasing.h | 3 ++- intl/unicharutil/util/IrishCasing.cpp | 2 +- intl/unicharutil/util/IrishCasing.h | 5 +++-- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/intl/hyphenation/nsHyphenator.h b/intl/hyphenation/nsHyphenator.h index 0bfd5c6f645..37b5613da94 100644 --- a/intl/hyphenation/nsHyphenator.h +++ b/intl/hyphenation/nsHyphenator.h @@ -15,7 +15,7 @@ class nsIURI; class nsHyphenator { public: - nsHyphenator(nsIURI *aURI); + explicit nsHyphenator(nsIURI *aURI); NS_INLINE_DECL_REFCOUNTING(nsHyphenator) diff --git a/intl/uconv/nsUCSupport.h b/intl/uconv/nsUCSupport.h index ba276190899..a144d94c6bf 100644 --- a/intl/uconv/nsUCSupport.h +++ b/intl/uconv/nsUCSupport.h @@ -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. diff --git a/intl/uconv/ucvcn/nsUnicodeToGBK.h b/intl/uconv/ucvcn/nsUnicodeToGBK.h index dc18f81efde..4633ce3baff 100644 --- a/intl/uconv/ucvcn/nsUnicodeToGBK.h +++ b/intl/uconv/ucvcn/nsUnicodeToGBK.h @@ -28,7 +28,7 @@ public: /** * Class constructor. */ - nsUnicodeToGBK(uint32_t aMaxLengthFactor = 2); + explicit nsUnicodeToGBK(uint32_t aMaxLengthFactor = 2); virtual ~nsUnicodeToGBK() {} protected: diff --git a/intl/unicharutil/util/GreekCasing.h b/intl/unicharutil/util/GreekCasing.h index 5a25c789849..3291908b5be 100644 --- a/intl/unicharutil/util/GreekCasing.h +++ b/intl/unicharutil/util/GreekCasing.h @@ -7,6 +7,7 @@ #define GreekCasing_h_ #include +#include "mozilla/Attributes.h" namespace mozilla { @@ -45,7 +46,7 @@ public: { } - State(const GreekStates& aState) + MOZ_IMPLICIT State(const GreekStates& aState) : mState(aState) { } diff --git a/intl/unicharutil/util/IrishCasing.cpp b/intl/unicharutil/util/IrishCasing.cpp index 17407cc38ca..20662ea2d72 100644 --- a/intl/unicharutil/util/IrishCasing.cpp +++ b/intl/unicharutil/util/IrishCasing.cpp @@ -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); } diff --git a/intl/unicharutil/util/IrishCasing.h b/intl/unicharutil/util/IrishCasing.h index 9c95c4d8328..f5cb888dc81 100644 --- a/intl/unicharutil/util/IrishCasing.h +++ b/intl/unicharutil/util/IrishCasing.h @@ -7,6 +7,7 @@ #define IrishCasing_h_ #include +#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)) { }