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

Added PTS to the converted PCM audio when replaying a DVD

This commit is contained in:
Klaus Schmidinger 2001-11-03 11:05:15 +01:00
parent 57bd015bcb
commit d78d555b27
5 changed files with 257 additions and 211 deletions

View File

@ -115,6 +115,7 @@ Helmut Sch
Andreas Schultz <aschultz@warp10.net> Andreas Schultz <aschultz@warp10.net>
for adding support for replaying DVDs (much of this was derived from for adding support for replaying DVDs (much of this was derived from
dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si>) dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si>)
for adding PTS to the converted PCM audio when replaying a DVD
Aaron Holtzman Aaron Holtzman
for writing 'ac3dec' for writing 'ac3dec'

View File

@ -831,7 +831,7 @@ Video Disk Recorder Revision History
- Fixed handling trick modes near the beginning and end of a recording. - Fixed handling trick modes near the beginning and end of a recording.
- Pressing the "Back" button while replaying a DVD now leads to the DVD menu. - Pressing the "Back" button while replaying a DVD now leads to the DVD menu.
2001-10-28: Version 0.98 2001-11-03: Version 0.98
- Completed storing the current audio volume in the setup.conf file (thanks - Completed storing the current audio volume in the setup.conf file (thanks
to Andy Grobb). to Andy Grobb).
@ -851,3 +851,6 @@ Video Disk Recorder Revision History
on an other free DVB card (if one is free at the moment). See MANUAL for on an other free DVB card (if one is free at the moment). See MANUAL for
details. details.
- Added some missing teletext PIDs (thanks to Norbert Schmidt). - Added some missing teletext PIDs (thanks to Norbert Schmidt).
- Added PTS to the converted PCM audio when replaying a DVD (thanks to Andreas
Schultz). Now the audio and video of a DVD replayed over the DVB card's A/V
out should always be in sync.

415
dvbapi.c
View File

@ -7,7 +7,7 @@
* DVD support initially written by Andreas Schultz <aschultz@warp10.net> * DVD support initially written by Andreas Schultz <aschultz@warp10.net>
* based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si> * based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si>
* *
* $Id: dvbapi.c 1.133 2001/10/27 13:00:29 kls Exp $ * $Id: dvbapi.c 1.134 2001/11/03 10:59:34 kls Exp $
*/ */
//#define DVDDEBUG 1 //#define DVDDEBUG 1
@ -713,7 +713,10 @@ protected:
void TrickSpeed(int Increment); void TrickSpeed(int Increment);
virtual void Empty(bool Block = false); virtual void Empty(bool Block = false);
virtual void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00) {} virtual void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00) {}
virtual void PlayExternalDolby(const uchar *b, int MaxLength);
virtual void Output(void); virtual void Output(void);
void putFrame(cFrame *Frame);
void putFrame(unsigned char *Data, int Length, eFrameType Type = ftUnknown);
public: public:
cPlayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev); cPlayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev);
virtual ~cPlayBuffer(); virtual ~cPlayBuffer();
@ -759,6 +762,28 @@ cPlayBuffer::~cPlayBuffer()
{ {
} }
void cPlayBuffer::PlayExternalDolby(const uchar *b, int MaxLength)
{
if (dolbyDev) {
if (b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01) {
if (b[3] == 0xBD) { // dolby
int l = b[4] * 256 + b[5] + 6;
int written = b[8] + 9; // skips the PES header
int n = min(l - written, MaxLength);
while (n > 0) {
int w = fwrite(&b[written], 1, n, dolbyDev);
if (w < 0) {
LOG_ERROR;
break;
}
n -= w;
written += w;
}
}
}
}
}
void cPlayBuffer::Output(void) void cPlayBuffer::Output(void)
{ {
dsyslog(LOG_INFO, "output thread started (pid=%d)", getpid()); dsyslog(LOG_INFO, "output thread started (pid=%d)", getpid());
@ -771,6 +796,9 @@ void cPlayBuffer::Output(void)
} }
const cFrame *frame = Get(); const cFrame *frame = Get();
if (frame) { if (frame) {
if (frame->Type() == ftDolby)
PlayExternalDolby(frame->Data(), frame->Count());
else {
StripAudioPackets((uchar *)frame->Data(), frame->Count(), (playMode == pmFast || playMode == pmSlow) ? 0x00 : audioTrack);//XXX StripAudioPackets((uchar *)frame->Data(), frame->Count(), (playMode == pmFast || playMode == pmSlow) ? 0x00 : audioTrack);//XXX
const uchar *p = frame->Data(); const uchar *p = frame->Data();
int r = frame->Count(); int r = frame->Count();
@ -789,6 +817,7 @@ void cPlayBuffer::Output(void)
} }
writeIndex = frame->Index(); writeIndex = frame->Index();
backTrace.Add(frame->Index(), frame->Count()); backTrace.Add(frame->Index(), frame->Count());
}
Drop(frame); Drop(frame);
} }
} }
@ -796,6 +825,20 @@ void cPlayBuffer::Output(void)
dsyslog(LOG_INFO, "output thread ended (pid=%d)", getpid()); dsyslog(LOG_INFO, "output thread ended (pid=%d)", getpid());
} }
void cPlayBuffer::putFrame(cFrame *Frame)
{
while (Busy() && !blockInput) {
if (Put(Frame))
return;
}
delete Frame; // caller relies on frame being put, otherwise this would be a memory leak!
}
void cPlayBuffer::putFrame(unsigned char *Data, int Length, eFrameType Type)
{
putFrame(new cFrame(Data, Length, Type));
}
void cPlayBuffer::TrickSpeed(int Increment) void cPlayBuffer::TrickSpeed(int Increment)
{ {
int nts = trickSpeed + Increment; int nts = trickSpeed + Increment;
@ -1089,11 +1132,8 @@ void cReplayBuffer::Input(void)
} }
else // allows replay even if the index file is missing else // allows replay even if the index file is missing
r = read(replayFile, b, sizeof(b)); r = read(replayFile, b, sizeof(b));
if (r > 0) { if (r > 0)
cFrame *frame = new cFrame(b, r, readIndex); putFrame(new cFrame(b, r, ftUnknown, readIndex));
while (Busy() && !blockInput && !Put(frame))
;
}
else if (r == 0) else if (r == 0)
eof = true; eof = true;
else if (r < 0 && FATALERRNO) { else if (r < 0 && FATALERRNO) {
@ -1117,19 +1157,8 @@ void cReplayBuffer::StripAudioPackets(uchar *b, int Length, uchar Except)
int l = b[i + 4] * 256 + b[i + 5] + 6; int l = b[i + 4] * 256 + b[i + 5] + 6;
switch (c) { switch (c) {
case 0xBD: // dolby case 0xBD: // dolby
if (Except && dolbyDev) { if (Except && dolbyDev)
int written = b[i + 8] + 9; // skips the PES header PlayExternalDolby(&b[i], Length - i);
int n = l - written;
while (n > 0) {
int w = fwrite(&b[i + written], 1, n, dolbyDev);
if (w < 0) {
LOG_ERROR;
break;
}
n -= w;
written += w;
}
}
// continue with deleting the data - otherwise it disturbs DVB replay // continue with deleting the data - otherwise it disturbs DVB replay
case 0xC0 ... 0xC1: // audio case 0xC0 ... 0xC1: // audio
if (c == 0xC1) if (c == 0xC1)
@ -1290,10 +1319,166 @@ bool cReplayBuffer::NextFile(uchar FileNumber, int FileOffset)
} }
#ifdef DVDSUPPORT #ifdef DVDSUPPORT
#define SYSTEM_HEADER 0xBB
#define PROG_STREAM_MAP 0xBC
#ifndef PRIVATE_STREAM1
#define PRIVATE_STREAM1 0xBD
#endif
#define PADDING_STREAM 0xBE
#ifndef PRIVATE_STREAM2
#define PRIVATE_STREAM2 0xBF
#endif
#define AUDIO_STREAM_S 0xC0
#define AUDIO_STREAM_E 0xDF
#define VIDEO_STREAM_S 0xE0
#define VIDEO_STREAM_E 0xEF
#define ECM_STREAM 0xF0
#define EMM_STREAM 0xF1
#define DSM_CC_STREAM 0xF2
#define ISO13522_STREAM 0xF3
#define PROG_STREAM_DIR 0xFF
#define cOPENDVD 0
#define cOPENTITLE 1
#define cOPENCHAPTER 2
#define cOUTCELL 3
#define cREADFRAME 4
#define cOUTPACK 5
#define cOUTFRAMES 6
#define aAC3 0x80
#define aLPCM 0xA0
// --- cAC3toPCM -------------------------------------------------------------
class cAC3toPCM {
private:
enum { AC3_STOP, AC3_START, AC3_PLAY } ac3stat;
uchar *ac3data;
int ac3inp;
int ac3outp;
public:
cAC3toPCM(void);
~cAC3toPCM();
void Clear(void);
void Put(unsigned char *sector, int length);
cFrame *Get(int size, uchar PTSflags = 0, uchar *PTSdata = 0);
};
cAC3toPCM::cAC3toPCM(void)
{
ac3dec_init();
ac3data = new uchar[AC3_BUFFER_SIZE];
Clear();
}
cAC3toPCM::~cAC3toPCM()
{
delete ac3data;
}
void cAC3toPCM::Clear(void)
{
ac3stat = AC3_START;
ac3outp = ac3inp = 0;
}
void cAC3toPCM::Put(unsigned char *sector, int length)
{
ac3dec_decode_data(sector, sector + length, ac3stat == AC3_START, &ac3inp, &ac3outp, (char *)ac3data);
ac3stat = AC3_PLAY;
}
// data=PCM samples, 16 bit, LSB first, 48kHz, stereo
cFrame *cAC3toPCM::Get(int size, uchar PTSflags, uchar *PTSdata)
{
if (ac3inp == ac3outp)
return NULL;
#define MAXSIZE 2022
uchar buffer[2048];
uchar *data;
if (size > 0) {
int p_size = (size > MAXSIZE) ? MAXSIZE : size;
int length = 10; // default header bytes
int header = 0;
int stuffb = 0;
switch (PTSflags) {
case 2: header = 5; // additional header bytes
stuffb = 1;
break;
case 3: header = 10;
break;
default: header = 0;
}
// header = 0; //XXX ???
stuffb = 0; //XXX ???
length += header;
length += stuffb;
buffer[0] = 0x00;
buffer[1] = 0x00;
buffer[2] = 0x01;
buffer[3] = PRIVATE_STREAM1;
buffer[6] = 0x80;
buffer[7] = PTSflags << 6;
buffer[8] = header + stuffb;
if (header)
memcpy(&buffer[9], (void *)PTSdata, header);
// add stuffing
data = buffer + 9 + header;
for (int cnt = 0; cnt < stuffb; cnt++)
data[cnt] = 0xff;
length += stuffb;
// add data
data = buffer + 9 + header + stuffb + 7;
int cnt = 0;
while (p_size) {
if (ac3outp != ac3inp) { // data in the buffer
data[cnt ^ 1] = ac3data[ac3outp]; // swab because ac3dec delivers wrong byteorder (the "xor" (^) is a swab!)
p_size--;
cnt++;
length++;
ac3outp = (ac3outp + 1) % AC3_BUFFER_SIZE;
}
else
break;
}
data = buffer + 9 + header + stuffb;
data[0] = aLPCM; // substream ID
data[1] = 0x00; // other stuff (see DVB specs), ignored by driver
data[2] = 0x00;
data[3] = 0x00;
data[4] = 0x00;
data[5] = 0x00;
data[6] = 0x00;
buffer[4] = (length >> 8) & 0xff;
buffer[5] = length & 0xff;
length += 6;
return new cFrame(buffer, length);
}
return NULL;
}
// --- cDVDplayBuffer -------------------------------------------------------- // --- cDVDplayBuffer --------------------------------------------------------
class cDVDplayBuffer : public cPlayBuffer { class cDVDplayBuffer : public cPlayBuffer {
private: private:
cAC3toPCM AC3toPCM;
uchar audioTrack; uchar audioTrack;
cDVD *dvd;//XXX necessary??? cDVD *dvd;//XXX necessary???
@ -1308,7 +1493,6 @@ private:
int doplay; int doplay;
int cyclestate; int cyclestate;
int prevcycle; int prevcycle;
int brakeCounter;
int skipCnt; int skipCnt;
tt_srpt_t *tt_srpt; tt_srpt_t *tt_srpt;
@ -1335,11 +1519,6 @@ private:
int logAudioTrack; int logAudioTrack;
int maxAudioTrack; int maxAudioTrack;
enum { AC3_STOP, AC3_START, AC3_PLAY } ac3stat;
uchar *ac3data;
int ac3inp;
int ac3outp;
int lpcm_count;
int is_nav_pack(unsigned char *buffer); int is_nav_pack(unsigned char *buffer);
void Close(void); void Close(void);
virtual void Empty(bool Block = false); virtual void Empty(bool Block = false);
@ -1350,10 +1529,7 @@ private:
int GetStuffingLen(const uchar *Data); int GetStuffingLen(const uchar *Data);
int GetPacketLength(const uchar *Data); int GetPacketLength(const uchar *Data);
int GetPESHeaderLength(const uchar *Data); int GetPESHeaderLength(const uchar *Data);
int SendPCM(int size); void handleAC3(unsigned char *sector, int length, uchar PTSflags, uchar *PTSdata);
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; }
@ -1369,17 +1545,6 @@ public:
virtual void ToggleAudioTrack(void); virtual void ToggleAudioTrack(void);
}; };
#define cOPENDVD 0
#define cOPENTITLE 1
#define cOPENCHAPTER 2
#define cOUTCELL 3
#define cREADFRAME 4
#define cOUTPACK 5
#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)
{ {
@ -1389,15 +1554,10 @@ cDVDplayBuffer::cDVDplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, cDVD
angle = 0; angle = 0;
cyclestate = cOPENDVD; cyclestate = cOPENDVD;
prevcycle = 0; prevcycle = 0;
brakeCounter = 0;
skipCnt = 0; skipCnt = 0;
logAudioTrack = 0; logAudioTrack = 0;
canToggleAudioTrack = true;//XXX determine from cDVD! canToggleAudioTrack = true;//XXX determine from cDVD!
ac3dec_init();
data = new uchar[1024 * DVD_VIDEO_LB_LEN]; data = new uchar[1024 * DVD_VIDEO_LB_LEN];
ac3data = new uchar[AC3_BUFFER_SIZE];
ac3inp = ac3outp = 0;
ac3stat = AC3_START;
canDoTrickMode = true; canDoTrickMode = true;
dvbApi->SetModeReplay(); dvbApi->SetModeReplay();
Start(); Start();
@ -1408,7 +1568,6 @@ cDVDplayBuffer::~cDVDplayBuffer()
Stop(); Stop();
Close(); Close();
dvbApi->SetModeNormal(false); dvbApi->SetModeNormal(false);
delete ac3data;
delete data; delete data;
} }
@ -1449,8 +1608,7 @@ void cDVDplayBuffer::ToggleAudioTrack(void)
#ifdef DVDDEBUG #ifdef DVDDEBUG
dsyslog(LOG_INFO, "DVB: Audio Stream ID changed to: %x", audioTrack); dsyslog(LOG_INFO, "DVB: Audio Stream ID changed to: %x", audioTrack);
#endif #endif
ac3stat = AC3_START; AC3toPCM.Clear();
ac3outp = ac3inp;
} }
} }
@ -1869,141 +2027,21 @@ int cDVDplayBuffer::ScanVideoPacket(const uchar *Data, int Count, uchar *Picture
return -1; return -1;
} }
#define SYSTEM_HEADER 0xBB void cDVDplayBuffer::handleAC3(unsigned char *sector, int length, uchar PTSflags, uchar *PTSdata)
#define PROG_STREAM_MAP 0xBC
#ifndef PRIVATE_STREAM1
#define PRIVATE_STREAM1 0xBD
#endif
#define PADDING_STREAM 0xBE
#ifndef PRIVATE_STREAM2
#define PRIVATE_STREAM2 0xBF
#endif
#define AUDIO_STREAM_S 0xC0
#define AUDIO_STREAM_E 0xDF
#define VIDEO_STREAM_S 0xE0
#define VIDEO_STREAM_E 0xEF
#define ECM_STREAM 0xF0
#define EMM_STREAM 0xF1
#define DSM_CC_STREAM 0xF2
#define ISO13522_STREAM 0xF3
#define PROG_STREAM_DIR 0xFF
// data=PCM samples, 16 bit, LSB first, 48kHz, stereo
int cDVDplayBuffer::SendPCM(int size)
{ {
#define PCM_FRAME_SIZE 1536
#define MAXSIZE 2032 AC3toPCM.Put(sector, length);
cFrame *frame;
uchar buffer[MAXSIZE + 16]; if ((frame = AC3toPCM.Get(PCM_FRAME_SIZE, PTSflags, PTSdata)) != NULL)
int length = 0; putFrame(frame);
int p_size; while ((frame = AC3toPCM.Get(PCM_FRAME_SIZE)) != NULL)
putFrame(frame);
if (ac3inp == ac3outp)
return 1;
while (size > 0) {
if (size >= MAXSIZE)
p_size = MAXSIZE;
else
p_size = size;
length = 10;
while (p_size) {
if (ac3outp != ac3inp) { // data in the buffer
buffer[(length + 6) ^ 1] = ac3data[ac3outp]; // swab because ac3dec delivers wrong byteorder
// XXX there is no 'swab' here??? (kls)
p_size--;
length++;
ac3outp = (ac3outp + 1) % AC3_BUFFER_SIZE;
}
else
break;
}
buffer[0] = 0x00;
buffer[1] = 0x00;
buffer[2] = 0x01;
buffer[3] = PRIVATE_STREAM1;
buffer[4] = (length >> 8) & 0xff;
buffer[5] = length & 0xff;
buffer[6] = 0x80;
buffer[7] = 0x00;
buffer[8] = 0x00;
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;
buffer[14] = 0x00;
buffer[15] = 0x00;
length += 6;
putFrame(buffer, length);
size -= MAXSIZE;
}
return 0;
}
void cDVDplayBuffer::playDecodedAC3(void)
{
int ac3_datasize = (AC3_BUFFER_SIZE + ac3inp - ac3outp) % AC3_BUFFER_SIZE;
if (ac3_datasize) {
if (ac3_datasize > 1024 * 48)
SendPCM(3096);
else if (ac3_datasize > 1024 * 32)
SendPCM(1536);
else if (ac3_datasize > 1024 * 16 && !(lpcm_count % 2))
SendPCM(1536);
else if (ac3_datasize && !(lpcm_count % 4))
SendPCM(1536);
lpcm_count++;
}
else
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)
ac3dec_decode_data(sector, sector + length, 0, &ac3inp, &ac3outp, (char *)ac3data);
else if (ac3stat == AC3_START) {
ac3dec_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, bool trickMode) int cDVDplayBuffer::decode_packet(unsigned char *sector, bool trickMode)
{ {
//XXX kls 2001-11-03: do we really need all these different return values?
uchar pt = 1; uchar pt = 1;
#if 0
uchar *osect = sector;
#endif
//make sure we got a PS packet header //make sure we got a PS packet header
if (!PacketStart(&sector, DVD_VIDEO_LB_LEN) && GetPacketType(sector) != 0xBA) { if (!PacketStart(&sector, DVD_VIDEO_LB_LEN) && GetPacketType(sector) != 0xBA) {
@ -2017,6 +2055,8 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, bool trickMode)
int datalen = r; int datalen = r;
sector[6] &= 0x8f; sector[6] &= 0x8f;
uchar PTSflags = sector[7] >> 6;
uchar *PTSdata = sector + 9;
uchar *data = sector; uchar *data = sector;
switch (GetPacketType(sector)) { switch (GetPacketType(sector)) {
@ -2025,6 +2065,7 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, bool trickMode)
ScanVideoPacket(sector, r, &pt); ScanVideoPacket(sector, r, &pt);
if (trickMode && pt != 1) if (trickMode && pt != 1)
return pt; return pt;
putFrame(sector, r, ftVideo);
break; break;
} }
case AUDIO_STREAM_S ... AUDIO_STREAM_E: { case AUDIO_STREAM_S ... AUDIO_STREAM_E: {
@ -2033,6 +2074,7 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, bool trickMode)
return 1; return 1;
if (audioTrack != GetPacketType(sector)) if (audioTrack != GetPacketType(sector))
return 5; return 5;
putFrame(sector, r, ftAudio);
break; break;
} }
case PRIVATE_STREAM1: case PRIVATE_STREAM1:
@ -2060,14 +2102,15 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, bool trickMode)
if (audioTrack == *data) { if (audioTrack == *data) {
switch (audioTrack & 0xF8) { switch (audioTrack & 0xF8) {
case aAC3: case aAC3:
if (dolbyDev)
putFrame(sector, r, ftDolby);
data += 4; data += 4;
// correct a3 data lenght - FIXME: why 13 ??? datalen -= 13; // 3 (mandatory header) + 6 (PS header) + 4 (AC3 header) = 13
datalen -= 13; handleAC3(data, datalen, PTSflags, PTSdata);
handleAC3(data, datalen);
break; break;
case aLPCM: case aLPCM:
// write(audio, sector+14 , sector[19]+(sector[18]<<8)+6); // write(audio, sector+14 , sector[19]+(sector[18]<<8)+6);
putFrame(sector, GetPacketLength(sector)); putFrame(sector, GetPacketLength(sector), ftAudio);
break; break;
default: default:
break; break;
@ -2096,9 +2139,6 @@ int cDVDplayBuffer::decode_packet(unsigned char *sector, bool trickMode)
return pt; return pt;
} }
} }
putFrame(sector, r);
if ((audioTrack & 0xF8) == aAC3)
playDecodedAC3();
return pt; return pt;
} }
@ -2106,8 +2146,7 @@ void cDVDplayBuffer::Empty(bool Block)
{ {
if (!(blockInput || blockOutput)) { if (!(blockInput || blockOutput)) {
cPlayBuffer::Empty(true); cPlayBuffer::Empty(true);
ac3stat = AC3_START; AC3toPCM.Clear();
ac3outp = ac3inp;
} }
if (!Block) if (!Block)
cPlayBuffer::Empty(false); cPlayBuffer::Empty(false);
@ -2149,9 +2188,7 @@ void cDVDplayBuffer::SkipSeconds(int Seconds)
Empty(true); Empty(true);
chapid = newchapid; chapid = newchapid;
NextState(cOPENCHAPTER); NextState(cOPENCHAPTER);
if (ac3stat != AC3_STOP) AC3toPCM.Clear();
ac3stat = AC3_START;
ac3outp = ac3inp;
Empty(false); Empty(false);
Play(); Play();
} }

View File

@ -7,7 +7,7 @@
* Parts of this file were inspired by the 'ringbuffy.c' from the * Parts of this file were inspired by the 'ringbuffy.c' from the
* LinuxDVB driver (see linuxtv.org). * LinuxDVB driver (see linuxtv.org).
* *
* $Id: ringbuffer.c 1.4 2001/08/05 12:17:45 kls Exp $ * $Id: ringbuffer.c 1.5 2001/11/03 09:50:46 kls Exp $
*/ */
#include "ringbuffer.h" #include "ringbuffer.h"
@ -215,9 +215,10 @@ int cRingBufferLinear::Get(uchar *Data, int Count)
// --- cFrame ---------------------------------------------------------------- // --- cFrame ----------------------------------------------------------------
cFrame::cFrame(const uchar *Data, int Count, int Index) cFrame::cFrame(const uchar *Data, int Count, eFrameType Type, int Index)
{ {
count = Count; count = Count;
type = Type;
index = Index; index = Index;
data = new uchar[count]; data = new uchar[count];
if (data) if (data)

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: ringbuffer.h 1.4 2001/08/05 11:12:06 kls Exp $ * $Id: ringbuffer.h 1.5 2001/11/03 10:41:33 kls Exp $
*/ */
#ifndef __RINGBUFFER_H #ifndef __RINGBUFFER_H
@ -75,18 +75,22 @@ public:
virtual ~cRingBufferLinear(); virtual ~cRingBufferLinear();
}; };
enum eFrameType { ftUnknown, ftVideo, ftAudio, ftDolby };
class cFrame { class cFrame {
friend class cRingBufferFrame; friend class cRingBufferFrame;
private: private:
cFrame *next; cFrame *next;
uchar *data; uchar *data;
int count; int count;
eFrameType type;
int index; int index;
public: public:
cFrame(const uchar *Data, int Count, int Index = -1); cFrame(const uchar *Data, int Count, eFrameType = ftUnknown, int Index = -1);
~cFrame(); ~cFrame();
const uchar *Data(void) const { return data; } const uchar *Data(void) const { return data; }
int Count(void) const { return count; } int Count(void) const { return count; }
eFrameType Type(void) const { return type; }
int Index(void) const { return index; } int Index(void) const { return index; }
}; };