Prevent encoding frames with wrong resolution.

This is a speculative fix for a crash that should be able to happen if a
codec is reconfigured while a frame is leaving the
VideoProcessingModule, causing a mismatch between configured codec and
input frame size.

BUG=
R=magjed@webrtc.org
TBR=mflodman@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#8615}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8615 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pbos@webrtc.org 2015-03-05 13:57:37 +00:00
parent 03054486f5
commit 67a9e40286
4 changed files with 20 additions and 1 deletions

View File

@ -640,6 +640,10 @@ bool VCMCodecDataBase::SupportsRenderScheduling() const {
return render_timing;
}
bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const {
return send_codec_.width == width && send_codec_.height == height;
}
VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder(
uint8_t payload_type,
VideoCodec* new_codec,

View File

@ -146,6 +146,8 @@ class VCMCodecDataBase {
// the encoded frames.
bool SupportsRenderScheduling() const;
bool MatchesCurrentResolution(int width, int height) const;
private:
typedef std::map<uint8_t, VCMDecoderMapItem*> DecoderMap;
typedef std::map<uint8_t, VCMExtDecoderMapItem*> ExternalDecoderMap;

View File

@ -370,6 +370,13 @@ int32_t VideoSender::AddVideoFrame(const I420VideoFrame& videoFrame,
return VCM_OK;
}
_mediaOpt.UpdateContentData(contentMetrics);
// TODO(pbos): Make sure setting send codec is synchronized with video
// processing so frame size always matches.
if (!_codecDataBase.MatchesCurrentResolution(videoFrame.width(),
videoFrame.height())) {
LOG(LS_ERROR) << "Incoming frame doesn't match set resolution. Dropping.";
return VCM_PARAMETER_ERROR;
}
int32_t ret =
_encoder->Encode(videoFrame, codecSpecificInfo, _nextFrameTypes);
recorder_->Add(videoFrame);

View File

@ -70,12 +70,17 @@ MATCHER_P(MatchesVp8StreamInfo, expected, "") {
class EmptyFrameGenerator : public FrameGenerator {
public:
EmptyFrameGenerator(int width, int height) : width_(width), height_(height) {}
I420VideoFrame* NextFrame() override {
frame_.reset(new I420VideoFrame());
frame_->CreateEmptyFrame(width_, height_, width_, (width_ + 1) / 2,
(width_ + 1) / 2);
return frame_.get();
}
private:
const int width_;
const int height_;
rtc::scoped_ptr<I420VideoFrame> frame_;
};
@ -199,7 +204,6 @@ class TestVideoSenderWithMockEncoder : public TestVideoSender {
void SetUp() override {
TestVideoSender::SetUp();
generator_.reset(new EmptyFrameGenerator());
EXPECT_EQ(
0,
sender_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType, false));
@ -217,6 +221,8 @@ class TestVideoSenderWithMockEncoder : public TestVideoSender {
ConfigureStream(
kDefaultWidth, kDefaultHeight, 1200, &settings_.simulcastStream[2]);
settings_.plType = kUnusedPayloadType; // Use the mocked encoder.
generator_.reset(
new EmptyFrameGenerator(settings_.width, settings_.height));
EXPECT_EQ(0, sender_->RegisterSendCodec(&settings_, 1, 1200));
}