| 1944 | }; |
| 1945 | |
| 1946 | static TimingStats RunVulkanUploadBenchmark(const BenchmarkOptions& options, const QImage& overlay_image, |
| 1947 | DecodeKind decode_kind, bool& used_hw_decode) { |
| 1948 | TimingStats stats; |
| 1949 | const auto total_start = Clock::now(); |
| 1950 | |
| 1951 | GenericDecodeReader decoder(options, decode_kind); |
| 1952 | decoder.Open(); |
| 1953 | |
| 1954 | ScopedFrame first_frame; |
| 1955 | double decode_ms = 0.0; |
| 1956 | if (!decoder.NextFrame(first_frame, decode_ms)) { |
| 1957 | decoder.Close(); |
| 1958 | used_hw_decode = false; |
| 1959 | return stats; |
| 1960 | } |
| 1961 | |
| 1962 | used_hw_decode = decoder.UsingHwDecode(); |
| 1963 | stats.decode_ms += decode_ms; |
| 1964 | |
| 1965 | AVBufferRef* vulkan_device_context = nullptr; |
| 1966 | try { |
| 1967 | const RenderLayout layout = ComputeRenderLayout(options, first_frame.get()->width, first_frame.get()->height); |
| 1968 | RgbaFrameConverter converter; |
| 1969 | RgbaFrameResizer resizer; |
| 1970 | |
| 1971 | CheckAv(av_hwdevice_ctx_create(&vulkan_device_context, AV_HWDEVICE_TYPE_VULKAN, nullptr, nullptr, 0), |
| 1972 | "av_hwdevice_ctx_create vulkan upload device"); |
| 1973 | DirectVulkanPreviewCompositor compositor( |
| 1974 | options, |
| 1975 | overlay_image, |
| 1976 | vulkan_device_context, |
| 1977 | layout.output_width, |
| 1978 | layout.output_height); |
| 1979 | |
| 1980 | const int frame_limit = options.max_frames; |
| 1981 | ScopedFrame current_frame = std::move(first_frame); |
| 1982 | int frame_index = 0; |
| 1983 | while (current_frame && frame_index < frame_limit) { |
| 1984 | const auto upload_start = Clock::now(); |
| 1985 | ScopedFrame rgba_input_frame = converter.Convert(current_frame.get()); |
| 1986 | ScopedFrame scaled_input_frame = resizer.Resize(rgba_input_frame.get(), layout.output_width, layout.output_height); |
| 1987 | ForceOpaqueAlpha(scaled_input_frame.get()); |
| 1988 | ScopedFrame main_input_frame(av_frame_clone(scaled_input_frame.get())); |
| 1989 | const auto upload_end = Clock::now(); |
| 1990 | stats.upload_ms += std::chrono::duration<double, std::milli>(upload_end - upload_start).count(); |
| 1991 | |
| 1992 | if (!main_input_frame) |
| 1993 | throw std::runtime_error("Unable to clone RGBA main frame"); |
| 1994 | |
| 1995 | const auto composite_start = Clock::now(); |
| 1996 | compositor.CompositeSoftwareRgba(main_input_frame.get()); |
| 1997 | if (ShouldDumpFrame(options, frame_index + 1)) { |
| 1998 | SaveDumpImage( |
| 1999 | options, |
| 2000 | decode_kind == DecodeKind::Cuda ? "CUDA->Vk" : |
| 2001 | decode_kind == DecodeKind::Vaapi ? "VAAPI->Vk" : |
| 2002 | decode_kind == DecodeKind::Vulkan ? "Vulkan->Vk" : |
| 2003 | "CPU->Vk", |
no test coverage detected