Send a null AVFrame to indicate end of stream to allow renderers to do render thread cleanup

This commit is contained in:
Cameron Gutman
2020-05-13 18:55:21 -07:00
parent 5ed7e03b2e
commit 51e9ab83ad
9 changed files with 48 additions and 0 deletions
@@ -202,6 +202,11 @@ int DrmRenderer::getRendererAttributes()
void DrmRenderer::renderFrame(AVFrame* frame) void DrmRenderer::renderFrame(AVFrame* frame)
{ {
if (frame == nullptr) {
// End of stream - nothing to do for us
return;
}
AVDRMFrameDescriptor* drmFrame = (AVDRMFrameDescriptor*)frame->data[0]; AVDRMFrameDescriptor* drmFrame = (AVDRMFrameDescriptor*)frame->data[0];
int err; int err;
uint32_t primeHandle; uint32_t primeHandle;
@@ -812,6 +812,11 @@ int DXVA2Renderer::getDecoderColorspace()
void DXVA2Renderer::renderFrame(AVFrame *frame) void DXVA2Renderer::renderFrame(AVFrame *frame)
{ {
if (frame == nullptr) {
// End of stream - nothing to do for us
return;
}
IDirect3DSurface9* surface = reinterpret_cast<IDirect3DSurface9*>(frame->data[3]); IDirect3DSurface9* surface = reinterpret_cast<IDirect3DSurface9*>(frame->data[3]);
HRESULT hr; HRESULT hr;
@@ -434,6 +434,12 @@ bool EGLRenderer::specialize() {
void EGLRenderer::renderFrame(AVFrame* frame) void EGLRenderer::renderFrame(AVFrame* frame)
{ {
EGLImage imgs[EGL_MAX_PLANES]; EGLImage imgs[EGL_MAX_PLANES];
if (frame == nullptr) {
// End of stream - nothing to do for us
return;
}
if (frame->hw_frames_ctx != nullptr) { if (frame->hw_frames_ctx != nullptr) {
// Find the native read-back format and load the shader // Find the native read-back format and load the shader
if (m_SwPixelFormat == AV_PIX_FMT_NONE) { if (m_SwPixelFormat == AV_PIX_FMT_NONE) {
@@ -147,6 +147,11 @@ bool MmalRenderer::needsTestFrame()
void MmalRenderer::renderFrame(AVFrame* frame) void MmalRenderer::renderFrame(AVFrame* frame)
{ {
if (frame == nullptr) {
// End of stream - nothing to do for us
return;
}
MMAL_BUFFER_HEADER_T* buffer = (MMAL_BUFFER_HEADER_T*)frame->data[3]; MMAL_BUFFER_HEADER_T* buffer = (MMAL_BUFFER_HEADER_T*)frame->data[3];
MMAL_STATUS_T status; MMAL_STATUS_T status;
@@ -45,6 +45,10 @@ Pacer::~Pacer()
m_RenderQueueNotEmpty.wakeAll(); m_RenderQueueNotEmpty.wakeAll();
SDL_WaitThread(m_RenderThread, nullptr); SDL_WaitThread(m_RenderThread, nullptr);
} }
else {
// Send a null AVFrame to indicate end of stream on the main thread
m_VsyncRenderer->renderFrame(nullptr);
}
// Delete any remaining unconsumed frames // Delete any remaining unconsumed frames
while (!m_RenderQueue.isEmpty()) { while (!m_RenderQueue.isEmpty()) {
@@ -106,6 +110,9 @@ int Pacer::renderThread(void* context)
me->renderLastFrameAndUnlock(); me->renderLastFrameAndUnlock();
} }
// Send a null AVFrame to indicate end of stream on the render thread
me->m_VsyncRenderer->renderFrame(nullptr);
return 0; return 0;
} }
@@ -259,6 +259,11 @@ void SdlRenderer::renderFrame(AVFrame* frame)
int err; int err;
AVFrame* swFrame = nullptr; AVFrame* swFrame = nullptr;
if (frame == nullptr) {
// End of stream - nothing to do for us
return;
}
if (frame->hw_frames_ctx != nullptr) { if (frame->hw_frames_ctx != nullptr) {
// If we are acting as the frontend for a hardware // If we are acting as the frontend for a hardware
// accelerated decoder, we'll need to read the frame // accelerated decoder, we'll need to read the frame
@@ -391,6 +391,11 @@ int VAAPIRenderer::getDecoderColorspace()
void void
VAAPIRenderer::renderFrame(AVFrame* frame) VAAPIRenderer::renderFrame(AVFrame* frame)
{ {
if (frame == nullptr) {
// End of stream - nothing to do for us
return;
}
VASurfaceID surface = (VASurfaceID)(uintptr_t)frame->data[3]; VASurfaceID surface = (VASurfaceID)(uintptr_t)frame->data[3];
AVHWDeviceContext* deviceContext = (AVHWDeviceContext*)m_HwContext->data; AVHWDeviceContext* deviceContext = (AVHWDeviceContext*)m_HwContext->data;
AVVAAPIDeviceContext* vaDeviceContext = (AVVAAPIDeviceContext*)deviceContext->hwctx; AVVAAPIDeviceContext* vaDeviceContext = (AVVAAPIDeviceContext*)deviceContext->hwctx;
@@ -302,6 +302,11 @@ int VDPAURenderer::getDecoderColorspace()
void VDPAURenderer::renderFrame(AVFrame* frame) void VDPAURenderer::renderFrame(AVFrame* frame)
{ {
if (frame == nullptr) {
// End of stream - nothing to do for us
return;
}
VdpStatus status; VdpStatus status;
VdpVideoSurface videoSurface = (VdpVideoSurface)(uintptr_t)frame->data[3]; VdpVideoSurface videoSurface = (VdpVideoSurface)(uintptr_t)frame->data[3];
@@ -158,6 +158,11 @@ public:
// Caller frees frame after we return // Caller frees frame after we return
virtual void renderFrame(AVFrame* frame) override virtual void renderFrame(AVFrame* frame) override
{ {
if (frame == nullptr) {
// End of stream - nothing to do for us
return;
}
OSStatus status; OSStatus status;
CVPixelBufferRef pixBuf = reinterpret_cast<CVPixelBufferRef>(frame->data[3]); CVPixelBufferRef pixBuf = reinterpret_cast<CVPixelBufferRef>(frame->data[3]);