2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/utility/source/video_frames_queue.h"
13 #ifdef WEBRTC_MODULE_UTILITY_VIDEO
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"
23 VideoFramesQueue::VideoFramesQueue()
28 VideoFramesQueue::~VideoFramesQueue() {
29 for (FrameList::iterator iter = _incomingFrames.begin();
30 iter != _incomingFrames.end(); ++iter) {
33 for (FrameList::iterator iter = _emptyFrames.begin();
34 iter != _emptyFrames.end(); ++iter) {
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()),
46 newFrame.render_time_ms()));
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();
57 if (_emptyFrames.size() + _incomingFrames.size() >
59 LOG(LS_WARNING) << "Too many frames, limit: " << KMaxNumberOfFrames;
62 ptrFrameToAdd = new I420VideoFrame();
64 ptrFrameToAdd->CopyFrame(newFrame);
65 _incomingFrames.push_back(ptrFrameToAdd);
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.
84 ReturnFrame(ptrRenderFrame);
85 _incomingFrames.pop_front();
87 ptrRenderFrame = ptrOldestFrameInList;
89 // All VideoFrames following this one will be even newer. No match
94 return ptrRenderFrame;
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);
112 int32_t VideoFramesQueue::SetRenderDelay(uint32_t renderDelay) {
113 _renderDelayMs = renderDelay;
116 } // namespace webrtc
117 #endif // WEBRTC_MODULE_UTILITY_VIDEO