Skip to content
This repository has been archived by the owner on Apr 15, 2023. It is now read-only.

Vnsi fixes #106

Merged
merged 12 commits into from Dec 10, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions addons/pvr.vdr.vnsi/src/VNSIDemux.cpp
Expand Up @@ -251,6 +251,12 @@ void cVNSIDemux::StreamChange(cResponsePacket *resp)
streams.stream[streams.iStreamCount].iCodecType = AVMEDIA_TYPE_AUDIO;
streams.stream[streams.iStreamCount].iCodecId = CODEC_ID_AAC;
}
else if(!strcmp(type, "AACLATM"))
{
streams.stream[streams.iStreamCount].iPhysicalId = pid;
streams.stream[streams.iStreamCount].iCodecType = AVMEDIA_TYPE_AUDIO;
streams.stream[streams.iStreamCount].iCodecId = CODEC_ID_AAC_LATM;
}
else if(!strcmp(type, "DTS"))
{
streams.stream[streams.iStreamCount].iPhysicalId = pid;
Expand Down
6 changes: 5 additions & 1 deletion addons/pvr.vdr.vnsi/vdr-plugin-vnsiserver/Makefile
Expand Up @@ -47,12 +47,16 @@ INCLUDES += -I$(VDRDIR)/include -I$(VDRDIR)

DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -DVNSI_SERVER_VERSION='"$(VERSION)"'

ifeq ($(DEBUG),1)
DEFINES += -DDEBUG
endif

### The object files (add further files here):

OBJS = vnsi.o bitstream.o vnsiclient.o config.o cxsocket.o demuxer.o demuxer_AAC.o \
demuxer_AC3.o demuxer_DTS.o demuxer_h264.o demuxer_MPEGAudio.o demuxer_MPEGVideo.o \
demuxer_Subtitle.o demuxer_Teletext.o receiver.o recplayer.o requestpacket.o responsepacket.o \
vnsiserver.o hash.o recordingscache.o
vnsiserver.o hash.o recordingscache.o setup.o

### Implicit rules:

Expand Down
6 changes: 4 additions & 2 deletions addons/pvr.vdr.vnsi/vdr-plugin-vnsiserver/demuxer.c
Expand Up @@ -226,8 +226,8 @@ void cParser::SendPacket(sStreamPacket *pkt)

cTSDemuxer::cTSDemuxer(cLiveStreamer *streamer, eStreamType type, int pid)
: m_Streamer(streamer)
, m_pID(pid)
, m_streamType(type)
, m_pID(pid)
{
m_pesError = false;
m_pesParser = NULL;
Expand All @@ -249,7 +249,9 @@ cTSDemuxer::cTSDemuxer(cLiveStreamer *streamer, eStreamType type, int pid)
m_pesParser = new cParserH264(this, m_Streamer, m_pID);
else if (m_streamType == stMPEG2AUDIO)
m_pesParser = new cParserMPEG2Audio(this, m_Streamer, m_pID);
else if (m_streamType == stAAC)
else if (m_streamType == stAACADST)
m_pesParser = new cParserAAC(this, m_Streamer, m_pID);
else if (m_streamType == stAACLATM)
m_pesParser = new cParserAAC(this, m_Streamer, m_pID);
else if (m_streamType == stAC3)
m_pesParser = new cParserAC3(this, m_Streamer, m_pID);
Expand Down
5 changes: 3 additions & 2 deletions addons/pvr.vdr.vnsi/vdr-plugin-vnsiserver/demuxer.h
Expand Up @@ -174,7 +174,8 @@ enum eStreamType
stAC3,
stMPEG2AUDIO,
stEAC3,
stAAC,
stAACADST,
stAACLATM,
stDTS,
stMPEG2VIDEO,
stH264,
Expand Down Expand Up @@ -242,9 +243,9 @@ class cTSDemuxer
{
private:
cLiveStreamer *m_Streamer;
eStreamType m_streamType;
const int m_pID;
eStreamContent m_streamContent;
eStreamType m_streamType;

bool m_pesError;
cParser *m_pesParser;
Expand Down
147 changes: 96 additions & 51 deletions addons/pvr.vdr.vnsi/vdr-plugin-vnsiserver/demuxer_AAC.c
Expand Up @@ -41,7 +41,7 @@ cParserAAC::cParserAAC(cTSDemuxer *demuxer, cLiveStreamer *streamer, int pID)
m_demuxer = demuxer;
m_streamBuffer = NULL;
m_streamBufferSize = 0;
m_streamBufferPtr = 0;
m_streamBufferDataSize = 0;
m_streamParserPtr = 0;
m_firstPUSIseen = false;

Expand All @@ -62,7 +62,7 @@ void cParserAAC::Parse(unsigned char *data, int size, bool pusi)
{
/* Payload unit start */
m_firstPUSIseen = true;
m_streamBufferPtr = 0;
m_streamBufferDataSize = 0;
m_streamParserPtr = 0;
}

Expand All @@ -75,18 +75,18 @@ void cParserAAC::Parse(unsigned char *data, int size, bool pusi)
m_streamBuffer = (uint8_t*)malloc(m_streamBufferSize);
}

if(m_streamBufferPtr + size >= m_streamBufferSize)
if(m_streamBufferDataSize + size >= m_streamBufferSize)
{
m_streamBufferSize += size * 4;
m_streamBuffer = (uint8_t*)realloc(m_streamBuffer, m_streamBufferSize);
}

memcpy(m_streamBuffer + m_streamBufferPtr, data, size);
m_streamBufferPtr += size;
memcpy(m_streamBuffer + m_streamBufferDataSize, data, size);
m_streamBufferDataSize += size;

if (m_streamParserPtr == 0)
{
if (m_streamBufferPtr < 9)
if (m_streamBufferDataSize < 9)
return;

int hlen = ParsePESHeader(data, size);
Expand All @@ -99,21 +99,77 @@ void cParserAAC::Parse(unsigned char *data, int size, bool pusi)
int p = m_streamParserPtr;

int l;
while ((l = m_streamBufferPtr - p) > 3)
if (m_demuxer->Type() == stAACLATM)
{
if(m_streamBuffer[p] == 0x56 && (m_streamBuffer[p + 1] & 0xe0) == 0xe0)
while ((l = m_streamBufferDataSize - p) > 3)
{
int muxlen = (m_streamBuffer[p + 1] & 0x1f) << 8 | m_streamBuffer[p + 2];
cBitstream bs(&m_streamBuffer[p], l * 8);
if(bs.readBits(11) == 0x2B7)
{
int muxlen = bs.readBits(13);

if(l < muxlen + 3)
break;
if(l < muxlen + 3)
break;

ParseLATMAudioMuxElement(m_streamBuffer + p + 3, muxlen);
p += muxlen + 3;
ParseLATMAudioMuxElement(m_streamBuffer + p + 3, muxlen);
p += muxlen + 3;
}
else
{
p++;
}
}
else
}
else if (m_demuxer->Type() == stAACADST)
{
while ((l = m_streamBufferDataSize - p) > 3)
{
p++;
if(m_streamBuffer[p] == 0xFF && (m_streamBuffer[p + 1] & 0xF0) == 0xF0)
{
// need at least 7 bytes for header
if (l < 7)
break;

cBitstream bs(&m_streamBuffer[p], l * 8);
bs.skipBits(15);

// check if CRC is present, means header is 9 byte long
int noCrc = bs.readBits(1);
if (!noCrc && (l < 9))
break;

bs.skipBits(2); // profile
m_SampleRateIndex = bs.readBits(4);
bs.skipBits(1); // private
m_ChannelConfig = bs.readBits(3);
bs.skipBits(4);

int frameLen = bs.readBits(13);

if (l < frameLen)
break;

m_SampleRate = aac_sample_rates[m_SampleRateIndex & 0x0E];
if (m_SampleRate)
m_FrameDuration = 1024 * 90000 / m_SampleRate;

sStreamPacket pkt;
pkt.id = m_pID;
pkt.size = frameLen;
pkt.data = &m_streamBuffer[p];
pkt.dts = m_curDTS;
pkt.pts = m_curDTS;
pkt.duration = m_FrameDuration;

m_curDTS += m_FrameDuration;
SendPacket(&pkt);

p += frameLen;
}
else
{
p++;
}
}
}
m_streamParserPtr = p;
Expand Down Expand Up @@ -148,38 +204,12 @@ void cParserAAC::ParseLATMAudioMuxElement(uint8_t *data, int len)

sStreamPacket pkt;
pkt.id = m_pID;
pkt.size = slotLen + 7;
pkt.data = (uint8_t*)malloc(pkt.size);
pkt.size = len + 3;
pkt.data = data-3;
pkt.dts = m_curDTS;
pkt.pts = m_curDTS;
pkt.duration = m_FrameDuration;

/* 7 bytes of ADTS header */
cBitstream out(pkt.data, 56);

out.putBits(0xfff, 12); // Sync marker
out.putBits(0, 1); // ID 0 = MPEG 4
out.putBits(0, 2); // Layer
out.putBits(1, 1); // Protection absent
out.putBits(2, 2); // AOT
out.putBits(m_SampleRateIndex, 4);
out.putBits(1, 1); // Private bit
out.putBits(m_ChannelConfig, 3);
out.putBits(1, 1); // Original
out.putBits(1, 1); // Copy
out.putBits(1, 1); // Copyright identification bit
out.putBits(1, 1); // Copyright identification start
out.putBits(slotLen, 13);
out.putBits(0, 11); // Buffer fullness
out.putBits(0, 2); // RDB in frame

assert(out.remainingBits() == 0);

/* AAC RDB */
uint8_t *buf = pkt.data + 7;
for (unsigned int i = 0; i < slotLen; i++)
*buf++ = bs.readBits(8);

m_curDTS += m_FrameDuration;

SendPacket(&pkt);
Expand All @@ -197,7 +227,7 @@ void cParserAAC::ReadStreamMuxConfig(cBitstream *bs)
return;

if (AudioMuxVersion)
LATMGetValue(bs); // taraFullness
LATMGetValue(bs); // taraFullness

bs->skipBits(1); // allStreamSameTimeFraming = 1
bs->skipBits(6); // numSubFrames = 0
Expand Down Expand Up @@ -235,7 +265,7 @@ void cParserAAC::ReadStreamMuxConfig(cBitstream *bs)

if (bs->readBits(1))
{ // other data?
if (AudioMuxVersion)
if (AudioMuxVersion == 1)
{
LATMGetValue(bs); // other_data_bits
}
Expand All @@ -258,24 +288,39 @@ void cParserAAC::ReadStreamMuxConfig(cBitstream *bs)
void cParserAAC::ReadAudioSpecificConfig(cBitstream *bs)
{
int aot = bs->readBits(5);
if (aot != 2)
return;
if (aot == 31)
aot = 32 + bs->readBits(6);

m_SampleRateIndex = bs->readBits(4);

if (m_SampleRateIndex == 0xf)
return;
m_SampleRate = bs->readBits(24);
else
m_SampleRate = aac_sample_rates[m_SampleRateIndex & 0xf];

m_SampleRate = aac_sample_rates[m_SampleRateIndex];
m_FrameDuration = 1024 * 90000 / m_SampleRate;
if (m_SampleRate)
m_FrameDuration = 1024 * 90000 / m_SampleRate;
m_ChannelConfig = bs->readBits(4);

if (aot == 5) { // AOT_SBR
if (bs->readBits(4) == 0xf) { // extensionSamplingFrequencyIndex
bs->skipBits(24);
}
aot = bs->readBits(5); // this is the main object type (i.e. non-extended)
if (aot == 31)
aot = 32 + bs->readBits(6);
}

if(aot != 2)
return;

bs->skipBits(1); //framelen_flag
if (bs->readBits1()) // depends_on_coder
bs->skipBits(14);

if (bs->readBits(1)) // ext_flag
bs->skipBits(1); // ext3_flag

m_demuxer->SetAudioInformation(m_ChannelConfig, m_SampleRate, 0, 0, 0);
// ffmpeg won't get started if this info is set
// m_demuxer->SetAudioInformation(m_ChannelConfig, m_SampleRate, 0, 0, 0);
}
2 changes: 1 addition & 1 deletion addons/pvr.vdr.vnsi/vdr-plugin-vnsiserver/demuxer_AAC.h
Expand Up @@ -36,7 +36,7 @@ class cParserAAC : public cParser
cTSDemuxer *m_demuxer;
uint8_t *m_streamBuffer;
int m_streamBufferSize;
int m_streamBufferPtr;
int m_streamBufferDataSize;
int m_streamParserPtr;
bool m_firstPUSIseen;

Expand Down
23 changes: 18 additions & 5 deletions addons/pvr.vdr.vnsi/vdr-plugin-vnsiserver/demuxer_AC3.c
Expand Up @@ -127,6 +127,9 @@ cParserAC3::cParserAC3(cTSDemuxer *demuxer, cLiveStreamer *streamer, int pID)
m_NextDTS = 0;
m_AC3BufferPtr = 0;
m_HeaderFound = false;
m_FrameOffset = 0;
m_CurrentOffset = 0;
m_NextFrameOffset = 0;

for (int i = 0; i < AV_PARSER_PTS_NB; i++)
{
Expand Down Expand Up @@ -238,7 +241,8 @@ int cParserAC3::FindHeaders(uint8_t **poutbuf, int *poutbuf_size,
uint8_t *buf_ptr = buf;
while (buf_size > 0)
{
if (buf_ptr[0] == 0x0b && buf_ptr[1] == 0x77 && !m_HeaderFound)
if (!m_HeaderFound && (buf_size >= 9) &&
(buf_ptr[0] == 0x0b && buf_ptr[1] == 0x77))
{
cBitstream bs(buf_ptr + 2, AC3_HEADER_SIZE * 8);

Expand Down Expand Up @@ -288,8 +292,8 @@ int cParserAC3::FindHeaders(uint8_t **poutbuf, int *poutbuf_size,

/*int substreamid =*/ bs.readBits(3);

int framesize = (bs.readBits(11) + 1) << 1;
if (framesize < AC3_HEADER_SIZE)
m_FrameSize = (bs.readBits(11) + 1) << 1;
if (m_FrameSize < AC3_HEADER_SIZE)
return -1;

int numBlocks = 6;
Expand All @@ -310,14 +314,23 @@ int cParserAC3::FindHeaders(uint8_t **poutbuf, int *poutbuf_size,
int channelMode = bs.readBits(3);
int lfeon = bs.readBits(1);

m_BitRate = (uint32_t)(8.0 * framesize * m_SampleRate / (numBlocks * 256.0));
m_BitRate = (uint32_t)(8.0 * m_FrameSize * m_SampleRate / (numBlocks * 256.0));
m_Channels = AC3ChannelsTable[channelMode] + lfeon;
}
m_HeaderFound = true;
}

if (m_HeaderFound)
m_AC3Buffer[m_AC3BufferPtr++] = buf_ptr[0];
{
if (m_AC3BufferPtr > AC3_MAX_CODED_FRAME_SIZE - 1)
{
ERRORLOG("error in AC3 frame size");
m_AC3BufferPtr = 0;
m_HeaderFound = false;
}
else
m_AC3Buffer[m_AC3BufferPtr++] = buf_ptr[0];
}

if (m_FrameSize && m_AC3BufferPtr >= m_FrameSize)
{
Expand Down