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; |
} |