Chromium Code Reviews

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: fix errata on comment Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « no previous file | 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/android/build_info.h" 9 #include "base/android/build_info.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 145 matching lines...)
156 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo()) { 156 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo()) {
157 // Defer stream texture creation until we are sure it's necessary. 157 // Defer stream texture creation until we are sure it's necessary.
158 needs_establish_peer_ = false; 158 needs_establish_peer_ = false;
159 current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1)); 159 current_frame_ = VideoFrame::CreateBlackFrame(gfx::Size(1, 1));
160 } 160 }
161 #endif // defined(VIDEO_HOLE) 161 #endif // defined(VIDEO_HOLE)
162 TryCreateStreamTextureProxyIfNeeded(); 162 TryCreateStreamTextureProxyIfNeeded();
163 } 163 }
164 164
165 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { 165 WebMediaPlayerAndroid::~WebMediaPlayerAndroid() {
166 DCHECK(main_thread_checker_.CalledOnValidThread());
166 SetVideoFrameProviderClient(NULL); 167 SetVideoFrameProviderClient(NULL);
167 client_->setWebLayer(NULL); 168 client_->setWebLayer(NULL);
168 169
169 if (player_manager_) { 170 if (player_manager_) {
170 player_manager_->DestroyPlayer(player_id_); 171 player_manager_->DestroyPlayer(player_id_);
171 player_manager_->UnregisterMediaPlayer(player_id_); 172 player_manager_->UnregisterMediaPlayer(player_id_);
172 } 173 }
173 174
174 if (stream_id_) { 175 if (stream_id_) {
175 GLES2Interface* gl = stream_texture_factory_->ContextGL(); 176 GLES2Interface* gl = stream_texture_factory_->ContextGL();
176 gl->DeleteTextures(1, &texture_id_); 177 gl->DeleteTextures(1, &texture_id_);
177 texture_id_ = 0; 178 texture_id_ = 0;
178 texture_mailbox_ = gpu::Mailbox(); 179 texture_mailbox_ = gpu::Mailbox();
179 stream_id_ = 0; 180 stream_id_ = 0;
180 } 181 }
181 182
182 { 183 {
183 base::AutoLock auto_lock(current_frame_lock_); 184 base::AutoLock auto_lock(current_frame_lock_);
184 current_frame_ = NULL; 185 current_frame_ = NULL;
185 } 186 }
186 187
187 if (player_type_ == MEDIA_PLAYER_TYPE_MEDIA_SOURCE && delegate_) 188 if (player_type_ == MEDIA_PLAYER_TYPE_MEDIA_SOURCE && delegate_)
188 delegate_->PlayerGone(this); 189 delegate_->PlayerGone(this);
189 } 190 }
190 191
191 void WebMediaPlayerAndroid::load(LoadType load_type, 192 void WebMediaPlayerAndroid::load(LoadType load_type,
192 const blink::WebURL& url, 193 const blink::WebURL& url,
193 CORSMode cors_mode) { 194 CORSMode cors_mode) {
195 DCHECK(main_thread_checker_.CalledOnValidThread());
194 ReportMediaSchemeUma(GURL(url)); 196 ReportMediaSchemeUma(GURL(url));
195 197
196 switch (load_type) { 198 switch (load_type) {
197 case LoadTypeURL: 199 case LoadTypeURL:
198 player_type_ = MEDIA_PLAYER_TYPE_URL; 200 player_type_ = MEDIA_PLAYER_TYPE_URL;
199 break; 201 break;
200 202
201 case LoadTypeMediaSource: 203 case LoadTypeMediaSource:
202 player_type_ = MEDIA_PLAYER_TYPE_MEDIA_SOURCE; 204 player_type_ = MEDIA_PLAYER_TYPE_MEDIA_SOURCE;
203 break; 205 break;
(...skipping 45 matching lines...)
249 251
250 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); 252 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
251 UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing); 253 UpdateReadyState(WebMediaPlayer::ReadyStateHaveNothing);
252 } 254 }
253 255
254 void WebMediaPlayerAndroid::DidLoadMediaInfo( 256 void WebMediaPlayerAndroid::DidLoadMediaInfo(
255 MediaInfoLoader::Status status, 257 MediaInfoLoader::Status status,
256 const GURL& redirected_url, 258 const GURL& redirected_url,
257 const GURL& first_party_for_cookies, 259 const GURL& first_party_for_cookies,
258 bool allow_stored_credentials) { 260 bool allow_stored_credentials) {
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( 269 InitializePlayer(
267 redirected_url, first_party_for_cookies, allow_stored_credentials, 0); 270 redirected_url, first_party_for_cookies, allow_stored_credentials, 0);
268 271
269 UpdateNetworkState(WebMediaPlayer::NetworkStateIdle); 272 UpdateNetworkState(WebMediaPlayer::NetworkStateIdle);
270 } 273 }
271 274
272 void WebMediaPlayerAndroid::play() { 275 void WebMediaPlayerAndroid::play() {
276 DCHECK(main_thread_checker_.CalledOnValidThread());
273 #if defined(VIDEO_HOLE) 277 #if defined(VIDEO_HOLE)
274 if (hasVideo() && needs_external_surface_ && 278 if (hasVideo() && needs_external_surface_ &&
275 !player_manager_->IsInFullscreen(frame_)) { 279 !player_manager_->IsInFullscreen(frame_)) {
276 DCHECK(!needs_establish_peer_); 280 DCHECK(!needs_establish_peer_);
277 player_manager_->RequestExternalSurface(player_id_, last_computed_rect_); 281 player_manager_->RequestExternalSurface(player_id_, last_computed_rect_);
278 } 282 }
279 #endif // defined(VIDEO_HOLE) 283 #endif // defined(VIDEO_HOLE)
280 284
281 TryCreateStreamTextureProxyIfNeeded(); 285 TryCreateStreamTextureProxyIfNeeded();
282 // There is no need to establish the surface texture peer for fullscreen 286 // There is no need to establish the surface texture peer for fullscreen
283 // video. 287 // video.
284 if (hasVideo() && needs_establish_peer_ && 288 if (hasVideo() && needs_establish_peer_ &&
285 !player_manager_->IsInFullscreen(frame_)) { 289 !player_manager_->IsInFullscreen(frame_)) {
286 EstablishSurfaceTexturePeer(); 290 EstablishSurfaceTexturePeer();
287 } 291 }
288 292
289 if (paused()) 293 if (paused())
290 player_manager_->Start(player_id_); 294 player_manager_->Start(player_id_);
291 UpdatePlayingState(true); 295 UpdatePlayingState(true);
292 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading); 296 UpdateNetworkState(WebMediaPlayer::NetworkStateLoading);
293 } 297 }
294 298
295 void WebMediaPlayerAndroid::pause() { 299 void WebMediaPlayerAndroid::pause() {
300 DCHECK(main_thread_checker_.CalledOnValidThread());
296 Pause(true); 301 Pause(true);
297 } 302 }
298 303
299 void WebMediaPlayerAndroid::seek(double seconds) { 304 void WebMediaPlayerAndroid::seek(double seconds) {
300 DCHECK(main_thread_checker_.CalledOnValidThread()); 305 DCHECK(main_thread_checker_.CalledOnValidThread());
301 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")"; 306 DVLOG(1) << __FUNCTION__ << "(" << seconds << ")";
302 307
303 base::TimeDelta new_seek_time = ConvertSecondsToTimestamp(seconds); 308 base::TimeDelta new_seek_time = ConvertSecondsToTimestamp(seconds);
304 309
305 if (seeking_) { 310 if (seeking_) {
(...skipping 36 matching lines...)
342 347
343 bool WebMediaPlayerAndroid::supportsSave() const { 348 bool WebMediaPlayerAndroid::supportsSave() const {
344 return false; 349 return false;
345 } 350 }
346 351
347 void WebMediaPlayerAndroid::setRate(double rate) { 352 void WebMediaPlayerAndroid::setRate(double rate) {
348 NOTIMPLEMENTED(); 353 NOTIMPLEMENTED();
349 } 354 }
350 355
351 void WebMediaPlayerAndroid::setVolume(double volume) { 356 void WebMediaPlayerAndroid::setVolume(double volume) {
357 DCHECK(main_thread_checker_.CalledOnValidThread());
352 player_manager_->SetVolume(player_id_, volume); 358 player_manager_->SetVolume(player_id_, volume);
353 } 359 }
354 360
355 bool WebMediaPlayerAndroid::hasVideo() const { 361 bool WebMediaPlayerAndroid::hasVideo() const {
362 DCHECK(main_thread_checker_.CalledOnValidThread());
356 // If we have obtained video size information before, use it. 363 // If we have obtained video size information before, use it.
357 if (has_size_info_) 364 if (has_size_info_)
358 return !natural_size_.isEmpty(); 365 return !natural_size_.isEmpty();
359 366
360 // TODO(qinmin): need a better method to determine whether the current media 367 // TODO(qinmin): need a better method to determine whether the current media
361 // content contains video. Android does not provide any function to do 368 // content contains video. Android does not provide any function to do
362 // this. 369 // this.
363 // We don't know whether the current media content has video unless 370 // We don't know whether the current media content has video unless
364 // the player is prepared. If the player is not prepared, we fall back 371 // the player is prepared. If the player is not prepared, we fall back
365 // to the mime-type. There may be no mime-type on a redirect URL. 372 // to the mime-type. There may be no mime-type on a redirect URL.
366 // In that case, we conservatively assume it contains video so that 373 // In that case, we conservatively assume it contains video so that
367 // enterfullscreen call will not fail. 374 // enterfullscreen call will not fail.
368 if (!url_.has_path()) 375 if (!url_.has_path())
369 return false; 376 return false;
370 std::string mime; 377 std::string mime;
371 if (!net::GetMimeTypeFromFile(base::FilePath(url_.path()), &mime)) 378 if (!net::GetMimeTypeFromFile(base::FilePath(url_.path()), &mime))
372 return true; 379 return true;
373 return mime.find("audio/") == std::string::npos; 380 return mime.find("audio/") == std::string::npos;
374 } 381 }
375 382
376 bool WebMediaPlayerAndroid::hasAudio() const { 383 bool WebMediaPlayerAndroid::hasAudio() const {
384 DCHECK(main_thread_checker_.CalledOnValidThread());
377 if (!url_.has_path()) 385 if (!url_.has_path())
378 return false; 386 return false;
379 std::string mime; 387 std::string mime;
380 if (!net::GetMimeTypeFromFile(base::FilePath(url_.path()), &mime)) 388 if (!net::GetMimeTypeFromFile(base::FilePath(url_.path()), &mime))
381 return true; 389 return true;
382 390
383 if (mime.find("audio/") != std::string::npos || 391 if (mime.find("audio/") != std::string::npos ||
384 mime.find("video/") != std::string::npos || 392 mime.find("video/") != std::string::npos ||
385 mime.find("application/ogg") != std::string::npos) { 393 mime.find("application/ogg") != std::string::npos) {
386 return true; 394 return true;
387 } 395 }
388 return false; 396 return false;
389 } 397 }
390 398
391 bool WebMediaPlayerAndroid::paused() const { 399 bool WebMediaPlayerAndroid::paused() const {
392 return !is_playing_; 400 return !is_playing_;
393 } 401 }
394 402
395 bool WebMediaPlayerAndroid::seeking() const { 403 bool WebMediaPlayerAndroid::seeking() const {
396 return seeking_; 404 return seeking_;
397 } 405 }
398 406
399 double WebMediaPlayerAndroid::duration() const { 407 double WebMediaPlayerAndroid::duration() const {
408 DCHECK(main_thread_checker_.CalledOnValidThread());
400 // HTML5 spec requires duration to be NaN if readyState is HAVE_NOTHING 409 // HTML5 spec requires duration to be NaN if readyState is HAVE_NOTHING
401 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) 410 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing)
402 return std::numeric_limits<double>::quiet_NaN(); 411 return std::numeric_limits<double>::quiet_NaN();
403 412
404 if (duration_ == media::kInfiniteDuration()) 413 if (duration_ == media::kInfiniteDuration())
405 return std::numeric_limits<double>::infinity(); 414 return std::numeric_limits<double>::infinity();
406 415
407 return duration_.InSecondsF(); 416 return duration_.InSecondsF();
408 } 417 }
409 418
410 double WebMediaPlayerAndroid::timelineOffset() const { 419 double WebMediaPlayerAndroid::timelineOffset() const {
420 DCHECK(main_thread_checker_.CalledOnValidThread());
411 base::Time timeline_offset; 421 base::Time timeline_offset;
412 if (media_source_delegate_) 422 if (media_source_delegate_)
413 timeline_offset = media_source_delegate_->GetTimelineOffset(); 423 timeline_offset = media_source_delegate_->GetTimelineOffset();
414 424
415 if (timeline_offset.is_null()) 425 if (timeline_offset.is_null())
416 return std::numeric_limits<double>::quiet_NaN(); 426 return std::numeric_limits<double>::quiet_NaN();
417 427
418 return timeline_offset.ToJsTime(); 428 return timeline_offset.ToJsTime();
419 } 429 }
420 430
421 double WebMediaPlayerAndroid::currentTime() const { 431 double WebMediaPlayerAndroid::currentTime() const {
432 DCHECK(main_thread_checker_.CalledOnValidThread());
422 // If the player is processing a seek, return the seek time. 433 // If the player is processing a seek, return the seek time.
423 // Blink may still query us if updatePlaybackState() occurs while seeking. 434 // Blink may still query us if updatePlaybackState() occurs while seeking.
424 if (seeking()) { 435 if (seeking()) {
425 return pending_seek_ ? 436 return pending_seek_ ?
426 pending_seek_time_.InSecondsF() : seek_time_.InSecondsF(); 437 pending_seek_time_.InSecondsF() : seek_time_.InSecondsF();
427 } 438 }
428 439
429 return current_time_; 440 return current_time_;
430 } 441 }
431 442
(...skipping 28 matching lines...)
460 bool ret = did_loading_progress_; 471 bool ret = did_loading_progress_;
461 did_loading_progress_ = false; 472 did_loading_progress_ = false;
462 return ret; 473 return ret;
463 } 474 }
464 475
465 bool WebMediaPlayerAndroid::EnsureTextureBackedSkBitmap(GrContext* gr, 476 bool WebMediaPlayerAndroid::EnsureTextureBackedSkBitmap(GrContext* gr,
466 SkBitmap& bitmap, 477 SkBitmap& bitmap,
467 const WebSize& size, 478 const WebSize& size,
468 GrSurfaceOrigin origin, 479 GrSurfaceOrigin origin,
469 GrPixelConfig config) { 480 GrPixelConfig config) {
481 DCHECK(main_thread_checker_.CalledOnValidThread());
470 if (!bitmap.getTexture() || bitmap.width() != size.width 482 if (!bitmap.getTexture() || bitmap.width() != size.width
471 || bitmap.height() != size.height) { 483 || bitmap.height() != size.height) {
472 if (!gr) 484 if (!gr)
473 return false; 485 return false;
474 GrTextureDesc desc; 486 GrTextureDesc desc;
475 desc.fConfig = config; 487 desc.fConfig = config;
476 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; 488 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
477 desc.fSampleCnt = 0; 489 desc.fSampleCnt = 0;
478 desc.fOrigin = origin; 490 desc.fOrigin = origin;
479 desc.fWidth = size.width; 491 desc.fWidth = size.width;
(...skipping 10 matching lines...)
490 bitmap.setInfo(info); 502 bitmap.setInfo(info);
491 bitmap.setPixelRef(pixelRef)->unref(); 503 bitmap.setPixelRef(pixelRef)->unref();
492 } 504 }
493 505
494 return true; 506 return true;
495 } 507 }
496 508
497 void WebMediaPlayerAndroid::paint(blink::WebCanvas* canvas, 509 void WebMediaPlayerAndroid::paint(blink::WebCanvas* canvas,
498 const blink::WebRect& rect, 510 const blink::WebRect& rect,
499 unsigned char alpha) { 511 unsigned char alpha) {
512 DCHECK(main_thread_checker_.CalledOnValidThread());
500 scoped_ptr<blink::WebGraphicsContext3DProvider> provider = 513 scoped_ptr<blink::WebGraphicsContext3DProvider> provider =
501 scoped_ptr<blink::WebGraphicsContext3DProvider>(blink::Platform::current( 514 scoped_ptr<blink::WebGraphicsContext3DProvider>(blink::Platform::current(
502 )->createSharedOffscreenGraphicsContext3DProvider()); 515 )->createSharedOffscreenGraphicsContext3DProvider());
503 if (!provider) 516 if (!provider)
504 return; 517 return;
505 blink::WebGraphicsContext3D* context3D = provider->context3d(); 518 blink::WebGraphicsContext3D* context3D = provider->context3d();
506 if (!context3D || !context3D->makeContextCurrent()) 519 if (!context3D || !context3D->makeContextCurrent())
507 return; 520 return;
508 521
509 // Copy video texture into a RGBA texture based bitmap first as video texture 522 // Copy video texture into a RGBA texture based bitmap first as video texture
(...skipping 28 matching lines...)
538 } 551 }
539 552
540 bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture( 553 bool WebMediaPlayerAndroid::copyVideoTextureToPlatformTexture(
541 blink::WebGraphicsContext3D* web_graphics_context, 554 blink::WebGraphicsContext3D* web_graphics_context,
542 unsigned int texture, 555 unsigned int texture,
543 unsigned int level, 556 unsigned int level,
544 unsigned int internal_format, 557 unsigned int internal_format,
545 unsigned int type, 558 unsigned int type,
546 bool premultiply_alpha, 559 bool premultiply_alpha,
547 bool flip_y) { 560 bool flip_y) {
561 DCHECK(main_thread_checker_.CalledOnValidThread());
548 // Don't allow clients to copy an encrypted video frame. 562 // Don't allow clients to copy an encrypted video frame.
549 if (needs_external_surface_) 563 if (needs_external_surface_)
550 return false; 564 return false;
551 565
552 scoped_refptr<VideoFrame> video_frame; 566 scoped_refptr<VideoFrame> video_frame;
553 { 567 {
554 base::AutoLock auto_lock(current_frame_lock_); 568 base::AutoLock auto_lock(current_frame_lock_);
555 video_frame = current_frame_; 569 video_frame = current_frame_;
556 } 570 }
557 571
558 if (!video_frame || 572 if (!video_frame ||
559 video_frame->format() != media::VideoFrame::NATIVE_TEXTURE) 573 video_frame->format() != media::VideoFrame::NATIVE_TEXTURE)
560 return false; 574 return false;
561 const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder(); 575 const gpu::MailboxHolder* mailbox_holder = video_frame->mailbox_holder();
562 DCHECK((!is_remote_ && 576 DCHECK((!is_remote_ &&
563 mailbox_holder->texture_target == GL_TEXTURE_EXTERNAL_OES) || 577 mailbox_holder->texture_target == GL_TEXTURE_EXTERNAL_OES) ||
564 (is_remote_ && mailbox_holder->texture_target == GL_TEXTURE_2D)); 578 (is_remote_ && mailbox_holder->texture_target == GL_TEXTURE_2D));
565 579
566 // For hidden video element (with style "display:none"), ensure the texture
567 // size is set.
568 if (!is_remote_ &&
569 (cached_stream_texture_size_.width != natural_size_.width ||
570 cached_stream_texture_size_.height != natural_size_.height)) {
571 stream_texture_factory_->SetStreamTextureSize(
572 stream_id_, gfx::Size(natural_size_.width, natural_size_.height));
573 cached_stream_texture_size_ = natural_size_;
574 }
575
576 web_graphics_context->waitSyncPoint(mailbox_holder->sync_point); 580 web_graphics_context->waitSyncPoint(mailbox_holder->sync_point);
577 581
578 // Ensure the target of texture is set before copyTextureCHROMIUM, otherwise 582 // Ensure the target of texture is set before copyTextureCHROMIUM, otherwise
579 // an invalid texture target may be used for copy texture. 583 // an invalid texture target may be used for copy texture.
580 uint32 src_texture = web_graphics_context->createAndConsumeTextureCHROMIUM( 584 uint32 src_texture = web_graphics_context->createAndConsumeTextureCHROMIUM(
581 mailbox_holder->texture_target, mailbox_holder->mailbox.name); 585 mailbox_holder->texture_target, mailbox_holder->mailbox.name);
582 586
583 // The video is stored in an unmultiplied format, so premultiply if 587 // The video is stored in an unmultiplied format, so premultiply if
584 // necessary. 588 // necessary.
585 web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, 589 web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM,
(...skipping 13 matching lines...)
599 603
600 web_graphics_context->deleteTexture(src_texture); 604 web_graphics_context->deleteTexture(src_texture);
601 web_graphics_context->flush(); 605 web_graphics_context->flush();
602 606
603 SyncPointClientImpl client(web_graphics_context); 607 SyncPointClientImpl client(web_graphics_context);
604 video_frame->UpdateReleaseSyncPoint(&client); 608 video_frame->UpdateReleaseSyncPoint(&client);
605 return true; 609 return true;
606 } 610 }
607 611
608 bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const { 612 bool WebMediaPlayerAndroid::hasSingleSecurityOrigin() const {
613 DCHECK(main_thread_checker_.CalledOnValidThread());
609 if (player_type_ != MEDIA_PLAYER_TYPE_URL) 614 if (player_type_ != MEDIA_PLAYER_TYPE_URL)
610 return true; 615 return true;
611 616
612 if (!info_loader_ || !info_loader_->HasSingleOrigin()) 617 if (!info_loader_ || !info_loader_->HasSingleOrigin())
613 return false; 618 return false;
614 619
615 // TODO(qinmin): The url might be redirected when android media player 620 // TODO(qinmin): The url might be redirected when android media player
616 // requests the stream. As a result, we cannot guarantee there is only 621 // requests the stream. As a result, we cannot guarantee there is only
617 // a single origin. Only if the HTTP request was made without credentials, 622 // a single origin. Only if the HTTP request was made without credentials,
618 // we will honor the return value from HasSingleSecurityOriginInternal() 623 // we will honor the return value from HasSingleSecurityOriginInternal()
619 // in pre-L android versions. 624 // in pre-L android versions.
620 // Check http://crbug.com/334204. 625 // Check http://crbug.com/334204.
621 if (!allow_stored_credentials_) 626 if (!allow_stored_credentials_)
622 return true; 627 return true;
623 628
624 return base::android::BuildInfo::GetInstance()->sdk_int() >= 629 return base::android::BuildInfo::GetInstance()->sdk_int() >=
625 kSDKVersionToSupportSecurityOriginCheck; 630 kSDKVersionToSupportSecurityOriginCheck;
626 } 631 }
627 632
628 bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const { 633 bool WebMediaPlayerAndroid::didPassCORSAccessCheck() const {
634 DCHECK(main_thread_checker_.CalledOnValidThread());
629 if (info_loader_) 635 if (info_loader_)
630 return info_loader_->DidPassCORSAccessCheck(); 636 return info_loader_->DidPassCORSAccessCheck();
631 return false; 637 return false;
632 } 638 }
633 639
634 double WebMediaPlayerAndroid::mediaTimeForTimeValue(double timeValue) const { 640 double WebMediaPlayerAndroid::mediaTimeForTimeValue(double timeValue) const {
635 return ConvertSecondsToTimestamp(timeValue).InSecondsF(); 641 return ConvertSecondsToTimestamp(timeValue).InSecondsF();
636 } 642 }
637 643
638 unsigned WebMediaPlayerAndroid::decodedFrameCount() const { 644 unsigned WebMediaPlayerAndroid::decodedFrameCount() const {
(...skipping 19 matching lines...)
658 664
659 unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const { 665 unsigned WebMediaPlayerAndroid::videoDecodedByteCount() const {
660 if (media_source_delegate_) 666 if (media_source_delegate_)
661 return media_source_delegate_->VideoDecodedByteCount(); 667 return media_source_delegate_->VideoDecodedByteCount();
662 NOTIMPLEMENTED(); 668 NOTIMPLEMENTED();
663 return 0; 669 return 0;
664 } 670 }
665 671
666 void WebMediaPlayerAndroid::OnMediaMetadataChanged( 672 void WebMediaPlayerAndroid::OnMediaMetadataChanged(
667 const base::TimeDelta& duration, int width, int height, bool success) { 673 const base::TimeDelta& duration, int width, int height, bool success) {
674 DCHECK(main_thread_checker_.CalledOnValidThread());
668 bool need_to_signal_duration_changed = false; 675 bool need_to_signal_duration_changed = false;
669 676
670 if (url_.SchemeIs("file")) 677 if (url_.SchemeIs("file"))
671 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded); 678 UpdateNetworkState(WebMediaPlayer::NetworkStateLoaded);
672 679
673 // Update duration, if necessary, prior to ready state updates that may 680 // Update duration, if necessary, prior to ready state updates that may
674 // cause duration() query. 681 // cause duration() query.
675 if (!ignore_metadata_duration_change_ && duration_ != duration) { 682 if (!ignore_metadata_duration_change_ && duration_ != duration) {
676 duration_ = duration; 683 duration_ = duration;
677 684
(...skipping 83 matching lines...)
761 case MediaPlayerAndroid::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: 768 case MediaPlayerAndroid::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
762 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError); 769 UpdateNetworkState(WebMediaPlayer::NetworkStateFormatError);
763 break; 770 break;
764 case MediaPlayerAndroid::MEDIA_ERROR_INVALID_CODE: 771 case MediaPlayerAndroid::MEDIA_ERROR_INVALID_CODE:
765 break; 772 break;
766 } 773 }
767 client_->repaint(); 774 client_->repaint();
768 } 775 }
769 776
770 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) { 777 void WebMediaPlayerAndroid::OnVideoSizeChanged(int width, int height) {
778 DCHECK(main_thread_checker_.CalledOnValidThread());
771 has_size_info_ = true; 779 has_size_info_ = true;
772 if (natural_size_.width == width && natural_size_.height == height) 780 if (natural_size_.width == width && natural_size_.height == height)
773 return; 781 return;
774 782
775 #if defined(VIDEO_HOLE) 783 #if defined(VIDEO_HOLE)
776 // Use H/W surface for encrypted video. 784 // Use H/W surface for encrypted video.
777 // TODO(qinmin): Change this so that only EME needs the H/W surface 785 // TODO(qinmin): Change this so that only EME needs the H/W surface
778 if (force_use_overlay_embedded_video_ || 786 if (force_use_overlay_embedded_video_ ||
779 (media_source_delegate_ && media_source_delegate_->IsVideoEncrypted() && 787 (media_source_delegate_ && media_source_delegate_->IsVideoEncrypted() &&
780 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo())) { 788 player_manager_->ShouldUseVideoOverlayForEmbeddedEncryptedVideo())) {
781 needs_external_surface_ = true; 789 needs_external_surface_ = true;
782 if (!paused() && !player_manager_->IsInFullscreen(frame_)) 790 if (!paused() && !player_manager_->IsInFullscreen(frame_))
783 player_manager_->RequestExternalSurface(player_id_, last_computed_rect_); 791 player_manager_->RequestExternalSurface(player_id_, last_computed_rect_);
784 } else if (stream_texture_proxy_ && !stream_id_) { 792 } else if (stream_texture_proxy_ && !stream_id_) {
785 // Do deferred stream texture creation finally. 793 // Do deferred stream texture creation finally.
786 DoCreateStreamTexture(); 794 DoCreateStreamTexture();
787 SetNeedsEstablishPeer(true); 795 SetNeedsEstablishPeer(true);
788 } 796 }
789 #endif // defined(VIDEO_HOLE) 797 #endif // defined(VIDEO_HOLE)
798 natural_size_.width = width;
799 natural_size_.height = height;
800
790 // When play() gets called, |natural_size_| may still be empty and 801 // When play() gets called, |natural_size_| may still be empty and
791 // EstablishSurfaceTexturePeer() will not get called. As a result, the video 802 // EstablishSurfaceTexturePeer() will not get called. As a result, the video
792 // may play without a surface texture. When we finally get the valid video 803 // may play without a surface texture. When we finally get the valid video
793 // size here, we should call EstablishSurfaceTexturePeer() if it has not been 804 // size here, we should call EstablishSurfaceTexturePeer() if it has not been
794 // previously called. 805 // previously called.
795 if (!paused() && needs_establish_peer_) 806 if (!paused() && needs_establish_peer_)
796 EstablishSurfaceTexturePeer(); 807 EstablishSurfaceTexturePeer();
797 808
798 natural_size_.width = width;
799 natural_size_.height = height;
800 ReallocateVideoFrame(); 809 ReallocateVideoFrame();
801 810
811 // For hidden video element (with style "display:none"), ensure the texture
812 // size is set.
813 if (!is_remote_ && cached_stream_texture_size_ != natural_size_) {
814 stream_texture_factory_->SetStreamTextureSize(
815 stream_id_, gfx::Size(natural_size_.width, natural_size_.height));
816 cached_stream_texture_size_ = natural_size_;
817 }
818
802 // Lazily allocate compositing layer. 819 // Lazily allocate compositing layer.
803 if (!video_weblayer_) { 820 if (!video_weblayer_) {
804 video_weblayer_.reset(new WebLayerImpl( 821 video_weblayer_.reset(new WebLayerImpl(
805 cc::VideoLayer::Create(this, media::VIDEO_ROTATION_0))); 822 cc::VideoLayer::Create(this, media::VIDEO_ROTATION_0)));
806 client_->setWebLayer(video_weblayer_.get()); 823 client_->setWebLayer(video_weblayer_.get());
807 } 824 }
808 825
809 // TODO(qinmin): This is a hack. We need the media element to stop showing the 826 // TODO(qinmin): This is a hack. We need the media element to stop showing the
810 // poster image by forcing it to call setDisplayMode(video). Should move the 827 // poster image by forcing it to call setDisplayMode(video). Should move the
811 // logic into HTMLMediaElement.cpp. 828 // logic into HTMLMediaElement.cpp.
(...skipping 153 matching lines...)
965 player_manager_->EnterFullscreen(player_id_, frame_); 982 player_manager_->EnterFullscreen(player_id_, frame_);
966 } 983 }
967 984
968 void WebMediaPlayerAndroid::Pause(bool is_media_related_action) { 985 void WebMediaPlayerAndroid::Pause(bool is_media_related_action) {
969 player_manager_->Pause(player_id_, is_media_related_action); 986 player_manager_->Pause(player_id_, is_media_related_action);
970 UpdatePlayingState(false); 987 UpdatePlayingState(false);
971 } 988 }
972 989
973 void WebMediaPlayerAndroid::DrawRemotePlaybackText( 990 void WebMediaPlayerAndroid::DrawRemotePlaybackText(
974 const std::string& remote_playback_message) { 991 const std::string& remote_playback_message) {
975
976 DCHECK(main_thread_checker_.CalledOnValidThread()); 992 DCHECK(main_thread_checker_.CalledOnValidThread());
977 if (!video_weblayer_) 993 if (!video_weblayer_)
978 return; 994 return;
979 995
980 // TODO(johnme): Should redraw this frame if the layer bounds change; but 996 // TODO(johnme): Should redraw this frame if the layer bounds change; but
981 // there seems no easy way to listen for the layer resizing (as opposed to 997 // there seems no easy way to listen for the layer resizing (as opposed to
982 // OnVideoSizeChanged, which is when the frame sizes of the video file 998 // OnVideoSizeChanged, which is when the frame sizes of the video file
983 // change). Perhaps have to poll (on main thread of course)? 999 // change). Perhaps have to poll (on main thread of course)?
984 gfx::Size video_size_css_px = video_weblayer_->bounds(); 1000 gfx::Size video_size_css_px = video_weblayer_->bounds();
985 float device_scale_factor = frame_->view()->deviceScaleFactor(); 1001 float device_scale_factor = frame_->view()->deviceScaleFactor();
(...skipping 101 matching lines...)
1087 remote_playback_texture_id)), 1103 remote_playback_texture_id)),
1088 canvas_size /* coded_size */, 1104 canvas_size /* coded_size */,
1089 gfx::Rect(canvas_size) /* visible_rect */, 1105 gfx::Rect(canvas_size) /* visible_rect */,
1090 canvas_size /* natural_size */, 1106 canvas_size /* natural_size */,
1091 base::TimeDelta() /* timestamp */, 1107 base::TimeDelta() /* timestamp */,
1092 VideoFrame::ReadPixelsCB()); 1108 VideoFrame::ReadPixelsCB());
1093 SetCurrentFrameInternal(new_frame); 1109 SetCurrentFrameInternal(new_frame);
1094 } 1110 }
1095 1111
1096 void WebMediaPlayerAndroid::ReallocateVideoFrame() { 1112 void WebMediaPlayerAndroid::ReallocateVideoFrame() {
1113 DCHECK(main_thread_checker_.CalledOnValidThread());
1097 if (needs_external_surface_) { 1114 if (needs_external_surface_) {
1098 // VideoFrame::CreateHoleFrame is only defined under VIDEO_HOLE. 1115 // VideoFrame::CreateHoleFrame is only defined under VIDEO_HOLE.
1099 #if defined(VIDEO_HOLE) 1116 #if defined(VIDEO_HOLE)
1100 if (!natural_size_.isEmpty()) { 1117 if (!natural_size_.isEmpty()) {
1101 scoped_refptr<VideoFrame> new_frame = 1118 scoped_refptr<VideoFrame> new_frame =
1102 VideoFrame::CreateHoleFrame(natural_size_); 1119 VideoFrame::CreateHoleFrame(natural_size_);
1103 SetCurrentFrameInternal(new_frame); 1120 SetCurrentFrameInternal(new_frame);
1104 // Force the client to grab the hole frame. 1121 // Force the client to grab the hole frame.
1105 client_->repaint(); 1122 client_->repaint();
1106 } 1123 }
(...skipping 24 matching lines...)
1131 1148
1132 void WebMediaPlayerAndroid::SetVideoFrameProviderClient( 1149 void WebMediaPlayerAndroid::SetVideoFrameProviderClient(
1133 cc::VideoFrameProvider::Client* client) { 1150 cc::VideoFrameProvider::Client* client) {
1134 // This is called from both the main renderer thread and the compositor 1151 // This is called from both the main renderer thread and the compositor
1135 // thread (when the main thread is blocked). 1152 // thread (when the main thread is blocked).
1136 if (video_frame_provider_client_) 1153 if (video_frame_provider_client_)
1137 video_frame_provider_client_->StopUsingProvider(); 1154 video_frame_provider_client_->StopUsingProvider();
1138 video_frame_provider_client_ = client; 1155 video_frame_provider_client_ = client;
1139 1156
1140 // Set the callback target when a frame is produced. 1157 // Set the callback target when a frame is produced.
1141 if (stream_texture_proxy_) 1158 if (stream_texture_proxy_) {
1142 stream_texture_proxy_->SetClient(client); 1159 stream_texture_proxy_->SetClient(client);
1160 // If client exists, the compositor thread calls it. At that time,
1161 // stream_id_, needs_external_surface_, is_remote_ can be accessed because
1162 // the main thread is blocked.
1163 if (client && !stream_texture_proxy_initialized_ && stream_id_ &&
1164 !needs_external_surface_ && !is_remote_) {
1165 stream_texture_proxy_->BindToCurrentThread(stream_id_);
1166 stream_texture_proxy_initialized_ = true;
1167 }
1168 }
1143 } 1169 }
1144 1170
1145 void WebMediaPlayerAndroid::SetCurrentFrameInternal( 1171 void WebMediaPlayerAndroid::SetCurrentFrameInternal(
1146 scoped_refptr<media::VideoFrame>& video_frame) { 1172 scoped_refptr<media::VideoFrame>& video_frame) {
1173 DCHECK(main_thread_checker_.CalledOnValidThread());
1147 base::AutoLock auto_lock(current_frame_lock_); 1174 base::AutoLock auto_lock(current_frame_lock_);
1148 current_frame_ = video_frame; 1175 current_frame_ = video_frame;
1149 } 1176 }
1150 1177
1151 scoped_refptr<media::VideoFrame> WebMediaPlayerAndroid::GetCurrentFrame() { 1178 scoped_refptr<media::VideoFrame> WebMediaPlayerAndroid::GetCurrentFrame() {
1152 scoped_refptr<VideoFrame> video_frame; 1179 scoped_refptr<VideoFrame> video_frame;
1153 { 1180 {
1154 base::AutoLock auto_lock(current_frame_lock_); 1181 base::AutoLock auto_lock(current_frame_lock_);
1155 video_frame = current_frame_; 1182 video_frame = current_frame_;
1156 } 1183 }
1157 1184
1158 if (!stream_texture_proxy_initialized_ && stream_texture_proxy_ &&
1159 stream_id_ && !needs_external_surface_ && !is_remote_) {
1160 gfx::Size natural_size = video_frame->natural_size();
1161 // TODO(sievers): These variables are accessed on the wrong thread here.
1162 stream_texture_proxy_->BindToCurrentThread(stream_id_);
1163 stream_texture_factory_->SetStreamTextureSize(stream_id_, natural_size);
1164 stream_texture_proxy_initialized_ = true;
1165 cached_stream_texture_size_ = natural_size;
1166 }
1167
1168 return video_frame; 1185 return video_frame;
1169 } 1186 }
1170 1187
1171 void WebMediaPlayerAndroid::PutCurrentFrame( 1188 void WebMediaPlayerAndroid::PutCurrentFrame(
1172 const scoped_refptr<media::VideoFrame>& frame) { 1189 const scoped_refptr<media::VideoFrame>& frame) {
1173 } 1190 }
1174 1191
1175 void WebMediaPlayerAndroid::TryCreateStreamTextureProxyIfNeeded() { 1192 void WebMediaPlayerAndroid::TryCreateStreamTextureProxyIfNeeded() {
1193 DCHECK(main_thread_checker_.CalledOnValidThread());
1176 // Already created. 1194 // Already created.
1177 if (stream_texture_proxy_) 1195 if (stream_texture_proxy_)
1178 return; 1196 return;
1179 1197
1180 // No factory to create proxy. 1198 // No factory to create proxy.
1181 if (!stream_texture_factory_) 1199 if (!stream_texture_factory_)
1182 return; 1200 return;
1183 1201
1184 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy()); 1202 stream_texture_proxy_.reset(stream_texture_factory_->CreateProxy());
1185 if (needs_establish_peer_ && stream_texture_proxy_) { 1203 if (needs_establish_peer_ && stream_texture_proxy_) {
1186 DoCreateStreamTexture(); 1204 DoCreateStreamTexture();
1187 ReallocateVideoFrame(); 1205 ReallocateVideoFrame();
1188 } 1206 }
1189 1207
1190 if (stream_texture_proxy_ && video_frame_provider_client_) 1208 if (stream_texture_proxy_ && video_frame_provider_client_)
1191 stream_texture_proxy_->SetClient(video_frame_provider_client_); 1209 stream_texture_proxy_->SetClient(video_frame_provider_client_);
1192 } 1210 }
1193 1211
1194 void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() { 1212 void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() {
1213 DCHECK(main_thread_checker_.CalledOnValidThread());
1195 if (!stream_texture_proxy_) 1214 if (!stream_texture_proxy_)
1196 return; 1215 return;
1197 1216
1198 if (stream_texture_factory_.get() && stream_id_) 1217 if (stream_texture_factory_.get() && stream_id_)
1199 stream_texture_factory_->EstablishPeer(stream_id_, player_id_); 1218 stream_texture_factory_->EstablishPeer(stream_id_, player_id_);
1219
1220 // Set the deferred size because the size was changed in remote mode.
1221 if (!is_remote_ && cached_stream_texture_size_ != natural_size_) {
1222 stream_texture_factory_->SetStreamTextureSize(
1223 stream_id_, gfx::Size(natural_size_.width, natural_size_.height));
1224 cached_stream_texture_size_ = natural_size_;
1225 }
1226
1200 needs_establish_peer_ = false; 1227 needs_establish_peer_ = false;
1201 } 1228 }
1202 1229
1203 void WebMediaPlayerAndroid::DoCreateStreamTexture() { 1230 void WebMediaPlayerAndroid::DoCreateStreamTexture() {
1231 DCHECK(main_thread_checker_.CalledOnValidThread());
1204 DCHECK(!stream_id_); 1232 DCHECK(!stream_id_);
1205 DCHECK(!texture_id_); 1233 DCHECK(!texture_id_);
1206 stream_id_ = stream_texture_factory_->CreateStreamTexture( 1234 stream_id_ = stream_texture_factory_->CreateStreamTexture(
1207 kGLTextureExternalOES, &texture_id_, &texture_mailbox_); 1235 kGLTextureExternalOES, &texture_id_, &texture_mailbox_);
1208 } 1236 }
1209 1237
1210 void WebMediaPlayerAndroid::SetNeedsEstablishPeer(bool needs_establish_peer) { 1238 void WebMediaPlayerAndroid::SetNeedsEstablishPeer(bool needs_establish_peer) {
1211 needs_establish_peer_ = needs_establish_peer; 1239 needs_establish_peer_ = needs_establish_peer;
1212 } 1240 }
1213 1241
(...skipping 406 matching lines...)
1620 player_manager_->EnterFullscreen(player_id_, frame_); 1648 player_manager_->EnterFullscreen(player_id_, frame_);
1621 SetNeedsEstablishPeer(false); 1649 SetNeedsEstablishPeer(false);
1622 } 1650 }
1623 } 1651 }
1624 1652
1625 bool WebMediaPlayerAndroid::canEnterFullscreen() const { 1653 bool WebMediaPlayerAndroid::canEnterFullscreen() const {
1626 return player_manager_->CanEnterFullscreen(frame_); 1654 return player_manager_->CanEnterFullscreen(frame_);
1627 } 1655 }
1628 1656
1629 } // namespace content 1657 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine