Revert of Deprecate VCMPacketizationCallback::SendData and use EncodedImageCallback instead. (patchset #5 id:80001 of https://codereview.webrtc.org/1897233002/ )

Reason for revert:
API changes broke downstream.

Original issue's description:
> Deprecate VCMPacketizationCallback::SendData and use EncodedImageCallback instead.
> EncodedImageCallback is used by all encoder implementations and seems to be what we should try to use in the transport.
> EncodedImageCallback can of course be cleaned up in the future.
>
> This moves creation of RTPVideoHeader from the GenericEncoder to the PayLoadRouter.
>
> BUG=webrtc::5687
>
> Committed: https://crrev.com/f5d55aaecdc39e9cc66eb6e87614f04afe28f6eb
> Cr-Commit-Position: refs/heads/master@{#12436}

TBR=stefan@webrtc.org,pbos@webrtc.org,perkj@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc::5687

Review URL: https://codereview.webrtc.org/1903193002

Cr-Commit-Position: refs/heads/master@{#12441}
This commit is contained in:
kjellander
2016-04-20 04:13:23 -07:00
committed by Commit bot
parent 049da04a7a
commit a261e61366
23 changed files with 333 additions and 333 deletions

View File

@ -238,6 +238,7 @@ bool VCMCodecDataBase::SetSendCodec(const VideoCodec* send_codec,
memcpy(&send_codec_, &new_send_codec, sizeof(send_codec_));
if (!reset_required) {
encoded_frame_callback_->SetPayloadType(send_codec_.plType);
return true;
}
@ -248,6 +249,7 @@ bool VCMCodecDataBase::SetSendCodec(const VideoCodec* send_codec,
ptr_encoder_.reset(
new VCMGenericEncoder(external_encoder_, encoder_rate_observer_,
encoded_frame_callback_, internal_source_));
encoded_frame_callback_->SetPayloadType(send_codec_.plType);
encoded_frame_callback_->SetInternalSource(internal_source_);
if (ptr_encoder_->InitEncode(&send_codec_, number_of_cores_,
max_payload_size_) < 0) {

View File

@ -21,6 +21,76 @@
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
namespace webrtc {
namespace {
// Map information from info into rtp. If no relevant information is found
// in info, rtp is set to NULL.
void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader* rtp) {
RTC_DCHECK(info);
switch (info->codecType) {
case kVideoCodecVP8: {
rtp->codec = kRtpVideoVp8;
rtp->codecHeader.VP8.InitRTPVideoHeaderVP8();
rtp->codecHeader.VP8.pictureId = info->codecSpecific.VP8.pictureId;
rtp->codecHeader.VP8.nonReference = info->codecSpecific.VP8.nonReference;
rtp->codecHeader.VP8.temporalIdx = info->codecSpecific.VP8.temporalIdx;
rtp->codecHeader.VP8.layerSync = info->codecSpecific.VP8.layerSync;
rtp->codecHeader.VP8.tl0PicIdx = info->codecSpecific.VP8.tl0PicIdx;
rtp->codecHeader.VP8.keyIdx = info->codecSpecific.VP8.keyIdx;
rtp->simulcastIdx = info->codecSpecific.VP8.simulcastIdx;
return;
}
case kVideoCodecVP9: {
rtp->codec = kRtpVideoVp9;
rtp->codecHeader.VP9.InitRTPVideoHeaderVP9();
rtp->codecHeader.VP9.inter_pic_predicted =
info->codecSpecific.VP9.inter_pic_predicted;
rtp->codecHeader.VP9.flexible_mode =
info->codecSpecific.VP9.flexible_mode;
rtp->codecHeader.VP9.ss_data_available =
info->codecSpecific.VP9.ss_data_available;
rtp->codecHeader.VP9.picture_id = info->codecSpecific.VP9.picture_id;
rtp->codecHeader.VP9.tl0_pic_idx = info->codecSpecific.VP9.tl0_pic_idx;
rtp->codecHeader.VP9.temporal_idx = info->codecSpecific.VP9.temporal_idx;
rtp->codecHeader.VP9.spatial_idx = info->codecSpecific.VP9.spatial_idx;
rtp->codecHeader.VP9.temporal_up_switch =
info->codecSpecific.VP9.temporal_up_switch;
rtp->codecHeader.VP9.inter_layer_predicted =
info->codecSpecific.VP9.inter_layer_predicted;
rtp->codecHeader.VP9.gof_idx = info->codecSpecific.VP9.gof_idx;
rtp->codecHeader.VP9.num_spatial_layers =
info->codecSpecific.VP9.num_spatial_layers;
if (info->codecSpecific.VP9.ss_data_available) {
rtp->codecHeader.VP9.spatial_layer_resolution_present =
info->codecSpecific.VP9.spatial_layer_resolution_present;
if (info->codecSpecific.VP9.spatial_layer_resolution_present) {
for (size_t i = 0; i < info->codecSpecific.VP9.num_spatial_layers;
++i) {
rtp->codecHeader.VP9.width[i] = info->codecSpecific.VP9.width[i];
rtp->codecHeader.VP9.height[i] = info->codecSpecific.VP9.height[i];
}
}
rtp->codecHeader.VP9.gof.CopyGofInfoVP9(info->codecSpecific.VP9.gof);
}
rtp->codecHeader.VP9.num_ref_pics = info->codecSpecific.VP9.num_ref_pics;
for (int i = 0; i < info->codecSpecific.VP9.num_ref_pics; ++i)
rtp->codecHeader.VP9.pid_diff[i] = info->codecSpecific.VP9.p_diff[i];
return;
}
case kVideoCodecH264:
rtp->codec = kRtpVideoH264;
return;
case kVideoCodecGeneric:
rtp->codec = kRtpVideoGeneric;
rtp->simulcastIdx = info->codecSpecific.generic.simulcast_idx;
return;
default:
return;
}
}
} // namespace
VCMGenericEncoder::VCMGenericEncoder(
VideoEncoder* encoder,
VideoEncoderRateObserver* rate_observer,
@ -146,6 +216,7 @@ VCMEncodedFrameCallback::VCMEncodedFrameCallback(
EncodedImageCallback* post_encode_callback)
: send_callback_(),
media_opt_(nullptr),
payload_type_(0),
internal_source_(false),
post_encode_callback_(post_encode_callback) {}
@ -163,8 +234,19 @@ int32_t VCMEncodedFrameCallback::Encoded(
const RTPFragmentationHeader* fragmentation_header) {
TRACE_EVENT_INSTANT1("webrtc", "VCMEncodedFrameCallback::Encoded",
"timestamp", encoded_image._timeStamp);
int ret_val = post_encode_callback_->Encoded(encoded_image, codec_specific,
fragmentation_header);
post_encode_callback_->Encoded(encoded_image, nullptr, nullptr);
if (send_callback_ == nullptr)
return VCM_UNINITIALIZED;
RTPVideoHeader rtp_video_header;
memset(&rtp_video_header, 0, sizeof(RTPVideoHeader));
if (codec_specific)
CopyCodecSpecific(codec_specific, &rtp_video_header);
rtp_video_header.rotation = encoded_image.rotation_;
int32_t ret_val = send_callback_->SendData(
payload_type_, encoded_image, fragmentation_header, &rtp_video_header);
if (ret_val < 0)
return ret_val;

View File

@ -44,6 +44,7 @@ class VCMEncodedFrameCallback : public EncodedImageCallback {
const RTPFragmentationHeader* fragmentation_header) override;
int32_t SetTransportCallback(VCMPacketizationCallback* transport);
void SetMediaOpt(media_optimization::MediaOptimization* media_opt);
void SetPayloadType(uint8_t payload_type) { payload_type_ = payload_type; }
void SetInternalSource(bool internal_source) {
internal_source_ = internal_source;
}
@ -53,6 +54,7 @@ class VCMEncodedFrameCallback : public EncodedImageCallback {
private:
VCMPacketizationCallback* send_callback_;
media_optimization::MediaOptimization* media_opt_;
uint8_t payload_type_;
bool internal_source_;
EncodedImageCallback* post_encode_callback_;

View File

@ -57,11 +57,13 @@ struct VCMFrameCount {
};
// Callback class used for sending data ready to be packetized
// Deprecated.
// TODO(perkj): Remove once OnEncoderImplementationName is not used.
class VCMPacketizationCallback {
public:
// TODO(perkj): Refactor this. It does not belong in VCMPacketizationCallback.
virtual int32_t SendData(uint8_t payloadType,
const EncodedImage& encoded_image,
const RTPFragmentationHeader* fragmentationHeader,
const RTPVideoHeader* rtpVideoHdr) = 0;
virtual void OnEncoderImplementationName(const char* implementation_name) {}
protected:

View File

@ -18,7 +18,7 @@ namespace webrtc {
IvfFileWriter::IvfFileWriter(const std::string& file_name,
std::unique_ptr<FileWrapper> file,
VideoCodecType codec_type)
RtpVideoCodecTypes codec_type)
: codec_type_(codec_type),
num_frames_(0),
width_(0),
@ -34,8 +34,9 @@ IvfFileWriter::~IvfFileWriter() {
const size_t kIvfHeaderSize = 32;
std::unique_ptr<IvfFileWriter> IvfFileWriter::Open(const std::string& file_name,
VideoCodecType codec_type) {
std::unique_ptr<IvfFileWriter> IvfFileWriter::Open(
const std::string& file_name,
RtpVideoCodecTypes codec_type) {
std::unique_ptr<IvfFileWriter> file_writer;
std::unique_ptr<FileWrapper> file(FileWrapper::Create());
if (file->OpenFile(file_name.c_str(), false) != 0)
@ -64,19 +65,19 @@ bool IvfFileWriter::WriteHeader() {
ByteWriter<uint16_t>::WriteLittleEndian(&ivf_header[6], 32); // Header size.
switch (codec_type_) {
case kVideoCodecVP8:
case kRtpVideoVp8:
ivf_header[8] = 'V';
ivf_header[9] = 'P';
ivf_header[10] = '8';
ivf_header[11] = '0';
break;
case kVideoCodecVP9:
case kRtpVideoVp9:
ivf_header[8] = 'V';
ivf_header[9] = 'P';
ivf_header[10] = '9';
ivf_header[11] = '0';
break;
case kVideoCodecH264:
case kRtpVideoH264:
ivf_header[8] = 'H';
ivf_header[9] = '2';
ivf_header[10] = '6';

View File

@ -27,18 +27,18 @@ class IvfFileWriter {
~IvfFileWriter();
static std::unique_ptr<IvfFileWriter> Open(const std::string& file_name,
VideoCodecType codec_type);
RtpVideoCodecTypes codec_type);
bool WriteFrame(const EncodedImage& encoded_image);
bool Close();
private:
IvfFileWriter(const std::string& path_name,
std::unique_ptr<FileWrapper> file,
VideoCodecType codec_type);
RtpVideoCodecTypes codec_type);
bool WriteHeader();
bool InitFromFirstFrame(const EncodedImage& encoded_image);
const VideoCodecType codec_type_;
const RtpVideoCodecTypes codec_type_;
size_t num_frames_;
uint16_t width_;
uint16_t height_;

View File

@ -103,7 +103,7 @@ class IvfFileWriterTest : public ::testing::Test {
}
}
void RunBasicFileStructureTest(VideoCodecType codec_type,
void RunBasicFileStructureTest(RtpVideoCodecTypes codec_type,
const uint8_t fourcc[4],
bool use_capture_tims_ms) {
file_writer_ = IvfFileWriter::Open(file_name_, codec_type);
@ -135,7 +135,7 @@ class IvfFileWriterTest : public ::testing::Test {
};
TEST_F(IvfFileWriterTest, RemovesUnusedFile) {
file_writer_ = IvfFileWriter::Open(file_name_, kVideoCodecVP8);
file_writer_ = IvfFileWriter::Open(file_name_, kRtpVideoVp8);
ASSERT_TRUE(file_writer_.get() != nullptr);
EXPECT_TRUE(FileExists());
EXPECT_TRUE(file_writer_->Close());
@ -145,32 +145,32 @@ TEST_F(IvfFileWriterTest, RemovesUnusedFile) {
TEST_F(IvfFileWriterTest, WritesBasicVP8FileNtpTimestamp) {
const uint8_t fourcc[4] = {'V', 'P', '8', '0'};
RunBasicFileStructureTest(kVideoCodecVP8, fourcc, false);
RunBasicFileStructureTest(kRtpVideoVp8, fourcc, false);
}
TEST_F(IvfFileWriterTest, WritesBasicVP8FileMsTimestamp) {
const uint8_t fourcc[4] = {'V', 'P', '8', '0'};
RunBasicFileStructureTest(kVideoCodecVP8, fourcc, true);
RunBasicFileStructureTest(kRtpVideoVp8, fourcc, true);
}
TEST_F(IvfFileWriterTest, WritesBasicVP9FileNtpTimestamp) {
const uint8_t fourcc[4] = {'V', 'P', '9', '0'};
RunBasicFileStructureTest(kVideoCodecVP9, fourcc, false);
RunBasicFileStructureTest(kRtpVideoVp9, fourcc, false);
}
TEST_F(IvfFileWriterTest, WritesBasicVP9FileMsTimestamp) {
const uint8_t fourcc[4] = {'V', 'P', '9', '0'};
RunBasicFileStructureTest(kVideoCodecVP9, fourcc, true);
RunBasicFileStructureTest(kRtpVideoVp9, fourcc, true);
}
TEST_F(IvfFileWriterTest, WritesBasicH264FileNtpTimestamp) {
const uint8_t fourcc[4] = {'H', '2', '6', '4'};
RunBasicFileStructureTest(kVideoCodecH264, fourcc, false);
RunBasicFileStructureTest(kRtpVideoH264, fourcc, false);
}
TEST_F(IvfFileWriterTest, WritesBasicH264FileMsTimestamp) {
const uint8_t fourcc[4] = {'H', '2', '6', '4'};
RunBasicFileStructureTest(kVideoCodecH264, fourcc, true);
RunBasicFileStructureTest(kRtpVideoH264, fourcc, true);
}
} // namespace webrtc

View File

@ -54,6 +54,7 @@ class EncodedImageCallbackWrapper : public EncodedImageCallback {
callback_ = callback;
}
// TODO(andresp): Change to void as return value is ignored.
virtual int32_t Encoded(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) {

View File

@ -79,8 +79,6 @@ class VideoSender {
uint8_t lossRate,
int64_t rtt);
// Deprecated. Use |post_encode_callback| instead.
// TODO(perkj): Remove once |OnEncoderImplementationName| is not used.
int32_t RegisterTransportCallback(VCMPacketizationCallback* transport);
int32_t RegisterSendStatisticsCallback(VCMSendStatisticsCallback* sendStats);
int32_t RegisterProtectionCallback(VCMProtectionCallback* protection);

View File

@ -86,19 +86,19 @@ class EmptyFrameGenerator : public FrameGenerator {
std::unique_ptr<VideoFrame> frame_;
};
class EncodedImageCallbackImpl : public EncodedImageCallback {
class PacketizationCallback : public VCMPacketizationCallback {
public:
explicit EncodedImageCallbackImpl(Clock* clock)
explicit PacketizationCallback(Clock* clock)
: clock_(clock), start_time_ms_(clock_->TimeInMilliseconds()) {}
virtual ~EncodedImageCallbackImpl() {}
virtual ~PacketizationCallback() {}
int32_t Encoded(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) override {
assert(codec_specific_info);
frame_data_.push_back(
FrameData(encoded_image._length, *codec_specific_info));
int32_t SendData(uint8_t payload_type,
const EncodedImage& encoded_image,
const RTPFragmentationHeader* fragmentation_header,
const RTPVideoHeader* rtp_video_header) override {
assert(rtp_video_header);
frame_data_.push_back(FrameData(encoded_image._length, *rtp_video_header));
return 0;
}
@ -130,12 +130,11 @@ class EncodedImageCallbackImpl : public EncodedImageCallback {
struct FrameData {
FrameData() {}
FrameData(size_t payload_size, const CodecSpecificInfo& codec_specific_info)
: payload_size(payload_size),
codec_specific_info(codec_specific_info) {}
FrameData(size_t payload_size, const RTPVideoHeader& rtp_video_header)
: payload_size(payload_size), rtp_video_header(rtp_video_header) {}
size_t payload_size;
CodecSpecificInfo codec_specific_info;
RTPVideoHeader rtp_video_header;
};
int64_t interval_ms() {
@ -147,9 +146,9 @@ class EncodedImageCallbackImpl : public EncodedImageCallback {
int CountFramesWithinTemporalLayer(int temporal_layer) {
int frames = 0;
for (size_t i = 0; i < frame_data_.size(); ++i) {
EXPECT_EQ(kVideoCodecVP8, frame_data_[i].codec_specific_info.codecType);
EXPECT_EQ(kRtpVideoVp8, frame_data_[i].rtp_video_header.codec);
const uint8_t temporal_idx =
frame_data_[i].codec_specific_info.codecSpecific.VP8.temporalIdx;
frame_data_[i].rtp_video_header.codecHeader.VP8.temporalIdx;
if (temporal_idx <= temporal_layer || temporal_idx == kNoTemporalIdx)
frames++;
}
@ -159,9 +158,9 @@ class EncodedImageCallbackImpl : public EncodedImageCallback {
size_t SumPayloadBytesWithinTemporalLayer(int temporal_layer) {
size_t payload_size = 0;
for (size_t i = 0; i < frame_data_.size(); ++i) {
EXPECT_EQ(kVideoCodecVP8, frame_data_[i].codec_specific_info.codecType);
EXPECT_EQ(kRtpVideoVp8, frame_data_[i].rtp_video_header.codec);
const uint8_t temporal_idx =
frame_data_[i].codec_specific_info.codecSpecific.VP8.temporalIdx;
frame_data_[i].rtp_video_header.codecHeader.VP8.temporalIdx;
if (temporal_idx <= temporal_layer || temporal_idx == kNoTemporalIdx)
payload_size += frame_data_[i].payload_size;
}
@ -177,11 +176,12 @@ class TestVideoSender : public ::testing::Test {
protected:
// Note: simulated clock starts at 1 seconds, since parts of webrtc use 0 as
// a special case (e.g. frame rate in media optimization).
TestVideoSender() : clock_(1000), encoded_frame_callback_(&clock_) {}
TestVideoSender() : clock_(1000), packetization_callback_(&clock_) {}
void SetUp() override {
sender_.reset(
new VideoSender(&clock_, &encoded_frame_callback_, nullptr, nullptr));
new VideoSender(&clock_, &post_encode_callback_, nullptr, nullptr));
EXPECT_EQ(0, sender_->RegisterTransportCallback(&packetization_callback_));
}
void AddFrame() {
@ -190,7 +190,8 @@ class TestVideoSender : public ::testing::Test {
}
SimulatedClock clock_;
EncodedImageCallbackImpl encoded_frame_callback_;
PacketizationCallback packetization_callback_;
MockEncodedImageCallback post_encode_callback_;
// Used by subclassing tests, need to outlive sender_.
std::unique_ptr<VideoEncoder> encoder_;
std::unique_ptr<VideoSender> sender_;
@ -414,6 +415,8 @@ class TestVideoSenderWithVp8 : public TestVideoSender {
void InsertFrames(float framerate, float seconds) {
for (int i = 0; i < seconds * framerate; ++i) {
clock_.AdvanceTimeMilliseconds(1000.0f / framerate);
EXPECT_CALL(post_encode_callback_, Encoded(_, NULL, NULL))
.WillOnce(Return(0));
AddFrame();
// SetChannelParameters needs to be called frequently to propagate
// framerate from the media optimization into the encoder.
@ -432,10 +435,10 @@ class TestVideoSenderWithVp8 : public TestVideoSender {
// It appears that this 5 seconds simulation is needed to allow
// bitrate and framerate to stabilize.
InsertFrames(framerate, short_simulation_interval);
encoded_frame_callback_.Reset();
packetization_callback_.Reset();
InsertFrames(framerate, long_simulation_interval);
return encoded_frame_callback_.CalculateVp8StreamInfo();
return packetization_callback_.CalculateVp8StreamInfo();
}
protected:

View File

@ -35,7 +35,6 @@ class MockVieEncoder : public ViEEncoder {
nullptr,
nullptr,
pacer,
nullptr,
nullptr) {}
~MockVieEncoder() {}

View File

@ -13,85 +13,11 @@
#include "webrtc/base/checks.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
namespace webrtc {
namespace {
// Map information from info into rtp.
void CopyCodecSpecific(const CodecSpecificInfo* info, RTPVideoHeader* rtp) {
RTC_DCHECK(info);
switch (info->codecType) {
case kVideoCodecVP8: {
rtp->codec = kRtpVideoVp8;
rtp->codecHeader.VP8.InitRTPVideoHeaderVP8();
rtp->codecHeader.VP8.pictureId = info->codecSpecific.VP8.pictureId;
rtp->codecHeader.VP8.nonReference = info->codecSpecific.VP8.nonReference;
rtp->codecHeader.VP8.temporalIdx = info->codecSpecific.VP8.temporalIdx;
rtp->codecHeader.VP8.layerSync = info->codecSpecific.VP8.layerSync;
rtp->codecHeader.VP8.tl0PicIdx = info->codecSpecific.VP8.tl0PicIdx;
rtp->codecHeader.VP8.keyIdx = info->codecSpecific.VP8.keyIdx;
rtp->simulcastIdx = info->codecSpecific.VP8.simulcastIdx;
return;
}
case kVideoCodecVP9: {
rtp->codec = kRtpVideoVp9;
rtp->codecHeader.VP9.InitRTPVideoHeaderVP9();
rtp->codecHeader.VP9.inter_pic_predicted =
info->codecSpecific.VP9.inter_pic_predicted;
rtp->codecHeader.VP9.flexible_mode =
info->codecSpecific.VP9.flexible_mode;
rtp->codecHeader.VP9.ss_data_available =
info->codecSpecific.VP9.ss_data_available;
rtp->codecHeader.VP9.picture_id = info->codecSpecific.VP9.picture_id;
rtp->codecHeader.VP9.tl0_pic_idx = info->codecSpecific.VP9.tl0_pic_idx;
rtp->codecHeader.VP9.temporal_idx = info->codecSpecific.VP9.temporal_idx;
rtp->codecHeader.VP9.spatial_idx = info->codecSpecific.VP9.spatial_idx;
rtp->codecHeader.VP9.temporal_up_switch =
info->codecSpecific.VP9.temporal_up_switch;
rtp->codecHeader.VP9.inter_layer_predicted =
info->codecSpecific.VP9.inter_layer_predicted;
rtp->codecHeader.VP9.gof_idx = info->codecSpecific.VP9.gof_idx;
rtp->codecHeader.VP9.num_spatial_layers =
info->codecSpecific.VP9.num_spatial_layers;
if (info->codecSpecific.VP9.ss_data_available) {
rtp->codecHeader.VP9.spatial_layer_resolution_present =
info->codecSpecific.VP9.spatial_layer_resolution_present;
if (info->codecSpecific.VP9.spatial_layer_resolution_present) {
for (size_t i = 0; i < info->codecSpecific.VP9.num_spatial_layers;
++i) {
rtp->codecHeader.VP9.width[i] = info->codecSpecific.VP9.width[i];
rtp->codecHeader.VP9.height[i] = info->codecSpecific.VP9.height[i];
}
}
rtp->codecHeader.VP9.gof.CopyGofInfoVP9(info->codecSpecific.VP9.gof);
}
rtp->codecHeader.VP9.num_ref_pics = info->codecSpecific.VP9.num_ref_pics;
for (int i = 0; i < info->codecSpecific.VP9.num_ref_pics; ++i)
rtp->codecHeader.VP9.pid_diff[i] = info->codecSpecific.VP9.p_diff[i];
return;
}
case kVideoCodecH264:
rtp->codec = kRtpVideoH264;
return;
case kVideoCodecGeneric:
rtp->codec = kRtpVideoGeneric;
rtp->simulcastIdx = info->codecSpecific.generic.simulcast_idx;
return;
default:
return;
}
}
} // namespace
PayloadRouter::PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules,
int payload_type)
: active_(false),
num_sending_modules_(1),
rtp_modules_(rtp_modules),
payload_type_(payload_type) {
PayloadRouter::PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules)
: active_(false), num_sending_modules_(1), rtp_modules_(rtp_modules) {
UpdateModuleSendingState();
}
@ -134,33 +60,31 @@ void PayloadRouter::UpdateModuleSendingState() {
}
}
int32_t PayloadRouter::Encoded(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) {
bool PayloadRouter::RoutePayload(FrameType frame_type,
int8_t payload_type,
uint32_t time_stamp,
int64_t capture_time_ms,
const uint8_t* payload_data,
size_t payload_length,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* rtp_video_hdr) {
rtc::CritScope lock(&crit_);
RTC_DCHECK(!rtp_modules_.empty());
if (!active_ || num_sending_modules_ == 0)
return -1;
return false;
int stream_idx = 0;
RTPVideoHeader rtp_video_header;
memset(&rtp_video_header, 0, sizeof(RTPVideoHeader));
if (codec_specific_info)
CopyCodecSpecific(codec_specific_info, &rtp_video_header);
rtp_video_header.rotation = encoded_image.rotation_;
RTC_DCHECK_LT(rtp_video_header.simulcastIdx, rtp_modules_.size());
if (rtp_video_hdr) {
RTC_DCHECK_LT(rtp_video_hdr->simulcastIdx, rtp_modules_.size());
// The simulcast index might actually be larger than the number of modules
// in case the encoder was processing a frame during a codec reconfig.
if (rtp_video_header.simulcastIdx >= num_sending_modules_)
return -1;
stream_idx = rtp_video_header.simulcastIdx;
if (rtp_video_hdr->simulcastIdx >= num_sending_modules_)
return false;
stream_idx = rtp_video_hdr->simulcastIdx;
}
return rtp_modules_[stream_idx]->SendOutgoingData(
encoded_image._frameType, payload_type_, encoded_image._timeStamp,
encoded_image.capture_time_ms_, encoded_image._buffer,
encoded_image._length, fragmentation, &rtp_video_header);
frame_type, payload_type, time_stamp, capture_time_ms, payload_data,
payload_length, fragmentation, rtp_video_hdr) == 0 ? true : false;
}
void PayloadRouter::SetTargetSendBitrates(

View File

@ -17,7 +17,6 @@
#include "webrtc/base/criticalsection.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/common_types.h"
#include "webrtc/video_encoder.h"
#include "webrtc/system_wrappers/include/atomic32.h"
namespace webrtc {
@ -28,11 +27,10 @@ struct RTPVideoHeader;
// PayloadRouter routes outgoing data to the correct sending RTP module, based
// on the simulcast layer in RTPVideoHeader.
class PayloadRouter : public EncodedImageCallback {
class PayloadRouter {
public:
// Rtp modules are assumed to be sorted in simulcast index order.
explicit PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules,
int payload_type);
explicit PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules);
~PayloadRouter();
static size_t DefaultMaxPayloadLength();
@ -43,11 +41,16 @@ class PayloadRouter : public EncodedImageCallback {
void set_active(bool active);
bool active();
// Implements EncodedImageCallback.
// Returns 0 if the packet was routed / sent, -1 otherwise.
int32_t Encoded(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) override;
// Input parameters according to the signature of RtpRtcp::SendOutgoingData.
// Returns true if the packet was routed / sent, false otherwise.
bool RoutePayload(FrameType frame_type,
int8_t payload_type,
uint32_t time_stamp,
int64_t capture_time_ms,
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation,
const RTPVideoHeader* rtp_video_hdr);
// Configures current target bitrate per module. 'stream_bitrates' is assumed
// to be in the same order as 'SetSendingRtpModules'.
@ -66,7 +69,6 @@ class PayloadRouter : public EncodedImageCallback {
// Rtp modules are assumed to be sorted in simulcast index order. Not owned.
const std::vector<RtpRtcp*> rtp_modules_;
const int payload_type_;
RTC_DISALLOW_COPY_AND_ASSIGN(PayloadRouter);
};

View File

@ -14,7 +14,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/video/payload_router.h"
using ::testing::_;
@ -28,56 +27,46 @@ TEST(PayloadRouterTest, SendOnOneModule) {
MockRtpRtcp rtp;
std::vector<RtpRtcp*> modules(1, &rtp);
uint8_t payload = 'a';
int8_t payload_type = 96;
EncodedImage encoded_image;
encoded_image._timeStamp = 1;
encoded_image.capture_time_ms_ = 2;
encoded_image._frameType = kVideoFrameKey;
encoded_image._buffer = &payload;
encoded_image._length = 1;
PayloadRouter payload_router(modules, payload_type);
PayloadRouter payload_router(modules);
payload_router.SetSendingRtpModules(modules.size());
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _))
uint8_t payload = 'a';
FrameType frame_type = kVideoFrameKey;
int8_t payload_type = 96;
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(0);
EXPECT_EQ(-1, payload_router.Encoded(encoded_image, nullptr, nullptr));
EXPECT_FALSE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
&payload, 1, nullptr, nullptr));
payload_router.set_active(true);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _))
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(1);
EXPECT_EQ(0, payload_router.Encoded(encoded_image, nullptr, nullptr));
EXPECT_TRUE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
&payload, 1, nullptr, nullptr));
payload_router.set_active(false);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _))
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(0);
EXPECT_EQ(-1, payload_router.Encoded(encoded_image, nullptr, nullptr));
EXPECT_FALSE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
&payload, 1, nullptr, nullptr));
payload_router.set_active(true);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _))
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(1);
EXPECT_EQ(0, payload_router.Encoded(encoded_image, nullptr, nullptr));
EXPECT_TRUE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
&payload, 1, nullptr, nullptr));
payload_router.SetSendingRtpModules(0);
EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _))
EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
nullptr, nullptr))
.Times(0);
EXPECT_EQ(-1, payload_router.Encoded(encoded_image, nullptr, nullptr));
EXPECT_FALSE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
&payload, 1, nullptr, nullptr));
}
TEST(PayloadRouterTest, SendSimulcast) {
@ -87,46 +76,36 @@ TEST(PayloadRouterTest, SendSimulcast) {
modules.push_back(&rtp_1);
modules.push_back(&rtp_2);
int8_t payload_type = 96;
uint8_t payload = 'a';
EncodedImage encoded_image;
encoded_image._timeStamp = 1;
encoded_image.capture_time_ms_ = 2;
encoded_image._frameType = kVideoFrameKey;
encoded_image._buffer = &payload;
encoded_image._length = 1;
PayloadRouter payload_router(modules, payload_type);
PayloadRouter payload_router(modules);
payload_router.SetSendingRtpModules(modules.size());
CodecSpecificInfo codec_info_1;
memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
codec_info_1.codecType = kVideoCodecVP8;
codec_info_1.codecSpecific.VP8.simulcastIdx = 0;
uint8_t payload_1 = 'a';
FrameType frame_type_1 = kVideoFrameKey;
int8_t payload_type_1 = 96;
RTPVideoHeader rtp_hdr_1;
rtp_hdr_1.simulcastIdx = 0;
payload_router.set_active(true);
EXPECT_CALL(rtp_1, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _))
EXPECT_CALL(rtp_1, SendOutgoingData(frame_type_1, payload_type_1, 0, 0, _, 1,
nullptr, &rtp_hdr_1))
.Times(1);
EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
EXPECT_EQ(0, payload_router.Encoded(encoded_image, &codec_info_1, nullptr));
EXPECT_TRUE(payload_router.RoutePayload(frame_type_1, payload_type_1, 0, 0,
&payload_1, 1, nullptr, &rtp_hdr_1));
CodecSpecificInfo codec_info_2;
memset(&codec_info_2, 0, sizeof(CodecSpecificInfo));
codec_info_2.codecType = kVideoCodecVP8;
codec_info_2.codecSpecific.VP8.simulcastIdx = 1;
EXPECT_CALL(rtp_2, SendOutgoingData(encoded_image._frameType, payload_type,
encoded_image._timeStamp,
encoded_image.capture_time_ms_, &payload,
encoded_image._length, nullptr, _))
uint8_t payload_2 = 'b';
FrameType frame_type_2 = kVideoFrameDelta;
int8_t payload_type_2 = 97;
RTPVideoHeader rtp_hdr_2;
rtp_hdr_2.simulcastIdx = 1;
EXPECT_CALL(rtp_2, SendOutgoingData(frame_type_2, payload_type_2, 0, 0, _, 1,
nullptr, &rtp_hdr_2))
.Times(1);
EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
EXPECT_EQ(0, payload_router.Encoded(encoded_image, &codec_info_2, nullptr));
EXPECT_TRUE(payload_router.RoutePayload(frame_type_2, payload_type_2, 0, 0,
&payload_2, 1, nullptr, &rtp_hdr_2));
// Inactive.
payload_router.set_active(false);
@ -134,8 +113,10 @@ TEST(PayloadRouterTest, SendSimulcast) {
.Times(0);
EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
EXPECT_EQ(-1, payload_router.Encoded(encoded_image, &codec_info_1, nullptr));
EXPECT_EQ(-1, payload_router.Encoded(encoded_image, &codec_info_2, nullptr));
EXPECT_FALSE(payload_router.RoutePayload(frame_type_1, payload_type_1, 0, 0,
&payload_1, 1, nullptr, &rtp_hdr_1));
EXPECT_FALSE(payload_router.RoutePayload(frame_type_2, payload_type_2, 0, 0,
&payload_2, 1, nullptr, &rtp_hdr_2));
// Invalid simulcast index.
payload_router.SetSendingRtpModules(1);
@ -144,8 +125,9 @@ TEST(PayloadRouterTest, SendSimulcast) {
.Times(0);
EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
.Times(0);
codec_info_2.codecSpecific.VP8.simulcastIdx = 1;
EXPECT_EQ(-1, payload_router.Encoded(encoded_image, &codec_info_2, nullptr));
rtp_hdr_1.simulcastIdx = 1;
EXPECT_FALSE(payload_router.RoutePayload(frame_type_1, payload_type_1, 0, 0,
&payload_1, 1, nullptr, &rtp_hdr_1));
}
TEST(PayloadRouterTest, MaxPayloadLength) {
@ -157,7 +139,7 @@ TEST(PayloadRouterTest, MaxPayloadLength) {
std::vector<RtpRtcp*> modules;
modules.push_back(&rtp_1);
modules.push_back(&rtp_2);
PayloadRouter payload_router(modules, 42);
PayloadRouter payload_router(modules);
EXPECT_EQ(kDefaultMaxLength, PayloadRouter::DefaultMaxPayloadLength());
payload_router.SetSendingRtpModules(modules.size());
@ -188,7 +170,7 @@ TEST(PayloadRouterTest, SetTargetSendBitrates) {
std::vector<RtpRtcp*> modules;
modules.push_back(&rtp_1);
modules.push_back(&rtp_2);
PayloadRouter payload_router(modules, 42);
PayloadRouter payload_router(modules);
payload_router.SetSendingRtpModules(modules.size());
const uint32_t bitrate_1 = 10000;

View File

@ -17,7 +17,6 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/modules/video_coding/include/video_codec_interface.h"
#include "webrtc/system_wrappers/include/metrics.h"
namespace webrtc {
@ -427,17 +426,8 @@ void SendStatisticsProxy::OnSetRates(uint32_t bitrate_bps, int framerate) {
void SendStatisticsProxy::OnSendEncodedImage(
const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_info) {
size_t simulcast_idx = 0;
if (codec_info) {
if (codec_info->codecType == kVideoCodecVP8) {
simulcast_idx = codec_info->codecSpecific.VP8.simulcastIdx;
} else if (codec_info->codecType == kVideoCodecGeneric) {
simulcast_idx = codec_info->codecSpecific.generic.simulcast_idx;
}
}
const RTPVideoHeader* rtp_video_header) {
size_t simulcast_idx = rtp_video_header ? rtp_video_header->simulcastIdx : 0;
if (simulcast_idx >= config_.rtp.ssrcs.size()) {
LOG(LS_ERROR) << "Encoded image outside simulcast range (" << simulcast_idx
<< " >= " << config_.rtp.ssrcs.size() << ").";
@ -479,16 +469,17 @@ void SendStatisticsProxy::OnSendEncodedImage(
}
}
if (encoded_image.qp_ != -1 && codec_info) {
if (codec_info->codecType == kVideoCodecVP8) {
if (encoded_image.qp_ != -1 && rtp_video_header) {
if (rtp_video_header->codec == kRtpVideoVp8) {
int spatial_idx = (config_.rtp.ssrcs.size() == 1)
? -1
: static_cast<int>(simulcast_idx);
uma_container_->qp_counters_[spatial_idx].vp8.Add(encoded_image.qp_);
} else if (codec_info->codecType == kVideoCodecVP9) {
int spatial_idx = (codec_info->codecSpecific.VP9.num_spatial_layers == 1)
} else if (rtp_video_header->codec == kRtpVideoVp9) {
int spatial_idx =
(rtp_video_header->codecHeader.VP9.num_spatial_layers == 1)
? -1
: codec_info->codecSpecific.VP9.spatial_idx;
: rtp_video_header->codecHeader.VP9.spatial_idx;
uma_container_->qp_counters_[spatial_idx].vp9.Add(encoded_image.qp_);
}
}

View File

@ -49,7 +49,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
VideoSendStream::Stats GetStats();
virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_info);
const RTPVideoHeader* rtp_video_header);
// Used to update incoming frame rate.
void OnIncomingFrame(int width, int height);

View File

@ -334,16 +334,16 @@ TEST_F(SendStatisticsProxyTest, SwitchContentTypeUpdatesHistograms) {
TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8) {
test::ClearHistograms();
EncodedImage encoded_image;
CodecSpecificInfo codec_info;
codec_info.codecType = kVideoCodecVP8;
RTPVideoHeader rtp_video_header;
rtp_video_header.codec = kRtpVideoVp8;
for (int i = 0; i < kMinRequiredSamples; ++i) {
codec_info.codecSpecific.VP8.simulcastIdx = 0;
rtp_video_header.simulcastIdx = 0;
encoded_image.qp_ = kQpIdx0;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
codec_info.codecSpecific.VP8.simulcastIdx = 1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
rtp_video_header.simulcastIdx = 1;
encoded_image.qp_ = kQpIdx1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
}
statistics_proxy_.reset();
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp8.S0"));
@ -362,13 +362,13 @@ TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) {
test::ClearHistograms();
EncodedImage encoded_image;
CodecSpecificInfo codec_info;
codec_info.codecType = kVideoCodecVP8;
RTPVideoHeader rtp_video_header;
rtp_video_header.codec = kRtpVideoVp8;
for (int i = 0; i < kMinRequiredSamples; ++i) {
codec_info.codecSpecific.VP8.simulcastIdx = 0;
rtp_video_header.simulcastIdx = 0;
encoded_image.qp_ = kQpIdx0;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
}
statistics_proxy_.reset();
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp8"));
@ -378,17 +378,18 @@ TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp8OneSsrc) {
TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9) {
test::ClearHistograms();
EncodedImage encoded_image;
CodecSpecificInfo codec_info;
codec_info.codecType = kVideoCodecVP9;
codec_info.codecSpecific.VP9.num_spatial_layers = 2;
RTPVideoHeader rtp_video_header;
rtp_video_header.simulcastIdx = 0;
rtp_video_header.codec = kRtpVideoVp9;
rtp_video_header.codecHeader.VP9.num_spatial_layers = 2;
for (int i = 0; i < kMinRequiredSamples; ++i) {
encoded_image.qp_ = kQpIdx0;
codec_info.codecSpecific.VP9.spatial_idx = 0;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
rtp_video_header.codecHeader.VP9.spatial_idx = 0;
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
encoded_image.qp_ = kQpIdx1;
codec_info.codecSpecific.VP9.spatial_idx = 1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
rtp_video_header.codecHeader.VP9.spatial_idx = 1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
}
statistics_proxy_.reset();
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp9.S0"));
@ -407,14 +408,15 @@ TEST_F(SendStatisticsProxyTest, VerifyQpHistogramStats_Vp9OneSpatialLayer) {
test::ClearHistograms();
EncodedImage encoded_image;
CodecSpecificInfo codec_info;
codec_info.codecType = kVideoCodecVP9;
codec_info.codecSpecific.VP9.num_spatial_layers = 1;
RTPVideoHeader rtp_video_header;
rtp_video_header.simulcastIdx = 0;
rtp_video_header.codec = kRtpVideoVp9;
rtp_video_header.codecHeader.VP9.num_spatial_layers = 1;
for (int i = 0; i < kMinRequiredSamples; ++i) {
encoded_image.qp_ = kQpIdx0;
codec_info.codecSpecific.VP9.spatial_idx = 0;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
rtp_video_header.codecHeader.VP9.spatial_idx = 0;
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
}
statistics_proxy_.reset();
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Encoded.Qp.Vp9"));
@ -456,13 +458,12 @@ TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) {
encoded_image._encodedWidth = kEncodedWidth;
encoded_image._encodedHeight = kEncodedHeight;
CodecSpecificInfo codec_info;
codec_info.codecType = kVideoCodecVP8;
codec_info.codecSpecific.VP8.simulcastIdx = 0;
RTPVideoHeader rtp_video_header;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
codec_info.codecSpecific.VP8.simulcastIdx = 1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
rtp_video_header.simulcastIdx = 0;
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
rtp_video_header.simulcastIdx = 1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
VideoSendStream::Stats stats = statistics_proxy_->GetStats();
EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
@ -484,8 +485,8 @@ TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) {
// Report stats for second SSRC to make sure it's not outdated along with the
// first SSRC.
codec_info.codecSpecific.VP8.simulcastIdx = 1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
rtp_video_header.simulcastIdx = 1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
// Forward 1 ms, reach timeout, substream 0 should have no resolution
// reported, but substream 1 should.
@ -504,13 +505,12 @@ TEST_F(SendStatisticsProxyTest, ClearsResolutionFromInactiveSsrcs) {
encoded_image._encodedWidth = kEncodedWidth;
encoded_image._encodedHeight = kEncodedHeight;
CodecSpecificInfo codec_info;
codec_info.codecType = kVideoCodecVP8;
codec_info.codecSpecific.VP8.simulcastIdx = 0;
RTPVideoHeader rtp_video_header;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
codec_info.codecSpecific.VP8.simulcastIdx = 1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &codec_info);
rtp_video_header.simulcastIdx = 0;
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
rtp_video_header.simulcastIdx = 1;
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
statistics_proxy_->OnInactiveSsrc(config_.rtp.ssrcs[1]);
VideoSendStream::Stats stats = statistics_proxy_->GetStats();

View File

@ -405,10 +405,25 @@ int32_t VideoReceiveStream::Encoded(
if (kEnableFrameRecording) {
if (!ivf_writer_.get()) {
RTC_DCHECK(codec_specific_info);
RtpVideoCodecTypes rtp_codec_type;
switch (codec_specific_info->codecType) {
case kVideoCodecVP8:
rtp_codec_type = kRtpVideoVp8;
break;
case kVideoCodecVP9:
rtp_codec_type = kRtpVideoVp9;
break;
case kVideoCodecH264:
rtp_codec_type = kRtpVideoH264;
break;
default:
rtp_codec_type = kRtpVideoNone;
RTC_NOTREACHED() << "Unsupported codec "
<< codec_specific_info->codecType;
}
std::ostringstream oss;
oss << "receive_bitstream_ssrc_" << config_.rtp.remote_ssrc << ".ivf";
ivf_writer_ =
IvfFileWriter::Open(oss.str(), codec_specific_info->codecType);
ivf_writer_ = IvfFileWriter::Open(oss.str(), rtp_codec_type);
}
if (ivf_writer_.get()) {
bool ok = ivf_writer_->WriteFrame(encoded_image);

View File

@ -229,16 +229,14 @@ VideoSendStream::VideoSendStream(
this,
config.post_encode_callback,
&stats_proxy_),
vie_encoder_(
num_cpu_cores,
vie_encoder_(num_cpu_cores,
config_.rtp.ssrcs,
module_process_thread_,
&stats_proxy_,
config.pre_encode_callback,
&overuse_detector_,
congestion_controller_->pacer(),
&payload_router_,
config.post_encode_callback ? &encoded_frame_proxy_ : nullptr),
&payload_router_),
vcm_(vie_encoder_.vcm()),
bandwidth_observer_(congestion_controller_->GetBitrateController()
->CreateRtcpBandwidthObserver()),
@ -252,7 +250,7 @@ VideoSendStream::VideoSendStream(
congestion_controller_->packet_router(),
&stats_proxy_,
config_.rtp.ssrcs.size())),
payload_router_(rtp_rtcp_modules_, config.encoder_settings.payload_type),
payload_router_(rtp_rtcp_modules_),
input_(&encoder_wakeup_event_,
config_.local_renderer,
&stats_proxy_,
@ -321,6 +319,9 @@ VideoSendStream::VideoSendStream(
ReconfigureVideoEncoder(encoder_config);
if (config_.post_encode_callback)
vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_);
if (config_.suspend_below_min_bitrate) {
vcm_->SuspendBelowMinBitrate();
bitrate_allocator_->EnforceMinBitrate(false);

View File

@ -1807,6 +1807,7 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) {
const CodecSpecificInfo* codecSpecificInfo,
const std::vector<FrameType>* frame_types) override {
CodecSpecificInfo specifics;
memset(&specifics, 0, sizeof(specifics));
specifics.codecType = kVideoCodecGeneric;
uint8_t buffer[16] = {0};

View File

@ -85,8 +85,7 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores,
rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
OveruseFrameDetector* overuse_detector,
PacedSender* pacer,
PayloadRouter* payload_router,
EncodedImageCallback* post_encode_callback)
PayloadRouter* payload_router)
: number_of_cores_(number_of_cores),
ssrcs_(ssrcs),
vp_(VideoProcessing::Create()),
@ -99,7 +98,6 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores,
overuse_detector_(overuse_detector),
pacer_(pacer),
send_payload_router_(payload_router),
post_encode_callback_(post_encode_callback),
time_of_last_frame_activity_ms_(0),
encoder_config_(),
min_transmit_bitrate_bps_(0),
@ -123,10 +121,6 @@ bool ViEEncoder::Init() {
// Enable/disable content analysis: off by default for now.
vp_->EnableContentAnalysis(false);
vcm_->RegisterPostEncodeImageCallback(this);
// TODO(perkj): Remove |RegisterTransportCallback| as soon as we don't use
// VCMPacketizationCallback::OnEncoderImplementationName.
if (vcm_->RegisterTransportCallback(this) != 0) {
return false;
}
@ -409,14 +403,10 @@ void ViEEncoder::OnSetRates(uint32_t bitrate_bps, int framerate) {
stats_proxy_->OnSetRates(bitrate_bps, framerate);
}
void ViEEncoder::OnEncoderImplementationName(const char* implementation_name) {
if (stats_proxy_)
stats_proxy_->OnEncoderImplementationName(implementation_name);
}
int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) {
int32_t ViEEncoder::SendData(const uint8_t payload_type,
const EncodedImage& encoded_image,
const RTPFragmentationHeader* fragmentation_header,
const RTPVideoHeader* rtp_video_hdr) {
RTC_DCHECK(send_payload_router_);
{
@ -424,22 +414,17 @@ int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image,
time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp();
}
if (post_encode_callback_) {
post_encode_callback_->Encoded(encoded_image, codec_specific_info,
fragmentation);
}
if (stats_proxy_)
stats_proxy_->OnSendEncodedImage(encoded_image, rtp_video_hdr);
if (stats_proxy_) {
stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info);
}
int success = send_payload_router_->Encoded(
encoded_image, codec_specific_info, fragmentation);
bool success = send_payload_router_->RoutePayload(
encoded_image._frameType, payload_type, encoded_image._timeStamp,
encoded_image.capture_time_ms_, encoded_image._buffer,
encoded_image._length, fragmentation_header, rtp_video_hdr);
overuse_detector_->FrameSent(encoded_image._timeStamp);
if (kEnableFrameRecording) {
int layer = codec_specific_info->codecType == kVideoCodecVP8
? codec_specific_info->codecSpecific.VP8.simulcastIdx
: 0;
int layer = rtp_video_hdr->simulcastIdx;
IvfFileWriter* file_writer;
{
rtc::CritScope lock(&data_cs_);
@ -450,7 +435,7 @@ int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image,
oss << "_" << ssrc;
oss << "_layer" << layer << ".ivf";
file_writers_[layer] =
IvfFileWriter::Open(oss.str(), codec_specific_info->codecType);
IvfFileWriter::Open(oss.str(), rtp_video_hdr->codec);
}
file_writer = file_writers_[layer].get();
}
@ -460,7 +445,13 @@ int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image,
}
}
return success;
return success ? 0 : -1;
}
void ViEEncoder::OnEncoderImplementationName(
const char* implementation_name) {
if (stats_proxy_)
stats_proxy_->OnEncoderImplementationName(implementation_name);
}
int32_t ViEEncoder::SendStatistics(const uint32_t bit_rate,
@ -540,6 +531,11 @@ void ViEEncoder::OnBitrateUpdated(uint32_t bitrate_bps,
stats_proxy_->OnSuspendChange(video_is_suspended);
}
void ViEEncoder::RegisterPostEncodeImageCallback(
EncodedImageCallback* post_encode_callback) {
vcm_->RegisterPostEncodeImageCallback(post_encode_callback);
}
QMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessing* vpm)
: vp_(vpm) {
}

View File

@ -18,7 +18,6 @@
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/common_types.h"
#include "webrtc/video_encoder.h"
#include "webrtc/media/base/videosinkinterface.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/video_coding/include/video_coding_defines.h"
@ -42,7 +41,6 @@ class VideoCodingModule;
class VideoEncoder;
class ViEEncoder : public VideoEncoderRateObserver,
public EncodedImageCallback,
public VCMPacketizationCallback,
public VCMSendStatisticsCallback {
public:
@ -56,8 +54,7 @@ class ViEEncoder : public VideoEncoderRateObserver,
rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
OveruseFrameDetector* overuse_detector,
PacedSender* pacer,
PayloadRouter* payload_router,
EncodedImageCallback* post_encode_callback);
PayloadRouter* payload_router);
~ViEEncoder();
bool Init();
@ -95,13 +92,12 @@ class ViEEncoder : public VideoEncoderRateObserver,
void OnSetRates(uint32_t bitrate_bps, int framerate) override;
// Implements VCMPacketizationCallback.
int32_t SendData(uint8_t payload_type,
const EncodedImage& encoded_image,
const RTPFragmentationHeader* fragmentation_header,
const RTPVideoHeader* rtp_video_hdr) override;
void OnEncoderImplementationName(const char* implementation_name) override;
// Implements EncodedImageCallback.
int32_t Encoded(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) override;
// Implements VideoSendStatisticsCallback.
int32_t SendStatistics(const uint32_t bit_rate,
const uint32_t frame_rate) override;
@ -111,6 +107,10 @@ class ViEEncoder : public VideoEncoderRateObserver,
virtual void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id);
virtual void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id);
// New-style callbacks, used by VideoSendStream.
void RegisterPostEncodeImageCallback(
EncodedImageCallback* post_encode_callback);
int GetPaddingNeededBps() const;
void OnBitrateUpdated(uint32_t bitrate_bps,
@ -139,7 +139,6 @@ class ViEEncoder : public VideoEncoderRateObserver,
OveruseFrameDetector* const overuse_detector_;
PacedSender* const pacer_;
PayloadRouter* const send_payload_router_;
EncodedImageCallback* const post_encode_callback_;
// The time we last received an input frame or encoded frame. This is used to
// track when video is stopped long enough that we also want to stop sending

View File

@ -31,7 +31,6 @@ class EncodedImageCallback {
virtual ~EncodedImageCallback() {}
// Callback function which is called when an image has been encoded.
// TODO(perkj): Change this to return void.
virtual int32_t Encoded(const EncodedImage& encoded_image,
const CodecSpecificInfo* codec_specific_info,
const RTPFragmentationHeader* fragmentation) = 0;