[FFmpeg-trac] #1876(avcodec:closed): vc1dec.c multi-threading decode crash issue

FFmpeg trac at avcodec.org
Sat Nov 10 21:55:25 CET 2012


#1876: vc1dec.c multi-threading decode crash issue
-------------------------------------+-------------------------------------
             Reporter:  DonMoir      |                    Owner:
                 Type:  defect       |                   Status:  closed
             Priority:  important    |                Component:  avcodec
              Version:  unspecified  |               Resolution:
             Keywords:  vc1 crash    |  needs_more_info
             Blocking:               |               Blocked By:
Analyzed by developer:  0            |  Reproduced by developer:  0
-------------------------------------+-------------------------------------

Comment (by DonMoir):

 It can be hard to reproduce and it may take me about 10 tries. It came to
 me as a bug from a beta tester where it would happen on occasion. So then
 I wrote some code to trigger it more often. Running, opening multiple
 instances of the above file at the same time is the best way I can
 reproduce it. It does not happen anywhere else except in code that calls
 vc1_decode_frame. The crash can be anywhere because of memory overwrites
 etc.

 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 in vc1_decode_frame 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.

-- 
Ticket URL: <https://ffmpeg.org/trac/ffmpeg/ticket/1876#comment:15>
FFmpeg <http://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list