diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2002-11-14 22:25:20 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2002-11-14 22:25:20 +0000 |
commit | 152ba68cc9135a5fd2427dd3e212b83c45e320db (patch) | |
tree | 5059c879a7d9ff688f2a6329a48b5d00adfa57cb /libavcodec/huffyuv.c | |
parent | b24cf8283e2aa25029019dcc96ecc35bc3137fa7 (diff) | |
download | ffmpeg-152ba68cc9135a5fd2427dd3e212b83c45e320db.tar.gz |
YV12 support (warning this is experimental & wont work with offical huffyuv but there is a approx. 20% speed & compression gain)
10l flush_put_bits()
Originally committed as revision 1214 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/huffyuv.c')
-rw-r--r-- | libavcodec/huffyuv.c | 145 |
1 files changed, 116 insertions, 29 deletions
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index ad8b814fe0..fe1df1032e 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -328,7 +328,7 @@ s->bgr32=1; //if(avctx->extradata) // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size); if(avctx->extradata_size){ - if(avctx->bits_per_sample&7) + if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12) s->version=1; // do such files exist at all? else s->version=2; @@ -473,6 +473,13 @@ static int encode_init(AVCodecContext *avctx) s->version=2; switch(avctx->pix_fmt){ + case PIX_FMT_YUV420P: + if(avctx->strict_std_compliance>=0){ + fprintf(stderr, "YV12-huffyuv is experimental, there WILL be no compatbility! (use (v)strict=-1)\n"); + return -1; + } + s->bitstream_bpp= 12; + break; case PIX_FMT_YUV422P: s->bitstream_bpp= 16; break; @@ -554,6 +561,17 @@ static void decode_422_bitstream(HYuvContext *s, int count){ } } +static void decode_gray_bitstream(HYuvContext *s, int count){ + int i; + + count/=2; + + for(i=0; i<count; i++){ + s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + } +} + static void encode_422_bitstream(HYuvContext *s, int count){ int i; @@ -575,6 +593,23 @@ static void encode_422_bitstream(HYuvContext *s, int count){ } } +static void encode_gray_bitstream(HYuvContext *s, int count){ + int i; + + count/=2; + if(s->flags&CODEC_FLAG_PASS1){ + for(i=0; i<count; i++){ + s->stats[0][ s->temp[0][2*i ] ]++; + s->stats[0][ s->temp[0][2*i+1] ]++; + } + }else{ + for(i=0; i<count; i++){ + put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); + put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]); + } + } +} + static void decode_bgr_bitstream(HYuvContext *s, int count){ int i; @@ -634,7 +669,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 init_get_bits(&s->gb, s->bitstream_buffer, buf_size); if(s->bitstream_bpp<24){ - int y; + int y, cy; int lefty, leftu, leftv; int lefttopy, lefttopu, lefttopv; @@ -663,13 +698,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv); } - for(y=1; y<s->height; y++){ + for(cy=y=1; y<s->height; y++,cy++){ uint8_t *ydst, *udst, *vdst; - decode_422_bitstream(s, width); + + if(s->bitstream_bpp==12){ + decode_gray_bitstream(s, width); + + ydst= s->picture[0] + s->linesize[0]*y; + + lefty= add_left_prediction(ydst, s->temp[0], width, lefty); + if(s->predictor == PLANE){ + if(y>s->interlaced) + s->dsp.add_bytes(ydst, ydst - fake_ystride, width); + } + y++; + if(y>=s->height) break; + } ydst= s->picture[0] + s->linesize[0]*y; - udst= s->picture[1] + s->linesize[1]*y; - vdst= s->picture[2] + s->linesize[2]*y; + udst= s->picture[1] + s->linesize[1]*cy; + vdst= s->picture[2] + s->linesize[2]*cy; + + decode_422_bitstream(s, width); lefty= add_left_prediction(ydst, s->temp[0], width, lefty); if(!(s->flags&CODEC_FLAG_GRAY)){ @@ -677,7 +727,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv); } if(s->predictor == PLANE){ - if(y>s->interlaced){ + if(cy>s->interlaced){ s->dsp.add_bytes(ydst, ydst - fake_ystride, width); if(!(s->flags&CODEC_FLAG_GRAY)){ s->dsp.add_bytes(udst, udst - fake_ustride, width2); @@ -696,7 +746,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv); } - y=1; + cy=y=1; /* second line is left predicted for interlaced case */ if(s->interlaced){ @@ -706,7 +756,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 leftu= add_left_prediction(s->picture[1] + s->linesize[2], s->temp[1], width2, leftu); leftv= add_left_prediction(s->picture[2] + s->linesize[1], s->temp[2], width2, leftv); } - y++; + y++; cy++; } /* next 4 pixels are left predicted too */ @@ -727,15 +777,26 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 add_median_prediction(s->picture[1] + fake_ustride+2, s->picture[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); add_median_prediction(s->picture[2] + fake_vstride+2, s->picture[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); } - y++; - - for(; y<height; y++){ + y++; cy++; + + for(; y<height; y++,cy++){ uint8_t *ydst, *udst, *vdst; + + if(s->bitstream_bpp==12){ + while(2*cy > y){ + decode_gray_bitstream(s, width); + ydst= s->picture[0] + s->linesize[0]*y; + add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); + y++; + } + if(y>=height) break; + } + decode_422_bitstream(s, width); - + ydst= s->picture[0] + s->linesize[0]*y; - udst= s->picture[1] + s->linesize[1]*y; - vdst= s->picture[2] + s->linesize[2]*y; + udst= s->picture[1] + s->linesize[1]*cy; + vdst= s->picture[2] + s->linesize[2]*cy; add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); if(!(s->flags&CODEC_FLAG_GRAY)){ @@ -834,8 +895,8 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, s->linesize[i]= pict->linesize[i]; } - if(avctx->pix_fmt == PIX_FMT_YUV422P){ - int lefty, leftu, leftv, y; + if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){ + int lefty, leftu, leftv, y, cy; put_bits(&s->pb, 8, leftv= s->picture[2][0]); put_bits(&s->pb, 8, lefty= s->picture[0][1]); @@ -850,14 +911,14 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, if(s->predictor==MEDIAN){ int lefttopy, lefttopu, lefttopv; - y=1; + cy=y=1; if(s->interlaced){ lefty= sub_left_prediction(s->temp[0], s->picture[0]+s->linesize[0], width , lefty); leftu= sub_left_prediction(s->temp[1], s->picture[1]+s->linesize[1], width2, leftu); leftv= sub_left_prediction(s->temp[2], s->picture[2]+s->linesize[2], width2, leftv); encode_422_bitstream(s, width); - y++; + y++; cy++; } lefty= sub_left_prediction(s->temp[0], s->picture[0]+fake_ystride, 4, lefty); @@ -865,7 +926,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, leftv= sub_left_prediction(s->temp[2], s->picture[2]+fake_ystride, 2, leftv); encode_422_bitstream(s, 4); - + lefttopy= s->picture[0][3]; lefttopu= s->picture[1][1]; lefttopv= s->picture[2][1]; @@ -873,14 +934,23 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, sub_median_prediction(s->temp[1], s->picture[1]+2, s->picture[1] + fake_ustride+2, width2-2, &leftu, &lefttopu); sub_median_prediction(s->temp[2], s->picture[2]+2, s->picture[2] + fake_vstride+2, width2-2, &leftv, &lefttopv); encode_422_bitstream(s, width-4); - y++; + y++; cy++; - for(; y<height; y++){ + for(; y<height; y++,cy++){ uint8_t *ydst, *udst, *vdst; + if(s->bitstream_bpp==12){ + while(2*cy > y){ + ydst= s->picture[0] + s->linesize[0]*y; + sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); + encode_gray_bitstream(s, width); + y++; + } + if(y>=height) break; + } ydst= s->picture[0] + s->linesize[0]*y; - udst= s->picture[1] + s->linesize[1]*y; - vdst= s->picture[2] + s->linesize[2]*y; + udst= s->picture[1] + s->linesize[1]*cy; + vdst= s->picture[2] + s->linesize[2]*cy; sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu); @@ -889,14 +959,30 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, encode_422_bitstream(s, width); } }else{ - for(y=1; y<height; y++){ + for(cy=y=1; y<height; y++,cy++){ uint8_t *ydst, *udst, *vdst; - + + /* encode a luma only line & y++ */ + if(s->bitstream_bpp==12){ + ydst= s->picture[0] + s->linesize[0]*y; + + if(s->predictor == PLANE && s->interlaced < y){ + s->dsp.diff_bytes(s->temp[0], ydst, ydst - fake_ystride, width); + + lefty= sub_left_prediction(s->temp[0], s->temp[0], width , lefty); + }else{ + lefty= sub_left_prediction(s->temp[0], ydst, width , lefty); + } + encode_gray_bitstream(s, width); + y++; + if(y>=height) break; + } + ydst= s->picture[0] + s->linesize[0]*y; - udst= s->picture[1] + s->linesize[1]*y; - vdst= s->picture[2] + s->linesize[2]*y; + udst= s->picture[1] + s->linesize[1]*cy; + vdst= s->picture[2] + s->linesize[2]*cy; - if(s->predictor == PLANE && s->interlaced < y){ + if(s->predictor == PLANE && s->interlaced < cy){ s->dsp.diff_bytes(s->temp[0], ydst, ydst - fake_ystride, width); s->dsp.diff_bytes(s->temp[1], udst, udst - fake_ustride, width2); s->dsp.diff_bytes(s->temp[2], vdst, vdst - fake_vstride, width2); @@ -933,6 +1019,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, p++; } }else{ + flush_put_bits(&s->pb); bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); } |