The current design, where
- proper init is called for the first per-thread context
- first thread's private data is copied into private data for all the
other threads
- a "fixup" function is called for all the other threads to e.g.
allocate dynamically allocated data
is very fragile and hard to follow, so it is removed. Instead a single
function is used to init all the per-thread contexts. Where necessary,
AVCodecInternal.is_copy can be used to differentiate between the first
thread and the other ones (e.g. for decoding the extradata just once).
---
doc/multithreading.txt | 3 ---
libavcodec/aic.c | 1 -
libavcodec/avcodec.h | 6 ------
libavcodec/exr.c | 12 ------------
libavcodec/h264dec.c | 38 ++++++++++----------------------------
libavcodec/hevcdec.c | 27 +++++++--------------------
libavcodec/huffyuvdec.c | 25 -------------------------
libavcodec/magicyuv.c | 16 ----------------
libavcodec/mdec.c | 10 ----------
libavcodec/mimic.c | 20 +-------------------
libavcodec/pthread_frame.c | 17 +++++++----------
libavcodec/rv30.c | 1 -
libavcodec/rv34.c | 21 ---------------------
libavcodec/rv34.h | 1 -
libavcodec/rv40.c | 1 -
libavcodec/vp3.c | 37 -------------------------------------
libavcodec/vp8.c | 16 ----------------
libavcodec/vp9.c | 1 -
18 files changed, 25 insertions(+), 228 deletions(-)
diff --git a/doc/multithreading.txt b/doc/multithreading.txt
index df9cd4e..17e0428 100644
--- a/doc/multithreading.txt
+++ b/doc/multithreading.txt
@@ -51,9 +51,6 @@ the decode process starts. Call ff_thread_finish_setup()
afterwards. If
some code can't be moved, have update_thread_context() run it in the next
thread.
-If the codec allocates writable tables in its init(), add an init_thread_copy()
-which re-allocates them for other threads.
-
Add CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very
little
speed gain at this point but it should work.
diff --git a/libavcodec/aic.c b/libavcodec/aic.c
index 2c9b6f8..d217e65 100644
--- a/libavcodec/aic.c
+++ b/libavcodec/aic.c
@@ -487,5 +487,4 @@ AVCodec ff_aic_decoder = {
.close = aic_decode_close,
.decode = aic_decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(aic_decode_init),
};
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 95da50b..05f2212 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3174,12 +3174,6 @@ typedef struct AVCodec {
* @{
*/
/**
- * If defined, called on thread contexts when they are created.
- * If the codec allocates writable tables in init(), re-allocate them here.
- * priv_data will be set to a copy of the original.
- */
- int (*init_thread_copy)(AVCodecContext *);
- /**
* Copy necessary context variables from a previous thread context to the
current one.
* If not defined, the next thread will start automatically; otherwise,
the codec
* must call ff_thread_finish_setup().
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 28cee84..dc1d0d5 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -1389,17 +1389,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
return 0;
}
-static int decode_init_thread_copy(AVCodecContext *avctx)
-{ EXRContext *s = avctx->priv_data;
-
- // allocate thread data, used for non EXR_RAW compression types
- s->thread_data = av_mallocz_array(avctx->thread_count,
sizeof(EXRThreadData));
- if (!s->thread_data)
- return AVERROR_INVALIDDATA;
-
- return 0;
-}
-
static av_cold int decode_end(AVCodecContext *avctx)
{
EXRContext *s = avctx->priv_data;
@@ -1442,7 +1431,6 @@ AVCodec ff_exr_decoder = {
.id = AV_CODEC_ID_EXR,
.priv_data_size = sizeof(EXRContext),
.init = decode_init,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.close = decode_end,
.decode = decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index ac831a0..7ee4111 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -380,14 +380,16 @@ static av_cold int h264_decode_init(AVCodecContext *avctx)
h->avctx->framerate.num *= 2;
avctx->ticks_per_frame = 2;
- if (avctx->extradata_size > 0 && avctx->extradata) {
- ret = ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size,
- &h->ps, &h->is_avc, &h->nal_length_size,
- avctx->err_recognition, avctx);
- if (ret < 0) {
- h264_decode_end(avctx);
- return ret;
- }
+ if (!avctx->internal->is_copy) {
+ if (avctx->extradata_size > 0 && avctx->extradata) {
+ ret = ff_h264_decode_extradata(avctx->extradata,
avctx->extradata_size,
+ &h->ps, &h->is_avc,
&h->nal_length_size,
+ avctx->err_recognition, avctx);
+ if (ret < 0) {
+ h264_decode_end(avctx);
+ return ret;
+ }
+ }
}
if (h->ps.sps && h->ps.sps->bitstream_restriction_flag &&
@@ -404,25 +406,6 @@ static av_cold int h264_decode_init(AVCodecContext *avctx)
return 0;
}
-static int decode_init_thread_copy(AVCodecContext *avctx)
-{
- H264Context *h = avctx->priv_data;
- int ret;
-
- if (!avctx->internal->is_copy)
- return 0;
-
- memset(h, 0, sizeof(*h));
-
- ret = h264_init_context(avctx, h);
- if (ret < 0)
- return ret;
-
- h->context_initialized = 0;
-
- return 0;
-}
-
/**
* instantaneous decoder refresh.
*/
@@ -801,7 +784,6 @@ AVCodec ff_h264_decoder = {
AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
FF_CODEC_CAP_ALLOCATE_PROGRESS,
.flush = flush_dpb,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.update_thread_context =
ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
.profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles),
.priv_class = &h264_class,
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index bb144ac..cbd6a9d 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -3026,31 +3026,19 @@ static av_cold int hevc_decode_init(AVCodecContext
*avctx)
if (ret < 0)
return ret;
- if (avctx->extradata_size > 0 && avctx->extradata) {
- ret = hevc_decode_extradata(s, avctx->extradata,
avctx->extradata_size);
- if (ret < 0) {
- hevc_decode_free(avctx);
- return ret;
+ if (!avctx->internal->is_copy) {
+ if (avctx->extradata_size > 0 && avctx->extradata) {
+ ret = hevc_decode_extradata(s, avctx->extradata,
avctx->extradata_size);
+ if (ret < 0) {
+ hevc_decode_free(avctx);
+ return ret;
+ }
}
}
return 0;
}
-static av_cold int hevc_init_thread_copy(AVCodecContext *avctx)
-{
- HEVCContext *s = avctx->priv_data;
- int ret;
-
- memset(s, 0, sizeof(*s));
-
- ret = hevc_init_context(avctx);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
static void hevc_decode_flush(AVCodecContext *avctx)
{
HEVCContext *s = avctx->priv_data;
@@ -3086,7 +3074,6 @@ AVCodec ff_hevc_decoder = {
.decode = hevc_decode_frame,
.flush = hevc_decode_flush,
.update_thread_context = hevc_update_thread_context,
- .init_thread_copy = hevc_init_thread_copy,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c
index 12eca26..6875f36 100644
--- a/libavcodec/huffyuvdec.c
+++ b/libavcodec/huffyuvdec.c
@@ -354,29 +354,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
return 0;
}
-static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
-{
- HYuvContext *s = avctx->priv_data;
- int i, ret;
-
- if ((ret = ff_huffyuv_alloc_temp(s)) < 0)
- return ret;
-
- for (i = 0; i < 6; i++)
- s->vlc[i].table = NULL;
-
- if (s->version == 2) {
- if ((ret = read_huffman_tables(s, avctx->extradata + 4,
- avctx->extradata_size)) < 0)
- return ret;
- } else {
- if ((ret = read_old_huffman_tables(s)) < 0)
- return ret;
- }
-
- return 0;
-}
-
/* TODO instead of restarting the read when the code isn't in the first level
* of the joint table, jump into the 2nd level of the individual table. */
#define READ_2PIX(dst0, dst1, plane1) \
@@ -794,7 +771,6 @@ AVCodec ff_huffyuv_decoder = {
.decode = decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
AV_CODEC_CAP_FRAME_THREADS,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
};
#if CONFIG_FFVHUFF_DECODER
@@ -809,6 +785,5 @@ AVCodec ff_ffvhuff_decoder = {
.decode = decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
AV_CODEC_CAP_FRAME_THREADS,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
};
#endif /* CONFIG_FFVHUFF_DECODER */
diff --git a/libavcodec/magicyuv.c b/libavcodec/magicyuv.c
index 310ead4..b5d9ed0 100644
--- a/libavcodec/magicyuv.c
+++ b/libavcodec/magicyuv.c
@@ -427,21 +427,6 @@ static int magy_decode_frame(AVCodecContext *avctx, void
*data,
return avpkt->size;
}
-#if HAVE_THREADS
-static int magy_init_thread_copy(AVCodecContext *avctx)
-{
- MagicYUVContext *s = avctx->priv_data;
- int i;
-
- for (i = 0; i < FF_ARRAY_ELEMS(s->slices); i++) {
- s->slices[i] = NULL;
- s->slices_size[i] = 0;
- }
-
- return 0;
-}
-#endif
-
static av_cold int magy_decode_init(AVCodecContext *avctx)
{
MagicYUVContext *s = avctx->priv_data;
@@ -470,7 +455,6 @@ AVCodec ff_magicyuv_decoder = {
.id = AV_CODEC_ID_MAGICYUV,
.priv_data_size = sizeof(MagicYUVContext),
.init = magy_decode_init,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(magy_init_thread_copy),
.close = magy_decode_end,
.decode = magy_decode_frame,
.capabilities = AV_CODEC_CAP_DR1 |
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index 4b6056e..6c342ce 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -234,15 +234,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
return 0;
}
-static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
-{
- MDECContext * const a = avctx->priv_data;
-
- a->avctx = avctx;
-
- return 0;
-}
-
static av_cold int decode_end(AVCodecContext *avctx)
{
MDECContext * const a = avctx->priv_data;
@@ -263,5 +254,4 @@ AVCodec ff_mdec_decoder = {
.close = decode_end,
.decode = decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy)
};
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 460debc..fe38844 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -127,8 +127,7 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx)
av_frame_free(&ctx->frames[i].f);
}
- if (!avctx->internal->is_copy)
- ff_free_vlc(&ctx->vlc);
+ ff_free_vlc(&ctx->vlc);
return 0;
}
@@ -446,22 +445,6 @@ static int mimic_decode_frame(AVCodecContext *avctx, void
*data,
return buf_size;
}
-static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
-{
- MimicContext *ctx = avctx->priv_data;
- int i;
-
- for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
- ctx->frames[i].f = av_frame_alloc();
- if (!ctx->frames[i].f) {
- mimic_decode_end(avctx);
- return AVERROR(ENOMEM);
- }
- }
-
- return 0;
-}
-
AVCodec ff_mimic_decoder = {
.name = "mimic",
.long_name = NULL_IF_CONFIG_SMALL("Mimic"),
@@ -473,6 +456,5 @@ AVCodec ff_mimic_decoder = {
.decode = mimic_decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
.update_thread_context =
ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
};
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index f511e7b..ed726d4 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -734,27 +734,24 @@ int ff_frame_thread_init(AVCodecContext *avctx)
copy->internal->last_pkt_props = &p->avpkt;
if (!i) {
- src = copy;
-
- if (codec->init)
- err = codec->init(copy);
-
update_context_from_thread(avctx, copy, 1);
} else {
- copy->priv_data = av_malloc(codec->priv_data_size);
+ copy->priv_data = av_mallocz(codec->priv_data_size);
if (!copy->priv_data) {
err = AVERROR(ENOMEM);
goto error;
}
- memcpy(copy->priv_data, src->priv_data, codec->priv_data_size);
copy->internal->is_copy = 1;
-
- if (codec->init_thread_copy)
- err = codec->init_thread_copy(copy);
}
+ if (codec->init)
+ err = codec->init(copy);
+
if (err) goto error;
+ if (!i)
+ update_context_from_thread(avctx, copy, 1);
+
if (!pthread_create(&p->thread, NULL, frame_worker_thread, p))
p->thread_init = 1;
}
diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index f94e884..af84563 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -289,7 +289,6 @@ AVCodec ff_rv30_decoder = {
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE
},
- .init_thread_copy =
ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy),
.update_thread_context =
ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context),
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
};
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index b2ad5d0..f36da2b 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -1514,27 +1514,6 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
return 0;
}
-int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx)
-{
- int err;
- RV34DecContext *r = avctx->priv_data;
-
- r->s.avctx = avctx;
-
- if (avctx->internal->is_copy) {
- r->tmp_b_block_base = NULL;
- ff_mpv_idct_init(&r->s);
- if ((err = ff_mpv_common_init(&r->s)) < 0)
- return err;
- if ((err = rv34_decoder_alloc(r)) < 0) {
- ff_mpv_common_end(&r->s);
- return err;
- }
- }
-
- return 0;
-}
-
int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const
AVCodecContext *src)
{
RV34DecContext *r = dst->priv_data, *r1 = src->priv_data;
diff --git a/libavcodec/rv34.h b/libavcodec/rv34.h
index 0ac24bf..ab8f712 100644
--- a/libavcodec/rv34.h
+++ b/libavcodec/rv34.h
@@ -134,7 +134,6 @@ int ff_rv34_get_start_offset(GetBitContext *gb, int blocks);
int ff_rv34_decode_init(AVCodecContext *avctx);
int ff_rv34_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
AVPacket *avpkt);
int ff_rv34_decode_end(AVCodecContext *avctx);
-int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx);
int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const
AVCodecContext *src);
#endif /* AVCODEC_RV34_H */
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index d02a1ca..7b60e0c 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -578,7 +578,6 @@ AVCodec ff_rv40_decoder = {
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE
},
- .init_thread_copy =
ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy),
.update_thread_context =
ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context),
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
};
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 2f43d22..632da21 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -293,9 +293,6 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
av_frame_free(&s->last_frame.f);
av_frame_free(&s->golden_frame.f);
- if (avctx->internal->is_copy)
- return 0;
-
for (i = 0; i < 16; i++) {
ff_free_vlc(&s->dc_vlc[i]);
ff_free_vlc(&s->ac_vlc_1[i]);
@@ -1936,21 +1933,6 @@ static int vp3_update_thread_context(AVCodecContext
*dst, const AVCodecContext *
}
if (s != s1) {
- // init tables if the first frame hasn't been decoded
- if (!s->current_frame.f->data[0]) {
- int y_fragment_count, c_fragment_count;
- s->avctx = dst;
- err = allocate_tables(dst);
- if (err)
- return err;
- y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
- c_fragment_count = s->fragment_width[1] * s->fragment_height[1];
- memcpy(s->motion_val[0], s1->motion_val[0],
- y_fragment_count * sizeof(*s->motion_val[0]));
- memcpy(s->motion_val[1], s1->motion_val[1],
- c_fragment_count * sizeof(*s->motion_val[1]));
- }
-
// copy previous frame data
if ((err = ref_frames(s, s1)) < 0)
return err;
@@ -2179,23 +2161,6 @@ static int read_huffman_tree(AVCodecContext *avctx,
GetBitContext *gb)
return 0;
}
-static int vp3_init_thread_copy(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
-
- s->superblock_coding = NULL;
- s->all_fragments = NULL;
- s->coded_fragment_list[0] = NULL;
- s->dct_tokens_base = NULL;
- s->superblock_fragments = NULL;
- s->macroblock_coding = NULL;
- s->motion_val[0] = NULL;
- s->motion_val[1] = NULL;
- s->edge_emu_buffer = NULL;
-
- return init_frames(s);
-}
-
#if CONFIG_THEORA_DECODER
static const enum AVPixelFormat theora_pix_fmts[4] = {
AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P
@@ -2496,7 +2461,6 @@ AVCodec ff_theora_decoder = {
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
AV_CODEC_CAP_FRAME_THREADS,
.flush = vp3_decode_flush,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
.update_thread_context =
ONLY_IF_THREADS_ENABLED(vp3_update_thread_context),
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
};
@@ -2514,7 +2478,6 @@ AVCodec ff_vp3_decoder = {
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
AV_CODEC_CAP_FRAME_THREADS,
.flush = vp3_decode_flush,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
.update_thread_context =
ONLY_IF_THREADS_ENABLED(vp3_update_thread_context),
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
};
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index e97933e..3941e07 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -2771,21 +2771,6 @@ av_cold int ff_vp8_decode_init(AVCodecContext *avctx)
}
#if CONFIG_VP8_DECODER
-static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx)
-{
- VP8Context *s = avctx->priv_data;
- int ret;
-
- s->avctx = avctx;
-
- if ((ret = vp8_init_frames(s)) < 0) {
- ff_vp8_decode_free(avctx);
- return ret;
- }
-
- return 0;
-}
-
#define REBASE(pic) pic ? pic - &s_src->frames[0] + &s->frames[0] : NULL
static int vp8_decode_update_thread_context(AVCodecContext *dst,
@@ -2851,7 +2836,6 @@ AVCodec ff_vp8_decoder = {
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
AV_CODEC_CAP_SLICE_THREADS,
.flush = vp8_decode_flush,
- .init_thread_copy =
ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy),
.update_thread_context =
ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context),
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
};
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 1fb3288..59297f4 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -1543,7 +1543,6 @@ AVCodec ff_vp9_decoder = {
.flush = vp9_decode_flush,
.close = vp9_decode_free,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .init_thread_copy = vp9_decode_init,
.update_thread_context = vp9_decode_update_thread_context,
.bsfs = "vp9_superframe_split",
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS,
--
2.0.0
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel