1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef MEDIA_GPU_TEST_VIDEO_FRAME_FILE_WRITER_H_
6 #define MEDIA_GPU_TEST_VIDEO_FRAME_FILE_WRITER_H_
7 
8 #include <limits>
9 #include <memory>
10 
11 #include "base/files/file_path.h"
12 #include "base/memory/scoped_refptr.h"
13 #include "base/sequence_checker.h"
14 #include "base/synchronization/condition_variable.h"
15 #include "base/synchronization/lock.h"
16 #include "base/threading/thread.h"
17 #include "media/gpu/test/video_frame_helpers.h"
18 
19 namespace media {
20 
21 class VideoFrameMapper;
22 
23 namespace test {
24 
25 // The video frame file writer class implements functionality to write video
26 // frames to file. The supported output formats are PNG and raw I420 YUV.
27 class VideoFrameFileWriter : public VideoFrameProcessor {
28  public:
29   // Supported output formats.
30   enum class OutputFormat {
31     kPNG = 0,
32     kYUV,
33   };
34 
35   ~VideoFrameFileWriter() override;
36 
37   // Create an instance of the video frame file writer.
38   // |output_folder| specifies the folder video frames will be written to.
39   // |output_format| specifies the output file format.
40   // |output_limit| limits the max number of files that can be written.
41   static std::unique_ptr<VideoFrameFileWriter> Create(
42       const base::FilePath& output_folder,
43       OutputFormat output_format = OutputFormat::kPNG,
44       size_t output_limit = std::numeric_limits<size_t>::max());
45 
46   // Interface VideoFrameProcessor
47   void ProcessVideoFrame(scoped_refptr<const VideoFrame> video_frame,
48                          size_t frame_index) override;
49   // Wait until all currently scheduled frame write operations are done.
50   bool WaitUntilDone() override;
51 
52  private:
53   VideoFrameFileWriter(const base::FilePath& output_folder,
54                        OutputFormat output_format,
55                        size_t output_limit);
56 
57   // Initialize the video frame file writer.
58   bool Initialize();
59 
60   // Writes the specified video frame to file on the |file_writer_thread_|.
61   void ProcessVideoFrameTask(scoped_refptr<const VideoFrame> video_frame,
62                              size_t frame_index);
63 
64   // Write the video frame to disk in PNG format.
65   void WriteVideoFramePNG(scoped_refptr<const VideoFrame> video_frame,
66                           const base::FilePath& filename);
67   // Write the video frame to disk in I420 YUV format.
68   void WriteVideoFrameYUV(scoped_refptr<const VideoFrame> video_frame,
69                           const base::FilePath& filename);
70 
71   // Output folder the frames will be written to.
72   const base::FilePath output_folder_;
73   // Output format of the frames.
74   const OutputFormat output_format_;
75   // The maximum number of frames that can be written.
76   const size_t output_limit_;
77 
78   // The video frame mapper used to gain access to the raw video frame memory.
79   std::unique_ptr<VideoFrameMapper> video_frame_mapper_;
80 
81   // The number of frames currently queued for writing.
82   size_t num_frames_writing_ GUARDED_BY(frame_writer_lock_);
83   // The number of frames currently written or queued to be written.
84   size_t num_frames_writes_requested_ = 0u;
85 
86   // Thread on which video frame writing is done.
87   base::Thread frame_writer_thread_;
88   mutable base::Lock frame_writer_lock_;
89   mutable base::ConditionVariable frame_writer_cv_;
90 
91   SEQUENCE_CHECKER(writer_sequence_checker_);
92   SEQUENCE_CHECKER(writer_thread_sequence_checker_);
93 
94   DISALLOW_COPY_AND_ASSIGN(VideoFrameFileWriter);
95 };
96 
97 }  // namespace test
98 }  // namespace media
99 
100 #endif  // MEDIA_GPU_TEST_VIDEO_FRAME_FILE_WRITER_H_
101