aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/ffv1.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2010-10-10 21:04:45 +0000
committerMichael Niedermayer <michaelni@gmx.at>2010-10-10 21:04:45 +0000
commitc5ac275b2e2b59804530617d91c0eaae77b5e852 (patch)
tree3d5adf3fdafe7d882b22d61a6c868874c613ba4c /libavcodec/ffv1.c
parent0f27aca7b38c99a7fd9a8ade6b0dfc5acd83e872 (diff)
downloadffmpeg-c5ac275b2e2b59804530617d91c0eaae77b5e852.tar.gz
Allow storing multiple quant tables in extradata that can then be selected per keyframe in ffv1.
Originally committed as revision 25439 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/ffv1.c')
-rw-r--r--libavcodec/ffv1.c85
1 files changed, 47 insertions, 38 deletions
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index f477d04826..808d0e99bb 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -36,6 +36,8 @@
#define MAX_PLANES 4
#define CONTEXT_SIZE 32
+#define MAX_QUANT_TABLES 8
+
extern const uint8_t ff_log2_run[32];
static const int8_t quant3[256]={
@@ -234,11 +236,15 @@ typedef struct FFV1Context{
int ac; ///< 1=range coder <-> 0=golomb rice
PlaneContext plane[MAX_PLANES];
int16_t quant_table[5][256];
+ int16_t quant_tables[MAX_QUANT_TABLES][5][256];
+ int context_count[MAX_QUANT_TABLES];
uint8_t state_transition[256];
int run_index;
int colorspace;
int_fast16_t *sample_buffer;
+ int quant_table_count;
+
DSPContext dsp;
}FFV1Context;
@@ -622,6 +628,8 @@ static void write_header(FFV1Context *f){
put_rac(c, state, 0); //no transparency plane
write_quant_tables(c, f->quant_table);
+ }else{
+ put_symbol(c, state, f->avctx->context_model, 0);
}
}
#endif /* CONFIG_FFV1_ENCODER */
@@ -671,7 +679,10 @@ static int write_extra_header(FFV1Context *f){
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
- write_quant_tables(c, f->quant_table);
+
+ put_symbol(c, state, f->quant_table_count, 0);
+ for(i=0; i<f->quant_table_count; i++)
+ write_quant_tables(c, f->quant_tables[i]);
f->avctx->extradata_size= ff_rac_terminate(c);
@@ -690,32 +701,28 @@ static av_cold int encode_init(AVCodecContext *avctx)
s->plane_count=2;
for(i=0; i<256; i++){
+ s->quant_table_count=2;
if(avctx->bits_per_raw_sample <=8){
- s->quant_table[0][i]= quant11[i];
- s->quant_table[1][i]= 11*quant11[i];
- if(avctx->context_model==0){
- s->quant_table[2][i]= 11*11*quant11[i];
- s->quant_table[3][i]=
- s->quant_table[4][i]=0;
- }else{
- s->quant_table[2][i]= 11*11*quant5 [i];
- s->quant_table[3][i]= 5*11*11*quant5 [i];
- s->quant_table[4][i]= 5*5*11*11*quant5 [i];
- }
+ s->quant_tables[0][0][i]= quant11[i];
+ s->quant_tables[0][1][i]= 11*quant11[i];
+ s->quant_tables[0][2][i]= 11*11*quant11[i];
+ s->quant_tables[1][0][i]= quant11[i];
+ s->quant_tables[1][1][i]= 11*quant11[i];
+ s->quant_tables[1][2][i]= 11*11*quant5 [i];
+ s->quant_tables[1][3][i]= 5*11*11*quant5 [i];
+ s->quant_tables[1][4][i]= 5*5*11*11*quant5 [i];
}else{
- s->quant_table[0][i]= quant9_10bit[i];
- s->quant_table[1][i]= 11*quant9_10bit[i];
- if(avctx->context_model==0){
- s->quant_table[2][i]= 11*11*quant9_10bit[i];
- s->quant_table[3][i]=
- s->quant_table[4][i]=0;
- }else{
- s->quant_table[2][i]= 11*11*quant5_10bit[i];
- s->quant_table[3][i]= 5*11*11*quant5_10bit[i];
- s->quant_table[4][i]= 5*5*11*11*quant5_10bit[i];
- }
+ s->quant_tables[0][0][i]= quant9_10bit[i];
+ s->quant_tables[0][1][i]= 11*quant9_10bit[i];
+ s->quant_tables[0][2][i]= 11*11*quant9_10bit[i];
+ s->quant_tables[1][0][i]= quant9_10bit[i];
+ s->quant_tables[1][1][i]= 11*quant9_10bit[i];
+ s->quant_tables[1][2][i]= 11*11*quant5_10bit[i];
+ s->quant_tables[1][3][i]= 5*11*11*quant5_10bit[i];
+ s->quant_tables[1][4][i]= 5*5*11*11*quant5_10bit[i];
}
}
+ memcpy(s->quant_table, s->quant_tables[avctx->context_model], sizeof(s->quant_table));
for(i=0; i<s->plane_count; i++){
PlaneContext * const p= &s->plane[i];
@@ -1052,7 +1059,7 @@ static int read_quant_tables(RangeCoder *c, int16_t quant_table[5][256]){
static int read_extra_header(FFV1Context *f){
RangeCoder * const c= &f->c;
uint8_t state[CONTEXT_SIZE];
- int i,context_count;
+ int i;
memset(state, 128, sizeof(state));
@@ -1073,20 +1080,14 @@ static int read_extra_header(FFV1Context *f){
f->chroma_v_shift= get_symbol(c, state, 0);
get_rac(c, state); //transparency plane
f->plane_count= 2;
- context_count= read_quant_tables(c, f->quant_table);
- if(context_count < 0){
- av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
- return -1;
- }
- for(i=0; i<f->plane_count; i++){
- PlaneContext * const p= &f->plane[i];
-
- p->context_count= context_count;
- if(f->ac){
- if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t));
- }else{
- if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState));
+ f->quant_table_count= get_symbol(c, state, 0);
+ if(f->quant_table_count > (unsigned)MAX_QUANT_TABLES)
+ return -1;
+ for(i=0; i<f->quant_table_count; i++){
+ if((f->context_count[i]= read_quant_tables(c, f->quant_tables[i])) < 0){
+ av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
+ return -1;
}
}
@@ -1159,6 +1160,15 @@ static int read_header(FFV1Context *f){
return -1;
}
+ }else{
+ i=get_symbol(c, state, 0);
+ if(i > (unsigned)f->quant_table_count){
+ av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n");
+ return -1;
+ }
+ memcpy(f->quant_table, f->quant_tables[i], sizeof(f->quant_table));
+ context_count= f->context_count[i];
+ }
for(i=0; i<f->plane_count; i++){
PlaneContext * const p= &f->plane[i];
@@ -1170,7 +1180,6 @@ static int read_header(FFV1Context *f){
if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState));
}
}
- }
return 0;
}