Search code examples
cxmlvideoffmpegmlt

Inconsistant rendering in mlt XML and C interface and 'hold' producer and avformat consumer


I am trying to create a short video that is just a single image. (I know its a bit silly, but its a test for something bigger).

The code I have for rendering it is:

#include <framework/mlt.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
  if(mlt_factory_init(NULL)) {
    mlt_profile p = mlt_profile_init(NULL);
    mlt_consumer target = mlt_factory_consumer(p, "avformat", 
    mlt_producer source = mlt_factory_producer(p, "hold", "/Users/leif/logo.png");
    mlt_producer_set_in_and_out(source, 0, 10);
    mlt_consumer_connect(target, mlt_producer_service(source));
    mlt_consumer_start(target);

    sleep(5);
    mlt_consumer_stop(target);

    mlt_consumer_close(target);
    mlt_producer_close(source);
    mlt_factory_close();
  } else {
    printf("No\n");
  }

  return 0;
}

Where logo.png is this file.

When I run this code and play output.mp4, the picture comes out all garbelled. There is a green line in the middle and the logo is superimposed on itself a lot.

On the other hand, if I change the consumer to be SDL, the image plays just fine.

And finally, if I change the consumer to be XML, and then use the melt command line application to render it:

melt -consumer avformat:xmlout.mp4 output.xml

and play the video, it also plays fine.

Is there something I am missing in the avformat consumer that I should be setting? Or something else that I am missing here?

Edit: For reference, the outputted xml file: output.xml is:

<?xml version="1.0" encoding="utf-8"?>
<mlt LC_NUMERIC="en_US.UTF-8" version="6.2.0" root="/Users/leif/src/video/private" title="Anonymous Submission" parent="producer0" in="0" out="10">
      <profile description="DV/DVD PAL" width="720" height="576" progressive="0" sample_aspect_num="16" sample_aspect_den="15" display_aspect_num="4" display_aspect_den="3" frame_rate_num="25" frame_rate_den="1" colorspace="601"/>
  <producer id="producer0" title="Anonymous Submission" in="0" out="10">
    <property name="length">15000</property>
    <property name="eof">pause</property>
    <property name="resource">/Users/leif/logo.png</property>
    <property name="aspect_ratio">1.06667</property>
    <property name="frame">0</property>
    <property name="method">onefield</property>
    <property name="mlt_service">hold</property>
    <property name="global_feed">1</property>
  </producer>
</mlt>

Solution

  • From the related bug report:

    mlt_factory_profile() is actually a little tricky and unclear because the framework itself does not mandate agreements between producers and consumers. There is a MLT super-producer called "loader" that adds a bunch of normalization filters to facilitate agreement. And when you specify the service parameter to mlt_factory_producer() you are bypassing this producer. You see in the above linked code a reference to MLT_PRODUCER, which has a default of "loader" defined earlier in that file.

    So, really, to make things work you should say mlt_factory_producer(p, NULL, "hold:/Users/leif/logo.png");

    As for XML, see how producer_xml.c is doing exactly that.