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

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

Issue 2398963003: Move usage of QualityScaler to ViEEncoder. (Closed)
Patch Set: Fix flaky test Created 4 years, 1 month 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 */
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 220
221 SEncParamExt encoder_params = CreateEncoderParams(); 221 SEncParamExt encoder_params = CreateEncoderParams();
222 // Initialize. 222 // Initialize.
223 if (openh264_encoder_->InitializeExt(&encoder_params) != 0) { 223 if (openh264_encoder_->InitializeExt(&encoder_params) != 0) {
224 LOG(LS_ERROR) << "Failed to initialize OpenH264 encoder"; 224 LOG(LS_ERROR) << "Failed to initialize OpenH264 encoder";
225 Release(); 225 Release();
226 ReportError(); 226 ReportError();
227 return WEBRTC_VIDEO_CODEC_ERROR; 227 return WEBRTC_VIDEO_CODEC_ERROR;
228 } 228 }
229 // TODO(pbos): Base init params on these values before submitting. 229 // TODO(pbos): Base init params on these values before submitting.
230 quality_scaler_.Init(codec_settings->codecType, codec_settings->startBitrate,
231 codec_settings->width, codec_settings->height,
232 codec_settings->maxFramerate);
233 int video_format = EVideoFormatType::videoFormatI420; 230 int video_format = EVideoFormatType::videoFormatI420;
234 openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT, 231 openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT,
235 &video_format); 232 &video_format);
236 233
237 // Initialize encoded image. Default buffer size: size of unencoded data. 234 // Initialize encoded image. Default buffer size: size of unencoded data.
238 encoded_image_._size = 235 encoded_image_._size =
239 CalcBufferSize(kI420, codec_settings->width, codec_settings->height); 236 CalcBufferSize(kI420, codec_settings->width, codec_settings->height);
240 encoded_image_._buffer = new uint8_t[encoded_image_._size]; 237 encoded_image_._buffer = new uint8_t[encoded_image_._size];
241 encoded_image_buffer_.reset(encoded_image_._buffer); 238 encoded_image_buffer_.reset(encoded_image_._buffer);
242 encoded_image_._completeFrame = true; 239 encoded_image_._completeFrame = true;
(...skipping 19 matching lines...) Expand all
262 encoded_image_callback_ = callback; 259 encoded_image_callback_ = callback;
263 return WEBRTC_VIDEO_CODEC_OK; 260 return WEBRTC_VIDEO_CODEC_OK;
264 } 261 }
265 262
266 int32_t H264EncoderImpl::SetRates(uint32_t bitrate, uint32_t framerate) { 263 int32_t H264EncoderImpl::SetRates(uint32_t bitrate, uint32_t framerate) {
267 if (bitrate <= 0 || framerate <= 0) { 264 if (bitrate <= 0 || framerate <= 0) {
268 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 265 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
269 } 266 }
270 target_bps_ = bitrate * 1000; 267 target_bps_ = bitrate * 1000;
271 max_frame_rate_ = static_cast<float>(framerate); 268 max_frame_rate_ = static_cast<float>(framerate);
272 quality_scaler_.ReportFramerate(framerate);
273 269
274 SBitrateInfo target_bitrate; 270 SBitrateInfo target_bitrate;
275 memset(&target_bitrate, 0, sizeof(SBitrateInfo)); 271 memset(&target_bitrate, 0, sizeof(SBitrateInfo));
276 target_bitrate.iLayer = SPATIAL_LAYER_ALL, 272 target_bitrate.iLayer = SPATIAL_LAYER_ALL,
277 target_bitrate.iBitrate = target_bps_; 273 target_bitrate.iBitrate = target_bps_;
278 openh264_encoder_->SetOption(ENCODER_OPTION_BITRATE, 274 openh264_encoder_->SetOption(ENCODER_OPTION_BITRATE,
279 &target_bitrate); 275 &target_bitrate);
280 openh264_encoder_->SetOption(ENCODER_OPTION_FRAME_RATE, &max_frame_rate_); 276 openh264_encoder_->SetOption(ENCODER_OPTION_FRAME_RATE, &max_frame_rate_);
281 return WEBRTC_VIDEO_CODEC_OK; 277 return WEBRTC_VIDEO_CODEC_OK;
282 } 278 }
283 279
284 int32_t H264EncoderImpl::Encode(const VideoFrame& input_frame, 280 int32_t H264EncoderImpl::Encode(const VideoFrame& input_frame,
285 const CodecSpecificInfo* codec_specific_info, 281 const CodecSpecificInfo* codec_specific_info,
286 const std::vector<FrameType>* frame_types) { 282 const std::vector<FrameType>* frame_types) {
287 if (!IsInitialized()) { 283 if (!IsInitialized()) {
288 ReportError(); 284 ReportError();
289 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 285 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
290 } 286 }
291 if (input_frame.IsZeroSize()) { 287 if (input_frame.IsZeroSize()) {
292 ReportError(); 288 ReportError();
293 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 289 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
294 } 290 }
295 if (!encoded_image_callback_) { 291 if (!encoded_image_callback_) {
296 LOG(LS_WARNING) << "InitEncode() has been called, but a callback function " 292 LOG(LS_WARNING) << "InitEncode() has been called, but a callback function "
297 << "has not been set with RegisterEncodeCompleteCallback()"; 293 << "has not been set with RegisterEncodeCompleteCallback()";
298 ReportError(); 294 ReportError();
299 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 295 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
300 } 296 }
301 297
302 quality_scaler_.OnEncodeFrame(input_frame.width(), input_frame.height());
303 rtc::scoped_refptr<const VideoFrameBuffer> frame_buffer =
304 quality_scaler_.GetScaledBuffer(input_frame.video_frame_buffer());
305 if (frame_buffer->width() != width_ || frame_buffer->height() != height_) {
306 LOG(LS_INFO) << "Encoder reinitialized from " << width_ << "x" << height_
307 << " to " << frame_buffer->width() << "x"
308 << frame_buffer->height();
309 width_ = frame_buffer->width();
310 height_ = frame_buffer->height();
311 SEncParamExt encoder_params = CreateEncoderParams();
312 openh264_encoder_->SetOption(ENCODER_OPTION_SVC_ENCODE_PARAM_EXT,
313 &encoder_params);
314 }
315
316 bool force_key_frame = false; 298 bool force_key_frame = false;
317 if (frame_types != nullptr) { 299 if (frame_types != nullptr) {
318 // We only support a single stream. 300 // We only support a single stream.
319 RTC_DCHECK_EQ(frame_types->size(), static_cast<size_t>(1)); 301 RTC_DCHECK_EQ(frame_types->size(), static_cast<size_t>(1));
320 // Skip frame? 302 // Skip frame?
321 if ((*frame_types)[0] == kEmptyFrame) { 303 if ((*frame_types)[0] == kEmptyFrame) {
322 return WEBRTC_VIDEO_CODEC_OK; 304 return WEBRTC_VIDEO_CODEC_OK;
323 } 305 }
324 // Force key frame? 306 // Force key frame?
325 force_key_frame = (*frame_types)[0] == kVideoFrameKey; 307 force_key_frame = (*frame_types)[0] == kVideoFrameKey;
326 } 308 }
327 if (force_key_frame) { 309 if (force_key_frame) {
328 // API doc says ForceIntraFrame(false) does nothing, but calling this 310 // API doc says ForceIntraFrame(false) does nothing, but calling this
329 // function forces a key frame regardless of the |bIDR| argument's value. 311 // function forces a key frame regardless of the |bIDR| argument's value.
330 // (If every frame is a key frame we get lag/delays.) 312 // (If every frame is a key frame we get lag/delays.)
331 openh264_encoder_->ForceIntraFrame(true); 313 openh264_encoder_->ForceIntraFrame(true);
332 } 314 }
333 315 rtc::scoped_refptr<const VideoFrameBuffer> frame_buffer =
316 input_frame.video_frame_buffer();
334 // EncodeFrame input. 317 // EncodeFrame input.
335 SSourcePicture picture; 318 SSourcePicture picture;
336 memset(&picture, 0, sizeof(SSourcePicture)); 319 memset(&picture, 0, sizeof(SSourcePicture));
337 picture.iPicWidth = frame_buffer->width(); 320 picture.iPicWidth = frame_buffer->width();
338 picture.iPicHeight = frame_buffer->height(); 321 picture.iPicHeight = frame_buffer->height();
339 picture.iColorFormat = EVideoFormatType::videoFormatI420; 322 picture.iColorFormat = EVideoFormatType::videoFormatI420;
340 picture.uiTimeStamp = input_frame.ntp_time_ms(); 323 picture.uiTimeStamp = input_frame.ntp_time_ms();
341 picture.iStride[0] = frame_buffer->StrideY(); 324 picture.iStride[0] = frame_buffer->StrideY();
342 picture.iStride[1] = frame_buffer->StrideU(); 325 picture.iStride[1] = frame_buffer->StrideU();
343 picture.iStride[2] = frame_buffer->StrideV(); 326 picture.iStride[2] = frame_buffer->StrideV();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 if (encoded_image_._length > 0) { 359 if (encoded_image_._length > 0) {
377 // Deliver encoded image. 360 // Deliver encoded image.
378 CodecSpecificInfo codec_specific; 361 CodecSpecificInfo codec_specific;
379 codec_specific.codecType = kVideoCodecH264; 362 codec_specific.codecType = kVideoCodecH264;
380 encoded_image_callback_->OnEncodedImage(encoded_image_, &codec_specific, 363 encoded_image_callback_->OnEncodedImage(encoded_image_, &codec_specific,
381 &frag_header); 364 &frag_header);
382 365
383 // Parse and report QP. 366 // Parse and report QP.
384 h264_bitstream_parser_.ParseBitstream(encoded_image_._buffer, 367 h264_bitstream_parser_.ParseBitstream(encoded_image_._buffer,
385 encoded_image_._length); 368 encoded_image_._length);
386 int qp = -1; 369 h264_bitstream_parser_.GetLastSliceQp(&encoded_image_.qp_);
387 if (h264_bitstream_parser_.GetLastSliceQp(&qp))
388 quality_scaler_.ReportQP(qp);
389 } else {
390 quality_scaler_.ReportDroppedFrame();
391 } 370 }
392 return WEBRTC_VIDEO_CODEC_OK; 371 return WEBRTC_VIDEO_CODEC_OK;
393 } 372 }
394 373
395 const char* H264EncoderImpl::ImplementationName() const { 374 const char* H264EncoderImpl::ImplementationName() const {
396 return "OpenH264"; 375 return "OpenH264";
397 } 376 }
398 377
399 bool H264EncoderImpl::IsInitialized() const { 378 bool H264EncoderImpl::IsInitialized() const {
400 return openh264_encoder_ != nullptr; 379 return openh264_encoder_ != nullptr;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 460
482 int32_t H264EncoderImpl::SetChannelParameters( 461 int32_t H264EncoderImpl::SetChannelParameters(
483 uint32_t packet_loss, int64_t rtt) { 462 uint32_t packet_loss, int64_t rtt) {
484 return WEBRTC_VIDEO_CODEC_OK; 463 return WEBRTC_VIDEO_CODEC_OK;
485 } 464 }
486 465
487 int32_t H264EncoderImpl::SetPeriodicKeyFrames(bool enable) { 466 int32_t H264EncoderImpl::SetPeriodicKeyFrames(bool enable) {
488 return WEBRTC_VIDEO_CODEC_OK; 467 return WEBRTC_VIDEO_CODEC_OK;
489 } 468 }
490 469
491 void H264EncoderImpl::OnDroppedFrame() { 470 QualityScaler::Settings H264EncoderImpl::GetQPThresholds() const {
492 quality_scaler_.ReportDroppedFrame(); 471 return QualityScaler::Settings(true);
493 } 472 }
494 473
495 } // namespace webrtc 474 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698