| Index: media/mojo/services/mojo_demuxer_service.cc
|
| diff --git a/media/mojo/services/mojo_demuxer_service.cc b/media/mojo/services/mojo_demuxer_service.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d2602f141f77dc8c2b498117624290987e1091d8
|
| --- /dev/null
|
| +++ b/media/mojo/services/mojo_demuxer_service.cc
|
| @@ -0,0 +1,270 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "media/mojo/services/mojo_demuxer_service.h"
|
| +
|
| +#include "base/lazy_instance.h"
|
| +#include "media/base/bind_to_current_loop.h"
|
| +#include "media/base/data_buffer.h"
|
| +#include "media/base/demuxer_factory.h"
|
| +#include "media/base/media_tracks.h"
|
| +#include "media/mojo/common/media_type_converters.h"
|
| +#include "media/mojo/common/mojo_data_buffer_converter.h"
|
| +#include "media/mojo/services/mojo_data_source_adapter.h"
|
| +#include "media/mojo/services/mojo_demuxer_service_context.h"
|
| +
|
| +namespace media {
|
| +
|
| +namespace {
|
| +
|
| +// Manages all Demuxers created by MojoDemuxerService. Can only have one
|
| +// instance per
|
| +// process so use a LazyInstance to ensure this.
|
| +class DemuxerManager {
|
| + public:
|
| + DemuxerManager() {}
|
| + ~DemuxerManager() {}
|
| +
|
| + // Returns the Demuxer associated with |demuxer_id|. Can be called on any
|
| + // thread.
|
| + Demuxer* GetDemuxer(int demuxer_id) {
|
| + base::AutoLock lock(lock_);
|
| + auto iter = demuxer_map_.find(demuxer_id);
|
| + return iter == demuxer_map_.end() ? nullptr : iter->second;
|
| + }
|
| +
|
| + // Registers the |demuxer| for |demuxer_id|.
|
| + void RegisterDemuxer(int demuxer_id, Demuxer* demuxer) {
|
| + base::AutoLock lock(lock_);
|
| + DCHECK(!demuxer_map_.count(demuxer_id));
|
| + demuxer_map_[demuxer_id] = demuxer;
|
| + }
|
| +
|
| + // Unregisters the Demuxer associated with |demuxer_id|.
|
| + void UnregisterDemuxer(int demuxer_id) {
|
| + base::AutoLock lock(lock_);
|
| + DCHECK(demuxer_map_.count(demuxer_id));
|
| + demuxer_map_.erase(demuxer_id);
|
| + }
|
| +
|
| + private:
|
| + // Lock to protect |demuxer_map_|.
|
| + base::Lock lock_;
|
| + std::map<int, Demuxer*> demuxer_map_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DemuxerManager);
|
| +};
|
| +
|
| +base::LazyInstance<DemuxerManager>::Leaky g_demuxer_manager =
|
| + LAZY_INSTANCE_INITIALIZER;
|
| +
|
| +} // namespace
|
| +
|
| +MojoDemuxerService::MojoDemuxerService(
|
| + base::WeakPtr<MojoDemuxerServiceContext> context,
|
| + DemuxerFactory* demuxer_factory)
|
| + : task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
| + context_(context),
|
| + demuxer_factory_(demuxer_factory),
|
| + data_source_(nullptr),
|
| + demuxer_id_(MediaResource::kInvalidRemoteId),
|
| + demuxer_(nullptr),
|
| + source_buffer_(nullptr),
|
| + weak_factory_(this) {
|
| + DCHECK(context_);
|
| + DCHECK(demuxer_factory_);
|
| +}
|
| +
|
| +MojoDemuxerService::~MojoDemuxerService() {
|
| + CHECK(task_runner_->BelongsToCurrentThread());
|
| + if (demuxer_id_ == MediaResource::kInvalidRemoteId)
|
| + return;
|
| +
|
| + g_demuxer_manager.Get().UnregisterDemuxer(demuxer_id_);
|
| +
|
| + if (context_)
|
| + context_->UnregisterDemuxer(demuxer_id_);
|
| +}
|
| +
|
| +media::Demuxer* MojoDemuxerService::GetDemuxerSourceBuffer(
|
| + media::SourceBuffer** source_buffer_out) {
|
| + CHECK(task_runner_->BelongsToCurrentThread());
|
| + DCHECK(source_buffer_out);
|
| +
|
| + *source_buffer_out = source_buffer_;
|
| +
|
| + return demuxer_.get();
|
| +}
|
| +
|
| +media::Demuxer* MojoDemuxerService::GetDemuxer(
|
| + const PipelineStatusCB& demuxer_init_cb) {
|
| + CHECK(task_runner_->BelongsToCurrentThread());
|
| + if (!demuxer_init_cb.is_null())
|
| + demuxer_init_cb_ = demuxer_init_cb;
|
| +
|
| + return demuxer_.get();
|
| +}
|
| +
|
| +void MojoDemuxerService::Initialize(
|
| + mojom::DemuxerClientAssociatedPtrInfo client,
|
| + int32_t demuxer_id,
|
| + media::Demuxer::LoadType load_type,
|
| + mojom::DataSourcePtr mojo_data_source,
|
| + const InitializeCallback& callback) {
|
| + CHECK(task_runner_->BelongsToCurrentThread());
|
| + client_.Bind(std::move(client));
|
| +
|
| + std::unique_ptr<media::Demuxer> demuxer;
|
| +
|
| + if (load_type == media::Demuxer::LoadType::LoadTypeMediaSource) {
|
| + demuxer = demuxer_factory_->CreateDemuxerSourceBuffer(
|
| + base::ThreadTaskRunnerHandle::Get(),
|
| + base::ThreadTaskRunnerHandle::Get(), base::Bind(&base::DoNothing),
|
| + BindToCurrentLoop(
|
| + base::Bind(&MojoDemuxerService::OnEncryptedMediaInitData,
|
| + weak_factory_.GetWeakPtr())),
|
| + &source_buffer_);
|
| + } else if (load_type == media::Demuxer::LoadType::LoadTypeURL) {
|
| + CHECK(mojo_data_source);
|
| + data_source_.reset(new MojoDataSourceAdapter(
|
| + std::move(mojo_data_source),
|
| + base::Bind(&MojoDemuxerService::OnDataSourceReady,
|
| + weak_factory_.GetWeakPtr(), callback)));
|
| + demuxer = demuxer_factory_->CreateDemuxer(
|
| + nullptr, base::ThreadTaskRunnerHandle::Get(), data_source_.get(),
|
| + BindToCurrentLoop(
|
| + base::Bind(&MojoDemuxerService::OnEncryptedMediaInitData,
|
| + weak_factory_.GetWeakPtr())),
|
| + BindToCurrentLoop(base::Bind(&MojoDemuxerService::OnMediaTracksUpdated,
|
| + weak_factory_.GetWeakPtr())));
|
| + }
|
| +
|
| + if (!demuxer) {
|
| + callback.Run(false);
|
| + return;
|
| + }
|
| +
|
| + demuxer_ = std::move(demuxer);
|
| +
|
| + demuxer_id_ = demuxer_id;
|
| + context_->RegisterDemuxer(demuxer_id_, this);
|
| + g_demuxer_manager.Get().RegisterDemuxer(demuxer_id_, demuxer_.get());
|
| +
|
| + if (load_type == media::Demuxer::LoadType::LoadTypeMediaSource) {
|
| + demuxer_->Initialize(this,
|
| + base::Bind(&MojoDemuxerService::OnDemuxerInitialized,
|
| + weak_factory_.GetWeakPtr()),
|
| + false);
|
| + callback.Run(true);
|
| + }
|
| +}
|
| +
|
| +void MojoDemuxerService::OnDataSourceReady(const InitializeCallback& callback) {
|
| + demuxer_->Initialize(this,
|
| + base::Bind(&MojoDemuxerService::OnDemuxerInitialized,
|
| + weak_factory_.GetWeakPtr()),
|
| + false);
|
| + callback.Run(true);
|
| +}
|
| +
|
| +void MojoDemuxerService::OnDemuxerInitialized(PipelineStatus status) {
|
| + demuxer_init_cb_.Run(status);
|
| +}
|
| +
|
| +void MojoDemuxerService::StartWaitingForSeek(base::TimeDelta seek_time) {
|
| + demuxer_->StartWaitingForSeek(seek_time);
|
| +}
|
| +
|
| +void MojoDemuxerService::CancelPendingSeek(base::TimeDelta seek_time) {
|
| + demuxer_->CancelPendingSeek(seek_time);
|
| +}
|
| +
|
| +void MojoDemuxerService::Seek(base::TimeDelta time,
|
| + const SeekCallback& callback) {
|
| + demuxer_->Seek(time, base::Bind(&MojoDemuxerService::OnSeek,
|
| + weak_factory_.GetWeakPtr(), callback));
|
| +}
|
| +
|
| +void MojoDemuxerService::OnSeek(const SeekCallback& callback,
|
| + PipelineStatus status) {
|
| + callback.Run(status);
|
| +}
|
| +
|
| +void MojoDemuxerService::Stop() {
|
| + demuxer_->Stop();
|
| +}
|
| +
|
| +void MojoDemuxerService::AbortPendingReads() {
|
| + demuxer_->AbortPendingReads();
|
| +}
|
| +
|
| +void MojoDemuxerService::GetStartTime(const GetStartTimeCallback& callback) {
|
| + base::TimeDelta start_time = demuxer_->GetStartTime();
|
| + callback.Run(start_time);
|
| +}
|
| +
|
| +void MojoDemuxerService::GetTimelineOffset(
|
| + const GetTimelineOffsetCallback& callback) {
|
| + base::Time timeline_offset = demuxer_->GetTimelineOffset();
|
| + callback.Run(timeline_offset);
|
| +}
|
| +
|
| +void MojoDemuxerService::GetMemoryUsage(
|
| + const GetMemoryUsageCallback& callback) {
|
| + int64_t memory_usage = demuxer_->GetMemoryUsage();
|
| + callback.Run(memory_usage);
|
| +}
|
| +
|
| +void MojoDemuxerService::OnEnabledAudioTracksChanged(
|
| + const std::vector<MediaTrack::Id>& track_ids,
|
| + base::TimeDelta current_time) {
|
| + demuxer_->OnEnabledAudioTracksChanged(track_ids, current_time);
|
| +}
|
| +void MojoDemuxerService::OnSelectedVideoTrackChanged(
|
| + const std::vector<MediaTrack::Id>& track_ids,
|
| + base::TimeDelta current_time) {
|
| + demuxer_->OnSelectedVideoTrackChanged(track_ids, current_time);
|
| +}
|
| +
|
| +void MojoDemuxerService::OnEncryptedMediaInitData(
|
| + EmeInitDataType init_data_type,
|
| + const std::vector<uint8_t>& init_data) {
|
| + CHECK(task_runner_->BelongsToCurrentThread());
|
| + client_->OnEncryptedMediaInitData(init_data_type, init_data);
|
| +}
|
| +
|
| +void MojoDemuxerService::OnMediaTracksUpdated(
|
| + std::unique_ptr<MediaTracks> tracks) {
|
| + CHECK(task_runner_->BelongsToCurrentThread());
|
| + mojom::MediaTracksPtr mojo_tracks = mojom::MediaTracks::From(*tracks.get());
|
| + client_->OnMediaTracksUpdated(std::move(mojo_tracks));
|
| +}
|
| +
|
| +void MojoDemuxerService::OnBufferedTimeRangesChanged(
|
| + const Ranges<base::TimeDelta>& ranges) {
|
| + CHECK(task_runner_->BelongsToCurrentThread());
|
| + mojom::RangesTimeDeltaPtr mojo_ranges = mojom::RangesTimeDelta::From(ranges);
|
| + client_->OnBufferedTimeRangesChanged(std::move(mojo_ranges));
|
| +}
|
| +
|
| +void MojoDemuxerService::SetDuration(base::TimeDelta duration) {
|
| + CHECK(task_runner_->BelongsToCurrentThread());
|
| + client_->OnSetDuration(duration);
|
| +}
|
| +
|
| +void MojoDemuxerService::OnDemuxerError(PipelineStatus error) {
|
| + CHECK(task_runner_->BelongsToCurrentThread());
|
| + client_->OnDemuxerError(error);
|
| +}
|
| +
|
| +void MojoDemuxerService::AddTextStream(DemuxerStream* text_stream,
|
| + const TextTrackConfig& config) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void MojoDemuxerService::RemoveTextStream(DemuxerStream* text_stream) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +} // namespace media
|
|
|