| OLD | NEW |
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 } | 280 } |
| 281 | 281 |
| 282 int32_t MediaCodecVideoEncoder::InitEncode( | 282 int32_t MediaCodecVideoEncoder::InitEncode( |
| 283 const webrtc::VideoCodec* codec_settings, | 283 const webrtc::VideoCodec* codec_settings, |
| 284 int32_t /* number_of_cores */, | 284 int32_t /* number_of_cores */, |
| 285 size_t /* max_payload_size */) { | 285 size_t /* max_payload_size */) { |
| 286 const int kMinWidth = 320; | 286 const int kMinWidth = 320; |
| 287 const int kMinHeight = 180; | 287 const int kMinHeight = 180; |
| 288 const int kLowQpThresholdDenominator = 3; | 288 const int kLowQpThresholdDenominator = 3; |
| 289 if (codec_settings == NULL) { | 289 if (codec_settings == NULL) { |
| 290 ALOGE("NULL VideoCodec instance"); | 290 ALOGE << "NULL VideoCodec instance"; |
| 291 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 291 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 292 } | 292 } |
| 293 // Factory should guard against other codecs being used with us. | 293 // Factory should guard against other codecs being used with us. |
| 294 RTC_CHECK(codec_settings->codecType == codecType_) | 294 RTC_CHECK(codec_settings->codecType == codecType_) |
| 295 << "Unsupported codec " << codec_settings->codecType << " for " | 295 << "Unsupported codec " << codec_settings->codecType << " for " |
| 296 << codecType_; | 296 << codecType_; |
| 297 | 297 |
| 298 ALOGD("InitEncode request"); | 298 ALOGD << "InitEncode request"; |
| 299 scale_ = webrtc::field_trial::FindFullName( | 299 scale_ = webrtc::field_trial::FindFullName( |
| 300 "WebRTC-MediaCodecVideoEncoder-AutomaticResize") == "Enabled"; | 300 "WebRTC-MediaCodecVideoEncoder-AutomaticResize") == "Enabled"; |
| 301 ALOGD("Automatic resize: %s", scale_ ? "enabled" : "disabled"); | 301 ALOGD << "Encoder automatic resize " << (scale_ ? "enabled" : "disabled"); |
| 302 if (scale_) { | 302 if (scale_) { |
| 303 if (codecType_ == kVideoCodecVP8) { | 303 if (codecType_ == kVideoCodecVP8) { |
| 304 // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the | 304 // QP is obtained from VP8-bitstream for HW, so the QP corresponds to the |
| 305 // (internal) range: [0, 127]. And we cannot change QP_max in HW, so it is | 305 // (internal) range: [0, 127]. And we cannot change QP_max in HW, so it is |
| 306 // always = 127. Note that in SW, QP is that of the user-level range [0, | 306 // always = 127. Note that in SW, QP is that of the user-level range [0, |
| 307 // 63]. | 307 // 63]. |
| 308 const int kMaxQp = 127; | 308 const int kMaxQp = 127; |
| 309 // TODO(pbos): Investigate whether high-QP thresholds make sense for VP8. | 309 // TODO(pbos): Investigate whether high-QP thresholds make sense for VP8. |
| 310 // This effectively disables high QP as VP8 QP can't go above this | 310 // This effectively disables high QP as VP8 QP can't go above this |
| 311 // threshold. | 311 // threshold. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 | 345 |
| 346 int32_t MediaCodecVideoEncoder::RegisterEncodeCompleteCallback( | 346 int32_t MediaCodecVideoEncoder::RegisterEncodeCompleteCallback( |
| 347 webrtc::EncodedImageCallback* callback) { | 347 webrtc::EncodedImageCallback* callback) { |
| 348 return codec_thread_->Invoke<int32_t>( | 348 return codec_thread_->Invoke<int32_t>( |
| 349 Bind(&MediaCodecVideoEncoder::RegisterEncodeCompleteCallbackOnCodecThread, | 349 Bind(&MediaCodecVideoEncoder::RegisterEncodeCompleteCallbackOnCodecThread, |
| 350 this, | 350 this, |
| 351 callback)); | 351 callback)); |
| 352 } | 352 } |
| 353 | 353 |
| 354 int32_t MediaCodecVideoEncoder::Release() { | 354 int32_t MediaCodecVideoEncoder::Release() { |
| 355 ALOGD("EncoderRelease request"); | 355 ALOGD << "EncoderRelease request"; |
| 356 return codec_thread_->Invoke<int32_t>( | 356 return codec_thread_->Invoke<int32_t>( |
| 357 Bind(&MediaCodecVideoEncoder::ReleaseOnCodecThread, this)); | 357 Bind(&MediaCodecVideoEncoder::ReleaseOnCodecThread, this)); |
| 358 } | 358 } |
| 359 | 359 |
| 360 int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */, | 360 int32_t MediaCodecVideoEncoder::SetChannelParameters(uint32_t /* packet_loss */, |
| 361 int64_t /* rtt */) { | 361 int64_t /* rtt */) { |
| 362 return WEBRTC_VIDEO_CODEC_OK; | 362 return WEBRTC_VIDEO_CODEC_OK; |
| 363 } | 363 } |
| 364 | 364 |
| 365 int32_t MediaCodecVideoEncoder::SetRates(uint32_t new_bit_rate, | 365 int32_t MediaCodecVideoEncoder::SetRates(uint32_t new_bit_rate, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 393 DeliverPendingOutputs(jni); | 393 DeliverPendingOutputs(jni); |
| 394 codec_thread_->PostDelayed(kMediaCodecPollMs, this); | 394 codec_thread_->PostDelayed(kMediaCodecPollMs, this); |
| 395 } | 395 } |
| 396 | 396 |
| 397 void MediaCodecVideoEncoder::CheckOnCodecThread() { | 397 void MediaCodecVideoEncoder::CheckOnCodecThread() { |
| 398 RTC_CHECK(codec_thread_ == ThreadManager::Instance()->CurrentThread()) | 398 RTC_CHECK(codec_thread_ == ThreadManager::Instance()->CurrentThread()) |
| 399 << "Running on wrong thread!"; | 399 << "Running on wrong thread!"; |
| 400 } | 400 } |
| 401 | 401 |
| 402 void MediaCodecVideoEncoder::ResetCodec() { | 402 void MediaCodecVideoEncoder::ResetCodec() { |
| 403 ALOGE("ResetCodec"); | 403 ALOGE << "ResetCodec"; |
| 404 if (Release() != WEBRTC_VIDEO_CODEC_OK || | 404 if (Release() != WEBRTC_VIDEO_CODEC_OK || |
| 405 codec_thread_->Invoke<int32_t>(Bind( | 405 codec_thread_->Invoke<int32_t>(Bind( |
| 406 &MediaCodecVideoEncoder::InitEncodeOnCodecThread, this, | 406 &MediaCodecVideoEncoder::InitEncodeOnCodecThread, this, |
| 407 width_, height_, 0, 0)) != WEBRTC_VIDEO_CODEC_OK) { | 407 width_, height_, 0, 0)) != WEBRTC_VIDEO_CODEC_OK) { |
| 408 // TODO(fischman): wouldn't it be nice if there was a way to gracefully | 408 // TODO(fischman): wouldn't it be nice if there was a way to gracefully |
| 409 // degrade to a SW encoder at this point? There isn't one AFAICT :( | 409 // degrade to a SW encoder at this point? There isn't one AFAICT :( |
| 410 // https://code.google.com/p/webrtc/issues/detail?id=2920 | 410 // https://code.google.com/p/webrtc/issues/detail?id=2920 |
| 411 } | 411 } |
| 412 } | 412 } |
| 413 | 413 |
| 414 int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread( | 414 int32_t MediaCodecVideoEncoder::InitEncodeOnCodecThread( |
| 415 int width, int height, int kbps, int fps) { | 415 int width, int height, int kbps, int fps) { |
| 416 CheckOnCodecThread(); | 416 CheckOnCodecThread(); |
| 417 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 417 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
| 418 ScopedLocalRefFrame local_ref_frame(jni); | 418 ScopedLocalRefFrame local_ref_frame(jni); |
| 419 | 419 |
| 420 ALOGD("InitEncodeOnCodecThread Type: %d. %d x %d. Bitrate: %d kbps. Fps: %d", | 420 ALOGD << "InitEncodeOnCodecThread Type: " << (int)codecType_ << ", " << |
| 421 (int)codecType_, width, height, kbps, fps); | 421 width << " x " << height << ". Bitrate: " << kbps << |
| 422 " kbps. Fps: " << fps; |
| 422 if (kbps == 0) { | 423 if (kbps == 0) { |
| 423 kbps = last_set_bitrate_kbps_; | 424 kbps = last_set_bitrate_kbps_; |
| 424 } | 425 } |
| 425 if (fps == 0) { | 426 if (fps == 0) { |
| 426 fps = last_set_fps_; | 427 fps = last_set_fps_; |
| 427 } | 428 } |
| 428 | 429 |
| 429 width_ = width; | 430 width_ = width; |
| 430 height_ = height; | 431 height_ = height; |
| 431 last_set_bitrate_kbps_ = kbps; | 432 last_set_bitrate_kbps_ = kbps; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 | 523 |
| 523 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count"; | 524 RTC_CHECK(frame_types->size() == 1) << "Unexpected stream count"; |
| 524 // Check framerate before spatial resolution change. | 525 // Check framerate before spatial resolution change. |
| 525 if (scale_) | 526 if (scale_) |
| 526 quality_scaler_.OnEncodeFrame(frame); | 527 quality_scaler_.OnEncodeFrame(frame); |
| 527 | 528 |
| 528 const VideoFrame& input_frame = | 529 const VideoFrame& input_frame = |
| 529 scale_ ? quality_scaler_.GetScaledFrame(frame) : frame; | 530 scale_ ? quality_scaler_.GetScaledFrame(frame) : frame; |
| 530 | 531 |
| 531 if (input_frame.width() != width_ || input_frame.height() != height_) { | 532 if (input_frame.width() != width_ || input_frame.height() != height_) { |
| 532 ALOGD("Frame resolution change from %d x %d to %d x %d", | 533 ALOGD << "Frame resolution change from " << width_ << " x " << height_ << |
| 533 width_, height_, input_frame.width(), input_frame.height()); | 534 " to " << input_frame.width() << " x " << input_frame.height(); |
| 534 width_ = input_frame.width(); | 535 width_ = input_frame.width(); |
| 535 height_ = input_frame.height(); | 536 height_ = input_frame.height(); |
| 536 ResetCodec(); | 537 ResetCodec(); |
| 537 return WEBRTC_VIDEO_CODEC_OK; | 538 return WEBRTC_VIDEO_CODEC_OK; |
| 538 } | 539 } |
| 539 | 540 |
| 540 // Check if we accumulated too many frames in encoder input buffers | 541 // Check if we accumulated too many frames in encoder input buffers |
| 541 // or the encoder latency exceeds 70 ms and drop frame if so. | 542 // or the encoder latency exceeds 70 ms and drop frame if so. |
| 542 if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) { | 543 if (frames_in_queue_ > 0 && last_input_timestamp_ms_ >= 0) { |
| 543 int encoder_latency_ms = last_input_timestamp_ms_ - | 544 int encoder_latency_ms = last_input_timestamp_ms_ - |
| 544 last_output_timestamp_ms_; | 545 last_output_timestamp_ms_; |
| 545 if (frames_in_queue_ > 2 || encoder_latency_ms > 70) { | 546 if (frames_in_queue_ > 2 || encoder_latency_ms > 70) { |
| 546 ALOGD("Drop frame - encoder is behind by %d ms. Q size: %d", | 547 ALOGD << "Drop frame - encoder is behind by " << encoder_latency_ms << |
| 547 encoder_latency_ms, frames_in_queue_); | 548 " ms. Q size: " << frames_in_queue_; |
| 548 frames_dropped_++; | 549 frames_dropped_++; |
| 549 // Report dropped frame to quality_scaler_. | 550 // Report dropped frame to quality_scaler_. |
| 550 OnDroppedFrame(); | 551 OnDroppedFrame(); |
| 551 return WEBRTC_VIDEO_CODEC_OK; | 552 return WEBRTC_VIDEO_CODEC_OK; |
| 552 } | 553 } |
| 553 } | 554 } |
| 554 | 555 |
| 555 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, | 556 int j_input_buffer_index = jni->CallIntMethod(*j_media_codec_video_encoder_, |
| 556 j_dequeue_input_buffer_method_); | 557 j_dequeue_input_buffer_method_); |
| 557 CHECK_EXCEPTION(jni); | 558 CHECK_EXCEPTION(jni); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 callback_ = callback; | 617 callback_ = callback; |
| 617 return WEBRTC_VIDEO_CODEC_OK; | 618 return WEBRTC_VIDEO_CODEC_OK; |
| 618 } | 619 } |
| 619 | 620 |
| 620 int32_t MediaCodecVideoEncoder::ReleaseOnCodecThread() { | 621 int32_t MediaCodecVideoEncoder::ReleaseOnCodecThread() { |
| 621 if (!inited_) { | 622 if (!inited_) { |
| 622 return WEBRTC_VIDEO_CODEC_OK; | 623 return WEBRTC_VIDEO_CODEC_OK; |
| 623 } | 624 } |
| 624 CheckOnCodecThread(); | 625 CheckOnCodecThread(); |
| 625 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 626 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
| 626 ALOGD("EncoderReleaseOnCodecThread: Frames received: %d. Encoded: %d. " | 627 ALOGD << "EncoderReleaseOnCodecThread: Frames received: " << |
| 627 "Dropped: %d.", frames_received_, frames_encoded_, frames_dropped_); | 628 frames_received_ << ". Encoded: " << frames_encoded_ << |
| 629 ". Dropped: " << frames_dropped_; |
| 628 ScopedLocalRefFrame local_ref_frame(jni); | 630 ScopedLocalRefFrame local_ref_frame(jni); |
| 629 for (size_t i = 0; i < input_buffers_.size(); ++i) | 631 for (size_t i = 0; i < input_buffers_.size(); ++i) |
| 630 jni->DeleteGlobalRef(input_buffers_[i]); | 632 jni->DeleteGlobalRef(input_buffers_[i]); |
| 631 input_buffers_.clear(); | 633 input_buffers_.clear(); |
| 632 jni->CallVoidMethod(*j_media_codec_video_encoder_, j_release_method_); | 634 jni->CallVoidMethod(*j_media_codec_video_encoder_, j_release_method_); |
| 633 CHECK_EXCEPTION(jni); | 635 CHECK_EXCEPTION(jni); |
| 634 rtc::MessageQueueManager::Clear(this); | 636 rtc::MessageQueueManager::Clear(this); |
| 635 inited_ = false; | 637 inited_ = false; |
| 638 ALOGD << "EncoderReleaseOnCodecThread done."; |
| 636 return WEBRTC_VIDEO_CODEC_OK; | 639 return WEBRTC_VIDEO_CODEC_OK; |
| 637 } | 640 } |
| 638 | 641 |
| 639 int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate, | 642 int32_t MediaCodecVideoEncoder::SetRatesOnCodecThread(uint32_t new_bit_rate, |
| 640 uint32_t frame_rate) { | 643 uint32_t frame_rate) { |
| 641 CheckOnCodecThread(); | 644 CheckOnCodecThread(); |
| 642 if (last_set_bitrate_kbps_ == new_bit_rate && | 645 if (last_set_bitrate_kbps_ == new_bit_rate && |
| 643 last_set_fps_ == frame_rate) { | 646 last_set_fps_ == frame_rate) { |
| 644 return WEBRTC_VIDEO_CODEC_OK; | 647 return WEBRTC_VIDEO_CODEC_OK; |
| 645 } | 648 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 frame_encoding_time_ms); | 741 frame_encoding_time_ms); |
| 739 | 742 |
| 740 // Calculate and print encoding statistics - every 3 seconds. | 743 // Calculate and print encoding statistics - every 3 seconds. |
| 741 frames_encoded_++; | 744 frames_encoded_++; |
| 742 current_frames_++; | 745 current_frames_++; |
| 743 current_bytes_ += payload_size; | 746 current_bytes_ += payload_size; |
| 744 current_encoding_time_ms_ += frame_encoding_time_ms; | 747 current_encoding_time_ms_ += frame_encoding_time_ms; |
| 745 int statistic_time_ms = GetCurrentTimeMs() - start_time_ms_; | 748 int statistic_time_ms = GetCurrentTimeMs() - start_time_ms_; |
| 746 if (statistic_time_ms >= kMediaCodecStatisticsIntervalMs && | 749 if (statistic_time_ms >= kMediaCodecStatisticsIntervalMs && |
| 747 current_frames_ > 0) { | 750 current_frames_ > 0) { |
| 748 ALOGD("Encoder bitrate: %d, target: %d kbps, fps: %d," | 751 ALOGD << "Encoded frames: " << frames_encoded_ << ". Bitrate: " << |
| 749 " encTime: %d for last %d ms", | 752 (current_bytes_ * 8 / statistic_time_ms) << |
| 750 current_bytes_ * 8 / statistic_time_ms, | 753 ", target: " << last_set_bitrate_kbps_ << " kbps, fps: " << |
| 751 last_set_bitrate_kbps_, | 754 ((current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms) |
| 752 (current_frames_ * 1000 + statistic_time_ms / 2) / statistic_time_ms, | 755 << ", encTime: " << |
| 753 current_encoding_time_ms_ / current_frames_, statistic_time_ms); | 756 (current_encoding_time_ms_ / current_frames_) << " for last " << |
| 757 statistic_time_ms << " ms."; |
| 754 start_time_ms_ = GetCurrentTimeMs(); | 758 start_time_ms_ = GetCurrentTimeMs(); |
| 755 current_frames_ = 0; | 759 current_frames_ = 0; |
| 756 current_bytes_ = 0; | 760 current_bytes_ = 0; |
| 757 current_encoding_time_ms_ = 0; | 761 current_encoding_time_ms_ = 0; |
| 758 } | 762 } |
| 759 | 763 |
| 760 // Callback - return encoded frame. | 764 // Callback - return encoded frame. |
| 761 int32_t callback_status = 0; | 765 int32_t callback_status = 0; |
| 762 if (callback_) { | 766 if (callback_) { |
| 763 scoped_ptr<webrtc::EncodedImage> image( | 767 scoped_ptr<webrtc::EncodedImage> image( |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 int32_t naluPosition = NextNaluPosition( | 813 int32_t naluPosition = NextNaluPosition( |
| 810 payload + scPosition, payload_size - scPosition); | 814 payload + scPosition, payload_size - scPosition); |
| 811 if (naluPosition < 0) { | 815 if (naluPosition < 0) { |
| 812 break; | 816 break; |
| 813 } | 817 } |
| 814 scPosition += naluPosition; | 818 scPosition += naluPosition; |
| 815 scPositions[scPositionsLength++] = scPosition; | 819 scPositions[scPositionsLength++] = scPosition; |
| 816 scPosition += H264_SC_LENGTH; | 820 scPosition += H264_SC_LENGTH; |
| 817 } | 821 } |
| 818 if (scPositionsLength == 0) { | 822 if (scPositionsLength == 0) { |
| 819 ALOGE("Start code is not found!"); | 823 ALOGE << "Start code is not found!"; |
| 820 ALOGE("Data 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", | 824 ALOGE << "Data:" << image->_buffer[0] << " " << image->_buffer[1] |
| 821 image->_buffer[0], image->_buffer[1], image->_buffer[2], | 825 << " " << image->_buffer[2] << " " << image->_buffer[3] |
| 822 image->_buffer[3], image->_buffer[4], image->_buffer[5]); | 826 << " " << image->_buffer[4] << " " << image->_buffer[5]; |
| 823 ResetCodec(); | 827 ResetCodec(); |
| 824 return false; | 828 return false; |
| 825 } | 829 } |
| 826 scPositions[scPositionsLength] = payload_size; | 830 scPositions[scPositionsLength] = payload_size; |
| 827 header.VerifyAndAllocateFragmentationHeader(scPositionsLength); | 831 header.VerifyAndAllocateFragmentationHeader(scPositionsLength); |
| 828 for (size_t i = 0; i < scPositionsLength; i++) { | 832 for (size_t i = 0; i < scPositionsLength; i++) { |
| 829 header.fragmentationOffset[i] = scPositions[i] + H264_SC_LENGTH; | 833 header.fragmentationOffset[i] = scPositions[i] + H264_SC_LENGTH; |
| 830 header.fragmentationLength[i] = | 834 header.fragmentationLength[i] = |
| 831 scPositions[i + 1] - header.fragmentationOffset[i]; | 835 scPositions[i + 1] - header.fragmentationOffset[i]; |
| 832 header.fragmentationPlType[i] = 0; | 836 header.fragmentationPlType[i] = 0; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 906 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
| 903 ScopedLocalRefFrame local_ref_frame(jni); | 907 ScopedLocalRefFrame local_ref_frame(jni); |
| 904 jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder"); | 908 jclass j_encoder_class = FindClass(jni, "org/webrtc/MediaCodecVideoEncoder"); |
| 905 supported_codecs_.clear(); | 909 supported_codecs_.clear(); |
| 906 | 910 |
| 907 bool is_vp8_hw_supported = jni->CallStaticBooleanMethod( | 911 bool is_vp8_hw_supported = jni->CallStaticBooleanMethod( |
| 908 j_encoder_class, | 912 j_encoder_class, |
| 909 GetStaticMethodID(jni, j_encoder_class, "isVp8HwSupported", "()Z")); | 913 GetStaticMethodID(jni, j_encoder_class, "isVp8HwSupported", "()Z")); |
| 910 CHECK_EXCEPTION(jni); | 914 CHECK_EXCEPTION(jni); |
| 911 if (is_vp8_hw_supported) { | 915 if (is_vp8_hw_supported) { |
| 912 ALOGD("VP8 HW Encoder supported."); | 916 ALOGD << "VP8 HW Encoder supported."; |
| 913 supported_codecs_.push_back(VideoCodec(kVideoCodecVP8, "VP8", | 917 supported_codecs_.push_back(VideoCodec(kVideoCodecVP8, "VP8", |
| 914 MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT, MAX_VIDEO_FPS)); | 918 MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT, MAX_VIDEO_FPS)); |
| 915 } | 919 } |
| 916 | 920 |
| 917 bool is_h264_hw_supported = jni->CallStaticBooleanMethod( | 921 bool is_h264_hw_supported = jni->CallStaticBooleanMethod( |
| 918 j_encoder_class, | 922 j_encoder_class, |
| 919 GetStaticMethodID(jni, j_encoder_class, "isH264HwSupported", "()Z")); | 923 GetStaticMethodID(jni, j_encoder_class, "isH264HwSupported", "()Z")); |
| 920 CHECK_EXCEPTION(jni); | 924 CHECK_EXCEPTION(jni); |
| 921 if (is_h264_hw_supported) { | 925 if (is_h264_hw_supported) { |
| 922 ALOGD("H.264 HW Encoder supported."); | 926 ALOGD << "H.264 HW Encoder supported."; |
| 923 supported_codecs_.push_back(VideoCodec(kVideoCodecH264, "H264", | 927 supported_codecs_.push_back(VideoCodec(kVideoCodecH264, "H264", |
| 924 MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT, MAX_VIDEO_FPS)); | 928 MAX_VIDEO_WIDTH, MAX_VIDEO_HEIGHT, MAX_VIDEO_FPS)); |
| 925 } | 929 } |
| 926 } | 930 } |
| 927 | 931 |
| 928 MediaCodecVideoEncoderFactory::~MediaCodecVideoEncoderFactory() {} | 932 MediaCodecVideoEncoderFactory::~MediaCodecVideoEncoderFactory() {} |
| 929 | 933 |
| 930 webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder( | 934 webrtc::VideoEncoder* MediaCodecVideoEncoderFactory::CreateVideoEncoder( |
| 931 VideoCodecType type) { | 935 VideoCodecType type) { |
| 932 if (supported_codecs_.empty()) { | 936 if (supported_codecs_.empty()) { |
| 933 return NULL; | 937 return NULL; |
| 934 } | 938 } |
| 935 for (std::vector<VideoCodec>::const_iterator it = supported_codecs_.begin(); | 939 for (std::vector<VideoCodec>::const_iterator it = supported_codecs_.begin(); |
| 936 it != supported_codecs_.end(); ++it) { | 940 it != supported_codecs_.end(); ++it) { |
| 937 if (it->type == type) { | 941 if (it->type == type) { |
| 938 ALOGD("Create HW video encoder for type %d (%s).", | 942 ALOGD << "Create HW video encoder for type " << (int)type << |
| 939 (int)type, it->name.c_str()); | 943 " (" << it->name << ")."; |
| 940 return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), type); | 944 return new MediaCodecVideoEncoder(AttachCurrentThreadIfNeeded(), type); |
| 941 } | 945 } |
| 942 } | 946 } |
| 943 return NULL; | 947 return NULL; |
| 944 } | 948 } |
| 945 | 949 |
| 946 const std::vector<MediaCodecVideoEncoderFactory::VideoCodec>& | 950 const std::vector<MediaCodecVideoEncoderFactory::VideoCodec>& |
| 947 MediaCodecVideoEncoderFactory::codecs() const { | 951 MediaCodecVideoEncoderFactory::codecs() const { |
| 948 return supported_codecs_; | 952 return supported_codecs_; |
| 949 } | 953 } |
| 950 | 954 |
| 951 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( | 955 void MediaCodecVideoEncoderFactory::DestroyVideoEncoder( |
| 952 webrtc::VideoEncoder* encoder) { | 956 webrtc::VideoEncoder* encoder) { |
| 953 ALOGD("Destroy video encoder."); | 957 ALOGD << "Destroy video encoder."; |
| 954 delete encoder; | 958 delete encoder; |
| 955 } | 959 } |
| 956 | 960 |
| 957 } // namespace webrtc_jni | 961 } // namespace webrtc_jni |
| 958 | 962 |
| OLD | NEW |