Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/glue/webmediaplayer_impl.h" | 5 #include "webkit/glue/webmediaplayer_impl.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h" |
| 27 #include "webkit/glue/media/buffered_data_source.h" | 27 #include "webkit/glue/media/buffered_data_source.h" |
| 28 #include "webkit/glue/media/simple_data_source.h" | 28 #include "webkit/glue/media/simple_data_source.h" |
| 29 #include "webkit/glue/media/video_renderer_impl.h" | 29 #include "webkit/glue/media/video_renderer_impl.h" |
| 30 #include "webkit/glue/media/web_video_renderer.h" | 30 #include "webkit/glue/media/web_video_renderer.h" |
| 31 #include "webkit/glue/webvideoframe_impl.h" | 31 #include "webkit/glue/webvideoframe_impl.h" |
| 32 | 32 |
| 33 using WebKit::WebCanvas; | 33 using WebKit::WebCanvas; |
| 34 using WebKit::WebRect; | 34 using WebKit::WebRect; |
| 35 using WebKit::WebSize; | 35 using WebKit::WebSize; |
| 36 using media::PipelineStatus; | |
| 36 | 37 |
| 37 namespace { | 38 namespace { |
| 38 | 39 |
| 39 // Limits the maximum outstanding repaints posted on render thread. | 40 // Limits the maximum outstanding repaints posted on render thread. |
| 40 // This number of 50 is a guess, it does not take too much memory on the task | 41 // This number of 50 is a guess, it does not take too much memory on the task |
| 41 // queue but gives up a pretty good latency on repaint. | 42 // queue but gives up a pretty good latency on repaint. |
| 42 const int kMaxOutstandingRepaints = 50; | 43 const int kMaxOutstandingRepaints = 50; |
| 43 | 44 |
| 44 // Limits the range of playback rate. | 45 // Limits the range of playback rate. |
| 45 // | 46 // |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 DCHECK(MessageLoop::current() == render_loop_); | 165 DCHECK(MessageLoop::current() == render_loop_); |
| 165 webmediaplayer_ = NULL; | 166 webmediaplayer_ = NULL; |
| 166 video_renderer_ = NULL; | 167 video_renderer_ = NULL; |
| 167 | 168 |
| 168 { | 169 { |
| 169 base::AutoLock auto_lock(data_sources_lock_); | 170 base::AutoLock auto_lock(data_sources_lock_); |
| 170 data_sources_.clear(); | 171 data_sources_.clear(); |
| 171 } | 172 } |
| 172 } | 173 } |
| 173 | 174 |
| 174 void WebMediaPlayerImpl::Proxy::PipelineInitializationCallback() { | 175 void WebMediaPlayerImpl::Proxy::PipelineInitializationCallback( |
| 175 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 176 PipelineStatus status) { |
| 176 &WebMediaPlayerImpl::Proxy::PipelineInitializationTask)); | 177 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 178 this, &WebMediaPlayerImpl::Proxy::PipelineInitializationTask, status)); | |
| 177 } | 179 } |
| 178 | 180 |
| 179 void WebMediaPlayerImpl::Proxy::PipelineSeekCallback() { | 181 void WebMediaPlayerImpl::Proxy::PipelineSeekCallback(PipelineStatus status) { |
| 180 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 182 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 181 &WebMediaPlayerImpl::Proxy::PipelineSeekTask)); | 183 this, &WebMediaPlayerImpl::Proxy::PipelineSeekTask, status)); |
| 182 } | 184 } |
| 183 | 185 |
| 184 void WebMediaPlayerImpl::Proxy::PipelineEndedCallback() { | 186 void WebMediaPlayerImpl::Proxy::PipelineEndedCallback(PipelineStatus status) { |
| 185 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 187 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 186 &WebMediaPlayerImpl::Proxy::PipelineEndedTask)); | 188 this, &WebMediaPlayerImpl::Proxy::PipelineEndedTask, status)); |
| 187 } | 189 } |
| 188 | 190 |
| 189 void WebMediaPlayerImpl::Proxy::PipelineErrorCallback() { | 191 void WebMediaPlayerImpl::Proxy::PipelineErrorCallback(PipelineStatus error) { |
| 190 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 192 DCHECK_NE(error, media::PIPELINE_OK); |
| 191 &WebMediaPlayerImpl::Proxy::PipelineErrorTask)); | 193 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 194 this, &WebMediaPlayerImpl::Proxy::PipelineErrorTask, error)); | |
| 192 } | 195 } |
| 193 | 196 |
| 194 void WebMediaPlayerImpl::Proxy::NetworkEventCallback() { | 197 void WebMediaPlayerImpl::Proxy::NetworkEventCallback(PipelineStatus status) { |
| 195 render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, | 198 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| 196 &WebMediaPlayerImpl::Proxy::NetworkEventTask)); | 199 this, &WebMediaPlayerImpl::Proxy::NetworkEventTask, status)); |
| 197 } | 200 } |
| 198 | 201 |
| 199 void WebMediaPlayerImpl::Proxy::AddDataSource(WebDataSource* data_source) { | 202 void WebMediaPlayerImpl::Proxy::AddDataSource(WebDataSource* data_source) { |
| 200 base::AutoLock auto_lock(data_sources_lock_); | 203 base::AutoLock auto_lock(data_sources_lock_); |
| 201 data_sources_.push_back(make_scoped_refptr(data_source)); | 204 data_sources_.push_back(make_scoped_refptr(data_source)); |
| 202 } | 205 } |
| 203 | 206 |
| 204 void WebMediaPlayerImpl::Proxy::RepaintTask() { | 207 void WebMediaPlayerImpl::Proxy::RepaintTask() { |
| 205 DCHECK(MessageLoop::current() == render_loop_); | 208 DCHECK(MessageLoop::current() == render_loop_); |
| 206 { | 209 { |
| 207 base::AutoLock auto_lock(lock_); | 210 base::AutoLock auto_lock(lock_); |
| 208 --outstanding_repaints_; | 211 --outstanding_repaints_; |
| 209 DCHECK_GE(outstanding_repaints_, 0); | 212 DCHECK_GE(outstanding_repaints_, 0); |
| 210 } | 213 } |
| 211 if (webmediaplayer_) { | 214 if (webmediaplayer_) { |
| 212 webmediaplayer_->Repaint(); | 215 webmediaplayer_->Repaint(); |
| 213 } | 216 } |
| 214 } | 217 } |
| 215 | 218 |
| 216 void WebMediaPlayerImpl::Proxy::PipelineInitializationTask() { | 219 void WebMediaPlayerImpl::Proxy::PipelineInitializationTask( |
| 220 PipelineStatus status) { | |
| 217 DCHECK(MessageLoop::current() == render_loop_); | 221 DCHECK(MessageLoop::current() == render_loop_); |
| 218 if (webmediaplayer_) { | 222 if (webmediaplayer_) { |
| 219 webmediaplayer_->OnPipelineInitialize(); | 223 webmediaplayer_->OnPipelineInitialize(status); |
| 220 } | 224 } |
| 221 } | 225 } |
| 222 | 226 |
| 223 void WebMediaPlayerImpl::Proxy::PipelineSeekTask() { | 227 void WebMediaPlayerImpl::Proxy::PipelineSeekTask(PipelineStatus status) { |
| 224 DCHECK(MessageLoop::current() == render_loop_); | 228 DCHECK(MessageLoop::current() == render_loop_); |
| 225 if (webmediaplayer_) { | 229 if (webmediaplayer_) { |
| 226 webmediaplayer_->OnPipelineSeek(); | 230 webmediaplayer_->OnPipelineSeek(status); |
| 227 } | 231 } |
| 228 } | 232 } |
| 229 | 233 |
| 230 void WebMediaPlayerImpl::Proxy::PipelineEndedTask() { | 234 void WebMediaPlayerImpl::Proxy::PipelineEndedTask(PipelineStatus status) { |
| 231 DCHECK(MessageLoop::current() == render_loop_); | 235 DCHECK(MessageLoop::current() == render_loop_); |
| 232 if (webmediaplayer_) { | 236 if (webmediaplayer_) { |
| 233 webmediaplayer_->OnPipelineEnded(); | 237 webmediaplayer_->OnPipelineEnded(status); |
| 234 } | 238 } |
| 235 } | 239 } |
| 236 | 240 |
| 237 void WebMediaPlayerImpl::Proxy::PipelineErrorTask() { | 241 void WebMediaPlayerImpl::Proxy::PipelineErrorTask(PipelineStatus error) { |
| 238 DCHECK(MessageLoop::current() == render_loop_); | 242 DCHECK(MessageLoop::current() == render_loop_); |
| 239 if (webmediaplayer_) { | 243 if (webmediaplayer_) { |
| 240 webmediaplayer_->OnPipelineError(); | 244 webmediaplayer_->OnPipelineError(error); |
| 241 } | 245 } |
| 242 } | 246 } |
| 243 | 247 |
| 244 void WebMediaPlayerImpl::Proxy::NetworkEventTask() { | 248 void WebMediaPlayerImpl::Proxy::NetworkEventTask(PipelineStatus status) { |
| 245 DCHECK(MessageLoop::current() == render_loop_); | 249 DCHECK(MessageLoop::current() == render_loop_); |
| 246 if (webmediaplayer_) { | 250 if (webmediaplayer_) { |
| 247 webmediaplayer_->OnNetworkEvent(); | 251 webmediaplayer_->OnNetworkEvent(status); |
| 248 } | 252 } |
| 249 } | 253 } |
| 250 | 254 |
| 251 void WebMediaPlayerImpl::Proxy::GetCurrentFrame( | 255 void WebMediaPlayerImpl::Proxy::GetCurrentFrame( |
| 252 scoped_refptr<media::VideoFrame>* frame_out) { | 256 scoped_refptr<media::VideoFrame>* frame_out) { |
| 253 if (video_renderer_) | 257 if (video_renderer_) |
| 254 video_renderer_->GetCurrentFrame(frame_out); | 258 video_renderer_->GetCurrentFrame(frame_out); |
| 255 } | 259 } |
| 256 | 260 |
| 257 void WebMediaPlayerImpl::Proxy::PutCurrentFrame( | 261 void WebMediaPlayerImpl::Proxy::PutCurrentFrame( |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 737 void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() { | 741 void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() { |
| 738 Destroy(); | 742 Destroy(); |
| 739 main_loop_ = NULL; | 743 main_loop_ = NULL; |
| 740 } | 744 } |
| 741 | 745 |
| 742 void WebMediaPlayerImpl::Repaint() { | 746 void WebMediaPlayerImpl::Repaint() { |
| 743 DCHECK(MessageLoop::current() == main_loop_); | 747 DCHECK(MessageLoop::current() == main_loop_); |
| 744 GetClient()->repaint(); | 748 GetClient()->repaint(); |
| 745 } | 749 } |
| 746 | 750 |
| 747 void WebMediaPlayerImpl::OnPipelineInitialize() { | 751 void WebMediaPlayerImpl::OnPipelineInitialize(PipelineStatus status) { |
| 748 DCHECK(MessageLoop::current() == main_loop_); | 752 DCHECK(MessageLoop::current() == main_loop_); |
| 749 if (pipeline_->GetError() == media::PIPELINE_OK) { | 753 if (status == media::PIPELINE_OK) { |
| 750 // Only keep one time range starting from 0. | 754 // Only keep one time range starting from 0. |
| 751 WebKit::WebTimeRanges new_buffered(static_cast<size_t>(1)); | 755 WebKit::WebTimeRanges new_buffered(static_cast<size_t>(1)); |
| 752 new_buffered[0].start = 0.0f; | 756 new_buffered[0].start = 0.0f; |
| 753 new_buffered[0].end = | 757 new_buffered[0].end = |
| 754 static_cast<float>(pipeline_->GetMediaDuration().InSecondsF()); | 758 static_cast<float>(pipeline_->GetMediaDuration().InSecondsF()); |
| 755 buffered_.swap(new_buffered); | 759 buffered_.swap(new_buffered); |
| 756 | 760 |
| 757 // Since we have initialized the pipeline, say we have everything otherwise | 761 // Since we have initialized the pipeline, say we have everything otherwise |
| 758 // we'll remain either loading/idle. | 762 // we'll remain either loading/idle. |
| 759 // TODO(hclam): change this to report the correct status. | 763 // TODO(hclam): change this to report the correct status. |
| 760 SetReadyState(WebKit::WebMediaPlayer::HaveMetadata); | 764 SetReadyState(WebKit::WebMediaPlayer::HaveMetadata); |
| 761 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData); | 765 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData); |
| 762 if (pipeline_->IsLoaded()) { | 766 if (pipeline_->IsLoaded()) { |
| 763 SetNetworkState(WebKit::WebMediaPlayer::Loaded); | 767 SetNetworkState(WebKit::WebMediaPlayer::Loaded); |
| 764 } | 768 } |
| 765 } else { | 769 } else { |
| 766 // TODO(hclam): should use pipeline_->GetError() to determine the state | 770 // TODO(hclam): should use |status| to determine the state |
| 767 // properly and reports error using MediaError. | 771 // properly and reports error using MediaError. |
| 768 // WebKit uses FormatError to indicate an error for bogus URL or bad file. | 772 // WebKit uses FormatError to indicate an error for bogus URL or bad file. |
| 769 // Since we are at the initialization stage we can safely treat every error | 773 // Since we are at the initialization stage we can safely treat every error |
| 770 // as format error. Should post a task to call to |webmediaplayer_|. | 774 // as format error. Should post a task to call to |webmediaplayer_|. |
| 771 SetNetworkState(WebKit::WebMediaPlayer::FormatError); | 775 SetNetworkState(WebKit::WebMediaPlayer::FormatError); |
| 772 } | 776 } |
| 773 | 777 |
| 774 // Repaint to trigger UI update. | 778 // Repaint to trigger UI update. |
| 775 Repaint(); | 779 Repaint(); |
| 776 } | 780 } |
| 777 | 781 |
| 778 void WebMediaPlayerImpl::OnPipelineSeek() { | 782 void WebMediaPlayerImpl::OnPipelineSeek(PipelineStatus status) { |
| 779 DCHECK(MessageLoop::current() == main_loop_); | 783 DCHECK(MessageLoop::current() == main_loop_); |
| 780 if (pipeline_->GetError() == media::PIPELINE_OK) { | 784 if (status == media::PIPELINE_OK) { |
| 781 // Update our paused time. | 785 // Update our paused time. |
| 782 if (paused_) { | 786 if (paused_) { |
| 783 paused_time_ = pipeline_->GetCurrentTime(); | 787 paused_time_ = pipeline_->GetCurrentTime(); |
| 784 } | 788 } |
| 785 | 789 |
| 786 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData); | 790 SetReadyState(WebKit::WebMediaPlayer::HaveEnoughData); |
| 787 seeking_ = false; | 791 seeking_ = false; |
| 788 GetClient()->timeChanged(); | 792 GetClient()->timeChanged(); |
| 789 } | 793 } |
| 790 } | 794 } |
| 791 | 795 |
| 792 void WebMediaPlayerImpl::OnPipelineEnded() { | 796 void WebMediaPlayerImpl::OnPipelineEnded(PipelineStatus status) { |
| 793 DCHECK(MessageLoop::current() == main_loop_); | 797 DCHECK(MessageLoop::current() == main_loop_); |
| 794 if (pipeline_->GetError() == media::PIPELINE_OK) { | 798 if (status == media::PIPELINE_OK) { |
| 795 GetClient()->timeChanged(); | 799 GetClient()->timeChanged(); |
| 796 } | 800 } |
| 797 } | 801 } |
| 798 | 802 |
| 799 void WebMediaPlayerImpl::OnPipelineError() { | 803 void WebMediaPlayerImpl::OnPipelineError(PipelineStatus error) { |
| 800 DCHECK(MessageLoop::current() == main_loop_); | 804 DCHECK(MessageLoop::current() == main_loop_); |
| 801 switch (pipeline_->GetError()) { | 805 switch (error) { |
| 802 case media::PIPELINE_OK: | 806 case media::PIPELINE_OK: |
| 807 LOG(DFATAL) << "PIPELINE_OK isn't an error!"; | |
| 808 break; | |
| 809 | |
| 803 case media::PIPELINE_ERROR_INITIALIZATION_FAILED: | 810 case media::PIPELINE_ERROR_INITIALIZATION_FAILED: |
| 804 case media::PIPELINE_ERROR_REQUIRED_FILTER_MISSING: | 811 case media::PIPELINE_ERROR_REQUIRED_FILTER_MISSING: |
| 805 case media::PIPELINE_ERROR_COULD_NOT_RENDER: | 812 case media::PIPELINE_ERROR_COULD_NOT_RENDER: |
| 806 case media::PIPELINE_ERROR_URL_NOT_FOUND: | 813 case media::PIPELINE_ERROR_URL_NOT_FOUND: |
| 807 case media::PIPELINE_ERROR_NETWORK: | 814 case media::PIPELINE_ERROR_NETWORK: |
| 808 case media::PIPELINE_ERROR_READ: | 815 case media::PIPELINE_ERROR_READ: |
| 809 case media::DEMUXER_ERROR_COULD_NOT_OPEN: | 816 case media::DEMUXER_ERROR_COULD_NOT_OPEN: |
| 810 case media::DEMUXER_ERROR_COULD_NOT_PARSE: | 817 case media::DEMUXER_ERROR_COULD_NOT_PARSE: |
| 811 case media::DEMUXER_ERROR_NO_SUPPORTED_STREAMS: | 818 case media::DEMUXER_ERROR_NO_SUPPORTED_STREAMS: |
| 812 case media::DEMUXER_ERROR_COULD_NOT_CREATE_THREAD: | 819 case media::DEMUXER_ERROR_COULD_NOT_CREATE_THREAD: |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 823 case media::PIPELINE_ERROR_INVALID_STATE: | 830 case media::PIPELINE_ERROR_INVALID_STATE: |
| 824 // Decode error. | 831 // Decode error. |
| 825 SetNetworkState(WebMediaPlayer::DecodeError); | 832 SetNetworkState(WebMediaPlayer::DecodeError); |
| 826 break; | 833 break; |
| 827 } | 834 } |
| 828 | 835 |
| 829 // Repaint to trigger UI update. | 836 // Repaint to trigger UI update. |
| 830 Repaint(); | 837 Repaint(); |
| 831 } | 838 } |
| 832 | 839 |
| 833 void WebMediaPlayerImpl::OnNetworkEvent() { | 840 void WebMediaPlayerImpl::OnNetworkEvent(PipelineStatus status) { |
| 834 DCHECK(MessageLoop::current() == main_loop_); | 841 DCHECK(MessageLoop::current() == main_loop_); |
| 835 if (pipeline_->GetError() == media::PIPELINE_OK) { | 842 if (status == media::PIPELINE_OK) { |
| 836 if (pipeline_->IsNetworkActive()) { | 843 if (pipeline_->IsNetworkActive()) { |
| 837 SetNetworkState(WebKit::WebMediaPlayer::Loading); | 844 SetNetworkState(WebKit::WebMediaPlayer::Loading); |
| 838 } else { | 845 } else { |
| 839 // If we are inactive because we just finished receiving all the data, | 846 // If we are inactive because we just finished receiving all the data, |
| 840 // do one final repaint to show final progress. | 847 // do one final repaint to show final progress. |
| 841 if (bytesLoaded() == totalBytes() && | 848 if (bytesLoaded() == totalBytes() && |
| 842 network_state_ != WebKit::WebMediaPlayer::Idle) { | 849 network_state_ != WebKit::WebMediaPlayer::Idle) { |
| 843 Repaint(); | 850 Repaint(); |
| 844 | 851 |
| 845 SetNetworkState(WebKit::WebMediaPlayer::Loaded); | 852 SetNetworkState(WebKit::WebMediaPlayer::Loaded); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 885 message_loop_factory_.reset(); | 892 message_loop_factory_.reset(); |
| 886 | 893 |
| 887 // And then detach the proxy, it may live on the render thread for a little | 894 // And then detach the proxy, it may live on the render thread for a little |
| 888 // longer until all the tasks are finished. | 895 // longer until all the tasks are finished. |
| 889 if (proxy_) { | 896 if (proxy_) { |
| 890 proxy_->Detach(); | 897 proxy_->Detach(); |
| 891 proxy_ = NULL; | 898 proxy_ = NULL; |
| 892 } | 899 } |
| 893 } | 900 } |
| 894 | 901 |
| 895 void WebMediaPlayerImpl::PipelineStoppedCallback() { | 902 void WebMediaPlayerImpl::PipelineStoppedCallback(PipelineStatus status) { |
|
acolwell GONE FROM CHROMIUM
2011/03/15 23:43:55
Could we replace the code that uses this with your
Ami GONE FROM CHROMIUM
2011/03/16 00:01:02
Next CL.
| |
| 896 pipeline_stopped_.Signal(); | 903 pipeline_stopped_.Signal(); |
| 897 } | 904 } |
| 898 | 905 |
| 899 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { | 906 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { |
| 900 DCHECK(MessageLoop::current() == main_loop_); | 907 DCHECK(MessageLoop::current() == main_loop_); |
| 901 DCHECK(client_); | 908 DCHECK(client_); |
| 902 return client_; | 909 return client_; |
| 903 } | 910 } |
| 904 | 911 |
| 905 } // namespace webkit_glue | 912 } // namespace webkit_glue |
| OLD | NEW |