Removed constraint for changing resolution when using default encoder and added VP8 log.
Review URL: http://webrtc-codereview.appspot.com/330029 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1314 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
6c877363f7
commit
9c0aedc28b
@ -19,6 +19,25 @@
|
|||||||
#include "tb_video_channel.h"
|
#include "tb_video_channel.h"
|
||||||
#include "vie_autotest_defines.h"
|
#include "vie_autotest_defines.h"
|
||||||
|
|
||||||
|
class RenderFilter : public webrtc::ViEEffectFilter {
|
||||||
|
public:
|
||||||
|
RenderFilter()
|
||||||
|
: last_render_width_(0),
|
||||||
|
last_render_height_(0) {}
|
||||||
|
|
||||||
|
~RenderFilter() {}
|
||||||
|
|
||||||
|
virtual int Transform(int size, unsigned char* frame_buffer,
|
||||||
|
unsigned int time_stamp, unsigned int width,
|
||||||
|
unsigned int height) {
|
||||||
|
last_render_width_ = width;
|
||||||
|
last_render_height_ = height;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
unsigned int last_render_width_;
|
||||||
|
unsigned int last_render_height_;
|
||||||
|
};
|
||||||
|
|
||||||
void ViEAutoTest::ViECodecStandardTest()
|
void ViEAutoTest::ViECodecStandardTest()
|
||||||
{
|
{
|
||||||
TbInterfaces interfaces = TbInterfaces("ViECodecStandardTest");
|
TbInterfaces interfaces = TbInterfaces("ViECodecStandardTest");
|
||||||
@ -174,6 +193,8 @@ void ViEAutoTest::ViECodecExtendedTest()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPECT_TRUE(codecSet);
|
EXPECT_TRUE(codecSet);
|
||||||
|
webrtc::VideoCodec send_codec;
|
||||||
|
memcpy(&send_codec, &videoCodec, sizeof(videoCodec));
|
||||||
|
|
||||||
EXPECT_EQ(0, ViE.base->StartSend(videoChannel1));
|
EXPECT_EQ(0, ViE.base->StartSend(videoChannel1));
|
||||||
EXPECT_EQ(0, ViE.base->StartReceive(videoChannel1));
|
EXPECT_EQ(0, ViE.base->StartReceive(videoChannel1));
|
||||||
@ -215,13 +236,40 @@ void ViEAutoTest::ViECodecExtendedTest()
|
|||||||
|
|
||||||
AutoTestSleep(KAutoTestSleepTimeMs);
|
AutoTestSleep(KAutoTestSleepTimeMs);
|
||||||
|
|
||||||
// Check that we received H.263 on both channels
|
|
||||||
EXPECT_EQ(webrtc::kVideoCodecVP8,
|
EXPECT_EQ(webrtc::kVideoCodecVP8,
|
||||||
codecObserver1.incomingCodec.codecType);
|
codecObserver1.incomingCodec.codecType);
|
||||||
EXPECT_EQ(176, codecObserver1.incomingCodec.width);
|
EXPECT_EQ(send_codec.width, codecObserver1.incomingCodec.width);
|
||||||
EXPECT_EQ(webrtc::kVideoCodecVP8,
|
EXPECT_EQ(webrtc::kVideoCodecVP8,
|
||||||
codecObserver2.incomingCodec.codecType);
|
codecObserver2.incomingCodec.codecType);
|
||||||
EXPECT_EQ(176, codecObserver2.incomingCodec.width);
|
EXPECT_EQ(send_codec.width, codecObserver2.incomingCodec.width);
|
||||||
|
|
||||||
|
// Change resolution on one of the channels and verify it changes for
|
||||||
|
// the other channel too.
|
||||||
|
send_codec.width = 2 * codecWidth;
|
||||||
|
send_codec.height = 2 * codecHeight;
|
||||||
|
EXPECT_EQ(0, ViE.codec->SetSendCodec(videoChannel1, send_codec));
|
||||||
|
|
||||||
|
// We need to verify using render effect filter since we won't trigger
|
||||||
|
// a decode reset in loopback (due to using the same SSRC).
|
||||||
|
RenderFilter filter1;
|
||||||
|
RenderFilter filter2;
|
||||||
|
EXPECT_EQ(0,
|
||||||
|
ViE.image_process->RegisterRenderEffectFilter(videoChannel1,
|
||||||
|
filter1));
|
||||||
|
EXPECT_EQ(0,
|
||||||
|
ViE.image_process->RegisterRenderEffectFilter(videoChannel2,
|
||||||
|
filter2));
|
||||||
|
|
||||||
|
AutoTestSleep(KAutoTestSleepTimeMs);
|
||||||
|
|
||||||
|
EXPECT_EQ(0, ViE.image_process->DeregisterRenderEffectFilter(
|
||||||
|
videoChannel1));
|
||||||
|
EXPECT_EQ(0, ViE.image_process->DeregisterRenderEffectFilter(
|
||||||
|
videoChannel2));
|
||||||
|
EXPECT_EQ(send_codec.width, filter1.last_render_width_);
|
||||||
|
EXPECT_EQ(send_codec.height, filter1.last_render_height_);
|
||||||
|
EXPECT_EQ(send_codec.width, filter2.last_render_width_);
|
||||||
|
EXPECT_EQ(send_codec.height, filter2.last_render_height_);
|
||||||
|
|
||||||
// Delete the first channel and keep the second
|
// Delete the first channel and keep the second
|
||||||
EXPECT_EQ(0, ViE.base->DeleteChannel(videoChannel1));
|
EXPECT_EQ(0, ViE.base->DeleteChannel(videoChannel1));
|
||||||
|
@ -470,6 +470,20 @@ bool ViEChannelManager::ChannelUsingViEEncoder(int channel_id) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViEChannelManager::ChannelsUsingViEEncoder(int channel_id,
|
||||||
|
ChannelList* channels) const {
|
||||||
|
CriticalSectionScoped cs(*channel_id_critsect_);
|
||||||
|
MapItem* encoder_item = vie_encoder_map_.Find(channel_id);
|
||||||
|
assert(encoder_item);
|
||||||
|
MapItem* channel_item = channel_map_.First();
|
||||||
|
while (channel_item) {
|
||||||
|
if (vie_encoder_map_.Find(channel_item->GetId())) {
|
||||||
|
channels->push_back(static_cast<ViEChannel*>(channel_item->GetItem()));
|
||||||
|
}
|
||||||
|
channel_item = channel_map_.Next(channel_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ViEChannelManagerScoped::ViEChannelManagerScoped(
|
ViEChannelManagerScoped::ViEChannelManagerScoped(
|
||||||
const ViEChannelManager& vie_channel_manager)
|
const ViEChannelManager& vie_channel_manager)
|
||||||
: ViEManagerScopedBase(vie_channel_manager) {
|
: ViEManagerScopedBase(vie_channel_manager) {
|
||||||
@ -489,4 +503,10 @@ bool ViEChannelManagerScoped::ChannelUsingViEEncoder(int channel_id) const {
|
|||||||
ChannelUsingViEEncoder(channel_id);
|
ChannelUsingViEEncoder(channel_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViEChannelManagerScoped::ChannelsUsingViEEncoder(
|
||||||
|
int channel_id, ChannelList* channels) const {
|
||||||
|
(static_cast<const ViEChannelManager*>(vie_manager_))->
|
||||||
|
ChannelsUsingViEEncoder(channel_id, channels);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#ifndef WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_MANAGER_H_
|
#ifndef WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_MANAGER_H_
|
||||||
#define WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_MANAGER_H_
|
#define WEBRTC_VIDEO_ENGINE_VIE_CHANNEL_MANAGER_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "engine_configurations.h"
|
#include "engine_configurations.h"
|
||||||
#include "system_wrappers/interface/map_wrapper.h"
|
#include "system_wrappers/interface/map_wrapper.h"
|
||||||
#include "system_wrappers/interface/scoped_ptr.h"
|
#include "system_wrappers/interface/scoped_ptr.h"
|
||||||
@ -29,6 +31,8 @@ class VieRemb;
|
|||||||
class VoEVideoSync;
|
class VoEVideoSync;
|
||||||
class VoiceEngine;
|
class VoiceEngine;
|
||||||
|
|
||||||
|
typedef std::list<ViEChannel*> ChannelList;
|
||||||
|
|
||||||
class ViEChannelManager: private ViEManagerBase {
|
class ViEChannelManager: private ViEManagerBase {
|
||||||
friend class ViEChannelManagerScoped;
|
friend class ViEChannelManagerScoped;
|
||||||
public:
|
public:
|
||||||
@ -84,6 +88,7 @@ class ViEChannelManager: private ViEManagerBase {
|
|||||||
// Returns true if at least one other channels uses the same ViEEncoder as
|
// Returns true if at least one other channels uses the same ViEEncoder as
|
||||||
// channel_id.
|
// channel_id.
|
||||||
bool ChannelUsingViEEncoder(int channel_id) const;
|
bool ChannelUsingViEEncoder(int channel_id) const;
|
||||||
|
void ChannelsUsingViEEncoder(int channel_id, ChannelList* channels) const;
|
||||||
|
|
||||||
// Protects channel_map_ and free_channel_ids_.
|
// Protects channel_map_ and free_channel_ids_.
|
||||||
CriticalSectionWrapper* channel_id_critsect_;
|
CriticalSectionWrapper* channel_id_critsect_;
|
||||||
@ -109,9 +114,13 @@ class ViEChannelManagerScoped: private ViEManagerScopedBase {
|
|||||||
ViEChannel* Channel(int vie_channel_id) const;
|
ViEChannel* Channel(int vie_channel_id) const;
|
||||||
ViEEncoder* Encoder(int vie_channel_id) const;
|
ViEEncoder* Encoder(int vie_channel_id) const;
|
||||||
|
|
||||||
// Returns true if at lease one other channels uses the same ViEEncoder as
|
// Returns true if at least one other channels uses the same ViEEncoder as
|
||||||
// channel_id.
|
// channel_id.
|
||||||
bool ChannelUsingViEEncoder(int channel_id) const;
|
bool ChannelUsingViEEncoder(int channel_id) const;
|
||||||
|
|
||||||
|
// Returns a list with pointers to all channels using the same encoder as the
|
||||||
|
// channel with |channel_id|, including the one with the specified id.
|
||||||
|
void ChannelsUsingViEEncoder(int channel_id, ChannelList* channels) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -106,12 +106,23 @@ int ViECodecImpl::SetSendCodec(const int video_channel,
|
|||||||
video_channel, video_codec.codecType);
|
video_channel, video_codec.codecType);
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(instance_id_, video_channel),
|
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(instance_id_, video_channel),
|
||||||
"%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d"
|
"%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d"
|
||||||
"maxBr: %d, min_br: %d, frame_rate: %d)", __FUNCTION__,
|
"maxBr: %d, min_br: %d, frame_rate: %d, qpMax: %u,"
|
||||||
|
"numberOfSimulcastStreams: %u )", __FUNCTION__,
|
||||||
video_codec.codecType, video_codec.plType, video_codec.width,
|
video_codec.codecType, video_codec.plType, video_codec.width,
|
||||||
video_codec.height, video_codec.startBitrate,
|
video_codec.height, video_codec.startBitrate,
|
||||||
video_codec.maxBitrate, video_codec.minBitrate,
|
video_codec.maxBitrate, video_codec.minBitrate,
|
||||||
video_codec.maxFramerate);
|
video_codec.maxFramerate, video_codec.qpMax,
|
||||||
|
video_codec.numberOfSimulcastStreams);
|
||||||
|
if (video_codec.codecType == kVideoCodecVP8) {
|
||||||
|
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(instance_id_, video_channel),
|
||||||
|
"pictureLossIndicationOn: %d, feedbackModeOn: %d, "
|
||||||
|
"complexity: %d, resilience: %d, numberOfTemporalLayers: %u",
|
||||||
|
video_codec.codecSpecific.VP8.pictureLossIndicationOn,
|
||||||
|
video_codec.codecSpecific.VP8.feedbackModeOn,
|
||||||
|
video_codec.codecSpecific.VP8.complexity,
|
||||||
|
video_codec.codecSpecific.VP8.resilience,
|
||||||
|
video_codec.codecSpecific.VP8.numberOfTemporalLayers);
|
||||||
|
}
|
||||||
if (!CodecValid(video_codec)) {
|
if (!CodecValid(video_codec)) {
|
||||||
// Error logged.
|
// Error logged.
|
||||||
SetLastError(kViECodecInvalidCodec);
|
SetLastError(kViECodecInvalidCodec);
|
||||||
@ -154,23 +165,23 @@ int ViECodecImpl::SetSendCodec(const int video_channel,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to check if the codec settings changed, then we need a new SSRC.
|
|
||||||
bool new_rtp_stream = false;
|
|
||||||
|
|
||||||
VideoCodec encoder;
|
VideoCodec encoder;
|
||||||
vie_encoder->GetEncoder(encoder);
|
vie_encoder->GetEncoder(encoder);
|
||||||
if (encoder.codecType != video_codec_internal.codecType ||
|
if (encoder.codecType != video_codec_internal.codecType &&
|
||||||
encoder.width != video_codec_internal.width ||
|
cs.ChannelUsingViEEncoder(video_channel)) {
|
||||||
encoder.height != video_codec_internal.height) {
|
// We don't allow changing codec type when several channels share encoder.
|
||||||
if (cs.ChannelUsingViEEncoder(video_channel)) {
|
|
||||||
// We don't allow changing codec type or size when several
|
|
||||||
// channels share encoder.
|
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(instance_id_, video_channel),
|
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(instance_id_, video_channel),
|
||||||
"%s: Settings differs from other channels using encoder",
|
"%s: Settings differs from other channels using encoder",
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
SetLastError(kViECodecInUse);
|
SetLastError(kViECodecInUse);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
// Make sure to generate a new SSRC if the codec type and/or resolution has
|
||||||
|
// changed. This won't have any effect if the user has set an SSRC.
|
||||||
|
bool new_rtp_stream = false;
|
||||||
|
if (encoder.codecType != video_codec_internal.codecType ||
|
||||||
|
encoder.width != video_codec_internal.width ||
|
||||||
|
encoder.height != video_codec_internal.height) {
|
||||||
new_rtp_stream = true;
|
new_rtp_stream = true;
|
||||||
}
|
}
|
||||||
if (video_codec_internal.numberOfSimulcastStreams > 1) {
|
if (video_codec_internal.numberOfSimulcastStreams > 1) {
|
||||||
@ -219,14 +230,23 @@ int ViECodecImpl::SetSendCodec(const int video_channel,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give the channel the new information.
|
// Give the channel(s) the new information.
|
||||||
if (vie_channel->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
|
ChannelList channels;
|
||||||
|
cs.ChannelsUsingViEEncoder(video_channel, &channels);
|
||||||
|
for (ChannelList::iterator it = channels.begin(); it != channels.end();
|
||||||
|
++it) {
|
||||||
|
bool ret = true;
|
||||||
|
if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
|
||||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
|
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
|
||||||
"%s: Could not set send codec for channel %d", __FUNCTION__,
|
"%s: Could not set send codec for channel %d", __FUNCTION__,
|
||||||
video_channel);
|
video_channel);
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
if (!ret) {
|
||||||
SetLastError(kViECodecUnknownError);
|
SetLastError(kViECodecUnknownError);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the protection mode, we might be switching NACK/FEC.
|
// Update the protection mode, we might be switching NACK/FEC.
|
||||||
vie_encoder->UpdateProtectionMethod();
|
vie_encoder->UpdateProtectionMethod();
|
||||||
|
Loading…
Reference in New Issue
Block a user