Home | History | Annotate | Download | only in devices
      1 /*
      2  * libjingle
      3  * Copyright 2004 Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 //
     29 // This file contains two classes, VideoRecorder and FileVideoCapturer.
     30 // VideoRecorder records the captured frames into a file. The file stores a
     31 // sequence of captured frames; each frame has a header defined in struct
     32 // CapturedFrame, followed by the frame data.
     33 //
     34 // FileVideoCapturer, a subclass of VideoCapturer, is a simulated video capturer
     35 // that periodically reads images from a previously recorded file.
     36 
     37 #ifndef TALK_MEDIA_DEVICES_FILEVIDEOCAPTURER_H_
     38 #define TALK_MEDIA_DEVICES_FILEVIDEOCAPTURER_H_
     39 
     40 #include <string>
     41 #include <vector>
     42 
     43 #include "talk/media/base/videocapturer.h"
     44 #include "webrtc/base/stream.h"
     45 #include "webrtc/base/stringutils.h"
     46 
     47 namespace rtc {
     48 class FileStream;
     49 }
     50 
     51 namespace cricket {
     52 
     53 // Utility class to record the frames captured by a video capturer into a file.
     54 class VideoRecorder {
     55  public:
     56   VideoRecorder() {}
     57   ~VideoRecorder() { Stop(); }
     58 
     59   // Start the recorder by opening the specified file. Return true if the file
     60   // is opened successfully. write_header should normally be true; false means
     61   // write raw frame pixel data to file without any headers.
     62   bool Start(const std::string& filename, bool write_header);
     63   // Stop the recorder by closing the file.
     64   void Stop();
     65   // Record a video frame to the file. Return true if the frame is written to
     66   // the file successfully. This method needs to be called after Start() and
     67   // before Stop().
     68   bool RecordFrame(const CapturedFrame& frame);
     69 
     70  private:
     71   rtc::FileStream video_file_;
     72   bool write_header_;
     73 
     74   RTC_DISALLOW_COPY_AND_ASSIGN(VideoRecorder);
     75 };
     76 
     77 // Simulated video capturer that periodically reads frames from a file.
     78 class FileVideoCapturer : public VideoCapturer {
     79  public:
     80   static const int kForever = -1;
     81 
     82   FileVideoCapturer();
     83   virtual ~FileVideoCapturer();
     84 
     85   // Determines if the given device is actually a video file, to be captured
     86   // with a FileVideoCapturer.
     87   static bool IsFileVideoCapturerDevice(const Device& device) {
     88     return rtc::starts_with(device.id.c_str(), kVideoFileDevicePrefix);
     89   }
     90 
     91   // Creates a fake device for the given filename.
     92   static Device CreateFileVideoCapturerDevice(const std::string& filename) {
     93     std::stringstream id;
     94     id << kVideoFileDevicePrefix << filename;
     95     return Device(filename, id.str());
     96   }
     97 
     98   // Set how many times to repeat reading the file. Repeat forever if the
     99   // parameter is kForever; no repeat if the parameter is 0 or
    100   // less than -1.
    101   void set_repeat(int repeat) { repeat_ = repeat; }
    102 
    103   // If ignore_framerate is true, file is read as quickly as possible. If
    104   // false, read rate is controlled by the timestamps in the video file
    105   // (thus simulating camera capture). Default value set to false.
    106   void set_ignore_framerate(bool ignore_framerate) {
    107     ignore_framerate_ = ignore_framerate;
    108   }
    109 
    110   // Initializes the capturer with the given file.
    111   bool Init(const std::string& filename);
    112 
    113   // Initializes the capturer with the given device. This should only be used
    114   // if IsFileVideoCapturerDevice returned true for the given device.
    115   bool Init(const Device& device);
    116 
    117   // Override virtual methods of parent class VideoCapturer.
    118   virtual CaptureState Start(const VideoFormat& capture_format);
    119   virtual void Stop();
    120   virtual bool IsRunning();
    121   virtual bool IsScreencast() const { return false; }
    122 
    123  protected:
    124   // Override virtual methods of parent class VideoCapturer.
    125   virtual bool GetPreferredFourccs(std::vector<uint32_t>* fourccs);
    126 
    127   // Read the frame header from the file stream, video_file_.
    128   rtc::StreamResult ReadFrameHeader(CapturedFrame* frame);
    129 
    130   // Read a frame and determine how long to wait for the next frame. If the
    131   // frame is read successfully, Set the output parameter, wait_time_ms and
    132   // return true. Otherwise, do not change wait_time_ms and return false.
    133   bool ReadFrame(bool first_frame, int* wait_time_ms);
    134 
    135   // Return the CapturedFrame - useful for extracting contents after reading
    136   // a frame. Should be used only while still reading a file (i.e. only while
    137   // the CapturedFrame object still exists).
    138   const CapturedFrame* frame() const {
    139     return &captured_frame_;
    140   }
    141 
    142  private:
    143   class FileReadThread;  // Forward declaration, defined in .cc.
    144 
    145   static const char* kVideoFileDevicePrefix;
    146   rtc::FileStream video_file_;
    147   CapturedFrame captured_frame_;
    148   // The number of bytes allocated buffer for captured_frame_.data.
    149   uint32_t frame_buffer_size_;
    150   FileReadThread* file_read_thread_;
    151   int repeat_;  // How many times to repeat the file.
    152   int64_t last_frame_timestamp_ns_;  // Timestamp of last read frame.
    153   bool ignore_framerate_;
    154 
    155   RTC_DISALLOW_COPY_AND_ASSIGN(FileVideoCapturer);
    156 };
    157 
    158 }  // namespace cricket
    159 
    160 #endif  // TALK_MEDIA_DEVICES_FILEVIDEOCAPTURER_H_
    161