From 71f7b22dba60524b2285643ae0b49d8f64977129 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 19 Oct 2012 10:19:36 +0200 Subject: ffv1: split decoder and encoder --- libavcodec/ffv1.h | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 libavcodec/ffv1.h (limited to 'libavcodec/ffv1.h') diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h new file mode 100644 index 0000000000..7676c61be3 --- /dev/null +++ b/libavcodec/ffv1.h @@ -0,0 +1,184 @@ +/* + * FFV1 codec for libavcodec + * + * Copyright (c) 2012 Michael Niedermayer + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_FFV1_H +#define AVCODEC_FFV1_H +#include "avcodec.h" + +#define MAX_PLANES 4 +#define CONTEXT_SIZE 32 + +#define MAX_QUANT_TABLES 8 +#define MAX_CONTEXT_INPUTS 5 + +extern const uint8_t ff_log2_run[41]; + +extern const int8_t ffv1_quant5_10bit[256]; +extern const int8_t ffv1_quant5[256]; +extern const int8_t ffv1_quant9_10bit[256]; +extern const int8_t ffv1_quant11[256]; +extern const uint8_t ffv1_ver2_state[256]; + +typedef struct VlcState { + int16_t drift; + uint16_t error_sum; + int8_t bias; + uint8_t count; +} VlcState; + +typedef struct PlaneContext { + int16_t quant_table[MAX_CONTEXT_INPUTS][256]; + int quant_table_index; + int context_count; + uint8_t (*state)[CONTEXT_SIZE]; + VlcState *vlc_state; + uint8_t interlace_bit_state[2]; +} PlaneContext; + +#define MAX_SLICES 256 + +typedef struct FFV1Context { + AVCodecContext *avctx; + RangeCoder c; + GetBitContext gb; + PutBitContext pb; + uint64_t rc_stat[256][2]; + uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2]; + int version; + int width, height; + int chroma_h_shift, chroma_v_shift; + int flags; + int picture_number; + AVFrame picture; + int plane_count; + int ac; // 1 = range coder <-> 0 = golomb rice + PlaneContext plane[MAX_PLANES]; + int16_t quant_table[MAX_CONTEXT_INPUTS][256]; + int16_t quant_tables[MAX_QUANT_TABLES][MAX_CONTEXT_INPUTS][256]; + int context_count[MAX_QUANT_TABLES]; + uint8_t state_transition[256]; + uint8_t (*initial_states[MAX_QUANT_TABLES])[32]; + int run_index; + int colorspace; + int16_t *sample_buffer; + int gob_count; + + int quant_table_count; + + DSPContext dsp; + + struct FFV1Context *slice_context[MAX_SLICES]; + int slice_count; + int num_v_slices; + int num_h_slices; + int slice_width; + int slice_height; + int slice_x; + int slice_y; +} FFV1Context; + +static av_always_inline int fold(int diff, int bits) +{ + if (bits == 8) + diff = (int8_t)diff; + else { + diff += 1 << (bits - 1); + diff &= (1 << bits) - 1; + diff -= 1 << (bits - 1); + } + + return diff; +} + +static inline int predict(int16_t *src, int16_t *last) +{ + const int LT = last[-1]; + const int T = last[0]; + const int L = src[-1]; + + return mid_pred(L, L + T - LT, T); +} + +static inline int get_context(PlaneContext *p, int16_t *src, + int16_t *last, int16_t *last2) +{ + const int LT = last[-1]; + const int T = last[0]; + const int RT = last[1]; + const int L = src[-1]; + + if (p->quant_table[3][127]) { + const int TT = last2[0]; + const int LL = src[-2]; + return p->quant_table[0][(L - LT) & 0xFF] + + p->quant_table[1][(LT - T) & 0xFF] + + p->quant_table[2][(T - RT) & 0xFF] + + p->quant_table[3][(LL - L) & 0xFF] + + p->quant_table[4][(TT - T) & 0xFF]; + } else + return p->quant_table[0][(L - LT) & 0xFF] + + p->quant_table[1][(LT - T) & 0xFF] + + p->quant_table[2][(T - RT) & 0xFF]; +} + +static inline void update_vlc_state(VlcState *const state, const int v) +{ + int drift = state->drift; + int count = state->count; + state->error_sum += FFABS(v); + drift += v; + + if (count == 128) { // FIXME: variable + count >>= 1; + drift >>= 1; + state->error_sum >>= 1; + } + count++; + + if (drift <= -count) { + if (state->bias > -128) + state->bias--; + + drift += count; + if (drift <= -count) + drift = -count + 1; + } else if (drift > 0) { + if (state->bias < 127) + state->bias++; + + drift -= count; + if (drift > 0) + drift = 0; + } + + state->drift = drift; + state->count = count; +} + +int ffv1_common_init(AVCodecContext *avctx); +int ffv1_init_slice_state(FFV1Context *f); +int ffv1_init_slice_contexts(FFV1Context *f); +int ffv1_allocate_initial_states(FFV1Context *f); +void ffv1_clear_state(FFV1Context *f); +int ffv1_close(AVCodecContext *avctx); + +#endif /* AVCODEC_FFV1_H */ -- cgit v1.2.3