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:
parent
7bc3a4172a
commit
c530043684
@ -49,7 +49,7 @@ public:
|
|||||||
// <0 - Error
|
// <0 - Error
|
||||||
virtual int Encode(const VideoFrame& inputImage,
|
virtual int Encode(const VideoFrame& inputImage,
|
||||||
const CodecSpecificInfo* /*codecSpecificInfo*/,
|
const CodecSpecificInfo* /*codecSpecificInfo*/,
|
||||||
const VideoFrameType /*frameTypes*/);
|
const std::vector<VideoFrameType>* /*frame_types*/);
|
||||||
|
|
||||||
// Register an encode complete callback object.
|
// Register an encode complete callback object.
|
||||||
//
|
//
|
||||||
|
@ -78,7 +78,7 @@ int I420Encoder::InitEncode(const VideoCodec* codecSettings,
|
|||||||
|
|
||||||
int I420Encoder::Encode(const VideoFrame& inputImage,
|
int I420Encoder::Encode(const VideoFrame& inputImage,
|
||||||
const CodecSpecificInfo* /*codecSpecificInfo*/,
|
const CodecSpecificInfo* /*codecSpecificInfo*/,
|
||||||
const VideoFrameType /*frameType*/) {
|
const std::vector<VideoFrameType>* /*frame_types*/) {
|
||||||
if (!_inited) {
|
if (!_inited) {
|
||||||
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class MockVideoEncoder : public VideoEncoder {
|
|||||||
MOCK_METHOD3(Encode,
|
MOCK_METHOD3(Encode,
|
||||||
WebRtc_Word32(const VideoFrame& inputImage,
|
WebRtc_Word32(const VideoFrame& inputImage,
|
||||||
const CodecSpecificInfo* codecSpecificInfo,
|
const CodecSpecificInfo* codecSpecificInfo,
|
||||||
const VideoFrameType frameType));
|
const std::vector<VideoFrameType>* frame_types));
|
||||||
MOCK_METHOD1(RegisterEncodeCompleteCallback,
|
MOCK_METHOD1(RegisterEncodeCompleteCallback,
|
||||||
WebRtc_Word32(EncodedImageCallback* callback));
|
WebRtc_Word32(EncodedImageCallback* callback));
|
||||||
MOCK_METHOD0(Release, WebRtc_Word32());
|
MOCK_METHOD0(Release, WebRtc_Word32());
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_INTERFACE_VIDEO_CODEC_INTERFACE_H
|
#ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_INTERFACE_VIDEO_CODEC_INTERFACE_H
|
||||||
#define 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 "common_types.h"
|
||||||
#include "modules/interface/module_common_types.h"
|
#include "modules/interface/module_common_types.h"
|
||||||
#include "modules/video_coding/codecs/interface/video_error_codes.h"
|
#include "modules/video_coding/codecs/interface/video_error_codes.h"
|
||||||
@ -95,12 +97,14 @@ public:
|
|||||||
// Input:
|
// Input:
|
||||||
// - inputImage : Image to be encoded
|
// - inputImage : Image to be encoded
|
||||||
// - codecSpecificInfo : Pointer to codec specific data
|
// - 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.
|
// Return value : WEBRTC_VIDEO_CODEC_OK if OK, < 0
|
||||||
virtual WebRtc_Word32 Encode(const VideoFrame& inputImage,
|
// otherwise.
|
||||||
const CodecSpecificInfo* codecSpecificInfo,
|
virtual WebRtc_Word32 Encode(
|
||||||
const VideoFrameType frameType) = 0;
|
const VideoFrame& inputImage,
|
||||||
|
const CodecSpecificInfo* codecSpecificInfo,
|
||||||
|
const std::vector<VideoFrameType>* frame_types) = 0;
|
||||||
|
|
||||||
// Register an encode complete callback object.
|
// Register an encode complete callback object.
|
||||||
//
|
//
|
||||||
|
@ -180,17 +180,17 @@ bool VideoProcessorImpl::ProcessFrame(int frame_number) {
|
|||||||
source_frame_.SetTimeStamp(frame_number);
|
source_frame_.SetTimeStamp(frame_number);
|
||||||
|
|
||||||
// Decide if we're going to force a keyframe:
|
// 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 &&
|
if (config_.keyframe_interval > 0 &&
|
||||||
frame_number % 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.
|
// For dropped frames, we regard them as zero size encoded frames.
|
||||||
encoded_frame_size_ = 0;
|
encoded_frame_size_ = 0;
|
||||||
|
|
||||||
WebRtc_Word32 encode_result = encoder_->Encode(source_frame_, NULL,
|
WebRtc_Word32 encode_result = encoder_->Encode(source_frame_, NULL,
|
||||||
frame_type);
|
&frame_types);
|
||||||
|
|
||||||
if (encode_result != WEBRTC_VIDEO_CODEC_OK) {
|
if (encode_result != WEBRTC_VIDEO_CODEC_OK) {
|
||||||
fprintf(stderr, "Failed to encode frame %d, return code: %d\n",
|
fprintf(stderr, "Failed to encode frame %d, return code: %d\n",
|
||||||
|
@ -12,8 +12,9 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sstream>
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "tick_util.h"
|
#include "tick_util.h"
|
||||||
@ -422,7 +423,7 @@ NormalAsyncTest::Encode()
|
|||||||
}
|
}
|
||||||
_encodeCompleteTime = 0;
|
_encodeCompleteTime = 0;
|
||||||
_encodeTimes[rawImage.TimeStamp()] = tGetTime();
|
_encodeTimes[rawImage.TimeStamp()] = tGetTime();
|
||||||
VideoFrameType frameType = kDeltaFrame;
|
std::vector<VideoFrameType> frame_types(1, kDeltaFrame);
|
||||||
|
|
||||||
// check SLI queue
|
// check SLI queue
|
||||||
_hasReceivedSLI = false;
|
_hasReceivedSLI = false;
|
||||||
@ -458,13 +459,13 @@ NormalAsyncTest::Encode()
|
|||||||
if (_hasReceivedPLI)
|
if (_hasReceivedPLI)
|
||||||
{
|
{
|
||||||
// respond to PLI by encoding a key frame
|
// respond to PLI by encoding a key frame
|
||||||
frameType = kKeyFrame;
|
frame_types[0] = kKeyFrame;
|
||||||
_hasReceivedPLI = false;
|
_hasReceivedPLI = false;
|
||||||
_hasReceivedSLI = false; // don't trigger both at once
|
_hasReceivedSLI = false; // don't trigger both at once
|
||||||
}
|
}
|
||||||
|
|
||||||
webrtc::CodecSpecificInfo* codecSpecificInfo = CreateEncoderSpecificInfo();
|
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);
|
EXPECT_EQ(ret, WEBRTC_VIDEO_CODEC_OK);
|
||||||
if (codecSpecificInfo != NULL)
|
if (codecSpecificInfo != NULL)
|
||||||
{
|
{
|
||||||
|
@ -267,13 +267,13 @@ bool PerformanceTest::Encode()
|
|||||||
{
|
{
|
||||||
VideoFrame rawImage;
|
VideoFrame rawImage;
|
||||||
VideoBufferToRawImage(_inputVideoBuffer, rawImage);
|
VideoBufferToRawImage(_inputVideoBuffer, rawImage);
|
||||||
VideoFrameType frameType = kDeltaFrame;
|
std::vector<VideoFrameType> frameTypes(1, kDeltaFrame);
|
||||||
if (_requestKeyFrame && !(_encFrameCnt%50))
|
if (_requestKeyFrame && !(_encFrameCnt%50))
|
||||||
{
|
{
|
||||||
frameType = kKeyFrame;
|
frameTypes[0] = kKeyFrame;
|
||||||
}
|
}
|
||||||
webrtc::CodecSpecificInfo* codecSpecificInfo = CreateEncoderSpecificInfo();
|
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);
|
EXPECT_EQ(ret, WEBRTC_VIDEO_CODEC_OK);
|
||||||
if (codecSpecificInfo != NULL)
|
if (codecSpecificInfo != NULL)
|
||||||
{
|
{
|
||||||
|
@ -240,8 +240,7 @@ UnitTest::Setup()
|
|||||||
|
|
||||||
// Ensures our initial parameters are valid.
|
// Ensures our initial parameters are valid.
|
||||||
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
|
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == WEBRTC_VIDEO_CODEC_OK);
|
||||||
VideoFrameType videoFrameType = kDeltaFrame;
|
_encoder->Encode(image, NULL, NULL);
|
||||||
_encoder->Encode(image, NULL, videoFrameType);
|
|
||||||
_refEncFrameLength = WaitForEncodedFrame();
|
_refEncFrameLength = WaitForEncodedFrame();
|
||||||
ASSERT_TRUE(_refEncFrameLength > 0);
|
ASSERT_TRUE(_refEncFrameLength > 0);
|
||||||
_refEncFrame = new unsigned char[_refEncFrameLength];
|
_refEncFrame = new unsigned char[_refEncFrameLength];
|
||||||
@ -266,7 +265,7 @@ UnitTest::Setup()
|
|||||||
_inputVideoBuffer.SetWidth(_source->GetWidth());
|
_inputVideoBuffer.SetWidth(_source->GetWidth());
|
||||||
_inputVideoBuffer.SetHeight(_source->GetHeight());
|
_inputVideoBuffer.SetHeight(_source->GetHeight());
|
||||||
VideoBufferToRawImage(_inputVideoBuffer, image);
|
VideoBufferToRawImage(_inputVideoBuffer, image);
|
||||||
_encoder->Encode(image, NULL, videoFrameType);
|
_encoder->Encode(image, NULL, NULL);
|
||||||
ASSERT_TRUE(WaitForEncodedFrame() > 0);
|
ASSERT_TRUE(WaitForEncodedFrame() > 0);
|
||||||
}
|
}
|
||||||
EncodedImage encodedImage;
|
EncodedImage encodedImage;
|
||||||
@ -352,7 +351,6 @@ UnitTest::Perform()
|
|||||||
int frameLength;
|
int frameLength;
|
||||||
VideoFrame inputImage;
|
VideoFrame inputImage;
|
||||||
EncodedImage encodedImage;
|
EncodedImage encodedImage;
|
||||||
VideoFrameType videoFrameType = kDeltaFrame;
|
|
||||||
|
|
||||||
//----- Encoder parameter tests -----
|
//----- Encoder parameter tests -----
|
||||||
|
|
||||||
@ -360,7 +358,7 @@ UnitTest::Perform()
|
|||||||
// We want to revert the initialization done in Setup().
|
// We want to revert the initialization done in Setup().
|
||||||
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
|
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
|
||||||
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
|
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
|
||||||
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType)
|
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL)
|
||||||
== WEBRTC_VIDEO_CODEC_UNINITIALIZED);
|
== WEBRTC_VIDEO_CODEC_UNINITIALIZED);
|
||||||
|
|
||||||
//-- InitEncode() errors --
|
//-- InitEncode() errors --
|
||||||
@ -423,7 +421,7 @@ UnitTest::Perform()
|
|||||||
// inputVideoBuffer unallocated.
|
// inputVideoBuffer unallocated.
|
||||||
_inputVideoBuffer.Free();
|
_inputVideoBuffer.Free();
|
||||||
inputImage.Free();
|
inputImage.Free();
|
||||||
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
|
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
|
||||||
WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
|
WEBRTC_VIDEO_CODEC_ERR_PARAMETER);
|
||||||
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
|
_inputVideoBuffer.VerifyAndAllocate(_lengthSourceFrame);
|
||||||
_inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _refFrame);
|
_inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _refFrame);
|
||||||
@ -436,8 +434,9 @@ UnitTest::Perform()
|
|||||||
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
|
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
|
||||||
for (int i = 1; i <= 60; i++)
|
for (int i = 1; i <= 60; i++)
|
||||||
{
|
{
|
||||||
VideoFrameType frameType = !(i % 2) ? kKeyFrame : kDeltaFrame;
|
VideoFrameType frame_type = !(i % 2) ? kKeyFrame : kDeltaFrame;
|
||||||
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, frameType) ==
|
std::vector<VideoFrameType> frame_types(1, frame_type);
|
||||||
|
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, &frame_types) ==
|
||||||
WEBRTC_VIDEO_CODEC_OK);
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
EXPECT_TRUE(WaitForEncodedFrame() > 0);
|
EXPECT_TRUE(WaitForEncodedFrame() > 0);
|
||||||
}
|
}
|
||||||
@ -445,12 +444,12 @@ UnitTest::Perform()
|
|||||||
// Init then encode.
|
// Init then encode.
|
||||||
_encodedVideoBuffer.UpdateLength(0);
|
_encodedVideoBuffer.UpdateLength(0);
|
||||||
_encodedVideoBuffer.Reset();
|
_encodedVideoBuffer.Reset();
|
||||||
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
|
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
|
||||||
WEBRTC_VIDEO_CODEC_OK);
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
EXPECT_TRUE(WaitForEncodedFrame() > 0);
|
EXPECT_TRUE(WaitForEncodedFrame() > 0);
|
||||||
|
|
||||||
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == 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();
|
frameLength = WaitForEncodedFrame();
|
||||||
EXPECT_TRUE(frameLength > 0);
|
EXPECT_TRUE(frameLength > 0);
|
||||||
EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
|
EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
|
||||||
@ -459,11 +458,11 @@ UnitTest::Perform()
|
|||||||
// Reset then encode.
|
// Reset then encode.
|
||||||
_encodedVideoBuffer.UpdateLength(0);
|
_encodedVideoBuffer.UpdateLength(0);
|
||||||
_encodedVideoBuffer.Reset();
|
_encodedVideoBuffer.Reset();
|
||||||
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
|
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
|
||||||
WEBRTC_VIDEO_CODEC_OK);
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
WaitForEncodedFrame();
|
WaitForEncodedFrame();
|
||||||
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == 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();
|
frameLength = WaitForEncodedFrame();
|
||||||
EXPECT_TRUE(frameLength > 0);
|
EXPECT_TRUE(frameLength > 0);
|
||||||
EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
|
EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
|
||||||
@ -472,12 +471,12 @@ UnitTest::Perform()
|
|||||||
// Release then encode.
|
// Release then encode.
|
||||||
_encodedVideoBuffer.UpdateLength(0);
|
_encodedVideoBuffer.UpdateLength(0);
|
||||||
_encodedVideoBuffer.Reset();
|
_encodedVideoBuffer.Reset();
|
||||||
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
|
EXPECT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
|
||||||
WEBRTC_VIDEO_CODEC_OK);
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
WaitForEncodedFrame();
|
WaitForEncodedFrame();
|
||||||
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
|
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
|
||||||
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) == 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();
|
frameLength = WaitForEncodedFrame();
|
||||||
EXPECT_TRUE(frameLength > 0);
|
EXPECT_TRUE(frameLength > 0);
|
||||||
EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
|
EXPECT_TRUE(CheckIfBitExact(_refEncFrame, _refEncFrameLength,
|
||||||
@ -588,8 +587,7 @@ UnitTest::Perform()
|
|||||||
tempInput.CopyFrame(tmpLength, inputImage.Buffer());
|
tempInput.CopyFrame(tmpLength, inputImage.Buffer());
|
||||||
tempInput.SetWidth(tempInst.width);
|
tempInput.SetWidth(tempInst.width);
|
||||||
tempInput.SetHeight(tempInst.height);
|
tempInput.SetHeight(tempInst.height);
|
||||||
VideoFrameType videoFrameType = kDeltaFrame;
|
_encoder->Encode(tempInput, NULL, NULL);
|
||||||
_encoder->Encode(tempInput, NULL, videoFrameType);
|
|
||||||
frameLength = WaitForEncodedFrame();
|
frameLength = WaitForEncodedFrame();
|
||||||
EXPECT_TRUE(frameLength > 0);
|
EXPECT_TRUE(frameLength > 0);
|
||||||
tempInput.Free();
|
tempInput.Free();
|
||||||
@ -607,7 +605,7 @@ UnitTest::Perform()
|
|||||||
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
|
EXPECT_TRUE(_encoder->Release() == WEBRTC_VIDEO_CODEC_OK);
|
||||||
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
|
EXPECT_TRUE(_encoder->InitEncode(&_inst, 1, 1440) ==
|
||||||
WEBRTC_VIDEO_CODEC_OK);
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
_encoder->Encode(inputImage, NULL, videoFrameType);
|
_encoder->Encode(inputImage, NULL, NULL);
|
||||||
frameLength = WaitForEncodedFrame();
|
frameLength = WaitForEncodedFrame();
|
||||||
EXPECT_TRUE(frameLength > 0);
|
EXPECT_TRUE(frameLength > 0);
|
||||||
|
|
||||||
@ -666,8 +664,7 @@ UnitTest::Perform()
|
|||||||
_inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _sourceBuffer);
|
_inputVideoBuffer.CopyBuffer(_lengthSourceFrame, _sourceBuffer);
|
||||||
_inputVideoBuffer.SetTimeStamp(frames);
|
_inputVideoBuffer.SetTimeStamp(frames);
|
||||||
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
|
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
|
||||||
VideoFrameType videoFrameType = kDeltaFrame;
|
ASSERT_TRUE(_encoder->Encode(inputImage, NULL, NULL) ==
|
||||||
ASSERT_TRUE(_encoder->Encode(inputImage, NULL, videoFrameType) ==
|
|
||||||
WEBRTC_VIDEO_CODEC_OK);
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
frameLength = WaitForEncodedFrame();
|
frameLength = WaitForEncodedFrame();
|
||||||
//ASSERT_TRUE(frameLength);
|
//ASSERT_TRUE(frameLength);
|
||||||
@ -745,8 +742,7 @@ UnitTest::RateControlTests()
|
|||||||
static_cast<WebRtc_UWord32>(9e4 /
|
static_cast<WebRtc_UWord32>(9e4 /
|
||||||
static_cast<float>(_inst.maxFramerate)));
|
static_cast<float>(_inst.maxFramerate)));
|
||||||
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
|
VideoBufferToRawImage(_inputVideoBuffer, inputImage);
|
||||||
VideoFrameType videoFrameType = kDeltaFrame;
|
ASSERT_EQ(_encoder->Encode(inputImage, NULL, NULL),
|
||||||
ASSERT_EQ(_encoder->Encode(inputImage, NULL, videoFrameType),
|
|
||||||
WEBRTC_VIDEO_CODEC_OK);
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
frameLength = WaitForEncodedFrame();
|
frameLength = WaitForEncodedFrame();
|
||||||
ASSERT_GE(frameLength, 0u);
|
ASSERT_GE(frameLength, 0u);
|
||||||
|
@ -149,7 +149,6 @@ bool VP8RpsTest::EncodeRps(RpsDecodeCompleteCallback* decodeCallback) {
|
|||||||
}
|
}
|
||||||
_encodeCompleteTime = 0;
|
_encodeCompleteTime = 0;
|
||||||
_encodeTimes[rawImage.TimeStamp()] = tGetTime();
|
_encodeTimes[rawImage.TimeStamp()] = tGetTime();
|
||||||
webrtc::VideoFrameType frameType = webrtc::kDeltaFrame;
|
|
||||||
|
|
||||||
webrtc::CodecSpecificInfo* codecSpecificInfo = CreateEncoderSpecificInfo();
|
webrtc::CodecSpecificInfo* codecSpecificInfo = CreateEncoderSpecificInfo();
|
||||||
codecSpecificInfo->codecSpecific.VP8.pictureIdRPSI =
|
codecSpecificInfo->codecSpecific.VP8.pictureIdRPSI =
|
||||||
@ -162,7 +161,7 @@ bool VP8RpsTest::EncodeRps(RpsDecodeCompleteCallback* decodeCallback) {
|
|||||||
sli_ = false;
|
sli_ = false;
|
||||||
}
|
}
|
||||||
printf("Encoding: %u\n", _framecnt);
|
printf("Encoding: %u\n", _framecnt);
|
||||||
int ret = _encoder->Encode(rawImage, codecSpecificInfo, frameType);
|
int ret = _encoder->Encode(rawImage, codecSpecificInfo, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
printf("Failed to encode: %u\n", _framecnt);
|
printf("Failed to encode: %u\n", _framecnt);
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@
|
|||||||
'type': 'executable',
|
'type': 'executable',
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'webrtc_vp8',
|
'webrtc_vp8',
|
||||||
|
'<(DEPTH)/testing/gmock.gyp:gmock',
|
||||||
'<(DEPTH)/testing/gtest.gyp:gtest',
|
'<(DEPTH)/testing/gtest.gyp:gtest',
|
||||||
'<(webrtc_root)/test/test.gyp:test_support_main',
|
'<(webrtc_root)/test/test.gyp:test_support_main',
|
||||||
],
|
],
|
||||||
|
@ -326,7 +326,7 @@ uint32_t VP8EncoderImpl::MaxIntraTarget(uint32_t optimalBuffersize) {
|
|||||||
|
|
||||||
int VP8EncoderImpl::Encode(const VideoFrame& input_image,
|
int VP8EncoderImpl::Encode(const VideoFrame& input_image,
|
||||||
const CodecSpecificInfo* codec_specific_info,
|
const CodecSpecificInfo* codec_specific_info,
|
||||||
const VideoFrameType frame_type) {
|
const std::vector<VideoFrameType>* frame_types) {
|
||||||
if (!inited_) {
|
if (!inited_) {
|
||||||
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
||||||
}
|
}
|
||||||
@ -337,6 +337,12 @@ int VP8EncoderImpl::Encode(const VideoFrame& input_image,
|
|||||||
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
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.
|
// Check for change in frame size.
|
||||||
if (input_image.Width() != codec_.width ||
|
if (input_image.Width() != codec_.width ||
|
||||||
input_image.Height() != codec_.height) {
|
input_image.Height() != codec_.height) {
|
||||||
|
@ -74,7 +74,7 @@ class VP8EncoderImpl : public VP8Encoder {
|
|||||||
|
|
||||||
virtual int Encode(const VideoFrame& input_image,
|
virtual int Encode(const VideoFrame& input_image,
|
||||||
const CodecSpecificInfo* codec_specific_info,
|
const CodecSpecificInfo* codec_specific_info,
|
||||||
const VideoFrameType frame_type);
|
const std::vector<VideoFrameType>* frame_types);
|
||||||
|
|
||||||
// Register an encode complete callback object.
|
// Register an encode complete callback object.
|
||||||
//
|
//
|
||||||
|
@ -260,7 +260,7 @@ public:
|
|||||||
//
|
//
|
||||||
// Return value : VCM_OK, on success.
|
// Return value : VCM_OK, on success.
|
||||||
// < 0, on error.
|
// < 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
|
// 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
|
// over-uses its bit rate. This API is designed to be used when the encoded frames
|
||||||
|
@ -227,31 +227,30 @@ webrtc::FrameType VCMEncodedFrame::ConvertFrameType(VideoFrameType frameType)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frameType)
|
VideoFrameType VCMEncodedFrame::ConvertFrameType(webrtc::FrameType frame_type) {
|
||||||
{
|
switch (frame_type) {
|
||||||
switch (frameType)
|
|
||||||
{
|
|
||||||
case kVideoFrameKey:
|
case kVideoFrameKey:
|
||||||
{
|
return kKeyFrame;
|
||||||
return kKeyFrame;
|
|
||||||
}
|
|
||||||
case kVideoFrameDelta:
|
case kVideoFrameDelta:
|
||||||
{
|
return kDeltaFrame;
|
||||||
return kDeltaFrame;
|
|
||||||
}
|
|
||||||
case kVideoFrameGolden:
|
case kVideoFrameGolden:
|
||||||
{
|
return kGoldenFrame;
|
||||||
return kGoldenFrame;
|
|
||||||
}
|
|
||||||
case kVideoFrameAltRef:
|
case kVideoFrameAltRef:
|
||||||
{
|
return kAltRefFrame;
|
||||||
return kAltRefFrame;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
{
|
assert(false);
|
||||||
return kDeltaFrame;
|
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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_ENCODED_FRAME_H_
|
#ifndef WEBRTC_MODULES_VIDEO_CODING_ENCODED_FRAME_H_
|
||||||
#define WEBRTC_MODULES_VIDEO_CODING_ENCODED_FRAME_H_
|
#define WEBRTC_MODULES_VIDEO_CODING_ENCODED_FRAME_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "common_types.h"
|
#include "common_types.h"
|
||||||
#include "common_video/interface/video_image.h"
|
#include "common_video/interface/video_image.h"
|
||||||
#include "modules/interface/module_common_types.h"
|
#include "modules/interface/module_common_types.h"
|
||||||
@ -93,6 +95,9 @@ public:
|
|||||||
|
|
||||||
static webrtc::FrameType ConvertFrameType(VideoFrameType frameType);
|
static webrtc::FrameType ConvertFrameType(VideoFrameType frameType);
|
||||||
static VideoFrameType ConvertFrameType(webrtc::FrameType frameType);
|
static VideoFrameType ConvertFrameType(webrtc::FrameType frameType);
|
||||||
|
static void ConvertFrameTypes(
|
||||||
|
const std::vector<webrtc::FrameType>& frame_types,
|
||||||
|
std::vector<VideoFrameType>* video_frame_types);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
@ -59,9 +59,13 @@ VCMGenericEncoder::InitEncode(const VideoCodec* settings,
|
|||||||
WebRtc_Word32
|
WebRtc_Word32
|
||||||
VCMGenericEncoder::Encode(const VideoFrame& inputFrame,
|
VCMGenericEncoder::Encode(const VideoFrame& inputFrame,
|
||||||
const CodecSpecificInfo* codecSpecificInfo,
|
const CodecSpecificInfo* codecSpecificInfo,
|
||||||
const FrameType frameType) {
|
const std::vector<FrameType>* frameTypes) {
|
||||||
VideoFrameType videoFrameType = VCMEncodedFrame::ConvertFrameType(frameType);
|
std::vector<VideoFrameType> video_frame_types(frameTypes->size(),
|
||||||
return _encoder.Encode(inputFrame, codecSpecificInfo, videoFrameType);
|
kDeltaFrame);
|
||||||
|
if (frameTypes) {
|
||||||
|
VCMEncodedFrame::ConvertFrameTypes(*frameTypes, &video_frame_types);
|
||||||
|
}
|
||||||
|
return _encoder.Encode(inputFrame, codecSpecificInfo, &video_frame_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtc_Word32
|
WebRtc_Word32
|
||||||
@ -110,10 +114,17 @@ VCMGenericEncoder::SetPeriodicKeyFrames(bool enable)
|
|||||||
return _encoder.SetPeriodicKeyFrames(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;
|
VideoFrame image;
|
||||||
VideoFrameType videoFrameType = VCMEncodedFrame::ConvertFrameType(frameType);
|
std::vector<VideoFrameType> video_frame_types(kVideoFrameDelta);
|
||||||
return _encoder.Encode(image, NULL, videoFrameType);
|
if (frame_types) {
|
||||||
|
VCMEncodedFrame::ConvertFrameTypes(*frame_types, &video_frame_types);
|
||||||
|
}
|
||||||
|
return _encoder.Encode(image, NULL, &video_frame_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtc_Word32
|
WebRtc_Word32
|
||||||
|
@ -101,7 +101,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
WebRtc_Word32 Encode(const VideoFrame& inputFrame,
|
WebRtc_Word32 Encode(const VideoFrame& inputFrame,
|
||||||
const CodecSpecificInfo* codecSpecificInfo,
|
const CodecSpecificInfo* codecSpecificInfo,
|
||||||
const FrameType frameType);
|
const std::vector<FrameType>* frameTypes);
|
||||||
/**
|
/**
|
||||||
* Set new target bit rate and frame rate
|
* Set new target bit rate and frame rate
|
||||||
* Return Value: new bit rate if OK, otherwise <0s
|
* Return Value: new bit rate if OK, otherwise <0s
|
||||||
@ -127,7 +127,7 @@ public:
|
|||||||
|
|
||||||
WebRtc_Word32 SetPeriodicKeyFrames(bool enable);
|
WebRtc_Word32 SetPeriodicKeyFrames(bool enable);
|
||||||
|
|
||||||
WebRtc_Word32 RequestFrame(const FrameType frameType);
|
WebRtc_Word32 RequestFrame(const std::vector<FrameType>* frame_types);
|
||||||
|
|
||||||
bool InternalSource() const;
|
bool InternalSource() const;
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ _scheduleKeyRequest(false),
|
|||||||
_sendCritSect(CriticalSectionWrapper::CreateCriticalSection()),
|
_sendCritSect(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
_encoder(),
|
_encoder(),
|
||||||
_encodedFrameCallback(),
|
_encodedFrameCallback(),
|
||||||
_nextFrameType(kVideoFrameDelta),
|
_nextFrameTypes(1, kVideoFrameDelta),
|
||||||
_mediaOpt(id, clock_),
|
_mediaOpt(id, clock_),
|
||||||
_sendCodecType(kVideoCodecUnknown),
|
_sendCodecType(kVideoCodecUnknown),
|
||||||
_sendStatsCallback(NULL),
|
_sendStatsCallback(NULL),
|
||||||
@ -334,6 +334,9 @@ VideoCodingModuleImpl::RegisterSendCodec(const VideoCodec* sendCodec,
|
|||||||
_sendCodecType = sendCodec->codecType;
|
_sendCodecType = sendCodec->codecType;
|
||||||
int numLayers = (_sendCodecType != kVideoCodecVP8) ? 1 :
|
int numLayers = (_sendCodecType != kVideoCodecVP8) ? 1 :
|
||||||
sendCodec->codecSpecific.VP8.numberOfTemporalLayers;
|
sendCodec->codecSpecific.VP8.numberOfTemporalLayers;
|
||||||
|
_nextFrameTypes.clear();
|
||||||
|
_nextFrameTypes.resize(VCM_MAX(sendCodec->numberOfSimulcastStreams, 1),
|
||||||
|
kVideoFrameDelta);
|
||||||
|
|
||||||
_mediaOpt.SetEncodingData(_sendCodecType,
|
_mediaOpt.SetEncodingData(_sendCodecType,
|
||||||
sendCodec->maxBitrate,
|
sendCodec->maxBitrate,
|
||||||
@ -661,7 +664,9 @@ VideoCodingModuleImpl::AddVideoFrame(const VideoFrame& videoFrame,
|
|||||||
{
|
{
|
||||||
return VCM_UNINITIALIZED;
|
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;
|
return VCM_OK;
|
||||||
}
|
}
|
||||||
@ -679,7 +684,7 @@ VideoCodingModuleImpl::AddVideoFrame(const VideoFrame& videoFrame,
|
|||||||
_mediaOpt.updateContentData(contentMetrics);
|
_mediaOpt.updateContentData(contentMetrics);
|
||||||
WebRtc_Word32 ret = _encoder->Encode(videoFrame,
|
WebRtc_Word32 ret = _encoder->Encode(videoFrame,
|
||||||
codecSpecificInfo,
|
codecSpecificInfo,
|
||||||
_nextFrameType);
|
&_nextFrameTypes);
|
||||||
if (_encoderInputFile != NULL)
|
if (_encoderInputFile != NULL)
|
||||||
{
|
{
|
||||||
if (fwrite(videoFrame.Buffer(), 1, videoFrame.Length(),
|
if (fwrite(videoFrame.Buffer(), 1, videoFrame.Length(),
|
||||||
@ -695,19 +700,23 @@ VideoCodingModuleImpl::AddVideoFrame(const VideoFrame& videoFrame,
|
|||||||
"Encode error: %d", ret);
|
"Encode error: %d", ret);
|
||||||
return 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;
|
return VCM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtc_Word32 VideoCodingModuleImpl::IntraFrameRequest() {
|
WebRtc_Word32 VideoCodingModuleImpl::IntraFrameRequest(int stream_index) {
|
||||||
|
assert(stream_index >= 0);
|
||||||
CriticalSectionScoped cs(_sendCritSect);
|
CriticalSectionScoped cs(_sendCritSect);
|
||||||
_nextFrameType = kVideoFrameKey;
|
_nextFrameTypes[stream_index] = kVideoFrameKey;
|
||||||
if (_encoder != NULL && _encoder->InternalSource()) {
|
if (_encoder != NULL && _encoder->InternalSource()) {
|
||||||
// Try to request the frame if we have an external encoder with
|
// Try to request the frame if we have an external encoder with
|
||||||
// internal source since AddVideoFrame never will be called.
|
// internal source since AddVideoFrame never will be called.
|
||||||
if (_encoder->RequestFrame(_nextFrameType) == WEBRTC_VIDEO_CODEC_OK) {
|
if (_encoder->RequestFrame(&_nextFrameTypes) ==
|
||||||
_nextFrameType = kVideoFrameDelta;
|
WEBRTC_VIDEO_CODEC_OK) {
|
||||||
|
_nextFrameTypes[stream_index] = kVideoFrameDelta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VCM_OK;
|
return VCM_OK;
|
||||||
|
@ -11,19 +11,20 @@
|
|||||||
#ifndef WEBRTC_MODULES_VIDEO_CODING_VIDEO_CODING_IMPL_H_
|
#ifndef WEBRTC_MODULES_VIDEO_CODING_VIDEO_CODING_IMPL_H_
|
||||||
#define WEBRTC_MODULES_VIDEO_CODING_VIDEO_CODING_IMPL_H_
|
#define WEBRTC_MODULES_VIDEO_CODING_VIDEO_CODING_IMPL_H_
|
||||||
|
|
||||||
#include "video_coding.h"
|
#include "modules/video_coding/main/interface/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 <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
|
namespace webrtc
|
||||||
{
|
{
|
||||||
@ -147,7 +148,7 @@ public:
|
|||||||
const VideoContentMetrics* _contentMetrics = NULL,
|
const VideoContentMetrics* _contentMetrics = NULL,
|
||||||
const CodecSpecificInfo* codecSpecificInfo = NULL);
|
const CodecSpecificInfo* codecSpecificInfo = NULL);
|
||||||
|
|
||||||
virtual WebRtc_Word32 IntraFrameRequest();
|
virtual WebRtc_Word32 IntraFrameRequest(int stream_index);
|
||||||
|
|
||||||
//Enable frame dropper
|
//Enable frame dropper
|
||||||
virtual WebRtc_Word32 EnableFrameDropper(bool enable);
|
virtual WebRtc_Word32 EnableFrameDropper(bool enable);
|
||||||
@ -300,7 +301,7 @@ private:
|
|||||||
CriticalSectionWrapper* _sendCritSect; // Critical section for send side
|
CriticalSectionWrapper* _sendCritSect; // Critical section for send side
|
||||||
VCMGenericEncoder* _encoder;
|
VCMGenericEncoder* _encoder;
|
||||||
VCMEncodedFrameCallback _encodedFrameCallback;
|
VCMEncodedFrameCallback _encodedFrameCallback;
|
||||||
FrameType _nextFrameType;
|
std::vector<FrameType> _nextFrameTypes;
|
||||||
VCMMediaOptimization _mediaOpt;
|
VCMMediaOptimization _mediaOpt;
|
||||||
VideoCodecType _sendCodecType;
|
VideoCodecType _sendCodecType;
|
||||||
VCMSendStatisticsCallback* _sendStatsCallback;
|
VCMSendStatisticsCallback* _sendStatsCallback;
|
||||||
|
@ -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
|
@ -83,6 +83,7 @@
|
|||||||
'jitter_buffer_unittest.cc',
|
'jitter_buffer_unittest.cc',
|
||||||
'session_info_unittest.cc',
|
'session_info_unittest.cc',
|
||||||
'video_coding_robustness_unittest.cc',
|
'video_coding_robustness_unittest.cc',
|
||||||
|
'video_coding_impl_unittest.cc',
|
||||||
'qm_select_unittest.cc',
|
'qm_select_unittest.cc',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -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
|
// 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.
|
// and because no frame type request callback has been registered.
|
||||||
TEST(_vcm->Decode() == VCM_MISSING_CALLBACK);
|
TEST(_vcm->Decode() == VCM_MISSING_CALLBACK);
|
||||||
TEST(_vcm->IntraFrameRequest() == VCM_OK);
|
TEST(_vcm->IntraFrameRequest(0) == VCM_OK);
|
||||||
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
|
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
|
||||||
sourceFrame.SetTimeStamp(_timeStamp);
|
sourceFrame.SetTimeStamp(_timeStamp);
|
||||||
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
|
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
|
||||||
@ -250,7 +250,7 @@ CodecDataBaseTest::Perform(CmdArgs& args)
|
|||||||
sendCodec.width = _width;
|
sendCodec.width = _width;
|
||||||
sendCodec.height = _height;
|
sendCodec.height = _height;
|
||||||
TEST(_vcm->RegisterReceiveCodec(&sendCodec, 1) == VCM_OK);
|
TEST(_vcm->RegisterReceiveCodec(&sendCodec, 1) == VCM_OK);
|
||||||
TEST(_vcm->IntraFrameRequest() == VCM_OK);
|
TEST(_vcm->IntraFrameRequest(0) == VCM_OK);
|
||||||
waitEvent->Wait(33);
|
waitEvent->Wait(33);
|
||||||
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
|
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
|
||||||
sourceFrame.SetTimeStamp(_timeStamp);
|
sourceFrame.SetTimeStamp(_timeStamp);
|
||||||
@ -260,7 +260,7 @@ CodecDataBaseTest::Perform(CmdArgs& args)
|
|||||||
waitEvent->Wait(33);
|
waitEvent->Wait(33);
|
||||||
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
|
_timeStamp += (WebRtc_UWord32)(9e4 / _frameRate);
|
||||||
sourceFrame.SetTimeStamp(_timeStamp);
|
sourceFrame.SetTimeStamp(_timeStamp);
|
||||||
TEST(_vcm->IntraFrameRequest() == VCM_OK);
|
TEST(_vcm->IntraFrameRequest(0) == VCM_OK);
|
||||||
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
|
TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
|
||||||
TEST(_vcm->Decode() == VCM_OK);
|
TEST(_vcm->Decode() == VCM_OK);
|
||||||
TEST(_vcm->ResetDecoder() == VCM_OK);
|
TEST(_vcm->ResetDecoder() == VCM_OK);
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
virtual WebRtc_Word32 Encode(
|
virtual WebRtc_Word32 Encode(
|
||||||
const webrtc::VideoFrame& inputImage,
|
const webrtc::VideoFrame& inputImage,
|
||||||
const webrtc::CodecSpecificInfo* codecSpecificInfo,
|
const webrtc::CodecSpecificInfo* codecSpecificInfo,
|
||||||
const webrtc::VideoFrameType frameType);
|
const std::vector<webrtc::VideoFrameType>* frameTypes);
|
||||||
|
|
||||||
virtual WebRtc_Word32 RegisterEncodeCompleteCallback(
|
virtual WebRtc_Word32 RegisterEncodeCompleteCallback(
|
||||||
webrtc::EncodedImageCallback* callback);
|
webrtc::EncodedImageCallback* callback);
|
||||||
|
@ -120,7 +120,7 @@ WebRtc_Word32 TbI420Encoder::InitEncode(const webrtc::VideoCodec* inst,
|
|||||||
WebRtc_Word32 TbI420Encoder::Encode(
|
WebRtc_Word32 TbI420Encoder::Encode(
|
||||||
const webrtc::VideoFrame& inputImage,
|
const webrtc::VideoFrame& inputImage,
|
||||||
const webrtc::CodecSpecificInfo* /*codecSpecificInfo*/,
|
const webrtc::CodecSpecificInfo* /*codecSpecificInfo*/,
|
||||||
const webrtc::VideoFrameType /*frameType*/)
|
const std::vector<webrtc::VideoFrameType>* /*frameTypes*/)
|
||||||
{
|
{
|
||||||
_functionCalls.Encode++;
|
_functionCalls.Encode++;
|
||||||
if (!_inited)
|
if (!_inited)
|
||||||
|
@ -749,17 +749,19 @@ WebRtc_Word32 ViECapturer::InitEncode(const VideoCodec* codec_settings,
|
|||||||
return capture_encoder_->ConfigureEncoder(*codec_settings, max_payload_size);
|
return capture_encoder_->ConfigureEncoder(*codec_settings, max_payload_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtc_Word32 ViECapturer::Encode(const VideoFrame& input_image,
|
WebRtc_Word32 ViECapturer::Encode(
|
||||||
const CodecSpecificInfo* codec_specific_info,
|
const VideoFrame& input_image,
|
||||||
const VideoFrameType frame_type) {
|
const CodecSpecificInfo* codec_specific_info,
|
||||||
|
const std::vector<VideoFrameType>* frame_types) {
|
||||||
CriticalSectionScoped cs(encoding_cs_.get());
|
CriticalSectionScoped cs(encoding_cs_.get());
|
||||||
if (!capture_encoder_) {
|
if (!capture_encoder_) {
|
||||||
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
|
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);
|
return capture_encoder_->EncodeFrameType(kVideoFrameKey);
|
||||||
}
|
} else if ((*frame_types)[0] == kSkipFrame) {
|
||||||
if (frame_type == kSkipFrame) {
|
|
||||||
return capture_encoder_->EncodeFrameType(kFrameEmpty);
|
return capture_encoder_->EncodeFrameType(kFrameEmpty);
|
||||||
}
|
}
|
||||||
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#ifndef WEBRTC_VIDEO_ENGINE_VIE_CAPTURER_H_
|
#ifndef WEBRTC_VIDEO_ENGINE_VIE_CAPTURER_H_
|
||||||
#define WEBRTC_VIDEO_ENGINE_VIE_CAPTURER_H_
|
#define WEBRTC_VIDEO_ENGINE_VIE_CAPTURER_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "common_types.h" // NOLINT
|
#include "common_types.h" // NOLINT
|
||||||
#include "engine_configurations.h" // NOLINT
|
#include "engine_configurations.h" // NOLINT
|
||||||
#include "modules/video_capture/main/interface/video_capture.h"
|
#include "modules/video_capture/main/interface/video_capture.h"
|
||||||
@ -142,7 +144,7 @@ class ViECapturer
|
|||||||
WebRtc_UWord32 max_payload_size);
|
WebRtc_UWord32 max_payload_size);
|
||||||
virtual WebRtc_Word32 Encode(const VideoFrame& input_image,
|
virtual WebRtc_Word32 Encode(const VideoFrame& input_image,
|
||||||
const CodecSpecificInfo* codec_specific_info,
|
const CodecSpecificInfo* codec_specific_info,
|
||||||
const VideoFrameType frame_type);
|
const std::vector<VideoFrameType>* frame_types);
|
||||||
virtual WebRtc_Word32 RegisterEncodeCompleteCallback(
|
virtual WebRtc_Word32 RegisterEncodeCompleteCallback(
|
||||||
EncodedImageCallback* callback);
|
EncodedImageCallback* callback);
|
||||||
virtual WebRtc_Word32 Release();
|
virtual WebRtc_Word32 Release();
|
||||||
|
@ -585,7 +585,7 @@ int ViEEncoder::GetPreferedFrameSettings(int* width,
|
|||||||
int ViEEncoder::SendKeyFrame() {
|
int ViEEncoder::SendKeyFrame() {
|
||||||
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
|
||||||
ViEId(engine_id_, channel_id_), "%s", __FUNCTION__);
|
ViEId(engine_id_, channel_id_), "%s", __FUNCTION__);
|
||||||
return vcm_.IntraFrameRequest();
|
return vcm_.IntraFrameRequest(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtc_Word32 ViEEncoder::SendCodecStatistics(
|
WebRtc_Word32 ViEEncoder::SendCodecStatistics(
|
||||||
@ -818,7 +818,7 @@ void ViEEncoder::OnReceivedIntraFrameRequest(uint32_t /*ssrc*/) {
|
|||||||
"%s: Not not encoding new intra due to timing", __FUNCTION__);
|
"%s: Not not encoding new intra due to timing", __FUNCTION__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vcm_.IntraFrameRequest();
|
vcm_.IntraFrameRequest(0);
|
||||||
time_last_intra_request_ms_ = now;
|
time_last_intra_request_ms_ = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user