OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 (width_ + 1) / 2); | 79 (width_ + 1) / 2); |
80 return frame_.get(); | 80 return frame_.get(); |
81 } | 81 } |
82 | 82 |
83 private: | 83 private: |
84 const int width_; | 84 const int width_; |
85 const int height_; | 85 const int height_; |
86 std::unique_ptr<VideoFrame> frame_; | 86 std::unique_ptr<VideoFrame> frame_; |
87 }; | 87 }; |
88 | 88 |
89 class EncodedImageCallbackImpl : public EncodedImageCallback { | 89 class PacketizationCallback : public VCMPacketizationCallback { |
90 public: | 90 public: |
91 explicit EncodedImageCallbackImpl(Clock* clock) | 91 explicit PacketizationCallback(Clock* clock) |
92 : clock_(clock), start_time_ms_(clock_->TimeInMilliseconds()) {} | 92 : clock_(clock), start_time_ms_(clock_->TimeInMilliseconds()) {} |
93 | 93 |
94 virtual ~EncodedImageCallbackImpl() {} | 94 virtual ~PacketizationCallback() {} |
95 | 95 |
96 int32_t Encoded(const EncodedImage& encoded_image, | 96 int32_t SendData(uint8_t payload_type, |
97 const CodecSpecificInfo* codec_specific_info, | 97 const EncodedImage& encoded_image, |
98 const RTPFragmentationHeader* fragmentation) override { | 98 const RTPFragmentationHeader* fragmentation_header, |
99 assert(codec_specific_info); | 99 const RTPVideoHeader* rtp_video_header) override { |
100 frame_data_.push_back( | 100 assert(rtp_video_header); |
101 FrameData(encoded_image._length, *codec_specific_info)); | 101 frame_data_.push_back(FrameData(encoded_image._length, *rtp_video_header)); |
102 return 0; | 102 return 0; |
103 } | 103 } |
104 | 104 |
105 void Reset() { | 105 void Reset() { |
106 frame_data_.clear(); | 106 frame_data_.clear(); |
107 start_time_ms_ = clock_->TimeInMilliseconds(); | 107 start_time_ms_ = clock_->TimeInMilliseconds(); |
108 } | 108 } |
109 | 109 |
110 float FramerateFpsWithinTemporalLayer(int temporal_layer) { | 110 float FramerateFpsWithinTemporalLayer(int temporal_layer) { |
111 return CountFramesWithinTemporalLayer(temporal_layer) * | 111 return CountFramesWithinTemporalLayer(temporal_layer) * |
(...skipping 11 matching lines...) Expand all Loading... |
123 info.framerate_fps[tl] = FramerateFpsWithinTemporalLayer(tl); | 123 info.framerate_fps[tl] = FramerateFpsWithinTemporalLayer(tl); |
124 info.bitrate_kbps[tl] = BitrateKbpsWithinTemporalLayer(tl); | 124 info.bitrate_kbps[tl] = BitrateKbpsWithinTemporalLayer(tl); |
125 } | 125 } |
126 return info; | 126 return info; |
127 } | 127 } |
128 | 128 |
129 private: | 129 private: |
130 struct FrameData { | 130 struct FrameData { |
131 FrameData() {} | 131 FrameData() {} |
132 | 132 |
133 FrameData(size_t payload_size, const CodecSpecificInfo& codec_specific_info) | 133 FrameData(size_t payload_size, const RTPVideoHeader& rtp_video_header) |
134 : payload_size(payload_size), | 134 : payload_size(payload_size), rtp_video_header(rtp_video_header) {} |
135 codec_specific_info(codec_specific_info) {} | |
136 | 135 |
137 size_t payload_size; | 136 size_t payload_size; |
138 CodecSpecificInfo codec_specific_info; | 137 RTPVideoHeader rtp_video_header; |
139 }; | 138 }; |
140 | 139 |
141 int64_t interval_ms() { | 140 int64_t interval_ms() { |
142 int64_t diff = (clock_->TimeInMilliseconds() - start_time_ms_); | 141 int64_t diff = (clock_->TimeInMilliseconds() - start_time_ms_); |
143 EXPECT_GT(diff, 0); | 142 EXPECT_GT(diff, 0); |
144 return diff; | 143 return diff; |
145 } | 144 } |
146 | 145 |
147 int CountFramesWithinTemporalLayer(int temporal_layer) { | 146 int CountFramesWithinTemporalLayer(int temporal_layer) { |
148 int frames = 0; | 147 int frames = 0; |
149 for (size_t i = 0; i < frame_data_.size(); ++i) { | 148 for (size_t i = 0; i < frame_data_.size(); ++i) { |
150 EXPECT_EQ(kVideoCodecVP8, frame_data_[i].codec_specific_info.codecType); | 149 EXPECT_EQ(kRtpVideoVp8, frame_data_[i].rtp_video_header.codec); |
151 const uint8_t temporal_idx = | 150 const uint8_t temporal_idx = |
152 frame_data_[i].codec_specific_info.codecSpecific.VP8.temporalIdx; | 151 frame_data_[i].rtp_video_header.codecHeader.VP8.temporalIdx; |
153 if (temporal_idx <= temporal_layer || temporal_idx == kNoTemporalIdx) | 152 if (temporal_idx <= temporal_layer || temporal_idx == kNoTemporalIdx) |
154 frames++; | 153 frames++; |
155 } | 154 } |
156 return frames; | 155 return frames; |
157 } | 156 } |
158 | 157 |
159 size_t SumPayloadBytesWithinTemporalLayer(int temporal_layer) { | 158 size_t SumPayloadBytesWithinTemporalLayer(int temporal_layer) { |
160 size_t payload_size = 0; | 159 size_t payload_size = 0; |
161 for (size_t i = 0; i < frame_data_.size(); ++i) { | 160 for (size_t i = 0; i < frame_data_.size(); ++i) { |
162 EXPECT_EQ(kVideoCodecVP8, frame_data_[i].codec_specific_info.codecType); | 161 EXPECT_EQ(kRtpVideoVp8, frame_data_[i].rtp_video_header.codec); |
163 const uint8_t temporal_idx = | 162 const uint8_t temporal_idx = |
164 frame_data_[i].codec_specific_info.codecSpecific.VP8.temporalIdx; | 163 frame_data_[i].rtp_video_header.codecHeader.VP8.temporalIdx; |
165 if (temporal_idx <= temporal_layer || temporal_idx == kNoTemporalIdx) | 164 if (temporal_idx <= temporal_layer || temporal_idx == kNoTemporalIdx) |
166 payload_size += frame_data_[i].payload_size; | 165 payload_size += frame_data_[i].payload_size; |
167 } | 166 } |
168 return payload_size; | 167 return payload_size; |
169 } | 168 } |
170 | 169 |
171 Clock* clock_; | 170 Clock* clock_; |
172 int64_t start_time_ms_; | 171 int64_t start_time_ms_; |
173 vector<FrameData> frame_data_; | 172 vector<FrameData> frame_data_; |
174 }; | 173 }; |
175 | 174 |
176 class TestVideoSender : public ::testing::Test { | 175 class TestVideoSender : public ::testing::Test { |
177 protected: | 176 protected: |
178 // Note: simulated clock starts at 1 seconds, since parts of webrtc use 0 as | 177 // Note: simulated clock starts at 1 seconds, since parts of webrtc use 0 as |
179 // a special case (e.g. frame rate in media optimization). | 178 // a special case (e.g. frame rate in media optimization). |
180 TestVideoSender() : clock_(1000), encoded_frame_callback_(&clock_) {} | 179 TestVideoSender() : clock_(1000), packetization_callback_(&clock_) {} |
181 | 180 |
182 void SetUp() override { | 181 void SetUp() override { |
183 sender_.reset( | 182 sender_.reset( |
184 new VideoSender(&clock_, &encoded_frame_callback_, nullptr, nullptr)); | 183 new VideoSender(&clock_, &post_encode_callback_, nullptr, nullptr)); |
| 184 EXPECT_EQ(0, sender_->RegisterTransportCallback(&packetization_callback_)); |
185 } | 185 } |
186 | 186 |
187 void AddFrame() { | 187 void AddFrame() { |
188 assert(generator_.get()); | 188 assert(generator_.get()); |
189 sender_->AddVideoFrame(*generator_->NextFrame(), NULL, NULL); | 189 sender_->AddVideoFrame(*generator_->NextFrame(), NULL, NULL); |
190 } | 190 } |
191 | 191 |
192 SimulatedClock clock_; | 192 SimulatedClock clock_; |
193 EncodedImageCallbackImpl encoded_frame_callback_; | 193 PacketizationCallback packetization_callback_; |
| 194 MockEncodedImageCallback post_encode_callback_; |
194 // Used by subclassing tests, need to outlive sender_. | 195 // Used by subclassing tests, need to outlive sender_. |
195 std::unique_ptr<VideoEncoder> encoder_; | 196 std::unique_ptr<VideoEncoder> encoder_; |
196 std::unique_ptr<VideoSender> sender_; | 197 std::unique_ptr<VideoSender> sender_; |
197 std::unique_ptr<FrameGenerator> generator_; | 198 std::unique_ptr<FrameGenerator> generator_; |
198 }; | 199 }; |
199 | 200 |
200 class TestVideoSenderWithMockEncoder : public TestVideoSender { | 201 class TestVideoSenderWithMockEncoder : public TestVideoSender { |
201 protected: | 202 protected: |
202 void SetUp() override { | 203 void SetUp() override { |
203 TestVideoSender::SetUp(); | 204 TestVideoSender::SetUp(); |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 VideoCodingModule::Codec(kVideoCodecVP8, &codec); | 408 VideoCodingModule::Codec(kVideoCodecVP8, &codec); |
408 codec.width = width; | 409 codec.width = width; |
409 codec.height = height; | 410 codec.height = height; |
410 codec.codecSpecific.VP8.numberOfTemporalLayers = temporal_layers; | 411 codec.codecSpecific.VP8.numberOfTemporalLayers = temporal_layers; |
411 return codec; | 412 return codec; |
412 } | 413 } |
413 | 414 |
414 void InsertFrames(float framerate, float seconds) { | 415 void InsertFrames(float framerate, float seconds) { |
415 for (int i = 0; i < seconds * framerate; ++i) { | 416 for (int i = 0; i < seconds * framerate; ++i) { |
416 clock_.AdvanceTimeMilliseconds(1000.0f / framerate); | 417 clock_.AdvanceTimeMilliseconds(1000.0f / framerate); |
| 418 EXPECT_CALL(post_encode_callback_, Encoded(_, NULL, NULL)) |
| 419 .WillOnce(Return(0)); |
417 AddFrame(); | 420 AddFrame(); |
418 // SetChannelParameters needs to be called frequently to propagate | 421 // SetChannelParameters needs to be called frequently to propagate |
419 // framerate from the media optimization into the encoder. | 422 // framerate from the media optimization into the encoder. |
420 // Note: SetChannelParameters fails if less than 2 frames are in the | 423 // Note: SetChannelParameters fails if less than 2 frames are in the |
421 // buffer since it will fail to calculate the framerate. | 424 // buffer since it will fail to calculate the framerate. |
422 if (i != 0) { | 425 if (i != 0) { |
423 EXPECT_EQ(VCM_OK, sender_->SetChannelParameters( | 426 EXPECT_EQ(VCM_OK, sender_->SetChannelParameters( |
424 available_bitrate_kbps_ * 1000, 0, 200)); | 427 available_bitrate_kbps_ * 1000, 0, 200)); |
425 } | 428 } |
426 } | 429 } |
427 } | 430 } |
428 | 431 |
429 Vp8StreamInfo SimulateWithFramerate(float framerate) { | 432 Vp8StreamInfo SimulateWithFramerate(float framerate) { |
430 const float short_simulation_interval = 5.0; | 433 const float short_simulation_interval = 5.0; |
431 const float long_simulation_interval = 10.0; | 434 const float long_simulation_interval = 10.0; |
432 // It appears that this 5 seconds simulation is needed to allow | 435 // It appears that this 5 seconds simulation is needed to allow |
433 // bitrate and framerate to stabilize. | 436 // bitrate and framerate to stabilize. |
434 InsertFrames(framerate, short_simulation_interval); | 437 InsertFrames(framerate, short_simulation_interval); |
435 encoded_frame_callback_.Reset(); | 438 packetization_callback_.Reset(); |
436 | 439 |
437 InsertFrames(framerate, long_simulation_interval); | 440 InsertFrames(framerate, long_simulation_interval); |
438 return encoded_frame_callback_.CalculateVp8StreamInfo(); | 441 return packetization_callback_.CalculateVp8StreamInfo(); |
439 } | 442 } |
440 | 443 |
441 protected: | 444 protected: |
442 VideoCodec codec_; | 445 VideoCodec codec_; |
443 int codec_bitrate_kbps_; | 446 int codec_bitrate_kbps_; |
444 int available_bitrate_kbps_; | 447 int available_bitrate_kbps_; |
445 }; | 448 }; |
446 | 449 |
447 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) | 450 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) |
448 #define MAYBE_FixedTemporalLayersStrategy DISABLED_FixedTemporalLayersStrategy | 451 #define MAYBE_FixedTemporalLayersStrategy DISABLED_FixedTemporalLayersStrategy |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 } | 503 } |
501 { | 504 { |
502 // TODO(andresp): Find out why this fails with framerate = 7.5 | 505 // TODO(andresp): Find out why this fails with framerate = 7.5 |
503 Vp8StreamInfo expected = {{7.0, 7.0, 7.0}, {high_b, high_b, high_b}}; | 506 Vp8StreamInfo expected = {{7.0, 7.0, 7.0}, {high_b, high_b, high_b}}; |
504 EXPECT_THAT(SimulateWithFramerate(7.0), MatchesVp8StreamInfo(expected)); | 507 EXPECT_THAT(SimulateWithFramerate(7.0), MatchesVp8StreamInfo(expected)); |
505 } | 508 } |
506 } | 509 } |
507 } // namespace | 510 } // namespace |
508 } // namespace vcm | 511 } // namespace vcm |
509 } // namespace webrtc | 512 } // namespace webrtc |
OLD | NEW |