V4l api - need some help getting dvb devices to work

Da Rock freebsd-multimedia at herveybayaustralia.com.au
Wed Oct 7 02:51:31 UTC 2015


I'm trying to get a handle on the v4l api - specifically dvb devices. 
I've hunted up as much in tutorials as I can, but I cannot seem to get a 
working system. Mind you I'm just trying to get my feet at this point, 
and so the code I'm working on is testing only - an app will come later 
once I get clear in my head.

One thing I am wondering is if there isn't something in the FreeBSD 
implementation that might be stopping things from working correctly - 
though I don't know why.

I started with the code from the tutorial, and I got the frontend setup 
correctly and tuned. What I need to get working is the dvr device. My 
aim is to get a full ts stream for ffmpeg or other to mux into 
respective streams and processing. This means I need to use pid 8192 to 
be filtered. tzap is incapable of this, as it relies entirely on the 
apid and vpid, and ignores the sid.

Once I got the frontend setup, it took me a while to figure out how to 
set the pid's and demux use, but I finally got there and I have that set 
as well; but still the dvr won't work.

This is the code (based from 
http://linuxtv.org/downloads/v4l-dvb-apis/frontend-properties.html, and 
some of tzap code):


#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/dmx.h>

static struct dtv_property props[] = {
     { .cmd = DTV_DELIVERY_SYSTEM, .u.data = SYS_DVBT },
     { .cmd = DTV_FREQUENCY,       .u.data = 177500000 },
     { .cmd = DTV_MODULATION,      .u.data = QAM_64 },
     { .cmd = DTV_INVERSION,       .u.data = INVERSION_AUTO },
     { .cmd = DTV_SYMBOL_RATE,     .u.data = 7000000 },
     { .cmd = DTV_INNER_FEC,       .u.data = FEC_3_4 },
     { .cmd = DTV_TUNE }
};

static struct dtv_properties dtv_prop = {
     .num = 6, .props = props
};


static void print_frontend_stats(int fe_fd, int human_readable)
{
     fe_status_t status;
     uint16_t snr, _signal;
     uint32_t ber, uncorrected_blocks;

     ioctl(fe_fd, FE_READ_STATUS, &status);
     ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &_signal);
     ioctl(fe_fd, FE_READ_SNR, &snr);
     ioctl(fe_fd, FE_READ_BER, &ber);
     ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks);

     if (human_readable) {
         printf ("status %02x | signal %3u%% | snr %3u%% | ber %d | unc 
%d | ",
             status, (_signal * 100) / 0xffff, (snr * 100) / 0xffff, 
ber, uncorrected_blocks);
     } else {
         fprintf (stderr, "status %02x | signal %04x | snr %04x | ber 
%08x | unc %08x | ",
             status, _signal, snr, ber, uncorrected_blocks);
     }

     if (status & FE_HAS_LOCK)
         //fprintf(stderr,"FE_HAS_LOCK");
         printf("FE_HAS_LOCK");

     //fprintf(stderr,"\n");
     printf("\n");
}

int main(void)
{
     int fd = open("/dev/dvb/adapter0/frontend0", O_RDWR);
     int dd = open("/dev/dvb/adapter0/demux0", O_RDWR);
     int buffersize = 64 * 100 * 1024;

     struct dmx_pes_filter_params pesfilter;
     pesfilter.pid = 8192;
     pesfilter.input = DMX_IN_FRONTEND;
     pesfilter.output = DMX_OUT_TS_TAP;
     pesfilter.pes_type = DMX_PES_OTHER;
     pesfilter.flags = DMX_IMMEDIATE_START;

     if (!fd) {
         perror ("open");
         return -1;
     }
     if (ioctl(fd, FE_SET_PROPERTY, &dtv_prop) < 0) {
         perror("ioctl");
         return -1;
     }
     printf("Frontend set\n");

     if (!dd) {
         perror("open");
         return -1;
     }
     if (ioctl(dd, DMX_SET_BUFFER_SIZE, buffersize) < 0) {
         perror("DMX_SET_BUFFER_SIZE failed");
     }
     if (ioctl(dd, DMX_SET_PES_FILTER, &pesfilter) < 0) {
         perror("Set PES Filter failed");
         return -1;
     }
     if (ioctl(dd, DMX_START) < 0) {
         perror("DMX_STOP");
         return -1;
     }

     while (1) {
         print_frontend_stats(fd, 1);
         sleep (1);
     }

     return 0;
}

Could anyone provide some guidance on what is wrong here? Have I not got 
the concept correctly? Where could I find some good tutorials on v4l?


More information about the freebsd-multimedia mailing list