Upstream version 9.37.193.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / video_frame_deliverer.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 "content/renderer/media/video_frame_deliverer.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9
10 namespace content {
11 namespace {
12 void ResetCallback(scoped_ptr<VideoCaptureDeliverFrameCB> callback) {
13   // |callback| will be deleted when this exits.
14 }
15 }  // namespace
16
17 VideoFrameDeliverer::VideoFrameDeliverer(
18     const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
19     : io_message_loop_(io_message_loop) {
20   DCHECK(io_message_loop_);
21 }
22
23 VideoFrameDeliverer::~VideoFrameDeliverer() {
24   DCHECK(callbacks_.empty());
25 }
26
27 void VideoFrameDeliverer::AddCallback(
28     void* id,
29     const VideoCaptureDeliverFrameCB& callback) {
30   DCHECK(thread_checker_.CalledOnValidThread());
31   io_message_loop_->PostTask(
32       FROM_HERE,
33       base::Bind(&VideoFrameDeliverer::AddCallbackOnIO,
34                  this, id, callback));
35 }
36
37 void VideoFrameDeliverer::AddCallbackOnIO(
38     void* id,
39     const VideoCaptureDeliverFrameCB& callback) {
40   DCHECK(io_message_loop_->BelongsToCurrentThread());
41   callbacks_.push_back(std::make_pair(id, callback));
42 }
43
44 void VideoFrameDeliverer::RemoveCallback(void* id) {
45   DCHECK(thread_checker_.CalledOnValidThread());
46   io_message_loop_->PostTask(
47       FROM_HERE,
48       base::Bind(&VideoFrameDeliverer::RemoveCallbackOnIO,
49                  this, id, base::MessageLoopProxy::current()));
50 }
51
52 void VideoFrameDeliverer::RemoveCallbackOnIO(
53     void* id, const scoped_refptr<base::MessageLoopProxy>& message_loop) {
54   DCHECK(io_message_loop_->BelongsToCurrentThread());
55   std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin();
56   for (; it != callbacks_.end(); ++it) {
57     if (it->first == id) {
58       // Callback is copied to heap and then deleted on the target thread.
59       // The following code ensures that the callback is not referenced on
60       // the stack.
61       scoped_ptr<VideoCaptureDeliverFrameCB> callback;
62       {
63         callback.reset(new VideoCaptureDeliverFrameCB(it->second));
64         callbacks_.erase(it);
65       }
66       message_loop->PostTask(
67           FROM_HERE, base::Bind(&ResetCallback, base::Passed(&callback)));
68       return;
69     }
70   }
71 }
72
73 void VideoFrameDeliverer::DeliverFrameOnIO(
74     const scoped_refptr<media::VideoFrame>& frame,
75     const media::VideoCaptureFormat& format,
76     const base::TimeTicks& estimated_capture_time) {
77   DCHECK(io_message_loop_->BelongsToCurrentThread());
78   for (std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin();
79        it != callbacks_.end(); ++it) {
80     it->second.Run(frame, format, estimated_capture_time);
81   }
82 }
83
84 }  // namespace content