| 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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 | 231 |
| 232 // Initialize our codec. | 232 // Initialize our codec. |
| 233 if (avcodec_open2(codec_context, codec, NULL) < 0) { | 233 if (avcodec_open2(codec_context, codec, NULL) < 0) { |
| 234 std::cerr << "Error: Could not open codec " | 234 std::cerr << "Error: Could not open codec " |
| 235 << codec_context->codec->name << " for " | 235 << codec_context->codec->name << " for " |
| 236 << in_path.value() << std::endl; | 236 << in_path.value() << std::endl; |
| 237 return 1; | 237 return 1; |
| 238 } | 238 } |
| 239 | 239 |
| 240 // Buffer used for audio decoding. | 240 // Buffer used for audio decoding. |
| 241 scoped_ptr_malloc<int16, media::ScopedPtrAVFree> samples( | 241 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> audio_frame( |
| 242 reinterpret_cast<int16*>(av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE))); | |
| 243 | |
| 244 // Buffer used for video decoding. | |
| 245 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> frame( | |
| 246 avcodec_alloc_frame()); | 242 avcodec_alloc_frame()); |
| 247 if (!frame.get()) { | 243 if (!audio_frame.get()) { |
| 248 std::cerr << "Error: avcodec_alloc_frame for " | 244 std::cerr << "Error: avcodec_alloc_frame for " |
| 249 << in_path.value() << std::endl; | 245 << in_path.value() << std::endl; |
| 250 return 1; | 246 return 1; |
| 247 } |
| 248 |
| 249 // Buffer used for video decoding. |
| 250 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> video_frame( |
| 251 avcodec_alloc_frame()); |
| 252 if (!video_frame.get()) { |
| 253 std::cerr << "Error: avcodec_alloc_frame for " |
| 254 << in_path.value() << std::endl; |
| 255 return 1; |
| 251 } | 256 } |
| 252 | 257 |
| 253 // Stats collector. | 258 // Stats collector. |
| 254 EnterTimingSection(); | 259 EnterTimingSection(); |
| 255 std::vector<double> decode_times; | 260 std::vector<double> decode_times; |
| 256 decode_times.reserve(4096); | 261 decode_times.reserve(4096); |
| 257 // Parse through the entire stream until we hit EOF. | 262 // Parse through the entire stream until we hit EOF. |
| 258 #if SHOW_VERBOSE | 263 #if SHOW_VERBOSE |
| 259 base::TimeTicks start = base::TimeTicks::HighResNow(); | 264 base::TimeTicks start = base::TimeTicks::HighResNow(); |
| 260 #endif | 265 #endif |
| (...skipping 16 matching lines...) Expand all Loading... |
| 277 packet.size = 0; | 282 packet.size = 0; |
| 278 } else { | 283 } else { |
| 279 break; | 284 break; |
| 280 } | 285 } |
| 281 } | 286 } |
| 282 | 287 |
| 283 // Only decode packets from our target stream. | 288 // Only decode packets from our target stream. |
| 284 if (packet.stream_index == target_stream) { | 289 if (packet.stream_index == target_stream) { |
| 285 int result = -1; | 290 int result = -1; |
| 286 if (target_codec == AVMEDIA_TYPE_AUDIO) { | 291 if (target_codec == AVMEDIA_TYPE_AUDIO) { |
| 287 int size_out = AVCODEC_MAX_AUDIO_FRAME_SIZE; | 292 int size_out = 0; |
| 293 int got_audio = 0; |
| 294 |
| 295 avcodec_get_frame_defaults(audio_frame.get()); |
| 288 | 296 |
| 289 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); | 297 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); |
| 290 result = avcodec_decode_audio3(codec_context, samples.get(), &size_out, | 298 result = avcodec_decode_audio4(codec_context, audio_frame.get(), |
| 291 &packet); | 299 &got_audio, &packet); |
| 292 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; | 300 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; |
| 293 | 301 |
| 294 if (size_out) { | 302 if (got_audio) { |
| 303 size_out = av_samples_get_buffer_size( |
| 304 NULL, codec_context->channels, audio_frame->nb_samples, |
| 305 codec_context->sample_fmt, 1); |
| 306 } |
| 307 |
| 308 if (got_audio && size_out) { |
| 295 decode_times.push_back(delta.InMillisecondsF()); | 309 decode_times.push_back(delta.InMillisecondsF()); |
| 296 ++frames; | 310 ++frames; |
| 297 read_result = 0; // Force continuation. | 311 read_result = 0; // Force continuation. |
| 298 | 312 |
| 299 if (output) { | 313 if (output) { |
| 300 if (fwrite(samples.get(), 1, size_out, output) != | 314 if (fwrite(audio_frame->data[0], 1, size_out, output) != |
| 301 static_cast<size_t>(size_out)) { | 315 static_cast<size_t>(size_out)) { |
| 302 std::cerr << "Error: Could not write " | 316 std::cerr << "Error: Could not write " |
| 303 << size_out << " bytes for " << in_path.value() | 317 << size_out << " bytes for " << in_path.value() |
| 304 << std::endl; | 318 << std::endl; |
| 305 return 1; | 319 return 1; |
| 306 } | 320 } |
| 307 } | 321 } |
| 308 | 322 |
| 309 const uint8* u8_samples = | 323 const uint8* u8_samples = |
| 310 reinterpret_cast<const uint8*>(samples.get()); | 324 reinterpret_cast<const uint8*>(audio_frame->data[0]); |
| 311 if (hash_djb2) { | 325 if (hash_djb2) { |
| 312 hash_value = DJB2Hash(u8_samples, size_out, hash_value); | 326 hash_value = DJB2Hash(u8_samples, size_out, hash_value); |
| 313 } | 327 } |
| 314 if (hash_md5) { | 328 if (hash_md5) { |
| 315 base::MD5Update( | 329 base::MD5Update( |
| 316 &ctx, | 330 &ctx, |
| 317 base::StringPiece( | 331 base::StringPiece(reinterpret_cast<const char*>(u8_samples), |
| 318 reinterpret_cast<const char*>(u8_samples), size_out)); | 332 size_out)); |
| 319 } | 333 } |
| 320 } | 334 } |
| 321 } else if (target_codec == AVMEDIA_TYPE_VIDEO) { | 335 } else if (target_codec == AVMEDIA_TYPE_VIDEO) { |
| 322 int got_picture = 0; | 336 int got_picture = 0; |
| 323 | 337 |
| 338 avcodec_get_frame_defaults(video_frame.get()); |
| 339 |
| 324 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); | 340 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); |
| 325 result = avcodec_decode_video2(codec_context, frame.get(), | 341 result = avcodec_decode_video2(codec_context, video_frame.get(), |
| 326 &got_picture, &packet); | 342 &got_picture, &packet); |
| 327 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; | 343 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; |
| 328 | 344 |
| 329 if (got_picture) { | 345 if (got_picture) { |
| 330 decode_times.push_back(delta.InMillisecondsF()); | 346 decode_times.push_back(delta.InMillisecondsF()); |
| 331 ++frames; | 347 ++frames; |
| 332 read_result = 0; // Force continuation. | 348 read_result = 0; // Force continuation. |
| 333 | 349 |
| 334 for (int plane = 0; plane < 3; ++plane) { | 350 for (int plane = 0; plane < 3; ++plane) { |
| 335 const uint8* source = frame->data[plane]; | 351 const uint8* source = video_frame->data[plane]; |
| 336 const size_t source_stride = frame->linesize[plane]; | 352 const size_t source_stride = video_frame->linesize[plane]; |
| 337 size_t bytes_per_line = codec_context->width; | 353 size_t bytes_per_line = codec_context->width; |
| 338 size_t copy_lines = codec_context->height; | 354 size_t copy_lines = codec_context->height; |
| 339 if (plane != 0) { | 355 if (plane != 0) { |
| 340 switch (codec_context->pix_fmt) { | 356 switch (codec_context->pix_fmt) { |
| 341 case PIX_FMT_YUV420P: | 357 case PIX_FMT_YUV420P: |
| 342 case PIX_FMT_YUVJ420P: | 358 case PIX_FMT_YUVJ420P: |
| 343 bytes_per_line /= 2; | 359 bytes_per_line /= 2; |
| 344 copy_lines = (copy_lines + 1) / 2; | 360 copy_lines = (copy_lines + 1) / 2; |
| 345 break; | 361 break; |
| 346 case PIX_FMT_YUV422P: | 362 case PIX_FMT_YUV422P: |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 #if defined(ENABLE_WINDOWS_EXCEPTIONS) | 507 #if defined(ENABLE_WINDOWS_EXCEPTIONS) |
| 492 } __except(EXCEPTION_EXECUTE_HANDLER) { | 508 } __except(EXCEPTION_EXECUTE_HANDLER) { |
| 493 *log_out << " Exception:" << std::setw(11) << GetExceptionCode() | 509 *log_out << " Exception:" << std::setw(11) << GetExceptionCode() |
| 494 << " " << in_path.value() << std::endl; | 510 << " " << in_path.value() << std::endl; |
| 495 return 1; | 511 return 1; |
| 496 } | 512 } |
| 497 #endif | 513 #endif |
| 498 CommandLine::Reset(); | 514 CommandLine::Reset(); |
| 499 return 0; | 515 return 0; |
| 500 } | 516 } |
| OLD | NEW |