| OLD | NEW |
| 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 <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_shared_buffer_video_frame.h" | 18 #include "media/mojo/common/mojo_shared_buffer_video_frame.h" |
| 19 #include "media/mojo/interfaces/decryptor.mojom.h" | 19 #include "media/mojo/interfaces/decryptor.mojom.h" |
| 20 #include "services/shell/public/cpp/connect.h" | 20 #include "services/shell/public/cpp/connect.h" |
| 21 | 21 |
| 22 namespace media { | 22 namespace media { |
| 23 | 23 |
| 24 MojoDecryptor::MojoDecryptor(interfaces::DecryptorPtr remote_decryptor) | 24 MojoDecryptor::MojoDecryptor(mojom::DecryptorPtr remote_decryptor) |
| 25 : remote_decryptor_(std::move(remote_decryptor)), weak_factory_(this) { | 25 : remote_decryptor_(std::move(remote_decryptor)), weak_factory_(this) { |
| 26 DVLOG(1) << __FUNCTION__; | 26 DVLOG(1) << __FUNCTION__; |
| 27 CreateDataPipes(); | 27 CreateDataPipes(); |
| 28 } | 28 } |
| 29 | 29 |
| 30 MojoDecryptor::~MojoDecryptor() { | 30 MojoDecryptor::~MojoDecryptor() { |
| 31 DVLOG(1) << __FUNCTION__; | 31 DVLOG(1) << __FUNCTION__; |
| 32 DCHECK(thread_checker_.CalledOnValidThread()); | 32 DCHECK(thread_checker_.CalledOnValidThread()); |
| 33 } | 33 } |
| 34 | 34 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 | 49 |
| 50 void MojoDecryptor::Decrypt(StreamType stream_type, | 50 void MojoDecryptor::Decrypt(StreamType stream_type, |
| 51 const scoped_refptr<DecoderBuffer>& encrypted, | 51 const scoped_refptr<DecoderBuffer>& encrypted, |
| 52 const DecryptCB& decrypt_cb) { | 52 const DecryptCB& decrypt_cb) { |
| 53 DVLOG(3) << __FUNCTION__; | 53 DVLOG(3) << __FUNCTION__; |
| 54 DCHECK(thread_checker_.CalledOnValidThread()); | 54 DCHECK(thread_checker_.CalledOnValidThread()); |
| 55 | 55 |
| 56 remote_decryptor_->Decrypt( | 56 remote_decryptor_->Decrypt( |
| 57 static_cast<interfaces::DemuxerStream::Type>(stream_type), | 57 static_cast<mojom::DemuxerStream::Type>(stream_type), |
| 58 TransferDecoderBuffer(encrypted), | 58 TransferDecoderBuffer(encrypted), |
| 59 base::Bind(&MojoDecryptor::OnBufferDecrypted, weak_factory_.GetWeakPtr(), | 59 base::Bind(&MojoDecryptor::OnBufferDecrypted, weak_factory_.GetWeakPtr(), |
| 60 decrypt_cb)); | 60 decrypt_cb)); |
| 61 } | 61 } |
| 62 | 62 |
| 63 void MojoDecryptor::CancelDecrypt(StreamType stream_type) { | 63 void MojoDecryptor::CancelDecrypt(StreamType stream_type) { |
| 64 DVLOG(1) << __FUNCTION__; | 64 DVLOG(1) << __FUNCTION__; |
| 65 DCHECK(thread_checker_.CalledOnValidThread()); | 65 DCHECK(thread_checker_.CalledOnValidThread()); |
| 66 | 66 |
| 67 remote_decryptor_->CancelDecrypt( | 67 remote_decryptor_->CancelDecrypt( |
| 68 static_cast<interfaces::DemuxerStream::Type>(stream_type)); | 68 static_cast<mojom::DemuxerStream::Type>(stream_type)); |
| 69 } | 69 } |
| 70 | 70 |
| 71 void MojoDecryptor::InitializeAudioDecoder(const AudioDecoderConfig& config, | 71 void MojoDecryptor::InitializeAudioDecoder(const AudioDecoderConfig& config, |
| 72 const DecoderInitCB& init_cb) { | 72 const DecoderInitCB& init_cb) { |
| 73 DVLOG(1) << __FUNCTION__; | 73 DVLOG(1) << __FUNCTION__; |
| 74 DCHECK(thread_checker_.CalledOnValidThread()); | 74 DCHECK(thread_checker_.CalledOnValidThread()); |
| 75 | 75 |
| 76 remote_decryptor_->InitializeAudioDecoder( | 76 remote_decryptor_->InitializeAudioDecoder( |
| 77 interfaces::AudioDecoderConfig::From(config), init_cb); | 77 mojom::AudioDecoderConfig::From(config), init_cb); |
| 78 } | 78 } |
| 79 | 79 |
| 80 void MojoDecryptor::InitializeVideoDecoder(const VideoDecoderConfig& config, | 80 void MojoDecryptor::InitializeVideoDecoder(const VideoDecoderConfig& config, |
| 81 const DecoderInitCB& init_cb) { | 81 const DecoderInitCB& init_cb) { |
| 82 DVLOG(1) << __FUNCTION__; | 82 DVLOG(1) << __FUNCTION__; |
| 83 DCHECK(thread_checker_.CalledOnValidThread()); | 83 DCHECK(thread_checker_.CalledOnValidThread()); |
| 84 | 84 |
| 85 remote_decryptor_->InitializeVideoDecoder( | 85 remote_decryptor_->InitializeVideoDecoder( |
| 86 interfaces::VideoDecoderConfig::From(config), init_cb); | 86 mojom::VideoDecoderConfig::From(config), init_cb); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void MojoDecryptor::DecryptAndDecodeAudio( | 89 void MojoDecryptor::DecryptAndDecodeAudio( |
| 90 const scoped_refptr<DecoderBuffer>& encrypted, | 90 const scoped_refptr<DecoderBuffer>& encrypted, |
| 91 const AudioDecodeCB& audio_decode_cb) { | 91 const AudioDecodeCB& audio_decode_cb) { |
| 92 DVLOG(3) << __FUNCTION__; | 92 DVLOG(3) << __FUNCTION__; |
| 93 DCHECK(thread_checker_.CalledOnValidThread()); | 93 DCHECK(thread_checker_.CalledOnValidThread()); |
| 94 | 94 |
| 95 remote_decryptor_->DecryptAndDecodeAudio( | 95 remote_decryptor_->DecryptAndDecodeAudio( |
| 96 TransferDecoderBuffer(encrypted), | 96 TransferDecoderBuffer(encrypted), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 108 TransferDecoderBuffer(encrypted), | 108 TransferDecoderBuffer(encrypted), |
| 109 base::Bind(&MojoDecryptor::OnVideoDecoded, weak_factory_.GetWeakPtr(), | 109 base::Bind(&MojoDecryptor::OnVideoDecoded, weak_factory_.GetWeakPtr(), |
| 110 video_decode_cb)); | 110 video_decode_cb)); |
| 111 } | 111 } |
| 112 | 112 |
| 113 void MojoDecryptor::ResetDecoder(StreamType stream_type) { | 113 void MojoDecryptor::ResetDecoder(StreamType stream_type) { |
| 114 DVLOG(1) << __FUNCTION__; | 114 DVLOG(1) << __FUNCTION__; |
| 115 DCHECK(thread_checker_.CalledOnValidThread()); | 115 DCHECK(thread_checker_.CalledOnValidThread()); |
| 116 | 116 |
| 117 remote_decryptor_->ResetDecoder( | 117 remote_decryptor_->ResetDecoder( |
| 118 static_cast<interfaces::DemuxerStream::Type>(stream_type)); | 118 static_cast<mojom::DemuxerStream::Type>(stream_type)); |
| 119 } | 119 } |
| 120 | 120 |
| 121 void MojoDecryptor::DeinitializeDecoder(StreamType stream_type) { | 121 void MojoDecryptor::DeinitializeDecoder(StreamType stream_type) { |
| 122 DVLOG(1) << __FUNCTION__; | 122 DVLOG(1) << __FUNCTION__; |
| 123 DCHECK(thread_checker_.CalledOnValidThread()); | 123 DCHECK(thread_checker_.CalledOnValidThread()); |
| 124 | 124 |
| 125 remote_decryptor_->DeinitializeDecoder( | 125 remote_decryptor_->DeinitializeDecoder( |
| 126 static_cast<interfaces::DemuxerStream::Type>(stream_type)); | 126 static_cast<mojom::DemuxerStream::Type>(stream_type)); |
| 127 } | 127 } |
| 128 | 128 |
| 129 void MojoDecryptor::OnKeyAdded() { | 129 void MojoDecryptor::OnKeyAdded() { |
| 130 DVLOG(1) << __FUNCTION__; | 130 DVLOG(1) << __FUNCTION__; |
| 131 DCHECK(thread_checker_.CalledOnValidThread()); | 131 DCHECK(thread_checker_.CalledOnValidThread()); |
| 132 | 132 |
| 133 if (!new_audio_key_cb_.is_null()) | 133 if (!new_audio_key_cb_.is_null()) |
| 134 new_audio_key_cb_.Run(); | 134 new_audio_key_cb_.Run(); |
| 135 | 135 |
| 136 if (!new_video_key_cb_.is_null()) | 136 if (!new_video_key_cb_.is_null()) |
| 137 new_video_key_cb_.Run(); | 137 new_video_key_cb_.Run(); |
| 138 } | 138 } |
| 139 | 139 |
| 140 void MojoDecryptor::OnBufferDecrypted(const DecryptCB& decrypt_cb, | 140 void MojoDecryptor::OnBufferDecrypted(const DecryptCB& decrypt_cb, |
| 141 interfaces::Decryptor::Status status, | 141 mojom::Decryptor::Status status, |
| 142 interfaces::DecoderBufferPtr buffer) { | 142 mojom::DecoderBufferPtr buffer) { |
| 143 DVLOG_IF(1, status != interfaces::Decryptor::Status::SUCCESS) | 143 DVLOG_IF(1, status != mojom::Decryptor::Status::SUCCESS) |
| 144 << __FUNCTION__ << "(" << status << ")"; | 144 << __FUNCTION__ << "(" << status << ")"; |
| 145 DVLOG_IF(3, status == interfaces::Decryptor::Status::SUCCESS) << __FUNCTION__; | 145 DVLOG_IF(3, status == mojom::Decryptor::Status::SUCCESS) << __FUNCTION__; |
| 146 DCHECK(thread_checker_.CalledOnValidThread()); | 146 DCHECK(thread_checker_.CalledOnValidThread()); |
| 147 | 147 |
| 148 if (buffer.is_null()) { | 148 if (buffer.is_null()) { |
| 149 decrypt_cb.Run(static_cast<Decryptor::Status>(status), nullptr); | 149 decrypt_cb.Run(static_cast<Decryptor::Status>(status), nullptr); |
| 150 return; | 150 return; |
| 151 } | 151 } |
| 152 | 152 |
| 153 decrypt_cb.Run(static_cast<Decryptor::Status>(status), | 153 decrypt_cb.Run(static_cast<Decryptor::Status>(status), |
| 154 ReadDecoderBuffer(std::move(buffer))); | 154 ReadDecoderBuffer(std::move(buffer))); |
| 155 } | 155 } |
| 156 | 156 |
| 157 void MojoDecryptor::OnAudioDecoded( | 157 void MojoDecryptor::OnAudioDecoded( |
| 158 const AudioDecodeCB& audio_decode_cb, | 158 const AudioDecodeCB& audio_decode_cb, |
| 159 interfaces::Decryptor::Status status, | 159 mojom::Decryptor::Status status, |
| 160 mojo::Array<interfaces::AudioBufferPtr> audio_buffers) { | 160 mojo::Array<mojom::AudioBufferPtr> audio_buffers) { |
| 161 DVLOG_IF(1, status != interfaces::Decryptor::Status::SUCCESS) | 161 DVLOG_IF(1, status != mojom::Decryptor::Status::SUCCESS) |
| 162 << __FUNCTION__ << "(" << status << ")"; | 162 << __FUNCTION__ << "(" << status << ")"; |
| 163 DVLOG_IF(3, status == interfaces::Decryptor::Status::SUCCESS) << __FUNCTION__; | 163 DVLOG_IF(3, status == mojom::Decryptor::Status::SUCCESS) << __FUNCTION__; |
| 164 DCHECK(thread_checker_.CalledOnValidThread()); | 164 DCHECK(thread_checker_.CalledOnValidThread()); |
| 165 | 165 |
| 166 Decryptor::AudioFrames audio_frames; | 166 Decryptor::AudioFrames audio_frames; |
| 167 for (size_t i = 0; i < audio_buffers.size(); ++i) | 167 for (size_t i = 0; i < audio_buffers.size(); ++i) |
| 168 audio_frames.push_back(audio_buffers[i].To<scoped_refptr<AudioBuffer>>()); | 168 audio_frames.push_back(audio_buffers[i].To<scoped_refptr<AudioBuffer>>()); |
| 169 | 169 |
| 170 audio_decode_cb.Run(static_cast<Decryptor::Status>(status), audio_frames); | 170 audio_decode_cb.Run(static_cast<Decryptor::Status>(status), audio_frames); |
| 171 } | 171 } |
| 172 | 172 |
| 173 void MojoDecryptor::OnVideoDecoded(const VideoDecodeCB& video_decode_cb, | 173 void MojoDecryptor::OnVideoDecoded(const VideoDecodeCB& video_decode_cb, |
| 174 interfaces::Decryptor::Status status, | 174 mojom::Decryptor::Status status, |
| 175 interfaces::VideoFramePtr video_frame) { | 175 mojom::VideoFramePtr video_frame) { |
| 176 DVLOG_IF(1, status != interfaces::Decryptor::Status::SUCCESS) | 176 DVLOG_IF(1, status != mojom::Decryptor::Status::SUCCESS) |
| 177 << __FUNCTION__ << "(" << status << ")"; | 177 << __FUNCTION__ << "(" << status << ")"; |
| 178 DVLOG_IF(3, status == interfaces::Decryptor::Status::SUCCESS) << __FUNCTION__; | 178 DVLOG_IF(3, status == mojom::Decryptor::Status::SUCCESS) << __FUNCTION__; |
| 179 DCHECK(thread_checker_.CalledOnValidThread()); | 179 DCHECK(thread_checker_.CalledOnValidThread()); |
| 180 | 180 |
| 181 if (video_frame.is_null()) { | 181 if (video_frame.is_null()) { |
| 182 video_decode_cb.Run(static_cast<Decryptor::Status>(status), nullptr); | 182 video_decode_cb.Run(static_cast<Decryptor::Status>(status), nullptr); |
| 183 return; | 183 return; |
| 184 } | 184 } |
| 185 | 185 |
| 186 scoped_refptr<VideoFrame> frame(video_frame.To<scoped_refptr<VideoFrame>>()); | 186 scoped_refptr<VideoFrame> frame(video_frame.To<scoped_refptr<VideoFrame>>()); |
| 187 | 187 |
| 188 // If using shared memory, ensure that ReleaseSharedBuffer() is called when | 188 // If using shared memory, ensure that ReleaseSharedBuffer() is called when |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 | 221 |
| 222 // Keep one end of each pipe. | 222 // Keep one end of each pipe. |
| 223 producer_handle_ = std::move(write_pipe.producer_handle); | 223 producer_handle_ = std::move(write_pipe.producer_handle); |
| 224 consumer_handle_ = std::move(read_pipe.consumer_handle); | 224 consumer_handle_ = std::move(read_pipe.consumer_handle); |
| 225 | 225 |
| 226 // Pass the other end of each pipe to |remote_decryptor_|. | 226 // Pass the other end of each pipe to |remote_decryptor_|. |
| 227 remote_decryptor_->Initialize(std::move(write_pipe.consumer_handle), | 227 remote_decryptor_->Initialize(std::move(write_pipe.consumer_handle), |
| 228 std::move(read_pipe.producer_handle)); | 228 std::move(read_pipe.producer_handle)); |
| 229 } | 229 } |
| 230 | 230 |
| 231 interfaces::DecoderBufferPtr MojoDecryptor::TransferDecoderBuffer( | 231 mojom::DecoderBufferPtr MojoDecryptor::TransferDecoderBuffer( |
| 232 const scoped_refptr<DecoderBuffer>& encrypted) { | 232 const scoped_refptr<DecoderBuffer>& encrypted) { |
| 233 interfaces::DecoderBufferPtr buffer = | 233 mojom::DecoderBufferPtr buffer = mojom::DecoderBuffer::From(encrypted); |
| 234 interfaces::DecoderBuffer::From(encrypted); | |
| 235 if (encrypted->end_of_stream()) | 234 if (encrypted->end_of_stream()) |
| 236 return buffer; | 235 return buffer; |
| 237 | 236 |
| 238 // Serialize the data section of the DecoderBuffer into our pipe. | 237 // Serialize the data section of the DecoderBuffer into our pipe. |
| 239 uint32_t num_bytes = base::checked_cast<uint32_t>(encrypted->data_size()); | 238 uint32_t num_bytes = base::checked_cast<uint32_t>(encrypted->data_size()); |
| 240 DCHECK_GT(num_bytes, 0u); | 239 DCHECK_GT(num_bytes, 0u); |
| 241 CHECK_EQ(WriteDataRaw(producer_handle_.get(), encrypted->data(), &num_bytes, | 240 CHECK_EQ(WriteDataRaw(producer_handle_.get(), encrypted->data(), &num_bytes, |
| 242 MOJO_READ_DATA_FLAG_ALL_OR_NONE), | 241 MOJO_READ_DATA_FLAG_ALL_OR_NONE), |
| 243 MOJO_RESULT_OK); | 242 MOJO_RESULT_OK); |
| 244 CHECK_EQ(num_bytes, static_cast<uint32_t>(encrypted->data_size())); | 243 CHECK_EQ(num_bytes, static_cast<uint32_t>(encrypted->data_size())); |
| 245 return buffer; | 244 return buffer; |
| 246 } | 245 } |
| 247 | 246 |
| 248 scoped_refptr<DecoderBuffer> MojoDecryptor::ReadDecoderBuffer( | 247 scoped_refptr<DecoderBuffer> MojoDecryptor::ReadDecoderBuffer( |
| 249 interfaces::DecoderBufferPtr buffer) { | 248 mojom::DecoderBufferPtr buffer) { |
| 250 scoped_refptr<DecoderBuffer> media_buffer( | 249 scoped_refptr<DecoderBuffer> media_buffer( |
| 251 buffer.To<scoped_refptr<DecoderBuffer>>()); | 250 buffer.To<scoped_refptr<DecoderBuffer>>()); |
| 252 if (media_buffer->end_of_stream()) | 251 if (media_buffer->end_of_stream()) |
| 253 return media_buffer; | 252 return media_buffer; |
| 254 | 253 |
| 255 // Wait for the data to become available in the DataPipe. | 254 // Wait for the data to become available in the DataPipe. |
| 256 MojoHandleSignalsState state; | 255 MojoHandleSignalsState state; |
| 257 CHECK_EQ(MOJO_RESULT_OK, | 256 CHECK_EQ(MOJO_RESULT_OK, |
| 258 MojoWait(consumer_handle_.get().value(), MOJO_HANDLE_SIGNAL_READABLE, | 257 MojoWait(consumer_handle_.get().value(), MOJO_HANDLE_SIGNAL_READABLE, |
| 259 MOJO_DEADLINE_INDEFINITE, &state)); | 258 MOJO_DEADLINE_INDEFINITE, &state)); |
| 260 CHECK_EQ(MOJO_HANDLE_SIGNAL_READABLE, state.satisfied_signals); | 259 CHECK_EQ(MOJO_HANDLE_SIGNAL_READABLE, state.satisfied_signals); |
| 261 | 260 |
| 262 // Read the inner data for the DecoderBuffer from our DataPipe. | 261 // Read the inner data for the DecoderBuffer from our DataPipe. |
| 263 uint32_t num_bytes = base::checked_cast<uint32_t>(media_buffer->data_size()); | 262 uint32_t num_bytes = base::checked_cast<uint32_t>(media_buffer->data_size()); |
| 264 DCHECK_GT(num_bytes, 0u); | 263 DCHECK_GT(num_bytes, 0u); |
| 265 CHECK_EQ(ReadDataRaw(consumer_handle_.get(), media_buffer->writable_data(), | 264 CHECK_EQ(ReadDataRaw(consumer_handle_.get(), media_buffer->writable_data(), |
| 266 &num_bytes, MOJO_READ_DATA_FLAG_ALL_OR_NONE), | 265 &num_bytes, MOJO_READ_DATA_FLAG_ALL_OR_NONE), |
| 267 MOJO_RESULT_OK); | 266 MOJO_RESULT_OK); |
| 268 CHECK_EQ(num_bytes, static_cast<uint32_t>(media_buffer->data_size())); | 267 CHECK_EQ(num_bytes, static_cast<uint32_t>(media_buffer->data_size())); |
| 269 return media_buffer; | 268 return media_buffer; |
| 270 } | 269 } |
| 271 | 270 |
| 272 } // namespace media | 271 } // namespace media |
| OLD | NEW |