mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
ffv1dec: add code to support frame threading with gop=1 ffv1
CODEC_CAP_FRAME_THREADS is not added yet because that would unconditionally enable it, breaking gop>1 files. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
1a392fc550
commit
ff0b4c08ca
@ -38,6 +38,7 @@
|
|||||||
#include "golomb.h"
|
#include "golomb.h"
|
||||||
#include "mathops.h"
|
#include "mathops.h"
|
||||||
#include "ffv1.h"
|
#include "ffv1.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state,
|
static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state,
|
||||||
int is_signed)
|
int is_signed)
|
||||||
@ -733,12 +734,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
|
|||||||
int buf_size = avpkt->size;
|
int buf_size = avpkt->size;
|
||||||
FFV1Context *f = avctx->priv_data;
|
FFV1Context *f = avctx->priv_data;
|
||||||
RangeCoder *const c = &f->slice_context[0]->c;
|
RangeCoder *const c = &f->slice_context[0]->c;
|
||||||
|
ThreadFrame frame = { .f = data };
|
||||||
int i, ret;
|
int i, ret;
|
||||||
uint8_t keystate = 128;
|
uint8_t keystate = 128;
|
||||||
const uint8_t *buf_p;
|
const uint8_t *buf_p;
|
||||||
AVFrame *const p = data;
|
AVFrame *const p = data;
|
||||||
|
|
||||||
f->cur = p;
|
f->cur = p;
|
||||||
|
f->avctx = avctx;
|
||||||
|
|
||||||
ff_init_range_decoder(c, buf, buf_size);
|
ff_init_range_decoder(c, buf, buf_size);
|
||||||
ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
|
ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
|
||||||
@ -759,8 +762,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
|
|||||||
p->key_frame = 0;
|
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) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed.\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (avctx->debug & FF_DEBUG_PICT_INFO)
|
if (avctx->debug & FF_DEBUG_PICT_INFO)
|
||||||
av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n",
|
av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n",
|
||||||
@ -801,6 +806,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
|
|||||||
} else
|
} else
|
||||||
fs->c.bytestream_end = (uint8_t *)(buf_p + v);
|
fs->c.bytestream_end = (uint8_t *)(buf_p + v);
|
||||||
|
|
||||||
|
fs->avctx = avctx;
|
||||||
fs->cur = p;
|
fs->cur = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -845,6 +851,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
|
|||||||
return buf_size;
|
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 = {
|
AVCodec ff_ffv1_decoder = {
|
||||||
.name = "ffv1",
|
.name = "ffv1",
|
||||||
.type = AVMEDIA_TYPE_VIDEO,
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
@ -853,6 +877,7 @@ AVCodec ff_ffv1_decoder = {
|
|||||||
.init = decode_init,
|
.init = decode_init,
|
||||||
.close = ffv1_close,
|
.close = ffv1_close,
|
||||||
.decode = decode_frame,
|
.decode = decode_frame,
|
||||||
|
.init_thread_copy = init_thread_copy,
|
||||||
.capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ |
|
.capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ |
|
||||||
CODEC_CAP_SLICE_THREADS,
|
CODEC_CAP_SLICE_THREADS,
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
|
.long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
|
||||||
|
Loading…
Reference in New Issue
Block a user