summaryrefslogtreecommitdiff
path: root/dxr3multichannelaudio.c
diff options
context:
space:
mode:
authorscop <scop>2005-04-19 18:19:34 +0000
committerscop <scop>2005-04-19 18:19:34 +0000
commitf9c59e544ada17055c3ed15b3d80f0d285c3928d (patch)
treecd7b038c17b040beb435e0a16aab02346854c9ad /dxr3multichannelaudio.c
parentdea137eddfe1017e9ff85a8c221aee2bca4647ad (diff)
downloadvdr-plugin-dxr3-f9c59e544ada17055c3ed15b3d80f0d285c3928d.tar.gz
vdr-plugin-dxr3-f9c59e544ada17055c3ed15b3d80f0d285c3928d.tar.bz2
Mass indentation/whitespace cleanup.
Diffstat (limited to 'dxr3multichannelaudio.c')
-rw-r--r--dxr3multichannelaudio.c1080
1 files changed, 607 insertions, 473 deletions
diff --git a/dxr3multichannelaudio.c b/dxr3multichannelaudio.c
index 9a12d70..1d1bc30 100644
--- a/dxr3multichannelaudio.c
+++ b/dxr3multichannelaudio.c
@@ -1,10 +1,10 @@
/*
-* dxr3multichannelaudio.c:
-*
-* taken from the AC3overDVB Patch maintained by Stefan Huelswitt
-*
-*
-*/
+ * dxr3multichannelaudio.c:
+ *
+ * taken from the AC3overDVB Patch maintained by Stefan Huelswitt
+ *
+ *
+ */
#include <malloc.h>
#include "dxr3multichannelaudio.h"
@@ -22,625 +22,759 @@
#define aLPCM 0xA0
#define aMPEG 0xC0
-#define aVDR 0x0B // VDR specific audio substream
-#define aSPU 0x20 // SPU stream
+#define aVDR 0x0B // VDR specific audio substream
+#define aSPU 0x20 // SPU stream
#define PES_HDR_SIZE 6 // length of PES header
#define PTS_SIZE 5 // length of PTS data
#define MAX_FRAMECOUNT 1536 // max. LPCM payload size
-#define SYNC_SIZE 7 // how many bytes we need to sync on a audio header
+#define SYNC_SIZE 7 // how many bytes needed to sync on a audio header
#define AC3_SIZE 6144 // size of AC3 IEC paket
#define DTS_SIZE 2048 // size of DTS IEC paket
#define IEC_HDR_SIZE 8 // size of IEC header
-// --- cAudioEncapsulator ------------------------------------------------------
+// --- cAudioEncapsulator -----------------------------------------------------
-class cAudioEncapsulator {
+class cAudioEncapsulator
+{
private:
- int totalSize, frameCount;
- cFrame *frame;
- uchar *frameData;
- //
- uchar syncBuff[SYNC_SIZE];
- int have, length, skipped;
- //
- uchar ptsFlags;
- const uchar *ptsData;
- int ptsDelay;
- //
- void NewFrame(uchar PTSflags, const uchar *PTSdata);
- void SyncFound(const uchar *data);
+ int totalSize, frameCount;
+ cFrame *frame;
+ uchar *frameData;
+ //
+ uchar syncBuff[SYNC_SIZE];
+ int have, length, skipped;
+ //
+ uchar ptsFlags;
+ const uchar *ptsData;
+ int ptsDelay;
+ //
+ void NewFrame(uchar PTSflags, const uchar *PTSdata);
+ void SyncFound(const uchar *data);
protected:
- int streamType;
- cRingBufferFrame *ringBuffer;
- int fillup, firstBurst;
- bool mute, muteData;
- //
- void StartFrame(int size, uchar PTSflags, const uchar *PTSdata);
- void FinishFrame(void);
- void PutData(const uchar *data, int len);
- void SendIECpause(int type, uchar PTSflags, const uchar *PTSdata);
- //
- virtual int SyncInfo(const uchar *data)=0;
- virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata)=0;
- virtual void FinishIECFrame(void);
+ int streamType;
+ cRingBufferFrame *ringBuffer;
+ int fillup, firstBurst;
+ bool mute, muteData;
+ //
+ void StartFrame(int size, uchar PTSflags, const uchar *PTSdata);
+ void FinishFrame(void);
+ void PutData(const uchar *data, int len);
+ void SendIECpause(int type, uchar PTSflags, const uchar *PTSdata);
+ //
+ virtual int SyncInfo(const uchar *data)=0;
+ virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags,
+ const uchar *PTSdata) = 0;
+ virtual void FinishIECFrame(void);
public:
- cAudioEncapsulator(cRingBufferFrame *rb, int StreamType);
- virtual ~cAudioEncapsulator();
- void Clear(void);
- void Decode(const uchar *data, int len, uchar PTSflags, int PTSdelay, const uchar *PTSdata);
- int StreamType() { return streamType; }
- void Mute(bool Mute) { mute=Mute; }
- };
+ cAudioEncapsulator(cRingBufferFrame *rb, int StreamType);
+ virtual ~cAudioEncapsulator();
+ void Clear(void);
+ void Decode(const uchar *data, int len, uchar PTSflags, int PTSdelay,
+ const uchar *PTSdata);
+ int StreamType()
+ {
+ return streamType;
+ }
+ void Mute(bool Mute)
+ {
+ mute = Mute;
+ }
+};
cAudioEncapsulator::cAudioEncapsulator(cRingBufferFrame *rb, int StreamType)
{
- ringBuffer=rb;
- streamType=StreamType;
- frame=0; firstBurst=1;
- Clear();
+ ringBuffer = rb;
+ streamType = StreamType;
+ frame = 0;
+ firstBurst = 1;
+ Clear();
}
cAudioEncapsulator::~cAudioEncapsulator()
{
- delete frame;
+ delete frame;
}
void cAudioEncapsulator::Clear(void)
{
- delete frame;
- frame=0; frameCount=0; fillup=0; mute=muteData=false;
- have=length=skipped=0;
+ delete frame;
+ frame = 0;
+ frameCount = 0;
+ fillup = 0;
+ mute = muteData = false;
+ have = length = skipped = 0;
}
-void cAudioEncapsulator::StartFrame(int size, uchar PTSflags, const uchar *PTSdata)
+void cAudioEncapsulator::StartFrame(int size, uchar PTSflags,
+ const uchar *PTSdata)
{
- if(frame) {
- DEBUG("StartFrame() with unfinished frame!\n");
- FinishFrame();
+ if (frame)
+ {
+ DEBUG("StartFrame() with unfinished frame!\n");
+ FinishFrame();
}
- ED("StartFrame: size=%d ptsFlags=%d\n",size,PTSflags);
- totalSize=size;
- NewFrame(PTSflags,PTSdata);
+ ED("StartFrame: size=%d ptsFlags=%d\n", size, PTSflags);
+ totalSize = size;
+ NewFrame(PTSflags, PTSdata);
}
void cAudioEncapsulator::NewFrame(uchar PTSflags, const uchar *PTSdata)
{
- if(!totalSize) {
- DEBUG("NewFrame: new frame requested, but totalSize=0\n");
- return;
+ if (!totalSize)
+ {
+ DEBUG("NewFrame: new frame requested, but totalSize=0\n");
+ return;
}
- static const int ptslen[] = { 0,0,PTS_SIZE,PTS_SIZE*2 };
- const int plen = ptslen[PTSflags];
- int len = std::min(totalSize, MAX_FRAMECOUNT);
- ED("NewFrame: totalSize=%d frameCount=%d PTSflags=%d",totalSize,len,PTSflags);
- totalSize -= len;
- ED(" new totalSize=%d\n",totalSize);
- len += (plen + 3 + 7);
- frameCount = len+PES_HDR_SIZE;
- frameData = MALLOC(uchar,frameCount);
- if (frameData) {
- frame = new cFrame(frameData, -frameCount, ftUnknown);
- if (frame) {
- uchar buf[10];
- // build the PES header
- buf[0] = 0x00;
- buf[1] = 0x00;
- buf[2] = 0x01;
- buf[3] = 0xBD; // PRIVATE_STREAM1
- buf[4] = (len >> 8) & 0xFF;
- buf[5] = len & 0xFF;
- buf[6] = 0x84;
- buf[7] = plen ? (PTSflags << 6) : 0;
- buf[8] = plen;
- PutData(buf,9);
-
- if (plen) PutData(PTSdata,plen);
-
- // build LPCM header
- buf[0] = aLPCM; // substream ID
- buf[1] = 0xFF;
- buf[2] = 0x00;
- buf[3] = 0x00;
- buf[4] = 0x00;
- buf[5] = 0x00;
- buf[6] = 0x81;
- PutData(buf,7);
- return;
- }
- else { free(frameData); frameData=0; }
+ static const int ptslen[] = { 0, 0, PTS_SIZE, PTS_SIZE*2 };
+ const int plen = ptslen[PTSflags];
+ int len = std::min(totalSize, MAX_FRAMECOUNT);
+ ED("NewFrame: totalSize=%d frameCount=%d PTSflags=%d", totalSize, len, PTSflags);
+ totalSize -= len;
+ ED(" new totalSize=%d\n",totalSize);
+ len += (plen + 3 + 7);
+ frameCount = len + PES_HDR_SIZE;
+ frameData = MALLOC(uchar, frameCount);
+ if (frameData)
+ {
+ frame = new cFrame(frameData, -frameCount, ftUnknown);
+ if (frame)
+ {
+ uchar buf[10];
+ // build the PES header
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ buf[2] = 0x01;
+ buf[3] = 0xBD; // PRIVATE_STREAM1
+ buf[4] = (len >> 8) & 0xFF;
+ buf[5] = len & 0xFF;
+ buf[6] = 0x84;
+ buf[7] = plen ? (PTSflags << 6) : 0;
+ buf[8] = plen;
+ PutData(buf, 9);
+
+ if (plen)
+ PutData(PTSdata, plen);
+
+ // build LPCM header
+ buf[0] = aLPCM; // substream ID
+ buf[1] = 0xFF;
+ buf[2] = 0x00;
+ buf[3] = 0x00;
+ buf[4] = 0x00;
+ buf[5] = 0x00;
+ buf[6] = 0x81;
+ PutData(buf, 7);
+ return;
+ }
+ else
+ {
+ free(frameData);
+ frameData = 0;
+ }
}
- esyslog("Failed to build frame for audio encapsulation");
+ esyslog("Failed to build frame for audio encapsulation");
}
void cAudioEncapsulator::FinishFrame(void)
{
- if (frameCount) {
- DEBUG("FinishFrame() with frameCount>0\n");
- PutData(0,frameCount);
+ if (frameCount)
+ {
+ DEBUG("FinishFrame() with frameCount>0\n");
+ PutData(0, frameCount);
}
- if (frame && frameData) {
- ED("FinishFrame: totalSize=%d\n",totalSize);
- if (!ringBuffer->Put(frame)) {
- esyslog("Ringbuffer overflow. Encapsulated audio frame lost");
- delete frame;
- }
+ if (frame && frameData)
+ {
+ ED("FinishFrame: totalSize=%d\n", totalSize);
+ if (!ringBuffer->Put(frame)) {
+ esyslog("Ringbuffer overflow. Encapsulated audio frame lost");
+ delete frame;
+ }
}
- frame=0; frameData=0; frameCount=0;
+ frame = 0;
+ frameData = 0;
+ frameCount = 0;
}
void cAudioEncapsulator::PutData(const uchar *data, int len)
{
- if(!muteData) {
- if(!frameData) DEBUG("PutData() without frame\n");
- while (frameData && len > 0) {
- int l = std::min(len,frameCount);
- if(data) {
- memcpy(frameData,data,l);
- data += l;
- }
- else memset(frameData,0,l);
- frameData += l; len -= l; frameCount -= l;
-
- ED("PutData: %s=%d len=%d frameCount=%d\n",data?"put":"zero",l,len,frameCount);
- if (!frameCount) {
- FinishFrame();
- if (totalSize > 0) NewFrame(0,0);
- }
- }
+ if (!muteData)
+ {
+ if (!frameData)
+ DEBUG("PutData() without frame\n");
+ while (frameData && len > 0)
+ {
+ int l = std::min(len, frameCount);
+ if (data)
+ {
+ memcpy(frameData, data, l);
+ data += l;
+ }
+ else
+ memset(frameData, 0, l);
+ frameData += l;
+ len -= l;
+ frameCount -= l;
+
+ ED("PutData: %s=%d len=%d frameCount=%d\n",
+ data ? "put" : "zero", l, len, frameCount);
+ if (!frameCount)
+ {
+ FinishFrame();
+ if (totalSize > 0)
+ NewFrame(0, 0);
+ }
+ }
}
}
-void cAudioEncapsulator::SendIECpause(int type, uchar PTSflags, const uchar *PTSdata)
+void cAudioEncapsulator::SendIECpause(int type, uchar PTSflags,
+ const uchar *PTSdata)
{
- StartFrame(AC3_SIZE,PTSflags,PTSdata);
- uchar burst[IEC_HDR_SIZE];
- // prepare IEC 60958 data frame
- burst[0] = 0xF8;
- burst[1] = 0x72;
- burst[2] = 0x4E;
- burst[3] = 0x1F;
-
- switch (type) {
+ StartFrame(AC3_SIZE, PTSflags, PTSdata);
+ uchar burst[IEC_HDR_SIZE];
+ // prepare IEC 60958 data frame
+ burst[0] = 0xF8;
+ burst[1] = 0x72;
+ burst[2] = 0x4E;
+ burst[3] = 0x1F;
+
+ switch (type) {
default:
case 0:
- burst[4] = 7 << 5; // null frame, stream = 7
- burst[5] = 0x00;
- burst[6] = 0x00; // No data therein
- burst[7] = 0x00;
- break;
+ burst[4] = 7 << 5; // null frame, stream = 7
+ burst[5] = 0x00;
+ burst[6] = 0x00; // No data therein
+ burst[7] = 0x00;
+ break;
case 1:
- burst[4] = 0x00; // Audio ES Channel empty, wait
- burst[5] = 0x03; // for DD Decoder or pause
- burst[6] = 0x00; // Trailing frame size is 32 bits payload
- burst[7] = 0x20;
- break;
+ burst[4] = 0x00; // Audio ES Channel empty, wait
+ burst[5] = 0x03; // for DD Decoder or pause
+ burst[6] = 0x00; // Trailing frame size is 32 bits payload
+ burst[7] = 0x20;
+ break;
case -1:
- burst[4] = 0x01; // User stop, skip or error
- burst[5] = 0x03;
- burst[6] = 0x08; // Trailing frame size is zero
- burst[7] = 0x00;
- break;
+ burst[4] = 0x01; // User stop, skip or error
+ burst[5] = 0x03;
+ burst[6] = 0x08; // Trailing frame size is zero
+ burst[7] = 0x00;
+ break;
}
- PutData(burst,sizeof(burst));
- PutData(0,AC3_SIZE-sizeof(burst));
- FinishFrame();
- muteData = true;
+ PutData(burst, sizeof(burst));
+ PutData(0, AC3_SIZE - sizeof(burst));
+ FinishFrame();
+ muteData = true;
}
void cAudioEncapsulator::FinishIECFrame(void)
{
- if(!muteData) {
- ED("FinishIECFrame: fillup=%d\n",fillup);
- if (fillup) PutData(0,fillup);
- FinishFrame();
+ if (!muteData)
+ {
+ ED("FinishIECFrame: fillup=%d\n", fillup);
+ if (fillup)
+ PutData(0, fillup);
+ FinishFrame();
}
- muteData=false; fillup=0;
+ muteData = false;
+ fillup = 0;
}
void cAudioEncapsulator::SyncFound(const uchar *data)
{
- if(skipped) {
- DEBUG("Decode: skipped %d bytes\n",skipped);
- ED("skipped: "); for(int k=-skipped ; k<0 ; k++) ED("%02x ",data[k]);
- ED("\ndata: "); for(int k=0 ; k<24 ; k++) ED("%02x ",data[k]);
- ED("\n");
- skipped=0;
+ if (skipped)
+ {
+ DEBUG("Decode: skipped %d bytes\n", skipped);
+ ED("skipped: "); for(int k = -skipped; k < 0; k++) ED("%02x ",data[k]);
+ ED("\ndata: "); for(int k = 0; k<24; k++) ED("%02x ", data[k]);
+ ED("\n");
+ skipped = 0;
}
- uchar pf=0;
- ED("Decode: sync found ptsFlags=%d ptsDelay=%d\n",ptsFlags,ptsDelay);
- if(ptsFlags && ptsDelay<=1) {
- pf=ptsFlags; ptsFlags=0;
+ uchar pf = 0;
+ ED("Decode: sync found ptsFlags=%d ptsDelay=%d\n", ptsFlags, ptsDelay);
+ if (ptsFlags && ptsDelay <= 1)
+ {
+ pf = ptsFlags;
+ ptsFlags = 0;
}
- if(firstBurst || mute) {
- SendIECpause(1,pf,ptsData);
- if(firstBurst && ++firstBurst>10) firstBurst=0;
+ if (firstBurst || mute)
+ {
+ SendIECpause(1, pf, ptsData);
+ if (firstBurst && ++firstBurst>10)
+ firstBurst = 0;
}
- else StartIECFrame(data,length,pf,ptsData);
- PutData(data,SYNC_SIZE);
- have = SYNC_SIZE;
+ else
+ StartIECFrame(data, length, pf, ptsData);
+ PutData(data, SYNC_SIZE);
+ have = SYNC_SIZE;
}
-void cAudioEncapsulator::Decode(const uchar *data, int len, uchar PTSflags, int PTSdelay, const uchar *PTSdata)
+void cAudioEncapsulator::Decode(const uchar *data, int len, uchar PTSflags,
+ int PTSdelay, const uchar *PTSdata)
{
- ED("Decode: enter length=%d have=%d len=%d PTSflags=%d PTSdelay=%d\n",length,have,len,PTSflags,PTSdelay);
- if(PTSflags) {
- // if we are close to the end of an audio frame, but are already receiving
- // the start of the next frame, assume a corrupted stream and finish the
- // incomplete frame.
- if(length && length-have<20 && !PTSdelay && SyncInfo(data)) {
- int miss=length-have;
- DEBUG("Decode: incomplete frame (stream corrupt?). syncing to next. miss=%d\n",miss);
- PutData(0,miss);
- FinishIECFrame();
- length=have=0;
- }
-/*
- // we only send PTS info if we're nearly at frame start, except
- // if we're signaled to delay the PTS
- if(length && have>40) {
- if(PTSdelay) ED("Decode: PTS delayed\n");
- else {
- DEBUG("Decode: PTS info dropped length=%d have=%d\n",length,have);
- PTSflags=0;
- }
- }
-*/
- ptsFlags=PTSflags; ptsData=PTSdata; ptsDelay=PTSdelay;
-// ED("Decode: saved PTS flags=%d delay=%d\n",ptsFlags,ptsDelay);
+ ED("Decode: enter length=%d have=%d len=%d PTSflags=%d PTSdelay=%d\n",
+ length, have, len, PTSflags, PTSdelay);
+ if (PTSflags)
+ {
+ // if we are close to the end of an audio frame, but are already
+ // receiving the start of the next frame, assume a corrupted stream
+ // and finish the incomplete frame.
+ if (length && length-have < 20 && !PTSdelay && SyncInfo(data))
+ {
+ int miss = length - have;
+ DEBUG("Decode: incomplete frame (stream corrupt?). syncing to next. miss=%d\n", miss);
+ PutData(0, miss);
+ FinishIECFrame();
+ length = have = 0;
+ }
+ /*
+ // we only send PTS info if we're nearly at frame start, except
+ // if we're signaled to delay the PTS
+ if (length && have > 40)
+ {
+ if(PTSdelay)
+ ED("Decode: PTS delayed\n");
+ else
+ {
+ DEBUG("Decode: PTS info dropped length=%d have=%d\n",
+ length, have);
+ PTSflags = 0;
+ }
+ }
+ */
+ ptsFlags = PTSflags;
+ ptsData = PTSdata;
+ ptsDelay = PTSdelay;
+ //ED("Decode: saved PTS flags=%d delay=%d\n", ptsFlags, ptsDelay);
}
#if 0
- {
- printf("Decode: len=%d\n",len);
- for(int i=0 ; i<len ; ) {
- printf("%04x:",i);
- for(int j=0 ; j<16 && i<len ; j++) {
- printf(" %02x",data[i++]);
- }
- printf("\n");
+ {
+ printf("Decode: len=%d\n", len);
+ for (int i = 0; i < len; )
+ {
+ printf("%04x:", i);
+ for (int j = 0; j < 16 && i < len; j++)
+ printf(" %02x", data[i++]);
+ printf("\n");
+ }
}
- }
#endif
- int used=0;
- while (used < len) {
- if (!length) { // we are still searching for a header sync
- if (!have) { // buffer is empty, work without buffering
- if (used+SYNC_SIZE < len) {
- length=SyncInfo(&data[used]);
- if (length) {
- ED("Decode: sync found at offset %d (len=%d)\n",used,length);
- SyncFound(&data[used]);
- used += SYNC_SIZE; ptsDelay -= SYNC_SIZE;
- continue;
- }
- else { used++; skipped++; }
- }
- else { // not enough data to try a sync, buffer the rest
- ED("Decode: buffering started\n");
- have = len-used;
- memcpy(syncBuff,&data[used],have);
- used += have; ptsDelay -= have;
- }
- }
- else { // unfortunaly buffer is not empty, so continue with buffering until sync found
- int need=std::min(SYNC_SIZE-have,len-used);
- if (need) {
- memcpy(&syncBuff[have],&data[used],need);
- have += need; used += need; ptsDelay -= need;
- }
- if (have==SYNC_SIZE) {
- length=SyncInfo(syncBuff);
- if (length) {
- ED("Decode: (buffered) sync found at offset %d (len=%d)\n",used-7,length);
- SyncFound(syncBuff);
- continue;
- }
- else {
- memmove(syncBuff,syncBuff+1,SYNC_SIZE-1);
- have--; skipped++;
- }
- }
- }
- }
- else { // we have a header sync and are copying data
- int need = std::min(length-have,len-used);
- if(need) {
- ED("Decode: writing %d\n",need);
- PutData(&data[used],need);
- have += need; used += need; ptsDelay -= need;
- if (have == length) {
- FinishIECFrame();
- length = have = 0;
- continue;
- }
- }
- }
+ int used = 0;
+ while (used < len)
+ {
+ if (!length) // we are still searching for a header sync
+ {
+ if (!have) // buffer is empty, work without buffering
+ {
+ if (used + SYNC_SIZE < len)
+ {
+ length = SyncInfo(&data[used]);
+ if (length)
+ {
+ ED("Decode: sync found at offset %d (len=%d)\n",
+ used, length);
+ SyncFound(&data[used]);
+ used += SYNC_SIZE;
+ ptsDelay -= SYNC_SIZE;
+ continue;
+ }
+ else
+ {
+ used++;
+ skipped++;
+ }
+ }
+ else // not enough data to try a sync, buffer the rest
+ {
+ ED("Decode: buffering started\n");
+ have = len - used;
+ memcpy(syncBuff, &data[used], have);
+ used += have;
+ ptsDelay -= have;
+ }
+ }
+ else // unfortunately buffer is not empty, so continue with
+ // buffering until sync found
+ {
+ int need = std::min(SYNC_SIZE - have, len - used);
+ if (need)
+ {
+ memcpy(&syncBuff[have], &data[used], need);
+ have += need;
+ used += need;
+ ptsDelay -= need;
+ }
+ if (have == SYNC_SIZE)
+ {
+ length = SyncInfo(syncBuff);
+ if (length)
+ {
+ ED("Decode: (buffered) sync found at offset %d (len=%d)\n",used-7,length);
+ SyncFound(syncBuff);
+ continue;
+ }
+ else
+ {
+ memmove(syncBuff, syncBuff + 1, SYNC_SIZE - 1);
+ have--;
+ skipped++;
+ }
+ }
+ }
+ }
+ else // we have a header sync and are copying data
+ {
+ int need = std::min(length - have, len - used);
+ if (need)
+ {
+ ED("Decode: writing %d\n", need);
+ PutData(&data[used], need);
+ have += need;
+ used += need;
+ ptsDelay -= need;
+ if (have == length)
+ {
+ FinishIECFrame();
+ length = have = 0;
+ continue;
+ }
+ }
+ }
}
- ED("Decode: leave length=%d have=%d len=%d used=%d\n",length,have,len,used);
+ ED("Decode: leave length=%d have=%d len=%d used=%d\n",
+ length, have, len, used);
}
-// --- cAudioEncapsulatorAC3 ---------------------------------------------------
+// --- cAudioEncapsulatorAC3 --------------------------------------------------
class cAudioEncapsulatorAC3 : public cAudioEncapsulator {
private:
- virtual int SyncInfo(const uchar *buf);
- virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata);
+ virtual int SyncInfo(const uchar *buf);
+ virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags,
+ const uchar *PTSdata);
public:
- cAudioEncapsulatorAC3(cRingBufferFrame *rb, int StreamType);
- };
+ cAudioEncapsulatorAC3(cRingBufferFrame *rb, int StreamType);
+};
-cAudioEncapsulatorAC3::cAudioEncapsulatorAC3(cRingBufferFrame *rb, int StreamType)
-:cAudioEncapsulator(rb, StreamType)
+cAudioEncapsulatorAC3::cAudioEncapsulatorAC3(cRingBufferFrame *rb,
+ int StreamType)
+ : cAudioEncapsulator(rb, StreamType)
{}
int cAudioEncapsulatorAC3::SyncInfo(const uchar *buf)
{
- static const int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
- 128, 160, 192, 224, 256, 320, 384, 448,
- 512, 576, 640};
-
- if ((buf[0] != 0x0B) || (buf[1] != 0x77)) /* syncword */
- return 0;
- if (buf[5] >= 0x60) /* bsid >= 12 */
- return 0;
-
- int frmsizecod = buf[4] & 63;
- if (frmsizecod >= 38)
- return 0;
- int bitrate = rate[frmsizecod >> 1];
-
- switch (buf[4] & 0xC0) {
- case 0:
- return 4 * bitrate;
- case 0x40:
- return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
- case 0x80:
- return 6 * bitrate;
- default:
- return 0;
- }
+ static const int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112,
+ 128, 160, 192, 224, 256, 320, 384, 448,
+ 512, 576, 640 };
+
+ if ((buf[0] != 0x0B) || (buf[1] != 0x77)) /* syncword */
+ return 0;
+ if (buf[5] >= 0x60) /* bsid >= 12 */
+ return 0;
+
+ int frmsizecod = buf[4] & 63;
+ if (frmsizecod >= 38)
+ return 0;
+ int bitrate = rate[frmsizecod >> 1];
+
+ switch (buf[4] & 0xC0) {
+ case 0:
+ return 4 * bitrate;
+ case 0x40:
+ return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
+ case 0x80:
+ return 6 * bitrate;
+ default:
+ return 0;
+ }
}
-void cAudioEncapsulatorAC3::StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata)
+void cAudioEncapsulatorAC3::StartIECFrame(const uchar *buf, int length,
+ uchar PTSflags, const uchar *PTSdata)
{
- StartFrame(AC3_SIZE,PTSflags,PTSdata);
- fillup = AC3_SIZE-IEC_HDR_SIZE-length;
-
- // prepare IEC 60958 data frame
- uchar burst[IEC_HDR_SIZE];
- burst[0] = 0xF8;
- burst[1] = 0x72;
- burst[2] = 0x4E;
- burst[3] = 0x1F;
- burst[4] = (buf[5] & 0x07); // Pc1
- burst[5] = 0x01; // Pc2 AC-3
- burst[6] = ((length * 8) >> 8 ) & 0xFF; // Pd1
- burst[7] = (length * 8) & 0xFF; // Pd2
- PutData(burst,sizeof(burst));
+ StartFrame(AC3_SIZE, PTSflags, PTSdata);
+ fillup = AC3_SIZE - IEC_HDR_SIZE - length;
+
+ // prepare IEC 60958 data frame
+ uchar burst[IEC_HDR_SIZE];
+ burst[0] = 0xF8;
+ burst[1] = 0x72;
+ burst[2] = 0x4E;
+ burst[3] = 0x1F;
+ burst[4] = (buf[5] & 0x07); // Pc1
+ burst[5] = 0x01; // Pc2 AC-3
+ burst[6] = ((length * 8) >> 8 ) & 0xFF; // Pd1
+ burst[7] = (length * 8) & 0xFF; // Pd2
+ PutData(burst,sizeof(burst));
}
-// --- cAudioEncapsulatorDTS ---------------------------------------------------
+// --- cAudioEncapsulatorDTS --------------------------------------------------
-class cAudioEncapsulatorDTS : public cAudioEncapsulator {
+class cAudioEncapsulatorDTS : public cAudioEncapsulator
+{
private:
- virtual int SyncInfo(const uchar *buf);
- virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata);
+ virtual int SyncInfo(const uchar *buf);
+ virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags,
+ const uchar *PTSdata);
public:
- cAudioEncapsulatorDTS(cRingBufferFrame *rb, int StreamType);
- };
+ cAudioEncapsulatorDTS(cRingBufferFrame *rb, int StreamType);
+};
-cAudioEncapsulatorDTS::cAudioEncapsulatorDTS(cRingBufferFrame *rb, int StreamType)
-: cAudioEncapsulator(rb, StreamType)
+cAudioEncapsulatorDTS::cAudioEncapsulatorDTS(cRingBufferFrame *rb,
+ int StreamType)
+ : cAudioEncapsulator(rb, StreamType)
{}
int cAudioEncapsulatorDTS::SyncInfo(const uchar *buf)
{
- if ((buf[0] != 0x7F) ||
- (buf[1] != 0xfE) ||
- (buf[2] != 0x80) ||
- (buf[3] != 0x01)) return 0;
+ if ((buf[0] != 0x7F) ||
+ (buf[1] != 0xfE) ||
+ (buf[2] != 0x80) ||
+ (buf[3] != 0x01))
+ return 0;
- int length = ((buf[5] & 0x03) << 12) |
- ((buf[6] & 0xFF) << 4) |
- ((buf[7] & 0xF0) >> 4);
+ int length = ((buf[5] & 0x03) << 12) |
+ ((buf[6] & 0xFF) << 4) |
+ ((buf[7] & 0xF0) >> 4);
- return length + 1;
+ return length + 1;
}
-void cAudioEncapsulatorDTS::StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata)
+void cAudioEncapsulatorDTS::StartIECFrame(const uchar *buf, int length,
+ uchar PTSflags, const uchar *PTSdata)
{
- uchar ac5_type = ((buf[4] & 0x01) << 6) | ((buf[5] >>2) & 0x3F);
- uchar ac5_spdif_type;
- switch(ac5_type) {
- case 0x0F:
- ac5_spdif_type = 0x0B; /* DTS */
- break;
- case 0x1F:
- ac5_spdif_type = 0x0C; /* DTS */
- break;
- case 0x3F:
- ac5_spdif_type = 0x0D; /* DTS */
- break;
- default:
- ac5_spdif_type = 0x00; /* DTS */
- esyslog("DTS: SPDIF type not detected: ac5 type = %X!\n", ac5_type);
- break;
- }
-
- if (length > DTS_SIZE-IEC_HDR_SIZE) {
- DEBUG("DTS: length too long %d\n",length);
- return;
- }
-
- StartFrame(DTS_SIZE,PTSflags,PTSdata);
- fillup = DTS_SIZE-IEC_HDR_SIZE-length;
-
- // prepare IEC 60958 data frame
- uchar burst[IEC_HDR_SIZE];
- burst[0] = 0xF8;
- burst[1] = 0x72;
- burst[2] = 0x4E;
- burst[3] = 0x1F;
- burst[4] = 0x00;
- burst[5] = ac5_spdif_type; /* DTS data */
- burst[6] = ((length * 8) >> 8 ) & 0xFF; /* ac5_length * 8 */
- burst[7] = (length * 8) & 0xFF;
- PutData(burst,sizeof(burst));
+ uchar ac5_type = ((buf[4] & 0x01) << 6) | ((buf[5] >>2) & 0x3F);
+ uchar ac5_spdif_type;
+ switch(ac5_type)
+ {
+ case 0x0F:
+ ac5_spdif_type = 0x0B; // DTS
+ break;
+ case 0x1F:
+ ac5_spdif_type = 0x0C; // DTS
+ break;
+ case 0x3F:
+ ac5_spdif_type = 0x0D; // DTS
+ break;
+ default:
+ ac5_spdif_type = 0x00; // DTS
+ esyslog("DTS: SPDIF type not detected: ac5 type = %X!\n", ac5_type);
+ break;
+ }
+
+ if (length > DTS_SIZE-IEC_HDR_SIZE)
+ {
+ DEBUG("DTS: length too long %d\n", length);
+ return;
+ }
+
+ StartFrame(DTS_SIZE, PTSflags, PTSdata);
+ fillup = DTS_SIZE - IEC_HDR_SIZE - length;
+
+ // prepare IEC 60958 data frame
+ uchar burst[IEC_HDR_SIZE];
+ burst[0] = 0xF8;
+ burst[1] = 0x72;
+ burst[2] = 0x4E;
+ burst[3] = 0x1F;
+ burst[4] = 0x00;
+ burst[5] = ac5_spdif_type; // DTS data
+ burst[6] = ((length * 8) >> 8) & 0xFF; // ac5_length * 8
+ burst[7] = (length * 8) & 0xFF;
+ PutData(burst,sizeof(burst));
}
-// --- cMultichannelAudio ------------------------------------------------------
+// --- cMultichannelAudio -----------------------------------------------------
cMultichannelAudio::cMultichannelAudio(cRingBufferFrame *rb)
{
- encapsulator=0; ringBuffer=rb;
- fixed=false;
- if(!ringBuffer) DEBUG("multichannel: no ringbuffer!");
+ encapsulator = 0;
+ ringBuffer = rb;
+ fixed = false;
+ if (!ringBuffer)
+ DEBUG("multichannel: no ringbuffer!");
}
cMultichannelAudio::~cMultichannelAudio()
{
- delete encapsulator;
+ delete encapsulator;
}
void cMultichannelAudio::Clear()
{
- Lock();
- if(encapsulator) encapsulator->Clear();
- Unlock();
+ Lock();
+ if (encapsulator)
+ encapsulator->Clear();
+ Unlock();
}
void cMultichannelAudio::Reset()
{
- Lock();
- delete encapsulator; encapsulator=0;
- fixed=false;
- Unlock();
+ Lock();
+ delete encapsulator;
+ encapsulator = 0;
+ fixed = false;
+ Unlock();
}
/*
void cMultichannelAudio::Mute(bool Mute)
{
- Lock();
- if(encapsulator) encapsulator->Mute(Mute);
- Unlock();
+ Lock();
+ if (encapsulator)
+ encapsulator->Mute(Mute);
+ Unlock();
}
*/
int cMultichannelAudio::Check(uchar *b, int length, uchar *header)
{
- Lock();
- int res=0;
- ptsDelay=0; offset=0; ptsData=0;
-
- // get PTS information
- ptsFlags=header[7]>>6;
- if(ptsFlags) ptsData=&header[9];
-
- // AC3 frames may span over multiple PES packets. Unfortunaly the continuation
- // packets start with the aLPCM code sometimes. Some magic here to detect
- // this case.
- uchar subStreamType=b[0];
- if(subStreamType!=aVDR) subStreamType&=0xF8;
- bool aligned=header[6]&4;
- if(!aligned) {
- uchar ost=encapsulator ? encapsulator->StreamType() : 0;
- if(!ptsFlags) {
- if((subStreamType!=aLPCM && subStreamType!=aSPU) || fixed) {
- if(ost>0) {
- ED("multichannel: crossing -> keep encapsulator\n");
- subStreamType=ost;
- }
- else {
- ED("multichannel: crossing -> skip\n");
- res=1; goto out; // skip
- }
- }
- }
- else if(fixed && ost>0) {
- ED("multichannel: fixed unaligned -> keep encapsulator\n");
- subStreamType=ost;
- }
+ Lock();
+ int res = 0;
+ ptsDelay = 0;
+ offset = 0;
+ ptsData = 0;
+
+ // get PTS information
+ ptsFlags = header[7] >> 6;
+ if (ptsFlags)
+ ptsData = &header[9];
+
+ // AC3 frames may span over multiple PES packets. Unfortunately the
+ // continuation packets start with the aLPCM code sometimes. Some magic
+ // here to detect this case.
+ uchar subStreamType = b[0];
+ if (subStreamType != aVDR)
+ subStreamType&=0xF8;
+ bool aligned = header[6] & 4;
+ if (!aligned)
+ {
+ uchar ost = encapsulator ? encapsulator->StreamType() : 0;
+ if (!ptsFlags)
+ {
+ if ((subStreamType != aLPCM && subStreamType != aSPU) || fixed)
+ {
+ if (ost > 0)
+ {
+ ED("multichannel: crossing -> keep encapsulator\n");
+ subStreamType = ost;
+ }
+ else
+ {
+ ED("multichannel: crossing -> skip\n");
+ res = 1;
+ goto out; // skip
+ }
+ }
+ }
+ else if (fixed && ost > 0)
+ {
+ ED("multichannel: fixed unaligned -> keep encapsulator\n");
+ subStreamType = ost;
+ }
}
- fixed=false;
+ fixed = false;
- switch(subStreamType) {
+ switch (subStreamType)
+ {
case aDTS:
case aAC3:
- offset=4; // skip the DVD stream infos
- break;
+ offset = 4; // skip the DVD stream infos
+ break;
default:
- if(aligned || !ptsFlags) {
- if(encapsulator) {
- Reset();
- DEBUG("multichannel: interrupted encapsulator stream (unknown)\n");
- }
- DEBUG("multichannel: unknown substream type %x (skipped)\n",subStreamType);
- res=1; goto out; // skip
- }
- subStreamType=aVDR;
- ED("multichannel: assuming aVDR for unknown substream type\n");
- // fall through
+ if (aligned || !ptsFlags)
+ {
+ if (encapsulator)
+ {
+ Reset();
+ DEBUG("multichannel: interrupted encapsulator stream (unknown)\n");
+ }
+ DEBUG("multichannel: unknown substream type %x (skipped)\n",
+ subStreamType);
+ res = 1;
+ goto out; // skip
+ }
+ subStreamType = aVDR;
+ ED("multichannel: assuming aVDR for unknown substream type\n");
+ // fall through
case aVDR:
- fixed=true;
- break;
+ fixed = true;
+ break;
case aLPCM:
- if(encapsulator) {
- Reset();
- DEBUG("multichannel: interrupted encapsulator stream (LPCM)\n");
- }
- ED("multichannel: LPCM\n");
- res=2; goto out; // pass
+ if (encapsulator)
+ {
+ Reset();
+ DEBUG("multichannel: interrupted encapsulator stream (LPCM)\n");
+ }
+ ED("multichannel: LPCM\n");
+ res = 2;
+ goto out; // pass
case aSPU:
- ED("multichannel: SPU stream (skipped)\n");
- res=1; goto out; // skip
+ ED("multichannel: SPU stream (skipped)\n");
+ res = 1;
+ goto out; // skip
}
- // If the SubStreamType has changed then select the right encapsulator
- if(!encapsulator || encapsulator->StreamType()!=subStreamType) {
- DEBUG("multichannel: new encapsulator %x\n",subStreamType);
- Reset();
- switch(subStreamType) {
- case aAC3:
- case aVDR: // AC3
- encapsulator=new cAudioEncapsulatorAC3(ringBuffer,subStreamType);
- break;
- case aDTS: // Dts
- encapsulator=new cAudioEncapsulatorDTS(ringBuffer,subStreamType);
- break;
- }
- if(!encapsulator) {
- DEBUG("multichannel: no encapsulator\n");
- res=1; goto out; // skip
- }
+ // If the SubStreamType has changed then select the right encapsulator
+ if (!encapsulator || encapsulator->StreamType() != subStreamType)
+ {
+ DEBUG("multichannel: new encapsulator %x\n", subStreamType);
+ Reset();
+ switch (subStreamType)
+ {
+ case aAC3:
+ case aVDR: // AC3
+ encapsulator = new cAudioEncapsulatorAC3(ringBuffer,subStreamType);
+ break;
+ case aDTS: // Dts
+ encapsulator = new cAudioEncapsulatorDTS(ringBuffer,subStreamType);
+ break;
+ }
+ if (!encapsulator)
+ {
+ DEBUG("multichannel: no encapsulator\n");
+ res = 1;
+ goto out; // skip
+ }
}
out:
- ED("HEADER type=%x sub=%x ptsflags=%d length=%d\n",header[3],subStreamType,ptsFlags,length);
- ED("head: "); for(int k=0 ; k<24 ; k++) ED("%02x ",header[k]);
- ED("\ndata: "); for(int k=0 ; k<24 ; k++) ED("%02x ",b[k]);
- ED("\n");
+ ED("HEADER type=%x sub=%x ptsflags=%d length=%d\n",
+ header[3], subStreamType, ptsFlags, length);
+ ED("head: "); for(int k = 0; k < 24; k++) ED("%02x ", header[k]);
+ ED("\ndata: "); for(int k = 0; k < 24; k++) ED("%02x ", b[k]);
+ ED("\n");
- Unlock(); return res;
+ Unlock();
+ return res;
}
void cMultichannelAudio::Encapsulate(uchar *b, int length)
{
- Lock();
- if(offset && ptsFlags) { // get start of the packet to which the PTS belong (DVD only)
- if(offset>=2 && length>offset-2) ptsDelay|=b[offset-2]*256;
- if(offset>=1 && length>offset-1) ptsDelay|=b[offset-1];
+ Lock();
+ if(offset && ptsFlags)
+ { // get start of the packet to which the PTS belong (DVD only)
+ if (offset >= 2 && length > offset - 2)
+ ptsDelay |= b[offset - 2] * 256;
+ if (offset >= 1 && length > offset - 1)
+ ptsDelay |= b[offset - 1];
}
- if(length>=offset) {
- if(encapsulator)
- encapsulator->Decode(b+offset,length-offset,ptsFlags,ptsDelay,ptsData);
- ptsFlags=0; ptsDelay=0; offset=0; ptsData=0;
+ if (length >= offset)
+ {
+ if (encapsulator)
+ encapsulator->Decode(b+offset, length - offset, ptsFlags,
+ ptsDelay, ptsData);
+ ptsFlags = 0;
+ ptsDelay = 0;
+ offset = 0;
+ ptsData = 0;
}
- else offset-=length;
- Unlock();
+ else
+ offset -= length;
+ Unlock();
}
// Local variables: