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

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

Issue 1538063003: Use data pipe to pass DecoderBuffer contents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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/services/mojo_decryptor.h" 5 #include "media/mojo/services/mojo_decryptor.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "media/base/audio_buffer.h" 10 #include "media/base/audio_buffer.h"
11 #include "media/base/decoder_buffer.h" 11 #include "media/base/decoder_buffer.h"
12 #include "media/base/video_frame.h" 12 #include "media/base/video_frame.h"
13 #include "media/mojo/interfaces/decryptor.mojom.h" 13 #include "media/mojo/interfaces/decryptor.mojom.h"
14 #include "media/mojo/services/media_type_converters.h" 14 #include "media/mojo/services/media_type_converters.h"
15 #include "mojo/application/public/cpp/connect.h" 15 #include "mojo/application/public/cpp/connect.h"
16 16
17 namespace media { 17 namespace media {
18 18
19 MojoDecryptor::MojoDecryptor(interfaces::DecryptorPtr remote_decryptor) 19 MojoDecryptor::MojoDecryptor(interfaces::DecryptorPtr remote_decryptor)
20 : remote_decryptor_(std::move(remote_decryptor)), weak_factory_(this) {} 20 : remote_decryptor_(std::move(remote_decryptor)), weak_factory_(this) {
21 CreateDataPipes();
22 }
21 23
22 MojoDecryptor::~MojoDecryptor() {} 24 MojoDecryptor::~MojoDecryptor() {}
23 25
24 void MojoDecryptor::RegisterNewKeyCB(StreamType stream_type, 26 void MojoDecryptor::RegisterNewKeyCB(StreamType stream_type,
25 const NewKeyCB& key_added_cb) { 27 const NewKeyCB& key_added_cb) {
26 switch (stream_type) { 28 switch (stream_type) {
27 case kAudio: 29 case kAudio:
28 new_audio_key_cb_ = key_added_cb; 30 new_audio_key_cb_ = key_added_cb;
29 break; 31 break;
30 case kVideo: 32 case kVideo:
31 new_video_key_cb_ = key_added_cb; 33 new_video_key_cb_ = key_added_cb;
32 break; 34 break;
33 default: 35 default:
34 NOTREACHED(); 36 NOTREACHED();
35 } 37 }
36 } 38 }
37 39
38 void MojoDecryptor::Decrypt(StreamType stream_type, 40 void MojoDecryptor::Decrypt(StreamType stream_type,
39 const scoped_refptr<DecoderBuffer>& encrypted, 41 const scoped_refptr<DecoderBuffer>& encrypted,
40 const DecryptCB& decrypt_cb) { 42 const DecryptCB& decrypt_cb) {
43 DVLOG(1) << __FUNCTION__;
44 WriteDataIntoDataPipe(encrypted);
41 remote_decryptor_->Decrypt( 45 remote_decryptor_->Decrypt(
42 static_cast<interfaces::DemuxerStream::Type>(stream_type), 46 static_cast<interfaces::DemuxerStream::Type>(stream_type),
43 interfaces::DecoderBuffer::From(encrypted), 47 interfaces::DecoderBuffer::From(encrypted),
44 base::Bind(&MojoDecryptor::OnBufferDecrypted, weak_factory_.GetWeakPtr(), 48 base::Bind(&MojoDecryptor::OnBufferDecrypted, weak_factory_.GetWeakPtr(),
45 decrypt_cb)); 49 decrypt_cb));
46 } 50 }
47 51
48 void MojoDecryptor::CancelDecrypt(StreamType stream_type) { 52 void MojoDecryptor::CancelDecrypt(StreamType stream_type) {
53 DVLOG(1) << __FUNCTION__;
49 remote_decryptor_->CancelDecrypt( 54 remote_decryptor_->CancelDecrypt(
50 static_cast<interfaces::DemuxerStream::Type>(stream_type)); 55 static_cast<interfaces::DemuxerStream::Type>(stream_type));
51 } 56 }
52 57
53 void MojoDecryptor::InitializeAudioDecoder(const AudioDecoderConfig& config, 58 void MojoDecryptor::InitializeAudioDecoder(const AudioDecoderConfig& config,
54 const DecoderInitCB& init_cb) { 59 const DecoderInitCB& init_cb) {
60 DVLOG(1) << __FUNCTION__;
55 remote_decryptor_->InitializeAudioDecoder( 61 remote_decryptor_->InitializeAudioDecoder(
56 interfaces::AudioDecoderConfig::From(config), init_cb); 62 interfaces::AudioDecoderConfig::From(config), init_cb);
57 } 63 }
58 64
59 void MojoDecryptor::InitializeVideoDecoder(const VideoDecoderConfig& config, 65 void MojoDecryptor::InitializeVideoDecoder(const VideoDecoderConfig& config,
60 const DecoderInitCB& init_cb) { 66 const DecoderInitCB& init_cb) {
67 DVLOG(1) << __FUNCTION__;
61 remote_decryptor_->InitializeVideoDecoder( 68 remote_decryptor_->InitializeVideoDecoder(
62 interfaces::VideoDecoderConfig::From(config), init_cb); 69 interfaces::VideoDecoderConfig::From(config), init_cb);
63 } 70 }
64 71
65 void MojoDecryptor::DecryptAndDecodeAudio( 72 void MojoDecryptor::DecryptAndDecodeAudio(
66 const scoped_refptr<DecoderBuffer>& encrypted, 73 const scoped_refptr<DecoderBuffer>& encrypted,
67 const AudioDecodeCB& audio_decode_cb) { 74 const AudioDecodeCB& audio_decode_cb) {
75 DVLOG(1) << __FUNCTION__;
xhwang 2015/12/19 18:16:30 Probably use DVLOG(3) for repeating events.
jrummell 2015/12/21 23:20:55 Done.
76 WriteDataIntoDataPipe(encrypted);
68 remote_decryptor_->DecryptAndDecodeAudio( 77 remote_decryptor_->DecryptAndDecodeAudio(
69 interfaces::DecoderBuffer::From(encrypted), 78 interfaces::DecoderBuffer::From(encrypted),
xhwang 2015/12/19 18:16:30 It might be more clear to do: buffer = interfaces
jrummell 2015/12/21 23:20:55 Done.
70 base::Bind(&MojoDecryptor::OnAudioDecoded, weak_factory_.GetWeakPtr(), 79 base::Bind(&MojoDecryptor::OnAudioDecoded, weak_factory_.GetWeakPtr(),
71 audio_decode_cb)); 80 audio_decode_cb));
72 } 81 }
73 82
74 void MojoDecryptor::DecryptAndDecodeVideo( 83 void MojoDecryptor::DecryptAndDecodeVideo(
75 const scoped_refptr<DecoderBuffer>& encrypted, 84 const scoped_refptr<DecoderBuffer>& encrypted,
76 const VideoDecodeCB& video_decode_cb) { 85 const VideoDecodeCB& video_decode_cb) {
86 DVLOG(1) << __FUNCTION__;
87 DVLOG(3) << " encrypted: " << encrypted->AsHumanReadableString();
88 WriteDataIntoDataPipe(encrypted);
77 remote_decryptor_->DecryptAndDecodeVideo( 89 remote_decryptor_->DecryptAndDecodeVideo(
78 interfaces::DecoderBuffer::From(encrypted), 90 interfaces::DecoderBuffer::From(encrypted),
79 base::Bind(&MojoDecryptor::OnVideoDecoded, weak_factory_.GetWeakPtr(), 91 base::Bind(&MojoDecryptor::OnVideoDecoded, weak_factory_.GetWeakPtr(),
80 video_decode_cb)); 92 video_decode_cb));
81 } 93 }
82 94
83 void MojoDecryptor::ResetDecoder(StreamType stream_type) { 95 void MojoDecryptor::ResetDecoder(StreamType stream_type) {
96 DVLOG(1) << __FUNCTION__;
84 remote_decryptor_->ResetDecoder( 97 remote_decryptor_->ResetDecoder(
85 static_cast<interfaces::DemuxerStream::Type>(stream_type)); 98 static_cast<interfaces::DemuxerStream::Type>(stream_type));
86 } 99 }
87 100
88 void MojoDecryptor::DeinitializeDecoder(StreamType stream_type) { 101 void MojoDecryptor::DeinitializeDecoder(StreamType stream_type) {
102 DVLOG(1) << __FUNCTION__;
89 remote_decryptor_->DeinitializeDecoder( 103 remote_decryptor_->DeinitializeDecoder(
90 static_cast<interfaces::DemuxerStream::Type>(stream_type)); 104 static_cast<interfaces::DemuxerStream::Type>(stream_type));
91 } 105 }
92 106
93 void MojoDecryptor::OnKeyAdded() { 107 void MojoDecryptor::OnKeyAdded() {
108 DVLOG(1) << __FUNCTION__;
94 if (!new_audio_key_cb_.is_null()) 109 if (!new_audio_key_cb_.is_null())
95 new_audio_key_cb_.Run(); 110 new_audio_key_cb_.Run();
96 111
97 if (!new_video_key_cb_.is_null()) 112 if (!new_video_key_cb_.is_null())
98 new_video_key_cb_.Run(); 113 new_video_key_cb_.Run();
99 } 114 }
100 115
101 void MojoDecryptor::OnBufferDecrypted(const DecryptCB& decrypt_cb, 116 void MojoDecryptor::OnBufferDecrypted(const DecryptCB& decrypt_cb,
102 interfaces::Decryptor::Status status, 117 interfaces::Decryptor::Status status,
103 interfaces::DecoderBufferPtr buffer) { 118 interfaces::DecoderBufferPtr buffer) {
104 decrypt_cb.Run(static_cast<Decryptor::Status>(status), 119 DVLOG(1) << __FUNCTION__ << "(" << status << ")";
105 std::move(buffer.To<scoped_refptr<DecoderBuffer>>())); 120 if (buffer.is_null()) {
121 decrypt_cb.Run(static_cast<Decryptor::Status>(status), nullptr);
122 return;
123 }
124
125 scoped_refptr<DecoderBuffer> media_buffer(
126 buffer.To<scoped_refptr<DecoderBuffer>>());
127 ReadDataFromDataPipe(media_buffer);
128 DVLOG(3) << " media_buffer: " << media_buffer->AsHumanReadableString();
129 decrypt_cb.Run(static_cast<Decryptor::Status>(status), media_buffer);
106 } 130 }
107 131
108 void MojoDecryptor::OnAudioDecoded( 132 void MojoDecryptor::OnAudioDecoded(
109 const AudioDecodeCB& audio_decode_cb, 133 const AudioDecodeCB& audio_decode_cb,
110 interfaces::Decryptor::Status status, 134 interfaces::Decryptor::Status status,
111 mojo::Array<interfaces::AudioBufferPtr> audio_buffers) { 135 mojo::Array<interfaces::AudioBufferPtr> audio_buffers) {
136 DVLOG(1) << __FUNCTION__ << "(" << status << ")";
xhwang 2015/12/19 18:16:30 ditto about log level
jrummell 2015/12/21 23:20:55 Done.
112 Decryptor::AudioFrames audio_frames; 137 Decryptor::AudioFrames audio_frames;
113 for (size_t i = 0; i < audio_buffers.size(); ++i) 138 for (size_t i = 0; i < audio_buffers.size(); ++i)
114 audio_frames.push_back(audio_buffers[i].To<scoped_refptr<AudioBuffer>>()); 139 audio_frames.push_back(audio_buffers[i].To<scoped_refptr<AudioBuffer>>());
115 140
116 audio_decode_cb.Run(static_cast<Decryptor::Status>(status), audio_frames); 141 audio_decode_cb.Run(static_cast<Decryptor::Status>(status), audio_frames);
117 } 142 }
118 143
119 void MojoDecryptor::OnVideoDecoded(const VideoDecodeCB& video_decode_cb, 144 void MojoDecryptor::OnVideoDecoded(const VideoDecodeCB& video_decode_cb,
120 interfaces::Decryptor::Status status, 145 interfaces::Decryptor::Status status,
121 interfaces::VideoFramePtr video_frame) { 146 interfaces::VideoFramePtr video_frame) {
122 video_decode_cb.Run(static_cast<Decryptor::Status>(status), 147 DVLOG(1) << __FUNCTION__ << "(" << status << ")";
xhwang 2015/12/19 18:16:30 ditto about log level
jrummell 2015/12/21 23:20:55 Done.
123 std::move(video_frame.To<scoped_refptr<VideoFrame>>())); 148 if (video_frame.is_null()) {
149 video_decode_cb.Run(static_cast<Decryptor::Status>(status), nullptr);
150 return;
151 }
152
153 scoped_refptr<VideoFrame> frame(video_frame.To<scoped_refptr<VideoFrame>>());
154 DVLOG(3) << " video_frame: " << frame->AsHumanReadableString();
xhwang 2015/12/19 18:16:30 We probably don't need this by default.
jrummell 2015/12/21 23:20:55 Done.
155 video_decode_cb.Run(static_cast<Decryptor::Status>(status), frame);
156 }
157
158 void MojoDecryptor::CreateDataPipes() {
159 // Allocate DataPipe size based on video content. Video can get quite large;
160 // at 4K, VP9 delivers packets which are ~1MB in size; so allow for 50%
161 // headroom.
162 MojoCreateDataPipeOptions options;
163 options.struct_size = sizeof(MojoCreateDataPipeOptions);
164 options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE;
165 options.element_num_bytes = 1;
166 options.capacity_num_bytes = 1.5 * (1024 * 1024);
167
168 // Create 2 pipes, one for each direction.
169 mojo::DataPipe data_pipe1(options);
170 mojo::DataPipe data_pipe2(options);
xhwang 2015/12/19 18:16:30 naming: it seems these should be write/read pipe,
jrummell 2015/12/21 23:20:55 Done.
171
172 // Keep one end of each pipe.
173 write_pipe_ = data_pipe1.producer_handle.Pass();
174 read_pipe_ = data_pipe2.consumer_handle.Pass();
175
176 // Pass the other end of each pipe to |remote_decryptor_|.
177 remote_decryptor_->Initialize(data_pipe1.consumer_handle.Pass(),
178 data_pipe2.producer_handle.Pass());
179 }
180
181 void MojoDecryptor::WriteDataIntoDataPipe(
182 const scoped_refptr<DecoderBuffer>& buffer) {
183 if (!buffer->end_of_stream()) {
xhwang 2015/12/19 18:16:30 return early: if (buffer->end_of_stream()) retu
jrummell 2015/12/21 23:20:55 Done.
184 // Serialize the data section of the DecoderBuffer into our pipe.
185 uint32_t num_bytes = buffer->data_size();
186 DCHECK_GT(num_bytes, 0u);
187 CHECK_EQ(WriteDataRaw(write_pipe_.get(), buffer->data(), &num_bytes,
188 MOJO_READ_DATA_FLAG_ALL_OR_NONE),
189 MOJO_RESULT_OK);
190 CHECK_EQ(num_bytes, static_cast<uint32_t>(buffer->data_size()));
191 }
192 }
193
194 void MojoDecryptor::ReadDataFromDataPipe(
195 const scoped_refptr<DecoderBuffer>& buffer) {
196 if (!buffer->end_of_stream()) {
xhwang 2015/12/19 18:16:30 ditto
jrummell 2015/12/21 23:20:55 Done.
197 // Read the inner data for the DecoderBuffer from our DataPipe.
198 uint32_t num_bytes = buffer->data_size();
199 DCHECK_GT(num_bytes, 0u);
200 CHECK_EQ(ReadDataRaw(read_pipe_.get(), buffer->writable_data(), &num_bytes,
201 MOJO_READ_DATA_FLAG_ALL_OR_NONE),
202 MOJO_RESULT_OK);
203 CHECK_EQ(num_bytes, static_cast<uint32_t>(buffer->data_size()));
204 }
124 } 205 }
125 206
126 } // namespace media 207 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698