[linux-dvb] RFC: Multiple TS recordings

Felix Domke tmbinc at elitedvb.net
Mon Apr 3 23:44:40 CEST 2006

Hash: SHA1

Every now and then, the very same question arises - "dvr0 is fine - but
what's about multiple recordings?"

Let us take v4 out of the equation. We have lots of hardware with
v3-only drivers, lots of applications with v3-only support and lots of
users which we don't want to loose.

Further, let's divide the problem into two pieces:

a.) It's currently not possible to record TS data (compared to PES)
(without the use of dvr0).
b.) We only have one dvr0 device. (I know there is dvr1, but it's
neither scalable nor does it fit - dvr1 belongs to demux1, and can't be
used as a secondary dvr0).

a.) can be fixed easily with the proposal i've once posted:

We redefine the "pes_type" element in the dmx_pes_filter_params into a
new meaning.

Currently, dmx_pes_filter_params is used for 3 things:

 - sending a PES stream to a hardware decoder with
.output = DMX_OUT_DECODER,
.pes_type = DMX_PES_AUDIO0 / DMX_PES_VIDEO0 / ...

 - getting PES data into userspace with
.output = DMX_OUT_TAP,
.pes_type = DMX_PES_OTHER

 - getting TS data into dvr0 with
.output = DMX_OUT_TS_TAP,
.pes_type = DMX_PES_OTHER

the "pes_type" field is totally unused in the DMX_OUT_TAP-case (which we
are interested in) - it's always DMX_PES_OTHER. We could redefine it a
bit, in a backward compatible way:

+typedef enum {
+       DMX_TAP_TS,
+       DMX_TAP_PES = DMX_PES_OTHER, /* for backward binary compat. */
+} dmx_tap_type_t;

struct dmx_pes_filter_params
        __u16          pid;
        dmx_input_t    input;
        dmx_output_t   output;
+       union {
        dmx_pes_type_t pes_type;
+       dmx_tap_type_t tap_type;
+       };
        __u32          flags;

now, we define
 - getting TS data into userspace with:
.output = DMX_OUT_TAP,
.tap_type = DMX_TAP_TS
 - getting PES data into userspace with:
.output = DMX_OUT_TAP,
.tap_type = DMX_TAP_PES

(note that the latter is binary identically with the original PES
filtering case)

the required change in dmxdev.c change is almost trivial:

  if (otype == DMX_OUT_DECODER)
    ts_type = TS_DECODER;
    ts_type = 0;

    /* DMX_OUT_TS_TAP expects TS headers */
  if (otype == DMX_OUT_TS_TAP)
    ts_type |= TS_PACKET;

    /* DMX_OUT_TAP used to expect PES packets. */
  if (otype == DMX_OUT_TAP)
    ts_type |= TS_PACKET;

      /* now, if somebody specified something else than DMX_PES_OTHER,
we assume TS filtering. */
    if (ts_pes == DMX_TAP_PES) /* i.e. DMX_PES_OTHER for backward compat. */
      ts_type |= TS_PAYLOAD_ONLY;

All demux drivers don't care for that. They already support filtering TS
and PES. They don't care if they filter into dvr0 or not.

This proposal is completely backward compatible. Newer dvb-core will
handle older applications fine, older dvb-core will throw an error with
newer application only if they use the new ts filtering feature. It is
both source- and binary-level compatible, nor does it change any sizes.
If the anonymous union is a problem, we could use the "wrong" name
(pes_type), that shouldn't really be a problem.

Now we still have problem b.) - we could filter x streams in kernel and
mux them together in userspace, but we want to avoid that, for efficency
reasons of course, but also for the fact that recovering the timing
between the different packet source is impossible (well, current
pid-queue-based hardware won't do it better, but it COULD be improved
without breaking userspace).

for b.), i propose the following API extension:

+#define DMX_ADD_PID              _IO('o', 51)
+#define DMX_REMOVE_PID           _IO('o', 52)

The semantic is that you first open a demux0, then setup all your
parameters with DMX_SET_PES_FILTER (including TS filtering, if you want
- - in fact, it doesn't make sense for PES-filtering unless we have
hardware mux support, i.e. copy full PES packets). You don't specify

Then, you would add additional pids with the DMX_ADD_PID call. All of
them will be filtered with the same parameters.

Then you do DMX_START, and you will receive all requested PIDs.

DMX_ADD_PID / DMX_REMOVE_PID would still work when the demux is running,
for example to track PMT-ES changes (new/vanishing audio track etc.).

(Furthermore, DMX_SET_PES_FILTER could be extended to not include the
pid if it's an invalid value, say 0xFFFF. You would have a more
symmetrical api in that case, as you don't need to split the first pid
up into a different ioctl.)

I made a hacky implementation of that into dmxdev, which works pretty
well for the first shot. There are a couple of special cases (filtering
the same pid twice..) which still have to be handled, but overall it's
ok. It basically adds multiple feeds per filter, into a linked-list.
I'll polish that patch a bit and send it here to review later.

(In fact, a different thing to talk about would be hardware-DVR support
(and i would could O(1)-software-demux-support into that...) - putting
multiple 'TS'-type streams into a queue can often be hardware
accelerated, by sharing one big queue. (This would also leave the timing
intact, which is currently impossible, unless you get an interrupt on
every packet)

So, please comment!

Version: GnuPG v1.4.2 (MingW32)


More information about the linux-dvb mailing list