#include "avcodec.h"
#include "internal.h"
#include "get_bits.h"
-#include "put_bits.h"
#include "rangecoder.h"
#include "golomb.h"
#include "mathops.h"
#include "ffv1.h"
+#include "thread.h"
static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state,
int is_signed)
if (f->version > 2) {
f->ec = get_symbol(c, state, 0);
+ if (f->minor_version > 2)
+ f->intra = get_symbol(c, state, 0);
}
if (f->version > 2) {
int buf_size = avpkt->size;
FFV1Context *f = avctx->priv_data;
RangeCoder *const c = &f->slice_context[0]->c;
+ ThreadFrame frame = { .f = data };
int i, ret;
uint8_t keystate = 128;
const uint8_t *buf_p;
AVFrame *const p = data;
f->cur = p;
+ f->avctx = avctx;
ff_init_range_decoder(c, buf, buf_size);
ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
p->key_frame = 0;
}
- if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0)
+ if ((ret = ff_thread_get_buffer(avctx, &frame, AV_GET_BUFFER_FLAG_REF)) < 0)
return ret;
if (avctx->debug & FF_DEBUG_PICT_INFO)
} else
fs->c.bytestream_end = (uint8_t *)(buf_p + v);
+ fs->avctx = avctx;
fs->cur = p;
}
return buf_size;
}
+static int init_thread_copy(AVCodecContext *avctx)
+{
+ FFV1Context *f = avctx->priv_data;
+ int ret, i;
+
+ for (i = 0; i < f->quant_table_count; i++) {
+ void *p = f->initial_states[i];
+ f->initial_states[i] = av_malloc(f->context_count[i] * sizeof(*f->initial_states[i]));
+ if (!f->initial_states[i])
+ return AVERROR(ENOMEM);
+ memcpy(f->initial_states[i], p, f->context_count[i] * sizeof(*f->initial_states[i]));
+ }
+
+ if ((ret = ffv1_init_slice_contexts(f)) < 0)
+ return ret;
+ return 0;
+}
+
AVCodec ff_ffv1_decoder = {
.name = "ffv1",
.type = AVMEDIA_TYPE_VIDEO,
.init = decode_init,
.close = ffv1_close,
.decode = decode_frame,
+ .init_thread_copy = init_thread_copy,
.capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ |
CODEC_CAP_SLICE_THREADS,
.long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),