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

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: rebase Created 4 years 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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 228
229 SEncParamExt encoder_params = CreateEncoderParams(); 229 SEncParamExt encoder_params = CreateEncoderParams();
230 // Initialize. 230 // Initialize.
231 if (openh264_encoder_->InitializeExt(&encoder_params) != 0) { 231 if (openh264_encoder_->InitializeExt(&encoder_params) != 0) {
232 LOG(LS_ERROR) << "Failed to initialize OpenH264 encoder"; 232 LOG(LS_ERROR) << "Failed to initialize OpenH264 encoder";
233 Release(); 233 Release();
234 ReportError(); 234 ReportError();
235 return WEBRTC_VIDEO_CODEC_ERROR; 235 return WEBRTC_VIDEO_CODEC_ERROR;
236 } 236 }
237 // TODO(pbos): Base init params on these values before submitting. 237 // TODO(pbos): Base init params on these values before submitting.
238 quality_scaler_.Init(codec_settings->codecType, codec_settings->startBitrate,
239 codec_settings->width, codec_settings->height,
240 codec_settings->maxFramerate);
241 int video_format = EVideoFormatType::videoFormatI420; 238 int video_format = EVideoFormatType::videoFormatI420;
242 openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT, 239 openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT,
243 &video_format); 240 &video_format);
244 241
245 // Initialize encoded image. Default buffer size: size of unencoded data. 242 // Initialize encoded image. Default buffer size: size of unencoded data.
246 encoded_image_._size = 243 encoded_image_._size =
247 CalcBufferSize(kI420, codec_settings->width, codec_settings->height); 244 CalcBufferSize(kI420, codec_settings->width, codec_settings->height);
248 encoded_image_._buffer = new uint8_t[encoded_image_._size]; 245 encoded_image_._buffer = new uint8_t[encoded_image_._size];
249 encoded_image_buffer_.reset(encoded_image_._buffer); 246 encoded_image_buffer_.reset(encoded_image_._buffer);
250 encoded_image_._completeFrame = true; 247 encoded_image_._completeFrame = true;
(...skipping 21 matching lines...) Expand all
272 } 269 }
273 270
274 int32_t H264EncoderImpl::SetRateAllocation( 271 int32_t H264EncoderImpl::SetRateAllocation(
275 const BitrateAllocation& bitrate_allocation, 272 const BitrateAllocation& bitrate_allocation,
276 uint32_t framerate) { 273 uint32_t framerate) {
277 if (bitrate_allocation.get_sum_bps() <= 0 || framerate <= 0) 274 if (bitrate_allocation.get_sum_bps() <= 0 || framerate <= 0)
278 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 275 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
279 276
280 target_bps_ = bitrate_allocation.get_sum_bps(); 277 target_bps_ = bitrate_allocation.get_sum_bps();
281 max_frame_rate_ = static_cast<float>(framerate); 278 max_frame_rate_ = static_cast<float>(framerate);
282 quality_scaler_.ReportFramerate(framerate);
283 279
284 SBitrateInfo target_bitrate; 280 SBitrateInfo target_bitrate;
285 memset(&target_bitrate, 0, sizeof(SBitrateInfo)); 281 memset(&target_bitrate, 0, sizeof(SBitrateInfo));
286 target_bitrate.iLayer = SPATIAL_LAYER_ALL, 282 target_bitrate.iLayer = SPATIAL_LAYER_ALL,
287 target_bitrate.iBitrate = target_bps_; 283 target_bitrate.iBitrate = target_bps_;
288 openh264_encoder_->SetOption(ENCODER_OPTION_BITRATE, 284 openh264_encoder_->SetOption(ENCODER_OPTION_BITRATE,
289 &target_bitrate); 285 &target_bitrate);
290 openh264_encoder_->SetOption(ENCODER_OPTION_FRAME_RATE, &max_frame_rate_); 286 openh264_encoder_->SetOption(ENCODER_OPTION_FRAME_RATE, &max_frame_rate_);
291 return WEBRTC_VIDEO_CODEC_OK; 287 return WEBRTC_VIDEO_CODEC_OK;
292 } 288 }
293 289
294 int32_t H264EncoderImpl::Encode(const VideoFrame& input_frame, 290 int32_t H264EncoderImpl::Encode(const VideoFrame& input_frame,
295 const CodecSpecificInfo* codec_specific_info, 291 const CodecSpecificInfo* codec_specific_info,
296 const std::vector<FrameType>* frame_types) { 292 const std::vector<FrameType>* frame_types) {
297 if (!IsInitialized()) { 293 if (!IsInitialized()) {
298 ReportError(); 294 ReportError();
299 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 295 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
300 } 296 }
301 if (input_frame.IsZeroSize()) { 297 if (input_frame.IsZeroSize()) {
302 ReportError(); 298 ReportError();
303 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 299 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
304 } 300 }
305 if (!encoded_image_callback_) { 301 if (!encoded_image_callback_) {
306 LOG(LS_WARNING) << "InitEncode() has been called, but a callback function " 302 LOG(LS_WARNING) << "InitEncode() has been called, but a callback function "
307 << "has not been set with RegisterEncodeCompleteCallback()"; 303 << "has not been set with RegisterEncodeCompleteCallback()";
308 ReportError(); 304 ReportError();
309 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 305 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
310 } 306 }
311 307
312 quality_scaler_.OnEncodeFrame(input_frame.width(), input_frame.height());
313 rtc::scoped_refptr<const VideoFrameBuffer> frame_buffer =
314 quality_scaler_.GetScaledBuffer(input_frame.video_frame_buffer());
315 if (frame_buffer->width() != width_ || frame_buffer->height() != height_) {
316 LOG(LS_INFO) << "Encoder reinitialized from " << width_ << "x" << height_
317 << " to " << frame_buffer->width() << "x"
318 << frame_buffer->height();
319 width_ = frame_buffer->width();
320 height_ = frame_buffer->height();
321 SEncParamExt encoder_params = CreateEncoderParams();
322 openh264_encoder_->SetOption(ENCODER_OPTION_SVC_ENCODE_PARAM_EXT,
323 &encoder_params);
324 }
325
326 bool force_key_frame = false; 308 bool force_key_frame = false;
327 if (frame_types != nullptr) { 309 if (frame_types != nullptr) {
328 // We only support a single stream. 310 // We only support a single stream.
329 RTC_DCHECK_EQ(frame_types->size(), 1); 311 RTC_DCHECK_EQ(frame_types->size(), 1);
330 // Skip frame? 312 // Skip frame?
331 if ((*frame_types)[0] == kEmptyFrame) { 313 if ((*frame_types)[0] == kEmptyFrame) {
332 return WEBRTC_VIDEO_CODEC_OK; 314 return WEBRTC_VIDEO_CODEC_OK;
333 } 315 }
334 // Force key frame? 316 // Force key frame?
335 force_key_frame = (*frame_types)[0] == kVideoFrameKey; 317 force_key_frame = (*frame_types)[0] == kVideoFrameKey;
336 } 318 }
337 if (force_key_frame) { 319 if (force_key_frame) {
338 // API doc says ForceIntraFrame(false) does nothing, but calling this 320 // API doc says ForceIntraFrame(false) does nothing, but calling this
339 // function forces a key frame regardless of the |bIDR| argument's value. 321 // function forces a key frame regardless of the |bIDR| argument's value.
340 // (If every frame is a key frame we get lag/delays.) 322 // (If every frame is a key frame we get lag/delays.)
341 openh264_encoder_->ForceIntraFrame(true); 323 openh264_encoder_->ForceIntraFrame(true);
342 } 324 }
343 325 rtc::scoped_refptr<const VideoFrameBuffer> frame_buffer =
326 input_frame.video_frame_buffer();
344 // EncodeFrame input. 327 // EncodeFrame input.
345 SSourcePicture picture; 328 SSourcePicture picture;
346 memset(&picture, 0, sizeof(SSourcePicture)); 329 memset(&picture, 0, sizeof(SSourcePicture));
347 picture.iPicWidth = frame_buffer->width(); 330 picture.iPicWidth = frame_buffer->width();
348 picture.iPicHeight = frame_buffer->height(); 331 picture.iPicHeight = frame_buffer->height();
349 picture.iColorFormat = EVideoFormatType::videoFormatI420; 332 picture.iColorFormat = EVideoFormatType::videoFormatI420;
350 picture.uiTimeStamp = input_frame.ntp_time_ms(); 333 picture.uiTimeStamp = input_frame.ntp_time_ms();
351 picture.iStride[0] = frame_buffer->StrideY(); 334 picture.iStride[0] = frame_buffer->StrideY();
352 picture.iStride[1] = frame_buffer->StrideU(); 335 picture.iStride[1] = frame_buffer->StrideU();
353 picture.iStride[2] = frame_buffer->StrideV(); 336 picture.iStride[2] = frame_buffer->StrideV();
(...skipping 23 matching lines...) Expand all
377 encoded_image_._frameType = ConvertToVideoFrameType(info.eFrameType); 360 encoded_image_._frameType = ConvertToVideoFrameType(info.eFrameType);
378 361
379 // Split encoded image up into fragments. This also updates |encoded_image_|. 362 // Split encoded image up into fragments. This also updates |encoded_image_|.
380 RTPFragmentationHeader frag_header; 363 RTPFragmentationHeader frag_header;
381 RtpFragmentize(&encoded_image_, &encoded_image_buffer_, *frame_buffer, &info, 364 RtpFragmentize(&encoded_image_, &encoded_image_buffer_, *frame_buffer, &info,
382 &frag_header); 365 &frag_header);
383 366
384 // Encoder can skip frames to save bandwidth in which case 367 // Encoder can skip frames to save bandwidth in which case
385 // |encoded_image_._length| == 0. 368 // |encoded_image_._length| == 0.
386 if (encoded_image_._length > 0) { 369 if (encoded_image_._length > 0) {
387 // Parse and report QP.
388 h264_bitstream_parser_.ParseBitstream(encoded_image_._buffer,
389 encoded_image_._length);
390 int qp = -1;
391 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) {
392 quality_scaler_.ReportQP(qp);
393 encoded_image_.qp_ = qp;
394 }
395
396 // Deliver encoded image. 370 // Deliver encoded image.
397 CodecSpecificInfo codec_specific; 371 CodecSpecificInfo codec_specific;
398 codec_specific.codecType = kVideoCodecH264; 372 codec_specific.codecType = kVideoCodecH264;
399 encoded_image_callback_->OnEncodedImage(encoded_image_, &codec_specific, 373 encoded_image_callback_->OnEncodedImage(encoded_image_, &codec_specific,
400 &frag_header); 374 &frag_header);
401 } else { 375
402 quality_scaler_.ReportDroppedFrame(); 376 // Parse and report QP.
377 h264_bitstream_parser_.ParseBitstream(encoded_image_._buffer,
378 encoded_image_._length);
379 h264_bitstream_parser_.GetLastSliceQp(&encoded_image_.qp_);
403 } 380 }
404 return WEBRTC_VIDEO_CODEC_OK; 381 return WEBRTC_VIDEO_CODEC_OK;
405 } 382 }
406 383
407 const char* H264EncoderImpl::ImplementationName() const { 384 const char* H264EncoderImpl::ImplementationName() const {
408 return "OpenH264"; 385 return "OpenH264";
409 } 386 }
410 387
411 bool H264EncoderImpl::IsInitialized() const { 388 bool H264EncoderImpl::IsInitialized() const {
412 return openh264_encoder_ != nullptr; 389 return openh264_encoder_ != nullptr;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 470
494 int32_t H264EncoderImpl::SetChannelParameters( 471 int32_t H264EncoderImpl::SetChannelParameters(
495 uint32_t packet_loss, int64_t rtt) { 472 uint32_t packet_loss, int64_t rtt) {
496 return WEBRTC_VIDEO_CODEC_OK; 473 return WEBRTC_VIDEO_CODEC_OK;
497 } 474 }
498 475
499 int32_t H264EncoderImpl::SetPeriodicKeyFrames(bool enable) { 476 int32_t H264EncoderImpl::SetPeriodicKeyFrames(bool enable) {
500 return WEBRTC_VIDEO_CODEC_OK; 477 return WEBRTC_VIDEO_CODEC_OK;
501 } 478 }
502 479
503 void H264EncoderImpl::OnDroppedFrame() { 480 VideoEncoder::ScalingSettings H264EncoderImpl::GetScalingSettings() const {
504 quality_scaler_.ReportDroppedFrame(); 481 return VideoEncoder::ScalingSettings(true);
505 } 482 }
506 483
507 } // namespace webrtc 484 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h ('k') | webrtc/modules/video_coding/codecs/i420/include/i420.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698