[FFmpeg-devel] [PATCH] ffplay: fix a crash caused by aborting the video queue
avcoder
ffmpeg at gmail.com
Sun Aug 28 08:08:59 CEST 2011
On Sun, Aug 28, 2011 at 4:13 AM, Marton Balint <cus at passwd.hu> wrote:
>>>
>>> I don't agree, because with my patch, alloc_picture and
>>> SDL_LockYUVOverlay
>>> of queue_picture cannot run at the same time, therefore there is no
>>> chance
>>> that SDL_LockYUVOverlay will do a lock using a currently freed pointer,
>>> which may be the case, if SDL_LockYUVOverlay happens when the main thread
>>> is
>>> in the middle of alloc_picture.
>>
>>
>> SDL_LockYUVOverlay has no chance to happens when the main thread is in
>> the middle of alloc_picture in the original implementation
>>
>> there are serialization.
>>
>> /* alloc or resize hardware picture buffer */
>> if (!vp->bmp ||
>> #if CONFIG_AVFILTER
>> vp->width != is->out_video_filter->inputs[0]->w ||
>> vp->height != is->out_video_filter->inputs[0]->h) {
>> #else
>> vp->width != is->video_st->codec->width ||
>> vp->height != is->video_st->codec->height) {
>> #endif
>> SDL_Event event;
>>
>> vp->allocated = 0;
>>
>> /* the allocation must be done in the main thread to avoid
>> locking problems */
>> event.type = FF_ALLOC_EVENT;
>> event.user.data1 = is;
>> SDL_PushEvent(&event);
>>
>> // ----------------------- code
>> a--------------------------------------
>> /* wait until the picture is allocated */
>> SDL_LockMutex(is->pictq_mutex);
>> while (!vp->allocated && !is->videoq.abort_request) {
>> SDL_CondWait(is->pictq_cond, is->pictq_mutex);
>> }
>> SDL_UnlockMutex(is->pictq_mutex);
>>
>> // -----------------------code b
>> --------------------------------------
>> if (is->videoq.abort_request)
>> return -1;
>> }
>>
>> /* if the frame is not skipped, then display it */
>> if (vp->bmp) {
>> AVPicture pict;
>> #if CONFIG_AVFILTER
>> if(vp->picref)
>> avfilter_unref_buffer(vp->picref);
>> vp->picref = src_frame->opaque;
>> #endif
>>
>> // ----------------------------code
>> c-----------------------------------
>> /* get a pointer on the bitmap */
>> SDL_LockYUVOverlay (vp->bmp);
>>
>> memset(&pict,0,sizeof(AVPicture));
>> pict.data[0] = vp->bmp->pixels[0];
>> pict.data[1] = vp->bmp->pixels[2];
>> pict.data[2] = vp->bmp->pixels[1];
>>
>> pict.linesize[0] = vp->bmp->pitches[0];
>> pict.linesize[1] = vp->bmp->pitches[2];
>> pict.linesize[2] = vp->bmp->pitches[1];
>>
>> ......
>>
>> }
>>
>>
>> 'code c' and 'alloc_picture()' can be concurrent only in abort mode,
>> but 'code b ' prevent them.
>
> 'Code b' only prevents the lock in the aborted thread. It does not prevent
> the lock when a new video_thread is spawned, and videoq.abort_request is no
> longer set. In the freshly spawned video_thread the code execution goes
> through 'code a', because the alloc event from the aborted thread may only
> be processed after posting of the second alloc event.
Thanks for your patient.
I understand your conclusion, 'stream_cycle_channel()' could ( only? )
cause this bug.
Your patch is valid.
--
-----------------------------------------------------------------------------------------
My key fingerprint: d1:03:f5:32:26:ff:d7:3c:e4:42:e3:51:ec:92:78:b2
More information about the ffmpeg-devel
mailing list