| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/mojo/clients/mojo_video_decoder.h" | 5 #include "media/mojo/clients/mojo_video_decoder.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
| 13 #include "media/base/decoder_buffer.h" | 13 #include "media/base/decoder_buffer.h" |
| 14 #include "media/base/demuxer_stream.h" |
| 14 #include "media/base/video_frame.h" | 15 #include "media/base/video_frame.h" |
| 15 #include "media/mojo/common/media_type_converters.h" | 16 #include "media/mojo/common/media_type_converters.h" |
| 17 #include "media/mojo/common/mojo_decoder_buffer_converter.h" |
| 16 | 18 |
| 17 namespace media { | 19 namespace media { |
| 18 | 20 |
| 19 MojoVideoDecoder::MojoVideoDecoder( | 21 MojoVideoDecoder::MojoVideoDecoder( |
| 20 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 22 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 21 GpuVideoAcceleratorFactories* gpu_factories, | 23 GpuVideoAcceleratorFactories* gpu_factories, |
| 22 mojom::VideoDecoderPtr remote_decoder) | 24 mojom::VideoDecoderPtr remote_decoder) |
| 23 : task_runner_(task_runner), | 25 : task_runner_(task_runner), |
| 24 gpu_factories_(gpu_factories), | 26 gpu_factories_(gpu_factories), |
| 25 remote_decoder_info_(remote_decoder.PassInterface()), | 27 remote_decoder_info_(remote_decoder.PassInterface()), |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 const DecodeCB& decode_cb) { | 74 const DecodeCB& decode_cb) { |
| 73 DVLOG(1) << __FUNCTION__; | 75 DVLOG(1) << __FUNCTION__; |
| 74 DCHECK(task_runner_->BelongsToCurrentThread()); | 76 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 75 | 77 |
| 76 if (has_connection_error_) { | 78 if (has_connection_error_) { |
| 77 task_runner_->PostTask(FROM_HERE, | 79 task_runner_->PostTask(FROM_HERE, |
| 78 base::Bind(decode_cb, DecodeStatus::DECODE_ERROR)); | 80 base::Bind(decode_cb, DecodeStatus::DECODE_ERROR)); |
| 79 return; | 81 return; |
| 80 } | 82 } |
| 81 | 83 |
| 82 mojom::DecoderBufferPtr mojo_buffer = mojom::DecoderBuffer::From(buffer); | 84 mojom::DecoderBufferPtr mojo_buffer = |
| 83 | 85 mojo_decoder_buffer_writer_->ConvertDecoderBuffer(buffer); |
| 84 // TODO(sandersd): Destruct cleanly on error. | 86 if (!mojo_buffer) { |
| 85 if (!buffer->end_of_stream()) { | 87 task_runner_->PostTask(FROM_HERE, |
| 86 uint32_t data_size = base::checked_cast<uint32_t>(buffer->data_size()); | 88 base::Bind(decode_cb, DecodeStatus::DECODE_ERROR)); |
| 87 DCHECK_GT(data_size, 0u); | 89 return; |
| 88 uint32_t bytes_written = data_size; | |
| 89 CHECK_EQ(WriteDataRaw(decoder_buffer_pipe_.get(), buffer->data(), | |
| 90 &bytes_written, MOJO_READ_DATA_FLAG_ALL_OR_NONE), | |
| 91 MOJO_RESULT_OK); | |
| 92 CHECK_EQ(bytes_written, data_size); | |
| 93 } | 90 } |
| 94 | 91 |
| 95 // TODO(sandersd): Support more than one decode at a time. | 92 // TODO(sandersd): Support more than one decode at a time. |
| 96 decode_cb_ = decode_cb; | 93 decode_cb_ = decode_cb; |
| 97 remote_decoder_->Decode( | 94 remote_decoder_->Decode( |
| 98 std::move(mojo_buffer), | 95 std::move(mojo_buffer), |
| 99 base::Bind(&MojoVideoDecoder::OnDecodeDone, base::Unretained(this))); | 96 base::Bind(&MojoVideoDecoder::OnDecodeDone, base::Unretained(this))); |
| 100 } | 97 } |
| 101 | 98 |
| 102 void MojoVideoDecoder::OnVideoFrameDecoded(mojom::VideoFramePtr frame) { | 99 void MojoVideoDecoder::OnVideoFrameDecoded(mojom::VideoFramePtr frame) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 } | 144 } |
| 148 | 145 |
| 149 void MojoVideoDecoder::BindRemoteDecoder() { | 146 void MojoVideoDecoder::BindRemoteDecoder() { |
| 150 DVLOG(1) << __FUNCTION__; | 147 DVLOG(1) << __FUNCTION__; |
| 151 DCHECK(task_runner_->BelongsToCurrentThread()); | 148 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 152 DCHECK(!remote_decoder_bound_); | 149 DCHECK(!remote_decoder_bound_); |
| 153 | 150 |
| 154 remote_decoder_.Bind(std::move(remote_decoder_info_)); | 151 remote_decoder_.Bind(std::move(remote_decoder_info_)); |
| 155 remote_decoder_bound_ = true; | 152 remote_decoder_bound_ = true; |
| 156 | 153 |
| 157 if (remote_decoder_.encountered_error()) { | |
| 158 has_connection_error_ = true; | |
| 159 return; | |
| 160 } | |
| 161 | |
| 162 remote_decoder_.set_connection_error_handler( | 154 remote_decoder_.set_connection_error_handler( |
| 163 base::Bind(&MojoVideoDecoder::OnConnectionError, base::Unretained(this))); | 155 base::Bind(&MojoVideoDecoder::OnConnectionError, base::Unretained(this))); |
| 164 | 156 |
| 165 // TODO(sandersd): Better buffer sizing. | 157 // TODO(sandersd): Better buffer sizing. |
| 166 MojoCreateDataPipeOptions options; | 158 mojo::ScopedDataPipeConsumerHandle remote_consumer_handle; |
| 167 options.struct_size = sizeof(options); | 159 mojo_decoder_buffer_writer_ = MojoDecoderBufferWriter::Create( |
| 168 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; | 160 DemuxerStream::VIDEO, &remote_consumer_handle); |
| 169 options.element_num_bytes = 1; | |
| 170 options.capacity_num_bytes = 2 * 1024 * 1024; | |
| 171 mojo::DataPipe decoder_buffer_pipe(options); | |
| 172 | 161 |
| 173 decoder_buffer_pipe_ = std::move(decoder_buffer_pipe.producer_handle); | |
| 174 remote_decoder_->Construct(binding_.CreateInterfacePtrAndBind(), | 162 remote_decoder_->Construct(binding_.CreateInterfacePtrAndBind(), |
| 175 std::move(decoder_buffer_pipe.consumer_handle)); | 163 std::move(remote_consumer_handle)); |
| 176 } | 164 } |
| 177 | 165 |
| 178 void MojoVideoDecoder::OnConnectionError() { | 166 void MojoVideoDecoder::OnConnectionError() { |
| 179 DVLOG(1) << __FUNCTION__; | 167 DVLOG(1) << __FUNCTION__; |
| 180 DCHECK(task_runner_->BelongsToCurrentThread()); | 168 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 181 | 169 |
| 182 has_connection_error_ = true; | 170 has_connection_error_ = true; |
| 183 | 171 |
| 184 // TODO(sandersd): Write a wrapper class (like BindToCurrentLoop) that handles | 172 // TODO(sandersd): Write a wrapper class (like BindToCurrentLoop) that handles |
| 185 // the lifetime of callbacks like this. | 173 // the lifetime of callbacks like this. |
| 186 if (!init_cb_.is_null()) | 174 if (!init_cb_.is_null()) |
| 187 base::ResetAndReturn(&init_cb_).Run(false); | 175 base::ResetAndReturn(&init_cb_).Run(false); |
| 188 // TODO(sandersd): If there is a pending reset, should these be aborted? | 176 // TODO(sandersd): If there is a pending reset, should these be aborted? |
| 189 if (!decode_cb_.is_null()) | 177 if (!decode_cb_.is_null()) |
| 190 base::ResetAndReturn(&decode_cb_).Run(DecodeStatus::DECODE_ERROR); | 178 base::ResetAndReturn(&decode_cb_).Run(DecodeStatus::DECODE_ERROR); |
| 191 if (!reset_cb_.is_null()) | 179 if (!reset_cb_.is_null()) |
| 192 base::ResetAndReturn(&reset_cb_).Run(); | 180 base::ResetAndReturn(&reset_cb_).Run(); |
| 193 } | 181 } |
| 194 | 182 |
| 195 } // namespace media | 183 } // namespace media |
| OLD | NEW |