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