Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: webrtc/modules/video_coding/codecs/test/videoprocessor.h

Issue 2741953002: Step #4: Run VideoProcessor integration test batch mode on task queue. (Closed)
Patch Set: Fix gn. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 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
11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_H_ 11 #ifndef WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_H_
12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_H_ 12 #define WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_H_
13 13
14 #include <memory> 14 #include <memory>
15 #include <string> 15 #include <string>
16 #include <vector> 16 #include <vector>
17 17
18 #include "webrtc/api/video/video_frame.h" 18 #include "webrtc/api/video/video_frame.h"
19 #include "webrtc/base/buffer.h" 19 #include "webrtc/base/buffer.h"
20 #include "webrtc/base/checks.h" 20 #include "webrtc/base/checks.h"
21 #include "webrtc/base/sequenced_task_checker.h"
22 #include "webrtc/base/task_queue.h"
21 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 23 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
22 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 24 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
23 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" 25 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
24 #include "webrtc/modules/video_coding/codecs/test/stats.h" 26 #include "webrtc/modules/video_coding/codecs/test/stats.h"
25 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h" 27 #include "webrtc/modules/video_coding/utility/ivf_file_writer.h"
26 #include "webrtc/test/testsupport/frame_reader.h" 28 #include "webrtc/test/testsupport/frame_reader.h"
27 #include "webrtc/test/testsupport/frame_writer.h" 29 #include "webrtc/test/testsupport/frame_writer.h"
28 30
29 namespace webrtc { 31 namespace webrtc {
30 32
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 // Regarding packet loss: Note that keyframes are excluded (first or all 123 // Regarding packet loss: Note that keyframes are excluded (first or all
122 // depending on the ExcludeFrameTypes setting). This is because if key frames 124 // depending on the ExcludeFrameTypes setting). This is because if key frames
123 // would be altered, all the following delta frames would be pretty much 125 // would be altered, all the following delta frames would be pretty much
124 // worthless. VP8 has an error-resilience feature that makes it able to handle 126 // worthless. VP8 has an error-resilience feature that makes it able to handle
125 // packet loss in key non-first keyframes, which is why only the first is 127 // packet loss in key non-first keyframes, which is why only the first is
126 // excluded by default. 128 // excluded by default.
127 // Packet loss in such important frames is handled on a higher level in the 129 // Packet loss in such important frames is handled on a higher level in the
128 // Video Engine, where signaling would request a retransmit of the lost packets, 130 // Video Engine, where signaling would request a retransmit of the lost packets,
129 // since they're so important. 131 // since they're so important.
130 // 132 //
131 // Note this class is not thread safe in any way and is meant for simple testing 133 // This class should be run on a single thread, or a single task queue.
132 // purposes.
133 class VideoProcessor { 134 class VideoProcessor {
134 public: 135 public:
135 virtual ~VideoProcessor() {} 136 virtual ~VideoProcessor();
136 137
137 // Performs initial calculations about frame size, sets up callbacks etc. 138 // Performs initial calculations about frame size, sets up callbacks etc.
138 // Returns false if an error has occurred, in addition to printing to stderr. 139 // Returns false if an error has occurred, in addition to printing to stderr.
139 virtual bool Init() = 0; 140 virtual bool Init() = 0;
140 141
142 virtual void DeregisterCallbacks() = 0;
tommi 2017/03/21 10:03:27 Add documentation? (e.g. if there is a condition t
brandtr 2017/06/28 09:40:24 Documentation added. Semantics and name have chang
143
141 // Processes a single frame. Returns true as long as there's more frames 144 // Processes a single frame. Returns true as long as there's more frames
142 // available in the source clip. 145 // available in the source clip.
143 // Frame number must be an integer >= 0. 146 // Frame number must be an integer >= 0.
144 virtual bool ProcessFrame(int frame_number) = 0; 147 virtual bool ProcessFrame(int frame_number) = 0;
145 148
146 // Updates the encoder with the target bit rate and the frame rate. 149 // Updates the encoder with the target bit rate and the frame rate.
147 virtual void SetRates(int bit_rate, int frame_rate) = 0; 150 virtual void SetRates(int bit_rate, int frame_rate) = 0;
148 151
149 // Return the size of the encoded frame in bytes. Dropped frames by the 152 // Return the size of the encoded frame in bytes. Dropped frames by the
150 // encoder are regarded as zero size. 153 // encoder are regarded as zero size.
(...skipping 14 matching lines...) Expand all
165 VideoProcessorImpl(webrtc::VideoEncoder* encoder, 168 VideoProcessorImpl(webrtc::VideoEncoder* encoder,
166 webrtc::VideoDecoder* decoder, 169 webrtc::VideoDecoder* decoder,
167 FrameReader* analysis_frame_reader, 170 FrameReader* analysis_frame_reader,
168 FrameWriter* analysis_frame_writer, 171 FrameWriter* analysis_frame_writer,
169 PacketManipulator* packet_manipulator, 172 PacketManipulator* packet_manipulator,
170 const TestConfig& config, 173 const TestConfig& config,
171 Stats* stats, 174 Stats* stats,
172 FrameWriter* source_frame_writer, 175 FrameWriter* source_frame_writer,
173 IvfFileWriter* encoded_frame_writer, 176 IvfFileWriter* encoded_frame_writer,
174 FrameWriter* decoded_frame_writer); 177 FrameWriter* decoded_frame_writer);
175 virtual ~VideoProcessorImpl(); 178 ~VideoProcessorImpl() override;
176 bool Init() override; 179 bool Init() override;
180 void DeregisterCallbacks() override;
177 bool ProcessFrame(int frame_number) override; 181 bool ProcessFrame(int frame_number) override;
178 182
179 private: 183 private:
180 // Container that holds per-frame information that needs to be stored between 184 // Container that holds per-frame information that needs to be stored between
181 // calls to Encode and Decode, as well as the corresponding callbacks. It is 185 // calls to Encode and Decode, as well as the corresponding callbacks. It is
182 // not directly used for statistics -- for that, test::FrameStatistic is used. 186 // not directly used for statistics -- for that, test::FrameStatistic is used.
183 struct FrameInfo { 187 struct FrameInfo {
184 FrameInfo() 188 FrameInfo()
185 : timestamp(0), 189 : timestamp(0),
186 encode_start_ns(0), 190 encode_start_ns(0),
187 decode_start_ns(0), 191 decode_start_ns(0),
188 encoded_frame_size(0), 192 encoded_frame_size(0),
189 encoded_frame_type(kVideoFrameDelta), 193 encoded_frame_type(kVideoFrameDelta),
190 decoded_width(0), 194 decoded_width(0),
191 decoded_height(0), 195 decoded_height(0),
192 manipulated_length(0) {} 196 manipulated_length(0) {}
193 197
194 uint32_t timestamp; 198 uint32_t timestamp;
195 int64_t encode_start_ns; 199 int64_t encode_start_ns;
196 int64_t decode_start_ns; 200 int64_t decode_start_ns;
197 size_t encoded_frame_size; 201 size_t encoded_frame_size;
198 FrameType encoded_frame_type; 202 FrameType encoded_frame_type;
199 int decoded_width; 203 int decoded_width;
200 int decoded_height; 204 int decoded_height;
201 size_t manipulated_length; 205 size_t manipulated_length;
202 }; 206 };
203 207
204 // Callback class required to implement according to the VideoEncoder API. 208 // Callback adapter class for encoder callback.
209 // Will post the callback on the task queue it was created on, if such a
210 // queue exists.
205 class VideoProcessorEncodeCompleteCallback 211 class VideoProcessorEncodeCompleteCallback
206 : public webrtc::EncodedImageCallback { 212 : public webrtc::EncodedImageCallback {
207 public: 213 public:
208 explicit VideoProcessorEncodeCompleteCallback(VideoProcessorImpl* vp) 214 explicit VideoProcessorEncodeCompleteCallback(
209 : video_processor_(vp) {} 215 VideoProcessorImpl* video_processor)
216 : video_processor_(video_processor),
217 task_queue_(rtc::TaskQueue::Current()) {}
tommi 2017/03/21 10:03:27 if task_queue_ should never be null, please DCHECK
brandtr 2017/06/28 09:40:24 |task_queue_| can be null when the VideoProcessor
218
210 Result OnEncodedImage( 219 Result OnEncodedImage(
211 const webrtc::EncodedImage& encoded_image, 220 const webrtc::EncodedImage& encoded_image,
212 const webrtc::CodecSpecificInfo* codec_specific_info, 221 const webrtc::CodecSpecificInfo* codec_specific_info,
213 const webrtc::RTPFragmentationHeader* fragmentation) override { 222 const webrtc::RTPFragmentationHeader* fragmentation) override {
214 // Forward to parent class.
215 RTC_CHECK(codec_specific_info); 223 RTC_CHECK(codec_specific_info);
224
225 if (task_queue_ && !task_queue_->IsCurrent()) {
tommi 2017/03/21 10:03:27 it feels to me that the class has too many ways of
brandtr 2017/06/28 09:40:24 I agree that it is messy. The underlying reason is
226 task_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(
227 new EncodeCallbackTask(video_processor_, encoded_image,
228 codec_specific_info, fragmentation)));
229 return Result(Result::OK, 0);
230 }
231
216 video_processor_->FrameEncoded(codec_specific_info->codecType, 232 video_processor_->FrameEncoded(codec_specific_info->codecType,
217 encoded_image, fragmentation); 233 encoded_image, fragmentation);
218 return Result(Result::OK, 0); 234 return Result(Result::OK, 0);
219 } 235 }
220 236
221 private: 237 private:
238 class EncodeCallbackTask : public rtc::QueuedTask {
239 public:
240 EncodeCallbackTask(VideoProcessorImpl* video_processor,
241 const webrtc::EncodedImage& encoded_image,
242 const webrtc::CodecSpecificInfo* codec_specific_info,
243 const webrtc::RTPFragmentationHeader* fragmentation)
244 : video_processor_(video_processor),
245 buffer_(encoded_image._buffer, encoded_image._length),
246 encoded_image_(encoded_image),
247 codec_specific_info_(*codec_specific_info) {
248 encoded_image_._buffer = buffer_.data();
249 RTC_CHECK(fragmentation);
250 fragmentation_.CopyFrom(*fragmentation);
251 }
252
253 bool Run() override {
254 video_processor_->FrameEncoded(codec_specific_info_.codecType,
255 encoded_image_, &fragmentation_);
256 return true;
257 }
258
259 private:
260 VideoProcessorImpl* const video_processor_;
261 rtc::Buffer buffer_;
262 webrtc::EncodedImage encoded_image_;
263 const webrtc::CodecSpecificInfo codec_specific_info_;
264 webrtc::RTPFragmentationHeader fragmentation_;
265 };
266
222 VideoProcessorImpl* const video_processor_; 267 VideoProcessorImpl* const video_processor_;
268 rtc::TaskQueue* const task_queue_;
223 }; 269 };
224 270
225 // Callback class required to implement according to the VideoDecoder API. 271 // Callback adapter class for decoder callback.
272 // Will post the callback on the task queue it was created on, if such a
273 // queue exists.
226 class VideoProcessorDecodeCompleteCallback 274 class VideoProcessorDecodeCompleteCallback
227 : public webrtc::DecodedImageCallback { 275 : public webrtc::DecodedImageCallback {
228 public: 276 public:
229 explicit VideoProcessorDecodeCompleteCallback(VideoProcessorImpl* vp) 277 explicit VideoProcessorDecodeCompleteCallback(
230 : video_processor_(vp) {} 278 VideoProcessorImpl* video_processor)
279 : video_processor_(video_processor),
280 task_queue_(rtc::TaskQueue::Current()) {}
281
231 int32_t Decoded(webrtc::VideoFrame& image) override { 282 int32_t Decoded(webrtc::VideoFrame& image) override {
232 // Forward to parent class. 283 if (task_queue_ && !task_queue_->IsCurrent()) {
284 task_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(
285 new DecodeCallbackTask(video_processor_, image)));
286 return 0;
287 }
288
233 video_processor_->FrameDecoded(image); 289 video_processor_->FrameDecoded(image);
234 return 0; 290 return 0;
235 } 291 }
292
236 int32_t Decoded(webrtc::VideoFrame& image, 293 int32_t Decoded(webrtc::VideoFrame& image,
237 int64_t decode_time_ms) override { 294 int64_t decode_time_ms) override {
238 return Decoded(image); 295 return Decoded(image);
239 } 296 }
297
240 void Decoded(webrtc::VideoFrame& image, 298 void Decoded(webrtc::VideoFrame& image,
241 rtc::Optional<int32_t> decode_time_ms, 299 rtc::Optional<int32_t> decode_time_ms,
242 rtc::Optional<uint8_t> qp) override { 300 rtc::Optional<uint8_t> qp) override {
243 Decoded(image, 301 Decoded(image);
244 decode_time_ms ? static_cast<int32_t>(*decode_time_ms) : -1);
245 } 302 }
246 303
247 private: 304 private:
305 class DecodeCallbackTask : public rtc::QueuedTask {
306 public:
307 DecodeCallbackTask(VideoProcessorImpl* video_processor,
308 const webrtc::VideoFrame& image)
309 : video_processor_(video_processor), image_(image) {}
310
311 bool Run() override {
312 video_processor_->FrameDecoded(image_);
313 return true;
314 }
315
316 private:
317 VideoProcessorImpl* const video_processor_;
318 webrtc::VideoFrame image_;
319 };
320
248 VideoProcessorImpl* const video_processor_; 321 VideoProcessorImpl* const video_processor_;
322 rtc::TaskQueue* const task_queue_;
249 }; 323 };
250 324
251 // Invoked by the callback when a frame has completed encoding. 325 // Invoked by the callback when a frame has completed encoding.
252 void FrameEncoded(webrtc::VideoCodecType codec, 326 void FrameEncoded(webrtc::VideoCodecType codec,
253 const webrtc::EncodedImage& encodedImage, 327 const webrtc::EncodedImage& encodedImage,
254 const webrtc::RTPFragmentationHeader* fragmentation); 328 const webrtc::RTPFragmentationHeader* fragmentation);
255 329
256 // Invoked by the callback when a frame has completed decoding. 330 // Invoked by the callback when a frame has completed decoding.
257 void FrameDecoded(const webrtc::VideoFrame& image); 331 void FrameDecoded(const webrtc::VideoFrame& image);
258 332
259 // Updates the encoder with the target bit rate and the frame rate. 333 // Updates the encoder with the target bit rate and the frame rate.
260 void SetRates(int bit_rate, int frame_rate) override; 334 void SetRates(int bit_rate, int frame_rate) override;
261 335
262 // Return the size of the encoded frame in bytes. 336 // Return the size of the encoded frame in bytes.
263 size_t EncodedFrameSize(int frame_number) override; 337 size_t EncodedFrameSize(int frame_number) override;
264 338
265 // Return the encoded frame type (key or delta). 339 // Return the encoded frame type (key or delta).
266 FrameType EncodedFrameType(int frame_number) override; 340 FrameType EncodedFrameType(int frame_number) override;
267 341
268 // Return the number of dropped frames. 342 // Return the number of dropped frames.
269 int NumberDroppedFrames() override; 343 int NumberDroppedFrames() override;
270 344
271 // Return the number of spatial resizes. 345 // Return the number of spatial resizes.
272 int NumberSpatialResizes() override; 346 int NumberSpatialResizes() override;
273 347
274 webrtc::VideoEncoder* const encoder_; 348 webrtc::VideoEncoder* const encoder_ PT_GUARDED_BY(task_checker_);
275 webrtc::VideoDecoder* const decoder_; 349 webrtc::VideoDecoder* const decoder_ PT_GUARDED_BY(task_checker_);
276 const std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_; 350 const std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_
351 PT_GUARDED_BY(task_checker_);
277 352
278 // Adapters for the codec callbacks. 353 // Adapters for the codec callbacks.
279 const std::unique_ptr<EncodedImageCallback> encode_callback_; 354 std::unique_ptr<EncodedImageCallback> encode_callback_
280 const std::unique_ptr<DecodedImageCallback> decode_callback_; 355 GUARDED_BY(task_checker_);
356 std::unique_ptr<DecodedImageCallback> decode_callback_
357 GUARDED_BY(task_checker_);
281 358
282 PacketManipulator* const packet_manipulator_; 359 PacketManipulator* const packet_manipulator_ PT_GUARDED_BY(task_checker_);
283 const TestConfig& config_; 360 const TestConfig& config_;
284 361
285 // These (mandatory) file manipulators are used for, e.g., objective PSNR and 362 // These (mandatory) file manipulators are used for, e.g., objective PSNR and
286 // SSIM calculations at the end of a test run. 363 // SSIM calculations at the end of a test run.
287 FrameReader* const analysis_frame_reader_; 364 FrameReader* const analysis_frame_reader_ PT_GUARDED_BY(task_checker_);
288 FrameWriter* const analysis_frame_writer_; 365 FrameWriter* const analysis_frame_writer_ PT_GUARDED_BY(task_checker_);
289 const int num_frames_; 366 const int num_frames_;
290 367
291 // These (optional) file writers are used for persistently storing the output 368 // These (optional) file writers are used for persistently storing the output
292 // of the coding pipeline at different stages: pre encode (source), post 369 // of the coding pipeline at different stages: pre encode (source), post
293 // encode (encoded), and post decode (decoded). The purpose is to give the 370 // encode (encoded), and post decode (decoded). The purpose is to give the
294 // experimenter an option to subjectively evaluate the quality of the 371 // experimenter an option to subjectively evaluate the quality of the
295 // encoding, given the test settings. Each frame writer is enabled by being 372 // encoding, given the test settings. Each frame writer is enabled by being
296 // non-null. 373 // non-null.
297 FrameWriter* const source_frame_writer_; 374 FrameWriter* const source_frame_writer_ PT_GUARDED_BY(task_checker_);
298 IvfFileWriter* const encoded_frame_writer_; 375 IvfFileWriter* const encoded_frame_writer_ PT_GUARDED_BY(task_checker_);
299 FrameWriter* const decoded_frame_writer_; 376 FrameWriter* const decoded_frame_writer_ PT_GUARDED_BY(task_checker_);
300 377
301 bool initialized_; 378 bool initialized_ GUARDED_BY(task_checker_);
302 379
303 // Frame metadata for all frames that have been added through a call to 380 // Frame metadata for all frames that have been added through a call to
304 // ProcessFrames(). We need to store this metadata over the course of the 381 // ProcessFrames(). We need to store this metadata over the course of the
305 // test run, to support pipelining HW codecs. 382 // test run, to support pipelining HW codecs.
306 std::vector<FrameInfo> frame_infos_; 383 std::vector<FrameInfo> frame_infos_ GUARDED_BY(task_checker_);
307 int last_encoded_frame_num_; 384 int last_encoded_frame_num_ GUARDED_BY(task_checker_);
308 int last_decoded_frame_num_; 385 int last_decoded_frame_num_ GUARDED_BY(task_checker_);
309 386
310 // Keep track of if we have excluded the first key frame from packet loss. 387 // Keep track of if we have excluded the first key frame from packet loss.
311 bool first_key_frame_has_been_excluded_; 388 bool first_key_frame_has_been_excluded_ GUARDED_BY(task_checker_);
312 389
313 // Keep track of the last successfully decoded frame, since we write that 390 // Keep track of the last successfully decoded frame, since we write that
314 // frame to disk when decoding fails. 391 // frame to disk when decoding fails.
315 rtc::Buffer last_decoded_frame_buffer_; 392 rtc::Buffer last_decoded_frame_buffer_ GUARDED_BY(task_checker_);
316 393
317 // Statistics. 394 // Statistics.
318 Stats* stats_; 395 Stats* stats_ PT_GUARDED_BY(task_checker_);
319 int num_dropped_frames_; 396 int num_dropped_frames_ GUARDED_BY(task_checker_);
320 int num_spatial_resizes_; 397 int num_spatial_resizes_ GUARDED_BY(task_checker_);
321 double bit_rate_factor_; // Multiply frame length with this to get bit rate. 398 // Multiply frame length with this to get bit rate.
399 double bit_rate_factor_ GUARDED_BY(task_checker_);
400
401 rtc::SequencedTaskChecker task_checker_;
322 }; 402 };
323 403
324 } // namespace test 404 } // namespace test
325 } // namespace webrtc 405 } // namespace webrtc
326 406
327 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_H_ 407 #endif // WEBRTC_MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698