diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2001-08-05 15:46:21 +0200 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2001-08-05 15:46:21 +0200 |
commit | 6329146bd8d3ef245ad21b042247277cd094fc51 (patch) | |
tree | 5029c939acfa3602906d98812f981085ca43cf63 /dvbapi.c | |
parent | 2276d81677bea4785f42c5308fd02ae0406f766f (diff) | |
download | vdr-6329146bd8d3ef245ad21b042247277cd094fc51.tar.gz vdr-6329146bd8d3ef245ad21b042247277cd094fc51.tar.bz2 |
AC3 fixes from Andreas Schultz
Diffstat (limited to 'dvbapi.c')
-rw-r--r-- | dvbapi.c | 114 |
1 files changed, 69 insertions, 45 deletions
@@ -6,7 +6,7 @@ * * 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 @@ -1187,6 +1187,8 @@ private: int GetPESHeaderLength(const uchar *Data); int SendPCM(int size); void playDecodedAC3(void); + void handleAC3(unsigned char *sector, int length); + void putFrame(unsigned char *sector, int length); unsigned int getAudioStream(unsigned int StreamId); void setChapid(void); void NextState(int State) { prevcycle = cyclestate; cyclestate = State; } @@ -1210,6 +1212,9 @@ public: #define cOUTPACK 5 #define cOUTFRAMES 6 +#define aAC3 0x80 +#define aLPCM 0xA0 + cDVDplayBuffer::cDVDplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, cDVD *DvD, int title) :cPlayBuffer(DvbApi, VideoDev, AudioDev) { @@ -1257,13 +1262,13 @@ unsigned int cDVDplayBuffer::getAudioStream(unsigned int StreamId) int track = (cur_pgc->audio_control[StreamId] >> 8) & 0x07; switch (vts_file->vtsi_mat->vts_audio_attr[track].audio_format) { case 0: // ac3 - trackID = 0x80; + trackID = aAC3; break; case 2: // mpeg1 case 3: // mpeg2ext case 4: // lpcm case 6: // dts - trackID = 0xC0; + trackID = aLPCM; break; default: esyslog(LOG_ERR, "ERROR: unknown Audio stream info"); return 0; @@ -1765,8 +1770,8 @@ int cDVDplayBuffer::SendPCM(int size) buffer[7] = 0x00; buffer[8] = 0x00; - buffer[9] = 0xa0; // substream ID - buffer[10] = 0x00; // other stuff (see DVD specs), ignored by driver + buffer[9] = aLPCM; // substream ID + buffer[10] = 0x00; // other stuff (see DVD specs), ignored by driver buffer[11] = 0x00; buffer[12] = 0x00; buffer[13] = 0x00; @@ -1775,9 +1780,7 @@ int cDVDplayBuffer::SendPCM(int size) length += 6; - cFrame *frame = new cFrame(buffer, length); - while (Busy() && !blockInput && !Put(frame)) - ; + putFrame(buffer, length); size -= MAXSIZE; } return 0; @@ -1802,6 +1805,37 @@ void cDVDplayBuffer::playDecodedAC3(void) 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) { uchar pt = 1; @@ -1818,9 +1852,10 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode) int offset = 14 + GetStuffingLen(sector); sector += offset; int r = DVD_VIDEO_LB_LEN - offset; - int ac3datalen = r; + int datalen = r; sector[6] &= 0x8f; + uchar *data = sector; switch (GetPacketType(sector)) { case VIDEO_STREAM_S ... VIDEO_STREAM_E: @@ -1840,12 +1875,12 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode) } case PRIVATE_STREAM1: { - ac3datalen = GetPacketLength(sector); + datalen = GetPacketLength(sector); //skip optional Header bytes - ac3datalen -= GetPESHeaderLength(sector); - sector += GetPESHeaderLength(sector); + datalen -= GetPESHeaderLength(sector); + data += GetPESHeaderLength(sector); //skip mandatory header bytes - sector += 3; + data += 3; //fallthrough is intended } case PRIVATE_STREAM2: @@ -1857,33 +1892,24 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode) return 1; // skip PS header bytes - sector += 6; - //we are now at the beginning of the payload - - //correct ac3 data lenght - FIXME: why 13 ??? - ac3datalen -= 13; - if (audioTrack == *sector) { - sector +=4; - if (dolbyDev) { - while (ac3datalen > 0) { - int w = fwrite(sector, 1, ac3datalen , dolbyDev); - if (w < 0) { - LOG_ERROR; - 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(); + data += 6; + // data now points to the beginning of the payload + + if (audioTrack == *data) { + switch (audioTrack & 0xF8) { + case aAC3: + data += 4; + // correct a3 data lenght - FIXME: why 13 ??? + datalen -= 13; + handleAC3(data, datalen); + break; + case aLPCM: + // write(audio, sector+14 , sector[19]+(sector[18]<<8)+6); + putFrame(sector, GetPacketLength(sector)); + break; + default: + break; + } } return pt; } @@ -1908,11 +1934,9 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, int trickMode) return pt; } } - cFrame *frame = new cFrame(sector, r); - while (Busy() && !blockInput && !Put(frame)) - ; - - playDecodedAC3(); + putFrame(sector, r); + if ((audioTrack & 0xF8) == aAC3) + playDecodedAC3(); return pt; } |