Change jni VideoEncoderWrapper to not use the encoder task queue

If the task to call OnEncodedImage is posted to the encoder task queue
just after VideoStreamEncoder::Stop post the task to release the
encoder, the destruction sequence of java HardwareVideoEncoder
deadlocks in outputBuffersBusyCount.waitForZero();

Encoders are generally allowed to call OnEncodedImage on any internal
encoder thread, so posting to the encoder task queue seems unnecessary.

Bug: webrtc:9378
Change-Id: Iee14f151d9efdc5ab348f9c86069fdb762e6a0dc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161447
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30035}
This commit is contained in:
Niels Möller
2019-12-06 15:51:29 +01:00
committed by Commit Bot
parent dfbfb46062
commit 5b030cabcc
2 changed files with 42 additions and 61 deletions

View File

@ -50,10 +50,6 @@ int VideoEncoderWrapper::InitEncode(const VideoCodec* codec_settings,
capabilities_ = settings.capabilities; capabilities_ = settings.capabilities;
number_of_cores_ = settings.number_of_cores; number_of_cores_ = settings.number_of_cores;
num_resets_ = 0; num_resets_ = 0;
{
rtc::CritScope lock(&encoder_queue_crit_);
encoder_queue_ = TaskQueueBase::Current();
}
return InitEncodeInternal(jni); return InitEncodeInternal(jni);
} }
@ -118,10 +114,6 @@ int32_t VideoEncoderWrapper::Release() {
RTC_LOG(LS_INFO) << "release: " << status; RTC_LOG(LS_INFO) << "release: " << status;
frame_extra_infos_.clear(); frame_extra_infos_.clear();
initialized_ = false; initialized_ = false;
{
rtc::CritScope lock(&encoder_queue_crit_);
encoder_queue_ = nullptr;
}
return status; return status;
} }
@ -256,10 +248,6 @@ void VideoEncoderWrapper::OnEncodedFrame(
int64_t capture_time_ns = int64_t capture_time_ns =
GetJavaEncodedImageCaptureTimeNs(jni, j_encoded_image); GetJavaEncodedImageCaptureTimeNs(jni, j_encoded_image);
{
rtc::CritScope lock(&encoder_queue_crit_);
if (encoder_queue_ != nullptr) {
encoder_queue_->PostTask(ToQueuedTask([this, frame, capture_time_ns]() {
// Encoded frames are delivered in the order received, but some of them // Encoded frames are delivered in the order received, but some of them
// may be dropped, so remove records of frames older than the current // may be dropped, so remove records of frames older than the current
// one. // one.
@ -294,8 +282,7 @@ void VideoEncoderWrapper::OnEncodedFrame(
EncodedImage frame_copy = frame; EncodedImage frame_copy = frame;
frame_copy.SetTimestamp(frame_extra_info.timestamp_rtp); frame_copy.SetTimestamp(frame_extra_info.timestamp_rtp);
frame_copy.capture_time_ms_ = frame_copy.capture_time_ms_ = capture_time_ns / rtc::kNumNanosecsPerMillisec;
capture_time_ns / rtc::kNumNanosecsPerMillisec;
RTPFragmentationHeader header = ParseFragmentationHeader(frame); RTPFragmentationHeader header = ParseFragmentationHeader(frame);
if (frame_copy.qp_ < 0) if (frame_copy.qp_ < 0)
@ -304,9 +291,6 @@ void VideoEncoderWrapper::OnEncodedFrame(
CodecSpecificInfo info(ParseCodecSpecificInfo(frame)); CodecSpecificInfo info(ParseCodecSpecificInfo(frame));
callback_->OnEncodedImage(frame_copy, &info, &header); callback_->OnEncodedImage(frame_copy, &info, &header);
}));
}
}
} }
int32_t VideoEncoderWrapper::HandleReturnCode(JNIEnv* jni, int32_t VideoEncoderWrapper::HandleReturnCode(JNIEnv* jni,

View File

@ -17,7 +17,6 @@
#include <vector> #include <vector>
#include "absl/types/optional.h" #include "absl/types/optional.h"
#include "api/task_queue/task_queue_base.h"
#include "api/video_codecs/video_encoder.h" #include "api/video_codecs/video_encoder.h"
#include "common_video/h264/h264_bitstream_parser.h" #include "common_video/h264/h264_bitstream_parser.h"
#include "modules/video_coding/codecs/vp9/include/vp9_globals.h" #include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
@ -84,8 +83,6 @@ class VideoEncoderWrapper : public VideoEncoder {
const ScopedJavaGlobalRef<jobject> encoder_; const ScopedJavaGlobalRef<jobject> encoder_;
const ScopedJavaGlobalRef<jclass> int_array_class_; const ScopedJavaGlobalRef<jclass> int_array_class_;
rtc::CriticalSection encoder_queue_crit_;
TaskQueueBase* encoder_queue_ RTC_GUARDED_BY(encoder_queue_crit_);
std::deque<FrameExtraInfo> frame_extra_infos_; std::deque<FrameExtraInfo> frame_extra_infos_;
EncodedImageCallback* callback_; EncodedImageCallback* callback_;
bool initialized_; bool initialized_;