Commit 0f13cd31 authored by Luca Barbato's avatar Luca Barbato

ffv1: update to ffv1 version 3

Based on code from Carl Eugen Hoyos, Michael Niedermayer and Paul B Mahol.
parent 4a2a4524
......@@ -138,12 +138,16 @@ int ffv1_common_init(AVCodecContext *avctx)
s->avctx = avctx;
s->flags = avctx->flags;
if (!avctx->width || !avctx->height)
return AVERROR_INVALIDDATA;
avcodec_get_frame_defaults(&s->picture);
ff_dsputil_init(&s->dsp, avctx);
s->width = avctx->width;
s->height = avctx->height;
assert(s->width && s->height);
// defaults
s->num_h_slices = 1;
s->num_v_slices = 1;
......@@ -151,35 +155,34 @@ int ffv1_common_init(AVCodecContext *avctx)
return 0;
}
int ffv1_init_slice_state(FFV1Context *f)
int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs)
{
int i, j;
for (i = 0; i < f->slice_count; i++) {
FFV1Context *fs = f->slice_context[i];
for (j = 0; j < f->plane_count; j++) {
PlaneContext *const p = &fs->plane[j];
if (fs->ac) {
if (!p->state)
p->state = av_malloc(CONTEXT_SIZE * p->context_count *
sizeof(uint8_t));
if (!p->state)
return AVERROR(ENOMEM);
} else {
if (!p->vlc_state)
p->vlc_state = av_malloc(p->context_count * sizeof(VlcState));
if (!p->vlc_state)
return AVERROR(ENOMEM);
}
int j;
fs->plane_count = f->plane_count;
fs->transparency = f->transparency;
for (j = 0; j < f->plane_count; j++) {
PlaneContext *const p = &fs->plane[j];
if (fs->ac) {
if (!p->state)
p->state = av_malloc(CONTEXT_SIZE * p->context_count *
sizeof(uint8_t));
if (!p->state)
return AVERROR(ENOMEM);
} else {
if (!p->vlc_state)
p->vlc_state = av_malloc(p->context_count * sizeof(VlcState));
if (!p->vlc_state)
return AVERROR(ENOMEM);
}
}
if (fs->ac > 1) {
// FIXME: only redo if state_transition changed
for (j = 1; j < 256; j++) {
fs->c.one_state[j] = fs->state_transition[j];
fs->c.zero_state[256 - j] = 256 - fs->c.one_state[j];
}
if (fs->ac > 1) {
//FIXME only redo if state_transition changed
for (j = 1; j < 256; j++) {
fs->c.one_state[j] = f->state_transition[j];
fs->c.zero_state[256 - j] = 256 - fs->c.one_state[j];
}
}
......@@ -209,7 +212,7 @@ av_cold int ffv1_init_slice_contexts(FFV1Context *f)
fs->slice_x = sxs;
fs->slice_y = sys;
fs->sample_buffer = av_malloc(9 * (fs->width + 6) *
fs->sample_buffer = av_malloc(3 * MAX_PLANES * (fs->width + 6) *
sizeof(*fs->sample_buffer));
if (!fs->sample_buffer)
return AVERROR(ENOMEM);
......@@ -232,31 +235,28 @@ int ffv1_allocate_initial_states(FFV1Context *f)
return 0;
}
void ffv1_clear_state(FFV1Context *f)
void ffv1_clear_slice_state(FFV1Context *f, FFV1Context *fs)
{
int i, si, j;
for (si = 0; si < f->slice_count; si++) {
FFV1Context *fs = f->slice_context[si];
for (i = 0; i < f->plane_count; i++) {
PlaneContext *p = &fs->plane[i];
int i, j;
p->interlace_bit_state[0] = 128;
p->interlace_bit_state[1] = 128;
if (fs->ac) {
if (f->initial_states[p->quant_table_index]) {
memcpy(p->state, f->initial_states[p->quant_table_index],
CONTEXT_SIZE * p->context_count);
} else
memset(p->state, 128, CONTEXT_SIZE * p->context_count);
} else {
for (j = 0; j < p->context_count; j++) {
p->vlc_state[j].drift = 0;
p->vlc_state[j].error_sum = 4; // FFMAX((RANGE + 32)/64, 2);
p->vlc_state[j].bias = 0;
p->vlc_state[j].count = 1;
}
for (i = 0; i < f->plane_count; i++) {
PlaneContext *p = &fs->plane[i];
p->interlace_bit_state[0] = 128;
p->interlace_bit_state[1] = 128;
if (fs->ac) {
if (f->initial_states[p->quant_table_index]) {
memcpy(p->state, f->initial_states[p->quant_table_index],
CONTEXT_SIZE * p->context_count);
} else
memset(p->state, 128, CONTEXT_SIZE * p->context_count);
} else {
for (j = 0; j < p->context_count; j++) {
p->vlc_state[j].drift = 0;
p->vlc_state[j].error_sum = 4; //FFMAX((RANGE + 32)/64, 2);
p->vlc_state[j].bias = 0;
p->vlc_state[j].count = 1;
}
}
}
......@@ -269,6 +269,8 @@ av_cold int ffv1_close(AVCodecContext *avctx)
if (avctx->codec->decode && s->picture.data[0])
avctx->release_buffer(avctx, &s->picture);
if (avctx->codec->decode && s->last_picture.data[0])
avctx->release_buffer(avctx, &s->last_picture);
for (j = 0; j < s->slice_count; j++) {
FFV1Context *fs = s->slice_context[j];
......
/*
* FFV1 codec for libavcodec
*
* Copyright (c) 2012 Michael Niedermayer <michaelni@gmx.at>
* Copyright (c) 2003-2012 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of Libav.
*
......@@ -57,6 +57,7 @@ typedef struct PlaneContext {
#define MAX_SLICES 256
typedef struct FFV1Context {
AVClass *class;
AVCodecContext *avctx;
RangeCoder c;
GetBitContext gb;
......@@ -64,13 +65,17 @@ typedef struct FFV1Context {
uint64_t rc_stat[256][2];
uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2];
int version;
int minor_version;
int width, height;
int chroma_planes;
int chroma_h_shift, chroma_v_shift;
int transparency;
int flags;
int picture_number;
AVFrame picture;
AVFrame picture, last_picture;
int plane_count;
int ac; // 1 = range coder <-> 0 = golomb rice
int ac_byte_count; // number of bytes used for AC coding
PlaneContext plane[MAX_PLANES];
int16_t quant_table[MAX_CONTEXT_INPUTS][256];
int16_t quant_tables[MAX_QUANT_TABLES][MAX_CONTEXT_INPUTS][256];
......@@ -80,8 +85,15 @@ typedef struct FFV1Context {
int run_index;
int colorspace;
int16_t *sample_buffer;
int gob_count;
int ec;
int slice_damaged;
int key_frame_ok;
int bits_per_raw_sample;
int packed_at_lsb;
int gob_count;
int quant_table_count;
DSPContext dsp;
......@@ -175,10 +187,10 @@ static inline void update_vlc_state(VlcState *const state, const int v)
}
int ffv1_common_init(AVCodecContext *avctx);
int ffv1_init_slice_state(FFV1Context *f);
int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs);
int ffv1_init_slice_contexts(FFV1Context *f);
int ffv1_allocate_initial_states(FFV1Context *f);
void ffv1_clear_state(FFV1Context *f);
void ffv1_clear_slice_state(FFV1Context *f, FFV1Context *fs);
int ffv1_close(AVCodecContext *avctx);
#endif /* AVCODEC_FFV1_H */
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment