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

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

Issue 1823443002: Use data pipe for encoded buffers in MojoAudioDecoder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@spitzer-audio-service-impl
Patch Set: Addressed comments Created 4 years, 9 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
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/services/mojo_audio_decoder.h" 5 #include "media/mojo/services/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/thread_task_runner_handle.h" 13 #include "base/thread_task_runner_handle.h"
14 #include "media/base/audio_buffer.h"
14 #include "media/base/cdm_context.h" 15 #include "media/base/cdm_context.h"
15 #include "media/mojo/common/media_type_converters.h" 16 #include "media/mojo/common/media_type_converters.h"
16 17
17 namespace media { 18 namespace media {
18 19
19 MojoAudioDecoder::MojoAudioDecoder( 20 MojoAudioDecoder::MojoAudioDecoder(
20 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 21 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
21 interfaces::AudioDecoderPtr remote_decoder) 22 interfaces::AudioDecoderPtr remote_decoder)
22 : task_runner_(task_runner), 23 : task_runner_(task_runner),
23 remote_decoder_(std::move(remote_decoder)), 24 remote_decoder_(std::move(remote_decoder)),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 return; 59 return;
59 } 60 }
60 61
61 // Otherwise, set an error handler to catch the connection error. 62 // Otherwise, set an error handler to catch the connection error.
62 // Using base::Unretained(this) is safe because |this| owns |remote_decoder_|, 63 // Using base::Unretained(this) is safe because |this| owns |remote_decoder_|,
63 // and the error handler can't be invoked once |remote_decoder_| is destroyed. 64 // and the error handler can't be invoked once |remote_decoder_| is destroyed.
64 remote_decoder_.set_connection_error_handler( 65 remote_decoder_.set_connection_error_handler(
65 base::Bind(&MojoAudioDecoder::OnConnectionError, base::Unretained(this))); 66 base::Bind(&MojoAudioDecoder::OnConnectionError, base::Unretained(this)));
66 67
67 init_cb_ = init_cb; 68 init_cb_ = init_cb;
69 output_cb_ = output_cb;
68 70
69 // Using base::Unretained(this) is safe because |this| owns |remote_decoder_|, 71 // Using base::Unretained(this) is safe because |this| owns |remote_decoder_|,
70 // and the callback won't be dispatched if |remote_decoder_| is destroyed. 72 // and the callback won't be dispatched if |remote_decoder_| is destroyed.
71 remote_decoder_->Initialize( 73 remote_decoder_->Initialize(
72 binding_.CreateInterfacePtrAndBind(), 74 binding_.CreateInterfacePtrAndBind(),
73 interfaces::AudioDecoderConfig::From(config), cdm_id, 75 interfaces::AudioDecoderConfig::From(config), cdm_id,
74 base::Bind(&MojoAudioDecoder::OnInitialized, base::Unretained(this))); 76 base::Bind(&MojoAudioDecoder::OnInitialized, base::Unretained(this)));
75 } 77 }
76 78
77 void MojoAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 79 void MojoAudioDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
78 const DecodeCB& decode_cb) { 80 const DecodeCB& decode_cb) {
79 DVLOG(3) << __FUNCTION__; 81 DVLOG(3) << __FUNCTION__;
80 DCHECK(task_runner_->BelongsToCurrentThread()); 82 DCHECK(task_runner_->BelongsToCurrentThread());
81 83
82 if (has_connection_error_) { 84 if (has_connection_error_) {
83 task_runner_->PostTask(FROM_HERE, base::Bind(decode_cb, kDecodeError)); 85 task_runner_->PostTask(FROM_HERE, base::Bind(decode_cb, kDecodeError));
84 return; 86 return;
85 } 87 }
86 88
87 DCHECK(decode_cb_.is_null()); 89 DCHECK(decode_cb_.is_null());
88 decode_cb_ = decode_cb; 90 decode_cb_ = decode_cb;
89 91
90 // This code won't work because |buffer| is not serialized.
91 // TODO(timav): Serialize DecodeBuffer into data pipe.
92 remote_decoder_->Decode( 92 remote_decoder_->Decode(
93 interfaces::DecoderBuffer::From(buffer), 93 TransferDecoderBuffer(buffer),
94 base::Bind(&MojoAudioDecoder::OnDecodeStatus, base::Unretained(this))); 94 base::Bind(&MojoAudioDecoder::OnDecodeStatus, base::Unretained(this)));
95 } 95 }
96 96
97 void MojoAudioDecoder::Reset(const base::Closure& closure) { 97 void MojoAudioDecoder::Reset(const base::Closure& closure) {
98 DVLOG(2) << __FUNCTION__; 98 DVLOG(2) << __FUNCTION__;
99 DCHECK(task_runner_->BelongsToCurrentThread()); 99 DCHECK(task_runner_->BelongsToCurrentThread());
100 100
101 if (has_connection_error_) { 101 if (has_connection_error_) {
102 if (!decode_cb_.is_null()) { 102 if (!decode_cb_.is_null()) {
103 task_runner_->PostTask( 103 task_runner_->PostTask(
(...skipping 15 matching lines...) Expand all
119 DVLOG(1) << __FUNCTION__; 119 DVLOG(1) << __FUNCTION__;
120 DCHECK(task_runner_->BelongsToCurrentThread()); 120 DCHECK(task_runner_->BelongsToCurrentThread());
121 121
122 return needs_bitstream_conversion_; 122 return needs_bitstream_conversion_;
123 } 123 }
124 124
125 void MojoAudioDecoder::OnBufferDecoded(interfaces::AudioBufferPtr buffer) { 125 void MojoAudioDecoder::OnBufferDecoded(interfaces::AudioBufferPtr buffer) {
126 DVLOG(1) << __FUNCTION__; 126 DVLOG(1) << __FUNCTION__;
127 DCHECK(task_runner_->BelongsToCurrentThread()); 127 DCHECK(task_runner_->BelongsToCurrentThread());
128 128
129 NOTIMPLEMENTED(); 129 output_cb_.Run(buffer.To<scoped_refptr<AudioBuffer>>());
130 } 130 }
131 131
132 void MojoAudioDecoder::OnConnectionError() { 132 void MojoAudioDecoder::OnConnectionError() {
133 DVLOG(1) << __FUNCTION__; 133 DVLOG(1) << __FUNCTION__;
134 DCHECK(task_runner_->BelongsToCurrentThread()); 134 DCHECK(task_runner_->BelongsToCurrentThread());
135 135
136 has_connection_error_ = true; 136 has_connection_error_ = true;
137 137
138 if (!init_cb_.is_null()) { 138 if (!init_cb_.is_null()) {
139 base::ResetAndReturn(&init_cb_).Run(false); 139 base::ResetAndReturn(&init_cb_).Run(false);
140 return; 140 return;
141 } 141 }
142 142
143 if (!decode_cb_.is_null()) 143 if (!decode_cb_.is_null())
144 base::ResetAndReturn(&decode_cb_).Run(kDecodeError); 144 base::ResetAndReturn(&decode_cb_).Run(kDecodeError);
145 if (!reset_cb_.is_null()) 145 if (!reset_cb_.is_null())
146 base::ResetAndReturn(&reset_cb_).Run(); 146 base::ResetAndReturn(&reset_cb_).Run();
147 } 147 }
148 148
149 void MojoAudioDecoder::OnInitialized(bool status, 149 void MojoAudioDecoder::OnInitialized(bool status,
150 bool needs_bitstream_conversion) { 150 bool needs_bitstream_conversion) {
151 DVLOG(1) << __FUNCTION__ << ": status:" << status; 151 DVLOG(1) << __FUNCTION__ << ": status:" << status;
152 DCHECK(task_runner_->BelongsToCurrentThread()); 152 DCHECK(task_runner_->BelongsToCurrentThread());
153 153
154 needs_bitstream_conversion_ = needs_bitstream_conversion; 154 needs_bitstream_conversion_ = needs_bitstream_conversion;
155 155
156 if (status)
157 CreateDataPipe();
158
156 task_runner_->PostTask(FROM_HERE, base::Bind(init_cb_, status)); 159 task_runner_->PostTask(FROM_HERE, base::Bind(init_cb_, status));
157 } 160 }
158 161
159 static media::AudioDecoder::Status ConvertDecodeStatus( 162 static media::AudioDecoder::Status ConvertDecodeStatus(
160 interfaces::AudioDecoder::DecodeStatus status) { 163 interfaces::AudioDecoder::DecodeStatus status) {
161 switch (status) { 164 switch (status) {
162 case interfaces::AudioDecoder::DecodeStatus::OK: 165 case interfaces::AudioDecoder::DecodeStatus::OK:
163 return media::AudioDecoder::kOk; 166 return media::AudioDecoder::kOk;
164 case interfaces::AudioDecoder::DecodeStatus::ABORTED: 167 case interfaces::AudioDecoder::DecodeStatus::ABORTED:
165 return media::AudioDecoder::kAborted; 168 return media::AudioDecoder::kAborted;
(...skipping 17 matching lines...) Expand all
183 DVLOG(1) << __FUNCTION__; 186 DVLOG(1) << __FUNCTION__;
184 DCHECK(task_runner_->BelongsToCurrentThread()); 187 DCHECK(task_runner_->BelongsToCurrentThread());
185 188
186 // For pending decodes OnDecodeStatus() should arrive before OnResetDone(). 189 // For pending decodes OnDecodeStatus() should arrive before OnResetDone().
187 DCHECK(decode_cb_.is_null()); 190 DCHECK(decode_cb_.is_null());
188 191
189 DCHECK(!reset_cb_.is_null()); 192 DCHECK(!reset_cb_.is_null());
190 base::ResetAndReturn(&reset_cb_).Run(); 193 base::ResetAndReturn(&reset_cb_).Run();
191 } 194 }
192 195
196 void MojoAudioDecoder::CreateDataPipe() {
197 MojoCreateDataPipeOptions options;
198 options.struct_size = sizeof(MojoCreateDataPipeOptions);
199 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
200 options.element_num_bytes = 1;
201 // TODO(timav): Consider capacity calculation based on AudioDecoderConfig.
202 options.capacity_num_bytes = 512 * 1024;
203
204 mojo::DataPipe write_pipe(options);
205
206 // Keep producer end.
207 producer_handle_ = std::move(write_pipe.producer_handle);
208
209 // Pass consumer end to |remote_decoder_|.
210 remote_decoder_->SetDataSource(std::move(write_pipe.consumer_handle));
211 }
212
213 interfaces::DecoderBufferPtr MojoAudioDecoder::TransferDecoderBuffer(
214 const scoped_refptr<DecoderBuffer>& media_buffer) {
215 interfaces::DecoderBufferPtr buffer =
216 interfaces::DecoderBuffer::From(media_buffer);
217 if (media_buffer->end_of_stream())
218 return buffer;
219
220 // Serialize the data section of the DecoderBuffer into our pipe.
221 uint32_t num_bytes = base::checked_cast<uint32_t>(media_buffer->data_size());
222 DCHECK_GT(num_bytes, 0u);
223 CHECK_EQ(WriteDataRaw(producer_handle_.get(), media_buffer->data(),
224 &num_bytes, MOJO_READ_DATA_FLAG_ALL_OR_NONE),
225 MOJO_RESULT_OK);
226 CHECK_EQ(num_bytes, static_cast<uint32_t>(media_buffer->data_size()));
227 return buffer;
228 }
229
193 } // namespace media 230 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698