Fix crash with CVO turned on for VP9 codec

CopyCodecSpecific nulls out the rtpheader pointer hence causing the crash downstream.

More details about the codec type enums:
There are 2 enums defined. webrtc::VideoCodecType webrtc::RtpCodecTypes and they don't match. Inside CopyCodecSpecific in generic_encoder.cc, it was converted from the first to the 2nd type. At that point, it'll be kRtpVideoNone (as the effect of memset to 0). kRtpVideoNone is a bad value as it could cause assert. Later, it'll be reset to kRtpVideoGeneric in RTPSender::SendOutgoingData so it's not a concern.

BUG=4511
R=pbos@webrtc.org, pthatcher@webrtc.org, stefan@webrtc.org

Committed: https://crrev.com/29b1a1c0c7c6f4b1ae4d63844b1dfaa7a72530a0
Cr-Commit-Position: refs/heads/master@{#8951}

Review URL: https://webrtc-codereview.appspot.com/47999004

Cr-Commit-Position: refs/heads/master@{#8955}
This commit is contained in:
Guo-wei Shieh 2015-04-08 13:00:10 -07:00
parent d61ebda941
commit 2c37078e40
2 changed files with 24 additions and 21 deletions

View File

@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "webrtc/base/checks.h"
#include "webrtc/engine_configurations.h" #include "webrtc/engine_configurations.h"
#include "webrtc/modules/video_coding/main/source/encoded_frame.h" #include "webrtc/modules/video_coding/main/source/encoded_frame.h"
#include "webrtc/modules/video_coding/main/source/generic_encoder.h" #include "webrtc/modules/video_coding/main/source/generic_encoder.h"
@ -19,35 +20,30 @@ namespace webrtc {
namespace { namespace {
// Map information from info into rtp. If no relevant information is found // Map information from info into rtp. If no relevant information is found
// in info, rtp is set to NULL. // in info, rtp is set to NULL.
void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader** rtp) { void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader* rtp) {
if (!info) { DCHECK(info);
*rtp = NULL;
return;
}
switch (info->codecType) { switch (info->codecType) {
case kVideoCodecVP8: { case kVideoCodecVP8: {
(*rtp)->codec = kRtpVideoVp8; rtp->codec = kRtpVideoVp8;
(*rtp)->codecHeader.VP8.InitRTPVideoHeaderVP8(); rtp->codecHeader.VP8.InitRTPVideoHeaderVP8();
(*rtp)->codecHeader.VP8.pictureId = info->codecSpecific.VP8.pictureId; rtp->codecHeader.VP8.pictureId = info->codecSpecific.VP8.pictureId;
(*rtp)->codecHeader.VP8.nonReference = rtp->codecHeader.VP8.nonReference =
info->codecSpecific.VP8.nonReference; info->codecSpecific.VP8.nonReference;
(*rtp)->codecHeader.VP8.temporalIdx = info->codecSpecific.VP8.temporalIdx; rtp->codecHeader.VP8.temporalIdx = info->codecSpecific.VP8.temporalIdx;
(*rtp)->codecHeader.VP8.layerSync = info->codecSpecific.VP8.layerSync; rtp->codecHeader.VP8.layerSync = info->codecSpecific.VP8.layerSync;
(*rtp)->codecHeader.VP8.tl0PicIdx = info->codecSpecific.VP8.tl0PicIdx; rtp->codecHeader.VP8.tl0PicIdx = info->codecSpecific.VP8.tl0PicIdx;
(*rtp)->codecHeader.VP8.keyIdx = info->codecSpecific.VP8.keyIdx; rtp->codecHeader.VP8.keyIdx = info->codecSpecific.VP8.keyIdx;
(*rtp)->simulcastIdx = info->codecSpecific.VP8.simulcastIdx; rtp->simulcastIdx = info->codecSpecific.VP8.simulcastIdx;
return; return;
} }
case kVideoCodecH264: case kVideoCodecH264:
(*rtp)->codec = kRtpVideoH264; rtp->codec = kRtpVideoH264;
return; return;
case kVideoCodecGeneric: case kVideoCodecGeneric:
(*rtp)->codec = kRtpVideoGeneric; rtp->codec = kRtpVideoGeneric;
(*rtp)->simulcastIdx = info->codecSpecific.generic.simulcast_idx; rtp->simulcastIdx = info->codecSpecific.generic.simulcast_idx;
return; return;
default: default:
// No codec specific info. Change RTP header pointer to NULL.
*rtp = NULL;
return; return;
} }
} }
@ -256,7 +252,9 @@ int32_t VCMEncodedFrameCallback::Encoded(
RTPVideoHeader rtpVideoHeader; RTPVideoHeader rtpVideoHeader;
memset(&rtpVideoHeader, 0, sizeof(RTPVideoHeader)); memset(&rtpVideoHeader, 0, sizeof(RTPVideoHeader));
RTPVideoHeader* rtpVideoHeaderPtr = &rtpVideoHeader; RTPVideoHeader* rtpVideoHeaderPtr = &rtpVideoHeader;
CopyCodecSpecific(codecSpecificInfo, &rtpVideoHeaderPtr); if (codecSpecificInfo) {
CopyCodecSpecific(codecSpecificInfo, rtpVideoHeaderPtr);
}
rtpVideoHeader.rotation = _rotation; rtpVideoHeader.rotation = _rotation;
int32_t callbackReturn = _sendCallback->SendData( int32_t callbackReturn = _sendCallback->SendData(

View File

@ -8,12 +8,15 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "webrtc/test/call_test.h" #include "webrtc/test/call_test.h"
#include "webrtc/test/encoder_settings.h" #include "webrtc/test/encoder_settings.h"
namespace webrtc { namespace webrtc {
namespace test { namespace test {
namespace {
const int kVideoRotationRtpExtensionId = 4;
}
CallTest::CallTest() CallTest::CallTest()
: clock_(Clock::GetRealTimeClock()), : clock_(Clock::GetRealTimeClock()),
send_stream_(NULL), send_stream_(NULL),
@ -94,6 +97,8 @@ void CallTest::CreateSendConfig(size_t num_streams) {
encoder_config_.streams = test::CreateVideoStreams(num_streams); encoder_config_.streams = test::CreateVideoStreams(num_streams);
for (size_t i = 0; i < num_streams; ++i) for (size_t i = 0; i < num_streams; ++i)
send_config_.rtp.ssrcs.push_back(kSendSsrcs[i]); send_config_.rtp.ssrcs.push_back(kSendSsrcs[i]);
send_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kVideoRotation, kVideoRotationRtpExtensionId));
} }
void CallTest::CreateMatchingReceiveConfigs() { void CallTest::CreateMatchingReceiveConfigs() {