[FFmpeg-trac] #773(avcodec:new): Decoding H.264 gets stuck with Win XP, w32threads, and custom AVCodecContext.get_buffer

FFmpeg trac at avcodec.org
Fri Dec 16 00:14:26 CET 2011


#773: Decoding H.264 gets stuck with Win XP, w32threads, and custom
AVCodecContext.get_buffer
----------------------------------+----------------------------------
             Reporter:  andreasg  |                     Type:  defect
               Status:  new       |                 Priority:  normal
            Component:  avcodec   |                  Version:  0.9
             Keywords:            |               Blocked By:
             Blocking:            |  Reproduced by developer:  0
Analyzed by developer:  0         |
----------------------------------+----------------------------------
 I have an application that decodes H.264 video to in-memory RGB frames.
 It works fine multi-threaded in Windows 7 or single-threaded in Windows
 XP.  I use FFmpeg 0.9 that includes the patches from Dec. 7 of this
 functionality in w32threads.h.

 FFmpeg is cross-compiled from Fedora 15 with this configuration:

 configure --enable-memalign-hack --disable-pthreads --enable-w32threads
 --arch=x86 --target-os=mingw32 --cross-prefix=i686-pc-mingw32-

 I traced the problem to my use of a custom get_buffer, the functions
 ff_thread_get_buffer and submit_packet, and the new w32threads
 implementation for Windows XP (not using SleepConditionVariableCS).

 After decoding some of the frames, the threads get stuck here:

 ff_thread_get_buffer:
 while (p->state != STATE_SETTING_UP)
     pthread_cond_wait(&p->progress_cond, &p->progress_mutex);

 submit_packet:
 while (p->state == STATE_SETTING_UP)
     pthread_cond_wait(&p->progress_cond, &p->progress_mutex);

 As the ffmpeg application does not use a custom get_buffer, it does not
 have this problem.  I tried to figure out what is happening in
 w32threads.h but unfortunately adding too many print statements makes the
 problem go away.

 I think that the problem can be avoided by using different condition
 variables for signaling in the two directions between the threads but I
 haven't tried it.

 P.S.: I'm using a custom get_buffer to get a more reliable presentation
 timestamp.  I should check if this is still necessary in the current
 FFmpeg version.

   int64_t global_video_pkt_pts = AV_NOPTS_VALUE;

   int getFrameBuffer (AVCodecContext* c, AVFrame* pic) {
     int ret = avcodec_default_get_buffer (c, pic);
     int64_t* pts = (int64_t*) av_malloc (sizeof (int64_t));
     *pts = global_video_pkt_pts;
     pic->opaque = pts;
     return ret;
   }

   void releaseFrameBuffer (AVCodecContext* c, AVFrame* pic) {
     if (pic)
       av_freep (&pic->opaque);
     avcodec_default_release_buffer (c, pic);
   }

   ...
   global_video_pkt_pts = packet_context.packet.dts;

-- 
Ticket URL: <https://ffmpeg.org/trac/ffmpeg/ticket/773>
FFmpeg <http://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list