OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "content/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_decode_accelerator.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/android/build_info.h" | 9 #include "base/android/build_info.h" |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 20 matching lines...) Expand all Loading... | |
31 #include "media/base/limits.h" | 31 #include "media/base/limits.h" |
32 #include "media/base/media.h" | 32 #include "media/base/media.h" |
33 #include "media/base/timestamp_constants.h" | 33 #include "media/base/timestamp_constants.h" |
34 #include "media/base/video_decoder_config.h" | 34 #include "media/base/video_decoder_config.h" |
35 #include "media/video/picture.h" | 35 #include "media/video/picture.h" |
36 #include "ui/gl/android/scoped_java_surface.h" | 36 #include "ui/gl/android/scoped_java_surface.h" |
37 #include "ui/gl/android/surface_texture.h" | 37 #include "ui/gl/android/surface_texture.h" |
38 #include "ui/gl/gl_bindings.h" | 38 #include "ui/gl/gl_bindings.h" |
39 | 39 |
40 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 40 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
41 #include "media/base/media_keys.h" | |
42 #include "media/mojo/services/mojo_cdm_service.h" | 41 #include "media/mojo/services/mojo_cdm_service.h" |
43 #endif | 42 #endif |
44 | 43 |
45 #define POST_ERROR(error_code, error_message) \ | 44 #define POST_ERROR(error_code, error_message) \ |
46 do { \ | 45 do { \ |
47 DLOG(ERROR) << error_message; \ | 46 DLOG(ERROR) << error_message; \ |
48 PostError(FROM_HERE, media::VideoDecodeAccelerator::error_code); \ | 47 PostError(FROM_HERE, media::VideoDecodeAccelerator::error_code); \ |
49 } while (0) | 48 } while (0) |
50 | 49 |
51 namespace content { | 50 namespace content { |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, | 255 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, |
257 const base::Callback<bool(void)>& make_context_current) | 256 const base::Callback<bool(void)>& make_context_current) |
258 : client_(NULL), | 257 : client_(NULL), |
259 make_context_current_(make_context_current), | 258 make_context_current_(make_context_current), |
260 codec_(media::kCodecH264), | 259 codec_(media::kCodecH264), |
261 is_encrypted_(false), | 260 is_encrypted_(false), |
262 needs_protected_surface_(false), | 261 needs_protected_surface_(false), |
263 state_(NO_ERROR), | 262 state_(NO_ERROR), |
264 picturebuffers_requested_(false), | 263 picturebuffers_requested_(false), |
265 gl_decoder_(decoder), | 264 gl_decoder_(decoder), |
265 media_drm_bridge_cdm_context_(nullptr), | |
266 cdm_registration_id_(0), | 266 cdm_registration_id_(0), |
267 pending_input_buf_index_(-1), | 267 pending_input_buf_index_(-1), |
268 error_sequence_token_(0), | 268 error_sequence_token_(0), |
269 defer_errors_(false), | 269 defer_errors_(false), |
270 weak_this_factory_(this) { | 270 weak_this_factory_(this) { |
271 if (UseDeferredRenderingStrategy()) { | 271 if (UseDeferredRenderingStrategy()) { |
272 // TODO(liberato, watk): Figure out what we want to do about zero copy for | 272 // TODO(liberato, watk): Figure out what we want to do about zero copy for |
273 // fullscreen external SurfaceView in WebView. http://crbug.com/582170. | 273 // fullscreen external SurfaceView in WebView. http://crbug.com/582170. |
274 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync()); | 274 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync()); |
275 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; | 275 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; |
276 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this)); | 276 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this)); |
277 } else { | 277 } else { |
278 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; | 278 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; |
279 strategy_.reset(new AndroidCopyingBackingStrategy(this)); | 279 strategy_.reset(new AndroidCopyingBackingStrategy(this)); |
280 } | 280 } |
281 } | 281 } |
282 | 282 |
283 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 283 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
284 DCHECK(thread_checker_.CalledOnValidThread()); | 284 DCHECK(thread_checker_.CalledOnValidThread()); |
285 g_avda_timer.Pointer()->StopTimer(this); | 285 g_avda_timer.Pointer()->StopTimer(this); |
286 | 286 |
287 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 287 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
288 if (cdm_) { | 288 if (!media_drm_bridge_cdm_context_) |
289 DCHECK(cdm_registration_id_); | 289 return; |
290 static_cast<media::MediaDrmBridge*>(cdm_.get()) | 290 |
291 ->UnregisterPlayer(cdm_registration_id_); | 291 DCHECK(cdm_registration_id_); |
292 } | 292 media_drm_bridge_cdm_context_->UnregisterPlayer(cdm_registration_id_); |
293 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 293 #endif // defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
294 } | 294 } |
295 | 295 |
296 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, | 296 bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, |
297 Client* client) { | 297 Client* client) { |
298 DCHECK(!media_codec_); | 298 DCHECK(!media_codec_); |
299 DCHECK(thread_checker_.CalledOnValidThread()); | 299 DCHECK(thread_checker_.CalledOnValidThread()); |
300 TRACE_EVENT0("media", "AVDA::Initialize"); | 300 TRACE_EVENT0("media", "AVDA::Initialize"); |
301 | 301 |
302 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); | 302 DVLOG(1) << __FUNCTION__ << ": " << config.AsHumanReadableString(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 if (is_encrypted_) | 358 if (is_encrypted_) |
359 return true; | 359 return true; |
360 | 360 |
361 return ConfigureMediaCodec(); | 361 return ConfigureMediaCodec(); |
362 } | 362 } |
363 | 363 |
364 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) { | 364 void AndroidVideoDecodeAccelerator::SetCdm(int cdm_id) { |
365 DVLOG(2) << __FUNCTION__ << ": " << cdm_id; | 365 DVLOG(2) << __FUNCTION__ << ": " << cdm_id; |
366 | 366 |
367 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 367 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
368 using media::MediaDrmBridge; | |
369 | |
370 DCHECK(client_) << "SetCdm() must be called after Initialize()."; | 368 DCHECK(client_) << "SetCdm() must be called after Initialize()."; |
371 | 369 |
372 if (cdm_) { | 370 if (media_drm_bridge_cdm_context_) { |
373 NOTREACHED() << "We do not support resetting CDM."; | 371 NOTREACHED() << "We do not support resetting CDM."; |
374 NotifyCdmAttached(false); | 372 NotifyCdmAttached(false); |
375 return; | 373 return; |
376 } | 374 } |
377 | 375 |
378 cdm_ = media::MojoCdmService::LegacyGetCdm(cdm_id); | 376 // Store the CDM to hold a reference to it. |
379 DCHECK(cdm_); | 377 cdm_for_reference_holding_only_ = media::MojoCdmService::LegacyGetCdm(cdm_id); |
378 DCHECK(cdm_for_reference_holding_only_); | |
380 | 379 |
381 // On Android platform the MediaKeys will be its subclass MediaDrmBridge. | 380 // On Android platform the CdmContext must be a MediaDrmBridgeCdmContext. |
ddorwin
2016/03/22 17:20:12
nit: This sounds like this is true for all instanc
| |
382 MediaDrmBridge* drm_bridge = static_cast<MediaDrmBridge*>(cdm_.get()); | 381 media_drm_bridge_cdm_context_ = static_cast<media::MediaDrmBridgeCdmContext*>( |
382 cdm_for_reference_holding_only_->GetCdmContext()); | |
383 DCHECK(media_drm_bridge_cdm_context_); | |
383 | 384 |
384 // Register CDM callbacks. The callbacks registered will be posted back to | 385 // Register CDM callbacks. The callbacks registered will be posted back to |
385 // this thread via BindToCurrentLoop. | 386 // this thread via BindToCurrentLoop. |
386 | 387 |
387 // Since |this| holds a reference to the |cdm_|, by the time the CDM is | 388 // Since |this| holds a reference to the |cdm_|, by the time the CDM is |
388 // destructed, UnregisterPlayer() must have been called and |this| has been | 389 // destructed, UnregisterPlayer() must have been called and |this| has been |
389 // destructed as well. So the |cdm_unset_cb| will never have a chance to be | 390 // destructed as well. So the |cdm_unset_cb| will never have a chance to be |
390 // called. | 391 // called. |
391 // TODO(xhwang): Remove |cdm_unset_cb| after it's not used on all platforms. | 392 // TODO(xhwang): Remove |cdm_unset_cb| after it's not used on all platforms. |
392 cdm_registration_id_ = | 393 cdm_registration_id_ = media_drm_bridge_cdm_context_->RegisterPlayer( |
393 drm_bridge->RegisterPlayer(media::BindToCurrentLoop(base::Bind( | 394 media::BindToCurrentLoop( |
394 &AndroidVideoDecodeAccelerator::OnKeyAdded, | 395 base::Bind(&AndroidVideoDecodeAccelerator::OnKeyAdded, |
395 weak_this_factory_.GetWeakPtr())), | 396 weak_this_factory_.GetWeakPtr())), |
396 base::Bind(&base::DoNothing)); | 397 base::Bind(&base::DoNothing)); |
397 | 398 |
398 drm_bridge->SetMediaCryptoReadyCB(media::BindToCurrentLoop( | 399 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB(media::BindToCurrentLoop( |
399 base::Bind(&AndroidVideoDecodeAccelerator::OnMediaCryptoReady, | 400 base::Bind(&AndroidVideoDecodeAccelerator::OnMediaCryptoReady, |
400 weak_this_factory_.GetWeakPtr()))); | 401 weak_this_factory_.GetWeakPtr()))); |
401 | 402 |
402 // Postpone NotifyCdmAttached() call till we create the MediaCodec after | 403 // Postpone NotifyCdmAttached() call till we create the MediaCodec after |
403 // OnMediaCryptoReady(). | 404 // OnMediaCryptoReady(). |
404 | |
405 #else | 405 #else |
406 | 406 |
407 NOTIMPLEMENTED(); | 407 NOTIMPLEMENTED(); |
408 NotifyCdmAttached(false); | 408 NotifyCdmAttached(false); |
409 | 409 |
410 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 410 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
411 } | 411 } |
412 | 412 |
413 void AndroidVideoDecodeAccelerator::DoIOTask() { | 413 void AndroidVideoDecodeAccelerator::DoIOTask() { |
414 DCHECK(thread_checker_.CalledOnValidThread()); | 414 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1064 media::VideoDecodeAccelerator::Error error) { | 1064 media::VideoDecodeAccelerator::Error error) { |
1065 base::MessageLoop::current()->PostDelayedTask( | 1065 base::MessageLoop::current()->PostDelayedTask( |
1066 from_here, | 1066 from_here, |
1067 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, | 1067 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, |
1068 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_), | 1068 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_), |
1069 (defer_errors_ ? ErrorPostingDelay() : base::TimeDelta())); | 1069 (defer_errors_ ? ErrorPostingDelay() : base::TimeDelta())); |
1070 state_ = ERROR; | 1070 state_ = ERROR; |
1071 } | 1071 } |
1072 | 1072 |
1073 void AndroidVideoDecodeAccelerator::OnMediaCryptoReady( | 1073 void AndroidVideoDecodeAccelerator::OnMediaCryptoReady( |
1074 media::MediaDrmBridge::JavaObjectPtr media_crypto, | 1074 media::MediaDrmBridgeCdmContext::JavaObjectPtr media_crypto, |
1075 bool needs_protected_surface) { | 1075 bool needs_protected_surface) { |
1076 DVLOG(1) << __FUNCTION__; | 1076 DVLOG(1) << __FUNCTION__; |
1077 | 1077 |
1078 if (!media_crypto) { | 1078 if (!media_crypto) { |
1079 LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream."; | 1079 LOG(ERROR) << "MediaCrypto is not available, can't play encrypted stream."; |
1080 cdm_for_reference_holding_only_ = nullptr; | |
1081 media_drm_bridge_cdm_context_ = nullptr; | |
1080 NotifyCdmAttached(false); | 1082 NotifyCdmAttached(false); |
1081 return; | 1083 return; |
1082 } | 1084 } |
1083 | 1085 |
1084 DCHECK(!media_crypto->is_null()); | 1086 DCHECK(!media_crypto->is_null()); |
1085 | 1087 |
1086 // We assume this is a part of the initialization process, thus MediaCodec | 1088 // We assume this is a part of the initialization process, thus MediaCodec |
1087 // is not created yet. | 1089 // is not created yet. |
1088 DCHECK(!media_codec_); | 1090 DCHECK(!media_codec_); |
1089 | 1091 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1200 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: | 1202 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: |
1201 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | | 1203 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | |
1202 media::VideoDecodeAccelerator::Capabilities:: | 1204 media::VideoDecodeAccelerator::Capabilities:: |
1203 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1205 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
1204 } | 1206 } |
1205 | 1207 |
1206 return capabilities; | 1208 return capabilities; |
1207 } | 1209 } |
1208 | 1210 |
1209 } // namespace content | 1211 } // namespace content |
OLD | NEW |