diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-10-21 14:05:46 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-10-21 14:26:23 +0200 |
commit | e4255eaf47373c0c1691cbcbc0816253e938b662 (patch) | |
tree | 2943cf510ddf31c2adbe5fb2087b9f6830da5fd2 /libavcodec/ffv1.h | |
parent | dcbff35199e1596d9d1200e734ef4a4c306e50f1 (diff) | |
download | ffmpeg-e4255eaf47373c0c1691cbcbc0816253e938b662.tar.gz |
ffv1: split decoder and encoder
This is not based on lucas work due to code divergence (its less work this way
than trying to merge from a split based on 2 years outdated code)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/ffv1.h')
-rw-r--r-- | libavcodec/ffv1.h | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h new file mode 100644 index 0000000000..6c88565be5 --- /dev/null +++ b/libavcodec/ffv1.h @@ -0,0 +1,212 @@ +/* + * FFV1 codec for libavcodec + * + * Copyright (c) 2003-2012 Michael Niedermayer <michaelni@gmx.at> + * + * This file is part of FFmpeg. + * + * FFmpeg 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. + * + * FFmpeg 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 FFmpeg; 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 + +/** + * @file + * FF Video Codec 1 (a lossless codec) + */ + +#include "libavutil/avassert.h" +#include "libavutil/crc.h" +#include "libavutil/opt.h" +#include "libavutil/imgutils.h" +#include "libavutil/pixdesc.h" +#include "libavutil/timer.h" +#include "avcodec.h" +#include "internal.h" +#include "dsputil.h" +#include "rangecoder.h" +#include "golomb.h" +#include "mathops.h" + +#ifdef __INTEL_COMPILER +#undef av_flatten +#define av_flatten +#endif + +#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]; + +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 { + AVClass *class; + 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 minor_version; + int width, height; + int chroma_h_shift, chroma_v_shift; + int chroma_planes; + int transparency; + int flags; + int picture_number; + AVFrame picture; + AVFrame 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]; + 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 packed_at_lsb; + int ec; + int slice_damaged; + int key_frame_ok; + + 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; + int bits_per_raw_sample; +} FFV1Context; + +int ffv1_common_init(AVCodecContext *avctx); +int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs); +int ffv1_init_slices_state(FFV1Context *f); +int ffv1_init_slice_contexts(FFV1Context *f); +int ffv1_allocate_initial_states(FFV1Context *f); +void ffv1_clear_slice_state(FFV1Context *f, FFV1Context *fs); +int ffv1_common_end(AVCodecContext *avctx); + +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; +} + +#endif /* AVCODEC_FFV1_H */ |