Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc

Issue 1211353002: Integration of VP9 packetization. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: set ss data if not set Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 * 9 *
10 */ 10 */
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 if (width * height <= 352 * 288) 50 if (width * height <= 352 * 288)
51 return 5; 51 return 5;
52 else 52 else
53 return 7; 53 return 7;
54 } 54 }
55 55
56 VP9Encoder* VP9Encoder::Create() { 56 VP9Encoder* VP9Encoder::Create() {
57 return new VP9EncoderImpl(); 57 return new VP9EncoderImpl();
58 } 58 }
59 59
60 void VP9EncoderImpl::EncoderOutputCodedPacketCallback(vpx_codec_cx_pkt* pkt,
61 void* user_data) {
62 VP9EncoderImpl* enc = (VP9EncoderImpl*)(user_data);
63 enc->GetEncodedLayerFrame(pkt);
64 }
65
60 VP9EncoderImpl::VP9EncoderImpl() 66 VP9EncoderImpl::VP9EncoderImpl()
61 : encoded_image_(), 67 : encoded_image_(),
62 encoded_complete_callback_(NULL), 68 encoded_complete_callback_(NULL),
63 inited_(false), 69 inited_(false),
64 timestamp_(0), 70 timestamp_(0),
65 picture_id_(0), 71 picture_id_(0),
66 cpu_speed_(3), 72 cpu_speed_(3),
67 rc_max_intra_target_(0), 73 rc_max_intra_target_(0),
68 encoder_(NULL), 74 encoder_(NULL),
69 config_(NULL), 75 config_(NULL),
70 raw_(NULL) { 76 raw_(NULL),
77 input_image_(NULL),
78 tl0_pic_idx_(0),
79 gof_idx_(0),
80 num_temporal_layers_(0),
81 num_spatial_layers_(0) {
71 memset(&codec_, 0, sizeof(codec_)); 82 memset(&codec_, 0, sizeof(codec_));
72 uint32_t seed = static_cast<uint32_t>(TickTime::MillisecondTimestamp()); 83 uint32_t seed = static_cast<uint32_t>(TickTime::MillisecondTimestamp());
73 srand(seed); 84 srand(seed);
74 } 85 }
75 86
76 VP9EncoderImpl::~VP9EncoderImpl() { 87 VP9EncoderImpl::~VP9EncoderImpl() {
77 Release(); 88 Release();
78 } 89 }
79 90
80 int VP9EncoderImpl::Release() { 91 int VP9EncoderImpl::Release() {
(...skipping 13 matching lines...) Expand all
94 config_ = NULL; 105 config_ = NULL;
95 } 106 }
96 if (raw_ != NULL) { 107 if (raw_ != NULL) {
97 vpx_img_free(raw_); 108 vpx_img_free(raw_);
98 raw_ = NULL; 109 raw_ = NULL;
99 } 110 }
100 inited_ = false; 111 inited_ = false;
101 return WEBRTC_VIDEO_CODEC_OK; 112 return WEBRTC_VIDEO_CODEC_OK;
102 } 113 }
103 114
115 bool VP9EncoderImpl::SetSvcRates() {
116 float rate_ratio[VPX_MAX_LAYERS] = {0};
117 float total = 0;
118 uint8_t i = 0;
119
120 for (i = 0; i < num_spatial_layers_; ++i) {
121 if (svc_internal_.svc_params.scaling_factor_num[i] <= 0 ||
122 svc_internal_.svc_params.scaling_factor_den[i] <= 0) {
123 return false;
124 }
125 rate_ratio[i] = static_cast<float>(
126 svc_internal_.svc_params.scaling_factor_num[i]) /
127 svc_internal_.svc_params.scaling_factor_den[i];
128 total += rate_ratio[i];
129 }
130
131 for (i = 0; i < num_spatial_layers_; ++i) {
132 config_->ss_target_bitrate[i] = static_cast<unsigned int>(
133 config_->rc_target_bitrate * rate_ratio[i] / total);
134 if (num_temporal_layers_ == 1) {
135 config_->layer_target_bitrate[i] = config_->ss_target_bitrate[i];
136 } else if (num_temporal_layers_ == 2) {
137 config_->layer_target_bitrate[i * num_temporal_layers_] =
138 config_->ss_target_bitrate[i] * 2 / 3;
139 config_->layer_target_bitrate[i * num_temporal_layers_ + 1] =
140 config_->ss_target_bitrate[i];
141 } else if (num_temporal_layers_ == 3) {
142 config_->layer_target_bitrate[i * num_temporal_layers_] =
143 config_->ss_target_bitrate[i] / 2;
144 config_->layer_target_bitrate[i * num_temporal_layers_ + 1] =
145 config_->layer_target_bitrate[i * num_temporal_layers_] +
146 (config_->ss_target_bitrate[i] / 4);
147 config_->layer_target_bitrate[i * num_temporal_layers_ + 2] =
148 config_->ss_target_bitrate[i];
149 } else {
150 return false;
151 }
152 }
153
154 // For now, temporal layers only supported when having one spatial layer.
155 if (num_spatial_layers_ == 1) {
156 for (i = 0; i < num_temporal_layers_; ++i) {
157 config_->ts_target_bitrate[i] = config_->layer_target_bitrate[i];
158 }
159 }
160
161 return true;
162 }
163
104 int VP9EncoderImpl::SetRates(uint32_t new_bitrate_kbit, 164 int VP9EncoderImpl::SetRates(uint32_t new_bitrate_kbit,
105 uint32_t new_framerate) { 165 uint32_t new_framerate) {
106 if (!inited_) { 166 if (!inited_) {
107 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 167 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
108 } 168 }
109 if (encoder_->err) { 169 if (encoder_->err) {
110 return WEBRTC_VIDEO_CODEC_ERROR; 170 return WEBRTC_VIDEO_CODEC_ERROR;
111 } 171 }
112 if (new_framerate < 1) { 172 if (new_framerate < 1) {
113 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 173 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
114 } 174 }
115 // Update bit rate 175 // Update bit rate
116 if (codec_.maxBitrate > 0 && new_bitrate_kbit > codec_.maxBitrate) { 176 if (codec_.maxBitrate > 0 && new_bitrate_kbit > codec_.maxBitrate) {
117 new_bitrate_kbit = codec_.maxBitrate; 177 new_bitrate_kbit = codec_.maxBitrate;
118 } 178 }
119 config_->rc_target_bitrate = new_bitrate_kbit; 179 config_->rc_target_bitrate = new_bitrate_kbit;
120 codec_.maxFramerate = new_framerate; 180 codec_.maxFramerate = new_framerate;
181
182 if (!SetSvcRates()) {
183 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
184 }
185
121 // Update encoder context 186 // Update encoder context
122 if (vpx_codec_enc_config_set(encoder_, config_)) { 187 if (vpx_codec_enc_config_set(encoder_, config_)) {
123 return WEBRTC_VIDEO_CODEC_ERROR; 188 return WEBRTC_VIDEO_CODEC_ERROR;
124 } 189 }
125 return WEBRTC_VIDEO_CODEC_OK; 190 return WEBRTC_VIDEO_CODEC_OK;
126 } 191 }
127 192
128 int VP9EncoderImpl::InitEncode(const VideoCodec* inst, 193 int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
129 int number_of_cores, 194 int number_of_cores,
130 size_t /*max_payload_size*/) { 195 size_t /*max_payload_size*/) {
131 if (inst == NULL) { 196 if (inst == NULL) {
132 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 197 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
133 } 198 }
134 if (inst->maxFramerate < 1) { 199 if (inst->maxFramerate < 1) {
135 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 200 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
136 } 201 }
137 // Allow zero to represent an unspecified maxBitRate 202 // Allow zero to represent an unspecified maxBitRate
138 if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) { 203 if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) {
139 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 204 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
140 } 205 }
141 if (inst->width < 1 || inst->height < 1) { 206 if (inst->width < 1 || inst->height < 1) {
142 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 207 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
143 } 208 }
144 if (number_of_cores < 1) { 209 if (number_of_cores < 1) {
145 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 210 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
146 } 211 }
212 if (inst->codecSpecific.VP9.numberOfTemporalLayers > 3) {
213 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
214 }
215 // For now, only support one spatial layer.
216 if (inst->codecSpecific.VP9.numberOfSpatialLayers != 1) {
217 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
218 }
147 int retVal = Release(); 219 int retVal = Release();
148 if (retVal < 0) { 220 if (retVal < 0) {
149 return retVal; 221 return retVal;
150 } 222 }
151 if (encoder_ == NULL) { 223 if (encoder_ == NULL) {
152 encoder_ = new vpx_codec_ctx_t; 224 encoder_ = new vpx_codec_ctx_t;
153 } 225 }
154 if (config_ == NULL) { 226 if (config_ == NULL) {
155 config_ = new vpx_codec_enc_cfg_t; 227 config_ = new vpx_codec_enc_cfg_t;
156 } 228 }
157 timestamp_ = 0; 229 timestamp_ = 0;
158 if (&codec_ != inst) { 230 if (&codec_ != inst) {
159 codec_ = *inst; 231 codec_ = *inst;
160 } 232 }
233
234 num_spatial_layers_ = inst->codecSpecific.VP9.numberOfSpatialLayers;
235 num_temporal_layers_ = inst->codecSpecific.VP9.numberOfTemporalLayers;
236 if (num_temporal_layers_ == 0)
237 num_temporal_layers_ = 1;
238
161 // Random start 16 bits is enough. 239 // Random start 16 bits is enough.
162 picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF; 240 picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF;
163 // Allocate memory for encoded image 241 // Allocate memory for encoded image
164 if (encoded_image_._buffer != NULL) { 242 if (encoded_image_._buffer != NULL) {
165 delete [] encoded_image_._buffer; 243 delete [] encoded_image_._buffer;
166 } 244 }
167 encoded_image_._size = CalcBufferSize(kI420, codec_.width, codec_.height); 245 encoded_image_._size = CalcBufferSize(kI420, codec_.width, codec_.height);
168 encoded_image_._buffer = new uint8_t[encoded_image_._size]; 246 encoded_image_._buffer = new uint8_t[encoded_image_._size];
169 encoded_image_._completeFrame = true; 247 encoded_image_._completeFrame = true;
170 // Creating a wrapper to the image - setting image data to NULL. Actual 248 // Creating a wrapper to the image - setting image data to NULL. Actual
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 if (inst->codecSpecific.VP9.keyFrameInterval > 0) { 280 if (inst->codecSpecific.VP9.keyFrameInterval > 0) {
203 config_->kf_mode = VPX_KF_AUTO; 281 config_->kf_mode = VPX_KF_AUTO;
204 config_->kf_max_dist = inst->codecSpecific.VP9.keyFrameInterval; 282 config_->kf_max_dist = inst->codecSpecific.VP9.keyFrameInterval;
205 } else { 283 } else {
206 config_->kf_mode = VPX_KF_DISABLED; 284 config_->kf_mode = VPX_KF_DISABLED;
207 } 285 }
208 // Determine number of threads based on the image size and #cores. 286 // Determine number of threads based on the image size and #cores.
209 config_->g_threads = NumberOfThreads(config_->g_w, 287 config_->g_threads = NumberOfThreads(config_->g_w,
210 config_->g_h, 288 config_->g_h,
211 number_of_cores); 289 number_of_cores);
290
212 cpu_speed_ = GetCpuSpeed(config_->g_w, config_->g_h); 291 cpu_speed_ = GetCpuSpeed(config_->g_w, config_->g_h);
292
293 // TODO(asapersson): Check configuration of temporal switch up and increase
294 // pattern length.
295 if (num_temporal_layers_ == 1) {
296 gof_.SetGofInfoVP9(kTemporalStructureMode1);
297 config_->temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING;
298 config_->ts_number_layers = 1;
299 config_->ts_rate_decimator[0] = 1;
300 config_->ts_periodicity = 1;
301 config_->ts_layer_id[0] = 0;
302 } else if (num_temporal_layers_ == 2) {
303 gof_.SetGofInfoVP9(kTemporalStructureMode2);
304 config_->temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_0101;
305 config_->ts_number_layers = 2;
306 config_->ts_rate_decimator[0] = 2;
307 config_->ts_rate_decimator[1] = 1;
308 config_->ts_periodicity = 2;
309 config_->ts_layer_id[0] = 0;
310 config_->ts_layer_id[1] = 1;
311 } else if (num_temporal_layers_ == 3) {
312 gof_.SetGofInfoVP9(kTemporalStructureMode3);
313 config_->temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_0212;
314 config_->ts_number_layers = 3;
315 config_->ts_rate_decimator[0] = 4;
316 config_->ts_rate_decimator[1] = 2;
317 config_->ts_rate_decimator[2] = 1;
318 config_->ts_periodicity = 4;
319 config_->ts_layer_id[0] = 0;
320 config_->ts_layer_id[1] = 2;
321 config_->ts_layer_id[2] = 1;
322 config_->ts_layer_id[3] = 2;
323 } else {
324 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
325 }
326
327 tl0_pic_idx_ = static_cast<uint8_t>(rand());
328
213 return InitAndSetControlSettings(inst); 329 return InitAndSetControlSettings(inst);
214 } 330 }
215 331
216 int VP9EncoderImpl::NumberOfThreads(int width, 332 int VP9EncoderImpl::NumberOfThreads(int width,
217 int height, 333 int height,
218 int number_of_cores) { 334 int number_of_cores) {
335 // For the current libvpx library, only 1 thread is supported when SVC is
336 // turned on.
337 if (num_temporal_layers_ > 1 || num_spatial_layers_ > 1) {
338 return 1;
339 }
340
219 // Keep the number of encoder threads equal to the possible number of column 341 // Keep the number of encoder threads equal to the possible number of column
220 // tiles, which is (1, 2, 4, 8). See comments below for VP9E_SET_TILE_COLUMNS. 342 // tiles, which is (1, 2, 4, 8). See comments below for VP9E_SET_TILE_COLUMNS.
221 if (width * height >= 1280 * 720 && number_of_cores > 4) { 343 if (width * height >= 1280 * 720 && number_of_cores > 4) {
222 return 4; 344 return 4;
223 } else if (width * height >= 640 * 480 && number_of_cores > 2) { 345 } else if (width * height >= 640 * 480 && number_of_cores > 2) {
224 return 2; 346 return 2;
225 } else { 347 } else {
226 // 1 thread less than VGA. 348 // 1 thread less than VGA.
227 return 1; 349 return 1;
228 } 350 }
229 } 351 }
230 352
231 int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) { 353 int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
354
355 config_->ss_number_layers = num_spatial_layers_;
356
357 if (num_spatial_layers_ > 1) {
358 config_->rc_min_quantizer = 0;
359 config_->rc_max_quantizer = 63;
360 }
361 int scaling_factor_num = 256;
362 for (int i = num_spatial_layers_ - 1; i >= 0; --i) {
363 svc_internal_.svc_params.max_quantizers[i] = config_->rc_max_quantizer;
364 svc_internal_.svc_params.min_quantizers[i] = config_->rc_min_quantizer;
365 // 1:2 scaling in each dimension.
366 svc_internal_.svc_params.scaling_factor_num[i] = scaling_factor_num;
367 svc_internal_.svc_params.scaling_factor_den[i] = 256;
368 scaling_factor_num /= 2;
369 }
370
371 if (!SetSvcRates()) {
372 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
373 }
374
232 if (vpx_codec_enc_init(encoder_, vpx_codec_vp9_cx(), config_, 0)) { 375 if (vpx_codec_enc_init(encoder_, vpx_codec_vp9_cx(), config_, 0)) {
233 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 376 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
234 } 377 }
235 vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_); 378 vpx_codec_control(encoder_, VP8E_SET_CPUUSED, cpu_speed_);
236 vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT, 379 vpx_codec_control(encoder_, VP8E_SET_MAX_INTRA_BITRATE_PCT,
237 rc_max_intra_target_); 380 rc_max_intra_target_);
238 vpx_codec_control(encoder_, VP9E_SET_AQ_MODE, 381 vpx_codec_control(encoder_, VP9E_SET_AQ_MODE,
239 inst->codecSpecific.VP9.adaptiveQpMode ? 3 : 0); 382 inst->codecSpecific.VP9.adaptiveQpMode ? 3 : 0);
383
384 vpx_codec_control(
385 encoder_, VP9E_SET_SVC,
386 (num_temporal_layers_ > 1 || num_spatial_layers_ > 1) ? 1 : 0);
387 if (num_temporal_layers_ > 1 || num_spatial_layers_ > 1) {
388 vpx_codec_control(encoder_, VP9E_SET_SVC_PARAMETERS,
389 &svc_internal_.svc_params);
390 }
391 // Register callback for getting each spatial layer.
392 vpx_codec_priv_output_cx_pkt_cb_pair_t cbp = {
393 VP9EncoderImpl::EncoderOutputCodedPacketCallback, (void*)(this)};
394 vpx_codec_control(encoder_, VP9E_REGISTER_CX_CALLBACK, (void*)(&cbp));
395
240 // Control function to set the number of column tiles in encoding a frame, in 396 // Control function to set the number of column tiles in encoding a frame, in
241 // log2 unit: e.g., 0 = 1 tile column, 1 = 2 tile columns, 2 = 4 tile columns. 397 // log2 unit: e.g., 0 = 1 tile column, 1 = 2 tile columns, 2 = 4 tile columns.
242 // The number tile columns will be capped by the encoder based on image size 398 // The number tile columns will be capped by the encoder based on image size
243 // (minimum width of tile column is 256 pixels, maximum is 4096). 399 // (minimum width of tile column is 256 pixels, maximum is 4096).
244 vpx_codec_control(encoder_, VP9E_SET_TILE_COLUMNS, (config_->g_threads >> 1)); 400 vpx_codec_control(encoder_, VP9E_SET_TILE_COLUMNS, (config_->g_threads >> 1));
245 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) 401 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64)
246 // Note denoiser is still off by default until further testing/optimization, 402 // Note denoiser is still off by default until further testing/optimization,
247 // i.e., codecSpecific.VP9.denoisingOn == 0. 403 // i.e., codecSpecific.VP9.denoisingOn == 0.
248 vpx_codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY, 404 vpx_codec_control(encoder_, VP9E_SET_NOISE_SENSITIVITY,
249 inst->codecSpecific.VP9.denoisingOn ? 1 : 0); 405 inst->codecSpecific.VP9.denoisingOn ? 1 : 0);
(...skipping 29 matching lines...) Expand all
279 if (encoded_complete_callback_ == NULL) { 435 if (encoded_complete_callback_ == NULL) {
280 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 436 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
281 } 437 }
282 VideoFrameType frame_type = kDeltaFrame; 438 VideoFrameType frame_type = kDeltaFrame;
283 // We only support one stream at the moment. 439 // We only support one stream at the moment.
284 if (frame_types && frame_types->size() > 0) { 440 if (frame_types && frame_types->size() > 0) {
285 frame_type = (*frame_types)[0]; 441 frame_type = (*frame_types)[0];
286 } 442 }
287 DCHECK_EQ(input_image.width(), static_cast<int>(raw_->d_w)); 443 DCHECK_EQ(input_image.width(), static_cast<int>(raw_->d_w));
288 DCHECK_EQ(input_image.height(), static_cast<int>(raw_->d_h)); 444 DCHECK_EQ(input_image.height(), static_cast<int>(raw_->d_h));
445
446 // Set input image for use in the callback.
447 // This was necessary since you need some information from input_image.
448 // You can save only the necessary information (such as timestamp) instead of
449 // doing this.
450 input_image_ = &input_image;
451
289 // Image in vpx_image_t format. 452 // Image in vpx_image_t format.
290 // Input image is const. VPX's raw image is not defined as const. 453 // Input image is const. VPX's raw image is not defined as const.
291 raw_->planes[VPX_PLANE_Y] = const_cast<uint8_t*>(input_image.buffer(kYPlane)); 454 raw_->planes[VPX_PLANE_Y] = const_cast<uint8_t*>(input_image.buffer(kYPlane));
292 raw_->planes[VPX_PLANE_U] = const_cast<uint8_t*>(input_image.buffer(kUPlane)); 455 raw_->planes[VPX_PLANE_U] = const_cast<uint8_t*>(input_image.buffer(kUPlane));
293 raw_->planes[VPX_PLANE_V] = const_cast<uint8_t*>(input_image.buffer(kVPlane)); 456 raw_->planes[VPX_PLANE_V] = const_cast<uint8_t*>(input_image.buffer(kVPlane));
294 raw_->stride[VPX_PLANE_Y] = input_image.stride(kYPlane); 457 raw_->stride[VPX_PLANE_Y] = input_image.stride(kYPlane);
295 raw_->stride[VPX_PLANE_U] = input_image.stride(kUPlane); 458 raw_->stride[VPX_PLANE_U] = input_image.stride(kUPlane);
296 raw_->stride[VPX_PLANE_V] = input_image.stride(kVPlane); 459 raw_->stride[VPX_PLANE_V] = input_image.stride(kVPlane);
297 460
298 int flags = 0; 461 int flags = 0;
299 bool send_keyframe = (frame_type == kKeyFrame); 462 bool send_keyframe = (frame_type == kKeyFrame);
300 if (send_keyframe) { 463 if (send_keyframe) {
301 // Key frame request from caller. 464 // Key frame request from caller.
302 flags = VPX_EFLAG_FORCE_KF; 465 flags = VPX_EFLAG_FORCE_KF;
303 } 466 }
304 assert(codec_.maxFramerate > 0); 467 assert(codec_.maxFramerate > 0);
305 uint32_t duration = 90000 / codec_.maxFramerate; 468 uint32_t duration = 90000 / codec_.maxFramerate;
306 if (vpx_codec_encode(encoder_, raw_, timestamp_, duration, flags, 469 if (vpx_codec_encode(encoder_, raw_, timestamp_, duration, flags,
307 VPX_DL_REALTIME)) { 470 VPX_DL_REALTIME)) {
308 return WEBRTC_VIDEO_CODEC_ERROR; 471 return WEBRTC_VIDEO_CODEC_ERROR;
309 } 472 }
310 timestamp_ += duration; 473 timestamp_ += duration;
311 return GetEncodedPartitions(input_image); 474
475 return WEBRTC_VIDEO_CODEC_OK;
312 } 476 }
313 477
314 void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific, 478 void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
315 const vpx_codec_cx_pkt& pkt, 479 const vpx_codec_cx_pkt& pkt,
316 uint32_t timestamp) { 480 uint32_t timestamp) {
317 assert(codec_specific != NULL); 481 assert(codec_specific != NULL);
318 codec_specific->codecType = kVideoCodecVP9; 482 codec_specific->codecType = kVideoCodecVP9;
319 CodecSpecificInfoVP9 *vp9_info = &(codec_specific->codecSpecific.VP9); 483 CodecSpecificInfoVP9 *vp9_info = &(codec_specific->codecSpecific.VP9);
320 vp9_info->pictureId = picture_id_; 484 // TODO(asapersson): Set correct values.
321 vp9_info->keyIdx = kNoKeyIdx; 485 vp9_info->inter_pic_predicted =
322 vp9_info->nonReference = (pkt.data.frame.flags & VPX_FRAME_IS_DROPPABLE) != 0; 486 (pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? false : true;
323 // TODO(marpan): Temporal layers are supported in the current VP9 version, 487 vp9_info->flexible_mode = codec_.codecSpecific.VP9.flexibleMode;
324 // but for now use 1 temporal layer encoding. Will update this when temporal 488 vp9_info->ss_data_available =
325 // layer support for VP9 is added in webrtc. 489 (pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
326 vp9_info->temporalIdx = kNoTemporalIdx; 490 if (pkt.data.frame.flags & VPX_FRAME_IS_KEY) {
327 vp9_info->layerSync = false; 491 gof_idx_ = 0;
328 vp9_info->tl0PicIdx = kNoTl0PicIdx; 492 }
329 picture_id_ = (picture_id_ + 1) & 0x7FFF; 493
494 vpx_svc_layer_id_t layer_id = {0};
495 vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
496
497 assert(num_temporal_layers_ > 0);
498 assert(num_spatial_layers_ > 0);
499 if (num_temporal_layers_ == 1) {
500 assert(layer_id.temporal_layer_id == 0);
501 vp9_info->temporal_idx = kNoTemporalIdx;
502 } else {
503 vp9_info->temporal_idx = layer_id.temporal_layer_id;
504 }
505 if (num_spatial_layers_ == 1) {
506 assert(layer_id.spatial_layer_id == 0);
507 vp9_info->spatial_idx = kNoSpatialIdx;
508 } else {
509 vp9_info->spatial_idx = layer_id.spatial_layer_id;
510 }
511 if (layer_id.spatial_layer_id != 0) {
512 vp9_info->ss_data_available = false;
513 }
514
515 if (vp9_info->flexible_mode) {
516 vp9_info->gof_idx = kNoGofIdx;
517 } else {
518 vp9_info->gof_idx =
519 static_cast<uint8_t>(gof_idx_++ % gof_.num_frames_in_gof);
520 }
521
522 // TODO(asapersson): this info has to be obtained from the encoder.
523 vp9_info->temporal_up_switch = true;
524
525 if (layer_id.spatial_layer_id == 0) {
526 picture_id_ = (picture_id_ + 1) & 0x7FFF;
527 // TODO(asapersson): this info has to be obtained from the encoder.
528 vp9_info->inter_layer_predicted = false;
529 } else {
530 // TODO(asapersson): this info has to be obtained from the encoder.
531 vp9_info->inter_layer_predicted = true;
532 }
533
534 vp9_info->picture_id = picture_id_;
535
536 if (!vp9_info->flexible_mode) {
537 if (layer_id.temporal_layer_id == 0 && layer_id.spatial_layer_id == 0) {
538 tl0_pic_idx_++;
539 }
540 vp9_info->tl0_pic_idx = tl0_pic_idx_;
541 }
542
543 if (vp9_info->ss_data_available) {
544 vp9_info->num_spatial_layers = num_spatial_layers_;
545 vp9_info->spatial_layer_resolution_present = true;
546 for (size_t i = 0; i < vp9_info->num_spatial_layers; ++i) {
547 vp9_info->width[i] = codec_.width *
548 svc_internal_.svc_params.scaling_factor_num[i] /
549 svc_internal_.svc_params.scaling_factor_den[i];
550 vp9_info->height[i] = codec_.height *
551 svc_internal_.svc_params.scaling_factor_num[i] /
552 svc_internal_.svc_params.scaling_factor_den[i];
553 }
554 if (!vp9_info->flexible_mode) {
555 vp9_info->gof.CopyGofInfoVP9(gof_);
556 }
557 }
330 } 558 }
331 559
332 int VP9EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image) { 560 int VP9EncoderImpl::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) {
333 vpx_codec_iter_t iter = NULL;
334 encoded_image_._length = 0; 561 encoded_image_._length = 0;
335 encoded_image_._frameType = kDeltaFrame; 562 encoded_image_._frameType = kDeltaFrame;
336 RTPFragmentationHeader frag_info; 563 RTPFragmentationHeader frag_info;
337 // Note: no data partitioning in VP9, so 1 partition only. We keep this 564 // Note: no data partitioning in VP9, so 1 partition only. We keep this
338 // fragmentation data for now, until VP9 packetizer is implemented. 565 // fragmentation data for now, until VP9 packetizer is implemented.
339 frag_info.VerifyAndAllocateFragmentationHeader(1); 566 frag_info.VerifyAndAllocateFragmentationHeader(1);
340 int part_idx = 0; 567 int part_idx = 0;
341 CodecSpecificInfo codec_specific; 568 CodecSpecificInfo codec_specific;
342 const vpx_codec_cx_pkt_t *pkt = NULL; 569
343 while ((pkt = vpx_codec_get_cx_data(encoder_, &iter)) != NULL) { 570 assert(pkt->kind == VPX_CODEC_CX_FRAME_PKT);
344 switch (pkt->kind) { 571 memcpy(&encoded_image_._buffer[encoded_image_._length], pkt->data.frame.buf,
345 case VPX_CODEC_CX_FRAME_PKT: { 572 pkt->data.frame.sz);
346 memcpy(&encoded_image_._buffer[encoded_image_._length], 573 frag_info.fragmentationOffset[part_idx] = encoded_image_._length;
347 pkt->data.frame.buf, 574 frag_info.fragmentationLength[part_idx] =
348 pkt->data.frame.sz); 575 static_cast<uint32_t>(pkt->data.frame.sz);
349 frag_info.fragmentationOffset[part_idx] = encoded_image_._length; 576 frag_info.fragmentationPlType[part_idx] = 0;
350 frag_info.fragmentationLength[part_idx] = 577 frag_info.fragmentationTimeDiff[part_idx] = 0;
351 static_cast<uint32_t>(pkt->data.frame.sz); 578 encoded_image_._length += static_cast<uint32_t>(pkt->data.frame.sz);
352 frag_info.fragmentationPlType[part_idx] = 0; 579 assert(encoded_image_._length <= encoded_image_._size);
353 frag_info.fragmentationTimeDiff[part_idx] = 0; 580
354 encoded_image_._length += static_cast<uint32_t>(pkt->data.frame.sz); 581 // End of frame.
355 assert(encoded_image_._length <= encoded_image_._size); 582 // Check if encoded frame is a key frame.
356 break; 583 if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
357 } 584 encoded_image_._frameType = kKeyFrame;
358 default: {
359 break;
360 }
361 }
362 // End of frame.
363 if ((pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT) == 0) {
364 // Check if encoded frame is a key frame.
365 if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
366 encoded_image_._frameType = kKeyFrame;
367 }
368 PopulateCodecSpecific(&codec_specific, *pkt, input_image.timestamp());
369 break;
370 }
371 } 585 }
586 PopulateCodecSpecific(&codec_specific, *pkt, input_image_->timestamp());
587
372 if (encoded_image_._length > 0) { 588 if (encoded_image_._length > 0) {
373 TRACE_COUNTER1("webrtc", "EncodedFrameSize", encoded_image_._length); 589 TRACE_COUNTER1("webrtc", "EncodedFrameSize", encoded_image_._length);
374 encoded_image_._timeStamp = input_image.timestamp(); 590 encoded_image_._timeStamp = input_image_->timestamp();
375 encoded_image_.capture_time_ms_ = input_image.render_time_ms(); 591 encoded_image_.capture_time_ms_ = input_image_->render_time_ms();
376 encoded_image_._encodedHeight = raw_->d_h; 592 encoded_image_._encodedHeight = raw_->d_h;
377 encoded_image_._encodedWidth = raw_->d_w; 593 encoded_image_._encodedWidth = raw_->d_w;
378 encoded_complete_callback_->Encoded(encoded_image_, &codec_specific, 594 encoded_complete_callback_->Encoded(encoded_image_, &codec_specific,
379 &frag_info); 595 &frag_info);
380 } 596 }
381 return WEBRTC_VIDEO_CODEC_OK; 597 return WEBRTC_VIDEO_CODEC_OK;
382 } 598 }
383 599
384 int VP9EncoderImpl::SetChannelParameters(uint32_t packet_loss, int64_t rtt) { 600 int VP9EncoderImpl::SetChannelParameters(uint32_t packet_loss, int64_t rtt) {
385 return WEBRTC_VIDEO_CODEC_OK; 601 return WEBRTC_VIDEO_CODEC_OK;
386 } 602 }
387 603
388 int VP9EncoderImpl::RegisterEncodeCompleteCallback( 604 int VP9EncoderImpl::RegisterEncodeCompleteCallback(
389 EncodedImageCallback* callback) { 605 EncodedImageCallback* callback) {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 decoder_ = NULL; 775 decoder_ = NULL;
560 } 776 }
561 // Releases buffers from the pool. Any buffers not in use are deleted. Buffers 777 // Releases buffers from the pool. Any buffers not in use are deleted. Buffers
562 // still referenced externally are deleted once fully released, not returning 778 // still referenced externally are deleted once fully released, not returning
563 // to the pool. 779 // to the pool.
564 frame_buffer_pool_.ClearPool(); 780 frame_buffer_pool_.ClearPool();
565 inited_ = false; 781 inited_ = false;
566 return WEBRTC_VIDEO_CODEC_OK; 782 return WEBRTC_VIDEO_CODEC_OK;
567 } 783 }
568 } // namespace webrtc 784 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/codecs/vp9/vp9_impl.h ('k') | webrtc/modules/video_coding/main/source/codec_database.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698