blob: 23e681d9aefecc7bec4c2d44efe8ec2c875c60bb [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(),
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000025 _rotation_set(false) {
philipel9d3ab612015-12-21 04:12:39 -080026 _codecSpecificInfo.codecType = kVideoCodecUnknown;
niklase@google.com470e71d2011-07-07 08:21:25 +000027}
28
29VCMEncodedFrame::VCMEncodedFrame(const webrtc::EncodedImage& rhs)
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000030 : webrtc::EncodedImage(rhs),
31 _renderTimeMs(-1),
32 _payloadType(0),
33 _missingFrame(false),
34 _codec(kVideoCodecUnknown),
35 _fragmentation(),
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000036 _rotation_set(false) {
philipel9d3ab612015-12-21 04:12:39 -080037 _codecSpecificInfo.codecType = kVideoCodecUnknown;
38 _buffer = NULL;
39 _size = 0;
40 _length = 0;
41 if (rhs._buffer != NULL) {
hbosd6648362016-01-21 05:43:11 -080042 VerifyAndAllocate(rhs._length +
43 EncodedImage::GetBufferPaddingBytes(_codec));
philipel9d3ab612015-12-21 04:12:39 -080044 memcpy(_buffer, rhs._buffer, rhs._length);
45 }
niklase@google.com470e71d2011-07-07 08:21:25 +000046}
47
48VCMEncodedFrame::VCMEncodedFrame(const VCMEncodedFrame& rhs)
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000049 : webrtc::EncodedImage(rhs),
50 _renderTimeMs(rhs._renderTimeMs),
51 _payloadType(rhs._payloadType),
52 _missingFrame(rhs._missingFrame),
53 _codecSpecificInfo(rhs._codecSpecificInfo),
54 _codec(rhs._codec),
55 _fragmentation(),
guoweis@webrtc.org54d072e2015-03-17 21:54:50 +000056 _rotation_set(rhs._rotation_set) {
stefan@webrtc.orgc3d89102011-09-08 06:50:28 +000057 _buffer = NULL;
58 _size = 0;
59 _length = 0;
philipel9d3ab612015-12-21 04:12:39 -080060 if (rhs._buffer != NULL) {
hbosd6648362016-01-21 05:43:11 -080061 VerifyAndAllocate(rhs._length +
62 EncodedImage::GetBufferPaddingBytes(_codec));
philipel9d3ab612015-12-21 04:12:39 -080063 memcpy(_buffer, rhs._buffer, rhs._length);
64 _length = rhs._length;
stefan@webrtc.orgc3d89102011-09-08 06:50:28 +000065 }
andrew@webrtc.org418443c2012-11-23 19:17:23 +000066 _fragmentation.CopyFrom(rhs._fragmentation);
niklase@google.com470e71d2011-07-07 08:21:25 +000067}
68
philipel9d3ab612015-12-21 04:12:39 -080069VCMEncodedFrame::~VCMEncodedFrame() {
70 Free();
niklase@google.com470e71d2011-07-07 08:21:25 +000071}
72
philipel9d3ab612015-12-21 04:12:39 -080073void VCMEncodedFrame::Free() {
74 Reset();
75 if (_buffer != NULL) {
76 delete[] _buffer;
77 _buffer = NULL;
78 }
niklase@google.com470e71d2011-07-07 08:21:25 +000079}
80
philipel9d3ab612015-12-21 04:12:39 -080081void VCMEncodedFrame::Reset() {
82 _renderTimeMs = -1;
83 _timeStamp = 0;
84 _payloadType = 0;
85 _frameType = kVideoFrameDelta;
86 _encodedWidth = 0;
87 _encodedHeight = 0;
88 _completeFrame = false;
89 _missingFrame = false;
90 _length = 0;
91 _codecSpecificInfo.codecType = kVideoCodecUnknown;
92 _codec = kVideoCodecUnknown;
perkj414dda12016-07-04 01:45:23 -070093 rotation_ = kVideoRotation_0;
philipel9d3ab612015-12-21 04:12:39 -080094 _rotation_set = false;
niklase@google.com470e71d2011-07-07 08:21:25 +000095}
96
philipel9d3ab612015-12-21 04:12:39 -080097void VCMEncodedFrame::CopyCodecSpecific(const RTPVideoHeader* header) {
stefan@webrtc.org2ec56062014-07-31 14:59:24 +000098 if (header) {
99 switch (header->codec) {
100 case kRtpVideoVp8: {
101 if (_codecSpecificInfo.codecType != kVideoCodecVP8) {
102 // This is the first packet for this frame.
103 _codecSpecificInfo.codecSpecific.VP8.pictureId = -1;
104 _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0;
105 _codecSpecificInfo.codecSpecific.VP8.layerSync = false;
106 _codecSpecificInfo.codecSpecific.VP8.keyIdx = -1;
107 _codecSpecificInfo.codecType = kVideoCodecVP8;
henrik.lundin@webrtc.org473bac82011-08-17 09:47:33 +0000108 }
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000109 _codecSpecificInfo.codecSpecific.VP8.nonReference =
110 header->codecHeader.VP8.nonReference;
111 if (header->codecHeader.VP8.pictureId != kNoPictureId) {
112 _codecSpecificInfo.codecSpecific.VP8.pictureId =
113 header->codecHeader.VP8.pictureId;
114 }
115 if (header->codecHeader.VP8.temporalIdx != kNoTemporalIdx) {
116 _codecSpecificInfo.codecSpecific.VP8.temporalIdx =
117 header->codecHeader.VP8.temporalIdx;
118 _codecSpecificInfo.codecSpecific.VP8.layerSync =
119 header->codecHeader.VP8.layerSync;
120 }
121 if (header->codecHeader.VP8.keyIdx != kNoKeyIdx) {
122 _codecSpecificInfo.codecSpecific.VP8.keyIdx =
123 header->codecHeader.VP8.keyIdx;
124 }
125 break;
126 }
asaperssona9455ab2015-07-31 06:10:09 -0700127 case kRtpVideoVp9: {
128 if (_codecSpecificInfo.codecType != kVideoCodecVP9) {
129 // This is the first packet for this frame.
130 _codecSpecificInfo.codecSpecific.VP9.picture_id = -1;
131 _codecSpecificInfo.codecSpecific.VP9.temporal_idx = 0;
132 _codecSpecificInfo.codecSpecific.VP9.spatial_idx = 0;
133 _codecSpecificInfo.codecSpecific.VP9.gof_idx = 0;
134 _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted = false;
135 _codecSpecificInfo.codecSpecific.VP9.tl0_pic_idx = -1;
136 _codecSpecificInfo.codecType = kVideoCodecVP9;
137 }
138 _codecSpecificInfo.codecSpecific.VP9.inter_pic_predicted =
139 header->codecHeader.VP9.inter_pic_predicted;
140 _codecSpecificInfo.codecSpecific.VP9.flexible_mode =
141 header->codecHeader.VP9.flexible_mode;
philipelcfc319b2015-11-10 07:17:23 -0800142 _codecSpecificInfo.codecSpecific.VP9.num_ref_pics =
143 header->codecHeader.VP9.num_ref_pics;
144 for (uint8_t r = 0; r < header->codecHeader.VP9.num_ref_pics; ++r) {
145 _codecSpecificInfo.codecSpecific.VP9.p_diff[r] =
146 header->codecHeader.VP9.pid_diff[r];
147 }
asaperssona9455ab2015-07-31 06:10:09 -0700148 _codecSpecificInfo.codecSpecific.VP9.ss_data_available =
149 header->codecHeader.VP9.ss_data_available;
150 if (header->codecHeader.VP9.picture_id != kNoPictureId) {
151 _codecSpecificInfo.codecSpecific.VP9.picture_id =
152 header->codecHeader.VP9.picture_id;
153 }
154 if (header->codecHeader.VP9.tl0_pic_idx != kNoTl0PicIdx) {
155 _codecSpecificInfo.codecSpecific.VP9.tl0_pic_idx =
156 header->codecHeader.VP9.tl0_pic_idx;
157 }
158 if (header->codecHeader.VP9.temporal_idx != kNoTemporalIdx) {
159 _codecSpecificInfo.codecSpecific.VP9.temporal_idx =
160 header->codecHeader.VP9.temporal_idx;
161 _codecSpecificInfo.codecSpecific.VP9.temporal_up_switch =
162 header->codecHeader.VP9.temporal_up_switch;
163 }
164 if (header->codecHeader.VP9.spatial_idx != kNoSpatialIdx) {
165 _codecSpecificInfo.codecSpecific.VP9.spatial_idx =
166 header->codecHeader.VP9.spatial_idx;
167 _codecSpecificInfo.codecSpecific.VP9.inter_layer_predicted =
168 header->codecHeader.VP9.inter_layer_predicted;
169 }
170 if (header->codecHeader.VP9.gof_idx != kNoGofIdx) {
171 _codecSpecificInfo.codecSpecific.VP9.gof_idx =
172 header->codecHeader.VP9.gof_idx;
173 }
174 if (header->codecHeader.VP9.ss_data_available) {
175 _codecSpecificInfo.codecSpecific.VP9.num_spatial_layers =
176 header->codecHeader.VP9.num_spatial_layers;
177 _codecSpecificInfo.codecSpecific.VP9
178 .spatial_layer_resolution_present =
179 header->codecHeader.VP9.spatial_layer_resolution_present;
180 if (header->codecHeader.VP9.spatial_layer_resolution_present) {
181 for (size_t i = 0; i < header->codecHeader.VP9.num_spatial_layers;
182 ++i) {
183 _codecSpecificInfo.codecSpecific.VP9.width[i] =
184 header->codecHeader.VP9.width[i];
185 _codecSpecificInfo.codecSpecific.VP9.height[i] =
186 header->codecHeader.VP9.height[i];
187 }
188 }
189 _codecSpecificInfo.codecSpecific.VP9.gof.CopyGofInfoVP9(
190 header->codecHeader.VP9.gof);
191 }
192 break;
193 }
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000194 case kRtpVideoH264: {
195 _codecSpecificInfo.codecType = kVideoCodecH264;
196 break;
197 }
198 default: {
199 _codecSpecificInfo.codecType = kVideoCodecUnknown;
200 break;
201 }
henrik.lundin@webrtc.org473bac82011-08-17 09:47:33 +0000202 }
stefan@webrtc.org2ec56062014-07-31 14:59:24 +0000203 }
henrik.lundin@webrtc.org473bac82011-08-17 09:47:33 +0000204}
205
stefan@webrtc.orgc3d89102011-09-08 06:50:28 +0000206const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const {
207 return &_fragmentation;
208}
209
philipel9d3ab612015-12-21 04:12:39 -0800210void VCMEncodedFrame::VerifyAndAllocate(size_t minimumSize) {
211 if (minimumSize > _size) {
212 // create buffer of sufficient size
213 uint8_t* newBuffer = new uint8_t[minimumSize];
214 if (_buffer) {
215 // copy old data
216 memcpy(newBuffer, _buffer, _size);
217 delete[] _buffer;
niklase@google.com470e71d2011-07-07 08:21:25 +0000218 }
philipel9d3ab612015-12-21 04:12:39 -0800219 _buffer = newBuffer;
220 _size = minimumSize;
221 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000222}
223
pbos22993e12015-10-19 02:39:06 -0700224} // namespace webrtc