summaryrefslogtreecommitdiff
path: root/dxr3multichannelaudio.c
diff options
context:
space:
mode:
authorscop <scop>2005-04-18 19:26:16 +0000
committerscop <scop>2005-04-18 19:26:16 +0000
commitf8a3d81fc0b548a0f76e205fee433e4c94a4ee57 (patch)
tree2f69513d7d57e15b920c8eb4bb4b4a877d5b0881 /dxr3multichannelaudio.c
parent37c4c7b0a4a388d6c933e95756ddd30dd0cca6fd (diff)
downloadvdr-plugin-dxr3-f8a3d81fc0b548a0f76e205fee433e4c94a4ee57.tar.gz
vdr-plugin-dxr3-f8a3d81fc0b548a0f76e205fee433e4c94a4ee57.tar.bz2
Oops, wrong tree... revert.
Diffstat (limited to 'dxr3multichannelaudio.c')
-rw-r--r--dxr3multichannelaudio.c298
1 files changed, 149 insertions, 149 deletions
diff --git a/dxr3multichannelaudio.c b/dxr3multichannelaudio.c
index 673fee5..1f1471d 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"
@@ -38,7 +38,7 @@
// --- cAudioEncapsulator ------------------------------------------------------
class cAudioEncapsulator {
- private:
+private:
int totalSize, frameCount;
cFrame *frame;
uchar *frameData;
@@ -52,7 +52,7 @@ class cAudioEncapsulator {
//
void NewFrame(uchar PTSflags, const uchar *PTSdata);
void SyncFound(const uchar *data);
- protected:
+protected:
int streamType;
cRingBufferFrame *ringBuffer;
int fillup, firstBurst;
@@ -66,14 +66,14 @@ class cAudioEncapsulator {
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:
+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::cAudioEncapsulator(cRingBufferFrame *rb, int StreamType)
{
@@ -100,7 +100,7 @@ void cAudioEncapsulator::StartFrame(int size, uchar PTSflags, const uchar *PTSda
if(frame) {
DEBUG("StartFrame() with unfinished frame!\n");
FinishFrame();
- }
+ }
ED("StartFrame: size=%d ptsFlags=%d\n",size,PTSflags);
totalSize=size;
NewFrame(PTSflags,PTSdata);
@@ -111,7 +111,7 @@ void cAudioEncapsulator::NewFrame(uchar PTSflags, const uchar *PTSdata)
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);
@@ -149,9 +149,9 @@ void cAudioEncapsulator::NewFrame(uchar PTSflags, const uchar *PTSdata)
buf[6] = 0x81;
PutData(buf,7);
return;
- }
+ }
else { free(frameData); frameData=0; }
- }
+ }
esyslog("Failed to build frame for audio encapsulation");
}
@@ -160,14 +160,14 @@ void cAudioEncapsulator::FinishFrame(void)
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;
+ }
}
- }
frame=0; frameData=0; frameCount=0;
}
@@ -180,7 +180,7 @@ void cAudioEncapsulator::PutData(const uchar *data, int len)
if(data) {
memcpy(frameData,data,l);
data += l;
- }
+ }
else memset(frameData,0,l);
frameData += l; len -= l; frameCount -= l;
@@ -188,9 +188,9 @@ void cAudioEncapsulator::PutData(const uchar *data, int len)
if (!frameCount) {
FinishFrame();
if (totalSize > 0) NewFrame(0,0);
+ }
}
}
- }
}
void cAudioEncapsulator::SendIECpause(int type, uchar PTSflags, const uchar *PTSdata)
@@ -204,26 +204,26 @@ void cAudioEncapsulator::SendIECpause(int type, uchar PTSflags, const uchar *PTS
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;
- 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;
- 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;
- }
+ default:
+ case 0:
+ 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;
+ 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;
+ }
PutData(burst,sizeof(burst));
PutData(0,AC3_SIZE-sizeof(burst));
FinishFrame();
@@ -236,7 +236,7 @@ void cAudioEncapsulator::FinishIECFrame(void)
ED("FinishIECFrame: fillup=%d\n",fillup);
if (fillup) PutData(0,fillup);
FinishFrame();
- }
+ }
muteData=false; fillup=0;
}
@@ -248,16 +248,16 @@ void cAudioEncapsulator::SyncFound(const uchar *data)
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;
- }
+ }
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;
@@ -276,31 +276,31 @@ void cAudioEncapsulator::Decode(const uchar *data, int len, uchar PTSflags, int
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;
- }
- }
- */
+ 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: 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("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("\n");
}
}
#endif
@@ -316,36 +316,36 @@ void cAudioEncapsulator::Decode(const uchar *data, int len, uchar PTSflags, int
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) {
@@ -356,53 +356,53 @@ void cAudioEncapsulator::Decode(const uchar *data, int len, uchar PTSflags, int
FinishIECFrame();
length = have = 0;
continue;
- }
+ }
+ }
}
}
- }
ED("Decode: leave length=%d have=%d len=%d used=%d\n",length,have,len,used);
}
// --- cAudioEncapsulatorAC3 ---------------------------------------------------
class cAudioEncapsulatorAC3 : public cAudioEncapsulator {
- private:
+private:
virtual int SyncInfo(const uchar *buf);
virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata);
- public:
+public:
cAudioEncapsulatorAC3(cRingBufferFrame *rb, int StreamType);
-};
+ };
cAudioEncapsulatorAC3::cAudioEncapsulatorAC3(cRingBufferFrame *rb, int StreamType)
- :cAudioEncapsulator(rb, 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};
+ 128, 160, 192, 224, 256, 320, 384, 448,
+ 512, 576, 640};
if ((buf[0] != 0x0B) || (buf[1] != 0x77)) /* syncword */
- return 0;
+ return 0;
if (buf[5] >= 0x60) /* bsid >= 12 */
- return 0;
+ return 0;
int frmsizecod = buf[4] & 63;
if (frmsizecod >= 38)
- return 0;
+ return 0;
int bitrate = rate[frmsizecod >> 1];
switch (buf[4] & 0xC0) {
case 0:
- return 4 * bitrate;
+ return 4 * bitrate;
case 0x40:
- return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
+ return 2 * (320 * bitrate / 147 + (frmsizecod & 1));
case 0x80:
- return 6 * bitrate;
+ return 6 * bitrate;
default:
- return 0;
- }
+ return 0;
+ }
}
void cAudioEncapsulatorAC3::StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata)
@@ -426,15 +426,15 @@ void cAudioEncapsulatorAC3::StartIECFrame(const uchar *buf, int length, uchar PT
// --- cAudioEncapsulatorDTS ---------------------------------------------------
class cAudioEncapsulatorDTS : public cAudioEncapsulator {
- private:
+private:
virtual int SyncInfo(const uchar *buf);
virtual void StartIECFrame(const uchar *buf, int length, uchar PTSflags, const uchar *PTSdata);
- public:
+public:
cAudioEncapsulatorDTS(cRingBufferFrame *rb, int StreamType);
-};
+ };
cAudioEncapsulatorDTS::cAudioEncapsulatorDTS(cRingBufferFrame *rb, int StreamType)
- : cAudioEncapsulator(rb, StreamType)
+: cAudioEncapsulator(rb, StreamType)
{}
int cAudioEncapsulatorDTS::SyncInfo(const uchar *buf)
@@ -445,8 +445,8 @@ int cAudioEncapsulatorDTS::SyncInfo(const uchar *buf)
(buf[3] != 0x01)) return 0;
int length = ((buf[5] & 0x03) << 12) |
- ((buf[6] & 0xFF) << 4) |
- ((buf[7] & 0xF0) >> 4);
+ ((buf[6] & 0xFF) << 4) |
+ ((buf[7] & 0xF0) >> 4);
return length + 1;
}
@@ -457,24 +457,24 @@ void cAudioEncapsulatorDTS::StartIECFrame(const uchar *buf, int length, uchar PT
uchar ac5_spdif_type;
switch(ac5_type) {
case 0x0F:
- ac5_spdif_type = 0x0B; /* DTS */
- break;
+ ac5_spdif_type = 0x0B; /* DTS */
+ break;
case 0x1F:
- ac5_spdif_type = 0x0C; /* DTS */
- break;
+ ac5_spdif_type = 0x0C; /* DTS */
+ break;
case 0x3F:
- ac5_spdif_type = 0x0D; /* DTS */
- break;
+ 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;
- }
+ 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;
- }
+ DEBUG("DTS: length too long %d\n",length);
+ return;
+ }
StartFrame(DTS_SIZE,PTSflags,PTSdata);
fillup = DTS_SIZE-IEC_HDR_SIZE-length;
@@ -522,12 +522,12 @@ void cMultichannelAudio::Reset()
}
/*
- void cMultichannelAudio::Mute(bool Mute)
- {
+void cMultichannelAudio::Mute(bool Mute)
+{
Lock();
if(encapsulator) encapsulator->Mute(Mute);
Unlock();
- }
+}
*/
int cMultichannelAudio::Check(uchar *b, int length, uchar *header)
@@ -553,72 +553,72 @@ int cMultichannelAudio::Check(uchar *b, int length, uchar *header)
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;
switch(subStreamType) {
- case aDTS:
- case aAC3:
- offset=4; // skip the DVD stream infos
- break;
- default:
- if(aligned || !ptsFlags) {
+ case aDTS:
+ case aAC3:
+ 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
+ case aVDR:
+ fixed=true;
+ break;
+ case aLPCM:
if(encapsulator) {
- Reset();
- DEBUG("multichannel: interrupted encapsulator stream (unknown)\n");
- }
- DEBUG("multichannel: unknown substream type %x (skipped)\n",subStreamType);
+ 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
}
- subStreamType=aVDR;
- ED("multichannel: assuming aVDR for unknown substream type\n");
- // fall through
- case aVDR:
- fixed=true;
- break;
- case aLPCM:
- 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
- }
// 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;
- }
+ 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:
+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]);
@@ -633,12 +633,12 @@ void cMultichannelAudio::Encapsulate(uchar *b, int length)
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;
- }
+ }
else offset-=length;
Unlock();
}