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