Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // ffmpeg_unittests verify that the parts of the FFmpeg API that Chromium uses | 5 // ffmpeg_unittests verify that the parts of the FFmpeg API that Chromium uses |
| 6 // function as advertised for each media format that Chromium supports. This | 6 // function as advertised for each media format that Chromium supports. This |
| 7 // mostly includes stuff like reporting proper timestamps, seeking to | 7 // mostly includes stuff like reporting proper timestamps, seeking to |
| 8 // keyframes, and supporting certain features like reordered_opaque. | 8 // keyframes, and supporting certain features like reordered_opaque. |
| 9 // | 9 // |
| 10 // Known failures as of r54591: | 10 // Known failures as of r54591: |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 #include "media/ffmpeg/ffmpeg_common.h" | 39 #include "media/ffmpeg/ffmpeg_common.h" |
| 40 #include "media/ffmpeg/file_protocol.h" | 40 #include "media/ffmpeg/file_protocol.h" |
| 41 #include "testing/gtest/include/gtest/gtest.h" | 41 #include "testing/gtest/include/gtest/gtest.h" |
| 42 | 42 |
| 43 int main(int argc, char** argv) { | 43 int main(int argc, char** argv) { |
| 44 return base::PerfTestSuite(argc, argv).Run(); | 44 return base::PerfTestSuite(argc, argv).Run(); |
| 45 } | 45 } |
| 46 | 46 |
| 47 namespace media { | 47 namespace media { |
| 48 | 48 |
| 49 // Mirror setting in ffmpeg_video_decoder. | |
| 50 static const int kDecodeThreads = 2; | |
|
scherkus (not reviewing)
2012/02/06 21:13:49
we should actually consider refactoring this to us
DaleCurtis
2012/02/07 19:09:13
Merge w/ PipelineIntegrationTests would probably b
| |
| 51 | |
| 49 class AVPacketQueue { | 52 class AVPacketQueue { |
| 50 public: | 53 public: |
| 51 AVPacketQueue() { | 54 AVPacketQueue() { |
| 52 } | 55 } |
| 53 | 56 |
| 54 ~AVPacketQueue() { | 57 ~AVPacketQueue() { |
| 55 flush(); | 58 flush(); |
| 56 } | 59 } |
| 57 | 60 |
| 58 bool empty() { | 61 bool empty() { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 .AppendASCII(name.c_str()); | 129 .AppendASCII(name.c_str()); |
| 127 FilePath::StringType raw_path = path.value(); | 130 FilePath::StringType raw_path = path.value(); |
| 128 EXPECT_TRUE(file_util::PathExists(path)); | 131 EXPECT_TRUE(file_util::PathExists(path)); |
| 129 | 132 |
| 130 #if defined(OS_WIN) | 133 #if defined(OS_WIN) |
| 131 std::string ascii_path = WideToASCII(path.value()); | 134 std::string ascii_path = WideToASCII(path.value()); |
| 132 #else | 135 #else |
| 133 std::string ascii_path = path.value(); | 136 std::string ascii_path = path.value(); |
| 134 #endif | 137 #endif |
| 135 | 138 |
| 136 EXPECT_EQ(0, av_open_input_file(&av_format_context_, | 139 EXPECT_EQ(0, avformat_open_input(&av_format_context_, |
| 137 ascii_path.c_str(), | 140 ascii_path.c_str(), |
|
scherkus (not reviewing)
2012/02/06 21:13:49
indent
DaleCurtis
2012/02/07 19:09:13
Done. Argh, cpplint.py is totally useless.
| |
| 138 NULL, 0, NULL)) | 141 NULL, NULL)) |
| 139 << "Could not open " << path.value(); | 142 << "Could not open " << path.value(); |
| 140 EXPECT_LE(0, av_find_stream_info(av_format_context_)) | 143 EXPECT_LE(0, avformat_find_stream_info(av_format_context_, NULL)) |
| 141 << "Could not find stream information for " << path.value(); | 144 << "Could not find stream information for " << path.value(); |
| 142 | 145 |
| 143 // Determine duration by picking max stream duration. | 146 // Determine duration by picking max stream duration. |
| 144 for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) { | 147 for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) { |
| 145 AVStream* av_stream = av_format_context_->streams[i]; | 148 AVStream* av_stream = av_format_context_->streams[i]; |
| 146 int64 duration = ConvertFromTimeBase(av_stream->time_base, | 149 int64 duration = ConvertFromTimeBase(av_stream->time_base, |
| 147 av_stream->duration).InMicroseconds(); | 150 av_stream->duration).InMicroseconds(); |
| 148 duration_ = std::max(duration_, duration); | 151 duration_ = std::max(duration_, duration); |
| 149 } | 152 } |
| 150 | 153 |
| 151 // Final check to see if the container itself specifies a duration. | 154 // Final check to see if the container itself specifies a duration. |
| 152 AVRational av_time_base = {1, AV_TIME_BASE}; | 155 AVRational av_time_base = {1, AV_TIME_BASE}; |
| 153 int64 duration = | 156 int64 duration = |
| 154 ConvertFromTimeBase(av_time_base, | 157 ConvertFromTimeBase(av_time_base, |
| 155 av_format_context_->duration).InMicroseconds(); | 158 av_format_context_->duration).InMicroseconds(); |
| 156 duration_ = std::max(duration_, duration); | 159 duration_ = std::max(duration_, duration); |
| 157 } | 160 } |
| 158 | 161 |
| 159 void CloseFile() { | 162 void CloseFile() { |
| 160 av_close_input_file(av_format_context_); | 163 avformat_close_input(&av_format_context_); |
| 161 } | 164 } |
| 162 | 165 |
| 163 void OpenCodecs() { | 166 void OpenCodecs() { |
| 164 for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) { | 167 for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) { |
| 165 AVStream* av_stream = av_format_context_->streams[i]; | 168 AVStream* av_stream = av_format_context_->streams[i]; |
| 166 AVCodecContext* av_codec_context = av_stream->codec; | 169 AVCodecContext* av_codec_context = av_stream->codec; |
| 167 AVCodec* av_codec = avcodec_find_decoder(av_codec_context->codec_id); | 170 AVCodec* av_codec = avcodec_find_decoder(av_codec_context->codec_id); |
| 168 | 171 |
| 169 EXPECT_TRUE(av_codec) | 172 EXPECT_TRUE(av_codec) |
| 170 << "Could not find AVCodec with CodecID " | 173 << "Could not find AVCodec with CodecID " |
| 171 << av_codec_context->codec_id; | 174 << av_codec_context->codec_id; |
| 172 EXPECT_EQ(0, avcodec_open(av_codec_context, av_codec)) | 175 |
| 176 av_codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; | |
| 177 av_codec_context->err_recognition = AV_EF_CAREFUL; | |
| 178 av_codec_context->thread_count = ( | |
| 179 av_codec_context->codec_id == CODEC_ID_THEORA ? 1 : kDecodeThreads); | |
| 180 | |
| 181 EXPECT_EQ(0, avcodec_open2(av_codec_context, av_codec, NULL)) | |
| 173 << "Could not open AVCodecContext with CodecID " | 182 << "Could not open AVCodecContext with CodecID " |
| 174 << av_codec_context->codec_id; | 183 << av_codec_context->codec_id; |
| 175 | 184 |
| 176 if (av_codec->type == AVMEDIA_TYPE_AUDIO) { | 185 if (av_codec->type == AVMEDIA_TYPE_AUDIO) { |
| 177 EXPECT_EQ(-1, audio_stream_index_) << "Found multiple audio streams."; | 186 EXPECT_EQ(-1, audio_stream_index_) << "Found multiple audio streams."; |
| 178 audio_stream_index_ = static_cast<int>(i); | 187 audio_stream_index_ = static_cast<int>(i); |
| 179 } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) { | 188 } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) { |
| 180 EXPECT_EQ(-1, video_stream_index_) << "Found multiple video streams."; | 189 EXPECT_EQ(-1, video_stream_index_) << "Found multiple video streams."; |
| 181 video_stream_index_ = static_cast<int>(i); | 190 video_stream_index_ = static_cast<int>(i); |
| 182 } else { | 191 } else { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 } | 273 } |
| 265 | 274 |
| 266 EXPECT_GE(result, 0) << "Audio decode error."; | 275 EXPECT_GE(result, 0) << "Audio decode error."; |
| 267 if (result < 0 || (size_out == 0 && end_of_stream)) { | 276 if (result < 0 || (size_out == 0 && end_of_stream)) { |
| 268 return false; | 277 return false; |
| 269 } | 278 } |
| 270 | 279 |
| 271 if (result > 0) { | 280 if (result > 0) { |
| 272 // TODO(scherkus): move this to ffmpeg_common.h and dedup. | 281 // TODO(scherkus): move this to ffmpeg_common.h and dedup. |
| 273 int64 denominator = av_audio_context()->channels * | 282 int64 denominator = av_audio_context()->channels * |
| 274 av_get_bits_per_sample_fmt(av_audio_context()->sample_fmt) / 8 * | 283 av_get_bytes_per_sample(av_audio_context()->sample_fmt) * |
| 275 av_audio_context()->sample_rate; | 284 av_audio_context()->sample_rate; |
| 276 double microseconds = size_out / | 285 double microseconds = size_out / |
| 277 (denominator / | 286 (denominator / |
| 278 static_cast<double>(base::Time::kMicrosecondsPerSecond)); | 287 static_cast<double>(base::Time::kMicrosecondsPerSecond)); |
| 279 decoded_audio_duration_ = static_cast<int64>(microseconds); | 288 decoded_audio_duration_ = static_cast<int64>(microseconds); |
| 280 | 289 |
| 281 if (packet.pts == static_cast<int64>(AV_NOPTS_VALUE)) { | 290 if (packet.pts == static_cast<int64>(AV_NOPTS_VALUE)) { |
| 282 EXPECT_NE(decoded_audio_time_, static_cast<int64>(AV_NOPTS_VALUE)) | 291 EXPECT_NE(decoded_audio_time_, static_cast<int64>(AV_NOPTS_VALUE)) |
| 283 << "We never received an initial timestamped audio packet! " | 292 << "We never received an initial timestamped audio packet! " |
| 284 << "Looks like there's a seeking/parsing bug in FFmpeg."; | 293 << "Looks like there's a seeking/parsing bug in FFmpeg."; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 static bool initialized = false; | 404 static bool initialized = false; |
| 396 if (initialized) { | 405 if (initialized) { |
| 397 return; | 406 return; |
| 398 } | 407 } |
| 399 | 408 |
| 400 FilePath path; | 409 FilePath path; |
| 401 PathService::Get(base::DIR_MODULE, &path); | 410 PathService::Get(base::DIR_MODULE, &path); |
| 402 EXPECT_TRUE(InitializeMediaLibrary(path)) | 411 EXPECT_TRUE(InitializeMediaLibrary(path)) |
| 403 << "Could not initialize media library."; | 412 << "Could not initialize media library."; |
| 404 | 413 |
| 405 avcodec_init(); | |
| 406 av_log_set_level(AV_LOG_FATAL); | 414 av_log_set_level(AV_LOG_FATAL); |
| 407 av_register_all(); | 415 av_register_all(); |
| 408 av_register_protocol2(&kFFmpegFileProtocol, sizeof(kFFmpegFileProtocol)); | 416 ffurl_register_protocol(&kFFmpegFileProtocol, sizeof(kFFmpegFileProtocol)); |
| 409 initialized = true; | 417 initialized = true; |
| 410 } | 418 } |
| 411 | 419 |
| 412 AVFormatContext* av_format_context_; | 420 AVFormatContext* av_format_context_; |
| 413 int audio_stream_index_; | 421 int audio_stream_index_; |
| 414 int video_stream_index_; | 422 int video_stream_index_; |
| 415 AVPacketQueue audio_packets_; | 423 AVPacketQueue audio_packets_; |
| 416 AVPacketQueue video_packets_; | 424 AVPacketQueue video_packets_; |
| 417 | 425 |
| 418 scoped_ptr_malloc<int16, media::ScopedPtrAVFree> audio_buffer_; | 426 scoped_ptr_malloc<int16, media::ScopedPtrAVFree> audio_buffer_; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 646 SeekTo(0.4); | 654 SeekTo(0.4); |
| 647 ReadRemainingFile(); | 655 ReadRemainingFile(); |
| 648 EXPECT_TRUE(StepDecodeVideo()); | 656 EXPECT_TRUE(StepDecodeVideo()); |
| 649 VLOG(1) << decoded_video_time(); | 657 VLOG(1) << decoded_video_time(); |
| 650 | 658 |
| 651 CloseCodecs(); | 659 CloseCodecs(); |
| 652 CloseFile(); | 660 CloseFile(); |
| 653 } | 661 } |
| 654 | 662 |
| 655 } // namespace media | 663 } // namespace media |
| OLD | NEW |