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

Side by Side Diff: webrtc/api/android/jni/androidmediaencoder_jni.cc

Issue 2474993002: Pass selected cricket::VideoCodec down to internal H264 encoder (Closed)
Patch Set: Fix. 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 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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 // Android's MediaCodec SDK API behind the scenes to implement (hopefully) 89 // Android's MediaCodec SDK API behind the scenes to implement (hopefully)
90 // HW-backed video encode. This C++ class is implemented as a very thin shim, 90 // HW-backed video encode. This C++ class is implemented as a very thin shim,
91 // delegating all of the interesting work to org.webrtc.MediaCodecVideoEncoder. 91 // delegating all of the interesting work to org.webrtc.MediaCodecVideoEncoder.
92 // MediaCodecVideoEncoder is created, operated, and destroyed on a single 92 // MediaCodecVideoEncoder is created, operated, and destroyed on a single
93 // thread, currently the libjingle Worker thread. 93 // thread, currently the libjingle Worker thread.
94 class MediaCodecVideoEncoder : public webrtc::VideoEncoder, 94 class MediaCodecVideoEncoder : public webrtc::VideoEncoder,
95 public rtc::MessageHandler { 95 public rtc::MessageHandler {
96 public: 96 public:
97 virtual ~MediaCodecVideoEncoder(); 97 virtual ~MediaCodecVideoEncoder();
98 MediaCodecVideoEncoder(JNIEnv* jni, 98 MediaCodecVideoEncoder(JNIEnv* jni,
99 VideoCodecType codecType, 99 const cricket::VideoCodec& codec,
100 jobject egl_context); 100 jobject egl_context);
101 101
102 // webrtc::VideoEncoder implementation. Everything trampolines to 102 // webrtc::VideoEncoder implementation. Everything trampolines to
103 // |codec_thread_| for execution. 103 // |codec_thread_| for execution.
104 int32_t InitEncode(const webrtc::VideoCodec* codec_settings, 104 int32_t InitEncode(const webrtc::VideoCodec* codec_settings,
105 int32_t /* number_of_cores */, 105 int32_t /* number_of_cores */,
106 size_t /* max_payload_size */) override; 106 size_t /* max_payload_size */) override;
107 int32_t Encode(const webrtc::VideoFrame& input_image, 107 int32_t Encode(const webrtc::VideoFrame& input_image,
108 const webrtc::CodecSpecificInfo* /* codec_specific_info */, 108 const webrtc::CodecSpecificInfo* /* codec_specific_info */,
109 const std::vector<webrtc::FrameType>* frame_types) override; 109 const std::vector<webrtc::FrameType>* frame_types) override;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // true on success. 178 // true on success.
179 bool DeliverPendingOutputs(JNIEnv* jni); 179 bool DeliverPendingOutputs(JNIEnv* jni);
180 180
181 // Search for H.264 start codes. 181 // Search for H.264 start codes.
182 int32_t NextNaluPosition(uint8_t *buffer, size_t buffer_size); 182 int32_t NextNaluPosition(uint8_t *buffer, size_t buffer_size);
183 183
184 // Displays encoder statistics. 184 // Displays encoder statistics.
185 void LogStatistics(bool force_log); 185 void LogStatistics(bool force_log);
186 186
187 // Type of video codec. 187 // Type of video codec.
188 VideoCodecType codecType_; 188 const cricket::VideoCodec codec_;
189 189
190 // Valid all the time since RegisterEncodeCompleteCallback() Invoke()s to 190 // Valid all the time since RegisterEncodeCompleteCallback() Invoke()s to
191 // |codec_thread_| synchronously. 191 // |codec_thread_| synchronously.
192 webrtc::EncodedImageCallback* callback_; 192 webrtc::EncodedImageCallback* callback_;
193 193
194 // State that is constant for the lifetime of this object once the ctor 194 // State that is constant for the lifetime of this object once the ctor
195 // returns. 195 // returns.
196 std::unique_ptr<Thread> 196 std::unique_ptr<Thread>
197 codec_thread_; // Thread on which to operate MediaCodec. 197 codec_thread_; // Thread on which to operate MediaCodec.
198 rtc::ThreadChecker codec_thread_checker_; 198 rtc::ThreadChecker codec_thread_checker_;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 294
295 bool sw_fallback_required_; 295 bool sw_fallback_required_;
296 }; 296 };
297 297
298 MediaCodecVideoEncoder::~MediaCodecVideoEncoder() { 298 MediaCodecVideoEncoder::~MediaCodecVideoEncoder() {
299 // Call Release() to ensure no more callbacks to us after we are deleted. 299 // Call Release() to ensure no more callbacks to us after we are deleted.
300 Release(); 300 Release();
301 } 301 }
302 302
303 MediaCodecVideoEncoder::MediaCodecVideoEncoder(JNIEnv* jni, 303 MediaCodecVideoEncoder::MediaCodecVideoEncoder(JNIEnv* jni,
304 VideoCodecType codecType, 304 const cricket::VideoCodec& codec,
305 jobject egl_context) 305 jobject egl_context)
306 : codecType_(codecType), 306 : codec_(codec),
307 callback_(NULL), 307 callback_(NULL),
308 codec_thread_(new Thread()), 308 codec_thread_(new Thread()),
309 j_media_codec_video_encoder_class_( 309 j_media_codec_video_encoder_class_(
310 jni, 310 jni,
311 FindClass(jni, "org/webrtc/MediaCodecVideoEncoder")), 311 FindClass(jni, "org/webrtc/MediaCodecVideoEncoder")),
312 j_media_codec_video_encoder_( 312 j_media_codec_video_encoder_(
313 jni, 313 jni,
314 jni->NewObject(*j_media_codec_video_encoder_class_, 314 jni->NewObject(*j_media_codec_video_encoder_class_,
315 GetMethodID(jni, 315 GetMethodID(jni,
316 *j_media_codec_video_encoder_class_, 316 *j_media_codec_video_encoder_class_,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 384
385 int32_t MediaCodecVideoEncoder::InitEncode( 385 int32_t MediaCodecVideoEncoder::InitEncode(
386 const webrtc::VideoCodec* codec_settings, 386 const webrtc::VideoCodec* codec_settings,
387 int32_t /* number_of_cores */, 387 int32_t /* number_of_cores */,
388 size_t /* max_payload_size */) { 388 size_t /* max_payload_size */) {
389 if (codec_settings == NULL) { 389 if (codec_settings == NULL) {
390 ALOGE << "NULL VideoCodec instance"; 390 ALOGE << "NULL VideoCodec instance";
391 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 391 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
392 } 392 }
393 // Factory should guard against other codecs being used with us. 393 // Factory should guard against other codecs being used with us.
394 RTC_CHECK(codec_settings->codecType == codecType_) 394 const VideoCodecType codec_type = cricket::CodecTypeFromName(codec_.name);
395 RTC_CHECK(codec_settings->codecType == codec_type)
395 << "Unsupported codec " << codec_settings->codecType << " for " 396 << "Unsupported codec " << codec_settings->codecType << " for "
396 << codecType_; 397 << codec_type;
397 if (sw_fallback_required_) { 398 if (sw_fallback_required_) {
398 return WEBRTC_VIDEO_CODEC_OK; 399 return WEBRTC_VIDEO_CODEC_OK;
399 } 400 }
400 codec_mode_ = codec_settings->mode; 401 codec_mode_ = codec_settings->mode;
401 int init_width = codec_settings->width; 402 int init_width = codec_settings->width;
402 int init_height = codec_settings->height; 403 int init_height = codec_settings->height;
403 // Scaling is disabled for VP9, but optionally enabled for VP8. 404 // Scaling is disabled for VP9, but optionally enabled for VP8.
404 // TODO(pbos): Extract automaticResizeOn out of VP8 settings. 405 // TODO(pbos): Extract automaticResizeOn out of VP8 settings.
405 scale_ = false; 406 scale_ = false;
406 if (codecType_ == kVideoCodecVP8) { 407 if (codec_type == kVideoCodecVP8) {
407 scale_ = codec_settings->codecSpecific.VP8.automaticResizeOn; 408 scale_ = codec_settings->codecSpecific.VP8.automaticResizeOn;
408 } else if (codecType_ != kVideoCodecVP9) { 409 } else if (codec_type != kVideoCodecVP9) {
409 scale_ = true; 410 scale_ = true;
410 } 411 }
411 412
412 ALOGD << "InitEncode request: " << init_width << " x " << init_height; 413 ALOGD << "InitEncode request: " << init_width << " x " << init_height;
413 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); 414 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled");
414 415
415 if (scale_) { 416 if (scale_) {
416 if (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecH264) { 417 if (codec_type == kVideoCodecVP8 || codec_type == kVideoCodecH264) {
417 quality_scaler_.Init(codecType_, codec_settings->startBitrate, 418 quality_scaler_.Init(codec_type, codec_settings->startBitrate,
418 codec_settings->width, codec_settings->height, 419 codec_settings->width, codec_settings->height,
419 codec_settings->maxFramerate); 420 codec_settings->maxFramerate);
420 } else { 421 } else {
421 // When adding codec support to additional hardware codecs, also configure 422 // When adding codec support to additional hardware codecs, also configure
422 // their QP thresholds for scaling. 423 // their QP thresholds for scaling.
423 RTC_NOTREACHED() << "Unsupported codec without configured QP thresholds."; 424 RTC_NOTREACHED() << "Unsupported codec without configured QP thresholds.";
424 scale_ = false; 425 scale_ = false;
425 } 426 }
426 QualityScaler::Resolution res = quality_scaler_.GetScaledResolution(); 427 QualityScaler::Resolution res = quality_scaler_.GetScaledResolution();
427 init_width = res.width; 428 init_width = res.width;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 WEBRTC_VIDEO_CODEC_OK) { 514 WEBRTC_VIDEO_CODEC_OK) {
514 ALOGE << "Initializing encoder failed during reset."; 515 ALOGE << "Initializing encoder failed during reset.";
515 return false; 516 return false;
516 } 517 }
517 return true; 518 return true;
518 } 519 }
519 520
520 bool MediaCodecVideoEncoder::ProcessHWErrorOnCodecThread( 521 bool MediaCodecVideoEncoder::ProcessHWErrorOnCodecThread(
521 bool reset_if_fallback_unavailable) { 522 bool reset_if_fallback_unavailable) {
522 ALOGE << "ProcessHWErrorOnCodecThread"; 523 ALOGE << "ProcessHWErrorOnCodecThread";
523 if (VideoEncoder::IsSupportedSoftware( 524 if (VideoEncoder::IsSupportedSoftware(codec_)) {
524 VideoEncoder::CodecToEncoderType(codecType_))) {
525 ALOGE << "Fallback to SW encoder."; 525 ALOGE << "Fallback to SW encoder.";
526 sw_fallback_required_ = true; 526 sw_fallback_required_ = true;
527 return false; 527 return false;
528 } else if (reset_if_fallback_unavailable) { 528 } else if (reset_if_fallback_unavailable) {
529 ALOGE << "Reset encoder."; 529 ALOGE << "Reset encoder.";
530 return ResetCodecOnCodecThread(); 530 return ResetCodecOnCodecThread();
531 } 531 }
532 return false; 532 return false;
533 } 533 }
534 534
535 int32_t MediaCodecVideoEncoder::ProcessHWErrorOnEncodeOnCodecThread() { 535 int32_t MediaCodecVideoEncoder::ProcessHWErrorOnEncodeOnCodecThread() {
536 ProcessHWErrorOnCodecThread(true /* reset_if_fallback_unavailable */); 536 ProcessHWErrorOnCodecThread(true /* reset_if_fallback_unavailable */);
537 return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE 537 return sw_fallback_required_ ? WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE
538 : WEBRTC_VIDEO_CODEC_ERROR; 538 : WEBRTC_VIDEO_CODEC_ERROR;
539 } 539 }
540 540
541 int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread( 541 int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread(
542 int width, int height, int kbps, int fps, bool use_surface) { 542 int width, int height, int kbps, int fps, bool use_surface) {
543 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread()); 543 RTC_DCHECK(codec_thread_checker_.CalledOnValidThread());
544 if (sw_fallback_required_) { 544 if (sw_fallback_required_) {
545 return WEBRTC_VIDEO_CODEC_OK; 545 return WEBRTC_VIDEO_CODEC_OK;
546 } 546 }
547 RTC_CHECK(!use_surface || egl_context_ != nullptr) << "EGL context not set."; 547 RTC_CHECK(!use_surface || egl_context_ != nullptr) << "EGL context not set.";
548 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 548 JNIEnv* jni = AttachCurrentThreadIfNeeded();
549 ScopedLocalRefFrame local_ref_frame(jni); 549 ScopedLocalRefFrame local_ref_frame(jni);
550 550
551 ALOGD << "InitEncodeOnCodecThread Type: " << (int)codecType_ << ", " << 551 const VideoCodecType codec_type = cricket::CodecTypeFromName(codec_.name);
552 width << " x " << height << ". Bitrate: " << kbps << 552 ALOGD << "InitEncodeOnCodecThread Type: " << (int)codec_type << ", " << width
553 " kbps. Fps: " << fps; 553 << " x " << height << ". Bitrate: " << kbps << " kbps. Fps: " << fps;
554 if (kbps == 0) { 554 if (kbps == 0) {
555 kbps = last_set_bitrate_kbps_; 555 kbps = last_set_bitrate_kbps_;
556 } 556 }
557 if (fps == 0) { 557 if (fps == 0) {
558 fps = MAX_VIDEO_FPS; 558 fps = MAX_VIDEO_FPS;
559 } 559 }
560 560
561 width_ = width; 561 width_ = width;
562 height_ = height; 562 height_ = height;
563 last_set_bitrate_kbps_ = kbps; 563 last_set_bitrate_kbps_ = kbps;
(...skipping 18 matching lines...) Expand all
582 use_surface_ = use_surface; 582 use_surface_ = use_surface;
583 picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF; 583 picture_id_ = static_cast<uint16_t>(rand()) & 0x7FFF;
584 gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1); 584 gof_.SetGofInfoVP9(webrtc::TemporalStructureMode::kTemporalStructureMode1);
585 tl0_pic_idx_ = static_cast<uint8_t>(rand()); 585 tl0_pic_idx_ = static_cast<uint8_t>(rand());
586 gof_idx_ = 0; 586 gof_idx_ = 0;
587 last_frame_received_ms_ = -1; 587 last_frame_received_ms_ = -1;
588 frames_received_since_last_key_ = kMinKeyFrameInterval; 588 frames_received_since_last_key_ = kMinKeyFrameInterval;
589 589
590 // We enforce no extra stride/padding in the format creation step. 590 // We enforce no extra stride/padding in the format creation step.
591 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName( 591 jobject j_video_codec_enum = JavaEnumFromIndexAndClassName(
592 jni, "MediaCodecVideoEncoder$VideoCodecType", codecType_); 592 jni, "MediaCodecVideoEncoder$VideoCodecType", codec_type);
593 const bool encode_status = jni->CallBooleanMethod( 593 const bool encode_status = jni->CallBooleanMethod(
594 *j_media_codec_video_encoder_, j_init_encode_method_, 594 *j_media_codec_video_encoder_, j_init_encode_method_,
595 j_video_codec_enum, width, height, kbps, fps, 595 j_video_codec_enum, width, height, kbps, fps,
596 (use_surface ? egl_context_ : nullptr)); 596 (use_surface ? egl_context_ : nullptr));
597 if (!encode_status) { 597 if (!encode_status) {
598 ALOGE << "Failed to configure encoder."; 598 ALOGE << "Failed to configure encoder.";
599 ProcessHWErrorOnCodecThread(false /* reset_if_fallback_unavailable */); 599 ProcessHWErrorOnCodecThread(false /* reset_if_fallback_unavailable */);
600 return WEBRTC_VIDEO_CODEC_ERROR; 600 return WEBRTC_VIDEO_CODEC_ERROR;
601 } 601 }
602 if (CheckException(jni)) { 602 if (CheckException(jni)) {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 size_t payload_size = jni->GetDirectBufferCapacity(j_output_buffer); 1056 size_t payload_size = jni->GetDirectBufferCapacity(j_output_buffer);
1057 uint8_t* payload = reinterpret_cast<uint8_t*>( 1057 uint8_t* payload = reinterpret_cast<uint8_t*>(
1058 jni->GetDirectBufferAddress(j_output_buffer)); 1058 jni->GetDirectBufferAddress(j_output_buffer));
1059 if (CheckException(jni)) { 1059 if (CheckException(jni)) {
1060 ALOGE << "Exception in get direct buffer address."; 1060 ALOGE << "Exception in get direct buffer address.";
1061 ProcessHWErrorOnCodecThread(true /* reset_if_fallback_unavailable */); 1061 ProcessHWErrorOnCodecThread(true /* reset_if_fallback_unavailable */);
1062 return WEBRTC_VIDEO_CODEC_ERROR; 1062 return WEBRTC_VIDEO_CODEC_ERROR;
1063 } 1063 }
1064 1064
1065 // Callback - return encoded frame. 1065 // Callback - return encoded frame.
1066 const VideoCodecType codec_type = cricket::CodecTypeFromName(codec_.name);
1066 int32_t callback_status = 0; 1067 int32_t callback_status = 0;
1067 if (callback_) { 1068 if (callback_) {
1068 std::unique_ptr<webrtc::EncodedImage> image( 1069 std::unique_ptr<webrtc::EncodedImage> image(
1069 new webrtc::EncodedImage(payload, payload_size, payload_size)); 1070 new webrtc::EncodedImage(payload, payload_size, payload_size));
1070 image->_encodedWidth = width_; 1071 image->_encodedWidth = width_;
1071 image->_encodedHeight = height_; 1072 image->_encodedHeight = height_;
1072 image->_timeStamp = output_timestamp_; 1073 image->_timeStamp = output_timestamp_;
1073 image->capture_time_ms_ = output_render_time_ms_; 1074 image->capture_time_ms_ = output_render_time_ms_;
1074 image->rotation_ = output_rotation_; 1075 image->rotation_ = output_rotation_;
1075 image->_frameType = 1076 image->_frameType =
1076 (key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta); 1077 (key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta);
1077 image->_completeFrame = true; 1078 image->_completeFrame = true;
1078 image->adapt_reason_.quality_resolution_downscales = 1079 image->adapt_reason_.quality_resolution_downscales =
1079 scale_ ? quality_scaler_.downscale_shift() : -1; 1080 scale_ ? quality_scaler_.downscale_shift() : -1;
1080 1081
1081 webrtc::CodecSpecificInfo info; 1082 webrtc::CodecSpecificInfo info;
1082 memset(&info, 0, sizeof(info)); 1083 memset(&info, 0, sizeof(info));
1083 info.codecType = codecType_; 1084 info.codecType = codec_type;
1084 if (codecType_ == kVideoCodecVP8) { 1085 if (codec_type == kVideoCodecVP8) {
1085 info.codecSpecific.VP8.pictureId = picture_id_; 1086 info.codecSpecific.VP8.pictureId = picture_id_;
1086 info.codecSpecific.VP8.nonReference = false; 1087 info.codecSpecific.VP8.nonReference = false;
1087 info.codecSpecific.VP8.simulcastIdx = 0; 1088 info.codecSpecific.VP8.simulcastIdx = 0;
1088 info.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx; 1089 info.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx;
1089 info.codecSpecific.VP8.layerSync = false; 1090 info.codecSpecific.VP8.layerSync = false;
1090 info.codecSpecific.VP8.tl0PicIdx = webrtc::kNoTl0PicIdx; 1091 info.codecSpecific.VP8.tl0PicIdx = webrtc::kNoTl0PicIdx;
1091 info.codecSpecific.VP8.keyIdx = webrtc::kNoKeyIdx; 1092 info.codecSpecific.VP8.keyIdx = webrtc::kNoKeyIdx;
1092 } else if (codecType_ == kVideoCodecVP9) { 1093 } else if (codec_type == kVideoCodecVP9) {
1093 if (key_frame) { 1094 if (key_frame) {
1094 gof_idx_ = 0; 1095 gof_idx_ = 0;
1095 } 1096 }
1096 info.codecSpecific.VP9.picture_id = picture_id_; 1097 info.codecSpecific.VP9.picture_id = picture_id_;
1097 info.codecSpecific.VP9.inter_pic_predicted = key_frame ? false : true; 1098 info.codecSpecific.VP9.inter_pic_predicted = key_frame ? false : true;
1098 info.codecSpecific.VP9.flexible_mode = false; 1099 info.codecSpecific.VP9.flexible_mode = false;
1099 info.codecSpecific.VP9.ss_data_available = key_frame ? true : false; 1100 info.codecSpecific.VP9.ss_data_available = key_frame ? true : false;
1100 info.codecSpecific.VP9.tl0_pic_idx = tl0_pic_idx_++; 1101 info.codecSpecific.VP9.tl0_pic_idx = tl0_pic_idx_++;
1101 info.codecSpecific.VP9.temporal_idx = webrtc::kNoTemporalIdx; 1102 info.codecSpecific.VP9.temporal_idx = webrtc::kNoTemporalIdx;
1102 info.codecSpecific.VP9.spatial_idx = webrtc::kNoSpatialIdx; 1103 info.codecSpecific.VP9.spatial_idx = webrtc::kNoSpatialIdx;
1103 info.codecSpecific.VP9.temporal_up_switch = true; 1104 info.codecSpecific.VP9.temporal_up_switch = true;
1104 info.codecSpecific.VP9.inter_layer_predicted = false; 1105 info.codecSpecific.VP9.inter_layer_predicted = false;
1105 info.codecSpecific.VP9.gof_idx = 1106 info.codecSpecific.VP9.gof_idx =
1106 static_cast<uint8_t>(gof_idx_++ % gof_.num_frames_in_gof); 1107 static_cast<uint8_t>(gof_idx_++ % gof_.num_frames_in_gof);
1107 info.codecSpecific.VP9.num_spatial_layers = 1; 1108 info.codecSpecific.VP9.num_spatial_layers = 1;
1108 info.codecSpecific.VP9.spatial_layer_resolution_present = false; 1109 info.codecSpecific.VP9.spatial_layer_resolution_present = false;
1109 if (info.codecSpecific.VP9.ss_data_available) { 1110 if (info.codecSpecific.VP9.ss_data_available) {
1110 info.codecSpecific.VP9.spatial_layer_resolution_present = true; 1111 info.codecSpecific.VP9.spatial_layer_resolution_present = true;
1111 info.codecSpecific.VP9.width[0] = width_; 1112 info.codecSpecific.VP9.width[0] = width_;
1112 info.codecSpecific.VP9.height[0] = height_; 1113 info.codecSpecific.VP9.height[0] = height_;
1113 info.codecSpecific.VP9.gof.CopyGofInfoVP9(gof_); 1114 info.codecSpecific.VP9.gof.CopyGofInfoVP9(gof_);
1114 } 1115 }
1115 } 1116 }
1116 picture_id_ = (picture_id_ + 1) & 0x7FFF; 1117 picture_id_ = (picture_id_ + 1) & 0x7FFF;
1117 1118
1118 // Generate a header describing a single fragment. 1119 // Generate a header describing a single fragment.
1119 webrtc::RTPFragmentationHeader header; 1120 webrtc::RTPFragmentationHeader header;
1120 memset(&header, 0, sizeof(header)); 1121 memset(&header, 0, sizeof(header));
1121 if (codecType_ == kVideoCodecVP8 || codecType_ == kVideoCodecVP9) { 1122 if (codec_type == kVideoCodecVP8 || codec_type == kVideoCodecVP9) {
1122 header.VerifyAndAllocateFragmentationHeader(1); 1123 header.VerifyAndAllocateFragmentationHeader(1);
1123 header.fragmentationOffset[0] = 0; 1124 header.fragmentationOffset[0] = 0;
1124 header.fragmentationLength[0] = image->_length; 1125 header.fragmentationLength[0] = image->_length;
1125 header.fragmentationPlType[0] = 0; 1126 header.fragmentationPlType[0] = 0;
1126 header.fragmentationTimeDiff[0] = 0; 1127 header.fragmentationTimeDiff[0] = 0;
1127 if (codecType_ == kVideoCodecVP8 && scale_) { 1128 if (codec_type == kVideoCodecVP8 && scale_) {
1128 int qp; 1129 int qp;
1129 if (webrtc::vp8::GetQp(payload, payload_size, &qp)) { 1130 if (webrtc::vp8::GetQp(payload, payload_size, &qp)) {
1130 current_acc_qp_ += qp; 1131 current_acc_qp_ += qp;
1131 quality_scaler_.ReportQP(qp); 1132 quality_scaler_.ReportQP(qp);
1132 image->qp_ = qp; 1133 image->qp_ = qp;
1133 } 1134 }
1134 } 1135 }
1135 } else if (codecType_ == kVideoCodecH264) { 1136 } else if (codec_type == kVideoCodecH264) {
1136 if (scale_) { 1137 if (scale_) {
1137 h264_bitstream_parser_.ParseBitstream(payload, payload_size); 1138 h264_bitstream_parser_.ParseBitstream(payload, payload_size);
1138 int qp; 1139 int qp;
1139 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) { 1140 if (h264_bitstream_parser_.GetLastSliceQp(&qp)) {
1140 current_acc_qp_ += qp; 1141 current_acc_qp_ += qp;
1141 quality_scaler_.ReportQP(qp); 1142 quality_scaler_.ReportQP(qp);
1142 } 1143 }
1143 } 1144 }
1144 // For H.264 search for start codes. 1145 // For H.264 search for start codes.
1145 int32_t scPositions[MAX_NALUS_PERFRAME + 1] = {}; 1146 int32_t scPositions[MAX_NALUS_PERFRAME + 1] = {};
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 } 1352 }
1352 1353
1353 webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder( 1354 webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder(
1354 const cricket::VideoCodec& codec) { 1355 const cricket::VideoCodec& codec) {
1355 if (supported_codecs_.empty()) { 1356 if (supported_codecs_.empty()) {
1356 ALOGW << "No HW video encoder for codec " << codec.name; 1357 ALOGW << "No HW video encoder for codec " << codec.name;
1357 return nullptr; 1358 return nullptr;
1358 } 1359 }
1359 if (IsCodecSupported(supported_codecs_, codec)) { 1360 if (IsCodecSupported(supported_codecs_, codec)) {
1360 ALOGD << "Create HW video encoder for " << codec.name; 1361 ALOGD << "Create HW video encoder for " << codec.name;
1361 const VideoCodecType type = cricket::CodecTypeFromName(codec.name); 1362 return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), codec,
1362 return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), type,
1363 egl_context_); 1363 egl_context_);
1364 } 1364 }
1365 ALOGW << "Can not find HW video encoder for type " << codec.name; 1365 ALOGW << "Can not find HW video encoder for type " << codec.name;
1366 return nullptr; 1366 return nullptr;
1367 } 1367 }
1368 1368
1369 const std::vector<cricket::VideoCodec>& 1369 const std::vector<cricket::VideoCodec>&
1370 MediaCodecVideoEncoderFactory::supported_codecs() const { 1370 MediaCodecVideoEncoderFactory::supported_codecs() const {
1371 return supported_codecs_; 1371 return supported_codecs_;
1372 } 1372 }
1373 1373
1374 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( 1374 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder(
1375 webrtc::VideoEncoder* encoder) { 1375 webrtc::VideoEncoder* encoder) {
1376 ALOGD << "Destroy video encoder."; 1376 ALOGD << "Destroy video encoder.";
1377 delete encoder; 1377 delete encoder;
1378 } 1378 }
1379 1379
1380 } // namespace webrtc_jni 1380 } // namespace webrtc_jni
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698