Re: [FFmpeg-devel] Need help with threading issue (possible deadlock?)
Hi, On Mon, Jul 13, 2015 at 7:15 AM, Donny Yang wrote: > On 13 July 2015 at 20:50, Ronald S. Bultje wrote: > > > Hi, > > > > On Mon, Jul 13, 2015 at 4:26 AM, Donny Yang wrote: > > > > > Hello > > > > > > I'm trying to fix ffmpeg's APNG decoding for images with the PREVIOUS > > > dispose op while trying to keep it multithreaded, but it seems to > > deadlock > > > whenever I use more that one thread. > > > > > > How do I reproduce? ffmpeg -threads 2 -i test.apng -f null - works for > me. > > So does ffplay -threads 2 test.apng > > > > It hangs for me when I run: ffmpeg -threads 2 -i test.apng test_%02d.png > Additionally, ffmpeg -threads 2 -i test.apng -f null - also hangs. > > Maybe it's due to system differences? Can you run it in gdb and - when it hangs - press ctrl-c and run "thread apply all bt"? We can also do some more interactive debugging on IRC. Ronald ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] Need help with threading issue (possible deadlock?)
On 13 July 2015 at 20:50, Ronald S. Bultje wrote: > Hi, > > On Mon, Jul 13, 2015 at 4:26 AM, Donny Yang wrote: > > > Hello > > > > I'm trying to fix ffmpeg's APNG decoding for images with the PREVIOUS > > dispose op while trying to keep it multithreaded, but it seems to > deadlock > > whenever I use more that one thread. > > > How do I reproduce? ffmpeg -threads 2 -i test.apng -f null - works for me. > So does ffplay -threads 2 test.apng > It hangs for me when I run: ffmpeg -threads 2 -i test.apng test_%02d.png Additionally, ffmpeg -threads 2 -i test.apng -f null - also hangs. Maybe it's due to system differences? I've also attached some debug output, if it helps $ uname -a Linux home 3.19.0-22-generic #22~14.04.1-Ubuntu SMP Wed Jun 17 10:03:13 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux $ ldd ffmpeg linux-vdso.so.1 => (0x7ffd5727a000) libXv.so.1 => /usr/lib/x86_64-linux-gnu/libXv.so.1 (0x7fc939451000) libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x7fc93911c000) libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x7fc938f0a000) libva.so.1 => /usr/lib/x86_64-linux-gnu/libva.so.1 (0x7fc938cf4000) libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x7fc938ad5000) libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x7fc9388d2000) libxcb-xfixes.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-xfixes.so.0 (0x7fc9386cb000) libxcb-shape.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shape.so.0 (0x7fc9384c7000) libasound.so.2 => /usr/lib/x86_64-linux-gnu/libasound.so.2 (0x7fc9381d7000) libSDL-1.2.so.0 => /usr/lib/x86_64-linux-gnu/libSDL-1.2.so.0 (0x7fc937f41000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x7fc937c3b000) liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x7fc937a19000) libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x7fc937809000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x7fc9375f) libvdpau.so.1 => /usr/lib/x86_64-linux-gnu/libvdpau.so.1 (0x7fc9373ec000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x7fc9371ce000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x7fc936e09000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x7fc936c05000) libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x7fc936a01000) libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x7fc9367fb000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x7fc9365f3000) /lib64/ld-linux-x86-64.so.2 (0x7fc939656000) libpulse-simple.so.0 => /usr/lib/x86_64-linux-gnu/libpulse-simple.so.0 (0x7fc9363ef000) libpulse.so.0 => /usr/lib/x86_64-linux-gnu/libpulse.so.0 (0x7fc9361a6000) libcaca.so.0 => /usr/lib/x86_64-linux-gnu/libcaca.so.0 (0x7fc935ed9000) libpulsecommon-4.0.so => /usr/lib/x86_64-linux-gnu/pulseaudio/ libpulsecommon-4.0.so (0x7fc935c72000) libjson-c.so.2 => /lib/x86_64-linux-gnu/libjson-c.so.2 (0x7fc935a67000) libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x7fc935822000) libslang.so.2 => /lib/x86_64-linux-gnu/libslang.so.2 (0x7fc935492000) libncursesw.so.5 => /lib/x86_64-linux-gnu/libncursesw.so.5 (0x7fc93525e000) libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x7fc935035000) libwrap.so.0 => /lib/x86_64-linux-gnu/libwrap.so.0 (0x7fc934e2b000) libsndfile.so.1 => /usr/lib/x86_64-linux-gnu/libsndfile.so.1 (0x7fc934bc3000) libasyncns.so.0 => /usr/lib/x86_64-linux-gnu/libasyncns.so.0 (0x7fc9349bd000) libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1 (0x7fc9347a3000) libFLAC.so.8 => /usr/lib/x86_64-linux-gnu/libFLAC.so.8 (0x7fc934572000) libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x7fc9340a3000) libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x7fc933e76000) libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x7fc933c6d000) libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x7fc933a52000) log Description: Binary data ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] Need help with threading issue (possible deadlock?)
Hi, On Mon, Jul 13, 2015 at 4:26 AM, Donny Yang wrote: > Hello > > I'm trying to fix ffmpeg's APNG decoding for images with the PREVIOUS > dispose op while trying to keep it multithreaded, but it seems to deadlock > whenever I use more that one thread. How do I reproduce? ffmpeg -threads 2 -i test.apng -f null - works for me. So does ffplay -threads 2 test.apng Ronald ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] Need help with threading issue (possible deadlock?)
Hello I'm trying to fix ffmpeg's APNG decoding for images with the PREVIOUS dispose op while trying to keep it multithreaded, but it seems to deadlock whenever I use more that one thread. Is there something obvious I'm missing, or otherwise misunderstanding how ffmpeg's threads work? Or should I just disable threading? PS. I already asked my GSoC mentor about this and he said to disable threading, but I submitted a patch a while ago to disable threading and another dev was against that. From f801fd3934f83d0bc0edf389a50967207c6be168 Mon Sep 17 00:00:00 2001 From: Donny Yang Date: Mon, 13 Jul 2015 18:19:52 +1000 Subject: [PATCH] [WIP] apng: Fix decoding images with the PREVIOUS dispose op --- libavcodec/pngdec.c | 47 +++ 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 60c4975..525e340 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -643,6 +643,11 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, if ((ret = ff_thread_get_buffer(avctx, &s->picture, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; +if (avctx->codec_id == AV_CODEC_ID_APNG && s->dispose_op != APNG_DISPOSE_OP_PREVIOUS) { +ff_thread_release_buffer(avctx, &s->previous_picture); +if ((ret = ff_thread_get_buffer(avctx, &s->previous_picture, AV_GET_BUFFER_FLAG_REF)) < 0) +return ret; +} ff_thread_finish_setup(avctx); p->pict_type= AV_PICTURE_TYPE_I; @@ -917,20 +922,20 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, return AVERROR_PATCHWELCOME; } -// Copy the previous frame to the buffer -ff_thread_await_progress(&s->last_picture, INT_MAX, 0); -memcpy(buffer, s->last_picture.f->data[0], s->image_linesize * s->height); - // Do the disposal operation specified by the last frame on the frame -if (s->last_dispose_op == APNG_DISPOSE_OP_BACKGROUND) { -for (y = s->last_y_offset; y < s->last_y_offset + s->last_h; ++y) -memset(buffer + s->image_linesize * y + s->bpp * s->last_x_offset, 0, s->bpp * s->last_w); -} else if (s->last_dispose_op == APNG_DISPOSE_OP_PREVIOUS) { +if (s->last_dispose_op != APNG_DISPOSE_OP_PREVIOUS) { +ff_thread_await_progress(&s->last_picture, INT_MAX, 0); +memcpy(buffer, s->last_picture.f->data[0], s->image_linesize * s->height); + +if (s->last_dispose_op == APNG_DISPOSE_OP_BACKGROUND) +for (y = s->last_y_offset; y < s->last_y_offset + s->last_h; ++y) +memset(buffer + s->image_linesize * y + s->bpp * s->last_x_offset, 0, s->bpp * s->last_w); + +memcpy(s->previous_picture.f->data[0], buffer, s->image_linesize * s->height); +ff_thread_report_progress(&s->previous_picture, INT_MAX, 0); +} else { ff_thread_await_progress(&s->previous_picture, INT_MAX, 0); -for (y = s->last_y_offset; y < s->last_y_offset + s->last_h; ++y) { -size_t row_start = s->image_linesize * y + s->bpp * s->last_x_offset; -memcpy(buffer + row_start, s->previous_picture.f->data[0] + row_start, s->bpp * s->last_w); -} +memcpy(buffer, s->previous_picture.f->data[0], s->image_linesize * s->height); } // Perform blending @@ -1206,13 +1211,9 @@ static int decode_frame_apng(AVCodecContext *avctx, PNGDecContext *const s = avctx->priv_data; int ret; AVFrame *p; -ThreadFrame tmp; -ff_thread_release_buffer(avctx, &s->previous_picture); -tmp = s->previous_picture; -s->previous_picture = s->last_picture; -s->last_picture = s->picture; -s->picture = tmp; +ff_thread_release_buffer(avctx, &s->last_picture); +FFSWAP(ThreadFrame, s->picture, s->last_picture); p = s->picture.f; if (!(s->state & PNG_IHDR)) { @@ -1291,8 +1292,14 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) pdst->state |= psrc->state & (PNG_IHDR | PNG_PLTE); ff_thread_release_buffer(dst, &pdst->last_picture); -if (psrc->last_picture.f->data[0]) -return ff_thread_ref_frame(&pdst->last_picture, &psrc->last_picture); +if (psrc->last_picture.f->data[0] && +(ret = ff_thread_ref_frame(&pdst->last_picture, &psrc->last_picture)) < 0) +return ret; + +ff_thread_release_buffer(dst, &pdst->previous_picture); +if (psrc->previous_picture.f->data[0] && +(ret = ff_thread_ref_frame(&pdst->previous_picture, &psrc->previous_picture)) < 0) +return ret; } return 0; -- 2.4.5 test.apng Description: Binary data ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel