[MPlayer-dev-eng] Patch: Jack audio output
Ed Wildgoose
lists at wildgooses.com
Mon Oct 18 18:18:25 CEST 2004
Thanks for the comments, new patch attached, and thoughts inline below:
>> +long approx_bytes_in_jackd = 12288; // Rough estimate (=512 frames *
>> 6 channels * 2 bytes * 2 buffers
>
>
> when is this default used? Does jack always use 6 channels? This seems
> fishy to me.
Sure, leave it set to zero then. It gets assigned in the Init function
and also in the Reset function anyway. I only had it set like this so
that when I was testing I could quickly comment out the other ways that
it was set and play with the value here.
I will resubmit with it set to zero. This is a red herring really.
>> -long JACK_Write(int deviceID, char *data, unsigned long bytes); /*
>> returns the number of bytes written */
>> +long JACK_Write(int deviceID, unsigned char *data, unsigned long
>> bytes); /* returns the number of bytes written */
>
>
> This change is rather irrelevant. Leave it as it was I'd say
We can do, but the actual API changed in bio2jack to make it an unsigned
char... For whatever reason we aren't loading the bio2jack.h file and
instead portions of it are reproduced here directly...
...However, this raises a seperate issue which is that we are compiling
to use bio2jack as a shared library... For the sake of a small header
file and a block of code I would much prefer to simply include bio2jack
in mplayer source and then we can at least be sure that we are
distributing something which works to the end user... CVS would
obviously then have to track bio2jack source, but at least we don't
break when bio2jack breaks. What do you think? I can provide all the
files, but I'm not sure how to change the various makefiles...?
>> long JACK_GetJackLatency(int deviceID); /* return the latency in
>> milliseconds of jack */
>> int JACK_SetState(int deviceID, enum status_enum state); /*
>> playing, paused, stopped */
>> -int JACK_SetVolumeForChannel(int deviceID, unsigned int channel,
>> unsigned int volume);
>> +int JACK_SetAllVolume(int deviceID, unsigned int volume); /*
>> returns 0 on success */
>> +int JACK_SetVolumeForChannel(int deviceID, unsigned int channel,
>> unsigned int volume); /* return 0 on success */
>
>
> You only added a comment to the line with JACK_SetVolumeForChannel. If
> you really want those comments put them on seperate lines and make
> them doxygen-style.
Fair enough. I think this was a cut and paste from bio2jack.h. I will
remove the comments.
(I added comments to all lines though, so not sure exactly that this was
what you meant?)
>> unsigned int bits_per_sample;
>> -
>> +
>
> cosmetics.
Yeah, sorry about that. Something to do with my copy of vi
interchanging tabs and spaces. I have never quick mastered the relevant
config to control this properly... Will resubmit
>> + unsigned int jack_port_name_count=0;
>> + const char *jack_port_name=NULL;
>> +
>> mp_msg(MSGT_AO, MSGL_INFO, "AO: [Jack] Initialising library.\n");
>> JACK_Init();
>>
>> + if (ao_subdevice) {
>> + jack_port_flags = 0;
>> + jack_port_name_count = 1;
>
>
> What purpose does this variable have?
Which variable? They are all used in Jack_OpenEx. Basically the syntax
is slightly different if you just want it to pick a handy physical
output device, versus whether you want it to bind to some other filter
in the chain. This code should handle those conditions. (without a
bunch of IF statements)
> You only removed a lonely tab in this last line...
Yeah, sorry. Does it matter?
>> + // Rather rough way to find out the rough number of bytes
>> buffered
>> + approx_bytes_in_jackd = JACK_GetJackBufferedBytes(driver) * 2;
>> +
>
>
> Maybe a bit too rough a way... This might break more than it fixes...
Unlikely (to be worse than not doing it). We are counting "backwards",
and the function call tells us the size of the audio buffer. We know
that there must be at least two buffers, and also that Jack defaults to
using two buffers, and also that Jack will frequently be left with two
buffers for real use (since it's a low latency audio system).
If you take this line out then you will *always* have lipsync issues.
If you leave it in, then you *may* have lipsync issues in a few unusual
configurations. However, right now there is no API to do better than
that, but I am talking with the bio2jack author about how we can do
better. Expect a later patch to improve on this behaviour, but I think
at the moment it is pretty good as per above.
>> static int play(void* data,int len,int flags)
>> {
>> - return JACK_Write(driver, data, len);
>> + int ret=0;
>> + ret = JACK_Write(driver, data, len);
>> + return ret;
>> }
>
>
> I can see no functional change here...
Agreed. It is only a little more convenient for testing. Would you
prefer not to have this kind of thing changed then?
>> @@ -181,6 +213,9 @@
>> static void reset()
>> {
>> JACK_Reset(driver);
>> + latency = JACK_GetJackLatency(driver);
>> + // Rather rough way to find out the rough number of bytes buffered
>> + approx_bytes_in_jackd = JACK_GetJackBufferedBytes(driver);
>
>
> Why is this done here?
As stated above, we should perhaps check the size of the audio buffers
constantly, but since it's highly unusual (and quite difficult) to
change the size of the audio buffer whilst actually running then we can
compromise and just check the size of the buffer when we init the driver
and on any major resets.
I don't actually know when Reset is called in general though? Perhaps
it never is called in any useful situations?
>> @@ -192,6 +227,8 @@
>>
>> static float get_delay()
>> {
>> - return (float )JACK_GetJackLatency(driver);
>> + float ret=0;
>> + ret = (JACK_GetBytesStored(driver) + approx_bytes_in_jackd +
>> latency) / (float)ao_data.bps;
>> + return ret;
>> }
>
>
> Either this is wrong or the JACK_GetJackLatency function has an
> idiotic name I think...
Nope, it's correct and the name is not too idiotic. The
JACK_GetJackLatency gets the fixed latency of the Jack audio server
(usually zero). It is measured in terms of the number of buffers of
delay which will be incurred as a result of a complex graph, or some sub
filter which creates a filter delay. On the other hand bio2jack has
it's own larger audio buffer (since we are converting a callback style
api to a blocking style api) and this is measured by the
JACK_GetBytesStored function
So our calculation here is: "Bytes in the bio2jack layer" + bytes in
the jack subsystem (fixed) + overhead/latency in the jack graph
Does that make any sense?
New patch attached
Thanks
Ed W
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: mplayer_jack3.diff
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20041018/694f1ed6/attachment.txt>
More information about the MPlayer-dev-eng
mailing list