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

Side by Side Diff: media/mojo/clients/mojo_decryptor.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, 6 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_decryptor.h" 5 #include "media/mojo/clients/mojo_decryptor.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/numerics/safe_conversions.h" 13 #include "base/numerics/safe_conversions.h"
14 #include "media/base/audio_buffer.h" 14 #include "media/base/audio_buffer.h"
15 #include "media/base/decoder_buffer.h" 15 #include "media/base/decoder_buffer.h"
16 #include "media/base/video_frame.h" 16 #include "media/base/video_frame.h"
17 #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"
18 #include "media/mojo/common/mojo_shared_buffer_video_frame.h" 19 #include "media/mojo/common/mojo_shared_buffer_video_frame.h"
19 #include "media/mojo/interfaces/decryptor.mojom.h" 20 #include "media/mojo/interfaces/decryptor.mojom.h"
20 #include "services/shell/public/cpp/connect.h" 21 #include "services/shell/public/cpp/connect.h"
21 22
22 namespace media { 23 namespace media {
23 24
24 MojoDecryptor::MojoDecryptor(mojom::DecryptorPtr remote_decryptor) 25 MojoDecryptor::MojoDecryptor(mojom::DecryptorPtr remote_decryptor)
25 : remote_decryptor_(std::move(remote_decryptor)), weak_factory_(this) { 26 : remote_decryptor_(std::move(remote_decryptor)), weak_factory_(this) {
26 DVLOG(1) << __FUNCTION__; 27 DVLOG(1) << __FUNCTION__;
27 CreateDataPipes(); 28
29 // Allocate DataPipe size based on video content.
30
31 mojo::ScopedDataPipeConsumerHandle remote_consumer_handle;
32 mojo_decoder_buffer_writer_ = MojoDecoderBufferWriter::Create(
33 DemuxerStream::VIDEO, &remote_consumer_handle);
34
35 mojo::ScopedDataPipeProducerHandle remote_producer_handle;
36 mojo_decoder_buffer_reader_ = MojoDecoderBufferReader::Create(
37 DemuxerStream::VIDEO, &remote_producer_handle);
38
39 // Pass the other end of each pipe to |remote_decryptor_|.
40 remote_decryptor_->Initialize(std::move(remote_consumer_handle),
41 std::move(remote_producer_handle));
28 } 42 }
29 43
30 MojoDecryptor::~MojoDecryptor() { 44 MojoDecryptor::~MojoDecryptor() {
31 DVLOG(1) << __FUNCTION__; 45 DVLOG(1) << __FUNCTION__;
32 DCHECK(thread_checker_.CalledOnValidThread()); 46 DCHECK(thread_checker_.CalledOnValidThread());
33 } 47 }
34 48
35 void MojoDecryptor::RegisterNewKeyCB(StreamType stream_type, 49 void MojoDecryptor::RegisterNewKeyCB(StreamType stream_type,
36 const NewKeyCB& key_added_cb) { 50 const NewKeyCB& key_added_cb) {
37 DCHECK(thread_checker_.CalledOnValidThread()); 51 DCHECK(thread_checker_.CalledOnValidThread());
38 switch (stream_type) { 52 switch (stream_type) {
39 case kAudio: 53 case kAudio:
40 new_audio_key_cb_ = key_added_cb; 54 new_audio_key_cb_ = key_added_cb;
41 break; 55 break;
42 case kVideo: 56 case kVideo:
43 new_video_key_cb_ = key_added_cb; 57 new_video_key_cb_ = key_added_cb;
44 break; 58 break;
45 default: 59 default:
46 NOTREACHED(); 60 NOTREACHED();
47 } 61 }
48 } 62 }
49 63
50 void MojoDecryptor::Decrypt(StreamType stream_type, 64 void MojoDecryptor::Decrypt(StreamType stream_type,
51 const scoped_refptr<DecoderBuffer>& encrypted, 65 const scoped_refptr<DecoderBuffer>& encrypted,
52 const DecryptCB& decrypt_cb) { 66 const DecryptCB& decrypt_cb) {
53 DVLOG(3) << __FUNCTION__; 67 DVLOG(3) << __FUNCTION__;
54 DCHECK(thread_checker_.CalledOnValidThread()); 68 DCHECK(thread_checker_.CalledOnValidThread());
55 69
70 mojom::DecoderBufferPtr mojo_buffer =
71 mojo_decoder_buffer_writer_->WriteDecoderBuffer(encrypted);
72 if (!mojo_buffer) {
73 decrypt_cb.Run(kError, nullptr);
74 return;
75 }
76
56 remote_decryptor_->Decrypt( 77 remote_decryptor_->Decrypt(
57 static_cast<mojom::DemuxerStream::Type>(stream_type), 78 static_cast<mojom::DemuxerStream::Type>(stream_type),
58 TransferDecoderBuffer(encrypted), 79 std::move(mojo_buffer),
59 base::Bind(&MojoDecryptor::OnBufferDecrypted, weak_factory_.GetWeakPtr(), 80 base::Bind(&MojoDecryptor::OnBufferDecrypted, weak_factory_.GetWeakPtr(),
60 decrypt_cb)); 81 decrypt_cb));
61 } 82 }
62 83
63 void MojoDecryptor::CancelDecrypt(StreamType stream_type) { 84 void MojoDecryptor::CancelDecrypt(StreamType stream_type) {
64 DVLOG(1) << __FUNCTION__; 85 DVLOG(1) << __FUNCTION__;
65 DCHECK(thread_checker_.CalledOnValidThread()); 86 DCHECK(thread_checker_.CalledOnValidThread());
66 87
67 remote_decryptor_->CancelDecrypt( 88 remote_decryptor_->CancelDecrypt(
68 static_cast<mojom::DemuxerStream::Type>(stream_type)); 89 static_cast<mojom::DemuxerStream::Type>(stream_type));
(...skipping 16 matching lines...) Expand all
85 remote_decryptor_->InitializeVideoDecoder( 106 remote_decryptor_->InitializeVideoDecoder(
86 mojom::VideoDecoderConfig::From(config), init_cb); 107 mojom::VideoDecoderConfig::From(config), init_cb);
87 } 108 }
88 109
89 void MojoDecryptor::DecryptAndDecodeAudio( 110 void MojoDecryptor::DecryptAndDecodeAudio(
90 const scoped_refptr<DecoderBuffer>& encrypted, 111 const scoped_refptr<DecoderBuffer>& encrypted,
91 const AudioDecodeCB& audio_decode_cb) { 112 const AudioDecodeCB& audio_decode_cb) {
92 DVLOG(3) << __FUNCTION__; 113 DVLOG(3) << __FUNCTION__;
93 DCHECK(thread_checker_.CalledOnValidThread()); 114 DCHECK(thread_checker_.CalledOnValidThread());
94 115
116 mojom::DecoderBufferPtr mojo_buffer =
117 mojo_decoder_buffer_writer_->WriteDecoderBuffer(encrypted);
118 if (!mojo_buffer) {
119 audio_decode_cb.Run(kError, AudioFrames());
120 return;
121 }
122
95 remote_decryptor_->DecryptAndDecodeAudio( 123 remote_decryptor_->DecryptAndDecodeAudio(
96 TransferDecoderBuffer(encrypted), 124 std::move(mojo_buffer),
97 base::Bind(&MojoDecryptor::OnAudioDecoded, weak_factory_.GetWeakPtr(), 125 base::Bind(&MojoDecryptor::OnAudioDecoded, weak_factory_.GetWeakPtr(),
98 audio_decode_cb)); 126 audio_decode_cb));
99 } 127 }
100 128
101 void MojoDecryptor::DecryptAndDecodeVideo( 129 void MojoDecryptor::DecryptAndDecodeVideo(
102 const scoped_refptr<DecoderBuffer>& encrypted, 130 const scoped_refptr<DecoderBuffer>& encrypted,
103 const VideoDecodeCB& video_decode_cb) { 131 const VideoDecodeCB& video_decode_cb) {
104 DVLOG(3) << __FUNCTION__; 132 DVLOG(3) << __FUNCTION__;
105 DCHECK(thread_checker_.CalledOnValidThread()); 133 DCHECK(thread_checker_.CalledOnValidThread());
106 134
135 mojom::DecoderBufferPtr mojo_buffer =
136 mojo_decoder_buffer_writer_->WriteDecoderBuffer(encrypted);
137 if (!mojo_buffer) {
138 video_decode_cb.Run(kError, nullptr);
139 return;
140 }
141
107 remote_decryptor_->DecryptAndDecodeVideo( 142 remote_decryptor_->DecryptAndDecodeVideo(
108 TransferDecoderBuffer(encrypted), 143 std::move(mojo_buffer),
109 base::Bind(&MojoDecryptor::OnVideoDecoded, weak_factory_.GetWeakPtr(), 144 base::Bind(&MojoDecryptor::OnVideoDecoded, weak_factory_.GetWeakPtr(),
110 video_decode_cb)); 145 video_decode_cb));
111 } 146 }
112 147
113 void MojoDecryptor::ResetDecoder(StreamType stream_type) { 148 void MojoDecryptor::ResetDecoder(StreamType stream_type) {
114 DVLOG(1) << __FUNCTION__; 149 DVLOG(1) << __FUNCTION__;
115 DCHECK(thread_checker_.CalledOnValidThread()); 150 DCHECK(thread_checker_.CalledOnValidThread());
116 151
117 remote_decryptor_->ResetDecoder( 152 remote_decryptor_->ResetDecoder(
118 static_cast<mojom::DemuxerStream::Type>(stream_type)); 153 static_cast<mojom::DemuxerStream::Type>(stream_type));
(...skipping 24 matching lines...) Expand all
143 DVLOG_IF(1, status != mojom::Decryptor::Status::SUCCESS) 178 DVLOG_IF(1, status != mojom::Decryptor::Status::SUCCESS)
144 << __FUNCTION__ << "(" << status << ")"; 179 << __FUNCTION__ << "(" << status << ")";
145 DVLOG_IF(3, status == mojom::Decryptor::Status::SUCCESS) << __FUNCTION__; 180 DVLOG_IF(3, status == mojom::Decryptor::Status::SUCCESS) << __FUNCTION__;
146 DCHECK(thread_checker_.CalledOnValidThread()); 181 DCHECK(thread_checker_.CalledOnValidThread());
147 182
148 if (buffer.is_null()) { 183 if (buffer.is_null()) {
149 decrypt_cb.Run(static_cast<Decryptor::Status>(status), nullptr); 184 decrypt_cb.Run(static_cast<Decryptor::Status>(status), nullptr);
150 return; 185 return;
151 } 186 }
152 187
153 decrypt_cb.Run(static_cast<Decryptor::Status>(status), 188 scoped_refptr<DecoderBuffer> media_buffer =
154 ReadDecoderBuffer(std::move(buffer))); 189 mojo_decoder_buffer_reader_->ReadDecoderBuffer(buffer);
190 if (!media_buffer) {
191 decrypt_cb.Run(kError, nullptr);
192 return;
193 }
194
195 decrypt_cb.Run(static_cast<Decryptor::Status>(status), media_buffer);
155 } 196 }
156 197
157 void MojoDecryptor::OnAudioDecoded( 198 void MojoDecryptor::OnAudioDecoded(
158 const AudioDecodeCB& audio_decode_cb, 199 const AudioDecodeCB& audio_decode_cb,
159 mojom::Decryptor::Status status, 200 mojom::Decryptor::Status status,
160 mojo::Array<mojom::AudioBufferPtr> audio_buffers) { 201 mojo::Array<mojom::AudioBufferPtr> audio_buffers) {
161 DVLOG_IF(1, status != mojom::Decryptor::Status::SUCCESS) 202 DVLOG_IF(1, status != mojom::Decryptor::Status::SUCCESS)
162 << __FUNCTION__ << "(" << status << ")"; 203 << __FUNCTION__ << "(" << status << ")";
163 DVLOG_IF(3, status == mojom::Decryptor::Status::SUCCESS) << __FUNCTION__; 204 DVLOG_IF(3, status == mojom::Decryptor::Status::SUCCESS) << __FUNCTION__;
164 DCHECK(thread_checker_.CalledOnValidThread()); 205 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 } 239 }
199 240
200 void MojoDecryptor::ReleaseSharedBuffer(mojo::ScopedSharedBufferHandle buffer, 241 void MojoDecryptor::ReleaseSharedBuffer(mojo::ScopedSharedBufferHandle buffer,
201 size_t buffer_size) { 242 size_t buffer_size) {
202 DVLOG(1) << __FUNCTION__; 243 DVLOG(1) << __FUNCTION__;
203 DCHECK(thread_checker_.CalledOnValidThread()); 244 DCHECK(thread_checker_.CalledOnValidThread());
204 245
205 remote_decryptor_->ReleaseSharedBuffer(std::move(buffer), buffer_size); 246 remote_decryptor_->ReleaseSharedBuffer(std::move(buffer), buffer_size);
206 } 247 }
207 248
208 void MojoDecryptor::CreateDataPipes() {
209 // Allocate DataPipe size based on video content. Video can get quite large;
210 // at 4K, VP9 delivers packets which are ~1MB in size; so allow for 50%
211 // headroom.
212 MojoCreateDataPipeOptions options;
213 options.struct_size = sizeof(MojoCreateDataPipeOptions);
214 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
215 options.element_num_bytes = 1;
216 options.capacity_num_bytes = 1.5 * (1024 * 1024);
217
218 // Create 2 pipes, one for each direction.
219 mojo::DataPipe write_pipe(options);
220 mojo::DataPipe read_pipe(options);
221
222 // Keep one end of each pipe.
223 producer_handle_ = std::move(write_pipe.producer_handle);
224 consumer_handle_ = std::move(read_pipe.consumer_handle);
225
226 // Pass the other end of each pipe to |remote_decryptor_|.
227 remote_decryptor_->Initialize(std::move(write_pipe.consumer_handle),
228 std::move(read_pipe.producer_handle));
229 }
230
231 mojom::DecoderBufferPtr MojoDecryptor::TransferDecoderBuffer(
232 const scoped_refptr<DecoderBuffer>& encrypted) {
233 mojom::DecoderBufferPtr buffer = mojom::DecoderBuffer::From(encrypted);
234 if (encrypted->end_of_stream())
235 return buffer;
236
237 // Serialize the data section of the DecoderBuffer into our pipe.
238 uint32_t num_bytes = base::checked_cast<uint32_t>(encrypted->data_size());
239 DCHECK_GT(num_bytes, 0u);
240 CHECK_EQ(WriteDataRaw(producer_handle_.get(), encrypted->data(), &num_bytes,
241 MOJO_READ_DATA_FLAG_ALL_OR_NONE),
242 MOJO_RESULT_OK);
243 CHECK_EQ(num_bytes, static_cast<uint32_t>(encrypted->data_size()));
244 return buffer;
245 }
246
247 scoped_refptr<DecoderBuffer> MojoDecryptor::ReadDecoderBuffer(
248 mojom::DecoderBufferPtr buffer) {
249 scoped_refptr<DecoderBuffer> media_buffer(
250 buffer.To<scoped_refptr<DecoderBuffer>>());
251 if (media_buffer->end_of_stream())
252 return media_buffer;
253
254 // Wait for the data to become available in the DataPipe.
255 MojoHandleSignalsState state;
256 CHECK_EQ(MOJO_RESULT_OK,
257 MojoWait(consumer_handle_.get().value(), MOJO_HANDLE_SIGNAL_READABLE,
258 MOJO_DEADLINE_INDEFINITE, &state));
259 CHECK_EQ(MOJO_HANDLE_SIGNAL_READABLE, state.satisfied_signals);
260
261 // Read the inner data for the DecoderBuffer from our DataPipe.
262 uint32_t num_bytes = base::checked_cast<uint32_t>(media_buffer->data_size());
263 DCHECK_GT(num_bytes, 0u);
264 CHECK_EQ(ReadDataRaw(consumer_handle_.get(), media_buffer->writable_data(),
265 &num_bytes, MOJO_READ_DATA_FLAG_ALL_OR_NONE),
266 MOJO_RESULT_OK);
267 CHECK_EQ(num_bytes, static_cast<uint32_t>(media_buffer->data_size()));
268 return media_buffer;
269 }
270
271 } // namespace media 249 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698