On Freitag, 21. Juli 2023 04:16:05 CEST you wrote: > The cairoblend transition has an optimization that if the b frame is > opaque, it will never request the a frame > imagehttps://github.com/mltframework/mlt/blob/master/src/modules/frei0r/tra > nsition_frei0r.c#L61 When this optimization is triggered, get_frame is never > called on the a frame. As a result, the field order filter never has a > chance to set the top_field_first flag on the a > frame.https://github.com/mltframework/mlt/blob/master/src/modules/core/filt > er_fieldorder.c#L115 > > As a test, you can defeat the optimization in a couple of ways:* Set > invert=1 on the transition* Set the color to be slightly transparent* > Comment out the optimization in the code What should be done in this > optimization case? I am not sure. Maybe copy the key image properties from > the b frame to the a frame. There are many others that could be included. > This might be a pretty good list here: > https://github.com/mltframework/mlt/blob/master/src/framework/mlt_tractor.c > #L379
Thanks a lot for the help and analysis, that helped. I was able to fix the problem by moving the mlt_tractor 's frame properties stuff (as linked above) to a new function called mlt_tractor_pass_properties, and then call this function in the cairoblend and qtblend optimisation. Attached is my patch. If that approach seems ok for you, I can create a pull request. Best regards, Jean-Baptiste > Or maybe there could be a different trick like all the contents of the > a_frame and b_frame could be swapped when performing this optimization. > ~Brian > > > On Thursday, July 20, 2023 at 02:42:47 AM CDT, Jean-Baptiste Mardelle > <[email protected]> wrote: > > Hi all, > > I was recently made aware of an issue in interlaced rendering that seems > like a bug but I am not exactly sure where the problem lies. > > The problem is that in some cases, MLT renders an interlaced video with > bottom field first, even when asked for a top field first result. I tracked > down the issue to some transitions. For example with a simple 2 track color > sample : > > melt color:red out=20 -track color:blue out=20 -consumer avformat:test.mp4 > f=mxf progressive=0 real_time=-1 threads=0 top_field_first=1 > vcodec=mpeg2video > > Produces a correct top field first video. Now if you add a transition but > keep the exact same rendering parameters: > > melt color:red out=20 -track color:blue out=20 -transition frei0r.cairoblend > a_track=0 b_track=1 out=20 -consumer avformat:test.mp4 f=mxf progressive=0 > real_time=-1 threads=0 top_field_first=1 vcodec=mpeg2video > > You get an interlaced video with bottom field first! > Not all transition seem to have this problem, but at least frei0r.cairoblend > and qtblend do break the field order. > > FYI, I used mediainfo to detect the field order of the rendered videos. > > Do you have any hint on where / how to fix this ? > Thanks a lot, > > Jean-Baptiste_______________________________________________ > Mlt-devel mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/mlt-devel
diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers
index 6cd3d394..5999bf4b 100644
--- a/src/framework/mlt.vers
+++ b/src/framework/mlt.vers
@@ -680,4 +680,5 @@ MLT_7.16.0 {
MLT_7.18.0 {
global:
mlt_audio_free_data;
+ mlt_tractor_pass_properties;
} MLT_7.16.0;
diff --git a/src/framework/mlt_tractor.c b/src/framework/mlt_tractor.c
index 287913f8..b1306c3e 100644
--- a/src/framework/mlt_tractor.c
+++ b/src/framework/mlt_tractor.c
@@ -345,41 +345,14 @@ mlt_producer mlt_tractor_get_track(mlt_tractor self, int index)
return mlt_multitrack_track(mlt_tractor_multitrack(self), index);
}
-static int producer_get_image(mlt_frame self,
- uint8_t **buffer,
- mlt_image_format *format,
- int *width,
- int *height,
- int writable)
-{
- uint8_t *data = NULL;
- int size = 0;
- mlt_properties properties = MLT_FRAME_PROPERTIES(self);
- mlt_frame frame = mlt_frame_pop_service(self);
- mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame);
-
- mlt_properties_set_int(frame_properties,
- "resize_alpha",
- mlt_properties_get_int(properties, "resize_alpha"));
- mlt_properties_set_int(frame_properties,
- "distort",
- mlt_properties_get_int(properties, "distort"));
- mlt_properties_copy(frame_properties, properties, "consumer.");
- // WebVfx uses this to setup a consumer-stopping event handler.
- mlt_properties_set_data(frame_properties,
- "consumer",
- mlt_properties_get_data(properties, "consumer", NULL),
- 0,
- NULL,
- NULL);
-
- mlt_frame_get_image(frame, buffer, format, width, height, writable);
- mlt_frame_set_image(self, *buffer, 0, NULL);
+/** Pass the consumer defined frame values from one frame to another
+ *
+ * \param properties The destination frame properties
+ * \param frame_properties The source frame properties
+ */
- mlt_properties_set_int(properties, "width", *width);
- mlt_properties_set_int(properties, "height", *height);
- mlt_properties_set_int(properties, "format", *format);
- mlt_properties_set_double(properties, "aspect_ratio", mlt_frame_get_aspect_ratio(frame));
+void mlt_tractor_pass_properties(mlt_properties properties, mlt_properties frame_properties)
+{
mlt_properties_set_int(properties,
"progressive",
mlt_properties_get_int(frame_properties, "progressive"));
@@ -426,6 +399,45 @@ static int producer_get_image(mlt_frame self,
NULL);
}
}
+}
+
+static int producer_get_image(mlt_frame self,
+ uint8_t **buffer,
+ mlt_image_format *format,
+ int *width,
+ int *height,
+ int writable)
+{
+ uint8_t *data = NULL;
+ int size = 0;
+ mlt_properties properties = MLT_FRAME_PROPERTIES(self);
+ mlt_frame frame = mlt_frame_pop_service(self);
+ mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame);
+
+ mlt_properties_set_int(frame_properties,
+ "resize_alpha",
+ mlt_properties_get_int(properties, "resize_alpha"));
+ mlt_properties_set_int(frame_properties,
+ "distort",
+ mlt_properties_get_int(properties, "distort"));
+ mlt_properties_copy(frame_properties, properties, "consumer.");
+ // WebVfx uses this to setup a consumer-stopping event handler.
+ mlt_properties_set_data(frame_properties,
+ "consumer",
+ mlt_properties_get_data(properties, "consumer", NULL),
+ 0,
+ NULL,
+ NULL);
+
+ mlt_frame_get_image(frame, buffer, format, width, height, writable);
+ mlt_frame_set_image(self, *buffer, 0, NULL);
+
+ mlt_properties_set_int(properties, "width", *width);
+ mlt_properties_set_int(properties, "height", *height);
+ mlt_properties_set_int(properties, "format", *format);
+ mlt_properties_set_double(properties, "aspect_ratio", mlt_frame_get_aspect_ratio(frame));
+
+ mlt_tractor_pass_properties(properties, frame_properties);
data = mlt_frame_get_alpha_size(frame, &size);
if (data) {
diff --git a/src/framework/mlt_tractor.h b/src/framework/mlt_tractor.h
index e8206ed9..c4d41a2b 100644
--- a/src/framework/mlt_tractor.h
+++ b/src/framework/mlt_tractor.h
@@ -60,5 +60,6 @@ extern int mlt_tractor_insert_track(mlt_tractor self, mlt_producer producer, int
extern int mlt_tractor_remove_track(mlt_tractor self, int index);
extern mlt_producer mlt_tractor_get_track(mlt_tractor self, int index);
extern void mlt_tractor_close(mlt_tractor self);
+extern void mlt_tractor_pass_properties(mlt_properties properties, mlt_properties frame_properties);
#endif
diff --git a/src/modules/frei0r/transition_frei0r.c b/src/modules/frei0r/transition_frei0r.c
index 1dc4e2ed..756e5148 100644
--- a/src/modules/frei0r/transition_frei0r.c
+++ b/src/modules/frei0r/transition_frei0r.c
@@ -68,9 +68,12 @@ static int transition_get_image(mlt_frame a_frame,
// Check if the alpha channel is entirely opaque.
&& mlt_image_rgba_opaque(images[1], *width, *height)) {
if (invert)
+ {
error = mlt_frame_get_image(a_frame, image, format, width, height, 0);
- else
+ } else {
+ mlt_tractor_pass_properties(a_props, b_props);
*image = images[1];
+ }
} else {
error = mlt_frame_get_image(a_frame, &images[0], format, width, height, 0);
if (error)
diff --git a/src/modules/qt/transition_qtblend.cpp b/src/modules/qt/transition_qtblend.cpp
index 9ed48c04..162ab21d 100644
--- a/src/modules/qt/transition_qtblend.cpp
+++ b/src/modules/qt/transition_qtblend.cpp
@@ -189,6 +189,7 @@ static int get_image(mlt_frame a_frame,
}
if (!hasAlpha) {
// Prepare output image
+ mlt_tractor_pass_properties(properties, b_properties);
if (b_frame->convert_image && (b_width != request_width || b_height != request_height)) {
mlt_properties_set_int(b_properties, "convert_image_width", request_width);
mlt_properties_set_int(b_properties, "convert_image_height", request_height);
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Mlt-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mlt-devel
