2014-04-14 11:24:00 +00:00
|
|
|
/* -*- mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2013-09-27 05:22:37 +00:00
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "MediaSourceDecoder.h"
|
|
|
|
|
|
|
|
#include "mozilla/dom/HTMLMediaElement.h"
|
2013-10-05 08:04:39 +00:00
|
|
|
#include "mozilla/dom/TimeRanges.h"
|
2014-08-13 12:22:00 +00:00
|
|
|
#include "MediaDecoderStateMachine.h"
|
2013-10-05 08:04:39 +00:00
|
|
|
#include "MediaSource.h"
|
2014-08-13 12:22:00 +00:00
|
|
|
#include "MediaSourceReader.h"
|
|
|
|
#include "MediaSourceResource.h"
|
2014-07-22 08:20:00 +00:00
|
|
|
|
2013-09-27 05:22:37 +00:00
|
|
|
#ifdef PR_LOGGING
|
2014-08-11 01:21:17 +00:00
|
|
|
extern PRLogModuleInfo* GetMediaSourceLog();
|
|
|
|
extern PRLogModuleInfo* GetMediaSourceAPILog();
|
|
|
|
|
|
|
|
#define MSE_DEBUG(...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, (__VA_ARGS__))
|
|
|
|
#define MSE_DEBUGV(...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG+1, (__VA_ARGS__))
|
|
|
|
#define MSE_API(...) PR_LOG(GetMediaSourceAPILog(), PR_LOG_DEBUG, (__VA_ARGS__))
|
2013-09-27 05:22:37 +00:00
|
|
|
#else
|
2014-03-05 03:35:46 +00:00
|
|
|
#define MSE_DEBUG(...)
|
2014-08-11 01:21:17 +00:00
|
|
|
#define MSE_DEBUGV(...)
|
|
|
|
#define MSE_API(...)
|
2013-09-27 05:22:37 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
2014-08-13 12:22:00 +00:00
|
|
|
class SubBufferDecoder;
|
2013-09-27 05:22:37 +00:00
|
|
|
|
2014-08-18 05:02:26 +00:00
|
|
|
class MediaSourceStateMachine : public MediaDecoderStateMachine
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MediaSourceStateMachine(MediaDecoder* aDecoder,
|
|
|
|
MediaDecoderReader* aReader,
|
|
|
|
bool aRealTime = false)
|
|
|
|
: MediaDecoderStateMachine(aDecoder, aReader, aRealTime)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<SubBufferDecoder> CreateSubDecoder(const nsACString& aType,
|
|
|
|
MediaSourceDecoder* aParentDecoder) {
|
|
|
|
if (!mReader) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
MediaSourceReader* reader = static_cast<MediaSourceReader*>(mReader.get());
|
|
|
|
return reader->CreateSubDecoder(aType, aParentDecoder, mDecodeTaskQueue);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult EnqueueDecoderInitialization() {
|
|
|
|
AssertCurrentThreadInMonitor();
|
|
|
|
if (!mReader) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
RefPtr<nsIRunnable> task =
|
|
|
|
NS_NewRunnableMethod(this, &MediaSourceStateMachine::InitializePendingDecoders);
|
|
|
|
return mDecodeTaskQueue->Dispatch(task);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void InitializePendingDecoders() {
|
|
|
|
if (!mReader) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
MediaSourceReader* reader = static_cast<MediaSourceReader*>(mReader.get());
|
|
|
|
reader->InitializePendingDecoders();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-11-18 04:22:47 +00:00
|
|
|
MediaSourceDecoder::MediaSourceDecoder(dom::HTMLMediaElement* aElement)
|
2013-09-27 05:22:37 +00:00
|
|
|
: mMediaSource(nullptr)
|
|
|
|
{
|
|
|
|
Init(aElement);
|
|
|
|
}
|
|
|
|
|
|
|
|
MediaDecoder*
|
|
|
|
MediaSourceDecoder::Clone()
|
|
|
|
{
|
|
|
|
// TODO: Sort out cloning.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
MediaDecoderStateMachine*
|
|
|
|
MediaSourceDecoder::CreateStateMachine()
|
|
|
|
{
|
2014-08-18 05:02:26 +00:00
|
|
|
return new MediaSourceStateMachine(this, new MediaSourceReader(this, mMediaSource));
|
2013-09-27 05:22:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
MediaSourceDecoder::Load(nsIStreamListener**, MediaDecoder*)
|
|
|
|
{
|
2014-02-17 22:53:51 +00:00
|
|
|
MOZ_ASSERT(!mDecoderStateMachine);
|
|
|
|
mDecoderStateMachine = CreateStateMachine();
|
|
|
|
if (!mDecoderStateMachine) {
|
|
|
|
NS_WARNING("Failed to create state machine!");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2014-08-05 14:55:02 +00:00
|
|
|
|
|
|
|
nsresult rv = mDecoderStateMachine->Init(nullptr);
|
|
|
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
SetStateMachineParameters();
|
|
|
|
|
|
|
|
return rv;
|
2013-09-27 05:22:37 +00:00
|
|
|
}
|
|
|
|
|
2013-10-05 08:04:39 +00:00
|
|
|
nsresult
|
2013-11-18 04:22:47 +00:00
|
|
|
MediaSourceDecoder::GetSeekable(dom::TimeRanges* aSeekable)
|
2013-10-05 08:04:39 +00:00
|
|
|
{
|
|
|
|
double duration = mMediaSource->Duration();
|
|
|
|
if (IsNaN(duration)) {
|
|
|
|
// Return empty range.
|
|
|
|
} else if (duration > 0 && mozilla::IsInfinite(duration)) {
|
2013-11-18 04:22:47 +00:00
|
|
|
nsRefPtr<dom::TimeRanges> bufferedRanges = new dom::TimeRanges();
|
2014-08-11 04:32:21 +00:00
|
|
|
mMediaSource->GetBuffered(bufferedRanges);
|
2014-04-21 13:30:00 +00:00
|
|
|
aSeekable->Add(bufferedRanges->GetStartTime(), bufferedRanges->GetEndTime());
|
2013-10-05 08:04:39 +00:00
|
|
|
} else {
|
|
|
|
aSeekable->Add(0, duration);
|
|
|
|
}
|
2014-08-11 01:21:17 +00:00
|
|
|
MSE_DEBUG("MediaSourceDecoder(%p)::GetSeekable startTime=%f endTime=%f",
|
|
|
|
this, aSeekable->GetStartTime(), aSeekable->GetEndTime());
|
2013-10-05 08:04:39 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2014-04-14 11:24:00 +00:00
|
|
|
/*static*/
|
|
|
|
already_AddRefed<MediaResource>
|
|
|
|
MediaSourceDecoder::CreateResource()
|
|
|
|
{
|
|
|
|
return nsRefPtr<MediaResource>(new MediaSourceResource()).forget();
|
|
|
|
}
|
|
|
|
|
2013-09-27 05:22:37 +00:00
|
|
|
void
|
2013-11-18 04:22:47 +00:00
|
|
|
MediaSourceDecoder::AttachMediaSource(dom::MediaSource* aMediaSource)
|
2013-09-27 05:22:37 +00:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(!mMediaSource && !mDecoderStateMachine);
|
|
|
|
mMediaSource = aMediaSource;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
MediaSourceDecoder::DetachMediaSource()
|
|
|
|
{
|
|
|
|
mMediaSource = nullptr;
|
|
|
|
}
|
|
|
|
|
2014-04-21 13:30:00 +00:00
|
|
|
already_AddRefed<SubBufferDecoder>
|
2013-09-27 05:22:37 +00:00
|
|
|
MediaSourceDecoder::CreateSubDecoder(const nsACString& aType)
|
|
|
|
{
|
2014-08-18 05:02:26 +00:00
|
|
|
if (!mDecoderStateMachine) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
MediaSourceStateMachine* sm = static_cast<MediaSourceStateMachine*>(mDecoderStateMachine.get());
|
|
|
|
return sm->CreateSubDecoder(aType, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
MediaSourceDecoder::EnqueueDecoderInitialization()
|
|
|
|
{
|
|
|
|
if (!mDecoderStateMachine) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
MediaSourceStateMachine* sm = static_cast<MediaSourceStateMachine*>(mDecoderStateMachine.get());
|
|
|
|
return sm->EnqueueDecoderInitialization();
|
2014-04-21 13:30:00 +00:00
|
|
|
}
|
|
|
|
|
2013-09-27 05:22:37 +00:00
|
|
|
} // namespace mozilla
|