diff mbox

[FFmpeg-devel] avcodec/decode: copy the output parameters from the last bsf in the chain back to the AVCodecContext

Message ID 20180720015423.1760-1-jamrial@gmail.com
State Accepted
Commit 662558f985f50834eebe82d6b6854c66f33ab320
Headers show

Commit Message

James Almer July 20, 2018, 1:54 a.m. UTC
Certain AVCodecParameters, like the contents of the extradata, may be changed
by the init() function of any of the bitstream filters in the chain.

Signed-off-by: James Almer <jamrial@gmail.com>
---
Things worked fine without this until now by pure chance. vp9_superframe_split
doesn't use extradata, and those hardware decoders inserting h264_mp4toannexb
and hevc_mp4toannexb passed the extradata to functions that could handle it
unfiltered.

 libavcodec/decode.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

Michael Niedermayer July 20, 2018, 11:23 p.m. UTC | #1
On Thu, Jul 19, 2018 at 10:54:23PM -0300, James Almer wrote:
> Certain AVCodecParameters, like the contents of the extradata, may be changed
> by the init() function of any of the bitstream filters in the chain.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> Things worked fine without this until now by pure chance. vp9_superframe_split
> doesn't use extradata, and those hardware decoders inserting h264_mp4toannexb
> and hevc_mp4toannexb passed the extradata to functions that could handle it
> unfiltered.
> 
>  libavcodec/decode.c | 4 ++++
>  1 file changed, 4 insertions(+)

this breaks:
./ffmpeg -i https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png -bitexact -pix_fmt rgba -f framecrc -
...
[apng @ 0x2d431c0] chunk too big
[apng @ 0x2d44380] chunk too big
[apng @ 0x2d45b40] chunk too big
[apng @ 0x2d472c0] chunk too big
[apng @ 0x2d48a40] chunk too big
[apng @ 0x2d4a1c0] chunk too big
[apng @ 0x2d4b940] chunk too big
[apng @ 0x2d4d0c0] chunk too big
[apng @ 0x2d4e840] chunk too big
[apng @ 0x2d4ffc0] chunk too big
[apng @ 0x2d5fc00] chunk too big
[apng @ 0x2d612c0] chunk too big
Error while decoding stream #0:0: Invalid data found when processing input
[apng @ 0x2d62900] chunk too big
Error while decoding stream #0:0: Invalid data found when processing input
[apng @ 0x2d431c0] chunk too big
Error while decoding stream #0:0: Invalid data found when processing input
[apng @ 0x2d44380] chunk too big
Error while decoding stream #0:0: Invalid data found when processing input
[apng @ 0x2d45b40] chunk too big
Error while decoding stream #0:0: Invalid data found when processing input
[apng @ 0x2d472c0] chunk too big
Error while decoding stream #0:0: Invalid data found when processing input
[apng @ 0x2d48a40] chunk too big
Error while decoding stream #0:0: Invalid data found when processing input
[apng @ 0x2d4a1c0] chunk too big
Error while decoding stream #0:0: Invalid data found when processing input
[apng @ 0x2d4b940] chunk too big
Error while decoding stream #0:0: Invalid data found when processing input


> 
> diff --git a/libavcodec/decode.c b/libavcodec/decode.c
> index 6a3a4df179..0c8cdd5bd2 100644
> --- a/libavcodec/decode.c
> +++ b/libavcodec/decode.c
> @@ -246,6 +246,10 @@ static int bsfs_init(AVCodecContext *avctx)
>              goto fail;
>      }
>  
> +    ret = avcodec_parameters_to_context(avctx, s->bsfs[s->nb_bsfs - 1]->par_out);
> +    if (ret < 0)
> +        return ret;
> +
>      return 0;
>  fail:
>      ff_decode_bsfs_uninit(avctx);
> -- 
> 2.18.0
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
James Almer July 20, 2018, 11:30 p.m. UTC | #2
On 7/20/2018 8:23 PM, Michael Niedermayer wrote:
> On Thu, Jul 19, 2018 at 10:54:23PM -0300, James Almer wrote:
>> Certain AVCodecParameters, like the contents of the extradata, may be changed
>> by the init() function of any of the bitstream filters in the chain.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> Things worked fine without this until now by pure chance. vp9_superframe_split
>> doesn't use extradata, and those hardware decoders inserting h264_mp4toannexb
>> and hevc_mp4toannexb passed the extradata to functions that could handle it
>> unfiltered.
>>
>>  libavcodec/decode.c | 4 ++++
>>  1 file changed, 4 insertions(+)
> 
> this breaks:
> ./ffmpeg -i https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png -bitexact -pix_fmt rgba -f framecrc -
> ...
> [apng @ 0x2d431c0] chunk too big
> [apng @ 0x2d44380] chunk too big
> [apng @ 0x2d45b40] chunk too big
> [apng @ 0x2d472c0] chunk too big
> [apng @ 0x2d48a40] chunk too big
> [apng @ 0x2d4a1c0] chunk too big
> [apng @ 0x2d4b940] chunk too big
> [apng @ 0x2d4d0c0] chunk too big
> [apng @ 0x2d4e840] chunk too big
> [apng @ 0x2d4ffc0] chunk too big
> [apng @ 0x2d5fc00] chunk too big
> [apng @ 0x2d612c0] chunk too big
> Error while decoding stream #0:0: Invalid data found when processing input
> [apng @ 0x2d62900] chunk too big
> Error while decoding stream #0:0: Invalid data found when processing input
> [apng @ 0x2d431c0] chunk too big
> Error while decoding stream #0:0: Invalid data found when processing input
> [apng @ 0x2d44380] chunk too big
> Error while decoding stream #0:0: Invalid data found when processing input
> [apng @ 0x2d45b40] chunk too big
> Error while decoding stream #0:0: Invalid data found when processing input
> [apng @ 0x2d472c0] chunk too big
> Error while decoding stream #0:0: Invalid data found when processing input
> [apng @ 0x2d48a40] chunk too big
> Error while decoding stream #0:0: Invalid data found when processing input
> [apng @ 0x2d4a1c0] chunk too big
> Error while decoding stream #0:0: Invalid data found when processing input
> [apng @ 0x2d4b940] chunk too big
> Error while decoding stream #0:0: Invalid data found when processing input

I can't reproduce this. Are you sure it was this patch and not some
other change in your tree?
Michael Niedermayer July 21, 2018, 5:34 p.m. UTC | #3
On Fri, Jul 20, 2018 at 08:30:19PM -0300, James Almer wrote:
> On 7/20/2018 8:23 PM, Michael Niedermayer wrote:
> > On Thu, Jul 19, 2018 at 10:54:23PM -0300, James Almer wrote:
> >> Certain AVCodecParameters, like the contents of the extradata, may be changed
> >> by the init() function of any of the bitstream filters in the chain.
> >>
> >> Signed-off-by: James Almer <jamrial@gmail.com>
> >> ---
> >> Things worked fine without this until now by pure chance. vp9_superframe_split
> >> doesn't use extradata, and those hardware decoders inserting h264_mp4toannexb
> >> and hevc_mp4toannexb passed the extradata to functions that could handle it
> >> unfiltered.
> >>
> >>  libavcodec/decode.c | 4 ++++
> >>  1 file changed, 4 insertions(+)
> > 
> > this breaks:
> > ./ffmpeg -i https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png -bitexact -pix_fmt rgba -f framecrc -
> > ...
> > [apng @ 0x2d431c0] chunk too big
> > [apng @ 0x2d44380] chunk too big
> > [apng @ 0x2d45b40] chunk too big
> > [apng @ 0x2d472c0] chunk too big
> > [apng @ 0x2d48a40] chunk too big
> > [apng @ 0x2d4a1c0] chunk too big
> > [apng @ 0x2d4b940] chunk too big
> > [apng @ 0x2d4d0c0] chunk too big
> > [apng @ 0x2d4e840] chunk too big
> > [apng @ 0x2d4ffc0] chunk too big
> > [apng @ 0x2d5fc00] chunk too big
> > [apng @ 0x2d612c0] chunk too big
> > Error while decoding stream #0:0: Invalid data found when processing input
> > [apng @ 0x2d62900] chunk too big
> > Error while decoding stream #0:0: Invalid data found when processing input
> > [apng @ 0x2d431c0] chunk too big
> > Error while decoding stream #0:0: Invalid data found when processing input
> > [apng @ 0x2d44380] chunk too big
> > Error while decoding stream #0:0: Invalid data found when processing input
> > [apng @ 0x2d45b40] chunk too big
> > Error while decoding stream #0:0: Invalid data found when processing input
> > [apng @ 0x2d472c0] chunk too big
> > Error while decoding stream #0:0: Invalid data found when processing input
> > [apng @ 0x2d48a40] chunk too big
> > Error while decoding stream #0:0: Invalid data found when processing input
> > [apng @ 0x2d4a1c0] chunk too big
> > Error while decoding stream #0:0: Invalid data found when processing input
> > [apng @ 0x2d4b940] chunk too big
> > Error while decoding stream #0:0: Invalid data found when processing input
> 
> I can't reproduce this. Are you sure it was this patch and not some
> other change in your tree?

this patch seems to trigger the crash and or some anomalies
valgrind output below.
The exact error differs between valgrind and no valgrind


==3661== Syscall param sendmsg(mmsg[0].msg_hdr) points to uninitialised byte(s)
==3661==    at 0xC7647D9: sendmmsg (sendmmsg.c:32)
==3661==    by 0x113FFAB0: __libc_res_nsend (res_send.c:1279)
==3661==    by 0x113FCE2B: __libc_res_nquery (res_query.c:227)
==3661==    by 0x113FD862: __libc_res_nsearch (res_query.c:591)
==3661==    by 0x11C1CC72: _nss_dns_gethostbyname4_r (dns-host.c:315)
==3661==    by 0xC735665: gaih_inet (getaddrinfo.c:858)
==3661==    by 0xC73896C: getaddrinfo (getaddrinfo.c:2414)
==3661==    by 0x7D29C5: tcp_open (tcp.c:116)
==3661==    by 0x67A36C: ffurl_connect (avio.c:209)
==3661==    by 0x67AA81: ffurl_open_whitelist (avio.c:345)
==3661==    by 0x83F149: ff_tls_open_underlying (tls.c:107)
==3661==    by 0x7D7D78: tls_open (tls_openssl.c:239)
==3661==    by 0x67A346: ffurl_connect (avio.c:209)
==3661==    by 0x67AA81: ffurl_open_whitelist (avio.c:345)
==3661==    by 0x6C957B: http_open_cnx_internal (http.c:235)
==3661==    by 0x6C9680: http_open_cnx (http.c:262)
==3661==    by 0x6CA560: http_open (http.c:557)
==3661==    by 0x67A346: ffurl_connect (avio.c:209)
==3661==    by 0x67AA81: ffurl_open_whitelist (avio.c:345)
==3661==    by 0x67E88D: ffio_open_whitelist (aviobuf.c:1167)
==3661==  Address 0x7feff9260 is on thread 1's stack
==3661==  Uninitialised value was created by a stack allocation
==3661==    at 0x113FEE6D: __libc_res_nsend (res_send.c:364)
==3661== 
Input #0, apng, from 'https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png':
  Duration: N/A, bitrate: N/A
    Stream #0:0: Video: apng, rgba(pc), 100x100, 13.33 fps, 13.33 tbr, 100k tbn, 100k tbc
Stream mapping:
  Stream #0:0 -> #0:0 (apng (native) -> rawvideo (native))
Press [q] to stop, [?] for help
==3661== Thread 2:
==3661== Invalid read of size 4
==3661==    at 0xB1081F: bytestream_get_be32 (bytestream.h:92)
==3661==    by 0xB10841: bytestream2_get_be32u (bytestream.h:92)
==3661==    by 0xB1088F: bytestream2_get_be32 (bytestream.h:92)
==3661==    by 0xB14FA0: decode_frame_common (pngdec.c:1196)
==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
==3661==    by 0xC76303C: clone (clone.S:111)
==3661==  Address 0x1171d6c0 is 0 bytes inside a block of size 109 free'd
==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==3661==    by 0x1218592: av_free (mem.c:223)
==3661==    by 0x12185CA: av_freep (mem.c:233)
==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
==3661==    by 0x43383E: decode (ffmpeg.c:2238)
==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
==3661== 
==3661== Invalid read of size 4
==3661==    at 0xB106EC: bytestream_get_le32 (bytestream.h:88)
==3661==    by 0xB10707: bytestream2_get_le32u (bytestream.h:88)
==3661==    by 0xB10755: bytestream2_get_le32 (bytestream.h:88)
==3661==    by 0xB1500B: decode_frame_common (pngdec.c:1202)
==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
==3661==    by 0xC76303C: clone (clone.S:111)
==3661==  Address 0x1171d6c4 is 4 bytes inside a block of size 109 free'd
==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==3661==    by 0x1218592: av_free (mem.c:223)
==3661==    by 0x12185CA: av_freep (mem.c:233)
==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
==3661==    by 0x43383E: decode (ffmpeg.c:2238)
==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
==3661== 
==3661== Invalid read of size 4
==3661==    at 0xB1081F: bytestream_get_be32 (bytestream.h:92)
==3661==    by 0xB10841: bytestream2_get_be32u (bytestream.h:92)
==3661==    by 0xB1088F: bytestream2_get_be32 (bytestream.h:92)
==3661==    by 0xB128AD: decode_ihdr_chunk (pngdec.c:566)
==3661==    by 0xB151EB: decode_frame_common (pngdec.c:1224)
==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
==3661==    by 0xC76303C: clone (clone.S:111)
==3661==  Address 0x1171d6c8 is 8 bytes inside a block of size 109 free'd
==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==3661==    by 0x1218592: av_free (mem.c:223)
==3661==    by 0x12185CA: av_freep (mem.c:233)
==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
==3661==    by 0x43383E: decode (ffmpeg.c:2238)
==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
==3661== 
==3661== Invalid read of size 4
==3661==    at 0xB1081F: bytestream_get_be32 (bytestream.h:92)
==3661==    by 0xB10841: bytestream2_get_be32u (bytestream.h:92)
==3661==    by 0xB1088F: bytestream2_get_be32 (bytestream.h:92)
==3661==    by 0xB128DD: decode_ihdr_chunk (pngdec.c:567)
==3661==    by 0xB151EB: decode_frame_common (pngdec.c:1224)
==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
==3661==    by 0xC76303C: clone (clone.S:111)
==3661==  Address 0x1171d6cc is 12 bytes inside a block of size 109 free'd
==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==3661==    by 0x1218592: av_free (mem.c:223)
==3661==    by 0x12185CA: av_freep (mem.c:233)
==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
==3661==    by 0x43383E: decode (ffmpeg.c:2238)
==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
==3661== 
==3661== Invalid read of size 1
==3661==    at 0xB1095A: bytestream_get_byte (bytestream.h:95)
==3661==    by 0xB10979: bytestream2_get_byteu (bytestream.h:95)
==3661==    by 0xB109C6: bytestream2_get_byte (bytestream.h:95)
==3661==    by 0xB129A9: decode_ihdr_chunk (pngdec.c:573)
==3661==    by 0xB151EB: decode_frame_common (pngdec.c:1224)
==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
==3661==    by 0xC76303C: clone (clone.S:111)
==3661==  Address 0x1171d6d0 is 16 bytes inside a block of size 109 free'd
==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==3661==    by 0x1218592: av_free (mem.c:223)
==3661==    by 0x12185CA: av_freep (mem.c:233)
==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
==3661==    by 0x43383E: decode (ffmpeg.c:2238)
==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
==3661== 
==3661== Invalid read of size 1
==3661==    at 0xB1095A: bytestream_get_byte (bytestream.h:95)
==3661==    by 0xB10979: bytestream2_get_byteu (bytestream.h:95)
==3661==    by 0xB109C6: bytestream2_get_byte (bytestream.h:95)
==3661==    by 0xB12A9E: decode_ihdr_chunk (pngdec.c:579)
==3661==    by 0xB151EB: decode_frame_common (pngdec.c:1224)
==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
==3661==    by 0xC76303C: clone (clone.S:111)
==3661==  Address 0x1171d6d1 is 17 bytes inside a block of size 109 free'd
==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==3661==    by 0x1218592: av_free (mem.c:223)
==3661==    by 0x12185CA: av_freep (mem.c:233)
==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
==3661==    by 0x43383E: decode (ffmpeg.c:2238)
==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
==3661== 
==3661== Invalid read of size 1
==3661==    at 0xB1095A: bytestream_get_byte (bytestream.h:95)
==3661==    by 0xB10979: bytestream2_get_byteu (bytestream.h:95)
==3661==    by 0xB109C6: bytestream2_get_byte (bytestream.h:95)
==3661==    by 0xB12ABA: decode_ihdr_chunk (pngdec.c:580)
==3661==    by 0xB151EB: decode_frame_common (pngdec.c:1224)
==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
==3661==    by 0xC76303C: clone (clone.S:111)
==3661==  Address 0x1171d6d2 is 18 bytes inside a block of size 109 free'd
==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==3661==    by 0x1218592: av_free (mem.c:223)
==3661==    by 0x12185CA: av_freep (mem.c:233)
==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
==3661==    by 0x43383E: decode (ffmpeg.c:2238)
==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
==3661== 
==3661== Invalid read of size 1
==3661==    at 0xB1095A: bytestream_get_byte (bytestream.h:95)
==3661==    by 0xB10979: bytestream2_get_byteu (bytestream.h:95)
==3661==    by 0xB109C6: bytestream2_get_byte (bytestream.h:95)
==3661==    by 0xB12AD6: decode_ihdr_chunk (pngdec.c:581)
==3661==    by 0xB151EB: decode_frame_common (pngdec.c:1224)
==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
==3661==    by 0xC76303C: clone (clone.S:111)
==3661==  Address 0x1171d6d3 is 19 bytes inside a block of size 109 free'd
==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==3661==    by 0x1218592: av_free (mem.c:223)
==3661==    by 0x12185CA: av_freep (mem.c:233)
==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
==3661==    by 0x43383E: decode (ffmpeg.c:2238)
==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
==3661== 
==3661== Invalid read of size 1
==3661==    at 0xB1095A: bytestream_get_byte (bytestream.h:95)
==3661==    by 0xB10979: bytestream2_get_byteu (bytestream.h:95)
==3661==    by 0xB109C6: bytestream2_get_byte (bytestream.h:95)
==3661==    by 0xB12AF2: decode_ihdr_chunk (pngdec.c:582)
==3661==    by 0xB151EB: decode_frame_common (pngdec.c:1224)
==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
==3661==    by 0xC76303C: clone (clone.S:111)
==3661==  Address 0x1171d6d4 is 20 bytes inside a block of size 109 free'd
==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==3661==    by 0x1218592: av_free (mem.c:223)
==3661==    by 0x12185CA: av_freep (mem.c:233)
==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
==3661==    by 0x43383E: decode (ffmpeg.c:2238)
==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
==3661== 
#tb 0: 3/40
#media_type 0: video
#codec_id 0: rawvideo
#dimensions 0: 100x100
#sar 0: 0/1
Output #0, framecrc, to 'pipe:':
    Stream #0:0: Video: rawvideo (RGBA / 0x41424752), rgba, 100x100, q=2-31, 4266 kb/s, 13.33 fps, 13.33 tbn, 13.33 tbc
    Metadata:
      encoder         : Lavc rawvideo
0,          0,          0,        1,    40000, 0x15284fcd
0,          1,          1,        1,    40000, 0xc77f0451
0,          2,          2,        1,    40000, 0x895c402915 bitrate=  11.0kbits/s speed=0.201x    
0,          3,          3,        1,    40000, 0x9474bd69
0,          4,          4,        1,    40000, 0xdd67407e
0,          5,          5,        1,    40000, 0x2ff049ee
0,          6,          6,        1,    40000, 0xd944c1bb
0,          7,          7,        1,    40000, 0x56850692
0,          8,          8,        1,    40000, 0x8816ce06
0,          9,          9,        1,    40000, 0x0d7170a8
0,         10,         10,        1,    40000, 0x85290373
0,         11,         11,        1,    40000, 0xd2899862
0,         12,         12,        1,    40000, 0x8730ed6d
0,         13,         13,        1,    40000, 0x914257ad
0,         14,         14,        1,    40000, 0x513b88a4
0,         15,         15,        1,    40000, 0x695a8ff0
0,         16,         16,        1,    40000, 0xec63be20
0,         17,         17,        1,    40000, 0x024a7b99
0,         18,         18,        1,    40000, 0x28b05fc4
0,         19,         19,        1,    40000, 0xcf1fceb2
==3661==    at 0x1214D54: VALGRIND_PRINTF_BACKTRACE (valgrind.h:4550)
==3661==    by 0x12157D4: av_log_default_callback (log.c:351)
==3661==    by 0x1215973: av_vlog (log.c:377)
==3661==    by 0x1215933: av_log (log.c:369)
==3661==    by 0x42BC09: term_exit (ffmpeg.c:330)
==3661==    by 0x43CD7E: transcode (ffmpeg.c:4701)
==3661==    by 0x43D4C8: main (ffmpeg.c:4886)
frame=   20 fps=0.0 q=-0.0 Lsize=       1kB time=00:00:01.50 bitrate=   6.7kbits/s speed=1.69x    
video:781kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
==3661==    at 0x1214D54: VALGRIND_PRINTF_BACKTRACE (valgrind.h:4550)
==3661==    by 0x12157D4: av_log_default_callback (log.c:351)
==3661==    by 0x1215973: av_vlog (log.c:377)
==3661==    by 0x1215933: av_log (log.c:369)
==3661==    by 0x42BC09: term_exit (ffmpeg.c:330)
==3661==    by 0x42C8D7: ffmpeg_cleanup (ffmpeg.c:632)
==3661==    by 0x424601: exit_program (cmdutils.c:139)
==3661==    by 0x43D682: main (in /ffmpeg_g)
==3661== 
==3661== HEAP SUMMARY:
==3661==     in use at exit: 157,104 bytes in 2,751 blocks
==3661==   total heap usage: 6,653 allocs, 3,902 frees, 4,958,040 bytes allocated
==3661== 
==3661== LEAK SUMMARY:
==3661==    definitely lost: 0 bytes in 0 blocks
==3661==    indirectly lost: 0 bytes in 0 blocks
==3661==      possibly lost: 0 bytes in 0 blocks
==3661==    still reachable: 157,104 bytes in 2,751 blocks
==3661==         suppressed: 0 bytes in 0 blocks
==3661== Reachable blocks (those to which a pointer was found) are not shown.
==3661== To see them, rerun with: --leak-check=full --show-reachable=yes
==3661== 
==3661== For counts of detected and suppressed errors, rerun with: -v
==3661== ERROR SUMMARY: 17 errors from 12 contexts (suppressed: 0 from 0)

[...]
James Almer July 21, 2018, 6:01 p.m. UTC | #4
On 7/21/2018 2:34 PM, Michael Niedermayer wrote:
> On Fri, Jul 20, 2018 at 08:30:19PM -0300, James Almer wrote:
>> On 7/20/2018 8:23 PM, Michael Niedermayer wrote:
>>> On Thu, Jul 19, 2018 at 10:54:23PM -0300, James Almer wrote:
>>>> Certain AVCodecParameters, like the contents of the extradata, may be changed
>>>> by the init() function of any of the bitstream filters in the chain.
>>>>
>>>> Signed-off-by: James Almer <jamrial@gmail.com>
>>>> ---
>>>> Things worked fine without this until now by pure chance. vp9_superframe_split
>>>> doesn't use extradata, and those hardware decoders inserting h264_mp4toannexb
>>>> and hevc_mp4toannexb passed the extradata to functions that could handle it
>>>> unfiltered.
>>>>
>>>>  libavcodec/decode.c | 4 ++++
>>>>  1 file changed, 4 insertions(+)
>>>
>>> this breaks:
>>> ./ffmpeg -i https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png -bitexact -pix_fmt rgba -f framecrc -
>>> ...
>>> [apng @ 0x2d431c0] chunk too big
>>> [apng @ 0x2d44380] chunk too big
>>> [apng @ 0x2d45b40] chunk too big
>>> [apng @ 0x2d472c0] chunk too big
>>> [apng @ 0x2d48a40] chunk too big
>>> [apng @ 0x2d4a1c0] chunk too big
>>> [apng @ 0x2d4b940] chunk too big
>>> [apng @ 0x2d4d0c0] chunk too big
>>> [apng @ 0x2d4e840] chunk too big
>>> [apng @ 0x2d4ffc0] chunk too big
>>> [apng @ 0x2d5fc00] chunk too big
>>> [apng @ 0x2d612c0] chunk too big
>>> Error while decoding stream #0:0: Invalid data found when processing input
>>> [apng @ 0x2d62900] chunk too big
>>> Error while decoding stream #0:0: Invalid data found when processing input
>>> [apng @ 0x2d431c0] chunk too big
>>> Error while decoding stream #0:0: Invalid data found when processing input
>>> [apng @ 0x2d44380] chunk too big
>>> Error while decoding stream #0:0: Invalid data found when processing input
>>> [apng @ 0x2d45b40] chunk too big
>>> Error while decoding stream #0:0: Invalid data found when processing input
>>> [apng @ 0x2d472c0] chunk too big
>>> Error while decoding stream #0:0: Invalid data found when processing input
>>> [apng @ 0x2d48a40] chunk too big
>>> Error while decoding stream #0:0: Invalid data found when processing input
>>> [apng @ 0x2d4a1c0] chunk too big
>>> Error while decoding stream #0:0: Invalid data found when processing input
>>> [apng @ 0x2d4b940] chunk too big
>>> Error while decoding stream #0:0: Invalid data found when processing input
>>
>> I can't reproduce this. Are you sure it was this patch and not some
>> other change in your tree?
> 
> this patch seems to trigger the crash and or some anomalies
> valgrind output below.
> The exact error differs between valgrind and no valgrind
> 
> 
> ==3661== Syscall param sendmsg(mmsg[0].msg_hdr) points to uninitialised byte(s)
> ==3661==    at 0xC7647D9: sendmmsg (sendmmsg.c:32)
> ==3661==    by 0x113FFAB0: __libc_res_nsend (res_send.c:1279)
> ==3661==    by 0x113FCE2B: __libc_res_nquery (res_query.c:227)
> ==3661==    by 0x113FD862: __libc_res_nsearch (res_query.c:591)
> ==3661==    by 0x11C1CC72: _nss_dns_gethostbyname4_r (dns-host.c:315)
> ==3661==    by 0xC735665: gaih_inet (getaddrinfo.c:858)
> ==3661==    by 0xC73896C: getaddrinfo (getaddrinfo.c:2414)
> ==3661==    by 0x7D29C5: tcp_open (tcp.c:116)
> ==3661==    by 0x67A36C: ffurl_connect (avio.c:209)
> ==3661==    by 0x67AA81: ffurl_open_whitelist (avio.c:345)
> ==3661==    by 0x83F149: ff_tls_open_underlying (tls.c:107)
> ==3661==    by 0x7D7D78: tls_open (tls_openssl.c:239)
> ==3661==    by 0x67A346: ffurl_connect (avio.c:209)
> ==3661==    by 0x67AA81: ffurl_open_whitelist (avio.c:345)
> ==3661==    by 0x6C957B: http_open_cnx_internal (http.c:235)
> ==3661==    by 0x6C9680: http_open_cnx (http.c:262)
> ==3661==    by 0x6CA560: http_open (http.c:557)
> ==3661==    by 0x67A346: ffurl_connect (avio.c:209)
> ==3661==    by 0x67AA81: ffurl_open_whitelist (avio.c:345)
> ==3661==    by 0x67E88D: ffio_open_whitelist (aviobuf.c:1167)
> ==3661==  Address 0x7feff9260 is on thread 1's stack
> ==3661==  Uninitialised value was created by a stack allocation
> ==3661==    at 0x113FEE6D: __libc_res_nsend (res_send.c:364)
> ==3661== 
> Input #0, apng, from 'https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png':
>   Duration: N/A, bitrate: N/A
>     Stream #0:0: Video: apng, rgba(pc), 100x100, 13.33 fps, 13.33 tbr, 100k tbn, 100k tbc
> Stream mapping:
>   Stream #0:0 -> #0:0 (apng (native) -> rawvideo (native))
> Press [q] to stop, [?] for help
> ==3661== Thread 2:
> ==3661== Invalid read of size 4
> ==3661==    at 0xB1081F: bytestream_get_be32 (bytestream.h:92)
> ==3661==    by 0xB10841: bytestream2_get_be32u (bytestream.h:92)
> ==3661==    by 0xB1088F: bytestream2_get_be32 (bytestream.h:92)
> ==3661==    by 0xB14FA0: decode_frame_common (pngdec.c:1196)
> ==3661==    by 0xB1600B: decode_frame_apng (pngdec.c:1490)
> ==3661==    by 0xB25DA8: frame_worker_thread (pthread_frame.c:201)
> ==3661==    by 0xC44F183: start_thread (pthread_create.c:312)
> ==3661==    by 0xC76303C: clone (clone.S:111)
> ==3661==  Address 0x1171d6c0 is 0 bytes inside a block of size 109 free'd
> ==3661==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
> ==3661==    by 0x1218592: av_free (mem.c:223)
> ==3661==    by 0x12185CA: av_freep (mem.c:233)
> ==3661==    by 0xC004FE: avcodec_parameters_to_context (utils.c:2126)
> ==3661==    by 0x8AD34E: bsfs_init (decode.c:284)
> ==3661==    by 0x8AE729: avcodec_send_packet (decode.c:695)
> ==3661==    by 0x43383E: decode (ffmpeg.c:2238)
> ==3661==    by 0x434098: decode_video (ffmpeg.c:2382)
> ==3661==    by 0x4350E0: process_input_packet (ffmpeg.c:2623)
> ==3661==    by 0x43C536: process_input (ffmpeg.c:4505)
> ==3661==    by 0x43CADF: transcode_step (ffmpeg.c:4625)
> ==3661==    by 0x43CC5B: transcode (ffmpeg.c:4679)
> ==3661==    by 0x43D4C8: main (ffmpeg.c:4886)

Data race, it seems. Looking at bsfs_init() again, i see it's called
from avcodec_send_packet(), which is long after the codec is
initialized. So i guess copying the filtered parameters back to the
AVCodecContext is not an option. Or at least not unless the decoder sets
AV_CODEC_CAP_PARAM_CHANGE.

This is a problem, or will be once a decoder needs to autoinsert a bsf
that makes a change that needs to be reflected in the codec context.
It may be a good idea (or even necessary) to see how feasible it is to
call this function from avcodec_open2() instead.

Patch dropped in any case.
diff mbox

Patch

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 6a3a4df179..0c8cdd5bd2 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -246,6 +246,10 @@  static int bsfs_init(AVCodecContext *avctx)
             goto fail;
     }
 
+    ret = avcodec_parameters_to_context(avctx, s->bsfs[s->nb_bsfs - 1]->par_out);
+    if (ret < 0)
+        return ret;
+
     return 0;
 fail:
     ff_decode_bsfs_uninit(avctx);