X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fffv1.c;h=a0a4a1d0096f51bee5e04494ff740f1d2f6b4bfb;hb=4ccb7911baa761d373e28068b93db13a76a780b8;hp=0a982e8754faea034a9c764d0a1dfd002ba82301;hpb=0665199e438fcdd2000717352fc665a8cf017f7c;p=ffmpeg diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index 0a982e8754f..a0a4a1d0096 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -250,8 +250,9 @@ typedef struct FFV1Context{ uint8_t (*initial_states[MAX_QUANT_TABLES])[32]; int run_index; int colorspace; - int_fast16_t *sample_buffer; + int16_t *sample_buffer; int gob_count; + int packed_at_lsb; int quant_table_count; @@ -279,7 +280,8 @@ static av_always_inline int fold(int diff, int bits){ return diff; } -static inline int predict(int_fast16_t *src, int_fast16_t *last){ +static inline int predict(int16_t *src, int16_t *last) +{ const int LT= last[-1]; const int T= last[ 0]; const int L = src[-1]; @@ -287,7 +289,9 @@ static inline int predict(int_fast16_t *src, int_fast16_t *last){ return mid_pred(L, L + T - LT, T); } -static inline int get_context(PlaneContext *p, int_fast16_t *src, int_fast16_t *last, int_fast16_t *last2){ +static inline int get_context(PlaneContext *p, int16_t *src, + int16_t *last, int16_t *last2) +{ const int LT= last[-1]; const int T= last[ 0]; const int RT= last[ 1]; @@ -506,7 +510,10 @@ static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int } #if CONFIG_FFV1_ENCODER -static av_always_inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){ +static av_always_inline int encode_line(FFV1Context *s, int w, + int16_t *sample[2], + int plane_index, int bits) +{ PlaneContext * const p= &s->plane[plane_index]; RangeCoder * const c= &s->c; int x; @@ -591,7 +598,7 @@ static av_always_inline int encode_line(FFV1Context *s, int w, int_fast16_t *sam static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ int x,y,i; const int ring_size= s->avctx->context_model ? 3 : 2; - int_fast16_t *sample[3]; + int16_t *sample[3]; s->run_index=0; memset(s->sample_buffer, 0, ring_size*(w+6)*sizeof(*s->sample_buffer)); @@ -609,8 +616,14 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, } encode_line(s, w, sample, plane_index, 8); }else{ - for(x=0; x> (16 - s->avctx->bits_per_raw_sample); + if(s->packed_at_lsb){ + for(x=0; x> (16 - s->avctx->bits_per_raw_sample); + } } encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); } @@ -621,7 +634,7 @@ 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; - int_fast16_t *sample[3][3]; + int16_t *sample[3][3]; s->run_index=0; memset(s->sample_buffer, 0, ring_size*3*(w+6)*sizeof(*s->sample_buffer)); @@ -725,6 +738,8 @@ static av_cold int common_init(AVCodecContext *avctx){ s->avctx= avctx; s->flags= avctx->flags; + avcodec_get_frame_defaults(&s->picture); + dsputil_init(&s->dsp, avctx); s->width = avctx->width; @@ -964,6 +979,10 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->coded_frame= &s->picture; switch(avctx->pix_fmt){ + case PIX_FMT_YUV420P9: + case PIX_FMT_YUV420P10: + case PIX_FMT_YUV422P10: + s->packed_at_lsb = 1; case PIX_FMT_YUV444P16: case PIX_FMT_YUV422P16: case PIX_FMT_YUV420P16: @@ -1127,6 +1146,7 @@ static int encode_slice(AVCodecContext *c, void *arg){ int x= fs->slice_x; int y= fs->slice_y; AVFrame * const p= &f->picture; + const int ps= (c->bits_per_raw_sample>8)+1; if(f->colorspace==0){ const int chroma_width = -((-width )>>f->chroma_h_shift); @@ -1134,12 +1154,12 @@ static int encode_slice(AVCodecContext *c, void *arg){ const int cx= x>>f->chroma_h_shift; const int cy= y>>f->chroma_v_shift; - encode_plane(fs, p->data[0] + x + y*p->linesize[0], width, height, p->linesize[0], 0); + encode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0); - encode_plane(fs, p->data[1] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); - encode_plane(fs, p->data[2] + cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1); + encode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); + encode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1); }else{ - encode_rgb_frame(fs, (uint32_t*)(p->data[0]) + x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4); + encode_rgb_frame(fs, (uint32_t*)(p->data[0]) + ps*x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4); } emms_c(); @@ -1160,7 +1180,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); *p = *pict; - p->pict_type= FF_I_TYPE; + p->pict_type= AV_PICTURE_TYPE_I; if(avctx->gop_size==0 || f->picture_number % avctx->gop_size == 0){ put_rac(c, &keystate, 1); @@ -1305,7 +1325,10 @@ static av_cold int common_end(AVCodecContext *avctx){ return 0; } -static av_always_inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){ +static av_always_inline void decode_line(FFV1Context *s, int w, + int16_t *sample[2], + int plane_index, int bits) +{ PlaneContext * const p= &s->plane[plane_index]; RangeCoder * const c= &s->c; int x; @@ -1365,7 +1388,7 @@ static av_always_inline void decode_line(FFV1Context *s, int w, int_fast16_t *sa static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ int x, y; - int_fast16_t *sample[2]; + int16_t *sample[2]; sample[0]=s->sample_buffer +3; sample[1]=s->sample_buffer+w+6+3; @@ -1374,7 +1397,7 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, memset(s->sample_buffer, 0, 2*(w+6)*sizeof(*s->sample_buffer)); for(y=0; yavctx->bits_per_raw_sample); - for(x=0; xavctx->bits_per_raw_sample); + if(s->packed_at_lsb){ + for(x=0; xavctx->bits_per_raw_sample); + } } } //STOP_TIMER("decode-line")} @@ -1400,7 +1429,7 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ int x, y, p; - int_fast16_t *sample[3][2]; + int16_t *sample[3][2]; for(x=0; x<3; x++){ sample[x][0] = s->sample_buffer + x*2 *(w+6) + 3; sample[x][1] = s->sample_buffer + (x*2+1)*(w+6) + 3; @@ -1412,7 +1441,7 @@ static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int st for(y=0; yslice_height; int x= fs->slice_x; int y= fs->slice_y; + const int ps= (c->bits_per_raw_sample>8)+1; AVFrame * const p= &f->picture; av_assert1(width && height); @@ -1455,12 +1485,12 @@ static int decode_slice(AVCodecContext *c, void *arg){ const int chroma_height= -((-height)>>f->chroma_v_shift); const int cx= x>>f->chroma_h_shift; const int cy= y>>f->chroma_v_shift; - decode_plane(fs, p->data[0] + x + y*p->linesize[0], width, height, p->linesize[0], 0); + decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0); - decode_plane(fs, p->data[1] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); - decode_plane(fs, p->data[2] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[2], 1); + decode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); + decode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[2], 1); }else{ - decode_rgb_frame(fs, (uint32_t*)p->data[0] + x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4); + decode_rgb_frame(fs, (uint32_t*)p->data[0] + ps*x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4); } emms_c(); @@ -1606,7 +1636,25 @@ static int read_header(FFV1Context *f){ av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); return -1; } - }else{ + }else if(f->avctx->bits_per_raw_sample==9) { + 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_YUV420P9 ; f->packed_at_lsb=1; break; + default: + av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); + return -1; + } + }else if(f->avctx->bits_per_raw_sample==10) { + 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_YUV422P10; f->packed_at_lsb=1; break; + case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P10; f->packed_at_lsb=1; 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; @@ -1643,6 +1691,7 @@ static int read_header(FFV1Context *f){ for(j=0; jslice_count; j++){ FFV1Context *fs= f->slice_context[j]; fs->ac= f->ac; + fs->packed_at_lsb= f->packed_at_lsb; if(f->version >= 2){ fs->slice_x = get_symbol(c, state, 0) *f->width ; @@ -1723,7 +1772,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); - p->pict_type= FF_I_TYPE; //FIXME I vs. P + p->pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P if(get_rac(c, &keystate)){ p->key_frame= 1; if(read_header(f) < 0) @@ -1810,7 +1859,7 @@ AVCodec ff_ffv1_encoder = { encode_frame, common_end, .capabilities = CODEC_CAP_SLICE_THREADS, - .pix_fmts= (const 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}, + .pix_fmts= (const 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_YUV420P9, PIX_FMT_YUV420P10, PIX_FMT_YUV422P10, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), }; #endif