Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] Help on use of DMX_OUT_TAP (II)
A while ago I sent an email about a problem I was having when demuxing
video and audio streams. I'm still having the problem, so now I have
simplified the problem down to a small test program. I have attached the
program to the end of this email, and I hope that using it my problem is
easily reproduced. I have tried the code using latest CVS drivers, and the
latest released drivers; both produce the same results. I'm hoping the
problem lies with a mistake in my code, but I suppose there could be a bug
in the DVB driver.
I am trying to demux a video stream and an audio stream and read them from
their demux file descriptors (using DMX_OUT_TAP in the filter settings).
In this situation I get errors on the video stream. The log is also
attached to this email. Note that if I enable the filters but use
DMX_OUT_TS_TAP and read from dvr0, all is ok.
The errors don't seem to go away whatever size I make my buffer (I've
tried from 16 bytes up to 64KB). In addition, the PC I'm running it on is
pretty fast, so I think it can keep up with the data rate. It certainly
has no problems when I read from dvr0. I have a Nova-t card by the way.
I also have one more small question if I may: Is it recommended that you
read data in this way (ie. demuxing and reading streams separately). Are
there any implications for keeping audio and video in sync? I want to read
from more than one channel at once so this is why I don't use dvr0.
Any help on this problem would be much appreciated, thanks,
James.
The code can be compiled with:
gcc -I...path_to_dvb_code.../include/linux/dvb/ ../test.cc
Note that you may need to change the PIDs for your set-up and tune the
card in before running it (PIDs are currently 600 and 601 at the start of
main()). I do the tuning by running dvbstream beforehand.
/***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dmx.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define DVB_LOG_ERROR(error, str) ( printf str, printf("\n"), error )
static int open_stream(unsigned int pid, dmx_pes_type_t type)
{
int flags = O_RDWR;
if (type == DMX_PES_AUDIO) flags |= O_NONBLOCK;
int fd = open("/dev/dvb/adapter0/demux0", flags);
if (fd < 0) DVB_LOG_ERROR(0, ("%s: Failed to open demux device for PID %d.", __FUNCTION__, pid));
/* Now we set the filters */
struct dmx_pes_filter_params pesFilterParams;
pesFilterParams.pid = (uint16_t)pid;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_TAP;
pesFilterParams.pes_type = type;
pesFilterParams.flags = DMX_IMMEDIATE_START;
int status;
if ((status = ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams)) < 0) {
close(fd);
perror("Error:");
return DVB_LOG_ERROR(0, ("%s: Failed to set filters for PID %d (status %d).", __FUNCTION__, pid, status));
}
return fd;
}
int main(int argc, char* argv[]) {
/* Open streams. */
uint8_t buf[1 * 1024];
int video_fd = open_stream(600, DMX_PES_VIDEO);
int audio_fd = open_stream(601, DMX_PES_AUDIO);
if ((video_fd < 0) || (audio_fd < 0)) return 1;
/* Read from streams. */
printf("Buf size is %d, video_fd=%d, audio_fd=%d.\n", sizeof(buf), video_fd, audio_fd);
while (1) {
int bytes;
/* Video. */
bytes = read(video_fd, buf, sizeof(buf));
if (bytes < 0) {
fprintf(stderr, "Errno %d: ", errno);
perror("video_fd read");
} else {
fprintf(stderr, "Read %d bytes from video_fd.\n", bytes);
}
/* Audio. */
bytes = read(audio_fd, buf, sizeof(buf));
if (bytes < 0) {
if (errno != EAGAIN) {
fprintf(stderr, "Errno %d: ", errno);
perror("audio_fd read");
}
} else {
fprintf(stderr, "Read %d bytes from audio_fd.\n", bytes);
}
}
}
/***********************************************************************/
Output when I run it:
Buf size is 1024, video_fd=3, audio_fd=4.
Errno 75: video_fd read: Value too large for defined data type
Read 1024 bytes from audio_fd.
Read 1024 bytes from video_fd.
Read 416 bytes from audio_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 540 bytes from audio_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 888 bytes from audio_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 902 bytes from audio_fd.
Read 1024 bytes from video_fd.
Read 540 bytes from audio_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 360 bytes from audio_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 720 bytes from audio_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 1024 bytes from audio_fd.
Read 1024 bytes from video_fd.
Read 416 bytes from audio_fd.
Read 1024 bytes from video_fd.
Read 1024 bytes from video_fd.
etc.
--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe linux-dvb" as subject.
Home |
Main Index |
Thread Index