mirror of
https://github.com/LibreELEC/LibreELEC.tv
synced 2025-09-24 19:46:01 +07:00
2743 lines
91 KiB
Diff
2743 lines
91 KiB
Diff
From d1d19f8d0a69f751b03a97ef0f546564527a7caa Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 18:53:25 +0100
|
|
Subject: [PATCH 01/18] [imx] @wolfgar Renamed CDVDVideoCodecIMXBuffer to
|
|
CDVDVideoCodecIMXVPUBuffer and added typedef for Renderer
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 34 +++++------
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 70 +++++++++++-----------
|
|
2 files changed, 53 insertions(+), 51 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index 34db863..17d2f15 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -264,7 +264,7 @@ bool CDVDVideoCodecIMX::VpuAllocFrameBuffers(void)
|
|
uvSize=Align(uvSize,nAlign);
|
|
}
|
|
|
|
- m_outputBuffers = new CDVDVideoCodecIMXBuffer*[m_vpuFrameBufferNum];
|
|
+ m_outputBuffers = new CDVDVideoCodecIMXVPUBuffer*[m_vpuFrameBufferNum];
|
|
|
|
for (int i=0 ; i < m_vpuFrameBufferNum; i++)
|
|
{
|
|
@@ -319,9 +319,9 @@ bool CDVDVideoCodecIMX::VpuAllocFrameBuffers(void)
|
|
m_vpuFrameBuffers[i].pbufVirtCb_tilebot=0;
|
|
|
|
#ifdef TRACE_FRAMES
|
|
- m_outputBuffers[i] = new CDVDVideoCodecIMXBuffer(i);
|
|
+ m_outputBuffers[i] = new CDVDVideoCodecIMXVPUBuffer(i);
|
|
#else
|
|
- m_outputBuffers[i] = new CDVDVideoCodecIMXBuffer();
|
|
+ m_outputBuffers[i] = new CDVDVideoCodecIMXVPUBuffer();
|
|
#endif
|
|
}
|
|
|
|
@@ -916,7 +916,7 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture)
|
|
int idx = VpuFindBuffer(m_frameInfo.pDisplayFrameBuf->pbufY);
|
|
if (idx != -1)
|
|
{
|
|
- CDVDVideoCodecIMXBuffer *buffer = m_outputBuffers[idx];
|
|
+ CDVDVideoCodecIMXVPUBuffer *buffer = m_outputBuffers[idx];
|
|
|
|
pDvdVideoPicture->pts = buffer->GetPts();
|
|
pDvdVideoPicture->dts = m_dts;
|
|
@@ -978,11 +978,11 @@ void CDVDVideoCodecIMX::Leave()
|
|
/*******************************************/
|
|
|
|
#ifdef TRACE_FRAMES
|
|
-CDVDVideoCodecIMXBuffer::CDVDVideoCodecIMXBuffer(int idx)
|
|
+CDVDVideoCodecIMXVPUBuffer::CDVDVideoCodecIMXVPUBuffer(int idx)
|
|
: m_refs(1)
|
|
, m_idx(idx)
|
|
#else
|
|
-CDVDVideoCodecIMXBuffer::CDVDVideoCodecIMXBuffer()
|
|
+CDVDVideoCodecIMXVPUBuffer::CDVDVideoCodecIMXVPUBuffer()
|
|
: m_refs(1)
|
|
#endif
|
|
, m_frameBuffer(NULL)
|
|
@@ -992,7 +992,7 @@ CDVDVideoCodecIMXBuffer::CDVDVideoCodecIMXBuffer()
|
|
{
|
|
}
|
|
|
|
-void CDVDVideoCodecIMXBuffer::Lock()
|
|
+void CDVDVideoCodecIMXVPUBuffer::Lock()
|
|
{
|
|
#ifdef TRACE_FRAMES
|
|
long count = AtomicIncrement(&m_refs);
|
|
@@ -1002,7 +1002,7 @@ void CDVDVideoCodecIMXBuffer::Lock()
|
|
#endif
|
|
}
|
|
|
|
-long CDVDVideoCodecIMXBuffer::Release()
|
|
+long CDVDVideoCodecIMXVPUBuffer::Release()
|
|
{
|
|
long count = AtomicDecrement(&m_refs);
|
|
#ifdef TRACE_FRAMES
|
|
@@ -1034,18 +1034,18 @@ long CDVDVideoCodecIMXBuffer::Release()
|
|
return count;
|
|
}
|
|
|
|
-bool CDVDVideoCodecIMXBuffer::IsValid()
|
|
+bool CDVDVideoCodecIMXVPUBuffer::IsValid()
|
|
{
|
|
return m_frameBuffer != NULL;
|
|
}
|
|
|
|
-bool CDVDVideoCodecIMXBuffer::Rendered() const
|
|
+bool CDVDVideoCodecIMXVPUBuffer::Rendered() const
|
|
{
|
|
return m_rendered;
|
|
}
|
|
|
|
-void CDVDVideoCodecIMXBuffer::Queue(VpuDecOutFrameInfo *frameInfo,
|
|
- CDVDVideoCodecIMXBuffer *previous)
|
|
+void CDVDVideoCodecIMXVPUBuffer::Queue(VpuDecOutFrameInfo *frameInfo,
|
|
+ CDVDVideoCodecIMXVPUBuffer *previous)
|
|
{
|
|
// No lock necessary because at this time there is definitely no
|
|
// thread still holding a reference
|
|
@@ -1061,7 +1061,7 @@ void CDVDVideoCodecIMXBuffer::Queue(VpuDecOutFrameInfo *frameInfo,
|
|
m_phyAddr = m_frameBuffer->pbufY;
|
|
}
|
|
|
|
-VpuDecRetCode CDVDVideoCodecIMXBuffer::ReleaseFramebuffer(VpuDecHandle *handle)
|
|
+VpuDecRetCode CDVDVideoCodecIMXVPUBuffer::ReleaseFramebuffer(VpuDecHandle *handle)
|
|
{
|
|
// Again no lock required because this is only issued after the last
|
|
// external reference was released
|
|
@@ -1084,22 +1084,22 @@ VpuDecRetCode CDVDVideoCodecIMXBuffer::ReleaseFramebuffer(VpuDecHandle *handle)
|
|
return ret;
|
|
}
|
|
|
|
-void CDVDVideoCodecIMXBuffer::SetPts(double pts)
|
|
+void CDVDVideoCodecIMXVPUBuffer::SetPts(double pts)
|
|
{
|
|
m_pts = pts;
|
|
}
|
|
|
|
-double CDVDVideoCodecIMXBuffer::GetPts(void) const
|
|
+double CDVDVideoCodecIMXVPUBuffer::GetPts(void) const
|
|
{
|
|
return m_pts;
|
|
}
|
|
|
|
-CDVDVideoCodecIMXBuffer *CDVDVideoCodecIMXBuffer::GetPreviousBuffer() const
|
|
+CDVDVideoCodecIMXVPUBuffer *CDVDVideoCodecIMXVPUBuffer::GetPreviousBuffer() const
|
|
{
|
|
return m_previousBuffer;
|
|
}
|
|
|
|
-CDVDVideoCodecIMXBuffer::~CDVDVideoCodecIMXBuffer()
|
|
+CDVDVideoCodecIMXVPUBuffer::~CDVDVideoCodecIMXVPUBuffer()
|
|
{
|
|
assert(m_refs == 0);
|
|
#ifdef TRACE_FRAMES
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index 6533683..eb88ecd 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -48,13 +48,13 @@ class CDecMemInfo
|
|
VpuMemDesc* phyMem;
|
|
};
|
|
|
|
-class CDVDVideoCodecIMXBuffer
|
|
+class CDVDVideoCodecIMXVPUBuffer
|
|
{
|
|
public:
|
|
#ifdef TRACE_FRAMES
|
|
- CDVDVideoCodecIMXBuffer(int idx);
|
|
+ CDVDVideoCodecIMXVPUBuffer(int idx);
|
|
#else
|
|
- CDVDVideoCodecIMXBuffer();
|
|
+ CDVDVideoCodecIMXVPUBuffer();
|
|
#endif
|
|
|
|
// reference counting
|
|
@@ -64,11 +64,11 @@ class CDVDVideoCodecIMXBuffer
|
|
|
|
bool Rendered() const;
|
|
void Queue(VpuDecOutFrameInfo *frameInfo,
|
|
- CDVDVideoCodecIMXBuffer *previous);
|
|
+ CDVDVideoCodecIMXVPUBuffer *previous);
|
|
VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle);
|
|
void SetPts(double pts);
|
|
double GetPts(void) const;
|
|
- CDVDVideoCodecIMXBuffer *GetPreviousBuffer() const;
|
|
+ CDVDVideoCodecIMXVPUBuffer *GetPreviousBuffer() const;
|
|
|
|
uint32_t m_iWidth;
|
|
uint32_t m_iHeight;
|
|
@@ -77,7 +77,7 @@ class CDVDVideoCodecIMXBuffer
|
|
|
|
private:
|
|
// private because we are reference counted
|
|
- virtual ~CDVDVideoCodecIMXBuffer();
|
|
+ virtual ~CDVDVideoCodecIMXVPUBuffer();
|
|
|
|
private:
|
|
#ifdef TRACE_FRAMES
|
|
@@ -87,13 +87,15 @@ class CDVDVideoCodecIMXBuffer
|
|
VpuFrameBuffer *m_frameBuffer;
|
|
bool m_rendered;
|
|
double m_pts;
|
|
- CDVDVideoCodecIMXBuffer *m_previousBuffer; // Holds a the reference counted
|
|
+ CDVDVideoCodecIMXVPUBuffer *m_previousBuffer; // Holds a the reference counted
|
|
// previous buffer
|
|
};
|
|
|
|
+typedef CDVDVideoCodecIMXVPUBuffer CDVDVideoCodecIMXBuffer;
|
|
+
|
|
class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
{
|
|
- friend class CDVDVideoCodecIMXBuffer;
|
|
+ friend class CDVDVideoCodecIMXVPUBuffer;
|
|
friend class CDVDVideoCodecIPUBuffer;
|
|
|
|
public:
|
|
@@ -122,30 +124,30 @@ class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
bool VpuAllocFrameBuffers();
|
|
int VpuFindBuffer(void *frameAddr);
|
|
|
|
- static const int m_extraVpuBuffers; // Number of additional buffers for VPU
|
|
- static const int m_maxVpuDecodeLoops; // Maximum iterations in VPU decoding loop
|
|
- static CCriticalSection m_codecBufferLock; // Lock to protect buffers handled
|
|
- // by both decoding and rendering threads
|
|
-
|
|
- CDVDStreamInfo m_hints; // Hints from demuxer at stream opening
|
|
- const char *m_pFormatName; // Current decoder format name
|
|
- VpuDecOpenParam m_decOpenParam; // Parameters required to call VPU_DecOpen
|
|
- CDecMemInfo m_decMemInfo; // VPU dedicated memory description
|
|
- VpuDecHandle m_vpuHandle; // Handle for VPU library calls
|
|
- VpuDecInitInfo m_initInfo; // Initial info returned from VPU at decoding start
|
|
- bool m_dropState; // Current drop state
|
|
- int m_vpuFrameBufferNum; // Total number of allocated frame buffers
|
|
- VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description
|
|
- CDVDVideoCodecIMXBuffer **m_outputBuffers; // Table of VPU output buffers
|
|
- CDVDVideoCodecIMXBuffer *m_lastBuffer; // Keep track of previous VPU output buffer (needed by deinterlacing motion engin)
|
|
- VpuMemDesc *m_extraMem; // Table of allocated extra Memory
|
|
- int m_frameCounter; // Decoded frames counter
|
|
- bool m_usePTS; // State whether pts out of decoding process should be used
|
|
- VpuDecOutFrameInfo m_frameInfo; // Store last VPU output frame info
|
|
- CBitstreamConverter *m_converter; // H264 annex B converter
|
|
- bool m_convert_bitstream; // State whether bitstream conversion is required
|
|
- int m_bytesToBeConsumed; // Remaining bytes in VPU
|
|
- double m_previousPts; // Enable to keep pts when needed
|
|
- bool m_frameReported; // State whether the frame consumed event will be reported by libfslvpu
|
|
- double m_dts; // Current dts
|
|
+ static const int m_extraVpuBuffers; // Number of additional buffers for VPU
|
|
+ static const int m_maxVpuDecodeLoops; // Maximum iterations in VPU decoding loop
|
|
+ static CCriticalSection m_codecBufferLock; // Lock to protect buffers handled
|
|
+ // by both decoding and rendering threads
|
|
+
|
|
+ CDVDStreamInfo m_hints; // Hints from demuxer at stream opening
|
|
+ const char *m_pFormatName; // Current decoder format name
|
|
+ VpuDecOpenParam m_decOpenParam; // Parameters required to call VPU_DecOpen
|
|
+ CDecMemInfo m_decMemInfo; // VPU dedicated memory description
|
|
+ VpuDecHandle m_vpuHandle; // Handle for VPU library calls
|
|
+ VpuDecInitInfo m_initInfo; // Initial info returned from VPU at decoding start
|
|
+ bool m_dropState; // Current drop state
|
|
+ int m_vpuFrameBufferNum; // Total number of allocated frame buffers
|
|
+ VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description
|
|
+ CDVDVideoCodecIMXVPUBuffer **m_outputBuffers; // Table of VPU output buffers
|
|
+ CDVDVideoCodecIMXVPUBuffer *m_lastBuffer; // Keep track of previous VPU output buffer (needed by deinterlacing motion engin)
|
|
+ VpuMemDesc *m_extraMem; // Table of allocated extra Memory
|
|
+ int m_frameCounter; // Decoded frames counter
|
|
+ bool m_usePTS; // State whether pts out of decoding process should be used
|
|
+ VpuDecOutFrameInfo m_frameInfo; // Store last VPU output frame info
|
|
+ CBitstreamConverter *m_converter; // H264 annex B converter
|
|
+ bool m_convert_bitstream; // State whether bitstream conversion is required
|
|
+ int m_bytesToBeConsumed; // Remaining bytes in VPU
|
|
+ double m_previousPts; // Enable to keep pts when needed
|
|
+ bool m_frameReported; // State whether the frame consumed event will be reported by libfslvpu
|
|
+ double m_dts; // Current dts
|
|
};
|
|
|
|
From f62a4dab8e084dffa74fddfbc5cdc16a2b49f721 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 18:58:33 +0100
|
|
Subject: [PATCH 02/18] [imx] @wolfgar Indentation
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 34 +++++++++++-----------
|
|
1 file changed, 17 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index eb88ecd..88b555c 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -58,16 +58,16 @@ class CDVDVideoCodecIMXVPUBuffer
|
|
#endif
|
|
|
|
// reference counting
|
|
- virtual void Lock();
|
|
- virtual long Release();
|
|
- virtual bool IsValid();
|
|
-
|
|
- bool Rendered() const;
|
|
- void Queue(VpuDecOutFrameInfo *frameInfo,
|
|
- CDVDVideoCodecIMXVPUBuffer *previous);
|
|
- VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle);
|
|
- void SetPts(double pts);
|
|
- double GetPts(void) const;
|
|
+ virtual void Lock();
|
|
+ virtual long Release();
|
|
+ virtual bool IsValid();
|
|
+
|
|
+ bool Rendered() const;
|
|
+ void Queue(VpuDecOutFrameInfo *frameInfo,
|
|
+ CDVDVideoCodecIMXVPUBuffer *previous);
|
|
+ VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle);
|
|
+ void SetPts(double pts);
|
|
+ double GetPts(void) const;
|
|
CDVDVideoCodecIMXVPUBuffer *GetPreviousBuffer() const;
|
|
|
|
uint32_t m_iWidth;
|
|
@@ -77,18 +77,18 @@ class CDVDVideoCodecIMXVPUBuffer
|
|
|
|
private:
|
|
// private because we are reference counted
|
|
- virtual ~CDVDVideoCodecIMXVPUBuffer();
|
|
+ virtual ~CDVDVideoCodecIMXVPUBuffer();
|
|
|
|
private:
|
|
#ifdef TRACE_FRAMES
|
|
- int m_idx;
|
|
+ int m_idx;
|
|
#endif
|
|
- long m_refs;
|
|
- VpuFrameBuffer *m_frameBuffer;
|
|
- bool m_rendered;
|
|
- double m_pts;
|
|
+ long m_refs;
|
|
+ VpuFrameBuffer *m_frameBuffer;
|
|
+ bool m_rendered;
|
|
+ double m_pts;
|
|
CDVDVideoCodecIMXVPUBuffer *m_previousBuffer; // Holds a the reference counted
|
|
- // previous buffer
|
|
+ // previous buffer
|
|
};
|
|
|
|
typedef CDVDVideoCodecIMXVPUBuffer CDVDVideoCodecIMXBuffer;
|
|
|
|
From 7190879c7e4038e26edec13d50f026fed1d95728 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 19:04:49 +0100
|
|
Subject: [PATCH 03/18] [imx] @wolfgar Added base class CDVDVideoCodecIMXBuffer
|
|
that CDVDVideoCodecIMXVPUBuffer derives from
|
|
|
|
---
|
|
xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 8 ++--
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 40 ++++++++++------
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 53 ++++++++++++++++------
|
|
3 files changed, 67 insertions(+), 34 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
index 81fe19b..b0229ef 100644
|
|
--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
@@ -2733,16 +2733,16 @@ void CLinuxRendererGLES::UploadIMXMAPTexture(int index)
|
|
glBindTexture(m_textureTarget, plane.id);
|
|
|
|
GLuint physical = ~0U;
|
|
- GLvoid *virt = (GLvoid*)IMXBuffer->m_VirtAddr;
|
|
- glTexDirectVIVMap(m_textureTarget, IMXBuffer->m_iWidth, IMXBuffer->m_iHeight, GL_VIV_NV12,
|
|
+ GLvoid *virt = (GLvoid*)IMXBuffer->pVirtAddr;
|
|
+ glTexDirectVIVMap(m_textureTarget, IMXBuffer->iWidth, IMXBuffer->iHeight, GL_VIV_NV12,
|
|
(GLvoid **)&virt, &physical);
|
|
glTexDirectInvalidateVIV(m_textureTarget);
|
|
|
|
glBindTexture(m_textureTarget, 0);
|
|
|
|
plane.flipindex = m_buffers[index].flipindex;
|
|
- plane.texwidth = IMXBuffer->m_iWidth;
|
|
- plane.texheight = IMXBuffer->m_iHeight;
|
|
+ plane.texwidth = IMXBuffer->iWidth;
|
|
+ plane.texheight = IMXBuffer->iHeight;
|
|
|
|
CalculateTextureSourceRects(index, 1);
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index 17d2f15..9782a2c 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -976,18 +976,38 @@ void CDVDVideoCodecIMX::Leave()
|
|
}
|
|
|
|
/*******************************************/
|
|
+#ifdef TRACE_FRAMES
|
|
+CDVDVideoCodecIMXBuffer::CDVDVideoCodecIMXBuffer(int idx)
|
|
+ : m_idx(idx)
|
|
+ , m_refs(1)
|
|
+#else
|
|
+CDVDVideoCodecIMXBuffer::CDVDVideoCodecIMXBuffer()
|
|
+ : m_refs(1)
|
|
+#endif
|
|
+ , m_pts(DVD_NOPTS_VALUE)
|
|
+ , m_dts(DVD_NOPTS_VALUE)
|
|
+{
|
|
+}
|
|
+
|
|
+void CDVDVideoCodecIMXBuffer::SetPts(double pts)
|
|
+{
|
|
+ m_pts = pts;
|
|
+}
|
|
+
|
|
+void CDVDVideoCodecIMXBuffer::SetDts(double dts)
|
|
+{
|
|
+ m_dts = dts;
|
|
+}
|
|
|
|
#ifdef TRACE_FRAMES
|
|
CDVDVideoCodecIMXVPUBuffer::CDVDVideoCodecIMXVPUBuffer(int idx)
|
|
- : m_refs(1)
|
|
- , m_idx(idx)
|
|
+ : CDVDVideoCodecIMXBuffer(idx)
|
|
#else
|
|
CDVDVideoCodecIMXVPUBuffer::CDVDVideoCodecIMXVPUBuffer()
|
|
- : m_refs(1)
|
|
+ : CDVDVideoCodecIMXBuffer()
|
|
#endif
|
|
, m_frameBuffer(NULL)
|
|
, m_rendered(false)
|
|
- , m_pts(DVD_NOPTS_VALUE)
|
|
, m_previousBuffer(NULL)
|
|
{
|
|
}
|
|
@@ -1078,22 +1098,12 @@ VpuDecRetCode CDVDVideoCodecIMXVPUBuffer::ReleaseFramebuffer(VpuDecHandle *handl
|
|
#endif
|
|
m_rendered = false;
|
|
m_frameBuffer = NULL;
|
|
- m_pts = DVD_NOPTS_VALUE;
|
|
+ SetPts(DVD_NOPTS_VALUE);
|
|
SAFE_RELEASE(m_previousBuffer);
|
|
|
|
return ret;
|
|
}
|
|
|
|
-void CDVDVideoCodecIMXVPUBuffer::SetPts(double pts)
|
|
-{
|
|
- m_pts = pts;
|
|
-}
|
|
-
|
|
-double CDVDVideoCodecIMXVPUBuffer::GetPts(void) const
|
|
-{
|
|
- return m_pts;
|
|
-}
|
|
-
|
|
CDVDVideoCodecIMXVPUBuffer *CDVDVideoCodecIMXVPUBuffer::GetPreviousBuffer() const
|
|
{
|
|
return m_previousBuffer;
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index 88b555c..c4452ca 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -48,7 +48,44 @@ class CDecMemInfo
|
|
VpuMemDesc* phyMem;
|
|
};
|
|
|
|
-class CDVDVideoCodecIMXVPUBuffer
|
|
+// Base class of IMXVPU buffer
|
|
+class CDVDVideoCodecIMXBuffer {
|
|
+public:
|
|
+#ifdef TRACE_FRAMES
|
|
+ CDVDVideoCodecIMXBuffer(int idx);
|
|
+#else
|
|
+ CDVDVideoCodecIMXBuffer();
|
|
+#endif
|
|
+
|
|
+ // reference counting
|
|
+ virtual void Lock() = 0;
|
|
+ virtual long Release() = 0;
|
|
+ virtual bool IsValid() = 0;
|
|
+
|
|
+ void SetPts(double pts);
|
|
+ double GetPts(void) const { return m_pts; }
|
|
+
|
|
+ void SetDts(double dts);
|
|
+ double GetDts(void) const { return m_dts; }
|
|
+
|
|
+ uint32_t iWidth;
|
|
+ uint32_t iHeight;
|
|
+ uint8_t *pPhysAddr;
|
|
+ uint8_t *pVirtAddr;
|
|
+ uint8_t iFormat;
|
|
+
|
|
+protected:
|
|
+#ifdef TRACE_FRAMES
|
|
+ int m_idx;
|
|
+#endif
|
|
+ long m_refs;
|
|
+
|
|
+private:
|
|
+ double m_pts;
|
|
+ double m_dts;
|
|
+};
|
|
+
|
|
+class CDVDVideoCodecIMXVPUBuffer : public CDVDVideoCodecIMXBuffer
|
|
{
|
|
public:
|
|
#ifdef TRACE_FRAMES
|
|
@@ -66,33 +103,19 @@ class CDVDVideoCodecIMXVPUBuffer
|
|
void Queue(VpuDecOutFrameInfo *frameInfo,
|
|
CDVDVideoCodecIMXVPUBuffer *previous);
|
|
VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle);
|
|
- void SetPts(double pts);
|
|
- double GetPts(void) const;
|
|
CDVDVideoCodecIMXVPUBuffer *GetPreviousBuffer() const;
|
|
|
|
- uint32_t m_iWidth;
|
|
- uint32_t m_iHeight;
|
|
- uint8_t *m_phyAddr;
|
|
- uint8_t *m_VirtAddr;
|
|
-
|
|
private:
|
|
// private because we are reference counted
|
|
virtual ~CDVDVideoCodecIMXVPUBuffer();
|
|
|
|
private:
|
|
-#ifdef TRACE_FRAMES
|
|
- int m_idx;
|
|
-#endif
|
|
- long m_refs;
|
|
VpuFrameBuffer *m_frameBuffer;
|
|
bool m_rendered;
|
|
- double m_pts;
|
|
CDVDVideoCodecIMXVPUBuffer *m_previousBuffer; // Holds a the reference counted
|
|
// previous buffer
|
|
};
|
|
|
|
-typedef CDVDVideoCodecIMXVPUBuffer CDVDVideoCodecIMXBuffer;
|
|
-
|
|
class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
{
|
|
friend class CDVDVideoCodecIMXVPUBuffer;
|
|
|
|
From fd94f1fcad232f4b8df20616ef2b4fe4fe84cd2c Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 19:15:04 +0100
|
|
Subject: [PATCH 04/18] [imx] @wolfgar Added CDVDVideoCodecIMXIPUBuffer class
|
|
that wraps IPU allocated picture buffers
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 236 +++++++++++++++++++++
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 44 +++-
|
|
2 files changed, 279 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index 9782a2c..e812b60 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -1116,3 +1116,239 @@ CDVDVideoCodecIMXVPUBuffer::~CDVDVideoCodecIMXVPUBuffer()
|
|
CLog::Log(LOGDEBUG, "~ %02d (VPU)\n", m_idx);
|
|
#endif
|
|
}
|
|
+
|
|
+#ifdef TRACE_FRAMES
|
|
+CDVDVideoCodecIMXIPUBuffer::CDVDVideoCodecIMXIPUBuffer(int idx)
|
|
+ : CDVDVideoCodecIMXBuffer(idx)
|
|
+#else
|
|
+CDVDVideoCodecIMXIPUBuffer::CDVDVideoCodecIMXIPUBuffer()
|
|
+ : CDVDVideoCodecIMXBuffer()
|
|
+#endif
|
|
+ , m_bFree(true)
|
|
+ , m_pPhyAddr(0)
|
|
+ , m_pVirtAddr(NULL)
|
|
+ , m_nSize(0)
|
|
+{
|
|
+}
|
|
+
|
|
+CDVDVideoCodecIMXIPUBuffer::~CDVDVideoCodecIMXIPUBuffer()
|
|
+{
|
|
+ assert(m_refs == 0);
|
|
+#ifdef TRACE_FRAMES
|
|
+ CLog::Log(LOGDEBUG, "~ %02d (IPU)\n", m_idx);
|
|
+#endif
|
|
+}
|
|
+
|
|
+void CDVDVideoCodecIMXIPUBuffer::Lock()
|
|
+{
|
|
+#ifdef TRACE_FRAMES
|
|
+ long count = AtomicIncrement(&m_refs);
|
|
+ CLog::Log(LOGDEBUG, "R+ %02d - ref : %d (IPU)\n", m_idx, count);
|
|
+#else
|
|
+ AtomicIncrement(&m_refs);
|
|
+#endif
|
|
+
|
|
+}
|
|
+
|
|
+long CDVDVideoCodecIMXIPUBuffer::Release()
|
|
+{
|
|
+ long count = AtomicDecrement(&m_refs);
|
|
+#ifdef TRACE_FRAMES
|
|
+ CLog::Log(LOGDEBUG, "R- %02d - ref : %d (IPU)\n", m_idx, count);
|
|
+#endif
|
|
+ if (count == 1)
|
|
+ {
|
|
+ ReleaseFrameBuffer();
|
|
+ }
|
|
+ else if (count == 0)
|
|
+ {
|
|
+ delete this;
|
|
+ }
|
|
+
|
|
+ return count;
|
|
+}
|
|
+
|
|
+bool CDVDVideoCodecIMXIPUBuffer::IsValid()
|
|
+{
|
|
+ return /*m_source && m_source->IsValid() && */m_pPhyAddr;
|
|
+}
|
|
+
|
|
+bool CDVDVideoCodecIMXIPUBuffer::Process(int fd, CDVDVideoCodecIMXVPUBuffer *buffer,
|
|
+ VpuFieldType fieldType, int fieldFmt,
|
|
+ bool lowMotion)
|
|
+{
|
|
+ CDVDVideoCodecIMXVPUBuffer *previousBuffer;
|
|
+ struct ipu_task task;
|
|
+ memset(&task, 0, sizeof(task));
|
|
+ task.priority = IPU_TASK_PRIORITY_HIGH;
|
|
+
|
|
+ if (lowMotion)
|
|
+ previousBuffer = buffer->GetPreviousBuffer();
|
|
+ else
|
|
+ previousBuffer = NULL;
|
|
+
|
|
+ m_bFree = true;
|
|
+ iWidth = buffer->iWidth;
|
|
+ iHeight = buffer->iHeight;
|
|
+
|
|
+ // Input is the VPU decoded frame
|
|
+ task.input.width = iWidth;
|
|
+ task.input.height = iHeight;
|
|
+#ifdef IMX_INPUT_FORMAT_I420
|
|
+ task.input.format = IPU_PIX_FMT_YUV420P;
|
|
+#else
|
|
+ task.input.format = IPU_PIX_FMT_NV12;
|
|
+#endif
|
|
+
|
|
+ // Output is our IPU buffer
|
|
+ task.output.width = iWidth;
|
|
+ task.output.height = iHeight;
|
|
+#ifdef IMX_OUTPUT_FORMAT_I420
|
|
+ task.output.format = IPU_PIX_FMT_YUV420P;
|
|
+ format = 0;
|
|
+#else
|
|
+ task.output.format = IPU_PIX_FMT_NV12;
|
|
+ iFormat = 1;
|
|
+#endif
|
|
+ task.output.paddr = (int)pPhysAddr;
|
|
+
|
|
+ // Fill current and next buffer address
|
|
+ if (lowMotion && previousBuffer && previousBuffer->IsValid())
|
|
+ {
|
|
+ task.input.paddr = (int)previousBuffer->pPhysAddr;
|
|
+ task.input.paddr_n = (int)buffer->pPhysAddr;
|
|
+ task.input.deinterlace.motion = LOW_MOTION;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ task.input.paddr = (int)buffer->pPhysAddr;
|
|
+ task.input.deinterlace.motion = HIGH_MOTION;
|
|
+ }
|
|
+
|
|
+ task.input.deinterlace.enable = 1;
|
|
+ task.input.deinterlace.field_fmt = fieldFmt;
|
|
+
|
|
+ switch (fieldType)
|
|
+ {
|
|
+ case VPU_FIELD_TOP:
|
|
+ case VPU_FIELD_TB:
|
|
+ task.input.deinterlace.field_fmt |= IPU_DEINTERLACE_FIELD_TOP;
|
|
+ break;
|
|
+ case VPU_FIELD_BOTTOM:
|
|
+ case VPU_FIELD_BT:
|
|
+ task.input.deinterlace.field_fmt |= IPU_DEINTERLACE_FIELD_BOTTOM;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+#ifdef IMX_PROFILE
|
|
+ unsigned int time = XbmcThreads::SystemClockMillis();
|
|
+#endif
|
|
+ int ret = ioctl(fd, IPU_QUEUE_TASK, &task);
|
|
+#ifdef IMX_PROFILE
|
|
+ CLog::Log(LOGDEBUG, "DEINT: tm:%d\n", XbmcThreads::SystemClockMillis() - time);
|
|
+#endif
|
|
+ if (ret < 0)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "IPU task failed: %s\n", strerror(errno));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ m_bFree = false;
|
|
+ buffer->Lock();
|
|
+
|
|
+ // Copy PTS
|
|
+ SetPts(buffer->GetPts());
|
|
+ SetDts(buffer->GetDts());
|
|
+
|
|
+ buffer->Release();
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+void CDVDVideoCodecIMXIPUBuffer::ReleaseFrameBuffer()
|
|
+{
|
|
+#ifdef TRACE_FRAMES
|
|
+ CLog::Log(LOGDEBUG, "- %02d (IPU)\n", m_idx);
|
|
+#endif
|
|
+ m_bFree = true;
|
|
+}
|
|
+
|
|
+bool CDVDVideoCodecIMXIPUBuffer::Allocate(int fd, int width, int height, int nAlign)
|
|
+{
|
|
+ m_iWidth = Align(width,FRAME_ALIGN);
|
|
+ m_iHeight = Align(height,(2*FRAME_ALIGN));
|
|
+ // I420 == 12 bpp
|
|
+ m_nSize = m_iWidth*m_iHeight*12/8;
|
|
+ m_pPhyAddr = m_nSize;
|
|
+
|
|
+ pPhysAddr = pVirtAddr = NULL;
|
|
+
|
|
+ int r = ioctl(fd, IPU_ALLOC, &m_pPhyAddr);
|
|
+ if (r < 0)
|
|
+ {
|
|
+ m_pPhyAddr = 0;
|
|
+ CLog::Log(LOGERROR, "ioctl IPU_ALLOC fail: disable deinterlacing: %s\n", strerror(errno));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ CLog::Log(LOGNOTICE, "IPU: alloc %d bytes for frame of %dx%d at 0x%x\n",
|
|
+ m_nSize, m_iWidth, m_iHeight, m_pPhyAddr);
|
|
+
|
|
+ m_pVirtAddr = (uint8_t*)mmap(0, m_nSize, PROT_READ | PROT_WRITE, MAP_SHARED,
|
|
+ fd, m_pPhyAddr);
|
|
+ if (!m_pVirtAddr)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "IPU mmap failed: disable deinterlacing: %s\n", strerror(errno));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (nAlign>1)
|
|
+ {
|
|
+ pPhysAddr = (uint8_t*)Align(m_pPhyAddr, nAlign);
|
|
+ pVirtAddr = (uint8_t*)Align(m_pVirtAddr, nAlign);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ pPhysAddr = (uint8_t*)m_pPhyAddr;
|
|
+ pVirtAddr = (uint8_t*)m_pVirtAddr;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool CDVDVideoCodecIMXIPUBuffer::Free(int fd)
|
|
+{
|
|
+ bool ret = true;
|
|
+
|
|
+ // Unmap virtual memory
|
|
+ if (m_pVirtAddr != NULL)
|
|
+ {
|
|
+ if(munmap(m_pVirtAddr, m_nSize))
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "IPU unmap failed: %s\n", strerror(errno));
|
|
+ ret = false;
|
|
+ }
|
|
+
|
|
+ m_pVirtAddr = NULL;
|
|
+ }
|
|
+
|
|
+ // Free IPU memory
|
|
+ if (m_pPhyAddr)
|
|
+ {
|
|
+ if (ioctl(fd, IPU_FREE, &m_pPhyAddr))
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "IPU free buffer 0x%x failed: %s\n",
|
|
+ m_pPhyAddr, strerror(errno));
|
|
+ ret = false;
|
|
+ }
|
|
+
|
|
+ m_pPhyAddr = 0;
|
|
+ }
|
|
+
|
|
+ pPhysAddr = pVirtAddr = NULL;
|
|
+ m_bFree = true;
|
|
+
|
|
+ return ret;
|
|
+}
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index c4452ca..86edaa2 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -48,7 +48,8 @@ class CDecMemInfo
|
|
VpuMemDesc* phyMem;
|
|
};
|
|
|
|
-// Base class of IMXVPU buffer
|
|
+
|
|
+// Base class of IMXVPU and IMXIPU buffer
|
|
class CDVDVideoCodecIMXBuffer {
|
|
public:
|
|
#ifdef TRACE_FRAMES
|
|
@@ -85,6 +86,7 @@ class CDVDVideoCodecIMXBuffer {
|
|
double m_dts;
|
|
};
|
|
|
|
+
|
|
class CDVDVideoCodecIMXVPUBuffer : public CDVDVideoCodecIMXBuffer
|
|
{
|
|
public:
|
|
@@ -116,6 +118,46 @@ class CDVDVideoCodecIMXVPUBuffer : public CDVDVideoCodecIMXBuffer
|
|
// previous buffer
|
|
};
|
|
|
|
+
|
|
+// Shared buffer that holds an IPU allocated memory block and serves as target
|
|
+// for IPU operations such as deinterlacing, rotation or color conversion.
|
|
+class CDVDVideoCodecIMXIPUBuffer : public CDVDVideoCodecIMXBuffer
|
|
+{
|
|
+public:
|
|
+#ifdef TRACE_FRAMES
|
|
+ CDVDVideoCodecIMXIPUBuffer(int idx);
|
|
+#else
|
|
+ CDVDVideoCodecIMXIPUBuffer();
|
|
+#endif
|
|
+
|
|
+ // reference counting
|
|
+ virtual void Lock();
|
|
+ virtual long Release();
|
|
+ virtual bool IsValid();
|
|
+
|
|
+ // Returns whether the buffer is ready to be used
|
|
+ bool Rendered() const { return m_bFree; }
|
|
+ bool Process(int fd, CDVDVideoCodecIMXVPUBuffer *buffer,
|
|
+ VpuFieldType fieldType, int fieldFmt,
|
|
+ bool lowMotion);
|
|
+ void ReleaseFrameBuffer();
|
|
+
|
|
+ bool Allocate(int fd, int width, int height, int nAlign);
|
|
+ bool Free(int fd);
|
|
+
|
|
+private:
|
|
+ virtual ~CDVDVideoCodecIMXIPUBuffer();
|
|
+
|
|
+private:
|
|
+ bool m_bFree;
|
|
+ int m_pPhyAddr;
|
|
+ uint8_t *m_pVirtAddr;
|
|
+ uint32_t m_iWidth;
|
|
+ uint32_t m_iHeight;
|
|
+ int m_nSize;
|
|
+};
|
|
+
|
|
+
|
|
class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
{
|
|
friend class CDVDVideoCodecIMXVPUBuffer;
|
|
|
|
From 8c4eb96c7c82b66bad008dd521429f8cc1039d2d Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 19:16:49 +0100
|
|
Subject: [PATCH 05/18] [imx] @wolfgar Added CDVDVideoCodecIMXIPUBuffers that
|
|
manages a pool of IPU buffers and implements deinterlacing of VPU buffers to
|
|
IPU buffers
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 134 +++++++++++++++++++++
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 37 ++++++
|
|
2 files changed, 171 insertions(+)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index e812b60..5dfa4f8 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -1352,3 +1352,137 @@ bool CDVDVideoCodecIMXIPUBuffer::Free(int fd)
|
|
|
|
return ret;
|
|
}
|
|
+
|
|
+CDVDVideoCodecIMXIPUBuffers::CDVDVideoCodecIMXIPUBuffers()
|
|
+ : m_ipuHandle(0)
|
|
+ , m_bufferNum(0)
|
|
+ , m_buffers(NULL)
|
|
+ , m_currentFieldFmt(0)
|
|
+{
|
|
+}
|
|
+
|
|
+CDVDVideoCodecIMXIPUBuffers::~CDVDVideoCodecIMXIPUBuffers()
|
|
+{
|
|
+ Close();
|
|
+}
|
|
+
|
|
+bool CDVDVideoCodecIMXIPUBuffers::Init(int width, int height, int numBuffers, int nAlign)
|
|
+{
|
|
+ if (numBuffers<=0)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "IPU Init: invalid number of buffers: %d\n", numBuffers);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ m_ipuHandle = open("/dev/mxc_ipu", O_RDWR, 0);
|
|
+ if (m_ipuHandle<=0)
|
|
+ {
|
|
+ CLog::Log(LOGWARNING, "Failed to initialize IPU: deinterlacing disabled: %s\n",
|
|
+ strerror(errno));
|
|
+ m_ipuHandle = 0;
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ m_bufferNum = numBuffers;
|
|
+ m_buffers = new CDVDVideoCodecIMXIPUBuffer*[m_bufferNum];
|
|
+ m_currentFieldFmt = 0;
|
|
+
|
|
+ for (int i=0; i < m_bufferNum; i++)
|
|
+ {
|
|
+#ifdef TRACE_FRAMES
|
|
+ m_buffers[i] = new CDVDVideoCodecIMXIPUBuffer(i);
|
|
+#else
|
|
+ m_buffers[i] = new CDVDVideoCodecIMXIPUBuffer;
|
|
+#endif
|
|
+ if (!m_buffers[i]->Allocate(m_ipuHandle, width, height, nAlign))
|
|
+ {
|
|
+ Close();
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool CDVDVideoCodecIMXIPUBuffers::Reset()
|
|
+{
|
|
+ for (int i=0; i < m_bufferNum; i++)
|
|
+ m_buffers[i]->ReleaseFrameBuffer();
|
|
+ m_currentFieldFmt = 0;
|
|
+}
|
|
+
|
|
+bool CDVDVideoCodecIMXIPUBuffers::Close()
|
|
+{
|
|
+ bool ret = true;
|
|
+
|
|
+ if (m_ipuHandle)
|
|
+ {
|
|
+ for (int i=0; i < m_bufferNum; i++)
|
|
+ {
|
|
+ if (m_buffers[i] == NULL ) continue;
|
|
+ if (!m_buffers[i]->Free(m_ipuHandle))
|
|
+ ret = false;
|
|
+ }
|
|
+
|
|
+ // Close IPU device
|
|
+ if (close(m_ipuHandle))
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "IPU failed to close interface: %s\n", strerror(errno));
|
|
+ ret = false;
|
|
+ }
|
|
+
|
|
+ m_ipuHandle = 0;
|
|
+ }
|
|
+
|
|
+ if (m_buffers)
|
|
+ {
|
|
+ for (int i=0; i < m_bufferNum; i++)
|
|
+ SAFE_RELEASE(m_buffers[i]);
|
|
+
|
|
+ delete m_buffers;
|
|
+ m_buffers = NULL;
|
|
+ }
|
|
+
|
|
+ m_bufferNum = 0;
|
|
+ return true;
|
|
+}
|
|
+
|
|
+CDVDVideoCodecIMXIPUBuffer *
|
|
+CDVDVideoCodecIMXIPUBuffers::Process(CDVDVideoCodecIMXBuffer *sourceBuffer,
|
|
+ VpuFieldType fieldType, bool lowMotion)
|
|
+{
|
|
+ CDVDVideoCodecIMXIPUBuffer *target = NULL;
|
|
+ bool ret = true;
|
|
+
|
|
+ if (!m_bufferNum)
|
|
+ return NULL;
|
|
+
|
|
+ for (int i=0; i < m_bufferNum; i++ )
|
|
+ {
|
|
+ if (!m_buffers[i]->Rendered()) continue;
|
|
+
|
|
+ // IPU process:
|
|
+ // SRC: Current VPU physical buffer address + last VPU buffer address
|
|
+ // DST: IPU buffer[i]
|
|
+ ret = m_buffers[i]->Process(m_ipuHandle, (CDVDVideoCodecIMXVPUBuffer*)sourceBuffer,
|
|
+ fieldType, m_currentFieldFmt,
|
|
+ lowMotion);
|
|
+ if (ret)
|
|
+ {
|
|
+#ifdef TRACE_FRAMES
|
|
+ CLog::Log(LOGDEBUG, "+ %02d (IPU)\n", i);
|
|
+#endif
|
|
+ target = m_buffers[i];
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ // Buffers are there but there is no free one, this is an error!
|
|
+ // Rendering will continue with unprocessed frames ...
|
|
+ if (ret && target==NULL)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "Deinterlacing: did not find free buffer, forward unprocessed frame\n");
|
|
+ }
|
|
+
|
|
+ return target;
|
|
+}
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index 86edaa2..bb2f7d1 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -26,6 +26,14 @@
|
|
#include "utils/BitstreamConverter.h"
|
|
|
|
|
|
+// The decoding format of the VPU buffer. Comment this to decode
|
|
+// as NV12. The VPU works faster with I420.
|
|
+#define IMX_INPUT_FORMAT_I420
|
|
+
|
|
+// The deinterlacer output and render format. Uncomment to use I420.
|
|
+// The IPU works faster when outputting to NV12.
|
|
+//#define IMX_OUTPUT_FORMAT_I420
|
|
+
|
|
//#define IMX_PROFILE
|
|
//#define TRACE_FRAMES
|
|
|
|
@@ -158,6 +166,35 @@ class CDVDVideoCodecIMXIPUBuffer : public CDVDVideoCodecIMXBuffer
|
|
};
|
|
|
|
|
|
+// Collection class that manages a pool of IPU buffers that are used for
|
|
+// deinterlacing. In future they can also serve rotation or color conversion
|
|
+// buffers.
|
|
+class CDVDVideoCodecIMXIPUBuffers
|
|
+{
|
|
+ public:
|
|
+ CDVDVideoCodecIMXIPUBuffers();
|
|
+ ~CDVDVideoCodecIMXIPUBuffers();
|
|
+
|
|
+ bool Init(int width, int height, int numBuffers, int nAlign);
|
|
+ // Sets the mode to be used if deinterlacing is set to AUTO
|
|
+ void SetAutoMode(bool mode) { m_autoMode = mode; }
|
|
+ bool AutoMode() const { return m_autoMode; }
|
|
+ bool Reset();
|
|
+ bool Close();
|
|
+
|
|
+ CDVDVideoCodecIMXIPUBuffer *
|
|
+ Process(CDVDVideoCodecIMXBuffer *sourceBuffer,
|
|
+ VpuFieldType fieldType, bool lowMotion);
|
|
+
|
|
+ private:
|
|
+ int m_ipuHandle;
|
|
+ bool m_autoMode;
|
|
+ int m_bufferNum;
|
|
+ CDVDVideoCodecIMXIPUBuffer **m_buffers;
|
|
+ int m_currentFieldFmt;
|
|
+};
|
|
+
|
|
+
|
|
class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
{
|
|
friend class CDVDVideoCodecIMXVPUBuffer;
|
|
|
|
From 4b14e49ad629c7fe22b438aee2065dafd426c97f Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 19:22:28 +0100
|
|
Subject: [PATCH 06/18] [imx] @wolfgar Added mixer thread implementation with
|
|
capacity limited input/output queue
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 248 ++++++++++++++++++++-
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 90 ++++++++
|
|
2 files changed, 336 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index 5dfa4f8..6da91eb 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -26,11 +26,15 @@
|
|
#include <sys/ioctl.h>
|
|
#include <unistd.h>
|
|
#include <sys/mman.h>
|
|
+#include <linux/mxcfb.h>
|
|
+#include <linux/ipu.h>
|
|
+#include "settings/MediaSettings.h"
|
|
+#include "settings/VideoSettings.h"
|
|
+#include "settings/AdvancedSettings.h"
|
|
#include "threads/SingleLock.h"
|
|
+#include "threads/Atomics.h"
|
|
#include "utils/log.h"
|
|
#include "DVDClock.h"
|
|
-#include "settings/AdvancedSettings.h"
|
|
-#include "threads/Atomics.h"
|
|
|
|
#define FRAME_ALIGN 16
|
|
#define MEDIAINFO 1
|
|
@@ -1486,3 +1490,243 @@ CDVDVideoCodecIMXIPUBuffers::Process(CDVDVideoCodecIMXBuffer *sourceBuffer,
|
|
|
|
return target;
|
|
}
|
|
+
|
|
+
|
|
+CDVDVideoMixerIMX::CDVDVideoMixerIMX(CDVDVideoCodecIMXIPUBuffers *proc)
|
|
+ : CThread("IMX6 Mixer")
|
|
+ , m_beginInput(0), m_endInput(0), m_bufferedInput(0)
|
|
+ , m_beginOutput(0), m_endOutput(0), m_bufferedOutput(0)
|
|
+ , m_proc(proc)
|
|
+{
|
|
+}
|
|
+
|
|
+CDVDVideoMixerIMX::~CDVDVideoMixerIMX()
|
|
+{
|
|
+ Dispose();
|
|
+}
|
|
+
|
|
+void CDVDVideoMixerIMX::SetCapacity(int nInput, int nOutput)
|
|
+{
|
|
+ Reset();
|
|
+ m_input.resize(nInput);
|
|
+ m_output.resize(nOutput);
|
|
+}
|
|
+
|
|
+void CDVDVideoMixerIMX::Start()
|
|
+{
|
|
+ Create();
|
|
+}
|
|
+
|
|
+void CDVDVideoMixerIMX::Reset()
|
|
+{
|
|
+ CSingleLock lk(m_monitor);
|
|
+
|
|
+ // Release all still referenced buffers
|
|
+ for (size_t i = 0; i < m_input.size(); ++i)
|
|
+ {
|
|
+ SAFE_RELEASE(m_input[i]);
|
|
+ m_input[i] = NULL;
|
|
+ }
|
|
+
|
|
+ for (size_t i = 0; i < m_output.size(); ++i)
|
|
+ {
|
|
+ SAFE_RELEASE(m_output[i]);
|
|
+ m_output[i] = NULL;
|
|
+ }
|
|
+
|
|
+ // Reset ring buffer
|
|
+ m_beginInput = m_endInput = m_bufferedInput = 0;
|
|
+ m_beginOutput = m_endOutput = m_bufferedOutput = 0;
|
|
+
|
|
+ m_inputNotFull.notifyAll();
|
|
+ m_outputNotFull.notifyAll();
|
|
+}
|
|
+
|
|
+void CDVDVideoMixerIMX::Dispose()
|
|
+{
|
|
+ StopThread();
|
|
+ Reset();
|
|
+}
|
|
+
|
|
+bool CDVDVideoMixerIMX::IsActive() {
|
|
+ return IsRunning();
|
|
+}
|
|
+
|
|
+CDVDVideoCodecIMXBuffer *CDVDVideoMixerIMX::Process(CDVDVideoCodecIMXVPUBuffer *buffer)
|
|
+{
|
|
+ CSingleLock lk(m_monitor);
|
|
+ CDVDVideoCodecIMXBuffer *r;
|
|
+
|
|
+ if (m_bStop)
|
|
+ {
|
|
+ m_inputNotEmpty.notifyAll();
|
|
+ m_outputNotFull.notifyAll();
|
|
+ SAFE_RELEASE(buffer);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (m_bufferedOutput)
|
|
+ {
|
|
+ // Pop the output
|
|
+ r = m_output[m_beginOutput];
|
|
+ m_output[m_beginOutput] = NULL;
|
|
+ m_beginOutput = (m_beginOutput+1) % m_output.size();
|
|
+ --m_bufferedOutput;
|
|
+ m_outputNotFull.notifyAll();
|
|
+ }
|
|
+ else
|
|
+ r = NULL;
|
|
+
|
|
+ // Flush call?
|
|
+ if (!buffer)
|
|
+ return r;
|
|
+
|
|
+ // If the input queue is full, wait for a free slot
|
|
+ while ((m_bufferedInput == m_input.size()) && !m_bStop)
|
|
+ m_inputNotFull.wait(lk);
|
|
+
|
|
+ if (m_bStop)
|
|
+ {
|
|
+ m_inputNotEmpty.notifyAll();
|
|
+ m_outputNotFull.notifyAll();
|
|
+ buffer->Release();
|
|
+ return r;
|
|
+ }
|
|
+
|
|
+ // Store the value
|
|
+ m_input[m_endInput] = buffer;
|
|
+ m_endInput = (m_endInput+1) % m_input.size();
|
|
+ ++m_bufferedInput;
|
|
+ m_inputNotEmpty.notifyAll();
|
|
+
|
|
+ //CLog::Log(LOGNOTICE, "Pushed input frame %x\n", (int)buffer);
|
|
+
|
|
+ return r;
|
|
+}
|
|
+
|
|
+void CDVDVideoMixerIMX::OnStartup()
|
|
+{
|
|
+ CLog::Log(LOGNOTICE, "CDVDVideoMixerIMX::OnStartup: Mixer Thread created");
|
|
+}
|
|
+
|
|
+void CDVDVideoMixerIMX::OnExit()
|
|
+{
|
|
+ CLog::Log(LOGNOTICE, "CDVDVideoMixerIMX::OnExit: Mixer Thread terminated");
|
|
+}
|
|
+
|
|
+void CDVDVideoMixerIMX::StopThread(bool bWait /*= true*/)
|
|
+{
|
|
+ CThread::StopThread(false);
|
|
+ m_inputNotFull.notifyAll();
|
|
+ m_inputNotEmpty.notifyAll();
|
|
+ m_outputNotFull.notifyAll();
|
|
+ if (bWait)
|
|
+ CThread::StopThread(true);
|
|
+}
|
|
+
|
|
+void CDVDVideoMixerIMX::Process()
|
|
+{
|
|
+ while (!m_bStop)
|
|
+ {
|
|
+ // Blocking until an input is available
|
|
+ CDVDVideoCodecIMXVPUBuffer *inputBuffer = GetNextInput();
|
|
+ if (inputBuffer)
|
|
+ {
|
|
+ // Wait for free slot
|
|
+ WaitForFreeOutput();
|
|
+
|
|
+ CDVDVideoCodecIMXBuffer *outputBuffer = ProcessFrame(inputBuffer);
|
|
+
|
|
+ // Queue the output if any
|
|
+ if (outputBuffer)
|
|
+ {
|
|
+ // Blocking until a free output slot is available. The buffer is
|
|
+ // reference counted in PushOutput
|
|
+ PushOutput(outputBuffer);
|
|
+ }
|
|
+
|
|
+ SAFE_RELEASE(inputBuffer);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+CDVDVideoCodecIMXVPUBuffer *CDVDVideoMixerIMX::GetNextInput() {
|
|
+ CSingleLock lk(m_monitor);
|
|
+ while (!m_bufferedInput && !m_bStop)
|
|
+ m_inputNotEmpty.wait(lk);
|
|
+
|
|
+ if (m_bStop)
|
|
+ return NULL;
|
|
+
|
|
+ CDVDVideoCodecIMXVPUBuffer *v = m_input[m_beginInput];
|
|
+ m_input[m_beginInput] = NULL;
|
|
+ m_beginInput = (m_beginInput+1) % m_input.size();
|
|
+ --m_bufferedInput;
|
|
+ m_inputNotFull.notifyAll();
|
|
+
|
|
+ //CLog::Log(LOGNOTICE, "Popped input frame %x\n", (int)v);
|
|
+
|
|
+ return v;
|
|
+}
|
|
+
|
|
+void CDVDVideoMixerIMX::WaitForFreeOutput() {
|
|
+ CSingleLock lk(m_monitor);
|
|
+
|
|
+ // Output queue is full, wait for a free slot
|
|
+ while (m_bufferedOutput == m_output.size() && !m_bStop)
|
|
+ m_outputNotFull.wait(lk);
|
|
+}
|
|
+
|
|
+bool CDVDVideoMixerIMX::PushOutput(CDVDVideoCodecIMXBuffer *v) {
|
|
+ CSingleLock lk(m_monitor);
|
|
+
|
|
+ v->Lock();
|
|
+
|
|
+ // If closed return false
|
|
+ if (m_bStop)
|
|
+ {
|
|
+ v->Release();
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // Store the value
|
|
+ m_output[m_endOutput] = v;
|
|
+ m_endOutput = (m_endOutput+1) % m_output.size();
|
|
+ ++m_bufferedOutput;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+CDVDVideoCodecIMXBuffer *CDVDVideoMixerIMX::ProcessFrame(CDVDVideoCodecIMXVPUBuffer *inputBuffer)
|
|
+{
|
|
+ CDVDVideoCodecIMXBuffer *outputBuffer;
|
|
+ EDEINTERLACEMODE mDeintMode = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
|
|
+ //EINTERLACEMETHOD mInt = CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod;
|
|
+
|
|
+ if ((mDeintMode == VS_DEINTERLACEMODE_OFF)
|
|
+ || ((mDeintMode == VS_DEINTERLACEMODE_AUTO) && !m_proc->AutoMode()))
|
|
+ {
|
|
+ outputBuffer = inputBuffer;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+#ifdef IMX_PROFILE_BUFFERS
|
|
+ unsigned long long current = XbmcThreads::SystemClockMillis();
|
|
+#endif
|
|
+//#define DUMMY_DEINTERLACER
|
|
+#ifdef DUMMY_DEINTERLACER
|
|
+ Sleep(35);
|
|
+ outputBuffer = inputBuffer;
|
|
+#else
|
|
+ outputBuffer = m_proc->Process(inputBuffer,
|
|
+ inputBuffer->GetFieldType(),
|
|
+ false);
|
|
+#endif
|
|
+#ifdef IMX_PROFILE_BUFFERS
|
|
+ CLog::Log(LOGNOTICE, "+P %x %lld\n", (int)outputBuffer,
|
|
+ XbmcThreads::SystemClockMillis()-current);
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ return outputBuffer;
|
|
+}
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index bb2f7d1..5b4d835 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -19,10 +19,14 @@
|
|
*
|
|
*/
|
|
#include <queue>
|
|
+#include <vector>
|
|
#include <imx-mm/vpu/vpu_wrapper.h>
|
|
#include "DVDVideoCodec.h"
|
|
#include "DVDStreamInfo.h"
|
|
#include "threads/CriticalSection.h"
|
|
+#include "threads/Condition.h"
|
|
+#include "threads/Event.h"
|
|
+#include "threads/Thread.h"
|
|
#include "utils/BitstreamConverter.h"
|
|
|
|
|
|
@@ -34,6 +38,15 @@
|
|
// The IPU works faster when outputting to NV12.
|
|
//#define IMX_OUTPUT_FORMAT_I420
|
|
|
|
+// This enables logging of times for Decode->Decode, Render->Render,
|
|
+// Deinterlace->Deinterlace. It helps to profile several stages of
|
|
+// processing with respect to changed kernels or other configurations.
|
|
+// Since we utilize VPU, IPU and GPU at the same time different kernel
|
|
+// priorities to those subsystems can result in a very different user
|
|
+// experience. With that setting enabled we can build some statistics,
|
|
+// as numbers are always better than "feelings"
|
|
+//#define IMX_PROFILE_BUFFERS
|
|
+
|
|
//#define IMX_PROFILE
|
|
//#define TRACE_FRAMES
|
|
|
|
@@ -195,6 +208,83 @@ class CDVDVideoCodecIMXIPUBuffers
|
|
};
|
|
|
|
|
|
+// Collection class that manages a pool of IPU buffers that are used for
|
|
+// deinterlacing. In future they can also serve rotation or color conversion
|
|
+// buffers.
|
|
+class CDVDVideoCodecIMXIPUBuffers
|
|
+{
|
|
+ public:
|
|
+ CDVDVideoCodecIMXIPUBuffers();
|
|
+ ~CDVDVideoCodecIMXIPUBuffers();
|
|
+
|
|
+ bool Init(int width, int height, int numBuffers, int nAlign);
|
|
+ // Sets the mode to be used if deinterlacing is set to AUTO
|
|
+ void SetAutoMode(bool mode) { m_autoMode = mode; }
|
|
+ bool AutoMode() const { return m_autoMode; }
|
|
+ bool Reset();
|
|
+ bool Close();
|
|
+
|
|
+ CDVDVideoCodecIMXIPUBuffer *
|
|
+ Process(CDVDVideoCodecIMXBuffer *sourceBuffer,
|
|
+ VpuFieldType fieldType, bool lowMotion);
|
|
+
|
|
+ private:
|
|
+ int m_ipuHandle;
|
|
+ bool m_autoMode;
|
|
+ int m_bufferNum;
|
|
+ CDVDVideoCodecIMXIPUBuffer **m_buffers;
|
|
+ int m_currentFieldFmt;
|
|
+};
|
|
+
|
|
+
|
|
+class CDVDVideoMixerIMX : private CThread {
|
|
+public:
|
|
+ CDVDVideoMixerIMX(CDVDVideoCodecIMXIPUBuffers *proc);
|
|
+ virtual ~CDVDVideoMixerIMX();
|
|
+
|
|
+ void SetCapacity(int intput, int output);
|
|
+
|
|
+ void Start();
|
|
+ void Reset();
|
|
+ void Dispose();
|
|
+ bool IsActive();
|
|
+
|
|
+ // This function blocks until an input slot is available.
|
|
+ // It returns if an output is available.
|
|
+ CDVDVideoCodecIMXBuffer *Process(CDVDVideoCodecIMXVPUBuffer *input);
|
|
+
|
|
+private:
|
|
+ CDVDVideoCodecIMXVPUBuffer *GetNextInput();
|
|
+ void WaitForFreeOutput();
|
|
+ bool PushOutput(CDVDVideoCodecIMXBuffer *v);
|
|
+ CDVDVideoCodecIMXBuffer *ProcessFrame(CDVDVideoCodecIMXVPUBuffer *input);
|
|
+
|
|
+ virtual void OnStartup();
|
|
+ virtual void OnExit();
|
|
+ virtual void StopThread(bool bWait = true);
|
|
+ virtual void Process();
|
|
+
|
|
+private:
|
|
+ typedef std::vector<CDVDVideoCodecIMXVPUBuffer*> InputBuffers;
|
|
+ typedef std::vector<CDVDVideoCodecIMXBuffer*> OutputBuffers;
|
|
+
|
|
+ CDVDVideoCodecIMXIPUBuffers *m_proc;
|
|
+ InputBuffers m_input;
|
|
+ volatile int m_beginInput, m_endInput;
|
|
+ volatile size_t m_bufferedInput;
|
|
+ XbmcThreads::ConditionVariable m_inputNotEmpty;
|
|
+ XbmcThreads::ConditionVariable m_inputNotFull;
|
|
+
|
|
+ OutputBuffers m_output;
|
|
+ volatile int m_beginOutput, m_endOutput;
|
|
+ volatile size_t m_bufferedOutput;
|
|
+ XbmcThreads::ConditionVariable m_outputNotFull;
|
|
+
|
|
+ mutable CCriticalSection m_monitor;
|
|
+ CDVDVideoCodecIMXBuffer *m_lastFrame; // Last input frame
|
|
+};
|
|
+
|
|
+
|
|
class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
{
|
|
friend class CDVDVideoCodecIMXVPUBuffer;
|
|
|
|
From 657ea2836b26cc70c3ed4cee881b876080ab228b Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 19:30:30 +0100
|
|
Subject: [PATCH 07/18] [imx] @wolfgar Removed friend declaration
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 3 ---
|
|
1 file changed, 3 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index 5b4d835..33e449f 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -287,9 +287,6 @@ class CDVDVideoMixerIMX : private CThread {
|
|
|
|
class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
{
|
|
- friend class CDVDVideoCodecIMXVPUBuffer;
|
|
- friend class CDVDVideoCodecIPUBuffer;
|
|
-
|
|
public:
|
|
CDVDVideoCodecIMX();
|
|
virtual ~CDVDVideoCodecIMX();
|
|
|
|
From 288033e49346e9f2710d1a145abadf2308553d54 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 19:42:49 +0100
|
|
Subject: [PATCH 08/18] [imx] @wolfgar Added missing attribute to
|
|
CDVDVideoCodecIMXVPUBuffer, cosmetics (indentation) and allocate buffer
|
|
according to input format at compile time
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 130 ++++++++++++++-------
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 7 +-
|
|
2 files changed, 91 insertions(+), 46 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index 6da91eb..87a6c48 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -94,8 +94,8 @@ bool CDVDVideoCodecIMX::VpuAllocBuffers(VpuMemInfo *pMemBlock)
|
|
return true;
|
|
|
|
AllocFailure:
|
|
- VpuFreeBuffers();
|
|
- return false;
|
|
+ VpuFreeBuffers();
|
|
+ return false;
|
|
}
|
|
|
|
int CDVDVideoCodecIMX::VpuFindBuffer(void *frameAddr)
|
|
@@ -231,50 +231,76 @@ bool CDVDVideoCodecIMX::VpuOpen(void)
|
|
|
|
bool CDVDVideoCodecIMX::VpuAllocFrameBuffers(void)
|
|
{
|
|
+ int totalSize = 0;
|
|
+ int ySize = 0;
|
|
+ int uSize = 0;
|
|
+ int vSize = 0;
|
|
+ int mvSize = 0;
|
|
+ int yStride = 0;
|
|
+ int uvStride = 0;
|
|
+
|
|
VpuDecRetCode ret;
|
|
VpuMemDesc vpuMem;
|
|
- int totalSize=0;
|
|
- int mvSize=0;
|
|
- int ySize=0;
|
|
- int uvSize=0;
|
|
- int yStride=0;
|
|
- int uvStride=0;
|
|
unsigned char* ptr;
|
|
unsigned char* ptrVirt;
|
|
int nAlign;
|
|
|
|
- m_vpuFrameBufferNum = m_initInfo.nMinFrameBufferCount + m_extraVpuBuffers;
|
|
+ m_vpuFrameBufferNum = m_initInfo.nMinFrameBufferCount + m_extraVpuBuffers;
|
|
m_vpuFrameBuffers = new VpuFrameBuffer[m_vpuFrameBufferNum];
|
|
|
|
- yStride=Align(m_initInfo.nPicWidth,FRAME_ALIGN);
|
|
+ yStride = Align(m_initInfo.nPicWidth,FRAME_ALIGN);
|
|
if(m_initInfo.nInterlace)
|
|
{
|
|
- ySize=Align(m_initInfo.nPicWidth,FRAME_ALIGN)*Align(m_initInfo.nPicHeight,(2*FRAME_ALIGN));
|
|
+ ySize = Align(m_initInfo.nPicWidth,FRAME_ALIGN)*Align(m_initInfo.nPicHeight,(2*FRAME_ALIGN));
|
|
}
|
|
else
|
|
{
|
|
- ySize=Align(m_initInfo.nPicWidth,FRAME_ALIGN)*Align(m_initInfo.nPicHeight,FRAME_ALIGN);
|
|
+ ySize = Align(m_initInfo.nPicWidth,FRAME_ALIGN)*Align(m_initInfo.nPicHeight,FRAME_ALIGN);
|
|
+ }
|
|
+
|
|
+#ifdef IMX_INPUT_FORMAT_I420
|
|
+ switch (m_initInfo.nMjpgSourceFormat)
|
|
+ {
|
|
+ case 0: // I420 (4:2:0)
|
|
+ uvStride = yStride / 2;
|
|
+ uSize = vSize = mvSize = ySize / 4;
|
|
+ break;
|
|
+ case 1: // Y42B (4:2:2 horizontal)
|
|
+ uvStride = yStride / 2;
|
|
+ uSize = vSize = mvSize = ySize / 2;
|
|
+ break;
|
|
+ case 3: // Y444 (4:4:4)
|
|
+ uvStride = yStride;
|
|
+ uSize = vSize = mvSize = ySize;
|
|
+ break;
|
|
+ default:
|
|
+ CLog::Log(LOGERROR, "%s: invalid source format in init info\n",__FUNCTION__,ret);
|
|
+ return false;
|
|
}
|
|
|
|
- //NV12 for all video
|
|
- uvStride=yStride;
|
|
- uvSize=ySize/2;
|
|
- mvSize=uvSize/2;
|
|
+#else
|
|
+ // NV12
|
|
+ uvStride = yStride;
|
|
+ uSize = ySize/2;
|
|
+ mvSize = uSize/2;
|
|
+#endif
|
|
|
|
- nAlign=m_initInfo.nAddressAlignment;
|
|
+ nAlign = m_initInfo.nAddressAlignment;
|
|
if(nAlign>1)
|
|
{
|
|
- ySize=Align(ySize,nAlign);
|
|
- uvSize=Align(uvSize,nAlign);
|
|
+ ySize = Align(ySize, nAlign);
|
|
+ uSize = Align(uSize, nAlign);
|
|
+ vSize = Align(vSize, nAlign);
|
|
+ mvSize = Align(mvSize, nAlign);
|
|
}
|
|
|
|
m_outputBuffers = new CDVDVideoCodecIMXVPUBuffer*[m_vpuFrameBufferNum];
|
|
|
|
for (int i=0 ; i < m_vpuFrameBufferNum; i++)
|
|
{
|
|
- totalSize=(ySize+uvSize+mvSize+nAlign)*1;
|
|
+ totalSize = ySize + uSize + vSize + mvSize + nAlign;
|
|
|
|
- vpuMem.nSize=totalSize;
|
|
+ vpuMem.nSize = totalSize;
|
|
ret = VPU_DecGetMem(&vpuMem);
|
|
if(ret != VPU_DEC_RET_SUCCESS)
|
|
{
|
|
@@ -291,36 +317,44 @@ bool CDVDVideoCodecIMX::VpuAllocFrameBuffers(void)
|
|
m_decMemInfo.phyMem[m_decMemInfo.nPhyNum-1].nSize = vpuMem.nSize;
|
|
|
|
//fill frameBuf
|
|
- ptr=(unsigned char*)vpuMem.nPhyAddr;
|
|
- ptrVirt=(unsigned char*)vpuMem.nVirtAddr;
|
|
+ ptr = (unsigned char*)vpuMem.nPhyAddr;
|
|
+ ptrVirt = (unsigned char*)vpuMem.nVirtAddr;
|
|
|
|
//align the base address
|
|
if(nAlign>1)
|
|
{
|
|
- ptr=(unsigned char*)Align(ptr,nAlign);
|
|
- ptrVirt=(unsigned char*)Align(ptrVirt,nAlign);
|
|
+ ptr = (unsigned char*)Align(ptr,nAlign);
|
|
+ ptrVirt = (unsigned char*)Align(ptrVirt,nAlign);
|
|
}
|
|
|
|
// fill stride info
|
|
- m_vpuFrameBuffers[i].nStrideY=yStride;
|
|
- m_vpuFrameBuffers[i].nStrideC=uvStride;
|
|
+ m_vpuFrameBuffers[i].nStrideY = yStride;
|
|
+ m_vpuFrameBuffers[i].nStrideC = uvStride;
|
|
|
|
// fill phy addr
|
|
- m_vpuFrameBuffers[i].pbufY=ptr;
|
|
- m_vpuFrameBuffers[i].pbufCb=ptr+ySize;
|
|
- m_vpuFrameBuffers[i].pbufCr=0;
|
|
- m_vpuFrameBuffers[i].pbufMvCol=ptr+ySize+uvSize;
|
|
+ m_vpuFrameBuffers[i].pbufY = ptr;
|
|
+ m_vpuFrameBuffers[i].pbufCb = ptr + ySize;
|
|
+#ifdef IMX_INPUT_FORMAT_I420
|
|
+ m_vpuFrameBuffers[i].pbufCr = ptr + ySize + uSize;
|
|
+#else
|
|
+ m_vpuFrameBuffers[i].pbufCr = 0;
|
|
+#endif
|
|
+ m_vpuFrameBuffers[i].pbufMvCol = ptr + ySize + uSize + vSize;
|
|
|
|
// fill virt addr
|
|
- m_vpuFrameBuffers[i].pbufVirtY=ptrVirt;
|
|
- m_vpuFrameBuffers[i].pbufVirtCb=ptrVirt+ySize;
|
|
- m_vpuFrameBuffers[i].pbufVirtCr=0;
|
|
- m_vpuFrameBuffers[i].pbufVirtMvCol=ptrVirt+ySize+uvSize;
|
|
+ m_vpuFrameBuffers[i].pbufVirtY = ptrVirt;
|
|
+ m_vpuFrameBuffers[i].pbufVirtCb = ptrVirt + ySize;
|
|
+#ifdef IMX_INPUT_FORMAT_I420
|
|
+ m_vpuFrameBuffers[i].pbufVirtCr = ptrVirt + ySize + uSize;
|
|
+#else
|
|
+ m_vpuFrameBuffers[i].pbufVirtCr = 0;
|
|
+#endif
|
|
+ m_vpuFrameBuffers[i].pbufVirtMvCol = ptrVirt + ySize + uSize + vSize;
|
|
|
|
- m_vpuFrameBuffers[i].pbufY_tilebot=0;
|
|
- m_vpuFrameBuffers[i].pbufCb_tilebot=0;
|
|
- m_vpuFrameBuffers[i].pbufVirtY_tilebot=0;
|
|
- m_vpuFrameBuffers[i].pbufVirtCb_tilebot=0;
|
|
+ m_vpuFrameBuffers[i].pbufY_tilebot = 0;
|
|
+ m_vpuFrameBuffers[i].pbufCb_tilebot = 0;
|
|
+ m_vpuFrameBuffers[i].pbufVirtY_tilebot = 0;
|
|
+ m_vpuFrameBuffers[i].pbufVirtCb_tilebot = 0;
|
|
|
|
#ifdef TRACE_FRAMES
|
|
m_outputBuffers[i] = new CDVDVideoCodecIMXVPUBuffer(i);
|
|
@@ -647,7 +681,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts)
|
|
m_bytesToBeConsumed += inData.nSize;
|
|
ret = VPU_DecDecodeBuf(m_vpuHandle, &inData, &decRet);
|
|
#ifdef IMX_PROFILE
|
|
- CLog::Log(LOGDEBUG, "%s - VPU dec 0x%x decode takes : %lld\n\n", __FUNCTION__, decRet, XbmcThreads::SystemClockMillis() - before_dec);
|
|
+ CLog::Log(LOGDEBUG, "%s - VPU dec 0x%x decode takes : %lld\n\n", __FUNCTION__, decRet, XbmcThreads::SystemClockMillis() - before_dec);
|
|
#endif
|
|
|
|
if (ret != VPU_DEC_RET_SUCCESS)
|
|
@@ -1079,10 +1113,18 @@ void CDVDVideoCodecIMXVPUBuffer::Queue(VpuDecOutFrameInfo *frameInfo,
|
|
if (m_previousBuffer)
|
|
m_previousBuffer->Lock();
|
|
|
|
- m_iWidth = frameInfo->pExtInfo->nFrmWidth;
|
|
- m_iHeight = frameInfo->pExtInfo->nFrmHeight;
|
|
- m_VirtAddr = m_frameBuffer->pbufVirtY;
|
|
- m_phyAddr = m_frameBuffer->pbufY;
|
|
+ iWidth = frameInfo->pExtInfo->nFrmWidth;
|
|
+ iHeight = frameInfo->pExtInfo->nFrmHeight;
|
|
+ pVirtAddr = m_frameBuffer->pbufVirtY;
|
|
+ pPhysAddr = m_frameBuffer->pbufY;
|
|
+
|
|
+ m_fieldType = frameInfo->eFieldType;
|
|
+ // We decode to I420
|
|
+#ifdef IMX_INPUT_FORMAT_I420
|
|
+ iFormat = 0;
|
|
+#else
|
|
+ iFormat = 1;
|
|
+#endif
|
|
}
|
|
|
|
VpuDecRetCode CDVDVideoCodecIMXVPUBuffer::ReleaseFramebuffer(VpuDecHandle *handle)
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index 33e449f..c8b807d 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -127,16 +127,19 @@ class CDVDVideoCodecIMXVPUBuffer : public CDVDVideoCodecIMXBuffer
|
|
CDVDVideoCodecIMXVPUBuffer *previous);
|
|
VpuDecRetCode ReleaseFramebuffer(VpuDecHandle *handle);
|
|
CDVDVideoCodecIMXVPUBuffer *GetPreviousBuffer() const;
|
|
+ VpuFieldType GetFieldType() const { return m_fieldType; }
|
|
|
|
private:
|
|
// private because we are reference counted
|
|
- virtual ~CDVDVideoCodecIMXVPUBuffer();
|
|
+ virtual ~CDVDVideoCodecIMXVPUBuffer();
|
|
|
|
private:
|
|
VpuFrameBuffer *m_frameBuffer;
|
|
+ VpuFieldType m_fieldType;
|
|
+
|
|
bool m_rendered;
|
|
CDVDVideoCodecIMXVPUBuffer *m_previousBuffer; // Holds a the reference counted
|
|
- // previous buffer
|
|
+ // previous buffer
|
|
};
|
|
|
|
|
|
|
|
From 9cb00a6922b74690e7502cd72dba98071297700e Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 19:46:32 +0100
|
|
Subject: [PATCH 09/18] [imx] @wolfgar Added more VPU decoder configuration and
|
|
fixed nChromaInterleave depending on input format
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 22 ++++++++++++++++++++++
|
|
1 file changed, 22 insertions(+)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index 87a6c48..c09b4e6 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -189,7 +189,11 @@ bool CDVDVideoCodecIMX::VpuOpen(void)
|
|
VpuAllocBuffers(&memInfo);
|
|
|
|
m_decOpenParam.nReorderEnable = 1;
|
|
+#ifdef IMX_INPUT_FORMAT_I420
|
|
+ m_decOpenParam.nChromaInterleave = 0;
|
|
+#else
|
|
m_decOpenParam.nChromaInterleave = 1;
|
|
+#endif
|
|
m_decOpenParam.nMapType = 0;
|
|
m_decOpenParam.nTiled2LinearEnable = 0;
|
|
m_decOpenParam.nEnableFileMode = 0;
|
|
@@ -210,6 +214,24 @@ bool CDVDVideoCodecIMX::VpuOpen(void)
|
|
goto VpuOpenError;
|
|
}
|
|
|
|
+ config = VPU_DEC_CONF_BUFDELAY;
|
|
+ param = 0;
|
|
+ ret = VPU_DecConfig(m_vpuHandle, config, ¶m);
|
|
+ if (ret != VPU_DEC_RET_SUCCESS)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "%s - iMX VPU set buffer delay failed (%d).\n", __FUNCTION__, ret);
|
|
+ goto VpuOpenError;
|
|
+ }
|
|
+
|
|
+ config = VPU_DEC_CONF_INPUTTYPE;
|
|
+ param = VPU_DEC_IN_NORMAL;
|
|
+ ret = VPU_DecConfig(m_vpuHandle, config, ¶m);
|
|
+ if (ret != VPU_DEC_RET_SUCCESS)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "%s - iMX VPU configure input type failed (%d).\n", __FUNCTION__, ret);
|
|
+ goto VpuOpenError;
|
|
+ }
|
|
+
|
|
// Note that libvpufsl (file vpu_wrapper.c) associates VPU_DEC_CAP_FRAMESIZE
|
|
// capability to the value of nDecFrameRptEnabled which is in fact directly
|
|
// related to the ability to generate VPU_DEC_ONE_FRM_CONSUMED even if the
|
|
|
|
From abe29f2acc6291d5807f34ed0fd9fd7ba83f8274 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 19:50:47 +0100
|
|
Subject: [PATCH 10/18] [imx] @wolfgar Added deinterlacer initialization and
|
|
mixer thread but still unused
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 12 +++++++++++-
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 3 +++
|
|
2 files changed, 14 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index c09b4e6..59187e8 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -385,16 +385,25 @@ bool CDVDVideoCodecIMX::VpuAllocFrameBuffers(void)
|
|
#endif
|
|
}
|
|
|
|
+ CLog::Log(LOGNOTICE, "IMX: Initialize hardware deinterlacing\n");
|
|
+ if (!m_deinterlacer.Init(m_initInfo.nPicWidth, m_initInfo.nPicHeight, GetAllowedReferences()+5, nAlign))
|
|
+ {
|
|
+ CLog::Log(LOGWARNING, "IMX: Failed to initialize IPU buffers: deinterlacing disabled\n");
|
|
+ }
|
|
+
|
|
+ m_deinterlacer.SetAutoMode(m_initInfo.nInterlace);
|
|
+
|
|
return true;
|
|
}
|
|
|
|
-CDVDVideoCodecIMX::CDVDVideoCodecIMX()
|
|
+CDVDVideoCodecIMX::CDVDVideoCodecIMX() : m_mixer(&m_deinterlacer)
|
|
{
|
|
m_pFormatName = "iMX-xxx";
|
|
m_vpuHandle = 0;
|
|
m_vpuFrameBuffers = NULL;
|
|
m_outputBuffers = NULL;
|
|
m_lastBuffer = NULL;
|
|
+ m_currentBuffer = NULL;
|
|
m_extraMem = NULL;
|
|
m_vpuFrameBufferNum = 0;
|
|
m_dropState = false;
|
|
@@ -409,6 +418,7 @@ CDVDVideoCodecIMX::CDVDVideoCodecIMX()
|
|
m_convert_bitstream = false;
|
|
m_bytesToBeConsumed = 0;
|
|
m_previousPts = DVD_NOPTS_VALUE;
|
|
+ m_mixer.SetCapacity(3,3);
|
|
}
|
|
|
|
CDVDVideoCodecIMX::~CDVDVideoCodecIMX()
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index c8b807d..69e27f7 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -330,8 +330,11 @@ class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
bool m_dropState; // Current drop state
|
|
int m_vpuFrameBufferNum; // Total number of allocated frame buffers
|
|
VpuFrameBuffer *m_vpuFrameBuffers; // Table of VPU frame buffers description
|
|
+ CDVDVideoCodecIMXIPUBuffers m_deinterlacer; // Pool of buffers used for deinterlacing
|
|
+ CDVDVideoMixerIMX m_mixer;
|
|
CDVDVideoCodecIMXVPUBuffer **m_outputBuffers; // Table of VPU output buffers
|
|
CDVDVideoCodecIMXVPUBuffer *m_lastBuffer; // Keep track of previous VPU output buffer (needed by deinterlacing motion engin)
|
|
+ CDVDVideoCodecIMXBuffer *m_currentBuffer;
|
|
VpuMemDesc *m_extraMem; // Table of allocated extra Memory
|
|
int m_frameCounter; // Decoded frames counter
|
|
bool m_usePTS; // State whether pts out of decoding process should be used
|
|
|
|
From f54fdf922228a37fb7d4f89177f4bd5c766a8026 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 19:56:14 +0100
|
|
Subject: [PATCH 11/18] [imx] @wolfgar Cosmetics and removed duplicate class
|
|
declaration
|
|
|
|
---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 71 +++++++---------------
|
|
1 file changed, 21 insertions(+), 50 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index 69e27f7..7c0e7da 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -187,60 +187,32 @@ class CDVDVideoCodecIMXIPUBuffer : public CDVDVideoCodecIMXBuffer
|
|
// buffers.
|
|
class CDVDVideoCodecIMXIPUBuffers
|
|
{
|
|
- public:
|
|
- CDVDVideoCodecIMXIPUBuffers();
|
|
- ~CDVDVideoCodecIMXIPUBuffers();
|
|
-
|
|
- bool Init(int width, int height, int numBuffers, int nAlign);
|
|
- // Sets the mode to be used if deinterlacing is set to AUTO
|
|
- void SetAutoMode(bool mode) { m_autoMode = mode; }
|
|
- bool AutoMode() const { return m_autoMode; }
|
|
- bool Reset();
|
|
- bool Close();
|
|
-
|
|
- CDVDVideoCodecIMXIPUBuffer *
|
|
- Process(CDVDVideoCodecIMXBuffer *sourceBuffer,
|
|
- VpuFieldType fieldType, bool lowMotion);
|
|
-
|
|
- private:
|
|
- int m_ipuHandle;
|
|
- bool m_autoMode;
|
|
- int m_bufferNum;
|
|
- CDVDVideoCodecIMXIPUBuffer **m_buffers;
|
|
- int m_currentFieldFmt;
|
|
-};
|
|
+public:
|
|
+ CDVDVideoCodecIMXIPUBuffers();
|
|
+ ~CDVDVideoCodecIMXIPUBuffers();
|
|
|
|
+ bool Init(int width, int height, int numBuffers, int nAlign);
|
|
+ // Sets the mode to be used if deinterlacing is set to AUTO
|
|
+ void SetAutoMode(bool mode) { m_autoMode = mode; }
|
|
+ bool AutoMode() const { return m_autoMode; }
|
|
+ bool Reset();
|
|
+ bool Close();
|
|
|
|
-// Collection class that manages a pool of IPU buffers that are used for
|
|
-// deinterlacing. In future they can also serve rotation or color conversion
|
|
-// buffers.
|
|
-class CDVDVideoCodecIMXIPUBuffers
|
|
-{
|
|
- public:
|
|
- CDVDVideoCodecIMXIPUBuffers();
|
|
- ~CDVDVideoCodecIMXIPUBuffers();
|
|
-
|
|
- bool Init(int width, int height, int numBuffers, int nAlign);
|
|
- // Sets the mode to be used if deinterlacing is set to AUTO
|
|
- void SetAutoMode(bool mode) { m_autoMode = mode; }
|
|
- bool AutoMode() const { return m_autoMode; }
|
|
- bool Reset();
|
|
- bool Close();
|
|
-
|
|
- CDVDVideoCodecIMXIPUBuffer *
|
|
- Process(CDVDVideoCodecIMXBuffer *sourceBuffer,
|
|
- VpuFieldType fieldType, bool lowMotion);
|
|
-
|
|
- private:
|
|
- int m_ipuHandle;
|
|
- bool m_autoMode;
|
|
- int m_bufferNum;
|
|
- CDVDVideoCodecIMXIPUBuffer **m_buffers;
|
|
- int m_currentFieldFmt;
|
|
+ CDVDVideoCodecIMXIPUBuffer *
|
|
+ Process(CDVDVideoCodecIMXBuffer *sourceBuffer,
|
|
+ VpuFieldType fieldType, bool lowMotion);
|
|
+
|
|
+private:
|
|
+ int m_ipuHandle;
|
|
+ bool m_autoMode;
|
|
+ int m_bufferNum;
|
|
+ CDVDVideoCodecIMXIPUBuffer **m_buffers;
|
|
+ int m_currentFieldFmt;
|
|
};
|
|
|
|
|
|
-class CDVDVideoMixerIMX : private CThread {
|
|
+class CDVDVideoMixerIMX : private CThread
|
|
+{
|
|
public:
|
|
CDVDVideoMixerIMX(CDVDVideoCodecIMXIPUBuffers *proc);
|
|
virtual ~CDVDVideoMixerIMX();
|
|
@@ -309,7 +281,6 @@ class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
static void Leave();
|
|
|
|
protected:
|
|
-
|
|
bool VpuOpen();
|
|
bool VpuAllocBuffers(VpuMemInfo *);
|
|
bool VpuFreeBuffers();
|
|
|
|
From 5c8168ca2a215c52b7d2fba81de6b300df87586a Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Tue, 25 Nov 2014 20:00:17 +0100
|
|
Subject: [PATCH 12/18] [imx6] @wolfgar Activated deinterlacer and mixer thread
|
|
|
|
---
|
|
xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 53 +++++---
|
|
xbmc/cores/VideoRenderers/LinuxRendererGLES.h | 3 +
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 141 ++++++++++++---------
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 6 -
|
|
4 files changed, 123 insertions(+), 80 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
index b0229ef..037a57b 100644
|
|
--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
@@ -89,7 +89,12 @@ static PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR;
|
|
#include "windowing/egl/EGLWrapper.h"
|
|
#include "DVDCodecs/Video/DVDVideoCodecIMX.h"
|
|
|
|
+#define GL_VIV_YV12 0x8FC0
|
|
#define GL_VIV_NV12 0x8FC1
|
|
+#define GL_VIV_YUY2 0x8FC2
|
|
+#define GL_VIV_UYVY 0x8FC3
|
|
+#define GL_VIV_NV21 0x8FC4
|
|
+#define GL_VIV_I420 0x8FC5
|
|
typedef void (GL_APIENTRYP PFNGLTEXDIRECTVIVMAPPROC) (GLenum Target, GLsizei Width, GLsizei Height, GLenum Format, GLvoid ** Logical, const GLuint * Physical);
|
|
typedef void (GL_APIENTRYP PFNGLTEXDIRECTINVALIDATEVIVPROC) (GLenum Target);
|
|
static PFNGLTEXDIRECTVIVMAPPROC glTexDirectVIVMap;
|
|
@@ -1237,7 +1242,7 @@ void CLinuxRendererGLES::RenderMultiPass(int index, int field)
|
|
// imgwidth *= planes[0].pixpertex_x;
|
|
// imgheight *= planes[0].pixpertex_y;
|
|
// }
|
|
-//
|
|
+//
|
|
// glBegin(GL_QUADS);
|
|
//
|
|
// glMultiTexCoord2fARB(GL_TEXTURE0, planes[0].rect.x1, planes[0].rect.y1);
|
|
@@ -1683,18 +1688,23 @@ void CLinuxRendererGLES::RenderIMXMAPTexture(int index, int field)
|
|
YUVPLANE &plane = m_buffers[index].fields[field][0];
|
|
CDVDVideoCodecIMXBuffer *buffer = m_buffers[index].IMXBuffer;
|
|
|
|
- if(buffer == NULL) return;
|
|
+#ifdef IMX_PROFILE_BUFFERS
|
|
+ static unsigned long long last = 0;
|
|
+ unsigned long long current = XbmcThreads::SystemClockMillis();
|
|
+ CLog::Log(LOGNOTICE, "+R %x %lld\n", (int)buffer, current-last);
|
|
+ last = current;
|
|
+#endif
|
|
|
|
- CDVDVideoCodecIMX::Enter();
|
|
+ if(buffer == NULL) return;
|
|
|
|
if(!buffer->IsValid())
|
|
{
|
|
- CDVDVideoCodecIMX::Leave();
|
|
return;
|
|
}
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
+ glEnable(m_textureTarget);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(m_textureTarget, plane.id);
|
|
|
|
@@ -1742,10 +1752,9 @@ void CLinuxRendererGLES::RenderIMXMAPTexture(int index, int field)
|
|
VerifyGLState();
|
|
|
|
glBindTexture(m_textureTarget, 0);
|
|
+ glDisable(m_textureTarget);
|
|
VerifyGLState();
|
|
|
|
- CDVDVideoCodecIMX::Leave();
|
|
-
|
|
#ifdef DEBUG_VERBOSE
|
|
CLog::Log(LOGDEBUG, "RenderIMXMAPTexture %d: tm:%d\n", index, XbmcThreads::SystemClockMillis() - time);
|
|
#endif
|
|
@@ -2719,25 +2728,29 @@ void CLinuxRendererGLES::UploadIMXMAPTexture(int index)
|
|
|
|
if(IMXBuffer)
|
|
{
|
|
- CDVDVideoCodecIMX::Enter();
|
|
-
|
|
if(!IMXBuffer->IsValid())
|
|
{
|
|
- CDVDVideoCodecIMX::Leave();
|
|
return;
|
|
}
|
|
|
|
YUVPLANE &plane = m_buffers[index].fields[0][0];
|
|
|
|
+ glEnable(m_textureTarget);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
+
|
|
glBindTexture(m_textureTarget, plane.id);
|
|
|
|
GLuint physical = ~0U;
|
|
GLvoid *virt = (GLvoid*)IMXBuffer->pVirtAddr;
|
|
- glTexDirectVIVMap(m_textureTarget, IMXBuffer->iWidth, IMXBuffer->iHeight, GL_VIV_NV12,
|
|
- (GLvoid **)&virt, &physical);
|
|
- glTexDirectInvalidateVIV(m_textureTarget);
|
|
|
|
+ if (IMXBuffer->iFormat == 0)
|
|
+ glTexDirectVIVMap(m_textureTarget, IMXBuffer->iWidth, IMXBuffer->iHeight, GL_VIV_I420,
|
|
+ (GLvoid **)&virt, &physical);
|
|
+ else
|
|
+ glTexDirectVIVMap(m_textureTarget, IMXBuffer->iWidth, IMXBuffer->iHeight, GL_VIV_NV12,
|
|
+ (GLvoid **)&virt, &physical);
|
|
+
|
|
+ glTexDirectInvalidateVIV(m_textureTarget);
|
|
glBindTexture(m_textureTarget, 0);
|
|
|
|
plane.flipindex = m_buffers[index].flipindex;
|
|
@@ -2746,7 +2759,7 @@ void CLinuxRendererGLES::UploadIMXMAPTexture(int index)
|
|
|
|
CalculateTextureSourceRects(index, 1);
|
|
|
|
- CDVDVideoCodecIMX::Leave();
|
|
+ glDisable(m_textureTarget);
|
|
}
|
|
#endif
|
|
}
|
|
@@ -2864,9 +2877,6 @@ bool CLinuxRendererGLES::Supports(EDEINTERLACEMODE mode)
|
|
if(m_renderMethod & RENDER_CVREF)
|
|
return false;
|
|
|
|
- if(m_renderMethod & RENDER_IMXMAP)
|
|
- return false;
|
|
-
|
|
if(mode == VS_DEINTERLACEMODE_AUTO
|
|
|| mode == VS_DEINTERLACEMODE_FORCE)
|
|
return true;
|
|
@@ -2901,6 +2911,15 @@ bool CLinuxRendererGLES::Supports(EINTERLACEMETHOD method)
|
|
if(method == VS_INTERLACEMETHOD_AUTO)
|
|
return true;
|
|
|
|
+ if(m_renderMethod & RENDER_IMXMAP)
|
|
+ { /*
|
|
+ if(method == VS_INTERLACEMETHOD_DEINTERLACE
|
|
+ || method == VS_INTERLACEMETHOD_DEINTERLACE_HALF)
|
|
+ return true;
|
|
+ else*/
|
|
+ return false;
|
|
+ }
|
|
+
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
if(method == VS_INTERLACEMETHOD_DEINTERLACE
|
|
|| method == VS_INTERLACEMETHOD_DEINTERLACE_HALF
|
|
@@ -2966,6 +2985,8 @@ unsigned int CLinuxRendererGLES::GetOptimalBufferSize()
|
|
m_format == RENDER_FMT_EGLIMG ||
|
|
m_format == RENDER_FMT_MEDIACODEC)
|
|
return 2;
|
|
+ else if(m_format == RENDER_FMT_IMXMAP)
|
|
+ return 1;
|
|
else
|
|
return 3;
|
|
}
|
|
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h
|
|
index d8bf35d..0532c19 100644
|
|
--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h
|
|
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.h
|
|
@@ -42,6 +42,9 @@ namespace Shaders { class BaseVideoFilterShader; }
|
|
class COpenMaxVideo;
|
|
class CDVDVideoCodecStageFright;
|
|
class CDVDMediaCodecInfo;
|
|
+#ifdef HAS_IMXVPU
|
|
+class CDVDVideoCodecIMXBuffer;
|
|
+#endif
|
|
typedef std::vector<int> Features;
|
|
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index 59187e8..f841380 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -44,7 +44,6 @@
|
|
// Experiments show that we need at least one more (+1) VPU buffer than the min value returned by the VPU
|
|
const int CDVDVideoCodecIMX::m_extraVpuBuffers = 6;
|
|
const int CDVDVideoCodecIMX::m_maxVpuDecodeLoops = 5;
|
|
-CCriticalSection CDVDVideoCodecIMX::m_codecBufferLock;
|
|
|
|
bool CDVDVideoCodecIMX::VpuAllocBuffers(VpuMemInfo *pMemBlock)
|
|
{
|
|
@@ -557,6 +556,8 @@ bool CDVDVideoCodecIMX::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
|
|
return false;
|
|
}
|
|
|
|
+ m_mixer.Start();
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -565,12 +566,12 @@ void CDVDVideoCodecIMX::Dispose(void)
|
|
VpuDecRetCode ret;
|
|
bool VPU_loaded = m_vpuHandle;
|
|
|
|
- // Prevent rendering thread from using frame buffers
|
|
- Enter();
|
|
+ // Dispose the mixer thread
|
|
+ m_mixer.Dispose();
|
|
|
|
// Release last buffer
|
|
- if(m_lastBuffer)
|
|
- SAFE_RELEASE(m_lastBuffer);
|
|
+ SAFE_RELEASE(m_lastBuffer);
|
|
+ SAFE_RELEASE(m_currentBuffer);
|
|
|
|
// Invalidate output buffers to prevent the renderer from mapping this memory
|
|
for (int i=0; i<m_vpuFrameBufferNum; i++)
|
|
@@ -579,8 +580,6 @@ void CDVDVideoCodecIMX::Dispose(void)
|
|
SAFE_RELEASE(m_outputBuffers[i]);
|
|
}
|
|
|
|
- Leave();
|
|
-
|
|
if (m_vpuHandle)
|
|
{
|
|
ret = VPU_DecFlushAll(m_vpuHandle);
|
|
@@ -648,6 +647,8 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts)
|
|
unsigned long long before_dec;
|
|
#endif
|
|
|
|
+ SAFE_RELEASE(m_currentBuffer);
|
|
+
|
|
if (!m_vpuHandle)
|
|
{
|
|
VpuOpen();
|
|
@@ -704,6 +705,10 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts)
|
|
inData.sCodecData.nSize = 0;
|
|
}
|
|
|
|
+#ifdef IMX_PROFILE_BUFFERS
|
|
+ static unsigned long long dec_time = 0;
|
|
+#endif
|
|
+
|
|
while (true) // Decode as long as the VPU consumes data
|
|
{
|
|
#ifdef IMX_PROFILE
|
|
@@ -711,7 +716,11 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts)
|
|
#endif
|
|
if (m_frameReported)
|
|
m_bytesToBeConsumed += inData.nSize;
|
|
+ unsigned long long before_dec = XbmcThreads::SystemClockMillis();
|
|
ret = VPU_DecDecodeBuf(m_vpuHandle, &inData, &decRet);
|
|
+#ifdef IMX_PROFILE_BUFFERS
|
|
+ dec_time += XbmcThreads::SystemClockMillis()-before_dec;
|
|
+#endif
|
|
#ifdef IMX_PROFILE
|
|
CLog::Log(LOGDEBUG, "%s - VPU dec 0x%x decode takes : %lld\n\n", __FUNCTION__, decRet, XbmcThreads::SystemClockMillis() - before_dec);
|
|
#endif
|
|
@@ -802,14 +811,64 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts)
|
|
m_frameInfo.pExtInfo->nFrmWidth = (((m_frameInfo.pExtInfo->nFrmWidth) + 15) & ~15);
|
|
m_frameInfo.pExtInfo->nFrmHeight = (((m_frameInfo.pExtInfo->nFrmHeight) + 15) & ~15);
|
|
|
|
- /* quick & dirty fix to get proper timestamping for VP8 codec */
|
|
- if (m_decOpenParam.CodecFormat == VPU_V_VP8)
|
|
+ idx = VpuFindBuffer(m_frameInfo.pDisplayFrameBuf->pbufY);
|
|
+ if (idx != -1)
|
|
{
|
|
- idx = VpuFindBuffer(m_frameInfo.pDisplayFrameBuf->pbufY);
|
|
- m_outputBuffers[idx]->SetPts(pts);
|
|
- }
|
|
+ CDVDVideoCodecIMXVPUBuffer *buffer = m_outputBuffers[idx];
|
|
+ /* quick & dirty fix to get proper timestamping for VP8 codec */
|
|
+ if (m_decOpenParam.CodecFormat == VPU_V_VP8)
|
|
+ buffer->SetPts(pts);
|
|
|
|
- retStatus |= VC_PICTURE;
|
|
+ buffer->Lock();
|
|
+ buffer->SetDts(dts);
|
|
+ buffer->Queue(&m_frameInfo, m_lastBuffer);
|
|
+
|
|
+#ifdef IMX_PROFILE_BUFFERS
|
|
+ CLog::Log(LOGNOTICE, "+D %x %lld\n", buffer, dec_time);
|
|
+ dec_time = 0;
|
|
+#endif
|
|
+
|
|
+#ifdef TRACE_FRAMES
|
|
+ CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, pDvdVideoPicture->dts, pDvdVideoPicture->pts);
|
|
+#endif
|
|
+
|
|
+ if (!m_usePTS)
|
|
+ {
|
|
+ buffer->SetPts(DVD_NOPTS_VALUE);
|
|
+ buffer->SetDts(DVD_NOPTS_VALUE);
|
|
+ }
|
|
+
|
|
+ // Save last buffer
|
|
+ SAFE_RELEASE(m_lastBuffer);
|
|
+ m_lastBuffer = buffer;
|
|
+ m_lastBuffer->Lock();
|
|
+
|
|
+#ifdef IMX_PROFILE_BUFFERS
|
|
+ static unsigned long long lastD = 0;
|
|
+ unsigned long long current = XbmcThreads::SystemClockMillis(), tmp;
|
|
+ CLog::Log(LOGNOTICE, "+V %x %lld\n", buffer, current-lastD);
|
|
+ lastD = current;
|
|
+#endif
|
|
+
|
|
+ //m_currentBuffer = buffer;
|
|
+ if (m_dropState)
|
|
+ {
|
|
+ m_currentBuffer = m_mixer.Process(NULL);
|
|
+ if (!m_currentBuffer)
|
|
+ m_currentBuffer = buffer;
|
|
+ else
|
|
+ buffer->Release();
|
|
+ }
|
|
+ else
|
|
+ m_currentBuffer = m_mixer.Process(buffer);
|
|
+
|
|
+ if (m_currentBuffer)
|
|
+ {
|
|
+ retStatus |= VC_PICTURE;
|
|
+ //m_currentBuffer->Release();
|
|
+ //m_currentBuffer = NULL;
|
|
+ }
|
|
+ }
|
|
} //VPU_DEC_OUTPUT_DIS
|
|
|
|
// According to libfslvpuwrap: If this flag is set then the frame should
|
|
@@ -901,8 +960,6 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts)
|
|
// at next call...
|
|
m_previousPts = pts;
|
|
}
|
|
- // Store current dts (will be used only if VC_PICTURE is set)
|
|
- m_dts = dts;
|
|
|
|
#ifdef IMX_PROFILE
|
|
CLog::Log(LOGDEBUG, "%s - returns %x - duration %lld\n", __FUNCTION__, retStatus, XbmcThreads::SystemClockMillis() - previous);
|
|
@@ -920,9 +977,13 @@ void CDVDVideoCodecIMX::Reset()
|
|
if (g_advancedSettings.CanLogComponent(LOGVIDEO))
|
|
CLog::Log(LOGDEBUG, "%s - called\n", __FUNCTION__);
|
|
|
|
+ // Restart mixer
|
|
+ m_mixer.Dispose();
|
|
+ m_mixer.Start();
|
|
+
|
|
// Release last buffer
|
|
- if(m_lastBuffer)
|
|
- SAFE_RELEASE(m_lastBuffer);
|
|
+ SAFE_RELEASE(m_lastBuffer);
|
|
+ SAFE_RELEASE(m_currentBuffer);
|
|
|
|
// Invalidate all buffers
|
|
for(int i=0; i < m_vpuFrameBufferNum; i++)
|
|
@@ -983,38 +1044,12 @@ bool CDVDVideoCodecIMX::GetPicture(DVDVideoPicture* pDvdVideoPicture)
|
|
pDvdVideoPicture->iDisplayWidth = ((pDvdVideoPicture->iWidth * m_frameInfo.pExtInfo->nQ16ShiftWidthDivHeightRatio) + 32767) >> 16;
|
|
pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight;
|
|
|
|
- int idx = VpuFindBuffer(m_frameInfo.pDisplayFrameBuf->pbufY);
|
|
- if (idx != -1)
|
|
- {
|
|
- CDVDVideoCodecIMXVPUBuffer *buffer = m_outputBuffers[idx];
|
|
-
|
|
- pDvdVideoPicture->pts = buffer->GetPts();
|
|
- pDvdVideoPicture->dts = m_dts;
|
|
- if (!m_usePTS)
|
|
- {
|
|
- pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
|
|
- pDvdVideoPicture->dts = DVD_NOPTS_VALUE;
|
|
- }
|
|
-
|
|
- buffer->Queue(&m_frameInfo, m_lastBuffer);
|
|
-
|
|
-#ifdef TRACE_FRAMES
|
|
- CLog::Log(LOGDEBUG, "+ %02d dts %f pts %f (VPU)\n", idx, pDvdVideoPicture->dts, pDvdVideoPicture->pts);
|
|
-#endif
|
|
-
|
|
- pDvdVideoPicture->IMXBuffer = buffer;
|
|
- pDvdVideoPicture->IMXBuffer->Lock();
|
|
+ // Current buffer is locked already -> hot potato
|
|
+ pDvdVideoPicture->pts = m_currentBuffer->GetPts();
|
|
+ pDvdVideoPicture->dts = m_currentBuffer->GetDts();
|
|
|
|
- // Save last buffer
|
|
- if (m_lastBuffer)
|
|
- SAFE_RELEASE(m_lastBuffer);
|
|
- m_lastBuffer = buffer;
|
|
- m_lastBuffer->Lock();
|
|
- }
|
|
- else
|
|
- {
|
|
- CLog::Log(LOGERROR, "%s - could not find frame buffer\n", __FUNCTION__);
|
|
- }
|
|
+ pDvdVideoPicture->IMXBuffer = m_currentBuffer;
|
|
+ m_currentBuffer = NULL;
|
|
|
|
return true;
|
|
}
|
|
@@ -1035,16 +1070,6 @@ void CDVDVideoCodecIMX::SetDropState(bool bDrop)
|
|
}
|
|
}
|
|
|
|
-void CDVDVideoCodecIMX::Enter()
|
|
-{
|
|
- m_codecBufferLock.lock();
|
|
-}
|
|
-
|
|
-void CDVDVideoCodecIMX::Leave()
|
|
-{
|
|
- m_codecBufferLock.unlock();
|
|
-}
|
|
-
|
|
/*******************************************/
|
|
#ifdef TRACE_FRAMES
|
|
CDVDVideoCodecIMXBuffer::CDVDVideoCodecIMXBuffer(int idx)
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index 7c0e7da..6af8130 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -277,9 +277,6 @@ class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
virtual const char* GetName(void) { return (const char*)m_pFormatName; }
|
|
virtual unsigned GetAllowedReferences();
|
|
|
|
- static void Enter();
|
|
- static void Leave();
|
|
-
|
|
protected:
|
|
bool VpuOpen();
|
|
bool VpuAllocBuffers(VpuMemInfo *);
|
|
@@ -289,8 +286,6 @@ class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
|
|
static const int m_extraVpuBuffers; // Number of additional buffers for VPU
|
|
static const int m_maxVpuDecodeLoops; // Maximum iterations in VPU decoding loop
|
|
- static CCriticalSection m_codecBufferLock; // Lock to protect buffers handled
|
|
- // by both decoding and rendering threads
|
|
|
|
CDVDStreamInfo m_hints; // Hints from demuxer at stream opening
|
|
const char *m_pFormatName; // Current decoder format name
|
|
@@ -315,5 +310,4 @@ class CDVDVideoCodecIMX : public CDVDVideoCodec
|
|
int m_bytesToBeConsumed; // Remaining bytes in VPU
|
|
double m_previousPts; // Enable to keep pts when needed
|
|
bool m_frameReported; // State whether the frame consumed event will be reported by libfslvpu
|
|
- double m_dts; // Current dts
|
|
};
|
|
|
|
From a9f1458a4b43f722db4d115e1b5e0a1c4d81f72f Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Wed, 26 Nov 2014 01:11:54 +0100
|
|
Subject: [PATCH 13/18] [imx] @wolfgar return 3 in
|
|
LinuxRendererGLES::GetOptimalBufferSize for IMX render path
|
|
|
|
---
|
|
xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
index 037a57b..35c905b 100644
|
|
--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
@@ -2986,7 +2986,7 @@ unsigned int CLinuxRendererGLES::GetOptimalBufferSize()
|
|
m_format == RENDER_FMT_MEDIACODEC)
|
|
return 2;
|
|
else if(m_format == RENDER_FMT_IMXMAP)
|
|
- return 1;
|
|
+ return 3;
|
|
else
|
|
return 3;
|
|
}
|
|
|
|
From b3c24108ad8f61989f9fbbeab605c021782889f4 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Thu, 27 Nov 2014 22:39:10 +0100
|
|
Subject: [PATCH 14/18] [imx] @wolfgar Corrected some comments, fixed iFormat
|
|
along with IMX_OUTPUT_FORMAT_I420
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 9 +++++----
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 4 ++--
|
|
2 files changed, 7 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index f841380..511956d 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -644,6 +644,8 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts)
|
|
|
|
#ifdef IMX_PROFILE
|
|
static unsigned long long previous, current;
|
|
+#endif
|
|
+#if defined(IMX_PROFILE) || defined(IMX_PROFILE_BUFFERS)
|
|
unsigned long long before_dec;
|
|
#endif
|
|
|
|
@@ -711,12 +713,11 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts)
|
|
|
|
while (true) // Decode as long as the VPU consumes data
|
|
{
|
|
-#ifdef IMX_PROFILE
|
|
+#if defined(IMX_PROFILE) || defined(IMX_PROFILE_BUFFERS)
|
|
before_dec = XbmcThreads::SystemClockMillis();
|
|
#endif
|
|
if (m_frameReported)
|
|
m_bytesToBeConsumed += inData.nSize;
|
|
- unsigned long long before_dec = XbmcThreads::SystemClockMillis();
|
|
ret = VPU_DecDecodeBuf(m_vpuHandle, &inData, &decRet);
|
|
#ifdef IMX_PROFILE_BUFFERS
|
|
dec_time += XbmcThreads::SystemClockMillis()-before_dec;
|
|
@@ -1125,7 +1126,7 @@ long CDVDVideoCodecIMXVPUBuffer::Release()
|
|
#endif
|
|
if (count == 2)
|
|
{
|
|
- // Only referenced by the coded and its next frame, release the previous
|
|
+ // Only referenced by the codec and its next frame, release the previous
|
|
SAFE_RELEASE(m_previousBuffer);
|
|
}
|
|
if (count == 1)
|
|
@@ -1308,7 +1309,7 @@ bool CDVDVideoCodecIMXIPUBuffer::Process(int fd, CDVDVideoCodecIMXVPUBuffer *buf
|
|
task.output.height = iHeight;
|
|
#ifdef IMX_OUTPUT_FORMAT_I420
|
|
task.output.format = IPU_PIX_FMT_YUV420P;
|
|
- format = 0;
|
|
+ iFormat = 0;
|
|
#else
|
|
task.output.format = IPU_PIX_FMT_NV12;
|
|
iFormat = 1;
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index 6af8130..d9aadc9 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -38,8 +38,8 @@
|
|
// The IPU works faster when outputting to NV12.
|
|
//#define IMX_OUTPUT_FORMAT_I420
|
|
|
|
-// This enables logging of times for Decode->Decode, Render->Render,
|
|
-// Deinterlace->Deinterlace. It helps to profile several stages of
|
|
+// This enables logging of times for Decode, Render->Render,
|
|
+// Deinterlace. It helps to profile several stages of
|
|
// processing with respect to changed kernels or other configurations.
|
|
// Since we utilize VPU, IPU and GPU at the same time different kernel
|
|
// priorities to those subsystems can result in a very different user
|
|
|
|
From 4eff53acf4e0dfe892a484ec7355bc60aafda6c0 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Thu, 27 Nov 2014 22:42:36 +0100
|
|
Subject: [PATCH 15/18] [imx] @wolfgar Enable LOW_MOTION for SD content
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index 511956d..51ec5d8 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -1818,9 +1818,11 @@ CDVDVideoCodecIMXBuffer *CDVDVideoMixerIMX::ProcessFrame(CDVDVideoCodecIMXVPUBuf
|
|
Sleep(35);
|
|
outputBuffer = inputBuffer;
|
|
#else
|
|
+ // Enable low motion for buffers that are not split up by the VDIC
|
|
+ bool lowMotion = (inputBuffer->iWidth < 1024) && (inputBuffer->iHeight < 1024);
|
|
outputBuffer = m_proc->Process(inputBuffer,
|
|
inputBuffer->GetFieldType(),
|
|
- false);
|
|
+ lowMotion);
|
|
#endif
|
|
#ifdef IMX_PROFILE_BUFFERS
|
|
CLog::Log(LOGNOTICE, "+P %x %lld\n", (int)outputBuffer,
|
|
|
|
From 021f9599d77a0579f278c3f8d4a9ea474f71c177 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Fri, 28 Nov 2014 23:42:09 +0100
|
|
Subject: [PATCH 16/18] [imx] @wolfgar Removed commented lines and removed
|
|
WRITE flag for read only mapped buffers
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 6 +-----
|
|
1 file changed, 1 insertion(+), 5 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index 51ec5d8..d20028f 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -864,11 +864,7 @@ int CDVDVideoCodecIMX::Decode(BYTE *pData, int iSize, double dts, double pts)
|
|
m_currentBuffer = m_mixer.Process(buffer);
|
|
|
|
if (m_currentBuffer)
|
|
- {
|
|
retStatus |= VC_PICTURE;
|
|
- //m_currentBuffer->Release();
|
|
- //m_currentBuffer = NULL;
|
|
- }
|
|
}
|
|
} //VPU_DEC_OUTPUT_DIS
|
|
|
|
@@ -1400,7 +1396,7 @@ bool CDVDVideoCodecIMXIPUBuffer::Allocate(int fd, int width, int height, int nAl
|
|
CLog::Log(LOGNOTICE, "IPU: alloc %d bytes for frame of %dx%d at 0x%x\n",
|
|
m_nSize, m_iWidth, m_iHeight, m_pPhyAddr);
|
|
|
|
- m_pVirtAddr = (uint8_t*)mmap(0, m_nSize, PROT_READ | PROT_WRITE, MAP_SHARED,
|
|
+ m_pVirtAddr = (uint8_t*)mmap(0, m_nSize, PROT_READ, MAP_SHARED,
|
|
fd, m_pPhyAddr);
|
|
if (!m_pVirtAddr)
|
|
{
|
|
|
|
From ea72d307c53eb417c6d2bb898cae438e34b62c89 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Fri, 5 Dec 2014 17:02:36 +0000
|
|
Subject: [PATCH 17/18] [imx] @wolfgar Added VDI buffer splitting to bypass
|
|
kernel splitting algorithms which introduces some DMA memory burst penalties
|
|
|
|
---
|
|
xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 8 ++-
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 62 +++++++++++++++++++---
|
|
.../dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h | 17 ++++--
|
|
3 files changed, 76 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
index 35c905b..0364a6c 100644
|
|
--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
+++ b/xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp
|
|
@@ -2746,9 +2746,15 @@ void CLinuxRendererGLES::UploadIMXMAPTexture(int index)
|
|
if (IMXBuffer->iFormat == 0)
|
|
glTexDirectVIVMap(m_textureTarget, IMXBuffer->iWidth, IMXBuffer->iHeight, GL_VIV_I420,
|
|
(GLvoid **)&virt, &physical);
|
|
- else
|
|
+ else if (IMXBuffer->iFormat == 1)
|
|
glTexDirectVIVMap(m_textureTarget, IMXBuffer->iWidth, IMXBuffer->iHeight, GL_VIV_NV12,
|
|
(GLvoid **)&virt, &physical);
|
|
+ else if (IMXBuffer->iFormat == 2)
|
|
+ glTexDirectVIVMap(m_textureTarget, IMXBuffer->iWidth, IMXBuffer->iHeight, GL_RGB565,
|
|
+ (GLvoid **)&virt, &physical);
|
|
+ else if (IMXBuffer->iFormat == 3)
|
|
+ glTexDirectVIVMap(m_textureTarget, IMXBuffer->iWidth, IMXBuffer->iHeight, GL_RGBA,
|
|
+ (GLvoid **)&virt, &physical);
|
|
|
|
glTexDirectInvalidateVIV(m_textureTarget);
|
|
glBindTexture(m_textureTarget, 0);
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index d20028f..f556223 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -36,6 +36,7 @@
|
|
#include "utils/log.h"
|
|
#include "DVDClock.h"
|
|
|
|
+#define IMX_MDI_MAX_WIDTH 968
|
|
#define FRAME_ALIGN 16
|
|
#define MEDIAINFO 1
|
|
#define _4CC(c1,c2,c3,c4) (((uint32_t)(c4)<<24)|((uint32_t)(c3)<<16)|((uint32_t)(c2)<<8)|(uint32_t)(c1))
|
|
@@ -1294,6 +1295,8 @@ bool CDVDVideoCodecIMXIPUBuffer::Process(int fd, CDVDVideoCodecIMXVPUBuffer *buf
|
|
// Input is the VPU decoded frame
|
|
task.input.width = iWidth;
|
|
task.input.height = iHeight;
|
|
+ task.input.crop.h = iHeight;
|
|
+
|
|
#ifdef IMX_INPUT_FORMAT_I420
|
|
task.input.format = IPU_PIX_FMT_YUV420P;
|
|
#else
|
|
@@ -1303,6 +1306,7 @@ bool CDVDVideoCodecIMXIPUBuffer::Process(int fd, CDVDVideoCodecIMXVPUBuffer *buf
|
|
// Output is our IPU buffer
|
|
task.output.width = iWidth;
|
|
task.output.height = iHeight;
|
|
+ task.output.crop.h = iHeight;
|
|
#ifdef IMX_OUTPUT_FORMAT_I420
|
|
task.output.format = IPU_PIX_FMT_YUV420P;
|
|
iFormat = 0;
|
|
@@ -1310,6 +1314,14 @@ bool CDVDVideoCodecIMXIPUBuffer::Process(int fd, CDVDVideoCodecIMXVPUBuffer *buf
|
|
task.output.format = IPU_PIX_FMT_NV12;
|
|
iFormat = 1;
|
|
#endif
|
|
+#ifdef IMX_OUTPUT_FORMAT_RGB565
|
|
+ task.output.format = IPU_PIX_FMT_RGB565;
|
|
+ iFormat = 2;
|
|
+#endif
|
|
+#ifdef IMX_OUTPUT_FORMAT_RGB32
|
|
+ task.output.format = IPU_PIX_FMT_RGB32;
|
|
+ iFormat = 3;
|
|
+#endif
|
|
task.output.paddr = (int)pPhysAddr;
|
|
|
|
// Fill current and next buffer address
|
|
@@ -1345,15 +1357,42 @@ bool CDVDVideoCodecIMXIPUBuffer::Process(int fd, CDVDVideoCodecIMXVPUBuffer *buf
|
|
#ifdef IMX_PROFILE
|
|
unsigned int time = XbmcThreads::SystemClockMillis();
|
|
#endif
|
|
- int ret = ioctl(fd, IPU_QUEUE_TASK, &task);
|
|
+
|
|
+ /* We do the VDI buffer splitting ourselves since the kernel
|
|
+ * driver (IPU) is either buggy or it is a feature that it does
|
|
+ * not split widths to multiple of 16 to get maximum burst on
|
|
+ * on DMA. Since we know that the input and output dimensions are the
|
|
+ * same we can implement an easier algorithm that takes care of
|
|
+ * that.
|
|
+ */
|
|
+ unsigned int nRequiredStripes = (iWidth+IMX_MDI_MAX_WIDTH-1) / IMX_MDI_MAX_WIDTH;
|
|
+ unsigned int iProcWidth = iWidth;
|
|
+ unsigned int iStripeOffset = 0;
|
|
+
|
|
+ while (iStripeOffset < iWidth)
|
|
+ {
|
|
+ unsigned int iStripeWidth = Align(iWidth/nRequiredStripes, FRAME_ALIGN);
|
|
+ if (iStripeWidth > iProcWidth)
|
|
+ iStripeWidth = iProcWidth;
|
|
+
|
|
+ task.input.crop.pos.x = iStripeOffset;
|
|
+ task.input.crop.w = iStripeWidth;
|
|
+ task.output.crop.pos.x = task.input.crop.pos.x;
|
|
+ task.output.crop.w = task.input.crop.w;
|
|
+
|
|
+ if (ioctl(fd, IPU_QUEUE_TASK, &task) < 0)
|
|
+ {
|
|
+ CLog::Log(LOGERROR, "IPU task failed: %s\n", strerror(errno));
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ iStripeOffset += iStripeWidth;
|
|
+ iProcWidth -= iStripeWidth;
|
|
+ }
|
|
+
|
|
#ifdef IMX_PROFILE
|
|
CLog::Log(LOGDEBUG, "DEINT: tm:%d\n", XbmcThreads::SystemClockMillis() - time);
|
|
#endif
|
|
- if (ret < 0)
|
|
- {
|
|
- CLog::Log(LOGERROR, "IPU task failed: %s\n", strerror(errno));
|
|
- return false;
|
|
- }
|
|
|
|
m_bFree = false;
|
|
buffer->Lock();
|
|
@@ -1379,8 +1418,19 @@ bool CDVDVideoCodecIMXIPUBuffer::Allocate(int fd, int width, int height, int nAl
|
|
{
|
|
m_iWidth = Align(width,FRAME_ALIGN);
|
|
m_iHeight = Align(height,(2*FRAME_ALIGN));
|
|
+#if defined(IMX_OUTPUT_FORMAT_NV12) || defined(IMX_OUTPUT_FORMAT_I420)
|
|
// I420 == 12 bpp
|
|
m_nSize = m_iWidth*m_iHeight*12/8;
|
|
+#endif
|
|
+#ifdef IMX_OUTPUT_FORMAT_RGB565
|
|
+ // RGB565 = 16 bpp
|
|
+ m_nSize = m_iWidth*m_iHeight*16/8;
|
|
+#endif
|
|
+#ifdef IMX_OUTPUT_FORMAT_RGB32
|
|
+ // RGB32 = 32 bpp
|
|
+ m_nSize = m_iWidth*m_iHeight*32/8;
|
|
+#endif
|
|
+
|
|
m_pPhyAddr = m_nSize;
|
|
|
|
pPhysAddr = pVirtAddr = NULL;
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
index d9aadc9..f44168b 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.h
|
|
@@ -31,12 +31,16 @@
|
|
|
|
|
|
// The decoding format of the VPU buffer. Comment this to decode
|
|
-// as NV12. The VPU works faster with I420.
|
|
-#define IMX_INPUT_FORMAT_I420
|
|
+// as NV12. The VPU works faster with NV12 in combination with
|
|
+// deinterlacing.
|
|
+//#define IMX_INPUT_FORMAT_I420
|
|
|
|
-// The deinterlacer output and render format. Uncomment to use I420.
|
|
-// The IPU works faster when outputting to NV12.
|
|
+// The deinterlacer output and render format. Only one format must be active
|
|
+// at a time
|
|
+#define IMX_OUTPUT_FORMAT_NV12
|
|
//#define IMX_OUTPUT_FORMAT_I420
|
|
+//#define IMX_OUTPUT_FORMAT_RGB565
|
|
+//#define IMX_OUTPUT_FORMAT_RGB32
|
|
|
|
// This enables logging of times for Decode, Render->Render,
|
|
// Deinterlace. It helps to profile several stages of
|
|
@@ -50,6 +54,11 @@
|
|
//#define IMX_PROFILE
|
|
//#define TRACE_FRAMES
|
|
|
|
+// If uncommented a file "stream.dump" will be created in the current
|
|
+// directory whenever a new stream is started. This is only for debugging
|
|
+// and performance tests. This define must never be active in distributions.
|
|
+//#define DUMP_STREAM
|
|
+
|
|
class CDecMemInfo
|
|
{
|
|
public:
|
|
|
|
From 3c6b55e684e821c0ddedcd8fbb86b19363ce8f39 Mon Sep 17 00:00:00 2001
|
|
From: smallint <tahoma@gmx.de>
|
|
Date: Fri, 5 Dec 2014 17:58:36 +0000
|
|
Subject: [PATCH 18/18] [imx] @wolfgar Removed IPU task priority setting
|
|
|
|
---
|
|
xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp | 1 -
|
|
1 file changed, 1 deletion(-)
|
|
|
|
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
index f556223..5c2b021 100644
|
|
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecIMX.cpp
|
|
@@ -1281,7 +1281,6 @@ bool CDVDVideoCodecIMXIPUBuffer::Process(int fd, CDVDVideoCodecIMXVPUBuffer *buf
|
|
CDVDVideoCodecIMXVPUBuffer *previousBuffer;
|
|
struct ipu_task task;
|
|
memset(&task, 0, sizeof(task));
|
|
- task.priority = IPU_TASK_PRIORITY_HIGH;
|
|
|
|
if (lowMotion)
|
|
previousBuffer = buffer->GetPreviousBuffer();
|