diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2016-08-07 23:37:17 +0200 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2016-08-08 00:27:43 +0200 |
commit | 74314f1f5f9ef69700eb18b85a8260e2754a31ef (patch) | |
tree | 097e9b61add9b11061b63f17dea74c21d8061ff5 /libavcodec/ffv1enc.c | |
parent | 22d13e4290c8fdba57485e1b501f6a92283a10db (diff) | |
download | ffmpeg-74314f1f5f9ef69700eb18b85a8260e2754a31ef.tar.gz |
avcodec/ffv1: template functions to allow data types different from int16_t
This is required for >= 16bit RGB support
I tried it without templates but its too much duplicated code
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec/ffv1enc.c')
-rw-r--r-- | libavcodec/ffv1enc.c | 167 |
1 files changed, 5 insertions, 162 deletions
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 383956bcc9..552f653846 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -268,107 +268,12 @@ static inline void put_vlc_symbol(PutBitContext *pb, VlcState *const state, update_vlc_state(state, v); } -static av_always_inline int encode_line(FFV1Context *s, int w, - int16_t *sample[3], - int plane_index, int bits) -{ - PlaneContext *const p = &s->plane[plane_index]; - RangeCoder *const c = &s->c; - int x; - int run_index = s->run_index; - int run_count = 0; - int run_mode = 0; - - if (s->ac != AC_GOLOMB_RICE) { - if (c->bytestream_end - c->bytestream < w * 35) { - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return AVERROR_INVALIDDATA; - } - } else { - if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) < w * 4) { - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return AVERROR_INVALIDDATA; - } - } - - if (s->slice_coding_mode == 1) { - for (x = 0; x < w; x++) { - int i; - int v = sample[0][x]; - for (i = bits-1; i>=0; i--) { - uint8_t state = 128; - put_rac(c, &state, (v>>i) & 1); - } - } - return 0; - } - - for (x = 0; x < w; x++) { - int diff, context; - - context = get_context(p, sample[0] + x, sample[1] + x, sample[2] + x); - diff = sample[0][x] - predict(sample[0] + x, sample[1] + x); - - if (context < 0) { - context = -context; - diff = -diff; - } - - diff = fold(diff, bits); - - if (s->ac != AC_GOLOMB_RICE) { - if (s->flags & AV_CODEC_FLAG_PASS1) { - put_symbol_inline(c, p->state[context], diff, 1, s->rc_stat, - s->rc_stat2[p->quant_table_index][context]); - } else { - put_symbol_inline(c, p->state[context], diff, 1, NULL, NULL); - } - } else { - if (context == 0) - run_mode = 1; - - if (run_mode) { - if (diff) { - while (run_count >= 1 << ff_log2_run[run_index]) { - run_count -= 1 << ff_log2_run[run_index]; - run_index++; - put_bits(&s->pb, 1, 1); - } - - put_bits(&s->pb, 1 + ff_log2_run[run_index], run_count); - if (run_index) - run_index--; - run_count = 0; - run_mode = 0; - if (diff > 0) - diff--; - } else { - run_count++; - } - } - - ff_dlog(s->avctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n", - run_count, run_index, run_mode, x, - (int)put_bits_count(&s->pb)); - - if (run_mode == 0) - put_vlc_symbol(&s->pb, &p->vlc_state[context], diff, bits); - } - } - if (run_mode) { - while (run_count >= 1 << ff_log2_run[run_index]) { - run_count -= 1 << ff_log2_run[run_index]; - run_index++; - put_bits(&s->pb, 1, 1); - } +#define TYPE int16_t +#define RENAME(name) name +#include "ffv1enc_template.c" +#undef TYPE +#undef RENAME - if (run_count) - put_bits(&s->pb, 1, 1); - } - s->run_index = run_index; - - return 0; -} static int encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index, int pixel_stride) @@ -410,68 +315,6 @@ static int encode_plane(FFV1Context *s, uint8_t *src, int w, int h, return 0; } -static int encode_rgb_frame(FFV1Context *s, const uint8_t *src[3], - int w, int h, const int stride[3]) -{ - int x, y, p, i; - const int ring_size = s->context_model ? 3 : 2; - int16_t *sample[4][3]; - int lbd = s->bits_per_raw_sample <= 8; - int bits = s->bits_per_raw_sample > 0 ? s->bits_per_raw_sample : 8; - int offset = 1 << bits; - - s->run_index = 0; - - memset(s->sample_buffer, 0, ring_size * MAX_PLANES * - (w + 6) * sizeof(*s->sample_buffer)); - - for (y = 0; y < h; y++) { - for (i = 0; i < ring_size; i++) - for (p = 0; p < MAX_PLANES; p++) - sample[p][i]= s->sample_buffer + p*ring_size*(w+6) + ((h+i-y)%ring_size)*(w+6) + 3; - - for (x = 0; x < w; x++) { - int b, g, r, av_uninit(a); - if (lbd) { - unsigned v = *((const uint32_t*)(src[0] + x*4 + stride[0]*y)); - b = v & 0xFF; - g = (v >> 8) & 0xFF; - r = (v >> 16) & 0xFF; - a = v >> 24; - } else { - b = *((const uint16_t *)(src[0] + x*2 + stride[0]*y)); - g = *((const uint16_t *)(src[1] + x*2 + stride[1]*y)); - r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y)); - } - - if (s->slice_coding_mode != 1) { - b -= g; - r -= g; - g += (b * s->slice_rct_by_coef + r * s->slice_rct_ry_coef) >> 2; - b += offset; - r += offset; - } - - sample[0][0][x] = g; - sample[1][0][x] = b; - sample[2][0][x] = r; - sample[3][0][x] = a; - } - for (p = 0; p < 3 + s->transparency; p++) { - int ret; - sample[p][0][-1] = sample[p][1][0 ]; - sample[p][1][ w] = sample[p][1][w-1]; - if (lbd && s->slice_coding_mode == 0) - ret = encode_line(s, w, sample[p], (p + 1) / 2, 9); - else - ret = encode_line(s, w, sample[p], (p + 1) / 2, bits + (s->slice_coding_mode != 1)); - if (ret < 0) - return ret; - } - } - return 0; -} - static void write_quant_table(RangeCoder *c, int16_t *quant_table) { int last = 0; |