[FFmpeg-devel] [PATCH] libavdevice: JACK demuxer

Olivier Guilyardi list
Sat Feb 28 14:41:51 CET 2009


Michael Niedermayer a ?crit :
> On Sat, Feb 28, 2009 at 01:46:21AM +0100, Olivier Guilyardi wrote:
>> Version 0.6 of the jack demuxer path is attached.
> [...]
>>>> +            latency = latency / self->nports;
>>>> +            cycle_delay = jack_frames_since_cycle_start(self->client);
>>>> +            info.pts = av_gettime() - (latency + cycle_delay) * self->frame_ms;
>>> does jack not provide a timestamp for the returned audio?
>> Jack doesn't provide any absolute timestamp. Only some running counters. This is
>> one of the reasons why I asked whether timestamps should be absolute or relative
>> in an earlier post.
> 
> we need timestamps that are compareable to the "system clock/wall clock" so
> audio/video sync is possible. We also need accurate timestamps and
> av_gettime() is probably not accurate enough for many uses.
> I assume the running counters count samples and not true time?
> If so JACK has the same problem OSS has.

JACK does feature some sophisticated time computing routines, but nothing for 
absolute (system/wall) timestamps.

> this needs something like
> 
> estimated_time = av_gettime() - (latency + cycle_delay) * self->frame_ms; (taken from your code)
> 
> pts= last_pts + samples_since_last_time / sample_rate
> pts+= (estimated_time - pts)*0.01;
> sample_rate+= (samples_since_last_time/estimated_time_since_last - sample_rate)*0.001;

I have something better to propose you: Delay Locked Loop (DLL) time filtering. 
I didn't use it at first, because I was unsure that it fitted the job, and to 
avoid creating some confusion.

More about it by Fons Adriaensen:
http://www.kokkinizita.net/papers/usingdll.pdf

> also as our OSS code doesnt have something similar yet, you would possibly
> make some people happy if you could implement this in a seperate file, & patch
> and it could be used by both ...
> (note the 0.001 / 0.01 constants are arbitary picked by me and likely poor
>  choices, and above code is untested ...)

You are in a lucky day, I implemented DLL filtering as a small standalone 
library, libpendule, a few weeks ago:

http://svn.samalyse.com/pendule/trunk/

We've done quite a lot of measuring on various hardware (see the README about 
./measure and ./graph), and the results are very good in regard to jitter reduction.

libpendule actually consists into two very small files, pendule.h and pendule.c, 
with no dependency. It could be used in the oss demuxer, and possibly others. 
Plus, I'll make you a good price ;) Do you buy?

> 
> [...]
>>>> +    for (i = 0; i < self->nports; i++) {
>>>> +        jack_ringbuffer_read(self->data_rb, (char *) self->channel_buffer,
>>>> +                             info.size * sizeof(float));
>>>> +        for (j = 0; j < info.size; j++) {
>>>> +            output_data[j * self->nports + i] = self->channel_buffer[j];
>>>> +        }
>>>> +    }
>>> useless copy?
>>> why not allocate a packet (or several) and read directly into them?
>> The data needs to be interleaved. Doing this efficiently in-place is non
>> trivial, because there might be more than 2 input channels. In other terms this
>> is a matrix transposition with an unknown number of rows and columns. For
>> example, 
> 
> is the ringbuffer stuff doing a copy on its own? if so maybe you should
> not use it but rather directly copy & interleave the data into AVPackets.

Yes, the way I use the ringbuffer implies two copy operations (w+r).

There is an important point to consider: the process_callback function is 
running in a thread with realtime priority, and mustn't do anything that could 
block. In particular, allocating memory (and thus packets) in there isn't an 
option at all.

Plus, there is no way to use a standard lock mechanism (except with 
pthread_mutex_trylock()) to share memory with the other thread. This is why most 
Jack apps use so-called lock-free ringbuffers, which are perfect in this 
context: http://jackaudio.org/files/docs/html/ringbuffer_8h.html

However, I think some copy operation(s) could be suppressed. Please give me a 
few days to sort that out. Tell me if you have any realtime-safe ideas.

--
   Olivier




More information about the ffmpeg-devel mailing list