• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
VideoRecorder()56   VideoRecorder() {}
~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.
IsFileVideoCapturerDevice(const Device & device)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.
CreateFileVideoCapturerDevice(const std::string & 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.
set_repeat(int repeat)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.
set_ignore_framerate(bool ignore_framerate)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();
IsScreencast()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).
frame()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