| 362 | } |
| 363 | |
| 364 | Status ReadVideoFile(const string& filename, std::vector<uint8>* output_data, |
| 365 | uint32* width, uint32* height, uint32* frames) { |
| 366 | if (!IsBinaryInstalled(kFfmpegExecutable)) { |
| 367 | return Status(error::Code::NOT_FOUND, StrCat("FFmpeg could not be found.")); |
| 368 | } |
| 369 | |
| 370 | string output_filename = io::GetTempFilename("raw"); |
| 371 | string stderr_filename = io::GetTempFilename("err"); |
| 372 | |
| 373 | // Create an argument list. |
| 374 | const std::vector<string> args = |
| 375 | FfmpegVideoCommandLine(filename, output_filename); |
| 376 | // Execute ffmpeg and report errors. |
| 377 | pid_t child_pid = ::fork(); |
| 378 | if (child_pid < 0) { |
| 379 | return Status(error::Code::UNKNOWN, |
| 380 | StrCat("fork failed: ", strerror(errno))); |
| 381 | } |
| 382 | if (child_pid == 0) { |
| 383 | const int fd = |
| 384 | open(stderr_filename.c_str(), O_RDWR | O_CREAT | O_APPEND, 0600); |
| 385 | if (fd < 0) { |
| 386 | const int error = errno; |
| 387 | LOG(ERROR) << "FFmpeg stderr file could not be created: " |
| 388 | << strerror(error); |
| 389 | ::_exit(error); |
| 390 | } |
| 391 | close(STDERR_FILENO); |
| 392 | dup2(fd, STDERR_FILENO); |
| 393 | ExecuteFfmpeg(args); |
| 394 | } else { |
| 395 | int status_code; |
| 396 | if (::waitpid(child_pid, &status_code, 0) < 0) { |
| 397 | return Status(error::Code::UNKNOWN, |
| 398 | StrCat("waitpid failed: ", strerror(errno))); |
| 399 | } |
| 400 | if (status_code) { |
| 401 | return Status(error::Code::UNKNOWN, |
| 402 | StrCat("FFmpeg execution failed: ", status_code)); |
| 403 | } |
| 404 | |
| 405 | TF_QCHECK_OK(ReadInfoFile(stderr_filename, width, height, frames)) |
| 406 | << "Could not read FFmpeg stderr file: " << stderr_filename; |
| 407 | |
| 408 | string raw_data; |
| 409 | TF_QCHECK_OK(ReadFileToString(Env::Default(), output_filename, &raw_data)) |
| 410 | << "Could not read FFmpeg output file: " << output_filename; |
| 411 | output_data->resize(raw_data.size()); |
| 412 | std::copy_n(raw_data.data(), raw_data.size(), output_data->begin()); |
| 413 | |
| 414 | TF_QCHECK_OK(Env::Default()->DeleteFile(output_filename)) |
| 415 | << output_filename; |
| 416 | TF_QCHECK_OK(Env::Default()->DeleteFile(stderr_filename)) |
| 417 | << stderr_filename; |
| 418 | return Status::OK(); |
| 419 | } |
| 420 | } |
| 421 | } // namespace ffmpeg |
no test coverage detected