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 |