| 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 ffurl_register_protocol(&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 |