GNOME Bugzilla – Bug 610556
Memory violation when starting to decode a running DV PAL RTP stream
Last modified: 2010-02-23 11:55:27 UTC
Context: The computer is receiving RTP packets containing DV PAL video. Packets are coming through a WiFi, so lost packet ratio is far from 0. At this point, I start gst-launch as following: gst-launch --gst-debug=ffmpeg:5 -v udpsrc port=5765 caps="application/x-rtp, encode=(string)SD-VCR/625-50" ! rtpdvdepay ! ffdec_dvvideo ! fakesink It seems to be important that the video stream is already running when I start gst_launch (in this way, *maybe* the first decoded frame is just half a frame…). Result: Caught SIGSEGV accessing address 0x19bb000 Backtrace (partially handmade): 0 libSystem.B.dylib 0xffff0840 __memcpy + 160 1 libgstffmpeg.so 0x22c3f160 ff_img_copy_plane + 64 0 libgstffmpeg.so 0x011165cc av_picture_copy + 60 1 libgstffmpeg.so 0x01016ec4 gst_ffmpegdec_video_frame + 3623 2 libgstffmpeg.so 0x0101980a gst_ffmpegdec_frame + 1069 3 libgstffmpeg.so 0x0101b985 gst_ffmpegdec_chain + 4013 4 libgstreamer-0.10.0.dylib 0x00054016 gst_pad_chain_data_unchecked + 545 5 libgstreamer-0.10.0.dylib 0x00054b9d gst_pad_push_data + 532 6 libgstreamer-0.10.0.dylib 0x00055164 gst_pad_push + 365 7 libgstrtp-0.10.0.dylib 0x0070d4a2 gst_base_rtp_depayload_push_full + 912 8 libgstrtp-0.10.0.dylib 0x0070d4d6 gst_base_rtp_depayload_push_ts + 39 9 libgstrtp-0.10.0.dylib 0x0070c95d gst_base_rtp_depayload_chain + 1308 10 libgstreamer-0.10.0.dylib 0x00054016 gst_pad_chain_data_unchecked + 545 11 libgstreamer-0.10.0.dylib 0x00054b9d gst_pad_push_data + 532 12 libgstreamer-0.10.0.dylib 0x00055164 gst_pad_push + 365 13 libgstrtphook.so 0x005db50a gst_rtp_jitter_buffer_loop + 1274 14 libgstreamer-0.10.0.dylib 0x0007bd45 gst_task_func + 688 15 libgstreamer-0.10.0.dylib 0x0007cfc5 default_func + 53 16 libglib-2.0.0.dylib 0x003633bc g_thread_pool_thread_proxy + 110 17 libglib-2.0.0.dylib 0x00361c0f g_thread_create_proxy + 373 18 libSystem.B.dylib 0x9843afbd _pthread_start + 345 19 libSystem.B.dylib 0x9843ae42 thread_start + 34 First analysis: The source buffer from which memcpy() is copying is located at 0x1964000. ff_img_copy_plane() expects a buffer of 720 * 576 bytes (ending at 0x19C9400) but found no valid memory. Few printf() gives me the impression the size of the buffer was made for 720x480 byte frames. The frame is decode by this code: /* now decode the frame */ len = avcodec_decode_video (ffmpegdec->context, ffmpegdec->picture, &have_data, data, size); On the first decoded frame, just before this code, ffmpegdec->context->width=720 and ffmpegdec->context->height=576. Just after this code, ffmpegdec->context->width=720 and ffmpegdec->context->height=480. ffmpegdec->format also stores the size but there the size stay on 720x576. Later, we copy the frame data based on ffmpegdec->format and we read outside the buffer, generating the memory violation. Complete output (with few additional homemade printf starting by "GMO"): ... New clock: GstSystemClock /GstPipeline:pipeline0/GstRTPDVDepay:rtpdvdepay0.GstPad:src: caps = video/x-dv, systemstream=(boolean)false, width=(int)720, height=(int)576, framerate=(fraction)25/1 /GstPipeline:pipeline0/GstRTPDVDepay:rtpdvdepay0.GstPad:sink: caps = application/x-rtp, encode=(string)SD-VCR/625-50, media=(string)video, payload=(int)96, encoding-name=(string)DV, clock-rate=(int)90000 0:00:00.234834000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:2287:gst_ffmpegdec_sink_event:<ffdec_dvvideo0> Handling newsegment event 0:00:00.234897000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:2368:gst_ffmpegdec_sink_event:<ffdec_dvvideo0> NEWSEGMENT in time start 0:00:00.000000000 -- stop 99:99:99.999999999 0:00:00.235009000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:695:gst_ffmpegdec_setcaps:<ffdec_dvvideo0:sink> setcaps called 0:00:00.235802000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:726:gst_ffmpegdec_setcaps:<ffdec_dvvideo0> size 0x0 0:00:00.235827000 13552 0x6afd80 LOG ffmpeg gstffmpegcodecmap.c:2117:gst_ffmpeg_caps_with_codecid: codec_id:25, codec_type:0, caps:0x8edc80 context:0x8f0000 0:00:00.235851000 13552 0x6afd80 DEBUG ffmpeg gstffmpegcodecmap.c:2166:gst_ffmpeg_caps_with_codecid: no codec data 0:00:00.235876000 13552 0x6afd80 DEBUG ffmpeg gstffmpegcodecmap.c:1866:gst_ffmpeg_caps_to_pixfmt: converting caps 0x8edc80 0:00:00.235896000 13552 0x6afd80 DEBUG ffmpeg gstffmpegcodecmap.c:1884:gst_ffmpeg_caps_to_pixfmt: setting framerate 25/1 = 25,000000 0:00:00.235925000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:733:gst_ffmpegdec_setcaps:<ffdec_dvvideo0> size after 720x576 0:00:00.235945000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:763:gst_ffmpegdec_setcaps:<ffdec_dvvideo0> Using framerate 25/1 from incoming caps 0:00:00.235963000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:773:gst_ffmpegdec_setcaps:<ffdec_dvvideo0> trying to enable direct rendering 0:00:00.235980000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:781:gst_ffmpegdec_setcaps:<ffdec_dvvideo0> enabled direct rendering 0:00:00.236958000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:609:gst_ffmpegdec_open:<ffdec_dvvideo0> Opened ffmpeg codec dvvideo, id 25 0:00:00.236990000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:642:gst_ffmpegdec_open:<ffdec_dvvideo0> No parser for codec /GstPipeline:pipeline0/ffdec_dvvideo:ffdec_dvvideo0.GstPad:sink: caps = video/x-dv, systemstream=(boolean)false, width=(int)720, height=(int)576, framerate=(fraction)25/1 0:00:00.237118000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:2957:gst_ts_handler_append:<ffdec_dvvideo0> store timestamp @ index [01] buf_count: 0 ts: 0:00:00.022542000, offset: 18446744073709551615, size: 144000 0:00:00.237143000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:2447:gst_ffmpegdec_chain:<ffdec_dvvideo0> waiting for keyframe 0:00:00.237162000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:2452:gst_ffmpegdec_chain:<ffdec_dvvideo0> got keyframe 0:00:00.237185000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:2464:gst_ffmpegdec_chain:<ffdec_dvvideo0> Received new data of size 144000, offset:18446744073709551615, ts:0:00:00.022542000, dur:99:99:99.999999999 0:00:00.237221000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:2554:gst_ffmpegdec_chain:<ffdec_dvvideo0> resized padding buffer to 144008 0:00:00.237457000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:2142:gst_ffmpegdec_frame:<ffdec_dvvideo0> data:0x1940000, size:144000, offset:-1, ts:0:00:00.022542000, dur:99:99:99.999999999 0:00:00.237492000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1657:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> Going to store opaque values, current ts:0:00:00.022542000, offset: -1 0:00:00.237513000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:3023:gst_ts_handler_get_ts:<ffdec_dvvideo0> Index 1 yielded ts 0:00:00.022542000 offset -1 0:00:00.237537000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1560:opaque_store:<ffdec_dvvideo0> Stored ts:0:00:00.022542000, offset:18446744073709551615 as opaque 0x8fb8c0 GMO: ffmpegdec->picture just before decoding: 0x6add80 GMO: data[0]=0x0, data[1]=0x0, data[2]=0x0 0:00:00.237671000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:919:gst_ffmpegdec_get_buffer:<ffdec_dvvideo0> getting buffer, apply pts 22542000 0:00:00.237701000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:936:gst_ffmpegdec_get_buffer:<ffdec_dvvideo0> dimension 720x480, coded 720x480 0:00:00.237720000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:963:gst_ffmpegdec_get_buffer:<ffdec_dvvideo0> raw outsize 720/480 0:00:00.237738000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:969:gst_ffmpegdec_get_buffer:<ffdec_dvvideo0> aligned outsize 736/480, clip 720/576 0:00:00.237755000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:973:gst_ffmpegdec_get_buffer:<ffdec_dvvideo0> we need clipping, fallback alloc GMO: width=720, height=576 GMO: ffmpegdec->picture just after decoding: 0x6add80 GMO: data[0]=0x1964000, data[1]=0x8ff200, data[2]=0x914c00 0:00:00.243777000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:2985:gst_ts_handler_consume:<ffdec_dvvideo0> Stepping over 120000 bytes @ index 1 has 144000 bytes 0:00:00.243819000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1688:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> after decode: len 120000, have_data 200 0:00:00.243838000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1577:opaque_find:<ffdec_dvvideo0> Found opaque 0x8fb8c0 - ts:0:00:00.022542000, offset:-1 0:00:00.243862000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1718:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> Found opaque values, current ts:0:00:00.022542000, offset: -1 0:00:00.243881000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1721:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> ts-handler: pts 22542000 0:00:00.244054000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1723:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> picture: pts 22542000 0:00:00.244078000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1725:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> picture: num 0 0:00:00.244095000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1727:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> picture: ref 0 0:00:00.244112000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1729:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> picture: display 0 0:00:00.244161000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1731:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> picture: opaque 0x0 0:00:00.244191000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1733:gst_ffmpegdec_video_frame:<ffdec_dvvideo0> repeat_pict:0 0:00:00.245380000 13552 0x6afd80 WARN ffmpeg gstffmpegdec.c:1739:gst_ffmpegdec_video_frame: Change in interlacing ! picture:1, recorded:0 0:00:00.245409000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1152:gst_ffmpegdec_negotiate:<ffdec_dvvideo0> Renegotiating video from 0x0@ -1/-1 fps to 720x480@ 25/1 fps 0:00:00.245433000 13552 0x6afd80 LOG ffmpeg gstffmpegcodecmap.c:1744:gst_ffmpeg_codectype_to_video_caps: context:0x8f0000, codec_id:25, encode:0, codec:0x0 0:00:00.245453000 13552 0x6afd80 LOG ffmpeg gstffmpegcodecmap.c:194:gst_ff_vid_caps_new: context:0x8f0000, codec_id:25, mimetype:video/x-raw-yuv 0:00:00.245496000 13552 0x6afd80 DEBUG ffmpeg gstffmpegcodecmap.c:1622:gst_ffmpeg_pixfmt_to_caps: caps for pix_fmt=8: 0x8edcc0 0:00:00.245520000 13552 0x6afd80 DEBUG ffmpeg gstffmpegdec.c:1126:gst_ffmpegdec_add_pixel_aspect_ratio:<ffdec_dvvideo0> Neither demuxer nor codec provide a pixel-aspect-ratio GMO: width=720, height=480 /GstPipeline:pipeline0/ffdec_dvvideo:ffdec_dvvideo0.GstPad:src: caps = video/x-raw-yuv, width=(int)720, height=(int)576, framerate=(fraction)25/1, format=(fourcc)Y41B, interlaced=(boolean)true 0:00:00.245659000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:1452:check_keyframe:<ffdec_dvvideo0> current picture: type: 1, is_keyframe:1, is_itype:1, is_reference:0 0:00:00.245680000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:1478:get_output_buffer:<ffdec_dvvideo0> get output buffer 0:00:00.245698000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:1487:get_output_buffer:<ffdec_dvvideo0> clip width 720/height 576 GMO: 720 480 0:00:00.245716000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:854:alloc_output_buffer:<ffdec_dvvideo0> alloc output buffer 0:00:00.245746000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:866:alloc_output_buffer:<ffdec_dvvideo0> calling pad_alloc 0:00:00.245812000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:1501:get_output_buffer:<ffdec_dvvideo0> linsize 736 184 184 0:00:00.245832000 13552 0x6afd80 LOG ffmpeg gstffmpegdec.c:1503:get_output_buffer:<ffdec_dvvideo0> data 0 -17190400 -17101824 0 libgstffmpeg.so 0x01115eb5 av_picture_copy + 53 0 libgstffmpeg.so 0x01115dc5 ff_img_copy_plane + 101 GMO: after renegotiation: width=720, height=480 GMO: 1-0x1b00000 720 0x1964000 736 720 576 Caught SIGSEGV accessing address 0x19bb000
It looks like it has to do with the fact that when one of the headers is dropped, the decoder can't decode properly.
Created attachment 154417 [details] [review] possible patch A possible patch that waits for all the headers to arrive before pushing out frames.
Isn't this pre-release material? Or too invasive/risky?
Your call. I would not call it too risky, it's also not a regression. I'm happy to commit after the release.
It's a fix for a crasher, no? Even if not a regression, it would be nice to get it in if it's not risky, IMHO.
commit e43839eae9da88fdc90d70367d0e16b335ce5f1d Author: Wim Taymans <wim.taymans@collabora.co.uk> Date: Mon Feb 22 18:20:46 2010 +0100 dvdepay: don't output frames until we have a header Wait for the complete first 6 header DIF packets before outputting a frame. Decoders need this info to correctly decode the data. Fixes #610556