From d5f7f1fef157e0f1dccaf6e39b40e8e3a63c3ef0 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 3 Jun 2013 14:43:18 +0000 Subject: audio frame multi-threaded decoding Signed-off-by: Paul B Mahol --- libavcodec/options_table.h | 6 +++--- libavcodec/pthread.c | 8 +++++++- libavcodec/utils.c | 10 +++++++--- libavformat/utils.c | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 4fd6cff0c7..65d4ab494c 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -227,7 +227,7 @@ static const AVOption options[]={ {"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"}, {"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"}, {"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"}, -{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|D, "debug"}, +{"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|A|D, "debug"}, {"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"}, {"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"}, {"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"}, @@ -285,7 +285,7 @@ static const AVOption options[]={ {"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"}, {"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, -{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|E|D, "threads"}, +{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|A|E|D, "threads"}, {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"}, {"me_threshold", "motion estimation threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E}, @@ -357,7 +357,7 @@ static const AVOption options[]={ {"chroma_sample_location", NULL, OFFSET(chroma_sample_location), AV_OPT_TYPE_INT, {.i64 = AVCHROMA_LOC_UNSPECIFIED }, 0, AVCHROMA_LOC_NB-1, V|E|D}, {"log_level_offset", "set the log level offset", OFFSET(log_level_offset), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX }, {"slices", "number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|E}, -{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"}, +{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.i64 = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|A|E|D, "thread_type"}, {"slice", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, {"frame", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"}, {"audio_service_type", "audio service type", OFFSET(audio_service_type), AV_OPT_TYPE_INT, {.i64 = AV_AUDIO_SERVICE_TYPE_MAIN }, 0, AV_AUDIO_SERVICE_TYPE_NB-1, A|E, "audio_service_type"}, diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 7968a61358..7404f870da 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -403,6 +403,11 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, dst->hwaccel = src->hwaccel; dst->hwaccel_context = src->hwaccel_context; + + dst->channels = src->channels; + dst->sample_rate = src->sample_rate; + dst->sample_fmt = src->sample_fmt; + dst->channel_layout = src->channel_layout; } if (for_user) { @@ -477,7 +482,8 @@ static void release_delayed_buffers(PerThreadContext *p) pthread_mutex_lock(&fctx->buffer_mutex); // fix extended data in case the caller screwed it up - av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO); + av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO || + p->avctx->codec_type == AVMEDIA_TYPE_AUDIO); f = &p->released_buffers[--p->num_released_buffers]; f->extended_data = f->data; av_frame_unref(f); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index e0aea28ecd..01e3fbd0dd 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -2075,7 +2075,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, if (!avctx->refcounted_frames) av_frame_unref(&avci->to_free); - if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { + if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { uint8_t *side; int side_size; // copy to ensure we do not change avpkt @@ -2084,11 +2084,15 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, apply_param_change(avctx, &tmp); avctx->pkt = &tmp; - ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp); + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) + ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp); + else { + ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp); + frame->pkt_dts = avpkt->dts; + } if (ret >= 0 && *got_frame_ptr) { add_metadata_from_side_data(avctx, frame); avctx->frame_number++; - frame->pkt_dts = avpkt->dts; av_frame_set_best_effort_timestamp(frame, guess_correct_pts(avctx, frame->pkt_pts, diff --git a/libavformat/utils.c b/libavformat/utils.c index baa717701a..d53e6544ee 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3179,7 +3179,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) find_stream_info_err: for (i=0; i < ic->nb_streams; i++) { st = ic->streams[i]; - if (ic->streams[i]->codec) + if (ic->streams[i]->codec && ic->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO) ic->streams[i]->codec->thread_count = 0; if (st->info) av_freep(&st->info->duration_error); -- cgit v1.2.3