diff --git a/webrtc/modules/video_coding/main/source/generic_encoder.cc b/webrtc/modules/video_coding/main/source/generic_encoder.cc index 727ca2537..d641e52a1 100644 --- a/webrtc/modules/video_coding/main/source/generic_encoder.cc +++ b/webrtc/modules/video_coding/main/source/generic_encoder.cc @@ -24,7 +24,7 @@ _codecType(kVideoCodecUnknown), _VCMencodedFrameCallback(NULL), _bitRate(0), _frameRate(0), -_internalSource(false) +_internalSource(internalSource) { } @@ -59,12 +59,10 @@ VCMGenericEncoder::InitEncode(const VideoCodec* settings, WebRtc_Word32 VCMGenericEncoder::Encode(const I420VideoFrame& inputFrame, const CodecSpecificInfo* codecSpecificInfo, - const std::vector* frameTypes) { - std::vector video_frame_types(frameTypes->size(), + const std::vector& frameTypes) { + std::vector video_frame_types(frameTypes.size(), kDeltaFrame); - if (frameTypes) { - VCMEncodedFrame::ConvertFrameTypes(*frameTypes, &video_frame_types); - } + VCMEncodedFrame::ConvertFrameTypes(frameTypes, &video_frame_types); return _encoder.Encode(inputFrame, codecSpecificInfo, &video_frame_types); } @@ -115,15 +113,11 @@ VCMGenericEncoder::SetPeriodicKeyFrames(bool enable) } WebRtc_Word32 VCMGenericEncoder::RequestFrame( - const std::vector* frame_types) { - if (!frame_types) { - return 0; - } + const std::vector& frame_types) { I420VideoFrame image; - std::vector video_frame_types(kVideoFrameDelta); - if (frame_types) { - VCMEncodedFrame::ConvertFrameTypes(*frame_types, &video_frame_types); - } + std::vector video_frame_types(frame_types.size(), + kDeltaFrame); + VCMEncodedFrame::ConvertFrameTypes(frame_types, &video_frame_types); return _encoder.Encode(image, NULL, &video_frame_types); } diff --git a/webrtc/modules/video_coding/main/source/generic_encoder.h b/webrtc/modules/video_coding/main/source/generic_encoder.h index 9f7432be0..aab336786 100644 --- a/webrtc/modules/video_coding/main/source/generic_encoder.h +++ b/webrtc/modules/video_coding/main/source/generic_encoder.h @@ -101,7 +101,7 @@ public: */ WebRtc_Word32 Encode(const I420VideoFrame& inputFrame, const CodecSpecificInfo* codecSpecificInfo, - const std::vector* frameTypes); + const std::vector& frameTypes); /** * Set new target bit rate and frame rate * Return Value: new bit rate if OK, otherwise <0s @@ -127,7 +127,7 @@ public: WebRtc_Word32 SetPeriodicKeyFrames(bool enable); - WebRtc_Word32 RequestFrame(const std::vector* frame_types); + WebRtc_Word32 RequestFrame(const std::vector& frame_types); bool InternalSource() const; diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.cc b/webrtc/modules/video_coding/main/source/video_coding_impl.cc index 0f8f1eb45..9494bc2bd 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.cc @@ -683,7 +683,7 @@ VideoCodingModuleImpl::AddVideoFrame(const I420VideoFrame& videoFrame, _mediaOpt.updateContentData(contentMetrics); WebRtc_Word32 ret = _encoder->Encode(videoFrame, codecSpecificInfo, - &_nextFrameTypes); + _nextFrameTypes); if (_encoderInputFile != NULL) { if (PrintI420VideoFrame(videoFrame, _encoderInputFile) < 0) @@ -707,13 +707,16 @@ VideoCodingModuleImpl::AddVideoFrame(const I420VideoFrame& videoFrame, } WebRtc_Word32 VideoCodingModuleImpl::IntraFrameRequest(int stream_index) { - assert(stream_index >= 0); CriticalSectionScoped cs(_sendCritSect); + if (stream_index < 0 || + static_cast(stream_index) >= _nextFrameTypes.size()) { + return -1; + } _nextFrameTypes[stream_index] = kVideoFrameKey; if (_encoder != NULL && _encoder->InternalSource()) { // Try to request the frame if we have an external encoder with // internal source since AddVideoFrame never will be called. - if (_encoder->RequestFrame(&_nextFrameTypes) == + if (_encoder->RequestFrame(_nextFrameTypes) == WEBRTC_VIDEO_CODEC_OK) { _nextFrameTypes[stream_index] = kVideoFrameDelta; } diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl_unittest.cc b/webrtc/modules/video_coding/main/source/video_coding_impl_unittest.cc index 43cca9862..27297ac4f 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl_unittest.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_impl_unittest.cc @@ -109,6 +109,32 @@ TEST_F(TestVideoCodingModule, TestIntraRequests) { EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL)); ExpectIntraRequest(-1); EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL)); + + EXPECT_EQ(-1, vcm_->IntraFrameRequest(3)); + ExpectIntraRequest(-1); + EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL)); + + EXPECT_EQ(-1, vcm_->IntraFrameRequest(-1)); + ExpectIntraRequest(-1); + EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL)); +} + +TEST_F(TestVideoCodingModule, TestIntraRequestsInternalCapture) { + // De-register current external encoder. + EXPECT_EQ(0, vcm_->RegisterExternalEncoder(NULL, kUnusedPayloadType, false)); + // Register encoder with internal capture. + EXPECT_EQ(0, vcm_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType, + true)); + EXPECT_EQ(0, vcm_->RegisterSendCodec(&settings_, 1, 1200)); + ExpectIntraRequest(0); + EXPECT_EQ(0, vcm_->IntraFrameRequest(0)); + ExpectIntraRequest(1); + EXPECT_EQ(0, vcm_->IntraFrameRequest(1)); + ExpectIntraRequest(2); + EXPECT_EQ(0, vcm_->IntraFrameRequest(2)); + // No requests expected since these indices are out of bounds. + EXPECT_EQ(-1, vcm_->IntraFrameRequest(3)); + EXPECT_EQ(-1, vcm_->IntraFrameRequest(-1)); } } // namespace webrtc