| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 // Standalone benchmarking application based on FFmpeg. This tool is used to | 5 // Standalone benchmarking application based on FFmpeg. This tool is used to |
| 6 // measure decoding performance between different FFmpeg compile and run-time | 6 // measure decoding performance between different FFmpeg compile and run-time |
| 7 // options. We also use this tool to measure performance regressions when | 7 // options. We also use this tool to measure performance regressions when |
| 8 // testing newer builds of FFmpeg from trunk. | 8 // testing newer builds of FFmpeg from trunk. |
| 9 | 9 |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 | 310 |
| 311 // Initialize our codec. | 311 // Initialize our codec. |
| 312 if (avcodec_open(codec_context, codec) < 0) { | 312 if (avcodec_open(codec_context, codec) < 0) { |
| 313 std::cerr << "Error: Could not open codec " | 313 std::cerr << "Error: Could not open codec " |
| 314 << codec_context->codec->name << " for " | 314 << codec_context->codec->name << " for " |
| 315 << in_path << std::endl; | 315 << in_path << std::endl; |
| 316 return 1; | 316 return 1; |
| 317 } | 317 } |
| 318 | 318 |
| 319 // Buffer used for audio decoding. | 319 // Buffer used for audio decoding. |
| 320 int16* samples = | 320 scoped_ptr_malloc<int16, media::ScopedPtrAVFree> samples( |
| 321 reinterpret_cast<int16*>(av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE)); | 321 reinterpret_cast<int16*>(av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE))); |
| 322 | 322 |
| 323 // Buffer used for video decoding. | 323 // Buffer used for video decoding. |
| 324 AVFrame* frame = avcodec_alloc_frame(); | 324 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> frame( |
| 325 if (!frame) { | 325 avcodec_alloc_frame()); |
| 326 if (!frame.get()) { |
| 326 std::cerr << "Error: avcodec_alloc_frame for " | 327 std::cerr << "Error: avcodec_alloc_frame for " |
| 327 << in_path << std::endl; | 328 << in_path << std::endl; |
| 328 return 1; | 329 return 1; |
| 329 } | 330 } |
| 330 | 331 |
| 331 // Stats collector. | 332 // Stats collector. |
| 332 EnterTimingSection(); | 333 EnterTimingSection(); |
| 333 std::vector<double> decode_times; | 334 std::vector<double> decode_times; |
| 334 decode_times.reserve(4096); | 335 decode_times.reserve(4096); |
| 335 // Parse through the entire stream until we hit EOF. | 336 // Parse through the entire stream until we hit EOF. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 356 } | 357 } |
| 357 } | 358 } |
| 358 | 359 |
| 359 // Only decode packets from our target stream. | 360 // Only decode packets from our target stream. |
| 360 if (packet.stream_index == target_stream) { | 361 if (packet.stream_index == target_stream) { |
| 361 int result = -1; | 362 int result = -1; |
| 362 if (target_codec == CODEC_TYPE_AUDIO) { | 363 if (target_codec == CODEC_TYPE_AUDIO) { |
| 363 int size_out = AVCODEC_MAX_AUDIO_FRAME_SIZE; | 364 int size_out = AVCODEC_MAX_AUDIO_FRAME_SIZE; |
| 364 | 365 |
| 365 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); | 366 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); |
| 366 result = avcodec_decode_audio3(codec_context, samples, &size_out, | 367 result = avcodec_decode_audio3(codec_context, samples.get(), &size_out, |
| 367 &packet); | 368 &packet); |
| 368 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; | 369 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; |
| 369 | 370 |
| 370 if (size_out) { | 371 if (size_out) { |
| 371 decode_times.push_back(delta.InMillisecondsF()); | 372 decode_times.push_back(delta.InMillisecondsF()); |
| 372 ++frames; | 373 ++frames; |
| 373 read_result = 0; // Force continuation. | 374 read_result = 0; // Force continuation. |
| 374 | 375 |
| 375 if (output) { | 376 if (output) { |
| 376 if (fwrite(samples, 1, size_out, output) != | 377 if (fwrite(samples.get(), 1, size_out, output) != |
| 377 static_cast<size_t>(size_out)) { | 378 static_cast<size_t>(size_out)) { |
| 378 std::cerr << "Error: Could not write " | 379 std::cerr << "Error: Could not write " |
| 379 << size_out << " bytes for " << in_path << std::endl; | 380 << size_out << " bytes for " << in_path << std::endl; |
| 380 return 1; | 381 return 1; |
| 381 } | 382 } |
| 382 } | 383 } |
| 384 |
| 385 const uint8* u8_samples = |
| 386 reinterpret_cast<const uint8*>(samples.get()); |
| 383 if (hash_djb2) { | 387 if (hash_djb2) { |
| 384 hash_value = DJB2Hash(reinterpret_cast<const uint8*>(samples), | 388 hash_value = DJB2Hash(u8_samples, size_out, hash_value); |
| 385 size_out, hash_value); | |
| 386 } | 389 } |
| 387 if (hash_md5) { | 390 if (hash_md5) { |
| 388 MD5Update(&ctx, reinterpret_cast<const uint8*>(samples), | 391 MD5Update(&ctx, u8_samples, size_out); |
| 389 size_out); | |
| 390 } | 392 } |
| 391 } | 393 } |
| 392 } else if (target_codec == CODEC_TYPE_VIDEO) { | 394 } else if (target_codec == CODEC_TYPE_VIDEO) { |
| 393 int got_picture = 0; | 395 int got_picture = 0; |
| 394 | 396 |
| 395 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); | 397 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); |
| 396 result = avcodec_decode_video2(codec_context, frame, &got_picture, | 398 result = avcodec_decode_video2(codec_context, frame.get(), |
| 397 &packet); | 399 &got_picture, &packet); |
| 398 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; | 400 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; |
| 399 | 401 |
| 400 if (got_picture) { | 402 if (got_picture) { |
| 401 decode_times.push_back(delta.InMillisecondsF()); | 403 decode_times.push_back(delta.InMillisecondsF()); |
| 402 ++frames; | 404 ++frames; |
| 403 read_result = 0; // Force continuation. | 405 read_result = 0; // Force continuation. |
| 404 | 406 |
| 405 for (int plane = 0; plane < 3; ++plane) { | 407 for (int plane = 0; plane < 3; ++plane) { |
| 406 const uint8* source = frame->data[plane]; | 408 const uint8* source = frame->data[plane]; |
| 407 const size_t source_stride = frame->linesize[plane]; | 409 const size_t source_stride = frame->linesize[plane]; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 } | 469 } |
| 468 // Free our packet. | 470 // Free our packet. |
| 469 av_free_packet(&packet); | 471 av_free_packet(&packet); |
| 470 | 472 |
| 471 if (max_frames && (frames >= max_frames)) | 473 if (max_frames && (frames >= max_frames)) |
| 472 break; | 474 break; |
| 473 } while (read_result >= 0); | 475 } while (read_result >= 0); |
| 474 base::TimeDelta total = base::TimeTicks::HighResNow() - start; | 476 base::TimeDelta total = base::TimeTicks::HighResNow() - start; |
| 475 LeaveTimingSection(); | 477 LeaveTimingSection(); |
| 476 | 478 |
| 479 // Clean up. |
| 477 if (output) | 480 if (output) |
| 478 file_util::CloseFile(output); | 481 file_util::CloseFile(output); |
| 482 if (codec_context) |
| 483 avcodec_close(codec_context); |
| 484 if (format_context) |
| 485 av_close_input_file(format_context); |
| 479 | 486 |
| 480 // Calculate the sum of times. Note that some of these may be zero. | 487 // Calculate the sum of times. Note that some of these may be zero. |
| 481 double sum = 0; | 488 double sum = 0; |
| 482 for (size_t i = 0; i < decode_times.size(); ++i) { | 489 for (size_t i = 0; i < decode_times.size(); ++i) { |
| 483 sum += decode_times[i]; | 490 sum += decode_times[i]; |
| 484 } | 491 } |
| 485 | 492 |
| 486 // Print our results. | 493 // Print our results. |
| 487 log_out->setf(std::ios::fixed); | 494 log_out->setf(std::ios::fixed); |
| 488 log_out->precision(2); | 495 log_out->precision(2); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 } | 534 } |
| 528 #if defined(OS_WIN) | 535 #if defined(OS_WIN) |
| 529 } __except(EXCEPTION_EXECUTE_HANDLER) { | 536 } __except(EXCEPTION_EXECUTE_HANDLER) { |
| 530 *log_out << " Exception:" << std::setw(11) << GetExceptionCode() | 537 *log_out << " Exception:" << std::setw(11) << GetExceptionCode() |
| 531 << " " << in_path << std::endl; | 538 << " " << in_path << std::endl; |
| 532 return 1; | 539 return 1; |
| 533 } | 540 } |
| 534 #endif | 541 #endif |
| 535 return 0; | 542 return 0; |
| 536 } | 543 } |
| OLD | NEW |