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
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133

media / capture / video / file_video_capture_device.h [blame]

// Copyright 2013 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_CAPTURE_VIDEO_FILE_VIDEO_CAPTURE_DEVICE_H_
#define MEDIA_CAPTURE_VIDEO_FILE_VIDEO_CAPTURE_DEVICE_H_

#include <stdint.h>

#include <memory>

#include "base/containers/queue.h"
#include "base/files/file.h"
#include "base/files/memory_mapped_file.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
#include "media/capture/video/video_capture_device.h"

namespace media {

class VideoFileParser;

// Implementation of a VideoCaptureDevice class that reads from a file. Used for
// testing the video capture pipeline when no real hardware is available. The
// supported file formats are YUV4MPEG2 (a.k.a. Y4M) and MJPEG/JPEG. YUV4MPEG2
// is a minimal container with a series of uncompressed video only frames, see
// the link http://wiki.multimedia.cx/index.php?title=YUV4MPEG2 for more
// information on the file format. Several restrictions and notes apply, see the
// implementation file.
// Example Y4M videos can be found in http://media.xiph.org/video/derf.
// Example MJPEG videos can be found in media/test/data/bear.mjpeg.
// Restrictions: Y4M videos should have .y4m file extension and MJPEG videos
// should have .mjpeg file extension.
class CAPTURE_EXPORT FileVideoCaptureDevice : public VideoCaptureDevice {
 public:
  // Reads and parses the header of a |file_path|, returning the collected
  // pixel format in |video_format|. Returns true on file parsed successfully,
  // or false.
  // Restrictions: Only trivial Y4M per-frame headers and MJPEG are supported.
  static bool GetVideoCaptureFormat(const base::FilePath& file_path,
                                    VideoCaptureFormat* video_format);

  // Constructor of the class, with a fully qualified file path as input, which
  // represents the Y4M or MJPEG file to stream repeatedly.
  explicit FileVideoCaptureDevice(
      const base::FilePath& file_path,
      std::unique_ptr<gpu::GpuMemoryBufferSupport> gmb_support = nullptr);

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

  // VideoCaptureDevice implementation, class methods.
  ~FileVideoCaptureDevice() override;
  void AllocateAndStart(
      const VideoCaptureParams& params,
      std::unique_ptr<VideoCaptureDevice::Client> client) override;
  void StopAndDeAllocate() override;
  void GetPhotoState(GetPhotoStateCallback callback) override;
  void SetPhotoOptions(mojom::PhotoSettingsPtr settings,
                       SetPhotoOptionsCallback callback) override;
  void TakePhoto(TakePhotoCallback callback) override;

 private:
  // Opens a given file |file_path| for reading, and stores collected format
  // information in |video_format|. Returns the parsed file to the
  // caller, who is responsible for closing it.
  static std::unique_ptr<VideoFileParser> GetVideoFileParser(
      const base::FilePath& file_path,
      VideoCaptureFormat* video_format);

  // Crops frame with respect to PTZ settings.
  std::vector<uint8_t> CropPTZRegion(const uint8_t* frame,
                                     size_t frame_buffer_size,
                                     VideoPixelFormat* final_pixel_format);

  // Called on the |capture_thread_|.
  void OnAllocateAndStart(const VideoCaptureParams& params,
                          std::unique_ptr<Client> client);
  void OnGetPhotoState(GetPhotoStateCallback callback);
  void OnSetPhotoOptions(mojom::PhotoSettingsPtr settings,
                         SetPhotoOptionsCallback callback);
  void OnStopAndDeAllocate();
  const uint8_t* GetNextFrame();
  void OnCaptureTask();

  // |thread_checker_| is used to check that destructor, AllocateAndStart() and
  // StopAndDeAllocate() are called in the correct thread that owns the object.
  base::ThreadChecker thread_checker_;

  // |capture_thread_| is used for internal operations via posting tasks to it.
  // It is active between OnAllocateAndStart() and OnStopAndDeAllocate().
  base::Thread capture_thread_;
  // The following members belong to |capture_thread_|.
  std::unique_ptr<VideoCaptureDevice::Client> client_;
  const base::FilePath file_path_;
  std::unique_ptr<VideoFileParser> file_parser_;
  VideoCaptureFormat capture_format_;

  // The max zoom-able integer level that can be zoomed-in with respect to
  // aspect ratio of original file.
  int zoom_max_levels_;
  // Numerator of file aspect ratio.
  int aspect_ratio_numerator_;
  // Denominator of file aspect ratio.
  int aspect_ratio_denominator_;
  // Current zoom values.
  int zoom_;
  // Current pan values.
  int pan_;
  // Current tilt values.
  int tilt_;

  // Target time for the next frame.
  base::TimeTicks next_frame_time_;
  // The system time when we receive the first frame.
  base::TimeTicks first_ref_time_;

  // Whether GpuMemoryBuffer or MappableSI based video capture buffer is enabled
  // or not.
  bool video_capture_use_mappable_buffer_ = false;
  std::unique_ptr<gpu::GpuMemoryBufferSupport> gmb_support_;

  // Guards the below variables from concurrent access between methods running
  // on the main thread and |capture_thread_|.
  base::Lock lock_;
  base::queue<TakePhotoCallback> take_photo_callbacks_;
};

}  // namespace media

#endif  // MEDIA_CAPTURE_VIDEO_FILE_VIDEO_CAPTURE_DEVICE_H_