Skip to content

melt: skip Qt preflight for XML-only consumers#1231

Merged
ddennedy merged 1 commit into
mltframework:masterfrom
Komzpa:fixer-skip-qt-preflight-for-xml
May 2, 2026
Merged

melt: skip Qt preflight for XML-only consumers#1231
ddennedy merged 1 commit into
mltframework:masterfrom
Komzpa:fixer-skip-qt-preflight-for-xml

Conversation

@Komzpa
Copy link
Copy Markdown
Contributor

@Komzpa Komzpa commented May 1, 2026

Summary

Move melt's Qt filter preflight until after the requested consumer is known, and skip it for the direct xml consumer.

The xml consumer serializes the MLT service graph instead of rendering frames, so melt <input> -consumer xml should not eagerly instantiate qtcrop only to pre-initialize Qt. Rendering and default/unknown consumer paths still keep the existing main-thread Qt preflight.

This was motivated by an observed Fixer-captured local melt-7 abort whose stack reached filter_qtcrop_init through the Qt preflight while an XML consumer command was involved. I have not independently reproduced the exact original crash from a clean MLT checkout, so this should be read as a narrow cleanup for a valid XML serialization path rather than a proven broad crash fix.

Recovered context

The command came from a small generated Kdenlive workflow for a personal drone-footage edit. The local project generator was using melt ... -consumer xml as part of validating/inspecting generated .kdenlive projects.

After digging into that project, the strongest project-side issue I found was malformed Kdenlive structure: timeline-only hold/timewarp/route-title producers were originally being given bin clip identity (kdenlive:id, kdenlive:folderid, kdenlive:clip_type, kdenlive:clipname) and some timeline entries also carried kdenlive:id. That made Kdenlive treat internal timeline fragments as bin clips, matching the later Clip Problems / invalid preview-producer symptoms. The project generator has since been fixed and linted for that.

That project-side problem is separate from this MLT change. I narrowed this PR accordingly and removed the earlier extra multi/qglsl handling.

Validation

  • Configured and built a reduced local tree with Qt6 and XML enabled:

    cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTING=OFF -DMOD_AVFORMAT=OFF -DMOD_QT6=ON -DMOD_XML=ON -DMOD_KDENLIVE=ON -DMOD_RESAMPLE=OFF -DMOD_RUBBERBAND=OFF -DUSE_LV2=OFF -DUSE_VST2=OFF -DMOD_NORMALIZE=OFF -DMOD_GLAXNIMATE_QT6=OFF -DMOD_MOVIT=OFF -DMOD_OPENCV=OFF -DMOD_DECKLINK=OFF -DMOD_NDI=OFF -DMOD_FREI0R=OFF -DMOD_GDK=OFF -DMOD_JACKRACK=OFF -DMOD_OLDFILM=OFF -DMOD_OPENFX=OFF -DMOD_PLUSGPL=OFF -DMOD_RTAUDIO=OFF -DMOD_SDL2=OFF -DMOD_SOX=OFF -DMOD_VIDSTAB=OFF -DMOD_VORBIS=OFF -DMOD_XINE=OFF

  • cmake --build build -j$(nproc)

  • MLT_REPOSITORY=$PWD/build/out/lib/mlt MLT_DATA=$PWD/build/out/share/mlt QT_QPA_PLATFORM=offscreen build/out/bin/melt color:red out=1 -consumer xml produced XML successfully

  • MLT_REPOSITORY=$PWD/build/out/lib/mlt MLT_DATA=$PWD/build/out/share/mlt QT_QPA_PLATFORM=offscreen build/out/bin/melt color:red -consumer null real_time=-1 terminate_on_pause=1 completed successfully

  • git diff --check

A full avformat build was not possible on this machine because FFmpeg development packages were unavailable, so the exact DJI MP4 command was not rerun against this local MLT checkout.

Comment thread src/melt/melt.c Outdated
@ddennedy
Copy link
Copy Markdown
Member

ddennedy commented May 1, 2026

This is intended to avoid aborts from Qt GUI startup for commands like melt <input> -consumer xml

Are you saying that you are experiencing some kind of failure as a result of that command? Interesting that I have not seen it, and it has not been reported.

@Komzpa
Copy link
Copy Markdown
Contributor Author

Komzpa commented May 1, 2026

Yes. I should have phrased the PR body more cautiously.

What I observed was an actual local melt-7 ABRT captured by Fixer while running an XML consumer command, not a failure I independently reproduced from a clean upstream checkout. I published the sanitized evidence here:

https://fixer.maumap.com/issues/019de528-88fa-7c32-b598-344b21669f2e

The relevant stack signature is:

QMessageLogger::fatal(char const*, ...) const
QGuiApplicationPrivate::createEventDispatcher()
QCoreApplicationPrivate::init()
QGuiApplicationPrivate::init()
QApplicationPrivate::init()
createQApplicationIfNeeded(mlt_service_s*)
filter_qtcrop_init
mlt_factory_filter
main

So the honest statement is: this patch was motivated by an observed coredump where XML output still reached Qt/qtcrop initialization. In my reduced local validation I confirmed that moving the preflight keeps -consumer xml working and keeps a rendering-ish/null path working, but I did not reproduce the exact original MP4 crash locally because that reduced build did not include avformat.

If this direction looks wrong or too speculative for MLT, I am happy to close the PR rather than waste maintainer time. If the direction is useful, I can update the PR description to say “observed coredump / not independently reproduced” instead of making it sound like a broadly reported failure.

@ddennedy
Copy link
Copy Markdown
Member

ddennedy commented May 1, 2026

Well, it is true that this Qt initialization is not necessary for the very valid use case of melt -consumer xml. I am wondering some about your context: why are you running that? For example, you could be following docs or a tutorial and ran into this problem. Or you can be using some private or unpopular MLT app that is generating MLT XML from complex melt command lines for whatever reason. That answers whether the block I mentioned involving qglsl and multi consumers. Is that really necessary or simply excessive diligence by AI. Are you using qlsl or multi? It would be very weird to use either of those with the xml consumer. Or you cannot really answer because you are simply doing broad bug hunting? Is that kind of the purpose of Fixer? Never heard of it before.

@Komzpa
Copy link
Copy Markdown
Contributor Author

Komzpa commented May 1, 2026

The thing that happened is that I was trying to use AI to help me generate this video: https://www.tiktok.com/@komzpa/video/7618149102383123719 - it's a celebratory video for me passing the driving exam from some drone footage excerpt.

Where it ended is that I had a bunch of scripts that stitch together the final video from the source drone footage. I wanted to adjust it manually and asked Codex to convert it to something I can continue polishing in kdenlive. Unfortunately kdenlive kept crashing in various ways on that generated project (I guess something was missing or slightly wrong, but I don't know what exactly) and I ended up finishing the video in a small ad-hoc created web-based video editor it made just for that clip.

I'll try to recover more details on what exactly was fed into kdenlive/mlt and will come back with answers, or close the PR.

Fixer (https://fixer.maumap.com/) is the service I run on my machines for now, running AI half-manually trying to calibrate it on the stuff I see before advertising more broadly - it happened to collect a stack trace from the crash, and afterwards make some sense of it. I now understand that there probably wasn't enough data recorded to build a proper reproducer, and this PR is more speculative than desirable. I've made some adjustments so there will be more info in the future.

@Komzpa Komzpa force-pushed the fixer-skip-qt-preflight-for-xml branch from ebf19b7 to 4ee221e Compare May 1, 2026 22:58
@Komzpa
Copy link
Copy Markdown
Contributor Author

Komzpa commented May 1, 2026

I recovered more of the local context and narrowed the patch accordingly.

The multi / qglsl handling was excessive; I removed it. The PR now only skips the Qt preflight for the direct xml consumer and leaves all other consumer paths using the existing qtcrop preflight.

The generated Kdenlive project also had its own separate structural problem: timeline-only hold/timewarp/route-title producers were originally marked with bin clip identity (kdenlive:id, kdenlive:folderid, etc.), and some timeline entries carried kdenlive:id even though their producers were not real main_bin assets. That better explains the Kdenlive Clip Problems / preview instability I saw later, and I fixed that in the local generator/linter. So I do not want to claim this MLT patch fixes the Kdenlive project instability.

The remaining MLT-side claim is narrower: melt <input> -consumer xml is a valid serialization path and does not need to instantiate qtcrop just for the main-thread Qt preflight. I updated the PR body with this context and validation.

@ddennedy
Copy link
Copy Markdown
Member

ddennedy commented May 1, 2026

Ignore build error:

D:/a/mlt/mlt/src/modules/jackrack/plugin_mgr.c: In function 'plugin_is_valid':
D:/a/mlt/mlt/src/modules/jackrack/plugin_mgr.c:197:19: error: variable 'icount' set but not used [-Werror=unused-but-set-variable=]
  197 |     unsigned long icount = 0;

Maybe msys2 got a new version of compiler that caught that. Obviously, unrelated to this.

@ddennedy ddennedy added this to the v7.40.0 milestone May 1, 2026
@Komzpa
Copy link
Copy Markdown
Contributor Author

Komzpa commented May 1, 2026

I found a separate, reproducible XML parsing/path issue while going back through the Kdenlive project context: relative <mlt root="..."> is currently resolved against the caller cwd instead of the XML document directory. I opened that as a separate focused PR: #1232

Keeping this PR scoped to the Qt preflight/XML-consumer behavior so the two issues do not get mixed.

@ddennedy ddennedy merged commit ccefc17 into mltframework:master May 2, 2026
15 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants