// Copyright 2016 The TensorFlow Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ============================================================================= #include "tensorflow/contrib/ffmpeg/ffmpeg_lib.h" #include #include #include "tensorflow/core/lib/io/path.h" #include "tensorflow/core/lib/strings/str_util.h" #include "tensorflow/core/platform/env.h" #include "tensorflow/core/platform/mutex.h" #include "tensorflow/core/platform/test.h" #include "tensorflow/core/platform/thread_annotations.h" #include "tensorflow/core/util/command_line_flags.h" using tensorflow::testing::TensorFlowSrcRoot; namespace tensorflow { namespace ffmpeg { namespace { const char kTestWavFilename[] = "contrib/ffmpeg/testdata/mono_10khz.wav"; const char kTestMp3Filename[] = "contrib/ffmpeg/testdata/test_sound1.mp3"; // Set to true via a command line flag iff the test is expected to have FFmpeg // installed. mutex mu(LINKER_INITIALIZED); bool should_ffmpeg_be_installed GUARDED_BY(mu) = false; string ParseTestFlags(int* argc, char** argv) { mutex_lock l(mu); std::vector flag_list = { Flag("should_ffmpeg_be_installed", &should_ffmpeg_be_installed, "indicates that ffmpeg should be installed")}; string usage = Flags::Usage(argv[0], flag_list); if (!Flags::Parse(argc, argv, flag_list)) { LOG(ERROR) << "\n" << usage; exit(2); } return usage; } TEST(FfmpegLibTest, TestUninstalled) { { mutex_lock l(mu); if (should_ffmpeg_be_installed) { return; } LOG(INFO) << "Assuming FFmpeg is uninstalled."; } string filename = io::JoinPath(TensorFlowSrcRoot(), kTestMp3Filename); std::vector output_samples; Status status = ReadAudioFile(filename, "mp3", 5000, 1, &output_samples); ASSERT_EQ(status.code(), error::Code::NOT_FOUND); } TEST(FfmpegLibTest, TestInstalled) { { mutex_lock l(mu); if (!should_ffmpeg_be_installed) { return; } LOG(INFO) << "Assuming FFmpeg is installed."; } string filename = io::JoinPath(TensorFlowSrcRoot(), kTestMp3Filename); std::vector output_samples; Status status = ReadAudioFile(filename, "mp3", 5000, 1, &output_samples); ASSERT_TRUE(status.ok()); } TEST(FfmpegLibTest, TestRoundTripGeneratedWav) { { mutex_lock l(mu); if (!should_ffmpeg_be_installed) { return; } } std::vector sine_wave; sine_wave.reserve(20000); for (int i = 0; i < 20000; ++i) { sine_wave.push_back(std::sin(6.28 * 440.0 * i / 20000.0)); } string content; ASSERT_TRUE(CreateAudioFile("wav", 0, 20000, 1, sine_wave, &content).ok()); string temp_filename = GetTempFilename("wav"); ASSERT_TRUE(WriteStringToFile(Env::Default(), temp_filename, content).ok()); std::vector roundtrip_data; ASSERT_TRUE( ReadAudioFile(temp_filename, "wav", 20000, 1, &roundtrip_data).ok()); EXPECT_EQ(sine_wave.size(), roundtrip_data.size()); size_t min_size = std::min(sine_wave.size(), roundtrip_data.size()); for (size_t i = 0; i < min_size; ++i) { EXPECT_NEAR(sine_wave[i], roundtrip_data[i], 0.01); EXPECT_LE(roundtrip_data[i], 1.0); EXPECT_LE(-1.0, roundtrip_data[i]); } } TEST(FfmpegLibTest, TestRoundTripWav) { { mutex_lock l(mu); if (!should_ffmpeg_be_installed) { return; } } string filename = io::JoinPath(TensorFlowSrcRoot(), kTestWavFilename); std::vector output_samples; ASSERT_TRUE(ReadAudioFile(filename, "wav", 10000, 1, &output_samples).ok()); string original_audio; ASSERT_TRUE(ReadFileToString(Env::Default(), filename, &original_audio).ok()); string written_audio; ASSERT_TRUE( CreateAudioFile("wav", 0, 10000, 1, output_samples, &written_audio).ok()); EXPECT_EQ(original_audio, written_audio); } } // namespace } // namespace ffmpeg } // namespace tensorflow int main(int argc, char** argv) { tensorflow::string usage = tensorflow::ffmpeg::ParseTestFlags(&argc, argv); testing::InitGoogleTest(&argc, argv); if (argc != 1) { LOG(ERROR) << usage; return 2; } return RUN_ALL_TESTS(); }