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