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

Side by Side Diff: content/renderer/media/android/webmediaplayer_android.cc

Issue 448063003: media: Fix not-thread-safe access to variables in android media code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 months 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
« no previous file with comments | « content/renderer/media/android/webmediaplayer_android.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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/renderer/media/android/webmediaplayer_android.h" 5 #include "content/renderer/media/android/webmediaplayer_android.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo()) { 153 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo()) {
154 // Defer stream texture creation until we are sure it's necessary. 154 // Defer stream texture creation until we are sure it's necessary.
155 needs_establish_peer_ = false; 155 needs_establish_peer_ = false;
156 current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1)); 156 current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1));
157 } 157 }
158 #endif // defined(VIDEO_HOLE) 158 #endif // defined(VIDEO_HOLE)
159 TryCreateStreamTextureProxyIfNeeded(); 159 TryCreateStreamTextureProxyIfNeeded();
160 } 160 }
161 161
162 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { 162 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
163 DCHECK(main_thread_checker_.CalledOnValidThread());
163 SetVideoFrameProviderClient(NULL); 164 SetVideoFrameProviderClient(NULL);
164 client_->setWebLayer(NULL); 165 client_->setWebLayer(NULL);
165 166
166 if (player_manager_) { 167 if (player_manager_) {
167 player_manager_->DestroyPlayer(player_id_); 168 player_manager_->DestroyPlayer(player_id_);
168 player_manager_->UnregisterMediaPlayer(player_id_); 169 player_manager_->UnregisterMediaPlayer(player_id_);
169 } 170 }
170 171
171 if (stream_id_) { 172 if (stream_id_) {
172 GLES2Interface* gl = stream_texture_factory_->ContextGL(); 173 GLES2Interface* gl = stream_texture_factory_->ContextGL();
173 gl->DeleteTextures(1, &texture_id_); 174 gl->DeleteTextures(1, &texture_id_);
174 texture_id_ = 0; 175 texture_id_ = 0;
175 texture_mailbox_ = gpu::Mailbox(); 176 texture_mailbox_ = gpu::Mailbox();
176 stream_id_ = 0; 177 stream_id_ = 0;
177 } 178 }
178 179
179 { 180 {
180 base::AutoLock auto_lock(current_frame_lock_); 181 base::AutoLock auto_lock(current_frame_lock_);
181 current_frame_ = NULL; 182 current_frame_ = NULL;
182 } 183 }
183 184
184 if (player_type_ == MEDIA_PLAYER_TYPE_MEDIA_SOURCE && delegate_) 185 if (player_type_ == MEDIA_PLAYER_TYPE_MEDIA_SOURCE && delegate_)
185 delegate_->PlayerGone(this); 186 delegate_->PlayerGone(this);
186 } 187 }
187 188
188 void WebMediaPlayerAndroid::load(LoadType load_type, 189 void WebMediaPlayerAndroid::load(LoadType load_type,
189 const blink::WebURL& url, 190 const blink::WebURL& url,
190 CORSMode cors_mode) { 191 CORSMode cors_mode) {
192 DCHECK(main_thread_checker_.CalledOnValidThread());
191 ReportMediaSchemeUma(GURL(url)); 193 ReportMediaSchemeUma(GURL(url));
192 194
193 switch (load_type) { 195 switch (load_type) {
194 case LoadTypeURL: 196 case LoadTypeURL:
195 player_type_ = MEDIA_PLAYER_TYPE_URL; 197 player_type_ = MEDIA_PLAYER_TYPE_URL;
196 break; 198 break;
197 199
198 case LoadTypeMediaSource: 200 case LoadTypeMediaSource:
199 player_type_ = MEDIA_PLAYER_TYPE_MEDIA_SOURCE; 201 player_type_ = MEDIA_PLAYER_TYPE_MEDIA_SOURCE;
200 break; 202 break;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 } 251 }
250 252
251 if (player_manager_->ShouldEnterFullscreen(frame_)) 253 if (player_manager_->ShouldEnterFullscreen(frame_))
252 player_manager_->EnterFullscreen(player_id_, frame_); 254 player_manager_->EnterFullscreen(player_id_, frame_);
253 255
254 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); 256 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
255 UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing); 257 UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing);
256 } 258 }
257 259
258 void WebMediaPlayerAndroid::DidLoadMediaInfo(MediaInfoLoader::Status status) { 260 void WebMediaPlayerAndroid::DidLoadMediaInfo(MediaInfoLoader::Status status) {
261 DCHECK(main_thread_checker_.CalledOnValidThread());
259 DCHECK(!media_source_delegate_); 262 DCHECK(!media_source_delegate_);
260 if (status == MediaInfoLoader::kFailed) { 263 if (status == MediaInfoLoader::kFailed) {
261 info_loader_.reset(); 264 info_loader_.reset();
262 UpdateNetworkState(WebMediaPlayer::NetworkStateNetworkError); 265 UpdateNetworkState(WebMediaPlayer::NetworkStateNetworkError);
263 return; 266 return;
264 } 267 }
265 268
266 InitializePlayer(0); 269 InitializePlayer(0);
267 270
268 UpdateNetworkState(WebMediaPlayer::NetworkStateIdle); 271 UpdateNetworkState(WebMediaPlayer::NetworkStateIdle);
269 } 272 }
270 273
271 void WebMediaPlayerAndroid::play() { 274 void WebMediaPlayerAndroid::play() {
275 DCHECK(main_thread_checker_.CalledOnValidThread());
272 #if defined(VIDEO_HOLE) 276 #if defined(VIDEO_HOLE)
273 if (hasVideo() && needs_external_surface_ && 277 if (hasVideo() && needs_external_surface_ &&
274 !player_manager_->IsInFullscreen(frame_)) { 278 !player_manager_->IsInFullscreen(frame_)) {
275 DCHECK(!needs_establish_peer_); 279 DCHECK(!needs_establish_peer_);
276 player_manager_->RequestExternalSurface(player_id_, last_computed_rect_); 280 player_manager_->RequestExternalSurface(player_id_, last_computed_rect_);
277 } 281 }
278 #endif // defined(VIDEO_HOLE) 282 #endif // defined(VIDEO_HOLE)
279 283
280 TryCreateStreamTextureProxyIfNeeded(); 284 TryCreateStreamTextureProxyIfNeeded();
281 // There is no need to establish the surface texture peer for fullscreen 285 // There is no need to establish the surface texture peer for fullscreen
282 // video. 286 // video.
283 if (hasVideo() && needs_establish_peer_ && 287 if (hasVideo() && needs_establish_peer_ &&
284 !player_manager_->IsInFullscreen(frame_)) { 288 !player_manager_->IsInFullscreen(frame_)) {
285 EstablishSurfaceTexturePeer(); 289 EstablishSurfaceTexturePeer();
286 } 290 }
287 291
288 if (paused()) 292 if (paused())
289 player_manager_->Start(player_id_); 293 player_manager_->Start(player_id_);
290 UpdatePlayingState(true); 294 UpdatePlayingState(true);
291 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); 295 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
292 } 296 }
293 297
294 void WebMediaPlayerAndroid::pause() { 298 void WebMediaPlayerAndroid::pause() {
299 DCHECK(main_thread_checker_.CalledOnValidThread());
295 Pause(true); 300 Pause(true);
296 } 301 }
297 302
298 void WebMediaPlayerAndroid::seek(double seconds) { 303 void WebMediaPlayerAndroid::seek(double seconds) {
299 DCHECK(main_thread_checker_.CalledOnValidThread()); 304 DCHECK(main_thread_checker_.CalledOnValidThread());
300 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")"; 305 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")";
301 306
302 base::TimeDelta new_seek_time = ConvertSecondsToTimestamp(seconds); 307 base::TimeDelta new_seek_time = ConvertSecondsToTimestamp(seconds);
303 308
304 if (seeking_) { 309 if (seeking_) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 346
342 bool WebMediaPlayerAndroid::supportsSave() const { 347 bool WebMediaPlayerAndroid::supportsSave() const {
343 return false; 348 return false;
344 } 349 }
345 350
346 void WebMediaPlayerAndroid::setRate(double rate) { 351 void WebMediaPlayerAndroid::setRate(double rate) {
347 NOTIMPLEMENTED(); 352 NOTIMPLEMENTED();
348 } 353 }
349 354
350 void WebMediaPlayerAndroid::setVolume(double volume) { 355 void WebMediaPlayerAndroid::setVolume(double volume) {
356 DCHECK(main_thread_checker_.CalledOnValidThread());
351 player_manager_->SetVolume(player_id_, volume); 357 player_manager_->SetVolume(player_id_, volume);
352 } 358 }
353 359
354 bool WebMediaPlayerAndroid::hasVideo() const { 360 bool WebMediaPlayerAndroid::hasVideo() const {
361 DCHECK(main_thread_checker_.CalledOnValidThread());
355 // If we have obtained video size information before, use it. 362 // If we have obtained video size information before, use it.
356 if (has_size_info_) 363 if (has_size_info_)
357 return !natural_size_.isEmpty(); 364 return !natural_size_.isEmpty();
358 365
359 // TODO(qinmin): need a better method to determine whether the current media 366 // TODO(qinmin): need a better method to determine whether the current media
360 // content contains video. Android does not provide any function to do 367 // content contains video. Android does not provide any function to do
361 // this. 368 // this.
362 // We don't know whether the current media content has video unless 369 // We don't know whether the current media content has video unless
363 // the player is prepared. If the player is not prepared, we fall back 370 // the player is prepared. If the player is not prepared, we fall back
364 // to the mime-type. There may be no mime-type on a redirect URL. 371 // to the mime-type. There may be no mime-type on a redirect URL.
365 // In that case, we conservatively assume it contains video so that 372 // In that case, we conservatively assume it contains video so that
366 // enterfullscreen call will not fail. 373 // enterfullscreen call will not fail.
367 if (!url_.has_path()) 374 if (!url_.has_path())
368 return false; 375 return false;
369 std::string mime; 376 std::string mime;
370 if (!net::GetMimeTypeFromFile(base::FilePath(url_.path()), &mime)) 377 if (!net::GetMimeTypeFromFile(base::FilePath(url_.path()), &mime))
371 return true; 378 return true;
372 return mime.find("audio/") == std::string::npos; 379 return mime.find("audio/") == std::string::npos;
373 } 380 }
374 381
375 bool WebMediaPlayerAndroid::hasAudio() const { 382 bool WebMediaPlayerAndroid::hasAudio() const {
383 DCHECK(main_thread_checker_.CalledOnValidThread());
376 if (!url_.has_path()) 384 if (!url_.has_path())
377 return false; 385 return false;
378 std::string mime; 386 std::string mime;
379 if (!net::GetMimeTypeFromFile(base::FilePath(url_.path()), &mime)) 387 if (!net::GetMimeTypeFromFile(base::FilePath(url_.path()), &mime))
380 return true; 388 return true;
381 389
382 if (mime.find("audio/") != std::string::npos || 390 if (mime.find("audio/") != std::string::npos ||
383 mime.find("video/") != std::string::npos || 391 mime.find("video/") != std::string::npos ||
384 mime.find("application/ogg") != std::string::npos) { 392 mime.find("application/ogg") != std::string::npos) {
385 return true; 393 return true;
386 } 394 }
387 return false; 395 return false;
388 } 396 }
389 397
390 bool WebMediaPlayerAndroid::paused() const { 398 bool WebMediaPlayerAndroid::paused() const {
391 return !is_playing_; 399 return !is_playing_;
392 } 400 }
393 401
394 bool WebMediaPlayerAndroid::seeking() const { 402 bool WebMediaPlayerAndroid::seeking() const {
395 return seeking_; 403 return seeking_;
396 } 404 }
397 405
398 double WebMediaPlayerAndroid::duration() const { 406 double WebMediaPlayerAndroid::duration() const {
407 DCHECK(main_thread_checker_.CalledOnValidThread());
399 // HTML5 spec requires duration to be NaN if readyState is HAVE_NOTHING 408 // HTML5 spec requires duration to be NaN if readyState is HAVE_NOTHING
400 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) 409 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing)
401 return std::numeric_limits<double>::quiet_NaN(); 410 return std::numeric_limits<double>::quiet_NaN();
402 411
403 if (duration_ == media::kInfiniteDuration()) 412 if (duration_ == media::kInfiniteDuration())
404 return std::numeric_limits<double>::infinity(); 413 return std::numeric_limits<double>::infinity();
405 414
406 return duration_.InSecondsF(); 415 return duration_.InSecondsF();
407 } 416 }
408 417
409 double WebMediaPlayerAndroid::timelineOffset() const { 418 double WebMediaPlayerAndroid::timelineOffset() const {
419 DCHECK(main_thread_checker_.CalledOnValidThread());
410 base::Time timeline_offset; 420 base::Time timeline_offset;
411 if (media_source_delegate_) 421 if (media_source_delegate_)
412 timeline_offset = media_source_delegate_->GetTimelineOffset(); 422 timeline_offset = media_source_delegate_->GetTimelineOffset();
413 423
414 if (timeline_offset.is_null()) 424 if (timeline_offset.is_null())
415 return std::numeric_limits<double>::quiet_NaN(); 425 return std::numeric_limits<double>::quiet_NaN();
416 426
417 return timeline_offset.ToJsTime(); 427 return timeline_offset.ToJsTime();
418 } 428 }
419 429
420 double WebMediaPlayerAndroid::currentTime() const { 430 double WebMediaPlayerAndroid::currentTime() const {
431 DCHECK(main_thread_checker_.CalledOnValidThread());
421 // If the player is processing a seek, return the seek time. 432 // If the player is processing a seek, return the seek time.
422 // Blink may still query us if updatePlaybackState() occurs while seeking. 433 // Blink may still query us if updatePlaybackState() occurs while seeking.
423 if (seeking()) { 434 if (seeking()) {
424 return pending_seek_ ? 435 return pending_seek_ ?
425 pending_seek_time_.InSecondsF() : seek_time_.InSecondsF(); 436 pending_seek_time_.InSecondsF() : seek_time_.InSecondsF();
426 } 437 }
427 438
428 return current_time_; 439 return current_time_;
429 } 440 }
430 441
(...skipping 28 matching lines...) Expand all
459 bool ret = did_loading_progress_; 470 bool ret = did_loading_progress_;
460 did_loading_progress_ = false; 471 did_loading_progress_ = false;
461 return ret; 472 return ret;
462 } 473 }
463 474
464 bool WebMediaPlayerAndroid::EnsureTextureBackedSkBitmap(GrContext* gr, 475 bool WebMediaPlayerAndroid::EnsureTextureBackedSkBitmap(GrContext* gr,
465 SkBitmap& bitmap, 476 SkBitmap& bitmap,
466 const WebSize& size, 477 const WebSize& size,
467 GrSurfaceOrigin origin, 478 GrSurfaceOrigin origin,
468 GrPixelConfig config) { 479 GrPixelConfig config) {
480 DCHECK(main_thread_checker_.CalledOnValidThread());
469 if (!bitmap.getTexture() || bitmap.width() != size.width 481 if (!bitmap.getTexture() || bitmap.width() != size.width
470 || bitmap.height() != size.height) { 482 || bitmap.height() != size.height) {
471 if (!gr) 483 if (!gr)
472 return false; 484 return false;
473 GrTextureDesc desc; 485 GrTextureDesc desc;
474 desc.fConfig = config; 486 desc.fConfig = config;
475 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 487 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
476 desc.fSampleCnt = 0; 488 desc.fSampleCnt = 0;
477 desc.fOrigin = origin; 489 desc.fOrigin = origin;
478 desc.fWidth = size.width; 490 desc.fWidth = size.width;
(...skipping 10 matching lines...) Expand all
489 bitmap.setInfo(info); 501 bitmap.setInfo(info);
490 bitmap.setPixelRef(pixelRef)->unref(); 502 bitmap.setPixelRef(pixelRef)->unref();
491 } 503 }
492 504
493 return true; 505 return true;
494 } 506 }
495 507
496 void WebMediaPlayerAndroid::paint(blink::WebCanvas* canvas, 508 void WebMediaPlayerAndroid::paint(blink::WebCanvas* canvas,
497 const blink::WebRect& rect, 509 const blink::WebRect& rect,
498 unsigned char alpha) { 510 unsigned char alpha) {
511 DCHECK(main_thread_checker_.CalledOnValidThread());
499 scoped_ptr<blink::WebGraphicsContext3DProvider> provider = 512 scoped_ptr<blink::WebGraphicsContext3DProvider> provider =
500 scoped_ptr<blink::WebGraphicsContext3DProvider>(blink::Platform::current( 513 scoped_ptr<blink::WebGraphicsContext3DProvider>(blink::Platform::current(
501 )->createSharedOffscreenGraphicsContext3DProvider()); 514 )->createSharedOffscreenGraphicsContext3DProvider());
502 if (!provider) 515 if (!provider)
503 return; 516 return;
504 blink::WebGraphicsContext3D* context3D = provider->context3d(); 517 blink::WebGraphicsContext3D* context3D = provider->context3d();
505 if (!context3D || !context3D->makeContextCurrent()) 518 if (!context3D || !context3D->makeContextCurrent())
506 return; 519 return;
507 520
508 // Copy video texture into a RGBA texture based bitmap first as video texture 521 // Copy video texture into a RGBA texture based bitmap first as video texture
(...skipping 28 matching lines...) Expand all
537 } 550 }
538 551
539 bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture( 552 bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture(
540 blink::WebGraphicsContext3D* web_graphics_context, 553 blink::WebGraphicsContext3D* web_graphics_context,
541 unsigned int texture, 554 unsigned int texture,
542 unsigned int level, 555 unsigned int level,
543 unsigned int internal_format, 556 unsigned int internal_format,
544 unsigned int type, 557 unsigned int type,
545 bool premultiply_alpha, 558 bool premultiply_alpha,
546 bool flip_y) { 559 bool flip_y) {
560 DCHECK(main_thread_checker_.CalledOnValidThread());
547 // Don't allow clients to copy an encrypted video frame. 561 // Don't allow clients to copy an encrypted video frame.
548 if (needs_external_surface_) 562 if (needs_external_surface_)
549 return false; 563 return false;
550 564
551 scoped_refptr<VideoFrame> video_frame; 565 scoped_refptr<VideoFrame> video_frame;
552 { 566 {
553 base::AutoLock auto_lock(current_frame_lock_); 567 base::AutoLock auto_lock(current_frame_lock_);
554 video_frame = current_frame_; 568 video_frame = current_frame_;
555 } 569 }
556 570
557 if (!video_frame || 571 if (!video_frame ||
558 video_frame->format() != media::VideoFrame::NATIVE_TEXTURE) 572 video_frame->format() != media::VideoFrame::NATIVE_TEXTURE)
559 return false; 573 return false;
560 const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder(); 574 const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder();
561 DCHECK((!is_remote_ && 575 DCHECK((!is_remote_ &&
562 mailbox_holder->texture_target == GL_TEXTURE_EXTERNAL_OES) || 576 mailbox_holder->texture_target == GL_TEXTURE_EXTERNAL_OES) ||
563 (is_remote_ && mailbox_holder->texture_target == GL_TEXTURE_2D)); 577 (is_remote_ && mailbox_holder->texture_target == GL_TEXTURE_2D));
564 578
565 // For hidden video element (with style "display:none"), ensure the texture
566 // size is set.
567 if (!is_remote_ &&
568 (cached_stream_texture_size_.width != natural_size_.width ||
569 cached_stream_texture_size_.height != natural_size_.height)) {
570 stream_texture_factory_->SetStreamTextureSize(
571 stream_id_, gfx::Size(natural_size_.width, natural_size_.height));
572 cached_stream_texture_size_ = natural_size_;
573 }
574
575 web_graphics_context->waitSyncPoint(mailbox_holder->sync_point); 579 web_graphics_context->waitSyncPoint(mailbox_holder->sync_point);
576 580
577 // Ensure the target of texture is set before copyTextureCHROMIUM, otherwise 581 // Ensure the target of texture is set before copyTextureCHROMIUM, otherwise
578 // an invalid texture target may be used for copy texture. 582 // an invalid texture target may be used for copy texture.
579 uint32 src_texture = web_graphics_context->createAndConsumeTextureCHROMIUM( 583 uint32 src_texture = web_graphics_context->createAndConsumeTextureCHROMIUM(
580 mailbox_holder->texture_target, mailbox_holder->mailbox.name); 584 mailbox_holder->texture_target, mailbox_holder->mailbox.name);
581 585
582 // The video is stored in an unmultiplied format, so premultiply if 586 // The video is stored in an unmultiplied format, so premultiply if
583 // necessary. 587 // necessary.
584 web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, 588 web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM,
(...skipping 13 matching lines...) Expand all
598 602
599 web_graphics_context->deleteTexture(src_texture); 603 web_graphics_context->deleteTexture(src_texture);
600 web_graphics_context->flush(); 604 web_graphics_context->flush();
601 605
602 SyncPointClientImpl client(web_graphics_context); 606 SyncPointClientImpl client(web_graphics_context);
603 video_frame->UpdateReleaseSyncPoint(&client); 607 video_frame->UpdateReleaseSyncPoint(&client);
604 return true; 608 return true;
605 } 609 }
606 610
607 bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const { 611 bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const {
612 DCHECK(main_thread_checker_.CalledOnValidThread());
608 if (info_loader_) 613 if (info_loader_)
609 return info_loader_->HasSingleOrigin(); 614 return info_loader_->HasSingleOrigin();
610 // The info loader may have failed. 615 // The info loader may have failed.
611 if (player_type_ == MEDIA_PLAYER_TYPE_URL) 616 if (player_type_ == MEDIA_PLAYER_TYPE_URL)
612 return false; 617 return false;
613 return true; 618 return true;
614 } 619 }
615 620
616 bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const { 621 bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const {
622 DCHECK(main_thread_checker_.CalledOnValidThread());
617 if (info_loader_) 623 if (info_loader_)
618 return info_loader_->DidPassCORSAccessCheck(); 624 return info_loader_->DidPassCORSAccessCheck();
619 return false; 625 return false;
620 } 626 }
621 627
622 double WebMediaPlayerAndroid::mediaTimeForTimeValue(double timeValue) const { 628 double WebMediaPlayerAndroid::mediaTimeForTimeValue(double timeValue) const {
623 return ConvertSecondsToTimestamp(timeValue).InSecondsF(); 629 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
624 } 630 }
625 631
626 unsigned WebMediaPlayerAndroid::decodedFrameCount() const { 632 unsigned WebMediaPlayerAndroid::decodedFrameCount() const {
(...skipping 19 matching lines...) Expand all
646 652
647 unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const { 653 unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const {
648 if (media_source_delegate_) 654 if (media_source_delegate_)
649 return media_source_delegate_->VideoDecodedByteCount(); 655 return media_source_delegate_->VideoDecodedByteCount();
650 NOTIMPLEMENTED(); 656 NOTIMPLEMENTED();
651 return 0; 657 return 0;
652 } 658 }
653 659
654 void WebMediaPlayerAndroid::OnMediaMetadataChanged( 660 void WebMediaPlayerAndroid::OnMediaMetadataChanged(
655 const base::TimeDelta& duration, int width, int height, bool success) { 661 const base::TimeDelta& duration, int width, int height, bool success) {
662 DCHECK(main_thread_checker_.CalledOnValidThread());
656 bool need_to_signal_duration_changed = false; 663 bool need_to_signal_duration_changed = false;
657 664
658 if (url_.SchemeIs("file")) 665 if (url_.SchemeIs("file"))
659 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded); 666 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded);
660 667
661 // Update duration, if necessary, prior to ready state updates that may 668 // Update duration, if necessary, prior to ready state updates that may
662 // cause duration() query. 669 // cause duration() query.
663 if (!ignore_metadata_duration_change_ && duration_ != duration) { 670 if (!ignore_metadata_duration_change_ && duration_ != duration) {
664 duration_ = duration; 671 duration_ = duration;
665 672
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 case MediaPlayerAndroid::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: 756 case MediaPlayerAndroid::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
750 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError); 757 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError);
751 break; 758 break;
752 case MediaPlayerAndroid::MEDIA_ERROR_INVALID_CODE: 759 case MediaPlayerAndroid::MEDIA_ERROR_INVALID_CODE:
753 break; 760 break;
754 } 761 }
755 client_->repaint(); 762 client_->repaint();
756 } 763 }
757 764
758 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) { 765 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) {
766 DCHECK(main_thread_checker_.CalledOnValidThread());
759 has_size_info_ = true; 767 has_size_info_ = true;
760 if (natural_size_.width == width && natural_size_.height == height) 768 if (natural_size_.width == width && natural_size_.height == height)
761 return; 769 return;
762 770
763 #if defined(VIDEO_HOLE) 771 #if defined(VIDEO_HOLE)
764 // Use H/W surface for encrypted video. 772 // Use H/W surface for encrypted video.
765 // TODO(qinmin): Change this so that only EME needs the H/W surface 773 // TODO(qinmin): Change this so that only EME needs the H/W surface
766 if (force_use_overlay_embedded_video_ || 774 if (force_use_overlay_embedded_video_ ||
767 (media_source_delegate_ && media_source_delegate_->IsVideoEncrypted() && 775 (media_source_delegate_ && media_source_delegate_->IsVideoEncrypted() &&
768 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo())) { 776 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo())) {
(...skipping 11 matching lines...) Expand all
780 // may play without a surface texture. When we finally get the valid video 788 // may play without a surface texture. When we finally get the valid video
781 // size here, we should call EstablishSurfaceTexturePeer() if it has not been 789 // size here, we should call EstablishSurfaceTexturePeer() if it has not been
782 // previously called. 790 // previously called.
783 if (!paused() && needs_establish_peer_) 791 if (!paused() && needs_establish_peer_)
784 EstablishSurfaceTexturePeer(); 792 EstablishSurfaceTexturePeer();
785 793
786 natural_size_.width = width; 794 natural_size_.width = width;
787 natural_size_.height = height; 795 natural_size_.height = height;
788 ReallocateVideoFrame(); 796 ReallocateVideoFrame();
789 797
798 // For hidden video element (with style "display:none"), ensure the texture
799 // size is set.
800 if (!is_remote_) {
801 stream_texture_factory_->SetStreamTextureSize(
802 stream_id_, gfx::Size(natural_size_.width, natural_size_.height));
803 }
804
790 // Lazily allocate compositing layer. 805 // Lazily allocate compositing layer.
791 if (!video_weblayer_) { 806 if (!video_weblayer_) {
792 video_weblayer_.reset(new WebLayerImpl(cc::VideoLayer::Create(this))); 807 video_weblayer_.reset(new WebLayerImpl(cc::VideoLayer::Create(this)));
793 client_->setWebLayer(video_weblayer_.get()); 808 client_->setWebLayer(video_weblayer_.get());
794 } 809 }
795 810
796 // TODO(qinmin): This is a hack. We need the media element to stop showing the 811 // TODO(qinmin): This is a hack. We need the media element to stop showing the
797 // poster image by forcing it to call setDisplayMode(video). Should move the 812 // poster image by forcing it to call setDisplayMode(video). Should move the
798 // logic into HTMLMediaElement.cpp. 813 // logic into HTMLMediaElement.cpp.
799 client_->timeChanged(); 814 client_->timeChanged();
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 frame_->document().url()); 962 frame_->document().url());
948 } 963 }
949 964
950 void WebMediaPlayerAndroid::Pause(bool is_media_related_action) { 965 void WebMediaPlayerAndroid::Pause(bool is_media_related_action) {
951 player_manager_->Pause(player_id_, is_media_related_action); 966 player_manager_->Pause(player_id_, is_media_related_action);
952 UpdatePlayingState(false); 967 UpdatePlayingState(false);
953 } 968 }
954 969
955 void WebMediaPlayerAndroid::DrawRemotePlaybackText( 970 void WebMediaPlayerAndroid::DrawRemotePlaybackText(
956 const std::string& remote_playback_message) { 971 const std::string& remote_playback_message) {
957
958 DCHECK(main_thread_checker_.CalledOnValidThread()); 972 DCHECK(main_thread_checker_.CalledOnValidThread());
959 if (!video_weblayer_) 973 if (!video_weblayer_)
960 return; 974 return;
961 975
962 // TODO(johnme): Should redraw this frame if the layer bounds change; but 976 // TODO(johnme): Should redraw this frame if the layer bounds change; but
963 // there seems no easy way to listen for the layer resizing (as opposed to 977 // there seems no easy way to listen for the layer resizing (as opposed to
964 // OnVideoSizeChanged, which is when the frame sizes of the video file 978 // OnVideoSizeChanged, which is when the frame sizes of the video file
965 // change). Perhaps have to poll (on main thread of course)? 979 // change). Perhaps have to poll (on main thread of course)?
966 gfx::Size video_size_css_px = video_weblayer_->bounds(); 980 gfx::Size video_size_css_px = video_weblayer_->bounds();
967 float device_scale_factor = frame_->view()->deviceScaleFactor(); 981 float device_scale_factor = frame_->view()->deviceScaleFactor();
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 remote_playback_texture_id)), 1083 remote_playback_texture_id)),
1070 canvas_size /* coded_size */, 1084 canvas_size /* coded_size */,
1071 gfx::Rect(canvas_size) /* visible_rect */, 1085 gfx::Rect(canvas_size) /* visible_rect */,
1072 canvas_size /* natural_size */, 1086 canvas_size /* natural_size */,
1073 base::TimeDelta() /* timestamp */, 1087 base::TimeDelta() /* timestamp */,
1074 VideoFrame::ReadPixelsCB()); 1088 VideoFrame::ReadPixelsCB());
1075 SetCurrentFrameInternal(new_frame); 1089 SetCurrentFrameInternal(new_frame);
1076 } 1090 }
1077 1091
1078 void WebMediaPlayerAndroid::ReallocateVideoFrame() { 1092 void WebMediaPlayerAndroid::ReallocateVideoFrame() {
1093 DCHECK(main_thread_checker_.CalledOnValidThread());
1079 if (needs_external_surface_) { 1094 if (needs_external_surface_) {
1080 // VideoFrame::CreateHoleFrame is only defined under VIDEO_HOLE. 1095 // VideoFrame::CreateHoleFrame is only defined under VIDEO_HOLE.
1081 #if defined(VIDEO_HOLE) 1096 #if defined(VIDEO_HOLE)
1082 if (!natural_size_.isEmpty()) { 1097 if (!natural_size_.isEmpty()) {
1083 scoped_refptr<VideoFrame> new_frame = 1098 scoped_refptr<VideoFrame> new_frame =
1084 VideoFrame::CreateHoleFrame(natural_size_); 1099 VideoFrame::CreateHoleFrame(natural_size_);
1085 SetCurrentFrameInternal(new_frame); 1100 SetCurrentFrameInternal(new_frame);
1086 // Force the client to grab the hole frame. 1101 // Force the client to grab the hole frame.
1087 client_->repaint(); 1102 client_->repaint();
1088 } 1103 }
(...skipping 24 matching lines...) Expand all
1113 1128
1114 void WebMediaPlayerAndroid::SetVideoFrameProviderClient( 1129 void WebMediaPlayerAndroid::SetVideoFrameProviderClient(
1115 cc::VideoFrameProvider::Client* client) { 1130 cc::VideoFrameProvider::Client* client) {
1116 // This is called from both the main renderer thread and the compositor 1131 // This is called from both the main renderer thread and the compositor
1117 // thread (when the main thread is blocked). 1132 // thread (when the main thread is blocked).
1118 if (video_frame_provider_client_) 1133 if (video_frame_provider_client_)
1119 video_frame_provider_client_->StopUsingProvider(); 1134 video_frame_provider_client_->StopUsingProvider();
1120 video_frame_provider_client_ = client; 1135 video_frame_provider_client_ = client;
1121 1136
1122 // Set the callback target when a frame is produced. 1137 // Set the callback target when a frame is produced.
1123 if (stream_texture_proxy_) 1138 if (stream_texture_proxy_) {
1124 stream_texture_proxy_->SetClient(client); 1139 stream_texture_proxy_->SetClient(client);
1140 // If client exists, the compositor thread calls it. At that time,
1141 // stream_id_, needs_external_surface_, is_remote_ can be accessed because
1142 // the main thread is blocked.
1143 if (client && !stream_texture_proxy_initialized_ && stream_id_ &&
1144 !needs_external_surface_ && !is_remote_) {
1145 stream_texture_proxy_->BindToCurrentThread(stream_id_);
qinmin 2014/08/08 22:02:58 I don't think this is correct, the stream_texture_
dshwang 2014/08/09 06:01:26 As above comments, I bind the proxy to the composi
qinmin 2014/08/10 18:33:51 i see, i missed the non-null check on client. On
1146 stream_texture_proxy_initialized_ = true;
1147 }
1148 }
1125 } 1149 }
1126 1150
1127 void WebMediaPlayerAndroid::SetCurrentFrameInternal( 1151 void WebMediaPlayerAndroid::SetCurrentFrameInternal(
1128 scoped_refptr<media::VideoFrame>& video_frame) { 1152 scoped_refptr<media::VideoFrame>& video_frame) {
1153 DCHECK(main_thread_checker_.CalledOnValidThread());
1129 base::AutoLock auto_lock(current_frame_lock_); 1154 base::AutoLock auto_lock(current_frame_lock_);
1130 current_frame_ = video_frame; 1155 current_frame_ = video_frame;
1131 } 1156 }
1132 1157
1133 scoped_refptr<media::VideoFrame> WebMediaPlayerAndroid::GetCurrentFrame() { 1158 scoped_refptr<media::VideoFrame> WebMediaPlayerAndroid::GetCurrentFrame() {
1134 scoped_refptr<VideoFrame> video_frame; 1159 scoped_refptr<VideoFrame> video_frame;
1135 { 1160 {
1136 base::AutoLock auto_lock(current_frame_lock_); 1161 base::AutoLock auto_lock(current_frame_lock_);
1137 video_frame = current_frame_; 1162 video_frame = current_frame_;
1138 } 1163 }
1139 1164
1140 if (!stream_texture_proxy_initialized_ && stream_texture_proxy_ &&
1141 stream_id_ && !needs_external_surface_ && !is_remote_) {
1142 gfx::Size natural_size = video_frame->natural_size();
1143 // TODO(sievers): These variables are accessed on the wrong thread here.
1144 stream_texture_proxy_->BindToCurrentThread(stream_id_);
1145 stream_texture_factory_->SetStreamTextureSize(stream_id_, natural_size);
1146 stream_texture_proxy_initialized_ = true;
1147 cached_stream_texture_size_ = natural_size;
1148 }
1149
1150 return video_frame; 1165 return video_frame;
1151 } 1166 }
1152 1167
1153 void WebMediaPlayerAndroid::PutCurrentFrame( 1168 void WebMediaPlayerAndroid::PutCurrentFrame(
1154 const scoped_refptr<media::VideoFrame>& frame) { 1169 const scoped_refptr<media::VideoFrame>& frame) {
1155 } 1170 }
1156 1171
1157 void WebMediaPlayerAndroid::TryCreateStreamTextureProxyIfNeeded() { 1172 void WebMediaPlayerAndroid::TryCreateStreamTextureProxyIfNeeded() {
1173 DCHECK(main_thread_checker_.CalledOnValidThread());
1158 // Already created. 1174 // Already created.
1159 if (stream_texture_proxy_) 1175 if (stream_texture_proxy_)
1160 return; 1176 return;
1161 1177
1162 // No factory to create proxy. 1178 // No factory to create proxy.
1163 if (!stream_texture_factory_) 1179 if (!stream_texture_factory_)
1164 return; 1180 return;
1165 1181
1166 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy()); 1182 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy());
1167 if (needs_establish_peer_ && stream_texture_proxy_) { 1183 if (needs_establish_peer_ && stream_texture_proxy_) {
1168 DoCreateStreamTexture(); 1184 DoCreateStreamTexture();
1169 ReallocateVideoFrame(); 1185 ReallocateVideoFrame();
1170 } 1186 }
1171 1187
1172 if (stream_texture_proxy_ && video_frame_provider_client_) 1188 if (stream_texture_proxy_ && video_frame_provider_client_)
1173 stream_texture_proxy_->SetClient(video_frame_provider_client_); 1189 stream_texture_proxy_->SetClient(video_frame_provider_client_);
1174 } 1190 }
1175 1191
1176 void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() { 1192 void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() {
1193 DCHECK(main_thread_checker_.CalledOnValidThread());
1177 if (!stream_texture_proxy_) 1194 if (!stream_texture_proxy_)
1178 return; 1195 return;
1179 1196
1180 if (stream_texture_factory_.get() && stream_id_) 1197 if (stream_texture_factory_.get() && stream_id_)
1181 stream_texture_factory_->EstablishPeer(stream_id_, player_id_); 1198 stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
1182 needs_establish_peer_ = false; 1199 needs_establish_peer_ = false;
1183 } 1200 }
1184 1201
1185 void WebMediaPlayerAndroid::DoCreateStreamTexture() { 1202 void WebMediaPlayerAndroid::DoCreateStreamTexture() {
1203 DCHECK(main_thread_checker_.CalledOnValidThread());
1186 DCHECK(!stream_id_); 1204 DCHECK(!stream_id_);
1187 DCHECK(!texture_id_); 1205 DCHECK(!texture_id_);
1188 stream_id_ = stream_texture_factory_->CreateStreamTexture( 1206 stream_id_ = stream_texture_factory_->CreateStreamTexture(
1189 kGLTextureExternalOES, &texture_id_, &texture_mailbox_); 1207 kGLTextureExternalOES, &texture_id_, &texture_mailbox_);
1190 } 1208 }
1191 1209
1192 void WebMediaPlayerAndroid::SetNeedsEstablishPeer(bool needs_establish_peer) { 1210 void WebMediaPlayerAndroid::SetNeedsEstablishPeer(bool needs_establish_peer) {
1193 needs_establish_peer_ = needs_establish_peer; 1211 needs_establish_peer_ = needs_establish_peer;
1194 } 1212 }
1195 1213
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 player_manager_->EnterFullscreen(player_id_, frame_); 1620 player_manager_->EnterFullscreen(player_id_, frame_);
1603 SetNeedsEstablishPeer(false); 1621 SetNeedsEstablishPeer(false);
1604 } 1622 }
1605 } 1623 }
1606 1624
1607 bool WebMediaPlayerAndroid::canEnterFullscreen() const { 1625 bool WebMediaPlayerAndroid::canEnterFullscreen() const {
1608 return player_manager_->CanEnterFullscreen(frame_); 1626 return player_manager_->CanEnterFullscreen(frame_);
1609 } 1627 }
1610 1628
1611 } // namespace content 1629 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/android/webmediaplayer_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698