Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] Re: Help on use of DMX_OUT_TAP (II)
On Mon, 2 Jun 2003, Johannes Stezenbach wrote:
> [Code fragment removed]
> This can't work. You must use select() or poll() to wait for
> data to arrive, then read() from the file descriptor which is ready.
I changed my code to use select() and exactly the same happens. I'm
beginning to suspect some bug in the DVB driver code.
But, I have discovered an interesting phenomenon by changing the size of
the buffer I pass into read(). The smaller I make the buffer the fewer
overrun errors I receive, for example if I make the buffer size 512 bytes,
I receive 9KB of valid data and then an overrun error (and then the cycle
begins again and I get 9KB of valid data). For a 1024 byte buffer size I
receive 9KB of valid data but I get several overrun errors in a block, and
then the cycle repeats. For a 2048 byte buffer size I just get a continual
stream of errors.
Note that when I talk about these errors they're all on the video stream;
the audio stream is always fine.
What is special about ~9KB?
If nobody can see a problem with my code, I'm wondering if the DVB driver
has a problem with its buffering code?
Any help would be greatly received,
James.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here's my latest code:
/* Compile using: gcc -I...path_to_DVB.../include/linux/dvb/ test.cc */
#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 )
#define MAX(a, b) (((a)>(b))?(a):(b))
static int open_stream(unsigned int pid, dmx_pes_type_t type)
{
int flags = O_RDWR;
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[512];
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;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(video_fd, &readfds);
FD_SET(audio_fd, &readfds);
int sel = select(MAX(video_fd, audio_fd) + 1, &readfds, NULL, &readfds, NULL);
if (FD_ISSET(video_fd, &readfds)) {
/* 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);
}
} else if (FD_ISSET(audio_fd, &readfds)) {
/* Audio. */
bytes = read(audio_fd, buf, sizeof(buf));
if (bytes < 0) {
fprintf(stderr, "Errno %d: ", errno);
perror("audio_fd read");
} else {
fprintf(stderr, "Read %d bytes from audio_fd.\n", bytes);
}
} else {
fprintf(stderr, "Select returned nothing?\n");
}
}
}
and the output is typically:
Buf size is 512, video_fd=3, audio_fd=4.
Errno 75: video_fd read: Value too large for defined data type
Read 512 bytes from audio_fd.
Read 512 bytes from audio_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 512 bytes from audio_fd.
Read 512 bytes from audio_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 512 bytes from audio_fd.
Read 512 bytes from audio_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 512 bytes from audio_fd.
Read 512 bytes from audio_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 512 bytes from audio_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Read 512 bytes from video_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 512 bytes from audio_fd.
Read 512 bytes from audio_fd.
Errno 75: video_fd read: Value too large for defined data type
Read 512 bytes from audio_fd.
Read 512 bytes from audio_fd.
etc.
--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe linux-dvb" as subject.
Home |
Main Index |
Thread Index