9.2. The DVR device

The following program code shows how to use the DVR device for recording.

 #include <sys/ioctl.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <time.h>
 #include <unistd.h>

 #include <linux/dvb/dmx.h>
 #include <linux/dvb/video.h>
 #include <sys/poll.h>
 #define DVR "/dev/dvb/adapter0/dvr1"
 #define AUDIO "/dev/dvb/adapter0/audio1"
 #define VIDEO "/dev/dvb/adapter0/video1"

 #define BUFFY (188⋆20)
 #define MAX_LENGTH (1024⋆1024⋆5) /⋆ record 5MB ⋆/


 /⋆ switch the demuxes to recording, assuming the transponder is tuned ⋆/

 /⋆ demux1, demux2: file descriptor of video and audio filters ⋆/
 /⋆ vpid, apid:     PIDs of video and audio channels           ⋆/

 int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
 {
	 struct dmx_pes_filter_params pesFilterParams;

	 if (demux1 < 0){
		 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
		     < 0){
			 perror("DEMUX DEVICE: ");
			 return -1;
		 }
	 }

	 if (demux2 < 0){
		 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
		     < 0){
			 perror("DEMUX DEVICE: ");
			 return -1;
		 }
	 }

	 pesFilterParams.pid = vpid;
	 pesFilterParams.input = DMX_IN_FRONTEND;
	 pesFilterParams.output = DMX_OUT_TS_TAP;
	 pesFilterParams.pes_type = DMX_PES_VIDEO;
	 pesFilterParams.flags = DMX_IMMEDIATE_START;
	 if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
		 perror("DEMUX DEVICE");
		 return -1;
	 }
	 pesFilterParams.pid = apid;
	 pesFilterParams.input = DMX_IN_FRONTEND;
	 pesFilterParams.output = DMX_OUT_TS_TAP;
	 pesFilterParams.pes_type = DMX_PES_AUDIO;
	 pesFilterParams.flags = DMX_IMMEDIATE_START;
	 if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
		 perror("DEMUX DEVICE");
		 return -1;
	 }
	 return 0;
 }

 /⋆ start recording MAX_LENGTH , assuming the transponder is tuned ⋆/

 /⋆ demux1, demux2: file descriptor of video and audio filters ⋆/
 /⋆ vpid, apid:     PIDs of video and audio channels           ⋆/
 int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
 {
	 int i;
	 int len;
	 int written;
	 uint8_t buf[BUFFY];
	 uint64_t length;
	 struct pollfd pfd[1];
	 int dvr, dvr_out;

	 /⋆ open dvr device ⋆/
	 if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){
			 perror("DVR DEVICE");
			 return -1;
	 }

	 /⋆ switch video and audio demuxes to dvr ⋆/
	 printf ("Switching dvr on\n");
	 i = switch_to_record(demux1, demux2, vpid, apid);
	 printf("finished: ");

	 printf("Recording %2.0f MB of test file in TS format\n",
		MAX_LENGTH/(1024.0⋆1024.0));
	 length = 0;

	 /⋆ open output file ⋆/
	 if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
				  |O_TRUNC, S_IRUSR|S_IWUSR
				  |S_IRGRP|S_IWGRP|S_IROTH|
				  S_IWOTH)) < 0){
		 perror("Can't open file for dvr test");
		 return -1;
	 }

	 pfd[0].fd = dvr;
	 pfd[0].events = POLLIN;

	 /⋆ poll for dvr data and write to file ⋆/
	 while (length < MAX_LENGTH ) {
		 if (poll(pfd,1,1)){
			 if (pfd[0].revents & POLLIN){
				 len = read(dvr, buf, BUFFY);
				 if (len < 0){
					 perror("recording");
					 return -1;
				 }
				 if (len > 0){
					 written = 0;
					 while (written < len)
						 written +=
							 write (dvr_out,
								buf, len);
					 length += len;
					 printf("written %2.0f MB\r",
						length/1024./1024.);
				 }
			 }
		 }
	 }
	 return 0;
 }