1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

AC3 fixes from Andreas Schultz

This commit is contained in:
Klaus Schmidinger 2001-08-05 15:46:21 +02:00
parent 2276d81677
commit 6329146bd8

104
dvbapi.c
View File

@ -6,7 +6,7 @@
* *
* DVD support initially written by Andreas Schultz <aschultz@warp10.net> * DVD support initially written by Andreas Schultz <aschultz@warp10.net>
* *
* $Id: dvbapi.c 1.98 2001/08/05 12:17:02 kls Exp $ * $Id: dvbapi.c 1.99 2001/08/05 15:46:21 kls Exp $
*/ */
//#define DVDDEBUG 1 //#define DVDDEBUG 1
@ -1187,6 +1187,8 @@ private:
int GetPESHeaderLength(const uchar *Data); int GetPESHeaderLength(const uchar *Data);
int SendPCM(int size); int SendPCM(int size);
void playDecodedAC3(void); void playDecodedAC3(void);
void handleAC3(unsigned char *sector, int length);
void putFrame(unsigned char *sector, int length);
unsigned int getAudioStream(unsigned int StreamId); unsigned int getAudioStream(unsigned int StreamId);
void setChapid(void); void setChapid(void);
void NextState(int State) { prevcycle = cyclestate; cyclestate = State; } void NextState(int State) { prevcycle = cyclestate; cyclestate = State; }
@ -1210,6 +1212,9 @@ public:
#define cOUTPACK 5 #define cOUTPACK 5
#define cOUTFRAMES 6 #define cOUTFRAMES 6
#define aAC3 0x80
#define aLPCM 0xA0
cDVDplayBuffer::cDVDplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, cDVD *DvD, int title) cDVDplayBuffer::cDVDplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, cDVD *DvD, int title)
:cPlayBuffer(DvbApi, VideoDev, AudioDev) :cPlayBuffer(DvbApi, VideoDev, AudioDev)
{ {
@ -1257,13 +1262,13 @@ unsigned int cDVDplayBuffer::getAudioStream(unsigned int StreamId)
int track = (cur_pgc->audio_control[StreamId] >> 8) & 0x07; int track = (cur_pgc->audio_control[StreamId] >> 8) & 0x07;
switch (vts_file->vtsi_mat->vts_audio_attr[track].audio_format) { switch (vts_file->vtsi_mat->vts_audio_attr[track].audio_format) {
case 0: // ac3 case 0: // ac3
trackID = 0x80; trackID = aAC3;
break; break;
case 2: // mpeg1 case 2: // mpeg1
case 3: // mpeg2ext case 3: // mpeg2ext
case 4: // lpcm case 4: // lpcm
case 6: // dts case 6: // dts
trackID = 0xC0; trackID = aLPCM;
break; break;
default: esyslog(LOG_ERR, "ERROR: unknown Audio stream info"); default: esyslog(LOG_ERR, "ERROR: unknown Audio stream info");
return 0; return 0;
@ -1765,7 +1770,7 @@ int cDVDplayBuffer::SendPCM(int size)
buffer[7] = 0x00; buffer[7] = 0x00;
buffer[8] = 0x00; buffer[8] = 0x00;
buffer[9] = 0xa0; // substream ID buffer[9] = aLPCM; // substream ID
buffer[10] = 0x00; // other stuff (see DVD specs), ignored by driver buffer[10] = 0x00; // other stuff (see DVD specs), ignored by driver
buffer[11] = 0x00; buffer[11] = 0x00;
buffer[12] = 0x00; buffer[12] = 0x00;
@ -1775,9 +1780,7 @@ int cDVDplayBuffer::SendPCM(int size)
length += 6; length += 6;
cFrame *frame = new cFrame(buffer, length); putFrame(buffer, length);
while (Busy() && !blockInput && !Put(frame))
;
size -= MAXSIZE; size -= MAXSIZE;
} }
return 0; return 0;
@ -1802,6 +1805,37 @@ void cDVDplayBuffer::playDecodedAC3(void)
lpcm_count=0; lpcm_count=0;
} }
void cDVDplayBuffer::handleAC3(unsigned char *sector, int length)
{
if (dolbyDev) {
while (length > 0) {
int w = fwrite(sector, 1, length , dolbyDev);
if (w < 0) {
LOG_ERROR;
break;
}
length -= w;
sector += w;
}
}
else {
if (ac3stat == AC3_PLAY)
ac3_decode_data(sector, sector+length, 0, &ac3inp, &ac3outp, (char *)ac3data);
else if (ac3stat == AC3_START) {
ac3_decode_data(sector, sector+length, 1, &ac3inp, &ac3outp, (char *)ac3data);
ac3stat = AC3_PLAY;
}
}
//playDecodedAC3();
}
void cDVDplayBuffer::putFrame(unsigned char *sector, int length)
{
cFrame *frame = new cFrame(sector, length);
while (Busy() && !blockInput && !Put(frame))
;
}
int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode) int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode)
{ {
uchar pt = 1; uchar pt = 1;
@ -1818,9 +1852,10 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode)
int offset = 14 + GetStuffingLen(sector); int offset = 14 + GetStuffingLen(sector);
sector += offset; sector += offset;
int r = DVD_VIDEO_LB_LEN - offset; int r = DVD_VIDEO_LB_LEN - offset;
int ac3datalen = r; int datalen = r;
sector[6] &= 0x8f; sector[6] &= 0x8f;
uchar *data = sector;
switch (GetPacketType(sector)) { switch (GetPacketType(sector)) {
case VIDEO_STREAM_S ... VIDEO_STREAM_E: case VIDEO_STREAM_S ... VIDEO_STREAM_E:
@ -1840,12 +1875,12 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode)
} }
case PRIVATE_STREAM1: case PRIVATE_STREAM1:
{ {
ac3datalen = GetPacketLength(sector); datalen = GetPacketLength(sector);
//skip optional Header bytes //skip optional Header bytes
ac3datalen -= GetPESHeaderLength(sector); datalen -= GetPESHeaderLength(sector);
sector += GetPESHeaderLength(sector); data += GetPESHeaderLength(sector);
//skip mandatory header bytes //skip mandatory header bytes
sector += 3; data += 3;
//fallthrough is intended //fallthrough is intended
} }
case PRIVATE_STREAM2: case PRIVATE_STREAM2:
@ -1857,33 +1892,24 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode)
return 1; return 1;
// skip PS header bytes // skip PS header bytes
sector += 6; data += 6;
//we are now at the beginning of the payload // data now points to the beginning of the payload
//correct ac3 data lenght - FIXME: why 13 ??? if (audioTrack == *data) {
ac3datalen -= 13; switch (audioTrack & 0xF8) {
if (audioTrack == *sector) { case aAC3:
sector +=4; data += 4;
if (dolbyDev) { // correct a3 data lenght - FIXME: why 13 ???
while (ac3datalen > 0) { datalen -= 13;
int w = fwrite(sector, 1, ac3datalen , dolbyDev); handleAC3(data, datalen);
if (w < 0) { break;
LOG_ERROR; case aLPCM:
// write(audio, sector+14 , sector[19]+(sector[18]<<8)+6);
putFrame(sector, GetPacketLength(sector));
break;
default:
break; break;
} }
ac3datalen -= w;
sector += w;
}
}
else {
if (ac3stat == AC3_PLAY)
ac3_decode_data(sector, sector+ac3datalen, 0, &ac3inp, &ac3outp, (char *)ac3data);
else if (ac3stat == AC3_START) {
ac3_decode_data(sector, sector+ac3datalen, 1, &ac3inp, &ac3outp, (char *)ac3data);
ac3stat = AC3_PLAY;
}
}
//playDecodedAC3();
} }
return pt; return pt;
} }
@ -1908,10 +1934,8 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode)
return pt; return pt;
} }
} }
cFrame *frame = new cFrame(sector, r); putFrame(sector, r);
while (Busy() && !blockInput && !Put(frame)) if ((audioTrack & 0xF8) == aAC3)
;
playDecodedAC3(); playDecodedAC3();
return pt; return pt;
} }