|
|
|
@@ -56,6 +56,26 @@ static const int8_t quant3[256]={ |
|
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, |
|
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, |
|
|
|
}; |
|
|
|
|
|
|
|
static const int8_t quant5_10bit[256]={ |
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, |
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
|
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
|
|
|
1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, |
|
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, |
|
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, |
|
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, |
|
|
|
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1, |
|
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, |
|
|
|
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, |
|
|
|
-1,-1,-1,-1,-1,-1,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0, |
|
|
|
}; |
|
|
|
|
|
|
|
static const int8_t quant5[256]={ |
|
|
|
0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
|
|
@@ -110,6 +130,25 @@ static const int8_t quant9[256]={ |
|
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3, |
|
|
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1, |
|
|
|
}; |
|
|
|
static const int8_t quant9_10bit[256]={ |
|
|
|
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, |
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, |
|
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
|
|
|
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, |
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
|
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, |
|
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, |
|
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, |
|
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, |
|
|
|
-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3, |
|
|
|
-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, |
|
|
|
-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, |
|
|
|
-2,-2,-2,-2,-1,-1,-1,-1,-1,-1,-1,-1,-0,-0,-0,-0, |
|
|
|
}; |
|
|
|
|
|
|
|
static const int8_t quant11[256]={ |
|
|
|
0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, |
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, |
|
|
|
@@ -224,9 +263,7 @@ static inline void put_symbol_inline(RangeCoder *c, uint8_t *state, int v, int i |
|
|
|
const int a= FFABS(v); |
|
|
|
const int e= av_log2(a); |
|
|
|
put_rac(c, state+0, 0); |
|
|
|
|
|
|
|
assert(e<=9); |
|
|
|
|
|
|
|
if(e<=9){ |
|
|
|
for(i=0; i<e; i++){ |
|
|
|
put_rac(c, state+1+i, 1); //1..10 |
|
|
|
} |
|
|
|
@@ -238,6 +275,19 @@ static inline void put_symbol_inline(RangeCoder *c, uint8_t *state, int v, int i |
|
|
|
|
|
|
|
if(is_signed) |
|
|
|
put_rac(c, state+11 + e, v < 0); //11..21 |
|
|
|
}else{ |
|
|
|
for(i=0; i<e; i++){ |
|
|
|
put_rac(c, state+1+FFMIN(i,9), 1); //1..10 |
|
|
|
} |
|
|
|
put_rac(c, state+1+9, 0); |
|
|
|
|
|
|
|
for(i=e-1; i>=0; i--){ |
|
|
|
put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31 |
|
|
|
} |
|
|
|
|
|
|
|
if(is_signed) |
|
|
|
put_rac(c, state+11 + 10, v < 0); //11..21 |
|
|
|
} |
|
|
|
}else{ |
|
|
|
put_rac(c, state+0, 1); |
|
|
|
} |
|
|
|
@@ -247,22 +297,22 @@ static void av_noinline put_symbol(RangeCoder *c, uint8_t *state, int v, int is_ |
|
|
|
put_symbol_inline(c, state, v, is_signed); |
|
|
|
} |
|
|
|
|
|
|
|
static inline int get_symbol_inline(RangeCoder *c, uint8_t *state, int is_signed){ |
|
|
|
static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, int is_signed){ |
|
|
|
if(get_rac(c, state+0)) |
|
|
|
return 0; |
|
|
|
else{ |
|
|
|
int i, e, a; |
|
|
|
e= 0; |
|
|
|
while(get_rac(c, state+1 + e) && e<9){ //1..10 |
|
|
|
while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10 |
|
|
|
e++; |
|
|
|
} |
|
|
|
|
|
|
|
a= 1; |
|
|
|
for(i=e-1; i>=0; i--){ |
|
|
|
a += a + get_rac(c, state+22 + i); //22..31 |
|
|
|
a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31 |
|
|
|
} |
|
|
|
|
|
|
|
e= -(is_signed && get_rac(c, state+11 + e)); //11..21 |
|
|
|
e= -(is_signed && get_rac(c, state+11 + FFMIN(e, 10))); //11..21 |
|
|
|
return (a^e)-e; |
|
|
|
} |
|
|
|
} |
|
|
|
@@ -451,10 +501,17 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, |
|
|
|
sample[0][-1]= sample[1][0 ]; |
|
|
|
sample[1][ w]= sample[1][w-1]; |
|
|
|
//{START_TIMER |
|
|
|
if(s->avctx->bits_per_raw_sample<=8){ |
|
|
|
for(x=0; x<w; x++){ |
|
|
|
sample[0][x]= src[x + stride*y]; |
|
|
|
} |
|
|
|
encode_line(s, w, sample, plane_index, 8); |
|
|
|
}else{ |
|
|
|
for(x=0; x<w; x++){ |
|
|
|
sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->avctx->bits_per_raw_sample); |
|
|
|
} |
|
|
|
encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); |
|
|
|
} |
|
|
|
//STOP_TIMER("encode line")} |
|
|
|
} |
|
|
|
} |
|
|
|
@@ -523,6 +580,8 @@ static void write_header(FFV1Context *f){ |
|
|
|
put_symbol(c, state, f->version, 0); |
|
|
|
put_symbol(c, state, f->avctx->coder_type, 0); |
|
|
|
put_symbol(c, state, f->colorspace, 0); //YUV cs type |
|
|
|
if(f->version>0) |
|
|
|
put_symbol(c, state, f->avctx->bits_per_raw_sample, 0); |
|
|
|
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); |
|
|
|
@@ -562,6 +621,7 @@ static av_cold int encode_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
s->plane_count=2; |
|
|
|
for(i=0; i<256; i++){ |
|
|
|
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){ |
|
|
|
@@ -573,6 +633,19 @@ static av_cold int encode_init(AVCodecContext *avctx) |
|
|
|
s->quant_table[3][i]= 5*11*11*quant5 [i]; |
|
|
|
s->quant_table[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]; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for(i=0; i<s->plane_count; i++){ |
|
|
|
@@ -593,6 +666,19 @@ static av_cold int encode_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
avctx->coded_frame= &s->picture; |
|
|
|
switch(avctx->pix_fmt){ |
|
|
|
case PIX_FMT_YUV444P16: |
|
|
|
case PIX_FMT_YUV422P16: |
|
|
|
case PIX_FMT_YUV420P16: |
|
|
|
if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ |
|
|
|
av_log(avctx, AV_LOG_ERROR, "More than 8 bit per component is still experimental and no gurantee is yet made for future compatibility\n" |
|
|
|
"Use vstrict=-2 / -strict -2 to use it anyway.\n"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if(avctx->bits_per_raw_sample <=8){ |
|
|
|
av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample inavlid\n"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
s->version= 1; |
|
|
|
case PIX_FMT_YUV444P: |
|
|
|
case PIX_FMT_YUV422P: |
|
|
|
case PIX_FMT_YUV420P: |
|
|
|
@@ -788,10 +874,17 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, |
|
|
|
sample[0][ w]= sample[0][w-1]; |
|
|
|
|
|
|
|
//{START_TIMER |
|
|
|
if(s->avctx->bits_per_raw_sample <= 8){ |
|
|
|
decode_line(s, w, sample, plane_index, 8); |
|
|
|
for(x=0; x<w; x++){ |
|
|
|
src[x + stride*y]= sample[1][x]; |
|
|
|
} |
|
|
|
}else{ |
|
|
|
decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); |
|
|
|
for(x=0; x<w; x++){ |
|
|
|
((uint16_t*)(src + stride*y))[x]= sample[1][x] << (16 - s->avctx->bits_per_raw_sample); |
|
|
|
} |
|
|
|
} |
|
|
|
//STOP_TIMER("decode-line")} |
|
|
|
} |
|
|
|
} |
|
|
|
@@ -877,6 +970,8 @@ static int read_header(FFV1Context *f){ |
|
|
|
f->version= get_symbol(c, state, 0); |
|
|
|
f->ac= f->avctx->coder_type= get_symbol(c, state, 0); |
|
|
|
f->colorspace= get_symbol(c, state, 0); //YUV cs type |
|
|
|
if(f->version>0) |
|
|
|
f->avctx->bits_per_raw_sample= get_symbol(c, state, 0); |
|
|
|
get_rac(c, state); //no chroma = false |
|
|
|
f->chroma_h_shift= get_symbol(c, state, 0); |
|
|
|
f->chroma_v_shift= get_symbol(c, state, 0); |
|
|
|
@@ -884,6 +979,7 @@ static int read_header(FFV1Context *f){ |
|
|
|
f->plane_count= 2; |
|
|
|
|
|
|
|
if(f->colorspace==0){ |
|
|
|
if(f->avctx->bits_per_raw_sample<=8){ |
|
|
|
switch(16*f->chroma_h_shift + f->chroma_v_shift){ |
|
|
|
case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break; |
|
|
|
case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break; |
|
|
|
@@ -894,6 +990,16 @@ static int read_header(FFV1Context *f){ |
|
|
|
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; |
|
|
|
default: |
|
|
|
av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
}else if(f->colorspace==1){ |
|
|
|
if(f->chroma_h_shift || f->chroma_v_shift){ |
|
|
|
av_log(f->avctx, AV_LOG_ERROR, "chroma subsampling not supported in this colorspace\n"); |
|
|
|
@@ -1042,7 +1148,7 @@ AVCodec ffv1_encoder = { |
|
|
|
encode_init, |
|
|
|
encode_frame, |
|
|
|
common_end, |
|
|
|
.pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_NONE}, |
|
|
|
.pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_NONE}, |
|
|
|
.long_name= NULL_IF_CONFIG_SMALL("FFmpeg codec #1"), |
|
|
|
}; |
|
|
|
#endif |