| // Copyright 2014 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/clients/mojo_demuxer_stream_impl.h" |
| |
| #include <stdint.h> |
| #include <utility> |
| |
| #include "base/bind.h" |
| #include "base/numerics/safe_conversions.h" |
| #include "media/base/audio_decoder_config.h" |
| #include "media/base/decoder_buffer.h" |
| #include "media/base/video_decoder_config.h" |
| #include "media/mojo/common/media_type_converters.h" |
| #include "media/mojo/common/mojo_decoder_buffer_converter.h" |
| |
| namespace media { |
| |
| MojoDemuxerStreamImpl::MojoDemuxerStreamImpl( |
| media::DemuxerStream* stream, |
| mojo::InterfaceRequest<mojom::DemuxerStream> request) |
| : binding_(this, std::move(request)), |
| stream_(stream), |
| weak_factory_(this) {} |
| |
| MojoDemuxerStreamImpl::~MojoDemuxerStreamImpl() {} |
| |
| // This is called when our DemuxerStreamClient has connected itself and is |
| // ready to receive messages. Send an initial config and notify it that |
| // we are now ready for business. |
| void MojoDemuxerStreamImpl::Initialize(const InitializeCallback& callback) { |
| DVLOG(2) << __func__; |
| |
| // Prepare the initial config. |
| mojom::AudioDecoderConfigPtr audio_config; |
| mojom::VideoDecoderConfigPtr video_config; |
| if (stream_->type() == Type::AUDIO) { |
| audio_config = |
| mojom::AudioDecoderConfig::From(stream_->audio_decoder_config()); |
| } else if (stream_->type() == Type::VIDEO) { |
| video_config = |
| mojom::VideoDecoderConfig::From(stream_->video_decoder_config()); |
| } else { |
| NOTREACHED() << "Unsupported stream type: " << stream_->type(); |
| return; |
| } |
| |
| mojo::ScopedDataPipeConsumerHandle remote_consumer_handle; |
| mojo_decoder_buffer_writer_ = |
| MojoDecoderBufferWriter::Create(stream_->type(), &remote_consumer_handle); |
| |
| callback.Run(stream_->type(), std::move(remote_consumer_handle), |
| std::move(audio_config), std::move(video_config)); |
| } |
| |
| void MojoDemuxerStreamImpl::Read(const ReadCallback& callback) { |
| stream_->Read(base::Bind(&MojoDemuxerStreamImpl::OnBufferReady, |
| weak_factory_.GetWeakPtr(), callback)); |
| } |
| |
| void MojoDemuxerStreamImpl::EnableBitstreamConverter() { |
| stream_->EnableBitstreamConverter(); |
| } |
| |
| void MojoDemuxerStreamImpl::OnBufferReady( |
| const ReadCallback& callback, |
| Status status, |
| const scoped_refptr<media::DecoderBuffer>& buffer) { |
| mojom::AudioDecoderConfigPtr audio_config; |
| mojom::VideoDecoderConfigPtr video_config; |
| |
| if (status == Status::kConfigChanged) { |
| DVLOG(2) << __func__ << ": ConfigChange!"; |
| // Send the config change so our client can read it once it parses the |
| // Status obtained via Run() below. |
| if (stream_->type() == Type::AUDIO) { |
| audio_config = |
| mojom::AudioDecoderConfig::From(stream_->audio_decoder_config()); |
| } else if (stream_->type() == Type::VIDEO) { |
| video_config = |
| mojom::VideoDecoderConfig::From(stream_->video_decoder_config()); |
| } else { |
| NOTREACHED() << "Unsupported config change encountered for type: " |
| << stream_->type(); |
| } |
| |
| callback.Run(Status::kConfigChanged, mojom::DecoderBufferPtr(), |
| std::move(audio_config), std::move(video_config)); |
| return; |
| } |
| |
| if (status == Status::kAborted) { |
| callback.Run(Status::kAborted, mojom::DecoderBufferPtr(), |
| std::move(audio_config), std::move(video_config)); |
| return; |
| } |
| |
| DCHECK_EQ(status, Status::kOk); |
| |
| mojom::DecoderBufferPtr mojo_buffer = |
| mojo_decoder_buffer_writer_->WriteDecoderBuffer(buffer); |
| if (!mojo_buffer) { |
| callback.Run(Status::kAborted, mojom::DecoderBufferPtr(), |
| std::move(audio_config), std::move(video_config)); |
| return; |
| } |
| |
| // TODO(dalecurtis): Once we can write framed data to the DataPipe, fill via |
| // the producer handle and then read more to keep the pipe full. Waiting for |
| // space can be accomplished using an AsyncWaiter. |
| callback.Run(status, std::move(mojo_buffer), std::move(audio_config), |
| std::move(video_config)); |
| } |
| |
| } // namespace media |