xref: /aosp_15_r20/external/webrtc/test/testsupport/ivf_video_frame_generator.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2019 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 
11 #ifndef TEST_TESTSUPPORT_IVF_VIDEO_FRAME_GENERATOR_H_
12 #define TEST_TESTSUPPORT_IVF_VIDEO_FRAME_GENERATOR_H_
13 
14 #include <memory>
15 #include <string>
16 
17 #include "absl/types/optional.h"
18 #include "api/sequence_checker.h"
19 #include "api/test/frame_generator_interface.h"
20 #include "api/video/video_codec_type.h"
21 #include "api/video/video_frame.h"
22 #include "api/video_codecs/video_decoder.h"
23 #include "modules/video_coding/utility/ivf_file_reader.h"
24 #include "rtc_base/event.h"
25 #include "rtc_base/synchronization/mutex.h"
26 
27 namespace webrtc {
28 namespace test {
29 
30 // All methods except constructor must be used from the same thread.
31 class IvfVideoFrameGenerator : public FrameGeneratorInterface {
32  public:
33   explicit IvfVideoFrameGenerator(const std::string& file_name);
34   ~IvfVideoFrameGenerator() override;
35 
36   VideoFrameData NextFrame() override;
37   void ChangeResolution(size_t width, size_t height) override;
38 
39  private:
40   class DecodedCallback : public DecodedImageCallback {
41    public:
DecodedCallback(IvfVideoFrameGenerator * reader)42     explicit DecodedCallback(IvfVideoFrameGenerator* reader)
43         : reader_(reader) {}
44 
45     int32_t Decoded(VideoFrame& decoded_image) override;
46     int32_t Decoded(VideoFrame& decoded_image, int64_t decode_time_ms) override;
47     void Decoded(VideoFrame& decoded_image,
48                  absl::optional<int32_t> decode_time_ms,
49                  absl::optional<uint8_t> qp) override;
50 
51    private:
52     IvfVideoFrameGenerator* const reader_;
53   };
54 
55   void OnFrameDecoded(const VideoFrame& decoded_frame);
56   static std::unique_ptr<VideoDecoder> CreateVideoDecoder(
57       VideoCodecType codec_type);
58 
59   DecodedCallback callback_;
60   std::unique_ptr<IvfFileReader> file_reader_;
61   std::unique_ptr<VideoDecoder> video_decoder_;
62 
63   size_t width_;
64   size_t height_;
65 
66   // This lock is used to ensure that all API method will be called
67   // sequentially. It is required because we need to ensure that generator
68   // won't be destroyed while it is reading the next frame on another thread,
69   // because it will cause SIGSEGV when decoder callback will be invoked.
70   //
71   // FrameGenerator is injected into PeerConnection via some scoped_ref object
72   // and it can happen that the last pointer will be destroyed on the different
73   // thread comparing to the one from which frames were read.
74   Mutex lock_;
75   // This lock is used to sync between sending and receiving frame from decoder.
76   // We can't reuse `lock_` because then generator can be destroyed between
77   // frame was sent to decoder and decoder callback was invoked.
78   Mutex frame_decode_lock_;
79 
80   rtc::Event next_frame_decoded_;
81   absl::optional<VideoFrame> next_frame_ RTC_GUARDED_BY(frame_decode_lock_);
82 };
83 
84 }  // namespace test
85 }  // namespace webrtc
86 
87 #endif  // TEST_TESTSUPPORT_IVF_VIDEO_FRAME_GENERATOR_H_
88