Chromium Code Reviews| Index: content/renderer/media/webmediaplayer_ms.cc |
| diff --git a/content/renderer/media/webmediaplayer_ms.cc b/content/renderer/media/webmediaplayer_ms.cc |
| index d4312920b06f7f4b1cb55d99e0b59faea7cb205f..7e7c8b19ba2ed1ef1a75d7860547ef07c5013f53 100644 |
| --- a/content/renderer/media/webmediaplayer_ms.cc |
| +++ b/content/renderer/media/webmediaplayer_ms.cc |
| @@ -71,6 +71,12 @@ scoped_refptr<media::VideoFrame> CopyFrameToYV12( |
| return new_frame; |
| } |
| +// Empty method used for keeping a reference to the original media::VideoFrame |
| +// in OnFrameAvailable() if a color conversion between I420 and YV12 is needed. |
| +static void ReleaseOriginalFrame( |
| + const scoped_refptr<media::VideoFrame>& frame) { |
| +} |
| + |
| } // anonymous namespace |
| namespace content { |
| @@ -402,12 +408,33 @@ void WebMediaPlayerMS::OnFrameAvailable( |
| DVLOG(3) << "WebMediaPlayerMS::OnFrameAvailable"; |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| ++total_frame_count_; |
| + |
| + // Rendering do not support I420 but video capture use I420. |
| + // The only difference between YV12 and I420 is the order of U and V plane. |
| + // To solve that the I420 frame is simply wrapped in an YV12 video frame. |
| + scoped_refptr<media::VideoFrame> yv12_frame = frame; |
|
perkj_chrome
2014/03/27 09:25:39
The incoming frame can be a texture as well- not n
|
| + if (frame->format() == media::VideoFrame::I420) { |
| + yv12_frame = media::VideoFrame::WrapExternalYuvData( |
| + media::VideoFrame::YV12, |
| + frame->coded_size(), |
| + frame->visible_rect(), |
| + frame->natural_size(), |
| + frame->stride(media::VideoFrame::kYPlane), |
| + frame->stride(media::VideoFrame::kUPlane), |
| + frame->stride(media::VideoFrame::kVPlane), |
| + frame->data(media::VideoFrame::kYPlane), |
| + frame->data(media::VideoFrame::kUPlane), |
| + frame->data(media::VideoFrame::kVPlane), |
| + frame->GetTimestamp(), |
| + base::Bind(&ReleaseOriginalFrame, frame)); |
| + } |
| + |
| if (!received_first_frame_) { |
| received_first_frame_ = true; |
| { |
| base::AutoLock auto_lock(current_frame_lock_); |
| DCHECK(!current_frame_used_); |
| - current_frame_ = frame; |
| + current_frame_ = yv12_frame; |
| } |
| SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
| SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); |
| @@ -426,17 +453,17 @@ void WebMediaPlayerMS::OnFrameAvailable( |
| if (!sequence_started_) { |
| sequence_started_ = true; |
| - start_time_ = frame->GetTimestamp(); |
| + start_time_ = yv12_frame->GetTimestamp(); |
| } |
| bool size_changed = !current_frame_.get() || |
| - current_frame_->natural_size() != frame->natural_size(); |
| + current_frame_->natural_size() != yv12_frame->natural_size(); |
| { |
| base::AutoLock auto_lock(current_frame_lock_); |
| if (!current_frame_used_ && current_frame_.get()) |
| ++dropped_frame_count_; |
| - current_frame_ = frame; |
| - current_time_ = frame->GetTimestamp() - start_time_; |
| + current_frame_ = yv12_frame; |
| + current_time_ = yv12_frame->GetTimestamp() - start_time_; |
| current_frame_used_ = false; |
| } |