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