Bug 1059049 - Pass CDMProxy from MediaSourceDecoder to subreaders - r=cpearce,kinetik

This commit is contained in:
Edwin Flores 2014-10-14 11:05:00 +13:00
Родитель 2cfbd51813
Коммит c547b19a64
11 изменённых файлов: 117 добавлений и 7 удалений

Просмотреть файл

@ -39,6 +39,9 @@ public:
// True if this reader is waiting media resource allocation
virtual bool IsWaitingMediaResources() { return false; }
// True if this reader is waiting for a Content Decryption Module to become
// available.
virtual bool IsWaitingOnCDMResource() { return false; }
// True when this reader need to become dormant state
virtual bool IsDormantNeeded() { return false; }
// Release media resources they should be released in dormant state

Просмотреть файл

@ -92,7 +92,7 @@ private:
bool IsSupportedAudioMimeType(const char* aMimeType);
void NotifyResourcesStatusChanged();
bool IsWaitingOnCodecResource();
bool IsWaitingOnCDMResource();
virtual bool IsWaitingOnCDMResource() MOZ_OVERRIDE;
nsAutoPtr<mp4_demuxer::MP4Demuxer> mDemuxer;
nsAutoPtr<PlatformDecoderModule> mPlatform;

Просмотреть файл

@ -61,6 +61,7 @@ PlatformDecoderModule::Init()
#endif
}
#ifdef MOZ_EME
class CreateTaskQueueTask : public nsRunnable {
public:
NS_IMETHOD Run() {
@ -81,7 +82,6 @@ CreateTaskQueue()
return t->mTaskQueue.forget();
}
#ifdef MOZ_EME
/* static */
PlatformDecoderModule*
PlatformDecoderModule::CreateCDMWrapper(CDMProxy* aProxy,

Просмотреть файл

@ -187,4 +187,17 @@ MediaSourceDecoder::PrepareReaderInitialization()
mReader->PrepareInitialization();
}
#ifdef MOZ_EME
nsresult
MediaSourceDecoder::SetCDMProxy(CDMProxy* aProxy)
{
nsresult rv = MediaDecoder::SetCDMProxy(aProxy);
NS_ENSURE_SUCCESS(rv, rv);
rv = mReader->SetCDMProxy(aProxy);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
#endif
} // namespace mozilla

Просмотреть файл

@ -63,6 +63,10 @@ public:
// registered TrackBuffers essential for initialization.
void PrepareReaderInitialization();
#ifdef MOZ_EME
virtual nsresult SetCDMProxy(CDMProxy* aProxy) MOZ_OVERRIDE;
#endif
private:
// The owning MediaSource holds a strong reference to this decoder, and
// calls Attach/DetachMediaSource on this decoder to set and clear

Просмотреть файл

@ -329,6 +329,9 @@ MediaSourceReader::CreateSubDecoder(const nsACString& aType)
MSE_DEBUG("MediaSourceReader(%p)::CreateSubDecoder subdecoder %p subreader %p",
this, decoder.get(), reader.get());
decoder->SetReader(reader);
#ifdef MOZ_EME
decoder->SetCDMProxy(mCDMProxy);
#endif
return decoder.forget();
}
@ -515,4 +518,20 @@ MediaSourceReader::IsEnded()
return mEnded;
}
#ifdef MOZ_EME
nsresult
MediaSourceReader::SetCDMProxy(CDMProxy* aProxy)
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
mCDMProxy = aProxy;
for (size_t i = 0; i < mTrackBuffers.Length(); i++) {
nsresult rv = mTrackBuffers[i]->SetCDMProxy(aProxy);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
#endif
} // namespace mozilla

Просмотреть файл

@ -101,6 +101,10 @@ public:
// Return true if the Ended method has been called
bool IsEnded();
#ifdef MOZ_EME
nsresult SetCDMProxy(CDMProxy* aProxy);
#endif
private:
bool SwitchAudioReader(int64_t aTarget);
bool SwitchVideoReader(int64_t aTarget);
@ -123,6 +127,10 @@ private:
nsRefPtr<TrackBuffer> mAudioTrack;
nsRefPtr<TrackBuffer> mVideoTrack;
#ifdef MOZ_EME
nsRefPtr<CDMProxy> mCDMProxy;
#endif
// These are read and written on the decode task queue threads.
int64_t mLastAudioTime;
int64_t mLastVideoTime;

Просмотреть файл

@ -11,6 +11,9 @@
#include "MediaDecoderReader.h"
#include "SourceBufferResource.h"
#include "mozilla/Attributes.h"
#ifdef MOZ_EME
#include "mozilla/CDMProxy.h"
#endif
#include "mozilla/ReentrantMonitor.h"
namespace mozilla {
@ -81,6 +84,23 @@ public:
mTaskQueue = aTaskQueue;
}
#ifdef MOZ_EME
virtual nsresult SetCDMProxy(CDMProxy* aProxy)
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
mCDMProxy = aProxy;
return NS_OK;
}
virtual CDMProxy* GetCDMProxy() MOZ_OVERRIDE
{
MOZ_ASSERT(OnDecodeThread() || NS_IsMainThread());
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
return mCDMProxy;
}
#endif
// Given a time convert it into an approximate byte offset from the
// cached data. Returns -1 if no such value is computable.
int64_t ConvertToByteOffset(double aTime);
@ -96,6 +116,10 @@ private:
AbstractMediaDecoder* mParentDecoder;
nsRefPtr<MediaDecoderReader> mReader;
int64_t mMediaDuration;
#ifdef MOZ_EME
nsRefPtr<CDMProxy> mCDMProxy;
#endif
};
} // namespace mozilla

Просмотреть файл

@ -237,6 +237,7 @@ TrackBuffer::NewDecoder()
mLastStartTimestamp = 0;
mLastEndTimestamp = 0;
decoder->SetTaskQueue(mTaskQueue);
return QueueInitializeDecoder(decoder);
}
@ -247,7 +248,6 @@ TrackBuffer::QueueInitializeDecoder(SourceBufferDecoder* aDecoder)
NS_NewRunnableMethodWithArg<SourceBufferDecoder*>(this,
&TrackBuffer::InitializeDecoder,
aDecoder);
aDecoder->SetTaskQueue(mTaskQueue);
if (NS_FAILED(mTaskQueue->Dispatch(task))) {
MSE_DEBUG("MediaSourceReader(%p): Failed to enqueue decoder initialization task", this);
RemoveDecoder(aDecoder);
@ -272,8 +272,16 @@ TrackBuffer::InitializeDecoder(SourceBufferDecoder* aDecoder)
MediaInfo mi;
nsAutoPtr<MetadataTags> tags; // TODO: Handle metadata.
nsresult rv = reader->ReadMetadata(&mi, getter_Transfers(tags));
aDecoder->SetTaskQueue(nullptr);
reader->SetIdle();
if (NS_SUCCEEDED(rv) && reader->IsWaitingOnCDMResource()) {
ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
mWaitingDecoders.AppendElement(aDecoder);
return;
}
aDecoder->SetTaskQueue(nullptr);
if (NS_FAILED(rv) || (!mi.HasVideo() && !mi.HasAudio())) {
// XXX: Need to signal error back to owning SourceBuffer.
MSE_DEBUG("TrackBuffer(%p): Reader %p failed to initialize rv=%x audio=%d video=%d",
@ -415,6 +423,31 @@ TrackBuffer::Decoders()
return mInitializedDecoders;
}
#ifdef MOZ_EME
nsresult
TrackBuffer::SetCDMProxy(CDMProxy* aProxy)
{
ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
nsresult rv = mDecoders[i]->SetCDMProxy(aProxy);
NS_ENSURE_SUCCESS(rv, rv);
}
for (uint32_t i = 0; i < mWaitingDecoders.Length(); ++i) {
CDMCaps::AutoLock caps(aProxy->Capabilites());
caps.CallOnMainThreadWhenCapsAvailable(
NS_NewRunnableMethodWithArg<SourceBufferDecoder*>(this,
&TrackBuffer::QueueInitializeDecoder,
mWaitingDecoders[i]));
}
mWaitingDecoders.Clear();
return NS_OK;
}
#endif
#if defined(DEBUG)
void
TrackBuffer::Dump(const char* aPath)

Просмотреть файл

@ -73,6 +73,10 @@ public:
// TODO: Refactor to a cleaner interface between TrackBuffer and MediaSourceReader.
const nsTArray<nsRefPtr<SourceBufferDecoder>>& Decoders();
#ifdef MOZ_EME
nsresult SetCDMProxy(CDMProxy* aProxy);
#endif
#if defined(DEBUG)
void Dump(const char* aPath);
#endif
@ -127,6 +131,10 @@ private:
// Access protected by mParentDecoder's monitor.
nsTArray<nsRefPtr<SourceBufferDecoder>> mInitializedDecoders;
// Decoders which are waiting on a Content Decryption Module to be able to
// finish ReadMetadata.
nsTArray<nsRefPtr<SourceBufferDecoder>> mWaitingDecoders;
// The decoder that the owning SourceBuffer is currently appending data to.
nsRefPtr<SourceBufferDecoder> mCurrentDecoder;

Просмотреть файл

@ -376,9 +376,6 @@ ClearKeyDecryptor::ClearKeyDecryptor(GMPDecryptorCallback* aCallback,
ClearKeyDecryptor::~ClearKeyDecryptor()
{
CK_LOGD("ClearKeyDecryptor dtor; key ID = %08x...", *(uint32_t*)&mKey[0]);
if (mThread) {
mThread->Join();
}
}
uint32_t
@ -393,6 +390,7 @@ ClearKeyDecryptor::Release()
if (!--mRefCnt) {
if (mThread) {
mThread->Post(new DestroyTask(this));
mThread->Join();
} else {
delete this;
}