Send a null AVFrame to indicate end of stream to allow renderers to do render thread cleanup
This commit is contained in:
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]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue