• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // =============================================================================
15 
16 #include "tensorflow/contrib/ffmpeg/ffmpeg_lib.h"
17 
18 #include <stdlib.h>
19 #include <vector>
20 
21 #include "tensorflow/core/lib/io/path.h"
22 #include "tensorflow/core/lib/strings/str_util.h"
23 #include "tensorflow/core/platform/env.h"
24 #include "tensorflow/core/platform/mutex.h"
25 #include "tensorflow/core/platform/test.h"
26 #include "tensorflow/core/platform/thread_annotations.h"
27 #include "tensorflow/core/util/command_line_flags.h"
28 
29 using tensorflow::testing::TensorFlowSrcRoot;
30 
31 namespace tensorflow {
32 namespace ffmpeg {
33 namespace {
34 
35 const char kTestWavFilename[] = "contrib/ffmpeg/testdata/mono_10khz.wav";
36 const char kTestMp3Filename[] = "contrib/ffmpeg/testdata/test_sound1.mp3";
37 
38 // Set to true via a command line flag iff the test is expected to have FFmpeg
39 // installed.
40 mutex mu(LINKER_INITIALIZED);
41 bool should_ffmpeg_be_installed GUARDED_BY(mu) = false;
42 
ParseTestFlags(int * argc,char ** argv)43 string ParseTestFlags(int* argc, char** argv) {
44   mutex_lock l(mu);
45   std::vector<Flag> flag_list = {
46       Flag("should_ffmpeg_be_installed", &should_ffmpeg_be_installed,
47            "indicates that ffmpeg should be installed")};
48   string usage = Flags::Usage(argv[0], flag_list);
49   if (!Flags::Parse(argc, argv, flag_list)) {
50     LOG(ERROR) << "\n" << usage;
51     exit(2);
52   }
53   return usage;
54 }
55 
TEST(FfmpegLibTest,TestUninstalled)56 TEST(FfmpegLibTest, TestUninstalled) {
57   {
58     mutex_lock l(mu);
59     if (should_ffmpeg_be_installed) {
60       return;
61     }
62     LOG(INFO) << "Assuming FFmpeg is uninstalled.";
63   }
64 
65   string filename = io::JoinPath(TensorFlowSrcRoot(), kTestMp3Filename);
66   std::vector<float> output_samples;
67   Status status = ReadAudioFile(filename, "mp3", 5000, 1, &output_samples);
68   ASSERT_EQ(status.code(), error::Code::NOT_FOUND);
69 }
70 
TEST(FfmpegLibTest,TestInstalled)71 TEST(FfmpegLibTest, TestInstalled) {
72   {
73     mutex_lock l(mu);
74     if (!should_ffmpeg_be_installed) {
75       return;
76     }
77     LOG(INFO) << "Assuming FFmpeg is installed.";
78   }
79 
80   string filename = io::JoinPath(TensorFlowSrcRoot(), kTestMp3Filename);
81   std::vector<float> output_samples;
82   Status status = ReadAudioFile(filename, "mp3", 5000, 1, &output_samples);
83   ASSERT_TRUE(status.ok());
84 }
85 
TEST(FfmpegLibTest,TestRoundTripGeneratedWav)86 TEST(FfmpegLibTest, TestRoundTripGeneratedWav) {
87   {
88     mutex_lock l(mu);
89     if (!should_ffmpeg_be_installed) {
90       return;
91     }
92   }
93 
94   std::vector<float> sine_wave;
95   sine_wave.reserve(20000);
96   for (int i = 0; i < 20000; ++i) {
97     sine_wave.push_back(std::sin(6.28 * 440.0 * i / 20000.0));
98   }
99   string content;
100   ASSERT_TRUE(CreateAudioFile("wav", 0, 20000, 1, sine_wave, &content).ok());
101   string temp_filename = GetTempFilename("wav");
102   ASSERT_TRUE(WriteStringToFile(Env::Default(), temp_filename, content).ok());
103   std::vector<float> roundtrip_data;
104   ASSERT_TRUE(
105       ReadAudioFile(temp_filename, "wav", 20000, 1, &roundtrip_data).ok());
106   EXPECT_EQ(sine_wave.size(), roundtrip_data.size());
107   size_t min_size = std::min(sine_wave.size(), roundtrip_data.size());
108   for (size_t i = 0; i < min_size; ++i) {
109     EXPECT_NEAR(sine_wave[i], roundtrip_data[i], 0.01);
110     EXPECT_LE(roundtrip_data[i], 1.0);
111     EXPECT_LE(-1.0, roundtrip_data[i]);
112   }
113 }
114 
TEST(FfmpegLibTest,TestRoundTripWav)115 TEST(FfmpegLibTest, TestRoundTripWav) {
116   {
117     mutex_lock l(mu);
118     if (!should_ffmpeg_be_installed) {
119       return;
120     }
121   }
122 
123   string filename = io::JoinPath(TensorFlowSrcRoot(), kTestWavFilename);
124   std::vector<float> output_samples;
125   ASSERT_TRUE(ReadAudioFile(filename, "wav", 10000, 1, &output_samples).ok());
126   string original_audio;
127   ASSERT_TRUE(ReadFileToString(Env::Default(), filename, &original_audio).ok());
128 
129   string written_audio;
130   ASSERT_TRUE(
131       CreateAudioFile("wav", 0, 10000, 1, output_samples, &written_audio).ok());
132 
133   EXPECT_EQ(original_audio, written_audio);
134 }
135 
136 }  // namespace
137 }  // namespace ffmpeg
138 }  // namespace tensorflow
139 
main(int argc,char ** argv)140 int main(int argc, char** argv) {
141   tensorflow::string usage = tensorflow::ffmpeg::ParseTestFlags(&argc, argv);
142   testing::InitGoogleTest(&argc, argv);
143   if (argc != 1) {
144     LOG(ERROR) << usage;
145     return 2;
146   }
147   return RUN_ALL_TESTS();
148 }
149