diff mbox

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

Message ID 20180727145749.9436-8-jamrial@gmail.com
State Accepted
Commit f631c328e680a3dd491936b92f69970c20cdcfc7
Headers show

Commit Message

James Almer July 27, 2018, 2:57 p.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>
---
Now it's not going to be called after the codec has been opened.

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

Comments

Michael Niedermayer July 28, 2018, 1:58 a.m. UTC | #1
On Fri, Jul 27, 2018 at 11:57:49AM -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>
> ---
> Now it's not going to be called after the codec has been opened.
> 
>  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 -

  libavutil      56. 18.102 / 56. 18.102
  libavcodec     58. 22.100 / 58. 22.100
  libavformat    58. 17.101 / 58. 17.101
  libavdevice    58.  4.101 / 58.  4.101
  libavfilter     7. 26.100 /  7. 26.100
  libswscale      5.  2.100 /  5.  2.100
  libswresample   3.  2.100 /  3.  2.100
  libpostproc    55.  2.100 / 55.  2.100
==7203== Syscall param sendmsg(mmsg[0].msg_hdr) points to uninitialised byte(s)
==7203==    at 0xF5667D9: sendmmsg (sendmmsg.c:32)
==7203==    by 0x1FF88AB0: __libc_res_nsend (res_send.c:1279)
==7203==    by 0x1FF85E2B: __libc_res_nquery (res_query.c:227)
==7203==    by 0x1FF86862: __libc_res_nsearch (res_query.c:591)
==7203==    by 0x25B07C72: _nss_dns_gethostbyname4_r (dns-host.c:315)
==7203==    by 0xF537665: gaih_inet (getaddrinfo.c:858)
==7203==    by 0xF53A96C: getaddrinfo (getaddrinfo.c:2414)
==7203==    by 0x783CAC: tcp_open (in ffmpeg/ffmpeg_g)
==7203==    by 0x6710D5: ffurl_connect (in ffmpeg/ffmpeg_g)
==7203==    by 0x6717CC: ffurl_open_whitelist (in ffmpeg/ffmpeg_g)
==7203==    by 0x7D8C23: ff_tls_open_underlying (in ffmpeg/ffmpeg_g)
==7203==    by 0x786BBA: tls_open (in ffmpeg/ffmpeg_g)
==7203==    by 0x670FBE: ffurl_connect (in ffmpeg/ffmpeg_g)
==7203==    by 0x6717CC: ffurl_open_whitelist (in ffmpeg/ffmpeg_g)
==7203==    by 0x6B85AC: http_open_cnx_internal (in ffmpeg/ffmpeg_g)
==7203==    by 0x6B87FA: http_open_cnx (in ffmpeg/ffmpeg_g)
==7203==    by 0x6B9A18: http_open (in ffmpeg/ffmpeg_g)
==7203==    by 0x670FBE: ffurl_connect (in ffmpeg/ffmpeg_g)
==7203==    by 0x6717CC: ffurl_open_whitelist (in ffmpeg/ffmpeg_g)
==7203==    by 0x67AF2F: ffio_open_whitelist (in ffmpeg/ffmpeg_g)
==7203==  Address 0x7feff7ff0 is on thread 1's stack
==7203==  Uninitialised value was created by a stack allocation
==7203==    at 0x1FF87E6D: __libc_res_nsend (res_send.c:364)
==7203== 
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
==7203== Thread 2:
==7203== Invalid read of size 4
==7203==    at 0xA43816: decode_frame_common.isra.9 (in ffmpeg/ffmpeg_g)
==7203==    by 0xA46C37: decode_frame_apng (in ffmpeg/ffmpeg_g)
==7203==    by 0xA544B0: frame_worker_thread (in ffmpeg/ffmpeg_g)
==7203==    by 0xB8A2183: start_thread (pthread_create.c:312)
==7203==    by 0xF56503C: clone (clone.S:111)
==7203==  Address 0x256136c0 is 0 bytes inside a block of size 109 free'd
==7203==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==7203==    by 0xB3362F: avcodec_parameters_to_context (in ffmpeg/ffmpeg_g)
==7203==    by 0x829EC8: ff_decode_bsfs_init (in ffmpeg/ffmpeg_g)
==7203==    by 0xB3044A: avcodec_open2 (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CA18C: transcode_init (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CC6F8: transcode (in ffmpeg/ffmpeg_g)
==7203==    by 0x4AACDC: main (in ffmpeg/ffmpeg_g)
==7203== 
==7203== Invalid read of size 4
==7203==    at 0xA4384A: decode_frame_common.isra.9 (in ffmpeg/ffmpeg_g)
==7203==    by 0xA46C37: decode_frame_apng (in ffmpeg/ffmpeg_g)
==7203==    by 0xA544B0: frame_worker_thread (in ffmpeg/ffmpeg_g)
==7203==    by 0xB8A2183: start_thread (pthread_create.c:312)
==7203==    by 0xF56503C: clone (clone.S:111)
==7203==  Address 0x256136c4 is 4 bytes inside a block of size 109 free'd
==7203==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==7203==    by 0xB3362F: avcodec_parameters_to_context (in ffmpeg/ffmpeg_g)
==7203==    by 0x829EC8: ff_decode_bsfs_init (in ffmpeg/ffmpeg_g)
==7203==    by 0xB3044A: avcodec_open2 (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CA18C: transcode_init (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CC6F8: transcode (in ffmpeg/ffmpeg_g)
==7203==    by 0x4AACDC: main (in ffmpeg/ffmpeg_g)
==7203== 
==7203== Invalid read of size 4
==7203==    at 0xA44E8E: decode_frame_common.isra.9 (in ffmpeg/ffmpeg_g)
==7203==    by 0xA46C37: decode_frame_apng (in ffmpeg/ffmpeg_g)
==7203==    by 0xA544B0: frame_worker_thread (in ffmpeg/ffmpeg_g)
==7203==    by 0xB8A2183: start_thread (pthread_create.c:312)
==7203==    by 0xF56503C: clone (clone.S:111)
==7203==  Address 0x256136c8 is 8 bytes inside a block of size 109 free'd
==7203==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==7203==    by 0xB3362F: avcodec_parameters_to_context (in ffmpeg/ffmpeg_g)
==7203==    by 0x829EC8: ff_decode_bsfs_init (in ffmpeg/ffmpeg_g)
==7203==    by 0xB3044A: avcodec_open2 (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CA18C: transcode_init (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CC6F8: transcode (in ffmpeg/ffmpeg_g)
==7203==    by 0x4AACDC: main (in ffmpeg/ffmpeg_g)
==7203== 
==7203== Invalid read of size 4
==7203==    at 0xA44EB2: decode_frame_common.isra.9 (in ffmpeg/ffmpeg_g)
==7203==    by 0xA46C37: decode_frame_apng (in ffmpeg/ffmpeg_g)
==7203==    by 0xA544B0: frame_worker_thread (in ffmpeg/ffmpeg_g)
==7203==    by 0xB8A2183: start_thread (pthread_create.c:312)
==7203==    by 0xF56503C: clone (clone.S:111)
==7203==  Address 0x256136cc is 12 bytes inside a block of size 109 free'd
==7203==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==7203==    by 0xB3362F: avcodec_parameters_to_context (in ffmpeg/ffmpeg_g)
==7203==    by 0x829EC8: ff_decode_bsfs_init (in ffmpeg/ffmpeg_g)
==7203==    by 0xB3044A: avcodec_open2 (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CA18C: transcode_init (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CC6F8: transcode (in ffmpeg/ffmpeg_g)
==7203==    by 0x4AACDC: main (in ffmpeg/ffmpeg_g)
==7203== 
==7203== Invalid read of size 1
==7203==    at 0xA4401E: decode_frame_common.isra.9 (in ffmpeg/ffmpeg_g)
==7203==    by 0xA46C37: decode_frame_apng (in ffmpeg/ffmpeg_g)
==7203==    by 0xA544B0: frame_worker_thread (in ffmpeg/ffmpeg_g)
==7203==    by 0xB8A2183: start_thread (pthread_create.c:312)
==7203==    by 0xF56503C: clone (clone.S:111)
==7203==  Address 0x256136d0 is 16 bytes inside a block of size 109 free'd
==7203==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==7203==    by 0xB3362F: avcodec_parameters_to_context (in ffmpeg/ffmpeg_g)
==7203==    by 0x829EC8: ff_decode_bsfs_init (in ffmpeg/ffmpeg_g)
==7203==    by 0xB3044A: avcodec_open2 (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CA18C: transcode_init (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CC6F8: transcode (in ffmpeg/ffmpeg_g)
==7203==    by 0x4AACDC: main (in ffmpeg/ffmpeg_g)
==7203== 
==7203== Invalid read of size 1
==7203==    at 0xA44053: decode_frame_common.isra.9 (in ffmpeg/ffmpeg_g)
==7203==    by 0xA46C37: decode_frame_apng (in ffmpeg/ffmpeg_g)
==7203==    by 0xA544B0: frame_worker_thread (in ffmpeg/ffmpeg_g)
==7203==    by 0xB8A2183: start_thread (pthread_create.c:312)
==7203==    by 0xF56503C: clone (clone.S:111)
==7203==  Address 0x256136d1 is 17 bytes inside a block of size 109 free'd
==7203==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==7203==    by 0xB3362F: avcodec_parameters_to_context (in ffmpeg/ffmpeg_g)
==7203==    by 0x829EC8: ff_decode_bsfs_init (in ffmpeg/ffmpeg_g)
==7203==    by 0xB3044A: avcodec_open2 (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CA18C: transcode_init (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CC6F8: transcode (in ffmpeg/ffmpeg_g)
==7203==    by 0x4AACDC: main (in ffmpeg/ffmpeg_g)
==7203== 
==7203== Invalid read of size 1
==7203==    at 0xA44076: decode_frame_common.isra.9 (in ffmpeg/ffmpeg_g)
==7203==    by 0xA46C37: decode_frame_apng (in ffmpeg/ffmpeg_g)
==7203==    by 0xA544B0: frame_worker_thread (in ffmpeg/ffmpeg_g)
==7203==    by 0xB8A2183: start_thread (pthread_create.c:312)
==7203==    by 0xF56503C: clone (clone.S:111)
==7203==  Address 0x256136d2 is 18 bytes inside a block of size 109 free'd
==7203==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==7203==    by 0xB3362F: avcodec_parameters_to_context (in ffmpeg/ffmpeg_g)
==7203==    by 0x829EC8: ff_decode_bsfs_init (in ffmpeg/ffmpeg_g)
==7203==    by 0xB3044A: avcodec_open2 (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CA18C: transcode_init (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CC6F8: transcode (in ffmpeg/ffmpeg_g)
==7203==    by 0x4AACDC: main (in ffmpeg/ffmpeg_g)
==7203== 
==7203== Invalid read of size 1
==7203==    at 0xA44099: decode_frame_common.isra.9 (in ffmpeg/ffmpeg_g)
==7203==    by 0xA46C37: decode_frame_apng (in ffmpeg/ffmpeg_g)
==7203==    by 0xA544B0: frame_worker_thread (in ffmpeg/ffmpeg_g)
==7203==    by 0xB8A2183: start_thread (pthread_create.c:312)
==7203==    by 0xF56503C: clone (clone.S:111)
==7203==  Address 0x256136d3 is 19 bytes inside a block of size 109 free'd
==7203==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==7203==    by 0xB3362F: avcodec_parameters_to_context (in ffmpeg/ffmpeg_g)
==7203==    by 0x829EC8: ff_decode_bsfs_init (in ffmpeg/ffmpeg_g)
==7203==    by 0xB3044A: avcodec_open2 (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CA18C: transcode_init (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CC6F8: transcode (in ffmpeg/ffmpeg_g)
==7203==    by 0x4AACDC: main (in ffmpeg/ffmpeg_g)
==7203== 
==7203== Invalid read of size 1
==7203==    at 0xA440BB: decode_frame_common.isra.9 (in ffmpeg/ffmpeg_g)
==7203==    by 0xA46C37: decode_frame_apng (in ffmpeg/ffmpeg_g)
==7203==    by 0xA544B0: frame_worker_thread (in ffmpeg/ffmpeg_g)
==7203==    by 0xB8A2183: start_thread (pthread_create.c:312)
==7203==    by 0xF56503C: clone (clone.S:111)
==7203==  Address 0x256136d4 is 20 bytes inside a block of size 109 free'd
==7203==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==7203==    by 0xB3362F: avcodec_parameters_to_context (in ffmpeg/ffmpeg_g)
==7203==    by 0x829EC8: ff_decode_bsfs_init (in ffmpeg/ffmpeg_g)
==7203==    by 0xB3044A: avcodec_open2 (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CA18C: transcode_init (in ffmpeg/ffmpeg_g)
==7203==    by 0x4CC6F8: transcode (in ffmpeg/ffmpeg_g)
==7203==    by 0x4AACDC: main (in ffmpeg/ffmpeg_g)
==7203== 
#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.234x    
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
frame=   20 fps=0.0 q=-0.0 Lsize=       1kB time=00:00:01.50 bitrate=   6.7kbits/s speed=2.01x    
video:781kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
==7203== 
==7203== HEAP SUMMARY:
==7203==     in use at exit: 157,232 bytes in 2,754 blocks
==7203==   total heap usage: 6,692 allocs, 3,938 frees, 5,002,126 bytes allocated
==7203== 
==7203== LEAK SUMMARY:
==7203==    definitely lost: 0 bytes in 0 blocks
==7203==    indirectly lost: 0 bytes in 0 blocks
==7203==      possibly lost: 0 bytes in 0 blocks
==7203==    still reachable: 157,232 bytes in 2,754 blocks
==7203==         suppressed: 0 bytes in 0 blocks
==7203== Reachable blocks (those to which a pointer was found) are not shown.
==7203== To see them, rerun with: --leak-check=full --show-reachable=yes
==7203== 
==7203== For counts of detected and suppressed errors, rerun with: -v
==7203== ERROR SUMMARY: 17 errors from 12 contexts (suppressed: 0 from 0)


[...]
James Almer July 28, 2018, 2:11 a.m. UTC | #2
On 7/27/2018 10:58 PM, Michael Niedermayer wrote:
> On Fri, Jul 27, 2018 at 11:57:49AM -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>
>> ---
>> Now it's not going to be called after the codec has been opened.
>>
>>  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 -

Is any other decoder failing the same way? Because the apng decoder
threading code may be faulty otherwise. Plenty of avctx fields are
changed after ff_thread_init() is called within avcodec_open2(). There
should not be a race at this point.
Michael Niedermayer July 28, 2018, 7:09 a.m. UTC | #3
On Fri, Jul 27, 2018 at 11:11:47PM -0300, James Almer wrote:
> On 7/27/2018 10:58 PM, Michael Niedermayer wrote:
> > On Fri, Jul 27, 2018 at 11:57:49AM -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>
> >> ---
> >> Now it's not going to be called after the codec has been opened.
> >>
> >>  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 -
> 
> Is any other decoder failing the same way? Because the apng decoder
> threading code may be faulty otherwise. Plenty of avctx fields are
> changed after ff_thread_init() is called within avcodec_open2(). There
> should not be a race at this point.

I found a failure with mpeg4 (with bframes) decoding + pcm_alaw from mkv but it
does not want to reproduce. The slightest change i do makes this not happen
even just duplicating a command line parameter (which should have no effect)
simply adding the -threads parameter to it independant of value makes it go away
too


in the png case
this hits teh issue:
-threads 2 -i https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png  -f framecrc -

this does not:
-threads 1 -i https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png  -f framecrc -

also odly the bitexact flag made a differnce in how it fails outside valgrind
last i tried. (doesnt make a difference in valgrind it seems)
diff mbox

Patch

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 2e82f6b506..4607e9f318 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -281,6 +281,10 @@  int ff_decode_bsfs_init(AVCodecContext *avctx)
             bsfs_str++;
     }
 
+    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);