Implement Base::ConstrainNewCodec2.
BUG=1788
R=wu@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/15009004
git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@6743 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/media/webrtc/webrtcvideoengine2.cc b/media/webrtc/webrtcvideoengine2.cc
index 1ce1b99..21e51eb 100644
--- a/media/webrtc/webrtcvideoengine2.cc
+++ b/media/webrtc/webrtcvideoengine2.cc
@@ -73,28 +73,8 @@
// The formats are sorted by the descending order of width. We use the order to
// find the next format for CPU and bandwidth adaptation.
-const VideoFormatPod kDefaultVideoFormat = {
+const VideoFormatPod kDefaultMaxVideoFormat = {
640, 400, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY};
-const VideoFormatPod kVideoFormats[] = {
- {1280, 800, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {1280, 720, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {960, 600, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {960, 540, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- kDefaultVideoFormat,
- {640, 360, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {640, 480, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {480, 300, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {480, 270, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {480, 360, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {320, 200, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {320, 180, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {320, 240, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {240, 150, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {240, 135, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {240, 180, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {160, 100, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {160, 90, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY},
- {160, 120, FPS_TO_INTERVAL(kDefaultFramerate), FOURCC_ANY}, };
static bool FindFirstMatchingCodec(const std::vector<VideoCodec>& codecs,
const VideoCodec& requested_codec,
@@ -107,49 +87,6 @@
}
return false;
}
-static bool FindBestVideoFormat(int max_width,
- int max_height,
- int aspect_width,
- int aspect_height,
- VideoFormat* video_format) {
- assert(max_width > 0);
- assert(max_height > 0);
- assert(aspect_width > 0);
- assert(aspect_height > 0);
- VideoFormat best_format;
- for (int i = 0; i < ARRAY_SIZE(kVideoFormats); ++i) {
- const VideoFormat format(kVideoFormats[i]);
-
- // Skip any format that is larger than the local or remote maximums, or
- // smaller than the current best match
- if (format.width > max_width || format.height > max_height ||
- (format.width < best_format.width &&
- format.height < best_format.height)) {
- continue;
- }
-
- // If we don't have any matches yet, this is the best so far.
- if (best_format.width == 0) {
- best_format = format;
- continue;
- }
-
- // Prefer closer aspect ratios i.e:
- // |format| aspect - requested aspect <
- // |best_format| aspect - requested aspect
- if (abs(format.width * aspect_height * best_format.height -
- aspect_width * format.height * best_format.height) <
- abs(best_format.width * aspect_height * format.height -
- aspect_width * format.height * best_format.height)) {
- best_format = format;
- }
- }
- if (best_format.width != 0) {
- *video_format = best_format;
- return true;
- }
- return false;
-}
static void AddDefaultFeedbackParams(VideoCodec* codec) {
const FeedbackParam kFir(kRtcpFbParamCcm, kRtcpFbCcmParamFir);
@@ -170,8 +107,8 @@
static VideoCodec DefaultVideoCodec() {
VideoCodec default_codec(kDefaultVideoCodecPref.payload_type,
kDefaultVideoCodecPref.name,
- kDefaultVideoFormat.width,
- kDefaultVideoFormat.height,
+ kDefaultMaxVideoFormat.width,
+ kDefaultMaxVideoFormat.height,
kDefaultFramerate,
0);
AddDefaultFeedbackParams(&default_codec);
@@ -267,7 +204,7 @@
channel_factory_ = channel_factory;
video_codecs_ = DefaultVideoCodecs();
- default_codec_format_ = VideoFormat(kDefaultVideoFormat);
+ default_codec_format_ = VideoFormat(kDefaultMaxVideoFormat);
rtp_header_extensions_.push_back(
RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension,
@@ -320,8 +257,21 @@
bool WebRtcVideoEngine2::SetDefaultEncoderConfig(
const VideoEncoderConfig& config) {
- // TODO(pbos): Implement. Should be covered by corresponding unit tests.
- LOG(LS_VERBOSE) << "SetDefaultEncoderConfig()";
+ const VideoCodec& codec = config.max_codec;
+ // TODO(pbos): Make use of external encoder factory.
+ if (!GetVideoEncoderFactory()->SupportsCodec(codec)) {
+ LOG(LS_ERROR) << "SetDefaultEncoderConfig, codec not supported:"
+ << codec.ToString();
+ return false;
+ }
+
+ default_codec_format_ =
+ VideoFormat(codec.width,
+ codec.height,
+ VideoFormat::FpsToInterval(codec.framerate),
+ FOURCC_ANY);
+ video_codecs_.clear();
+ video_codecs_.push_back(codec);
return true;
}
@@ -382,17 +332,10 @@
// TODO(pbos): Probe encoder factory to figure out that the codec is supported
// if supported by the encoder factory. Add a corresponding test that fails
// with this code (that doesn't ask the factory).
- for (int i = 0; i < ARRAY_SIZE(kVideoFormats); ++i) {
- const VideoFormat fmt(kVideoFormats[i]);
- if ((in.width != 0 || in.height != 0) &&
- (fmt.width != in.width || fmt.height != in.height)) {
- continue;
- }
- for (size_t j = 0; j < video_codecs_.size(); ++j) {
- VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0);
- if (codec.Matches(in)) {
- return true;
- }
+ for (size_t j = 0; j < video_codecs_.size(); ++j) {
+ VideoCodec codec(video_codecs_[j].id, video_codecs_[j].name, 0, 0, 0, 0);
+ if (codec.Matches(in)) {
+ return true;
}
}
return false;
@@ -406,7 +349,6 @@
const VideoCodec& current,
VideoCodec* out) {
assert(out != NULL);
- // TODO(pbos): Implement.
if (requested.width != requested.height &&
(requested.height == 0 || requested.width == 0)) {
@@ -420,37 +362,26 @@
return false;
}
- // Pick the best quality that is within their and our bounds and has the
- // correct aspect ratio.
- VideoFormat format;
- if (requested.width == 0 && requested.height == 0) {
- // Special case with resolution 0. The channel should not send frames.
- } else {
- int max_width = talk_base::_min(requested.width, matching_codec.width);
- int max_height = talk_base::_min(requested.height, matching_codec.height);
- int aspect_width = max_width;
- int aspect_height = max_height;
- if (current.width > 0 && current.height > 0) {
- aspect_width = current.width;
- aspect_height = current.height;
- }
- if (!FindBestVideoFormat(
- max_width, max_height, aspect_width, aspect_height, &format)) {
- return false;
- }
- }
-
out->id = requested.id;
out->name = requested.name;
out->preference = requested.preference;
out->params = requested.params;
out->framerate =
talk_base::_min(requested.framerate, matching_codec.framerate);
- out->width = format.width;
- out->height = format.height;
out->params = requested.params;
out->feedback_params = requested.feedback_params;
- return true;
+ out->width = requested.width;
+ out->height = requested.height;
+ if (requested.width == 0 && requested.height == 0) {
+ return true;
+ }
+
+ while (out->width > matching_codec.width) {
+ out->width /= 2;
+ out->height /= 2;
+ }
+
+ return out->width > 0 && out->height > 0;
}
bool WebRtcVideoEngine2::SetVoiceEngine(WebRtcVoiceEngine* voice_engine) {
diff --git a/media/webrtc/webrtcvideoengine2_unittest.cc b/media/webrtc/webrtcvideoengine2_unittest.cc
index 0954bcb..45ea161 100644
--- a/media/webrtc/webrtcvideoengine2_unittest.cc
+++ b/media/webrtc/webrtcvideoengine2_unittest.cc
@@ -350,8 +350,10 @@
vp8_diff_id.id = 97;
EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
+ // FindCodec ignores the codec size.
+ // Test that FindCodec can accept uncommon codec size.
cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
- EXPECT_FALSE(engine_.FindCodec(vp8_diff_res));
+ EXPECT_TRUE(engine_.FindCodec(vp8_diff_res));
// PeerConnection doesn't negotiate the resolution at this point.
// Test that FindCodec can handle the case when width/height is 0.
@@ -424,6 +426,17 @@
<< "Channel should be stoppable even without set codecs.";
}
+class WebRtcVideoEngine2BaseTest
+ : public VideoEngineTest<cricket::WebRtcVideoEngine2> {
+ protected:
+ typedef VideoEngineTest<cricket::WebRtcVideoEngine2> Base;
+};
+
+#define WEBRTC_ENGINE_BASE_TEST(test) \
+ TEST_F(WebRtcVideoEngine2BaseTest, test) { Base::test##Body(); }
+
+WEBRTC_ENGINE_BASE_TEST(ConstrainNewCodec2);
+
class WebRtcVideoChannel2BaseTest
: public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
protected:
@@ -431,118 +444,74 @@
typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
};
+#define WEBRTC_BASE_TEST(test) \
+ TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
+
+#define WEBRTC_DISABLED_BASE_TEST(test) \
+ TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_ ## test) { Base::test(); }
+
// TODO(pbos): Fix WebRtcVideoEngine2BaseTest, where we want CheckCoInitialize.
#if 0
// TODO(juberti): Figure out why ViE is munging the COM refcount.
#ifdef WIN32
-TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_CheckCoInitialize) {
+WEBRTC_DISABLED_BASE_TEST(CheckCoInitialize) {
Base::CheckCoInitialize();
}
#endif
#endif
-TEST_F(WebRtcVideoChannel2BaseTest, SetSend) { Base::SetSend(); }
+WEBRTC_BASE_TEST(SetSend);
+WEBRTC_BASE_TEST(SetSendWithoutCodecs);
+WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
-TEST_F(WebRtcVideoChannel2BaseTest, SetSendWithoutCodecs) {
- Base::SetSendWithoutCodecs();
-}
+WEBRTC_BASE_TEST(GetStats);
+WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
+WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
-TEST_F(WebRtcVideoChannel2BaseTest, SetSendSetsTransportBufferSizes) {
- Base::SetSendSetsTransportBufferSizes();
-}
+WEBRTC_BASE_TEST(SetSendBandwidth);
-TEST_F(WebRtcVideoChannel2BaseTest, GetStats) { Base::GetStats(); }
+WEBRTC_BASE_TEST(SetSendSsrc);
+WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
-TEST_F(WebRtcVideoChannel2BaseTest, GetStatsMultipleRecvStreams) {
- Base::GetStatsMultipleRecvStreams();
-}
+WEBRTC_BASE_TEST(SetRenderer);
+WEBRTC_BASE_TEST(AddRemoveRecvStreams);
-TEST_F(WebRtcVideoChannel2BaseTest, GetStatsMultipleSendStreams) {
- Base::GetStatsMultipleSendStreams();
-}
+WEBRTC_DISABLED_BASE_TEST(AddRemoveRecvStreamAndRender);
-TEST_F(WebRtcVideoChannel2BaseTest, SetSendBandwidth) {
- Base::SetSendBandwidth();
-}
-TEST_F(WebRtcVideoChannel2BaseTest, SetSendSsrc) { Base::SetSendSsrc(); }
-TEST_F(WebRtcVideoChannel2BaseTest, SetSendSsrcAfterSetCodecs) {
- Base::SetSendSsrcAfterSetCodecs();
-}
+WEBRTC_BASE_TEST(AddRemoveRecvStreamsNoConference);
-TEST_F(WebRtcVideoChannel2BaseTest, SetRenderer) { Base::SetRenderer(); }
+WEBRTC_BASE_TEST(AddRemoveSendStreams);
-TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveRecvStreams) {
- Base::AddRemoveRecvStreams();
-}
+WEBRTC_BASE_TEST(SimulateConference);
-TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_AddRemoveRecvStreamAndRender) {
- Base::AddRemoveRecvStreamAndRender();
-}
+WEBRTC_BASE_TEST(AddRemoveCapturer);
-TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveRecvStreamsNoConference) {
- Base::AddRemoveRecvStreamsNoConference();
-}
+WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
-TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveSendStreams) {
- Base::AddRemoveSendStreams();
-}
-
-TEST_F(WebRtcVideoChannel2BaseTest, SimulateConference) {
- Base::SimulateConference();
-}
-
-TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveCapturer) {
- Base::AddRemoveCapturer();
-}
-
-TEST_F(WebRtcVideoChannel2BaseTest, RemoveCapturerWithoutAdd) {
- Base::RemoveCapturerWithoutAdd();
-}
-
-TEST_F(WebRtcVideoChannel2BaseTest, AddRemoveCapturerMultipleSources) {
- Base::AddRemoveCapturerMultipleSources();
-}
+WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
// TODO(pbos): Figure out why this fails so often.
-TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_HighAspectHighHeightCapturer) {
- Base::HighAspectHighHeightCapturer();
-}
+WEBRTC_DISABLED_BASE_TEST(HighAspectHighHeightCapturer);
-TEST_F(WebRtcVideoChannel2BaseTest, RejectEmptyStreamParams) {
- Base::RejectEmptyStreamParams();
-}
+WEBRTC_BASE_TEST(RejectEmptyStreamParams);
-TEST_F(WebRtcVideoChannel2BaseTest, AdaptResolution16x10) {
- Base::AdaptResolution16x10();
-}
+WEBRTC_BASE_TEST(AdaptResolution16x10);
-TEST_F(WebRtcVideoChannel2BaseTest, AdaptResolution4x3) {
- Base::AdaptResolution4x3();
-}
+WEBRTC_BASE_TEST(AdaptResolution4x3);
-TEST_F(WebRtcVideoChannel2BaseTest, MuteStream) { Base::MuteStream(); }
+WEBRTC_BASE_TEST(MuteStream);
-TEST_F(WebRtcVideoChannel2BaseTest, MultipleSendStreams) {
- Base::MultipleSendStreams();
-}
+WEBRTC_BASE_TEST(MultipleSendStreams);
// TODO(juberti): Restore this test once we support sending 0 fps.
-TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_AdaptDropAllFrames) {
- Base::AdaptDropAllFrames();
-}
+WEBRTC_DISABLED_BASE_TEST(AdaptDropAllFrames);
// TODO(juberti): Understand why we get decode errors on this test.
-TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_AdaptFramerate) {
- Base::AdaptFramerate();
-}
+WEBRTC_DISABLED_BASE_TEST(AdaptFramerate);
-TEST_F(WebRtcVideoChannel2BaseTest, SetSendStreamFormat0x0) {
- Base::SetSendStreamFormat0x0();
-}
+WEBRTC_BASE_TEST(SetSendStreamFormat0x0);
// TODO(zhurunz): Fix the flakey test.
-TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SetSendStreamFormat) {
- Base::SetSendStreamFormat();
-}
+WEBRTC_DISABLED_BASE_TEST(SetSendStreamFormat);
TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
Base::TwoStreamsSendAndReceive(kVp8Codec);