mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Using timer priority to interrupt lower priority timer recording
This commit is contained in:
		
							
								
								
									
										8
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -266,7 +266,7 @@ Video Disk Recorder Revision History | ||||
|   are programmed via the "Schedules" menu) are now replaced by suitable | ||||
|   substitutes. | ||||
|  | ||||
| 2000-11-11: Version 0.68 | ||||
| 2000-11-12: Version 0.68 | ||||
|  | ||||
| - Date and time in the title of an event info page are now always right adjusted. | ||||
| - The 'current channel' is now handled device specific (in case there is more | ||||
| @@ -281,3 +281,9 @@ Video Disk Recorder Revision History | ||||
| - There can now be a configuration file named 'commands.conf' that defines | ||||
|   commands that can be executed through the "Main" menu's "Commands" option | ||||
|   (see FORMATS for details on how to define these commands). | ||||
| - The 'Priority' parameter of the timers is now also used to interrupt a low | ||||
|   priority timer recording if a higher priority timer wants to record. | ||||
| - A timer recording on a DVB card with a CAM module will now be interrupted | ||||
|   by a timer that needs to use this specific DVB card to record an encrypted | ||||
|   channel, if the timer currently occupying this DVB card doesn't need the | ||||
|   CAM module (and thus can continue recording on a different DVB card). | ||||
|   | ||||
							
								
								
									
										4
									
								
								MANUAL
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								MANUAL
									
									
									
									
									
								
							| @@ -203,7 +203,9 @@ Video Disk Recorder User's Manual | ||||
|              to free space for a new recording. If the disk is full and a new | ||||
|              recording needs more space, an existing recording with the lowest | ||||
|              Priority (and which has exceeded its guaranteed Lifetime) will be | ||||
|              removed. | ||||
|              removed. If all available DVB cards are currently occupied, a | ||||
|              timer with a higher priority will interrupt the timer with the | ||||
|              lowest priority in order to start recording. | ||||
|   Lifetime:  The number of days (0..99) a recording made through this timer is | ||||
|              guaranteed to remain on disk before it is automatically removed | ||||
|              to free up space for a new recording. Note that setting this | ||||
|   | ||||
							
								
								
									
										10
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								config.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: config.c 1.32 2000/11/11 15:41:07 kls Exp $ | ||||
|  * $Id: config.c 1.33 2000/11/12 12:22:40 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
| @@ -294,8 +294,8 @@ cTimer::cTimer(bool Instant) | ||||
|   if (stop >= 2400) | ||||
|      stop -= 2400; | ||||
| //TODO VPS??? | ||||
|   priority = 99; | ||||
|   lifetime = 99; | ||||
|   priority = DEFAULTPRIORITY; | ||||
|   lifetime = DEFAULTLIFETIME; | ||||
|   *file = 0; | ||||
|   summary = NULL; | ||||
|   if (Instant && ch) | ||||
| @@ -319,8 +319,8 @@ cTimer::cTimer(const cEventInfo *EventInfo) | ||||
|   stop = time->tm_hour * 100 + time->tm_min; | ||||
|   if (stop >= 2400) | ||||
|      stop -= 2400; | ||||
|   priority = 99; | ||||
|   lifetime = 99; | ||||
|   priority = DEFAULTPRIORITY; | ||||
|   lifetime = DEFAULTLIFETIME; | ||||
|   *file = 0; | ||||
|   const char *Title = EventInfo->GetTitle(); | ||||
|   if (!isempty(Title)) | ||||
|   | ||||
							
								
								
									
										5
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								config.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: config.h 1.32 2000/11/11 14:39:40 kls Exp $ | ||||
|  * $Id: config.h 1.33 2000/11/12 12:22:24 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __CONFIG_H | ||||
| @@ -95,6 +95,9 @@ public: | ||||
|   bool Switch(cDvbApi *DvbApi = NULL); | ||||
|   }; | ||||
|  | ||||
| #define DEFAULTPRIORITY 99 | ||||
| #define DEFAULTLIFETIME 99 | ||||
|  | ||||
| class cTimer : public cListObject { | ||||
| private: | ||||
|   time_t startTime, stopTime; | ||||
|   | ||||
							
								
								
									
										30
									
								
								dvbapi.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								dvbapi.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: dvbapi.c 1.36 2000/11/05 18:30:58 kls Exp $ | ||||
|  * $Id: dvbapi.c 1.37 2000/11/12 12:59:50 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "dvbapi.h" | ||||
| @@ -1091,6 +1091,8 @@ cDvbApi::cDvbApi(const char *VideoFileName, const char *VbiFileName) | ||||
|   pidRecord = pidReplay = 0; | ||||
|   fromRecord = toRecord = -1; | ||||
|   fromReplay = toReplay = -1; | ||||
|   ca = 0; | ||||
|   priority = -1; | ||||
|   videoDev = open(VideoFileName, O_RDWR | O_NONBLOCK); | ||||
|   if (videoDev >= 0) { | ||||
|      siProcessor = new cSIProcessor(VbiFileName); | ||||
| @@ -1161,22 +1163,25 @@ bool cDvbApi::SetPrimaryDvbApi(int n) | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| cDvbApi *cDvbApi::GetDvbApi(int Ca) | ||||
| cDvbApi *cDvbApi::GetDvbApi(int Ca, int Priority) | ||||
| { | ||||
|   cDvbApi *d = NULL; | ||||
|   Ca--; | ||||
|   int index = Ca - 1; | ||||
|   for (int i = MAXDVBAPI; --i >= 0; ) { | ||||
|       if (dvbApi[i] && !dvbApi[i]->Recording()) { | ||||
|          if (i == Ca) | ||||
|             return dvbApi[i]; | ||||
|          if (Ca < 0) { | ||||
|       if (dvbApi[i]) { | ||||
|          if (i == index) { // means we need exactly _this_ device | ||||
|             d = dvbApi[i]; | ||||
|             if (d != PrimaryDvbApi) | ||||
|             break; | ||||
|             } | ||||
|          else if (Ca == 0) { // means any device would be acceptable | ||||
|             if (!d || !dvbApi[i]->Recording() || (d->Recording() && d->Priority() > dvbApi[i]->Priority())) | ||||
|                d = dvbApi[i]; | ||||
|             if (d && d != PrimaryDvbApi && !d->Recording()) // avoids the PrimaryDvbApi if possible | ||||
|                break; | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|   return d; | ||||
|   return (d && (!d->Recording() || d->Priority() < Priority || (!d->Ca() && Ca))) ? d : NULL; | ||||
| } | ||||
|  | ||||
| int cDvbApi::Index(void) | ||||
| @@ -1746,7 +1751,7 @@ bool cDvbApi::Replaying(void) | ||||
|   return pidReplay; | ||||
| } | ||||
|  | ||||
| bool cDvbApi::StartRecord(const char *FileName) | ||||
| bool cDvbApi::StartRecord(const char *FileName, int Ca, int Priority) | ||||
| { | ||||
|   if (Recording()) { | ||||
|      esyslog(LOG_ERR, "ERROR: StartRecord() called while recording - ignored!"); | ||||
| @@ -1843,6 +1848,9 @@ bool cDvbApi::StartRecord(const char *FileName) | ||||
|  | ||||
|      fromRecord = fromRecordPipe[0]; | ||||
|      toRecord = toRecordPipe[1]; | ||||
|  | ||||
|      ca = Ca; | ||||
|      priority = Priority; | ||||
|      return true; | ||||
|      } | ||||
|   return false; | ||||
| @@ -1857,6 +1865,8 @@ void cDvbApi::StopRecord(void) | ||||
|      toRecord = fromRecord = -1; | ||||
|      KillProcess(pidRecord); | ||||
|      pidRecord = 0; | ||||
|      ca = 0; | ||||
|      priority = -1; | ||||
|      SetReplayMode(VID_PLAY_RESET); //XXX | ||||
|      } | ||||
| } | ||||
|   | ||||
							
								
								
									
										25
									
								
								dvbapi.h
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								dvbapi.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: dvbapi.h 1.22 2000/11/05 13:39:31 kls Exp $ | ||||
|  * $Id: dvbapi.h 1.23 2000/11/12 12:52:41 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __DVBAPI_H | ||||
| @@ -59,11 +59,15 @@ public: | ||||
|   static bool SetPrimaryDvbApi(int n); | ||||
|          // Sets the primary DVB device to 'n' (which must be in the range | ||||
|          // 1...NumDvbApis) and returns true if this was possible. | ||||
|   static cDvbApi *GetDvbApi(int Ca = 0); | ||||
|   static cDvbApi *GetDvbApi(int Ca, int Priority); | ||||
|          // Selects a free DVB device, starting with the highest device number | ||||
|          // (but avoiding, if possible, the PrimaryDvbApi). | ||||
|          // If Ca is not 0, the device with the given number will be returned | ||||
|          // if it is not currently recording. | ||||
|          // If Ca is not 0, the device with the given number will be returned. | ||||
|          // If all DVB devices are currently recording, the one recording the | ||||
|          // lowest priority timer (if any) that is lower than the given Priority | ||||
|          // will be returned. | ||||
|          // The caller must check whether the returned DVB device is actually | ||||
|          // recording and stop recording if necessary. | ||||
|   int Index(void); | ||||
|          // Returns the index of this DvbApi. | ||||
|   static bool Init(void); | ||||
| @@ -158,14 +162,23 @@ private: | ||||
|   pid_t pidRecord, pidReplay; | ||||
|   int fromRecord, toRecord; | ||||
|   int fromReplay, toReplay; | ||||
|   int ca; | ||||
|   int priority; | ||||
|   void SetReplayMode(int Mode); | ||||
| protected: | ||||
|   int  Ca(void) { return ca; } | ||||
|        // Returns the ca of the current recording session (0..MAXDVBAPI). | ||||
|   int  Priority(void) { return priority; } | ||||
|        // Returns the priority of the current recording session (0..99), | ||||
|        // or -1 if no recording is currently active. | ||||
| public: | ||||
|   bool Recording(void); | ||||
|        // Returns true if we are currently recording. | ||||
|   bool Replaying(void); | ||||
|        // Returns true if we are currently replaying. | ||||
|   bool StartRecord(const char *FileName); | ||||
|        // Starts recording the current channel into the given file. | ||||
|   bool StartRecord(const char *FileName, int Ca, int Priority); | ||||
|        // Starts recording the current channel into the given file, with | ||||
|        // the given ca and priority. | ||||
|        // In order to be able to record longer movies, | ||||
|        // a numerical suffix will be appended to the file name. The inital | ||||
|        // value of that suffix will be larger than any existing file under | ||||
|   | ||||
							
								
								
									
										19
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								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.46 2000/11/11 15:22:56 kls Exp $ | ||||
|  * $Id: menu.c 1.47 2000/11/12 13:03:35 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "menu.h" | ||||
| @@ -1817,7 +1817,7 @@ cRecordControl::cRecordControl(cDvbApi *DvbApi, cTimer *Timer) | ||||
|   timer->SetRecording(true); | ||||
|   Channels.SwitchTo(timer->channel, dvbApi); | ||||
|   cRecording Recording(timer); | ||||
|   if (dvbApi->StartRecord(Recording.FileName())) | ||||
|   if (dvbApi->StartRecord(Recording.FileName(), Channels.GetByNumber(timer->channel)->ca, timer->priority)) | ||||
|      Recording.WriteSummary(); | ||||
|   Interface->DisplayRecording(dvbApi->Index(), true); | ||||
| } | ||||
| @@ -1863,8 +1863,9 @@ bool cRecordControls::Start(cTimer *Timer) | ||||
|   cChannel *channel = Channels.GetByNumber(ch); | ||||
|  | ||||
|   if (channel) { | ||||
|      cDvbApi *dvbApi = cDvbApi::GetDvbApi(channel->ca); | ||||
|      cDvbApi *dvbApi = cDvbApi::GetDvbApi(channel->ca, Timer ? Timer->priority : DEFAULTPRIORITY); | ||||
|      if (dvbApi) { | ||||
|         Stop(dvbApi); | ||||
|         for (int i = 0; i < MAXDVBAPI; i++) { | ||||
|             if (!RecordControls[i]) { | ||||
|                RecordControls[i] = new cRecordControl(dvbApi, Timer); | ||||
| @@ -1891,6 +1892,18 @@ void cRecordControls::Stop(const char *InstantId) | ||||
|       } | ||||
| } | ||||
|  | ||||
| void cRecordControls::Stop(cDvbApi *DvbApi) | ||||
| { | ||||
|   for (int i = 0; i < MAXDVBAPI; i++) { | ||||
|       if (RecordControls[i]) { | ||||
|          if (RecordControls[i]->Uses(DvbApi)) { | ||||
|             isyslog(LOG_INFO, "stopping recording on DVB device %d due to higher priority", DvbApi->Index() + 1); | ||||
|             RecordControls[i]->Stop(); | ||||
|             } | ||||
|          } | ||||
|       } | ||||
| } | ||||
|  | ||||
| const char *cRecordControls::GetInstantId(const char *LastInstantId) | ||||
| { | ||||
|   for (int i = 0; i < MAXDVBAPI; i++) { | ||||
|   | ||||
							
								
								
									
										4
									
								
								menu.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								menu.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: menu.h 1.13 2000/11/01 14:03:09 kls Exp $ | ||||
|  * $Id: menu.h 1.14 2000/11/12 12:33:00 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef _MENU_H | ||||
| @@ -59,6 +59,7 @@ public: | ||||
|   cRecordControl(cDvbApi *DvbApi, cTimer *Timer = NULL); | ||||
|   virtual ~cRecordControl(); | ||||
|   bool Process(void); | ||||
|   bool Uses(cDvbApi *DvbApi) { return DvbApi == dvbApi; } | ||||
|   void Stop(bool KeepInstant = false); | ||||
|   bool IsInstant(void) { return instantId; } | ||||
|   const char *InstantId(void) { return instantId; } | ||||
| @@ -70,6 +71,7 @@ private: | ||||
| public: | ||||
|   static bool Start(cTimer *Timer = NULL); | ||||
|   static void Stop(const char *InstantId); | ||||
|   static void Stop(cDvbApi *DvbApi); | ||||
|   static const char *GetInstantId(const char *LastInstantId); | ||||
|   static void Process(void); | ||||
|   }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user