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