mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Recording and Transfer Mode now handle more than 2 audio PIDs
This commit is contained in:
		
							
								
								
									
										7
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -3311,3 +3311,10 @@ Video Disk Recorder Revision History | ||||
| - Fixed playing files with PES packets longer than 2048 byte through the full | ||||
|   featured DVB card (thanks to Marco Kremer for reporting this one and providing | ||||
|   a test sample). | ||||
| - Recording and Transfer Mode now handle more than 2 audio PIDs. For this the | ||||
|   interfaces of the following functions have been changed: | ||||
|   cTransferControl::cTransferControl() | ||||
|   cTransfer::cTransfer() | ||||
|   cRecorder::cRecorder() | ||||
|   cReceiver::cReceiver() | ||||
|   cRemux::cRemux() | ||||
|   | ||||
							
								
								
									
										38
									
								
								PLUGINS.html
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								PLUGINS.html
									
									
									
									
									
								
							| @@ -14,18 +14,18 @@ Copyright © 2004 Klaus Schmidinger<br> | ||||
| <a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a> | ||||
| </center> | ||||
| <p> | ||||
| <!--X1.3.0--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.0 are marked like this. | ||||
| <!--X1.3.0--></td></tr></table> | ||||
| <!--X1.3.7--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <!--X1.3.7--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.7 are marked like this. | ||||
| <!--X1.3.7--></td></tr></table> | ||||
| <!--X1.3.8--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <!--X1.3.8--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.8 are marked like this. | ||||
| <!--X1.3.8--></td></tr></table> | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.18 are marked like this. | ||||
| <!--X1.3.18--></td></tr></table> | ||||
| <!--X1.3.19--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.19 are marked like this. | ||||
| <!--X1.3.19--></td></tr></table> | ||||
| <p> | ||||
| VDR provides an easy to use plugin interface that allows additional functionality | ||||
| to be added to the program by implementing a dynamically loadable library file. | ||||
| @@ -73,11 +73,9 @@ structures and allows it to hook itself into specific areas to perform special a | ||||
| <li><a href="#Status monitor">Status monitor</a> | ||||
| <li><a href="#Players">Players</a> | ||||
| <li><a href="#Receivers">Receivers</a> | ||||
| <!--X1.3.0--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <li><a href="#Filters">Filters</a> | ||||
| <!--X1.3.0--></td></tr></table> | ||||
| <li><a href="#The On Screen Display">The On Screen Display</a> | ||||
| <!--X1.3.7--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <!--X1.3.7--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <li><a href="#Skins">Skins</a> | ||||
| <li><a href="#Themes">Themes</a> | ||||
| <!--X1.3.7--></td></tr></table> | ||||
| @@ -1023,7 +1021,7 @@ public: | ||||
| Take a look at the files <tt>player.h</tt> and <tt>dvbplayer.c</tt> to see how VDR implements | ||||
| its own player for the VDR recordings. | ||||
| <p> | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| To play the actual data, the player needs to call its member function | ||||
|  | ||||
| <p><table><tr><td bgcolor=#F0F0F0><pre> | ||||
| @@ -1046,7 +1044,7 @@ bool DevicePoll(cPoller &Poller, int TimeoutMs = 0); | ||||
|  | ||||
| to determine whether the device is ready for further data. | ||||
| <p> | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| By default all audio track handling is done by the device a player is | ||||
| attached to. | ||||
| If the player can provide more than a single audio track, and has special | ||||
| @@ -1183,7 +1181,9 @@ public: | ||||
|   }; | ||||
|  | ||||
| cMyReceiver::cMyReceiver(int Pid) | ||||
| :cReceiver(0, -1, 1, Pid) | ||||
| <!--X1.3.19--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| :cReceiver(0, -1, Pid) | ||||
| <!--X1.3.19--></td></tr></table> | ||||
| { | ||||
| } | ||||
|  | ||||
| @@ -1223,7 +1223,6 @@ Mode</i>). | ||||
| If the <tt>cReceiver</tt> isn't needed any more, it may simply be <i>deleted</i> | ||||
| and will automatically detach itself from the <tt>cDevice</tt>. | ||||
|  | ||||
| <!--X1.3.0--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <a name="Filters"><hr><h2>Filters</h2> | ||||
|  | ||||
| <center><i><b>A Fistful of Datas</b></i></center><p> | ||||
| @@ -1267,9 +1266,8 @@ If the <tt>cFilter</tt> isn't needed any more, it may simply be <i>deleted</i> | ||||
| and will automatically detach itself from the <tt>cDevice</tt>. | ||||
| <p> | ||||
| See VDR/eit.c or VDR/pat.c to learn how to process filter data. | ||||
| <!--X1.3.0--></td></tr></table> | ||||
|  | ||||
| <!--X1.3.7--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <!--X1.3.7--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <a name="The On Screen Display"><hr><h2>The On Screen Display</h2> | ||||
|  | ||||
| <center><i><b>Window to the world</b></i></center><p> | ||||
| @@ -1362,7 +1360,7 @@ public: | ||||
|   virtual cSkinDisplayMenu *DisplayMenu(void); | ||||
|   virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly); | ||||
|   virtual cSkinDisplayVolume *DisplayVolume(void); | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
|   virtual cSkinDisplayMessage *DisplayTrack(int NumTracks, const char * const *Tracks); | ||||
| <!--X1.3.18--></td></tr></table> | ||||
|   virtual cSkinDisplayMessage *DisplayMessage(void); | ||||
| @@ -1384,7 +1382,7 @@ new cMySkin; | ||||
| in the <a href="#Getting started"><tt>Start()</tt></a> function of your plugin. | ||||
| Do not delete this object, it will be automatically deleted when the program ends. | ||||
| <p> | ||||
| <!--X1.3.8--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <!--X1.3.8--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| In order to be able to easily identify plugins that implement a skin it is recommended | ||||
| that the name of such a plugin should be | ||||
|  | ||||
| @@ -1495,7 +1493,7 @@ repectively. | ||||
| If the device can provide more than a single audio track, it can implement the | ||||
| following function to make them available: | ||||
|  | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.3.18--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <p><table><tr><td bgcolor=#F0F0F0><pre> | ||||
| virtual void SetAudioTrackDevice(eTrackType Type); | ||||
| virtual int GetAudioChannelDevice(void); | ||||
| @@ -1558,7 +1556,6 @@ virtual void SetVideoFormat(bool VideoFormat16_9); | ||||
| virtual void SetVolumeDevice(int Volume); | ||||
| </pre></td></tr></table><p> | ||||
|  | ||||
| <!--X1.3.0--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <p> | ||||
| <b>Section Filtering</b> | ||||
| <p> | ||||
| @@ -1583,12 +1580,11 @@ from its constructor. | ||||
| <p> | ||||
| See <a href="#Filters">Filters</a> on how to set up actual filters that can | ||||
| handle section data. | ||||
| <!--X1.3.0--></td></tr></table> | ||||
|  | ||||
| <p> | ||||
| <b>On Screen Display</b> | ||||
| <p> | ||||
| <!--X1.3.7--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <!--X1.3.7--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| If your device provides On Screen Display (OSD) capabilities (which every device | ||||
| that is supposed to be used as a primary device should do), it shall implement | ||||
| an "OSD provider" class, derived from <tt>cOsdProvider</tt>, which, when its <tt>CreateOsd()</tt> | ||||
|   | ||||
							
								
								
									
										13
									
								
								channels.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								channels.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: channels.c 1.33 2004/12/26 12:34:52 kls Exp $ | ||||
|  * $Id: channels.c 1.34 2005/01/16 13:49:30 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "channels.h" | ||||
| @@ -193,6 +193,7 @@ cChannel::cChannel(const cChannel &Channel) | ||||
|   ppid         = 0; | ||||
|   apids[0]     = 0; | ||||
|   dpids[0]     = 0; | ||||
|   spids[0]     = 0; | ||||
|   tpid         = 0; | ||||
|   caids[0]     = 0; | ||||
|   nid          = 0; | ||||
| @@ -421,8 +422,8 @@ void cChannel::SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][4], int *Dp | ||||
|   if (!modified) | ||||
|      modified = IntArraysDiffer(apids, Apids, alangs, ALangs) || IntArraysDiffer(dpids, Dpids, dlangs, DLangs); | ||||
|   if (modified) { | ||||
|      char OldApidsBuf[MAXAPIDS * 2 * 10 + 10]; // 2: Apids and Dpids, 10: 5 digits plus delimiting ',' or ';' plus optional '=cod', +10: paranoia | ||||
|      char NewApidsBuf[MAXAPIDS * 2 * 10 + 10]; | ||||
|      char OldApidsBuf[(MAXAPIDS + MAXDPIDS) * 10 + 10]; // 10: 5 digits plus delimiting ',' or ';' plus optional '=cod', +10: paranoia | ||||
|      char NewApidsBuf[(MAXAPIDS + MAXDPIDS) * 10 + 10]; | ||||
|      char *q = OldApidsBuf; | ||||
|      q += IntArrayToString(q, apids, 10, alangs); | ||||
|      if (dpids[0]) { | ||||
| @@ -443,6 +444,8 @@ void cChannel::SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][4], int *Dp | ||||
|      for (int i = 0; i <= MAXAPIDS; i++) { // <= to copy the terminating 0 | ||||
|          apids[i] = Apids[i]; | ||||
|          strn0cpy(alangs[i], ALangs[i], 4); | ||||
|          } | ||||
|      for (int i = 0; i <= MAXDPIDS; i++) { // <= to copy the terminating 0 | ||||
|          dpids[i] = Dpids[i]; | ||||
|          strn0cpy(dlangs[i], DLangs[i], 4); | ||||
|          } | ||||
| @@ -623,7 +626,7 @@ cString cChannel::ToText(const cChannel *Channel) | ||||
|      if (Channel->ppid && Channel->ppid != Channel->vpid) | ||||
|         q += snprintf(q, sizeof(vpidbuf) - (q - vpidbuf), "+%d", Channel->ppid); | ||||
|      *q = 0; | ||||
|      char apidbuf[MAXAPIDS * 2 * 10 + 10]; // 2: Apids and Dpids, 10: 5 digits plus delimiting ',' or ';' plus optional '=cod', +10: paranoia | ||||
|      char apidbuf[(MAXAPIDS + MAXDPIDS) * 10 + 10]; // 10: 5 digits plus delimiting ',' or ';' plus optional '=cod', +10: paranoia | ||||
|      q = apidbuf; | ||||
|      q += IntArrayToString(q, Channel->apids, 10, Channel->alangs); | ||||
|      if (Channel->dpids[0]) { | ||||
| @@ -726,7 +729,7 @@ bool cChannel::Parse(const char *s, bool AllowNonUniqueID) | ||||
|               int NumDpids = 0; | ||||
|               char *strtok_next; | ||||
|               while ((q = strtok_r(p, ",", &strtok_next)) != NULL) { | ||||
|                     if (NumDpids < MAXAPIDS) { | ||||
|                     if (NumDpids < MAXDPIDS) { | ||||
|                        char *l = strchr(q, '='); | ||||
|                        if (l) { | ||||
|                           *l++ = 0; | ||||
|   | ||||
							
								
								
									
										23
									
								
								channels.h
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								channels.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: channels.h 1.24 2004/12/26 12:15:52 kls Exp $ | ||||
|  * $Id: channels.h 1.25 2005/01/16 13:46:41 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __CHANNELS_H | ||||
| @@ -30,8 +30,10 @@ | ||||
| #define CHANNELSMOD_AUTO    1 | ||||
| #define CHANNELSMOD_USER    2 | ||||
|  | ||||
| #define MAXAPIDS 32 | ||||
| #define MAXCAIDS  8 | ||||
| #define MAXAPIDS 32 // audio | ||||
| #define MAXDPIDS  8 // dolby | ||||
| #define MAXSPIDS  8 // subtitles | ||||
| #define MAXCAIDS  8 // conditional access | ||||
|  | ||||
| struct tChannelParameterMap { | ||||
|   int userValue; | ||||
| @@ -100,8 +102,10 @@ private: | ||||
|   int ppid; | ||||
|   int apids[MAXAPIDS + 1]; // list is zero-terminated | ||||
|   char alangs[MAXAPIDS][4]; | ||||
|   int dpids[MAXAPIDS + 1]; // list is zero-terminated | ||||
|   char dlangs[MAXAPIDS][4]; | ||||
|   int dpids[MAXDPIDS + 1]; // list is zero-terminated | ||||
|   char dlangs[MAXDPIDS][4]; | ||||
|   int spids[MAXSPIDS + 1]; // list is zero-terminated | ||||
|   char slangs[MAXSPIDS][4]; | ||||
|   int tpid; | ||||
|   int caids[MAXCAIDS + 1]; // list is zero-terminated | ||||
|   int nid; | ||||
| @@ -144,10 +148,15 @@ public: | ||||
|   int Srate(void) const { return srate; } | ||||
|   int Vpid(void) const { return vpid; } | ||||
|   int Ppid(void) const { return ppid; } | ||||
|   const int *Apids(void) const { return apids; } | ||||
|   const int *Dpids(void) const { return dpids; } | ||||
|   const int *Spids(void) const { return spids; } | ||||
|   int Apid(int i) const { return (0 <= i && i < MAXAPIDS) ? apids[i] : 0; } | ||||
|   int Dpid(int i) const { return (0 <= i && i < MAXAPIDS) ? dpids[i] : 0; } | ||||
|   int Dpid(int i) const { return (0 <= i && i < MAXDPIDS) ? dpids[i] : 0; } | ||||
|   int Spid(int i) const { return (0 <= i && i < MAXSPIDS) ? spids[i] : 0; } | ||||
|   const char *Alang(int i) const { return (0 <= i && i < MAXAPIDS) ? alangs[i] : ""; } | ||||
|   const char *Dlang(int i) const { return (0 <= i && i < MAXAPIDS) ? dlangs[i] : ""; } | ||||
|   const char *Dlang(int i) const { return (0 <= i && i < MAXDPIDS) ? dlangs[i] : ""; } | ||||
|   const char *Slang(int i) const { return (0 <= i && i < MAXSPIDS) ? slangs[i] : ""; } | ||||
|   int Tpid(void) const { return tpid; } | ||||
|   int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; } | ||||
|   int Nid(void) const { return nid; } | ||||
|   | ||||
							
								
								
									
										17
									
								
								device.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								device.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: device.c 1.73 2005/01/09 12:36:48 kls Exp $ | ||||
|  * $Id: device.c 1.74 2005/01/16 14:05:37 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "device.h" | ||||
| @@ -512,7 +512,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) | ||||
|      if (CaDevice && CanReplay()) { | ||||
|         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->Apid(0), Channel->Apid(1), Channel->Dpid(0), Channel->Dpid(1))); | ||||
|            cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids())); | ||||
|         else | ||||
|            Result = scrNoTransfer; | ||||
|         } | ||||
| @@ -545,11 +545,12 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) | ||||
|         // Set the available audio tracks: | ||||
|         ClrAvailableTracks(); | ||||
|         currentAudioTrack = ttAudioFirst; | ||||
|         for (int i = 0; i < MAXAPIDS; i++) { | ||||
|         for (int i = 0; i < MAXAPIDS; i++) | ||||
|             SetAvailableTrack(ttAudio, i, Channel->Apid(i), Channel->Alang(i)); | ||||
|             if (Setup.UseDolbyDigital) | ||||
|         if (Setup.UseDolbyDigital) { | ||||
|            for (int i = 0; i < MAXDPIDS; i++) | ||||
|                SetAvailableTrack(ttDolby, i, Channel->Dpid(i), Channel->Dlang(i)); | ||||
|             } | ||||
|            } | ||||
|         // Select the preferred audio track: | ||||
|         eTrackType PreferredTrack = ttAudioFirst; | ||||
|         int LanguagePreference = -1; | ||||
| @@ -849,7 +850,7 @@ int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly) | ||||
|           } | ||||
|         if (w > 0) | ||||
|            Start += w; | ||||
|         else if (w <= 0) { | ||||
|         else { | ||||
|            if (Start != Data) | ||||
|               esyslog("ERROR: incomplete PES packet write!"); | ||||
|            return Start == Data ? w : Start - Data; | ||||
| @@ -1041,7 +1042,7 @@ bool cDevice::AttachReceiver(cReceiver *Receiver) | ||||
|   cMutexLock MutexLock(&mutexReceiver); | ||||
|   for (int i = 0; i < MAXRECEIVERS; i++) { | ||||
|       if (!receiver[i]) { | ||||
|          for (int n = 0; n < MAXRECEIVEPIDS; n++) { | ||||
|          for (int n = 0; n < Receiver->numPids; n++) { | ||||
|              if (!AddPid(Receiver->pids[n])) { | ||||
|                 for ( ; n-- > 0; ) | ||||
|                     DelPid(Receiver->pids[n]); | ||||
| @@ -1074,7 +1075,7 @@ void cDevice::Detach(cReceiver *Receiver) | ||||
|          receiver[i] = NULL; | ||||
|          Receiver->device = NULL; | ||||
|          Unlock(); | ||||
|          for (int n = 0; n < MAXRECEIVEPIDS; n++) | ||||
|          for (int n = 0; n < Receiver->numPids; n++) | ||||
|              DelPid(Receiver->pids[n]); | ||||
|          } | ||||
|       else if (receiver[i]) | ||||
|   | ||||
							
								
								
									
										10
									
								
								device.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								device.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: device.h 1.51 2005/01/08 10:15:00 kls Exp $ | ||||
|  * $Id: device.h 1.52 2005/01/16 14:26:16 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __DEVICE_H | ||||
| @@ -22,7 +22,7 @@ | ||||
| #include "tools.h" | ||||
|  | ||||
| #define MAXDEVICES         16 // the maximum number of devices in the system | ||||
| #define MAXPIDHANDLES      16 // the maximum number of different PIDs per device | ||||
| #define MAXPIDHANDLES      64 // the maximum number of different PIDs per device | ||||
| #define MAXRECEIVERS       16 // the maximum number of receivers per device | ||||
| #define MAXVOLUME         255 | ||||
| #define VOLUMEDELTA         5 // used to increase/decrease the volume | ||||
| @@ -59,14 +59,14 @@ enum eVideoSystem { vsPAL, | ||||
| enum eTrackType { ttNone, | ||||
|                   ttAudio, | ||||
|                   ttAudioFirst = ttAudio, | ||||
|                   ttAudioLast  = ttAudioFirst + 31/*XXX MAXAPIDS - 1*/, | ||||
|                   ttAudioLast  = ttAudioFirst + 31, // MAXAPIDS - 1 | ||||
|                   ttDolby, | ||||
|                   ttDolbyFirst = ttDolby, | ||||
|                   ttDolbyLast  = ttDolbyFirst + 31/*XXX MAXAPIDS - 1*/, | ||||
|                   ttDolbyLast  = ttDolbyFirst + 8, // MAXDPIDS - 1 | ||||
|                   /* future... | ||||
|                   ttSubtitle, | ||||
|                   ttSubtitleFirst = ttSubtitle, | ||||
|                   ttSubtitleLast  = ttSubtitleFirst + 31, | ||||
|                   ttSubtitleLast  = ttSubtitleFirst + 8, // MAXSPIDS - 1 | ||||
|                   */ | ||||
|                   ttMaxTrackTypes | ||||
|                 }; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: dvbdevice.c 1.115 2005/01/16 11:59:21 kls Exp $ | ||||
|  * $Id: dvbdevice.c 1.116 2005/01/16 12:05:13 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "dvbdevice.h" | ||||
| @@ -813,7 +813,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) | ||||
|      CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true)); | ||||
|      } | ||||
|   else if (StartTransferMode) | ||||
|      cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apid(0), Channel->Apid(1), Channel->Dpid(0), Channel->Dpid(1))); | ||||
|      cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids())); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|   | ||||
							
								
								
									
										4
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								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.336 2005/01/14 14:27:29 kls Exp $ | ||||
|  * $Id: menu.c 1.337 2005/01/16 12:05:13 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "menu.h" | ||||
| @@ -3019,7 +3019,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) | ||||
|   isyslog("record %s", fileName); | ||||
|   if (MakeDirs(fileName, true)) { | ||||
|      const cChannel *ch = timer->Channel(); | ||||
|      recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid(0), ch->Apid(1), ch->Dpid(0), ch->Dpid(1)); | ||||
|      recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids()); | ||||
|      if (device->AttachReceiver(recorder)) { | ||||
|         Recording.WriteSummary(); | ||||
|         cStatus::MsgRecording(device, Recording.Name()); | ||||
|   | ||||
							
								
								
									
										8
									
								
								pat.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								pat.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: pat.c 1.10 2004/10/16 10:01:12 kls Exp $ | ||||
|  * $Id: pat.c 1.11 2005/01/16 13:54:34 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "pat.h" | ||||
| @@ -325,9 +325,9 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length | ||||
|         int Vpid = 0; | ||||
|         int Ppid = pmt.getPCRPid(); | ||||
|         int Apids[MAXAPIDS] = { 0 }; | ||||
|         int Dpids[MAXAPIDS] = { 0 }; | ||||
|         int Dpids[MAXDPIDS] = { 0 }; | ||||
|         char ALangs[MAXAPIDS][4] = { "" }; | ||||
|         char DLangs[MAXAPIDS][4] = { "" }; | ||||
|         char DLangs[MAXDPIDS][4] = { "" }; | ||||
|         int Tpid = 0; | ||||
|         int NumApids = 0; | ||||
|         int NumDpids = 0; | ||||
| @@ -386,7 +386,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length | ||||
|                           delete d; | ||||
|                           } | ||||
|                       if (dpid) { | ||||
|                          if (NumDpids < MAXAPIDS) { | ||||
|                          if (NumDpids < MAXDPIDS) { | ||||
|                             Dpids[NumDpids] = dpid; | ||||
|                             strn0cpy(DLangs[NumDpids], lang, 4); | ||||
|                             NumDpids++; | ||||
|   | ||||
							
								
								
									
										37
									
								
								receiver.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								receiver.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: receiver.c 1.3 2002/07/28 15:14:49 kls Exp $ | ||||
|  * $Id: receiver.c 1.4 2005/01/16 14:03:01 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include <stdarg.h> | ||||
| @@ -12,25 +12,28 @@ | ||||
| #include "receiver.h" | ||||
| #include "tools.h" | ||||
|  | ||||
| cReceiver::cReceiver(int Ca, int Priority, int NumPids, ...) | ||||
| cReceiver::cReceiver(int Ca, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3) | ||||
| { | ||||
|   device = NULL; | ||||
|   ca = Ca; | ||||
|   priority = Priority; | ||||
|   for (int i = 0; i < MAXRECEIVEPIDS; i++) | ||||
|       pids[i] = 0; | ||||
|   if (NumPids) { | ||||
|      va_list ap; | ||||
|      va_start(ap, NumPids); | ||||
|      int n = 0; | ||||
|      while (n < MAXRECEIVEPIDS && NumPids--) { | ||||
|            if ((pids[n] = va_arg(ap, int)) != 0) | ||||
|               n++; | ||||
|            } | ||||
|      va_end(ap); | ||||
|   numPids = 0; | ||||
|   if (Pid) | ||||
|      pids[numPids++] = Pid; | ||||
|   if (Pids1) { | ||||
|      while (*Pids1 && numPids < MAXRECEIVEPIDS) | ||||
|            pids[numPids++] = *Pids1++; | ||||
|      } | ||||
|   else | ||||
|      esyslog("ERROR: cReceiver called without a PID!"); | ||||
|   if (Pids2) { | ||||
|      while (*Pids2 && numPids < MAXRECEIVEPIDS) | ||||
|            pids[numPids++] = *Pids2++; | ||||
|      } | ||||
|   if (Pids3) { | ||||
|      while (*Pids3 && numPids < MAXRECEIVEPIDS) | ||||
|            pids[numPids++] = *Pids3++; | ||||
|      } | ||||
|   if (numPids >= MAXRECEIVEPIDS) | ||||
|      dsyslog("too many PIDs in cReceiver"); | ||||
| } | ||||
|  | ||||
| cReceiver::~cReceiver() | ||||
| @@ -41,11 +44,9 @@ cReceiver::~cReceiver() | ||||
| bool cReceiver::WantsPid(int Pid) | ||||
| { | ||||
|   if (Pid) { | ||||
|      for (int i = 0; i < MAXRECEIVEPIDS; i++) { | ||||
|      for (int i = 0; i < numPids; i++) { | ||||
|          if (pids[i] == Pid) | ||||
|             return true; | ||||
|          if (!pids[i]) | ||||
|             break; | ||||
|          } | ||||
|      } | ||||
|   return false; | ||||
|   | ||||
							
								
								
									
										42
									
								
								receiver.h
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								receiver.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: receiver.h 1.2 2002/07/28 11:22:01 kls Exp $ | ||||
|  * $Id: receiver.h 1.3 2005/01/16 14:05:10 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __RECEIVER_H | ||||
| @@ -12,7 +12,7 @@ | ||||
|  | ||||
| #include "device.h" | ||||
|  | ||||
| #define MAXRECEIVEPIDS  16 // the maximum number of PIDs per receiver | ||||
| #define MAXRECEIVEPIDS  64 // the maximum number of PIDs per receiver | ||||
|  | ||||
| class cReceiver { | ||||
|   friend class cDevice; | ||||
| @@ -21,30 +21,32 @@ private: | ||||
|   int ca; | ||||
|   int priority; | ||||
|   int pids[MAXRECEIVEPIDS]; | ||||
|   int numPids; | ||||
|   bool WantsPid(int Pid); | ||||
| protected: | ||||
|   void Detach(void); | ||||
|   virtual void Activate(bool On) {} | ||||
|                // This function is called just before the cReceiver gets attached to | ||||
|                // (On == true) or detached from (On == false) a cDevice. It can be used | ||||
|                // to do things like starting/stopping a thread. | ||||
|                // It is guaranteed that Receive() will not be called before Activate(true). | ||||
|                ///< This function is called just before the cReceiver gets attached to | ||||
|                ///< (On == true) or detached from (On == false) a cDevice. It can be used | ||||
|                ///< to do things like starting/stopping a thread. | ||||
|                ///< It is guaranteed that Receive() will not be called before Activate(true). | ||||
|   virtual void Receive(uchar *Data, int Length) = 0; | ||||
|                // This function is called from the cDevice we are attached to, and | ||||
|                // delivers one TS packet from the set of PIDs the cReceiver has requested. | ||||
|                // The data packet must be accepted immediately, and the call must return | ||||
|                // as soon as possible, without any unnecessary delay. Each TS packet | ||||
|                // will be delivered only ONCE, so the cReceiver must make sure that | ||||
|                // it will be able to buffer the data if necessary. | ||||
|                ///< This function is called from the cDevice we are attached to, and | ||||
|                ///< delivers one TS packet from the set of PIDs the cReceiver has requested. | ||||
|                ///< The data packet must be accepted immediately, and the call must return | ||||
|                ///< as soon as possible, without any unnecessary delay. Each TS packet | ||||
|                ///< will be delivered only ONCE, so the cReceiver must make sure that | ||||
|                ///< it will be able to buffer the data if necessary. | ||||
| public: | ||||
|   cReceiver(int Ca, int Priority, int NumPids, ...); | ||||
|                // Creates a new receiver that requires conditional access Ca and has | ||||
|                // the given Priority. NumPids defines the number of PIDs that follow | ||||
|                // this parameter. If any of these PIDs are 0, they will be silently ignored. | ||||
|                // The total number of non-zero PIDs must not exceed MAXRECEIVEPIDS. | ||||
|                // Priority may be any value in the range 0..99. Negative values indicate | ||||
|                // that this cReceiver may be detached at any time (without blocking the | ||||
|                // cDevice it is attached to). | ||||
|   cReceiver(int Ca, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL); | ||||
|                ///< Creates a new receiver that requires conditional access Ca and has | ||||
|                ///< the given Priority. Pid is a single PID (typically the video PID), while | ||||
|                ///< Pids1...Pids3 are pointers to zero terminated lists of PIDs. | ||||
|                ///< If any of these PIDs are 0, they will be silently ignored. | ||||
|                ///< The total number of non-zero PIDs must not exceed MAXRECEIVEPIDS. | ||||
|                ///< Priority may be any value in the range 0..99. Negative values indicate | ||||
|                ///< that this cReceiver may be detached at any time (without blocking the | ||||
|                ///< cDevice it is attached to). | ||||
|   virtual ~cReceiver(); | ||||
|   }; | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: recorder.c 1.12 2005/01/09 12:16:36 kls Exp $ | ||||
|  * $Id: recorder.c 1.13 2005/01/16 12:53:17 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include <stdarg.h> | ||||
| @@ -127,8 +127,8 @@ void cFileWriter::Action(void) | ||||
|   active = false; | ||||
| } | ||||
|  | ||||
| cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2) | ||||
| :cReceiver(Ca, Priority, Setup.UseDolbyDigital ? 5 : 3, VPid, APid1, APid2, DPid1, DPid2) | ||||
| cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids) | ||||
| :cReceiver(Ca, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) | ||||
| ,cThread("recording") | ||||
| { | ||||
|   active = false; | ||||
| @@ -139,7 +139,7 @@ cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int A | ||||
|  | ||||
|   ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, TS_SIZE * 2, true, "Recorder"); | ||||
|   ringBuffer->SetTimeouts(0, 100); | ||||
|   remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2, true); | ||||
|   remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, true); | ||||
|   writer = new cFileWriter(FileName, remux); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: recorder.h 1.2 2004/10/10 11:22:38 kls Exp $ | ||||
|  * $Id: recorder.h 1.3 2005/01/16 12:05:13 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __RECORDER_H | ||||
| @@ -29,7 +29,7 @@ protected: | ||||
|   virtual void Receive(uchar *Data, int Length); | ||||
|   virtual void Action(void); | ||||
| public: | ||||
|   cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2); | ||||
|   cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids); | ||||
|                // Creates a new recorder that requires conditional access Ca, has | ||||
|                // the given Priority and will record the given PIDs into the file FileName. | ||||
|   virtual ~cRecorder(); | ||||
|   | ||||
							
								
								
									
										73
									
								
								remux.c
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								remux.c
									
									
									
									
									
								
							| @@ -11,11 +11,12 @@ | ||||
|  * The cDolbyRepacker code was originally written by Reinhard Nissl <rnissl@gmx.de>, | ||||
|  * and adapted to the VDR coding style by Klaus.Schmidinger@cadsoft.de. | ||||
|  * | ||||
|  * $Id: remux.c 1.24 2005/01/15 12:07:43 kls Exp $ | ||||
|  * $Id: remux.c 1.25 2005/01/16 14:34:25 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "remux.h" | ||||
| #include <stdlib.h> | ||||
| #include "channels.h" | ||||
| #include "thread.h" | ||||
| #include "tools.h" | ||||
|  | ||||
| @@ -335,6 +336,7 @@ int cDolbyRepacker::BreakAt(const uchar *Data, int Count) | ||||
|  | ||||
| class cTS2PES { | ||||
| private: | ||||
|   int pid; | ||||
|   int size; | ||||
|   int found; | ||||
|   int count; | ||||
| @@ -362,16 +364,18 @@ private: | ||||
|   void write_ipack(const uint8_t *Data, int Count); | ||||
|   void instant_repack(const uint8_t *Buf, int Count); | ||||
| public: | ||||
|   cTS2PES(cRingBufferLinear *ResultBuffer, int Size, uint8_t AudioCid = 0x00, cRepacker *Repacker = NULL); | ||||
|   cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t AudioCid = 0x00, cRepacker *Repacker = NULL); | ||||
|   ~cTS2PES(); | ||||
|   int Pid(void) { return pid; } | ||||
|   void ts_to_pes(const uint8_t *Buf); // don't need count (=188) | ||||
|   void Clear(void); | ||||
|   }; | ||||
|  | ||||
| uint8_t cTS2PES::headr[] = { 0x00, 0x00, 0x01 }; | ||||
|  | ||||
| cTS2PES::cTS2PES(cRingBufferLinear *ResultBuffer, int Size, uint8_t AudioCid, cRepacker *Repacker) | ||||
| cTS2PES::cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t AudioCid, cRepacker *Repacker) | ||||
| { | ||||
|   pid = Pid; | ||||
|   resultBuffer = ResultBuffer; | ||||
|   size = Size; | ||||
|   audioCid = AudioCid; | ||||
| @@ -700,35 +704,44 @@ void cTS2PES::ts_to_pes(const uint8_t *Buf) // don't need count (=188) | ||||
|  | ||||
| #define RESULTBUFFERSIZE KILOBYTE(256) | ||||
|  | ||||
| cRemux::cRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool ExitOnFailure) | ||||
| cRemux::cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure) | ||||
| { | ||||
|   vPid = VPid; | ||||
|   aPid1 = APid1; | ||||
|   aPid2 = APid2; | ||||
|   dPid1 = DPid1; | ||||
|   dPid2 = DPid2; | ||||
|   exitOnFailure = ExitOnFailure; | ||||
|   isRadio = VPid == 0 || VPid == 1 || VPid == 0x1FFF; | ||||
|   numUPTerrors = 0; | ||||
|   synced = false; | ||||
|   skipped = 0; | ||||
|   numTracks = 0; | ||||
|   resultSkipped = 0; | ||||
|   resultBuffer = new cRingBufferLinear(RESULTBUFFERSIZE, IPACKS, false, "Result"); | ||||
|   resultBuffer->SetTimeouts(0, 100); | ||||
|   vTS2PES  =         new cTS2PES(resultBuffer, IPACKS); | ||||
|   aTS2PES1 =         new cTS2PES(resultBuffer, IPACKS, 0xC0); | ||||
|   aTS2PES2 = aPid2 ? new cTS2PES(resultBuffer, IPACKS, 0xC1) : NULL; | ||||
|   dTS2PES1 = dPid1 ? new cTS2PES(resultBuffer, IPACKS, 0x00, new cDolbyRepacker) : NULL; | ||||
|   //XXX don't yet know how to tell apart primary and secondary DD data... | ||||
|   dTS2PES2 = /*XXX dPid2 ? new cTS2PES(resultBuffer, IPACKS, 0x00, new cDolbyRepacker) : XXX*/ NULL; | ||||
|   if (VPid) | ||||
|      ts2pes[numTracks++] = new cTS2PES(VPid, resultBuffer, IPACKS); | ||||
|   if (APids) { | ||||
|      int n = 0; | ||||
|      while (*APids && numTracks < MAXTRACKS && n < MAXAPIDS) | ||||
|            ts2pes[numTracks++] = new cTS2PES(*APids++, resultBuffer, IPACKS, 0xC0 + n++); | ||||
|      } | ||||
|   if (DPids) { | ||||
|      int n = 0; | ||||
|      while (*DPids && numTracks < MAXTRACKS && n < MAXDPIDS) { | ||||
|            ts2pes[numTracks++] = new cTS2PES(*DPids++, resultBuffer, IPACKS, 0x00, new cDolbyRepacker); //XXX substream id(n++)??? | ||||
|            break; //XXX until we can handle substream ids we can only handle a single Dolby track | ||||
|            } | ||||
|      } | ||||
|   /* future... | ||||
|   if (SPids) { | ||||
|      int n = 0; | ||||
|      while (*SPids && numTracks < MAXTRACKS && n < MAXSPIDS) | ||||
|            ts2pes[numTracks++] = new cTS2PES(*SPids++, resultBuffer, IPACKS); //XXX substream id(n++)??? | ||||
|      } | ||||
|   */ | ||||
| } | ||||
|  | ||||
| cRemux::~cRemux() | ||||
| { | ||||
|   delete vTS2PES; | ||||
|   delete aTS2PES1; | ||||
|   delete aTS2PES2; | ||||
|   delete dTS2PES1; | ||||
|   delete dTS2PES2; | ||||
|   for (int t = 0; t < numTracks; t++) | ||||
|       delete ts2pes[t]; | ||||
|   delete resultBuffer; | ||||
| } | ||||
|  | ||||
| @@ -800,11 +813,12 @@ int cRemux::Put(const uchar *Data, int Count) | ||||
|          break; // A cTS2PES might write one full packet and also a small rest | ||||
|       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); | ||||
|          else if (pid == dPid1 && dTS2PES1) dTS2PES1->ts_to_pes(Data + i); | ||||
|          else if (pid == dPid2 && dTS2PES2) dTS2PES2->ts_to_pes(Data + i); | ||||
|          for (int t = 0; t < numTracks; t++) { | ||||
|              if (ts2pes[t]->Pid() == pid) { | ||||
|                 ts2pes[t]->ts_to_pes(Data + i); | ||||
|                 break; | ||||
|                 } | ||||
|              } | ||||
|          } | ||||
|       used += TS_SIZE; | ||||
|       } | ||||
| @@ -842,7 +856,7 @@ uchar *cRemux::Get(int &Count, uchar *PictureType) | ||||
|  | ||||
|   // Special VPID case to enable recording radio channels: | ||||
|  | ||||
|   if (vPid == 0 || vPid == 1 || vPid == 0x1FFF) { | ||||
|   if (isRadio) { | ||||
|      // XXX actually '0' should be enough, but '1' must be used with encrypted channels (driver bug?) | ||||
|      // XXX also allowing 0x1FFF to not break Michael Paar's original patch, | ||||
|      // XXX but it would probably be best to only use '0' | ||||
| @@ -920,11 +934,8 @@ void cRemux::Del(int Count) | ||||
|  | ||||
| void cRemux::Clear(void) | ||||
| { | ||||
|   if (vTS2PES)  vTS2PES->Clear(); | ||||
|   if (aTS2PES1) aTS2PES1->Clear(); | ||||
|   if (aTS2PES2) aTS2PES2->Clear(); | ||||
|   if (dTS2PES1) dTS2PES1->Clear(); | ||||
|   if (dTS2PES2) dTS2PES2->Clear(); | ||||
|   for (int t = 0; t < numTracks; t++) | ||||
|       ts2pes[t]->Clear(); | ||||
|   resultBuffer->Clear(); | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										16
									
								
								remux.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								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.12 2004/10/15 12:31:16 kls Exp $ | ||||
|  * $Id: remux.h 1.13 2005/01/16 13:15:17 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __REMUX_H | ||||
| @@ -21,23 +21,31 @@ | ||||
| #define P_FRAME    2 | ||||
| #define B_FRAME    3 | ||||
|  | ||||
| #define MAXTRACKS 64 | ||||
|  | ||||
| class cTS2PES; | ||||
|  | ||||
| class cRemux { | ||||
| private: | ||||
|   bool exitOnFailure; | ||||
|   bool isRadio; | ||||
|   int numUPTerrors; | ||||
|   bool synced; | ||||
|   int skipped; | ||||
|   int vPid, aPid1, aPid2, dPid1, dPid2; | ||||
|   cTS2PES *vTS2PES, *aTS2PES1, *aTS2PES2, *dTS2PES1, *dTS2PES2; | ||||
|   cTS2PES *ts2pes[MAXTRACKS]; | ||||
|   int numTracks; | ||||
|   cRingBufferLinear *resultBuffer; | ||||
|   int resultSkipped; | ||||
|   int GetPid(const uchar *Data); | ||||
|   int GetPacketLength(const uchar *Data, int Count, int Offset); | ||||
|   int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType); | ||||
| public: | ||||
|   cRemux(int VPid, int APid1, int APid2, int DPid1, int DPid2, bool ExitOnFailure = false); | ||||
|   cRemux(int VPid, const int *APids, const int *DPids, const int *SPids, bool ExitOnFailure = false); | ||||
|        ///< Creates a new remuxer for the given PIDs. VPid is the video PID, while | ||||
|        ///< APids, DPids and SPids are pointers to zero terminated lists of audio, | ||||
|        ///< dolby and subtitle PIDs (the pointers may be NULL if there is no such | ||||
|        ///< PID). If ExitOnFailure is true, the remuxer will initiate an "emergency | ||||
|        ///< exit" in case of problems with the data stream. | ||||
|   ~cRemux(); | ||||
|   int Put(const uchar *Data, int Count); | ||||
|        ///< Puts at most Count bytes of Data into the remuxer. | ||||
|   | ||||
							
								
								
									
										14
									
								
								transfer.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								transfer.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: transfer.c 1.22 2005/01/07 15:44:30 kls Exp $ | ||||
|  * $Id: transfer.c 1.23 2005/01/16 13:26:38 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "transfer.h" | ||||
| @@ -14,13 +14,13 @@ | ||||
|  | ||||
| // --- cTransfer ------------------------------------------------------------- | ||||
|  | ||||
| cTransfer::cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2) | ||||
| :cReceiver(0, -1, 5, VPid, APid1, APid2, DPid1, DPid2) | ||||
| cTransfer::cTransfer(int VPid, const int *APids, const int *DPids, const int *SPids) | ||||
| :cReceiver(0, -1, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) | ||||
| ,cThread("transfer") | ||||
| { | ||||
|   ringBuffer = new cRingBufferLinear(TRANSFERBUFSIZE, TS_SIZE * 2, true, "Transfer"); | ||||
|   remux = new cRemux(VPid, APid1, APid2, DPid1, DPid2); | ||||
|   needsBufferReserve = VPid != 0 && DPid1 != 0; | ||||
|   remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids); | ||||
|   needsBufferReserve = Setup.UseDolbyDigital && VPid != 0 && DPids && DPids[0] != 0; | ||||
|   active = false; | ||||
| } | ||||
|  | ||||
| @@ -143,8 +143,8 @@ void cTransfer::Action(void) | ||||
|  | ||||
| cDevice *cTransferControl::receiverDevice = NULL; | ||||
|  | ||||
| cTransferControl::cTransferControl(cDevice *ReceiverDevice, int VPid, int APid1, int APid2, int DPid1, int DPid2) | ||||
| :cControl(transfer = new cTransfer(VPid, APid1, APid2, DPid1, DPid2), true) | ||||
| cTransferControl::cTransferControl(cDevice *ReceiverDevice, int VPid, const int *APids, const int *DPids, const int *SPids) | ||||
| :cControl(transfer = new cTransfer(VPid, APids, DPids, SPids), true) | ||||
| { | ||||
|   ReceiverDevice->AttachReceiver(transfer); | ||||
|   receiverDevice = ReceiverDevice; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: transfer.h 1.8 2005/01/07 15:44:32 kls Exp $ | ||||
|  * $Id: transfer.h 1.9 2005/01/16 12:05:13 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __TRANSFER_H | ||||
| @@ -27,7 +27,7 @@ protected: | ||||
|   virtual void Receive(uchar *Data, int Length); | ||||
|   virtual void Action(void); | ||||
| public: | ||||
|   cTransfer(int VPid, int APid1, int APid2, int DPid1, int DPid2); | ||||
|   cTransfer(int VPid, const int *APids, const int *DPids, const int *SPids); | ||||
|   virtual ~cTransfer(); | ||||
|   }; | ||||
|  | ||||
| @@ -36,7 +36,7 @@ private: | ||||
|   cTransfer *transfer; | ||||
|   static cDevice *receiverDevice; | ||||
| public: | ||||
|   cTransferControl(cDevice *ReceiverDevice, int VPid, int APid1, int APid2, int DPid1, int DPid2); | ||||
|   cTransferControl(cDevice *ReceiverDevice, int VPid, const int *APids, const int *DPids, const int *SPids); | ||||
|   ~cTransferControl(); | ||||
|   virtual void Hide(void) {} | ||||
|   static cDevice *ReceiverDevice(void) { return receiverDevice; } | ||||
|   | ||||
							
								
								
									
										5
									
								
								vdr.5
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								vdr.5
									
									
									
									
									
								
							| @@ -8,7 +8,7 @@ | ||||
| .\" License as specified in the file COPYING that comes with the | ||||
| .\" vdr distribution. | ||||
| .\" | ||||
| .\" $Id: vdr.5 1.32 2005/01/09 13:16:40 kls Exp $ | ||||
| .\" $Id: vdr.5 1.33 2005/01/16 13:45:57 kls Exp $ | ||||
| .\" | ||||
| .TH vdr 5 "19 Dec 2004" "1.3.18" "Video Disk Recorder Files" | ||||
| .SH NAME | ||||
| @@ -559,7 +559,8 @@ The files \fI001.vdr\fR...\fI255.vdr\fR are the actual recorded MPEG data | ||||
| files. In order to keep the size of an individual file below a given limit, | ||||
| a recording is split into several files. The contents of these files is | ||||
| \fBPacketized Elementary Stream\fR (PES) and contains ES packets with ids | ||||
| 0xE0 for video, 0xC0 for audio 1 and 0xC1 for audio 2 (if available). | ||||
| 0xE0...0xEF for video (only one of these may actually occur in a file), | ||||
| 0xC0...0xDF for audio 1...32 (up to 32 audio tracks may occur). | ||||
| Dolby Digital data is stored in packets with ids 0xBD. | ||||
| .SS INDEX | ||||
| The file \fIindex.vdr\fR (if present in a recording directory) contains | ||||
|   | ||||
		Reference in New Issue
	
	Block a user