|
|
@ -763,52 +763,12 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) |
|
|
|
avctx->codec = NULL; |
|
|
|
avctx->codec = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int ff_frame_thread_init(AVCodecContext *avctx) |
|
|
|
static av_cold int init_thread(PerThreadContext *p, |
|
|
|
|
|
|
|
FrameThreadContext *fctx, AVCodecContext *avctx, |
|
|
|
|
|
|
|
AVCodecContext *src, const AVCodec *codec, int first) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int thread_count = avctx->thread_count; |
|
|
|
|
|
|
|
const AVCodec *codec = avctx->codec; |
|
|
|
|
|
|
|
AVCodecContext *src = avctx; |
|
|
|
|
|
|
|
FrameThreadContext *fctx; |
|
|
|
|
|
|
|
int i, err = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!thread_count) { |
|
|
|
|
|
|
|
int nb_cpus = av_cpu_count(); |
|
|
|
|
|
|
|
// 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); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
thread_count = avctx->thread_count = 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (thread_count <= 1) { |
|
|
|
|
|
|
|
avctx->active_thread_type = 0; |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext)); |
|
|
|
|
|
|
|
if (!fctx) |
|
|
|
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); |
|
|
|
|
|
|
|
if (!fctx->threads) { |
|
|
|
|
|
|
|
av_freep(&avctx->internal->thread_ctx); |
|
|
|
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_init(&fctx->buffer_mutex, NULL); |
|
|
|
|
|
|
|
pthread_mutex_init(&fctx->hwaccel_mutex, NULL); |
|
|
|
|
|
|
|
pthread_mutex_init(&fctx->async_mutex, NULL); |
|
|
|
|
|
|
|
pthread_cond_init(&fctx->async_cond, NULL); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fctx->async_lock = 1; |
|
|
|
|
|
|
|
fctx->delaying = 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (codec->type == AVMEDIA_TYPE_VIDEO) |
|
|
|
|
|
|
|
avctx->delay = src->thread_count - 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < thread_count; i++) { |
|
|
|
|
|
|
|
AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); |
|
|
|
AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); |
|
|
|
PerThreadContext *p = &fctx->threads[i]; |
|
|
|
int err; |
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_init(&p->mutex, NULL); |
|
|
|
pthread_mutex_init(&p->mutex, NULL); |
|
|
|
pthread_mutex_init(&p->progress_mutex, NULL); |
|
|
|
pthread_mutex_init(&p->progress_mutex, NULL); |
|
|
@ -819,22 +779,19 @@ int ff_frame_thread_init(AVCodecContext *avctx) |
|
|
|
p->frame = av_frame_alloc(); |
|
|
|
p->frame = av_frame_alloc(); |
|
|
|
if (!p->frame) { |
|
|
|
if (!p->frame) { |
|
|
|
av_freep(©); |
|
|
|
av_freep(©); |
|
|
|
err = AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
goto error; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
p->avpkt = av_packet_alloc(); |
|
|
|
p->avpkt = av_packet_alloc(); |
|
|
|
if (!p->avpkt) { |
|
|
|
if (!p->avpkt) { |
|
|
|
av_freep(©); |
|
|
|
av_freep(©); |
|
|
|
err = AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
goto error; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
p->parent = fctx; |
|
|
|
p->parent = fctx; |
|
|
|
p->avctx = copy; |
|
|
|
p->avctx = copy; |
|
|
|
|
|
|
|
|
|
|
|
if (!copy) { |
|
|
|
if (!copy) { |
|
|
|
err = AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
goto error; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
*copy = *src; |
|
|
|
*copy = *src; |
|
|
@ -842,8 +799,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) |
|
|
|
copy->internal = av_malloc(sizeof(AVCodecInternal)); |
|
|
|
copy->internal = av_malloc(sizeof(AVCodecInternal)); |
|
|
|
if (!copy->internal) { |
|
|
|
if (!copy->internal) { |
|
|
|
copy->priv_data = NULL; |
|
|
|
copy->priv_data = NULL; |
|
|
|
err = AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
goto error; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
*copy->internal = *src->internal; |
|
|
|
*copy->internal = *src->internal; |
|
|
|
copy->internal->thread_ctx = p; |
|
|
|
copy->internal->thread_ctx = p; |
|
|
@ -854,27 +810,27 @@ int ff_frame_thread_init(AVCodecContext *avctx) |
|
|
|
if (codec->priv_data_size) { |
|
|
|
if (codec->priv_data_size) { |
|
|
|
copy->priv_data = av_mallocz(codec->priv_data_size); |
|
|
|
copy->priv_data = av_mallocz(codec->priv_data_size); |
|
|
|
if (!copy->priv_data) { |
|
|
|
if (!copy->priv_data) { |
|
|
|
err = AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
goto error; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (codec->priv_class) { |
|
|
|
if (codec->priv_class) { |
|
|
|
*(const AVClass **)copy->priv_data = codec->priv_class; |
|
|
|
*(const AVClass **)copy->priv_data = codec->priv_class; |
|
|
|
err = av_opt_copy(copy->priv_data, src->priv_data); |
|
|
|
err = av_opt_copy(copy->priv_data, src->priv_data); |
|
|
|
if (err < 0) |
|
|
|
if (err < 0) |
|
|
|
goto error; |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (i) |
|
|
|
if (!first) |
|
|
|
copy->internal->is_copy = 1; |
|
|
|
copy->internal->is_copy = 1; |
|
|
|
|
|
|
|
|
|
|
|
if (codec->init) |
|
|
|
if (codec->init) |
|
|
|
err = codec->init(copy); |
|
|
|
err = codec->init(copy); |
|
|
|
|
|
|
|
if (err < 0) { |
|
|
|
|
|
|
|
return err; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (err) goto error; |
|
|
|
if (first) |
|
|
|
|
|
|
|
|
|
|
|
if (!i) |
|
|
|
|
|
|
|
update_context_from_thread(avctx, copy, 1); |
|
|
|
update_context_from_thread(avctx, copy, 1); |
|
|
|
|
|
|
|
|
|
|
|
atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); |
|
|
|
atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); |
|
|
@ -882,6 +838,59 @@ int ff_frame_thread_init(AVCodecContext *avctx) |
|
|
|
err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); |
|
|
|
err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); |
|
|
|
p->thread_init= !err; |
|
|
|
p->thread_init= !err; |
|
|
|
if(!p->thread_init) |
|
|
|
if(!p->thread_init) |
|
|
|
|
|
|
|
return err; |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int ff_frame_thread_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int thread_count = avctx->thread_count; |
|
|
|
|
|
|
|
const AVCodec *codec = avctx->codec; |
|
|
|
|
|
|
|
AVCodecContext *src = avctx; |
|
|
|
|
|
|
|
FrameThreadContext *fctx; |
|
|
|
|
|
|
|
int i, err = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!thread_count) { |
|
|
|
|
|
|
|
int nb_cpus = av_cpu_count(); |
|
|
|
|
|
|
|
// 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); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
thread_count = avctx->thread_count = 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (thread_count <= 1) { |
|
|
|
|
|
|
|
avctx->active_thread_type = 0; |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext)); |
|
|
|
|
|
|
|
if (!fctx) |
|
|
|
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); |
|
|
|
|
|
|
|
if (!fctx->threads) { |
|
|
|
|
|
|
|
av_freep(&avctx->internal->thread_ctx); |
|
|
|
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_init(&fctx->buffer_mutex, NULL); |
|
|
|
|
|
|
|
pthread_mutex_init(&fctx->hwaccel_mutex, NULL); |
|
|
|
|
|
|
|
pthread_mutex_init(&fctx->async_mutex, NULL); |
|
|
|
|
|
|
|
pthread_cond_init(&fctx->async_cond, NULL); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fctx->async_lock = 1; |
|
|
|
|
|
|
|
fctx->delaying = 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (codec->type == AVMEDIA_TYPE_VIDEO) |
|
|
|
|
|
|
|
avctx->delay = src->thread_count - 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < thread_count; i++) { |
|
|
|
|
|
|
|
PerThreadContext *p = &fctx->threads[i]; |
|
|
|
|
|
|
|
int first = !i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = init_thread(p, fctx, avctx, src, codec, first); |
|
|
|
|
|
|
|
if (err < 0) |
|
|
|
goto error; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|