[mythtv] Seg Fault in mediacodec

Peter Bennett pb.mythtv at gmail.com
Thu Jul 5 21:16:43 UTC 2018



On 07/05/2018 04:58 PM, Peter Bennett wrote:
>
>
>
> On 07/05/2018 04:49 PM, Aman Gupta wrote:
>>
>> On Thu, Jul 5, 2018 at 4:04 PM Peter Bennett <pb.mythtv at gmail.com 
>> <mailto:pb.mythtv at gmail.com>> wrote:
>>
>>
>>
>>     On 07/05/2018 01:08 PM, David Engel wrote:
>>>>     I reduced the number of buffers so that it displays a couple of frames
>>>>     before crashing. I see a fat green line along the bottom. I suspect that it
>>>>     is trying to use a frame size of 1920x1088 instead of 1920x1080 (see the
>>>>     trace I sent, it shows slice-height 1088). I plan to step through the ffmpeg
>>>>     code and see if perhaps it is copying 8 rows more than it should. I don't
>>>>     know what the slice-height refers to, but it looks suspicious.
>>>>
>>>>     It may be that the problem is associated with 1080 rows. Of the resolutions
>>>>     I have tried, only 1080 is not divisible by 16. I have tried 480, 720, 2160
>>>>     - all work without seg fault.
>>>     You could be on to something.  The a/v side of things is not an area
>>>     with which I'm intimately familier, however, I vaguely recall various
>>>     issues with 1080 vs. 1088 popping up in the past.  Where's Mike Dean
>>>     when we need him?:)
>>     It turns out that is in fact the cause of the crash. The second
>>     plane in the buffer follows on immediately after 1080 lines of
>>     the first plane, but the code assumes it is after 1088 lines of
>>     the first plane, based on slice_height. Is slice_height supposed
>>     to tell the height of the plane? It crashes on copying data for
>>     the second plane when it hits the actual end of the data and
>>     starts accessing addresses beyond that.
>>
>>     This is the patch that fixes it. Instead of using slice_height
>>     here, use height. I suspect that this may cause a failure in
>>     Nougat or other systems if they do in fact have a gap between planes.
>>
>>     --- a/mythtv/external/FFmpeg/libavcodec/mediacodec_sw_buffer.c
>>     +++ b/mythtv/external/FFmpeg/libavcodec/mediacodec_sw_buffer.c
>>     @@ -150,7 +150,8 @@ void
>>     ff_mediacodec_sw_buffer_copy_yuv420_semi_planar(AVCodecContext
>>     *avctx,
>>              } else if (i == 1) {
>>                  height = avctx->height / 2;
>>
>>     -            src += s->slice_height * s->stride;
>>     +            src += s->height * s->stride;
>>                  src += s->crop_top * s->stride;
>>                  src += s->crop_left;
>>              }
>>
>>     Aman - please let me know if this is the correct fix and if you
>>     can incorporate it into FFmpeg.
>>
>>
>> I'm not very familiar with the s/w decoding code paths. I believe 
>> this part of the code came from gstreamer so it might be useful to 
>> see what (if anything) they've done to deal with Oreo.
>>
>> If this breaks Nougat then obviously it cannot be committed as-is.
>>
>> IIRC slice_height is supposed to return the size of the buffer so I'm 
>> pretty sure the correct thing to do here is to continue using 
>> slice_height. It's possible that adding the crop values on top is 
>> what's causing the buffer overflow- maybe those weren't set before Oreo?
>>
>> Aman
>>
>>
>>
>>     Peter
>>
>
> Here is the output from explore on my Oreo system when it got the seg 
> fault. You can see that crop_left is zero so leaving that out will not 
> help. It seems to me that this may be a bug in Oreo or the Shield 
> version of it.
>
>   The value of '*s' is of type 'MediaCodecDecContext' which is a 
> typedef of type 'struct MediaCodecDecContext'
> The value of '*s' is a struct/class of type 'struct 
> MediaCodecDecContext' with the following fields:
>
>                  avctx = <Enter 0 to explore this field of type 
> 'AVCodecContext *'>
>               refcount = 1 .. (Value of type 'atomic_int')
>        hw_buffer_count = 0 .. (Value of type 'atomic_int')
>             codec_name = <Enter 3 to explore this field of type 'char *'>
>                  codec = <Enter 4 to explore this field of type 
> 'FFAMediaCodec *'>
>                 format = <Enter 5 to explore this field of type 
> 'FFAMediaFormat *'>
>                surface = <Enter 6 to explore this field of type 'void *'>
>                started = 0 .. (Value of type 'int')
>               draining = 0 .. (Value of type 'int')
>               flushing = 0 .. (Value of type 'int')
>                    eos = 0 .. (Value of type 'int')
>                  width = 1920 .. (Value of type 'int')
>                 height = 1080 .. (Value of type 'int')
>                 stride = 1920 .. (Value of type 'int')
>           slice_height = 1088 .. (Value of type 'int')
>           color_format = 21 .. (Value of type 'int')
>               crop_top = 0 .. (Value of type 'int')
>            crop_bottom = 1079 .. (Value of type 'int')
>              crop_left = 0 .. (Value of type 'int')
>             crop_right = 1919 .. (Value of type 'int')
>          display_width = 1920 .. (Value of type 'int')
>         display_height = 1080 .. (Value of type 'int')
>    output_buffer_count = <Enter 22 to explore this field of type 
> 'uint64_t'>
>   current_input_buffer = <Enter 23 to explore this field of type 
> 'ssize_t'>
>            delay_flush = false .. (Value of type '_Bool')
>                 serial = 1 .. (Value of type 'atomic_int')
>
>
Aman

You could check the size of the buffer received. This is the trace log 
message -

[mpeg2_mediacodec @ 0x2afc77f378] Got output buffer 7 offset=0 
size=3110400 ts=53009921316 flags=0

Buffer size of 3110400 is equal to 1920*1080 + 1920 * 540.

If you use the slice_height you access 1920 * 1088 + 1920 * 540 = 
3125760 bytes which is more than the buffer size.

Using the buffer size you can tell whether height or slice_height should 
be used.

Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mythtv.org/pipermail/mythtv-dev/attachments/20180705/788b30d0/attachment.html>


More information about the mythtv-dev mailing list