Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / remoting / ios / bridge / frame_consumer_bridge.cc
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.
4
5 #include "remoting/ios/bridge/frame_consumer_bridge.h"
6
7 #include "base/bind.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"
12
13 namespace remoting {
14
15 FrameConsumerBridge::FrameConsumerBridge(OnFrameCallback callback)
16     : callback_(callback), frame_producer_(NULL) {}
17
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)));
27     done_event.Wait();
28   }
29 }
30
31 void FrameConsumerBridge::Initialize(FrameProducer* producer) {
32   DCHECK(!frame_producer_);
33   frame_producer_ = producer;
34   DCHECK(frame_producer_);
35 }
36
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().
46     ReturnBuffer(buffer);
47     return;
48   }
49
50   // This call completes synchronously.
51   callback_.Run(view_size, buffer, region);
52
53   // Recycle |buffer| by returning it to |frame_producer_| as the next buffer
54   frame_producer_->DrawBuffer(buffer);
55 }
56
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);
61
62   DCHECK(it != buffers_.end());
63   buffers_.erase(it);
64 }
65
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);
72
73   // Now that the size is well known, ask the producer to start drawing
74   DrawWithNewBuffer();
75 }
76
77 FrameConsumerBridge::PixelFormat FrameConsumerBridge::GetPixelFormat() {
78   return FORMAT_RGBA;
79 }
80
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);
86 }
87
88 }  // namespace remoting