Skip to contentSkip to conversation

Is xine DVB broken with Linux 3.3.1?

PATCH Superseded Chris Rankin 4 participants 9 messages Apr 4, 2012 – Apr 6, 2012 Media (V4L/DVB)

lore
Share & tools
lore
#0 lore raw

 Hi,

Is anyone else having difficulty watching DVB-T with xine and a 3.3.1 kernel? I have tried the following with several different USB adapters:

1) Plug in the device
2) Launch xine.
3) Select DVB-T channel.

and each time, the results are the same. Namely, xine refuses to acknowledge any of my channels. However, if I execute scandvb before running xine then xine suddenly realises that the exact same channels.conf file is OK after all.

It looks as if scandvb is initialising a piece of the USB DVB device's internal "state", and xine cannot tune the adapter into any channel until it has.

Can anyone else reproduce this, please?
Thanks,
Chris

#1 lore raw

I have just checked the 3.2.14 kernel, and it seems unaffected by this issue. So I'm guessing it was introduced recently in the 3.3 kernel.

Cheers,
Chris

#2 lore raw

DVB ioctl FE_GET_EVENT behaviour broken in 3.3

The reason that DVB playback with xine is broken in 3.3 is that the userspace semantics of FE_GET_EVENT have changed. Xine tunes into a DVB channel as follows:

* discards stale frontend events by calling FE_GET_EVENT until there is none left.
* calls FE_SET_FRONTEND with the new frequency.
* starts polling for new frontend events by calling FE_GET_EVENT again.

Xine assumes that *every* FE_GET_EVENT after calling FE_SET_FRONTEND will have dvb_frontend_event.parameters.frequency set to the new frequency, if this channel exists. However, under Linux 3.3, at least the first new event with a newly-plugged-in device has a frequency parameter of zero. I am assuming that Linux is populating the frequency parameter from an internal data structure because xine behaves normally once some other DVB application manages to set it to something other than zero. And xine then continues to behave normally until I unplug the DVB adapter and plug in back in again.

So the question is: why is there no frequency for this first FE_GET_EVENT? Are the parameters incomplete, or shouldn't this event have been sent in the first place?

Cheers,
Chris

#3 lore raw

Re: DVB ioctl FE_GET_EVENT behaviour broken in 3.3

Quoted 19 lines · Chris Rankin

The reason that DVB playback with xine is broken in 3.3 is that the userspace semantics of FE_GET_EVENT have changed. Xine tunes into a DVB channel as follows:

* discards stale frontend events by calling FE_GET_EVENT until there is none left.
* calls FE_SET_FRONTEND with the new frequency.
* starts polling for new frontend events by calling FE_GET_EVENT again.

Xine assumes that *every* FE_GET_EVENT after calling FE_SET_FRONTEND will have dvb_frontend_event.parameters.frequency set to the new frequency, if this channel exists. However, under Linux 3.3, at least the first new event with a newly-plugged-in device has a frequency parameter of zero. I am assuming that Linux is populating the frequency parameter from an internal data structure because xine behaves normally once some other DVB application manages to set it to something other than zero. And xine then continues to behave normally until I unplug the DVB adapter and plug in back in again.

Quoted 3 lines

So the question is: why is there no frequency for this first FE_GET_EVENT? Are the parameters incomplete, or shouldn't this event have been sent in the first place?

I have no enough experience, but IMHO all frontend parameters should be available just after demod is LOCKed. Before LOCK you cannot know many parameters at all and frequency also can be changed a little bit during tuning process (ZigZag tuning algo).

Could you try to git bisect to find out patch causing that regression?

I suspect it is some change done for DVB core, git log drivers/media/dvb/dvb-core/ shows rather many patches that could be the reason.

regards
Antti

Signature · 1 line
http://palosaari.fi/
#4 lore raw

Re: DVB ioctl FE_GET_EVENT behaviour broken in 3.3

Quoted 2 lines

Before LOCK you cannot know many parameters at all and frequency also can be changed a little bit during tuning process (ZigZag tuning algo).

But surely the point of calling poll() on the front end's descriptor is either to be notified once the tuning algorithm has locked, or to be told that LOCK has failed? This would certainly seem to have been xine's assumption for the past 10+ years.

Quoted 1 line

Could you try to git bisect to find out patch causing that regression?

I don't have a git tree to bisect with, so I expect I'll have to resort to more "old fashioned" methods.

Quoted 1 line

I suspect it is some change done for DVB core

Me too, because this bug is affecting *every* DVB adapter that I own. (All USB, but anyway...)

Cheers,
Chris

#5 lore raw

Re: DVB ioctl FE_GET_EVENT behaviour broken in 3.3

In reply to Antti Palosaari

The problem is that the following line was deleted from the FE_SET_FRONTEND ioctl logic:

        fepriv->parameters_out = fepriv->parameters_in;

The following dirty little patch restores the correct behaviour:

dvb_frontend.c renamed from dvb_frontend.c.orig +2 -0
@@ -1877,6 +1877,8 @@
 	if (c->hierarchy == HIERARCHY_NONE && c->code_rate_LP == FEC_NONE)
 		c->code_rate_LP = FEC_AUTO;
 
+	fepriv->parameters_out.frequency = c->frequency;
+
 	/* get frontend-specific tuning settings */
 	memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
 	if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, 

&fetunesettings) == 0)) {

I'm hoping that someone out there who understands the new logic better than I can provide a better patch.

Cheers,
Chris

#6 lore raw

[REGRESSION] Linux 3.3 DVB userspace ABI broken for xine (FE_SET_FRONTEND)

In reply to Chris Rankin

Hi,

The following commit has broken the DVB ABI for xine:

http://git.linuxtv.org/linux-2.6.git/commitdiff/e399ce77e6e8f0ff2e0b8ef808cbb88fc824c610

author: Mauro Carvalho Chehab <[email protected]>
Sun, 1 Jan 2012 19:11:16 +0000 (16:11 -0300)
committer: Mauro Carvalho Chehab <[email protected]>
Wed, 4 Jan 2012 19:30:02 +0000 (17:30 -0200)

This var were used during DVBv3 times, in order to keep a copy of the parameters used by the events. This is not needed anymore, as the parameters are now dynamically generated from the DVBv5 structure.

So, just get rid of it. That means that a DVBv5 pure call won't use anymore any DVBv3 parameters.

The problem is that xine is expecting every event after a successful FE_SET_FRONTEND ioctl to have a non-zero frequency parameter, regardless of whether the tuning process has LOCKed yet. What used to happen is that the events inherited the initial tuning parameters from the FE_SET_FRONTEND call. However, the fepriv->parameters_out struct is now not initialised until the status contains the FE_HAS_LOCK bit.

You might argue that this behaviour is intentional, except that if an application other than xine uses the DVB adapter and manages to set the parameters_out.frequency field to something other than zero, then xine no longer has any problems until either the adapter is replugged or the kernel modules reloaded. This can only mean that the fepriv->parameters_out struct still contains the (stale) tuning information from the previous application.

So can we please restore the original ABI behaviour, and have fepriv->parameters_out initialised by FE_SET_FRONTEND again?

Cheers,
Chris

#7 lore raw

PATCH 1/1 Linux 3.3 DVB userspace ABI broken for xine (FE_SET_FRONTEND)

In fact, the following patch works for me.

drivers/media/dvb/dvb-core/dvb_frontend.c renamed from drivers/media/dvb/dvb-core/dvb_frontend.c.orig +7 -0
@@ -1831,6 +1831,13 @@
 		return -EINVAL;
 
 	/*
+	 * Initialize output parameters to match the values given by
+	 * the user. FE_SET_FRONTEND triggers an initial frontend event
+	 * with status = 0, which copies output parameters to userspace.
+	 */
+	dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
+
+	/*
 	 * Be sure that the bandwidth will be filled for all
 	 * non-satellite systems, as tuners need to know what
 	 * low pass/Nyquist half filter should be applied, in
#8 lore raw

PATCH v2 1/1 Linux 3.3 DVB userspace ABI broken for xine (FE_SET_FRONTEND)

In reply to Chris Rankin

I've had a closer look at the commit which caused the regression and it looks like there were two places where fepriv->parameters_in was assigned to fepriv->parameters_out. So I've updated my patch accordingly.

Cheers,
Chris

drivers/media/dvb/dvb-core/dvb_frontend.c renamed from drivers/media/dvb/dvb-core/dvb_frontend.c.orig +10 -0
@@ -143,6 +143,8 @@
 static void dvb_frontend_wakeup(struct dvb_frontend *fe);
 static int dtv_get_frontend(struct dvb_frontend *fe,
 			    struct dvb_frontend_parameters *p_out);
+static int dtv_property_legacy_params_sync(struct dvb_frontend *fe,
+					   struct dvb_frontend_parameters *p);
 
 static bool has_get_frontend(struct dvb_frontend *fe)
 {
@@ -695,6 +697,7 @@
 					fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
 					fepriv->delay = HZ / 2;
 				}
+				dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
 				fe->ops.read_status(fe, &s);
 				if (s != fepriv->status) {
 					dvb_frontend_add_event(fe, s); /* update event list */
@@ -1831,6 +1834,13 @@
 		return -EINVAL;
 
 	/*
+	 * Initialize output parameters to match the values given by
+	 * the user. FE_SET_FRONTEND triggers an initial frontend event
+	 * with status = 0, which copies output parameters to userspace.
+	 */
+	dtv_property_legacy_params_sync(fe, &fepriv->parameters_out);
+
+	/*
 	 * Be sure that the bandwidth will be filled for all
 	 * non-satellite systems, as tuners need to know what
 	 * low pass/Nyquist half filter should be applied, in