OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 25 matching lines...) Expand all Loading... | |
36 | 36 |
37 namespace webrtc { | 37 namespace webrtc { |
38 | 38 |
39 using DegredationPreference = VideoSendStream::DegradationPreference; | 39 using DegredationPreference = VideoSendStream::DegradationPreference; |
40 using ScaleReason = ScalingObserverInterface::ScaleReason; | 40 using ScaleReason = ScalingObserverInterface::ScaleReason; |
41 using ::testing::_; | 41 using ::testing::_; |
42 using ::testing::Return; | 42 using ::testing::Return; |
43 | 43 |
44 namespace { | 44 namespace { |
45 const size_t kMaxPayloadLength = 1440; | 45 const size_t kMaxPayloadLength = 1440; |
46 const int kTargetBitrateBps = 100000; | 46 const int kTargetBitrateBps = 1000000; |
47 const int kLowTargetBitrateBps = kTargetBitrateBps / 10; | |
48 const int kMaxInitialFramedrop = 4; | |
47 | 49 |
48 class TestBuffer : public webrtc::I420Buffer { | 50 class TestBuffer : public webrtc::I420Buffer { |
49 public: | 51 public: |
50 TestBuffer(rtc::Event* event, int width, int height) | 52 TestBuffer(rtc::Event* event, int width, int height) |
51 : I420Buffer(width, height), event_(event) {} | 53 : I420Buffer(width, height), event_(event) {} |
52 | 54 |
53 private: | 55 private: |
54 friend class rtc::RefCountedObject<TestBuffer>; | 56 friend class rtc::RefCountedObject<TestBuffer>; |
55 ~TestBuffer() override { | 57 ~TestBuffer() override { |
56 if (event_) | 58 if (event_) |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 | 144 |
143 void ConfigureEncoder(VideoEncoderConfig video_encoder_config, | 145 void ConfigureEncoder(VideoEncoderConfig video_encoder_config, |
144 bool nack_enabled) { | 146 bool nack_enabled) { |
145 if (vie_encoder_) | 147 if (vie_encoder_) |
146 vie_encoder_->Stop(); | 148 vie_encoder_->Stop(); |
147 vie_encoder_.reset(new ViEEncoderUnderTest( | 149 vie_encoder_.reset(new ViEEncoderUnderTest( |
148 stats_proxy_.get(), video_send_config_.encoder_settings)); | 150 stats_proxy_.get(), video_send_config_.encoder_settings)); |
149 vie_encoder_->SetSink(&sink_, false /* rotation_applied */); | 151 vie_encoder_->SetSink(&sink_, false /* rotation_applied */); |
150 vie_encoder_->SetSource(&video_source_, | 152 vie_encoder_->SetSource(&video_source_, |
151 VideoSendStream::DegradationPreference::kBalanced); | 153 VideoSendStream::DegradationPreference::kBalanced); |
152 vie_encoder_->SetStartBitrate(10000); | 154 vie_encoder_->SetStartBitrate(kTargetBitrateBps); |
153 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), | 155 vie_encoder_->ConfigureEncoder(std::move(video_encoder_config), |
154 kMaxPayloadLength, nack_enabled); | 156 kMaxPayloadLength, nack_enabled); |
155 } | 157 } |
156 | 158 |
157 void ResetEncoder(const std::string& payload_name, | 159 void ResetEncoder(const std::string& payload_name, |
158 size_t num_streams, | 160 size_t num_streams, |
159 size_t num_temporal_layers, | 161 size_t num_temporal_layers, |
160 bool nack_enabled) { | 162 bool nack_enabled) { |
161 video_send_config_.encoder_settings.payload_name = payload_name; | 163 video_send_config_.encoder_settings.payload_name = payload_name; |
162 | 164 |
163 VideoEncoderConfig video_encoder_config; | 165 VideoEncoderConfig video_encoder_config; |
164 video_encoder_config.number_of_streams = num_streams; | 166 video_encoder_config.number_of_streams = num_streams; |
165 video_encoder_config.max_bitrate_bps = 1000000; | 167 video_encoder_config.max_bitrate_bps = kTargetBitrateBps; |
166 video_encoder_config.video_stream_factory = | 168 video_encoder_config.video_stream_factory = |
167 new rtc::RefCountedObject<VideoStreamFactory>(num_temporal_layers); | 169 new rtc::RefCountedObject<VideoStreamFactory>(num_temporal_layers); |
168 ConfigureEncoder(std::move(video_encoder_config), nack_enabled); | 170 ConfigureEncoder(std::move(video_encoder_config), nack_enabled); |
169 } | 171 } |
170 | 172 |
171 VideoFrame CreateFrame(int64_t ntp_time_ms, | 173 VideoFrame CreateFrame(int64_t ntp_time_ms, |
172 rtc::Event* destruction_event) const { | 174 rtc::Event* destruction_event) const { |
173 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>( | 175 VideoFrame frame(new rtc::RefCountedObject<TestBuffer>( |
174 destruction_event, codec_width_, codec_height_), | 176 destruction_event, codec_width_, codec_height_), |
175 99, 99, kVideoRotation_0); | 177 99, 99, kVideoRotation_0); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 void WaitForEncodedFrame(int64_t expected_ntp_time) { | 258 void WaitForEncodedFrame(int64_t expected_ntp_time) { |
257 uint32_t timestamp = 0; | 259 uint32_t timestamp = 0; |
258 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs)); | 260 EXPECT_TRUE(encoded_frame_event_.Wait(kDefaultTimeoutMs)); |
259 { | 261 { |
260 rtc::CritScope lock(&crit_); | 262 rtc::CritScope lock(&crit_); |
261 timestamp = timestamp_; | 263 timestamp = timestamp_; |
262 } | 264 } |
263 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp); | 265 test_encoder_->CheckLastTimeStampsMatch(expected_ntp_time, timestamp); |
264 } | 266 } |
265 | 267 |
268 void ExpectDroppedFrame() { EXPECT_FALSE(encoded_frame_event_.Wait(20)); } | |
269 | |
266 void SetExpectNoFrames() { | 270 void SetExpectNoFrames() { |
267 rtc::CritScope lock(&crit_); | 271 rtc::CritScope lock(&crit_); |
268 expect_frames_ = false; | 272 expect_frames_ = false; |
269 } | 273 } |
270 | 274 |
271 int number_of_reconfigurations() { | 275 int number_of_reconfigurations() { |
272 rtc::CritScope lock(&crit_); | 276 rtc::CritScope lock(&crit_); |
273 return number_of_reconfigurations_; | 277 return number_of_reconfigurations_; |
274 } | 278 } |
275 | 279 |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
672 sink_.WaitForEncodedFrame(3); | 676 sink_.WaitForEncodedFrame(3); |
673 | 677 |
674 stats = stats_proxy_->GetStats(); | 678 stats = stats_proxy_->GetStats(); |
675 EXPECT_FALSE(stats.cpu_limited_resolution); | 679 EXPECT_FALSE(stats.cpu_limited_resolution); |
676 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | 680 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); |
677 | 681 |
678 vie_encoder_->Stop(); | 682 vie_encoder_->Stop(); |
679 } | 683 } |
680 | 684 |
681 TEST_F(ViEEncoderTest, SwitchingSourceKeepsCpuAdaptation) { | 685 TEST_F(ViEEncoderTest, SwitchingSourceKeepsCpuAdaptation) { |
682 const int kTargetBitrateBps = 100000; | |
683 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 686 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
684 | 687 |
685 int frame_width = 1280; | 688 int frame_width = 1280; |
686 int frame_height = 720; | 689 int frame_height = 720; |
687 video_source_.IncomingCapturedFrame( | 690 video_source_.IncomingCapturedFrame( |
688 CreateFrame(1, frame_width, frame_height)); | 691 CreateFrame(1, frame_width, frame_height)); |
689 sink_.WaitForEncodedFrame(1); | 692 sink_.WaitForEncodedFrame(1); |
690 | 693 |
691 VideoSendStream::Stats stats = stats_proxy_->GetStats(); | 694 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
692 EXPECT_FALSE(stats.cpu_limited_resolution); | 695 EXPECT_FALSE(stats.cpu_limited_resolution); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
742 CreateFrame(6, frame_width, frame_height)); | 745 CreateFrame(6, frame_width, frame_height)); |
743 sink_.WaitForEncodedFrame(6); | 746 sink_.WaitForEncodedFrame(6); |
744 stats = stats_proxy_->GetStats(); | 747 stats = stats_proxy_->GetStats(); |
745 EXPECT_FALSE(stats.cpu_limited_resolution); | 748 EXPECT_FALSE(stats.cpu_limited_resolution); |
746 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); | 749 EXPECT_EQ(2, stats.number_of_cpu_adapt_changes); |
747 | 750 |
748 vie_encoder_->Stop(); | 751 vie_encoder_->Stop(); |
749 } | 752 } |
750 | 753 |
751 TEST_F(ViEEncoderTest, SwitchingSourceKeepsQualityAdaptation) { | 754 TEST_F(ViEEncoderTest, SwitchingSourceKeepsQualityAdaptation) { |
752 const int kTargetBitrateBps = 100000; | |
753 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 755 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
754 | 756 |
755 int frame_width = 1280; | 757 int frame_width = 1280; |
756 int frame_height = 720; | 758 int frame_height = 720; |
757 video_source_.IncomingCapturedFrame( | 759 video_source_.IncomingCapturedFrame( |
758 CreateFrame(1, frame_width, frame_height)); | 760 CreateFrame(1, frame_width, frame_height)); |
759 sink_.WaitForEncodedFrame(1); | 761 sink_.WaitForEncodedFrame(1); |
760 | 762 |
761 VideoSendStream::Stats stats = stats_proxy_->GetStats(); | 763 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
762 EXPECT_FALSE(stats.cpu_limited_resolution); | 764 EXPECT_FALSE(stats.cpu_limited_resolution); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
878 sink_.WaitForEncodedFrame(1); | 880 sink_.WaitForEncodedFrame(1); |
879 | 881 |
880 VideoSendStream::Stats stats = stats_proxy_->GetStats(); | 882 VideoSendStream::Stats stats = stats_proxy_->GetStats(); |
881 EXPECT_EQ(video_encoder_config_.max_bitrate_bps, | 883 EXPECT_EQ(video_encoder_config_.max_bitrate_bps, |
882 stats.preferred_media_bitrate_bps); | 884 stats.preferred_media_bitrate_bps); |
883 | 885 |
884 vie_encoder_->Stop(); | 886 vie_encoder_->Stop(); |
885 } | 887 } |
886 | 888 |
887 TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) { | 889 TEST_F(ViEEncoderTest, ScalingUpAndDownDoesNothingWithMaintainResolution) { |
888 const int kTargetBitrateBps = 100000; | |
889 int frame_width = 1280; | 890 int frame_width = 1280; |
890 int frame_height = 720; | 891 int frame_height = 720; |
891 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 892 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
892 | 893 |
893 // Expect no scaling to begin with | 894 // Expect no scaling to begin with |
894 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count); | 895 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count); |
895 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); | 896 EXPECT_FALSE(video_source_.sink_wants().max_pixel_count_step_up); |
896 | 897 |
897 video_source_.IncomingCapturedFrame( | 898 video_source_.IncomingCapturedFrame( |
898 CreateFrame(1, frame_width, frame_height)); | 899 CreateFrame(1, frame_width, frame_height)); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
931 CreateFrame(4, frame_width, frame_height)); | 932 CreateFrame(4, frame_width, frame_height)); |
932 sink_.WaitForEncodedFrame(4); | 933 sink_.WaitForEncodedFrame(4); |
933 | 934 |
934 // Expect nothing to change, still no scaling | 935 // Expect nothing to change, still no scaling |
935 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count); | 936 EXPECT_FALSE(new_video_source.sink_wants().max_pixel_count); |
936 | 937 |
937 vie_encoder_->Stop(); | 938 vie_encoder_->Stop(); |
938 } | 939 } |
939 | 940 |
940 TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) { | 941 TEST_F(ViEEncoderTest, DoesNotScaleBelowSetLimit) { |
941 const int kTargetBitrateBps = 100000; | |
942 int frame_width = 1280; | 942 int frame_width = 1280; |
943 int frame_height = 720; | 943 int frame_height = 720; |
944 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 944 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); |
945 | 945 |
946 for (size_t i = 1; i <= 10; i++) { | 946 for (size_t i = 1; i <= 10; i++) { |
947 video_source_.IncomingCapturedFrame( | 947 video_source_.IncomingCapturedFrame( |
948 CreateFrame(i, frame_width, frame_height)); | 948 CreateFrame(i, frame_width, frame_height)); |
949 sink_.WaitForEncodedFrame(i); | 949 sink_.WaitForEncodedFrame(i); |
950 // Trigger scale down | 950 // Trigger scale down |
951 vie_encoder_->TriggerQualityLow(); | 951 vie_encoder_->TriggerQualityLow(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
988 TEST_F(ViEEncoderTest, CallsBitrateObserver) { | 988 TEST_F(ViEEncoderTest, CallsBitrateObserver) { |
989 class MockBitrateObserver : public VideoBitrateAllocationObserver { | 989 class MockBitrateObserver : public VideoBitrateAllocationObserver { |
990 public: | 990 public: |
991 MOCK_METHOD1(OnBitrateAllocationUpdated, void(const BitrateAllocation&)); | 991 MOCK_METHOD1(OnBitrateAllocationUpdated, void(const BitrateAllocation&)); |
992 } bitrate_observer; | 992 } bitrate_observer; |
993 vie_encoder_->SetBitrateObserver(&bitrate_observer); | 993 vie_encoder_->SetBitrateObserver(&bitrate_observer); |
994 | 994 |
995 const int kDefaultFps = 30; | 995 const int kDefaultFps = 30; |
996 const BitrateAllocation expected_bitrate = | 996 const BitrateAllocation expected_bitrate = |
997 DefaultVideoBitrateAllocator(fake_encoder_.codec_config()) | 997 DefaultVideoBitrateAllocator(fake_encoder_.codec_config()) |
998 .GetAllocation(kTargetBitrateBps, kDefaultFps); | 998 .GetAllocation(kLowTargetBitrateBps, kDefaultFps); |
999 | 999 |
1000 // First called on bitrate updated, then again on first frame. | 1000 // First called on bitrate updated, then again on first frame. |
1001 EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate)) | 1001 EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate)) |
1002 .Times(2); | 1002 .Times(2); |
1003 vie_encoder_->OnBitrateUpdated(kTargetBitrateBps, 0, 0); | 1003 vie_encoder_->OnBitrateUpdated(kLowTargetBitrateBps, 0, 0); |
1004 | 1004 |
1005 const int64_t kStartTimeMs = 1; | 1005 const int64_t kStartTimeMs = 1; |
1006 video_source_.IncomingCapturedFrame( | 1006 video_source_.IncomingCapturedFrame( |
1007 CreateFrame(kStartTimeMs, codec_width_, codec_height_)); | 1007 CreateFrame(kStartTimeMs, codec_width_, codec_height_)); |
1008 sink_.WaitForEncodedFrame(kStartTimeMs); | 1008 sink_.WaitForEncodedFrame(kStartTimeMs); |
1009 | 1009 |
1010 // Not called on second frame. | 1010 // Not called on second frame. |
1011 EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate)) | 1011 EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate)) |
1012 .Times(0); | 1012 .Times(0); |
1013 video_source_.IncomingCapturedFrame( | 1013 video_source_.IncomingCapturedFrame( |
1014 CreateFrame(kStartTimeMs + 1, codec_width_, codec_height_)); | 1014 CreateFrame(kStartTimeMs + 1, codec_width_, codec_height_)); |
1015 sink_.WaitForEncodedFrame(kStartTimeMs + 1); | 1015 sink_.WaitForEncodedFrame(kStartTimeMs + 1); |
1016 | 1016 |
1017 // Called after a process interval. | 1017 // Called after a process interval. |
1018 const int64_t kProcessIntervalMs = | 1018 const int64_t kProcessIntervalMs = |
1019 vcm::VCMProcessTimer::kDefaultProcessIntervalMs; | 1019 vcm::VCMProcessTimer::kDefaultProcessIntervalMs; |
1020 // TODO(sprang): ViEEncoder should die and/or get injectable clock. | 1020 // TODO(sprang): ViEEncoder should die and/or get injectable clock. |
1021 // Sleep for one processing interval plus one frame to avoid flakiness. | 1021 // Sleep for one processing interval plus one frame to avoid flakiness. |
1022 SleepMs(kProcessIntervalMs + 1000 / kDefaultFps); | 1022 SleepMs(kProcessIntervalMs + 1000 / kDefaultFps); |
1023 EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate)) | 1023 EXPECT_CALL(bitrate_observer, OnBitrateAllocationUpdated(expected_bitrate)) |
1024 .Times(1); | 1024 .Times(1); |
1025 video_source_.IncomingCapturedFrame(CreateFrame( | 1025 video_source_.IncomingCapturedFrame(CreateFrame( |
1026 kStartTimeMs + kProcessIntervalMs, codec_width_, codec_height_)); | 1026 kStartTimeMs + kProcessIntervalMs, codec_width_, codec_height_)); |
1027 sink_.WaitForEncodedFrame(kStartTimeMs + kProcessIntervalMs); | 1027 sink_.WaitForEncodedFrame(kStartTimeMs + kProcessIntervalMs); |
1028 | 1028 |
1029 vie_encoder_->Stop(); | 1029 vie_encoder_->Stop(); |
1030 } | 1030 } |
1031 | 1031 |
1032 TEST_F(ViEEncoderTest, DropsFramesAndScalesWhenBitrateIsTooLow) { | |
1033 vie_encoder_->OnBitrateUpdated(kLowTargetBitrateBps, 0, 0); | |
1034 int frame_width = 640; | |
1035 int frame_height = 360; | |
1036 | |
1037 video_source_.IncomingCapturedFrame( | |
1038 CreateFrame(1, frame_width, frame_height)); | |
1039 | |
1040 // Expect to drop this frame, the wait should time out. | |
1041 sink_.ExpectDroppedFrame(); | |
1042 | |
1043 // Expect the sink_wants to specify a scaled frame. | |
1044 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count); | |
1045 EXPECT_LT(*video_source_.sink_wants().max_pixel_count, 1000 * 1000); | |
1046 | |
1047 int last_pixel_count = *video_source_.sink_wants().max_pixel_count; | |
1048 | |
1049 // Next frame is scaled | |
1050 video_source_.IncomingCapturedFrame( | |
1051 CreateFrame(2, frame_width * 3 / 4, frame_height * 3 / 4)); | |
1052 | |
1053 // Expect to drop this frame, the wait should time out. | |
1054 sink_.ExpectDroppedFrame(); | |
1055 | |
1056 EXPECT_LT(*video_source_.sink_wants().max_pixel_count, last_pixel_count); | |
1057 | |
1058 vie_encoder_->Stop(); | |
1059 } | |
1060 | |
1061 TEST_F(ViEEncoderTest, NrOfInitiallyDroppedFramesLimited) { | |
perkj_webrtc
2017/01/23 08:54:22
NrOfDroppedFramesLimited?
kthelgason
2017/01/23 12:39:06
Done.
| |
1062 // 1kbps. This can never be achieved. | |
1063 vie_encoder_->OnBitrateUpdated(1000, 0, 0); | |
1064 int frame_width = 640; | |
1065 int frame_height = 360; | |
1066 | |
1067 // We expect the n initial frames to get dropped. | |
1068 int i; | |
1069 for (i = 1; i <= kMaxInitialFramedrop; ++i) { | |
1070 video_source_.IncomingCapturedFrame( | |
1071 CreateFrame(i, frame_width, frame_height)); | |
1072 sink_.ExpectDroppedFrame(); | |
1073 } | |
1074 // The n+1th frame should not, even though it's size is too large. | |
perkj_webrtc
2017/01/23 08:54:22
/s not be dropped, even ....
kthelgason
2017/01/23 12:39:06
Done.
| |
1075 video_source_.IncomingCapturedFrame( | |
1076 CreateFrame(i, frame_width, frame_height)); | |
1077 sink_.WaitForEncodedFrame(i); | |
1078 | |
1079 // Expect the sink_wants to specify a scaled frame. | |
1080 EXPECT_TRUE(video_source_.sink_wants().max_pixel_count); | |
1081 EXPECT_LT(*video_source_.sink_wants().max_pixel_count, 1000 * 1000); | |
1082 | |
1083 vie_encoder_->Stop(); | |
1084 } | |
1085 | |
1086 TEST_F(ViEEncoderTest, InitialFramedropOffWithMaintainResolutionPreference) { | |
perkj_webrtc
2017/01/23 08:54:22
FrameDropOffWithMain.. ?
kthelgason
2017/01/23 12:39:06
Done.
| |
1087 int frame_width = 640; | |
1088 int frame_height = 360; | |
1089 vie_encoder_->OnBitrateUpdated(kLowTargetBitrateBps, 0, 0); | |
1090 | |
1091 // Set degradation preference. | |
1092 vie_encoder_->SetSource( | |
1093 &video_source_, | |
1094 VideoSendStream::DegradationPreference::kMaintainResolution); | |
1095 | |
1096 video_source_.IncomingCapturedFrame( | |
1097 CreateFrame(1, frame_width, frame_height)); | |
1098 // Frame should not be dropped, even if it's too large. | |
1099 sink_.WaitForEncodedFrame(1); | |
1100 | |
1101 vie_encoder_->Stop(); | |
1102 } | |
1103 | |
1032 } // namespace webrtc | 1104 } // namespace webrtc |
OLD | NEW |