/*
* FFV1 codec for libavcodec
*
- * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2003-2012 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
static inline void put_vlc_symbol(PutBitContext *pb, VlcState * const state, int v, int bits){
int i, k, code;
-//printf("final: %d ", v);
v = fold(v - state->bias, bits);
i= state->count;
i += i;
}
- assert(k<=8);
+ av_assert2(k<=13);
#if 0 // JPEG LS
if(k==0 && 2*state->drift <= - state->count) code= v ^ (-1);
code= v ^ ((2*state->drift + state->count)>>31);
#endif
-//printf("v:%d/%d bias:%d error:%d drift:%d count:%d k:%d\n", v, code, state->bias, state->error_sum, state->drift, state->count, k);
+ av_dlog(NULL, "v:%d/%d bias:%d error:%d drift:%d count:%d k:%d\n", v, code,
+ state->bias, state->error_sum, state->drift, state->count, k);
set_sr_golomb(pb, code, k, 12, bits);
update_vlc_state(state, v);
assert(k<=8);
v= get_sr_golomb(gb, k, 12, bits);
-//printf("v:%d bias:%d error:%d drift:%d count:%d k:%d", v, state->bias, state->error_sum, state->drift, state->count, k);
+ av_dlog(NULL, "v:%d bias:%d error:%d drift:%d count:%d k:%d",
+ v, state->bias, state->error_sum, state->drift, state->count, k);
#if 0 // JPEG LS
if(k==0 && 2*state->drift <= - state->count) v ^= (-1);
ret= fold(v + state->bias, bits);
update_vlc_state(state, v);
-//printf("final: %d\n", ret);
+
return ret;
}
}
}
-// printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, (int)put_bits_count(&s->pb));
+ av_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);
b += offset;
r += offset;
-// assert(g>=0 && b>=0 && r>=0);
-// assert(g<256 && b<512 && r<512);
sample[0][0][x]= g;
sample[1][0][x]= b;
sample[2][0][x]= r;
static av_cold int common_init(AVCodecContext *avctx){
FFV1Context *s = avctx->priv_data;
+ if(!avctx->width || !avctx->height)
+ return AVERROR_INVALIDDATA;
+
s->avctx= avctx;
s->flags= avctx->flags;
s->width = avctx->width;
s->height= avctx->height;
- assert(s->width && s->height);
//defaults
s->num_h_slices=1;
s->num_v_slices=1;
ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
put_symbol(c, state, f->version, 0);
- if(f->version > 2)
+ if(f->version > 2) {
+ if(f->version == 3)
+ f->minor_version = 2;
put_symbol(c, state, f->minor_version, 0);
+ }
put_symbol(c, state, f->ac, 0);
if(f->ac>1){
for(i=1; i<256; i++){
s->plane_count=3;
switch(avctx->pix_fmt){
- case PIX_FMT_YUV444P9:
- case PIX_FMT_YUV422P9:
- case PIX_FMT_YUV420P9:
+ case AV_PIX_FMT_YUV444P9:
+ case AV_PIX_FMT_YUV422P9:
+ case AV_PIX_FMT_YUV420P9:
if (!avctx->bits_per_raw_sample)
s->bits_per_raw_sample = 9;
- case PIX_FMT_YUV444P10:
- case PIX_FMT_YUV420P10:
- case PIX_FMT_YUV422P10:
+ case AV_PIX_FMT_YUV444P10:
+ case AV_PIX_FMT_YUV420P10:
+ case AV_PIX_FMT_YUV422P10:
s->packed_at_lsb = 1;
if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
s->bits_per_raw_sample = 10;
- case PIX_FMT_GRAY16:
- case PIX_FMT_YUV444P16:
- case PIX_FMT_YUV422P16:
- case PIX_FMT_YUV420P16:
+ case AV_PIX_FMT_GRAY16:
+ case AV_PIX_FMT_YUV444P16:
+ case AV_PIX_FMT_YUV422P16:
+ case AV_PIX_FMT_YUV420P16:
if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) {
s->bits_per_raw_sample = 16;
} else if (!s->bits_per_raw_sample){
return AVERROR_INVALIDDATA;
}
s->version= FFMAX(s->version, 1);
- case PIX_FMT_GRAY8:
- case PIX_FMT_YUV444P:
- case PIX_FMT_YUV440P:
- case PIX_FMT_YUV422P:
- case PIX_FMT_YUV420P:
- case PIX_FMT_YUV411P:
- case PIX_FMT_YUV410P:
+ case AV_PIX_FMT_GRAY8:
+ case AV_PIX_FMT_YUV444P:
+ case AV_PIX_FMT_YUV440P:
+ case AV_PIX_FMT_YUV422P:
+ case AV_PIX_FMT_YUV420P:
+ case AV_PIX_FMT_YUV411P:
+ case AV_PIX_FMT_YUV410P:
s->chroma_planes= av_pix_fmt_descriptors[avctx->pix_fmt].nb_components < 3 ? 0 : 1;
s->colorspace= 0;
break;
- case PIX_FMT_YUVA444P:
- case PIX_FMT_YUVA422P:
- case PIX_FMT_YUVA420P:
+ case AV_PIX_FMT_YUVA444P:
+ case AV_PIX_FMT_YUVA422P:
+ case AV_PIX_FMT_YUVA420P:
s->chroma_planes= 1;
s->colorspace= 0;
s->transparency= 1;
break;
- case PIX_FMT_RGB32:
+ case AV_PIX_FMT_RGB32:
s->colorspace= 1;
s->transparency= 1;
break;
- case PIX_FMT_0RGB32:
+ case AV_PIX_FMT_0RGB32:
s->colorspace= 1;
break;
- case PIX_FMT_GBRP9:
+ case AV_PIX_FMT_GBRP9:
if (!avctx->bits_per_raw_sample)
s->bits_per_raw_sample = 9;
- case PIX_FMT_GBRP10:
+ case AV_PIX_FMT_GBRP10:
if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
s->bits_per_raw_sample = 10;
- case PIX_FMT_GBRP12:
+ case AV_PIX_FMT_GBRP12:
if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
s->bits_per_raw_sample = 12;
- case PIX_FMT_GBRP14:
+ case AV_PIX_FMT_GBRP14:
if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
s->bits_per_raw_sample = 14;
else if (!s->bits_per_raw_sample)
encode_slice_header(f, fs);
}
if(!fs->ac){
+ if(f->version > 2)
+ put_rac(&fs->c, (uint8_t[]){129}, 0);
fs->ac_byte_count = f->version > 2 || (!x&&!y) ? ff_rac_terminate(&fs->c) : 0;
init_put_bits(&fs->pb, fs->c.bytestream_start + fs->ac_byte_count, fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count);
}
for(i=1; i<f->slice_count; i++){
FFV1Context *fs= f->slice_context[i];
- uint8_t *start = pkt->data + (pkt->size-used_count)*i/f->slice_count;
+ uint8_t *start = pkt->data + (pkt->size-used_count)*(int64_t)i/f->slice_count;
int len = pkt->size/f->slice_count;
-
ff_init_range_encoder(&fs->c, start, len);
}
avctx->execute(avctx, encode_slice, &f->slice_context[0], NULL, f->slice_count, sizeof(void*));
int bytes;
if(fs->ac){
- uint8_t state=128;
+ uint8_t state=129;
put_rac(&fs->c, &state, 0);
bytes= ff_rac_terminate(&fs->c);
}else{
}else
diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits);
-// printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, get_bits_count(&s->gb));
+ av_dlog(s->avctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n",
+ run_count, run_index, run_mode, x, get_bits_count(&s->gb));
}
if(sign) diff= -diff;
int r= sample[2][1][x];
int a= sample[3][1][x];
-// assert(g>=0 && b>=0 && r>=0);
-// assert(g<256 && b<512 && r<512);
-
b -= offset;
r -= offset;
g -= (b + r)>>2;
y= fs->slice_y;
if(!fs->ac){
+ if (f->version == 3 && f->minor_version > 1 || f->version > 3)
+ get_rac(&fs->c, (uint8_t[]){129});
fs->ac_byte_count = f->version > 2 || (!x&&!y) ? fs->c.bytestream - fs->c.bytestream_start - 1 : 0;
init_get_bits(&fs->gb,
fs->c.bytestream_start + fs->ac_byte_count,
decode_rgb_frame(fs, planes, width, height, p->linesize);
}
if(fs->ac && f->version > 2) {
- int v = fs->c.bytestream_end - fs->c.bytestream - 3 - 5*f->ec;
- if(v != -1 && v!= 0) {
+ int v;
+ get_rac(&fs->c, (uint8_t[]){129});
+ v = fs->c.bytestream_end - fs->c.bytestream - 2 - 5*f->ec;
+ if(v) {
av_log(f->avctx, AV_LOG_ERROR, "bytestream end mismatching by %d\n", v);
fs->slice_damaged = 1;
}
while(len--){
quant_table[i] = scale*v;
i++;
-//printf("%2d ",v);
-//if(i%16==0) printf("\n");
}
}
if(f->colorspace==0){
if(!f->transparency && !f->chroma_planes){
if (f->avctx->bits_per_raw_sample<=8)
- f->avctx->pix_fmt= PIX_FMT_GRAY8;
+ f->avctx->pix_fmt= AV_PIX_FMT_GRAY8;
else
- f->avctx->pix_fmt= PIX_FMT_GRAY16;
+ f->avctx->pix_fmt= AV_PIX_FMT_GRAY16;
}else if(f->avctx->bits_per_raw_sample<=8 && !f->transparency){
switch(16*f->chroma_h_shift + f->chroma_v_shift){
- case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break;
- case 0x01: f->avctx->pix_fmt= PIX_FMT_YUV440P; break;
- case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break;
- case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break;
- case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break;
- case 0x22: f->avctx->pix_fmt= PIX_FMT_YUV410P; break;
+ case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUV444P; break;
+ case 0x01: f->avctx->pix_fmt= AV_PIX_FMT_YUV440P; break;
+ case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUV422P; break;
+ case 0x11: f->avctx->pix_fmt= AV_PIX_FMT_YUV420P; break;
+ case 0x20: f->avctx->pix_fmt= AV_PIX_FMT_YUV411P; break;
+ case 0x22: f->avctx->pix_fmt= AV_PIX_FMT_YUV410P; break;
default:
av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
return -1;
}
}else if(f->avctx->bits_per_raw_sample<=8 && f->transparency){
switch(16*f->chroma_h_shift + f->chroma_v_shift){
- case 0x00: f->avctx->pix_fmt= PIX_FMT_YUVA444P; break;
- case 0x10: f->avctx->pix_fmt= PIX_FMT_YUVA422P; break;
- case 0x11: f->avctx->pix_fmt= PIX_FMT_YUVA420P; break;
+ case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUVA444P; break;
+ case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUVA422P; break;
+ case 0x11: f->avctx->pix_fmt= AV_PIX_FMT_YUVA420P; break;
default:
av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
return -1;
}else if(f->avctx->bits_per_raw_sample==9) {
f->packed_at_lsb=1;
switch(16*f->chroma_h_shift + f->chroma_v_shift){
- case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P9; break;
- case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P9; break;
- case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P9; break;
+ case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUV444P9; break;
+ case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUV422P9; break;
+ case 0x11: f->avctx->pix_fmt= AV_PIX_FMT_YUV420P9; break;
default:
av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
return -1;
}else if(f->avctx->bits_per_raw_sample==10) {
f->packed_at_lsb=1;
switch(16*f->chroma_h_shift + f->chroma_v_shift){
- case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P10; break;
- case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P10; break;
- case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P10; break;
+ case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUV444P10; break;
+ case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUV422P10; break;
+ case 0x11: f->avctx->pix_fmt= AV_PIX_FMT_YUV420P10; break;
default:
av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
return -1;
}
}else {
switch(16*f->chroma_h_shift + f->chroma_v_shift){
- case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break;
- case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break;
- case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P16; break;
+ case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUV444P16; break;
+ case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUV422P16; break;
+ case 0x11: f->avctx->pix_fmt= AV_PIX_FMT_YUV420P16; break;
default:
av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
return -1;
return -1;
}
if(f->avctx->bits_per_raw_sample==9)
- f->avctx->pix_fmt= PIX_FMT_GBRP9;
+ f->avctx->pix_fmt= AV_PIX_FMT_GBRP9;
else if(f->avctx->bits_per_raw_sample==10)
- f->avctx->pix_fmt= PIX_FMT_GBRP10;
+ f->avctx->pix_fmt= AV_PIX_FMT_GBRP10;
else if(f->avctx->bits_per_raw_sample==12)
- f->avctx->pix_fmt= PIX_FMT_GBRP12;
+ f->avctx->pix_fmt= AV_PIX_FMT_GBRP12;
else if(f->avctx->bits_per_raw_sample==14)
- f->avctx->pix_fmt= PIX_FMT_GBRP14;
+ f->avctx->pix_fmt= AV_PIX_FMT_GBRP14;
else
- if(f->transparency) f->avctx->pix_fmt= PIX_FMT_RGB32;
- else f->avctx->pix_fmt= PIX_FMT_0RGB32;
+ if(f->transparency) f->avctx->pix_fmt= AV_PIX_FMT_RGB32;
+ else f->avctx->pix_fmt= AV_PIX_FMT_0RGB32;
}else{
av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n");
return -1;
}
-//printf("%d %d %d\n", f->chroma_h_shift, f->chroma_v_shift,f->avctx->pix_fmt);
+ av_dlog(f->avctx, "%d %d %d\n",
+ f->chroma_h_shift, f->chroma_v_shift, f->avctx->pix_fmt);
if(f->version < 2){
context_count= read_quant_tables(c, f->quant_table);
if(context_count < 0){
}
if(avctx->debug&FF_DEBUG_PICT_INFO)
- av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d\n",
- f->version, p->key_frame, f->ac, f->ec, f->slice_count);
+ av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n",
+ f->version, p->key_frame, f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample);
buf_p= buf + buf_size;
for(i=f->slice_count-1; i>=0; i--){
.close = common_end,
.capabilities = CODEC_CAP_SLICE_THREADS,
.defaults = ffv1_defaults,
- .pix_fmts = (const enum PixelFormat[]){
- PIX_FMT_YUV420P, PIX_FMT_YUVA420P, PIX_FMT_YUVA422P, PIX_FMT_YUV444P,
- PIX_FMT_YUVA444P, PIX_FMT_YUV440P, PIX_FMT_YUV422P, PIX_FMT_YUV411P,
- PIX_FMT_YUV410P, PIX_FMT_0RGB32, PIX_FMT_RGB32, PIX_FMT_YUV420P16,
- PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_YUV444P9, PIX_FMT_YUV422P9,
- PIX_FMT_YUV420P9, PIX_FMT_YUV420P10, PIX_FMT_YUV422P10, PIX_FMT_YUV444P10,
- PIX_FMT_GRAY16, PIX_FMT_GRAY8, PIX_FMT_GBRP9, PIX_FMT_GBRP10,
- PIX_FMT_GBRP12, PIX_FMT_GBRP14,
- PIX_FMT_NONE
+ .pix_fmts = (const enum AVPixelFormat[]){
+ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P,
+ AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
+ AV_PIX_FMT_YUV410P, AV_PIX_FMT_0RGB32, AV_PIX_FMT_RGB32, AV_PIX_FMT_YUV420P16,
+ AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9,
+ AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
+ AV_PIX_FMT_GRAY16, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
+ AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14,
+ AV_PIX_FMT_NONE
},
.long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
.priv_class = &class,