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

Side by Side Diff: webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc

Issue 1716173002: Histograms for H264EncoderImpl/H264DecoderImpl initialization and errors (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 10 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) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 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 */
11 11
12 #include "webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h" 12 #include "webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h"
13 13
14 #include <limits> 14 #include <limits>
15 15
16 #include "third_party/openh264/src/codec/api/svc/codec_api.h" 16 #include "third_party/openh264/src/codec/api/svc/codec_api.h"
17 #include "third_party/openh264/src/codec/api/svc/codec_app_def.h" 17 #include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
18 #include "third_party/openh264/src/codec/api/svc/codec_def.h" 18 #include "third_party/openh264/src/codec/api/svc/codec_def.h"
19 19
20 #include "webrtc/base/checks.h" 20 #include "webrtc/base/checks.h"
21 #include "webrtc/base/logging.h" 21 #include "webrtc/base/logging.h"
22 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 22 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
23 #include "webrtc/system_wrappers/include/metrics.h"
23 24
24 namespace webrtc { 25 namespace webrtc {
25 26
26 namespace { 27 namespace {
27 28
28 const bool kOpenH264EncoderDetailedLogging = false; 29 const bool kOpenH264EncoderDetailedLogging = false;
29 30
30 int NumberOfThreads(int width, int height, int number_of_cores) { 31 int NumberOfThreads(int width, int height, int number_of_cores) {
31 // TODO(hbos): In Chromium, multiple threads do not work with sandbox on Mac, 32 // TODO(hbos): In Chromium, multiple threads do not work with sandbox on Mac,
32 // see crbug.com/583348. Until further investigated, only use one thread. 33 // see crbug.com/583348. Until further investigated, only use one thread.
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 } 134 }
134 // Copy the entire layer's data (including start codes). 135 // Copy the entire layer's data (including start codes).
135 memcpy(encoded_image->_buffer + encoded_image->_length, 136 memcpy(encoded_image->_buffer + encoded_image->_length,
136 layerInfo.pBsBuf, 137 layerInfo.pBsBuf,
137 layer_len); 138 layer_len);
138 encoded_image->_length += layer_len; 139 encoded_image->_length += layer_len;
139 } 140 }
140 } 141 }
141 142
142 H264EncoderImpl::H264EncoderImpl() 143 H264EncoderImpl::H264EncoderImpl()
143 : openh264_encoder_(nullptr), 144 : has_reported_init_(false),
145 has_reported_error_(false),
146 openh264_encoder_(nullptr),
144 encoded_image_callback_(nullptr) { 147 encoded_image_callback_(nullptr) {
145 } 148 }
146 149
147 H264EncoderImpl::~H264EncoderImpl() { 150 H264EncoderImpl::~H264EncoderImpl() {
148 Release(); 151 Release();
149 } 152 }
150 153
151 int32_t H264EncoderImpl::InitEncode(const VideoCodec* codec_settings, 154 int32_t H264EncoderImpl::InitEncode(const VideoCodec* codec_settings,
152 int32_t number_of_cores, 155 int32_t number_of_cores,
153 size_t /*max_payload_size*/) { 156 size_t /*max_payload_size*/) {
157 ReportInit();
154 if (!codec_settings || 158 if (!codec_settings ||
155 codec_settings->codecType != kVideoCodecH264) { 159 codec_settings->codecType != kVideoCodecH264) {
160 ReportError();
156 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 161 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
157 } 162 }
158 if (codec_settings->maxFramerate == 0) 163 if (codec_settings->maxFramerate == 0) {
164 ReportError();
159 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 165 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
160 if (codec_settings->width < 1 || codec_settings->height < 1) 166 }
167 if (codec_settings->width < 1 || codec_settings->height < 1) {
168 ReportError();
161 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 169 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
170 }
162 171
163 int32_t release_ret = Release(); 172 int32_t release_ret = Release();
164 if (release_ret != WEBRTC_VIDEO_CODEC_OK) 173 if (release_ret != WEBRTC_VIDEO_CODEC_OK) {
174 ReportError();
165 return release_ret; 175 return release_ret;
176 }
166 RTC_DCHECK(!openh264_encoder_); 177 RTC_DCHECK(!openh264_encoder_);
167 178
168 // Create encoder. 179 // Create encoder.
169 if (WelsCreateSVCEncoder(&openh264_encoder_) != 0) { 180 if (WelsCreateSVCEncoder(&openh264_encoder_) != 0) {
170 // Failed to create encoder. 181 // Failed to create encoder.
171 LOG(LS_ERROR) << "Failed to create OpenH264 encoder"; 182 LOG(LS_ERROR) << "Failed to create OpenH264 encoder";
172 RTC_DCHECK(!openh264_encoder_); 183 RTC_DCHECK(!openh264_encoder_);
184 ReportError();
173 return WEBRTC_VIDEO_CODEC_ERROR; 185 return WEBRTC_VIDEO_CODEC_ERROR;
174 } 186 }
175 RTC_DCHECK(openh264_encoder_); 187 RTC_DCHECK(openh264_encoder_);
176 if (kOpenH264EncoderDetailedLogging) { 188 if (kOpenH264EncoderDetailedLogging) {
177 int trace_level = WELS_LOG_DETAIL; 189 int trace_level = WELS_LOG_DETAIL;
178 openh264_encoder_->SetOption(ENCODER_OPTION_TRACE_LEVEL, 190 openh264_encoder_->SetOption(ENCODER_OPTION_TRACE_LEVEL,
179 &trace_level); 191 &trace_level);
180 } 192 }
181 // else WELS_LOG_DEFAULT is used by default. 193 // else WELS_LOG_DEFAULT is used by default.
182 194
183 codec_settings_ = *codec_settings; 195 codec_settings_ = *codec_settings;
184 if (codec_settings_.targetBitrate == 0) 196 if (codec_settings_.targetBitrate == 0)
185 codec_settings_.targetBitrate = codec_settings_.startBitrate; 197 codec_settings_.targetBitrate = codec_settings_.startBitrate;
186 198
187 // Initialization parameters. 199 // Initialization parameters.
188 // There are two ways to initialize. There is SEncParamBase (cleared with 200 // There are two ways to initialize. There is SEncParamBase (cleared with
189 // memset(&p, 0, sizeof(SEncParamBase)) used in Initialize, and SEncParamExt 201 // memset(&p, 0, sizeof(SEncParamBase)) used in Initialize, and SEncParamExt
190 // which is a superset of SEncParamBase (cleared with GetDefaultParams) used 202 // which is a superset of SEncParamBase (cleared with GetDefaultParams) used
191 // in InitializeExt. 203 // in InitializeExt.
192 SEncParamExt init_params; 204 SEncParamExt init_params;
193 openh264_encoder_->GetDefaultParams(&init_params); 205 openh264_encoder_->GetDefaultParams(&init_params);
194 if (codec_settings_.mode == kRealtimeVideo) { 206 if (codec_settings_.mode == kRealtimeVideo) {
195 init_params.iUsageType = CAMERA_VIDEO_REAL_TIME; 207 init_params.iUsageType = CAMERA_VIDEO_REAL_TIME;
196 } else if (codec_settings_.mode == kScreensharing) { 208 } else if (codec_settings_.mode == kScreensharing) {
197 init_params.iUsageType = SCREEN_CONTENT_REAL_TIME; 209 init_params.iUsageType = SCREEN_CONTENT_REAL_TIME;
198 } else { 210 } else {
211 ReportError();
199 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 212 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
200 } 213 }
201 init_params.iPicWidth = codec_settings_.width; 214 init_params.iPicWidth = codec_settings_.width;
202 init_params.iPicHeight = codec_settings_.height; 215 init_params.iPicHeight = codec_settings_.height;
203 // |init_params| uses bit/s, |codec_settings_| uses kbit/s. 216 // |init_params| uses bit/s, |codec_settings_| uses kbit/s.
204 init_params.iTargetBitrate = codec_settings_.targetBitrate * 1000; 217 init_params.iTargetBitrate = codec_settings_.targetBitrate * 1000;
205 init_params.iMaxBitrate = codec_settings_.maxBitrate * 1000; 218 init_params.iMaxBitrate = codec_settings_.maxBitrate * 1000;
206 // Rate Control mode 219 // Rate Control mode
207 init_params.iRCMode = RC_BITRATE_MODE; 220 init_params.iRCMode = RC_BITRATE_MODE;
208 init_params.fMaxFrameRate = static_cast<float>(codec_settings_.maxFramerate); 221 init_params.fMaxFrameRate = static_cast<float>(codec_settings_.maxFramerate);
(...skipping 20 matching lines...) Expand all
229 init_params.sSpatialLayers[0].fFrameRate = init_params.fMaxFrameRate; 242 init_params.sSpatialLayers[0].fFrameRate = init_params.fMaxFrameRate;
230 init_params.sSpatialLayers[0].iSpatialBitrate = init_params.iTargetBitrate; 243 init_params.sSpatialLayers[0].iSpatialBitrate = init_params.iTargetBitrate;
231 init_params.sSpatialLayers[0].iMaxSpatialBitrate = init_params.iMaxBitrate; 244 init_params.sSpatialLayers[0].iMaxSpatialBitrate = init_params.iMaxBitrate;
232 // Slice num according to number of threads. 245 // Slice num according to number of threads.
233 init_params.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_AUTO_SLICE; 246 init_params.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_AUTO_SLICE;
234 247
235 // Initialize. 248 // Initialize.
236 if (openh264_encoder_->InitializeExt(&init_params) != 0) { 249 if (openh264_encoder_->InitializeExt(&init_params) != 0) {
237 LOG(LS_ERROR) << "Failed to initialize OpenH264 encoder"; 250 LOG(LS_ERROR) << "Failed to initialize OpenH264 encoder";
238 Release(); 251 Release();
252 ReportError();
239 return WEBRTC_VIDEO_CODEC_ERROR; 253 return WEBRTC_VIDEO_CODEC_ERROR;
240 } 254 }
241 int video_format = EVideoFormatType::videoFormatI420; 255 int video_format = EVideoFormatType::videoFormatI420;
242 openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT, 256 openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT,
243 &video_format); 257 &video_format);
244 258
245 // Initialize encoded image. Default buffer size: size of unencoded data. 259 // Initialize encoded image. Default buffer size: size of unencoded data.
246 encoded_image_._size = CalcBufferSize( 260 encoded_image_._size = CalcBufferSize(
247 kI420, codec_settings_.width, codec_settings_.height); 261 kI420, codec_settings_.width, codec_settings_.height);
248 encoded_image_._buffer = new uint8_t[encoded_image_._size]; 262 encoded_image_._buffer = new uint8_t[encoded_image_._size];
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 &target_bitrate); 306 &target_bitrate);
293 float max_framerate = static_cast<float>(codec_settings_.maxFramerate); 307 float max_framerate = static_cast<float>(codec_settings_.maxFramerate);
294 openh264_encoder_->SetOption(ENCODER_OPTION_FRAME_RATE, 308 openh264_encoder_->SetOption(ENCODER_OPTION_FRAME_RATE,
295 &max_framerate); 309 &max_framerate);
296 return WEBRTC_VIDEO_CODEC_OK; 310 return WEBRTC_VIDEO_CODEC_OK;
297 } 311 }
298 312
299 int32_t H264EncoderImpl::Encode( 313 int32_t H264EncoderImpl::Encode(
300 const VideoFrame& frame, const CodecSpecificInfo* codec_specific_info, 314 const VideoFrame& frame, const CodecSpecificInfo* codec_specific_info,
301 const std::vector<FrameType>* frame_types) { 315 const std::vector<FrameType>* frame_types) {
302 if (!IsInitialized()) 316 if (!IsInitialized()) {
317 ReportError();
303 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 318 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
304 if (frame.IsZeroSize()) 319 }
320 if (frame.IsZeroSize()) {
321 ReportError();
305 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 322 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
323 }
306 if (!encoded_image_callback_) { 324 if (!encoded_image_callback_) {
307 LOG(LS_WARNING) << "InitEncode() has been called, but a callback function " 325 LOG(LS_WARNING) << "InitEncode() has been called, but a callback function "
308 << "has not been set with RegisterEncodeCompleteCallback()"; 326 << "has not been set with RegisterEncodeCompleteCallback()";
327 ReportError();
309 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 328 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
310 } 329 }
311 if (frame.width() != codec_settings_.width || 330 if (frame.width() != codec_settings_.width ||
312 frame.height() != codec_settings_.height) { 331 frame.height() != codec_settings_.height) {
313 LOG(LS_WARNING) << "Encoder initialized for " << codec_settings_.width 332 LOG(LS_WARNING) << "Encoder initialized for " << codec_settings_.width
314 << "x" << codec_settings_.height << " but trying to encode " 333 << "x" << codec_settings_.height << " but trying to encode "
315 << frame.width() << "x" << frame.height() << " frame."; 334 << frame.width() << "x" << frame.height() << " frame.";
335 ReportError();
316 return WEBRTC_VIDEO_CODEC_ERR_SIZE; 336 return WEBRTC_VIDEO_CODEC_ERR_SIZE;
317 } 337 }
318 338
319 bool force_key_frame = false; 339 bool force_key_frame = false;
320 if (frame_types != nullptr) { 340 if (frame_types != nullptr) {
321 // We only support a single stream. 341 // We only support a single stream.
322 RTC_DCHECK_EQ(frame_types->size(), static_cast<size_t>(1)); 342 RTC_DCHECK_EQ(frame_types->size(), static_cast<size_t>(1));
323 // Skip frame? 343 // Skip frame?
324 if ((*frame_types)[0] == kEmptyFrame) { 344 if ((*frame_types)[0] == kEmptyFrame) {
325 return WEBRTC_VIDEO_CODEC_OK; 345 return WEBRTC_VIDEO_CODEC_OK;
(...skipping 24 matching lines...) Expand all
350 370
351 // EncodeFrame output. 371 // EncodeFrame output.
352 SFrameBSInfo info; 372 SFrameBSInfo info;
353 memset(&info, 0, sizeof(SFrameBSInfo)); 373 memset(&info, 0, sizeof(SFrameBSInfo));
354 374
355 // Encode! 375 // Encode!
356 int enc_ret = openh264_encoder_->EncodeFrame(&picture, &info); 376 int enc_ret = openh264_encoder_->EncodeFrame(&picture, &info);
357 if (enc_ret != 0) { 377 if (enc_ret != 0) {
358 LOG(LS_ERROR) << "OpenH264 frame encoding failed, EncodeFrame returned " 378 LOG(LS_ERROR) << "OpenH264 frame encoding failed, EncodeFrame returned "
359 << enc_ret << "."; 379 << enc_ret << ".";
380 ReportError();
360 return WEBRTC_VIDEO_CODEC_ERROR; 381 return WEBRTC_VIDEO_CODEC_ERROR;
361 } 382 }
362 383
363 encoded_image_._encodedWidth = frame.width(); 384 encoded_image_._encodedWidth = frame.width();
364 encoded_image_._encodedHeight = frame.height(); 385 encoded_image_._encodedHeight = frame.height();
365 encoded_image_._timeStamp = frame.timestamp(); 386 encoded_image_._timeStamp = frame.timestamp();
366 encoded_image_.ntp_time_ms_ = frame.ntp_time_ms(); 387 encoded_image_.ntp_time_ms_ = frame.ntp_time_ms();
367 encoded_image_.capture_time_ms_ = frame.render_time_ms(); 388 encoded_image_.capture_time_ms_ = frame.render_time_ms();
368 encoded_image_._frameType = EVideoFrameType_to_FrameType(info.eFrameType); 389 encoded_image_._frameType = EVideoFrameType_to_FrameType(info.eFrameType);
369 390
(...skipping 12 matching lines...) Expand all
382 &codec_specific, 403 &codec_specific,
383 &frag_header); 404 &frag_header);
384 } 405 }
385 return WEBRTC_VIDEO_CODEC_OK; 406 return WEBRTC_VIDEO_CODEC_OK;
386 } 407 }
387 408
388 bool H264EncoderImpl::IsInitialized() const { 409 bool H264EncoderImpl::IsInitialized() const {
389 return openh264_encoder_ != nullptr; 410 return openh264_encoder_ != nullptr;
390 } 411 }
391 412
413 void H264EncoderImpl::ReportInit() {
414 if (has_reported_init_)
415 return;
416 RTC_HISTOGRAM_COUNTS("WebRTC.Video.H264EncoderImpl.Init",
hlundin-webrtc 2016/02/23 13:55:54 Same again.
hbos 2016/02/23 14:43:26 Done.
417 1 /* sample */,
418 1 /* min */, 1 /* max */,
419 1 /* bucket count */);
420 has_reported_init_ = true;
421 }
422
423 void H264EncoderImpl::ReportError() {
424 if (has_reported_error_)
425 return;
426 RTC_HISTOGRAM_COUNTS("WebRTC.Video.H264EncoderImpl.Error",
427 1 /* sample */,
428 1 /* min */, 1 /* max */,
429 1 /* bucket count */);
430 has_reported_error_ = true;
431 }
432
392 int32_t H264EncoderImpl::SetChannelParameters( 433 int32_t H264EncoderImpl::SetChannelParameters(
393 uint32_t packet_loss, int64_t rtt) { 434 uint32_t packet_loss, int64_t rtt) {
394 return WEBRTC_VIDEO_CODEC_OK; 435 return WEBRTC_VIDEO_CODEC_OK;
395 } 436 }
396 437
397 int32_t H264EncoderImpl::SetPeriodicKeyFrames(bool enable) { 438 int32_t H264EncoderImpl::SetPeriodicKeyFrames(bool enable) {
398 return WEBRTC_VIDEO_CODEC_OK; 439 return WEBRTC_VIDEO_CODEC_OK;
399 } 440 }
400 441
401 void H264EncoderImpl::OnDroppedFrame() { 442 void H264EncoderImpl::OnDroppedFrame() {
402 } 443 }
403 444
404 } // namespace webrtc 445 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698