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