diff options
-rw-r--r-- | HISTORY | 3 | ||||
-rw-r--r-- | PLUGINS.html | 48 | ||||
-rw-r--r-- | device.c | 36 | ||||
-rw-r--r-- | device.h | 40 | ||||
-rw-r--r-- | dvbdevice.c | 36 | ||||
-rw-r--r-- | dvbdevice.h | 14 | ||||
-rw-r--r-- | dvbplayer.c | 38 | ||||
-rw-r--r-- | menu.c | 16 | ||||
-rw-r--r-- | player.h | 23 | ||||
-rw-r--r-- | recorder.c | 4 | ||||
-rw-r--r-- | remux.c | 16 | ||||
-rw-r--r-- | remux.h | 5 | ||||
-rw-r--r-- | transfer.c | 74 | ||||
-rw-r--r-- | transfer.h | 9 |
14 files changed, 297 insertions, 65 deletions
@@ -1580,7 +1580,7 @@ Video Disk Recorder Revision History - Fixed a bug when pressing the "Blue" button in the main menu without having displayed it (thanks to Oliver Endriss for reporting this one). -2002-10-11: Version 1.1.13 +2002-10-12: Version 1.1.13 - Added cDevice::DeviceNumber() to get the number of a device, not counting any gaps that might be in the index count. @@ -1596,3 +1596,4 @@ Video Disk Recorder Revision History Scheffler). - Fixed switching the video format in the Setup/DVB menu (thanks to Uwe Scheffler for reporting this one). +- Reactivated full handling of second audio PID (even in 'Transfer Mode'). diff --git a/PLUGINS.html b/PLUGINS.html index 106bcc74..991092ee 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -21,18 +21,18 @@ VDR program and present itself to the user. The <i>inside</i> interface provides the plugin code access to VDR's internal data structures and allows it to hook itself into specific areas to perform special actions. <p> -<!--X1.1.8--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> -Important modifications introduced in version 1.1.8 are marked like this. -<!--X1.1.8--></td></tr></table> -<!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> +<!--X1.1.9--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> Important modifications introduced in version 1.1.9 are marked like this. <!--X1.1.9--></td></tr></table> -<!--X1.1.11--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> +<!--X1.1.11--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> Important modifications introduced in version 1.1.11 are marked like this. <!--X1.1.11--></td></tr></table> -<!--X1.1.12--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<!--X1.1.12--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> Important modifications introduced in version 1.1.12 are marked like this. <!--X1.1.12--></td></tr></table> +<!--X1.1.13--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +Important modifications introduced in version 1.1.13 are marked like this. +<!--X1.1.13--></td></tr></table> <a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center> @@ -964,6 +964,18 @@ bool DevicePoll(cPoller &Poller, int TimeoutMs = 0); </pre></td></tr></table><p> to determine whether the device is ready for further data. +<!--X1.1.13--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<p> +If the player can provide more than a single audio track, it can implement the +following functions to make them available: + +<p><table><tr><td bgcolor=#F0F0F0><pre><br> +virtual int NumAudioTracks(void) const; +virtual const char **GetAudioTracks(int *CurrentTrack = NULL); +virtual void SetAudioTrack(int Index); +</pre></td></tr></table><p> + +<!--X1.1.13--></td></tr></table> <p> TODO: PlayAudio()??? <p> @@ -1182,9 +1194,9 @@ the <tt>cDvbDevice</tt>, which is used to access the DVB PCI cards. If the new device can receive, it most likely needs to provide a way of selecting which channel it shall tune to: -<!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> +<!--X1.1.9--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> <p><table><tr><td bgcolor=#F0F0F0><pre><br> -<!--X1.1.12--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<!--X1.1.12--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> virtual bool ProvidesSource(int Source) const; <!--X1.1.12--></td></tr></table> virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL); @@ -1195,6 +1207,20 @@ These functions will be called with the desired source or channel and shall retu this device can provide the requested source or channel and whether tuning to it was successful, repectively. <!--X1.1.9--></td></tr></table> +<!--X1.1.13--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> +<p> +<b>Audio selection</b> +<p> +If the device can provide more than a single audio track, it can implement the +following functions to make them available: + +<p><table><tr><td bgcolor=#F0F0F0><pre><br> +virtual int NumAudioTracksDevice(void) const; +virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const; +virtual void SetAudioTrackDevice(int Index); +</pre></td></tr></table><p> + +<!--X1.1.13--></td></tr></table> <p> <b>Recording</b> <p> @@ -1204,7 +1230,7 @@ A device that can be used for recording must implement the functions virtual bool SetPid(cPidHandle *Handle, int Type, bool On); virtual bool OpenDvr(void); virtual void CloseDvr(void); -<!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> +<!--X1.1.9--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> virtual bool GetTSPacket(uchar *&Data); <!--X1.1.9--></td></tr></table> </pre></td></tr></table><p> @@ -1250,7 +1276,6 @@ virtual void SetVideoFormat(bool VideoFormat16_9); virtual void SetVolumeDevice(int Volume); </pre></td></tr></table><p> -<!--X1.1.8--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> <p> <b>On Screen Display</b> <p> @@ -1266,7 +1291,6 @@ which must return a newly created object of a derived cOsdBase class that implements the functions necessary to display OSD information on your device. The caller of this function will delete the object as soon as it is no longer needed. -<!--X1.1.8--></td></tr></table> <p> <b>Initializing new devices</b> @@ -1291,7 +1315,7 @@ shut down (delete) all devices when the program terminates. It is therefore important that the devices are created on the heap, using the <tt>new</tt> operator! -<!--X1.1.11--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> +<!--X1.1.11--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> <hr><h2>Remote Control</h2> <center><i><b>The joy of zapping!</b></i></center><p> @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 1.26 2002/10/07 16:21:46 kls Exp $ + * $Id: device.c 1.27 2002/10/12 13:24:37 kls Exp $ */ #include "device.h" @@ -365,7 +365,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) if (CaDevice) { cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel if (CaDevice->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()! - cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apid1(), 0, 0, 0));//XXX+ + cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apid1(), Channel->Apid2(), Channel->Dpid1(), Channel->Dpid2()));//XXX+ else Result = scrNoTransfer; } @@ -398,6 +398,20 @@ void cDevice::SetVolumeDevice(int Volume) { } +int cDevice::NumAudioTracksDevice(void) const +{ + return 0; +} + +const char **cDevice::GetAudioTracksDevice(int *CurrentTrack) const +{ + return NULL; +} + +void cDevice::SetAudioTrackDevice(int Index) +{ +} + bool cDevice::ToggleMute(void) { int OldVolume = volume; @@ -416,6 +430,24 @@ void cDevice::SetVolume(int Volume, bool Absolute) mute = false; } +int cDevice::NumAudioTracks(void) const +{ + return player ? player->NumAudioTracks() : NumAudioTracksDevice(); +} + +const char **cDevice::GetAudioTracks(int *CurrentTrack) const +{ + return player ? player->GetAudioTracks(CurrentTrack) : GetAudioTracksDevice(CurrentTrack); +} + +void cDevice::SetAudioTrack(int Index) +{ + if (player) + player->SetAudioTrack(Index); + else + SetAudioTrackDevice(Index); +} + bool cDevice::SetPlayMode(ePlayMode PlayMode) { return false; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 1.22 2002/10/06 15:59:08 kls Exp $ + * $Id: device.h 1.23 2002/10/12 11:15:13 kls Exp $ */ #ifndef __DEVICE_H @@ -219,7 +219,7 @@ public: // Sets the output video format to either 16:9 or 4:3 (only useful // if this device has an MPEG decoder). -// Volume facilities +// Audio facilities private: bool mute; @@ -227,6 +227,27 @@ private: protected: virtual void SetVolumeDevice(int Volume); // Sets the audio volume on this device (Volume = 0...255). + virtual int NumAudioTracksDevice(void) const; + // Returns the number of audio tracks that are currently available on this + // device. The default return value is 0, meaning that this device + // doesn't have multiple audio track capabilities. The return value may + // change with every call and need not necessarily be the number of list + // entries returned by GetAudioTracksDevice(). This function is mainly called to + // decide whether there should be an "Audio" button in a menu. + virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const; + // Returns a list of currently available audio tracks. The last entry in the + // list must be NULL. The number of entries does not necessarily have to be + // the same as returned by a previous call to NumAudioTracksDevice(). + // If CurrentTrack is given, it will be set to the index of the current track + // in the returned list. Note that the list must not be changed after it has + // been returned by a call to GetAudioTracksDevice()! The only time the list may + // change is *inside* the GetAudioTracksDevice() function. + // By default the return value is NULL and CurrentTrack, if given, will not + // have any meaning. + virtual void SetAudioTrackDevice(int Index); + // Sets the current audio track to the given value, which should be within the + // range of the list returned by a previous call to GetAudioTracksDevice() + // (otherwise nothing will happen). public: bool IsMute(void) const { return mute; } bool ToggleMute(void); @@ -235,6 +256,21 @@ public: // Sets the volume to the given value, either absolutely or relative to // the current volume. static int CurrentVolume(void) { return primaryDevice ? primaryDevice->volume : 0; }//XXX??? + int NumAudioTracks(void) const; + // Returns the number of audio tracks that are currently available on this + // device or a player attached to it. + const char **GetAudioTracks(int *CurrentTrack = NULL) const; + // Returns a list of currently available audio tracks. The last entry in the + // list is NULL. The number of entries does not necessarily have to be + // the same as returned by a previous call to NumAudioTracks(). + // If CurrentTrack is given, it will be set to the index of the current track + // in the returned list. + // By default the return value is NULL and CurrentTrack, if given, will not + // have any meaning. + void SetAudioTrack(int Index); + // Sets the current audio track to the given value, which should be within the + // range of the list returned by a previous call to GetAudioTracks() (otherwise + // nothing will happen). // Player facilities diff --git a/dvbdevice.c b/dvbdevice.c index 418e3c89..a4a4308d 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 1.23 2002/10/11 12:49:12 kls Exp $ + * $Id: dvbdevice.c 1.24 2002/10/12 11:15:45 kls Exp $ */ #include "dvbdevice.h" @@ -130,6 +130,8 @@ cDvbDevice::cDvbDevice(int n) else esyslog("ERROR: can't open DVB device %d", n); + aPid1 = aPid2 = 0; + source = -1; frequency = -1; diseqcCommands = NULL; @@ -722,6 +724,8 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) // PID settings: if (TurnOnLivePIDs) { + aPid1 = Channel->Apid1(); + aPid2 = Channel->Apid2(); if (!(AddPid(Channel->Apid1(), ptAudio) && AddPid(Channel->Vpid(), ptVideo))) {//XXX+ dolby dpid1!!! (if audio plugins are attached) esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1); return false; @@ -756,6 +760,36 @@ void cDvbDevice::SetVolumeDevice(int Volume) } } +int cDvbDevice::NumAudioTracksDevice(void) const +{ + int n = 0; + if (aPid1) + n++; + if (aPid2 && aPid1 != aPid2) + n++; + return n; +} + +const char **cDvbDevice::GetAudioTracksDevice(int *CurrentTrack) const +{ + if (NumAudioTracks()) { + if (CurrentTrack) + *CurrentTrack = (pidHandles[ptAudio].pid == aPid1) ? 0 : 1; + static const char *audioTracks1[] = { "Audio 1", NULL }; + static const char *audioTracks2[] = { "Audio 1", "Audio 2", NULL }; + return NumAudioTracks() > 1 ? audioTracks2 : audioTracks1; + } + return NULL; +} + +void cDvbDevice::SetAudioTrackDevice(int Index) +{ + if (0 <= Index && Index < NumAudioTracks()) { + DelPid(pidHandles[ptAudio].pid); + AddPid(Index ? aPid2 : aPid1, ptAudio); + } +} + bool cDvbDevice::SetPlayMode(ePlayMode PlayMode) { if (PlayMode != pmExtern_THIS_SHOULD_BE_AVOIDED && fd_video < 0 && fd_audio < 0) { diff --git a/dvbdevice.h b/dvbdevice.h index 98456643..b5484dc7 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.h 1.13 2002/10/11 12:24:19 kls Exp $ + * $Id: dvbdevice.h 1.14 2002/10/12 11:15:39 kls Exp $ */ #ifndef __DVBDEVICE_H @@ -13,11 +13,6 @@ #ifdef NEWSTRUCT #include <linux/dvb/frontend.h> #else -#include <stdlib.h> // FIXME: this is apparently necessary for the ost/... header files - // FIXME: shouldn't every header file include ALL the other header - // FIXME: files it depends on? The sequence in which header files - // FIXME: are included here should not matter - and it should NOT - // FIXME: be necessary to include <stdlib.h> here! #include <ost/frontend.h> #endif #include "device.h" @@ -87,10 +82,15 @@ public: public: virtual void SetVideoFormat(bool VideoFormat16_9); -// Volume facilities +// Audio facilities +private: + int aPid1, aPid2; protected: virtual void SetVolumeDevice(int Volume); + virtual int NumAudioTracksDevice(void) const; + virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const; + virtual void SetAudioTrackDevice(int Index); // EIT facilities diff --git a/dvbplayer.c b/dvbplayer.c index 7edadfbc..927fde4e 100644 --- a/dvbplayer.c +++ b/dvbplayer.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbplayer.c 1.13 2002/09/15 13:33:31 kls Exp $ + * $Id: dvbplayer.c 1.14 2002/10/12 12:29:31 kls Exp $ */ #include "dvbplayer.h" @@ -96,6 +96,8 @@ private: ePlayDirs playDir; int trickSpeed; int readIndex, writeIndex; + bool canToggleAudioTrack; + uchar audioTrack; cFrame *readFrame; const cFrame *playFrame; void TrickSpeed(int Increment); @@ -120,6 +122,9 @@ public: void Goto(int Position, bool Still = false); virtual bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false); virtual bool GetReplayMode(bool &Play, bool &Forward, int &Speed); + virtual int NumAudioTracks(void) const; + virtual const char **GetAudioTracks(int *CurrentTrack = NULL) const; + virtual void SetAudioTrack(int Index); }; #define MAX_VIDEO_SLOWMOTION 63 // max. arg to pass to VIDEO_SLOWMOTION // TODO is this value correct? @@ -139,6 +144,8 @@ cDvbPlayer::cDvbPlayer(const char *FileName) playMode = pmPlay; playDir = pdForward; trickSpeed = NORMAL_SPEED; + canToggleAudioTrack = false; + audioTrack = 0xC0; readIndex = writeIndex = -1; readFrame = NULL; playFrame = NULL; @@ -216,7 +223,7 @@ void cDvbPlayer::StripAudioPackets(uchar *b, int Length, uchar Except) // continue with deleting the data - otherwise it disturbs DVB replay case 0xC0 ... 0xC1: // audio if (c == 0xC1) - ;//XXX+ canToggleAudioTrack = true; + canToggleAudioTrack = true; if (!Except || c != Except) { int n = l; for (int j = i; j < Length && n--; j++) @@ -353,7 +360,7 @@ void cDvbPlayer::Action(void) continue; } r = ReadFrame(replayFile, b, Length, sizeof(b)); - StripAudioPackets(b, r, 0xC0); //XXX+ audioTrack + StripAudioPackets(b, r, audioTrack); } else // allows replay even if the index file is missing r = read(replayFile, b, sizeof(b)); @@ -623,6 +630,31 @@ bool cDvbPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed) return true; } +int cDvbPlayer::NumAudioTracks(void) const +{ + return canToggleAudioTrack ? 2 : 1; +} + +const char **cDvbPlayer::GetAudioTracks(int *CurrentTrack = NULL) const +{ + if (NumAudioTracks()) { + if (CurrentTrack) + *CurrentTrack = (audioTrack == 0xC0) ? 0 : 1; + static const char *audioTracks1[] = { "Audio 1", NULL }; + static const char *audioTracks2[] = { "Audio 1", "Audio 2", NULL }; + return NumAudioTracks() > 1 ? audioTracks2 : audioTracks1; + } + return NULL; +} + +void cDvbPlayer::SetAudioTrack(int Index) +{ + if ((audioTrack == 0xC0) != (Index == 0)) { + audioTrack = (Index == 1) ? 0xC1 : 0xC0; + Empty(); + } +} + // --- cDvbPlayerControl ----------------------------------------------------- cDvbPlayerControl::cDvbPlayerControl(const char *FileName) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.213 2002/10/12 09:06:57 kls Exp $ + * $Id: menu.c 1.214 2002/10/12 13:34:56 kls Exp $ */ #include "menu.h" @@ -2212,7 +2212,7 @@ void cMenuMain::Set(void) // Color buttons: - SetHelp(tr("Record"), /*XXX+ cDevice::PrimaryDevice()->CanToggleAudioTrack() ? tr("Language") :XXX*/ NULL, NULL, replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL); + SetHelp(tr("Record"), cDevice::PrimaryDevice()->NumAudioTracks() > 1 ? tr("Language") : NULL, NULL, replaying ? tr("Button$Stop") : cReplayControl::LastReplayed() ? tr("Resume") : NULL); Display(); lastActivity = time(NULL); } @@ -2264,13 +2264,17 @@ eOSState cMenuMain::ProcessKey(eKeys Key) state = osRecord; break; case kGreen: if (!HasSubMenu()) { - /*XXX+ - if (cDevice::PrimaryDevice()->CanToggleAudioTrack()) { + int CurrentAudioTrack = -1; + const char **AudioTracks = cDevice::PrimaryDevice()->GetAudioTracks(&CurrentAudioTrack); + if (AudioTracks) { + const char **at = &AudioTracks[CurrentAudioTrack]; + if (!*++at) + at = AudioTracks; Interface->Clear(); - cDevice::PrimaryDevice()->ToggleAudioTrack(); + cDevice::PrimaryDevice()->SetAudioTrack(at - AudioTracks); + //XXX Interface->Info(*at); state = osEnd; } - XXX*/ } break; case kBlue: if (!HasSubMenu()) @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: player.h 1.8 2002/08/16 09:14:12 kls Exp $ + * $Id: player.h 1.9 2002/10/12 11:17:02 kls Exp $ */ #ifndef __PLAYER_H @@ -50,6 +50,27 @@ public: // we are going forward or backward and 'Speed' is -1 if this is normal // play/pause mode, 0 if it is single speed fast/slow forward/back mode // and >0 if this is multi speed mode. + virtual int NumAudioTracks(void) const { return 0; } + // Returns the number of audio tracks that are currently available on this + // player. The default return value is 0, meaning that this player + // doesn't have multiple audio track capabilities. The return value may + // change with every call and need not necessarily be the number of list + // entries returned by GetAudioTracks(). This function is mainly called to + // decide whether there should be an "Audio" button in a menu. + virtual const char **GetAudioTracks(int *CurrentTrack = NULL) const { return NULL; } + // Returns a list of currently available audio tracks. The last entry in the + // list must be NULL. The number of entries does not necessarily have to be + // the same as returned by a previous call to NumAudioTracks(). + // If CurrentTrack is given, it will be set to the index of the current track + // in the returned list. Note that the list must not be changed after it has + // been returned by a call to GetAudioTracks()! The only time the list may + // change is *inside* the GetAudioTracks() function. + // By default the return value is NULL and CurrentTrack, if given, will not + // have any meaning. + virtual void SetAudioTrack(int Index) {} + // Sets the current audio track to the given value, which should be within the + // range of the list returned by a previous call to GetAudioTracks() + // (otherwise nothing will happen). }; class cControl : public cOsdObject { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recorder.c 1.2 2002/09/07 13:40:23 kls Exp $ + * $Id: recorder.c 1.3 2002/10/12 13:34:29 kls Exp $ */ #include <stdarg.h> @@ -119,7 +119,7 @@ void cRecorder::Action(void) r += g; if (r > 0) { int Count = r, Result; - const uchar *p = remux->Process(b, Count, Result, &pictureType); + uchar *p = remux->Process(b, Count, Result, &pictureType); if (p) { //XXX+ active??? see old version (Busy) if (!active && pictureType == I_FRAME) // finish the recording before the next 'I' frame @@ -8,7 +8,7 @@ * the Linux DVB driver's 'tuxplayer' example and were rewritten to suit * VDR's needs. * - * $Id: remux.c 1.11 2002/08/11 11:48:34 kls Exp $ + * $Id: remux.c 1.12 2002/10/12 13:33:54 kls Exp $ */ /* The calling interface of the 'cRemux::Process()' function is defined @@ -482,17 +482,9 @@ int cRemux::ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &Pic return -1; } -void cRemux::SetAudioPid(int APid) -{ - aPid1 = APid; - vTS2PES->Clear(); - aTS2PES1->Clear(); - resultCount = resultDelivered = 0; -} - #define TS_SYNC_BYTE 0x47 -const uchar *cRemux::Process(const uchar *Data, int &Count, int &Result, uchar *PictureType) +uchar *cRemux::Process(const uchar *Data, int &Count, int &Result, uchar *PictureType) { uchar dummyPictureType; if (!PictureType) @@ -611,7 +603,7 @@ XXX*/ if (synced) { *PictureType = pt; Result = l; - const uchar *p = resultBuffer + resultDelivered; + uchar *p = resultBuffer + resultDelivered; resultDelivered += l; return p; } @@ -629,7 +621,7 @@ XXX*/ return NULL; // no useful data found, wait for more if (synced) { Result = l; - const uchar *p = resultBuffer + resultDelivered; + uchar *p = resultBuffer + resultDelivered; resultDelivered += l; return p; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.h 1.7 2002/08/09 16:18:02 kls Exp $ + * $Id: remux.h 1.8 2002/10/12 13:30:24 kls Exp $ */ #ifndef __REMUX_H @@ -47,8 +47,7 @@ private: public: 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); + uchar *Process(const uchar *Data, int &Count, int &Result, uchar *PictureType = NULL); }; #endif // __REMUX_H @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: transfer.c 1.3 2002/09/22 09:50:48 kls Exp $ + * $Id: transfer.c 1.4 2002/10/12 13:32:48 kls Exp $ */ #include "transfer.h" @@ -21,6 +21,8 @@ cTransfer::cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2) { ringBuffer = new cRingBufferLinear(VIDEOBUFSIZE, true); remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2); + canToggleAudioTrack = false; + audioTrack = 0xC0; gotBufferReserve = false; active = false; } @@ -86,9 +88,9 @@ void cTransfer::Action(void) if (r > 0) { int Count = r, Result; - const uchar *p = remux->Process(b, Count, Result); + uchar *p = remux->Process(b, Count, Result); if (p) { - //XXX+ StripAudio??? + StripAudioPackets(p, Result, audioTrack); while (Result > 0 && active) { int w = PlayVideo(p, Result); if (w > 0) { @@ -112,15 +114,65 @@ void cTransfer::Action(void) dsyslog("transfer thread ended (pid=%d)", getpid()); } -void cTransfer::SetAudioPid(int APid) +void cTransfer::StripAudioPackets(uchar *b, int Length, uchar Except) { - /*XXX+ - Clear(); - //XXX we may need to have access to the audio device, too, in order to clear it - CHECK(ioctl(toDevice, VIDEO_CLEAR_BUFFER)); - gotBufferReserve = false; - remux.SetAudioPid(APid); - XXX*/ + 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 0xBD: // dolby + if (Except) + ;//XXX+ PlayExternalDolby(&b[i], Length - i); + // 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 + break; + default: + //esyslog("ERROR: unexpected packet id %02X", c); + l = 0; + } + if (l) + i += l - 1; // the loop increments, too! + } + /*XXX + else + esyslog("ERROR: broken packet header"); + XXX*/ + } +} + +int cTransfer::NumAudioTracks(void) const +{ + return canToggleAudioTrack ? 2 : 1; +} + +const char **cTransfer::GetAudioTracks(int *CurrentTrack = NULL) const +{ + if (NumAudioTracks()) { + if (CurrentTrack) + *CurrentTrack = (audioTrack == 0xC0) ? 0 : 1; + static const char *audioTracks1[] = { "Audio 1", NULL }; + static const char *audioTracks2[] = { "Audio 1", "Audio 2", NULL }; + return NumAudioTracks() > 1 ? audioTracks2 : audioTracks1; + } + return NULL; +} + +void cTransfer::SetAudioTrack(int Index) +{ + if ((audioTrack == 0xC0) != (Index == 0)) { + audioTrack = (Index == 1) ? 0xC1 : 0xC0; + DeviceClear(); + } } // --- cTransferControl ------------------------------------------------------ @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: transfer.h 1.2 2002/06/23 12:26:24 kls Exp $ + * $Id: transfer.h 1.3 2002/10/12 12:59:05 kls Exp $ */ #ifndef __TRANSFER_H @@ -20,8 +20,11 @@ class cTransfer : public cReceiver, public cPlayer, public cThread { private: cRingBufferLinear *ringBuffer; cRemux *remux; + bool canToggleAudioTrack; + uchar audioTrack; bool gotBufferReserve; bool active; + void StripAudioPackets(uchar *b, int Length, uchar Except = 0x00); protected: virtual void Activate(bool On); virtual void Receive(uchar *Data, int Length); @@ -29,7 +32,9 @@ protected: public: cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2); virtual ~cTransfer(); - void SetAudioPid(int APid); + virtual int NumAudioTracks(void) const; + virtual const char **GetAudioTracks(int *CurrentTrack = NULL) const; + virtual void SetAudioTrack(int Index); }; class cTransferControl : public cControl { |