| 778 | } |
| 779 | |
| 780 | static TimingStats RunCpuCompositeBenchmark(const BenchmarkOptions& options, const QImage& overlay_image, |
| 781 | DecodeKind decode_kind, bool& used_hw_decode) { |
| 782 | TimingStats stats; |
| 783 | const auto total_start = Clock::now(); |
| 784 | GenericDecodeReader decoder(options, decode_kind); |
| 785 | decoder.Open(); |
| 786 | used_hw_decode = false; |
| 787 | |
| 788 | RgbaFrameConverter converter; |
| 789 | RenderLayout layout; |
| 790 | QImage prepared_overlay; |
| 791 | bool overlay_ready = false; |
| 792 | for (int frame_index = 0; frame_index < options.max_frames; ++frame_index) { |
| 793 | ScopedFrame input_frame; |
| 794 | double decode_ms = 0.0; |
| 795 | if (!decoder.NextFrame(input_frame, decode_ms)) |
| 796 | break; |
| 797 | stats.decode_ms += decode_ms; |
| 798 | used_hw_decode = used_hw_decode || decoder.UsingHwDecode(); |
| 799 | |
| 800 | const auto composite_start = Clock::now(); |
| 801 | ScopedFrame rgba_frame = converter.Convert(input_frame.get()); |
| 802 | QImage source_image = QImageFromRgbaFrame(rgba_frame.get()); |
| 803 | if (!overlay_ready) { |
| 804 | layout = ComputeRenderLayout(options, source_image.width(), source_image.height()); |
| 805 | prepared_overlay = PrepareOverlayImage(options, layout, overlay_image); |
| 806 | overlay_ready = true; |
| 807 | } |
| 808 | QImage output(layout.output_width, layout.output_height, QImage::Format_RGBA8888_Premultiplied); |
| 809 | output.fill(QColor("#101418")); |
| 810 | |
| 811 | QPainter painter(&output); |
| 812 | painter.setRenderHint(QPainter::SmoothPixmapTransform, true); |
| 813 | painter.setRenderHint(QPainter::Antialiasing, true); |
| 814 | painter.drawImage(output.rect(), source_image); |
| 815 | painter.setOpacity(1.0); |
| 816 | painter.drawImage(layout.overlay_x, layout.overlay_y, prepared_overlay); |
| 817 | painter.end(); |
| 818 | const std::string row_name = |
| 819 | decode_kind == DecodeKind::Cuda ? "CUDA->CPU" : |
| 820 | decode_kind == DecodeKind::Vaapi ? "VAAPI->CPU" : |
| 821 | decode_kind == DecodeKind::Vulkan ? "Vulkan->CPU" : |
| 822 | "CPU->CPU"; |
| 823 | SaveDumpImage(options, row_name, frame_index + 1, output); |
| 824 | const auto composite_end = Clock::now(); |
| 825 | |
| 826 | stats.composite_ms += std::chrono::duration<double, std::milli>(composite_end - composite_start).count(); |
| 827 | stats.frames++; |
| 828 | } |
| 829 | |
| 830 | decoder.Close(); |
| 831 | stats.total_ms = std::chrono::duration<double, std::milli>(Clock::now() - total_start).count(); |
| 832 | return stats; |
| 833 | } |
| 834 | |
| 835 | static ScopedFrame ConvertQImageToAvFrame(const QImage& image) { |
| 836 | QImage rgba = image.convertToFormat(QImage::Format_RGBA8888); |
no test coverage detected