| 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 "webkit/renderer/media/webmediaplayer_impl.h" |     5 #include "webkit/renderer/media/webmediaplayer_impl.h" | 
|     6  |     6  | 
|     7 #include <algorithm> |     7 #include <algorithm> | 
|     8 #include <limits> |     8 #include <limits> | 
|     9 #include <string> |     9 #include <string> | 
|    10 #include <vector> |    10 #include <vector> | 
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   147       starting_(false), |   147       starting_(false), | 
|   148       chunk_demuxer_(NULL), |   148       chunk_demuxer_(NULL), | 
|   149       pending_repaint_(false), |   149       pending_repaint_(false), | 
|   150       pending_size_change_(false), |   150       pending_size_change_(false), | 
|   151       video_frame_provider_client_(NULL), |   151       video_frame_provider_client_(NULL), | 
|   152       text_track_index_(0) { |   152       text_track_index_(0) { | 
|   153   media_log_->AddEvent( |   153   media_log_->AddEvent( | 
|   154       media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |   154       media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 
|   155  |   155  | 
|   156   CHECK(media_thread_.Start()); |   156   CHECK(media_thread_.Start()); | 
|   157   pipeline_.reset(new media::Pipeline( |   157   pipeline_.reset(new media::Pipeline(media_thread_.message_loop_proxy(), | 
|   158       media_thread_.message_loop_proxy(), media_log_)); |   158                                       media_log_.get())); | 
|   159  |   159  | 
|   160   // Let V8 know we started new thread if we did not do it yet. |   160   // Let V8 know we started new thread if we did not do it yet. | 
|   161   // Made separate task to avoid deletion of player currently being created. |   161   // Made separate task to avoid deletion of player currently being created. | 
|   162   // Also, delaying GC until after player starts gets rid of starting lag -- |   162   // Also, delaying GC until after player starts gets rid of starting lag -- | 
|   163   // collection happens in parallel with playing. |   163   // collection happens in parallel with playing. | 
|   164   // |   164   // | 
|   165   // TODO(enal): remove when we get rid of per-audio-stream thread. |   165   // TODO(enal): remove when we get rid of per-audio-stream thread. | 
|   166   main_loop_->PostTask( |   166   main_loop_->PostTask( | 
|   167       FROM_HERE, |   167       FROM_HERE, | 
|   168       base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, |   168       base::Bind(&WebMediaPlayerImpl::IncrementExternallyAllocatedMemory, | 
|   169                  AsWeakPtr())); |   169                  AsWeakPtr())); | 
|   170  |   170  | 
|   171   // Also we want to be notified of |main_loop_| destruction. |   171   // Also we want to be notified of |main_loop_| destruction. | 
|   172   base::MessageLoop::current()->AddDestructionObserver(this); |   172   base::MessageLoop::current()->AddDestructionObserver(this); | 
|   173  |   173  | 
|   174   if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) { |   174   if (WebKit::WebRuntimeFeatures::isEncryptedMediaEnabled()) { | 
|   175     decryptor_.reset(new ProxyDecryptor( |   175     decryptor_.reset(new ProxyDecryptor( | 
|   176         client, |   176         client, | 
|   177         frame, |   177         frame, | 
|   178         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded), |   178         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded), | 
|   179         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError), |   179         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError), | 
|   180         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyMessage), |   180         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyMessage), | 
|   181         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey))); |   181         BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNeedKey))); | 
|   182   } |   182   } | 
|   183  |   183  | 
|   184   // Use the null sink if no sink was provided. |   184   // Use the null sink if no sink was provided. | 
|   185   audio_source_provider_ = new WebAudioSourceProviderImpl( |   185   audio_source_provider_ = new WebAudioSourceProviderImpl( | 
|   186       params.audio_renderer_sink() ? params.audio_renderer_sink() : |   186       params.audio_renderer_sink().get() | 
|   187       new media::NullAudioSink(media_thread_.message_loop_proxy())); |   187           ? params.audio_renderer_sink() | 
 |   188           : new media::NullAudioSink(media_thread_.message_loop_proxy())); | 
|   188 } |   189 } | 
|   189  |   190  | 
|   190 WebMediaPlayerImpl::~WebMediaPlayerImpl() { |   191 WebMediaPlayerImpl::~WebMediaPlayerImpl() { | 
|   191   SetVideoFrameProviderClient(NULL); |   192   SetVideoFrameProviderClient(NULL); | 
|   192   GetClient()->setWebLayer(NULL); |   193   GetClient()->setWebLayer(NULL); | 
|   193  |   194  | 
|   194   DCHECK(main_loop_->BelongsToCurrentThread()); |   195   DCHECK(main_loop_->BelongsToCurrentThread()); | 
|   195   media_log_->AddEvent( |   196   media_log_->AddEvent( | 
|   196       media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); |   197       media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); | 
|   197  |   198  | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   241 }  // anonymous namespace |   242 }  // anonymous namespace | 
|   242  |   243  | 
|   243 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, CORSMode cors_mode) { |   244 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, CORSMode cors_mode) { | 
|   244   DCHECK(main_loop_->BelongsToCurrentThread()); |   245   DCHECK(main_loop_->BelongsToCurrentThread()); | 
|   245  |   246  | 
|   246   LoadSetup(url); |   247   LoadSetup(url); | 
|   247  |   248  | 
|   248   // Otherwise it's a regular request which requires resolving the URL first. |   249   // Otherwise it's a regular request which requires resolving the URL first. | 
|   249   GURL gurl(url); |   250   GURL gurl(url); | 
|   250   data_source_.reset(new BufferedDataSource( |   251   data_source_.reset(new BufferedDataSource( | 
|   251       main_loop_, frame_, media_log_, base::Bind( |   252       main_loop_, | 
|   252           &WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); |   253       frame_, | 
 |   254       media_log_.get(), | 
 |   255       base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); | 
|   253   data_source_->Initialize( |   256   data_source_->Initialize( | 
|   254       url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), |   257       url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), | 
|   255       base::Bind( |   258       base::Bind( | 
|   256           &WebMediaPlayerImpl::DataSourceInitialized, |   259           &WebMediaPlayerImpl::DataSourceInitialized, | 
|   257           AsWeakPtr(), gurl)); |   260           AsWeakPtr(), gurl)); | 
|   258  |   261  | 
|   259   is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); |   262   is_local_source_ = !gurl.SchemeIs("http") && !gurl.SchemeIs("https"); | 
|   260 } |   263 } | 
|   261  |   264  | 
|   262 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, |   265 void WebMediaPlayerImpl::load(const WebKit::WebURL& url, | 
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   535   } |   538   } | 
|   536  |   539  | 
|   537   // Avoid locking and potentially blocking the video rendering thread while |   540   // Avoid locking and potentially blocking the video rendering thread while | 
|   538   // painting in software. |   541   // painting in software. | 
|   539   scoped_refptr<media::VideoFrame> video_frame; |   542   scoped_refptr<media::VideoFrame> video_frame; | 
|   540   { |   543   { | 
|   541     base::AutoLock auto_lock(lock_); |   544     base::AutoLock auto_lock(lock_); | 
|   542     video_frame = current_frame_; |   545     video_frame = current_frame_; | 
|   543   } |   546   } | 
|   544   gfx::Rect gfx_rect(rect); |   547   gfx::Rect gfx_rect(rect); | 
|   545   skcanvas_video_renderer_.Paint(video_frame, canvas, gfx_rect, alpha); |   548   skcanvas_video_renderer_.Paint(video_frame.get(), canvas, gfx_rect, alpha); | 
|   546 } |   549 } | 
|   547  |   550  | 
|   548 bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const { |   551 bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const { | 
|   549   if (data_source_) |   552   if (data_source_) | 
|   550     return data_source_->HasSingleOrigin(); |   553     return data_source_->HasSingleOrigin(); | 
|   551   return true; |   554   return true; | 
|   552 } |   555 } | 
|   553  |   556  | 
|   554 bool WebMediaPlayerImpl::didPassCORSAccessCheck() const { |   557 bool WebMediaPlayerImpl::didPassCORSAccessCheck() const { | 
|   555   if (data_source_) |   558   if (data_source_) | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   627     unsigned int level, |   630     unsigned int level, | 
|   628     unsigned int internal_format, |   631     unsigned int internal_format, | 
|   629     unsigned int type, |   632     unsigned int type, | 
|   630     bool premultiply_alpha, |   633     bool premultiply_alpha, | 
|   631     bool flip_y) { |   634     bool flip_y) { | 
|   632   scoped_refptr<media::VideoFrame> video_frame; |   635   scoped_refptr<media::VideoFrame> video_frame; | 
|   633   { |   636   { | 
|   634     base::AutoLock auto_lock(lock_); |   637     base::AutoLock auto_lock(lock_); | 
|   635     video_frame = current_frame_; |   638     video_frame = current_frame_; | 
|   636   } |   639   } | 
|   637   if (video_frame && |   640   if (video_frame.get() && | 
|   638       video_frame->format() == media::VideoFrame::NATIVE_TEXTURE && |   641       video_frame->format() == media::VideoFrame::NATIVE_TEXTURE && | 
|   639       video_frame->texture_target() == GL_TEXTURE_2D) { |   642       video_frame->texture_target() == GL_TEXTURE_2D) { | 
|   640     uint32 source_texture = video_frame->texture_id(); |   643     uint32 source_texture = video_frame->texture_id(); | 
|   641     // The video is stored in a unmultiplied format, so premultiply |   644     // The video is stored in a unmultiplied format, so premultiply | 
|   642     // if necessary. |   645     // if necessary. | 
|   643     web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, |   646     web_graphics_context->pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM, | 
|   644         premultiply_alpha); |   647         premultiply_alpha); | 
|   645     // Application itself needs to take care of setting the right flip_y |   648     // Application itself needs to take care of setting the right flip_y | 
|   646     // value down to get the expected result. |   649     // value down to get the expected result. | 
|   647     // flip_y==true means to reverse the video orientation while |   650     // flip_y==true means to reverse the video orientation while | 
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1090   ScopedVector<media::AudioDecoder> audio_decoders; |  1093   ScopedVector<media::AudioDecoder> audio_decoders; | 
|  1091   audio_decoders.push_back(new media::FFmpegAudioDecoder( |  1094   audio_decoders.push_back(new media::FFmpegAudioDecoder( | 
|  1092       media_thread_.message_loop_proxy())); |  1095       media_thread_.message_loop_proxy())); | 
|  1093   if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) { |  1096   if (cmd_line->HasSwitch(switches::kEnableOpusPlayback)) { | 
|  1094     audio_decoders.push_back(new media::OpusAudioDecoder( |  1097     audio_decoders.push_back(new media::OpusAudioDecoder( | 
|  1095         media_thread_.message_loop_proxy())); |  1098         media_thread_.message_loop_proxy())); | 
|  1096   } |  1099   } | 
|  1097  |  1100  | 
|  1098   scoped_ptr<media::AudioRenderer> audio_renderer( |  1101   scoped_ptr<media::AudioRenderer> audio_renderer( | 
|  1099       new media::AudioRendererImpl(media_thread_.message_loop_proxy(), |  1102       new media::AudioRendererImpl(media_thread_.message_loop_proxy(), | 
|  1100                                    audio_source_provider_, |  1103                                    audio_source_provider_.get(), | 
|  1101                                    audio_decoders.Pass(), |  1104                                    audio_decoders.Pass(), | 
|  1102                                    set_decryptor_ready_cb)); |  1105                                    set_decryptor_ready_cb)); | 
|  1103   filter_collection->SetAudioRenderer(audio_renderer.Pass()); |  1106   filter_collection->SetAudioRenderer(audio_renderer.Pass()); | 
|  1104  |  1107  | 
|  1105   // Create our video decoders and renderer. |  1108   // Create our video decoders and renderer. | 
|  1106   ScopedVector<media::VideoDecoder> video_decoders; |  1109   ScopedVector<media::VideoDecoder> video_decoders; | 
|  1107  |  1110  | 
|  1108   if (gpu_factories_) { |  1111   if (gpu_factories_.get()) { | 
|  1109     video_decoders.push_back(new media::GpuVideoDecoder( |  1112     video_decoders.push_back(new media::GpuVideoDecoder( | 
|  1110         media_thread_.message_loop_proxy(), gpu_factories_)); |  1113         media_thread_.message_loop_proxy(), gpu_factories_)); | 
|  1111   } |  1114   } | 
|  1112  |  1115  | 
|  1113   // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released |  1116   // TODO(phajdan.jr): Remove ifdefs when libvpx with vp9 support is released | 
|  1114   // (http://crbug.com/174287) . |  1117   // (http://crbug.com/174287) . | 
|  1115 #if !defined(MEDIA_DISABLE_LIBVPX) |  1118 #if !defined(MEDIA_DISABLE_LIBVPX) | 
|  1116   if (cmd_line->HasSwitch(switches::kEnableVp9Playback) || |  1119   if (cmd_line->HasSwitch(switches::kEnableVp9Playback) || | 
|  1117       cmd_line->HasSwitch(switches::kEnableVp8AlphaPlayback)) { |  1120       cmd_line->HasSwitch(switches::kEnableVp8AlphaPlayback)) { | 
|  1118     video_decoders.push_back(new media::VpxVideoDecoder( |  1121     video_decoders.push_back(new media::VpxVideoDecoder( | 
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1170   DCHECK(main_loop_->BelongsToCurrentThread()); |  1173   DCHECK(main_loop_->BelongsToCurrentThread()); | 
|  1171  |  1174  | 
|  1172   // Abort any pending IO so stopping the pipeline doesn't get blocked. |  1175   // Abort any pending IO so stopping the pipeline doesn't get blocked. | 
|  1173   if (data_source_) |  1176   if (data_source_) | 
|  1174     data_source_->Abort(); |  1177     data_source_->Abort(); | 
|  1175   if (chunk_demuxer_) { |  1178   if (chunk_demuxer_) { | 
|  1176     chunk_demuxer_->Shutdown(); |  1179     chunk_demuxer_->Shutdown(); | 
|  1177     chunk_demuxer_ = NULL; |  1180     chunk_demuxer_ = NULL; | 
|  1178   } |  1181   } | 
|  1179  |  1182  | 
|  1180   if (gpu_factories_) { |  1183   if (gpu_factories_.get()) { | 
|  1181     gpu_factories_->Abort(); |  1184     gpu_factories_->Abort(); | 
|  1182     gpu_factories_ = NULL; |  1185     gpu_factories_ = NULL; | 
|  1183   } |  1186   } | 
|  1184  |  1187  | 
|  1185   // Make sure to kill the pipeline so there's no more media threads running. |  1188   // Make sure to kill the pipeline so there's no more media threads running. | 
|  1186   // Note: stopping the pipeline might block for a long time. |  1189   // Note: stopping the pipeline might block for a long time. | 
|  1187   base::WaitableEvent waiter(false, false); |  1190   base::WaitableEvent waiter(false, false); | 
|  1188   pipeline_->Stop(base::Bind( |  1191   pipeline_->Stop(base::Bind( | 
|  1189       &base::WaitableEvent::Signal, base::Unretained(&waiter))); |  1192       &base::WaitableEvent::Signal, base::Unretained(&waiter))); | 
|  1190   waiter.Wait(); |  1193   waiter.Wait(); | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  1203   data_source_.reset(); |  1206   data_source_.reset(); | 
|  1204 } |  1207 } | 
|  1205  |  1208  | 
|  1206 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { |  1209 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { | 
|  1207   DCHECK(main_loop_->BelongsToCurrentThread()); |  1210   DCHECK(main_loop_->BelongsToCurrentThread()); | 
|  1208   DCHECK(client_); |  1211   DCHECK(client_); | 
|  1209   return client_; |  1212   return client_; | 
|  1210 } |  1213 } | 
|  1211  |  1214  | 
|  1212 WebKit::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { |  1215 WebKit::WebAudioSourceProvider* WebMediaPlayerImpl::audioSourceProvider() { | 
|  1213   return audio_source_provider_; |  1216   return audio_source_provider_.get(); | 
|  1214 } |  1217 } | 
|  1215  |  1218  | 
|  1216 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { |  1219 void WebMediaPlayerImpl::IncrementExternallyAllocatedMemory() { | 
|  1217   DCHECK(main_loop_->BelongsToCurrentThread()); |  1220   DCHECK(main_loop_->BelongsToCurrentThread()); | 
|  1218   incremented_externally_allocated_memory_ = true; |  1221   incremented_externally_allocated_memory_ = true; | 
|  1219   v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); |  1222   v8::V8::AdjustAmountOfExternalAllocatedMemory(kPlayerExtraMemory); | 
|  1220 } |  1223 } | 
|  1221  |  1224  | 
|  1222 double WebMediaPlayerImpl::GetPipelineDuration() const { |  1225 double WebMediaPlayerImpl::GetPipelineDuration() const { | 
|  1223   base::TimeDelta duration = pipeline_->GetMediaDuration(); |  1226   base::TimeDelta duration = pipeline_->GetMediaDuration(); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  1234   if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |  1237   if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 
|  1235     return; |  1238     return; | 
|  1236  |  1239  | 
|  1237   GetClient()->durationChanged(); |  1240   GetClient()->durationChanged(); | 
|  1238 } |  1241 } | 
|  1239  |  1242  | 
|  1240 void WebMediaPlayerImpl::FrameReady( |  1243 void WebMediaPlayerImpl::FrameReady( | 
|  1241     const scoped_refptr<media::VideoFrame>& frame) { |  1244     const scoped_refptr<media::VideoFrame>& frame) { | 
|  1242   base::AutoLock auto_lock(lock_); |  1245   base::AutoLock auto_lock(lock_); | 
|  1243  |  1246  | 
|  1244   if (current_frame_ && |  1247   if (current_frame_.get() && | 
|  1245       current_frame_->natural_size() != frame->natural_size() && |  1248       current_frame_->natural_size() != frame->natural_size() && | 
|  1246       !pending_size_change_) { |  1249       !pending_size_change_) { | 
|  1247     pending_size_change_ = true; |  1250     pending_size_change_ = true; | 
|  1248   } |  1251   } | 
|  1249  |  1252  | 
|  1250   current_frame_ = frame; |  1253   current_frame_ = frame; | 
|  1251  |  1254  | 
|  1252   if (pending_repaint_) |  1255   if (pending_repaint_) | 
|  1253     return; |  1256     return; | 
|  1254  |  1257  | 
|  1255   pending_repaint_ = true; |  1258   pending_repaint_ = true; | 
|  1256   main_loop_->PostTask(FROM_HERE, base::Bind( |  1259   main_loop_->PostTask(FROM_HERE, base::Bind( | 
|  1257       &WebMediaPlayerImpl::Repaint, AsWeakPtr())); |  1260       &WebMediaPlayerImpl::Repaint, AsWeakPtr())); | 
|  1258 } |  1261 } | 
|  1259  |  1262  | 
|  1260 }  // namespace webkit_media |  1263 }  // namespace webkit_media | 
| OLD | NEW |