[Kdenlive-devel] current mlt jack issues
Dan Dennedy
dan at dennedy.org
Fri Jun 22 06:34:46 UTC 2012
On Tue, Apr 24, 2012 at 1:22 AM, Ed Rogalsky <ed.rogalsky at googlemail.com> wrote:
> Hi Dan,
>
> the last days I had some time and I worked on the jack integration in
> kdenlive. Now I'm some steps farther.
> But I have two issues:
>
> #1: MLT hangs on closing when filter_jackrack was active and
> videoglwidget.cpp is compiled in kdenlive (opengl activated)
>
> It was tricky to find this problem but now its clear. When in Kdenlive
> OPENGL is activated (see src/CMakeLists.txt)
>
> if(OPENGL_FOUND)
> list(APPEND kdenlive_SRCS videoglwidget.cpp)
> endif(OPENGL_FOUND)
>
> then mlt (kdenlive) hangs forever on closing when the filter_jackrack was
> loaded. If you shutdown the jackd before closing the
> program it closes without hanging. If I compile kdenlive without
> videoglwidget.cpp all is working just perfect. It seems that there are
> some side effects between jackd/filter_jackrack and opengl.
I just integrated jack into Shotcut, which also uses OpenGL very
similarly, and I did not reproduce this problem.
> Any ideas what the problem is?
>
>
> #2: funny sinus sound on transport stop when sdl_preview consumer is used
> instead of sdl
>
> Steps to reproduce:
>
> 1) bash# MLT_CONSUMER=sdl_preview melt -jack my_sound.wav
> 2) start jack transport
> 3) stop jack transport
>
> Now you can hear a pretty cool sinus tone or something like that with
> different frequencies and volumes on every stop.
>
> The reason for this is the code in consumer_sdl_preview.c:
I do not think this is a problem
> static void *consumer_thread( void *arg )
> {
> ...
> int eos_threshold = 20 + mlt_properties_get_int(
> MLT_CONSUMER_PROPERTIES( this->play ), "buffer" );
> ...
> // Loop until told not to
> while( this->running )
> {
> // Get a frame from the attached producer
> frame = mlt_consumer_get_frame( consumer );
>
> // Ensure that we have a frame
> if ( this->running && frame != NULL )
> {
> ....
> // If we aren't playing normally, then use the still
> if ( speed != 1 )
> {
> mlt_producer producer = MLT_PRODUCER( mlt_service_get_producer(
> MLT_CONSUMER_SERVICE( consumer ) ) );
> mlt_position duration = producer? mlt_producer_get_playtime( producer ) :
> -1;
> int pause = 0;
>
> #ifndef SKIP_WAIT_EOS
> if ( this->active == this->play )
> {
> // Do not interrupt the play consumer near the end
> if ( duration - this->last_position > eos_threshold ) <--- this criteria is
> true on jack transport stop, why?
> {
> // Get a new frame at the sought position
> mlt_frame_close( frame );
> if ( producer )
> mlt_producer_seek( producer, this->last_position );
> frame = mlt_consumer_get_frame( consumer );
> pause = 1;
> }
> ...
> }
> #else
> pause = this->active == this->play;
> #endif
> if ( pause ) <--- pause is true and the this->play (sdl) consumer is
> stopped
> {
> // Start the still consumer
> mlt_consumer_stop( this->play );
> this->last_speed = speed;
> this->active = this->still;
> this->ignore_change = 0;
> mlt_consumer_start( this->still );
> }
> ...
> }
>
> The result is that in filter_jackrack.c:
>
> the function jackrack_get_audio() is not called and the jack
> "output_buffers" is not filled with data. Then in jack_process
>
>
> static int jack_process (jack_nframes_t frames, void * data)
> {
> ...
> for ( i = 0; i < channels; i++ )
> {
> size_t jack_size = ( frames * sizeof(float) );
> size_t ring_size;
> // Send audio through out port
> jack_output_buffers[i] = jack_port_get_buffer( jack_output_ports[i], frames
> );
> if ( ! jack_output_buffers[i] )
> {
> mlt_log_error( MLT_FILTER_SERVICE(filter), "no buffer for output port %d\n",
> i );
> err = 1;
> break;
> }
> ring_size = jack_ringbuffer_read_space( output_buffers[i] ); <--- ring_size
> = 0, nothing is copied to jackd
> jack_ringbuffer_read( output_buffers[i], ( char * )jack_output_buffers[i],
> ring_size < jack_size ? ring_size : jack_size );
> ....
> }
>
> the ring_size is 0 and no data is transfered to the jack outport
This is the problem - jack playing unset memory. This is what I have
committed and works for me using melt -jack -consumer sdl_preview.
--- a/src/modules/jackrack/filter_jackrack.c
+++ b/src/modules/jackrack/filter_jackrack.c
@@ -271,6 +271,8 @@ static int jack_process (jack_nframes_t frames, void * data)
}
ring_size = jack_ringbuffer_read_space( output_buffers[i] );
jack_ringbuffer_read( output_buffers[i], ( char *
)jack_output_buffers[i], ring_size < jack_size ? ring_size : jack_size
);
+ if ( ring_size < jack_size )
+ memset( &jack_output_buffers[i][ring_size], 0, jack_size - ring_size );
// Return audio through in port
jack_input_buffers[i] = jack_port_get_buffer( jack_input_ports[i], frames );
> (jack_output_buffers). In this case jackd produces a very painful sound (the
> mlt jack outports are connected to system).
> You get the same result if you set a breakpoint in the jack_process or the
> consumer_thread.
>
> The sdl consumer instead doesn't stop the generation of data and thats why
> you don't get this behaviour for sdl (default consumer). But the SDL
> Consumer doesn't work very well with video data.
>
> Kdenlive uses the sdl_preview consumer for the monitors. Thats why I need a
> solution for the sdl_preview consumer.
>
> Is there a solution for this (my) problem?
>
> Thanks
> eddrog
>
More information about the Kdenlive
mailing list