[FFmpeg-devel] Threading issue with avcodec_decode_video2 ?

Don Moir donmoir at comcast.net
Tue Oct 30 20:58:32 CET 2012


>> I looked over those two functions, and sadly its required to call them
>> there, because its possible that width/height of the video are not
>> known during the init function, or may even change in case of vc1image
>> decoding.
>> Now, the static structures should only be initialized once, and guard
>> themself against re-init, so i see two solutions: Either lock this
>> block, or call them once in the init function to create the static
>> data, and keep calling them in there.
>>
>> I'm partial to the locking.
>>
>> - Hendrik
>
> Thank you Hendrik. Given what you said, putting a lock around the init functions in vc1_decode_frame does for sure have the least 
> amount of potential impact. That was my first pass on it but found it necessary to add avpriv_lock_avcodec and 
> avpriv_unlock_avcodec since these don't currently exist. Could be other ways as well. Should be a rare event.

My only current way to fix this is to have a unique build. After looking around some more and hints from Hendrik, it appears the fix 
is best put in vc1_decode_frame.

The problem code is:

    if (!s->context_initialized) {
        if (ff_msmpeg4_decode_init(avctx) < 0 ||  ff_vc1_decode_init_alloc_tables(v) < 0)
            goto err;
        s->low_delay = !avctx->has_b_frames || v->res_sprite;
        if (v->profile == PROFILE_ADVANCED) {
            s->h_edge_pos = avctx->coded_width;
            s->v_edge_pos = avctx->coded_height;
        }
    }

The offending statement is:

        if (ff_msmpeg4_decode_init(avctx) < 0 ||  ff_vc1_decode_init_alloc_tables(v) < 0)

After adding avpriv_lock_codec and avpriv_unlock_codec since they don't exist.

A couple ways to organize the fix but this way produces no addional testing or assignments:

    if (!s->context_initialized) {
        avpriv_lock_avcodec ();
        if (ff_msmpeg4_decode_init(avctx) < 0 ||  ff_vc1_decode_init_alloc_tables(v) < 0) {
            avpriv_unlock_avcodec ();
            goto err;
        }
        avpriv_unlock_avcodec ();
        s->low_delay = !avctx->has_b_frames || v->res_sprite;
        if (v->profile == PROFILE_ADVANCED) {
            s->h_edge_pos = avctx->coded_width;
            s->v_edge_pos = avctx->coded_height;
        }
    }

I don't like this way with the 2 unlocks and I would probably restructure to an initialize_context function but trying to keep it 
straight foward here.

If there is any way else to fix it with less impact, I don't know.

This is a severe problem when multi-threading leading to crashes and as Carl stated: "As you know, we consider crashes important". 
Who doesn't ?

I don't know if you have any way of testing multi-threading issues.

I don't know if I should create a ticket on it just so Carl can close it because I did not provide "complete, uncut console output 
and backtrace" and he will not be able to produce the problem with a single threaded (or single video) application. 



More information about the ffmpeg-devel mailing list