[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