xref: /aosp_15_r20/external/webrtc/test/pc/e2e/analyzer/video/video_dumping.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2022 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 #include "test/pc/e2e/analyzer/video/video_dumping.h"
11 
12 #include <stdio.h>
13 
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "absl/strings/string_view.h"
20 #include "api/test/video/video_frame_writer.h"
21 #include "api/video/video_frame.h"
22 #include "rtc_base/logging.h"
23 #include "system_wrappers/include/clock.h"
24 #include "test/testsupport/video_frame_writer.h"
25 
26 namespace webrtc {
27 namespace webrtc_pc_e2e {
28 namespace {
29 
30 class VideoFrameIdsWriter final : public test::VideoFrameWriter {
31  public:
VideoFrameIdsWriter(absl::string_view file_name)32   explicit VideoFrameIdsWriter(absl::string_view file_name)
33       : file_name_(file_name) {
34     output_file_ = fopen(file_name_.c_str(), "wb");
35     RTC_LOG(LS_INFO) << "Writing VideoFrame IDs into " << file_name_;
36     RTC_CHECK(output_file_ != nullptr)
37         << "Failed to open file to dump frame ids for writing: " << file_name_;
38   }
~VideoFrameIdsWriter()39   ~VideoFrameIdsWriter() override { Close(); }
40 
WriteFrame(const VideoFrame & frame)41   bool WriteFrame(const VideoFrame& frame) override {
42     RTC_CHECK(output_file_ != nullptr) << "Writer is already closed";
43     int chars_written = fprintf(output_file_, "%d\n", frame.id());
44     if (chars_written < 2) {
45       RTC_LOG(LS_ERROR) << "Failed to write frame id to the output file: "
46                         << file_name_;
47       return false;
48     }
49     return true;
50   }
51 
Close()52   void Close() override {
53     if (output_file_ != nullptr) {
54       RTC_LOG(LS_INFO) << "Closing file for VideoFrame IDs: " << file_name_;
55       fclose(output_file_);
56       output_file_ = nullptr;
57     }
58   }
59 
60  private:
61   const std::string file_name_;
62   FILE* output_file_;
63 };
64 
65 // Broadcast received frame to multiple underlying frame writers.
66 class BroadcastingFrameWriter final : public test::VideoFrameWriter {
67  public:
BroadcastingFrameWriter(std::vector<std::unique_ptr<test::VideoFrameWriter>> delegates)68   explicit BroadcastingFrameWriter(
69       std::vector<std::unique_ptr<test::VideoFrameWriter>> delegates)
70       : delegates_(std::move(delegates)) {}
~BroadcastingFrameWriter()71   ~BroadcastingFrameWriter() override { Close(); }
72 
WriteFrame(const webrtc::VideoFrame & frame)73   bool WriteFrame(const webrtc::VideoFrame& frame) override {
74     for (auto& delegate : delegates_) {
75       if (!delegate->WriteFrame(frame)) {
76         return false;
77       }
78     }
79     return true;
80   }
81 
Close()82   void Close() override {
83     for (auto& delegate : delegates_) {
84       delegate->Close();
85     }
86   }
87 
88  private:
89   std::vector<std::unique_ptr<test::VideoFrameWriter>> delegates_;
90 };
91 
92 }  // namespace
93 
VideoWriter(test::VideoFrameWriter * video_writer,int sampling_modulo)94 VideoWriter::VideoWriter(test::VideoFrameWriter* video_writer,
95                          int sampling_modulo)
96     : video_writer_(video_writer), sampling_modulo_(sampling_modulo) {}
97 
OnFrame(const VideoFrame & frame)98 void VideoWriter::OnFrame(const VideoFrame& frame) {
99   if (frames_counter_++ % sampling_modulo_ != 0) {
100     return;
101   }
102   bool result = video_writer_->WriteFrame(frame);
103   RTC_CHECK(result) << "Failed to write frame";
104 }
105 
CreateVideoFrameWithIdsWriter(std::unique_ptr<test::VideoFrameWriter> video_writer_delegate,absl::string_view frame_ids_dump_file_name)106 std::unique_ptr<test::VideoFrameWriter> CreateVideoFrameWithIdsWriter(
107     std::unique_ptr<test::VideoFrameWriter> video_writer_delegate,
108     absl::string_view frame_ids_dump_file_name) {
109   std::vector<std::unique_ptr<test::VideoFrameWriter>> requested_writers;
110   requested_writers.push_back(std::move(video_writer_delegate));
111   requested_writers.push_back(
112       std::make_unique<VideoFrameIdsWriter>(frame_ids_dump_file_name));
113   return std::make_unique<BroadcastingFrameWriter>(
114       std::move(requested_writers));
115 }
116 
117 }  // namespace webrtc_pc_e2e
118 }  // namespace webrtc
119