| Index: media/mojo/common/mojo_decoder_buffer_converter.cc
|
| diff --git a/media/mojo/common/mojo_decoder_buffer_converter.cc b/media/mojo/common/mojo_decoder_buffer_converter.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..01b786967c3a28799ee4100ca6e5ba4b4f69f63c
|
| --- /dev/null
|
| +++ b/media/mojo/common/mojo_decoder_buffer_converter.cc
|
| @@ -0,0 +1,151 @@
|
| +// Copyright 2016 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/common/mojo_decoder_buffer_converter.h"
|
| +
|
| +#include <memory>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/single_thread_task_runner.h"
|
| +#include "base/threading/thread_task_runner_handle.h"
|
| +#include "media/base/audio_buffer.h"
|
| +#include "media/base/cdm_context.h"
|
| +#include "media/base/decoder_buffer.h"
|
| +#include "media/mojo/common/media_type_converters.h"
|
| +
|
| +namespace media {
|
| +
|
| +namespace {
|
| +
|
| +std::unique_ptr<mojo::DataPipe> CreateDataPipe(DemuxerStream::Type type) {
|
| + MojoCreateDataPipeOptions options;
|
| + options.struct_size = sizeof(MojoCreateDataPipeOptions);
|
| + options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
|
| + options.element_num_bytes = 1;
|
| +
|
| + if (type == DemuxerStream::AUDIO) {
|
| + // TODO(timav): Consider capacity calculation based on AudioDecoderConfig.
|
| + options.capacity_num_bytes = 512 * 1024;
|
| + } else if (type == DemuxerStream::VIDEO) {
|
| + // Video can get quite large; at 4K, VP9 delivers packets which are ~1MB in
|
| + // size; so allow for 50% head room.
|
| + options.capacity_num_bytes = 1.5 * (1024 * 1024);
|
| + } else {
|
| + NOTREACHED() << "Unsupported type: " << type;
|
| + // Choose a random size.
|
| + options.capacity_num_bytes = 512 * 1024;
|
| + }
|
| +
|
| + return base::WrapUnique(new mojo::DataPipe(options));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// MojoDecoderBufferReader
|
| +
|
| +// static
|
| +std::unique_ptr<MojoDecoderBufferReader> MojoDecoderBufferReader::Create(
|
| + DemuxerStream::Type type,
|
| + mojo::ScopedDataPipeProducerHandle* producer_handle) {
|
| + DVLOG(1) << __FUNCTION__;
|
| + std::unique_ptr<mojo::DataPipe> data_pipe = CreateDataPipe(type);
|
| + *producer_handle = std::move(data_pipe->producer_handle);
|
| + return base::WrapUnique(
|
| + new MojoDecoderBufferReader(std::move(data_pipe->consumer_handle)));
|
| +}
|
| +
|
| +MojoDecoderBufferReader::MojoDecoderBufferReader(
|
| + mojo::ScopedDataPipeConsumerHandle consumer_handle)
|
| + : consumer_handle_(std::move(consumer_handle)) {
|
| + DVLOG(1) << __FUNCTION__;
|
| +}
|
| +
|
| +MojoDecoderBufferReader::~MojoDecoderBufferReader() {
|
| + DVLOG(1) << __FUNCTION__;
|
| +}
|
| +
|
| +scoped_refptr<DecoderBuffer> MojoDecoderBufferReader::ConvertDecoderBuffer(
|
| + const mojom::DecoderBufferPtr& buffer) {
|
| + DVLOG(3) << __FUNCTION__;
|
| + scoped_refptr<DecoderBuffer> media_buffer(
|
| + buffer.To<scoped_refptr<DecoderBuffer>>());
|
| + DCHECK(media_buffer);
|
| +
|
| + if (media_buffer->end_of_stream())
|
| + return media_buffer;
|
| +
|
| + // Wait for the data to become available in the DataPipe.
|
| + MojoHandleSignalsState state;
|
| + MojoResult result =
|
| + MojoWait(consumer_handle_.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
|
| + MOJO_DEADLINE_INDEFINITE, &state);
|
| +
|
| + if (result != MOJO_RESULT_OK) {
|
| + DVLOG(1) << __FUNCTION__ << ": Peer closed the data pipe";
|
| + return nullptr;
|
| + }
|
| +
|
| + // Read the inner data for the DecoderBuffer from our DataPipe.
|
| + uint32_t data_size = static_cast<uint32_t>(media_buffer->data_size());
|
| + DCHECK_EQ(data_size, buffer->data_size);
|
| + DCHECK_GT(data_size, 0u);
|
| +
|
| + uint32_t bytes_read = data_size;
|
| + result = ReadDataRaw(consumer_handle_.get(), media_buffer->writable_data(),
|
| + &bytes_read, MOJO_READ_DATA_FLAG_ALL_OR_NONE);
|
| + if (result != MOJO_RESULT_OK || bytes_read != data_size) {
|
| + DVLOG(1) << __FUNCTION__ << ": reading from pipe failed";
|
| + return nullptr;
|
| + }
|
| +
|
| + return media_buffer;
|
| +}
|
| +
|
| +// MojoDecoderBufferWriter
|
| +
|
| +// static
|
| +std::unique_ptr<MojoDecoderBufferWriter> MojoDecoderBufferWriter::Create(
|
| + DemuxerStream::Type type,
|
| + mojo::ScopedDataPipeConsumerHandle* consumer_handle) {
|
| + DVLOG(1) << __FUNCTION__;
|
| + std::unique_ptr<mojo::DataPipe> data_pipe = CreateDataPipe(type);
|
| + *consumer_handle = std::move(data_pipe->consumer_handle);
|
| + return base::WrapUnique(
|
| + new MojoDecoderBufferWriter(std::move(data_pipe->producer_handle)));
|
| +}
|
| +
|
| +MojoDecoderBufferWriter::MojoDecoderBufferWriter(
|
| + mojo::ScopedDataPipeProducerHandle producer_handle)
|
| + : producer_handle_(std::move(producer_handle)) {
|
| + DVLOG(1) << __FUNCTION__;
|
| +}
|
| +
|
| +MojoDecoderBufferWriter::~MojoDecoderBufferWriter() {
|
| + DVLOG(1) << __FUNCTION__;
|
| +}
|
| +
|
| +mojom::DecoderBufferPtr MojoDecoderBufferWriter::ConvertDecoderBuffer(
|
| + const scoped_refptr<DecoderBuffer>& media_buffer) {
|
| + DVLOG(3) << __FUNCTION__;
|
| + mojom::DecoderBufferPtr buffer = mojom::DecoderBuffer::From(media_buffer);
|
| +
|
| + if (media_buffer->end_of_stream())
|
| + return buffer;
|
| +
|
| + // Serialize the data section of the DecoderBuffer into our pipe.
|
| + uint32_t num_bytes = base::checked_cast<uint32_t>(media_buffer->data_size());
|
| + DCHECK_GT(num_bytes, 0u);
|
| + MojoResult result =
|
| + WriteDataRaw(producer_handle_.get(), media_buffer->data(), &num_bytes,
|
| + MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
|
| + if (result != MOJO_RESULT_OK || num_bytes != media_buffer->data_size()) {
|
| + DVLOG(1) << __FUNCTION__ << ": writing to data pipe failed";
|
| + return nullptr;
|
| + }
|
| +
|
| + return buffer;
|
| +}
|
| +
|
| +} // namespace media
|
|
|