Reactivated full handling of second audio PID (even in 'Transfer Mode')

This commit is contained in:
Klaus Schmidinger 2002-10-12 14:29:46 +02:00
parent 371b9be00b
commit ec5795bda2
14 changed files with 297 additions and 65 deletions

View File

@ -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').

View File

@ -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>&nbsp;</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>&nbsp;</td><td width=100%>
<!--X1.1.9--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</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>&nbsp;</td><td width=100%>
<!--X1.1.11--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</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>&nbsp;</td><td width=100%>
<!--X1.1.12--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</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>&nbsp;</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 &amp;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>&nbsp;</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>&nbsp;</td><td width=100%>
<!--X1.1.9--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
<!--X1.1.12--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
<!--X1.1.12--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</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>&nbsp;</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>&nbsp;</td><td width=100%>
<!--X1.1.9--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
virtual bool GetTSPacket(uchar *&amp;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>&nbsp;</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>&nbsp;</td><td width=100%>
<!--X1.1.11--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<hr><h2>Remote Control</h2>
<center><i><b>The joy of zapping!</b></i></center><p>

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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)

16
menu.c
View File

@ -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())

View File

@ -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 {

View File

@ -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

16
remux.c
View File

@ -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;
}

View File

@ -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

View File

@ -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 ------------------------------------------------------

View File

@ -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 {