Deadlock?
I am using ffmpeg 4.2.1. When I encode to h264, the program sometimes deadlocks.
the threadpool_thread x264_pthread_cond_wait will wait mutex
REALIGN_STACK static void *threadpool_thread( x264_threadpool_t *pool )
{
if( pool->init_func )
pool->init_func( pool->init_arg );
while( !pool->exit )
{
x264_threadpool_job_t *job = NULL;
x264_pthread_mutex_lock( &pool->run.mutex );
while( !pool->exit && !pool->run.i_size )
x264_pthread_cond_wait( &pool->run.cv_fill, &pool->run.mutex ); //enter mutex, this line is waiting
if( pool->run.i_size )
{
job = (void*)x264_frame_shift( pool->run.list );
pool->run.i_size--;
}
x264_pthread_mutex_unlock( &pool->run.mutex );
if( !job )
continue;
job->ret = job->func( job->arg );
x264_sync_frame_list_push( &pool->done, (void*)job );
}
return NULL;
}
and if new AVFrame come, x264_sync_frame_list_push will wait mutex.
void x264_sync_frame_list_push( x264_sync_frame_list_t *slist, x264_frame_t *frame )
{
x264_pthread_mutex_lock( &slist->mutex ); //this line will wait
while( slist->i_size == slist->i_max_size )
x264_pthread_cond_wait( &slist->cv_empty, &slist->mutex );
slist->list[ slist->i_size++ ] = frame;
x264_pthread_mutex_unlock( &slist->mutex );
x264_pthread_cond_broadcast( &slist->cv_fill );
}
My code
encode_av_codec_ctx_->bit_rate = stream->codecpar->bit_rate;
encode_av_codec_ctx_->width = des_width;
encode_av_codec_ctx_->height = des_height;
encode_av_codec_ctx_->codec_id = AV_CODEC_ID_H264;
encode_av_codec_ctx_->codec_type = AVMEDIA_TYPE_VIDEO;
encode_av_codec_ctx_->time_base = { 1, 25 };
encode_av_codec_ctx_->framerate = { 25, 1 };
encode_av_codec_ctx_->pix_fmt = format;
encode_av_codec_ctx_->gop_size = 50;
encode_av_codec_ctx_->has_b_frames = 0;
encode_av_codec_ctx_->max_b_frames = 0;
encode_av_codec_ctx_->qmin = 18;
encode_av_codec_ctx_->qmax = 40;
encode_av_codec_ctx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
encode_av_codec_ctx_->profile = FF_PROFILE_H264_HIGH;
encode_av_codec_ctx_->level = FF_LEVEL_UNKNOWN;
encode_av_codec_ctx_->flags |= AV_CODEC_FLAG_LOW_DELAY;
AVDictionary *options = NULL;
av_dict_set(&options, "preset", "ultrafast", 0);
av_dict_set(&options, "tune", "zerolatency", 0);
Where did I use it wrong? thinks.