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
VCMEncodedFrame()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
VCMEncodedFrame(const webrtc::EncodedImage & rhs)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
VCMEncodedFrame(const VCMEncodedFrame & rhs)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
~VCMEncodedFrame()71 VCMEncodedFrame::~VCMEncodedFrame()
72 {
73 Free();
74 }
75
Free()76 void VCMEncodedFrame::Free()
77 {
78 Reset();
79 if (_buffer != NULL)
80 {
81 delete [] _buffer;
82 _buffer = NULL;
83 }
84 }
85
Reset()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
CopyCodecSpecific(const RTPVideoHeader * header)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
FragmentationHeader() const144 const RTPFragmentationHeader* VCMEncodedFrame::FragmentationHeader() const {
145 return &_fragmentation;
146 }
147
VerifyAndAllocate(const uint32_t minimumSize)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
ConvertFrameType(VideoFrameType frameType)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
ConvertFrameType(webrtc::FrameType frame_type)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
ConvertFrameTypes(const std::vector<webrtc::FrameType> & frame_types,std::vector<VideoFrameType> * video_frame_types)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