| 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 |