Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/LAVFilters.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2013-04-12 19:56:00 +0400
committerHendrik Leppkes <h.leppkes@gmail.com>2013-04-12 19:56:00 +0400
commit3530164c08842043ef8058912eb0cbbe0289360b (patch)
treec6f19ce1723f92470d807c9783044926a4c8cfe5 /decoder
parent6fa1bc55f703fa30b0badf3fba0f1637df4e387e (diff)
Remove MT Filtering thread
While this method does slightly increase performance, it does this at the cost of smooth playback. So instead we accept a small performance penality in benchmarks (should not affect real-world situations), but guarantee much smoother playback instead.
Diffstat (limited to 'decoder')
-rw-r--r--decoder/LAVVideo/Filtering.cpp6
-rw-r--r--decoder/LAVVideo/LAVVideo.cpp144
-rw-r--r--decoder/LAVVideo/LAVVideo.h18
3 files changed, 8 insertions, 160 deletions
diff --git a/decoder/LAVVideo/Filtering.cpp b/decoder/LAVVideo/Filtering.cpp
index 4460e44b..0df76ec7 100644
--- a/decoder/LAVVideo/Filtering.cpp
+++ b/decoder/LAVVideo/Filtering.cpp
@@ -38,7 +38,7 @@ static void avfilter_free_lav_buffer(LAVFrame *pFrame)
av_frame_free((AVFrame **)&pFrame->priv_data);
}
-HRESULT CLAVVideo::Filter(LAVFrame *pFrame, HRESULT (CLAVVideo::*deliverFunc)(LAVFrame *pFrame))
+HRESULT CLAVVideo::Filter(LAVFrame *pFrame)
{
int ret = 0;
BOOL bFlush = pFrame->flags & LAV_FRAME_FLAG_FLUSH;
@@ -204,7 +204,7 @@ HRESULT CLAVVideo::Filter(LAVFrame *pFrame, HRESULT (CLAVVideo::*deliverFunc)(LA
outFrame->priv_data = av_frame_alloc();
av_frame_move_ref((AVFrame *)outFrame->priv_data, out_frame);
- hrDeliver = (*this.*deliverFunc)(outFrame);
+ hrDeliver = DeliverToRenderer(outFrame);
}
}
if (!refcountedFrame)
@@ -225,6 +225,6 @@ HRESULT CLAVVideo::Filter(LAVFrame *pFrame, HRESULT (CLAVVideo::*deliverFunc)(LA
} else {
m_filterPixFmt = LAVPixFmt_None;
deliver:
- return (*this.*deliverFunc)(pFrame);
+ return DeliverToRenderer(pFrame);
}
}
diff --git a/decoder/LAVVideo/LAVVideo.cpp b/decoder/LAVVideo/LAVVideo.cpp
index 73dbea0c..95ccde32 100644
--- a/decoder/LAVVideo/LAVVideo.cpp
+++ b/decoder/LAVVideo/LAVVideo.cpp
@@ -81,9 +81,7 @@ CLAVVideo::CLAVVideo(LPUNKNOWN pUnk, HRESULT* phr)
, m_LAVPinInfoValid(FALSE)
, m_bMadVR(-1)
, m_bOverlayMixer(-1)
- , m_bMTFiltering(FALSE)
, m_bFlushing(FALSE)
- , m_evFilterInput(TRUE)
, m_pSubtitleInput(NULL)
, m_SubtitleConsumer(NULL)
, m_pLastSequenceFrame(NULL)
@@ -129,7 +127,6 @@ CLAVVideo::~CLAVVideo()
m_pTrayIcon = NULL;
}
SAFE_DELETE(m_ControlThread);
- CloseMTFilterThread();
ReleaseLastSequenceFrame();
m_Decoder.Close();
@@ -578,20 +575,6 @@ BOOL CLAVVideo::IsInterlaced()
return (m_settings.SWDeintMode == SWDeintMode_None || m_filterPixFmt == LAVPixFmt_None) && m_Decoder.IsInterlaced() && !(m_settings.DeintMode == DeintMode_Disable);
}
-void CLAVVideo::CloseMTFilterThread()
-{
- if (m_bMTFiltering) {
- CAMThread::CallWorker(CMD_EXIT);
- CAMThread::Close();
-
- LAVFrame *pFrame = NULL;
- while(pFrame = m_MTFilterContext.inputQueue.Pop())
- ReleaseFrame(&pFrame);
- while(pFrame = m_MTFilterContext.outputQueue.Pop())
- ReleaseFrame(&pFrame);
- }
-}
-
static const LPWSTR stream_ar_blacklist[] = {
L".mkv", L".webm",
L".mp4", L".mov", L".m4v",
@@ -694,8 +677,6 @@ HRESULT CLAVVideo::CreateDecoder(const CMediaType *pmt)
SAFE_CO_FREE(pszExtension);
- CloseMTFilterThread();
-
hr = m_Decoder.CreateDecoder(pmt, codec);
if (FAILED(hr)) {
DbgLog((LOG_TRACE, 10, L"-> Decoder creation failed"));
@@ -707,13 +688,6 @@ HRESULT CLAVVideo::CreateDecoder(const CMediaType *pmt)
m_Decoder.GetPixelFormat(&pix, &bpp);
m_PixFmtConverter.SetInputFmt(pix, bpp);
- if (SUCCEEDED(hr) && m_Decoder.HasThreadSafeBuffers() == S_OK) {
- m_bMTFiltering = TRUE;
- CAMThread::Create();
- } else {
- m_bMTFiltering = FALSE;
- }
-
if (pix == LAVPixFmt_YUV420 || pix == LAVPixFmt_YUV422 || pix == LAVPixFmt_NV12)
m_filterPixFmt = pix;
@@ -743,7 +717,7 @@ HRESULT CLAVVideo::EndOfStream()
CAutoLock cAutoLock(&m_csReceive);
m_Decoder.EndOfStream();
- FilteringEndOfStream();
+ Filter(GetFlushFrame());
DbgLog((LOG_TRACE, 1, L"EndOfStream finished, decoder flushed"));
return __super::EndOfStream();
@@ -790,20 +764,6 @@ HRESULT CLAVVideo::PerformFlush()
{
CAutoLock cAutoLock(&m_csReceive);
- if (m_bMTFiltering) {
- // Block until the worker thread is in idle-state
- CAMThread::CallWorker(CMD_BEGIN_FLUSH);
-
- // Release all input/output frames
- LAVFrame *pFrame = NULL;
- while(pFrame = m_MTFilterContext.inputQueue.Pop())
- ReleaseFrame(&pFrame);
- while(pFrame = m_MTFilterContext.outputQueue.Pop())
- ReleaseFrame(&pFrame);
-
- CAMThread::CallWorker(CMD_END_FLUSH);
- }
-
ReleaseLastSequenceFrame();
m_Decoder.Flush();
@@ -842,7 +802,6 @@ HRESULT CLAVVideo::BreakConnect(PIN_DIRECTION dir)
{
DbgLog((LOG_TRACE, 10, L"::BreakConnect"));
if (dir == PINDIR_INPUT) {
- CloseMTFilterThread();
m_Decoder.Close();
if (m_pFilterGraph)
@@ -1257,90 +1216,6 @@ STDMETHODIMP_(LAVFrame*) CLAVVideo::GetFlushFrame()
return pFlushFrame;
}
-HRESULT CLAVVideo::QueueFrameForMTOutput(LAVFrame *pFrame)
-{
- m_MTFilterContext.outputQueue.Push(pFrame);
- return S_OK;
-}
-
-DWORD CLAVVideo::ThreadProc()
-{
- BOOL bFlushed = FALSE, bEOS = FALSE;
- DWORD cmd;
- LAVFrame *pFrame = NULL;
-
- DbgLog((LOG_TRACE, 10, L"Starting MT Filtering thread"));
-
- HANDLE hWaitEvents[2] = { GetRequestHandle(), m_evFilterInput };
- while(1) {
- if (!bEOS) {
- WaitForMultipleObjects(2, hWaitEvents, FALSE, INFINITE);
- }
- if (CheckRequest(&cmd)) {
- switch (cmd) {
- case CMD_EXIT:
- Reply(S_OK);
- return 0;
- case CMD_EOS:
- if (m_MTFilterContext.inputQueue.Empty()) {
- Filter(GetFlushFrame(), &CLAVVideo::QueueFrameForMTOutput);
- Reply(S_OK);
- bEOS = FALSE;
- } else {
- bEOS = TRUE;
- }
- break;
- case CMD_BEGIN_FLUSH:
- bFlushed = TRUE;
- // During a flush, all remaining data is removed by the caller, so assume there isn't any
- m_evFilterInput.Reset();
- Reply(S_OK);
- break;
- case CMD_END_FLUSH:
- bFlushed = FALSE;
- Reply(S_OK);
- break;
- default:
- ASSERT(0);
- }
- }
-
- if (bFlushed)
- continue;
-
- {
- CAutoLock inLock(&m_MTFilterContext.inputQueue);
- pFrame = m_MTFilterContext.inputQueue.Pop();
- if (!pFrame || m_MTFilterContext.inputQueue.Empty()) {
- m_evFilterInput.Reset();
- }
- }
- if (!pFrame)
- continue;
-
- Filter(pFrame, &CLAVVideo::QueueFrameForMTOutput);
- pFrame = NULL;
- }
-}
-
-STDMETHODIMP CLAVVideo::FilteringEndOfStream()
-{
- if (m_bMTFiltering) {
- // Tell Worker Thread to process all frames and then return
- // This call blocks until everything is done
- CAMThread::CallWorker(CMD_EOS);
-
- // Deliver all frames in the output queue
- LAVFrame *pFrame = NULL;
- while(pFrame = m_MTFilterContext.outputQueue.Pop())
- DeliverToRenderer(pFrame);
- } else {
- Filter(GetFlushFrame(), &CLAVVideo::DeliverToRenderer);
- }
-
- return S_OK;
-}
-
STDMETHODIMP CLAVVideo::Deliver(LAVFrame *pFrame)
{
// Out-of-sequence flush event to get all frames delivered,
@@ -1348,7 +1223,7 @@ STDMETHODIMP CLAVVideo::Deliver(LAVFrame *pFrame)
// so no need to flush the decoder here
if (pFrame->flags & LAV_FRAME_FLAG_FLUSH) {
DbgLog((LOG_TRACE, 10, L"Decoder triggered a flush..."));
- FilteringEndOfStream();
+ Filter(GetFlushFrame());
ReleaseFrame(&pFrame);
return S_FALSE;
@@ -1401,20 +1276,7 @@ STDMETHODIMP CLAVVideo::Deliver(LAVFrame *pFrame)
|| pFrame->flags & LAV_FRAME_FLAG_REDRAW) {
return DeliverToRenderer(pFrame);
} else {
- if (m_bMTFiltering) {
- // Feed new frames into queue
- while (m_MTFilterContext.inputQueue.Size() >= LAV_MT_FILTER_QUEUE_SIZE)
- Sleep(1);
-
- m_MTFilterContext.inputQueue.Push(pFrame);
- m_evFilterInput.Set();
-
- // Take old ones out
- while (pFrame = m_MTFilterContext.outputQueue.Pop()) {
- DeliverToRenderer(pFrame);
- }
- } else
- Filter(pFrame, &CLAVVideo::DeliverToRenderer);
+ Filter(pFrame);
}
return S_OK;
}
diff --git a/decoder/LAVVideo/LAVVideo.h b/decoder/LAVVideo/LAVVideo.h
index b5e1adca..362e243a 100644
--- a/decoder/LAVVideo/LAVVideo.h
+++ b/decoder/LAVVideo/LAVVideo.h
@@ -54,7 +54,7 @@ typedef struct {
} TimingCache;
[uuid("EE30215D-164F-4A92-A4EB-9D4C13390F9F")]
-class CLAVVideo : public CTransformFilter, public ISpecifyPropertyPages2, public ILAVVideoSettings, public ILAVVideoStatus, public ILAVVideoCallback, protected CAMThread
+class CLAVVideo : public CTransformFilter, public ISpecifyPropertyPages2, public ILAVVideoSettings, public ILAVVideoStatus, public ILAVVideoCallback
{
public:
CLAVVideo(LPUNKNOWN pUnk, HRESULT* phr);
@@ -174,9 +174,6 @@ public:
const static AMOVIESETUP_MEDIATYPE sudPinTypesOut[];
const static int sudPinTypesOutCount;
-protected:
- DWORD ThreadProc();
-
private:
HRESULT LoadDefaults();
HRESULT ReadSettings(HKEY rootKey);
@@ -196,11 +193,8 @@ private:
BOOL IsInterlaced();
- HRESULT Filter(LAVFrame *pFrame, HRESULT (CLAVVideo::*deliverFunc)(LAVFrame *pFrame));
+ HRESULT Filter(LAVFrame *pFrame);
HRESULT DeliverToRenderer(LAVFrame *pFrame);
- HRESULT QueueFrameForMTOutput(LAVFrame *pFrame);
- STDMETHODIMP FilteringEndOfStream();
- void CloseMTFilterThread();
HRESULT PerformFlush();
HRESULT ReleaseLastSequenceFrame();
@@ -260,14 +254,6 @@ private:
LAVFrame *m_pLastSequenceFrame;
- BOOL m_bMTFiltering;
- CAMEvent m_evFilterInput;
- enum {CMD_EXIT, CMD_EOS, CMD_BEGIN_FLUSH, CMD_END_FLUSH};
- struct {
- CSynchronizedQueue<LAVFrame *> inputQueue;
- CSynchronizedQueue<LAVFrame *> outputQueue;
- } m_MTFilterContext;
-
AM_SimpleRateChange m_DVDRate;
BOOL m_bRuntimeConfig;