Fixing some case-sensitive codec name comparisons.
As specified in RFC 4288, Section 4.2, and RFC 4855, Section 3, these names should be case-insensitive. They already were being treated as case-insensitive in some other places. This bug was resulting in either a crash or no decoded video, depending on the platform. BUG=webrtc:6439, webrtc:7027 Review-Url: https://codereview.webrtc.org/2782273002 Cr-Commit-Position: refs/heads/master@{#17515}
This commit is contained in:
parent
716d7ac5c1
commit
c964d0b3fa
@ -245,7 +245,7 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver,
|
|||||||
received_sdp_munger_ = munger;
|
received_sdp_munger_ = munger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Siimlar to the above, but this is run on SDP immediately after it's
|
// Similar to the above, but this is run on SDP immediately after it's
|
||||||
// generated.
|
// generated.
|
||||||
void SetGeneratedSdpMunger(
|
void SetGeneratedSdpMunger(
|
||||||
std::function<void(cricket::SessionDescription*)> munger) {
|
std::function<void(cricket::SessionDescription*)> munger) {
|
||||||
@ -2701,6 +2701,60 @@ TEST_F(PeerConnectionIntegrationTest, EndToEndConnectionTimeWithTurnTurnPair) {
|
|||||||
delete SetCalleePcWrapperAndReturnCurrent(nullptr);
|
delete SetCalleePcWrapperAndReturnCurrent(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that audio and video flow end-to-end when codec names don't use the
|
||||||
|
// expected casing, given that they're supposed to be case insensitive. To test
|
||||||
|
// this, all but one codec is removed from each media description, and its
|
||||||
|
// casing is changed.
|
||||||
|
//
|
||||||
|
// In the past, this has regressed and caused crashes/black video, due to the
|
||||||
|
// fact that code at some layers was doing case-insensitive comparisons and
|
||||||
|
// code at other layers was not.
|
||||||
|
TEST_F(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
|
||||||
|
ASSERT_TRUE(CreatePeerConnectionWrappers());
|
||||||
|
ConnectFakeSignaling();
|
||||||
|
caller()->AddAudioVideoMediaStream();
|
||||||
|
callee()->AddAudioVideoMediaStream();
|
||||||
|
|
||||||
|
// Remove all but one audio/video codec (opus and VP8), and change the
|
||||||
|
// casing of the caller's generated offer.
|
||||||
|
caller()->SetGeneratedSdpMunger([](cricket::SessionDescription* description) {
|
||||||
|
cricket::AudioContentDescription* audio =
|
||||||
|
GetFirstAudioContentDescription(description);
|
||||||
|
ASSERT_NE(nullptr, audio);
|
||||||
|
auto audio_codecs = audio->codecs();
|
||||||
|
audio_codecs.erase(std::remove_if(audio_codecs.begin(), audio_codecs.end(),
|
||||||
|
[](const cricket::AudioCodec& codec) {
|
||||||
|
return codec.name != "opus";
|
||||||
|
}),
|
||||||
|
audio_codecs.end());
|
||||||
|
ASSERT_EQ(1u, audio_codecs.size());
|
||||||
|
audio_codecs[0].name = "OpUs";
|
||||||
|
audio->set_codecs(audio_codecs);
|
||||||
|
|
||||||
|
cricket::VideoContentDescription* video =
|
||||||
|
GetFirstVideoContentDescription(description);
|
||||||
|
ASSERT_NE(nullptr, video);
|
||||||
|
auto video_codecs = video->codecs();
|
||||||
|
video_codecs.erase(std::remove_if(video_codecs.begin(), video_codecs.end(),
|
||||||
|
[](const cricket::VideoCodec& codec) {
|
||||||
|
return codec.name != "VP8";
|
||||||
|
}),
|
||||||
|
video_codecs.end());
|
||||||
|
ASSERT_EQ(1u, video_codecs.size());
|
||||||
|
video_codecs[0].name = "vP8";
|
||||||
|
video->set_codecs(video_codecs);
|
||||||
|
});
|
||||||
|
|
||||||
|
caller()->CreateAndSetAndSignalOffer();
|
||||||
|
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
|
||||||
|
|
||||||
|
// Verify frames are still received end-to-end.
|
||||||
|
ExpectNewFramesReceivedWithWait(
|
||||||
|
kDefaultExpectedAudioFrameCount, kDefaultExpectedVideoFrameCount,
|
||||||
|
kDefaultExpectedAudioFrameCount, kDefaultExpectedVideoFrameCount,
|
||||||
|
kMaxWaitForFramesMs);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif // if !defined(THREAD_SANITIZER)
|
#endif // if !defined(THREAD_SANITIZER)
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
#include "webrtc/base/trace_event.h"
|
#include "webrtc/base/trace_event.h"
|
||||||
|
#include "webrtc/common_types.h"
|
||||||
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
|
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
|
||||||
#include "webrtc/system_wrappers/include/metrics.h"
|
#include "webrtc/system_wrappers/include/metrics.h"
|
||||||
|
|
||||||
@ -50,15 +51,21 @@ const char* GetUmaPrefix(VideoEncoderConfig::ContentType content_type) {
|
|||||||
|
|
||||||
HistogramCodecType PayloadNameToHistogramCodecType(
|
HistogramCodecType PayloadNameToHistogramCodecType(
|
||||||
const std::string& payload_name) {
|
const std::string& payload_name) {
|
||||||
if (payload_name == "VP8") {
|
rtc::Optional<VideoCodecType> codecType =
|
||||||
return kVideoVp8;
|
PayloadNameToCodecType(payload_name);
|
||||||
} else if (payload_name == "VP9") {
|
if (!codecType) {
|
||||||
return kVideoVp9;
|
|
||||||
} else if (payload_name == "H264") {
|
|
||||||
return kVideoH264;
|
|
||||||
} else {
|
|
||||||
return kVideoUnknown;
|
return kVideoUnknown;
|
||||||
}
|
}
|
||||||
|
switch (*codecType) {
|
||||||
|
case kVideoCodecVP8:
|
||||||
|
return kVideoVp8;
|
||||||
|
case kVideoCodecVP9:
|
||||||
|
return kVideoVp9;
|
||||||
|
case kVideoCodecH264:
|
||||||
|
return kVideoH264;
|
||||||
|
default:
|
||||||
|
return kVideoUnknown;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateCodecTypeHistogram(const std::string& payload_name) {
|
void UpdateCodecTypeHistogram(const std::string& payload_name) {
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
#include "webrtc/base/optional.h"
|
#include "webrtc/base/optional.h"
|
||||||
#include "webrtc/base/trace_event.h"
|
#include "webrtc/base/trace_event.h"
|
||||||
|
#include "webrtc/common_types.h"
|
||||||
#include "webrtc/common_video/h264/profile_level_id.h"
|
#include "webrtc/common_video/h264/profile_level_id.h"
|
||||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
|
#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
|
||||||
@ -142,15 +143,8 @@ VideoCodec CreateDecoderVideoCodec(const VideoReceiveStream::Decoder& decoder) {
|
|||||||
|
|
||||||
codec.plType = decoder.payload_type;
|
codec.plType = decoder.payload_type;
|
||||||
strncpy(codec.plName, decoder.payload_name.c_str(), sizeof(codec.plName));
|
strncpy(codec.plName, decoder.payload_name.c_str(), sizeof(codec.plName));
|
||||||
if (decoder.payload_name == "VP8") {
|
codec.codecType =
|
||||||
codec.codecType = kVideoCodecVP8;
|
PayloadNameToCodecType(decoder.payload_name).value_or(kVideoCodecGeneric);
|
||||||
} else if (decoder.payload_name == "VP9") {
|
|
||||||
codec.codecType = kVideoCodecVP9;
|
|
||||||
} else if (decoder.payload_name == "H264") {
|
|
||||||
codec.codecType = kVideoCodecH264;
|
|
||||||
} else {
|
|
||||||
codec.codecType = kVideoCodecGeneric;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (codec.codecType == kVideoCodecVP8) {
|
if (codec.codecType == kVideoCodecVP8) {
|
||||||
*(codec.VP8()) = VideoEncoder::GetDefaultVp8Settings();
|
*(codec.VP8()) = VideoEncoder::GetDefaultVp8Settings();
|
||||||
|
|||||||
@ -263,9 +263,14 @@ std::string VideoSendStream::StreamStats::ToString() const {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool PayloadTypeSupportsSkippingFecPackets(const std::string& payload_name) {
|
bool PayloadTypeSupportsSkippingFecPackets(const std::string& payload_name) {
|
||||||
if (payload_name == "VP8" || payload_name == "VP9")
|
rtc::Optional<VideoCodecType> codecType =
|
||||||
|
PayloadNameToCodecType(payload_name);
|
||||||
|
if (codecType &&
|
||||||
|
(*codecType == kVideoCodecVP8 || *codecType == kVideoCodecVP9)) {
|
||||||
return true;
|
return true;
|
||||||
RTC_DCHECK(payload_name == "H264" || payload_name == "FAKE")
|
}
|
||||||
|
RTC_DCHECK((codecType && *codecType == kVideoCodecH264) ||
|
||||||
|
payload_name == "FAKE")
|
||||||
<< "unknown payload_name " << payload_name;
|
<< "unknown payload_name " << payload_name;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user