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 > <j...@kdenlive.org> 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 > Mlt-devel@lists.sourceforge.net > 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 Mlt-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mlt-devel