| 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_service.h" | 5 #include "media/mojo/services/mojo_decryptor_service.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/numerics/safe_conversions.h" | 10 #include "base/numerics/safe_conversions.h" |
| 11 #include "media/base/audio_decoder_config.h" | 11 #include "media/base/audio_decoder_config.h" |
| 12 #include "media/base/cdm_context.h" | 12 #include "media/base/cdm_context.h" |
| 13 #include "media/base/decoder_buffer.h" | 13 #include "media/base/decoder_buffer.h" |
| 14 #include "media/base/decryptor.h" | 14 #include "media/base/decryptor.h" |
| 15 #include "media/base/media_keys.h" | 15 #include "media/base/media_keys.h" |
| 16 #include "media/base/video_decoder_config.h" | 16 #include "media/base/video_decoder_config.h" |
| 17 #include "media/base/video_frame.h" | 17 #include "media/base/video_frame.h" |
| 18 #include "media/mojo/common/media_type_converters.h" | 18 #include "media/mojo/common/media_type_converters.h" |
| 19 #include "media/mojo/common/mojo_decoder_buffer_converter.h" |
| 19 #include "media/mojo/common/mojo_shared_buffer_video_frame.h" | 20 #include "media/mojo/common/mojo_shared_buffer_video_frame.h" |
| 20 #include "media/mojo/interfaces/demuxer_stream.mojom.h" | 21 #include "media/mojo/interfaces/demuxer_stream.mojom.h" |
| 21 | 22 |
| 22 namespace media { | 23 namespace media { |
| 23 | 24 |
| 24 MojoDecryptorService::MojoDecryptorService( | 25 MojoDecryptorService::MojoDecryptorService( |
| 25 const scoped_refptr<MediaKeys>& cdm, | 26 const scoped_refptr<MediaKeys>& cdm, |
| 26 mojo::InterfaceRequest<mojom::Decryptor> request, | 27 mojo::InterfaceRequest<mojom::Decryptor> request, |
| 27 const base::Closure& error_handler) | 28 const base::Closure& error_handler) |
| 28 : binding_(this, std::move(request)), cdm_(cdm), weak_factory_(this) { | 29 : binding_(this, std::move(request)), cdm_(cdm), weak_factory_(this) { |
| 29 DVLOG(1) << __FUNCTION__; | 30 DVLOG(1) << __FUNCTION__; |
| 30 decryptor_ = cdm->GetCdmContext()->GetDecryptor(); | 31 decryptor_ = cdm->GetCdmContext()->GetDecryptor(); |
| 31 DCHECK(decryptor_); | 32 DCHECK(decryptor_); |
| 32 weak_this_ = weak_factory_.GetWeakPtr(); | 33 weak_this_ = weak_factory_.GetWeakPtr(); |
| 33 binding_.set_connection_error_handler(error_handler); | 34 binding_.set_connection_error_handler(error_handler); |
| 34 } | 35 } |
| 35 | 36 |
| 36 MojoDecryptorService::~MojoDecryptorService() {} | 37 MojoDecryptorService::~MojoDecryptorService() {} |
| 37 | 38 |
| 38 void MojoDecryptorService::Initialize( | 39 void MojoDecryptorService::Initialize( |
| 39 mojo::ScopedDataPipeConsumerHandle receive_pipe, | 40 mojo::ScopedDataPipeConsumerHandle receive_pipe, |
| 40 mojo::ScopedDataPipeProducerHandle transmit_pipe) { | 41 mojo::ScopedDataPipeProducerHandle transmit_pipe) { |
| 41 producer_handle_ = std::move(transmit_pipe); | 42 mojo_decoder_buffer_writer_.reset( |
| 42 consumer_handle_ = std::move(receive_pipe); | 43 new MojoDecoderBufferWriter(std::move(transmit_pipe))); |
| 44 mojo_decoder_buffer_reader_.reset( |
| 45 new MojoDecoderBufferReader(std::move(receive_pipe))); |
| 43 } | 46 } |
| 44 | 47 |
| 45 void MojoDecryptorService::Decrypt(mojom::DemuxerStream::Type stream_type, | 48 void MojoDecryptorService::Decrypt(mojom::DemuxerStream::Type stream_type, |
| 46 mojom::DecoderBufferPtr encrypted, | 49 mojom::DecoderBufferPtr encrypted, |
| 47 const DecryptCallback& callback) { | 50 const DecryptCallback& callback) { |
| 48 DVLOG(3) << __FUNCTION__; | 51 DVLOG(3) << __FUNCTION__; |
| 52 |
| 53 scoped_refptr<DecoderBuffer> media_buffer = |
| 54 mojo_decoder_buffer_reader_->ConvertDecoderBuffer(encrypted); |
| 55 if (!media_buffer) { |
| 56 callback.Run(Status::DECRYPTION_ERROR, nullptr); |
| 57 return; |
| 58 } |
| 59 |
| 49 decryptor_->Decrypt( | 60 decryptor_->Decrypt( |
| 50 static_cast<media::Decryptor::StreamType>(stream_type), | 61 static_cast<media::Decryptor::StreamType>(stream_type), |
| 51 ReadDecoderBuffer(std::move(encrypted)), | 62 std::move(media_buffer), |
| 52 base::Bind(&MojoDecryptorService::OnDecryptDone, weak_this_, callback)); | 63 base::Bind(&MojoDecryptorService::OnDecryptDone, weak_this_, callback)); |
| 53 } | 64 } |
| 54 | 65 |
| 55 void MojoDecryptorService::CancelDecrypt( | 66 void MojoDecryptorService::CancelDecrypt( |
| 56 mojom::DemuxerStream::Type stream_type) { | 67 mojom::DemuxerStream::Type stream_type) { |
| 57 DVLOG(1) << __FUNCTION__; | 68 DVLOG(1) << __FUNCTION__; |
| 58 decryptor_->CancelDecrypt( | 69 decryptor_->CancelDecrypt( |
| 59 static_cast<media::Decryptor::StreamType>(stream_type)); | 70 static_cast<media::Decryptor::StreamType>(stream_type)); |
| 60 } | 71 } |
| 61 | 72 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 76 decryptor_->InitializeVideoDecoder( | 87 decryptor_->InitializeVideoDecoder( |
| 77 config.To<VideoDecoderConfig>(), | 88 config.To<VideoDecoderConfig>(), |
| 78 base::Bind(&MojoDecryptorService::OnVideoDecoderInitialized, weak_this_, | 89 base::Bind(&MojoDecryptorService::OnVideoDecoderInitialized, weak_this_, |
| 79 callback)); | 90 callback)); |
| 80 } | 91 } |
| 81 | 92 |
| 82 void MojoDecryptorService::DecryptAndDecodeAudio( | 93 void MojoDecryptorService::DecryptAndDecodeAudio( |
| 83 mojom::DecoderBufferPtr encrypted, | 94 mojom::DecoderBufferPtr encrypted, |
| 84 const DecryptAndDecodeAudioCallback& callback) { | 95 const DecryptAndDecodeAudioCallback& callback) { |
| 85 DVLOG(3) << __FUNCTION__; | 96 DVLOG(3) << __FUNCTION__; |
| 97 |
| 98 scoped_refptr<DecoderBuffer> media_buffer = |
| 99 mojo_decoder_buffer_reader_->ConvertDecoderBuffer(encrypted); |
| 100 if (!media_buffer) { |
| 101 callback.Run(Status::DECRYPTION_ERROR, nullptr); |
| 102 return; |
| 103 } |
| 104 |
| 86 decryptor_->DecryptAndDecodeAudio( | 105 decryptor_->DecryptAndDecodeAudio( |
| 87 ReadDecoderBuffer(std::move(encrypted)), | 106 std::move(media_buffer), |
| 88 base::Bind(&MojoDecryptorService::OnAudioDecoded, weak_this_, callback)); | 107 base::Bind(&MojoDecryptorService::OnAudioDecoded, weak_this_, callback)); |
| 89 } | 108 } |
| 90 | 109 |
| 91 void MojoDecryptorService::DecryptAndDecodeVideo( | 110 void MojoDecryptorService::DecryptAndDecodeVideo( |
| 92 mojom::DecoderBufferPtr encrypted, | 111 mojom::DecoderBufferPtr encrypted, |
| 93 const DecryptAndDecodeVideoCallback& callback) { | 112 const DecryptAndDecodeVideoCallback& callback) { |
| 94 DVLOG(3) << __FUNCTION__; | 113 DVLOG(3) << __FUNCTION__; |
| 114 |
| 115 scoped_refptr<DecoderBuffer> media_buffer = |
| 116 mojo_decoder_buffer_reader_->ConvertDecoderBuffer(encrypted); |
| 117 if (!media_buffer) { |
| 118 callback.Run(Status::DECRYPTION_ERROR, nullptr); |
| 119 return; |
| 120 } |
| 121 |
| 95 decryptor_->DecryptAndDecodeVideo( | 122 decryptor_->DecryptAndDecodeVideo( |
| 96 ReadDecoderBuffer(std::move(encrypted)), | 123 std::move(media_buffer), |
| 97 base::Bind(&MojoDecryptorService::OnVideoDecoded, weak_this_, callback)); | 124 base::Bind(&MojoDecryptorService::OnVideoDecoded, weak_this_, callback)); |
| 98 } | 125 } |
| 99 | 126 |
| 100 void MojoDecryptorService::ResetDecoder( | 127 void MojoDecryptorService::ResetDecoder( |
| 101 mojom::DemuxerStream::Type stream_type) { | 128 mojom::DemuxerStream::Type stream_type) { |
| 102 DVLOG(1) << __FUNCTION__; | 129 DVLOG(1) << __FUNCTION__; |
| 103 decryptor_->ResetDecoder( | 130 decryptor_->ResetDecoder( |
| 104 static_cast<media::Decryptor::StreamType>(stream_type)); | 131 static_cast<media::Decryptor::StreamType>(stream_type)); |
| 105 } | 132 } |
| 106 | 133 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 124 DVLOG_IF(1, status != media::Decryptor::kSuccess) << __FUNCTION__ << "(" | 151 DVLOG_IF(1, status != media::Decryptor::kSuccess) << __FUNCTION__ << "(" |
| 125 << status << ")"; | 152 << status << ")"; |
| 126 DVLOG_IF(3, status == media::Decryptor::kSuccess) << __FUNCTION__; | 153 DVLOG_IF(3, status == media::Decryptor::kSuccess) << __FUNCTION__; |
| 127 | 154 |
| 128 if (!buffer) { | 155 if (!buffer) { |
| 129 DCHECK_NE(status, media::Decryptor::kSuccess); | 156 DCHECK_NE(status, media::Decryptor::kSuccess); |
| 130 callback.Run(static_cast<Decryptor::Status>(status), nullptr); | 157 callback.Run(static_cast<Decryptor::Status>(status), nullptr); |
| 131 return; | 158 return; |
| 132 } | 159 } |
| 133 | 160 |
| 134 callback.Run(static_cast<Decryptor::Status>(status), | 161 mojom::DecoderBufferPtr mojo_buffer = |
| 135 TransferDecoderBuffer(buffer)); | 162 mojo_decoder_buffer_writer_->ConvertDecoderBuffer(buffer); |
| 163 if (!mojo_buffer) { |
| 164 callback.Run(Status::DECRYPTION_ERROR, nullptr); |
| 165 return; |
| 166 } |
| 167 |
| 168 callback.Run(static_cast<Decryptor::Status>(status), std::move(mojo_buffer)); |
| 136 } | 169 } |
| 137 | 170 |
| 138 void MojoDecryptorService::OnAudioDecoderInitialized( | 171 void MojoDecryptorService::OnAudioDecoderInitialized( |
| 139 const InitializeAudioDecoderCallback& callback, | 172 const InitializeAudioDecoderCallback& callback, |
| 140 bool success) { | 173 bool success) { |
| 141 DVLOG(1) << __FUNCTION__ << "(" << success << ")"; | 174 DVLOG(1) << __FUNCTION__ << "(" << success << ")"; |
| 142 callback.Run(success); | 175 callback.Run(success); |
| 143 } | 176 } |
| 144 | 177 |
| 145 void MojoDecryptorService::OnVideoDecoderInitialized( | 178 void MojoDecryptorService::OnVideoDecoderInitialized( |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 MojoSharedBufferVideoFrame* mojo_frame = | 218 MojoSharedBufferVideoFrame* mojo_frame = |
| 186 static_cast<MojoSharedBufferVideoFrame*>(frame.get()); | 219 static_cast<MojoSharedBufferVideoFrame*>(frame.get()); |
| 187 in_use_video_frames_.insert( | 220 in_use_video_frames_.insert( |
| 188 std::make_pair(mojo_frame->Handle().value(), frame)); | 221 std::make_pair(mojo_frame->Handle().value(), frame)); |
| 189 } | 222 } |
| 190 | 223 |
| 191 callback.Run(static_cast<Decryptor::Status>(status), | 224 callback.Run(static_cast<Decryptor::Status>(status), |
| 192 mojom::VideoFrame::From(frame)); | 225 mojom::VideoFrame::From(frame)); |
| 193 } | 226 } |
| 194 | 227 |
| 195 mojom::DecoderBufferPtr MojoDecryptorService::TransferDecoderBuffer( | |
| 196 const scoped_refptr<DecoderBuffer>& encrypted) { | |
| 197 mojom::DecoderBufferPtr buffer = mojom::DecoderBuffer::From(encrypted); | |
| 198 if (encrypted->end_of_stream()) | |
| 199 return buffer; | |
| 200 | |
| 201 // Serialize the data section of the DecoderBuffer into our pipe. | |
| 202 uint32_t bytes_to_write = | |
| 203 base::checked_cast<uint32_t>(encrypted->data_size()); | |
| 204 DCHECK_GT(bytes_to_write, 0u); | |
| 205 uint32_t bytes_written = bytes_to_write; | |
| 206 CHECK_EQ(WriteDataRaw(producer_handle_.get(), encrypted->data(), | |
| 207 &bytes_written, MOJO_READ_DATA_FLAG_ALL_OR_NONE), | |
| 208 MOJO_RESULT_OK); | |
| 209 CHECK_EQ(bytes_to_write, bytes_written); | |
| 210 return buffer; | |
| 211 } | |
| 212 | |
| 213 scoped_refptr<DecoderBuffer> MojoDecryptorService::ReadDecoderBuffer( | |
| 214 mojom::DecoderBufferPtr buffer) { | |
| 215 scoped_refptr<DecoderBuffer> media_buffer( | |
| 216 buffer.To<scoped_refptr<DecoderBuffer>>()); | |
| 217 if (media_buffer->end_of_stream()) | |
| 218 return media_buffer; | |
| 219 | |
| 220 // Wait for the data to become available in the DataPipe. | |
| 221 MojoHandleSignalsState state; | |
| 222 CHECK_EQ(MOJO_RESULT_OK, | |
| 223 MojoWait(consumer_handle_.get().value(), MOJO_HANDLE_SIGNAL_READABLE, | |
| 224 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 225 CHECK_EQ(MOJO_HANDLE_SIGNAL_READABLE, state.satisfied_signals); | |
| 226 | |
| 227 // Read the inner data for the DecoderBuffer from our DataPipe. | |
| 228 uint32_t bytes_to_read = | |
| 229 base::checked_cast<uint32_t>(media_buffer->data_size()); | |
| 230 DCHECK_GT(bytes_to_read, 0u); | |
| 231 uint32_t bytes_read = bytes_to_read; | |
| 232 CHECK_EQ(ReadDataRaw(consumer_handle_.get(), media_buffer->writable_data(), | |
| 233 &bytes_read, MOJO_READ_DATA_FLAG_ALL_OR_NONE), | |
| 234 MOJO_RESULT_OK); | |
| 235 CHECK_EQ(bytes_to_read, bytes_read); | |
| 236 return media_buffer; | |
| 237 } | |
| 238 | |
| 239 } // namespace media | 228 } // namespace media |
| OLD | NEW |