OLD | NEW |
---|---|
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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 | 206 |
207 SEncParamExt encoder_params = CreateEncoderParams(); | 207 SEncParamExt encoder_params = CreateEncoderParams(); |
208 // Initialize. | 208 // Initialize. |
209 if (openh264_encoder_->InitializeExt(&encoder_params) != 0) { | 209 if (openh264_encoder_->InitializeExt(&encoder_params) != 0) { |
210 LOG(LS_ERROR) << "Failed to initialize OpenH264 encoder"; | 210 LOG(LS_ERROR) << "Failed to initialize OpenH264 encoder"; |
211 Release(); | 211 Release(); |
212 ReportError(); | 212 ReportError(); |
213 return WEBRTC_VIDEO_CODEC_ERROR; | 213 return WEBRTC_VIDEO_CODEC_ERROR; |
214 } | 214 } |
215 // TODO(pbos): Base init params on these values before submitting. | 215 // TODO(pbos): Base init params on these values before submitting. |
216 quality_scaler_.Init(codec_settings_.codecType, codec_settings_.startBitrate, | |
217 codec_settings_.width, codec_settings_.height, | |
218 codec_settings_.maxFramerate); | |
219 int video_format = EVideoFormatType::videoFormatI420; | 216 int video_format = EVideoFormatType::videoFormatI420; |
220 openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT, | 217 openh264_encoder_->SetOption(ENCODER_OPTION_DATAFORMAT, |
221 &video_format); | 218 &video_format); |
222 | 219 |
223 // Initialize encoded image. Default buffer size: size of unencoded data. | 220 // Initialize encoded image. Default buffer size: size of unencoded data. |
224 encoded_image_._size = CalcBufferSize( | 221 encoded_image_._size = CalcBufferSize( |
225 kI420, codec_settings_.width, codec_settings_.height); | 222 kI420, codec_settings_.width, codec_settings_.height); |
226 encoded_image_._buffer = new uint8_t[encoded_image_._size]; | 223 encoded_image_._buffer = new uint8_t[encoded_image_._size]; |
227 encoded_image_buffer_.reset(encoded_image_._buffer); | 224 encoded_image_buffer_.reset(encoded_image_._buffer); |
228 encoded_image_._completeFrame = true; | 225 encoded_image_._completeFrame = true; |
(...skipping 19 matching lines...) Expand all Loading... | |
248 encoded_image_callback_ = callback; | 245 encoded_image_callback_ = callback; |
249 return WEBRTC_VIDEO_CODEC_OK; | 246 return WEBRTC_VIDEO_CODEC_OK; |
250 } | 247 } |
251 | 248 |
252 int32_t H264EncoderImpl::SetRates(uint32_t bitrate, uint32_t framerate) { | 249 int32_t H264EncoderImpl::SetRates(uint32_t bitrate, uint32_t framerate) { |
253 if (bitrate <= 0 || framerate <= 0) { | 250 if (bitrate <= 0 || framerate <= 0) { |
254 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 251 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
255 } | 252 } |
256 codec_settings_.targetBitrate = bitrate; | 253 codec_settings_.targetBitrate = bitrate; |
257 codec_settings_.maxFramerate = framerate; | 254 codec_settings_.maxFramerate = framerate; |
258 quality_scaler_.ReportFramerate(framerate); | |
259 | 255 |
260 SBitrateInfo target_bitrate; | 256 SBitrateInfo target_bitrate; |
261 memset(&target_bitrate, 0, sizeof(SBitrateInfo)); | 257 memset(&target_bitrate, 0, sizeof(SBitrateInfo)); |
262 target_bitrate.iLayer = SPATIAL_LAYER_ALL, | 258 target_bitrate.iLayer = SPATIAL_LAYER_ALL, |
263 target_bitrate.iBitrate = codec_settings_.targetBitrate * 1000; | 259 target_bitrate.iBitrate = codec_settings_.targetBitrate * 1000; |
264 openh264_encoder_->SetOption(ENCODER_OPTION_BITRATE, | 260 openh264_encoder_->SetOption(ENCODER_OPTION_BITRATE, |
265 &target_bitrate); | 261 &target_bitrate); |
266 float max_framerate = static_cast<float>(codec_settings_.maxFramerate); | 262 float max_framerate = static_cast<float>(codec_settings_.maxFramerate); |
267 openh264_encoder_->SetOption(ENCODER_OPTION_FRAME_RATE, | 263 openh264_encoder_->SetOption(ENCODER_OPTION_FRAME_RATE, |
268 &max_framerate); | 264 &max_framerate); |
(...skipping 11 matching lines...) Expand all Loading... | |
280 ReportError(); | 276 ReportError(); |
281 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 277 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
282 } | 278 } |
283 if (!encoded_image_callback_) { | 279 if (!encoded_image_callback_) { |
284 LOG(LS_WARNING) << "InitEncode() has been called, but a callback function " | 280 LOG(LS_WARNING) << "InitEncode() has been called, but a callback function " |
285 << "has not been set with RegisterEncodeCompleteCallback()"; | 281 << "has not been set with RegisterEncodeCompleteCallback()"; |
286 ReportError(); | 282 ReportError(); |
287 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 283 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
288 } | 284 } |
289 | 285 |
290 quality_scaler_.OnEncodeFrame(input_frame.width(), input_frame.height()); | |
magjed_webrtc
2016/10/26 14:28:36
I would like to document the condition that the in
kthelgason
2016/10/26 19:02:49
I agree, good call. Done.
| |
291 rtc::scoped_refptr<const VideoFrameBuffer> frame_buffer = | |
292 quality_scaler_.GetScaledBuffer(input_frame.video_frame_buffer()); | |
293 if (frame_buffer->width() != codec_settings_.width || | |
294 frame_buffer->height() != codec_settings_.height) { | |
295 LOG(LS_INFO) << "Encoder reinitialized from " << codec_settings_.width | |
296 << "x" << codec_settings_.height << " to " | |
297 << frame_buffer->width() << "x" << frame_buffer->height(); | |
298 codec_settings_.width = frame_buffer->width(); | |
299 codec_settings_.height = frame_buffer->height(); | |
300 SEncParamExt encoder_params = CreateEncoderParams(); | |
301 openh264_encoder_->SetOption(ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, | |
302 &encoder_params); | |
303 } | |
304 | |
305 bool force_key_frame = false; | 286 bool force_key_frame = false; |
306 if (frame_types != nullptr) { | 287 if (frame_types != nullptr) { |
307 // We only support a single stream. | 288 // We only support a single stream. |
308 RTC_DCHECK_EQ(frame_types->size(), static_cast<size_t>(1)); | 289 RTC_DCHECK_EQ(frame_types->size(), static_cast<size_t>(1)); |
309 // Skip frame? | 290 // Skip frame? |
310 if ((*frame_types)[0] == kEmptyFrame) { | 291 if ((*frame_types)[0] == kEmptyFrame) { |
311 return WEBRTC_VIDEO_CODEC_OK; | 292 return WEBRTC_VIDEO_CODEC_OK; |
312 } | 293 } |
313 // Force key frame? | 294 // Force key frame? |
314 force_key_frame = (*frame_types)[0] == kVideoFrameKey; | 295 force_key_frame = (*frame_types)[0] == kVideoFrameKey; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
365 if (encoded_image_._length > 0) { | 346 if (encoded_image_._length > 0) { |
366 // Deliver encoded image. | 347 // Deliver encoded image. |
367 CodecSpecificInfo codec_specific; | 348 CodecSpecificInfo codec_specific; |
368 codec_specific.codecType = kVideoCodecH264; | 349 codec_specific.codecType = kVideoCodecH264; |
369 encoded_image_callback_->Encoded(encoded_image_, &codec_specific, | 350 encoded_image_callback_->Encoded(encoded_image_, &codec_specific, |
370 &frag_header); | 351 &frag_header); |
371 | 352 |
372 // Parse and report QP. | 353 // Parse and report QP. |
373 h264_bitstream_parser_.ParseBitstream(encoded_image_._buffer, | 354 h264_bitstream_parser_.ParseBitstream(encoded_image_._buffer, |
374 encoded_image_._length); | 355 encoded_image_._length); |
375 int qp = -1; | 356 h264_bitstream_parser_.GetLastSliceQp(&encoded_image_.qp_) |
376 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) | |
377 quality_scaler_.ReportQP(qp); | |
378 } else { | |
379 quality_scaler_.ReportDroppedFrame(); | |
380 } | 357 } |
381 return WEBRTC_VIDEO_CODEC_OK; | 358 return WEBRTC_VIDEO_CODEC_OK; |
382 } | 359 } |
383 | 360 |
384 const char* H264EncoderImpl::ImplementationName() const { | 361 const char* H264EncoderImpl::ImplementationName() const { |
385 return "OpenH264"; | 362 return "OpenH264"; |
386 } | 363 } |
387 | 364 |
388 bool H264EncoderImpl::IsInitialized() const { | 365 bool H264EncoderImpl::IsInitialized() const { |
389 return openh264_encoder_ != nullptr; | 366 return openh264_encoder_ != nullptr; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 | 441 |
465 int32_t H264EncoderImpl::SetChannelParameters( | 442 int32_t H264EncoderImpl::SetChannelParameters( |
466 uint32_t packet_loss, int64_t rtt) { | 443 uint32_t packet_loss, int64_t rtt) { |
467 return WEBRTC_VIDEO_CODEC_OK; | 444 return WEBRTC_VIDEO_CODEC_OK; |
468 } | 445 } |
469 | 446 |
470 int32_t H264EncoderImpl::SetPeriodicKeyFrames(bool enable) { | 447 int32_t H264EncoderImpl::SetPeriodicKeyFrames(bool enable) { |
471 return WEBRTC_VIDEO_CODEC_OK; | 448 return WEBRTC_VIDEO_CODEC_OK; |
472 } | 449 } |
473 | 450 |
474 void H264EncoderImpl::OnDroppedFrame() { | 451 QualityScaler::Settings H264EncoderImpl::GetQPThresholds() const { |
475 quality_scaler_.ReportDroppedFrame(); | 452 return QualityScaler::Settings(true); |
476 } | 453 } |
477 | 454 |
478 } // namespace webrtc | 455 } // namespace webrtc |
OLD | NEW |