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 switch (header->codec) { 105 case kRtpVideoVp8: { 106 if (_codecSpecificInfo.codecType != kVideoCodecVP8) { 107 // This is the first packet for this frame. 108 _codecSpecificInfo.codecSpecific.VP8.pictureId = -1; 109 _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 0; 110 _codecSpecificInfo.codecSpecific.VP8.layerSync = false; 111 _codecSpecificInfo.codecSpecific.VP8.keyIdx = -1; 112 _codecSpecificInfo.codecType = kVideoCodecVP8; 113 } 114 _codecSpecificInfo.codecSpecific.VP8.nonReference = 115 header->codecHeader.VP8.nonReference; 116 if (header->codecHeader.VP8.pictureId != kNoPictureId) { 117 _codecSpecificInfo.codecSpecific.VP8.pictureId = 118 header->codecHeader.VP8.pictureId; 119 } 120 if (header->codecHeader.VP8.temporalIdx != kNoTemporalIdx) { 121 _codecSpecificInfo.codecSpecific.VP8.temporalIdx = 122 header->codecHeader.VP8.temporalIdx; 123 _codecSpecificInfo.codecSpecific.VP8.layerSync = 124 header->codecHeader.VP8.layerSync; 125 } 126 if (header->codecHeader.VP8.keyIdx != kNoKeyIdx) { 127 _codecSpecificInfo.codecSpecific.VP8.keyIdx = 128 header->codecHeader.VP8.keyIdx; 129 } 130 break; 131 } 132 case kRtpVideoH264: { 133 _codecSpecificInfo.codecType = kVideoCodecH264; 134 break; 135 } 136 default: { 137 _codecSpecificInfo.codecType = kVideoCodecUnknown; 138 break; 139 } 140 } 141 } 142 } 143 144 const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const { 145 return &_fragmentation; 146 } 147 148 void VCMEncodedFrame::VerifyAndAllocate(const uint32_t minimumSize) 149 { 150 if(minimumSize > _size) 151 { 152 // create buffer of sufficient size 153 uint8_t* newBuffer = new uint8_t[minimumSize]; 154 if(_buffer) 155 { 156 // copy old data 157 memcpy(newBuffer, _buffer, _size); 158 delete [] _buffer; 159 } 160 _buffer = newBuffer; 161 _size = minimumSize; 162 } 163 } 164 165 webrtc::FrameType VCMEncodedFrame::ConvertFrameType(VideoFrameType frameType) 166 { 167 switch(frameType) { 168 case kKeyFrame: 169 return kVideoFrameKey; 170 case kDeltaFrame: 171 return kVideoFrameDelta; 172 case kSkipFrame: 173 return kFrameEmpty; 174 default: 175 return kVideoFrameDelta; 176 } 177 } 178 179 VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frame_type) { 180 switch (frame_type) { 181 case kVideoFrameKey: 182 return kKeyFrame; 183 case kVideoFrameDelta: 184 return kDeltaFrame; 185 default: 186 assert(false); 187 return kDeltaFrame; 188 } 189 } 190 191 void VCMEncodedFrame::ConvertFrameTypes( 192 const std::vector<webrtc::FrameType>& frame_types, 193 std::vector<VideoFrameType>* video_frame_types) { 194 assert(video_frame_types); 195 video_frame_types->reserve(frame_types.size()); 196 for (size_t i = 0; i < frame_types.size(); ++i) { 197 (*video_frame_types)[i] = ConvertFrameType(frame_types[i]); 198 } 199 } 200 201 } 202