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 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 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 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 71 VCMEncodedFrame::~VCMEncodedFrame() 72 { 73 Free(); 74 } 75 76 void VCMEncodedFrame::Free() 77 { 78 Reset(); 79 if (_buffer != NULL) 80 { 81 delete [] _buffer; 82 _buffer = NULL; 83 } 84 } 85 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 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 148 const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const { 149 return &_fragmentation; 150 } 151 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 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 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 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