# HG changeset patch # User nenolod # Date 1173729990 25200 # Node ID 23a5aa2c545c0fcd909262a2189b39994572a4ce # Parent 2eaaa3aa182b9f11b7f21f5c113ef6aab0ce0310 [svn] - bork bork bork diff -r 2eaaa3aa182b -r 23a5aa2c545c ChangeLog --- a/ChangeLog Mon Mar 12 13:00:06 2007 -0700 +++ b/ChangeLog Mon Mar 12 13:06:30 2007 -0700 @@ -1,3 +1,40 @@ +2007-03-12 20:00:06 +0000 William Pitcock + revision [1728] + - make the whole thing compile. runtime linking is another story. + + trunk/src/ffmpeg/Makefile | 8 + trunk/src/ffmpeg/ffmpeg.c | 478 + + trunk/src/ffmpeg/libavcodec/Makefile | 16 + trunk/src/ffmpeg/libavcodec/mpegvideo.c | 6881 -------------------------- + trunk/src/ffmpeg/libavcodec/qpeg.c | 324 - + trunk/src/ffmpeg/libavcodec/svq1.c | 1431 ----- + trunk/src/ffmpeg/libavcodec/svq1_cb.h | 1580 ----- + trunk/src/ffmpeg/libavcodec/svq1_vlc.h | 281 - + trunk/src/ffmpeg/libavcodec/svq3.c | 1014 --- + trunk/src/ffmpeg/libavcodec/tiertexseqv.c | 232 + trunk/src/ffmpeg/libavcodec/truemotion1.c | 923 --- + trunk/src/ffmpeg/libavcodec/truemotion1data.h | 829 --- + trunk/src/ffmpeg/libavcodec/truemotion2.c | 893 --- + trunk/src/ffmpeg/libavcodec/ulti.c | 428 - + trunk/src/ffmpeg/libavcodec/ulti_cb.h | 4119 --------------- + trunk/src/ffmpeg/libavcodec/vc1dsp.c | 453 - + trunk/src/ffmpeg/libavcodec/zmbv.c | 692 -- + trunk/src/ffmpeg/libavformat/Makefile | 18 + trunk/src/ffmpeg/libavformat/avformat.h | 4 + trunk/src/ffmpeg/libavformat/avisynth.c | 222 + trunk/src/ffmpeg/libavformat/dc1394.c | 193 + trunk/src/ffmpeg/libavformat/dv1394.c | 240 + trunk/src/ffmpeg/libavformat/dv1394.h | 357 - + trunk/src/ffmpeg/libavformat/file.c | 1 + trunk/src/ffmpeg/libavformat/grab_bktr.c | 330 - + trunk/src/ffmpeg/libavformat/rtp.c | 876 --- + trunk/src/ffmpeg/libavformat/rtp.h | 127 + trunk/src/ffmpeg/libavformat/tcp.c | 232 + trunk/src/ffmpeg/libavformat/udp.c | 504 - + trunk/src/ffmpeg/wma.c | 478 - + 30 files changed, 499 insertions(+), 23665 deletions(-) + + 2007-03-12 18:47:10 +0000 William Pitcock revision [1726] - remove more video stuff diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/4xm.c --- a/src/ffmpeg/libavcodec/4xm.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,759 +0,0 @@ -/* - * 4XM codec - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file 4xm.c - * 4XM codec. - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" - -//#undef NDEBUG -//#include - -#define BLOCK_TYPE_VLC_BITS 5 -#define ACDC_VLC_BITS 9 - -#define CFRAME_BUFFER_COUNT 100 - -static const uint8_t block_type_tab[4][8][2]={ - { //{8,4,2}x{8,4,2} - { 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0} - },{ //{8,4}x1 - { 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0} - },{ //1x{8,4} - { 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0} - },{ //1x2, 2x1 - { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4} - } -}; - -static const uint8_t size2index[4][4]={ - {-1, 3, 1, 1}, - { 3, 0, 0, 0}, - { 2, 0, 0, 0}, - { 2, 0, 0, 0}, -}; - -static const int8_t mv[256][2]={ -{ 0, 0},{ 0, -1},{ -1, 0},{ 1, 0},{ 0, 1},{ -1, -1},{ 1, -1},{ -1, 1}, -{ 1, 1},{ 0, -2},{ -2, 0},{ 2, 0},{ 0, 2},{ -1, -2},{ 1, -2},{ -2, -1}, -{ 2, -1},{ -2, 1},{ 2, 1},{ -1, 2},{ 1, 2},{ -2, -2},{ 2, -2},{ -2, 2}, -{ 2, 2},{ 0, -3},{ -3, 0},{ 3, 0},{ 0, 3},{ -1, -3},{ 1, -3},{ -3, -1}, -{ 3, -1},{ -3, 1},{ 3, 1},{ -1, 3},{ 1, 3},{ -2, -3},{ 2, -3},{ -3, -2}, -{ 3, -2},{ -3, 2},{ 3, 2},{ -2, 3},{ 2, 3},{ 0, -4},{ -4, 0},{ 4, 0}, -{ 0, 4},{ -1, -4},{ 1, -4},{ -4, -1},{ 4, -1},{ 4, 1},{ -1, 4},{ 1, 4}, -{ -3, -3},{ -3, 3},{ 3, 3},{ -2, -4},{ -4, -2},{ 4, -2},{ -4, 2},{ -2, 4}, -{ 2, 4},{ -3, -4},{ 3, -4},{ 4, -3},{ -5, 0},{ -4, 3},{ -3, 4},{ 3, 4}, -{ -1, -5},{ -5, -1},{ -5, 1},{ -1, 5},{ -2, -5},{ 2, -5},{ 5, -2},{ 5, 2}, -{ -4, -4},{ -4, 4},{ -3, -5},{ -5, -3},{ -5, 3},{ 3, 5},{ -6, 0},{ 0, 6}, -{ -6, -1},{ -6, 1},{ 1, 6},{ 2, -6},{ -6, 2},{ 2, 6},{ -5, -4},{ 5, 4}, -{ 4, 5},{ -6, -3},{ 6, 3},{ -7, 0},{ -1, -7},{ 5, -5},{ -7, 1},{ -1, 7}, -{ 4, -6},{ 6, 4},{ -2, -7},{ -7, 2},{ -3, -7},{ 7, -3},{ 3, 7},{ 6, -5}, -{ 0, -8},{ -1, -8},{ -7, -4},{ -8, 1},{ 4, 7},{ 2, -8},{ -2, 8},{ 6, 6}, -{ -8, 3},{ 5, -7},{ -5, 7},{ 8, -4},{ 0, -9},{ -9, -1},{ 1, 9},{ 7, -6}, -{ -7, 6},{ -5, -8},{ -5, 8},{ -9, 3},{ 9, -4},{ 7, -7},{ 8, -6},{ 6, 8}, -{ 10, 1},{-10, 2},{ 9, -5},{ 10, -3},{ -8, -7},{-10, -4},{ 6, -9},{-11, 0}, -{ 11, 1},{-11, -2},{ -2, 11},{ 7, -9},{ -7, 9},{ 10, 6},{ -4, 11},{ 8, -9}, -{ 8, 9},{ 5, 11},{ 7,-10},{ 12, -3},{ 11, 6},{ -9, -9},{ 8, 10},{ 5, 12}, -{-11, 7},{ 13, 2},{ 6,-12},{ 10, 9},{-11, 8},{ -7, 12},{ 0, 14},{ 14, -2}, -{ -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{ 5, 14},{-15, -1},{-14, -6},{ 3,-15}, -{ 11,-11},{ -7, 14},{ -5, 15},{ 8,-14},{ 15, 6},{ 3, 16},{ 7,-15},{-16, 5}, -{ 0, 17},{-16, -6},{-10, 14},{-16, 7},{ 12, 13},{-16, 8},{-17, 6},{-18, 3}, -{ -7, 17},{ 15, 11},{ 16, 10},{ 2,-19},{ 3,-19},{-11,-16},{-18, 8},{-19, -6}, -{ 2,-20},{-17,-11},{-10,-18},{ 8, 19},{-21, -1},{-20, 7},{ -4, 21},{ 21, 5}, -{ 15, 16},{ 2,-22},{-10,-20},{-22, 5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5}, -{ 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24}, -{ 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27, 6},{ 1,-28}, -{-11, 26},{-17,-23},{ 7, 28},{ 11,-27},{ 29, 5},{-23,-19},{-28,-11},{-21, 22}, -{-30, 7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27}, -{-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32} -}; - -// this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table -static const uint8_t dequant_table[64]={ - 16, 15, 13, 19, 24, 31, 28, 17, - 17, 23, 25, 31, 36, 63, 45, 21, - 18, 24, 27, 37, 52, 59, 49, 20, - 16, 28, 34, 40, 60, 80, 51, 20, - 18, 31, 48, 66, 68, 86, 56, 21, - 19, 38, 56, 59, 64, 64, 48, 20, - 27, 48, 55, 55, 56, 51, 35, 15, - 20, 35, 34, 32, 31, 22, 15, 8, -}; - -static VLC block_type_vlc[4]; - - -typedef struct CFrameBuffer{ - unsigned int allocated_size; - unsigned int size; - int id; - uint8_t *data; -}CFrameBuffer; - -typedef struct FourXContext{ - AVCodecContext *avctx; - DSPContext dsp; - AVFrame current_picture, last_picture; - GetBitContext pre_gb; ///< ac/dc prefix - GetBitContext gb; - uint8_t *bytestream; - uint16_t *wordstream; - int mv[256]; - VLC pre_vlc; - int last_dc; - DECLARE_ALIGNED_8(DCTELEM, block[6][64]); - uint8_t *bitstream_buffer; - unsigned int bitstream_buffer_size; - CFrameBuffer cfrm[CFRAME_BUFFER_COUNT]; -} FourXContext; - - -#define FIX_1_082392200 70936 -#define FIX_1_414213562 92682 -#define FIX_1_847759065 121095 -#define FIX_2_613125930 171254 - -#define MULTIPLY(var,const) (((var)*(const)) >> 16) - -static void idct(DCTELEM block[64]){ - int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int tmp10, tmp11, tmp12, tmp13; - int z5, z10, z11, z12, z13; - int i; - int temp[64]; - - for(i=0; i<8; i++){ - tmp10 = block[8*0 + i] + block[8*4 + i]; - tmp11 = block[8*0 + i] - block[8*4 + i]; - - tmp13 = block[8*2 + i] + block[8*6 + i]; - tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13; - - tmp0 = tmp10 + tmp13; - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - z13 = block[8*5 + i] + block[8*3 + i]; - z10 = block[8*5 + i] - block[8*3 + i]; - z11 = block[8*1 + i] + block[8*7 + i]; - z12 = block[8*1 + i] - block[8*7 + i]; - - tmp7 = z11 + z13; - tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); - - z5 = MULTIPLY(z10 + z12, FIX_1_847759065); - tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; - tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; - - tmp6 = tmp12 - tmp7; - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - temp[8*0 + i] = tmp0 + tmp7; - temp[8*7 + i] = tmp0 - tmp7; - temp[8*1 + i] = tmp1 + tmp6; - temp[8*6 + i] = tmp1 - tmp6; - temp[8*2 + i] = tmp2 + tmp5; - temp[8*5 + i] = tmp2 - tmp5; - temp[8*4 + i] = tmp3 + tmp4; - temp[8*3 + i] = tmp3 - tmp4; - } - - for(i=0; i<8*8; i+=8){ - tmp10 = temp[0 + i] + temp[4 + i]; - tmp11 = temp[0 + i] - temp[4 + i]; - - tmp13 = temp[2 + i] + temp[6 + i]; - tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13; - - tmp0 = tmp10 + tmp13; - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - z13 = temp[5 + i] + temp[3 + i]; - z10 = temp[5 + i] - temp[3 + i]; - z11 = temp[1 + i] + temp[7 + i]; - z12 = temp[1 + i] - temp[7 + i]; - - tmp7 = z11 + z13; - tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); - - z5 = MULTIPLY(z10 + z12, FIX_1_847759065); - tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; - tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; - - tmp6 = tmp12 - tmp7; - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - block[0 + i] = (tmp0 + tmp7)>>6; - block[7 + i] = (tmp0 - tmp7)>>6; - block[1 + i] = (tmp1 + tmp6)>>6; - block[6 + i] = (tmp1 - tmp6)>>6; - block[2 + i] = (tmp2 + tmp5)>>6; - block[5 + i] = (tmp2 - tmp5)>>6; - block[4 + i] = (tmp3 + tmp4)>>6; - block[3 + i] = (tmp3 - tmp4)>>6; - } -} - -static void init_vlcs(FourXContext *f){ - int i; - - for(i=0; i<4; i++){ - init_vlc(&block_type_vlc[i], BLOCK_TYPE_VLC_BITS, 7, - &block_type_tab[i][0][1], 2, 1, - &block_type_tab[i][0][0], 2, 1, 1); - } -} - -static void init_mv(FourXContext *f){ - int i; - - for(i=0; i<256; i++){ - f->mv[i] = mv[i][0] + mv[i][1]*f->current_picture.linesize[0]/2; - } -} - -static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){ - int i; - dc*= 0x10001; - - switch(log2w){ - case 0: - for(i=0; igb, block_type_vlc[index].table, BLOCK_TYPE_VLC_BITS, 1); - - assert(code>=0 && code<=6); - - if(code == 0){ - src += f->mv[ *f->bytestream++ ]; - mcdc(dst, src, log2w, h, stride, 1, 0); - }else if(code == 1){ - log2h--; - decode_p_block(f, dst , src , log2w, log2h, stride); - decode_p_block(f, dst + (stride<mv[ *f->bytestream++ ]; - mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++)); - }else if(code == 5){ - mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++)); - }else if(code == 6){ - if(log2w){ - dst[0] = le2me_16(*f->wordstream++); - dst[1] = le2me_16(*f->wordstream++); - }else{ - dst[0 ] = le2me_16(*f->wordstream++); - dst[stride] = le2me_16(*f->wordstream++); - } - } -} - -static int get32(void *p){ - return le2me_32(*(uint32_t*)p); -} - -static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){ - int x, y; - const int width= f->avctx->width; - const int height= f->avctx->height; - uint16_t *src= (uint16_t*)f->last_picture.data[0]; - uint16_t *dst= (uint16_t*)f->current_picture.data[0]; - const int stride= f->current_picture.linesize[0]>>1; - const unsigned int bitstream_size= get32(buf+8); - const unsigned int bytestream_size= get32(buf+16); - const unsigned int wordstream_size= get32(buf+12); - - if(bitstream_size+ bytestream_size+ wordstream_size + 20 != length - || bitstream_size > (1<<26) - || bytestream_size > (1<<26) - || wordstream_size > (1<<26) - ){ - av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size, - bitstream_size+ bytestream_size+ wordstream_size - length); - return -1; - } - - f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE); - f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)(buf + 20), bitstream_size/4); - init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size); - - f->wordstream= (uint16_t*)(buf + 20 + bitstream_size); - f->bytestream= buf + 20 + bitstream_size + wordstream_size; - - init_mv(f); - - for(y=0; ygb)+31)/32*4) - av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n", - bitstream_size - (get_bits_count(&f->gb)+31)/32*4, - bytestream_size - (f->bytestream - (buf + 20 + bitstream_size + wordstream_size)), - wordstream_size - (((uint8_t*)f->wordstream) - (buf + 20 + bitstream_size)) - ); - - return 0; -} - -/** - * decode block and dequantize. - * Note this is allmost identical to mjpeg - */ -static int decode_i_block(FourXContext *f, DCTELEM *block){ - int code, i, j, level, val; - - /* DC coef */ - val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); - if (val>>4){ - av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n"); - } - - if(val) - val = get_xbits(&f->gb, val); - - val = val * dequant_table[0] + f->last_dc; - f->last_dc = - block[0] = val; - /* AC coefs */ - i = 1; - for(;;) { - code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); - - /* EOB */ - if (code == 0) - break; - if (code == 0xf0) { - i += 16; - } else { - level = get_xbits(&f->gb, code & 0xf); - i += code >> 4; - if (i >= 64) { - av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i); - return 0; - } - - j= ff_zigzag_direct[i]; - block[j] = level * dequant_table[j]; - i++; - if (i >= 64) - break; - } - } - - return 0; -} - -static inline void idct_put(FourXContext *f, int x, int y){ - DCTELEM (*block)[64]= f->block; - int stride= f->current_picture.linesize[0]>>1; - int i; - uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x; - - for(i=0; i<4; i++){ - block[i][0] += 0x80*8*8; - idct(block[i]); - } - - if(!(f->avctx->flags&CODEC_FLAG_GRAY)){ - for(i=4; i<6; i++) idct(block[i]); - } - -/* Note transform is: -y= ( 1b + 4g + 2r)/14 -cb=( 3b - 2g - 1r)/14 -cr=(-1b - 4g + 5r)/14 -*/ - for(y=0; y<8; y++){ - for(x=0; x<8; x++){ - DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize - int cb= block[4][x + 8*y]; - int cr= block[5][x + 8*y]; - int cg= (cb + cr)>>1; - int y; - - cb+=cb; - - y = temp[0]; - dst[0 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); - y = temp[1]; - dst[1 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); - y = temp[8]; - dst[ stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); - y = temp[9]; - dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); - dst += 2; - } - dst += 2*stride - 2*8; - } -} - -static int decode_i_mb(FourXContext *f){ - int i; - - f->dsp.clear_blocks(f->block[0]); - - for(i=0; i<6; i++){ - if(decode_i_block(f, f->block[i]) < 0) - return -1; - } - - return 0; -} - -static uint8_t *read_huffman_tables(FourXContext *f, uint8_t * const buf){ - int frequency[512]; - uint8_t flag[512]; - int up[512]; - uint8_t len_tab[257]; - int bits_tab[257]; - int start, end; - uint8_t *ptr= buf; - int j; - - memset(frequency, 0, sizeof(frequency)); - memset(up, -1, sizeof(up)); - - start= *ptr++; - end= *ptr++; - for(;;){ - int i; - - for(i=start; i<=end; i++){ - frequency[i]= *ptr++; -// printf("%d %d %d\n", start, end, frequency[i]); - } - start= *ptr++; - if(start==0) break; - - end= *ptr++; - } - frequency[256]=1; - - while((ptr - buf)&3) ptr++; // 4byte align - -// for(j=0; j<16; j++) -// printf("%2X", ptr[j]); - - for(j=257; j<512; j++){ - int min_freq[2]= {256*256, 256*256}; - int smallest[2]= {0, 0}; - int i; - for(i=0; i 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ? - } - - bits_tab[j]= bits; - len_tab[j]= len; - } - - init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, - len_tab , 1, 1, - bits_tab, 4, 4, 0); - - return ptr; -} - -static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){ - int x, y; - const int width= f->avctx->width; - const int height= f->avctx->height; - uint16_t *dst= (uint16_t*)f->current_picture.data[0]; - const int stride= f->current_picture.linesize[0]>>1; - const unsigned int bitstream_size= get32(buf); - const int token_count __attribute__((unused)) = get32(buf + bitstream_size + 8); - unsigned int prestream_size= 4*get32(buf + bitstream_size + 4); - uint8_t *prestream= buf + bitstream_size + 12; - - if(prestream_size + bitstream_size + 12 != length - || bitstream_size > (1<<26) - || prestream_size > (1<<26)){ - av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); - return -1; - } - - prestream= read_huffman_tables(f, prestream); - - init_get_bits(&f->gb, buf + 4, 8*bitstream_size); - - prestream_size= length + buf - prestream; - - f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE); - f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)prestream, prestream_size/4); - init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size); - - f->last_dc= 0*128*8*8; - - for(y=0; ypre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256) - av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n"); - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - FourXContext * const f = avctx->priv_data; - AVFrame *picture = data; - AVFrame *p, temp; - int i, frame_4cc, frame_size; - - frame_4cc= get32(buf); - if(buf_size != get32(buf+4)+8 || buf_size < 20){ - av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, get32(buf+4)); - } - - if(frame_4cc == ff_get_fourcc("cfrm")){ - int free_index=-1; - const int data_size= buf_size - 20; - const int id= get32(buf+12); - const int whole_size= get32(buf+16); - CFrameBuffer *cfrm; - - for(i=0; icfrm[i].id && f->cfrm[i].id < avctx->frame_number) - av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id); - } - - for(i=0; icfrm[i].id == id) break; - if(f->cfrm[i].size == 0 ) free_index= i; - } - - if(i>=CFRAME_BUFFER_COUNT){ - i= free_index; - f->cfrm[i].id= id; - } - cfrm= &f->cfrm[i]; - - cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE); - if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL - av_log(f->avctx, AV_LOG_ERROR, "realloc falure"); - return -1; - } - - memcpy(cfrm->data + cfrm->size, buf+20, data_size); - cfrm->size += data_size; - - if(cfrm->size >= whole_size){ - buf= cfrm->data; - frame_size= cfrm->size; - - if(id != avctx->frame_number){ - av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number); - } - - cfrm->size= cfrm->id= 0; - frame_4cc= ff_get_fourcc("pfrm"); - }else - return buf_size; - }else{ - buf= buf + 12; - frame_size= buf_size - 12; - } - - temp= f->current_picture; - f->current_picture= f->last_picture; - f->last_picture= temp; - - p= &f->current_picture; - avctx->coded_frame= p; - - avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management - - if(p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference= 1; - if(avctx->get_buffer(avctx, p) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - if(frame_4cc == ff_get_fourcc("ifrm")){ - p->pict_type= I_TYPE; - if(decode_i_frame(f, buf, frame_size) < 0) - return -1; - }else if(frame_4cc == ff_get_fourcc("pfrm")){ - p->pict_type= P_TYPE; - if(decode_p_frame(f, buf, frame_size) < 0) - return -1; - }else if(frame_4cc == ff_get_fourcc("snd_")){ - av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size); - }else{ - av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size); - } - -#if 0 -for(i=0; i<20; i++){ - printf("%2X %c ", buf[i], clip(buf[i],16,126)); -} -#endif - - p->key_frame= p->pict_type == I_TYPE; - - *picture= *p; - *data_size = sizeof(AVPicture); - - emms_c(); - - return buf_size; -} - - -static void common_init(AVCodecContext *avctx){ - FourXContext * const f = avctx->priv_data; - - dsputil_init(&f->dsp, avctx); - - f->avctx= avctx; -} - -static int decode_init(AVCodecContext *avctx){ - FourXContext * const f = avctx->priv_data; - - common_init(avctx); - init_vlcs(f); - - avctx->pix_fmt= PIX_FMT_RGB565; - - return 0; -} - - -static int decode_end(AVCodecContext *avctx){ - FourXContext * const f = avctx->priv_data; - int i; - - av_freep(&f->bitstream_buffer); - f->bitstream_buffer_size=0; - for(i=0; icfrm[i].data); - f->cfrm[i].allocated_size= 0; - } - free_vlc(&f->pre_vlc); - - return 0; -} - -AVCodec fourxm_decoder = { - "4xm", - CODEC_TYPE_VIDEO, - CODEC_ID_4XM, - sizeof(FourXContext), - decode_init, - NULL, - decode_end, - decode_frame, - /*CODEC_CAP_DR1,*/ -}; - diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/8bps.c --- a/src/ffmpeg/libavcodec/8bps.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -/* - * Quicktime Planar RGB (8BPS) Video Decoder - * Copyright (C) 2003 Roberto Togni - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/** - * @file 8bps.c - * QT 8BPS Video Decoder by Roberto Togni - * For more information about the 8BPS format, visit: - * http://www.pcisys.net/~melanson/codecs/ - * - * Supports: PAL8 (RGB 8bpp, paletted) - * : BGR24 (RGB 24bpp) (can also output it as RGBA32) - * : RGBA32 (RGB 32bpp, 4th plane is probably alpha and it's ignored) - * - */ - -#include -#include - -#include "common.h" -#include "avcodec.h" - - -const enum PixelFormat pixfmt_rgb24[] = {PIX_FMT_BGR24, PIX_FMT_RGBA32, -1}; - -/* - * Decoder context - */ -typedef struct EightBpsContext { - - AVCodecContext *avctx; - AVFrame pic; - - unsigned char planes; - unsigned char planemap[4]; -} EightBpsContext; - - -/* - * - * Decode a frame - * - */ -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) -{ - EightBpsContext * const c = (EightBpsContext *)avctx->priv_data; - unsigned char *encoded = (unsigned char *)buf; - unsigned char *pixptr, *pixptr_end; - unsigned int height = avctx->height; // Real image height - unsigned int dlen, p, row; - unsigned char *lp, *dp; - unsigned char count; - unsigned int px_inc; - unsigned int planes = c->planes; - unsigned char *planemap = c->planemap; - - if(c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - c->pic.reference = 0; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; - if(avctx->get_buffer(avctx, &c->pic) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - /* Set data pointer after line lengths */ - dp = encoded + planes * (height << 1); - - /* Ignore alpha plane, don't know what to do with it */ - if (planes == 4) - planes--; - - px_inc = planes + (avctx->pix_fmt == PIX_FMT_RGBA32); - - for (p = 0; p < planes; p++) { - /* Lines length pointer for this plane */ - lp = encoded + p * (height << 1); - - /* Decode a plane */ - for(row = 0; row < height; row++) { - pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p]; - pixptr_end = pixptr + c->pic.linesize[0]; - dlen = be2me_16(*(unsigned short *)(lp+row*2)); - /* Decode a row of this plane */ - while(dlen > 0) { - if(dp + 1 >= buf+buf_size) return -1; - if ((count = *dp++) <= 127) { - count++; - dlen -= count + 1; - if (pixptr + count * px_inc > pixptr_end) - break; - if(dp + count > buf+buf_size) return -1; - while(count--) { - *pixptr = *dp++; - pixptr += px_inc; - } - } else { - count = 257 - count; - if (pixptr + count * px_inc > pixptr_end) - break; - while(count--) { - *pixptr = *dp; - pixptr += px_inc; - } - dp++; - dlen -= 2; - } - } - } - } - - if (avctx->palctrl) { - memcpy (c->pic.data[1], avctx->palctrl->palette, AVPALETTE_SIZE); - if (avctx->palctrl->palette_changed) { - c->pic.palette_has_changed = 1; - avctx->palctrl->palette_changed = 0; - } else - c->pic.palette_has_changed = 0; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; - - /* always report that the buffer was completely consumed */ - return buf_size; -} - - -/* - * - * Init 8BPS decoder - * - */ -static int decode_init(AVCodecContext *avctx) -{ - EightBpsContext * const c = (EightBpsContext *)avctx->priv_data; - - c->avctx = avctx; - avctx->has_b_frames = 0; - - c->pic.data[0] = NULL; - - if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { - return 1; - } - - switch (avctx->bits_per_sample) { - case 8: - avctx->pix_fmt = PIX_FMT_PAL8; - c->planes = 1; - c->planemap[0] = 0; // 1st plane is palette indexes - if (avctx->palctrl == NULL) { - av_log(avctx, AV_LOG_ERROR, "Error: PAL8 format but no palette from demuxer.\n"); - return -1; - } - break; - case 24: - avctx->pix_fmt = avctx->get_format(avctx, pixfmt_rgb24); - c->planes = 3; - c->planemap[0] = 2; // 1st plane is red - c->planemap[1] = 1; // 2nd plane is green - c->planemap[2] = 0; // 3rd plane is blue - break; - case 32: - avctx->pix_fmt = PIX_FMT_RGBA32; - c->planes = 4; -#ifdef WORDS_BIGENDIAN - c->planemap[0] = 1; // 1st plane is red - c->planemap[1] = 2; // 2nd plane is green - c->planemap[2] = 3; // 3rd plane is blue - c->planemap[3] = 0; // 4th plane is alpha??? -#else - c->planemap[0] = 2; // 1st plane is red - c->planemap[1] = 1; // 2nd plane is green - c->planemap[2] = 0; // 3rd plane is blue - c->planemap[3] = 3; // 4th plane is alpha??? -#endif - break; - default: - av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n", avctx->bits_per_sample); - return -1; - } - - return 0; -} - - - - -/* - * - * Uninit 8BPS decoder - * - */ -static int decode_end(AVCodecContext *avctx) -{ - EightBpsContext * const c = (EightBpsContext *)avctx->priv_data; - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - - - -AVCodec eightbps_decoder = { - "8bps", - CODEC_TYPE_VIDEO, - CODEC_ID_8BPS, - sizeof(EightBpsContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, -}; diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/Makefile --- a/src/ffmpeg/libavcodec/Makefile Mon Mar 12 13:00:06 2007 -0700 +++ b/src/ffmpeg/libavcodec/Makefile Mon Mar 12 13:06:30 2007 -0700 @@ -4,30 +4,28 @@ OBJECTIVE_LIBS_NOINST= libavcodec.a SOURCES = \ -4xm.c raw.c \ -8bps.c resample.c \ -resample2.c \ + raw.c \ + resample.c \ + resample2.c \ aasc.c \ rpza.c \ -ac3enc.c huffyuv.c rtjpeg.c \ +ac3enc.c \ adpcm.c \ -adx.c imgconvert.c shorten.c \ -alac.c imgresample.c simple_idct.c \ +adx.c shorten.c \ +alac.c simple_idct.c \ allcodecs.c \ smc.c \ apiexample.c \ -asv1.c jfdctfst.c sonic.c \ -audioconvert.c jfdctint.c \ +sonic.c \ +audioconvert.c \ avs.c \ -jrevdct.c targa.c \ bitstream.c kmvc.c \ -bitstream_filter.c lcl.c tiff.c \ +bitstream_filter.c lcl.c \ bmp.c \ cabac.c loco.c \ -cavs.c lzo.c truespeech.c \ -cavsdsp.c mace.c tscc.c \ +lzo.c truespeech.c \ +mace.c tscc.c \ mdct.c tta.c \ -cljr.c \ cook.c utils.c \ cscd.c \ cyuv.c \ diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/asv1.c --- a/src/ffmpeg/libavcodec/asv1.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,655 +0,0 @@ -/* - * ASUS V1/V2 codec - * Copyright (c) 2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file asv1.c - * ASUS V1/V2 codec. - */ - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" - -//#undef NDEBUG -//#include - -#define VLC_BITS 6 -#define ASV2_LEVEL_VLC_BITS 10 - -typedef struct ASV1Context{ - AVCodecContext *avctx; - DSPContext dsp; - AVFrame picture; - PutBitContext pb; - GetBitContext gb; - ScanTable scantable; - int inv_qscale; - int mb_width; - int mb_height; - int mb_width2; - int mb_height2; - DECLARE_ALIGNED_8(DCTELEM, block[6][64]); - DECLARE_ALIGNED_8(uint16_t, intra_matrix[64]); - DECLARE_ALIGNED_8(int, q_intra_matrix[64]); - uint8_t *bitstream_buffer; - unsigned int bitstream_buffer_size; -} ASV1Context; - -static const uint8_t scantab[64]={ - 0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19, - 0x02,0x0A,0x03,0x0B,0x12,0x1A,0x13,0x1B, - 0x04,0x0C,0x05,0x0D,0x20,0x28,0x21,0x29, - 0x06,0x0E,0x07,0x0F,0x14,0x1C,0x15,0x1D, - 0x22,0x2A,0x23,0x2B,0x30,0x38,0x31,0x39, - 0x16,0x1E,0x17,0x1F,0x24,0x2C,0x25,0x2D, - 0x32,0x3A,0x33,0x3B,0x26,0x2E,0x27,0x2F, - 0x34,0x3C,0x35,0x3D,0x36,0x3E,0x37,0x3F, -}; - - -static const uint8_t ccp_tab[17][2]={ - {0x2,2}, {0x7,5}, {0xB,5}, {0x3,5}, - {0xD,5}, {0x5,5}, {0x9,5}, {0x1,5}, - {0xE,5}, {0x6,5}, {0xA,5}, {0x2,5}, - {0xC,5}, {0x4,5}, {0x8,5}, {0x3,2}, - {0xF,5}, //EOB -}; - -static const uint8_t level_tab[7][2]={ - {3,4}, {3,3}, {3,2}, {0,3}, {2,2}, {2,3}, {2,4} -}; - -static const uint8_t dc_ccp_tab[8][2]={ - {0x1,2}, {0xD,4}, {0xF,4}, {0xC,4}, - {0x5,3}, {0xE,4}, {0x4,3}, {0x0,2}, -}; - -static const uint8_t ac_ccp_tab[16][2]={ - {0x00,2}, {0x3B,6}, {0x0A,4}, {0x3A,6}, - {0x02,3}, {0x39,6}, {0x3C,6}, {0x38,6}, - {0x03,3}, {0x3D,6}, {0x08,4}, {0x1F,5}, - {0x09,4}, {0x0B,4}, {0x0D,4}, {0x0C,4}, -}; - -static const uint8_t asv2_level_tab[63][2]={ - {0x3F,10},{0x2F,10},{0x37,10},{0x27,10},{0x3B,10},{0x2B,10},{0x33,10},{0x23,10}, - {0x3D,10},{0x2D,10},{0x35,10},{0x25,10},{0x39,10},{0x29,10},{0x31,10},{0x21,10}, - {0x1F, 8},{0x17, 8},{0x1B, 8},{0x13, 8},{0x1D, 8},{0x15, 8},{0x19, 8},{0x11, 8}, - {0x0F, 6},{0x0B, 6},{0x0D, 6},{0x09, 6}, - {0x07, 4},{0x05, 4}, - {0x03, 2}, - {0x00, 5}, - {0x02, 2}, - {0x04, 4},{0x06, 4}, - {0x08, 6},{0x0C, 6},{0x0A, 6},{0x0E, 6}, - {0x10, 8},{0x18, 8},{0x14, 8},{0x1C, 8},{0x12, 8},{0x1A, 8},{0x16, 8},{0x1E, 8}, - {0x20,10},{0x30,10},{0x28,10},{0x38,10},{0x24,10},{0x34,10},{0x2C,10},{0x3C,10}, - {0x22,10},{0x32,10},{0x2A,10},{0x3A,10},{0x26,10},{0x36,10},{0x2E,10},{0x3E,10}, -}; - - -static VLC ccp_vlc; -static VLC level_vlc; -static VLC dc_ccp_vlc; -static VLC ac_ccp_vlc; -static VLC asv2_level_vlc; - -static void init_vlcs(ASV1Context *a){ - static int done = 0; - - if (!done) { - done = 1; - - init_vlc(&ccp_vlc, VLC_BITS, 17, - &ccp_tab[0][1], 2, 1, - &ccp_tab[0][0], 2, 1, 1); - init_vlc(&dc_ccp_vlc, VLC_BITS, 8, - &dc_ccp_tab[0][1], 2, 1, - &dc_ccp_tab[0][0], 2, 1, 1); - init_vlc(&ac_ccp_vlc, VLC_BITS, 16, - &ac_ccp_tab[0][1], 2, 1, - &ac_ccp_tab[0][0], 2, 1, 1); - init_vlc(&level_vlc, VLC_BITS, 7, - &level_tab[0][1], 2, 1, - &level_tab[0][0], 2, 1, 1); - init_vlc(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63, - &asv2_level_tab[0][1], 2, 1, - &asv2_level_tab[0][0], 2, 1, 1); - } -} - -//FIXME write a reversed bitstream reader to avoid the double reverse -static inline int asv2_get_bits(GetBitContext *gb, int n){ - return ff_reverse[ get_bits(gb, n) << (8-n) ]; -} - -static inline void asv2_put_bits(PutBitContext *pb, int n, int v){ - put_bits(pb, n, ff_reverse[ v << (8-n) ]); -} - -static inline int asv1_get_level(GetBitContext *gb){ - int code= get_vlc2(gb, level_vlc.table, VLC_BITS, 1); - - if(code==3) return get_sbits(gb, 8); - else return code - 3; -} - -static inline int asv2_get_level(GetBitContext *gb){ - int code= get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1); - - if(code==31) return (int8_t)asv2_get_bits(gb, 8); - else return code - 31; -} - -static inline void asv1_put_level(PutBitContext *pb, int level){ - unsigned int index= level + 3; - - if(index <= 6) put_bits(pb, level_tab[index][1], level_tab[index][0]); - else{ - put_bits(pb, level_tab[3][1], level_tab[3][0]); - put_bits(pb, 8, level&0xFF); - } -} - -static inline void asv2_put_level(PutBitContext *pb, int level){ - unsigned int index= level + 31; - - if(index <= 62) put_bits(pb, asv2_level_tab[index][1], asv2_level_tab[index][0]); - else{ - put_bits(pb, asv2_level_tab[31][1], asv2_level_tab[31][0]); - asv2_put_bits(pb, 8, level&0xFF); - } -} - -static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64]){ - int i; - - block[0]= 8*get_bits(&a->gb, 8); - - for(i=0; i<11; i++){ - const int ccp= get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1); - - if(ccp){ - if(ccp == 16) break; - if(ccp < 0 || i>=10){ - av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n"); - return -1; - } - - if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; - if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; - if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; - if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; - } - } - - return 0; -} - -static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64]){ - int i, count, ccp; - - count= asv2_get_bits(&a->gb, 4); - - block[0]= 8*asv2_get_bits(&a->gb, 8); - - ccp= get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1); - if(ccp){ - if(ccp&4) block[a->scantable.permutated[1]]= (asv2_get_level(&a->gb) * a->intra_matrix[1])>>4; - if(ccp&2) block[a->scantable.permutated[2]]= (asv2_get_level(&a->gb) * a->intra_matrix[2])>>4; - if(ccp&1) block[a->scantable.permutated[3]]= (asv2_get_level(&a->gb) * a->intra_matrix[3])>>4; - } - - for(i=1; igb, ac_ccp_vlc.table, VLC_BITS, 1); - - if(ccp){ - if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; - if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; - if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; - if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; - } - } - - return 0; -} - -static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){ - int i; - int nc_count=0; - - put_bits(&a->pb, 8, (block[0] + 32)>>6); - block[0]= 0; - - for(i=0; i<10; i++){ - const int index= scantab[4*i]; - int ccp=0; - - if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; - if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; - if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; - if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; - - if(ccp){ - for(;nc_count; nc_count--) - put_bits(&a->pb, ccp_tab[0][1], ccp_tab[0][0]); - - put_bits(&a->pb, ccp_tab[ccp][1], ccp_tab[ccp][0]); - - if(ccp&8) asv1_put_level(&a->pb, block[index + 0]); - if(ccp&4) asv1_put_level(&a->pb, block[index + 8]); - if(ccp&2) asv1_put_level(&a->pb, block[index + 1]); - if(ccp&1) asv1_put_level(&a->pb, block[index + 9]); - }else{ - nc_count++; - } - } - put_bits(&a->pb, ccp_tab[16][1], ccp_tab[16][0]); -} - -static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){ - int i; - int count=0; - - for(count=63; count>3; count--){ - const int index= scantab[count]; - - if( (block[index]*a->q_intra_matrix[index] + (1<<15))>>16 ) - break; - } - - count >>= 2; - - asv2_put_bits(&a->pb, 4, count); - asv2_put_bits(&a->pb, 8, (block[0] + 32)>>6); - block[0]= 0; - - for(i=0; i<=count; i++){ - const int index= scantab[4*i]; - int ccp=0; - - if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; - if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; - if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; - if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; - - assert(i || ccp<8); - if(i) put_bits(&a->pb, ac_ccp_tab[ccp][1], ac_ccp_tab[ccp][0]); - else put_bits(&a->pb, dc_ccp_tab[ccp][1], dc_ccp_tab[ccp][0]); - - if(ccp){ - if(ccp&8) asv2_put_level(&a->pb, block[index + 0]); - if(ccp&4) asv2_put_level(&a->pb, block[index + 8]); - if(ccp&2) asv2_put_level(&a->pb, block[index + 1]); - if(ccp&1) asv2_put_level(&a->pb, block[index + 9]); - } - } -} - -static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){ - int i; - - a->dsp.clear_blocks(block[0]); - - if(a->avctx->codec_id == CODEC_ID_ASV1){ - for(i=0; i<6; i++){ - if( asv1_decode_block(a, block[i]) < 0) - return -1; - } - }else{ - for(i=0; i<6; i++){ - if( asv2_decode_block(a, block[i]) < 0) - return -1; - } - } - return 0; -} - -static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){ - int i; - - if(a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < 30*16*16*3/2/8){ - av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - if(a->avctx->codec_id == CODEC_ID_ASV1){ - for(i=0; i<6; i++) - asv1_encode_block(a, block[i]); - }else{ - for(i=0; i<6; i++) - asv2_encode_block(a, block[i]); - } - return 0; -} - -static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){ - DCTELEM (*block)[64]= a->block; - int linesize= a->picture.linesize[0]; - - uint8_t *dest_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; - uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; - uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; - - a->dsp.idct_put(dest_y , linesize, block[0]); - a->dsp.idct_put(dest_y + 8, linesize, block[1]); - a->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); - a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); - - if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ - a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]); - a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]); - } -} - -static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ - DCTELEM (*block)[64]= a->block; - int linesize= a->picture.linesize[0]; - int i; - - uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; - uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; - uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; - - a->dsp.get_pixels(block[0], ptr_y , linesize); - a->dsp.get_pixels(block[1], ptr_y + 8, linesize); - a->dsp.get_pixels(block[2], ptr_y + 8*linesize , linesize); - a->dsp.get_pixels(block[3], ptr_y + 8*linesize + 8, linesize); - for(i=0; i<4; i++) - a->dsp.fdct(block[i]); - - if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ - a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]); - a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]); - for(i=4; i<6; i++) - a->dsp.fdct(block[i]); - } -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - ASV1Context * const a = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&a->picture; - int mb_x, mb_y; - - if(p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference= 0; - if(avctx->get_buffer(avctx, p) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - p->pict_type= I_TYPE; - p->key_frame= 1; - - a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - - if(avctx->codec_id == CODEC_ID_ASV1) - a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (uint32_t*)buf, buf_size/4); - else{ - int i; - for(i=0; ibitstream_buffer[i]= ff_reverse[ buf[i] ]; - } - - init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8); - - for(mb_y=0; mb_ymb_height2; mb_y++){ - for(mb_x=0; mb_xmb_width2; mb_x++){ - if( decode_mb(a, a->block) <0) - return -1; - - idct_put(a, mb_x, mb_y); - } - } - - if(a->mb_width2 != a->mb_width){ - mb_x= a->mb_width2; - for(mb_y=0; mb_ymb_height2; mb_y++){ - if( decode_mb(a, a->block) <0) - return -1; - - idct_put(a, mb_x, mb_y); - } - } - - if(a->mb_height2 != a->mb_height){ - mb_y= a->mb_height2; - for(mb_x=0; mb_xmb_width; mb_x++){ - if( decode_mb(a, a->block) <0) - return -1; - - idct_put(a, mb_x, mb_y); - } - } -#if 0 -int i; -printf("%d %d\n", 8*buf_size, get_bits_count(&a->gb)); -for(i=get_bits_count(&a->gb); i<8*buf_size; i++){ - printf("%d", get_bits1(&a->gb)); -} - -for(i=0; iavctx->extradata_size; i++){ - printf("%c\n", ((uint8_t*)s->avctx->extradata)[i]); -} -#endif - - *picture= *(AVFrame*)&a->picture; - *data_size = sizeof(AVPicture); - - emms_c(); - - return (get_bits_count(&a->gb)+31)/32*4; -} - -#ifdef CONFIG_ENCODERS -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - ASV1Context * const a = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&a->picture; - int size; - int mb_x, mb_y; - - init_put_bits(&a->pb, buf, buf_size); - - *p = *pict; - p->pict_type= I_TYPE; - p->key_frame= 1; - - for(mb_y=0; mb_ymb_height2; mb_y++){ - for(mb_x=0; mb_xmb_width2; mb_x++){ - dct_get(a, mb_x, mb_y); - encode_mb(a, a->block); - } - } - - if(a->mb_width2 != a->mb_width){ - mb_x= a->mb_width2; - for(mb_y=0; mb_ymb_height2; mb_y++){ - dct_get(a, mb_x, mb_y); - encode_mb(a, a->block); - } - } - - if(a->mb_height2 != a->mb_height){ - mb_y= a->mb_height2; - for(mb_x=0; mb_xmb_width; mb_x++){ - dct_get(a, mb_x, mb_y); - encode_mb(a, a->block); - } - } - emms_c(); - - align_put_bits(&a->pb); - while(put_bits_count(&a->pb)&31) - put_bits(&a->pb, 8, 0); - - size= put_bits_count(&a->pb)/32; - - if(avctx->codec_id == CODEC_ID_ASV1) - a->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); - else{ - int i; - for(i=0; i<4*size; i++) - buf[i]= ff_reverse[ buf[i] ]; - } - - return size*4; -} -#endif /* CONFIG_ENCODERS */ - -static void common_init(AVCodecContext *avctx){ - ASV1Context * const a = avctx->priv_data; - - dsputil_init(&a->dsp, avctx); - - a->mb_width = (avctx->width + 15) / 16; - a->mb_height = (avctx->height + 15) / 16; - a->mb_width2 = (avctx->width + 0) / 16; - a->mb_height2 = (avctx->height + 0) / 16; - - avctx->coded_frame= (AVFrame*)&a->picture; - a->avctx= avctx; -} - -static int decode_init(AVCodecContext *avctx){ - ASV1Context * const a = avctx->priv_data; - AVFrame *p= (AVFrame*)&a->picture; - int i; - const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; - - common_init(avctx); - init_vlcs(a); - ff_init_scantable(a->dsp.idct_permutation, &a->scantable, scantab); - avctx->pix_fmt= PIX_FMT_YUV420P; - - a->inv_qscale= ((uint8_t*)avctx->extradata)[0]; - if(a->inv_qscale == 0){ - av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n"); - if(avctx->codec_id == CODEC_ID_ASV1) - a->inv_qscale= 6; - else - a->inv_qscale= 10; - } - - for(i=0; i<64; i++){ - int index= scantab[i]; - - a->intra_matrix[i]= 64*scale*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale; - } - - p->qstride= a->mb_width; - p->qscale_table= av_malloc( p->qstride * a->mb_height); - p->quality= (32*scale + a->inv_qscale/2)/a->inv_qscale; - memset(p->qscale_table, p->quality, p->qstride*a->mb_height); - - return 0; -} - -#ifdef CONFIG_ENCODERS -static int encode_init(AVCodecContext *avctx){ - ASV1Context * const a = avctx->priv_data; - int i; - const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; - - common_init(avctx); - - if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE; - - a->inv_qscale= (32*scale*FF_QUALITY_SCALE + avctx->global_quality/2) / avctx->global_quality; - - avctx->extradata= av_mallocz(8); - avctx->extradata_size=8; - ((uint32_t*)avctx->extradata)[0]= le2me_32(a->inv_qscale); - ((uint32_t*)avctx->extradata)[1]= le2me_32(ff_get_fourcc("ASUS")); - - for(i=0; i<64; i++){ - int q= 32*scale*ff_mpeg1_default_intra_matrix[i]; - a->q_intra_matrix[i]= ((a->inv_qscale<<16) + q/2) / q; - } - - return 0; -} -#endif - -static int decode_end(AVCodecContext *avctx){ - ASV1Context * const a = avctx->priv_data; - - av_freep(&a->bitstream_buffer); - av_freep(&a->picture.qscale_table); - a->bitstream_buffer_size=0; - - return 0; -} - -AVCodec asv1_decoder = { - "asv1", - CODEC_TYPE_VIDEO, - CODEC_ID_ASV1, - sizeof(ASV1Context), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, -}; - -AVCodec asv2_decoder = { - "asv2", - CODEC_TYPE_VIDEO, - CODEC_ID_ASV2, - sizeof(ASV1Context), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, -}; - -#ifdef CONFIG_ENCODERS - -AVCodec asv1_encoder = { - "asv1", - CODEC_TYPE_VIDEO, - CODEC_ID_ASV1, - sizeof(ASV1Context), - encode_init, - encode_frame, - //encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -AVCodec asv2_encoder = { - "asv2", - CODEC_TYPE_VIDEO, - CODEC_ID_ASV2, - sizeof(ASV1Context), - encode_init, - encode_frame, - //encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -#endif //CONFIG_ENCODERS diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/cavs.c --- a/src/ffmpeg/libavcodec/cavs.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1502 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. - * Copyright (c) 2006 Stefan Gehrer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file cavs.c - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder - * @author Stefan Gehrer - */ - -#include "avcodec.h" -#include "bitstream.h" -#include "golomb.h" -#include "mpegvideo.h" -#include "cavsdata.h" - -typedef struct { - MpegEncContext s; - Picture picture; ///< currently decoded frame - Picture DPB[2]; ///< reference frames - int dist[2]; ///< temporal distances from current frame to ref frames - int profile, level; - int aspect_ratio; - int mb_width, mb_height; - int pic_type; - int progressive; - int pic_structure; - int skip_mode_flag; ///< select between skip_count or one skip_flag per MB - int loop_filter_disable; - int alpha_offset, beta_offset; - int ref_flag; - int mbx, mby; ///< macroblock coordinates - int flags; ///< availability flags of neighbouring macroblocks - int stc; ///< last start code - uint8_t *cy, *cu, *cv; ///< current MB sample pointers - int left_qp; - uint8_t *top_qp; - - /** mv motion vector cache - 0: D3 B2 B3 C2 - 4: A1 X0 X1 - - 8: A3 X2 X3 - - - X are the vectors in the current macroblock (5,6,9,10) - A is the macroblock to the left (4,8) - B is the macroblock to the top (1,2) - C is the macroblock to the top-right (3) - D is the macroblock to the top-left (0) - - the same is repeated for backward motion vectors */ - vector_t mv[2*4*3]; - vector_t *top_mv[2]; - vector_t *col_mv; - - /** luma pred mode cache - 0: -- B2 B3 - 3: A1 X0 X1 - 6: A3 X2 X3 */ - int pred_mode_Y[3*3]; - int *top_pred_Y; - int l_stride, c_stride; - int luma_scan[4]; - int qp; - int qp_fixed; - int cbp; - ScanTable scantable; - - /** intra prediction is done with un-deblocked samples - they are saved here before deblocking the MB */ - uint8_t *top_border_y, *top_border_u, *top_border_v; - uint8_t left_border_y[26], left_border_u[10], left_border_v[10]; - uint8_t intern_border_y[26]; - uint8_t topleft_border_y, topleft_border_u, topleft_border_v; - - void (*intra_pred_l[8])(uint8_t *d,uint8_t *top,uint8_t *left,int stride); - void (*intra_pred_c[7])(uint8_t *d,uint8_t *top,uint8_t *left,int stride); - uint8_t *col_type_base; - uint8_t *col_type; - - /* scaling factors for MV prediction */ - int sym_factor; ///< for scaling in symmetrical B block - int direct_den[2]; ///< for scaling in direct B block - int scale_den[2]; ///< for scaling neighbouring MVs - - int got_keyframe; - DCTELEM *block; -} AVSContext; - -/***************************************************************************** - * - * in-loop deblocking filter - * - ****************************************************************************/ - -static inline int get_bs(vector_t *mvP, vector_t *mvQ, int b) { - if((mvP->ref == REF_INTRA) || (mvQ->ref == REF_INTRA)) - return 2; - if( (abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4) ) - return 1; - if(b){ - mvP += MV_BWD_OFFS; - mvQ += MV_BWD_OFFS; - if( (abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4) ) - return 1; - }else{ - if(mvP->ref != mvQ->ref) - return 1; - } - return 0; -} - -#define SET_PARAMS \ - alpha = alpha_tab[clip(qp_avg + h->alpha_offset,0,63)]; \ - beta = beta_tab[clip(qp_avg + h->beta_offset, 0,63)]; \ - tc = tc_tab[clip(qp_avg + h->alpha_offset,0,63)]; - -/** - * in-loop deblocking filter for a single macroblock - * - * boundary strength (bs) mapping: - * - * --4---5-- - * 0 2 | - * | 6 | 7 | - * 1 3 | - * --------- - * - */ -static void filter_mb(AVSContext *h, enum mb_t mb_type) { - DECLARE_ALIGNED_8(uint8_t, bs[8]); - int qp_avg, alpha, beta, tc; - int i; - - /* save un-deblocked lines */ - h->topleft_border_y = h->top_border_y[h->mbx*16+15]; - h->topleft_border_u = h->top_border_u[h->mbx*10+8]; - h->topleft_border_v = h->top_border_v[h->mbx*10+8]; - memcpy(&h->top_border_y[h->mbx*16], h->cy + 15* h->l_stride,16); - memcpy(&h->top_border_u[h->mbx*10+1], h->cu + 7* h->c_stride,8); - memcpy(&h->top_border_v[h->mbx*10+1], h->cv + 7* h->c_stride,8); - for(i=0;i<8;i++) { - h->left_border_y[i*2+1] = *(h->cy + 15 + (i*2+0)*h->l_stride); - h->left_border_y[i*2+2] = *(h->cy + 15 + (i*2+1)*h->l_stride); - h->left_border_u[i+1] = *(h->cu + 7 + i*h->c_stride); - h->left_border_v[i+1] = *(h->cv + 7 + i*h->c_stride); - } - if(!h->loop_filter_disable) { - /* determine bs */ - if(mb_type == I_8X8) - *((uint64_t *)bs) = 0x0202020202020202ULL; - else{ - *((uint64_t *)bs) = 0; - if(partition_flags[mb_type] & SPLITV){ - bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8); - bs[3] = get_bs(&h->mv[MV_FWD_X2], &h->mv[MV_FWD_X3], mb_type > P_8X8); - } - if(partition_flags[mb_type] & SPLITH){ - bs[6] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X2], mb_type > P_8X8); - bs[7] = get_bs(&h->mv[MV_FWD_X1], &h->mv[MV_FWD_X3], mb_type > P_8X8); - } - bs[0] = get_bs(&h->mv[MV_FWD_A1], &h->mv[MV_FWD_X0], mb_type > P_8X8); - bs[1] = get_bs(&h->mv[MV_FWD_A3], &h->mv[MV_FWD_X2], mb_type > P_8X8); - bs[4] = get_bs(&h->mv[MV_FWD_B2], &h->mv[MV_FWD_X0], mb_type > P_8X8); - bs[5] = get_bs(&h->mv[MV_FWD_B3], &h->mv[MV_FWD_X1], mb_type > P_8X8); - } - if( *((uint64_t *)bs) ) { - if(h->flags & A_AVAIL) { - qp_avg = (h->qp + h->left_qp + 1) >> 1; - SET_PARAMS; - h->s.dsp.cavs_filter_lv(h->cy,h->l_stride,alpha,beta,tc,bs[0],bs[1]); - h->s.dsp.cavs_filter_cv(h->cu,h->c_stride,alpha,beta,tc,bs[0],bs[1]); - h->s.dsp.cavs_filter_cv(h->cv,h->c_stride,alpha,beta,tc,bs[0],bs[1]); - } - qp_avg = h->qp; - SET_PARAMS; - h->s.dsp.cavs_filter_lv(h->cy + 8,h->l_stride,alpha,beta,tc,bs[2],bs[3]); - h->s.dsp.cavs_filter_lh(h->cy + 8*h->l_stride,h->l_stride,alpha,beta,tc, - bs[6],bs[7]); - - if(h->flags & B_AVAIL) { - qp_avg = (h->qp + h->top_qp[h->mbx] + 1) >> 1; - SET_PARAMS; - h->s.dsp.cavs_filter_lh(h->cy,h->l_stride,alpha,beta,tc,bs[4],bs[5]); - h->s.dsp.cavs_filter_ch(h->cu,h->c_stride,alpha,beta,tc,bs[4],bs[5]); - h->s.dsp.cavs_filter_ch(h->cv,h->c_stride,alpha,beta,tc,bs[4],bs[5]); - } - } - } - h->left_qp = h->qp; - h->top_qp[h->mbx] = h->qp; -} - -#undef SET_PARAMS - -/***************************************************************************** - * - * spatial intra prediction - * - ****************************************************************************/ - -static inline void load_intra_pred_luma(AVSContext *h, uint8_t *top, - uint8_t **left, int block) { - int i; - - switch(block) { - case 0: - *left = h->left_border_y; - h->left_border_y[0] = h->left_border_y[1]; - memset(&h->left_border_y[17],h->left_border_y[16],9); - memcpy(&top[1],&h->top_border_y[h->mbx*16],16); - top[17] = top[16]; - top[0] = top[1]; - if((h->flags & A_AVAIL) && (h->flags & B_AVAIL)) - h->left_border_y[0] = top[0] = h->topleft_border_y; - break; - case 1: - *left = h->intern_border_y; - for(i=0;i<8;i++) - h->intern_border_y[i+1] = *(h->cy + 7 + i*h->l_stride); - memset(&h->intern_border_y[9],h->intern_border_y[8],9); - h->intern_border_y[0] = h->intern_border_y[1]; - memcpy(&top[1],&h->top_border_y[h->mbx*16+8],8); - if(h->flags & C_AVAIL) - memcpy(&top[9],&h->top_border_y[(h->mbx + 1)*16],8); - else - memset(&top[9],top[8],9); - top[17] = top[16]; - top[0] = top[1]; - if(h->flags & B_AVAIL) - h->intern_border_y[0] = top[0] = h->top_border_y[h->mbx*16+7]; - break; - case 2: - *left = &h->left_border_y[8]; - memcpy(&top[1],h->cy + 7*h->l_stride,16); - top[17] = top[16]; - top[0] = top[1]; - if(h->flags & A_AVAIL) - top[0] = h->left_border_y[8]; - break; - case 3: - *left = &h->intern_border_y[8]; - for(i=0;i<8;i++) - h->intern_border_y[i+9] = *(h->cy + 7 + (i+8)*h->l_stride); - memset(&h->intern_border_y[17],h->intern_border_y[16],9); - memcpy(&top[0],h->cy + 7 + 7*h->l_stride,9); - memset(&top[9],top[8],9); - break; - } -} - -static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int y; - uint64_t a = unaligned64(&top[1]); - for(y=0;y<8;y++) { - *((uint64_t *)(d+y*stride)) = a; - } -} - -static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int y; - uint64_t a; - for(y=0;y<8;y++) { - a = left[y+1] * 0x0101010101010101ULL; - *((uint64_t *)(d+y*stride)) = a; - } -} - -static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int y; - uint64_t a = 0x8080808080808080ULL; - for(y=0;y<8;y++) - *((uint64_t *)(d+y*stride)) = a; -} - -static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y,ia; - int ih = 0; - int iv = 0; - uint8_t *cm = cropTbl + MAX_NEG_CROP; - - for(x=0; x<4; x++) { - ih += (x+1)*(top[5+x]-top[3-x]); - iv += (x+1)*(left[5+x]-left[3-x]); - } - ia = (top[8]+left[8])<<4; - ih = (17*ih+16)>>5; - iv = (17*iv+16)>>5; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = cm[(ia+(x-3)*ih+(y-3)*iv+16)>>5]; -} - -#define LOWPASS(ARRAY,INDEX) \ - (( ARRAY[(INDEX)-1] + 2*ARRAY[(INDEX)] + ARRAY[(INDEX)+1] + 2) >> 2) - -static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = (LOWPASS(top,x+1) + LOWPASS(left,y+1)) >> 1; -} - -static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = (LOWPASS(top,x+y+2) + LOWPASS(left,x+y+2)) >> 1; -} - -static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - if(x==y) - d[y*stride+x] = (left[1]+2*top[0]+top[1]+2)>>2; - else if(x>y) - d[y*stride+x] = LOWPASS(top,x-y); - else - d[y*stride+x] = LOWPASS(left,y-x); -} - -static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = LOWPASS(left,y+1); -} - -static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { - int x,y; - for(y=0; y<8; y++) - for(x=0; x<8; x++) - d[y*stride+x] = LOWPASS(top,x+1); -} - -#undef LOWPASS - -static inline void modify_pred(const int_fast8_t *mod_table, int *mode) { - *mode = mod_table[*mode]; - if(*mode < 0) { - av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n"); - *mode = 0; - } -} - -/***************************************************************************** - * - * motion compensation - * - ****************************************************************************/ - -static inline void mc_dir_part(AVSContext *h,Picture *pic,int square, - int chroma_height,int delta,int list,uint8_t *dest_y, - uint8_t *dest_cb,uint8_t *dest_cr,int src_x_offset, - int src_y_offset,qpel_mc_func *qpix_op, - h264_chroma_mc_func chroma_op,vector_t *mv){ - MpegEncContext * const s = &h->s; - const int mx= mv->x + src_x_offset*8; - const int my= mv->y + src_y_offset*8; - const int luma_xy= (mx&3) + ((my&3)<<2); - uint8_t * src_y = pic->data[0] + (mx>>2) + (my>>2)*h->l_stride; - uint8_t * src_cb= pic->data[1] + (mx>>3) + (my>>3)*h->c_stride; - uint8_t * src_cr= pic->data[2] + (mx>>3) + (my>>3)*h->c_stride; - int extra_width= 0; //(s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16; - int extra_height= extra_width; - int emu=0; - const int full_mx= mx>>2; - const int full_my= my>>2; - const int pic_width = 16*h->mb_width; - const int pic_height = 16*h->mb_height; - - if(!pic->data[0]) - return; - if(mx&7) extra_width -= 3; - if(my&7) extra_height -= 3; - - if( full_mx < 0-extra_width - || full_my < 0-extra_height - || full_mx + 16/*FIXME*/ > pic_width + extra_width - || full_my + 16/*FIXME*/ > pic_height + extra_height){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*h->l_stride, h->l_stride, - 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height); - src_y= s->edge_emu_buffer + 2 + 2*h->l_stride; - emu=1; - } - - qpix_op[luma_xy](dest_y, src_y, h->l_stride); //FIXME try variable height perhaps? - if(!square){ - qpix_op[luma_xy](dest_y + delta, src_y + delta, h->l_stride); - } - - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, h->c_stride, - 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1); - src_cb= s->edge_emu_buffer; - } - chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx&7, my&7); - - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, h->c_stride, - 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1); - src_cr= s->edge_emu_buffer; - } - chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx&7, my&7); -} - -static inline void mc_part_std(AVSContext *h,int square,int chroma_height,int delta, - uint8_t *dest_y,uint8_t *dest_cb,uint8_t *dest_cr, - int x_offset, int y_offset,qpel_mc_func *qpix_put, - h264_chroma_mc_func chroma_put,qpel_mc_func *qpix_avg, - h264_chroma_mc_func chroma_avg, vector_t *mv){ - qpel_mc_func *qpix_op= qpix_put; - h264_chroma_mc_func chroma_op= chroma_put; - - dest_y += 2*x_offset + 2*y_offset*h->l_stride; - dest_cb += x_offset + y_offset*h->c_stride; - dest_cr += x_offset + y_offset*h->c_stride; - x_offset += 8*h->mbx; - y_offset += 8*h->mby; - - if(mv->ref >= 0){ - Picture *ref= &h->DPB[mv->ref]; - mc_dir_part(h, ref, square, chroma_height, delta, 0, - dest_y, dest_cb, dest_cr, x_offset, y_offset, - qpix_op, chroma_op, mv); - - qpix_op= qpix_avg; - chroma_op= chroma_avg; - } - - if((mv+MV_BWD_OFFS)->ref >= 0){ - Picture *ref= &h->DPB[0]; - mc_dir_part(h, ref, square, chroma_height, delta, 1, - dest_y, dest_cb, dest_cr, x_offset, y_offset, - qpix_op, chroma_op, mv+MV_BWD_OFFS); - } -} - -static void inter_pred(AVSContext *h, enum mb_t mb_type) { - if(partition_flags[mb_type] == 0){ // 16x16 - mc_part_std(h, 1, 8, 0, h->cy, h->cu, h->cv, 0, 0, - h->s.dsp.put_cavs_qpel_pixels_tab[0], - h->s.dsp.put_h264_chroma_pixels_tab[0], - h->s.dsp.avg_cavs_qpel_pixels_tab[0], - h->s.dsp.avg_h264_chroma_pixels_tab[0],&h->mv[MV_FWD_X0]); - }else{ - mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 0, 0, - h->s.dsp.put_cavs_qpel_pixels_tab[1], - h->s.dsp.put_h264_chroma_pixels_tab[1], - h->s.dsp.avg_cavs_qpel_pixels_tab[1], - h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X0]); - mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 4, 0, - h->s.dsp.put_cavs_qpel_pixels_tab[1], - h->s.dsp.put_h264_chroma_pixels_tab[1], - h->s.dsp.avg_cavs_qpel_pixels_tab[1], - h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X1]); - mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 0, 4, - h->s.dsp.put_cavs_qpel_pixels_tab[1], - h->s.dsp.put_h264_chroma_pixels_tab[1], - h->s.dsp.avg_cavs_qpel_pixels_tab[1], - h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X2]); - mc_part_std(h, 1, 4, 0, h->cy, h->cu, h->cv, 4, 4, - h->s.dsp.put_cavs_qpel_pixels_tab[1], - h->s.dsp.put_h264_chroma_pixels_tab[1], - h->s.dsp.avg_cavs_qpel_pixels_tab[1], - h->s.dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X3]); - } - /* set intra prediction modes to default values */ - h->pred_mode_Y[3] = h->pred_mode_Y[6] = INTRA_L_LP; - h->top_pred_Y[h->mbx*2+0] = h->top_pred_Y[h->mbx*2+1] = INTRA_L_LP; -} - -/***************************************************************************** - * - * motion vector prediction - * - ****************************************************************************/ - -static inline void set_mvs(vector_t *mv, enum block_t size) { - switch(size) { - case BLK_16X16: - mv[MV_STRIDE ] = mv[0]; - mv[MV_STRIDE+1] = mv[0]; - case BLK_16X8: - mv[1] = mv[0]; - break; - case BLK_8X16: - mv[MV_STRIDE] = mv[0]; - break; - } -} - -static inline void store_mvs(AVSContext *h) { - h->col_mv[(h->mby*h->mb_width + h->mbx)*4 + 0] = h->mv[MV_FWD_X0]; - h->col_mv[(h->mby*h->mb_width + h->mbx)*4 + 1] = h->mv[MV_FWD_X1]; - h->col_mv[(h->mby*h->mb_width + h->mbx)*4 + 2] = h->mv[MV_FWD_X2]; - h->col_mv[(h->mby*h->mb_width + h->mbx)*4 + 3] = h->mv[MV_FWD_X3]; -} - -static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, vector_t *src, int distp) { - int den = h->scale_den[src->ref]; - - *d_x = (src->x*distp*den + 256 + (src->x>>31)) >> 9; - *d_y = (src->y*distp*den + 256 + (src->y>>31)) >> 9; -} - -static inline void mv_pred_median(AVSContext *h, vector_t *mvP, vector_t *mvA, vector_t *mvB, vector_t *mvC) { - int ax, ay, bx, by, cx, cy; - int len_ab, len_bc, len_ca, len_mid; - - /* scale candidates according to their temporal span */ - scale_mv(h, &ax, &ay, mvA, mvP->dist); - scale_mv(h, &bx, &by, mvB, mvP->dist); - scale_mv(h, &cx, &cy, mvC, mvP->dist); - /* find the geometrical median of the three candidates */ - len_ab = abs(ax - bx) + abs(ay - by); - len_bc = abs(bx - cx) + abs(by - cy); - len_ca = abs(cx - ax) + abs(cy - ay); - len_mid = mid_pred(len_ab, len_bc, len_ca); - if(len_mid == len_ab) { - mvP->x = cx; - mvP->y = cy; - } else if(len_mid == len_bc) { - mvP->x = ax; - mvP->y = ay; - } else { - mvP->x = bx; - mvP->y = by; - } -} - -static inline void mv_pred_direct(AVSContext *h, vector_t *pmv_fw, - vector_t *col_mv) { - vector_t *pmv_bw = pmv_fw + MV_BWD_OFFS; - int den = h->direct_den[col_mv->ref]; - int m = col_mv->x >> 31; - - pmv_fw->dist = h->dist[1]; - pmv_bw->dist = h->dist[0]; - pmv_fw->ref = 1; - pmv_bw->ref = 0; - /* scale the co-located motion vector according to its temporal span */ - pmv_fw->x = (((den+(den*col_mv->x*pmv_fw->dist^m)-m-1)>>14)^m)-m; - pmv_bw->x = m-(((den+(den*col_mv->x*pmv_bw->dist^m)-m-1)>>14)^m); - m = col_mv->y >> 31; - pmv_fw->y = (((den+(den*col_mv->y*pmv_fw->dist^m)-m-1)>>14)^m)-m; - pmv_bw->y = m-(((den+(den*col_mv->y*pmv_bw->dist^m)-m-1)>>14)^m); -} - -static inline void mv_pred_sym(AVSContext *h, vector_t *src, enum block_t size) { - vector_t *dst = src + MV_BWD_OFFS; - - /* backward mv is the scaled and negated forward mv */ - dst->x = -((src->x * h->sym_factor + 256) >> 9); - dst->y = -((src->y * h->sym_factor + 256) >> 9); - dst->ref = 0; - dst->dist = h->dist[0]; - set_mvs(dst, size); -} - -static void mv_pred(AVSContext *h, enum mv_loc_t nP, enum mv_loc_t nC, - enum mv_pred_t mode, enum block_t size, int ref) { - vector_t *mvP = &h->mv[nP]; - vector_t *mvA = &h->mv[nP-1]; - vector_t *mvB = &h->mv[nP-4]; - vector_t *mvC = &h->mv[nC]; - const vector_t *mvP2 = NULL; - - mvP->ref = ref; - mvP->dist = h->dist[mvP->ref]; - if(mvC->ref == NOT_AVAIL) - mvC = &h->mv[nP-5]; // set to top-left (mvD) - if((mode == MV_PRED_PSKIP) && - ((mvA->ref == NOT_AVAIL) || (mvB->ref == NOT_AVAIL) || - ((mvA->x | mvA->y | mvA->ref) == 0) || - ((mvB->x | mvB->y | mvB->ref) == 0) )) { - mvP2 = &un_mv; - /* if there is only one suitable candidate, take it */ - } else if((mvA->ref >= 0) && (mvB->ref < 0) && (mvC->ref < 0)) { - mvP2= mvA; - } else if((mvA->ref < 0) && (mvB->ref >= 0) && (mvC->ref < 0)) { - mvP2= mvB; - } else if((mvA->ref < 0) && (mvB->ref < 0) && (mvC->ref >= 0)) { - mvP2= mvC; - } else if(mode == MV_PRED_LEFT && mvA->ref == ref){ - mvP2= mvA; - } else if(mode == MV_PRED_TOP && mvB->ref == ref){ - mvP2= mvB; - } else if(mode == MV_PRED_TOPRIGHT && mvC->ref == ref){ - mvP2= mvC; - } - if(mvP2){ - mvP->x = mvP2->x; - mvP->y = mvP2->y; - }else - mv_pred_median(h, mvP, mvA, mvB, mvC); - - if(mode < MV_PRED_PSKIP) { - mvP->x += get_se_golomb(&h->s.gb); - mvP->y += get_se_golomb(&h->s.gb); - } - set_mvs(mvP,size); -} - -/***************************************************************************** - * - * residual data decoding - * - ****************************************************************************/ - -/** kth-order exponential golomb code */ -static inline int get_ue_code(GetBitContext *gb, int order) { - if(order) { - int ret = get_ue_golomb(gb) << order; - return ret + get_bits(gb,order); - } - return get_ue_golomb(gb); -} - -/** - * decode coefficients from one 8x8 block, dequantize, inverse transform - * and add them to sample block - * @param r pointer to 2D VLC table - * @param esc_golomb_order escape codes are k-golomb with this order k - * @param qp quantizer - * @param dst location of sample block - * @param stride line stride in frame buffer - */ -static int decode_residual_block(AVSContext *h, GetBitContext *gb, - const residual_vlc_t *r, int esc_golomb_order, - int qp, uint8_t *dst, int stride) { - int i,pos = -1; - int level_code, esc_code, level, run, mask; - int level_buf[64]; - int run_buf[64]; - int dqm = dequant_mul[qp]; - int dqs = dequant_shift[qp]; - int dqa = 1 << (dqs - 1); - const uint8_t *scantab = h->scantable.permutated; - DCTELEM *block = h->block; - - for(i=0;i<65;i++) { - level_code = get_ue_code(gb,r->golomb_order); - if(level_code >= ESCAPE_CODE) { - run = ((level_code - ESCAPE_CODE) >> 1) + 1; - esc_code = get_ue_code(gb,esc_golomb_order); - level = esc_code + (run > r->max_run ? 1 : r->level_add[run]); - while(level > r->inc_limit) - r++; - mask = -(level_code & 1); - level = (level^mask) - mask; - } else { - level = r->rltab[level_code][0]; - if(!level) //end of block signal - break; - run = r->rltab[level_code][1]; - r += r->rltab[level_code][2]; - } - level_buf[i] = level; - run_buf[i] = run; - } - /* inverse scan and dequantization */ - while(--i >= 0){ - pos += run_buf[i]; - if(pos > 63) { - av_log(h->s.avctx, AV_LOG_ERROR, - "position out of block bounds at pic %d MB(%d,%d)\n", - h->picture.poc, h->mbx, h->mby); - return -1; - } - block[scantab[pos]] = (level_buf[i]*dqm + dqa) >> dqs; - } - h->s.dsp.cavs_idct8_add(dst,block,stride); - return 0; -} - - -static inline void decode_residual_chroma(AVSContext *h) { - if(h->cbp & (1<<4)) - decode_residual_block(h,&h->s.gb,chroma_2dvlc,0, chroma_qp[h->qp], - h->cu,h->c_stride); - if(h->cbp & (1<<5)) - decode_residual_block(h,&h->s.gb,chroma_2dvlc,0, chroma_qp[h->qp], - h->cv,h->c_stride); -} - -static inline int decode_residual_inter(AVSContext *h) { - int block; - - /* get coded block pattern */ - int cbp= get_ue_golomb(&h->s.gb); - if(cbp > 63){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n"); - return -1; - } - h->cbp = cbp_tab[cbp][1]; - - /* get quantizer */ - if(h->cbp && !h->qp_fixed) - h->qp = (h->qp + get_se_golomb(&h->s.gb)) & 63; - for(block=0;block<4;block++) - if(h->cbp & (1<s.gb,inter_2dvlc,0,h->qp, - h->cy + h->luma_scan[block], h->l_stride); - decode_residual_chroma(h); - - return 0; -} - -/***************************************************************************** - * - * macroblock level - * - ****************************************************************************/ - -/** - * initialise predictors for motion vectors and intra prediction - */ -static inline void init_mb(AVSContext *h) { - int i; - - /* copy predictors from top line (MB B and C) into cache */ - for(i=0;i<3;i++) { - h->mv[MV_FWD_B2+i] = h->top_mv[0][h->mbx*2+i]; - h->mv[MV_BWD_B2+i] = h->top_mv[1][h->mbx*2+i]; - } - h->pred_mode_Y[1] = h->top_pred_Y[h->mbx*2+0]; - h->pred_mode_Y[2] = h->top_pred_Y[h->mbx*2+1]; - /* clear top predictors if MB B is not available */ - if(!(h->flags & B_AVAIL)) { - h->mv[MV_FWD_B2] = un_mv; - h->mv[MV_FWD_B3] = un_mv; - h->mv[MV_BWD_B2] = un_mv; - h->mv[MV_BWD_B3] = un_mv; - h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL; - h->flags &= ~(C_AVAIL|D_AVAIL); - } else if(h->mbx) { - h->flags |= D_AVAIL; - } - if(h->mbx == h->mb_width-1) //MB C not available - h->flags &= ~C_AVAIL; - /* clear top-right predictors if MB C is not available */ - if(!(h->flags & C_AVAIL)) { - h->mv[MV_FWD_C2] = un_mv; - h->mv[MV_BWD_C2] = un_mv; - } - /* clear top-left predictors if MB D is not available */ - if(!(h->flags & D_AVAIL)) { - h->mv[MV_FWD_D3] = un_mv; - h->mv[MV_BWD_D3] = un_mv; - } - /* set pointer for co-located macroblock type */ - h->col_type = &h->col_type_base[h->mby*h->mb_width + h->mbx]; -} - -static inline void check_for_slice(AVSContext *h); - -/** - * save predictors for later macroblocks and increase - * macroblock address - * @returns 0 if end of frame is reached, 1 otherwise - */ -static inline int next_mb(AVSContext *h) { - int i; - - h->flags |= A_AVAIL; - h->cy += 16; - h->cu += 8; - h->cv += 8; - /* copy mvs as predictors to the left */ - for(i=0;i<=20;i+=4) - h->mv[i] = h->mv[i+2]; - /* copy bottom mvs from cache to top line */ - h->top_mv[0][h->mbx*2+0] = h->mv[MV_FWD_X2]; - h->top_mv[0][h->mbx*2+1] = h->mv[MV_FWD_X3]; - h->top_mv[1][h->mbx*2+0] = h->mv[MV_BWD_X2]; - h->top_mv[1][h->mbx*2+1] = h->mv[MV_BWD_X3]; - /* next MB address */ - h->mbx++; - if(h->mbx == h->mb_width) { //new mb line - h->flags = B_AVAIL|C_AVAIL; - /* clear left pred_modes */ - h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL; - /* clear left mv predictors */ - for(i=0;i<=20;i+=4) - h->mv[i] = un_mv; - h->mbx = 0; - h->mby++; - /* re-calculate sample pointers */ - h->cy = h->picture.data[0] + h->mby*16*h->l_stride; - h->cu = h->picture.data[1] + h->mby*8*h->c_stride; - h->cv = h->picture.data[2] + h->mby*8*h->c_stride; - if(h->mby == h->mb_height) { //frame end - return 0; - } else { - //check_for_slice(h); - } - } - return 1; -} - -static int decode_mb_i(AVSContext *h, int cbp_code) { - GetBitContext *gb = &h->s.gb; - int block, pred_mode_uv; - uint8_t top[18]; - uint8_t *left = NULL; - uint8_t *d; - - init_mb(h); - - /* get intra prediction modes from stream */ - for(block=0;block<4;block++) { - int nA,nB,predpred; - int pos = scan3x3[block]; - - nA = h->pred_mode_Y[pos-1]; - nB = h->pred_mode_Y[pos-3]; - predpred = FFMIN(nA,nB); - if(predpred == NOT_AVAIL) // if either is not available - predpred = INTRA_L_LP; - if(!get_bits1(gb)){ - int rem_mode= get_bits(gb, 2); - predpred = rem_mode + (rem_mode >= predpred); - } - h->pred_mode_Y[pos] = predpred; - } - pred_mode_uv = get_ue_golomb(gb); - if(pred_mode_uv > 6) { - av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n"); - return -1; - } - - /* save pred modes before they get modified */ - h->pred_mode_Y[3] = h->pred_mode_Y[5]; - h->pred_mode_Y[6] = h->pred_mode_Y[8]; - h->top_pred_Y[h->mbx*2+0] = h->pred_mode_Y[7]; - h->top_pred_Y[h->mbx*2+1] = h->pred_mode_Y[8]; - - /* modify pred modes according to availability of neighbour samples */ - if(!(h->flags & A_AVAIL)) { - modify_pred(left_modifier_l, &h->pred_mode_Y[4] ); - modify_pred(left_modifier_l, &h->pred_mode_Y[7] ); - modify_pred(left_modifier_c, &pred_mode_uv ); - } - if(!(h->flags & B_AVAIL)) { - modify_pred(top_modifier_l, &h->pred_mode_Y[4] ); - modify_pred(top_modifier_l, &h->pred_mode_Y[5] ); - modify_pred(top_modifier_c, &pred_mode_uv ); - } - - /* get coded block pattern */ - if(h->pic_type == FF_I_TYPE) - cbp_code = get_ue_golomb(gb); - if(cbp_code > 63){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n"); - return -1; - } - h->cbp = cbp_tab[cbp_code][0]; - if(h->cbp && !h->qp_fixed) - h->qp = (h->qp + get_se_golomb(gb)) & 63; //qp_delta - - /* luma intra prediction interleaved with residual decode/transform/add */ - for(block=0;block<4;block++) { - d = h->cy + h->luma_scan[block]; - load_intra_pred_luma(h, top, &left, block); - h->intra_pred_l[h->pred_mode_Y[scan3x3[block]]] - (d, top, left, h->l_stride); - if(h->cbp & (1<qp,d,h->l_stride); - } - - /* chroma intra prediction */ - /* extend borders by one pixel */ - h->left_border_u[9] = h->left_border_u[8]; - h->left_border_v[9] = h->left_border_v[8]; - h->top_border_u[h->mbx*10+9] = h->top_border_u[h->mbx*10+8]; - h->top_border_v[h->mbx*10+9] = h->top_border_v[h->mbx*10+8]; - if(h->mbx && h->mby) { - h->top_border_u[h->mbx*10] = h->left_border_u[0] = h->topleft_border_u; - h->top_border_v[h->mbx*10] = h->left_border_v[0] = h->topleft_border_v; - } else { - h->left_border_u[0] = h->left_border_u[1]; - h->left_border_v[0] = h->left_border_v[1]; - h->top_border_u[h->mbx*10] = h->top_border_u[h->mbx*10+1]; - h->top_border_v[h->mbx*10] = h->top_border_v[h->mbx*10+1]; - } - h->intra_pred_c[pred_mode_uv](h->cu, &h->top_border_u[h->mbx*10], - h->left_border_u, h->c_stride); - h->intra_pred_c[pred_mode_uv](h->cv, &h->top_border_v[h->mbx*10], - h->left_border_v, h->c_stride); - - decode_residual_chroma(h); - filter_mb(h,I_8X8); - - /* mark motion vectors as intra */ - h->mv[MV_FWD_X0] = intra_mv; - set_mvs(&h->mv[MV_FWD_X0], BLK_16X16); - h->mv[MV_BWD_X0] = intra_mv; - set_mvs(&h->mv[MV_BWD_X0], BLK_16X16); - if(h->pic_type != FF_B_TYPE) - *h->col_type = I_8X8; - - return 0; -} - -static void decode_mb_p(AVSContext *h, enum mb_t mb_type) { - GetBitContext *gb = &h->s.gb; - int ref[4]; - - init_mb(h); - switch(mb_type) { - case P_SKIP: - mv_pred(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_PSKIP, BLK_16X16, 0); - break; - case P_16X16: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - mv_pred(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16,ref[0]); - break; - case P_16X8: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ref[2] = h->ref_flag ? 0 : get_bits1(gb); - mv_pred(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, ref[0]); - mv_pred(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, ref[2]); - break; - case P_8X16: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ref[1] = h->ref_flag ? 0 : get_bits1(gb); - mv_pred(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, ref[0]); - mv_pred(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, ref[1]); - break; - case P_8X8: - ref[0] = h->ref_flag ? 0 : get_bits1(gb); - ref[1] = h->ref_flag ? 0 : get_bits1(gb); - ref[2] = h->ref_flag ? 0 : get_bits1(gb); - ref[3] = h->ref_flag ? 0 : get_bits1(gb); - mv_pred(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_MEDIAN, BLK_8X8, ref[0]); - mv_pred(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_MEDIAN, BLK_8X8, ref[1]); - mv_pred(h, MV_FWD_X2, MV_FWD_X1, MV_PRED_MEDIAN, BLK_8X8, ref[2]); - mv_pred(h, MV_FWD_X3, MV_FWD_X0, MV_PRED_MEDIAN, BLK_8X8, ref[3]); - } - inter_pred(h, mb_type); - store_mvs(h); - if(mb_type != P_SKIP) - decode_residual_inter(h); - filter_mb(h,mb_type); - *h->col_type = mb_type; -} - -static void decode_mb_b(AVSContext *h, enum mb_t mb_type) { - int block; - enum sub_mb_t sub_type[4]; - int flags; - - init_mb(h); - - /* reset all MVs */ - h->mv[MV_FWD_X0] = dir_mv; - set_mvs(&h->mv[MV_FWD_X0], BLK_16X16); - h->mv[MV_BWD_X0] = dir_mv; - set_mvs(&h->mv[MV_BWD_X0], BLK_16X16); - switch(mb_type) { - case B_SKIP: - case B_DIRECT: - if(!(*h->col_type)) { - /* intra MB at co-location, do in-plane prediction */ - mv_pred(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_BSKIP, BLK_16X16, 1); - mv_pred(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_BSKIP, BLK_16X16, 0); - } else - /* direct prediction from co-located P MB, block-wise */ - for(block=0;block<4;block++) - mv_pred_direct(h,&h->mv[mv_scan[block]], - &h->col_mv[(h->mby*h->mb_width+h->mbx)*4 + block]); - break; - case B_FWD_16X16: - mv_pred(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1); - break; - case B_SYM_16X16: - mv_pred(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1); - mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X16); - break; - case B_BWD_16X16: - mv_pred(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_MEDIAN, BLK_16X16, 0); - break; - case B_8X8: - for(block=0;block<4;block++) - sub_type[block] = get_bits(&h->s.gb,2); - for(block=0;block<4;block++) { - switch(sub_type[block]) { - case B_SUB_DIRECT: - if(!(*h->col_type)) { - /* intra MB at co-location, do in-plane prediction */ - mv_pred(h, mv_scan[block], mv_scan[block]-3, - MV_PRED_BSKIP, BLK_8X8, 1); - mv_pred(h, mv_scan[block]+MV_BWD_OFFS, - mv_scan[block]-3+MV_BWD_OFFS, - MV_PRED_BSKIP, BLK_8X8, 0); - } else - mv_pred_direct(h,&h->mv[mv_scan[block]], - &h->col_mv[(h->mby*h->mb_width + h->mbx)*4 + block]); - break; - case B_SUB_FWD: - mv_pred(h, mv_scan[block], mv_scan[block]-3, - MV_PRED_MEDIAN, BLK_8X8, 1); - break; - case B_SUB_SYM: - mv_pred(h, mv_scan[block], mv_scan[block]-3, - MV_PRED_MEDIAN, BLK_8X8, 1); - mv_pred_sym(h, &h->mv[mv_scan[block]], BLK_8X8); - break; - } - } - for(block=0;block<4;block++) { - if(sub_type[block] == B_SUB_BWD) - mv_pred(h, mv_scan[block]+MV_BWD_OFFS, - mv_scan[block]+MV_BWD_OFFS-3, - MV_PRED_MEDIAN, BLK_8X8, 0); - } - break; - default: - assert((mb_type > B_SYM_16X16) && (mb_type < B_8X8)); - flags = partition_flags[mb_type]; - if(mb_type & 1) { /* 16x8 macroblock types */ - if(flags & FWD0) - mv_pred(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, 1); - if(flags & SYM0) - mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X8); - if(flags & FWD1) - mv_pred(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, 1); - if(flags & SYM1) - mv_pred_sym(h, &h->mv[MV_FWD_X2], BLK_16X8); - if(flags & BWD0) - mv_pred(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_TOP, BLK_16X8, 0); - if(flags & BWD1) - mv_pred(h, MV_BWD_X2, MV_BWD_A1, MV_PRED_LEFT, BLK_16X8, 0); - } else { /* 8x16 macroblock types */ - if(flags & FWD0) - mv_pred(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, 1); - if(flags & SYM0) - mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_8X16); - if(flags & FWD1) - mv_pred(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT,BLK_8X16, 1); - if(flags & SYM1) - mv_pred_sym(h, &h->mv[MV_FWD_X1], BLK_8X16); - if(flags & BWD0) - mv_pred(h, MV_BWD_X0, MV_BWD_B3, MV_PRED_LEFT, BLK_8X16, 0); - if(flags & BWD1) - mv_pred(h, MV_BWD_X1, MV_BWD_C2, MV_PRED_TOPRIGHT,BLK_8X16, 0); - } - } - inter_pred(h, mb_type); - if(mb_type != B_SKIP) - decode_residual_inter(h); - filter_mb(h,mb_type); -} - -/***************************************************************************** - * - * slice level - * - ****************************************************************************/ - -static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) { - if(h->stc > 0xAF) - av_log(h->s.avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc); - h->mby = h->stc; - if((h->mby == 0) && (!h->qp_fixed)){ - h->qp_fixed = get_bits1(gb); - h->qp = get_bits(gb,6); - } - /* inter frame or second slice can have weighting params */ - if((h->pic_type != FF_I_TYPE) || (!h->pic_structure && h->mby >= h->mb_width/2)) - if(get_bits1(gb)) { //slice_weighting_flag - av_log(h->s.avctx, AV_LOG_ERROR, - "weighted prediction not yet supported\n"); - } - return 0; -} - -static inline void check_for_slice(AVSContext *h) { - GetBitContext *gb = &h->s.gb; - int align; - align = (-get_bits_count(gb)) & 7; - if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) { - get_bits_long(gb,24+align); - h->stc = get_bits(gb,8); - decode_slice_header(h,gb); - } -} - -/***************************************************************************** - * - * frame level - * - ****************************************************************************/ - -static void init_pic(AVSContext *h) { - int i; - - /* clear some predictors */ - for(i=0;i<=20;i+=4) - h->mv[i] = un_mv; - h->mv[MV_BWD_X0] = dir_mv; - set_mvs(&h->mv[MV_BWD_X0], BLK_16X16); - h->mv[MV_FWD_X0] = dir_mv; - set_mvs(&h->mv[MV_FWD_X0], BLK_16X16); - h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL; - h->cy = h->picture.data[0]; - h->cu = h->picture.data[1]; - h->cv = h->picture.data[2]; - h->l_stride = h->picture.linesize[0]; - h->c_stride = h->picture.linesize[1]; - h->luma_scan[2] = 8*h->l_stride; - h->luma_scan[3] = 8*h->l_stride+8; - h->mbx = h->mby = 0; - h->flags = 0; -} - -static int decode_pic(AVSContext *h) { - MpegEncContext *s = &h->s; - int skip_count; - enum mb_t mb_type; - - if (!s->context_initialized) { - s->avctx->idct_algo = FF_IDCT_CAVS; - if (MPV_common_init(s) < 0) - return -1; - ff_init_scantable(s->dsp.idct_permutation,&h->scantable,ff_zigzag_direct); - } - get_bits(&s->gb,16);//bbv_dwlay - if(h->stc == PIC_PB_START_CODE) { - h->pic_type = get_bits(&s->gb,2) + FF_I_TYPE; - if(h->pic_type > FF_B_TYPE) { - av_log(s->avctx, AV_LOG_ERROR, "illegal picture type\n"); - return -1; - } - /* make sure we have the reference frames we need */ - if(!h->DPB[0].data[0] || - (!h->DPB[1].data[0] && h->pic_type == FF_B_TYPE)) - return -1; - } else { - h->pic_type = FF_I_TYPE; - if(get_bits1(&s->gb)) - get_bits(&s->gb,16);//time_code - } - /* release last B frame */ - if(h->picture.data[0]) - s->avctx->release_buffer(s->avctx, (AVFrame *)&h->picture); - - s->avctx->get_buffer(s->avctx, (AVFrame *)&h->picture); - init_pic(h); - h->picture.poc = get_bits(&s->gb,8)*2; - - /* get temporal distances and MV scaling factors */ - if(h->pic_type != FF_B_TYPE) { - h->dist[0] = (h->picture.poc - h->DPB[0].poc + 512) % 512; - } else { - h->dist[0] = (h->DPB[0].poc - h->picture.poc + 512) % 512; - } - h->dist[1] = (h->picture.poc - h->DPB[1].poc + 512) % 512; - h->scale_den[0] = h->dist[0] ? 512/h->dist[0] : 0; - h->scale_den[1] = h->dist[1] ? 512/h->dist[1] : 0; - if(h->pic_type == FF_B_TYPE) { - h->sym_factor = h->dist[0]*h->scale_den[1]; - } else { - h->direct_den[0] = h->dist[0] ? 16384/h->dist[0] : 0; - h->direct_den[1] = h->dist[1] ? 16384/h->dist[1] : 0; - } - - if(s->low_delay) - get_ue_golomb(&s->gb); //bbv_check_times - h->progressive = get_bits1(&s->gb); - if(h->progressive) - h->pic_structure = 1; - else if(!(h->pic_structure = get_bits1(&s->gb) && (h->stc == PIC_PB_START_CODE)) ) - get_bits1(&s->gb); //advanced_pred_mode_disable - skip_bits1(&s->gb); //top_field_first - skip_bits1(&s->gb); //repeat_first_field - h->qp_fixed = get_bits1(&s->gb); - h->qp = get_bits(&s->gb,6); - if(h->pic_type == FF_I_TYPE) { - if(!h->progressive && !h->pic_structure) - skip_bits1(&s->gb);//what is this? - skip_bits(&s->gb,4); //reserved bits - } else { - if(!(h->pic_type == FF_B_TYPE && h->pic_structure == 1)) - h->ref_flag = get_bits1(&s->gb); - skip_bits(&s->gb,4); //reserved bits - h->skip_mode_flag = get_bits1(&s->gb); - } - h->loop_filter_disable = get_bits1(&s->gb); - if(!h->loop_filter_disable && get_bits1(&s->gb)) { - h->alpha_offset = get_se_golomb(&s->gb); - h->beta_offset = get_se_golomb(&s->gb); - } else { - h->alpha_offset = h->beta_offset = 0; - } - check_for_slice(h); - if(h->pic_type == FF_I_TYPE) { - do { - decode_mb_i(h, 0); - } while(next_mb(h)); - } else if(h->pic_type == FF_P_TYPE) { - do { - if(h->skip_mode_flag) { - skip_count = get_ue_golomb(&s->gb); - while(skip_count--) { - decode_mb_p(h,P_SKIP); - if(!next_mb(h)) - goto done; - } - mb_type = get_ue_golomb(&s->gb) + P_16X16; - } else - mb_type = get_ue_golomb(&s->gb) + P_SKIP; - if(mb_type > P_8X8) { - decode_mb_i(h, mb_type - P_8X8 - 1); - } else - decode_mb_p(h,mb_type); - } while(next_mb(h)); - } else { /* FF_B_TYPE */ - do { - if(h->skip_mode_flag) { - skip_count = get_ue_golomb(&s->gb); - while(skip_count--) { - decode_mb_b(h,B_SKIP); - if(!next_mb(h)) - goto done; - } - mb_type = get_ue_golomb(&s->gb) + B_DIRECT; - } else - mb_type = get_ue_golomb(&s->gb) + B_SKIP; - if(mb_type > B_8X8) { - decode_mb_i(h, mb_type - B_8X8 - 1); - } else - decode_mb_b(h,mb_type); - } while(next_mb(h)); - } - done: - if(h->pic_type != FF_B_TYPE) { - if(h->DPB[1].data[0]) - s->avctx->release_buffer(s->avctx, (AVFrame *)&h->DPB[1]); - memcpy(&h->DPB[1], &h->DPB[0], sizeof(Picture)); - memcpy(&h->DPB[0], &h->picture, sizeof(Picture)); - memset(&h->picture,0,sizeof(Picture)); - } - return 0; -} - -/***************************************************************************** - * - * headers and interface - * - ****************************************************************************/ - -/** - * some predictions require data from the top-neighbouring macroblock. - * this data has to be stored for one complete row of macroblocks - * and this storage space is allocated here - */ -static void init_top_lines(AVSContext *h) { - /* alloc top line of predictors */ - h->top_qp = av_malloc( h->mb_width); - h->top_mv[0] = av_malloc((h->mb_width*2+1)*sizeof(vector_t)); - h->top_mv[1] = av_malloc((h->mb_width*2+1)*sizeof(vector_t)); - h->top_pred_Y = av_malloc( h->mb_width*2*sizeof(*h->top_pred_Y)); - h->top_border_y = av_malloc((h->mb_width+1)*16); - h->top_border_u = av_malloc((h->mb_width)*10); - h->top_border_v = av_malloc((h->mb_width)*10); - - /* alloc space for co-located MVs and types */ - h->col_mv = av_malloc( h->mb_width*h->mb_height*4*sizeof(vector_t)); - h->col_type_base = av_malloc(h->mb_width*h->mb_height); - h->block = av_mallocz(64*sizeof(DCTELEM)); -} - -static int decode_seq_header(AVSContext *h) { - MpegEncContext *s = &h->s; - extern const AVRational ff_frame_rate_tab[]; - int frame_rate_code; - - h->profile = get_bits(&s->gb,8); - h->level = get_bits(&s->gb,8); - skip_bits1(&s->gb); //progressive sequence - s->width = get_bits(&s->gb,14); - s->height = get_bits(&s->gb,14); - skip_bits(&s->gb,2); //chroma format - skip_bits(&s->gb,3); //sample_precision - h->aspect_ratio = get_bits(&s->gb,4); - frame_rate_code = get_bits(&s->gb,4); - skip_bits(&s->gb,18);//bit_rate_lower - skip_bits1(&s->gb); //marker_bit - skip_bits(&s->gb,12);//bit_rate_upper - s->low_delay = get_bits1(&s->gb); - h->mb_width = (s->width + 15) >> 4; - h->mb_height = (s->height + 15) >> 4; - h->s.avctx->time_base.den = ff_frame_rate_tab[frame_rate_code].num; - h->s.avctx->time_base.num = ff_frame_rate_tab[frame_rate_code].den; - h->s.avctx->width = s->width; - h->s.avctx->height = s->height; - if(!h->top_qp) - init_top_lines(h); - return 0; -} - -/** - * finds the end of the current frame in the bitstream. - * @return the position of the first byte of the next frame, or -1 - */ -int ff_cavs_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) { - int pic_found, i; - uint32_t state; - - pic_found= pc->frame_start_found; - state= pc->state; - - i=0; - if(!pic_found){ - for(i=0; i SLICE_MAX_START_CODE){ - pc->frame_start_found=0; - pc->state=-1; - return i-3; - } - } - } - } - pc->frame_start_found= pic_found; - pc->state= state; - return END_NOT_FOUND; -} - -void ff_cavs_flush(AVCodecContext * avctx) { - AVSContext *h = avctx->priv_data; - h->got_keyframe = 0; -} - -static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, - uint8_t * buf, int buf_size) { - AVSContext *h = avctx->priv_data; - MpegEncContext *s = &h->s; - int input_size; - const uint8_t *buf_end; - const uint8_t *buf_ptr; - AVFrame *picture = data; - uint32_t stc; - - s->avctx = avctx; - - if (buf_size == 0) { - if(!s->low_delay && h->DPB[0].data[0]) { - *data_size = sizeof(AVPicture); - *picture = *(AVFrame *) &h->DPB[0]; - } - return 0; - } - - buf_ptr = buf; - buf_end = buf + buf_size; - for(;;) { - buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc); - if(stc & 0xFFFFFE00) - return FFMAX(0, buf_ptr - buf - s->parse_context.last_index); - input_size = (buf_end - buf_ptr)*8; - switch(stc) { - case SEQ_START_CODE: - init_get_bits(&s->gb, buf_ptr, input_size); - decode_seq_header(h); - break; - case PIC_I_START_CODE: - if(!h->got_keyframe) { - if(h->DPB[0].data[0]) - avctx->release_buffer(avctx, (AVFrame *)&h->DPB[0]); - if(h->DPB[1].data[0]) - avctx->release_buffer(avctx, (AVFrame *)&h->DPB[1]); - h->got_keyframe = 1; - } - case PIC_PB_START_CODE: - *data_size = 0; - if(!h->got_keyframe) - break; - init_get_bits(&s->gb, buf_ptr, input_size); - h->stc = stc; - if(decode_pic(h)) - break; - *data_size = sizeof(AVPicture); - if(h->pic_type != FF_B_TYPE) { - if(h->DPB[1].data[0]) { - *picture = *(AVFrame *) &h->DPB[1]; - } else { - *data_size = 0; - } - } else - *picture = *(AVFrame *) &h->picture; - break; - case EXT_START_CODE: - //mpeg_decode_extension(avctx,buf_ptr, input_size); - break; - case USER_START_CODE: - //mpeg_decode_user_data(avctx,buf_ptr, input_size); - break; - default: - if (stc >= SLICE_MIN_START_CODE && - stc <= SLICE_MAX_START_CODE) { - init_get_bits(&s->gb, buf_ptr, input_size); - decode_slice_header(h, &s->gb); - } - break; - } - } -} - -static int cavs_decode_init(AVCodecContext * avctx) { - AVSContext *h = avctx->priv_data; - MpegEncContext * const s = &h->s; - - MPV_decode_defaults(s); - s->avctx = avctx; - - avctx->pix_fmt= PIX_FMT_YUV420P; - - h->luma_scan[0] = 0; - h->luma_scan[1] = 8; - h->intra_pred_l[ INTRA_L_VERT] = intra_pred_vert; - h->intra_pred_l[ INTRA_L_HORIZ] = intra_pred_horiz; - h->intra_pred_l[ INTRA_L_LP] = intra_pred_lp; - h->intra_pred_l[ INTRA_L_DOWN_LEFT] = intra_pred_down_left; - h->intra_pred_l[INTRA_L_DOWN_RIGHT] = intra_pred_down_right; - h->intra_pred_l[ INTRA_L_LP_LEFT] = intra_pred_lp_left; - h->intra_pred_l[ INTRA_L_LP_TOP] = intra_pred_lp_top; - h->intra_pred_l[ INTRA_L_DC_128] = intra_pred_dc_128; - h->intra_pred_c[ INTRA_C_LP] = intra_pred_lp; - h->intra_pred_c[ INTRA_C_HORIZ] = intra_pred_horiz; - h->intra_pred_c[ INTRA_C_VERT] = intra_pred_vert; - h->intra_pred_c[ INTRA_C_PLANE] = intra_pred_plane; - h->intra_pred_c[ INTRA_C_LP_LEFT] = intra_pred_lp_left; - h->intra_pred_c[ INTRA_C_LP_TOP] = intra_pred_lp_top; - h->intra_pred_c[ INTRA_C_DC_128] = intra_pred_dc_128; - h->mv[ 7] = un_mv; - h->mv[19] = un_mv; - return 0; -} - -static int cavs_decode_end(AVCodecContext * avctx) { - AVSContext *h = avctx->priv_data; - - av_free(h->top_qp); - av_free(h->top_mv[0]); - av_free(h->top_mv[1]); - av_free(h->top_pred_Y); - av_free(h->top_border_y); - av_free(h->top_border_u); - av_free(h->top_border_v); - av_free(h->col_mv); - av_free(h->col_type_base); - av_free(h->block); - return 0; -} - -AVCodec cavs_decoder = { - "cavs", - CODEC_TYPE_VIDEO, - CODEC_ID_CAVS, - sizeof(AVSContext), - cavs_decode_init, - NULL, - cavs_decode_end, - cavs_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .flush= ff_cavs_flush, -}; diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/cavsdsp.c --- a/src/ffmpeg/libavcodec/cavsdsp.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,546 +0,0 @@ -/* - * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. - * - * DSP functions - * - * Copyright (c) 2006 Stefan Gehrer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "dsputil.h" - -/***************************************************************************** - * - * in-loop deblocking filter - * - ****************************************************************************/ - -#define P2 p0_p[-3*stride] -#define P1 p0_p[-2*stride] -#define P0 p0_p[-1*stride] -#define Q0 p0_p[ 0*stride] -#define Q1 p0_p[ 1*stride] -#define Q2 p0_p[ 2*stride] - -static inline void loop_filter_l2(uint8_t *p0_p,int stride,int alpha, int beta) { - int p0 = P0; - int q0 = Q0; - - if(abs(p0-q0)>2) + 2; - if(abs(P2-p0) < beta && abs(p0-q0) < alpha) { - P0 = (P1 + p0 + s) >> 2; - P1 = (2*P1 + s) >> 2; - } else - P0 = (2*P1 + s) >> 2; - if(abs(Q2-q0) < beta && abs(q0-p0) < alpha) { - Q0 = (Q1 + q0 + s) >> 2; - Q1 = (2*Q1 + s) >> 2; - } else - Q0 = (2*Q1 + s) >> 2; - } -} - -static inline void loop_filter_l1(uint8_t *p0_p, int stride, int alpha, int beta, int tc) { - int p0 = P0; - int q0 = Q0; - - if(abs(p0-q0)>3,-tc, tc); - P0 = clip_uint8(p0+delta); - Q0 = clip_uint8(q0-delta); - if(abs(P2-p0)>3, -tc, tc); - P1 = clip_uint8(P1+delta); - } - if(abs(Q2-q0)>3, -tc, tc); - Q1 = clip_uint8(Q1-delta); - } - } -} - -static inline void loop_filter_c2(uint8_t *p0_p,int stride,int alpha, int beta) { - int p0 = P0; - int q0 = Q0; - - if(abs(p0-q0)>2) + 2; - if(abs(P2-p0) < beta && abs(p0-q0) < alpha) { - P0 = (P1 + p0 + s) >> 2; - } else - P0 = (2*P1 + s) >> 2; - if(abs(Q2-q0) < beta && abs(q0-p0) < alpha) { - Q0 = (Q1 + q0 + s) >> 2; - } else - Q0 = (2*Q1 + s) >> 2; - } -} - -static inline void loop_filter_c1(uint8_t *p0_p,int stride,int alpha, int beta, - int tc) { - if(abs(P0-Q0)>3, -tc, tc); - P0 = clip_uint8(P0+delta); - Q0 = clip_uint8(Q0-delta); - } -} - -#undef P0 -#undef P1 -#undef P2 -#undef Q0 -#undef Q1 -#undef Q2 - -static void cavs_filter_lv_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { - int i; - if(bs1==2) - for(i=0;i<16;i++) - loop_filter_l2(d + i*stride,1,alpha,beta); - else { - if(bs1) - for(i=0;i<8;i++) - loop_filter_l1(d + i*stride,1,alpha,beta,tc); - if (bs2) - for(i=8;i<16;i++) - loop_filter_l1(d + i*stride,1,alpha,beta,tc); - } -} - -static void cavs_filter_lh_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { - int i; - if(bs1==2) - for(i=0;i<16;i++) - loop_filter_l2(d + i,stride,alpha,beta); - else { - if(bs1) - for(i=0;i<8;i++) - loop_filter_l1(d + i,stride,alpha,beta,tc); - if (bs2) - for(i=8;i<16;i++) - loop_filter_l1(d + i,stride,alpha,beta,tc); - } -} - -static void cavs_filter_cv_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { - int i; - if(bs1==2) - for(i=0;i<8;i++) - loop_filter_c2(d + i*stride,1,alpha,beta); - else { - if(bs1) - for(i=0;i<4;i++) - loop_filter_c1(d + i*stride,1,alpha,beta,tc); - if (bs2) - for(i=4;i<8;i++) - loop_filter_c1(d + i*stride,1,alpha,beta,tc); - } -} - -static void cavs_filter_ch_c(uint8_t *d, int stride, int alpha, int beta, int tc, - int bs1, int bs2) { - int i; - if(bs1==2) - for(i=0;i<8;i++) - loop_filter_c2(d + i,stride,alpha,beta); - else { - if(bs1) - for(i=0;i<4;i++) - loop_filter_c1(d + i,stride,alpha,beta,tc); - if (bs2) - for(i=4;i<8;i++) - loop_filter_c1(d + i,stride,alpha,beta,tc); - } -} - -/***************************************************************************** - * - * inverse transform - * - ****************************************************************************/ - -static void cavs_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride) { - int i; - DCTELEM (*src)[8] = (DCTELEM(*)[8])block; - uint8_t *cm = cropTbl + MAX_NEG_CROP; - - src[0][0] += 8; - - for( i = 0; i < 8; i++ ) { - const int a0 = 3*src[i][1] - (src[i][7]<<1); - const int a1 = 3*src[i][3] + (src[i][5]<<1); - const int a2 = (src[i][3]<<1) - 3*src[i][5]; - const int a3 = (src[i][1]<<1) + 3*src[i][7]; - - const int b4 = ((a0 + a1 + a3)<<1) + a1; - const int b5 = ((a0 - a1 + a2)<<1) + a0; - const int b6 = ((a3 - a2 - a1)<<1) + a3; - const int b7 = ((a0 - a2 - a3)<<1) - a2; - - const int a7 = (src[i][2]<<2) - 10*src[i][6]; - const int a6 = (src[i][6]<<2) + 10*src[i][2]; - const int a5 = ((src[i][0] - src[i][4]) << 3) + 4; - const int a4 = ((src[i][0] + src[i][4]) << 3) + 4; - - const int b0 = a4 + a6; - const int b1 = a5 + a7; - const int b2 = a5 - a7; - const int b3 = a4 - a6; - - src[i][0] = (b0 + b4) >> 3; - src[i][1] = (b1 + b5) >> 3; - src[i][2] = (b2 + b6) >> 3; - src[i][3] = (b3 + b7) >> 3; - src[i][4] = (b3 - b7) >> 3; - src[i][5] = (b2 - b6) >> 3; - src[i][6] = (b1 - b5) >> 3; - src[i][7] = (b0 - b4) >> 3; - } - for( i = 0; i < 8; i++ ) { - const int a0 = 3*src[1][i] - (src[7][i]<<1); - const int a1 = 3*src[3][i] + (src[5][i]<<1); - const int a2 = (src[3][i]<<1) - 3*src[5][i]; - const int a3 = (src[1][i]<<1) + 3*src[7][i]; - - const int b4 = ((a0 + a1 + a3)<<1) + a1; - const int b5 = ((a0 - a1 + a2)<<1) + a0; - const int b6 = ((a3 - a2 - a1)<<1) + a3; - const int b7 = ((a0 - a2 - a3)<<1) - a2; - - const int a7 = (src[2][i]<<2) - 10*src[6][i]; - const int a6 = (src[6][i]<<2) + 10*src[2][i]; - const int a5 = (src[0][i] - src[4][i]) << 3; - const int a4 = (src[0][i] + src[4][i]) << 3; - - const int b0 = a4 + a6; - const int b1 = a5 + a7; - const int b2 = a5 - a7; - const int b3 = a4 - a6; - - dst[i + 0*stride] = cm[ dst[i + 0*stride] + ((b0 + b4) >> 7)]; - dst[i + 1*stride] = cm[ dst[i + 1*stride] + ((b1 + b5) >> 7)]; - dst[i + 2*stride] = cm[ dst[i + 2*stride] + ((b2 + b6) >> 7)]; - dst[i + 3*stride] = cm[ dst[i + 3*stride] + ((b3 + b7) >> 7)]; - dst[i + 4*stride] = cm[ dst[i + 4*stride] + ((b3 - b7) >> 7)]; - dst[i + 5*stride] = cm[ dst[i + 5*stride] + ((b2 - b6) >> 7)]; - dst[i + 6*stride] = cm[ dst[i + 6*stride] + ((b1 - b5) >> 7)]; - dst[i + 7*stride] = cm[ dst[i + 7*stride] + ((b0 - b4) >> 7)]; - } - memset(block,0,64*sizeof(DCTELEM)); -} - -/***************************************************************************** - * - * motion compensation - * - ****************************************************************************/ - -#define CAVS_SUBPIX(OPNAME, OP, NAME, A, B, C, D, E, F) \ -static void OPNAME ## cavs_filt8_h_ ## NAME(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - const int h=8;\ - uint8_t *cm = cropTbl + MAX_NEG_CROP;\ - int i;\ - for(i=0; i>3] -#define op_put2(a, b) a = cm[((b)+64)>>7] -#define op_put3(a, b) a = cm[((b)+32)>>6] -#define op_put4(a, b) a = cm[((b)+512)>>10] -#define op_avg1(a, b) a = ((a)+cm[((b)+4)>>3] +1)>>1 -#define op_avg2(a, b) a = ((a)+cm[((b)+64)>>7] +1)>>1 -#define op_avg3(a, b) a = ((a)+cm[((b)+32)>>6] +1)>>1 -#define op_avg4(a, b) a = ((a)+cm[((b)+512)>>10]+1)>>1 -CAVS_SUBPIX(put_ , op_put1, hpel, 0, -1, 5, 5, -1, 0) -CAVS_SUBPIX(put_ , op_put2, qpel_l, -1, -2, 96, 42, -7, 0) -CAVS_SUBPIX(put_ , op_put2, qpel_r, 0, -7, 42, 96, -2, -1) -CAVS_SUBPIX_HV(put_, op_put3, jj, 0, -1, 5, 5, -1, 0, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(put_, op_put4, ff, 0, -1, 5, 5, -1, 0, -1, -2, 96, 42, -7, 0, 0) -CAVS_SUBPIX_HV(put_, op_put4, ii, -1, -2, 96, 42, -7, 0, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(put_, op_put4, kk, 0, -7, 42, 96, -2, -1, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(put_, op_put4, qq, 0, -1, 5, 5, -1, 0, 0, -7, 42, 96, -2,-1, 0) -CAVS_SUBPIX_HV(put_, op_put2, egpr, 0, -1, 5, 5, -1, 0, 0, -1, 5, 5, -1, 0, 1) -CAVS_SUBPIX(avg_ , op_avg1, hpel, 0, -1, 5, 5, -1, 0) -CAVS_SUBPIX(avg_ , op_avg2, qpel_l, -1, -2, 96, 42, -7, 0) -CAVS_SUBPIX(avg_ , op_avg2, qpel_r, 0, -7, 42, 96, -2, -1) -CAVS_SUBPIX_HV(avg_, op_avg3, jj, 0, -1, 5, 5, -1, 0, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(avg_, op_avg4, ff, 0, -1, 5, 5, -1, 0, -1, -2, 96, 42, -7, 0, 0) -CAVS_SUBPIX_HV(avg_, op_avg4, ii, -1, -2, 96, 42, -7, 0, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(avg_, op_avg4, kk, 0, -7, 42, 96, -2, -1, 0, -1, 5, 5, -1, 0, 0) -CAVS_SUBPIX_HV(avg_, op_avg4, qq, 0, -1, 5, 5, -1, 0, 0, -7, 42, 96, -2,-1, 0) -CAVS_SUBPIX_HV(avg_, op_avg2, egpr, 0, -1, 5, 5, -1, 0, 0, -1, 5, 5, -1, 0, 1) -CAVS_MC(put_, 8) -CAVS_MC(put_, 16) -CAVS_MC(avg_, 8) -CAVS_MC(avg_, 16) - -void ff_put_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride); -void ff_avg_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride); -void ff_put_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride); -void ff_avg_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride); - -void ff_cavsdsp_init(DSPContext* c, AVCodecContext *avctx) { -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_c; \ - c->PFX ## _pixels_tab[IDX][ 1] = ff_ ## PFX ## NUM ## _mc10_c; \ - c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_c; \ - c->PFX ## _pixels_tab[IDX][ 3] = ff_ ## PFX ## NUM ## _mc30_c; \ - c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_c; \ - c->PFX ## _pixels_tab[IDX][ 5] = ff_ ## PFX ## NUM ## _mc11_c; \ - c->PFX ## _pixels_tab[IDX][ 6] = ff_ ## PFX ## NUM ## _mc21_c; \ - c->PFX ## _pixels_tab[IDX][ 7] = ff_ ## PFX ## NUM ## _mc31_c; \ - c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_c; \ - c->PFX ## _pixels_tab[IDX][ 9] = ff_ ## PFX ## NUM ## _mc12_c; \ - c->PFX ## _pixels_tab[IDX][10] = ff_ ## PFX ## NUM ## _mc22_c; \ - c->PFX ## _pixels_tab[IDX][11] = ff_ ## PFX ## NUM ## _mc32_c; \ - c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_c; \ - c->PFX ## _pixels_tab[IDX][13] = ff_ ## PFX ## NUM ## _mc13_c; \ - c->PFX ## _pixels_tab[IDX][14] = ff_ ## PFX ## NUM ## _mc23_c; \ - c->PFX ## _pixels_tab[IDX][15] = ff_ ## PFX ## NUM ## _mc33_c - dspfunc(put_cavs_qpel, 0, 16); - dspfunc(put_cavs_qpel, 1, 8); - dspfunc(avg_cavs_qpel, 0, 16); - dspfunc(avg_cavs_qpel, 1, 8); - c->cavs_filter_lv = cavs_filter_lv_c; - c->cavs_filter_lh = cavs_filter_lh_c; - c->cavs_filter_cv = cavs_filter_cv_c; - c->cavs_filter_ch = cavs_filter_ch_c; - c->cavs_idct8_add = cavs_idct8_add_c; -} diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/cljr.c --- a/src/ffmpeg/libavcodec/cljr.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ -/* - * Cirrus Logic AccuPak (CLJR) codec - * Copyright (c) 2003 Alex Beregszaszi - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/** - * @file cljr.c - * Cirrus Logic AccuPak codec. - */ - -#include "avcodec.h" -#include "mpegvideo.h" - -typedef struct CLJRContext{ - AVCodecContext *avctx; - AVFrame picture; - int delta[16]; - int offset[4]; - GetBitContext gb; -} CLJRContext; - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - CLJRContext * const a = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&a->picture; - int x, y; - - if(p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference= 0; - if(avctx->get_buffer(avctx, p) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - p->pict_type= I_TYPE; - p->key_frame= 1; - - init_get_bits(&a->gb, buf, buf_size); - - for(y=0; yheight; y++){ - uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ]; - uint8_t *cb= &a->picture.data[1][ y*a->picture.linesize[1] ]; - uint8_t *cr= &a->picture.data[2][ y*a->picture.linesize[2] ]; - for(x=0; xwidth; x+=4){ - luma[3] = get_bits(&a->gb, 5) << 3; - luma[2] = get_bits(&a->gb, 5) << 3; - luma[1] = get_bits(&a->gb, 5) << 3; - luma[0] = get_bits(&a->gb, 5) << 3; - luma+= 4; - *(cb++) = get_bits(&a->gb, 6) << 2; - *(cr++) = get_bits(&a->gb, 6) << 2; - } - } - - *picture= *(AVFrame*)&a->picture; - *data_size = sizeof(AVPicture); - - emms_c(); - - return buf_size; -} - -#if 0 -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - CLJRContext * const a = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&a->picture; - int size; - int mb_x, mb_y; - - *p = *pict; - p->pict_type= I_TYPE; - p->key_frame= 1; - - emms_c(); - - align_put_bits(&a->pb); - while(get_bit_count(&a->pb)&31) - put_bits(&a->pb, 8, 0); - - size= get_bit_count(&a->pb)/32; - - return size*4; -} -#endif - -static void common_init(AVCodecContext *avctx){ - CLJRContext * const a = avctx->priv_data; - - avctx->coded_frame= (AVFrame*)&a->picture; - a->avctx= avctx; -} - -static int decode_init(AVCodecContext *avctx){ - - common_init(avctx); - - avctx->pix_fmt= PIX_FMT_YUV411P; - - return 0; -} - -#if 0 -static int encode_init(AVCodecContext *avctx){ - - common_init(avctx); - - return 0; -} -#endif - -AVCodec cljr_decoder = { - "cljr", - CODEC_TYPE_VIDEO, - CODEC_ID_CLJR, - sizeof(CLJRContext), - decode_init, - NULL, - NULL, - decode_frame, - CODEC_CAP_DR1, -}; -#if 0 -#ifdef CONFIG_ENCODERS - -AVCodec cljr_encoder = { - "cljr", - CODEC_TYPE_VIDEO, - CODEC_ID_cljr, - sizeof(CLJRContext), - encode_init, - encode_frame, - //encode_end, -}; - -#endif //CONFIG_ENCODERS -#endif diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/cyuv.c --- a/src/ffmpeg/libavcodec/cyuv.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/* - * - * Copyright (C) 2003 the ffmpeg project - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Creative YUV (CYUV) Video Decoder - * by Mike Melanson (melanson@pcisys.net) - * based on "Creative YUV (CYUV) stream format for AVI": - * http://www.csse.monash.edu.au/~timf/videocodec/cyuv.txt - * - */ - -/** - * @file cyuv.c - * Creative YUV (CYUV) Video Decoder. - */ - -#include -#include -#include -#include - -#include "common.h" -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" - - -typedef struct CyuvDecodeContext { - AVCodecContext *avctx; - int width, height; - AVFrame frame; -} CyuvDecodeContext; - -static int cyuv_decode_init(AVCodecContext *avctx) -{ - CyuvDecodeContext *s = avctx->priv_data; - - s->avctx = avctx; - s->width = avctx->width; - /* width needs to be divisible by 4 for this codec to work */ - if (s->width & 0x3) - return -1; - s->height = avctx->height; - avctx->pix_fmt = PIX_FMT_YUV411P; - avctx->has_b_frames = 0; - - return 0; -} - -static int cyuv_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - CyuvDecodeContext *s=avctx->priv_data; - - unsigned char *y_plane; - unsigned char *u_plane; - unsigned char *v_plane; - int y_ptr; - int u_ptr; - int v_ptr; - - /* prediction error tables (make it clear that they are signed values) */ - signed char *y_table = (signed char*)buf + 0; - signed char *u_table = (signed char*)buf + 16; - signed char *v_table = (signed char*)buf + 32; - - unsigned char y_pred, u_pred, v_pred; - int stream_ptr; - unsigned char cur_byte; - int pixel_groups; - - /* sanity check the buffer size: A buffer has 3x16-bytes tables - * followed by (height) lines each with 3 bytes to represent groups - * of 4 pixels. Thus, the total size of the buffer ought to be: - * (3 * 16) + height * (width * 3 / 4) */ - if (buf_size != 48 + s->height * (s->width * 3 / 4)) { - av_log(avctx, AV_LOG_ERROR, "ffmpeg: cyuv: got a buffer with %d bytes when %d were expected\n", - buf_size, - 48 + s->height * (s->width * 3 / 4)); - return -1; - } - - /* pixel data starts 48 bytes in, after 3x16-byte tables */ - stream_ptr = 48; - - if(s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; - s->frame.reference = 0; - if(avctx->get_buffer(avctx, &s->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - y_plane = s->frame.data[0]; - u_plane = s->frame.data[1]; - v_plane = s->frame.data[2]; - - /* iterate through each line in the height */ - for (y_ptr = 0, u_ptr = 0, v_ptr = 0; - y_ptr < (s->height * s->frame.linesize[0]); - y_ptr += s->frame.linesize[0] - s->width, - u_ptr += s->frame.linesize[1] - s->width / 4, - v_ptr += s->frame.linesize[2] - s->width / 4) { - - /* reset predictors */ - cur_byte = buf[stream_ptr++]; - u_plane[u_ptr++] = u_pred = cur_byte & 0xF0; - y_plane[y_ptr++] = y_pred = (cur_byte & 0x0F) << 4; - - cur_byte = buf[stream_ptr++]; - v_plane[v_ptr++] = v_pred = cur_byte & 0xF0; - y_pred += y_table[cur_byte & 0x0F]; - y_plane[y_ptr++] = y_pred; - - cur_byte = buf[stream_ptr++]; - y_pred += y_table[cur_byte & 0x0F]; - y_plane[y_ptr++] = y_pred; - y_pred += y_table[(cur_byte & 0xF0) >> 4]; - y_plane[y_ptr++] = y_pred; - - /* iterate through the remaining pixel groups (4 pixels/group) */ - pixel_groups = s->width / 4 - 1; - while (pixel_groups--) { - - cur_byte = buf[stream_ptr++]; - u_pred += u_table[(cur_byte & 0xF0) >> 4]; - u_plane[u_ptr++] = u_pred; - y_pred += y_table[cur_byte & 0x0F]; - y_plane[y_ptr++] = y_pred; - - cur_byte = buf[stream_ptr++]; - v_pred += v_table[(cur_byte & 0xF0) >> 4]; - v_plane[v_ptr++] = v_pred; - y_pred += y_table[cur_byte & 0x0F]; - y_plane[y_ptr++] = y_pred; - - cur_byte = buf[stream_ptr++]; - y_pred += y_table[cur_byte & 0x0F]; - y_plane[y_ptr++] = y_pred; - y_pred += y_table[(cur_byte & 0xF0) >> 4]; - y_plane[y_ptr++] = y_pred; - - } - } - - *data_size=sizeof(AVFrame); - *(AVFrame*)data= s->frame; - - return buf_size; -} - -static int cyuv_decode_end(AVCodecContext *avctx) -{ -/* CyuvDecodeContext *s = avctx->priv_data;*/ - - return 0; -} - -AVCodec cyuv_decoder = { - "cyuv", - CODEC_TYPE_VIDEO, - CODEC_ID_CYUV, - sizeof(CyuvDecodeContext), - cyuv_decode_init, - NULL, - cyuv_decode_end, - cyuv_decode_frame, - CODEC_CAP_DR1, - NULL -}; - diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/dsputil.c --- a/src/ffmpeg/libavcodec/dsputil.c Mon Mar 12 13:00:06 2007 -0700 +++ b/src/ffmpeg/libavcodec/dsputil.c Mon Mar 12 13:06:30 2007 -0700 @@ -3,45 +3,34 @@ * Copyright (c) 2000, 2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or + * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * version 2 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer */ - + /** * @file dsputil.c * DSP utils */ - + #include "avcodec.h" #include "dsputil.h" -#include "mpegvideo.h" #include "simple_idct.h" -#include "faandct.h" -#include "snow.h" -/* snow.c */ -void ff_spatial_dwt(int *buffer, int width, int height, int stride, int type, int decomposition_count); - -/* vorbis.c */ -void vorbis_inverse_coupling(float *mag, float *ang, int blocksize); - -uint8_t cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; -uint32_t squareTbl[512] = {0, }; +uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; +uint32_t squareTbl[512]; const uint8_t ff_zigzag_direct[64] = { 0, 1, 8, 16, 9, 2, 3, 10, @@ -68,96 +57,96 @@ }; /* not permutated inverse zigzag_direct + 1 for MMX quantizer */ -DECLARE_ALIGNED_8(uint16_t, inv_zigzag_direct16[64]) = {0, }; +uint16_t __align8 inv_zigzag_direct16[64]; const uint8_t ff_alternate_horizontal_scan[64] = { - 0, 1, 2, 3, 8, 9, 16, 17, + 0, 1, 2, 3, 8, 9, 16, 17, 10, 11, 4, 5, 6, 7, 15, 14, - 13, 12, 19, 18, 24, 25, 32, 33, + 13, 12, 19, 18, 24, 25, 32, 33, 26, 27, 20, 21, 22, 23, 28, 29, - 30, 31, 34, 35, 40, 41, 48, 49, + 30, 31, 34, 35, 40, 41, 48, 49, 42, 43, 36, 37, 38, 39, 44, 45, - 46, 47, 50, 51, 56, 57, 58, 59, + 46, 47, 50, 51, 56, 57, 58, 59, 52, 53, 54, 55, 60, 61, 62, 63, }; const uint8_t ff_alternate_vertical_scan[64] = { - 0, 8, 16, 24, 1, 9, 2, 10, + 0, 8, 16, 24, 1, 9, 2, 10, 17, 25, 32, 40, 48, 56, 57, 49, - 41, 33, 26, 18, 3, 11, 4, 12, + 41, 33, 26, 18, 3, 11, 4, 12, 19, 27, 34, 42, 50, 58, 35, 43, - 51, 59, 20, 28, 5, 13, 6, 14, + 51, 59, 20, 28, 5, 13, 6, 14, 21, 29, 36, 44, 52, 60, 37, 45, - 53, 61, 22, 30, 7, 15, 23, 31, + 53, 61, 22, 30, 7, 15, 23, 31, 38, 46, 54, 62, 39, 47, 55, 63, }; /* a*inverse[b]>>32 == a/b for all 0<=a<=65536 && 2<=b<=255 */ const uint32_t inverse[256]={ - 0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757, - 536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154, - 268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709, - 178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333, - 134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367, - 107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283, - 89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315, - 76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085, - 67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498, - 59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675, - 53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441, - 48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183, - 44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712, - 41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400, - 38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163, - 35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641, - 33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573, - 31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737, - 29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493, - 28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373, - 26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368, - 25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671, - 24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767, - 23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740, - 22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751, - 21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635, - 20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593, - 19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944, - 19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933, - 18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575, - 17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532, + 0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757, + 536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154, + 268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709, + 178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333, + 134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367, + 107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283, + 89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315, + 76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085, + 67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498, + 59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675, + 53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441, + 48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183, + 44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712, + 41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400, + 38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163, + 35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641, + 33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573, + 31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737, + 29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493, + 28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373, + 26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368, + 25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671, + 24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767, + 23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740, + 22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751, + 21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635, + 20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593, + 19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944, + 19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933, + 18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575, + 17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532, 17318417, 17248865, 17179870, 17111424, 17043522, 16976156, 16909321, 16843010, }; /* Input permutation for the simple_idct_mmx */ static const uint8_t simple_mmx_permutation[64]={ - 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, - 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, - 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, - 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, - 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, - 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, - 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, - 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, + 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, + 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, + 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, + 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, + 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, + 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, + 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, + 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, }; - +#if 0 static int pix_sum_c(uint8_t * pix, int line_size) { int s, i, j; s = 0; for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j += 8) { - s += pix[0]; - s += pix[1]; - s += pix[2]; - s += pix[3]; - s += pix[4]; - s += pix[5]; - s += pix[6]; - s += pix[7]; - pix += 8; - } - pix += line_size - 16; + for (j = 0; j < 16; j += 8) { + s += pix[0]; + s += pix[1]; + s += pix[2]; + s += pix[3]; + s += pix[4]; + s += pix[5]; + s += pix[6]; + s += pix[7]; + pix += 8; + } + pix += line_size - 16; } return s; } @@ -169,33 +158,33 @@ s = 0; for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j += 8) { + for (j = 0; j < 16; j += 8) { #if 0 - s += sq[pix[0]]; - s += sq[pix[1]]; - s += sq[pix[2]]; - s += sq[pix[3]]; - s += sq[pix[4]]; - s += sq[pix[5]]; - s += sq[pix[6]]; - s += sq[pix[7]]; + s += sq[pix[0]]; + s += sq[pix[1]]; + s += sq[pix[2]]; + s += sq[pix[3]]; + s += sq[pix[4]]; + s += sq[pix[5]]; + s += sq[pix[6]]; + s += sq[pix[7]]; #else #if LONG_MAX > 2147483647 - register uint64_t x=*(uint64_t*)pix; - s += sq[x&0xff]; - s += sq[(x>>8)&0xff]; - s += sq[(x>>16)&0xff]; - s += sq[(x>>24)&0xff]; + register uint64_t x=*(uint64_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; s += sq[(x>>32)&0xff]; s += sq[(x>>40)&0xff]; s += sq[(x>>48)&0xff]; s += sq[(x>>56)&0xff]; #else - register uint32_t x=*(uint32_t*)pix; - s += sq[x&0xff]; - s += sq[(x>>8)&0xff]; - s += sq[(x>>16)&0xff]; - s += sq[(x>>24)&0xff]; + register uint32_t x=*(uint32_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; x=*(uint32_t*)(pix+4); s += sq[x&0xff]; s += sq[(x>>8)&0xff]; @@ -203,16 +192,16 @@ s += sq[(x>>24)&0xff]; #endif #endif - pix += 8; - } - pix += line_size - 16; + pix += 8; + } + pix += line_size - 16; } return s; } static void bswap_buf(uint32_t *dst, uint32_t *src, int w){ int i; - + for(i=0; i+8<=w; i+=8){ dst[i+0]= bswap_32(src[i+0]); dst[i+1]= bswap_32(src[i+1]); @@ -228,23 +217,6 @@ } } -static int sse4_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) -{ - int s, i; - uint32_t *sq = squareTbl + 256; - - s = 0; - for (i = 0; i < h; i++) { - s += sq[pix1[0] - pix2[0]]; - s += sq[pix1[1] - pix2[1]]; - s += sq[pix1[2] - pix2[2]]; - s += sq[pix1[3] - pix2[3]]; - pix1 += line_size; - pix2 += line_size; - } - return s; -} - static int sse8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { int s, i; @@ -296,102 +268,6 @@ return s; } - -#ifdef CONFIG_SNOW_ENCODER //dwt is in snow.c -static inline int w_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int w, int h, int type){ - int s, i, j; - const int dec_count= w==8 ? 3 : 4; - int tmp[32*32]; - int level, ori; - static const int scale[2][2][4][4]={ - { - { - // 9/7 8x8 dec=3 - {268, 239, 239, 213}, - { 0, 224, 224, 152}, - { 0, 135, 135, 110}, - },{ - // 9/7 16x16 or 32x32 dec=4 - {344, 310, 310, 280}, - { 0, 320, 320, 228}, - { 0, 175, 175, 136}, - { 0, 129, 129, 102}, - } - },{ - { - // 5/3 8x8 dec=3 - {275, 245, 245, 218}, - { 0, 230, 230, 156}, - { 0, 138, 138, 113}, - },{ - // 5/3 16x16 or 32x32 dec=4 - {352, 317, 317, 286}, - { 0, 328, 328, 233}, - { 0, 180, 180, 140}, - { 0, 132, 132, 105}, - } - } - }; - - for (i = 0; i < h; i++) { - for (j = 0; j < w; j+=4) { - tmp[32*i+j+0] = (pix1[j+0] - pix2[j+0])<<4; - tmp[32*i+j+1] = (pix1[j+1] - pix2[j+1])<<4; - tmp[32*i+j+2] = (pix1[j+2] - pix2[j+2])<<4; - tmp[32*i+j+3] = (pix1[j+3] - pix2[j+3])<<4; - } - pix1 += line_size; - pix2 += line_size; - } - - ff_spatial_dwt(tmp, w, h, 32, type, dec_count); - - s=0; - assert(w==h); - for(level=0; level>(dec_count-level); - int sx= (ori&1) ? size : 0; - int stride= 32<<(dec_count-level); - int sy= (ori&2) ? stride>>1 : 0; - - for(i=0; i=0); - return s>>9; -} - -static int w53_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ - return w_c(v, pix1, pix2, line_size, 8, h, 1); -} - -static int w97_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ - return w_c(v, pix1, pix2, line_size, 8, h, 0); -} - -static int w53_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ - return w_c(v, pix1, pix2, line_size, 16, h, 1); -} - -static int w97_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ - return w_c(v, pix1, pix2, line_size, 16, h, 0); -} - -int w53_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ - return w_c(v, pix1, pix2, line_size, 32, h, 1); -} - -int w97_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ - return w_c(v, pix1, pix2, line_size, 32, h, 0); -} -#endif - static void get_pixels_c(DCTELEM *restrict block, const uint8_t *pixels, int line_size) { int i; @@ -412,7 +288,7 @@ } static void diff_pixels_c(DCTELEM *restrict block, const uint8_t *s1, - const uint8_t *s2, int stride){ + const uint8_t *s2, int stride){ int i; /* read the pixels */ @@ -433,11 +309,11 @@ static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) + int line_size) { int i; uint8_t *cm = cropTbl + MAX_NEG_CROP; - + /* read the pixels */ for(i=0;i<8;i++) { pixels[0] = cm[block[0]]; @@ -454,67 +330,12 @@ } } -static void put_pixels_clamped4_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) -{ - int i; - uint8_t *cm = cropTbl + MAX_NEG_CROP; - - /* read the pixels */ - for(i=0;i<4;i++) { - pixels[0] = cm[block[0]]; - pixels[1] = cm[block[1]]; - pixels[2] = cm[block[2]]; - pixels[3] = cm[block[3]]; - - pixels += line_size; - block += 8; - } -} - -static void put_pixels_clamped2_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) -{ - int i; - uint8_t *cm = cropTbl + MAX_NEG_CROP; - - /* read the pixels */ - for(i=0;i<2;i++) { - pixels[0] = cm[block[0]]; - pixels[1] = cm[block[1]]; - - pixels += line_size; - block += 8; - } -} - -static void put_signed_pixels_clamped_c(const DCTELEM *block, - uint8_t *restrict pixels, - int line_size) -{ - int i, j; - - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - if (*block < -128) - *pixels = 0; - else if (*block > 127) - *pixels = 255; - else - *pixels = (uint8_t)(*block + 128); - block++; - pixels++; - } - pixels += (line_size - 8); - } -} - static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, int line_size) { int i; uint8_t *cm = cropTbl + MAX_NEG_CROP; - + /* read the pixels */ for(i=0;i<8;i++) { pixels[0] = cm[pixels[0] + block[0]]; @@ -529,69 +350,7 @@ block += 8; } } - -static void add_pixels_clamped4_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) -{ - int i; - uint8_t *cm = cropTbl + MAX_NEG_CROP; - - /* read the pixels */ - for(i=0;i<4;i++) { - pixels[0] = cm[pixels[0] + block[0]]; - pixels[1] = cm[pixels[1] + block[1]]; - pixels[2] = cm[pixels[2] + block[2]]; - pixels[3] = cm[pixels[3] + block[3]]; - pixels += line_size; - block += 8; - } -} - -static void add_pixels_clamped2_c(const DCTELEM *block, uint8_t *restrict pixels, - int line_size) -{ - int i; - uint8_t *cm = cropTbl + MAX_NEG_CROP; - - /* read the pixels */ - for(i=0;i<2;i++) { - pixels[0] = cm[pixels[0] + block[0]]; - pixels[1] = cm[pixels[1] + block[1]]; - pixels += line_size; - block += 8; - } -} - -static void add_pixels8_c(uint8_t *restrict pixels, DCTELEM *block, int line_size) -{ - int i; - for(i=0;i<8;i++) { - pixels[0] += block[0]; - pixels[1] += block[1]; - pixels[2] += block[2]; - pixels[3] += block[3]; - pixels[4] += block[4]; - pixels[5] += block[5]; - pixels[6] += block[6]; - pixels[7] += block[7]; - pixels += line_size; - block += 8; - } -} - -static void add_pixels4_c(uint8_t *restrict pixels, DCTELEM *block, int line_size) -{ - int i; - for(i=0;i<4;i++) { - pixels[0] += block[0]; - pixels[1] += block[1]; - pixels[2] += block[2]; - pixels[3] += block[3]; - pixels += line_size; - block += 4; - } -} - +#endif #if 0 #define PIXOP2(OPNAME, OP) \ @@ -1106,2760 +865,14 @@ #endif #define op_put(a, b) a = b -PIXOP2(avg, op_avg) -PIXOP2(put, op_put) +//PIXOP2(avg, op_avg) +//PIXOP2(put, op_put) #undef op_avg #undef op_put #define avg2(a,b) ((a+b+1)>>1) #define avg4(a,b,c,d) ((a+b+c+d+2)>>2) -static void put_no_rnd_pixels16_l2_c(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){ - put_no_rnd_pixels16_l2(dst, a, b, stride, stride, stride, h); -} - -static void put_no_rnd_pixels8_l2_c(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){ - put_no_rnd_pixels8_l2(dst, a, b, stride, stride, stride, h); -} - -static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, int x16, int y16, int rounder) -{ - const int A=(16-x16)*(16-y16); - const int B=( x16)*(16-y16); - const int C=(16-x16)*( y16); - const int D=( x16)*( y16); - int i; - - for(i=0; i>8; - dst[1]= (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + rounder)>>8; - dst[2]= (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + rounder)>>8; - dst[3]= (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + rounder)>>8; - dst[4]= (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + rounder)>>8; - dst[5]= (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + rounder)>>8; - dst[6]= (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + rounder)>>8; - dst[7]= (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + rounder)>>8; - dst+= stride; - src+= stride; - } -} - -void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, - int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height) -{ - int y, vx, vy; - const int s= 1<>16; - src_y= vy>>16; - frac_x= src_x&(s-1); - frac_y= src_y&(s-1); - src_x>>=shift; - src_y>>=shift; - - if((unsigned)src_x < width){ - if((unsigned)src_y < height){ - index= src_x + src_y*stride; - dst[y*stride + x]= ( ( src[index ]*(s-frac_x) - + src[index +1]* frac_x )*(s-frac_y) - + ( src[index+stride ]*(s-frac_x) - + src[index+stride+1]* frac_x )* frac_y - + r)>>(shift*2); - }else{ - index= src_x + clip(src_y, 0, height)*stride; - dst[y*stride + x]= ( ( src[index ]*(s-frac_x) - + src[index +1]* frac_x )*s - + r)>>(shift*2); - } - }else{ - if((unsigned)src_y < height){ - index= clip(src_x, 0, width) + src_y*stride; - dst[y*stride + x]= ( ( src[index ]*(s-frac_y) - + src[index+stride ]* frac_y )*s - + r)>>(shift*2); - }else{ - index= clip(src_x, 0, width) + clip(src_y, 0, height)*stride; - dst[y*stride + x]= src[index ]; - } - } - - vx+= dxx; - vy+= dyx; - } - ox += dxy; - oy += dyy; - } -} - -static inline void put_tpel_pixels_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - switch(width){ - case 2: put_pixels2_c (dst, src, stride, height); break; - case 4: put_pixels4_c (dst, src, stride, height); break; - case 8: put_pixels8_c (dst, src, stride, height); break; - case 16:put_pixels16_c(dst, src, stride, height); break; - } -} - -static inline void put_tpel_pixels_mc10_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (683*(2*src[j] + src[j+1] + 1)) >> 11; - } - src += stride; - dst += stride; - } -} - -static inline void put_tpel_pixels_mc20_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (683*(src[j] + 2*src[j+1] + 1)) >> 11; - } - src += stride; - dst += stride; - } -} - -static inline void put_tpel_pixels_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (683*(2*src[j] + src[j+stride] + 1)) >> 11; - } - src += stride; - dst += stride; - } -} - -static inline void put_tpel_pixels_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15; - } - src += stride; - dst += stride; - } -} - -static inline void put_tpel_pixels_mc12_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; - } - src += stride; - dst += stride; - } -} - -static inline void put_tpel_pixels_mc02_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (683*(src[j] + 2*src[j+stride] + 1)) >> 11; - } - src += stride; - dst += stride; - } -} - -static inline void put_tpel_pixels_mc21_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; - } - src += stride; - dst += stride; - } -} - -static inline void put_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15; - } - src += stride; - dst += stride; - } -} - -static inline void avg_tpel_pixels_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - switch(width){ - case 2: avg_pixels2_c (dst, src, stride, height); break; - case 4: avg_pixels4_c (dst, src, stride, height); break; - case 8: avg_pixels8_c (dst, src, stride, height); break; - case 16:avg_pixels16_c(dst, src, stride, height); break; - } -} - -static inline void avg_tpel_pixels_mc10_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((683*(2*src[j] + src[j+1] + 1)) >> 11) + 1) >> 1; - } - src += stride; - dst += stride; - } -} - -static inline void avg_tpel_pixels_mc20_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+1] + 1)) >> 11) + 1) >> 1; - } - src += stride; - dst += stride; - } -} - -static inline void avg_tpel_pixels_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((683*(2*src[j] + src[j+stride] + 1)) >> 11) + 1) >> 1; - } - src += stride; - dst += stride; - } -} - -static inline void avg_tpel_pixels_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15) + 1) >> 1; - } - src += stride; - dst += stride; - } -} - -static inline void avg_tpel_pixels_mc12_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; - } - src += stride; - dst += stride; - } -} - -static inline void avg_tpel_pixels_mc02_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+stride] + 1)) >> 11) + 1) >> 1; - } - src += stride; - dst += stride; - } -} - -static inline void avg_tpel_pixels_mc21_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; - } - src += stride; - dst += stride; - } -} - -static inline void avg_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ - int i,j; - for (i=0; i < height; i++) { - for (j=0; j < width; j++) { - dst[j] = (dst[j] + ((2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15) + 1) >> 1; - } - src += stride; - dst += stride; - } -} -#if 0 -#define TPEL_WIDTH(width)\ -static void put_tpel_pixels ## width ## _mc00_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ - void put_tpel_pixels_mc00_c(dst, src, stride, width, height);}\ -static void put_tpel_pixels ## width ## _mc10_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ - void put_tpel_pixels_mc10_c(dst, src, stride, width, height);}\ -static void put_tpel_pixels ## width ## _mc20_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ - void put_tpel_pixels_mc20_c(dst, src, stride, width, height);}\ -static void put_tpel_pixels ## width ## _mc01_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ - void put_tpel_pixels_mc01_c(dst, src, stride, width, height);}\ -static void put_tpel_pixels ## width ## _mc11_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ - void put_tpel_pixels_mc11_c(dst, src, stride, width, height);}\ -static void put_tpel_pixels ## width ## _mc21_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ - void put_tpel_pixels_mc21_c(dst, src, stride, width, height);}\ -static void put_tpel_pixels ## width ## _mc02_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ - void put_tpel_pixels_mc02_c(dst, src, stride, width, height);}\ -static void put_tpel_pixels ## width ## _mc12_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ - void put_tpel_pixels_mc12_c(dst, src, stride, width, height);}\ -static void put_tpel_pixels ## width ## _mc22_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ - void put_tpel_pixels_mc22_c(dst, src, stride, width, height);} -#endif - -#define H264_CHROMA_MC(OPNAME, OP)\ -static void OPNAME ## h264_chroma_mc2_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\ - const int A=(8-x)*(8-y);\ - const int B=( x)*(8-y);\ - const int C=(8-x)*( y);\ - const int D=( x)*( y);\ - int i;\ - \ - assert(x<8 && y<8 && x>=0 && y>=0);\ -\ - for(i=0; i=0 && y>=0);\ -\ - for(i=0; i=0 && y>=0);\ -\ - for(i=0; i>6)+1)>>1) -#define op_put(a, b) a = (((b) + 32)>>6) - -H264_CHROMA_MC(put_ , op_put) -H264_CHROMA_MC(avg_ , op_avg) -#undef op_avg -#undef op_put - -static void put_no_rnd_h264_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){ - const int A=(8-x)*(8-y); - const int B=( x)*(8-y); - const int C=(8-x)*( y); - const int D=( x)*( y); - int i; - - assert(x<8 && y<8 && x>=0 && y>=0); - - for(i=0; i> 6; - dst[1] = (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + 32 - 4) >> 6; - dst[2] = (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + 32 - 4) >> 6; - dst[3] = (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + 32 - 4) >> 6; - dst[4] = (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + 32 - 4) >> 6; - dst[5] = (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + 32 - 4) >> 6; - dst[6] = (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + 32 - 4) >> 6; - dst[7] = (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + 32 - 4) >> 6; - dst+= stride; - src+= stride; - } -} - -static inline void copy_block2(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) -{ - int i; - for(i=0; i>5]+1)>>1) -#define op_avg_no_rnd(a, b) a = (((a)+cm[((b) + 15)>>5])>>1) -#define op_put(a, b) a = cm[((b) + 16)>>5] -#define op_put_no_rnd(a, b) a = cm[((b) + 15)>>5] - -QPEL_MC(0, put_ , _ , op_put) -QPEL_MC(1, put_no_rnd_, _no_rnd_, op_put_no_rnd) -QPEL_MC(0, avg_ , _ , op_avg) -//QPEL_MC(1, avg_no_rnd , _ , op_avg) -#undef op_avg -#undef op_avg_no_rnd -#undef op_put -#undef op_put_no_rnd - -#if 1 -#define H264_LOWPASS(OPNAME, OP, OP2) \ -static void OPNAME ## h264_qpel2_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ - const int h=2;\ - uint8_t *cm = cropTbl + MAX_NEG_CROP;\ - int i;\ - for(i=0; i>5]+1)>>1) -//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7) -#define op_put(a, b) a = cm[((b) + 16)>>5] -#define op2_avg(a, b) a = (((a)+cm[((b) + 512)>>10]+1)>>1) -#define op2_put(a, b) a = cm[((b) + 512)>>10] - -H264_LOWPASS(put_ , op_put, op2_put) -H264_LOWPASS(avg_ , op_avg, op2_avg) -H264_MC(put_, 2) -H264_MC(put_, 4) -H264_MC(put_, 8) -H264_MC(put_, 16) -H264_MC(avg_, 4) -H264_MC(avg_, 8) -H264_MC(avg_, 16) - -#undef op_avg -#undef op_put -#undef op2_avg -#undef op2_put -#endif - -#define op_scale1(x) block[x] = clip_uint8( (block[x]*weight + offset) >> log2_denom ) -#define op_scale2(x) dst[x] = clip_uint8( (src[x]*weights + dst[x]*weightd + offset) >> (log2_denom+1)) -#define H264_WEIGHT(W,H) \ -static void weight_h264_pixels ## W ## x ## H ## _c(uint8_t *block, int stride, int log2_denom, int weight, int offset){ \ - int y; \ - offset <<= log2_denom; \ - if(log2_denom) offset += 1<<(log2_denom-1); \ - for(y=0; y>4]; - dst[1]= cm[(9*(src[1] + src[2]) - (src[ 0] + src[3]) + 8)>>4]; - dst[2]= cm[(9*(src[2] + src[3]) - (src[ 1] + src[4]) + 8)>>4]; - dst[3]= cm[(9*(src[3] + src[4]) - (src[ 2] + src[5]) + 8)>>4]; - dst[4]= cm[(9*(src[4] + src[5]) - (src[ 3] + src[6]) + 8)>>4]; - dst[5]= cm[(9*(src[5] + src[6]) - (src[ 4] + src[7]) + 8)>>4]; - dst[6]= cm[(9*(src[6] + src[7]) - (src[ 5] + src[8]) + 8)>>4]; - dst[7]= cm[(9*(src[7] + src[8]) - (src[ 6] + src[9]) + 8)>>4]; - dst+=dstStride; - src+=srcStride; - } -} - -#ifdef CONFIG_CAVS_DECODER -/* AVS specific */ -void ff_cavsdsp_init(DSPContext* c, AVCodecContext *avctx); - -void ff_put_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride) { - put_pixels8_c(dst, src, stride, 8); -} -void ff_avg_cavs_qpel8_mc00_c(uint8_t *dst, uint8_t *src, int stride) { - avg_pixels8_c(dst, src, stride, 8); -} -void ff_put_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride) { - put_pixels16_c(dst, src, stride, 16); -} -void ff_avg_cavs_qpel16_mc00_c(uint8_t *dst, uint8_t *src, int stride) { - avg_pixels16_c(dst, src, stride, 16); -} -#endif /* CONFIG_CAVS_DECODER */ - -#if defined(CONFIG_VC1_DECODER) || defined(CONFIG_WMV3_DECODER) -/* VC-1 specific */ -void ff_vc1dsp_init(DSPContext* c, AVCodecContext *avctx); - -void ff_put_vc1_mspel_mc00_c(uint8_t *dst, uint8_t *src, int stride, int rnd) { - put_pixels8_c(dst, src, stride, 8); -} -#endif /* CONFIG_VC1_DECODER||CONFIG_WMV3_DECODER */ - -static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w){ - uint8_t *cm = cropTbl + MAX_NEG_CROP; - int i; - - for(i=0; i>4]; - dst[1*dstStride]= cm[(9*(src1 + src2) - (src0 + src3) + 8)>>4]; - dst[2*dstStride]= cm[(9*(src2 + src3) - (src1 + src4) + 8)>>4]; - dst[3*dstStride]= cm[(9*(src3 + src4) - (src2 + src5) + 8)>>4]; - dst[4*dstStride]= cm[(9*(src4 + src5) - (src3 + src6) + 8)>>4]; - dst[5*dstStride]= cm[(9*(src5 + src6) - (src4 + src7) + 8)>>4]; - dst[6*dstStride]= cm[(9*(src6 + src7) - (src5 + src8) + 8)>>4]; - dst[7*dstStride]= cm[(9*(src7 + src8) - (src6 + src9) + 8)>>4]; - src++; - dst++; - } -} - -static void put_mspel8_mc00_c (uint8_t *dst, uint8_t *src, int stride){ - put_pixels8_c(dst, src, stride, 8); -} - -static void put_mspel8_mc10_c(uint8_t *dst, uint8_t *src, int stride){ - uint8_t half[64]; - wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); - put_pixels8_l2(dst, src, half, stride, stride, 8, 8); -} - -static void put_mspel8_mc20_c(uint8_t *dst, uint8_t *src, int stride){ - wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8); -} - -static void put_mspel8_mc30_c(uint8_t *dst, uint8_t *src, int stride){ - uint8_t half[64]; - wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); - put_pixels8_l2(dst, src+1, half, stride, stride, 8, 8); -} - -static void put_mspel8_mc02_c(uint8_t *dst, uint8_t *src, int stride){ - wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8); -} - -static void put_mspel8_mc12_c(uint8_t *dst, uint8_t *src, int stride){ - uint8_t halfH[88]; - uint8_t halfV[64]; - uint8_t halfHV[64]; - wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); - wmv2_mspel8_v_lowpass(halfV, src, 8, stride, 8); - wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8); - put_pixels8_l2(dst, halfV, halfHV, stride, 8, 8, 8); -} -static void put_mspel8_mc32_c(uint8_t *dst, uint8_t *src, int stride){ - uint8_t halfH[88]; - uint8_t halfV[64]; - uint8_t halfHV[64]; - wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); - wmv2_mspel8_v_lowpass(halfV, src+1, 8, stride, 8); - wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8); - put_pixels8_l2(dst, halfV, halfHV, stride, 8, 8, 8); -} -static void put_mspel8_mc22_c(uint8_t *dst, uint8_t *src, int stride){ - uint8_t halfH[88]; - wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); - wmv2_mspel8_v_lowpass(dst, halfH+8, stride, 8, 8); -} - -static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale){ - int x; - const int strength= ff_h263_loop_filter_strength[qscale]; - - for(x=0; x<8; x++){ - int d1, d2, ad1; - int p0= src[x-2*stride]; - int p1= src[x-1*stride]; - int p2= src[x+0*stride]; - int p3= src[x+1*stride]; - int d = (p0 - p3 + 4*(p2 - p1)) / 8; - - if (d<-2*strength) d1= 0; - else if(d<- strength) d1=-2*strength - d; - else if(d< strength) d1= d; - else if(d< 2*strength) d1= 2*strength - d; - else d1= 0; - - p1 += d1; - p2 -= d1; - if(p1&256) p1= ~(p1>>31); - if(p2&256) p2= ~(p2>>31); - - src[x-1*stride] = p1; - src[x+0*stride] = p2; - - ad1= FFABS(d1)>>1; - - d2= clip((p0-p3)/4, -ad1, ad1); - - src[x-2*stride] = p0 - d2; - src[x+ stride] = p3 + d2; - } -} - -static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){ - int y; - const int strength= ff_h263_loop_filter_strength[qscale]; - - for(y=0; y<8; y++){ - int d1, d2, ad1; - int p0= src[y*stride-2]; - int p1= src[y*stride-1]; - int p2= src[y*stride+0]; - int p3= src[y*stride+1]; - int d = (p0 - p3 + 4*(p2 - p1)) / 8; - - if (d<-2*strength) d1= 0; - else if(d<- strength) d1=-2*strength - d; - else if(d< strength) d1= d; - else if(d< 2*strength) d1= 2*strength - d; - else d1= 0; - - p1 += d1; - p2 -= d1; - if(p1&256) p1= ~(p1>>31); - if(p2&256) p2= ~(p2>>31); - - src[y*stride-1] = p1; - src[y*stride+0] = p2; - - ad1= FFABS(d1)>>1; - - d2= clip((p0-p3)/4, -ad1, ad1); - - src[y*stride-2] = p0 - d2; - src[y*stride+1] = p3 + d2; - } -} - -static void h261_loop_filter_c(uint8_t *src, int stride){ - int x,y,xy,yz; - int temp[64]; - - for(x=0; x<8; x++){ - temp[x ] = 4*src[x ]; - temp[x + 7*8] = 4*src[x + 7*stride]; - } - for(y=1; y<7; y++){ - for(x=0; x<8; x++){ - xy = y * stride + x; - yz = y * 8 + x; - temp[yz] = src[xy - stride] + 2*src[xy] + src[xy + stride]; - } - } - - for(y=0; y<8; y++){ - src[ y*stride] = (temp[ y*8] + 2)>>2; - src[7+y*stride] = (temp[7+y*8] + 2)>>2; - for(x=1; x<7; x++){ - xy = y * stride + x; - yz = y * 8 + x; - src[xy] = (temp[yz-1] + 2*temp[yz] + temp[yz+1] + 8)>>4; - } - } -} - -static inline void h264_loop_filter_luma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) -{ - int i, d; - for( i = 0; i < 4; i++ ) { - if( tc0[i] < 0 ) { - pix += 4*ystride; - continue; - } - for( d = 0; d < 4; d++ ) { - const int p0 = pix[-1*xstride]; - const int p1 = pix[-2*xstride]; - const int p2 = pix[-3*xstride]; - const int q0 = pix[0]; - const int q1 = pix[1*xstride]; - const int q2 = pix[2*xstride]; - - if( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( q1 - q0 ) < beta ) { - - int tc = tc0[i]; - int i_delta; - - if( FFABS( p2 - p0 ) < beta ) { - pix[-2*xstride] = p1 + clip( (( p2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - p1, -tc0[i], tc0[i] ); - tc++; - } - if( FFABS( q2 - q0 ) < beta ) { - pix[ xstride] = q1 + clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - q1, -tc0[i], tc0[i] ); - tc++; - } - - i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - pix[-xstride] = clip_uint8( p0 + i_delta ); /* p0' */ - pix[0] = clip_uint8( q0 - i_delta ); /* q0' */ - } - pix += ystride; - } - } -} -static void h264_v_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) -{ - h264_loop_filter_luma_c(pix, stride, 1, alpha, beta, tc0); -} -static void h264_h_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) -{ - h264_loop_filter_luma_c(pix, 1, stride, alpha, beta, tc0); -} - -static inline void h264_loop_filter_chroma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) -{ - int i, d; - for( i = 0; i < 4; i++ ) { - const int tc = tc0[i]; - if( tc <= 0 ) { - pix += 2*ystride; - continue; - } - for( d = 0; d < 2; d++ ) { - const int p0 = pix[-1*xstride]; - const int p1 = pix[-2*xstride]; - const int q0 = pix[0]; - const int q1 = pix[1*xstride]; - - if( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( q1 - q0 ) < beta ) { - - int delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); - - pix[-xstride] = clip_uint8( p0 + delta ); /* p0' */ - pix[0] = clip_uint8( q0 - delta ); /* q0' */ - } - pix += ystride; - } - } -} -static void h264_v_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) -{ - h264_loop_filter_chroma_c(pix, stride, 1, alpha, beta, tc0); -} -static void h264_h_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) -{ - h264_loop_filter_chroma_c(pix, 1, stride, alpha, beta, tc0); -} - -static inline void h264_loop_filter_chroma_intra_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta) -{ - int d; - for( d = 0; d < 8; d++ ) { - const int p0 = pix[-1*xstride]; - const int p1 = pix[-2*xstride]; - const int q0 = pix[0]; - const int q1 = pix[1*xstride]; - - if( FFABS( p0 - q0 ) < alpha && - FFABS( p1 - p0 ) < beta && - FFABS( q1 - q0 ) < beta ) { - - pix[-xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */ - pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */ - } - pix += ystride; - } -} -static void h264_v_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta) -{ - h264_loop_filter_chroma_intra_c(pix, stride, 1, alpha, beta); -} -static void h264_h_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta) -{ - h264_loop_filter_chroma_intra_c(pix, 1, stride, alpha, beta); -} - -static inline int pix_abs16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) -{ - int s, i; - - s = 0; - for(i=0;iavctx->nsse_weight; - else return score1 + FFABS(score2)*8; -} - -static int nsse8_c(void *v, uint8_t *s1, uint8_t *s2, int stride, int h){ - MpegEncContext *c = v; - int score1=0; - int score2=0; - int x,y; - - for(y=0; yavctx->nsse_weight; - else return score1 + FFABS(score2)*8; -} - -static int try_8x8basis_c(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale){ - int i; - unsigned int sum=0; - - for(i=0; i<8*8; i++){ - int b= rem[i] + ((basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT)); - int w= weight[i]; - b>>= RECON_SHIFT; - assert(-512>4; - } - return sum>>2; -} - -static void add_8x8basis_c(int16_t rem[64], int16_t basis[64], int scale){ - int i; - - for(i=0; i<8*8; i++){ - rem[i] += (basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT); - } -} - -/** - * permutes an 8x8 block. - * @param block the block which will be permuted according to the given permutation vector - * @param permutation the permutation vector - * @param last the last non zero coefficient in scantable order, used to speed the permutation up - * @param scantable the used scantable, this is only used to speed the permutation up, the block is not - * (inverse) permutated to scantable order! - */ -void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last) -{ - int i; - DCTELEM temp[64]; - - if(last<=0) return; - //if(permutation[1]==1) return; //FIXME its ok but not clean and might fail for some perms - - for(i=0; i<=last; i++){ - const int j= scantable[i]; - temp[j]= block[j]; - block[j]=0; - } - - for(i=0; i<=last; i++){ - const int j= scantable[i]; - const int perm_j= permutation[j]; - block[perm_j]= temp[j]; - } -} - -static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){ - return 0; -} - -void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){ - int i; - - memset(cmp, 0, sizeof(void*)*5); - - for(i=0; i<5; i++){ - switch(type&0xFF){ - case FF_CMP_SAD: - cmp[i]= c->sad[i]; - break; - case FF_CMP_SATD: - cmp[i]= c->hadamard8_diff[i]; - break; - case FF_CMP_SSE: - cmp[i]= c->sse[i]; - break; - case FF_CMP_DCT: - cmp[i]= c->dct_sad[i]; - break; - case FF_CMP_DCT264: - cmp[i]= c->dct264_sad[i]; - break; - case FF_CMP_DCTMAX: - cmp[i]= c->dct_max[i]; - break; - case FF_CMP_PSNR: - cmp[i]= c->quant_psnr[i]; - break; - case FF_CMP_BIT: - cmp[i]= c->bit[i]; - break; - case FF_CMP_RD: - cmp[i]= c->rd[i]; - break; - case FF_CMP_VSAD: - cmp[i]= c->vsad[i]; - break; - case FF_CMP_VSSE: - cmp[i]= c->vsse[i]; - break; - case FF_CMP_ZERO: - cmp[i]= zero_cmp; - break; - case FF_CMP_NSSE: - cmp[i]= c->nsse[i]; - break; -#ifdef CONFIG_SNOW_ENCODER - case FF_CMP_W53: - cmp[i]= c->w53[i]; - break; - case FF_CMP_W97: - cmp[i]= c->w97[i]; - break; -#endif - default: - av_log(NULL, AV_LOG_ERROR,"internal error in cmp function selection\n"); - } - } -} - -/** - * memset(blocks, 0, sizeof(DCTELEM)*6*64) - */ -static void clear_blocks_c(DCTELEM *blocks) -{ - memset(blocks, 0, sizeof(DCTELEM)*6*64); -} - -static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){ - int i; - for(i=0; i+7maxi){ - maxi=sum; - printf("MAX:%d\n", maxi); -} -#endif - return sum; -} - -static int hadamard8_intra8x8_c(/*MpegEncContext*/ void *s, uint8_t *src, uint8_t *dummy, int stride, int h){ - int i; - int temp[64]; - int sum=0; - - assert(h==8); - - for(i=0; i<8; i++){ - //FIXME try pointer walks - BUTTERFLY2(temp[8*i+0], temp[8*i+1], src[stride*i+0],src[stride*i+1]); - BUTTERFLY2(temp[8*i+2], temp[8*i+3], src[stride*i+2],src[stride*i+3]); - BUTTERFLY2(temp[8*i+4], temp[8*i+5], src[stride*i+4],src[stride*i+5]); - BUTTERFLY2(temp[8*i+6], temp[8*i+7], src[stride*i+6],src[stride*i+7]); - - BUTTERFLY1(temp[8*i+0], temp[8*i+2]); - BUTTERFLY1(temp[8*i+1], temp[8*i+3]); - BUTTERFLY1(temp[8*i+4], temp[8*i+6]); - BUTTERFLY1(temp[8*i+5], temp[8*i+7]); - - BUTTERFLY1(temp[8*i+0], temp[8*i+4]); - BUTTERFLY1(temp[8*i+1], temp[8*i+5]); - BUTTERFLY1(temp[8*i+2], temp[8*i+6]); - BUTTERFLY1(temp[8*i+3], temp[8*i+7]); - } - - for(i=0; i<8; i++){ - BUTTERFLY1(temp[8*0+i], temp[8*1+i]); - BUTTERFLY1(temp[8*2+i], temp[8*3+i]); - BUTTERFLY1(temp[8*4+i], temp[8*5+i]); - BUTTERFLY1(temp[8*6+i], temp[8*7+i]); - - BUTTERFLY1(temp[8*0+i], temp[8*2+i]); - BUTTERFLY1(temp[8*1+i], temp[8*3+i]); - BUTTERFLY1(temp[8*4+i], temp[8*6+i]); - BUTTERFLY1(temp[8*5+i], temp[8*7+i]); - - sum += - BUTTERFLYA(temp[8*0+i], temp[8*4+i]) - +BUTTERFLYA(temp[8*1+i], temp[8*5+i]) - +BUTTERFLYA(temp[8*2+i], temp[8*6+i]) - +BUTTERFLYA(temp[8*3+i], temp[8*7+i]); - } - - sum -= FFABS(temp[8*0] + temp[8*4]); // -mean - - return sum; -} - -static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ - MpegEncContext * const s= (MpegEncContext *)c; - DECLARE_ALIGNED_8(uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); - DCTELEM * const temp= (DCTELEM*)aligned_temp; - int sum=0, i; - - assert(h==8); - - s->dsp.diff_pixels(temp, src1, src2, stride); - s->dsp.fdct(temp); - - for(i=0; i<64; i++) - sum+= FFABS(temp[i]); - - return sum; -} - -#ifdef CONFIG_GPL -#define DCT8_1D {\ - const int s07 = SRC(0) + SRC(7);\ - const int s16 = SRC(1) + SRC(6);\ - const int s25 = SRC(2) + SRC(5);\ - const int s34 = SRC(3) + SRC(4);\ - const int a0 = s07 + s34;\ - const int a1 = s16 + s25;\ - const int a2 = s07 - s34;\ - const int a3 = s16 - s25;\ - const int d07 = SRC(0) - SRC(7);\ - const int d16 = SRC(1) - SRC(6);\ - const int d25 = SRC(2) - SRC(5);\ - const int d34 = SRC(3) - SRC(4);\ - const int a4 = d16 + d25 + (d07 + (d07>>1));\ - const int a5 = d07 - d34 - (d25 + (d25>>1));\ - const int a6 = d07 + d34 - (d16 + (d16>>1));\ - const int a7 = d16 - d25 + (d34 + (d34>>1));\ - DST(0, a0 + a1 ) ;\ - DST(1, a4 + (a7>>2)) ;\ - DST(2, a2 + (a3>>1)) ;\ - DST(3, a5 + (a6>>2)) ;\ - DST(4, a0 - a1 ) ;\ - DST(5, a6 - (a5>>2)) ;\ - DST(6, (a2>>1) - a3 ) ;\ - DST(7, (a4>>2) - a7 ) ;\ -} - -static int dct264_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ - MpegEncContext * const s= (MpegEncContext *)c; - int16_t dct[8][8]; - int i; - int sum=0; - - s->dsp.diff_pixels(dct, src1, src2, stride); - -#define SRC(x) dct[i][x] -#define DST(x,v) dct[i][x]= v - for( i = 0; i < 8; i++ ) - DCT8_1D -#undef SRC -#undef DST - -#define SRC(x) dct[x][i] -#define DST(x,v) sum += FFABS(v) - for( i = 0; i < 8; i++ ) - DCT8_1D -#undef SRC -#undef DST - return sum; -} -#endif - -static int dct_max8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ - MpegEncContext * const s= (MpegEncContext *)c; - DECLARE_ALIGNED_8(uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); - DCTELEM * const temp= (DCTELEM*)aligned_temp; - int sum=0, i; - - assert(h==8); - - s->dsp.diff_pixels(temp, src1, src2, stride); - s->dsp.fdct(temp); - - for(i=0; i<64; i++) - sum= FFMAX(sum, FFABS(temp[i])); - - return sum; -} - -static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ - MpegEncContext * const s= (MpegEncContext *)c; - DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64*2/8]); - DCTELEM * const temp= (DCTELEM*)aligned_temp; - DCTELEM * const bak = ((DCTELEM*)aligned_temp)+64; - int sum=0, i; - - assert(h==8); - s->mb_intra=0; - - s->dsp.diff_pixels(temp, src1, src2, stride); - - memcpy(bak, temp, 64*sizeof(DCTELEM)); - - s->block_last_index[0/*FIXME*/]= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); - s->dct_unquantize_inter(s, temp, 0, s->qscale); - simple_idct(temp); //FIXME - - for(i=0; i<64; i++) - sum+= (temp[i]-bak[i])*(temp[i]-bak[i]); - - return sum; -} - -static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ - MpegEncContext * const s= (MpegEncContext *)c; - const uint8_t *scantable= s->intra_scantable.permutated; - DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); - DECLARE_ALIGNED_8 (uint64_t, aligned_bak[stride]); - DCTELEM * const temp= (DCTELEM*)aligned_temp; - uint8_t * const bak= (uint8_t*)aligned_bak; - int i, last, run, bits, level, distoration, start_i; - const int esc_length= s->ac_esc_length; - uint8_t * length; - uint8_t * last_length; - - assert(h==8); - - for(i=0; i<8; i++){ - ((uint32_t*)(bak + i*stride))[0]= ((uint32_t*)(src2 + i*stride))[0]; - ((uint32_t*)(bak + i*stride))[1]= ((uint32_t*)(src2 + i*stride))[1]; - } - - s->dsp.diff_pixels(temp, src1, src2, stride); - - s->block_last_index[0/*FIXME*/]= last= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); - - bits=0; - - if (s->mb_intra) { - start_i = 1; - length = s->intra_ac_vlc_length; - last_length= s->intra_ac_vlc_last_length; - bits+= s->luma_dc_vlc_length[temp[0] + 256]; //FIXME chroma - } else { - start_i = 0; - length = s->inter_ac_vlc_length; - last_length= s->inter_ac_vlc_last_length; - } - - if(last>=start_i){ - run=0; - for(i=start_i; i=0){ - if(s->mb_intra) - s->dct_unquantize_intra(s, temp, 0, s->qscale); - else - s->dct_unquantize_inter(s, temp, 0, s->qscale); - } - - s->dsp.idct_add(bak, stride, temp); - - distoration= s->dsp.sse[1](NULL, bak, src1, stride, 8); - - return distoration + ((bits*s->qscale*s->qscale*109 + 64)>>7); -} - -static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ - MpegEncContext * const s= (MpegEncContext *)c; - const uint8_t *scantable= s->intra_scantable.permutated; - DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); - DCTELEM * const temp= (DCTELEM*)aligned_temp; - int i, last, run, bits, level, start_i; - const int esc_length= s->ac_esc_length; - uint8_t * length; - uint8_t * last_length; - - assert(h==8); - - s->dsp.diff_pixels(temp, src1, src2, stride); - - s->block_last_index[0/*FIXME*/]= last= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); - - bits=0; - - if (s->mb_intra) { - start_i = 1; - length = s->intra_ac_vlc_length; - last_length= s->intra_ac_vlc_last_length; - bits+= s->luma_dc_vlc_length[temp[0] + 256]; //FIXME chroma - } else { - start_i = 0; - length = s->inter_ac_vlc_length; - last_length= s->inter_ac_vlc_last_length; - } - - if(last>=start_i){ - run=0; - for(i=start_i; i>31; - // is this faster on some gcc/cpu combinations? -// if(tmp > 0x43c0ffff) tmp = 0xFFFF; -// else tmp = 0; - } - dst[i] = tmp - 0x8000; - } -} - -/* XXX: those functions should be suppressed ASAP when all IDCTs are - converted */ -static void ff_jref_idct_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct (block); - put_pixels_clamped_c(block, dest, line_size); -} -static void ff_jref_idct_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct (block); - add_pixels_clamped_c(block, dest, line_size); -} - -static void ff_jref_idct4_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct4 (block); - put_pixels_clamped4_c(block, dest, line_size); -} -static void ff_jref_idct4_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct4 (block); - add_pixels_clamped4_c(block, dest, line_size); -} - -static void ff_jref_idct2_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct2 (block); - put_pixels_clamped2_c(block, dest, line_size); -} -static void ff_jref_idct2_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - j_rev_dct2 (block); - add_pixels_clamped2_c(block, dest, line_size); -} - -static void ff_jref_idct1_put(uint8_t *dest, int line_size, DCTELEM *block) -{ - uint8_t *cm = cropTbl + MAX_NEG_CROP; - - dest[0] = cm[(block[0] + 4)>>3]; -} -static void ff_jref_idct1_add(uint8_t *dest, int line_size, DCTELEM *block) -{ - uint8_t *cm = cropTbl + MAX_NEG_CROP; - - dest[0] = cm[dest[0] + ((block[0] + 4)>>3)]; -} - -static void just_return() { return; } - /* init static data */ void dsputil_static_init(void) { @@ -3870,364 +883,10 @@ cropTbl[i] = 0; cropTbl[i + MAX_NEG_CROP + 256] = 255; } - + for(i=0;i<512;i++) { squareTbl[i] = (i - 256) * (i - 256); } - + for(i=0; i<64; i++) inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1; } - - -void dsputil_init(DSPContext* c, AVCodecContext *avctx) -{ - int i; - -#ifdef CONFIG_ENCODERS - if(avctx->dct_algo==FF_DCT_FASTINT) { - c->fdct = fdct_ifast; - c->fdct248 = fdct_ifast248; - } - else if(avctx->dct_algo==FF_DCT_FAAN) { - c->fdct = ff_faandct; - c->fdct248 = ff_faandct248; - } - else { - c->fdct = ff_jpeg_fdct_islow; //slow/accurate/default - c->fdct248 = ff_fdct248_islow; - } -#endif //CONFIG_ENCODERS - - if(avctx->lowres==1){ - if(avctx->idct_algo==FF_IDCT_INT || avctx->idct_algo==FF_IDCT_AUTO){ - c->idct_put= ff_jref_idct4_put; - c->idct_add= ff_jref_idct4_add; - }else{ - c->idct_put= ff_h264_lowres_idct_put_c; - c->idct_add= ff_h264_lowres_idct_add_c; - } - c->idct = j_rev_dct4; - c->idct_permutation_type= FF_NO_IDCT_PERM; - }else if(avctx->lowres==2){ - c->idct_put= ff_jref_idct2_put; - c->idct_add= ff_jref_idct2_add; - c->idct = j_rev_dct2; - c->idct_permutation_type= FF_NO_IDCT_PERM; - }else if(avctx->lowres==3){ - c->idct_put= ff_jref_idct1_put; - c->idct_add= ff_jref_idct1_add; - c->idct = j_rev_dct1; - c->idct_permutation_type= FF_NO_IDCT_PERM; - }else{ - if(avctx->idct_algo==FF_IDCT_INT){ - c->idct_put= ff_jref_idct_put; - c->idct_add= ff_jref_idct_add; - c->idct = j_rev_dct; - c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; - }else if(avctx->idct_algo==FF_IDCT_VP3){ - c->idct_put= ff_vp3_idct_put_c; - c->idct_add= ff_vp3_idct_add_c; - c->idct = ff_vp3_idct_c; - c->idct_permutation_type= FF_NO_IDCT_PERM; - }else{ //accurate/default - c->idct_put= simple_idct_put; - c->idct_add= simple_idct_add; - c->idct = simple_idct; - c->idct_permutation_type= FF_NO_IDCT_PERM; - } - } - - c->h264_idct_add= ff_h264_idct_add_c; - c->h264_idct8_add= ff_h264_idct8_add_c; - c->h264_idct_dc_add= ff_h264_idct_dc_add_c; - c->h264_idct8_dc_add= ff_h264_idct8_dc_add_c; - - c->get_pixels = get_pixels_c; - c->diff_pixels = diff_pixels_c; - c->put_pixels_clamped = put_pixels_clamped_c; - c->put_signed_pixels_clamped = put_signed_pixels_clamped_c; - c->add_pixels_clamped = add_pixels_clamped_c; - c->add_pixels8 = add_pixels8_c; - c->add_pixels4 = add_pixels4_c; - c->gmc1 = gmc1_c; - c->gmc = ff_gmc_c; - c->clear_blocks = clear_blocks_c; - c->pix_sum = pix_sum_c; - c->pix_norm1 = pix_norm1_c; - - /* TODO [0] 16 [1] 8 */ - c->pix_abs[0][0] = pix_abs16_c; - c->pix_abs[0][1] = pix_abs16_x2_c; - c->pix_abs[0][2] = pix_abs16_y2_c; - c->pix_abs[0][3] = pix_abs16_xy2_c; - c->pix_abs[1][0] = pix_abs8_c; - c->pix_abs[1][1] = pix_abs8_x2_c; - c->pix_abs[1][2] = pix_abs8_y2_c; - c->pix_abs[1][3] = pix_abs8_xy2_c; - -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][0] = PFX ## _pixels ## NUM ## _c; \ - c->PFX ## _pixels_tab[IDX][1] = PFX ## _pixels ## NUM ## _x2_c; \ - c->PFX ## _pixels_tab[IDX][2] = PFX ## _pixels ## NUM ## _y2_c; \ - c->PFX ## _pixels_tab[IDX][3] = PFX ## _pixels ## NUM ## _xy2_c - - dspfunc(put, 0, 16); - dspfunc(put_no_rnd, 0, 16); - dspfunc(put, 1, 8); - dspfunc(put_no_rnd, 1, 8); - dspfunc(put, 2, 4); - dspfunc(put, 3, 2); - - dspfunc(avg, 0, 16); - dspfunc(avg_no_rnd, 0, 16); - dspfunc(avg, 1, 8); - dspfunc(avg_no_rnd, 1, 8); - dspfunc(avg, 2, 4); - dspfunc(avg, 3, 2); -#undef dspfunc - - c->put_no_rnd_pixels_l2[0]= put_no_rnd_pixels16_l2_c; - c->put_no_rnd_pixels_l2[1]= put_no_rnd_pixels8_l2_c; - - c->put_tpel_pixels_tab[ 0] = put_tpel_pixels_mc00_c; - c->put_tpel_pixels_tab[ 1] = put_tpel_pixels_mc10_c; - c->put_tpel_pixels_tab[ 2] = put_tpel_pixels_mc20_c; - c->put_tpel_pixels_tab[ 4] = put_tpel_pixels_mc01_c; - c->put_tpel_pixels_tab[ 5] = put_tpel_pixels_mc11_c; - c->put_tpel_pixels_tab[ 6] = put_tpel_pixels_mc21_c; - c->put_tpel_pixels_tab[ 8] = put_tpel_pixels_mc02_c; - c->put_tpel_pixels_tab[ 9] = put_tpel_pixels_mc12_c; - c->put_tpel_pixels_tab[10] = put_tpel_pixels_mc22_c; - - c->avg_tpel_pixels_tab[ 0] = avg_tpel_pixels_mc00_c; - c->avg_tpel_pixels_tab[ 1] = avg_tpel_pixels_mc10_c; - c->avg_tpel_pixels_tab[ 2] = avg_tpel_pixels_mc20_c; - c->avg_tpel_pixels_tab[ 4] = avg_tpel_pixels_mc01_c; - c->avg_tpel_pixels_tab[ 5] = avg_tpel_pixels_mc11_c; - c->avg_tpel_pixels_tab[ 6] = avg_tpel_pixels_mc21_c; - c->avg_tpel_pixels_tab[ 8] = avg_tpel_pixels_mc02_c; - c->avg_tpel_pixels_tab[ 9] = avg_tpel_pixels_mc12_c; - c->avg_tpel_pixels_tab[10] = avg_tpel_pixels_mc22_c; - -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_c; \ - c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_c; \ - c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_c; \ - c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_c; \ - c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_c; \ - c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_c; \ - c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_c; \ - c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_c; \ - c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_c; \ - c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_c; \ - c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_c; \ - c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_c; \ - c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_c; \ - c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_c; \ - c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_c; \ - c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_c - - dspfunc(put_qpel, 0, 16); - dspfunc(put_no_rnd_qpel, 0, 16); - - dspfunc(avg_qpel, 0, 16); - /* dspfunc(avg_no_rnd_qpel, 0, 16); */ - - dspfunc(put_qpel, 1, 8); - dspfunc(put_no_rnd_qpel, 1, 8); - - dspfunc(avg_qpel, 1, 8); - /* dspfunc(avg_no_rnd_qpel, 1, 8); */ - - dspfunc(put_h264_qpel, 0, 16); - dspfunc(put_h264_qpel, 1, 8); - dspfunc(put_h264_qpel, 2, 4); - dspfunc(put_h264_qpel, 3, 2); - dspfunc(avg_h264_qpel, 0, 16); - dspfunc(avg_h264_qpel, 1, 8); - dspfunc(avg_h264_qpel, 2, 4); - -#undef dspfunc - c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_c; - c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_c; - c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_c; - c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_c; - c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_c; - c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_c; - c->put_no_rnd_h264_chroma_pixels_tab[0]= put_no_rnd_h264_chroma_mc8_c; - - c->weight_h264_pixels_tab[0]= weight_h264_pixels16x16_c; - c->weight_h264_pixels_tab[1]= weight_h264_pixels16x8_c; - c->weight_h264_pixels_tab[2]= weight_h264_pixels8x16_c; - c->weight_h264_pixels_tab[3]= weight_h264_pixels8x8_c; - c->weight_h264_pixels_tab[4]= weight_h264_pixels8x4_c; - c->weight_h264_pixels_tab[5]= weight_h264_pixels4x8_c; - c->weight_h264_pixels_tab[6]= weight_h264_pixels4x4_c; - c->weight_h264_pixels_tab[7]= weight_h264_pixels4x2_c; - c->weight_h264_pixels_tab[8]= weight_h264_pixels2x4_c; - c->weight_h264_pixels_tab[9]= weight_h264_pixels2x2_c; - c->biweight_h264_pixels_tab[0]= biweight_h264_pixels16x16_c; - c->biweight_h264_pixels_tab[1]= biweight_h264_pixels16x8_c; - c->biweight_h264_pixels_tab[2]= biweight_h264_pixels8x16_c; - c->biweight_h264_pixels_tab[3]= biweight_h264_pixels8x8_c; - c->biweight_h264_pixels_tab[4]= biweight_h264_pixels8x4_c; - c->biweight_h264_pixels_tab[5]= biweight_h264_pixels4x8_c; - c->biweight_h264_pixels_tab[6]= biweight_h264_pixels4x4_c; - c->biweight_h264_pixels_tab[7]= biweight_h264_pixels4x2_c; - c->biweight_h264_pixels_tab[8]= biweight_h264_pixels2x4_c; - c->biweight_h264_pixels_tab[9]= biweight_h264_pixels2x2_c; - -#ifdef CONFIG_CAVS_DECODER - ff_cavsdsp_init(c,avctx); -#endif -#if defined(CONFIG_VC1_DECODER) || defined(CONFIG_WMV3_DECODER) - ff_vc1dsp_init(c,avctx); -#endif - - c->put_mspel_pixels_tab[0]= put_mspel8_mc00_c; - c->put_mspel_pixels_tab[1]= put_mspel8_mc10_c; - c->put_mspel_pixels_tab[2]= put_mspel8_mc20_c; - c->put_mspel_pixels_tab[3]= put_mspel8_mc30_c; - c->put_mspel_pixels_tab[4]= put_mspel8_mc02_c; - c->put_mspel_pixels_tab[5]= put_mspel8_mc12_c; - c->put_mspel_pixels_tab[6]= put_mspel8_mc22_c; - c->put_mspel_pixels_tab[7]= put_mspel8_mc32_c; - -#define SET_CMP_FUNC(name) \ - c->name[0]= name ## 16_c;\ - c->name[1]= name ## 8x8_c; - - SET_CMP_FUNC(hadamard8_diff) - c->hadamard8_diff[4]= hadamard8_intra16_c; - SET_CMP_FUNC(dct_sad) - SET_CMP_FUNC(dct_max) -#ifdef CONFIG_GPL - SET_CMP_FUNC(dct264_sad) -#endif - c->sad[0]= pix_abs16_c; - c->sad[1]= pix_abs8_c; - c->sse[0]= sse16_c; - c->sse[1]= sse8_c; - c->sse[2]= sse4_c; - SET_CMP_FUNC(quant_psnr) - SET_CMP_FUNC(rd) - SET_CMP_FUNC(bit) - c->vsad[0]= vsad16_c; - c->vsad[4]= vsad_intra16_c; - c->vsse[0]= vsse16_c; - c->vsse[4]= vsse_intra16_c; - c->nsse[0]= nsse16_c; - c->nsse[1]= nsse8_c; -#ifdef CONFIG_SNOW_ENCODER - c->w53[0]= w53_16_c; - c->w53[1]= w53_8_c; - c->w97[0]= w97_16_c; - c->w97[1]= w97_8_c; -#endif - - c->add_bytes= add_bytes_c; - c->diff_bytes= diff_bytes_c; - c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; - c->bswap_buf= bswap_buf; - - c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_c; - c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_c; - c->h264_v_loop_filter_chroma= h264_v_loop_filter_chroma_c; - c->h264_h_loop_filter_chroma= h264_h_loop_filter_chroma_c; - c->h264_v_loop_filter_chroma_intra= h264_v_loop_filter_chroma_intra_c; - c->h264_h_loop_filter_chroma_intra= h264_h_loop_filter_chroma_intra_c; - c->h264_loop_filter_strength= NULL; - - c->h263_h_loop_filter= h263_h_loop_filter_c; - c->h263_v_loop_filter= h263_v_loop_filter_c; - - c->h261_loop_filter= h261_loop_filter_c; - - c->try_8x8basis= try_8x8basis_c; - c->add_8x8basis= add_8x8basis_c; - -#ifdef CONFIG_SNOW_ENCODER - c->vertical_compose97i = ff_snow_vertical_compose97i; - c->horizontal_compose97i = ff_snow_horizontal_compose97i; - c->inner_add_yblock = ff_snow_inner_add_yblock; -#endif - -#ifdef CONFIG_VORBIS_DECODER - c->vorbis_inverse_coupling = vorbis_inverse_coupling; -#endif - c->vector_fmul = vector_fmul_c; - c->vector_fmul_reverse = vector_fmul_reverse_c; - c->vector_fmul_add_add = ff_vector_fmul_add_add_c; - c->float_to_int16 = ff_float_to_int16_c; - - c->shrink[0]= ff_img_copy_plane; - c->shrink[1]= ff_shrink22; - c->shrink[2]= ff_shrink44; - c->shrink[3]= ff_shrink88; - - c->prefetch= just_return; - - memset(c->put_2tap_qpel_pixels_tab, 0, sizeof(c->put_2tap_qpel_pixels_tab)); - memset(c->avg_2tap_qpel_pixels_tab, 0, sizeof(c->avg_2tap_qpel_pixels_tab)); - -#ifdef HAVE_MMX - dsputil_init_mmx(c, avctx); -#endif -#ifdef ARCH_ARMV4L - dsputil_init_armv4l(c, avctx); -#endif -#ifdef HAVE_MLIB - dsputil_init_mlib(c, avctx); -#endif -#ifdef ARCH_SPARC - dsputil_init_vis(c,avctx); -#endif -#ifdef ARCH_ALPHA - dsputil_init_alpha(c, avctx); -#endif -#ifdef ARCH_POWERPC - dsputil_init_ppc(c, avctx); -#endif -#ifdef HAVE_MMI - dsputil_init_mmi(c, avctx); -#endif -#ifdef ARCH_SH4 - dsputil_init_sh4(c,avctx); -#endif -#ifdef ARCH_BFIN - dsputil_init_bfin(c,avctx); -#endif - - for(i=0; i<64; i++){ - if(!c->put_2tap_qpel_pixels_tab[0][i]) - c->put_2tap_qpel_pixels_tab[0][i]= c->put_h264_qpel_pixels_tab[0][i]; - if(!c->avg_2tap_qpel_pixels_tab[0][i]) - c->avg_2tap_qpel_pixels_tab[0][i]= c->avg_h264_qpel_pixels_tab[0][i]; - } - - switch(c->idct_permutation_type){ - case FF_NO_IDCT_PERM: - for(i=0; i<64; i++) - c->idct_permutation[i]= i; - break; - case FF_LIBMPEG2_IDCT_PERM: - for(i=0; i<64; i++) - c->idct_permutation[i]= (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2); - break; - case FF_SIMPLE_IDCT_PERM: - for(i=0; i<64; i++) - c->idct_permutation[i]= simple_mmx_permutation[i]; - break; - case FF_TRANSPOSE_IDCT_PERM: - for(i=0; i<64; i++) - c->idct_permutation[i]= ((i&7)<<3) | (i>>3); - break; - case FF_PARTTRANS_IDCT_PERM: - for(i=0; i<64; i++) - c->idct_permutation[i]= (i&0x24) | ((i&3)<<3) | ((i>>3)&3); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Internal error, IDCT permutation not set\n"); - } -} - diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/dsputil.h --- a/src/ffmpeg/libavcodec/dsputil.h Mon Mar 12 13:00:06 2007 -0700 +++ b/src/ffmpeg/libavcodec/dsputil.h Mon Mar 12 13:06:30 2007 -0700 @@ -3,21 +3,19 @@ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or + * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * version 2 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -37,7 +35,6 @@ //#define DEBUG /* dct code */ typedef short DCTELEM; -typedef int DWTELEM; void fdct_ifast (DCTELEM *data); void fdct_ifast248 (DCTELEM *data); @@ -45,25 +42,11 @@ void ff_fdct248_islow (DCTELEM *data); void j_rev_dct (DCTELEM *data); -void j_rev_dct4 (DCTELEM *data); -void j_rev_dct2 (DCTELEM *data); -void j_rev_dct1 (DCTELEM *data); void ff_fdct_mmx(DCTELEM *block); void ff_fdct_mmx2(DCTELEM *block); void ff_fdct_sse2(DCTELEM *block); -void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); -void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block); -void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block); - -void ff_vector_fmul_add_add_c(float *dst, const float *src0, const float *src1, - const float *src2, int src3, int blocksize, int step); -void ff_float_to_int16_c(int16_t *dst, const float *src, int len); - /* encoding scans */ extern const uint8_t ff_alternate_horizontal_scan[64]; extern const uint8_t ff_alternate_vertical_scan[64]; @@ -71,25 +54,12 @@ extern const uint8_t ff_zigzag248_direct[64]; /* pixel operations */ -#define MAX_NEG_CROP 1024 +#define MAX_NEG_CROP 384 /* temporary */ extern uint32_t squareTbl[512]; extern uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; -/* VP3 DSP functions */ -void ff_vp3_idct_c(DCTELEM *block/* align 16*/); -void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); -void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); - -/* 1/2^n downscaling functions from imgconvert.c */ -void ff_img_copy_plane(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); -void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); -void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); -void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); - -void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, - int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); /* minimum alignment rules ;) if u notice errors in the align stuff, need more alignment for some asm code for some cpu @@ -116,8 +86,6 @@ typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h); typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); -typedef void (*h264_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int offset); -typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offset); #define DEF_OLD_QPEL(name)\ void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ @@ -149,9 +117,6 @@ typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/; -// for snow slices -typedef struct slice_buffer_s slice_buffer; - /** * DSPContext. */ @@ -160,10 +125,7 @@ void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size); void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride); void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); - void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); - void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size); - void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size); /** * translational global motion compensation. */ @@ -172,12 +134,12 @@ * global motion compensation. */ void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int ox, int oy, - int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); void (*clear_blocks)(DCTELEM *blocks/*align 16*/); int (*pix_sum)(uint8_t * pix, int line_size); int (*pix_norm1)(uint8_t * pix, int line_size); // 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4 - + me_cmp_func sad[5]; /* identical to pix_absAxA except additional void * */ me_cmp_func sse[5]; me_cmp_func hadamard8_diff[5]; @@ -187,22 +149,16 @@ me_cmp_func rd[5]; me_cmp_func vsad[5]; me_cmp_func vsse[5]; - me_cmp_func nsse[5]; - me_cmp_func w53[5]; - me_cmp_func w97[5]; - me_cmp_func dct_max[5]; - me_cmp_func dct264_sad[5]; me_cmp_func me_pre_cmp[5]; me_cmp_func me_cmp[5]; me_cmp_func me_sub_cmp[5]; me_cmp_func mb_cmp[5]; me_cmp_func ildct_cmp[5]; //only width 16 used - me_cmp_func frame_skip_cmp[5]; //only width 8 used /** * Halfpel motion compensation with rounding (a+b+1)>>1. - * this is an array[4][4] of motion compensation funcions for 4 + * this is an array[4][4] of motion compensation funcions for 4 * horizontal blocksizes (8,16) and the 4 halfpel positions
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination where the result is stored @@ -214,7 +170,7 @@ /** * Halfpel motion compensation with rounding (a+b+1)>>1. - * This is an array[4][4] of motion compensation functions for 4 + * This is an array[4][4] of motion compensation functions for 4 * horizontal blocksizes (8,16) and the 4 halfpel positions
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination into which the result is averaged (a+b+1)>>1 @@ -226,7 +182,7 @@ /** * Halfpel motion compensation with no rounding (a+b)>>1. - * this is an array[2][4] of motion compensation funcions for 2 + * this is an array[2][4] of motion compensation funcions for 2 * horizontal blocksizes (8,16) and the 4 halfpel positions
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination where the result is stored @@ -234,11 +190,11 @@ * @param line_size number of bytes in a horizontal line of block * @param h height */ - op_pixels_func put_no_rnd_pixels_tab[4][4]; + op_pixels_func put_no_rnd_pixels_tab[2][4]; /** * Halfpel motion compensation with no rounding (a+b)>>1. - * this is an array[2][4] of motion compensation funcions for 2 + * this is an array[2][4] of motion compensation funcions for 2 * horizontal blocksizes (8,16) and the 4 halfpel positions
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] * @param block destination into which the result is averaged (a+b)>>1 @@ -246,10 +202,8 @@ * @param line_size number of bytes in a horizontal line of block * @param h height */ - op_pixels_func avg_no_rnd_pixels_tab[4][4]; - - void (*put_no_rnd_pixels_l2[2])(uint8_t *block/*align width (8 or 16)*/, const uint8_t *a/*align 1*/, const uint8_t *b/*align 1*/, int line_size, int h); - + op_pixels_func avg_no_rnd_pixels_tab[2][4]; + /** * Thirdpel motion compensation with rounding (a+b+1)>>1. * this is an array[12] of motion compensation funcions for the 9 thirdpel positions
@@ -267,35 +221,18 @@ qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16]; qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16]; qpel_mc_func put_mspel_pixels_tab[8]; - + /** * h264 Chram MC */ h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; - /* This is really one func used in VC-1 decoding */ - h264_chroma_mc_func put_no_rnd_h264_chroma_pixels_tab[3]; h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; - qpel_mc_func put_h264_qpel_pixels_tab[4][16]; - qpel_mc_func avg_h264_qpel_pixels_tab[4][16]; - - qpel_mc_func put_2tap_qpel_pixels_tab[4][16]; - qpel_mc_func avg_2tap_qpel_pixels_tab[4][16]; - - h264_weight_func weight_h264_pixels_tab[10]; - h264_biweight_func biweight_h264_pixels_tab[10]; - - /* AVS specific */ - qpel_mc_func put_cavs_qpel_pixels_tab[2][16]; - qpel_mc_func avg_cavs_qpel_pixels_tab[2][16]; - void (*cavs_filter_lv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2); - void (*cavs_idct8_add)(uint8_t *dst, DCTELEM *block, int stride); - + qpel_mc_func put_h264_qpel_pixels_tab[3][16]; + qpel_mc_func avg_h264_qpel_pixels_tab[3][16]; + me_cmp_func pix_abs[2][4]; - + /* huffyuv specific */ void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); @@ -305,54 +242,30 @@ */ void (*sub_hfyu_median_prediction)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top); void (*bswap_buf)(uint32_t *dst, uint32_t *src, int w); - - void (*h264_v_loop_filter_luma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); - void (*h264_h_loop_filter_luma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); - void (*h264_v_loop_filter_chroma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); - void (*h264_h_loop_filter_chroma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); - void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix, int stride, int alpha, int beta); - void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix, int stride, int alpha, int beta); - // h264_loop_filter_strength: simd only. the C version is inlined in h264.c - void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2], - int bidir, int edges, int step, int mask_mv0, int mask_mv1); - + void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); - void (*h261_loop_filter)(uint8_t *src, int stride); - - /* assume len is a multiple of 4, and arrays are 16-byte aligned */ - void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize); - /* assume len is a multiple of 8, and arrays are 16-byte aligned */ - void (*vector_fmul)(float *dst, const float *src, int len); - void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len); - /* assume len is a multiple of 8, and src arrays are 16-byte aligned */ - void (*vector_fmul_add_add)(float *dst, const float *src0, const float *src1, const float *src2, int src3, int len, int step); - - /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767] - * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */ - void (*float_to_int16)(int16_t *dst, const float *src, int len); - /* (I)DCT */ void (*fdct)(DCTELEM *block/* align 16*/); void (*fdct248)(DCTELEM *block/* align 16*/); - + /* IDCT really*/ void (*idct)(DCTELEM *block/* align 16*/); - + /** * block -> idct -> clip to unsigned 8 bit -> dest. * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...) * @param line_size size in bytes of a horizotal line of dest */ void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); - + /** * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. * @param line_size size in bytes of a horizotal line of dest */ void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); - + /** * idct input permutation. * several optimized IDCTs need a permutated input (relative to the normal order of the reference @@ -371,38 +284,12 @@ #define FF_LIBMPEG2_IDCT_PERM 2 #define FF_SIMPLE_IDCT_PERM 3 #define FF_TRANSPOSE_IDCT_PERM 4 -#define FF_PARTTRANS_IDCT_PERM 5 int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale); void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale); #define BASIS_SHIFT 16 #define RECON_SHIFT 6 - void (*h264_idct_add)(uint8_t *dst, DCTELEM *block, int stride); - void (*h264_idct8_add)(uint8_t *dst, DCTELEM *block, int stride); - void (*h264_idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride); - void (*h264_idct8_dc_add)(uint8_t *dst, DCTELEM *block, int stride); - - /* snow wavelet */ - void (*vertical_compose97i)(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width); - void (*horizontal_compose97i)(DWTELEM *b, int width); - void (*inner_add_yblock)(uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8); - - void (*prefetch)(void *mem, int stride, int h); - - void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); - - /* vc1 functions */ - void (*vc1_inv_trans_8x8)(DCTELEM *b); - void (*vc1_inv_trans_8x4)(DCTELEM *b, int n); - void (*vc1_inv_trans_4x8)(DCTELEM *b, int n); - void (*vc1_inv_trans_4x4)(DCTELEM *b, int n); - void (*vc1_v_overlap)(uint8_t* src, int stride, int rnd); - void (*vc1_h_overlap)(uint8_t* src, int stride, int rnd); - /* put 8x8 block with bicubic interpolation and quarterpel precision - * last argument is actually round value instead of height - */ - op_pixels_func put_vc1_mspel_pixels_tab[16]; } DSPContext; void dsputil_static_init(void); @@ -416,7 +303,7 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type); -#define BYTE_VEC32(c) ((c)*0x01010101UL) +#define BYTE_VEC32(c) ((c)*0x01010101UL) static inline uint32_t rnd_avg32(uint32_t a, uint32_t b) { @@ -428,30 +315,6 @@ return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); } -static inline int get_penalty_factor(int lambda, int lambda2, int type){ - switch(type&0xFF){ - default: - case FF_CMP_SAD: - return lambda>>FF_LAMBDA_SHIFT; - case FF_CMP_DCT: - return (3*lambda)>>(FF_LAMBDA_SHIFT+1); - case FF_CMP_W53: - return (4*lambda)>>(FF_LAMBDA_SHIFT); - case FF_CMP_W97: - return (2*lambda)>>(FF_LAMBDA_SHIFT); - case FF_CMP_SATD: - case FF_CMP_DCT264: - return (2*lambda)>>FF_LAMBDA_SHIFT; - case FF_CMP_RD: - case FF_CMP_PSNR: - case FF_CMP_SSE: - case FF_CMP_NSSE: - return lambda2>>FF_LAMBDA_SHIFT; - case FF_CMP_BIT: - return 1; - } -} - /** * Empty mmx state. * this must be called between any dsp function and float/double code. @@ -463,12 +326,6 @@ one or more MultiMedia extension */ int mm_support(void); -#ifdef __GNUC__ - #define DECLARE_ALIGNED_16(t,v) t v __attribute__ ((aligned (16))) -#else - #define DECLARE_ALIGNED_16(t,v) __declspec(align(16)) t v -#endif - #if defined(HAVE_MMX) #undef emms_c @@ -478,14 +335,11 @@ #define MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */ #define MM_SSE 0x0008 /* SSE functions */ #define MM_SSE2 0x0010 /* PIV SSE2 functions */ -#define MM_3DNOWEXT 0x0020 /* AMD 3DNowExt */ -#define MM_SSE3 0x0040 /* Prescott SSE3 functions */ extern int mm_flags; void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); -void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); static inline void emms(void) { @@ -499,13 +353,7 @@ emms();\ } -#ifdef __GNUC__ - #define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) -#else - #define DECLARE_ALIGNED_8(t,v) __declspec(align(8)) t v -#endif - -#define STRIDE_ALIGN 8 +#define __align8 __attribute__ ((aligned (8))) void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx); @@ -513,35 +361,21 @@ #elif defined(ARCH_ARMV4L) /* This is to use 4 bytes read to the IDCT pointers for some 'zero' - line optimizations */ -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (4))) -#define STRIDE_ALIGN 4 - -#define MM_IWMMXT 0x0100 /* XScale IWMMXT */ - -extern int mm_flags; + line ptimizations */ +#define __align8 __attribute__ ((aligned (4))) void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx); #elif defined(HAVE_MLIB) /* SPARC/VIS IDCT needs 8-byte aligned DCT blocks */ -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) -#define STRIDE_ALIGN 8 +#define __align8 __attribute__ ((aligned (8))) void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); -#elif defined(ARCH_SPARC) - -/* SPARC/VIS IDCT needs 8-byte aligned DCT blocks */ -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) -#define STRIDE_ALIGN 8 -void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); - #elif defined(ARCH_ALPHA) -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) -#define STRIDE_ALIGN 8 +#define __align8 __attribute__ ((aligned (8))) void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); @@ -557,36 +391,25 @@ #undef pixel #endif -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (16))) -#define STRIDE_ALIGN 16 +#define __align8 __attribute__ ((aligned (16))) void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); #elif defined(HAVE_MMI) -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (16))) -#define STRIDE_ALIGN 16 +#define __align8 __attribute__ ((aligned (16))) void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); #elif defined(ARCH_SH4) -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) -#define STRIDE_ALIGN 8 +#define __align8 __attribute__ ((aligned (8))) void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); -#elif defined(ARCH_BFIN) - -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) -#define STRIDE_ALIGN 8 - -void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); - #else -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) -#define STRIDE_ALIGN 8 +#define __align8 #endif @@ -600,7 +423,6 @@ #define LD32(a) (((const struct unaligned_32 *) (a))->l) #define LD64(a) (((const struct unaligned_64 *) (a))->l) -#define ST16(a, b) (((struct unaligned_16 *) (a))->l) = (b) #define ST32(a, b) (((struct unaligned_32 *) (a))->l) = (b) #else /* __GNUC__ */ @@ -609,7 +431,6 @@ #define LD32(a) (*((uint32_t*)(a))) #define LD64(a) (*((uint64_t*)(a))) -#define ST16(a, b) *((uint16_t*)(a)) = (b) #define ST32(a, b) *((uint32_t*)(a)) = (b) #endif /* !__GNUC__ */ @@ -625,8 +446,6 @@ FFTSample type */ typedef float FFTSample; -struct MDCTContext; - typedef struct FFTComplex { FFTSample re, im; } FFTComplex; @@ -638,23 +457,19 @@ FFTComplex *exptab; FFTComplex *exptab1; /* only used by SSE code */ void (*fft_calc)(struct FFTContext *s, FFTComplex *z); - void (*imdct_calc)(struct MDCTContext *s, FFTSample *output, - const FFTSample *input, FFTSample *tmp); } FFTContext; -int ff_fft_init(FFTContext *s, int nbits, int inverse); -void ff_fft_permute(FFTContext *s, FFTComplex *z); -void ff_fft_calc_c(FFTContext *s, FFTComplex *z); -void ff_fft_calc_sse(FFTContext *s, FFTComplex *z); -void ff_fft_calc_3dn(FFTContext *s, FFTComplex *z); -void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z); -void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z); +int fft_inits(FFTContext *s, int nbits, int inverse); +void fft_permute(FFTContext *s, FFTComplex *z); +void fft_calc_c(FFTContext *s, FFTComplex *z); +void fft_calc_sse(FFTContext *s, FFTComplex *z); +void fft_calc_altivec(FFTContext *s, FFTComplex *z); -static inline void ff_fft_calc(FFTContext *s, FFTComplex *z) +static inline void fft_calc(FFTContext *s, FFTComplex *z) { s->fft_calc(s, z); } -void ff_fft_end(FFTContext *s); +void fft_end(FFTContext *s); /* MDCT computation */ @@ -670,10 +485,6 @@ int ff_mdct_init(MDCTContext *s, int nbits, int inverse); void ff_imdct_calc(MDCTContext *s, FFTSample *output, const FFTSample *input, FFTSample *tmp); -void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, - const FFTSample *input, FFTSample *tmp); -void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, - const FFTSample *input, FFTSample *tmp); void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input, FFTSample *tmp); void ff_mdct_end(MDCTContext *s); diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/dv.c --- a/src/ffmpeg/libavcodec/dv.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1265 +0,0 @@ -/* - * DV decoder - * Copyright (c) 2002 Fabrice Bellard. - * Copyright (c) 2004 Roman Shaposhnik. - * - * DV encoder - * Copyright (c) 2003 Roman Shaposhnik. - * - * 50 Mbps (DVCPRO50) support - * Copyright (c) 2006 Daniel Maas - * - * Many thanks to Dan Dennedy for providing wealth - * of DV technical info. - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file dv.c - * DV codec. - */ -#define ALT_BITSTREAM_READER -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "simple_idct.h" -#include "dvdata.h" - -//#undef NDEBUG -//#include - -typedef struct DVVideoContext { - const DVprofile* sys; - AVFrame picture; - AVCodecContext *avctx; - uint8_t *buf; - - uint8_t dv_zigzag[2][64]; - uint8_t dv_idct_shift[2][2][22][64]; - - void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size); - void (*fdct[2])(DCTELEM *block); - void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block); -} DVVideoContext; - -/* MultiThreading - dv_anchor applies to entire DV codec, not just the avcontext */ -/* one element is needed for each video segment in a DV frame */ -/* at most there are 2 DIF channels * 12 DIF sequences * 27 video segments (PAL 50Mbps) */ -#define DV_ANCHOR_SIZE (2*12*27) - -static void* dv_anchor[DV_ANCHOR_SIZE]; - -#define TEX_VLC_BITS 9 - -#ifdef DV_CODEC_TINY_TARGET -#define DV_VLC_MAP_RUN_SIZE 15 -#define DV_VLC_MAP_LEV_SIZE 23 -#else -#define DV_VLC_MAP_RUN_SIZE 64 -#define DV_VLC_MAP_LEV_SIZE 512 //FIXME sign was removed so this should be /2 but needs check -#endif - -/* XXX: also include quantization */ -static RL_VLC_ELEM *dv_rl_vlc; -/* VLC encoding lookup table */ -static struct dv_vlc_pair { - uint32_t vlc; - uint8_t size; -} (*dv_vlc_map)[DV_VLC_MAP_LEV_SIZE] = NULL; - -static void dv_build_unquantize_tables(DVVideoContext *s, uint8_t* perm) -{ - int i, q, j; - - /* NOTE: max left shift is 6 */ - for(q = 0; q < 22; q++) { - /* 88DCT */ - for(i = 1; i < 64; i++) { - /* 88 table */ - j = perm[i]; - s->dv_idct_shift[0][0][q][j] = - dv_quant_shifts[q][dv_88_areas[i]] + 1; - s->dv_idct_shift[1][0][q][j] = s->dv_idct_shift[0][0][q][j] + 1; - } - - /* 248DCT */ - for(i = 1; i < 64; i++) { - /* 248 table */ - s->dv_idct_shift[0][1][q][i] = - dv_quant_shifts[q][dv_248_areas[i]] + 1; - s->dv_idct_shift[1][1][q][i] = s->dv_idct_shift[0][1][q][i] + 1; - } - } -} - -static int dvvideo_init(AVCodecContext *avctx) -{ - DVVideoContext *s = avctx->priv_data; - DSPContext dsp; - static int done=0; - int i, j; - - if (!done) { - VLC dv_vlc; - uint16_t new_dv_vlc_bits[NB_DV_VLC*2]; - uint8_t new_dv_vlc_len[NB_DV_VLC*2]; - uint8_t new_dv_vlc_run[NB_DV_VLC*2]; - int16_t new_dv_vlc_level[NB_DV_VLC*2]; - - done = 1; - - dv_vlc_map = av_mallocz_static(DV_VLC_MAP_LEV_SIZE*DV_VLC_MAP_RUN_SIZE*sizeof(struct dv_vlc_pair)); - if (!dv_vlc_map) - return -ENOMEM; - - /* dv_anchor lets each thread know its Id */ - for (i=0; i= DV_VLC_MAP_RUN_SIZE) - continue; -#ifdef DV_CODEC_TINY_TARGET - if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE) - continue; -#endif - - if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0) - continue; - - dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc = dv_vlc_bits[i] << - (!!dv_vlc_level[i]); - dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size = dv_vlc_len[i] + - (!!dv_vlc_level[i]); - } - for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) { -#ifdef DV_CODEC_TINY_TARGET - for (j = 1; j < DV_VLC_MAP_LEV_SIZE; j++) { - if (dv_vlc_map[i][j].size == 0) { - dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc | - (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); - dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + - dv_vlc_map[0][j].size; - } - } -#else - for (j = 1; j < DV_VLC_MAP_LEV_SIZE/2; j++) { - if (dv_vlc_map[i][j].size == 0) { - dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc | - (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); - dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + - dv_vlc_map[0][j].size; - } - dv_vlc_map[i][((uint16_t)(-j))&0x1ff].vlc = - dv_vlc_map[i][j].vlc | 1; - dv_vlc_map[i][((uint16_t)(-j))&0x1ff].size = - dv_vlc_map[i][j].size; - } -#endif - } - } - - /* Generic DSP setup */ - dsputil_init(&dsp, avctx); - s->get_pixels = dsp.get_pixels; - - /* 88DCT setup */ - s->fdct[0] = dsp.fdct; - s->idct_put[0] = dsp.idct_put; - for (i=0; i<64; i++) - s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]]; - - /* 248DCT setup */ - s->fdct[1] = dsp.fdct248; - s->idct_put[1] = simple_idct248_put; // FIXME: need to add it to DSP - if(avctx->lowres){ - for (i=0; i<64; i++){ - int j= ff_zigzag248_direct[i]; - s->dv_zigzag[1][i] = dsp.idct_permutation[(j&7) + (j&8)*4 + (j&48)/2]; - } - }else - memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64); - - /* XXX: do it only for constant case */ - dv_build_unquantize_tables(s, dsp.idct_permutation); - - avctx->coded_frame = &s->picture; - s->avctx= avctx; - - return 0; -} - -// #define VLC_DEBUG -// #define printf(...) av_log(NULL, AV_LOG_ERROR, __VA_ARGS__) - -typedef struct BlockInfo { - const uint8_t *shift_table; - const uint8_t *scan_table; - const int *iweight_table; - uint8_t pos; /* position in block */ - uint8_t dct_mode; - uint8_t partial_bit_count; - uint16_t partial_bit_buffer; - int shift_offset; -} BlockInfo; - -/* block size in bits */ -static const uint16_t block_sizes[6] = { - 112, 112, 112, 112, 80, 80 -}; -/* bit budget for AC only in 5 MBs */ -static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; -/* see dv_88_areas and dv_248_areas for details */ -static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; - -static inline int get_bits_left(GetBitContext *s) -{ - return s->size_in_bits - get_bits_count(s); -} - -static inline int get_bits_size(GetBitContext *s) -{ - return s->size_in_bits; -} - -static inline int put_bits_left(PutBitContext* s) -{ - return (s->buf_end - s->buf) * 8 - put_bits_count(s); -} - -/* decode ac coefs */ -static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) -{ - int last_index = get_bits_size(gb); - const uint8_t *scan_table = mb->scan_table; - const uint8_t *shift_table = mb->shift_table; - const int *iweight_table = mb->iweight_table; - int pos = mb->pos; - int partial_bit_count = mb->partial_bit_count; - int level, pos1, run, vlc_len, index; - - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - - /* if we must parse a partial vlc, we do it here */ - if (partial_bit_count > 0) { - re_cache = ((unsigned)re_cache >> partial_bit_count) | - (mb->partial_bit_buffer << (sizeof(re_cache)*8 - partial_bit_count)); - re_index -= partial_bit_count; - mb->partial_bit_count = 0; - } - - /* get the AC coefficients until last_index is reached */ - for(;;) { -#ifdef VLC_DEBUG - printf("%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16), re_index); -#endif - /* our own optimized GET_RL_VLC */ - index = NEG_USR32(re_cache, TEX_VLC_BITS); - vlc_len = dv_rl_vlc[index].len; - if (vlc_len < 0) { - index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level; - vlc_len = TEX_VLC_BITS - vlc_len; - } - level = dv_rl_vlc[index].level; - run = dv_rl_vlc[index].run; - - /* gotta check if we're still within gb boundaries */ - if (re_index + vlc_len > last_index) { - /* should be < 16 bits otherwise a codeword could have been parsed */ - mb->partial_bit_count = last_index - re_index; - mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count); - re_index = last_index; - break; - } - re_index += vlc_len; - -#ifdef VLC_DEBUG - printf("run=%d level=%d\n", run, level); -#endif - pos += run; - if (pos >= 64) - break; - - pos1 = scan_table[pos]; - level <<= shift_table[pos1]; - - /* unweigh, round, and shift down */ - level = (level*iweight_table[pos] + (1 << (dv_iweight_bits-1))) >> dv_iweight_bits; - - block[pos1] = level; - - UPDATE_CACHE(re, gb); - } - CLOSE_READER(re, gb); - mb->pos = pos; -} - -static inline void bit_copy(PutBitContext *pb, GetBitContext *gb) -{ - int bits_left = get_bits_left(gb); - while (bits_left >= MIN_CACHE_BITS) { - put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS)); - bits_left -= MIN_CACHE_BITS; - } - if (bits_left > 0) { - put_bits(pb, bits_left, get_bits(gb, bits_left)); - } -} - -/* mb_x and mb_y are in units of 8 pixels */ -static inline void dv_decode_video_segment(DVVideoContext *s, - uint8_t *buf_ptr1, - const uint16_t *mb_pos_ptr) -{ - int quant, dc, dct_mode, class1, j; - int mb_index, mb_x, mb_y, v, last_index; - DCTELEM *block, *block1; - int c_offset; - uint8_t *y_ptr; - void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block); - uint8_t *buf_ptr; - PutBitContext pb, vs_pb; - GetBitContext gb; - BlockInfo mb_data[5 * 6], *mb, *mb1; - DECLARE_ALIGNED_8(DCTELEM, sblock[5*6][64]); - DECLARE_ALIGNED_8(uint8_t, mb_bit_buffer[80 + 4]); /* allow some slack */ - DECLARE_ALIGNED_8(uint8_t, vs_bit_buffer[5 * 80 + 4]); /* allow some slack */ - const int log2_blocksize= 3-s->avctx->lowres; - - assert((((int)mb_bit_buffer)&7)==0); - assert((((int)vs_bit_buffer)&7)==0); - - memset(sblock, 0, sizeof(sblock)); - - /* pass 1 : read DC and AC coefficients in blocks */ - buf_ptr = buf_ptr1; - block1 = &sblock[0][0]; - mb1 = mb_data; - init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80); - for(mb_index = 0; mb_index < 5; mb_index++, mb1 += 6, block1 += 6 * 64) { - /* skip header */ - quant = buf_ptr[3] & 0x0f; - buf_ptr += 4; - init_put_bits(&pb, mb_bit_buffer, 80); - mb = mb1; - block = block1; - for(j = 0;j < 6; j++) { - last_index = block_sizes[j]; - init_get_bits(&gb, buf_ptr, last_index); - - /* get the dc */ - dc = get_sbits(&gb, 9); - dct_mode = get_bits1(&gb); - mb->dct_mode = dct_mode; - mb->scan_table = s->dv_zigzag[dct_mode]; - mb->iweight_table = dct_mode ? dv_iweight_248 : dv_iweight_88; - class1 = get_bits(&gb, 2); - mb->shift_table = s->dv_idct_shift[class1 == 3][dct_mode] - [quant + dv_quant_offset[class1]]; - dc = dc << 2; - /* convert to unsigned because 128 is not added in the - standard IDCT */ - dc += 1024; - block[0] = dc; - buf_ptr += last_index >> 3; - mb->pos = 0; - mb->partial_bit_count = 0; - -#ifdef VLC_DEBUG - printf("MB block: %d, %d ", mb_index, j); -#endif - dv_decode_ac(&gb, mb, block); - - /* write the remaining bits in a new buffer only if the - block is finished */ - if (mb->pos >= 64) - bit_copy(&pb, &gb); - - block += 64; - mb++; - } - - /* pass 2 : we can do it just after */ -#ifdef VLC_DEBUG - printf("***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index); -#endif - block = block1; - mb = mb1; - init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb)); - flush_put_bits(&pb); - for(j = 0;j < 6; j++, block += 64, mb++) { - if (mb->pos < 64 && get_bits_left(&gb) > 0) { - dv_decode_ac(&gb, mb, block); - /* if still not finished, no need to parse other blocks */ - if (mb->pos < 64) - break; - } - } - /* all blocks are finished, so the extra bytes can be used at - the video segment level */ - if (j >= 6) - bit_copy(&vs_pb, &gb); - } - - /* we need a pass other the whole video segment */ -#ifdef VLC_DEBUG - printf("***pass 3 size=%d\n", put_bits_count(&vs_pb)); -#endif - block = &sblock[0][0]; - mb = mb_data; - init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb)); - flush_put_bits(&vs_pb); - for(mb_index = 0; mb_index < 5; mb_index++) { - for(j = 0;j < 6; j++) { - if (mb->pos < 64) { -#ifdef VLC_DEBUG - printf("start %d:%d\n", mb_index, j); -#endif - dv_decode_ac(&gb, mb, block); - } - if (mb->pos >= 64 && mb->pos < 127) - av_log(NULL, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos); - block += 64; - mb++; - } - } - - /* compute idct and place blocks */ - block = &sblock[0][0]; - mb = mb_data; - for(mb_index = 0; mb_index < 5; mb_index++) { - v = *mb_pos_ptr++; - mb_x = v & 0xff; - mb_y = v >> 8; - if (s->sys->pix_fmt == PIX_FMT_YUV422P) { - y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + (mb_x>>1))<picture.linesize[1] + (mb_x >> 2))<picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<sys->pix_fmt == PIX_FMT_YUV411P) - c_offset = ((mb_y * s->picture.linesize[1] + (mb_x >> 2))<> 1) * s->picture.linesize[1] + (mb_x >> 1))<idct_put[mb->dct_mode && log2_blocksize==3]; - if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */ - if (j == 0 || j == 2) { - /* Y0 Y1 */ - idct_put(y_ptr + ((j >> 1)<picture.linesize[0], block); - } else if(j > 3) { - /* Cr Cb */ - idct_put(s->picture.data[6 - j] + c_offset, - s->picture.linesize[6 - j], block); - } - /* note: j=1 and j=3 are "dummy" blocks in 4:2:2 */ - } else { /* 4:1:1 or 4:2:0 */ - if (j < 4) { - if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { - /* NOTE: at end of line, the macroblock is handled as 420 */ - idct_put(y_ptr + (j<picture.linesize[0], block); - } else { - idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<picture.linesize[0], block); - } - } else { - if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) { - uint64_t aligned_pixels[64/8]; - uint8_t *pixels= (uint8_t*)aligned_pixels; - uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1; - int x, y, linesize; - /* NOTE: at end of line, the macroblock is handled as 420 */ - idct_put(pixels, 8, block); - linesize = s->picture.linesize[6 - j]; - c_ptr = s->picture.data[6 - j] + c_offset; - ptr = pixels; - for(y = 0;y < (1<picture.data[6 - j] + c_offset, - s->picture.linesize[6 - j], block); - } - } - } - block += 64; - mb++; - } - } -} - -#ifdef DV_CODEC_TINY_TARGET -/* Converts run and level (where level != 0) pair into vlc, returning bit size */ -static always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc) -{ - int size; - if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { - *vlc = dv_vlc_map[run][level].vlc | sign; - size = dv_vlc_map[run][level].size; - } - else { - if (level < DV_VLC_MAP_LEV_SIZE) { - *vlc = dv_vlc_map[0][level].vlc | sign; - size = dv_vlc_map[0][level].size; - } else { - *vlc = 0xfe00 | (level << 1) | sign; - size = 16; - } - if (run) { - *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc : - (0x1f80 | (run - 1))) << size; - size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; - } - } - - return size; -} - -static always_inline int dv_rl2vlc_size(int run, int level) -{ - int size; - - if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { - size = dv_vlc_map[run][level].size; - } - else { - size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16; - if (run) { - size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; - } - } - return size; -} -#else -static always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc) -{ - *vlc = dv_vlc_map[run][l].vlc | sign; - return dv_vlc_map[run][l].size; -} - -static always_inline int dv_rl2vlc_size(int run, int l) -{ - return dv_vlc_map[run][l].size; -} -#endif - -typedef struct EncBlockInfo { - int area_q[4]; - int bit_size[4]; - int prev[5]; - int cur_ac; - int cno; - int dct_mode; - DCTELEM mb[64]; - uint8_t next[64]; - uint8_t sign[64]; - uint8_t partial_bit_count; - uint32_t partial_bit_buffer; /* we can't use uint16_t here */ -} EncBlockInfo; - -static always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi, PutBitContext* pb_pool, - PutBitContext* pb_end) -{ - int prev; - int bits_left; - PutBitContext* pb = pb_pool; - int size = bi->partial_bit_count; - uint32_t vlc = bi->partial_bit_buffer; - - bi->partial_bit_count = bi->partial_bit_buffer = 0; - for(;;){ - /* Find suitable storage space */ - for (; size > (bits_left = put_bits_left(pb)); pb++) { - if (bits_left) { - size -= bits_left; - put_bits(pb, bits_left, vlc >> size); - vlc = vlc & ((1<= pb_end) { - bi->partial_bit_count = size; - bi->partial_bit_buffer = vlc; - return pb; - } - } - - /* Store VLC */ - put_bits(pb, size, vlc); - - if(bi->cur_ac>=64) - break; - - /* Construct the next VLC */ - prev= bi->cur_ac; - bi->cur_ac = bi->next[prev]; - if(bi->cur_ac < 64){ - size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc); - } else { - size = 4; vlc = 6; /* End Of Block stamp */ - } - } - return pb; -} - -static always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi, - const uint8_t* zigzag_scan, const int *weight, int bias) -{ - int i, area; - /* We offer two different methods for class number assignment: the - method suggested in SMPTE 314M Table 22, and an improved - method. The SMPTE method is very conservative; it assigns class - 3 (i.e. severe quantization) to any block where the largest AC - component is greater than 36. ffmpeg's DV encoder tracks AC bit - consumption precisely, so there is no need to bias most blocks - towards strongly lossy compression. Instead, we assign class 2 - to most blocks, and use class 3 only when strictly necessary - (for blocks whose largest AC component exceeds 255). */ - -#if 0 /* SMPTE spec method */ - static const int classes[] = {12, 24, 36, 0xffff}; -#else /* improved ffmpeg method */ - static const int classes[] = {-1, -1, 255, 0xffff}; -#endif - int max=classes[0]; - int prev=0; - - bi->mb[0] = blk[0]; - - for (area = 0; area < 4; area++) { - bi->prev[area] = prev; - bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) - for (i=mb_area_start[area]; i 30U) { - bi->sign[i] = (level>>31)&1; - /* weigh it and and shift down into range, adding for rounding */ - /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT - AND the 2x doubling of the weights */ - level = (FFABS(level) * weight[i] + (1<<(dv_weight_bits+3))) >> (dv_weight_bits+4); - bi->mb[i] = level; - if(level>max) max= level; - bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level); - bi->next[prev]= i; - prev= i; - } - } - } - bi->next[prev]= i; - for(bi->cno = 0; max > classes[bi->cno]; bi->cno++); - - bi->cno += bias; - - if (bi->cno >= 3) { - bi->cno = 3; - prev=0; - i= bi->next[prev]; - for (area = 0; area < 4; area++) { - bi->prev[area] = prev; - bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) - for (; inext[i]) { - bi->mb[i] >>=1; - - if (bi->mb[i]) { - bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]); - bi->next[prev]= i; - prev= i; - } - } - } - bi->next[prev]= i; - } -} - -//FIXME replace this by dsputil -#define SC(x, y) ((s[x] - s[y]) ^ ((s[x] - s[y]) >> 7)) -static always_inline int dv_guess_dct_mode(DCTELEM *blk) { - DCTELEM *s; - int score88 = 0; - int score248 = 0; - int i; - - /* Compute 8-8 score (small values give a better chance for 8-8 DCT) */ - s = blk; - for(i=0; i<7; i++) { - score88 += SC(0, 8) + SC(1, 9) + SC(2, 10) + SC(3, 11) + - SC(4, 12) + SC(5,13) + SC(6, 14) + SC(7, 15); - s += 8; - } - /* Compute 2-4-8 score (small values give a better chance for 2-4-8 DCT) */ - s = blk; - for(i=0; i<6; i++) { - score248 += SC(0, 16) + SC(1,17) + SC(2, 18) + SC(3, 19) + - SC(4, 20) + SC(5,21) + SC(6, 22) + SC(7, 23); - s += 8; - } - - return (score88 - score248 > -10); -} - -static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos) -{ - int size[5]; - int i, j, k, a, prev, a2; - EncBlockInfo* b; - - size[0] = size[1] = size[2] = size[3] = size[4] = 1<<24; - do { - b = blks; - for (i=0; i<5; i++) { - if (!qnos[i]) - continue; - - qnos[i]--; - size[i] = 0; - for (j=0; j<6; j++, b++) { - for (a=0; a<4; a++) { - if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) { - b->bit_size[a] = 1; // 4 areas 4 bits for EOB :) - b->area_q[a]++; - prev= b->prev[a]; - assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]); - for (k= b->next[prev] ; knext[k]) { - b->mb[k] >>= 1; - if (b->mb[k]) { - b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]); - prev= k; - } else { - if(b->next[k] >= mb_area_start[a+1] && b->next[k]<64){ - for(a2=a+1; b->next[k] >= mb_area_start[a2+1]; a2++) - b->prev[a2] = prev; - assert(a2<4); - assert(b->mb[b->next[k]]); - b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]]) - -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]); - assert(b->prev[a2]==k && (a2+1 >= 4 || b->prev[a2+1]!=k)); - b->prev[a2] = prev; - } - b->next[prev] = b->next[k]; - } - } - b->prev[a+1]= prev; - } - size[i] += b->bit_size[a]; - } - } - if(vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4]) - return; - } - } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]); - - - for(a=2; a==2 || vs_total_ac_bits < size[0]; a+=a){ - b = blks; - size[0] = 5*6*4; //EOB - for (j=0; j<6*5; j++, b++) { - prev= b->prev[0]; - for (k= b->next[prev]; k<64; k= b->next[k]) { - if(b->mb[k] < a && b->mb[k] > -a){ - b->next[prev] = b->next[k]; - }else{ - size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]); - prev= k; - } - } - } - } -} - -static inline void dv_encode_video_segment(DVVideoContext *s, - uint8_t *dif, - const uint16_t *mb_pos_ptr) -{ - int mb_index, i, j, v; - int mb_x, mb_y, c_offset, linesize; - uint8_t* y_ptr; - uint8_t* data; - uint8_t* ptr; - int do_edge_wrap; - DECLARE_ALIGNED_8(DCTELEM, block[64]); - EncBlockInfo enc_blks[5*6]; - PutBitContext pbs[5*6]; - PutBitContext* pb; - EncBlockInfo* enc_blk; - int vs_bit_size = 0; - int qnos[5]; - - assert((((int)block) & 7) == 0); - - enc_blk = &enc_blks[0]; - pb = &pbs[0]; - for(mb_index = 0; mb_index < 5; mb_index++) { - v = *mb_pos_ptr++; - mb_x = v & 0xff; - mb_y = v >> 8; - if (s->sys->pix_fmt == PIX_FMT_YUV422P) { - y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 4); - } else { /* 4:1:1 */ - y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8); - } - if (s->sys->pix_fmt == PIX_FMT_YUV420P) { - c_offset = (((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8)); - } else { /* 4:2:2 or 4:1:1 */ - c_offset = ((mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8)); - } - do_edge_wrap = 0; - qnos[mb_index] = 15; /* No quantization */ - ptr = dif + mb_index*80 + 4; - for(j = 0;j < 6; j++) { - int dummy = 0; - if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */ - if (j == 0 || j == 2) { - /* Y0 Y1 */ - data = y_ptr + ((j>>1) * 8); - linesize = s->picture.linesize[0]; - } else if (j > 3) { - /* Cr Cb */ - data = s->picture.data[6 - j] + c_offset; - linesize = s->picture.linesize[6 - j]; - } else { - /* j=1 and j=3 are "dummy" blocks, used for AC data only */ - data = 0; - linesize = 0; - dummy = 1; - } - } else { /* 4:1:1 or 4:2:0 */ - if (j < 4) { /* Four Y blocks */ - /* NOTE: at end of line, the macroblock is handled as 420 */ - if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { - data = y_ptr + (j * 8); - } else { - data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]); - } - linesize = s->picture.linesize[0]; - } else { /* Cr and Cb blocks */ - /* don't ask Fabrice why they inverted Cb and Cr ! */ - data = s->picture.data[6 - j] + c_offset; - linesize = s->picture.linesize[6 - j]; - if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) - do_edge_wrap = 1; - } - } - - /* Everything is set up -- now just copy data -> DCT block */ - if (do_edge_wrap) { /* Edge wrap copy: 4x16 -> 8x8 */ - uint8_t* d; - DCTELEM *b = block; - for (i=0;i<8;i++) { - d = data + 8 * linesize; - b[0] = data[0]; b[1] = data[1]; b[2] = data[2]; b[3] = data[3]; - b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3]; - data += linesize; - b += 8; - } - } else { /* Simple copy: 8x8 -> 8x8 */ - if (!dummy) - s->get_pixels(block, data, linesize); - } - - if(s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) - enc_blk->dct_mode = dv_guess_dct_mode(block); - else - enc_blk->dct_mode = 0; - enc_blk->area_q[0] = enc_blk->area_q[1] = enc_blk->area_q[2] = enc_blk->area_q[3] = 0; - enc_blk->partial_bit_count = 0; - enc_blk->partial_bit_buffer = 0; - enc_blk->cur_ac = 0; - - if (dummy) { - /* We rely on the fact that encoding all zeros leads to an immediate EOB, - which is precisely what the spec calls for in the "dummy" blocks. */ - memset(block, 0, sizeof(block)); - } else { - s->fdct[enc_blk->dct_mode](block); - } - - dv_set_class_number(block, enc_blk, - enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct, - enc_blk->dct_mode ? dv_weight_248 : dv_weight_88, - j/4); - - init_put_bits(pb, ptr, block_sizes[j]/8); - put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024 + 2) >> 2)); - put_bits(pb, 1, enc_blk->dct_mode); - put_bits(pb, 2, enc_blk->cno); - - vs_bit_size += enc_blk->bit_size[0] + enc_blk->bit_size[1] + - enc_blk->bit_size[2] + enc_blk->bit_size[3]; - ++enc_blk; - ++pb; - ptr += block_sizes[j]/8; - } - } - - if (vs_total_ac_bits < vs_bit_size) - dv_guess_qnos(&enc_blks[0], &qnos[0]); - - for (i=0; i<5; i++) { - dif[i*80 + 3] = qnos[i]; - } - - /* First pass over individual cells only */ - for (j=0; j<5*6; j++) - dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]); - - /* Second pass over each MB space */ - for (j=0; j<5*6; j+=6) { - pb= &pbs[j]; - for (i=0; i<6; i++) { - if (enc_blks[i+j].partial_bit_count) - pb=dv_encode_ac(&enc_blks[i+j], pb, &pbs[j+6]); - } - } - - /* Third and final pass over the whole vides segment space */ - pb= &pbs[0]; - for (j=0; j<5*6; j++) { - if (enc_blks[j].partial_bit_count) - pb=dv_encode_ac(&enc_blks[j], pb, &pbs[6*5]); - if (enc_blks[j].partial_bit_count) - av_log(NULL, AV_LOG_ERROR, "ac bitstream overflow\n"); - } - - for (j=0; j<5*6; j++) - flush_put_bits(&pbs[j]); -} - -static int dv_decode_mt(AVCodecContext *avctx, void* sl) -{ - DVVideoContext *s = avctx->priv_data; - int slice = (size_t)sl; - - /* which DIF channel is this? */ - int chan = slice / (s->sys->difseg_size * 27); - - /* slice within the DIF channel */ - int chan_slice = slice % (s->sys->difseg_size * 27); - - /* byte offset of this channel's data */ - int chan_offset = chan * s->sys->difseg_size * 150 * 80; - - dv_decode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset], - &s->sys->video_place[slice*5]); - return 0; -} - -#ifdef CONFIG_ENCODERS -static int dv_encode_mt(AVCodecContext *avctx, void* sl) -{ - DVVideoContext *s = avctx->priv_data; - int slice = (size_t)sl; - - /* which DIF channel is this? */ - int chan = slice / (s->sys->difseg_size * 27); - - /* slice within the DIF channel */ - int chan_slice = slice % (s->sys->difseg_size * 27); - - /* byte offset of this channel's data */ - int chan_offset = chan * s->sys->difseg_size * 150 * 80; - - dv_encode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset], - &s->sys->video_place[slice*5]); - return 0; -} -#endif - -#ifdef CONFIG_DECODERS -/* NOTE: exactly one frame must be given (120000 bytes for NTSC, - 144000 bytes for PAL - or twice those for 50Mbps) */ -static int dvvideo_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - DVVideoContext *s = avctx->priv_data; - - s->sys = dv_frame_profile(buf); - if (!s->sys || buf_size < s->sys->frame_size) - return -1; /* NOTE: we only accept several full frames */ - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - s->picture.reference = 0; - s->picture.key_frame = 1; - s->picture.pict_type = FF_I_TYPE; - avctx->pix_fmt = s->sys->pix_fmt; - avcodec_set_dimensions(avctx, s->sys->width, s->sys->height); - if(avctx->get_buffer(avctx, &s->picture) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - s->picture.interlaced_frame = 1; - s->picture.top_field_first = 0; - - s->buf = buf; - avctx->execute(avctx, dv_decode_mt, (void**)&dv_anchor[0], NULL, - s->sys->n_difchan * s->sys->difseg_size * 27); - - emms_c(); - - /* return image */ - *data_size = sizeof(AVFrame); - *(AVFrame*)data= s->picture; - - return s->sys->frame_size; -} -#endif - - -static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c, uint8_t* buf) -{ - /* - * Here's what SMPTE314M says about these two: - * (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical - * as track application IDs (APTn = 001, AP1n = - * 001, AP2n = 001, AP3n = 001), if the source signal - * comes from a digital VCR. If the signal source is - * unknown, all bits for these data shall be set to 1. - * (page 12) STYPE: STYPE defines a signal type of video signal - * 00000b = 4:1:1 compression - * 00100b = 4:2:2 compression - * XXXXXX = Reserved - * Now, I've got two problems with these statements: - * 1. it looks like APT == 111b should be a safe bet, but it isn't. - * It seems that for PAL as defined in IEC 61834 we have to set - * APT to 000 and for SMPTE314M to 001. - * 2. It is not at all clear what STYPE is used for 4:2:0 PAL - * compression scheme (if any). - */ - int apt = (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0 : 1); - int stype = (c->sys->pix_fmt == PIX_FMT_YUV422P ? 4 : 0); - - uint8_t aspect = 0; - if((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) == 17) /* 16:9 */ - aspect = 0x02; - - buf[0] = (uint8_t)pack_id; - switch (pack_id) { - case dv_header525: /* I can't imagine why these two weren't defined as real */ - case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */ - buf[1] = 0xf8 | /* reserved -- always 1 */ - (apt & 0x07); /* APT: Track application ID */ - buf[2] = (0 << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */ - (0x0f << 3) | /* reserved -- always 1 */ - (apt & 0x07); /* AP1: Audio application ID */ - buf[3] = (0 << 7) | /* TF2: video data is 0 - valid; 1 - invalid */ - (0x0f << 3) | /* reserved -- always 1 */ - (apt & 0x07); /* AP2: Video application ID */ - buf[4] = (0 << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */ - (0x0f << 3) | /* reserved -- always 1 */ - (apt & 0x07); /* AP3: Subcode application ID */ - break; - case dv_video_source: - buf[1] = 0xff; /* reserved -- always 1 */ - buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */ - (1 << 6) | /* following CLF is valid - 0, invalid - 1 */ - (3 << 4) | /* CLF: color frames id (see ITU-R BT.470-4) */ - 0xf; /* reserved -- always 1 */ - buf[3] = (3 << 6) | /* reserved -- always 1 */ - (c->sys->dsf << 5) | /* system: 60fields/50fields */ - stype; /* signal type video compression */ - buf[4] = 0xff; /* VISC: 0xff -- no information */ - break; - case dv_video_control: - buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */ - 0x3f; /* reserved -- always 1 */ - buf[2] = 0xc8 | /* reserved -- always b11001xxx */ - aspect; - buf[3] = (1 << 7) | /* Frame/field flag 1 -- frame, 0 -- field */ - (1 << 6) | /* First/second field flag 0 -- field 2, 1 -- field 1 */ - (1 << 5) | /* Frame change flag 0 -- same picture as before, 1 -- different */ - (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */ - 0xc; /* reserved -- always b1100 */ - buf[4] = 0xff; /* reserved -- always 1 */ - break; - default: - buf[1] = buf[2] = buf[3] = buf[4] = 0xff; - } - return 5; -} - -static void dv_format_frame(DVVideoContext* c, uint8_t* buf) -{ - int chan, i, j, k; - - for (chan = 0; chan < c->sys->n_difchan; chan++) { - for (i = 0; i < c->sys->difseg_size; i++) { - memset(buf, 0xff, 80 * 6); /* First 6 DIF blocks are for control data */ - - /* DV header: 1DIF */ - buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf); - buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf); - buf += 72; /* unused bytes */ - - /* DV subcode: 2DIFs */ - for (j = 0; j < 2; j++) { - buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf); - for (k = 0; k < 6; k++) - buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5; - buf += 29; /* unused bytes */ - } - - /* DV VAUX: 3DIFS */ - for (j = 0; j < 3; j++) { - buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf); - buf += dv_write_pack(dv_video_source, c, buf); - buf += dv_write_pack(dv_video_control, c, buf); - buf += 7*5; - buf += dv_write_pack(dv_video_source, c, buf); - buf += dv_write_pack(dv_video_control, c, buf); - buf += 4*5 + 2; /* unused bytes */ - } - - /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */ - for (j = 0; j < 135; j++) { - if (j%15 == 0) { - memset(buf, 0xff, 80); - buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf); - buf += 77; /* audio control & shuffled PCM audio */ - } - buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf); - buf += 77; /* 1 video macro block: 1 bytes control - 4 * 14 bytes Y 8x8 data - 10 bytes Cr 8x8 data - 10 bytes Cb 8x8 data */ - } - } - } -} - - -#ifdef CONFIG_ENCODERS -static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size, - void *data) -{ - DVVideoContext *s = c->priv_data; - - s->sys = dv_codec_profile(c); - if (!s->sys) - return -1; - if(buf_size < s->sys->frame_size) - return -1; - - c->pix_fmt = s->sys->pix_fmt; - s->picture = *((AVFrame *)data); - s->picture.key_frame = 1; - s->picture.pict_type = FF_I_TYPE; - - s->buf = buf; - c->execute(c, dv_encode_mt, (void**)&dv_anchor[0], NULL, - s->sys->n_difchan * s->sys->difseg_size * 27); - - emms_c(); - - dv_format_frame(s, buf); - - return s->sys->frame_size; -} -#endif - -static int dvvideo_close(AVCodecContext *c) -{ - - return 0; -} - - -#ifdef CONFIG_DVVIDEO_ENCODER -AVCodec dvvideo_encoder = { - "dvvideo", - CODEC_TYPE_VIDEO, - CODEC_ID_DVVIDEO, - sizeof(DVVideoContext), - dvvideo_init, - dvvideo_encode_frame, - dvvideo_close, - NULL, - CODEC_CAP_DR1, - NULL -}; -#endif // CONFIG_DVVIDEO_ENCODER - -#ifdef CONFIG_DVVIDEO_DECODER -AVCodec dvvideo_decoder = { - "dvvideo", - CODEC_TYPE_VIDEO, - CODEC_ID_DVVIDEO, - sizeof(DVVideoContext), - dvvideo_init, - NULL, - dvvideo_close, - dvvideo_decode_frame, - CODEC_CAP_DR1, - NULL -}; -#endif diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/huffyuv.c --- a/src/ffmpeg/libavcodec/huffyuv.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1290 +0,0 @@ -/* - * huffyuv codec for libavcodec - * - * Copyright (c) 2002-2003 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of - * the algorithm used - */ - -/** - * @file huffyuv.c - * huffyuv codec for libavcodec. - */ - -#include "common.h" -#include "bitstream.h" -#include "avcodec.h" -#include "dsputil.h" - -#define VLC_BITS 11 - -#ifdef WORDS_BIGENDIAN -#define B 3 -#define G 2 -#define R 1 -#else -#define B 0 -#define G 1 -#define R 2 -#endif - -typedef enum Predictor{ - LEFT= 0, - PLANE, - MEDIAN, -} Predictor; - -typedef struct HYuvContext{ - AVCodecContext *avctx; - Predictor predictor; - GetBitContext gb; - PutBitContext pb; - int interlaced; - int decorrelate; - int bitstream_bpp; - int version; - int yuy2; //use yuy2 instead of 422P - int bgr32; //use bgr32 instead of bgr24 - int width, height; - int flags; - int context; - int picture_number; - int last_slice_end; - uint8_t *temp[3]; - uint64_t stats[3][256]; - uint8_t len[3][256]; - uint32_t bits[3][256]; - VLC vlc[3]; - AVFrame picture; - uint8_t *bitstream_buffer; - unsigned int bitstream_buffer_size; - DSPContext dsp; -}HYuvContext; - -static const unsigned char classic_shift_luma[] = { - 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8, - 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70, - 69,68, 0 -}; - -static const unsigned char classic_shift_chroma[] = { - 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183, - 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119, - 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0 -}; - -static const unsigned char classic_add_luma[256] = { - 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37, - 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36, - 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36, - 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39, - 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37, - 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29, - 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16, - 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14, - 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6, - 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15, - 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25, - 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49, - 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60, - 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52, - 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43, - 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8, -}; - -static const unsigned char classic_add_chroma[256] = { - 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9, - 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7, - 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77, - 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63, - 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22, - 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111, - 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1, - 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134, - 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96, - 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41, - 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36, - 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26, - 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13, - 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8, - 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2, -}; - -static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){ - int i; - - for(i=0; idsp.diff_bytes(dst+16, src+16, src+15, w-16); - return src[w-1]; - } -} - -static void read_len_table(uint8_t *dst, GetBitContext *gb){ - int i, val, repeat; - - for(i=0; i<256;){ - repeat= get_bits(gb, 3); - val = get_bits(gb, 5); - if(repeat==0) - repeat= get_bits(gb, 8); -//printf("%d %d\n", val, repeat); - while (repeat--) - dst[i++] = val; - } -} - -static int generate_bits_table(uint32_t *dst, uint8_t *len_table){ - int len, index; - uint32_t bits=0; - - for(len=32; len>0; len--){ - for(index=0; index<256; index++){ - if(len_table[index]==len) - dst[index]= bits++; - } - if(bits & 1){ - av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n"); - return -1; - } - bits >>= 1; - } - return 0; -} - -#ifdef CONFIG_ENCODERS -static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){ - uint64_t counts[2*size]; - int up[2*size]; - int offset, i, next; - - for(offset=1; ; offset<<=1){ - for(i=0; i counts[i]){ - if(min1 > counts[i]){ - min2= min1; - min2_i= min1_i; - min1= counts[i]; - min1_i= i; - }else{ - min2= counts[i]; - min2_i= i; - } - } - } - - if(min2==INT64_MAX) break; - - counts[next]= min1 + min2; - counts[min1_i]= - counts[min2_i]= INT64_MAX; - up[min1_i]= - up[min2_i]= next; - up[next]= -1; - } - - for(i=0; i= 32) break; - - dst[i]= len; - } - if(i==size) break; - } -} -#endif /* CONFIG_ENCODERS */ - -static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){ - GetBitContext gb; - int i; - - init_get_bits(&gb, src, length*8); - - for(i=0; i<3; i++){ - read_len_table(s->len[i], &gb); - - if(generate_bits_table(s->bits[i], s->len[i])<0){ - return -1; - } -#if 0 -for(j=0; j<256; j++){ -printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j); -} -#endif - free_vlc(&s->vlc[i]); - init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); - } - - return (get_bits_count(&gb)+7)/8; -} - -static int read_old_huffman_tables(HYuvContext *s){ -#if 1 - GetBitContext gb; - int i; - - init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8); - read_len_table(s->len[0], &gb); - init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8); - read_len_table(s->len[1], &gb); - - for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i]; - for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i]; - - if(s->bitstream_bpp >= 24){ - memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t)); - memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t)); - } - memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t)); - memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t)); - - for(i=0; i<3; i++){ - free_vlc(&s->vlc[i]); - init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); - } - - return 0; -#else - av_log(s->avctx, AV_LOG_DEBUG, "v1 huffyuv is not supported \n"); - return -1; -#endif -} - -static void alloc_temp(HYuvContext *s){ - int i; - - if(s->bitstream_bpp<24){ - for(i=0; i<3; i++){ - s->temp[i]= av_malloc(s->width + 16); - } - }else{ - s->temp[0]= av_malloc(4*s->width + 16); - } -} - -static int common_init(AVCodecContext *avctx){ - HYuvContext *s = avctx->priv_data; - - s->avctx= avctx; - s->flags= avctx->flags; - - dsputil_init(&s->dsp, avctx); - - s->width= avctx->width; - s->height= avctx->height; - assert(s->width>0 && s->height>0); - - return 0; -} - -#ifdef CONFIG_DECODERS -static int decode_init(AVCodecContext *avctx) -{ - HYuvContext *s = avctx->priv_data; - - common_init(avctx); - memset(s->vlc, 0, 3*sizeof(VLC)); - - avctx->coded_frame= &s->picture; - s->interlaced= s->height > 288; - -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) && avctx->bits_per_sample != 12) - s->version=1; // do such files exist at all? - else - s->version=2; - }else - s->version=0; - - if(s->version==2){ - int method, interlace; - - method= ((uint8_t*)avctx->extradata)[0]; - s->decorrelate= method&64 ? 1 : 0; - s->predictor= method&63; - s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1]; - if(s->bitstream_bpp==0) - s->bitstream_bpp= avctx->bits_per_sample&~7; - interlace= (((uint8_t*)avctx->extradata)[2] & 0x30) >> 4; - s->interlaced= (interlace==1) ? 1 : (interlace==2) ? 0 : s->interlaced; - s->context= ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0; - - if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0) - return -1; - }else{ - switch(avctx->bits_per_sample&7){ - case 1: - s->predictor= LEFT; - s->decorrelate= 0; - break; - case 2: - s->predictor= LEFT; - s->decorrelate= 1; - break; - case 3: - s->predictor= PLANE; - s->decorrelate= avctx->bits_per_sample >= 24; - break; - case 4: - s->predictor= MEDIAN; - s->decorrelate= 0; - break; - default: - s->predictor= LEFT; //OLD - s->decorrelate= 0; - break; - } - s->bitstream_bpp= avctx->bits_per_sample & ~7; - s->context= 0; - - if(read_old_huffman_tables(s) < 0) - return -1; - } - - switch(s->bitstream_bpp){ - case 12: - avctx->pix_fmt = PIX_FMT_YUV420P; - break; - case 16: - if(s->yuy2){ - avctx->pix_fmt = PIX_FMT_YUV422; - }else{ - avctx->pix_fmt = PIX_FMT_YUV422P; - } - break; - case 24: - case 32: - if(s->bgr32){ - avctx->pix_fmt = PIX_FMT_RGBA32; - }else{ - avctx->pix_fmt = PIX_FMT_BGR24; - } - break; - default: - assert(0); - } - - alloc_temp(s); - -// av_log(NULL, AV_LOG_DEBUG, "pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced); - - return 0; -} -#endif - -#ifdef CONFIG_ENCODERS -static int store_table(HYuvContext *s, uint8_t *len, uint8_t *buf){ - int i; - int index= 0; - - for(i=0; i<256;){ - int val= len[i]; - int repeat=0; - - for(; i<256 && len[i]==val && repeat<255; i++) - repeat++; - - assert(val < 32 && val >0 && repeat<256 && repeat>0); - if(repeat>7){ - buf[index++]= val; - buf[index++]= repeat; - }else{ - buf[index++]= val | (repeat<<5); - } - } - - return index; -} - -static int encode_init(AVCodecContext *avctx) -{ - HYuvContext *s = avctx->priv_data; - int i, j; - - common_init(avctx); - - avctx->extradata= av_mallocz(1024*30); // 256*3+4 == 772 - avctx->stats_out= av_mallocz(1024*30); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132 - s->version=2; - - avctx->coded_frame= &s->picture; - - switch(avctx->pix_fmt){ - case PIX_FMT_YUV420P: - s->bitstream_bpp= 12; - break; - case PIX_FMT_YUV422P: - s->bitstream_bpp= 16; - break; - default: - av_log(avctx, AV_LOG_ERROR, "format not supported\n"); - return -1; - } - avctx->bits_per_sample= s->bitstream_bpp; - s->decorrelate= s->bitstream_bpp >= 24; - s->predictor= avctx->prediction_method; - s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0; - if(avctx->context_model==1){ - s->context= avctx->context_model; - if(s->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)){ - av_log(avctx, AV_LOG_ERROR, "context=1 is not compatible with 2 pass huffyuv encoding\n"); - return -1; - } - }else s->context= 0; - - if(avctx->codec->id==CODEC_ID_HUFFYUV){ - if(avctx->pix_fmt==PIX_FMT_YUV420P){ - av_log(avctx, AV_LOG_ERROR, "Error: YV12 is not supported by huffyuv; use vcodec=ffvhuff or format=422p\n"); - return -1; - } - if(avctx->context_model){ - av_log(avctx, AV_LOG_ERROR, "Error: per-frame huffman tables are not supported by huffyuv; use vcodec=ffvhuff\n"); - return -1; - } - if(s->interlaced != ( s->height > 288 )) - av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n"); - } - - ((uint8_t*)avctx->extradata)[0]= s->predictor; - ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp; - ((uint8_t*)avctx->extradata)[2]= s->interlaced ? 0x10 : 0x20; - if(s->context) - ((uint8_t*)avctx->extradata)[2]|= 0x40; - ((uint8_t*)avctx->extradata)[3]= 0; - s->avctx->extradata_size= 4; - - if(avctx->stats_in){ - char *p= avctx->stats_in; - - for(i=0; i<3; i++) - for(j=0; j<256; j++) - s->stats[i][j]= 1; - - for(;;){ - for(i=0; i<3; i++){ - char *next; - - for(j=0; j<256; j++){ - s->stats[i][j]+= strtol(p, &next, 0); - if(next==p) return -1; - p=next; - } - } - if(p[0]==0 || p[1]==0 || p[2]==0) break; - } - }else{ - for(i=0; i<3; i++) - for(j=0; j<256; j++){ - int d= FFMIN(j, 256-j); - - s->stats[i][j]= 100000000/(d+1); - } - } - - for(i=0; i<3; i++){ - generate_len_table(s->len[i], s->stats[i], 256); - - if(generate_bits_table(s->bits[i], s->len[i])<0){ - return -1; - } - - s->avctx->extradata_size+= - store_table(s, s->len[i], &((uint8_t*)s->avctx->extradata)[s->avctx->extradata_size]); - } - - if(s->context){ - for(i=0; i<3; i++){ - int pels = s->width*s->height / (i?40:10); - for(j=0; j<256; j++){ - int d= FFMIN(j, 256-j); - s->stats[i][j]= pels/(d+1); - } - } - }else{ - for(i=0; i<3; i++) - for(j=0; j<256; j++) - s->stats[i][j]= 0; - } - -// printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced); - - alloc_temp(s); - - s->picture_number=0; - - return 0; -} -#endif /* CONFIG_ENCODERS */ - -static void decode_422_bitstream(HYuvContext *s, int count){ - int i; - - count/=2; - - for(i=0; itemp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); - s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); - s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); - s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); - } -} - -static void decode_gray_bitstream(HYuvContext *s, int count){ - int i; - - count/=2; - - for(i=0; itemp[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); - } -} - -#ifdef CONFIG_ENCODERS -static int encode_422_bitstream(HYuvContext *s, int count){ - int i; - - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 2*4*count){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - count/=2; - if(s->flags&CODEC_FLAG_PASS1){ - for(i=0; istats[0][ s->temp[0][2*i ] ]++; - s->stats[1][ s->temp[1][ i ] ]++; - s->stats[0][ s->temp[0][2*i+1] ]++; - s->stats[2][ s->temp[2][ i ] ]++; - } - } - if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) - return 0; - if(s->context){ - for(i=0; istats[0][ s->temp[0][2*i ] ]++; - put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); - s->stats[1][ s->temp[1][ i ] ]++; - put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]); - s->stats[0][ s->temp[0][2*i+1] ]++; - put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]); - s->stats[2][ s->temp[2][ i ] ]++; - put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]); - } - }else{ - for(i=0; ipb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); - put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]); - put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]); - put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]); - } - } - return 0; -} - -static int encode_gray_bitstream(HYuvContext *s, int count){ - int i; - - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*count){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - count/=2; - if(s->flags&CODEC_FLAG_PASS1){ - for(i=0; istats[0][ s->temp[0][2*i ] ]++; - s->stats[0][ s->temp[0][2*i+1] ]++; - } - } - if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) - return 0; - - if(s->context){ - for(i=0; istats[0][ s->temp[0][2*i ] ]++; - put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); - s->stats[0][ s->temp[0][2*i+1] ]++; - put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]); - } - }else{ - for(i=0; ipb, 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] ]); - } - } - return 0; -} -#endif /* CONFIG_ENCODERS */ - -static void decode_bgr_bitstream(HYuvContext *s, int count){ - int i; - - if(s->decorrelate){ - if(s->bitstream_bpp==24){ - for(i=0; itemp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); - s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G]; - s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+G]; - } - }else{ - for(i=0; itemp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); - s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G]; - s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+G]; - get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?! - } - } - }else{ - if(s->bitstream_bpp==24){ - for(i=0; itemp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); - s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); - s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); - } - }else{ - for(i=0; itemp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); - s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); - s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); - get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?! - } - } - } -} - -#ifdef CONFIG_DECODERS -static void draw_slice(HYuvContext *s, int y){ - int h, cy; - int offset[4]; - - if(s->avctx->draw_horiz_band==NULL) - return; - - h= y - s->last_slice_end; - y -= h; - - if(s->bitstream_bpp==12){ - cy= y>>1; - }else{ - cy= y; - } - - offset[0] = s->picture.linesize[0]*y; - offset[1] = s->picture.linesize[1]*cy; - offset[2] = s->picture.linesize[2]*cy; - offset[3] = 0; - emms_c(); - - s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h); - - s->last_slice_end= y + h; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){ - HYuvContext *s = avctx->priv_data; - const int width= s->width; - const int width2= s->width>>1; - const int height= s->height; - int fake_ystride, fake_ustride, fake_vstride; - AVFrame * const p= &s->picture; - int table_size= 0; - - AVFrame *picture = data; - - s->bitstream_buffer= av_fast_realloc(s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - - s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4); - - if(p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference= 0; - if(avctx->get_buffer(avctx, p) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - if(s->context){ - table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size); - if(table_size < 0) - return -1; - } - - if((unsigned)(buf_size-table_size) >= INT_MAX/8) - return -1; - - init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size)*8); - - fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0]; - fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1]; - fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2]; - - s->last_slice_end= 0; - - if(s->bitstream_bpp<24){ - int y, cy; - int lefty, leftu, leftv; - int lefttopy, lefttopu, lefttopv; - - if(s->yuy2){ - p->data[0][3]= get_bits(&s->gb, 8); - p->data[0][2]= get_bits(&s->gb, 8); - p->data[0][1]= get_bits(&s->gb, 8); - p->data[0][0]= get_bits(&s->gb, 8); - - av_log(avctx, AV_LOG_ERROR, "YUY2 output is not implemented yet\n"); - return -1; - }else{ - - leftv= p->data[2][0]= get_bits(&s->gb, 8); - lefty= p->data[0][1]= get_bits(&s->gb, 8); - leftu= p->data[1][0]= get_bits(&s->gb, 8); - p->data[0][0]= get_bits(&s->gb, 8); - - switch(s->predictor){ - case LEFT: - case PLANE: - decode_422_bitstream(s, width-2); - lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); - leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); - } - - for(cy=y=1; yheight; y++,cy++){ - uint8_t *ydst, *udst, *vdst; - - if(s->bitstream_bpp==12){ - decode_gray_bitstream(s, width); - - ydst= p->data[0] + p->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; - } - - draw_slice(s, y); - - ydst= p->data[0] + p->linesize[0]*y; - udst= p->data[1] + p->linesize[1]*cy; - vdst= p->data[2] + p->linesize[2]*cy; - - decode_422_bitstream(s, width); - lefty= add_left_prediction(ydst, s->temp[0], width, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= add_left_prediction(udst, s->temp[1], width2, leftu); - leftv= add_left_prediction(vdst, s->temp[2], width2, leftv); - } - if(s->predictor == PLANE){ - 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); - s->dsp.add_bytes(vdst, vdst - fake_vstride, width2); - } - } - } - } - draw_slice(s, height); - - break; - case MEDIAN: - /* first line except first 2 pixels is left predicted */ - decode_422_bitstream(s, width-2); - lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); - leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); - } - - cy=y=1; - - /* second line is left predicted for interlaced case */ - if(s->interlaced){ - decode_422_bitstream(s, width); - lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); - leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); - } - y++; cy++; - } - - /* next 4 pixels are left predicted too */ - decode_422_bitstream(s, 4); - lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty); - if(!(s->flags&CODEC_FLAG_GRAY)){ - leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu); - leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv); - } - - /* next line except the first 4 pixels is median predicted */ - lefttopy= p->data[0][3]; - decode_422_bitstream(s, width-4); - add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy); - if(!(s->flags&CODEC_FLAG_GRAY)){ - lefttopu= p->data[1][1]; - lefttopv= p->data[2][1]; - add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); - add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); - } - y++; cy++; - - for(; ybitstream_bpp==12){ - while(2*cy > y){ - decode_gray_bitstream(s, width); - ydst= p->data[0] + p->linesize[0]*y; - add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); - y++; - } - if(y>=height) break; - } - draw_slice(s, y); - - decode_422_bitstream(s, width); - - ydst= p->data[0] + p->linesize[0]*y; - udst= p->data[1] + p->linesize[1]*cy; - vdst= p->data[2] + p->linesize[2]*cy; - - add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); - if(!(s->flags&CODEC_FLAG_GRAY)){ - add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu); - add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv); - } - } - - draw_slice(s, height); - break; - } - } - }else{ - int y; - int leftr, leftg, leftb; - const int last_line= (height-1)*p->linesize[0]; - - if(s->bitstream_bpp==32){ - skip_bits(&s->gb, 8); - leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8); - leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8); - leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8); - }else{ - leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8); - leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8); - leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8); - skip_bits(&s->gb, 8); - } - - if(s->bgr32){ - switch(s->predictor){ - case LEFT: - case PLANE: - decode_bgr_bitstream(s, width-1); - add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb); - - for(y=s->height-2; y>=0; y--){ //yes its stored upside down - decode_bgr_bitstream(s, width); - - add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb); - if(s->predictor == PLANE){ - if((y&s->interlaced)==0 && yheight-1-s->interlaced){ - s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, - p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride); - } - } - } - draw_slice(s, height); // just 1 large slice as this is not possible in reverse order - break; - default: - av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n"); - } - }else{ - - av_log(avctx, AV_LOG_ERROR, "BGR24 output is not implemented yet\n"); - return -1; - } - } - emms_c(); - - *picture= *p; - *data_size = sizeof(AVFrame); - - return (get_bits_count(&s->gb)+31)/32*4 + table_size; -} -#endif - -static int common_end(HYuvContext *s){ - int i; - - for(i=0; i<3; i++){ - av_freep(&s->temp[i]); - } - return 0; -} - -#ifdef CONFIG_DECODERS -static int decode_end(AVCodecContext *avctx) -{ - HYuvContext *s = avctx->priv_data; - int i; - - common_end(s); - av_freep(&s->bitstream_buffer); - - for(i=0; i<3; i++){ - free_vlc(&s->vlc[i]); - } - - return 0; -} -#endif - -#ifdef CONFIG_ENCODERS -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - HYuvContext *s = avctx->priv_data; - AVFrame *pict = data; - const int width= s->width; - const int width2= s->width>>1; - const int height= s->height; - const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0]; - const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1]; - const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2]; - AVFrame * const p= &s->picture; - int i, j, size=0; - - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - if(s->context){ - for(i=0; i<3; i++){ - generate_len_table(s->len[i], s->stats[i], 256); - if(generate_bits_table(s->bits[i], s->len[i])<0) - return -1; - size+= store_table(s, s->len[i], &buf[size]); - } - - for(i=0; i<3; i++) - for(j=0; j<256; j++) - s->stats[i][j] >>= 1; - } - - init_put_bits(&s->pb, buf+size, buf_size-size); - - 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= p->data[2][0]); - put_bits(&s->pb, 8, lefty= p->data[0][1]); - put_bits(&s->pb, 8, leftu= p->data[1][0]); - put_bits(&s->pb, 8, p->data[0][0]); - - lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty); - leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu); - leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv); - - encode_422_bitstream(s, width-2); - - if(s->predictor==MEDIAN){ - int lefttopy, lefttopu, lefttopv; - cy=y=1; - if(s->interlaced){ - lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty); - leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu); - leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv); - - encode_422_bitstream(s, width); - y++; cy++; - } - - lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty); - leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ustride, 2, leftu); - leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_vstride, 2, leftv); - - encode_422_bitstream(s, 4); - - lefttopy= p->data[0][3]; - lefttopu= p->data[1][1]; - lefttopv= p->data[2][1]; - s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy); - s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu); - s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv); - encode_422_bitstream(s, width-4); - y++; cy++; - - for(; ybitstream_bpp==12){ - while(2*cy > y){ - ydst= p->data[0] + p->linesize[0]*y; - s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); - encode_gray_bitstream(s, width); - y++; - } - if(y>=height) break; - } - ydst= p->data[0] + p->linesize[0]*y; - udst= p->data[1] + p->linesize[1]*cy; - vdst= p->data[2] + p->linesize[2]*cy; - - s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); - s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu); - s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv); - - encode_422_bitstream(s, width); - } - }else{ - for(cy=y=1; ybitstream_bpp==12){ - ydst= p->data[0] + p->linesize[0]*y; - - if(s->predictor == PLANE && s->interlaced < y){ - s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); - - lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty); - }else{ - lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty); - } - encode_gray_bitstream(s, width); - y++; - if(y>=height) break; - } - - ydst= p->data[0] + p->linesize[0]*y; - udst= p->data[1] + p->linesize[1]*cy; - vdst= p->data[2] + p->linesize[2]*cy; - - if(s->predictor == PLANE && s->interlaced < cy){ - s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); - s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2); - s->dsp.diff_bytes(s->temp[2] + width2, vdst, vdst - fake_vstride, width2); - - lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty); - leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu); - leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + width2, width2, leftv); - }else{ - lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty); - leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu); - leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv); - } - - encode_422_bitstream(s, width); - } - } - }else{ - av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); - } - emms_c(); - - size+= (put_bits_count(&s->pb)+31)/8; - size/= 4; - - if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){ - int j; - char *p= avctx->stats_out; - char *end= p + 1024*30; - for(i=0; i<3; i++){ - for(j=0; j<256; j++){ - snprintf(p, end-p, "%"PRIu64" ", s->stats[i][j]); - p+= strlen(p); - s->stats[i][j]= 0; - } - snprintf(p, end-p, "\n"); - p++; - } - } - if(!(s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)){ - flush_put_bits(&s->pb); - s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); - avctx->stats_out[0] = '\0'; - } - - s->picture_number++; - - return size*4; -} - -static int encode_end(AVCodecContext *avctx) -{ - HYuvContext *s = avctx->priv_data; - - common_end(s); - - av_freep(&avctx->extradata); - av_freep(&avctx->stats_out); - - return 0; -} -#endif /* CONFIG_ENCODERS */ - -#ifdef CONFIG_DECODERS -AVCodec huffyuv_decoder = { - "huffyuv", - CODEC_TYPE_VIDEO, - CODEC_ID_HUFFYUV, - sizeof(HYuvContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, - NULL -}; - -AVCodec ffvhuff_decoder = { - "ffvhuff", - CODEC_TYPE_VIDEO, - CODEC_ID_FFVHUFF, - sizeof(HYuvContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, - NULL -}; -#endif - -#ifdef CONFIG_ENCODERS - -AVCodec huffyuv_encoder = { - "huffyuv", - CODEC_TYPE_VIDEO, - CODEC_ID_HUFFYUV, - sizeof(HYuvContext), - encode_init, - encode_frame, - encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV422P, -1}, -}; - -AVCodec ffvhuff_encoder = { - "ffvhuff", - CODEC_TYPE_VIDEO, - CODEC_ID_FFVHUFF, - sizeof(HYuvContext), - encode_init, - encode_frame, - encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, -1}, -}; - -#endif //CONFIG_ENCODERS diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/imgconvert.c --- a/src/ffmpeg/libavcodec/imgconvert.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2735 +0,0 @@ -/* - * Misc image convertion routines - * Copyright (c) 2001, 2002, 2003 Fabrice Bellard. - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file imgconvert.c - * Misc image convertion routines. - */ - -/* TODO: - * - write 'ffimg' program to test all the image related stuff - * - move all api to slice based system - * - integrate deinterlacing, postprocessing and scaling in the conversion process - */ - -#include "avcodec.h" -#include "dsputil.h" - -#ifdef USE_FASTMEMCPY -#include "libvo/fastmemcpy.h" -#endif - -#ifdef HAVE_MMX -#include "i386/mmx.h" -#endif - -#define xglue(x, y) x ## y -#define glue(x, y) xglue(x, y) - -#define FF_COLOR_RGB 0 /* RGB color space */ -#define FF_COLOR_GRAY 1 /* gray color space */ -#define FF_COLOR_YUV 2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ -#define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ - -#define FF_PIXEL_PLANAR 0 /* each channel has one component in AVPicture */ -#define FF_PIXEL_PACKED 1 /* only one components containing all the channels */ -#define FF_PIXEL_PALETTE 2 /* one components containing indexes for a palette */ - -typedef struct PixFmtInfo { - const char *name; - uint8_t nb_channels; /* number of channels (including alpha) */ - uint8_t color_type; /* color type (see FF_COLOR_xxx constants) */ - uint8_t pixel_type; /* pixel storage type (see FF_PIXEL_xxx constants) */ - uint8_t is_alpha : 1; /* true if alpha can be specified */ - uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */ - uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */ - uint8_t depth; /* bit depth of the color components */ -} PixFmtInfo; - -/* this table gives more information about formats */ -static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { - /* YUV formats */ - [PIX_FMT_YUV420P] = { - .name = "yuv420p", - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 1, .y_chroma_shift = 1, - }, - [PIX_FMT_YUV422P] = { - .name = "yuv422p", - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 1, .y_chroma_shift = 0, - }, - [PIX_FMT_YUV444P] = { - .name = "yuv444p", - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_YUV422] = { - .name = "yuv422", - .nb_channels = 1, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 1, .y_chroma_shift = 0, - }, - [PIX_FMT_UYVY422] = { - .name = "uyvy422", - .nb_channels = 1, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 1, .y_chroma_shift = 0, - }, - [PIX_FMT_YUV410P] = { - .name = "yuv410p", - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 2, .y_chroma_shift = 2, - }, - [PIX_FMT_YUV411P] = { - .name = "yuv411p", - .nb_channels = 3, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 2, .y_chroma_shift = 0, - }, - - /* JPEG YUV */ - [PIX_FMT_YUVJ420P] = { - .name = "yuvj420p", - .nb_channels = 3, - .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 1, .y_chroma_shift = 1, - }, - [PIX_FMT_YUVJ422P] = { - .name = "yuvj422p", - .nb_channels = 3, - .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 1, .y_chroma_shift = 0, - }, - [PIX_FMT_YUVJ444P] = { - .name = "yuvj444p", - .nb_channels = 3, - .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - - /* RGB formats */ - [PIX_FMT_RGB24] = { - .name = "rgb24", - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_BGR24] = { - .name = "bgr24", - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_RGBA32] = { - .name = "rgba32", - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_RGB565] = { - .name = "rgb565", - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_RGB555] = { - .name = "rgb555", - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - - /* gray / mono formats */ - [PIX_FMT_GRAY8] = { - .name = "gray", - .nb_channels = 1, - .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - }, - [PIX_FMT_MONOWHITE] = { - .name = "monow", - .nb_channels = 1, - .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 1, - }, - [PIX_FMT_MONOBLACK] = { - .name = "monob", - .nb_channels = 1, - .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 1, - }, - - /* paletted formats */ - [PIX_FMT_PAL8] = { - .name = "pal8", - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PALETTE, - .depth = 8, - }, - [PIX_FMT_XVMC_MPEG2_MC] = { - .name = "xvmcmc", - }, - [PIX_FMT_XVMC_MPEG2_IDCT] = { - .name = "xvmcidct", - }, - [PIX_FMT_UYVY411] = { - .name = "uyvy411", - .nb_channels = 1, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 2, .y_chroma_shift = 0, - }, - [PIX_FMT_BGR32] = { - .name = "bgr32", - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_BGR565] = { - .name = "bgr565", - .nb_channels = 3, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_BGR555] = { - .name = "bgr555", - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_RGB8] = { - .name = "rgb8", - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_RGB4] = { - .name = "rgb4", - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_RGB4_BYTE] = { - .name = "rgb4_byte", - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_BGR8] = { - .name = "bgr8", - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_BGR4] = { - .name = "bgr4", - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_BGR4_BYTE] = { - .name = "bgr4_byte", - .nb_channels = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_NV12] = { - .name = "nv12", - .nb_channels = 2, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 1, .y_chroma_shift = 1, - }, - [PIX_FMT_NV21] = { - .name = "nv12", - .nb_channels = 2, - .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, - .x_chroma_shift = 1, .y_chroma_shift = 1, - }, - - [PIX_FMT_BGR32_1] = { - .name = "bgr32_1", - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, - [PIX_FMT_RGB32_1] = { - .name = "rgb32_1", - .nb_channels = 4, .is_alpha = 1, - .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, - .x_chroma_shift = 0, .y_chroma_shift = 0, - }, -}; - -void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift) -{ - *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift; - *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift; -} - -const char *avcodec_get_pix_fmt_name(int pix_fmt) -{ - if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) - return "???"; - else - return pix_fmt_info[pix_fmt].name; -} - -enum PixelFormat avcodec_get_pix_fmt(const char* name) -{ - int i; - - for (i=0; i < PIX_FMT_NB; i++) - if (!strcmp(pix_fmt_info[i].name, name)) - break; - return i; -} - -/* Picture field are filled with 'ptr' addresses. Also return size */ -int avpicture_fill(AVPicture *picture, uint8_t *ptr, - int pix_fmt, int width, int height) -{ - int size, w2, h2, size2; - const PixFmtInfo *pinfo; - - if(avcodec_check_dimensions(NULL, width, height)) - goto fail; - - pinfo = &pix_fmt_info[pix_fmt]; - size = width * height; - switch(pix_fmt) { - case PIX_FMT_YUV420P: - case PIX_FMT_YUV422P: - case PIX_FMT_YUV444P: - case PIX_FMT_YUV410P: - case PIX_FMT_YUV411P: - case PIX_FMT_YUVJ420P: - case PIX_FMT_YUVJ422P: - case PIX_FMT_YUVJ444P: - w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift; - h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; - size2 = w2 * h2; - picture->data[0] = ptr; - picture->data[1] = picture->data[0] + size; - picture->data[2] = picture->data[1] + size2; - picture->linesize[0] = width; - picture->linesize[1] = w2; - picture->linesize[2] = w2; - return size + 2 * size2; - case PIX_FMT_NV12: - case PIX_FMT_NV21: - w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift; - h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; - size2 = w2 * h2 * 2; - picture->data[0] = ptr; - picture->data[1] = picture->data[0] + size; - picture->data[2] = NULL; - picture->linesize[0] = width; - picture->linesize[1] = w2; - picture->linesize[2] = 0; - return size + 2 * size2; - case PIX_FMT_RGB24: - case PIX_FMT_BGR24: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->linesize[0] = width * 3; - return size * 3; - case PIX_FMT_RGBA32: - case PIX_FMT_BGR32: - case PIX_FMT_RGB32_1: - case PIX_FMT_BGR32_1: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->linesize[0] = width * 4; - return size * 4; - case PIX_FMT_BGR555: - case PIX_FMT_BGR565: - case PIX_FMT_RGB555: - case PIX_FMT_RGB565: - case PIX_FMT_YUV422: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->linesize[0] = width * 2; - return size * 2; - case PIX_FMT_UYVY422: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->linesize[0] = width * 2; - return size * 2; - case PIX_FMT_UYVY411: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->linesize[0] = width + width/2; - return size + size/2; - case PIX_FMT_RGB8: - case PIX_FMT_BGR8: - case PIX_FMT_RGB4_BYTE: - case PIX_FMT_BGR4_BYTE: - case PIX_FMT_GRAY8: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->linesize[0] = width; - return size; - case PIX_FMT_RGB4: - case PIX_FMT_BGR4: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->linesize[0] = width / 2; - return size / 2; - case PIX_FMT_MONOWHITE: - case PIX_FMT_MONOBLACK: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->linesize[0] = (width + 7) >> 3; - return picture->linesize[0] * height; - case PIX_FMT_PAL8: - size2 = (size + 3) & ~3; - picture->data[0] = ptr; - picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */ - picture->data[2] = NULL; - picture->linesize[0] = width; - picture->linesize[1] = 4; - return size2 + 256 * 4; - default: -fail: - picture->data[0] = NULL; - picture->data[1] = NULL; - picture->data[2] = NULL; - picture->data[3] = NULL; - return -1; - } -} - -int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, - unsigned char *dest, int dest_size) -{ - const PixFmtInfo* pf = &pix_fmt_info[pix_fmt]; - int i, j, w, h, data_planes; - const unsigned char* s; - int size = avpicture_get_size(pix_fmt, width, height); - - if (size > dest_size || size < 0) - return -1; - - if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) { - if (pix_fmt == PIX_FMT_YUV422 || - pix_fmt == PIX_FMT_UYVY422 || - pix_fmt == PIX_FMT_BGR565 || - pix_fmt == PIX_FMT_BGR565 || - pix_fmt == PIX_FMT_RGB565 || - pix_fmt == PIX_FMT_RGB555) - w = width * 2; - else if (pix_fmt == PIX_FMT_UYVY411) - w = width + width/2; - else if (pix_fmt == PIX_FMT_PAL8) - w = width; - else - w = width * (pf->depth * pf->nb_channels / 8); - - data_planes = 1; - h = height; - } else { - data_planes = pf->nb_channels; - w = (width*pf->depth + 7)/8; - h = height; - } - - for (i=0; i> pf->x_chroma_shift; - h = height >> pf->y_chroma_shift; - } - s = src->data[i]; - for(j=0; jlinesize[i]; - } - } - - if (pf->pixel_type == FF_PIXEL_PALETTE) - memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4); - - return size; -} - -int avpicture_get_size(int pix_fmt, int width, int height) -{ - AVPicture dummy_pict; - return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); -} - -/** - * compute the loss when converting from a pixel format to another - */ -int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, - int has_alpha) -{ - const PixFmtInfo *pf, *ps; - int loss; - - ps = &pix_fmt_info[src_pix_fmt]; - pf = &pix_fmt_info[dst_pix_fmt]; - - /* compute loss */ - loss = 0; - pf = &pix_fmt_info[dst_pix_fmt]; - if (pf->depth < ps->depth || - (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565)) - loss |= FF_LOSS_DEPTH; - if (pf->x_chroma_shift > ps->x_chroma_shift || - pf->y_chroma_shift > ps->y_chroma_shift) - loss |= FF_LOSS_RESOLUTION; - switch(pf->color_type) { - case FF_COLOR_RGB: - if (ps->color_type != FF_COLOR_RGB && - ps->color_type != FF_COLOR_GRAY) - loss |= FF_LOSS_COLORSPACE; - break; - case FF_COLOR_GRAY: - if (ps->color_type != FF_COLOR_GRAY) - loss |= FF_LOSS_COLORSPACE; - break; - case FF_COLOR_YUV: - if (ps->color_type != FF_COLOR_YUV) - loss |= FF_LOSS_COLORSPACE; - break; - case FF_COLOR_YUV_JPEG: - if (ps->color_type != FF_COLOR_YUV_JPEG && - ps->color_type != FF_COLOR_YUV && - ps->color_type != FF_COLOR_GRAY) - loss |= FF_LOSS_COLORSPACE; - break; - default: - /* fail safe test */ - if (ps->color_type != pf->color_type) - loss |= FF_LOSS_COLORSPACE; - break; - } - if (pf->color_type == FF_COLOR_GRAY && - ps->color_type != FF_COLOR_GRAY) - loss |= FF_LOSS_CHROMA; - if (!pf->is_alpha && (ps->is_alpha && has_alpha)) - loss |= FF_LOSS_ALPHA; - if (pf->pixel_type == FF_PIXEL_PALETTE && - (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY)) - loss |= FF_LOSS_COLORQUANT; - return loss; -} - -static int avg_bits_per_pixel(int pix_fmt) -{ - int bits; - const PixFmtInfo *pf; - - pf = &pix_fmt_info[pix_fmt]; - switch(pf->pixel_type) { - case FF_PIXEL_PACKED: - switch(pix_fmt) { - case PIX_FMT_YUV422: - case PIX_FMT_UYVY422: - case PIX_FMT_RGB565: - case PIX_FMT_RGB555: - case PIX_FMT_BGR565: - case PIX_FMT_BGR555: - bits = 16; - break; - case PIX_FMT_UYVY411: - bits = 12; - break; - default: - bits = pf->depth * pf->nb_channels; - break; - } - break; - case FF_PIXEL_PLANAR: - if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) { - bits = pf->depth * pf->nb_channels; - } else { - bits = pf->depth + ((2 * pf->depth) >> - (pf->x_chroma_shift + pf->y_chroma_shift)); - } - break; - case FF_PIXEL_PALETTE: - bits = 8; - break; - default: - bits = -1; - break; - } - return bits; -} - -static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, - int src_pix_fmt, - int has_alpha, - int loss_mask) -{ - int dist, i, loss, min_dist, dst_pix_fmt; - - /* find exact color match with smallest size */ - dst_pix_fmt = -1; - min_dist = 0x7fffffff; - for(i = 0;i < PIX_FMT_NB; i++) { - if (pix_fmt_mask & (1 << i)) { - loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask; - if (loss == 0) { - dist = avg_bits_per_pixel(i); - if (dist < min_dist) { - min_dist = dist; - dst_pix_fmt = i; - } - } - } - } - return dst_pix_fmt; -} - -/** - * find best pixel format to convert to. Return -1 if none found - */ -int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, - int has_alpha, int *loss_ptr) -{ - int dst_pix_fmt, loss_mask, i; - static const int loss_mask_order[] = { - ~0, /* no loss first */ - ~FF_LOSS_ALPHA, - ~FF_LOSS_RESOLUTION, - ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION), - ~FF_LOSS_COLORQUANT, - ~FF_LOSS_DEPTH, - 0, - }; - - /* try with successive loss */ - i = 0; - for(;;) { - loss_mask = loss_mask_order[i++]; - dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, - has_alpha, loss_mask); - if (dst_pix_fmt >= 0) - goto found; - if (loss_mask == 0) - break; - } - return -1; - found: - if (loss_ptr) - *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); - return dst_pix_fmt; -} - -void ff_img_copy_plane(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - if((!dst) || (!src)) - return; - for(;height > 0; height--) { - memcpy(dst, src, width); - dst += dst_wrap; - src += src_wrap; - } -} - -/** - * Copy image 'src' to 'dst'. - */ -void img_copy(AVPicture *dst, const AVPicture *src, - int pix_fmt, int width, int height) -{ - int bwidth, bits, i; - const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; - - pf = &pix_fmt_info[pix_fmt]; - switch(pf->pixel_type) { - case FF_PIXEL_PACKED: - switch(pix_fmt) { - case PIX_FMT_YUV422: - case PIX_FMT_UYVY422: - case PIX_FMT_RGB565: - case PIX_FMT_RGB555: - case PIX_FMT_BGR565: - case PIX_FMT_BGR555: - bits = 16; - break; - case PIX_FMT_UYVY411: - bits = 12; - break; - default: - bits = pf->depth * pf->nb_channels; - break; - } - bwidth = (width * bits + 7) >> 3; - ff_img_copy_plane(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - bwidth, height); - break; - case FF_PIXEL_PLANAR: - for(i = 0; i < pf->nb_channels; i++) { - int w, h; - w = width; - h = height; - if (i == 1 || i == 2) { - w >>= pf->x_chroma_shift; - h >>= pf->y_chroma_shift; - } - bwidth = (w * pf->depth + 7) >> 3; - ff_img_copy_plane(dst->data[i], dst->linesize[i], - src->data[i], src->linesize[i], - bwidth, h); - } - break; - case FF_PIXEL_PALETTE: - ff_img_copy_plane(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - width, height); - /* copy the palette */ - ff_img_copy_plane(dst->data[1], dst->linesize[1], - src->data[1], src->linesize[1], - 4, 256); - break; - } -} - -/* XXX: totally non optimized */ - -static void yuv422_to_yuv420p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - - for(;height >= 1; height -= 2) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[0]; - cb[0] = p[1]; - lum[1] = p[2]; - cr[0] = p[3]; - p += 4; - lum += 2; - cb++; - cr++; - } - if (w) { - lum[0] = p[0]; - cb[0] = p[1]; - cr[0] = p[3]; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - if (height>1) { - p = p1; - lum = lum1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[0]; - lum[1] = p[2]; - p += 4; - lum += 2; - } - if (w) { - lum[0] = p[0]; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - } - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - -static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - - for(;height >= 1; height -= 2) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[1]; - cb[0] = p[0]; - lum[1] = p[3]; - cr[0] = p[2]; - p += 4; - lum += 2; - cb++; - cr++; - } - if (w) { - lum[0] = p[1]; - cb[0] = p[0]; - cr[0] = p[2]; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - if (height>1) { - p = p1; - lum = lum1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[1]; - lum[1] = p[3]; - p += 4; - lum += 2; - } - if (w) { - lum[0] = p[1]; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - } - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - - -static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[1]; - cb[0] = p[0]; - lum[1] = p[3]; - cr[0] = p[2]; - p += 4; - lum += 2; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - - -static void yuv422_to_yuv422p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - lum[0] = p[0]; - cb[0] = p[1]; - lum[1] = p[2]; - cr[0] = p[3]; - p += 4; - lum += 2; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - -static void yuv422p_to_yuv422(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - uint8_t *p, *p1; - const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = dst->data[0]; - lum1 = src->data[0]; - cb1 = src->data[1]; - cr1 = src->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - p[0] = lum[0]; - p[1] = cb[0]; - p[2] = lum[1]; - p[3] = cr[0]; - p += 4; - lum += 2; - cb++; - cr++; - } - p1 += dst->linesize[0]; - lum1 += src->linesize[0]; - cb1 += src->linesize[1]; - cr1 += src->linesize[2]; - } -} - -static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - uint8_t *p, *p1; - const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = dst->data[0]; - lum1 = src->data[0]; - cb1 = src->data[1]; - cr1 = src->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 2; w -= 2) { - p[1] = lum[0]; - p[0] = cb[0]; - p[3] = lum[1]; - p[2] = cr[0]; - p += 4; - lum += 2; - cb++; - cr++; - } - p1 += dst->linesize[0]; - lum1 += src->linesize[0]; - cb1 += src->linesize[1]; - cr1 += src->linesize[2]; - } -} - -static void uyvy411_to_yuv411p(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - const uint8_t *p, *p1; - uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; - int w; - - p1 = src->data[0]; - lum1 = dst->data[0]; - cb1 = dst->data[1]; - cr1 = dst->data[2]; - for(;height > 0; height--) { - p = p1; - lum = lum1; - cb = cb1; - cr = cr1; - for(w = width; w >= 4; w -= 4) { - cb[0] = p[0]; - lum[0] = p[1]; - lum[1] = p[2]; - cr[0] = p[3]; - lum[2] = p[4]; - lum[3] = p[5]; - p += 6; - lum += 4; - cb++; - cr++; - } - p1 += src->linesize[0]; - lum1 += dst->linesize[0]; - cb1 += dst->linesize[1]; - cr1 += dst->linesize[2]; - } -} - - -static void yuv420p_to_yuv422(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - int w, h; - uint8_t *line1, *line2, *linesrc = dst->data[0]; - uint8_t *lum1, *lum2, *lumsrc = src->data[0]; - uint8_t *cb1, *cb2 = src->data[1]; - uint8_t *cr1, *cr2 = src->data[2]; - - for(h = height / 2; h--;) { - line1 = linesrc; - line2 = linesrc + dst->linesize[0]; - - lum1 = lumsrc; - lum2 = lumsrc + src->linesize[0]; - - cb1 = cb2; - cr1 = cr2; - - for(w = width / 2; w--;) { - *line1++ = *lum1++; *line2++ = *lum2++; - *line1++ = *line2++ = *cb1++; - *line1++ = *lum1++; *line2++ = *lum2++; - *line1++ = *line2++ = *cr1++; - } - - linesrc += dst->linesize[0] * 2; - lumsrc += src->linesize[0] * 2; - cb2 += src->linesize[1]; - cr2 += src->linesize[2]; - } -} - -static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - int w, h; - uint8_t *line1, *line2, *linesrc = dst->data[0]; - uint8_t *lum1, *lum2, *lumsrc = src->data[0]; - uint8_t *cb1, *cb2 = src->data[1]; - uint8_t *cr1, *cr2 = src->data[2]; - - for(h = height / 2; h--;) { - line1 = linesrc; - line2 = linesrc + dst->linesize[0]; - - lum1 = lumsrc; - lum2 = lumsrc + src->linesize[0]; - - cb1 = cb2; - cr1 = cr2; - - for(w = width / 2; w--;) { - *line1++ = *line2++ = *cb1++; - *line1++ = *lum1++; *line2++ = *lum2++; - *line1++ = *line2++ = *cr1++; - *line1++ = *lum1++; *line2++ = *lum2++; - } - - linesrc += dst->linesize[0] * 2; - lumsrc += src->linesize[0] * 2; - cb2 += src->linesize[1]; - cr2 += src->linesize[2]; - } -} - -#define SCALEBITS 10 -#define ONE_HALF (1 << (SCALEBITS - 1)) -#define FIX(x) ((int) ((x) * (1<> SCALEBITS];\ - g = cm[(y + g_add) >> SCALEBITS];\ - b = cm[(y + b_add) >> SCALEBITS];\ -} - -#define YUV_TO_RGB1(cb1, cr1)\ -{\ - cb = (cb1) - 128;\ - cr = (cr1) - 128;\ - r_add = FIX(1.40200) * cr + ONE_HALF;\ - g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\ - b_add = FIX(1.77200) * cb + ONE_HALF;\ -} - -#define YUV_TO_RGB2(r, g, b, y1)\ -{\ - y = (y1) << SCALEBITS;\ - r = cm[(y + r_add) >> SCALEBITS];\ - g = cm[(y + g_add) >> SCALEBITS];\ - b = cm[(y + b_add) >> SCALEBITS];\ -} - -#define Y_CCIR_TO_JPEG(y)\ - cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS] - -#define Y_JPEG_TO_CCIR(y)\ - (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) - -#define C_CCIR_TO_JPEG(y)\ - cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS] - -/* NOTE: the clamp is really necessary! */ -static inline int C_JPEG_TO_CCIR(int y) { - y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS); - if (y < 16) - y = 16; - return y; -} - - -#define RGB_TO_Y(r, g, b) \ -((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \ - FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS) - -#define RGB_TO_U(r1, g1, b1, shift)\ -(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ - FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) - -#define RGB_TO_V(r1, g1, b1, shift)\ -(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ - FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) - -#define RGB_TO_Y_CCIR(r, g, b) \ -((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ - FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) - -#define RGB_TO_U_CCIR(r1, g1, b1, shift)\ -(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ - FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) - -#define RGB_TO_V_CCIR(r1, g1, b1, shift)\ -(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ - FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) - -static uint8_t y_ccir_to_jpeg[256]; -static uint8_t y_jpeg_to_ccir[256]; -static uint8_t c_ccir_to_jpeg[256]; -static uint8_t c_jpeg_to_ccir[256]; - -/* init various conversion tables */ -static void img_convert_init(void) -{ - int i; - uint8_t *cm = cropTbl + MAX_NEG_CROP; - - for(i = 0;i < 256; i++) { - y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i); - y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i); - c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i); - c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i); - } -} - -/* apply to each pixel the given table */ -static void img_apply_table(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height, const uint8_t *table1) -{ - int n; - const uint8_t *s; - uint8_t *d; - const uint8_t *table; - - table = table1; - for(;height > 0; height--) { - s = src; - d = dst; - n = width; - while (n >= 4) { - d[0] = table[s[0]]; - d[1] = table[s[1]]; - d[2] = table[s[2]]; - d[3] = table[s[3]]; - d += 4; - s += 4; - n -= 4; - } - while (n > 0) { - d[0] = table[s[0]]; - d++; - s++; - n--; - } - dst += dst_wrap; - src += src_wrap; - } -} - -/* XXX: use generic filter ? */ -/* XXX: in most cases, the sampling position is incorrect */ - -/* 4x1 -> 1x1 */ -static void shrink41(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w; - const uint8_t *s; - uint8_t *d; - - for(;height > 0; height--) { - s = src; - d = dst; - for(w = width;w > 0; w--) { - d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2; - s += 4; - d++; - } - src += src_wrap; - dst += dst_wrap; - } -} - -/* 2x1 -> 1x1 */ -static void shrink21(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w; - const uint8_t *s; - uint8_t *d; - - for(;height > 0; height--) { - s = src; - d = dst; - for(w = width;w > 0; w--) { - d[0] = (s[0] + s[1]) >> 1; - s += 2; - d++; - } - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x2 -> 1x1 */ -static void shrink12(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w; - uint8_t *d; - const uint8_t *s1, *s2; - - for(;height > 0; height--) { - s1 = src; - s2 = s1 + src_wrap; - d = dst; - for(w = width;w >= 4; w-=4) { - d[0] = (s1[0] + s2[0]) >> 1; - d[1] = (s1[1] + s2[1]) >> 1; - d[2] = (s1[2] + s2[2]) >> 1; - d[3] = (s1[3] + s2[3]) >> 1; - s1 += 4; - s2 += 4; - d += 4; - } - for(;w > 0; w--) { - d[0] = (s1[0] + s2[0]) >> 1; - s1++; - s2++; - d++; - } - src += 2 * src_wrap; - dst += dst_wrap; - } -} - -/* 2x2 -> 1x1 */ -void ff_shrink22(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w; - const uint8_t *s1, *s2; - uint8_t *d; - - for(;height > 0; height--) { - s1 = src; - s2 = s1 + src_wrap; - d = dst; - for(w = width;w >= 4; w-=4) { - d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; - d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2; - d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2; - d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2; - s1 += 8; - s2 += 8; - d += 4; - } - for(;w > 0; w--) { - d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; - s1 += 2; - s2 += 2; - d++; - } - src += 2 * src_wrap; - dst += dst_wrap; - } -} - -/* 4x4 -> 1x1 */ -void ff_shrink44(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w; - const uint8_t *s1, *s2, *s3, *s4; - uint8_t *d; - - for(;height > 0; height--) { - s1 = src; - s2 = s1 + src_wrap; - s3 = s2 + src_wrap; - s4 = s3 + src_wrap; - d = dst; - for(w = width;w > 0; w--) { - d[0] = (s1[0] + s1[1] + s1[2] + s1[3] + - s2[0] + s2[1] + s2[2] + s2[3] + - s3[0] + s3[1] + s3[2] + s3[3] + - s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4; - s1 += 4; - s2 += 4; - s3 += 4; - s4 += 4; - d++; - } - src += 4 * src_wrap; - dst += dst_wrap; - } -} - -/* 8x8 -> 1x1 */ -void ff_shrink88(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w, i; - - for(;height > 0; height--) { - for(w = width;w > 0; w--) { - int tmp=0; - for(i=0; i<8; i++){ - tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7]; - src += src_wrap; - } - *(dst++) = (tmp + 32)>>6; - src += 8 - 8*src_wrap; - } - src += 8*src_wrap - 8*width; - dst += dst_wrap - width; - } -} - -static void grow21_line(uint8_t *dst, const uint8_t *src, - int width) -{ - int w; - const uint8_t *s1; - uint8_t *d; - - s1 = src; - d = dst; - for(w = width;w >= 4; w-=4) { - d[1] = d[0] = s1[0]; - d[3] = d[2] = s1[1]; - s1 += 2; - d += 4; - } - for(;w >= 2; w -= 2) { - d[1] = d[0] = s1[0]; - s1 ++; - d += 2; - } - /* only needed if width is not a multiple of two */ - /* XXX: veryfy that */ - if (w) { - d[0] = s1[0]; - } -} - -static void grow41_line(uint8_t *dst, const uint8_t *src, - int width) -{ - int w, v; - const uint8_t *s1; - uint8_t *d; - - s1 = src; - d = dst; - for(w = width;w >= 4; w-=4) { - v = s1[0]; - d[0] = v; - d[1] = v; - d[2] = v; - d[3] = v; - s1 ++; - d += 4; - } -} - -/* 1x1 -> 2x1 */ -static void grow21(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - for(;height > 0; height--) { - grow21_line(dst, src, width); - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x1 -> 2x2 */ -static void grow22(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - for(;height > 0; height--) { - grow21_line(dst, src, width); - if (height%2) - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x1 -> 4x1 */ -static void grow41(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - for(;height > 0; height--) { - grow41_line(dst, src, width); - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x1 -> 4x4 */ -static void grow44(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - for(;height > 0; height--) { - grow41_line(dst, src, width); - if ((height & 3) == 1) - src += src_wrap; - dst += dst_wrap; - } -} - -/* 1x2 -> 2x1 */ -static void conv411(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height) -{ - int w, c; - const uint8_t *s1, *s2; - uint8_t *d; - - width>>=1; - - for(;height > 0; height--) { - s1 = src; - s2 = src + src_wrap; - d = dst; - for(w = width;w > 0; w--) { - c = (s1[0] + s2[0]) >> 1; - d[0] = c; - d[1] = c; - s1++; - s2++; - d += 2; - } - src += src_wrap * 2; - dst += dst_wrap; - } -} - -/* XXX: add jpeg quantize code */ - -#define TRANSP_INDEX (6*6*6) - -/* this is maybe slow, but allows for extensions */ -static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b) -{ - return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6)); -} - -static void build_rgb_palette(uint8_t *palette, int has_alpha) -{ - uint32_t *pal; - static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff }; - int i, r, g, b; - - pal = (uint32_t *)palette; - i = 0; - for(r = 0; r < 6; r++) { - for(g = 0; g < 6; g++) { - for(b = 0; b < 6; b++) { - pal[i++] = (0xff << 24) | (pal_value[r] << 16) | - (pal_value[g] << 8) | pal_value[b]; - } - } - } - if (has_alpha) - pal[i++] = 0; - while (i < 256) - pal[i++] = 0xff000000; -} - -/* copy bit n to bits 0 ... n - 1 */ -static inline unsigned int bitcopy_n(unsigned int a, int n) -{ - int mask; - mask = (1 << n) - 1; - return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask); -} - -/* rgb555 handling */ - -#define RGB_NAME rgb555 - -#define RGB_IN(r, g, b, s)\ -{\ - unsigned int v = ((const uint16_t *)(s))[0];\ - r = bitcopy_n(v >> (10 - 3), 3);\ - g = bitcopy_n(v >> (5 - 3), 3);\ - b = bitcopy_n(v << 3, 3);\ -} - -#define RGBA_IN(r, g, b, a, s)\ -{\ - unsigned int v = ((const uint16_t *)(s))[0];\ - r = bitcopy_n(v >> (10 - 3), 3);\ - g = bitcopy_n(v >> (5 - 3), 3);\ - b = bitcopy_n(v << 3, 3);\ - a = (-(v >> 15)) & 0xff;\ -} - -#define RGBA_OUT(d, r, g, b, a)\ -{\ - ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \ - ((a << 8) & 0x8000);\ -} - -#define BPP 2 - -#include "imgconvert_template.h" - -/* rgb565 handling */ - -#define RGB_NAME rgb565 - -#define RGB_IN(r, g, b, s)\ -{\ - unsigned int v = ((const uint16_t *)(s))[0];\ - r = bitcopy_n(v >> (11 - 3), 3);\ - g = bitcopy_n(v >> (5 - 2), 2);\ - b = bitcopy_n(v << 3, 3);\ -} - -#define RGB_OUT(d, r, g, b)\ -{\ - ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\ -} - -#define BPP 2 - -#include "imgconvert_template.h" - -/* bgr24 handling */ - -#define RGB_NAME bgr24 - -#define RGB_IN(r, g, b, s)\ -{\ - b = (s)[0];\ - g = (s)[1];\ - r = (s)[2];\ -} - -#define RGB_OUT(d, r, g, b)\ -{\ - (d)[0] = b;\ - (d)[1] = g;\ - (d)[2] = r;\ -} - -#define BPP 3 - -#include "imgconvert_template.h" - -#undef RGB_IN -#undef RGB_OUT -#undef BPP - -/* rgb24 handling */ - -#define RGB_NAME rgb24 -#define FMT_RGB24 - -#define RGB_IN(r, g, b, s)\ -{\ - r = (s)[0];\ - g = (s)[1];\ - b = (s)[2];\ -} - -#define RGB_OUT(d, r, g, b)\ -{\ - (d)[0] = r;\ - (d)[1] = g;\ - (d)[2] = b;\ -} - -#define BPP 3 - -#include "imgconvert_template.h" - -/* rgba32 handling */ - -#define RGB_NAME rgba32 -#define FMT_RGBA32 - -#define RGB_IN(r, g, b, s)\ -{\ - unsigned int v = ((const uint32_t *)(s))[0];\ - r = (v >> 16) & 0xff;\ - g = (v >> 8) & 0xff;\ - b = v & 0xff;\ -} - -#define RGBA_IN(r, g, b, a, s)\ -{\ - unsigned int v = ((const uint32_t *)(s))[0];\ - a = (v >> 24) & 0xff;\ - r = (v >> 16) & 0xff;\ - g = (v >> 8) & 0xff;\ - b = v & 0xff;\ -} - -#define RGBA_OUT(d, r, g, b, a)\ -{\ - ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\ -} - -#define BPP 4 - -#include "imgconvert_template.h" - -static void mono_to_gray(AVPicture *dst, const AVPicture *src, - int width, int height, int xor_mask) -{ - const unsigned char *p; - unsigned char *q; - int v, dst_wrap, src_wrap; - int y, w; - - p = src->data[0]; - src_wrap = src->linesize[0] - ((width + 7) >> 3); - - q = dst->data[0]; - dst_wrap = dst->linesize[0] - width; - for(y=0;y= 8) { - v = *p++ ^ xor_mask; - q[0] = -(v >> 7); - q[1] = -((v >> 6) & 1); - q[2] = -((v >> 5) & 1); - q[3] = -((v >> 4) & 1); - q[4] = -((v >> 3) & 1); - q[5] = -((v >> 2) & 1); - q[6] = -((v >> 1) & 1); - q[7] = -((v >> 0) & 1); - w -= 8; - q += 8; - } - if (w > 0) { - v = *p++ ^ xor_mask; - do { - q[0] = -((v >> 7) & 1); - q++; - v <<= 1; - } while (--w); - } - p += src_wrap; - q += dst_wrap; - } -} - -static void monowhite_to_gray(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - mono_to_gray(dst, src, width, height, 0xff); -} - -static void monoblack_to_gray(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - mono_to_gray(dst, src, width, height, 0x00); -} - -static void gray_to_mono(AVPicture *dst, const AVPicture *src, - int width, int height, int xor_mask) -{ - int n; - const uint8_t *s; - uint8_t *d; - int j, b, v, n1, src_wrap, dst_wrap, y; - - s = src->data[0]; - src_wrap = src->linesize[0] - width; - - d = dst->data[0]; - dst_wrap = dst->linesize[0] - ((width + 7) >> 3); - - for(y=0;y= 8) { - v = 0; - for(j=0;j<8;j++) { - b = s[0]; - s++; - v = (v << 1) | (b >> 7); - } - d[0] = v ^ xor_mask; - d++; - n -= 8; - } - if (n > 0) { - n1 = n; - v = 0; - while (n > 0) { - b = s[0]; - s++; - v = (v << 1) | (b >> 7); - n--; - } - d[0] = (v << (8 - (n1 & 7))) ^ xor_mask; - d++; - } - s += src_wrap; - d += dst_wrap; - } -} - -static void gray_to_monowhite(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - gray_to_mono(dst, src, width, height, 0xff); -} - -static void gray_to_monoblack(AVPicture *dst, const AVPicture *src, - int width, int height) -{ - gray_to_mono(dst, src, width, height, 0x00); -} - -typedef struct ConvertEntry { - void (*convert)(AVPicture *dst, - const AVPicture *src, int width, int height); -} ConvertEntry; - -/* Add each new convertion function in this table. In order to be able - to convert from any format to any format, the following constraints - must be satisfied: - - - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24 - - - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8 - - - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32 - - - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from - PIX_FMT_RGB24. - - - PIX_FMT_422 must convert to and from PIX_FMT_422P. - - The other conversion functions are just optimisations for common cases. -*/ -static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = { - [PIX_FMT_YUV420P] = { - [PIX_FMT_YUV422] = { - .convert = yuv420p_to_yuv422, - }, - [PIX_FMT_RGB555] = { - .convert = yuv420p_to_rgb555 - }, - [PIX_FMT_RGB565] = { - .convert = yuv420p_to_rgb565 - }, - [PIX_FMT_BGR24] = { - .convert = yuv420p_to_bgr24 - }, - [PIX_FMT_RGB24] = { - .convert = yuv420p_to_rgb24 - }, - [PIX_FMT_RGBA32] = { - .convert = yuv420p_to_rgba32 - }, - [PIX_FMT_UYVY422] = { - .convert = yuv420p_to_uyvy422, - }, - }, - [PIX_FMT_YUV422P] = { - [PIX_FMT_YUV422] = { - .convert = yuv422p_to_yuv422, - }, - [PIX_FMT_UYVY422] = { - .convert = yuv422p_to_uyvy422, - }, - }, - [PIX_FMT_YUV444P] = { - [PIX_FMT_RGB24] = { - .convert = yuv444p_to_rgb24 - }, - }, - [PIX_FMT_YUVJ420P] = { - [PIX_FMT_RGB555] = { - .convert = yuvj420p_to_rgb555 - }, - [PIX_FMT_RGB565] = { - .convert = yuvj420p_to_rgb565 - }, - [PIX_FMT_BGR24] = { - .convert = yuvj420p_to_bgr24 - }, - [PIX_FMT_RGB24] = { - .convert = yuvj420p_to_rgb24 - }, - [PIX_FMT_RGBA32] = { - .convert = yuvj420p_to_rgba32 - }, - }, - [PIX_FMT_YUVJ444P] = { - [PIX_FMT_RGB24] = { - .convert = yuvj444p_to_rgb24 - }, - }, - [PIX_FMT_YUV422] = { - [PIX_FMT_YUV420P] = { - .convert = yuv422_to_yuv420p, - }, - [PIX_FMT_YUV422P] = { - .convert = yuv422_to_yuv422p, - }, - }, - [PIX_FMT_UYVY422] = { - [PIX_FMT_YUV420P] = { - .convert = uyvy422_to_yuv420p, - }, - [PIX_FMT_YUV422P] = { - .convert = uyvy422_to_yuv422p, - }, - }, - [PIX_FMT_RGB24] = { - [PIX_FMT_YUV420P] = { - .convert = rgb24_to_yuv420p - }, - [PIX_FMT_RGB565] = { - .convert = rgb24_to_rgb565 - }, - [PIX_FMT_RGB555] = { - .convert = rgb24_to_rgb555 - }, - [PIX_FMT_RGBA32] = { - .convert = rgb24_to_rgba32 - }, - [PIX_FMT_BGR24] = { - .convert = rgb24_to_bgr24 - }, - [PIX_FMT_GRAY8] = { - .convert = rgb24_to_gray - }, - [PIX_FMT_PAL8] = { - .convert = rgb24_to_pal8 - }, - [PIX_FMT_YUV444P] = { - .convert = rgb24_to_yuv444p - }, - [PIX_FMT_YUVJ420P] = { - .convert = rgb24_to_yuvj420p - }, - [PIX_FMT_YUVJ444P] = { - .convert = rgb24_to_yuvj444p - }, - }, - [PIX_FMT_RGBA32] = { - [PIX_FMT_RGB24] = { - .convert = rgba32_to_rgb24 - }, - [PIX_FMT_RGB555] = { - .convert = rgba32_to_rgb555 - }, - [PIX_FMT_PAL8] = { - .convert = rgba32_to_pal8 - }, - [PIX_FMT_YUV420P] = { - .convert = rgba32_to_yuv420p - }, - [PIX_FMT_GRAY8] = { - .convert = rgba32_to_gray - }, - }, - [PIX_FMT_BGR24] = { - [PIX_FMT_RGB24] = { - .convert = bgr24_to_rgb24 - }, - [PIX_FMT_YUV420P] = { - .convert = bgr24_to_yuv420p - }, - [PIX_FMT_GRAY8] = { - .convert = bgr24_to_gray - }, - }, - [PIX_FMT_RGB555] = { - [PIX_FMT_RGB24] = { - .convert = rgb555_to_rgb24 - }, - [PIX_FMT_RGBA32] = { - .convert = rgb555_to_rgba32 - }, - [PIX_FMT_YUV420P] = { - .convert = rgb555_to_yuv420p - }, - [PIX_FMT_GRAY8] = { - .convert = rgb555_to_gray - }, - }, - [PIX_FMT_RGB565] = { - [PIX_FMT_RGB24] = { - .convert = rgb565_to_rgb24 - }, - [PIX_FMT_YUV420P] = { - .convert = rgb565_to_yuv420p - }, - [PIX_FMT_GRAY8] = { - .convert = rgb565_to_gray - }, - }, - [PIX_FMT_GRAY8] = { - [PIX_FMT_RGB555] = { - .convert = gray_to_rgb555 - }, - [PIX_FMT_RGB565] = { - .convert = gray_to_rgb565 - }, - [PIX_FMT_RGB24] = { - .convert = gray_to_rgb24 - }, - [PIX_FMT_BGR24] = { - .convert = gray_to_bgr24 - }, - [PIX_FMT_RGBA32] = { - .convert = gray_to_rgba32 - }, - [PIX_FMT_MONOWHITE] = { - .convert = gray_to_monowhite - }, - [PIX_FMT_MONOBLACK] = { - .convert = gray_to_monoblack - }, - }, - [PIX_FMT_MONOWHITE] = { - [PIX_FMT_GRAY8] = { - .convert = monowhite_to_gray - }, - }, - [PIX_FMT_MONOBLACK] = { - [PIX_FMT_GRAY8] = { - .convert = monoblack_to_gray - }, - }, - [PIX_FMT_PAL8] = { - [PIX_FMT_RGB555] = { - .convert = pal8_to_rgb555 - }, - [PIX_FMT_RGB565] = { - .convert = pal8_to_rgb565 - }, - [PIX_FMT_BGR24] = { - .convert = pal8_to_bgr24 - }, - [PIX_FMT_RGB24] = { - .convert = pal8_to_rgb24 - }, - [PIX_FMT_RGBA32] = { - .convert = pal8_to_rgba32 - }, - }, - [PIX_FMT_UYVY411] = { - [PIX_FMT_YUV411P] = { - .convert = uyvy411_to_yuv411p, - }, - }, - -}; - -int avpicture_alloc(AVPicture *picture, - int pix_fmt, int width, int height) -{ - int size; - void *ptr; - - size = avpicture_get_size(pix_fmt, width, height); - if(size<0) - goto fail; - ptr = av_malloc(size); - if (!ptr) - goto fail; - avpicture_fill(picture, ptr, pix_fmt, width, height); - return 0; - fail: - memset(picture, 0, sizeof(AVPicture)); - return -1; -} - -void avpicture_free(AVPicture *picture) -{ - av_free(picture->data[0]); -} - -/* return true if yuv planar */ -static inline int is_yuv_planar(const PixFmtInfo *ps) -{ - return (ps->color_type == FF_COLOR_YUV || - ps->color_type == FF_COLOR_YUV_JPEG) && - ps->pixel_type == FF_PIXEL_PLANAR; -} - -/** - * Crop image top and left side - */ -int img_crop(AVPicture *dst, const AVPicture *src, - int pix_fmt, int top_band, int left_band) -{ - int y_shift; - int x_shift; - - if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt])) - return -1; - - y_shift = pix_fmt_info[pix_fmt].y_chroma_shift; - x_shift = pix_fmt_info[pix_fmt].x_chroma_shift; - - dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band; - dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift); - dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift); - - dst->linesize[0] = src->linesize[0]; - dst->linesize[1] = src->linesize[1]; - dst->linesize[2] = src->linesize[2]; - return 0; -} - -/** - * Pad image - */ -int img_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, - int padtop, int padbottom, int padleft, int padright, int *color) -{ - uint8_t *optr, *iptr; - int y_shift; - int x_shift; - int yheight; - int i, y; - - if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt])) - return -1; - - for (i = 0; i < 3; i++) { - x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0; - y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0; - - if (padtop || padleft) { - memset(dst->data[i], color[i], dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift)); - } - - if (padleft || padright || src) { - if (src) { /* first line */ - iptr = src->data[i]; - optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift); - memcpy(optr, iptr, src->linesize[i]); - iptr += src->linesize[i]; - } - optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (dst->linesize[i] - (padright >> x_shift)); - yheight = (height - 1 - (padtop + padbottom)) >> y_shift; - for (y = 0; y < yheight; y++) { - memset(optr, color[i], (padleft + padright) >> x_shift); - if (src) { - memcpy(optr + ((padleft + padright) >> x_shift), iptr, src->linesize[i]); - iptr += src->linesize[i]; - } - optr += dst->linesize[i]; - } - } - - if (padbottom || padright) { - optr = dst->data[i] + dst->linesize[i] * ((height - padbottom) >> y_shift) - (padright >> x_shift); - memset(optr, color[i], dst->linesize[i] * (padbottom >> y_shift) + (padright >> x_shift)); - } - } - return 0; -} - -#ifndef CONFIG_SWSCALER -/* XXX: always use linesize. Return -1 if not supported */ -int img_convert(AVPicture *dst, int dst_pix_fmt, - const AVPicture *src, int src_pix_fmt, - int src_width, int src_height) -{ - static int inited; - int i, ret, dst_width, dst_height, int_pix_fmt; - const PixFmtInfo *src_pix, *dst_pix; - const ConvertEntry *ce; - AVPicture tmp1, *tmp = &tmp1; - - if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB || - dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB) - return -1; - if (src_width <= 0 || src_height <= 0) - return 0; - - if (!inited) { - inited = 1; - img_convert_init(); - } - - dst_width = src_width; - dst_height = src_height; - - dst_pix = &pix_fmt_info[dst_pix_fmt]; - src_pix = &pix_fmt_info[src_pix_fmt]; - if (src_pix_fmt == dst_pix_fmt) { - /* no conversion needed: just copy */ - img_copy(dst, src, dst_pix_fmt, dst_width, dst_height); - return 0; - } - - ce = &convert_table[src_pix_fmt][dst_pix_fmt]; - if (ce->convert) { - /* specific conversion routine */ - ce->convert(dst, src, dst_width, dst_height); - return 0; - } - - /* gray to YUV */ - if (is_yuv_planar(dst_pix) && - src_pix_fmt == PIX_FMT_GRAY8) { - int w, h, y; - uint8_t *d; - - if (dst_pix->color_type == FF_COLOR_YUV_JPEG) { - ff_img_copy_plane(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height); - } else { - img_apply_table(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height, - y_jpeg_to_ccir); - } - /* fill U and V with 128 */ - w = dst_width; - h = dst_height; - w >>= dst_pix->x_chroma_shift; - h >>= dst_pix->y_chroma_shift; - for(i = 1; i <= 2; i++) { - d = dst->data[i]; - for(y = 0; y< h; y++) { - memset(d, 128, w); - d += dst->linesize[i]; - } - } - return 0; - } - - /* YUV to gray */ - if (is_yuv_planar(src_pix) && - dst_pix_fmt == PIX_FMT_GRAY8) { - if (src_pix->color_type == FF_COLOR_YUV_JPEG) { - ff_img_copy_plane(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height); - } else { - img_apply_table(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height, - y_ccir_to_jpeg); - } - return 0; - } - - /* YUV to YUV planar */ - if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) { - int x_shift, y_shift, w, h, xy_shift; - void (*resize_func)(uint8_t *dst, int dst_wrap, - const uint8_t *src, int src_wrap, - int width, int height); - - /* compute chroma size of the smallest dimensions */ - w = dst_width; - h = dst_height; - if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift) - w >>= dst_pix->x_chroma_shift; - else - w >>= src_pix->x_chroma_shift; - if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift) - h >>= dst_pix->y_chroma_shift; - else - h >>= src_pix->y_chroma_shift; - - x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift); - y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift); - xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf); - /* there must be filters for conversion at least from and to - YUV444 format */ - switch(xy_shift) { - case 0x00: - resize_func = ff_img_copy_plane; - break; - case 0x10: - resize_func = shrink21; - break; - case 0x20: - resize_func = shrink41; - break; - case 0x01: - resize_func = shrink12; - break; - case 0x11: - resize_func = ff_shrink22; - break; - case 0x22: - resize_func = ff_shrink44; - break; - case 0xf0: - resize_func = grow21; - break; - case 0xe0: - resize_func = grow41; - break; - case 0xff: - resize_func = grow22; - break; - case 0xee: - resize_func = grow44; - break; - case 0xf1: - resize_func = conv411; - break; - default: - /* currently not handled */ - goto no_chroma_filter; - } - - ff_img_copy_plane(dst->data[0], dst->linesize[0], - src->data[0], src->linesize[0], - dst_width, dst_height); - - for(i = 1;i <= 2; i++) - resize_func(dst->data[i], dst->linesize[i], - src->data[i], src->linesize[i], - dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift); - /* if yuv color space conversion is needed, we do it here on - the destination image */ - if (dst_pix->color_type != src_pix->color_type) { - const uint8_t *y_table, *c_table; - if (dst_pix->color_type == FF_COLOR_YUV) { - y_table = y_jpeg_to_ccir; - c_table = c_jpeg_to_ccir; - } else { - y_table = y_ccir_to_jpeg; - c_table = c_ccir_to_jpeg; - } - img_apply_table(dst->data[0], dst->linesize[0], - dst->data[0], dst->linesize[0], - dst_width, dst_height, - y_table); - - for(i = 1;i <= 2; i++) - img_apply_table(dst->data[i], dst->linesize[i], - dst->data[i], dst->linesize[i], - dst_width>>dst_pix->x_chroma_shift, - dst_height>>dst_pix->y_chroma_shift, - c_table); - } - return 0; - } - no_chroma_filter: - - /* try to use an intermediate format */ - if (src_pix_fmt == PIX_FMT_YUV422 || - dst_pix_fmt == PIX_FMT_YUV422) { - /* specific case: convert to YUV422P first */ - int_pix_fmt = PIX_FMT_YUV422P; - } else if (src_pix_fmt == PIX_FMT_UYVY422 || - dst_pix_fmt == PIX_FMT_UYVY422) { - /* specific case: convert to YUV422P first */ - int_pix_fmt = PIX_FMT_YUV422P; - } else if (src_pix_fmt == PIX_FMT_UYVY411 || - dst_pix_fmt == PIX_FMT_UYVY411) { - /* specific case: convert to YUV411P first */ - int_pix_fmt = PIX_FMT_YUV411P; - } else if ((src_pix->color_type == FF_COLOR_GRAY && - src_pix_fmt != PIX_FMT_GRAY8) || - (dst_pix->color_type == FF_COLOR_GRAY && - dst_pix_fmt != PIX_FMT_GRAY8)) { - /* gray8 is the normalized format */ - int_pix_fmt = PIX_FMT_GRAY8; - } else if ((is_yuv_planar(src_pix) && - src_pix_fmt != PIX_FMT_YUV444P && - src_pix_fmt != PIX_FMT_YUVJ444P)) { - /* yuv444 is the normalized format */ - if (src_pix->color_type == FF_COLOR_YUV_JPEG) - int_pix_fmt = PIX_FMT_YUVJ444P; - else - int_pix_fmt = PIX_FMT_YUV444P; - } else if ((is_yuv_planar(dst_pix) && - dst_pix_fmt != PIX_FMT_YUV444P && - dst_pix_fmt != PIX_FMT_YUVJ444P)) { - /* yuv444 is the normalized format */ - if (dst_pix->color_type == FF_COLOR_YUV_JPEG) - int_pix_fmt = PIX_FMT_YUVJ444P; - else - int_pix_fmt = PIX_FMT_YUV444P; - } else { - /* the two formats are rgb or gray8 or yuv[j]444p */ - if (src_pix->is_alpha && dst_pix->is_alpha) - int_pix_fmt = PIX_FMT_RGBA32; - else - int_pix_fmt = PIX_FMT_RGB24; - } - if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0) - return -1; - ret = -1; - if (img_convert(tmp, int_pix_fmt, - src, src_pix_fmt, src_width, src_height) < 0) - goto fail1; - if (img_convert(dst, dst_pix_fmt, - tmp, int_pix_fmt, dst_width, dst_height) < 0) - goto fail1; - ret = 0; - fail1: - avpicture_free(tmp); - return ret; -} -#endif - -/* NOTE: we scan all the pixels to have an exact information */ -static int get_alpha_info_pal8(const AVPicture *src, int width, int height) -{ - const unsigned char *p; - int src_wrap, ret, x, y; - unsigned int a; - uint32_t *palette = (uint32_t *)src->data[1]; - - p = src->data[0]; - src_wrap = src->linesize[0] - width; - ret = 0; - for(y=0;y> 24; - if (a == 0x00) { - ret |= FF_ALPHA_TRANSP; - } else if (a != 0xff) { - ret |= FF_ALPHA_SEMI_TRANSP; - } - p++; - } - p += src_wrap; - } - return ret; -} - -/** - * Tell if an image really has transparent alpha values. - * @return ored mask of FF_ALPHA_xxx constants - */ -int img_get_alpha_info(const AVPicture *src, - int pix_fmt, int width, int height) -{ - const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; - int ret; - - pf = &pix_fmt_info[pix_fmt]; - /* no alpha can be represented in format */ - if (!pf->is_alpha) - return 0; - switch(pix_fmt) { - case PIX_FMT_RGBA32: - ret = get_alpha_info_rgba32(src, width, height); - break; - case PIX_FMT_RGB555: - ret = get_alpha_info_rgb555(src, width, height); - break; - case PIX_FMT_PAL8: - ret = get_alpha_info_pal8(src, width, height); - break; - default: - /* we do not know, so everything is indicated */ - ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP; - break; - } - return ret; -} - -#ifdef HAVE_MMX -#define DEINT_INPLACE_LINE_LUM \ - movd_m2r(lum_m4[0],mm0);\ - movd_m2r(lum_m3[0],mm1);\ - movd_m2r(lum_m2[0],mm2);\ - movd_m2r(lum_m1[0],mm3);\ - movd_m2r(lum[0],mm4);\ - punpcklbw_r2r(mm7,mm0);\ - movd_r2m(mm2,lum_m4[0]);\ - punpcklbw_r2r(mm7,mm1);\ - punpcklbw_r2r(mm7,mm2);\ - punpcklbw_r2r(mm7,mm3);\ - punpcklbw_r2r(mm7,mm4);\ - paddw_r2r(mm3,mm1);\ - psllw_i2r(1,mm2);\ - paddw_r2r(mm4,mm0);\ - psllw_i2r(2,mm1);\ - paddw_r2r(mm6,mm2);\ - paddw_r2r(mm2,mm1);\ - psubusw_r2r(mm0,mm1);\ - psrlw_i2r(3,mm1);\ - packuswb_r2r(mm7,mm1);\ - movd_r2m(mm1,lum_m2[0]); - -#define DEINT_LINE_LUM \ - movd_m2r(lum_m4[0],mm0);\ - movd_m2r(lum_m3[0],mm1);\ - movd_m2r(lum_m2[0],mm2);\ - movd_m2r(lum_m1[0],mm3);\ - movd_m2r(lum[0],mm4);\ - punpcklbw_r2r(mm7,mm0);\ - punpcklbw_r2r(mm7,mm1);\ - punpcklbw_r2r(mm7,mm2);\ - punpcklbw_r2r(mm7,mm3);\ - punpcklbw_r2r(mm7,mm4);\ - paddw_r2r(mm3,mm1);\ - psllw_i2r(1,mm2);\ - paddw_r2r(mm4,mm0);\ - psllw_i2r(2,mm1);\ - paddw_r2r(mm6,mm2);\ - paddw_r2r(mm2,mm1);\ - psubusw_r2r(mm0,mm1);\ - psrlw_i2r(3,mm1);\ - packuswb_r2r(mm7,mm1);\ - movd_r2m(mm1,dst[0]); -#endif - -/* filter parameters: [-1 4 2 4 -1] // 8 */ -static void deinterlace_line(uint8_t *dst, - const uint8_t *lum_m4, const uint8_t *lum_m3, - const uint8_t *lum_m2, const uint8_t *lum_m1, - const uint8_t *lum, - int size) -{ -#ifndef HAVE_MMX - uint8_t *cm = cropTbl + MAX_NEG_CROP; - int sum; - - for(;size > 0;size--) { - sum = -lum_m4[0]; - sum += lum_m3[0] << 2; - sum += lum_m2[0] << 1; - sum += lum_m1[0] << 2; - sum += -lum[0]; - dst[0] = cm[(sum + 4) >> 3]; - lum_m4++; - lum_m3++; - lum_m2++; - lum_m1++; - lum++; - dst++; - } -#else - - { - mmx_t rounder; - rounder.uw[0]=4; - rounder.uw[1]=4; - rounder.uw[2]=4; - rounder.uw[3]=4; - pxor_r2r(mm7,mm7); - movq_m2r(rounder,mm6); - } - for (;size > 3; size-=4) { - DEINT_LINE_LUM - lum_m4+=4; - lum_m3+=4; - lum_m2+=4; - lum_m1+=4; - lum+=4; - dst+=4; - } -#endif -} -static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, - int size) -{ -#ifndef HAVE_MMX - uint8_t *cm = cropTbl + MAX_NEG_CROP; - int sum; - - for(;size > 0;size--) { - sum = -lum_m4[0]; - sum += lum_m3[0] << 2; - sum += lum_m2[0] << 1; - lum_m4[0]=lum_m2[0]; - sum += lum_m1[0] << 2; - sum += -lum[0]; - lum_m2[0] = cm[(sum + 4) >> 3]; - lum_m4++; - lum_m3++; - lum_m2++; - lum_m1++; - lum++; - } -#else - - { - mmx_t rounder; - rounder.uw[0]=4; - rounder.uw[1]=4; - rounder.uw[2]=4; - rounder.uw[3]=4; - pxor_r2r(mm7,mm7); - movq_m2r(rounder,mm6); - } - for (;size > 3; size-=4) { - DEINT_INPLACE_LINE_LUM - lum_m4+=4; - lum_m3+=4; - lum_m2+=4; - lum_m1+=4; - lum+=4; - } -#endif -} - -/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The - top field is copied as is, but the bottom field is deinterlaced - against the top field. */ -static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap, - const uint8_t *src1, int src_wrap, - int width, int height) -{ - const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2; - int y; - - src_m2 = src1; - src_m1 = src1; - src_0=&src_m1[src_wrap]; - src_p1=&src_0[src_wrap]; - src_p2=&src_p1[src_wrap]; - for(y=0;y<(height-2);y+=2) { - memcpy(dst,src_m1,width); - dst += dst_wrap; - deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width); - src_m2 = src_0; - src_m1 = src_p1; - src_0 = src_p2; - src_p1 += 2*src_wrap; - src_p2 += 2*src_wrap; - dst += dst_wrap; - } - memcpy(dst,src_m1,width); - dst += dst_wrap; - /* do last line */ - deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width); -} - -static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, - int width, int height) -{ - uint8_t *src_m1, *src_0, *src_p1, *src_p2; - int y; - uint8_t *buf; - buf = (uint8_t*)av_malloc(width); - - src_m1 = src1; - memcpy(buf,src_m1,width); - src_0=&src_m1[src_wrap]; - src_p1=&src_0[src_wrap]; - src_p2=&src_p1[src_wrap]; - for(y=0;y<(height-2);y+=2) { - deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width); - src_m1 = src_p1; - src_0 = src_p2; - src_p1 += 2*src_wrap; - src_p2 += 2*src_wrap; - } - /* do last line */ - deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width); - av_free(buf); -} - - -/* deinterlace - if not supported return -1 */ -int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, - int pix_fmt, int width, int height) -{ - int i; - - if (pix_fmt != PIX_FMT_YUV420P && - pix_fmt != PIX_FMT_YUV422P && - pix_fmt != PIX_FMT_YUV444P && - pix_fmt != PIX_FMT_YUV411P) - return -1; - if ((width & 3) != 0 || (height & 3) != 0) - return -1; - - for(i=0;i<3;i++) { - if (i == 1) { - switch(pix_fmt) { - case PIX_FMT_YUV420P: - width >>= 1; - height >>= 1; - break; - case PIX_FMT_YUV422P: - width >>= 1; - break; - case PIX_FMT_YUV411P: - width >>= 2; - break; - default: - break; - } - } - if (src == dst) { - deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], - width, height); - } else { - deinterlace_bottom_field(dst->data[i],dst->linesize[i], - src->data[i], src->linesize[i], - width, height); - } - } -#ifdef HAVE_MMX - emms(); -#endif - return 0; -} - -#undef FIX diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/imgresample.c --- a/src/ffmpeg/libavcodec/imgresample.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,942 +0,0 @@ -/* - * High quality image resampling with polyphase filters - * Copyright (c) 2001 Fabrice Bellard. - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file imgresample.c - * High quality image resampling with polyphase filters . - */ - -#include "avcodec.h" -#include "swscale.h" -#include "dsputil.h" - -#ifdef USE_FASTMEMCPY -#include "libvo/fastmemcpy.h" -#endif - -#define NB_COMPONENTS 3 - -#define PHASE_BITS 4 -#define NB_PHASES (1 << PHASE_BITS) -#define NB_TAPS 4 -#define FCENTER 1 /* index of the center of the filter */ -//#define TEST 1 /* Test it */ - -#define POS_FRAC_BITS 16 -#define POS_FRAC (1 << POS_FRAC_BITS) -/* 6 bits precision is needed for MMX */ -#define FILTER_BITS 8 - -#define LINE_BUF_HEIGHT (NB_TAPS * 4) - -struct ImgReSampleContext { - int iwidth, iheight, owidth, oheight; - int topBand, bottomBand, leftBand, rightBand; - int padtop, padbottom, padleft, padright; - int pad_owidth, pad_oheight; - int h_incr, v_incr; - DECLARE_ALIGNED_8(int16_t, h_filters[NB_PHASES][NB_TAPS]); /* horizontal filters */ - DECLARE_ALIGNED_8(int16_t, v_filters[NB_PHASES][NB_TAPS]); /* vertical filters */ - uint8_t *line_buf; -}; - -void av_build_filter(int16_t *filter, double factor, int tap_count, int phase_count, int scale, int type); - -static inline int get_phase(int pos) -{ - return ((pos) >> (POS_FRAC_BITS - PHASE_BITS)) & ((1 << PHASE_BITS) - 1); -} - -/* This function must be optimized */ -static void h_resample_fast(uint8_t *dst, int dst_width, const uint8_t *src, - int src_width, int src_start, int src_incr, - int16_t *filters) -{ - int src_pos, phase, sum, i; - const uint8_t *s; - int16_t *filter; - - src_pos = src_start; - for(i=0;i> POS_FRAC_BITS) < 0 || - (src_pos >> POS_FRAC_BITS) > (src_width - NB_TAPS)) - av_abort(); -#endif - s = src + (src_pos >> POS_FRAC_BITS); - phase = get_phase(src_pos); - filter = filters + phase * NB_TAPS; -#if NB_TAPS == 4 - sum = s[0] * filter[0] + - s[1] * filter[1] + - s[2] * filter[2] + - s[3] * filter[3]; -#else - { - int j; - sum = 0; - for(j=0;j> FILTER_BITS; - if (sum < 0) - sum = 0; - else if (sum > 255) - sum = 255; - dst[0] = sum; - src_pos += src_incr; - dst++; - } -} - -/* This function must be optimized */ -static void v_resample(uint8_t *dst, int dst_width, const uint8_t *src, - int wrap, int16_t *filter) -{ - int sum, i; - const uint8_t *s; - - s = src; - for(i=0;i> FILTER_BITS; - if (sum < 0) - sum = 0; - else if (sum > 255) - sum = 255; - dst[0] = sum; - dst++; - s++; - } -} - -#ifdef HAVE_MMX - -#include "i386/mmx.h" - -#define FILTER4(reg) \ -{\ - s = src + (src_pos >> POS_FRAC_BITS);\ - phase = get_phase(src_pos);\ - filter = filters + phase * NB_TAPS;\ - movq_m2r(*s, reg);\ - punpcklbw_r2r(mm7, reg);\ - movq_m2r(*filter, mm6);\ - pmaddwd_r2r(reg, mm6);\ - movq_r2r(mm6, reg);\ - psrlq_i2r(32, reg);\ - paddd_r2r(mm6, reg);\ - psrad_i2r(FILTER_BITS, reg);\ - src_pos += src_incr;\ -} - -#define DUMP(reg) movq_r2m(reg, tmp); printf(#reg "=%016Lx\n", tmp.uq); - -/* XXX: do four pixels at a time */ -static void h_resample_fast4_mmx(uint8_t *dst, int dst_width, - const uint8_t *src, int src_width, - int src_start, int src_incr, int16_t *filters) -{ - int src_pos, phase; - const uint8_t *s; - int16_t *filter; - mmx_t tmp; - - src_pos = src_start; - pxor_r2r(mm7, mm7); - - while (dst_width >= 4) { - - FILTER4(mm0); - FILTER4(mm1); - FILTER4(mm2); - FILTER4(mm3); - - packuswb_r2r(mm7, mm0); - packuswb_r2r(mm7, mm1); - packuswb_r2r(mm7, mm3); - packuswb_r2r(mm7, mm2); - movq_r2m(mm0, tmp); - dst[0] = tmp.ub[0]; - movq_r2m(mm1, tmp); - dst[1] = tmp.ub[0]; - movq_r2m(mm2, tmp); - dst[2] = tmp.ub[0]; - movq_r2m(mm3, tmp); - dst[3] = tmp.ub[0]; - dst += 4; - dst_width -= 4; - } - while (dst_width > 0) { - FILTER4(mm0); - packuswb_r2r(mm7, mm0); - movq_r2m(mm0, tmp); - dst[0] = tmp.ub[0]; - dst++; - dst_width--; - } - emms(); -} - -static void v_resample4_mmx(uint8_t *dst, int dst_width, const uint8_t *src, - int wrap, int16_t *filter) -{ - int sum, i, v; - const uint8_t *s; - mmx_t tmp; - mmx_t coefs[4]; - - for(i=0;i<4;i++) { - v = filter[i]; - coefs[i].uw[0] = v; - coefs[i].uw[1] = v; - coefs[i].uw[2] = v; - coefs[i].uw[3] = v; - } - - pxor_r2r(mm7, mm7); - s = src; - while (dst_width >= 4) { - movq_m2r(s[0 * wrap], mm0); - punpcklbw_r2r(mm7, mm0); - movq_m2r(s[1 * wrap], mm1); - punpcklbw_r2r(mm7, mm1); - movq_m2r(s[2 * wrap], mm2); - punpcklbw_r2r(mm7, mm2); - movq_m2r(s[3 * wrap], mm3); - punpcklbw_r2r(mm7, mm3); - - pmullw_m2r(coefs[0], mm0); - pmullw_m2r(coefs[1], mm1); - pmullw_m2r(coefs[2], mm2); - pmullw_m2r(coefs[3], mm3); - - paddw_r2r(mm1, mm0); - paddw_r2r(mm3, mm2); - paddw_r2r(mm2, mm0); - psraw_i2r(FILTER_BITS, mm0); - - packuswb_r2r(mm7, mm0); - movq_r2m(mm0, tmp); - - *(uint32_t *)dst = tmp.ud[0]; - dst += 4; - s += 4; - dst_width -= 4; - } - while (dst_width > 0) { - sum = s[0 * wrap] * filter[0] + - s[1 * wrap] * filter[1] + - s[2 * wrap] * filter[2] + - s[3 * wrap] * filter[3]; - sum = sum >> FILTER_BITS; - if (sum < 0) - sum = 0; - else if (sum > 255) - sum = 255; - dst[0] = sum; - dst++; - s++; - dst_width--; - } - emms(); -} -#endif - -#ifdef HAVE_ALTIVEC -typedef union { - vector unsigned char v; - unsigned char c[16]; -} vec_uc_t; - -typedef union { - vector signed short v; - signed short s[8]; -} vec_ss_t; - -void v_resample16_altivec(uint8_t *dst, int dst_width, const uint8_t *src, - int wrap, int16_t *filter) -{ - int sum, i; - const uint8_t *s; - vector unsigned char *tv, tmp, dstv, zero; - vec_ss_t srchv[4], srclv[4], fv[4]; - vector signed short zeros, sumhv, sumlv; - s = src; - - for(i=0;i<4;i++) - { - /* - The vec_madds later on does an implicit >>15 on the result. - Since FILTER_BITS is 8, and we have 15 bits of magnitude in - a signed short, we have just enough bits to pre-shift our - filter constants <<7 to compensate for vec_madds. - */ - fv[i].s[0] = filter[i] << (15-FILTER_BITS); - fv[i].v = vec_splat(fv[i].v, 0); - } - - zero = vec_splat_u8(0); - zeros = vec_splat_s16(0); - - - /* - When we're resampling, we'd ideally like both our input buffers, - and output buffers to be 16-byte aligned, so we can do both aligned - reads and writes. Sadly we can't always have this at the moment, so - we opt for aligned writes, as unaligned writes have a huge overhead. - To do this, do enough scalar resamples to get dst 16-byte aligned. - */ - i = (-(int)dst) & 0xf; - while(i>0) { - sum = s[0 * wrap] * filter[0] + - s[1 * wrap] * filter[1] + - s[2 * wrap] * filter[2] + - s[3 * wrap] * filter[3]; - sum = sum >> FILTER_BITS; - if (sum<0) sum = 0; else if (sum>255) sum=255; - dst[0] = sum; - dst++; - s++; - dst_width--; - i--; - } - - /* Do our altivec resampling on 16 pixels at once. */ - while(dst_width>=16) { - /* - Read 16 (potentially unaligned) bytes from each of - 4 lines into 4 vectors, and split them into shorts. - Interleave the multipy/accumulate for the resample - filter with the loads to hide the 3 cycle latency - the vec_madds have. - */ - tv = (vector unsigned char *) &s[0 * wrap]; - tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[i * wrap])); - srchv[0].v = (vector signed short) vec_mergeh(zero, tmp); - srclv[0].v = (vector signed short) vec_mergel(zero, tmp); - sumhv = vec_madds(srchv[0].v, fv[0].v, zeros); - sumlv = vec_madds(srclv[0].v, fv[0].v, zeros); - - tv = (vector unsigned char *) &s[1 * wrap]; - tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[1 * wrap])); - srchv[1].v = (vector signed short) vec_mergeh(zero, tmp); - srclv[1].v = (vector signed short) vec_mergel(zero, tmp); - sumhv = vec_madds(srchv[1].v, fv[1].v, sumhv); - sumlv = vec_madds(srclv[1].v, fv[1].v, sumlv); - - tv = (vector unsigned char *) &s[2 * wrap]; - tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[2 * wrap])); - srchv[2].v = (vector signed short) vec_mergeh(zero, tmp); - srclv[2].v = (vector signed short) vec_mergel(zero, tmp); - sumhv = vec_madds(srchv[2].v, fv[2].v, sumhv); - sumlv = vec_madds(srclv[2].v, fv[2].v, sumlv); - - tv = (vector unsigned char *) &s[3 * wrap]; - tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[3 * wrap])); - srchv[3].v = (vector signed short) vec_mergeh(zero, tmp); - srclv[3].v = (vector signed short) vec_mergel(zero, tmp); - sumhv = vec_madds(srchv[3].v, fv[3].v, sumhv); - sumlv = vec_madds(srclv[3].v, fv[3].v, sumlv); - - /* - Pack the results into our destination vector, - and do an aligned write of that back to memory. - */ - dstv = vec_packsu(sumhv, sumlv) ; - vec_st(dstv, 0, (vector unsigned char *) dst); - - dst+=16; - s+=16; - dst_width-=16; - } - - /* - If there are any leftover pixels, resample them - with the slow scalar method. - */ - while(dst_width>0) { - sum = s[0 * wrap] * filter[0] + - s[1 * wrap] * filter[1] + - s[2 * wrap] * filter[2] + - s[3 * wrap] * filter[3]; - sum = sum >> FILTER_BITS; - if (sum<0) sum = 0; else if (sum>255) sum=255; - dst[0] = sum; - dst++; - s++; - dst_width--; - } -} -#endif - -/* slow version to handle limit cases. Does not need optimisation */ -static void h_resample_slow(uint8_t *dst, int dst_width, - const uint8_t *src, int src_width, - int src_start, int src_incr, int16_t *filters) -{ - int src_pos, phase, sum, j, v, i; - const uint8_t *s, *src_end; - int16_t *filter; - - src_end = src + src_width; - src_pos = src_start; - for(i=0;i> POS_FRAC_BITS); - phase = get_phase(src_pos); - filter = filters + phase * NB_TAPS; - sum = 0; - for(j=0;j= src_end) - v = src_end[-1]; - else - v = s[0]; - sum += v * filter[j]; - s++; - } - sum = sum >> FILTER_BITS; - if (sum < 0) - sum = 0; - else if (sum > 255) - sum = 255; - dst[0] = sum; - src_pos += src_incr; - dst++; - } -} - -static void h_resample(uint8_t *dst, int dst_width, const uint8_t *src, - int src_width, int src_start, int src_incr, - int16_t *filters) -{ - int n, src_end; - - if (src_start < 0) { - n = (0 - src_start + src_incr - 1) / src_incr; - h_resample_slow(dst, n, src, src_width, src_start, src_incr, filters); - dst += n; - dst_width -= n; - src_start += n * src_incr; - } - src_end = src_start + dst_width * src_incr; - if (src_end > ((src_width - NB_TAPS) << POS_FRAC_BITS)) { - n = (((src_width - NB_TAPS + 1) << POS_FRAC_BITS) - 1 - src_start) / - src_incr; - } else { - n = dst_width; - } -#ifdef HAVE_MMX - if ((mm_flags & MM_MMX) && NB_TAPS == 4) - h_resample_fast4_mmx(dst, n, - src, src_width, src_start, src_incr, filters); - else -#endif - h_resample_fast(dst, n, - src, src_width, src_start, src_incr, filters); - if (n < dst_width) { - dst += n; - dst_width -= n; - src_start += n * src_incr; - h_resample_slow(dst, dst_width, - src, src_width, src_start, src_incr, filters); - } -} - -static void component_resample(ImgReSampleContext *s, - uint8_t *output, int owrap, int owidth, int oheight, - uint8_t *input, int iwrap, int iwidth, int iheight) -{ - int src_y, src_y1, last_src_y, ring_y, phase_y, y1, y; - uint8_t *new_line, *src_line; - - last_src_y = - FCENTER - 1; - /* position of the bottom of the filter in the source image */ - src_y = (last_src_y + NB_TAPS) * POS_FRAC; - ring_y = NB_TAPS; /* position in ring buffer */ - for(y=0;y> POS_FRAC_BITS; - while (last_src_y < src_y1) { - if (++ring_y >= LINE_BUF_HEIGHT + NB_TAPS) - ring_y = NB_TAPS; - last_src_y++; - /* handle limit conditions : replicate line (slightly - inefficient because we filter multiple times) */ - y1 = last_src_y; - if (y1 < 0) { - y1 = 0; - } else if (y1 >= iheight) { - y1 = iheight - 1; - } - src_line = input + y1 * iwrap; - new_line = s->line_buf + ring_y * owidth; - /* apply filter and handle limit cases correctly */ - h_resample(new_line, owidth, - src_line, iwidth, - FCENTER * POS_FRAC, s->h_incr, - &s->h_filters[0][0]); - /* handle ring buffer wraping */ - if (ring_y >= LINE_BUF_HEIGHT) { - memcpy(s->line_buf + (ring_y - LINE_BUF_HEIGHT) * owidth, - new_line, owidth); - } - } - /* apply vertical filter */ - phase_y = get_phase(src_y); -#ifdef HAVE_MMX - /* desactivated MMX because loss of precision */ - if ((mm_flags & MM_MMX) && NB_TAPS == 4 && 0) - v_resample4_mmx(output, owidth, - s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth, - &s->v_filters[phase_y][0]); - else -#endif -#ifdef HAVE_ALTIVEC - if ((mm_flags & MM_ALTIVEC) && NB_TAPS == 4 && FILTER_BITS <= 6) - v_resample16_altivec(output, owidth, - s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth, - &s->v_filters[phase_y][0]); - else -#endif - v_resample(output, owidth, - s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth, - &s->v_filters[phase_y][0]); - - src_y += s->v_incr; - - output += owrap; - } -} - -ImgReSampleContext *img_resample_init(int owidth, int oheight, - int iwidth, int iheight) -{ - return img_resample_full_init(owidth, oheight, iwidth, iheight, - 0, 0, 0, 0, 0, 0, 0, 0); -} - -ImgReSampleContext *img_resample_full_init(int owidth, int oheight, - int iwidth, int iheight, - int topBand, int bottomBand, - int leftBand, int rightBand, - int padtop, int padbottom, - int padleft, int padright) -{ - ImgReSampleContext *s; - - if (!owidth || !oheight || !iwidth || !iheight) - return NULL; - - s = av_mallocz(sizeof(ImgReSampleContext)); - if (!s) - return NULL; - if((unsigned)owidth >= UINT_MAX / (LINE_BUF_HEIGHT + NB_TAPS)) - return NULL; - s->line_buf = av_mallocz(owidth * (LINE_BUF_HEIGHT + NB_TAPS)); - if (!s->line_buf) - goto fail; - - s->owidth = owidth; - s->oheight = oheight; - s->iwidth = iwidth; - s->iheight = iheight; - - s->topBand = topBand; - s->bottomBand = bottomBand; - s->leftBand = leftBand; - s->rightBand = rightBand; - - s->padtop = padtop; - s->padbottom = padbottom; - s->padleft = padleft; - s->padright = padright; - - s->pad_owidth = owidth - (padleft + padright); - s->pad_oheight = oheight - (padtop + padbottom); - - s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / s->pad_owidth; - s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / s->pad_oheight; - - av_build_filter(&s->h_filters[0][0], (float) s->pad_owidth / - (float) (iwidth - leftBand - rightBand), NB_TAPS, NB_PHASES, 1<v_filters[0][0], (float) s->pad_oheight / - (float) (iheight - topBand - bottomBand), NB_TAPS, NB_PHASES, 1<data[i] + (((output->linesize[i] * - s->padtop) + s->padleft) >> shift); - - component_resample(s, optr, output->linesize[i], - s->pad_owidth >> shift, s->pad_oheight >> shift, - input->data[i] + (input->linesize[i] * - (s->topBand >> shift)) + (s->leftBand >> shift), - input->linesize[i], ((s->iwidth - s->leftBand - - s->rightBand) >> shift), - (s->iheight - s->topBand - s->bottomBand) >> shift); - } -} - -void img_resample_close(ImgReSampleContext *s) -{ - av_free(s->line_buf); - av_free(s); -} - -struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, - int dstW, int dstH, int dstFormat, - int flags, SwsFilter *srcFilter, - SwsFilter *dstFilter, double *param) -{ - struct SwsContext *ctx; - - ctx = av_malloc(sizeof(struct SwsContext)); - if (ctx == NULL) { - av_log(NULL, AV_LOG_ERROR, "Cannot allocate a resampling context!\n"); - - return NULL; - } - - if ((srcH != dstH) || (srcW != dstW)) { - if ((srcFormat != PIX_FMT_YUV420P) || (dstFormat != PIX_FMT_YUV420P)) { - av_log(NULL, AV_LOG_INFO, "PIX_FMT_YUV420P will be used as an intermediate format for rescaling\n"); - } - ctx->resampling_ctx = img_resample_init(dstW, dstH, srcW, srcH); - } else { - ctx->resampling_ctx = av_malloc(sizeof(ImgReSampleContext)); - ctx->resampling_ctx->iheight = srcH; - ctx->resampling_ctx->iwidth = srcW; - ctx->resampling_ctx->oheight = dstH; - ctx->resampling_ctx->owidth = dstW; - } - ctx->src_pix_fmt = srcFormat; - ctx->dst_pix_fmt = dstFormat; - - return ctx; -} - -void sws_freeContext(struct SwsContext *ctx) -{ - if ((ctx->resampling_ctx->iwidth != ctx->resampling_ctx->owidth) || - (ctx->resampling_ctx->iheight != ctx->resampling_ctx->oheight)) { - img_resample_close(ctx->resampling_ctx); - } else { - av_free(ctx->resampling_ctx); - } - av_free(ctx); -} - - -/** - * Checks if context is valid or reallocs a new one instead. - * If context is NULL, just calls sws_getContext() to get a new one. - * Otherwise, checks if the parameters are the same already saved in context. - * If that is the case, returns the current context. - * Otherwise, frees context and gets a new one. - * - * Be warned that srcFilter, dstFilter are not checked, they are - * asumed to remain valid. - */ -struct SwsContext *sws_getCachedContext(struct SwsContext *ctx, - int srcW, int srcH, int srcFormat, - int dstW, int dstH, int dstFormat, int flags, - SwsFilter *srcFilter, SwsFilter *dstFilter, double *param) -{ - if (ctx != NULL) { - if ((ctx->resampling_ctx->iwidth != srcW) || - (ctx->resampling_ctx->iheight != srcH) || - (ctx->src_pix_fmt != srcFormat) || - (ctx->resampling_ctx->owidth != dstW) || - (ctx->resampling_ctx->oheight != dstH) || - (ctx->dst_pix_fmt != dstFormat)) - { - sws_freeContext(ctx); - ctx = NULL; - } - } - if (ctx == NULL) { - return sws_getContext(srcW, srcH, srcFormat, - dstW, dstH, dstFormat, flags, - srcFilter, dstFilter, param); - } - return ctx; -} - -int sws_scale(struct SwsContext *ctx, uint8_t* src[], int srcStride[], - int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]) -{ - AVPicture src_pict, dst_pict; - int i, res = 0; - AVPicture picture_format_temp; - AVPicture picture_resample_temp, *formatted_picture, *resampled_picture; - uint8_t *buf1 = NULL, *buf2 = NULL; - enum PixelFormat current_pix_fmt; - - for (i = 0; i < 3; i++) { - src_pict.data[i] = src[i]; - src_pict.linesize[i] = srcStride[i]; - dst_pict.data[i] = dst[i]; - dst_pict.linesize[i] = dstStride[i]; - } - if ((ctx->resampling_ctx->iwidth != ctx->resampling_ctx->owidth) || - (ctx->resampling_ctx->iheight != ctx->resampling_ctx->oheight)) { - /* We have to rescale the picture, but only YUV420P rescaling is supported... */ - - if (ctx->src_pix_fmt != PIX_FMT_YUV420P) { - int size; - - /* create temporary picture for rescaling input*/ - size = avpicture_get_size(PIX_FMT_YUV420P, ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight); - buf1 = av_malloc(size); - if (!buf1) { - res = -1; - goto the_end; - } - formatted_picture = &picture_format_temp; - avpicture_fill((AVPicture*)formatted_picture, buf1, - PIX_FMT_YUV420P, ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight); - - if (img_convert((AVPicture*)formatted_picture, PIX_FMT_YUV420P, - &src_pict, ctx->src_pix_fmt, - ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight) < 0) { - - av_log(NULL, AV_LOG_ERROR, "pixel format conversion not handled\n"); - res = -1; - goto the_end; - } - } else { - formatted_picture = &src_pict; - } - - if (ctx->dst_pix_fmt != PIX_FMT_YUV420P) { - int size; - - /* create temporary picture for rescaling output*/ - size = avpicture_get_size(PIX_FMT_YUV420P, ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight); - buf2 = av_malloc(size); - if (!buf2) { - res = -1; - goto the_end; - } - resampled_picture = &picture_resample_temp; - avpicture_fill((AVPicture*)resampled_picture, buf2, - PIX_FMT_YUV420P, ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight); - - } else { - resampled_picture = &dst_pict; - } - - /* ...and finally rescale!!! */ - img_resample(ctx->resampling_ctx, resampled_picture, formatted_picture); - current_pix_fmt = PIX_FMT_YUV420P; - } else { - resampled_picture = &src_pict; - current_pix_fmt = ctx->src_pix_fmt; - } - - if (current_pix_fmt != ctx->dst_pix_fmt) { - if (img_convert(&dst_pict, ctx->dst_pix_fmt, - resampled_picture, current_pix_fmt, - ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight) < 0) { - - av_log(NULL, AV_LOG_ERROR, "pixel format conversion not handled\n"); - - res = -1; - goto the_end; - } - } else if (resampled_picture != &dst_pict) { - img_copy(&dst_pict, resampled_picture, current_pix_fmt, - ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight); - } - -the_end: - av_free(buf1); - av_free(buf2); - return res; -} - - -#ifdef TEST -#include - -/* input */ -#define XSIZE 256 -#define YSIZE 256 -uint8_t img[XSIZE * YSIZE]; - -/* output */ -#define XSIZE1 512 -#define YSIZE1 512 -uint8_t img1[XSIZE1 * YSIZE1]; -uint8_t img2[XSIZE1 * YSIZE1]; - -void save_pgm(const char *filename, uint8_t *img, int xsize, int ysize) -{ -#undef fprintf - FILE *f; - f=fopen(filename,"w"); - fprintf(f,"P5\n%d %d\n%d\n", xsize, ysize, 255); - fwrite(img,1, xsize * ysize,f); - fclose(f); -#define fprintf please_use_av_log -} - -static void dump_filter(int16_t *filter) -{ - int i, ph; - - for(ph=0;phh_filters[0][0]); - component_resample(s, img1, xsize, xsize, ysize, - img + 50 * XSIZE, XSIZE, XSIZE, YSIZE - 100); - img_resample_close(s); - - snprintf(buf, sizeof(buf), "/tmp/out%d.pgm", i); - save_pgm(buf, img1, xsize, ysize); - } - - /* mmx test */ -#ifdef HAVE_MMX - av_log(NULL, AV_LOG_INFO, "MMX test\n"); - fact = 0.72; - xsize = (int)(XSIZE * fact); - ysize = (int)(YSIZE * fact); - mm_flags = MM_MMX; - s = img_resample_init(xsize, ysize, XSIZE, YSIZE); - component_resample(s, img1, xsize, xsize, ysize, - img, XSIZE, XSIZE, YSIZE); - - mm_flags = 0; - s = img_resample_init(xsize, ysize, XSIZE, YSIZE); - component_resample(s, img2, xsize, xsize, ysize, - img, XSIZE, XSIZE, YSIZE); - if (memcmp(img1, img2, xsize * ysize) != 0) { - av_log(NULL, AV_LOG_ERROR, "mmx error\n"); - exit(1); - } - av_log(NULL, AV_LOG_INFO, "MMX OK\n"); -#endif - return 0; -} - -#endif diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/jfdctfst.c --- a/src/ffmpeg/libavcodec/jfdctfst.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,338 +0,0 @@ -/* - * jfdctfst.c - * - * This file is part of the Independent JPEG Group's software. - * - * The authors make NO WARRANTY or representation, either express or implied, - * with respect to this software, its quality, accuracy, merchantability, or - * fitness for a particular purpose. This software is provided "AS IS", and - * you, its user, assume the entire risk as to its quality and accuracy. - * - * This software is copyright (C) 1994-1996, Thomas G. Lane. - * All Rights Reserved except as specified below. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * software (or portions thereof) for any purpose, without fee, subject to - * these conditions: - * (1) If any part of the source code for this software is distributed, then - * this README file must be included, with this copyright and no-warranty - * notice unaltered; and any additions, deletions, or changes to the original - * files must be clearly indicated in accompanying documentation. - * (2) If only executable code is distributed, then the accompanying - * documentation must state that "this software is based in part on the work - * of the Independent JPEG Group". - * (3) Permission for use of this software is granted only if the user accepts - * full responsibility for any undesirable consequences; the authors accept - * NO LIABILITY for damages of any kind. - * - * These conditions apply to any software derived from or based on the IJG - * code, not just to the unmodified library. If you use our work, you ought - * to acknowledge us. - * - * Permission is NOT granted for the use of any IJG author's name or company - * name in advertising or publicity relating to this software or products - * derived from it. This software may be referred to only as "the Independent - * JPEG Group's software". - * - * We specifically permit and encourage the use of this software as the basis - * of commercial products, provided that all warranty or liability claims are - * assumed by the product vendor. - * - * This file contains a fast, not so accurate integer implementation of the - * forward DCT (Discrete Cosine Transform). - * - * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT - * on each column. Direct algorithms are also available, but they are - * much more complex and seem not to be any faster when reduced to code. - * - * This implementation is based on Arai, Agui, and Nakajima's algorithm for - * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in - * Japanese, but the algorithm is described in the Pennebaker & Mitchell - * JPEG textbook (see REFERENCES section in file README). The following code - * is based directly on figure 4-8 in P&M. - * While an 8-point DCT cannot be done in less than 11 multiplies, it is - * possible to arrange the computation so that many of the multiplies are - * simple scalings of the final outputs. These multiplies can then be - * folded into the multiplications or divisions by the JPEG quantization - * table entries. The AA&N method leaves only 5 multiplies and 29 adds - * to be done in the DCT itself. - * The primary disadvantage of this method is that with fixed-point math, - * accuracy is lost due to imprecise representation of the scaled - * quantization values. The smaller the quantization table entry, the less - * precise the scaled value, so this implementation does worse with high- - * quality-setting files than with low-quality ones. - */ - -/** - * @file jfdctfst.c - * Independent JPEG Group's fast AAN dct. - */ - -#include -#include -#include "common.h" -#include "dsputil.h" - -#define DCTSIZE 8 -#define GLOBAL(x) x -#define RIGHT_SHIFT(x, n) ((x) >> (n)) -#define SHIFT_TEMPS - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* Scaling decisions are generally the same as in the LL&M algorithm; - * see jfdctint.c for more details. However, we choose to descale - * (right shift) multiplication products as soon as they are formed, - * rather than carrying additional fractional bits into subsequent additions. - * This compromises accuracy slightly, but it lets us save a few shifts. - * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) - * everywhere except in the multiplications proper; this saves a good deal - * of work on 16-bit-int machines. - * - * Again to save a few shifts, the intermediate results between pass 1 and - * pass 2 are not upscaled, but are represented only to integral precision. - * - * A final compromise is to represent the multiplicative constants to only - * 8 fractional bits, rather than 13. This saves some shifting work on some - * machines, and may also reduce the cost of multiplication (since there - * are fewer one-bits in the constants). - */ - -#define CONST_BITS 8 - - -/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus - * causing a lot of useless floating-point operations at run time. - * To get around this we use the following pre-calculated constants. - * If you change CONST_BITS you may want to add appropriate values. - * (With a reasonable C compiler, you can just rely on the FIX() macro...) - */ - -#if CONST_BITS == 8 -#define FIX_0_382683433 ((int32_t) 98) /* FIX(0.382683433) */ -#define FIX_0_541196100 ((int32_t) 139) /* FIX(0.541196100) */ -#define FIX_0_707106781 ((int32_t) 181) /* FIX(0.707106781) */ -#define FIX_1_306562965 ((int32_t) 334) /* FIX(1.306562965) */ -#else -#define FIX_0_382683433 FIX(0.382683433) -#define FIX_0_541196100 FIX(0.541196100) -#define FIX_0_707106781 FIX(0.707106781) -#define FIX_1_306562965 FIX(1.306562965) -#endif - - -/* We can gain a little more speed, with a further compromise in accuracy, - * by omitting the addition in a descaling shift. This yields an incorrectly - * rounded result half the time... - */ - -#ifndef USE_ACCURATE_ROUNDING -#undef DESCALE -#define DESCALE(x,n) RIGHT_SHIFT(x, n) -#endif - - -/* Multiply a DCTELEM variable by an int32_t constant, and immediately - * descale to yield a DCTELEM result. - */ - -#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) - -static always_inline void row_fdct(DCTELEM * data){ - int_fast16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_fast16_t tmp10, tmp11, tmp12, tmp13; - int_fast16_t z1, z2, z3, z4, z5, z11, z13; - DCTELEM *dataptr; - int ctr; - SHIFT_TEMPS - - /* Pass 1: process rows. */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[0] + dataptr[7]; - tmp7 = dataptr[0] - dataptr[7]; - tmp1 = dataptr[1] + dataptr[6]; - tmp6 = dataptr[1] - dataptr[6]; - tmp2 = dataptr[2] + dataptr[5]; - tmp5 = dataptr[2] - dataptr[5]; - tmp3 = dataptr[3] + dataptr[4]; - tmp4 = dataptr[3] - dataptr[4]; - - /* Even part */ - - tmp10 = tmp0 + tmp3; /* phase 2 */ - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[0] = tmp10 + tmp11; /* phase 3 */ - dataptr[4] = tmp10 - tmp11; - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ - dataptr[2] = tmp13 + z1; /* phase 5 */ - dataptr[6] = tmp13 - z1; - - /* Odd part */ - - tmp10 = tmp4 + tmp5; /* phase 2 */ - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ - z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ - z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ - z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ - - z11 = tmp7 + z3; /* phase 5 */ - z13 = tmp7 - z3; - - dataptr[5] = z13 + z2; /* phase 6 */ - dataptr[3] = z13 - z2; - dataptr[1] = z11 + z4; - dataptr[7] = z11 - z4; - - dataptr += DCTSIZE; /* advance pointer to next row */ - } -} - -/* - * Perform the forward DCT on one block of samples. - */ - -GLOBAL(void) -fdct_ifast (DCTELEM * data) -{ - int_fast16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_fast16_t tmp10, tmp11, tmp12, tmp13; - int_fast16_t z1, z2, z3, z4, z5, z11, z13; - DCTELEM *dataptr; - int ctr; - SHIFT_TEMPS - - row_fdct(data); - - /* Pass 2: process columns. */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; - tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; - tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; - tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; - tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; - tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; - tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; - tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; - - /* Even part */ - - tmp10 = tmp0 + tmp3; /* phase 2 */ - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ - dataptr[DCTSIZE*4] = tmp10 - tmp11; - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ - dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ - dataptr[DCTSIZE*6] = tmp13 - z1; - - /* Odd part */ - - tmp10 = tmp4 + tmp5; /* phase 2 */ - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - /* The rotator is modified from fig 4-8 to avoid extra negations. */ - z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ - z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ - z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ - z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ - - z11 = tmp7 + z3; /* phase 5 */ - z13 = tmp7 - z3; - - dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ - dataptr[DCTSIZE*3] = z13 - z2; - dataptr[DCTSIZE*1] = z11 + z4; - dataptr[DCTSIZE*7] = z11 - z4; - - dataptr++; /* advance pointer to next column */ - } -} - -/* - * Perform the forward 2-4-8 DCT on one block of samples. - */ - -GLOBAL(void) -fdct_ifast248 (DCTELEM * data) -{ - int_fast16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_fast16_t tmp10, tmp11, tmp12, tmp13; - int_fast16_t z1; - DCTELEM *dataptr; - int ctr; - SHIFT_TEMPS - - row_fdct(data); - - /* Pass 2: process columns. */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*1]; - tmp1 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*3]; - tmp2 = dataptr[DCTSIZE*4] + dataptr[DCTSIZE*5]; - tmp3 = dataptr[DCTSIZE*6] + dataptr[DCTSIZE*7]; - tmp4 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*1]; - tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*3]; - tmp6 = dataptr[DCTSIZE*4] - dataptr[DCTSIZE*5]; - tmp7 = dataptr[DCTSIZE*6] - dataptr[DCTSIZE*7]; - - /* Even part */ - - tmp10 = tmp0 + tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - tmp13 = tmp0 - tmp3; - - dataptr[DCTSIZE*0] = tmp10 + tmp11; - dataptr[DCTSIZE*4] = tmp10 - tmp11; - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); - dataptr[DCTSIZE*2] = tmp13 + z1; - dataptr[DCTSIZE*6] = tmp13 - z1; - - tmp10 = tmp4 + tmp7; - tmp11 = tmp5 + tmp6; - tmp12 = tmp5 - tmp6; - tmp13 = tmp4 - tmp7; - - dataptr[DCTSIZE*1] = tmp10 + tmp11; - dataptr[DCTSIZE*5] = tmp10 - tmp11; - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); - dataptr[DCTSIZE*3] = tmp13 + z1; - dataptr[DCTSIZE*7] = tmp13 - z1; - - dataptr++; /* advance pointer to next column */ - } -} - - -#undef GLOBAL -#undef CONST_BITS -#undef DESCALE -#undef FIX_0_541196100 -#undef FIX_1_306562965 diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/jfdctint.c --- a/src/ffmpeg/libavcodec/jfdctint.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,406 +0,0 @@ -/* - * jfdctint.c - * - * This file is part of the Independent JPEG Group's software. - * - * The authors make NO WARRANTY or representation, either express or implied, - * with respect to this software, its quality, accuracy, merchantability, or - * fitness for a particular purpose. This software is provided "AS IS", and - * you, its user, assume the entire risk as to its quality and accuracy. - * - * This software is copyright (C) 1991-1996, Thomas G. Lane. - * All Rights Reserved except as specified below. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * software (or portions thereof) for any purpose, without fee, subject to - * these conditions: - * (1) If any part of the source code for this software is distributed, then - * this README file must be included, with this copyright and no-warranty - * notice unaltered; and any additions, deletions, or changes to the original - * files must be clearly indicated in accompanying documentation. - * (2) If only executable code is distributed, then the accompanying - * documentation must state that "this software is based in part on the work - * of the Independent JPEG Group". - * (3) Permission for use of this software is granted only if the user accepts - * full responsibility for any undesirable consequences; the authors accept - * NO LIABILITY for damages of any kind. - * - * These conditions apply to any software derived from or based on the IJG - * code, not just to the unmodified library. If you use our work, you ought - * to acknowledge us. - * - * Permission is NOT granted for the use of any IJG author's name or company - * name in advertising or publicity relating to this software or products - * derived from it. This software may be referred to only as "the Independent - * JPEG Group's software". - * - * We specifically permit and encourage the use of this software as the basis - * of commercial products, provided that all warranty or liability claims are - * assumed by the product vendor. - * - * This file contains a slow-but-accurate integer implementation of the - * forward DCT (Discrete Cosine Transform). - * - * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT - * on each column. Direct algorithms are also available, but they are - * much more complex and seem not to be any faster when reduced to code. - * - * This implementation is based on an algorithm described in - * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT - * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, - * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. - * The primary algorithm described there uses 11 multiplies and 29 adds. - * We use their alternate method with 12 multiplies and 32 adds. - * The advantage of this method is that no data path contains more than one - * multiplication; this allows a very simple and accurate implementation in - * scaled fixed-point arithmetic, with a minimal number of shifts. - */ - -/** - * @file jfdctint.c - * Independent JPEG Group's slow & accurate dct. - */ - -#include -#include -#include "common.h" -#include "dsputil.h" - -#define SHIFT_TEMPS -#define DCTSIZE 8 -#define BITS_IN_JSAMPLE 8 -#define GLOBAL(x) x -#define RIGHT_SHIFT(x, n) ((x) >> (n)) -#define MULTIPLY16C16(var,const) ((var)*(const)) - -#if 1 //def USE_ACCURATE_ROUNDING -#define DESCALE(x,n) RIGHT_SHIFT((x) + (1 << ((n) - 1)), n) -#else -#define DESCALE(x,n) RIGHT_SHIFT(x, n) -#endif - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* - * The poop on this scaling stuff is as follows: - * - * Each 1-D DCT step produces outputs which are a factor of sqrt(N) - * larger than the true DCT outputs. The final outputs are therefore - * a factor of N larger than desired; since N=8 this can be cured by - * a simple right shift at the end of the algorithm. The advantage of - * this arrangement is that we save two multiplications per 1-D DCT, - * because the y0 and y4 outputs need not be divided by sqrt(N). - * In the IJG code, this factor of 8 is removed by the quantization step - * (in jcdctmgr.c), NOT in this module. - * - * We have to do addition and subtraction of the integer inputs, which - * is no problem, and multiplication by fractional constants, which is - * a problem to do in integer arithmetic. We multiply all the constants - * by CONST_SCALE and convert them to integer constants (thus retaining - * CONST_BITS bits of precision in the constants). After doing a - * multiplication we have to divide the product by CONST_SCALE, with proper - * rounding, to produce the correct output. This division can be done - * cheaply as a right shift of CONST_BITS bits. We postpone shifting - * as long as possible so that partial sums can be added together with - * full fractional precision. - * - * The outputs of the first pass are scaled up by PASS1_BITS bits so that - * they are represented to better-than-integral precision. These outputs - * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word - * with the recommended scaling. (For 12-bit sample data, the intermediate - * array is int32_t anyway.) - * - * To avoid overflow of the 32-bit intermediate results in pass 2, we must - * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis - * shows that the values given below are the most effective. - */ - -#if BITS_IN_JSAMPLE == 8 -#define CONST_BITS 13 -#define PASS1_BITS 4 /* set this to 2 if 16x16 multiplies are faster */ -#else -#define CONST_BITS 13 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ -#endif - -/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus - * causing a lot of useless floating-point operations at run time. - * To get around this we use the following pre-calculated constants. - * If you change CONST_BITS you may want to add appropriate values. - * (With a reasonable C compiler, you can just rely on the FIX() macro...) - */ - -#if CONST_BITS == 13 -#define FIX_0_298631336 ((int32_t) 2446) /* FIX(0.298631336) */ -#define FIX_0_390180644 ((int32_t) 3196) /* FIX(0.390180644) */ -#define FIX_0_541196100 ((int32_t) 4433) /* FIX(0.541196100) */ -#define FIX_0_765366865 ((int32_t) 6270) /* FIX(0.765366865) */ -#define FIX_0_899976223 ((int32_t) 7373) /* FIX(0.899976223) */ -#define FIX_1_175875602 ((int32_t) 9633) /* FIX(1.175875602) */ -#define FIX_1_501321110 ((int32_t) 12299) /* FIX(1.501321110) */ -#define FIX_1_847759065 ((int32_t) 15137) /* FIX(1.847759065) */ -#define FIX_1_961570560 ((int32_t) 16069) /* FIX(1.961570560) */ -#define FIX_2_053119869 ((int32_t) 16819) /* FIX(2.053119869) */ -#define FIX_2_562915447 ((int32_t) 20995) /* FIX(2.562915447) */ -#define FIX_3_072711026 ((int32_t) 25172) /* FIX(3.072711026) */ -#else -#define FIX_0_298631336 FIX(0.298631336) -#define FIX_0_390180644 FIX(0.390180644) -#define FIX_0_541196100 FIX(0.541196100) -#define FIX_0_765366865 FIX(0.765366865) -#define FIX_0_899976223 FIX(0.899976223) -#define FIX_1_175875602 FIX(1.175875602) -#define FIX_1_501321110 FIX(1.501321110) -#define FIX_1_847759065 FIX(1.847759065) -#define FIX_1_961570560 FIX(1.961570560) -#define FIX_2_053119869 FIX(2.053119869) -#define FIX_2_562915447 FIX(2.562915447) -#define FIX_3_072711026 FIX(3.072711026) -#endif - - -/* Multiply an int32_t variable by an int32_t constant to yield an int32_t result. - * For 8-bit samples with the recommended scaling, all the variable - * and constant values involved are no more than 16 bits wide, so a - * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. - * For 12-bit samples, a full 32-bit multiplication will be needed. - */ - -#if BITS_IN_JSAMPLE == 8 && CONST_BITS<=13 && PASS1_BITS<=2 -#define MULTIPLY(var,const) MULTIPLY16C16(var,const) -#else -#define MULTIPLY(var,const) ((var) * (const)) -#endif - - -static always_inline void row_fdct(DCTELEM * data){ - int_fast32_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_fast32_t tmp10, tmp11, tmp12, tmp13; - int_fast32_t z1, z2, z3, z4, z5; - DCTELEM *dataptr; - int ctr; - SHIFT_TEMPS - - /* Pass 1: process rows. */ - /* Note results are scaled up by sqrt(8) compared to a true DCT; */ - /* furthermore, we scale the results by 2**PASS1_BITS. */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[0] + dataptr[7]; - tmp7 = dataptr[0] - dataptr[7]; - tmp1 = dataptr[1] + dataptr[6]; - tmp6 = dataptr[1] - dataptr[6]; - tmp2 = dataptr[2] + dataptr[5]; - tmp5 = dataptr[2] - dataptr[5]; - tmp3 = dataptr[3] + dataptr[4]; - tmp4 = dataptr[3] - dataptr[4]; - - /* Even part per LL&M figure 1 --- note that published figure is faulty; - * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". - */ - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS); - dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS); - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); - dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), - CONST_BITS-PASS1_BITS); - dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), - CONST_BITS-PASS1_BITS); - - /* Odd part per figure 8 --- note paper omits factor of sqrt(2). - * cK represents cos(K*pi/16). - * i0..i3 in the paper are tmp4..tmp7 here. - */ - - z1 = tmp4 + tmp7; - z2 = tmp5 + tmp6; - z3 = tmp4 + tmp6; - z4 = tmp5 + tmp7; - z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ - - tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ - tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ - tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ - tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ - z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ - z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ - z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ - z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ - - z3 += z5; - z4 += z5; - - dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); - dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); - dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); - dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); - - dataptr += DCTSIZE; /* advance pointer to next row */ - } -} - -/* - * Perform the forward DCT on one block of samples. - */ - -GLOBAL(void) -ff_jpeg_fdct_islow (DCTELEM * data) -{ - int_fast32_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_fast32_t tmp10, tmp11, tmp12, tmp13; - int_fast32_t z1, z2, z3, z4, z5; - DCTELEM *dataptr; - int ctr; - SHIFT_TEMPS - - row_fdct(data); - - /* Pass 2: process columns. - * We remove the PASS1_BITS scaling, but leave the results scaled up - * by an overall factor of 8. - */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; - tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; - tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; - tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; - tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; - tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; - tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; - tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; - - /* Even part per LL&M figure 1 --- note that published figure is faulty; - * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". - */ - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); - dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); - dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), - CONST_BITS+PASS1_BITS); - - /* Odd part per figure 8 --- note paper omits factor of sqrt(2). - * cK represents cos(K*pi/16). - * i0..i3 in the paper are tmp4..tmp7 here. - */ - - z1 = tmp4 + tmp7; - z2 = tmp5 + tmp6; - z3 = tmp4 + tmp6; - z4 = tmp5 + tmp7; - z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ - - tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ - tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ - tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ - tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ - z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ - z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ - z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ - z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ - - z3 += z5; - z4 += z5; - - dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, - CONST_BITS+PASS1_BITS); - - dataptr++; /* advance pointer to next column */ - } -} - -/* - * The secret of DCT2-4-8 is really simple -- you do the usual 1-DCT - * on the rows and then, instead of doing even and odd, part on the colums - * you do even part two times. - */ -GLOBAL(void) -ff_fdct248_islow (DCTELEM * data) -{ - int_fast32_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_fast32_t tmp10, tmp11, tmp12, tmp13; - int_fast32_t z1; - DCTELEM *dataptr; - int ctr; - SHIFT_TEMPS - - row_fdct(data); - - /* Pass 2: process columns. - * We remove the PASS1_BITS scaling, but leave the results scaled up - * by an overall factor of 8. - */ - - dataptr = data; - for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { - tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*1]; - tmp1 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*3]; - tmp2 = dataptr[DCTSIZE*4] + dataptr[DCTSIZE*5]; - tmp3 = dataptr[DCTSIZE*6] + dataptr[DCTSIZE*7]; - tmp4 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*1]; - tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*3]; - tmp6 = dataptr[DCTSIZE*4] - dataptr[DCTSIZE*5]; - tmp7 = dataptr[DCTSIZE*6] - dataptr[DCTSIZE*7]; - - tmp10 = tmp0 + tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - tmp13 = tmp0 - tmp3; - - dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); - dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); - dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), - CONST_BITS+PASS1_BITS); - - tmp10 = tmp4 + tmp7; - tmp11 = tmp5 + tmp6; - tmp12 = tmp5 - tmp6; - tmp13 = tmp4 - tmp7; - - dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); - dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); - - z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); - dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), - CONST_BITS+PASS1_BITS); - dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), - CONST_BITS+PASS1_BITS); - - dataptr++; /* advance pointer to next column */ - } -} diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/jrevdct.c --- a/src/ffmpeg/libavcodec/jrevdct.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1159 +0,0 @@ -/* - * jrevdct.c - * - * This file is part of the Independent JPEG Group's software. - * - * The authors make NO WARRANTY or representation, either express or implied, - * with respect to this software, its quality, accuracy, merchantability, or - * fitness for a particular purpose. This software is provided "AS IS", and - * you, its user, assume the entire risk as to its quality and accuracy. - * - * This software is copyright (C) 1991, 1992, Thomas G. Lane. - * All Rights Reserved except as specified below. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * software (or portions thereof) for any purpose, without fee, subject to - * these conditions: - * (1) If any part of the source code for this software is distributed, then - * this README file must be included, with this copyright and no-warranty - * notice unaltered; and any additions, deletions, or changes to the original - * files must be clearly indicated in accompanying documentation. - * (2) If only executable code is distributed, then the accompanying - * documentation must state that "this software is based in part on the work - * of the Independent JPEG Group". - * (3) Permission for use of this software is granted only if the user accepts - * full responsibility for any undesirable consequences; the authors accept - * NO LIABILITY for damages of any kind. - * - * These conditions apply to any software derived from or based on the IJG - * code, not just to the unmodified library. If you use our work, you ought - * to acknowledge us. - * - * Permission is NOT granted for the use of any IJG author's name or company - * name in advertising or publicity relating to this software or products - * derived from it. This software may be referred to only as "the Independent - * JPEG Group's software". - * - * We specifically permit and encourage the use of this software as the basis - * of commercial products, provided that all warranty or liability claims are - * assumed by the product vendor. - * - * This file contains the basic inverse-DCT transformation subroutine. - * - * This implementation is based on an algorithm described in - * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT - * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, - * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. - * The primary algorithm described there uses 11 multiplies and 29 adds. - * We use their alternate method with 12 multiplies and 32 adds. - * The advantage of this method is that no data path contains more than one - * multiplication; this allows a very simple and accurate implementation in - * scaled fixed-point arithmetic, with a minimal number of shifts. - * - * I've made lots of modifications to attempt to take advantage of the - * sparse nature of the DCT matrices we're getting. Although the logic - * is cumbersome, it's straightforward and the resulting code is much - * faster. - * - * A better way to do this would be to pass in the DCT block as a sparse - * matrix, perhaps with the difference cases encoded. - */ - -/** - * @file jrevdct.c - * Independent JPEG Group's LLM idct. - */ - -#include "common.h" -#include "dsputil.h" - -#define EIGHT_BIT_SAMPLES - -#define DCTSIZE 8 -#define DCTSIZE2 64 - -#define GLOBAL - -#define RIGHT_SHIFT(x, n) ((x) >> (n)) - -typedef DCTELEM DCTBLOCK[DCTSIZE2]; - -#define CONST_BITS 13 - -/* - * This routine is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ -#endif - - -/* - * A 2-D IDCT can be done by 1-D IDCT on each row followed by 1-D IDCT - * on each column. Direct algorithms are also available, but they are - * much more complex and seem not to be any faster when reduced to code. - * - * The poop on this scaling stuff is as follows: - * - * Each 1-D IDCT step produces outputs which are a factor of sqrt(N) - * larger than the true IDCT outputs. The final outputs are therefore - * a factor of N larger than desired; since N=8 this can be cured by - * a simple right shift at the end of the algorithm. The advantage of - * this arrangement is that we save two multiplications per 1-D IDCT, - * because the y0 and y4 inputs need not be divided by sqrt(N). - * - * We have to do addition and subtraction of the integer inputs, which - * is no problem, and multiplication by fractional constants, which is - * a problem to do in integer arithmetic. We multiply all the constants - * by CONST_SCALE and convert them to integer constants (thus retaining - * CONST_BITS bits of precision in the constants). After doing a - * multiplication we have to divide the product by CONST_SCALE, with proper - * rounding, to produce the correct output. This division can be done - * cheaply as a right shift of CONST_BITS bits. We postpone shifting - * as long as possible so that partial sums can be added together with - * full fractional precision. - * - * The outputs of the first pass are scaled up by PASS1_BITS bits so that - * they are represented to better-than-integral precision. These outputs - * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word - * with the recommended scaling. (To scale up 12-bit sample data further, an - * intermediate int32 array would be needed.) - * - * To avoid overflow of the 32-bit intermediate results in pass 2, we must - * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis - * shows that the values given below are the most effective. - */ - -#ifdef EIGHT_BIT_SAMPLES -#define PASS1_BITS 2 -#else -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ -#endif - -#define ONE ((int32_t) 1) - -#define CONST_SCALE (ONE << CONST_BITS) - -/* Convert a positive real constant to an integer scaled by CONST_SCALE. - * IMPORTANT: if your compiler doesn't do this arithmetic at compile time, - * you will pay a significant penalty in run time. In that case, figure - * the correct integer constant values and insert them by hand. - */ - -/* Actually FIX is no longer used, we precomputed them all */ -#define FIX(x) ((int32_t) ((x) * CONST_SCALE + 0.5)) - -/* Descale and correctly round an int32_t value that's scaled by N bits. - * We assume RIGHT_SHIFT rounds towards minus infinity, so adding - * the fudge factor is correct for either sign of X. - */ - -#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) - -/* Multiply an int32_t variable by an int32_t constant to yield an int32_t result. - * For 8-bit samples with the recommended scaling, all the variable - * and constant values involved are no more than 16 bits wide, so a - * 16x16->32 bit multiply can be used instead of a full 32x32 multiply; - * this provides a useful speedup on many machines. - * There is no way to specify a 16x16->32 multiply in portable C, but - * some C compilers will do the right thing if you provide the correct - * combination of casts. - * NB: for 12-bit samples, a full 32-bit multiplication will be needed. - */ - -#ifdef EIGHT_BIT_SAMPLES -#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ -#define MULTIPLY(var,const) (((int16_t) (var)) * ((int16_t) (const))) -#endif -#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ -#define MULTIPLY(var,const) (((int16_t) (var)) * ((int32_t) (const))) -#endif -#endif - -#ifndef MULTIPLY /* default definition */ -#define MULTIPLY(var,const) ((var) * (const)) -#endif - - -/* - Unlike our decoder where we approximate the FIXes, we need to use exact -ones here or successive P-frames will drift too much with Reference frame coding -*/ -#define FIX_0_211164243 1730 -#define FIX_0_275899380 2260 -#define FIX_0_298631336 2446 -#define FIX_0_390180644 3196 -#define FIX_0_509795579 4176 -#define FIX_0_541196100 4433 -#define FIX_0_601344887 4926 -#define FIX_0_765366865 6270 -#define FIX_0_785694958 6436 -#define FIX_0_899976223 7373 -#define FIX_1_061594337 8697 -#define FIX_1_111140466 9102 -#define FIX_1_175875602 9633 -#define FIX_1_306562965 10703 -#define FIX_1_387039845 11363 -#define FIX_1_451774981 11893 -#define FIX_1_501321110 12299 -#define FIX_1_662939225 13623 -#define FIX_1_847759065 15137 -#define FIX_1_961570560 16069 -#define FIX_2_053119869 16819 -#define FIX_2_172734803 17799 -#define FIX_2_562915447 20995 -#define FIX_3_072711026 25172 - -/* - * Perform the inverse DCT on one block of coefficients. - */ - -void j_rev_dct(DCTBLOCK data) -{ - int32_t tmp0, tmp1, tmp2, tmp3; - int32_t tmp10, tmp11, tmp12, tmp13; - int32_t z1, z2, z3, z4, z5; - int32_t d0, d1, d2, d3, d4, d5, d6, d7; - register DCTELEM *dataptr; - int rowctr; - - /* Pass 1: process rows. */ - /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ - /* furthermore, we scale the results by 2**PASS1_BITS. */ - - dataptr = data; - - for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any row in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * row DCT calculations can be simplified this way. - */ - - register int *idataptr = (int*)dataptr; - - /* WARNING: we do the same permutation as MMX idct to simplify the - video core */ - d0 = dataptr[0]; - d2 = dataptr[1]; - d4 = dataptr[2]; - d6 = dataptr[3]; - d1 = dataptr[4]; - d3 = dataptr[5]; - d5 = dataptr[6]; - d7 = dataptr[7]; - - if ((d1 | d2 | d3 | d4 | d5 | d6 | d7) == 0) { - /* AC terms all zero */ - if (d0) { - /* Compute a 32 bit value to assign. */ - DCTELEM dcval = (DCTELEM) (d0 << PASS1_BITS); - register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000); - - idataptr[0] = v; - idataptr[1] = v; - idataptr[2] = v; - idataptr[3] = v; - } - - dataptr += DCTSIZE; /* advance pointer to next row */ - continue; - } - - /* Even part: reverse the even part of the forward DCT. */ - /* The rotator is sqrt(2)*c(-6). */ -{ - if (d6) { - if (d2) { - /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */ - z1 = MULTIPLY(d2 + d6, FIX_0_541196100); - tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065); - tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } else { - /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */ - tmp2 = MULTIPLY(-d6, FIX_1_306562965); - tmp3 = MULTIPLY(d6, FIX_0_541196100); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } - } else { - if (d2) { - /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */ - tmp2 = MULTIPLY(d2, FIX_0_541196100); - tmp3 = MULTIPLY(d2, FIX_1_306562965); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } else { - /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */ - tmp10 = tmp13 = (d0 + d4) << CONST_BITS; - tmp11 = tmp12 = (d0 - d4) << CONST_BITS; - } - } - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - - if (d7) { - if (d5) { - if (d3) { - if (d1) { - /* d1 != 0, d3 != 0, d5 != 0, d7 != 0 */ - z1 = d7 + d1; - z2 = d5 + d3; - z3 = d7 + d3; - z4 = d5 + d1; - z5 = MULTIPLY(z3 + z4, FIX_1_175875602); - - tmp0 = MULTIPLY(d7, FIX_0_298631336); - tmp1 = MULTIPLY(d5, FIX_2_053119869); - tmp2 = MULTIPLY(d3, FIX_3_072711026); - tmp3 = MULTIPLY(d1, FIX_1_501321110); - z1 = MULTIPLY(-z1, FIX_0_899976223); - z2 = MULTIPLY(-z2, FIX_2_562915447); - z3 = MULTIPLY(-z3, FIX_1_961570560); - z4 = MULTIPLY(-z4, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 += z2 + z4; - tmp2 += z2 + z3; - tmp3 += z1 + z4; - } else { - /* d1 == 0, d3 != 0, d5 != 0, d7 != 0 */ - z2 = d5 + d3; - z3 = d7 + d3; - z5 = MULTIPLY(z3 + d5, FIX_1_175875602); - - tmp0 = MULTIPLY(d7, FIX_0_298631336); - tmp1 = MULTIPLY(d5, FIX_2_053119869); - tmp2 = MULTIPLY(d3, FIX_3_072711026); - z1 = MULTIPLY(-d7, FIX_0_899976223); - z2 = MULTIPLY(-z2, FIX_2_562915447); - z3 = MULTIPLY(-z3, FIX_1_961570560); - z4 = MULTIPLY(-d5, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 += z2 + z4; - tmp2 += z2 + z3; - tmp3 = z1 + z4; - } - } else { - if (d1) { - /* d1 != 0, d3 == 0, d5 != 0, d7 != 0 */ - z1 = d7 + d1; - z4 = d5 + d1; - z5 = MULTIPLY(d7 + z4, FIX_1_175875602); - - tmp0 = MULTIPLY(d7, FIX_0_298631336); - tmp1 = MULTIPLY(d5, FIX_2_053119869); - tmp3 = MULTIPLY(d1, FIX_1_501321110); - z1 = MULTIPLY(-z1, FIX_0_899976223); - z2 = MULTIPLY(-d5, FIX_2_562915447); - z3 = MULTIPLY(-d7, FIX_1_961570560); - z4 = MULTIPLY(-z4, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 += z2 + z4; - tmp2 = z2 + z3; - tmp3 += z1 + z4; - } else { - /* d1 == 0, d3 == 0, d5 != 0, d7 != 0 */ - tmp0 = MULTIPLY(-d7, FIX_0_601344887); - z1 = MULTIPLY(-d7, FIX_0_899976223); - z3 = MULTIPLY(-d7, FIX_1_961570560); - tmp1 = MULTIPLY(-d5, FIX_0_509795579); - z2 = MULTIPLY(-d5, FIX_2_562915447); - z4 = MULTIPLY(-d5, FIX_0_390180644); - z5 = MULTIPLY(d5 + d7, FIX_1_175875602); - - z3 += z5; - z4 += z5; - - tmp0 += z3; - tmp1 += z4; - tmp2 = z2 + z3; - tmp3 = z1 + z4; - } - } - } else { - if (d3) { - if (d1) { - /* d1 != 0, d3 != 0, d5 == 0, d7 != 0 */ - z1 = d7 + d1; - z3 = d7 + d3; - z5 = MULTIPLY(z3 + d1, FIX_1_175875602); - - tmp0 = MULTIPLY(d7, FIX_0_298631336); - tmp2 = MULTIPLY(d3, FIX_3_072711026); - tmp3 = MULTIPLY(d1, FIX_1_501321110); - z1 = MULTIPLY(-z1, FIX_0_899976223); - z2 = MULTIPLY(-d3, FIX_2_562915447); - z3 = MULTIPLY(-z3, FIX_1_961570560); - z4 = MULTIPLY(-d1, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 = z2 + z4; - tmp2 += z2 + z3; - tmp3 += z1 + z4; - } else { - /* d1 == 0, d3 != 0, d5 == 0, d7 != 0 */ - z3 = d7 + d3; - - tmp0 = MULTIPLY(-d7, FIX_0_601344887); - z1 = MULTIPLY(-d7, FIX_0_899976223); - tmp2 = MULTIPLY(d3, FIX_0_509795579); - z2 = MULTIPLY(-d3, FIX_2_562915447); - z5 = MULTIPLY(z3, FIX_1_175875602); - z3 = MULTIPLY(-z3, FIX_0_785694958); - - tmp0 += z3; - tmp1 = z2 + z5; - tmp2 += z3; - tmp3 = z1 + z5; - } - } else { - if (d1) { - /* d1 != 0, d3 == 0, d5 == 0, d7 != 0 */ - z1 = d7 + d1; - z5 = MULTIPLY(z1, FIX_1_175875602); - - z1 = MULTIPLY(z1, FIX_0_275899380); - z3 = MULTIPLY(-d7, FIX_1_961570560); - tmp0 = MULTIPLY(-d7, FIX_1_662939225); - z4 = MULTIPLY(-d1, FIX_0_390180644); - tmp3 = MULTIPLY(d1, FIX_1_111140466); - - tmp0 += z1; - tmp1 = z4 + z5; - tmp2 = z3 + z5; - tmp3 += z1; - } else { - /* d1 == 0, d3 == 0, d5 == 0, d7 != 0 */ - tmp0 = MULTIPLY(-d7, FIX_1_387039845); - tmp1 = MULTIPLY(d7, FIX_1_175875602); - tmp2 = MULTIPLY(-d7, FIX_0_785694958); - tmp3 = MULTIPLY(d7, FIX_0_275899380); - } - } - } - } else { - if (d5) { - if (d3) { - if (d1) { - /* d1 != 0, d3 != 0, d5 != 0, d7 == 0 */ - z2 = d5 + d3; - z4 = d5 + d1; - z5 = MULTIPLY(d3 + z4, FIX_1_175875602); - - tmp1 = MULTIPLY(d5, FIX_2_053119869); - tmp2 = MULTIPLY(d3, FIX_3_072711026); - tmp3 = MULTIPLY(d1, FIX_1_501321110); - z1 = MULTIPLY(-d1, FIX_0_899976223); - z2 = MULTIPLY(-z2, FIX_2_562915447); - z3 = MULTIPLY(-d3, FIX_1_961570560); - z4 = MULTIPLY(-z4, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 = z1 + z3; - tmp1 += z2 + z4; - tmp2 += z2 + z3; - tmp3 += z1 + z4; - } else { - /* d1 == 0, d3 != 0, d5 != 0, d7 == 0 */ - z2 = d5 + d3; - - z5 = MULTIPLY(z2, FIX_1_175875602); - tmp1 = MULTIPLY(d5, FIX_1_662939225); - z4 = MULTIPLY(-d5, FIX_0_390180644); - z2 = MULTIPLY(-z2, FIX_1_387039845); - tmp2 = MULTIPLY(d3, FIX_1_111140466); - z3 = MULTIPLY(-d3, FIX_1_961570560); - - tmp0 = z3 + z5; - tmp1 += z2; - tmp2 += z2; - tmp3 = z4 + z5; - } - } else { - if (d1) { - /* d1 != 0, d3 == 0, d5 != 0, d7 == 0 */ - z4 = d5 + d1; - - z5 = MULTIPLY(z4, FIX_1_175875602); - z1 = MULTIPLY(-d1, FIX_0_899976223); - tmp3 = MULTIPLY(d1, FIX_0_601344887); - tmp1 = MULTIPLY(-d5, FIX_0_509795579); - z2 = MULTIPLY(-d5, FIX_2_562915447); - z4 = MULTIPLY(z4, FIX_0_785694958); - - tmp0 = z1 + z5; - tmp1 += z4; - tmp2 = z2 + z5; - tmp3 += z4; - } else { - /* d1 == 0, d3 == 0, d5 != 0, d7 == 0 */ - tmp0 = MULTIPLY(d5, FIX_1_175875602); - tmp1 = MULTIPLY(d5, FIX_0_275899380); - tmp2 = MULTIPLY(-d5, FIX_1_387039845); - tmp3 = MULTIPLY(d5, FIX_0_785694958); - } - } - } else { - if (d3) { - if (d1) { - /* d1 != 0, d3 != 0, d5 == 0, d7 == 0 */ - z5 = d1 + d3; - tmp3 = MULTIPLY(d1, FIX_0_211164243); - tmp2 = MULTIPLY(-d3, FIX_1_451774981); - z1 = MULTIPLY(d1, FIX_1_061594337); - z2 = MULTIPLY(-d3, FIX_2_172734803); - z4 = MULTIPLY(z5, FIX_0_785694958); - z5 = MULTIPLY(z5, FIX_1_175875602); - - tmp0 = z1 - z4; - tmp1 = z2 + z4; - tmp2 += z5; - tmp3 += z5; - } else { - /* d1 == 0, d3 != 0, d5 == 0, d7 == 0 */ - tmp0 = MULTIPLY(-d3, FIX_0_785694958); - tmp1 = MULTIPLY(-d3, FIX_1_387039845); - tmp2 = MULTIPLY(-d3, FIX_0_275899380); - tmp3 = MULTIPLY(d3, FIX_1_175875602); - } - } else { - if (d1) { - /* d1 != 0, d3 == 0, d5 == 0, d7 == 0 */ - tmp0 = MULTIPLY(d1, FIX_0_275899380); - tmp1 = MULTIPLY(d1, FIX_0_785694958); - tmp2 = MULTIPLY(d1, FIX_1_175875602); - tmp3 = MULTIPLY(d1, FIX_1_387039845); - } else { - /* d1 == 0, d3 == 0, d5 == 0, d7 == 0 */ - tmp0 = tmp1 = tmp2 = tmp3 = 0; - } - } - } - } -} - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - dataptr[0] = (DCTELEM) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS); - dataptr[7] = (DCTELEM) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS); - dataptr[1] = (DCTELEM) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS); - dataptr[6] = (DCTELEM) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS); - dataptr[2] = (DCTELEM) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS); - dataptr[5] = (DCTELEM) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS); - dataptr[3] = (DCTELEM) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS); - dataptr[4] = (DCTELEM) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS); - - dataptr += DCTSIZE; /* advance pointer to next row */ - } - - /* Pass 2: process columns. */ - /* Note that we must descale the results by a factor of 8 == 2**3, */ - /* and also undo the PASS1_BITS scaling. */ - - dataptr = data; - for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) { - /* Columns of zeroes can be exploited in the same way as we did with rows. - * However, the row calculation has created many nonzero AC terms, so the - * simplification applies less often (typically 5% to 10% of the time). - * On machines with very fast multiplication, it's possible that the - * test takes more time than it's worth. In that case this section - * may be commented out. - */ - - d0 = dataptr[DCTSIZE*0]; - d1 = dataptr[DCTSIZE*1]; - d2 = dataptr[DCTSIZE*2]; - d3 = dataptr[DCTSIZE*3]; - d4 = dataptr[DCTSIZE*4]; - d5 = dataptr[DCTSIZE*5]; - d6 = dataptr[DCTSIZE*6]; - d7 = dataptr[DCTSIZE*7]; - - /* Even part: reverse the even part of the forward DCT. */ - /* The rotator is sqrt(2)*c(-6). */ - if (d6) { - if (d2) { - /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */ - z1 = MULTIPLY(d2 + d6, FIX_0_541196100); - tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065); - tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } else { - /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */ - tmp2 = MULTIPLY(-d6, FIX_1_306562965); - tmp3 = MULTIPLY(d6, FIX_0_541196100); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } - } else { - if (d2) { - /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */ - tmp2 = MULTIPLY(d2, FIX_0_541196100); - tmp3 = MULTIPLY(d2, FIX_1_306562965); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } else { - /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */ - tmp10 = tmp13 = (d0 + d4) << CONST_BITS; - tmp11 = tmp12 = (d0 - d4) << CONST_BITS; - } - } - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - if (d7) { - if (d5) { - if (d3) { - if (d1) { - /* d1 != 0, d3 != 0, d5 != 0, d7 != 0 */ - z1 = d7 + d1; - z2 = d5 + d3; - z3 = d7 + d3; - z4 = d5 + d1; - z5 = MULTIPLY(z3 + z4, FIX_1_175875602); - - tmp0 = MULTIPLY(d7, FIX_0_298631336); - tmp1 = MULTIPLY(d5, FIX_2_053119869); - tmp2 = MULTIPLY(d3, FIX_3_072711026); - tmp3 = MULTIPLY(d1, FIX_1_501321110); - z1 = MULTIPLY(-z1, FIX_0_899976223); - z2 = MULTIPLY(-z2, FIX_2_562915447); - z3 = MULTIPLY(-z3, FIX_1_961570560); - z4 = MULTIPLY(-z4, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 += z2 + z4; - tmp2 += z2 + z3; - tmp3 += z1 + z4; - } else { - /* d1 == 0, d3 != 0, d5 != 0, d7 != 0 */ - z1 = d7; - z2 = d5 + d3; - z3 = d7 + d3; - z5 = MULTIPLY(z3 + d5, FIX_1_175875602); - - tmp0 = MULTIPLY(d7, FIX_0_298631336); - tmp1 = MULTIPLY(d5, FIX_2_053119869); - tmp2 = MULTIPLY(d3, FIX_3_072711026); - z1 = MULTIPLY(-d7, FIX_0_899976223); - z2 = MULTIPLY(-z2, FIX_2_562915447); - z3 = MULTIPLY(-z3, FIX_1_961570560); - z4 = MULTIPLY(-d5, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 += z2 + z4; - tmp2 += z2 + z3; - tmp3 = z1 + z4; - } - } else { - if (d1) { - /* d1 != 0, d3 == 0, d5 != 0, d7 != 0 */ - z1 = d7 + d1; - z2 = d5; - z3 = d7; - z4 = d5 + d1; - z5 = MULTIPLY(z3 + z4, FIX_1_175875602); - - tmp0 = MULTIPLY(d7, FIX_0_298631336); - tmp1 = MULTIPLY(d5, FIX_2_053119869); - tmp3 = MULTIPLY(d1, FIX_1_501321110); - z1 = MULTIPLY(-z1, FIX_0_899976223); - z2 = MULTIPLY(-d5, FIX_2_562915447); - z3 = MULTIPLY(-d7, FIX_1_961570560); - z4 = MULTIPLY(-z4, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 += z2 + z4; - tmp2 = z2 + z3; - tmp3 += z1 + z4; - } else { - /* d1 == 0, d3 == 0, d5 != 0, d7 != 0 */ - tmp0 = MULTIPLY(-d7, FIX_0_601344887); - z1 = MULTIPLY(-d7, FIX_0_899976223); - z3 = MULTIPLY(-d7, FIX_1_961570560); - tmp1 = MULTIPLY(-d5, FIX_0_509795579); - z2 = MULTIPLY(-d5, FIX_2_562915447); - z4 = MULTIPLY(-d5, FIX_0_390180644); - z5 = MULTIPLY(d5 + d7, FIX_1_175875602); - - z3 += z5; - z4 += z5; - - tmp0 += z3; - tmp1 += z4; - tmp2 = z2 + z3; - tmp3 = z1 + z4; - } - } - } else { - if (d3) { - if (d1) { - /* d1 != 0, d3 != 0, d5 == 0, d7 != 0 */ - z1 = d7 + d1; - z3 = d7 + d3; - z5 = MULTIPLY(z3 + d1, FIX_1_175875602); - - tmp0 = MULTIPLY(d7, FIX_0_298631336); - tmp2 = MULTIPLY(d3, FIX_3_072711026); - tmp3 = MULTIPLY(d1, FIX_1_501321110); - z1 = MULTIPLY(-z1, FIX_0_899976223); - z2 = MULTIPLY(-d3, FIX_2_562915447); - z3 = MULTIPLY(-z3, FIX_1_961570560); - z4 = MULTIPLY(-d1, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 += z1 + z3; - tmp1 = z2 + z4; - tmp2 += z2 + z3; - tmp3 += z1 + z4; - } else { - /* d1 == 0, d3 != 0, d5 == 0, d7 != 0 */ - z3 = d7 + d3; - - tmp0 = MULTIPLY(-d7, FIX_0_601344887); - z1 = MULTIPLY(-d7, FIX_0_899976223); - tmp2 = MULTIPLY(d3, FIX_0_509795579); - z2 = MULTIPLY(-d3, FIX_2_562915447); - z5 = MULTIPLY(z3, FIX_1_175875602); - z3 = MULTIPLY(-z3, FIX_0_785694958); - - tmp0 += z3; - tmp1 = z2 + z5; - tmp2 += z3; - tmp3 = z1 + z5; - } - } else { - if (d1) { - /* d1 != 0, d3 == 0, d5 == 0, d7 != 0 */ - z1 = d7 + d1; - z5 = MULTIPLY(z1, FIX_1_175875602); - - z1 = MULTIPLY(z1, FIX_0_275899380); - z3 = MULTIPLY(-d7, FIX_1_961570560); - tmp0 = MULTIPLY(-d7, FIX_1_662939225); - z4 = MULTIPLY(-d1, FIX_0_390180644); - tmp3 = MULTIPLY(d1, FIX_1_111140466); - - tmp0 += z1; - tmp1 = z4 + z5; - tmp2 = z3 + z5; - tmp3 += z1; - } else { - /* d1 == 0, d3 == 0, d5 == 0, d7 != 0 */ - tmp0 = MULTIPLY(-d7, FIX_1_387039845); - tmp1 = MULTIPLY(d7, FIX_1_175875602); - tmp2 = MULTIPLY(-d7, FIX_0_785694958); - tmp3 = MULTIPLY(d7, FIX_0_275899380); - } - } - } - } else { - if (d5) { - if (d3) { - if (d1) { - /* d1 != 0, d3 != 0, d5 != 0, d7 == 0 */ - z2 = d5 + d3; - z4 = d5 + d1; - z5 = MULTIPLY(d3 + z4, FIX_1_175875602); - - tmp1 = MULTIPLY(d5, FIX_2_053119869); - tmp2 = MULTIPLY(d3, FIX_3_072711026); - tmp3 = MULTIPLY(d1, FIX_1_501321110); - z1 = MULTIPLY(-d1, FIX_0_899976223); - z2 = MULTIPLY(-z2, FIX_2_562915447); - z3 = MULTIPLY(-d3, FIX_1_961570560); - z4 = MULTIPLY(-z4, FIX_0_390180644); - - z3 += z5; - z4 += z5; - - tmp0 = z1 + z3; - tmp1 += z2 + z4; - tmp2 += z2 + z3; - tmp3 += z1 + z4; - } else { - /* d1 == 0, d3 != 0, d5 != 0, d7 == 0 */ - z2 = d5 + d3; - - z5 = MULTIPLY(z2, FIX_1_175875602); - tmp1 = MULTIPLY(d5, FIX_1_662939225); - z4 = MULTIPLY(-d5, FIX_0_390180644); - z2 = MULTIPLY(-z2, FIX_1_387039845); - tmp2 = MULTIPLY(d3, FIX_1_111140466); - z3 = MULTIPLY(-d3, FIX_1_961570560); - - tmp0 = z3 + z5; - tmp1 += z2; - tmp2 += z2; - tmp3 = z4 + z5; - } - } else { - if (d1) { - /* d1 != 0, d3 == 0, d5 != 0, d7 == 0 */ - z4 = d5 + d1; - - z5 = MULTIPLY(z4, FIX_1_175875602); - z1 = MULTIPLY(-d1, FIX_0_899976223); - tmp3 = MULTIPLY(d1, FIX_0_601344887); - tmp1 = MULTIPLY(-d5, FIX_0_509795579); - z2 = MULTIPLY(-d5, FIX_2_562915447); - z4 = MULTIPLY(z4, FIX_0_785694958); - - tmp0 = z1 + z5; - tmp1 += z4; - tmp2 = z2 + z5; - tmp3 += z4; - } else { - /* d1 == 0, d3 == 0, d5 != 0, d7 == 0 */ - tmp0 = MULTIPLY(d5, FIX_1_175875602); - tmp1 = MULTIPLY(d5, FIX_0_275899380); - tmp2 = MULTIPLY(-d5, FIX_1_387039845); - tmp3 = MULTIPLY(d5, FIX_0_785694958); - } - } - } else { - if (d3) { - if (d1) { - /* d1 != 0, d3 != 0, d5 == 0, d7 == 0 */ - z5 = d1 + d3; - tmp3 = MULTIPLY(d1, FIX_0_211164243); - tmp2 = MULTIPLY(-d3, FIX_1_451774981); - z1 = MULTIPLY(d1, FIX_1_061594337); - z2 = MULTIPLY(-d3, FIX_2_172734803); - z4 = MULTIPLY(z5, FIX_0_785694958); - z5 = MULTIPLY(z5, FIX_1_175875602); - - tmp0 = z1 - z4; - tmp1 = z2 + z4; - tmp2 += z5; - tmp3 += z5; - } else { - /* d1 == 0, d3 != 0, d5 == 0, d7 == 0 */ - tmp0 = MULTIPLY(-d3, FIX_0_785694958); - tmp1 = MULTIPLY(-d3, FIX_1_387039845); - tmp2 = MULTIPLY(-d3, FIX_0_275899380); - tmp3 = MULTIPLY(d3, FIX_1_175875602); - } - } else { - if (d1) { - /* d1 != 0, d3 == 0, d5 == 0, d7 == 0 */ - tmp0 = MULTIPLY(d1, FIX_0_275899380); - tmp1 = MULTIPLY(d1, FIX_0_785694958); - tmp2 = MULTIPLY(d1, FIX_1_175875602); - tmp3 = MULTIPLY(d1, FIX_1_387039845); - } else { - /* d1 == 0, d3 == 0, d5 == 0, d7 == 0 */ - tmp0 = tmp1 = tmp2 = tmp3 = 0; - } - } - } - } - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp3, - CONST_BITS+PASS1_BITS+3); - dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp10 - tmp3, - CONST_BITS+PASS1_BITS+3); - dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp11 + tmp2, - CONST_BITS+PASS1_BITS+3); - dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(tmp11 - tmp2, - CONST_BITS+PASS1_BITS+3); - dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(tmp12 + tmp1, - CONST_BITS+PASS1_BITS+3); - dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp12 - tmp1, - CONST_BITS+PASS1_BITS+3); - dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp13 + tmp0, - CONST_BITS+PASS1_BITS+3); - dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp13 - tmp0, - CONST_BITS+PASS1_BITS+3); - - dataptr++; /* advance pointer to next column */ - } -} - -#undef DCTSIZE -#define DCTSIZE 4 -#define DCTSTRIDE 8 - -void j_rev_dct4(DCTBLOCK data) -{ - int32_t tmp0, tmp1, tmp2, tmp3; - int32_t tmp10, tmp11, tmp12, tmp13; - int32_t z1; - int32_t d0, d2, d4, d6; - register DCTELEM *dataptr; - int rowctr; - - /* Pass 1: process rows. */ - /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ - /* furthermore, we scale the results by 2**PASS1_BITS. */ - - data[0] += 4; - - dataptr = data; - - for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any row in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * row DCT calculations can be simplified this way. - */ - - register int *idataptr = (int*)dataptr; - - d0 = dataptr[0]; - d2 = dataptr[1]; - d4 = dataptr[2]; - d6 = dataptr[3]; - - if ((d2 | d4 | d6) == 0) { - /* AC terms all zero */ - if (d0) { - /* Compute a 32 bit value to assign. */ - DCTELEM dcval = (DCTELEM) (d0 << PASS1_BITS); - register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000); - - idataptr[0] = v; - idataptr[1] = v; - } - - dataptr += DCTSTRIDE; /* advance pointer to next row */ - continue; - } - - /* Even part: reverse the even part of the forward DCT. */ - /* The rotator is sqrt(2)*c(-6). */ - if (d6) { - if (d2) { - /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */ - z1 = MULTIPLY(d2 + d6, FIX_0_541196100); - tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065); - tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } else { - /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */ - tmp2 = MULTIPLY(-d6, FIX_1_306562965); - tmp3 = MULTIPLY(d6, FIX_0_541196100); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } - } else { - if (d2) { - /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */ - tmp2 = MULTIPLY(d2, FIX_0_541196100); - tmp3 = MULTIPLY(d2, FIX_1_306562965); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } else { - /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */ - tmp10 = tmp13 = (d0 + d4) << CONST_BITS; - tmp11 = tmp12 = (d0 - d4) << CONST_BITS; - } - } - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - dataptr[0] = (DCTELEM) DESCALE(tmp10, CONST_BITS-PASS1_BITS); - dataptr[1] = (DCTELEM) DESCALE(tmp11, CONST_BITS-PASS1_BITS); - dataptr[2] = (DCTELEM) DESCALE(tmp12, CONST_BITS-PASS1_BITS); - dataptr[3] = (DCTELEM) DESCALE(tmp13, CONST_BITS-PASS1_BITS); - - dataptr += DCTSTRIDE; /* advance pointer to next row */ - } - - /* Pass 2: process columns. */ - /* Note that we must descale the results by a factor of 8 == 2**3, */ - /* and also undo the PASS1_BITS scaling. */ - - dataptr = data; - for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) { - /* Columns of zeroes can be exploited in the same way as we did with rows. - * However, the row calculation has created many nonzero AC terms, so the - * simplification applies less often (typically 5% to 10% of the time). - * On machines with very fast multiplication, it's possible that the - * test takes more time than it's worth. In that case this section - * may be commented out. - */ - - d0 = dataptr[DCTSTRIDE*0]; - d2 = dataptr[DCTSTRIDE*1]; - d4 = dataptr[DCTSTRIDE*2]; - d6 = dataptr[DCTSTRIDE*3]; - - /* Even part: reverse the even part of the forward DCT. */ - /* The rotator is sqrt(2)*c(-6). */ - if (d6) { - if (d2) { - /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */ - z1 = MULTIPLY(d2 + d6, FIX_0_541196100); - tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065); - tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } else { - /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */ - tmp2 = MULTIPLY(-d6, FIX_1_306562965); - tmp3 = MULTIPLY(d6, FIX_0_541196100); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } - } else { - if (d2) { - /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */ - tmp2 = MULTIPLY(d2, FIX_0_541196100); - tmp3 = MULTIPLY(d2, FIX_1_306562965); - - tmp0 = (d0 + d4) << CONST_BITS; - tmp1 = (d0 - d4) << CONST_BITS; - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - } else { - /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */ - tmp10 = tmp13 = (d0 + d4) << CONST_BITS; - tmp11 = tmp12 = (d0 - d4) << CONST_BITS; - } - } - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - dataptr[DCTSTRIDE*0] = tmp10 >> (CONST_BITS+PASS1_BITS+3); - dataptr[DCTSTRIDE*1] = tmp11 >> (CONST_BITS+PASS1_BITS+3); - dataptr[DCTSTRIDE*2] = tmp12 >> (CONST_BITS+PASS1_BITS+3); - dataptr[DCTSTRIDE*3] = tmp13 >> (CONST_BITS+PASS1_BITS+3); - - dataptr++; /* advance pointer to next column */ - } -} - -void j_rev_dct2(DCTBLOCK data){ - int d00, d01, d10, d11; - - data[0] += 4; - d00 = data[0+0*DCTSTRIDE] + data[1+0*DCTSTRIDE]; - d01 = data[0+0*DCTSTRIDE] - data[1+0*DCTSTRIDE]; - d10 = data[0+1*DCTSTRIDE] + data[1+1*DCTSTRIDE]; - d11 = data[0+1*DCTSTRIDE] - data[1+1*DCTSTRIDE]; - - data[0+0*DCTSTRIDE]= (d00 + d10)>>3; - data[1+0*DCTSTRIDE]= (d01 + d11)>>3; - data[0+1*DCTSTRIDE]= (d00 - d10)>>3; - data[1+1*DCTSTRIDE]= (d01 - d11)>>3; -} - -void j_rev_dct1(DCTBLOCK data){ - data[0] = (data[0] + 4)>>3; -} - -#undef FIX -#undef CONST_BITS diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/mpegvideo.h --- a/src/ffmpeg/libavcodec/mpegvideo.h Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,943 +0,0 @@ -/* - * Generic DCT based hybrid video encoder - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. - * Copyright (c) 2002-2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file mpegvideo.h - * mpegvideo header. - */ - -#ifndef AVCODEC_MPEGVIDEO_H -#define AVCODEC_MPEGVIDEO_H - -#include "dsputil.h" -#include "bitstream.h" -#include "ratecontrol.h" - -#define FRAME_SKIPPED 100 ///< return value for header parsers if frame is not coded - -enum OutputFormat { - FMT_MPEG1, - FMT_H261, - FMT_H263, - FMT_MJPEG, - FMT_H264, -}; - -#define EDGE_WIDTH 16 - -#define MPEG_BUF_SIZE (16 * 1024) - -#define QMAT_SHIFT_MMX 16 -#define QMAT_SHIFT 22 - -#define MAX_FCODE 7 -#define MAX_MV 2048 - -#define MAX_THREADS 8 - -#define MAX_PICTURE_COUNT 32 - -#define ME_MAP_SIZE 64 -#define ME_MAP_SHIFT 3 -#define ME_MAP_MV_BITS 11 - -/* run length table */ -#define MAX_RUN 64 -#define MAX_LEVEL 64 - -#define I_TYPE FF_I_TYPE ///< Intra -#define P_TYPE FF_P_TYPE ///< Predicted -#define B_TYPE FF_B_TYPE ///< Bi-dir predicted -#define S_TYPE FF_S_TYPE ///< S(GMC)-VOP MPEG4 -#define SI_TYPE FF_SI_TYPE ///< Switching Intra -#define SP_TYPE FF_SP_TYPE ///< Switching Predicted - -#define MAX_MB_BYTES (30*16*16*3/8 + 120) - -#define INPLACE_OFFSET 16 - -/** - * Scantable. - */ -typedef struct ScanTable{ - const uint8_t *scantable; - uint8_t permutated[64]; - uint8_t raster_end[64]; -#ifdef ARCH_POWERPC - /** Used by dct_quantise_alitvec to find last-non-zero */ - DECLARE_ALIGNED_8(uint8_t, inverse[64]); -#endif -} ScanTable; - -/** - * Picture. - */ -typedef struct Picture{ - FF_COMMON_FRAME - - /** - * halfpel luma planes. - */ - uint8_t *interpolated[3]; - int16_t (*motion_val_base[2])[2]; - uint32_t *mb_type_base; -#define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if theres just one type -#define IS_INTRA4x4(a) ((a)&MB_TYPE_INTRA4x4) -#define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16) -#define IS_PCM(a) ((a)&MB_TYPE_INTRA_PCM) -#define IS_INTRA(a) ((a)&7) -#define IS_INTER(a) ((a)&(MB_TYPE_16x16|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8)) -#define IS_SKIP(a) ((a)&MB_TYPE_SKIP) -#define IS_INTRA_PCM(a) ((a)&MB_TYPE_INTRA_PCM) -#define IS_INTERLACED(a) ((a)&MB_TYPE_INTERLACED) -#define IS_DIRECT(a) ((a)&MB_TYPE_DIRECT2) -#define IS_GMC(a) ((a)&MB_TYPE_GMC) -#define IS_16X16(a) ((a)&MB_TYPE_16x16) -#define IS_16X8(a) ((a)&MB_TYPE_16x8) -#define IS_8X16(a) ((a)&MB_TYPE_8x16) -#define IS_8X8(a) ((a)&MB_TYPE_8x8) -#define IS_SUB_8X8(a) ((a)&MB_TYPE_16x16) //note reused -#define IS_SUB_8X4(a) ((a)&MB_TYPE_16x8) //note reused -#define IS_SUB_4X8(a) ((a)&MB_TYPE_8x16) //note reused -#define IS_SUB_4X4(a) ((a)&MB_TYPE_8x8) //note reused -#define IS_ACPRED(a) ((a)&MB_TYPE_ACPRED) -#define IS_QUANT(a) ((a)&MB_TYPE_QUANT) -#define IS_DIR(a, part, list) ((a) & (MB_TYPE_P0L0<<((part)+2*(list)))) -#define USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0|MB_TYPE_P1L0)<<(2*(list)))) ///< does this mb use listX, note doesnt work if subMBs -#define HAS_CBP(a) ((a)&MB_TYPE_CBP) - - int field_poc[2]; ///< h264 top/bottom POC - int poc; ///< h264 frame POC - int frame_num; ///< h264 frame_num - int pic_id; ///< h264 pic_num or long_term_pic_idx - int long_ref; ///< 1->long term reference 0->short term reference - int ref_poc[2][16]; ///< h264 POCs of the frames used as reference - int ref_count[2]; ///< number of entries in ref_poc - - int mb_var_sum; ///< sum of MB variance for current frame - int mc_mb_var_sum; ///< motion compensated MB variance for current frame - uint16_t *mb_var; ///< Table for MB variances - uint16_t *mc_mb_var; ///< Table for motion compensated MB variances - uint8_t *mb_mean; ///< Table for MB luminance - int32_t *mb_cmp_score; ///< Table for MB cmp scores, for mb decision FIXME remove - int b_frame_score; /* */ -} Picture; - -typedef struct ParseContext{ - uint8_t *buffer; - int index; - int last_index; - unsigned int buffer_size; - uint32_t state; ///< contains the last few bytes in MSB order - int frame_start_found; - int overread; ///< the number of bytes which where irreversibly read from the next frame - int overread_index; ///< the index into ParseContext.buffer of the overreaded bytes -} ParseContext; - -struct MpegEncContext; - -/** - * Motion estimation context. - */ -typedef struct MotionEstContext{ - AVCodecContext *avctx; - int skip; ///< set if ME is skipped for the current MB - int co_located_mv[4][2]; ///< mv from last p frame for direct mode ME - int direct_basis_mv[4][2]; - uint8_t *scratchpad; ///< data area for the me algo, so that the ME doesnt need to malloc/free - uint8_t *best_mb; - uint8_t *temp_mb[2]; - uint8_t *temp; - int best_bits; - uint32_t *map; ///< map to avoid duplicate evaluations - uint32_t *score_map; ///< map to store the scores - int map_generation; - int pre_penalty_factor; - int penalty_factor; - int sub_penalty_factor; - int mb_penalty_factor; - int flags; - int sub_flags; - int mb_flags; - int pre_pass; ///< = 1 for the pre pass - int dia_size; - int xmin; - int xmax; - int ymin; - int ymax; - int pred_x; - int pred_y; - uint8_t *src[4][4]; - uint8_t *ref[4][4]; - int stride; - int uvstride; - /* temp variables for picture complexity calculation */ - int mc_mb_var_sum_temp; - int mb_var_sum_temp; - int scene_change_score; -/* cmp, chroma_cmp;*/ - op_pixels_func (*hpel_put)[4]; - op_pixels_func (*hpel_avg)[4]; - qpel_mc_func (*qpel_put)[16]; - qpel_mc_func (*qpel_avg)[16]; - uint8_t (*mv_penalty)[MAX_MV*2+1]; ///< amount of bits needed to encode a MV - uint8_t *current_mv_penalty; - int (*sub_motion_search)(struct MpegEncContext * s, - int *mx_ptr, int *my_ptr, int dmin, - int src_index, int ref_index, - int size, int h); -}MotionEstContext; - -/** - * MpegEncContext. - */ -typedef struct MpegEncContext { - struct AVCodecContext *avctx; - /* the following parameters must be initialized before encoding */ - int width, height;///< picture size. must be a multiple of 16 - int gop_size; - int intra_only; ///< if true, only intra pictures are generated - int bit_rate; ///< wanted bit rate - enum OutputFormat out_format; ///< output format - int h263_pred; ///< use mpeg4/h263 ac/dc predictions - -/* the following codec id fields are deprecated in favor of codec_id */ - int h263_plus; ///< h263 plus headers - int h263_msmpeg4; ///< generate MSMPEG4 compatible stream (deprecated, use msmpeg4_version instead) - int h263_flv; ///< use flv h263 header - - enum CodecID codec_id; /* see CODEC_ID_xxx */ - int fixed_qscale; ///< fixed qscale if non zero - int encoding; ///< true if we are encoding (vs decoding) - int flags; ///< AVCodecContext.flags (HQ, MV4, ...) - int flags2; ///< AVCodecContext.flags2 - int max_b_frames; ///< max number of b-frames for encoding - int luma_elim_threshold; - int chroma_elim_threshold; - int strict_std_compliance; ///< strictly follow the std (MPEG4, ...) - int workaround_bugs; ///< workaround bugs in encoders which cannot be detected automatically - /* the following fields are managed internally by the encoder */ - - /** bit output */ - PutBitContext pb; - - /* sequence parameters */ - int context_initialized; - int input_picture_number; ///< used to set pic->display_picture_number, shouldnt be used for/by anything else - int coded_picture_number; ///< used to set pic->coded_picture_number, shouldnt be used for/by anything else - int picture_number; //FIXME remove, unclear definition - int picture_in_gop_number; ///< 0-> first pic in gop, ... - int b_frames_since_non_b; ///< used for encoding, relative to not yet reordered input - int64_t user_specified_pts;///< last non zero pts from AVFrame which was passed into avcodec_encode_video() - int mb_width, mb_height; ///< number of MBs horizontally & vertically - int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressing of left & top MBs without sig11 - int b8_stride; ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressing - int b4_stride; ///< 4*mb_width+1 used for some 4x4 block arrays to allow simple addressing - int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replication) - int mb_num; ///< number of MBs of a picture - int linesize; ///< line size, in bytes, may be different from width - int uvlinesize; ///< line size, for chroma in bytes, may be different from width - Picture *picture; ///< main picture buffer - Picture **input_picture; ///< next pictures on display order for encoding - Picture **reordered_input_picture; ///< pointer to the next pictures in codedorder for encoding - - int start_mb_y; ///< start mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y) - int end_mb_y; ///< end mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y) - struct MpegEncContext *thread_context[MAX_THREADS]; - - /** - * copy of the previous picture structure. - * note, linesize & data, might not match the previous picture (for field pictures) - */ - Picture last_picture; - - /** - * copy of the next picture structure. - * note, linesize & data, might not match the next picture (for field pictures) - */ - Picture next_picture; - - /** - * copy of the source picture structure for encoding. - * note, linesize & data, might not match the source picture (for field pictures) - */ - Picture new_picture; - - /** - * copy of the current picture structure. - * note, linesize & data, might not match the current picture (for field pictures) - */ - Picture current_picture; ///< buffer to store the decompressed current picture - - Picture *last_picture_ptr; ///< pointer to the previous picture. - Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred) - Picture *current_picture_ptr; ///< pointer to the current picture - uint8_t *visualization_buffer[3]; //< temporary buffer vor MV visualization - int last_dc[3]; ///< last DC values for MPEG1 - int16_t *dc_val_base; - int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous - int16_t dc_cache[4*5]; - int y_dc_scale, c_dc_scale; - const uint8_t *y_dc_scale_table; ///< qscale -> y_dc_scale table - const uint8_t *c_dc_scale_table; ///< qscale -> c_dc_scale table - const uint8_t *chroma_qscale_table; ///< qscale -> chroma_qscale (h263) - uint8_t *coded_block_base; - uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1) - int16_t (*ac_val_base)[16]; - int16_t (*ac_val[3])[16]; ///< used for for mpeg4 AC prediction, all 3 arrays must be continuous - int ac_pred; - uint8_t *prev_pict_types; ///< previous picture types in bitstream order, used for mb skip -#define PREV_PICT_TYPES_BUFFER_SIZE 256 - int mb_skipped; ///< MUST BE SET only during DECODING - uint8_t *mbskip_table; /**< used to avoid copy if macroblock skipped (for black regions for example) - and used for b-frame encoding & decoding (contains skip table of next P Frame) */ - uint8_t *mbintra_table; ///< used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding - uint8_t *cbp_table; ///< used to store cbp, ac_pred for partitioned decoding - uint8_t *pred_dir_table; ///< used to store pred_dir for partitioned decoding - uint8_t *allocated_edge_emu_buffer; - uint8_t *edge_emu_buffer; ///< points into the middle of allocated_edge_emu_buffer - uint8_t *rd_scratchpad; ///< scratchpad for rate distortion mb decision - uint8_t *obmc_scratchpad; - uint8_t *b_scratchpad; ///< scratchpad used for writing into write only buffers - - int qscale; ///< QP - int chroma_qscale; ///< chroma QP - int lambda; ///< lagrange multipler used in rate distortion - int lambda2; ///< (lambda*lambda) >> FF_LAMBDA_SHIFT - int *lambda_table; - int adaptive_quant; ///< use adaptive quantization - int dquant; ///< qscale difference to prev qscale - int pict_type; ///< I_TYPE, P_TYPE, B_TYPE, ... - int last_pict_type; //FIXME removes - int last_non_b_pict_type; ///< used for mpeg4 gmc b-frames & ratecontrol - int dropable; - int frame_rate_index; - int last_lambda_for[5]; ///< last lambda for a specific pict type - - /* motion compensation */ - int unrestricted_mv; ///< mv can point outside of the coded picture - int h263_long_vectors; ///< use horrible h263v1 long vector mode - int decode; ///< if 0 then decoding will be skipped (for encoding b frames for example) - - DSPContext dsp; ///< pointers for accelerated dsp functions - int f_code; ///< forward MV resolution - int b_code; ///< backward MV resolution for B Frames (mpeg4) - int16_t (*p_mv_table_base)[2]; - int16_t (*b_forw_mv_table_base)[2]; - int16_t (*b_back_mv_table_base)[2]; - int16_t (*b_bidir_forw_mv_table_base)[2]; - int16_t (*b_bidir_back_mv_table_base)[2]; - int16_t (*b_direct_mv_table_base)[2]; - int16_t (*p_field_mv_table_base[2][2])[2]; - int16_t (*b_field_mv_table_base[2][2][2])[2]; - int16_t (*p_mv_table)[2]; ///< MV table (1MV per MB) p-frame encoding - int16_t (*b_forw_mv_table)[2]; ///< MV table (1MV per MB) forward mode b-frame encoding - int16_t (*b_back_mv_table)[2]; ///< MV table (1MV per MB) backward mode b-frame encoding - int16_t (*b_bidir_forw_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding - int16_t (*b_bidir_back_mv_table)[2]; ///< MV table (1MV per MB) bidir mode b-frame encoding - int16_t (*b_direct_mv_table)[2]; ///< MV table (1MV per MB) direct mode b-frame encoding - int16_t (*p_field_mv_table[2][2])[2]; ///< MV table (2MV per MB) interlaced p-frame encoding - int16_t (*b_field_mv_table[2][2][2])[2];///< MV table (4MV per MB) interlaced b-frame encoding - uint8_t (*p_field_select_table[2]); - uint8_t (*b_field_select_table[2][2]); - int me_method; ///< ME algorithm - int mv_dir; -#define MV_DIR_BACKWARD 1 -#define MV_DIR_FORWARD 2 -#define MV_DIRECT 4 ///< bidirectional mode where the difference equals the MV of the last P/S/I-Frame (mpeg4) - int mv_type; -#define MV_TYPE_16X16 0 ///< 1 vector for the whole mb -#define MV_TYPE_8X8 1 ///< 4 vectors (h263, mpeg4 4MV) -#define MV_TYPE_16X8 2 ///< 2 vectors, one per 16x8 block -#define MV_TYPE_FIELD 3 ///< 2 vectors, one per field -#define MV_TYPE_DMV 4 ///< 2 vectors, special mpeg2 Dual Prime Vectors - /**motion vectors for a macroblock - first coordinate : 0 = forward 1 = backward - second " : depend on type - third " : 0 = x, 1 = y - */ - int mv[2][4][2]; - int field_select[2][2]; - int last_mv[2][2][2]; ///< last MV, used for MV prediction in MPEG1 & B-frame MPEG4 - uint8_t *fcode_tab; ///< smallest fcode needed for each MV - int16_t direct_scale_mv[2][64]; ///< precomputed to avoid divisions in ff_mpeg4_set_direct_mv - - MotionEstContext me; - - int no_rounding; /**< apply no rounding to motion compensation (MPEG4, msmpeg4, ...) - for b-frames rounding mode is allways 0 */ - - int hurry_up; /**< when set to 1 during decoding, b frames will be skipped - when set to 2 idct/dequant will be skipped too */ - - /* macroblock layer */ - int mb_x, mb_y; - int mb_skip_run; - int mb_intra; - uint16_t *mb_type; ///< Table for candidate MB types for encoding -#define CANDIDATE_MB_TYPE_INTRA 0x01 -#define CANDIDATE_MB_TYPE_INTER 0x02 -#define CANDIDATE_MB_TYPE_INTER4V 0x04 -#define CANDIDATE_MB_TYPE_SKIPPED 0x08 -//#define MB_TYPE_GMC 0x10 - -#define CANDIDATE_MB_TYPE_DIRECT 0x10 -#define CANDIDATE_MB_TYPE_FORWARD 0x20 -#define CANDIDATE_MB_TYPE_BACKWARD 0x40 -#define CANDIDATE_MB_TYPE_BIDIR 0x80 - -#define CANDIDATE_MB_TYPE_INTER_I 0x100 -#define CANDIDATE_MB_TYPE_FORWARD_I 0x200 -#define CANDIDATE_MB_TYPE_BACKWARD_I 0x400 -#define CANDIDATE_MB_TYPE_BIDIR_I 0x800 - - int block_index[6]; ///< index to current MB in block based arrays with edges - int block_wrap[6]; - uint8_t *dest[3]; - - int *mb_index2xy; ///< mb_index -> mb_x + mb_y*mb_stride - - /** matrix transmitted in the bitstream */ - uint16_t intra_matrix[64]; - uint16_t chroma_intra_matrix[64]; - uint16_t inter_matrix[64]; - uint16_t chroma_inter_matrix[64]; -#define QUANT_BIAS_SHIFT 8 - int intra_quant_bias; ///< bias for the quantizer - int inter_quant_bias; ///< bias for the quantizer - int min_qcoeff; ///< minimum encodable coefficient - int max_qcoeff; ///< maximum encodable coefficient - int ac_esc_length; ///< num of bits needed to encode the longest esc - uint8_t *intra_ac_vlc_length; - uint8_t *intra_ac_vlc_last_length; - uint8_t *inter_ac_vlc_length; - uint8_t *inter_ac_vlc_last_length; - uint8_t *luma_dc_vlc_length; - uint8_t *chroma_dc_vlc_length; -#define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level)) - - int coded_score[8]; - - /** precomputed matrix (combine qscale and DCT renorm) */ - int (*q_intra_matrix)[64]; - int (*q_inter_matrix)[64]; - /** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/ - uint16_t (*q_intra_matrix16)[2][64]; - uint16_t (*q_inter_matrix16)[2][64]; - int block_last_index[12]; ///< last non zero coefficient in block - /* scantables */ - DECLARE_ALIGNED_8(ScanTable, intra_scantable); - ScanTable intra_h_scantable; - ScanTable intra_v_scantable; - ScanTable inter_scantable; ///< if inter == intra then intra should be used to reduce tha cache usage - - /* noise reduction */ - int (*dct_error_sum)[64]; - int dct_count[2]; - uint16_t (*dct_offset)[64]; - - void *opaque; ///< private data for the user - - /* bit rate control */ - int64_t wanted_bits; - int64_t total_bits; - int frame_bits; ///< bits used for the current frame - int next_lambda; ///< next lambda used for retrying to encode a frame - RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c - - /* statistics, used for 2-pass encoding */ - int mv_bits; - int header_bits; - int i_tex_bits; - int p_tex_bits; - int i_count; - int f_count; - int b_count; - int skip_count; - int misc_bits; ///< cbp, mb_type - int last_bits; ///< temp var used for calculating the above vars - - /* error concealment / resync */ - int error_count; - uint8_t *error_status_table; ///< table of the error status of each MB -#define VP_START 1 ///< current MB is the first after a resync marker -#define AC_ERROR 2 -#define DC_ERROR 4 -#define MV_ERROR 8 -#define AC_END 16 -#define DC_END 32 -#define MV_END 64 -//FIXME some prefix? - - int resync_mb_x; ///< x position of last resync marker - int resync_mb_y; ///< y position of last resync marker - GetBitContext last_resync_gb; ///< used to search for the next resync marker - int mb_num_left; ///< number of MBs left in this video packet (for partitioned Slices only) - int next_p_frame_damaged; ///< set if the next p frame is damaged, to avoid showing trashed b frames - int error_resilience; - - ParseContext parse_context; - - /* H.263 specific */ - int gob_index; - int obmc; ///< overlapped block motion compensation - - /* H.263+ specific */ - int umvplus; ///< == H263+ && unrestricted_mv - int h263_aic; ///< Advanded INTRA Coding (AIC) - int h263_aic_dir; ///< AIC direction: 0 = left, 1 = top - int h263_slice_structured; - int alt_inter_vlc; ///< alternative inter vlc - int modified_quant; - int loop_filter; - int custom_pcf; - - /* mpeg4 specific */ - int time_increment_bits; ///< number of bits to represent the fractional part of time - int last_time_base; - int time_base; ///< time in seconds of last I,P,S Frame - int64_t time; ///< time of current frame - int64_t last_non_b_time; - uint16_t pp_time; ///< time distance between the last 2 p,s,i frames - uint16_t pb_time; ///< time distance between the last b and p,s,i frame - uint16_t pp_field_time; - uint16_t pb_field_time; ///< like above, just for interlaced - int shape; - int vol_sprite_usage; - int sprite_width; - int sprite_height; - int sprite_left; - int sprite_top; - int sprite_brightness_change; - int num_sprite_warping_points; - int real_sprite_warping_points; - int sprite_offset[2][2]; ///< sprite offset[isChroma][isMVY] - int sprite_delta[2][2]; ///< sprite_delta [isY][isMVY] - int sprite_shift[2]; ///< sprite shift [isChroma] - int mcsel; - int quant_precision; - int quarter_sample; ///< 1->qpel, 0->half pel ME/MC - int scalability; - int hierachy_type; - int enhancement_type; - int new_pred; - int reduced_res_vop; - int aspect_ratio_info; //FIXME remove - int sprite_warping_accuracy; - int low_latency_sprite; - int data_partitioning; ///< data partitioning flag from header - int partitioned_frame; ///< is current frame partitioned - int rvlc; ///< reversible vlc - int resync_marker; ///< could this stream contain resync markers - int low_delay; ///< no reordering needed / has no b-frames - int vo_type; - int vol_control_parameters; ///< does the stream contain the low_delay flag, used to workaround buggy encoders - int intra_dc_threshold; ///< QP above whch the ac VLC should be used for intra dc - int use_intra_dc_vlc; - PutBitContext tex_pb; ///< used for data partitioned VOPs - PutBitContext pb2; ///< used for data partitioned VOPs - int mpeg_quant; - int t_frame; ///< time distance of first I -> B, used for interlaced b frames - int padding_bug_score; ///< used to detect the VERY common padding bug in MPEG4 - - /* divx specific, used to workaround (many) bugs in divx5 */ - int divx_version; - int divx_build; - int divx_packed; - uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them - int bitstream_buffer_size; - unsigned int allocated_bitstream_buffer_size; - - int xvid_build; - - /* lavc specific stuff, used to workaround bugs in libavcodec */ - int lavc_build; - - /* RV10 specific */ - int rv10_version; ///< RV10 version: 0 or 3 - int rv10_first_dc_coded[3]; - - /* MJPEG specific */ - struct MJpegContext *mjpeg_ctx; - int mjpeg_vsample[3]; ///< vertical sampling factors, default = {2, 1, 1} - int mjpeg_hsample[3]; ///< horizontal sampling factors, default = {2, 1, 1} - int mjpeg_write_tables; ///< do we want to have quantisation- and huffmantables in the jpeg file ? - int mjpeg_data_only_frames; ///< frames only with SOI, SOS and EOI markers - - /* MSMPEG4 specific */ - int mv_table_index; - int rl_table_index; - int rl_chroma_table_index; - int dc_table_index; - int use_skip_mb_code; - int slice_height; ///< in macroblocks - int first_slice_line; ///< used in mpeg4 too to handle resync markers - int flipflop_rounding; - int msmpeg4_version; ///< 0=not msmpeg4, 1=mp41, 2=mp42, 3=mp43/divx3 4=wmv1/7 5=wmv2/8 - int per_mb_rl_table; - int esc3_level_length; - int esc3_run_length; - /** [mb_intra][isChroma][level][run][last] */ - int (*ac_stats)[2][MAX_LEVEL+1][MAX_RUN+1][2]; - int inter_intra_pred; - int mspel; - - /* decompression specific */ - GetBitContext gb; - - /* Mpeg1 specific */ - int gop_picture_number; ///< index of the first picture of a GOP based on fake_pic_num & mpeg1 specific - int last_mv_dir; ///< last mv_dir, used for b frame encoding - int broken_link; ///< no_output_of_prior_pics_flag - uint8_t *vbv_delay_ptr; ///< pointer to vbv_delay in the bitstream - - /* MPEG2 specific - I wish I had not to support this mess. */ - int progressive_sequence; - int mpeg_f_code[2][2]; - int picture_structure; -/* picture type */ -#define PICT_TOP_FIELD 1 -#define PICT_BOTTOM_FIELD 2 -#define PICT_FRAME 3 - - int intra_dc_precision; - int frame_pred_frame_dct; - int top_field_first; - int concealment_motion_vectors; - int q_scale_type; - int intra_vlc_format; - int alternate_scan; - int repeat_first_field; - int chroma_420_type; - int chroma_format; -#define CHROMA_420 1 -#define CHROMA_422 2 -#define CHROMA_444 3 - int chroma_x_shift;//depend on pix_format, that depend on chroma_format - int chroma_y_shift; - - int progressive_frame; - int full_pel[2]; - int interlaced_dct; - int first_slice; - int first_field; ///< is 1 for the first field of a field picture 0 otherwise - - /* RTP specific */ - int rtp_mode; - - uint8_t *ptr_lastgob; - int swap_uv;//vcr2 codec is mpeg2 varint with UV swaped - short * pblocks[12]; - - DCTELEM (*block)[64]; ///< points to one of the following blocks - DCTELEM (*blocks)[8][64]; // for HQ mode we need to keep the best block - int (*decode_mb)(struct MpegEncContext *s, DCTELEM block[6][64]); // used by some codecs to avoid a switch() -#define SLICE_OK 0 -#define SLICE_ERROR -1 -#define SLICE_END -2 ///>s->avctx->lowres; - - s->block_index[0]+=2; - s->block_index[1]+=2; - s->block_index[2]+=2; - s->block_index[3]+=2; - s->block_index[4]++; - s->block_index[5]++; - s->dest[0]+= 2*block_size; - s->dest[1]+= block_size; - s->dest[2]+= block_size; -} - -static inline int get_bits_diff(MpegEncContext *s){ - const int bits= put_bits_count(&s->pb); - const int last= s->last_bits; - - s->last_bits = bits; - - return bits - last; -} - -/* motion_est.c */ -void ff_estimate_p_frame_motion(MpegEncContext * s, - int mb_x, int mb_y); -void ff_estimate_b_frame_motion(MpegEncContext * s, - int mb_x, int mb_y); -int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type); -void ff_fix_long_p_mvs(MpegEncContext * s); -void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_select, - int16_t (*mv_table)[2], int f_code, int type, int truncate); -void ff_init_me(MpegEncContext *s); -int ff_pre_estimate_p_frame_motion(MpegEncContext * s, int mb_x, int mb_y); -inline int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, - int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2], - int ref_mv_scale, int size, int h); -inline int ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index, - int ref_index, int size, int h, int add_rate); - -/* mpeg12.c */ -extern const uint16_t ff_mpeg1_default_intra_matrix[64]; -extern const uint16_t ff_mpeg1_default_non_intra_matrix[64]; -extern const uint8_t ff_mpeg1_dc_scale_table[128]; - -void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number); -void mpeg1_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void ff_mpeg1_encode_init(MpegEncContext *s); -void ff_mpeg1_encode_slice_header(MpegEncContext *s); -void ff_mpeg1_clean_buffers(MpegEncContext *s); -int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size); - - -/** RLTable. */ -typedef struct RLTable { - int n; ///< number of entries of table_vlc minus 1 - int last; ///< number of values for last = 0 - const uint16_t (*table_vlc)[2]; - const int8_t *table_run; - const int8_t *table_level; - uint8_t *index_run[2]; ///< encoding only - int8_t *max_level[2]; ///< encoding & decoding - int8_t *max_run[2]; ///< encoding & decoding - VLC vlc; ///< decoding only deprected FIXME remove - RL_VLC_ELEM *rl_vlc[32]; ///< decoding only -} RLTable; - -void init_rl(RLTable *rl, int use_static); -void init_vlc_rl(RLTable *rl, int use_static); - -static inline int get_rl_index(const RLTable *rl, int last, int run, int level) -{ - int index; - index = rl->index_run[last][run]; - if (index >= rl->n) - return rl->n; - if (level > rl->max_level[last][run]) - return rl->n; - return index + level - 1; -} - -extern const uint8_t ff_mpeg4_y_dc_scale_table[32]; -extern const uint8_t ff_mpeg4_c_dc_scale_table[32]; -extern const uint8_t ff_aic_dc_scale_table[32]; -extern const int16_t ff_mpeg4_default_intra_matrix[64]; -extern const int16_t ff_mpeg4_default_non_intra_matrix[64]; -extern const uint8_t ff_h263_chroma_qscale_table[32]; -extern const uint8_t ff_h263_loop_filter_strength[32]; - -/* h261.c */ -void ff_h261_loop_filter(MpegEncContext *s); -void ff_h261_reorder_mb_index(MpegEncContext* s); -void ff_h261_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number); -void ff_h261_encode_init(MpegEncContext *s); - - -/* h263.c, h263dec.c */ -int ff_h263_decode_init(AVCodecContext *avctx); -int ff_h263_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size); -int ff_h263_decode_end(AVCodecContext *avctx); -void h263_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void mpeg4_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void h263_encode_picture_header(MpegEncContext *s, int picture_number); -void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number); -void h263_encode_gob_header(MpegEncContext * s, int mb_line); -int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir, - int *px, int *py); -void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, - int dir); -void ff_set_mpeg4_time(MpegEncContext * s, int picture_number); -void mpeg4_encode_picture_header(MpegEncContext *s, int picture_number); -#ifdef CONFIG_ENCODERS -void h263_encode_init(MpegEncContext *s); -#else -static void h263_encode_init(MpegEncContext *s) {assert(0);} -#endif -void h263_decode_init_vlc(MpegEncContext *s); -int h263_decode_picture_header(MpegEncContext *s); -int ff_h263_decode_gob_header(MpegEncContext *s); -int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb); -void ff_h263_update_motion_val(MpegEncContext * s); -void ff_h263_loop_filter(MpegEncContext * s); -void ff_set_qscale(MpegEncContext * s, int qscale); -int ff_h263_decode_mba(MpegEncContext *s); -void ff_h263_encode_mba(MpegEncContext *s); - -int intel_h263_decode_picture_header(MpegEncContext *s); -int flv_h263_decode_picture_header(MpegEncContext *s); -int ff_h263_decode_mb(MpegEncContext *s, - DCTELEM block[6][64]); -int ff_mpeg4_decode_mb(MpegEncContext *s, - DCTELEM block[6][64]); -int h263_get_picture_format(int width, int height); -void ff_mpeg4_encode_video_packet_header(MpegEncContext *s); -void ff_mpeg4_clean_buffers(MpegEncContext *s); -void ff_mpeg4_stuffing(PutBitContext * pbc); -void ff_mpeg4_init_partitions(MpegEncContext *s); -void ff_mpeg4_merge_partitions(MpegEncContext *s); -void ff_clean_mpeg4_qscales(MpegEncContext *s); -void ff_clean_h263_qscales(MpegEncContext *s); -int ff_mpeg4_decode_partitions(MpegEncContext *s); -int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s); -int ff_h263_resync(MpegEncContext *s); -int ff_h263_get_gob_height(MpegEncContext *s); -void ff_mpeg4_init_direct_mv(MpegEncContext *s); -int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my); -int ff_h263_round_chroma(int x); -void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code); -int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size); - - -/* rv10.c */ -void rv10_encode_picture_header(MpegEncContext *s, int picture_number); -int rv_decode_dc(MpegEncContext *s, int n); -void rv20_encode_picture_header(MpegEncContext *s, int picture_number); - - -/* msmpeg4.c */ -void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number); -void msmpeg4_encode_ext_header(MpegEncContext * s); -void msmpeg4_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y); -int msmpeg4_decode_picture_header(MpegEncContext * s); -int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size); -int ff_msmpeg4_decode_init(MpegEncContext *s); -void ff_msmpeg4_encode_init(MpegEncContext *s); -int ff_wmv2_decode_picture_header(MpegEncContext * s); -int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s); -void ff_wmv2_add_mb(MpegEncContext *s, DCTELEM block[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr); -void ff_mspel_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - int motion_x, int motion_y, int h); -int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number); -void ff_wmv2_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y); - -/* mjpeg.c */ -int mjpeg_init(MpegEncContext *s); -void mjpeg_close(MpegEncContext *s); -void mjpeg_encode_mb(MpegEncContext *s, - DCTELEM block[6][64]); -void mjpeg_picture_header(MpegEncContext *s); -void mjpeg_picture_trailer(MpegEncContext *s); -void ff_mjpeg_stuffing(PutBitContext * pbc); - -/* cavs.c */ -int ff_cavs_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size); - -#endif /* AVCODEC_MPEGVIDEO_H */ - diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/rtjpeg.c --- a/src/ffmpeg/libavcodec/rtjpeg.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,164 +0,0 @@ -/* - * RTJpeg decoding functions - * Copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "common.h" -#include "bitstream.h" -#include "dsputil.h" -#include "rtjpeg.h" - -#define PUT_COEFF(c) \ - i = scan[coeff--]; \ - block[i] = (c) * quant[i]; - -//! aligns the bitstream to the give power of two -#define ALIGN(a) \ - n = (-get_bits_count(gb)) & (a - 1); \ - if (n) {skip_bits(gb, n);} - -/** - * \brief read one block from stream - * \param gb contains stream data - * \param block where data is written to - * \param scan array containing the mapping stream address -> block position - * \param quant quantization factors - * - * Note: GetBitContext is used to make the code simpler, since all data is - * aligned this could be done faster in a different way, e.g. as it is done - * in MPlayer libmpcodecs/native/RTjpegN.c - */ -static inline int get_block(GetBitContext *gb, DCTELEM *block, uint8_t *scan, - uint32_t *quant) { - int coeff, i, n; - int8_t ac; - uint8_t dc = get_bits(gb, 8); - - // block not coded - if (dc == 255) - return 0; - - // number of non-zero coefficients - coeff = get_bits(gb, 6); - // normally we would only need to clear the (63 - coeff) last values, - // but since we do not know where they are we just clear the whole block - memset(block, 0, 64 * sizeof(DCTELEM)); - - // 2 bits per coefficient - while (coeff) { - ac = get_sbits(gb, 2); - if (ac == -2) - break; // continue with more bits - PUT_COEFF(ac); - } - - // 4 bits per coefficient - ALIGN(4); - while (coeff) { - ac = get_sbits(gb, 4); - if (ac == -8) - break; // continue with more bits - PUT_COEFF(ac); - } - - // 8 bits per coefficient - ALIGN(8); - while (coeff) { - ac = get_sbits(gb, 8); - PUT_COEFF(ac); - } - - PUT_COEFF(dc); - return 1; -} - -/** - * \brief decode one rtjpeg YUV420 frame - * \param c context, must be initialized via rtjpeg_decode_init - * \param f AVFrame to place decoded frame into. If parts of the frame - * are not coded they are left unchanged, so consider initializing it - * \param buf buffer containing input data - * \param buf_size length of input data in bytes - * \return number of bytes consumed from the input buffer - */ -int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, - uint8_t *buf, int buf_size) { - GetBitContext gb; - int w = c->w / 16, h = c->h / 16; - int x, y; - void *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0]; - void *u = f->data[1], *v = f->data[2]; - init_get_bits(&gb, buf, buf_size * 8); - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - if (get_block(&gb, c->block, c->scan, c->lquant)) - c->dsp->idct_put(y1, f->linesize[0], c->block); - y1 += 8; - if (get_block(&gb, c->block, c->scan, c->lquant)) - c->dsp->idct_put(y1, f->linesize[0], c->block); - y1 += 8; - if (get_block(&gb, c->block, c->scan, c->lquant)) - c->dsp->idct_put(y2, f->linesize[0], c->block); - y2 += 8; - if (get_block(&gb, c->block, c->scan, c->lquant)) - c->dsp->idct_put(y2, f->linesize[0], c->block); - y2 += 8; - if (get_block(&gb, c->block, c->scan, c->cquant)) - c->dsp->idct_put(u, f->linesize[1], c->block); - u += 8; - if (get_block(&gb, c->block, c->scan, c->cquant)) - c->dsp->idct_put(v, f->linesize[2], c->block); - v += 8; - } - y1 += 2 * 8 * (f->linesize[0] - w); - y2 += 2 * 8 * (f->linesize[0] - w); - u += 8 * (f->linesize[1] - w); - v += 8 * (f->linesize[2] - w); - } - return get_bits_count(&gb) / 8; -} - -/** - * \brief initialize an RTJpegContext, may be called multiple times - * \param c context to initialize - * \param dsp specifies the idct to use for decoding - * \param width width of image, will be rounded down to the nearest multiple - * of 16 for decoding - * \param height height of image, will be rounded down to the nearest multiple - * of 16 for decoding - * \param lquant luma quantization table to use - * \param cquant chroma quantization table to use - */ -void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp, - int width, int height, - uint32_t *lquant, uint32_t *cquant) { - int i; - c->dsp = dsp; - for (i = 0; i < 64; i++) { - int z = ff_zigzag_direct[i]; - int p = c->dsp->idct_permutation[i]; - z = ((z << 3) | (z >> 3)) & 63; // rtjpeg uses a transposed variant - - // permute the scan and quantization tables for the chosen idct - c->scan[i] = c->dsp->idct_permutation[z]; - c->lquant[p] = lquant[i]; - c->cquant[p] = cquant[i]; - } - c->w = width; - c->h = height; -} diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/targa.c --- a/src/ffmpeg/libavcodec/targa.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,244 +0,0 @@ -/* - * Targa (.tga) image decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#include "avcodec.h" - -enum TargaCompr{ - TGA_NODATA = 0, // no image data - TGA_PAL = 1, // palettized - TGA_RGB = 2, // true-color - TGA_BW = 3, // black & white or grayscale - TGA_RLE = 8, // flag pointing that data is RLE-coded -}; - -typedef struct TargaContext { - AVFrame picture; - - int width, height; - int bpp; - int color_type; - int compression_type; -} TargaContext; - -static void targa_decode_rle(AVCodecContext *avctx, TargaContext *s, uint8_t *src, uint8_t *dst, int w, int h, int stride, int bpp) -{ - int i, x, y; - int depth = (bpp + 1) >> 3; - int type, count; - int diff; - - diff = stride - w * depth; - x = y = 0; - while(y < h){ - type = *src++; - count = (type & 0x7F) + 1; - type &= 0x80; - if((x + count > w) && (x + count + 1 > (h - y) * w)){ - av_log(avctx, AV_LOG_ERROR, "Packet went out of bounds: position (%i,%i) size %i\n", x, y, count); - return; - } - for(i = 0; i < count; i++){ - switch(depth){ - case 1: - *dst = *src; - break; - case 2: - *((uint16_t*)dst) = LE_16(src); - break; - case 3: - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - break; - } - dst += depth; - if(!type) - src += depth; - - x++; - if(x == w){ - x = 0; - y++; - dst += diff; - } - } - if(type) - src += depth; - } -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - TargaContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; - uint8_t *dst; - int stride; - int idlen, pal, compr, x, y, w, h, bpp, flags; - int first_clr, colors, csize; - - /* parse image header */ - idlen = *buf++; - pal = *buf++; - compr = *buf++; - first_clr = LE_16(buf); buf += 2; - colors = LE_16(buf); buf += 2; - csize = *buf++; - x = LE_16(buf); buf += 2; - y = LE_16(buf); buf += 2; - w = LE_16(buf); buf += 2; - h = LE_16(buf); buf += 2; - bpp = *buf++; - flags = *buf++; - //skip identifier if any - buf += idlen; - s->bpp = bpp; - s->width = w; - s->height = h; - switch(s->bpp){ - case 8: - avctx->pix_fmt = ((compr & (~TGA_RLE)) == TGA_BW) ? PIX_FMT_GRAY8 : PIX_FMT_PAL8; - break; - case 15: - avctx->pix_fmt = PIX_FMT_RGB555; - break; - case 16: - avctx->pix_fmt = PIX_FMT_RGB555; - break; - case 24: - avctx->pix_fmt = PIX_FMT_BGR24; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Bit depth %i is not supported\n", avctx->bits_per_sample); - return -1; - } - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - if(avcodec_check_dimensions(avctx, w, h)) - return -1; - if(w != avctx->width || h != avctx->height) - avcodec_set_dimensions(avctx, w, h); - if(avctx->get_buffer(avctx, p) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - if(flags & 0x20){ - dst = p->data[0]; - stride = p->linesize[0]; - }else{ //image is upside-down - dst = p->data[0] + p->linesize[0] * (h - 1); - stride = -p->linesize[0]; - } - - if(avctx->pix_fmt == PIX_FMT_PAL8 && avctx->palctrl){ - memcpy(p->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); - if(avctx->palctrl->palette_changed){ - p->palette_has_changed = 1; - avctx->palctrl->palette_changed = 0; - } - } - if(colors){ - if((colors + first_clr) > 256){ - av_log(avctx, AV_LOG_ERROR, "Incorrect palette: %i colors with offset %i\n", colors, first_clr); - return -1; - } - if(csize != 24){ - av_log(avctx, AV_LOG_ERROR, "Palette entry size %i bits is not supported\n", csize); - return -1; - } - if(avctx->pix_fmt != PIX_FMT_PAL8)//should not occur but skip palette anyway - buf += colors * ((csize + 1) >> 3); - else{ - int r, g, b, t; - int32_t *pal = ((int32_t*)p->data[1]) + first_clr; - for(t = 0; t < colors; t++){ - r = *buf++; - g = *buf++; - b = *buf++; - *pal++ = (b << 16) | (g << 8) | r; - } - p->palette_has_changed = 1; - avctx->palctrl->palette_changed = 0; - } - } - if((compr & (~TGA_RLE)) == TGA_NODATA) - memset(p->data[0], 0, p->linesize[0] * s->height); - else{ - if(compr & TGA_RLE) - targa_decode_rle(avctx, s, buf, dst, avctx->width, avctx->height, stride, bpp); - else{ - for(y = 0; y < s->height; y++){ -#ifdef WORDS_BIGENDIAN - if((s->bpp + 1) >> 3 == 2){ - uint16_t *dst16 = (uint16_t*)dst; - for(x = 0; x < s->width; x++) - dst16[x] = LE_16(buf + x * 2); - }else -#endif - memcpy(dst, buf, s->width * ((s->bpp + 1) >> 3)); - - dst += stride; - buf += s->width * ((s->bpp + 1) >> 3); - } - } - } - - *picture= *(AVFrame*)&s->picture; - *data_size = sizeof(AVPicture); - - return buf_size; -} - -static int targa_init(AVCodecContext *avctx){ - TargaContext *s = avctx->priv_data; - - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; - s->picture.data[0] = NULL; - - return 0; -} - -static int targa_end(AVCodecContext *avctx){ - TargaContext *s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - - return 0; -} - -AVCodec targa_decoder = { - "targa", - CODEC_TYPE_VIDEO, - CODEC_ID_TARGA, - sizeof(TargaContext), - targa_init, - NULL, - targa_end, - decode_frame, - 0, - NULL -}; diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/tiff.c --- a/src/ffmpeg/libavcodec/tiff.c Mon Mar 12 13:00:06 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,432 +0,0 @@ -/* - * TIFF image decoder - * Copyright (c) 2006 Konstantin Shishkov - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#include "avcodec.h" -#ifdef CONFIG_ZLIB -#include -#endif - -/* abridged list of TIFF tags */ -enum TiffTags{ - TIFF_WIDTH = 0x100, - TIFF_HEIGHT, - TIFF_BPP, - TIFF_COMPR, - TIFF_INVERT = 0x106, - TIFF_STRIP_OFFS = 0x111, - TIFF_ROWSPERSTRIP = 0x116, - TIFF_STRIP_SIZE, - TIFF_XPOS = 0x11E, - TIFF_YPOS = 0x11F, - TIFF_PREDICTOR = 0x13D -}; - -enum TiffCompr{ - TIFF_RAW = 1, - TIFF_CCITT_RLE, - TIFF_G3, - TIFF_G4, - TIFF_LZW, - TIFF_JPEG, - TIFF_NEWJPEG, - TIFF_ADOBE_DEFLATE, - TIFF_PACKBITS = 0x8005, - TIFF_DEFLATE = 0x80B2 -}; - -enum TiffTypes{ - TIFF_BYTE = 1, - TIFF_STRING, - TIFF_SHORT, - TIFF_LONG, - TIFF_LONGLONG -}; - -typedef struct TiffContext { - AVCodecContext *avctx; - AVFrame picture; - - int width, height; - unsigned int bpp; - int le; - int compr; - - int strips, rps; - int sot; - uint8_t* stripdata; - uint8_t* stripsizes; - int stripsize, stripoff; -} TiffContext; - -static int tget_short(uint8_t **p, int le){ - int v = le ? LE_16(*p) : BE_16(*p); - *p += 2; - return v; -} - -static int tget_long(uint8_t **p, int le){ - int v = le ? LE_32(*p) : BE_32(*p); - *p += 4; - return v; -} - -static int tget(uint8_t **p, int type, int le){ - switch(type){ - case TIFF_BYTE : return *(*p)++; - case TIFF_SHORT: return tget_short(p, le); - case TIFF_LONG : return tget_long (p, le); - default : return -1; - } -} - -static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, uint8_t *src, int size, int lines){ - int c, line, pixels, code; - uint8_t *ssrc = src; - int width = s->width * (s->bpp / 8); -#ifdef CONFIG_ZLIB - uint8_t *zbuf; unsigned long outlen; - - if(s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE){ - outlen = width * lines; - if(lines != s->height){ - av_log(s->avctx, AV_LOG_ERROR, "This decoder won't decode ZLib-packed TIFF with %i lines per strip\n", lines); - return -1; - } - zbuf = av_malloc(outlen); - if(uncompress(zbuf, &outlen, src, size) != Z_OK){ - av_log(s->avctx, AV_LOG_ERROR, "Uncompressing failed (%lu of %lu)\n", outlen, (unsigned long)width * lines); - av_free(zbuf); - return -1; - } - src = zbuf; - for(line = 0; line < lines; line++){ - memcpy(dst, src, width); - dst += stride; - src += width; - } - av_free(zbuf); - return 0; - } -#endif - for(line = 0; line < lines; line++){ - if(src - ssrc > size){ - av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n"); - return -1; - } - switch(s->compr){ - case TIFF_RAW: - memcpy(dst, src, s->width * (s->bpp / 8)); - src += s->width * (s->bpp / 8); - break; - case TIFF_PACKBITS: - for(pixels = 0; pixels < width;){ - code = (int8_t)*src++; - if(code >= 0){ - code++; - if(pixels + code > width){ - av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n"); - return -1; - } - memcpy(dst + pixels, src, code); - src += code; - pixels += code; - }else if(code != -128){ // -127..-1 - code = (-code) + 1; - if(pixels + code > width){ - av_log(s->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; - } - c = *src++; - memset(dst + pixels, c, code); - pixels += code; - } - } - break; - } - dst += stride; - } - return 0; -} - - -static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t *end_buf, AVFrame *pic) -{ - int tag, type, count, off, value = 0; - uint8_t *src, *dst; - int i, j, ssize, soff, stride; - - tag = tget_short(&buf, s->le); - type = tget_short(&buf, s->le); - count = tget_long(&buf, s->le); - off = tget_long(&buf, s->le); - - if(count == 1){ - switch(type){ - case TIFF_BYTE: - case TIFF_SHORT: - buf -= 4; - value = tget(&buf, type, s->le); - buf = NULL; - break; - case TIFF_LONG: - value = off; - buf = NULL; - break; - default: - value = -1; - buf = start + off; - } - }else{ - buf = start + off; - } - - if(buf && (buf < start || buf > end_buf)){ - av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); - return -1; - } - - switch(tag){ - case TIFF_WIDTH: - s->width = value; - break; - case TIFF_HEIGHT: - s->height = value; - s->avctx->pix_fmt = PIX_FMT_RGB24; - if(s->width != s->avctx->width || s->height != s->avctx->height){ - if(avcodec_check_dimensions(s->avctx, s->width, s->height)) - return -1; - avcodec_set_dimensions(s->avctx, s->width, s->height); - } - if(s->picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->picture); - if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - break; - case TIFF_BPP: - if(count == 1) s->bpp = value; - else{ - switch(type){ - case TIFF_BYTE: - s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF); - break; - case TIFF_SHORT: - case TIFF_LONG: - s->bpp = tget(&buf, type, s->le) + tget(&buf, type, s->le) + tget(&buf, type, s->le); - break; - default: - s->bpp = -1; - } - } - if(s->bpp != 24){ - av_log(s->avctx, AV_LOG_ERROR, "Only RGB24 is supported\n"); - return -1; - } - break; - case TIFF_COMPR: - s->compr = value; - switch(s->compr){ - case TIFF_RAW: - case TIFF_PACKBITS: - break; - case TIFF_DEFLATE: - case TIFF_ADOBE_DEFLATE: -#ifdef CONFIG_ZLIB - break; -#else - av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n"); - return -1; -#endif - case TIFF_LZW: - av_log(s->avctx, AV_LOG_ERROR, "LZW: not implemented yet\n"); - return -1; - case TIFF_G3: - av_log(s->avctx, AV_LOG_ERROR, "CCITT G3 compression is not supported\n"); - return -1; - case TIFF_G4: - av_log(s->avctx, AV_LOG_ERROR, "CCITT G4 compression is not supported\n"); - return -1; - case TIFF_CCITT_RLE: - av_log(s->avctx, AV_LOG_ERROR, "CCITT RLE compression is not supported\n"); - return -1; - default: - av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr); - return -1; - } - break; - case TIFF_ROWSPERSTRIP: - if(value < 1 || value > s->height){ - av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n"); - return -1; - } - s->rps = value; - break; - case TIFF_STRIP_OFFS: - if(count == 1){ - s->stripdata = NULL; - s->stripoff = value; - }else - s->stripdata = start + off; - s->strips = count; - s->sot = type; - if(s->stripdata > end_buf){ - av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); - return -1; - } - break; - case TIFF_STRIP_SIZE: - if(count == 1){ - s->stripsizes = NULL; - s->stripsize = value; - s->strips = 1; - }else{ - s->stripsizes = start + off; - } - s->strips = count; - if(s->stripsizes > end_buf){ - av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); - return -1; - } - if(!pic->data[0]){ - av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n"); - return -1; - } - /* now we have the data and may start decoding */ - stride = pic->linesize[0]; - dst = pic->data[0]; - for(i = 0; i < s->height; i += s->rps){ - if(s->stripsizes) - ssize = tget(&s->stripsizes, type, s->le); - else - ssize = s->stripsize; - - if(s->stripdata){ - soff = tget(&s->stripdata, s->sot, s->le); - }else - soff = s->stripoff; - src = start + soff; - if(tiff_unpack_strip(s, dst, stride, src, ssize, FFMIN(s->rps, s->height - i)) < 0) - break; - dst += s->rps * stride; - } - break; - case TIFF_PREDICTOR: - if(!pic->data[0]){ - av_log(s->avctx, AV_LOG_ERROR, "Picture initialization missing\n"); - return -1; - } - if(value == 2){ - src = pic->data[0] + pic->linesize[0]; - stride = pic->linesize[0]; - soff = s->bpp >> 3; - ssize = s->width * soff; - for(i = 0; i < s->height; i++) { - for(j = soff; j < ssize; j++) - src[j] += src[j - soff]; - src += stride; - } - } - break; - } - return 0; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - TiffContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; - uint8_t *orig_buf = buf, *end_buf = buf + buf_size; - int id, le, off; - int i, entries; - - //parse image header - id = LE_16(buf); buf += 2; - if(id == 0x4949) le = 1; - else if(id == 0x4D4D) le = 0; - else{ - av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n"); - return -1; - } - s->le = le; - // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number - // that further identifies the file as a TIFF file" - if(tget_short(&buf, le) != 42){ - av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n"); - return -1; - } - /* parse image file directory */ - off = tget_long(&buf, le); - if(orig_buf + off + 14 >= end_buf){ - av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n"); - return -1; - } - buf = orig_buf + off; - entries = tget_short(&buf, le); - for(i = 0; i < entries; i++){ - if(tiff_decode_tag(s, orig_buf, buf, end_buf, p) < 0) - return -1; - buf += 12; - } - - *picture= *(AVFrame*)&s->picture; - *data_size = sizeof(AVPicture); - - return buf_size; -} - -static int tiff_init(AVCodecContext *avctx){ - TiffContext *s = avctx->priv_data; - - s->width = 0; - s->height = 0; - s->avctx = avctx; - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; - s->picture.data[0] = NULL; - - return 0; -} - -static int tiff_end(AVCodecContext *avctx) -{ - TiffContext * const s = avctx->priv_data; - - if(s->picture.data[0]) - avctx->release_buffer(avctx, &s->picture); - return 0; -} - -AVCodec tiff_decoder = { - "tiff", - CODEC_TYPE_VIDEO, - CODEC_ID_TIFF, - sizeof(TiffContext), - tiff_init, - NULL, - tiff_end, - decode_frame, - 0, - NULL -}; diff -r 2eaaa3aa182b -r 23a5aa2c545c src/ffmpeg/libavcodec/utils.c --- a/src/ffmpeg/libavcodec/utils.c Mon Mar 12 13:00:06 2007 -0700 +++ b/src/ffmpeg/libavcodec/utils.c Mon Mar 12 13:06:30 2007 -0700 @@ -1,143 +1,102 @@ /* * utils for libavcodec * Copyright (c) 2001 Fabrice Bellard. + * Copyright (c) 2003 Michel Bardiaux for the av_log API * Copyright (c) 2002-2004 Michael Niedermayer + * Copyright (c) 2004 Roman Bogorodskiy (bmp-wma specific stuff) * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or + * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * version 2 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -/** - * @file utils.c - * utils. - */ - + #include "avcodec.h" #include "dsputil.h" -#include "mpegvideo.h" -#include "integer.h" -#include "opt.h" -#include "crc.h" #include -#include -#include -#ifdef __MINGW32__ -#include -#endif -const uint8_t ff_reverse[256]={ -0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0, -0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8, -0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4, -0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC, -0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2, -0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA, -0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6, -0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE, -0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1, -0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9, -0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5, -0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD, -0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3, -0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB, -0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7, -0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF, -}; - -static int volatile entangled_thread_counter=0; +void *av_mallocz(unsigned int size) +{ + void *ptr; + + ptr = av_malloc(size); + if (!ptr) + return NULL; + + memset(ptr, 0, size); + + return ptr; +} /** * realloc which does nothing if the block is large enough */ -void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size) +void *av_fast_realloc(void *ptr, int *size, unsigned int min_size) { - if(min_size < *size) - return ptr; - - *size= FFMAX(17*min_size/16 + 32, min_size); - - return av_realloc(ptr, *size); -} - -static unsigned int last_static = 0; -static unsigned int allocated_static = 0; -static void** array_static = NULL; - -/** - * allocation of static arrays - do not use for normal allocation. - */ -void *av_mallocz_static(unsigned int size) -{ - void *ptr = av_mallocz(size); - - if(ptr){ - array_static =av_fast_realloc(array_static, &allocated_static, sizeof(void*)*(last_static+1)); - if(!array_static) - return NULL; - array_static[last_static++] = ptr; - } - - return ptr; -} - -/** - * same as above, but does realloc - */ + if(min_size < (unsigned int)*size) + return ptr; + + *size= min_size + 10*1024; -void *av_realloc_static(void *ptr, unsigned int size) -{ - int i; - if(!ptr) - return av_mallocz_static(size); - /* Look for the old ptr */ - for(i = 0; i < last_static; i++) { - if(array_static[i] == ptr) { - array_static[i] = av_realloc(array_static[i], size); - return array_static[i]; - } - } - return NULL; - -} - -/** - * free all static arrays and reset pointers to 0. - */ -void av_free_static(void) -{ - while(last_static){ - av_freep(&array_static[--last_static]); - } - av_freep(&array_static); -} - -/** - * Call av_free_static automatically before it's too late - */ - -static void do_free(void) __attribute__ ((destructor)); - -static void do_free(void) -{ - av_free_static(); + return realloc(ptr, *size); } +/* allocation of static arrays - do not use for normal allocation */ +static unsigned int last_static = 0; +static char*** array_static = NULL; +static const unsigned int grow_static = 64; // ^2 +void *__av_mallocz_static(void** location, unsigned int size) +{ + unsigned int l = (last_static + grow_static) & ~(grow_static - 1); + void *ptr = av_mallocz(size); + if (!ptr) + return NULL; + + if (location) + { + if (l > last_static) + array_static = realloc(array_static, l); + array_static[last_static++] = (char**) location; + *location = ptr; + } + return ptr; +} +/* free all static arrays and reset pointers to 0 */ +void av_free_static(void) +{ + if (array_static) + { + unsigned i; + for (i = 0; i < last_static; i++) + { + free(*array_static[i]); + *array_static[i] = NULL; + } + free(array_static); + array_static = 0; + } + last_static = 0; +} + +/* cannot call it directly because of 'void **' casting is not automatic */ +void __av_freep(void **ptr) +{ + free(*ptr); + *ptr = NULL; +} + /* encoder management */ -AVCodec *first_avcodec = NULL; +AVCodec *first_avcodec; void register_avcodec(AVCodec *format) { @@ -148,13 +107,6 @@ format->next = NULL; } -void avcodec_set_dimensions(AVCodecContext *s, int width, int height){ - s->coded_width = width; - s->coded_height= height; - s->width = -((-width )>>s->lowres); - s->height= -((-height)>>s->lowres); -} - typedef struct InternalBuffer{ int last_pic_num; uint8_t *base[4]; @@ -164,16 +116,16 @@ #define INTERNAL_BUFFER_SIZE 32 +#undef ALIGN #define ALIGN(x, a) (((x)+(a)-1)&~((a)-1)) void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ - int w_align= 1; - int h_align= 1; - + int w_align= 1; + int h_align= 1; + switch(s->pix_fmt){ case PIX_FMT_YUV420P: case PIX_FMT_YUV422: - case PIX_FMT_UYVY422: case PIX_FMT_YUV422P: case PIX_FMT_YUV444P: case PIX_FMT_GRAY8: @@ -184,32 +136,10 @@ h_align= 16; break; case PIX_FMT_YUV411P: - case PIX_FMT_UYVY411: w_align=32; h_align=8; break; case PIX_FMT_YUV410P: - if(s->codec_id == CODEC_ID_SVQ1){ - w_align=64; - h_align=64; - } - case PIX_FMT_RGB555: - if(s->codec_id == CODEC_ID_RPZA){ - w_align=4; - h_align=4; - } - case PIX_FMT_PAL8: - if(s->codec_id == CODEC_ID_SMC){ - w_align=4; - h_align=4; - } - break; - case PIX_FMT_BGR24: - if((s->codec_id == CODEC_ID_MSZH) || (s->codec_id == CODEC_ID_ZLIB)){ - w_align=4; - h_align=4; - } - break; default: w_align= 1; h_align= 1; @@ -220,109 +150,6 @@ *height= ALIGN(*height, h_align); } -int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h){ - if((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/4) - return 0; - - av_log(av_log_ctx, AV_LOG_ERROR, "picture size invalid (%ux%u)\n", w, h); - return -1; -} - -int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ - int i; - int w= s->width; - int h= s->height; - InternalBuffer *buf; - int *picture_number; - - assert(pic->data[0]==NULL); - assert(INTERNAL_BUFFER_SIZE > s->internal_buffer_count); - - if(avcodec_check_dimensions(s,w,h)) - return -1; - - if(s->internal_buffer==NULL){ - s->internal_buffer= av_mallocz(INTERNAL_BUFFER_SIZE*sizeof(InternalBuffer)); - } -#if 0 - s->internal_buffer= av_fast_realloc( - s->internal_buffer, - &s->internal_buffer_size, - sizeof(InternalBuffer)*FFMAX(99, s->internal_buffer_count+1)/*FIXME*/ - ); -#endif - - buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; - picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE-1]).last_pic_num; //FIXME ugly hack - (*picture_number)++; - - if(buf->base[0]){ - pic->age= *picture_number - buf->last_pic_num; - buf->last_pic_num= *picture_number; - }else{ - int h_chroma_shift, v_chroma_shift; - int pixel_size, size[3]; - AVPicture picture; - - avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift); - - avcodec_align_dimensions(s, &w, &h); - - if(!(s->flags&CODEC_FLAG_EMU_EDGE)){ - w+= EDGE_WIDTH*2; - h+= EDGE_WIDTH*2; - } - avpicture_fill(&picture, NULL, s->pix_fmt, w, h); - pixel_size= picture.linesize[0]*8 / w; -//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", (int)picture.data[1], w, h, s->pix_fmt); - assert(pixel_size>=1); - //FIXME next ensures that linesize= 2^x uvlinesize, thats needed because some MC code assumes it - if(pixel_size == 3*8) - w= ALIGN(w, STRIDE_ALIGN<pix_fmt, w, h); - size[0] = picture.linesize[0] * h; - size[1] -= size[0]; - if(picture.data[2]) - size[1]= size[2]= size[1]/2; - else - size[2]= 0; - - buf->last_pic_num= -256*256*256*64; - memset(buf->base, 0, sizeof(buf->base)); - memset(buf->data, 0, sizeof(buf->data)); - - for(i=0; i<3 && size[i]; i++){ - const int h_shift= i==0 ? 0 : h_chroma_shift; - const int v_shift= i==0 ? 0 : v_chroma_shift; - - buf->linesize[i]= picture.linesize[i]; - - buf->base[i]= av_malloc(size[i]+16); //FIXME 16 - if(buf->base[i]==NULL) return -1; - memset(buf->base[i], 128, size[i]); - - // no edge if EDEG EMU or not planar YUV, we check for PAL8 redundantly to protect against a exploitable bug regression ... - if((s->flags&CODEC_FLAG_EMU_EDGE) || (s->pix_fmt == PIX_FMT_PAL8) || !size[2]) - buf->data[i] = buf->base[i]; - else - buf->data[i] = buf->base[i] + ALIGN((buf->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift), STRIDE_ALIGN); - } - pic->age= 256*256*256*64; - } - pic->type= FF_BUFFER_TYPE_INTERNAL; - - for(i=0; i<4; i++){ - pic->base[i]= buf->base[i]; - pic->data[i]= buf->data[i]; - pic->linesize[i]= buf->linesize[i]; - } - s->internal_buffer_count++; - - return 0; -} - void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){ int i; InternalBuffer *buf, *last, temp; @@ -348,564 +175,104 @@ pic->data[i]=NULL; // pic->base[i]=NULL; } -//printf("R%X\n", pic->opaque); } -int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){ - AVFrame temp_pic; - int i; - - /* If no picture return a new buffer */ - if(pic->data[0] == NULL) { - /* We will copy from buffer, so must be readable */ - pic->buffer_hints |= FF_BUFFER_HINTS_READABLE; - return s->get_buffer(s, pic); - } - - /* If internal buffer type return the same buffer */ - if(pic->type == FF_BUFFER_TYPE_INTERNAL) - return 0; - - /* - * Not internal type and reget_buffer not overridden, emulate cr buffer - */ - temp_pic = *pic; - for(i = 0; i < 4; i++) - pic->data[i] = pic->base[i] = NULL; - pic->opaque = NULL; - /* Allocate new frame */ - if (s->get_buffer(s, pic)) - return -1; - /* Copy image data from old buffer to new buffer */ - img_copy((AVPicture*)pic, (AVPicture*)&temp_pic, s->pix_fmt, s->width, - s->height); - s->release_buffer(s, &temp_pic); // Release old frame - return 0; -} - -int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void **arg, int *ret, int count){ - int i; - - for(i=0; icodec && avc->codec->name) - return avc->codec->name; - else - return "NULL"; -} - -#define OFFSET(x) offsetof(AVCodecContext,x) -#define DEFAULT 0 //should be NAN but it doesnt work as its not a constant in glibc as required by ANSI/ISO C -//these names are too long to be readable -#define V AV_OPT_FLAG_VIDEO_PARAM -#define A AV_OPT_FLAG_AUDIO_PARAM -#define S AV_OPT_FLAG_SUBTITLE_PARAM -#define E AV_OPT_FLAG_ENCODING_PARAM -#define D AV_OPT_FLAG_DECODING_PARAM - -#define AV_CODEC_DEFAULT_BITRATE 200*1000 - -static const AVOption options[]={ -{"b", "set video bitrate (in bits/s)", OFFSET(bit_rate), FF_OPT_TYPE_INT, AV_CODEC_DEFAULT_BITRATE, INT_MIN, INT_MAX, V|A|E}, -{"bt", "set video bitrate tolerance (in bits/s)", OFFSET(bit_rate_tolerance), FF_OPT_TYPE_INT, AV_CODEC_DEFAULT_BITRATE*20, INT_MIN, INT_MAX, V|E}, -{"flags", NULL, OFFSET(flags), FF_OPT_TYPE_FLAGS, DEFAULT, INT_MIN, INT_MAX, V|A|E|D, "flags"}, -{"mv4", "use four motion vector by macroblock (mpeg4)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_4MV, INT_MIN, INT_MAX, V|E, "flags"}, -{"obmc", "use overlapped block motion compensation (h263+)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_OBMC, INT_MIN, INT_MAX, V|E, "flags"}, -{"qpel", "use 1/4 pel motion compensation", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QPEL, INT_MIN, INT_MAX, V|E, "flags"}, -{"loop", "use loop filter", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_LOOP_FILTER, INT_MIN, INT_MAX, V|E, "flags"}, -{"qscale", "use fixed qscale", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QSCALE, INT_MIN, INT_MAX, 0, "flags"}, -{"gmc", "use gmc", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GMC, INT_MIN, INT_MAX, V|E, "flags"}, -{"mv0", "always try a mb with mv=<0,0>", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_MV0, INT_MIN, INT_MAX, V|E, "flags"}, -{"part", "use data partitioning", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PART, INT_MIN, INT_MAX, V|E, "flags"}, -{"input_preserved", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INPUT_PRESERVED, INT_MIN, INT_MAX, 0, "flags"}, -{"pass1", "use internal 2pass ratecontrol in first pass mode", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PASS1, INT_MIN, INT_MAX, 0, "flags"}, -{"pass2", "use internal 2pass ratecontrol in second pass mode", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PASS2, INT_MIN, INT_MAX, 0, "flags"}, -{"extern_huff", "use external huffman table (for mjpeg)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_EXTERN_HUFF, INT_MIN, INT_MAX, 0, "flags"}, -{"gray", "only decode/encode grayscale", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GRAY, INT_MIN, INT_MAX, V|E|D, "flags"}, -{"emu_edge", "don't draw edges", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_EMU_EDGE, INT_MIN, INT_MAX, 0, "flags"}, -{"psnr", "error[?] variables will be set during encoding", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_PSNR, INT_MIN, INT_MAX, V|E, "flags"}, -{"truncated", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_TRUNCATED, INT_MIN, INT_MAX, 0, "flags"}, -{"naq", "normalize adaptive quantization", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_NORMALIZE_AQP, INT_MIN, INT_MAX, V|E, "flags"}, -{"ildct", "use interlaced dct", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INTERLACED_DCT, INT_MIN, INT_MAX, V|E, "flags"}, -{"low_delay", "force low delay", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_LOW_DELAY, INT_MIN, INT_MAX, V|D, "flags"}, -{"alt", "enable alternate scantable (mpeg2/mpeg4)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_ALT_SCAN, INT_MIN, INT_MAX, V|E, "flags"}, -{"trell", "use trellis quantization", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_TRELLIS_QUANT, INT_MIN, INT_MAX, V|E, "flags"}, -{"global_header", "place global headers in extradata instead of every keyframe", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_GLOBAL_HEADER, INT_MIN, INT_MAX, 0, "flags"}, -{"bitexact", "use only bitexact stuff (except (i)dct)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_BITEXACT, INT_MIN, INT_MAX, A|V|S|D|E, "flags"}, -{"aic", "h263 advanced intra coding / mpeg4 ac prediction", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_AC_PRED, INT_MIN, INT_MAX, V|E, "flags"}, -{"umv", "use unlimited motion vectors", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_H263P_UMV, INT_MIN, INT_MAX, V|E, "flags"}, -{"cbp", "use rate distortion optimization for cbp", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_CBP_RD, INT_MIN, INT_MAX, V|E, "flags"}, -{"qprd", "use rate distortion optimization for qp selection", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_QP_RD, INT_MIN, INT_MAX, V|E, "flags"}, -{"aiv", "h263 alternative inter vlc", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_H263P_AIV, INT_MIN, INT_MAX, V|E, "flags"}, -{"slice", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG_H263P_SLICE_STRUCT, INT_MIN, INT_MAX, V|E, "flags"}, -{"ilme", "interlaced motion estimation", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_INTERLACED_ME, INT_MIN, INT_MAX, V|E, "flags"}, -{"scan_offset", "will reserve space for svcd scan offset user data", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_SVCD_SCAN_OFFSET, INT_MIN, INT_MAX, V|E, "flags"}, -{"cgop", "closed gop", 0, FF_OPT_TYPE_CONST, CODEC_FLAG_CLOSED_GOP, INT_MIN, INT_MAX, V|E, "flags"}, -{"fast", "allow non spec compliant speedup tricks", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_FAST, INT_MIN, INT_MAX, V|E, "flags2"}, -{"sgop", "strictly enforce gop size", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_STRICT_GOP, INT_MIN, INT_MAX, V|E, "flags2"}, -{"noout", "skip bitstream encoding", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_NO_OUTPUT, INT_MIN, INT_MAX, V|E, "flags2"}, -{"local_header", "place global headers at every keyframe instead of in extradata", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_LOCAL_HEADER, INT_MIN, INT_MAX, V|E, "flags2"}, -{"sub_id", NULL, OFFSET(sub_id), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"me_method", "set motion estimation method", OFFSET(me_method), FF_OPT_TYPE_INT, ME_EPZS, INT_MIN, INT_MAX, V|E, "me_method"}, -{"extradata_size", NULL, OFFSET(extradata_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"time_base", NULL, OFFSET(time_base), FF_OPT_TYPE_RATIONAL, DEFAULT, INT_MIN, INT_MAX}, -{"g", "set the group of picture size", OFFSET(gop_size), FF_OPT_TYPE_INT, 12, INT_MIN, INT_MAX, V|E}, -{"rate_emu", NULL, OFFSET(rate_emu), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"ac", "set number of audio channels", OFFSET(channels), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"cutoff", "set cutoff bandwidth", OFFSET(cutoff), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|E}, -{"frame_size", NULL, OFFSET(frame_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|E}, -{"frame_number", NULL, OFFSET(frame_number), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"real_pict_num", NULL, OFFSET(real_pict_num), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"delay", NULL, OFFSET(delay), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"qcomp", "video quantizer scale compression (VBR)", OFFSET(qcompress), FF_OPT_TYPE_FLOAT, 0.5, FLT_MIN, FLT_MAX, V|E}, -{"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), FF_OPT_TYPE_FLOAT, 0.5, FLT_MIN, FLT_MAX, V|E}, -{"qmin", "min video quantizer scale (VBR)", OFFSET(qmin), FF_OPT_TYPE_INT, 2, 1, 51, V|E}, -{"qmax", "max video quantizer scale (VBR)", OFFSET(qmax), FF_OPT_TYPE_INT, 31, 1, 51, V|E}, -{"qdiff", "max difference between the quantizer scale (VBR)", OFFSET(max_qdiff), FF_OPT_TYPE_INT, 3, INT_MIN, INT_MAX, V|E}, -{"bf", "use 'frames' B frames", OFFSET(max_b_frames), FF_OPT_TYPE_INT, DEFAULT, 0, FF_MAX_B_FRAMES, V|E}, -{"b_qfactor", "qp factor between p and b frames", OFFSET(b_quant_factor), FF_OPT_TYPE_FLOAT, 1.25, FLT_MIN, FLT_MAX, V|E}, -{"rc_strategy", NULL, OFFSET(rc_strategy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"b_strategy", NULL, OFFSET(b_frame_strategy), FF_OPT_TYPE_INT, 0, INT_MIN, INT_MAX, V|E}, -{"hurry_up", NULL, OFFSET(hurry_up), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, -{"rtp_mode", NULL, OFFSET(rtp_mode), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"rtp_payload_size", NULL, OFFSET(rtp_payload_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"mv_bits", NULL, OFFSET(mv_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"header_bits", NULL, OFFSET(header_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"i_tex_bits", NULL, OFFSET(i_tex_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"p_tex_bits", NULL, OFFSET(p_tex_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"i_count", NULL, OFFSET(i_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"p_count", NULL, OFFSET(p_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"skip_count", NULL, OFFSET(skip_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"misc_bits", NULL, OFFSET(misc_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"frame_bits", NULL, OFFSET(frame_bits), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"codec_tag", NULL, OFFSET(codec_tag), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"bug", "workaround not auto detected encoder bugs", OFFSET(workaround_bugs), FF_OPT_TYPE_FLAGS, FF_BUG_AUTODETECT, INT_MIN, INT_MAX, V|D, "bug"}, -{"autodetect", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_AUTODETECT, INT_MIN, INT_MAX, V|D, "bug"}, -{"old_msmpeg4", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_OLD_MSMPEG4, INT_MIN, INT_MAX, V|D, "bug"}, -{"xvid_ilace", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_XVID_ILACE, INT_MIN, INT_MAX, V|D, "bug"}, -{"ump4", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_UMP4, INT_MIN, INT_MAX, V|D, "bug"}, -{"no_padding", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_NO_PADDING, INT_MIN, INT_MAX, V|D, "bug"}, -{"amv", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_AMV, INT_MIN, INT_MAX, V|D, "bug"}, -{"ac_vlc", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_AC_VLC, INT_MIN, INT_MAX, V|D, "bug"}, -{"qpel_chroma", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_QPEL_CHROMA, INT_MIN, INT_MAX, V|D, "bug"}, -{"std_qpel", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_STD_QPEL, INT_MIN, INT_MAX, V|D, "bug"}, -{"qpel_chroma2", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_QPEL_CHROMA2, INT_MIN, INT_MAX, V|D, "bug"}, -{"direct_blocksize", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_DIRECT_BLOCKSIZE, INT_MIN, INT_MAX, V|D, "bug"}, -{"edge", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_EDGE, INT_MIN, INT_MAX, V|D, "bug"}, -{"hpel_chroma", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_HPEL_CHROMA, INT_MIN, INT_MAX, V|D, "bug"}, -{"dc_clip", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_DC_CLIP, INT_MIN, INT_MAX, V|D, "bug"}, -{"ms", NULL, 0, FF_OPT_TYPE_CONST, FF_BUG_MS, INT_MIN, INT_MAX, V|D, "bug"}, -{"lelim", "single coefficient elimination threshold for luminance (negative values also consider dc coefficient)", OFFSET(luma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"celim", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)", OFFSET(chroma_elim_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "strict"}, -{"very", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_VERY_STRICT, INT_MIN, INT_MAX, V|E, "strict"}, -{"strict", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_STRICT, INT_MIN, INT_MAX, V|E, "strict"}, -{"normal", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_NORMAL, INT_MIN, INT_MAX, V|E, "strict"}, -{"inofficial", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_INOFFICIAL, INT_MIN, INT_MAX, V|E, "strict"}, -{"experimental", NULL, 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_EXPERIMENTAL, INT_MIN, INT_MAX, V|E, "strict"}, -{"b_qoffset", "qp offset between p and b frames", OFFSET(b_quant_offset), FF_OPT_TYPE_FLOAT, 1.25, FLT_MIN, FLT_MAX, V|E}, -{"er", NULL, OFFSET(error_resilience), FF_OPT_TYPE_INT, FF_ER_CAREFUL, INT_MIN, INT_MAX, V|D, "er"}, -{"careful", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_CAREFUL, INT_MIN, INT_MAX, V|D, "er"}, -{"compliant", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_COMPLIANT, INT_MIN, INT_MAX, V|D, "er"}, -{"aggressive", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_AGGRESSIVE, INT_MIN, INT_MAX, V|D, "er"}, -{"very_aggressive", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_VERY_AGGRESSIVE, INT_MIN, INT_MAX, V|D, "er"}, -{"has_b_frames", NULL, OFFSET(has_b_frames), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"block_align", NULL, OFFSET(block_align), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"parse_only", NULL, OFFSET(parse_only), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"mpeg_quant", NULL, OFFSET(mpeg_quant), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"stats_out", NULL, OFFSET(stats_out), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX}, -{"stats_in", NULL, OFFSET(stats_in), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX}, -{"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", OFFSET(rc_qsquish), FF_OPT_TYPE_FLOAT, DEFAULT, 0, 99, V|E}, -{"rc_qmod_amp", NULL, OFFSET(rc_qmod_amp), FF_OPT_TYPE_FLOAT, DEFAULT, -FLT_MAX, FLT_MAX, V|E}, -{"rc_qmod_freq", NULL, OFFSET(rc_qmod_freq), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"rc_override_count", NULL, OFFSET(rc_override_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"rc_eq", "set rate control equation", OFFSET(rc_eq), FF_OPT_TYPE_STRING, DEFAULT, CHAR_MIN, CHAR_MAX, V|E}, -{"maxrate", "set max video bitrate tolerance (in bits/s)", OFFSET(rc_max_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"minrate", "set min video bitrate tolerance (in bits/s)", OFFSET(rc_min_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"rc_buf_aggressivity", NULL, OFFSET(rc_buffer_aggressivity), FF_OPT_TYPE_FLOAT, 1.0, FLT_MIN, FLT_MAX, V|E}, -{"i_qfactor", "qp factor between p and i frames", OFFSET(i_quant_factor), FF_OPT_TYPE_FLOAT, -0.8, -FLT_MAX, FLT_MAX, V|E}, -{"i_qoffset", "qp offset between p and i frames", OFFSET(i_quant_offset), FF_OPT_TYPE_FLOAT, 0.0, -FLT_MAX, FLT_MAX, V|E}, -{"rc_init_cplx", "initial complexity for 1-pass encoding", OFFSET(rc_initial_cplx), FF_OPT_TYPE_FLOAT, DEFAULT, -FLT_MAX, FLT_MAX, V|E}, -{"dct", NULL, OFFSET(dct_algo), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|E, "dct"}, -{"auto", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_AUTO, INT_MIN, INT_MAX, V|E, "dct"}, -{"fastint", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_FASTINT, INT_MIN, INT_MAX, V|E, "dct"}, -{"int", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_INT, INT_MIN, INT_MAX, V|E, "dct"}, -{"mmx", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_MMX, INT_MIN, INT_MAX, V|E, "dct"}, -{"mlib", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_MLIB, INT_MIN, INT_MAX, V|E, "dct"}, -{"altivec", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_ALTIVEC, INT_MIN, INT_MAX, V|E, "dct"}, -{"faan", NULL, 0, FF_OPT_TYPE_CONST, FF_DCT_FAAN, INT_MIN, INT_MAX, V|E, "dct"}, -{"lumi_mask", "lumimasking", OFFSET(lumi_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"tcplx_mask", "temporal complexity masking", OFFSET(temporal_cplx_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"scplx_mask", "spatial complexity masking", OFFSET(spatial_cplx_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"p_mask", "inter masking", OFFSET(p_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"dark_mask", "darkness masking", OFFSET(dark_masking), FF_OPT_TYPE_FLOAT, 0, -FLT_MAX, FLT_MAX, V|E}, -{"unused", NULL, OFFSET(unused), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"idct", NULL, OFFSET(idct_algo), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|E|D, "idct"}, -{"auto", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_AUTO, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"int", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_INT, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simple", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLE, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simplemmx", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEMMX, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"libmpeg2mmx", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_LIBMPEG2MMX, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"ps2", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_PS2, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"mlib", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_MLIB, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"arm", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_ARM, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"altivec", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_ALTIVEC, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"sh4", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SH4, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simplearm", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEARM, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"simplearmv5te", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_SIMPLEARMV5TE, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"h264", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_H264, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"vp3", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_VP3, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"ipp", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_IPP, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"xvidmmx", NULL, 0, FF_OPT_TYPE_CONST, FF_IDCT_XVIDMMX, INT_MIN, INT_MAX, V|E|D, "idct"}, -{"slice_count", NULL, OFFSET(slice_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"ec", NULL, OFFSET(error_concealment), FF_OPT_TYPE_FLAGS, 3, INT_MIN, INT_MAX, V|D, "ec"}, -{"guess_mvs", NULL, 0, FF_OPT_TYPE_CONST, FF_EC_GUESS_MVS, INT_MIN, INT_MAX, V|D, "ec"}, -{"deblock", NULL, 0, FF_OPT_TYPE_CONST, FF_EC_DEBLOCK, INT_MIN, INT_MAX, V|D, "ec"}, -{"bits_per_sample", NULL, OFFSET(bits_per_sample), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"pred", "prediction method", OFFSET(prediction_method), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "pred"}, -{"left", NULL, 0, FF_OPT_TYPE_CONST, FF_PRED_LEFT, INT_MIN, INT_MAX, V|E, "pred"}, -{"plane", NULL, 0, FF_OPT_TYPE_CONST, FF_PRED_PLANE, INT_MIN, INT_MAX, V|E, "pred"}, -{"median", NULL, 0, FF_OPT_TYPE_CONST, FF_PRED_MEDIAN, INT_MIN, INT_MAX, V|E, "pred"}, -{"aspect", NULL, OFFSET(sample_aspect_ratio), FF_OPT_TYPE_RATIONAL, DEFAULT, 0, 10, V|E}, -{"debug", "print specific debug info", OFFSET(debug), FF_OPT_TYPE_FLAGS, DEFAULT, 0, INT_MAX, V|A|S|E|D, "debug"}, -{"pict", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_PICT_INFO, INT_MIN, INT_MAX, V|D, "debug"}, -{"rc", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_RC, INT_MIN, INT_MAX, V|E, "debug"}, -{"bitstream", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_BITSTREAM, INT_MIN, INT_MAX, V|D, "debug"}, -{"mb_type", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_MB_TYPE, INT_MIN, INT_MAX, V|D, "debug"}, -{"qp", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_QP, INT_MIN, INT_MAX, V|D, "debug"}, -{"mv", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_MV, INT_MIN, INT_MAX, V|D, "debug"}, -{"dct_coeff", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_DCT_COEFF, INT_MIN, INT_MAX, V|D, "debug"}, -{"skip", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_SKIP, INT_MIN, INT_MAX, V|D, "debug"}, -{"startcode", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_STARTCODE, INT_MIN, INT_MAX, V|D, "debug"}, -{"pts", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_PTS, INT_MIN, INT_MAX, V|D, "debug"}, -{"er", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_ER, INT_MIN, INT_MAX, V|D, "debug"}, -{"mmco", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_MMCO, INT_MIN, INT_MAX, V|D, "debug"}, -{"bugs", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_BUGS, INT_MIN, INT_MAX, V|D, "debug"}, -{"vis_qp", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_QP, INT_MIN, INT_MAX, V|D, "debug"}, -{"vis_mb_type", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MB_TYPE, INT_MIN, INT_MAX, V|D, "debug"}, -{"vismv", "visualize motion vectors", OFFSET(debug_mv), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|D, "debug_mv"}, -{"pf", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_P_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, -{"bf", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_B_FOR, INT_MIN, INT_MAX, V|D, "debug_mv"}, -{"bb", NULL, 0, FF_OPT_TYPE_CONST, FF_DEBUG_VIS_MV_B_BACK, INT_MIN, INT_MAX, V|D, "debug_mv"}, -{"mb_qmin", NULL, OFFSET(mb_qmin), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"mb_qmax", NULL, OFFSET(mb_qmax), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"cmp", "full pel me compare function", OFFSET(me_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"subcmp", "sub pel me compare function", OFFSET(me_sub_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"mbcmp", "macroblock compare function", OFFSET(mb_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"ildctcmp", "interlaced dct compare function", OFFSET(ildct_cmp), FF_OPT_TYPE_INT, FF_CMP_VSAD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"dia_size", NULL, OFFSET(dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"last_pred", NULL, OFFSET(last_predictor_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"preme", "pre motion estimation", OFFSET(pre_me), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"precmp", "pre motion estimation compare function", OFFSET(me_pre_cmp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"sad", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_SAD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"sse", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_SSE, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"satd", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_SATD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"dct", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_DCT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"psnr", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_PSNR, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"bit", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_BIT, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"rd", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_RD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"zero", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_ZERO, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"vsad", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_VSAD, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"vsse", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_VSSE, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"nsse", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_NSSE, INT_MIN, INT_MAX, V|E, "cmp_func"}, -#ifdef CONFIG_SNOW_ENCODER -{"w53", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_W53, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"w97", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_W97, INT_MIN, INT_MAX, V|E, "cmp_func"}, -#endif -{"dctmax", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_DCTMAX, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"chroma", NULL, 0, FF_OPT_TYPE_CONST, FF_CMP_CHROMA, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"pre_dia_size", NULL, OFFSET(pre_dia_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"subq", "sub pel motion estimation quality", OFFSET(me_subpel_quality), FF_OPT_TYPE_INT, 8, INT_MIN, INT_MAX, V|E}, -{"dtg_active_format", NULL, OFFSET(dtg_active_format), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"ibias", "intra quant bias", OFFSET(intra_quant_bias), FF_OPT_TYPE_INT, FF_DEFAULT_QUANT_BIAS, INT_MIN, INT_MAX, V|E}, -{"pbias", "inter quant bias", OFFSET(inter_quant_bias), FF_OPT_TYPE_INT, FF_DEFAULT_QUANT_BIAS, INT_MIN, INT_MAX, V|E}, -{"color_table_id", NULL, OFFSET(color_table_id), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"internal_buffer_count", NULL, OFFSET(internal_buffer_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"global_quality", NULL, OFFSET(global_quality), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"coder", NULL, OFFSET(coder_type), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "coder"}, -{"vlc", "variable length coder / huffman coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_VLC, INT_MIN, INT_MAX, V|E, "coder"}, -{"ac", "arithmetic coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_AC, INT_MIN, INT_MAX, V|E, "coder"}, -{"context", "context model", OFFSET(context_model), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"slice_flags", NULL, OFFSET(slice_flags), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"mbd", NULL, OFFSET(mb_decision), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E, "mbd"}, -{"simple", NULL, 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_SIMPLE, INT_MIN, INT_MAX, V|E, "mbd"}, -{"bits", NULL, 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_BITS, INT_MIN, INT_MAX, V|E, "mbd"}, -{"rd", NULL, 0, FF_OPT_TYPE_CONST, FF_MB_DECISION_RD, INT_MIN, INT_MAX, V|E, "mbd"}, -{"stream_codec_tag", NULL, OFFSET(stream_codec_tag), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"sc_threshold", "scene change threshold", OFFSET(scenechange_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"lmin", "min lagrange factor (VBR)", OFFSET(lmin), FF_OPT_TYPE_INT, 2*FF_QP2LAMBDA, 0, INT_MAX, V|E}, -{"lmax", "max lagrange factor (VBR)", OFFSET(lmax), FF_OPT_TYPE_INT, 31*FF_QP2LAMBDA, 0, INT_MAX, V|E}, -{"nr", "noise reduction", OFFSET(noise_reduction), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"rc_init_occupancy", NULL, OFFSET(rc_initial_buffer_occupancy), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"inter_threshold", NULL, OFFSET(inter_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"flags2", NULL, OFFSET(flags2), FF_OPT_TYPE_FLAGS, CODEC_FLAG2_FASTPSKIP, INT_MIN, INT_MAX, V|A|E|D, "flags2"}, -{"error", NULL, OFFSET(error_rate), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"antialias", NULL, OFFSET(antialias_algo), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D, "aa"}, -{"auto", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_AUTO, INT_MIN, INT_MAX, V|D, "aa"}, -{"fastint", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_FASTINT, INT_MIN, INT_MAX, V|D, "aa"}, -{"int", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_INT, INT_MIN, INT_MAX, V|D, "aa"}, -{"float", NULL, 0, FF_OPT_TYPE_CONST, FF_AA_FLOAT, INT_MIN, INT_MAX, V|D, "aa"}, -{"qns", "quantizer noise shaping", OFFSET(quantizer_noise_shaping), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"threads", NULL, OFFSET(thread_count), FF_OPT_TYPE_INT, 1, INT_MIN, INT_MAX, V|E|D}, -{"me_threshold", "motion estimaton threshold", OFFSET(me_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, -{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"dc", "intra_dc_precision", OFFSET(intra_dc_precision), FF_OPT_TYPE_INT, 0, INT_MIN, INT_MAX, V|E}, -{"nssew", "nsse weight", OFFSET(nsse_weight), FF_OPT_TYPE_INT, 8, INT_MIN, INT_MAX, V|E}, -{"skip_top", NULL, OFFSET(skip_top), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, -{"skip_bottom", NULL, OFFSET(skip_bottom), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|D}, -{"profile", NULL, OFFSET(profile), FF_OPT_TYPE_INT, FF_PROFILE_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "profile"}, -{"unknown", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "profile"}, -{"level", NULL, OFFSET(level), FF_OPT_TYPE_INT, FF_LEVEL_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "level"}, -{"unknown", NULL, 0, FF_OPT_TYPE_CONST, FF_LEVEL_UNKNOWN, INT_MIN, INT_MAX, V|A|E, "level"}, -{"lowres", NULL, OFFSET(lowres), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|D}, -{"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"skip_factor", "frame skip factor", OFFSET(frame_skip_factor), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"skip_exp", "frame skip exponent", OFFSET(frame_skip_exp), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"skipcmp", "frame skip compare function", OFFSET(frame_skip_cmp), FF_OPT_TYPE_INT, FF_CMP_DCTMAX, INT_MIN, INT_MAX, V|E, "cmp_func"}, -{"border_mask", NULL, OFFSET(border_masking), FF_OPT_TYPE_FLOAT, DEFAULT, -FLT_MAX, FLT_MAX, V|E}, -{"mblmin", "min macroblock quantizer scale (VBR)", OFFSET(mb_lmin), FF_OPT_TYPE_INT, FF_QP2LAMBDA * 2, 1, FF_LAMBDA_MAX, V|E}, -{"mblmax", "max macroblock quantizer scale (VBR)", OFFSET(mb_lmax), FF_OPT_TYPE_INT, FF_QP2LAMBDA * 31, 1, FF_LAMBDA_MAX, V|E}, -{"mepc", "motion estimation bitrate penalty compensation (1.0 = 256)", OFFSET(me_penalty_compensation), FF_OPT_TYPE_INT, 256, INT_MIN, INT_MAX, V|E}, -{"bidir_refine", NULL, OFFSET(bidir_refine), FF_OPT_TYPE_INT, DEFAULT, 0, 4, V|E}, -{"brd_scale", NULL, OFFSET(brd_scale), FF_OPT_TYPE_INT, DEFAULT, 0, 10, V|E}, -{"crf", NULL, OFFSET(crf), FF_OPT_TYPE_FLOAT, DEFAULT, 0, 51, V|E}, -{"cqp", NULL, OFFSET(cqp), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, V|E}, -{"keyint_min", NULL, OFFSET(keyint_min), FF_OPT_TYPE_INT, 25, INT_MIN, INT_MAX, V|E}, -{"refs", NULL, OFFSET(refs), FF_OPT_TYPE_INT, 1, INT_MIN, INT_MAX, V|E}, -{"chromaoffset", NULL, OFFSET(chromaoffset), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"bframebias", NULL, OFFSET(bframebias), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"trellis", NULL, OFFSET(trellis), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|A|E}, -{"directpred", NULL, OFFSET(directpred), FF_OPT_TYPE_INT, 2, INT_MIN, INT_MAX, V|E}, -{"bpyramid", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BPYRAMID, INT_MIN, INT_MAX, V|E, "flags2"}, -{"wpred", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_WPRED, INT_MIN, INT_MAX, V|E, "flags2"}, -{"mixed_refs", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_MIXED_REFS, INT_MIN, INT_MAX, V|E, "flags2"}, -{"8x8dct", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_8X8DCT, INT_MIN, INT_MAX, V|E, "flags2"}, -{"fastpskip", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_FASTPSKIP, INT_MIN, INT_MAX, V|E, "flags2"}, -{"aud", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_AUD, INT_MIN, INT_MAX, V|E, "flags2"}, -{"brdo", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BRDO, INT_MIN, INT_MAX, V|E, "flags2"}, -{"complexityblur", NULL, OFFSET(complexityblur), FF_OPT_TYPE_FLOAT, 20.0, FLT_MIN, FLT_MAX, V|E}, -{"deblockalpha", NULL, OFFSET(deblockalpha), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"deblockbeta", NULL, OFFSET(deblockbeta), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, -{"partitions", NULL, OFFSET(partitions), FF_OPT_TYPE_FLAGS, DEFAULT, INT_MIN, INT_MAX, V|E, "partitions"}, -{"parti4x4", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_I4X4, INT_MIN, INT_MAX, V|E, "partitions"}, -{"parti8x8", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_I8X8, INT_MIN, INT_MAX, V|E, "partitions"}, -{"partp4x4", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_P4X4, INT_MIN, INT_MAX, V|E, "partitions"}, -{"partp8x8", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_P8X8, INT_MIN, INT_MAX, V|E, "partitions"}, -{"partb8x8", NULL, 0, FF_OPT_TYPE_CONST, X264_PART_B8X8, INT_MIN, INT_MAX, V|E, "partitions"}, -{"sc_factor", NULL, OFFSET(scenechange_factor), FF_OPT_TYPE_INT, 6, 0, INT_MAX, V|E}, -{"mv0_threshold", NULL, OFFSET(mv0_threshold), FF_OPT_TYPE_INT, 256, 0, INT_MAX, V|E}, -{"ivlc", "intra vlc table", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_INTRA_VLC, INT_MIN, INT_MAX, V|E, "flags2"}, -{"b_sensitivity", NULL, OFFSET(b_sensitivity), FF_OPT_TYPE_INT, 40, 1, INT_MAX, V|E}, -{"compression_level", NULL, OFFSET(compression_level), FF_OPT_TYPE_INT, FF_COMPRESSION_DEFAULT, INT_MIN, INT_MAX, V|A|E}, -{"use_lpc", NULL, OFFSET(use_lpc), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"lpc_coeff_precision", NULL, OFFSET(lpc_coeff_precision), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, A|E}, -{"min_prediction_order", NULL, OFFSET(min_prediction_order), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"max_prediction_order", NULL, OFFSET(max_prediction_order), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"prediction_order_method", NULL, OFFSET(prediction_order_method), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"min_partition_order", NULL, OFFSET(min_partition_order), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{"max_partition_order", NULL, OFFSET(max_partition_order), FF_OPT_TYPE_INT, -1, INT_MIN, INT_MAX, A|E}, -{NULL}, -}; - -#undef A -#undef V -#undef S -#undef E -#undef D -#undef DEFAULT - -static AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options }; - void avcodec_get_context_defaults(AVCodecContext *s){ - memset(s, 0, sizeof(AVCodecContext)); - - s->av_class= &av_codec_context_class; - - av_opt_set_defaults(s); - + s->bit_rate= 800*1000; + s->bit_rate_tolerance= s->bit_rate*10; + s->qmin= 2; + s->qmax= 31; + s->mb_qmin= 2; + s->mb_qmax= 31; s->rc_eq= "tex^qComp"; - s->time_base= (AVRational){0,1}; - s->get_buffer= avcodec_default_get_buffer; + s->qcompress= 0.5; + s->max_qdiff= 3; + s->b_quant_factor=1.25; + s->b_quant_offset=1.25; + s->i_quant_factor=-0.8; + s->i_quant_offset=0.0; + s->error_concealment= 3; + s->error_resilience= 1; + s->workaround_bugs= FF_BUG_AUTODETECT; + s->frame_rate_base= 1; + s->frame_rate = 25; + s->gop_size= 50; + s->me_method= ME_EPZS; + //s->get_buffer= avcodec_default_get_buffer; s->release_buffer= avcodec_default_release_buffer; s->get_format= avcodec_default_get_format; - s->execute= avcodec_default_execute; - s->sample_aspect_ratio= (AVRational){0,1}; - s->pix_fmt= PIX_FMT_NONE; - s->sample_fmt= SAMPLE_FMT_S16; // FIXME: set to NONE - + s->me_subpel_quality=8; + s->lmin= FF_QP2LAMBDA * s->qmin; + s->lmax= FF_QP2LAMBDA * s->qmax; + //s->sample_aspect_ratio= (AVRational){0,1}; + s->ildct_cmp= FF_CMP_VSAD; + + s->intra_quant_bias= FF_DEFAULT_QUANT_BIAS; + s->inter_quant_bias= FF_DEFAULT_QUANT_BIAS; s->palctrl = NULL; - s->reget_buffer= avcodec_default_reget_buffer; + //s->reget_buffer= avcodec_default_reget_buffer; } /** * allocates a AVCodecContext and set it to defaults. - * this can be deallocated by simply calling free() + * this can be deallocated by simply calling free() */ AVCodecContext *avcodec_alloc_context(void){ - AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); - + AVCodecContext *avctx= av_mallocz(sizeof(AVCodecContext)); + if(avctx==NULL) return NULL; - + avcodec_get_context_defaults(avctx); - + return avctx; } -void avcodec_get_frame_defaults(AVFrame *pic){ - memset(pic, 0, sizeof(AVFrame)); - - pic->pts= AV_NOPTS_VALUE; - pic->key_frame= 1; -} - /** * allocates a AVPFrame and set it to defaults. - * this can be deallocated by simply calling free() + * this can be deallocated by simply calling free() */ AVFrame *avcodec_alloc_frame(void){ - AVFrame *pic= av_malloc(sizeof(AVFrame)); - - if(pic==NULL) return NULL; - - avcodec_get_frame_defaults(pic); - + AVFrame *pic= av_mallocz(sizeof(AVFrame)); + return pic; } int avcodec_open(AVCodecContext *avctx, AVCodec *codec) { - int ret= -1; - - entangled_thread_counter++; - if(entangled_thread_counter != 1){ - av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n"); - goto end; - } + int ret; if(avctx->codec) - goto end; - - if (codec->priv_data_size > 0) { - avctx->priv_data = av_mallocz(codec->priv_data_size); - if (!avctx->priv_data) - goto end; - } else { - avctx->priv_data = NULL; - } - - if(avctx->coded_width && avctx->coded_height) - avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); - else if(avctx->width && avctx->height) - avcodec_set_dimensions(avctx, avctx->width, avctx->height); - - if((avctx->coded_width||avctx->coded_height) && avcodec_check_dimensions(avctx,avctx->coded_width,avctx->coded_height)){ - av_freep(&avctx->priv_data); - goto end; - } + return -1; avctx->codec = codec; avctx->codec_id = codec->id; avctx->frame_number = 0; + if (codec->priv_data_size > 0) { + avctx->priv_data = av_mallocz(codec->priv_data_size); + if (!avctx->priv_data) + return -ENOMEM; + } else { + avctx->priv_data = NULL; + } ret = avctx->codec->init(avctx); if (ret < 0) { av_freep(&avctx->priv_data); - avctx->codec= NULL; - goto end; + return ret; } - ret=0; -end: - entangled_thread_counter--; - return ret; -} - -int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const short *samples) -{ - if(buf_size < FF_MIN_BUFFER_SIZE && 0){ - av_log(avctx, AV_LOG_ERROR, "buffer smaller then minimum size\n"); - return -1; - } - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || samples){ - int ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples); - avctx->frame_number++; - return ret; - }else - return 0; + return 0; } -int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVFrame *pict) -{ - if(buf_size < FF_MIN_BUFFER_SIZE){ - av_log(avctx, AV_LOG_ERROR, "buffer smaller then minimum size\n"); - return -1; - } - if(avcodec_check_dimensions(avctx,avctx->width,avctx->height)) - return -1; - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || pict){ - int ret = avctx->codec->encode(avctx, buf, buf_size, (void *)pict); - avctx->frame_number++; - emms_c(); //needed to avoid an emms_c() call before every return; - - return ret; - }else - return 0; -} - -int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const AVSubtitle *sub) -{ - int ret; - ret = avctx->codec->encode(avctx, buf, buf_size, (void *)sub); - avctx->frame_number++; - return ret; -} - -/** - * decode a frame. - * @param buf bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE larger then the actual read bytes - * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end - * @param buf_size the size of the buffer in bytes - * @param got_picture_ptr zero if no frame could be decompressed, Otherwise, it is non zero - * @return -1 if error, otherwise return the number of - * bytes used. - */ -int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - uint8_t *buf, int buf_size) +int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const short *samples) { int ret; - *got_picture_ptr= 0; - if((avctx->coded_width||avctx->coded_height) && avcodec_check_dimensions(avctx,avctx->coded_width,avctx->coded_height)) - return -1; - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || buf_size){ - ret = avctx->codec->decode(avctx, picture, got_picture_ptr, - buf, buf_size); - - emms_c(); //needed to avoid an emms_c() call before every return; - - if (*got_picture_ptr) - avctx->frame_number++; - }else - ret= 0; - + ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples); + avctx->frame_number++; return ret; } @@ -913,54 +280,23 @@ *number of bytes used. If no frame could be decompressed, *frame_size_ptr is zero. Otherwise, it is the decompressed frame *size in BYTES. */ -int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, +int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, uint8_t *buf, int buf_size) { int ret; - - *frame_size_ptr= 0; - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || buf_size){ - ret = avctx->codec->decode(avctx, samples, frame_size_ptr, - buf, buf_size); - avctx->frame_number++; - }else - ret= 0; - return ret; -} - -/* decode a subtitle message. return -1 if error, otherwise return the - *number of bytes used. If no subtitle could be decompressed, - *got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */ -int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - const uint8_t *buf, int buf_size) -{ - int ret; - - *got_sub_ptr = 0; - ret = avctx->codec->decode(avctx, sub, got_sub_ptr, - (uint8_t *)buf, buf_size); - if (*got_sub_ptr) - avctx->frame_number++; + ret = avctx->codec->decode(avctx, samples, frame_size_ptr, + buf, buf_size); + avctx->frame_number++; return ret; } int avcodec_close(AVCodecContext *avctx) { - entangled_thread_counter++; - if(entangled_thread_counter != 1){ - av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n"); - entangled_thread_counter--; - return -1; - } - if (avctx->codec->close) avctx->codec->close(avctx); - avcodec_default_free_buffers(avctx); av_freep(&avctx->priv_data); avctx->codec = NULL; - entangled_thread_counter--; return 0; } @@ -969,7 +305,7 @@ AVCodec *p; p = first_avcodec; while (p) { - if (p->encode != NULL && p->id == id) + if (p->encode != NULL && (enum CodecID)p->id == id) return p; p = p->next; } @@ -993,7 +329,7 @@ AVCodec *p; p = first_avcodec; while (p) { - if (p->decode != NULL && p->id == id) + if (p->decode != NULL && (enum CodecID)p->id == id) return p; p = p->next; } @@ -1012,6 +348,18 @@ return NULL; } +AVCodec *avcodec_find(enum CodecID id) +{ + AVCodec *p; + p = first_avcodec; + while (p) { + if ((enum CodecID)p->id == id) + return p; + p = p->next; + } + return NULL; +} + void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { const char *codec_name; @@ -1027,61 +375,15 @@ if (p) { codec_name = p->name; - if (!encode && enc->codec_id == CODEC_ID_MP3) { - if (enc->sub_id == 2) - codec_name = "mp2"; - else if (enc->sub_id == 1) - codec_name = "mp1"; - } - } else if (enc->codec_id == CODEC_ID_MPEG2TS) { - /* fake mpeg2 transport stream codec (currently not - registered) */ - codec_name = "mpeg2ts"; } else if (enc->codec_name[0] != '\0') { codec_name = enc->codec_name; } else { /* output avi tags */ - if( isprint(enc->codec_tag&0xFF) && isprint((enc->codec_tag>>8)&0xFF) - && isprint((enc->codec_tag>>16)&0xFF) && isprint((enc->codec_tag>>24)&0xFF)){ - snprintf(buf1, sizeof(buf1), "%c%c%c%c / 0x%04X", - enc->codec_tag & 0xff, - (enc->codec_tag >> 8) & 0xff, - (enc->codec_tag >> 16) & 0xff, - (enc->codec_tag >> 24) & 0xff, - enc->codec_tag); - } else { - snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag); - } + snprintf(buf1, sizeof(buf1), "0x%04x", enc->codec_tag); codec_name = buf1; } switch(enc->codec_type) { - case CODEC_TYPE_VIDEO: - snprintf(buf, buf_size, - "Video: %s%s", - codec_name, enc->mb_decision ? " (hq)" : ""); - if (enc->pix_fmt != PIX_FMT_NONE) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %s", - avcodec_get_pix_fmt_name(enc->pix_fmt)); - } - if (enc->width) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %dx%d", - enc->width, enc->height); - if(av_log_get_level() >= AV_LOG_DEBUG){ - int g= ff_gcd(enc->time_base.num, enc->time_base.den); - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %d/%d", - enc->time_base.num/g, enc->time_base.den/g); - } - } - if (encode) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", q=%d-%d", enc->qmin, enc->qmax); - } - bitrate = enc->bit_rate; - break; case CODEC_TYPE_AUDIO: snprintf(buf, buf_size, "Audio: %s", @@ -1097,7 +399,7 @@ strcpy(channels_str, "5:1"); break; default: - snprintf(channels_str, sizeof(channels_str), "%d channels", enc->channels); + sprintf(channels_str, "%d channels", enc->channels); break; } if (enc->sample_rate) { @@ -1106,22 +408,9 @@ enc->sample_rate, channels_str); } - + /* for PCM codecs, compute bitrate directly */ switch(enc->codec_id) { - case CODEC_ID_PCM_S32LE: - case CODEC_ID_PCM_S32BE: - case CODEC_ID_PCM_U32LE: - case CODEC_ID_PCM_U32BE: - bitrate = enc->sample_rate * enc->channels * 32; - break; - case CODEC_ID_PCM_S24LE: - case CODEC_ID_PCM_S24BE: - case CODEC_ID_PCM_U24LE: - case CODEC_ID_PCM_U24BE: - case CODEC_ID_PCM_S24DAUD: - bitrate = enc->sample_rate * enc->channels * 24; - break; case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_U16LE: @@ -1143,13 +432,8 @@ snprintf(buf, buf_size, "Data: %s", codec_name); bitrate = enc->bit_rate; break; - case CODEC_TYPE_SUBTITLE: - snprintf(buf, buf_size, "Subtitle: %s", codec_name); - bitrate = enc->bit_rate; - break; default: - snprintf(buf, buf_size, "Invalid Codec type %d", enc->codec_type); - return; + av_abort(); } if (encode) { if (enc->flags & CODEC_FLAG_PASS1) @@ -1160,7 +444,7 @@ ", pass 2"); } if (bitrate != 0) { - snprintf(buf + strlen(buf), buf_size - strlen(buf), + snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %d kb/s", bitrate / 1000); } } @@ -1175,26 +459,16 @@ return LIBAVCODEC_BUILD; } -static void init_crcs(void){ - av_crc04C11DB7= av_mallocz_static(sizeof(AVCRC) * 257); - av_crc8005 = av_mallocz_static(sizeof(AVCRC) * 257); - av_crc07 = av_mallocz_static(sizeof(AVCRC) * 257); - av_crc_init(av_crc04C11DB7, 0, 32, 0x04c11db7, sizeof(AVCRC)*257); - av_crc_init(av_crc8005 , 0, 16, 0x8005 , sizeof(AVCRC)*257); - av_crc_init(av_crc07 , 0, 8, 0x07 , sizeof(AVCRC)*257); -} - /* must be called before any other functions */ void avcodec_init(void) { static int inited = 0; if (inited != 0) - return; + return; inited = 1; dsputil_static_init(); - init_crcs(); } /** @@ -1210,7 +484,7 @@ int i, j; if(s->internal_buffer==NULL) return; - + for(i=0; iinternal_buffer)[i]; for(j=0; j<4; j++){ @@ -1219,109 +493,143 @@ } } av_freep(&s->internal_buffer); - + s->internal_buffer_count=0; } - +#if 0 char av_get_pict_type_char(int pict_type){ switch(pict_type){ - case I_TYPE: return 'I'; - case P_TYPE: return 'P'; - case B_TYPE: return 'B'; - case S_TYPE: return 'S'; - case SI_TYPE:return 'i'; - case SP_TYPE:return 'p'; + case I_TYPE: return 'I'; + case P_TYPE: return 'P'; + case B_TYPE: return 'B'; + case S_TYPE: return 'S'; + case SI_TYPE:return 'i'; + case SP_TYPE:return 'p'; default: return '?'; } } -int av_get_bits_per_sample(enum CodecID codec_id){ - switch(codec_id){ - case CODEC_ID_ADPCM_SBPRO_2: - return 2; - case CODEC_ID_ADPCM_SBPRO_3: - return 3; - case CODEC_ID_ADPCM_SBPRO_4: - case CODEC_ID_ADPCM_CT: - return 4; - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_MULAW: - case CODEC_ID_PCM_S8: - case CODEC_ID_PCM_U8: - return 8; - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_U16BE: - case CODEC_ID_PCM_U16LE: - return 16; - case CODEC_ID_PCM_S24DAUD: - case CODEC_ID_PCM_S24BE: - case CODEC_ID_PCM_S24LE: - case CODEC_ID_PCM_U24BE: - case CODEC_ID_PCM_U24LE: - return 24; - case CODEC_ID_PCM_S32BE: - case CODEC_ID_PCM_S32LE: - case CODEC_ID_PCM_U32BE: - case CODEC_ID_PCM_U32LE: - return 32; - default: - return 0; +int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ + int exact=1, sign=0; + int64_t gcd; + + assert(den != 0); + + if(den < 0){ + den= -den; + nom= -nom; + } + + if(nom < 0){ + nom= -nom; + sign= 1; } + + gcd = ff_gcd(nom, den); + nom /= gcd; + den /= gcd; + + if(nom > max || den > max){ + AVRational a0={0,1}, a1={1,0}; + exact=0; + + for(;;){ + int64_t x= nom / den; + int64_t a2n= x*a1.num + a0.num; + int64_t a2d= x*a1.den + a0.den; + + if(a2n > max || a2d > max) break; + + nom %= den; + + a0= a1; + a1= (AVRational){a2n, a2d}; + if(nom==0) break; + x= nom; nom=den; den=x; + } + nom= a1.num; + den= a1.den; + } + + assert(ff_gcd(nom, den) == 1); + + if(sign) nom= -nom; + + *dst_nom = nom; + *dst_den = den; + + return exact; +} +#endif +int64_t av_rescale(int64_t a, int b, int c){ + uint64_t h, l; + assert(c > 0); + assert(b >=0); + + if(a<0) return -av_rescale(-a, b, c); + + h= a>>32; + if(h==0) return a*b/c; + + l= a&0xFFFFFFFF; + l *= b; + h *= b; + + l += (h%c)<<32; + + return ((h/c)<<32) + l/c; } -#if !defined(HAVE_THREADS) -int avcodec_thread_init(AVCodecContext *s, int thread_count){ - return -1; -} +/* av_log API */ + +#ifdef AV_LOG_TRAP_PRINTF +#undef stderr +#undef fprintf #endif -unsigned int av_xiphlacing(unsigned char *s, unsigned int v) +static int av_log_level = AV_LOG_DEBUG; + +static void av_log_default_callback(AVCodecContext* avctx, int level, const char* fmt, va_list vl) { - unsigned int n = 0; + static int print_prefix=1; - while(v >= 0xff) { - *s++ = 0xff; - v -= 0xff; - n++; - } - *s = v; - n++; - return n; + if(level>av_log_level) + return; + if(avctx && print_prefix) + fprintf(stderr, "[%s @ %p]", avctx->codec ? avctx->codec->name : "?", avctx); + + print_prefix= strstr(fmt, "\n") != NULL; + + vfprintf(stderr, fmt, vl); } -/* Wrapper to work around the lack of mkstemp() on mingw/cygin. - * Also, tries to create file in /tmp first, if possible. - * *prefix can be a character constant; *filename will be allocated internally. - * Returns file descriptor of opened file (or -1 on error) - * and opened file name in **filename. */ -int av_tempfile(char *prefix, char **filename) { - int fd=-1; -#ifdef __MINGW32__ - *filename = tempnam(".", prefix); -#else - size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ - *filename = av_malloc(len); -#endif - /* -----common section-----*/ - if (*filename == NULL) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); - return -1; - } -#ifdef __MINGW32__ - fd = open(*filename, _O_RDWR | _O_BINARY | _O_CREAT, 0444); -#else - snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); - fd = mkstemp(*filename); - if (fd < 0) { - snprintf(*filename, len, "./%sXXXXXX", prefix); - fd = mkstemp(*filename); - } -#endif - /* -----common section-----*/ - if (fd < 0) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); - return -1; - } - return fd; /* success */ +static void (*av_log_callback)(AVCodecContext*, int, const char*, va_list) = av_log_default_callback; + +void av_log(AVCodecContext* avctx, int level, const char *fmt, ...) +{ + va_list vl; + va_start(vl, fmt); + av_vlog(avctx, level, fmt, vl); + va_end(vl); +} + +void av_vlog(AVCodecContext* avctx, int level, const char *fmt, va_list vl) +{ + av_log_callback(avctx, level, fmt, vl); } + +int av_log_get_level(void) +{ + return av_log_level; +} + +void av_log_set_level(int level) +{ + av_log_level = level; +} + +void av_log_set_callback(void (*callback)(AVCodecContext*, int, const char*, va_list)) +{ + av_log_callback = callback; +} +