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" | |
15 #include "media/base/media_switches.h" | |
16 | |
17 | 13 |
18 namespace media { | 14 namespace media { |
19 static const char kFileVideoCaptureDeviceName[] = | |
20 "/dev/placeholder-for-file-backed-fake-capture-device"; | |
21 | |
22 static const int kY4MHeaderMaxSize = 200; | 15 static const int kY4MHeaderMaxSize = 200; |
23 static const char kY4MSimpleFrameDelimiter[] = "FRAME"; | 16 static const char kY4MSimpleFrameDelimiter[] = "FRAME"; |
24 static const int kY4MSimpleFrameDelimiterSize = 6; | 17 static const int kY4MSimpleFrameDelimiterSize = 6; |
25 | 18 |
26 int ParseY4MInt(const base::StringPiece& token) { | 19 int ParseY4MInt(const base::StringPiece& token) { |
27 int temp_int; | 20 int temp_int; |
28 CHECK(base::StringToInt(token, &temp_int)) << token; | 21 CHECK(base::StringToInt(token, &temp_int)) << token; |
29 return temp_int; | 22 return temp_int; |
30 } | 23 } |
31 | 24 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 index = blank_position + 1; | 96 index = blank_position + 1; |
104 } | 97 } |
105 // Last video format semantic correctness check before sending it back. | 98 // Last video format semantic correctness check before sending it back. |
106 CHECK(video_format->IsValid()); | 99 CHECK(video_format->IsValid()); |
107 } | 100 } |
108 | 101 |
109 // Reads and parses the header of a Y4M |file|, returning the collected pixel | 102 // 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 | 103 // format in |video_format|. Returns the index of the first byte of the first |
111 // video frame. | 104 // video frame. |
112 // Restrictions: Only trivial per-frame headers are supported. | 105 // Restrictions: Only trivial per-frame headers are supported. |
113 int64 ParseFileAndExtractVideoFormat( | 106 // static |
| 107 int64 FileVideoCaptureDevice::ParseFileAndExtractVideoFormat( |
114 base::File* file, | 108 base::File* file, |
115 media::VideoCaptureFormat* video_format) { | 109 media::VideoCaptureFormat* video_format) { |
116 std::string header(kY4MHeaderMaxSize, 0); | 110 std::string header(kY4MHeaderMaxSize, 0); |
117 file->Read(0, &header[0], kY4MHeaderMaxSize - 1); | 111 file->Read(0, &header[0], kY4MHeaderMaxSize - 1); |
118 | 112 |
119 size_t header_end = header.find(kY4MSimpleFrameDelimiter); | 113 size_t header_end = header.find(kY4MSimpleFrameDelimiter); |
120 CHECK_NE(header_end, header.npos); | 114 CHECK_NE(header_end, header.npos); |
121 | 115 |
122 ParseY4MTags(header, video_format); | 116 ParseY4MTags(header, video_format); |
123 return header_end + kY4MSimpleFrameDelimiterSize; | 117 return header_end + kY4MSimpleFrameDelimiterSize; |
124 } | 118 } |
125 | 119 |
126 // Opens a given file for reading, and returns the file to the caller, who is | 120 // Opens a given file for reading, and returns the file to the caller, who is |
127 // responsible for closing it. | 121 // responsible for closing it. |
128 base::File OpenFileForRead(const base::FilePath& file_path) { | 122 // static |
| 123 base::File FileVideoCaptureDevice::OpenFileForRead( |
| 124 const base::FilePath& file_path) { |
129 base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); | 125 base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
130 CHECK(file.IsValid()) << file_path.value(); | 126 CHECK(file.IsValid()) << file_path.value(); |
131 return file.Pass(); | 127 return file.Pass(); |
132 } | 128 } |
133 | 129 |
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) | 130 FileVideoCaptureDevice::FileVideoCaptureDevice(const base::FilePath& file_path) |
175 : capture_thread_("CaptureThread"), | 131 : capture_thread_("CaptureThread"), |
176 file_path_(file_path), | 132 file_path_(file_path), |
177 frame_size_(0), | 133 frame_size_(0), |
178 current_byte_index_(0), | 134 current_byte_index_(0), |
179 first_frame_byte_index_(0) {} | 135 first_frame_byte_index_(0) {} |
180 | 136 |
181 FileVideoCaptureDevice::~FileVideoCaptureDevice() { | 137 FileVideoCaptureDevice::~FileVideoCaptureDevice() { |
182 DCHECK(thread_checker_.CalledOnValidThread()); | 138 DCHECK(thread_checker_.CalledOnValidThread()); |
183 // Check if the thread is running. | 139 // Check if the thread is running. |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 base::TimeTicks::Now()); | 237 base::TimeTicks::Now()); |
282 // Reschedule next CaptureTask. | 238 // Reschedule next CaptureTask. |
283 base::MessageLoop::current()->PostDelayedTask( | 239 base::MessageLoop::current()->PostDelayedTask( |
284 FROM_HERE, | 240 FROM_HERE, |
285 base::Bind(&FileVideoCaptureDevice::OnCaptureTask, | 241 base::Bind(&FileVideoCaptureDevice::OnCaptureTask, |
286 base::Unretained(this)), | 242 base::Unretained(this)), |
287 base::TimeDelta::FromSeconds(1) / capture_format_.frame_rate); | 243 base::TimeDelta::FromSeconds(1) / capture_format_.frame_rate); |
288 } | 244 } |
289 | 245 |
290 } // namespace media | 246 } // namespace media |
OLD | NEW |