Bug Fix: Multiplex Codec Crash
This CL adds a lock to stashed_images_ in MultiplexEncoderAdapter. Without lock, it is possible that different threads acts on stashed_images_ simultaneously and leads to crash. Bug: webrtc:8965 Change-Id: I887861092d185c3bd6047eb529d8c1cf57fa4648 Reviewed-on: https://webrtc-review.googlesource.com/59260 Reviewed-by: Emircan Uysaler <emircan@webrtc.org> Commit-Queue: Qiang Chen <qiangchen@chromium.org> Cr-Commit-Position: refs/heads/master@{#22261}
This commit is contained in:
@ -20,6 +20,7 @@
|
|||||||
#include "api/video_codecs/video_encoder_factory.h"
|
#include "api/video_codecs/video_encoder_factory.h"
|
||||||
#include "modules/video_coding/codecs/multiplex/include/multiplex_encoded_image_packer.h"
|
#include "modules/video_coding/codecs/multiplex/include/multiplex_encoded_image_packer.h"
|
||||||
#include "modules/video_coding/include/video_codec_interface.h"
|
#include "modules/video_coding/include/video_codec_interface.h"
|
||||||
|
#include "rtc_base/criticalsection.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -66,13 +67,16 @@ class MultiplexEncoderAdapter : public VideoEncoder {
|
|||||||
std::vector<std::unique_ptr<AdapterEncodedImageCallback>> adapter_callbacks_;
|
std::vector<std::unique_ptr<AdapterEncodedImageCallback>> adapter_callbacks_;
|
||||||
EncodedImageCallback* encoded_complete_callback_;
|
EncodedImageCallback* encoded_complete_callback_;
|
||||||
|
|
||||||
std::map<uint32_t /* timestamp */, MultiplexImage> stashed_images_;
|
std::map<uint32_t /* timestamp */, MultiplexImage> stashed_images_
|
||||||
|
RTC_GUARDED_BY(crit_);
|
||||||
|
|
||||||
uint16_t picture_index_ = 0;
|
uint16_t picture_index_ = 0;
|
||||||
std::vector<uint8_t> multiplex_dummy_planes_;
|
std::vector<uint8_t> multiplex_dummy_planes_;
|
||||||
|
|
||||||
int key_frame_interval_;
|
int key_frame_interval_;
|
||||||
EncodedImage combined_image_;
|
EncodedImage combined_image_;
|
||||||
|
|
||||||
|
rtc::CriticalSection crit_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -122,10 +122,14 @@ int MultiplexEncoderAdapter::Encode(
|
|||||||
}
|
}
|
||||||
const bool has_alpha = input_image.video_frame_buffer()->type() ==
|
const bool has_alpha = input_image.video_frame_buffer()->type() ==
|
||||||
VideoFrameBuffer::Type::kI420A;
|
VideoFrameBuffer::Type::kI420A;
|
||||||
stashed_images_.emplace(
|
{
|
||||||
std::piecewise_construct, std::forward_as_tuple(input_image.timestamp()),
|
rtc::CritScope cs(&crit_);
|
||||||
std::forward_as_tuple(picture_index_,
|
stashed_images_.emplace(
|
||||||
has_alpha ? kAlphaCodecStreams : 1));
|
std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(input_image.timestamp()),
|
||||||
|
std::forward_as_tuple(picture_index_,
|
||||||
|
has_alpha ? kAlphaCodecStreams : 1));
|
||||||
|
}
|
||||||
|
|
||||||
++picture_index_;
|
++picture_index_;
|
||||||
|
|
||||||
@ -192,6 +196,7 @@ int MultiplexEncoderAdapter::Release() {
|
|||||||
}
|
}
|
||||||
encoders_.clear();
|
encoders_.clear();
|
||||||
adapter_callbacks_.clear();
|
adapter_callbacks_.clear();
|
||||||
|
rtc::CritScope cs(&crit_);
|
||||||
for (auto& stashed_image : stashed_images_) {
|
for (auto& stashed_image : stashed_images_) {
|
||||||
for (auto& image_component : stashed_image.second.image_components) {
|
for (auto& image_component : stashed_image.second.image_components) {
|
||||||
delete[] image_component.encoded_image._buffer;
|
delete[] image_component.encoded_image._buffer;
|
||||||
@ -214,12 +219,6 @@ EncodedImageCallback::Result MultiplexEncoderAdapter::OnEncodedImage(
|
|||||||
const EncodedImage& encodedImage,
|
const EncodedImage& encodedImage,
|
||||||
const CodecSpecificInfo* codecSpecificInfo,
|
const CodecSpecificInfo* codecSpecificInfo,
|
||||||
const RTPFragmentationHeader* fragmentation) {
|
const RTPFragmentationHeader* fragmentation) {
|
||||||
const auto& stashed_image_itr = stashed_images_.find(encodedImage._timeStamp);
|
|
||||||
const auto& stashed_image_next_itr = std::next(stashed_image_itr, 1);
|
|
||||||
RTC_DCHECK(stashed_image_itr != stashed_images_.end());
|
|
||||||
MultiplexImage& stashed_image = stashed_image_itr->second;
|
|
||||||
const uint8_t frame_count = stashed_image.component_count;
|
|
||||||
|
|
||||||
// Save the image
|
// Save the image
|
||||||
MultiplexImageComponent image_component;
|
MultiplexImageComponent image_component;
|
||||||
image_component.component_index = stream_idx;
|
image_component.component_index = stream_idx;
|
||||||
@ -230,6 +229,13 @@ EncodedImageCallback::Result MultiplexEncoderAdapter::OnEncodedImage(
|
|||||||
std::memcpy(image_component.encoded_image._buffer, encodedImage._buffer,
|
std::memcpy(image_component.encoded_image._buffer, encodedImage._buffer,
|
||||||
encodedImage._length);
|
encodedImage._length);
|
||||||
|
|
||||||
|
rtc::CritScope cs(&crit_);
|
||||||
|
const auto& stashed_image_itr = stashed_images_.find(encodedImage._timeStamp);
|
||||||
|
const auto& stashed_image_next_itr = std::next(stashed_image_itr, 1);
|
||||||
|
RTC_DCHECK(stashed_image_itr != stashed_images_.end());
|
||||||
|
MultiplexImage& stashed_image = stashed_image_itr->second;
|
||||||
|
const uint8_t frame_count = stashed_image.component_count;
|
||||||
|
|
||||||
stashed_image.image_components.push_back(image_component);
|
stashed_image.image_components.push_back(image_component);
|
||||||
|
|
||||||
if (stashed_image.image_components.size() == frame_count) {
|
if (stashed_image.image_components.size() == frame_count) {
|
||||||
|
|||||||
Reference in New Issue
Block a user