1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108

media / gpu / test / video_frame_file_writer.h [blame]

// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_GPU_TEST_VIDEO_FRAME_FILE_WRITER_H_
#define MEDIA_GPU_TEST_VIDEO_FRAME_FILE_WRITER_H_

#include <limits>
#include <memory>

#include "base/files/file_path.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "media/gpu/test/video_frame_helpers.h"

namespace media {

class VideoFrameMapper;

namespace test {

// The video frame file writer class implements functionality to write video
// frames to file. The supported output formats are PNG and raw I420 YUV.
class VideoFrameFileWriter : public VideoFrameProcessor {
 public:
  // Supported output formats.
  enum class OutputFormat {
    kPNG = 0,
    kYUV,
  };

  VideoFrameFileWriter(const VideoFrameFileWriter&) = delete;
  VideoFrameFileWriter& operator=(const VideoFrameFileWriter&) = delete;

  ~VideoFrameFileWriter() override;

  // Create an instance of the video frame file writer.
  // |output_folder| specifies the folder video frames will be written to.
  // |output_format| specifies the output file format.
  // |output_limit| limits the max number of files that can be written.
  static std::unique_ptr<VideoFrameFileWriter> Create(
      const base::FilePath& output_folder,
      OutputFormat output_format = OutputFormat::kPNG,
      size_t output_limit = std::numeric_limits<size_t>::max(),
      const base::FilePath::StringType& output_file_prefix =
          base::FilePath::StringType());

  // Interface VideoFrameProcessor
  void ProcessVideoFrame(scoped_refptr<const VideoFrame> video_frame,
                         size_t frame_index) override;
  // Wait until all currently scheduled frame write operations are done.
  bool WaitUntilDone() override;

 private:
  VideoFrameFileWriter(const base::FilePath& output_folder,
                       OutputFormat output_format,
                       size_t output_limit,
                       const base::FilePath::StringType& output_prefix);

  // Initialize the video frame file writer.
  bool Initialize();

  void CleanUpOnWriterThread();

  // Writes the specified video frame to file on the |file_writer_thread_|.
  void ProcessVideoFrameTask(scoped_refptr<const VideoFrame> video_frame,
                             size_t frame_index);

  // Write the video frame to disk in PNG format.
  void WriteVideoFramePNG(scoped_refptr<const VideoFrame> video_frame,
                          const base::FilePath& filename);
  // Write the video frame to disk in I420 YUV format.
  void WriteVideoFrameYUV(scoped_refptr<const VideoFrame> video_frame,
                          const base::FilePath& filename);

  // Output folder the frames will be written to.
  const base::FilePath output_folder_;
  // Output format of the frames.
  const OutputFormat output_format_;
  // The maximum number of frames that can be written.
  const size_t output_limit_;
  // The prefix of the output file.
  const base::FilePath::StringType output_file_prefix_;

  // The video frame mapper used to gain access to the raw video frame memory.
  std::unique_ptr<VideoFrameMapper> video_frame_mapper_;

  // The number of frames currently queued for writing.
  size_t num_frames_writing_ GUARDED_BY(frame_writer_lock_);
  // The number of frames currently written or queued to be written.
  size_t num_frames_writes_requested_ = 0u;

  // Thread on which video frame writing is done.
  base::Thread frame_writer_thread_;
  mutable base::Lock frame_writer_lock_;
  mutable base::ConditionVariable frame_writer_cv_;

  SEQUENCE_CHECKER(writer_sequence_checker_);
  SEQUENCE_CHECKER(writer_thread_sequence_checker_);
};

}  // namespace test
}  // namespace media

#endif  // MEDIA_GPU_TEST_VIDEO_FRAME_FILE_WRITER_H_