OLD | NEW |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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...) Loading... |
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 |
OLD | NEW |