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/interface/video_coding_defines.h"
12 #include "webrtc/modules/video_coding/main/source/encoded_frame.h"
13 #include "webrtc/modules/video_coding/main/source/generic_encoder.h"
14 #include "webrtc/modules/video_coding/main/source/jitter_buffer_common.h"
15
16 namespace webrtc {
17
VCMEncodedFrame()18 VCMEncodedFrame::VCMEncodedFrame()
19 :
20 webrtc::EncodedImage(),
21 _renderTimeMs(-1),
22 _payloadType(0),
23 _missingFrame(false),
24 _codec(kVideoCodecUnknown),
25 _fragmentation()
26 {
27 _codecSpecificInfo.codecType = kVideoCodecUnknown;
28 }
29
VCMEncodedFrame(const webrtc::EncodedImage & rhs)30 VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs)
31 :
32 webrtc::EncodedImage(rhs),
33 _renderTimeMs(-1),
34 _payloadType(0),
35 _missingFrame(false),
36 _codec(kVideoCodecUnknown),
37 _fragmentation()
38 {
39 _codecSpecificInfo.codecType = kVideoCodecUnknown;
40 _buffer = NULL;
41 _size = 0;
42 _length = 0;
43 if (rhs._buffer != NULL)
44 {
45 VerifyAndAllocate(rhs._length);
46 memcpy(_buffer, rhs._buffer, rhs._length);
47 }
48 }
49
VCMEncodedFrame(const VCMEncodedFrame & rhs)50 VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame& rhs)
51 :
52 webrtc::EncodedImage(rhs),
53 _renderTimeMs(rhs._renderTimeMs),
54 _payloadType(rhs._payloadType),
55 _missingFrame(rhs._missingFrame),
56 _codecSpecificInfo(rhs._codecSpecificInfo),
57 _codec(rhs._codec),
58 _fragmentation() {
59 _buffer = NULL;
60 _size = 0;
61 _length = 0;
62 if (rhs._buffer != NULL)
63 {
64 VerifyAndAllocate(rhs._length);
65 memcpy(_buffer, rhs._buffer, rhs._length);
66 _length = rhs._length;
67 }
68 _fragmentation.CopyFrom(rhs._fragmentation);
69 }
70
~VCMEncodedFrame()71 VCMEncodedFrame::~VCMEncodedFrame()
72 {
73 Free();
74 }
75
Free()76 void VCMEncodedFrame::Free()
77 {
78 Reset();
79 if (_buffer != NULL)
80 {
81 delete [] _buffer;
82 _buffer = NULL;
83 }
84 }
85
Reset()86 void VCMEncodedFrame::Reset()
87 {
88 _renderTimeMs = -1;
89 _timeStamp = 0;
90 _payloadType = 0;
91 _frameType = kDeltaFrame;
92 _encodedWidth = 0;
93 _encodedHeight = 0;
94 _completeFrame = false;
95 _missingFrame = false;
96 _length = 0;
97 _codecSpecificInfo.codecType = kVideoCodecUnknown;
98 _codec = kVideoCodecUnknown;
99 }
100
CopyCodecSpecific(const RTPVideoHeader * header)101 void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header)
102 {
103 if (header)
104 {
105 switch (header->codec)
106 {
107 case kRtpVideoVp8:
108 {
109 if (_codecSpecificInfo.codecType != kVideoCodecVP8)
110 {
111 // This is the first packet for this frame.
112 _codecSpecificInfo.codecSpecific.VP8.pictureId = -1;
113 _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
114 _codecSpecificInfo.codecSpecific.VP8.layerSync = false;
115 _codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
116 _codecSpecificInfo.codecType = kVideoCodecVP8;
117 }
118 _codecSpecificInfo.codecSpecific.VP8.nonReference =
119 header->codecHeader.VP8.nonReference;
120 if (header->codecHeader.VP8.pictureId != kNoPictureId)
121 {
122 _codecSpecificInfo.codecSpecific.VP8.pictureId =
123 header->codecHeader.VP8.pictureId;
124 }
125 if (header->codecHeader.VP8.temporalIdx != kNoTemporalIdx)
126 {
127 _codecSpecificInfo.codecSpecific.VP8.temporalIdx =
128 header->codecHeader.VP8.temporalIdx;
129 _codecSpecificInfo.codecSpecific.VP8.layerSync =
130 header->codecHeader.VP8.layerSync;
131 }
132 if (header->codecHeader.VP8.keyIdx != kNoKeyIdx)
133 {
134 _codecSpecificInfo.codecSpecific.VP8.keyIdx =
135 header->codecHeader.VP8.keyIdx;
136 }
137 break;
138 }
139 default:
140 {
141 _codecSpecificInfo.codecType = kVideoCodecUnknown;
142 break;
143 }
144 }
145 }
146 }
147
FragmentationHeader() const148 const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const {
149 return &_fragmentation;
150 }
151
VerifyAndAllocate(const uint32_t minimumSize)152 void VCMEncodedFrame::VerifyAndAllocate(const uint32_t minimumSize)
153 {
154 if(minimumSize > _size)
155 {
156 // create buffer of sufficient size
157 uint8_t* newBuffer = new uint8_t[minimumSize];
158 if(_buffer)
159 {
160 // copy old data
161 memcpy(newBuffer, _buffer, _size);
162 delete [] _buffer;
163 }
164 _buffer = newBuffer;
165 _size = minimumSize;
166 }
167 }
168
ConvertFrameType(VideoFrameType frameType)169 webrtc::FrameType VCMEncodedFrame::ConvertFrameType(VideoFrameType frameType)
170 {
171 switch(frameType) {
172 case kKeyFrame:
173 return kVideoFrameKey;
174 case kDeltaFrame:
175 return kVideoFrameDelta;
176 case kSkipFrame:
177 return kFrameEmpty;
178 default:
179 return kVideoFrameDelta;
180 }
181 }
182
ConvertFrameType(webrtc::FrameType frame_type)183 VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frame_type) {
184 switch (frame_type) {
185 case kVideoFrameKey:
186 return kKeyFrame;
187 case kVideoFrameDelta:
188 return kDeltaFrame;
189 default:
190 assert(false);
191 return kDeltaFrame;
192 }
193 }
194
ConvertFrameTypes(const std::vector<webrtc::FrameType> & frame_types,std::vector<VideoFrameType> * video_frame_types)195 void VCMEncodedFrame::ConvertFrameTypes(
196 const std::vector<webrtc::FrameType>& frame_types,
197 std::vector<VideoFrameType>* video_frame_types) {
198 assert(video_frame_types);
199 video_frame_types->reserve(frame_types.size());
200 for (size_t i = 0; i < frame_types.size(); ++i) {
201 (*video_frame_types)[i] = ConvertFrameType(frame_types[i]);
202 }
203 }
204
205 }
206