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