Skip to content

Commit

Permalink
Merge pull request xbmc#23996 from smp79/avcodec_flush_buffers
Browse files Browse the repository at this point in the history
Don't flush ffmpeg buffers if it holds any refs on close
  • Loading branch information
fritsch authored Oct 28, 2023
2 parents 63c56c0 + 0394b03 commit 5a6255c
Show file tree
Hide file tree
Showing 6 changed files with 1 addition and 56 deletions.
22 changes: 1 addition & 21 deletions xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,15 +1114,6 @@ bool CVideoBufferPool::HasFree()
return !m_freeViews.empty();
}

bool CVideoBufferPool::HasRefs()
{
std::unique_lock<CCriticalSection> lock(m_section);
// out buffers hold views
const size_t buffRefs = m_out.size() - m_freeOut.size();
// ffmpeg refs = total - free - out refs
return m_freeViews.size() != m_views.size() - buffRefs;
}

//-----------------------------------------------------------------------------
// DXVA::CDecoder
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1166,15 +1157,6 @@ CDecoder::~CDecoder()
av_freep(&m_avD3D11Context);
}

long CDecoder::Release()
{
// if ffmpeg holds any references, flush buffers
if (m_bufferPool && m_bufferPool->HasRefs())
avcodec_flush_buffers(m_avCtx);

return IHardwareDecoder::Release();
}

void CDecoder::Close()
{
std::unique_lock<CCriticalSection> lock(m_section);
Expand Down Expand Up @@ -1443,8 +1425,6 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, enum AVPixel
mainctx->hwaccel_context = m_avD3D11Context;
mainctx->slice_flags = SLICE_FLAG_ALLOW_FIELD | SLICE_FLAG_CODED_ORDER;

m_avCtx = mainctx;

if (m_format.Guid == DXVADDI_Intel_ModeH264_E)
{
#ifdef FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO
Expand Down Expand Up @@ -1693,7 +1673,7 @@ void CDecoder::ReleaseBuffer(uint8_t* data)
CLog::LogF(LOGWARNING, "return of invalid surface.");
}

IHardwareDecoder::Release();
Release();
}

int CDecoder::FFGetBuffer(AVCodecContext* avctx, AVFrame* pic, int flags)
Expand Down
5 changes: 0 additions & 5 deletions xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ class CVideoBufferPool : public IVideoBufferPool
bool IsValid(ID3D11View* view);
size_t Size();
bool HasFree();
bool HasRefs();

protected:
void Reset();
Expand Down Expand Up @@ -218,9 +217,6 @@ class CDecoder : public IHardwareDecoder, public ID3DResource
unsigned GetAllowedReferences() override;
void Reset() override;

// IDVDResourceCounted overrides
long Release() override;

bool OpenDecoder();
int GetBuffer(AVCodecContext* avctx, AVFrame* pic);
void ReleaseBuffer(uint8_t* data);
Expand Down Expand Up @@ -270,7 +266,6 @@ class CDecoder : public IHardwareDecoder, public ID3DResource
CContext::shared_ptr m_dxvaContext;
CVideoBuffer* m_videoBuffer = nullptr;
struct AVD3D11VAContext* m_avD3D11Context = nullptr;
struct AVCodecContext* m_avCtx = nullptr;
int m_refs = 0;
unsigned int m_shared = 0;
unsigned int m_surface_alignment = 0;
Expand Down
8 changes: 0 additions & 8 deletions xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,6 @@ CDecoder::CDecoder(CProcessInfo& processInfo) :
m_vaapiConfig.context = 0;
m_vaapiConfig.configId = VA_INVALID_ID;
m_vaapiConfig.processInfo = &m_processInfo;
m_avctx = nullptr;
m_getBufferError = 0;
}

Expand Down Expand Up @@ -753,7 +752,6 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A
avctx->get_buffer2 = CDecoder::FFGetBuffer;
avctx->slice_flags = SLICE_FLAG_CODED_ORDER|SLICE_FLAG_ALLOW_FIELD;

m_avctx = mainctx;
return true;
}

Expand All @@ -774,12 +772,6 @@ void CDecoder::Close()

long CDecoder::Release()
{
// if ffmpeg holds any references, flush buffers
if (m_avctx && m_videoSurfaces.HasRefs())
{
avcodec_flush_buffers(m_avctx);
}

if (m_presentPicture)
{
m_presentPicture->Release();
Expand Down
1 change: 0 additions & 1 deletion xbmc/cores/VideoPlayer/DVDCodecs/Video/VAAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,6 @@ class CDecoder
bool m_vaapiConfigured;
CVaapiConfig m_vaapiConfig;
CVideoSurfaces m_videoSurfaces;
AVCodecContext* m_avctx;
int m_getBufferError;

COutput m_vaapiOutput;
Expand Down
19 changes: 0 additions & 19 deletions xbmc/cores/VideoPlayer/DVDCodecs/Video/VDPAU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,17 +471,6 @@ int CVideoSurfaces::Size()
return m_state.size();
}

bool CVideoSurfaces::HasRefs()
{
std::unique_lock<CCriticalSection> lock(m_section);
for (const auto &i : m_state)
{
if (i.second & SURFACE_USED_FOR_REFERENCE)
return true;
}
return false;
}

//-----------------------------------------------------------------------------
// CVDPAU
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -626,7 +615,6 @@ bool CDecoder::Open(AVCodecContext* avctx, AVCodecContext* mainctx, const enum A
avctx->hwaccel_context = &m_hwContext;

CServiceBroker::GetWinSystem()->Register(this);
m_avctx = mainctx;
return true;
}
}
Expand Down Expand Up @@ -656,12 +644,6 @@ void CDecoder::Close()

long CDecoder::Release()
{
// if ffmpeg holds any references, flush buffers
if (m_avctx && m_videoSurfaces.HasRefs())
{
avcodec_flush_buffers(m_avctx);
}

// check if we should do some pre-cleanup here
// a second decoder might need resources
if (m_vdpauConfigured == true)
Expand Down Expand Up @@ -793,7 +775,6 @@ CDVDVideoCodec::VCReturn CDecoder::Check(AVCodecContext* avctx)
{
std::unique_lock<CCriticalSection> lock(m_DecoderSection);

avcodec_flush_buffers(avctx);
FiniVDPAUOutput();
if (m_vdpauConfig.context)
m_vdpauConfig.context->Release();
Expand Down
2 changes: 0 additions & 2 deletions xbmc/cores/VideoPlayer/DVDCodecs/Video/VDPAU.h
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,6 @@ class CVideoSurfaces
VdpVideoSurface RemoveNext(bool skiprender = false);
void Reset();
int Size();
bool HasRefs();
protected:
std::map<VdpVideoSurface, int> m_state;
std::list<VdpVideoSurface> m_freeSurfaces;
Expand Down Expand Up @@ -645,7 +644,6 @@ class CDecoder
CVdpauConfig m_vdpauConfig;
CVideoSurfaces m_videoSurfaces;
AVVDPAUContext m_hwContext;
AVCodecContext* m_avctx = nullptr;

COutput m_vdpauOutput;
CVdpauBufferStats m_bufferStats;
Expand Down

0 comments on commit 5a6255c

Please sign in to comment.