Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/video_coding/main/source/frame_buffer.cc @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

File size: 7.4 KB
Line 
1/*
2 *  Copyright (c) 2012 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/video_coding/main/source/frame_buffer.h"
12
13#include <assert.h>
14#include <string.h>
15
16#include "webrtc/modules/video_coding/main/source/packet.h"
17
18namespace webrtc {
19
20VCMFrameBuffer::VCMFrameBuffer()
21  :
22    _state(kStateEmpty),
23    _frameCounted(false),
24    _nackCount(0),
25    _latestPacketTimeMs(-1) {
26}
27
28VCMFrameBuffer::~VCMFrameBuffer() {
29}
30
31VCMFrameBuffer::VCMFrameBuffer(const VCMFrameBuffer& rhs)
32:
33VCMEncodedFrame(rhs),
34_state(rhs._state),
35_frameCounted(rhs._frameCounted),
36_sessionInfo(),
37_nackCount(rhs._nackCount),
38_latestPacketTimeMs(rhs._latestPacketTimeMs) {
39    _sessionInfo = rhs._sessionInfo;
40    _sessionInfo.UpdateDataPointers(rhs._buffer, _buffer);
41}
42
43webrtc::FrameType
44VCMFrameBuffer::FrameType() const {
45    return _sessionInfo.FrameType();
46}
47
48int32_t
49VCMFrameBuffer::GetLowSeqNum() const {
50    return _sessionInfo.LowSequenceNumber();
51}
52
53int32_t
54VCMFrameBuffer::GetHighSeqNum() const {
55    return _sessionInfo.HighSequenceNumber();
56}
57
58int VCMFrameBuffer::PictureId() const {
59  return _sessionInfo.PictureId();
60}
61
62int VCMFrameBuffer::TemporalId() const {
63  return _sessionInfo.TemporalId();
64}
65
66bool VCMFrameBuffer::LayerSync() const {
67  return _sessionInfo.LayerSync();
68}
69
70int VCMFrameBuffer::Tl0PicId() const {
71  return _sessionInfo.Tl0PicId();
72}
73
74bool VCMFrameBuffer::NonReference() const {
75  return _sessionInfo.NonReference();
76}
77
78bool
79VCMFrameBuffer::IsSessionComplete() const {
80    return _sessionInfo.complete();
81}
82
83// Insert packet
84VCMFrameBufferEnum
85VCMFrameBuffer::InsertPacket(const VCMPacket& packet,
86                             int64_t timeInMs,
87                             VCMDecodeErrorMode decode_error_mode,
88                             const FrameData& frame_data) {
89    // Is this packet part of this frame?
90    if (TimeStamp() && (TimeStamp() != packet.timestamp)) {
91        return kTimeStampError;
92    }
93
94    // sanity checks
95    if (_size + packet.sizeBytes +
96        (packet.insertStartCode ?  kH264StartCodeLengthBytes : 0 )
97        > kMaxJBFrameSizeBytes) {
98        return kSizeError;
99    }
100    if (NULL == packet.dataPtr && packet.sizeBytes > 0) {
101        return kSizeError;
102    }
103    if (packet.dataPtr != NULL) {
104        _payloadType = packet.payloadType;
105    }
106
107    if (kStateEmpty == _state) {
108        // First packet (empty and/or media) inserted into this frame.
109        // store some info and set some initial values.
110        _timeStamp = packet.timestamp;
111        _codec = packet.codec;
112        if (packet.frameType != kFrameEmpty) {
113            // first media packet
114            SetState(kStateIncomplete);
115        }
116    }
117
118    uint32_t requiredSizeBytes = Length() + packet.sizeBytes +
119                   (packet.insertStartCode ? kH264StartCodeLengthBytes : 0);
120    if (requiredSizeBytes >= _size) {
121        const uint8_t* prevBuffer = _buffer;
122        const uint32_t increments = requiredSizeBytes /
123                                          kBufferIncStepSizeBytes +
124                                        (requiredSizeBytes %
125                                         kBufferIncStepSizeBytes > 0);
126        const uint32_t newSize = _size +
127                                       increments * kBufferIncStepSizeBytes;
128        if (newSize > kMaxJBFrameSizeBytes) {
129            return kSizeError;
130        }
131        if (VerifyAndAllocate(newSize) == -1) {
132            return kSizeError;
133        }
134        _sessionInfo.UpdateDataPointers(prevBuffer, _buffer);
135    }
136
137    if (packet.width > 0 && packet.height > 0) {
138      _encodedWidth = packet.width;
139      _encodedHeight = packet.height;
140    }
141
142    CopyCodecSpecific(&packet.codecSpecificHeader);
143
144    int retVal = _sessionInfo.InsertPacket(packet, _buffer,
145                                           decode_error_mode,
146                                           frame_data);
147    if (retVal == -1) {
148        return kSizeError;
149    } else if (retVal == -2) {
150        return kDuplicatePacket;
151    } else if (retVal == -3) {
152        return kOutOfBoundsPacket;
153    }
154    // update length
155    _length = Length() + static_cast<uint32_t>(retVal);
156
157    _latestPacketTimeMs = timeInMs;
158
159    if (_sessionInfo.complete()) {
160      SetState(kStateComplete);
161      return kCompleteSession;
162    } else if (_sessionInfo.decodable()) {
163      SetState(kStateDecodable);
164      return kDecodableSession;
165    }
166    return kIncomplete;
167}
168
169int64_t
170VCMFrameBuffer::LatestPacketTimeMs() const {
171    return _latestPacketTimeMs;
172}
173
174void
175VCMFrameBuffer::IncrementNackCount() {
176    _nackCount++;
177}
178
179int16_t
180VCMFrameBuffer::GetNackCount() const {
181    return _nackCount;
182}
183
184bool
185VCMFrameBuffer::HaveFirstPacket() const {
186    return _sessionInfo.HaveFirstPacket();
187}
188
189bool
190VCMFrameBuffer::HaveLastPacket() const {
191    return _sessionInfo.HaveLastPacket();
192}
193
194int
195VCMFrameBuffer::NumPackets() const {
196    return _sessionInfo.NumPackets();
197}
198
199void
200VCMFrameBuffer::Reset() {
201    _length = 0;
202    _timeStamp = 0;
203    _sessionInfo.Reset();
204    _frameCounted = false;
205    _payloadType = 0;
206    _nackCount = 0;
207    _latestPacketTimeMs = -1;
208    _state = kStateEmpty;
209    VCMEncodedFrame::Reset();
210}
211
212// Set state of frame
213void
214VCMFrameBuffer::SetState(VCMFrameBufferStateEnum state) {
215    if (_state == state) {
216        return;
217    }
218    switch (state) {
219    case kStateIncomplete:
220        // we can go to this state from state kStateEmpty
221        assert(_state == kStateEmpty);
222
223        // Do nothing, we received a packet
224        break;
225
226    case kStateComplete:
227        assert(_state == kStateEmpty ||
228               _state == kStateIncomplete ||
229               _state == kStateDecodable);
230
231        break;
232
233    case kStateEmpty:
234        // Should only be set to empty through Reset().
235        assert(false);
236        break;
237
238    case kStateDecodable:
239        assert(_state == kStateEmpty ||
240               _state == kStateIncomplete);
241        break;
242    }
243    _state = state;
244}
245
246// Set counted status (as counted by JB or not)
247void VCMFrameBuffer::SetCountedFrame(bool frameCounted) {
248    _frameCounted = frameCounted;
249}
250
251bool VCMFrameBuffer::GetCountedFrame() const {
252    return _frameCounted;
253}
254
255// Get current state of frame
256VCMFrameBufferStateEnum
257VCMFrameBuffer::GetState() const {
258    return _state;
259}
260
261// Get current state of frame
262VCMFrameBufferStateEnum
263VCMFrameBuffer::GetState(uint32_t& timeStamp) const {
264    timeStamp = TimeStamp();
265    return GetState();
266}
267
268bool
269VCMFrameBuffer::IsRetransmitted() const {
270    return _sessionInfo.session_nack();
271}
272
273void
274VCMFrameBuffer::PrepareForDecode(bool continuous) {
275#ifdef INDEPENDENT_PARTITIONS
276    if (_codec == kVideoCodecVP8) {
277        _length =
278            _sessionInfo.BuildVP8FragmentationHeader(_buffer, _length,
279                                                     &_fragmentation);
280    } else {
281        int bytes_removed = _sessionInfo.MakeDecodable();
282        _length -= bytes_removed;
283    }
284#else
285    int bytes_removed = _sessionInfo.MakeDecodable();
286    _length -= bytes_removed;
287#endif
288    // Transfer frame information to EncodedFrame and create any codec
289    // specific information.
290    _frameType = ConvertFrameType(_sessionInfo.FrameType());
291    _completeFrame = _sessionInfo.complete();
292    _missingFrame = !continuous;
293}
294
295}  // namespace webrtc
Note: See TracBrowser for help on using the repository browser.