summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-11-28 17:38:04 +0100
committerMichael Niedermayer <michaelni@gmx.at>2011-11-28 17:38:04 +0100
commitf7b160e82929ae606111a7aa3a775785a92ce697 (patch)
tree2002d723516f61814124e2b8f4d787be975ccf84 /libavcodec
parentae5873f13bc7d0b4e93193ff7e90c92f52742268 (diff)
ffv1enc: Store transparency plane.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/ffv1.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index 2b7a928ca0..c74d3ba800 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -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;