| 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 // 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 | 10 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 video_stream_index_(-1), | 83 video_stream_index_(-1), |
| 84 audio_buffer_(NULL), | 84 audio_buffer_(NULL), |
| 85 video_buffer_(NULL), | 85 video_buffer_(NULL), |
| 86 decoded_audio_time_(AV_NOPTS_VALUE), | 86 decoded_audio_time_(AV_NOPTS_VALUE), |
| 87 decoded_audio_duration_(AV_NOPTS_VALUE), | 87 decoded_audio_duration_(AV_NOPTS_VALUE), |
| 88 decoded_video_time_(AV_NOPTS_VALUE), | 88 decoded_video_time_(AV_NOPTS_VALUE), |
| 89 decoded_video_duration_(AV_NOPTS_VALUE), | 89 decoded_video_duration_(AV_NOPTS_VALUE), |
| 90 duration_(AV_NOPTS_VALUE) { | 90 duration_(AV_NOPTS_VALUE) { |
| 91 InitializeFFmpeg(); | 91 InitializeFFmpeg(); |
| 92 | 92 |
| 93 audio_buffer_.reset( | 93 audio_buffer_.reset(avcodec_alloc_frame()); |
| 94 reinterpret_cast<int16*>(av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE))); | |
| 95 video_buffer_.reset(avcodec_alloc_frame()); | 94 video_buffer_.reset(avcodec_alloc_frame()); |
| 96 } | 95 } |
| 97 | 96 |
| 98 virtual ~FFmpegTest() { | 97 virtual ~FFmpegTest() { |
| 99 } | 98 } |
| 100 | 99 |
| 101 void OpenAndReadFile(const std::string& name) { | 100 void OpenAndReadFile(const std::string& name) { |
| 102 OpenFile(name); | 101 OpenFile(name); |
| 103 OpenCodecs(); | 102 OpenCodecs(); |
| 104 ReadRemainingFile(); | 103 ReadRemainingFile(); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 | 231 |
| 233 bool StepDecodeAudio() { | 232 bool StepDecodeAudio() { |
| 234 EXPECT_TRUE(has_audio()); | 233 EXPECT_TRUE(has_audio()); |
| 235 if (!has_audio() || audio_packets_.empty()) { | 234 if (!has_audio() || audio_packets_.empty()) { |
| 236 return false; | 235 return false; |
| 237 } | 236 } |
| 238 | 237 |
| 239 // Decode until output is produced, end of stream, or error. | 238 // Decode until output is produced, end of stream, or error. |
| 240 while (true) { | 239 while (true) { |
| 241 int result = 0; | 240 int result = 0; |
| 242 int size_out = AVCODEC_MAX_AUDIO_FRAME_SIZE; | 241 int got_audio = 0; |
| 243 bool end_of_stream = false; | 242 bool end_of_stream = false; |
| 244 | 243 |
| 245 AVPacket packet; | 244 AVPacket packet; |
| 246 if (audio_packets_.empty()) { | 245 if (audio_packets_.empty()) { |
| 247 av_init_packet(&packet); | 246 av_init_packet(&packet); |
| 248 end_of_stream = true; | 247 end_of_stream = true; |
| 249 } else { | 248 } else { |
| 250 memcpy(&packet, audio_packets_.peek(), sizeof(packet)); | 249 memcpy(&packet, audio_packets_.peek(), sizeof(packet)); |
| 251 } | 250 } |
| 252 | 251 |
| 253 result = avcodec_decode_audio3(av_audio_context(), audio_buffer_.get(), | 252 avcodec_get_frame_defaults(audio_buffer_.get()); |
| 254 &size_out, audio_packets_.peek()); | 253 result = avcodec_decode_audio4(av_audio_context(), audio_buffer_.get(), |
| 254 &got_audio, &packet); |
| 255 if (!audio_packets_.empty()) { | 255 if (!audio_packets_.empty()) { |
| 256 audio_packets_.pop(); | 256 audio_packets_.pop(); |
| 257 } | 257 } |
| 258 | 258 |
| 259 EXPECT_GE(result, 0) << "Audio decode error."; | 259 EXPECT_GE(result, 0) << "Audio decode error."; |
| 260 if (result < 0 || (size_out == 0 && end_of_stream)) { | 260 if (result < 0 || (got_audio == 0 && end_of_stream)) { |
| 261 return false; | 261 return false; |
| 262 } | 262 } |
| 263 | 263 |
| 264 if (result > 0) { | 264 if (result > 0) { |
| 265 // TODO(scherkus): move this to ffmpeg_common.h and dedup. | 265 double microseconds = 1.0L * audio_buffer_->nb_samples / |
| 266 int64 denominator = av_audio_context()->channels * | 266 av_audio_context()->sample_rate * |
| 267 av_get_bytes_per_sample(av_audio_context()->sample_fmt) * | 267 base::Time::kMicrosecondsPerSecond; |
| 268 av_audio_context()->sample_rate; | |
| 269 double microseconds = size_out / | |
| 270 (denominator / | |
| 271 static_cast<double>(base::Time::kMicrosecondsPerSecond)); | |
| 272 decoded_audio_duration_ = static_cast<int64>(microseconds); | 268 decoded_audio_duration_ = static_cast<int64>(microseconds); |
| 273 | 269 |
| 274 if (packet.pts == static_cast<int64>(AV_NOPTS_VALUE)) { | 270 if (packet.pts == static_cast<int64>(AV_NOPTS_VALUE)) { |
| 275 EXPECT_NE(decoded_audio_time_, static_cast<int64>(AV_NOPTS_VALUE)) | 271 EXPECT_NE(decoded_audio_time_, static_cast<int64>(AV_NOPTS_VALUE)) |
| 276 << "We never received an initial timestamped audio packet! " | 272 << "We never received an initial timestamped audio packet! " |
| 277 << "Looks like there's a seeking/parsing bug in FFmpeg."; | 273 << "Looks like there's a seeking/parsing bug in FFmpeg."; |
| 278 decoded_audio_time_ += decoded_audio_duration_; | 274 decoded_audio_time_ += decoded_audio_duration_; |
| 279 } else { | 275 } else { |
| 280 decoded_audio_time_ = | 276 decoded_audio_time_ = |
| 281 ConvertFromTimeBase(av_audio_stream()->time_base, packet.pts) | 277 ConvertFromTimeBase(av_audio_stream()->time_base, packet.pts) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 300 bool end_of_stream = false; | 296 bool end_of_stream = false; |
| 301 | 297 |
| 302 AVPacket packet; | 298 AVPacket packet; |
| 303 if (video_packets_.empty()) { | 299 if (video_packets_.empty()) { |
| 304 av_init_packet(&packet); | 300 av_init_packet(&packet); |
| 305 end_of_stream = true; | 301 end_of_stream = true; |
| 306 } else { | 302 } else { |
| 307 memcpy(&packet, video_packets_.peek(), sizeof(packet)); | 303 memcpy(&packet, video_packets_.peek(), sizeof(packet)); |
| 308 } | 304 } |
| 309 | 305 |
| 306 avcodec_get_frame_defaults(video_buffer_.get()); |
| 310 av_video_context()->reordered_opaque = packet.pts; | 307 av_video_context()->reordered_opaque = packet.pts; |
| 311 result = avcodec_decode_video2(av_video_context(), video_buffer_.get(), | 308 result = avcodec_decode_video2(av_video_context(), video_buffer_.get(), |
| 312 &got_picture, &packet); | 309 &got_picture, &packet); |
| 313 if (!video_packets_.empty()) { | 310 if (!video_packets_.empty()) { |
| 314 video_packets_.pop(); | 311 video_packets_.pop(); |
| 315 } | 312 } |
| 316 | 313 |
| 317 EXPECT_GE(result, 0) << "Video decode error."; | 314 EXPECT_GE(result, 0) << "Video decode error."; |
| 318 if (result < 0 || (got_picture == 0 && end_of_stream)) { | 315 if (result < 0 || (got_picture == 0 && end_of_stream)) { |
| 319 return false; | 316 return false; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 av_register_protocol2(&kFFmpegFileProtocol, sizeof(kFFmpegFileProtocol)); | 397 av_register_protocol2(&kFFmpegFileProtocol, sizeof(kFFmpegFileProtocol)); |
| 401 initialized = true; | 398 initialized = true; |
| 402 } | 399 } |
| 403 | 400 |
| 404 AVFormatContext* av_format_context_; | 401 AVFormatContext* av_format_context_; |
| 405 int audio_stream_index_; | 402 int audio_stream_index_; |
| 406 int video_stream_index_; | 403 int video_stream_index_; |
| 407 AVPacketQueue audio_packets_; | 404 AVPacketQueue audio_packets_; |
| 408 AVPacketQueue video_packets_; | 405 AVPacketQueue video_packets_; |
| 409 | 406 |
| 410 scoped_ptr_malloc<int16, media::ScopedPtrAVFree> audio_buffer_; | 407 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> audio_buffer_; |
| 411 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> video_buffer_; | 408 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> video_buffer_; |
| 412 | 409 |
| 413 int64 decoded_audio_time_; | 410 int64 decoded_audio_time_; |
| 414 int64 decoded_audio_duration_; | 411 int64 decoded_audio_duration_; |
| 415 int64 decoded_video_time_; | 412 int64 decoded_video_time_; |
| 416 int64 decoded_video_duration_; | 413 int64 decoded_video_duration_; |
| 417 int64 duration_; | 414 int64 duration_; |
| 418 | 415 |
| 419 DISALLOW_COPY_AND_ASSIGN(FFmpegTest); | 416 DISALLOW_COPY_AND_ASSIGN(FFmpegTest); |
| 420 }; | 417 }; |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 SeekTo(0.4); | 630 SeekTo(0.4); |
| 634 ReadRemainingFile(); | 631 ReadRemainingFile(); |
| 635 EXPECT_TRUE(StepDecodeVideo()); | 632 EXPECT_TRUE(StepDecodeVideo()); |
| 636 VLOG(1) << decoded_video_time(); | 633 VLOG(1) << decoded_video_time(); |
| 637 | 634 |
| 638 CloseCodecs(); | 635 CloseCodecs(); |
| 639 CloseFile(); | 636 CloseFile(); |
| 640 } | 637 } |
| 641 | 638 |
| 642 } // namespace media | 639 } // namespace media |
| OLD | NEW |