blob: fb8e5f433eaf8ba4a5f827aa48d7a408f800439d [file] [log] [blame]
[email protected]85a37afd2013-05-30 22:51:151// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]e5aeef02012-08-17 00:18:432// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]6cae92e2013-10-19 00:12:145#include "media/cdm/ppapi/cdm_adapter.h"
6
[email protected]9264e1502012-09-18 19:53:017#include <cstring>
[email protected]9264e1502012-09-18 19:53:018#include <string>
[email protected]d341e332012-08-28 18:57:409#include <vector>
[email protected]e5aeef02012-08-17 00:18:4310
[email protected]9264e1502012-09-18 19:53:0111#include "base/basictypes.h"
12#include "base/compiler_specific.h"
[email protected]177bcf82013-08-10 08:21:1613#include "media/cdm/ppapi/api/content_decryption_module.h"
[email protected]6cae92e2013-10-19 00:12:1414#include "media/cdm/ppapi/cdm_helpers.h"
[email protected]e5aeef02012-08-17 00:18:4315#include "ppapi/c/pp_errors.h"
16#include "ppapi/c/pp_stdint.h"
[email protected]98ad9782012-08-22 04:06:2217#include "ppapi/c/private/pp_content_decryptor.h"
[email protected]e5aeef02012-08-17 00:18:4318#include "ppapi/cpp/completion_callback.h"
19#include "ppapi/cpp/core.h"
[email protected]e5aeef02012-08-17 00:18:4320#include "ppapi/cpp/instance.h"
21#include "ppapi/cpp/logging.h"
22#include "ppapi/cpp/module.h"
23#include "ppapi/cpp/pass_ref.h"
[email protected]e5aeef02012-08-17 00:18:4324#include "ppapi/cpp/resource.h"
25#include "ppapi/cpp/var.h"
26#include "ppapi/cpp/var_array_buffer.h"
[email protected]e5aeef02012-08-17 00:18:4327#include "ppapi/utility/completion_callback_factory.h"
28
[email protected]76ee293e2013-05-22 18:10:4729#if defined(CHECK_DOCUMENT_URL)
30#include "ppapi/cpp/dev/url_util_dev.h"
31#include "ppapi/cpp/instance_handle.h"
32#endif // defined(CHECK_DOCUMENT_URL)
[email protected]799eace2013-03-11 20:28:2233
[email protected]e5aeef02012-08-17 00:18:4334namespace {
35
[email protected]98ad9782012-08-22 04:06:2236bool IsMainThread() {
37 return pp::Module::Get()->core()->IsMainThread();
38}
39
[email protected]8f1be472012-12-15 19:06:3340// Posts a task to run |cb| on the main thread. The task is posted even if the
41// current thread is the main thread.
42void PostOnMain(pp::CompletionCallback cb) {
43 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK);
44}
45
46// Ensures |cb| is called on the main thread, either because the current thread
47// is the main thread or by posting it to the main thread.
[email protected]e5aeef02012-08-17 00:18:4348void CallOnMain(pp::CompletionCallback cb) {
[email protected]98ad9782012-08-22 04:06:2249 // TODO(tomfinegan): This is only necessary because PPAPI doesn't allow calls
50 // off the main thread yet. Remove this once the change lands.
51 if (IsMainThread())
52 cb.Run(PP_OK);
53 else
[email protected]8f1be472012-12-15 19:06:3354 PostOnMain(cb);
[email protected]e5aeef02012-08-17 00:18:4355}
56
[email protected]181d9c12012-10-03 22:53:4857// Configures a cdm::InputBuffer. |subsamples| must exist as long as
58// |input_buffer| is in use.
59void ConfigureInputBuffer(
60 const pp::Buffer_Dev& encrypted_buffer,
61 const PP_EncryptedBlockInfo& encrypted_block_info,
62 std::vector<cdm::SubsampleEntry>* subsamples,
63 cdm::InputBuffer* input_buffer) {
64 PP_DCHECK(subsamples);
[email protected]741c28f2012-10-18 07:02:2565 PP_DCHECK(!encrypted_buffer.is_null());
66
[email protected]3b274b42012-10-26 20:41:2667 input_buffer->data = static_cast<uint8_t*>(encrypted_buffer.data());
[email protected]2468aae2012-11-21 19:53:1668 input_buffer->data_size = encrypted_block_info.data_size;
69 PP_DCHECK(encrypted_buffer.size() >=
70 static_cast<uint32_t>(input_buffer->data_size));
[email protected]181d9c12012-10-03 22:53:4871 input_buffer->data_offset = encrypted_block_info.data_offset;
[email protected]181d9c12012-10-03 22:53:4872
[email protected]f3fffa22013-01-25 22:16:0373 PP_DCHECK(encrypted_block_info.key_id_size <=
74 arraysize(encrypted_block_info.key_id));
75 input_buffer->key_id_size = encrypted_block_info.key_id_size;
76 input_buffer->key_id = input_buffer->key_id_size > 0 ?
77 encrypted_block_info.key_id : NULL;
78
79 PP_DCHECK(encrypted_block_info.iv_size <= arraysize(encrypted_block_info.iv));
80 input_buffer->iv_size = encrypted_block_info.iv_size;
81 input_buffer->iv = encrypted_block_info.iv_size > 0 ?
82 encrypted_block_info.iv : NULL;
83
84 input_buffer->num_subsamples = encrypted_block_info.num_subsamples;
[email protected]181d9c12012-10-03 22:53:4885 if (encrypted_block_info.num_subsamples > 0) {
86 subsamples->reserve(encrypted_block_info.num_subsamples);
87
88 for (uint32_t i = 0; i < encrypted_block_info.num_subsamples; ++i) {
89 subsamples->push_back(cdm::SubsampleEntry(
90 encrypted_block_info.subsamples[i].clear_bytes,
91 encrypted_block_info.subsamples[i].cipher_bytes));
92 }
93
94 input_buffer->subsamples = &(*subsamples)[0];
95 }
96
97 input_buffer->timestamp = encrypted_block_info.tracking_info.timestamp;
98}
99
[email protected]8f5a9a52012-10-23 20:49:20100PP_DecryptResult CdmStatusToPpDecryptResult(cdm::Status status) {
101 switch (status) {
102 case cdm::kSuccess:
103 return PP_DECRYPTRESULT_SUCCESS;
104 case cdm::kNoKey:
105 return PP_DECRYPTRESULT_DECRYPT_NOKEY;
106 case cdm::kNeedMoreData:
107 return PP_DECRYPTRESULT_NEEDMOREDATA;
108 case cdm::kDecryptError:
109 return PP_DECRYPTRESULT_DECRYPT_ERROR;
110 case cdm::kDecodeError:
111 return PP_DECRYPTRESULT_DECODE_ERROR;
112 default:
113 PP_NOTREACHED();
114 return PP_DECRYPTRESULT_DECODE_ERROR;
115 }
116}
117
[email protected]e9d3a1022012-10-11 23:43:55118PP_DecryptedFrameFormat CdmVideoFormatToPpDecryptedFrameFormat(
[email protected]181d9c12012-10-03 22:53:48119 cdm::VideoFormat format) {
[email protected]8f5a9a52012-10-23 20:49:20120 switch (format) {
121 case cdm::kYv12:
122 return PP_DECRYPTEDFRAMEFORMAT_YV12;
123 case cdm::kI420:
124 return PP_DECRYPTEDFRAMEFORMAT_I420;
125 default:
126 return PP_DECRYPTEDFRAMEFORMAT_UNKNOWN;
127 }
[email protected]e9d3a1022012-10-11 23:43:55128}
129
[email protected]c999b3b72012-10-19 22:33:46130cdm::AudioDecoderConfig::AudioCodec PpAudioCodecToCdmAudioCodec(
131 PP_AudioCodec codec) {
[email protected]8f5a9a52012-10-23 20:49:20132 switch (codec) {
133 case PP_AUDIOCODEC_VORBIS:
134 return cdm::AudioDecoderConfig::kCodecVorbis;
[email protected]4967628d2012-10-27 02:08:48135 case PP_AUDIOCODEC_AAC:
136 return cdm::AudioDecoderConfig::kCodecAac;
[email protected]8f5a9a52012-10-23 20:49:20137 default:
138 return cdm::AudioDecoderConfig::kUnknownAudioCodec;
139 }
[email protected]c999b3b72012-10-19 22:33:46140}
141
[email protected]e9d3a1022012-10-11 23:43:55142cdm::VideoDecoderConfig::VideoCodec PpVideoCodecToCdmVideoCodec(
143 PP_VideoCodec codec) {
[email protected]8f5a9a52012-10-23 20:49:20144 switch (codec) {
145 case PP_VIDEOCODEC_VP8:
[email protected]4967628d2012-10-27 02:08:48146 return cdm::VideoDecoderConfig::kCodecVp8;
147 case PP_VIDEOCODEC_H264:
148 return cdm::VideoDecoderConfig::kCodecH264;
[email protected]8f5a9a52012-10-23 20:49:20149 default:
150 return cdm::VideoDecoderConfig::kUnknownVideoCodec;
151 }
[email protected]e9d3a1022012-10-11 23:43:55152}
153
154cdm::VideoDecoderConfig::VideoCodecProfile PpVCProfileToCdmVCProfile(
155 PP_VideoCodecProfile profile) {
[email protected]8f5a9a52012-10-23 20:49:20156 switch (profile) {
157 case PP_VIDEOCODECPROFILE_VP8_MAIN:
158 return cdm::VideoDecoderConfig::kVp8ProfileMain;
[email protected]4967628d2012-10-27 02:08:48159 case PP_VIDEOCODECPROFILE_H264_BASELINE:
160 return cdm::VideoDecoderConfig::kH264ProfileBaseline;
161 case PP_VIDEOCODECPROFILE_H264_MAIN:
162 return cdm::VideoDecoderConfig::kH264ProfileMain;
163 case PP_VIDEOCODECPROFILE_H264_EXTENDED:
164 return cdm::VideoDecoderConfig::kH264ProfileExtended;
165 case PP_VIDEOCODECPROFILE_H264_HIGH:
166 return cdm::VideoDecoderConfig::kH264ProfileHigh;
167 case PP_VIDEOCODECPROFILE_H264_HIGH_10:
168 return cdm::VideoDecoderConfig::kH264ProfileHigh10;
169 case PP_VIDEOCODECPROFILE_H264_HIGH_422:
170 return cdm::VideoDecoderConfig::kH264ProfileHigh422;
171 case PP_VIDEOCODECPROFILE_H264_HIGH_444_PREDICTIVE:
172 return cdm::VideoDecoderConfig::kH264ProfileHigh444Predictive;
[email protected]8f5a9a52012-10-23 20:49:20173 default:
174 return cdm::VideoDecoderConfig::kUnknownVideoCodecProfile;
175 }
[email protected]e9d3a1022012-10-11 23:43:55176}
177
178cdm::VideoFormat PpDecryptedFrameFormatToCdmVideoFormat(
179 PP_DecryptedFrameFormat format) {
[email protected]8f5a9a52012-10-23 20:49:20180 switch (format) {
181 case PP_DECRYPTEDFRAMEFORMAT_YV12:
182 return cdm::kYv12;
183 case PP_DECRYPTEDFRAMEFORMAT_I420:
184 return cdm::kI420;
185 default:
186 return cdm::kUnknownVideoFormat;
187 }
[email protected]181d9c12012-10-03 22:53:48188}
189
[email protected]bf5f1682012-10-23 04:31:43190cdm::StreamType PpDecryptorStreamTypeToCdmStreamType(
191 PP_DecryptorStreamType stream_type) {
192 switch (stream_type) {
193 case PP_DECRYPTORSTREAMTYPE_AUDIO:
194 return cdm::kStreamTypeAudio;
195 case PP_DECRYPTORSTREAMTYPE_VIDEO:
196 return cdm::kStreamTypeVideo;
197 }
198
199 PP_NOTREACHED();
200 return cdm::kStreamTypeVideo;
201}
202
[email protected]e5aeef02012-08-17 00:18:43203} // namespace
204
[email protected]177bcf82013-08-10 08:21:16205namespace media {
[email protected]e5aeef02012-08-17 00:18:43206
[email protected]6cae92e2013-10-19 00:12:14207CdmAdapter::CdmAdapter(PP_Instance instance, pp::Module* module)
[email protected]e5aeef02012-08-17 00:18:43208 : pp::Instance(instance),
[email protected]d341e332012-08-28 18:57:40209 pp::ContentDecryptor_Private(this),
[email protected]9264e1502012-09-18 19:53:01210 allocator_(this),
[email protected]d341e332012-08-28 18:57:40211 cdm_(NULL) {
[email protected]e5aeef02012-08-17 00:18:43212 callback_factory_.Initialize(this);
213}
214
[email protected]6cae92e2013-10-19 00:12:14215CdmAdapter::~CdmAdapter() {
[email protected]d341e332012-08-28 18:57:40216 if (cdm_)
[email protected]b68e1442013-02-12 04:46:11217 cdm_->Destroy();
218}
219
[email protected]6cae92e2013-10-19 00:12:14220bool CdmAdapter::CreateCdmInstance(const std::string& key_system) {
[email protected]b68e1442013-02-12 04:46:11221 PP_DCHECK(!cdm_);
222 cdm_ = static_cast<cdm::ContentDecryptionModule*>(
223 ::CreateCdmInstance(cdm::kCdmInterfaceVersion,
224 key_system.data(), key_system.size(),
225 GetCdmHost, this));
226
227 return (cdm_ != NULL);
[email protected]d341e332012-08-28 18:57:40228}
229
[email protected]a941d4e572013-10-14 21:22:05230// No KeyErrors should be reported in this function because they cannot be
231// bubbled up in the WD EME API. Those errors will be reported during session
232// creation (aka GenerateKeyRequest).
[email protected]6cae92e2013-10-19 00:12:14233void CdmAdapter::Initialize(const std::string& key_system,
[email protected]38a995d92013-09-20 06:34:51234 bool can_challenge_platform) {
[email protected]6cb006c2013-01-10 21:39:18235 PP_DCHECK(!key_system.empty());
[email protected]38a995d92013-09-20 06:34:51236 PP_DCHECK(key_system_.empty() || (key_system_ == key_system && cdm_));
237
[email protected]a941d4e572013-10-14 21:22:05238 if (!cdm_ && !CreateCdmInstance(key_system))
239 return;
240
[email protected]38a995d92013-09-20 06:34:51241 PP_DCHECK(cdm_);
242 key_system_ = key_system;
243}
244
[email protected]6cae92e2013-10-19 00:12:14245void CdmAdapter::GenerateKeyRequest(const std::string& type,
[email protected]38a995d92013-09-20 06:34:51246 pp::VarArrayBuffer init_data) {
[email protected]a941d4e572013-10-14 21:22:05247 // Initialize() doesn't report an error, so GenerateKeyRequest() can be called
248 // even if Initialize() failed.
249 if (!cdm_) {
250 SendUnknownKeyError(key_system_, std::string());
251 return;
252 }
[email protected]e5aeef02012-08-17 00:18:43253
[email protected]76ee293e2013-05-22 18:10:47254#if defined(CHECK_DOCUMENT_URL)
255 PP_URLComponents_Dev url_components = {};
256 pp::Var href = pp::URLUtil_Dev::Get()->GetDocumentURL(
257 pp::InstanceHandle(pp_instance()), &url_components);
258 PP_DCHECK(href.is_string());
259 PP_DCHECK(!href.AsString().empty());
260 PP_DCHECK(url_components.host.begin);
261 PP_DCHECK(0 < url_components.host.len);
262#endif // defined(CHECK_DOCUMENT_URL)
[email protected]799eace2013-03-11 20:28:22263
[email protected]d341e332012-08-28 18:57:40264 cdm::Status status = cdm_->GenerateKeyRequest(
[email protected]f1b1db02012-10-29 22:50:23265 type.data(), type.size(),
[email protected]3b274b42012-10-26 20:41:26266 static_cast<const uint8_t*>(init_data.Map()),
[email protected]f75555a2012-12-10 22:35:24267 init_data.ByteLength());
[email protected]0b959582012-10-01 23:13:27268 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
[email protected]38a995d92013-09-20 06:34:51269 if (status != cdm::kSuccess)
270 SendUnknownKeyError(key_system_, std::string());
[email protected]e5aeef02012-08-17 00:18:43271}
272
[email protected]6cae92e2013-10-19 00:12:14273void CdmAdapter::AddKey(const std::string& session_id,
[email protected]98ad9782012-08-22 04:06:22274 pp::VarArrayBuffer key,
275 pp::VarArrayBuffer init_data) {
[email protected]a941d4e572013-10-14 21:22:05276 // TODO(jrummell): In EME WD, AddKey() can only be called on valid sessions.
277 // We should be able to DCHECK(cdm_) when addressing http://crbug.com/249976.
[email protected]3b274b42012-10-26 20:41:26278 if (!cdm_) {
[email protected]6cb006c2013-01-10 21:39:18279 SendUnknownKeyError(key_system_, session_id);
[email protected]3b274b42012-10-26 20:41:26280 return;
281 }
282
283 const uint8_t* key_ptr = static_cast<const uint8_t*>(key.Map());
[email protected]d341e332012-08-28 18:57:40284 int key_size = key.ByteLength();
[email protected]3b274b42012-10-26 20:41:26285 const uint8_t* init_data_ptr = static_cast<const uint8_t*>(init_data.Map());
[email protected]d341e332012-08-28 18:57:40286 int init_data_size = init_data.ByteLength();
[email protected]26b200102013-01-30 05:24:23287 PP_DCHECK(!init_data_ptr == !init_data_size);
[email protected]e5aeef02012-08-17 00:18:43288
[email protected]26b200102013-01-30 05:24:23289 if (!key_ptr || key_size <= 0) {
[email protected]6cb006c2013-01-10 21:39:18290 SendUnknownKeyError(key_system_, session_id);
[email protected]ea4ff802012-09-13 01:36:44291 return;
[email protected]3b274b42012-10-26 20:41:26292 }
[email protected]e5aeef02012-08-17 00:18:43293
[email protected]d341e332012-08-28 18:57:40294 cdm::Status status = cdm_->AddKey(session_id.data(), session_id.size(),
295 key_ptr, key_size,
296 init_data_ptr, init_data_size);
[email protected]0b959582012-10-01 23:13:27297 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
[email protected]d341e332012-08-28 18:57:40298 if (status != cdm::kSuccess) {
[email protected]6cb006c2013-01-10 21:39:18299 SendUnknownKeyError(key_system_, session_id);
[email protected]ea4ff802012-09-13 01:36:44300 return;
[email protected]d341e332012-08-28 18:57:40301 }
302
[email protected]6cb006c2013-01-10 21:39:18303 SendKeyAdded(key_system_, session_id);
[email protected]e5aeef02012-08-17 00:18:43304}
305
[email protected]6cae92e2013-10-19 00:12:14306void CdmAdapter::CancelKeyRequest(const std::string& session_id) {
[email protected]a941d4e572013-10-14 21:22:05307 // TODO(jrummell): In EME WD, AddKey() can only be called on valid sessions.
308 // We should be able to DCHECK(cdm_) when addressing http://crbug.com/249976.
[email protected]3b274b42012-10-26 20:41:26309 if (!cdm_) {
[email protected]6cb006c2013-01-10 21:39:18310 SendUnknownKeyError(key_system_, session_id);
[email protected]3b274b42012-10-26 20:41:26311 return;
312 }
313
[email protected]d341e332012-08-28 18:57:40314 cdm::Status status = cdm_->CancelKeyRequest(session_id.data(),
315 session_id.size());
[email protected]0b959582012-10-01 23:13:27316 PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
[email protected]3b274b42012-10-26 20:41:26317 if (status != cdm::kSuccess)
[email protected]6cb006c2013-01-10 21:39:18318 SendUnknownKeyError(key_system_, session_id);
[email protected]e5aeef02012-08-17 00:18:43319}
320
[email protected]3b274b42012-10-26 20:41:26321// Note: In the following decryption/decoding related functions, errors are NOT
322// reported via KeyError, but are reported via corresponding PPB calls.
323
[email protected]6cae92e2013-10-19 00:12:14324void CdmAdapter::Decrypt(pp::Buffer_Dev encrypted_buffer,
[email protected]98ad9782012-08-22 04:06:22325 const PP_EncryptedBlockInfo& encrypted_block_info) {
[email protected]e5aeef02012-08-17 00:18:43326 PP_DCHECK(!encrypted_buffer.is_null());
327
[email protected]ce19e7b52012-12-05 19:47:24328 // Release a buffer that the caller indicated it is finished with.
329 allocator_.Release(encrypted_block_info.tracking_info.buffer_id);
330
[email protected]3b274b42012-10-26 20:41:26331 cdm::Status status = cdm::kDecryptError;
[email protected]7ed56ed2012-10-02 02:43:27332 LinkedDecryptedBlock decrypted_block(new DecryptedBlockImpl());
[email protected]3b274b42012-10-26 20:41:26333
334 if (cdm_) {
335 cdm::InputBuffer input_buffer;
336 std::vector<cdm::SubsampleEntry> subsamples;
337 ConfigureInputBuffer(encrypted_buffer, encrypted_block_info, &subsamples,
338 &input_buffer);
339 status = cdm_->Decrypt(input_buffer, decrypted_block.get());
[email protected]f75555a2012-12-10 22:35:24340 PP_DCHECK(status != cdm::kSuccess ||
341 (decrypted_block->DecryptedBuffer() &&
342 decrypted_block->DecryptedBuffer()->Size()));
[email protected]3b274b42012-10-26 20:41:26343 }
[email protected]d341e332012-08-28 18:57:40344
345 CallOnMain(callback_factory_.NewCallback(
[email protected]6cae92e2013-10-19 00:12:14346 &CdmAdapter::DeliverBlock,
[email protected]d341e332012-08-28 18:57:40347 status,
[email protected]7ed56ed2012-10-02 02:43:27348 decrypted_block,
[email protected]d341e332012-08-28 18:57:40349 encrypted_block_info.tracking_info));
[email protected]e5aeef02012-08-17 00:18:43350}
351
[email protected]6cae92e2013-10-19 00:12:14352void CdmAdapter::InitializeAudioDecoder(
[email protected]c999b3b72012-10-19 22:33:46353 const PP_AudioDecoderConfig& decoder_config,
354 pp::Buffer_Dev extra_data_buffer) {
[email protected]3b274b42012-10-26 20:41:26355 cdm::Status status = cdm::kSessionError;
356 if (cdm_) {
357 cdm::AudioDecoderConfig cdm_decoder_config;
358 cdm_decoder_config.codec =
359 PpAudioCodecToCdmAudioCodec(decoder_config.codec);
360 cdm_decoder_config.channel_count = decoder_config.channel_count;
361 cdm_decoder_config.bits_per_channel = decoder_config.bits_per_channel;
362 cdm_decoder_config.samples_per_second = decoder_config.samples_per_second;
363 cdm_decoder_config.extra_data =
364 static_cast<uint8_t*>(extra_data_buffer.data());
365 cdm_decoder_config.extra_data_size =
366 static_cast<int32_t>(extra_data_buffer.size());
367 status = cdm_->InitializeAudioDecoder(cdm_decoder_config);
368 }
[email protected]c999b3b72012-10-19 22:33:46369
370 CallOnMain(callback_factory_.NewCallback(
[email protected]6cae92e2013-10-19 00:12:14371 &CdmAdapter::DecoderInitializeDone,
[email protected]c999b3b72012-10-19 22:33:46372 PP_DECRYPTORSTREAMTYPE_AUDIO,
373 decoder_config.request_id,
374 status == cdm::kSuccess));
375}
376
[email protected]6cae92e2013-10-19 00:12:14377void CdmAdapter::InitializeVideoDecoder(
[email protected]e9d3a1022012-10-11 23:43:55378 const PP_VideoDecoderConfig& decoder_config,
379 pp::Buffer_Dev extra_data_buffer) {
[email protected]3b274b42012-10-26 20:41:26380 cdm::Status status = cdm::kSessionError;
381 if (cdm_) {
382 cdm::VideoDecoderConfig cdm_decoder_config;
383 cdm_decoder_config.codec =
384 PpVideoCodecToCdmVideoCodec(decoder_config.codec);
385 cdm_decoder_config.profile =
386 PpVCProfileToCdmVCProfile(decoder_config.profile);
387 cdm_decoder_config.format =
388 PpDecryptedFrameFormatToCdmVideoFormat(decoder_config.format);
389 cdm_decoder_config.coded_size.width = decoder_config.width;
390 cdm_decoder_config.coded_size.height = decoder_config.height;
391 cdm_decoder_config.extra_data =
392 static_cast<uint8_t*>(extra_data_buffer.data());
393 cdm_decoder_config.extra_data_size =
394 static_cast<int32_t>(extra_data_buffer.size());
395 status = cdm_->InitializeVideoDecoder(cdm_decoder_config);
396 }
[email protected]e9d3a1022012-10-11 23:43:55397
398 CallOnMain(callback_factory_.NewCallback(
[email protected]6cae92e2013-10-19 00:12:14399 &CdmAdapter::DecoderInitializeDone,
[email protected]c999b3b72012-10-19 22:33:46400 PP_DECRYPTORSTREAMTYPE_VIDEO,
401 decoder_config.request_id,
402 status == cdm::kSuccess));
[email protected]e9d3a1022012-10-11 23:43:55403}
404
[email protected]6cae92e2013-10-19 00:12:14405void CdmAdapter::DeinitializeDecoder(PP_DecryptorStreamType decoder_type,
[email protected]23de87452012-10-12 07:03:09406 uint32_t request_id) {
[email protected]a941d4e572013-10-14 21:22:05407 PP_DCHECK(cdm_); // InitializeXxxxxDecoder should have succeeded.
[email protected]3b274b42012-10-26 20:41:26408 if (cdm_) {
409 cdm_->DeinitializeDecoder(
410 PpDecryptorStreamTypeToCdmStreamType(decoder_type));
411 }
412
[email protected]23de87452012-10-12 07:03:09413 CallOnMain(callback_factory_.NewCallback(
[email protected]6cae92e2013-10-19 00:12:14414 &CdmAdapter::DecoderDeinitializeDone,
[email protected]23de87452012-10-12 07:03:09415 decoder_type,
416 request_id));
417}
418
[email protected]6cae92e2013-10-19 00:12:14419void CdmAdapter::ResetDecoder(PP_DecryptorStreamType decoder_type,
[email protected]23de87452012-10-12 07:03:09420 uint32_t request_id) {
[email protected]a941d4e572013-10-14 21:22:05421 PP_DCHECK(cdm_); // InitializeXxxxxDecoder should have succeeded.
[email protected]3b274b42012-10-26 20:41:26422 if (cdm_)
423 cdm_->ResetDecoder(PpDecryptorStreamTypeToCdmStreamType(decoder_type));
424
[email protected]6cae92e2013-10-19 00:12:14425 CallOnMain(callback_factory_.NewCallback(&CdmAdapter::DecoderResetDone,
[email protected]23de87452012-10-12 07:03:09426 decoder_type,
427 request_id));
428}
429
[email protected]6cae92e2013-10-19 00:12:14430void CdmAdapter::DecryptAndDecode(
[email protected]467434d2012-10-12 10:48:53431 PP_DecryptorStreamType decoder_type,
432 pp::Buffer_Dev encrypted_buffer,
433 const PP_EncryptedBlockInfo& encrypted_block_info) {
[email protected]a941d4e572013-10-14 21:22:05434 PP_DCHECK(cdm_); // InitializeXxxxxDecoder should have succeeded.
[email protected]ce19e7b52012-12-05 19:47:24435 // Release a buffer that the caller indicated it is finished with.
436 allocator_.Release(encrypted_block_info.tracking_info.buffer_id);
437
[email protected]181d9c12012-10-03 22:53:48438 cdm::InputBuffer input_buffer;
439 std::vector<cdm::SubsampleEntry> subsamples;
[email protected]3b274b42012-10-26 20:41:26440 if (cdm_ && !encrypted_buffer.is_null()) {
[email protected]741c28f2012-10-18 07:02:25441 ConfigureInputBuffer(encrypted_buffer,
442 encrypted_block_info,
443 &subsamples,
444 &input_buffer);
445 }
[email protected]181d9c12012-10-03 22:53:48446
[email protected]ecbb97682012-10-24 22:33:54447 cdm::Status status = cdm::kDecodeError;
[email protected]3b274b42012-10-26 20:41:26448
[email protected]ecbb97682012-10-24 22:33:54449 switch (decoder_type) {
450 case PP_DECRYPTORSTREAMTYPE_VIDEO: {
451 LinkedVideoFrame video_frame(new VideoFrameImpl());
[email protected]3b274b42012-10-26 20:41:26452 if (cdm_)
453 status = cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get());
[email protected]ecbb97682012-10-24 22:33:54454 CallOnMain(callback_factory_.NewCallback(
[email protected]6cae92e2013-10-19 00:12:14455 &CdmAdapter::DeliverFrame,
[email protected]ecbb97682012-10-24 22:33:54456 status,
457 video_frame,
458 encrypted_block_info.tracking_info));
459 return;
460 }
461
462 case PP_DECRYPTORSTREAMTYPE_AUDIO: {
463 LinkedAudioFrames audio_frames(new AudioFramesImpl());
[email protected]3b274b42012-10-26 20:41:26464 if (cdm_) {
465 status = cdm_->DecryptAndDecodeSamples(input_buffer,
466 audio_frames.get());
467 }
[email protected]ecbb97682012-10-24 22:33:54468 CallOnMain(callback_factory_.NewCallback(
[email protected]6cae92e2013-10-19 00:12:14469 &CdmAdapter::DeliverSamples,
[email protected]ecbb97682012-10-24 22:33:54470 status,
471 audio_frames,
472 encrypted_block_info.tracking_info));
473 return;
474 }
475
476 default:
477 PP_NOTREACHED();
478 return;
479 }
[email protected]d341e332012-08-28 18:57:40480}
481
[email protected]6cae92e2013-10-19 00:12:14482cdm::Buffer* CdmAdapter::Allocate(int32_t capacity) {
[email protected]b68e1442013-02-12 04:46:11483 return allocator_.Allocate(capacity);
484}
485
[email protected]6cae92e2013-10-19 00:12:14486void CdmAdapter::SetTimer(int64_t delay_ms, void* context) {
[email protected]f5c9b938e2012-10-10 12:24:07487 // NOTE: doesn't really need to run on the main thread; could just as well run
488 // on a helper thread if |cdm_| were thread-friendly and care was taken. We
489 // only use CallOnMainThread() here to get delayed-execution behavior.
490 pp::Module::Get()->core()->CallOnMainThread(
491 delay_ms,
[email protected]6cae92e2013-10-19 00:12:14492 callback_factory_.NewCallback(&CdmAdapter::TimerExpired, context),
[email protected]f5c9b938e2012-10-10 12:24:07493 PP_OK);
494}
495
[email protected]6cae92e2013-10-19 00:12:14496void CdmAdapter::TimerExpired(int32_t result, void* context) {
[email protected]f5c9b938e2012-10-10 12:24:07497 PP_DCHECK(result == PP_OK);
[email protected]f75555a2012-12-10 22:35:24498 cdm_->TimerExpired(context);
[email protected]f5c9b938e2012-10-10 12:24:07499}
500
[email protected]6cae92e2013-10-19 00:12:14501double CdmAdapter::GetCurrentWallTimeInSeconds() {
[email protected]f5c9b938e2012-10-10 12:24:07502 return pp::Module::Get()->core()->GetTime();
503}
504
[email protected]6cae92e2013-10-19 00:12:14505void CdmAdapter::SendKeyMessage(
[email protected]f75555a2012-12-10 22:35:24506 const char* session_id, int32_t session_id_length,
507 const char* message, int32_t message_length,
508 const char* default_url, int32_t default_url_length) {
[email protected]6cb006c2013-01-10 21:39:18509 PP_DCHECK(!key_system_.empty());
[email protected]8f1be472012-12-15 19:06:33510 PostOnMain(callback_factory_.NewCallback(
[email protected]6cae92e2013-10-19 00:12:14511 &CdmAdapter::KeyMessage,
[email protected]6cb006c2013-01-10 21:39:18512 SessionInfo(key_system_,
513 std::string(session_id, session_id_length)),
[email protected]0a81bdb2013-06-29 23:18:06514 std::vector<uint8>(message, message + message_length),
[email protected]f75555a2012-12-10 22:35:24515 std::string(default_url, default_url_length)));
516}
517
[email protected]6cae92e2013-10-19 00:12:14518void CdmAdapter::SendKeyError(const char* session_id,
[email protected]f75555a2012-12-10 22:35:24519 int32_t session_id_length,
520 cdm::MediaKeyError error_code,
521 uint32_t system_code) {
[email protected]6cb006c2013-01-10 21:39:18522 SendKeyErrorInternal(key_system_,
523 std::string(session_id, session_id_length),
524 error_code,
525 system_code);
526}
527
[email protected]6cae92e2013-10-19 00:12:14528void CdmAdapter::GetPrivateData(int32_t* instance,
[email protected]703e8bad2013-10-15 20:26:25529 cdm::Host::GetPrivateInterface* get_interface) {
[email protected]b68e1442013-02-12 04:46:11530 *instance = pp_instance();
531 *get_interface = pp::Module::Get()->get_browser_interface();
532}
533
[email protected]6cae92e2013-10-19 00:12:14534void CdmAdapter::SendUnknownKeyError(const std::string& key_system,
[email protected]6cb006c2013-01-10 21:39:18535 const std::string& session_id) {
536 SendKeyErrorInternal(key_system, session_id, cdm::kUnknownError, 0);
537}
538
[email protected]6cae92e2013-10-19 00:12:14539void CdmAdapter::SendKeyAdded(const std::string& key_system,
[email protected]6cb006c2013-01-10 21:39:18540 const std::string& session_id) {
[email protected]8f1be472012-12-15 19:06:33541 PostOnMain(callback_factory_.NewCallback(
[email protected]6cae92e2013-10-19 00:12:14542 &CdmAdapter::KeyAdded,
[email protected]6cb006c2013-01-10 21:39:18543 SessionInfo(key_system_, session_id)));
[email protected]f75555a2012-12-10 22:35:24544}
545
[email protected]6cae92e2013-10-19 00:12:14546void CdmAdapter::SendKeyErrorInternal(const std::string& key_system,
[email protected]6cb006c2013-01-10 21:39:18547 const std::string& session_id,
548 cdm::MediaKeyError error_code,
549 uint32_t system_code) {
[email protected]6cae92e2013-10-19 00:12:14550 PostOnMain(callback_factory_.NewCallback(&CdmAdapter::KeyError,
[email protected]6cb006c2013-01-10 21:39:18551 SessionInfo(key_system_, session_id),
552 error_code,
553 system_code));
[email protected]8f1be472012-12-15 19:06:33554}
555
[email protected]6cae92e2013-10-19 00:12:14556void CdmAdapter::KeyAdded(int32_t result, const SessionInfo& session_info) {
[email protected]f5c9b938e2012-10-10 12:24:07557 PP_DCHECK(result == PP_OK);
[email protected]6cb006c2013-01-10 21:39:18558 PP_DCHECK(!session_info.key_system.empty());
559 pp::ContentDecryptor_Private::KeyAdded(session_info.key_system,
560 session_info.session_id);
[email protected]e5aeef02012-08-17 00:18:43561}
562
[email protected]6cae92e2013-10-19 00:12:14563void CdmAdapter::KeyMessage(int32_t result,
[email protected]6cb006c2013-01-10 21:39:18564 const SessionInfo& session_info,
[email protected]0a81bdb2013-06-29 23:18:06565 const std::vector<uint8>& message,
[email protected]f75555a2012-12-10 22:35:24566 const std::string& default_url) {
[email protected]f5c9b938e2012-10-10 12:24:07567 PP_DCHECK(result == PP_OK);
[email protected]6cb006c2013-01-10 21:39:18568 PP_DCHECK(!session_info.key_system.empty());
[email protected]6d613d62012-12-04 23:39:00569
[email protected]a6e4fbf2012-12-12 05:25:00570 pp::VarArrayBuffer message_array_buffer(message.size());
571 if (message.size() > 0) {
572 memcpy(message_array_buffer.Map(), message.data(), message.size());
[email protected]6d613d62012-12-04 23:39:00573 }
574
[email protected]d341e332012-08-28 18:57:40575 pp::ContentDecryptor_Private::KeyMessage(
[email protected]6cb006c2013-01-10 21:39:18576 session_info.key_system, session_info.session_id,
577 message_array_buffer, default_url);
[email protected]e5aeef02012-08-17 00:18:43578}
579
[email protected]6cae92e2013-10-19 00:12:14580void CdmAdapter::KeyError(int32_t result,
[email protected]6cb006c2013-01-10 21:39:18581 const SessionInfo& session_info,
[email protected]f75555a2012-12-10 22:35:24582 cdm::MediaKeyError error_code,
583 uint32_t system_code) {
[email protected]f5c9b938e2012-10-10 12:24:07584 PP_DCHECK(result == PP_OK);
[email protected]f75555a2012-12-10 22:35:24585 pp::ContentDecryptor_Private::KeyError(
[email protected]6cb006c2013-01-10 21:39:18586 session_info.key_system, session_info.session_id,
587 error_code, system_code);
[email protected]e5aeef02012-08-17 00:18:43588}
589
[email protected]6cae92e2013-10-19 00:12:14590void CdmAdapter::DeliverBlock(int32_t result,
[email protected]d341e332012-08-28 18:57:40591 const cdm::Status& status,
[email protected]7ed56ed2012-10-02 02:43:27592 const LinkedDecryptedBlock& decrypted_block,
[email protected]d341e332012-08-28 18:57:40593 const PP_DecryptTrackingInfo& tracking_info) {
[email protected]f5c9b938e2012-10-10 12:24:07594 PP_DCHECK(result == PP_OK);
[email protected]d341e332012-08-28 18:57:40595 PP_DecryptedBlockInfo decrypted_block_info;
[email protected]181d9c12012-10-03 22:53:48596 decrypted_block_info.tracking_info = tracking_info;
[email protected]f75555a2012-12-10 22:35:24597 decrypted_block_info.tracking_info.timestamp = decrypted_block->Timestamp();
[email protected]ce19e7b52012-12-05 19:47:24598 decrypted_block_info.tracking_info.buffer_id = 0;
599 decrypted_block_info.data_size = 0;
[email protected]8f5a9a52012-10-23 20:49:20600 decrypted_block_info.result = CdmStatusToPpDecryptResult(status);
[email protected]d341e332012-08-28 18:57:40601
[email protected]8f5a9a52012-10-23 20:49:20602 pp::Buffer_Dev buffer;
603
604 if (decrypted_block_info.result == PP_DECRYPTRESULT_SUCCESS) {
[email protected]f75555a2012-12-10 22:35:24605 PP_DCHECK(decrypted_block.get() && decrypted_block->DecryptedBuffer());
606 if (!decrypted_block.get() || !decrypted_block->DecryptedBuffer()) {
[email protected]ecbb97682012-10-24 22:33:54607 PP_NOTREACHED();
[email protected]d341e332012-08-28 18:57:40608 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
[email protected]8f5a9a52012-10-23 20:49:20609 } else {
[email protected]ce19e7b52012-12-05 19:47:24610 PpbBuffer* ppb_buffer =
[email protected]f75555a2012-12-10 22:35:24611 static_cast<PpbBuffer*>(decrypted_block->DecryptedBuffer());
[email protected]ce19e7b52012-12-05 19:47:24612 buffer = ppb_buffer->buffer_dev();
613 decrypted_block_info.tracking_info.buffer_id = ppb_buffer->buffer_id();
[email protected]f75555a2012-12-10 22:35:24614 decrypted_block_info.data_size = ppb_buffer->Size();
[email protected]8f5a9a52012-10-23 20:49:20615 }
[email protected]d341e332012-08-28 18:57:40616 }
617
[email protected]4bc37112012-09-21 19:49:25618 pp::ContentDecryptor_Private::DeliverBlock(buffer, decrypted_block_info);
[email protected]e5aeef02012-08-17 00:18:43619}
620
[email protected]6cae92e2013-10-19 00:12:14621void CdmAdapter::DecoderInitializeDone(int32_t result,
[email protected]c999b3b72012-10-19 22:33:46622 PP_DecryptorStreamType decoder_type,
623 uint32_t request_id,
624 bool success) {
625 PP_DCHECK(result == PP_OK);
626 pp::ContentDecryptor_Private::DecoderInitializeDone(decoder_type,
627 request_id,
628 success);
[email protected]e9d3a1022012-10-11 23:43:55629}
630
[email protected]6cae92e2013-10-19 00:12:14631void CdmAdapter::DecoderDeinitializeDone(int32_t result,
[email protected]23de87452012-10-12 07:03:09632 PP_DecryptorStreamType decoder_type,
633 uint32_t request_id) {
634 pp::ContentDecryptor_Private::DecoderDeinitializeDone(decoder_type,
635 request_id);
636}
637
[email protected]6cae92e2013-10-19 00:12:14638void CdmAdapter::DecoderResetDone(int32_t result,
[email protected]23de87452012-10-12 07:03:09639 PP_DecryptorStreamType decoder_type,
640 uint32_t request_id) {
641 pp::ContentDecryptor_Private::DecoderResetDone(decoder_type, request_id);
642}
643
[email protected]6cae92e2013-10-19 00:12:14644void CdmAdapter::DeliverFrame(
[email protected]181d9c12012-10-03 22:53:48645 int32_t result,
646 const cdm::Status& status,
647 const LinkedVideoFrame& video_frame,
648 const PP_DecryptTrackingInfo& tracking_info) {
[email protected]f5c9b938e2012-10-10 12:24:07649 PP_DCHECK(result == PP_OK);
[email protected]181d9c12012-10-03 22:53:48650 PP_DecryptedFrameInfo decrypted_frame_info;
[email protected]749576ff2012-10-30 05:10:48651 decrypted_frame_info.tracking_info.request_id = tracking_info.request_id;
[email protected]ce19e7b52012-12-05 19:47:24652 decrypted_frame_info.tracking_info.buffer_id = 0;
[email protected]8f5a9a52012-10-23 20:49:20653 decrypted_frame_info.result = CdmStatusToPpDecryptResult(status);
[email protected]181d9c12012-10-03 22:53:48654
[email protected]8f5a9a52012-10-23 20:49:20655 pp::Buffer_Dev buffer;
[email protected]741c28f2012-10-18 07:02:25656
[email protected]8f5a9a52012-10-23 20:49:20657 if (decrypted_frame_info.result == PP_DECRYPTRESULT_SUCCESS) {
[email protected]ce19e7b52012-12-05 19:47:24658 if (!IsValidVideoFrame(video_frame)) {
[email protected]ecbb97682012-10-24 22:33:54659 PP_NOTREACHED();
[email protected]8f5a9a52012-10-23 20:49:20660 decrypted_frame_info.result = PP_DECRYPTRESULT_DECODE_ERROR;
661 } else {
[email protected]ce19e7b52012-12-05 19:47:24662 PpbBuffer* ppb_buffer =
[email protected]f75555a2012-12-10 22:35:24663 static_cast<PpbBuffer*>(video_frame->FrameBuffer());
[email protected]ce19e7b52012-12-05 19:47:24664
665 buffer = ppb_buffer->buffer_dev();
666
[email protected]f75555a2012-12-10 22:35:24667 decrypted_frame_info.tracking_info.timestamp = video_frame->Timestamp();
[email protected]ce19e7b52012-12-05 19:47:24668 decrypted_frame_info.tracking_info.buffer_id = ppb_buffer->buffer_id();
669 decrypted_frame_info.format =
[email protected]f75555a2012-12-10 22:35:24670 CdmVideoFormatToPpDecryptedFrameFormat(video_frame->Format());
671 decrypted_frame_info.width = video_frame->Size().width;
672 decrypted_frame_info.height = video_frame->Size().height;
[email protected]181d9c12012-10-03 22:53:48673 decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y] =
[email protected]f75555a2012-12-10 22:35:24674 video_frame->PlaneOffset(cdm::VideoFrame::kYPlane);
[email protected]181d9c12012-10-03 22:53:48675 decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_U] =
[email protected]f75555a2012-12-10 22:35:24676 video_frame->PlaneOffset(cdm::VideoFrame::kUPlane);
[email protected]181d9c12012-10-03 22:53:48677 decrypted_frame_info.plane_offsets[PP_DECRYPTEDFRAMEPLANES_V] =
[email protected]f75555a2012-12-10 22:35:24678 video_frame->PlaneOffset(cdm::VideoFrame::kVPlane);
[email protected]181d9c12012-10-03 22:53:48679 decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_Y] =
[email protected]f75555a2012-12-10 22:35:24680 video_frame->Stride(cdm::VideoFrame::kYPlane);
[email protected]181d9c12012-10-03 22:53:48681 decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_U] =
[email protected]f75555a2012-12-10 22:35:24682 video_frame->Stride(cdm::VideoFrame::kUPlane);
[email protected]181d9c12012-10-03 22:53:48683 decrypted_frame_info.strides[PP_DECRYPTEDFRAMEPLANES_V] =
[email protected]f75555a2012-12-10 22:35:24684 video_frame->Stride(cdm::VideoFrame::kVPlane);
[email protected]8f5a9a52012-10-23 20:49:20685 }
[email protected]181d9c12012-10-03 22:53:48686 }
[email protected]181d9c12012-10-03 22:53:48687 pp::ContentDecryptor_Private::DeliverFrame(buffer, decrypted_frame_info);
688}
689
[email protected]6cae92e2013-10-19 00:12:14690void CdmAdapter::DeliverSamples(int32_t result,
[email protected]ecbb97682012-10-24 22:33:54691 const cdm::Status& status,
692 const LinkedAudioFrames& audio_frames,
693 const PP_DecryptTrackingInfo& tracking_info) {
694 PP_DCHECK(result == PP_OK);
[email protected]749576ff2012-10-30 05:10:48695
[email protected]ecbb97682012-10-24 22:33:54696 PP_DecryptedBlockInfo decrypted_block_info;
697 decrypted_block_info.tracking_info = tracking_info;
[email protected]ecbb97682012-10-24 22:33:54698 decrypted_block_info.tracking_info.timestamp = 0;
[email protected]ce19e7b52012-12-05 19:47:24699 decrypted_block_info.tracking_info.buffer_id = 0;
700 decrypted_block_info.data_size = 0;
[email protected]ecbb97682012-10-24 22:33:54701 decrypted_block_info.result = CdmStatusToPpDecryptResult(status);
702
703 pp::Buffer_Dev buffer;
704
705 if (decrypted_block_info.result == PP_DECRYPTRESULT_SUCCESS) {
[email protected]f75555a2012-12-10 22:35:24706 PP_DCHECK(audio_frames.get() && audio_frames->FrameBuffer());
707 if (!audio_frames.get() || !audio_frames->FrameBuffer()) {
[email protected]ecbb97682012-10-24 22:33:54708 PP_NOTREACHED();
709 decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
710 } else {
[email protected]f75555a2012-12-10 22:35:24711 PpbBuffer* ppb_buffer =
712 static_cast<PpbBuffer*>(audio_frames->FrameBuffer());
[email protected]ce19e7b52012-12-05 19:47:24713 buffer = ppb_buffer->buffer_dev();
714 decrypted_block_info.tracking_info.buffer_id = ppb_buffer->buffer_id();
[email protected]f75555a2012-12-10 22:35:24715 decrypted_block_info.data_size = ppb_buffer->Size();
[email protected]ecbb97682012-10-24 22:33:54716 }
717 }
718
719 pp::ContentDecryptor_Private::DeliverSamples(buffer, decrypted_block_info);
720}
[email protected]181d9c12012-10-03 22:53:48721
[email protected]6cae92e2013-10-19 00:12:14722bool CdmAdapter::IsValidVideoFrame(const LinkedVideoFrame& video_frame) {
[email protected]ce19e7b52012-12-05 19:47:24723 if (!video_frame.get() ||
[email protected]f75555a2012-12-10 22:35:24724 !video_frame->FrameBuffer() ||
725 (video_frame->Format() != cdm::kI420 &&
726 video_frame->Format() != cdm::kYv12)) {
[email protected]ce19e7b52012-12-05 19:47:24727 return false;
728 }
729
[email protected]f75555a2012-12-10 22:35:24730 PpbBuffer* ppb_buffer = static_cast<PpbBuffer*>(video_frame->FrameBuffer());
[email protected]ce19e7b52012-12-05 19:47:24731
732 for (int i = 0; i < cdm::VideoFrame::kMaxPlanes; ++i) {
733 int plane_height = (i == cdm::VideoFrame::kYPlane) ?
[email protected]f75555a2012-12-10 22:35:24734 video_frame->Size().height : (video_frame->Size().height + 1) / 2;
[email protected]ce19e7b52012-12-05 19:47:24735 cdm::VideoFrame::VideoPlane plane =
736 static_cast<cdm::VideoFrame::VideoPlane>(i);
[email protected]f75555a2012-12-10 22:35:24737 if (ppb_buffer->Size() < video_frame->PlaneOffset(plane) +
738 plane_height * video_frame->Stride(plane)) {
[email protected]ce19e7b52012-12-05 19:47:24739 return false;
740 }
741 }
742
743 return true;
744}
745
[email protected]b68e1442013-02-12 04:46:11746void* GetCdmHost(int host_interface_version, void* user_data) {
747 if (!host_interface_version || !user_data)
748 return NULL;
749
[email protected]703e8bad2013-10-15 20:26:25750 if (host_interface_version != cdm::kHostInterfaceVersion)
751 return NULL;
752
[email protected]6cae92e2013-10-19 00:12:14753 CdmAdapter* cdm_adapter = static_cast<CdmAdapter*>(user_data);
754 return static_cast<cdm::Host*>(cdm_adapter);
[email protected]b68e1442013-02-12 04:46:11755}
756
[email protected]e5aeef02012-08-17 00:18:43757// This object is the global object representing this plugin library as long
758// as it is loaded.
[email protected]6cae92e2013-10-19 00:12:14759class CdmAdapterModule : public pp::Module {
[email protected]e5aeef02012-08-17 00:18:43760 public:
[email protected]6cae92e2013-10-19 00:12:14761 CdmAdapterModule() : pp::Module() {
[email protected]a9c788e2012-10-26 23:54:55762 // This function blocks the renderer thread (PluginInstance::Initialize()).
763 // Move this call to other places if this may be a concern in the future.
764 INITIALIZE_CDM_MODULE();
765 }
[email protected]6cae92e2013-10-19 00:12:14766 virtual ~CdmAdapterModule() {
[email protected]f75555a2012-12-10 22:35:24767 DeinitializeCdmModule();
[email protected]a9c788e2012-10-26 23:54:55768 }
[email protected]e5aeef02012-08-17 00:18:43769
770 virtual pp::Instance* CreateInstance(PP_Instance instance) {
[email protected]6cae92e2013-10-19 00:12:14771 return new CdmAdapter(instance, this);
[email protected]e5aeef02012-08-17 00:18:43772 }
773};
774
[email protected]177bcf82013-08-10 08:21:16775} // namespace media
[email protected]d341e332012-08-28 18:57:40776
[email protected]e5aeef02012-08-17 00:18:43777namespace pp {
778
779// Factory function for your specialization of the Module object.
780Module* CreateModule() {
[email protected]6cae92e2013-10-19 00:12:14781 return new media::CdmAdapterModule();
[email protected]e5aeef02012-08-17 00:18:43782}
783
784} // namespace pp