OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/video/capture/file_video_capture_device.h" | 5 #include "media/video/capture/file_video_capture_device.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | |
11 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
12 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
13 #include "base/strings/string_piece.h" | 12 #include "base/strings/string_piece.h" |
14 #include "base/strings/sys_string_conversions.h" | 13 #include "base/strings/sys_string_conversions.h" |
15 #include "media/base/media_switches.h" | |
16 | |
17 | 14 |
18 namespace media { | 15 namespace media { |
19 static const char kFileVideoCaptureDeviceName[] = | |
20 "/dev/placeholder-for-file-backed-fake-capture-device"; | |
21 | |
22 static const int kY4MHeaderMaxSize = 200; | 16 static const int kY4MHeaderMaxSize = 200; |
23 static const char kY4MSimpleFrameDelimiter[] = "FRAME"; | 17 static const char kY4MSimpleFrameDelimiter[] = "FRAME"; |
24 static const int kY4MSimpleFrameDelimiterSize = 6; | 18 static const int kY4MSimpleFrameDelimiterSize = 6; |
25 | 19 |
26 int ParseY4MInt(const base::StringPiece& token) { | 20 int ParseY4MInt(const base::StringPiece& token) { |
27 int temp_int; | 21 int temp_int; |
28 CHECK(base::StringToInt(token, &temp_int)) << token; | 22 CHECK(base::StringToInt(token, &temp_int)) << token; |
29 return temp_int; | 23 return temp_int; |
30 } | 24 } |
31 | 25 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 index = blank_position + 1; | 97 index = blank_position + 1; |
104 } | 98 } |
105 // Last video format semantic correctness check before sending it back. | 99 // Last video format semantic correctness check before sending it back. |
106 CHECK(video_format->IsValid()); | 100 CHECK(video_format->IsValid()); |
107 } | 101 } |
108 | 102 |
109 // Reads and parses the header of a Y4M |file|, returning the collected pixel | 103 // Reads and parses the header of a Y4M |file|, returning the collected pixel |
110 // format in |video_format|. Returns the index of the first byte of the first | 104 // format in |video_format|. Returns the index of the first byte of the first |
111 // video frame. | 105 // video frame. |
112 // Restrictions: Only trivial per-frame headers are supported. | 106 // Restrictions: Only trivial per-frame headers are supported. |
113 int64 ParseFileAndExtractVideoFormat( | 107 // static |
| 108 int64 FileVideoCaptureDevice::ParseFileAndExtractVideoFormat( |
114 base::File* file, | 109 base::File* file, |
115 media::VideoCaptureFormat* video_format) { | 110 media::VideoCaptureFormat* video_format) { |
116 std::string header(kY4MHeaderMaxSize, 0); | 111 std::string header(kY4MHeaderMaxSize, 0); |
117 file->Read(0, &header[0], kY4MHeaderMaxSize - 1); | 112 file->Read(0, &header[0], kY4MHeaderMaxSize - 1); |
118 | 113 |
119 size_t header_end = header.find(kY4MSimpleFrameDelimiter); | 114 size_t header_end = header.find(kY4MSimpleFrameDelimiter); |
120 CHECK_NE(header_end, header.npos); | 115 CHECK_NE(header_end, header.npos); |
121 | 116 |
122 ParseY4MTags(header, video_format); | 117 ParseY4MTags(header, video_format); |
123 return header_end + kY4MSimpleFrameDelimiterSize; | 118 return header_end + kY4MSimpleFrameDelimiterSize; |
124 } | 119 } |
125 | 120 |
126 // Opens a given file for reading, and returns the file to the caller, who is | 121 // Opens a given file for reading, and returns the file to the caller, who is |
127 // responsible for closing it. | 122 // responsible for closing it. |
128 base::File OpenFileForRead(const base::FilePath& file_path) { | 123 // static |
| 124 base::File FileVideoCaptureDevice::OpenFileForRead( |
| 125 const base::FilePath& file_path) { |
129 base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); | 126 base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
130 CHECK(file.IsValid()) << file_path.value(); | 127 CHECK(file.IsValid()) << file_path.value(); |
131 return file.Pass(); | 128 return file.Pass(); |
132 } | 129 } |
133 | 130 |
134 // Inspects the command line and retrieves the file path parameter. | |
135 base::FilePath GetFilePathFromCommandLine() { | |
136 base::FilePath command_line_file_path = | |
137 CommandLine::ForCurrentProcess()->GetSwitchValuePath( | |
138 switches::kUseFileForFakeVideoCapture); | |
139 CHECK(!command_line_file_path.empty()); | |
140 return command_line_file_path; | |
141 } | |
142 | |
143 void FileVideoCaptureDevice::GetDeviceNames(Names* const device_names) { | |
144 DCHECK(device_names->empty()); | |
145 base::FilePath command_line_file_path = GetFilePathFromCommandLine(); | |
146 #if defined(OS_WIN) | |
147 device_names->push_back( | |
148 Name(base::SysWideToUTF8(command_line_file_path.value()), | |
149 kFileVideoCaptureDeviceName)); | |
150 #else | |
151 device_names->push_back(Name(command_line_file_path.value(), | |
152 kFileVideoCaptureDeviceName)); | |
153 #endif // OS_WIN | |
154 } | |
155 | |
156 void FileVideoCaptureDevice::GetDeviceSupportedFormats( | |
157 const Name& device, | |
158 VideoCaptureFormats* supported_formats) { | |
159 base::File file = OpenFileForRead(GetFilePathFromCommandLine()); | |
160 VideoCaptureFormat capture_format; | |
161 ParseFileAndExtractVideoFormat(&file, &capture_format); | |
162 supported_formats->push_back(capture_format); | |
163 } | |
164 | |
165 VideoCaptureDevice* FileVideoCaptureDevice::Create(const Name& device_name) { | |
166 #if defined(OS_WIN) | |
167 return new FileVideoCaptureDevice( | |
168 base::FilePath(base::SysUTF8ToWide(device_name.name()))); | |
169 #else | |
170 return new FileVideoCaptureDevice(base::FilePath(device_name.name())); | |
171 #endif // OS_WIN | |
172 } | |
173 | |
174 FileVideoCaptureDevice::FileVideoCaptureDevice(const base::FilePath& file_path) | 131 FileVideoCaptureDevice::FileVideoCaptureDevice(const base::FilePath& file_path) |
175 : capture_thread_("CaptureThread"), | 132 : capture_thread_("CaptureThread"), |
176 file_path_(file_path), | 133 file_path_(file_path), |
177 frame_size_(0), | 134 frame_size_(0), |
178 current_byte_index_(0), | 135 current_byte_index_(0), |
179 first_frame_byte_index_(0) {} | 136 first_frame_byte_index_(0) {} |
180 | 137 |
181 FileVideoCaptureDevice::~FileVideoCaptureDevice() { | 138 FileVideoCaptureDevice::~FileVideoCaptureDevice() { |
182 DCHECK(thread_checker_.CalledOnValidThread()); | 139 DCHECK(thread_checker_.CalledOnValidThread()); |
183 // Check if the thread is running. | 140 // Check if the thread is running. |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 base::TimeTicks::Now()); | 238 base::TimeTicks::Now()); |
282 // Reschedule next CaptureTask. | 239 // Reschedule next CaptureTask. |
283 base::MessageLoop::current()->PostDelayedTask( | 240 base::MessageLoop::current()->PostDelayedTask( |
284 FROM_HERE, | 241 FROM_HERE, |
285 base::Bind(&FileVideoCaptureDevice::OnCaptureTask, | 242 base::Bind(&FileVideoCaptureDevice::OnCaptureTask, |
286 base::Unretained(this)), | 243 base::Unretained(this)), |
287 base::TimeDelta::FromSeconds(1) / capture_format_.frame_rate); | 244 base::TimeDelta::FromSeconds(1) / capture_format_.frame_rate); |
288 } | 245 } |
289 | 246 |
290 } // namespace media | 247 } // namespace media |
OLD | NEW |