1 // libjingle
2 // Copyright 2004--2005, 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_SESSION_PHONE_FILEVIDEOCAPTURER_H_
35 #define TALK_SESSION_PHONE_FILEVIDEOCAPTURER_H_
36 
37 #include <string>
38 #include <vector>
39 
40 #include "talk/base/stream.h"
41 #include "talk/session/phone/videocapturer.h"
42 
43 namespace talk_base {
44 class FileStream;
45 }
46 
47 namespace cricket {
48 
49 // Utility class to record the frames captured by a video capturer into a file.
50 class VideoRecorder {
51  public:
VideoRecorder()52   VideoRecorder() {}
~VideoRecorder()53   ~VideoRecorder() { Stop(); }
54 
55   // Start the recorder by opening the specified file. Return true if the file
56   // is opened successfully. write_header should normally be true; false means
57   // write raw frame pixel data to file without any headers.
58   bool Start(const std::string& filename, bool write_header);
59   // Stop the recorder by closing the file.
60   void Stop();
61   // Record a video frame to the file. Return true if the frame is written to
62   // the file successfully. This method needs to be called after Start() and
63   // before Stop().
64   bool RecordFrame(const CapturedFrame& frame);
65 
66  private:
67   talk_base::FileStream video_file_;
68   bool write_header_;
69 
70   DISALLOW_COPY_AND_ASSIGN(VideoRecorder);
71 };
72 
73 // Simulated video capturer that periodically reads frames from a file.
74 class FileVideoCapturer : public VideoCapturer {
75  public:
76   FileVideoCapturer();
77   virtual ~FileVideoCapturer();
78 
79   // Determines if the given device is actually a video file, to be captured
80   // with a FileVideoCapturer.
IsFileVideoCapturerDevice(const Device & device)81   static bool IsFileVideoCapturerDevice(const Device& device) {
82     return device.id == kVideoFileDeviceName;
83   }
84 
85   // Creates a fake device for the given filename.
CreateFileVideoCapturerDevice(const std::string & filename)86   static Device CreateFileVideoCapturerDevice(const std::string& filename) {
87     return Device(filename, kVideoFileDeviceName);
88   }
89 
90   // Set how many times to repeat reading the file. Repeat forever if the
91   // parameter is talk_base::kForever(-1); no repeat if the parameter is 0 or
92   // less than -1.
set_repeat(int repeat)93   void set_repeat(int repeat) { repeat_ = repeat; }
94 
95   // If ignore_framerate is true, file is read as quickly as possible. If
96   // false, read rate is controlled by the timestamps in the video file
97   // (thus simulating camera capture). Default value set to false.
set_ignore_framerate(bool ignore_framerate)98   void set_ignore_framerate(bool ignore_framerate) {
99     ignore_framerate_ = ignore_framerate;
100   }
101 
102   // Initializes the capturer with the given file.
103   bool Init(const std::string& filename);
104 
105   // Initializes the capturer with the given device. This should only be used
106   // if IsFileVideoCapturerDevice returned true for the given device.
107   bool Init(const Device& device);
108 
109   // Override virtual methods of parent class VideoCapturer.
110   virtual CaptureResult Start(const VideoFormat& capture_format);
111   virtual void Stop();
112   virtual bool IsRunning();
113 
114  protected:
115   // Override virtual methods of parent class VideoCapturer.
116   virtual bool GetPreferredFourccs(std::vector<uint32>* fourccs);
117 
118   // Read the frame header from the file stream, video_file_.
119   talk_base::StreamResult ReadFrameHeader(CapturedFrame* frame);
120 
121   // Read a frame and determine how long to wait for the next frame. If the
122   // frame is read successfully, Set the output parameter, wait_time_ms and
123   // return true. Otherwise, do not change wait_time_ms and return false.
124   bool ReadFrame(bool first_frame, int* wait_time_ms);
125 
126   // Return the CapturedFrame - useful for extracting contents after reading
127   // a frame. Should be used only while still reading a file (i.e. only while
128   // the CapturedFrame object still exists).
frame()129   const CapturedFrame* frame() const {
130     return &captured_frame_;
131   }
132 
133  private:
134   class FileReadThread;  // Forward declaration, defined in .cc.
135 
136   static const char* kVideoFileDeviceName;
137   talk_base::FileStream video_file_;
138   CapturedFrame captured_frame_;
139   // The number of bytes allocated buffer for captured_frame_.data.
140   uint32 frame_buffer_size_;
141   FileReadThread* file_read_thread_;
142   int repeat_;  // How many times to repeat the file.
143   int64 start_time_ns_;  // Time when the file video capturer starts.
144   int64 last_frame_timestamp_ns_;  // Timestamp of last read frame.
145   bool ignore_framerate_;
146 
147   DISALLOW_COPY_AND_ASSIGN(FileVideoCapturer);
148 };
149 
150 }  // namespace cricket
151 
152 #endif  // TALK_SESSION_PHONE_FILEVIDEOCAPTURER_H_
153