[FFmpeg-trac] #10965(avcodec:new): avcodec: h.264 decoder flags result as ER error_occurred with frame threading

FFmpeg trac at avcodec.org
Tue Apr 16 12:09:00 EEST 2024


#10965: avcodec: h.264 decoder flags result as ER error_occurred with frame
threading
-------------------------------------+-------------------------------------
             Reporter:  jeeb         |                     Type:  defect
               Status:  new          |                 Priority:  normal
            Component:  avcodec      |                  Version:  git-
             Keywords:  avcodec      |  master
  h264                               |               Blocked By:
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
 Summary of the bug:

 With sample
 https://megumin.fushizen.eu/samples/2024-04-15-framethread_causes_er_errors.264
 , in case of frame threading being enabled, the H.264 decoder flags
 multiple output frames with decode_error_flags:
 FF_DECODE_ERROR_DECODE_SLICES (8) before the sudden end at the end of the
 sample (where there are actual MB decoding errors), while disabling
 threading leads to this flagging not happening

 The data seems to match between these two cases and there is no visual
 corruption, so either both are fine or both are in some manner broken. I
 have not compared against the JM reference decoder yet.

 How to reproduce:

 {{{
 % ffmpeg -threads:v 2 -i
 "https://megumin.fushizen.eu/samples/2024-04-15-framethread_causes_er_errors.264"
 -f null pipe:
 ffmpeg version N-114837-g257bc2a82a Copyright (c) 2000-2024 the FFmpeg
 developers
   built with gcc 14 (GCC)
   configuration: --prefix=/home/jeeb/ownapps/encoding_prefix/ --enable-
 static --disable-doc --disable-stripping --enable-gpl --enable-version3
 --enable-vaapi --enable-zlib --enable-libdav1d --enable-libx264 --enable-
 libsvtav1 --enable-libx265 --enable-libzimg --enable-gnutls --enable-
 libplacebo
   libavutil      59. 15.100 / 59. 15.100
   libavcodec     61.  5.103 / 61.  5.103
   libavformat    61.  3.100 / 61.  3.100
   libavdevice    61.  2.100 / 61.  2.100
   libavfilter    10.  2.101 / 10.  2.101
   libswscale      8.  2.100 /  8.  2.100
   libswresample   5.  2.100 /  5.  2.100
   libpostproc    58.  2.100 / 58.  2.100
 [h264 @ 0x5475300] Stream #0: not enough frames to estimate rate; consider
 increasing probesize
 Input #0, h264, from
 'https://megumin.fushizen.eu/samples/2024-04-15-framethread_causes_er_errors.264':
   Duration: N/A, bitrate: N/A
   Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, top first),
 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 50 tbr, 1200k tbn
 Stream mapping:
   Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native))
 Press [q] to stop, [?] for help
 Output #0, null, to 'pipe:':
   Metadata:
     encoder         : Lavf61.3.100
   Stream #0:0: Video: wrapped_avframe, yuv420p(tv, bt709, top coded first
 (swapped)), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 25 fps, 25 tbn
       Metadata:
         encoder         : Lavc61.5.103 wrapped_avframe
 [vist#0:0/h264 @ 0x6144c80] [dec:h264 @ 0x551c4c0] corrupt decoded frame
     Last message repeated 7 times
 [h264 @ 0x60bee40] error while decoding MB 64 10, bytestream -16
 speed=1.92x
 [h264 @ 0x60bee40] concealing 6945 DC, 6945 AC, 6945 MV errors in P frame
 [vist#0:0/h264 @ 0x6144c80] [dec:h264 @ 0x551c4c0] corrupt decoded frame
 [out#0/null @ 0x5517800] video:18KiB audio:0KiB subtitle:0KiB other
 streams:0KiB global headers:0KiB muxing overhead: unknown
 frame=   42 fps=0.0 q=-0.0 Lsize=N/A time=00:00:01.68 bitrate=N/A
 speed=2.51x
 }}}

 Comparison with threading disabled:
 {{{
 ffmpeg -threads:v 1 -i
 "https://megumin.fushizen.eu/samples/2024-04-15-framethread_causes_er_errors.264"
 -f null pipe:
 ffmpeg version N-114837-g257bc2a82a Copyright (c) 2000-2024 the FFmpeg
 developers
   built with gcc 14 (GCC)
   configuration: --prefix=/home/jeeb/ownapps/encoding_prefix/ --enable-
 static --disable-doc --disable-stripping --enable-gpl --enable-version3
 --enable-vaapi --enable-zlib --enable-libdav1d --enable-libx264 --enable-
 libsvtav1 --enable-libx265 --enable-libzimg --enable-gnutls --enable-
 libplacebo
   libavutil      59. 15.100 / 59. 15.100
   libavcodec     61.  5.103 / 61.  5.103
   libavformat    61.  3.100 / 61.  3.100
   libavdevice    61.  2.100 / 61.  2.100
   libavfilter    10.  2.101 / 10.  2.101
   libswscale      8.  2.100 /  8.  2.100
   libswresample   5.  2.100 /  5.  2.100
   libpostproc    58.  2.100 / 58.  2.100
 [h264 @ 0x605b300] Stream #0: not enough frames to estimate rate; consider
 increasing probesize
 Input #0, h264, from
 'https://megumin.fushizen.eu/samples/2024-04-15-framethread_causes_er_errors.264':
   Duration: N/A, bitrate: N/A
   Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, top first),
 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 50 tbr, 1200k tbn
 Stream mapping:
   Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native))
 Press [q] to stop, [?] for help
 Output #0, null, to 'pipe:':
   Metadata:
     encoder         : Lavf61.3.100
   Stream #0:0: Video: wrapped_avframe, yuv420p(tv, bt709, top coded first
 (swapped)), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 25 fps, 25 tbn
       Metadata:
         encoder         : Lavc61.5.103 wrapped_avframe
 [h264 @ 0x6de1580] error while decoding MB 64 10, bytestream -16
 speed=1.16x
 [h264 @ 0x6de1580] concealing 6945 DC, 6945 AC, 6945 MV errors in P frame
 [vist#0:0/h264 @ 0x6d2ac80] [dec:h264 @ 0x61024c0] corrupt decoded frame
 [out#0/null @ 0x60fd800] video:18KiB audio:0KiB subtitle:0KiB other
 streams:0KiB global headers:0KiB muxing overhead: unknown
 frame=   42 fps= 34 q=-0.0 Lsize=N/A time=00:00:01.68 bitrate=N/A
 speed=1.37x
 }}}

 Some changes I have applied to check values:
 {{{
 diff --git a/fftools/ffmpeg_dec.c b/fftools/ffmpeg_dec.c
 index 70de151301..5be43910ad 100644
 --- a/fftools/ffmpeg_dec.c
 +++ b/fftools/ffmpeg_dec.c
 @@ -731,7 +731,8 @@ static int packet_decode(DecoderPriv *dp, AVPacket
 *pkt, AVFrame *frame)

          if (frame->decode_error_flags || (frame->flags &
 AV_FRAME_FLAG_CORRUPT)) {
              av_log(dp, exit_on_error ? AV_LOG_FATAL : AV_LOG_WARNING,
 -                   "corrupt decoded frame\n");
 +                   "corrupt decoded frame. decode_error_flags: %d,
 AV_FRAME_FLAG_CORRUPT: %d\n",
 +                   frame->decode_error_flags, (frame->flags &
 AV_FRAME_FLAG_CORRUPT));
              if (exit_on_error)
                  return AVERROR_INVALIDDATA;
          }
 diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
 index 727dc1a662..f31c936595 100644
 --- a/libavcodec/h264dec.c
 +++ b/libavcodec/h264dec.c
 @@ -756,6 +756,9 @@ static int decode_nal_units(H264Context *h, const
 uint8_t *buf, int buf_size)
          if (h->cur_pic_ptr->decode_error_flags) {
              /* Frame-threading in use */
              atomic_int *decode_error =
 h->cur_pic_ptr->decode_error_flags;
 +            av_log(h->avctx, AV_LOG_WARNING,
 +                   "threaded error case: ret: %d, ER error_occurred: %d,
 decode_error_flags : %d\n",
 +                   ret, h->er.error_occurred,
 *h->cur_pic_ptr->decode_error_flags);
              /* Using atomics here is not supposed to provide
 syncronisation;
               * they are merely used to allow to set decode_error from
 both
               * decoding threads in case of coded slices. */
 }}}

 Example of checking that the output is the same between the two cases:
 {{{
 ffmpeg -threads:v 1 -i
 "https://megumin.fushizen.eu/samples/2024-04-15-framethread_causes_er_errors.264"
 -f framehash pipe: > 01-hashes_threadless.txt
 ffmpeg -threads:v 2 -i
 "https://megumin.fushizen.eu/samples/2024-04-15-framethread_causes_er_errors.264"
 -f framehash pipe: > 02-hashes_threaded.txt
 git diff --no-index 01-hashes_threadless.txt 02-hashes_threaded.txt
 }}}
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/10965>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list