[vlc-commits] DTV: read TS feed old-style from the monolithic DVR
Rémi Denis-Courmont
git at videolan.org
Sun Mar 20 13:57:00 CET 2011
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Mar 20 14:55:51 2011 +0200| [6232d987722bd52a9062841399278a44b4b7ec1f] | committer: Rémi Denis-Courmont
DTV: read TS feed old-style from the monolithic DVR
It seems that DMX_ADD_PID does not work. So revert back to the
non-shared DVR node, unless budget mode is enabled.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6232d987722bd52a9062841399278a44b4b7ec1f
---
modules/access/dtv/linux.c | 134 +++++++++++++++++++++++++++++++++++--------
1 files changed, 109 insertions(+), 25 deletions(-)
diff --git a/modules/access/dtv/linux.c b/modules/access/dtv/linux.c
index 6df92fb..de98803 100644
--- a/modules/access/dtv/linux.c
+++ b/modules/access/dtv/linux.c
@@ -159,6 +159,16 @@ struct dvb_device
vlc_object_t *obj;
int frontend;
int demux;
+#ifndef USE_DMX
+# define MAX_PIDS 256
+ int dir;
+ uint8_t dev_id;
+ struct
+ {
+ int fd;
+ uint16_t pid;
+ } pids[MAX_PIDS];
+#endif
int ca;
struct dvb_frontend_info info;
bool budget;
@@ -188,26 +198,28 @@ dvb_device_t *dvb_open (vlc_object_t *obj, bool tune)
}
d->obj = obj;
-
- d->demux = dvb_open_node (dirfd, device, "demux", O_RDONLY);
- if (d->demux == -1)
- {
- msg_Err (obj, "cannot access demux %"PRIu8" of adapter %"PRIu8": %m",
- device, adapter);
- free (d);
- close (dirfd);
- return NULL;
- }
-
- /* Use the same size as socket receive buffer. This is enough for IPTV so
- * it should be enough for DVB too. */
- if (ioctl (d->demux, DMX_SET_BUFFER_SIZE, 1 << 18) < 0)
- msg_Warn (obj, "cannot expand demultiplexing buffer: %m");
-
- /* We need to filter at least one PID. The tap for TS demultiplexing cannot
- * be configured otherwise. So add the PAT. */
+ d->frontend = -1;
+ d->ca = -1;
d->budget = var_InheritBool (obj, "dvb-budget-mode");
+
+#ifndef USE_DMX
+ if (d->budget)
+#endif
{
+ d->demux = dvb_open_node (dirfd, device, "demux", O_RDONLY);
+ if (d->demux == -1)
+ {
+ msg_Err (obj, "cannot access demultiplexer: %m");
+ free (d);
+ close (dirfd);
+ return NULL;
+ }
+
+ if (ioctl (d->demux, DMX_SET_BUFFER_SIZE, 1 << 20) < 0)
+ msg_Warn (obj, "cannot expand demultiplexing buffer: %m");
+
+ /* We need to filter at least one PID. The tap for TS demultiplexing
+ * cannot be configured otherwise. So add the PAT. */
struct dmx_pes_filter_params param;
param.pid = d->budget ? 0x2000 : 0x000;
@@ -217,12 +229,28 @@ dvb_device_t *dvb_open (vlc_object_t *obj, bool tune)
param.flags = DMX_IMMEDIATE_START;
if (ioctl (d->demux, DMX_SET_PES_FILTER, ¶m) < 0)
{
- msg_Err (obj, "cannot setup TS demultiplexer");
+ msg_Err (obj, "cannot setup TS demultiplexer: %m");
goto error;
}
+#ifndef USE_DMX
+ }
+ else
+ {
+ d->dir = fcntl (dirfd, F_DUPFD_CLOEXEC);
+ d->dev_id = device;
+
+ for (size_t i = 0; i < MAX_PIDS; i++)
+ d->pids[i].pid = d->pids[i].fd = -1;
+ d->demux = dvb_open_node (d->dir, device, "dvr", O_RDONLY);
+ if (d->demux == -1)
+ {
+ msg_Err (obj, "cannot access DVR: %m");
+ free (d);
+ close (dirfd);
+ return NULL;
+ }
+#endif
}
- d->frontend = -1;
- d->ca = -1;
if (tune)
{
@@ -260,6 +288,15 @@ error:
void dvb_close (dvb_device_t *d)
{
+#ifndef USE_DMX
+ if (!d->budget)
+ {
+ close (d->dir);
+ for (size_t i = 0; i < MAX_PIDS; i++)
+ if (d->pids[i].fd != -1)
+ close (d->pids[i].fd);
+ }
+#endif
if (d->ca != -1)
close (d->ca);
if (d->frontend != -1)
@@ -330,19 +367,66 @@ ssize_t dvb_read (dvb_device_t *d, void *buf, size_t len)
int dvb_add_pid (dvb_device_t *d, uint16_t pid)
{
- if (d->budget || pid == 0)
+ if (d->budget)
return 0;
- if (ioctl (d->demux, DMX_ADD_PID, &pid) >= 0)
+#ifdef USE_DMX
+ if (pid == 0 || ioctl (d->demux, DMX_ADD_PID, &pid) >= 0)
return 0;
+#else
+ for (size_t i = 0; i < MAX_PIDS; i++)
+ {
+ if (d->pids[i].pid == pid)
+ return 0;
+ if (d->pids[i].fd != -1)
+ continue;
+
+ int fd = dvb_open_node (d->dir, d->dev_id, "demux", O_RDONLY);
+ if (fd == -1)
+ goto error;
+
+ /* We need to filter at least one PID. The tap for TS demultiplexing
+ * cannot be configured otherwise. So add the PAT. */
+ struct dmx_pes_filter_params param;
+
+ param.pid = pid;
+ param.input = DMX_IN_FRONTEND;
+ param.output = DMX_OUT_TS_TAP;
+ param.pes_type = DMX_PES_OTHER;
+ param.flags = DMX_IMMEDIATE_START;
+ if (ioctl (fd, DMX_SET_PES_FILTER, ¶m) < 0)
+ {
+ close (fd);
+ goto error;
+ }
+ d->pids[i].fd = fd;
+ d->pids[i].pid = pid;
+ return 0;
+ }
+ errno = EMFILE;
+error:
+#endif
msg_Err (d->obj, "cannot add PID 0x%04"PRIu16": %m", pid);
return -1;
}
void dvb_remove_pid (dvb_device_t *d, uint16_t pid)
{
- if (d->budget || pid == 0)
+ if (d->budget)
return;
- ioctl (d->demux, DMX_REMOVE_PID, &pid);
+#ifdef USE_DMX
+ if (pid != 0)
+ ioctl (d->demux, DMX_REMOVE_PID, &pid);
+#else
+ for (size_t i = 0; i < MAX_PIDS; i++)
+ {
+ if (d->pids[i].pid == pid)
+ {
+ close (d->pids[i].fd);
+ d->pids[i].pid = d->pids[i].fd = -1;
+ return;
+ }
+ }
+#endif
}
const delsys_t *dvb_guess_system (dvb_device_t *d)
More information about the vlc-commits
mailing list