Add per stream intra requests.

BUG=

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2883 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2012-10-08 07:06:53 +00:00
parent 7bc3a4172a
commit c530043684
27 changed files with 260 additions and 108 deletions

View File

@ -49,7 +49,7 @@ public:
// <0 - Error
virtual int Encode(const VideoFrame& inputImage,
const CodecSpecificInfo* /*codecSpecificInfo*/,
const VideoFrameType /*frameTypes*/);
const std::vector<VideoFrameType>* /*frame_types*/);
// Register an encode complete callback object.
//

View File

@ -78,7 +78,7 @@ int I420Encoder::InitEncode(const VideoCodec* codecSettings,
int I420Encoder::Encode(const VideoFrame& inputImage,
const CodecSpecificInfo* /*codecSpecificInfo*/,
const VideoFrameType /*frameType*/) {
const std::vector<VideoFrameType>* /*frame_types*/) {
if (!_inited) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}

View File

@ -39,7 +39,7 @@ class MockVideoEncoder : public VideoEncoder {
MOCK_METHOD3(Encode,
WebRtc_Word32(const VideoFrame& inputImage,
const CodecSpecificInfo* codecSpecificInfo,
const VideoFrameType frameType));
const std::vector<VideoFrameType>* frame_types));
MOCK_METHOD1(RegisterEncodeCompleteCallback,
WebRtc_Word32(EncodedImageCallback* callback));
MOCK_METHOD0(Release, WebRtc_Word32());

View File

@ -11,6 +11,8 @@
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_INTERFACE_VIDEO_CODEC_INTERFACE_H
#define WEBRTC_MODULES_VIDEO_CODING_CODECS_INTERFACE_VIDEO_CODEC_INTERFACE_H
#include <vector>
#include "common_types.h"
#include "modules/interface/module_common_types.h"
#include "modules/video_coding/codecs/interface/video_error_codes.h"
@ -95,12 +97,14 @@ public:
// Input:
// - inputImage : Image to be encoded
// - codecSpecificInfo : Pointer to codec specific data
// - frameType : The frame type to encode
// - frame_types : The frame type to encode
//
// Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0 otherwise.
virtual WebRtc_Word32 Encode(const VideoFrame& inputImage,
const CodecSpecificInfo* codecSpecificInfo,
const VideoFrameType frameType) = 0;
// Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0
// otherwise.
virtual WebRtc_Word32 Encode(
const VideoFrame& inputImage,
const CodecSpecificInfo* codecSpecificInfo,
const std::vector<VideoFrameType>* frame_types) = 0;
// Register an encode complete callback object.
//

View File

@ -180,17 +180,17 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) {
source_frame_.SetTimeStamp(frame_number);
// Decide if we're going to force a keyframe:
VideoFrameType frame_type = kDeltaFrame;
std::vector<VideoFrameType> frame_types(1, kDeltaFrame);
if (config_.keyframe_interval > 0 &&
frame_number % config_.keyframe_interval == 0) {
frame_type = kKeyFrame;
frame_types[0] = kKeyFrame;
}
// For dropped frames, we regard them as zero size encoded frames.
encoded_frame_size_ = 0;
WebRtc_Word32 encode_result = encoder_->Encode(source_frame_, NULL,
frame_type);
&frame_types);
if (encode_result != WEBRTC_VIDEO_CODEC_OK) {
fprintf(stderr, "Failed to encode frame %d, return code: %d\n",

View File

@ -12,8 +12,9 @@
#include <assert.h>
#include <string.h>
#include <sstream>
#include <queue>
#include <sstream>
#include <vector>
#include "gtest/gtest.h"
#include "tick_util.h"
@ -422,7 +423,7 @@ NormalAsyncTest::Encode()
}
_encodeCompleteTime = 0;
_encodeTimes[rawImage.TimeStamp()] = tGetTime();
VideoFrameType frameType = kDeltaFrame;
std::vector<VideoFrameType> frame_types(1, kDeltaFrame);
// check SLI queue
_hasReceivedSLI = false;
@ -458,13 +459,13 @@ NormalAsyncTest::Encode()
if (_hasReceivedPLI)
{
// respond to PLI by encoding a key frame
frameType = kKeyFrame;
frame_types[0] = kKeyFrame;
_hasReceivedPLI = false;
_hasReceivedSLI = false; // don't trigger both at once
}
webrtc::CodecSpecificInfo* codecSpecificInfo = CreateEncoderSpecificInfo();
int ret = _encoder->Encode(rawImage, codecSpecificInfo, frameType);
int ret = _encoder->Encode(rawImage, codecSpecificInfo, &frame_types);
EXPECT_EQ(ret, WEBRTC_VIDEO_CODEC_OK);
if (codecSpecificInfo != NULL)
{

View File

@ -267,13 +267,13 @@ bool PerformanceTest::Encode()
{
VideoFrame rawImage;
VideoBufferToRawImage(_inputVideoBuffer, rawImage);
VideoFrameType frameType = kDeltaFrame;
std::vector<VideoFrameType> frameTypes(1, kDeltaFrame);
if (_requestKeyFrame && !(_encFrameCnt%50))
{
frameType = kKeyFrame;
frameTypes[0] = kKeyFrame;
}
webrtc::CodecSpecificInfo* codecSpecificInfo = CreateEncoderSpecificInfo();
int ret = _encoder->Encode(rawImage, codecSpecificInfo, frameType);
int ret = _encoder->Encode(rawImage, codecSpecificInfo, &frameTypes);
EXPECT_EQ(ret, WEBRTC_VIDEO_CODEC_OK);
if (codecSpecificInfo != NULL)
{

View File

@ -240,8 +240,7 @@ UnitTest::Setup()
// Ensures our initial parameters are valid.
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
VideoFrameType videoFrameType = kDeltaFrame;
_encoder->Encode(image, NULL, videoFrameType);
_encoder->Encode(image, NULL, NULL);
_refEncFrameLength = WaitForEncodedFrame();
ASSERT_TRUE(_refEncFrameLength > 0);
_refEncFrame = new unsigned char[_refEncFrameLength];
@ -266,7 +265,7 @@ UnitTest::Setup()
_inputVideoBuffer.SetWidth(_source->GetWidth());
_inputVideoBuffer.SetHeight(_source->GetHeight());
VideoBufferToRawImage(_inputVideoBuffer, image);
_encoder->Encode(image, NULL, videoFrameType);
_encoder->Encode(image, NULL, NULL);
ASSERT_TRUE(WaitForEncodedFrame() > 0);
}
EncodedImage encodedImage;
@ -352,7 +351,6 @@ UnitTest::Perform()
int frameLength;
VideoFrame inputImage;
EncodedImage encodedImage;
VideoFrameType videoFrameType = kDeltaFrame;
//----- Encoder parameter tests -----
@ -360,7 +358,7 @@ UnitTest::Perform()
// We want to revert the initialization done in Setup().
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType)
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL)
== WEBRTC_VIDEO_CODEC_UNINITIALIZED);
//-- InitEncode() errors --
@ -423,7 +421,7 @@ UnitTest::Perform()
// inputVideoBuffer unallocated.
_inputVideoBuffer.Free();
inputImage.Free();
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
_inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _refFrame);
@ -436,8 +434,9 @@ UnitTest::Perform()
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
for (int i = 1; i <= 60; i++)
{
VideoFrameType frameType = !(i % 2) ? kKeyFrame : kDeltaFrame;
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, frameType) ==
VideoFrameType frame_type = !(i % 2) ? kKeyFrame : kDeltaFrame;
std::vector<VideoFrameType> frame_types(1, frame_type);
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, &frame_types) ==
WEBRTC_VIDEO_CODEC_OK);
EXPECT_TRUE(WaitForEncodedFrame() > 0);
}
@ -445,12 +444,12 @@ UnitTest::Perform()
// Init then encode.
_encodedVideoBuffer.UpdateLength(0);
_encodedVideoBuffer.Reset();
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
WEBRTC_VIDEO_CODEC_OK);
EXPECT_TRUE(WaitForEncodedFrame() > 0);
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
_encoder->Encode(inputImage, NULL, videoFrameType);
_encoder->Encode(inputImage, NULL, NULL);
frameLength = WaitForEncodedFrame();
EXPECT_TRUE(frameLength > 0);
EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
@ -459,11 +458,11 @@ UnitTest::Perform()
// Reset then encode.
_encodedVideoBuffer.UpdateLength(0);
_encodedVideoBuffer.Reset();
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
WEBRTC_VIDEO_CODEC_OK);
WaitForEncodedFrame();
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
_encoder->Encode(inputImage, NULL, videoFrameType);
_encoder->Encode(inputImage, NULL, NULL);
frameLength = WaitForEncodedFrame();
EXPECT_TRUE(frameLength > 0);
EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
@ -472,12 +471,12 @@ UnitTest::Perform()
// Release then encode.
_encodedVideoBuffer.UpdateLength(0);
_encodedVideoBuffer.Reset();
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
WEBRTC_VIDEO_CODEC_OK);
WaitForEncodedFrame();
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
_encoder->Encode(inputImage, NULL, videoFrameType);
_encoder->Encode(inputImage, NULL, NULL);
frameLength = WaitForEncodedFrame();
EXPECT_TRUE(frameLength > 0);
EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
@ -588,8 +587,7 @@ UnitTest::Perform()
tempInput.CopyFrame(tmpLength, inputImage.Buffer());
tempInput.SetWidth(tempInst.width);
tempInput.SetHeight(tempInst.height);
VideoFrameType videoFrameType = kDeltaFrame;
_encoder->Encode(tempInput, NULL, videoFrameType);
_encoder->Encode(tempInput, NULL, NULL);
frameLength = WaitForEncodedFrame();
EXPECT_TRUE(frameLength > 0);
tempInput.Free();
@ -607,7 +605,7 @@ UnitTest::Perform()
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
WEBRTC_VIDEO_CODEC_OK);
_encoder->Encode(inputImage, NULL, videoFrameType);
_encoder->Encode(inputImage, NULL, NULL);
frameLength = WaitForEncodedFrame();
EXPECT_TRUE(frameLength > 0);
@ -666,8 +664,7 @@ UnitTest::Perform()
_inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _sourceBuffer);
_inputVideoBuffer.SetTimeStamp(frames);
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
VideoFrameType videoFrameType = kDeltaFrame;
ASSERT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
ASSERT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
WEBRTC_VIDEO_CODEC_OK);
frameLength = WaitForEncodedFrame();
//ASSERT_TRUE(frameLength);
@ -745,8 +742,7 @@ UnitTest::RateControlTests()
static_cast<WebRtc_UWord32>(9e4 /
static_cast<float>(_inst.maxFramerate)));
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
VideoFrameType videoFrameType = kDeltaFrame;
ASSERT_EQ(_encoder->Encode(inputImage, NULL, videoFrameType),
ASSERT_EQ(_encoder->Encode(inputImage, NULL, NULL),
WEBRTC_VIDEO_CODEC_OK);
frameLength = WaitForEncodedFrame();
ASSERT_GE(frameLength, 0u);

View File

@ -149,7 +149,6 @@ bool VP8RpsTest::EncodeRps(RpsDecodeCompleteCallback* decodeCallback) {
}
_encodeCompleteTime = 0;
_encodeTimes[rawImage.TimeStamp()] = tGetTime();
webrtc::VideoFrameType frameType = webrtc::kDeltaFrame;
webrtc::CodecSpecificInfo* codecSpecificInfo = CreateEncoderSpecificInfo();
codecSpecificInfo->codecSpecific.VP8.pictureIdRPSI =
@ -162,7 +161,7 @@ bool VP8RpsTest::EncodeRps(RpsDecodeCompleteCallback* decodeCallback) {
sli_ = false;
}
printf("Encoding: %u\n", _framecnt);
int ret = _encoder->Encode(rawImage, codecSpecificInfo, frameType);
int ret = _encoder->Encode(rawImage, codecSpecificInfo, NULL);
if (ret < 0)
printf("Failed to encode: %u\n", _framecnt);

View File

@ -103,6 +103,7 @@
'type': 'executable',
'dependencies': [
'webrtc_vp8',
'<(DEPTH)/testing/gmock.gyp:gmock',
'<(DEPTH)/testing/gtest.gyp:gtest',
'<(webrtc_root)/test/test.gyp:test_support_main',
],

View File

@ -326,7 +326,7 @@ uint32_t VP8EncoderImpl::MaxIntraTarget(uint32_t optimalBuffersize) {
int VP8EncoderImpl::Encode(const VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const VideoFrameType frame_type) {
const std::vector<VideoFrameType>* frame_types) {
if (!inited_) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
@ -337,6 +337,12 @@ int VP8EncoderImpl::Encode(const VideoFrame& input_image,
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
VideoFrameType frame_type = kDeltaFrame;
// We only support one stream at the moment.
if (frame_types && frame_types->size() > 0) {
frame_type = (*frame_types)[0];
}
// Check for change in frame size.
if (input_image.Width() != codec_.width ||
input_image.Height() != codec_.height) {

View File

@ -74,7 +74,7 @@ class VP8EncoderImpl : public VP8Encoder {
virtual int Encode(const VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const VideoFrameType frame_type);
const std::vector<VideoFrameType>* frame_types);
// Register an encode complete callback object.
//

View File

@ -260,7 +260,7 @@ public:
//
// Return value : VCM_OK, on success.
// < 0, on error.
virtual WebRtc_Word32 IntraFrameRequest() = 0;
virtual WebRtc_Word32 IntraFrameRequest(int stream_index) = 0;
// Frame Dropper enable. Can be used to disable the frame dropping when the encoder
// over-uses its bit rate. This API is designed to be used when the encoded frames

View File

@ -227,31 +227,30 @@ webrtc::FrameType VCMEncodedFrame::ConvertFrameType(VideoFrameType frameType)
}
}
VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frameType)
{
switch (frameType)
{
VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frame_type) {
switch (frame_type) {
case kVideoFrameKey:
{
return kKeyFrame;
}
return kKeyFrame;
case kVideoFrameDelta:
{
return kDeltaFrame;
}
return kDeltaFrame;
case kVideoFrameGolden:
{
return kGoldenFrame;
}
return kGoldenFrame;
case kVideoFrameAltRef:
{
return kAltRefFrame;
}
return kAltRefFrame;
default:
{
return kDeltaFrame;
}
}
assert(false);
return kDeltaFrame;
}
}
void VCMEncodedFrame::ConvertFrameTypes(
const std::vector<webrtc::FrameType>& frame_types,
std::vector<VideoFrameType>* video_frame_types) {
assert(video_frame_types);
video_frame_types->reserve(frame_types.size());
for (size_t i = 0; i < frame_types.size(); ++i) {
(*video_frame_types)[i] = ConvertFrameType(frame_types[i]);
}
}
}

View File

@ -11,6 +11,8 @@
#ifndef WEBRTC_MODULES_VIDEO_CODING_ENCODED_FRAME_H_
#define WEBRTC_MODULES_VIDEO_CODING_ENCODED_FRAME_H_
#include <vector>
#include "common_types.h"
#include "common_video/interface/video_image.h"
#include "modules/interface/module_common_types.h"
@ -93,6 +95,9 @@ public:
static webrtc::FrameType ConvertFrameType(VideoFrameType frameType);
static VideoFrameType ConvertFrameType(webrtc::FrameType frameType);
static void ConvertFrameTypes(
const std::vector<webrtc::FrameType>& frame_types,
std::vector<VideoFrameType>* video_frame_types);
protected:
/**

View File

@ -59,9 +59,13 @@ VCMGenericEncoder::InitEncode(const VideoCodec* settings,
WebRtc_Word32
VCMGenericEncoder::Encode(const VideoFrame& inputFrame,
const CodecSpecificInfo* codecSpecificInfo,
const FrameType frameType) {
VideoFrameType videoFrameType = VCMEncodedFrame::ConvertFrameType(frameType);
return _encoder.Encode(inputFrame, codecSpecificInfo, videoFrameType);
const std::vector<FrameType>* frameTypes) {
std::vector<VideoFrameType> video_frame_types(frameTypes->size(),
kDeltaFrame);
if (frameTypes) {
VCMEncodedFrame::ConvertFrameTypes(*frameTypes, &video_frame_types);
}
return _encoder.Encode(inputFrame, codecSpecificInfo, &video_frame_types);
}
WebRtc_Word32
@ -110,10 +114,17 @@ VCMGenericEncoder::SetPeriodicKeyFrames(bool enable)
return _encoder.SetPeriodicKeyFrames(enable);
}
WebRtc_Word32 VCMGenericEncoder::RequestFrame(const FrameType frameType) {
WebRtc_Word32 VCMGenericEncoder::RequestFrame(
const std::vector<FrameType>* frame_types) {
if (!frame_types) {
return 0;
}
VideoFrame image;
VideoFrameType videoFrameType = VCMEncodedFrame::ConvertFrameType(frameType);
return _encoder.Encode(image, NULL, videoFrameType);
std::vector<VideoFrameType> video_frame_types(kVideoFrameDelta);
if (frame_types) {
VCMEncodedFrame::ConvertFrameTypes(*frame_types, &video_frame_types);
}
return _encoder.Encode(image, NULL, &video_frame_types);
}
WebRtc_Word32

View File

@ -101,7 +101,7 @@ public:
*/
WebRtc_Word32 Encode(const VideoFrame& inputFrame,
const CodecSpecificInfo* codecSpecificInfo,
const FrameType frameType);
const std::vector<FrameType>* 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 FrameType frameType);
WebRtc_Word32 RequestFrame(const std::vector<FrameType>* frame_types);
bool InternalSource() const;

View File

@ -73,7 +73,7 @@ _scheduleKeyRequest(false),
_sendCritSect(CriticalSectionWrapper::CreateCriticalSection()),
_encoder(),
_encodedFrameCallback(),
_nextFrameType(kVideoFrameDelta),
_nextFrameTypes(1, kVideoFrameDelta),
_mediaOpt(id, clock_),
_sendCodecType(kVideoCodecUnknown),
_sendStatsCallback(NULL),
@ -334,6 +334,9 @@ VideoCodingModuleImpl::RegisterSendCodec(const VideoCodec* sendCodec,
_sendCodecType = sendCodec->codecType;
int numLayers = (_sendCodecType != kVideoCodecVP8) ? 1 :
sendCodec->codecSpecific.VP8.numberOfTemporalLayers;
_nextFrameTypes.clear();
_nextFrameTypes.resize(VCM_MAX(sendCodec->numberOfSimulcastStreams, 1),
kVideoFrameDelta);
_mediaOpt.SetEncodingData(_sendCodecType,
sendCodec->maxBitrate,
@ -661,7 +664,9 @@ VideoCodingModuleImpl::AddVideoFrame(const VideoFrame& videoFrame,
{
return VCM_UNINITIALIZED;
}
if (_nextFrameType == kFrameEmpty)
// TODO(holmer): Add support for dropping frames per stream. Currently we
// only have one frame dropper for all streams.
if (_nextFrameTypes[0] == kFrameEmpty)
{
return VCM_OK;
}
@ -679,7 +684,7 @@ VideoCodingModuleImpl::AddVideoFrame(const VideoFrame& videoFrame,
_mediaOpt.updateContentData(contentMetrics);
WebRtc_Word32 ret = _encoder->Encode(videoFrame,
codecSpecificInfo,
_nextFrameType);
&_nextFrameTypes);
if (_encoderInputFile != NULL)
{
if (fwrite(videoFrame.Buffer(), 1, videoFrame.Length(),
@ -695,19 +700,23 @@ VideoCodingModuleImpl::AddVideoFrame(const VideoFrame& videoFrame,
"Encode error: %d", ret);
return ret;
}
_nextFrameType = kVideoFrameDelta; // default frame type
for (size_t i = 0; i < _nextFrameTypes.size(); ++i) {
_nextFrameTypes[i] = kVideoFrameDelta; // Default frame type.
}
}
return VCM_OK;
}
WebRtc_Word32 VideoCodingModuleImpl::IntraFrameRequest() {
WebRtc_Word32 VideoCodingModuleImpl::IntraFrameRequest(int stream_index) {
assert(stream_index >= 0);
CriticalSectionScoped cs(_sendCritSect);
_nextFrameType = kVideoFrameKey;
_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(_nextFrameType) == WEBRTC_VIDEO_CODEC_OK) {
_nextFrameType = kVideoFrameDelta;
if (_encoder->RequestFrame(&_nextFrameTypes) ==
WEBRTC_VIDEO_CODEC_OK) {
_nextFrameTypes[stream_index] = kVideoFrameDelta;
}
}
return VCM_OK;

View File

@ -11,19 +11,20 @@
#ifndef WEBRTC_MODULES_VIDEO_CODING_VIDEO_CODING_IMPL_H_
#define WEBRTC_MODULES_VIDEO_CODING_VIDEO_CODING_IMPL_H_
#include "video_coding.h"
#include "critical_section_wrapper.h"
#include "frame_buffer.h"
#include "receiver.h"
#include "timing.h"
#include "jitter_buffer.h"
#include "codec_database.h"
#include "generic_decoder.h"
#include "generic_encoder.h"
#include "media_optimization.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "modules/video_coding/main/interface/video_coding.h"
#include <stdio.h>
#include <vector>
#include "modules/video_coding/main/source/codec_database.h"
#include "modules/video_coding/main/source/frame_buffer.h"
#include "modules/video_coding/main/source/generic_decoder.h"
#include "modules/video_coding/main/source/generic_encoder.h"
#include "modules/video_coding/main/source/jitter_buffer.h"
#include "modules/video_coding/main/source/media_optimization.h"
#include "modules/video_coding/main/source/receiver.h"
#include "modules/video_coding/main/source/tick_time_base.h"
#include "modules/video_coding/main/source/timing.h"
#include "system_wrappers/interface/critical_section_wrapper.h"
namespace webrtc
{
@ -147,7 +148,7 @@ public:
const VideoContentMetrics* _contentMetrics = NULL,
const CodecSpecificInfo* codecSpecificInfo = NULL);
virtual WebRtc_Word32 IntraFrameRequest();
virtual WebRtc_Word32 IntraFrameRequest(int stream_index);
//Enable frame dropper
virtual WebRtc_Word32 EnableFrameDropper(bool enable);
@ -300,7 +301,7 @@ private:
CriticalSectionWrapper* _sendCritSect; // Critical section for send side
VCMGenericEncoder* _encoder;
VCMEncodedFrameCallback _encodedFrameCallback;
FrameType _nextFrameType;
std::vector<FrameType> _nextFrameTypes;
VCMMediaOptimization _mediaOpt;
VideoCodecType _sendCodecType;
VCMSendStatisticsCallback* _sendStatsCallback;

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <vector>
#include "modules/video_coding/codecs/interface/mock/mock_video_codec_interface.h"
#include "modules/video_coding/main/interface/video_coding.h"
#include "system_wrappers/interface/scoped_ptr.h"
#include "gtest/gtest.h"
using ::testing::_;
using ::testing::AllOf;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::Field;
using ::testing::NiceMock;
using ::testing::Pointee;
using ::testing::Return;
namespace webrtc {
class TestVideoCodingModule : public ::testing::Test {
protected:
static const int kDefaultWidth = 1280;
static const int kDefaultHeight = 720;
static const int kNumberOfStreams = 3;
static const int kNumberOfLayers = 3;
static const int kUnusedPayloadType = 10;
virtual void SetUp() {
vcm_ = VideoCodingModule::Create(0);
EXPECT_EQ(0, vcm_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType,
false));
memset(&settings_, 0, sizeof(settings_));
EXPECT_EQ(0, vcm_->Codec(kVideoCodecVP8, &settings_));
settings_.numberOfSimulcastStreams = kNumberOfStreams;
ConfigureStream(kDefaultWidth / 4, kDefaultHeight / 4, 100,
&settings_.simulcastStream[0]);
ConfigureStream(kDefaultWidth / 2, kDefaultHeight / 2, 500,
&settings_.simulcastStream[1]);
ConfigureStream(kDefaultWidth, kDefaultHeight, 1200,
&settings_.simulcastStream[2]);
settings_.plType = kUnusedPayloadType; // Use the mocked encoder.
EXPECT_EQ(0, vcm_->RegisterSendCodec(&settings_, 1, 1200));
}
virtual void TearDown() {
VideoCodingModule::Destroy(vcm_);
input_frame_.Free();
}
void ExpectIntraRequest(int stream) {
if (stream == -1) {
// No intra request expected.
EXPECT_CALL(encoder_, Encode(
_, _, Pointee(ElementsAre(kDeltaFrame, kDeltaFrame, kDeltaFrame))))
.Times(1)
.WillRepeatedly(Return(0));
return;
}
assert(stream >= 0);
assert(stream < kNumberOfStreams);
std::vector<VideoFrameType> frame_types(kNumberOfStreams, kDeltaFrame);
frame_types[stream] = kKeyFrame;
EXPECT_CALL(encoder_, Encode(
_, _, Pointee(ElementsAreArray(&frame_types[0], frame_types.size()))))
.Times(1)
.WillRepeatedly(Return(0));
}
static void ConfigureStream(int width, int height, int max_bitrate,
SimulcastStream* stream) {
assert(stream);
stream->width = width;
stream->height = height;
stream->maxBitrate = max_bitrate;
stream->numberOfTemporalLayers = kNumberOfLayers;
stream->qpMax = 45;
}
VideoCodingModule* vcm_;
NiceMock<MockVideoEncoder> encoder_;
VideoFrame input_frame_;
VideoCodec settings_;
};
TEST_F(TestVideoCodingModule, TestIntraRequests) {
EXPECT_EQ(0, vcm_->IntraFrameRequest(0));
ExpectIntraRequest(0);
EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
ExpectIntraRequest(-1);
EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
EXPECT_EQ(0, vcm_->IntraFrameRequest(1));
ExpectIntraRequest(1);
EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
ExpectIntraRequest(-1);
EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
EXPECT_EQ(0, vcm_->IntraFrameRequest(2));
ExpectIntraRequest(2);
EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
ExpectIntraRequest(-1);
EXPECT_EQ(0, vcm_->AddVideoFrame(input_frame_, NULL, NULL));
}
} // namespace webrtc

View File

@ -83,6 +83,7 @@
'jitter_buffer_unittest.cc',
'session_info_unittest.cc',
'video_coding_robustness_unittest.cc',
'video_coding_impl_unittest.cc',
'qm_select_unittest.cc',
],
},

View File

@ -238,7 +238,7 @@ CodecDataBaseTest::Perform(CmdArgs& args)
// Try to decode a delta frame. Should get a warning since we have enabled the "require key frame" setting
// and because no frame type request callback has been registered.
TEST(_vcm->Decode() == VCM_MISSING_CALLBACK);
TEST(_vcm->IntraFrameRequest() == VCM_OK);
TEST(_vcm->IntraFrameRequest(0) == VCM_OK);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
@ -250,7 +250,7 @@ CodecDataBaseTest::Perform(CmdArgs& args)
sendCodec.width = _width;
sendCodec.height = _height;
TEST(_vcm->RegisterReceiveCodec(&sendCodec, 1) == VCM_OK);
TEST(_vcm->IntraFrameRequest() == VCM_OK);
TEST(_vcm->IntraFrameRequest(0) == VCM_OK);
waitEvent->Wait(33);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
@ -260,7 +260,7 @@ CodecDataBaseTest::Perform(CmdArgs& args)
waitEvent->Wait(33);
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
sourceFrame.SetTimeStamp(_timeStamp);
TEST(_vcm->IntraFrameRequest() == VCM_OK);
TEST(_vcm->IntraFrameRequest(0) == VCM_OK);
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
TEST(_vcm->Decode() == VCM_OK);
TEST(_vcm->ResetDecoder() == VCM_OK);

View File

@ -36,7 +36,7 @@ public:
virtual WebRtc_Word32 Encode(
const webrtc::VideoFrame& inputImage,
const webrtc::CodecSpecificInfo* codecSpecificInfo,
const webrtc::VideoFrameType frameType);
const std::vector<webrtc::VideoFrameType>* frameTypes);
virtual WebRtc_Word32 RegisterEncodeCompleteCallback(
webrtc::EncodedImageCallback* callback);

View File

@ -120,7 +120,7 @@ WebRtc_Word32 TbI420Encoder::InitEncode(const webrtc::VideoCodec* inst,
WebRtc_Word32 TbI420Encoder::Encode(
const webrtc::VideoFrame& inputImage,
const webrtc::CodecSpecificInfo* /*codecSpecificInfo*/,
const webrtc::VideoFrameType /*frameType*/)
const std::vector<webrtc::VideoFrameType>* /*frameTypes*/)
{
_functionCalls.Encode++;
if (!_inited)

View File

@ -749,17 +749,19 @@ WebRtc_Word32 ViECapturer::InitEncode(const VideoCodec* codec_settings,
return capture_encoder_->ConfigureEncoder(*codec_settings, max_payload_size);
}
WebRtc_Word32 ViECapturer::Encode(const VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const VideoFrameType frame_type) {
WebRtc_Word32 ViECapturer::Encode(
const VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const std::vector<VideoFrameType>* frame_types) {
CriticalSectionScoped cs(encoding_cs_.get());
if (!capture_encoder_) {
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
}
if (frame_type == kKeyFrame) {
if (frame_types == NULL) {
return capture_encoder_->EncodeFrameType(kVideoFrameDelta);
} else if ((*frame_types)[0] == kKeyFrame) {
return capture_encoder_->EncodeFrameType(kVideoFrameKey);
}
if (frame_type == kSkipFrame) {
} else if ((*frame_types)[0] == kSkipFrame) {
return capture_encoder_->EncodeFrameType(kFrameEmpty);
}
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;

View File

@ -11,6 +11,8 @@
#ifndef WEBRTC_VIDEO_ENGINE_VIE_CAPTURER_H_
#define WEBRTC_VIDEO_ENGINE_VIE_CAPTURER_H_
#include <vector>
#include "common_types.h" // NOLINT
#include "engine_configurations.h" // NOLINT
#include "modules/video_capture/main/interface/video_capture.h"
@ -142,7 +144,7 @@ class ViECapturer
WebRtc_UWord32 max_payload_size);
virtual WebRtc_Word32 Encode(const VideoFrame& input_image,
const CodecSpecificInfo* codec_specific_info,
const VideoFrameType frame_type);
const std::vector<VideoFrameType>* frame_types);
virtual WebRtc_Word32 RegisterEncodeCompleteCallback(
EncodedImageCallback* callback);
virtual WebRtc_Word32 Release();

View File

@ -585,7 +585,7 @@ int ViEEncoder::GetPreferedFrameSettings(int* width,
int ViEEncoder::SendKeyFrame() {
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
ViEId(engine_id_, channel_id_), "%s", __FUNCTION__);
return vcm_.IntraFrameRequest();
return vcm_.IntraFrameRequest(0);
}
WebRtc_Word32 ViEEncoder::SendCodecStatistics(
@ -818,7 +818,7 @@ void ViEEncoder::OnReceivedIntraFrameRequest(uint32_t /*ssrc*/) {
"%s: Not not encoding new intra due to timing", __FUNCTION__);
return;
}
vcm_.IntraFrameRequest();
vcm_.IntraFrameRequest(0);
time_last_intra_request_ms_ = now;
}