Hi Dan,<div><br></div><div>the last days I had some time and I worked on the jack integration in kdenlive. Now I'm some steps farther.</div><div>But I have two issues:</div><div><br></div><div><b>#1: MLT hangs on closing when filter_jackrack was active and videoglwidget.cpp is compiled in kdenlive (opengl activated)</b></div>
<div><br></div><div>It was tricky to find this problem but now its clear. When in Kdenlive OPENGL is activated (see src/CMakeLists.txt)</div><div><br></div><div>if(OPENGL_FOUND)</div><div>  list(APPEND kdenlive_SRCS videoglwidget.cpp)</div>
<div>endif(OPENGL_FOUND)</div><div><br></div><div>then mlt (kdenlive) hangs forever on closing when the filter_jackrack was loaded. If you shutdown the jackd before closing the </div><div>program it closes without hanging. If I compile kdenlive without videoglwidget.cpp all is working just perfect. It seems that there are</div>
<div>some side effects between jackd/filter_jackrack and opengl.</div><div><br></div><div><b>Any ideas what the problem is?</b></div><div><br></div><div><br></div><div><b>#2: funny sinus sound on transport stop when sdl_preview consumer is used instead of sdl </b></div>
<div><br></div><div>Steps to reproduce: </div><div><br></div><div>1) bash# MLT_CONSUMER=sdl_preview melt -jack my_sound.wav </div><div>2) start jack transport</div><div>3) stop jack transport</div><div><br></div><div>Now you can hear a pretty cool sinus tone or something like that with different frequencies and volumes on every stop.</div>
<div><br></div><div>The reason for this is the code in consumer_sdl_preview.c:</div><div><br></div><div>static void *consumer_thread( void *arg )</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>...</div>
<div>        int <b>eos_threshold </b>= 20 + mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( this->play ), "buffer" );</div><div>        ...</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>// Loop until told not to</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>while( this->running )</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>{</div><div><span class="Apple-tab-span" style="white-space:pre">            </span>// Get a frame from the attached producer</div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>frame = mlt_consumer_get_frame( consumer );</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">         </span>// Ensure that we have a frame</div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>if ( this->running && frame != NULL )</div><div><span class="Apple-tab-span" style="white-space:pre">             </span>{</div><div>                        ....</div>
<div><span class="Apple-tab-span" style="white-space:pre">                      </span>// If we aren't playing normally, then use the still</div><div><span class="Apple-tab-span" style="white-space:pre">                     </span>if ( speed != 1 )</div>
<div><span class="Apple-tab-span" style="white-space:pre">                      </span>{</div><div><span class="Apple-tab-span" style="white-space:pre">                            </span>mlt_producer producer = MLT_PRODUCER( mlt_service_get_producer( MLT_CONSUMER_SERVICE( consumer ) ) );</div>
<div><span class="Apple-tab-span" style="white-space:pre">                              </span>mlt_position duration = producer? mlt_producer_get_playtime( producer ) : -1;</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>int pause = 0;</div>
<div><br></div><div>#ifndef SKIP_WAIT_EOS</div><div><span class="Apple-tab-span" style="white-space:pre">                         </span>if ( this->active == this->play )</div><div><span class="Apple-tab-span" style="white-space:pre">                              </span>{</div>
<div><span class="Apple-tab-span" style="white-space:pre">                                      </span>// Do not interrupt the play consumer near the end</div><div><span class="Apple-tab-span" style="white-space:pre">                                   </span>if ( <b>duration - this->last_position > eos_threshold</b> ) <b> <--- this criteria is true on jack transport stop, why? </b></div>
<div><span class="Apple-tab-span" style="white-space:pre">                                      </span>{</div><div><span class="Apple-tab-span" style="white-space:pre">                                            </span>// Get a new frame at the sought position</div><div><span class="Apple-tab-span" style="white-space:pre">                                            </span>mlt_frame_close( frame );</div>
<div><span class="Apple-tab-span" style="white-space:pre">                                              </span>if ( producer )</div><div><span class="Apple-tab-span" style="white-space:pre">                                                      </span>mlt_producer_seek( producer, this->last_position );</div>
<div><span class="Apple-tab-span" style="white-space:pre">                                              </span>frame = mlt_consumer_get_frame( consumer );</div><div><span class="Apple-tab-span" style="white-space:pre">                                          </span>pause = 1;</div><div><span class="Apple-tab-span" style="white-space:pre">                                   </span>}</div>
<div>                                ...</div><div><span class="Apple-tab-span" style="white-space:pre">                            </span>}</div><div>#else</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>pause = this->active == this->play;</div>
<div>#endif</div><div><span class="Apple-tab-span" style="white-space:pre">                         </span>if ( <b>pause </b>) <b><--- pause is true and the this->play (sdl) consumer is stopped </b></div><div><span class="Apple-tab-span" style="white-space:pre">                            </span>{</div>
<div><span class="Apple-tab-span" style="white-space:pre">                                      </span>// Start the still consumer</div><div><span class="Apple-tab-span" style="white-space:pre">                                  </span><b>mlt_consumer_stop( this->play );</b></div>
<div><span class="Apple-tab-span" style="white-space:pre">                                      </span>this->last_speed = speed;</div><div><span class="Apple-tab-span" style="white-space:pre">                                 </span>this->active = this->still;</div><div><span class="Apple-tab-span" style="white-space:pre">                                    </span>this->ignore_change = 0;</div>
<div><span class="Apple-tab-span" style="white-space:pre">                                      </span>mlt_consumer_start( this->still );</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>}</div><div>                                ...</div>
<div>} </div><div><br></div><div>The result is that in filter_jackrack.c:</div><div><br></div><div>the function <b>jackrack_get_audio</b>() is not called and the jack "output_buffers" is not filled with data. Then in <b>jack_process</b></div>
<div><br></div><div><div><br></div><div>static int <b>jack_process</b> (jack_nframes_t frames, void * data)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>...</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>for ( i = 0; i < channels; i++ )</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>{</div><div><span class="Apple-tab-span" style="white-space:pre">            </span>size_t jack_size = ( frames * sizeof(float) );</div><div><span class="Apple-tab-span" style="white-space:pre">               </span>size_t ring_size;</div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span></div><div><span class="Apple-tab-span" style="white-space:pre">             </span>// Send audio through out port</div><div><span class="Apple-tab-span" style="white-space:pre">               </span>jack_output_buffers[i] = jack_port_get_buffer( jack_output_ports[i], frames );</div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>if ( ! jack_output_buffers[i] )</div><div><span class="Apple-tab-span" style="white-space:pre">              </span>{</div><div><span class="Apple-tab-span" style="white-space:pre">                    </span>mlt_log_error( MLT_FILTER_SERVICE(filter), "no buffer for output port %d\n", i );</div>
<div><span class="Apple-tab-span" style="white-space:pre">                      </span>err = 1;</div><div><span class="Apple-tab-span" style="white-space:pre">                     </span>break;</div><div><span class="Apple-tab-span" style="white-space:pre">               </span>}</div>
<div><b><span class="Apple-tab-span" style="white-space:pre">             </span>ring_size = jack_ringbuffer_read_space( output_buffers[i] );  <--- ring_size = 0, nothing is copied to jackd</b></div><div><b><span class="Apple-tab-span" style="white-space:pre">           </span>jack_ringbuffer_read( output_buffers[i], ( char * )jack_output_buffers[i], ring_size < jack_size ? ring_size : jack_size );</b></div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>....</div><div>}</div></div><div><br></div><div>the <b>ring_size </b>is 0 and no data is transfered to the jack outport (<b>jack_output_buffers). </b>In this case jackd produces a very painful sound (the mlt jack outports are connected to system).</div>
<div>You get the same result if you set a breakpoint in the jack_process or the consumer_thread.<b> </b></div><div><b><br></b></div><div>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. </div>
<div><br></div><div>Kdenlive uses the sdl_preview consumer for the monitors. Thats why I need a solution for the sdl_preview consumer.</div><div><br></div><div><b>Is there a solution for this (my) problem? </b>
</div><div><br></div><div>Thanks</div><div>eddrog</div><div><br></div>