Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / utility / source / video_frames_queue.cc
1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include "webrtc/modules/utility/source/video_frames_queue.h"
12
13 #ifdef WEBRTC_MODULE_UTILITY_VIDEO
14
15 #include <assert.h>
16
17 #include "webrtc/common_video/interface/texture_video_frame.h"
18 #include "webrtc/modules/interface/module_common_types.h"
19 #include "webrtc/system_wrappers/interface/logging.h"
20 #include "webrtc/system_wrappers/interface/tick_util.h"
21
22 namespace webrtc {
23 VideoFramesQueue::VideoFramesQueue()
24     : _renderDelayMs(10)
25 {
26 }
27
28 VideoFramesQueue::~VideoFramesQueue() {
29   for (FrameList::iterator iter = _incomingFrames.begin();
30        iter != _incomingFrames.end(); ++iter) {
31       delete *iter;
32   }
33   for (FrameList::iterator iter = _emptyFrames.begin();
34        iter != _emptyFrames.end(); ++iter) {
35       delete *iter;
36   }
37 }
38
39 int32_t VideoFramesQueue::AddFrame(const I420VideoFrame& newFrame) {
40   if (newFrame.native_handle() != NULL) {
41     _incomingFrames.push_back(new TextureVideoFrame(
42         static_cast<NativeHandle*>(newFrame.native_handle()),
43         newFrame.width(),
44         newFrame.height(),
45         newFrame.timestamp(),
46         newFrame.render_time_ms()));
47     return 0;
48   }
49
50   I420VideoFrame* ptrFrameToAdd = NULL;
51   // Try to re-use a VideoFrame. Only allocate new memory if it is necessary.
52   if (!_emptyFrames.empty()) {
53     ptrFrameToAdd = _emptyFrames.front();
54     _emptyFrames.pop_front();
55   }
56   if (!ptrFrameToAdd) {
57     if (_emptyFrames.size() + _incomingFrames.size() >
58         KMaxNumberOfFrames) {
59       LOG(LS_WARNING) << "Too many frames, limit: " << KMaxNumberOfFrames;
60       return -1;
61     }
62     ptrFrameToAdd = new I420VideoFrame();
63   }
64   ptrFrameToAdd->CopyFrame(newFrame);
65   _incomingFrames.push_back(ptrFrameToAdd);
66   return 0;
67 }
68
69 // Find the most recent frame that has a VideoFrame::RenderTimeMs() that is
70 // lower than current time in ms (TickTime::MillisecondTimestamp()).
71 // Note _incomingFrames is sorted so that the oldest frame is first.
72 // Recycle all frames that are older than the most recent frame.
73 I420VideoFrame* VideoFramesQueue::FrameToRecord() {
74   I420VideoFrame* ptrRenderFrame = NULL;
75   for (FrameList::iterator iter = _incomingFrames.begin();
76        iter != _incomingFrames.end(); ++iter) {
77     I420VideoFrame* ptrOldestFrameInList = *iter;
78     if (ptrOldestFrameInList->render_time_ms() <=
79         TickTime::MillisecondTimestamp() + _renderDelayMs) {
80       // List is traversed beginning to end. If ptrRenderFrame is not
81       // NULL it must be the first, and thus oldest, VideoFrame in the
82       // queue. It can be recycled.
83       if (ptrRenderFrame) {
84         ReturnFrame(ptrRenderFrame);
85        _incomingFrames.pop_front();
86       }
87       ptrRenderFrame = ptrOldestFrameInList;
88     } else {
89       // All VideoFrames following this one will be even newer. No match
90       // will be found.
91       break;
92     }
93   }
94   return ptrRenderFrame;
95 }
96
97 int32_t VideoFramesQueue::ReturnFrame(I420VideoFrame* ptrOldFrame) {
98   // No need to reuse texture frames because they do not allocate memory.
99   if (ptrOldFrame->native_handle() == NULL) {
100     ptrOldFrame->set_timestamp(0);
101     ptrOldFrame->set_width(0);
102     ptrOldFrame->set_height(0);
103     ptrOldFrame->set_render_time_ms(0);
104     ptrOldFrame->ResetSize();
105     _emptyFrames.push_back(ptrOldFrame);
106   } else {
107     delete ptrOldFrame;
108   }
109   return 0;
110 }
111
112 int32_t VideoFramesQueue::SetRenderDelay(uint32_t renderDelay) {
113   _renderDelayMs = renderDelay;
114   return 0;
115 }
116 }  // namespace webrtc
117 #endif // WEBRTC_MODULE_UTILITY_VIDEO