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