videoprocessor.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
  3. *
  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
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_H_
  11. #define MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_H_
  12. #include <stddef.h>
  13. #include <stdint.h>
  14. #include <map>
  15. #include <memory>
  16. #include <utility>
  17. #include <vector>
  18. #include "absl/types/optional.h"
  19. #include "api/task_queue/queued_task.h"
  20. #include "api/task_queue/task_queue_base.h"
  21. #include "api/test/videocodec_test_fixture.h"
  22. #include "api/video/encoded_image.h"
  23. #include "api/video/video_bitrate_allocation.h"
  24. #include "api/video/video_bitrate_allocator.h"
  25. #include "api/video/video_frame.h"
  26. #include "api/video_codecs/video_decoder.h"
  27. #include "api/video_codecs/video_encoder.h"
  28. #include "modules/include/module_common_types.h"
  29. #include "modules/video_coding/codecs/test/videocodec_test_stats_impl.h"
  30. #include "modules/video_coding/include/video_codec_interface.h"
  31. #include "modules/video_coding/utility/ivf_file_writer.h"
  32. #include "rtc_base/buffer.h"
  33. #include "rtc_base/checks.h"
  34. #include "rtc_base/constructor_magic.h"
  35. #include "rtc_base/synchronization/sequence_checker.h"
  36. #include "rtc_base/system/no_unique_address.h"
  37. #include "rtc_base/thread_annotations.h"
  38. #include "rtc_base/thread_checker.h"
  39. #include "test/testsupport/frame_reader.h"
  40. #include "test/testsupport/frame_writer.h"
  41. namespace webrtc {
  42. namespace test {
  43. // Handles encoding/decoding of video using the VideoEncoder/VideoDecoder
  44. // interfaces. This is done in a sequential manner in order to be able to
  45. // measure times properly.
  46. // The class processes a frame at the time for the configured input file.
  47. // It maintains state of where in the source input file the processing is at.
  48. class VideoProcessor {
  49. public:
  50. using VideoDecoderList = std::vector<std::unique_ptr<VideoDecoder>>;
  51. using LayerKey = std::pair<int /* spatial_idx */, int /* temporal_idx */>;
  52. using IvfFileWriterMap = std::map<LayerKey, std::unique_ptr<IvfFileWriter>>;
  53. // TODO(brandtr): Consider changing FrameWriterList to be a FrameWriterMap,
  54. // to be able to save different TLs separately.
  55. using FrameWriterList = std::vector<std::unique_ptr<FrameWriter>>;
  56. VideoProcessor(webrtc::VideoEncoder* encoder,
  57. VideoDecoderList* decoders,
  58. FrameReader* input_frame_reader,
  59. const VideoCodecTestFixture::Config& config,
  60. VideoCodecTestStatsImpl* stats,
  61. IvfFileWriterMap* encoded_frame_writers,
  62. FrameWriterList* decoded_frame_writers);
  63. ~VideoProcessor();
  64. // Reads a frame and sends it to the encoder. When the encode callback
  65. // is received, the encoded frame is buffered. After encoding is finished
  66. // buffered frame is sent to decoder. Quality evaluation is done in
  67. // the decode callback.
  68. void ProcessFrame();
  69. // Updates the encoder with target rates. Must be called at least once.
  70. void SetRates(size_t bitrate_kbps, double framerate_fps);
  71. private:
  72. class VideoProcessorEncodeCompleteCallback
  73. : public webrtc::EncodedImageCallback {
  74. public:
  75. explicit VideoProcessorEncodeCompleteCallback(
  76. VideoProcessor* video_processor)
  77. : video_processor_(video_processor),
  78. task_queue_(TaskQueueBase::Current()) {
  79. RTC_DCHECK(video_processor_);
  80. RTC_DCHECK(task_queue_);
  81. }
  82. Result OnEncodedImage(
  83. const webrtc::EncodedImage& encoded_image,
  84. const webrtc::CodecSpecificInfo* codec_specific_info) override {
  85. RTC_CHECK(codec_specific_info);
  86. // Post the callback to the right task queue, if needed.
  87. if (!task_queue_->IsCurrent()) {
  88. task_queue_->PostTask(std::make_unique<EncodeCallbackTask>(
  89. video_processor_, encoded_image, codec_specific_info));
  90. return Result(Result::OK, 0);
  91. }
  92. video_processor_->FrameEncoded(encoded_image, *codec_specific_info);
  93. return Result(Result::OK, 0);
  94. }
  95. private:
  96. class EncodeCallbackTask : public QueuedTask {
  97. public:
  98. EncodeCallbackTask(VideoProcessor* video_processor,
  99. const webrtc::EncodedImage& encoded_image,
  100. const webrtc::CodecSpecificInfo* codec_specific_info)
  101. : video_processor_(video_processor),
  102. encoded_image_(encoded_image),
  103. codec_specific_info_(*codec_specific_info) {
  104. encoded_image_.Retain();
  105. }
  106. bool Run() override {
  107. video_processor_->FrameEncoded(encoded_image_, codec_specific_info_);
  108. return true;
  109. }
  110. private:
  111. VideoProcessor* const video_processor_;
  112. webrtc::EncodedImage encoded_image_;
  113. const webrtc::CodecSpecificInfo codec_specific_info_;
  114. };
  115. VideoProcessor* const video_processor_;
  116. TaskQueueBase* const task_queue_;
  117. };
  118. class VideoProcessorDecodeCompleteCallback
  119. : public webrtc::DecodedImageCallback {
  120. public:
  121. explicit VideoProcessorDecodeCompleteCallback(
  122. VideoProcessor* video_processor,
  123. size_t simulcast_svc_idx)
  124. : video_processor_(video_processor),
  125. simulcast_svc_idx_(simulcast_svc_idx),
  126. task_queue_(TaskQueueBase::Current()) {
  127. RTC_DCHECK(video_processor_);
  128. RTC_DCHECK(task_queue_);
  129. }
  130. int32_t Decoded(webrtc::VideoFrame& image) override;
  131. int32_t Decoded(webrtc::VideoFrame& image,
  132. int64_t decode_time_ms) override {
  133. return Decoded(image);
  134. }
  135. void Decoded(webrtc::VideoFrame& image,
  136. absl::optional<int32_t> decode_time_ms,
  137. absl::optional<uint8_t> qp) override {
  138. Decoded(image);
  139. }
  140. private:
  141. VideoProcessor* const video_processor_;
  142. const size_t simulcast_svc_idx_;
  143. TaskQueueBase* const task_queue_;
  144. };
  145. // Invoked by the callback adapter when a frame has completed encoding.
  146. void FrameEncoded(const webrtc::EncodedImage& encoded_image,
  147. const webrtc::CodecSpecificInfo& codec_specific);
  148. // Invoked by the callback adapter when a frame has completed decoding.
  149. void FrameDecoded(const webrtc::VideoFrame& image, size_t simulcast_svc_idx);
  150. void DecodeFrame(const EncodedImage& encoded_image, size_t simulcast_svc_idx);
  151. // In order to supply the SVC decoders with super frames containing all
  152. // lower layer frames, we merge and store the layer frames in this method.
  153. const webrtc::EncodedImage* BuildAndStoreSuperframe(
  154. const EncodedImage& encoded_image,
  155. const VideoCodecType codec,
  156. size_t frame_number,
  157. size_t simulcast_svc_idx,
  158. bool inter_layer_predicted) RTC_RUN_ON(sequence_checker_);
  159. // Test input/output.
  160. VideoCodecTestFixture::Config config_ RTC_GUARDED_BY(sequence_checker_);
  161. const size_t num_simulcast_or_spatial_layers_;
  162. VideoCodecTestStatsImpl* const stats_;
  163. // Codecs.
  164. webrtc::VideoEncoder* const encoder_;
  165. VideoDecoderList* const decoders_;
  166. const std::unique_ptr<VideoBitrateAllocator> bitrate_allocator_;
  167. VideoBitrateAllocation bitrate_allocation_ RTC_GUARDED_BY(sequence_checker_);
  168. double framerate_fps_ RTC_GUARDED_BY(sequence_checker_);
  169. // Adapters for the codec callbacks.
  170. VideoProcessorEncodeCompleteCallback encode_callback_;
  171. // Assign separate callback object to each decoder. This allows us to identify
  172. // decoded layer in frame decode callback.
  173. // simulcast_svc_idx -> decode callback.
  174. std::vector<std::unique_ptr<VideoProcessorDecodeCompleteCallback>>
  175. decode_callback_;
  176. // Each call to ProcessFrame() will read one frame from |input_frame_reader_|.
  177. FrameReader* const input_frame_reader_;
  178. // Input frames are used as reference for frame quality evaluations.
  179. // Async codecs might queue frames. To handle that we keep input frame
  180. // and release it after corresponding coded frame is decoded and quality
  181. // measurement is done.
  182. // frame_number -> frame.
  183. std::map<size_t, VideoFrame> input_frames_ RTC_GUARDED_BY(sequence_checker_);
  184. // Encoder delivers coded frame layer-by-layer. We store coded frames and
  185. // then, after all layers are encoded, decode them. Such separation of
  186. // frame processing on superframe level simplifies encoding/decoding time
  187. // measurement.
  188. // simulcast_svc_idx -> merged SVC encoded frame.
  189. std::vector<EncodedImage> merged_encoded_frames_
  190. RTC_GUARDED_BY(sequence_checker_);
  191. // These (optional) file writers are used to persistently store the encoded
  192. // and decoded bitstreams. Each frame writer is enabled by being non-null.
  193. IvfFileWriterMap* const encoded_frame_writers_;
  194. FrameWriterList* const decoded_frame_writers_;
  195. // Metadata for inputed/encoded/decoded frames. Used for frame identification,
  196. // frame drop detection, etc. We assume that encoded/decoded frames are
  197. // ordered within each simulcast/spatial layer, but we do not make any
  198. // assumptions of frame ordering between layers.
  199. size_t last_inputed_frame_num_ RTC_GUARDED_BY(sequence_checker_);
  200. size_t last_inputed_timestamp_ RTC_GUARDED_BY(sequence_checker_);
  201. // simulcast_svc_idx -> encode status.
  202. std::vector<bool> first_encoded_frame_ RTC_GUARDED_BY(sequence_checker_);
  203. // simulcast_svc_idx -> frame_number.
  204. std::vector<size_t> last_encoded_frame_num_ RTC_GUARDED_BY(sequence_checker_);
  205. // simulcast_svc_idx -> decode status.
  206. std::vector<bool> first_decoded_frame_ RTC_GUARDED_BY(sequence_checker_);
  207. // simulcast_svc_idx -> frame_number.
  208. std::vector<size_t> last_decoded_frame_num_ RTC_GUARDED_BY(sequence_checker_);
  209. // simulcast_svc_idx -> buffer.
  210. std::vector<rtc::Buffer> decoded_frame_buffer_
  211. RTC_GUARDED_BY(sequence_checker_);
  212. // Time spent in frame encode callback. It is accumulated for layers and
  213. // reset when frame encode starts. When next layer is encoded post-encode time
  214. // is substracted from measured encode time. Thus we get pure encode time.
  215. int64_t post_encode_time_ns_ RTC_GUARDED_BY(sequence_checker_);
  216. // This class must be operated on a TaskQueue.
  217. RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
  218. RTC_DISALLOW_COPY_AND_ASSIGN(VideoProcessor);
  219. };
  220. } // namespace test
  221. } // namespace webrtc
  222. #endif // MODULES_VIDEO_CODING_CODECS_TEST_VIDEOPROCESSOR_H_