diff --git a/packager/media/file/file.gyp b/packager/media/file/file.gyp index 73aa4f5b89..ad164284e6 100644 --- a/packager/media/file/file.gyp +++ b/packager/media/file/file.gyp @@ -15,6 +15,8 @@ 'sources': [ 'file.cc', 'file.h', + 'file_util.cc', + 'file_util.h', 'file_closer.h', 'io_cache.cc', 'io_cache.h', @@ -48,6 +50,7 @@ 'type': '<(gtest_target_type)', 'sources': [ 'file_unittest.cc', + 'file_util_unittest.cc', 'io_cache_unittest.cc', 'memory_file_unittest.cc', ], diff --git a/packager/media/file/file_util.cc b/packager/media/file/file_util.cc new file mode 100644 index 0000000000..a4e54e3c47 --- /dev/null +++ b/packager/media/file/file_util.cc @@ -0,0 +1,44 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "packager/media/file/file_util.h" + +#include + +#include "packager/base/files/file_path.h" +#include "packager/base/files/file_util.h" +#include "packager/base/strings/stringprintf.h" +#include "packager/base/threading/platform_thread.h" +#include "packager/base/time/time.h" + +namespace shaka { +namespace { +// Create a temp file name using process/thread id and current time. +std::string TempFileName() { + const int32_t tid = static_cast(base::PlatformThread::CurrentId()); + const int64_t current_time = base::Time::Now().ToInternalValue(); + return base::StringPrintf("packager-tempfile-%x-%" PRIx64, tid, current_time); +} +} // namespace + +bool TempFilePath(const std::string& temp_dir, std::string* temp_file_path) { + if (temp_dir.empty()) { + base::FilePath file_path; + if (!base::CreateTemporaryFile(&file_path)) { + LOG(ERROR) << "Failed to create temporary file."; + return false; + } + *temp_file_path = file_path.AsUTF8Unsafe(); + } else { + *temp_file_path = + base::FilePath::FromUTF8Unsafe(temp_dir) + .Append(base::FilePath::FromUTF8Unsafe(TempFileName())) + .AsUTF8Unsafe(); + } + return true; +} + +} // namespace shaka diff --git a/packager/media/file/file_util.h b/packager/media/file/file_util.h new file mode 100644 index 0000000000..a85940638a --- /dev/null +++ b/packager/media/file/file_util.h @@ -0,0 +1,18 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include + +namespace shaka { + +/// Create a temp file name in directory @a temp_dir. Generate the temp file +/// in os specific temporary directory if @a temp_dir is empty. +/// @param temp_dir specifies the directory where the file should go. +/// @param temp_file_path is the result temp file path on success. +/// @returns true on success, false otherwise. +bool TempFilePath(const std::string& temp_dir, std::string* temp_file_path); + +} // namespace shaka diff --git a/packager/media/file/file_util_unittest.cc b/packager/media/file/file_util_unittest.cc new file mode 100644 index 0000000000..f43d10825e --- /dev/null +++ b/packager/media/file/file_util_unittest.cc @@ -0,0 +1,22 @@ +// Copyright 2016 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "packager/media/file/file_util.h" + +#include + +namespace shaka { + +TEST(FileUtilTest, Basic) { + std::string temp_file_path; + EXPECT_TRUE(TempFilePath("test", &temp_file_path)); + EXPECT_EQ(temp_file_path.find("test"), 0u); + + EXPECT_TRUE(TempFilePath("", &temp_file_path)); + // temp_file_path should be created in a system specific temp directory. +} + +} // namespace shaka diff --git a/packager/media/formats/mp4/single_segment_segmenter.cc b/packager/media/formats/mp4/single_segment_segmenter.cc index b8f4466a9e..b9fb64898a 100644 --- a/packager/media/formats/mp4/single_segment_segmenter.cc +++ b/packager/media/formats/mp4/single_segment_segmenter.cc @@ -6,38 +6,18 @@ #include "packager/media/formats/mp4/single_segment_segmenter.h" -#include -#include -#include - -#include "packager/base/files/file_util.h" -#include "packager/base/strings/stringprintf.h" -#include "packager/base/threading/platform_thread.h" -#include "packager/base/time/time.h" #include "packager/media/base/buffer_writer.h" #include "packager/media/base/media_stream.h" #include "packager/media/base/muxer_options.h" #include "packager/media/event/muxer_listener.h" #include "packager/media/event/progress_listener.h" #include "packager/media/file/file.h" +#include "packager/media/file/file_util.h" #include "packager/media/formats/mp4/box_definitions.h" namespace shaka { namespace media { namespace mp4 { -namespace { -// Create a temp file name using process/thread id and current time. -std::string TempFileName() { - int32_t tid = static_cast(base::PlatformThread::CurrentId()); - int64_t rand = 0; - if (RAND_bytes(reinterpret_cast(&rand), sizeof(rand)) != 1) { - LOG(WARNING) << "RAND_bytes failed with error: " - << ERR_error_string(ERR_get_error(), NULL); - rand = base::Time::Now().ToInternalValue(); - } - return base::StringPrintf("packager-tempfile-%x-%" PRIx64, tid, rand); -} -} // namespace SingleSegmentSegmenter::SingleSegmentSegmenter(const MuxerOptions& options, std::unique_ptr ftyp, @@ -77,18 +57,8 @@ Status SingleSegmentSegmenter::DoInitialize() { // progress_target was set for stage 1. Times two to account for stage 2. set_progress_target(progress_target() * 2); - if (options().temp_dir.empty()) { - base::FilePath temp_file_path; - if (!base::CreateTemporaryFile(&temp_file_path)) { - LOG(ERROR) << "Failed to create temporary file."; - return Status(error::FILE_FAILURE, "Unable to create temporary file."); - } - temp_file_name_ = temp_file_path.AsUTF8Unsafe(); - } else { - temp_file_name_ = - base::FilePath::FromUTF8Unsafe(options().temp_dir) - .Append(base::FilePath::FromUTF8Unsafe(TempFileName())).AsUTF8Unsafe(); - } + if (!TempFilePath(options().temp_dir, &temp_file_name_)) + return Status(error::FILE_FAILURE, "Unable to create temporary file."); temp_file_.reset(File::Open(temp_file_name_.c_str(), "w")); return temp_file_ ? Status::OK diff --git a/packager/media/formats/webm/seek_head.cc b/packager/media/formats/webm/seek_head.cc index 7579bd9513..bb8edf3822 100644 --- a/packager/media/formats/webm/seek_head.cc +++ b/packager/media/formats/webm/seek_head.cc @@ -52,8 +52,7 @@ bool SeekHead::Write(mkvmuxer::IMkvWriter* writer) { uint64_t payload_size = 0; for (const SeekHead::SeekElement& seek_element : seek_elements) { payload_size += - seek_element.size + - EbmlMasterElementSize(mkvmuxer::kMkvSeek, seek_element.size); + EbmlMasterElementWithPayloadSize(mkvmuxer::kMkvSeek, seek_element.size); } const int64_t start_pos = writer->Position(); diff --git a/packager/media/formats/webm/two_pass_single_segment_segmenter.cc b/packager/media/formats/webm/two_pass_single_segment_segmenter.cc index 52a7c63758..bced213c50 100644 --- a/packager/media/formats/webm/two_pass_single_segment_segmenter.cc +++ b/packager/media/formats/webm/two_pass_single_segment_segmenter.cc @@ -6,20 +6,13 @@ #include "packager/media/formats/webm/two_pass_single_segment_segmenter.h" -#include -#include -#include - #include -#include "packager/base/files/file_path.h" -#include "packager/base/strings/stringprintf.h" -#include "packager/base/threading/platform_thread.h" -#include "packager/base/time/time.h" #include "packager/media/base/media_sample.h" #include "packager/media/base/media_stream.h" #include "packager/media/base/muxer_options.h" #include "packager/media/base/stream_info.h" +#include "packager/media/file/file_util.h" #include "packager/third_party/libwebm/src/mkvmuxer.hpp" #include "packager/third_party/libwebm/src/mkvmuxerutil.hpp" #include "packager/third_party/libwebm/src/webmids.hpp" @@ -48,22 +41,6 @@ uint64_t UpdateCues(mkvmuxer::Cues* cues) { return cues_size; } -/// Create the temp file name using process/thread id and current time. -std::string TempFileName(const MuxerOptions& options) { - // TODO: Move to a common util function and remove other uses. - int32_t tid = static_cast(base::PlatformThread::CurrentId()); - int64_t rand = 0; - if (RAND_bytes(reinterpret_cast(&rand), sizeof(rand)) != 1) { - LOG(WARNING) << "RAND_bytes failed with error: " - << ERR_error_string(ERR_get_error(), NULL); - rand = base::Time::Now().ToInternalValue(); - } - std::string file_prefix = - base::StringPrintf("packager-tempfile-%x-%" PRIx64 ".tmp", tid, rand); - return base::FilePath::FromUTF8Unsafe(options.temp_dir).Append( - base::FilePath::FromUTF8Unsafe(file_prefix)).AsUTF8Unsafe(); -} - // Skips a given number of bytes in a file by reading. This allows // forward-seeking in non-seekable files. bool ReadSkip(File* file, int64_t byte_count) { @@ -100,7 +77,8 @@ Status TwoPassSingleSegmentSegmenter::DoInitialize( real_writer_ = std::move(writer); - temp_file_name_ = TempFileName(options()); + if (!TempFilePath(options().temp_dir, &temp_file_name_)) + return Status(error::FILE_FAILURE, "Unable to create temporary file."); std::unique_ptr temp(new MkvWriter); Status status = temp->Open(temp_file_name_); if (!status.ok())