From: Zhao Zhili <quinkblack@foxmail.com> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: Re: [FFmpeg-devel] [PATCH] lavd/sdl2: postpone sdl2 window creation Date: Mon, 9 Oct 2023 15:08:34 +0800 Message-ID: <tencent_8E99804E343D3ED756479CACE0105A1C3509@qq.com> (raw) In-Reply-To: <7cefb97575e05a358390dafea926174a7ea7c7d8.camel@intel.com> > On Sep 19, 2023, at 14:32, Xiang, Haihao <haihao.xiang-at-intel.com@ffmpeg.org> wrote: > > On Ma, 2023-09-18 at 14:00 +0200, Andreas Rheinhardt wrote: >> Xiang, Haihao: >>> From: Haihao Xiang <haihao.xiang@intel.com> >>> >>> Since 2d924b3, sdl2_write_header() and sdl2_write_packet() are called >>> in two different threads. However SDL2 requires window creation and >>> rendering should be done in the same thread, otherwise it shows nothing >>> when specifying SDL2 output device. >> >> Modifying a library to fix behaviour in an application (even the FFmpeg >> tool) is very fishy. > > Seems calling sdl2_write_header() and sdl2_write_packet() in two different > threads are allowed. I think the change in commit 2d924b3 revealed a bug in > libavdevice, we should fix libavdevice. SDL *must* be run in main thread on some platform like macOS. I don’t think it’s practical to fix the issue inside libavdevice. Add some checks like wether write_header and write packet run in the same thread can be helpful, but it doesn’t solve current issue. *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'API misuse warning: setting the main menu on a non-main thread. Main menu contents should only be modified from the main thread.' *** First throw call stack: ( 0 CoreFoundation 0x00000001872c88c0 __exceptionPreprocess + 176 1 libobjc.A.dylib 0x0000000186dc1eb4 objc_exception_throw + 60 2 Foundation 0x000000018840f18c -[NSCalendarDate initWithCoder:] + 0 3 AppKit 0x000000018aa0a444 -[NSMenu _setMenuName:] + 488 4 AppKit 0x000000018aa1efe8 -[NSApplication setMainMenu:] + 372 5 libSDL2-2.0.0.dylib 0x00000001044c9704 Cocoa_RegisterApp + 420 6 libSDL2-2.0.0.dylib 0x00000001044cf124 Cocoa_CreateDevice + 28 7 libSDL2-2.0.0.dylib 0x00000001044b7084 SDL_VideoInit_REAL + 464 8 libSDL2-2.0.0.dylib 0x000000010442787c SDL_InitSubSystem_REAL + 204 > > >> This patch makes things worse for people who want >> their call to avformat_write_header() to actually check whether sdl2 works. > > sdl2_write_header() always returns 0 (you also pointed it out below), so this > change doesn't have impact to user if user want to use avformat_write_header() > to check whether sdl2 works. > >> >>> >>> $ ffmpeg -f lavfi -i yuvtestsrc -pix_fmt yuv420p -f sdl2 "sdl2" >>> >>> Signed-off-by: Haihao Xiang <haihao.xiang@intel.com> >>> --- >>> libavdevice/sdl2.c | 13 +++++++++++++ >>> 1 file changed, 13 insertions(+) >>> >>> diff --git a/libavdevice/sdl2.c b/libavdevice/sdl2.c >>> index 342a253dc0..c9f7f03c28 100644 >>> --- a/libavdevice/sdl2.c >>> +++ b/libavdevice/sdl2.c >>> @@ -158,6 +158,11 @@ static int sdl2_write_trailer(AVFormatContext *s) >>> } >>> >>> static int sdl2_write_header(AVFormatContext *s) >>> +{ >>> + return 0; >>> +} >> >> There is no reason to keep an empty write-header function around. Just >> delete the function pointer in the FFOutputFormat. > > Thanks for pointing it out, I will delete it in the next version if you agree we > should fix the library. > >> >>> + >>> +static int sdl2_init(AVFormatContext *s) >>> { >>> SDLContext *sdl = s->priv_data; >>> AVStream *st = s->streams[0]; >>> @@ -165,6 +170,9 @@ static int sdl2_write_header(AVFormatContext *s) >>> int i, ret = 0; >>> int flags = 0; >>> >>> + if (sdl->inited) >> >> I am not an sdl2-expert at all (in fact, your patch made me read their >> headers for the first time), but it seems to me that you misread the >> semantics of "inited": It is set if someone else already initialized the >> library or if we called sdl2_write_header() without entering the fail >> path. In particular, inited being set does not mean that we called >> sdl2_write_header() without entering the fail path. >> >> The reason I am writing "without entering the fail path" and not >> "returns an error" is that sdl2_write_header() actually never sets an >> error on any error path. This means that the sdl2_init() below will >> always succeed. > > Honestly I am not an sdl2 expert too. I noticed sdl2_write_header() always > return 0, and sdl2_write_packet() is called even if sdl2_write_header() enters > the fail path. What I wanted is to make sdl2 works again and do not change the > code too much, hence I made sdl2_init() works as sdl2_write_header() with a > small change. I should look into the usage of inited carefully. > >> >> Given that inited is currently only used for one thing (namely checking >> whether SDL_Quit() should be called), it would be equivalent to the >> current code to move the call to SDL_Quit() to the error path in >> sdl2_write_header() and to make inited a local variable in >> sdl2_write_header(). >> >> The reason for the way inited is handled seems to me that because >> SDL_Quit() quits everything (and discards reference counters etc.), it >> may only be called if no one else uses SDL2, hence not calling >> SDL_Quit() if it was already initialized or if someone else may have >> initialized it after we have have returned via the non-error path in >> sdl2_write_header(). >> >> I think that this is wrong even if all interactions with SDL2 happen >> only in one thread: The check for whether SDL2 was already initialized >> only checks for whether the video subsystem was initialized. But other >> subsystems might have already been initialized and these would also be >> killed by SDL_Quit(). >> >> Therefore I think that we should never call SDL_Quit(). Instead we >> should call SDL_InitSubSystem() and call SDL_QuitSubSystem() iff >> SDL_InitSubSystem() succeeded. This is refcounted. And then >> write_trailer should be made a deinit function. >> >> I just made a quick test and this reduces the still reachable amount of >> memory at the end (as reported by Valgrind) considerably (from 5,314,497 >> to 312,104). > > How about to fix sdl initialization and memory issue in a separate patch if > someone is interested ? > >> >> Sorry for this rant which does not affect your threading issue at all. > > Never mind and many thanks for your valuable comments. > > BRs > Haihao > >> >>> + return 0; >>> + >>> if (!sdl->window_title) >>> sdl->window_title = av_strdup(s->url); >>> >>> @@ -249,6 +257,11 @@ static int sdl2_write_packet(AVFormatContext *s, >>> AVPacket *pkt) >>> int linesize[4]; >>> >>> SDL_Event event; >>> + >>> + ret = sdl2_init(s); >>> + if (ret) >>> + return ret; >>> + >>> if (SDL_PollEvent(&event)){ >>> switch (event.type) { >>> case SDL_KEYDOWN: >> >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> To unsubscribe, visit link above, or email >> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
prev parent reply other threads:[~2023-10-09 7:09 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-09-18 6:37 Xiang, Haihao 2023-09-18 12:00 ` Andreas Rheinhardt 2023-09-19 6:32 ` Xiang, Haihao 2023-10-09 7:08 ` Zhao Zhili [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=tencent_8E99804E343D3ED756479CACE0105A1C3509@qq.com \ --to=quinkblack@foxmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git