diff --git a/test/testffmpeg.c b/test/testffmpeg.c index 35e91265c1..03807a9ae5 100644 --- a/test/testffmpeg.c +++ b/test/testffmpeg.c @@ -881,6 +881,22 @@ static SDL_bool GetTextureForFrame(AVFrame *frame, SDL_Texture **texture) } } +static int BeginFrameRendering(AVFrame *frame) +{ + if (frame->format == AV_PIX_FMT_VULKAN) { + return BeginVulkanFrameRendering(vulkan_context, frame, renderer); + } + return 0; +} + +static int FinishFrameRendering(AVFrame *frame) +{ + if (frame->format == AV_PIX_FMT_VULKAN) { + return FinishVulkanFrameRendering(vulkan_context, frame, renderer); + } + return 0; +} + static void DisplayVideoTexture(AVFrame *frame) { /* Update the video texture */ @@ -913,6 +929,10 @@ static void HandleVideoFrame(AVFrame *frame, double pts) now = (double)(SDL_GetTicks() - video_start) / 1000.0; } + if (BeginFrameRendering(frame) < 0) { + return; + } + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); @@ -922,6 +942,8 @@ static void HandleVideoFrame(AVFrame *frame, double pts) MoveSprite(); SDL_RenderPresent(renderer); + + FinishFrameRendering(frame); } static AVCodecContext *OpenAudioStream(AVFormatContext *ic, int stream, const AVCodec *codec) diff --git a/test/testffmpeg_vulkan.c b/test/testffmpeg_vulkan.c index 5d7fbc5d02..467100b298 100644 --- a/test/testffmpeg_vulkan.c +++ b/test/testffmpeg_vulkan.c @@ -773,10 +773,18 @@ static int CreateCommandBuffers(VulkanVideoContext *context, SDL_Renderer *rende return 0; } -static int ScheduleFrameTransferToSDL(VulkanVideoContext *context, AVFrame *frame) +int BeginVulkanFrameRendering(VulkanVideoContext *context, AVFrame *frame, SDL_Renderer *renderer) { + AVHWFramesContext *frames = (AVHWFramesContext *)(frame->hw_frames_ctx->data); + AVVulkanFramesContext *vk = (AVVulkanFramesContext *)(frames->hwctx); AVVkFrame *pVkFrame = (AVVkFrame *)frame->data[0]; + if (CreateCommandBuffers(context, renderer) < 0) { + return -1; + } + + vk->lock_frame(frames, pVkFrame); + VkTimelineSemaphoreSubmitInfo timeline = { 0 }; timeline.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO; timeline.waitSemaphoreValueCount = 1; @@ -834,15 +842,22 @@ static int ScheduleFrameTransferToSDL(VulkanVideoContext *context, AVFrame *fram VkResult result = context->vkQueueSubmit(context->graphicsQueue, 1, &submitInfo, 0); if (result != VK_SUCCESS) { - return SDL_SetError("vkQueueSubmit(): %s", getVulkanResultString(result)); + /* Don't return an error here, we need to complete the frame operation */ + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION , "vkQueueSubmit(): %s", getVulkanResultString(result)); } + + SDL_AddVulkanRenderSemaphores(renderer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (Sint64)context->waitSemaphores[context->commandBufferIndex], (Sint64)context->signalSemaphores[context->commandBufferIndex]); + return 0; } -static int ScheduleFrameTransferToFFMPEG(VulkanVideoContext *context, AVFrame *frame) +int FinishVulkanFrameRendering(VulkanVideoContext *context, AVFrame *frame, SDL_Renderer *renderer) { + AVHWFramesContext *frames = (AVHWFramesContext *)(frame->hw_frames_ctx->data); + AVVulkanFramesContext *vk = (AVVulkanFramesContext *)(frames->hwctx); AVVkFrame *pVkFrame = (AVVkFrame *)frame->data[0]; + /* Transition the frame back to ffmpeg */ ++pVkFrame->sem_value[0]; VkTimelineSemaphoreSubmitInfo timeline = { 0 }; @@ -862,28 +877,12 @@ static int ScheduleFrameTransferToFFMPEG(VulkanVideoContext *context, AVFrame *f VkResult result = context->vkQueueSubmit(context->graphicsQueue, 1, &submitInfo, 0); if (result != VK_SUCCESS) { - return SDL_SetError("vkQueueSubmit(): %s", getVulkanResultString(result)); - } - return 0; -} - -static int PrepareFrameRendering(VulkanVideoContext *context, AVFrame *frame, SDL_Renderer *renderer) -{ - AVHWFramesContext *frames = (AVHWFramesContext *)(frame->hw_frames_ctx->data); - AVVulkanFramesContext *vk = (AVVulkanFramesContext *)(frames->hwctx); - AVVkFrame *pVkFrame = (AVVkFrame *)frame->data[0]; - - if (CreateCommandBuffers(context, renderer) < 0) { - return -1; + /* Don't return an error here, we need to complete the frame operation */ + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "vkQueueSubmit(): %s", getVulkanResultString(result)); } - vk->lock_frame(frames, pVkFrame); - ScheduleFrameTransferToSDL(context, frame); - ScheduleFrameTransferToFFMPEG(context, frame); vk->unlock_frame(frames, pVkFrame); - SDL_AddVulkanRenderSemaphores(renderer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (Sint64)context->waitSemaphores[context->commandBufferIndex], (Sint64)context->signalSemaphores[context->commandBufferIndex]); - context->commandBufferIndex = (context->commandBufferIndex + 1) % context->commandBufferCount; return 0; @@ -896,10 +895,6 @@ SDL_Texture *CreateVulkanVideoTexture(VulkanVideoContext *context, AVFrame *fram AVVkFrame *pVkFrame = (AVVkFrame *)frame->data[0]; Uint32 format; - if (PrepareFrameRendering(context, frame, renderer) < 0) { - return NULL; - } - switch (vk->format[0]) { case VK_FORMAT_G8B8G8R8_422_UNORM: format = SDL_PIXELFORMAT_YUY2; diff --git a/test/testffmpeg_vulkan.h b/test/testffmpeg_vulkan.h index 2ae046dfa3..78cabced44 100644 --- a/test/testffmpeg_vulkan.h +++ b/test/testffmpeg_vulkan.h @@ -15,8 +15,10 @@ typedef struct VulkanVideoContext VulkanVideoContext; -VulkanVideoContext *CreateVulkanVideoContext(SDL_Window *window); -void SetupVulkanRenderProperties(VulkanVideoContext *context, SDL_PropertiesID props); -void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceContext *ctx); -SDL_Texture *CreateVulkanVideoTexture(VulkanVideoContext *context, AVFrame *frame, SDL_Renderer *renderer, SDL_PropertiesID props); -void DestroyVulkanVideoContext(VulkanVideoContext *context); +extern VulkanVideoContext *CreateVulkanVideoContext(SDL_Window *window); +extern void SetupVulkanRenderProperties(VulkanVideoContext *context, SDL_PropertiesID props); +extern void SetupVulkanDeviceContextData(VulkanVideoContext *context, AVVulkanDeviceContext *ctx); +extern SDL_Texture *CreateVulkanVideoTexture(VulkanVideoContext *context, AVFrame *frame, SDL_Renderer *renderer, SDL_PropertiesID props); +extern int BeginVulkanFrameRendering(VulkanVideoContext *context, AVFrame *frame, SDL_Renderer *renderer); +extern int FinishVulkanFrameRendering(VulkanVideoContext *context, AVFrame *frame, SDL_Renderer *renderer); +extern void DestroyVulkanVideoContext(VulkanVideoContext *context);