1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/ios/bridge/frame_consumer_bridge.h"
8 #include "base/logging.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "remoting/base/util.h"
11 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
15 FrameConsumerBridge::FrameConsumerBridge(OnFrameCallback callback)
16 : callback_(callback), frame_producer_(NULL) {}
18 FrameConsumerBridge::~FrameConsumerBridge() {
19 // The producer should now return any pending buffers. At this point, however,
20 // the buffers are returned via tasks which may not be scheduled before the
21 // producer, so we free all the buffers once the producer's queue is empty.
22 // And the scheduled tasks will die quietly.
23 if (frame_producer_) {
24 base::WaitableEvent done_event(true, false);
25 frame_producer_->RequestReturnBuffers(base::Bind(
26 &base::WaitableEvent::Signal, base::Unretained(&done_event)));
31 void FrameConsumerBridge::Initialize(FrameProducer* producer) {
32 DCHECK(!frame_producer_);
33 frame_producer_ = producer;
34 DCHECK(frame_producer_);
37 void FrameConsumerBridge::ApplyBuffer(const webrtc::DesktopSize& view_size,
38 const webrtc::DesktopRect& clip_area,
39 webrtc::DesktopFrame* buffer,
40 const webrtc::DesktopRegion& region,
41 const webrtc::DesktopRegion& shape) {
42 DCHECK(frame_producer_);
43 if (!view_size_.equals(view_size)) {
44 // Drop the frame, since the data belongs to the previous generation,
45 // before SetSourceSize() called SetOutputSizeAndClip().
50 // This call completes synchronously.
51 callback_.Run(view_size, buffer, region);
53 // Recycle |buffer| by returning it to |frame_producer_| as the next buffer
54 frame_producer_->DrawBuffer(buffer);
57 void FrameConsumerBridge::ReturnBuffer(webrtc::DesktopFrame* buffer) {
58 DCHECK(frame_producer_);
59 ScopedVector<webrtc::DesktopFrame>::iterator it =
60 std::find(buffers_.begin(), buffers_.end(), buffer);
62 DCHECK(it != buffers_.end());
66 void FrameConsumerBridge::SetSourceSize(const webrtc::DesktopSize& source_size,
67 const webrtc::DesktopVector& dpi) {
68 DCHECK(frame_producer_);
69 view_size_ = source_size;
70 webrtc::DesktopRect clip_area = webrtc::DesktopRect::MakeSize(view_size_);
71 frame_producer_->SetOutputSizeAndClip(view_size_, clip_area);
73 // Now that the size is well known, ask the producer to start drawing
77 FrameConsumerBridge::PixelFormat FrameConsumerBridge::GetPixelFormat() {
81 void FrameConsumerBridge::DrawWithNewBuffer() {
82 DCHECK(frame_producer_);
83 webrtc::DesktopFrame* buffer = new webrtc::BasicDesktopFrame(view_size_);
84 buffers_.push_back(buffer);
85 frame_producer_->DrawBuffer(buffer);
88 } // namespace remoting