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 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 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 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 70 VCMEncodedFrame::~VCMEncodedFrame() { 71 Free(); 72 } 73 74 void VCMEncodedFrame::Free() { 75 Reset(); 76 if (_buffer != NULL) { 77 delete[] _buffer; 78 _buffer = NULL; 79 } 80 } 81 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 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 207 const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const { 208 return &_fragmentation; 209 } 210 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