mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Version 1.1.6
- Re-visited the race condition fix in the cDvbPlayer (thanks again to Andreas Schultz). - Changed the VFAT handling to allow users who normally use it but have forgotten to set it when compiling a new version of VDR to at least see their recordings made with VFAT enabled (thanks to Christian Rienecker). - Added some missing teletext PIDs (thanks to Joerg Riechardt). - Fixed PID handling for cReceiver. - Added a missing #include to ringbuffer.c (thanks to Martin Hammerschmid). - Now using CC, CFLAGS, CXX and CXXFLAGS in Makefile. - Changed the cDevice class to allow plugins to implement their own devices (see PLUGINS.html for details).
This commit is contained in:
		@@ -44,6 +44,7 @@ Martin Hammerschmid <martin@hammerschmid.com>
 | 
				
			|||||||
 for suggesting to use the "Blue" button in the main menu to resume replay
 | 
					 for suggesting to use the "Blue" button in the main menu to resume replay
 | 
				
			||||||
 for implementing pege up/down with the "Left" and "Right" keys
 | 
					 for implementing pege up/down with the "Left" and "Right" keys
 | 
				
			||||||
 for detecting a deadlock when switching channels via Schedule/Now|Next/Switch
 | 
					 for detecting a deadlock when switching channels via Schedule/Now|Next/Switch
 | 
				
			||||||
 | 
					 for adding a missing #include to ringbuffer.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Bastian Guse <bastian@nocopy.de>
 | 
					Bastian Guse <bastian@nocopy.de>
 | 
				
			||||||
 for writing the FORMATS entry for timers.conf
 | 
					 for writing the FORMATS entry for timers.conf
 | 
				
			||||||
@@ -367,3 +368,9 @@ Paul Lacatus <paul@campina.iiruc.ro>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Istvan Koenigsberger <istvnko@hotmail.com> and Guido Josten <guido.josten@t-online.de>
 | 
					Istvan Koenigsberger <istvnko@hotmail.com> and Guido Josten <guido.josten@t-online.de>
 | 
				
			||||||
 for translating OSD texts to the Hungarian language
 | 
					 for translating OSD texts to the Hungarian language
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Christian Rienecker <C.Rienecker@deutschepost.de>
 | 
				
			||||||
 | 
					 for making the VFAT handling more tolerant for users who forget to turn it on
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Joerg Riechardt <J.Riechardt@gmx.de>
 | 
				
			||||||
 | 
					 for filling in some missing teletext PIDs
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								HISTORY
									
									
									
									
									
								
							@@ -1378,3 +1378,17 @@ Video Disk Recorder Revision History
 | 
				
			|||||||
- Fixed a possible race condition in the cDvbPlayer (thanks to Andreas Schultz
 | 
					- Fixed a possible race condition in the cDvbPlayer (thanks to Andreas Schultz
 | 
				
			||||||
  for pointing out this one).
 | 
					  for pointing out this one).
 | 
				
			||||||
- Disabled channels on Transponder 12070 in 'channels.conf', which apparently no longer transmits.
 | 
					- Disabled channels on Transponder 12070 in 'channels.conf', which apparently no longer transmits.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2002-08-04: Version 1.1.6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Re-visited the race condition fix in the cDvbPlayer (thanks again to Andreas
 | 
				
			||||||
 | 
					  Schultz).
 | 
				
			||||||
 | 
					- Changed the VFAT handling to allow users who normally use it but have forgotten
 | 
				
			||||||
 | 
					  to set it when compiling a new version of VDR to at least see their recordings
 | 
				
			||||||
 | 
					  made with VFAT enabled (thanks to Christian Rienecker).
 | 
				
			||||||
 | 
					- Added some missing teletext PIDs (thanks to Joerg Riechardt).
 | 
				
			||||||
 | 
					- Fixed PID handling for cReceiver.
 | 
				
			||||||
 | 
					- Added a missing #include to ringbuffer.c (thanks to Martin Hammerschmid).
 | 
				
			||||||
 | 
					- Now using CC, CFLAGS, CXX and CXXFLAGS in Makefile.
 | 
				
			||||||
 | 
					- Changed the cDevice class to allow plugins to implement their own devices (see
 | 
				
			||||||
 | 
					  PLUGINS.html for details).
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								Makefile
									
									
									
									
									
								
							@@ -4,10 +4,16 @@
 | 
				
			|||||||
# See the main source file 'vdr.c' for copyright information and
 | 
					# See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
# how to reach the author.
 | 
					# how to reach the author.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# $Id: Makefile 1.42 2002/06/22 10:21:56 kls Exp $
 | 
					# $Id: Makefile 1.44 2002/07/28 15:20:47 kls Exp $
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.DELETE_ON_ERROR:
 | 
					.DELETE_ON_ERROR:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CC       = gcc
 | 
				
			||||||
 | 
					CFLAGS   = -O2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CXX      = g++
 | 
				
			||||||
 | 
					CXXFLAGS = -g -O2 -Wall -Woverloaded-virtual
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DVBDIR   = ../DVB
 | 
					DVBDIR   = ../DVB
 | 
				
			||||||
DTVDIR   = ./libdtv
 | 
					DTVDIR   = ./libdtv
 | 
				
			||||||
MANDIR   = /usr/local/man
 | 
					MANDIR   = /usr/local/man
 | 
				
			||||||
@@ -21,7 +27,7 @@ INCLUDES = -I$(DVBDIR)/ost/include
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
DTVLIB   = $(DTVDIR)/libdtv.a
 | 
					DTVLIB   = $(DTVDIR)/libdtv.a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OBJS = audio.o config.o cutter.o device.o dvbplayer.o dvbosd.o eit.o eitscan.o font.o i18n.o\
 | 
					OBJS = audio.o config.o cutter.o device.o dvbdevice.o dvbosd.o dvbplayer.o eit.o eitscan.o font.o i18n.o\
 | 
				
			||||||
       interface.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o receiver.o\
 | 
					       interface.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o receiver.o\
 | 
				
			||||||
       recorder.o recording.o remote.o remux.o ringbuffer.o status.o svdrp.o thread.o\
 | 
					       recorder.o recording.o remote.o remux.o ringbuffer.o status.o svdrp.o thread.o\
 | 
				
			||||||
       tools.o transfer.o vdr.o videodir.o
 | 
					       tools.o transfer.o vdr.o videodir.o
 | 
				
			||||||
@@ -58,11 +64,11 @@ font: genfontfile fontfix.c fontosd.c
 | 
				
			|||||||
# Implicit rules:
 | 
					# Implicit rules:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%.o: %.c
 | 
					%.o: %.c
 | 
				
			||||||
	g++ -g -O2 -Wall -Woverloaded-virtual -c $(DEFINES) $(INCLUDES) $<
 | 
						$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Dependencies:
 | 
					# Dependencies:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MAKEDEP = g++ -MM -MG
 | 
					MAKEDEP = $(CXX) -MM -MG
 | 
				
			||||||
DEPFILE = .dependencies
 | 
					DEPFILE = .dependencies
 | 
				
			||||||
$(DEPFILE): Makefile
 | 
					$(DEPFILE): Makefile
 | 
				
			||||||
	@$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
 | 
						@$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
 | 
				
			||||||
@@ -72,7 +78,7 @@ $(DEPFILE): Makefile
 | 
				
			|||||||
# The main program:
 | 
					# The main program:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vdr: $(OBJS) $(DTVLIB)
 | 
					vdr: $(OBJS) $(DTVLIB)
 | 
				
			||||||
	g++ -g -O2 -rdynamic $(OBJS) $(NCURSESLIB) -ljpeg -lpthread -ldl $(LIBDIRS) $(DTVLIB) -o vdr
 | 
						$(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) -ljpeg -lpthread -ldl $(LIBDIRS) $(DTVLIB) -o vdr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The font files:
 | 
					# The font files:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,7 +90,7 @@ fontosd.c:
 | 
				
			|||||||
# The font file generator:
 | 
					# The font file generator:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
genfontfile: genfontfile.c
 | 
					genfontfile: genfontfile.c
 | 
				
			||||||
	gcc -o $@ -O2 -L/usr/X11R6/lib $< -lX11
 | 
						$(CC) $(CFLAGS) -o $@ -L/usr/X11R6/lib $< -lX11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The libdtv library:
 | 
					# The libdtv library:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										207
									
								
								PLUGINS.html
									
									
									
									
									
								
							
							
						
						
									
										207
									
								
								PLUGINS.html
									
									
									
									
									
								
							@@ -12,7 +12,7 @@ This interface allows programmers to develop additional functionality for VDR co
 | 
				
			|||||||
separate from the core VDR source, without the need of patching the original
 | 
					separate from the core VDR source, without the need of patching the original
 | 
				
			||||||
VDR code (and all the problems of correlating various patches).
 | 
					VDR code (and all the problems of correlating various patches).
 | 
				
			||||||
<p>
 | 
					<p>
 | 
				
			||||||
<!--X1.1.3--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
 | 
					<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
				
			||||||
This document is divided into two parts, the first one describing the
 | 
					This document is divided into two parts, the first one describing the
 | 
				
			||||||
<a href="#Part I - The Outside Interface"><i>outside</i> interface</a>
 | 
					<a href="#Part I - The Outside Interface"><i>outside</i> interface</a>
 | 
				
			||||||
of the plugin system, and the second one describing the
 | 
					of the plugin system, and the second one describing the
 | 
				
			||||||
@@ -23,18 +23,18 @@ The <i>inside</i> interface provides the plugin code access to VDR's internal da
 | 
				
			|||||||
structures and allows it to hook itself into specific areas to perform special actions.
 | 
					structures and allows it to hook itself into specific areas to perform special actions.
 | 
				
			||||||
<!--X1.1.3--></td></tr></table>
 | 
					<!--X1.1.3--></td></tr></table>
 | 
				
			||||||
<p>
 | 
					<p>
 | 
				
			||||||
<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
					<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
				
			||||||
Important modifications introduced in version 1.1.2 are marked like this.
 | 
					 | 
				
			||||||
<!--X1.1.2--></td></tr></table>
 | 
					 | 
				
			||||||
<!--X1.1.3--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
 | 
					 | 
				
			||||||
Important modifications introduced in version 1.1.3 are marked like this.
 | 
					Important modifications introduced in version 1.1.3 are marked like this.
 | 
				
			||||||
<!--X1.1.3--></td></tr></table>
 | 
					<!--X1.1.3--></td></tr></table>
 | 
				
			||||||
<!--X1.1.4--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
 | 
					<!--X1.1.4--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
 | 
				
			||||||
Important modifications introduced in version 1.1.4 are marked like this.
 | 
					Important modifications introduced in version 1.1.4 are marked like this.
 | 
				
			||||||
<!--X1.1.4--></td></tr></table>
 | 
					<!--X1.1.4--></td></tr></table>
 | 
				
			||||||
<!--X1.1.5--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
 | 
					<!--X1.1.5--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
 | 
				
			||||||
Important modifications introduced in version 1.1.5 are marked like this.
 | 
					Important modifications introduced in version 1.1.5 are marked like this.
 | 
				
			||||||
<!--X1.1.5--></td></tr></table>
 | 
					<!--X1.1.5--></td></tr></table>
 | 
				
			||||||
 | 
					<!--X1.1.6--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
 | 
				
			||||||
 | 
					Important modifications introduced in version 1.1.6 are marked like this.
 | 
				
			||||||
 | 
					<!--X1.1.6--></td></tr></table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center>
 | 
					<a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -131,15 +131,12 @@ from the web, it will typically have a name like
 | 
				
			|||||||
<p>
 | 
					<p>
 | 
				
			||||||
and will unpack into a directory named
 | 
					and will unpack into a directory named
 | 
				
			||||||
<p>
 | 
					<p>
 | 
				
			||||||
<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
					 | 
				
			||||||
<tt>hello-0.0.1</tt>
 | 
					<tt>hello-0.0.1</tt>
 | 
				
			||||||
<!--X1.1.2--></td></tr></table>
 | 
					 | 
				
			||||||
<p>
 | 
					<p>
 | 
				
			||||||
To use the <tt>plugins</tt> and <tt>plugins-clean</tt> targets from the VDR <tt>Makefile</tt>
 | 
					To use the <tt>plugins</tt> and <tt>plugins-clean</tt> targets from the VDR <tt>Makefile</tt>
 | 
				
			||||||
you need to unpack such an archive into the <tt>VDR/PLUGINS/SRC</tt> directory and
 | 
					you need to unpack such an archive into the <tt>VDR/PLUGINS/SRC</tt> directory and
 | 
				
			||||||
create a symbolic link with the basic plugin name, as in
 | 
					create a symbolic link with the basic plugin name, as in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
					 | 
				
			||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
ln -s hello-0.0.1 hello
 | 
					ln -s hello-0.0.1 hello
 | 
				
			||||||
</pre></td></tr></table><p>
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
@@ -149,7 +146,6 @@ of only lowercase characters and digits, it will only follow the symbolic links,
 | 
				
			|||||||
should lead to the current version of the plugin you want to use. This way you can
 | 
					should lead to the current version of the plugin you want to use. This way you can
 | 
				
			||||||
have several different versions of a plugin source (like <tt>hello-0.0.1</tt> and
 | 
					have several different versions of a plugin source (like <tt>hello-0.0.1</tt> and
 | 
				
			||||||
<tt>hello-0.0.2</tt>) and define which one to actually use through the symbolic link.
 | 
					<tt>hello-0.0.2</tt>) and define which one to actually use through the symbolic link.
 | 
				
			||||||
<!--X1.1.2--></td></tr></table>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<a name="Initializing a new plugin directory"><hr><h2>Initializing a new plugin directory</h2>
 | 
					<a name="Initializing a new plugin directory"><hr><h2>Initializing a new plugin directory</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -422,11 +418,9 @@ If a plugin implements a function that runs in the background (presumably in a
 | 
				
			|||||||
thread of its own), or wants to make use of <a href="#Internationalization">internationalization</a>,
 | 
					thread of its own), or wants to make use of <a href="#Internationalization">internationalization</a>,
 | 
				
			||||||
it needs to implement the function
 | 
					it needs to implement the function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
					 | 
				
			||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
virtual bool Start(void);
 | 
					virtual bool Start(void);
 | 
				
			||||||
</pre></td></tr></table><p>
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
<!--X1.1.2--></td></tr></table>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
which is called once for each plugin at program startup.
 | 
					which is called once for each plugin at program startup.
 | 
				
			||||||
Inside this function the plugin must set up everything necessary to perform
 | 
					Inside this function the plugin must set up everything necessary to perform
 | 
				
			||||||
@@ -434,12 +428,10 @@ its task. This may, for instance, be a thread that collects data from the DVB
 | 
				
			|||||||
stream, which is later presented to the user via a function that is available
 | 
					stream, which is later presented to the user via a function that is available
 | 
				
			||||||
from the main menu.
 | 
					from the main menu.
 | 
				
			||||||
<p>
 | 
					<p>
 | 
				
			||||||
<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
					 | 
				
			||||||
A return value of <i>false</i> indicates that something has gone wrong and the
 | 
					A return value of <i>false</i> indicates that something has gone wrong and the
 | 
				
			||||||
plugin will not be able to perform its task. In that case, the plugin should
 | 
					plugin will not be able to perform its task. In that case, the plugin should
 | 
				
			||||||
write a proper error message to the log file. The first plugin that returns
 | 
					write a proper error message to the log file. The first plugin that returns
 | 
				
			||||||
<i>false</i> from its <tt>Start()</tt> function will cause VDR to exit.
 | 
					<i>false</i> from its <tt>Start()</tt> function will cause VDR to exit.
 | 
				
			||||||
<!--X1.1.2--></td></tr></table>
 | 
					 | 
				
			||||||
<p>
 | 
					<p>
 | 
				
			||||||
If the plugin doesn't implement any background functionality or internationalized
 | 
					If the plugin doesn't implement any background functionality or internationalized
 | 
				
			||||||
texts, it doesn't need to implement this function.
 | 
					texts, it doesn't need to implement this function.
 | 
				
			||||||
@@ -498,7 +490,6 @@ interaction is possible. If a specific action takes longer than a few seconds,
 | 
				
			|||||||
the plugin should launch a separate thread to do this.
 | 
					the plugin should launch a separate thread to do this.
 | 
				
			||||||
</b>
 | 
					</b>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
					 | 
				
			||||||
<hr><h2>Housekeeping</h2>
 | 
					<hr><h2>Housekeeping</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<center><i><b>Chores, chores...</b></i></center><p>
 | 
					<center><i><b>Chores, chores...</b></i></center><p>
 | 
				
			||||||
@@ -523,7 +514,6 @@ as possible! As long as the program stays inside this function, no other user
 | 
				
			|||||||
interaction is possible. If a specific action takes longer than a few seconds,
 | 
					interaction is possible. If a specific action takes longer than a few seconds,
 | 
				
			||||||
the plugin should launch a separate thread to do this.
 | 
					the plugin should launch a separate thread to do this.
 | 
				
			||||||
</b>
 | 
					</b>
 | 
				
			||||||
<!--X1.1.2--></td></tr></table>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<a name="Setup parameters"><hr><h2>Setup parameters</h2>
 | 
					<a name="Setup parameters"><hr><h2>Setup parameters</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -656,7 +646,6 @@ You can first assign the temporary values to the global variables and then do th
 | 
				
			|||||||
your setup parameters and use that one to copy all parameters with one single statement
 | 
					your setup parameters and use that one to copy all parameters with one single statement
 | 
				
			||||||
(like VDR does with its cSetup class).
 | 
					(like VDR does with its cSetup class).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
					 | 
				
			||||||
<hr><h2>Configuration files</h2>
 | 
					<hr><h2>Configuration files</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<center><i><b>I want my own stuff!</b></i></center><p>
 | 
					<center><i><b>I want my own stuff!</b></i></center><p>
 | 
				
			||||||
@@ -711,7 +700,6 @@ plugin class, by writing
 | 
				
			|||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
const char *MyConfigDir = cPlugin::ConfigDirectory();
 | 
					const char *MyConfigDir = cPlugin::ConfigDirectory();
 | 
				
			||||||
</pre></td></tr></table><p>
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
<!--X1.1.2--></td></tr></table>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<a name="Internationalization"><hr><h2>Internationalization</h2>
 | 
					<a name="Internationalization"><hr><h2>Internationalization</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -826,7 +814,7 @@ and display their help and/or version information in addition to its own output.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
If you want to make your plugin available to other VDR users, you'll need to
 | 
					If you want to make your plugin available to other VDR users, you'll need to
 | 
				
			||||||
make a package that can be easily distributed.
 | 
					make a package that can be easily distributed.
 | 
				
			||||||
<!--X1.1.3--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
 | 
					<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
				
			||||||
The <tt>Makefile</tt> that has been created by the call to
 | 
					The <tt>Makefile</tt> that has been created by the call to
 | 
				
			||||||
<a href="#Initializing a new plugin directory"><tt>newplugin</tt></a>
 | 
					<a href="#Initializing a new plugin directory"><tt>newplugin</tt></a>
 | 
				
			||||||
provides the target <tt>dist</tt>, which does this for you.
 | 
					provides the target <tt>dist</tt>, which does this for you.
 | 
				
			||||||
@@ -848,7 +836,7 @@ vdr-hello-0.0.1.tgz
 | 
				
			|||||||
in your source directory, where <tt>hello</tt> will be replaced with your actual
 | 
					in your source directory, where <tt>hello</tt> will be replaced with your actual
 | 
				
			||||||
plugin's name, and <tt>0.0.1</tt> will be your plugin's current version number.
 | 
					plugin's name, and <tt>0.0.1</tt> will be your plugin's current version number.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!--X1.1.3--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
 | 
					<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%>
 | 
				
			||||||
<a name="Part II - The Inside Interface"><hr><center><h1>Part II - The Inside Interface</h1></center>
 | 
					<a name="Part II - The Inside Interface"><hr><center><h1>Part II - The Inside Interface</h1></center>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<hr><h2>Status monitor</h2>
 | 
					<hr><h2>Status monitor</h2>
 | 
				
			||||||
@@ -925,7 +913,7 @@ member functions are available in <tt>cStatus</tt>. You only need to implement
 | 
				
			|||||||
the functions you actually want to use.
 | 
					the functions you actually want to use.
 | 
				
			||||||
<!--X1.1.3--></td></tr></table>
 | 
					<!--X1.1.3--></td></tr></table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!--X1.1.4--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
 | 
					<!--X1.1.4--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
 | 
				
			||||||
<hr><h2>Players</h2>
 | 
					<hr><h2>Players</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<center><i><b>Play it again, Sam!</b></i></center><p>
 | 
					<center><i><b>Play it again, Sam!</b></i></center><p>
 | 
				
			||||||
@@ -1076,7 +1064,63 @@ that they already know. If you absolutely want to do things differently, just go
 | 
				
			|||||||
ahead - it's your show...
 | 
					ahead - it's your show...
 | 
				
			||||||
<!--X1.1.4--></td></tr></table>
 | 
					<!--X1.1.4--></td></tr></table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!--X1.1.5--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
 | 
					<!--X1.1.6--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
 | 
				
			||||||
 | 
					<hr><h2>Receivers</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<center><i><b>Tapping into the stream...</b></i></center><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In order to receive any kind of data from a <tt>cDevice</tt>, a plugin must set up an
 | 
				
			||||||
 | 
					object derived from the <tt>cReceiver</tt> class:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
 | 
					#include <vdr/receiver.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class cMyReceiver : public cReceiver, cThread {
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual void Activate(bool On);
 | 
				
			||||||
 | 
					  virtual void Receive(uchar *Data, int Length);
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  cMyReceiver(int Pid);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cMyReceiver::cMyReceiver(int Pid)
 | 
				
			||||||
 | 
					:cReceiver(0, -1, 1, Pid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cMyReceiver::Activate(bool On)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // start your own thread for processing the received data
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cMyReceiver::Receive(uchar *Data, int Length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // buffer the data for processing in a separate thread
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the comments in <tt>VDR/receiver.h</tt> for details about the various
 | 
				
			||||||
 | 
					member functions of <tt>cReceiver</tt>.
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					The above example sets up a receiver that wants to receive data from only one
 | 
				
			||||||
 | 
					PID (for example the Teletext PID). In order to not interfere with other recording
 | 
				
			||||||
 | 
					operations, it sets its priority to <tt>-1</tt> (any negative value will allow
 | 
				
			||||||
 | 
					a <tt>cReceiver</tt> to be detached from its <tt>cDevice</tt> at any time.
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					Once a <tt>cReceiver</tt> has been created, it needs to be <i>attached</i> to
 | 
				
			||||||
 | 
					a <tt>cDevice</tt>:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
 | 
					cMyReceiver *Receiver = new cMyReceiver(123);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cDevice::PrimaryDevice()->AttachReceiver(Receiver);
 | 
				
			||||||
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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.1.6--></td></tr></table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!--X1.1.5--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
 | 
				
			||||||
<hr><h2>The On Screen Display</h2>
 | 
					<hr><h2>The On Screen Display</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<center><i><b>Express yourself</b></i></center><p>
 | 
					<center><i><b>Express yourself</b></i></center><p>
 | 
				
			||||||
@@ -1108,5 +1152,122 @@ of these functions, and VDR/osd.c to see how VDR opens the OSD and sets up
 | 
				
			|||||||
its windows and color depths).
 | 
					its windows and color depths).
 | 
				
			||||||
<!--X1.1.5--></td></tr></table>
 | 
					<!--X1.1.5--></td></tr></table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!--X1.1.6--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
 | 
				
			||||||
 | 
					<hr><h2>Devices</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<center><i><b>Expanding the possibilities</b></i></center><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					By default VDR is based on using DVB PCI cards that are supported by the
 | 
				
			||||||
 | 
					LinuxDVB driver. However, a plugin can implement additional devices that
 | 
				
			||||||
 | 
					can be used as sources of MPEG data for viewing or recording, and also
 | 
				
			||||||
 | 
					as output devices for replaying. Such a device can be a physical card
 | 
				
			||||||
 | 
					that is installed in the PC (like, for instance, an MPEG encoder card that
 | 
				
			||||||
 | 
					allows the analog signal of a proprietary set-top box to be integrated
 | 
				
			||||||
 | 
					into a VDR system; or an analog TV receiver card, which does the MPEG encoding
 | 
				
			||||||
 | 
					"on the fly" - assuming your machine is fast enough), or just a software program that takes an MPEG data
 | 
				
			||||||
 | 
					stream and displays it, for instance, on an existing graphics adapter.
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					To implement an additional device, a plugin must derive a class from cDevice:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
 | 
					#include <vdr/device.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class cMyDevice : public cDevice {
 | 
				
			||||||
 | 
					  ...
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The derived class must implement several virtual functions, according to
 | 
				
			||||||
 | 
					the abilities this new class of devices can provide. See the comments in the
 | 
				
			||||||
 | 
					file <tt>VDR/device.h</tt> for more information on the various functions,
 | 
				
			||||||
 | 
					and also <tt>VDR/dvbdevice.[hc]</tt> for details on the implementation of
 | 
				
			||||||
 | 
					the <tt>cDvbDevice</tt>, which is used to access the DVB PCI cards.
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					<b>Channel selection</b>
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					If the new device can receive, it most likely needs to provide a way of
 | 
				
			||||||
 | 
					selecting which channel it shall tune to:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
 | 
					virtual bool SetChannelDevice(const cChannel *Channel);
 | 
				
			||||||
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This function will be called with the desired channel and shall return whether
 | 
				
			||||||
 | 
					tuning to it was successful.
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					<b>Recording</b>
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					A device that can be used for recording must implement the functions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
 | 
					virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
 | 
				
			||||||
 | 
					virtual bool OpenDvr(void);
 | 
				
			||||||
 | 
					virtual void CloseDvr(void);
 | 
				
			||||||
 | 
					virtual int GetTSPacket(uchar *Data);
 | 
				
			||||||
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					which allow VDR to set the PIDs that shall be recorded, set up the device fro
 | 
				
			||||||
 | 
					recording (and shut it down again), and receive the MPEG data stream. The data
 | 
				
			||||||
 | 
					must be delivered in the form of a Transport Stream (TS), which consists of
 | 
				
			||||||
 | 
					packets that are all 188 bytes in size. Each call to <tt>GetTSPacket()</tt>
 | 
				
			||||||
 | 
					must deliver exactly one such packet (if one is currently available).
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					If this device allows receiving several different data streams, it can
 | 
				
			||||||
 | 
					implement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
 | 
					virtual bool CanBeReUsed(int Frequency, int Vpid);
 | 
				
			||||||
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					to indicate this to VDR.
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					<b>Replaying</b>
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					The functions to implement replaying capabilites are
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
 | 
					virtual bool HasDecoder(void) const;
 | 
				
			||||||
 | 
					virtual int SetPlayMode(bool On);
 | 
				
			||||||
 | 
					virtual void TrickSpeed(int Speed);
 | 
				
			||||||
 | 
					virtual void Clear(void);
 | 
				
			||||||
 | 
					virtual void Play(void);
 | 
				
			||||||
 | 
					virtual void Freeze(void);
 | 
				
			||||||
 | 
					virtual void Mute(void);
 | 
				
			||||||
 | 
					virtual void StillPicture(const uchar *Data, int Length);
 | 
				
			||||||
 | 
					virtual int PlayVideo(const uchar *Data, int Length);
 | 
				
			||||||
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In addition, the following functions may be implemented to provide further
 | 
				
			||||||
 | 
					functionality:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
 | 
					virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int Si
 | 
				
			||||||
 | 
					virtual void SetVideoFormat(bool VideoFormat16_9);
 | 
				
			||||||
 | 
					virtual void SetVolumeDevice(int Volume);
 | 
				
			||||||
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<b>Initializing new devices</b>
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					A derived cDevice class shall implement a static function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><table><tr><td bgcolor=#F0F0F0><pre><br>
 | 
				
			||||||
 | 
					static bool Initialize(void);
 | 
				
			||||||
 | 
					</pre></td></tr></table><p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					in which it determines whether the necessary hardware to run this sort of
 | 
				
			||||||
 | 
					device is actually present in this machine (or whatever other prerequisites
 | 
				
			||||||
 | 
					might be important), and then creates as many device objects as necessary.
 | 
				
			||||||
 | 
					See <tt>VDR/dvbdevice.c</tt> for the implementation of the <tt>cDvbDevice</tt>
 | 
				
			||||||
 | 
					initialize function.
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					A plugin that adds devices to a VDR instance shall call this initializing
 | 
				
			||||||
 | 
					function from its <a href="#Getting started"><tt>Start()</tt></a> function.
 | 
				
			||||||
 | 
					<p>
 | 
				
			||||||
 | 
					Nothing needs to be done to shut down the devices. VDR will automatically
 | 
				
			||||||
 | 
					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.6--></td></tr></table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,3 +18,7 @@ VDR Plugin 'hello' Revision History
 | 
				
			|||||||
2002-05-17: Version 0.0.4
 | 
					2002-05-17: Version 0.0.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Makefile improvements.
 | 
					- Makefile improvements.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2002-08-04: Version 0.0.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Added a missing #include.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,15 +3,16 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * See the README file for copyright information and how to reach the author.
 | 
					 * See the README file for copyright information and how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: hello.c 1.5 2002/05/14 21:23:25 kls Exp $
 | 
					 * $Id: hello.c 1.6 2002/08/04 15:13:35 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <getopt.h>
 | 
					#include <getopt.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <vdr/interface.h>
 | 
					#include <vdr/interface.h>
 | 
				
			||||||
#include <vdr/plugin.h>
 | 
					#include <vdr/plugin.h>
 | 
				
			||||||
#include "i18n.h"
 | 
					#include "i18n.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *VERSION        = "0.0.4";
 | 
					static const char *VERSION        = "0.0.5";
 | 
				
			||||||
static const char *DESCRIPTION    = "A friendly greeting";
 | 
					static const char *DESCRIPTION    = "A friendly greeting";
 | 
				
			||||||
static const char *MAINMENUENTRY  = "Hello";
 | 
					static const char *MAINMENUENTRY  = "Hello";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ BR3:11837:h:0:27500:201:202:204:0:28107
 | 
				
			|||||||
Hessen-3:11837:h:0:27500:301:302:304:0:28108
 | 
					Hessen-3:11837:h:0:27500:301:302:304:0:28108
 | 
				
			||||||
N3:12110:h:0:27500:2401:2402:2404:0:28224
 | 
					N3:12110:h:0:27500:2401:2402:2404:0:28224
 | 
				
			||||||
SR3:11837:h:0:27500:501:502:504:0:28110
 | 
					SR3:11837:h:0:27500:501:502:504:0:28110
 | 
				
			||||||
WDR:11837:h:0:27500:601:602:0:0:28111
 | 
					WDR:11837:h:0:27500:601:602:604:0:28111
 | 
				
			||||||
BR-alpha:11837:h:0:27500:701:702:704:0:28112
 | 
					BR-alpha:11837:h:0:27500:701:702:704:0:28112
 | 
				
			||||||
SWR BW:11837:h:0:27500:801:802:804:0:28113
 | 
					SWR BW:11837:h:0:27500:801:802:804:0:28113
 | 
				
			||||||
Phoenix:11837:h:0:27500:901:902:904:0:28114
 | 
					Phoenix:11837:h:0:27500:901:902:904:0:28114
 | 
				
			||||||
@@ -24,7 +24,7 @@ Super RTL:12188:h:0:27500:165:120:65:0:12040
 | 
				
			|||||||
VOX:12188:h:0:27500:167:136:0:0:12060
 | 
					VOX:12188:h:0:27500:167:136:0:0:12060
 | 
				
			||||||
DW TV:10788:v:0:22000:305:306:0:0:8905
 | 
					DW TV:10788:v:0:22000:305:306:0:0:8905
 | 
				
			||||||
Kabel 1:12480:v:0:27500:511:512:33:0:899
 | 
					Kabel 1:12480:v:0:27500:511:512:33:0:899
 | 
				
			||||||
Neun Live:12480:v:0:27500:767:768:0:0:897
 | 
					Neun Live:12480:v:0:27500:767:768:35:0:897
 | 
				
			||||||
DSF:12480:v:0:27500:1023:1024:0:0:900
 | 
					DSF:12480:v:0:27500:1023:1024:0:0:900
 | 
				
			||||||
HOT:12480:v:0:27500:1279:1280:0:0:40
 | 
					HOT:12480:v:0:27500:1279:1280:0:0:40
 | 
				
			||||||
Bloomberg TV Germany:12551:v:0:22000:162:99:0:0:12160
 | 
					Bloomberg TV Germany:12551:v:0:22000:162:99:0:0:12160
 | 
				
			||||||
@@ -111,7 +111,7 @@ BuLi 7:11719:h:0:27500:3327:3328,3329:0:101:245
 | 
				
			|||||||
BuLi 8:12031:h:0:27500:3071:3072,3073:0:101:208
 | 
					BuLi 8:12031:h:0:27500:3071:3072,3073:0:101:208
 | 
				
			||||||
BuLi 9:12031:h:0:27500:3327:3328,3329:0:101:209
 | 
					BuLi 9:12031:h:0:27500:3327:3328,3329:0:101:209
 | 
				
			||||||
:
 | 
					:
 | 
				
			||||||
TV Niepokalanow:11876:h:0:27500:305:321:0:0:20601
 | 
					:#TV Niepokalanow:11876:h:0:27500:305:321:0:0:20601
 | 
				
			||||||
Mosaico:11934:v:0:27500:165:100:0:0:29010
 | 
					Mosaico:11934:v:0:27500:165:100:0:0:29010
 | 
				
			||||||
Andalucia TV:11934:v:0:27500:166:104:0:0:29011
 | 
					Andalucia TV:11934:v:0:27500:166:104:0:0:29011
 | 
				
			||||||
TVC Internacional:11934:v:0:27500:167:108:0:0:0
 | 
					TVC Internacional:11934:v:0:27500:167:108:0:0:0
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								config.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: config.c 1.102 2002/06/16 12:57:31 kls Exp $
 | 
					 * $Id: config.c 1.103 2002/08/04 12:03:11 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
@@ -301,7 +301,7 @@ bool cChannel::Switch(cDevice *Device, bool Log)
 | 
				
			|||||||
     if (Log)
 | 
					     if (Log)
 | 
				
			||||||
        isyslog("switching to channel %d", number);
 | 
					        isyslog("switching to channel %d", number);
 | 
				
			||||||
     for (int i = 3; i--;) {
 | 
					     for (int i = 3; i--;) {
 | 
				
			||||||
         switch (Device->SetChannel(number, frequency, polarization, diseqc, srate, vpid, apid1, tpid, ca, pnr)) {
 | 
					         switch (Device->SetChannel(this)) {
 | 
				
			||||||
           case scrOk:         return true;
 | 
					           case scrOk:         return true;
 | 
				
			||||||
           case scrNoTransfer: if (Interface)
 | 
					           case scrNoTransfer: if (Interface)
 | 
				
			||||||
                                  Interface->Error(tr("Can't start Transfer Mode!"));
 | 
					                                  Interface->Error(tr("Can't start Transfer Mode!"));
 | 
				
			||||||
@@ -1018,7 +1018,7 @@ cSetup::cSetup(void)
 | 
				
			|||||||
  DefaultLifetime = 50;
 | 
					  DefaultLifetime = 50;
 | 
				
			||||||
  UseSubtitle = 1;
 | 
					  UseSubtitle = 1;
 | 
				
			||||||
  RecordingDirs = 1;
 | 
					  RecordingDirs = 1;
 | 
				
			||||||
  VideoFormat = VIDEO_FORMAT_4_3;
 | 
					  VideoFormat = 0;
 | 
				
			||||||
  RecordDolbyDigital = 1;
 | 
					  RecordDolbyDigital = 1;
 | 
				
			||||||
  ChannelInfoPos = 0;
 | 
					  ChannelInfoPos = 0;
 | 
				
			||||||
  OSDwidth = 52;
 | 
					  OSDwidth = 52;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								config.h
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: config.h 1.120 2002/07/13 09:46:59 kls Exp $
 | 
					 * $Id: config.h 1.121 2002/07/27 12:00:30 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __CONFIG_H
 | 
					#ifndef __CONFIG_H
 | 
				
			||||||
@@ -19,7 +19,7 @@
 | 
				
			|||||||
#include "eit.h"
 | 
					#include "eit.h"
 | 
				
			||||||
#include "tools.h"
 | 
					#include "tools.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VDRVERSION "1.1.5"
 | 
					#define VDRVERSION "1.1.6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAXPRIORITY 99
 | 
					#define MAXPRIORITY 99
 | 
				
			||||||
#define MAXLIFETIME 99
 | 
					#define MAXLIFETIME 99
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										697
									
								
								device.c
									
									
									
									
									
								
							
							
						
						
									
										697
									
								
								device.c
									
									
									
									
									
								
							@@ -4,108 +4,42 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: device.c 1.5 2002/06/23 12:51:24 kls Exp $
 | 
					 * $Id: device.c 1.8 2002/08/04 15:18:05 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "device.h"
 | 
					#include "device.h"
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
extern "C" {
 | 
					 | 
				
			||||||
#define HAVE_BOOLEAN
 | 
					 | 
				
			||||||
#include <jpeglib.h>
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#include <linux/videodev.h>
 | 
					 | 
				
			||||||
#include <ost/sec.h>
 | 
					 | 
				
			||||||
#include <poll.h>
 | 
					#include <poll.h>
 | 
				
			||||||
#include <sys/ioctl.h>
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
#include <sys/mman.h>
 | 
					#include <sys/mman.h>
 | 
				
			||||||
 | 
					#include "eit.h"
 | 
				
			||||||
#include "player.h"
 | 
					#include "player.h"
 | 
				
			||||||
#include "receiver.h"
 | 
					#include "receiver.h"
 | 
				
			||||||
#include "status.h"
 | 
					#include "status.h"
 | 
				
			||||||
#include "transfer.h"
 | 
					#include "transfer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEV_VIDEO         "/dev/video"
 | 
					// The default priority for non-primary devices:
 | 
				
			||||||
#define DEV_OST_OSD       "/dev/ost/osd"
 | 
					 | 
				
			||||||
#define DEV_OST_FRONTEND  "/dev/ost/frontend"
 | 
					 | 
				
			||||||
#define DEV_OST_SEC       "/dev/ost/sec"
 | 
					 | 
				
			||||||
#define DEV_OST_DVR       "/dev/ost/dvr"
 | 
					 | 
				
			||||||
#define DEV_OST_DEMUX     "/dev/ost/demux"
 | 
					 | 
				
			||||||
#define DEV_OST_VIDEO     "/dev/ost/video"
 | 
					 | 
				
			||||||
#define DEV_OST_AUDIO     "/dev/ost/audio"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// The default priority for non-primary DVB cards:
 | 
					 | 
				
			||||||
#define DEFAULTPRIORITY  -2
 | 
					#define DEFAULTPRIORITY  -2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TS_SIZE          188
 | 
					 | 
				
			||||||
#define TS_SYNC_BYTE     0x47
 | 
					 | 
				
			||||||
#define PID_MASK_HI      0x1F
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// The maximum time we wait before assuming that a recorded video data stream
 | 
					// The maximum time we wait before assuming that a recorded video data stream
 | 
				
			||||||
// is broken:
 | 
					// is broken:
 | 
				
			||||||
#define MAXBROKENTIMEOUT 30 // seconds
 | 
					#define MAXBROKENTIMEOUT 30 // seconds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *OstName(const char *Name, int n)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  static char buffer[_POSIX_PATH_MAX];
 | 
					 | 
				
			||||||
  snprintf(buffer, sizeof(buffer), "%s%d", Name, n);
 | 
					 | 
				
			||||||
  return buffer;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int OstOpen(const char *Name, int n, int Mode, bool ReportError = false)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  const char *FileName = OstName(Name, n);
 | 
					 | 
				
			||||||
  int fd = open(FileName, Mode);
 | 
					 | 
				
			||||||
  if (fd < 0 && ReportError)
 | 
					 | 
				
			||||||
     LOG_ERROR_STR(FileName);
 | 
					 | 
				
			||||||
  return fd;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int cDevice::numDevices = 0;
 | 
					int cDevice::numDevices = 0;
 | 
				
			||||||
int cDevice::useDevice = 0;
 | 
					int cDevice::useDevice = 0;
 | 
				
			||||||
 | 
					int cDevice::nextCardIndex = 0;
 | 
				
			||||||
cDevice *cDevice::device[MAXDEVICES] = { NULL };
 | 
					cDevice *cDevice::device[MAXDEVICES] = { NULL };
 | 
				
			||||||
cDevice *cDevice::primaryDevice = NULL;
 | 
					cDevice *cDevice::primaryDevice = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cDevice::cDevice(int n)
 | 
					cDevice::cDevice(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  frontendType = FrontendType(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
 | 
					  cardIndex = nextCardIndex++;
 | 
				
			||||||
  siProcessor = NULL;
 | 
					 | 
				
			||||||
  cardIndex = n;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Devices that are present on all card types:
 | 
					  SetVideoFormat(Setup.VideoFormat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fd_frontend = OstOpen(DEV_OST_FRONTEND, n, O_RDWR);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Devices that are only present on DVB-S cards:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fd_sec      = OstOpen(DEV_OST_SEC,      n, O_RDWR);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Devices that are only present on cards with decoders:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fd_osd      = OstOpen(DEV_OST_OSD,    n, O_RDWR);
 | 
					 | 
				
			||||||
  fd_video    = OstOpen(DEV_OST_VIDEO,  n, O_RDWR | O_NONBLOCK);
 | 
					 | 
				
			||||||
  fd_audio    = OstOpen(DEV_OST_AUDIO,  n, O_RDWR | O_NONBLOCK);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Video format:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  SetVideoFormat(Setup.VideoFormat ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // We only check the devices that must be present - the others will be checked before accessing them://XXX
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (fd_frontend >= 0) {
 | 
					 | 
				
			||||||
     siProcessor = new cSIProcessor(OstName(DEV_OST_DEMUX, n));
 | 
					 | 
				
			||||||
     FrontendInfo feinfo;
 | 
					 | 
				
			||||||
     if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0)
 | 
					 | 
				
			||||||
        frontendType = feinfo.type;
 | 
					 | 
				
			||||||
     else
 | 
					 | 
				
			||||||
        LOG_ERROR;
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
     esyslog("ERROR: can't open video device %d", n);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  dvrFileName = strdup(OstName(DEV_OST_DVR, CardIndex()));
 | 
					 | 
				
			||||||
  active = false;
 | 
					  active = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  currentChannel = 0;
 | 
					  currentChannel = 0;
 | 
				
			||||||
  frequency = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mute = false;
 | 
					  mute = false;
 | 
				
			||||||
  volume = Setup.CurrentVolume;
 | 
					  volume = Setup.CurrentVolume;
 | 
				
			||||||
@@ -115,17 +49,20 @@ cDevice::cDevice(int n)
 | 
				
			|||||||
  for (int i = 0; i < MAXRECEIVERS; i++)
 | 
					  for (int i = 0; i < MAXRECEIVERS; i++)
 | 
				
			||||||
      receiver[i] = NULL;
 | 
					      receiver[i] = NULL;
 | 
				
			||||||
  ca = -1;
 | 
					  ca = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (numDevices < MAXDEVICES) {
 | 
				
			||||||
 | 
					     device[numDevices++] = this;
 | 
				
			||||||
 | 
					     SetCaCaps(cardIndex);
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					     esyslog("ERROR: too many devices!");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cDevice::~cDevice()
 | 
					cDevice::~cDevice()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  delete dvrFileName;
 | 
					 | 
				
			||||||
  delete siProcessor;
 | 
					 | 
				
			||||||
  Detach(player);
 | 
					  Detach(player);
 | 
				
			||||||
  for (int i = 0; i < MAXRECEIVERS; i++)
 | 
					  for (int i = 0; i < MAXRECEIVERS; i++)
 | 
				
			||||||
      Detach(receiver[i]);
 | 
					      Detach(receiver[i]);
 | 
				
			||||||
  // We're not explicitly closing any device files here, since this sometimes
 | 
					 | 
				
			||||||
  // caused segfaults. Besides, the program is about to terminate anyway...
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::SetUseDevice(int n)
 | 
					void cDevice::SetUseDevice(int n)
 | 
				
			||||||
@@ -134,15 +71,44 @@ void cDevice::SetUseDevice(int n)
 | 
				
			|||||||
     useDevice |= (1 << n);
 | 
					     useDevice |= (1 << n);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cDevice::NextCardIndex(int n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (n > 0) {
 | 
				
			||||||
 | 
					     nextCardIndex += n;
 | 
				
			||||||
 | 
					     if (nextCardIndex >= MAXDEVICES)
 | 
				
			||||||
 | 
					        esyslog("ERROR: nextCardIndex too big (%d)", nextCardIndex);
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  else if (n < 0)
 | 
				
			||||||
 | 
					     esyslog("ERROR: illegal value in IncCardIndex(%d)", n);
 | 
				
			||||||
 | 
					  return nextCardIndex;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDevice::MakePrimaryDevice(bool On)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool cDevice::SetPrimaryDevice(int n)
 | 
					bool cDevice::SetPrimaryDevice(int n)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  n--;
 | 
					  n--;
 | 
				
			||||||
  if (0 <= n && n < numDevices && device[n]) {
 | 
					  if (0 <= n && n < numDevices && device[n]) {
 | 
				
			||||||
     isyslog("setting primary device to %d", n + 1);
 | 
					     isyslog("setting primary device to %d", n + 1);
 | 
				
			||||||
 | 
					     if (primaryDevice)
 | 
				
			||||||
 | 
					        primaryDevice->MakePrimaryDevice(false);
 | 
				
			||||||
     primaryDevice = device[n];
 | 
					     primaryDevice = device[n];
 | 
				
			||||||
 | 
					     primaryDevice->MakePrimaryDevice(true);
 | 
				
			||||||
     return true;
 | 
					     return true;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
  esyslog("invalid devive number: %d", n + 1);
 | 
					  esyslog("invalid device number: %d", n + 1);
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDevice::CanBeReUsed(int Frequency, int Vpid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDevice::HasDecoder(void) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
  return false;
 | 
					  return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -156,20 +122,7 @@ cDevice *cDevice::GetDevice(int Ca, int Priority, int Frequency, int Vpid, bool
 | 
				
			|||||||
  for (int i = 0; i < numDevices; i++) {
 | 
					  for (int i = 0; i < numDevices; i++) {
 | 
				
			||||||
      if ((Provides[i] = device[i]->ProvidesCa(Ca)) != 0) { // this device is basicly able to do the job
 | 
					      if ((Provides[i] = device[i]->ProvidesCa(Ca)) != 0) { // this device is basicly able to do the job
 | 
				
			||||||
         //XXX+ dsyslog("GetDevice: %d %d %d %5d %5d", i, device[i]->HasDecoder(), device[i]->Receiving(), Frequency, device[i]->frequency);//XXX
 | 
					         //XXX+ dsyslog("GetDevice: %d %d %d %5d %5d", i, device[i]->HasDecoder(), device[i]->Receiving(), Frequency, device[i]->frequency);//XXX
 | 
				
			||||||
         if (  (!device[i]->HasDecoder() // it's a "budget card" which can receive multiple channels...
 | 
					         if (device[i]->CanBeReUsed(Frequency, Vpid)) {
 | 
				
			||||||
               && device[i]->frequency == Frequency // ...and it is tuned to the requested frequency...
 | 
					 | 
				
			||||||
               && device[i]->Receiving() // ...and is already receiving
 | 
					 | 
				
			||||||
               // need not check priority - if a budget card is already receiving on the requested
 | 
					 | 
				
			||||||
               // frequency, we can attach another receiver regardless of priority
 | 
					 | 
				
			||||||
               )
 | 
					 | 
				
			||||||
            || (device[i]->HasDecoder() // it's a "full featured card" which can receive only one channel...
 | 
					 | 
				
			||||||
               && device[i]->frequency == Frequency // ...and it is tuned to the requested frequency...
 | 
					 | 
				
			||||||
               && device[i]->pidHandles[ptVideo].pid == Vpid // ...and the requested video PID...
 | 
					 | 
				
			||||||
               && device[i]->Receiving() // ...and is already receiving
 | 
					 | 
				
			||||||
               // need not check priority - if a full featured card is already receiving the requested
 | 
					 | 
				
			||||||
               // frequency and video PID, we can attach another receiver regardless of priority
 | 
					 | 
				
			||||||
               )
 | 
					 | 
				
			||||||
            ) {
 | 
					 | 
				
			||||||
            d = device[i];
 | 
					            d = device[i];
 | 
				
			||||||
            if (ReUse)
 | 
					            if (ReUse)
 | 
				
			||||||
               *ReUse = true;
 | 
					               *ReUse = true;
 | 
				
			||||||
@@ -204,50 +157,14 @@ cDevice *cDevice::GetDevice(int Ca, int Priority, int Frequency, int Vpid, bool
 | 
				
			|||||||
  return d;
 | 
					  return d;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::SetCaCaps(void)
 | 
					void cDevice::SetCaCaps(int Index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  for (int d = 0; d < numDevices; d++) {
 | 
					  for (int d = 0; d < numDevices; d++) {
 | 
				
			||||||
      for (int i = 0; i < MAXCACAPS; i++)
 | 
					      if (Index < 0 || Index == device[d]->CardIndex()) {
 | 
				
			||||||
          device[d]->caCaps[i] = Setup.CaCaps[device[d]->CardIndex()][i];
 | 
					         for (int i = 0; i < MAXCACAPS; i++)
 | 
				
			||||||
      }
 | 
					             device[d]->caCaps[i] = Setup.CaCaps[device[d]->CardIndex()][i];
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool cDevice::Probe(const char *FileName)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (access(FileName, F_OK) == 0) {
 | 
					 | 
				
			||||||
     dsyslog("probing %s", FileName);
 | 
					 | 
				
			||||||
     int f = open(FileName, O_RDONLY);
 | 
					 | 
				
			||||||
     if (f >= 0) {
 | 
					 | 
				
			||||||
        close(f);
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
     else if (errno != ENODEV && errno != EINVAL)
 | 
					 | 
				
			||||||
        LOG_ERROR_STR(FileName);
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
  else if (errno != ENOENT)
 | 
					 | 
				
			||||||
     LOG_ERROR_STR(FileName);
 | 
					 | 
				
			||||||
  return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool cDevice::Initialize(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  numDevices = 0;
 | 
					 | 
				
			||||||
  for (int i = 0; i < MAXDEVICES; i++) {
 | 
					 | 
				
			||||||
      if (useDevice == 0 || (useDevice & (1 << i)) != 0) {
 | 
					 | 
				
			||||||
         if (Probe(OstName(DEV_OST_FRONTEND, i)))
 | 
					 | 
				
			||||||
            device[numDevices++] = new cDevice(i);
 | 
					 | 
				
			||||||
         else
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
  primaryDevice = device[0];
 | 
					 | 
				
			||||||
  if (numDevices > 0) {
 | 
					 | 
				
			||||||
     isyslog("found %d video device%s", numDevices, numDevices > 1 ? "s" : "");
 | 
					 | 
				
			||||||
     SetCaCaps();
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
     esyslog("ERROR: no video device found, giving up!");
 | 
					 | 
				
			||||||
  return numDevices > 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::Shutdown(void)
 | 
					void cDevice::Shutdown(void)
 | 
				
			||||||
@@ -261,106 +178,13 @@ void cDevice::Shutdown(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
bool cDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
 | 
					bool cDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int videoDev = OstOpen(DEV_VIDEO, CardIndex(), O_RDWR, true);
 | 
					 | 
				
			||||||
  if (videoDev >= 0) {
 | 
					 | 
				
			||||||
     int result = 0;
 | 
					 | 
				
			||||||
     struct video_mbuf mbuf;
 | 
					 | 
				
			||||||
     result |= ioctl(videoDev, VIDIOCGMBUF, &mbuf);
 | 
					 | 
				
			||||||
     if (result == 0) {
 | 
					 | 
				
			||||||
        int msize = mbuf.size;
 | 
					 | 
				
			||||||
        unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
 | 
					 | 
				
			||||||
        if (mem && mem != (unsigned char *)-1) {
 | 
					 | 
				
			||||||
           // set up the size and RGB
 | 
					 | 
				
			||||||
           struct video_capability vc;
 | 
					 | 
				
			||||||
           result |= ioctl(videoDev, VIDIOCGCAP, &vc);
 | 
					 | 
				
			||||||
           struct video_mmap vm;
 | 
					 | 
				
			||||||
           vm.frame = 0;
 | 
					 | 
				
			||||||
           if ((SizeX > 0) && (SizeX <= vc.maxwidth) &&
 | 
					 | 
				
			||||||
               (SizeY > 0) && (SizeY <= vc.maxheight)) {
 | 
					 | 
				
			||||||
              vm.width = SizeX;
 | 
					 | 
				
			||||||
              vm.height = SizeY;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
           else {
 | 
					 | 
				
			||||||
              vm.width = vc.maxwidth;
 | 
					 | 
				
			||||||
              vm.height = vc.maxheight;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
           vm.format = VIDEO_PALETTE_RGB24;
 | 
					 | 
				
			||||||
           result |= ioctl(videoDev, VIDIOCMCAPTURE, &vm);
 | 
					 | 
				
			||||||
           result |= ioctl(videoDev, VIDIOCSYNC, &vm.frame);
 | 
					 | 
				
			||||||
           // make RGB out of BGR:
 | 
					 | 
				
			||||||
           int memsize = vm.width * vm.height;
 | 
					 | 
				
			||||||
           unsigned char *mem1 = mem;
 | 
					 | 
				
			||||||
           for (int i = 0; i < memsize; i++) {
 | 
					 | 
				
			||||||
               unsigned char tmp = mem1[2];
 | 
					 | 
				
			||||||
               mem1[2] = mem1[0];
 | 
					 | 
				
			||||||
               mem1[0] = tmp;
 | 
					 | 
				
			||||||
               mem1 += 3;
 | 
					 | 
				
			||||||
               }
 | 
					 | 
				
			||||||
         
 | 
					 | 
				
			||||||
           if (Quality < 0)
 | 
					 | 
				
			||||||
              Quality = 255; //XXX is this 'best'???
 | 
					 | 
				
			||||||
         
 | 
					 | 
				
			||||||
           isyslog("grabbing to %s (%s %d %d %d)", FileName, Jpeg ? "JPEG" : "PNM", Quality, vm.width, vm.height);
 | 
					 | 
				
			||||||
           FILE *f = fopen(FileName, "wb");
 | 
					 | 
				
			||||||
           if (f) {
 | 
					 | 
				
			||||||
              if (Jpeg) {
 | 
					 | 
				
			||||||
                 // write JPEG file:
 | 
					 | 
				
			||||||
                 struct jpeg_compress_struct cinfo;
 | 
					 | 
				
			||||||
                 struct jpeg_error_mgr jerr;
 | 
					 | 
				
			||||||
                 cinfo.err = jpeg_std_error(&jerr);
 | 
					 | 
				
			||||||
                 jpeg_create_compress(&cinfo);
 | 
					 | 
				
			||||||
                 jpeg_stdio_dest(&cinfo, f);
 | 
					 | 
				
			||||||
                 cinfo.image_width = vm.width;
 | 
					 | 
				
			||||||
                 cinfo.image_height = vm.height;
 | 
					 | 
				
			||||||
                 cinfo.input_components = 3;
 | 
					 | 
				
			||||||
                 cinfo.in_color_space = JCS_RGB;
 | 
					 | 
				
			||||||
         
 | 
					 | 
				
			||||||
                 jpeg_set_defaults(&cinfo);
 | 
					 | 
				
			||||||
                 jpeg_set_quality(&cinfo, Quality, true);
 | 
					 | 
				
			||||||
                 jpeg_start_compress(&cinfo, true);
 | 
					 | 
				
			||||||
         
 | 
					 | 
				
			||||||
                 int rs = vm.width * 3;
 | 
					 | 
				
			||||||
                 JSAMPROW rp[vm.height];
 | 
					 | 
				
			||||||
                 for (int k = 0; k < vm.height; k++)
 | 
					 | 
				
			||||||
                     rp[k] = &mem[rs * k];
 | 
					 | 
				
			||||||
                 jpeg_write_scanlines(&cinfo, rp, vm.height);
 | 
					 | 
				
			||||||
                 jpeg_finish_compress(&cinfo);
 | 
					 | 
				
			||||||
                 jpeg_destroy_compress(&cinfo);
 | 
					 | 
				
			||||||
                 }
 | 
					 | 
				
			||||||
              else {
 | 
					 | 
				
			||||||
                 // write PNM file:
 | 
					 | 
				
			||||||
                 if (fprintf(f, "P6\n%d\n%d\n255\n", vm.width, vm.height) < 0 ||
 | 
					 | 
				
			||||||
                     fwrite(mem, vm.width * vm.height * 3, 1, f) < 0) {
 | 
					 | 
				
			||||||
                    LOG_ERROR_STR(FileName);
 | 
					 | 
				
			||||||
                    result |= 1;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                 }
 | 
					 | 
				
			||||||
              fclose(f);
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
           else {
 | 
					 | 
				
			||||||
              LOG_ERROR_STR(FileName);
 | 
					 | 
				
			||||||
              result |= 1;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
           munmap(mem, msize);
 | 
					 | 
				
			||||||
           }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
           result |= 1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
     close(videoDev);
 | 
					 | 
				
			||||||
     return result == 0;
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
  return false;
 | 
					  return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::SetVideoFormat(videoFormat_t Format)
 | 
					void cDevice::SetVideoFormat(bool VideoFormat16_9)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (HasDecoder())
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_SET_FORMAT, Format));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//                          ptVideo        ptAudio        ptTeletext        ptDolby        ptOther
 | 
					 | 
				
			||||||
dmxPesType_t PesTypes[] = { DMX_PES_VIDEO, DMX_PES_AUDIO, DMX_PES_TELETEXT, DMX_PES_OTHER, DMX_PES_OTHER };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//#define PRINTPIDS(s) { char b[500]; char *q = b; q += sprintf(q, "%d %s ", CardIndex(), s); for (int i = 0; i < MAXPIDHANDLES; i++) q += sprintf(q, " %s%4d %d", i == ptOther ? "* " : "", pidHandles[i].pid, pidHandles[i].used); dsyslog(b); } //XXX+
 | 
					//#define PRINTPIDS(s) { char b[500]; char *q = b; q += sprintf(q, "%d %s ", CardIndex(), s); for (int i = 0; i < MAXPIDHANDLES; i++) q += sprintf(q, " %s%4d %d", i == ptOther ? "* " : "", pidHandles[i].pid, pidHandles[i].used); dsyslog(b); } //XXX+
 | 
				
			||||||
#define PRINTPIDS(s)
 | 
					#define PRINTPIDS(s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -375,13 +199,12 @@ bool cDevice::AddPid(int Pid, ePidType PidType)
 | 
				
			|||||||
         else if (a < 0 && i >= ptOther && !pidHandles[i].used)
 | 
					         else if (a < 0 && i >= ptOther && !pidHandles[i].used)
 | 
				
			||||||
            a = i;
 | 
					            a = i;
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
     dmxPesType_t PesType = PesTypes[ptOther];
 | 
					 | 
				
			||||||
     if (n >= 0) {
 | 
					     if (n >= 0) {
 | 
				
			||||||
        // The Pid is already in use
 | 
					        // The Pid is already in use
 | 
				
			||||||
        if (++pidHandles[n].used == 2 && n <= ptTeletext) {
 | 
					        if (++pidHandles[n].used == 2 && n <= ptTeletext) {
 | 
				
			||||||
           // It's a special PID that has to be switched into "tap" mode
 | 
					           // It's a special PID that may have to be switched into "tap" mode
 | 
				
			||||||
           PRINTPIDS("A");//XXX+
 | 
					           PRINTPIDS("A");//XXX+
 | 
				
			||||||
           return SetPid(pidHandles[n].fd, PesTypes[n], Pid, DMX_OUT_TS_TAP);
 | 
					           return SetPid(&pidHandles[n], n, true);
 | 
				
			||||||
           }
 | 
					           }
 | 
				
			||||||
        PRINTPIDS("a");//XXX+
 | 
					        PRINTPIDS("a");//XXX+
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
@@ -389,8 +212,6 @@ bool cDevice::AddPid(int Pid, ePidType PidType)
 | 
				
			|||||||
     else if (PidType < ptOther) {
 | 
					     else if (PidType < ptOther) {
 | 
				
			||||||
        // The Pid is not yet in use and it is a special one
 | 
					        // The Pid is not yet in use and it is a special one
 | 
				
			||||||
        n = PidType;
 | 
					        n = PidType;
 | 
				
			||||||
        PesType = PesTypes[PidType];
 | 
					 | 
				
			||||||
        PRINTPIDS("B");//XXX+
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
     else if (a >= 0) {
 | 
					     else if (a >= 0) {
 | 
				
			||||||
        // The Pid is not yet in use and we have a free slot
 | 
					        // The Pid is not yet in use and we have a free slot
 | 
				
			||||||
@@ -400,217 +221,51 @@ bool cDevice::AddPid(int Pid, ePidType PidType)
 | 
				
			|||||||
        esyslog("ERROR: no free slot for PID %d", Pid);
 | 
					        esyslog("ERROR: no free slot for PID %d", Pid);
 | 
				
			||||||
     if (n >= 0) {
 | 
					     if (n >= 0) {
 | 
				
			||||||
        pidHandles[n].pid = Pid;
 | 
					        pidHandles[n].pid = Pid;
 | 
				
			||||||
        pidHandles[n].fd = OstOpen(DEV_OST_DEMUX, CardIndex(), O_RDWR | O_NONBLOCK, true);
 | 
					 | 
				
			||||||
        pidHandles[n].used = 1;
 | 
					        pidHandles[n].used = 1;
 | 
				
			||||||
        PRINTPIDS("C");//XXX+
 | 
					        PRINTPIDS("C");//XXX+
 | 
				
			||||||
        return SetPid(pidHandles[n].fd, PesType, Pid, PidType <= ptTeletext ? DMX_OUT_DECODER : DMX_OUT_TS_TAP);
 | 
					        return SetPid(&pidHandles[n], n, true);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
  return true;
 | 
					  return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool cDevice::DelPid(int Pid)
 | 
					void cDevice::DelPid(int Pid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (Pid) {
 | 
					  if (Pid) {
 | 
				
			||||||
     for (int i = 0; i < MAXPIDHANDLES; i++) {
 | 
					     for (int i = 0; i < MAXPIDHANDLES; i++) {
 | 
				
			||||||
         if (pidHandles[i].pid == Pid) {
 | 
					         if (pidHandles[i].pid == Pid) {
 | 
				
			||||||
            switch (--pidHandles[i].used) {
 | 
					            if (--pidHandles[i].used < 2) {
 | 
				
			||||||
              case 0: CHECK(ioctl(pidHandles[i].fd, DMX_STOP));//XXX+ is this necessary???
 | 
					               SetPid(&pidHandles[i], i, false);
 | 
				
			||||||
                      close(pidHandles[i].fd);
 | 
					               if (pidHandles[i].used == 0) {
 | 
				
			||||||
                      pidHandles[i].fd = -1;
 | 
					                   pidHandles[i].handle = -1;
 | 
				
			||||||
                      pidHandles[i].pid = 0;
 | 
					                   pidHandles[i].pid = 0;
 | 
				
			||||||
                      break;
 | 
					                   }
 | 
				
			||||||
              case 1: if (i <= ptTeletext)
 | 
					               }
 | 
				
			||||||
                         SetPid(pidHandles[i].fd, PesTypes[i], Pid, DMX_OUT_DECODER);
 | 
					 | 
				
			||||||
                      break;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            PRINTPIDS("D");//XXX+
 | 
					            PRINTPIDS("D");//XXX+
 | 
				
			||||||
            return pidHandles[i].used;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDevice::SetPid(cPidHandle *Handle, int Type, bool On)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
  return false;
 | 
					  return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool cDevice::SetPid(int fd, dmxPesType_t PesType, int Pid, dmxOutput_t Output)
 | 
					eSetChannelResult cDevice::SetChannel(const cChannel *Channel)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (Pid) {
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd, DMX_STOP));
 | 
					 | 
				
			||||||
     if (Pid != 0x1FFF) {
 | 
					 | 
				
			||||||
        dmxPesFilterParams pesFilterParams;
 | 
					 | 
				
			||||||
        pesFilterParams.pid     = Pid;
 | 
					 | 
				
			||||||
        pesFilterParams.input   = DMX_IN_FRONTEND;
 | 
					 | 
				
			||||||
        pesFilterParams.output  = Output;
 | 
					 | 
				
			||||||
        pesFilterParams.pesType = PesType;
 | 
					 | 
				
			||||||
        pesFilterParams.flags   = DMX_IMMEDIATE_START;
 | 
					 | 
				
			||||||
        //XXX+ pesFilterParams.flags   = DMX_CHECK_CRC;//XXX
 | 
					 | 
				
			||||||
        if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
 | 
					 | 
				
			||||||
           LOG_ERROR;
 | 
					 | 
				
			||||||
           return false;
 | 
					 | 
				
			||||||
           }
 | 
					 | 
				
			||||||
        //XXX+ CHECK(ioctl(fd, DMX_SET_BUFFER_SIZE, KILOBYTE(32)));//XXX
 | 
					 | 
				
			||||||
        //XXX+ CHECK(ioctl(fd, DMX_START));//XXX
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
  return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
eSetChannelResult cDevice::SetChannel(int ChannelNumber, int Frequency, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Tpid, int Ca, int Pnr)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  StopReplay();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  cStatus::MsgChannelSwitch(this, 0);
 | 
					  cStatus::MsgChannelSwitch(this, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  StopReplay();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Must set this anyway to avoid getting stuck when switching through
 | 
					  // Must set this anyway to avoid getting stuck when switching through
 | 
				
			||||||
  // channels with 'Up' and 'Down' keys:
 | 
					  // channels with 'Up' and 'Down' keys:
 | 
				
			||||||
  currentChannel = ChannelNumber;
 | 
					  currentChannel = Channel->number;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Avoid noise while switching:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (HasDecoder()) {
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Stop setting system time:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (siProcessor)
 | 
					 | 
				
			||||||
     siProcessor->SetCurrentTransponder(0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // If this card can't receive this channel, we must not actually switch
 | 
					  // If this card can't receive this channel, we must not actually switch
 | 
				
			||||||
  // the channel here, because that would irritate the driver when we
 | 
					  // the channel here, because that would irritate the driver when we
 | 
				
			||||||
  // start replaying in Transfer Mode immediately after switching the channel:
 | 
					  // start replaying in Transfer Mode immediately after switching the channel:
 | 
				
			||||||
  bool NeedsTransferMode = (IsPrimaryDevice() && !ProvidesCa(Ca));
 | 
					  bool NeedsTransferMode = (IsPrimaryDevice() && !ProvidesCa(Channel->ca));
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!NeedsTransferMode) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     // Turn off current PIDs:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     if (HasDecoder()) {
 | 
					 | 
				
			||||||
        DelPid(pidHandles[ptVideo].pid);
 | 
					 | 
				
			||||||
        DelPid(pidHandles[ptAudio].pid);
 | 
					 | 
				
			||||||
        DelPid(pidHandles[ptTeletext].pid);
 | 
					 | 
				
			||||||
        DelPid(pidHandles[ptDolby].pid);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     FrontendParameters Frontend;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     switch (frontendType) {
 | 
					 | 
				
			||||||
       case FE_QPSK: { // DVB-S
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Frequency offsets:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            unsigned int freq = Frequency;
 | 
					 | 
				
			||||||
            int tone = SEC_TONE_OFF;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (freq < (unsigned int)Setup.LnbSLOF) {
 | 
					 | 
				
			||||||
               freq -= Setup.LnbFrequLo;
 | 
					 | 
				
			||||||
               tone = SEC_TONE_OFF;
 | 
					 | 
				
			||||||
               }
 | 
					 | 
				
			||||||
            else {
 | 
					 | 
				
			||||||
               freq -= Setup.LnbFrequHi;
 | 
					 | 
				
			||||||
               tone = SEC_TONE_ON;
 | 
					 | 
				
			||||||
               }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Frontend.Frequency = freq * 1000UL;
 | 
					 | 
				
			||||||
            Frontend.Inversion = INVERSION_AUTO;
 | 
					 | 
				
			||||||
            Frontend.u.qpsk.SymbolRate = Srate * 1000UL;
 | 
					 | 
				
			||||||
            Frontend.u.qpsk.FEC_inner = FEC_AUTO;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            int volt = (Polarization == 'v' || Polarization == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // DiseqC:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            secCommand scmd;
 | 
					 | 
				
			||||||
            scmd.type = 0;
 | 
					 | 
				
			||||||
            scmd.u.diseqc.addr = 0x10;
 | 
					 | 
				
			||||||
            scmd.u.diseqc.cmd = 0x38;
 | 
					 | 
				
			||||||
            scmd.u.diseqc.numParams = 1;
 | 
					 | 
				
			||||||
            scmd.u.diseqc.params[0] = 0xF0 | ((Diseqc * 4) & 0x0F) | (tone == SEC_TONE_ON ? 1 : 0) | (volt == SEC_VOLTAGE_18 ? 2 : 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            secCmdSequence scmds;
 | 
					 | 
				
			||||||
            scmds.voltage = volt;
 | 
					 | 
				
			||||||
            scmds.miniCommand = SEC_MINI_NONE;
 | 
					 | 
				
			||||||
            scmds.continuousTone = tone;
 | 
					 | 
				
			||||||
            scmds.numCommands = Setup.DiSEqC ? 1 : 0;
 | 
					 | 
				
			||||||
            scmds.commands = &scmd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
       case FE_QAM: { // DVB-C
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Frequency and symbol rate:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Frontend.Frequency = Frequency * 1000000UL;
 | 
					 | 
				
			||||||
            Frontend.Inversion = INVERSION_AUTO;
 | 
					 | 
				
			||||||
            Frontend.u.qam.SymbolRate = Srate * 1000UL;
 | 
					 | 
				
			||||||
            Frontend.u.qam.FEC_inner = FEC_AUTO;
 | 
					 | 
				
			||||||
            Frontend.u.qam.QAM = QAM_64;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
       case FE_OFDM: { // DVB-T
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Frequency and OFDM paramaters:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Frontend.Frequency = Frequency * 1000UL;
 | 
					 | 
				
			||||||
            Frontend.Inversion = INVERSION_AUTO;
 | 
					 | 
				
			||||||
            Frontend.u.ofdm.bandWidth=BANDWIDTH_8_MHZ;
 | 
					 | 
				
			||||||
            Frontend.u.ofdm.HP_CodeRate=FEC_2_3;
 | 
					 | 
				
			||||||
            Frontend.u.ofdm.LP_CodeRate=FEC_1_2;
 | 
					 | 
				
			||||||
            Frontend.u.ofdm.Constellation=QAM_64;
 | 
					 | 
				
			||||||
            Frontend.u.ofdm.TransmissionMode=TRANSMISSION_MODE_2K;
 | 
					 | 
				
			||||||
            Frontend.u.ofdm.guardInterval=GUARD_INTERVAL_1_32;
 | 
					 | 
				
			||||||
            Frontend.u.ofdm.HierarchyInformation=HIERARCHY_NONE;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
       default:
 | 
					 | 
				
			||||||
            esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
 | 
					 | 
				
			||||||
            return scrFailed;
 | 
					 | 
				
			||||||
       }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     // Tuning:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     // Wait for channel sync:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     if (cFile::FileReady(fd_frontend, 5000)) {
 | 
					 | 
				
			||||||
        FrontendEvent event;
 | 
					 | 
				
			||||||
        int res = ioctl(fd_frontend, FE_GET_EVENT, &event);
 | 
					 | 
				
			||||||
        if (res >= 0) {
 | 
					 | 
				
			||||||
           if (event.type != FE_COMPLETION_EV) {
 | 
					 | 
				
			||||||
              esyslog("ERROR: channel %d not sync'ed on DVB card %d!", ChannelNumber, CardIndex() + 1);
 | 
					 | 
				
			||||||
              if (IsPrimaryDevice())
 | 
					 | 
				
			||||||
                 cThread::RaisePanic();
 | 
					 | 
				
			||||||
              return scrFailed;
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
           }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
           esyslog("ERROR %d in frontend get event (channel %d, card %d)", res, ChannelNumber, CardIndex() + 1);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
     else
 | 
					 | 
				
			||||||
        esyslog("ERROR: timeout while tuning");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     frequency = Frequency;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     // PID settings:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     if (HasDecoder()) {
 | 
					 | 
				
			||||||
        if (!(AddPid(Vpid, ptVideo) && AddPid(Apid, ptAudio))) {//XXX+ dolby Dpid1!!! (if audio plugins are attached)
 | 
					 | 
				
			||||||
           esyslog("ERROR: failed to set PIDs for channel %d", ChannelNumber);
 | 
					 | 
				
			||||||
           return scrFailed;
 | 
					 | 
				
			||||||
           }
 | 
					 | 
				
			||||||
        if (IsPrimaryDevice())
 | 
					 | 
				
			||||||
           AddPid(Tpid, ptTeletext);
 | 
					 | 
				
			||||||
        CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (IsPrimaryDevice() && siProcessor)
 | 
					 | 
				
			||||||
     siProcessor->SetCurrentServiceID(Pnr);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  eSetChannelResult Result = scrOk;
 | 
					  eSetChannelResult Result = scrOk;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -618,30 +273,32 @@ eSetChannelResult cDevice::SetChannel(int ChannelNumber, int Frequency, char Pol
 | 
				
			|||||||
  // use the card that actually can receive it and transfer data from there:
 | 
					  // use the card that actually can receive it and transfer data from there:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (NeedsTransferMode) {
 | 
					  if (NeedsTransferMode) {
 | 
				
			||||||
     cDevice *CaDevice = GetDevice(Ca, 0);
 | 
					     cDevice *CaDevice = GetDevice(Channel->ca, 0);
 | 
				
			||||||
     if (CaDevice && !CaDevice->Receiving()) {
 | 
					     if (CaDevice && !CaDevice->Receiving() && CaDevice->SetChannel(Channel) == scrOk)
 | 
				
			||||||
        if ((Result = CaDevice->SetChannel(ChannelNumber, Frequency, Polarization, Diseqc, Srate, Vpid, Apid, Tpid, Ca, Pnr)) == scrOk)
 | 
					        cControl::Launch(new cTransferControl(CaDevice, Channel->vpid, Channel->apid1, 0, 0, 0));//XXX+
 | 
				
			||||||
           cControl::Launch(new cTransferControl(CaDevice, Vpid, Apid, 0, 0, 0));//XXX+
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
     else
 | 
					     else
 | 
				
			||||||
        Result = scrNoTransfer;
 | 
					        Result = scrNoTransfer;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 | 
					  else if (!SetChannelDevice(Channel))
 | 
				
			||||||
 | 
					     Result = scrFailed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (HasDecoder()) {
 | 
					  if (IsPrimaryDevice())
 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
 | 
					     cSIProcessor::SetCurrentServiceID(Channel->pnr);
 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Start setting system time:
 | 
					  cStatus::MsgChannelSwitch(this, Channel->number);
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (Result == scrOk && siProcessor)
 | 
					 | 
				
			||||||
     siProcessor->SetCurrentTransponder(Frequency);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  cStatus::MsgChannelSwitch(this, ChannelNumber);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return Result;
 | 
					  return Result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDevice::SetChannelDevice(const cChannel *Channel)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDevice::SetVolumeDevice(int Volume)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool cDevice::ToggleMute(void)
 | 
					bool cDevice::ToggleMute(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int OldVolume = volume;
 | 
					  int OldVolume = volume;
 | 
				
			||||||
@@ -653,78 +310,40 @@ bool cDevice::ToggleMute(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void cDevice::SetVolume(int Volume, bool Absolute)
 | 
					void cDevice::SetVolume(int Volume, bool Absolute)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (HasDecoder()) {
 | 
					  volume = min(max(Absolute ? Volume : volume + Volume, 0), MAXVOLUME);
 | 
				
			||||||
     volume = min(max(Absolute ? Volume : volume + Volume, 0), MAXVOLUME);
 | 
					  SetVolumeDevice(volume);
 | 
				
			||||||
     audioMixer_t am;
 | 
					  cStatus::MsgSetVolume(volume, Absolute);
 | 
				
			||||||
     am.volume_left = am.volume_right = volume;
 | 
					  if (volume > 0)
 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_MIXER, &am));
 | 
					     mute = false;
 | 
				
			||||||
     cStatus::MsgSetVolume(volume, Absolute);
 | 
					}
 | 
				
			||||||
     if (volume > 0)
 | 
					
 | 
				
			||||||
        mute = false;
 | 
					int cDevice::SetPlayMode(bool On)
 | 
				
			||||||
     }
 | 
					{
 | 
				
			||||||
 | 
					  return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::TrickSpeed(int Speed)
 | 
					void cDevice::TrickSpeed(int Speed)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (fd_video >= 0)
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_SLOWMOTION, Speed));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::Clear(void)
 | 
					void cDevice::Clear(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (fd_video >= 0)
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
 | 
					 | 
				
			||||||
  if (fd_audio >= 0)
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::Play(void)
 | 
					void cDevice::Play(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (fd_audio >= 0)
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
 | 
					 | 
				
			||||||
  if (fd_video >= 0)
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_CONTINUE));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::Freeze(void)
 | 
					void cDevice::Freeze(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (fd_audio >= 0)
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
 | 
					 | 
				
			||||||
  if (fd_video >= 0)
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_FREEZE));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::Mute(void)
 | 
					void cDevice::Mute(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (fd_audio >= 0) {
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true));
 | 
					 | 
				
			||||||
     }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDevice::StillPicture(const uchar *Data, int Length)
 | 
					void cDevice::StillPicture(const uchar *Data, int Length)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  Mute();
 | 
					 | 
				
			||||||
/* Using the VIDEO_STILLPICTURE ioctl call would be the
 | 
					 | 
				
			||||||
   correct way to display a still frame, but unfortunately this
 | 
					 | 
				
			||||||
   doesn't work with frames from VDR. So let's do pretty much the
 | 
					 | 
				
			||||||
   same here as in DVB/driver/dvb.c's play_iframe() - I have absolutely
 | 
					 | 
				
			||||||
   no idea why it works this way, but doesn't work with VIDEO_STILLPICTURE.
 | 
					 | 
				
			||||||
   If anybody ever finds out what could be changed so that VIDEO_STILLPICTURE
 | 
					 | 
				
			||||||
   could be used, please let me know!
 | 
					 | 
				
			||||||
   kls 2002-03-23
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
//#define VIDEO_STILLPICTURE_WORKS_WITH_VDR_FRAMES
 | 
					 | 
				
			||||||
#ifdef VIDEO_STILLPICTURE_WORKS_WITH_VDR_FRAMES
 | 
					 | 
				
			||||||
  videoDisplayStillPicture sp = { (char *)Data, Length };
 | 
					 | 
				
			||||||
  CHECK(ioctl(fd_video, VIDEO_STILLPICTURE, &sp));
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#define MIN_IFRAME 400000
 | 
					 | 
				
			||||||
  for (int i = MIN_IFRAME / Length + 1; i > 0; i--) {
 | 
					 | 
				
			||||||
      safe_write(fd_video, Data, Length);
 | 
					 | 
				
			||||||
      usleep(1); // allows the buffer to be displayed in case the progress display is active
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool cDevice::Replaying(void)
 | 
					bool cDevice::Replaying(void)
 | 
				
			||||||
@@ -741,19 +360,9 @@ bool cDevice::AttachPlayer(cPlayer *Player)
 | 
				
			|||||||
  if (HasDecoder()) {
 | 
					  if (HasDecoder()) {
 | 
				
			||||||
     if (player)
 | 
					     if (player)
 | 
				
			||||||
        Detach(player);
 | 
					        Detach(player);
 | 
				
			||||||
 | 
					 | 
				
			||||||
     if (siProcessor)
 | 
					 | 
				
			||||||
        siProcessor->SetStatus(false);
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_PLAY));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_PLAY));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     player = Player;
 | 
					     player = Player;
 | 
				
			||||||
     player->device = this;
 | 
					     player->device = this;
 | 
				
			||||||
     player->deviceFileHandle = fd_video;
 | 
					     player->deviceFileHandle = SetPlayMode(true);
 | 
				
			||||||
     player->Activate(true);
 | 
					     player->Activate(true);
 | 
				
			||||||
     return true;
 | 
					     return true;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
@@ -767,17 +376,7 @@ void cDevice::Detach(cPlayer *Player)
 | 
				
			|||||||
     player->deviceFileHandle = -1;
 | 
					     player->deviceFileHandle = -1;
 | 
				
			||||||
     player->device = NULL;
 | 
					     player->device = NULL;
 | 
				
			||||||
     player = NULL;
 | 
					     player = NULL;
 | 
				
			||||||
 | 
					     SetPlayMode(false);
 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_STOP, true));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_STOP, true));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
 | 
					 | 
				
			||||||
     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
 | 
					 | 
				
			||||||
     if (siProcessor)
 | 
					 | 
				
			||||||
        siProcessor->SetStatus(true);
 | 
					 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -802,14 +401,11 @@ void cDevice::StopReplay(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int cDevice::PlayVideo(const uchar *Data, int Length)
 | 
					int cDevice::PlayVideo(const uchar *Data, int Length)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (fd_video >= 0)
 | 
					 | 
				
			||||||
     return write(fd_video, Data, Length);
 | 
					 | 
				
			||||||
  return -1;
 | 
					  return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int cDevice::PlayAudio(const uchar *Data, int Length)
 | 
					int cDevice::PlayAudio(const uchar *Data, int Length)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //XXX+
 | 
					 | 
				
			||||||
  return -1;
 | 
					  return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -828,7 +424,7 @@ int cDevice::Priority(void)
 | 
				
			|||||||
int cDevice::CanShift(int Ca, int Priority, int UsedCards)
 | 
					int cDevice::CanShift(int Ca, int Priority, int UsedCards)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  return -1;//XXX+ too complex with multiple recordings per device
 | 
					  return -1;//XXX+ too complex with multiple recordings per device
 | 
				
			||||||
  // Test whether a receiving on this DVB device can be shifted to another one
 | 
					  // Test whether a receiver on this device can be shifted to another one
 | 
				
			||||||
  // in order to perform a new receiving with the given Ca and Priority on this device:
 | 
					  // in order to perform a new receiving with the given Ca and Priority on this device:
 | 
				
			||||||
  int ShiftLevel = -1; // default means this device can't be shifted
 | 
					  int ShiftLevel = -1; // default means this device can't be shifted
 | 
				
			||||||
  if (UsedCards & (1 << CardIndex()) != 0)
 | 
					  if (UsedCards & (1 << CardIndex()) != 0)
 | 
				
			||||||
@@ -882,7 +478,7 @@ int cDevice::ProvidesCa(int Ca)
 | 
				
			|||||||
bool cDevice::Receiving(void)
 | 
					bool cDevice::Receiving(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  for (int i = 0; i < MAXRECEIVERS; i++) {
 | 
					  for (int i = 0; i < MAXRECEIVERS; i++) {
 | 
				
			||||||
      if (receiver[i])
 | 
					      if (receiver[i] && receiver[i]->priority >= 0) // cReceiver with priority < 0 doesn't count
 | 
				
			||||||
         return true;
 | 
					         return true;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
  return false;
 | 
					  return false;
 | 
				
			||||||
@@ -892,51 +488,31 @@ void cDevice::Action(void)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  dsyslog("receiver thread started on device %d (pid=%d)", CardIndex() + 1, getpid());
 | 
					  dsyslog("receiver thread started on device %d (pid=%d)", CardIndex() + 1, getpid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int fd_dvr = open(dvrFileName, O_RDONLY | O_NONBLOCK);
 | 
					  if (OpenDvr()) {
 | 
				
			||||||
  if (fd_dvr >= 0) {
 | 
					 | 
				
			||||||
     pollfd pfd;
 | 
					 | 
				
			||||||
     pfd.fd = fd_dvr;
 | 
					 | 
				
			||||||
     pfd.events = pfd.revents = POLLIN;
 | 
					 | 
				
			||||||
     uchar b[TS_SIZE];
 | 
					     uchar b[TS_SIZE];
 | 
				
			||||||
     time_t t = time(NULL);
 | 
					     time_t t = time(NULL);
 | 
				
			||||||
     active = true;
 | 
					     active = true;
 | 
				
			||||||
     for (; active;) {
 | 
					     for (; active;) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
         // Read data from the DVR device:
 | 
					         // Read data from the DVR device:
 | 
				
			||||||
 | 
					         int r = GetTSPacket(b);
 | 
				
			||||||
         if (pfd.revents & POLLIN != 0) {
 | 
					         if (r == TS_SIZE) {
 | 
				
			||||||
            int r = read(fd_dvr, b, sizeof(b));
 | 
					            if (*b == TS_SYNC_BYTE) {
 | 
				
			||||||
            if (r == TS_SIZE) {
 | 
					               // We're locked on to a TS packet
 | 
				
			||||||
               if (*b == TS_SYNC_BYTE) {
 | 
					               int Pid = (((uint16_t)b[1] & PID_MASK_HI) << 8) | b[2];
 | 
				
			||||||
                  // We're locked on to a TS packet
 | 
					               // Distribute the packet to all attached receivers:
 | 
				
			||||||
                  int Pid = (((uint16_t)b[1] & PID_MASK_HI) << 8) | b[2];
 | 
					               Lock();
 | 
				
			||||||
                  // Distribute the packet to all attached receivers:
 | 
					               for (int i = 0; i < MAXRECEIVERS; i++) {
 | 
				
			||||||
                  Lock();
 | 
					                   if (receiver[i] && receiver[i]->WantsPid(Pid))
 | 
				
			||||||
                  for (int i = 0; i < MAXRECEIVERS; i++) {
 | 
					                      receiver[i]->Receive(b, TS_SIZE);
 | 
				
			||||||
                      if (receiver[i] && receiver[i]->WantsPid(Pid))
 | 
					                   }
 | 
				
			||||||
                         receiver[i]->Receive(b, TS_SIZE);
 | 
					               Unlock();
 | 
				
			||||||
                      }
 | 
					 | 
				
			||||||
                  Unlock();
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
               t = time(NULL);
 | 
					 | 
				
			||||||
               }
 | 
					 | 
				
			||||||
            else if (r > 0)
 | 
					 | 
				
			||||||
               esyslog("ERROR: got incomplete TS packet (%d bytes)", r);//XXX+ TODO do we have to read the rest???
 | 
					 | 
				
			||||||
            else if (r < 0) {
 | 
					 | 
				
			||||||
               if (FATALERRNO) {
 | 
					 | 
				
			||||||
                  if (errno == EBUFFEROVERFLOW) // this error code is not defined in the library
 | 
					 | 
				
			||||||
                     esyslog("ERROR: DVB driver buffer overflow on device %d", CardIndex() + 1);
 | 
					 | 
				
			||||||
                  else {
 | 
					 | 
				
			||||||
                     LOG_ERROR;
 | 
					 | 
				
			||||||
                     break;
 | 
					 | 
				
			||||||
                     }
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
               }
 | 
					               }
 | 
				
			||||||
 | 
					            t = time(NULL);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					         else if (r > 0)
 | 
				
			||||||
         // Wait for more data to become available:
 | 
					            esyslog("ERROR: got incomplete TS packet (%d bytes) on device %d", r, CardIndex() + 1);//XXX+ TODO do we have to read the rest???
 | 
				
			||||||
 | 
					         else if (r < 0)
 | 
				
			||||||
         poll(&pfd, 1, 100);
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
         //XXX+ put this into the recorder??? or give the receiver a flag whether it wants this?
 | 
					         //XXX+ put this into the recorder??? or give the receiver a flag whether it wants this?
 | 
				
			||||||
         if (time(NULL) - t > MAXBROKENTIMEOUT) {
 | 
					         if (time(NULL) - t > MAXBROKENTIMEOUT) {
 | 
				
			||||||
@@ -945,14 +521,26 @@ void cDevice::Action(void)
 | 
				
			|||||||
            t = time(NULL);
 | 
					            t = time(NULL);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
     close(fd_dvr);
 | 
					     CloseDvr();
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
     LOG_ERROR_STR(dvrFileName);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  dsyslog("receiver thread ended on device %d (pid=%d)", CardIndex() + 1, getpid());
 | 
					  dsyslog("receiver thread ended on device %d (pid=%d)", CardIndex() + 1, getpid());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDevice::OpenDvr(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDevice::CloseDvr(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cDevice::GetTSPacket(uchar *Data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool cDevice::AttachReceiver(cReceiver *Receiver)
 | 
					bool cDevice::AttachReceiver(cReceiver *Receiver)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //XXX+ check for same transponder???
 | 
					  //XXX+ check for same transponder???
 | 
				
			||||||
@@ -963,13 +551,8 @@ bool cDevice::AttachReceiver(cReceiver *Receiver)
 | 
				
			|||||||
  StopReplay();
 | 
					  StopReplay();
 | 
				
			||||||
  for (int i = 0; i < MAXRECEIVERS; i++) {
 | 
					  for (int i = 0; i < MAXRECEIVERS; i++) {
 | 
				
			||||||
      if (!receiver[i]) {
 | 
					      if (!receiver[i]) {
 | 
				
			||||||
         //siProcessor->SetStatus(false);//XXX+
 | 
					         for (int n = 0; n < MAXRECEIVEPIDS; n++)
 | 
				
			||||||
         for (int n = 0; n < MAXRECEIVEPIDS; n++) {
 | 
					             AddPid(Receiver->pids[n]);//XXX+ retval!
 | 
				
			||||||
             if (Receiver->pids[n])
 | 
					 | 
				
			||||||
                AddPid(Receiver->pids[n]);//XXX+ retval!
 | 
					 | 
				
			||||||
             else
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
             }
 | 
					 | 
				
			||||||
         Receiver->Activate(true);
 | 
					         Receiver->Activate(true);
 | 
				
			||||||
         Lock();
 | 
					         Lock();
 | 
				
			||||||
         Receiver->device = this;
 | 
					         Receiver->device = this;
 | 
				
			||||||
@@ -995,12 +578,8 @@ void cDevice::Detach(cReceiver *Receiver)
 | 
				
			|||||||
         receiver[i] = NULL;
 | 
					         receiver[i] = NULL;
 | 
				
			||||||
         Receiver->device = NULL;
 | 
					         Receiver->device = NULL;
 | 
				
			||||||
         Unlock();
 | 
					         Unlock();
 | 
				
			||||||
         for (int n = 0; n < MAXRECEIVEPIDS; n++) {
 | 
					         for (int n = 0; n < MAXRECEIVEPIDS; n++)
 | 
				
			||||||
             if (Receiver->pids[n])
 | 
					             DelPid(Receiver->pids[n]);
 | 
				
			||||||
                DelPid(Receiver->pids[n]);
 | 
					 | 
				
			||||||
             else
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
             }
 | 
					 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
      else if (receiver[i])
 | 
					      else if (receiver[i])
 | 
				
			||||||
         receiversLeft = true;
 | 
					         receiversLeft = true;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										207
									
								
								device.h
									
									
									
									
									
								
							
							
						
						
									
										207
									
								
								device.h
									
									
									
									
									
								
							@@ -4,38 +4,33 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: device.h 1.3 2002/06/23 11:50:24 kls Exp $
 | 
					 * $Id: device.h 1.5 2002/08/04 14:02:19 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __DEVICE_H
 | 
					#ifndef __DEVICE_H
 | 
				
			||||||
#define __DEVICE_H
 | 
					#define __DEVICE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#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/dmx.h>
 | 
					 | 
				
			||||||
#include <ost/frontend.h>
 | 
					 | 
				
			||||||
#include <ost/audio.h>
 | 
					 | 
				
			||||||
#include <ost/video.h>
 | 
					 | 
				
			||||||
#include "eit.h"
 | 
					 | 
				
			||||||
#include "thread.h"
 | 
					#include "thread.h"
 | 
				
			||||||
 | 
					#include "tools.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum eSetChannelResult { scrOk, scrNoTransfer, scrFailed };
 | 
					#define MAXDEVICES         16 // the maximum number of devices in the system
 | 
				
			||||||
 | 
					#define MAXCACAPS          16 // the maximum number of different CA values per device
 | 
				
			||||||
#define MAXDEVICES          4 // the maximum number of devices in the system
 | 
					#define MAXPIDHANDLES      16 // the maximum number of different PIDs per device
 | 
				
			||||||
#define MAXCACAPS          16 // the maximum number of different CA values per DVB device
 | 
					#define MAXRECEIVERS       16 // the maximum number of receivers per device
 | 
				
			||||||
#define MAXPIDHANDLES      16 // the maximum number of different PIDs per DVB device
 | 
					 | 
				
			||||||
#define MAXRECEIVERS       16 // the maximum number of receivers per DVB device
 | 
					 | 
				
			||||||
#define MAXVOLUME         255
 | 
					#define MAXVOLUME         255
 | 
				
			||||||
#define VOLUMEDELTA         5 // used to increase/decrease the volume
 | 
					#define VOLUMEDELTA         5 // used to increase/decrease the volume
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TS_SIZE          188
 | 
				
			||||||
 | 
					#define TS_SYNC_BYTE     0x47
 | 
				
			||||||
 | 
					#define PID_MASK_HI      0x1F
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum eSetChannelResult { scrOk, scrNoTransfer, scrFailed };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class cChannel;
 | 
				
			||||||
class cPlayer;
 | 
					class cPlayer;
 | 
				
			||||||
class cReceiver;
 | 
					class cReceiver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class cDevice : cThread {
 | 
					class cDevice : cThread {
 | 
				
			||||||
  friend class cOsd;//XXX
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  static int numDevices;
 | 
					  static int numDevices;
 | 
				
			||||||
  static int useDevice;
 | 
					  static int useDevice;
 | 
				
			||||||
@@ -43,106 +38,142 @@ private:
 | 
				
			|||||||
  static cDevice *primaryDevice;
 | 
					  static cDevice *primaryDevice;
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  static int NumDevices(void) { return numDevices; }
 | 
					  static int NumDevices(void) { return numDevices; }
 | 
				
			||||||
         // Returns the total number of DVB devices.
 | 
					         // Returns the total number of devices.
 | 
				
			||||||
  static void SetUseDevice(int n);
 | 
					  static void SetUseDevice(int n);
 | 
				
			||||||
         // Sets the 'useDevice' flag of the given DVB device.
 | 
					         // Sets the 'useDevice' flag of the given device.
 | 
				
			||||||
         // If this function is not called before Initialize(), all DVB devices
 | 
					         // If this function is not called before initializing, all devices
 | 
				
			||||||
         // will be used.
 | 
					         // will be used.
 | 
				
			||||||
 | 
					  static bool UseDevice(int n) { return useDevice == 0 || (useDevice & (1 << n)) != 0; }
 | 
				
			||||||
 | 
					         // Tells whether the device with the given card index shall be used in
 | 
				
			||||||
 | 
					         // this instance of VDR.
 | 
				
			||||||
  static bool SetPrimaryDevice(int n);
 | 
					  static bool SetPrimaryDevice(int n);
 | 
				
			||||||
         // Sets the primary DVB device to 'n' (which must be in the range
 | 
					         // Sets the primary device to 'n' (which must be in the range
 | 
				
			||||||
         // 1...numDevices) and returns true if this was possible.
 | 
					         // 1...numDevices) and returns true if this was possible.
 | 
				
			||||||
  static cDevice *PrimaryDevice(void) { return primaryDevice; }
 | 
					  static cDevice *PrimaryDevice(void) { return primaryDevice; }
 | 
				
			||||||
         // Returns the primary DVB device.
 | 
					         // Returns the primary device.
 | 
				
			||||||
  static cDevice *GetDevice(int Ca, int Priority, int Frequency = 0, int Vpid = 0, bool *ReUse = NULL);
 | 
					  static cDevice *GetDevice(int Ca, int Priority, int Frequency = 0, int Vpid = 0, bool *ReUse = NULL);
 | 
				
			||||||
         // Selects a free DVB device, avoiding the primaryDevice if possible.
 | 
					         // Selects a free device, avoiding the primaryDevice if possible.
 | 
				
			||||||
         // If Ca is not 0, the device with the given number will be returned
 | 
					         // If Ca is not 0, the device with the given number will be returned
 | 
				
			||||||
         // in case Ca is <= MAXDEVICES, or the device that provides the given
 | 
					         // in case Ca is <= MAXDEVICES, or the device that provides the given
 | 
				
			||||||
         // value in its caCaps.
 | 
					         // value in its caCaps.
 | 
				
			||||||
         // If there is a device that is already tuned to the given Frequency,
 | 
					         // If there is a device that is already receiving and can be re-used to
 | 
				
			||||||
         // and that device is able to receive multiple channels ("budget" cards),
 | 
					         // receive another data stream, that device will be returned.
 | 
				
			||||||
         // that device will be returned. Else if a ("full featured") device is
 | 
					         // If all devices are currently receiving, the one receiving with the
 | 
				
			||||||
         // tuned to Frequency and Vpid, that one will be returned.
 | 
					         // lowest priority (if any) that is lower than the given Priority
 | 
				
			||||||
         // If all DVB devices are currently receiving, the one receiving the
 | 
					 | 
				
			||||||
         // lowest priority timer (if any) that is lower than the given Priority
 | 
					 | 
				
			||||||
         // will be returned.
 | 
					         // will be returned.
 | 
				
			||||||
         // If ReUse is given, the caller will be informed whether the device can be re-used
 | 
					         // If ReUse is given, the caller will be informed whether the device can be re-used
 | 
				
			||||||
         // for a new recording. If ReUse returns 'true', the caller must NOT switch the channel
 | 
					         // for a new recording. If ReUse returns 'true', the caller must NOT switch the channel
 | 
				
			||||||
         // (the device is already properly tuned). Otherwise the caller MUST switch the channel.
 | 
					         // (the device is already properly tuned). Otherwise the caller MUST switch the channel.
 | 
				
			||||||
  static void SetCaCaps(void);
 | 
					  static void SetCaCaps(int Index = -1);
 | 
				
			||||||
         // Sets the CaCaps of all DVB devices according to the Setup data.
 | 
					         // Sets the CaCaps of the given device according to the Setup data.
 | 
				
			||||||
  static bool Probe(const char *FileName);
 | 
					         // By default the CaCaps of all devices are set.
 | 
				
			||||||
         // Probes for existing DVB devices.
 | 
					 | 
				
			||||||
  static bool Initialize(void);
 | 
					 | 
				
			||||||
         // Initializes the DVB devices.
 | 
					 | 
				
			||||||
         // Must be called before accessing any DVB functions.
 | 
					 | 
				
			||||||
  static void Shutdown(void);
 | 
					  static void Shutdown(void);
 | 
				
			||||||
         // Closes down all DVB devices.
 | 
					         // Closes down all devices.
 | 
				
			||||||
         // Must be called at the end of the program.
 | 
					         // Must be called at the end of the program.
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					  static int nextCardIndex;
 | 
				
			||||||
  int cardIndex;
 | 
					  int cardIndex;
 | 
				
			||||||
  int caCaps[MAXCACAPS];
 | 
					  int caCaps[MAXCACAPS];
 | 
				
			||||||
  FrontendType frontendType;
 | 
					protected:
 | 
				
			||||||
  char *dvrFileName;
 | 
					  cDevice(void);
 | 
				
			||||||
  bool active;
 | 
					 | 
				
			||||||
  int fd_osd, fd_frontend, fd_sec, fd_audio, fd_video;
 | 
					 | 
				
			||||||
  int OsdDeviceHandle(void) { return fd_osd; }
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
  cDevice(int n);
 | 
					 | 
				
			||||||
  virtual ~cDevice();
 | 
					  virtual ~cDevice();
 | 
				
			||||||
  bool IsPrimaryDevice(void) { return this == primaryDevice; }
 | 
					  static int NextCardIndex(int n = 0);
 | 
				
			||||||
 | 
					         // Each device in a given machine must have a unique card index, which
 | 
				
			||||||
 | 
					         // will be used to identify the device for assigning Ca parameters and
 | 
				
			||||||
 | 
					         // deciding whether to actually use that device in this particular
 | 
				
			||||||
 | 
					         // instance of VDR. Every time a new cDevice is created, it will be
 | 
				
			||||||
 | 
					         // given the current nextCardIndex, and then nextCardIndex will be
 | 
				
			||||||
 | 
					         // automatically incremented by 1. A derived class can determine whether
 | 
				
			||||||
 | 
					         // a given device shall be used by checking UseDevice(NextCardIndex()).
 | 
				
			||||||
 | 
					         // If a device is skipped, or if there are possible device indexes left
 | 
				
			||||||
 | 
					         // after a derived class has set up all its devices, NextCardIndex(n)
 | 
				
			||||||
 | 
					         // must be called, where n is the number of card indexes to skip.
 | 
				
			||||||
 | 
					  virtual void MakePrimaryDevice(bool On);
 | 
				
			||||||
 | 
					         // Informs a device that it will be the primary device. If there is
 | 
				
			||||||
 | 
					         // anything the device needs to set up when it becomes the primary
 | 
				
			||||||
 | 
					         // device (On = true) or to shut down when it no longer is the primary
 | 
				
			||||||
 | 
					         // device (On = false), it should do so in this function.
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  bool IsPrimaryDevice(void) const { return this == primaryDevice; }
 | 
				
			||||||
  int CardIndex(void) const { return cardIndex; }
 | 
					  int CardIndex(void) const { return cardIndex; }
 | 
				
			||||||
         // Returns the card index of this device (0 ... MAXDEVICES - 1).
 | 
					         // Returns the card index of this device (0 ... MAXDEVICES - 1).
 | 
				
			||||||
  int ProvidesCa(int Ca);
 | 
					  int ProvidesCa(int Ca);
 | 
				
			||||||
         // Checks whether this DVB device provides the given value in its
 | 
					         // Checks whether this device provides the given value in its
 | 
				
			||||||
         // caCaps. Returns 0 if the value is not provided, 1 if only this
 | 
					         // caCaps. Returns 0 if the value is not provided, 1 if only this
 | 
				
			||||||
         // value is provided, and > 1 if this and other values are provided.
 | 
					         // value is provided, and > 1 if this and other values are provided.
 | 
				
			||||||
         // If the given value is equal to the number of this DVB device,
 | 
					         // If the given value is equal to the number of this device,
 | 
				
			||||||
         // 1 is returned. If it is 0 (FTA), 1 plus the number of other values
 | 
					         // 1 is returned. If it is 0 (FTA), 1 plus the number of other values
 | 
				
			||||||
         // in caCaps is returned.
 | 
					         // in caCaps is returned.
 | 
				
			||||||
  bool HasDecoder(void) const { return fd_video >= 0 && fd_audio >= 0; }
 | 
					  virtual bool CanBeReUsed(int Frequency, int Vpid);//XXX TODO make it more abstract
 | 
				
			||||||
 | 
					         // Tells whether this device is already receiving and allows another
 | 
				
			||||||
 | 
					         // receiver with the given settings to be attached to it.
 | 
				
			||||||
 | 
					  virtual bool HasDecoder(void) const;
 | 
				
			||||||
 | 
					         // Tells whether this device has an MPEG decoder.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Channel facilities
 | 
					// Channel facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					protected:
 | 
				
			||||||
  int currentChannel;
 | 
					  int currentChannel;
 | 
				
			||||||
  int frequency;
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  eSetChannelResult SetChannel(int ChannelNumber, int Frequency, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Tpid, int Ca, int Pnr);
 | 
					  eSetChannelResult SetChannel(const cChannel *Channel);
 | 
				
			||||||
 | 
					         // Sets the device to the given channel (general setup).
 | 
				
			||||||
 | 
					  virtual bool SetChannelDevice(const cChannel *Channel);
 | 
				
			||||||
 | 
					         // Sets the device to the given channel (actual physical setup).
 | 
				
			||||||
  static int CurrentChannel(void) { return primaryDevice ? primaryDevice->currentChannel : 0; }
 | 
					  static int CurrentChannel(void) { return primaryDevice ? primaryDevice->currentChannel : 0; }
 | 
				
			||||||
 | 
					         // Returns the number of the current channel on the primary device.
 | 
				
			||||||
  int Channel(void) { return currentChannel; }
 | 
					  int Channel(void) { return currentChannel; }
 | 
				
			||||||
 | 
					         // Returns the number of the current channel on this device.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PID handle facilities
 | 
					// PID handle facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					  bool active;
 | 
				
			||||||
 | 
					  virtual void Action(void);
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
  enum ePidType { ptVideo, ptAudio, ptTeletext, ptDolby, ptOther };
 | 
					  enum ePidType { ptVideo, ptAudio, ptTeletext, ptDolby, ptOther };
 | 
				
			||||||
  class cPidHandle {
 | 
					  class cPidHandle {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
    int pid;
 | 
					    int pid;
 | 
				
			||||||
    int fd;
 | 
					    int handle;
 | 
				
			||||||
    int used;
 | 
					    int used;
 | 
				
			||||||
    cPidHandle(void) { pid = used = 0; fd = -1; }
 | 
					    cPidHandle(void) { pid = used = 0; handle = -1; }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  cPidHandle pidHandles[MAXPIDHANDLES];
 | 
					  cPidHandle pidHandles[MAXPIDHANDLES];
 | 
				
			||||||
  bool AddPid(int Pid, ePidType PidType = ptOther);
 | 
					  bool AddPid(int Pid, ePidType PidType = ptOther);
 | 
				
			||||||
  bool DelPid(int Pid);
 | 
					         // Adds a PID to the set of PIDs this device shall receive.
 | 
				
			||||||
  bool SetPid(int fd, dmxPesType_t PesType, int Pid, dmxOutput_t Output);
 | 
					  void DelPid(int Pid);
 | 
				
			||||||
  virtual void Action(void);
 | 
					         // Deletes a PID from the set of PIDs this device shall receive.
 | 
				
			||||||
 | 
					  virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
 | 
				
			||||||
 | 
					         // Does the actual PID setting on this device.
 | 
				
			||||||
 | 
					         // On indicates whether the PID shall be added or deleted.
 | 
				
			||||||
 | 
					         // Handle->handle can be used by the device to store information it
 | 
				
			||||||
 | 
					         // needs to receive this PID (for instance a file handle).
 | 
				
			||||||
 | 
					         // Handle->used indicated how many receivers are using this PID.
 | 
				
			||||||
 | 
					         // Type indicates some special types of PIDs, which the device may
 | 
				
			||||||
 | 
					         // need to set in a specific way.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Image Grab facilities
 | 
					// Image Grab facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
 | 
					  virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
 | 
				
			||||||
 | 
					         // Grabs the currently visible screen image into the given file, with the
 | 
				
			||||||
 | 
					         // given parameters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Video format facilities
 | 
					// Video format facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  virtual void SetVideoFormat(videoFormat_t Format);
 | 
					  virtual void SetVideoFormat(bool VideoFormat16_9);
 | 
				
			||||||
 | 
					         // Sets the output video format to either 16:9 or 4:3 (only useful
 | 
				
			||||||
 | 
					         // if this device has an MPEG decoder).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Volume facilities
 | 
					// Volume facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  bool mute;
 | 
					  bool mute;
 | 
				
			||||||
  int volume;
 | 
					  int volume;
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual void SetVolumeDevice(int Volume);
 | 
				
			||||||
 | 
					       // Sets the audio volume on this device (Volume = 0...255).
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  bool IsMute(void) { return mute; }
 | 
					  bool IsMute(void) { return mute; }
 | 
				
			||||||
  bool ToggleMute(void);
 | 
					  bool ToggleMute(void);
 | 
				
			||||||
@@ -152,30 +183,46 @@ public:
 | 
				
			|||||||
       // the current volume.
 | 
					       // the current volume.
 | 
				
			||||||
  static int CurrentVolume(void) { return primaryDevice ? primaryDevice->volume : 0; }//XXX???
 | 
					  static int CurrentVolume(void) { return primaryDevice ? primaryDevice->volume : 0; }//XXX???
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // EIT facilities
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
  cSIProcessor *siProcessor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Player facilities
 | 
					// Player facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  cPlayer *player;
 | 
					  cPlayer *player;
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual int SetPlayMode(bool On);
 | 
				
			||||||
 | 
					       // Sets the device into play mode (On = true) or normal
 | 
				
			||||||
 | 
					       // viewing mode (On = false). If On is true, it may return a file
 | 
				
			||||||
 | 
					       // handle that a player can use to poll this device when replaying.
 | 
				
			||||||
 | 
					       //XXX TODO should be implemented differently
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  void TrickSpeed(int Speed);
 | 
					  virtual void TrickSpeed(int Speed);
 | 
				
			||||||
  void Clear(void);
 | 
					       // Sets the device into a mode where replay is done slower.
 | 
				
			||||||
  void Play(void);
 | 
					       // Every single frame shall then be displayed the given number of
 | 
				
			||||||
  void Freeze(void);
 | 
					       // times.
 | 
				
			||||||
  void Mute(void);
 | 
					  virtual void Clear(void);
 | 
				
			||||||
  void StillPicture(const uchar *Data, int Length);
 | 
					       // Clears all video and audio data from the device.
 | 
				
			||||||
 | 
					  virtual void Play(void);
 | 
				
			||||||
 | 
					       // Sets the device into play mode (after a previous trick
 | 
				
			||||||
 | 
					       // mode).
 | 
				
			||||||
 | 
					  virtual void Freeze(void);
 | 
				
			||||||
 | 
					       // Puts the device into "freeze frame" mode.
 | 
				
			||||||
 | 
					  virtual void Mute(void);
 | 
				
			||||||
 | 
					       // Turns off audio while replaying.
 | 
				
			||||||
 | 
					  virtual void StillPicture(const uchar *Data, int Length);
 | 
				
			||||||
 | 
					       // Displays the given I-frame as a still picture.
 | 
				
			||||||
 | 
					  virtual int PlayVideo(const uchar *Data, int Length);
 | 
				
			||||||
 | 
					       // Actually plays the given data block as video. The data must be
 | 
				
			||||||
 | 
					       // part of a PES (Packetized Elementary Stream) which can contain
 | 
				
			||||||
 | 
					       // one video and one audio strem.
 | 
				
			||||||
 | 
					  virtual int PlayAudio(const uchar *Data, int Length);
 | 
				
			||||||
 | 
					       // Plays additional audio streams, like Dolby Digital.
 | 
				
			||||||
  bool Replaying(void);
 | 
					  bool Replaying(void);
 | 
				
			||||||
       // Returns true if we are currently replaying.
 | 
					       // Returns true if we are currently replaying.
 | 
				
			||||||
  void StopReplay(void);
 | 
					  void StopReplay(void);
 | 
				
			||||||
       // Stops the current replay session (if any).
 | 
					       // Stops the current replay session (if any).
 | 
				
			||||||
  bool AttachPlayer(cPlayer *Player);
 | 
					  bool AttachPlayer(cPlayer *Player);
 | 
				
			||||||
 | 
					       // Attaches the given player to this device.
 | 
				
			||||||
  void Detach(cPlayer *Player);
 | 
					  void Detach(cPlayer *Player);
 | 
				
			||||||
  virtual int PlayVideo(const uchar *Data, int Length);
 | 
					       // Detaches the given player from this device.
 | 
				
			||||||
  virtual int PlayAudio(const uchar *Data, int Length);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Receiver facilities
 | 
					// Receiver facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -184,16 +231,30 @@ private:
 | 
				
			|||||||
  int ca;
 | 
					  int ca;
 | 
				
			||||||
  int Priority(void);
 | 
					  int Priority(void);
 | 
				
			||||||
      // Returns the priority of the current receiving session (0..MAXPRIORITY),
 | 
					      // Returns the priority of the current receiving session (0..MAXPRIORITY),
 | 
				
			||||||
      // or -1 if no receiver is currently active. The primary DVB device will
 | 
					      // or -1 if no receiver is currently active. The primary device will
 | 
				
			||||||
      // always return at least Setup.PrimaryLimit-1.
 | 
					      // always return at least Setup.PrimaryLimit-1.
 | 
				
			||||||
  int CanShift(int Ca, int Priority, int UsedCards = 0);
 | 
					  int CanShift(int Ca, int Priority, int UsedCards = 0);
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual bool OpenDvr(void);
 | 
				
			||||||
 | 
					      // Opens the DVR of this device and prepares it to deliver a Transport
 | 
				
			||||||
 | 
					      // Stream for use in a cReceiver.
 | 
				
			||||||
 | 
					  virtual void CloseDvr(void);
 | 
				
			||||||
 | 
					      // Shuts down the DVR.
 | 
				
			||||||
 | 
					  virtual int GetTSPacket(uchar *Data);
 | 
				
			||||||
 | 
					      // Gets exactly one TS packet from the DVR of this device and copies it
 | 
				
			||||||
 | 
					      // into the given memory area (which is exactly 188 bytes in size).
 | 
				
			||||||
 | 
					      // Returns the number of bytes copied into Data (which must be 188).
 | 
				
			||||||
 | 
					      // If there is currently no TS packet available, 0 should be returned.
 | 
				
			||||||
 | 
					      // In case of a non recoverable error, returns -1.
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  int  Ca(void) { return ca; }
 | 
					  int  Ca(void) { return ca; }
 | 
				
			||||||
       // Returns the ca of the current receiving session.
 | 
					       // Returns the ca of the current receiving session.
 | 
				
			||||||
  bool Receiving(void);
 | 
					  bool Receiving(void);
 | 
				
			||||||
       // Returns true if we are currently receiving.
 | 
					       // Returns true if we are currently receiving.
 | 
				
			||||||
  bool AttachReceiver(cReceiver *Receiver);
 | 
					  bool AttachReceiver(cReceiver *Receiver);
 | 
				
			||||||
 | 
					       // Attaches the given receiver to this device.
 | 
				
			||||||
  void Detach(cReceiver *Receiver);
 | 
					  void Detach(cReceiver *Receiver);
 | 
				
			||||||
 | 
					       // Detaches the given receiver from this device.
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //__DEVICE_H
 | 
					#endif //__DEVICE_H
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										615
									
								
								dvbdevice.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										615
									
								
								dvbdevice.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,615 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * dvbdevice.c: The DVB device interface
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 | 
					 * how to reach the author.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * $Id: dvbdevice.c 1.1 2002/08/04 12:24:25 kls Exp $
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dvbdevice.h"
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#ifdef boolean
 | 
				
			||||||
 | 
					#define HAVE_BOOLEAN
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#include <jpeglib.h>
 | 
				
			||||||
 | 
					#undef boolean
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#include <limits.h>
 | 
				
			||||||
 | 
					#include <linux/videodev.h>
 | 
				
			||||||
 | 
					#include <ost/audio.h>
 | 
				
			||||||
 | 
					#include <ost/sec.h>
 | 
				
			||||||
 | 
					#include <ost/video.h>
 | 
				
			||||||
 | 
					#include <poll.h>
 | 
				
			||||||
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
 | 
					#include <sys/mman.h>
 | 
				
			||||||
 | 
					#include "dvbosd.h"
 | 
				
			||||||
 | 
					#include "player.h"
 | 
				
			||||||
 | 
					#include "receiver.h"
 | 
				
			||||||
 | 
					#include "status.h"
 | 
				
			||||||
 | 
					#include "transfer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MAXDVBDEVICES     4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEV_VIDEO         "/dev/video"
 | 
				
			||||||
 | 
					#define DEV_OST_OSD       "/dev/ost/osd"
 | 
				
			||||||
 | 
					#define DEV_OST_FRONTEND  "/dev/ost/frontend"
 | 
				
			||||||
 | 
					#define DEV_OST_SEC       "/dev/ost/sec"
 | 
				
			||||||
 | 
					#define DEV_OST_DVR       "/dev/ost/dvr"
 | 
				
			||||||
 | 
					#define DEV_OST_DEMUX     "/dev/ost/demux"
 | 
				
			||||||
 | 
					#define DEV_OST_VIDEO     "/dev/ost/video"
 | 
				
			||||||
 | 
					#define DEV_OST_AUDIO     "/dev/ost/audio"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *OstName(const char *Name, int n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  static char buffer[PATH_MAX];
 | 
				
			||||||
 | 
					  snprintf(buffer, sizeof(buffer), "%s%d", Name, n);
 | 
				
			||||||
 | 
					  return buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int OstOpen(const char *Name, int n, int Mode, bool ReportError = false)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  const char *FileName = OstName(Name, n);
 | 
				
			||||||
 | 
					  int fd = open(FileName, Mode);
 | 
				
			||||||
 | 
					  if (fd < 0 && ReportError)
 | 
				
			||||||
 | 
					     LOG_ERROR_STR(FileName);
 | 
				
			||||||
 | 
					  return fd;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cDvbDevice::cDvbDevice(int n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  frontendType = FrontendType(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
 | 
				
			||||||
 | 
					  siProcessor = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Devices that are present on all card types:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fd_frontend = OstOpen(DEV_OST_FRONTEND, n, O_RDWR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Devices that are only present on DVB-S cards:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fd_sec      = OstOpen(DEV_OST_SEC,      n, O_RDWR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Devices that are only present on cards with decoders:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fd_osd      = OstOpen(DEV_OST_OSD,    n, O_RDWR);
 | 
				
			||||||
 | 
					  fd_video    = OstOpen(DEV_OST_VIDEO,  n, O_RDWR | O_NONBLOCK);
 | 
				
			||||||
 | 
					  fd_audio    = OstOpen(DEV_OST_AUDIO,  n, O_RDWR | O_NONBLOCK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // The DVR device (will be opened and closed as needed):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fd_dvr = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Video format:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SetVideoFormat(Setup.VideoFormat ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // We only check the devices that must be present - the others will be checked before accessing them://XXX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (fd_frontend >= 0) {
 | 
				
			||||||
 | 
					     siProcessor = new cSIProcessor(OstName(DEV_OST_DEMUX, n));
 | 
				
			||||||
 | 
					     FrontendInfo feinfo;
 | 
				
			||||||
 | 
					     if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0)
 | 
				
			||||||
 | 
					        frontendType = feinfo.type;
 | 
				
			||||||
 | 
					     else
 | 
				
			||||||
 | 
					        LOG_ERROR;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					     esyslog("ERROR: can't open DVB device %d", n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  frequency = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cDvbDevice::~cDvbDevice()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  delete siProcessor;
 | 
				
			||||||
 | 
					  // We're not explicitly closing any device files here, since this sometimes
 | 
				
			||||||
 | 
					  // caused segfaults. Besides, the program is about to terminate anyway...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDvbDevice::Probe(const char *FileName)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (access(FileName, F_OK) == 0) {
 | 
				
			||||||
 | 
					     dsyslog("probing %s", FileName);
 | 
				
			||||||
 | 
					     int f = open(FileName, O_RDONLY);
 | 
				
			||||||
 | 
					     if (f >= 0) {
 | 
				
			||||||
 | 
					        close(f);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					     else if (errno != ENODEV && errno != EINVAL)
 | 
				
			||||||
 | 
					        LOG_ERROR_STR(FileName);
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  else if (errno != ENOENT)
 | 
				
			||||||
 | 
					     LOG_ERROR_STR(FileName);
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDvbDevice::Initialize(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int found = 0;
 | 
				
			||||||
 | 
					  int i;
 | 
				
			||||||
 | 
					  for (i = 0; i < MAXDVBDEVICES; i++) {
 | 
				
			||||||
 | 
					      if (UseDevice(NextCardIndex())) {
 | 
				
			||||||
 | 
					         if (Probe(OstName(DEV_OST_FRONTEND, i))) {
 | 
				
			||||||
 | 
					            new cDvbDevice(i);
 | 
				
			||||||
 | 
					            found++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					         else
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					         NextCardIndex(1); // skips this one
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					  NextCardIndex(MAXDVBDEVICES - i); // skips the rest
 | 
				
			||||||
 | 
					  if (found > 0)
 | 
				
			||||||
 | 
					     isyslog("found %d video device%s", found, found > 1 ? "s" : "");
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					     isyslog("no DVB device found");
 | 
				
			||||||
 | 
					  return found > 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::MakePrimaryDevice(bool On)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  cDvbOsd::SetDvbDevice(On ? this : NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDvbDevice::CanBeReUsed(int Frequency, int Vpid)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return Receiving() // to be reused the DVB device must already be receiving...
 | 
				
			||||||
 | 
					      && frequency == Frequency // ...and tuned to the requested frequency...
 | 
				
			||||||
 | 
					      && (!HasDecoder() // ...and either be a "budget card" which can receive multiple channels...
 | 
				
			||||||
 | 
					          || pidHandles[ptVideo].pid == Vpid // ...or be a "full featured card" that's already tuned to the requested video PID
 | 
				
			||||||
 | 
					         );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDvbDevice::HasDecoder(void) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return fd_video >= 0 && fd_audio >= 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDvbDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  int videoDev = OstOpen(DEV_VIDEO, CardIndex(), O_RDWR, true);
 | 
				
			||||||
 | 
					  if (videoDev >= 0) {
 | 
				
			||||||
 | 
					     int result = 0;
 | 
				
			||||||
 | 
					     struct video_mbuf mbuf;
 | 
				
			||||||
 | 
					     result |= ioctl(videoDev, VIDIOCGMBUF, &mbuf);
 | 
				
			||||||
 | 
					     if (result == 0) {
 | 
				
			||||||
 | 
					        int msize = mbuf.size;
 | 
				
			||||||
 | 
					        unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
 | 
				
			||||||
 | 
					        if (mem && mem != (unsigned char *)-1) {
 | 
				
			||||||
 | 
					           // set up the size and RGB
 | 
				
			||||||
 | 
					           struct video_capability vc;
 | 
				
			||||||
 | 
					           result |= ioctl(videoDev, VIDIOCGCAP, &vc);
 | 
				
			||||||
 | 
					           struct video_mmap vm;
 | 
				
			||||||
 | 
					           vm.frame = 0;
 | 
				
			||||||
 | 
					           if ((SizeX > 0) && (SizeX <= vc.maxwidth) &&
 | 
				
			||||||
 | 
					               (SizeY > 0) && (SizeY <= vc.maxheight)) {
 | 
				
			||||||
 | 
					              vm.width = SizeX;
 | 
				
			||||||
 | 
					              vm.height = SizeY;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					           else {
 | 
				
			||||||
 | 
					              vm.width = vc.maxwidth;
 | 
				
			||||||
 | 
					              vm.height = vc.maxheight;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					           vm.format = VIDEO_PALETTE_RGB24;
 | 
				
			||||||
 | 
					           result |= ioctl(videoDev, VIDIOCMCAPTURE, &vm);
 | 
				
			||||||
 | 
					           result |= ioctl(videoDev, VIDIOCSYNC, &vm.frame);
 | 
				
			||||||
 | 
					           // make RGB out of BGR:
 | 
				
			||||||
 | 
					           int memsize = vm.width * vm.height;
 | 
				
			||||||
 | 
					           unsigned char *mem1 = mem;
 | 
				
			||||||
 | 
					           for (int i = 0; i < memsize; i++) {
 | 
				
			||||||
 | 
					               unsigned char tmp = mem1[2];
 | 
				
			||||||
 | 
					               mem1[2] = mem1[0];
 | 
				
			||||||
 | 
					               mem1[0] = tmp;
 | 
				
			||||||
 | 
					               mem1 += 3;
 | 
				
			||||||
 | 
					               }
 | 
				
			||||||
 | 
					         
 | 
				
			||||||
 | 
					           if (Quality < 0)
 | 
				
			||||||
 | 
					              Quality = 255; //XXX is this 'best'???
 | 
				
			||||||
 | 
					         
 | 
				
			||||||
 | 
					           isyslog("grabbing to %s (%s %d %d %d)", FileName, Jpeg ? "JPEG" : "PNM", Quality, vm.width, vm.height);
 | 
				
			||||||
 | 
					           FILE *f = fopen(FileName, "wb");
 | 
				
			||||||
 | 
					           if (f) {
 | 
				
			||||||
 | 
					              if (Jpeg) {
 | 
				
			||||||
 | 
					                 // write JPEG file:
 | 
				
			||||||
 | 
					                 struct jpeg_compress_struct cinfo;
 | 
				
			||||||
 | 
					                 struct jpeg_error_mgr jerr;
 | 
				
			||||||
 | 
					                 cinfo.err = jpeg_std_error(&jerr);
 | 
				
			||||||
 | 
					                 jpeg_create_compress(&cinfo);
 | 
				
			||||||
 | 
					                 jpeg_stdio_dest(&cinfo, f);
 | 
				
			||||||
 | 
					                 cinfo.image_width = vm.width;
 | 
				
			||||||
 | 
					                 cinfo.image_height = vm.height;
 | 
				
			||||||
 | 
					                 cinfo.input_components = 3;
 | 
				
			||||||
 | 
					                 cinfo.in_color_space = JCS_RGB;
 | 
				
			||||||
 | 
					         
 | 
				
			||||||
 | 
					                 jpeg_set_defaults(&cinfo);
 | 
				
			||||||
 | 
					                 jpeg_set_quality(&cinfo, Quality, true);
 | 
				
			||||||
 | 
					                 jpeg_start_compress(&cinfo, true);
 | 
				
			||||||
 | 
					         
 | 
				
			||||||
 | 
					                 int rs = vm.width * 3;
 | 
				
			||||||
 | 
					                 JSAMPROW rp[vm.height];
 | 
				
			||||||
 | 
					                 for (int k = 0; k < vm.height; k++)
 | 
				
			||||||
 | 
					                     rp[k] = &mem[rs * k];
 | 
				
			||||||
 | 
					                 jpeg_write_scanlines(&cinfo, rp, vm.height);
 | 
				
			||||||
 | 
					                 jpeg_finish_compress(&cinfo);
 | 
				
			||||||
 | 
					                 jpeg_destroy_compress(&cinfo);
 | 
				
			||||||
 | 
					                 }
 | 
				
			||||||
 | 
					              else {
 | 
				
			||||||
 | 
					                 // write PNM file:
 | 
				
			||||||
 | 
					                 if (fprintf(f, "P6\n%d\n%d\n255\n", vm.width, vm.height) < 0 ||
 | 
				
			||||||
 | 
					                     fwrite(mem, vm.width * vm.height * 3, 1, f) < 0) {
 | 
				
			||||||
 | 
					                    LOG_ERROR_STR(FileName);
 | 
				
			||||||
 | 
					                    result |= 1;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                 }
 | 
				
			||||||
 | 
					              fclose(f);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					           else {
 | 
				
			||||||
 | 
					              LOG_ERROR_STR(FileName);
 | 
				
			||||||
 | 
					              result |= 1;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					           munmap(mem, msize);
 | 
				
			||||||
 | 
					           }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					           result |= 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					     close(videoDev);
 | 
				
			||||||
 | 
					     return result == 0;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::SetVideoFormat(bool VideoFormat16_9)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (HasDecoder())
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_SET_FORMAT, VideoFormat16_9 ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//                          ptVideo        ptAudio        ptTeletext        ptDolby        ptOther
 | 
				
			||||||
 | 
					dmxPesType_t PesTypes[] = { DMX_PES_VIDEO, DMX_PES_AUDIO, DMX_PES_TELETEXT, DMX_PES_OTHER, DMX_PES_OTHER };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (Handle->pid) {
 | 
				
			||||||
 | 
					     if (On) {
 | 
				
			||||||
 | 
					        if (Handle->handle < 0) {
 | 
				
			||||||
 | 
					           Handle->handle = OstOpen(DEV_OST_DEMUX, CardIndex(), O_RDWR | O_NONBLOCK, true);
 | 
				
			||||||
 | 
					           if (Handle->handle < 0)
 | 
				
			||||||
 | 
					              return false;
 | 
				
			||||||
 | 
					           }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					     else {
 | 
				
			||||||
 | 
					        CHECK(ioctl(Handle->handle, DMX_STOP));
 | 
				
			||||||
 | 
					        if (Handle->used == 0) {
 | 
				
			||||||
 | 
					           close(Handle->handle);
 | 
				
			||||||
 | 
					           Handle->handle = -1;
 | 
				
			||||||
 | 
					           return true;
 | 
				
			||||||
 | 
					           }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     if (Handle->pid != 0x1FFF) {
 | 
				
			||||||
 | 
					        dmxPesFilterParams pesFilterParams;
 | 
				
			||||||
 | 
					        pesFilterParams.pid     = Handle->pid;
 | 
				
			||||||
 | 
					        pesFilterParams.input   = DMX_IN_FRONTEND;
 | 
				
			||||||
 | 
					        pesFilterParams.output  = (Type <= ptTeletext && Handle->used <= 1) ? DMX_OUT_DECODER : DMX_OUT_TS_TAP;
 | 
				
			||||||
 | 
					        pesFilterParams.pesType = PesTypes[Type < ptOther ? Type : ptOther];
 | 
				
			||||||
 | 
					        pesFilterParams.flags   = DMX_IMMEDIATE_START;
 | 
				
			||||||
 | 
					        //XXX+ pesFilterParams.flags   = DMX_CHECK_CRC;//XXX
 | 
				
			||||||
 | 
					        if (ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
 | 
				
			||||||
 | 
					           LOG_ERROR;
 | 
				
			||||||
 | 
					           return false;
 | 
				
			||||||
 | 
					           }
 | 
				
			||||||
 | 
					        //XXX+ CHECK(ioctl(Handle->handle, DMX_SET_BUFFER_SIZE, KILOBYTE(32)));//XXX
 | 
				
			||||||
 | 
					        //XXX+ CHECK(ioctl(Handle->handle, DMX_START));//XXX
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDvbDevice::SetChannelDevice(const cChannel *Channel)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // Avoid noise while switching:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (HasDecoder()) {
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Stop setting system time:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (siProcessor)
 | 
				
			||||||
 | 
					     siProcessor->SetCurrentTransponder(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Turn off current PIDs:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (HasDecoder()) {
 | 
				
			||||||
 | 
					     DelPid(pidHandles[ptVideo].pid);
 | 
				
			||||||
 | 
					     DelPid(pidHandles[ptAudio].pid);
 | 
				
			||||||
 | 
					     DelPid(pidHandles[ptTeletext].pid);
 | 
				
			||||||
 | 
					     DelPid(pidHandles[ptDolby].pid);
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FrontendParameters Frontend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch (frontendType) {
 | 
				
			||||||
 | 
					    case FE_QPSK: { // DVB-S
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         // Frequency offsets:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         unsigned int freq = Channel->frequency;
 | 
				
			||||||
 | 
					         int tone = SEC_TONE_OFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         if (freq < (unsigned int)Setup.LnbSLOF) {
 | 
				
			||||||
 | 
					            freq -= Setup.LnbFrequLo;
 | 
				
			||||||
 | 
					            tone = SEC_TONE_OFF;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					         else {
 | 
				
			||||||
 | 
					            freq -= Setup.LnbFrequHi;
 | 
				
			||||||
 | 
					            tone = SEC_TONE_ON;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         Frontend.Frequency = freq * 1000UL;
 | 
				
			||||||
 | 
					         Frontend.Inversion = INVERSION_AUTO;
 | 
				
			||||||
 | 
					         Frontend.u.qpsk.SymbolRate = Channel->srate * 1000UL;
 | 
				
			||||||
 | 
					         Frontend.u.qpsk.FEC_inner = FEC_AUTO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         int volt = (Channel->polarization == 'v' || Channel->polarization == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         // DiseqC:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         secCommand scmd;
 | 
				
			||||||
 | 
					         scmd.type = 0;
 | 
				
			||||||
 | 
					         scmd.u.diseqc.addr = 0x10;
 | 
				
			||||||
 | 
					         scmd.u.diseqc.cmd = 0x38;
 | 
				
			||||||
 | 
					         scmd.u.diseqc.numParams = 1;
 | 
				
			||||||
 | 
					         scmd.u.diseqc.params[0] = 0xF0 | ((Channel->diseqc * 4) & 0x0F) | (tone == SEC_TONE_ON ? 1 : 0) | (volt == SEC_VOLTAGE_18 ? 2 : 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         secCmdSequence scmds;
 | 
				
			||||||
 | 
					         scmds.voltage = volt;
 | 
				
			||||||
 | 
					         scmds.miniCommand = SEC_MINI_NONE;
 | 
				
			||||||
 | 
					         scmds.continuousTone = tone;
 | 
				
			||||||
 | 
					         scmds.numCommands = Setup.DiSEqC ? 1 : 0;
 | 
				
			||||||
 | 
					         scmds.commands = &scmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds));
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					         break;
 | 
				
			||||||
 | 
					    case FE_QAM: { // DVB-C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         // Frequency and symbol rate:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         Frontend.Frequency = Channel->frequency * 1000000UL;
 | 
				
			||||||
 | 
					         Frontend.Inversion = INVERSION_AUTO;
 | 
				
			||||||
 | 
					         Frontend.u.qam.SymbolRate = Channel->srate * 1000UL;
 | 
				
			||||||
 | 
					         Frontend.u.qam.FEC_inner = FEC_AUTO;
 | 
				
			||||||
 | 
					         Frontend.u.qam.QAM = QAM_64;
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					         break;
 | 
				
			||||||
 | 
					    case FE_OFDM: { // DVB-T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         // Frequency and OFDM paramaters:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					         Frontend.Frequency = Channel->frequency * 1000UL;
 | 
				
			||||||
 | 
					         Frontend.Inversion = INVERSION_AUTO;
 | 
				
			||||||
 | 
					         Frontend.u.ofdm.bandWidth=BANDWIDTH_8_MHZ;
 | 
				
			||||||
 | 
					         Frontend.u.ofdm.HP_CodeRate=FEC_2_3;
 | 
				
			||||||
 | 
					         Frontend.u.ofdm.LP_CodeRate=FEC_1_2;
 | 
				
			||||||
 | 
					         Frontend.u.ofdm.Constellation=QAM_64;
 | 
				
			||||||
 | 
					         Frontend.u.ofdm.TransmissionMode=TRANSMISSION_MODE_2K;
 | 
				
			||||||
 | 
					         Frontend.u.ofdm.guardInterval=GUARD_INTERVAL_1_32;
 | 
				
			||||||
 | 
					         Frontend.u.ofdm.HierarchyInformation=HIERARCHY_NONE;
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					         break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					         esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
 | 
				
			||||||
 | 
					         return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Tuning:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CHECK(ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Wait for channel sync:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (cFile::FileReady(fd_frontend, 5000)) {
 | 
				
			||||||
 | 
					     FrontendEvent event;
 | 
				
			||||||
 | 
					     int res = ioctl(fd_frontend, FE_GET_EVENT, &event);
 | 
				
			||||||
 | 
					     if (res >= 0) {
 | 
				
			||||||
 | 
					        if (event.type != FE_COMPLETION_EV) {
 | 
				
			||||||
 | 
					           esyslog("ERROR: channel %d not sync'ed on DVB card %d!", Channel->number, CardIndex() + 1);
 | 
				
			||||||
 | 
					           if (IsPrimaryDevice())
 | 
				
			||||||
 | 
					              cThread::RaisePanic();
 | 
				
			||||||
 | 
					           return false;
 | 
				
			||||||
 | 
					           }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					     else
 | 
				
			||||||
 | 
					        esyslog("ERROR %d in frontend get event (channel %d, card %d)", res, Channel->number, CardIndex() + 1);
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					     esyslog("ERROR: timeout while tuning");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  frequency = Channel->frequency;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // PID settings:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (HasDecoder()) {
 | 
				
			||||||
 | 
					     if (!(AddPid(Channel->vpid, ptVideo) && AddPid(Channel->apid1, ptAudio))) {//XXX+ dolby dpid1!!! (if audio plugins are attached)
 | 
				
			||||||
 | 
					        esyslog("ERROR: failed to set PIDs for channel %d", Channel->number);
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					     if (IsPrimaryDevice())
 | 
				
			||||||
 | 
					        AddPid(Channel->tpid, ptTeletext);
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (HasDecoder()) {
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Start setting system time:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (siProcessor)
 | 
				
			||||||
 | 
					     siProcessor->SetCurrentTransponder(Channel->frequency);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::SetVolumeDevice(int Volume)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (HasDecoder()) {
 | 
				
			||||||
 | 
					     audioMixer_t am;
 | 
				
			||||||
 | 
					     am.volume_left = am.volume_right = Volume;
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_MIXER, &am));
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cDvbDevice::SetPlayMode(bool On)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (On) {
 | 
				
			||||||
 | 
					     if (siProcessor)
 | 
				
			||||||
 | 
					        siProcessor->SetStatus(false);
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_PLAY));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_PLAY));
 | 
				
			||||||
 | 
					     return fd_video;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  else {
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_STOP, true));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_STOP, true));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
 | 
				
			||||||
 | 
					     if (siProcessor)
 | 
				
			||||||
 | 
					        siProcessor->SetStatus(true);
 | 
				
			||||||
 | 
					     return -1;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::TrickSpeed(int Speed)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (fd_video >= 0)
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_SLOWMOTION, Speed));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::Clear(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (fd_video >= 0)
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
 | 
				
			||||||
 | 
					  if (fd_audio >= 0)
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::Play(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (fd_audio >= 0)
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
 | 
				
			||||||
 | 
					  if (fd_video >= 0)
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_CONTINUE));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::Freeze(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (fd_audio >= 0)
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
 | 
				
			||||||
 | 
					  if (fd_video >= 0)
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_video, VIDEO_FREEZE));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::Mute(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (fd_audio >= 0) {
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, false));
 | 
				
			||||||
 | 
					     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true));
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::StillPicture(const uchar *Data, int Length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Mute();
 | 
				
			||||||
 | 
					/* Using the VIDEO_STILLPICTURE ioctl call would be the
 | 
				
			||||||
 | 
					   correct way to display a still frame, but unfortunately this
 | 
				
			||||||
 | 
					   doesn't work with frames from VDR. So let's do pretty much the
 | 
				
			||||||
 | 
					   same here as in DVB/driver/dvb.c's play_iframe() - I have absolutely
 | 
				
			||||||
 | 
					   no idea why it works this way, but doesn't work with VIDEO_STILLPICTURE.
 | 
				
			||||||
 | 
					   If anybody ever finds out what could be changed so that VIDEO_STILLPICTURE
 | 
				
			||||||
 | 
					   could be used, please let me know!
 | 
				
			||||||
 | 
					   kls 2002-03-23
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					//#define VIDEO_STILLPICTURE_WORKS_WITH_VDR_FRAMES
 | 
				
			||||||
 | 
					#ifdef VIDEO_STILLPICTURE_WORKS_WITH_VDR_FRAMES
 | 
				
			||||||
 | 
					  videoDisplayStillPicture sp = { (char *)Data, Length };
 | 
				
			||||||
 | 
					  CHECK(ioctl(fd_video, VIDEO_STILLPICTURE, &sp));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define MIN_IFRAME 400000
 | 
				
			||||||
 | 
					  for (int i = MIN_IFRAME / Length + 1; i > 0; i--) {
 | 
				
			||||||
 | 
					      safe_write(fd_video, Data, Length);
 | 
				
			||||||
 | 
					      usleep(1); // allows the buffer to be displayed in case the progress display is active
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cDvbDevice::PlayVideo(const uchar *Data, int Length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (fd_video >= 0)
 | 
				
			||||||
 | 
					     return write(fd_video, Data, Length);
 | 
				
			||||||
 | 
					  return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cDvbDevice::PlayAudio(const uchar *Data, int Length)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  //XXX+
 | 
				
			||||||
 | 
					  return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool cDvbDevice::OpenDvr(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CloseDvr();
 | 
				
			||||||
 | 
					  fd_dvr = OstOpen(DEV_OST_DVR, CardIndex(), O_RDONLY | O_NONBLOCK, true);
 | 
				
			||||||
 | 
					  return fd_dvr >= 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbDevice::CloseDvr(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (fd_dvr >= 0) {
 | 
				
			||||||
 | 
					     close(fd_dvr);
 | 
				
			||||||
 | 
					     fd_dvr = -1;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int cDvbDevice::GetTSPacket(uchar *Data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (fd_dvr >= 0) {
 | 
				
			||||||
 | 
					     pollfd pfd;
 | 
				
			||||||
 | 
					     pfd.fd = fd_dvr;
 | 
				
			||||||
 | 
					     pfd.events = POLLIN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     poll(&pfd, 1, 100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     if (pfd.revents & POLLIN != 0) {
 | 
				
			||||||
 | 
					        int r = read(fd_dvr, Data, TS_SIZE);
 | 
				
			||||||
 | 
					        if (r >= 0)
 | 
				
			||||||
 | 
					           return r;
 | 
				
			||||||
 | 
					        else if (FATALERRNO) {
 | 
				
			||||||
 | 
					           if (errno == EBUFFEROVERFLOW) // this error code is not defined in the library
 | 
				
			||||||
 | 
					              esyslog("ERROR: DVB driver buffer overflow on device %d", CardIndex() + 1);
 | 
				
			||||||
 | 
					           else {
 | 
				
			||||||
 | 
					              LOG_ERROR;
 | 
				
			||||||
 | 
					              return -1;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					           }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					     return 0;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					     return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										97
									
								
								dvbdevice.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								dvbdevice.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * dvbdevice.h: The DVB device interface
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 | 
					 * how to reach the author.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * $Id: dvbdevice.h 1.1 2002/08/04 12:19:10 kls Exp $
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __DVBDEVICE_H
 | 
				
			||||||
 | 
					#define __DVBDEVICE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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>
 | 
				
			||||||
 | 
					#include "device.h"
 | 
				
			||||||
 | 
					#include "eit.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class cDvbDevice : public cDevice {
 | 
				
			||||||
 | 
					  friend class cDvbOsd;
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  static bool Probe(const char *FileName);
 | 
				
			||||||
 | 
					         // Probes for existing DVB devices.
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  static bool Initialize(void);
 | 
				
			||||||
 | 
					         // Initializes the DVB devices.
 | 
				
			||||||
 | 
					         // Must be called before accessing any DVB functions.
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  FrontendType frontendType;
 | 
				
			||||||
 | 
					  int fd_osd, fd_frontend, fd_sec, fd_audio, fd_video, fd_dvr;
 | 
				
			||||||
 | 
					  int OsdDeviceHandle(void) const { return fd_osd; }
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual void MakePrimaryDevice(bool On);
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  cDvbDevice(int n);
 | 
				
			||||||
 | 
					  virtual ~cDvbDevice();
 | 
				
			||||||
 | 
					  virtual bool CanBeReUsed(int Frequency, int Vpid);
 | 
				
			||||||
 | 
					  virtual bool HasDecoder(void) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Channel facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  int frequency;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  virtual bool SetChannelDevice(const cChannel *Channel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PID handle facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Image Grab facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Video format facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  virtual void SetVideoFormat(bool VideoFormat16_9);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Volume facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual void SetVolumeDevice(int Volume);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// EIT facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  cSIProcessor *siProcessor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Player facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual int SetPlayMode(bool On);
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  virtual void TrickSpeed(int Speed);
 | 
				
			||||||
 | 
					  virtual void Clear(void);
 | 
				
			||||||
 | 
					  virtual void Play(void);
 | 
				
			||||||
 | 
					  virtual void Freeze(void);
 | 
				
			||||||
 | 
					  virtual void Mute(void);
 | 
				
			||||||
 | 
					  virtual void StillPicture(const uchar *Data, int Length);
 | 
				
			||||||
 | 
					  virtual int PlayVideo(const uchar *Data, int Length);
 | 
				
			||||||
 | 
					  virtual int PlayAudio(const uchar *Data, int Length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Receiver facilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					  virtual bool OpenDvr(void);
 | 
				
			||||||
 | 
					  virtual void CloseDvr(void);
 | 
				
			||||||
 | 
					  virtual int GetTSPacket(uchar *Data);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //__DVBDEVICE_H
 | 
				
			||||||
							
								
								
									
										13
									
								
								dvbosd.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								dvbosd.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: dvbosd.c 1.17 2002/05/18 13:39:02 kls Exp $
 | 
					 * $Id: dvbosd.c 1.18 2002/08/04 10:13:21 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dvbosd.h"
 | 
					#include "dvbosd.h"
 | 
				
			||||||
@@ -13,10 +13,12 @@
 | 
				
			|||||||
#include <sys/unistd.h>
 | 
					#include <sys/unistd.h>
 | 
				
			||||||
#include "tools.h"
 | 
					#include "tools.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cDvbOsd::cDvbOsd(int OsdDev, int x, int y)
 | 
					const cDvbDevice *cDvbOsd::dvbDevice = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cDvbOsd::cDvbOsd(int x, int y)
 | 
				
			||||||
:cOsdBase(x, y)
 | 
					:cOsdBase(x, y)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  osdDev = OsdDev;
 | 
					  osdDev = dvbDevice ? dvbDevice->OsdDeviceHandle() : -1;
 | 
				
			||||||
  if (osdDev < 0)
 | 
					  if (osdDev < 0)
 | 
				
			||||||
     esyslog("ERROR: illegal OSD device handle (%d)!", osdDev);
 | 
					     esyslog("ERROR: illegal OSD device handle (%d)!", osdDev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -27,6 +29,11 @@ cDvbOsd::~cDvbOsd()
 | 
				
			|||||||
      CloseWindow(GetWindowNr(i));
 | 
					      CloseWindow(GetWindowNr(i));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cDvbOsd::SetDvbDevice(const cDvbDevice *DvbDevice)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  dvbDevice = DvbDevice;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool cDvbOsd::SetWindow(cWindow *Window)
 | 
					bool cDvbOsd::SetWindow(cWindow *Window)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if (Window) {
 | 
					  if (Window) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								dvbosd.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								dvbosd.h
									
									
									
									
									
								
							@@ -4,17 +4,19 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: dvbosd.h 1.13 2002/05/18 13:38:09 kls Exp $
 | 
					 * $Id: dvbosd.h 1.14 2002/08/04 10:12:14 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __DVBOSD_H
 | 
					#ifndef __DVBOSD_H
 | 
				
			||||||
#define __DVBOSD_H
 | 
					#define __DVBOSD_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <ost/osd.h>
 | 
					#include <ost/osd.h>
 | 
				
			||||||
 | 
					#include "dvbdevice.h"
 | 
				
			||||||
#include "osdbase.h"
 | 
					#include "osdbase.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class cDvbOsd : public cOsdBase {
 | 
					class cDvbOsd : public cOsdBase {
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					  static const cDvbDevice *dvbDevice;
 | 
				
			||||||
  int osdDev;
 | 
					  int osdDev;
 | 
				
			||||||
  bool SetWindow(cWindow *Window);
 | 
					  bool SetWindow(cWindow *Window);
 | 
				
			||||||
  void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
 | 
					  void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
 | 
				
			||||||
@@ -26,8 +28,9 @@ protected:
 | 
				
			|||||||
  virtual void MoveWindow(cWindow *Window, int x, int y);
 | 
					  virtual void MoveWindow(cWindow *Window, int x, int y);
 | 
				
			||||||
  virtual void CloseWindow(cWindow *Window);
 | 
					  virtual void CloseWindow(cWindow *Window);
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  cDvbOsd(int OsdDev, int x, int y);
 | 
					  cDvbOsd(int x, int y);
 | 
				
			||||||
  virtual ~cDvbOsd();
 | 
					  virtual ~cDvbOsd();
 | 
				
			||||||
 | 
					  static void SetDvbDevice(const cDvbDevice *DvbDevice);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //__DVBOSD_H
 | 
					#endif //__DVBOSD_H
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								dvbplayer.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								dvbplayer.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: dvbplayer.c 1.7 2002/07/14 14:30:36 kls Exp $
 | 
					 * $Id: dvbplayer.c 1.8 2002/07/27 11:57:48 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dvbplayer.h"
 | 
					#include "dvbplayer.h"
 | 
				
			||||||
@@ -90,6 +90,7 @@ private:
 | 
				
			|||||||
  int replayFile;
 | 
					  int replayFile;
 | 
				
			||||||
  bool eof;
 | 
					  bool eof;
 | 
				
			||||||
  bool active;
 | 
					  bool active;
 | 
				
			||||||
 | 
					  bool running;
 | 
				
			||||||
  ePlayModes playMode;
 | 
					  ePlayModes playMode;
 | 
				
			||||||
  ePlayDirs playDir;
 | 
					  ePlayDirs playDir;
 | 
				
			||||||
  int trickSpeed;
 | 
					  int trickSpeed;
 | 
				
			||||||
@@ -133,6 +134,7 @@ cDvbPlayer::cDvbPlayer(const char *FileName)
 | 
				
			|||||||
  index = NULL;
 | 
					  index = NULL;
 | 
				
			||||||
  eof = false;
 | 
					  eof = false;
 | 
				
			||||||
  active = true;
 | 
					  active = true;
 | 
				
			||||||
 | 
					  running = false;
 | 
				
			||||||
  playMode = pmPlay;
 | 
					  playMode = pmPlay;
 | 
				
			||||||
  playDir = pdForward;
 | 
					  playDir = pdForward;
 | 
				
			||||||
  trickSpeed = NORMAL_SPEED;
 | 
					  trickSpeed = NORMAL_SPEED;
 | 
				
			||||||
@@ -285,8 +287,9 @@ void cDvbPlayer::Activate(bool On)
 | 
				
			|||||||
        Start();
 | 
					        Start();
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
  else if (active) {
 | 
					  else if (active) {
 | 
				
			||||||
     active = false;
 | 
					     running = false;
 | 
				
			||||||
     Cancel(3);
 | 
					     Cancel(3);
 | 
				
			||||||
 | 
					     active = false;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -308,7 +311,8 @@ void cDvbPlayer::Action(void)
 | 
				
			|||||||
  if (readIndex >= 0)
 | 
					  if (readIndex >= 0)
 | 
				
			||||||
     isyslog("resuming replay at index %d (%s)", readIndex, IndexToHMSF(readIndex, true));
 | 
					     isyslog("resuming replay at index %d (%s)", readIndex, IndexToHMSF(readIndex, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while (active && NextFile()) {
 | 
					  running = true;
 | 
				
			||||||
 | 
					  while (running && NextFile()) {
 | 
				
			||||||
        pfd[1].fd = replayFile; // NextFile() may have returned a new file handle!
 | 
					        pfd[1].fd = replayFile; // NextFile() may have returned a new file handle!
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          LOCK_THREAD;
 | 
					          LOCK_THREAD;
 | 
				
			||||||
@@ -414,9 +418,9 @@ void cDvbPlayer::Action(void)
 | 
				
			|||||||
           break;
 | 
					           break;
 | 
				
			||||||
           }
 | 
					           }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					  active = running = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  dsyslog("dvbplayer thread ended (pid=%d)", getpid());
 | 
					  dsyslog("dvbplayer thread ended (pid=%d)", getpid());
 | 
				
			||||||
  active = false;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void cDvbPlayer::Pause(void)
 | 
					void cDvbPlayer::Pause(void)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								eit.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								eit.h
									
									
									
									
									
								
							@@ -16,7 +16,7 @@
 | 
				
			|||||||
 *   the Free Software Foundation; either version 2 of the License, or     *
 | 
					 *   the Free Software Foundation; either version 2 of the License, or     *
 | 
				
			||||||
 *   (at your option) any later version.                                   *
 | 
					 *   (at your option) any later version.                                   *
 | 
				
			||||||
 *                                                                         *
 | 
					 *                                                                         *
 | 
				
			||||||
 * $Id: eit.h 1.16 2002/03/10 10:56:57 kls Exp $
 | 
					 * $Id: eit.h 1.17 2002/08/04 11:30:24 kls Exp $
 | 
				
			||||||
 ***************************************************************************/
 | 
					 ***************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __EIT_H
 | 
					#ifndef __EIT_H
 | 
				
			||||||
@@ -158,7 +158,7 @@ public:
 | 
				
			|||||||
  static bool Read(FILE *f = NULL);
 | 
					  static bool Read(FILE *f = NULL);
 | 
				
			||||||
  void SetStatus(bool On);
 | 
					  void SetStatus(bool On);
 | 
				
			||||||
  void SetCurrentTransponder(int CurrentTransponder);
 | 
					  void SetCurrentTransponder(int CurrentTransponder);
 | 
				
			||||||
  bool SetCurrentServiceID(unsigned short servid);
 | 
					  static bool SetCurrentServiceID(unsigned short servid);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,10 +4,11 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: eitscan.c 1.3 2002/06/22 13:02:40 kls Exp $
 | 
					 * $Id: eitscan.c 1.4 2002/07/28 15:10:23 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "eitscan.h"
 | 
					#include "eitscan.h"
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cEITScanner::cEITScanner(void)
 | 
					cEITScanner::cEITScanner(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								menu.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: menu.c 1.202 2002/07/14 10:55:37 kls Exp $
 | 
					 * $Id: menu.c 1.203 2002/08/03 09:55:44 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "menu.h"
 | 
					#include "menu.h"
 | 
				
			||||||
@@ -1628,7 +1628,7 @@ eOSState cMenuSetupDVB::ProcessKey(eKeys Key)
 | 
				
			|||||||
  if (state == osBack && Key == kOk) {
 | 
					  if (state == osBack && Key == kOk) {
 | 
				
			||||||
     if (Setup.PrimaryDVB != oldPrimaryDVB) {
 | 
					     if (Setup.PrimaryDVB != oldPrimaryDVB) {
 | 
				
			||||||
        state = osSwitchDvb;
 | 
					        state = osSwitchDvb;
 | 
				
			||||||
        cDevice::PrimaryDevice()->SetVideoFormat(Setup.VideoFormat ? VIDEO_FORMAT_16_9 : VIDEO_FORMAT_4_3);
 | 
					        cDevice::PrimaryDevice()->SetVideoFormat(Setup.VideoFormat);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
  return state;
 | 
					  return state;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								osd.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								osd.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: osd.c 1.31 2002/07/14 10:57:45 kls Exp $
 | 
					 * $Id: osd.c 1.32 2002/08/04 10:11:26 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "osd.h"
 | 
					#include "osd.h"
 | 
				
			||||||
@@ -73,7 +73,7 @@ cOsdBase *cOsd::OpenRaw(int x, int y)
 | 
				
			|||||||
#ifdef DEBUG_OSD
 | 
					#ifdef DEBUG_OSD
 | 
				
			||||||
  return NULL;
 | 
					  return NULL;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
  return osd ? NULL : new cDvbOsd(cDevice::PrimaryDevice()->OsdDeviceHandle(), x, y);
 | 
					  return osd ? NULL : new cDvbOsd(x, y);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,18 +4,21 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: receiver.c 1.1 2002/06/08 09:58:29 kls Exp $
 | 
					 * $Id: receiver.c 1.3 2002/07/28 15:14:49 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include "receiver.h"
 | 
					#include "receiver.h"
 | 
				
			||||||
 | 
					#include "tools.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cReceiver::cReceiver(int Ca, int Priority, int NumPids, ...)
 | 
					cReceiver::cReceiver(int Ca, int Priority, int NumPids, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  device = NULL;
 | 
					  device = NULL;
 | 
				
			||||||
  ca = Ca;
 | 
					  ca = Ca;
 | 
				
			||||||
  priority = Priority;
 | 
					  priority = Priority;
 | 
				
			||||||
 | 
					  for (int i = 0; i < MAXRECEIVEPIDS; i++)
 | 
				
			||||||
 | 
					      pids[i] = 0;
 | 
				
			||||||
  if (NumPids) {
 | 
					  if (NumPids) {
 | 
				
			||||||
     va_list ap;
 | 
					     va_list ap;
 | 
				
			||||||
     va_start(ap, NumPids);
 | 
					     va_start(ap, NumPids);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: receiver.h 1.1 2002/06/08 15:32:51 kls Exp $
 | 
					 * $Id: receiver.h 1.2 2002/07/28 11:22:01 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __RECEIVER_H
 | 
					#ifndef __RECEIVER_H
 | 
				
			||||||
@@ -42,6 +42,9 @@ public:
 | 
				
			|||||||
               // the given Priority. NumPids defines the number of PIDs that follow
 | 
					               // 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.
 | 
					               // 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.
 | 
					               // 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();
 | 
					  virtual ~cReceiver();
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								recording.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								recording.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: recording.c 1.64 2002/06/22 10:11:49 kls Exp $
 | 
					 * $Id: recording.c 1.65 2002/07/27 12:55:14 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "recording.h"
 | 
					#include "recording.h"
 | 
				
			||||||
@@ -22,12 +22,24 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define RECEXT       ".rec"
 | 
					#define RECEXT       ".rec"
 | 
				
			||||||
#define DELEXT       ".del"
 | 
					#define DELEXT       ".del"
 | 
				
			||||||
#ifdef VFAT
 | 
					/* This was the original code, which works fine in a Linux only environment.
 | 
				
			||||||
#define DATAFORMAT   "%4d-%02d-%02d.%02d.%02d.%02d.%02d" RECEXT
 | 
					   Unfortunately, because of windows and its brain dead file system, we have
 | 
				
			||||||
#else
 | 
					   to use a more complicated approach, in order to allow users who have enabled
 | 
				
			||||||
 | 
					   the VFAT compile time option to see their recordings even if they forget to
 | 
				
			||||||
 | 
					   enable VFAT when compiling a new version of VDR... Gee, do I hate Windows.
 | 
				
			||||||
 | 
					   (kls 2002-07-27)
 | 
				
			||||||
#define DATAFORMAT   "%4d-%02d-%02d.%02d:%02d.%02d.%02d" RECEXT
 | 
					#define DATAFORMAT   "%4d-%02d-%02d.%02d:%02d.%02d.%02d" RECEXT
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#define NAMEFORMAT   "%s/%s/" DATAFORMAT
 | 
					#define NAMEFORMAT   "%s/%s/" DATAFORMAT
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					// start of implementation for brain dead systems
 | 
				
			||||||
 | 
					#define DATAFORMAT   "%4d-%02d-%02d.%02d%*c%02d.%02d.%02d" RECEXT
 | 
				
			||||||
 | 
					#ifdef VFAT
 | 
				
			||||||
 | 
					#define nameFORMAT   "%4d-%02d-%02d.%02d.%02d.%02d.%02d" RECEXT
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define nameFORMAT   "%4d-%02d-%02d.%02d:%02d.%02d.%02d" RECEXT
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define NAMEFORMAT   "%s/%s/" nameFORMAT
 | 
				
			||||||
 | 
					// end of implementation for brain dead systems
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RESUMEFILESUFFIX  "/resume.vdr"
 | 
					#define RESUMEFILESUFFIX  "/resume.vdr"
 | 
				
			||||||
#define SUMMARYFILESUFFIX "/summary.vdr"
 | 
					#define SUMMARYFILESUFFIX "/summary.vdr"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								remux.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								remux.h
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: remux.h 1.5 2001/06/23 14:06:59 kls Exp $
 | 
					 * $Id: remux.h 1.6 2002/08/04 10:27:07 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __REMUX_H
 | 
					#ifndef __REMUX_H
 | 
				
			||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <time.h> //XXX FIXME: DVB/ost/include/ost/dmx.h should include <time.h> itself!!!
 | 
					#include <time.h> //XXX FIXME: DVB/ost/include/ost/dmx.h should include <time.h> itself!!!
 | 
				
			||||||
#include <ost/dmx.h>
 | 
					#include <ost/dmx.h>
 | 
				
			||||||
 | 
					#include "tools.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Picture types:
 | 
					// Picture types:
 | 
				
			||||||
#define NO_PICTURE 0
 | 
					#define NO_PICTURE 0
 | 
				
			||||||
@@ -24,7 +25,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define RESULTBUFFERSIZE (MINVIDEODATA * 4)
 | 
					#define RESULTBUFFERSIZE (MINVIDEODATA * 4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef unsigned char uchar;
 | 
					 | 
				
			||||||
class cTS2PES;
 | 
					class cTS2PES;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class cRemux {
 | 
					class cRemux {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,10 +7,11 @@
 | 
				
			|||||||
 * Parts of this file were inspired by the 'ringbuffy.c' from the
 | 
					 * Parts of this file were inspired by the 'ringbuffy.c' from the
 | 
				
			||||||
 * LinuxDVB driver (see linuxtv.org).
 | 
					 * LinuxDVB driver (see linuxtv.org).
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: ringbuffer.c 1.9 2002/06/16 11:24:40 kls Exp $
 | 
					 * $Id: ringbuffer.c 1.10 2002/07/28 12:47:32 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ringbuffer.h"
 | 
					#include "ringbuffer.h"
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include "tools.h"
 | 
					#include "tools.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,15 +4,14 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: ringbuffer.h 1.6 2002/06/16 11:30:07 kls Exp $
 | 
					 * $Id: ringbuffer.h 1.7 2002/08/04 10:27:30 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __RINGBUFFER_H
 | 
					#ifndef __RINGBUFFER_H
 | 
				
			||||||
#define __RINGBUFFER_H
 | 
					#define __RINGBUFFER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "thread.h"
 | 
					#include "thread.h"
 | 
				
			||||||
 | 
					#include "tools.h"
 | 
				
			||||||
typedef unsigned char uchar;//XXX+
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class cRingBuffer {
 | 
					class cRingBuffer {
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								tools.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tools.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
 * See the main source file 'vdr.c' for copyright information and
 | 
					 * See the main source file 'vdr.c' for copyright information and
 | 
				
			||||||
 * how to reach the author.
 | 
					 * how to reach the author.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: tools.c 1.67 2002/05/18 15:10:45 kls Exp $
 | 
					 * $Id: tools.c 1.68 2002/08/03 15:44:53 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tools.h"
 | 
					#include "tools.h"
 | 
				
			||||||
@@ -407,7 +407,7 @@ bool RemoveEmptyDirectories(const char *DirName, bool RemoveThis)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
char *ReadLink(const char *FileName)
 | 
					char *ReadLink(const char *FileName)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  char RealName[_POSIX_PATH_MAX];
 | 
					  char RealName[PATH_MAX];
 | 
				
			||||||
  const char *TargetName = NULL;
 | 
					  const char *TargetName = NULL;
 | 
				
			||||||
  int n = readlink(FileName, RealName, sizeof(RealName) - 1);
 | 
					  int n = readlink(FileName, RealName, sizeof(RealName) - 1);
 | 
				
			||||||
  if (n < 0) {
 | 
					  if (n < 0) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								vdr.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								vdr.c
									
									
									
									
									
								
							@@ -22,7 +22,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * The project's page is at http://www.cadsoft.de/people/kls/vdr
 | 
					 * The project's page is at http://www.cadsoft.de/people/kls/vdr
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: vdr.c 1.117 2002/06/23 11:23:34 kls Exp $
 | 
					 * $Id: vdr.c 1.118 2002/08/04 09:56:30 kls Exp $
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <getopt.h>
 | 
					#include <getopt.h>
 | 
				
			||||||
@@ -33,6 +33,7 @@
 | 
				
			|||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
#include "cutter.h"
 | 
					#include "cutter.h"
 | 
				
			||||||
#include "device.h"
 | 
					#include "device.h"
 | 
				
			||||||
 | 
					#include "dvbdevice.h"
 | 
				
			||||||
#include "eitscan.h"
 | 
					#include "eitscan.h"
 | 
				
			||||||
#include "i18n.h"
 | 
					#include "i18n.h"
 | 
				
			||||||
#include "interface.h"
 | 
					#include "interface.h"
 | 
				
			||||||
@@ -326,11 +327,9 @@ int main(int argc, char *argv[])
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // DVB interfaces:
 | 
					  // DVB interfaces:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!cDevice::Initialize())
 | 
					  if (!cDvbDevice::Initialize())
 | 
				
			||||||
     return 2;
 | 
					     return 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cDevice::SetPrimaryDevice(Setup.PrimaryDVB);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  cSIProcessor::Read();
 | 
					  cSIProcessor::Read();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Start plugins:
 | 
					  // Start plugins:
 | 
				
			||||||
@@ -338,6 +337,10 @@ int main(int argc, char *argv[])
 | 
				
			|||||||
  if (!PluginManager.StartPlugins())
 | 
					  if (!PluginManager.StartPlugins())
 | 
				
			||||||
     return 2;
 | 
					     return 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Primary device:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  cDevice::SetPrimaryDevice(Setup.PrimaryDVB);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // OSD:
 | 
					  // OSD:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cOsd::Initialize();
 | 
					  cOsd::Initialize();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user