OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 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 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 // |input_frame_infos_|. | 267 // |input_frame_infos_|. |
268 webrtc::VideoRotation output_rotation_; // Last output frame rotation from | 268 webrtc::VideoRotation output_rotation_; // Last output frame rotation from |
269 // |input_frame_infos_|. | 269 // |input_frame_infos_|. |
270 | 270 |
271 // Frame size in bytes fed to MediaCodec. | 271 // Frame size in bytes fed to MediaCodec. |
272 int yuv_size_; | 272 int yuv_size_; |
273 // True only when between a callback_->OnEncodedImage() call return a positive | 273 // True only when between a callback_->OnEncodedImage() call return a positive |
274 // value and the next Encode() call being ignored. | 274 // value and the next Encode() call being ignored. |
275 bool drop_next_input_frame_; | 275 bool drop_next_input_frame_; |
276 bool scale_; | 276 bool scale_; |
| 277 webrtc::H264::Profile profile_; |
277 // Global references; must be deleted in Release(). | 278 // Global references; must be deleted in Release(). |
278 std::vector<jobject> input_buffers_; | 279 std::vector<jobject> input_buffers_; |
279 webrtc::H264BitstreamParser h264_bitstream_parser_; | 280 webrtc::H264BitstreamParser h264_bitstream_parser_; |
280 | 281 |
281 // VP9 variables to populate codec specific structure. | 282 // VP9 variables to populate codec specific structure. |
282 webrtc::GofInfoVP9 gof_; // Contains each frame's temporal information for | 283 webrtc::GofInfoVP9 gof_; // Contains each frame's temporal information for |
283 // non-flexible VP9 mode. | 284 // non-flexible VP9 mode. |
284 size_t gof_idx_; | 285 size_t gof_idx_; |
285 | 286 |
286 // EGL context - owned by factory, should not be allocated/destroyed | 287 // EGL context - owned by factory, should not be allocated/destroyed |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 "<init>", | 329 "<init>", |
329 "()V"))), | 330 "()V"))), |
330 inited_(false), | 331 inited_(false), |
331 use_surface_(false), | 332 use_surface_(false), |
332 egl_context_(egl_context), | 333 egl_context_(egl_context), |
333 sw_fallback_required_(false) { | 334 sw_fallback_required_(false) { |
334 encoder_queue_checker_.Detach(); | 335 encoder_queue_checker_.Detach(); |
335 | 336 |
336 jclass j_output_buffer_info_class = | 337 jclass j_output_buffer_info_class = |
337 FindClass(jni, "org/webrtc/MediaCodecVideoEncoder$OutputBufferInfo"); | 338 FindClass(jni, "org/webrtc/MediaCodecVideoEncoder$OutputBufferInfo"); |
338 j_init_encode_method_ = GetMethodID( | 339 j_init_encode_method_ = |
339 jni, | 340 GetMethodID(jni, *j_media_codec_video_encoder_class_, "initEncode", |
340 *j_media_codec_video_encoder_class_, | 341 "(Lorg/webrtc/MediaCodecVideoEncoder$VideoCodecType;" |
341 "initEncode", | 342 "IIIIILorg/webrtc/EglBase14$Context;)Z"); |
342 "(Lorg/webrtc/MediaCodecVideoEncoder$VideoCodecType;" | |
343 "IIIILorg/webrtc/EglBase14$Context;)Z"); | |
344 j_get_input_buffers_method_ = GetMethodID( | 343 j_get_input_buffers_method_ = GetMethodID( |
345 jni, | 344 jni, |
346 *j_media_codec_video_encoder_class_, | 345 *j_media_codec_video_encoder_class_, |
347 "getInputBuffers", | 346 "getInputBuffers", |
348 "()[Ljava/nio/ByteBuffer;"); | 347 "()[Ljava/nio/ByteBuffer;"); |
349 j_dequeue_input_buffer_method_ = GetMethodID( | 348 j_dequeue_input_buffer_method_ = GetMethodID( |
350 jni, *j_media_codec_video_encoder_class_, "dequeueInputBuffer", "()I"); | 349 jni, *j_media_codec_video_encoder_class_, "dequeueInputBuffer", "()I"); |
351 j_encode_buffer_method_ = GetMethodID( | 350 j_encode_buffer_method_ = GetMethodID( |
352 jni, *j_media_codec_video_encoder_class_, "encodeBuffer", "(ZIIJ)Z"); | 351 jni, *j_media_codec_video_encoder_class_, "encodeBuffer", "(ZIIJ)Z"); |
353 j_encode_texture_method_ = GetMethodID( | 352 j_encode_texture_method_ = GetMethodID( |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 scale_ = codec_settings->VP8().automaticResizeOn; | 411 scale_ = codec_settings->VP8().automaticResizeOn; |
413 } else if (codec_type == kVideoCodecVP9) { | 412 } else if (codec_type == kVideoCodecVP9) { |
414 scale_ = codec_settings->VP9().automaticResizeOn; | 413 scale_ = codec_settings->VP9().automaticResizeOn; |
415 } else { | 414 } else { |
416 scale_ = true; | 415 scale_ = true; |
417 } | 416 } |
418 | 417 |
419 ALOGD << "InitEncode request: " << init_width << " x " << init_height; | 418 ALOGD << "InitEncode request: " << init_width << " x " << init_height; |
420 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); | 419 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); |
421 | 420 |
| 421 // Check allowed H.264 profile |
| 422 profile_ = webrtc::H264::Profile::kProfileBaseline; |
| 423 if (codec_type == kVideoCodecH264) { |
| 424 const rtc::Optional<webrtc::H264::ProfileLevelId> profile_level_id = |
| 425 webrtc::H264::ParseSdpProfileLevelId(codec_.params); |
| 426 RTC_DCHECK(profile_level_id); |
| 427 profile_ = profile_level_id->profile; |
| 428 ALOGD << "H.264 profile: " << profile_; |
| 429 } |
| 430 |
422 return InitEncodeInternal( | 431 return InitEncodeInternal( |
423 init_width, init_height, codec_settings->startBitrate, | 432 init_width, init_height, codec_settings->startBitrate, |
424 codec_settings->maxFramerate, codec_settings->expect_encode_from_texture); | 433 codec_settings->maxFramerate, codec_settings->expect_encode_from_texture); |
425 } | 434 } |
426 | 435 |
427 int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */, | 436 int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */, |
428 int64_t /* rtt */) { | 437 int64_t /* rtt */) { |
429 return WEBRTC_VIDEO_CODEC_OK; | 438 return WEBRTC_VIDEO_CODEC_OK; |
430 } | 439 } |
431 | 440 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 if (sw_fallback_required_) { | 533 if (sw_fallback_required_) { |
525 return WEBRTC_VIDEO_CODEC_OK; | 534 return WEBRTC_VIDEO_CODEC_OK; |
526 } | 535 } |
527 RTC_CHECK(!use_surface || egl_context_ != nullptr) << "EGL context not set."; | 536 RTC_CHECK(!use_surface || egl_context_ != nullptr) << "EGL context not set."; |
528 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 537 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
529 ScopedLocalRefFrame local_ref_frame(jni); | 538 ScopedLocalRefFrame local_ref_frame(jni); |
530 | 539 |
531 const VideoCodecType codec_type = GetCodecType(); | 540 const VideoCodecType codec_type = GetCodecType(); |
532 ALOGD << "InitEncodeInternal Type: " << static_cast<int>(codec_type) << ", " | 541 ALOGD << "InitEncodeInternal Type: " << static_cast<int>(codec_type) << ", " |
533 << width << " x " << height << ". Bitrate: " << kbps | 542 << width << " x " << height << ". Bitrate: " << kbps |
534 << " kbps. Fps: " << fps; | 543 << " kbps. Fps: " << fps << ". Profile: " << profile_ << "."; |
535 if (kbps == 0) { | 544 if (kbps == 0) { |
536 kbps = last_set_bitrate_kbps_; | 545 kbps = last_set_bitrate_kbps_; |
537 } | 546 } |
538 if (fps == 0) { | 547 if (fps == 0) { |
539 fps = MAX_VIDEO_FPS; | 548 fps = MAX_VIDEO_FPS; |
540 } | 549 } |
541 | 550 |
542 width_ = width; | 551 width_ = width; |
543 height_ = height; | 552 height_ = height; |
544 last_set_bitrate_kbps_ = kbps; | 553 last_set_bitrate_kbps_ = kbps; |
(...skipping 18 matching lines...) Expand all Loading... |
563 use_surface_ = use_surface; | 572 use_surface_ = use_surface; |
564 gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1); | 573 gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1); |
565 gof_idx_ = 0; | 574 gof_idx_ = 0; |
566 last_frame_received_ms_ = -1; | 575 last_frame_received_ms_ = -1; |
567 frames_received_since_last_key_ = kMinKeyFrameInterval; | 576 frames_received_since_last_key_ = kMinKeyFrameInterval; |
568 | 577 |
569 // We enforce no extra stride/padding in the format creation step. | 578 // We enforce no extra stride/padding in the format creation step. |
570 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName( | 579 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName( |
571 jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type); | 580 jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type); |
572 const bool encode_status = jni->CallBooleanMethod( | 581 const bool encode_status = jni->CallBooleanMethod( |
573 *j_media_codec_video_encoder_, j_init_encode_method_, | 582 *j_media_codec_video_encoder_, j_init_encode_method_, j_video_codec_enum, |
574 j_video_codec_enum, width, height, kbps, fps, | 583 profile_, width, height, kbps, fps, |
575 (use_surface ? egl_context_ : nullptr)); | 584 (use_surface ? egl_context_ : nullptr)); |
576 if (!encode_status) { | 585 if (!encode_status) { |
577 ALOGE << "Failed to configure encoder."; | 586 ALOGE << "Failed to configure encoder."; |
578 ProcessHWError(false /* reset_if_fallback_unavailable */); | 587 ProcessHWError(false /* reset_if_fallback_unavailable */); |
579 return WEBRTC_VIDEO_CODEC_ERROR; | 588 return WEBRTC_VIDEO_CODEC_ERROR; |
580 } | 589 } |
581 if (CheckException(jni)) { | 590 if (CheckException(jni)) { |
582 ALOGE << "Exception in init encode."; | 591 ALOGE << "Exception in init encode."; |
583 ProcessHWError(false /* reset_if_fallback_unavailable */); | 592 ProcessHWError(false /* reset_if_fallback_unavailable */); |
584 return WEBRTC_VIDEO_CODEC_ERROR; | 593 return WEBRTC_VIDEO_CODEC_ERROR; |
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1245 jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder"); | 1254 jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder"); |
1246 jclass j_decoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoDecoder"); | 1255 jclass j_decoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoDecoder"); |
1247 supported_codecs_.clear(); | 1256 supported_codecs_.clear(); |
1248 | 1257 |
1249 bool is_vp8_hw_supported = jni->CallStaticBooleanMethod( | 1258 bool is_vp8_hw_supported = jni->CallStaticBooleanMethod( |
1250 j_encoder_class, | 1259 j_encoder_class, |
1251 GetStaticMethodID(jni, j_encoder_class, "isVp8HwSupported", "()Z")); | 1260 GetStaticMethodID(jni, j_encoder_class, "isVp8HwSupported", "()Z")); |
1252 CHECK_EXCEPTION(jni); | 1261 CHECK_EXCEPTION(jni); |
1253 if (is_vp8_hw_supported) { | 1262 if (is_vp8_hw_supported) { |
1254 ALOGD << "VP8 HW Encoder supported."; | 1263 ALOGD << "VP8 HW Encoder supported."; |
1255 supported_codecs_.push_back(cricket::VideoCodec("VP8")); | 1264 supported_codecs_.push_back(cricket::VideoCodec(cricket::kVp8CodecName)); |
1256 } | 1265 } |
1257 | 1266 |
1258 bool is_vp9_hw_supported = jni->CallStaticBooleanMethod( | 1267 bool is_vp9_hw_supported = jni->CallStaticBooleanMethod( |
1259 j_encoder_class, | 1268 j_encoder_class, |
1260 GetStaticMethodID(jni, j_encoder_class, "isVp9HwSupported", "()Z")); | 1269 GetStaticMethodID(jni, j_encoder_class, "isVp9HwSupported", "()Z")); |
1261 CHECK_EXCEPTION(jni); | 1270 CHECK_EXCEPTION(jni); |
1262 if (is_vp9_hw_supported) { | 1271 if (is_vp9_hw_supported) { |
1263 ALOGD << "VP9 HW Encoder supported."; | 1272 ALOGD << "VP9 HW Encoder supported."; |
1264 supported_codecs_.push_back(cricket::VideoCodec("VP9")); | 1273 supported_codecs_.push_back(cricket::VideoCodec(cricket::kVp9CodecName)); |
1265 } | 1274 } |
1266 supported_codecs_with_h264_hp_ = supported_codecs_; | 1275 supported_codecs_with_h264_hp_ = supported_codecs_; |
1267 | 1276 |
1268 // Check if high profile is supported by decoder. If yes, encoder can always | 1277 // Check if high profile is supported by decoder. If yes, encoder can always |
1269 // fall back to baseline profile as a subset as high profile. | 1278 // fall back to baseline profile as a subset as high profile. |
1270 bool is_h264_high_profile_hw_supported = jni->CallStaticBooleanMethod( | 1279 bool is_h264_high_profile_hw_supported = jni->CallStaticBooleanMethod( |
1271 j_decoder_class, | 1280 j_decoder_class, |
1272 GetStaticMethodID(jni, j_decoder_class, "isH264HighProfileHwSupported", | 1281 GetStaticMethodID(jni, j_decoder_class, "isH264HighProfileHwSupported", |
1273 "()Z")); | 1282 "()Z")); |
1274 CHECK_EXCEPTION(jni); | 1283 CHECK_EXCEPTION(jni); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1356 } | 1365 } |
1357 } | 1366 } |
1358 | 1367 |
1359 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( | 1368 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( |
1360 webrtc::VideoEncoder* encoder) { | 1369 webrtc::VideoEncoder* encoder) { |
1361 ALOGD << "Destroy video encoder."; | 1370 ALOGD << "Destroy video encoder."; |
1362 delete encoder; | 1371 delete encoder; |
1363 } | 1372 } |
1364 | 1373 |
1365 } // namespace webrtc_jni | 1374 } // namespace webrtc_jni |
OLD | NEW |