Multiproto

From LinuxTVWiki
Revision as of 19:44, 8 February 2012 by Js (talk | contribs) (Reverted edits by Sanders Dowdy (talk) to last revision by Jon2856)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Multiproto was a proposal for version 5.0 of the LinuxDVB API (see also S2API) which includes extensions for cards which support multiple DVB protocols (DVB-S, DVB-S2, DVB-T, DVB-C, DVB-H, ATSC, DSS). An alternative proposal, S2API, was evenutally selected as the new API and was released in kernel 2.6.28 on 24 Dec 2008.

Multiproto was an experimental project and was not implemented in any released version of Linux. Notably, the author of some of the main parts of multiproto has in the past incomprehensibly attempted to block its inclusion in Linux, highlighting both misunderstanding of the implications of the GPL and the need for stricter project management within the Linux DVB community http://www.linuxtv.org/pipermail/linux-dvb/2008-January/023355.html. After more than two years, a pull request for the API (excluding drivers) was eventually issued hours after the competing project S2API was announced http://linuxtv.org/pipermail/linux-dvb/2008-September/028896.html.

S2API and multiproto were reviewed at the Linux Plumbers' Conference in Portland, Oregon, Wed 17th - Fri 19th September 2008: http://linuxplumbersconf.org/program/microconfs/getmc.php?mc=chehab08. See http://www.linuxtv.org/downloads/plumbers2008/stoth_dvb_round_table_new_api.pdf.

An announcement regarding the conclusions of the review was made by the maintainer : http://www.linuxtv.org/news.php?entry=2008-09-23.mchehab, http://linuxtv.org/pipermail/linux-dvb/2008-September/029155.html, http://linuxtv.org/pipermail/linux-dvb/2008-September/029181.html, http://linuxtv.org/pipermail/linux-dvb/2008-September/029232.html. By unanimous vote, S2API was selected for inclusion in kernel 2.6.28. The multiproto API will therefore not be merged into the kernel. The decision is final. The device support in the multiproto tree will not be lost -- drivers can be easily converted to work with the S2API. It is intended to add support for products with the STB0899 demodulator (TT-3200 and others) to S2API before the merge.

Overview/Features

Discuss the features and facets of the project here ... this means you

Design Decisions

explain the choices made ... this means you

Technical Details

give a technical description of how the API change has been implemented ... this means you

New structs and enums have been added to expand the API for multiple frontends and the parameters required for protocols DVB-S, DSS, DVB-S2, DVB-T, DVB-H and ATSC. These are prefixed (at least for now) with "dvbfe_" and "DVBFE_" as opposed to the old "fe_" and "FE_". For details compare the old and new versions of include/linux/dvb/frontend.h. Currently multiproto implements both the new and old APIs and a glue layer to manage old/new drivers with new/old API calls. Presumably the plan is eventually to move to a pure 3.3 API and update all the drivers.

Simple enough you might think, but progress has been very slow. Since the first version, way back in April 2006, ten (10!) versions of the entire Linux kernel have been released. See http://www.linuxtv.org/pipermail/linux-dvb/2006-April/009522.html and http://kernelnewbies.org/Linux26Changes.

Evaluation

explain whether the design goals have been met or not ... this means you

1. Some application of Occam's Razor still needs to be made. There is repetition in the multiproto API arising from the use of unions of structs to hold parameters (often the same ones) for each type of frontend. However API calls (eg. ioctl dvbfe_params) can be addressed to individual frontends, i.e. /dev/dvb/adapterN/frontendM, so this repetition could be removed to create a cleaner API. For example these variables:

dvbfe_params.delsys.dvbs.fec
dvbfe_params.delsys.dss.fec
dvbfe_params.delsys.dvbs2.fec
dvbfe_params.delsys.dvbc.fec

could be replaced by the simpler:

dvbfe_params.fec

and these

dvbfe_info.delsys.dvbs.fec
dvbfe_info.delsys.dss.fec
dvbfe_info.delsys.dvbs2.fec

could be replaced by the simpler:

dvbfe_info.fec

If we simplify in this way, the relevant section of linux/include/linux/dvb/frontend.h would look like this: (note I added _caps to some variables to indicate that they are actually ORd sets of capabilities)

struct dvbfe_info {
       char				name[128];
       enum dvbfe_delsys		delsys;			//curr delivery sys, READABLE by user, not WRITEABLE
       enum dvbfe_modulation		modulation_caps;	//valid for DVB-S,S2,C,T,H,DSS,ATSC
       enum dvbfe_fec			fec_caps;		//valid for DVB-S,S2,DSS
       enum dvbfe_stream_priority	stream_priority_caps; 	//valid for DVB-T,H
       __u32				frequency_min;
       __u32				frequency_max;
       __u32				frequency_step;
       __u32				frequency_tolerance;
       __u32				symbol_rate_min;
       __u32				symbol_rate_max;
       __u32				symbol_rate_tolerance;
       enum fe_spectral_inversion	inversion;
       __u8				pad[128];
};

instead of the multiproto version which is more complex and repetitive:

/* DVB-S capability bitfields		*/
struct dvbfe_dvbs_info {
       enum dvbfe_modulation		modulation;
       enum dvbfe_fec			fec;
};
/* DSS capability bitfields		*/
struct dvbfe_dss_info {
       enum dvbfe_modulation		modulation;
       enum dvbfe_fec			fec;
};
/* DVB-S2 capability bitfields		*/
struct dvbfe_dvbs2_info {
       enum dvbfe_modulation		modulation;
       enum dvbfe_fec			fec;
       __u8				pad[32];
};
/* DVB-C capability bitfields		*/
struct dvbfe_dvbc_info {
      enum dvbfe_modulation		modulation;
};
/* DVB-T capability bitfields		*/
struct dvbfe_dvbt_info {
       enum dvbfe_modulation		modulation;
       enum dvbfe_stream_priority	stream_priority;
       __u8				pad[32]; 
};
/* DVB-H capability bitfields		*/
struct dvbfe_dvbh_info {
       enum dvbfe_modulation		modulation;
       enum dvbfe_stream_priority	stream_priority;
       __u8				pad[32];
};
/* ATSC capability bitfields		*/
struct dvbfe_atsc_info {
       enum dvbfe_modulation		modulation;
       __u8				pad[32];
};
struct dvbfe_info {
       char                            name[128];
       union {
               struct dvbfe_dvbs_info  dvbs;
               struct dvbfe_dss_info   dss;
               struct dvbfe_dvbs2_info dvbs2;
               struct dvbfe_dvbc_info  dvbc;
               struct dvbfe_dvbt_info  dvbt;
               struct dvbfe_dvbh_info  dvbh;
               struct dvbfe_atsc_info  atsc;
               __u8                    pad[128];
       } delsys;
       __u32                           frequency_min;
       __u32                           frequency_max;
       __u32                           frequency_step;
       __u32                           frequency_tolerance;
       __u32                           symbol_rate_min;
       __u32                           symbol_rate_max;
       __u32                           symbol_rate_tolerance;
       enum fe_spectral_inversion      inversion;
       __u8                            pad[128];
};

2. There was a problem with the design of the multiproto API. The routine DVBFE_GET_INFO actually changed the kernel state (in particular the variable which holds the delivery system). Simply calling DVBFE_SET_PARAMS with a complete correct set of parameters does not work. The corresponding screwy userspace code can be seen in the patched http://abraham.manu.googlepages.com/szap.c where DVBFE_GET_INFO is used to SET the delivery system variable before DVBFE_SET_PARAMS is called. Such odd unexpected behaviour is confusing and should not be accepted in the Linux kernel. At the very least some work needs to be done to rename the routines sensibly. DVBFE_GET_INFO appears to have been originally intended to provide information about the capabilities of the frontend, which is currently not apparent in its name. See http://www.linuxtv.org/pipermail/linux-dvb/2008-March/024266.html and http://www.linuxtv.org/pipermail/linux-dvb/2008-March/024281.html.

UPDATE March 09 2008: This appears to have been changed with the introduction of DVBFE_SET_DELSYS which is now used to set the delivery system. Tuning is done with szap2. Unfortunately the variable delsys has been completely removed from the struct dvbfe_info, instead of just making it a user-readable variable (not a writeable one), analogous to the "type" variable in the old dvb_frontend_info (but with a different range of values, i.e. DVB-S/S2/C/T/H/DSS/ATSC vs. QPSK/QAM/OFDM/ATSC). It would be nice if delsys were put back in, with code to set its value appropriately on DVBFE_GET_INFO calls.

Alternatives

S2API: Tag/Value-based API proposal

Following long standing frustration amongst developers and users about the lack of progress in getting multiproto into the Linux kernel, a group of four senior developers including the maintainer has proposed an alternative (Aug 29 2008) and announced that they no longer support multiproto. See http://linuxtv.org/pipermail/linux-dvb/2008-August/028313.html. The idea had been proposed earlier http://linuxtv.org/pipermail/linux-dvb/2007-November/021618.html. Technically it is quite different from multiproto. Control of the frontend is implemented using a command sequence of (tag,value) pairs to set all the required parameters and then initiate tuning. Thus it no longer depends on fixed structs to hold parameter data. A notable advantage of the tag/value technique is that it should make it much easier to keep up with future DVB transmission standards because this will at most require the definition of additional tags (i.e. commands) rather than a revision of the API. Commands can be made atomic by passing a whole command sequence in a single ioctl (for example a set of parameters followed by the tune command). Alternatively a sequence may be sent one command at a time. The development repository is available at http://linuxtv.org/hg/~stoth/s2. Work still needs to be done to finish the API design and port the existing DVB-S2 drivers to work with it. Other drivers are not affected.

APIs used in the HVR4000 drivers An alternative API has been created for the Hauppauge WinTV-HVR-4000 which makes minimal changes to the current v4l-dvb API in order to provide multifrontend support for DVB-T,DVB-S and DVB-S2 for that device. It offers backwards compatibility with existing binary multimedia applications for DVB-T and DVB-S without recompilation. Patches providing DVB-S2 support for szap and mythtv have been posted. See http://dev.kewl.org/hauppauge/experimental/, http://dev.kewl.org/hauppauge and http://www.linuxtv.org/pipermail/linux-dvb/2008-March/024243.html.

A different method was used to provide support for DVB-S2 in the HVR4000 single frontend (sfe) driver.

Use multiproto drivers with old API A patch exists which allows basic use of drivers developed for multiproto with the current API (3.2). See http://linuxtv.org/pipermail/linux-dvb/2008-May/026246.html and http://linuxtv.org/pipermail/linux-dvb/2008-August/027979.html.

Status and Migration Plan

explain how a migration from the current API to multiproto could be achieved ... this means you

The multiproto API will not be included in the Linux kernel (see above). Device support in the multiproto tree will simply be converted to work with S2API where necessary.

The mantis tree (http://jusst.de/hg/mantis) which also uses the multiproto API has not yet been merged into multiproto, meaning that there is unnecessary duplication of the core code and any code fixes in either tree are not automatically applied to both trees.

Making it Work

How to get it from the author's repository:

hg clone http://jusst.de/hg/multiproto

or

http://jusst.de/hg/multiproto/archive/tip.tar.bz2

UPDATE 1st Aug 2008: Igor Liplianin has created another repository containing multiproto code and szap2 at http://liplianindvb.sourceforge.net/hg/, reported to be working with the HVR-4000. See http://www.linuxtv.org/pipermail/linux-dvb/2008-July/027514.html. This appears to be similar to the V4L/DVB staging development repository at http://linuxtv.org/hg/v4l-dvb/ but with the addition of multiproto code.

hg clone http://liplianindvb.sourceforge.net/hg/liplianindvb
hg clone http://liplianindvb.sourceforge.net/hg/szap2


Drivers

There are currently no in-kernel multiproto drivers. There are several cards which have experimental support in the multiproto tree, perhaps with additional patches.

Provide details of which drivers work with multiproto ... this means you

See the descriptions for the following cards:

Azurewave AD-SP400 CI (Twinhan VP-1041)

Hauppauge WinTV-HVR-4000

KNC1 DVB-S2 TV Station (PCI32, supports CI)

TechnoTrend TT-budget S2-3200

TerraTec Cinergy S2 PCI HD CI (PCI32, CI)

provide the details of where the drivers and patches and necessary tools are available ... this means you

provide details of how to compile for recent kernels -- this means you

Sample kernel output

provide the relevant portion of dmesg here

Tuner / DiSEqC / Player support

provide comprehensive details of how to upgrade multimedia applications to work with the new API ... this means you

Scanning and tuning applications generally will not work with the new API unless they are modified. The situation is arguably improving but the lack of patched applications (and guidance on patching) has hindered completion and testing of multiproto and new drivers, and adoption of the new API. Needless to say, patching drivers and multiple applications is a step too far for most potential testers.

dvb-apps : There is still no patched dvb-apps tree. Someone needs to create one ... why don't you?

scan : see patched version at http://jusst.de/manu/scan.tar.bz2

szap: see patched version at http://abraham.manu.googlepages.com/szap.c Also see information about szap2 at http://allrussian.info/thread.php?postid=187408#post187408 and http://www.linuxtv.org/pipermail/linux-dvb/2008-February/023836.html.

MPlayer : someone needs to write a patch ... why don't you?

Kaffeine / xine-lib : someone needs to write a patch ... why don't you? There are some posts about getting Kaffeine to work with multiproto in these threads: http://www.linuxtv.org/pipermail/linux-dvb/2008-May/025882.html, http://www.linuxtv.org/pipermail/linux-dvb/2008-July/027141.html and in these two messages: http://sourceforge.net/mailarchive/forum.php?thread_name=48217036.3090709%40gmail.com&forum_name=kaffeine-devel and http://sourceforge.net/mailarchive/forum.php?thread_name=481DE023.9000903%40gmail.com&forum_name=kaffeine-devel .

VDR : Ugh, patch hell. Why is there no VDR development repository? History: VDR version 1.5.14 required multiproto (v1.5.14 announcement: http://www.linuxtv.org/pipermail/vdr/2008-January/015302.html) but this was revoked in 1.5.15 to make a multiproto-free release 1.6.0 due to the unavailability of multiproto in the Linux kernel mainstream (not a surprise to anyone). The requirement for multiproto was reinstated in version 1.7.0 (again jumping the gun), but it needs an old multiproto (from before delsys was removed (see above)), so you still have to patch it (multiproto-update.diff) to work with the current multiproto. But that patch is now broken -- you will have to fix it by hand. There is even a patch which can be used to revert that (1.7.0+multiproto-update.diff) to work with the v3.2 API drivers, and another newer one which will work with both APIs! See http://linuxtv.org/pipermail/vdr/2008-August/017534.html and http://www.udo-richter.de/vdr/patches.en.html#dvb-api-wrapper. [Prediction: VDR will remove the multiproto requirement again before v1.8.0, flip,flop,flip,flop...].

And you need yet another patch if you want H.264 support (http://www.linuxtv.org/pipermail/vdr/2008-April/016513.html). There are patches for vdr-rotor and GotoX too.

Version 1.7.1 has now been released, this time requiring multiproto_plus. See http://linuxtv.org/pipermail/linux-dvb/2008-September/028818.html.

Following the decision to merge S2API into the kernel (and not multiproto) the multiproto support in VDR needs to be replaced with S2API support. An initial patch supporting S2API for DVB-S only has been written, see http://linuxtv.org/pipermail/vdr/2008-September/017910.html.

MythTV : Two patches (one DVB-S/S2, one DVB-S only) have been posted http://www.linuxtv.org/pipermail/linux-dvb/2008-January/022757.html. Current status?

dvbstream : Someone needs to write a patch ... why don't you? See http://www.linuxtv.org/pipermail/linux-dvb/2008-February/024056.html.

provide details of how to use with DiSEqC -- this means you

How to patch an application for Multiproto

provide guidance on patching applications to use multiproto -- this means you

To tune to a channel : using the patched szap above as a guide we see that

struct dvb_frontend_parameters tuneto;
...
ioctl(fefd, FE_SET_FRONTEND, &tuneto);

must be replaced by

struct dvbfe_params fe_params;
...
ioctl(fefd, DVBFE_SET_PARAMS, &fe_params);

where the parts of dvbfe_params.delsys relevant for the delivery system used (DVB-S/DSS/DVB-S2) need to be set before the call.

To make the userspace code a lot cleaner C preprocessor macros can be used to hide the full details of the multiproto api - here is a short example:

#if (DVB_API_VERSION==3) && (DVB_API_VERSION_MINOR>=3)
#define FE_PARAM                struct dvbfe_params
#define IOCTL_SET_FE            DVBFE_SET_PARAMS
#define DVB_SET_DELIVERY(a, b)  (a)->delivery=(b)
#define DVBC_SET_SYMBOLRATE(a, b)       (a)->delsys.dvbc.symbol_rate=(b)
#else
#define FE_PARAM                struct dvb_frontend_parameters
#define IOCTL_SET_FE            FE_SET_FRONTEND
#define DVB_SET_DELIVERY(a, b)  do{ } while(0)
#define DVBC_SET_SYMBOLRATE(a, b)       (a)->u.qam.symbol_rate=(b)
#endif

void tune(int fefd) {
 FE_PARAM        fparm;
 
 memset(&fparm, 0, sizeof(FE_PARM));
 
 DVB_SET_DELIVERY(&fparm, DVBFE_DELSYS_DVBC);
 ...
 DVBC_SET_SYMBOLRATE(&fparm, symbolrate)
 
 if (ioctl(fefd, IOCTL_SET_FE, &fparm) < 0) {
   printf("Tuning failed");
 }
}

The code itself will stay clean of ifdef spaghetti and the compatibility macros can be hidden in some header file. See getstream [1] for a multiproto capable tuner coder without a single ifdef.

External Links