|
|
|
@ -165,6 +165,7 @@ typedef struct FFV1Context{ |
|
|
|
|
int version; |
|
|
|
|
int width, height; |
|
|
|
|
int chroma_h_shift, chroma_v_shift; |
|
|
|
|
int transparency; |
|
|
|
|
int flags; |
|
|
|
|
int picture_number; |
|
|
|
|
AVFrame picture; |
|
|
|
@ -562,21 +563,22 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, |
|
|
|
|
static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ |
|
|
|
|
int x, y, p, i; |
|
|
|
|
const int ring_size= s->avctx->context_model ? 3 : 2; |
|
|
|
|
int16_t *sample[3][3]; |
|
|
|
|
int16_t *sample[4][3]; |
|
|
|
|
s->run_index=0; |
|
|
|
|
|
|
|
|
|
memset(s->sample_buffer, 0, ring_size*3*(w+6)*sizeof(*s->sample_buffer)); |
|
|
|
|
memset(s->sample_buffer, 0, ring_size*4*(w+6)*sizeof(*s->sample_buffer)); |
|
|
|
|
|
|
|
|
|
for(y=0; y<h; y++){ |
|
|
|
|
for(i=0; i<ring_size; i++) |
|
|
|
|
for(p=0; p<3; p++) |
|
|
|
|
for(p=0; p<4; 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 v= src[x + stride*y]; |
|
|
|
|
unsigned v= src[x + stride*y]; |
|
|
|
|
int b= v&0xFF; |
|
|
|
|
int g= (v>>8)&0xFF; |
|
|
|
|
int r= (v>>16)&0xFF; |
|
|
|
|
int a= v>>24; |
|
|
|
|
|
|
|
|
|
b -= g; |
|
|
|
|
r -= g; |
|
|
|
@ -589,11 +591,12 @@ static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int st |
|
|
|
|
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; p++){ |
|
|
|
|
for(p=0; p<4; p++){ |
|
|
|
|
sample[p][0][-1]= sample[p][1][0 ]; |
|
|
|
|
sample[p][1][ w]= sample[p][1][w-1]; |
|
|
|
|
encode_line(s, w, sample[p], FFMIN(p, 1), 9); |
|
|
|
|
encode_line(s, w, sample[p], (p+1)/2, 9); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -640,7 +643,7 @@ static void write_header(FFV1Context *f){ |
|
|
|
|
put_rac(c, state, 1); //chroma planes
|
|
|
|
|
put_symbol(c, state, f->chroma_h_shift, 0); |
|
|
|
|
put_symbol(c, state, f->chroma_v_shift, 0); |
|
|
|
|
put_rac(c, state, 0); //no transparency plane
|
|
|
|
|
put_rac(c, state, f->transparency); |
|
|
|
|
|
|
|
|
|
write_quant_tables(c, f->quant_table); |
|
|
|
|
}else{ |
|
|
|
@ -687,6 +690,8 @@ static int init_slice_state(FFV1Context *f){ |
|
|
|
|
|
|
|
|
|
for(i=0; i<f->slice_count; i++){ |
|
|
|
|
FFV1Context *fs= f->slice_context[i]; |
|
|
|
|
fs->plane_count= f->plane_count; |
|
|
|
|
fs->transparency= f->transparency; |
|
|
|
|
for(j=0; j<f->plane_count; j++){ |
|
|
|
|
PlaneContext * const p= &fs->plane[j]; |
|
|
|
|
|
|
|
|
@ -735,7 +740,7 @@ static av_cold int init_slice_contexts(FFV1Context *f){ |
|
|
|
|
fs->slice_x = sxs; |
|
|
|
|
fs->slice_y = sys; |
|
|
|
|
|
|
|
|
|
fs->sample_buffer = av_malloc(9 * (fs->width+6) * sizeof(*fs->sample_buffer)); |
|
|
|
|
fs->sample_buffer = av_malloc(3*4 * (fs->width+6) * sizeof(*fs->sample_buffer)); |
|
|
|
|
if (!fs->sample_buffer) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
} |
|
|
|
@ -780,7 +785,7 @@ static int write_extra_header(FFV1Context *f){ |
|
|
|
|
put_rac(c, state, 1); //chroma planes
|
|
|
|
|
put_symbol(c, state, f->chroma_h_shift, 0); |
|
|
|
|
put_symbol(c, state, f->chroma_v_shift, 0); |
|
|
|
|
put_rac(c, state, 0); //no transparency plane
|
|
|
|
|
put_rac(c, state, f->transparency); |
|
|
|
|
put_symbol(c, state, f->num_h_slices-1, 0); |
|
|
|
|
put_symbol(c, state, f->num_v_slices-1, 0); |
|
|
|
|
|
|
|
|
@ -867,7 +872,7 @@ static av_cold int encode_init(AVCodecContext *avctx) |
|
|
|
|
for(i=1; i<256; i++) |
|
|
|
|
s->state_transition[i]=ver2_state[i]; |
|
|
|
|
|
|
|
|
|
s->plane_count=2; |
|
|
|
|
s->plane_count=3; |
|
|
|
|
for(i=0; i<256; i++){ |
|
|
|
|
s->quant_table_count=2; |
|
|
|
|
if(avctx->bits_per_raw_sample <=8){ |
|
|
|
@ -932,11 +937,14 @@ static av_cold int encode_init(AVCodecContext *avctx) |
|
|
|
|
break; |
|
|
|
|
case PIX_FMT_RGB32: |
|
|
|
|
s->colorspace= 1; |
|
|
|
|
s->transparency= 1; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
av_log(avctx, AV_LOG_ERROR, "format not supported\n"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
if(!s->transparency) |
|
|
|
|
s->plane_count= 2; |
|
|
|
|
avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); |
|
|
|
|
|
|
|
|
|
s->picture_number=0; |
|
|
|
|