Hi! It’s been a while 🙂
And sorry for that, I had planned to update last week but couldn’t do so as I had few health issues but now I’m alright.
The QML MLT producer – the progress so far…
From my understanding so far (forgive me for any mistakes that I might make – it’s a different codebase and different concepts – I wholeheartedly welcome corrections and suggestions) the whole producer boils down to two parts – the actual producer code (which is in C and which is the thing which does the ‘producer stuff’) and the wrapper code (which ‘wraps’, supplements and does the actual rendering part of the QML frames). The wrapper files are responsible for mainly rendering the QML templates that are passed to it and make it available for the actual producer to use. And consequently, most of the work is to be done in the wrapper files, as the producer in itself doesn’t change much as it will still do the same things like the existing XML producer (producer_kdenlivetitle.c) – such as loading a file, generating a frame, calling rendering methods from the wrapper files.
So let’s see what work has been done. Starting with the new producer file in mlt/src/modules/qt/producer_qml.c
void read_qml(mlt_properties properties)
As the name suggests, it opens a “resource” file and stores the QML file in the global mlt_properties which is passed.
static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
This method takes in a frame and makes use of the wrapper file – it calls the method which does the rendering part in the wrapper files ( renderKdenliveTitle() ) and sets the rendered image using mlt_frame_set_image to the frame that was passed.
static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
This method generates a frame, calls producer_get_image() and sets a ready rendered frame for the producer, and prepares for the next frame.
The wrapper file has the following methods –
void loadQml( producer_ktitle_qml self, const char *templateQml )
What this method does is – it loads a QML file which is a pointer to a char array and does a bunch of stuff – it checks if it is valid, initialises few properties using mlt_properties_set() methods (width and height). The next method we have is –
void renderKdenliveTitle( producer_ktitle_qml self, mlt_frame frame, mlt_image_format format, int width, int height, double position, int force_refresh )
renderKdenliveTitle() does the rendering part – given a mlt_frame, format and its parameters. And here is where I use QmlRenderer – my last month’s work – it renders QML. I refactored the code a bit to return a rendered QImage in the library. I make use of the renderSingleFrame() method which renders a QML frame for a given position (time)
The programming part in itself wasn’t difficult (although it is far, far from a complete producer – there are a lot of memory leaks right now), understanding how all of it works together in a piece is what took the most effort – in fact it took me a little more than week just to understand and comprehend working of the producer codebase!
For most of the part, I believe 80% of the producer work is done. The plan is to get a working, solid producer by next week. Although the current code is still far from a ready producer although the whole structure is set and most of the refactoring that had to be be done in the QmlRenderer library in order to accommodate the producer methods is done.
Also, the build system for the QmlRenderer lib was revamped, it’s a clean build system (thanks to Vincent), so for building, all you need to do is clone the repository and do this –
mkdir build cd build qmake -r .. make cd bin ./QmlRender -o /path/to/output/directory -i /path/to/input/QML/file
You can view the code for the QML MLT producer here.