| 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 // 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 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 | 350 |
| 351 // Initialize our codec. | 351 // Initialize our codec. |
| 352 if (avcodec_open2(codec_context, codec, NULL) < 0) { | 352 if (avcodec_open2(codec_context, codec, NULL) < 0) { |
| 353 std::cerr << "Error: Could not open codec " | 353 std::cerr << "Error: Could not open codec " |
| 354 << (codec_context->codec ? codec_context->codec->name : "(NULL)") | 354 << (codec_context->codec ? codec_context->codec->name : "(NULL)") |
| 355 << " for " << in_path.value() << std::endl; | 355 << " for " << in_path.value() << std::endl; |
| 356 return 1; | 356 return 1; |
| 357 } | 357 } |
| 358 | 358 |
| 359 // Buffer used for audio decoding. | 359 // Buffer used for audio decoding. |
| 360 scoped_ptr_malloc<int16, media::ScopedPtrAVFree> samples( | 360 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> audio_frame( |
| 361 reinterpret_cast<int16*>(av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE))); | |
| 362 | |
| 363 // Buffer used for video decoding. | |
| 364 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> frame( | |
| 365 avcodec_alloc_frame()); | 361 avcodec_alloc_frame()); |
| 366 if (!frame.get()) { | 362 if (!audio_frame.get()) { |
| 367 std::cerr << "Error: avcodec_alloc_frame for " | 363 std::cerr << "Error: avcodec_alloc_frame for " |
| 368 << in_path.value() << std::endl; | 364 << in_path.value() << std::endl; |
| 369 return 1; | 365 return 1; |
| 366 } |
| 367 |
| 368 // Buffer used for video decoding. |
| 369 scoped_ptr_malloc<AVFrame, media::ScopedPtrAVFree> video_frame( |
| 370 avcodec_alloc_frame()); |
| 371 if (!video_frame.get()) { |
| 372 std::cerr << "Error: avcodec_alloc_frame for " |
| 373 << in_path.value() << std::endl; |
| 374 return 1; |
| 370 } | 375 } |
| 371 | 376 |
| 372 // Remember size of video. | 377 // Remember size of video. |
| 373 int video_width = codec_context->width; | 378 int video_width = codec_context->width; |
| 374 int video_height = codec_context->height; | 379 int video_height = codec_context->height; |
| 375 | 380 |
| 376 // Stats collector. | 381 // Stats collector. |
| 377 EnterTimingSection(); | 382 EnterTimingSection(); |
| 378 std::vector<double> decode_times; | 383 std::vector<double> decode_times; |
| 379 decode_times.reserve(4096); | 384 decode_times.reserve(4096); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 398 packet.size = 0; | 403 packet.size = 0; |
| 399 } else { | 404 } else { |
| 400 break; | 405 break; |
| 401 } | 406 } |
| 402 } | 407 } |
| 403 | 408 |
| 404 // Only decode packets from our target stream. | 409 // Only decode packets from our target stream. |
| 405 if (packet.stream_index == target_stream) { | 410 if (packet.stream_index == target_stream) { |
| 406 int result = -1; | 411 int result = -1; |
| 407 if (target_codec == AVMEDIA_TYPE_AUDIO) { | 412 if (target_codec == AVMEDIA_TYPE_AUDIO) { |
| 408 int size_out = AVCODEC_MAX_AUDIO_FRAME_SIZE; | 413 int size_out = 0; |
| 414 int got_audio = 0; |
| 415 |
| 416 avcodec_get_frame_defaults(audio_frame.get()); |
| 409 | 417 |
| 410 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); | 418 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); |
| 411 result = avcodec_decode_audio3(codec_context, samples.get(), &size_out, | 419 result = avcodec_decode_audio4(codec_context, audio_frame.get(), |
| 412 &packet); | 420 &got_audio, &packet); |
| 413 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; | 421 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; |
| 414 | 422 |
| 415 if (size_out) { | 423 if (got_audio) { |
| 424 size_out = av_samples_get_buffer_size( |
| 425 NULL, codec_context->channels, audio_frame->nb_samples, |
| 426 codec_context->sample_fmt, 1); |
| 427 } |
| 428 |
| 429 if (got_audio && size_out) { |
| 416 decode_times.push_back(delta.InMillisecondsF()); | 430 decode_times.push_back(delta.InMillisecondsF()); |
| 417 ++frames; | 431 ++frames; |
| 418 read_result = 0; // Force continuation. | 432 read_result = 0; // Force continuation. |
| 419 | 433 |
| 420 if (output) { | 434 if (output) { |
| 421 if (fwrite(samples.get(), 1, size_out, output) != | 435 if (fwrite(audio_frame->data[0], 1, size_out, output) != |
| 422 static_cast<size_t>(size_out)) { | 436 static_cast<size_t>(size_out)) { |
| 423 std::cerr << "Error: Could not write " | 437 std::cerr << "Error: Could not write " |
| 424 << size_out << " bytes for " << in_path.value() | 438 << size_out << " bytes for " << in_path.value() |
| 425 << std::endl; | 439 << std::endl; |
| 426 return 1; | 440 return 1; |
| 427 } | 441 } |
| 428 } | 442 } |
| 429 | 443 |
| 430 const uint8* u8_samples = | 444 const uint8* u8_samples = |
| 431 reinterpret_cast<const uint8*>(samples.get()); | 445 reinterpret_cast<const uint8*>(audio_frame->data[0]); |
| 432 if (hash_djb2) { | 446 if (hash_djb2) { |
| 433 hash_value = DJB2Hash(u8_samples, size_out, hash_value); | 447 hash_value = DJB2Hash(u8_samples, size_out, hash_value); |
| 434 } | 448 } |
| 435 if (hash_md5) { | 449 if (hash_md5) { |
| 436 base::MD5Update( | 450 base::MD5Update( |
| 437 &ctx, | 451 &ctx, |
| 438 base::StringPiece(reinterpret_cast<const char*>(u8_samples), | 452 base::StringPiece(reinterpret_cast<const char*>(u8_samples), |
| 439 size_out)); | 453 size_out)); |
| 440 } | 454 } |
| 441 } | 455 } |
| 442 } else if (target_codec == AVMEDIA_TYPE_VIDEO) { | 456 } else if (target_codec == AVMEDIA_TYPE_VIDEO) { |
| 443 int got_picture = 0; | 457 int got_picture = 0; |
| 444 | 458 |
| 459 avcodec_get_frame_defaults(video_frame.get()); |
| 460 |
| 445 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); | 461 base::TimeTicks decode_start = base::TimeTicks::HighResNow(); |
| 446 result = avcodec_decode_video2(codec_context, frame.get(), | 462 result = avcodec_decode_video2(codec_context, video_frame.get(), |
| 447 &got_picture, &packet); | 463 &got_picture, &packet); |
| 448 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; | 464 base::TimeDelta delta = base::TimeTicks::HighResNow() - decode_start; |
| 449 | 465 |
| 450 if (got_picture) { | 466 if (got_picture) { |
| 451 decode_times.push_back(delta.InMillisecondsF()); | 467 decode_times.push_back(delta.InMillisecondsF()); |
| 452 ++frames; | 468 ++frames; |
| 453 read_result = 0; // Force continuation. | 469 read_result = 0; // Force continuation. |
| 454 | 470 |
| 455 for (int plane = 0; plane < 3; ++plane) { | 471 for (int plane = 0; plane < 3; ++plane) { |
| 456 const uint8* source = frame->data[plane]; | 472 const uint8* source = video_frame->data[plane]; |
| 457 const size_t source_stride = frame->linesize[plane]; | 473 const size_t source_stride = video_frame->linesize[plane]; |
| 458 size_t bytes_per_line = codec_context->width; | 474 size_t bytes_per_line = codec_context->width; |
| 459 size_t copy_lines = codec_context->height; | 475 size_t copy_lines = codec_context->height; |
| 460 if (plane != 0) { | 476 if (plane != 0) { |
| 461 switch (codec_context->pix_fmt) { | 477 switch (codec_context->pix_fmt) { |
| 462 case PIX_FMT_YUV420P: | 478 case PIX_FMT_YUV420P: |
| 463 case PIX_FMT_YUVJ420P: | 479 case PIX_FMT_YUVJ420P: |
| 464 bytes_per_line /= 2; | 480 bytes_per_line /= 2; |
| 465 copy_lines = (copy_lines + 1) / 2; | 481 copy_lines = (copy_lines + 1) / 2; |
| 466 break; | 482 break; |
| 467 case PIX_FMT_YUV422P: | 483 case PIX_FMT_YUV422P: |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 #if defined(ENABLE_WINDOWS_EXCEPTIONS) | 609 #if defined(ENABLE_WINDOWS_EXCEPTIONS) |
| 594 } __except(EXCEPTION_EXECUTE_HANDLER) { | 610 } __except(EXCEPTION_EXECUTE_HANDLER) { |
| 595 *log_out << " Exception:" << std::setw(11) << GetExceptionCode() | 611 *log_out << " Exception:" << std::setw(11) << GetExceptionCode() |
| 596 << " " << in_path.value() << std::endl; | 612 << " " << in_path.value() << std::endl; |
| 597 return 1; | 613 return 1; |
| 598 } | 614 } |
| 599 #endif | 615 #endif |
| 600 CommandLine::Reset(); | 616 CommandLine::Reset(); |
| 601 return 0; | 617 return 0; |
| 602 } | 618 } |
| OLD | NEW |