Index: content/renderer/media/rtc_video_decoder.cc |
=================================================================== |
--- content/renderer/media/rtc_video_decoder.cc (revision 109978) |
+++ content/renderer/media/rtc_video_decoder.cc (working copy) |
@@ -4,8 +4,6 @@ |
#include "content/renderer/media/rtc_video_decoder.h" |
-#include <deque> |
- |
#include "base/bind.h" |
#include "base/callback.h" |
#include "base/message_loop.h" |
@@ -87,6 +85,27 @@ |
VideoDecoder::Pause(callback); |
} |
+void RTCVideoDecoder::Flush(const base::Closure& callback) { |
+ if (MessageLoop::current() != message_loop_) { |
+ message_loop_->PostTask(FROM_HERE, |
+ base::Bind(&RTCVideoDecoder::Flush, |
+ this, callback)); |
+ return; |
+ } |
+ |
+ DCHECK_EQ(MessageLoop::current(), message_loop_); |
+ |
+ { |
+ base::AutoLock auto_lock(lock_); |
+ while (!read_cbs_.empty()) { |
+ DeliverBlackFrame(read_cbs_.front()); |
+ read_cbs_.pop(); |
+ } |
+ } |
+ |
+ VideoDecoder::Flush(callback); |
+} |
+ |
void RTCVideoDecoder::Stop(const base::Closure& callback) { |
if (MessageLoop::current() != message_loop_) { |
message_loop_->PostTask(FROM_HERE, |
@@ -123,9 +142,13 @@ |
return; |
} |
DCHECK_EQ(MessageLoop::current(), message_loop_); |
+ CHECK(!callback.is_null()); |
+ if (state_ != kNormal) { |
+ DeliverBlackFrame(callback); |
+ return; |
+ } |
base::AutoLock auto_lock(lock_); |
- CHECK(read_cb_.is_null()); |
- read_cb_ = callback; |
+ read_cbs_.push(callback); |
} |
const gfx::Size& RTCVideoDecoder::natural_size() { |
@@ -141,6 +164,10 @@ |
return true; |
} |
+// TODO(wjia): this function can be split into two parts so that the |lock_| |
+// can be removed. |
+// First creates media::VideoFrame, then post a task onto |message_loop_| |
+// to deliver that frame. |
bool RTCVideoDecoder::RenderFrame(const cricket::VideoFrame* frame) { |
// Called from libjingle thread. |
DCHECK(frame); |
@@ -151,10 +178,11 @@ |
ReadCB read_cb; |
{ |
base::AutoLock auto_lock(lock_); |
- if (read_cb_.is_null()) { |
+ if (read_cbs_.empty()) { |
return true; |
} |
- std::swap(read_cb, read_cb_); |
+ read_cb = read_cbs_.front(); |
+ read_cbs_.pop(); |
} |
// Always allocate a new frame. |
@@ -180,3 +208,12 @@ |
read_cb.Run(video_frame); |
return true; |
} |
+ |
+void RTCVideoDecoder::DeliverBlackFrame( |
+ const ReadCB& read_cb) { |
+ CHECK(!read_cb.is_null()); |
+ scoped_refptr<media::VideoFrame> video_frame = |
+ media::VideoFrame::CreateBlackFrame(visible_size_.width(), |
+ visible_size_.height()); |
+ read_cb.Run(video_frame); |
+} |