/**
* Array of progress values used by ff_thread_get_buffer().
*/
- int progress[MAX_BUFFERS][2];
- uint8_t progress_used[MAX_BUFFERS];
+ volatile int progress[MAX_BUFFERS][2];
+ volatile uint8_t progress_used[MAX_BUFFERS];
AVFrame *requested_frame; ///< AVFrame the codec passed to get_buffer()
} PerThreadContext;
* limit the number of threads to 16 for automatic detection */
#define MAX_AUTO_THREADS 16
-static int get_logical_cpus(AVCodecContext *avctx)
+int ff_get_logical_cpus(AVCodecContext *avctx)
{
int ret, nb_cpus = 1;
#if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT)
int thread_count = avctx->thread_count;
if (!thread_count) {
- int nb_cpus = get_logical_cpus(avctx);
+ int nb_cpus = ff_get_logical_cpus(avctx);
// use number of cores + 1 as thread count if there is more than one
if (nb_cpus > 1)
thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
dst->release_buffer = src->release_buffer;
dst->opaque = src->opaque;
- dst->dsp_mask = src->dsp_mask;
dst->debug = src->debug;
dst->debug_mv = src->debug_mv;
static void free_progress(AVFrame *f)
{
PerThreadContext *p = f->owner->thread_opaque;
- int *progress = f->thread_opaque;
+ volatile int *progress = f->thread_opaque;
p->progress_used[(progress - p->progress[0]) / 2] = 0;
}
void ff_thread_report_progress(AVFrame *f, int n, int field)
{
PerThreadContext *p;
- int *progress = f->thread_opaque;
+ volatile int *progress = f->thread_opaque;
if (!progress || progress[field] >= n) return;
void ff_thread_await_progress(AVFrame *f, int n, int field)
{
PerThreadContext *p;
- int *progress = f->thread_opaque;
+ volatile int *progress = f->thread_opaque;
if (!progress || progress[field] >= n) return;
int i, err = 0;
if (!thread_count) {
- int nb_cpus = get_logical_cpus(avctx);
+ int nb_cpus = ff_get_logical_cpus(avctx);
if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv)
nb_cpus = 1;
// use number of cores + 1 as thread count if there is more than one
void ff_thread_flush(AVCodecContext *avctx)
{
- FrameThreadContext *fctx = avctx->thread_opaque;
int i;
+ FrameThreadContext *fctx = avctx->thread_opaque;
if (!avctx->thread_opaque) return;
}
}
-static int *allocate_progress(PerThreadContext *p)
+static volatile int *allocate_progress(PerThreadContext *p)
{
int i;
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
{
PerThreadContext *p = avctx->thread_opaque;
- int *progress, err;
+ int err;
+ volatile int *progress;
f->owner = avctx;
}
pthread_mutex_lock(&p->parent->buffer_mutex);
- f->thread_opaque = progress = allocate_progress(p);
+ f->thread_opaque = (int*)(progress = allocate_progress(p));
if (!progress) {
pthread_mutex_unlock(&p->parent->buffer_mutex);
avctx->get_buffer == avcodec_default_get_buffer) {
err = avctx->get_buffer(avctx, f);
} else {
+ pthread_mutex_lock(&p->progress_mutex);
p->requested_frame = f;
p->state = STATE_GET_BUFFER;
- pthread_mutex_lock(&p->progress_mutex);
pthread_cond_broadcast(&p->progress_cond);
while (p->state != STATE_SETTING_UP)
avctx->thread_count = 1;
avctx->active_thread_type = 0;
}
+
+ if (avctx->thread_count > MAX_AUTO_THREADS)
+ av_log(avctx, AV_LOG_WARNING,
+ "Application has requested %d threads. Using a thread count greater than %d is not recommended.\n",
+ avctx->thread_count, MAX_AUTO_THREADS);
}
int ff_thread_init(AVCodecContext *avctx)