blob: cc3a91eeacdb9d41dcbd0a5839ab057104918402 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgddab60b2012-04-23 14:52:15 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
Henrik Kjellander2557b862015-11-18 22:00:21 +010011#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"
niklase@google.com470e71d2011-07-07 08:21:25 +000015
16namespace webrtc {
17
18VCMEncodedFrame::VCMEncodedFrame()
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000019 : webrtc::EncodedImage(),
20 _renderTimeMs(-1),
21 _payloadType(0),
22 _missingFrame(false),
23 _codec(kVideoCodecUnknown),
24 _fragmentation(),
25 _rotation(kVideoRotation_0),
26 _rotation_set(false) {
philipel9d3ab612015-12-21 04:12:39 -080027 _codecSpecificInfo.codecType = kVideoCodecUnknown;
niklase@google.com470e71d2011-07-07 08:21:25 +000028}
29
30VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs)
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000031 : 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) {
philipel9d3ab612015-12-21 04:12:39 -080039 _codecSpecificInfo.codecType = kVideoCodecUnknown;
40 _buffer = NULL;
41 _size = 0;
42 _length = 0;
43 if (rhs._buffer != NULL) {
hbosd6648362016-01-21 05:43:11 -080044 VerifyAndAllocate(rhs._length +
45 EncodedImage::GetBufferPaddingBytes(_codec));
philipel9d3ab612015-12-21 04:12:39 -080046 memcpy(_buffer, rhs._buffer, rhs._length);
47 }
niklase@google.com470e71d2011-07-07 08:21:25 +000048}
49
50VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame& rhs)
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000051 : webrtc::EncodedImage(rhs),
52 _renderTimeMs(rhs._renderTimeMs),
53 _payloadType(rhs._payloadType),
54 _missingFrame(rhs._missingFrame),
55 _codecSpecificInfo(rhs._codecSpecificInfo),
56 _codec(rhs._codec),
57 _fragmentation(),
58 _rotation(rhs._rotation),
59 _rotation_set(rhs._rotation_set) {
stefan@webrtc.orgc3d89102011-09-08 06:50:28 +000060 _buffer = NULL;
61 _size = 0;
62 _length = 0;
philipel9d3ab612015-12-21 04:12:39 -080063 if (rhs._buffer != NULL) {
hbosd6648362016-01-21 05:43:11 -080064 VerifyAndAllocate(rhs._length +
65 EncodedImage::GetBufferPaddingBytes(_codec));
philipel9d3ab612015-12-21 04:12:39 -080066 memcpy(_buffer, rhs._buffer, rhs._length);
67 _length = rhs._length;
stefan@webrtc.orgc3d89102011-09-08 06:50:28 +000068 }
andrew@webrtc.org418443c2012-11-23 19:17:23 +000069 _fragmentation.CopyFrom(rhs._fragmentation);
niklase@google.com470e71d2011-07-07 08:21:25 +000070}
71
philipel9d3ab612015-12-21 04:12:39 -080072VCMEncodedFrame::~VCMEncodedFrame() {
73 Free();
niklase@google.com470e71d2011-07-07 08:21:25 +000074}
75
philipel9d3ab612015-12-21 04:12:39 -080076void VCMEncodedFrame::Free() {
77 Reset();
78 if (_buffer != NULL) {
79 delete[] _buffer;
80 _buffer = NULL;
81 }
niklase@google.com470e71d2011-07-07 08:21:25 +000082}
83
philipel9d3ab612015-12-21 04:12:39 -080084void VCMEncodedFrame::Reset() {
85 _renderTimeMs = -1;
86 _timeStamp = 0;
87 _payloadType = 0;
88 _frameType = kVideoFrameDelta;
89 _encodedWidth = 0;
90 _encodedHeight = 0;
91 _completeFrame = false;
92 _missingFrame = false;
93 _length = 0;
94 _codecSpecificInfo.codecType = kVideoCodecUnknown;
95 _codec = kVideoCodecUnknown;
96 _rotation = kVideoRotation_0;
97 _rotation_set = false;
niklase@google.com470e71d2011-07-07 08:21:25 +000098}
99
philipel9d3ab612015-12-21 04:12:39 -0800100void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header) {
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000101 if (header) {
102 switch (header->codec) {
103 case kRtpVideoVp8: {
104 if (_codecSpecificInfo.codecType != kVideoCodecVP8) {
105 // This is the first packet for this frame.
106 _codecSpecificInfo.codecSpecific.VP8.pictureId = -1;
107 _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
108 _codecSpecificInfo.codecSpecific.VP8.layerSync = false;
109 _codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
110 _codecSpecificInfo.codecType = kVideoCodecVP8;
henrik.lundin@webrtc.org473bac82011-08-17 09:47:33 +0000111 }
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000112 _codecSpecificInfo.codecSpecific.VP8.nonReference =
113 header->codecHeader.VP8.nonReference;
114 if (header->codecHeader.VP8.pictureId != kNoPictureId) {
115 _codecSpecificInfo.codecSpecific.VP8.pictureId =
116 header->codecHeader.VP8.pictureId;
117 }
118 if (header->codecHeader.VP8.temporalIdx != kNoTemporalIdx) {
119 _codecSpecificInfo.codecSpecific.VP8.temporalIdx =
120 header->codecHeader.VP8.temporalIdx;
121 _codecSpecificInfo.codecSpecific.VP8.layerSync =
122 header->codecHeader.VP8.layerSync;
123 }
124 if (header->codecHeader.VP8.keyIdx != kNoKeyIdx) {
125 _codecSpecificInfo.codecSpecific.VP8.keyIdx =
126 header->codecHeader.VP8.keyIdx;
127 }
128 break;
129 }
asaperssona9455ab2015-07-31 06:10:09 -0700130 case kRtpVideoVp9: {
131 if (_codecSpecificInfo.codecType != kVideoCodecVP9) {
132 // This is the first packet for this frame.
133 _codecSpecificInfo.codecSpecific.VP9.picture_id = -1;
134 _codecSpecificInfo.codecSpecific.VP9.temporal_idx = 0;
135 _codecSpecificInfo.codecSpecific.VP9.spatial_idx = 0;
136 _codecSpecificInfo.codecSpecific.VP9.gof_idx = 0;
137 _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted = false;
138 _codecSpecificInfo.codecSpecific.VP9.tl0_pic_idx = -1;
139 _codecSpecificInfo.codecType = kVideoCodecVP9;
140 }
141 _codecSpecificInfo.codecSpecific.VP9.inter_pic_predicted =
142 header->codecHeader.VP9.inter_pic_predicted;
143 _codecSpecificInfo.codecSpecific.VP9.flexible_mode =
144 header->codecHeader.VP9.flexible_mode;
philipelcfc319b2015-11-10 07:17:23 -0800145 _codecSpecificInfo.codecSpecific.VP9.num_ref_pics =
146 header->codecHeader.VP9.num_ref_pics;
147 for (uint8_t r = 0; r < header->codecHeader.VP9.num_ref_pics; ++r) {
148 _codecSpecificInfo.codecSpecific.VP9.p_diff[r] =
149 header->codecHeader.VP9.pid_diff[r];
150 }
asaperssona9455ab2015-07-31 06:10:09 -0700151 _codecSpecificInfo.codecSpecific.VP9.ss_data_available =
152 header->codecHeader.VP9.ss_data_available;
153 if (header->codecHeader.VP9.picture_id != kNoPictureId) {
154 _codecSpecificInfo.codecSpecific.VP9.picture_id =
155 header->codecHeader.VP9.picture_id;
156 }
157 if (header->codecHeader.VP9.tl0_pic_idx != kNoTl0PicIdx) {
158 _codecSpecificInfo.codecSpecific.VP9.tl0_pic_idx =
159 header->codecHeader.VP9.tl0_pic_idx;
160 }
161 if (header->codecHeader.VP9.temporal_idx != kNoTemporalIdx) {
162 _codecSpecificInfo.codecSpecific.VP9.temporal_idx =
163 header->codecHeader.VP9.temporal_idx;
164 _codecSpecificInfo.codecSpecific.VP9.temporal_up_switch =
165 header->codecHeader.VP9.temporal_up_switch;
166 }
167 if (header->codecHeader.VP9.spatial_idx != kNoSpatialIdx) {
168 _codecSpecificInfo.codecSpecific.VP9.spatial_idx =
169 header->codecHeader.VP9.spatial_idx;
170 _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted =
171 header->codecHeader.VP9.inter_layer_predicted;
172 }
173 if (header->codecHeader.VP9.gof_idx != kNoGofIdx) {
174 _codecSpecificInfo.codecSpecific.VP9.gof_idx =
175 header->codecHeader.VP9.gof_idx;
176 }
177 if (header->codecHeader.VP9.ss_data_available) {
178 _codecSpecificInfo.codecSpecific.VP9.num_spatial_layers =
179 header->codecHeader.VP9.num_spatial_layers;
180 _codecSpecificInfo.codecSpecific.VP9
181 .spatial_layer_resolution_present =
182 header->codecHeader.VP9.spatial_layer_resolution_present;
183 if (header->codecHeader.VP9.spatial_layer_resolution_present) {
184 for (size_t i = 0; i < header->codecHeader.VP9.num_spatial_layers;
185 ++i) {
186 _codecSpecificInfo.codecSpecific.VP9.width[i] =
187 header->codecHeader.VP9.width[i];
188 _codecSpecificInfo.codecSpecific.VP9.height[i] =
189 header->codecHeader.VP9.height[i];
190 }
191 }
192 _codecSpecificInfo.codecSpecific.VP9.gof.CopyGofInfoVP9(
193 header->codecHeader.VP9.gof);
194 }
195 break;
196 }
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000197 case kRtpVideoH264: {
198 _codecSpecificInfo.codecType = kVideoCodecH264;
199 break;
200 }
201 default: {
202 _codecSpecificInfo.codecType = kVideoCodecUnknown;
203 break;
204 }
henrik.lundin@webrtc.org473bac82011-08-17 09:47:33 +0000205 }
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000206 }
henrik.lundin@webrtc.org473bac82011-08-17 09:47:33 +0000207}
208
stefan@webrtc.orgc3d89102011-09-08 06:50:28 +0000209const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const {
210 return &_fragmentation;
211}
212
philipel9d3ab612015-12-21 04:12:39 -0800213void VCMEncodedFrame::VerifyAndAllocate(size_t minimumSize) {
214 if (minimumSize > _size) {
215 // create buffer of sufficient size
216 uint8_t* newBuffer = new uint8_t[minimumSize];
217 if (_buffer) {
218 // copy old data
219 memcpy(newBuffer, _buffer, _size);
220 delete[] _buffer;
niklase@google.com470e71d2011-07-07 08:21:25 +0000221 }
philipel9d3ab612015-12-21 04:12:39 -0800222 _buffer = newBuffer;
223 _size = minimumSize;
224 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000225}
226
pbos22993e12015-10-19 02:39:06 -0700227} // namespace webrtc