bttv msp3400 2.6.15.6 - > 2.6.16 stereo stop working
- From: Roland Scheidegger <rscheidegger_lists (at) hispeed.ch>
- Date: Sat, 01 Apr 2006 02:57:48 +0200
Hans Verkuil wrote:
Why? And what would the application do with that information? The
application should be able to show what is transmitted (mono, stereo,
bilingual) which it can get from the rxsubchans field. That's what
it is there for. It's like setting your TV to LANG B and then switch
to a simple stereo transmission and suddenly it is LANG A.
Anyway, this really was the original intention of the API (I've been
discussing this before with Michael Schimek). The language still
needs improving, though. This whole area is one big mess where both
application and driver authors had different and usually wrong
interpretations of the API. Not helped by the mixing of V4L1 and
V4L2. I am sorting out the kernel drivers but as you can see it is a
difficult process.
Ok if that really is the intention of the API I will shut up. Usually
modern tv sets work like that, they often don't show you there are 2
languages available but simply display "A" or "B" on some popup - i.e.
the currently set mode. Granted, the app could figure it out itself (or
simply always set it) if it wants.
The xawtv author certainly thinked that audmode is not only used to
be set by the app (the -v 2 output will list that audmode as
"tuner current"). I would consider that as a flaw in the v4l2 api
btw, it doesn't quite make sense both ways - if it's never set by
the driver then an app has to go through hoops to figure out what
the current mode actually is
Again, why? The user needs to know what is transmitted! Say a channel
broadcasts NTSC mono + SAP. The audmode is set to stereo initially.
So G_TUNER will return mono as audmode (as that is the fallback in
this scenario). But that is not the 'tuner current'! The user needs
to know what is actually transmitted so that he/she can adjust the
audio mode accordingly.
Well, of course you can still show that information, noone is arguing
that the rxsubchans field to be changed somehow or going away.
Maybe there should have been a third field (i.e. one for the currently
possible modes (rxsubchans), one for the user requested mode (i.e.
audmode) and one for the currently in-use (for whatever reason) mode.
(query both rxsubchans and audmode, then determine the mode
according to that fallback matrix, and it's downright impossible if
there is a dual-language program and audmode is stereo, since two
answers are possbile in that case according to api spec
Yes, that's one reason I've added LANG1_LANG2. For normal TV viewing
it makes no sense to hear both languages, but for PVR recordings it
does. The core problem with this API is that nobody really understood
all the combinations that can happen. It was also originally
developed in a somewhat NTSC-centric manner and did not take the
complications that occur with NICAM/PAL into account. As a result the
stereo mode is almost obsolete. Really lang1 could take over the role
of stereo (or stereo that of lang1) since in practice they'll mean
the same thing. This API is not the best ever designed.
I don't quite agree that it makes no sense to hear both languages, can
be fun :-) (and somewhat interesting, for instance you can notice some
dual-language transmissions have obviously delays in the "common" audio
track (i.e. some music playing)).
Really? I didn't have any problems with my msp3400d pushed in
msp3400c mode. In the old situation that would give me noise, but no
longer with these patches.
Maybe I used the wrong patch (this was the hardest part in hacking the
driver, finding the right file to download!), but at least the
unmute/volume crackling was caused by the wake_thread in the new
internal audio routing stuff. I don't think you really want to do this,
you're abusing the thread (which is really intended for carrier scan) a
bit too much I think, unless you find some more robust way to tell the
thread what you actually want it to do.
Anyway, I also reincreased the time interval of the quick stereo
detection (because the chip really needs around 1 second, I've tried the
id reset reg but it didn't help (probably is only meant when you switch
channels without doing a new carrier scan), and if you switch to a
channel with only 1 carrier you end up with a lot of static for 1 second
otherwise sometimes). For the same reason I also increased the stereo
detection value (mono channels go down quite slowly to zero, sometimes
need longer than 1 second before they are below 4096, but stereo
channels were ALL above 16000 even after only 1 second - I'm not sure if
this is always the case, but it's true here). Carrier mute would
probably do the trick for avoiding this static, but it still mutes some
channels completely here which have a weak signal I guess.
I also got rid by the cracking and popping noises when channel switching
if an app unmutes in the meantime by only unmuting if there is no
carrier scan in progress.
There is still some faint popping (nothing like it was before!) when
unmuting/channel switching, I thought it's caused by using not the
fast_mute volume value, played with that but for some reason it didn't help.
Roland
diff -ur hg-hverkuil-v4l-dvb-orig/linux/drivers/media/video/msp3400-driver.c hg-hverkuil-v4l-dvb-9abb710ed22c/linux/drivers/media/video/msp3400-driver.c
--- hg-hverkuil-v4l-dvb-orig/linux/drivers/media/video/msp3400-driver.c 2006-03-31 15:30:06.000000000 +0200
+++ hg-hverkuil-v4l-dvb-9abb710ed22c/linux/drivers/media/video/msp3400-driver.c 2006-04-01 01:08:02.000000000 +0200
(at) (at) -307,17 +307,19 (at) (at)
struct msp_state *state = i2c_get_clientdata(client);
int bal = 0, bass, treble, loudness;
int val = 0;
+ int reallymuted = state->muted | state->scan_in_progress;
- if (!state->muted)
+ if (!reallymuted)
val = (state->volume * 0x7f / 65535) << 8;
- v4l_dbg(1, msp_debug, client, "mute=%s volume=%d\n",
- state->muted ? "on" : "off", state->volume);
+ v4l_dbg(1, msp_debug, client, "mute=%s scanning=%s volume=%d\n",
+ state->muted ? "on" : "off", state->scan_in_progress ? "yes" : "no",
+ state->volume);
msp_write_dsp(client, 0x0000, val);
- msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1));
+ msp_write_dsp(client, 0x0007, reallymuted ? 0x1 : (val | 0x1));
if (state->has_scart2_out_volume)
- msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1));
+ msp_write_dsp(client, 0x0040, reallymuted ? 0x1 : (val | 0x1));
if (state->has_headphones)
msp_write_dsp(client, 0x0006, val);
if (!state->has_sound_processing)
(at) (at) -737,7 +739,7 (at) (at)
msp_set_scart(client, sc1_out, 1);
msp_set_scart(client, sc2_out, 2);
msp_set_audmode(client);
- msp_wake_thread(client);
+/* msp_wake_thread(client);*/
break;
}
diff -ur hg-hverkuil-v4l-dvb-orig/linux/drivers/media/video/msp3400-driver.h hg-hverkuil-v4l-dvb-9abb710ed22c/linux/drivers/media/video/msp3400-driver.h
--- hg-hverkuil-v4l-dvb-orig/linux/drivers/media/video/msp3400-driver.h 2006-03-31 15:30:06.000000000 +0200
+++ hg-hverkuil-v4l-dvb-9abb710ed22c/linux/drivers/media/video/msp3400-driver.h 2006-04-01 01:00:48.000000000 +0200
(at) (at) -86,6 +86,7 (at) (at)
int volume, muted;
int balance, loudness;
int bass, treble;
+ int scan_in_progress;
/* thread */
struct task_struct *kthread;
diff -ur hg-hverkuil-v4l-dvb-orig/linux/drivers/media/video/msp3400-kthreads.c hg-hverkuil-v4l-dvb-9abb710ed22c/linux/drivers/media/video/msp3400-kthreads.c
--- hg-hverkuil-v4l-dvb-orig/linux/drivers/media/video/msp3400-kthreads.c 2006-03-31 15:30:06.000000000 +0200
+++ hg-hverkuil-v4l-dvb-9abb710ed22c/linux/drivers/media/video/msp3400-kthreads.c 2006-04-01 02:10:00.000000000 +0200
(at) (at) -389,8 +389,8 (at) (at)
if (val > 32767)
val -= 65536;
v4l_dbg(2, msp_debug, client, "stereo detect register: %d\n", val);
- if (val > 4096) {
- rxsubchans = V4L2_TUNER_SUB_STEREO;
+ if (val > 8192) {
+ rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
} else if (val < -4096) {
rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
} else {
(at) (at) -498,9 +498,13 (at) (at)
}
/* put into sane state (and mute) */
+ state->scan_in_progress = 1;
msp_reset(client);
msp3400c_set_mode(client, MSP_MODE_AM_DETECT);
+ msp3400c_set_carrier(client, msp3400c_init_data[MSP_MODE_AM_DETECT].cdo1,
+ msp3400c_init_data[MSP_MODE_AM_DETECT].cdo2);
+
val1 = val2 = 0;
max1 = max2 = -1;
state->watch_stereo = 0;
(at) (at) -627,6 +631,7 (at) (at)
msp3400c_set_carrier(client, state->second, state->main);
/* unmute, restore misc registers */
+ state->scan_in_progress = 0;
msp_set_audio(client);
msp_write_dsp(client, 0x13, state->acb);
(at) (at) -637,11 +642,11 (at) (at)
/* monitor tv audio mode, the first time don't wait
so long to get a quick stereo/bilingual result */
- count = 20;
+ count = 3;
while (state->watch_stereo) {
- watch_stereo(client);
- if (msp_sleep(state, count ? 200 : 5000))
+ if (msp_sleep(state, count ? 1000 : 5000))
goto restart;
+ watch_stereo(client);
if (count) count--;
}
}
--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request (at) redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list