Skip to content

Commit

Permalink
Support for 192-byte TS packets added to TsReader (as used for BD/AVC…
Browse files Browse the repository at this point in the history
…HD files).
  • Loading branch information
owlsroost committed Aug 5, 2016
1 parent 7e956e7 commit 585518e
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 34 deletions.
108 changes: 79 additions & 29 deletions DirectShowFilters/DvbCoreUtils/PacketSync.cpp
Expand Up @@ -28,6 +28,7 @@ CPacketSync::CPacketSync(void)
m_tempBufferPos = -1;
m_bInSync = false;
m_bFirstSynced = false;
m_packet_len = TS_PACKET_LEN;
}

CPacketSync::~CPacketSync(void)
Expand All @@ -39,6 +40,7 @@ void CPacketSync::Reset(void)
m_tempBufferPos = -1;
m_bInSync = false;
m_bFirstSynced = false;
m_packet_len = TS_PACKET_LEN;
}

// Ambass : Now, need to have 2 consecutive TS_PACKET_SYNC to try avoiding bad synchronisation.
Expand Down Expand Up @@ -168,23 +170,25 @@ void CPacketSync::OnRawData(byte* pData, int nDataLen)
// Ambass : Now, need to have 2 consecutive TS_PACKET_SYNC to try avoiding bad synchronisation.
// In case of data flow change ( Seek, tv Zap .... ) Reset() should be called first to flush buffer.
// Owlsroost : This version will abandon a buffer if it fails to sync within 8 * TSpacket lengths
void CPacketSync::OnRawData2(byte* pData, int nDataLen)
// Owlsroost : Modified to automatically handle 192 byte (e.g. BD/AVCHD) and 188 byte packet sizes.
// Only the basic 188 byte packet data is passed on for '192 byte' streams.
bool CPacketSync::OnRawData2(byte* pData, int nDataLen)
{
int syncOffset=0;
int tempBuffOffset=0;
bool goodPacket = false;

if (m_tempBufferPos > 0 ) //We have some residual data from the last call
if (m_tempBufferPos > 0 && m_bInSync) //We have some residual data from the last call, and we know the packet length
{
syncOffset = TS_PACKET_LEN - m_tempBufferPos;
syncOffset = m_packet_len - m_tempBufferPos;

if (nDataLen <= syncOffset)
{
//not enough total data to scan through a packet length,
//so add pData to the tempBuffer and return
memcpy(&m_tempBuffer[m_tempBufferPos], pData, nDataLen);
m_tempBufferPos += nDataLen;
return ;
return false ;
}

while ((nDataLen > syncOffset) && (m_tempBufferPos > tempBuffOffset))
Expand All @@ -198,7 +202,6 @@ void CPacketSync::OnRawData2(byte* pData, int nDataLen)
}
OnTsPacket(&m_tempBuffer[tempBuffOffset], syncOffset, nDataLen);
goodPacket = true;
m_bInSync = true;
break;
}
else if (m_bInSync &&
Expand Down Expand Up @@ -240,54 +243,99 @@ void CPacketSync::OnRawData2(byte* pData, int nDataLen)
//add pData to the tempBuffer and return
memcpy(&m_tempBuffer[m_tempBufferPos], pData, nDataLen);
m_tempBufferPos += nDataLen;
return;
return false;
}
}
}

m_tempBufferPos = 0; //We have consumed the residual data

while (nDataLen > (syncOffset + TS_PACKET_LEN)) //minimum of TS_PACKET_LEN+1 bytes available
while (nDataLen > (syncOffset + M2TS_PACKET_LEN)) //minimum of M2TS_PACKET_LEN+1 bytes available
{
if (!goodPacket && (syncOffset > (TS_PACKET_LEN * 8)) )
if (!goodPacket && (syncOffset > (M2TS_PACKET_LEN * 8)) )
{
//No sync - abandon the buffer
Reset();
return;
return false;
}

if ((pData[syncOffset] == TS_PACKET_SYNC) &&
(pData[syncOffset + TS_PACKET_LEN]==TS_PACKET_SYNC))

if (!m_bInSync)
{
if ((pData[syncOffset] == TS_PACKET_SYNC) &&
(pData[syncOffset + M2TS_PACKET_LEN]==TS_PACKET_SYNC) &&
(pData[syncOffset + TS_PACKET_LEN]!=TS_PACKET_SYNC))
{
m_bInSync = true;
m_packet_len = M2TS_PACKET_LEN;
}
else if ((pData[syncOffset] == TS_PACKET_SYNC) &&
(pData[syncOffset + TS_PACKET_LEN]==TS_PACKET_SYNC) &&
(pData[syncOffset + M2TS_PACKET_LEN]!=TS_PACKET_SYNC))
{
m_bInSync = true;
m_packet_len = TS_PACKET_LEN;
}
}

if (m_bInSync &&
((pData[syncOffset] == TS_PACKET_SYNC) &&
(pData[syncOffset + m_packet_len]==TS_PACKET_SYNC)))
{
OnTsPacket( &pData[syncOffset], syncOffset, nDataLen );
syncOffset += TS_PACKET_LEN;
syncOffset += m_packet_len;
goodPacket = true;
m_bInSync = true;
}
else if (m_bInSync &&
((pData[syncOffset] == TS_PACKET_SYNC) ||
(pData[syncOffset + TS_PACKET_LEN]==TS_PACKET_SYNC)))
(pData[syncOffset + m_packet_len]==TS_PACKET_SYNC)))
{
pData[syncOffset] = TS_PACKET_SYNC;
pData[syncOffset + TS_PACKET_LEN] = TS_PACKET_SYNC;
pData[syncOffset + m_packet_len] = TS_PACKET_SYNC;
OnTsPacket( &pData[syncOffset], syncOffset, nDataLen );
syncOffset += TS_PACKET_LEN;
syncOffset += m_packet_len;
goodPacket = true;
m_bInSync = false;
}
else
{
syncOffset++;
m_bInSync = false;
}
}
}

// We have less than TS_PACKET_LEN+1 bytes available - store residual data for next time
m_tempBufferPos= nDataLen - syncOffset;
if (m_tempBufferPos)

if (m_bInSync)
{
memcpy( m_tempBuffer, &pData[syncOffset], m_tempBufferPos );
//Catch and process TS_PACKET_LEN (only) size packets at end of buffer
while (nDataLen > (syncOffset + m_packet_len)) //minimum of TS_PACKET_LEN+1 bytes available
{
if ((pData[syncOffset] == TS_PACKET_SYNC) &&
(pData[syncOffset + m_packet_len]==TS_PACKET_SYNC))
{
OnTsPacket( &pData[syncOffset], syncOffset, nDataLen );
syncOffset += m_packet_len;
goodPacket = true;
}
else
{
syncOffset++;
m_bInSync = false;
}
}

// We have less than m_packet_len+1 bytes available - store residual data for next time
m_tempBufferPos = nDataLen - syncOffset;
if (m_tempBufferPos)
{
memcpy( m_tempBuffer, &pData[syncOffset], m_tempBufferPos );
}
}
else if (nDataLen < (M2TS_PACKET_LEN * 5))
{
//No sync and short buffer
return true;
}

return false;
}


Expand All @@ -300,14 +348,16 @@ void CPacketSync::OnRawData2(byte* pData, int nDataLen)
// Returns a count of bytes scanned while not in-sync with the TS packet boundaries.
int CPacketSync::OnRawDataCheck(byte* pData, int nDataLen)
{
if (!m_bInSync) return 0; //We don't know what the packet length is yet..

int syncOffset=0;
int tempBuffOffset=0;
bool goodPacket = false;
int syncErrors=0;

if (m_tempBufferPos > 0 ) //We have some residual data from the last call
{
syncOffset = TS_PACKET_LEN - m_tempBufferPos;
syncOffset = m_packet_len - m_tempBufferPos;

if (nDataLen <= syncOffset)
{
Expand Down Expand Up @@ -352,19 +402,19 @@ int CPacketSync::OnRawDataCheck(byte* pData, int nDataLen)
}
}

while (nDataLen > (syncOffset + TS_PACKET_LEN)) //minimum of TS_PACKET_LEN+1 bytes available
while (nDataLen > (syncOffset + m_packet_len)) //minimum of m_packet_len+1 bytes available
{
if (!goodPacket && (syncOffset > (TS_PACKET_LEN * 8)) )
if (!goodPacket && (syncOffset > (m_packet_len * 8)) )
{
//No sync - abandon the buffer
//Reset();
return syncErrors;
}

if ((pData[syncOffset] == TS_PACKET_SYNC) &&
(pData[syncOffset + TS_PACKET_LEN]==TS_PACKET_SYNC))
(pData[syncOffset + m_packet_len]==TS_PACKET_SYNC))
{
syncOffset += TS_PACKET_LEN;
syncOffset += m_packet_len;
goodPacket = true;
m_bFirstSynced = true;
}
Expand Down
11 changes: 9 additions & 2 deletions DirectShowFilters/TsReader/source/DeMultiplexer.cpp
Expand Up @@ -1269,7 +1269,10 @@ int CDeMultiplexer::ReadFromFile(ULONG lDataLength)
if (dwReadBytes > 0)
{
//yes, then process the raw data
OnRawData2(m_pFileReadBuffer,(int)dwReadBytes);
if (OnRawData2(m_pFileReadBuffer,(int)dwReadBytes))
{
Sleep(200); //Not enough data to initially sync or re-sync to stream
}
m_LastDataFromRtsp = GET_TIME_NOW();
}
else
Expand Down Expand Up @@ -1324,7 +1327,11 @@ int CDeMultiplexer::ReadFromFile(ULONG lDataLength)
if (dwReadBytes > 0)
{
//process data
OnRawData2(m_pFileReadBuffer,(int)dwReadBytes);
if (OnRawData2(m_pFileReadBuffer,(int)dwReadBytes))
{
//Not enough data to initially sync ro re-sync to stream, so stall for a while
Sleep(200);
}
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion DirectShowFilters/TsReader/source/TsReader.h
Expand Up @@ -57,7 +57,7 @@
#define SPEED_ADJ_LIMIT 4000

//Vid/Aud/Sub buffer sizes and limits
#define MAX_AUD_BUF_SIZE 640
#define MAX_AUD_BUF_SIZE 960
#define MAX_VID_BUF_SIZE 640
#define MAX_SUB_BUF_SIZE 640
#define AUD_BUF_SIZE_LOG_LIM (MAX_AUD_BUF_SIZE-100)
Expand Down
1 change: 0 additions & 1 deletion DirectShowFilters/TsReader/source/mediaformats.h
Expand Up @@ -350,7 +350,6 @@ static GUID MEDIASUBTYPE_HDMV_LPCM_AUDIO = {0x949f97fd, 0x56f6, 0x4527, 0xb4, 0x
static GUID MEDIASUBTYPE_HDMVSUB = {0x4eba53e, 0x9330, 0x436c, 0x91, 0x33, 0x55, 0x3e, 0xc8, 0x70, 0x31, 0xdc};
static GUID MEDIASUBTYPE_SVCD_SUBPICTURE = {0xda5b82ee, 0x6bd2, 0x426f, 0xbf, 0x1e, 0x30, 0x11, 0x2d, 0xa7, 0x8a, 0xe1};
static GUID MEDIASUBTYPE_CVD_SUBPICTURE = {0x7b57308f, 0x5154, 0x4c36, 0xb9, 0x3, 0x52, 0xfe, 0x76, 0xe1, 0x84, 0xfc};
//static GUID MEDIASUBTYPE_DTS = {0xe06d8033, 0xdb46, 0x11cf, 0xb4, 0xd1, 0x00, 0x80, 0x05f, 0x6c, 0xbb, 0xea};
static GUID MEDIATYPE_Subtitle = {0xe487eb08, 0x6b26, 0x4be9, 0x9d, 0xd3, 0x99, 0x34, 0x34, 0xd3, 0x13, 0xfd};
static GUID MEDIASUBTYPE_PS2_SUB = {0x4f3d3d21, 0x6d7c, 0x4f73, 0xaa, 0x5, 0xe3, 0x97, 0xb5, 0xea, 0xe0, 0xaa};

Expand Down
4 changes: 3 additions & 1 deletion DirectShowFilters/shared/PacketSync.h
Expand Up @@ -22,6 +22,7 @@

#define TS_PACKET_SYNC 0x47
#define TS_PACKET_LEN 188
#define M2TS_PACKET_LEN 192

class CPacketSync
{
Expand All @@ -31,7 +32,7 @@ class CPacketSync
public:
virtual ~CPacketSync(void);
void OnRawData(byte* pData, int nDataLen);
void OnRawData2(byte* pData, int nDataLen);
bool OnRawData2(byte* pData, int nDataLen);
int OnRawDataCheck(byte* pData, int nDataLen);
virtual void OnTsPacket(byte* tsPacket);
virtual void OnTsPacket(byte* tsPacket, int bufferOffset, int bufferLength);
Expand All @@ -42,4 +43,5 @@ class CPacketSync
int m_tempBufferPos;
bool m_bInSync;
bool m_bFirstSynced;
int m_packet_len;
};
27 changes: 27 additions & 0 deletions mediaportal/Core/Player/BaseTSReaderPlayer.cs
Expand Up @@ -459,6 +459,18 @@ public override string AudioType(int iStream)
{
return "AAC";
}
if (sType.subType == MEDIASUBTYPE_BD_LPCM_AUDIO)
{
return "LPCM";
}
if (sType.subType == MEDIASUBTYPE_DTS2)
{
return "DTS";
}
if (sType.subType == MEDIASUBTYPE_DTS_HD)
{
return "DTS-HD";
}
}
return Strings.Unknown;
}
Expand Down Expand Up @@ -2092,6 +2104,21 @@ private static Guid MEDIASUBTYPE_ADTS_AAC_AUDIO
get { return new Guid("00001600-0000-0010-8000-00aa00389b71"); }
}

private static Guid MEDIASUBTYPE_BD_LPCM_AUDIO
{
get { return new Guid("A23EB7FC-510B-466F-9FBF-5F878F69347C"); }
}

private static Guid MEDIASUBTYPE_DTS2
{
get { return new Guid("00002001-0000-0010-8000-00AA00389B71"); }
}

private static Guid MEDIASUBTYPE_DTS_HD
{
get { return new Guid("A2E58EB7-0FA9-48BB-A40C-FA0E156D0645"); }
}

#endregion
}
}
14 changes: 14 additions & 0 deletions mediaportal/Core/Player/g_player.cs
Expand Up @@ -834,6 +834,20 @@ public static void UpdateMediaInfoProperties()
case "LATMAAC":
AudioCodec = "AAC";
break;

case "DTS":
AudioCodec = "DTS";
break;

case "DTSHD":
case "DTS-HD":
AudioCodec = "DTSHD";
break;

case "PCM":
case "LPCM":
AudioCodec = "PCM";
break;
}
GUIPropertyManager.SetProperty("#Play.Current.AudioCodec.Texture", AudioCodec);

Expand Down

0 comments on commit 585518e

Please sign in to comment.