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