From d67fb2ce5563892d6b6735a82e1262cf35a713d9 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 24 Jun 2001 17:42:19 +0200 Subject: [PATCH] Added Dolby Digital recording/replay --- FORMATS | 5 ++- HISTORY | 5 ++- INSTALL | 9 ++++ config.c | 18 ++++++-- config.h | 5 ++- dvbapi.c | 129 ++++++++++++++++++++++++++++++++++++++----------------- dvbapi.h | 25 ++++++++--- i18n.c | 16 ++++++- menu.c | 4 +- remux.c | 25 +++++++---- remux.h | 8 ++-- runvdr | 4 +- vdr.c | 8 +++- 13 files changed, 188 insertions(+), 73 deletions(-) diff --git a/FORMATS b/FORMATS index 0f047352..03739ee5 100644 --- a/FORMATS +++ b/FORMATS @@ -26,6 +26,8 @@ Video Disk Recorder File Formats - Symbol rate - Video PID - Audio PID (either one number, or two, separated by a comma) + If this channel also carries Dolby Digital sound, the Dolby PIDs follow + the audio PIDs, separated by a semicolon, as in "...:101,102;103,104:..." - Teletext PID - Conditional Access (0 = Free To Air, 1 = can be decrypted by the first DVB card, 2 = can be decrypted by the second DVB card) @@ -135,5 +137,6 @@ Video Disk Recorder File Formats an individual file below a given limit, a recording is split into several files. The contents of these files is "Packetized Elementary Stream" (PES) and contains ES packets with ids 0xE0 for video, 0xC0 for audio 1 and 0xC1 - for audio 2 (if available). + for audio 2 (if available). Dolby Digital data is stored in packets with + ids 0xBD. diff --git a/HISTORY b/HISTORY index 6d1b62f9..9a305cd3 100644 --- a/HISTORY +++ b/HISTORY @@ -526,8 +526,11 @@ Video Disk Recorder Revision History - New setup parameter "VideoFormat" to define the aspect ratio of the tv set in use (4:3 or 16:9). -2001-06-22: Version 0.83 +2001-06-26: Version 0.83 - Avoiding "Device or resource busy" error message when setting PIDs. - Added Portugese language texts (Paulo Manuel Martins Lopes). +- Recording and replaying Dolby Digital (AC3) sound. +- No longer getting stuck when a channel doesn't sync while switching + with the 'Up' and 'Down' keys. diff --git a/INSTALL b/INSTALL index e7b4323e..7d7ec7ee 100644 --- a/INSTALL +++ b/INSTALL @@ -88,6 +88,15 @@ Command line options: Use "vdr --help" for a list of available command line options. +Replaying Dolby Digital audio: +------------------------------ + +To replay Dolby Digital audio you need a program that reads the DD data +from stdin and processes it in a way suitable for your audio hardware. +This program must be given to VDR with the '-a' option, as in + + vdr -a ac3play + The video data directory: ------------------------- diff --git a/config.c b/config.c index b8c2d9f8..644ca854 100644 --- a/config.c +++ b/config.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.47 2001/06/16 14:06:56 kls Exp $ + * $Id: config.c 1.48 2001/06/23 14:01:03 kls Exp $ */ #include "config.h" @@ -202,6 +202,8 @@ cChannel::cChannel(const cChannel *Channel) vpid = Channel ? Channel->vpid : 255; apid1 = Channel ? Channel->apid1 : 256; apid2 = Channel ? Channel->apid2 : 0; + dpid1 = Channel ? Channel->dpid1 : 257; + dpid2 = Channel ? Channel->dpid2 : 0; tpid = Channel ? Channel->tpid : 32; ca = Channel ? Channel->ca : 0; pnr = Channel ? Channel->pnr : 0; @@ -220,11 +222,15 @@ const char *cChannel::ToText(cChannel *Channel) if (Channel->groupSep) asprintf(&buffer, ":%s\n", s); else { - char apidbuf[20]; + char apidbuf[32]; char *q = apidbuf; q += snprintf(q, sizeof(apidbuf), "%d", Channel->apid1); if (Channel->apid2) q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->apid2); + if (Channel->dpid1 || Channel->dpid2) + q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ";%d", Channel->dpid1); + if (Channel->dpid2) + q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->dpid2); *q = 0; asprintf(&buffer, "%s:%d:%c:%d:%d:%d:%s:%d:%d:%d\n", s, Channel->frequency, Channel->polarization, Channel->diseqc, Channel->srate, Channel->vpid, apidbuf, Channel->tpid, Channel->ca, Channel->pnr); } @@ -253,7 +259,13 @@ bool cChannel::Parse(const char *s) char *apidbuf = NULL; int fields = sscanf(s, "%a[^:]:%d:%c:%d:%d:%d:%a[^:]:%d:%d:%d", &buffer, &frequency, &polarization, &diseqc, &srate, &vpid, &apidbuf, &tpid, &ca, &pnr); apid1 = apid2 = 0; + dpid1 = dpid2 = 0; + char *p = strchr(apidbuf, ';'); + if (p) + *p++ = 0; sscanf(apidbuf, "%d,%d", &apid1, &apid2); + if (p) + sscanf(p, "%d,%d", &dpid1, &dpid2); delete apidbuf; if (fields >= 9) { if (fields == 9) { @@ -286,7 +298,7 @@ bool cChannel::Switch(cDvbApi *DvbApi, bool Log) isyslog(LOG_INFO, "switching to channel %d", number); } for (int i = 3; i--;) { - if (DvbApi->SetChannel(number, frequency, polarization, diseqc, srate, vpid, apid1, apid2, tpid, ca, pnr)) + if (DvbApi->SetChannel(number, frequency, polarization, diseqc, srate, vpid, apid1, apid2, dpid1, dpid2, tpid, ca, pnr)) return true; esyslog(LOG_ERR, "retrying"); } diff --git a/config.h b/config.h index 1d81106a..8b113334 100644 --- a/config.h +++ b/config.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.49 2001/06/16 14:05:58 kls Exp $ + * $Id: config.h 1.50 2001/06/23 13:48:22 kls Exp $ */ #ifndef __CONFIG_H @@ -19,7 +19,7 @@ #include "eit.h" #include "tools.h" -#define VDRVERSION "0.82" +#define VDRVERSION "0.83" #define MaxBuffer 10000 @@ -96,6 +96,7 @@ public: int srate; int vpid; int apid1, apid2; + int dpid1, dpid2; int tpid; int ca; int pnr; diff --git a/dvbapi.c b/dvbapi.c index 49c83209..097f3561 100644 --- a/dvbapi.c +++ b/dvbapi.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.c 1.79 2001/06/17 15:18:11 kls Exp $ + * $Id: dvbapi.c 1.80 2001/06/24 17:42:19 kls Exp $ */ #include "dvbapi.h" @@ -451,14 +451,14 @@ protected: virtual void Input(void); virtual void Output(void); public: - cRecordBuffer(cDvbApi *DvbApi, const char *FileName, dvb_pid_t VPid, dvb_pid_t APid1, dvb_pid_t APid2); + cRecordBuffer(cDvbApi *DvbApi, const char *FileName, int VPid, int APid1, int APid2, int DPid1, int DPid2); virtual ~cRecordBuffer(); }; -cRecordBuffer::cRecordBuffer(cDvbApi *DvbApi, const char *FileName, dvb_pid_t VPid, dvb_pid_t APid1, dvb_pid_t APid2) +cRecordBuffer::cRecordBuffer(cDvbApi *DvbApi, const char *FileName, int VPid, int APid1, int APid2, int DPid1, int DPid2) :cRingBuffer(VIDEOBUFSIZE, true) ,fileName(FileName, true) -,remux(VPid, APid1, APid2, true) +,remux(VPid, APid1, APid2, DPid1, DPid2, true) { dvbApi = DvbApi; index = NULL; @@ -620,6 +620,7 @@ private: cFileName fileName; int fileOffset; int videoDev, audioDev; + FILE *dolbyDev; int replayFile; bool eof; int blockInput, blockOutput; @@ -661,6 +662,12 @@ cReplayBuffer::cReplayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev, const fileOffset = 0; videoDev = VideoDev; audioDev = AudioDev; + dolbyDev = NULL; + if (cDvbApi::AudioCommand()) { + dolbyDev = popen(cDvbApi::AudioCommand(), "w"); + if (!dolbyDev) + esyslog(LOG_ERR, "ERROR: can't open pipe to audio command '%s'", cDvbApi::AudioCommand()); + } replayFile = fileName.Open(); eof = false; blockInput = blockOutput = false; @@ -688,6 +695,8 @@ cReplayBuffer::~cReplayBuffer() Stop(); Save(); Close(); + if (dolbyDev) + pclose(dolbyDev); dvbApi->SetModeNormal(false); delete index; } @@ -795,24 +804,45 @@ void cReplayBuffer::StripAudioPackets(uchar *b, int Length, uchar Except) for (int i = 0; i < Length - 6; i++) { if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) { uchar c = b[i + 3]; + int l = b[i + 4] * 256 + b[i + 5] + 6; switch (c) { - case 0xC0 ... 0xDF: // audio - { - int n = b[i + 4] * 256 + b[i + 5]; - if (c == 0xC1) - canToggleAudioTrack = true; - if (!Except || c != Except) { - for (int j = i; j < Length && n--; j++) - b[j] = 0x00; - } - i += n; - } + case 0xBD: // dolby + if (Except && dolbyDev) { + int written = b[i + 8] + 9; // skips the PES header + 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 + case 0xC0 ... 0xC1: // audio + if (c == 0xC1) + canToggleAudioTrack = true; + if (!Except || c != Except) { + int n = l; + for (int j = i; j < Length && n--; j++) + b[j] = 0x00; + } break; - case 0xE0 ... 0xEF: // video - i += b[i + 4] * 256 + b[i + 5]; + case 0xE0: // video break; + default: + //esyslog(LOG_ERR, "ERROR: unexpected packet id %02X", c); + l = 0; } + if (l) + i += l - 1; // the loop increments, too! } + /*XXX + else + esyslog(LOG_ERR, "ERROR: broken packet header"); + XXX*/ } } @@ -1055,14 +1085,14 @@ protected: virtual void Input(void); virtual void Output(void); public: - cTransferBuffer(cDvbApi *DvbApi, int ToDevice, dvb_pid_t VPid, dvb_pid_t APid); + cTransferBuffer(cDvbApi *DvbApi, int ToDevice, int VPid, int APid); virtual ~cTransferBuffer(); void SetAudioPid(int APid); }; -cTransferBuffer::cTransferBuffer(cDvbApi *DvbApi, int ToDevice, dvb_pid_t VPid, dvb_pid_t APid) +cTransferBuffer::cTransferBuffer(cDvbApi *DvbApi, int ToDevice, int VPid, int APid) :cRingBuffer(VIDEOBUFSIZE, true) -,remux(VPid, APid) +,remux(VPid, APid, 0, 0, 0) { dvbApi = DvbApi; fromDevice = dvbApi->SetModeRecord(); @@ -1336,10 +1366,11 @@ int cDvbApi::NumDvbApis = 0; int cDvbApi::useDvbApi = 0; cDvbApi *cDvbApi::dvbApi[MAXDVBAPI] = { NULL }; cDvbApi *cDvbApi::PrimaryDvbApi = NULL; +char *cDvbApi::audioCommand = NULL; cDvbApi::cDvbApi(int n) { - vPid = aPid1 = aPid2 = 0; + vPid = aPid1 = aPid2 = dPid1 = dPid2 = 0; siProcessor = NULL; recordBuffer = NULL; replayBuffer = NULL; @@ -1359,6 +1390,8 @@ cDvbApi::cDvbApi(int n) fd_demuxv = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true); fd_demuxa1 = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true); fd_demuxa2 = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true); + fd_demuxd1 = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true); + fd_demuxd2 = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true); fd_demuxt = OstOpen(DEV_OST_DEMUX, n, O_RDWR | O_NONBLOCK, true); // Devices not present on "budget" cards: @@ -1381,7 +1414,7 @@ cDvbApi::cDvbApi(int n) // We only check the devices that must be present - the others will be checked before accessing them: - if (((fd_qpskfe >= 0 && fd_sec >= 0) || fd_qamfe >= 0) && fd_demuxv >= 0 && fd_demuxa1 >= 0 && fd_demuxa2 >= 0 && fd_demuxt >= 0) { + if (((fd_qpskfe >= 0 && fd_sec >= 0) || fd_qamfe >= 0) && fd_demuxv >= 0 && fd_demuxa1 >= 0 && fd_demuxa2 >= 0 && fd_demuxd1 >= 0 && fd_demuxd2 >= 0 && fd_demuxt >= 0) { siProcessor = new cSIProcessor(OstName(DEV_OST_DEMUX, n)); if (!dvbApi[0]) // only the first one shall set the system time siProcessor->SetUseTSTime(Setup.SetSystemTime); @@ -2037,32 +2070,35 @@ void cDvbApi::SetVideoFormat(videoFormat_t Format) CHECK(ioctl(fd_video, VIDEO_SET_FORMAT, Format)); } -bool cDvbApi::SetPid(int fd, dmxPesType_t PesType, dvb_pid_t Pid, dmxOutput_t Output) +bool cDvbApi::SetPid(int fd, dmxPesType_t PesType, int Pid, dmxOutput_t Output) { - if (Pid == 0x1FFF) + if (Pid) { CHECK(ioctl(fd, DMX_STOP)); - dmxPesFilterParams pesFilterParams; - pesFilterParams.pid = Pid; - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = Output; - pesFilterParams.pesType = PesType; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { - if (Pid != 0 && Pid != 0x1FFF) - LOG_ERROR; - return false; + dmxPesFilterParams pesFilterParams; + pesFilterParams.pid = Pid; + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = Output; + pesFilterParams.pesType = PesType; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { + if (Pid != 0x1FFF) + LOG_ERROR; + return false; + } } return true; } bool cDvbApi::SetPids(bool ForRecording) { - return SetVpid(vPid, ForRecording ? DMX_OUT_TS_TAP : DMX_OUT_DECODER) && + return SetVpid(vPid, ForRecording ? DMX_OUT_TS_TAP : DMX_OUT_DECODER) && SetApid1(aPid1, ForRecording ? DMX_OUT_TS_TAP : DMX_OUT_DECODER) && - SetApid2(ForRecording ? aPid2 : 0, DMX_OUT_TS_TAP); + SetApid2(ForRecording ? aPid2 : 0, DMX_OUT_TS_TAP) && + SetDpid1(ForRecording ? dPid1 : 0, DMX_OUT_TS_TAP) && + SetDpid2(ForRecording ? dPid2 : 0, DMX_OUT_TS_TAP); } -bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid1, int Apid2, int Tpid, int Ca, int Pnr) +bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid1, int Apid2, int Dpid1, int Dpid2, int Tpid, int Ca, int Pnr) { // Make sure the siProcessor won't access the device while switching cThreadLock ThreadLock(siProcessor); @@ -2084,8 +2120,14 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, SetVpid( 0x1FFF, DMX_OUT_DECODER); SetApid1(0x1FFF, DMX_OUT_DECODER); SetApid2(0x1FFF, DMX_OUT_DECODER); + SetDpid1(0x1FFF, DMX_OUT_DECODER); + SetDpid2(0x1FFF, DMX_OUT_DECODER); SetTpid( 0x1FFF, DMX_OUT_DECODER); + // Must set this anyway to avoid getting stuck when switching through + // channels with 'Up' and 'Down' keys: + currentChannel = ChannelNumber; + bool ChannelSynced = false; if (fd_qpskfe >= 0 && fd_sec >= 0) { // DVB-S @@ -2188,6 +2230,8 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, vPid = Vpid; aPid1 = Apid1; aPid2 = Apid2; + dPid1 = Dpid1; + dPid2 = Dpid2; if (!SetPids(false)) { esyslog(LOG_ERR, "ERROR: failed to set PIDs for channel %d", ChannelNumber); return false; @@ -2197,7 +2241,6 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true)); if (this == PrimaryDvbApi && siProcessor) siProcessor->SetCurrentServiceID(Pnr); - currentChannel = ChannelNumber; // If this DVB card can't receive this channel, let's see if we can // use the card that actually can receive it and transfer data from there: @@ -2206,7 +2249,7 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, cDvbApi *CaDvbApi = GetDvbApi(Ca, 0); if (CaDvbApi) { if (!CaDvbApi->Recording()) { - if (CaDvbApi->SetChannel(ChannelNumber, FrequencyMHz, Polarization, Diseqc, Srate, Vpid, Apid1, Apid2, Tpid, Ca, Pnr)) { + if (CaDvbApi->SetChannel(ChannelNumber, FrequencyMHz, Polarization, Diseqc, Srate, Vpid, Apid1, Apid2, Dpid1, Dpid2, Tpid, Ca, Pnr)) { SetModeReplay(); transferringFromDvbApi = CaDvbApi->StartTransfer(fd_video); } @@ -2290,7 +2333,7 @@ bool cDvbApi::StartRecord(const char *FileName, int Ca, int Priority) // Create recording buffer: - recordBuffer = new cRecordBuffer(this, FileName, vPid, aPid1, aPid2); + recordBuffer = new cRecordBuffer(this, FileName, vPid, aPid1, aPid2, dPid1, dPid2); if (recordBuffer) { ca = Ca; @@ -2428,6 +2471,12 @@ bool cDvbApi::ToggleAudioTrack(void) return false; } +void cDvbApi::SetAudioCommand(const char *Command) +{ + delete audioCommand; + audioCommand = strdup(Command); +} + // --- cEITScanner ----------------------------------------------------------- cEITScanner::cEITScanner(void) diff --git a/dvbapi.h b/dvbapi.h index 48579f3f..7ed0196f 100644 --- a/dvbapi.h +++ b/dvbapi.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.h 1.39 2001/06/16 14:21:16 kls Exp $ + * $Id: dvbapi.h 1.40 2001/06/24 17:42:19 kls Exp $ */ #ifndef __DVBAPI_H @@ -66,13 +66,15 @@ class cDvbApi { friend class cTransferBuffer; private: int videoDev; - int fd_osd, fd_qpskfe, fd_qamfe, fd_sec, fd_dvr, fd_audio, fd_video, fd_demuxa1, fd_demuxa2, fd_demuxv, fd_demuxt; - int vPid, aPid1, aPid2; - bool SetPid(int fd, dmxPesType_t PesType, dvb_pid_t Pid, dmxOutput_t Output); - bool SetVpid(int Vpid, dmxOutput_t Output) { return SetPid(fd_demuxv, DMX_PES_VIDEO, Vpid, Output); } + int fd_osd, fd_qpskfe, fd_qamfe, fd_sec, fd_dvr, fd_audio, fd_video, fd_demuxa1, fd_demuxa2, fd_demuxd1, fd_demuxd2, fd_demuxv, fd_demuxt; + int vPid, aPid1, aPid2, dPid1, dPid2; + bool SetPid(int fd, dmxPesType_t PesType, int Pid, dmxOutput_t Output); + bool SetVpid(int Vpid, dmxOutput_t Output) { return SetPid(fd_demuxv, DMX_PES_VIDEO, Vpid, Output); } bool SetApid1(int Apid, dmxOutput_t Output) { return SetPid(fd_demuxa1, DMX_PES_AUDIO, Apid, Output); } bool SetApid2(int Apid, dmxOutput_t Output) { return SetPid(fd_demuxa2, DMX_PES_OTHER, Apid, Output); } - bool SetTpid(int Tpid, dmxOutput_t Output) { return SetPid(fd_demuxt, DMX_PES_TELETEXT, Tpid, Output); } + bool SetDpid1(int Dpid, dmxOutput_t Output) { return SetPid(fd_demuxd1, DMX_PES_OTHER, Dpid, Output); } + bool SetDpid2(int Dpid, dmxOutput_t Output) { return SetPid(fd_demuxd2, DMX_PES_OTHER, Dpid, Output); } + bool SetTpid(int Tpid, dmxOutput_t Output) { return SetPid(fd_demuxt, DMX_PES_TELETEXT, Tpid, Output); } bool SetPids(bool ForRecording); cDvbApi(int n); public: @@ -182,7 +184,7 @@ public: private: int currentChannel; public: - bool SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid1, int Apid2, int Tpid, int Ca, int Pnr); + bool SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid1, int Apid2, int Dpid1, int Dpid2, int Tpid, int Ca, int Pnr); static int CurrentChannel(void) { return PrimaryDvbApi ? PrimaryDvbApi->currentChannel : 0; } int Channel(void) { return currentChannel; } @@ -268,11 +270,20 @@ public: // Audio track facilities +public: bool CanToggleAudioTrack(void); // Returns true if we are currently replaying and this recording has two // audio tracks, or if the current channel has two audio PIDs. bool ToggleAudioTrack(void); // Toggles the audio track if possible. + + // Dolby Digital audio facilities + +private: + static char *audioCommand; +public: + static void SetAudioCommand(const char *Command); + static const char *AudioCommand(void) { return audioCommand; } }; class cEITScanner { diff --git a/i18n.c b/i18n.c index 4cb3650b..1bc01d14 100644 --- a/i18n.c +++ b/i18n.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.20 2001/06/22 15:16:39 kls Exp $ + * $Id: i18n.c 1.21 2001/06/23 13:47:15 kls Exp $ * * Slovenian translations provided by Miha Setina * Italian translations provided by Alberto Carraro @@ -354,6 +354,20 @@ const tPhrase Phrases[] = { "Apid2", "Apid2", }, + { "Dpid1", + "Dpid1", + "Dpid1", + "Dpid1", + "Dpid1", + "Dpid1", + }, + { "Dpid2", + "Dpid2", + "Dpid2", + "Dpid2", + "Dpid2", + "Dpid2", + }, { "Tpid", "Tpid", "Tpid", diff --git a/menu.c b/menu.c index 06d50c83..2e014126 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.74 2001/06/16 14:23:02 kls Exp $ + * $Id: menu.c 1.75 2001/06/23 13:38:54 kls Exp $ */ #include "menu.h" @@ -545,6 +545,8 @@ cMenuEditChannel::cMenuEditChannel(int Index) Add(new cMenuEditIntItem( tr("Vpid"), &data.vpid, 0, 0xFFFE)); Add(new cMenuEditIntItem( tr("Apid1"), &data.apid1, 0, 0xFFFE)); Add(new cMenuEditIntItem( tr("Apid2"), &data.apid2, 0, 0xFFFE)); + Add(new cMenuEditIntItem( tr("Dpid1"), &data.dpid1, 0, 0xFFFE)); + Add(new cMenuEditIntItem( tr("Dpid2"), &data.dpid2, 0, 0xFFFE)); Add(new cMenuEditIntItem( tr("Tpid"), &data.tpid, 0, 0xFFFE)); Add(new cMenuEditIntItem( tr("CA"), &data.ca, 0, cDvbApi::NumDvbApis)); Add(new cMenuEditIntItem( tr("Pnr"), &data.pnr, 0)); diff --git a/remux.c b/remux.c index 51bd2a4a..3c7ec6e6 100644 --- a/remux.c +++ b/remux.c @@ -8,7 +8,7 @@ * the Linux DVB driver's 'tuxplayer' example and were rewritten to suit * VDR's needs. * - * $Id: remux.c 1.4 2001/06/14 15:30:09 kls Exp $ + * $Id: remux.c 1.5 2001/06/24 16:37:23 kls Exp $ */ /* The calling interface of the 'cRemux::Process()' function is defined @@ -419,11 +419,13 @@ void cTS2PES::ts_to_pes(const uint8_t *Buf) // don't need count (=188) // --- cRemux ---------------------------------------------------------------- -cRemux::cRemux(dvb_pid_t VPid, dvb_pid_t APid1, dvb_pid_t APid2, bool ExitOnFailure) +cRemux::cRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool ExitOnFailure) { vPid = VPid; aPid1 = APid1; aPid2 = APid2; + dPid1 = DPid1; + dPid2 = DPid2; exitOnFailure = ExitOnFailure; synced = false; skipped = 0; @@ -431,6 +433,9 @@ cRemux::cRemux(dvb_pid_t VPid, dvb_pid_t APid1, dvb_pid_t APid2, bool ExitOnFail vTS2PES = new cTS2PES(resultBuffer, &resultCount, IPACKS); aTS2PES1 = new cTS2PES(resultBuffer, &resultCount, IPACKS, 0xC0); aTS2PES2 = aPid2 ? new cTS2PES(resultBuffer, &resultCount, IPACKS, 0xC1) : NULL; + dTS2PES1 = dPid1 ? new cTS2PES(resultBuffer, &resultCount, IPACKS) : NULL; + //XXX don't yet know how to tell apart primary and secondary DD data... + dTS2PES2 = /*XXX dPid2 ? new cTS2PES(resultBuffer, &resultCount, IPACKS) : XXX*/ NULL; } cRemux::~cRemux() @@ -438,6 +443,8 @@ cRemux::~cRemux() delete vTS2PES; delete aTS2PES1; delete aTS2PES2; + delete dTS2PES1; + delete dTS2PES2; } int cRemux::GetPid(const uchar *Data) @@ -510,14 +517,13 @@ XXX*/ for (int i = 0; i < Count; i += TS_SIZE) { if (Count - i < TS_SIZE) break; - dvb_pid_t pid = GetPid(Data + i + 1); + int pid = GetPid(Data + i + 1); if (Data[i + 3] & 0x10) { // got payload - if (pid == vPid) - vTS2PES->ts_to_pes(Data + i); - else if (pid == aPid1) - aTS2PES1->ts_to_pes(Data + i); - else if (pid == aPid2 && aTS2PES2) - aTS2PES2->ts_to_pes(Data + i); + if (pid == vPid) vTS2PES->ts_to_pes(Data + i); + else if (pid == aPid1) aTS2PES1->ts_to_pes(Data + i); + else if (pid == aPid2 && aTS2PES2) aTS2PES2->ts_to_pes(Data + i); + else if (pid == dPid1 && dTS2PES1) dTS2PES1->ts_to_pes(Data + i); + else if (pid == dPid2 && dTS2PES2) dTS2PES2->ts_to_pes(Data + i); } used += TS_SIZE; if (resultCount > (int)sizeof(resultBuffer) / 2) @@ -587,6 +593,7 @@ XXX*/ } } break; + case PRIVATE_STREAM1: case AUDIO_STREAM_S ... AUDIO_STREAM_E: { int l = GetPacketLength(resultBuffer, resultCount, i); diff --git a/remux.h b/remux.h index ae19a441..792469e5 100644 --- a/remux.h +++ b/remux.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.h 1.4 2001/06/14 15:27:07 kls Exp $ + * $Id: remux.h 1.5 2001/06/23 14:06:59 kls Exp $ */ #ifndef __REMUX_H @@ -32,8 +32,8 @@ private: bool exitOnFailure; bool synced; int skipped; - dvb_pid_t vPid, aPid1, aPid2; - cTS2PES *vTS2PES, *aTS2PES1, *aTS2PES2; + int vPid, aPid1, aPid2, dPid1, dPid2; + cTS2PES *vTS2PES, *aTS2PES1, *aTS2PES2, *dTS2PES1, *dTS2PES2; uchar resultBuffer[RESULTBUFFERSIZE]; int resultCount; int resultDelivered; @@ -41,7 +41,7 @@ private: int GetPacketLength(const uchar *Data, int Count, int Offset); int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType); public: - cRemux(dvb_pid_t VPid, dvb_pid_t APid1, dvb_pid_t APid2 = 0, bool ExitOnFailure = false); + cRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool ExitOnFailure = false); ~cRemux(); void SetAudioPid(int APid); const uchar *Process(const uchar *Data, int &Count, int &Result, uchar *PictureType = NULL); diff --git a/runvdr b/runvdr index e4847162..93ca06c7 100755 --- a/runvdr +++ b/runvdr @@ -18,7 +18,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: runvdr 1.6 2001/06/09 12:20:04 kls Exp $ +# $Id: runvdr 1.7 2001/06/24 17:42:19 kls Exp $ DVBDIR="../DVB/driver" VDRPRG="./vdr" @@ -39,6 +39,6 @@ while (true) do echo "restarting VDR" $KILLPROC $VDRPRG sleep 10 - (cd $DVBDIR; make reload) + (cd $DVBDIR; make rmmod; make insmod) date done diff --git a/vdr.c b/vdr.c index 88dc2a1d..12b1a538 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: vdr.c 1.57 2001/05/25 09:31:09 kls Exp $ + * $Id: vdr.c 1.58 2001/06/23 12:29:41 kls Exp $ */ #include @@ -77,6 +77,7 @@ int main(int argc, char *argv[]) char *Terminal = NULL; static struct option long_options[] = { + { "audio", required_argument, NULL, 'a' }, { "config", required_argument, NULL, 'c' }, { "daemon", no_argument, NULL, 'd' }, { "device", required_argument, NULL, 'D' }, @@ -91,8 +92,10 @@ int main(int argc, char *argv[]) int c; int option_index = 0; - while ((c = getopt_long(argc, argv, "c:dD:hl:p:v:w:t:", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "a:c:dD:hl:p:v:w:t:", long_options, &option_index)) != -1) { switch (c) { + case 'a': cDvbApi::SetAudioCommand(optarg); + break; case 'c': ConfigDirectory = optarg; break; case 'd': DaemonMode = true; break; @@ -107,6 +110,7 @@ int main(int argc, char *argv[]) return 2; break; case 'h': printf("Usage: vdr [OPTION]\n\n" // for easier orientation, this is column 80| + " -a CMD, --audio=CMD send Dolby Digital audio to stdin of command CMD\n" " -c DIR, --config=DIR read config files from DIR (default is to read them\n" " from the video directory)\n" " -h, --help display this help and exit\n"