OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Software qualification test for FFmpeg. This test is used to certify that | 5 // Software qualification test for FFmpeg. This test is used to certify that |
6 // software decoding quality and performance of FFmpeg meets a mimimum | 6 // software decoding quality and performance of FFmpeg meets a mimimum |
7 // standard. | 7 // standard. |
8 | 8 |
9 #include <iomanip> | 9 #include <iomanip> |
10 #include <iostream> | 10 #include <iostream> |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 base::MD5Init(&ctx); | 107 base::MD5Init(&ctx); |
108 bool hash_md5 = false; | 108 bool hash_md5 = false; |
109 | 109 |
110 std::ostream* log_out = &std::cout; | 110 std::ostream* log_out = &std::cout; |
111 #if defined(ENABLE_WINDOWS_EXCEPTIONS) | 111 #if defined(ENABLE_WINDOWS_EXCEPTIONS) |
112 // Catch exceptions so this tool can be used in automated testing. | 112 // Catch exceptions so this tool can be used in automated testing. |
113 __try { | 113 __try { |
114 #endif | 114 #endif |
115 | 115 |
116 // Register FFmpeg and attempt to open file. | 116 // Register FFmpeg and attempt to open file. |
117 avcodec_init(); | |
118 av_log_set_level(verbose_level); | 117 av_log_set_level(verbose_level); |
119 av_register_all(); | 118 av_register_all(); |
120 av_register_protocol2(&kFFmpegFileProtocol, sizeof(kFFmpegFileProtocol)); | 119 av_register_protocol2(&kFFmpegFileProtocol, sizeof(kFFmpegFileProtocol)); |
121 AVFormatContext* format_context = NULL; | 120 AVFormatContext* format_context = NULL; |
122 // av_open_input_file wants a char*, which can't work with wide paths. | 121 // avformat_open_input() wants a char*, which can't work with wide paths. |
123 // So we assume ASCII on Windows. On other platforms we can pass the | 122 // So we assume ASCII on Windows. On other platforms we can pass the |
124 // path bytes through verbatim. | 123 // path bytes through verbatim. |
125 #if defined(OS_WIN) | 124 #if defined(OS_WIN) |
126 std::string string_path = WideToASCII(in_path.value()); | 125 std::string string_path = WideToASCII(in_path.value()); |
127 #else | 126 #else |
128 const std::string& string_path = in_path.value(); | 127 const std::string& string_path = in_path.value(); |
129 #endif | 128 #endif |
130 int result = av_open_input_file(&format_context, string_path.c_str(), | 129 int result = avformat_open_input(&format_context, string_path.c_str(), |
131 NULL, 0, NULL); | 130 NULL, NULL); |
132 if (result < 0) { | 131 if (result < 0) { |
133 switch (result) { | 132 switch (result) { |
134 case AVERROR(EINVAL): | 133 case AVERROR(EINVAL): |
135 std::cerr << "Error: File format not supported " | 134 std::cerr << "Error: File format not supported " |
136 << in_path.value() << std::endl; | 135 << in_path.value() << std::endl; |
137 break; | 136 break; |
138 default: | 137 default: |
139 std::cerr << "Error: Could not open input for " | 138 std::cerr << "Error: Could not open input for " |
140 << in_path.value() << std::endl; | 139 << in_path.value() << std::endl; |
141 break; | 140 break; |
142 } | 141 } |
143 return 1; | 142 return 1; |
144 } | 143 } |
145 | 144 |
146 // Open output file. | 145 // Open output file. |
147 FILE *output = NULL; | 146 FILE *output = NULL; |
148 if (!out_path.empty()) { | 147 if (!out_path.empty()) { |
149 output = file_util::OpenFile(out_path, "wb"); | 148 output = file_util::OpenFile(out_path, "wb"); |
150 if (!output) { | 149 if (!output) { |
151 std::cerr << "Error: Could not open output " | 150 std::cerr << "Error: Could not open output " |
152 << out_path.value() << std::endl; | 151 << out_path.value() << std::endl; |
153 return 1; | 152 return 1; |
154 } | 153 } |
155 } | 154 } |
156 | 155 |
157 // Parse a little bit of the stream to fill out the format context. | 156 // Parse a little bit of the stream to fill out the format context. |
158 if (av_find_stream_info(format_context) < 0) { | 157 if (avformat_find_stream_info(format_context, NULL) < 0) { |
159 std::cerr << "Error: Could not find stream info for " | 158 std::cerr << "Error: Could not find stream info for " |
160 << in_path.value() << std::endl; | 159 << in_path.value() << std::endl; |
161 return 1; | 160 return 1; |
162 } | 161 } |
163 | 162 |
164 // Find our target stream(s) | 163 // Find our target stream(s) |
165 int video_stream = -1; | 164 int video_stream = -1; |
166 int audio_stream = -1; | 165 int audio_stream = -1; |
167 for (size_t i = 0; i < format_context->nb_streams; ++i) { | 166 for (size_t i = 0; i < format_context->nb_streams; ++i) { |
168 AVCodecContext* codec_context = format_context->streams[i]->codec; | 167 AVCodecContext* codec_context = format_context->streams[i]->codec; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 } | 222 } |
224 | 223 |
225 // TODO(fbarchard): On next ffmpeg roll, retest if this work around is needed. | 224 // TODO(fbarchard): On next ffmpeg roll, retest if this work around is needed. |
226 if (codec_context->codec_id == CODEC_ID_THEORA) { | 225 if (codec_context->codec_id == CODEC_ID_THEORA) { |
227 std::cerr << "Warning: Disabling threads to avoid Theora bug " | 226 std::cerr << "Warning: Disabling threads to avoid Theora bug " |
228 << in_path.value() << std::endl; | 227 << in_path.value() << std::endl; |
229 video_threads = 1; | 228 video_threads = 1; |
230 } | 229 } |
231 | 230 |
232 codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; | 231 codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; |
233 codec_context->error_recognition = FF_ER_CAREFUL; | 232 codec_context->err_recognition = AV_EF_CAREFUL; |
234 | 233 |
235 // Initialize threaded decode. | 234 // Initialize threaded decode. |
236 if (target_codec == AVMEDIA_TYPE_VIDEO && video_threads > 0) { | 235 if (target_codec == AVMEDIA_TYPE_VIDEO && video_threads > 0) { |
237 codec_context->thread_count = video_threads; | 236 codec_context->thread_count = video_threads; |
238 } | 237 } |
239 | 238 |
240 // Initialize our codec. | 239 // Initialize our codec. |
241 if (avcodec_open(codec_context, codec) < 0) { | 240 if (avcodec_open2(codec_context, codec, NULL) < 0) { |
242 std::cerr << "Error: Could not open codec " | 241 std::cerr << "Error: Could not open codec " |
243 << codec_context->codec->name << " for " | 242 << codec_context->codec->name << " for " |
244 << in_path.value() << std::endl; | 243 << in_path.value() << std::endl; |
245 return 1; | 244 return 1; |
246 } | 245 } |
247 | 246 |
248 // Buffer used for audio decoding. | 247 // Buffer used for audio decoding. |
249 scoped_ptr_malloc<int16, media::ScopedPtrAVFree> samples( | 248 scoped_ptr_malloc<int16, media::ScopedPtrAVFree> samples( |
250 reinterpret_cast<int16*>(av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE))); | 249 reinterpret_cast<int16*>(av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE))); |
251 | 250 |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 base::TimeDelta total = base::TimeTicks::HighResNow() - start; | 413 base::TimeDelta total = base::TimeTicks::HighResNow() - start; |
415 #endif | 414 #endif |
416 LeaveTimingSection(); | 415 LeaveTimingSection(); |
417 | 416 |
418 // Clean up. | 417 // Clean up. |
419 if (output) | 418 if (output) |
420 file_util::CloseFile(output); | 419 file_util::CloseFile(output); |
421 if (codec_context) | 420 if (codec_context) |
422 avcodec_close(codec_context); | 421 avcodec_close(codec_context); |
423 if (format_context) | 422 if (format_context) |
424 av_close_input_file(format_context); | 423 avformat_close_input(&format_context); |
425 | 424 |
426 // Calculate the sum of times. Note that some of these may be zero. | 425 // Calculate the sum of times. Note that some of these may be zero. |
427 double sum = 0; | 426 double sum = 0; |
428 for (size_t i = 0; i < decode_times.size(); ++i) { | 427 for (size_t i = 0; i < decode_times.size(); ++i) { |
429 sum += decode_times[i]; | 428 sum += decode_times[i]; |
430 } | 429 } |
431 | 430 |
432 if (sum > 0) { | 431 if (sum > 0) { |
433 if (target_codec == AVMEDIA_TYPE_AUDIO) { | 432 if (target_codec == AVMEDIA_TYPE_AUDIO) { |
434 // Calculate the average milliseconds per frame. | 433 // Calculate the average milliseconds per frame. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 #if defined(ENABLE_WINDOWS_EXCEPTIONS) | 498 #if defined(ENABLE_WINDOWS_EXCEPTIONS) |
500 } __except(EXCEPTION_EXECUTE_HANDLER) { | 499 } __except(EXCEPTION_EXECUTE_HANDLER) { |
501 *log_out << " Exception:" << std::setw(11) << GetExceptionCode() | 500 *log_out << " Exception:" << std::setw(11) << GetExceptionCode() |
502 << " " << in_path.value() << std::endl; | 501 << " " << in_path.value() << std::endl; |
503 return 1; | 502 return 1; |
504 } | 503 } |
505 #endif | 504 #endif |
506 CommandLine::Reset(); | 505 CommandLine::Reset(); |
507 return 0; | 506 return 0; |
508 } | 507 } |
OLD | NEW |