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