diff mbox

dvb-apps: add test tool for DMX_OUT_TSDEMUX_TAP

Message ID 20110710124303.26655303@susi.home.s3e.de (mailing list archive)
State Not Applicable
Headers show

Commit Message

Stefan Seyfried July 10, 2011, 10:43 a.m. UTC
Hi all,

I patched test_dvr to use DMX_OUT_TSDEMUX_TAP and named it test_tapdmx.
Might be useful for others, too :-)
This is my first experience with mercurial, so bear with me if it's
totally wrong.

Best regards,

	Stefan

(attached in case the mailer screws it up)

# HG changeset patch
# User Stefan Seyfried <seife+dvb@b1-systems.com>
# Date 1310293978 -7200
# Node ID 0326ba8a015935abfd95f2909abd0d357a4be547
# Parent  148ede2a6809766a4ba4dd29bac896b3291b3efe
add test_tapdmx, like test_dvr but using DMX_OUT_TSDEMUX_TAP

Comments

Rémi Denis-Courmont July 10, 2011, 1:45 p.m. UTC | #1
Le dimanche 10 juillet 2011 13:43:03 Stefan Seyfried, vous avez écrit :
> Hi all,
> 
> I patched test_dvr to use DMX_OUT_TSDEMUX_TAP and named it test_tapdmx.
> Might be useful for others, too :-)
> This is my first experience with mercurial, so bear with me if it's
> totally wrong.

Did it work for you? We at VideoLAN.org could not get DMX_OUT_TSDEMUX_TAP to 
work with any of three distinct device/drivers (on two different delivery 
systems). We do get TS packets, but they seem to be partly corrupt.
Stefan Seyfried July 10, 2011, 7:37 p.m. UTC | #2
Am Sun, 10 Jul 2011 16:45:46 +0300
schrieb "Rémi Denis-Courmont" <remi@remlab.net>:

> Le dimanche 10 juillet 2011 13:43:03 Stefan Seyfried, vous avez écrit :
> > Hi all,
> > 
> > I patched test_dvr to use DMX_OUT_TSDEMUX_TAP and named it test_tapdmx.
> > Might be useful for others, too :-)
> > This is my first experience with mercurial, so bear with me if it's
> > totally wrong.
> 
> Did it work for you? We at VideoLAN.org could not get DMX_OUT_TSDEMUX_TAP to 
> work with any of three distinct device/drivers (on two different delivery 
> systems). We do get TS packets, but they seem to be partly corrupt.

Yes, worked today on plain openSUSE Factory, kernel 3.0.0-rc5-1-desktop

I did read your post to the list and actually looked up on how to use the
interface in the vlc code you linked ;-).

My device is a TeVii S660 USB DVB-S2

usb 2-1: New USB device found, idVendor=9022, idProduct=d660
usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 2-1: Product: DVBS2BOX
usb 2-1: Manufacturer: TBS-Tech
dvb-usb: found a 'TeVii S660 USB' in cold state, will try to load a firmware

I successfully recorded an audio and a video PID from Astra 19.2E
transponder 11836 MHz horizontal

Trying to record the complete TS (pid 0x2000) did produce dropouts, but
that might be due to insufficient buffer size or something like that.

In general the DMX_OUT_TSDEMUX_TAP interface worked well.

Just try it with my test_tapdmx :-)
HoP July 10, 2011, 11:17 p.m. UTC | #3
2011/7/10 Rémi Denis-Courmont <remi@remlab.net>:
> Le dimanche 10 juillet 2011 13:43:03 Stefan Seyfried, vous avez écrit :
>> Hi all,
>>
>> I patched test_dvr to use DMX_OUT_TSDEMUX_TAP and named it test_tapdmx.
>> Might be useful for others, too :-)
>> This is my first experience with mercurial, so bear with me if it's
>> totally wrong.
>
> Did it work for you? We at VideoLAN.org could not get DMX_OUT_TSDEMUX_TAP to
> work with any of three distinct device/drivers (on two different delivery
> systems). We do get TS packets, but they seem to be partly corrupt.

DMX_OUT_TSDEMUX_TAP works for me also. It worked well even
in 2.6.22 kernel with backported dvb_core from 2.6.28.

Honza
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

# HG changeset patch
# User Stefan Seyfried <seife+dvb@b1-systems.com>
# Date 1310293978 -7200
# Node ID 0326ba8a015935abfd95f2909abd0d357a4be547
# Parent  148ede2a6809766a4ba4dd29bac896b3291b3efe
add test_tapdmx, like test_dvr but using DMX_OUT_TSDEMUX_TAP

diff --git a/test/Makefile b/test/Makefile
--- a/test/Makefile
+++ b/test/Makefile
@@ -10,6 +10,7 @@ 
            test_av         \
            test_av_play    \
            test_dvr        \
+           test_tapdmx     \
            test_dvr_play   \
            test_pes        \
            test_sec_ne     \
diff --git a/test/test_tapdmx.c b/test/test_tapdmx.c
new file mode 100644
--- /dev/null
+++ b/test/test_tapdmx.c
@@ -0,0 +1,160 @@ 
+/* test_tapdmx.c - Test recording a TS from the dmx device.
+ * very similar to test_dvr but using the new DMX_OUT_TSDEMUX_TAP
+ * usage: test_tapdmx PID [more PIDs...]
+ *
+ * test_dvr is
+ *   Copyright (C) 2003 convergence GmbH
+ *   Johannes Stezenbach <js@convergence.de>
+ * test_tapdmx conversion is
+ *   Copyright (C) 2011 B1 Systems GmbH
+ *   Stefan Seyfried <seife+dvb@b1-systems.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+//hm, I haven't tested writing large files yet... maybe it works
+#define _LARGEFILE64_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <linux/dvb/dmx.h>
+
+static unsigned long BUF_SIZE = 64 * 1024;
+static unsigned long long total_bytes;
+
+static void usage(void)
+{
+	fprintf(stderr, "usage: test_tapdmx file PID [more PIDs...]\n"
+			"       record a partial TS stream consisting of TS packets\n"
+			"       with the selected PIDs to the given file.\n"
+			"       Use PID 0x2000 to record the full TS stream (if\n"
+			"       the hardware supports it).\n"
+			"       The demux device used can be changed by setting\n"
+			"       the environment variable DEMUX.\n"
+			"       You can override the input buffer size by setting BUF_SIZE to\n"
+			"       the number of bytes wanted.\n"
+			"       Note: There is no output buffering, so writing to stdout is\n"
+			"       not really supported, but you can try something like:\n"
+			"       BUF_SIZE=188 ./test_tapdmx /dev/stdout 0 2>/dev/null | xxd\n"
+			"       ./test_tapdmx /dev/stdout 0x100 0x110 2>/dev/null| xine stdin://mpeg2\n"
+			"\n");
+	exit(1);
+}
+
+
+static void process_data(int dvrfd, int tsfd)
+{
+	uint8_t buf[BUF_SIZE];
+	int bytes, b2;
+
+	bytes = read(dvrfd, buf, sizeof(buf));
+	if (bytes < 0) {
+		perror("read");
+		if (errno == EOVERFLOW)
+			return;
+		fprintf(stderr, "exiting due to read() error\n");
+		exit(1);
+	}
+	total_bytes += bytes;
+	b2 = write(tsfd, buf, bytes);
+	if (b2 == -1) {
+		perror("write");
+		exit(1);
+	} else if (b2 < bytes)
+		fprintf(stderr, "warning: read %d, but wrote only %d bytes\n", bytes, b2);
+	else
+		fprintf(stderr, "got %d bytes (%llu total)\n", bytes, total_bytes);
+}
+
+int main(int argc, char *argv[])
+{
+	int dmxfd, tsfd;
+	unsigned int pid;
+	struct dmx_pes_filter_params f;
+	char *dmxdev = "/dev/dvb/adapter0/demux0";
+	int i;
+	char *chkp;
+
+	if (argc < 3)
+		usage();
+
+	if (getenv("DEMUX"))
+		dmxdev = getenv("DEMUX");
+
+	fprintf(stderr, "using '%s'\n"
+		"writing to '%s'\n", dmxdev, argv[1]);
+	tsfd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0664);
+	if (tsfd == -1) {
+		perror("cannot write output file");
+		return 1;
+	}
+
+	dmxfd = open(dmxdev, O_RDONLY);
+	if (dmxfd == -1) {
+		perror("cannot open dmx device");
+		return 1;
+	}
+
+	if (getenv("BUF_SIZE") && ((BUF_SIZE = strtoul(getenv("BUF_SIZE"), NULL, 0)) > 0))
+		fprintf(stderr, "BUF_SIZE = %lu\n", BUF_SIZE);
+
+	pid = strtoul(argv[2], &chkp, 0);
+	if (pid > 0x2000 || chkp == argv[2])
+		usage();
+	fprintf(stderr, "adding filter for PID 0x%04x\n", pid);
+
+	memset(&f, 0, sizeof(f));
+	f.pid = (uint16_t) pid;
+	f.input = DMX_IN_FRONTEND;
+	f.output = DMX_OUT_TSDEMUX_TAP;
+	f.pes_type = DMX_PES_OTHER;
+
+	if (ioctl(dmxfd, DMX_SET_PES_FILTER, &f) == -1) {
+		perror("DMX_SET_PES_FILTER");
+		return 1;
+	}
+
+	for (i = 3; i < argc; i++) {
+		pid = strtoul(argv[i], &chkp, 0);
+		if (pid > 0x2000 || chkp == argv[i])
+			usage();
+		fprintf(stderr, "adding filter for PID 0x%04x\n", pid);
+		if (ioctl(dmxfd, DMX_ADD_PID, &pid) == -1) {
+			perror("DMX_ADD_PID");
+			return 1;
+		}
+	}
+	if (ioctl(dmxfd, DMX_START) == -1) {
+		perror("DMX_START");
+		close(dmxfd);
+		return 1;
+	}
+
+	for (;;) {
+		process_data(dmxfd, tsfd);
+	}
+
+	close(dmxfd);
+	return 0;
+}