Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: media/mojo/clients/mojo_audio_decoder.cc

Issue 2096063003: media: Add MojoDecoderBuffer{Reader|Writer} (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments addressed Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/mojo/clients/mojo_audio_decoder.h ('k') | media/mojo/clients/mojo_decryptor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_audio_decoder.h" 5 #include "media/mojo/clients/mojo_audio_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 "base/threading/thread_task_runner_handle.h" 13 #include "base/threading/thread_task_runner_handle.h"
14 #include "media/base/audio_buffer.h" 14 #include "media/base/audio_buffer.h"
15 #include "media/base/cdm_context.h" 15 #include "media/base/cdm_context.h"
16 #include "media/base/demuxer_stream.h"
16 #include "media/mojo/common/media_type_converters.h" 17 #include "media/mojo/common/media_type_converters.h"
18 #include "media/mojo/common/mojo_decoder_buffer_converter.h"
17 19
18 namespace media { 20 namespace media {
19 21
20 MojoAudioDecoder::MojoAudioDecoder( 22 MojoAudioDecoder::MojoAudioDecoder(
21 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 23 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
22 mojom::AudioDecoderPtr remote_decoder) 24 mojom::AudioDecoderPtr remote_decoder)
23 : task_runner_(task_runner), 25 : task_runner_(task_runner),
24 remote_decoder_info_(remote_decoder.PassInterface()), 26 remote_decoder_info_(remote_decoder.PassInterface()),
25 binding_(this), 27 binding_(this),
26 has_connection_error_(false), 28 has_connection_error_(false),
(...skipping 22 matching lines...) Expand all
49 // Fail immediately if the stream is encrypted but |cdm_context| is invalid. 51 // Fail immediately if the stream is encrypted but |cdm_context| is invalid.
50 int cdm_id = (config.is_encrypted() && cdm_context) 52 int cdm_id = (config.is_encrypted() && cdm_context)
51 ? cdm_context->GetCdmId() 53 ? cdm_context->GetCdmId()
52 : CdmContext::kInvalidCdmId; 54 : CdmContext::kInvalidCdmId;
53 55
54 if (config.is_encrypted() && CdmContext::kInvalidCdmId == cdm_id) { 56 if (config.is_encrypted() && CdmContext::kInvalidCdmId == cdm_id) {
55 task_runner_->PostTask(FROM_HERE, base::Bind(init_cb, false)); 57 task_runner_->PostTask(FROM_HERE, base::Bind(init_cb, false));
56 return; 58 return;
57 } 59 }
58 60
59 // If connection error has happened, fail immediately.
60 if (remote_decoder_.encountered_error()) {
61 task_runner_->PostTask(FROM_HERE, base::Bind(init_cb, false));
62 return;
63 }
64
65 // Otherwise, set an error handler to catch the connection error. 61 // Otherwise, set an error handler to catch the connection error.
66 // Using base::Unretained(this) is safe because |this| owns |remote_decoder_|, 62 // Using base::Unretained(this) is safe because |this| owns |remote_decoder_|,
67 // and the error handler can't be invoked once |remote_decoder_| is destroyed. 63 // and the error handler can't be invoked once |remote_decoder_| is destroyed.
68 remote_decoder_.set_connection_error_handler( 64 remote_decoder_.set_connection_error_handler(
69 base::Bind(&MojoAudioDecoder::OnConnectionError, base::Unretained(this))); 65 base::Bind(&MojoAudioDecoder::OnConnectionError, base::Unretained(this)));
70 66
71 init_cb_ = init_cb; 67 init_cb_ = init_cb;
72 output_cb_ = output_cb; 68 output_cb_ = output_cb;
73 69
74 // Using base::Unretained(this) is safe because |this| owns |remote_decoder_|, 70 // Using base::Unretained(this) is safe because |this| owns |remote_decoder_|,
75 // and the callback won't be dispatched if |remote_decoder_| is destroyed. 71 // and the callback won't be dispatched if |remote_decoder_| is destroyed.
76 remote_decoder_->Initialize( 72 remote_decoder_->Initialize(
77 binding_.CreateInterfacePtrAndBind(), 73 binding_.CreateInterfacePtrAndBind(),
78 mojom::AudioDecoderConfig::From(config), cdm_id, 74 mojom::AudioDecoderConfig::From(config), cdm_id,
79 base::Bind(&MojoAudioDecoder::OnInitialized, base::Unretained(this))); 75 base::Bind(&MojoAudioDecoder::OnInitialized, base::Unretained(this)));
80 } 76 }
81 77
82 void MojoAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& media_buffer, 78 void MojoAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& media_buffer,
83 const DecodeCB& decode_cb) { 79 const DecodeCB& decode_cb) {
84 DVLOG(3) << __FUNCTION__; 80 DVLOG(3) << __FUNCTION__;
85 DCHECK(task_runner_->BelongsToCurrentThread()); 81 DCHECK(task_runner_->BelongsToCurrentThread());
86 82
87 if (has_connection_error_) { 83 if (has_connection_error_) {
88 task_runner_->PostTask(FROM_HERE, 84 task_runner_->PostTask(FROM_HERE,
89 base::Bind(decode_cb, DecodeStatus::DECODE_ERROR)); 85 base::Bind(decode_cb, DecodeStatus::DECODE_ERROR));
90 return; 86 return;
91 } 87 }
92 88
93 mojom::DecoderBufferPtr buffer = TransferDecoderBuffer(media_buffer); 89 mojom::DecoderBufferPtr buffer =
90 mojo_decoder_buffer_writer_->WriteDecoderBuffer(media_buffer);
94 if (!buffer) { 91 if (!buffer) {
95 task_runner_->PostTask(FROM_HERE, 92 task_runner_->PostTask(FROM_HERE,
96 base::Bind(decode_cb, DecodeStatus::DECODE_ERROR)); 93 base::Bind(decode_cb, DecodeStatus::DECODE_ERROR));
97 return; 94 return;
98 } 95 }
99 96
100 DCHECK(decode_cb_.is_null()); 97 DCHECK(decode_cb_.is_null());
101 decode_cb_ = decode_cb; 98 decode_cb_ = decode_cb;
102 99
103 remote_decoder_->Decode( 100 remote_decoder_->Decode(
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 base::ResetAndReturn(&reset_cb_).Run(); 154 base::ResetAndReturn(&reset_cb_).Run();
158 } 155 }
159 156
160 void MojoAudioDecoder::OnInitialized(bool success, 157 void MojoAudioDecoder::OnInitialized(bool success,
161 bool needs_bitstream_conversion) { 158 bool needs_bitstream_conversion) {
162 DVLOG(1) << __FUNCTION__ << ": success:" << success; 159 DVLOG(1) << __FUNCTION__ << ": success:" << success;
163 DCHECK(task_runner_->BelongsToCurrentThread()); 160 DCHECK(task_runner_->BelongsToCurrentThread());
164 161
165 needs_bitstream_conversion_ = needs_bitstream_conversion; 162 needs_bitstream_conversion_ = needs_bitstream_conversion;
166 163
167 if (success) 164 if (success) {
168 CreateDataPipe(); 165 mojo::ScopedDataPipeConsumerHandle remote_consumer_handle;
166 mojo_decoder_buffer_writer_ = MojoDecoderBufferWriter::Create(
167 DemuxerStream::AUDIO, &remote_consumer_handle);
168 // Pass consumer end to |remote_decoder_|.
169 remote_decoder_->SetDataSource(std::move(remote_consumer_handle));
170 }
169 171
170 base::ResetAndReturn(&init_cb_).Run(success); 172 base::ResetAndReturn(&init_cb_).Run(success);
171 } 173 }
172 174
173 void MojoAudioDecoder::OnDecodeStatus(mojom::DecodeStatus status) { 175 void MojoAudioDecoder::OnDecodeStatus(mojom::DecodeStatus status) {
174 DVLOG(1) << __FUNCTION__ << ": status:" << status; 176 DVLOG(1) << __FUNCTION__ << ": status:" << status;
175 DCHECK(task_runner_->BelongsToCurrentThread()); 177 DCHECK(task_runner_->BelongsToCurrentThread());
176 178
177 DCHECK(!decode_cb_.is_null()); 179 DCHECK(!decode_cb_.is_null());
178 base::ResetAndReturn(&decode_cb_).Run(static_cast<DecodeStatus>(status)); 180 base::ResetAndReturn(&decode_cb_).Run(static_cast<DecodeStatus>(status));
179 } 181 }
180 182
181 void MojoAudioDecoder::OnResetDone() { 183 void MojoAudioDecoder::OnResetDone() {
182 DVLOG(1) << __FUNCTION__; 184 DVLOG(1) << __FUNCTION__;
183 DCHECK(task_runner_->BelongsToCurrentThread()); 185 DCHECK(task_runner_->BelongsToCurrentThread());
184 186
185 // For pending decodes OnDecodeStatus() should arrive before OnResetDone(). 187 // For pending decodes OnDecodeStatus() should arrive before OnResetDone().
186 DCHECK(decode_cb_.is_null()); 188 DCHECK(decode_cb_.is_null());
187 189
188 DCHECK(!reset_cb_.is_null()); 190 DCHECK(!reset_cb_.is_null());
189 base::ResetAndReturn(&reset_cb_).Run(); 191 base::ResetAndReturn(&reset_cb_).Run();
190 } 192 }
191 193
192 void MojoAudioDecoder::CreateDataPipe() {
193 MojoCreateDataPipeOptions options;
194 options.struct_size = sizeof(MojoCreateDataPipeOptions);
195 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
196 options.element_num_bytes = 1;
197 // TODO(timav): Consider capacity calculation based on AudioDecoderConfig.
198 options.capacity_num_bytes = 512 * 1024;
199
200 mojo::DataPipe write_pipe(options);
201
202 // Keep producer end.
203 producer_handle_ = std::move(write_pipe.producer_handle);
204
205 // Pass consumer end to |remote_decoder_|.
206 remote_decoder_->SetDataSource(std::move(write_pipe.consumer_handle));
207 }
208
209 mojom::DecoderBufferPtr MojoAudioDecoder::TransferDecoderBuffer(
210 const scoped_refptr<DecoderBuffer>& media_buffer) {
211 mojom::DecoderBufferPtr buffer = mojom::DecoderBuffer::From(media_buffer);
212 if (media_buffer->end_of_stream())
213 return buffer;
214
215 // Serialize the data section of the DecoderBuffer into our pipe.
216 uint32_t num_bytes = base::checked_cast<uint32_t>(media_buffer->data_size());
217 DCHECK_GT(num_bytes, 0u);
218 MojoResult result =
219 WriteDataRaw(producer_handle_.get(), media_buffer->data(), &num_bytes,
220 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
221 if (result != MOJO_RESULT_OK || num_bytes != media_buffer->data_size()) {
222 DVLOG(1) << __FUNCTION__ << ": writing to data pipe failed";
223 return nullptr;
224 }
225
226 return buffer;
227 }
228
229 } // namespace media 194 } // namespace media
OLDNEW
« no previous file with comments | « media/mojo/clients/mojo_audio_decoder.h ('k') | media/mojo/clients/mojo_decryptor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698