Skip to content
Snippets Groups Projects
Commit 0f13cd31 authored by Luca Barbato's avatar Luca Barbato
Browse files

ffv1: update to ffv1 version 3

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