diff options
Diffstat (limited to 'contrib/ffmpeg/libavcodec')
480 files changed, 69773 insertions, 39402 deletions
diff --git a/contrib/ffmpeg/libavcodec/4xm.c b/contrib/ffmpeg/libavcodec/4xm.c index 6889dbc4b..d833a3b18 100644 --- a/contrib/ffmpeg/libavcodec/4xm.c +++ b/contrib/ffmpeg/libavcodec/4xm.c @@ -27,6 +27,7 @@ #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" +#include "bytestream.h" //#undef NDEBUG //#include <assert.h> @@ -36,7 +37,8 @@ #define CFRAME_BUFFER_COUNT 100 -static const uint8_t block_type_tab[4][8][2]={ +static const uint8_t block_type_tab[2][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 @@ -46,6 +48,17 @@ static const uint8_t block_type_tab[4][8][2]={ },{ //1x2, 2x1 { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4} } + },{ + { //{8,4,2}x{8,4,2} + { 1,2}, { 4,3}, { 5,3}, {0,2}, {6,3}, {7,3}, {0,0} + },{//{8,4}x1 + { 1,2}, { 0,0}, { 2,2}, {0,2}, {6,3}, {7,3}, {0,0} + },{//1x{8,4} + { 1,2}, { 2,2}, { 0,0}, {0,2}, {6,3}, {7,3}, {0,0} + },{//1x2, 2x1 + { 1,2}, { 0,0}, { 0,0}, {0,2}, {2,2}, {6,3}, {7,3} + } + } }; static const uint8_t size2index[4][4]={ @@ -102,7 +115,7 @@ static const uint8_t dequant_table[64]={ 20, 35, 34, 32, 31, 22, 15, 8, }; -static VLC block_type_vlc[4]; +static VLC block_type_vlc[2][4]; typedef struct CFrameBuffer{ @@ -118,14 +131,15 @@ typedef struct FourXContext{ AVFrame current_picture, last_picture; GetBitContext pre_gb; ///< ac/dc prefix GetBitContext gb; - uint8_t *bytestream; - uint16_t *wordstream; + const uint8_t *bytestream; + const 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; + int version; CFrameBuffer cfrm[CFRAME_BUFFER_COUNT]; } FourXContext; @@ -224,10 +238,10 @@ static void idct(DCTELEM block[64]){ 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); + for(i=0; i<8; i++){ + init_vlc(&block_type_vlc[0][i], BLOCK_TYPE_VLC_BITS, 7, + &block_type_tab[0][i][0][1], 2, 1, + &block_type_tab[0][i][0][0], 2, 1, 1); } } @@ -235,7 +249,10 @@ 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; + if(f->version>1) + f->mv[i] = mv[i][0] + mv[i][1] *f->current_picture.linesize[0]/2; + else + f->mv[i] = (i&15) - 8 + ((i>>4)-8)*f->current_picture.linesize[0]/2; } } @@ -283,12 +300,18 @@ static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stri static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){ const int index= size2index[log2h][log2w]; const int h= 1<<log2h; - int code= get_vlc2(&f->gb, block_type_vlc[index].table, BLOCK_TYPE_VLC_BITS, 1); + int code= get_vlc2(&f->gb, block_type_vlc[1-(f->version>1)][index].table, BLOCK_TYPE_VLC_BITS, 1); + uint16_t *start= (uint16_t*)f->last_picture.data[0]; + uint16_t *end= start + stride*(f->avctx->height-h+1) - (1<<log2w); assert(code>=0 && code<=6); if(code == 0){ src += f->mv[ *f->bytestream++ ]; + if(start > src || src > end){ + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } mcdc(dst, src, log2w, h, stride, 1, 0); }else if(code == 1){ log2h--; @@ -298,8 +321,14 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo log2w--; decode_p_block(f, dst , src , log2w, log2h, stride); decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride); + }else if(code == 3 && f->version<2){ + mcdc(dst, src, log2w, h, stride, 1, 0); }else if(code == 4){ src += f->mv[ *f->bytestream++ ]; + if(start > src || src > end){ + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } 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++)); @@ -314,22 +343,28 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo } } -static int get32(void *p){ - return le2me_32(*(uint32_t*)p); -} - -static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){ +static int decode_p_frame(FourXContext *f, const 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); + unsigned int bitstream_size, bytestream_size, wordstream_size, extra; - if(bitstream_size+ bytestream_size+ wordstream_size + 20 != length + if(f->version>1){ + extra=20; + bitstream_size= AV_RL32(buf+8); + wordstream_size= AV_RL32(buf+12); + bytestream_size= AV_RL32(buf+16); + }else{ + extra=0; + bitstream_size = AV_RL16(buf-4); + wordstream_size= AV_RL16(buf-2); + bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0); + } + + if(bitstream_size+ bytestream_size+ wordstream_size + extra != length || bitstream_size > (1<<26) || bytestream_size > (1<<26) || wordstream_size > (1<<26) @@ -340,11 +375,11 @@ static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){ } 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); + f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (const uint32_t*)(buf + extra), 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; + f->wordstream= (const uint16_t*)(buf + extra + bitstream_size); + f->bytestream= buf + extra + bitstream_size + wordstream_size; init_mv(f); @@ -356,11 +391,13 @@ static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){ dst += 8*stride; } - if(bitstream_size != (get_bits_count(&f->gb)+31)/32*4) + if( bitstream_size != (get_bits_count(&f->gb)+31)/32*4 + || (((const char*)f->wordstream - (const char*)buf + 2)&~2) != extra + bitstream_size + wordstream_size + || (((const char*)f->bytestream - (const char*)buf + 3)&~3) != extra + bitstream_size + wordstream_size + bytestream_size) 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)) + -(((const char*)f->bytestream - (const char*)buf + 3)&~3) + (extra + bitstream_size + wordstream_size + bytestream_size), + -(((const char*)f->wordstream - (const char*)buf + 2)&~2) + (extra + bitstream_size + wordstream_size) ); return 0; @@ -471,14 +508,14 @@ static int decode_i_mb(FourXContext *f){ return 0; } -static uint8_t *read_huffman_tables(FourXContext *f, uint8_t * const buf){ +static const uint8_t *read_huffman_tables(FourXContext *f, const 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; + const uint8_t *ptr= buf; int j; memset(frequency, 0, sizeof(frequency)); @@ -548,16 +585,59 @@ static uint8_t *read_huffman_tables(FourXContext *f, uint8_t * const buf){ return ptr; } -static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){ +static int mix(int c0, int c1){ + int blue = 2*(c0&0x001F) + (c1&0x001F); + int green= (2*(c0&0x03E0) + (c1&0x03E0))>>5; + int red = 2*(c0>>10) + (c1>>10); + return red/3*1024 + green/3*32 + blue/3; +} + +static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ + int x, y, x2, y2; + 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; + + for(y=0; y<height; y+=16){ + for(x=0; x<width; x+=16){ + unsigned int color[4], bits; + memset(color, 0, sizeof(color)); +//warning following is purely guessed ... + color[0]= bytestream_get_le16(&buf); + color[1]= bytestream_get_le16(&buf); + + if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n"); + if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n"); + + color[2]= mix(color[0], color[1]); + color[3]= mix(color[1], color[0]); + + bits= bytestream_get_le32(&buf); + for(y2=0; y2<16; y2++){ + for(x2=0; x2<16; x2++){ + int index= 2*(x2>>2) + 8*(y2>>2); + dst[y2*stride+x2]= color[(bits>>index)&3]; + } + } + dst+=16; + } + dst += 16*stride - width; + } + + return 0; +} + +static int decode_i_frame(FourXContext *f, const 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; + const unsigned int bitstream_size= AV_RL32(buf); + const int token_count av_unused = AV_RL32(buf + bitstream_size + 8); + unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4); + const uint8_t *prestream= buf + bitstream_size + 12; if(prestream_size + bitstream_size + 12 != length || bitstream_size > (1<<26) @@ -573,7 +653,7 @@ static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){ 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); + f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (const 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; @@ -596,23 +676,23 @@ static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const 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)); + frame_4cc= AV_RL32(buf); + if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){ + av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(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); + const int id= AV_RL32(buf+12); + const int whole_size= AV_RL32(buf+16); CFrameBuffer *cfrm; for(i=0; i<CFRAME_BUFFER_COUNT; i++){ @@ -675,11 +755,15 @@ static int decode_frame(AVCodecContext *avctx, return -1; } - if(frame_4cc == ff_get_fourcc("ifrm")){ + if(frame_4cc == ff_get_fourcc("ifr2")){ + p->pict_type= I_TYPE; + if(decode_i2_frame(f, buf-4, frame_size) < 0) + return -1; + }else 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")){ + }else if(frame_4cc == ff_get_fourcc("pfrm") || frame_4cc == ff_get_fourcc("pfr2")){ p->pict_type= P_TYPE; if(decode_p_frame(f, buf, frame_size) < 0) return -1; @@ -711,10 +795,17 @@ static void common_init(AVCodecContext *avctx){ static int decode_init(AVCodecContext *avctx){ FourXContext * const f = avctx->priv_data; + if(avctx->extradata_size != 4 || !avctx->extradata) { + av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n"); + return 1; + } + + f->version= AV_RL32(avctx->extradata)>>16; common_init(avctx); init_vlcs(f); - avctx->pix_fmt= PIX_FMT_RGB565; + if(f->version>2) avctx->pix_fmt= PIX_FMT_RGB565; + else avctx->pix_fmt= PIX_FMT_RGB555; return 0; } diff --git a/contrib/ffmpeg/libavcodec/8bps.c b/contrib/ffmpeg/libavcodec/8bps.c index 3d4eb05b3..23883457d 100644 --- a/contrib/ffmpeg/libavcodec/8bps.c +++ b/contrib/ffmpeg/libavcodec/8bps.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -35,7 +34,6 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" @@ -59,14 +57,14 @@ typedef struct EightBpsContext { * Decode a frame * */ -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { - EightBpsContext * const c = (EightBpsContext *)avctx->priv_data; - unsigned char *encoded = (unsigned char *)buf; + EightBpsContext * const c = avctx->priv_data; + const unsigned char *encoded = buf; unsigned char *pixptr, *pixptr_end; unsigned int height = avctx->height; // Real image height unsigned int dlen, p, row; - unsigned char *lp, *dp; + const unsigned char *lp, *dp; unsigned char count; unsigned int px_inc; unsigned int planes = c->planes; @@ -99,7 +97,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 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)); + dlen = be2me_16(*(const unsigned short *)(lp+row*2)); /* Decode a row of this plane */ while(dlen > 0) { if(dp + 1 >= buf+buf_size) return -1; @@ -152,10 +150,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 */ static int decode_init(AVCodecContext *avctx) { - EightBpsContext * const c = (EightBpsContext *)avctx->priv_data; + EightBpsContext * const c = avctx->priv_data; c->avctx = avctx; - avctx->has_b_frames = 0; c->pic.data[0] = NULL; @@ -213,7 +210,7 @@ static int decode_init(AVCodecContext *avctx) */ static int decode_end(AVCodecContext *avctx) { - EightBpsContext * const c = (EightBpsContext *)avctx->priv_data; + EightBpsContext * const c = avctx->priv_data; if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); diff --git a/contrib/ffmpeg/libavcodec/Makefile b/contrib/ffmpeg/libavcodec/Makefile index 9ec6b96f1..3ae5f3ac9 100644 --- a/contrib/ffmpeg/libavcodec/Makefile +++ b/contrib/ffmpeg/libavcodec/Makefile @@ -4,69 +4,62 @@ # include ../config.mak -CFLAGS+=-I$(SRC_PATH)/libswscale $(AMR_CFLAGS) - -OBJS= bitstream.o \ - utils.o \ - allcodecs.o \ - mpegvideo.o \ - jrevdct.o \ - jfdctfst.o \ - jfdctint.o\ - mjpeg.o \ - resample.o \ - resample2.o \ - dsputil.o \ - motion_est.o \ - imgconvert.o \ - mpeg12.o \ - mpegaudiodec.o \ - simple_idct.o \ - ratecontrol.o \ - eval.o \ - error_resilience.o \ - fft.o \ - mdct.o \ - raw.o \ - golomb.o \ - cabac.o\ - faandct.o \ - parser.o \ - vp3dsp.o \ - h264idct.o \ - rangecoder.o \ - pnm.o \ - h263.o \ - msmpeg4.o \ - h263dec.o \ - opt.o \ - bitstream_filter.o \ - audioconvert.o \ +CFLAGS += -I$(SRC_PATH)/libswscale -I$(SRC_PATH)/libavcodec + +OBJS = allcodecs.o \ + audioconvert.o \ + bitstream.o \ + bitstream_filter.o \ + dsputil.o \ + error_resilience.o \ + eval.o \ + faanidct.o \ + imgconvert.o \ + jrevdct.o \ + mpeg12.o \ + mpeg12data.o \ + mpegvideo.o \ + opt.o \ + parser.o \ + raw.o \ + resample.o \ + resample2.o \ + simple_idct.o \ + utils.o \ HEADERS = avcodec.h opt.h +OBJS-$(CONFIG_ENCODERS) += faandct.o jfdctfst.o jfdctint.o + OBJS-$(CONFIG_AASC_DECODER) += aasc.o -OBJS-$(CONFIG_AC3_ENCODER) += ac3enc.o ac3.o +OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3tab.o ac3.o mdct.o fft.o +OBJS-$(CONFIG_AC3_ENCODER) += ac3enc.o ac3tab.o ac3.o OBJS-$(CONFIG_ALAC_DECODER) += alac.o +OBJS-$(CONFIG_AMV_DECODER) += sp5xdec.o mjpegdec.o mjpeg.o +OBJS-$(CONFIG_APE_DECODER) += apedec.o OBJS-$(CONFIG_ASV1_DECODER) += asv1.o OBJS-$(CONFIG_ASV1_ENCODER) += asv1.o OBJS-$(CONFIG_ASV2_DECODER) += asv1.o OBJS-$(CONFIG_ASV2_ENCODER) += asv1.o +OBJS-$(CONFIG_ATRAC3_DECODER) += atrac3.o mdct.o fft.o OBJS-$(CONFIG_AVS_DECODER) += avs.o +OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o OBJS-$(CONFIG_BMP_DECODER) += bmp.o OBJS-$(CONFIG_BMP_ENCODER) += bmpenc.o -OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdsp.o +OBJS-$(CONFIG_C93_DECODER) += c93.o +OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o golomb.o OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o OBJS-$(CONFIG_CLJR_DECODER) += cljr.o OBJS-$(CONFIG_CLJR_ENCODER) += cljr.o -OBJS-$(CONFIG_COOK_DECODER) += cook.o +OBJS-$(CONFIG_COOK_DECODER) += cook.o mdct.o fft.o OBJS-$(CONFIG_CSCD_DECODER) += cscd.o OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o OBJS-$(CONFIG_DCA_DECODER) += dca.o -OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o -OBJS-$(CONFIG_DSICINVIDEO_DECODER) += dsicinav.o +OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o +OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o mpegvideo_enc.o motion_est.o ratecontrol.o OBJS-$(CONFIG_DSICINAUDIO_DECODER) += dsicinav.o +OBJS-$(CONFIG_DSICINVIDEO_DECODER) += dsicinav.o OBJS-$(CONFIG_DVBSUB_DECODER) += dvbsubdec.o OBJS-$(CONFIG_DVBSUB_ENCODER) += dvbsub.o OBJS-$(CONFIG_DVDSUB_DECODER) += dvdsubdec.o @@ -75,130 +68,186 @@ OBJS-$(CONFIG_DVVIDEO_DECODER) += dv.o OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o OBJS-$(CONFIG_DXA_DECODER) += dxa.o OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o -OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o -OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o +OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o rangecoder.o golomb.o +OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o rangecoder.o OBJS-$(CONFIG_FFVHUFF_DECODER) += huffyuv.o OBJS-$(CONFIG_FFVHUFF_ENCODER) += huffyuv.o -OBJS-$(CONFIG_FLAC_DECODER) += flac.o -OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o +OBJS-$(CONFIG_FLAC_DECODER) += flac.o golomb.o +OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o golomb.o OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o +OBJS-$(CONFIG_FLV_DECODER) += h263dec.o h263.o +OBJS-$(CONFIG_FLV_ENCODER) += mpegvideo_enc.o motion_est.o ratecontrol.o h263.o OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o -OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o +OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o huffman.o OBJS-$(CONFIG_GIF_DECODER) += gifdec.o lzw.o OBJS-$(CONFIG_GIF_ENCODER) += gif.o -OBJS-$(CONFIG_H261_DECODER) += h261.o -OBJS-$(CONFIG_H261_ENCODER) += h261.o -OBJS-$(CONFIG_H264_DECODER) += h264.o -OBJS-$(CONFIG_H264_ENCODER) += h264enc.o h264dsp.o +OBJS-$(CONFIG_H261_DECODER) += h261dec.o h261.o +OBJS-$(CONFIG_H261_ENCODER) += h261enc.o h261.o mpegvideo_enc.o motion_est.o ratecontrol.o +OBJS-$(CONFIG_H263_DECODER) += h263dec.o h263.o +OBJS-$(CONFIG_H263I_DECODER) += h263dec.o h263.o +OBJS-$(CONFIG_H263_ENCODER) += mpegvideo_enc.o motion_est.o ratecontrol.o h263.o +OBJS-$(CONFIG_H263P_ENCODER) += mpegvideo_enc.o motion_est.o ratecontrol.o h263.o +OBJS-$(CONFIG_H264_DECODER) += h264.o h264idct.o h264pred.o cabac.o golomb.o +OBJS-$(CONFIG_H264_ENCODER) += h264enc.o h264dspenc.o OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o -OBJS-$(CONFIG_IMC_DECODER) += imc.o +OBJS-$(CONFIG_IMC_DECODER) += imc.o mdct.o fft.o OBJS-$(CONFIG_INDEO2_DECODER) += indeo2.o OBJS-$(CONFIG_INDEO3_DECODER) += indeo3.o -OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o +OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o mjpegdec.o mjpeg.o golomb.o +OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o golomb.o OBJS-$(CONFIG_KMVC_DECODER) += kmvc.o -OBJS-$(CONFIG_LOCO_DECODER) += loco.o +OBJS-$(CONFIG_LJPEG_ENCODER) += ljpegenc.o mjpegenc.o mjpeg.o mpegvideo_enc.o motion_est.o ratecontrol.o +OBJS-$(CONFIG_LOCO_DECODER) += loco.o golomb.o OBJS-$(CONFIG_MACE3_DECODER) += mace.o OBJS-$(CONFIG_MACE6_DECODER) += mace.o +OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpeg.o +OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpeg.o mpegvideo_enc.o motion_est.o ratecontrol.o +OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o mjpegdec.o mjpeg.o OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o -OBJS-$(CONFIG_MP2_ENCODER) += mpegaudio.o -OBJS-$(CONFIG_MPC7_DECODER) += mpc.o +OBJS-$(CONFIG_MP2_DECODER) += mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o +OBJS-$(CONFIG_MP2_ENCODER) += mpegaudioenc.o mpegaudio.o mpegaudiodata.o +OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o +OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o +OBJS-$(CONFIG_MP3ON4_DECODER) += mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o +OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o +OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o +OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpeg12data.o mpegvideo_enc.o motion_est.o ratecontrol.o +OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpeg12data.o mpegvideo_enc.o motion_est.o ratecontrol.o +OBJS-$(CONFIG_MPEG4_DECODER) += h263dec.o h263.o +OBJS-$(CONFIG_MPEG4_ENCODER) += mpegvideo_enc.o motion_est.o ratecontrol.o h263.o +OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o h263.o +OBJS-$(CONFIG_MSMPEG4V1_ENCODER) += msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o +OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o h263.o +OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o +OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o h263.o +OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o -OBJS-$(CONFIG_MSZH_DECODER) += lcl.o +OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o +OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o mdct.o fft.o OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o -OBJS-$(CONFIG_PNG_DECODER) += png.o -OBJS-$(CONFIG_PNG_ENCODER) += png.o -OBJS-$(CONFIG_QDM2_DECODER) += qdm2.o +OBJS-$(CONFIG_PAM_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PCX_DECODER) += pcx.o +OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o +OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o +OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PTX_DECODER) += ptx.o +OBJS-$(CONFIG_QDM2_DECODER) += qdm2.o mdct.o fft.o mpegaudiodec.o mpegaudiodecheader.o mpegaudio.o mpegaudiodata.o OBJS-$(CONFIG_QDRAW_DECODER) += qdrw.o OBJS-$(CONFIG_QPEG_DECODER) += qpeg.o OBJS-$(CONFIG_QTRLE_DECODER) += qtrle.o +OBJS-$(CONFIG_QTRLE_ENCODER) += qtrleenc.o OBJS-$(CONFIG_RA_144_DECODER) += ra144.o OBJS-$(CONFIG_RA_288_DECODER) += ra288.o -OBJS-$(CONFIG_ROQ_DECODER) += roqvideo.o +OBJS-$(CONFIG_RAWVIDEO_DECODER) += rawdec.o +OBJS-$(CONFIG_RAWVIDEO_ENCODER) += rawenc.o +OBJS-$(CONFIG_ROQ_DECODER) += roqvideodec.o roqvideo.o +OBJS-$(CONFIG_ROQ_ENCODER) += roqvideoenc.o roqvideo.o elbg.o OBJS-$(CONFIG_ROQ_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_ROQ_DPCM_ENCODER) += roqaudioenc.o OBJS-$(CONFIG_RPZA_DECODER) += rpza.o -OBJS-$(CONFIG_RV10_DECODER) += rv10.o -OBJS-$(CONFIG_RV10_ENCODER) += rv10.o -OBJS-$(CONFIG_RV20_DECODER) += rv10.o -OBJS-$(CONFIG_RV20_ENCODER) += rv10.o -OBJS-$(CONFIG_SHORTEN_DECODER) += shorten.o +OBJS-$(CONFIG_RV10_DECODER) += rv10.o h263.o +OBJS-$(CONFIG_RV10_ENCODER) += rv10.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o +OBJS-$(CONFIG_RV20_DECODER) += rv10.o h263.o +OBJS-$(CONFIG_RV20_ENCODER) += rv10.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o +OBJS-$(CONFIG_SGI_DECODER) += sgidec.o +OBJS-$(CONFIG_SGI_ENCODER) += sgienc.o rle.o +OBJS-$(CONFIG_SHORTEN_DECODER) += shorten.o golomb.o OBJS-$(CONFIG_SMACKAUD_DECODER) += smacker.o OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o OBJS-$(CONFIG_SMC_DECODER) += smc.o -OBJS-$(CONFIG_SNOW_DECODER) += snow.o -OBJS-$(CONFIG_SNOW_ENCODER) += snow.o +OBJS-$(CONFIG_SNOW_DECODER) += snow.o rangecoder.o +OBJS-$(CONFIG_SNOW_ENCODER) += snow.o rangecoder.o motion_est.o ratecontrol.o h263.o OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o -OBJS-$(CONFIG_SONIC_DECODER) += sonic.o -OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o -OBJS-$(CONFIG_SONIC_LS_DECODER) += sonic.o -OBJS-$(CONFIG_SVQ1_DECODER) += svq1.o -OBJS-$(CONFIG_SVQ1_ENCODER) += svq1.o -OBJS-$(CONFIG_SVQ3_DECODER) += h264.o +OBJS-$(CONFIG_SONIC_DECODER) += sonic.o golomb.o +OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o golomb.o +OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o golomb.o +OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o mjpegdec.o mjpeg.o +OBJS-$(CONFIG_SUNRAST_DECODER) += sunrast.o +OBJS-$(CONFIG_SVQ1_DECODER) += svq1dec.o svq1.o h263.o +OBJS-$(CONFIG_SVQ1_ENCODER) += svq1enc.o svq1.o motion_est.o h263.o +OBJS-$(CONFIG_SVQ3_DECODER) += h264.o h264idct.o h264pred.o cabac.o golomb.o OBJS-$(CONFIG_TARGA_DECODER) += targa.o -OBJS-$(CONFIG_TARGA_ENCODER) += targaenc.o -OBJS-$(CONFIG_THEORA_DECODER) += vp3.o xiph.o +OBJS-$(CONFIG_TARGA_ENCODER) += targaenc.o rle.o +OBJS-$(CONFIG_THEORA_DECODER) += vp3.o xiph.o vp3dsp.o +OBJS-$(CONFIG_THP_DECODER) += mjpegdec.o mjpeg.o OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o OBJS-$(CONFIG_TIFF_DECODER) += tiff.o lzw.o +OBJS-$(CONFIG_TIFF_ENCODER) += tiffenc.o rle.o lzwenc.o OBJS-$(CONFIG_TRUEMOTION1_DECODER) += truemotion1.o OBJS-$(CONFIG_TRUEMOTION2_DECODER) += truemotion2.o OBJS-$(CONFIG_TRUESPEECH_DECODER) += truespeech.o OBJS-$(CONFIG_TSCC_DECODER) += tscc.o OBJS-$(CONFIG_TTA_DECODER) += tta.o +OBJS-$(CONFIG_TXD_DECODER) += txd.o s3tc.o OBJS-$(CONFIG_ULTI_DECODER) += ulti.o -OBJS-$(CONFIG_VC1_DECODER) += vc1.o vc1dsp.o +OBJS-$(CONFIG_VB_DECODER) += vb.o +OBJS-$(CONFIG_VC1_DECODER) += vc1.o vc1data.o vc1dsp.o msmpeg4data.o intrax8.o intrax8dsp.o OBJS-$(CONFIG_VCR1_DECODER) += vcr1.o OBJS-$(CONFIG_VCR1_ENCODER) += vcr1.o OBJS-$(CONFIG_VMDAUDIO_DECODER) += vmdav.o OBJS-$(CONFIG_VMDVIDEO_DECODER) += vmdav.o OBJS-$(CONFIG_VMNC_DECODER) += vmnc.o -OBJS-$(CONFIG_VORBIS_DECODER) += vorbis.o vorbis_data.o xiph.o -OBJS-$(CONFIG_VORBIS_ENCODER) += vorbis_enc.o vorbis.o vorbis_data.o -OBJS-$(CONFIG_VP3_DECODER) += vp3.o -OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o -OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o +OBJS-$(CONFIG_VORBIS_DECODER) += vorbis_dec.o vorbis.o vorbis_data.o xiph.o mdct.o fft.o +OBJS-$(CONFIG_VORBIS_ENCODER) += vorbis_enc.o vorbis.o vorbis_data.o mdct.o fft.o +OBJS-$(CONFIG_VP3_DECODER) += vp3.o vp3dsp.o +OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vp3dsp.o +OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o vp3dsp.o huffman.o +OBJS-$(CONFIG_VP6A_DECODER) += vp6.o vp56.o vp56data.o vp3dsp.o huffman.o +OBJS-$(CONFIG_VP6F_DECODER) += vp6.o vp56.o vp56data.o vp3dsp.o huffman.o OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o -OBJS-$(CONFIG_WMAV1_DECODER) += wmadec.o wma.o -OBJS-$(CONFIG_WMAV2_DECODER) += wmadec.o wma.o -OBJS-$(CONFIG_WMAV1_ENCODER) += wmaenc.o wma.o -OBJS-$(CONFIG_WMAV2_ENCODER) += wmaenc.o wma.o -OBJS-$(CONFIG_WMV3_DECODER) += vc1.o vc1dsp.o +OBJS-$(CONFIG_WMAV1_DECODER) += wmadec.o wma.o mdct.o fft.o +OBJS-$(CONFIG_WMAV1_ENCODER) += wmaenc.o wma.o mdct.o fft.o +OBJS-$(CONFIG_WMAV2_DECODER) += wmadec.o wma.o mdct.o fft.o +OBJS-$(CONFIG_WMAV2_ENCODER) += wmaenc.o wma.o mdct.o fft.o +OBJS-$(CONFIG_WMV1_DECODER) += h263dec.o h263.o +OBJS-$(CONFIG_WMV1_ENCODER) += mpegvideo_enc.o motion_est.o ratecontrol.o h263.o +OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o msmpeg4.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o +OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o msmpeg4.o msmpeg4data.o mpegvideo_enc.o motion_est.o ratecontrol.o h263.o +OBJS-$(CONFIG_WMV3_DECODER) += vc1.o vc1data.o vc1dsp.o OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o OBJS-$(CONFIG_XAN_WC3_DECODER) += xan.o OBJS-$(CONFIG_XAN_WC4_DECODER) += xan.o OBJS-$(CONFIG_XL_DECODER) += xl.o -OBJS-$(CONFIG_ZLIB_DECODER) += lcl.o -OBJS-$(CONFIG_ZLIB_ENCODER) += lcl.o +OBJS-$(CONFIG_XSUB_DECODER) += xsubdec.o +OBJS-$(CONFIG_ZLIB_DECODER) += lcldec.o +OBJS-$(CONFIG_ZLIB_ENCODER) += lclenc.o OBJS-$(CONFIG_ZMBV_DECODER) += zmbv.o OBJS-$(CONFIG_ZMBV_ENCODER) += zmbvenc.o -OBJS-$(CONFIG_PCM_S32LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S32LE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_S32BE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S32BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U32LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U32LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S32LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S32LE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_U32BE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_U32BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_S24LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_S24LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U32LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U32LE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_S24BE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S24BE_ENCODER) += pcm.o -OBJS-$(CONFIG_PCM_U24LE_DECODER) += pcm.o -OBJS-$(CONFIG_PCM_U24LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S24LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_S24LE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_U24BE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_U24BE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_U24LE_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_U24LE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_S24DAUD_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S24DAUD_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_S16LE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S16LE_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_S16LE_PLANAR_DECODER)+= pcm.o OBJS-$(CONFIG_PCM_S16BE_DECODER) += pcm.o OBJS-$(CONFIG_PCM_S16BE_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_U16LE_DECODER) += pcm.o @@ -213,103 +262,92 @@ OBJS-$(CONFIG_PCM_ALAW_DECODER) += pcm.o OBJS-$(CONFIG_PCM_ALAW_ENCODER) += pcm.o OBJS-$(CONFIG_PCM_MULAW_DECODER) += pcm.o OBJS-$(CONFIG_PCM_MULAW_ENCODER) += pcm.o +OBJS-$(CONFIG_PCM_ZORK_DECODER) += pcm.o +OBJS-$(CONFIG_PCM_ZORK_ENCODER) += pcm.o OBJS-$(CONFIG_ADPCM_4XM_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_4XM_ENCODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adx.o -OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adx.o +OBJS-$(CONFIG_ADPCM_ADX_DECODER) += adxdec.o +OBJS-$(CONFIG_ADPCM_ADX_ENCODER) += adxenc.o OBJS-$(CONFIG_ADPCM_CT_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_CT_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_EA_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_EA_ENCODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_R1_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_R2_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_R3_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_EA_XAS_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o +OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_DK3_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_DK4_ENCODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_EA_SEAD_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_QT_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_QT_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_SMJPEG_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_WAV_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_WAV_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_WS_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_IMA_WS_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_MS_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_MS_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_SBPRO_2_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SBPRO_2_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_SBPRO_3_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SBPRO_3_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_SBPRO_4_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_SBPRO_4_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_SWF_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_SWF_ENCODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_THP_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_XA_DECODER) += adpcm.o -OBJS-$(CONFIG_ADPCM_XA_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcm.o +# libavformat dependencies +OBJS-$(CONFIG_MATROSKA_MUXER) += xiph.o +OBJS-$(CONFIG_OGG_MUXER) += xiph.o + # external codec libraries -OBJS-$(CONFIG_LIBA52) += a52dec.o -OBJS-$(CONFIG_LIBDTS) += dtsdec.o -OBJS-$(CONFIG_LIBFAAC) += faac.o -OBJS-$(CONFIG_LIBFAAD) += faad.o +OBJS-$(CONFIG_LIBA52) += liba52.o +OBJS-$(CONFIG_LIBAMR_NB) += libamr.o +OBJS-$(CONFIG_LIBAMR_WB) += libamr.o +OBJS-$(CONFIG_LIBFAAC) += libfaac.o +OBJS-$(CONFIG_LIBFAAD) += libfaad.o OBJS-$(CONFIG_LIBGSM) += libgsm.o -OBJS-$(CONFIG_LIBMP3LAME) += mp3lameaudio.o +OBJS-$(CONFIG_LIBMP3LAME) += libmp3lame.o OBJS-$(CONFIG_LIBTHEORA) += libtheoraenc.o -OBJS-$(CONFIG_LIBVORBIS) += oggvorbis.o -OBJS-$(CONFIG_X264) += x264.o -OBJS-$(CONFIG_XVID) += xvidff.o xvid_rc.o - -OBJS-$(CONFIG_AMR) += amr.o -OBJS-$(CONFIG_AMR_NB) += amr_float/sp_dec.o \ - amr_float/sp_enc.o \ - amr_float/interf_dec.o \ - amr_float/interf_enc.o - -ifeq ($(CONFIG_AMR_NB_FIXED),yes) -EXTRAOBJS += amr/*.o -EXTRADEPS=amrlibs -endif - -OBJS-$(CONFIG_AMR_WB) += amrwb_float/dec_acelp.o \ - amrwb_float/dec_dtx.o \ - amrwb_float/dec_gain.o \ - amrwb_float/dec_if.o \ - amrwb_float/dec_lpc.o \ - amrwb_float/dec_main.o \ - amrwb_float/dec_rom.o \ - amrwb_float/dec_util.o \ - amrwb_float/enc_acelp.o \ - amrwb_float/enc_dtx.o \ - amrwb_float/enc_gain.o \ - amrwb_float/enc_if.o \ - amrwb_float/enc_lpc.o \ - amrwb_float/enc_main.o \ - amrwb_float/enc_rom.o \ - amrwb_float/enc_util.o \ - amrwb_float/if_rom.o - -OBJS-$(CONFIG_AAC_PARSER) += parser.o -OBJS-$(CONFIG_AC3_PARSER) += parser.o ac3.o -OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs.o parser.o -OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsubdec.o -OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsubdec.o -OBJS-$(CONFIG_H261_PARSER) += h261.o -OBJS-$(CONFIG_H263_PARSER) += h263dec.o -OBJS-$(CONFIG_H264_PARSER) += h264.o -OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg.o -OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += parser.o -OBJS-$(CONFIG_MPEGAUDIO_PARSER) += parser.o -OBJS-$(CONFIG_MPEGVIDEO_PARSER) += parser.o -OBJS-$(CONFIG_PNM_PARSER) += pnm.o +OBJS-$(CONFIG_LIBVORBIS) += libvorbis.o +OBJS-$(CONFIG_LIBX264) += libx264.o +OBJS-$(CONFIG_LIBXVID) += libxvidff.o libxvid_rc.o + + +OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o +OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o aac_ac3_parser.o +OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o +OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o +OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsub_parser.o +OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsub_parser.o +OBJS-$(CONFIG_H261_PARSER) += h261_parser.o +OBJS-$(CONFIG_H263_PARSER) += h263_parser.o +OBJS-$(CONFIG_H264_PARSER) += h264_parser.o +OBJS-$(CONFIG_MJPEG_PARSER) += mjpeg_parser.o +OBJS-$(CONFIG_MLP_PARSER) += mlp_parser.o +OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o +OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o mpegaudiodecheader.o mpegaudiodata.o +OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o +OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o +OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o + +OBJS-$(CONFIG_DUMP_EXTRADATA_BSF) += dump_extradata_bsf.o +OBJS-$(CONFIG_H264_MP4TOANNEXB_BSF) += h264_mp4toannexb_bsf.o +OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF) += imx_dump_header_bsf.o +OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF) += mjpega_dump_header_bsf.o +OBJS-$(CONFIG_MOV2TEXTSUB_BSF) += movsub_bsf.o +OBJS-$(CONFIG_MP3_HEADER_COMPRESS_BSF) += mp3_header_compress_bsf.o +OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF) += mp3_header_decompress_bsf.o mpegaudiodata.o +OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o +OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o +OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o +OBJS-$(HAVE_BEOSTHREADS) += beosthread.o +OBJS-$(HAVE_OS2THREADS) += os2thread.o OBJS-$(HAVE_PTHREADS) += pthread.o OBJS-$(HAVE_W32THREADS) += w32thread.o -OBJS-$(HAVE_OS2THREADS) += os2thread.o -OBJS-$(HAVE_BEOSTHREADS) += beosthread.o OBJS-$(HAVE_XVMC_ACCEL) += xvmcvideo.o @@ -318,7 +356,7 @@ OBJS += imgresample.o endif # processor-specific code -ifeq ($(TARGET_MMX),yes) +ifeq ($(HAVE_MMX),yes) OBJS += i386/fdct_mmx.o \ i386/cputest.o \ i386/dsputil_mmx.o \ @@ -327,76 +365,92 @@ OBJS += i386/fdct_mmx.o \ i386/simple_idct_mmx.o \ i386/idct_mmx_xvid.o \ i386/fft_sse.o \ - i386/vp3dsp_mmx.o \ - i386/vp3dsp_sse2.o \ i386/fft_3dn.o \ i386/fft_3dn2.o \ OBJS-$(CONFIG_GPL) += i386/idct_mmx.o + +OBJS-$(CONFIG_ENCODERS) += i386/dsputilenc_mmx.o + OBJS-$(CONFIG_CAVS_DECODER) += i386/cavsdsp_mmx.o +OBJS-$(CONFIG_FLAC_ENCODER) += i386/flacdsp_mmx.o OBJS-$(CONFIG_SNOW_DECODER) += i386/snowdsp_mmx.o +OBJS-$(CONFIG_VC1_DECODER) += i386/vc1dsp_mmx.o +OBJS-$(CONFIG_VP3_DECODER) += i386/vp3dsp_mmx.o i386/vp3dsp_sse2.o +OBJS-$(CONFIG_VP5_DECODER) += i386/vp3dsp_mmx.o i386/vp3dsp_sse2.o +OBJS-$(CONFIG_VP6_DECODER) += i386/vp3dsp_mmx.o i386/vp3dsp_sse2.o +OBJS-$(CONFIG_VP6A_DECODER) += i386/vp3dsp_mmx.o i386/vp3dsp_sse2.o +OBJS-$(CONFIG_VP6F_DECODER) += i386/vp3dsp_mmx.o i386/vp3dsp_sse2.o +OBJS-$(CONFIG_WMV3_DECODER) += i386/vc1dsp_mmx.o endif -ASM_OBJS-$(TARGET_ARCH_ARMV4L) += armv4l/jrevdct_arm.o \ +ASM_OBJS-$(ARCH_ARMV4L) += armv4l/jrevdct_arm.o \ armv4l/simple_idct_arm.o \ armv4l/dsputil_arm_s.o \ -OBJS-$(TARGET_ARCH_ARMV4L) += armv4l/dsputil_arm.o \ +OBJS-$(ARCH_ARMV4L) += armv4l/dsputil_arm.o \ armv4l/mpegvideo_arm.o \ -OBJS-$(TARGET_IWMMXT) += armv4l/dsputil_iwmmxt.o \ +OBJS-$(HAVE_IWMMXT) += armv4l/dsputil_iwmmxt.o \ armv4l/mpegvideo_iwmmxt.o \ -ASM_OBJS-$(TARGET_ARMV5TE) += armv4l/simple_idct_armv5te.o \ +ASM_OBJS-$(HAVE_ARMV5TE) += armv4l/simple_idct_armv5te.o \ armv4l/mpegvideo_armv5te.o \ -ASM_OBJS-$(HAVE_ARMV6) += armv4l/simple_idct_armv6.o +ASM_OBJS-$(HAVE_ARMV6) += armv4l/simple_idct_armv6.o \ -OBJS-$(TARGET_ARCH_SPARC) += sparc/dsputil_vis.o \ - -sparc/dsputil_vis.o: CFLAGS += -mcpu=ultrasparc -mtune=ultrasparc +OBJS-$(HAVE_VIS) += sparc/dsputil_vis.o \ + sparc/simple_idct_vis.o \ OBJS-$(HAVE_MLIB) += mlib/dsputil_mlib.o \ -OBJS-$(TARGET_ARCH_ALPHA) += alpha/dsputil_alpha.o \ +OBJS-$(ARCH_ALPHA) += alpha/dsputil_alpha.o \ + alpha/motion_est_alpha.o \ alpha/mpegvideo_alpha.o \ alpha/simple_idct_alpha.o \ - alpha/motion_est_alpha.o \ -ASM_OBJS-$(TARGET_ARCH_ALPHA) += alpha/dsputil_alpha_asm.o \ +ASM_OBJS-$(ARCH_ALPHA) += alpha/dsputil_alpha_asm.o \ alpha/motion_est_mvi_asm.o \ -OBJS-$(TARGET_ARCH_POWERPC) += ppc/dsputil_ppc.o \ - ppc/mpegvideo_ppc.o \ +OBJS-$(ARCH_POWERPC) += ppc/dsputil_ppc.o \ -OBJS-$(TARGET_MMI) += ps2/dsputil_mmi.o \ +OBJS-$(HAVE_MMI) += ps2/dsputil_mmi.o \ ps2/idct_mmi.o \ ps2/mpegvideo_mmi.o \ -OBJS-$(TARGET_ARCH_SH4) += sh4/idct_sh4.o \ - sh4/dsputil_sh4.o \ +OBJS-$(ARCH_SH4) += sh4/idct_sh4.o \ sh4/dsputil_align.o \ + sh4/dsputil_sh4.o \ -OBJS-$(TARGET_ALTIVEC) += ppc/dsputil_altivec.o \ - ppc/mpegvideo_altivec.o \ - ppc/idct_altivec.o \ - ppc/fft_altivec.o \ - ppc/gmc_altivec.o \ +ALTIVEC-OBJS-yes += ppc/dsputil_altivec.o \ ppc/fdct_altivec.o \ + ppc/fft_altivec.o \ ppc/float_altivec.o \ + ppc/gmc_altivec.o \ + ppc/idct_altivec.o \ + ppc/int_altivec.o \ + ppc/mpegvideo_altivec.o \ -ifeq ($(TARGET_ALTIVEC),yes) -OBJS-$(CONFIG_H264_DECODER) += ppc/h264_altivec.o -OBJS-$(CONFIG_SNOW_DECODER) += ppc/snow_altivec.o -OBJS-$(CONFIG_VC1_DECODER) += ppc/vc1dsp_altivec.o -OBJS-$(CONFIG_WMV3_DECODER) += ppc/vc1dsp_altivec.o -endif +ALTIVEC-OBJS-$(CONFIG_H264_DECODER) += ppc/h264_altivec.o +ALTIVEC-OBJS-$(CONFIG_SNOW_DECODER) += ppc/snow_altivec.o +ALTIVEC-OBJS-$(CONFIG_VC1_DECODER) += ppc/vc1dsp_altivec.o +ALTIVEC-OBJS-$(CONFIG_WMV3_DECODER) += ppc/vc1dsp_altivec.o -OBJS-$(TARGET_ARCH_BFIN) += bfin/dsputil_bfin.o \ +# -maltivec is needed in order to build AltiVec code. +$(ALTIVEC-OBJS-yes): CFLAGS += -maltivec -mabi=altivec -ASM_OBJS-$(TARGET_ARCH_BFIN) += bfin/pixels_bfin.o \ - bfin/idct_bfin.o \ +# check_altivec must be built without -maltivec +OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS-yes) \ + ppc/check_altivec.o + +OBJS-$(ARCH_BFIN) += bfin/dsputil_bfin.o \ + bfin/mpegvideo_bfin.o \ + bfin/vp3_bfin.o \ + +ASM_OBJS-$(ARCH_BFIN) += bfin/pixels_bfin.o \ bfin/fdct_bfin.o \ + bfin/idct_bfin.o \ + bfin/vp3_idct_bfin.o \ EXTRALIBS := -L$(BUILD_ROOT)/libavutil -lavutil$(BUILDSUF) $(EXTRALIBS) @@ -404,45 +458,28 @@ NAME=avcodec LIBVERSION=$(LAVCVERSION) LIBMAJOR=$(LAVCMAJOR) -TESTS= imgresample-test fft-test dct-test -ifeq ($(TARGET_ARCH_X86),yes) -TESTS+= cpuid_test motion-test +TESTS = $(addsuffix -test$(EXESUF), cabac dct eval fft h264 imgresample rangecoder snow) +ifeq ($(ARCH_X86),yes) +TESTS += cpuid-test$(EXESUF) motion-test$(EXESUF) endif include ../common.mak -amrlibs: - $(MAKE) -C amr spclib fipoplib - -tests: apiexample $(TESTS) - clean:: rm -f \ - i386/*.o i386/*~ \ + alpha/*.o alpha/*~ \ armv4l/*.o armv4l/*~ \ + bfin/*.o bfin/*~ \ + i386/*.o i386/*~ \ mlib/*.o mlib/*~ \ - alpha/*.o alpha/*~ \ ppc/*.o ppc/*~ \ ps2/*.o ps2/*~ \ sh4/*.o sh4/*~ \ sparc/*.o sparc/*~ \ - amr_float/*.o \ - apiexample $(TESTS) - -$(MAKE) -C amr clean - -$(MAKE) -C amrwb_float -f makefile.gcc clean - -apiexample: apiexample.o $(LIB) - -cpuid_test: i386/cputest.c - $(CC) $(CFLAGS) -D__TEST__ -o $@ $< - -imgresample-test: imgresample.c $(LIB) - $(CC) $(CFLAGS) -DTEST -o $@ $^ $(EXTRALIBS) - -dct-test: dct-test.o fdctref.o $(LIB) - -motion-test: motion_test.o $(LIB) - -fft-test: fft-test.o $(LIB) + apiexample$(EXESUF) -.PHONY: amrlibs tests +cpuid-test$(EXESUF): i386/cputest.c +apiexample$(EXESUF): apiexample.o $(LIBNAME) +dct-test$(EXESUF): dct-test.o fdctref.o $(LIBNAME) +fft-test$(EXESUF): fft-test.o $(LIBNAME) +motion-test$(EXESUF): motion-test.o $(LIBNAME) diff --git a/contrib/ffmpeg/libavcodec/aac_ac3_parser.c b/contrib/ffmpeg/libavcodec/aac_ac3_parser.c new file mode 100644 index 000000000..999a18915 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/aac_ac3_parser.c @@ -0,0 +1,88 @@ +/* + * Common AAC and AC3 parser + * Copyright (c) 2003 Fabrice Bellard. + * 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 + */ + +#include "parser.h" +#include "aac_ac3_parser.h" + +int ff_aac_ac3_parse(AVCodecParserContext *s1, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + AACAC3ParseContext *s = s1->priv_data; + const uint8_t *buf_ptr; + int len, sample_rate, bit_rate, channels, samples; + + *poutbuf = NULL; + *poutbuf_size = 0; + + buf_ptr = buf; + while (buf_size > 0) { + int size_needed= s->frame_size ? s->frame_size : s->header_size; + len = s->inbuf_ptr - s->inbuf; + + if(len<size_needed){ + len = FFMIN(size_needed - len, buf_size); + memcpy(s->inbuf_ptr, buf_ptr, len); + buf_ptr += len; + s->inbuf_ptr += len; + buf_size -= len; + } + + if (s->frame_size == 0) { + if ((s->inbuf_ptr - s->inbuf) == s->header_size) { + len = s->sync(s->inbuf, &channels, &sample_rate, &bit_rate, + &samples); + if (len == 0) { + /* no sync found : move by one byte (inefficient, but simple!) */ + memmove(s->inbuf, s->inbuf + 1, s->header_size - 1); + s->inbuf_ptr--; + } else { + s->frame_size = len; + /* update codec info */ + avctx->sample_rate = sample_rate; + /* allow downmixing to stereo (or mono for AC3) */ + if(avctx->request_channels > 0 && + avctx->request_channels < channels && + (avctx->request_channels <= 2 || + (avctx->request_channels == 1 && + avctx->codec_id == CODEC_ID_AC3))) { + avctx->channels = avctx->request_channels; + } else { + avctx->channels = channels; + } + avctx->bit_rate = bit_rate; + avctx->frame_size = samples; + } + } + } else { + if(s->inbuf_ptr - s->inbuf == s->frame_size){ + *poutbuf = s->inbuf; + *poutbuf_size = s->frame_size; + s->inbuf_ptr = s->inbuf; + s->frame_size = 0; + break; + } + } + } + return buf_ptr - buf; +} diff --git a/contrib/ffmpeg/libavcodec/aac_ac3_parser.h b/contrib/ffmpeg/libavcodec/aac_ac3_parser.h new file mode 100644 index 000000000..e927de02d --- /dev/null +++ b/contrib/ffmpeg/libavcodec/aac_ac3_parser.h @@ -0,0 +1,43 @@ +/* + * Common AAC and AC3 parser prototypes + * Copyright (c) 2003 Fabrice Bellard. + * 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 + */ + +#ifndef FFMPEG_AAC_AC3_PARSER_H +#define FFMPEG_AAC_AC3_PARSER_H + +#include <stdint.h> +#include "avcodec.h" + +typedef struct AACAC3ParseContext { + uint8_t *inbuf_ptr; + int frame_size; + int header_size; + int (*sync)(const uint8_t *buf, int *channels, int *sample_rate, + int *bit_rate, int *samples); + uint8_t inbuf[8192]; /* input buffer */ +} AACAC3ParseContext; + +int ff_aac_ac3_parse(AVCodecParserContext *s1, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + +#endif /* FFMPEG_AAC_AC3_PARSER_H */ diff --git a/contrib/ffmpeg/libavcodec/aac_parser.c b/contrib/ffmpeg/libavcodec/aac_parser.c new file mode 100644 index 000000000..ac806931e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/aac_parser.c @@ -0,0 +1,100 @@ +/* + * Audio and Video frame extraction + * Copyright (c) 2003 Fabrice Bellard. + * 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 + */ + +#include "parser.h" +#include "aac_ac3_parser.h" +#include "bitstream.h" + + +#define AAC_HEADER_SIZE 7 + + +static const int aac_sample_rates[16] = { + 96000, 88200, 64000, 48000, 44100, 32000, + 24000, 22050, 16000, 12000, 11025, 8000, 7350 +}; + +static const int aac_channels[8] = { + 0, 1, 2, 3, 4, 5, 6, 8 +}; + + +static int aac_sync(const uint8_t *buf, int *channels, int *sample_rate, + int *bit_rate, int *samples) +{ + GetBitContext bits; + int size, rdb, ch, sr; + + init_get_bits(&bits, buf, AAC_HEADER_SIZE * 8); + + if(get_bits(&bits, 12) != 0xfff) + return 0; + + skip_bits1(&bits); /* id */ + skip_bits(&bits, 2); /* layer */ + skip_bits1(&bits); /* protection_absent */ + skip_bits(&bits, 2); /* profile_objecttype */ + sr = get_bits(&bits, 4); /* sample_frequency_index */ + if(!aac_sample_rates[sr]) + return 0; + skip_bits1(&bits); /* private_bit */ + ch = get_bits(&bits, 3); /* channel_configuration */ + if(!aac_channels[ch]) + return 0; + skip_bits1(&bits); /* original/copy */ + skip_bits1(&bits); /* home */ + + /* adts_variable_header */ + skip_bits1(&bits); /* copyright_identification_bit */ + skip_bits1(&bits); /* copyright_identification_start */ + size = get_bits(&bits, 13); /* aac_frame_length */ + if(size < AAC_HEADER_SIZE) + return 0; + + skip_bits(&bits, 11); /* adts_buffer_fullness */ + rdb = get_bits(&bits, 2); /* number_of_raw_data_blocks_in_frame */ + + *channels = aac_channels[ch]; + *sample_rate = aac_sample_rates[sr]; + *samples = (rdb + 1) * 1024; + *bit_rate = size * 8 * *sample_rate / *samples; + + return size; +} + +static int aac_parse_init(AVCodecParserContext *s1) +{ + AACAC3ParseContext *s = s1->priv_data; + s->inbuf_ptr = s->inbuf; + s->header_size = AAC_HEADER_SIZE; + s->sync = aac_sync; + return 0; +} + + +AVCodecParser aac_parser = { + { CODEC_ID_AAC }, + sizeof(AACAC3ParseContext), + aac_parse_init, + ff_aac_ac3_parse, + NULL, +}; diff --git a/contrib/ffmpeg/libavcodec/aasc.c b/contrib/ffmpeg/libavcodec/aasc.c index 8f26fae87..62912a81a 100644 --- a/contrib/ffmpeg/libavcodec/aasc.c +++ b/contrib/ffmpeg/libavcodec/aasc.c @@ -28,7 +28,6 @@ #include <stdlib.h> #include <string.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -47,7 +46,7 @@ typedef struct AascContext { static int aasc_decode_init(AVCodecContext *avctx) { - AascContext *s = (AascContext *)avctx->priv_data; + AascContext *s = avctx->priv_data; s->avctx = avctx; @@ -59,9 +58,9 @@ static int aasc_decode_init(AVCodecContext *avctx) static int aasc_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - AascContext *s = (AascContext *)avctx->priv_data; + AascContext *s = avctx->priv_data; int stream_ptr = 4; unsigned char rle_code; unsigned char stream_byte; @@ -153,7 +152,7 @@ static int aasc_decode_frame(AVCodecContext *avctx, static int aasc_decode_end(AVCodecContext *avctx) { - AascContext *s = (AascContext *)avctx->priv_data; + AascContext *s = avctx->priv_data; /* release the last frame */ if (s->frame.data[0]) diff --git a/contrib/ffmpeg/libavcodec/ac3.c b/contrib/ffmpeg/libavcodec/ac3.c index 3749d02f0..cc80277bc 100644 --- a/contrib/ffmpeg/libavcodec/ac3.c +++ b/contrib/ffmpeg/libavcodec/ac3.c @@ -26,9 +26,11 @@ #include "avcodec.h" #include "ac3.h" -#include "ac3tab.h" #include "bitstream.h" +static uint8_t band_start_tab[51]; +static uint8_t bin_to_band_tab[253]; + static inline int calc_lowcomp1(int a, int b0, int b1, int c) { if ((b0 + 256) == b1) { @@ -51,7 +53,7 @@ static inline int calc_lowcomp(int a, int b0, int b1, int bin) } void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd, - int16_t *bndpsd) + int16_t *band_psd) { int bin, i, j, k, end1, v; @@ -62,26 +64,26 @@ void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd, /* PSD integration */ j=start; - k=masktab[start]; + k=bin_to_band_tab[start]; do { v=psd[j]; j++; - end1 = FFMIN(bndtab[k+1], end); + end1 = FFMIN(band_start_tab[k+1], end); for(i=j;i<end1;i++) { /* logadd */ int adr = FFMIN(FFABS(v - psd[j]) >> 1, 255); - v = FFMAX(v, psd[j]) + latab[adr]; + v = FFMAX(v, psd[j]) + ff_ac3_log_add_tab[adr]; j++; } - bndpsd[k]=v; + band_psd[k]=v; k++; - } while (end > bndtab[k]); + } while (end > band_start_tab[k]); } -void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *bndpsd, - int start, int end, int fgain, int is_lfe, - int deltbae, int deltnseg, uint8_t *deltoffst, - uint8_t *deltlen, uint8_t *deltba, +void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd, + int start, int end, int fast_gain, int is_lfe, + int dba_mode, int dba_nsegs, uint8_t *dba_offsets, + uint8_t *dba_lengths, uint8_t *dba_values, int16_t *mask) { int16_t excite[50]; /* excitation */ @@ -90,24 +92,24 @@ void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *bndpsd, int lowcomp, fastleak, slowleak; /* excitation function */ - bndstrt = masktab[start]; - bndend = masktab[end-1] + 1; + bndstrt = bin_to_band_tab[start]; + bndend = bin_to_band_tab[end-1] + 1; if (bndstrt == 0) { lowcomp = 0; - lowcomp = calc_lowcomp1(lowcomp, bndpsd[0], bndpsd[1], 384); - excite[0] = bndpsd[0] - fgain - lowcomp; - lowcomp = calc_lowcomp1(lowcomp, bndpsd[1], bndpsd[2], 384); - excite[1] = bndpsd[1] - fgain - lowcomp; + lowcomp = calc_lowcomp1(lowcomp, band_psd[0], band_psd[1], 384); + excite[0] = band_psd[0] - fast_gain - lowcomp; + lowcomp = calc_lowcomp1(lowcomp, band_psd[1], band_psd[2], 384); + excite[1] = band_psd[1] - fast_gain - lowcomp; begin = 7; for (bin = 2; bin < 7; bin++) { if (!(is_lfe && bin == 6)) - lowcomp = calc_lowcomp1(lowcomp, bndpsd[bin], bndpsd[bin+1], 384); - fastleak = bndpsd[bin] - fgain; - slowleak = bndpsd[bin] - s->sgain; + lowcomp = calc_lowcomp1(lowcomp, band_psd[bin], band_psd[bin+1], 384); + fastleak = band_psd[bin] - fast_gain; + slowleak = band_psd[bin] - s->slow_gain; excite[bin] = fastleak - lowcomp; if (!(is_lfe && bin == 6)) { - if (bndpsd[bin] <= bndpsd[bin+1]) { + if (band_psd[bin] <= band_psd[bin+1]) { begin = bin + 1; break; } @@ -119,10 +121,10 @@ void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *bndpsd, for (bin = begin; bin < end1; bin++) { if (!(is_lfe && bin == 6)) - lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); + lowcomp = calc_lowcomp(lowcomp, band_psd[bin], band_psd[bin+1], bin); - fastleak = FFMAX(fastleak - s->fdecay, bndpsd[bin] - fgain); - slowleak = FFMAX(slowleak - s->sdecay, bndpsd[bin] - s->sgain); + fastleak = FFMAX(fastleak - s->fast_decay, band_psd[bin] - fast_gain); + slowleak = FFMAX(slowleak - s->slow_decay, band_psd[bin] - s->slow_gain); excite[bin] = FFMAX(fastleak - lowcomp, slowleak); } begin = 22; @@ -130,39 +132,39 @@ void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *bndpsd, /* coupling channel */ begin = bndstrt; - fastleak = (s->cplfleak << 8) + 768; - slowleak = (s->cplsleak << 8) + 768; + fastleak = (s->cpl_fast_leak << 8) + 768; + slowleak = (s->cpl_slow_leak << 8) + 768; } for (bin = begin; bin < bndend; bin++) { - fastleak = FFMAX(fastleak - s->fdecay, bndpsd[bin] - fgain); - slowleak = FFMAX(slowleak - s->sdecay, bndpsd[bin] - s->sgain); + fastleak = FFMAX(fastleak - s->fast_decay, band_psd[bin] - fast_gain); + slowleak = FFMAX(slowleak - s->slow_decay, band_psd[bin] - s->slow_gain); excite[bin] = FFMAX(fastleak, slowleak); } /* compute masking curve */ for (bin = bndstrt; bin < bndend; bin++) { - tmp = s->dbknee - bndpsd[bin]; + tmp = s->db_per_bit - band_psd[bin]; if (tmp > 0) { excite[bin] += tmp >> 2; } - mask[bin] = FFMAX(hth[bin >> s->halfratecod][s->fscod], excite[bin]); + mask[bin] = FFMAX(ff_ac3_hearing_threshold_tab[bin >> s->sr_shift][s->sr_code], excite[bin]); } /* delta bit allocation */ - if (deltbae == 0 || deltbae == 1) { + if (dba_mode == DBA_REUSE || dba_mode == DBA_NEW) { int band, seg, delta; band = 0; - for (seg = 0; seg < deltnseg; seg++) { - band += deltoffst[seg]; - if (deltba[seg] >= 4) { - delta = (deltba[seg] - 3) << 7; + for (seg = 0; seg < dba_nsegs; seg++) { + band += dba_offsets[seg]; + if (dba_values[seg] >= 4) { + delta = (dba_values[seg] - 3) << 7; } else { - delta = (deltba[seg] - 4) << 7; + delta = (dba_values[seg] - 4) << 7; } - for (k = 0; k < deltlen[seg]; k++) { + for (k = 0; k < dba_lengths[seg]; k++) { mask[band] += delta; band++; } @@ -171,49 +173,49 @@ void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *bndpsd, } void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end, - int snroffset, int floor, uint8_t *bap) + int snr_offset, int floor, uint8_t *bap) { int i, j, k, end1, v, address; - /* special case, if snroffset is -960, set all bap's to zero */ - if(snroffset == -960) { + /* special case, if snr offset is -960, set all bap's to zero */ + if(snr_offset == -960) { memset(bap, 0, 256); return; } i = start; - j = masktab[start]; + j = bin_to_band_tab[start]; do { - v = (FFMAX(mask[j] - snroffset - floor, 0) & 0x1FE0) + floor; - end1 = FFMIN(bndtab[j] + bndsz[j], end); + v = (FFMAX(mask[j] - snr_offset - floor, 0) & 0x1FE0) + floor; + end1 = FFMIN(band_start_tab[j] + ff_ac3_critical_band_size_tab[j], end); for (k = i; k < end1; k++) { address = av_clip((psd[i] - v) >> 5, 0, 63); - bap[i] = baptab[address]; + bap[i] = ff_ac3_bap_tab[address]; i++; } - } while (end > bndtab[j++]); + } while (end > band_start_tab[j++]); } /* AC3 bit allocation. The algorithm is the one described in the AC3 spec. */ void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap, int8_t *exp, int start, int end, - int snroffset, int fgain, int is_lfe, - int deltbae,int deltnseg, - uint8_t *deltoffst, uint8_t *deltlen, - uint8_t *deltba) + int snr_offset, int fast_gain, int is_lfe, + int dba_mode, int dba_nsegs, + uint8_t *dba_offsets, uint8_t *dba_lengths, + uint8_t *dba_values) { int16_t psd[256]; /* scaled exponents */ - int16_t bndpsd[50]; /* interpolated exponents */ + int16_t band_psd[50]; /* interpolated exponents */ int16_t mask[50]; /* masking value */ - ff_ac3_bit_alloc_calc_psd(exp, start, end, psd, bndpsd); + ff_ac3_bit_alloc_calc_psd(exp, start, end, psd, band_psd); - ff_ac3_bit_alloc_calc_mask(s, bndpsd, start, end, fgain, is_lfe, - deltbae, deltnseg, deltoffst, deltlen, deltba, + ff_ac3_bit_alloc_calc_mask(s, band_psd, start, end, fast_gain, is_lfe, + dba_mode, dba_nsegs, dba_offsets, dba_lengths, dba_values, mask); - ff_ac3_bit_alloc_calc_bap(mask, psd, start, end, snroffset, s->floor, bap); + ff_ac3_bit_alloc_calc_bap(mask, psd, start, end, snr_offset, s->floor, bap); } /** @@ -228,60 +230,10 @@ void ac3_common_init(void) k = 0; l = 0; for(i=0;i<50;i++) { - bndtab[i] = l; - v = bndsz[i]; - for(j=0;j<v;j++) masktab[k++]=i; + band_start_tab[i] = l; + v = ff_ac3_critical_band_size_tab[i]; + for(j=0;j<v;j++) bin_to_band_tab[k++]=i; l += v; } - bndtab[50] = l; -} - -int ff_ac3_parse_header(const uint8_t buf[7], AC3HeaderInfo *hdr) -{ - GetBitContext gbc; - - memset(hdr, 0, sizeof(*hdr)); - - init_get_bits(&gbc, buf, 54); - - hdr->sync_word = get_bits(&gbc, 16); - if(hdr->sync_word != 0x0B77) - return -1; - - /* read ahead to bsid to make sure this is AC-3, not E-AC-3 */ - hdr->bsid = show_bits_long(&gbc, 29) & 0x1F; - if(hdr->bsid > 10) - return -2; - - hdr->crc1 = get_bits(&gbc, 16); - hdr->fscod = get_bits(&gbc, 2); - if(hdr->fscod == 3) - return -3; - - hdr->frmsizecod = get_bits(&gbc, 6); - if(hdr->frmsizecod > 37) - return -4; - - skip_bits(&gbc, 5); // skip bsid, already got it - - hdr->bsmod = get_bits(&gbc, 3); - hdr->acmod = get_bits(&gbc, 3); - if((hdr->acmod & 1) && hdr->acmod != 1) { - hdr->cmixlev = get_bits(&gbc, 2); - } - if(hdr->acmod & 4) { - hdr->surmixlev = get_bits(&gbc, 2); - } - if(hdr->acmod == 2) { - hdr->dsurmod = get_bits(&gbc, 2); - } - hdr->lfeon = get_bits1(&gbc); - - hdr->halfratecod = FFMAX(hdr->bsid, 8) - 8; - hdr->sample_rate = ff_ac3_freqs[hdr->fscod] >> hdr->halfratecod; - hdr->bit_rate = (ff_ac3_bitratetab[hdr->frmsizecod>>1] * 1000) >> hdr->halfratecod; - hdr->channels = ff_ac3_channels[hdr->acmod] + hdr->lfeon; - hdr->frame_size = ff_ac3_frame_sizes[hdr->frmsizecod][hdr->fscod] * 2; - - return 0; + band_start_tab[50] = l; } diff --git a/contrib/ffmpeg/libavcodec/ac3.h b/contrib/ffmpeg/libavcodec/ac3.h index ae53a80c3..b5fa789c4 100644 --- a/contrib/ffmpeg/libavcodec/ac3.h +++ b/contrib/ffmpeg/libavcodec/ac3.h @@ -24,6 +24,11 @@ * Common code between AC3 encoder and decoder. */ +#ifndef FFMPEG_AC3_H +#define FFMPEG_AC3_H + +#include "ac3tab.h" + #define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ #define AC3_MAX_CHANNELS 6 /* including LFE channel */ @@ -38,11 +43,31 @@ #define EXP_D25 2 #define EXP_D45 3 +/** Delta bit allocation strategy */ +typedef enum { + DBA_REUSE = 0, + DBA_NEW, + DBA_NONE, + DBA_RESERVED +} AC3DeltaStrategy; + +/** Channel mode (audio coding mode) */ +typedef enum { + AC3_CHMODE_DUALMONO = 0, + AC3_CHMODE_MONO, + AC3_CHMODE_STEREO, + AC3_CHMODE_3F, + AC3_CHMODE_2F1R, + AC3_CHMODE_3F1R, + AC3_CHMODE_2F2R, + AC3_CHMODE_3F2R +} AC3ChannelMode; + typedef struct AC3BitAllocParameters { - int fscod; /* frequency */ - int halfratecod; - int sgain, sdecay, fdecay, dbknee, floor; - int cplfleak, cplsleak; + int sr_code; + int sr_shift; + int slow_gain, slow_decay, fast_decay, db_per_bit, floor; + int cpl_fast_leak, cpl_slow_leak; } AC3BitAllocParameters; /** @@ -55,21 +80,16 @@ typedef struct { */ uint16_t sync_word; uint16_t crc1; - uint8_t fscod; - uint8_t frmsizecod; - uint8_t bsid; - uint8_t bsmod; - uint8_t acmod; - uint8_t cmixlev; - uint8_t surmixlev; - uint8_t dsurmod; - uint8_t lfeon; + uint8_t sr_code; + uint8_t bitstream_id; + uint8_t channel_mode; + uint8_t lfe_on; /** @} */ /** @defgroup derived Derived values * @{ */ - uint8_t halfratecod; + uint8_t sr_shift; uint16_t sample_rate; uint32_t bit_rate; uint8_t channels; @@ -77,29 +97,6 @@ typedef struct { /** @} */ } AC3HeaderInfo; -/** - * Parses AC-3 frame header. - * Parses the header up to the lfeon element, which is the first 52 or 54 bits - * depending on the audio coding mode. - * @param buf[in] Array containing the first 7 bytes of the frame. - * @param hdr[out] Pointer to struct where header info is written. - * @return Returns 0 on success, -1 if there is a sync word mismatch, - * -2 if the bsid (version) element is invalid, -3 if the fscod (sample rate) - * element is invalid, or -4 if the frmsizecod (bit rate) element is invalid. - */ -int ff_ac3_parse_header(const uint8_t buf[7], AC3HeaderInfo *hdr); - -extern const uint16_t ff_ac3_frame_sizes[38][3]; -extern const uint8_t ff_ac3_channels[8]; -extern const uint16_t ff_ac3_freqs[3]; -extern const uint16_t ff_ac3_bitratetab[19]; -extern const int16_t ff_ac3_window[256]; -extern const uint8_t ff_sdecaytab[4]; -extern const uint8_t ff_fdecaytab[4]; -extern const uint16_t ff_sgaintab[4]; -extern const uint16_t ff_dbkneetab[4]; -extern const int16_t ff_floortab[8]; -extern const uint16_t ff_fgaintab[8]; void ac3_common_init(void); @@ -115,10 +112,10 @@ void ac3_common_init(void); * @param[in] start starting bin location * @param[in] end ending bin location * @param[out] psd signal power for each frequency bin - * @param[out] bndpsd signal power for each critical band + * @param[out] band_psd signal power for each critical band */ void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd, - int16_t *bndpsd); + int16_t *band_psd); /** * Calculates the masking curve. @@ -128,23 +125,23 @@ void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd, * allocation information is provided, it is used for adjusting the masking * curve, usually to give a closer match to a better psychoacoustic model. * - * @param[in] s adjustable bit allocation parameters - * @param[in] bndpsd signal power for each critical band - * @param[in] start starting bin location - * @param[in] end ending bin location - * @param[in] fgain fast gain (estimated signal-to-mask ratio) - * @param[in] is_lfe whether or not the channel being processed is the LFE - * @param[in] deltbae delta bit allocation exists (none, reuse, or new) - * @param[in] deltnseg number of delta segments - * @param[in] deltoffst location offsets for each segment - * @param[in] deltlen length of each segment - * @param[in] deltba delta bit allocation for each segment - * @param[out] mask calculated masking curve + * @param[in] s adjustable bit allocation parameters + * @param[in] band_psd signal power for each critical band + * @param[in] start starting bin location + * @param[in] end ending bin location + * @param[in] fast_gain fast gain (estimated signal-to-mask ratio) + * @param[in] is_lfe whether or not the channel being processed is the LFE + * @param[in] dba_mode delta bit allocation mode (none, reuse, or new) + * @param[in] dba_nsegs number of delta segments + * @param[in] dba_offsets location offsets for each segment + * @param[in] dba_lengths length of each segment + * @param[in] dba_values delta bit allocation for each segment + * @param[out] mask calculated masking curve */ -void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *bndpsd, - int start, int end, int fgain, int is_lfe, - int deltbae, int deltnseg, uint8_t *deltoffst, - uint8_t *deltlen, uint8_t *deltba, +void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd, + int start, int end, int fast_gain, int is_lfe, + int dba_mode, int dba_nsegs, uint8_t *dba_offsets, + uint8_t *dba_lengths, uint8_t *dba_values, int16_t *mask); /** @@ -157,15 +154,18 @@ void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *bndpsd, * @param[in] psd signal power for each frequency bin * @param[in] start starting bin location * @param[in] end ending bin location - * @param[in] snroffset SNR adjustment + * @param[in] snr_offset SNR adjustment * @param[in] floor noise floor * @param[out] bap bit allocation pointers */ void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end, - int snroffset, int floor, uint8_t *bap); + int snr_offset, int floor, uint8_t *bap); void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap, int8_t *exp, int start, int end, - int snroffset, int fgain, int is_lfe, - int deltbae,int deltnseg, - uint8_t *deltoffst, uint8_t *deltlen, uint8_t *deltba); + int snr_offset, int fast_gain, int is_lfe, + int dba_mode, int dba_nsegs, + uint8_t *dba_offsets, uint8_t *dba_lengths, + uint8_t *dba_values); + +#endif /* FFMPEG_AC3_H */ diff --git a/contrib/ffmpeg/libavcodec/ac3_parser.c b/contrib/ffmpeg/libavcodec/ac3_parser.c new file mode 100644 index 000000000..9bda20380 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ac3_parser.c @@ -0,0 +1,156 @@ +/* + * AC3 parser + * Copyright (c) 2003 Fabrice Bellard. + * 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 + */ + +#include "parser.h" +#include "ac3_parser.h" +#include "aac_ac3_parser.h" +#include "bitstream.h" + + +#define AC3_HEADER_SIZE 7 + + +static const uint8_t eac3_blocks[4] = { + 1, 2, 3, 6 +}; + + +int ff_ac3_parse_header(const uint8_t buf[7], AC3HeaderInfo *hdr) +{ + GetBitContext gbc; + int frame_size_code; + int num_blocks; + + memset(hdr, 0, sizeof(*hdr)); + + init_get_bits(&gbc, buf, 54); + + hdr->sync_word = get_bits(&gbc, 16); + if(hdr->sync_word != 0x0B77) + return AC3_PARSE_ERROR_SYNC; + + /* read ahead to bsid to distinguish between AC-3 and E-AC-3 */ + hdr->bitstream_id = show_bits_long(&gbc, 29) & 0x1F; + if(hdr->bitstream_id > 16) + return AC3_PARSE_ERROR_BSID; + + if(hdr->bitstream_id <= 10) { + /* Normal AC-3 */ + hdr->crc1 = get_bits(&gbc, 16); + hdr->sr_code = get_bits(&gbc, 2); + if(hdr->sr_code == 3) + return AC3_PARSE_ERROR_SAMPLE_RATE; + + frame_size_code = get_bits(&gbc, 6); + if(frame_size_code > 37) + return AC3_PARSE_ERROR_FRAME_SIZE; + + skip_bits(&gbc, 5); // skip bsid, already got it + + skip_bits(&gbc, 3); // skip bitstream mode + hdr->channel_mode = get_bits(&gbc, 3); + if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO) { + skip_bits(&gbc, 2); // skip center mix level + } + if(hdr->channel_mode & 4) { + skip_bits(&gbc, 2); // skip surround mix level + } + if(hdr->channel_mode == AC3_CHMODE_STEREO) { + skip_bits(&gbc, 2); // skip dolby surround mode + } + hdr->lfe_on = get_bits1(&gbc); + + hdr->sr_shift = FFMAX(hdr->bitstream_id, 8) - 8; + hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift; + hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift; + hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; + hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2; + } else { + /* Enhanced AC-3 */ + hdr->crc1 = 0; + skip_bits(&gbc, 2); // skip stream type + skip_bits(&gbc, 3); // skip substream id + + hdr->frame_size = (get_bits(&gbc, 11) + 1) << 1; + if(hdr->frame_size < AC3_HEADER_SIZE) + return AC3_PARSE_ERROR_FRAME_SIZE; + + hdr->sr_code = get_bits(&gbc, 2); + if (hdr->sr_code == 3) { + int sr_code2 = get_bits(&gbc, 2); + if(sr_code2 == 3) + return AC3_PARSE_ERROR_SAMPLE_RATE; + hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2; + hdr->sr_shift = 1; + num_blocks = 6; + } else { + num_blocks = eac3_blocks[get_bits(&gbc, 2)]; + hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code]; + hdr->sr_shift = 0; + } + + hdr->channel_mode = get_bits(&gbc, 3); + hdr->lfe_on = get_bits1(&gbc); + + hdr->bit_rate = (uint32_t)(8.0 * hdr->frame_size * hdr->sample_rate / + (num_blocks * 256.0)); + hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; + } + + return 0; +} + +static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, + int *bit_rate, int *samples) +{ + int err; + AC3HeaderInfo hdr; + + err = ff_ac3_parse_header(buf, &hdr); + + if(err < 0) + return 0; + + *sample_rate = hdr.sample_rate; + *bit_rate = hdr.bit_rate; + *channels = hdr.channels; + *samples = AC3_FRAME_SIZE; + return hdr.frame_size; +} + +static int ac3_parse_init(AVCodecParserContext *s1) +{ + AACAC3ParseContext *s = s1->priv_data; + s->inbuf_ptr = s->inbuf; + s->header_size = AC3_HEADER_SIZE; + s->sync = ac3_sync; + return 0; +} + + +AVCodecParser ac3_parser = { + { CODEC_ID_AC3 }, + sizeof(AACAC3ParseContext), + ac3_parse_init, + ff_aac_ac3_parse, + NULL, +}; diff --git a/contrib/ffmpeg/libavcodec/ac3_parser.h b/contrib/ffmpeg/libavcodec/ac3_parser.h new file mode 100644 index 000000000..ffac6190f --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ac3_parser.h @@ -0,0 +1,47 @@ +/* + * AC3 parser prototypes + * Copyright (c) 2003 Fabrice Bellard. + * 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 + */ + +#ifndef FFMPEG_AC3_PARSER_H +#define FFMPEG_AC3_PARSER_H + +#include "ac3.h" + +typedef enum { + AC3_PARSE_ERROR_SYNC = -1, + AC3_PARSE_ERROR_BSID = -2, + AC3_PARSE_ERROR_SAMPLE_RATE = -3, + AC3_PARSE_ERROR_FRAME_SIZE = -4, +} AC3ParseError; + +/** + * Parses AC-3 frame header. + * Parses the header up to the lfeon element, which is the first 52 or 54 bits + * depending on the audio coding mode. + * @param buf[in] Array containing the first 7 bytes of the frame. + * @param hdr[out] Pointer to struct where header info is written. + * @return Returns 0 on success, -1 if there is a sync word mismatch, + * -2 if the bsid (version) element is invalid, -3 if the fscod (sample rate) + * element is invalid, or -4 if the frmsizecod (bit rate) element is invalid. + */ +int ff_ac3_parse_header(const uint8_t buf[7], AC3HeaderInfo *hdr); + +#endif /* FFMPEG_AC3_PARSER_H */ diff --git a/contrib/ffmpeg/libavcodec/ac3dec.c b/contrib/ffmpeg/libavcodec/ac3dec.c new file mode 100644 index 000000000..0ce75e769 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ac3dec.c @@ -0,0 +1,1173 @@ +/* + * AC-3 Audio Decoder + * This code is developed as part of Google Summer of Code 2006 Program. + * + * Copyright (c) 2006 Kartikey Mahendra BHATT (bhattkm at gmail dot com). + * Copyright (c) 2007 Justin Ruggles + * + * Portions of this code are derived from liba52 + * http://liba52.sourceforge.net + * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> + * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 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 + * General Public License for more details. + * + * You should have received a copy of the GNU 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 <stdio.h> +#include <stddef.h> +#include <math.h> +#include <string.h> + +#include "avcodec.h" +#include "ac3_parser.h" +#include "bitstream.h" +#include "crc.h" +#include "dsputil.h" +#include "random.h" + +/** + * Table of bin locations for rematrixing bands + * reference: Section 7.5.2 Rematrixing : Frequency Band Definitions + */ +static const uint8_t rematrix_band_tab[5] = { 13, 25, 37, 61, 253 }; + +/** + * table for exponent to scale_factor mapping + * scale_factors[i] = 2 ^ -i + */ +static float scale_factors[25]; + +/** table for grouping exponents */ +static uint8_t exp_ungroup_tab[128][3]; + + +/** tables for ungrouping mantissas */ +static float b1_mantissas[32][3]; +static float b2_mantissas[128][3]; +static float b3_mantissas[8]; +static float b4_mantissas[128][2]; +static float b5_mantissas[16]; + +/** + * Quantization table: levels for symmetric. bits for asymmetric. + * reference: Table 7.18 Mapping of bap to Quantizer + */ +static const uint8_t quantization_tab[16] = { + 0, 3, 5, 7, 11, 15, + 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 +}; + +/** dynamic range table. converts codes to scale factors. */ +static float dynamic_range_tab[256]; + +/** Adjustments in dB gain */ +#define LEVEL_MINUS_3DB 0.7071067811865476 +#define LEVEL_MINUS_4POINT5DB 0.5946035575013605 +#define LEVEL_MINUS_6DB 0.5000000000000000 +#define LEVEL_MINUS_9DB 0.3535533905932738 +#define LEVEL_ZERO 0.0000000000000000 +#define LEVEL_ONE 1.0000000000000000 + +static const float gain_levels[6] = { + LEVEL_ZERO, + LEVEL_ONE, + LEVEL_MINUS_3DB, + LEVEL_MINUS_4POINT5DB, + LEVEL_MINUS_6DB, + LEVEL_MINUS_9DB +}; + +/** + * Table for center mix levels + * reference: Section 5.4.2.4 cmixlev + */ +static const uint8_t center_levels[4] = { 2, 3, 4, 3 }; + +/** + * Table for surround mix levels + * reference: Section 5.4.2.5 surmixlev + */ +static const uint8_t surround_levels[4] = { 2, 4, 0, 4 }; + +/** + * Table for default stereo downmixing coefficients + * reference: Section 7.8.2 Downmixing Into Two Channels + */ +static const uint8_t ac3_default_coeffs[8][5][2] = { + { { 1, 0 }, { 0, 1 }, }, + { { 2, 2 }, }, + { { 1, 0 }, { 0, 1 }, }, + { { 1, 0 }, { 3, 3 }, { 0, 1 }, }, + { { 1, 0 }, { 0, 1 }, { 4, 4 }, }, + { { 1, 0 }, { 3, 3 }, { 0, 1 }, { 5, 5 }, }, + { { 1, 0 }, { 0, 1 }, { 4, 0 }, { 0, 4 }, }, + { { 1, 0 }, { 3, 3 }, { 0, 1 }, { 4, 0 }, { 0, 4 }, }, +}; + +/* override ac3.h to include coupling channel */ +#undef AC3_MAX_CHANNELS +#define AC3_MAX_CHANNELS 7 +#define CPL_CH 0 + +#define AC3_OUTPUT_LFEON 8 + +typedef struct { + int channel_mode; ///< channel mode (acmod) + int block_switch[AC3_MAX_CHANNELS]; ///< block switch flags + int dither_flag[AC3_MAX_CHANNELS]; ///< dither flags + int dither_all; ///< true if all channels are dithered + int cpl_in_use; ///< coupling in use + int channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling + int phase_flags_in_use; ///< phase flags in use + int phase_flags[18]; ///< phase flags + int cpl_band_struct[18]; ///< coupling band structure + int num_rematrixing_bands; ///< number of rematrixing bands + int rematrixing_flags[4]; ///< rematrixing flags + int exp_strategy[AC3_MAX_CHANNELS]; ///< exponent strategies + int snr_offset[AC3_MAX_CHANNELS]; ///< signal-to-noise ratio offsets + int fast_gain[AC3_MAX_CHANNELS]; ///< fast gain values (signal-to-mask ratio) + int dba_mode[AC3_MAX_CHANNELS]; ///< delta bit allocation mode + int dba_nsegs[AC3_MAX_CHANNELS]; ///< number of delta segments + uint8_t dba_offsets[AC3_MAX_CHANNELS][8]; ///< delta segment offsets + uint8_t dba_lengths[AC3_MAX_CHANNELS][8]; ///< delta segment lengths + uint8_t dba_values[AC3_MAX_CHANNELS][8]; ///< delta values for each segment + + int sample_rate; ///< sample frequency, in Hz + int bit_rate; ///< stream bit rate, in bits-per-second + int frame_size; ///< current frame size, in bytes + + int channels; ///< number of total channels + int fbw_channels; ///< number of full-bandwidth channels + int lfe_on; ///< lfe channel in use + int lfe_ch; ///< index of LFE channel + int output_mode; ///< output channel configuration + int out_channels; ///< number of output channels + + int center_mix_level; ///< Center mix level index + int surround_mix_level; ///< Surround mix level index + float downmix_coeffs[AC3_MAX_CHANNELS][2]; ///< stereo downmix coefficients + float dynamic_range[2]; ///< dynamic range + float cpl_coords[AC3_MAX_CHANNELS][18]; ///< coupling coordinates + int num_cpl_bands; ///< number of coupling bands + int num_cpl_subbands; ///< number of coupling sub bands + int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin + int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin + AC3BitAllocParameters bit_alloc_params; ///< bit allocation parameters + + int8_t dexps[AC3_MAX_CHANNELS][256]; ///< decoded exponents + uint8_t bap[AC3_MAX_CHANNELS][256]; ///< bit allocation pointers + int16_t psd[AC3_MAX_CHANNELS][256]; ///< scaled exponents + int16_t band_psd[AC3_MAX_CHANNELS][50]; ///< interpolated exponents + int16_t mask[AC3_MAX_CHANNELS][50]; ///< masking curve values + + DECLARE_ALIGNED_16(float, transform_coeffs[AC3_MAX_CHANNELS][256]); ///< transform coefficients + + /* For IMDCT. */ + MDCTContext imdct_512; ///< for 512 sample IMDCT + MDCTContext imdct_256; ///< for 256 sample IMDCT + DSPContext dsp; ///< for optimization + float add_bias; ///< offset for float_to_int16 conversion + float mul_bias; ///< scaling for float_to_int16 conversion + + DECLARE_ALIGNED_16(float, output[AC3_MAX_CHANNELS-1][256]); ///< output after imdct transform and windowing + DECLARE_ALIGNED_16(short, int_output[AC3_MAX_CHANNELS-1][256]); ///< final 16-bit integer output + DECLARE_ALIGNED_16(float, delay[AC3_MAX_CHANNELS-1][256]); ///< delay - added to the next block + DECLARE_ALIGNED_16(float, tmp_imdct[256]); ///< temporary storage for imdct transform + DECLARE_ALIGNED_16(float, tmp_output[512]); ///< temporary storage for output before windowing + DECLARE_ALIGNED_16(float, window[256]); ///< window coefficients + + /* Miscellaneous. */ + GetBitContext gbc; ///< bitstream reader + AVRandomState dith_state; ///< for dither generation + AVCodecContext *avctx; ///< parent context +} AC3DecodeContext; + +/** + * Symmetrical Dequantization + * reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization + * Tables 7.19 to 7.23 + */ +static inline float +symmetric_dequant(int code, int levels) +{ + return (code - (levels >> 1)) * (2.0f / levels); +} + +/* + * Initialize tables at runtime. + */ +static void ac3_tables_init(void) +{ + int i; + + /* generate grouped mantissa tables + reference: Section 7.3.5 Ungrouping of Mantissas */ + for(i=0; i<32; i++) { + /* bap=1 mantissas */ + b1_mantissas[i][0] = symmetric_dequant( i / 9 , 3); + b1_mantissas[i][1] = symmetric_dequant((i % 9) / 3, 3); + b1_mantissas[i][2] = symmetric_dequant((i % 9) % 3, 3); + } + for(i=0; i<128; i++) { + /* bap=2 mantissas */ + b2_mantissas[i][0] = symmetric_dequant( i / 25 , 5); + b2_mantissas[i][1] = symmetric_dequant((i % 25) / 5, 5); + b2_mantissas[i][2] = symmetric_dequant((i % 25) % 5, 5); + + /* bap=4 mantissas */ + b4_mantissas[i][0] = symmetric_dequant(i / 11, 11); + b4_mantissas[i][1] = symmetric_dequant(i % 11, 11); + } + /* generate ungrouped mantissa tables + reference: Tables 7.21 and 7.23 */ + for(i=0; i<7; i++) { + /* bap=3 mantissas */ + b3_mantissas[i] = symmetric_dequant(i, 7); + } + for(i=0; i<15; i++) { + /* bap=5 mantissas */ + b5_mantissas[i] = symmetric_dequant(i, 15); + } + + /* generate dynamic range table + reference: Section 7.7.1 Dynamic Range Control */ + for(i=0; i<256; i++) { + int v = (i >> 5) - ((i >> 7) << 3) - 5; + dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20); + } + + /* generate scale factors for exponents and asymmetrical dequantization + reference: Section 7.3.2 Expansion of Mantissas for Asymmetric Quantization */ + for (i = 0; i < 25; i++) + scale_factors[i] = pow(2.0, -i); + + /* generate exponent tables + reference: Section 7.1.3 Exponent Decoding */ + for(i=0; i<128; i++) { + exp_ungroup_tab[i][0] = i / 25; + exp_ungroup_tab[i][1] = (i % 25) / 5; + exp_ungroup_tab[i][2] = (i % 25) % 5; + } +} + + +/** + * AVCodec initialization + */ +static int ac3_decode_init(AVCodecContext *avctx) +{ + AC3DecodeContext *s = avctx->priv_data; + s->avctx = avctx; + + ac3_common_init(); + ac3_tables_init(); + ff_mdct_init(&s->imdct_256, 8, 1); + ff_mdct_init(&s->imdct_512, 9, 1); + ff_kbd_window_init(s->window, 5.0, 256); + dsputil_init(&s->dsp, avctx); + av_init_random(0, &s->dith_state); + + /* set bias values for float to int16 conversion */ + if(s->dsp.float_to_int16 == ff_float_to_int16_c) { + s->add_bias = 385.0f; + s->mul_bias = 1.0f; + } else { + s->add_bias = 0.0f; + s->mul_bias = 32767.0f; + } + + /* allow downmixing to stereo or mono */ + if (avctx->channels > 0 && avctx->request_channels > 0 && + avctx->request_channels < avctx->channels && + avctx->request_channels <= 2) { + avctx->channels = avctx->request_channels; + } + + return 0; +} + +/** + * Parse the 'sync info' and 'bit stream info' from the AC-3 bitstream. + * GetBitContext within AC3DecodeContext must point to + * start of the synchronized ac3 bitstream. + */ +static int ac3_parse_header(AC3DecodeContext *s) +{ + AC3HeaderInfo hdr; + GetBitContext *gbc = &s->gbc; + int err, i; + + err = ff_ac3_parse_header(gbc->buffer, &hdr); + if(err) + return err; + + if(hdr.bitstream_id > 10) + return AC3_PARSE_ERROR_BSID; + + /* get decoding parameters from header info */ + s->bit_alloc_params.sr_code = hdr.sr_code; + s->channel_mode = hdr.channel_mode; + s->lfe_on = hdr.lfe_on; + s->bit_alloc_params.sr_shift = hdr.sr_shift; + s->sample_rate = hdr.sample_rate; + s->bit_rate = hdr.bit_rate; + s->channels = hdr.channels; + s->fbw_channels = s->channels - s->lfe_on; + s->lfe_ch = s->fbw_channels + 1; + s->frame_size = hdr.frame_size; + + /* set default output to all source channels */ + s->out_channels = s->channels; + s->output_mode = s->channel_mode; + if(s->lfe_on) + s->output_mode |= AC3_OUTPUT_LFEON; + + /* set default mix levels */ + s->center_mix_level = 3; // -4.5dB + s->surround_mix_level = 4; // -6.0dB + + /* skip over portion of header which has already been read */ + skip_bits(gbc, 16); // skip the sync_word + skip_bits(gbc, 16); // skip crc1 + skip_bits(gbc, 8); // skip fscod and frmsizecod + skip_bits(gbc, 11); // skip bsid, bsmod, and acmod + if(s->channel_mode == AC3_CHMODE_STEREO) { + skip_bits(gbc, 2); // skip dsurmod + } else { + if((s->channel_mode & 1) && s->channel_mode != AC3_CHMODE_MONO) + s->center_mix_level = center_levels[get_bits(gbc, 2)]; + if(s->channel_mode & 4) + s->surround_mix_level = surround_levels[get_bits(gbc, 2)]; + } + skip_bits1(gbc); // skip lfeon + + /* read the rest of the bsi. read twice for dual mono mode. */ + i = !(s->channel_mode); + do { + skip_bits(gbc, 5); // skip dialog normalization + if (get_bits1(gbc)) + skip_bits(gbc, 8); //skip compression + if (get_bits1(gbc)) + skip_bits(gbc, 8); //skip language code + if (get_bits1(gbc)) + skip_bits(gbc, 7); //skip audio production information + } while (i--); + + skip_bits(gbc, 2); //skip copyright bit and original bitstream bit + + /* skip the timecodes (or extra bitstream information for Alternate Syntax) + TODO: read & use the xbsi1 downmix levels */ + if (get_bits1(gbc)) + skip_bits(gbc, 14); //skip timecode1 / xbsi1 + if (get_bits1(gbc)) + skip_bits(gbc, 14); //skip timecode2 / xbsi2 + + /* skip additional bitstream info */ + if (get_bits1(gbc)) { + i = get_bits(gbc, 6); + do { + skip_bits(gbc, 8); + } while(i--); + } + + return 0; +} + +/** + * Set stereo downmixing coefficients based on frame header info. + * reference: Section 7.8.2 Downmixing Into Two Channels + */ +static void set_downmix_coeffs(AC3DecodeContext *s) +{ + int i; + float cmix = gain_levels[s->center_mix_level]; + float smix = gain_levels[s->surround_mix_level]; + + for(i=0; i<s->fbw_channels; i++) { + s->downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; + s->downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; + } + if(s->channel_mode > 1 && s->channel_mode & 1) { + s->downmix_coeffs[1][0] = s->downmix_coeffs[1][1] = cmix; + } + if(s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) { + int nf = s->channel_mode - 2; + s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB; + } + if(s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) { + int nf = s->channel_mode - 4; + s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = smix; + } +} + +/** + * Decode the grouped exponents according to exponent strategy. + * reference: Section 7.1.3 Exponent Decoding + */ +static void decode_exponents(GetBitContext *gbc, int exp_strategy, int ngrps, + uint8_t absexp, int8_t *dexps) +{ + int i, j, grp, group_size; + int dexp[256]; + int expacc, prevexp; + + /* unpack groups */ + group_size = exp_strategy + (exp_strategy == EXP_D45); + for(grp=0,i=0; grp<ngrps; grp++) { + expacc = get_bits(gbc, 7); + dexp[i++] = exp_ungroup_tab[expacc][0]; + dexp[i++] = exp_ungroup_tab[expacc][1]; + dexp[i++] = exp_ungroup_tab[expacc][2]; + } + + /* convert to absolute exps and expand groups */ + prevexp = absexp; + for(i=0; i<ngrps*3; i++) { + prevexp = av_clip(prevexp + dexp[i]-2, 0, 24); + for(j=0; j<group_size; j++) { + dexps[(i*group_size)+j] = prevexp; + } + } +} + +/** + * Generate transform coefficients for each coupled channel in the coupling + * range using the coupling coefficients and coupling coordinates. + * reference: Section 7.4.3 Coupling Coordinate Format + */ +static void uncouple_channels(AC3DecodeContext *s) +{ + int i, j, ch, bnd, subbnd; + + subbnd = -1; + i = s->start_freq[CPL_CH]; + for(bnd=0; bnd<s->num_cpl_bands; bnd++) { + do { + subbnd++; + for(j=0; j<12; j++) { + for(ch=1; ch<=s->fbw_channels; ch++) { + if(s->channel_in_cpl[ch]) { + s->transform_coeffs[ch][i] = s->transform_coeffs[CPL_CH][i] * s->cpl_coords[ch][bnd] * 8.0f; + if (ch == 2 && s->phase_flags[bnd]) + s->transform_coeffs[ch][i] = -s->transform_coeffs[ch][i]; + } + } + i++; + } + } while(s->cpl_band_struct[subbnd]); + } +} + +/** + * Grouped mantissas for 3-level 5-level and 11-level quantization + */ +typedef struct { + float b1_mant[3]; + float b2_mant[3]; + float b4_mant[2]; + int b1ptr; + int b2ptr; + int b4ptr; +} mant_groups; + +/** + * Get the transform coefficients for a particular channel + * reference: Section 7.3 Quantization and Decoding of Mantissas + */ +static int get_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, mant_groups *m) +{ + GetBitContext *gbc = &s->gbc; + int i, gcode, tbap, start, end; + uint8_t *exps; + uint8_t *bap; + float *coeffs; + + exps = s->dexps[ch_index]; + bap = s->bap[ch_index]; + coeffs = s->transform_coeffs[ch_index]; + start = s->start_freq[ch_index]; + end = s->end_freq[ch_index]; + + for (i = start; i < end; i++) { + tbap = bap[i]; + switch (tbap) { + case 0: + coeffs[i] = ((av_random(&s->dith_state) & 0xFFFF) / 65535.0f) - 0.5f; + break; + + case 1: + if(m->b1ptr > 2) { + gcode = get_bits(gbc, 5); + m->b1_mant[0] = b1_mantissas[gcode][0]; + m->b1_mant[1] = b1_mantissas[gcode][1]; + m->b1_mant[2] = b1_mantissas[gcode][2]; + m->b1ptr = 0; + } + coeffs[i] = m->b1_mant[m->b1ptr++]; + break; + + case 2: + if(m->b2ptr > 2) { + gcode = get_bits(gbc, 7); + m->b2_mant[0] = b2_mantissas[gcode][0]; + m->b2_mant[1] = b2_mantissas[gcode][1]; + m->b2_mant[2] = b2_mantissas[gcode][2]; + m->b2ptr = 0; + } + coeffs[i] = m->b2_mant[m->b2ptr++]; + break; + + case 3: + coeffs[i] = b3_mantissas[get_bits(gbc, 3)]; + break; + + case 4: + if(m->b4ptr > 1) { + gcode = get_bits(gbc, 7); + m->b4_mant[0] = b4_mantissas[gcode][0]; + m->b4_mant[1] = b4_mantissas[gcode][1]; + m->b4ptr = 0; + } + coeffs[i] = m->b4_mant[m->b4ptr++]; + break; + + case 5: + coeffs[i] = b5_mantissas[get_bits(gbc, 4)]; + break; + + default: + /* asymmetric dequantization */ + coeffs[i] = get_sbits(gbc, quantization_tab[tbap]) * scale_factors[quantization_tab[tbap]-1]; + break; + } + coeffs[i] *= scale_factors[exps[i]]; + } + + return 0; +} + +/** + * Remove random dithering from coefficients with zero-bit mantissas + * reference: Section 7.3.4 Dither for Zero Bit Mantissas (bap=0) + */ +static void remove_dithering(AC3DecodeContext *s) { + int ch, i; + int end=0; + float *coeffs; + uint8_t *bap; + + for(ch=1; ch<=s->fbw_channels; ch++) { + if(!s->dither_flag[ch]) { + coeffs = s->transform_coeffs[ch]; + bap = s->bap[ch]; + if(s->channel_in_cpl[ch]) + end = s->start_freq[CPL_CH]; + else + end = s->end_freq[ch]; + for(i=0; i<end; i++) { + if(!bap[i]) + coeffs[i] = 0.0f; + } + if(s->channel_in_cpl[ch]) { + bap = s->bap[CPL_CH]; + for(; i<s->end_freq[CPL_CH]; i++) { + if(!bap[i]) + coeffs[i] = 0.0f; + } + } + } + } +} + +/** + * Get the transform coefficients. + */ +static int get_transform_coeffs(AC3DecodeContext *s) +{ + int ch, end; + int got_cplchan = 0; + mant_groups m; + + m.b1ptr = m.b2ptr = m.b4ptr = 3; + + for (ch = 1; ch <= s->channels; ch++) { + /* transform coefficients for full-bandwidth channel */ + if (get_transform_coeffs_ch(s, ch, &m)) + return -1; + /* tranform coefficients for coupling channel come right after the + coefficients for the first coupled channel*/ + if (s->channel_in_cpl[ch]) { + if (!got_cplchan) { + if (get_transform_coeffs_ch(s, CPL_CH, &m)) { + av_log(s->avctx, AV_LOG_ERROR, "error in decoupling channels\n"); + return -1; + } + uncouple_channels(s); + got_cplchan = 1; + } + end = s->end_freq[CPL_CH]; + } else { + end = s->end_freq[ch]; + } + do + s->transform_coeffs[ch][end] = 0; + while(++end < 256); + } + + /* if any channel doesn't use dithering, zero appropriate coefficients */ + if(!s->dither_all) + remove_dithering(s); + + return 0; +} + +/** + * Stereo rematrixing. + * reference: Section 7.5.4 Rematrixing : Decoding Technique + */ +static void do_rematrixing(AC3DecodeContext *s) +{ + int bnd, i; + int end, bndend; + float tmp0, tmp1; + + end = FFMIN(s->end_freq[1], s->end_freq[2]); + + for(bnd=0; bnd<s->num_rematrixing_bands; bnd++) { + if(s->rematrixing_flags[bnd]) { + bndend = FFMIN(end, rematrix_band_tab[bnd+1]); + for(i=rematrix_band_tab[bnd]; i<bndend; i++) { + tmp0 = s->transform_coeffs[1][i]; + tmp1 = s->transform_coeffs[2][i]; + s->transform_coeffs[1][i] = tmp0 + tmp1; + s->transform_coeffs[2][i] = tmp0 - tmp1; + } + } + } +} + +/** + * Perform the 256-point IMDCT + */ +static void do_imdct_256(AC3DecodeContext *s, int chindex) +{ + int i, k; + DECLARE_ALIGNED_16(float, x[128]); + FFTComplex z[2][64]; + float *o_ptr = s->tmp_output; + + for(i=0; i<2; i++) { + /* de-interleave coefficients */ + for(k=0; k<128; k++) { + x[k] = s->transform_coeffs[chindex][2*k+i]; + } + + /* run standard IMDCT */ + s->imdct_256.fft.imdct_calc(&s->imdct_256, o_ptr, x, s->tmp_imdct); + + /* reverse the post-rotation & reordering from standard IMDCT */ + for(k=0; k<32; k++) { + z[i][32+k].re = -o_ptr[128+2*k]; + z[i][32+k].im = -o_ptr[2*k]; + z[i][31-k].re = o_ptr[2*k+1]; + z[i][31-k].im = o_ptr[128+2*k+1]; + } + } + + /* apply AC-3 post-rotation & reordering */ + for(k=0; k<64; k++) { + o_ptr[ 2*k ] = -z[0][ k].im; + o_ptr[ 2*k+1] = z[0][63-k].re; + o_ptr[128+2*k ] = -z[0][ k].re; + o_ptr[128+2*k+1] = z[0][63-k].im; + o_ptr[256+2*k ] = -z[1][ k].re; + o_ptr[256+2*k+1] = z[1][63-k].im; + o_ptr[384+2*k ] = z[1][ k].im; + o_ptr[384+2*k+1] = -z[1][63-k].re; + } +} + +/** + * Inverse MDCT Transform. + * Convert frequency domain coefficients to time-domain audio samples. + * reference: Section 7.9.4 Transformation Equations + */ +static inline void do_imdct(AC3DecodeContext *s) +{ + int ch; + int channels; + + /* Don't perform the IMDCT on the LFE channel unless it's used in the output */ + channels = s->fbw_channels; + if(s->output_mode & AC3_OUTPUT_LFEON) + channels++; + + for (ch=1; ch<=channels; ch++) { + if (s->block_switch[ch]) { + do_imdct_256(s, ch); + } else { + s->imdct_512.fft.imdct_calc(&s->imdct_512, s->tmp_output, + s->transform_coeffs[ch], s->tmp_imdct); + } + /* For the first half of the block, apply the window, add the delay + from the previous block, and send to output */ + s->dsp.vector_fmul_add_add(s->output[ch-1], s->tmp_output, + s->window, s->delay[ch-1], 0, 256, 1); + /* For the second half of the block, apply the window and store the + samples to delay, to be combined with the next block */ + s->dsp.vector_fmul_reverse(s->delay[ch-1], s->tmp_output+256, + s->window, 256); + } +} + +/** + * Downmix the output to mono or stereo. + */ +static void ac3_downmix(AC3DecodeContext *s) +{ + int i, j; + float v0, v1, s0, s1; + + for(i=0; i<256; i++) { + v0 = v1 = s0 = s1 = 0.0f; + for(j=0; j<s->fbw_channels; j++) { + v0 += s->output[j][i] * s->downmix_coeffs[j][0]; + v1 += s->output[j][i] * s->downmix_coeffs[j][1]; + s0 += s->downmix_coeffs[j][0]; + s1 += s->downmix_coeffs[j][1]; + } + v0 /= s0; + v1 /= s1; + if(s->output_mode == AC3_CHMODE_MONO) { + s->output[0][i] = (v0 + v1) * LEVEL_MINUS_3DB; + } else if(s->output_mode == AC3_CHMODE_STEREO) { + s->output[0][i] = v0; + s->output[1][i] = v1; + } + } +} + +/** + * Parse an audio block from AC-3 bitstream. + */ +static int ac3_parse_audio_block(AC3DecodeContext *s, int blk) +{ + int fbw_channels = s->fbw_channels; + int channel_mode = s->channel_mode; + int i, bnd, seg, ch; + GetBitContext *gbc = &s->gbc; + uint8_t bit_alloc_stages[AC3_MAX_CHANNELS]; + + memset(bit_alloc_stages, 0, AC3_MAX_CHANNELS); + + /* block switch flags */ + for (ch = 1; ch <= fbw_channels; ch++) + s->block_switch[ch] = get_bits1(gbc); + + /* dithering flags */ + s->dither_all = 1; + for (ch = 1; ch <= fbw_channels; ch++) { + s->dither_flag[ch] = get_bits1(gbc); + if(!s->dither_flag[ch]) + s->dither_all = 0; + } + + /* dynamic range */ + i = !(s->channel_mode); + do { + if(get_bits1(gbc)) { + s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)]-1.0) * + s->avctx->drc_scale)+1.0; + } else if(blk == 0) { + s->dynamic_range[i] = 1.0f; + } + } while(i--); + + /* coupling strategy */ + if (get_bits1(gbc)) { + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); + s->cpl_in_use = get_bits1(gbc); + if (s->cpl_in_use) { + /* coupling in use */ + int cpl_begin_freq, cpl_end_freq; + + /* determine which channels are coupled */ + for (ch = 1; ch <= fbw_channels; ch++) + s->channel_in_cpl[ch] = get_bits1(gbc); + + /* phase flags in use */ + if (channel_mode == AC3_CHMODE_STEREO) + s->phase_flags_in_use = get_bits1(gbc); + + /* coupling frequency range and band structure */ + cpl_begin_freq = get_bits(gbc, 4); + cpl_end_freq = get_bits(gbc, 4); + if (3 + cpl_end_freq - cpl_begin_freq < 0) { + av_log(s->avctx, AV_LOG_ERROR, "3+cplendf = %d < cplbegf = %d\n", 3+cpl_end_freq, cpl_begin_freq); + return -1; + } + s->num_cpl_bands = s->num_cpl_subbands = 3 + cpl_end_freq - cpl_begin_freq; + s->start_freq[CPL_CH] = cpl_begin_freq * 12 + 37; + s->end_freq[CPL_CH] = cpl_end_freq * 12 + 73; + for (bnd = 0; bnd < s->num_cpl_subbands - 1; bnd++) { + if (get_bits1(gbc)) { + s->cpl_band_struct[bnd] = 1; + s->num_cpl_bands--; + } + } + s->cpl_band_struct[s->num_cpl_subbands-1] = 0; + } else { + /* coupling not in use */ + for (ch = 1; ch <= fbw_channels; ch++) + s->channel_in_cpl[ch] = 0; + } + } + + /* coupling coordinates */ + if (s->cpl_in_use) { + int cpl_coords_exist = 0; + + for (ch = 1; ch <= fbw_channels; ch++) { + if (s->channel_in_cpl[ch]) { + if (get_bits1(gbc)) { + int master_cpl_coord, cpl_coord_exp, cpl_coord_mant; + cpl_coords_exist = 1; + master_cpl_coord = 3 * get_bits(gbc, 2); + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + cpl_coord_exp = get_bits(gbc, 4); + cpl_coord_mant = get_bits(gbc, 4); + if (cpl_coord_exp == 15) + s->cpl_coords[ch][bnd] = cpl_coord_mant / 16.0f; + else + s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16.0f) / 32.0f; + s->cpl_coords[ch][bnd] *= scale_factors[cpl_coord_exp + master_cpl_coord]; + } + } + } + } + /* phase flags */ + if (channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) { + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + s->phase_flags[bnd] = s->phase_flags_in_use? get_bits1(gbc) : 0; + } + } + } + + /* stereo rematrixing strategy and band structure */ + if (channel_mode == AC3_CHMODE_STEREO) { + if (get_bits1(gbc)) { + s->num_rematrixing_bands = 4; + if(s->cpl_in_use && s->start_freq[CPL_CH] <= 61) + s->num_rematrixing_bands -= 1 + (s->start_freq[CPL_CH] == 37); + for(bnd=0; bnd<s->num_rematrixing_bands; bnd++) + s->rematrixing_flags[bnd] = get_bits1(gbc); + } + } + + /* exponent strategies for each channel */ + s->exp_strategy[CPL_CH] = EXP_REUSE; + s->exp_strategy[s->lfe_ch] = EXP_REUSE; + for (ch = !s->cpl_in_use; ch <= s->channels; ch++) { + if(ch == s->lfe_ch) + s->exp_strategy[ch] = get_bits(gbc, 1); + else + s->exp_strategy[ch] = get_bits(gbc, 2); + if(s->exp_strategy[ch] != EXP_REUSE) + bit_alloc_stages[ch] = 3; + } + + /* channel bandwidth */ + for (ch = 1; ch <= fbw_channels; ch++) { + s->start_freq[ch] = 0; + if (s->exp_strategy[ch] != EXP_REUSE) { + int prev = s->end_freq[ch]; + if (s->channel_in_cpl[ch]) + s->end_freq[ch] = s->start_freq[CPL_CH]; + else { + int bandwidth_code = get_bits(gbc, 6); + if (bandwidth_code > 60) { + av_log(s->avctx, AV_LOG_ERROR, "bandwidth code = %d > 60", bandwidth_code); + return -1; + } + s->end_freq[ch] = bandwidth_code * 3 + 73; + } + if(blk > 0 && s->end_freq[ch] != prev) + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); + } + } + s->start_freq[s->lfe_ch] = 0; + s->end_freq[s->lfe_ch] = 7; + + /* decode exponents for each channel */ + for (ch = !s->cpl_in_use; ch <= s->channels; ch++) { + if (s->exp_strategy[ch] != EXP_REUSE) { + int group_size, num_groups; + group_size = 3 << (s->exp_strategy[ch] - 1); + if(ch == CPL_CH) + num_groups = (s->end_freq[ch] - s->start_freq[ch]) / group_size; + else if(ch == s->lfe_ch) + num_groups = 2; + else + num_groups = (s->end_freq[ch] + group_size - 4) / group_size; + s->dexps[ch][0] = get_bits(gbc, 4) << !ch; + decode_exponents(gbc, s->exp_strategy[ch], num_groups, s->dexps[ch][0], + &s->dexps[ch][s->start_freq[ch]+!!ch]); + if(ch != CPL_CH && ch != s->lfe_ch) + skip_bits(gbc, 2); /* skip gainrng */ + } + } + + /* bit allocation information */ + if (get_bits1(gbc)) { + s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift; + s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift; + s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab[get_bits(gbc, 2)]; + s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[get_bits(gbc, 2)]; + s->bit_alloc_params.floor = ff_ac3_floor_tab[get_bits(gbc, 3)]; + for(ch=!s->cpl_in_use; ch<=s->channels; ch++) { + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); + } + } + + /* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */ + if (get_bits1(gbc)) { + int csnr; + csnr = (get_bits(gbc, 6) - 15) << 4; + for (ch = !s->cpl_in_use; ch <= s->channels; ch++) { /* snr offset and fast gain */ + s->snr_offset[ch] = (csnr + get_bits(gbc, 4)) << 2; + s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)]; + } + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); + } + + /* coupling leak information */ + if (s->cpl_in_use && get_bits1(gbc)) { + s->bit_alloc_params.cpl_fast_leak = get_bits(gbc, 3); + s->bit_alloc_params.cpl_slow_leak = get_bits(gbc, 3); + bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2); + } + + /* delta bit allocation information */ + if (get_bits1(gbc)) { + /* delta bit allocation exists (strategy) */ + for (ch = !s->cpl_in_use; ch <= fbw_channels; ch++) { + s->dba_mode[ch] = get_bits(gbc, 2); + if (s->dba_mode[ch] == DBA_RESERVED) { + av_log(s->avctx, AV_LOG_ERROR, "delta bit allocation strategy reserved\n"); + return -1; + } + bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); + } + /* channel delta offset, len and bit allocation */ + for (ch = !s->cpl_in_use; ch <= fbw_channels; ch++) { + if (s->dba_mode[ch] == DBA_NEW) { + s->dba_nsegs[ch] = get_bits(gbc, 3); + for (seg = 0; seg <= s->dba_nsegs[ch]; seg++) { + s->dba_offsets[ch][seg] = get_bits(gbc, 5); + s->dba_lengths[ch][seg] = get_bits(gbc, 4); + s->dba_values[ch][seg] = get_bits(gbc, 3); + } + } + } + } else if(blk == 0) { + for(ch=0; ch<=s->channels; ch++) { + s->dba_mode[ch] = DBA_NONE; + } + } + + /* Bit allocation */ + for(ch=!s->cpl_in_use; ch<=s->channels; ch++) { + if(bit_alloc_stages[ch] > 2) { + /* Exponent mapping into PSD and PSD integration */ + ff_ac3_bit_alloc_calc_psd(s->dexps[ch], + s->start_freq[ch], s->end_freq[ch], + s->psd[ch], s->band_psd[ch]); + } + if(bit_alloc_stages[ch] > 1) { + /* Compute excitation function, Compute masking curve, and + Apply delta bit allocation */ + ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params, s->band_psd[ch], + s->start_freq[ch], s->end_freq[ch], + s->fast_gain[ch], (ch == s->lfe_ch), + s->dba_mode[ch], s->dba_nsegs[ch], + s->dba_offsets[ch], s->dba_lengths[ch], + s->dba_values[ch], s->mask[ch]); + } + if(bit_alloc_stages[ch] > 0) { + /* Compute bit allocation */ + ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch], + s->start_freq[ch], s->end_freq[ch], + s->snr_offset[ch], + s->bit_alloc_params.floor, + s->bap[ch]); + } + } + + /* unused dummy data */ + if (get_bits1(gbc)) { + int skipl = get_bits(gbc, 9); + while(skipl--) + skip_bits(gbc, 8); + } + + /* unpack the transform coefficients + this also uncouples channels if coupling is in use. */ + if (get_transform_coeffs(s)) { + av_log(s->avctx, AV_LOG_ERROR, "Error in routine get_transform_coeffs\n"); + return -1; + } + + /* recover coefficients if rematrixing is in use */ + if(s->channel_mode == AC3_CHMODE_STEREO) + do_rematrixing(s); + + /* apply scaling to coefficients (headroom, dynrng) */ + for(ch=1; ch<=s->channels; ch++) { + float gain = 2.0f * s->mul_bias; + if(s->channel_mode == AC3_CHMODE_DUALMONO) { + gain *= s->dynamic_range[ch-1]; + } else { + gain *= s->dynamic_range[0]; + } + for(i=0; i<s->end_freq[ch]; i++) { + s->transform_coeffs[ch][i] *= gain; + } + } + + do_imdct(s); + + /* downmix output if needed */ + if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) && + s->fbw_channels == s->out_channels)) { + ac3_downmix(s); + } + + /* convert float to 16-bit integer */ + for(ch=0; ch<s->out_channels; ch++) { + for(i=0; i<256; i++) { + s->output[ch][i] += s->add_bias; + } + s->dsp.float_to_int16(s->int_output[ch], s->output[ch], 256); + } + + return 0; +} + +/** + * Decode a single AC-3 frame. + */ +static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +{ + AC3DecodeContext *s = avctx->priv_data; + int16_t *out_samples = (int16_t *)data; + int i, blk, ch, err; + + /* initialize the GetBitContext with the start of valid AC-3 Frame */ + init_get_bits(&s->gbc, buf, buf_size * 8); + + /* parse the syncinfo */ + err = ac3_parse_header(s); + if(err) { + switch(err) { + case AC3_PARSE_ERROR_SYNC: + av_log(avctx, AV_LOG_ERROR, "frame sync error\n"); + break; + case AC3_PARSE_ERROR_BSID: + av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n"); + break; + case AC3_PARSE_ERROR_SAMPLE_RATE: + av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n"); + break; + case AC3_PARSE_ERROR_FRAME_SIZE: + av_log(avctx, AV_LOG_ERROR, "invalid frame size\n"); + break; + default: + av_log(avctx, AV_LOG_ERROR, "invalid header\n"); + break; + } + return -1; + } + + /* check that reported frame size fits in input buffer */ + if(s->frame_size > buf_size) { + av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); + return -1; + } + + /* check for crc mismatch */ + if(avctx->error_resilience >= FF_ER_CAREFUL) { + if(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size-2)) { + av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n"); + return -1; + } + /* TODO: error concealment */ + } + + avctx->sample_rate = s->sample_rate; + avctx->bit_rate = s->bit_rate; + + /* channel config */ + s->out_channels = s->channels; + if (avctx->request_channels > 0 && avctx->request_channels <= 2 && + avctx->request_channels < s->channels) { + s->out_channels = avctx->request_channels; + s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; + } + avctx->channels = s->out_channels; + + /* set downmixing coefficients if needed */ + if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) && + s->fbw_channels == s->out_channels)) { + set_downmix_coeffs(s); + } + + /* parse the audio blocks */ + for (blk = 0; blk < NB_BLOCKS; blk++) { + if (ac3_parse_audio_block(s, blk)) { + av_log(avctx, AV_LOG_ERROR, "error parsing the audio block\n"); + *data_size = 0; + return s->frame_size; + } + for (i = 0; i < 256; i++) + for (ch = 0; ch < s->out_channels; ch++) + *(out_samples++) = s->int_output[ch][i]; + } + *data_size = NB_BLOCKS * 256 * avctx->channels * sizeof (int16_t); + return s->frame_size; +} + +/** + * Uninitialize the AC-3 decoder. + */ +static int ac3_decode_end(AVCodecContext *avctx) +{ + AC3DecodeContext *s = avctx->priv_data; + ff_mdct_end(&s->imdct_512); + ff_mdct_end(&s->imdct_256); + + return 0; +} + +AVCodec ac3_decoder = { + .name = "ac3", + .type = CODEC_TYPE_AUDIO, + .id = CODEC_ID_AC3, + .priv_data_size = sizeof (AC3DecodeContext), + .init = ac3_decode_init, + .close = ac3_decode_end, + .decode = ac3_decode_frame, +}; diff --git a/contrib/ffmpeg/libavcodec/ac3enc.c b/contrib/ffmpeg/libavcodec/ac3enc.c index 5161b61e4..1b95e8060 100644 --- a/contrib/ffmpeg/libavcodec/ac3enc.c +++ b/contrib/ffmpeg/libavcodec/ac3enc.c @@ -37,34 +37,33 @@ typedef struct AC3EncodeContext { int lfe_channel; int bit_rate; unsigned int sample_rate; - unsigned int bsid; + unsigned int bitstream_id; unsigned int frame_size_min; /* minimum frame size in case rounding is necessary */ unsigned int frame_size; /* current frame size in words */ unsigned int bits_written; unsigned int samples_written; - int halfratecod; - unsigned int frmsizecod; - unsigned int fscod; /* frequency */ - unsigned int acmod; + int sr_shift; + unsigned int frame_size_code; + unsigned int sr_code; /* frequency */ + unsigned int channel_mode; int lfe; - unsigned int bsmod; + unsigned int bitstream_mode; short last_samples[AC3_MAX_CHANNELS][256]; unsigned int chbwcod[AC3_MAX_CHANNELS]; int nb_coefs[AC3_MAX_CHANNELS]; /* bitrate allocation control */ - int sgaincod, sdecaycod, fdecaycod, dbkneecod, floorcod; + int slow_gain_code, slow_decay_code, fast_decay_code, db_per_bit_code, floor_code; AC3BitAllocParameters bit_alloc; - int csnroffst; - int fgaincod[AC3_MAX_CHANNELS]; - int fsnroffst[AC3_MAX_CHANNELS]; + int coarse_snr_offset; + int fast_gain_code[AC3_MAX_CHANNELS]; + int fine_snr_offset[AC3_MAX_CHANNELS]; /* mantissa encoding */ int mant1_cnt, mant2_cnt, mant4_cnt; } AC3EncodeContext; static int16_t costab[64]; static int16_t sintab[64]; -static int16_t fft_rev[512]; static int16_t xcos1[128]; static int16_t xsin1[128]; @@ -74,8 +73,6 @@ static int16_t xsin1[128]; /* new exponents are sent if their Norm 1 exceed this number */ #define EXP_DIFF_THRESHOLD 1000 -static void fft_init(int ln); - static inline int16_t fix15(float a) { int v; @@ -93,7 +90,7 @@ typedef struct IComplex { static void fft_init(int ln) { - int i, j, m, n; + int i, n; float alpha; n = 1 << ln; @@ -103,14 +100,6 @@ static void fft_init(int ln) costab[i] = fix15(cos(alpha)); sintab[i] = fix15(sin(alpha)); } - - for(i=0;i<n;i++) { - m=0; - for(j=0;j<ln;j++) { - m |= ((i >> j) & 1) << (ln-j-1); - } - fft_rev[i]=m; - } } /* butter fly op */ @@ -148,14 +137,9 @@ static void fft(IComplex *z, int ln) /* reverse */ for(j=0;j<np;j++) { - int k; - IComplex tmp; - k = fft_rev[j]; - if (k < j) { - tmp = z[k]; - z[k] = z[j]; - z[j] = tmp; - } + int k = ff_reverse[j] >> (8 - ln); + if (k < j) + FFSWAP(IComplex, z[k], z[j]); } /* pass 0 */ @@ -438,7 +422,7 @@ static void bit_alloc_masking(AC3EncodeContext *s, int16_t mask[NB_BLOCKS][AC3_MAX_CHANNELS][50]) { int blk, ch; - int16_t bndpsd[NB_BLOCKS][AC3_MAX_CHANNELS][50]; + int16_t band_psd[NB_BLOCKS][AC3_MAX_CHANNELS][50]; for(blk=0; blk<NB_BLOCKS; blk++) { for(ch=0;ch<s->nb_all_channels;ch++) { @@ -448,12 +432,12 @@ static void bit_alloc_masking(AC3EncodeContext *s, } else { ff_ac3_bit_alloc_calc_psd(encoded_exp[blk][ch], 0, s->nb_coefs[ch], - psd[blk][ch], bndpsd[blk][ch]); - ff_ac3_bit_alloc_calc_mask(&s->bit_alloc, bndpsd[blk][ch], + psd[blk][ch], band_psd[blk][ch]); + ff_ac3_bit_alloc_calc_mask(&s->bit_alloc, band_psd[blk][ch], 0, s->nb_coefs[ch], - ff_fgaintab[s->fgaincod[ch]], + ff_ac3_fast_gain_tab[s->fast_gain_code[ch]], ch == s->lfe_channel, - 2, 0, NULL, NULL, NULL, + DBA_NONE, 0, NULL, NULL, NULL, mask[blk][ch]); } } @@ -464,12 +448,12 @@ static int bit_alloc(AC3EncodeContext *s, int16_t mask[NB_BLOCKS][AC3_MAX_CHANNELS][50], int16_t psd[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], uint8_t bap[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], - int frame_bits, int csnroffst, int fsnroffst) + int frame_bits, int coarse_snr_offset, int fine_snr_offset) { int i, ch; - int snroffset; + int snr_offset; - snroffset = (((csnroffst - 15) << 4) + fsnroffst) << 2; + snr_offset = (((coarse_snr_offset - 15) << 4) + fine_snr_offset) << 2; /* compute size */ for(i=0;i<NB_BLOCKS;i++) { @@ -478,7 +462,7 @@ static int bit_alloc(AC3EncodeContext *s, s->mant4_cnt = 0; for(ch=0;ch<s->nb_all_channels;ch++) { ff_ac3_bit_alloc_calc_bap(mask[i][ch], psd[i][ch], 0, - s->nb_coefs[ch], snroffset, + s->nb_coefs[ch], snr_offset, s->bit_alloc.floor, bap[i][ch]); frame_bits += compute_mantissa_size(s, bap[i][ch], s->nb_coefs[ch]); @@ -486,7 +470,7 @@ static int bit_alloc(AC3EncodeContext *s, } #if 0 printf("csnr=%d fsnr=%d frame_bits=%d diff=%d\n", - csnroffst, fsnroffst, frame_bits, + coarse_snr_offset, fine_snr_offset, frame_bits, 16 * s->frame_size - ((frame_bits + 7) & ~7)); #endif return 16 * s->frame_size - frame_bits; @@ -501,40 +485,40 @@ static int compute_bit_allocation(AC3EncodeContext *s, int frame_bits) { int i, ch; - int csnroffst, fsnroffst; + int coarse_snr_offset, fine_snr_offset; uint8_t bap1[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; int16_t psd[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; int16_t mask[NB_BLOCKS][AC3_MAX_CHANNELS][50]; static int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 }; /* init default parameters */ - s->sdecaycod = 2; - s->fdecaycod = 1; - s->sgaincod = 1; - s->dbkneecod = 2; - s->floorcod = 4; + s->slow_decay_code = 2; + s->fast_decay_code = 1; + s->slow_gain_code = 1; + s->db_per_bit_code = 2; + s->floor_code = 4; for(ch=0;ch<s->nb_all_channels;ch++) - s->fgaincod[ch] = 4; + s->fast_gain_code[ch] = 4; /* compute real values */ - s->bit_alloc.fscod = s->fscod; - s->bit_alloc.halfratecod = s->halfratecod; - s->bit_alloc.sdecay = ff_sdecaytab[s->sdecaycod] >> s->halfratecod; - s->bit_alloc.fdecay = ff_fdecaytab[s->fdecaycod] >> s->halfratecod; - s->bit_alloc.sgain = ff_sgaintab[s->sgaincod]; - s->bit_alloc.dbknee = ff_dbkneetab[s->dbkneecod]; - s->bit_alloc.floor = ff_floortab[s->floorcod]; + s->bit_alloc.sr_code = s->sr_code; + s->bit_alloc.sr_shift = s->sr_shift; + s->bit_alloc.slow_decay = ff_ac3_slow_decay_tab[s->slow_decay_code] >> s->sr_shift; + s->bit_alloc.fast_decay = ff_ac3_fast_decay_tab[s->fast_decay_code] >> s->sr_shift; + s->bit_alloc.slow_gain = ff_ac3_slow_gain_tab[s->slow_gain_code]; + s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code]; + s->bit_alloc.floor = ff_ac3_floor_tab[s->floor_code]; /* header size */ frame_bits += 65; - // if (s->acmod == 2) + // if (s->channel_mode == 2) // frame_bits += 2; - frame_bits += frame_bits_inc[s->acmod]; + frame_bits += frame_bits_inc[s->channel_mode]; /* audio blocks */ for(i=0;i<NB_BLOCKS;i++) { frame_bits += s->nb_channels * 2 + 2; /* blksw * c, dithflag * c, dynrnge, cplstre */ - if (s->acmod == 2) { + if (s->channel_mode == AC3_CHMODE_STEREO) { frame_bits++; /* rematstr */ if(i==0) frame_bits += 4; } @@ -568,43 +552,43 @@ static int compute_bit_allocation(AC3EncodeContext *s, /* now the big work begins : do the bit allocation. Modify the snr offset until we can pack everything in the requested frame size */ - csnroffst = s->csnroffst; - while (csnroffst >= 0 && - bit_alloc(s, mask, psd, bap, frame_bits, csnroffst, 0) < 0) - csnroffst -= SNR_INC1; - if (csnroffst < 0) { - av_log(NULL, AV_LOG_ERROR, "Bit allocation failed, try increasing the bitrate, -ab 384 for example!\n"); + coarse_snr_offset = s->coarse_snr_offset; + while (coarse_snr_offset >= 0 && + bit_alloc(s, mask, psd, bap, frame_bits, coarse_snr_offset, 0) < 0) + coarse_snr_offset -= SNR_INC1; + if (coarse_snr_offset < 0) { + av_log(NULL, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n"); return -1; } - while ((csnroffst + SNR_INC1) <= 63 && + while ((coarse_snr_offset + SNR_INC1) <= 63 && bit_alloc(s, mask, psd, bap1, frame_bits, - csnroffst + SNR_INC1, 0) >= 0) { - csnroffst += SNR_INC1; + coarse_snr_offset + SNR_INC1, 0) >= 0) { + coarse_snr_offset += SNR_INC1; memcpy(bap, bap1, sizeof(bap1)); } - while ((csnroffst + 1) <= 63 && - bit_alloc(s, mask, psd, bap1, frame_bits, csnroffst + 1, 0) >= 0) { - csnroffst++; + while ((coarse_snr_offset + 1) <= 63 && + bit_alloc(s, mask, psd, bap1, frame_bits, coarse_snr_offset + 1, 0) >= 0) { + coarse_snr_offset++; memcpy(bap, bap1, sizeof(bap1)); } - fsnroffst = 0; - while ((fsnroffst + SNR_INC1) <= 15 && + fine_snr_offset = 0; + while ((fine_snr_offset + SNR_INC1) <= 15 && bit_alloc(s, mask, psd, bap1, frame_bits, - csnroffst, fsnroffst + SNR_INC1) >= 0) { - fsnroffst += SNR_INC1; + coarse_snr_offset, fine_snr_offset + SNR_INC1) >= 0) { + fine_snr_offset += SNR_INC1; memcpy(bap, bap1, sizeof(bap1)); } - while ((fsnroffst + 1) <= 15 && + while ((fine_snr_offset + 1) <= 15 && bit_alloc(s, mask, psd, bap1, frame_bits, - csnroffst, fsnroffst + 1) >= 0) { - fsnroffst++; + coarse_snr_offset, fine_snr_offset + 1) >= 0) { + fine_snr_offset++; memcpy(bap, bap1, sizeof(bap1)); } - s->csnroffst = csnroffst; + s->coarse_snr_offset = coarse_snr_offset; for(ch=0;ch<s->nb_all_channels;ch++) - s->fsnroffst[ch] = fsnroffst; + s->fine_snr_offset[ch] = fine_snr_offset; #if defined(DEBUG_BITALLOC) { int j; @@ -632,7 +616,8 @@ static int AC3_encode_init(AVCodecContext *avctx) AC3EncodeContext *s = avctx->priv_data; int i, j, ch; float alpha; - static const uint8_t acmod_defs[6] = { + int bw_code; + static const uint8_t channel_mode_defs[6] = { 0x01, /* C */ 0x02, /* L R */ 0x03, /* L C R */ @@ -648,7 +633,7 @@ static int AC3_encode_init(AVCodecContext *avctx) /* number of channels */ if (channels < 1 || channels > 6) return -1; - s->acmod = acmod_defs[channels - 1]; + s->channel_mode = channel_mode_defs[channels - 1]; s->lfe = (channels == 6) ? 1 : 0; s->nb_all_channels = channels; s->nb_channels = channels > 5 ? 5 : channels; @@ -657,45 +642,53 @@ static int AC3_encode_init(AVCodecContext *avctx) /* frequency */ for(i=0;i<3;i++) { for(j=0;j<3;j++) - if ((ff_ac3_freqs[j] >> i) == freq) + if ((ff_ac3_sample_rate_tab[j] >> i) == freq) goto found; } return -1; found: s->sample_rate = freq; - s->halfratecod = i; - s->fscod = j; - s->bsid = 8 + s->halfratecod; - s->bsmod = 0; /* complete main audio service */ + s->sr_shift = i; + s->sr_code = j; + s->bitstream_id = 8 + s->sr_shift; + s->bitstream_mode = 0; /* complete main audio service */ /* bitrate & frame size */ - bitrate /= 1000; for(i=0;i<19;i++) { - if ((ff_ac3_bitratetab[i] >> s->halfratecod) == bitrate) + if ((ff_ac3_bitrate_tab[i] >> s->sr_shift)*1000 == bitrate) break; } if (i == 19) return -1; s->bit_rate = bitrate; - s->frmsizecod = i << 1; - s->frame_size_min = ff_ac3_frame_sizes[s->frmsizecod][s->fscod]; + s->frame_size_code = i << 1; + s->frame_size_min = ff_ac3_frame_size_tab[s->frame_size_code][s->sr_code]; s->bits_written = 0; s->samples_written = 0; s->frame_size = s->frame_size_min; /* bit allocation init */ - for(ch=0;ch<s->nb_channels;ch++) { - /* bandwidth for each channel */ + if(avctx->cutoff) { + /* calculate bandwidth based on user-specified cutoff frequency */ + int cutoff = av_clip(avctx->cutoff, 1, s->sample_rate >> 1); + int fbw_coeffs = cutoff * 512 / s->sample_rate; + bw_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); + } else { + /* use default bandwidth setting */ /* XXX: should compute the bandwidth according to the frame size, so that we avoid anoying high freq artefacts */ - s->chbwcod[ch] = 50; /* sample bandwidth as mpeg audio layer 2 table 0 */ - s->nb_coefs[ch] = ((s->chbwcod[ch] + 12) * 3) + 37; + bw_code = 50; + } + for(ch=0;ch<s->nb_channels;ch++) { + /* bandwidth for each channel */ + s->chbwcod[ch] = bw_code; + s->nb_coefs[ch] = bw_code * 3 + 73; } if (s->lfe) { s->nb_coefs[s->lfe_channel] = 7; /* fixed */ } /* initial snr offset */ - s->csnroffst = 40; + s->coarse_snr_offset = 40; /* mdct init */ fft_init(MDCT_NBITS - 2); @@ -718,16 +711,16 @@ static void output_frame_header(AC3EncodeContext *s, unsigned char *frame) put_bits(&s->pb, 16, 0x0b77); /* frame header */ put_bits(&s->pb, 16, 0); /* crc1: will be filled later */ - put_bits(&s->pb, 2, s->fscod); - put_bits(&s->pb, 6, s->frmsizecod + (s->frame_size - s->frame_size_min)); - put_bits(&s->pb, 5, s->bsid); - put_bits(&s->pb, 3, s->bsmod); - put_bits(&s->pb, 3, s->acmod); - if ((s->acmod & 0x01) && s->acmod != 0x01) + put_bits(&s->pb, 2, s->sr_code); + put_bits(&s->pb, 6, s->frame_size_code + (s->frame_size - s->frame_size_min)); + put_bits(&s->pb, 5, s->bitstream_id); + put_bits(&s->pb, 3, s->bitstream_mode); + put_bits(&s->pb, 3, s->channel_mode); + if ((s->channel_mode & 0x01) && s->channel_mode != AC3_CHMODE_MONO) put_bits(&s->pb, 2, 1); /* XXX -4.5 dB */ - if (s->acmod & 0x04) + if (s->channel_mode & 0x04) put_bits(&s->pb, 2, 1); /* XXX -6 dB */ - if (s->acmod == 0x02) + if (s->channel_mode == AC3_CHMODE_STEREO) put_bits(&s->pb, 2, 0); /* surround not indicated */ put_bits(&s->pb, 1, s->lfe); /* LFE */ put_bits(&s->pb, 5, 31); /* dialog norm: -31 db */ @@ -738,7 +731,7 @@ static void output_frame_header(AC3EncodeContext *s, unsigned char *frame) put_bits(&s->pb, 1, 1); /* original bitstream */ put_bits(&s->pb, 1, 0); /* no time code 1 */ put_bits(&s->pb, 1, 0); /* no time code 2 */ - put_bits(&s->pb, 1, 0); /* no addtional bit stream info */ + put_bits(&s->pb, 1, 0); /* no additional bit stream info */ } /* symetric quantization on 'levels' levels */ @@ -810,7 +803,7 @@ static void output_audio_block(AC3EncodeContext *s, put_bits(&s->pb, 1, 0); /* no new coupling strategy */ } - if (s->acmod == 2) + if (s->channel_mode == AC3_CHMODE_STEREO) { if(block_num==0) { @@ -900,20 +893,20 @@ static void output_audio_block(AC3EncodeContext *s, baie = (block_num == 0); put_bits(&s->pb, 1, baie); if (baie) { - put_bits(&s->pb, 2, s->sdecaycod); - put_bits(&s->pb, 2, s->fdecaycod); - put_bits(&s->pb, 2, s->sgaincod); - put_bits(&s->pb, 2, s->dbkneecod); - put_bits(&s->pb, 3, s->floorcod); + put_bits(&s->pb, 2, s->slow_decay_code); + put_bits(&s->pb, 2, s->fast_decay_code); + put_bits(&s->pb, 2, s->slow_gain_code); + put_bits(&s->pb, 2, s->db_per_bit_code); + put_bits(&s->pb, 3, s->floor_code); } /* snr offset */ put_bits(&s->pb, 1, baie); /* always present with bai */ if (baie) { - put_bits(&s->pb, 6, s->csnroffst); + put_bits(&s->pb, 6, s->coarse_snr_offset); for(ch=0;ch<s->nb_all_channels;ch++) { - put_bits(&s->pb, 4, s->fsnroffst[ch]); - put_bits(&s->pb, 3, s->fgaincod[ch]); + put_bits(&s->pb, 4, s->fine_snr_offset[ch]); + put_bits(&s->pb, 3, s->fast_gain_code[ch]); } } @@ -1132,16 +1125,17 @@ static int output_frame_end(AC3EncodeContext *s) /* Now we must compute both crcs : this is not so easy for crc1 because it is at the beginning of the data... */ frame_size_58 = (frame_size >> 1) + (frame_size >> 3); - crc1 = bswap_16(av_crc(av_crc8005, 0, frame + 4, 2 * frame_size_58 - 4)); + crc1 = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, + frame + 4, 2 * frame_size_58 - 4)); /* XXX: could precompute crc_inv */ crc_inv = pow_poly((CRC16_POLY >> 1), (16 * frame_size_58) - 16, CRC16_POLY); crc1 = mul_poly(crc_inv, crc1, CRC16_POLY); - frame[2] = crc1 >> 8; - frame[3] = crc1; + AV_WB16(frame+2,crc1); - crc2 = bswap_16(av_crc(av_crc8005, 0, frame + 2 * frame_size_58, (frame_size - frame_size_58) * 2 - 2)); - frame[2*frame_size - 2] = crc2 >> 8; - frame[2*frame_size - 1] = crc2; + crc2 = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, + frame + 2 * frame_size_58, + (frame_size - frame_size_58) * 2 - 2)); + AV_WB16(frame+2*frame_size-2,crc2); // printf("n=%d frame_size=%d\n", n, frame_size); return frame_size * 2; @@ -1242,11 +1236,11 @@ static int AC3_encode_frame(AVCodecContext *avctx, } /* adjust for fractional frame sizes */ - while(s->bits_written >= s->bit_rate*1000 && s->samples_written >= s->sample_rate) { - s->bits_written -= s->bit_rate*1000; + while(s->bits_written >= s->bit_rate && s->samples_written >= s->sample_rate) { + s->bits_written -= s->bit_rate; s->samples_written -= s->sample_rate; } - s->frame_size = s->frame_size_min + (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate*1000); + s->frame_size = s->frame_size_min + (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate); s->bits_written += s->frame_size * 16; s->samples_written += AC3_FRAME_SIZE; @@ -1271,6 +1265,7 @@ static int AC3_encode_close(AVCodecContext *avctx) /*************************************************************************/ /* TEST */ +#undef random #define FN (N/4) void fft_test(void) diff --git a/contrib/ffmpeg/libavcodec/ac3tab.c b/contrib/ffmpeg/libavcodec/ac3tab.c new file mode 100644 index 000000000..c87200b1d --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ac3tab.c @@ -0,0 +1,249 @@ +/* + * AC3 tables + * 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 ac3tab.c + * tables taken directly from AC3 spec. + */ + +#include "ac3tab.h" + +/** + * Possible frame sizes. + * from ATSC A/52 Table 5.18 Frame Size Code Table. + */ +const uint16_t ff_ac3_frame_size_tab[38][3] = { + { 64, 69, 96 }, + { 64, 70, 96 }, + { 80, 87, 120 }, + { 80, 88, 120 }, + { 96, 104, 144 }, + { 96, 105, 144 }, + { 112, 121, 168 }, + { 112, 122, 168 }, + { 128, 139, 192 }, + { 128, 140, 192 }, + { 160, 174, 240 }, + { 160, 175, 240 }, + { 192, 208, 288 }, + { 192, 209, 288 }, + { 224, 243, 336 }, + { 224, 244, 336 }, + { 256, 278, 384 }, + { 256, 279, 384 }, + { 320, 348, 480 }, + { 320, 349, 480 }, + { 384, 417, 576 }, + { 384, 418, 576 }, + { 448, 487, 672 }, + { 448, 488, 672 }, + { 512, 557, 768 }, + { 512, 558, 768 }, + { 640, 696, 960 }, + { 640, 697, 960 }, + { 768, 835, 1152 }, + { 768, 836, 1152 }, + { 896, 975, 1344 }, + { 896, 976, 1344 }, + { 1024, 1114, 1536 }, + { 1024, 1115, 1536 }, + { 1152, 1253, 1728 }, + { 1152, 1254, 1728 }, + { 1280, 1393, 1920 }, + { 1280, 1394, 1920 }, +}; + +/** + * Maps audio coding mode (acmod) to number of full-bandwidth channels. + * from ATSC A/52 Table 5.8 Audio Coding Mode + */ +const uint8_t ff_ac3_channels_tab[8] = { + 2, 1, 2, 3, 3, 4, 4, 5 +}; + +/* possible frequencies */ +const uint16_t ff_ac3_sample_rate_tab[3] = { 48000, 44100, 32000 }; + +/* possible bitrates */ +const uint16_t ff_ac3_bitrate_tab[19] = { + 32, 40, 48, 56, 64, 80, 96, 112, 128, + 160, 192, 224, 256, 320, 384, 448, 512, 576, 640 +}; + +/* AC3 MDCT window */ + +/* MDCT window */ +const int16_t ff_ac3_window[256] = { + 4, 7, 12, 16, 21, 28, 34, 42, + 51, 61, 72, 84, 97, 111, 127, 145, + 164, 184, 207, 231, 257, 285, 315, 347, + 382, 419, 458, 500, 544, 591, 641, 694, + 750, 810, 872, 937, 1007, 1079, 1155, 1235, + 1318, 1406, 1497, 1593, 1692, 1796, 1903, 2016, + 2132, 2253, 2379, 2509, 2644, 2783, 2927, 3076, + 3230, 3389, 3552, 3721, 3894, 4072, 4255, 4444, + 4637, 4835, 5038, 5246, 5459, 5677, 5899, 6127, + 6359, 6596, 6837, 7083, 7334, 7589, 7848, 8112, + 8380, 8652, 8927, 9207, 9491, 9778,10069,10363, +10660,10960,11264,11570,11879,12190,12504,12820, +13138,13458,13780,14103,14427,14753,15079,15407, +15735,16063,16392,16720,17049,17377,17705,18032, +18358,18683,19007,19330,19651,19970,20287,20602, +20914,21225,21532,21837,22139,22438,22733,23025, +23314,23599,23880,24157,24430,24699,24964,25225, +25481,25732,25979,26221,26459,26691,26919,27142, +27359,27572,27780,27983,28180,28373,28560,28742, +28919,29091,29258,29420,29577,29729,29876,30018, +30155,30288,30415,30538,30657,30771,30880,30985, +31086,31182,31274,31363,31447,31528,31605,31678, +31747,31814,31877,31936,31993,32046,32097,32145, +32190,32232,32272,32310,32345,32378,32409,32438, +32465,32490,32513,32535,32556,32574,32592,32608, +32623,32636,32649,32661,32671,32681,32690,32698, +32705,32712,32718,32724,32729,32733,32737,32741, +32744,32747,32750,32752,32754,32756,32757,32759, +32760,32761,32762,32763,32764,32764,32765,32765, +32766,32766,32766,32766,32767,32767,32767,32767, +32767,32767,32767,32767,32767,32767,32767,32767, +32767,32767,32767,32767,32767,32767,32767,32767, +}; + +const uint8_t ff_ac3_log_add_tab[260]= { +0x40,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37, +0x36,0x35,0x34,0x34,0x33,0x32,0x31,0x30,0x2f,0x2f, +0x2e,0x2d,0x2c,0x2c,0x2b,0x2a,0x29,0x29,0x28,0x27, +0x26,0x26,0x25,0x24,0x24,0x23,0x23,0x22,0x21,0x21, +0x20,0x20,0x1f,0x1e,0x1e,0x1d,0x1d,0x1c,0x1c,0x1b, +0x1b,0x1a,0x1a,0x19,0x19,0x18,0x18,0x17,0x17,0x16, +0x16,0x15,0x15,0x15,0x14,0x14,0x13,0x13,0x13,0x12, +0x12,0x12,0x11,0x11,0x11,0x10,0x10,0x10,0x0f,0x0f, +0x0f,0x0e,0x0e,0x0e,0x0d,0x0d,0x0d,0x0d,0x0c,0x0c, +0x0c,0x0c,0x0b,0x0b,0x0b,0x0b,0x0a,0x0a,0x0a,0x0a, +0x0a,0x09,0x09,0x09,0x09,0x09,0x08,0x08,0x08,0x08, +0x08,0x08,0x07,0x07,0x07,0x07,0x07,0x07,0x06,0x06, +0x06,0x06,0x06,0x06,0x06,0x06,0x05,0x05,0x05,0x05, +0x05,0x05,0x05,0x05,0x04,0x04,0x04,0x04,0x04,0x04, +0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03, +0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x02, +0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, +0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +const uint16_t ff_ac3_hearing_threshold_tab[50][3]= { +{ 0x04d0,0x04f0,0x0580 }, +{ 0x04d0,0x04f0,0x0580 }, +{ 0x0440,0x0460,0x04b0 }, +{ 0x0400,0x0410,0x0450 }, +{ 0x03e0,0x03e0,0x0420 }, +{ 0x03c0,0x03d0,0x03f0 }, +{ 0x03b0,0x03c0,0x03e0 }, +{ 0x03b0,0x03b0,0x03d0 }, +{ 0x03a0,0x03b0,0x03c0 }, +{ 0x03a0,0x03a0,0x03b0 }, +{ 0x03a0,0x03a0,0x03b0 }, +{ 0x03a0,0x03a0,0x03b0 }, +{ 0x03a0,0x03a0,0x03a0 }, +{ 0x0390,0x03a0,0x03a0 }, +{ 0x0390,0x0390,0x03a0 }, +{ 0x0390,0x0390,0x03a0 }, +{ 0x0380,0x0390,0x03a0 }, +{ 0x0380,0x0380,0x03a0 }, +{ 0x0370,0x0380,0x03a0 }, +{ 0x0370,0x0380,0x03a0 }, +{ 0x0360,0x0370,0x0390 }, +{ 0x0360,0x0370,0x0390 }, +{ 0x0350,0x0360,0x0390 }, +{ 0x0350,0x0360,0x0390 }, +{ 0x0340,0x0350,0x0380 }, +{ 0x0340,0x0350,0x0380 }, +{ 0x0330,0x0340,0x0380 }, +{ 0x0320,0x0340,0x0370 }, +{ 0x0310,0x0320,0x0360 }, +{ 0x0300,0x0310,0x0350 }, +{ 0x02f0,0x0300,0x0340 }, +{ 0x02f0,0x02f0,0x0330 }, +{ 0x02f0,0x02f0,0x0320 }, +{ 0x02f0,0x02f0,0x0310 }, +{ 0x0300,0x02f0,0x0300 }, +{ 0x0310,0x0300,0x02f0 }, +{ 0x0340,0x0320,0x02f0 }, +{ 0x0390,0x0350,0x02f0 }, +{ 0x03e0,0x0390,0x0300 }, +{ 0x0420,0x03e0,0x0310 }, +{ 0x0460,0x0420,0x0330 }, +{ 0x0490,0x0450,0x0350 }, +{ 0x04a0,0x04a0,0x03c0 }, +{ 0x0460,0x0490,0x0410 }, +{ 0x0440,0x0460,0x0470 }, +{ 0x0440,0x0440,0x04a0 }, +{ 0x0520,0x0480,0x0460 }, +{ 0x0800,0x0630,0x0440 }, +{ 0x0840,0x0840,0x0450 }, +{ 0x0840,0x0840,0x04e0 }, +}; + +const uint8_t ff_ac3_bap_tab[64]= { + 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, + 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, + 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, + 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, + 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, + 15, 15, 15, 15, +}; + +const uint8_t ff_ac3_slow_decay_tab[4]={ + 0x0f, 0x11, 0x13, 0x15, +}; + +const uint8_t ff_ac3_fast_decay_tab[4]={ + 0x3f, 0x53, 0x67, 0x7b, +}; + +const uint16_t ff_ac3_slow_gain_tab[4]= { + 0x540, 0x4d8, 0x478, 0x410, +}; + +const uint16_t ff_ac3_db_per_bit_tab[4]= { + 0x000, 0x700, 0x900, 0xb00, +}; + +const int16_t ff_ac3_floor_tab[8]= { + 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800, +}; + +const uint16_t ff_ac3_fast_gain_tab[8]= { + 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400, +}; + +const uint8_t ff_ac3_critical_band_size_tab[50]={ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, + 3, 6, 6, 6, 6, 6, 6, 12, 12, 12, 12, 24, 24, 24, 24, 24 +}; diff --git a/contrib/ffmpeg/libavcodec/ac3tab.h b/contrib/ffmpeg/libavcodec/ac3tab.h index b549c5ba9..deb32b420 100644 --- a/contrib/ffmpeg/libavcodec/ac3tab.h +++ b/contrib/ffmpeg/libavcodec/ac3tab.h @@ -1,6 +1,6 @@ /* * AC3 tables - * copyright (c) 2001 Fabrice Bellard + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. * * This file is part of FFmpeg. * @@ -19,233 +19,25 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/** - * @file ac3tab.h - * tables taken directly from AC3 spec. - */ - -/** - * Possible frame sizes. - * from ATSC A/52 Table 5.18 Frame Size Code Table. - */ -const uint16_t ff_ac3_frame_sizes[38][3] = { - { 64, 69, 96 }, - { 64, 70, 96 }, - { 80, 87, 120 }, - { 80, 88, 120 }, - { 96, 104, 144 }, - { 96, 105, 144 }, - { 112, 121, 168 }, - { 112, 122, 168 }, - { 128, 139, 192 }, - { 128, 140, 192 }, - { 160, 174, 240 }, - { 160, 175, 240 }, - { 192, 208, 288 }, - { 192, 209, 288 }, - { 224, 243, 336 }, - { 224, 244, 336 }, - { 256, 278, 384 }, - { 256, 279, 384 }, - { 320, 348, 480 }, - { 320, 349, 480 }, - { 384, 417, 576 }, - { 384, 418, 576 }, - { 448, 487, 672 }, - { 448, 488, 672 }, - { 512, 557, 768 }, - { 512, 558, 768 }, - { 640, 696, 960 }, - { 640, 697, 960 }, - { 768, 835, 1152 }, - { 768, 836, 1152 }, - { 896, 975, 1344 }, - { 896, 976, 1344 }, - { 1024, 1114, 1536 }, - { 1024, 1115, 1536 }, - { 1152, 1253, 1728 }, - { 1152, 1254, 1728 }, - { 1280, 1393, 1920 }, - { 1280, 1394, 1920 }, -}; - -/** - * Maps audio coding mode (acmod) to number of full-bandwidth channels. - * from ATSC A/52 Table 5.8 Audio Coding Mode - */ -const uint8_t ff_ac3_channels[8] = { - 2, 1, 2, 3, 3, 4, 4, 5 -}; - -/* possible frequencies */ -const uint16_t ff_ac3_freqs[3] = { 48000, 44100, 32000 }; - -/* possible bitrates */ -const uint16_t ff_ac3_bitratetab[19] = { - 32, 40, 48, 56, 64, 80, 96, 112, 128, - 160, 192, 224, 256, 320, 384, 448, 512, 576, 640 -}; - -/* AC3 MDCT window */ - -/* MDCT window */ -const int16_t ff_ac3_window[256] = { - 4, 7, 12, 16, 21, 28, 34, 42, - 51, 61, 72, 84, 97, 111, 127, 145, - 164, 184, 207, 231, 257, 285, 315, 347, - 382, 419, 458, 500, 544, 591, 641, 694, - 750, 810, 872, 937, 1007, 1079, 1155, 1235, - 1318, 1406, 1497, 1593, 1692, 1796, 1903, 2016, - 2132, 2253, 2379, 2509, 2644, 2783, 2927, 3076, - 3230, 3389, 3552, 3721, 3894, 4072, 4255, 4444, - 4637, 4835, 5038, 5246, 5459, 5677, 5899, 6127, - 6359, 6596, 6837, 7083, 7334, 7589, 7848, 8112, - 8380, 8652, 8927, 9207, 9491, 9778,10069,10363, -10660,10960,11264,11570,11879,12190,12504,12820, -13138,13458,13780,14103,14427,14753,15079,15407, -15735,16063,16392,16720,17049,17377,17705,18032, -18358,18683,19007,19330,19651,19970,20287,20602, -20914,21225,21532,21837,22139,22438,22733,23025, -23314,23599,23880,24157,24430,24699,24964,25225, -25481,25732,25979,26221,26459,26691,26919,27142, -27359,27572,27780,27983,28180,28373,28560,28742, -28919,29091,29258,29420,29577,29729,29876,30018, -30155,30288,30415,30538,30657,30771,30880,30985, -31086,31182,31274,31363,31447,31528,31605,31678, -31747,31814,31877,31936,31993,32046,32097,32145, -32190,32232,32272,32310,32345,32378,32409,32438, -32465,32490,32513,32535,32556,32574,32592,32608, -32623,32636,32649,32661,32671,32681,32690,32698, -32705,32712,32718,32724,32729,32733,32737,32741, -32744,32747,32750,32752,32754,32756,32757,32759, -32760,32761,32762,32763,32764,32764,32765,32765, -32766,32766,32766,32766,32767,32767,32767,32767, -32767,32767,32767,32767,32767,32767,32767,32767, -32767,32767,32767,32767,32767,32767,32767,32767, -}; - -static uint8_t masktab[253]; - -static const uint8_t latab[260]= { -0x0040,0x003f,0x003e,0x003d,0x003c,0x003b,0x003a,0x0039,0x0038,0x0037, -0x0036,0x0035,0x0034,0x0034,0x0033,0x0032,0x0031,0x0030,0x002f,0x002f, -0x002e,0x002d,0x002c,0x002c,0x002b,0x002a,0x0029,0x0029,0x0028,0x0027, -0x0026,0x0026,0x0025,0x0024,0x0024,0x0023,0x0023,0x0022,0x0021,0x0021, -0x0020,0x0020,0x001f,0x001e,0x001e,0x001d,0x001d,0x001c,0x001c,0x001b, -0x001b,0x001a,0x001a,0x0019,0x0019,0x0018,0x0018,0x0017,0x0017,0x0016, -0x0016,0x0015,0x0015,0x0015,0x0014,0x0014,0x0013,0x0013,0x0013,0x0012, -0x0012,0x0012,0x0011,0x0011,0x0011,0x0010,0x0010,0x0010,0x000f,0x000f, -0x000f,0x000e,0x000e,0x000e,0x000d,0x000d,0x000d,0x000d,0x000c,0x000c, -0x000c,0x000c,0x000b,0x000b,0x000b,0x000b,0x000a,0x000a,0x000a,0x000a, -0x000a,0x0009,0x0009,0x0009,0x0009,0x0009,0x0008,0x0008,0x0008,0x0008, -0x0008,0x0008,0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0006,0x0006, -0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0005,0x0005,0x0005,0x0005, -0x0005,0x0005,0x0005,0x0005,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004, -0x0004,0x0004,0x0004,0x0004,0x0004,0x0003,0x0003,0x0003,0x0003,0x0003, -0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0002, -0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002, -0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0001,0x0001, -0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001, -0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001, -0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001, -0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, -}; - -static const uint16_t hth[50][3]= { -{ 0x04d0,0x04f0,0x0580 }, -{ 0x04d0,0x04f0,0x0580 }, -{ 0x0440,0x0460,0x04b0 }, -{ 0x0400,0x0410,0x0450 }, -{ 0x03e0,0x03e0,0x0420 }, -{ 0x03c0,0x03d0,0x03f0 }, -{ 0x03b0,0x03c0,0x03e0 }, -{ 0x03b0,0x03b0,0x03d0 }, -{ 0x03a0,0x03b0,0x03c0 }, -{ 0x03a0,0x03a0,0x03b0 }, -{ 0x03a0,0x03a0,0x03b0 }, -{ 0x03a0,0x03a0,0x03b0 }, -{ 0x03a0,0x03a0,0x03a0 }, -{ 0x0390,0x03a0,0x03a0 }, -{ 0x0390,0x0390,0x03a0 }, -{ 0x0390,0x0390,0x03a0 }, -{ 0x0380,0x0390,0x03a0 }, -{ 0x0380,0x0380,0x03a0 }, -{ 0x0370,0x0380,0x03a0 }, -{ 0x0370,0x0380,0x03a0 }, -{ 0x0360,0x0370,0x0390 }, -{ 0x0360,0x0370,0x0390 }, -{ 0x0350,0x0360,0x0390 }, -{ 0x0350,0x0360,0x0390 }, -{ 0x0340,0x0350,0x0380 }, -{ 0x0340,0x0350,0x0380 }, -{ 0x0330,0x0340,0x0380 }, -{ 0x0320,0x0340,0x0370 }, -{ 0x0310,0x0320,0x0360 }, -{ 0x0300,0x0310,0x0350 }, -{ 0x02f0,0x0300,0x0340 }, -{ 0x02f0,0x02f0,0x0330 }, -{ 0x02f0,0x02f0,0x0320 }, -{ 0x02f0,0x02f0,0x0310 }, -{ 0x0300,0x02f0,0x0300 }, -{ 0x0310,0x0300,0x02f0 }, -{ 0x0340,0x0320,0x02f0 }, -{ 0x0390,0x0350,0x02f0 }, -{ 0x03e0,0x0390,0x0300 }, -{ 0x0420,0x03e0,0x0310 }, -{ 0x0460,0x0420,0x0330 }, -{ 0x0490,0x0450,0x0350 }, -{ 0x04a0,0x04a0,0x03c0 }, -{ 0x0460,0x0490,0x0410 }, -{ 0x0440,0x0460,0x0470 }, -{ 0x0440,0x0440,0x04a0 }, -{ 0x0520,0x0480,0x0460 }, -{ 0x0800,0x0630,0x0440 }, -{ 0x0840,0x0840,0x0450 }, -{ 0x0840,0x0840,0x04e0 }, -}; - -static const uint8_t baptab[64]= { - 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, - 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, - 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, - 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, - 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, - 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, - 15, 15, 15, 15, -}; - -const uint8_t ff_sdecaytab[4]={ - 0x0f, 0x11, 0x13, 0x15, -}; - -const uint8_t ff_fdecaytab[4]={ - 0x3f, 0x53, 0x67, 0x7b, -}; - -const uint16_t ff_sgaintab[4]= { - 0x540, 0x4d8, 0x478, 0x410, -}; - -const uint16_t ff_dbkneetab[4]= { - 0x000, 0x700, 0x900, 0xb00, -}; - -const int16_t ff_floortab[8]= { - 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800, -}; - -const uint16_t ff_fgaintab[8]= { - 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400, -}; - -static const uint8_t bndsz[50]={ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, - 3, 6, 6, 6, 6, 6, 6, 12, 12, 12, 12, 24, 24, 24, 24, 24 -}; - -static uint8_t bndtab[51]; +#ifndef FFMPEG_AC3TAB_H +#define FFMPEG_AC3TAB_H + +#include "common.h" + +extern const uint16_t ff_ac3_frame_size_tab[38][3]; +extern const uint8_t ff_ac3_channels_tab[8]; +extern const uint16_t ff_ac3_sample_rate_tab[3]; +extern const uint16_t ff_ac3_bitrate_tab[19]; +extern const int16_t ff_ac3_window[256]; +extern const uint8_t ff_ac3_log_add_tab[260]; +extern const uint16_t ff_ac3_hearing_threshold_tab[50][3]; +extern const uint8_t ff_ac3_bap_tab[64]; +extern const uint8_t ff_ac3_slow_decay_tab[4]; +extern const uint8_t ff_ac3_fast_decay_tab[4]; +extern const uint16_t ff_ac3_slow_gain_tab[4]; +extern const uint16_t ff_ac3_db_per_bit_tab[4]; +extern const int16_t ff_ac3_floor_tab[8]; +extern const uint16_t ff_ac3_fast_gain_tab[8]; +extern const uint8_t ff_ac3_critical_band_size_tab[50]; + +#endif /* FFMPEG_AC3TAB_H */ diff --git a/contrib/ffmpeg/libavcodec/adpcm.c b/contrib/ffmpeg/libavcodec/adpcm.c index 8800c3a20..eadcfaedd 100644 --- a/contrib/ffmpeg/libavcodec/adpcm.c +++ b/contrib/ffmpeg/libavcodec/adpcm.c @@ -20,6 +20,7 @@ */ #include "avcodec.h" #include "bitstream.h" +#include "bytestream.h" /** * @file adpcm.c @@ -29,6 +30,11 @@ * by Mike Melanson (melanson@pcisys.net) * CD-ROM XA ADPCM codec by BERO * EA ADPCM decoder by Robin Kay (komadori@myrealbox.com) + * EA ADPCM R1/R2/R3 decoder by Peter Ross (pross@xvid.org) + * EA IMA EACS decoder by Peter Ross (pross@xvid.org) + * EA IMA SEAD decoder by Peter Ross (pross@xvid.org) + * EA ADPCM XAS decoder by Peter Ross (pross@xvid.org) + * THP ADPCM decoder by Marco Gerards (mgerards@xs4all.nl) * * Features and limitations: * @@ -48,12 +54,6 @@ #define BLKSIZE 1024 -#define CLAMP_TO_SHORT(value) \ -if (value > 32767) \ - value = 32767; \ -else if (value < -32768) \ - value = -32768; \ - /* step_table[] and index_table[] are from the ADPCM reference source */ /* This is the index table: */ static const int index_table[16] = { @@ -148,8 +148,7 @@ typedef struct ADPCMChannelStatus { typedef struct ADPCMContext { int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */ - ADPCMChannelStatus status[2]; - short sample_buffer[32]; /* hold left samples while waiting for right samples */ + ADPCMChannelStatus status[6]; } ADPCMContext; /* XXX: implement encoding */ @@ -160,11 +159,6 @@ static int adpcm_encode_init(AVCodecContext *avctx) if (avctx->channels > 2) return -1; /* only stereo or mono =) */ switch(avctx->codec->id) { - case CODEC_ID_ADPCM_IMA_QT: - av_log(avctx, AV_LOG_ERROR, "ADPCM: codec adpcm_ima_qt unsupported for encoding !\n"); - avctx->frame_size = 64; /* XXX: can multiple of avctx->channels * 64 (left and right blocks are interleaved) */ - return -1; - break; case CODEC_ID_ADPCM_IMA_WAV: avctx->frame_size = (BLKSIZE - 4 * avctx->channels) * 8 / (4 * avctx->channels) + 1; /* each 16 bits sample gives one nibble */ /* and we have 4 bytes per channel overhead */ @@ -180,6 +174,15 @@ static int adpcm_encode_init(AVCodecContext *avctx) avctx->frame_size = BLKSIZE * avctx->channels; avctx->block_align = BLKSIZE; break; + case CODEC_ID_ADPCM_SWF: + if (avctx->sample_rate != 11025 && + avctx->sample_rate != 22050 && + avctx->sample_rate != 44100) { + av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, 22050 or 44100\n"); + return -1; + } + avctx->frame_size = 512 * (avctx->sample_rate / 11025); + break; default: return -1; break; @@ -203,8 +206,8 @@ static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, sho { int delta = sample - c->prev_sample; int nibble = FFMIN(7, abs(delta)*4/step_table[c->step_index]) + (delta<0)*8; - c->prev_sample = c->prev_sample + ((step_table[c->step_index] * yamaha_difflookup[nibble]) / 8); - CLAMP_TO_SHORT(c->prev_sample); + c->prev_sample += ((step_table[c->step_index] * yamaha_difflookup[nibble]) / 8); + c->prev_sample = av_clip_int16(c->prev_sample); c->step_index = av_clip(c->step_index + index_table[nibble], 0, 88); return nibble; } @@ -223,10 +226,9 @@ static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, shor nibble= av_clip(nibble, -8, 7)&0x0F; predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta; - CLAMP_TO_SHORT(predictor); c->sample2 = c->sample1; - c->sample1 = predictor; + c->sample1 = av_clip_int16(predictor); c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8; if (c->idelta < 16) c->idelta = 16; @@ -247,8 +249,8 @@ static inline unsigned char adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, nibble = FFMIN(7, abs(delta)*4/c->step) + (delta<0)*8; - c->predictor = c->predictor + ((c->step * yamaha_difflookup[nibble]) / 8); - CLAMP_TO_SHORT(c->predictor); + c->predictor += ((c->step * yamaha_difflookup[nibble]) / 8); + c->predictor = av_clip_int16(c->predictor); c->step = (c->step * yamaha_indexscale[nibble]) >> 8; c->step = av_clip(c->step, 127, 24567); @@ -293,7 +295,7 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples, nodes[0]->step = c->step_index; nodes[0]->sample1 = c->sample1; nodes[0]->sample2 = c->sample2; - if(version == CODEC_ID_ADPCM_IMA_WAV) + if((version == CODEC_ID_ADPCM_IMA_WAV) || (version == CODEC_ID_ADPCM_SWF)) nodes[0]->sample1 = c->prev_sample; if(version == CODEC_ID_ADPCM_MS) nodes[0]->step = c->idelta; @@ -328,7 +330,7 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples, #define STORE_NODE(NAME, STEP_INDEX)\ int d;\ uint32_t ssd;\ - CLAMP_TO_SHORT(dec_sample);\ + dec_sample = av_clip_int16(dec_sample);\ d = sample - dec_sample;\ ssd = nodes[j]->ssd + d*d;\ if(nodes_next[frontier-1] && ssd >= nodes_next[frontier-1]->ssd)\ @@ -364,7 +366,7 @@ static void adpcm_compress_trellis(AVCodecContext *avctx, const short *samples, next_##NAME:; STORE_NODE(ms, FFMAX(16, (AdaptationTable[nibble] * step) >> 8)); } - } else if(version == CODEC_ID_ADPCM_IMA_WAV) { + } else if((version == CODEC_ID_ADPCM_IMA_WAV)|| (version == CODEC_ID_ADPCM_SWF)) { #define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\ const int predictor = nodes[j]->sample1;\ const int div = (sample - predictor) * 4 / STEP_TABLE;\ @@ -440,22 +442,18 @@ static int adpcm_encode_frame(AVCodecContext *avctx, /* n = (BLKSIZE - 4 * avctx->channels) / (2 * 8 * avctx->channels); */ switch(avctx->codec->id) { - case CODEC_ID_ADPCM_IMA_QT: /* XXX: can't test until we get .mov writer */ - break; case CODEC_ID_ADPCM_IMA_WAV: n = avctx->frame_size / 8; c->status[0].prev_sample = (signed short)samples[0]; /* XXX */ /* c->status[0].step_index = 0; *//* XXX: not sure how to init the state machine */ - *dst++ = (c->status[0].prev_sample) & 0xFF; /* little endian */ - *dst++ = (c->status[0].prev_sample >> 8) & 0xFF; + bytestream_put_le16(&dst, c->status[0].prev_sample); *dst++ = (unsigned char)c->status[0].step_index; *dst++ = 0; /* unknown */ samples++; if (avctx->channels == 2) { - c->status[1].prev_sample = (signed short)samples[1]; + c->status[1].prev_sample = (signed short)samples[0]; /* c->status[1].step_index = 0; */ - *dst++ = (c->status[1].prev_sample) & 0xFF; - *dst++ = (c->status[1].prev_sample >> 8) & 0xFF; + bytestream_put_le16(&dst, c->status[1].prev_sample); *dst++ = (unsigned char)c->status[1].step_index; *dst++ = 0; samples++; @@ -481,17 +479,17 @@ static int adpcm_encode_frame(AVCodecContext *avctx, } } else for (; n>0; n--) { - *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]) & 0x0F; - *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels]) << 4) & 0xF0; + *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]); + *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels]) << 4; dst++; - *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]) & 0x0F; - *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4) & 0xF0; + *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]); + *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4; dst++; - *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]) & 0x0F; - *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4) & 0xF0; + *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]); + *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4; dst++; - *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]) & 0x0F; - *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4) & 0xF0; + *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]); + *dst |= adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4; dst++; /* right channel */ if (avctx->channels == 2) { @@ -511,6 +509,46 @@ static int adpcm_encode_frame(AVCodecContext *avctx, samples += 8 * avctx->channels; } break; + case CODEC_ID_ADPCM_SWF: + { + int i; + PutBitContext pb; + init_put_bits(&pb, dst, buf_size*8); + + n = avctx->frame_size-1; + + //Store AdpcmCodeSize + put_bits(&pb, 2, 2); //Set 4bits flash adpcm format + + //Init the encoder state + for(i=0; i<avctx->channels; i++){ + c->status[i].step_index = av_clip(c->status[i].step_index, 0, 63); // clip step so it fits 6 bits + put_bits(&pb, 16, samples[i] & 0xFFFF); + put_bits(&pb, 6, c->status[i].step_index); + c->status[i].prev_sample = (signed short)samples[i]; + } + + if(avctx->trellis > 0) { + uint8_t buf[2][n]; + adpcm_compress_trellis(avctx, samples+2, buf[0], &c->status[0], n); + if (avctx->channels == 2) + adpcm_compress_trellis(avctx, samples+3, buf[1], &c->status[1], n); + for(i=0; i<n; i++) { + put_bits(&pb, 4, buf[0][i]); + if (avctx->channels == 2) + put_bits(&pb, 4, buf[1][i]); + } + } else { + for (i=1; i<avctx->frame_size; i++) { + put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels*i])); + if (avctx->channels == 2) + put_bits(&pb, 4, adpcm_ima_compress_sample(&c->status[1], samples[2*i+1])); + } + } + flush_put_bits(&pb); + dst += put_bits_count(&pb)>>3; + break; + } case CODEC_ID_ADPCM_MS: for(i=0; i<avctx->channels; i++){ int predictor=0; @@ -523,20 +561,17 @@ static int adpcm_encode_frame(AVCodecContext *avctx, if (c->status[i].idelta < 16) c->status[i].idelta = 16; - *dst++ = c->status[i].idelta & 0xFF; - *dst++ = c->status[i].idelta >> 8; + bytestream_put_le16(&dst, c->status[i].idelta); } for(i=0; i<avctx->channels; i++){ c->status[i].sample1= *samples++; - *dst++ = c->status[i].sample1 & 0xFF; - *dst++ = c->status[i].sample1 >> 8; + bytestream_put_le16(&dst, c->status[i].sample1); } for(i=0; i<avctx->channels; i++){ c->status[i].sample2= *samples++; - *dst++ = c->status[i].sample2 & 0xFF; - *dst++ = c->status[i].sample2 >> 8; + bytestream_put_le16(&dst, c->status[i].sample2); } if(avctx->trellis > 0) { @@ -597,20 +632,29 @@ static int adpcm_encode_frame(AVCodecContext *avctx, static int adpcm_decode_init(AVCodecContext * avctx) { ADPCMContext *c = avctx->priv_data; + unsigned int max_channels = 2; - if(avctx->channels > 2U){ + switch(avctx->codec->id) { + case CODEC_ID_ADPCM_EA_R1: + case CODEC_ID_ADPCM_EA_R2: + case CODEC_ID_ADPCM_EA_R3: + max_channels = 6; + break; + } + if(avctx->channels > max_channels){ return -1; } - c->channel = 0; - c->status[0].predictor = c->status[1].predictor = 0; - c->status[0].step_index = c->status[1].step_index = 0; - c->status[0].step = c->status[1].step = 0; - switch(avctx->codec->id) { case CODEC_ID_ADPCM_CT: c->status[0].step = c->status[1].step = 511; break; + case CODEC_ID_ADPCM_IMA_WS: + if (avctx->extradata && avctx->extradata_size == 2 * 4) { + c->status[0].predictor = AV_RL32(avctx->extradata); + c->status[1].predictor = AV_RL32(avctx->extradata + 4); + } + break; default: break; } @@ -638,11 +682,10 @@ static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble, if (sign) predictor -= diff; else predictor += diff; - CLAMP_TO_SHORT(predictor); - c->predictor = predictor; + c->predictor = av_clip_int16(predictor); c->step_index = step_index; - return (short)predictor; + return (short)c->predictor; } static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble) @@ -651,19 +694,17 @@ static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble) predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256; predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta; - CLAMP_TO_SHORT(predictor); c->sample2 = c->sample1; - c->sample1 = predictor; + c->sample1 = av_clip_int16(predictor); c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8; if (c->idelta < 16) c->idelta = 16; - return (short)predictor; + return c->sample1; } static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble) { - int predictor; int sign, delta, diff; int new_step; @@ -673,23 +714,14 @@ static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble) * the reference ADPCM implementation since modern CPUs can do the mults * quickly enough */ diff = ((2 * delta + 1) * c->step) >> 3; - predictor = c->predictor; /* predictor update is not so trivial: predictor is multiplied on 254/256 before updating */ - if(sign) - predictor = ((predictor * 254) >> 8) - diff; - else - predictor = ((predictor * 254) >> 8) + diff; + c->predictor = ((c->predictor * 254) >> 8) + (sign ? -diff : diff); + c->predictor = av_clip_int16(c->predictor); /* calculate new step and clamp it to range 511..32767 */ new_step = (ct_adpcm_table[nibble & 7] * c->step) >> 8; - c->step = new_step; - if(c->step < 511) - c->step = 511; - if(c->step > 32767) - c->step = 32767; - - CLAMP_TO_SHORT(predictor); - c->predictor = predictor; - return (short)predictor; + c->step = av_clip(new_step, 511, 32767); + + return (short)c->predictor; } static inline short adpcm_sbpro_expand_nibble(ADPCMChannelStatus *c, char nibble, int size, int shift) @@ -700,16 +732,8 @@ static inline short adpcm_sbpro_expand_nibble(ADPCMChannelStatus *c, char nibble delta = nibble & ((1<<(size-1))-1); diff = delta << (7 + c->step + shift); - if (sign) - c->predictor -= diff; - else - c->predictor += diff; - /* clamp result */ - if (c->predictor > 16256) - c->predictor = 16256; - else if (c->predictor < -16384) - c->predictor = -16384; + c->predictor = av_clip(c->predictor + (sign ? -diff : diff), -16384,16256); /* calculate new step */ if (delta >= (2*size - 3) && c->step < 3) @@ -728,7 +752,7 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c } c->predictor += (c->step * yamaha_difflookup[nibble]) / 8; - CLAMP_TO_SHORT(c->predictor); + c->predictor = av_clip_int16(c->predictor); c->step = (c->step * yamaha_indexscale[nibble]) >> 8; c->step = av_clip(c->step, 127, 24567); return c->predictor; @@ -757,11 +781,10 @@ static void xa_decode(short *out, const unsigned char *in, t = (signed char)(d<<4)>>4; s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6); - CLAMP_TO_SHORT(s); - *out = s; - out += inc; s_2 = s_1; - s_1 = s; + s_1 = av_clip_int16(s); + *out = s_1; + out += inc; } if (inc==2) { /* stereo */ @@ -783,11 +806,10 @@ static void xa_decode(short *out, const unsigned char *in, t = (signed char)d >> 4; s = ( t<<shift ) + ((s_1*f0 + s_2*f1+32)>>6); - CLAMP_TO_SHORT(s); - *out = s; - out += inc; s_2 = s_1; - s_1 = s; + s_1 = av_clip_int16(s); + *out = s_1; + out += inc; } if (inc==2) { /* stereo */ @@ -819,7 +841,7 @@ static void xa_decode(short *out, const unsigned char *in, static int adpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { ADPCMContext *c = avctx->priv_data; ADPCMChannelStatus *cs; @@ -827,7 +849,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, int block_predictor[2]; short *samples; short *samples_end; - uint8_t *src; + const uint8_t *src; int st; /* stereo */ /* DK3 ADPCM accounting variables */ @@ -877,7 +899,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, if(cs->predictor & 0x8000) cs->predictor -= 0x10000; - CLAMP_TO_SHORT(cs->predictor); + cs->predictor = av_clip_int16(cs->predictor); cs->step_index = (*src++) & 0x7F; @@ -914,11 +936,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, for(i=0; i<avctx->channels; i++){ cs = &(c->status[i]); - cs->predictor = (int16_t)(src[0] + (src[1]<<8)); + cs->predictor = *samples++ = (int16_t)(src[0] + (src[1]<<8)); src+=2; - // XXX: is this correct ??: *samples++ = cs->predictor; - cs->step_index = *src++; if (cs->step_index > 88){ av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", cs->step_index); @@ -1101,8 +1121,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, } break; case CODEC_ID_ADPCM_XA: - c->status[0].sample1 = c->status[0].sample2 = - c->status[1].sample1 = c->status[1].sample2 = 0; while (buf_size >= 128) { xa_decode(samples, src, &c->status[0], &c->status[1], avctx->channels); @@ -1111,6 +1129,30 @@ static int adpcm_decode_frame(AVCodecContext *avctx, buf_size -= 128; } break; + case CODEC_ID_ADPCM_IMA_EA_EACS: + samples_in_chunk = bytestream_get_le32(&src) >> (1-st); + + if (samples_in_chunk > buf_size-4-(8<<st)) { + src += buf_size - 4; + break; + } + + for (i=0; i<=st; i++) + c->status[i].step_index = bytestream_get_le32(&src); + for (i=0; i<=st; i++) + c->status[i].predictor = bytestream_get_le32(&src); + + for (; samples_in_chunk; samples_in_chunk--, src++) { + *samples++ = adpcm_ima_expand_nibble(&c->status[0], *src>>4, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F, 3); + } + break; + case CODEC_ID_ADPCM_IMA_EA_SEAD: + for (; src < buf+buf_size; src++) { + *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4, 6); + *samples++ = adpcm_ima_expand_nibble(&c->status[st],src[0]&0x0F, 6); + } + break; case CODEC_ID_ADPCM_EA: samples_in_chunk = AV_RL32(src); if (samples_in_chunk >= ((buf_size - 12) * 2)) { @@ -1149,28 +1191,147 @@ static int adpcm_decode_frame(AVCodecContext *avctx, next_right_sample = (next_right_sample + (current_right_sample * coeff1r) + (previous_right_sample * coeff2r) + 0x80) >> 8; - CLAMP_TO_SHORT(next_left_sample); - CLAMP_TO_SHORT(next_right_sample); previous_left_sample = current_left_sample; - current_left_sample = next_left_sample; + current_left_sample = av_clip_int16(next_left_sample); previous_right_sample = current_right_sample; - current_right_sample = next_right_sample; + current_right_sample = av_clip_int16(next_right_sample); *samples++ = (unsigned short)current_left_sample; *samples++ = (unsigned short)current_right_sample; } } break; + case CODEC_ID_ADPCM_EA_R1: + case CODEC_ID_ADPCM_EA_R2: + case CODEC_ID_ADPCM_EA_R3: { + /* channel numbering + 2chan: 0=fl, 1=fr + 4chan: 0=fl, 1=rl, 2=fr, 3=rr + 6chan: 0=fl, 1=c, 2=fr, 3=rl, 4=rr, 5=sub */ + const int big_endian = avctx->codec->id == CODEC_ID_ADPCM_EA_R3; + int32_t previous_sample, current_sample, next_sample; + int32_t coeff1, coeff2; + uint8_t shift; + unsigned int channel; + uint16_t *samplesC; + const uint8_t *srcC; + + samples_in_chunk = (big_endian ? bytestream_get_be32(&src) + : bytestream_get_le32(&src)) / 28; + if (samples_in_chunk > UINT32_MAX/(28*avctx->channels) || + 28*samples_in_chunk*avctx->channels > samples_end-samples) { + src += buf_size - 4; + break; + } + + for (channel=0; channel<avctx->channels; channel++) { + srcC = src + (big_endian ? bytestream_get_be32(&src) + : bytestream_get_le32(&src)) + + (avctx->channels-channel-1) * 4; + samplesC = samples + channel; + + if (avctx->codec->id == CODEC_ID_ADPCM_EA_R1) { + current_sample = (int16_t)bytestream_get_le16(&srcC); + previous_sample = (int16_t)bytestream_get_le16(&srcC); + } else { + current_sample = c->status[channel].predictor; + previous_sample = c->status[channel].prev_sample; + } + + for (count1=0; count1<samples_in_chunk; count1++) { + if (*srcC == 0xEE) { /* only seen in R2 and R3 */ + srcC++; + current_sample = (int16_t)bytestream_get_be16(&srcC); + previous_sample = (int16_t)bytestream_get_be16(&srcC); + + for (count2=0; count2<28; count2++) { + *samplesC = (int16_t)bytestream_get_be16(&srcC); + samplesC += avctx->channels; + } + } else { + coeff1 = ea_adpcm_table[ (*srcC>>4) & 0x0F ]; + coeff2 = ea_adpcm_table[((*srcC>>4) & 0x0F) + 4]; + shift = (*srcC++ & 0x0F) + 8; + + for (count2=0; count2<28; count2++) { + if (count2 & 1) + next_sample = ((*srcC++ & 0x0F) << 28) >> shift; + else + next_sample = ((*srcC & 0xF0) << 24) >> shift; + + next_sample += (current_sample * coeff1) + + (previous_sample * coeff2); + next_sample = av_clip_int16(next_sample >> 8); + + previous_sample = current_sample; + current_sample = next_sample; + *samplesC = current_sample; + samplesC += avctx->channels; + } + } + } + + if (avctx->codec->id != CODEC_ID_ADPCM_EA_R1) { + c->status[channel].predictor = current_sample; + c->status[channel].prev_sample = previous_sample; + } + } + + src = src + buf_size - (4 + 4*avctx->channels); + samples += 28 * samples_in_chunk * avctx->channels; + break; + } + case CODEC_ID_ADPCM_EA_XAS: + if (samples_end-samples < 32*4*avctx->channels + || buf_size < (4+15)*4*avctx->channels) { + src += buf_size; + break; + } + for (channel=0; channel<avctx->channels; channel++) { + int coeff[2][4], shift[4]; + short *s2, *s = &samples[channel]; + for (n=0; n<4; n++, s+=32*avctx->channels) { + for (i=0; i<2; i++) + coeff[i][n] = ea_adpcm_table[(src[0]&0x0F)+4*i]; + shift[n] = (src[2]&0x0F) + 8; + for (s2=s, i=0; i<2; i++, src+=2, s2+=avctx->channels) + s2[0] = (src[0]&0xF0) + (src[1]<<8); + } + + for (m=2; m<32; m+=2) { + s = &samples[m*avctx->channels + channel]; + for (n=0; n<4; n++, src++, s+=32*avctx->channels) { + for (s2=s, i=0; i<8; i+=4, s2+=avctx->channels) { + int level = ((*src & (0xF0>>i)) << (24+i)) >> shift[n]; + int pred = s2[-1*avctx->channels] * coeff[0][n] + + s2[-2*avctx->channels] * coeff[1][n]; + s2[0] = av_clip_int16((level + pred + 0x80) >> 8); + } + } + } + } + samples += 32*4*avctx->channels; + break; + case CODEC_ID_ADPCM_IMA_AMV: case CODEC_ID_ADPCM_IMA_SMJPEG: - c->status[0].predictor = *src; - src += 2; - c->status[0].step_index = *src++; - src++; /* skip another byte before getting to the meat */ + c->status[0].predictor = (int16_t)bytestream_get_le16(&src); + c->status[0].step_index = bytestream_get_le16(&src); + + if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV) + src+=4; + while (src < buf + buf_size) { + char hi, lo; + lo = *src & 0x0F; + hi = (*src >> 4) & 0x0F; + + if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV) + FFSWAP(char, hi, lo); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], - *src & 0x0F, 3); + lo, 3); *samples++ = adpcm_ima_expand_nibble(&c->status[0], - (*src >> 4) & 0x0F, 3); + hi, 3); src++; } break; @@ -1236,56 +1397,57 @@ static int adpcm_decode_frame(AVCodecContext *avctx, { GetBitContext gb; const int *table; - int k0, signmask, nb_bits; + int k0, signmask, nb_bits, count; int size = buf_size*8; init_get_bits(&gb, buf, size); - //read bits & inital values + //read bits & initial values nb_bits = get_bits(&gb, 2)+2; //av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", nb_bits); table = swf_index_tables[nb_bits-2]; k0 = 1 << (nb_bits-2); signmask = 1 << (nb_bits-1); - for (i = 0; i < avctx->channels; i++) { - *samples++ = c->status[i].predictor = get_sbits(&gb, 16); - c->status[i].step_index = get_bits(&gb, 6); - } - - while (get_bits_count(&gb) < size) - { - int i; - + while (get_bits_count(&gb) <= size - 22*avctx->channels) { for (i = 0; i < avctx->channels; i++) { - // similar to IMA adpcm - int delta = get_bits(&gb, nb_bits); - int step = step_table[c->status[i].step_index]; - long vpdiff = 0; // vpdiff = (delta+0.5)*step/4 - int k = k0; - - do { - if (delta & k) - vpdiff += step; - step >>= 1; - k >>= 1; - } while(k); - vpdiff += step; - - if (delta & signmask) - c->status[i].predictor -= vpdiff; - else - c->status[i].predictor += vpdiff; - - c->status[i].step_index += table[delta & (~signmask)]; - - c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88); - c->status[i].predictor = av_clip(c->status[i].predictor, -32768, 32767); - - *samples++ = c->status[i].predictor; - if (samples >= samples_end) { - av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n"); - return -1; + *samples++ = c->status[i].predictor = get_sbits(&gb, 16); + c->status[i].step_index = get_bits(&gb, 6); + } + + for (count = 0; get_bits_count(&gb) <= size - nb_bits*avctx->channels && count < 4095; count++) { + int i; + + for (i = 0; i < avctx->channels; i++) { + // similar to IMA adpcm + int delta = get_bits(&gb, nb_bits); + int step = step_table[c->status[i].step_index]; + long vpdiff = 0; // vpdiff = (delta+0.5)*step/4 + int k = k0; + + do { + if (delta & k) + vpdiff += step; + step >>= 1; + k >>= 1; + } while(k); + vpdiff += step; + + if (delta & signmask) + c->status[i].predictor -= vpdiff; + else + c->status[i].predictor += vpdiff; + + c->status[i].step_index += table[delta & (~signmask)]; + + c->status[i].step_index = av_clip(c->status[i].step_index, 0, 88); + c->status[i].predictor = av_clip_int16(c->status[i].predictor); + + *samples++ = c->status[i].predictor; + if (samples >= samples_end) { + av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n"); + return -1; + } } } } @@ -1308,6 +1470,68 @@ static int adpcm_decode_frame(AVCodecContext *avctx, src++; } break; + case CODEC_ID_ADPCM_THP: + { + int table[2][16]; + unsigned int samplecnt; + int prev[2][2]; + int ch; + + if (buf_size < 80) { + av_log(avctx, AV_LOG_ERROR, "frame too small\n"); + return -1; + } + + src+=4; + samplecnt = bytestream_get_be32(&src); + + for (i = 0; i < 32; i++) + table[0][i] = (int16_t)bytestream_get_be16(&src); + + /* Initialize the previous sample. */ + for (i = 0; i < 4; i++) + prev[0][i] = (int16_t)bytestream_get_be16(&src); + + if (samplecnt >= (samples_end - samples) / (st + 1)) { + av_log(avctx, AV_LOG_ERROR, "allocated output buffer is too small\n"); + return -1; + } + + for (ch = 0; ch <= st; ch++) { + samples = (unsigned short *) data + ch; + + /* Read in every sample for this channel. */ + for (i = 0; i < samplecnt / 14; i++) { + int index = (*src >> 4) & 7; + unsigned int exp = 28 - (*src++ & 15); + int factor1 = table[ch][index * 2]; + int factor2 = table[ch][index * 2 + 1]; + + /* Decode 14 samples. */ + for (n = 0; n < 14; n++) { + int32_t sampledat; + if(n&1) sampledat= *src++ <<28; + else sampledat= (*src&0xF0)<<24; + + sampledat = ((prev[ch][0]*factor1 + + prev[ch][1]*factor2) >> 11) + (sampledat>>exp); + *samples = av_clip_int16(sampledat); + prev[ch][1] = prev[ch][0]; + prev[ch][0] = *samples++; + + /* In case of stereo, skip one sample, this sample + is for the other channel. */ + samples += st; + } + } + } + + /* In the previous loop, in case stereo is used, samples is + increased exactly one time too often. */ + samples -= st; + break; + } + default: return -1; } @@ -1352,21 +1576,27 @@ AVCodec name ## _decoder = { \ #define ADPCM_CODEC(id, name) \ ADPCM_ENCODER(id,name) ADPCM_DECODER(id,name) -ADPCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); -ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); -ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); -ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); -ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws); -ADPCM_CODEC(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); -ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); -ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); -ADPCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); -ADPCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); -ADPCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct); -ADPCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf); -ADPCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); -ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4); -ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3); -ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2); - -#undef ADPCM_CODEC +ADPCM_DECODER(CODEC_ID_ADPCM_4XM, adpcm_4xm); +ADPCM_DECODER(CODEC_ID_ADPCM_CT, adpcm_ct); +ADPCM_DECODER(CODEC_ID_ADPCM_EA, adpcm_ea); +ADPCM_DECODER(CODEC_ID_ADPCM_EA_R1, adpcm_ea_r1); +ADPCM_DECODER(CODEC_ID_ADPCM_EA_R2, adpcm_ea_r2); +ADPCM_DECODER(CODEC_ID_ADPCM_EA_R3, adpcm_ea_r3); +ADPCM_DECODER(CODEC_ID_ADPCM_EA_XAS, adpcm_ea_xas); +ADPCM_DECODER(CODEC_ID_ADPCM_IMA_AMV, adpcm_ima_amv); +ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); +ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); +ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs); +ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead); +ADPCM_DECODER(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); +ADPCM_DECODER(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); +ADPCM_CODEC (CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); +ADPCM_DECODER(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws); +ADPCM_CODEC (CODEC_ID_ADPCM_MS, adpcm_ms); +ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4); +ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3); +ADPCM_DECODER(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2); +ADPCM_CODEC (CODEC_ID_ADPCM_SWF, adpcm_swf); +ADPCM_DECODER(CODEC_ID_ADPCM_THP, adpcm_thp); +ADPCM_DECODER(CODEC_ID_ADPCM_XA, adpcm_xa); +ADPCM_CODEC (CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); diff --git a/contrib/ffmpeg/libavcodec/adx.c b/contrib/ffmpeg/libavcodec/adx.c deleted file mode 100644 index b449c9124..000000000 --- a/contrib/ffmpeg/libavcodec/adx.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * ADX ADPCM codecs - * Copyright (c) 2001,2003 BERO - * - * 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" - -/** - * @file adx.c - * SEGA CRI adx codecs. - * - * Reference documents: - * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html - * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ - */ - -typedef struct { - int s1,s2; -} PREV; - -typedef struct { - PREV prev[2]; - int header_parsed; - unsigned char dec_temp[18*2]; - unsigned short enc_temp[32*2]; - int in_temp; -} ADXContext; - -//#define BASEVOL 0x11e0 -#define BASEVOL 0x4000 -#define SCALE1 0x7298 -#define SCALE2 0x3350 - -#define CLIP(s) if (s>32767) s=32767; else if (s<-32768) s=-32768 - -/* 18 bytes <-> 32 samples */ - -#ifdef CONFIG_ENCODERS -static void adx_encode(unsigned char *adx,const short *wav,PREV *prev) -{ - int scale; - int i; - int s0,s1,s2,d; - int max=0; - int min=0; - int data[32]; - - s1 = prev->s1; - s2 = prev->s2; - for(i=0;i<32;i++) { - s0 = wav[i]; - d = ((s0<<14) - SCALE1*s1 + SCALE2*s2)/BASEVOL; - data[i]=d; - if (max<d) max=d; - if (min>d) min=d; - s2 = s1; - s1 = s0; - } - prev->s1 = s1; - prev->s2 = s2; - - /* -8..+7 */ - - if (max==0 && min==0) { - memset(adx,0,18); - return; - } - - if (max/7>-min/8) scale = max/7; - else scale = -min/8; - - if (scale==0) scale=1; - - adx[0] = scale>>8; - adx[1] = scale; - - for(i=0;i<16;i++) { - adx[i+2] = ((data[i*2]/scale)<<4) | ((data[i*2+1]/scale)&0xf); - } -} -#endif //CONFIG_ENCODERS - -static void adx_decode(short *out,const unsigned char *in,PREV *prev) -{ - int scale = ((in[0]<<8)|(in[1])); - int i; - int s0,s1,s2,d; - -// printf("%x ",scale); - - in+=2; - s1 = prev->s1; - s2 = prev->s2; - for(i=0;i<16;i++) { - d = in[i]; - // d>>=4; if (d&8) d-=16; - d = ((signed char)d >> 4); - s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; - CLIP(s0); - *out++=s0; - s2 = s1; - s1 = s0; - - d = in[i]; - //d&=15; if (d&8) d-=16; - d = ((signed char)(d<<4) >> 4); - s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; - CLIP(s0); - *out++=s0; - s2 = s1; - s1 = s0; - } - prev->s1 = s1; - prev->s2 = s2; - -} - -static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev) -{ - short tmp[32*2]; - int i; - - adx_decode(tmp ,in ,prev); - adx_decode(tmp+32,in+18,prev+1); - for(i=0;i<32;i++) { - out[i*2] = tmp[i]; - out[i*2+1] = tmp[i+32]; - } -} - -#ifdef CONFIG_ENCODERS - -static void write_long(unsigned char *p,uint32_t v) -{ - p[0] = v>>24; - p[1] = v>>16; - p[2] = v>>8; - p[3] = v; -} - -static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize) -{ -#if 0 - struct { - uint32_t offset; /* 0x80000000 + sample start - 4 */ - unsigned char unknown1[3]; /* 03 12 04 */ - unsigned char channel; /* 1 or 2 */ - uint32_t freq; - uint32_t size; - uint32_t unknown2; /* 01 f4 03 00 */ - uint32_t unknown3; /* 00 00 00 00 */ - uint32_t unknown4; /* 00 00 00 00 */ - - /* if loop - unknown3 00 15 00 01 - unknown4 00 00 00 01 - long loop_start_sample; - long loop_start_byte; - long loop_end_sample; - long loop_end_byte; - long - */ - } adxhdr; /* big endian */ - /* offset-6 "(c)CRI" */ -#endif - write_long(buf+0x00,0x80000000|0x20); - write_long(buf+0x04,0x03120400|avctx->channels); - write_long(buf+0x08,avctx->sample_rate); - write_long(buf+0x0c,0); /* FIXME: set after */ - write_long(buf+0x10,0x01040300); - write_long(buf+0x14,0x00000000); - write_long(buf+0x18,0x00000000); - memcpy(buf+0x1c,"\0\0(c)CRI",8); - return 0x20+4; -} - -static int adx_decode_init(AVCodecContext *avctx); -static int adx_encode_init(AVCodecContext *avctx) -{ - if (avctx->channels > 2) - return -1; /* only stereo or mono =) */ - avctx->frame_size = 32; - - avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; - -// avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; - - av_log(avctx, AV_LOG_DEBUG, "adx encode init\n"); - adx_decode_init(avctx); - - return 0; -} - -static int adx_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - - return 0; -} - -static int adx_encode_frame(AVCodecContext *avctx, - uint8_t *frame, int buf_size, void *data) -{ - ADXContext *c = avctx->priv_data; - const short *samples = data; - unsigned char *dst = frame; - int rest = avctx->frame_size; - -/* - input data size = - ffmpeg.c: do_audio_out() - frame_bytes = enc->frame_size * 2 * enc->channels; -*/ - -// printf("sz=%d ",buf_size); fflush(stdout); - if (!c->header_parsed) { - int hdrsize = adx_encode_header(avctx,dst,buf_size); - dst+=hdrsize; - c->header_parsed = 1; - } - - if (avctx->channels==1) { - while(rest>=32) { - adx_encode(dst,samples,c->prev); - dst+=18; - samples+=32; - rest-=32; - } - } else { - while(rest>=32*2) { - short tmpbuf[32*2]; - int i; - - for(i=0;i<32;i++) { - tmpbuf[i] = samples[i*2]; - tmpbuf[i+32] = samples[i*2+1]; - } - - adx_encode(dst,tmpbuf,c->prev); - adx_encode(dst+18,tmpbuf+32,c->prev+1); - dst+=18*2; - samples+=32*2; - rest-=32*2; - } - } - return dst-frame; -} - -#endif //CONFIG_ENCODERS - -static uint32_t read_long(const unsigned char *p) -{ - return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; -} - -static int is_adx(const unsigned char *buf,size_t bufsize) -{ - int offset; - - if (buf[0]!=0x80) return 0; - offset = (read_long(buf)^0x80000000)+4; - if (bufsize<offset || memcmp(buf+offset-6,"(c)CRI",6)) return 0; - return offset; -} - -/* return data offset or 6 */ -static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize) -{ - int offset; - int channels,freq,size; - - offset = is_adx(buf,bufsize); - if (offset==0) return 0; - - channels = buf[7]; - freq = read_long(buf+8); - size = read_long(buf+12); - -// printf("freq=%d ch=%d\n",freq,channels); - - avctx->sample_rate = freq; - avctx->channels = channels; - avctx->bit_rate = freq*channels*18*8/32; -// avctx->frame_size = 18*channels; - - return offset; -} - -static int adx_decode_init(AVCodecContext * avctx) -{ - ADXContext *c = avctx->priv_data; - -// printf("adx_decode_init\n"); fflush(stdout); - c->prev[0].s1 = 0; - c->prev[0].s2 = 0; - c->prev[1].s1 = 0; - c->prev[1].s2 = 0; - c->header_parsed = 0; - c->in_temp = 0; - return 0; -} - -#if 0 -static void dump(unsigned char *buf,size_t len) -{ - int i; - for(i=0;i<len;i++) { - if ((i&15)==0) av_log(NULL, AV_LOG_DEBUG, "%04x ",i); - av_log(NULL, AV_LOG_DEBUG, "%02x ",buf[i]); - if ((i&15)==15) av_log(NULL, AV_LOG_DEBUG, "\n"); - } - av_log(NULL, AV_LOG_ERROR, "\n"); -} -#endif - -static int adx_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf0, int buf_size) -{ - ADXContext *c = avctx->priv_data; - short *samples = data; - const uint8_t *buf = buf0; - int rest = buf_size; - - if (!c->header_parsed) { - int hdrsize = adx_decode_header(avctx,buf,rest); - if (hdrsize==0) return -1; - c->header_parsed = 1; - buf += hdrsize; - rest -= hdrsize; - } - - if (c->in_temp) { - int copysize = 18*avctx->channels - c->in_temp; - memcpy(c->dec_temp+c->in_temp,buf,copysize); - rest -= copysize; - buf += copysize; - if (avctx->channels==1) { - adx_decode(samples,c->dec_temp,c->prev); - samples += 32; - } else { - adx_decode_stereo(samples,c->dec_temp,c->prev); - samples += 32*2; - } - } - // - if (avctx->channels==1) { - while(rest>=18) { - adx_decode(samples,buf,c->prev); - rest-=18; - buf+=18; - samples+=32; - } - } else { - while(rest>=18*2) { - adx_decode_stereo(samples,buf,c->prev); - rest-=18*2; - buf+=18*2; - samples+=32*2; - } - } - // - c->in_temp = rest; - if (rest) { - memcpy(c->dec_temp,buf,rest); - buf+=rest; - } - *data_size = (uint8_t*)samples - (uint8_t*)data; -// printf("%d:%d ",buf-buf0,*data_size); fflush(stdout); - return buf-buf0; -} - -#ifdef CONFIG_ENCODERS -AVCodec adpcm_adx_encoder = { - "adpcm_adx", - CODEC_TYPE_AUDIO, - CODEC_ID_ADPCM_ADX, - sizeof(ADXContext), - adx_encode_init, - adx_encode_frame, - adx_encode_close, - NULL, -}; -#endif //CONFIG_ENCODERS - -AVCodec adpcm_adx_decoder = { - "adpcm_adx", - CODEC_TYPE_AUDIO, - CODEC_ID_ADPCM_ADX, - sizeof(ADXContext), - adx_decode_init, - NULL, - NULL, - adx_decode_frame, -}; - diff --git a/contrib/ffmpeg/libavcodec/adx.h b/contrib/ffmpeg/libavcodec/adx.h new file mode 100644 index 000000000..16180372a --- /dev/null +++ b/contrib/ffmpeg/libavcodec/adx.h @@ -0,0 +1,49 @@ +/* + * ADX ADPCM codecs + * Copyright (c) 2001,2003 BERO + * + * 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 adx.h + * SEGA CRI adx codecs. + * + * Reference documents: + * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html + * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ + */ + +#ifndef FFMPEG_ADX_H +#define FFMPEG_ADX_H + +typedef struct { + int s1,s2; +} PREV; + +typedef struct { + PREV prev[2]; + int header_parsed; + unsigned char dec_temp[18*2]; + int in_temp; +} ADXContext; + +#define BASEVOL 0x4000 +#define SCALE1 0x7298 +#define SCALE2 0x3350 + +#endif /* FFMPEG_ADX_H */ diff --git a/contrib/ffmpeg/libavcodec/adxdec.c b/contrib/ffmpeg/libavcodec/adxdec.c new file mode 100644 index 000000000..851badbee --- /dev/null +++ b/contrib/ffmpeg/libavcodec/adxdec.c @@ -0,0 +1,169 @@ +/* + * ADX ADPCM codecs + * Copyright (c) 2001,2003 BERO + * + * 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" +#include "adx.h" + +/** + * @file adx.c + * SEGA CRI adx codecs. + * + * Reference documents: + * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html + * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ + */ + +/* 18 bytes <-> 32 samples */ + +static void adx_decode(short *out,const unsigned char *in,PREV *prev) +{ + int scale = AV_RB16(in); + int i; + int s0,s1,s2,d; + +// printf("%x ",scale); + + in+=2; + s1 = prev->s1; + s2 = prev->s2; + for(i=0;i<16;i++) { + d = in[i]; + // d>>=4; if (d&8) d-=16; + d = ((signed char)d >> 4); + s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; + s2 = s1; + s1 = av_clip_int16(s0); + *out++=s1; + + d = in[i]; + //d&=15; if (d&8) d-=16; + d = ((signed char)(d<<4) >> 4); + s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; + s2 = s1; + s1 = av_clip_int16(s0); + *out++=s1; + } + prev->s1 = s1; + prev->s2 = s2; + +} + +static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev) +{ + short tmp[32*2]; + int i; + + adx_decode(tmp ,in ,prev); + adx_decode(tmp+32,in+18,prev+1); + for(i=0;i<32;i++) { + out[i*2] = tmp[i]; + out[i*2+1] = tmp[i+32]; + } +} + +/* return data offset or 0 */ +static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize) +{ + int offset; + + if (buf[0]!=0x80) return 0; + offset = (AV_RB32(buf)^0x80000000)+4; + if (bufsize<offset || memcmp(buf+offset-6,"(c)CRI",6)) return 0; + + avctx->channels = buf[7]; + avctx->sample_rate = AV_RB32(buf+8); + avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; + + return offset; +} + +static int adx_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf0, int buf_size) +{ + ADXContext *c = avctx->priv_data; + short *samples = data; + const uint8_t *buf = buf0; + int rest = buf_size; + + if (!c->header_parsed) { + int hdrsize = adx_decode_header(avctx,buf,rest); + if (hdrsize==0) return -1; + c->header_parsed = 1; + buf += hdrsize; + rest -= hdrsize; + } + + /* 18 bytes of data are expanded into 32*2 bytes of audio, + so guard against buffer overflows */ + if(rest/18 > *data_size/64) + rest = (*data_size/64) * 18; + + if (c->in_temp) { + int copysize = 18*avctx->channels - c->in_temp; + memcpy(c->dec_temp+c->in_temp,buf,copysize); + rest -= copysize; + buf += copysize; + if (avctx->channels==1) { + adx_decode(samples,c->dec_temp,c->prev); + samples += 32; + } else { + adx_decode_stereo(samples,c->dec_temp,c->prev); + samples += 32*2; + } + } + // + if (avctx->channels==1) { + while(rest>=18) { + adx_decode(samples,buf,c->prev); + rest-=18; + buf+=18; + samples+=32; + } + } else { + while(rest>=18*2) { + adx_decode_stereo(samples,buf,c->prev); + rest-=18*2; + buf+=18*2; + samples+=32*2; + } + } + // + c->in_temp = rest; + if (rest) { + memcpy(c->dec_temp,buf,rest); + buf+=rest; + } + *data_size = (uint8_t*)samples - (uint8_t*)data; +// printf("%d:%d ",buf-buf0,*data_size); fflush(stdout); + return buf-buf0; +} + +AVCodec adpcm_adx_decoder = { + "adpcm_adx", + CODEC_TYPE_AUDIO, + CODEC_ID_ADPCM_ADX, + sizeof(ADXContext), + NULL, + NULL, + NULL, + adx_decode_frame, +}; + diff --git a/contrib/ffmpeg/libavcodec/adxenc.c b/contrib/ffmpeg/libavcodec/adxenc.c new file mode 100644 index 000000000..4c3d74e3b --- /dev/null +++ b/contrib/ffmpeg/libavcodec/adxenc.c @@ -0,0 +1,193 @@ +/* + * ADX ADPCM codecs + * Copyright (c) 2001,2003 BERO + * + * 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" +#include "adx.h" + +/** + * @file adx.c + * SEGA CRI adx codecs. + * + * Reference documents: + * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html + * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ + */ + +/* 18 bytes <-> 32 samples */ + +static void adx_encode(unsigned char *adx,const short *wav,PREV *prev) +{ + int scale; + int i; + int s0,s1,s2,d; + int max=0; + int min=0; + int data[32]; + + s1 = prev->s1; + s2 = prev->s2; + for(i=0;i<32;i++) { + s0 = wav[i]; + d = ((s0<<14) - SCALE1*s1 + SCALE2*s2)/BASEVOL; + data[i]=d; + if (max<d) max=d; + if (min>d) min=d; + s2 = s1; + s1 = s0; + } + prev->s1 = s1; + prev->s2 = s2; + + /* -8..+7 */ + + if (max==0 && min==0) { + memset(adx,0,18); + return; + } + + if (max/7>-min/8) scale = max/7; + else scale = -min/8; + + if (scale==0) scale=1; + + AV_WB16(adx, scale); + + for(i=0;i<16;i++) { + adx[i+2] = ((data[i*2]/scale)<<4) | ((data[i*2+1]/scale)&0xf); + } +} + +static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize) +{ +#if 0 + struct { + uint32_t offset; /* 0x80000000 + sample start - 4 */ + unsigned char unknown1[3]; /* 03 12 04 */ + unsigned char channel; /* 1 or 2 */ + uint32_t freq; + uint32_t size; + uint32_t unknown2; /* 01 f4 03 00 */ + uint32_t unknown3; /* 00 00 00 00 */ + uint32_t unknown4; /* 00 00 00 00 */ + + /* if loop + unknown3 00 15 00 01 + unknown4 00 00 00 01 + long loop_start_sample; + long loop_start_byte; + long loop_end_sample; + long loop_end_byte; + long + */ + } adxhdr; /* big endian */ + /* offset-6 "(c)CRI" */ +#endif + AV_WB32(buf+0x00,0x80000000|0x20); + AV_WB32(buf+0x04,0x03120400|avctx->channels); + AV_WB32(buf+0x08,avctx->sample_rate); + AV_WB32(buf+0x0c,0); /* FIXME: set after */ + AV_WB32(buf+0x10,0x01040300); + AV_WB32(buf+0x14,0x00000000); + AV_WB32(buf+0x18,0x00000000); + memcpy(buf+0x1c,"\0\0(c)CRI",8); + return 0x20+4; +} + +static int adx_encode_init(AVCodecContext *avctx) +{ + if (avctx->channels > 2) + return -1; /* only stereo or mono =) */ + avctx->frame_size = 32; + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + +// avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; + + av_log(avctx, AV_LOG_DEBUG, "adx encode init\n"); + + return 0; +} + +static int adx_encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + + return 0; +} + +static int adx_encode_frame(AVCodecContext *avctx, + uint8_t *frame, int buf_size, void *data) +{ + ADXContext *c = avctx->priv_data; + const short *samples = data; + unsigned char *dst = frame; + int rest = avctx->frame_size; + +/* + input data size = + ffmpeg.c: do_audio_out() + frame_bytes = enc->frame_size * 2 * enc->channels; +*/ + +// printf("sz=%d ",buf_size); fflush(stdout); + if (!c->header_parsed) { + int hdrsize = adx_encode_header(avctx,dst,buf_size); + dst+=hdrsize; + c->header_parsed = 1; + } + + if (avctx->channels==1) { + while(rest>=32) { + adx_encode(dst,samples,c->prev); + dst+=18; + samples+=32; + rest-=32; + } + } else { + while(rest>=32*2) { + short tmpbuf[32*2]; + int i; + + for(i=0;i<32;i++) { + tmpbuf[i] = samples[i*2]; + tmpbuf[i+32] = samples[i*2+1]; + } + + adx_encode(dst,tmpbuf,c->prev); + adx_encode(dst+18,tmpbuf+32,c->prev+1); + dst+=18*2; + samples+=32*2; + rest-=32*2; + } + } + return dst-frame; +} + +AVCodec adpcm_adx_encoder = { + "adpcm_adx", + CODEC_TYPE_AUDIO, + CODEC_ID_ADPCM_ADX, + sizeof(ADXContext), + adx_encode_init, + adx_encode_frame, + adx_encode_close, + NULL, +}; diff --git a/contrib/ffmpeg/libavcodec/alac.c b/contrib/ffmpeg/libavcodec/alac.c index cc87c81e5..0689a46ef 100644 --- a/contrib/ffmpeg/libavcodec/alac.c +++ b/contrib/ffmpeg/libavcodec/alac.c @@ -1,7 +1,6 @@ /* * ALAC (Apple Lossless Audio Codec) decoder * Copyright (c) 2005 David Hammerton - * All rights reserved. * * This file is part of FFmpeg. * @@ -55,8 +54,11 @@ #include "avcodec.h" #include "bitstream.h" +#include "bytestream.h" +#include "unary.h" #define ALAC_EXTRADATA_SIZE 36 +#define MAX_CHANNELS 2 typedef struct { @@ -71,11 +73,9 @@ typedef struct { int bytespersample; /* buffers */ - int32_t *predicterror_buffer_a; - int32_t *predicterror_buffer_b; + int32_t *predicterror_buffer[MAX_CHANNELS]; - int32_t *outputsamples_buffer_a; - int32_t *outputsamples_buffer_b; + int32_t *outputsamples_buffer[MAX_CHANNELS]; /* stuff from setinfo */ uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */ @@ -86,8 +86,8 @@ typedef struct { uint8_t setinfo_rice_kmodifier; /* 0x0e */ uint8_t setinfo_7f; /* 0x02 */ uint16_t setinfo_80; /* 0x00ff */ - uint32_t setinfo_82; /* 0x000020e7 */ - uint32_t setinfo_86; /* 0x00069fe4 */ + uint32_t setinfo_82; /* 0x000020e7 */ /* max sample size?? */ + uint32_t setinfo_86; /* 0x00069fe4 */ /* bit rate (average)?? */ uint32_t setinfo_8a_rate; /* 0x0000ac44 */ /* end setinfo stuff */ @@ -95,16 +95,19 @@ typedef struct { static void allocate_buffers(ALACContext *alac) { - alac->predicterror_buffer_a = av_malloc(alac->setinfo_max_samples_per_frame * 4); - alac->predicterror_buffer_b = av_malloc(alac->setinfo_max_samples_per_frame * 4); + int chan; + for (chan = 0; chan < MAX_CHANNELS; chan++) { + alac->predicterror_buffer[chan] = + av_malloc(alac->setinfo_max_samples_per_frame * 4); - alac->outputsamples_buffer_a = av_malloc(alac->setinfo_max_samples_per_frame * 4); - alac->outputsamples_buffer_b = av_malloc(alac->setinfo_max_samples_per_frame * 4); + alac->outputsamples_buffer[chan] = + av_malloc(alac->setinfo_max_samples_per_frame * 4); + } } static int alac_set_info(ALACContext *alac) { - unsigned char *ptr = alac->avctx->extradata; + const unsigned char *ptr = alac->avctx->extradata; ptr += 4; /* size */ ptr += 4; /* alac */ @@ -114,39 +117,32 @@ static int alac_set_info(ALACContext *alac) av_log(alac->avctx, AV_LOG_ERROR, "setinfo_max_samples_per_frame too large\n"); return -1; } - alac->setinfo_max_samples_per_frame = AV_RB32(ptr); /* buffer size / 2 ? */ - ptr += 4; - alac->setinfo_7a = *ptr++; - alac->setinfo_sample_size = *ptr++; - alac->setinfo_rice_historymult = *ptr++; - alac->setinfo_rice_initialhistory = *ptr++; - alac->setinfo_rice_kmodifier = *ptr++; - alac->setinfo_7f = *ptr++; // channels? - alac->setinfo_80 = AV_RB16(ptr); - ptr += 2; - alac->setinfo_82 = AV_RB32(ptr); // max coded frame size - ptr += 4; - alac->setinfo_86 = AV_RB32(ptr); // bitrate ? - ptr += 4; - alac->setinfo_8a_rate = AV_RB32(ptr); // samplerate - ptr += 4; + + /* buffer size / 2 ? */ + alac->setinfo_max_samples_per_frame = bytestream_get_be32(&ptr); + alac->setinfo_7a = *ptr++; + alac->setinfo_sample_size = *ptr++; + alac->setinfo_rice_historymult = *ptr++; + alac->setinfo_rice_initialhistory = *ptr++; + alac->setinfo_rice_kmodifier = *ptr++; + /* channels? */ + alac->setinfo_7f = *ptr++; + alac->setinfo_80 = bytestream_get_be16(&ptr); + /* max coded frame size */ + alac->setinfo_82 = bytestream_get_be32(&ptr); + /* bitrate ? */ + alac->setinfo_86 = bytestream_get_be32(&ptr); + /* samplerate */ + alac->setinfo_8a_rate = bytestream_get_be32(&ptr); allocate_buffers(alac); return 0; } -/* hideously inefficient. could use a bitmask search, - * alternatively bsr on x86, - */ -static int count_leading_zeros(int32_t input) +static inline int count_leading_zeros(int32_t input) { - int i = 0; - while (!(0x80000000 & input) && i < 32) { - i++; - input = input << 1; - } - return i; + return 31-av_log2(input); } static void bastardized_rice_decompress(ALACContext *alac, @@ -164,18 +160,15 @@ static void bastardized_rice_decompress(ALACContext *alac, int sign_modifier = 0; for (output_count = 0; output_count < output_size; output_count++) { - int32_t x = 0; + int32_t x; int32_t x_modified; int32_t final_val; /* read x - number of 1s before 0 represent the rice */ - while (x <= 8 && get_bits1(&alac->gb)) { - x++; - } - + x = get_unary_0_9(&alac->gb); if (x > 8) { /* RICE THRESHOLD */ - /* use alternative encoding */ + /* use alternative encoding */ int32_t value; value = get_bits(&alac->gb, readsamplesize); @@ -186,7 +179,7 @@ static void bastardized_rice_decompress(ALACContext *alac, x = value; } else { - /* standard rice encoding */ + /* standard rice encoding */ int extrabits; int k; /* size of extra bits */ @@ -206,10 +199,9 @@ static void bastardized_rice_decompress(ALACContext *alac, if (extrabits > 1) { x += extrabits - 1; - get_bits(&alac->gb, k); - } else { - get_bits(&alac->gb, k - 1); - } + skip_bits(&alac->gb, k); + } else + skip_bits(&alac->gb, k - 1); } } @@ -222,8 +214,8 @@ static void bastardized_rice_decompress(ALACContext *alac, sign_modifier = 0; /* now update the history */ - history += (x_modified * rice_historymult) - - ((history * rice_historymult) >> 9); + history += x_modified * rice_historymult + - ((history * rice_historymult) >> 9); if (x_modified > 0xffff) history = 0xffff; @@ -234,10 +226,7 @@ static void bastardized_rice_decompress(ALACContext *alac, sign_modifier = 1; - x = 0; - while (x <= 8 && get_bits1(&alac->gb)) { - x++; - } + x = get_unary_0_9(&alac->gb); if (x > 8) { block_size = get_bits(&alac->gb, 16); @@ -256,16 +245,15 @@ static void bastardized_rice_decompress(ALACContext *alac, if (extrabits < 2) { x = 1 - extrabits; block_size += x; - get_bits(&alac->gb, k - 1); + skip_bits(&alac->gb, k - 1); } else { - get_bits(&alac->gb, k); + skip_bits(&alac->gb, k); } } if (block_size > 0) { memset(&output_buffer[output_count+1], 0, block_size * 4); output_count += block_size; - } if (block_size > 0xffff) @@ -276,12 +264,15 @@ static void bastardized_rice_decompress(ALACContext *alac, } } -#define SIGN_EXTENDED32(val, bits) ((val << (32 - bits)) >> (32 - bits)) +static inline int32_t extend_sign32(int32_t val, int bits) +{ + return (val << (32 - bits)) >> (32 - bits); +} -#define SIGN_ONLY(v) \ - ((v < 0) ? (-1) : \ - ((v > 0) ? (1) : \ - (0))) +static inline int sign_only(int v) +{ + return v ? FFSIGN(v) : 0; +} static void predictor_decompress_fir_adapt(int32_t *error_buffer, int32_t *buffer_out, @@ -297,7 +288,9 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer, *buffer_out = *error_buffer; if (!predictor_coef_num) { - if (output_size <= 1) return; + if (output_size <= 1) + return; + memcpy(buffer_out+1, error_buffer+1, (output_size-1) * 4); return; } @@ -306,53 +299,48 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer, /* second-best case scenario for fir decompression, * error describes a small difference from the previous sample only */ - if (output_size <= 1) return; + if (output_size <= 1) + return; for (i = 0; i < output_size - 1; i++) { int32_t prev_value; int32_t error_value; prev_value = buffer_out[i]; error_value = error_buffer[i+1]; - buffer_out[i+1] = SIGN_EXTENDED32((prev_value + error_value), readsamplesize); + buffer_out[i+1] = + extend_sign32((prev_value + error_value), readsamplesize); } return; } /* read warm-up samples */ - if (predictor_coef_num > 0) { - int i; + if (predictor_coef_num > 0) for (i = 0; i < predictor_coef_num; i++) { int32_t val; val = buffer_out[i] + error_buffer[i+1]; - - val = SIGN_EXTENDED32(val, readsamplesize); - + val = extend_sign32(val, readsamplesize); buffer_out[i+1] = val; } - } #if 0 /* 4 and 8 are very common cases (the only ones i've seen). these - * should be unrolled and optimised + * should be unrolled and optimized */ if (predictor_coef_num == 4) { - /* FIXME: optimised general case */ + /* FIXME: optimized general case */ return; } if (predictor_coef_table == 8) { - /* FIXME: optimised general case */ + /* FIXME: optimized general case */ return; } #endif - /* general case */ if (predictor_coef_num > 0) { - for (i = predictor_coef_num + 1; - i < output_size; - i++) { + for (i = predictor_coef_num + 1; i < output_size; i++) { int j; int sum = 0; int outval; @@ -366,7 +354,7 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer, outval = (1 << (predictor_quantitization-1)) + sum; outval = outval >> predictor_quantitization; outval = outval + buffer_out[0] + error_val; - outval = SIGN_EXTENDED32(outval, readsamplesize); + outval = extend_sign32(outval, readsamplesize); buffer_out[predictor_coef_num+1] = outval; @@ -375,7 +363,7 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer, while (predictor_num >= 0 && error_val > 0) { int val = buffer_out[0] - buffer_out[predictor_coef_num - predictor_num]; - int sign = SIGN_ONLY(val); + int sign = sign_only(val); predictor_coef_table[predictor_num] -= sign; @@ -391,7 +379,7 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer, while (predictor_num >= 0 && error_val < 0) { int val = buffer_out[0] - buffer_out[predictor_coef_num - predictor_num]; - int sign = - SIGN_ONLY(val); + int sign = - sign_only(val); predictor_coef_table[predictor_num] -= sign; @@ -409,32 +397,29 @@ static void predictor_decompress_fir_adapt(int32_t *error_buffer, } } -static void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b, - int16_t *buffer_out, - int numchannels, int numsamples, - uint8_t interlacing_shift, - uint8_t interlacing_leftweight) +static void reconstruct_stereo_16(int32_t *buffer[MAX_CHANNELS], + int16_t *buffer_out, + int numchannels, int numsamples, + uint8_t interlacing_shift, + uint8_t interlacing_leftweight) { int i; - if (numsamples <= 0) return; + if (numsamples <= 0) + return; /* weighted interlacing */ if (interlacing_leftweight) { for (i = 0; i < numsamples; i++) { - int32_t difference, midright; - int16_t left; - int16_t right; - - midright = buffer_a[i]; - difference = buffer_b[i]; + int32_t a, b; + a = buffer[0][i]; + b = buffer[1][i]; - right = midright - ((difference * interlacing_leftweight) >> interlacing_shift); - left = (midright - ((difference * interlacing_leftweight) >> interlacing_shift)) - + difference; + a -= (b * interlacing_leftweight) >> interlacing_shift; + b += a; - buffer_out[i*numchannels] = left; - buffer_out[i*numchannels + 1] = right; + buffer_out[i*numchannels] = b; + buffer_out[i*numchannels + 1] = a; } return; @@ -444,8 +429,8 @@ static void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b, for (i = 0; i < numsamples; i++) { int16_t left, right; - left = buffer_a[i]; - right = buffer_b[i]; + left = buffer[0][i]; + right = buffer[1][i]; buffer_out[i*numchannels] = left; buffer_out[i*numchannels + 1] = right; @@ -454,12 +439,18 @@ static void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b, static int alac_decode_frame(AVCodecContext *avctx, void *outbuffer, int *outputsize, - uint8_t *inbuffer, int input_buffer_size) + const uint8_t *inbuffer, int input_buffer_size) { ALACContext *alac = avctx->priv_data; int channels; int32_t outputsamples; + int hassize; + int readsamplesize; + int wasted_bytes; + int isnotcompressed; + uint8_t interlacing_shift; + uint8_t interlacing_leftweight; /* short-circuit null buffers */ if (!inbuffer || !input_buffer_size) @@ -479,118 +470,111 @@ static int alac_decode_frame(AVCodecContext *avctx, alac->context_initialized = 1; } - outputsamples = alac->setinfo_max_samples_per_frame; - init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8); - channels = get_bits(&alac->gb, 3); - - *outputsize = outputsamples * alac->bytespersample; - - switch(channels) { - case 0: { /* 1 channel */ - int hassize; - int isnotcompressed; - int readsamplesize; - - int wasted_bytes; - int ricemodifier; - + channels = get_bits(&alac->gb, 3) + 1; + if (channels > MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "channels > %d not supported\n", + MAX_CHANNELS); + return input_buffer_size; + } - /* 2^result = something to do with output waiting. - * perhaps matters if we read > 1 frame in a pass? - */ - get_bits(&alac->gb, 4); + /* 2^result = something to do with output waiting. + * perhaps matters if we read > 1 frame in a pass? + */ + skip_bits(&alac->gb, 4); - get_bits(&alac->gb, 12); /* unknown, skip 12 bits */ + skip_bits(&alac->gb, 12); /* unknown, skip 12 bits */ - hassize = get_bits(&alac->gb, 1); /* the output sample size is stored soon */ + /* the output sample size is stored soon */ + hassize = get_bits1(&alac->gb); - wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */ + wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */ - isnotcompressed = get_bits(&alac->gb, 1); /* whether the frame is compressed */ + /* whether the frame is compressed */ + isnotcompressed = get_bits1(&alac->gb); - if (hassize) { - /* now read the number of samples, - * as a 32bit integer */ - outputsamples = get_bits(&alac->gb, 32); - *outputsize = outputsamples * alac->bytespersample; - } + if (hassize) { + /* now read the number of samples as a 32bit integer */ + outputsamples = get_bits(&alac->gb, 32); + } else + outputsamples = alac->setinfo_max_samples_per_frame; - readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8); + *outputsize = outputsamples * alac->bytespersample; + readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + channels - 1; - if (!isnotcompressed) { - /* so it is compressed */ - int16_t predictor_coef_table[32]; - int predictor_coef_num; - int prediction_type; - int prediction_quantitization; - int i; + if (!isnotcompressed) { + /* so it is compressed */ + int16_t predictor_coef_table[channels][32]; + int predictor_coef_num[channels]; + int prediction_type[channels]; + int prediction_quantitization[channels]; + int ricemodifier[channels]; + int i, chan; - /* FIXME: skip 16 bits, not sure what they are. seem to be used in - * two channel case */ - get_bits(&alac->gb, 8); - get_bits(&alac->gb, 8); + interlacing_shift = get_bits(&alac->gb, 8); + interlacing_leftweight = get_bits(&alac->gb, 8); - prediction_type = get_bits(&alac->gb, 4); - prediction_quantitization = get_bits(&alac->gb, 4); + for (chan = 0; chan < channels; chan++) { + prediction_type[chan] = get_bits(&alac->gb, 4); + prediction_quantitization[chan] = get_bits(&alac->gb, 4); - ricemodifier = get_bits(&alac->gb, 3); - predictor_coef_num = get_bits(&alac->gb, 5); + ricemodifier[chan] = get_bits(&alac->gb, 3); + predictor_coef_num[chan] = get_bits(&alac->gb, 5); /* read the predictor table */ - for (i = 0; i < predictor_coef_num; i++) { - predictor_coef_table[i] = (int16_t)get_bits(&alac->gb, 16); - } + for (i = 0; i < predictor_coef_num[chan]; i++) + predictor_coef_table[chan][i] = (int16_t)get_bits(&alac->gb, 16); + } - if (wasted_bytes) { - /* these bytes seem to have something to do with - * > 2 channel files. - */ - av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n"); - } + if (wasted_bytes) + av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n"); + for (chan = 0; chan < channels; chan++) { bastardized_rice_decompress(alac, - alac->predicterror_buffer_a, + alac->predicterror_buffer[chan], outputsamples, readsamplesize, alac->setinfo_rice_initialhistory, alac->setinfo_rice_kmodifier, - ricemodifier * alac->setinfo_rice_historymult / 4, + ricemodifier[chan] * alac->setinfo_rice_historymult / 4, (1 << alac->setinfo_rice_kmodifier) - 1); - if (prediction_type == 0) { - /* adaptive fir */ - predictor_decompress_fir_adapt(alac->predicterror_buffer_a, - alac->outputsamples_buffer_a, + if (prediction_type[chan] == 0) { + /* adaptive fir */ + predictor_decompress_fir_adapt(alac->predicterror_buffer[chan], + alac->outputsamples_buffer[chan], outputsamples, readsamplesize, - predictor_coef_table, - predictor_coef_num, - prediction_quantitization); + predictor_coef_table[chan], + predictor_coef_num[chan], + prediction_quantitization[chan]); } else { - av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type); - /* i think the only other prediction type (or perhaps this is just a - * boolean?) runs adaptive fir twice.. like: + av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type[chan]); + /* I think the only other prediction type (or perhaps this is + * just a boolean?) runs adaptive fir twice.. like: * predictor_decompress_fir_adapt(predictor_error, tempout, ...) * predictor_decompress_fir_adapt(predictor_error, outputsamples ...) * little strange.. */ } - - } else { - /* not compressed, easy case */ - if (readsamplesize <= 16) { - int i; + } + } else { + /* not compressed, easy case */ + if (alac->setinfo_sample_size <= 16) { + int i, chan; + for (chan = 0; chan < channels; chan++) for (i = 0; i < outputsamples; i++) { - int32_t audiobits = get_bits(&alac->gb, readsamplesize); + int32_t audiobits; - audiobits = SIGN_EXTENDED32(audiobits, readsamplesize); + audiobits = get_bits(&alac->gb, alac->setinfo_sample_size); + audiobits = extend_sign32(audiobits, readsamplesize); - alac->outputsamples_buffer_a[i] = audiobits; + alac->outputsamples_buffer[chan][i] = audiobits; } - } else { - int i; + } else { + int i, chan; + for (chan = 0; chan < channels; chan++) for (i = 0; i < outputsamples; i++) { int32_t audiobits; @@ -598,224 +582,43 @@ static int alac_decode_frame(AVCodecContext *avctx, /* special case of sign extension.. * as we'll be ORing the low 16bits into this */ audiobits = audiobits << 16; - audiobits = audiobits >> (32 - readsamplesize); - - audiobits |= get_bits(&alac->gb, readsamplesize - 16); + audiobits = audiobits >> (32 - alac->setinfo_sample_size); + audiobits |= get_bits(&alac->gb, alac->setinfo_sample_size - 16); - alac->outputsamples_buffer_a[i] = audiobits; + alac->outputsamples_buffer[chan][i] = audiobits; } - } - /* wasted_bytes = 0; // unused */ } + /* wasted_bytes = 0; */ + interlacing_shift = 0; + interlacing_leftweight = 0; + } - switch(alac->setinfo_sample_size) { - case 16: { + switch(alac->setinfo_sample_size) { + case 16: + if (channels == 2) { + reconstruct_stereo_16(alac->outputsamples_buffer, + (int16_t*)outbuffer, + alac->numchannels, + outputsamples, + interlacing_shift, + interlacing_leftweight); + } else { int i; for (i = 0; i < outputsamples; i++) { - int16_t sample = alac->outputsamples_buffer_a[i]; + int16_t sample = alac->outputsamples_buffer[0][i]; ((int16_t*)outbuffer)[i * alac->numchannels] = sample; } - break; - } - case 20: - case 24: - case 32: - av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); - break; - default: - break; } break; - } - case 1: { /* 2 channels */ - int hassize; - int isnotcompressed; - int readsamplesize; - - int wasted_bytes; - - uint8_t interlacing_shift; - uint8_t interlacing_leftweight; - - /* 2^result = something to do with output waiting. - * perhaps matters if we read > 1 frame in a pass? - */ - get_bits(&alac->gb, 4); - - get_bits(&alac->gb, 12); /* unknown, skip 12 bits */ - - hassize = get_bits(&alac->gb, 1); /* the output sample size is stored soon */ - - wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */ - - isnotcompressed = get_bits(&alac->gb, 1); /* whether the frame is compressed */ - - if (hassize) { - /* now read the number of samples, - * as a 32bit integer */ - outputsamples = get_bits(&alac->gb, 32); - *outputsize = outputsamples * alac->bytespersample; - } - - readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + 1; - - if (!isnotcompressed) { - /* compressed */ - int16_t predictor_coef_table_a[32]; - int predictor_coef_num_a; - int prediction_type_a; - int prediction_quantitization_a; - int ricemodifier_a; - - int16_t predictor_coef_table_b[32]; - int predictor_coef_num_b; - int prediction_type_b; - int prediction_quantitization_b; - int ricemodifier_b; - - int i; - - interlacing_shift = get_bits(&alac->gb, 8); - interlacing_leftweight = get_bits(&alac->gb, 8); - - /******** channel 1 ***********/ - prediction_type_a = get_bits(&alac->gb, 4); - prediction_quantitization_a = get_bits(&alac->gb, 4); - - ricemodifier_a = get_bits(&alac->gb, 3); - predictor_coef_num_a = get_bits(&alac->gb, 5); - - /* read the predictor table */ - for (i = 0; i < predictor_coef_num_a; i++) { - predictor_coef_table_a[i] = (int16_t)get_bits(&alac->gb, 16); - } - - /******** channel 2 *********/ - prediction_type_b = get_bits(&alac->gb, 4); - prediction_quantitization_b = get_bits(&alac->gb, 4); - - ricemodifier_b = get_bits(&alac->gb, 3); - predictor_coef_num_b = get_bits(&alac->gb, 5); - - /* read the predictor table */ - for (i = 0; i < predictor_coef_num_b; i++) { - predictor_coef_table_b[i] = (int16_t)get_bits(&alac->gb, 16); - } - - /*********************/ - if (wasted_bytes) { - /* see mono case */ - av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n"); - } - - /* channel 1 */ - bastardized_rice_decompress(alac, - alac->predicterror_buffer_a, - outputsamples, - readsamplesize, - alac->setinfo_rice_initialhistory, - alac->setinfo_rice_kmodifier, - ricemodifier_a * alac->setinfo_rice_historymult / 4, - (1 << alac->setinfo_rice_kmodifier) - 1); - - if (prediction_type_a == 0) { - /* adaptive fir */ - predictor_decompress_fir_adapt(alac->predicterror_buffer_a, - alac->outputsamples_buffer_a, - outputsamples, - readsamplesize, - predictor_coef_table_a, - predictor_coef_num_a, - prediction_quantitization_a); - } else { - /* see mono case */ - av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type_a); - } - - /* channel 2 */ - bastardized_rice_decompress(alac, - alac->predicterror_buffer_b, - outputsamples, - readsamplesize, - alac->setinfo_rice_initialhistory, - alac->setinfo_rice_kmodifier, - ricemodifier_b * alac->setinfo_rice_historymult / 4, - (1 << alac->setinfo_rice_kmodifier) - 1); - - if (prediction_type_b == 0) { - /* adaptive fir */ - predictor_decompress_fir_adapt(alac->predicterror_buffer_b, - alac->outputsamples_buffer_b, - outputsamples, - readsamplesize, - predictor_coef_table_b, - predictor_coef_num_b, - prediction_quantitization_b); - } else { - av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type_b); - } - } else { - /* not compressed, easy case */ - if (alac->setinfo_sample_size <= 16) { - int i; - for (i = 0; i < outputsamples; i++) { - int32_t audiobits_a, audiobits_b; - - audiobits_a = get_bits(&alac->gb, alac->setinfo_sample_size); - audiobits_b = get_bits(&alac->gb, alac->setinfo_sample_size); - - audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size); - audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size); - - alac->outputsamples_buffer_a[i] = audiobits_a; - alac->outputsamples_buffer_b[i] = audiobits_b; - } - } else { - int i; - for (i = 0; i < outputsamples; i++) { - int32_t audiobits_a, audiobits_b; - - audiobits_a = get_bits(&alac->gb, 16); - audiobits_a = audiobits_a << 16; - audiobits_a = audiobits_a >> (32 - alac->setinfo_sample_size); - audiobits_a |= get_bits(&alac->gb, alac->setinfo_sample_size - 16); - - audiobits_b = get_bits(&alac->gb, 16); - audiobits_b = audiobits_b << 16; - audiobits_b = audiobits_b >> (32 - alac->setinfo_sample_size); - audiobits_b |= get_bits(&alac->gb, alac->setinfo_sample_size - 16); - - alac->outputsamples_buffer_a[i] = audiobits_a; - alac->outputsamples_buffer_b[i] = audiobits_b; - } - } - /* wasted_bytes = 0; */ - interlacing_shift = 0; - interlacing_leftweight = 0; - } - - switch(alac->setinfo_sample_size) { - case 16: { - deinterlace_16(alac->outputsamples_buffer_a, - alac->outputsamples_buffer_b, - (int16_t*)outbuffer, - alac->numchannels, - outputsamples, - interlacing_shift, - interlacing_leftweight); - break; - } - case 20: - case 24: - case 32: - av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); - break; - default: - break; - } - + case 20: + case 24: + // It is not clear if there exist any encoder that creates 24 bit ALAC + // files. iTunes convert 24 bit raw files to 16 bit before encoding. + case 32: + av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); + break; + default: break; - } } return input_buffer_size; @@ -838,11 +641,11 @@ static int alac_decode_close(AVCodecContext *avctx) { ALACContext *alac = avctx->priv_data; - av_free(alac->predicterror_buffer_a); - av_free(alac->predicterror_buffer_b); - - av_free(alac->outputsamples_buffer_a); - av_free(alac->outputsamples_buffer_b); + int chan; + for (chan = 0; chan < MAX_CHANNELS; chan++) { + av_free(alac->predicterror_buffer[chan]); + av_free(alac->outputsamples_buffer[chan]); + } return 0; } diff --git a/contrib/ffmpeg/libavcodec/allcodecs.c b/contrib/ffmpeg/libavcodec/allcodecs.c index b247cbe34..9bb35fa97 100644 --- a/contrib/ffmpeg/libavcodec/allcodecs.c +++ b/contrib/ffmpeg/libavcodec/allcodecs.c @@ -26,14 +26,20 @@ #include "avcodec.h" -#define REGISTER_ENCODER(X,x) \ - if(ENABLE_##X##_ENCODER) register_avcodec(&x##_encoder) -#define REGISTER_DECODER(X,x) \ - if(ENABLE_##X##_DECODER) register_avcodec(&x##_decoder) +#define REGISTER_ENCODER(X,x) { \ + extern AVCodec x##_encoder; \ + if(ENABLE_##X##_ENCODER) register_avcodec(&x##_encoder); } +#define REGISTER_DECODER(X,x) { \ + extern AVCodec x##_decoder; \ + if(ENABLE_##X##_DECODER) register_avcodec(&x##_decoder); } #define REGISTER_ENCDEC(X,x) REGISTER_ENCODER(X,x); REGISTER_DECODER(X,x) -#define REGISTER_PARSER(X,x) \ - if(ENABLE_##X##_PARSER) av_register_codec_parser(&x##_parser) +#define REGISTER_PARSER(X,x) { \ + extern AVCodecParser x##_parser; \ + if(ENABLE_##X##_PARSER) av_register_codec_parser(&x##_parser); } +#define REGISTER_BSF(X,x) { \ + extern AVBitStreamFilter x##_bsf; \ + if(ENABLE_##X##_BSF) av_register_bitstream_filter(&x##_bsf); } /** * Register all the codecs, parsers and bitstream filters which were enabled at @@ -47,231 +53,261 @@ */ void avcodec_register_all(void) { - static int inited = 0; + static int initialized; - if (inited != 0) + if (initialized) return; - inited = 1; + initialized = 1; /* video codecs */ - REGISTER_DECODER(AASC, aasc); - REGISTER_ENCDEC (ASV1, asv1); - REGISTER_ENCDEC (ASV2, asv2); - REGISTER_DECODER(AVS, avs); - REGISTER_ENCDEC (BMP, bmp); - REGISTER_DECODER(CAVS, cavs); - REGISTER_DECODER(CINEPAK, cinepak); - REGISTER_DECODER(CLJR, cljr); - REGISTER_DECODER(CSCD, cscd); - REGISTER_DECODER(CYUV, cyuv); - REGISTER_DECODER(DCA, dca); - REGISTER_DECODER(DNXHD, dnxhd); - REGISTER_DECODER(DSICINVIDEO, dsicinvideo); - REGISTER_ENCDEC (DVVIDEO, dvvideo); - REGISTER_DECODER(DXA, dxa); - REGISTER_DECODER(EIGHTBPS, eightbps); - REGISTER_ENCDEC (FFV1, ffv1); - REGISTER_ENCDEC (FFVHUFF, ffvhuff); - REGISTER_ENCDEC (FLASHSV, flashsv); - REGISTER_DECODER(FLIC, flic); - REGISTER_ENCDEC (FLV, flv); - REGISTER_DECODER(FOURXM, fourxm); - REGISTER_DECODER(FRAPS, fraps); - REGISTER_ENCDEC (GIF, gif); - REGISTER_ENCDEC (H261, h261); - REGISTER_ENCDEC (H263, h263); - REGISTER_DECODER(H263I, h263i); - REGISTER_ENCODER(H263P, h263p); - REGISTER_DECODER(H264, h264); - REGISTER_ENCDEC (HUFFYUV, huffyuv); - REGISTER_DECODER(IDCIN, idcin); - REGISTER_DECODER(INDEO2, indeo2); - REGISTER_DECODER(INDEO3, indeo3); - REGISTER_DECODER(INTERPLAY_VIDEO, interplay_video); - REGISTER_ENCODER(JPEGLS, jpegls); - REGISTER_DECODER(KMVC, kmvc); - REGISTER_ENCODER(LJPEG, ljpeg); - REGISTER_DECODER(LOCO, loco); - REGISTER_DECODER(MDEC, mdec); - REGISTER_ENCDEC (MJPEG, mjpeg); - REGISTER_DECODER(MJPEGB, mjpegb); - REGISTER_DECODER(MMVIDEO, mmvideo); - REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc); - REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); - REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); - REGISTER_ENCDEC (MPEG4, mpeg4); - REGISTER_DECODER(MPEGVIDEO, mpegvideo); - REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1); - REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); - REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); - REGISTER_DECODER(MSRLE, msrle); - REGISTER_DECODER(MSVIDEO1, msvideo1); - REGISTER_DECODER(MSZH, mszh); - REGISTER_DECODER(NUV, nuv); - REGISTER_ENCODER(PAM, pam); - REGISTER_ENCODER(PBM, pbm); - REGISTER_ENCODER(PGM, pgm); - REGISTER_ENCODER(PGMYUV, pgmyuv); - REGISTER_ENCDEC (PNG, png); - REGISTER_ENCODER(PPM, ppm); - REGISTER_DECODER(QDRAW, qdraw); - REGISTER_DECODER(QPEG, qpeg); - REGISTER_DECODER(QTRLE, qtrle); - REGISTER_ENCDEC (RAWVIDEO, rawvideo); - REGISTER_DECODER(ROQ, roq); - REGISTER_DECODER(RPZA, rpza); - REGISTER_ENCDEC (RV10, rv10); - REGISTER_ENCDEC (RV20, rv20); - REGISTER_DECODER(SMACKER, smacker); - REGISTER_DECODER(SMC, smc); - REGISTER_ENCDEC (SNOW, snow); - REGISTER_DECODER(SP5X, sp5x); - REGISTER_ENCDEC (SVQ1, svq1); - REGISTER_DECODER(SVQ3, svq3); - REGISTER_ENCDEC (TARGA, targa); - REGISTER_DECODER(THEORA, theora); - REGISTER_DECODER(THP, thp); - REGISTER_DECODER(TIERTEXSEQVIDEO, tiertexseqvideo); - REGISTER_DECODER(TIFF, tiff); - REGISTER_DECODER(TRUEMOTION1, truemotion1); - REGISTER_DECODER(TRUEMOTION2, truemotion2); - REGISTER_DECODER(TSCC, tscc); - REGISTER_DECODER(ULTI, ulti); - REGISTER_DECODER(VC1, vc1); - REGISTER_DECODER(VCR1, vcr1); - REGISTER_DECODER(VMDVIDEO, vmdvideo); - REGISTER_DECODER(VMNC, vmnc); - REGISTER_DECODER(VP3, vp3); - REGISTER_DECODER(VP5, vp5); - REGISTER_DECODER(VP6, vp6); - REGISTER_DECODER(VP6F, vp6f); - REGISTER_DECODER(VQA, vqa); - REGISTER_ENCDEC (WMV1, wmv1); - REGISTER_ENCDEC (WMV2, wmv2); - REGISTER_DECODER(WMV3, wmv3); - REGISTER_DECODER(WNV1, wnv1); - REGISTER_ENCODER(X264, x264); - REGISTER_DECODER(XAN_WC3, xan_wc3); - REGISTER_DECODER(XL, xl); - REGISTER_ENCODER(XVID, xvid); - REGISTER_ENCDEC (ZLIB, zlib); - REGISTER_ENCDEC (ZMBV, zmbv); + REGISTER_DECODER (AASC, aasc); + REGISTER_DECODER (AMV, amv); + REGISTER_ENCDEC (ASV1, asv1); + REGISTER_ENCDEC (ASV2, asv2); + REGISTER_DECODER (AVS, avs); + REGISTER_DECODER (BETHSOFTVID, bethsoftvid); + REGISTER_ENCDEC (BMP, bmp); + REGISTER_DECODER (C93, c93); + REGISTER_DECODER (CAVS, cavs); + REGISTER_DECODER (CINEPAK, cinepak); + REGISTER_DECODER (CLJR, cljr); + REGISTER_DECODER (CSCD, cscd); + REGISTER_DECODER (CYUV, cyuv); + REGISTER_ENCDEC (DNXHD, dnxhd); + REGISTER_DECODER (DSICINVIDEO, dsicinvideo); + REGISTER_ENCDEC (DVVIDEO, dvvideo); + REGISTER_DECODER (DXA, dxa); + REGISTER_DECODER (EIGHTBPS, eightbps); + REGISTER_ENCDEC (FFV1, ffv1); + REGISTER_ENCDEC (FFVHUFF, ffvhuff); + REGISTER_ENCDEC (FLASHSV, flashsv); + REGISTER_DECODER (FLIC, flic); + REGISTER_ENCDEC (FLV, flv); + REGISTER_DECODER (FOURXM, fourxm); + REGISTER_DECODER (FRAPS, fraps); + REGISTER_ENCDEC (GIF, gif); + REGISTER_ENCDEC (H261, h261); + REGISTER_ENCDEC (H263, h263); + REGISTER_DECODER (H263I, h263i); + REGISTER_ENCODER (H263P, h263p); + REGISTER_DECODER (H264, h264); + REGISTER_ENCDEC (HUFFYUV, huffyuv); + REGISTER_DECODER (IDCIN, idcin); + REGISTER_DECODER (INDEO2, indeo2); + REGISTER_DECODER (INDEO3, indeo3); + REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video); + REGISTER_ENCDEC (JPEGLS, jpegls); + REGISTER_DECODER (KMVC, kmvc); + REGISTER_ENCODER (LJPEG, ljpeg); + REGISTER_DECODER (LOCO, loco); + REGISTER_DECODER (MDEC, mdec); + REGISTER_ENCDEC (MJPEG, mjpeg); + REGISTER_DECODER (MJPEGB, mjpegb); + REGISTER_DECODER (MMVIDEO, mmvideo); + REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc); + REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); + REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); + REGISTER_ENCDEC (MPEG4, mpeg4); + REGISTER_DECODER (MPEGVIDEO, mpegvideo); + REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1); + REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); + REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); + REGISTER_DECODER (MSRLE, msrle); + REGISTER_DECODER (MSVIDEO1, msvideo1); + REGISTER_DECODER (MSZH, mszh); + REGISTER_DECODER (NUV, nuv); + REGISTER_ENCODER (PAM, pam); + REGISTER_ENCODER (PBM, pbm); + REGISTER_DECODER (PCX, pcx); + REGISTER_ENCODER (PGM, pgm); + REGISTER_ENCODER (PGMYUV, pgmyuv); + REGISTER_ENCDEC (PNG, png); + REGISTER_ENCODER (PPM, ppm); + REGISTER_DECODER (PTX, ptx); + REGISTER_DECODER (QDRAW, qdraw); + REGISTER_DECODER (QPEG, qpeg); + REGISTER_ENCDEC (QTRLE, qtrle); + REGISTER_ENCDEC (RAWVIDEO, rawvideo); + REGISTER_ENCDEC (ROQ, roq); + REGISTER_DECODER (RPZA, rpza); + REGISTER_ENCDEC (RV10, rv10); + REGISTER_ENCDEC (RV20, rv20); + REGISTER_ENCDEC (SGI, sgi); + REGISTER_DECODER (SMACKER, smacker); + REGISTER_DECODER (SMC, smc); + REGISTER_ENCDEC (SNOW, snow); + REGISTER_DECODER (SP5X, sp5x); + REGISTER_DECODER (SUNRAST, sunrast); + REGISTER_ENCDEC (SVQ1, svq1); + REGISTER_DECODER (SVQ3, svq3); + REGISTER_ENCDEC (TARGA, targa); + REGISTER_DECODER (THEORA, theora); + REGISTER_DECODER (THP, thp); + REGISTER_DECODER (TIERTEXSEQVIDEO, tiertexseqvideo); + REGISTER_ENCDEC (TIFF, tiff); + REGISTER_DECODER (TRUEMOTION1, truemotion1); + REGISTER_DECODER (TRUEMOTION2, truemotion2); + REGISTER_DECODER (TSCC, tscc); + REGISTER_DECODER (TXD, txd); + REGISTER_DECODER (ULTI, ulti); + REGISTER_DECODER (VB, vb); + REGISTER_DECODER (VC1, vc1); + REGISTER_DECODER (VCR1, vcr1); + REGISTER_DECODER (VMDVIDEO, vmdvideo); + REGISTER_DECODER (VMNC, vmnc); + REGISTER_DECODER (VP3, vp3); + REGISTER_DECODER (VP5, vp5); + REGISTER_DECODER (VP6, vp6); + REGISTER_DECODER (VP6A, vp6a); + REGISTER_DECODER (VP6F, vp6f); + REGISTER_DECODER (VQA, vqa); + REGISTER_ENCDEC (WMV1, wmv1); + REGISTER_ENCDEC (WMV2, wmv2); + REGISTER_DECODER (WMV3, wmv3); + REGISTER_DECODER (WNV1, wnv1); + REGISTER_DECODER (XAN_WC3, xan_wc3); + REGISTER_DECODER (XL, xl); + REGISTER_DECODER (XSUB, xsub); + REGISTER_ENCDEC (ZLIB, zlib); + REGISTER_ENCDEC (ZMBV, zmbv); /* audio codecs */ - REGISTER_DECODER(AAC, aac); - REGISTER_DECODER(MPEG4AAC, mpeg4aac); - REGISTER_ENCODER(AC3, ac3); - REGISTER_DECODER(ALAC, alac); - REGISTER_ENCDEC (AMR_NB, amr_nb); - REGISTER_ENCDEC (AMR_WB, amr_wb); - REGISTER_DECODER(COOK, cook); - REGISTER_DECODER(DSICINAUDIO, dsicinaudio); - REGISTER_DECODER(DTS, dts); - REGISTER_ENCODER(FAAC, faac); - REGISTER_ENCDEC (FLAC, flac); - REGISTER_DECODER(IMC, imc); - REGISTER_DECODER(LIBA52, liba52); - REGISTER_ENCDEC (LIBGSM, libgsm); - REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); - REGISTER_ENCODER(LIBTHEORA, libtheora); - REGISTER_DECODER(MACE3, mace3); - REGISTER_DECODER(MACE6, mace6); - REGISTER_ENCDEC (MP2, mp2); - REGISTER_DECODER(MP3, mp3); - REGISTER_DECODER(MP3ADU, mp3adu); - REGISTER_ENCODER(MP3LAME, mp3lame); - REGISTER_DECODER(MP3ON4, mp3on4); - REGISTER_DECODER(MPC7, mpc7); - if (!ENABLE_VORBIS_ENCODER) REGISTER_ENCODER(OGGVORBIS, oggvorbis); - if (!ENABLE_VORBIS_DECODER) REGISTER_DECODER(OGGVORBIS, oggvorbis); - REGISTER_DECODER(QDM2, qdm2); - REGISTER_DECODER(RA_144, ra_144); - REGISTER_DECODER(RA_288, ra_288); - REGISTER_DECODER(SHORTEN, shorten); - REGISTER_DECODER(SMACKAUD, smackaud); - REGISTER_ENCDEC (SONIC, sonic); - REGISTER_ENCODER(SONIC_LS, sonic_ls); - REGISTER_DECODER(TRUESPEECH, truespeech); - REGISTER_DECODER(TTA, tta); - REGISTER_DECODER(VMDAUDIO, vmdaudio); - REGISTER_ENCDEC (VORBIS, vorbis); - REGISTER_DECODER(WAVPACK, wavpack); - REGISTER_ENCDEC(WMAV1, wmav1); - REGISTER_ENCDEC(WMAV2, wmav2); - REGISTER_DECODER(WS_SND1, ws_snd1); + REGISTER_DECODER (MPEG4AAC, mpeg4aac); + REGISTER_ENCDEC (AC3, ac3); + REGISTER_DECODER (ALAC, alac); + REGISTER_DECODER (APE, ape); + REGISTER_DECODER (ATRAC3, atrac3); + REGISTER_DECODER (COOK, cook); + REGISTER_DECODER (DCA, dca); + REGISTER_DECODER (DSICINAUDIO, dsicinaudio); + REGISTER_ENCDEC (FLAC, flac); + REGISTER_DECODER (IMC, imc); + REGISTER_DECODER (MACE3, mace3); + REGISTER_DECODER (MACE6, mace6); + REGISTER_ENCDEC (MP2, mp2); + REGISTER_DECODER (MP3, mp3); + REGISTER_DECODER (MP3ADU, mp3adu); + REGISTER_DECODER (MP3ON4, mp3on4); + REGISTER_DECODER (MPC7, mpc7); + REGISTER_DECODER (MPC8, mpc8); + REGISTER_DECODER (NELLYMOSER, nellymoser); + REGISTER_DECODER (QDM2, qdm2); + REGISTER_DECODER (RA_144, ra_144); + REGISTER_DECODER (RA_288, ra_288); + REGISTER_DECODER (SHORTEN, shorten); + REGISTER_DECODER (SMACKAUD, smackaud); + REGISTER_ENCDEC (SONIC, sonic); + REGISTER_ENCODER (SONIC_LS, sonic_ls); + REGISTER_DECODER (TRUESPEECH, truespeech); + REGISTER_DECODER (TTA, tta); + REGISTER_DECODER (VMDAUDIO, vmdaudio); + REGISTER_ENCDEC (VORBIS, vorbis); + REGISTER_DECODER (WAVPACK, wavpack); + REGISTER_ENCDEC (WMAV1, wmav1); + REGISTER_ENCDEC (WMAV2, wmav2); + REGISTER_DECODER (WS_SND1, ws_snd1); /* pcm codecs */ - REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); - REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw); - REGISTER_ENCDEC (PCM_S8, pcm_s8); - REGISTER_ENCDEC (PCM_S16BE, pcm_s16be); - REGISTER_ENCDEC (PCM_S16LE, pcm_s16le); - REGISTER_ENCDEC (PCM_S24BE, pcm_s24be); - REGISTER_ENCDEC (PCM_S24DAUD, pcm_s24daud); - REGISTER_ENCDEC (PCM_S24LE, pcm_s24le); - REGISTER_ENCDEC (PCM_S32BE, pcm_s32be); - REGISTER_ENCDEC (PCM_S32LE, pcm_s32le); - REGISTER_ENCDEC (PCM_U8, pcm_u8); - REGISTER_ENCDEC (PCM_U16BE, pcm_u16be); - REGISTER_ENCDEC (PCM_U16LE, pcm_u16le); - REGISTER_ENCDEC (PCM_U24BE, pcm_u24be); - REGISTER_ENCDEC (PCM_U24LE, pcm_u24le); - REGISTER_ENCDEC (PCM_U32BE, pcm_u32be); - REGISTER_ENCDEC (PCM_U32LE, pcm_u32le); + REGISTER_ENCDEC (PCM_ALAW, pcm_alaw); + REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw); + REGISTER_ENCDEC (PCM_S8, pcm_s8); + REGISTER_ENCDEC (PCM_S16BE, pcm_s16be); + REGISTER_ENCDEC (PCM_S16LE, pcm_s16le); + REGISTER_DECODER (PCM_S16LE_PLANAR, pcm_s16le_planar); + REGISTER_ENCDEC (PCM_S24BE, pcm_s24be); + REGISTER_ENCDEC (PCM_S24DAUD, pcm_s24daud); + REGISTER_ENCDEC (PCM_S24LE, pcm_s24le); + REGISTER_ENCDEC (PCM_S32BE, pcm_s32be); + REGISTER_ENCDEC (PCM_S32LE, pcm_s32le); + REGISTER_ENCDEC (PCM_U8, pcm_u8); + REGISTER_ENCDEC (PCM_U16BE, pcm_u16be); + REGISTER_ENCDEC (PCM_U16LE, pcm_u16le); + REGISTER_ENCDEC (PCM_U24BE, pcm_u24be); + REGISTER_ENCDEC (PCM_U24LE, pcm_u24le); + REGISTER_ENCDEC (PCM_U32BE, pcm_u32be); + REGISTER_ENCDEC (PCM_U32LE, pcm_u32le); + REGISTER_ENCDEC (PCM_ZORK , pcm_zork); /* dpcm codecs */ - REGISTER_DECODER(INTERPLAY_DPCM, interplay_dpcm); - REGISTER_DECODER(ROQ_DPCM, roq_dpcm); - REGISTER_DECODER(SOL_DPCM, sol_dpcm); - REGISTER_DECODER(XAN_DPCM, xan_dpcm); + REGISTER_DECODER (INTERPLAY_DPCM, interplay_dpcm); + REGISTER_ENCDEC (ROQ_DPCM, roq_dpcm); + REGISTER_DECODER (SOL_DPCM, sol_dpcm); + REGISTER_DECODER (XAN_DPCM, xan_dpcm); /* adpcm codecs */ - REGISTER_ENCDEC (ADPCM_4XM, adpcm_4xm); - REGISTER_ENCDEC (ADPCM_ADX, adpcm_adx); - REGISTER_ENCDEC (ADPCM_CT, adpcm_ct); - REGISTER_ENCDEC (ADPCM_EA, adpcm_ea); - REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); - REGISTER_ENCDEC (ADPCM_IMA_DK3, adpcm_ima_dk3); - REGISTER_ENCDEC (ADPCM_IMA_DK4, adpcm_ima_dk4); - REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt); - REGISTER_ENCDEC (ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); - REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav); - REGISTER_ENCDEC (ADPCM_IMA_WS, adpcm_ima_ws); - REGISTER_ENCDEC (ADPCM_MS, adpcm_ms); - REGISTER_ENCDEC (ADPCM_SBPRO_2, adpcm_sbpro_2); - REGISTER_ENCDEC (ADPCM_SBPRO_3, adpcm_sbpro_3); - REGISTER_ENCDEC (ADPCM_SBPRO_4, adpcm_sbpro_4); - REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf); - REGISTER_ENCDEC (ADPCM_XA, adpcm_xa); - REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha); + REGISTER_DECODER (ADPCM_4XM, adpcm_4xm); + REGISTER_ENCDEC (ADPCM_ADX, adpcm_adx); + REGISTER_DECODER (ADPCM_CT, adpcm_ct); + REGISTER_DECODER (ADPCM_EA, adpcm_ea); + REGISTER_DECODER (ADPCM_EA_R1, adpcm_ea_r1); + REGISTER_DECODER (ADPCM_EA_R2, adpcm_ea_r2); + REGISTER_DECODER (ADPCM_EA_R3, adpcm_ea_r3); + REGISTER_DECODER (ADPCM_EA_XAS, adpcm_ea_xas); + REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); + REGISTER_DECODER (ADPCM_IMA_AMV, adpcm_ima_amv); + REGISTER_DECODER (ADPCM_IMA_DK3, adpcm_ima_dk3); + REGISTER_DECODER (ADPCM_IMA_DK4, adpcm_ima_dk4); + REGISTER_DECODER (ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs); + REGISTER_DECODER (ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead); + REGISTER_DECODER (ADPCM_IMA_QT, adpcm_ima_qt); + REGISTER_DECODER (ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); + REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav); + REGISTER_DECODER (ADPCM_IMA_WS, adpcm_ima_ws); + REGISTER_ENCDEC (ADPCM_MS, adpcm_ms); + REGISTER_DECODER (ADPCM_SBPRO_2, adpcm_sbpro_2); + REGISTER_DECODER (ADPCM_SBPRO_3, adpcm_sbpro_3); + REGISTER_DECODER (ADPCM_SBPRO_4, adpcm_sbpro_4); + REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf); + REGISTER_DECODER (ADPCM_THP, adpcm_thp); + REGISTER_DECODER (ADPCM_XA, adpcm_xa); + REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha); /* subtitles */ - REGISTER_ENCDEC (DVBSUB, dvbsub); - REGISTER_ENCDEC (DVDSUB, dvdsub); + REGISTER_ENCDEC (DVBSUB, dvbsub); + REGISTER_ENCDEC (DVDSUB, dvdsub); + + /* external libraries */ + REGISTER_DECODER (LIBA52, liba52); + REGISTER_ENCDEC (LIBAMR_NB, libamr_nb); + REGISTER_ENCDEC (LIBAMR_WB, libamr_wb); + REGISTER_ENCODER (LIBFAAC, libfaac); + REGISTER_DECODER (LIBFAAD, libfaad); + REGISTER_ENCDEC (LIBGSM, libgsm); + REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); + REGISTER_ENCODER (LIBMP3LAME, libmp3lame); + REGISTER_ENCODER (LIBTHEORA, libtheora); + REGISTER_ENCODER (LIBVORBIS, libvorbis); + REGISTER_ENCODER (LIBX264, libx264); + REGISTER_ENCODER (LIBXVID, libxvid); /* parsers */ - REGISTER_PARSER (AAC, aac); - REGISTER_PARSER (AC3, ac3); - REGISTER_PARSER (CAVSVIDEO, cavsvideo); - REGISTER_PARSER (DCA, dca); - REGISTER_PARSER (DVBSUB, dvbsub); - REGISTER_PARSER (DVDSUB, dvdsub); - REGISTER_PARSER (H261, h261); - REGISTER_PARSER (H263, h263); - REGISTER_PARSER (H264, h264); - REGISTER_PARSER (MJPEG, mjpeg); - REGISTER_PARSER (MPEG4VIDEO, mpeg4video); - REGISTER_PARSER (MPEGAUDIO, mpegaudio); - REGISTER_PARSER (MPEGVIDEO, mpegvideo); - REGISTER_PARSER (PNM, pnm); - REGISTER_PARSER (VC1, vc1); + REGISTER_PARSER (AAC, aac); + REGISTER_PARSER (AC3, ac3); + REGISTER_PARSER (CAVSVIDEO, cavsvideo); + REGISTER_PARSER (DCA, dca); + REGISTER_PARSER (DVBSUB, dvbsub); + REGISTER_PARSER (DVDSUB, dvdsub); + REGISTER_PARSER (H261, h261); + REGISTER_PARSER (H263, h263); + REGISTER_PARSER (H264, h264); + REGISTER_PARSER (MJPEG, mjpeg); + REGISTER_PARSER (MLP, mlp); + REGISTER_PARSER (MPEG4VIDEO, mpeg4video); + REGISTER_PARSER (MPEGAUDIO, mpegaudio); + REGISTER_PARSER (MPEGVIDEO, mpegvideo); + REGISTER_PARSER (PNM, pnm); + REGISTER_PARSER (VC1, vc1); - av_register_bitstream_filter(&dump_extradata_bsf); - av_register_bitstream_filter(&remove_extradata_bsf); - av_register_bitstream_filter(&noise_bsf); - av_register_bitstream_filter(&mp3_header_compress_bsf); - av_register_bitstream_filter(&mp3_header_decompress_bsf); - av_register_bitstream_filter(&mjpega_dump_header_bsf); - av_register_bitstream_filter(&imx_dump_header_bsf); + /* bitstream filters */ + REGISTER_BSF (DUMP_EXTRADATA, dump_extradata); + REGISTER_BSF (H264_MP4TOANNEXB, h264_mp4toannexb); + REGISTER_BSF (IMX_DUMP_HEADER, imx_dump_header); + REGISTER_BSF (MJPEGA_DUMP_HEADER, mjpega_dump_header); + REGISTER_BSF (MP3_HEADER_COMPRESS, mp3_header_compress); + REGISTER_BSF (MP3_HEADER_DECOMPRESS, mp3_header_decompress); + REGISTER_BSF (MOV2TEXTSUB, mov2textsub); + REGISTER_BSF (NOISE, noise); + REGISTER_BSF (REMOVE_EXTRADATA, remove_extradata); + REGISTER_BSF (TEXT2MOVSUB, text2movsub); } diff --git a/contrib/ffmpeg/libavcodec/alpha/asm.h b/contrib/ffmpeg/libavcodec/alpha/asm.h index c0ddde528..1d0fa6f6a 100644 --- a/contrib/ffmpeg/libavcodec/alpha/asm.h +++ b/contrib/ffmpeg/libavcodec/alpha/asm.h @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef LIBAVCODEC_ALPHA_ASM_H -#define LIBAVCODEC_ALPHA_ASM_H +#ifndef FFMPEG_ASM_H +#define FFMPEG_ASM_H #include <inttypes.h> @@ -188,4 +188,4 @@ struct unaligned_long { uint64_t l; } __attribute__((packed)); #error "Unknown compiler!" #endif -#endif /* LIBAVCODEC_ALPHA_ASM_H */ +#endif /* FFMPEG_ASM_H */ diff --git a/contrib/ffmpeg/libavcodec/alpha/dsputil_alpha.c b/contrib/ffmpeg/libavcodec/alpha/dsputil_alpha.c index c98d6f7ff..36357356e 100644 --- a/contrib/ffmpeg/libavcodec/alpha/dsputil_alpha.c +++ b/contrib/ffmpeg/libavcodec/alpha/dsputil_alpha.c @@ -20,7 +20,7 @@ */ #include "asm.h" -#include "../dsputil.h" +#include "dsputil.h" extern void simple_idct_axp(DCTELEM *block); extern void simple_idct_put_axp(uint8_t *dest, int line_size, DCTELEM *block); diff --git a/contrib/ffmpeg/libavcodec/alpha/motion_est_alpha.c b/contrib/ffmpeg/libavcodec/alpha/motion_est_alpha.c index 337ffb38e..b23338c09 100644 --- a/contrib/ffmpeg/libavcodec/alpha/motion_est_alpha.c +++ b/contrib/ffmpeg/libavcodec/alpha/motion_est_alpha.c @@ -20,7 +20,7 @@ */ #include "asm.h" -#include "../dsputil.h" +#include "dsputil.h" void get_pixels_mvi(DCTELEM *restrict block, const uint8_t *restrict pixels, int line_size) diff --git a/contrib/ffmpeg/libavcodec/alpha/mpegvideo_alpha.c b/contrib/ffmpeg/libavcodec/alpha/mpegvideo_alpha.c index 8ad264b06..9aa20f420 100644 --- a/contrib/ffmpeg/libavcodec/alpha/mpegvideo_alpha.c +++ b/contrib/ffmpeg/libavcodec/alpha/mpegvideo_alpha.c @@ -20,8 +20,8 @@ */ #include "asm.h" -#include "../dsputil.h" -#include "../mpegvideo.h" +#include "dsputil.h" +#include "mpegvideo.h" static void dct_unquantize_h263_intra_axp(MpegEncContext *s, DCTELEM *block, int n, int qscale) diff --git a/contrib/ffmpeg/libavcodec/alpha/regdef.h b/contrib/ffmpeg/libavcodec/alpha/regdef.h index 01e263bac..aaa15e994 100644 --- a/contrib/ffmpeg/libavcodec/alpha/regdef.h +++ b/contrib/ffmpeg/libavcodec/alpha/regdef.h @@ -20,8 +20,8 @@ */ /* Some BSDs don't seem to have regdef.h... sigh */ -#ifndef alpha_regdef_h -#define alpha_regdef_h +#ifndef FFMPEG_REGDEF_H +#define FFMPEG_REGDEF_H #define v0 $0 /* function return value */ @@ -63,4 +63,4 @@ #define sp $30 /* stack pointer */ #define zero $31 /* reads as zero, writes are noops */ -#endif /* alpha_regdef_h */ +#endif /* FFMPEG_REGDEF_H */ diff --git a/contrib/ffmpeg/libavcodec/alpha/simple_idct_alpha.c b/contrib/ffmpeg/libavcodec/alpha/simple_idct_alpha.c index adadd3ab0..f664801f9 100644 --- a/contrib/ffmpeg/libavcodec/alpha/simple_idct_alpha.c +++ b/contrib/ffmpeg/libavcodec/alpha/simple_idct_alpha.c @@ -3,6 +3,12 @@ * * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> * + * based upon some outcommented C code from mpeg2dec (idct_mmx.c + * written by Aaron Holtzman <aholtzma@ess.engr.uvic.ca>) + * + * Alpha optimizations by MÃ¥ns RullgÃ¥rd <mans@mansr.com> + * and Falk Hueffner <falk@debian.org> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,16 +24,10 @@ * 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 - * - * based upon some outcommented c code from mpeg2dec (idct_mmx.c - * written by Aaron Holtzman <aholtzma@ess.engr.uvic.ca>) - * - * Alpha optimiziations by Måns Rullgård <mru@users.sourceforge.net> - * and Falk Hueffner <falk@debian.org> */ #include "asm.h" -#include "../dsputil.h" +#include "dsputil.h" extern void (*put_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels, int line_size); diff --git a/contrib/ffmpeg/libavcodec/apedec.c b/contrib/ffmpeg/libavcodec/apedec.c new file mode 100644 index 000000000..032bc7397 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/apedec.c @@ -0,0 +1,922 @@ +/* + * Monkey's Audio lossless audio decoder + * Copyright (c) 2007 Benjamin Zores <ben@geexbox.org> + * based upon libdemac from Dave Chapman. + * + * 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 + */ + +#define ALT_BITSTREAM_READER_LE +#include "avcodec.h" +#include "dsputil.h" +#include "bitstream.h" +#include "bytestream.h" + +/** + * @file apedec.c + * Monkey's Audio lossless audio decoder + */ + +#define BLOCKS_PER_LOOP 4608 +#define MAX_CHANNELS 2 +#define MAX_BYTESPERSAMPLE 3 + +#define APE_FRAMECODE_MONO_SILENCE 1 +#define APE_FRAMECODE_STEREO_SILENCE 3 +#define APE_FRAMECODE_PSEUDO_STEREO 4 + +#define HISTORY_SIZE 512 +#define PREDICTOR_ORDER 8 +/** Total size of all predictor histories */ +#define PREDICTOR_SIZE 50 + +#define YDELAYA (18 + PREDICTOR_ORDER*4) +#define YDELAYB (18 + PREDICTOR_ORDER*3) +#define XDELAYA (18 + PREDICTOR_ORDER*2) +#define XDELAYB (18 + PREDICTOR_ORDER) + +#define YADAPTCOEFFSA 18 +#define XADAPTCOEFFSA 14 +#define YADAPTCOEFFSB 10 +#define XADAPTCOEFFSB 5 + +/** + * Possible compression levels + * @{ + */ +enum APECompressionLevel { + COMPRESSION_LEVEL_FAST = 1000, + COMPRESSION_LEVEL_NORMAL = 2000, + COMPRESSION_LEVEL_HIGH = 3000, + COMPRESSION_LEVEL_EXTRA_HIGH = 4000, + COMPRESSION_LEVEL_INSANE = 5000 +}; +/** @} */ + +#define APE_FILTER_LEVELS 3 + +/** Filter orders depending on compression level */ +static const uint16_t ape_filter_orders[5][APE_FILTER_LEVELS] = { + { 0, 0, 0 }, + { 16, 0, 0 }, + { 64, 0, 0 }, + { 32, 256, 0 }, + { 16, 256, 1280 } +}; + +/** Filter fraction bits depending on compression level */ +static const uint16_t ape_filter_fracbits[5][APE_FILTER_LEVELS] = { + { 0, 0, 0 }, + { 11, 0, 0 }, + { 11, 0, 0 }, + { 10, 13, 0 }, + { 11, 13, 15 } +}; + + +/** Filters applied to the decoded data */ +typedef struct APEFilter { + int16_t *coeffs; ///< actual coefficients used in filtering + int16_t *adaptcoeffs; ///< adaptive filter coefficients used for correcting of actual filter coefficients + int16_t *historybuffer; ///< filter memory + int16_t *delay; ///< filtered values + + int avg; +} APEFilter; + +typedef struct APERice { + uint32_t k; + uint32_t ksum; +} APERice; + +typedef struct APERangecoder { + uint32_t low; ///< low end of interval + uint32_t range; ///< length of interval + uint32_t help; ///< bytes_to_follow resp. intermediate value + unsigned int buffer; ///< buffer for input/output +} APERangecoder; + +/** Filter histories */ +typedef struct APEPredictor { + int32_t *buf; + + int32_t lastA[2]; + + int32_t filterA[2]; + int32_t filterB[2]; + + int32_t coeffsA[2][4]; ///< adaption coefficients + int32_t coeffsB[2][5]; ///< adaption coefficients + int32_t historybuffer[HISTORY_SIZE + PREDICTOR_SIZE]; +} APEPredictor; + +/** Decoder context */ +typedef struct APEContext { + AVCodecContext *avctx; + DSPContext dsp; + int channels; + int samples; ///< samples left to decode in current frame + + int fileversion; ///< codec version, very important in decoding process + int compression_level; ///< compression levels + int fset; ///< which filter set to use (calculated from compression level) + int flags; ///< global decoder flags + + uint32_t CRC; ///< frame CRC + int frameflags; ///< frame flags + int currentframeblocks; ///< samples (per channel) in current frame + int blocksdecoded; ///< count of decoded samples in current frame + APEPredictor predictor; ///< predictor used for final reconstruction + + int32_t decoded0[BLOCKS_PER_LOOP]; ///< decoded data for the first channel + int32_t decoded1[BLOCKS_PER_LOOP]; ///< decoded data for the second channel + + int16_t* filterbuf[APE_FILTER_LEVELS]; ///< filter memory + + APERangecoder rc; ///< rangecoder used to decode actual values + APERice riceX; ///< rice code parameters for the second channel + APERice riceY; ///< rice code parameters for the first channel + APEFilter filters[APE_FILTER_LEVELS][2]; ///< filters used for reconstruction + + uint8_t *data; ///< current frame data + uint8_t *data_end; ///< frame data end + const uint8_t *ptr; ///< current position in frame data + const uint8_t *last_ptr; ///< position where last 4608-sample block ended +} APEContext; + +// TODO: dsputilize +static inline void vector_add(int16_t * v1, int16_t * v2, int order) +{ + while (order--) + *v1++ += *v2++; +} + +// TODO: dsputilize +static inline void vector_sub(int16_t * v1, int16_t * v2, int order) +{ + while (order--) + *v1++ -= *v2++; +} + +// TODO: dsputilize +static inline int32_t scalarproduct(int16_t * v1, int16_t * v2, int order) +{ + int res = 0; + + while (order--) + res += *v1++ * *v2++; + + return res; +} + +static int ape_decode_init(AVCodecContext * avctx) +{ + APEContext *s = avctx->priv_data; + int i; + + if (avctx->extradata_size != 6) { + av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n"); + return -1; + } + if (avctx->bits_per_sample != 16) { + av_log(avctx, AV_LOG_ERROR, "Only 16-bit samples are supported\n"); + return -1; + } + if (avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n"); + return -1; + } + s->avctx = avctx; + s->channels = avctx->channels; + s->fileversion = AV_RL16(avctx->extradata); + s->compression_level = AV_RL16(avctx->extradata + 2); + s->flags = AV_RL16(avctx->extradata + 4); + + av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", s->compression_level, s->flags); + if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE) { + av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", s->compression_level); + return -1; + } + s->fset = s->compression_level / 1000 - 1; + for (i = 0; i < APE_FILTER_LEVELS; i++) { + if (!ape_filter_orders[s->fset][i]) + break; + s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4); + } + + dsputil_init(&s->dsp, avctx); + return 0; +} + +static int ape_decode_close(AVCodecContext * avctx) +{ + APEContext *s = avctx->priv_data; + int i; + + for (i = 0; i < APE_FILTER_LEVELS; i++) + av_freep(&s->filterbuf[i]); + + return 0; +} + +/** + * @defgroup rangecoder APE range decoder + * @{ + */ + +#define CODE_BITS 32 +#define TOP_VALUE ((unsigned int)1 << (CODE_BITS-1)) +#define SHIFT_BITS (CODE_BITS - 9) +#define EXTRA_BITS ((CODE_BITS-2) % 8 + 1) +#define BOTTOM_VALUE (TOP_VALUE >> 8) + +/** Start the decoder */ +static inline void range_start_decoding(APEContext * ctx) +{ + ctx->rc.buffer = bytestream_get_byte(&ctx->ptr); + ctx->rc.low = ctx->rc.buffer >> (8 - EXTRA_BITS); + ctx->rc.range = (uint32_t) 1 << EXTRA_BITS; +} + +/** Perform normalization */ +static inline void range_dec_normalize(APEContext * ctx) +{ + while (ctx->rc.range <= BOTTOM_VALUE) { + ctx->rc.buffer = (ctx->rc.buffer << 8) | bytestream_get_byte(&ctx->ptr); + ctx->rc.low = (ctx->rc.low << 8) | ((ctx->rc.buffer >> 1) & 0xFF); + ctx->rc.range <<= 8; + } +} + +/** + * Calculate culmulative frequency for next symbol. Does NO update! + * @param tot_f is the total frequency or (code_value)1<<shift + * @return the culmulative frequency + */ +static inline int range_decode_culfreq(APEContext * ctx, int tot_f) +{ + range_dec_normalize(ctx); + ctx->rc.help = ctx->rc.range / tot_f; + return ctx->rc.low / ctx->rc.help; +} + +/** + * Decode value with given size in bits + * @param shift number of bits to decode + */ +static inline int range_decode_culshift(APEContext * ctx, int shift) +{ + range_dec_normalize(ctx); + ctx->rc.help = ctx->rc.range >> shift; + return ctx->rc.low / ctx->rc.help; +} + + +/** + * Update decoding state + * @param sy_f the interval length (frequency of the symbol) + * @param lt_f the lower end (frequency sum of < symbols) + */ +static inline void range_decode_update(APEContext * ctx, int sy_f, int lt_f) +{ + ctx->rc.low -= ctx->rc.help * lt_f; + ctx->rc.range = ctx->rc.help * sy_f; +} + +/** Decode n bits (n <= 16) without modelling */ +static inline int range_decode_bits(APEContext * ctx, int n) +{ + int sym = range_decode_culshift(ctx, n); + range_decode_update(ctx, 1, sym); + return sym; +} + + +#define MODEL_ELEMENTS 64 + +/** + * Fixed probabilities for symbols in Monkey Audio version 3.97 + */ +static const uint32_t counts_3970[65] = { + 0, 14824, 28224, 39348, 47855, 53994, 58171, 60926, + 62682, 63786, 64463, 64878, 65126, 65276, 65365, 65419, + 65450, 65469, 65480, 65487, 65491, 65493, 65494, 65495, + 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, + 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, + 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, + 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, + 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, + 65536 +}; + +/** + * Probability ranges for symbols in Monkey Audio version 3.97 + */ +static const uint16_t counts_diff_3970[64] = { + 14824, 13400, 11124, 8507, 6139, 4177, 2755, 1756, + 1104, 677, 415, 248, 150, 89, 54, 31, + 19, 11, 7, 4, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 +}; + +/** + * Fixed probabilities for symbols in Monkey Audio version 3.98 + */ +static const uint32_t counts_3980[65] = { + 0, 19578, 36160, 48417, 56323, 60899, 63265, 64435, + 64971, 65232, 65351, 65416, 65447, 65466, 65476, 65482, + 65485, 65488, 65490, 65491, 65492, 65493, 65494, 65495, + 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, + 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, + 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, + 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, + 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, + 65536 +}; + +/** + * Probability ranges for symbols in Monkey Audio version 3.98 + */ +static const uint16_t counts_diff_3980[64] = { + 19578, 16582, 12257, 7906, 4576, 2366, 1170, 536, + 261, 119, 65, 31, 19, 10, 6, 3, + 3, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 +}; + +/** + * Decode symbol + * @param counts probability range start position + * @param count_diffs probability range widths + */ +static inline int range_get_symbol(APEContext * ctx, + const uint32_t counts[], + const uint16_t counts_diff[]) +{ + int symbol, cf; + + cf = range_decode_culshift(ctx, 16); + + /* figure out the symbol inefficiently; a binary search would be much better */ + for (symbol = 0; counts[symbol + 1] <= cf; symbol++); + + range_decode_update(ctx, counts_diff[symbol], counts[symbol]); + + return symbol; +} +/** @} */ // group rangecoder + +static inline void update_rice(APERice *rice, int x) +{ + rice->ksum += ((x + 1) / 2) - ((rice->ksum + 16) >> 5); + + if (rice->k == 0) + rice->k = 1; + else if (rice->ksum < (1 << (rice->k + 4))) + rice->k--; + else if (rice->ksum >= (1 << (rice->k + 5))) + rice->k++; +} + +static inline int ape_decode_value(APEContext * ctx, APERice *rice) +{ + int x, overflow; + + if (ctx->fileversion < 3980) { + int tmpk; + + overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970); + + if (overflow == (MODEL_ELEMENTS - 1)) { + tmpk = range_decode_bits(ctx, 5); + overflow = 0; + } else + tmpk = (rice->k < 1) ? 0 : rice->k - 1; + + if (tmpk <= 16) + x = range_decode_bits(ctx, tmpk); + else { + x = range_decode_bits(ctx, 16); + x |= (range_decode_bits(ctx, tmpk - 16) << 16); + } + x += overflow << tmpk; + } else { + int base, pivot; + + pivot = rice->ksum >> 5; + if (pivot == 0) + pivot = 1; + + overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980); + + if (overflow == (MODEL_ELEMENTS - 1)) { + overflow = range_decode_bits(ctx, 16) << 16; + overflow |= range_decode_bits(ctx, 16); + } + + base = range_decode_culfreq(ctx, pivot); + range_decode_update(ctx, 1, base); + + x = base + overflow * pivot; + } + + update_rice(rice, x); + + /* Convert to signed */ + if (x & 1) + return (x >> 1) + 1; + else + return -(x >> 1); +} + +static void entropy_decode(APEContext * ctx, int blockstodecode, int stereo) +{ + int32_t *decoded0 = ctx->decoded0; + int32_t *decoded1 = ctx->decoded1; + + ctx->blocksdecoded = blockstodecode; + + if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { + /* We are pure silence, just memset the output buffer. */ + memset(decoded0, 0, blockstodecode * sizeof(int32_t)); + memset(decoded1, 0, blockstodecode * sizeof(int32_t)); + } else { + while (blockstodecode--) { + *decoded0++ = ape_decode_value(ctx, &ctx->riceY); + if (stereo) + *decoded1++ = ape_decode_value(ctx, &ctx->riceX); + } + } + + if (ctx->blocksdecoded == ctx->currentframeblocks) + range_dec_normalize(ctx); /* normalize to use up all bytes */ +} + +static void init_entropy_decoder(APEContext * ctx) +{ + /* Read the CRC */ + ctx->CRC = bytestream_get_be32(&ctx->ptr); + + /* Read the frame flags if they exist */ + ctx->frameflags = 0; + if ((ctx->fileversion > 3820) && (ctx->CRC & 0x80000000)) { + ctx->CRC &= ~0x80000000; + + ctx->frameflags = bytestream_get_be32(&ctx->ptr); + } + + /* Keep a count of the blocks decoded in this frame */ + ctx->blocksdecoded = 0; + + /* Initialize the rice structs */ + ctx->riceX.k = 10; + ctx->riceX.ksum = (1 << ctx->riceX.k) * 16; + ctx->riceY.k = 10; + ctx->riceY.ksum = (1 << ctx->riceY.k) * 16; + + /* The first 8 bits of input are ignored. */ + ctx->ptr++; + + range_start_decoding(ctx); +} + +static const int32_t initial_coeffs[4] = { + 360, 317, -109, 98 +}; + +static void init_predictor_decoder(APEContext * ctx) +{ + APEPredictor *p = &ctx->predictor; + + /* Zero the history buffers */ + memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(int32_t)); + p->buf = p->historybuffer; + + /* Initialize and zero the coefficients */ + memcpy(p->coeffsA[0], initial_coeffs, sizeof(initial_coeffs)); + memcpy(p->coeffsA[1], initial_coeffs, sizeof(initial_coeffs)); + memset(p->coeffsB, 0, sizeof(p->coeffsB)); + + p->filterA[0] = p->filterA[1] = 0; + p->filterB[0] = p->filterB[1] = 0; + p->lastA[0] = p->lastA[1] = 0; +} + +/** Get inverse sign of integer (-1 for positive, 1 for negative and 0 for zero) */ +static inline int APESIGN(int32_t x) { + return (x < 0) - (x > 0); +} + +static int predictor_update_filter(APEPredictor *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB) +{ + int32_t predictionA, predictionB; + + p->buf[delayA] = p->lastA[filter]; + p->buf[adaptA] = APESIGN(p->buf[delayA]); + p->buf[delayA - 1] = p->buf[delayA] - p->buf[delayA - 1]; + p->buf[adaptA - 1] = APESIGN(p->buf[delayA - 1]); + + predictionA = p->buf[delayA ] * p->coeffsA[filter][0] + + p->buf[delayA - 1] * p->coeffsA[filter][1] + + p->buf[delayA - 2] * p->coeffsA[filter][2] + + p->buf[delayA - 3] * p->coeffsA[filter][3]; + + /* Apply a scaled first-order filter compression */ + p->buf[delayB] = p->filterA[filter ^ 1] - ((p->filterB[filter] * 31) >> 5); + p->buf[adaptB] = APESIGN(p->buf[delayB]); + p->buf[delayB - 1] = p->buf[delayB] - p->buf[delayB - 1]; + p->buf[adaptB - 1] = APESIGN(p->buf[delayB - 1]); + p->filterB[filter] = p->filterA[filter ^ 1]; + + predictionB = p->buf[delayB ] * p->coeffsB[filter][0] + + p->buf[delayB - 1] * p->coeffsB[filter][1] + + p->buf[delayB - 2] * p->coeffsB[filter][2] + + p->buf[delayB - 3] * p->coeffsB[filter][3] + + p->buf[delayB - 4] * p->coeffsB[filter][4]; + + p->lastA[filter] = decoded + ((predictionA + (predictionB >> 1)) >> 10); + p->filterA[filter] = p->lastA[filter] + ((p->filterA[filter] * 31) >> 5); + + if (!decoded) // no need updating filter coefficients + return p->filterA[filter]; + + if (decoded > 0) { + p->coeffsA[filter][0] -= p->buf[adaptA ]; + p->coeffsA[filter][1] -= p->buf[adaptA - 1]; + p->coeffsA[filter][2] -= p->buf[adaptA - 2]; + p->coeffsA[filter][3] -= p->buf[adaptA - 3]; + + p->coeffsB[filter][0] -= p->buf[adaptB ]; + p->coeffsB[filter][1] -= p->buf[adaptB - 1]; + p->coeffsB[filter][2] -= p->buf[adaptB - 2]; + p->coeffsB[filter][3] -= p->buf[adaptB - 3]; + p->coeffsB[filter][4] -= p->buf[adaptB - 4]; + } else { + p->coeffsA[filter][0] += p->buf[adaptA ]; + p->coeffsA[filter][1] += p->buf[adaptA - 1]; + p->coeffsA[filter][2] += p->buf[adaptA - 2]; + p->coeffsA[filter][3] += p->buf[adaptA - 3]; + + p->coeffsB[filter][0] += p->buf[adaptB ]; + p->coeffsB[filter][1] += p->buf[adaptB - 1]; + p->coeffsB[filter][2] += p->buf[adaptB - 2]; + p->coeffsB[filter][3] += p->buf[adaptB - 3]; + p->coeffsB[filter][4] += p->buf[adaptB - 4]; + } + return p->filterA[filter]; +} + +static void predictor_decode_stereo(APEContext * ctx, int count) +{ + int32_t predictionA, predictionB; + APEPredictor *p = &ctx->predictor; + int32_t *decoded0 = ctx->decoded0; + int32_t *decoded1 = ctx->decoded1; + + while (count--) { + /* Predictor Y */ + predictionA = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, YADAPTCOEFFSA, YADAPTCOEFFSB); + predictionB = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, XADAPTCOEFFSA, XADAPTCOEFFSB); + *(decoded0++) = predictionA; + *(decoded1++) = predictionB; + + /* Combined */ + p->buf++; + + /* Have we filled the history buffer? */ + if (p->buf == p->historybuffer + HISTORY_SIZE) { + memmove(p->historybuffer, p->buf, PREDICTOR_SIZE * sizeof(int32_t)); + p->buf = p->historybuffer; + } + } +} + +static void predictor_decode_mono(APEContext * ctx, int count) +{ + APEPredictor *p = &ctx->predictor; + int32_t *decoded0 = ctx->decoded0; + int32_t predictionA, currentA, A; + + currentA = p->lastA[0]; + + while (count--) { + A = *decoded0; + + p->buf[YDELAYA] = currentA; + p->buf[YDELAYA - 1] = p->buf[YDELAYA] - p->buf[YDELAYA - 1]; + + predictionA = p->buf[YDELAYA ] * p->coeffsA[0][0] + + p->buf[YDELAYA - 1] * p->coeffsA[0][1] + + p->buf[YDELAYA - 2] * p->coeffsA[0][2] + + p->buf[YDELAYA - 3] * p->coeffsA[0][3]; + + currentA = A + (predictionA >> 10); + + p->buf[YADAPTCOEFFSA] = APESIGN(p->buf[YDELAYA ]); + p->buf[YADAPTCOEFFSA - 1] = APESIGN(p->buf[YDELAYA - 1]); + + if (A > 0) { + p->coeffsA[0][0] -= p->buf[YADAPTCOEFFSA ]; + p->coeffsA[0][1] -= p->buf[YADAPTCOEFFSA - 1]; + p->coeffsA[0][2] -= p->buf[YADAPTCOEFFSA - 2]; + p->coeffsA[0][3] -= p->buf[YADAPTCOEFFSA - 3]; + } else if (A < 0) { + p->coeffsA[0][0] += p->buf[YADAPTCOEFFSA ]; + p->coeffsA[0][1] += p->buf[YADAPTCOEFFSA - 1]; + p->coeffsA[0][2] += p->buf[YADAPTCOEFFSA - 2]; + p->coeffsA[0][3] += p->buf[YADAPTCOEFFSA - 3]; + } + + p->buf++; + + /* Have we filled the history buffer? */ + if (p->buf == p->historybuffer + HISTORY_SIZE) { + memmove(p->historybuffer, p->buf, PREDICTOR_SIZE * sizeof(int32_t)); + p->buf = p->historybuffer; + } + + p->filterA[0] = currentA + ((p->filterA[0] * 31) >> 5); + *(decoded0++) = p->filterA[0]; + } + + p->lastA[0] = currentA; +} + +static void do_init_filter(APEFilter *f, int16_t * buf, int order) +{ + f->coeffs = buf; + f->historybuffer = buf + order; + f->delay = f->historybuffer + order * 2; + f->adaptcoeffs = f->historybuffer + order; + + memset(f->historybuffer, 0, (order * 2) * sizeof(int16_t)); + memset(f->coeffs, 0, order * sizeof(int16_t)); + f->avg = 0; +} + +static void init_filter(APEContext * ctx, APEFilter *f, int16_t * buf, int order) +{ + do_init_filter(&f[0], buf, order); + do_init_filter(&f[1], buf + order * 3 + HISTORY_SIZE, order); +} + +static inline void do_apply_filter(int version, APEFilter *f, int32_t *data, int count, int order, int fracbits) +{ + int res; + int absres; + + while (count--) { + /* round fixedpoint scalar product */ + res = (scalarproduct(f->delay - order, f->coeffs, order) + (1 << (fracbits - 1))) >> fracbits; + + if (*data < 0) + vector_add(f->coeffs, f->adaptcoeffs - order, order); + else if (*data > 0) + vector_sub(f->coeffs, f->adaptcoeffs - order, order); + + res += *data; + + *data++ = res; + + /* Update the output history */ + *f->delay++ = av_clip_int16(res); + + if (version < 3980) { + /* Version ??? to < 3.98 files (untested) */ + f->adaptcoeffs[0] = (res == 0) ? 0 : ((res >> 28) & 8) - 4; + f->adaptcoeffs[-4] >>= 1; + f->adaptcoeffs[-8] >>= 1; + } else { + /* Version 3.98 and later files */ + + /* Update the adaption coefficients */ + absres = (res < 0 ? -res : res); + + if (absres > (f->avg * 3)) + *f->adaptcoeffs = ((res >> 25) & 64) - 32; + else if (absres > (f->avg * 4) / 3) + *f->adaptcoeffs = ((res >> 26) & 32) - 16; + else if (absres > 0) + *f->adaptcoeffs = ((res >> 27) & 16) - 8; + else + *f->adaptcoeffs = 0; + + f->avg += (absres - f->avg) / 16; + + f->adaptcoeffs[-1] >>= 1; + f->adaptcoeffs[-2] >>= 1; + f->adaptcoeffs[-8] >>= 1; + } + + f->adaptcoeffs++; + + /* Have we filled the history buffer? */ + if (f->delay == f->historybuffer + HISTORY_SIZE + (order * 2)) { + memmove(f->historybuffer, f->delay - (order * 2), + (order * 2) * sizeof(int16_t)); + f->delay = f->historybuffer + order * 2; + f->adaptcoeffs = f->historybuffer + order; + } + } +} + +static void apply_filter(APEContext * ctx, APEFilter *f, + int32_t * data0, int32_t * data1, + int count, int order, int fracbits) +{ + do_apply_filter(ctx->fileversion, &f[0], data0, count, order, fracbits); + if (data1) + do_apply_filter(ctx->fileversion, &f[1], data1, count, order, fracbits); +} + +static void ape_apply_filters(APEContext * ctx, int32_t * decoded0, + int32_t * decoded1, int count) +{ + int i; + + for (i = 0; i < APE_FILTER_LEVELS; i++) { + if (!ape_filter_orders[ctx->fset][i]) + break; + apply_filter(ctx, ctx->filters[i], decoded0, decoded1, count, ape_filter_orders[ctx->fset][i], ape_filter_fracbits[ctx->fset][i]); + } +} + +static void init_frame_decoder(APEContext * ctx) +{ + int i; + init_entropy_decoder(ctx); + init_predictor_decoder(ctx); + + for (i = 0; i < APE_FILTER_LEVELS; i++) { + if (!ape_filter_orders[ctx->fset][i]) + break; + init_filter(ctx, ctx->filters[i], ctx->filterbuf[i], ape_filter_orders[ctx->fset][i]); + } +} + +static void ape_unpack_mono(APEContext * ctx, int count) +{ + int32_t left; + int32_t *decoded0 = ctx->decoded0; + int32_t *decoded1 = ctx->decoded1; + + if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { + entropy_decode(ctx, count, 0); + /* We are pure silence, so we're done. */ + av_log(ctx->avctx, AV_LOG_DEBUG, "pure silence mono\n"); + return; + } + + entropy_decode(ctx, count, 0); + ape_apply_filters(ctx, decoded0, NULL, count); + + /* Now apply the predictor decoding */ + predictor_decode_mono(ctx, count); + + /* Pseudo-stereo - just copy left channel to right channel */ + if (ctx->channels == 2) { + while (count--) { + left = *decoded0; + *(decoded1++) = *(decoded0++) = left; + } + } +} + +static void ape_unpack_stereo(APEContext * ctx, int count) +{ + int32_t left, right; + int32_t *decoded0 = ctx->decoded0; + int32_t *decoded1 = ctx->decoded1; + + if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { + /* We are pure silence, so we're done. */ + av_log(ctx->avctx, AV_LOG_DEBUG, "pure silence stereo\n"); + return; + } + + entropy_decode(ctx, count, 1); + ape_apply_filters(ctx, decoded0, decoded1, count); + + /* Now apply the predictor decoding */ + predictor_decode_stereo(ctx, count); + + /* Decorrelate and scale to output depth */ + while (count--) { + left = *decoded1 - (*decoded0 / 2); + right = left + *decoded0; + + *(decoded0++) = left; + *(decoded1++) = right; + } +} + +static int ape_decode_frame(AVCodecContext * avctx, + void *data, int *data_size, + const uint8_t * buf, int buf_size) +{ + APEContext *s = avctx->priv_data; + int16_t *samples = data; + int nblocks; + int i, n; + int blockstodecode; + int bytes_used; + + if (buf_size == 0 && !s->samples) { + *data_size = 0; + return 0; + } + + /* should not happen but who knows */ + if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) { + av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc! (max is %d where you have %d)\n", *data_size, s->samples * 2 * avctx->channels); + return -1; + } + + if(!s->samples){ + s->data = av_realloc(s->data, (buf_size + 3) & ~3); + s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2); + s->ptr = s->last_ptr = s->data; + s->data_end = s->data + buf_size; + + nblocks = s->samples = bytestream_get_be32(&s->ptr); + n = bytestream_get_be32(&s->ptr); + if(n < 0 || n > 3){ + av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n"); + s->data = NULL; + return -1; + } + s->ptr += n; + + s->currentframeblocks = nblocks; + buf += 4; + if (s->samples <= 0) { + *data_size = 0; + return buf_size; + } + + memset(s->decoded0, 0, sizeof(s->decoded0)); + memset(s->decoded1, 0, sizeof(s->decoded1)); + + /* Initialize the frame decoder */ + init_frame_decoder(s); + } + + if (!s->data) { + *data_size = 0; + return buf_size; + } + + nblocks = s->samples; + blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks); + + if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO)) + ape_unpack_mono(s, blockstodecode); + else + ape_unpack_stereo(s, blockstodecode); + + for (i = 0; i < blockstodecode; i++) { + *samples++ = s->decoded0[i]; + if(s->channels == 2) + *samples++ = s->decoded1[i]; + } + + s->samples -= blockstodecode; + + *data_size = blockstodecode * 2 * s->channels; + bytes_used = s->samples ? s->ptr - s->last_ptr : buf_size; + s->last_ptr = s->ptr; + return bytes_used; +} + +AVCodec ape_decoder = { + "ape", + CODEC_TYPE_AUDIO, + CODEC_ID_APE, + sizeof(APEContext), + ape_decode_init, + NULL, + ape_decode_close, + ape_decode_frame, +}; diff --git a/contrib/ffmpeg/libavcodec/apiexample.c b/contrib/ffmpeg/libavcodec/apiexample.c index 151637bd2..793cfaa04 100644 --- a/contrib/ffmpeg/libavcodec/apiexample.c +++ b/contrib/ffmpeg/libavcodec/apiexample.c @@ -336,11 +336,11 @@ void video_decode_example(const char *outfilename, const char *filename) picture= avcodec_alloc_frame(); if(codec->capabilities&CODEC_CAP_TRUNCATED) - c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */ + c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */ - /* for some codecs, such as msmpeg4 and mpeg4, width and height - MUST be initialized there because these info are not available - in the bitstream */ + /* For some codecs, such as msmpeg4 and mpeg4, width and height + MUST be initialized there because this information is not + available in the bitstream. */ /* open it */ if (avcodec_open(c, codec) < 0) { @@ -433,8 +433,7 @@ int main(int argc, char **argv) /* must be called before using avcodec lib */ avcodec_init(); - /* register all the codecs (you can also register only the codec - you wish to have smaller code */ + /* register all the codecs */ avcodec_register_all(); if (argc <= 1) { diff --git a/contrib/ffmpeg/libavcodec/armv4l/dsputil_arm.c b/contrib/ffmpeg/libavcodec/armv4l/dsputil_arm.c index 61b5fdacc..47daec7a6 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/dsputil_arm.c +++ b/contrib/ffmpeg/libavcodec/armv4l/dsputil_arm.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" #ifdef HAVE_IPP #include "ipp.h" #endif @@ -209,67 +209,69 @@ void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx) ff_put_pixels_clamped = c->put_pixels_clamped; ff_add_pixels_clamped = c->add_pixels_clamped; - if(idct_algo == FF_IDCT_AUTO){ + if (avctx->lowres == 0) { + if(idct_algo == FF_IDCT_AUTO){ #if defined(HAVE_IPP) - idct_algo = FF_IDCT_IPP; + idct_algo = FF_IDCT_IPP; #elif defined(HAVE_ARMV6) - idct_algo = FF_IDCT_SIMPLEARMV6; + idct_algo = FF_IDCT_SIMPLEARMV6; #elif defined(HAVE_ARMV5TE) - idct_algo = FF_IDCT_SIMPLEARMV5TE; + idct_algo = FF_IDCT_SIMPLEARMV5TE; #else - idct_algo = FF_IDCT_ARM; + idct_algo = FF_IDCT_ARM; #endif - } + } - if(idct_algo==FF_IDCT_ARM){ - c->idct_put= j_rev_dct_ARM_put; - c->idct_add= j_rev_dct_ARM_add; - c->idct = j_rev_dct_ARM; - c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;/* FF_NO_IDCT_PERM */ - } else if (idct_algo==FF_IDCT_SIMPLEARM){ - c->idct_put= simple_idct_ARM_put; - c->idct_add= simple_idct_ARM_add; - c->idct = simple_idct_ARM; - c->idct_permutation_type= FF_NO_IDCT_PERM; + if(idct_algo==FF_IDCT_ARM){ + c->idct_put= j_rev_dct_ARM_put; + c->idct_add= j_rev_dct_ARM_add; + c->idct = j_rev_dct_ARM; + c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;/* FF_NO_IDCT_PERM */ + } else if (idct_algo==FF_IDCT_SIMPLEARM){ + c->idct_put= simple_idct_ARM_put; + c->idct_add= simple_idct_ARM_add; + c->idct = simple_idct_ARM; + c->idct_permutation_type= FF_NO_IDCT_PERM; #ifdef HAVE_ARMV6 - } else if (idct_algo==FF_IDCT_SIMPLEARMV6){ - c->idct_put= ff_simple_idct_put_armv6; - c->idct_add= ff_simple_idct_add_armv6; - c->idct = ff_simple_idct_armv6; - c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; + } else if (idct_algo==FF_IDCT_SIMPLEARMV6){ + c->idct_put= ff_simple_idct_put_armv6; + c->idct_add= ff_simple_idct_add_armv6; + c->idct = ff_simple_idct_armv6; + c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; #endif #ifdef HAVE_ARMV5TE - } else if (idct_algo==FF_IDCT_SIMPLEARMV5TE){ - c->idct_put= simple_idct_put_armv5te; - c->idct_add= simple_idct_add_armv5te; - c->idct = simple_idct_armv5te; - c->idct_permutation_type = FF_NO_IDCT_PERM; + } else if (idct_algo==FF_IDCT_SIMPLEARMV5TE){ + c->idct_put= simple_idct_put_armv5te; + c->idct_add= simple_idct_add_armv5te; + c->idct = simple_idct_armv5te; + c->idct_permutation_type = FF_NO_IDCT_PERM; #endif #ifdef HAVE_IPP - } else if (idct_algo==FF_IDCT_IPP){ - c->idct_put= simple_idct_ipp_put; - c->idct_add= simple_idct_ipp_add; - c->idct = simple_idct_ipp; - c->idct_permutation_type= FF_NO_IDCT_PERM; + } else if (idct_algo==FF_IDCT_IPP){ + c->idct_put= simple_idct_ipp_put; + c->idct_add= simple_idct_ipp_add; + c->idct = simple_idct_ipp; + c->idct_permutation_type= FF_NO_IDCT_PERM; #endif + } } -/* c->put_pixels_tab[0][0] = put_pixels16_arm; */ // NG! + c->put_pixels_tab[0][0] = put_pixels16_arm; c->put_pixels_tab[0][1] = put_pixels16_x2_arm; //OK! c->put_pixels_tab[0][2] = put_pixels16_y2_arm; //OK! -/* c->put_pixels_tab[0][3] = put_pixels16_xy2_arm; /\* NG *\/ */ -/* c->put_no_rnd_pixels_tab[0][0] = put_pixels16_arm; */ + c->put_pixels_tab[0][3] = put_pixels16_xy2_arm; + c->put_no_rnd_pixels_tab[0][0] = put_pixels16_arm; c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_arm; // OK c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_arm; //OK -/* c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_arm; //NG */ + c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_arm; c->put_pixels_tab[1][0] = put_pixels8_arm; //OK c->put_pixels_tab[1][1] = put_pixels8_x2_arm; //OK -/* c->put_pixels_tab[1][2] = put_pixels8_y2_arm; //NG */ -/* c->put_pixels_tab[1][3] = put_pixels8_xy2_arm; //NG */ + c->put_pixels_tab[1][2] = put_pixels8_y2_arm; + c->put_pixels_tab[1][3] = put_pixels8_xy2_arm; c->put_no_rnd_pixels_tab[1][0] = put_pixels8_arm;//OK c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_arm; //OK c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_arm; //OK -/* c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_arm;//NG */ + c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_arm; #ifdef HAVE_IWMMXT dsputil_init_iwmmxt(c, avctx); diff --git a/contrib/ffmpeg/libavcodec/armv4l/dsputil_arm_s.S b/contrib/ffmpeg/libavcodec/armv4l/dsputil_arm_s.S index 2a3ee9c50..56ffc04e7 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/dsputil_arm_s.S +++ b/contrib/ffmpeg/libavcodec/armv4l/dsputil_arm_s.S @@ -553,7 +553,7 @@ put_no_rnd_pixels8_y2_arm: .word 4b @ ---------------------------------------------------------------- -.macro RND_XY2_IT align, rnd +.macro RND_XY2_IT align @ l1= (a & 0x03030303) + (b & 0x03030303) ?(+ 0x02020202) @ h1= ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2) .if \align == 0 @@ -582,11 +582,7 @@ put_no_rnd_pixels8_y2_arm: and r9, r5, r14 and r10, r6, r14 and r11, r7, r14 -.if \rnd == 1 - ldreq r14, [r12, #16] @ 0x02020202 -.else - ldreq r14, [r12, #28] @ 0x01010101 -.endif + ldreq r14, [r12, #16] @ 0x02020202/0x01010101 add r8, r8, r10 add r9, r9, r11 addeq r8, r8, r14 @@ -598,12 +594,13 @@ put_no_rnd_pixels8_y2_arm: and r7, r14, r7, lsr #2 add r10, r4, r6 add r11, r5, r7 + subs r3, r3, #1 .endm -.macro RND_XY2_EXPAND align, rnd - RND_XY2_IT \align, \rnd +.macro RND_XY2_EXPAND align + RND_XY2_IT \align 6: stmfd sp!, {r8-r11} - RND_XY2_IT \align, \rnd + RND_XY2_IT \align ldmfd sp!, {r4-r7} add r4, r4, r8 add r5, r5, r9 @@ -614,10 +611,9 @@ put_no_rnd_pixels8_y2_arm: and r5, r14, r5, lsr #2 add r4, r4, r6 add r5, r5, r7 - subs r3, r3, #1 stmia r0, {r4-r5} add r0, r0, r2 - bne 6b + bge 6b ldmfd sp!, {r4-r11,pc} .endm @@ -634,19 +630,19 @@ put_pixels8_xy2_arm: bic r1, r1, #3 ldrne pc, [r5] 1: - RND_XY2_EXPAND 0, 1 + RND_XY2_EXPAND 0 .align 8 2: - RND_XY2_EXPAND 1, 1 + RND_XY2_EXPAND 1 .align 8 3: - RND_XY2_EXPAND 2, 1 + RND_XY2_EXPAND 2 .align 8 4: - RND_XY2_EXPAND 3, 1 + RND_XY2_EXPAND 3 5: .word 0x03030303 @@ -656,7 +652,6 @@ put_pixels8_xy2_arm: .word 0x02020202 .word 0xFCFCFCFC >> 2 .word 0x0F0F0F0F - .word 0x01010101 .align 8 .global put_no_rnd_pixels8_xy2_arm @@ -671,26 +666,25 @@ put_no_rnd_pixels8_xy2_arm: bic r1, r1, #3 ldrne pc, [r5] 1: - RND_XY2_EXPAND 0, 0 + RND_XY2_EXPAND 0 .align 8 2: - RND_XY2_EXPAND 1, 0 + RND_XY2_EXPAND 1 .align 8 3: - RND_XY2_EXPAND 2, 0 + RND_XY2_EXPAND 2 .align 8 4: - RND_XY2_EXPAND 3, 0 + RND_XY2_EXPAND 3 5: .word 0x03030303 .word 2b .word 3b .word 4b - .word 0x02020202 + .word 0x01010101 .word 0xFCFCFCFC >> 2 .word 0x0F0F0F0F - .word 0x01010101 diff --git a/contrib/ffmpeg/libavcodec/armv4l/dsputil_iwmmxt.c b/contrib/ffmpeg/libavcodec/armv4l/dsputil_iwmmxt.c index 7536100ee..18329ddf6 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/dsputil_iwmmxt.c +++ b/contrib/ffmpeg/libavcodec/armv4l/dsputil_iwmmxt.c @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" #define DEF(x, y) x ## _no_rnd_ ## y ##_iwmmxt #define SET_RND(regd) __asm__ __volatile__ ("mov r12, #1 \n\t tbcsth " #regd ", r12":::"r12"); @@ -123,6 +123,25 @@ void add_pixels_clamped_iwmmxt(const DCTELEM *block, uint8_t *pixels, int line_s : "cc", "memory", "r12"); } +static void clear_blocks_iwmmxt(DCTELEM *blocks) +{ + asm volatile( + "wzero wr0 \n\t" + "mov r1, #(128 * 6 / 32) \n\t" + "1: \n\t" + "wstrd wr0, [%0] \n\t" + "wstrd wr0, [%0, #8] \n\t" + "wstrd wr0, [%0, #16] \n\t" + "wstrd wr0, [%0, #24] \n\t" + "subs r1, r1, #1 \n\t" + "add %0, %0, #32 \n\t" + "bne 1b \n\t" + : "+r"(blocks) + : + : "r1" + ); +} + static void nop(uint8_t *block, const uint8_t *pixels, int line_size, int h) { return; @@ -146,6 +165,8 @@ void dsputil_init_iwmmxt(DSPContext* c, AVCodecContext *avctx) c->add_pixels_clamped = add_pixels_clamped_iwmmxt; + c->clear_blocks = clear_blocks_iwmmxt; + c->put_pixels_tab[0][0] = put_pixels16_iwmmxt; c->put_pixels_tab[0][1] = put_pixels16_x2_iwmmxt; c->put_pixels_tab[0][2] = put_pixels16_y2_iwmmxt; diff --git a/contrib/ffmpeg/libavcodec/armv4l/dsputil_iwmmxt_rnd.h b/contrib/ffmpeg/libavcodec/armv4l/dsputil_iwmmxt_rnd.h index 51ba61c47..f7151c7c6 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/dsputil_iwmmxt_rnd.h +++ b/contrib/ffmpeg/libavcodec/armv4l/dsputil_iwmmxt_rnd.h @@ -19,6 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/* This header intentionally has no multiple inclusion guards. It is meant to + * be included multiple times and generates different code depending on the + * value of certain #defines. */ + void DEF(put, pixels8)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) { int stride = line_size; diff --git a/contrib/ffmpeg/libavcodec/armv4l/mathops.h b/contrib/ffmpeg/libavcodec/armv4l/mathops.h index 7ddd0ec6e..cc097c3ff 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/mathops.h +++ b/contrib/ffmpeg/libavcodec/armv4l/mathops.h @@ -19,6 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_ARMV4L_MATHOPS_H +#define FFMPEG_ARMV4L_MATHOPS_H + #ifdef FRAC_BITS # define MULL(a, b) \ ({ int lo, hi;\ @@ -47,3 +50,5 @@ __rt; }) #endif + +#endif /* FFMPEG_ARMV4L_MATHOPS_H */ diff --git a/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_arm.c b/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_arm.c index 22d40d8bc..0aca43557 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_arm.c +++ b/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_arm.c @@ -16,12 +16,11 @@ * 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 "../dsputil.h" -#include "../mpegvideo.h" -#include "../avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "avcodec.h" extern void MPV_common_init_iwmmxt(MpegEncContext *s); extern void MPV_common_init_armv5te(MpegEncContext *s); @@ -29,7 +28,7 @@ extern void MPV_common_init_armv5te(MpegEncContext *s); void MPV_common_init_armv4l(MpegEncContext *s) { /* IWMMXT support is a superset of armv5te, so - * allow optimised functions for armv5te unless + * allow optimized functions for armv5te unless * a better iwmmxt function exists */ #ifdef HAVE_ARMV5TE diff --git a/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_armv5te.c b/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_armv5te.c index 5e83c8a43..4322b19f2 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_armv5te.c +++ b/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_armv5te.c @@ -19,15 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/* - * Some useful links for those who may be interested in optimizing code for ARM. - * ARM Architecture Reference Manual: http://www.arm.com/community/academy/resources.html - * Instructions timings and optimization guide for ARM9E: http://www.arm.com/pdfs/DDI0222B_9EJS_r1p2.pdf - */ - -#include "../dsputil.h" -#include "../mpegvideo.h" -#include "../avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "avcodec.h" #ifdef ENABLE_ARM_TESTS @@ -158,7 +152,7 @@ __asm__ __volatile__( \ static void dct_unquantize_h263_intra_armv5te(MpegEncContext *s, DCTELEM *block, int n, int qscale) { - int i, level, qmul, qadd; + int level, qmul, qadd; int nCoeffs; assert(s->block_last_index[n]>=0); @@ -187,7 +181,7 @@ static void dct_unquantize_h263_intra_armv5te(MpegEncContext *s, static void dct_unquantize_h263_inter_armv5te(MpegEncContext *s, DCTELEM *block, int n, int qscale) { - int i, level, qmul, qadd; + int qmul, qadd; int nCoeffs; assert(s->block_last_index[n]>=0); diff --git a/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_iwmmxt.c b/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_iwmmxt.c index 1336ac5f8..9e1121391 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_iwmmxt.c +++ b/contrib/ffmpeg/libavcodec/armv4l/mpegvideo_iwmmxt.c @@ -18,9 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" -#include "../mpegvideo.h" -#include "../avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "avcodec.h" static void dct_unquantize_h263_intra_iwmmxt(MpegEncContext *s, DCTELEM *block, int n, int qscale) diff --git a/contrib/ffmpeg/libavcodec/armv4l/simple_idct_arm.S b/contrib/ffmpeg/libavcodec/armv4l/simple_idct_arm.S index b5a20f6da..98e900970 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/simple_idct_arm.S +++ b/contrib/ffmpeg/libavcodec/armv4l/simple_idct_arm.S @@ -1,10 +1,12 @@ /* * simple_idct_arm.S * Copyright (C) 2002 Frederic 'dilb' Boulay. - * All Rights Reserved. * * Author: Frederic Boulay <dilb@handhelds.org> * + * The function defined in this file is derived from the simple_idct function + * from the libavcodec library part of the FFmpeg project. + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -20,9 +22,6 @@ * 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 - * - * The function defined in this file, is derived from the simple_idct function - * from the libavcodec library part of the ffmpeg project. */ /* useful constants for the algorithm, they are save in __constant_ptr__ at */ @@ -80,7 +79,7 @@ simple_idct_ARM: __row_loop: - @@ read the row and check if it is null, almost null, or not, according to strongarm specs, it is not necessary to optimise ldr accesses (i.e. split 32bits in 2 16bits words), at least it gives more usable registers :) + @@ read the row and check if it is null, almost null, or not, according to strongarm specs, it is not necessary to optimize ldr accesses (i.e. split 32bits in 2 16bits words), at least it gives more usable registers :) ldr r1, [r14, #0] @ R1=(int32)(R12)[0]=ROWr32[0] (relative row cast to a 32b pointer) ldr r2, [r14, #4] @ R2=(int32)(R12)[1]=ROWr32[1] ldr r3, [r14, #8] @ R3=ROWr32[2] @@ -422,7 +421,7 @@ __end_a_evaluation2: @@ col[40] = ((a2 - b2) >> COL_SHIFT); @@ col[48] = ((a1 - b1) >> COL_SHIFT); @@ col[56] = ((a0 - b0) >> COL_SHIFT); - @@@@@ no optimisation here @@@@@ + @@@@@ no optimization here @@@@@ add r8, r6, r0 @ R8=a0+b0 add r9, r2, r1 @ R9=a1+b1 mov r8, r8, asr #COL_SHIFT diff --git a/contrib/ffmpeg/libavcodec/armv4l/simple_idct_armv5te.S b/contrib/ffmpeg/libavcodec/armv4l/simple_idct_armv5te.S index 28bee0643..8add33127 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/simple_idct_armv5te.S +++ b/contrib/ffmpeg/libavcodec/armv4l/simple_idct_armv5te.S @@ -2,7 +2,7 @@ * Simple IDCT * * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> - * Copyright (c) 2006 Mans Rullgard <mru@inprovide.com> + * Copyright (c) 2006 Mans Rullgard <mans@mansr.com> * * This file is part of FFmpeg. * @@ -42,6 +42,7 @@ w26: .long W26 w57: .long W57 .align + .type idct_row_armv5te, %function .func idct_row_armv5te idct_row_armv5te: str lr, [sp, #-4]! @@ -262,6 +263,7 @@ row_dc_only: .endm .align + .type idct_col_armv5te, %function .func idct_col_armv5te idct_col_armv5te: str lr, [sp, #-4]! @@ -336,6 +338,7 @@ idct_col_armv5te: .endfunc .align + .type idct_col_put_armv5te, %function .func idct_col_put_armv5te idct_col_put_armv5te: str lr, [sp, #-4]! @@ -455,6 +458,7 @@ idct_col_put_armv5te: .endfunc .align + .type idct_col_add_armv5te, %function .func idct_col_add_armv5te idct_col_add_armv5te: str lr, [sp, #-4]! @@ -608,6 +612,7 @@ idct_col_add_armv5te: .align .global simple_idct_armv5te + .type simple_idct_armv5te, %function .func simple_idct_armv5te simple_idct_armv5te: stmfd sp!, {v1, v2, v3, v4, v5, v6, v7, fp, lr} @@ -643,6 +648,7 @@ simple_idct_armv5te: .align .global simple_idct_add_armv5te + .type simple_idct_add_armv5te, %function .func simple_idct_add_armv5te simple_idct_add_armv5te: stmfd sp!, {a1, a2, v1, v2, v3, v4, v5, v6, v7, fp, lr} @@ -681,6 +687,7 @@ simple_idct_add_armv5te: .align .global simple_idct_put_armv5te + .type simple_idct_put_armv5te, %function .func simple_idct_put_armv5te simple_idct_put_armv5te: stmfd sp!, {a1, a2, v1, v2, v3, v4, v5, v6, v7, fp, lr} diff --git a/contrib/ffmpeg/libavcodec/armv4l/simple_idct_armv6.S b/contrib/ffmpeg/libavcodec/armv4l/simple_idct_armv6.S index 401e1910d..ab18c9f87 100644 --- a/contrib/ffmpeg/libavcodec/armv4l/simple_idct_armv6.S +++ b/contrib/ffmpeg/libavcodec/armv4l/simple_idct_armv6.S @@ -2,7 +2,7 @@ * Simple IDCT * * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> - * Copyright (c) 2007 Mans Rullgard <mru@inprovide.com> + * Copyright (c) 2007 Mans Rullgard <mans@mansr.com> * * This file is part of FFmpeg. * @@ -191,6 +191,7 @@ w57: .long W57 a2 = dest */ .align + .type idct_row_armv6, %function .func idct_row_armv6 idct_row_armv6: str lr, [sp, #-4]! @@ -245,6 +246,7 @@ idct_row_armv6: a2 = dest */ .align + .type idct_col_armv6, %function .func idct_col_armv6 idct_col_armv6: stmfd sp!, {a2, lr} @@ -275,6 +277,7 @@ idct_col_armv6: a3 = line size */ .align + .type idct_col_put_armv6, %function .func idct_col_put_armv6 idct_col_put_armv6: stmfd sp!, {a2, a3, lr} @@ -307,6 +310,7 @@ idct_col_put_armv6: a3 = line size */ .align + .type idct_col_add_armv6, %function .func idct_col_add_armv6 idct_col_add_armv6: stmfd sp!, {a2, a3, lr} @@ -391,6 +395,7 @@ idct_col_add_armv6: .align .global ff_simple_idct_armv6 + .type ff_simple_idct_armv6, %function .func ff_simple_idct_armv6 /* void ff_simple_idct_armv6(DCTELEM *data); */ ff_simple_idct_armv6: @@ -409,6 +414,7 @@ ff_simple_idct_armv6: .align .global ff_simple_idct_add_armv6 + .type ff_simple_idct_add_armv6, %function .func ff_simple_idct_add_armv6 /* ff_simple_idct_add_armv6(uint8_t *dest, int line_size, DCTELEM *data); */ ff_simple_idct_add_armv6: @@ -429,6 +435,7 @@ ff_simple_idct_add_armv6: .align .global ff_simple_idct_put_armv6 + .type ff_simple_idct_put_armv6, %function .func ff_simple_idct_put_armv6 /* ff_simple_idct_put_armv6(uint8_t *dest, int line_size, DCTELEM *data); */ ff_simple_idct_put_armv6: diff --git a/contrib/ffmpeg/libavcodec/asv1.c b/contrib/ffmpeg/libavcodec/asv1.c index ec6bbb9ba..a0589cdd6 100644 --- a/contrib/ffmpeg/libavcodec/asv1.c +++ b/contrib/ffmpeg/libavcodec/asv1.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "bitstream.h" #include "dsputil.h" #include "mpegvideo.h" @@ -386,7 +387,7 @@ static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { ASV1Context * const a = avctx->priv_data; AVFrame *picture = data; @@ -407,7 +408,7 @@ static int decode_frame(AVCodecContext *avctx, 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); + a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (const uint32_t*)buf, buf_size/4); else{ int i; for(i=0; i<buf_size; i++) diff --git a/contrib/ffmpeg/libavcodec/atrac3.c b/contrib/ffmpeg/libavcodec/atrac3.c new file mode 100644 index 000000000..de6b32836 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/atrac3.c @@ -0,0 +1,1068 @@ +/* + * Atrac 3 compatible decoder + * Copyright (c) 2006-2007 Maxim Poliakovski + * Copyright (c) 2006-2007 Benjamin Larsson + * + * 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 atrac3.c + * Atrac 3 compatible decoder. + * This decoder handles RealNetworks, RealAudio atrc data. + * Atrac 3 is identified by the codec name atrc in RealMedia files. + * + * To use this decoder, a calling application must supply the extradata + * bytes provided from the RealMedia container: 10 bytes or 14 bytes + * from the WAV container. + */ + +#include <math.h> +#include <stddef.h> +#include <stdio.h> + +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" +#include "bytestream.h" + +#include "atrac3data.h" + +#define JOINT_STEREO 0x12 +#define STEREO 0x2 + + +/* These structures are needed to store the parsed gain control data. */ +typedef struct { + int num_gain_data; + int levcode[8]; + int loccode[8]; +} gain_info; + +typedef struct { + gain_info gBlock[4]; +} gain_block; + +typedef struct { + int pos; + int numCoefs; + float coef[8]; +} tonal_component; + +typedef struct { + int bandsCoded; + int numComponents; + tonal_component components[64]; + float prevFrame[1024]; + int gcBlkSwitch; + gain_block gainBlock[2]; + + DECLARE_ALIGNED_16(float, spectrum[1024]); + DECLARE_ALIGNED_16(float, IMDCT_buf[1024]); + + float delayBuf1[46]; ///<qmf delay buffers + float delayBuf2[46]; + float delayBuf3[46]; +} channel_unit; + +typedef struct { + GetBitContext gb; + //@{ + /** stream data */ + int channels; + int codingMode; + int bit_rate; + int sample_rate; + int samples_per_channel; + int samples_per_frame; + + int bits_per_frame; + int bytes_per_frame; + int pBs; + channel_unit* pUnits; + //@} + //@{ + /** joint-stereo related variables */ + int matrix_coeff_index_prev[4]; + int matrix_coeff_index_now[4]; + int matrix_coeff_index_next[4]; + int weighting_delay[6]; + //@} + //@{ + /** data buffers */ + float outSamples[2048]; + uint8_t* decoded_bytes_buffer; + float tempBuf[1070]; + DECLARE_ALIGNED_16(float,mdct_tmp[512]); + //@} + //@{ + /** extradata */ + int atrac3version; + int delay; + int scrambled_stream; + int frame_factor; + //@} +} ATRAC3Context; + +static DECLARE_ALIGNED_16(float,mdct_window[512]); +static float qmf_window[48]; +static VLC spectral_coeff_tab[7]; +static float SFTable[64]; +static float gain_tab1[16]; +static float gain_tab2[31]; +static MDCTContext mdct_ctx; +static DSPContext dsp; + + +/* quadrature mirror synthesis filter */ + +/** + * Quadrature mirror synthesis filter. + * + * @param inlo lower part of spectrum + * @param inhi higher part of spectrum + * @param nIn size of spectrum buffer + * @param pOut out buffer + * @param delayBuf delayBuf buffer + * @param temp temp buffer + */ + + +static void iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp) +{ + int i, j; + float *p1, *p3; + + memcpy(temp, delayBuf, 46*sizeof(float)); + + p3 = temp + 46; + + /* loop1 */ + for(i=0; i<nIn; i+=2){ + p3[2*i+0] = inlo[i ] + inhi[i ]; + p3[2*i+1] = inlo[i ] - inhi[i ]; + p3[2*i+2] = inlo[i+1] + inhi[i+1]; + p3[2*i+3] = inlo[i+1] - inhi[i+1]; + } + + /* loop2 */ + p1 = temp; + for (j = nIn; j != 0; j--) { + float s1 = 0.0; + float s2 = 0.0; + + for (i = 0; i < 48; i += 2) { + s1 += p1[i] * qmf_window[i]; + s2 += p1[i+1] * qmf_window[i+1]; + } + + pOut[0] = s2; + pOut[1] = s1; + + p1 += 2; + pOut += 2; + } + + /* Update the delay buffer. */ + memcpy(delayBuf, temp + nIn*2, 46*sizeof(float)); +} + +/** + * Regular 512 points IMDCT without overlapping, with the exception of the swapping of odd bands + * caused by the reverse spectra of the QMF. + * + * @param pInput float input + * @param pOutput float output + * @param odd_band 1 if the band is an odd band + * @param mdct_tmp aligned temporary buffer for the mdct + */ + +static void IMLT(float *pInput, float *pOutput, int odd_band, float* mdct_tmp) +{ + int i; + + if (odd_band) { + /** + * Reverse the odd bands before IMDCT, this is an effect of the QMF transform + * or it gives better compression to do it this way. + * FIXME: It should be possible to handle this in ff_imdct_calc + * for that to happen a modification of the prerotation step of + * all SIMD code and C code is needed. + * Or fix the functions before so they generate a pre reversed spectrum. + */ + + for (i=0; i<128; i++) + FFSWAP(float, pInput[i], pInput[255-i]); + } + + mdct_ctx.fft.imdct_calc(&mdct_ctx,pOutput,pInput,mdct_tmp); + + /* Perform windowing on the output. */ + dsp.vector_fmul(pOutput,mdct_window,512); + +} + + +/** + * Atrac 3 indata descrambling, only used for data coming from the rm container + * + * @param in pointer to 8 bit array of indata + * @param bits amount of bits + * @param out pointer to 8 bit array of outdata + */ + +static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ + int i, off; + uint32_t c; + const uint32_t* buf; + uint32_t* obuf = (uint32_t*) out; + + off = (int)((long)inbuffer & 3); + buf = (const uint32_t*) (inbuffer - off); + c = be2me_32((0x537F6103 >> (off*8)) | (0x537F6103 << (32-(off*8)))); + bytes += 3 + off; + for (i = 0; i < bytes/4; i++) + obuf[i] = c ^ buf[i]; + + if (off) + av_log(NULL,AV_LOG_DEBUG,"Offset of %d not handled, post sample on ffmpeg-dev.\n",off); + + return off; +} + + +static void init_atrac3_transforms(ATRAC3Context *q) { + float enc_window[256]; + float s; + int i; + + /* Generate the mdct window, for details see + * http://wiki.multimedia.cx/index.php?title=RealAudio_atrc#Windows */ + for (i=0 ; i<256; i++) + enc_window[i] = (sin(((i + 0.5) / 256.0 - 0.5) * M_PI) + 1.0) * 0.5; + + if (!mdct_window[0]) + for (i=0 ; i<256; i++) { + mdct_window[i] = enc_window[i]/(enc_window[i]*enc_window[i] + enc_window[255-i]*enc_window[255-i]); + mdct_window[511-i] = mdct_window[i]; + } + + /* Generate the QMF window. */ + for (i=0 ; i<24; i++) { + s = qmf_48tap_half[i] * 2.0; + qmf_window[i] = s; + qmf_window[47 - i] = s; + } + + /* Initialize the MDCT transform. */ + ff_mdct_init(&mdct_ctx, 9, 1); +} + +/** + * Atrac3 uninit, free all allocated memory + */ + +static int atrac3_decode_close(AVCodecContext *avctx) +{ + ATRAC3Context *q = avctx->priv_data; + + av_free(q->pUnits); + av_free(q->decoded_bytes_buffer); + + return 0; +} + +/** +/ * Mantissa decoding + * + * @param gb the GetBit context + * @param selector what table is the output values coded with + * @param codingFlag constant length coding or variable length coding + * @param mantissas mantissa output table + * @param numCodes amount of values to get + */ + +static void readQuantSpectralCoeffs (GetBitContext *gb, int selector, int codingFlag, int* mantissas, int numCodes) +{ + int numBits, cnt, code, huffSymb; + + if (selector == 1) + numCodes /= 2; + + if (codingFlag != 0) { + /* constant length coding (CLC) */ + //FIXME we don't have any samples coded in CLC mode + numBits = CLCLengthTab[selector]; + + if (selector > 1) { + for (cnt = 0; cnt < numCodes; cnt++) { + if (numBits) + code = get_sbits(gb, numBits); + else + code = 0; + mantissas[cnt] = code; + } + } else { + for (cnt = 0; cnt < numCodes; cnt++) { + if (numBits) + code = get_bits(gb, numBits); //numBits is always 4 in this case + else + code = 0; + mantissas[cnt*2] = seTab_0[code >> 2]; + mantissas[cnt*2+1] = seTab_0[code & 3]; + } + } + } else { + /* variable length coding (VLC) */ + if (selector != 1) { + for (cnt = 0; cnt < numCodes; cnt++) { + huffSymb = get_vlc2(gb, spectral_coeff_tab[selector-1].table, spectral_coeff_tab[selector-1].bits, 3); + huffSymb += 1; + code = huffSymb >> 1; + if (huffSymb & 1) + code = -code; + mantissas[cnt] = code; + } + } else { + for (cnt = 0; cnt < numCodes; cnt++) { + huffSymb = get_vlc2(gb, spectral_coeff_tab[selector-1].table, spectral_coeff_tab[selector-1].bits, 3); + mantissas[cnt*2] = decTable1[huffSymb*2]; + mantissas[cnt*2+1] = decTable1[huffSymb*2+1]; + } + } + } +} + +/** + * Restore the quantized band spectrum coefficients + * + * @param gb the GetBit context + * @param pOut decoded band spectrum + * @return outSubbands subband counter, fix for broken specification/files + */ + +static int decodeSpectrum (GetBitContext *gb, float *pOut) +{ + int numSubbands, codingMode, cnt, first, last, subbWidth, *pIn; + int subband_vlc_index[32], SF_idxs[32]; + int mantissas[128]; + float SF; + + numSubbands = get_bits(gb, 5); // number of coded subbands + codingMode = get_bits1(gb); // coding Mode: 0 - VLC/ 1-CLC + + /* Get the VLC selector table for the subbands, 0 means not coded. */ + for (cnt = 0; cnt <= numSubbands; cnt++) + subband_vlc_index[cnt] = get_bits(gb, 3); + + /* Read the scale factor indexes from the stream. */ + for (cnt = 0; cnt <= numSubbands; cnt++) { + if (subband_vlc_index[cnt] != 0) + SF_idxs[cnt] = get_bits(gb, 6); + } + + for (cnt = 0; cnt <= numSubbands; cnt++) { + first = subbandTab[cnt]; + last = subbandTab[cnt+1]; + + subbWidth = last - first; + + if (subband_vlc_index[cnt] != 0) { + /* Decode spectral coefficients for this subband. */ + /* TODO: This can be done faster is several blocks share the + * same VLC selector (subband_vlc_index) */ + readQuantSpectralCoeffs (gb, subband_vlc_index[cnt], codingMode, mantissas, subbWidth); + + /* Decode the scale factor for this subband. */ + SF = SFTable[SF_idxs[cnt]] * iMaxQuant[subband_vlc_index[cnt]]; + + /* Inverse quantize the coefficients. */ + for (pIn=mantissas ; first<last; first++, pIn++) + pOut[first] = *pIn * SF; + } else { + /* This subband was not coded, so zero the entire subband. */ + memset(pOut+first, 0, subbWidth*sizeof(float)); + } + } + + /* Clear the subbands that were not coded. */ + first = subbandTab[cnt]; + memset(pOut+first, 0, (1024 - first) * sizeof(float)); + return numSubbands; +} + +/** + * Restore the quantized tonal components + * + * @param gb the GetBit context + * @param pComponent tone component + * @param numBands amount of coded bands + */ + +static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent, int numBands) +{ + int i,j,k,cnt; + int components, coding_mode_selector, coding_mode, coded_values_per_component; + int sfIndx, coded_values, max_coded_values, quant_step_index, coded_components; + int band_flags[4], mantissa[8]; + float *pCoef; + float scalefactor; + int component_count = 0; + + components = get_bits(gb,5); + + /* no tonal components */ + if (components == 0) + return 0; + + coding_mode_selector = get_bits(gb,2); + if (coding_mode_selector == 2) + return -1; + + coding_mode = coding_mode_selector & 1; + + for (i = 0; i < components; i++) { + for (cnt = 0; cnt <= numBands; cnt++) + band_flags[cnt] = get_bits1(gb); + + coded_values_per_component = get_bits(gb,3); + + quant_step_index = get_bits(gb,3); + if (quant_step_index <= 1) + return -1; + + if (coding_mode_selector == 3) + coding_mode = get_bits1(gb); + + for (j = 0; j < (numBands + 1) * 4; j++) { + if (band_flags[j >> 2] == 0) + continue; + + coded_components = get_bits(gb,3); + + for (k=0; k<coded_components; k++) { + sfIndx = get_bits(gb,6); + pComponent[component_count].pos = j * 64 + (get_bits(gb,6)); + max_coded_values = 1024 - pComponent[component_count].pos; + coded_values = coded_values_per_component + 1; + coded_values = FFMIN(max_coded_values,coded_values); + + scalefactor = SFTable[sfIndx] * iMaxQuant[quant_step_index]; + + readQuantSpectralCoeffs(gb, quant_step_index, coding_mode, mantissa, coded_values); + + pComponent[component_count].numCoefs = coded_values; + + /* inverse quant */ + pCoef = pComponent[k].coef; + for (cnt = 0; cnt < coded_values; cnt++) + pCoef[cnt] = mantissa[cnt] * scalefactor; + + component_count++; + } + } + } + + return component_count; +} + +/** + * Decode gain parameters for the coded bands + * + * @param gb the GetBit context + * @param pGb the gainblock for the current band + * @param numBands amount of coded bands + */ + +static int decodeGainControl (GetBitContext *gb, gain_block *pGb, int numBands) +{ + int i, cf, numData; + int *pLevel, *pLoc; + + gain_info *pGain = pGb->gBlock; + + for (i=0 ; i<=numBands; i++) + { + numData = get_bits(gb,3); + pGain[i].num_gain_data = numData; + pLevel = pGain[i].levcode; + pLoc = pGain[i].loccode; + + for (cf = 0; cf < numData; cf++){ + pLevel[cf]= get_bits(gb,4); + pLoc [cf]= get_bits(gb,5); + if(cf && pLoc[cf] <= pLoc[cf-1]) + return -1; + } + } + + /* Clear the unused blocks. */ + for (; i<4 ; i++) + pGain[i].num_gain_data = 0; + + return 0; +} + +/** + * Apply gain parameters and perform the MDCT overlapping part + * + * @param pIn input float buffer + * @param pPrev previous float buffer to perform overlap against + * @param pOut output float buffer + * @param pGain1 current band gain info + * @param pGain2 next band gain info + */ + +static void gainCompensateAndOverlap (float *pIn, float *pPrev, float *pOut, gain_info *pGain1, gain_info *pGain2) +{ + /* gain compensation function */ + float gain1, gain2, gain_inc; + int cnt, numdata, nsample, startLoc, endLoc; + + + if (pGain2->num_gain_data == 0) + gain1 = 1.0; + else + gain1 = gain_tab1[pGain2->levcode[0]]; + + if (pGain1->num_gain_data == 0) { + for (cnt = 0; cnt < 256; cnt++) + pOut[cnt] = pIn[cnt] * gain1 + pPrev[cnt]; + } else { + numdata = pGain1->num_gain_data; + pGain1->loccode[numdata] = 32; + pGain1->levcode[numdata] = 4; + + nsample = 0; // current sample = 0 + + for (cnt = 0; cnt < numdata; cnt++) { + startLoc = pGain1->loccode[cnt] * 8; + endLoc = startLoc + 8; + + gain2 = gain_tab1[pGain1->levcode[cnt]]; + gain_inc = gain_tab2[(pGain1->levcode[cnt+1] - pGain1->levcode[cnt])+15]; + + /* interpolate */ + for (; nsample < startLoc; nsample++) + pOut[nsample] = (pIn[nsample] * gain1 + pPrev[nsample]) * gain2; + + /* interpolation is done over eight samples */ + for (; nsample < endLoc; nsample++) { + pOut[nsample] = (pIn[nsample] * gain1 + pPrev[nsample]) * gain2; + gain2 *= gain_inc; + } + } + + for (; nsample < 256; nsample++) + pOut[nsample] = (pIn[nsample] * gain1) + pPrev[nsample]; + } + + /* Delay for the overlapping part. */ + memcpy(pPrev, &pIn[256], 256*sizeof(float)); +} + +/** + * Combine the tonal band spectrum and regular band spectrum + * + * @param pSpectrum output spectrum buffer + * @param numComponents amount of tonal components + * @param pComponent tonal components for this band + */ + +static void addTonalComponents (float *pSpectrum, int numComponents, tonal_component *pComponent) +{ + int cnt, i; + float *pIn, *pOut; + + for (cnt = 0; cnt < numComponents; cnt++){ + pIn = pComponent[cnt].coef; + pOut = &(pSpectrum[pComponent[cnt].pos]); + + for (i=0 ; i<pComponent[cnt].numCoefs ; i++) + pOut[i] += pIn[i]; + } +} + + +#define INTERPOLATE(old,new,nsample) ((old) + (nsample)*0.125*((new)-(old))) + +static void reverseMatrixing(float *su1, float *su2, int *pPrevCode, int *pCurrCode) +{ + int i, band, nsample, s1, s2; + float c1, c2; + float mc1_l, mc1_r, mc2_l, mc2_r; + + for (i=0,band = 0; band < 4*256; band+=256,i++) { + s1 = pPrevCode[i]; + s2 = pCurrCode[i]; + nsample = 0; + + if (s1 != s2) { + /* Selector value changed, interpolation needed. */ + mc1_l = matrixCoeffs[s1*2]; + mc1_r = matrixCoeffs[s1*2+1]; + mc2_l = matrixCoeffs[s2*2]; + mc2_r = matrixCoeffs[s2*2+1]; + + /* Interpolation is done over the first eight samples. */ + for(; nsample < 8; nsample++) { + c1 = su1[band+nsample]; + c2 = su2[band+nsample]; + c2 = c1 * INTERPOLATE(mc1_l,mc2_l,nsample) + c2 * INTERPOLATE(mc1_r,mc2_r,nsample); + su1[band+nsample] = c2; + su2[band+nsample] = c1 * 2.0 - c2; + } + } + + /* Apply the matrix without interpolation. */ + switch (s2) { + case 0: /* M/S decoding */ + for (; nsample < 256; nsample++) { + c1 = su1[band+nsample]; + c2 = su2[band+nsample]; + su1[band+nsample] = c2 * 2.0; + su2[band+nsample] = (c1 - c2) * 2.0; + } + break; + + case 1: + for (; nsample < 256; nsample++) { + c1 = su1[band+nsample]; + c2 = su2[band+nsample]; + su1[band+nsample] = (c1 + c2) * 2.0; + su2[band+nsample] = c2 * -2.0; + } + break; + case 2: + case 3: + for (; nsample < 256; nsample++) { + c1 = su1[band+nsample]; + c2 = su2[band+nsample]; + su1[band+nsample] = c1 + c2; + su2[band+nsample] = c1 - c2; + } + break; + default: + assert(0); + } + } +} + +static void getChannelWeights (int indx, int flag, float ch[2]){ + + if (indx == 7) { + ch[0] = 1.0; + ch[1] = 1.0; + } else { + ch[0] = (float)(indx & 7) / 7.0; + ch[1] = sqrt(2 - ch[0]*ch[0]); + if(flag) + FFSWAP(float, ch[0], ch[1]); + } +} + +static void channelWeighting (float *su1, float *su2, int *p3) +{ + int band, nsample; + /* w[x][y] y=0 is left y=1 is right */ + float w[2][2]; + + if (p3[1] != 7 || p3[3] != 7){ + getChannelWeights(p3[1], p3[0], w[0]); + getChannelWeights(p3[3], p3[2], w[1]); + + for(band = 1; band < 4; band++) { + /* scale the channels by the weights */ + for(nsample = 0; nsample < 8; nsample++) { + su1[band*256+nsample] *= INTERPOLATE(w[0][0], w[0][1], nsample); + su2[band*256+nsample] *= INTERPOLATE(w[1][0], w[1][1], nsample); + } + + for(; nsample < 256; nsample++) { + su1[band*256+nsample] *= w[1][0]; + su2[band*256+nsample] *= w[1][1]; + } + } + } +} + + +/** + * Decode a Sound Unit + * + * @param gb the GetBit context + * @param pSnd the channel unit to be used + * @param pOut the decoded samples before IQMF in float representation + * @param channelNum channel number + * @param codingMode the coding mode (JOINT_STEREO or regular stereo/mono) + */ + + +static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_unit *pSnd, float *pOut, int channelNum, int codingMode) +{ + int band, result=0, numSubbands, numBands; + + if (codingMode == JOINT_STEREO && channelNum == 1) { + if (get_bits(gb,2) != 3) { + av_log(NULL,AV_LOG_ERROR,"JS mono Sound Unit id != 3.\n"); + return -1; + } + } else { + if (get_bits(gb,6) != 0x28) { + av_log(NULL,AV_LOG_ERROR,"Sound Unit id != 0x28.\n"); + return -1; + } + } + + /* number of coded QMF bands */ + pSnd->bandsCoded = get_bits(gb,2); + + result = decodeGainControl (gb, &(pSnd->gainBlock[pSnd->gcBlkSwitch]), pSnd->bandsCoded); + if (result) return result; + + pSnd->numComponents = decodeTonalComponents (gb, pSnd->components, pSnd->bandsCoded); + if (pSnd->numComponents == -1) return -1; + + numSubbands = decodeSpectrum (gb, pSnd->spectrum); + + /* Merge the decoded spectrum and tonal components. */ + addTonalComponents (pSnd->spectrum, pSnd->numComponents, pSnd->components); + + + /* Convert number of subbands into number of MLT/QMF bands */ + numBands = (subbandTab[numSubbands] - 1) >> 8; + + + /* Reconstruct time domain samples. */ + for (band=0; band<4; band++) { + /* Perform the IMDCT step without overlapping. */ + if (band <= numBands) { + IMLT(&(pSnd->spectrum[band*256]), pSnd->IMDCT_buf, band&1,q->mdct_tmp); + } else + memset(pSnd->IMDCT_buf, 0, 512 * sizeof(float)); + + /* gain compensation and overlapping */ + gainCompensateAndOverlap (pSnd->IMDCT_buf, &(pSnd->prevFrame[band*256]), &(pOut[band*256]), + &((pSnd->gainBlock[1 - (pSnd->gcBlkSwitch)]).gBlock[band]), + &((pSnd->gainBlock[pSnd->gcBlkSwitch]).gBlock[band])); + } + + /* Swap the gain control buffers for the next frame. */ + pSnd->gcBlkSwitch ^= 1; + + return 0; +} + +/** + * Frame handling + * + * @param q Atrac3 private context + * @param databuf the input data + */ + +static int decodeFrame(ATRAC3Context *q, uint8_t* databuf) +{ + int result, i; + float *p1, *p2, *p3, *p4; + uint8_t *ptr1, *ptr2; + + if (q->codingMode == JOINT_STEREO) { + + /* channel coupling mode */ + /* decode Sound Unit 1 */ + init_get_bits(&q->gb,databuf,q->bits_per_frame); + + result = decodeChannelSoundUnit(q,&q->gb, q->pUnits, q->outSamples, 0, JOINT_STEREO); + if (result != 0) + return (result); + + /* Framedata of the su2 in the joint-stereo mode is encoded in + * reverse byte order so we need to swap it first. */ + ptr1 = databuf; + ptr2 = databuf+q->bytes_per_frame-1; + for (i = 0; i < (q->bytes_per_frame/2); i++, ptr1++, ptr2--) { + FFSWAP(uint8_t,*ptr1,*ptr2); + } + + /* Skip the sync codes (0xF8). */ + ptr1 = databuf; + for (i = 4; *ptr1 == 0xF8; i++, ptr1++) { + if (i >= q->bytes_per_frame) + return -1; + } + + + /* set the bitstream reader at the start of the second Sound Unit*/ + init_get_bits(&q->gb,ptr1,q->bits_per_frame); + + /* Fill the Weighting coeffs delay buffer */ + memmove(q->weighting_delay,&(q->weighting_delay[2]),4*sizeof(int)); + q->weighting_delay[4] = get_bits1(&q->gb); + q->weighting_delay[5] = get_bits(&q->gb,3); + + for (i = 0; i < 4; i++) { + q->matrix_coeff_index_prev[i] = q->matrix_coeff_index_now[i]; + q->matrix_coeff_index_now[i] = q->matrix_coeff_index_next[i]; + q->matrix_coeff_index_next[i] = get_bits(&q->gb,2); + } + + /* Decode Sound Unit 2. */ + result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[1], &q->outSamples[1024], 1, JOINT_STEREO); + if (result != 0) + return (result); + + /* Reconstruct the channel coefficients. */ + reverseMatrixing(q->outSamples, &q->outSamples[1024], q->matrix_coeff_index_prev, q->matrix_coeff_index_now); + + channelWeighting(q->outSamples, &q->outSamples[1024], q->weighting_delay); + + } else { + /* normal stereo mode or mono */ + /* Decode the channel sound units. */ + for (i=0 ; i<q->channels ; i++) { + + /* Set the bitstream reader at the start of a channel sound unit. */ + init_get_bits(&q->gb, databuf+((i*q->bytes_per_frame)/q->channels), (q->bits_per_frame)/q->channels); + + result = decodeChannelSoundUnit(q,&q->gb, &q->pUnits[i], &q->outSamples[i*1024], i, q->codingMode); + if (result != 0) + return (result); + } + } + + /* Apply the iQMF synthesis filter. */ + p1= q->outSamples; + for (i=0 ; i<q->channels ; i++) { + p2= p1+256; + p3= p2+256; + p4= p3+256; + iqmf (p1, p2, 256, p1, q->pUnits[i].delayBuf1, q->tempBuf); + iqmf (p4, p3, 256, p3, q->pUnits[i].delayBuf2, q->tempBuf); + iqmf (p1, p3, 512, p1, q->pUnits[i].delayBuf3, q->tempBuf); + p1 +=1024; + } + + return 0; +} + + +/** + * Atrac frame decoding + * + * @param avctx pointer to the AVCodecContext + */ + +static int atrac3_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) { + ATRAC3Context *q = avctx->priv_data; + int result = 0, i; + uint8_t* databuf; + int16_t* samples = data; + + if (buf_size < avctx->block_align) + return buf_size; + + /* Check if we need to descramble and what buffer to pass on. */ + if (q->scrambled_stream) { + decode_bytes(buf, q->decoded_bytes_buffer, avctx->block_align); + databuf = q->decoded_bytes_buffer; + } else { + databuf = buf; + } + + result = decodeFrame(q, databuf); + + if (result != 0) { + av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n"); + return -1; + } + + if (q->channels == 1) { + /* mono */ + for (i = 0; i<1024; i++) + samples[i] = av_clip_int16(round(q->outSamples[i])); + *data_size = 1024 * sizeof(int16_t); + } else { + /* stereo */ + for (i = 0; i < 1024; i++) { + samples[i*2] = av_clip_int16(round(q->outSamples[i])); + samples[i*2+1] = av_clip_int16(round(q->outSamples[1024+i])); + } + *data_size = 2048 * sizeof(int16_t); + } + + return avctx->block_align; +} + + +/** + * Atrac3 initialization + * + * @param avctx pointer to the AVCodecContext + */ + +static int atrac3_decode_init(AVCodecContext *avctx) +{ + int i; + const uint8_t *edata_ptr = avctx->extradata; + ATRAC3Context *q = avctx->priv_data; + + /* Take data from the AVCodecContext (RM container). */ + q->sample_rate = avctx->sample_rate; + q->channels = avctx->channels; + q->bit_rate = avctx->bit_rate; + q->bits_per_frame = avctx->block_align * 8; + q->bytes_per_frame = avctx->block_align; + + /* Take care of the codec-specific extradata. */ + if (avctx->extradata_size == 14) { + /* Parse the extradata, WAV format */ + av_log(avctx,AV_LOG_DEBUG,"[0-1] %d\n",bytestream_get_le16(&edata_ptr)); //Unknown value always 1 + q->samples_per_channel = bytestream_get_le32(&edata_ptr); + q->codingMode = bytestream_get_le16(&edata_ptr); + av_log(avctx,AV_LOG_DEBUG,"[8-9] %d\n",bytestream_get_le16(&edata_ptr)); //Dupe of coding mode + q->frame_factor = bytestream_get_le16(&edata_ptr); //Unknown always 1 + av_log(avctx,AV_LOG_DEBUG,"[12-13] %d\n",bytestream_get_le16(&edata_ptr)); //Unknown always 0 + + /* setup */ + q->samples_per_frame = 1024 * q->channels; + q->atrac3version = 4; + q->delay = 0x88E; + if (q->codingMode) + q->codingMode = JOINT_STEREO; + else + q->codingMode = STEREO; + + q->scrambled_stream = 0; + + if ((q->bytes_per_frame == 96*q->channels*q->frame_factor) || (q->bytes_per_frame == 152*q->channels*q->frame_factor) || (q->bytes_per_frame == 192*q->channels*q->frame_factor)) { + } else { + av_log(avctx,AV_LOG_ERROR,"Unknown frame/channel/frame_factor configuration %d/%d/%d\n", q->bytes_per_frame, q->channels, q->frame_factor); + return -1; + } + + } else if (avctx->extradata_size == 10) { + /* Parse the extradata, RM format. */ + q->atrac3version = bytestream_get_be32(&edata_ptr); + q->samples_per_frame = bytestream_get_be16(&edata_ptr); + q->delay = bytestream_get_be16(&edata_ptr); + q->codingMode = bytestream_get_be16(&edata_ptr); + + q->samples_per_channel = q->samples_per_frame / q->channels; + q->scrambled_stream = 1; + + } else { + av_log(NULL,AV_LOG_ERROR,"Unknown extradata size %d.\n",avctx->extradata_size); + } + /* Check the extradata. */ + + if (q->atrac3version != 4) { + av_log(avctx,AV_LOG_ERROR,"Version %d != 4.\n",q->atrac3version); + return -1; + } + + if (q->samples_per_frame != 1024 && q->samples_per_frame != 2048) { + av_log(avctx,AV_LOG_ERROR,"Unknown amount of samples per frame %d.\n",q->samples_per_frame); + return -1; + } + + if (q->delay != 0x88E) { + av_log(avctx,AV_LOG_ERROR,"Unknown amount of delay %x != 0x88E.\n",q->delay); + return -1; + } + + if (q->codingMode == STEREO) { + av_log(avctx,AV_LOG_DEBUG,"Normal stereo detected.\n"); + } else if (q->codingMode == JOINT_STEREO) { + av_log(avctx,AV_LOG_DEBUG,"Joint stereo detected.\n"); + } else { + av_log(avctx,AV_LOG_ERROR,"Unknown channel coding mode %x!\n",q->codingMode); + return -1; + } + + if (avctx->channels <= 0 || avctx->channels > 2 /*|| ((avctx->channels * 1024) != q->samples_per_frame)*/) { + av_log(avctx,AV_LOG_ERROR,"Channel configuration error!\n"); + return -1; + } + + + if(avctx->block_align >= UINT_MAX/2) + return -1; + + /* Pad the data buffer with FF_INPUT_BUFFER_PADDING_SIZE, + * this is for the bitstream reader. */ + if ((q->decoded_bytes_buffer = av_mallocz((avctx->block_align+(4-avctx->block_align%4) + FF_INPUT_BUFFER_PADDING_SIZE))) == NULL) + return AVERROR(ENOMEM); + + + /* Initialize the VLC tables. */ + for (i=0 ; i<7 ; i++) { + init_vlc (&spectral_coeff_tab[i], 9, huff_tab_sizes[i], + huff_bits[i], 1, 1, + huff_codes[i], 1, 1, INIT_VLC_USE_STATIC); + } + + init_atrac3_transforms(q); + + /* Generate the scale factors. */ + for (i=0 ; i<64 ; i++) + SFTable[i] = pow(2.0, (i - 15) / 3.0); + + /* Generate gain tables. */ + for (i=0 ; i<16 ; i++) + gain_tab1[i] = powf (2.0, (4 - i)); + + for (i=-15 ; i<16 ; i++) + gain_tab2[i+15] = powf (2.0, i * -0.125); + + /* init the joint-stereo decoding data */ + q->weighting_delay[0] = 0; + q->weighting_delay[1] = 7; + q->weighting_delay[2] = 0; + q->weighting_delay[3] = 7; + q->weighting_delay[4] = 0; + q->weighting_delay[5] = 7; + + for (i=0; i<4; i++) { + q->matrix_coeff_index_prev[i] = 3; + q->matrix_coeff_index_now[i] = 3; + q->matrix_coeff_index_next[i] = 3; + } + + dsputil_init(&dsp, avctx); + + q->pUnits = av_mallocz(sizeof(channel_unit)*q->channels); + if (!q->pUnits) { + av_free(q->decoded_bytes_buffer); + return AVERROR(ENOMEM); + } + + return 0; +} + + +AVCodec atrac3_decoder = +{ + .name = "atrac 3", + .type = CODEC_TYPE_AUDIO, + .id = CODEC_ID_ATRAC3, + .priv_data_size = sizeof(ATRAC3Context), + .init = atrac3_decode_init, + .close = atrac3_decode_close, + .decode = atrac3_decode_frame, +}; diff --git a/contrib/ffmpeg/libavcodec/atrac3data.h b/contrib/ffmpeg/libavcodec/atrac3data.h new file mode 100644 index 000000000..786629d03 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/atrac3data.h @@ -0,0 +1,140 @@ +/* + * Atrac 3 compatible decoder data + * Copyright (c) 2006-2007 Maxim Poliakovski + * Copyright (c) 2006-2007 Benjamin Larsson + * + * 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 atrac3data.h + * Atrac 3 AKA RealAudio 8 compatible decoder data + */ + +#ifndef FFMPEG_ATRAC3DATA_H +#define FFMPEG_ATRAC3DATA_H + +#include <stdint.h> + +/* VLC tables */ + +static const uint8_t huffcode1[9] = { + 0x0,0x4,0x5,0xC,0xD,0x1C,0x1D,0x1E,0x1F, +}; + +static const uint8_t huffbits1[9] = { + 1,3,3,4,4,5,5,5,5, +}; + +static const uint8_t huffcode2[5] = { + 0x0,0x4,0x5,0x6,0x7, +}; + +static const uint8_t huffbits2[5] = { + 1,3,3,3,3, +}; + +static const uint8_t huffcode3[7] = { +0x0,0x4,0x5,0xC,0xD,0xE,0xF, +}; + +static const uint8_t huffbits3[7] = { + 1,3,3,4,4,4,4, +}; + +static const uint8_t huffcode4[9] = { + 0x0,0x4,0x5,0xC,0xD,0x1C,0x1D,0x1E,0x1F, +}; + +static const uint8_t huffbits4[9] = { + 1,3,3,4,4,5,5,5,5, +}; + +static const uint8_t huffcode5[15] = { + 0x0,0x2,0x3,0x8,0x9,0xA,0xB,0x1C,0x1D,0x3C,0x3D,0x3E,0x3F,0xC,0xD, +}; + +static const uint8_t huffbits5[15] = { + 2,3,3,4,4,4,4,5,5,6,6,6,6,4,4 +}; + +static const uint8_t huffcode6[31] = { + 0x0,0x2,0x3,0x4,0x5,0x6,0x7,0x14,0x15,0x16,0x17,0x18,0x19,0x34,0x35, + 0x36,0x37,0x38,0x39,0x3A,0x3B,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x8,0x9, +}; + +static const uint8_t huffbits6[31] = { + 3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,4,4 +}; + +static const uint8_t huffcode7[63] = { + 0x0,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,0x10,0x11,0x24,0x25,0x26,0x27,0x28, + 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x68,0x69,0x6A,0x6B,0x6C, + 0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2, + 0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x2,0x3, +}; + +static const uint8_t huffbits7[63] = { + 3,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,4,4 +}; + +static const uint8_t huff_tab_sizes[7] = { + 9, 5, 7, 9, 15, 31, 63, +}; + +static const uint8_t* huff_codes[7] = { + huffcode1,huffcode2,huffcode3,huffcode4,huffcode5,huffcode6,huffcode7, +}; + +static const uint8_t* huff_bits[7] = { + huffbits1,huffbits2,huffbits3,huffbits4,huffbits5,huffbits6,huffbits7, +}; + +/* selector tables */ + +static const uint8_t CLCLengthTab[8] = {0, 4, 3, 3, 4, 4, 5, 6}; +static const int8_t seTab_0[4] = {0, 1, -2, -1}; +static const int8_t decTable1[18] = {0,0, 0,1, 0,-1, 1,0, -1,0, 1,1, 1,-1, -1,1, -1,-1}; + + +/* tables for the scalefactor decoding */ + +static const float iMaxQuant[8] = { + 0.0, 1.0/1.5, 1.0/2.5, 1.0/3.5, 1.0/4.5, 1.0/7.5, 1.0/15.5, 1.0/31.5 +}; + +static const uint16_t subbandTab[33] = { + 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, + 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024 +}; + +/* transform data */ + +static const float qmf_48tap_half[24] = { + -0.00001461907, -0.00009205479, -0.000056157569, 0.00030117269, + 0.0002422519,-0.00085293897, -0.0005205574, 0.0020340169, + 0.00078333891, -0.0042153862, -0.00075614988, 0.0078402944, + -0.000061169922, -0.01344162, 0.0024626821, 0.021736089, + -0.007801671, -0.034090221, 0.01880949, 0.054326009, + -0.043596379, -0.099384367, 0.13207909, 0.46424159 +}; + +/* joint stereo related tables */ +static const float matrixCoeffs[8] = {0.0, 2.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0}; + +#endif /* FFMPEG_ATRAC3DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/audioconvert.c b/contrib/ffmpeg/libavcodec/audioconvert.c index e6291ac6d..4c021219f 100644 --- a/contrib/ffmpeg/libavcodec/audioconvert.c +++ b/contrib/ffmpeg/libavcodec/audioconvert.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -54,8 +53,8 @@ if(fmt_pair == ofmt + 5*ifmt){\ }while(po < end);\ } -//FIXME put things below under ifdefs so we dont waste space for cases no codec will need -//FIXME rounding and cliping ? +//FIXME put things below under ifdefs so we do not waste space for cases no codec will need +//FIXME rounding and clipping ? CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_U8 , *(uint8_t*)pi) else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)<<8) diff --git a/contrib/ffmpeg/libavcodec/avcodec.h b/contrib/ffmpeg/libavcodec/avcodec.h index 1d8427a9d..32dd4da28 100644 --- a/contrib/ffmpeg/libavcodec/avcodec.h +++ b/contrib/ffmpeg/libavcodec/avcodec.h @@ -15,30 +15,31 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVCODEC_H -#define AVCODEC_H +#ifndef FFMPEG_AVCODEC_H +#define FFMPEG_AVCODEC_H /** * @file avcodec.h - * external api header. + * external API header */ -#ifdef __cplusplus -extern "C" { -#endif - -#include "avutil.h" +#include "libavutil/avutil.h" #include <sys/types.h> /* size_t */ -#define AV_STRINGIFY(s) AV_TOSTRING(s) -#define AV_TOSTRING(s) #s +#define LIBAVCODEC_VERSION_MAJOR 51 +#define LIBAVCODEC_VERSION_MINOR 50 +#define LIBAVCODEC_VERSION_MICRO 1 -#define LIBAVCODEC_VERSION_INT ((51<<16)+(40<<8)+2) -#define LIBAVCODEC_VERSION 51.40.2 +#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) #define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT #define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) @@ -48,15 +49,21 @@ extern "C" { #define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} /** + * Identifies the syntax and semantics of the bitstream. + * The principle is roughly: + * Two decoders with the same ID can decode the same streams. + * Two encoders with the same ID can encode compatible streams. + * There may be slight deviations from the principle due to implementation + * details. * - * if you add a codec id to this list add it so that - * 1. no value of a existing codec id changes (that would break ABI) - * 2. closest to similar codecs + * If you add a codec ID to this list, add it so that + * 1. no value of a existing codec ID changes (that would break ABI), + * 2. it is as close as possible to similar codecs. */ enum CodecID { CODEC_ID_NONE, CODEC_ID_MPEG1VIDEO, - CODEC_ID_MPEG2VIDEO, /* prefered ID for MPEG Video 1 or 2 decoding */ + CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding CODEC_ID_MPEG2VIDEO_XVMC, CODEC_ID_H261, CODEC_ID_H263, @@ -159,8 +166,20 @@ enum CodecID { CODEC_ID_DXA, CODEC_ID_DNXHD, CODEC_ID_THP, - - /* various pcm "codecs" */ + CODEC_ID_SGI, + CODEC_ID_C93, + CODEC_ID_BETHSOFTVID, + CODEC_ID_PTX, + CODEC_ID_TXD, + CODEC_ID_VP6A, + CODEC_ID_AMV, + CODEC_ID_VB, + CODEC_ID_PCX, + CODEC_ID_SUNRAST, + CODEC_ID_INDEO4, + CODEC_ID_INDEO5, + + /* various PCM "codecs" */ CODEC_ID_PCM_S16LE= 0x10000, CODEC_ID_PCM_S16BE, CODEC_ID_PCM_U16LE, @@ -178,8 +197,10 @@ enum CodecID { CODEC_ID_PCM_U24LE, CODEC_ID_PCM_U24BE, CODEC_ID_PCM_S24DAUD, + CODEC_ID_PCM_ZORK, + CODEC_ID_PCM_S16LE_PLANAR, - /* various adpcm codecs */ + /* various ADPCM codecs */ CODEC_ID_ADPCM_IMA_QT= 0x11000, CODEC_ID_ADPCM_IMA_WAV, CODEC_ID_ADPCM_IMA_DK3, @@ -198,6 +219,14 @@ enum CodecID { CODEC_ID_ADPCM_SBPRO_4, CODEC_ID_ADPCM_SBPRO_3, CODEC_ID_ADPCM_SBPRO_2, + CODEC_ID_ADPCM_THP, + CODEC_ID_ADPCM_IMA_AMV, + CODEC_ID_ADPCM_EA_R1, + CODEC_ID_ADPCM_EA_R3, + CODEC_ID_ADPCM_EA_R2, + CODEC_ID_ADPCM_IMA_EA_SEAD, + CODEC_ID_ADPCM_IMA_EA_EACS, + CODEC_ID_ADPCM_EA_XAS, /* AMR */ CODEC_ID_AMR_NB= 0x12000, @@ -214,7 +243,7 @@ enum CodecID { CODEC_ID_SOL_DPCM, CODEC_ID_MP2= 0x15000, - CODEC_ID_MP3, /* prefered ID for MPEG Audio layer 1, 2 or3 decoding */ + CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 CODEC_ID_AAC, #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) CODEC_ID_MPEG4AAC, @@ -236,7 +265,7 @@ enum CodecID { CODEC_ID_SHORTEN, CODEC_ID_ALAC, CODEC_ID_WESTWOOD_SND1, - CODEC_ID_GSM, /* As in Berlin toast format */ + CODEC_ID_GSM, ///< as in Berlin toast format CODEC_ID_QDM2, CODEC_ID_COOK, CODEC_ID_TRUESPEECH, @@ -248,18 +277,34 @@ enum CodecID { CODEC_ID_IMC, CODEC_ID_MUSEPACK7, CODEC_ID_MLP, - CODEC_ID_GSM_MS, /* As found in WAV */ + CODEC_ID_GSM_MS, /* as found in WAV */ + CODEC_ID_ATRAC3, + CODEC_ID_VOXWARE, + CODEC_ID_APE, + CODEC_ID_NELLYMOSER, + CODEC_ID_MUSEPACK8, + CODEC_ID_SPEEX, + CODEC_ID_WMAVOICE, + CODEC_ID_WMAPRO, + CODEC_ID_WMALOSSLESS, /* subtitle codecs */ CODEC_ID_DVD_SUBTITLE= 0x17000, CODEC_ID_DVB_SUBTITLE, + CODEC_ID_TEXT, ///< raw UTF-8 text + CODEC_ID_XSUB, + CODEC_ID_SSA, + CODEC_ID_MOV_TEXT, - CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG2 transport - stream (only used by libavformat) */ + /* other specific kind of codecs (generaly used for attachments) */ + CODEC_ID_TTF= 0x18000, + + CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS + * stream (only used by libavformat) */ }; #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) -/* CODEC_ID_MP3LAME is absolete */ +/* CODEC_ID_MP3LAME is obsolete */ #define CODEC_ID_MP3LAME CODEC_ID_MP3 #define CODEC_ID_MPEG4AAC CODEC_ID_AAC #endif @@ -270,11 +315,14 @@ enum CodecType { CODEC_TYPE_AUDIO, CODEC_TYPE_DATA, CODEC_TYPE_SUBTITLE, + CODEC_TYPE_ATTACHMENT, CODEC_TYPE_NB }; -/* currently unused, may be used if 24/32 bits samples ever supported */ -/* all in native endian */ +/** + * Currently unused, may be used if 24/32 bits samples are ever supported. + * all in native-endian format + */ enum SampleFormat { SAMPLE_FMT_NONE = -1, SAMPLE_FMT_U8, ///< unsigned 8 bits @@ -289,34 +337,37 @@ enum SampleFormat { /** * Required number of additionally allocated bytes at the end of the input bitstream for decoding. - * this is mainly needed because some optimized bitstream readers read - * 32 or 64 bit at once and could read over the end<br> - * Note, if the first 23 bits of the additional bytes are not 0 then damaged - * MPEG bitstreams could cause overread and segfault + * This is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end.<br> + * Note: If the first 23 bits of the additional bytes are not 0, then damaged + * MPEG bitstreams could cause overread and segfault. */ #define FF_INPUT_BUFFER_PADDING_SIZE 8 /** - * minimum encoding buffer size. - * used to avoid some checks during header writing + * minimum encoding buffer size + * Used to avoid some checks during header writing. */ #define FF_MIN_BUFFER_SIZE 16384 -/* motion estimation type, EPZS by default */ +/** + * motion estimation type. + */ enum Motion_Est_ID { - ME_ZERO = 1, + ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed ME_FULL, ME_LOG, ME_PHODS, - ME_EPZS, - ME_X1, - ME_HEX, - ME_UMH, - ME_ITER, + ME_EPZS, ///< enhanced predictive zonal search + ME_X1, ///< reserved for experiments + ME_HEX, ///< hexagon based search + ME_UMH, ///< uneven multi-hexagon search + ME_ITER, ///< iterative search }; enum AVDiscard{ -//we leave some space between them for extensions (drop some keyframes for intra only or drop just some bidir frames) + /* We leave some space between them for extensions (drop some + * keyframes for intra-only or drop just some bidir frames). */ AVDISCARD_NONE =-16, ///< discard nothing AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi AVDISCARD_NONREF = 8, ///< discard all non reference @@ -328,73 +379,77 @@ enum AVDiscard{ typedef struct RcOverride{ int start_frame; int end_frame; - int qscale; // if this is 0 then quality_factor will be used instead + int qscale; // If this is 0 then quality_factor will be used instead. float quality_factor; } RcOverride; #define FF_MAX_B_FRAMES 16 /* encoding support - these flags can be passed in AVCodecContext.flags before initing - Note: not everything is supported yet. + These flags can be passed in AVCodecContext.flags before initialization. + Note: Not everything is supported yet. */ -#define CODEC_FLAG_QSCALE 0x0002 ///< use fixed qscale -#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / Advanced prediction for H263 -#define CODEC_FLAG_QPEL 0x0010 ///< use qpel MC -#define CODEC_FLAG_GMC 0x0020 ///< use GMC -#define CODEC_FLAG_MV0 0x0040 ///< always try a MB with MV=<0,0> -#define CODEC_FLAG_PART 0x0080 ///< use data partitioning -/* parent program guarantees that the input for b-frame containing streams is not written to - for at least s->max_b_frames+1 frames, if this is not set than the input will be copied */ +#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. +#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. +#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. +#define CODEC_FLAG_GMC 0x0020 ///< Use GMC. +#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>. +#define CODEC_FLAG_PART 0x0080 ///< Use data partitioning. +/** + * The parent program guarantees that the input for B-frames containing + * streams is not written to for at least s->max_b_frames+1 frames, if + * this is not set the input will be copied. + */ #define CODEC_FLAG_INPUT_PRESERVED 0x0100 -#define CODEC_FLAG_PASS1 0x0200 ///< use internal 2pass ratecontrol in first pass mode -#define CODEC_FLAG_PASS2 0x0400 ///< use internal 2pass ratecontrol in second pass mode -#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< use external huffman table (for mjpeg) -#define CODEC_FLAG_GRAY 0x2000 ///< only decode/encode grayscale -#define CODEC_FLAG_EMU_EDGE 0x4000///< don't draw edges -#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding -#define CODEC_FLAG_TRUNCATED 0x00010000 /** input bitstream might be truncated at a random location instead - of only at frame boundaries */ -#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< normalize adaptive quantization -#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< use interlaced dct -#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< force low delay -#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< use alternate scan -#define CODEC_FLAG_TRELLIS_QUANT 0x00200000 ///< use trellis quantization -#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< place global headers in extradata instead of every keyframe -#define CODEC_FLAG_BITEXACT 0x00800000 ///< use only bitexact stuff (except (i)dct) +#define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode. +#define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode. +#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< Use external Huffman table (for MJPEG). +#define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale. +#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges. +#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding. +#define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random + location instead of only at frame boundaries. */ +#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< Normalize adaptive quantization. +#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT. +#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< Force low delay. +#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< Use alternate scan. +#define CODEC_FLAG_TRELLIS_QUANT 0x00200000 ///< Use trellis quantization. +#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< Place global headers in extradata instead of every keyframe. +#define CODEC_FLAG_BITEXACT 0x00800000 ///< Use only bitexact stuff (except (I)DCT). /* Fx : Flag for h263+ extra options */ #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) -#define CODEC_FLAG_H263P_AIC 0x01000000 ///< H263 Advanced intra coding / MPEG4 AC prediction (remove this) +#define CODEC_FLAG_H263P_AIC 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction (remove this) #endif -#define CODEC_FLAG_AC_PRED 0x01000000 ///< H263 Advanced intra coding / MPEG4 AC prediction -#define CODEC_FLAG_H263P_UMV 0x02000000 ///< Unlimited motion vector -#define CODEC_FLAG_CBP_RD 0x04000000 ///< use rate distortion optimization for cbp -#define CODEC_FLAG_QP_RD 0x08000000 ///< use rate distortion optimization for qp selectioon -#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H263 Alternative inter vlc +#define CODEC_FLAG_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction +#define CODEC_FLAG_H263P_UMV 0x02000000 ///< unlimited motion vector +#define CODEC_FLAG_CBP_RD 0x04000000 ///< Use rate distortion optimization for cbp. +#define CODEC_FLAG_QP_RD 0x08000000 ///< Use rate distortion optimization for qp selectioon. +#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H.263 alternative inter VLC #define CODEC_FLAG_OBMC 0x00000001 ///< OBMC #define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter #define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000 #define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation -#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< will reserve space for SVCD scan offset user data +#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data. #define CODEC_FLAG_CLOSED_GOP ((int)0x80000000) -#define CODEC_FLAG2_FAST 0x00000001 ///< allow non spec compliant speedup tricks -#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< strictly enforce GOP size -#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< skip bitstream encoding -#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< place global headers at every keyframe instead of in extradata -#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow b-frames to be used as references -#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for b-frames +#define CODEC_FLAG2_FAST 0x00000001 ///< Allow non spec compliant speedup tricks. +#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size. +#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding. +#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata. +#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow B-frames to be used as references. +#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for B-frames #define CODEC_FLAG2_MIXED_REFS 0x00000040 ///< H.264 one reference per partition, as opposed to one reference per macroblock #define CODEC_FLAG2_8X8DCT 0x00000080 ///< H.264 high profile 8x8 transform #define CODEC_FLAG2_FASTPSKIP 0x00000100 ///< H.264 fast pskip #define CODEC_FLAG2_AUD 0x00000200 ///< H.264 access unit delimiters -#define CODEC_FLAG2_BRDO 0x00000400 ///< b-frame rate-distortion optimization -#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< use MPEG-2 intra VLC table -#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< only do ME/MC (I frames -> ref, P frame -> ME+MC) -#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format -#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skiping -#define CODEC_FLAG2_CHUNKS 0x00008000 ///< input bitstream might be truncated at a packet boundaries instead of only at frame boundaries -#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< use MPEG-2 non linear quantizer +#define CODEC_FLAG2_BRDO 0x00000400 ///< B-frame rate-distortion optimization +#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table. +#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC). +#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. +#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping +#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries. +#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer. +#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible /* Unsupported options : * Syntax Arithmetic coding (SAC) @@ -403,21 +458,20 @@ typedef struct RcOverride{ /* /Fx */ /* codec capabilities */ -#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< decoder can use draw_horiz_band callback +#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< Decoder can use draw_horiz_band callback. /** * Codec uses get_buffer() for allocating buffers. * direct rendering method 1 */ #define CODEC_CAP_DR1 0x0002 -/* if 'parse_only' field is true, then avcodec_parse_frame() can be - used */ +/* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */ #define CODEC_CAP_PARSE_ONLY 0x0004 #define CODEC_CAP_TRUNCATED 0x0008 -/* codec can export data for HW decoding (XvMC) */ +/* Codec can export data for HW decoding (XvMC). */ #define CODEC_CAP_HWACCEL 0x0010 /** - * codec has a non zero delay and needs to be feeded with NULL at the end to get the delayed data. - * if this is not set, the codec is guaranteed to never be feeded with NULL data + * Codec has a nonzero delay and needs to be fed with NULL at the end to get the delayed data. + * If this is not set, the codec is guaranteed to never be fed with NULL data. */ #define CODEC_CAP_DELAY 0x0020 /** @@ -426,16 +480,16 @@ typedef struct RcOverride{ */ #define CODEC_CAP_SMALL_LAST_FRAME 0x0040 -//the following defines may change, don't expect compatibility if you use them +//The following defines may change, don't expect compatibility if you use them. #define MB_TYPE_INTRA4x4 0x0001 -#define MB_TYPE_INTRA16x16 0x0002 //FIXME h264 specific -#define MB_TYPE_INTRA_PCM 0x0004 //FIXME h264 specific +#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific +#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific #define MB_TYPE_16x16 0x0008 #define MB_TYPE_16x8 0x0010 #define MB_TYPE_8x16 0x0020 #define MB_TYPE_8x8 0x0040 #define MB_TYPE_INTERLACED 0x0080 -#define MB_TYPE_DIRECT2 0x0100 //FIXME +#define MB_TYPE_DIRECT2 0x0100 //FIXME #define MB_TYPE_ACPRED 0x0200 #define MB_TYPE_GMC 0x0400 #define MB_TYPE_SKIP 0x0800 @@ -452,28 +506,29 @@ typedef struct RcOverride{ /** * Pan Scan area. - * this specifies the area which should be displayed. Note there may be multiple such areas for one frame + * This specifies the area which should be displayed. + * Note there may be multiple such areas for one frame. */ typedef struct AVPanScan{ /** - * id. - * - encoding: set by user. - * - decoding: set by lavc + * id + * - encoding: Set by user. + * - decoding: Set by libavcodec. */ int id; /** * width and height in 1/16 pel - * - encoding: set by user. - * - decoding: set by lavc + * - encoding: Set by user. + * - decoding: Set by libavcodec. */ int width; int height; /** - * position of the top left corner in 1/16 pel for up to 3 fields/frames. - * - encoding: set by user. - * - decoding: set by lavc + * position of the top left corner in 1/16 pel for up to 3 fields/frames + * - encoding: Set by user. + * - decoding: Set by libavcodec. */ int16_t position[3][2]; }AVPanScan; @@ -481,99 +536,99 @@ typedef struct AVPanScan{ #define FF_COMMON_FRAME \ /**\ * pointer to the picture planes.\ - * this might be different from the first allocated byte\ + * This might be different from the first allocated byte\ * - encoding: \ * - decoding: \ */\ uint8_t *data[4];\ int linesize[4];\ /**\ - * pointer to the first allocated byte of the picture. can be used in get_buffer/release_buffer\ - * this isn't used by lavc unless the default get/release_buffer() is used\ + * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.\ + * This isn't used by libavcodec unless the default get/release_buffer() is used.\ * - encoding: \ * - decoding: \ */\ uint8_t *base[4];\ /**\ * 1 -> keyframe, 0-> not\ - * - encoding: set by lavc\ - * - decoding: set by lavc\ + * - encoding: Set by libavcodec.\ + * - decoding: Set by libavcodec.\ */\ int key_frame;\ \ /**\ - * picture type of the frame, see ?_TYPE below.\ - * - encoding: set by lavc for coded_picture (and set by user for input)\ - * - decoding: set by lavc\ + * Picture type of the frame, see ?_TYPE below.\ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ */\ int pict_type;\ \ /**\ * presentation timestamp in time_base units (time when frame should be shown to user)\ - * if AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed\ - * - encoding: MUST be set by user\ - * - decoding: set by lavc\ + * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.\ + * - encoding: MUST be set by user.\ + * - decoding: Set by libavcodec.\ */\ int64_t pts;\ \ /**\ - * picture number in bitstream order.\ + * picture number in bitstream order\ * - encoding: set by\ - * - decoding: set by lavc\ + * - decoding: Set by libavcodec.\ */\ int coded_picture_number;\ /**\ - * picture number in display order.\ + * picture number in display order\ * - encoding: set by\ - * - decoding: set by lavc\ + * - decoding: Set by libavcodec.\ */\ int display_picture_number;\ \ /**\ * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ - * - encoding: set by lavc for coded_picture (and set by user for input)\ - * - decoding: set by lavc\ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ */\ int quality; \ \ /**\ * buffer age (1->was last buffer and dint change, 2->..., ...).\ - * set to INT_MAX if the buffer has not been used yet \ + * Set to INT_MAX if the buffer has not been used yet.\ * - encoding: unused\ - * - decoding: MUST be set by get_buffer()\ + * - decoding: MUST be set by get_buffer().\ */\ int age;\ \ /**\ * is this picture used as reference\ * - encoding: unused\ - * - decoding: set by lavc (before get_buffer() call))\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ */\ int reference;\ \ /**\ * QP table\ * - encoding: unused\ - * - decoding: set by lavc\ + * - decoding: Set by libavcodec.\ */\ int8_t *qscale_table;\ /**\ * QP store stride\ * - encoding: unused\ - * - decoding: set by lavc\ + * - decoding: Set by libavcodec.\ */\ int qstride;\ \ /**\ - * mbskip_table[mb]>=1 if MB didnt change\ + * mbskip_table[mb]>=1 if MB didn't change\ * stride= mb_width = (width+15)>>4\ * - encoding: unused\ - * - decoding: set by lavc\ + * - decoding: Set by libavcodec.\ */\ uint8_t *mbskip_table;\ \ /**\ - * Motion vector table.\ + * motion vector table\ * @code\ * example:\ * int mv_sample_log2= 4 - motion_subsample_log2;\ @@ -581,16 +636,16 @@ typedef struct AVPanScan{ * int mv_stride= (mb_width << mv_sample_log2) + 1;\ * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];\ * @endcode\ - * - encoding: set by user\ - * - decoding: set by lavc\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ */\ int16_t (*motion_val[2])[2];\ \ /**\ - * Macroblock type table\ + * macroblock type table\ * mb_type_base + mb_width + 2\ - * - encoding: set by user\ - * - decoding: set by lavc\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ */\ uint32_t *mb_type;\ \ @@ -598,37 +653,37 @@ typedef struct AVPanScan{ * log2 of the size of the block which a single vector in motion_val represents: \ * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)\ * - encoding: unused\ - * - decoding: set by lavc\ + * - decoding: Set by libavcodec.\ */\ uint8_t motion_subsample_log2;\ \ /**\ * for some private data of the user\ * - encoding: unused\ - * - decoding: set by user\ + * - decoding: Set by user.\ */\ void *opaque;\ \ /**\ * error\ - * - encoding: set by lavc if flags&CODEC_FLAG_PSNR\ + * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\ * - decoding: unused\ */\ uint64_t error[4];\ \ /**\ - * type of the buffer (to keep track of who has to dealloc data[*])\ - * - encoding: set by the one who allocs it\ - * - decoding: set by the one who allocs it\ - * Note: user allocated (direct rendering) & internal buffers can not coexist currently\ + * type of the buffer (to keep track of who has to deallocate data[*])\ + * - encoding: Set by the one who allocates it.\ + * - decoding: Set by the one who allocates it.\ + * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\ */\ int type;\ \ /**\ - * when decoding, this signal how much the picture must be delayed.\ + * When decoding, this signals how much the picture must be delayed.\ * extra_delay = repeat_pict / (2*fps)\ * - encoding: unused\ - * - decoding: set by lavc\ + * - decoding: Set by libavcodec.\ */\ int repeat_pict;\ \ @@ -639,50 +694,50 @@ typedef struct AVPanScan{ \ /**\ * The content of the picture is interlaced.\ - * - encoding: set by user\ - * - decoding: set by lavc (default 0)\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec. (default 0)\ */\ int interlaced_frame;\ \ /**\ - * if the content is interlaced, is top field displayed first.\ - * - encoding: set by user\ - * - decoding: set by lavc\ + * If the content is interlaced, is top field displayed first.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ */\ int top_field_first;\ \ /**\ * Pan scan.\ - * - encoding: set by user\ - * - decoding: set by lavc\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ */\ AVPanScan *pan_scan;\ \ /**\ - * tell user application that palette has changed from previous frame.\ + * Tell user application that palette has changed from previous frame.\ * - encoding: ??? (no palette-enabled encoder yet)\ - * - decoding: set by lavc (default 0)\ + * - decoding: Set by libavcodec. (default 0).\ */\ int palette_has_changed;\ \ /**\ - * Codec suggestion on buffer type if != 0\ + * codec suggestion on buffer type if != 0\ * - encoding: unused\ - * - decoding: set by lavc (before get_buffer() call))\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ */\ int buffer_hints;\ \ /**\ - * DCT coeffitients\ + * DCT coefficients\ * - encoding: unused\ - * - decoding: set by lavc\ + * - decoding: Set by libavcodec.\ */\ short *dct_coeff;\ \ /**\ - * Motion referece frame index\ - * - encoding: set by user\ - * - decoding: set by lavc\ + * motion referece frame index\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ */\ int8_t *ref_index[2]; @@ -691,25 +746,31 @@ typedef struct AVPanScan{ #define FF_QSCALE_TYPE_H264 2 #define FF_BUFFER_TYPE_INTERNAL 1 -#define FF_BUFFER_TYPE_USER 2 ///< Direct rendering buffers (image is (de)allocated by user) -#define FF_BUFFER_TYPE_SHARED 4 ///< buffer from somewhere else, don't dealloc image (data/base), all other tables are not shared -#define FF_BUFFER_TYPE_COPY 8 ///< just a (modified) copy of some other buffer, don't dealloc anything +#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user) +#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared. +#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything. -#define FF_I_TYPE 1 // Intra -#define FF_P_TYPE 2 // Predicted -#define FF_B_TYPE 3 // Bi-dir predicted -#define FF_S_TYPE 4 // S(GMC)-VOP MPEG4 +#define FF_I_TYPE 1 // Intra +#define FF_P_TYPE 2 // Predicted +#define FF_B_TYPE 3 // Bi-dir predicted +#define FF_S_TYPE 4 // S(GMC)-VOP MPEG4 #define FF_SI_TYPE 5 #define FF_SP_TYPE 6 -#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore) -#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer -#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content -#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update) +#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore). +#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer. +#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content. +#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update). /** * Audio Video Frame. + * New fields can be added to the end of FF_COMMON_FRAME with minor version + * bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. No fields should be added into AVFrame before or after + * FF_COMMON_FRAME! + * sizeof(AVFrame) must not be used outside libav*. */ typedef struct AVFrame { FF_COMMON_FRAME @@ -718,48 +779,52 @@ typedef struct AVFrame { #define DEFAULT_FRAME_RATE_BASE 1001000 /** - * main external api structure. + * main external API structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVCodecContext) must not be used outside libav*. */ typedef struct AVCodecContext { /** - * Info on struct for av_log + * information on struct for av_log * - set by avcodec_alloc_context */ AVClass *av_class; /** - * the average bitrate. - * - encoding: set by user. unused for constant quantizer encoding - * - decoding: set by lavc. 0 or some bitrate if this info is available in the stream + * the average bitrate + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream. */ int bit_rate; /** * number of bits the bitstream is allowed to diverge from the reference. * the reference can be CBR (for CBR pass1) or VBR (for pass2) - * - encoding: set by user. unused for constant quantizer encoding + * - encoding: Set by user; unused for constant quantizer encoding. * - decoding: unused */ int bit_rate_tolerance; /** * CODEC_FLAG_*. - * - encoding: set by user. - * - decoding: set by user. + * - encoding: Set by user. + * - decoding: Set by user. */ int flags; /** - * some codecs needs additionnal format info. It is stored here - * if any muxer uses this then ALL demuxers/parsers AND encoders for the specific codec MUST set it correctly - * too otherwise stream copy breaks - * in general use of this field by muxers is not recommanded - * - encoding: set by lavc. - * - decoding: set by lavc. (FIXME is this ok?) + * Some codecs need additional format info. It is stored here. + * If any muxer uses this then ALL demuxers/parsers AND encoders for the + * specific codec MUST set it correctly otherwise stream copy breaks. + * In general use of this field by muxers is not recommanded. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. (FIXME: Is this OK?) */ int sub_id; /** - * motion estimation algorithm used for video coding. + * Motion estimation algorithm used for video coding. * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex), * 8 (umh), 9 (iter) [7, 8 are x264 specific, 9 is snow specific] * - encoding: MUST be set by user. @@ -768,26 +833,26 @@ typedef struct AVCodecContext { int me_method; /** - * some codecs need / can use extra-data like huffman tables. - * mjpeg: huffman tables + * some codecs need / can use extradata like Huffman tables. + * mjpeg: Huffman tables * rv10: additional flags * mpeg4: global headers (they can be in the bitstream or here) - * the allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger - * then extradata_size to avoid prolems if its read with the bitstream reader - * the bytewise contents of extradata must not depend on the architecture or cpu endianness - * - encoding: set/allocated/freed by lavc. - * - decoding: set/allocated/freed by user. + * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger + * than extradata_size to avoid prolems if it is read with the bitstream reader. + * The bytewise contents of extradata must not depend on the architecture or CPU endianness. + * - encoding: Set/allocated/freed by libavcodec. + * - decoding: Set/allocated/freed by user. */ uint8_t *extradata; int extradata_size; /** - * this is the fundamental unit of time (in seconds) in terms - * of which frame timestamps are represented. for fixed-fps content, + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, * timebase should be 1/framerate and timestamp increments should be * identically 1. - * - encoding: MUST be set by user - * - decoding: set by lavc. + * - encoding: MUST be set by user. + * - decoding: Set by libavcodec. */ AVRational time_base; @@ -795,43 +860,43 @@ typedef struct AVCodecContext { /** * picture width / height. * - encoding: MUST be set by user. - * - decoding: set by lavc. - * Note, for compatibility its possible to set this instead of - * coded_width/height before decoding + * - decoding: Set by libavcodec. + * Note: For compatibility it is possible to set this instead of + * coded_width/height before decoding. */ int width, height; #define FF_ASPECT_EXTENDED 15 /** - * the number of pictures in a group of pitures, or 0 for intra_only. - * - encoding: set by user. + * the number of pictures in a group of pictures, or 0 for intra_only + * - encoding: Set by user. * - decoding: unused */ int gop_size; /** - * pixel format, see PIX_FMT_xxx. - * - encoding: set by user. - * - decoding: set by lavc. + * Pixel format, see PIX_FMT_xxx. + * - encoding: Set by user. + * - decoding: Set by libavcodec. */ enum PixelFormat pix_fmt; /** - * Frame rate emulation. If not zero lower layer (i.e. format handler) + * Frame rate emulation. If not zero, the lower layer (i.e. format handler) * has to read frames at native frame rate. - * - encoding: set by user. - * - decoding: unused. + * - encoding: Set by user. + * - decoding: unused */ int rate_emu; /** - * if non NULL, 'draw_horiz_band' is called by the libavcodec - * decoder to draw an horizontal band. It improve cache usage. Not + * If non NULL, 'draw_horiz_band' is called by the libavcodec + * decoder to draw a horizontal band. It improves cache usage. Not * all codecs can do that. You must check the codec capabilities - * before + * beforehand. * - encoding: unused - * - decoding: set by user. + * - decoding: Set by user. * @param height the height of the slice * @param y the y position of the slice * @param type 1->top field, 2->bottom field, 3->frame @@ -842,28 +907,28 @@ typedef struct AVCodecContext { int y, int type, int height); /* audio only */ - int sample_rate; ///< samples per sec + int sample_rate; ///< samples per second int channels; /** - * audio sample format. - * - encoding: set by user. - * - decoding: set by lavc. + * audio sample format + * - encoding: Set by user. + * - decoding: Set by libavcodec. */ - enum SampleFormat sample_fmt; ///< sample format, currenly unused + enum SampleFormat sample_fmt; ///< sample format, currently unused - /* the following data should not be initialized */ + /* The following data should not be initialized. */ /** - * samples per packet. initialized when calling 'init' + * Samples per packet, initialized when calling 'init'. */ int frame_size; int frame_number; ///< audio or video frame number - int real_pict_num; ///< returns the real picture number of previous encoded frame + int real_pict_num; ///< Returns the real picture number of previous encoded frame. /** - * number of frames the decoded output will be delayed relative to + * Number of frames the decoded output will be delayed relative to * the encoded input. - * - encoding: set by lavc. + * - encoding: Set by libavcodec. * - decoding: unused */ int delay; @@ -873,37 +938,37 @@ typedef struct AVCodecContext { float qblur; ///< amount of qscale smoothing over time (0.0-1.0) /** - * minimum quantizer. - * - encoding: set by user. + * minimum quantizer + * - encoding: Set by user. * - decoding: unused */ int qmin; /** - * maximum quantizer. - * - encoding: set by user. + * maximum quantizer + * - encoding: Set by user. * - decoding: unused */ int qmax; /** - * maximum quantizer difference between frames. - * - encoding: set by user. + * maximum quantizer difference between frames + * - encoding: Set by user. * - decoding: unused */ int max_qdiff; /** - * maximum number of b frames between non b frames. - * note: the output will be delayed by max_b_frames+1 relative to the input - * - encoding: set by user. + * maximum number of B-frames between non-B-frames + * Note: The output will be delayed by max_b_frames+1 relative to the input. + * - encoding: Set by user. * - decoding: unused */ int max_b_frames; /** - * qscale factor between ip and b frames. - * - encoding: set by user. + * qscale factor between IP and B-frames + * - encoding: Set by user. * - decoding: unused */ float b_quant_factor; @@ -915,9 +980,9 @@ typedef struct AVCodecContext { int b_frame_strategy; /** - * hurry up amount. + * hurry up amount * - encoding: unused - * - decoding: set by user. 1-> skip b frames, 2-> skip idct/dequant too, 5-> skip everything except header + * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header * @deprecated Deprecated in favor of skip_idct and skip_frame. */ int hurry_up; @@ -932,19 +997,19 @@ typedef struct AVCodecContext { #endif int rtp_payload_size; /* The size of the RTP payload: the coder will */ - /* do it's best to deliver a chunk with size */ + /* do its best to deliver a chunk with size */ /* below rtp_payload_size, the chunk will start */ - /* with a start code on some codecs like H.263 */ + /* with a start code on some codecs like H.263. */ /* This doesn't take account of any particular */ - /* headers inside the transmited RTP payload */ + /* headers inside the transmitted RTP payload. */ - /* The RTP callback: This function is called */ - /* every time the encoder has a packet to send */ - /* Depends on the encoder if the data starts */ - /* with a Start Code (it should) H.263 does. */ - /* mb_nb contains the number of macroblocks */ - /* encoded in the RTP payload */ + /* The RTP callback: This function is called */ + /* every time the encoder has a packet to send. */ + /* It depends on the encoder if the data starts */ + /* with a Start Code (it should). H.263 does. */ + /* mb_nb contains the number of macroblocks */ + /* encoded in the RTP payload. */ void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb); /* statistics, used for 2-pass encoding */ @@ -958,16 +1023,16 @@ typedef struct AVCodecContext { int misc_bits; /** - * number of bits used for the previously encoded frame. - * - encoding: set by lavc + * number of bits used for the previously encoded frame + * - encoding: Set by libavcodec. * - decoding: unused */ int frame_bits; /** - * private data of the user, can be used to carry app specific stuff. - * - encoding: set by user - * - decoding: set by user + * Private data of the user, can be used to carry app specific stuff. + * - encoding: Set by user. + * - decoding: Set by user. */ void *opaque; @@ -977,23 +1042,23 @@ typedef struct AVCodecContext { /** * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). - * this is used to workaround some encoder bugs - * a demuxer should set this to what is stored in the field used to identify the codec - * if there are mutiple such fields in a container then the demuxer should choose the one - * which maximizes the information about the used codec - * if the codec tag field in a container is larger then 32bit then the demxuer should - * remap the longer id to 32bit with a table or other structure alternatively a new + * This is used to work around some encoder bugs. + * A demuxer should set this to what is stored in the field used to identify the codec. + * If there are multiple such fields in a container then the demuxer should choose the one + * which maximizes the information about the used codec. + * If the codec tag field in a container is larger then 32 bits then the demuxer should + * remap the longer ID to 32 bits with a table or other structure. Alternatively a new * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated - * first - * - encoding: set by user, if not then the default based on codec_id will be used - * - decoding: set by user, will be converted to upper case by lavc during init + * first. + * - encoding: Set by user, if not then the default based on codec_id will be used. + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. */ unsigned int codec_tag; /** - * workaround bugs in encoders which sometimes cannot be detected automatically. - * - encoding: set by user - * - decoding: set by user + * Work around bugs in encoders which sometimes cannot be detected automatically. + * - encoding: Set by user + * - decoding: Set by user */ int workaround_bugs; #define FF_BUG_AUTODETECT 1 ///< autodetection @@ -1002,7 +1067,7 @@ typedef struct AVCodecContext { #define FF_BUG_UMP4 8 #define FF_BUG_NO_PADDING 16 #define FF_BUG_AMV 32 -#define FF_BUG_AC_VLC 0 ///< will be removed, libavcodec can now handle these non compliant files by default +#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default. #define FF_BUG_QPEL_CHROMA 64 #define FF_BUG_STD_QPEL 128 #define FF_BUG_QPEL_CHROMA2 256 @@ -1010,49 +1075,49 @@ typedef struct AVCodecContext { #define FF_BUG_EDGE 1024 #define FF_BUG_HPEL_CHROMA 2048 #define FF_BUG_DC_CLIP 4096 -#define FF_BUG_MS 8192 ///< workaround various bugs in microsofts broken decoders -//#define FF_BUG_FAKE_SCALABILITY 16 //autodetection should work 100% +#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders. +//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%. /** - * luma single coeff elimination threshold. - * - encoding: set by user + * luma single coefficient elimination threshold + * - encoding: Set by user. * - decoding: unused */ int luma_elim_threshold; /** - * chroma single coeff elimination threshold. - * - encoding: set by user + * chroma single coeff elimination threshold + * - encoding: Set by user. * - decoding: unused */ int chroma_elim_threshold; /** - * strictly follow the std (MPEG4, ...). - * - encoding: set by user + * strictly follow the standard (MPEG4, ...). + * - encoding: Set by user. * - decoding: unused */ int strict_std_compliance; -#define FF_COMPLIANCE_VERY_STRICT 2 ///< strictly conform to a older more strict version of the spec or reference software -#define FF_COMPLIANCE_STRICT 1 ///< strictly conform to all the things in the spec no matter what consequences +#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to a older more strict version of the spec or reference software. +#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences. #define FF_COMPLIANCE_NORMAL 0 -#define FF_COMPLIANCE_INOFFICIAL -1 ///< allow inofficial extensions -#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< allow non standarized experimental things +#define FF_COMPLIANCE_INOFFICIAL -1 ///< Allow inofficial extensions. +#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things. /** - * qscale offset between ip and b frames. - * if > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset) - * if < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset) - * - encoding: set by user. + * qscale offset between IP and B-frames + * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. * - decoding: unused */ float b_quant_offset; /** - * error resilience higher values will detect more errors but may missdetect - * some more or less valid parts as errors. + * Error resilience; higher values will detect more errors but may + * misdetect some more or less valid parts as errors. * - encoding: unused - * - decoding: set by user + * - decoding: Set by user. */ int error_resilience; #define FF_ER_CAREFUL 1 @@ -1061,67 +1126,67 @@ typedef struct AVCodecContext { #define FF_ER_VERY_AGGRESSIVE 4 /** - * called at the beginning of each frame to get a buffer for it. - * if pic.reference is set then the frame will be read later by lavc + * Called at the beginning of each frame to get a buffer for it. + * If pic.reference is set then the frame will be read later by libavcodec. * avcodec_align_dimensions() should be used to find the required width and - * height, as they normally need to be rounded up to the next multiple of 16 + * height, as they normally need to be rounded up to the next multiple of 16. * - encoding: unused - * - decoding: set by lavc, user can override + * - decoding: Set by libavcodec., user can override. */ int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); /** - * called to release buffers which where allocated with get_buffer. - * a released buffer can be reused in get_buffer() - * pic.data[*] must be set to NULL + * Called to release buffers which where allocated with get_buffer. + * A released buffer can be reused in get_buffer(). + * pic.data[*] must be set to NULL. * - encoding: unused - * - decoding: set by lavc, user can override + * - decoding: Set by libavcodec., user can override. */ void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); /** - * if 1 the stream has a 1 frame delay during decoding. - * - encoding: set by lavc - * - decoding: set by lavc + * If 1 the stream has a 1 frame delay during decoding. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. */ int has_b_frames; /** * number of bytes per packet if constant and known or 0 - * used by some WAV based audio codecs + * Used by some WAV based audio codecs. */ int block_align; - int parse_only; /* - decoding only: if true, only parsing is done + int parse_only; /* - decoding only: If true, only parsing is done (function avcodec_parse_frame()). The frame data is returned. Only MPEG codecs support this now. */ /** - * 0-> h263 quant 1-> mpeg quant. - * - encoding: set by user. + * 0-> h263 quant 1-> mpeg quant + * - encoding: Set by user. * - decoding: unused */ int mpeg_quant; /** - * pass1 encoding statistics output buffer. - * - encoding: set by lavc + * pass1 encoding statistics output buffer + * - encoding: Set by libavcodec. * - decoding: unused */ char *stats_out; /** - * pass2 encoding statistics input buffer. - * concatenated stuff from stats_out of pass1 should be placed here - * - encoding: allocated/set/freed by user + * pass2 encoding statistics input buffer + * Concatenated stuff from stats_out of pass1 should be placed here. + * - encoding: Allocated/set/freed by user. * - decoding: unused */ char *stats_in; /** - * ratecontrol qmin qmax limiting method. - * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax - * - encoding: set by user. + * ratecontrol qmin qmax limiting method + * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax. + * - encoding: Set by user. * - decoding: unused */ float rc_qsquish; @@ -1130,68 +1195,68 @@ typedef struct AVCodecContext { int rc_qmod_freq; /** - * ratecontrol override, see RcOverride. - * - encoding: allocated/set/freed by user. + * ratecontrol override, see RcOverride + * - encoding: Allocated/set/freed by user. * - decoding: unused */ RcOverride *rc_override; int rc_override_count; /** - * rate control equation. - * - encoding: set by user + * rate control equation + * - encoding: Set by user * - decoding: unused */ - char *rc_eq; + const char *rc_eq; /** - * maximum bitrate. - * - encoding: set by user. + * maximum bitrate + * - encoding: Set by user. * - decoding: unused */ int rc_max_rate; /** - * minimum bitrate. - * - encoding: set by user. + * minimum bitrate + * - encoding: Set by user. * - decoding: unused */ int rc_min_rate; /** - * decoder bitstream buffer size. - * - encoding: set by user. + * decoder bitstream buffer size + * - encoding: Set by user. * - decoding: unused */ int rc_buffer_size; float rc_buffer_aggressivity; /** - * qscale factor between p and i frames. - * if > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset) - * if < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset) - * - encoding: set by user. + * qscale factor between P and I-frames + * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. * - decoding: unused */ float i_quant_factor; /** - * qscale offset between p and i frames. - * - encoding: set by user. + * qscale offset between P and I-frames + * - encoding: Set by user. * - decoding: unused */ float i_quant_offset; /** - * initial complexity for pass1 ratecontrol. - * - encoding: set by user. + * initial complexity for pass1 ratecontrol + * - encoding: Set by user. * - decoding: unused */ float rc_initial_cplx; /** - * dct algorithm, see FF_DCT_* below. - * - encoding: set by user + * DCT algorithm, see FF_DCT_* below + * - encoding: Set by user. * - decoding: unused */ int dct_algo; @@ -1204,86 +1269,91 @@ typedef struct AVCodecContext { #define FF_DCT_FAAN 6 /** - * luminance masking (0-> disabled). - * - encoding: set by user + * luminance masking (0-> disabled) + * - encoding: Set by user. * - decoding: unused */ float lumi_masking; /** - * temporary complexity masking (0-> disabled). - * - encoding: set by user + * temporary complexity masking (0-> disabled) + * - encoding: Set by user. * - decoding: unused */ float temporal_cplx_masking; /** - * spatial complexity masking (0-> disabled). - * - encoding: set by user + * spatial complexity masking (0-> disabled) + * - encoding: Set by user. * - decoding: unused */ float spatial_cplx_masking; /** - * p block masking (0-> disabled). - * - encoding: set by user + * p block masking (0-> disabled) + * - encoding: Set by user. * - decoding: unused */ float p_masking; /** - * darkness masking (0-> disabled). - * - encoding: set by user + * darkness masking (0-> disabled) + * - encoding: Set by user. * - decoding: unused */ float dark_masking; +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) /* for binary compatibility */ int unused; +#endif /** - * idct algorithm, see FF_IDCT_* below. - * - encoding: set by user - * - decoding: set by user + * IDCT algorithm, see FF_IDCT_* below. + * - encoding: Set by user. + * - decoding: Set by user. */ int idct_algo; -#define FF_IDCT_AUTO 0 -#define FF_IDCT_INT 1 -#define FF_IDCT_SIMPLE 2 -#define FF_IDCT_SIMPLEMMX 3 -#define FF_IDCT_LIBMPEG2MMX 4 -#define FF_IDCT_PS2 5 -#define FF_IDCT_MLIB 6 -#define FF_IDCT_ARM 7 -#define FF_IDCT_ALTIVEC 8 -#define FF_IDCT_SH4 9 -#define FF_IDCT_SIMPLEARM 10 -#define FF_IDCT_H264 11 -#define FF_IDCT_VP3 12 -#define FF_IDCT_IPP 13 -#define FF_IDCT_XVIDMMX 14 -#define FF_IDCT_CAVS 15 +#define FF_IDCT_AUTO 0 +#define FF_IDCT_INT 1 +#define FF_IDCT_SIMPLE 2 +#define FF_IDCT_SIMPLEMMX 3 +#define FF_IDCT_LIBMPEG2MMX 4 +#define FF_IDCT_PS2 5 +#define FF_IDCT_MLIB 6 +#define FF_IDCT_ARM 7 +#define FF_IDCT_ALTIVEC 8 +#define FF_IDCT_SH4 9 +#define FF_IDCT_SIMPLEARM 10 +#define FF_IDCT_H264 11 +#define FF_IDCT_VP3 12 +#define FF_IDCT_IPP 13 +#define FF_IDCT_XVIDMMX 14 +#define FF_IDCT_CAVS 15 #define FF_IDCT_SIMPLEARMV5TE 16 -#define FF_IDCT_SIMPLEARMV6 17 +#define FF_IDCT_SIMPLEARMV6 17 +#define FF_IDCT_SIMPLEVIS 18 +#define FF_IDCT_WMV2 19 +#define FF_IDCT_FAAN 20 /** - * slice count. - * - encoding: set by lavc - * - decoding: set by user (or 0) + * slice count + * - encoding: Set by libavcodec. + * - decoding: Set by user (or 0). */ int slice_count; /** - * slice offsets in the frame in bytes. - * - encoding: set/allocated by lavc - * - decoding: set/allocated by user (or NULL) + * slice offsets in the frame in bytes + * - encoding: Set/allocated by libavcodec. + * - decoding: Set/allocated by user (or NULL). */ int *slice_offset; /** - * error concealment flags. + * error concealment flags * - encoding: unused - * - decoding: set by user + * - decoding: Set by user. */ int error_concealment; #define FF_EC_GUESS_MVS 1 @@ -1293,35 +1363,33 @@ typedef struct AVCodecContext { * dsp_mask could be add used to disable unwanted CPU features * CPU features (i.e. MMX, SSE. ...) * - * with FORCE flag you may instead enable given CPU features - * (Dangerous: usable in case of misdetection, improper usage however will - * result into program crash) + * With the FORCE flag you may instead enable given CPU features. + * (Dangerous: Usable in case of misdetection, improper usage however will + * result into program crash.) */ unsigned dsp_mask; -#define FF_MM_FORCE 0x80000000 /* force usage of selected flags (OR) */ +#define FF_MM_FORCE 0x80000000 /* Force usage of selected flags (OR) */ /* lower 16 bits - CPU features */ -#ifdef HAVE_MMX -#define FF_MM_MMX 0x0001 /* standard MMX */ -#define FF_MM_3DNOW 0x0004 /* AMD 3DNOW */ -#define FF_MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */ -#define FF_MM_SSE 0x0008 /* SSE functions */ -#define FF_MM_SSE2 0x0010 /* PIV SSE2 functions */ -#define FF_MM_3DNOWEXT 0x0020 /* AMD 3DNowExt */ -#endif /* HAVE_MMX */ -#ifdef HAVE_IWMMXT -#define FF_MM_IWMMXT 0x0100 /* XScale IWMMXT */ -#endif /* HAVE_IWMMXT */ +#define FF_MM_MMX 0x0001 ///< standard MMX +#define FF_MM_3DNOW 0x0004 ///< AMD 3DNOW +#define FF_MM_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext +#define FF_MM_SSE 0x0008 ///< SSE functions +#define FF_MM_SSE2 0x0010 ///< PIV SSE2 functions +#define FF_MM_3DNOWEXT 0x0020 ///< AMD 3DNowExt +#define FF_MM_SSE3 0x0040 ///< Prescott SSE3 functions +#define FF_MM_SSSE3 0x0080 ///< Conroe SSSE3 functions +#define FF_MM_IWMMXT 0x0100 ///< XScale IWMMXT /** * bits per sample/pixel from the demuxer (needed for huffyuv). - * - encoding: set by lavc - * - decoding: set by user + * - encoding: Set by libavcodec. + * - decoding: Set by user. */ int bits_per_sample; /** - * prediction method (needed for huffyuv). - * - encoding: set by user + * prediction method (needed for huffyuv) + * - encoding: Set by user. * - decoding: unused */ int prediction_method; @@ -1330,46 +1398,46 @@ typedef struct AVCodecContext { #define FF_PRED_MEDIAN 2 /** - * sample aspect ratio (0 if unknown). - * numerator and denominator must be relative prime and smaller then 256 for some video standards - * - encoding: set by user. - * - decoding: set by lavc. + * sample aspect ratio (0 if unknown) + * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. + * - encoding: Set by user. + * - decoding: Set by libavcodec. */ AVRational sample_aspect_ratio; /** - * the picture in the bitstream. - * - encoding: set by lavc - * - decoding: set by lavc + * the picture in the bitstream + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. */ AVFrame *coded_frame; /** - * debug. - * - encoding: set by user. - * - decoding: set by user. + * debug + * - encoding: Set by user. + * - decoding: Set by user. */ int debug; -#define FF_DEBUG_PICT_INFO 1 -#define FF_DEBUG_RC 2 -#define FF_DEBUG_BITSTREAM 4 -#define FF_DEBUG_MB_TYPE 8 -#define FF_DEBUG_QP 16 -#define FF_DEBUG_MV 32 -#define FF_DEBUG_DCT_COEFF 0x00000040 -#define FF_DEBUG_SKIP 0x00000080 -#define FF_DEBUG_STARTCODE 0x00000100 -#define FF_DEBUG_PTS 0x00000200 -#define FF_DEBUG_ER 0x00000400 -#define FF_DEBUG_MMCO 0x00000800 -#define FF_DEBUG_BUGS 0x00001000 -#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_PICT_INFO 1 +#define FF_DEBUG_RC 2 +#define FF_DEBUG_BITSTREAM 4 +#define FF_DEBUG_MB_TYPE 8 +#define FF_DEBUG_QP 16 +#define FF_DEBUG_MV 32 +#define FF_DEBUG_DCT_COEFF 0x00000040 +#define FF_DEBUG_SKIP 0x00000080 +#define FF_DEBUG_STARTCODE 0x00000100 +#define FF_DEBUG_PTS 0x00000200 +#define FF_DEBUG_ER 0x00000400 +#define FF_DEBUG_MMCO 0x00000800 +#define FF_DEBUG_BUGS 0x00001000 +#define FF_DEBUG_VIS_QP 0x00002000 #define FF_DEBUG_VIS_MB_TYPE 0x00004000 /** - * debug. - * - encoding: set by user. - * - decoding: set by user. + * debug + * - encoding: Set by user. + * - decoding: Set by user. */ int debug_mv; #define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames @@ -1377,127 +1445,127 @@ typedef struct AVCodecContext { #define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames /** - * error. - * - encoding: set by lavc if flags&CODEC_FLAG_PSNR + * error + * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR. * - decoding: unused */ uint64_t error[4]; /** - * minimum MB quantizer. + * minimum MB quantizer * - encoding: unused * - decoding: unused */ int mb_qmin; /** - * maximum MB quantizer. + * maximum MB quantizer * - encoding: unused * - decoding: unused */ int mb_qmax; /** - * motion estimation compare function. - * - encoding: set by user. + * motion estimation comparison function + * - encoding: Set by user. * - decoding: unused */ int me_cmp; /** - * subpixel motion estimation compare function. - * - encoding: set by user. + * subpixel motion estimation comparison function + * - encoding: Set by user. * - decoding: unused */ int me_sub_cmp; /** - * macroblock compare function (not supported yet). - * - encoding: set by user. + * macroblock comparison function (not supported yet) + * - encoding: Set by user. * - decoding: unused */ int mb_cmp; /** - * interlaced dct compare function - * - encoding: set by user. + * interlaced DCT comparison function + * - encoding: Set by user. * - decoding: unused */ int ildct_cmp; -#define FF_CMP_SAD 0 -#define FF_CMP_SSE 1 -#define FF_CMP_SATD 2 -#define FF_CMP_DCT 3 -#define FF_CMP_PSNR 4 -#define FF_CMP_BIT 5 -#define FF_CMP_RD 6 -#define FF_CMP_ZERO 7 -#define FF_CMP_VSAD 8 -#define FF_CMP_VSSE 9 -#define FF_CMP_NSSE 10 -#define FF_CMP_W53 11 -#define FF_CMP_W97 12 +#define FF_CMP_SAD 0 +#define FF_CMP_SSE 1 +#define FF_CMP_SATD 2 +#define FF_CMP_DCT 3 +#define FF_CMP_PSNR 4 +#define FF_CMP_BIT 5 +#define FF_CMP_RD 6 +#define FF_CMP_ZERO 7 +#define FF_CMP_VSAD 8 +#define FF_CMP_VSSE 9 +#define FF_CMP_NSSE 10 +#define FF_CMP_W53 11 +#define FF_CMP_W97 12 #define FF_CMP_DCTMAX 13 #define FF_CMP_DCT264 14 #define FF_CMP_CHROMA 256 /** - * ME diamond size & shape. - * - encoding: set by user. + * ME diamond size & shape + * - encoding: Set by user. * - decoding: unused */ int dia_size; /** - * amount of previous MV predictors (2a+1 x 2a+1 square). - * - encoding: set by user. + * amount of previous MV predictors (2a+1 x 2a+1 square) + * - encoding: Set by user. * - decoding: unused */ int last_predictor_count; /** - * pre pass for motion estimation. - * - encoding: set by user. + * prepass for motion estimation + * - encoding: Set by user. * - decoding: unused */ int pre_me; /** - * motion estimation pre pass compare function. - * - encoding: set by user. + * motion estimation prepass comparison function + * - encoding: Set by user. * - decoding: unused */ int me_pre_cmp; /** - * ME pre pass diamond size & shape. - * - encoding: set by user. + * ME prepass diamond size & shape + * - encoding: Set by user. * - decoding: unused */ int pre_dia_size; /** - * subpel ME quality. - * - encoding: set by user. + * subpel ME quality + * - encoding: Set by user. * - decoding: unused */ int me_subpel_quality; /** - * callback to negotiate the pixelFormat. + * callback to negotiate the pixelFormat * @param fmt is the list of formats which are supported by the codec, - * its terminated by -1 as 0 is a valid format, the formats are ordered by quality - * the first is allways the native one - * @return the choosen format + * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. + * The first is always the native one. + * @return the chosen format * - encoding: unused - * - decoding: set by user, if not set then the native format will always be choosen + * - decoding: Set by user, if not set the native format will be chosen. */ enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt); /** - * DTG active format information (additionnal aspect ratio - * information only used in DVB MPEG2 transport streams). 0 if - * not set. + * DTG active format information (additional aspect ratio + * information only used in DVB MPEG-2 transport streams) + * 0 if not set. * - * - encoding: unused. - * - decoding: set by decoder + * - encoding: unused + * - decoding: Set by decoder. */ int dtg_active_format; #define FF_DTG_AFD_SAME 8 @@ -1509,46 +1577,46 @@ typedef struct AVCodecContext { #define FF_DTG_AFD_SP_4_3 15 /** - * Maximum motion estimation search range in subpel units. - * if 0 then no limit + * maximum motion estimation search range in subpel units + * If 0 then no limit. * - * - encoding: set by user. - * - decoding: unused. + * - encoding: Set by user. + * - decoding: unused */ int me_range; /** - * intra quantizer bias. - * - encoding: set by user. + * intra quantizer bias + * - encoding: Set by user. * - decoding: unused */ int intra_quant_bias; #define FF_DEFAULT_QUANT_BIAS 999999 /** - * inter quantizer bias. - * - encoding: set by user. + * inter quantizer bias + * - encoding: Set by user. * - decoding: unused */ int inter_quant_bias; /** - * color table ID. - * - encoding: unused. - * - decoding: which clrtable should be used for 8bit RGB images - * table have to be stored somewhere FIXME + * color table ID + * - encoding: unused + * - decoding: Which clrtable should be used for 8bit RGB images. + * Tables have to be stored somewhere. FIXME */ int color_table_id; /** - * internal_buffer count. - * Don't touch, used by lavc default_get_buffer() + * internal_buffer count + * Don't touch, used by libavcodec default_get_buffer(). */ int internal_buffer_count; /** - * internal_buffers. - * Don't touch, used by lavc default_get_buffer() + * internal_buffers + * Don't touch, used by libavcodec default_get_buffer(). */ void *internal_buffer; @@ -1559,25 +1627,28 @@ typedef struct AVCodecContext { #define FF_QUALITY_SCALE FF_LAMBDA_SCALE //FIXME maybe remove /** - * global quality for codecs which cannot change it per frame. - * this should be proportional to MPEG1/2/4 qscale. - * - encoding: set by user. + * Global quality for codecs which cannot change it per frame. + * This should be proportional to MPEG-1/2/4 qscale. + * - encoding: Set by user. * - decoding: unused */ int global_quality; -#define FF_CODER_TYPE_VLC 0 -#define FF_CODER_TYPE_AC 1 +#define FF_CODER_TYPE_VLC 0 +#define FF_CODER_TYPE_AC 1 +#define FF_CODER_TYPE_RAW 2 +#define FF_CODER_TYPE_RLE 3 +#define FF_CODER_TYPE_DEFLATE 4 /** * coder type - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int coder_type; /** * context model - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int context_model; @@ -1585,7 +1656,7 @@ typedef struct AVCodecContext { /** * * - encoding: unused - * - decoding: set by user. + * - decoding: Set by user. */ uint8_t * (*realloc)(struct AVCodecContext *s, uint8_t *buf, int buf_size); #endif @@ -1593,7 +1664,7 @@ typedef struct AVCodecContext { /** * slice flags * - encoding: unused - * - decoding: set by user. + * - decoding: Set by user. */ int slice_flags; #define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display @@ -1609,7 +1680,7 @@ typedef struct AVCodecContext { /** * macroblock decision mode - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int mb_decision; @@ -1619,105 +1690,105 @@ typedef struct AVCodecContext { /** * custom intra quantization matrix - * - encoding: set by user, can be NULL - * - decoding: set by lavc + * - encoding: Set by user, can be NULL. + * - decoding: Set by libavcodec. */ uint16_t *intra_matrix; /** * custom inter quantization matrix - * - encoding: set by user, can be NULL - * - decoding: set by lavc + * - encoding: Set by user, can be NULL. + * - decoding: Set by libavcodec. */ uint16_t *inter_matrix; /** * fourcc from the AVI stream header (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). - * this is used to workaround some encoder bugs + * This is used to work around some encoder bugs. * - encoding: unused - * - decoding: set by user, will be converted to upper case by lavc during init + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. */ unsigned int stream_codec_tag; /** - * scene change detection threshold. - * 0 is default, larger means fewer detected scene changes - * - encoding: set by user. + * scene change detection threshold + * 0 is default, larger means fewer detected scene changes. + * - encoding: Set by user. * - decoding: unused */ int scenechange_threshold; /** - * minimum lagrange multipler - * - encoding: set by user. + * minimum Lagrange multipler + * - encoding: Set by user. * - decoding: unused */ int lmin; /** - * maximum lagrange multipler - * - encoding: set by user. + * maximum Lagrange multipler + * - encoding: Set by user. * - decoding: unused */ int lmax; /** - * Palette control structure + * palette control structure * - encoding: ??? (no palette-enabled encoder yet) - * - decoding: set by user. + * - decoding: Set by user. */ struct AVPaletteControl *palctrl; /** * noise reduction strength - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int noise_reduction; /** - * called at the beginning of a frame to get cr buffer for it. - * buffer type (size, hints) must be the same. lavc won't check it. - * lavc will pass previous buffer in pic, function should return + * Called at the beginning of a frame to get cr buffer for it. + * Buffer type (size, hints) must be the same. libavcodec won't check it. + * libavcodec will pass previous buffer in pic, function should return * same buffer or new buffer with old frame "painted" into it. - * if pic.data[0] == NULL must behave like get_buffer(). + * If pic.data[0] == NULL must behave like get_buffer(). * - encoding: unused - * - decoding: set by lavc, user can override + * - decoding: Set by libavcodec., user can override */ int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); /** - * number of bits which should be loaded into the rc buffer before decoding starts - * - encoding: set by user. + * Number of bits which should be loaded into the rc buffer before decoding starts. + * - encoding: Set by user. * - decoding: unused */ int rc_initial_buffer_occupancy; /** * - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int inter_threshold; /** - * CODEC_FLAG2_*. - * - encoding: set by user. - * - decoding: set by user. + * CODEC_FLAG2_* + * - encoding: Set by user. + * - decoding: Set by user. */ int flags2; /** - * simulates errors in the bitstream to test error concealment. - * - encoding: set by user. - * - decoding: unused. + * Simulates errors in the bitstream to test error concealment. + * - encoding: Set by user. + * - decoding: unused */ int error_rate; /** * MP3 antialias algorithm, see FF_AA_* below. * - encoding: unused - * - decoding: set by user + * - decoding: Set by user. */ int antialias_algo; #define FF_AA_AUTO 0 @@ -1725,166 +1796,171 @@ typedef struct AVCodecContext { #define FF_AA_INT 2 #define FF_AA_FLOAT 3 /** - * Quantizer noise shaping. - * - encoding: set by user + * quantizer noise shaping + * - encoding: Set by user. * - decoding: unused */ int quantizer_noise_shaping; /** - * Thread count. + * thread count * is used to decide how many independent tasks should be passed to execute() - * - encoding: set by user - * - decoding: set by user + * - encoding: Set by user. + * - decoding: Set by user. */ int thread_count; /** - * the codec may call this to execute several independent things. it will return only after - * finishing all tasks, the user may replace this with some multithreaded implementation, the - * default implementation will execute the parts serially + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. * @param count the number of things to execute - * - encoding: set by lavc, user can override - * - decoding: set by lavc, user can override + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. */ int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void **arg2, int *ret, int count); /** - * Thread opaque. - * can be used by execute() to store some per AVCodecContext stuff. + * thread opaque + * Can be used by execute() to store some per AVCodecContext stuff. * - encoding: set by execute() * - decoding: set by execute() */ void *thread_opaque; /** - * Motion estimation threshold. under which no motion estimation is - * performed, but instead the user specified motion vectors are used + * Motion estimation threshold below which no motion estimation is + * performed, but instead the user specified motion vectors are used. * - * - encoding: set by user + * - encoding: Set by user. * - decoding: unused */ int me_threshold; /** - * Macroblock threshold. under which the user specified macroblock types will be used - * - encoding: set by user + * Macroblock threshold below which the user specified macroblock types will be used. + * - encoding: Set by user. * - decoding: unused */ int mb_threshold; /** - * precision of the intra dc coefficient - 8. - * - encoding: set by user + * precision of the intra DC coefficient - 8 + * - encoding: Set by user. * - decoding: unused */ int intra_dc_precision; /** - * noise vs. sse weight for the nsse comparsion function. - * - encoding: set by user + * noise vs. sse weight for the nsse comparsion function + * - encoding: Set by user. * - decoding: unused */ int nsse_weight; /** - * number of macroblock rows at the top which are skipped. + * Number of macroblock rows at the top which are skipped. * - encoding: unused - * - decoding: set by user + * - decoding: Set by user. */ int skip_top; /** - * number of macroblock rows at the bottom which are skipped. + * Number of macroblock rows at the bottom which are skipped. * - encoding: unused - * - decoding: set by user + * - decoding: Set by user. */ int skip_bottom; /** * profile - * - encoding: set by user - * - decoding: set by lavc + * - encoding: Set by user. + * - decoding: Set by libavcodec. */ int profile; #define FF_PROFILE_UNKNOWN -99 +#define FF_PROFILE_AAC_MAIN 0 +#define FF_PROFILE_AAC_LOW 1 +#define FF_PROFILE_AAC_SSR 2 +#define FF_PROFILE_AAC_LTP 3 /** * level - * - encoding: set by user - * - decoding: set by lavc + * - encoding: Set by user. + * - decoding: Set by libavcodec. */ int level; #define FF_LEVEL_UNKNOWN -99 /** - * low resolution decoding. 1-> 1/2 size, 2->1/4 size + * low resolution decoding, 1-> 1/2 size, 2->1/4 size * - encoding: unused - * - decoding: set by user + * - decoding: Set by user. */ int lowres; /** - * bitsream width / height. may be different from width/height if lowres - * or other things are used + * Bitstream width / height, may be different from width/height if lowres + * or other things are used. * - encoding: unused - * - decoding: set by user before init if known, codec should override / dynamically change if needed + * - decoding: Set by user before init if known. Codec should override / dynamically change if needed. */ int coded_width, coded_height; /** * frame skip threshold - * - encoding: set by user + * - encoding: Set by user. * - decoding: unused */ int frame_skip_threshold; /** * frame skip factor - * - encoding: set by user + * - encoding: Set by user. * - decoding: unused */ int frame_skip_factor; /** * frame skip exponent - * - encoding: set by user + * - encoding: Set by user. * - decoding: unused */ int frame_skip_exp; /** - * frame skip comparission function - * - encoding: set by user. + * frame skip comparison function + * - encoding: Set by user. * - decoding: unused */ int frame_skip_cmp; /** - * border processing masking. raises the quantizer for mbs on the borders + * Border processing masking, raises the quantizer for mbs on the borders * of the picture. - * - encoding: set by user + * - encoding: Set by user. * - decoding: unused */ float border_masking; /** - * minimum MB lagrange multipler. - * - encoding: set by user. + * minimum MB lagrange multipler + * - encoding: Set by user. * - decoding: unused */ int mb_lmin; /** - * maximum MB lagrange multipler. - * - encoding: set by user. + * maximum MB lagrange multipler + * - encoding: Set by user. * - decoding: unused */ int mb_lmax; /** * - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int me_penalty_compensation; @@ -1892,90 +1968,90 @@ typedef struct AVCodecContext { /** * * - encoding: unused - * - decoding: set by user. + * - decoding: Set by user. */ enum AVDiscard skip_loop_filter; /** * * - encoding: unused - * - decoding: set by user. + * - decoding: Set by user. */ enum AVDiscard skip_idct; /** * * - encoding: unused - * - decoding: set by user. + * - decoding: Set by user. */ enum AVDiscard skip_frame; /** * - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int bidir_refine; /** * - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int brd_scale; /** * constant rate factor - quality-based VBR - values ~correspond to qps - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ float crf; /** * constant quantization parameter rate control method - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int cqp; /** - * minimum gop size - * - encoding: set by user. + * minimum GOP size + * - encoding: Set by user. * - decoding: unused */ int keyint_min; /** * number of reference frames - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int refs; /** * chroma qp offset from luma - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int chromaoffset; /** - * influences how often b-frames are used - * - encoding: set by user. + * Influences how often B-frames are used. + * - encoding: Set by user. * - decoding: unused */ int bframebias; /** * trellis RD quantization - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int trellis; /** - * reduce fluctuations in qp (before curve compression) - * - encoding: set by user. + * Reduce fluctuations in qp (before curve compression). + * - encoding: Set by user. * - decoding: unused */ float complexityblur; @@ -1983,7 +2059,7 @@ typedef struct AVCodecContext { /** * in-loop deblocking filter alphac0 parameter * alpha is in the range -6...6 - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int deblockalpha; @@ -1991,123 +2067,144 @@ typedef struct AVCodecContext { /** * in-loop deblocking filter beta parameter * beta is in the range -6...6 - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int deblockbeta; /** * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4 - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int partitions; -#define X264_PART_I4X4 0x001 /* Analyse i4x4 */ -#define X264_PART_I8X8 0x002 /* Analyse i8x8 (requires 8x8 transform) */ -#define X264_PART_P8X8 0x010 /* Analyse p16x8, p8x16 and p8x8 */ -#define X264_PART_P4X4 0x020 /* Analyse p8x4, p4x8, p4x4 */ -#define X264_PART_B8X8 0x100 /* Analyse b16x8, b8x16 and b8x8 */ +#define X264_PART_I4X4 0x001 /* Analyze i4x4 */ +#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */ +#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */ +#define X264_PART_P4X4 0x020 /* Analyze p8x4, p4x8, p4x4 */ +#define X264_PART_B8X8 0x100 /* Analyze b16x8, b8x16 and b8x8 */ /** - * direct mv prediction mode - 0 (none), 1 (spatial), 2 (temporal) - * - encoding: set by user. + * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal) + * - encoding: Set by user. * - decoding: unused */ int directpred; /** - * audio cutoff bandwidth (0 means "automatic") . Currently used only by FAAC - * - encoding: set by user. + * Audio cutoff bandwidth (0 means "automatic") + * - encoding: Set by user. * - decoding: unused */ int cutoff; /** - * multiplied by qscale for each frame and added to scene_change_score - * - encoding: set by user. + * Multiplied by qscale for each frame and added to scene_change_score. + * - encoding: Set by user. * - decoding: unused */ int scenechange_factor; /** * - * note: value depends upon the compare functin used for fullpel ME - * - encoding: set by user. + * Note: Value depends upon the compare function used for fullpel ME. + * - encoding: Set by user. * - decoding: unused */ int mv0_threshold; /** - * adjusts sensitivity of b_frame_strategy 1 - * - encoding: set by user. + * Adjusts sensitivity of b_frame_strategy 1. + * - encoding: Set by user. * - decoding: unused */ int b_sensitivity; /** - * - encoding: set by user. + * - encoding: Set by user. * - decoding: unused */ int compression_level; #define FF_COMPRESSION_DEFAULT -1 /** - * sets whether to use LPC mode - used by FLAC encoder - * - encoding: set by user. - * - decoding: unused. + * Sets whether to use LPC mode - used by FLAC encoder. + * - encoding: Set by user. + * - decoding: unused */ int use_lpc; /** * LPC coefficient precision - used by FLAC encoder - * - encoding: set by user. - * - decoding: unused. + * - encoding: Set by user. + * - decoding: unused */ int lpc_coeff_precision; /** - * - encoding: set by user. - * - decoding: unused. + * - encoding: Set by user. + * - decoding: unused */ int min_prediction_order; /** - * - encoding: set by user. - * - decoding: unused. + * - encoding: Set by user. + * - decoding: unused */ int max_prediction_order; /** * search method for selecting prediction order - * - encoding: set by user. - * - decoding: unused. + * - encoding: Set by user. + * - decoding: unused */ int prediction_order_method; /** - * - encoding: set by user. - * - decoding: unused. + * - encoding: Set by user. + * - decoding: unused */ int min_partition_order; /** - * - encoding: set by user. - * - decoding: unused. + * - encoding: Set by user. + * - decoding: unused */ int max_partition_order; /** * GOP timecode frame start number, in non drop frame format - * - encoding: set by user. - * - decoding: unused. + * - encoding: Set by user. + * - decoding: unused */ int64_t timecode_frame_start; + + /** + * Decoder should decode to this many channels if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + */ + int request_channels; + + /** + * Percentage of dynamic range compression to be applied by the decoder. + * The default value is 1.0, corresponding to full compression. + * - encoding: unused + * - decoding: Set by user. + */ + float drc_scale; } AVCodecContext; /** * AVCodec. */ typedef struct AVCodec { + /** + * Name of the codec implementation. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + * This is the primary way to find a codec from the user perspective. + */ const char *name; enum CodecType type; enum CodecID id; @@ -2116,7 +2213,7 @@ typedef struct AVCodec { int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); int (*close)(AVCodecContext *); int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, - uint8_t *buf, int buf_size); + const uint8_t *buf, int buf_size); int capabilities; struct AVCodec *next; void (*flush)(AVCodecContext *); @@ -2137,20 +2234,22 @@ typedef struct AVPicture { * AVPaletteControl * This structure defines a method for communicating palette changes * between and demuxer and a decoder. - * this is totally broken, palette changes should be sent as AVPackets + * + * @deprecated Use AVPacket to send palette changes instead. + * This is totally broken. */ #define AVPALETTE_SIZE 1024 #define AVPALETTE_COUNT 256 typedef struct AVPaletteControl { - /* demuxer sets this to 1 to indicate the palette has changed; - * decoder resets to 0 */ + /* Demuxer sets this to 1 to indicate the palette has changed; + * decoder resets to 0. */ int palette_changed; /* 4-byte ARGB palette entries, stored in native byte order; note that * the individual palette components should be on a 8-bit scale; if - * the palette data comes from a IBM VGA native format, the component - * data is probably 6 bits in size and needs to be scaled */ + * the palette data comes from an IBM VGA native format, the component + * data is probably 6 bits in size and needs to be scaled. */ unsigned int palette[AVPALETTE_COUNT]; } AVPaletteControl attribute_deprecated; @@ -2174,255 +2273,6 @@ typedef struct AVSubtitle { AVSubtitleRect *rects; } AVSubtitle; -extern AVCodec ac3_encoder; -extern AVCodec amr_nb_encoder; -extern AVCodec amr_wb_encoder; -extern AVCodec asv1_encoder; -extern AVCodec asv2_encoder; -extern AVCodec bmp_encoder; -extern AVCodec dvvideo_encoder; -extern AVCodec faac_encoder; -extern AVCodec ffv1_encoder; -extern AVCodec ffvhuff_encoder; -extern AVCodec flac_encoder; -extern AVCodec flashsv_encoder; -extern AVCodec flv_encoder; -extern AVCodec gif_encoder; -extern AVCodec h261_encoder; -extern AVCodec h263_encoder; -extern AVCodec h263p_encoder; -extern AVCodec h264_encoder; -extern AVCodec huffyuv_encoder; -extern AVCodec jpegls_encoder; -extern AVCodec libgsm_encoder; -extern AVCodec libgsm_ms_encoder; -extern AVCodec libtheora_encoder; -extern AVCodec ljpeg_encoder; -extern AVCodec mdec_encoder; -extern AVCodec mjpeg_encoder; -extern AVCodec mp2_encoder; -extern AVCodec mp3lame_encoder; -extern AVCodec mpeg1video_encoder; -extern AVCodec mpeg2video_encoder; -extern AVCodec mpeg4_encoder; -extern AVCodec msmpeg4v1_encoder; -extern AVCodec msmpeg4v2_encoder; -extern AVCodec msmpeg4v3_encoder; -extern AVCodec oggvorbis_encoder; -extern AVCodec pam_encoder; -extern AVCodec pbm_encoder; -extern AVCodec pgm_encoder; -extern AVCodec pgmyuv_encoder; -extern AVCodec png_encoder; -extern AVCodec ppm_encoder; -extern AVCodec rv10_encoder; -extern AVCodec rv20_encoder; -extern AVCodec snow_encoder; -extern AVCodec sonic_encoder; -extern AVCodec sonic_ls_encoder; -extern AVCodec svq1_encoder; -extern AVCodec targa_encoder; -extern AVCodec vcr1_encoder; -extern AVCodec vorbis_encoder; -extern AVCodec wmav1_encoder; -extern AVCodec wmav2_encoder; -extern AVCodec wmv1_encoder; -extern AVCodec wmv2_encoder; -extern AVCodec x264_encoder; -extern AVCodec xvid_encoder; -extern AVCodec zlib_encoder; -extern AVCodec zmbv_encoder; - -extern AVCodec aac_decoder; -extern AVCodec aasc_decoder; -extern AVCodec alac_decoder; -extern AVCodec amr_nb_decoder; -extern AVCodec amr_wb_decoder; -extern AVCodec asv1_decoder; -extern AVCodec asv2_decoder; -extern AVCodec avs_decoder; -extern AVCodec bmp_decoder; -extern AVCodec cavs_decoder; -extern AVCodec cinepak_decoder; -extern AVCodec cljr_decoder; -extern AVCodec cook_decoder; -extern AVCodec cscd_decoder; -extern AVCodec cyuv_decoder; -extern AVCodec dca_decoder; -extern AVCodec dnxhd_decoder; -extern AVCodec dsicinaudio_decoder; -extern AVCodec dsicinvideo_decoder; -extern AVCodec dvvideo_decoder; -extern AVCodec dxa_decoder; -extern AVCodec eightbps_decoder; -extern AVCodec ffv1_decoder; -extern AVCodec ffvhuff_decoder; -extern AVCodec flac_decoder; -extern AVCodec flashsv_decoder; -extern AVCodec flic_decoder; -extern AVCodec flv_decoder; -extern AVCodec fourxm_decoder; -extern AVCodec fraps_decoder; -extern AVCodec gif_decoder; -extern AVCodec h261_decoder; -extern AVCodec h263_decoder; -extern AVCodec h263i_decoder; -extern AVCodec h264_decoder; -extern AVCodec huffyuv_decoder; -extern AVCodec idcin_decoder; -extern AVCodec imc_decoder; -extern AVCodec indeo2_decoder; -extern AVCodec indeo3_decoder; -extern AVCodec interplay_dpcm_decoder; -extern AVCodec interplay_video_decoder; -extern AVCodec kmvc_decoder; -extern AVCodec libgsm_decoder; -extern AVCodec libgsm_ms_decoder; -extern AVCodec loco_decoder; -extern AVCodec mace3_decoder; -extern AVCodec mace6_decoder; -extern AVCodec mdec_decoder; -extern AVCodec mjpeg_decoder; -extern AVCodec mjpegb_decoder; -extern AVCodec mmvideo_decoder; -extern AVCodec mp2_decoder; -extern AVCodec mp3_decoder; -extern AVCodec mp3adu_decoder; -extern AVCodec mp3on4_decoder; -extern AVCodec mpc7_decoder; -extern AVCodec mpeg1video_decoder; -extern AVCodec mpeg2video_decoder; -extern AVCodec mpeg4_decoder; -extern AVCodec mpeg4aac_decoder; -extern AVCodec mpeg_xvmc_decoder; -extern AVCodec mpegvideo_decoder; -extern AVCodec msmpeg4v1_decoder; -extern AVCodec msmpeg4v2_decoder; -extern AVCodec msmpeg4v3_decoder; -extern AVCodec msrle_decoder; -extern AVCodec msvideo1_decoder; -extern AVCodec mszh_decoder; -extern AVCodec nuv_decoder; -extern AVCodec oggvorbis_decoder; -extern AVCodec png_decoder; -extern AVCodec qdm2_decoder; -extern AVCodec qdraw_decoder; -extern AVCodec qpeg_decoder; -extern AVCodec qtrle_decoder; -extern AVCodec ra_144_decoder; -extern AVCodec ra_288_decoder; -extern AVCodec roq_decoder; -extern AVCodec roq_dpcm_decoder; -extern AVCodec rpza_decoder; -extern AVCodec rv10_decoder; -extern AVCodec rv20_decoder; -extern AVCodec rv30_decoder; -extern AVCodec rv40_decoder; -extern AVCodec shorten_decoder; -extern AVCodec smackaud_decoder; -extern AVCodec smacker_decoder; -extern AVCodec smc_decoder; -extern AVCodec snow_decoder; -extern AVCodec sol_dpcm_decoder; -extern AVCodec sonic_decoder; -extern AVCodec sp5x_decoder; -extern AVCodec svq1_decoder; -extern AVCodec svq3_decoder; -extern AVCodec targa_decoder; -extern AVCodec theora_decoder; -extern AVCodec thp_decoder; -extern AVCodec tiertexseqvideo_decoder; -extern AVCodec tiff_decoder; -extern AVCodec truemotion1_decoder; -extern AVCodec truemotion2_decoder; -extern AVCodec truespeech_decoder; -extern AVCodec tscc_decoder; -extern AVCodec tta_decoder; -extern AVCodec ulti_decoder; -extern AVCodec vc1_decoder; -extern AVCodec vcr1_decoder; -extern AVCodec vmdaudio_decoder; -extern AVCodec vmdvideo_decoder; -extern AVCodec vmnc_decoder; -extern AVCodec vorbis_decoder; -extern AVCodec vp3_decoder; -extern AVCodec vp5_decoder; -extern AVCodec vp6_decoder; -extern AVCodec vp6f_decoder; -extern AVCodec vqa_decoder; -extern AVCodec wavpack_decoder; -extern AVCodec wmav1_decoder; -extern AVCodec wmav2_decoder; -extern AVCodec wmv1_decoder; -extern AVCodec wmv2_decoder; -extern AVCodec wmv3_decoder; -extern AVCodec wnv1_decoder; -extern AVCodec ws_snd1_decoder; -extern AVCodec xan_dpcm_decoder; -extern AVCodec xan_wc3_decoder; -extern AVCodec xl_decoder; -extern AVCodec zlib_decoder; -extern AVCodec zmbv_decoder; - -/* pcm codecs */ -#define PCM_CODEC(id, name) \ -extern AVCodec name ## _decoder; \ -extern AVCodec name ## _encoder - -PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); -PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); -PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); -PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); -PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); -PCM_CODEC(CODEC_ID_PCM_S24BE, pcm_s24be); -PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); -PCM_CODEC(CODEC_ID_PCM_S24LE, pcm_s24le); -PCM_CODEC(CODEC_ID_PCM_S32BE, pcm_s32be); -PCM_CODEC(CODEC_ID_PCM_S32LE, pcm_s32le); -PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); -PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); -PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); -PCM_CODEC(CODEC_ID_PCM_U24BE, pcm_u24be); -PCM_CODEC(CODEC_ID_PCM_U24LE, pcm_u24le); -PCM_CODEC(CODEC_ID_PCM_U32BE, pcm_u32be); -PCM_CODEC(CODEC_ID_PCM_U32LE, pcm_u32le); - -/* adpcm codecs */ - -PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); -PCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx); -PCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct); -PCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); -PCM_CODEC(CODEC_ID_ADPCM_G726, adpcm_g726); -PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); -PCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); -PCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); -PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); -PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws); -PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); -PCM_CODEC(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2); -PCM_CODEC(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3); -PCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4); -PCM_CODEC(CODEC_ID_ADPCM_SMJPEG, adpcm_ima_smjpeg); -PCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf); -PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); -PCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); - -#undef PCM_CODEC - -/* dummy raw video codec */ -extern AVCodec rawvideo_decoder; -extern AVCodec rawvideo_encoder; - -/* the following codecs use external GPL libs */ -extern AVCodec dts_decoder; -extern AVCodec liba52_decoder; - -/* subtitles */ -extern AVCodec dvbsub_decoder; -extern AVCodec dvbsub_encoder; -extern AVCodec dvdsub_decoder; -extern AVCodec dvdsub_encoder; /* resample.c */ @@ -2444,13 +2294,20 @@ void av_resample_close(struct AVResampleContext *c); #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) /* YUV420 format is assumed ! */ -struct ImgReSampleContext attribute_deprecated; - +/** + * @deprecated Use the software scaler (swscale) instead. + */ typedef struct ImgReSampleContext ImgReSampleContext attribute_deprecated; +/** + * @deprecated Use the software scaler (swscale) instead. + */ attribute_deprecated ImgReSampleContext *img_resample_init(int output_width, int output_height, int input_width, int input_height); +/** + * @deprecated Use the software scaler (swscale) instead. + */ attribute_deprecated ImgReSampleContext *img_resample_full_init(int owidth, int oheight, int iwidth, int iheight, int topBand, int bottomBand, @@ -2458,34 +2315,39 @@ attribute_deprecated ImgReSampleContext *img_resample_full_init(int owidth, int int padtop, int padbottom, int padleft, int padright); - -attribute_deprecated void img_resample(ImgReSampleContext *s, +/** + * @deprecated Use the software scaler (swscale) instead. + */ +attribute_deprecated void img_resample(struct ImgReSampleContext *s, AVPicture *output, const AVPicture *input); -attribute_deprecated void img_resample_close(ImgReSampleContext *s); +/** + * @deprecated Use the software scaler (swscale) instead. + */ +attribute_deprecated void img_resample_close(struct ImgReSampleContext *s); #endif /** * Allocate memory for a picture. Call avpicture_free to free it. * - * @param picture the picture to be filled in. - * @param pix_fmt the format of the picture. - * @param width the width of the picture. - * @param height the height of the picture. - * @return Zero if successful, a negative value if not. + * @param picture the picture to be filled in + * @param pix_fmt the format of the picture + * @param width the width of the picture + * @param height the height of the picture + * @return zero if successful, a negative value if not */ int avpicture_alloc(AVPicture *picture, int pix_fmt, int width, int height); /** * Free a picture previously allocated by avpicture_alloc(). * - * @param picture The AVPicture to be freed. + * @param picture the AVPicture to be freed */ void avpicture_free(AVPicture *picture); /** - * Fill in AVPicture's fields. + * Fill in the AVPicture fields. * The fields of the given AVPicture are filled in by using the 'ptr' address * which points to the image data buffer. Depending on the specified picture * format, one or multiple image data pointers and line sizes will be set. @@ -2493,12 +2355,12 @@ void avpicture_free(AVPicture *picture); * the different picture planes and the line sizes of the different planes * will be stored in the lines_sizes array. * - * @param picture AVPicture who's fields are to be filled in + * @param picture AVPicture whose fields are to be filled in * @param ptr Buffer which will contain or contains the actual image data - * @param pix_fmt The format in which the picture data is stored - * @param width The width of the image in pixels - * @param height The height of the image in pixels - * @return Size of the image data in bytes. + * @param pix_fmt The format in which the picture data is stored. + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return size of the image data in bytes */ int avpicture_fill(AVPicture *picture, uint8_t *ptr, int pix_fmt, int width, int height); @@ -2509,9 +2371,9 @@ int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, * Calculate the size in bytes that a picture of the given width and height * would occupy if stored in the given picture format. * - * @param pix_fmt The given picture format - * @param width The width of the image - * @param height The height of the image + * @param pix_fmt the given picture format + * @param width the width of the image + * @param height the height of the image * @return Image data size in bytes */ int avpicture_get_size(int pix_fmt, int width, int height); @@ -2537,11 +2399,11 @@ unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat p); * other formats. These losses can involve loss of chroma, but also loss of * resolution, loss of color depth, loss due to the color space conversion, loss * of the alpha bits or loss due to color quantization. - * avcodec_get_fix_fmt_loss() informs you on the various types of losses which - * will occur when converting from one pixel format to another. + * avcodec_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. * - * @param[in] dst_pix_fmt Destination pixel format. - * @param[in] src_pix_fmt Source pixel format. + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format * @param[in] has_alpha Whether the source pixel format alpha channel is used. * @return Combination of flags informing you what kind of losses will occur. */ @@ -2554,8 +2416,8 @@ int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, * may occur. For example, when converting from RGB24 to GRAY, the color * information will be lost. Similarly, other losses occur when converting from * some formats to other formats. avcodec_find_best_pix_fmt() searches which of - * the given pixel formats should be used to undergo the least amount of losses. - * The pixel formats from which it choses one, are determined by the + * the given pixel formats should be used to suffer the least amount of loss. + * The pixel formats from which it chooses one, are determined by the * \p pix_fmt_mask parameter. * * @code @@ -2564,8 +2426,8 @@ int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss); * @endcode * - * @param[in] pix_fmt_mask Bitmask determining which pixel format to choose from. - * @param[in] src_pix_fmt Source pixel format. + * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from + * @param[in] src_pix_fmt source pixel format * @param[in] has_alpha Whether the source pixel format alpha channel is used. * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. * @return The best pixel format to convert to or -1 if none was found. @@ -2573,6 +2435,19 @@ int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, int has_alpha, int *loss_ptr); + +/** + * Print in buf the string corresponding to the pixel format with + * number pix_fmt, or an header if pix_fmt is negative. + * + * @param[in] buf the buffer where to write the string + * @param[in] buf_size the size of buf + * @param[in] pix_fmt the number of the pixel format to print the corresponding info string, or + * a negative value to print the corresponding header. + * Meaningful values for obtaining a pixel format info vary from 0 to PIX_FMT_NB -1. + */ +void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt); + #define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ #define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ @@ -2584,7 +2459,10 @@ int img_get_alpha_info(const AVPicture *src, int pix_fmt, int width, int height); #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) -/* convert among pixel formats */ +/** + * convert among pixel formats + * @deprecated Use the software scaler (swscale) instead. + */ attribute_deprecated int img_convert(AVPicture *dst, int dst_pix_fmt, const AVPicture *src, int pix_fmt, int width, int height); @@ -2597,7 +2475,10 @@ int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, /* external high level API */ +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) extern AVCodec *first_avcodec; +#endif +AVCodec *av_codec_next(AVCodec *c); /* returns LIBAVCODEC_VERSION_INT constant */ unsigned avcodec_version(void); @@ -2615,33 +2496,33 @@ void avcodec_init(void); void register_avcodec(AVCodec *format); /** - * Finds an encoder with a matching codec ID. + * Finds a registered encoder with a matching codec ID. * - * @param id CodecID of the requested encoder. + * @param id CodecID of the requested encoder * @return An encoder if one was found, NULL otherwise. */ AVCodec *avcodec_find_encoder(enum CodecID id); /** - * Finds an encoder with the specified name. + * Finds a registered encoder with the specified name. * - * @param name Name of the requested encoder. + * @param name name of the requested encoder * @return An encoder if one was found, NULL otherwise. */ AVCodec *avcodec_find_encoder_by_name(const char *name); /** - * Finds a decoder with a matching codec ID. + * Finds a registered decoder with a matching codec ID. * - * @param id CodecID of the requested decoder. + * @param id CodecID of the requested decoder * @return A decoder if one was found, NULL otherwise. */ AVCodec *avcodec_find_decoder(enum CodecID id); /** - * Finds an decoder with the specified name. + * Finds a registered decoder with the specified name. * - * @param name Name of the requested decoder. + * @param name name of the requested decoder * @return A decoder if one was found, NULL otherwise. */ AVCodec *avcodec_find_decoder_by_name(const char *name); @@ -2717,9 +2598,10 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for * retrieving a codec. * - * @warning This function is not thread save! + * @warning This function is not thread safe! * * @code + * avcodec_register_all(); * codec = avcodec_find_decoder(CODEC_ID_H264); * if (!codec) * exit(1); @@ -2730,9 +2612,9 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v * exit(1); * @endcode * - * @param avctx The context which will be setup to use the given codec. + * @param avctx The context which will be set up to use the given codec. * @param codec The codec to use within the context. - * @return Zero on success, a negative value on error. + * @return zero on success, a negative value on error * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder */ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); @@ -2742,13 +2624,13 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); */ attribute_deprecated int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, - uint8_t *buf, int buf_size); + const uint8_t *buf, int buf_size); /** * Decodes an audio frame from \p buf into \p samples. - * The avcodec_decode_audio2() function decodes a frame of audio from the input + * The avcodec_decode_audio2() function decodes an audio frame from the input * buffer \p buf of size \p buf_size. To decode it, it makes use of the - * audiocodec which was coupled with \p avctx using avcodec_open(). The + * audio codec which was coupled with \p avctx using avcodec_open(). The * resulting decoded frame is stored in output buffer \p samples. If no frame * could be decompressed, \p frame_size_ptr is zero. Otherwise, it is the * decompressed frame size in \e bytes. @@ -2764,7 +2646,7 @@ attribute_deprecated int avcodec_decode_audio(AVCodecContext *avctx, int16_t *sa * no overreading happens for damaged MPEG streams. * * @note You might have to align the input buffer \p buf and output buffer \p - * samples. The alignment requirements depend on the CPU: on some CPUs it isn't + * samples. The alignment requirements depend on the CPU: On some CPUs it isn't * necessary at all, on others it won't work at all if not aligned and on others * it will work but it will have an impact on performance. In practice, the * bitstream should have 4 byte alignment at minimum and all sample data should @@ -2772,23 +2654,23 @@ attribute_deprecated int avcodec_decode_audio(AVCodecContext *avctx, int16_t *sa * the linesize is not a multiple of 16 then there's no sense in aligning the * start of the buffer to 16. * - * @param avctx The codec context. - * @param[out] samples The output buffer. - * @param[in,out] frame_size_ptr The output buffer size in bytes. - * @param[in] buf The input buffer. - * @param[in] buf_size The input buffer size in bytes. + * @param avctx the codec context + * @param[out] samples the output buffer + * @param[in,out] frame_size_ptr the output buffer size in bytes + * @param[in] buf the input buffer + * @param[in] buf_size the input buffer size in bytes * @return On error a negative value is returned, otherwise the number of bytes * used or zero if no frame could be decompressed. */ int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, - uint8_t *buf, int buf_size); + const uint8_t *buf, int buf_size); /** * Decodes a video frame from \p buf into \p picture. - * The avcodec_decode_video() function decodes a frame of video from the input + * The avcodec_decode_video() function decodes a video frame from the input * buffer \p buf of size \p buf_size. To decode it, it makes use of the - * videocodec which was coupled with \p avctx using avcodec_open(). The + * video codec which was coupled with \p avctx using avcodec_open(). The * resulting decoded frame is stored in \p picture. * * @warning The input buffer must be \c FF_INPUT_BUFFER_PADDING_SIZE larger than @@ -2807,21 +2689,21 @@ int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, * the linesize is not a multiple of 16 then there's no sense in aligning the * start of the buffer to 16. * - * @param avctx The codec context. + * @param avctx the codec context * @param[out] picture The AVFrame in which the decoded video frame will be stored. - * @param[in] buf The input buffer. - * @param[in] buf_size The size of the input buffer in bytes. - * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is non zero. + * @param[in] buf the input buffer + * @param[in] buf_size the size of the input buffer in bytes + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. * @return On error a negative value is returned, otherwise the number of bytes * used or zero if no frame could be decompressed. */ int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, - uint8_t *buf, int buf_size); + const uint8_t *buf, int buf_size); -/* 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. */ +/* 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); @@ -2831,35 +2713,37 @@ int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, /** * Encodes an audio frame from \p samples into \p buf. - * The avcodec_encode_audio() function encodes a frame of audio from the input - * buffer \p samples. To encode it, it makes use of the audiocodec which was + * The avcodec_encode_audio() function encodes an audio frame from the input + * buffer \p samples. To encode it, it makes use of the audio codec which was * coupled with \p avctx using avcodec_open(). The resulting encoded frame is * stored in output buffer \p buf. * * @note The output buffer should be at least \c FF_MIN_BUFFER_SIZE bytes large. * - * @param avctx The codec context. - * @param[out] buf The output buffer. - * @param[in] buf_size The output buffer size. - * @param[in] samples The input buffer containing the samples. - * @return On error a negative value is returned, on succes zero or the number - * of bytes used from the input buffer. + * @param avctx the codec context + * @param[out] buf the output buffer + * @param[in] buf_size the output buffer size + * @param[in] samples the input buffer containing the samples + * The number of samples read from this buffer is frame_size*channels, + * both of which are defined in \p avctx. + * @return On error a negative value is returned, on success zero or the number + * of bytes used to encode the data read from the input buffer. */ int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, const short *samples); /** * Encodes a video frame from \p pict into \p buf. - * The avcodec_encode_video() function encodes a frame of video from the input - * \p pict. To encode it, it makes use of the videocodec which was coupled with + * The avcodec_encode_video() function encodes a video frame from the input + * \p pict. To encode it, it makes use of the video codec which was coupled with * \p avctx using avcodec_open(). The resulting encoded bytes representing the * frame are stored in the output buffer \p buf. The input picture should be * stored using a specific format, namely \c avctx.pix_fmt. * - * @param avctx The codec context. - * @param[out] buf The output buffer for the bitstream of encoded frame. - * @param[in] buf_size The size of the outputbuffer in bytes. - * @param[in] pict The input picture to encode. + * @param avctx the codec context + * @param[out] buf the output buffer for the bitstream of encoded frame + * @param[in] buf_size the size of the output buffer in bytes + * @param[in] pict the input picture to encode * @return On error a negative value is returned, on success zero or the number * of bytes used from the input buffer. */ @@ -2884,7 +2768,7 @@ void avcodec_default_free_buffers(AVCodecContext *s); /** * Returns a single letter to describe the given picture type \p pict_type. * - * @param[in] pict_type The picture type. + * @param[in] pict_type the picture type * @return A single character representing the picture type. */ char av_get_pict_type_char(int pict_type); @@ -2892,11 +2776,19 @@ char av_get_pict_type_char(int pict_type); /** * Returns codec bits per sample. * - * @param[in] codec_id The codec. + * @param[in] codec_id the codec * @return Number of bits per sample or zero if unknown for the given codec. */ int av_get_bits_per_sample(enum CodecID codec_id); +/** + * Returns sample format bits per sample. + * + * @param[in] sample_fmt the sample format + * @return Number of bits per sample or zero if unknown for the given sample format. + */ +int av_get_bits_per_sample_format(enum SampleFormat sample_fmt); + /* frame parsing */ typedef struct AVCodecParserContext { void *priv_data; @@ -2906,8 +2798,8 @@ typedef struct AVCodecParserContext { (incremented by each av_parser_parse()) */ int64_t last_frame_offset; /* offset of the last frame */ /* video info */ - int pict_type; /* XXX: put it back in AVCodecContext */ - int repeat_pict; /* XXX: put it back in AVCodecContext */ + int pict_type; /* XXX: Put it back in AVCodecContext. */ + int repeat_pict; /* XXX: Put it back in AVCodecContext. */ int64_t pts; /* pts of the current frame */ int64_t dts; /* dts of the current frame */ @@ -2924,6 +2816,9 @@ typedef struct AVCodecParserContext { int flags; #define PARSER_FLAG_COMPLETE_FRAMES 0x0001 + + int64_t offset; ///< byte offset from starting packet start + int64_t last_offset; } AVCodecParserContext; typedef struct AVCodecParser { @@ -2932,14 +2827,17 @@ typedef struct AVCodecParser { int (*parser_init)(AVCodecParserContext *s); int (*parser_parse)(AVCodecParserContext *s, AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, + const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size); void (*parser_close)(AVCodecParserContext *s); int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); struct AVCodecParser *next; } AVCodecParser; +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) extern AVCodecParser *av_first_parser; +#endif +AVCodecParser *av_parser_next(AVCodecParser *c); void av_register_codec_parser(AVCodecParser *parser); AVCodecParserContext *av_parser_init(int codec_id); @@ -2954,22 +2852,6 @@ int av_parser_change(AVCodecParserContext *s, const uint8_t *buf, int buf_size, int keyframe); void av_parser_close(AVCodecParserContext *s); -extern AVCodecParser aac_parser; -extern AVCodecParser ac3_parser; -extern AVCodecParser cavsvideo_parser; -extern AVCodecParser dca_parser; -extern AVCodecParser dvbsub_parser; -extern AVCodecParser dvdsub_parser; -extern AVCodecParser h261_parser; -extern AVCodecParser h263_parser; -extern AVCodecParser h264_parser; -extern AVCodecParser mjpeg_parser; -extern AVCodecParser mpeg4video_parser; -extern AVCodecParser mpegaudio_parser; -extern AVCodecParser mpegvideo_parser; -extern AVCodecParser pnm_parser; -extern AVCodecParser vc1_parser; - typedef struct AVBitStreamFilterContext { void *priv_data; @@ -2986,11 +2868,10 @@ typedef struct AVBitStreamFilter { AVCodecContext *avctx, const char *args, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe); + void (*close)(AVBitStreamFilterContext *bsfc); struct AVBitStreamFilter *next; } AVBitStreamFilter; -extern AVBitStreamFilter *av_first_bitstream_filter; - void av_register_bitstream_filter(AVBitStreamFilter *bsf); AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, @@ -2999,14 +2880,7 @@ int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, const uint8_t *buf, int buf_size, int keyframe); void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); -extern AVBitStreamFilter dump_extradata_bsf; -extern AVBitStreamFilter remove_extradata_bsf; -extern AVBitStreamFilter noise_bsf; -extern AVBitStreamFilter mp3_header_compress_bsf; -extern AVBitStreamFilter mp3_header_decompress_bsf; -extern AVBitStreamFilter mjpega_dump_header_bsf; -extern AVBitStreamFilter imx_dump_header_bsf; - +AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); /* memory */ @@ -3021,8 +2895,12 @@ void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); /* for static data only */ /** - * Frees all static arrays and reset their pointers to 0. + * Frees all static arrays and resets their pointers to 0. * Call this function to release all statically allocated tables. + * + * @deprecated. Code which uses av_free_static is broken/misdesigned + * and should correctly use static arrays + * */ attribute_deprecated void av_free_static(void); @@ -3032,7 +2910,9 @@ attribute_deprecated void av_free_static(void); * @warning Do not use for normal allocation. * * @param[in] size The amount of memory you need in bytes. - * @return Block of memory of the requested size. + * @return block of memory of the requested size + * @deprecated. Code which uses av_mallocz_static is broken/misdesigned + * and should correctly use static arrays */ attribute_deprecated void *av_mallocz_static(unsigned int size); @@ -3043,49 +2923,80 @@ void av_picture_copy(AVPicture *dst, const AVPicture *src, int pix_fmt, int width, int height); /** - * Crop image top and left side + * Crop image top and left side. */ int av_picture_crop(AVPicture *dst, const AVPicture *src, int pix_fmt, int top_band, int left_band); /** - * Pad image + * Pad image. */ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, int padtop, int padbottom, int padleft, int padright, int *color); #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) +/** + * @deprecated Use the software scaler (swscale) instead. + */ attribute_deprecated void img_copy(AVPicture *dst, const AVPicture *src, int pix_fmt, int width, int height); +/** + * @deprecated Use the software scaler (swscale) instead. + */ attribute_deprecated int img_crop(AVPicture *dst, const AVPicture *src, int pix_fmt, int top_band, int left_band); +/** + * @deprecated Use the software scaler (swscale) instead. + */ attribute_deprecated 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); #endif extern unsigned int av_xiphlacing(unsigned char *s, unsigned int v); +/** + * Parses \p str and put in \p width_ptr and \p height_ptr the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * <width>x<height> or a valid video frame size abbreviation. + * @param[in,out] width_ptr pointer to the variable which will contain the detected + * frame width value + * @param[in,out] height_ptr pointer to the variable which will contain the detected + * frame height value + */ +int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * Parses \p str and put in \p frame_rate the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * <frame_rate_nom>/<frame_rate_den>, a float number or a valid video rate abbreviation + * @param[in,out] frame_rate pointer to the AVRational which will contain the detected + * frame rate + */ +int av_parse_video_frame_rate(AVRational *frame_rate, const char *str); + /* error handling */ #if EINVAL > 0 -#define AVERROR(e) (-(e)) /**< returns a negative error code from a POSIX error code, to return from library functions. */ -#define AVUNERROR(e) (-(e)) /**< returns a POSIX error code from a library function error return value. */ +#define AVERROR(e) (-(e)) /**< Returns a negative error code from a POSIX error code, to return from library functions. */ +#define AVUNERROR(e) (-(e)) /**< Returns a POSIX error code from a library function error return value. */ #else -/* some platforms have E* and errno already negated. */ +/* Some platforms have E* and errno already negated. */ #define AVERROR(e) (e) #define AVUNERROR(e) (e) #endif #define AVERROR_UNKNOWN AVERROR(EINVAL) /**< unknown error */ -#define AVERROR_IO AVERROR(EIO) /**< i/o error */ -#define AVERROR_NUMEXPECTED AVERROR(EDOM) /**< number syntax expected in filename */ +#define AVERROR_IO AVERROR(EIO) /**< I/O error */ +#define AVERROR_NUMEXPECTED AVERROR(EDOM) /**< Number syntax expected in filename. */ #define AVERROR_INVALIDDATA AVERROR(EINVAL) /**< invalid data found */ #define AVERROR_NOMEM AVERROR(ENOMEM) /**< not enough memory */ #define AVERROR_NOFMT AVERROR(EILSEQ) /**< unknown format */ -#define AVERROR_NOTSUPP AVERROR(ENOSYS) /**< operation not supported */ - -#ifdef __cplusplus -} -#endif +#define AVERROR_NOTSUPP AVERROR(ENOSYS) /**< Operation not supported. */ +#define AVERROR_NOENT AVERROR(ENOENT) /**< No such file or directory. */ +#define AVERROR_PATCHWELCOME -MKTAG('P','A','W','E') /**< Not yet implemented in FFmpeg. Patches welcome. */ -#endif /* AVCODEC_H */ +#endif /* FFMPEG_AVCODEC_H */ diff --git a/contrib/ffmpeg/libavcodec/avs.c b/contrib/ffmpeg/libavcodec/avs.c index ebfa8adb7..7d4f3e45e 100644 --- a/contrib/ffmpeg/libavcodec/avs.c +++ b/contrib/ffmpeg/libavcodec/avs.c @@ -16,7 +16,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" @@ -44,12 +44,13 @@ typedef enum { static int avs_decode_frame(AVCodecContext * avctx, - void *data, int *data_size, uint8_t * buf, int buf_size) + void *data, int *data_size, const uint8_t * buf, int buf_size) { avs_context_t *const avs = avctx->priv_data; AVFrame *picture = data; AVFrame *const p = (AVFrame *) & avs->picture; - uint8_t *table, *vect, *out; + const uint8_t *table, *vect; + uint8_t *out; int i, j, x, y, stride, vect_w = 3, vect_h = 3; int sub_type; avs_block_type_t type; diff --git a/contrib/ffmpeg/libavcodec/beosthread.c b/contrib/ffmpeg/libavcodec/beosthread.c index 3d059912b..4c99bc0ff 100644 --- a/contrib/ffmpeg/libavcodec/beosthread.c +++ b/contrib/ffmpeg/libavcodec/beosthread.c @@ -16,12 +16,10 @@ * 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 - * */ //#define DEBUG #include "avcodec.h" -#include "common.h" #include <OS.h> @@ -74,8 +72,8 @@ static int32 ff_thread_func(void *v){ } /** - * free what has been allocated by avcodec_thread_init(). - * must be called after decoding has finished, especially dont call while avcodec_thread_execute() is running + * Free what has been allocated by avcodec_thread_init(). + * Must be called after decoding has finished, especially do not call while avcodec_thread_execute() is running. */ void avcodec_thread_free(AVCodecContext *s){ ThreadContext *c= s->thread_opaque; diff --git a/contrib/ffmpeg/libavcodec/bethsoftvideo.c b/contrib/ffmpeg/libavcodec/bethsoftvideo.c new file mode 100644 index 000000000..9d1f6124a --- /dev/null +++ b/contrib/ffmpeg/libavcodec/bethsoftvideo.c @@ -0,0 +1,139 @@ +/* + * Bethesda VID video decoder + * Copyright (C) 2007 Nicholas Tung + * + * 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 bethsoftvideo.c + * @brief Bethesda Softworks VID Video Decoder + * @author Nicholas Tung [ntung (at. ntung com] (2007-03) + * @sa http://wiki.multimedia.cx/index.php?title=Bethsoft_VID + * @sa http://www.svatopluk.com/andux/docs/dfvid.html + */ + +#include "common.h" +#include "dsputil.h" +#include "bethsoftvideo.h" +#include "bytestream.h" + +typedef struct BethsoftvidContext { + AVFrame frame; +} BethsoftvidContext; + +static int bethsoftvid_decode_init(AVCodecContext *avctx) +{ + BethsoftvidContext *vid = avctx->priv_data; + vid->frame.reference = 1; + vid->frame.buffer_hints = FF_BUFFER_HINTS_VALID | + FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + avctx->pix_fmt = PIX_FMT_PAL8; + return 0; +} + +static void set_palette(AVFrame * frame, const uint8_t * palette_buffer) +{ + uint32_t * palette = (uint32_t *)frame->data[1]; + int a; + for(a = 0; a < 256; a++){ + palette[a] = AV_RB24(&palette_buffer[a * 3]) * 4; + } + frame->palette_has_changed = 1; +} + +static int bethsoftvid_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + BethsoftvidContext * vid = avctx->priv_data; + char block_type; + uint8_t * dst; + uint8_t * frame_end; + int remaining = avctx->width; // number of bytes remaining on a line + const int wrap_to_next_line = vid->frame.linesize[0] - avctx->width; + int code; + int yoffset; + + if (avctx->reget_buffer(avctx, &vid->frame)) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + dst = vid->frame.data[0]; + frame_end = vid->frame.data[0] + vid->frame.linesize[0] * avctx->height; + + switch(block_type = *buf++){ + case PALETTE_BLOCK: + set_palette(&vid->frame, buf); + return 0; + case VIDEO_YOFF_P_FRAME: + yoffset = bytestream_get_le16(&buf); + if(yoffset >= avctx->height) + return -1; + dst += vid->frame.linesize[0] * yoffset; + } + + // main code + while((code = *buf++)){ + int length = code & 0x7f; + + // copy any bytes starting at the current position, and ending at the frame width + while(length > remaining){ + if(code < 0x80) + bytestream_get_buffer(&buf, dst, remaining); + else if(block_type == VIDEO_I_FRAME) + memset(dst, buf[0], remaining); + length -= remaining; // decrement the number of bytes to be copied + dst += remaining + wrap_to_next_line; // skip over extra bytes at end of frame + remaining = avctx->width; + if(dst == frame_end) + goto end; + } + + // copy any remaining bytes after / if line overflows + if(code < 0x80) + bytestream_get_buffer(&buf, dst, length); + else if(block_type == VIDEO_I_FRAME) + memset(dst, *buf++, length); + remaining -= length; + dst += length; + } + end: + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = vid->frame; + + return buf_size; +} + +static int bethsoftvid_decode_end(AVCodecContext *avctx) +{ + BethsoftvidContext * vid = avctx->priv_data; + if(vid->frame.data[0]) + avctx->release_buffer(avctx, &vid->frame); + return 0; +} + +AVCodec bethsoftvid_decoder = { + .name = "bethsoftvid", + .type = CODEC_TYPE_VIDEO, + .id = CODEC_ID_BETHSOFTVID, + .priv_data_size = sizeof(BethsoftvidContext), + .init = bethsoftvid_decode_init, + .close = bethsoftvid_decode_end, + .decode = bethsoftvid_decode_frame, +}; diff --git a/contrib/ffmpeg/libavcodec/bethsoftvideo.h b/contrib/ffmpeg/libavcodec/bethsoftvideo.h new file mode 100644 index 000000000..96629cd05 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/bethsoftvideo.h @@ -0,0 +1,36 @@ +/* + * Bethesda VID video decoder + * Copyright (C) 2007 Nicholas Tung + * + * 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 + */ + +#ifndef FFMPEG_BETHSOFTVIDEO_H +#define FFMPEG_BETHSOFTVIDEO_H + +enum BethsoftVidBlockType +{ + PALETTE_BLOCK = 0x02, + FIRST_AUDIO_BLOCK = 0x7c, + AUDIO_BLOCK = 0x7d, + VIDEO_I_FRAME = 0x03, + VIDEO_P_FRAME = 0x01, + VIDEO_YOFF_P_FRAME = 0x04, + EOF_BLOCK = 0x14, +}; + +#endif /* FFMPEG_BETHSOFTVIDEO_H */ diff --git a/contrib/ffmpeg/libavcodec/bfin/config_bfin.h b/contrib/ffmpeg/libavcodec/bfin/config_bfin.h index 1f5080900..0f0eab6be 100644 --- a/contrib/ffmpeg/libavcodec/bfin/config_bfin.h +++ b/contrib/ffmpeg/libavcodec/bfin/config_bfin.h @@ -29,18 +29,37 @@ DEFUN(put_pixels_clamped,mL1, rts; */ + +#ifndef FFMPEG_CONFIG_BFIN_H +#define FFMPEG_CONFIG_BFIN_H + #ifndef DEFUN +#define mL3 .text #ifndef mL1 +#ifdef __FDPIC__ #define mL1 .l1.text +#else +#define mL1 mL3 +#endif #endif -#define mL3 .text #define DEFUN(fname,where,interface) \ .section where; \ .global _ff_bfin_ ## fname ; \ + .type _ff_bfin_ ## fname, STT_FUNC; \ .align 8; \ _ff_bfin_ ## fname +#define DEFUN_END(fname) \ + .size _ff_bfin_ ## fname, . - _ff_bfin_ ## fname + +#ifdef __FDPIC__ +#define RELOC(reg,got,obj) reg = [got + obj@GOT17M4] +#else +#define RELOC(reg,got,obj) reg.L = obj; reg.H = obj +#endif + #endif +#endif /* FFMPEG_CONFIG_BFIN_H */ diff --git a/contrib/ffmpeg/libavcodec/bfin/dsputil_bfin.c b/contrib/ffmpeg/libavcodec/bfin/dsputil_bfin.c index b4d549fb7..a72459948 100644 --- a/contrib/ffmpeg/libavcodec/bfin/dsputil_bfin.c +++ b/contrib/ffmpeg/libavcodec/bfin/dsputil_bfin.c @@ -22,62 +22,43 @@ */ #include <unistd.h> -#include <bits/bfin_sram.h> -#include "../avcodec.h" -#include "../dsputil.h" +#include "avcodec.h" +#include "dsputil.h" +#include "dsputil_bfin.h" -#define USE_L1CODE - -#ifdef USE_L1CODE -#define L1CODE __attribute__ ((l1_text)) -#else -#define L1CODE -#endif int off; -extern void ff_bfin_idct (DCTELEM *block) L1CODE; -extern void ff_bfin_fdct (DCTELEM *block) L1CODE; -extern void ff_bfin_add_pixels_clamped (DCTELEM *block, uint8_t *dest, int line_size) L1CODE; -extern void ff_bfin_put_pixels_clamped (DCTELEM *block, uint8_t *dest, int line_size) L1CODE; -extern void ff_bfin_diff_pixels (DCTELEM *block, uint8_t *s1, uint8_t *s2, int stride) L1CODE; -extern void ff_bfin_get_pixels (DCTELEM *restrict block, const uint8_t *pixels, int line_size) L1CODE; -extern int ff_bfin_pix_norm1 (uint8_t * pix, int line_size) L1CODE; -extern int ff_bfin_z_sad8x8 (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) L1CODE; -extern int ff_bfin_z_sad16x16 (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) L1CODE; - -extern void ff_bfin_z_put_pixels16_xy2 (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) L1CODE; -extern void ff_bfin_z_put_pixels8_xy2 (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) L1CODE; -extern void ff_bfin_put_pixels16_xy2_nornd (uint8_t *block, const uint8_t *s0, int line_size, int h) L1CODE; -extern void ff_bfin_put_pixels8_xy2_nornd (uint8_t *block, const uint8_t *s0, int line_size, int h) L1CODE; +extern void ff_bfin_idct (DCTELEM *block) attribute_l1_text; +extern void ff_bfin_fdct (DCTELEM *block) attribute_l1_text; +extern void ff_bfin_vp3_idct (DCTELEM *block); +extern void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, DCTELEM *block); +extern void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, DCTELEM *block); +extern void ff_bfin_add_pixels_clamped (DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text; +extern void ff_bfin_put_pixels_clamped (DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text; +extern void ff_bfin_diff_pixels (DCTELEM *block, uint8_t *s1, uint8_t *s2, int stride) attribute_l1_text; +extern void ff_bfin_get_pixels (DCTELEM *restrict block, const uint8_t *pixels, int line_size) attribute_l1_text; +extern int ff_bfin_pix_norm1 (uint8_t * pix, int line_size) attribute_l1_text; +extern int ff_bfin_z_sad8x8 (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) attribute_l1_text; +extern int ff_bfin_z_sad16x16 (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) attribute_l1_text; +extern void ff_bfin_z_put_pixels16_xy2 (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) attribute_l1_text; +extern void ff_bfin_z_put_pixels8_xy2 (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) attribute_l1_text; +extern void ff_bfin_put_pixels16_xy2_nornd (uint8_t *block, const uint8_t *s0, int line_size, int h) attribute_l1_text; +extern void ff_bfin_put_pixels8_xy2_nornd (uint8_t *block, const uint8_t *s0, int line_size, int h) attribute_l1_text; -extern int ff_bfin_pix_sum (uint8_t *p, int stride) L1CODE; -extern void ff_bfin_put_pixels8uc (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) L1CODE; -extern void ff_bfin_put_pixels16uc (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) L1CODE; -extern void ff_bfin_put_pixels8uc_nornd (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) L1CODE; -extern void ff_bfin_put_pixels16uc_nornd (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) L1CODE; +extern int ff_bfin_pix_sum (uint8_t *p, int stride) attribute_l1_text; -extern int ff_bfin_sse4 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) L1CODE; -extern int ff_bfin_sse8 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) L1CODE; -extern int ff_bfin_sse16 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) L1CODE; +extern void ff_bfin_put_pixels8uc (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) attribute_l1_text; +extern void ff_bfin_put_pixels16uc (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) attribute_l1_text; +extern void ff_bfin_put_pixels8uc_nornd (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) attribute_l1_text; +extern void ff_bfin_put_pixels16uc_nornd (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) attribute_l1_text; +extern int ff_bfin_sse4 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) attribute_l1_text; +extern int ff_bfin_sse8 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) attribute_l1_text; +extern int ff_bfin_sse16 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) attribute_l1_text; -#if 0 -void pblk (uint8_t *p, int w, int h, int s) -{ - int i,j; - av_log (0,0,"0x%08x:\n", p); - for (i = 0;i<h;i++) { - for (j=0;j<w;j++) - av_log (0,0,"%3d ", p[j]); - p+=s; - av_log (0,0,"\n"); - } - av_log (0,0,"\n"); -} -#endif static void bfin_idct_add (uint8_t *dest, int line_size, DCTELEM *block) { @@ -183,7 +164,16 @@ static int bfin_pix_abs16 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, return ff_bfin_z_sad16x16 (blk1,blk2,line_size,line_size,h); } -static uint8_t vtmp_blk[256] __attribute__((l1_data_B)); +static int bfin_vsad_intra16 (void *c, uint8_t *blk1, uint8_t *dummy, int stride, int h) { + return ff_bfin_z_sad16x16 (blk1,blk1+stride,stride<<1,stride<<1,h); +} + +static int bfin_vsad (void *c, uint8_t *blk1, uint8_t *blk2, int stride, int h) { + return ff_bfin_z_sad16x16 (blk1,blk1+stride,stride<<1,stride<<1,h) + + ff_bfin_z_sad16x16 (blk2,blk2+stride,stride<<1,stride<<1,h); +} + +static uint8_t vtmp_blk[256] attribute_l1_data_b; static int bfin_pix_abs16_x2 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h) { @@ -252,6 +242,9 @@ void dsputil_init_bfin( DSPContext* c, AVCodecContext *avctx ) c->sad[0] = bfin_pix_abs16; c->sad[1] = bfin_pix_abs8; + c->vsad[0] = bfin_vsad; + c->vsad[4] = bfin_vsad_intra16; + /* TODO [0] 16 [1] 8 */ c->pix_abs[0][0] = bfin_pix_abs16; c->pix_abs[0][1] = bfin_pix_abs16_x2; @@ -300,10 +293,17 @@ void dsputil_init_bfin( DSPContext* c, AVCodecContext *avctx ) c->put_no_rnd_pixels_tab[0][2] = bfin_put_pixels16_y2_nornd; c->put_no_rnd_pixels_tab[0][3] = ff_bfin_put_pixels16_xy2_nornd; - c->fdct = ff_bfin_fdct; - c->idct = ff_bfin_idct; - c->idct_add = bfin_idct_add; - c->idct_put = bfin_idct_put; + c->idct_permutation_type = FF_NO_IDCT_PERM; + c->fdct = ff_bfin_fdct; + if (avctx->idct_algo==FF_IDCT_VP3) { + c->idct = ff_bfin_vp3_idct; + c->idct_add = ff_bfin_vp3_idct_add; + c->idct_put = ff_bfin_vp3_idct_put; + } else { + c->idct = ff_bfin_idct; + c->idct_add = bfin_idct_add; + c->idct_put = bfin_idct_put; + } } diff --git a/contrib/ffmpeg/libavcodec/bfin/dsputil_bfin.h b/contrib/ffmpeg/libavcodec/bfin/dsputil_bfin.h new file mode 100644 index 000000000..411c8ea73 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/bfin/dsputil_bfin.h @@ -0,0 +1,74 @@ +/* + * BlackFin DSPUTILS COMMON OPTIMIZATIONS HEADER + * + * Copyright (C) 2007 Marc Hoffman <mmh@pleasantst.com> + * + * 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 + */ + + +#ifndef FFMPEG_DSPUTIL_BFIN_H +#define FFMPEG_DSPUTIL_BFIN_H + +#ifdef __FDPIC__ +#define attribute_l1_text __attribute__ ((l1_text)) +#define attribute_l1_data_b __attribute__((l1_data_B)) +#else +#define attribute_l1_text +#define attribute_l1_data_b +#endif + +#ifdef BFIN_PROFILE + +static double Telem[16]; +static char *TelemNames[16]; +static int TelemCnt; + +#define PROF(lab,e) { int xx_e = e; char*xx_lab = lab; uint64_t xx_t0 = read_time(); +#define EPROF() xx_t0 = read_time()-xx_t0; Telem[xx_e] = Telem[xx_e] + xx_t0; TelemNames[xx_e] = xx_lab; } + +static void prof_report (void) +{ + int i; + double s = 0; + for (i=0;i<16;i++) { + double v; + if (TelemNames[i]) { + v = Telem[i]/TelemCnt; + av_log (NULL,AV_LOG_DEBUG,"%-20s: %12.4f\t%12.4f\n", TelemNames[i],v,v/64); + s = s + Telem[i]; + } + } + av_log (NULL,AV_LOG_DEBUG,"%-20s: %12.4f\t%12.4f\n%20.4f\t%d\n", + "total",s/TelemCnt,s/TelemCnt/64,s,TelemCnt); +} + +static void bfprof (void) +{ + static int init; + if (!init) atexit (prof_report); + init=1; + TelemCnt++; +} + +#else +#define PROF(a,b) +#define EPROF() +#define bfprof() +#endif + +#endif /* FFMPEG_DSPUTIL_BFIN_H */ diff --git a/contrib/ffmpeg/libavcodec/bfin/fdct_bfin.S b/contrib/ffmpeg/libavcodec/bfin/fdct_bfin.S index 8230673e8..03f2709e3 100644 --- a/contrib/ffmpeg/libavcodec/bfin/fdct_bfin.S +++ b/contrib/ffmpeg/libavcodec/bfin/fdct_bfin.S @@ -129,23 +129,30 @@ root:/u/ffmpeg/bhead/libavcodec> #include "config_bfin.h" +#ifdef __FDPIC__ .section .l1.data.B,"aw",@progbits +#else +.data +#endif .align 4; dct_coeff: .short 0x5a82, 0x2d41, 0x187e, 0x3b21, 0x0c7c, 0x3ec5, 0x238e, 0x3537; +#ifdef __FDPIC__ .section .l1.data.A,"aw",@progbits +#endif .align 4 vtmp: .space 128 +.text DEFUN(fdct,mL1, (DCTELEM *block)): [--SP] = (R7:4, P5:3); // Push the registers onto the stack. b0 = r0; - r0 = [P3+dct_coeff@GOT17M4]; + RELOC(r0, P3, dct_coeff); b3 = r0; - r0 = [P3+vtmp@GOT17M4]; + RELOC(r0, P3, vtmp); b2 = r0; L3 = 16; // L3 is set to 16 to make the coefficient @@ -321,4 +328,5 @@ DEFUN(fdct,mL1, L3=0; (r7:4,p5:3) = [sp++]; RTS; +DEFUN_END(fdct) diff --git a/contrib/ffmpeg/libavcodec/bfin/idct_bfin.S b/contrib/ffmpeg/libavcodec/bfin/idct_bfin.S index f6904c189..7bb104038 100644 --- a/contrib/ffmpeg/libavcodec/bfin/idct_bfin.S +++ b/contrib/ffmpeg/libavcodec/bfin/idct_bfin.S @@ -57,7 +57,11 @@ IDCT BFINidct: 88.3 kdct/s #include "config_bfin.h" +#ifdef __FDPIC__ .section .l1.data.B,"aw",@progbits +#else +.data +#endif .align 4; coefs: @@ -72,7 +76,9 @@ coefs: .short 0x18F9; //cos(7pi/16) .short 0x7D8A; //cos(pi/16) -.section .l1.data.A +#ifdef __FDPIC__ +.section .l1.data.A,"aw",@progbits +#endif vtmp: .space 256 @@ -81,6 +87,7 @@ vtmp: .space 256 #define TMP2 FP-16 +.text DEFUN(idct,mL1, (DCTELEM *block)): @@ -88,8 +95,8 @@ DEFUN(idct,mL1, link 16; [--SP] = (R7:4, P5:3); // Push the registers onto the stack. B0 = R0; // Pointer to Input matrix - R1 = [P3+coefs@GOT17M4]; // Pointer to Coefficients - R2 = [P3+vtmp@GOT17M4]; // Pointer to Temporary matrix + RELOC(R1, P3, coefs); // Pointer to Coefficients + RELOC(R2, P3, vtmp); // Pointer to Temporary matrix B3 = R1; B2 = R2; L3 = 20; // L3 is used for making the coefficient array @@ -293,5 +300,6 @@ DEFUN(idct,mL1, (R7:4,P5:3)=[SP++]; unlink; RTS; +DEFUN_END(idct) diff --git a/contrib/ffmpeg/libavcodec/bfin/mathops.h b/contrib/ffmpeg/libavcodec/bfin/mathops.h new file mode 100644 index 000000000..ec40f4e68 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/bfin/mathops.h @@ -0,0 +1,52 @@ +/* + * mathops.h + * + * Copyright (C) 2007 Marc Hoffman <mmhoffm@gmail.com> + * + * 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 + */ +#ifndef FFMPEG_BFIN_MATHOPS_H +#define FFMPEG_BFIN_MATHOPS_H + +#ifdef CONFIG_MPEGAUDIO_HP +#define MULH(X,Y) ({ int xxo; \ + asm ( \ + "a1 = %2.L * %1.L (FU);\n\t" \ + "a1 = a1 >> 16;\n\t" \ + "a1 += %2.H * %1.L (IS,M);\n\t" \ + "a0 = %1.H * %2.H, a1+= %1.H * %2.L (IS,M);\n\t"\ + "a1 = a1 >>> 16;\n\t" \ + "%0 = (a0 += a1);\n\t" \ + : "=d" (xxo) : "d" (X), "d" (Y) : "A0","A1"); xxo; }) +#else +#define MULH(X,Y) ({ int xxo; \ + asm ( \ + "a1 = %2.H * %1.L (IS,M);\n\t" \ + "a0 = %1.H * %2.H, a1+= %1.H * %2.L (IS,M);\n\t"\ + "a1 = a1 >>> 16;\n\t" \ + "%0 = (a0 += a1);\n\t" \ + : "=d" (xxo) : "d" (X), "d" (Y) : "A0","A1"); xxo; }) +#endif + +/* signed 16x16 -> 32 multiply */ +#define MUL16(a, b) ({ int xxo; \ + asm ( \ + "%0 = %1.l*%2.l (is);\n\t" \ + : "=W" (xxo) : "d" (a), "d" (b) : "A1"); \ + xxo; }) + +#endif /* FFMPEG_BFIN_MATHOPS_H */ diff --git a/contrib/ffmpeg/libavcodec/bfin/mpegvideo_bfin.c b/contrib/ffmpeg/libavcodec/bfin/mpegvideo_bfin.c new file mode 100644 index 000000000..9dd121baf --- /dev/null +++ b/contrib/ffmpeg/libavcodec/bfin/mpegvideo_bfin.c @@ -0,0 +1,152 @@ +/* + * BlackFin MPEGVIDEO OPTIMIZATIONS + * + * Copyright (C) 2007 Marc Hoffman <mmh@pleasantst.com> + * + * 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 "dsputil.h" +#include "mpegvideo.h" +#include "avcodec.h" +#include "dsputil_bfin.h" + + +extern void ff_bfin_fdct (DCTELEM *block) attribute_l1_text; + + +static int dct_quantize_bfin (MpegEncContext *s, + DCTELEM *block, int n, + int qscale, int *overflow) +{ + int last_non_zero, q, start_i; + const short *qmat; + short *bias; + const uint8_t *scantable= s->intra_scantable.scantable; + short dc; + int max=0; + + PROF("fdct",0); + ff_bfin_fdct (block); + EPROF(); + + PROF("denoise",1); + if(s->dct_error_sum) + s->denoise_dct(s, block); + EPROF(); + + PROF("quant-init",2); + if (s->mb_intra) { + if (!s->h263_aic) { + if (n < 4) + q = s->y_dc_scale; + else + q = s->c_dc_scale; + q = q << 3; + } else + /* For AIC we skip quant/dequant of INTRADC */ + q = 1 << 3; + + /* note: block[0] is assumed to be positive */ + dc = block[0] = (block[0] + (q >> 1)) / q; + start_i = 1; + last_non_zero = 0; + bias = s->q_intra_matrix16[qscale][1]; + qmat = s->q_intra_matrix16[qscale][0]; + + } else { + start_i = 0; + last_non_zero = -1; + bias = s->q_inter_matrix16[qscale][1]; + qmat = s->q_inter_matrix16[qscale][0]; + + } + EPROF(); + + PROF("quantize",4); + + /* for(i=start_i; i<64; i++) { */ + /* sign = (block[i]>>15)|1; */ + /* level = ((abs(block[i])+bias[0])*qmat[i])>>16; */ + /* if (level < 0) level = 0; */ + /* max |= level; */ + /* level = level * sign; */ + /* block[i] = level; */ + /* } */ + + asm volatile + ("i2=%1;\n\t" + "r1=[%1++]; \n\t" + "r0=r1>>>15 (v); \n\t" + "lsetup (0f,1f) lc0=%3; \n\t" + "0: r0=r0|%4; \n\t" + " r1=abs r1 (v) || r2=[%2++];\n\t" + " r1=r1+|+%5; \n\t" + " r1=max(r1,%6) (v); \n\t" + " r1.h=(a1 =r1.h*r2.h), r1.l=(a0 =r1.l*r2.l) (tfu); \n\t" + " %0=%0|r1; \n\t" + " r0.h=(a1 =r1.h*r0.h), r0.l=(a0 =r1.l*r0.l) (is) || r1=[%1++];\n\t" + "1: r0=r1>>>15 (v) || [i2++]=r0;\n\t" + "r1=%0>>16; \n\t" + "%0=%0|r1; \n\t" + "%0.h=0; \n\t" + : "=&d" (max) + : "b" (block), "b" (qmat), "a" (32), "d" (0x00010001), "d" (bias[0]*0x10001), "d" (0) + : "R0","R1","R2", "I2"); + if (start_i == 1) block[0] = dc; + + EPROF(); + + + PROF("zzscan",5); + + asm volatile + ("r0=b[%1--] (x); \n\t" + "lsetup (0f,1f) lc0=%3; \n\t" /* for(i=63; i>=start_i; i--) { */ + "0: p0=r0; \n\t" /* j = scantable[i]; */ + " p0=%2+(p0<<1); \n\t" /* if (block[j]) { */ + " r0=w[p0]; \n\t" /* last_non_zero = i; */ + " cc=r0==0; \n\t" /* break; */ + " if !cc jump 2f; \n\t" /* } */ + "1: r0=b[%1--] (x); \n\t" /* } */ + " %0=%4; \n\t" + " jump 3f; \n\t" + "2: %0=lc0; \n\t" + "3:\n\t" + + : "=d" (last_non_zero) + : "a" (scantable+63), "a" (block), "a" (63), "d" (last_non_zero) + : "P0","R0"); + + EPROF(); + + *overflow= s->max_qcoeff < max; //overflow might have happened + + bfprof(); + + /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */ + if (s->dsp.idct_permutation_type != FF_NO_IDCT_PERM) + ff_block_permute(block, s->dsp.idct_permutation, scantable, last_non_zero); + + return last_non_zero; +} + +void MPV_common_init_bfin (MpegEncContext *s) +{ + s->dct_quantize= dct_quantize_bfin; +} + diff --git a/contrib/ffmpeg/libavcodec/bfin/pixels_bfin.S b/contrib/ffmpeg/libavcodec/bfin/pixels_bfin.S index 2968fcff6..69b493b64 100644 --- a/contrib/ffmpeg/libavcodec/bfin/pixels_bfin.S +++ b/contrib/ffmpeg/libavcodec/bfin/pixels_bfin.S @@ -48,6 +48,7 @@ ppc$1: R2 = Max(R0, R4) (V) || [I1++M1] = R6; (R7:4) = [SP++]; RTS; +DEFUN_END(put_pixels_clamped) DEFUN(add_pixels_clamped,mL1, (DCTELEM *block, uint8_t *dest, int line_size)): @@ -80,6 +81,7 @@ apc$3: R6 = BYTEOP3P(R1:0, R3:2) (LO) || [I2++M0] = R6 || R2 = [I1]; (R7:4) = [SP++]; RTS; +DEFUN_END(add_pixels_clamped) /* @@ -121,6 +123,7 @@ pp8$1: DISALGNEXCPT || R2 = [I1++] || [I3++M3] = R7; (r7:6) = [sp++]; RTS; +DEFUN_END(put_pixels8uc) DEFUN(put_pixels16uc,mL1, (uint8_t *block, const uint8_t *s0, const uint8_t *s1, @@ -155,6 +158,7 @@ pp16$1: DISALGNEXCPT || R2 = [I1++] || [I3++M3] = R7; (r7:6) = [sp++]; unlink; RTS; +DEFUN_END(put_pixels16uc) @@ -184,6 +188,7 @@ pp8$3: DISALGNEXCPT || R2 = [I1++] || [I3++M3] = R7; (r7:6) = [sp++]; RTS; +DEFUN_END(put_pixels8uc_nornd) DEFUN(put_pixels16uc_nornd,mL1, (uint8_t *block, const uint8_t *s0, const uint8_t *s1, @@ -217,6 +222,7 @@ pp16$3: DISALGNEXCPT || R2 = [I1++] || [I3++M3] = R7; (r7:6) = [sp++]; RTS; +DEFUN_END(put_pixels16uc_nornd) DEFUN(z_put_pixels16_xy2,mL1, (uint8_t *block, const uint8_t *s0, @@ -275,6 +281,7 @@ LE$16O: DISALGNEXCPT || R2 = [I1++] || [I3++M2] = R5; (r7:4) = [sp++]; unlink; rts; +DEFUN_END(z_put_pixels16_xy2) DEFUN(put_pixels16_xy2_nornd,mL1, (uint8_t *block, const uint8_t *s0, @@ -332,6 +339,7 @@ LE$16OT:DISALGNEXCPT || R2 = [I1++] || [I3++M2] = R5; (r7:4) = [sp++]; unlink; rts; +DEFUN_END(put_pixels16_xy2_nornd) DEFUN(z_put_pixels8_xy2,mL1, (uint8_t *block, const uint8_t *s0, @@ -381,6 +389,7 @@ LE$8O: DISALGNEXCPT || R2 =[I1++] || [I3++M2] = R5; (r7:4) = [sp++]; unlink; rts; +DEFUN_END(z_put_pixels8_xy2) DEFUN(put_pixels8_xy2_nornd,mL1, (uint8_t *block, const uint8_t *s0, int line_size, int h)): @@ -458,6 +467,7 @@ DEFUN(diff_pixels,mL1, (r7:4) = [sp++]; unlink; rts; +DEFUN_END(put_pixels8_xy2_nornd) /* for (i = 0; i < 16; i++) { @@ -504,6 +514,7 @@ LE$PS: r6=r6+|+r4; (r7:4) = [sp++]; unlink; rts; +DEFUN_END(pix_sum) DEFUN(get_pixels,mL1, @@ -528,6 +539,7 @@ gp8$1: [I3++]=R5 (r7:4) = [sp++]; RTS; +DEFUN_END(get_pixels) /* sad = sad16x16 (ubyte *mb, ubyte *refwin, srcwidth, refwinwidth, h) */ @@ -559,6 +571,7 @@ e$16: SAA (R1:0,R3:2) (R) || R0 = [I0++] || R2 = [I1++]; R0 = R2 + R3 ; unlink; RTS; +DEFUN_END(z_sad16x16) /* sad = sad8x8 (ubyte *mb, ubyte *refwin, int srcwidth, int refwinwidth, int h) */ /* 36 cycles */ @@ -586,6 +599,7 @@ e$8: DISALGNEXCPT || R1 = [I0++] || R3 = [I1++]; R3=A1.L+A1.H, R2=A0.L+A0.H ; R0 = R2 + R3 ; RTS; +DEFUN_END(z_sad8x8) DEFUN(pix_norm1,mL1, (uint8_t * pix, int line_size)): @@ -629,6 +643,7 @@ _pix_norm1_blkfn_loopEnd: (R7:4,P5:3)=[SP++]; RTS; +DEFUN_END(pix_norm1) DEFUN(sse4,mL1, (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)): @@ -655,6 +670,7 @@ DEFUN(sse4,mL1, (r7:6) = [sp++]; unlink; rts; +DEFUN_END(sse4) DEFUN(sse8,mL1, (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)): @@ -684,6 +700,7 @@ DEFUN(sse8,mL1, (r7:6) = [sp++]; unlink; rts; +DEFUN_END(sse8) DEFUN(sse16,mL1, (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)): @@ -719,5 +736,6 @@ DEFUN(sse16,mL1, (r7:6) = [sp++]; unlink; rts; +DEFUN_END(sse16) diff --git a/contrib/ffmpeg/libavcodec/bfin/vp3_bfin.c b/contrib/ffmpeg/libavcodec/bfin/vp3_bfin.c new file mode 100644 index 000000000..fce5668d0 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/bfin/vp3_bfin.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> + * + * 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" +#include "dsputil.h" +#include "dsputil_bfin.h" + +extern void ff_bfin_vp3_idct (DCTELEM *block) attribute_l1_text; +extern void ff_bfin_idct (DCTELEM *block) attribute_l1_text; +extern void ff_bfin_add_pixels_clamped (DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text; +extern void ff_bfin_put_pixels_clamped (DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text; + +/* Intra iDCT offset 128 */ +void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, DCTELEM *block) +{ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + int i,j; + + ff_bfin_vp3_idct (block); + + for (i=0;i<8;i++) + for (j=0;j<8;j++) + dest[line_size*i+j]=cm[128+block[i*8+j]]; +} + +/* Inter iDCT */ +void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_bfin_vp3_idct (block); + ff_bfin_add_pixels_clamped (block, dest, line_size); +} + + diff --git a/contrib/ffmpeg/libavcodec/bfin/vp3_idct_bfin.S b/contrib/ffmpeg/libavcodec/bfin/vp3_idct_bfin.S new file mode 100644 index 000000000..ec8c1bee7 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/bfin/vp3_idct_bfin.S @@ -0,0 +1,281 @@ +/* + * vp3_idct BlackFin + * + * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> + * + * 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 + */ +/* + This blackfin DSP code implements an 8x8 inverse type II DCT. + +Prototype : void ff_bfin_vp3_idct(DCTELEM *in) + +Registers Used : A0, A1, R0-R7, I0-I3, B0, B2, B3, M0-M2, L0-L3, P0-P5, LC0. + +*/ + +#include "config_bfin.h" + +#ifdef __FDPIC__ +.section .l1.data.B,"aw",@progbits +#else +.data +#endif + +.align 4; +coefs: +.short 0x5a82; // C4 +.short 0x5a82; // C4 +.short 0x30FC; //cos(3pi/8) C6 +.short 0x7642; //cos(pi/8) C2 +.short 0x18F9; //cos(7pi/16) +.short 0x7D8A; //cos(pi/16) +.short 0x471D; //cos(5pi/16) +.short 0x6A6E; //cos(3pi/16) +.short 0x18F9; //cos(7pi/16) +.short 0x7D8A; //cos(pi/16) + +#ifdef __FDPIC__ +.section .l1.data.A +#endif + +vtmp: .space 256 + +#define TMP0 FP-8 +#define TMP1 FP-12 +#define TMP2 FP-16 + + +.text +DEFUN(vp3_idct,mL1, + (DCTELEM *block)): + +/********************** Function Prologue *********************************/ + link 16; + [--SP] = (R7:4, P5:3); // Push the registers onto the stack. + B0 = R0; // Pointer to Input matrix + RELOC(R1, P3, coefs); // Pointer to Coefficients + RELOC(R2, P3, vtmp); // Pointer to Temporary matrix + B3 = R1; + B2 = R2; + L3 = 20; // L3 is used for making the coefficient array + // circular. + // MUST BE RESTORED TO ZERO at function exit. + M1 = 16 (X); // All these registers are initialized for + M3 = 8(X); // modifying address offsets. + + I0 = B0; // I0 points to Input Element (0, 0). + I2 = B0; // I2 points to Input Element (0, 0). + I2 += M3 || R0.H = W[I0]; + // Element 0 is read into R0.H + I1 = I2; // I1 points to input Element (0, 6). + I1 += 4 || R0.L = W[I2++]; + // I2 points to input Element (0, 4). + // Element 4 is read into R0.L. + P2 = 8 (X); + P3 = 32 (X); + P4 = -32 (X); + P5 = 98 (X); + R7 = 0x8000(Z); + I3 = B3; // I3 points to Coefficients + P0 = B2; // P0 points to array Element (0, 0) of temp + P1 = B2; + R7 = [I3++] || [TMP2]=R7; // Coefficient C4 is read into R7.H and R7.L. + MNOP; + NOP; + + /* + * A1 = Y0 * cos(pi/4) + * A0 = Y0 * cos(pi/4) + * A1 = A1 + Y4 * cos(pi/4) + * A0 = A0 - Y4 * cos(pi/4) + * load: + * R1=(Y2,Y6) + * R7=(C2,C6) + * res: + * R3=Y0, R2=Y4 + */ + A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || I0+= 4 || R1.L=W[I1++]; + R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || R1.H=W[I0--] || R7=[I3++]; + + LSETUP (.0, .1) LC0 = P2; // perform 8 1d idcts + + P2 = 112 (X); + P1 = P1 + P2; // P1 points to element (7, 0) of temp buffer. + P2 = -94(X); + +.0: + /* + * A1 = Y2 * cos(3pi/8) + * A0 = Y2 * cos(pi/8) + * A1 = A1 - Y6 * cos(pi/8) + * A0 = A0 + Y6 * cos(3pi/8) + * R5 = (Y1,Y7) + * R7 = (C1,C7) + * res: + * R1=Y2, R0=Y6 + */ + A1=R7.L*R1.H, A0=R7.H*R1.H (IS) || I0+=4 || R5.H=W[I0]; + R1=(A1-=R7.H*R1.L), R0=(A0+=R7.L*R1.L) (IS) || R5.L=W[I1--] || R7=[I3++]; + /* + * Y0 = Y0 + Y6. + * Y4 = Y4 + Y2. + * Y2 = Y4 - Y2. + * Y6 = Y0 - Y6. + * R3 is saved + * R6.l=Y3 + * note: R3: Y0, R2: Y4, R1: Y2, R0: Y6 + */ + R3=R3+R0, R0=R3-R0; + R2=R2+R1, R1=R2-R1 || [TMP0]=R3 || R6.L=W[I0--]; + /* + * Compute the odd portion (1,3,5,7) even is done. + * + * Y1 = C7 * Y1 - C1 * Y7 + C3 * Y5 - C5 * Y3. + * Y7 = C1 * Y1 + C7 * Y7 + C5 * Y5 + C3 * Y3. + * Y5 = C5 * Y1 + C3 * Y7 + C7 * Y5 - C1 * Y3. + * Y3 = C3 * Y1 - C5 * Y7 - C1 * Y5 - C7 * Y3. + */ + // R5=(Y1,Y7) R6=(Y5,Y3) // R7=(C1,C7) + A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || [TMP1]=R2 || R6.H=W[I2--]; + A1-=R7.H*R5.L, A0+=R7.L*R5.L (IS) || I0-=4 || R7=[I3++]; + A1+=R7.H*R6.H, A0+=R7.L*R6.H (IS) || I0+=M1; // R7=(C3,C5) + R3 =(A1-=R7.L*R6.L), R2 =(A0+=R7.H*R6.L) (IS); + A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || R4=[TMP0]; + A1+=R7.H*R5.L, A0-=R7.L*R5.L (IS) || I1+=M1 || R7=[I3++]; // R7=(C1,C7) + A1+=R7.L*R6.H, A0-=R7.H*R6.H (IS); + R7 =(A1-=R7.H*R6.L), R6 =(A0-=R7.L*R6.L) (IS) || I2+=M1; + // R3=Y1, R2=Y7, R7=Y5, R6=Y3 + + /* Transpose write column. */ + R5.H=R4+R2 (RND12); // Y0=Y0+Y7 + R5.L=R4-R2 (RND12) || R4 = [TMP1]; // Y7=Y7-Y0 + R2.H=R1+R7 (RND12) || W[P0++P3]=R5.H; // Y2=Y2+Y5 st Y0 + R2.L=R1-R7 (RND12) || W[P1++P4]=R5.L || R7=[I3++]; // Y5=Y2-Y5 st Y7 + R5.H=R0-R3 (RND12) || W[P0++P3]=R2.H || R1.L=W[I1++]; // Y1=Y6-Y1 st Y2 + R5.L=R0+R3 (RND12) || W[P1++P4]=R2.L || R0.H=W[I0++]; // Y6=Y6+Y1 st Y5 + R3.H=R4-R6 (RND12) || W[P0++P3]=R5.H || R0.L=W[I2++]; // Y3=Y3-Y4 st Y1 + R3.L=R4+R6 (RND12) || W[P1++P4]=R5.L || R1.H=W[I0++]; // Y4=Y3+Y4 st Y6 + + /* pipeline loop start, + drain Y3, Y4 */ + A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || W[P0++P2]= R3.H || R1.H = W[I0--]; +.1: R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || W[P1++P5]= R3.L || R7 = [I3++]; + + + + I0 = B2; // I0 points to Input Element (0, 0) + I2 = B2; // I2 points to Input Element (0, 0) + I2 += M3 || R0.H = W[I0]; + // Y0 is read in R0.H + I1 = I2; // I1 points to input Element (0, 6) + I1 += 4 || R0.L = W[I2++]; + // I2 points to input Element (0, 4) + // Y4 is read in R0.L + P2 = 8 (X); + I3 = B3; // I3 points to Coefficients + P0 = B0; // P0 points to array Element (0, 0) for writing + // output + P1 = B0; + R7 = [I3++]; // R7.H = C4 and R7.L = C4 + NOP; + + /* + * A1 = Y0 * cos(pi/4) + * A0 = Y0 * cos(pi/4) + * A1 = A1 + Y4 * cos(pi/4) + * A0 = A0 - Y4 * cos(pi/4) + * load: + * R1=(Y2,Y6) + * R7=(C2,C6) + * res: + * R3=Y0, R2=Y4 + */ + A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || I0+=4 || R1.L=W[I1++]; + R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || R1.H=W[I0--] || R7=[I3++]; + + LSETUP (.2, .3) LC0 = P2; // peform 8 1d idcts + P2 = 112 (X); + P1 = P1 + P2; + P2 = -94(X); + +.2: + /* + * A1 = Y2 * cos(3pi/8) + * A0 = Y2 * cos(pi/8) + * A1 = A1 - Y6 * cos(pi/8) + * A0 = A0 + Y6 * cos(3pi/8) + * R5 = (Y1,Y7) + * R7 = (C1,C7) + * res: + * R1=Y2, R0=Y6 + */ + A1=R7.L*R1.H, A0=R7.H*R1.H (IS) || I0+=4 || R5.H=W[I0]; + R1=(A1-=R7.H*R1.L), R0=(A0+=R7.L*R1.L) (IS) || R5.L=W[I1--] || R7=[I3++]; + /* + * Y0 = Y0 + Y6. + * Y4 = Y4 + Y2. + * Y2 = Y4 - Y2. + * Y6 = Y0 - Y6. + * R3 is saved + * R6.l=Y3 + * note: R3: Y0, R2: Y4, R1: Y2, R0: Y6 + */ + R3=R3+R0, R0=R3-R0; + R2=R2+R1, R1=R2-R1 || [TMP0]=R3 || R6.L=W[I0--]; + /* + * Compute the odd portion (1,3,5,7) even is done. + * + * Y1 = C7 * Y1 - C1 * Y7 + C3 * Y5 - C5 * Y3. + * Y7 = C1 * Y1 + C7 * Y7 + C5 * Y5 + C3 * Y3. + * Y5 = C5 * Y1 + C3 * Y7 + C7 * Y5 - C1 * Y3. + * Y3 = C3 * Y1 - C5 * Y7 - C1 * Y5 - C7 * Y3. + */ + // R5=(Y1,Y7) R6=(Y5,Y3) // R7=(C1,C7) + A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || [TMP1]=R2 || R6.H=W[I2--]; + A1-=R7.H*R5.L, A0+=R7.L*R5.L (IS) || I0-=4 || R7=[I3++]; + A1+=R7.H*R6.H, A0+=R7.L*R6.H (IS) || I0+=M1; // R7=(C3,C5) + R3 =(A1-=R7.L*R6.L), R2 =(A0+=R7.H*R6.L) (IS); + A1 =R7.L*R5.H, A0 =R7.H*R5.H (IS) || R4=[TMP0]; + A1+=R7.H*R5.L, A0-=R7.L*R5.L (IS) || I1+=M1 || R7=[I3++]; // R7=(C1,C7) + A1+=R7.L*R6.H, A0-=R7.H*R6.H (IS); + R7 =(A1-=R7.H*R6.L), R6 =(A0-=R7.L*R6.L) (IS) || I2+=M1; + // R3=Y1, R2=Y7, R7=Y5, R6=Y3 + + /* Transpose write column. */ + R5.H=R4+R2 (RND20); // Y0=Y0+Y7 + R5.L=R4-R2 (RND20) || R4 = [TMP1]; // Y7=Y7-Y0 + R5=R5>>>2(v); + R2.H=R1+R7 (RND20) || W[P0++P3]=R5.H; // Y2=Y2+Y5 st Y0 + R2.L=R1-R7 (RND20) || W[P1++P4]=R5.L || R7=[I3++]; // Y5=Y2-Y5 st Y7 + R2=R2>>>2(v); + R5.H=R0-R3 (RND20) || W[P0++P3]=R2.H || R1.L=W[I1++]; // Y1=Y6-Y1 st Y2 + R5.L=R0+R3 (RND20) || W[P1++P4]=R2.L || R0.H=W[I0++]; // Y6=Y6+Y1 st Y5 + R5=R5>>>2(v); + R3.H=R4-R6 (RND20) || W[P0++P3]=R5.H || R0.L=W[I2++]; // Y3=Y3-Y4 st Y1 + R3.L=R4+R6 (RND20) || W[P1++P4]=R5.L || R1.H=W[I0++]; // Y4=Y3+Y4 st Y6 + R3=R3>>>2(v); + /* pipeline loop start, + drain Y3, Y4 */ + A1=R7.H*R0.H, A0=R7.H*R0.H (IS) || W[P0++P2]= R3.H || R1.H = W[I0--]; +.3: R3=(A1+=R7.H*R0.L), R2=(A0-=R7.H*R0.L) (IS) || W[P1++P5]= R3.L || R7 = [I3++]; + + L3 = 0; + (R7:4,P5:3)=[SP++]; + unlink; + RTS; +DEFUN_END(vp3_idct) + + diff --git a/contrib/ffmpeg/libavcodec/bitstream.c b/contrib/ffmpeg/libavcodec/bitstream.c index a0c239798..b74775e9c 100644 --- a/contrib/ffmpeg/libavcodec/bitstream.c +++ b/contrib/ffmpeg/libavcodec/bitstream.c @@ -3,6 +3,8 @@ * Copyright (c) 2000, 2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * + * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,8 +20,6 @@ * 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 - * - * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at> */ /** @@ -36,6 +36,8 @@ * @param[in] ptr The block of memory to reallocate. * @param[in] size The requested size. * @return Block of memory of requested size. + * @deprecated. Code which uses ff_realloc_static is broken/misdesigned + * and should correctly use static arrays */ attribute_deprecated void *ff_realloc_static(void *ptr, unsigned int size); @@ -48,7 +50,7 @@ void align_put_bits(PutBitContext *s) #endif } -void ff_put_string(PutBitContext * pbc, char *s, int put_zero) +void ff_put_string(PutBitContext * pbc, const char *s, int put_zero) { while(*s){ put_bits(pbc, 8, *s); @@ -58,6 +60,28 @@ void ff_put_string(PutBitContext * pbc, char *s, int put_zero) put_bits(pbc, 8, 0); } +void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length) +{ + const uint16_t *srcw= (const uint16_t*)src; + int words= length>>4; + int bits= length&15; + int i; + + if(length==0) return; + + if(ENABLE_SMALL || words < 16 || put_bits_count(pb)&7){ + for(i=0; i<words; i++) put_bits(pb, 16, be2me_16(srcw[i])); + }else{ + for(i=0; put_bits_count(pb)&31; i++) + put_bits(pb, 8, src[i]); + flush_put_bits(pb); + memcpy(pbBufPtr(pb), src+i, 2*words-i); + skip_put_bytes(pb, 2*words-i); + } + + put_bits(pb, bits, be2me_16(srcw[words])>>(16-bits)); +} + /* VLC decoding */ //#define DEBUG_VLC @@ -102,16 +126,17 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, + const void *symbols, int symbols_wrap, int symbols_size, uint32_t code_prefix, int n_prefix, int flags) { - int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2; + int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2, symbol; uint32_t code; VLC_TYPE (*table)[2]; table_size = 1 << table_nb_bits; table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_STATIC); #ifdef DEBUG_VLC - printf("new table index=%d size=%d code_prefix=%x n=%d\n", + av_log(NULL,AV_LOG_DEBUG,"new table index=%d size=%d code_prefix=%x n=%d\n", table_index, table_size, code_prefix, n_prefix); #endif if (table_index < 0) @@ -130,8 +155,12 @@ static int build_table(VLC *vlc, int table_nb_bits, /* we accept tables with holes */ if (n <= 0) continue; + if (!symbols) + symbol = i; + else + GET_DATA(symbol, symbols, i, symbols_wrap, symbols_size); #if defined(DEBUG_VLC) && 0 - printf("i=%d n=%d code=0x%x\n", i, n, code); + av_log(NULL,AV_LOG_DEBUG,"i=%d n=%d code=0x%x\n", i, n, code); #endif /* if code matches the prefix, it is in the table */ n -= n_prefix; @@ -156,14 +185,14 @@ static int build_table(VLC *vlc, int table_nb_bits, return -1; } table[j][1] = n; //bits - table[j][0] = i; //code + table[j][0] = symbol; j++; } } else { n -= table_nb_bits; j = (code >> ((flags & INIT_VLC_LE) ? n_prefix : n)) & ((1 << table_nb_bits) - 1); #ifdef DEBUG_VLC - printf("%4x: n=%d (subtable)\n", + av_log(NULL,AV_LOG_DEBUG,"%4x: n=%d (subtable)\n", j, n); #endif /* compute table size */ @@ -187,6 +216,7 @@ static int build_table(VLC *vlc, int table_nb_bits, index = build_table(vlc, n, nb_codes, bits, bits_wrap, bits_size, codes, codes_wrap, codes_size, + symbols, symbols_wrap, symbols_size, (flags & INIT_VLC_LE) ? (code_prefix | (i << n_prefix)) : ((code_prefix << table_nb_bits) | i), n_prefix + table_nb_bits, flags); if (index < 0) @@ -212,6 +242,8 @@ static int build_table(VLC *vlc, int table_nb_bits, 'codes' : table which gives the bit pattern of of each vlc code. + 'symbols' : table which gives the values to be returned from get_vlc(). + 'xxx_wrap' : give the number of bytes between each entry of the 'bits' or 'codes' tables. @@ -219,14 +251,15 @@ static int build_table(VLC *vlc, int table_nb_bits, or 'codes' tables. 'wrap' and 'size' allows to use any memory configuration and types - (byte/word/long) to store the 'bits' and 'codes' tables. + (byte/word/long) to store the 'bits', 'codes', and 'symbols' tables. 'use_static' should be set to 1 for tables, which should be freed with av_free_static(), 0 if free_vlc() will be used. */ -int init_vlc(VLC *vlc, int nb_bits, int nb_codes, +int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, + const void *symbols, int symbols_wrap, int symbols_size, int flags) { vlc->bits = nb_bits; @@ -242,14 +275,15 @@ int init_vlc(VLC *vlc, int nb_bits, int nb_codes, } #ifdef DEBUG_VLC - printf("build table nb_codes=%d\n", nb_codes); + av_log(NULL,AV_LOG_DEBUG,"build table nb_codes=%d\n", nb_codes); #endif if (build_table(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, codes, codes_wrap, codes_size, + symbols, symbols_wrap, symbols_size, 0, 0, flags) < 0) { - av_free(vlc->table); + av_freep(&vlc->table); return -1; } return 0; @@ -258,6 +292,6 @@ int init_vlc(VLC *vlc, int nb_bits, int nb_codes, void free_vlc(VLC *vlc) { - av_free(vlc->table); + av_freep(&vlc->table); } diff --git a/contrib/ffmpeg/libavcodec/bitstream.h b/contrib/ffmpeg/libavcodec/bitstream.h index 18842702c..0a6f7de53 100644 --- a/contrib/ffmpeg/libavcodec/bitstream.h +++ b/contrib/ffmpeg/libavcodec/bitstream.h @@ -23,13 +23,19 @@ * bitstream api header. */ -#ifndef BITSTREAM_H -#define BITSTREAM_H - +#ifndef FFMPEG_BITSTREAM_H +#define FFMPEG_BITSTREAM_H + +#include <stdint.h> +#include <stdlib.h> +#include <assert.h> +#include "common.h" +#include "bswap.h" +#include "intreadwrite.h" #include "log.h" #if defined(ALT_BITSTREAM_READER_LE) && !defined(ALT_BITSTREAM_READER) -#define ALT_BITSTREAM_READER +# define ALT_BITSTREAM_READER #endif //#define ALT_BITSTREAM_WRITER @@ -38,7 +44,7 @@ # ifdef ARCH_ARMV4L # define A32_BITSTREAM_READER # else -#define ALT_BITSTREAM_READER +# define ALT_BITSTREAM_READER //#define LIBMPEG2_BITSTREAM_READER //#define A32_BITSTREAM_READER # endif @@ -131,7 +137,8 @@ static inline void flush_put_bits(PutBitContext *s) } void align_put_bits(PutBitContext *s); -void ff_put_string(PutBitContext * pbc, char *s, int put_zero); +void ff_put_string(PutBitContext * pbc, const char *s, int put_zero); +void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length); /* bit input */ /* buffer, buffer_end and size_in_bits must be present and used by every reader */ @@ -166,11 +173,11 @@ typedef struct RL_VLC_ELEM { uint8_t run; } RL_VLC_ELEM; -#if defined(ARCH_SPARC) || defined(ARCH_ARMV4L) || defined(ARCH_MIPS) +#if defined(ARCH_SPARC) || defined(ARCH_ARMV4L) || defined(ARCH_MIPS) || defined(ARCH_BFIN) #define UNALIGNED_STORES_ARE_BAD #endif -/* used to avoid missaligned exceptions on some archs (alpha, ...) */ +/* used to avoid misaligned exceptions on some archs (alpha, ...) */ #if defined(ARCH_X86) # define unaligned16(a) (*(const uint16_t*)(a)) # define unaligned32(a) (*(const uint32_t*)(a)) @@ -335,8 +342,8 @@ static inline void skip_put_bytes(PutBitContext *s, int n){ } /** - * skips the given number of bits. - * must only be used if the actual values in the bitstream dont matter + * Skips the given number of bits. + * Must only be used if the actual values in the bitstream do not matter. */ static inline void skip_put_bits(PutBitContext *s, int n){ #ifdef ALT_BITSTREAM_WRITER @@ -400,26 +407,6 @@ LAST_SKIP_BITS(name, gb, num) for examples see get_bits, show_bits, skip_bits, get_vlc */ -static inline int unaligned32_be(const void *v) -{ -#ifdef CONFIG_ALIGN - const uint8_t *p=v; - return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]); -#else - return be2me_32( unaligned32(v)); //original -#endif -} - -static inline int unaligned32_le(const void *v) -{ -#ifdef CONFIG_ALIGN - const uint8_t *p=v; - return (((p[3]<<8) | p[2])<<16) | (p[1]<<8) | (p[0]); -#else - return le2me_32( unaligned32(v)); //original -#endif -} - #ifdef ALT_BITSTREAM_READER # define MIN_CACHE_BITS 25 @@ -432,13 +419,13 @@ static inline int unaligned32_le(const void *v) # ifdef ALT_BITSTREAM_READER_LE # define UPDATE_CACHE(name, gb)\ - name##_cache= unaligned32_le( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) >> (name##_index&0x07);\ + name##_cache= AV_RL32( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) >> (name##_index&0x07);\ # define SKIP_CACHE(name, gb, num)\ name##_cache >>= (num); # else # define UPDATE_CACHE(name, gb)\ - name##_cache= unaligned32_be( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ + name##_cache= AV_RB32( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ # define SKIP_CACHE(name, gb, num)\ name##_cache <<= (num); @@ -799,9 +786,19 @@ static inline void align_get_bits(GetBitContext *s) if(n) skip_bits(s, n); } -int init_vlc(VLC *vlc, int nb_bits, int nb_codes, +#define init_vlc(vlc, nb_bits, nb_codes,\ + bits, bits_wrap, bits_size,\ + codes, codes_wrap, codes_size,\ + flags)\ + init_vlc_sparse(vlc, nb_bits, nb_codes,\ + bits, bits_wrap, bits_size,\ + codes, codes_wrap, codes_size,\ + NULL, 0, 0, flags) + +int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, + const void *symbols, int symbols_wrap, int symbols_size, int flags); #define INIT_VLC_USE_STATIC 1 #define INIT_VLC_LE 2 @@ -873,7 +870,7 @@ void free_vlc(VLC *vlc); * parses a vlc code, faster then get_vlc() * @param bits is the number of bits which will be read at once, must be * identical to nb_bits in init_vlc() - * @param max_depth is the number of times bits bits must be readed to completly + * @param max_depth is the number of times bits bits must be read to completely * read the longest vlc code * = (max_vlc_length + bits - 1) / bits */ @@ -953,4 +950,11 @@ static inline int decode012(GetBitContext *gb){ return get_bits1(gb) + 1; } -#endif /* BITSTREAM_H */ +static inline int decode210(GetBitContext *gb){ + if (get_bits1(gb)) + return 0; + else + return 2 - get_bits1(gb); +} + +#endif /* FFMPEG_BITSTREAM_H */ diff --git a/contrib/ffmpeg/libavcodec/bitstream_filter.c b/contrib/ffmpeg/libavcodec/bitstream_filter.c index 89fc4e175..aeafd7db4 100644 --- a/contrib/ffmpeg/libavcodec/bitstream_filter.c +++ b/contrib/ffmpeg/libavcodec/bitstream_filter.c @@ -19,10 +19,14 @@ */ #include "avcodec.h" -#include "mpegaudio.h" AVBitStreamFilter *first_bitstream_filter= NULL; +AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f){ + if(f) return f->next; + else return first_bitstream_filter; +} + void av_register_bitstream_filter(AVBitStreamFilter *bsf){ bsf->next = first_bitstream_filter; first_bitstream_filter= bsf; @@ -44,6 +48,8 @@ AVBitStreamFilterContext *av_bitstream_filter_init(const char *name){ } void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc){ + if(bsfc->filter->close) + bsfc->filter->close(bsfc); av_freep(&bsfc->priv_data); av_parser_close(bsfc->parser); av_free(bsfc); @@ -57,228 +63,3 @@ int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, *poutbuf_size= buf_size; return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size, buf, buf_size, keyframe); } - -static int dump_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - int cmd= args ? *args : 0; - /* cast to avoid warning about discarding qualifiers */ - if(avctx->extradata){ - if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER) && cmd=='a') - ||(keyframe && (cmd=='k' || !cmd)) - ||(cmd=='e') - /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){ - int size= buf_size + avctx->extradata_size; - *poutbuf_size= size; - *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - - memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); - memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - return 1; - } - } - return 0; -} - -static int remove_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - int cmd= args ? *args : 0; - AVCodecParserContext *s; - - if(!bsfc->parser){ - bsfc->parser= av_parser_init(avctx->codec_id); - } - s= bsfc->parser; - - if(s && s->parser->split){ - if( (((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) && cmd=='a') - ||(!keyframe && cmd=='k') - ||(cmd=='e' || !cmd) - ){ - int i= s->parser->split(avctx, buf, buf_size); - buf += i; - buf_size -= i; - } - } - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - - return 0; -} - -static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - int amount= args ? atoi(args) : 10000; - unsigned int *state= bsfc->priv_data; - int i; - - *poutbuf= av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - - memcpy(*poutbuf, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - for(i=0; i<buf_size; i++){ - (*state) += (*poutbuf)[i] + 1; - if(*state % amount == 0) - (*poutbuf)[i] = *state; - } - return 1; -} - -#define MP3_MASK 0xFFFE0CCF - -static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - uint32_t header, extraheader; - int mode_extension, header_size; - - if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "not standards compliant\n"); - return -1; - } - - header = AV_RB32(buf); - mode_extension= (header>>4)&3; - - if(ff_mpa_check_header(header) < 0 || (header&0x60000) != 0x20000){ -output_unchanged: - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - - av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header); - return 0; - } - - if(avctx->extradata_size == 0){ - avctx->extradata_size=15; - avctx->extradata= av_malloc(avctx->extradata_size); - strcpy(avctx->extradata, "FFCMP3 0.0"); - memcpy(avctx->extradata+11, buf, 4); - } - if(avctx->extradata_size != 15){ - av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n"); - return -1; - } - extraheader = AV_RB32(avctx->extradata+11); - if((extraheader&MP3_MASK) != (header&MP3_MASK)) - goto output_unchanged; - - header_size= (header&0x10000) ? 4 : 6; - - *poutbuf_size= buf_size - header_size; - *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); - - if(avctx->channels==2){ - if((header & (3<<19)) != 3<<19){ - (*poutbuf)[1] &= 0x3F; - (*poutbuf)[1] |= mode_extension<<6; - FFSWAP(int, (*poutbuf)[1], (*poutbuf)[2]); - }else{ - (*poutbuf)[1] &= 0x8F; - (*poutbuf)[1] |= mode_extension<<4; - } - } - - return 1; -} - -static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe){ - uint32_t header; - int sample_rate= avctx->sample_rate; - int sample_rate_index=0; - int lsf, mpeg25, bitrate_index, frame_size; - - header = AV_RB32(buf); - if(ff_mpa_check_header(header) >= 0){ - *poutbuf= (uint8_t *) buf; - *poutbuf_size= buf_size; - - return 0; - } - - if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){ - av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size); - return -1; - } - - header= AV_RB32(avctx->extradata+11) & MP3_MASK; - - lsf = sample_rate < (24000+32000)/2; - mpeg25 = sample_rate < (12000+16000)/2; - sample_rate_index= (header>>10)&3; - sample_rate= mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off - - for(bitrate_index=2; bitrate_index<30; bitrate_index++){ - frame_size = mpa_bitrate_tab[lsf][2][bitrate_index>>1]; - frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1); - if(frame_size == buf_size + 4) - break; - if(frame_size == buf_size + 6) - break; - } - if(bitrate_index == 30){ - av_log(avctx, AV_LOG_ERROR, "couldnt find bitrate_index\n"); - return -1; - } - - header |= (bitrate_index&1)<<9; - header |= (bitrate_index>>1)<<12; - header |= (frame_size == buf_size + 4)<<16; //FIXME actually set a correct crc instead of 0 - - *poutbuf_size= frame_size; - *poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - - if(avctx->channels==2){ - uint8_t *p= *poutbuf + frame_size - buf_size; - if(lsf){ - FFSWAP(int, p[1], p[2]); - header |= (p[1] & 0xC0)>>2; - p[1] &= 0x3F; - }else{ - header |= p[1] & 0x30; - p[1] &= 0xCF; - } - } - - (*poutbuf)[0]= header>>24; - (*poutbuf)[1]= header>>16; - (*poutbuf)[2]= header>> 8; - (*poutbuf)[3]= header ; - - return 1; -} - -AVBitStreamFilter dump_extradata_bsf={ - "dump_extra", - 0, - dump_extradata, -}; - -AVBitStreamFilter remove_extradata_bsf={ - "remove_extra", - 0, - remove_extradata, -}; - -AVBitStreamFilter noise_bsf={ - "noise", - sizeof(int), - noise, -}; - -AVBitStreamFilter mp3_header_compress_bsf={ - "mp3comp", - 0, - mp3_header_compress, -}; - -AVBitStreamFilter mp3_header_decompress_bsf={ - "mp3decomp", - 0, - mp3_header_decompress, -}; diff --git a/contrib/ffmpeg/libavcodec/bmp.c b/contrib/ffmpeg/libavcodec/bmp.c index d1cfdce6d..35d20e6cc 100644 --- a/contrib/ffmpeg/libavcodec/bmp.c +++ b/contrib/ffmpeg/libavcodec/bmp.c @@ -34,7 +34,7 @@ static int bmp_decode_init(AVCodecContext *avctx){ static int bmp_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { BMPContext *s = avctx->priv_data; AVFrame *picture = data; @@ -48,7 +48,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, uint32_t rgb[3]; uint8_t *ptr; int dsize; - uint8_t *buf0 = buf; + const uint8_t *buf0 = buf; if(buf_size < 14){ av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); @@ -111,7 +111,6 @@ static int bmp_decode_frame(AVCodecContext *avctx, rgb[2] = bytestream_get_le32(&buf); } - avctx->codec_id = CODEC_ID_BMP; avctx->width = width; avctx->height = height > 0? height: -height; @@ -194,7 +193,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, break; case 16: for(i = 0; i < avctx->height; i++){ - uint16_t *src = (uint16_t *) buf; + const uint16_t *src = (const uint16_t *) buf; uint16_t *dst = (uint16_t *) ptr; for(j = 0; j < avctx->width; j++) @@ -206,7 +205,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, break; case 32: for(i = 0; i < avctx->height; i++){ - uint8_t *src = buf; + const uint8_t *src = buf; uint8_t *dst = ptr; for(j = 0; j < avctx->width; j++){ diff --git a/contrib/ffmpeg/libavcodec/bmp.h b/contrib/ffmpeg/libavcodec/bmp.h index cf6ace845..cbbd21ce9 100644 --- a/contrib/ffmpeg/libavcodec/bmp.h +++ b/contrib/ffmpeg/libavcodec/bmp.h @@ -19,6 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_BMP_H +#define FFMPEG_BMP_H + +#include "avcodec.h" + typedef struct BMPContext { AVFrame picture; } BMPContext; @@ -29,3 +34,5 @@ typedef enum { BMP_RLE4 =2, BMP_BITFIELDS =3, } BiCompression; + +#endif /* FFMPEG_BMP_H */ diff --git a/contrib/ffmpeg/libavcodec/bytestream.h b/contrib/ffmpeg/libavcodec/bytestream.h index d1e9f82ed..3a94e719c 100644 --- a/contrib/ffmpeg/libavcodec/bytestream.h +++ b/contrib/ffmpeg/libavcodec/bytestream.h @@ -22,27 +22,38 @@ #ifndef FFMPEG_BYTESTREAM_H #define FFMPEG_BYTESTREAM_H -#define DEF(name, bytes, read, write)\ -static av_always_inline unsigned int bytestream_get_ ## name(uint8_t **b){\ +#include "common.h" + +#define DEF_T(type, name, bytes, read, write) \ +static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\ (*b) += bytes;\ return read(*b - bytes);\ }\ -static av_always_inline void bytestream_put_ ##name(uint8_t **b, const unsigned int value){\ +static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type value){\ write(*b, value);\ (*b) += bytes;\ -}; +} + +#define DEF(name, bytes, read, write) \ + DEF_T(unsigned int, name, bytes, read, write) +#define DEF64(name, bytes, read, write) \ + DEF_T(uint64_t, name, bytes, read, write) -DEF(le32, 4, AV_RL32, AV_WL32) -DEF(le24, 3, AV_RL24, AV_WL24) -DEF(le16, 2, AV_RL16, AV_WL16) -DEF(be32, 4, AV_RB32, AV_WB32) -DEF(be24, 3, AV_RB24, AV_WB24) -DEF(be16, 2, AV_RB16, AV_WB16) -DEF(byte, 1, AV_RB8 , AV_WB8 ) +DEF64(le64, 8, AV_RL64, AV_WL64) +DEF (le32, 4, AV_RL32, AV_WL32) +DEF (le24, 3, AV_RL24, AV_WL24) +DEF (le16, 2, AV_RL16, AV_WL16) +DEF64(be64, 8, AV_RB64, AV_WB64) +DEF (be32, 4, AV_RB32, AV_WB32) +DEF (be24, 3, AV_RB24, AV_WB24) +DEF (be16, 2, AV_RB16, AV_WB16) +DEF (byte, 1, AV_RB8 , AV_WB8 ) #undef DEF +#undef DEF64 +#undef DEF_T -static av_always_inline unsigned int bytestream_get_buffer(uint8_t **b, uint8_t *dst, unsigned int size) +static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size) { memcpy(dst, *b, size); (*b) += size; diff --git a/contrib/ffmpeg/libavcodec/c93.c b/contrib/ffmpeg/libavcodec/c93.c new file mode 100644 index 000000000..2b5d3900c --- /dev/null +++ b/contrib/ffmpeg/libavcodec/c93.c @@ -0,0 +1,253 @@ +/* + * Interplay C93 video decoder + * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com> + * + * 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" +#include "bytestream.h" + +typedef struct { + AVFrame pictures[2]; + int currentpic; +} C93DecoderContext; + +typedef enum { + C93_8X8_FROM_PREV = 0x02, + C93_4X4_FROM_PREV = 0x06, + C93_4X4_FROM_CURR = 0x07, + C93_8X8_2COLOR = 0x08, + C93_4X4_2COLOR = 0x0A, + C93_4X4_4COLOR_GRP = 0x0B, + C93_4X4_4COLOR = 0x0D, + C93_NOOP = 0x0E, + C93_8X8_INTRA = 0x0F, +} C93BlockType; + +#define WIDTH 320 +#define HEIGHT 192 + +#define C93_HAS_PALETTE 0x01 +#define C93_FIRST_FRAME 0x02 + +static int decode_init(AVCodecContext *avctx) +{ + avctx->pix_fmt = PIX_FMT_PAL8; + return 0; +} + +static int decode_end(AVCodecContext *avctx) +{ + C93DecoderContext * const c93 = avctx->priv_data; + + if (c93->pictures[0].data[0]) + avctx->release_buffer(avctx, &c93->pictures[0]); + if (c93->pictures[1].data[0]) + avctx->release_buffer(avctx, &c93->pictures[1]); + return 0; +} + +static inline int copy_block(AVCodecContext *avctx, uint8_t *to, + uint8_t *from, int offset, int height, int stride) +{ + int i; + int width = height; + int from_x = offset % WIDTH; + int from_y = offset / WIDTH; + int overflow = from_x + width - WIDTH; + + if (!from) { + /* silently ignoring predictive blocks in first frame */ + return 0; + } + + if (from_y + height > HEIGHT) { + av_log(avctx, AV_LOG_ERROR, "invalid offset %d during C93 decoding\n", + offset); + return -1; + } + + if (overflow > 0) { + width -= overflow; + for (i = 0; i < height; i++) { + memcpy(&to[i*stride+width], &from[(from_y+i)*stride], overflow); + } + } + + for (i = 0; i < height; i++) { + memcpy(&to[i*stride], &from[(from_y+i)*stride+from_x], width); + } + + return 0; +} + +static inline void draw_n_color(uint8_t *out, int stride, int width, + int height, int bpp, uint8_t cols[4], uint8_t grps[4], uint32_t col) +{ + int x, y; + for (y = 0; y < height; y++) { + if (grps) + cols[0] = grps[3 * (y >> 1)]; + for (x = 0; x < width; x++) { + if (grps) + cols[1]= grps[(x >> 1) + 1]; + out[x + y*stride] = cols[col & ((1 << bpp) - 1)]; + col >>= bpp; + } + } +} + +static int decode_frame(AVCodecContext *avctx, void *data, + int *data_size, const uint8_t * buf, int buf_size) +{ + C93DecoderContext * const c93 = avctx->priv_data; + AVFrame * const newpic = &c93->pictures[c93->currentpic]; + AVFrame * const oldpic = &c93->pictures[c93->currentpic^1]; + AVFrame *picture = data; + uint8_t *out; + int stride, i, x, y, bt = 0; + + c93->currentpic ^= 1; + + newpic->reference = 1; + newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | + FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; + if (avctx->reget_buffer(avctx, newpic)) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + + stride = newpic->linesize[0]; + + if (buf[0] & C93_FIRST_FRAME) { + newpic->pict_type = FF_I_TYPE; + newpic->key_frame = 1; + } else { + newpic->pict_type = FF_P_TYPE; + newpic->key_frame = 0; + } + + if (*buf++ & C93_HAS_PALETTE) { + uint32_t *palette = (uint32_t *) newpic->data[1]; + const uint8_t *palbuf = buf + buf_size - 768 - 1; + for (i = 0; i < 256; i++) { + palette[i] = bytestream_get_be24(&palbuf); + } + } else { + if (oldpic->data[1]) + memcpy(newpic->data[1], oldpic->data[1], 256 * 4); + } + + for (y = 0; y < HEIGHT; y += 8) { + out = newpic->data[0] + y * stride; + for (x = 0; x < WIDTH; x += 8) { + uint8_t *copy_from = oldpic->data[0]; + unsigned int offset, j; + uint8_t cols[4], grps[4]; + C93BlockType block_type; + + if (!bt) + bt = *buf++; + + block_type= bt & 0x0F; + switch (block_type) { + case C93_8X8_FROM_PREV: + offset = bytestream_get_le16(&buf); + if (copy_block(avctx, out, copy_from, offset, 8, stride)) + return -1; + break; + + case C93_4X4_FROM_CURR: + copy_from = newpic->data[0]; + case C93_4X4_FROM_PREV: + for (j = 0; j < 8; j += 4) { + for (i = 0; i < 8; i += 4) { + offset = bytestream_get_le16(&buf); + if (copy_block(avctx, &out[j*stride+i], + copy_from, offset, 4, stride)) + return -1; + } + } + break; + + case C93_8X8_2COLOR: + bytestream_get_buffer(&buf, cols, 2); + for (i = 0; i < 8; i++) { + draw_n_color(out + i*stride, stride, 8, 1, 1, cols, + NULL, *buf++); + } + + break; + + case C93_4X4_2COLOR: + case C93_4X4_4COLOR: + case C93_4X4_4COLOR_GRP: + for (j = 0; j < 8; j += 4) { + for (i = 0; i < 8; i += 4) { + if (block_type == C93_4X4_2COLOR) { + bytestream_get_buffer(&buf, cols, 2); + draw_n_color(out + i + j*stride, stride, 4, 4, + 1, cols, NULL, bytestream_get_le16(&buf)); + } else if (block_type == C93_4X4_4COLOR) { + bytestream_get_buffer(&buf, cols, 4); + draw_n_color(out + i + j*stride, stride, 4, 4, + 2, cols, NULL, bytestream_get_le32(&buf)); + } else { + bytestream_get_buffer(&buf, grps, 4); + draw_n_color(out + i + j*stride, stride, 4, 4, + 1, cols, grps, bytestream_get_le16(&buf)); + } + } + } + break; + + case C93_NOOP: + break; + + case C93_8X8_INTRA: + for (j = 0; j < 8; j++) + bytestream_get_buffer(&buf, out + j*stride, 8); + break; + + default: + av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n", + block_type, x, y); + return -1; + } + bt >>= 4; + out += 8; + } + } + + *picture = *newpic; + *data_size = sizeof(AVFrame); + + return buf_size; +} + +AVCodec c93_decoder = { + "c93", + CODEC_TYPE_VIDEO, + CODEC_ID_C93, + sizeof(C93DecoderContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; diff --git a/contrib/ffmpeg/libavcodec/cabac.c b/contrib/ffmpeg/libavcodec/cabac.c index c6da6292a..fc17bb6ac 100644 --- a/contrib/ffmpeg/libavcodec/cabac.c +++ b/contrib/ffmpeg/libavcodec/cabac.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -179,12 +178,14 @@ void ff_init_cabac_states(CABACContext *c){ } } -#if 0 //selftest +#ifdef TEST +#undef random #define SIZE 10240 #include "avcodec.h" +#include "cabac.h" -int main(){ +int main(void){ CABACContext c; uint8_t b[9*SIZE]; uint8_t r[9*SIZE]; @@ -192,7 +193,7 @@ int main(){ uint8_t state[10]= {0}; ff_init_cabac_encoder(&c, b, SIZE); - ff_init_cabac_states(&c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); + ff_init_cabac_states(&c); for(i=0; i<SIZE; i++){ r[i]= random()%7; @@ -262,4 +263,4 @@ STOP_TIMER("get_cabac_ueg") return 0; } -#endif +#endif /* TEST */ diff --git a/contrib/ffmpeg/libavcodec/cabac.h b/contrib/ffmpeg/libavcodec/cabac.h index 147d25ffa..6d5a6f170 100644 --- a/contrib/ffmpeg/libavcodec/cabac.h +++ b/contrib/ffmpeg/libavcodec/cabac.h @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -25,6 +24,10 @@ * Context Adaptive Binary Arithmetic Coder. */ +#ifndef FFMPEG_CABAC_H +#define FFMPEG_CABAC_H + +#include "bitstream.h" //#undef NDEBUG #include <assert.h> @@ -87,6 +90,7 @@ static inline void renorm_cabac_encoder(CABACContext *c){ } } +#ifdef TEST static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state]; @@ -256,6 +260,7 @@ static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int put_cabac_bypass(c, sign); } } +#endif /* TEST */ static void refill(CABACContext *c){ #if CABAC_BITS == 16 @@ -267,6 +272,7 @@ static void refill(CABACContext *c){ c->bytestream+= CABAC_BITS/8; } +#if ! ( defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS) ) static void refill2(CABACContext *c){ int i, x; @@ -284,6 +290,7 @@ static void refill2(CABACContext *c){ c->low += x<<i; c->bytestream+= CABAC_BITS/8; } +#endif static inline void renorm_cabac_decoder(CABACContext *c){ while(c->range < 0x100){ @@ -320,7 +327,7 @@ static inline void renorm_cabac_decoder_once(CABACContext *c){ //P3:665 athlon:517 asm( "lea -0x100(%0), %%eax \n\t" - "cdq \n\t" + "cltd \n\t" "mov %0, %%eax \n\t" "and %%edx, %0 \n\t" "and %1, %%edx \n\t" @@ -363,7 +370,7 @@ static inline void renorm_cabac_decoder_once(CABACContext *c){ refill(c); } -static int av_always_inline get_cabac_inline(CABACContext *c, uint8_t * const state){ +static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ //FIXME gcc generates duplicate load/stores for c->low and c->range #define LOW "0" #define RANGE "4" @@ -376,7 +383,7 @@ static int av_always_inline get_cabac_inline(CABACContext *c, uint8_t * const st #define BYTE "16" #define BYTEEND "20" #endif -#if defined(ARCH_X86) && defined(CONFIG_7REGS) && defined(CONFIG_EBX_AVAILABLE) && !( defined(ARCH_X86_64) && defined(PIC) ) +#if defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS) int bit; #ifndef BRANCHLESS_CABAC_DECODER @@ -454,7 +461,7 @@ static int av_always_inline get_cabac_inline(CABACContext *c, uint8_t * const st "2: \n\t" "movl %%edx, "RANGE "(%2) \n\t" "movl %%ebx, "LOW "(%2) \n\t" - :"=&a"(bit) //FIXME this is fragile gcc either runs out of registers or misscompiles it (for example if "+a"(bit) or "+m"(*state) is used + :"=&a"(bit) //FIXME this is fragile gcc either runs out of registers or miscompiles it (for example if "+a"(bit) or "+m"(*state) is used :"r"(state), "r"(c) : "%"REG_c, "%ebx", "%edx", "%"REG_S, "memory" ); @@ -532,10 +539,10 @@ static int av_always_inline get_cabac_inline(CABACContext *c, uint8_t * const st ); bit&=1; #endif /* BRANCHLESS_CABAC_DECODER */ -#else /* defined(ARCH_X86) && !(defined(PIC) && defined(__GNUC__)) */ +#else /* defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS) */ int s = *state; int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; - int bit, lps_mask attribute_unused; + int bit, lps_mask av_unused; c->range -= RangeLPS; #ifndef BRANCHLESS_CABAC_DECODER @@ -571,7 +578,7 @@ static int av_always_inline get_cabac_inline(CABACContext *c, uint8_t * const st if(!(c->low & CABAC_MASK)) refill2(c); #endif /* BRANCHLESS_CABAC_DECODER */ -#endif /* defined(ARCH_X86) && !(defined(PIC) && defined(__GNUC__)) */ +#endif /* defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS) */ return bit; } @@ -592,7 +599,7 @@ static int get_cabac_bypass(CABACContext *c){ "shl $17, %%ebx \n\t" "add %%eax, %%eax \n\t" "sub %%ebx, %%eax \n\t" - "cdq \n\t" + "cltd \n\t" "and %%edx, %%ebx \n\t" "add %%ebx, %%eax \n\t" "test %%ax, %%ax \n\t" @@ -639,7 +646,7 @@ static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ "shl $17, %%ebx \n\t" "add %%eax, %%eax \n\t" "sub %%ebx, %%eax \n\t" - "cdq \n\t" + "cltd \n\t" "and %%edx, %%ebx \n\t" "add %%ebx, %%eax \n\t" "xor %%edx, %%ecx \n\t" @@ -679,8 +686,8 @@ static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ } //FIXME the x86 code from this file should be moved into i386/h264 or cabac something.c/h (note ill kill you if you move my code away from under my fingers before iam finished with it!) -//FIXME use some macros to avoid duplicatin get_cabac (cant be done yet as that would make optimization work hard) -#if defined(ARCH_X86) && defined(CONFIG_7REGS) && defined(CONFIG_EBX_AVAILABLE) && !( defined(ARCH_X86_64) && defined(PIC) ) +//FIXME use some macros to avoid duplicatin get_cabac (cannot be done yet as that would make optimization work hard) +#if defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS) static int decode_significance_x86(CABACContext *c, int max_coeff, uint8_t *significant_coeff_ctx_base, int *index){ void *end= significant_coeff_ctx_base + max_coeff - 1; int minusstart= -(int)significant_coeff_ctx_base; @@ -731,7 +738,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, uint8_t *sign return coeff_count; } -static int decode_significance_8x8_x86(CABACContext *c, uint8_t *significant_coeff_ctx_base, int *index, uint8_t *sig_off){ +static int decode_significance_8x8_x86(CABACContext *c, uint8_t *significant_coeff_ctx_base, int *index, const uint8_t *sig_off){ int minusindex= 4-(int)index; int coeff_count; long last=0; @@ -786,7 +793,7 @@ static int decode_significance_8x8_x86(CABACContext *c, uint8_t *significant_coe ); return coeff_count; } -#endif /* defined(ARCH_X86) && !(defined(PIC) && defined(__GNUC__)) */ +#endif /* defined(ARCH_X86) && && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS) */ /** * @@ -802,8 +809,9 @@ static int get_cabac_terminate(CABACContext *c){ } } +#if 0 /** - * get (truncated) unnary binarization. + * Get (truncated) unary binarization. */ static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){ int i; @@ -857,3 +865,6 @@ static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signe }else return i; } +#endif /* 0 */ + +#endif /* FFMPEG_CABAC_H */ diff --git a/contrib/ffmpeg/libavcodec/cavs.c b/contrib/ffmpeg/libavcodec/cavs.c index 4672635d7..2867c0679 100644 --- a/contrib/ffmpeg/libavcodec/cavs.c +++ b/contrib/ffmpeg/libavcodec/cavs.c @@ -16,7 +16,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -28,82 +28,9 @@ #include "avcodec.h" #include "bitstream.h" #include "golomb.h" -#include "mpegvideo.h" +#include "cavs.h" #include "cavsdata.h" -#ifdef CONFIG_CAVS_DECODER -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 @@ -144,7 +71,7 @@ static inline int get_bs(vector_t *mvP, vector_t *mvQ, int b) { * --------- * */ -static void filter_mb(AVSContext *h, enum mb_t mb_type) { +void ff_cavs_filter(AVSContext *h, enum mb_t mb_type) { DECLARE_ALIGNED_8(uint8_t, bs[8]); int qp_avg, alpha, beta, tc; int i; @@ -168,11 +95,11 @@ static void filter_mb(AVSContext *h, enum mb_t mb_type) { *((uint64_t *)bs) = 0x0202020202020202ULL; else{ *((uint64_t *)bs) = 0; - if(partition_flags[mb_type] & SPLITV){ + if(ff_cavs_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){ + if(ff_cavs_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); } @@ -216,7 +143,7 @@ static void filter_mb(AVSContext *h, enum mb_t mb_type) { * ****************************************************************************/ -static inline void load_intra_pred_luma(AVSContext *h, uint8_t *top, +void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top, uint8_t **left, int block) { int i; @@ -266,9 +193,26 @@ static inline void load_intra_pred_luma(AVSContext *h, uint8_t *top, } } +void ff_cavs_load_intra_pred_chroma(AVSContext *h) { + /* 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]; + } +} + static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride) { int y; - uint64_t a = unaligned64(&top[1]); + uint64_t a = AV_RN64(&top[1]); for(y=0;y<8;y++) { *((uint64_t *)(d+y*stride)) = a; } @@ -353,11 +297,23 @@ static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride) #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; +void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv) { + /* 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(ff_left_modifier_l, &h->pred_mode_Y[4] ); + modify_pred(ff_left_modifier_l, &h->pred_mode_Y[7] ); + modify_pred(ff_left_modifier_c, pred_mode_uv ); + } + if(!(h->flags & B_AVAIL)) { + modify_pred(ff_top_modifier_l, &h->pred_mode_Y[4] ); + modify_pred(ff_top_modifier_l, &h->pred_mode_Y[5] ); + modify_pred(ff_top_modifier_c, pred_mode_uv ); } } @@ -454,8 +410,8 @@ static inline void mc_part_std(AVSContext *h,int square,int chroma_height,int de } } -static void inter_pred(AVSContext *h, enum mb_t mb_type) { - if(partition_flags[mb_type] == 0){ // 16x16 +void ff_cavs_inter(AVSContext *h, enum mb_t mb_type) { + if(ff_cavs_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], @@ -483,9 +439,6 @@ static void inter_pred(AVSContext *h, enum mb_t mb_type) { 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; } /***************************************************************************** @@ -494,27 +447,6 @@ static void inter_pred(AVSContext *h, enum mb_t mb_type) { * ****************************************************************************/ -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]; @@ -547,37 +479,8 @@ static inline void mv_pred_median(AVSContext *h, vector_t *mvP, vector_t *mvA, v } } -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) { +void ff_cavs_mv(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]; @@ -592,7 +495,7 @@ static void mv_pred(AVSContext *h, enum mv_loc_t nP, enum mv_loc_t nC, ((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; + mvP2 = &ff_cavs_un_mv; /* if there is only one suitable candidate, take it */ } else if((mvA->ref >= 0) && (mvB->ref < 0) && (mvC->ref < 0)) { mvP2= mvA; @@ -622,111 +525,6 @@ static void mv_pred(AVSContext *h, enum mv_loc_t nP, enum mv_loc_t nC, /***************************************************************************** * - * 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<<block)) - decode_residual_block(h,&h->s.gb,inter_2dvlc,0,h->qp, - h->cy + h->luma_scan[block], h->l_stride); - decode_residual_chroma(h); - - return 0; -} - -/***************************************************************************** - * * macroblock level * ****************************************************************************/ @@ -734,7 +532,7 @@ static inline int decode_residual_inter(AVSContext *h) { /** * initialise predictors for motion vectors and intra prediction */ -static inline void init_mb(AVSContext *h) { +void ff_cavs_init_mb(AVSContext *h) { int i; /* copy predictors from top line (MB B and C) into cache */ @@ -746,10 +544,10 @@ static inline void init_mb(AVSContext *h) { 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->mv[MV_FWD_B2] = ff_cavs_un_mv; + h->mv[MV_FWD_B3] = ff_cavs_un_mv; + h->mv[MV_BWD_B2] = ff_cavs_un_mv; + h->mv[MV_BWD_B3] = ff_cavs_un_mv; h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL; h->flags &= ~(C_AVAIL|D_AVAIL); } else if(h->mbx) { @@ -759,26 +557,24 @@ static inline void init_mb(AVSContext *h) { 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; + h->mv[MV_FWD_C2] = ff_cavs_un_mv; + h->mv[MV_BWD_C2] = ff_cavs_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; + h->mv[MV_FWD_D3] = ff_cavs_un_mv; + h->mv[MV_BWD_D3] = ff_cavs_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 ff_cavs_next_mb(AVSContext *h) { int i; h->flags |= A_AVAIL; @@ -801,7 +597,7 @@ static inline int next_mb(AVSContext *h) { 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->mv[i] = ff_cavs_un_mv; h->mbx = 0; h->mby++; /* re-calculate sample pointers */ @@ -817,309 +613,21 @@ static inline int next_mb(AVSContext *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<<block)) - decode_residual_block(h,gb,intra_2dvlc,1,h->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) { +void ff_cavs_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; + h->mv[i] = ff_cavs_un_mv; + h->mv[MV_BWD_X0] = ff_cavs_dir_mv; set_mvs(&h->mv[MV_BWD_X0], BLK_16X16); - h->mv[MV_FWD_X0] = dir_mv; + h->mv[MV_FWD_X0] = ff_cavs_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]; @@ -1133,136 +641,6 @@ static void init_pic(AVSContext *h) { 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 @@ -1274,7 +652,7 @@ static int decode_pic(AVSContext *h) { * 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) { +void ff_cavs_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)); @@ -1290,116 +668,7 @@ static void init_top_lines(AVSContext *h) { 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; -} - -static void 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) { +int ff_cavs_init(AVCodecContext *avctx) { AVSContext *h = avctx->priv_data; MpegEncContext * const s = &h->s; @@ -1425,12 +694,12 @@ static int cavs_decode_init(AVCodecContext * avctx) { 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; + h->mv[ 7] = ff_cavs_un_mv; + h->mv[19] = ff_cavs_un_mv; return 0; } -static int cavs_decode_end(AVCodecContext * avctx) { +int ff_cavs_end(AVCodecContext *avctx) { AVSContext *h = avctx->priv_data; av_free(h->top_qp); @@ -1445,96 +714,3 @@ static int cavs_decode_end(AVCodecContext * avctx) { 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= cavs_flush, -}; -#endif /* CONFIG_CAVS_DECODER */ - -#ifdef CONFIG_CAVSVIDEO_PARSER -/** - * finds the end of the current frame in the bitstream. - * @return the position of the first byte of the next frame, or -1 - */ -static int 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<buf_size; i++){ - state= (state<<8) | buf[i]; - if(state == PIC_I_START_CODE || state == PIC_PB_START_CODE){ - i++; - pic_found=1; - break; - } - } - } - - if(pic_found){ - /* EOF considered as end of frame */ - if (buf_size == 0) - return 0; - for(; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if((state&0xFFFFFF00) == 0x100){ - if(state < SLICE_MIN_START_CODE || state > 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; -} - -static int cavsvideo_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= cavs_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - *poutbuf = (uint8_t *)buf; - *poutbuf_size = buf_size; - return next; -} - -AVCodecParser cavsvideo_parser = { - { CODEC_ID_CAVS }, - sizeof(ParseContext1), - NULL, - cavsvideo_parse, - ff_parse1_close, - ff_mpeg4video_split, -}; -#endif /* CONFIG_CAVSVIDEO_PARSER */ diff --git a/contrib/ffmpeg/libavcodec/cavs.h b/contrib/ffmpeg/libavcodec/cavs.h new file mode 100644 index 000000000..9afa96e42 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/cavs.h @@ -0,0 +1,314 @@ +/* + * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. + * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> + * + * 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 + */ + +#ifndef FFMPEG_CAVS_H +#define FFMPEG_CAVS_H + +#include "dsputil.h" +#include "mpegvideo.h" + +#define SLICE_MIN_START_CODE 0x00000101 +#define SLICE_MAX_START_CODE 0x000001af +#define EXT_START_CODE 0x000001b5 +#define USER_START_CODE 0x000001b2 +#define CAVS_START_CODE 0x000001b0 +#define PIC_I_START_CODE 0x000001b3 +#define PIC_PB_START_CODE 0x000001b6 + +#define A_AVAIL 1 +#define B_AVAIL 2 +#define C_AVAIL 4 +#define D_AVAIL 8 +#define NOT_AVAIL -1 +#define REF_INTRA -2 +#define REF_DIR -3 + +#define ESCAPE_CODE 59 + +#define FWD0 0x01 +#define FWD1 0x02 +#define BWD0 0x04 +#define BWD1 0x08 +#define SYM0 0x10 +#define SYM1 0x20 +#define SPLITH 0x40 +#define SPLITV 0x80 + +#define MV_BWD_OFFS 12 +#define MV_STRIDE 4 + +enum mb_t { + I_8X8 = 0, + P_SKIP, + P_16X16, + P_16X8, + P_8X16, + P_8X8, + B_SKIP, + B_DIRECT, + B_FWD_16X16, + B_BWD_16X16, + B_SYM_16X16, + B_8X8 = 29 +}; + +enum sub_mb_t { + B_SUB_DIRECT, + B_SUB_FWD, + B_SUB_BWD, + B_SUB_SYM +}; + +enum intra_luma_t { + INTRA_L_VERT, + INTRA_L_HORIZ, + INTRA_L_LP, + INTRA_L_DOWN_LEFT, + INTRA_L_DOWN_RIGHT, + INTRA_L_LP_LEFT, + INTRA_L_LP_TOP, + INTRA_L_DC_128 +}; + +enum intra_chroma_t { + INTRA_C_LP, + INTRA_C_HORIZ, + INTRA_C_VERT, + INTRA_C_PLANE, + INTRA_C_LP_LEFT, + INTRA_C_LP_TOP, + INTRA_C_DC_128, +}; + +enum mv_pred_t { + MV_PRED_MEDIAN, + MV_PRED_LEFT, + MV_PRED_TOP, + MV_PRED_TOPRIGHT, + MV_PRED_PSKIP, + MV_PRED_BSKIP +}; + +enum block_t { + BLK_16X16, + BLK_16X8, + BLK_8X16, + BLK_8X8 +}; + +enum mv_loc_t { + MV_FWD_D3 = 0, + MV_FWD_B2, + MV_FWD_B3, + MV_FWD_C2, + MV_FWD_A1, + MV_FWD_X0, + MV_FWD_X1, + MV_FWD_A3 = 8, + MV_FWD_X2, + MV_FWD_X3, + MV_BWD_D3 = MV_BWD_OFFS, + MV_BWD_B2, + MV_BWD_B3, + MV_BWD_C2, + MV_BWD_A1, + MV_BWD_X0, + MV_BWD_X1, + MV_BWD_A3 = MV_BWD_OFFS+8, + MV_BWD_X2, + MV_BWD_X3 +}; + +DECLARE_ALIGNED_8(typedef, struct) { + int16_t x; + int16_t y; + int16_t dist; + int16_t ref; +} vector_t; + +typedef struct dec_2dvlc_t { + int8_t rltab[59][3]; + int8_t level_add[27]; + int8_t golomb_order; + int inc_limit; + int8_t max_run; +} dec_2dvlc_t; + +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; + +extern const uint8_t ff_cavs_dequant_shift[64]; +extern const uint16_t ff_cavs_dequant_mul[64]; +extern const dec_2dvlc_t ff_cavs_intra_dec[7]; +extern const dec_2dvlc_t ff_cavs_inter_dec[7]; +extern const dec_2dvlc_t ff_cavs_chroma_dec[5]; +extern const uint8_t ff_cavs_chroma_qp[64]; +extern const uint8_t ff_cavs_scan3x3[4]; +extern const uint8_t ff_cavs_partition_flags[30]; +extern const int_fast8_t ff_left_modifier_l[8]; +extern const int_fast8_t ff_top_modifier_l[8]; +extern const int_fast8_t ff_left_modifier_c[7]; +extern const int_fast8_t ff_top_modifier_c[7]; +extern const vector_t ff_cavs_intra_mv; +extern const vector_t ff_cavs_un_mv; +extern const vector_t ff_cavs_dir_mv; + +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; + } +} + +static inline void set_intra_mode_default(AVSContext *h) { + 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; +} + +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 set_mv_intra(AVSContext *h) { + h->mv[MV_FWD_X0] = ff_cavs_intra_mv; + set_mvs(&h->mv[MV_FWD_X0], BLK_16X16); + h->mv[MV_BWD_X0] = ff_cavs_intra_mv; + set_mvs(&h->mv[MV_BWD_X0], BLK_16X16); + if(h->pic_type != FF_B_TYPE) + *h->col_type = I_8X8; +} + +static inline int dequant(AVSContext *h, DCTELEM *level_buf, uint8_t *run_buf, + DCTELEM *dst, int mul, int shift, int coeff_num) { + int round = 1 << (shift - 1); + int pos = -1; + const uint8_t *scantab = h->scantable.permutated; + + /* inverse scan and dequantization */ + while(--coeff_num >= 0){ + pos += run_buf[coeff_num]; + 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; + } + dst[scantab[pos]] = (level_buf[coeff_num]*mul + round) >> shift; + } + return 0; +} + +void ff_cavs_filter(AVSContext *h, enum mb_t mb_type); +void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top, uint8_t **left, + int block); +void ff_cavs_load_intra_pred_chroma(AVSContext *h); +void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv); +void ff_cavs_inter(AVSContext *h, enum mb_t mb_type); +void ff_cavs_mv(AVSContext *h, enum mv_loc_t nP, enum mv_loc_t nC, + enum mv_pred_t mode, enum block_t size, int ref); +void ff_cavs_init_mb(AVSContext *h); +int ff_cavs_next_mb(AVSContext *h); +void ff_cavs_init_pic(AVSContext *h); +void ff_cavs_init_top_lines(AVSContext *h); +int ff_cavs_init(AVCodecContext *avctx); +int ff_cavs_end (AVCodecContext *avctx); + +#endif /* FFMPEG_CAVS_H */ diff --git a/contrib/ffmpeg/libavcodec/cavs_parser.c b/contrib/ffmpeg/libavcodec/cavs_parser.c new file mode 100644 index 000000000..33f7fff71 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/cavs_parser.c @@ -0,0 +1,107 @@ +/* + * Chinese AVS video (AVS1-P2, JiZhun profile) parser. + * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> + * + * 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 cavs_parser.c + * Chinese AVS video (AVS1-P2, JiZhun profile) parser + * @author Stefan Gehrer <stefan.gehrer@gmx.de> + */ + +#include "parser.h" +#include "cavs.h" + + +/** + * finds the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int 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<buf_size; i++){ + state= (state<<8) | buf[i]; + if(state == PIC_I_START_CODE || state == PIC_PB_START_CODE){ + i++; + pic_found=1; + break; + } + } + } + + if(pic_found){ + /* EOF considered as end of frame */ + if (buf_size == 0) + return 0; + for(; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if((state&0xFFFFFF00) == 0x100){ + if(state < SLICE_MIN_START_CODE || state > 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; +} + +static int cavsvideo_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + int next; + + if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ + next= buf_size; + }else{ + next= cavs_find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser cavsvideo_parser = { + { CODEC_ID_CAVS }, + sizeof(ParseContext1), + NULL, + cavsvideo_parse, + ff_parse1_close, + ff_mpeg4video_split, +}; diff --git a/contrib/ffmpeg/libavcodec/cavsdata.h b/contrib/ffmpeg/libavcodec/cavsdata.h index d76985136..a24fb5ddb 100644 --- a/contrib/ffmpeg/libavcodec/cavsdata.h +++ b/contrib/ffmpeg/libavcodec/cavsdata.h @@ -16,123 +16,15 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define SLICE_MIN_START_CODE 0x00000101 -#define SLICE_MAX_START_CODE 0x000001af -#define EXT_START_CODE 0x000001b5 -#define USER_START_CODE 0x000001b2 -#define SEQ_START_CODE 0x000001b0 -#define PIC_I_START_CODE 0x000001b3 -#define PIC_PB_START_CODE 0x000001b6 +#ifndef FFMPEG_CAVSDATA_H +#define FFMPEG_CAVSDATA_H -#define A_AVAIL 1 -#define B_AVAIL 2 -#define C_AVAIL 4 -#define D_AVAIL 8 -#define NOT_AVAIL -1 -#define REF_INTRA -2 -#define REF_DIR -3 +#include "cavs.h" -#define ESCAPE_CODE 59 - -#define FWD0 0x01 -#define FWD1 0x02 -#define BWD0 0x04 -#define BWD1 0x08 -#define SYM0 0x10 -#define SYM1 0x20 -#define SPLITH 0x40 -#define SPLITV 0x80 - -#define MV_BWD_OFFS 12 -#define MV_STRIDE 4 - -enum mb_t { - I_8X8 = 0, - P_SKIP, - P_16X16, - P_16X8, - P_8X16, - P_8X8, - B_SKIP, - B_DIRECT, - B_FWD_16X16, - B_BWD_16X16, - B_SYM_16X16, - B_8X8 = 29 -}; - -enum sub_mb_t { - B_SUB_DIRECT, - B_SUB_FWD, - B_SUB_BWD, - B_SUB_SYM -}; - -enum intra_luma_t { - INTRA_L_VERT, - INTRA_L_HORIZ, - INTRA_L_LP, - INTRA_L_DOWN_LEFT, - INTRA_L_DOWN_RIGHT, - INTRA_L_LP_LEFT, - INTRA_L_LP_TOP, - INTRA_L_DC_128 -}; - -enum intra_chroma_t { - INTRA_C_LP, - INTRA_C_HORIZ, - INTRA_C_VERT, - INTRA_C_PLANE, - INTRA_C_LP_LEFT, - INTRA_C_LP_TOP, - INTRA_C_DC_128, -}; - -enum mv_pred_t { - MV_PRED_MEDIAN, - MV_PRED_LEFT, - MV_PRED_TOP, - MV_PRED_TOPRIGHT, - MV_PRED_PSKIP, - MV_PRED_BSKIP -}; - -enum block_t { - BLK_16X16, - BLK_16X8, - BLK_8X16, - BLK_8X8 -}; - -enum mv_loc_t { - MV_FWD_D3 = 0, - MV_FWD_B2, - MV_FWD_B3, - MV_FWD_C2, - MV_FWD_A1, - MV_FWD_X0, - MV_FWD_X1, - MV_FWD_A3 = 8, - MV_FWD_X2, - MV_FWD_X3, - MV_BWD_D3 = MV_BWD_OFFS, - MV_BWD_B2, - MV_BWD_B3, - MV_BWD_C2, - MV_BWD_A1, - MV_BWD_X0, - MV_BWD_X1, - MV_BWD_A3 = MV_BWD_OFFS+8, - MV_BWD_X2, - MV_BWD_X3 -}; - -#ifdef CONFIG_CAVS_DECODER -static const uint8_t partition_flags[30] = { +const uint8_t ff_cavs_partition_flags[30] = { 0, //I_8X8 0, //P_SKIP 0, //P_16X16 @@ -165,32 +57,16 @@ static const uint8_t partition_flags[30] = { SPLITH|SPLITV, //B_8X8 = 29 }; -static const uint8_t scan3x3[4] = {4,5,7,8}; - -static const uint8_t mv_scan[4] = { - MV_FWD_X0,MV_FWD_X1, - MV_FWD_X2,MV_FWD_X3 -}; - -static const uint8_t cbp_tab[64][2] = { - {63, 0},{15,15},{31,63},{47,31},{ 0,16},{14,32},{13,47},{11,13}, - { 7,14},{ 5,11},{10,12},{ 8, 5},{12,10},{61, 7},{ 4,48},{55, 3}, - { 1, 2},{ 2, 8},{59, 4},{ 3, 1},{62,61},{ 9,55},{ 6,59},{29,62}, - {45,29},{51,27},{23,23},{39,19},{27,30},{46,28},{53, 9},{30, 6}, - {43,60},{37,21},{60,44},{16,26},{21,51},{28,35},{19,18},{35,20}, - {42,24},{26,53},{44,17},{32,37},{58,39},{24,45},{20,58},{17,43}, - {18,42},{48,46},{22,36},{33,33},{25,34},{49,40},{40,52},{36,49}, - {34,50},{50,56},{52,25},{54,22},{41,54},{56,57},{38,41},{57,38} -}; +const uint8_t ff_cavs_scan3x3[4] = {4,5,7,8}; -static const uint8_t chroma_qp[64] = { +const uint8_t ff_cavs_chroma_qp[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 32,33,34,35,36,37,38,39,40,41,42,42,43,43,44,44, 45,45,46,46,47,47,48,48,48,49,49,49,50,50,50,51 }; -static const uint8_t dequant_shift[64] = { +const uint8_t ff_cavs_dequant_shift[64] = { 14,14,14,14,14,14,14,14, 13,13,13,13,13,13,13,13, 13,12,12,12,12,12,12,12, @@ -201,7 +77,7 @@ static const uint8_t dequant_shift[64] = { 7, 7, 7, 7, 7, 7, 7, 7 }; -static const uint16_t dequant_mul[64] = { +const uint16_t ff_cavs_dequant_mul[64] = { 32768,36061,38968,42495,46341,50535,55437,60424, 32932,35734,38968,42495,46177,50535,55109,59933, 65535,35734,38968,42577,46341,50617,55027,60097, @@ -212,35 +88,20 @@ static const uint16_t dequant_mul[64] = { 32771,35734,38965,42497,46341,50535,55109,60099 }; -DECLARE_ALIGNED_8(typedef, struct) { - int16_t x; - int16_t y; - int16_t dist; - int16_t ref; -} vector_t; - /** marks block as unavailable, i.e. out of picture or not yet decoded */ -static const vector_t un_mv = {0,0,1,NOT_AVAIL}; +const vector_t ff_cavs_un_mv = {0,0,1,NOT_AVAIL}; /** marks block as "no prediction from this direction" e.g. forward motion vector in BWD partition */ -static const vector_t dir_mv = {0,0,1,REF_DIR}; +const vector_t ff_cavs_dir_mv = {0,0,1,REF_DIR}; /** marks block as using intra prediction */ -static const vector_t intra_mv = {0,0,1,REF_INTRA}; - -typedef struct residual_vlc_t { - int8_t rltab[59][3]; - int8_t level_add[27]; - int8_t golomb_order; - int inc_limit; - int8_t max_run; -} residual_vlc_t; +const vector_t ff_cavs_intra_mv = {0,0,1,REF_INTRA}; #define EOB 0,0,0 -static const residual_vlc_t intra_2dvlc[7] = { +const dec_2dvlc_t ff_cavs_intra_dec[7] = { { { //level / run / table_inc { 1, 1, 1},{ -1, 1, 1},{ 1, 2, 1},{ -1, 2, 1},{ 1, 3, 1},{ -1, 3, 1}, @@ -377,7 +238,7 @@ static const residual_vlc_t intra_2dvlc[7] = { } }; -static const residual_vlc_t inter_2dvlc[7] = { +const dec_2dvlc_t ff_cavs_inter_dec[7] = { { { //level / run { 1, 1, 1},{ -1, 1, 1},{ 1, 2, 1},{ -1, 2, 1},{ 1, 3, 1},{ -1, 3, 1}, @@ -514,7 +375,7 @@ static const residual_vlc_t inter_2dvlc[7] = { } }; -static const residual_vlc_t chroma_2dvlc[5] = { +const dec_2dvlc_t ff_cavs_chroma_dec[5] = { { { //level / run { 1, 1, 1},{ -1, 1, 1},{ 1, 2, 1},{ -1, 2, 1},{ 1, 3, 1},{ -1, 3, 1}, @@ -636,8 +497,9 @@ static const uint8_t tc_tab[64] = { 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9 }; -static const int_fast8_t left_modifier_l[8] = { 0,-1, 6,-1,-1, 7, 6, 7}; -static const int_fast8_t top_modifier_l[8] = {-1, 1, 5,-1,-1, 5, 7, 7}; -static const int_fast8_t left_modifier_c[7] = { 5,-1, 2,-1, 6, 5, 6}; -static const int_fast8_t top_modifier_c[7] = { 4, 1,-1,-1, 4, 6, 6}; -#endif /* CONFIG_CAVS_DECODER */ +const int_fast8_t ff_left_modifier_l[8] = { 0,-1, 6,-1,-1, 7, 6, 7}; +const int_fast8_t ff_top_modifier_l[8] = {-1, 1, 5,-1,-1, 5, 7, 7}; +const int_fast8_t ff_left_modifier_c[7] = { 5,-1, 2,-1, 6, 5, 6}; +const int_fast8_t ff_top_modifier_c[7] = { 4, 1,-1,-1, 4, 6, 6}; + +#endif /* FFMPEG_CAVSDATA_H */ diff --git a/contrib/ffmpeg/libavcodec/cavsdec.c b/contrib/ffmpeg/libavcodec/cavsdec.c new file mode 100644 index 000000000..b3849a434 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/cavsdec.c @@ -0,0 +1,702 @@ +/* + * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. + * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> + * + * 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 cavs.c + * Chinese AVS video (AVS1-P2, JiZhun profile) decoder + * @author Stefan Gehrer <stefan.gehrer@gmx.de> + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "golomb.h" +#include "cavs.h" + +static const uint8_t mv_scan[4] = { + MV_FWD_X0,MV_FWD_X1, + MV_FWD_X2,MV_FWD_X3 +}; + +static const uint8_t cbp_tab[64][2] = { + {63, 0},{15,15},{31,63},{47,31},{ 0,16},{14,32},{13,47},{11,13}, + { 7,14},{ 5,11},{10,12},{ 8, 5},{12,10},{61, 7},{ 4,48},{55, 3}, + { 1, 2},{ 2, 8},{59, 4},{ 3, 1},{62,61},{ 9,55},{ 6,59},{29,62}, + {45,29},{51,27},{23,23},{39,19},{27,30},{46,28},{53, 9},{30, 6}, + {43,60},{37,21},{60,44},{16,26},{21,51},{28,35},{19,18},{35,20}, + {42,24},{26,53},{44,17},{32,37},{58,39},{24,45},{20,58},{17,43}, + {18,42},{48,46},{22,36},{33,33},{25,34},{49,40},{40,52},{36,49}, + {34,50},{50,56},{52,25},{54,22},{41,54},{56,57},{38,41},{57,38} +}; + +/***************************************************************************** + * + * motion vector prediction + * + ****************************************************************************/ + +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 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); +} + +/***************************************************************************** + * + * 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 dec_2dvlc_t *r, int esc_golomb_order, + int qp, uint8_t *dst, int stride) { + int i, level_code, esc_code, level, run, mask; + DCTELEM level_buf[64]; + uint8_t run_buf[64]; + 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; + } + if(dequant(h,level_buf, run_buf, block, ff_cavs_dequant_mul[qp], + ff_cavs_dequant_shift[qp], i)) + return -1; + 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,ff_cavs_chroma_dec,0, + ff_cavs_chroma_qp[h->qp],h->cu,h->c_stride); + if(h->cbp & (1<<5)) + decode_residual_block(h,&h->s.gb,ff_cavs_chroma_dec,0, + ff_cavs_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<<block)) + decode_residual_block(h,&h->s.gb,ff_cavs_inter_dec,0,h->qp, + h->cy + h->luma_scan[block], h->l_stride); + decode_residual_chroma(h); + + return 0; +} + +/***************************************************************************** + * + * macroblock level + * + ****************************************************************************/ + +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; + + ff_cavs_init_mb(h); + + /* get intra prediction modes from stream */ + for(block=0;block<4;block++) { + int nA,nB,predpred; + int pos = ff_cavs_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; + } + ff_cavs_modify_mb_i(h, &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]; + ff_cavs_load_intra_pred_luma(h, top, &left, block); + h->intra_pred_l[h->pred_mode_Y[ff_cavs_scan3x3[block]]] + (d, top, left, h->l_stride); + if(h->cbp & (1<<block)) + decode_residual_block(h,gb,ff_cavs_intra_dec,1,h->qp,d,h->l_stride); + } + + /* chroma intra prediction */ + ff_cavs_load_intra_pred_chroma(h); + 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); + ff_cavs_filter(h,I_8X8); + set_mv_intra(h); + return 0; +} + +static void decode_mb_p(AVSContext *h, enum mb_t mb_type) { + GetBitContext *gb = &h->s.gb; + int ref[4]; + + ff_cavs_init_mb(h); + switch(mb_type) { + case P_SKIP: + ff_cavs_mv(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); + ff_cavs_mv(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); + ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, ref[0]); + ff_cavs_mv(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); + ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, ref[0]); + ff_cavs_mv(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); + ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_MEDIAN, BLK_8X8, ref[0]); + ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_MEDIAN, BLK_8X8, ref[1]); + ff_cavs_mv(h, MV_FWD_X2, MV_FWD_X1, MV_PRED_MEDIAN, BLK_8X8, ref[2]); + ff_cavs_mv(h, MV_FWD_X3, MV_FWD_X0, MV_PRED_MEDIAN, BLK_8X8, ref[3]); + } + ff_cavs_inter(h, mb_type); + set_intra_mode_default(h); + store_mvs(h); + if(mb_type != P_SKIP) + decode_residual_inter(h); + ff_cavs_filter(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; + + ff_cavs_init_mb(h); + + /* reset all MVs */ + h->mv[MV_FWD_X0] = ff_cavs_dir_mv; + set_mvs(&h->mv[MV_FWD_X0], BLK_16X16); + h->mv[MV_BWD_X0] = ff_cavs_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 */ + ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_BSKIP, BLK_16X16, 1); + ff_cavs_mv(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: + ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1); + break; + case B_SYM_16X16: + ff_cavs_mv(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: + ff_cavs_mv(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 */ + ff_cavs_mv(h, mv_scan[block], mv_scan[block]-3, + MV_PRED_BSKIP, BLK_8X8, 1); + ff_cavs_mv(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: + ff_cavs_mv(h, mv_scan[block], mv_scan[block]-3, + MV_PRED_MEDIAN, BLK_8X8, 1); + break; + case B_SUB_SYM: + ff_cavs_mv(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) + ff_cavs_mv(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 = ff_cavs_partition_flags[mb_type]; + if(mb_type & 1) { /* 16x8 macroblock types */ + if(flags & FWD0) + ff_cavs_mv(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) + ff_cavs_mv(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) + ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_TOP, BLK_16X8, 0); + if(flags & BWD1) + ff_cavs_mv(h, MV_BWD_X2, MV_BWD_A1, MV_PRED_LEFT, BLK_16X8, 0); + } else { /* 8x16 macroblock types */ + if(flags & FWD0) + ff_cavs_mv(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) + ff_cavs_mv(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) + ff_cavs_mv(h, MV_BWD_X0, MV_BWD_B3, MV_PRED_LEFT, BLK_8X16, 0); + if(flags & BWD1) + ff_cavs_mv(h,MV_BWD_X1,MV_BWD_C2,MV_PRED_TOPRIGHT,BLK_8X16,0); + } + } + ff_cavs_inter(h, mb_type); + set_intra_mode_default(h); + if(mb_type != B_SKIP) + decode_residual_inter(h); + ff_cavs_filter(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) { + skip_bits_long(gb,24+align); + h->stc = get_bits(gb,8); + decode_slice_header(h,gb); + } +} + +/***************************************************************************** + * + * frame level + * + ****************************************************************************/ + +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); + } + skip_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)) + skip_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); + ff_cavs_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)) ) + skip_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(ff_cavs_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(!ff_cavs_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(ff_cavs_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(!ff_cavs_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(ff_cavs_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 + * + ****************************************************************************/ + +static int decode_seq_header(AVSContext *h) { + MpegEncContext *s = &h->s; + 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) + ff_cavs_init_top_lines(h); + return 0; +} + +static void 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, + const 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 = -1; + + 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 CAVS_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; + } + } +} + +AVCodec cavs_decoder = { + "cavs", + CODEC_TYPE_VIDEO, + CODEC_ID_CAVS, + sizeof(AVSContext), + ff_cavs_init, + NULL, + ff_cavs_end, + cavs_decode_frame, + CODEC_CAP_DR1 | CODEC_CAP_DELAY, + .flush= cavs_flush, +}; diff --git a/contrib/ffmpeg/libavcodec/cavsdsp.c b/contrib/ffmpeg/libavcodec/cavsdsp.c index 55ecaae0a..fd744cc80 100644 --- a/contrib/ffmpeg/libavcodec/cavsdsp.c +++ b/contrib/ffmpeg/libavcodec/cavsdsp.c @@ -19,7 +19,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdio.h> diff --git a/contrib/ffmpeg/libavcodec/cinepak.c b/contrib/ffmpeg/libavcodec/cinepak.c index db0519b5d..66ecd3fc5 100644 --- a/contrib/ffmpeg/libavcodec/cinepak.c +++ b/contrib/ffmpeg/libavcodec/cinepak.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -35,7 +34,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -61,7 +59,7 @@ typedef struct CinepakContext { DSPContext dsp; AVFrame frame; - unsigned char *data; + const unsigned char *data; int size; int width, height; @@ -74,9 +72,9 @@ typedef struct CinepakContext { } CinepakContext; static void cinepak_decode_codebook (cvid_codebook_t *codebook, - int chunk_id, int size, uint8_t *data) + int chunk_id, int size, const uint8_t *data) { - uint8_t *eod = (data + size); + const uint8_t *eod = (data + size); uint32_t flag, mask; int i, n; @@ -123,9 +121,9 @@ static void cinepak_decode_codebook (cvid_codebook_t *codebook, } static int cinepak_decode_vectors (CinepakContext *s, cvid_strip_t *strip, - int chunk_id, int size, uint8_t *data) + int chunk_id, int size, const uint8_t *data) { - uint8_t *eod = (data + size); + const uint8_t *eod = (data + size); uint32_t flag, mask; cvid_codebook_t *codebook; unsigned int x, y; @@ -266,9 +264,9 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip_t *strip, } static int cinepak_decode_strip (CinepakContext *s, - cvid_strip_t *strip, uint8_t *data, int size) + cvid_strip_t *strip, const uint8_t *data, int size) { - uint8_t *eod = (data + size); + const uint8_t *eod = (data + size); int chunk_id, chunk_size; /* coordinate sanity checks */ @@ -319,7 +317,7 @@ static int cinepak_decode_strip (CinepakContext *s, static int cinepak_decode (CinepakContext *s) { - uint8_t *eod = (s->data + s->size); + const uint8_t *eod = (s->data + s->size); int i, result, strip_size, frame_flags, num_strips; int y0 = 0; int encoded_buf_size; @@ -391,7 +389,7 @@ static int cinepak_decode (CinepakContext *s) static int cinepak_decode_init(AVCodecContext *avctx) { - CinepakContext *s = (CinepakContext *)avctx->priv_data; + CinepakContext *s = avctx->priv_data; s->avctx = avctx; s->width = (avctx->width + 3) & ~3; @@ -407,7 +405,6 @@ static int cinepak_decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_PAL8; } - avctx->has_b_frames = 0; dsputil_init(&s->dsp, avctx); s->frame.data[0] = NULL; @@ -417,9 +414,9 @@ static int cinepak_decode_init(AVCodecContext *avctx) static int cinepak_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - CinepakContext *s = (CinepakContext *)avctx->priv_data; + CinepakContext *s = avctx->priv_data; s->data = buf; s->size = buf_size; @@ -452,7 +449,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx, static int cinepak_decode_end(AVCodecContext *avctx) { - CinepakContext *s = (CinepakContext *)avctx->priv_data; + CinepakContext *s = avctx->priv_data; if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); diff --git a/contrib/ffmpeg/libavcodec/cljr.c b/contrib/ffmpeg/libavcodec/cljr.c index 44810f5cf..6b76411ac 100644 --- a/contrib/ffmpeg/libavcodec/cljr.c +++ b/contrib/ffmpeg/libavcodec/cljr.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -38,7 +37,7 @@ typedef struct CLJRContext{ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { CLJRContext * const a = avctx->priv_data; AVFrame *picture = data; diff --git a/contrib/ffmpeg/libavcodec/colorspace.h b/contrib/ffmpeg/libavcodec/colorspace.h new file mode 100644 index 000000000..9d89d6daa --- /dev/null +++ b/contrib/ffmpeg/libavcodec/colorspace.h @@ -0,0 +1,111 @@ +/* + * Colorspace conversion defines + * 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 colorspace.h + * Various defines for YUV<->RGB conversion + */ + +#ifndef FFMPEG_COLORSPACE_H +#define FFMPEG_COLORSPACE_H + +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) + +#define YUV_TO_RGB1_CCIR(cb1, cr1)\ +{\ + cb = (cb1) - 128;\ + cr = (cr1) - 128;\ + r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\ + g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \ + ONE_HALF;\ + b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\ +} + +#define YUV_TO_RGB2_CCIR(r, g, b, y1)\ +{\ + y = ((y1) - 16) * FIX(255.0/219.0);\ + r = cm[(y + r_add) >> 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) + +#endif /* FFMPEG_COLORSPACE_H */ diff --git a/contrib/ffmpeg/libavcodec/cook.c b/contrib/ffmpeg/libavcodec/cook.c index 32b1081cc..8fa14e31c 100644 --- a/contrib/ffmpeg/libavcodec/cook.c +++ b/contrib/ffmpeg/libavcodec/cook.c @@ -18,12 +18,11 @@ * 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 cook.c - * Cook compatible decoder. + * Cook compatible decoder. Bastardization of the G.722.1 standard. * This decoder handles RealNetworks, RealAudio G2 data. * Cook is identified by the codec name cook in RM files. * @@ -50,7 +49,6 @@ #include "avcodec.h" #include "bitstream.h" #include "dsputil.h" -#include "common.h" #include "bytestream.h" #include "random.h" @@ -70,7 +68,29 @@ typedef struct { int *previous; } cook_gains; -typedef struct { +typedef struct cook { + /* + * The following 5 functions provide the lowlevel arithmetic on + * the internal audio buffers. + */ + void (* scalar_dequant)(struct cook *q, int index, int quant_index, + int* subband_coef_index, int* subband_coef_sign, + float* mlt_p); + + void (* decouple) (struct cook *q, + int subband, + float f1, float f2, + float *decode_buffer, + float *mlt_buffer1, float *mlt_buffer2); + + void (* imlt_window) (struct cook *q, float *buffer1, + cook_gains *gains_ptr, float *previous_buffer); + + void (* interpolate) (struct cook *q, float* buffer, + int gain_index, int gain_index_next); + + void (* saturate_output) (struct cook *q, int chan, int16_t *out); + GetBitContext gb; /* stream data */ int nb_channels; @@ -123,6 +143,9 @@ typedef struct { float mono_previous_buffer2[1024]; float decode_buffer_1[1024]; float decode_buffer_2[1024]; + float decode_buffer_0[1060]; /* static allocation for joint decode */ + + const float *cplscales[5]; } COOKContext; /* debug functions */ @@ -195,19 +218,19 @@ static int init_cook_vlc_tables(COOKContext *q) { result = 0; for (i=0 ; i<13 ; i++) { - result &= init_vlc (&q->envelope_quant_index[i], 9, 24, + result |= init_vlc (&q->envelope_quant_index[i], 9, 24, envelope_quant_index_huffbits[i], 1, 1, envelope_quant_index_huffcodes[i], 2, 2, 0); } av_log(NULL,AV_LOG_DEBUG,"sqvh VLC init\n"); for (i=0 ; i<7 ; i++) { - result &= init_vlc (&q->sqvh[i], vhvlcsize_tab[i], vhsize_tab[i], + result |= init_vlc (&q->sqvh[i], vhvlcsize_tab[i], vhsize_tab[i], cvh_huffbits[i], 1, 1, cvh_huffcodes[i], 2, 2, 0); } if (q->nb_channels==2 && q->joint_stereo==1){ - result &= init_vlc (&q->ccpl, 6, (1<<q->js_vlc_bits)-1, + result |= init_vlc (&q->ccpl, 6, (1<<q->js_vlc_bits)-1, ccpl_huffbits[q->js_vlc_bits-2], 1, 1, ccpl_huffcodes[q->js_vlc_bits-2], 2, 2, 0); av_log(NULL,AV_LOG_DEBUG,"Joint-stereo VLC used.\n"); @@ -241,6 +264,18 @@ static int init_cook_mlt(COOKContext *q) { return 0; } +static const float *maybe_reformat_buffer32 (COOKContext *q, const float *ptr, int n) +{ + if (1) + return ptr; +} + +static void init_cplscales_table (COOKContext *q) { + int i; + for (i=0;i<5;i++) + q->cplscales[i] = maybe_reformat_buffer32 (q, cplscales[i], (1<<(i+2))-1); +} + /*************** init functions end ***********/ /** @@ -248,7 +283,7 @@ static int init_cook_mlt(COOKContext *q) { * Why? No idea, some checksum/error detection method maybe. * * Out buffer size: extra bytes are needed to cope with - * padding/missalignment. + * padding/misalignment. * Subpackets passed to the decoder can contain two, consecutive * half-subpackets, of identical but arbitrary size. * 1234 1234 1234 1234 extraA extraB @@ -266,10 +301,10 @@ static int init_cook_mlt(COOKContext *q) { #define DECODE_BYTES_PAD1(bytes) (3 - ((bytes)+3) % 4) #define DECODE_BYTES_PAD2(bytes) ((bytes) % 4 + DECODE_BYTES_PAD1(2 * (bytes))) -static inline int decode_bytes(uint8_t* inbuffer, uint8_t* out, int bytes){ +static inline int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ int i, off; uint32_t c; - uint32_t* buf; + const uint32_t* buf; uint32_t* obuf = (uint32_t*) out; /* FIXME: 64 bit platforms would be able to do 64 bits at a time. * I'm too lazy though, should be something like @@ -278,7 +313,7 @@ static inline int decode_bytes(uint8_t* inbuffer, uint8_t* out, int bytes){ * Buffer alignment needs to be checked. */ off = (int)((long)inbuffer & 3); - buf = (uint32_t*) (inbuffer - off); + buf = (const uint32_t*) (inbuffer - off); c = be2me_32((0x37c511f2 >> (off*8)) | (0x37c511f2 << (32-(off*8)))); bytes += 3 + off; for (i = 0; i < bytes/4; i++) @@ -353,9 +388,7 @@ static void decode_gain_info(GetBitContext *gb, int *gaininfo) static void decode_envelope(COOKContext *q, int* quant_index_table) { int i,j, vlc_index; - int bitbias; - bitbias = get_bits_count(&q->gb); quant_index_table[0]= get_bits(&q->gb,6) - 6; //This is used later in categorize for (i=1 ; i < q->total_subbands ; i++){ @@ -385,15 +418,13 @@ static void decode_envelope(COOKContext *q, int* quant_index_table) { static void categorize(COOKContext *q, int* quant_index_table, int* category, int* category_index){ - int exp_idx, bias, tmpbias, bits_left, num_bits, index, v, i, j; + int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j; int exp_index2[102]; int exp_index1[102]; - int tmp_categorize_array1[128]; - int tmp_categorize_array1_idx=0; - int tmp_categorize_array2[128]; - int tmp_categorize_array2_idx=0; - int category_index_size=0; + int tmp_categorize_array[128*2]; + int tmp_categorize_array1_idx=q->numvector_size; + int tmp_categorize_array2_idx=q->numvector_size; bits_left = q->bits_per_subpacket - get_bits_count(&q->gb); @@ -405,8 +436,7 @@ static void categorize(COOKContext *q, int* quant_index_table, memset(&exp_index1,0,102*sizeof(int)); memset(&exp_index2,0,102*sizeof(int)); - memset(&tmp_categorize_array1,0,128*sizeof(int)); - memset(&tmp_categorize_array2,0,128*sizeof(int)); + memset(&tmp_categorize_array,0,128*2*sizeof(int)); bias=-32; @@ -415,12 +445,7 @@ static void categorize(COOKContext *q, int* quant_index_table, num_bits = 0; index = 0; for (j=q->total_subbands ; j>0 ; j--){ - exp_idx = (i - quant_index_table[index] + bias) / 2; - if (exp_idx<0){ - exp_idx=0; - } else if(exp_idx >7) { - exp_idx=7; - } + exp_idx = av_clip((i - quant_index_table[index] + bias) / 2, 0, 7); index++; num_bits+=expbits_tab[exp_idx]; } @@ -432,25 +457,20 @@ static void categorize(COOKContext *q, int* quant_index_table, /* Calculate total number of bits. */ num_bits=0; for (i=0 ; i<q->total_subbands ; i++) { - exp_idx = (bias - quant_index_table[i]) / 2; - if (exp_idx<0) { - exp_idx=0; - } else if(exp_idx >7) { - exp_idx=7; - } + exp_idx = av_clip((bias - quant_index_table[i]) / 2, 0, 7); num_bits += expbits_tab[exp_idx]; exp_index1[i] = exp_idx; exp_index2[i] = exp_idx; } - tmpbias = bias = num_bits; + tmpbias1 = tmpbias2 = num_bits; for (j = 1 ; j < q->numvector_size ; j++) { - if (tmpbias + bias > 2*bits_left) { /* ---> */ + if (tmpbias1 + tmpbias2 > 2*bits_left) { /* ---> */ int max = -999999; index=-1; for (i=0 ; i<q->total_subbands ; i++){ if (exp_index1[i] < 7) { - v = (-2*exp_index1[i]) - quant_index_table[i] - 32; + v = (-2*exp_index1[i]) - quant_index_table[i] + bias; if ( v >= max) { max = v; index = i; @@ -458,16 +478,16 @@ static void categorize(COOKContext *q, int* quant_index_table, } } if(index==-1)break; - tmp_categorize_array1[tmp_categorize_array1_idx++] = index; - tmpbias -= expbits_tab[exp_index1[index]] - - expbits_tab[exp_index1[index]+1]; + tmp_categorize_array[tmp_categorize_array1_idx++] = index; + tmpbias1 -= expbits_tab[exp_index1[index]] - + expbits_tab[exp_index1[index]+1]; ++exp_index1[index]; } else { /* <--- */ int min = 999999; index=-1; for (i=0 ; i<q->total_subbands ; i++){ if(exp_index2[i] > 0){ - v = (-2*exp_index2[i])-quant_index_table[i]; + v = (-2*exp_index2[i])-quant_index_table[i]+bias; if ( v < min) { min = v; index = i; @@ -475,9 +495,9 @@ static void categorize(COOKContext *q, int* quant_index_table, } } if(index == -1)break; - tmp_categorize_array2[tmp_categorize_array2_idx++] = index; - tmpbias -= expbits_tab[exp_index2[index]] - - expbits_tab[exp_index2[index]-1]; + tmp_categorize_array[--tmp_categorize_array2_idx] = index; + tmpbias2 -= expbits_tab[exp_index2[index]] - + expbits_tab[exp_index2[index]-1]; --exp_index2[index]; } } @@ -485,17 +505,8 @@ static void categorize(COOKContext *q, int* quant_index_table, for(i=0 ; i<q->total_subbands ; i++) category[i] = exp_index2[i]; - /* Concatenate the two arrays. */ - for(i=tmp_categorize_array2_idx-1 ; i >= 0; i--) - category_index[category_index_size++] = tmp_categorize_array2[i]; - - for(i=0;i<tmp_categorize_array1_idx;i++) - category_index[category_index_size++ ] = tmp_categorize_array1[i]; - - /* FIXME: mc_sich_ra8_20.rm triggers this, not sure with what we - should fill the remaining bytes. */ - for(i=category_index_size;i<q->numvector_size;i++) - category_index[i]=0; + for(i=0 ; i<q->numvector_size-1 ; i++) + category_index[i] = tmp_categorize_array[tmp_categorize_array2_idx++]; } @@ -508,7 +519,7 @@ static void categorize(COOKContext *q, int* quant_index_table, * @param category_index pointer to the category_index array */ -static void inline expand_category(COOKContext *q, int* category, +static inline void expand_category(COOKContext *q, int* category, int* category_index){ int i; for(i=0 ; i<q->num_vectors ; i++){ @@ -527,7 +538,7 @@ static void inline expand_category(COOKContext *q, int* category, * @param mlt_p pointer into the mlt buffer */ -static void scalar_dequant(COOKContext *q, int index, int quant_index, +static void scalar_dequant_float(COOKContext *q, int index, int quant_index, int* subband_coef_index, int* subband_coef_sign, float* mlt_p){ int i; @@ -558,15 +569,11 @@ static int unpack_SQVH(COOKContext *q, int category, int* subband_coef_index, int* subband_coef_sign) { int i,j; int vlc, vd ,tmp, result; - int ub; - int cb; vd = vd_tab[category]; result = 0; for(i=0 ; i<vpr_tab[category] ; i++){ - ub = get_bits_count(&q->gb); vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3); - cb = get_bits_count(&q->gb); if (q->bits_per_subpacket < get_bits_count(&q->gb)){ vlc = 0; result = 1; @@ -626,9 +633,9 @@ static void decode_vectors(COOKContext* q, int* category, memset(subband_coef_index, 0, sizeof(subband_coef_index)); memset(subband_coef_sign, 0, sizeof(subband_coef_sign)); } - scalar_dequant(q, index, quant_index_table[band], - subband_coef_index, subband_coef_sign, - &mlt_buffer[band * 20]); + q->scalar_dequant(q, index, quant_index_table[band], + subband_coef_index, subband_coef_sign, + &mlt_buffer[band * SUBBAND_SIZE]); } if(q->total_subbands*SUBBAND_SIZE >= q->samples_per_channel){ @@ -641,8 +648,7 @@ static void decode_vectors(COOKContext* q, int* category, * function for decoding mono data * * @param q pointer to the COOKContext - * @param mlt_buffer1 pointer to left channel mlt coefficients - * @param mlt_buffer2 pointer to right channel mlt coefficients + * @param mlt_buffer pointer to mlt coefficients */ static void mono_decode(COOKContext *q, float* mlt_buffer) { @@ -671,7 +677,7 @@ static void mono_decode(COOKContext *q, float* mlt_buffer) { * @param gain_index_next index for the next block multiplier */ -static void interpolate(COOKContext *q, float* buffer, +static void interpolate_float(COOKContext *q, float* buffer, int gain_index, int gain_index_next){ int i; float fc1, fc2; @@ -692,6 +698,32 @@ static void interpolate(COOKContext *q, float* buffer, } } +/** + * Apply transform window, overlap buffers. + * + * @param q pointer to the COOKContext + * @param inbuffer pointer to the mltcoefficients + * @param gains_ptr current and previous gains + * @param previous_buffer pointer to the previous buffer to be used for overlapping + */ + +static void imlt_window_float (COOKContext *q, float *buffer1, + cook_gains *gains_ptr, float *previous_buffer) +{ + const float fc = q->pow2tab[gains_ptr->previous[0] + 63]; + int i; + /* The weird thing here, is that the two halves of the time domain + * buffer are swapped. Also, the newest data, that we save away for + * next frame, has the wrong sign. Hence the subtraction below. + * Almost sounds like a complex conjugate/reverse data/FFT effect. + */ + + /* Apply window and overlap */ + for(i = 0; i < q->samples_per_channel; i++){ + buffer1[i] = buffer1[i] * fc * q->mlt_window[i] - + previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i]; + } +} /** * The modulated lapped transform, this takes transform coefficients @@ -708,7 +740,6 @@ static void interpolate(COOKContext *q, float* buffer, static void imlt_gain(COOKContext *q, float *inbuffer, cook_gains *gains_ptr, float* previous_buffer) { - const float fc = q->pow2tab[gains_ptr->previous[0] + 63]; float *buffer0 = q->mono_mdct_output; float *buffer1 = q->mono_mdct_output + q->samples_per_channel; int i; @@ -717,23 +748,13 @@ static void imlt_gain(COOKContext *q, float *inbuffer, q->mdct_ctx.fft.imdct_calc(&q->mdct_ctx, q->mono_mdct_output, inbuffer, q->mdct_tmp); - /* The weird thing here, is that the two halves of the time domain - * buffer are swapped. Also, the newest data, that we save away for - * next frame, has the wrong sign. Hence the subtraction below. - * Almost sounds like a complex conjugate/reverse data/FFT effect. - */ - - /* Apply window and overlap */ - for(i = 0; i < q->samples_per_channel; i++){ - buffer1[i] = buffer1[i] * fc * q->mlt_window[i] - - previous_buffer[i] * q->mlt_window[q->samples_per_channel - 1 - i]; - } + q->imlt_window (q, buffer1, gains_ptr, previous_buffer); /* Apply gain profile */ for (i = 0; i < 8; i++) { if (gains_ptr->now[i] || gains_ptr->now[i + 1]) - interpolate(q, &buffer1[q->gain_size_factor * i], - gains_ptr->now[i], gains_ptr->now[i + 1]); + q->interpolate(q, &buffer1[q->gain_size_factor * i], + gains_ptr->now[i], gains_ptr->now[i + 1]); } /* Save away the current to be previous block. */ @@ -771,6 +792,30 @@ static void decouple_info(COOKContext *q, int* decouple_tab){ return; } +/* + * function decouples a pair of signals from a single signal via multiplication. + * + * @param q pointer to the COOKContext + * @param subband index of the current subband + * @param f1 multiplier for channel 1 extraction + * @param f2 multiplier for channel 2 extraction + * @param decode_buffer input buffer + * @param mlt_buffer1 pointer to left channel mlt coefficients + * @param mlt_buffer2 pointer to right channel mlt coefficients + */ +static void decouple_float (COOKContext *q, + int subband, + float f1, float f2, + float *decode_buffer, + float *mlt_buffer1, float *mlt_buffer2) +{ + int j, tmp_idx; + for (j=0 ; j<SUBBAND_SIZE ; j++) { + tmp_idx = ((q->js_subband_start + subband)*SUBBAND_SIZE)+j; + mlt_buffer1[SUBBAND_SIZE*subband + j] = f1 * decode_buffer[tmp_idx]; + mlt_buffer2[SUBBAND_SIZE*subband + j] = f2 * decode_buffer[tmp_idx]; + } +} /** * function for decoding joint stereo data @@ -784,10 +829,10 @@ static void joint_decode(COOKContext *q, float* mlt_buffer1, float* mlt_buffer2) { int i,j; int decouple_tab[SUBBAND_SIZE]; - float decode_buffer[1060]; - int idx, cpl_tmp,tmp_idx; + float *decode_buffer = q->decode_buffer_0; + int idx, cpl_tmp; float f1,f2; - float* cplscale; + const float* cplscale; memset(decouple_tab, 0, sizeof(decouple_tab)); memset(decode_buffer, 0, sizeof(decode_buffer)); @@ -812,14 +857,10 @@ static void joint_decode(COOKContext *q, float* mlt_buffer1, for (i=q->js_subband_start ; i<q->subbands ; i++) { cpl_tmp = cplband[i]; idx -=decouple_tab[cpl_tmp]; - cplscale = (float*)cplscales[q->js_vlc_bits-2]; //choose decoupler table + cplscale = q->cplscales[q->js_vlc_bits-2]; //choose decoupler table f1 = cplscale[decouple_tab[cpl_tmp]]; f2 = cplscale[idx-1]; - for (j=0 ; j<SUBBAND_SIZE ; j++) { - tmp_idx = ((q->js_subband_start + i)*20)+j; - mlt_buffer1[20*i + j] = f1 * decode_buffer[tmp_idx]; - mlt_buffer2[20*i + j] = f2 * decode_buffer[tmp_idx]; - } + q->decouple (q, i, f1, f2, decode_buffer, mlt_buffer1, mlt_buffer2); idx = (1 << q->js_vlc_bits) - 1; } } @@ -834,7 +875,7 @@ static void joint_decode(COOKContext *q, float* mlt_buffer1, */ static inline void -decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, +decode_bytes_and_gain(COOKContext *q, const uint8_t *inbuffer, cook_gains *gains_ptr) { int offset; @@ -849,6 +890,26 @@ decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, FFSWAP(int *, gains_ptr->now, gains_ptr->previous); } + /** + * Saturate the output signal to signed 16bit integers. + * + * @param q pointer to the COOKContext + * @param chan channel to saturate + * @param out pointer to the output vector + */ +static void +saturate_output_float (COOKContext *q, int chan, int16_t *out) +{ + int j; + float *output = q->mono_mdct_output + q->samples_per_channel; + /* Clip and convert floats to 16 bits. + */ + for (j = 0; j < q->samples_per_channel; j++) { + out[chan + q->nb_channels * j] = + av_clip_int16(lrintf(output[j])); + } +} + /** * Final part of subpacket decoding: * Apply modulated lapped transform, gain compensation, @@ -867,17 +928,8 @@ mlt_compensate_output(COOKContext *q, float *decode_buffer, cook_gains *gains, float *previous_buffer, int16_t *out, int chan) { - float *output = q->mono_mdct_output + q->samples_per_channel; - int j; - imlt_gain(q, decode_buffer, gains, previous_buffer); - - /* Clip and convert floats to 16 bits. - */ - for (j = 0; j < q->samples_per_channel; j++) { - out[chan + q->nb_channels * j] = - av_clip(lrintf(output[j]), -32768, 32767); - } + q->saturate_output (q, chan, out); } @@ -892,7 +944,7 @@ mlt_compensate_output(COOKContext *q, float *decode_buffer, */ -static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, +static int decode_subpacket(COOKContext *q, const uint8_t *inbuffer, int sub_packet_size, int16_t *outbuffer) { /* packet dump */ // for (i=0 ; i<sub_packet_size ; i++) { @@ -937,7 +989,7 @@ static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, static int cook_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) { + const uint8_t *buf, int buf_size) { COOKContext *q = avctx->priv_data; if (buf_size < avctx->block_align) @@ -986,7 +1038,7 @@ static void dump_cook_context(COOKContext *q) static int cook_decode_init(AVCodecContext *avctx) { COOKContext *q = avctx->priv_data; - uint8_t *edata_ptr = avctx->extradata; + const uint8_t *edata_ptr = avctx->extradata; /* Take care of the codec specific extradata. */ if (avctx->extradata_size <= 0) { @@ -1075,6 +1127,7 @@ static int cook_decode_init(AVCodecContext *avctx) init_rootpow2table(q); init_pow2table(q); init_gain_table(q); + init_cplscales_table(q); if (init_cook_vlc_tables(q) != 0) return -1; @@ -1109,6 +1162,15 @@ static int cook_decode_init(AVCodecContext *avctx) if ( init_cook_mlt(q) != 0 ) return -1; + /* Initialize COOK signal arithmetic handling */ + if (1) { + q->scalar_dequant = scalar_dequant_float; + q->decouple = decouple_float; + q->imlt_window = imlt_window_float; + q->interpolate = interpolate_float; + q->saturate_output = saturate_output_float; + } + /* Try to catch some obviously faulty streams, othervise it might be exploitable */ if (q->total_subbands > 53) { av_log(avctx,AV_LOG_ERROR,"total_subbands > 53, report sample!\n"); diff --git a/contrib/ffmpeg/libavcodec/cookdata.h b/contrib/ffmpeg/libavcodec/cookdata.h index 395c9a7dd..38beef41c 100644 --- a/contrib/ffmpeg/libavcodec/cookdata.h +++ b/contrib/ffmpeg/libavcodec/cookdata.h @@ -18,7 +18,6 @@ * 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 - * */ /** @@ -26,6 +25,11 @@ * Cook AKA RealAudio G2 compatible decoderdata */ +#ifndef FFMPEG_COOKDATA_H +#define FFMPEG_COOKDATA_H + +#include <stdint.h> + /* various data tables */ static const int expbits_tab[8] = { @@ -557,3 +561,5 @@ static const float cplscale6[63] = { static const float* cplscales[5] = { cplscale2, cplscale3, cplscale4, cplscale5, cplscale6, }; + +#endif /* FFMPEG_COOKDATA_H */ diff --git a/contrib/ffmpeg/libavcodec/cscd.c b/contrib/ffmpeg/libavcodec/cscd.c index 2e7d05c40..26e662d54 100644 --- a/contrib/ffmpeg/libavcodec/cscd.c +++ b/contrib/ffmpeg/libavcodec/cscd.c @@ -21,7 +21,6 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" #ifdef CONFIG_ZLIB @@ -36,7 +35,7 @@ typedef struct { unsigned char* decomp_buf; } CamStudioContext; -static void copy_frame_default(AVFrame *f, uint8_t *src, +static void copy_frame_default(AVFrame *f, const uint8_t *src, int linelen, int height) { int i; uint8_t *dst = f->data[0]; @@ -48,7 +47,7 @@ static void copy_frame_default(AVFrame *f, uint8_t *src, } } -static void add_frame_default(AVFrame *f, uint8_t *src, +static void add_frame_default(AVFrame *f, const uint8_t *src, int linelen, int height) { int i, j; uint8_t *dst = f->data[0]; @@ -66,7 +65,7 @@ static void add_frame_default(AVFrame *f, uint8_t *src, #define add_frame_16 add_frame_default #define add_frame_32 add_frame_default #else -static void copy_frame_16(AVFrame *f, uint8_t *src, +static void copy_frame_16(AVFrame *f, const uint8_t *src, int linelen, int height) { int i, j; uint8_t *dst = f->data[0]; @@ -82,7 +81,7 @@ static void copy_frame_16(AVFrame *f, uint8_t *src, } } -static void copy_frame_32(AVFrame *f, uint8_t *src, +static void copy_frame_32(AVFrame *f, const uint8_t *src, int linelen, int height) { int i, j; uint8_t *dst = f->data[0]; @@ -100,7 +99,7 @@ static void copy_frame_32(AVFrame *f, uint8_t *src, } } -static void add_frame_16(AVFrame *f, uint8_t *src, +static void add_frame_16(AVFrame *f, const uint8_t *src, int linelen, int height) { int i, j; uint8_t *dst = f->data[0]; @@ -116,7 +115,7 @@ static void add_frame_16(AVFrame *f, uint8_t *src, } } -static void add_frame_32(AVFrame *f, uint8_t *src, +static void add_frame_32(AVFrame *f, const uint8_t *src, int linelen, int height) { int i, j; uint8_t *dst = f->data[0]; @@ -136,8 +135,8 @@ static void add_frame_32(AVFrame *f, uint8_t *src, #endif static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) { - CamStudioContext *c = (CamStudioContext *)avctx->priv_data; + const uint8_t *buf, int buf_size) { + CamStudioContext *c = avctx->priv_data; AVFrame *picture = data; if (buf_size < 2) { @@ -214,11 +213,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, } static int decode_init(AVCodecContext *avctx) { - CamStudioContext *c = (CamStudioContext *)avctx->priv_data; + CamStudioContext *c = avctx->priv_data; if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) { return 1; } - avctx->has_b_frames = 0; switch (avctx->bits_per_sample) { case 16: avctx->pix_fmt = PIX_FMT_RGB555; break; case 24: avctx->pix_fmt = PIX_FMT_BGR24; break; @@ -243,7 +241,7 @@ static int decode_init(AVCodecContext *avctx) { } static int decode_end(AVCodecContext *avctx) { - CamStudioContext *c = (CamStudioContext *)avctx->priv_data; + CamStudioContext *c = avctx->priv_data; av_freep(&c->decomp_buf); if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); diff --git a/contrib/ffmpeg/libavcodec/cyuv.c b/contrib/ffmpeg/libavcodec/cyuv.c index 101f2bd85..c36495ec6 100644 --- a/contrib/ffmpeg/libavcodec/cyuv.c +++ b/contrib/ffmpeg/libavcodec/cyuv.c @@ -1,4 +1,8 @@ /* + * 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 * * Copyright (C) 2003 the ffmpeg project * @@ -17,12 +21,6 @@ * 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 - * */ /** @@ -35,7 +33,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" @@ -58,14 +55,13 @@ static int cyuv_decode_init(AVCodecContext *avctx) 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) + const uint8_t *buf, int buf_size) { CyuvDecodeContext *s=avctx->priv_data; @@ -77,9 +73,9 @@ static int cyuv_decode_frame(AVCodecContext *avctx, 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; + const signed char *y_table = (const signed char*)buf + 0; + const signed char *u_table = (const signed char*)buf + 16; + const signed char *v_table = (const signed char*)buf + 32; unsigned char y_pred, u_pred, v_pred; int stream_ptr; diff --git a/contrib/ffmpeg/libavcodec/dca.c b/contrib/ffmpeg/libavcodec/dca.c index a57dcdc44..2a449a203 100644 --- a/contrib/ffmpeg/libavcodec/dca.c +++ b/contrib/ffmpeg/libavcodec/dca.c @@ -35,15 +35,7 @@ #include "bitstream.h" #include "dcadata.h" #include "dcahuff.h" -#include "parser.h" - -/** DCA syncwords, also used for bitstream type detection */ -//@{ -#define DCA_MARKER_RAW_BE 0x7FFE8001 -#define DCA_MARKER_RAW_LE 0xFE7F0180 -#define DCA_MARKER_14B_BE 0x1FFFE800 -#define DCA_MARKER_14B_LE 0xFF1F00E8 -//@} +#include "dca.h" //#define TRACE @@ -95,7 +87,7 @@ static BitAlloc dca_smpl_bitalloc[11]; ///< samples VLCs /** Pre-calculated cosine modulation coefs for the QMF */ static float cos_mod[544]; -static int av_always_inline get_bitalloc(GetBitContext *gb, BitAlloc *ba, int idx) +static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba, int idx) { return get_vlc2(gb, ba->vlc[idx].table, ba->vlc[idx].bits, ba->wrap) + ba->offset; } @@ -185,16 +177,16 @@ typedef struct { DSPContext dsp; } DCAContext; -static void dca_init_vlcs() +static void dca_init_vlcs(void) { - static int vlcs_inited = 0; + static int vlcs_initialized = 0; int i, j; - if (vlcs_inited) + if (vlcs_initialized) return; dca_bitalloc_index.offset = 1; - dca_bitalloc_index.wrap = 1; + dca_bitalloc_index.wrap = 2; for (i = 0; i < 5; i++) init_vlc(&dca_bitalloc_index.vlc[i], bitalloc_12_vlc_bits[i], 12, bitalloc_12_bits[i], 1, 1, @@ -222,7 +214,7 @@ static void dca_init_vlcs() bitalloc_bits[i][j], 1, 1, bitalloc_codes[i][j], 2, 2, 1); } - vlcs_inited = 1; + vlcs_initialized = 1; } static inline void get_array(GetBitContext *gb, int *dst, int len, int bits) @@ -285,7 +277,8 @@ static int dca_parse_frame_header(DCAContext * s) s->dialog_norm = get_bits(&s->gb, 4); /* FIXME: channels mixing levels */ - s->output = DCA_STEREO; + s->output = s->amode; + if(s->lfe) s->output |= DCA_LFE; #ifdef TRACE av_log(s->avctx, AV_LOG_DEBUG, "frame type: %i\n", s->frame_type); @@ -395,11 +388,11 @@ static int dca_parse_frame_header(DCAContext * s) } -static inline int get_scale(GetBitContext *gb, int level, int index, int value) +static inline int get_scale(GetBitContext *gb, int level, int value) { if (level < 5) { /* huffman encoded */ - value += get_bitalloc(gb, &dca_scalefactor, index); + value += get_bitalloc(gb, &dca_scalefactor, level); } else if(level < 8) value = get_bits(gb, level + 1); return value; @@ -436,7 +429,7 @@ static int dca_subframe_header(DCAContext * s) s->bitalloc[j][k] = get_bits(&s->gb, 4); else { s->bitalloc[j][k] = - get_bitalloc(&s->gb, &dca_bitalloc_index, j); + get_bitalloc(&s->gb, &dca_bitalloc_index, s->bitalloc_huffman[j]); } if (s->bitalloc[j][k] > 26) { @@ -460,28 +453,28 @@ static int dca_subframe_header(DCAContext * s) } for (j = 0; j < s->prim_channels; j++) { - uint32_t *scale_table; + const uint32_t *scale_table; int scale_sum; memset(s->scale_factor[j], 0, s->subband_activity[j] * sizeof(s->scale_factor[0][0][0]) * 2); if (s->scalefactor_huffman[j] == 6) - scale_table = (uint32_t *) scale_factor_quant7; + scale_table = scale_factor_quant7; else - scale_table = (uint32_t *) scale_factor_quant6; + scale_table = scale_factor_quant6; /* When huffman coded, only the difference is encoded */ scale_sum = 0; for (k = 0; k < s->subband_activity[j]; k++) { if (k >= s->vq_start_subband[j] || s->bitalloc[j][k] > 0) { - scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], j, scale_sum); + scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); s->scale_factor[j][k][0] = scale_table[scale_sum]; } if (k < s->vq_start_subband[j] && s->transition_mode[j][k]) { /* Get second scale factor */ - scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], j, scale_sum); + scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); s->scale_factor[j][k][1] = scale_table[scale_sum]; } } @@ -507,7 +500,7 @@ static int dca_subframe_header(DCAContext * s) * (is this valid as well for joint scales ???) */ for (k = s->subband_activity[j]; k < s->subband_activity[source_channel]; k++) { - scale = get_scale(&s->gb, s->joint_huff[j], j, 0); + scale = get_scale(&s->gb, s->joint_huff[j], 0); scale += 64; /* bias */ s->joint_scale_factor[j][k] = scale; /*joint_scale_table[scale]; */ } @@ -521,10 +514,18 @@ static int dca_subframe_header(DCAContext * s) } /* Stereo downmix coefficients */ - if (s->prim_channels > 2 && s->downmix) { - for (j = 0; j < s->prim_channels; j++) { - s->downmix_coef[j][0] = get_bits(&s->gb, 7); - s->downmix_coef[j][1] = get_bits(&s->gb, 7); + if (s->prim_channels > 2) { + if(s->downmix) { + for (j = 0; j < s->prim_channels; j++) { + s->downmix_coef[j][0] = get_bits(&s->gb, 7); + s->downmix_coef[j][1] = get_bits(&s->gb, 7); + } + } else { + int am = s->amode & DCA_CHANNEL_MASK; + for (j = 0; j < s->prim_channels; j++) { + s->downmix_coef[j][0] = dca_default_coeffs[am][j][0]; + s->downmix_coef[j][1] = dca_default_coeffs[am][j][1]; + } } } @@ -611,6 +612,7 @@ static int dca_subframe_header(DCAContext * s) } for (j = 0; j < s->prim_channels; j++) { if (s->joint_intensity[j] > 0) { + int source_channel = s->joint_intensity[j] - 1; av_log(s->avctx, AV_LOG_DEBUG, "Joint scale factor index:\n"); for (k = s->subband_activity[j]; k < s->subband_activity[source_channel]; k++) av_log(s->avctx, AV_LOG_DEBUG, " %i", s->joint_scale_factor[j][k]); @@ -629,6 +631,7 @@ static int dca_subframe_header(DCAContext * s) for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]); if(s->lfe){ + int lfe_samples = 2 * s->lfe * s->subsubframes; av_log(s->avctx, AV_LOG_DEBUG, "LFE samples:\n"); for (j = lfe_samples; j < lfe_samples * 2; j++) av_log(s->avctx, AV_LOG_DEBUG, " %f", s->lfe_data[j]); @@ -643,7 +646,7 @@ static void qmf_32_subbands(DCAContext * s, int chans, float samples_in[32][8], float *samples_out, float scale, float bias) { - float *prCoeff; + const float *prCoeff; int i, j, k; float praXin[33], *raXin = &praXin[1]; @@ -656,9 +659,9 @@ static void qmf_32_subbands(DCAContext * s, int chans, /* Select filter */ if (!s->multirate_inter) /* Non-perfect reconstruction */ - prCoeff = (float *) fir_32bands_nonperfect; + prCoeff = fir_32bands_nonperfect; else /* Perfect reconstruction */ - prCoeff = (float *) fir_32bands_perfect; + prCoeff = fir_32bands_perfect; /* Reconstructed channel sample index */ for (subindex = 0; subindex < 8; subindex++) { @@ -749,18 +752,18 @@ static void lfe_interpolation_fir(int decimation_select, } /* downmixing routines */ -#define MIX_REAR1(samples, si1) \ - samples[i] += samples[si1]; \ - samples[i+256] += samples[si1]; +#define MIX_REAR1(samples, si1, rs, coef) \ + samples[i] += samples[si1] * coef[rs][0]; \ + samples[i+256] += samples[si1] * coef[rs][1]; -#define MIX_REAR2(samples, si1, si2) \ - samples[i] += samples[si1]; \ - samples[i+256] += samples[si2]; +#define MIX_REAR2(samples, si1, si2, rs, coef) \ + samples[i] += samples[si1] * coef[rs][0] + samples[si2] * coef[rs+1][0]; \ + samples[i+256] += samples[si1] * coef[rs][1] + samples[si2] * coef[rs+1][1]; -#define MIX_FRONT3(samples) \ +#define MIX_FRONT3(samples, coef) \ t = samples[i]; \ - samples[i] += samples[i+256]; \ - samples[i+256] = samples[i+512] + t; + samples[i] = t * coef[0][0] + samples[i+256] * coef[1][0] + samples[i+512] * coef[2][0]; \ + samples[i+256] = t * coef[0][1] + samples[i+256] * coef[1][1] + samples[i+512] * coef[2][1]; #define DOWNMIX_TO_STEREO(op1, op2) \ for(i = 0; i < 256; i++){ \ @@ -768,10 +771,17 @@ static void lfe_interpolation_fir(int decimation_select, op2 \ } -static void dca_downmix(float *samples, int srcfmt) +static void dca_downmix(float *samples, int srcfmt, + int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]) { int i; float t; + float coef[DCA_PRIM_CHANNELS_MAX][2]; + + for(i=0; i<DCA_PRIM_CHANNELS_MAX; i++) { + coef[i][0] = dca_downmix_coeffs[downmix_coef[i][0]]; + coef[i][1] = dca_downmix_coeffs[downmix_coef[i][1]]; + } switch (srcfmt) { case DCA_MONO: @@ -784,21 +794,21 @@ static void dca_downmix(float *samples, int srcfmt) case DCA_STEREO: break; case DCA_3F: - DOWNMIX_TO_STEREO(MIX_FRONT3(samples),); + DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef),); break; case DCA_2F1R: - DOWNMIX_TO_STEREO(MIX_REAR1(samples, i + 512),); + DOWNMIX_TO_STEREO(MIX_REAR1(samples, i + 512, 2, coef),); break; case DCA_3F1R: - DOWNMIX_TO_STEREO(MIX_FRONT3(samples), - MIX_REAR1(samples, i + 768)); + DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef), + MIX_REAR1(samples, i + 768, 3, coef)); break; case DCA_2F2R: - DOWNMIX_TO_STEREO(MIX_REAR2(samples, i + 512, i + 768),); + DOWNMIX_TO_STEREO(MIX_REAR2(samples, i + 512, i + 768, 2, coef),); break; case DCA_3F2R: - DOWNMIX_TO_STEREO(MIX_FRONT3(samples), - MIX_REAR2(samples, i + 768, i + 1024)); + DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef), + MIX_REAR2(samples, i + 768, i + 1024, 3, coef)); break; } } @@ -832,7 +842,7 @@ static int dca_subsubframe(DCAContext * s) int k, l; int subsubframe = s->current_subsubframe; - float *quant_step_table; + const float *quant_step_table; /* FIXME */ float subband_samples[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8]; @@ -843,9 +853,9 @@ static int dca_subsubframe(DCAContext * s) /* Select quantization step size table */ if (s->bit_rate == 0x1f) - quant_step_table = (float *) lossless_quant_d; + quant_step_table = lossless_quant_d; else - quant_step_table = (float *) lossy_quant_d; + quant_step_table = lossy_quant_d; for (k = 0; k < s->prim_channels; k++) { for (l = 0; l < s->vq_start_subband[k]; l++) { @@ -979,7 +989,7 @@ static int dca_subsubframe(DCAContext * s) /* Down mixing */ if (s->prim_channels > dca_channels[s->output & DCA_CHANNEL_MASK]) { - dca_downmix(s->samples, s->amode); + dca_downmix(s->samples, s->amode, s->downmix_coef); } /* Generate LFE samples for this subsubframe FIXME!!! */ @@ -991,7 +1001,7 @@ static int dca_subsubframe(DCAContext * s) s->lfe_data + lfe_samples + 2 * s->lfe * subsubframe, &s->samples[256 * i_channels], - 8388608.0, s->bias); + 256.0, 0 /* s->bias */); /* Outputs 20bits pcm samples */ } @@ -1081,14 +1091,20 @@ static int dca_decode_block(DCAContext * s) /** * Convert bitstream to one representation based on sync marker */ -static int dca_convert_bitstream(uint8_t * src, int src_size, uint8_t * dst, +static int dca_convert_bitstream(const uint8_t * src, int src_size, uint8_t * dst, int max_size) { uint32_t mrk; int i, tmp; - uint16_t *ssrc = (uint16_t *) src, *sdst = (uint16_t *) dst; + const uint16_t *ssrc = (const uint16_t *) src; + uint16_t *sdst = (uint16_t *) dst; PutBitContext pb; + if((unsigned)src_size > (unsigned)max_size) { + av_log(NULL, AV_LOG_ERROR, "Input frame size larger then DCA_MAX_FRAME_SIZE!\n"); + return -1; + } + mrk = AV_RB32(src); switch (mrk) { case DCA_MARKER_RAW_BE: @@ -1118,7 +1134,7 @@ static int dca_convert_bitstream(uint8_t * src, int src_size, uint8_t * dst, */ static int dca_decode_frame(AVCodecContext * avctx, void *data, int *data_size, - uint8_t * buf, int buf_size) + const uint8_t * buf, int buf_size) { int i, j, k; @@ -1129,21 +1145,27 @@ static int dca_decode_frame(AVCodecContext * avctx, s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE); if (s->dca_buffer_size == -1) { - av_log(avctx, AV_LOG_ERROR, "Not a DCA frame\n"); + av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n"); return -1; } init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); if (dca_parse_frame_header(s) < 0) { //seems like the frame is corrupt, try with the next one + *data_size=0; return buf_size; } //set AVCodec values with parsed data avctx->sample_rate = s->sample_rate; - avctx->channels = 2; //FIXME avctx->bit_rate = s->bit_rate; - channels = dca_channels[s->output]; + channels = s->prim_channels + !!s->lfe; + if(avctx->request_channels == 2 && s->prim_channels > 2) { + channels = 2; + s->output = DCA_STEREO; + } + + avctx->channels = channels; if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels) return -1; *data_size = 0; @@ -1173,9 +1195,9 @@ static int dca_decode_frame(AVCodecContext * avctx, static void pre_calc_cosmod(DCAContext * s) { int i, j, k; - static int cosmod_inited = 0; + static int cosmod_initialized = 0; - if(cosmod_inited) return; + if(cosmod_initialized) return; for (j = 0, k = 0; k < 16; k++) for (i = 0; i < 16; i++) cos_mod[j++] = cos((2 * i + 1) * (2 * k + 1) * M_PI / 64); @@ -1190,7 +1212,7 @@ static void pre_calc_cosmod(DCAContext * s) for (k = 0; k < 16; k++) cos_mod[j++] = -0.25 / (2.0 * sin((2 * k + 1) * M_PI / 128)); - cosmod_inited = 1; + cosmod_initialized = 1; } @@ -1209,6 +1231,13 @@ static int dca_decode_init(AVCodecContext * avctx) pre_calc_cosmod(s); dsputil_init(&s->dsp, avctx); + + /* allow downmixing to stereo */ + if (avctx->channels > 0 && avctx->request_channels < avctx->channels && + avctx->request_channels == 2) { + avctx->channels = avctx->request_channels; + } + return 0; } @@ -1221,102 +1250,3 @@ AVCodec dca_decoder = { .init = dca_decode_init, .decode = dca_decode_frame, }; - -#ifdef CONFIG_DCA_PARSER - -typedef struct DCAParseContext { - ParseContext pc; - uint32_t lastmarker; -} DCAParseContext; - -#define IS_MARKER(state, i, buf, buf_size) \ - ((state == DCA_MARKER_14B_LE && (i < buf_size-2) && (buf[i+1] & 0xF0) == 0xF0 && buf[i+2] == 0x07) \ - || (state == DCA_MARKER_14B_BE && (i < buf_size-2) && buf[i+1] == 0x07 && (buf[i+2] & 0xF0) == 0xF0) \ - || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE) - -/** - * finds the end of the current frame in the bitstream. - * @return the position of the first byte of the next frame, or -1 - */ -static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, - int buf_size) -{ - int start_found, i; - uint32_t state; - ParseContext *pc = &pc1->pc; - - start_found = pc->frame_start_found; - state = pc->state; - - i = 0; - if (!start_found) { - for (i = 0; i < buf_size; i++) { - state = (state << 8) | buf[i]; - if (IS_MARKER(state, i, buf, buf_size)) { - if (pc1->lastmarker && state == pc1->lastmarker) { - start_found = 1; - break; - } else if (!pc1->lastmarker) { - start_found = 1; - pc1->lastmarker = state; - break; - } - } - } - } - if (start_found) { - for (; i < buf_size; i++) { - state = (state << 8) | buf[i]; - if (state == pc1->lastmarker && IS_MARKER(state, i, buf, buf_size)) { - pc->frame_start_found = 0; - pc->state = -1; - return i - 3; - } - } - } - pc->frame_start_found = start_found; - pc->state = state; - return END_NOT_FOUND; -} - -static int dca_parse_init(AVCodecParserContext * s) -{ - DCAParseContext *pc1 = s->priv_data; - - pc1->lastmarker = 0; - return 0; -} - -static int dca_parse(AVCodecParserContext * s, - AVCodecContext * avctx, - uint8_t ** poutbuf, int *poutbuf_size, - const uint8_t * buf, int buf_size) -{ - DCAParseContext *pc1 = s->priv_data; - ParseContext *pc = &pc1->pc; - int next; - - if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { - next = buf_size; - } else { - next = dca_find_frame_end(pc1, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **) & buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - *poutbuf = (uint8_t *) buf; - *poutbuf_size = buf_size; - return next; -} - -AVCodecParser dca_parser = { - {CODEC_ID_DTS}, - sizeof(DCAParseContext), - dca_parse_init, - dca_parse, - ff_parse_close, -}; -#endif /* CONFIG_DCA_PARSER */ diff --git a/contrib/ffmpeg/libavcodec/dca.h b/contrib/ffmpeg/libavcodec/dca.h new file mode 100644 index 000000000..e2197a440 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/dca.h @@ -0,0 +1,34 @@ +/* + * DCA compatible decoder + * Copyright (C) 2004 Gildas Bazin + * Copyright (C) 2004 Benjamin Zores + * Copyright (C) 2006 Benjamin Larsson + * Copyright (C) 2007 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 + */ + +#ifndef FFMPEG_DCA_H +#define FFMPEG_DCA_H + +/** DCA syncwords, also used for bitstream type detection */ +#define DCA_MARKER_RAW_BE 0x7FFE8001 +#define DCA_MARKER_RAW_LE 0xFE7F0180 +#define DCA_MARKER_14B_BE 0x1FFFE800 +#define DCA_MARKER_14B_LE 0xFF1F00E8 + +#endif /* FFMPEG_DCA_H */ diff --git a/contrib/ffmpeg/libavcodec/dca_parser.c b/contrib/ffmpeg/libavcodec/dca_parser.c new file mode 100644 index 000000000..6618b3156 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/dca_parser.c @@ -0,0 +1,126 @@ +/* + * DCA parser + * Copyright (C) 2004 Gildas Bazin + * Copyright (C) 2004 Benjamin Zores + * Copyright (C) 2006 Benjamin Larsson + * Copyright (C) 2007 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 + */ + +/** + * @file dca_parser.c + */ + +#include "parser.h" +#include "dca.h" + +typedef struct DCAParseContext { + ParseContext pc; + uint32_t lastmarker; +} DCAParseContext; + +#define IS_MARKER(state, i, buf, buf_size) \ + ((state == DCA_MARKER_14B_LE && (i < buf_size-2) && (buf[i+1] & 0xF0) == 0xF0 && buf[i+2] == 0x07) \ + || (state == DCA_MARKER_14B_BE && (i < buf_size-2) && buf[i+1] == 0x07 && (buf[i+2] & 0xF0) == 0xF0) \ + || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE) + +/** + * finds the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, + int buf_size) +{ + int start_found, i; + uint32_t state; + ParseContext *pc = &pc1->pc; + + start_found = pc->frame_start_found; + state = pc->state; + + i = 0; + if (!start_found) { + for (i = 0; i < buf_size; i++) { + state = (state << 8) | buf[i]; + if (IS_MARKER(state, i, buf, buf_size)) { + if (pc1->lastmarker && state == pc1->lastmarker) { + start_found = 1; + break; + } else if (!pc1->lastmarker) { + start_found = 1; + pc1->lastmarker = state; + break; + } + } + } + } + if (start_found) { + for (; i < buf_size; i++) { + state = (state << 8) | buf[i]; + if (state == pc1->lastmarker && IS_MARKER(state, i, buf, buf_size)) { + pc->frame_start_found = 0; + pc->state = -1; + return i - 3; + } + } + } + pc->frame_start_found = start_found; + pc->state = state; + return END_NOT_FOUND; +} + +static int dca_parse_init(AVCodecParserContext * s) +{ + DCAParseContext *pc1 = s->priv_data; + + pc1->lastmarker = 0; + return 0; +} + +static int dca_parse(AVCodecParserContext * s, + AVCodecContext * avctx, + const uint8_t ** poutbuf, int *poutbuf_size, + const uint8_t * buf, int buf_size) +{ + DCAParseContext *pc1 = s->priv_data; + ParseContext *pc = &pc1->pc; + int next; + + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + next = dca_find_frame_end(pc1, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser dca_parser = { + {CODEC_ID_DTS}, + sizeof(DCAParseContext), + dca_parse_init, + dca_parse, + ff_parse_close, +}; diff --git a/contrib/ffmpeg/libavcodec/dcadata.h b/contrib/ffmpeg/libavcodec/dcadata.h index c9f2ca747..40e78360d 100644 --- a/contrib/ffmpeg/libavcodec/dcadata.h +++ b/contrib/ffmpeg/libavcodec/dcadata.h @@ -24,6 +24,11 @@ * @file dcadata.c */ +#ifndef FFMPEG_DCADATA_H +#define FFMPEG_DCADATA_H + +#include <stdint.h> + /* Generic tables */ static const uint32_t dca_sample_rates[16] = @@ -7309,7 +7314,7 @@ static const float fir_32bands_nonperfect[] = +1.390191784E-007 }; -//FIXME the coeffs are symetric +//FIXME the coeffs are symmetric static const float lfe_fir_64[] = { 2.6584343868307770E-004, @@ -7826,7 +7831,7 @@ static const float lfe_fir_64[] = 2.6584343868307770E-004 }; -//FIXME the coeffs are symetric +//FIXME the coeffs are symmetric static const float lfe_fir_128[] = { @@ -8344,7 +8349,7 @@ static const float lfe_fir_128[] = 0.00053168571 }; -/* 10^-(dB/20), with dB beeing a list of dB values rangeing from 0 to -72 */ +/* 10^-(dB/20), with dB being a list of dB values ranging from 0 to -72 */ /* do a 20*log10(dca_downmix_coeffs) to reconvert the values */ static const float dca_downmix_coeffs[65] = { @@ -8361,6 +8366,19 @@ static const float dca_downmix_coeffs[65] = { 0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000, }; +static const uint8_t dca_default_coeffs[16][5][2] = { + { { 13, 13 }, }, + { { 0, 64 }, { 64, 0 }, }, + { { 0, 64 }, { 64, 0 }, }, + { { 0, 64 }, { 64, 0 }, }, + { { 0, 64 }, { 64, 0 }, }, + { { 6, 6 }, { 0, 25 }, { 25, 0 }, }, + { { 0, 25 }, { 25, 0 }, { 13, 13 }, }, + { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 13, 13 }, }, + { { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, + { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, +}; + /* downmix coeffs TABLE 9 @@ -8452,3 +8470,5 @@ where Ch(n) represents the subband samples in the (n)th audio channel. */ + +#endif /* FFMPEG_DCADATA_H */ diff --git a/contrib/ffmpeg/libavcodec/dcahuff.h b/contrib/ffmpeg/libavcodec/dcahuff.h index 8a78aee7e..a140f3b8b 100644 --- a/contrib/ffmpeg/libavcodec/dcahuff.h +++ b/contrib/ffmpeg/libavcodec/dcahuff.h @@ -20,6 +20,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_DCAHUFF_H +#define FFMPEG_DCAHUFF_H + +#include <stdint.h> +#include <stdlib.h> + #define TMODE_COUNT 4 static const uint8_t tmode_vlc_bits[TMODE_COUNT] = { 3, 3, 3, 2 }; static const uint16_t tmode_codes[TMODE_COUNT][4] = { @@ -1066,3 +1072,5 @@ static const uint8_t* bitalloc_bits[10][8] = { { bitalloc_129_bits_a, bitalloc_129_bits_b, bitalloc_129_bits_c, bitalloc_129_bits_d, bitalloc_129_bits_e, bitalloc_129_bits_f, bitalloc_129_bits_g, NULL } }; + +#endif /* FFMPEG_DCAHUFF_H */ diff --git a/contrib/ffmpeg/libavcodec/dct-test.c b/contrib/ffmpeg/libavcodec/dct-test.c index 7cd866832..c3ef297c4 100644 --- a/contrib/ffmpeg/libavcodec/dct-test.c +++ b/contrib/ffmpeg/libavcodec/dct-test.c @@ -30,17 +30,20 @@ #include <string.h> #include <sys/time.h> #include <unistd.h> +#include <math.h> #include "dsputil.h" #include "simple_idct.h" #include "faandct.h" +#include "faanidct.h" #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif #undef printf +#undef random void *fast_memcpy(void *a, const void *b, size_t c){return memcpy(a,b,c);}; @@ -51,7 +54,6 @@ extern void ff_idct_xvid_mmx(DCTELEM *block); extern void ff_idct_xvid_mmx2(DCTELEM *block); extern void init_fdct(); -extern void j_rev_dct(DCTELEM *data); extern void ff_mmx_idct(DCTELEM *data); extern void ff_mmxext_idct(DCTELEM *data); @@ -85,19 +87,24 @@ struct algo { struct algo algos[] = { DCT_ERROR( "REF-DBL", 0, fdct, fdct, NO_PERM), + DCT_ERROR("FAAN", 0, ff_faandct, fdct, FAAN_SCALE), + DCT_ERROR("FAANI", 1, ff_faanidct, idct, NO_PERM), DCT_ERROR("IJG-AAN-INT", 0, fdct_ifast, fdct, SCALE_PERM), DCT_ERROR("IJG-LLM-INT", 0, ff_jpeg_fdct_islow, fdct, NO_PERM), DCT_ERROR("REF-DBL", 1, idct, idct, NO_PERM), DCT_ERROR("INT", 1, j_rev_dct, idct, MMX_PERM), - DCT_ERROR("SIMPLE-C", 1, simple_idct, idct, NO_PERM), + DCT_ERROR("SIMPLE-C", 1, ff_simple_idct, idct, NO_PERM), -#ifdef ARCH_X86 +#ifdef HAVE_MMX DCT_ERROR("MMX", 0, ff_fdct_mmx, fdct, NO_PERM), +#ifdef HAVE_MMX2 DCT_ERROR("MMX2", 0, ff_fdct_mmx2, fdct, NO_PERM), - DCT_ERROR("FAAN", 0, ff_faandct, fdct, FAAN_SCALE), +#endif +#ifdef CONFIG_GPL DCT_ERROR("LIBMPEG2-MMX", 1, ff_mmx_idct, idct, MMX_PERM), DCT_ERROR("LIBMPEG2-MMXEXT", 1, ff_mmxext_idct, idct, MMX_PERM), +#endif DCT_ERROR("SIMPLE-MMX", 1, ff_simple_idct_mmx, idct, MMX_SIMPLE_PERM), DCT_ERROR("XVID-MMX", 1, ff_idct_xvid_mmx, idct, NO_PERM), DCT_ERROR("XVID-MMX2", 1, ff_idct_xvid_mmx2, idct, NO_PERM), @@ -333,7 +340,7 @@ void dct_error(const char *name, int is_idct, for(i=0; i<64; i++) block[i]= block1[i]; // memcpy(block, block1, sizeof(DCTELEM) * 64); -// dont memcpy especially not fastmemcpy because it does movntq !!! +// do not memcpy especially not fastmemcpy because it does movntq !!! fdct_func(block); } it1 += NB_ITS_SPEED; @@ -493,7 +500,7 @@ void idct248_error(const char *name, for(i=0; i<64; i++) block[i]= block1[i]; // memcpy(block, block1, sizeof(DCTELEM) * 64); -// dont memcpy especially not fastmemcpy because it does movntq !!! +// do not memcpy especially not fastmemcpy because it does movntq !!! idct248_put(img_dest, 8, block); } it1 += NB_ITS_SPEED; @@ -554,7 +561,7 @@ int main(int argc, char **argv) printf("ffmpeg DCT/IDCT test\n"); if (test_248_dct) { - idct248_error("SIMPLE-C", simple_idct248_put); + idct248_error("SIMPLE-C", ff_simple_idct248_put); } else { for (i=0;algos[i].name;i++) if (algos[i].is_idct == test_idct) { diff --git a/contrib/ffmpeg/libavcodec/dnxhddata.c b/contrib/ffmpeg/libavcodec/dnxhddata.c new file mode 100644 index 000000000..fa6d13fa4 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/dnxhddata.c @@ -0,0 +1,443 @@ +/* + * VC3/DNxHD data. + * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>. + * + * 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" +#include "dnxhddata.h" + +static const uint8_t dnxhd_1237_luma_weight[] = { + 0, 32, 33, 34, 34, 36, 37, 36, + 36, 37, 38, 38, 38, 39, 41, 44, + 43, 41, 40, 41, 46, 49, 47, 46, + 47, 49, 51, 54, 60, 62, 59, 55, + 54, 56, 58, 61, 65, 66, 64, 63, + 66, 73, 78, 79, 80, 79, 78, 78, + 82, 87, 89, 90, 93, 95, 96, 97, + 97, 100, 104, 102, 98, 98, 99, 99, +}; + +static const uint8_t dnxhd_1237_chroma_weight[] = { + 0, 32, 36, 39, 39, 38, 39, 41, + 45, 51, 57, 58, 53, 48, 47, 51, + 55, 58, 66, 75, 81, 83, 82, 78, + 73, 72, 74, 77, 83, 85, 83, 82, + 89, 99, 96, 90, 94, 97, 99, 105, + 109, 105, 95, 89, 92, 95, 94, 93, + 92, 88, 89, 90, 93, 95, 96, 97, + 97, 100, 104, 102, 98, 98, 99, 99, +}; + +static const uint8_t dnxhd_1238_luma_weight[] = { + 0, 32, 32, 33, 34, 33, 33, 33, + 33, 33, 33, 33, 33, 35, 37, 37, + 36, 36, 35, 36, 38, 38, 36, 35, + 36, 37, 38, 41, 42, 41, 39, 38, + 38, 38, 39, 41, 42, 41, 39, 39, + 40, 41, 43, 44, 44, 44, 44, 44, + 45, 47, 47, 47, 49, 50, 51, 51, + 51, 53, 55, 57, 58, 59, 57, 57, +}; + +static const uint8_t dnxhd_1238_chroma_weight[] = { + 0, 32, 35, 35, 35, 34, 34, 35, + 39, 43, 45, 45, 41, 39, 40, 41, + 42, 44, 48, 55, 59, 63, 65, 59, + 53, 52, 52, 55, 61, 62, 58, 58, + 63, 66, 66, 65, 70, 74, 70, 66, + 65, 68, 75, 77, 74, 74, 77, 76, + 73, 73, 73, 73, 76, 80, 89, 90, + 82, 77, 80, 86, 84, 82, 82, 82, +}; + +static const uint8_t dnxhd_1241_luma_weight[] = { + 0, 32, 33, 34, 34, 35, 36, 37, + 36, 37, 38, 38, 38, 39, 39, 40, + 40, 38, 38, 39, 38, 37, 39, 41, + 41, 42, 43, 45, 45, 46, 47, 46, + 45, 43, 39, 37, 37, 40, 44, 45, + 45, 46, 46, 46, 47, 47, 46, 44, + 42, 43, 45, 47, 48, 49, 50, 49, + 48, 46, 47, 48, 48, 49, 49, 49, +}; + +static const uint8_t dnxhd_1241_chroma_weight[] = { + 0, 32, 36, 38, 37, 37, 40, 41, + 40, 40, 42, 42, 41, 41, 41, 41, + 42, 43, 44, 44, 45, 46, 46, 45, + 44, 45, 45, 45, 45, 46, 47, 46, + 45, 44, 42, 41, 43, 45, 45, 47, + 48, 48, 48, 46, 47, 47, 46, 47, + 46, 45, 45, 47, 48, 49, 50, 49, + 48, 46, 48, 49, 48, 49, 49, 49, +}; + +static const uint8_t dnxhd_1242_luma_weight[] = { + 0, 32, 33, 33, 34, 35, 36, 35, + 33, 33, 35, 36, 37, 37, 38, 37, + 37, 37, 36, 37, 37, 37, 38, 39, + 37, 36, 37, 40, 42, 45, 46, 44, + 41, 42, 44, 45, 47, 49, 50, 48, + 46, 48, 49, 50, 52, 52, 50, 49, + 47, 48, 50, 50, 51, 51, 50, 49, + 49, 51, 52, 51, 49, 47, 47, 47, +}; + +static const uint8_t dnxhd_1242_chroma_weight[] = { + 0, 32, 37, 42, 45, 45, 45, 44, + 38, 37, 40, 42, 44, 49, 51, 47, + 41, 40, 43, 44, 46, 48, 51, 54, + 51, 47, 47, 45, 47, 50, 51, 49, + 46, 47, 49, 47, 50, 55, 55, 51, + 48, 49, 51, 51, 52, 52, 54, 54, + 49, 49, 52, 53, 54, 54, 53, 53, + 55, 59, 63, 62, 60, 60, 60, 60, + }; + +static const uint8_t dnxhd_1243_luma_weight[] = { + 0, 32, 32, 33, 33, 35, 35, 35, + 35, 35, 35, 35, 34, 35, 38, 40, + 39, 37, 37, 37, 36, 35, 36, 38, + 40, 41, 42, 44, 45, 44, 42, 41, + 40, 38, 36, 36, 37, 38, 40, 43, + 44, 45, 45, 45, 45, 45, 45, 41, + 39, 41, 45, 47, 47, 48, 48, 48, + 46, 44, 45, 47, 47, 48, 47, 47, +}; + +static const uint8_t dnxhd_1243_chroma_weight[] = { + 0, 32, 36, 37, 36, 37, 39, 39, + 41, 43, 43, 42, 41, 41, 41, 42, + 43, 43, 43, 44, 44, 44, 46, 47, + 46, 45, 45, 45, 45, 46, 44, 44, + 45, 44, 42, 41, 43, 46, 45, 44, + 45, 45, 45, 46, 46, 46, 45, 44, + 45, 44, 45, 47, 47, 48, 49, 48, + 46, 45, 46, 47, 47, 48, 47, 47, +}; + +static const uint8_t dnxhd_1251_luma_weight[] = { + 0, 32, 32, 34, 34, 34, 34, 35, + 35, 35, 36, 37, 36, 36, 35, 36, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 39, 41, 44, 43, 41, 40, + 40, 40, 40, 39, 40, 41, 40, 39, + 40, 43, 46, 46, 44, 44, 44, 42, + 41, 43, 46, 48, 50, 55, 58, 53, + 48, 50, 55, 58, 61, 62, 62, 62, +}; + +static const uint8_t dnxhd_1251_chroma_weight[] = { + 0, 32, 35, 36, 36, 35, 36, 39, + 41, 43, 45, 44, 41, 39, 40, 42, + 43, 43, 45, 48, 48, 48, 50, 50, + 50, 51, 51, 51, 51, 52, 53, 54, + 51, 49, 51, 52, 52, 56, 57, 55, + 54, 54, 55, 56, 55, 58, 58, 58, + 60, 61, 62, 62, 59, 57, 58, 58, + 61, 59, 59, 59, 61, 62, 62, 62, +}; + +static const uint8_t dnxhd_1252_luma_weight[] = { + 0, 32, 34, 35, 36, 36, 36, 37, + 36, 37, 39, 40, 41, 40, 40, 40, + 41, 41, 42, 41, 41, 43, 44, 44, + 45, 46, 48, 55, 60, 57, 52, 50, + 49, 49, 52, 52, 53, 55, 58, 62, + 65, 73, 82, 82, 80, 78, 73, 68, + 71, 82, 90, 90, 88, 87, 90, 95, + 100, 107, 103, 97, 95, 93, 99, 99, +}; +static const uint8_t dnxhd_1252_chroma_weight[] = { + 0, 32, 35, 36, 37, 37, 38, 40, + 42, 46, 49, 50, 50, 49, 49, 53, + 56, 56, 57, 58, 60, 62, 64, 65, + 63, 64, 64, 65, 66, 65, 67, 71, + 72, 74, 74, 74, 74, 77, 81, 78, + 72, 73, 82, 85, 89, 88, 84, 80, + 90, 100, 90, 90, 88, 87, 90, 95, + 114, 128, 125, 129, 134, 125, 116, 116, +}; + +static const uint8_t dnxhd_1237_dc_codes[12] = { + 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, +}; + +static const uint8_t dnxhd_1237_dc_bits[12] = { + 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, +}; + +static const uint16_t dnxhd_1237_ac_codes[257] = { + 0, 1, 4, 5, 12, 26, 27, 56, 57, 58, 59, 120, 121, 244, 245, 246, 247, 248, 498, 499, 500, 501, 502, 1006, 1007, 1008, 1009, 1010, 1011, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 32668, 32669, 32670, 32671, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 65370, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, 65379, 65380, 65381, 65382, 65383, 65384, 65385, 65386, 65387, 65388, 65389, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; + +static const uint8_t dnxhd_1237_ac_bits[257] = { + 2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; + +static const uint8_t dnxhd_1237_ac_level[257] = { + 1, 1, 2, 0, 3, 4, 2, 5, 6, 7, 3, 8, 9, 10, 11, 12, 4, 5, 13, 14, 15, 16, 6, 17, 18, 19, 20, 21, 7, 22, 23, 24, 25, 26, 27, 8, 9, 28, 29, 30, 31, 32, 33, 34, 10, 11, 12, 35, 36, 37, 38, 39, 40, 41, 13, 14, 15, 16, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 17, 18, 19, 20, 21, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 1, 22, 23, 24, 25, 26, 27, 62, 63, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; + +static const uint8_t dnxhd_1237_ac_run_flag[257] = { + 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint8_t dnxhd_1237_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint16_t dnxhd_1237_run_codes[62] = { + 0, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 58, 118, 119, 240, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; + +static const uint8_t dnxhd_1237_run_bits[62] = { + 1, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; + +static const uint8_t dnxhd_1237_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 53, 57, 58, 59, 60, 61, 62, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 54, 55, 56, +}; + +static const uint8_t dnxhd_1238_dc_codes[12] = { + 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, +}; + +static const uint8_t dnxhd_1238_dc_bits[12] = { + 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, +}; + +static const uint16_t dnxhd_1238_ac_codes[257] = { + 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 499, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; + +static const uint8_t dnxhd_1238_ac_bits[257] = { + 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; + +static const uint8_t dnxhd_1238_ac_level[257] = { + 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 22, 6, 7, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 10, 11, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 12, 13, 14, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 15, 16, 17, 18, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40, 25, 26, 27, 28, 29, 30, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; /* 0 is EOB */ + +static const uint8_t dnxhd_1238_ac_run_flag[257] = { + 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint8_t dnxhd_1238_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint16_t dnxhd_1238_run_codes[62] = { + 0, 4, 10, 11, 24, 25, 26, 27, 56, 57, 58, 59, 120, 242, 486, 487, 488, 489, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; + +static const uint8_t dnxhd_1238_run_bits[62] = { + 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; + +static const uint8_t dnxhd_1238_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 21, 17, 18, 19, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +}; + +static const uint8_t dnxhd_1241_dc_codes[14] = { + 10, 62, 11, 12, 13, 0, 1, 2, 3, 4, 14, 30, 126, 127, +}; + +static const uint8_t dnxhd_1241_dc_bits[14] = { + 4, 6, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 7, 7, +}; +static const uint16_t dnxhd_1241_ac_codes[257] = { + 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; + +static const uint8_t dnxhd_1241_ac_bits[257] = { + 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; + +static const uint8_t dnxhd_1241_ac_level[257] = { + 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 7, 22, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 38, 10, 11, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 12, 13, 14, 15, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1, 16, 17, 18, 19, 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 25, 26, 27, 28, 29, 30, 31, 32, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; + +static const uint8_t dnxhd_1241_ac_run_flag[257] = { + 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint8_t dnxhd_1241_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint16_t dnxhd_1241_run_codes[62] = { + 0, 4, 10, 11, 24, 25, 26, 27, 56, 57, 58, 59, 120, 242, 486, 487, 488, 489, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; + +static const uint8_t dnxhd_1241_run_bits[62] = { + 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; + +static const uint8_t dnxhd_1241_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 17, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +}; + +static const uint8_t dnxhd_1251_dc_codes[12] = { + 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, +}; +static const uint8_t dnxhd_1251_dc_bits[12] = { + 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, +}; +static const uint16_t dnxhd_1251_ac_codes[257] = { + 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 8134, 8135, 8136, 8137, 8138, 8139, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 16339, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 32709, 32710, 32711, 32712, 32713, 32714, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; +static const uint8_t dnxhd_1251_ac_bits[257] = { + 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; +static const uint8_t dnxhd_1251_ac_level[257] = { + 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 22, 23, 24, 25, 26, 27, 28, 29, 7, 8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 9, 10, 11, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 12, 13, 14, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 20, 21, 22, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 23, 24, 25, 26, 27, 28, 59, 60, 61, 62, 63, 64, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; +static const uint8_t dnxhd_1251_ac_run_flag[257] = { + 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const uint8_t dnxhd_1251_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const uint16_t dnxhd_1251_run_codes[62] = { + 0, 4, 5, 12, 26, 27, 28, 58, 118, 119, 120, 242, 486, 487, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; +static const uint8_t dnxhd_1251_run_bits[62] = { + 1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; +static const uint8_t dnxhd_1251_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +}; + +static const uint8_t dnxhd_1252_dc_codes[12] = { + 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, +}; +static const uint8_t dnxhd_1252_dc_bits[12] = { + 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, +}; +static const uint16_t dnxhd_1252_ac_codes[257] = { + 0, 1, 4, 10, 11, 12, 26, 27, 56, 57, 58, 118, 119, 120, 242, 243, 244, 245, 246, 247, 496, 497, 498, 499, 500, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, +}; +static const uint8_t dnxhd_1252_ac_bits[257] = { + 2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}; +static const uint8_t dnxhd_1252_ac_level[257] = { + 1, 1, 2, 3, 2, 0, 4, 5, 6, 7, 3, 8, 9, 10, 11, 12, 13, 14, 4, 5, 15, 16, 17, 18, 6, 19, 20, 21, 22, 23, 24, 7, 8, 25, 26, 27, 28, 29, 30, 31, 32, 9, 10, 33, 34, 35, 36, 37, 38, 39, 40, 41, 11, 12, 13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 14, 15, 16, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 17, 18, 19, 20, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +}; +static const uint8_t dnxhd_1252_ac_run_flag[257] = { + 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const uint8_t dnxhd_1252_ac_index_flag[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; +static const uint16_t dnxhd_1252_run_codes[62] = { + 0, 4, 5, 12, 26, 27, 28, 58, 118, 119, 120, 242, 486, 487, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, +}; +static const uint8_t dnxhd_1252_run_bits[62] = { + 1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +}; +static const uint8_t dnxhd_1252_run[62] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +}; + +const CIDEntry ff_dnxhd_cid_table[] = { + { 1237, 1920, 1080, 0, 606208, 606208, 4, 8, + dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight, + dnxhd_1237_dc_codes, dnxhd_1237_dc_bits, + dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level, + dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag, + dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, + { 115, 120, 145, 240, 290 } }, + { 1238, 1920, 1080, 0, 917504, 917504, 4, 8, + dnxhd_1238_luma_weight, dnxhd_1238_chroma_weight, + dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, + dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, + dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, + dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run, + { 175, 185, 220, 365, 440 } }, + { 1241, 1920, 1080, 1, 917504, 458752, 6, 10, + dnxhd_1241_luma_weight, dnxhd_1241_chroma_weight, + dnxhd_1241_dc_codes, dnxhd_1241_dc_bits, + dnxhd_1241_ac_codes, dnxhd_1241_ac_bits, dnxhd_1241_ac_level, + dnxhd_1241_ac_run_flag, dnxhd_1241_ac_index_flag, + dnxhd_1241_run_codes, dnxhd_1241_run_bits, dnxhd_1241_run, + { 185, 220 } }, + { 1242, 1920, 1080, 1, 606208, 303104, 4, 8, + dnxhd_1242_luma_weight, dnxhd_1242_chroma_weight, + dnxhd_1237_dc_codes, dnxhd_1237_dc_bits, + dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level, + dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag, + dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, + { 120, 145 } }, + { 1243, 1920, 1080, 1, 917504, 458752, 4, 8, + dnxhd_1243_luma_weight, dnxhd_1243_chroma_weight, + dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, + dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, + dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, + dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run, + { 185, 220 } }, + { 1251, 1280, 720, 0, 458752, 458752, 4, 8, + dnxhd_1251_luma_weight, dnxhd_1251_chroma_weight, + dnxhd_1251_dc_codes, dnxhd_1251_dc_bits, + dnxhd_1251_ac_codes, dnxhd_1251_ac_bits, dnxhd_1251_ac_level, + dnxhd_1251_ac_run_flag, dnxhd_1251_ac_index_flag, + dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run, + { 90, 110, 175, 220 } }, + { 1252, 1280, 720, 0, 303104, 303104, 4, 8, + dnxhd_1252_luma_weight, dnxhd_1252_chroma_weight, + dnxhd_1252_dc_codes, dnxhd_1252_dc_bits, + dnxhd_1252_ac_codes, dnxhd_1252_ac_bits, dnxhd_1252_ac_level, + dnxhd_1252_ac_run_flag, dnxhd_1252_ac_index_flag, + dnxhd_1252_run_codes, dnxhd_1252_run_bits, dnxhd_1252_run, + { 60, 75, 115, 145 } }, + { 1253, 1920, 1080, 0, 188416, 188416, 4, 8, + dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight, + dnxhd_1237_dc_codes, dnxhd_1237_dc_bits, + dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level, + dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag, + dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, + { 36, 45, 75, 90 } }, +}; + +int ff_dnxhd_get_cid_table(int cid) +{ + int i; + for (i = 0; i < sizeof(ff_dnxhd_cid_table)/sizeof(CIDEntry); i++) + if (ff_dnxhd_cid_table[i].cid == cid) + return i; + return -1; +} + +int ff_dnxhd_find_cid(AVCodecContext *avctx) +{ + int i, j; + int mbs = avctx->bit_rate/1000000; + for (i = 0; i < sizeof(ff_dnxhd_cid_table)/sizeof(CIDEntry); i++) { + const CIDEntry *cid = &ff_dnxhd_cid_table[i]; + if (cid->width == avctx->width && cid->height == avctx->height && + cid->interlaced == !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT) && + cid->bit_depth == 8) { // until 10 bit is supported + for (j = 0; j < sizeof(cid->bit_rates); j++) { + if (cid->bit_rates[j] == mbs) + return cid->cid; + } + } + } + return 0; +} diff --git a/contrib/ffmpeg/libavcodec/dnxhddata.h b/contrib/ffmpeg/libavcodec/dnxhddata.h index 5d5aa528b..1bd028e08 100644 --- a/contrib/ffmpeg/libavcodec/dnxhddata.h +++ b/contrib/ffmpeg/libavcodec/dnxhddata.h @@ -19,88 +19,33 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -static const uint8_t dnxhd_1238_luma_weigth[] = { - 0, 32, 32, 33, 34, 33, 33, 33, - 33, 33, 33, 33, 33, 35, 37, 37, - 36, 36, 35, 36, 38, 38, 36, 35, - 36, 37, 38, 41, 42, 41, 39, 38, - 38, 38, 39, 41, 42, 41, 39, 39, - 40, 41, 43, 44, 44, 44, 44, 44, - 45, 47, 47, 47, 49, 50, 51, 51, - 51, 53, 55, 57, 58, 59, 57, 57, -}; - -static const uint8_t dnxhd_1238_chroma_weigth[] = { - 0, 32, 35, 35, 35, 34, 34, 35, - 39, 43, 45, 45, 41, 39, 40, 41, - 42, 44, 48, 55, 59, 63, 65, 59, - 53, 52, 52, 55, 61, 62, 58, 58, - 63, 66, 66, 65, 70, 74, 70, 66, - 65, 68, 75, 77, 74, 74, 77, 76, - 73, 73, 73, 73, 76, 80, 89, 90, - 82, 77, 80, 86, 84, 82, 82, 82, -}; - -/* FIXME permute */ -static const uint8_t dnxhd_1243_luma_weigth[] = { - 0,32,35,35,38,40,44,45, - 32,33,35,35,39,42,44,45, - 33,35,34,37,41,42,45,45, - 35,35,37,40,41,44,45,48, - 35,37,38,40,43,45,47,48, - 36,36,38,40,45,47,48,47, - 35,36,38,41,45,46,47,48, - 36,37,39,41,44,45,47,47, -}; - -/* FIXME permute */ -static const uint8_t dnxhd_1243_chroma_weigth[] = { - 0,32,37,39,41,42,45,45, - 36,36,39,41,43,45,46,45, - 37,41,41,43,45,44,45,46, - 43,42,43,46,44,45,46,48, - 43,44,47,45,44,46,47,49, - 44,46,44,45,45,47,48,47, - 44,42,46,44,45,46,47,48, - 41,43,45,44,45,46,47,47, -}; - -static const uint8_t dnxhd_1238_dc_codes[12] = { - 0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63, -}; - -static const uint8_t dnxhd_1238_dc_bits[12] = { - 3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6, -}; - -static const uint16_t dnxhd_1238_ac_codes[257] = { - 0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 499, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535, -}; - -static const uint8_t dnxhd_1238_ac_bits[257] = { - 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -}; - -static const uint8_t dnxhd_1238_ac_level[257] = { - 1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 22, 6, 7, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 10, 11, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 12, 13, 14, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 15, 16, 17, 18, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40, 25, 26, 27, 28, 29, 30, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, -}; /* 0 is EOB */ - -static const uint8_t dnxhd_1238_ac_run_flag[257] = { - 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const uint8_t dnxhd_1238_ac_index_flag[257] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const uint16_t dnxhd_1238_run_codes[62] = { - 0, 4, 10, 11, 24, 25, 26, 27, 56, 57, 58, 59, 120, 242, 486, 487, 488, 489, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, -}; - -static const uint8_t dnxhd_1238_run_bits[62] = { - 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, -}; - -static const uint8_t dnxhd_1238_run[62] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 21, 17, 18, 19, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, -}; +#ifndef FFMPEG_DNXHDDATA_H +#define FFMPEG_DNXHDDATA_H + +#include <stdint.h> +#include "avcodec.h" + +typedef struct { + int cid; + unsigned int width, height; + int interlaced; + unsigned int frame_size; + unsigned int coding_unit_size; + int index_bits; + int bit_depth; + const uint8_t *luma_weight, *chroma_weight; + const uint8_t *dc_codes, *dc_bits; + const uint16_t *ac_codes; + const uint8_t *ac_bits, *ac_level; + const uint8_t *ac_run_flag, *ac_index_flag; + const uint16_t *run_codes; + const uint8_t *run_bits, *run; + int bit_rates[5]; ///< Helpher to choose variants, rounded to nearest 5Mb/s +} CIDEntry; + +extern const CIDEntry ff_dnxhd_cid_table[]; + +int ff_dnxhd_get_cid_table(int cid); +int ff_dnxhd_find_cid(AVCodecContext *avctx); + +#endif /* FFMPEG_DNXHDDATA_H */ diff --git a/contrib/ffmpeg/libavcodec/dnxhddec.c b/contrib/ffmpeg/libavcodec/dnxhddec.c index 224439c47..8d3977ed5 100644 --- a/contrib/ffmpeg/libavcodec/dnxhddec.c +++ b/contrib/ffmpeg/libavcodec/dnxhddec.c @@ -29,22 +29,6 @@ #include "mpegvideo.h" typedef struct { - int cid; - unsigned int width, height; - int interlaced; - unsigned int frame_size; - int index_bits; - int bit_depth; - const uint8_t *luma_weigth, *chroma_weigth; - const uint8_t *dc_codes, *dc_bits; - const uint16_t *ac_codes; - const uint8_t *ac_bits, *ac_level; - const uint8_t *ac_run_flag, *ac_index_flag; - const uint16_t *run_codes; - const uint8_t *run_bits, *run; -} CIDEntry; - -typedef struct { AVCodecContext *avctx; AVFrame picture; GetBitContext gb; @@ -53,11 +37,7 @@ typedef struct { unsigned int mb_width, mb_height; uint32_t mb_scan_index[68]; /* max for 1080p */ int cur_field; ///< current interlaced field - int index_bits; ///< length of index value VLC ac_vlc, dc_vlc, run_vlc; - const uint8_t *ac_level, *run; - const uint8_t *ac_run_flag, *ac_index_flag; - const uint8_t *luma_weigth, *chroma_weigth; int last_dc[3]; DSPContext dsp; DECLARE_ALIGNED_16(DCTELEM, blocks[8][64]); @@ -65,32 +45,8 @@ typedef struct { const CIDEntry *cid_table; } DNXHDContext; -static const CIDEntry cid_table[] = { - { 1238, 1920, 1080, 0, 917504, 4, 8, - dnxhd_1238_luma_weigth, dnxhd_1238_chroma_weigth, - dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, - dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, - dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, - dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run }, -/* { 1243, 1920, 1080, 1, 917504, 4, 8, */ -/* dnxhd_1243_luma_weigth, dnxhd_1243_chroma_weigth, */ -/* dnxhd_1238_dc_codes, dnxhd_1238_dc_bits, */ -/* dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level, */ -/* dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag, */ -/* dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run }, */ -}; - -static int dnxhd_get_cid_table(int cid) -{ - int i; - for (i = 0; i < sizeof(cid_table)/sizeof(CIDEntry); i++) - if (cid_table[i].cid == cid) - return i; - return -1; -} - #define DNXHD_VLC_BITS 9 -#define DNXHD_DC_VLC_BITS 6 +#define DNXHD_DC_VLC_BITS 7 static int dnxhd_decode_init(AVCodecContext *avctx) { @@ -108,36 +64,27 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) if (!ctx->cid_table) { int index; - if ((index = dnxhd_get_cid_table(cid)) < 0) { + if ((index = ff_dnxhd_get_cid_table(cid)) < 0) { av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %d\n", cid); return -1; } - ctx->cid_table = &cid_table[index]; + ctx->cid_table = &ff_dnxhd_cid_table[index]; init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257, - cid_table->ac_bits, 1, 1, - cid_table->ac_codes, 2, 2, 0); - init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, 12, - cid_table->dc_bits, 1, 1, - cid_table->dc_codes, 1, 1, 0); + ctx->cid_table->ac_bits, 1, 1, + ctx->cid_table->ac_codes, 2, 2, 0); + init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, ctx->cid_table->bit_depth+4, + ctx->cid_table->dc_bits, 1, 1, + ctx->cid_table->dc_codes, 1, 1, 0); init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62, - cid_table->run_bits, 1, 1, - cid_table->run_codes, 2, 2, 0); - - ctx->run = cid_table->run; - ctx->ac_level = cid_table->ac_level; - ctx->ac_run_flag = cid_table->ac_run_flag; - ctx->ac_index_flag = cid_table->ac_index_flag; - ctx->luma_weigth = cid_table->luma_weigth; - ctx->chroma_weigth = cid_table->chroma_weigth; - - ctx->index_bits = cid_table->index_bits; + ctx->cid_table->run_bits, 1, 1, + ctx->cid_table->run_codes, 2, 2, 0); ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct); } return 0; } -static int dnxhd_decode_header(DNXHDContext *ctx, uint8_t *buf, int buf_size) +static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field) { static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; int i; @@ -149,9 +96,11 @@ static int dnxhd_decode_header(DNXHDContext *ctx, uint8_t *buf, int buf_size) av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n"); return -1; } - if (buf[5] & 2) {/* interlaced FIXME top or bottom */ + if (buf[5] & 2) { /* interlaced */ + ctx->cur_field = buf[5] & 1; ctx->picture.interlaced_frame = 1; - av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d\n", buf[5] & 3); + ctx->picture.top_field_first = first_field ^ ctx->cur_field; + av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field); } ctx->height = AV_RB16(buf + 0x18); @@ -159,7 +108,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, uint8_t *buf, int buf_size) dprintf(ctx->avctx, "width %d, heigth %d\n", ctx->width, ctx->height); - if (buf[0x21] & 0x80) { + if (buf[0x21] & 0x40) { av_log(ctx->avctx, AV_LOG_ERROR, "10 bit per component\n"); return -1; } @@ -170,7 +119,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, uint8_t *buf, int buf_size) if (dnxhd_init_vlc(ctx, ctx->cid) < 0) return -1; - if (buf_size < ctx->cid_table->frame_size) { + if (buf_size < ctx->cid_table->coding_unit_size) { av_log(ctx->avctx, AV_LOG_ERROR, "incorrect frame size\n"); return -1; } @@ -212,10 +161,10 @@ static void dnxhd_decode_dct_block(DNXHDContext *ctx, DCTELEM *block, int n, int if (n&2) { component = 1 + (n&1); - weigth_matrix = ctx->chroma_weigth; + weigth_matrix = ctx->cid_table->chroma_weight; } else { component = 0; - weigth_matrix = ctx->luma_weigth; + weigth_matrix = ctx->cid_table->luma_weight; } ctx->last_dc[component] += dnxhd_decode_dc(ctx); @@ -224,38 +173,42 @@ static void dnxhd_decode_dct_block(DNXHDContext *ctx, DCTELEM *block, int n, int for (i = 1; ; i++) { index = get_vlc2(&ctx->gb, ctx->ac_vlc.table, DNXHD_VLC_BITS, 2); //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index); - level = ctx->ac_level[index]; + level = ctx->cid_table->ac_level[index]; if (!level) { /* EOB */ //av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n"); return; } sign = get_sbits(&ctx->gb, 1); - if (ctx->ac_index_flag[index]) { - level += get_bits(&ctx->gb, ctx->index_bits)<<6; + if (ctx->cid_table->ac_index_flag[index]) { + level += get_bits(&ctx->gb, ctx->cid_table->index_bits)<<6; } - if (ctx->ac_run_flag[index]) { + if (ctx->cid_table->ac_run_flag[index]) { index2 = get_vlc2(&ctx->gb, ctx->run_vlc.table, DNXHD_VLC_BITS, 2); - i += ctx->run[index2]; + i += ctx->cid_table->run[index2]; } - j = ctx->scantable.permutated[i]; - //av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j); - //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weigth %d\n", level, weigth_matrix[i]); - level = (2*level+1) * qscale * weigth_matrix[i]; - if (weigth_matrix[i] != 32) // FIXME 10bit - level += 32; - level >>= 6; - level = (level^sign) - sign; - if (i > 63) { av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i); return; } + j = ctx->scantable.permutated[i]; + //av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j); + //av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weigth %d\n", level, weigth_matrix[i]); + level = (2*level+1) * qscale * weigth_matrix[i]; + if (ctx->cid_table->bit_depth == 10) { + if (weigth_matrix[i] != 8) + level += 8; + level >>= 4; + } else { + if (weigth_matrix[i] != 32) + level += 32; + level >>= 6; + } //av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level); - block[j] = level; + block[j] = (level^sign) - sign; } } @@ -277,10 +230,22 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) for (i = 0; i < 8; i++) { dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale); } + + if (ctx->picture.interlaced_frame) { + dct_linesize_luma <<= 1; + dct_linesize_chroma <<= 1; + } + dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4); dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3); dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3); + if (ctx->cur_field) { + dest_y += ctx->picture.linesize[0]; + dest_u += ctx->picture.linesize[1]; + dest_v += ctx->picture.linesize[2]; + } + dct_offset = dct_linesize_luma << 3; ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]); ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]); @@ -298,11 +263,13 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) return 0; } -static int dnxhd_decode_macroblocks(DNXHDContext *ctx, uint8_t *buf, int buf_size) +static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int buf_size) { int x, y; for (y = 0; y < ctx->mb_height; y++) { - memset(ctx->last_dc, 4, sizeof(ctx->last_dc)); // 4 for levels +128 + ctx->last_dc[0] = + ctx->last_dc[1] = + ctx->last_dc[2] = 1<<(ctx->cid_table->bit_depth+2); // for levels +2^(bitdepth-1) init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3); for (x = 0; x < ctx->mb_width; x++) { //START_TIMER; @@ -314,14 +281,16 @@ static int dnxhd_decode_macroblocks(DNXHDContext *ctx, uint8_t *buf, int buf_siz } static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { DNXHDContext *ctx = avctx->priv_data; AVFrame *picture = data; + int first_field = 1; dprintf(avctx, "frame size %d\n", buf_size); - if (dnxhd_decode_header(ctx, buf, buf_size) < 0) + decode_coding_unit: + if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0) return -1; avctx->pix_fmt = PIX_FMT_YUV422P; @@ -329,15 +298,24 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, return -1; avcodec_set_dimensions(avctx, ctx->width, ctx->height); - if (ctx->picture.data[0]) - avctx->release_buffer(avctx, &ctx->picture); - if (avctx->get_buffer(avctx, &ctx->picture) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + if (first_field) { + if (ctx->picture.data[0]) + avctx->release_buffer(avctx, &ctx->picture); + if (avctx->get_buffer(avctx, &ctx->picture) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } } dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280); + if (first_field && ctx->picture.interlaced_frame) { + buf += ctx->cid_table->coding_unit_size; + buf_size -= ctx->cid_table->coding_unit_size; + first_field = 0; + goto decode_coding_unit; + } + *picture = ctx->picture; *data_size = sizeof(AVPicture); return buf_size; @@ -347,7 +325,7 @@ static int dnxhd_decode_close(AVCodecContext *avctx) { DNXHDContext *ctx = avctx->priv_data; - if(ctx->picture.data[0]) + if (ctx->picture.data[0]) avctx->release_buffer(avctx, &ctx->picture); free_vlc(&ctx->ac_vlc); free_vlc(&ctx->dc_vlc); diff --git a/contrib/ffmpeg/libavcodec/dnxhdenc.c b/contrib/ffmpeg/libavcodec/dnxhdenc.c new file mode 100644 index 000000000..3da6a1a67 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/dnxhdenc.c @@ -0,0 +1,847 @@ +/* + * VC3/DNxHD encoder + * Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at smartjog dot com> + * + * VC-3 encoder funded by the British Broadcasting Corporation + * + * 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 + */ + +//#define DEBUG +#define RC_VARIANCE 1 // use variance or ssd for fast rc + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "dnxhddata.h" + +typedef struct { + uint16_t mb; + int value; +} RCCMPEntry; + +typedef struct { + int ssd; + int bits; +} RCEntry; + +int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); + +typedef struct DNXHDEncContext { + MpegEncContext m; ///< Used for quantization dsp functions + + AVFrame frame; + int cid; + const CIDEntry *cid_table; + uint8_t *msip; ///< Macroblock Scan Indices Payload + uint32_t *slice_size; + + struct DNXHDEncContext *thread[MAX_THREADS]; + + unsigned dct_y_offset; + unsigned dct_uv_offset; + int interlaced; + int cur_field; + + DECLARE_ALIGNED_16(DCTELEM, blocks[8][64]); + + int (*qmatrix_c) [64]; + int (*qmatrix_l) [64]; + uint16_t (*qmatrix_l16)[2][64]; + uint16_t (*qmatrix_c16)[2][64]; + + unsigned frame_bits; + uint8_t *src[3]; + + uint16_t *table_vlc_codes; + uint8_t *table_vlc_bits; + uint16_t *table_run_codes; + uint8_t *table_run_bits; + + /** Rate control */ + unsigned slice_bits; + unsigned qscale; + unsigned lambda; + + unsigned thread_size; + + uint16_t *mb_bits; + uint8_t *mb_qscale; + + RCCMPEntry *mb_cmp; + RCEntry (*mb_rc)[8160]; +} DNXHDEncContext; + +#define LAMBDA_FRAC_BITS 10 + +static int dnxhd_init_vlc(DNXHDEncContext *ctx) +{ + int i; + + CHECKED_ALLOCZ(ctx->table_vlc_codes, 449*2); + CHECKED_ALLOCZ(ctx->table_vlc_bits, 449); + CHECKED_ALLOCZ(ctx->table_run_codes, 63*2); + CHECKED_ALLOCZ(ctx->table_run_bits, 63); + + for (i = 0; i < 257; i++) { + int level = ctx->cid_table->ac_level[i] + + (ctx->cid_table->ac_run_flag[i] << 7) + (ctx->cid_table->ac_index_flag[i] << 8); + assert(level < 449); + if (ctx->cid_table->ac_level[i] == 64 && ctx->cid_table->ac_index_flag[i]) + level -= 64; // use 0+(1<<8) level + ctx->table_vlc_codes[level] = ctx->cid_table->ac_codes[i]; + ctx->table_vlc_bits [level] = ctx->cid_table->ac_bits[i]; + } + for (i = 0; i < 62; i++) { + int run = ctx->cid_table->run[i]; + assert(run < 63); + ctx->table_run_codes[run] = ctx->cid_table->run_codes[i]; + ctx->table_run_bits [run] = ctx->cid_table->run_bits[i]; + } + return 0; + fail: + return -1; +} + +static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) +{ + // init first elem to 1 to avoid div by 0 in convert_matrix + uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t* + int qscale, i; + + CHECKED_ALLOCZ(ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int)); + CHECKED_ALLOCZ(ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int)); + CHECKED_ALLOCZ(ctx->qmatrix_l16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t)); + CHECKED_ALLOCZ(ctx->qmatrix_c16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t)); + + for (i = 1; i < 64; i++) { + int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; + weight_matrix[j] = ctx->cid_table->luma_weight[i]; + } + ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix, + ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); + for (i = 1; i < 64; i++) { + int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]]; + weight_matrix[j] = ctx->cid_table->chroma_weight[i]; + } + ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix, + ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1); + for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) { + for (i = 0; i < 64; i++) { + ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2; + ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2; + ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2; + } + } + return 0; + fail: + return -1; +} + +static int dnxhd_init_rc(DNXHDEncContext *ctx) +{ + CHECKED_ALLOCZ(ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry)); + if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) + CHECKED_ALLOCZ(ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry)); + + ctx->frame_bits = (ctx->cid_table->coding_unit_size - 640 - 4) * 8; + ctx->qscale = 1; + ctx->lambda = 2<<LAMBDA_FRAC_BITS; // qscale 2 + return 0; + fail: + return -1; +} + +static int dnxhd_encode_init(AVCodecContext *avctx) +{ + DNXHDEncContext *ctx = avctx->priv_data; + int i, index; + + ctx->cid = ff_dnxhd_find_cid(avctx); + if (!ctx->cid || avctx->pix_fmt != PIX_FMT_YUV422P) { + av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n"); + return -1; + } + av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid); + + index = ff_dnxhd_get_cid_table(ctx->cid); + ctx->cid_table = &ff_dnxhd_cid_table[index]; + + ctx->m.avctx = avctx; + ctx->m.mb_intra = 1; + ctx->m.h263_aic = 1; + + dsputil_init(&ctx->m.dsp, avctx); + ff_dct_common_init(&ctx->m); + if (!ctx->m.dct_quantize) + ctx->m.dct_quantize = dct_quantize_c; + + ctx->m.mb_height = (avctx->height + 15) / 16; + ctx->m.mb_width = (avctx->width + 15) / 16; + + if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) { + ctx->interlaced = 1; + ctx->m.mb_height /= 2; + } + + ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width; + + if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS) + ctx->m.intra_quant_bias = avctx->intra_quant_bias; + if (dnxhd_init_qmat(ctx, ctx->m.intra_quant_bias, 0) < 0) // XXX tune lbias/cbias + return -1; + + if (dnxhd_init_vlc(ctx) < 0) + return -1; + if (dnxhd_init_rc(ctx) < 0) + return -1; + + CHECKED_ALLOCZ(ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t)); + CHECKED_ALLOCZ(ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t)); + CHECKED_ALLOCZ(ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t)); + + ctx->frame.key_frame = 1; + ctx->frame.pict_type = FF_I_TYPE; + ctx->m.avctx->coded_frame = &ctx->frame; + + if (avctx->thread_count > MAX_THREADS || (avctx->thread_count > ctx->m.mb_height)) { + av_log(avctx, AV_LOG_ERROR, "too many threads\n"); + return -1; + } + + ctx->thread[0] = ctx; + for (i = 1; i < avctx->thread_count; i++) { + ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext)); + memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext)); + } + + for (i = 0; i < avctx->thread_count; i++) { + ctx->thread[i]->m.start_mb_y = (ctx->m.mb_height*(i ) + avctx->thread_count/2) / avctx->thread_count; + ctx->thread[i]->m.end_mb_y = (ctx->m.mb_height*(i+1) + avctx->thread_count/2) / avctx->thread_count; + } + + return 0; + fail: //for CHECKED_ALLOCZ + return -1; +} + +static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) +{ + DNXHDEncContext *ctx = avctx->priv_data; + const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 }; + + memcpy(buf, header_prefix, 5); + buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01; + buf[6] = 0x80; // crc flag off + buf[7] = 0xa0; // reserved + AV_WB16(buf + 0x18, avctx->height); // ALPF + AV_WB16(buf + 0x1a, avctx->width); // SPL + AV_WB16(buf + 0x1d, avctx->height); // NAL + + buf[0x21] = 0x38; // FIXME 8 bit per comp + buf[0x22] = 0x88 + (ctx->frame.interlaced_frame<<2); + AV_WB32(buf + 0x28, ctx->cid); // CID + buf[0x2c] = ctx->interlaced ? 0 : 0x80; + + buf[0x5f] = 0x01; // UDL + + buf[0x167] = 0x02; // reserved + AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS + buf[0x16d] = ctx->m.mb_height; // Ns + buf[0x16f] = 0x10; // reserved + + ctx->msip = buf + 0x170; + return 0; +} + +static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff) +{ + int nbits; + if (diff < 0) { + nbits = av_log2_16bit(-2*diff); + diff--; + } else { + nbits = av_log2_16bit(2*diff); + } + put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits, + (ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1))); +} + +static av_always_inline void dnxhd_encode_block(DNXHDEncContext *ctx, DCTELEM *block, int last_index, int n) +{ + int last_non_zero = 0; + int offset = 0; + int slevel, i, j; + + dnxhd_encode_dc(ctx, block[0] - ctx->m.last_dc[n]); + ctx->m.last_dc[n] = block[0]; + + for (i = 1; i <= last_index; i++) { + j = ctx->m.intra_scantable.permutated[i]; + slevel = block[j]; + if (slevel) { + int run_level = i - last_non_zero - 1; + int sign; + MASK_ABS(sign, slevel); + if (slevel > 64) { + offset = (slevel-1) >> 6; + slevel = 256 | (slevel & 63); // level 64 is treated as 0 + } + if (run_level) + slevel |= 128; + put_bits(&ctx->m.pb, ctx->table_vlc_bits[slevel]+1, (ctx->table_vlc_codes[slevel]<<1)|(sign&1)); + if (offset) { + put_bits(&ctx->m.pb, 4, offset); + offset = 0; + } + if (run_level) + put_bits(&ctx->m.pb, ctx->table_run_bits[run_level], ctx->table_run_codes[run_level]); + last_non_zero = i; + } + } + put_bits(&ctx->m.pb, ctx->table_vlc_bits[0], ctx->table_vlc_codes[0]); // EOB +} + +static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *block, int n, int qscale, int last_index) +{ + const uint8_t *weight_matrix; + int level; + int i; + + weight_matrix = (n&2) ? ctx->cid_table->chroma_weight : ctx->cid_table->luma_weight; + + for (i = 1; i <= last_index; i++) { + int j = ctx->m.intra_scantable.permutated[i]; + level = block[j]; + if (level) { + if (level < 0) { + level = (1-2*level) * qscale * weight_matrix[i]; + if (weight_matrix[i] != 32) + level += 32; + level >>= 6; + level = -level; + } else { + level = (2*level+1) * qscale * weight_matrix[i]; + if (weight_matrix[i] != 32) + level += 32; + level >>= 6; + } + block[j] = level; + } + } +} + +static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block) +{ + int score = 0; + int i; + for (i = 0; i < 64; i++) + score += (block[i]-qblock[i])*(block[i]-qblock[i]); + return score; +} + +static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *block, int last_index) +{ + int last_non_zero = 0; + int bits = 0; + int i, j, level; + for (i = 1; i <= last_index; i++) { + j = ctx->m.intra_scantable.permutated[i]; + level = block[j]; + if (level) { + int run_level = i - last_non_zero - 1; + level = FFABS(level); + if (level > 64) { + level = 256 | (level & 63); // level 64 is treated as 0 + bits += 4; + } + level |= (!!run_level)<<7; + bits += ctx->table_vlc_bits[level]+1 + ctx->table_run_bits[run_level]; + last_non_zero = i; + } + } + return bits; +} + +static av_always_inline void dnxhd_get_pixels_4x8(DCTELEM *restrict block, const uint8_t *pixels, int line_size) +{ + int i; + for (i = 0; i < 4; i++) { + block[0] = pixels[0]; + block[1] = pixels[1]; + block[2] = pixels[2]; + block[3] = pixels[3]; + block[4] = pixels[4]; + block[5] = pixels[5]; + block[6] = pixels[6]; + block[7] = pixels[7]; + pixels += line_size; + block += 8; + } + memcpy(block , block- 8, sizeof(*block)*8); + memcpy(block+ 8, block-16, sizeof(*block)*8); + memcpy(block+16, block-24, sizeof(*block)*8); + memcpy(block+24, block-32, sizeof(*block)*8); +} + +static av_always_inline void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y) +{ + const uint8_t *ptr_y = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize) + (mb_x << 4); + const uint8_t *ptr_u = ctx->thread[0]->src[1] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3); + const uint8_t *ptr_v = ctx->thread[0]->src[2] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3); + DSPContext *dsp = &ctx->m.dsp; + + dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize); + dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize); + dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize); + dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize); + + if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) { + if (ctx->interlaced) { + dnxhd_get_pixels_4x8(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize); + dnxhd_get_pixels_4x8(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize); + dnxhd_get_pixels_4x8(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize); + dnxhd_get_pixels_4x8(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize); + } else + memset(ctx->blocks[4], 0, 4*64*sizeof(DCTELEM)); + } else { + dsp->get_pixels(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize); + dsp->get_pixels(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize); + dsp->get_pixels(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize); + dsp->get_pixels(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize); + } +} + +static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i) +{ + if (i&2) { + ctx->m.q_intra_matrix16 = ctx->qmatrix_c16; + ctx->m.q_intra_matrix = ctx->qmatrix_c; + return 1 + (i&1); + } else { + ctx->m.q_intra_matrix16 = ctx->qmatrix_l16; + ctx->m.q_intra_matrix = ctx->qmatrix_l; + return 0; + } +} + +static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg) +{ + DNXHDEncContext *ctx = arg; + int mb_y, mb_x; + int qscale = ctx->thread[0]->qscale; + + for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) { + ctx->m.last_dc[0] = + ctx->m.last_dc[1] = + ctx->m.last_dc[2] = 1024; + + for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { + unsigned mb = mb_y * ctx->m.mb_width + mb_x; + int ssd = 0; + int ac_bits = 0; + int dc_bits = 0; + int i; + + dnxhd_get_blocks(ctx, mb_x, mb_y); + + for (i = 0; i < 8; i++) { + DECLARE_ALIGNED_16(DCTELEM, block[64]); + DCTELEM *src_block = ctx->blocks[i]; + int overflow, nbits, diff, last_index; + int n = dnxhd_switch_matrix(ctx, i); + + memcpy(block, src_block, sizeof(block)); + last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow); + ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index); + + diff = block[0] - ctx->m.last_dc[n]; + if (diff < 0) nbits = av_log2_16bit(-2*diff); + else nbits = av_log2_16bit( 2*diff); + dc_bits += ctx->cid_table->dc_bits[nbits] + nbits; + + ctx->m.last_dc[n] = block[0]; + + if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) { + dnxhd_unquantize_c(ctx, block, i, qscale, last_index); + ctx->m.dsp.idct(block); + ssd += dnxhd_ssd_block(block, src_block); + } + } + ctx->mb_rc[qscale][mb].ssd = ssd; + ctx->mb_rc[qscale][mb].bits = ac_bits+dc_bits+12+8*ctx->table_vlc_bits[0]; + } + } + return 0; +} + +static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg) +{ + DNXHDEncContext *ctx = arg; + int mb_y, mb_x; + + for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) { + ctx->m.last_dc[0] = + ctx->m.last_dc[1] = + ctx->m.last_dc[2] = 1024; + for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { + unsigned mb = mb_y * ctx->m.mb_width + mb_x; + int qscale = ctx->mb_qscale[mb]; + int i; + + put_bits(&ctx->m.pb, 12, qscale<<1); + + dnxhd_get_blocks(ctx, mb_x, mb_y); + + for (i = 0; i < 8; i++) { + DCTELEM *block = ctx->blocks[i]; + int last_index, overflow; + int n = dnxhd_switch_matrix(ctx, i); + last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow); + dnxhd_encode_block(ctx, block, last_index, n); + } + } + if (put_bits_count(&ctx->m.pb)&31) + put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0); + } + flush_put_bits(&ctx->m.pb); + return 0; +} + +static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx, uint8_t *buf) +{ + int mb_y, mb_x; + int i, offset = 0; + for (i = 0; i < ctx->m.avctx->thread_count; i++) { + int thread_size = 0; + for (mb_y = ctx->thread[i]->m.start_mb_y; mb_y < ctx->thread[i]->m.end_mb_y; mb_y++) { + ctx->slice_size[mb_y] = 0; + for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { + unsigned mb = mb_y * ctx->m.mb_width + mb_x; + ctx->slice_size[mb_y] += ctx->mb_bits[mb]; + } + ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31; + ctx->slice_size[mb_y] >>= 3; + thread_size += ctx->slice_size[mb_y]; + } + init_put_bits(&ctx->thread[i]->m.pb, buf + 640 + offset, thread_size); + offset += thread_size; + } +} + +static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg) +{ + DNXHDEncContext *ctx = arg; + int mb_y, mb_x; + for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) { + for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) { + unsigned mb = mb_y * ctx->m.mb_width + mb_x; + uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize) + (mb_x<<4); + int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize); + int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)(sum*sum))>>8)+128)>>8; + ctx->mb_cmp[mb].value = varc; + ctx->mb_cmp[mb].mb = mb; + } + } + return 0; +} + +static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx) +{ + int lambda, up_step, down_step; + int last_lower = INT_MAX, last_higher = 0; + int x, y, q; + + for (q = 1; q < avctx->qmax; q++) { + ctx->qscale = q; + avctx->execute(avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count); + } + up_step = down_step = 2<<LAMBDA_FRAC_BITS; + lambda = ctx->lambda; + + for (;;) { + int bits = 0; + int end = 0; + if (lambda == last_higher) { + lambda++; + end = 1; // need to set final qscales/bits + } + for (y = 0; y < ctx->m.mb_height; y++) { + for (x = 0; x < ctx->m.mb_width; x++) { + unsigned min = UINT_MAX; + int qscale = 1; + int mb = y*ctx->m.mb_width+x; + for (q = 1; q < avctx->qmax; q++) { + unsigned score = ctx->mb_rc[q][mb].bits*lambda+(ctx->mb_rc[q][mb].ssd<<LAMBDA_FRAC_BITS); + if (score < min) { + min = score; + qscale = q; + } + } + bits += ctx->mb_rc[qscale][mb].bits; + ctx->mb_qscale[mb] = qscale; + ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits; + } + bits = (bits+31)&~31; // padding + if (bits > ctx->frame_bits) + break; + } + //dprintf(ctx->m.avctx, "lambda %d, up %u, down %u, bits %d, frame %d\n", + // lambda, last_higher, last_lower, bits, ctx->frame_bits); + if (end) { + if (bits > ctx->frame_bits) + return -1; + break; + } + if (bits < ctx->frame_bits) { + last_lower = FFMIN(lambda, last_lower); + if (last_higher != 0) + lambda = (lambda+last_higher)>>1; + else + lambda -= down_step; + down_step *= 5; // XXX tune ? + up_step = 1<<LAMBDA_FRAC_BITS; + lambda = FFMAX(1, lambda); + if (lambda == last_lower) + break; + } else { + last_higher = FFMAX(lambda, last_higher); + if (last_lower != INT_MAX) + lambda = (lambda+last_lower)>>1; + else + lambda += up_step; + up_step *= 5; + down_step = 1<<LAMBDA_FRAC_BITS; + } + } + //dprintf(ctx->m.avctx, "out lambda %d\n", lambda); + ctx->lambda = lambda; + return 0; +} + +static int dnxhd_find_qscale(DNXHDEncContext *ctx) +{ + int bits = 0; + int up_step = 1; + int down_step = 1; + int last_higher = 0; + int last_lower = INT_MAX; + int qscale; + int x, y; + + qscale = ctx->qscale; + for (;;) { + bits = 0; + ctx->qscale = qscale; + // XXX avoid recalculating bits + ctx->m.avctx->execute(ctx->m.avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, ctx->m.avctx->thread_count); + for (y = 0; y < ctx->m.mb_height; y++) { + for (x = 0; x < ctx->m.mb_width; x++) + bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits; + bits = (bits+31)&~31; // padding + if (bits > ctx->frame_bits) + break; + } + //dprintf(ctx->m.avctx, "%d, qscale %d, bits %d, frame %d, higher %d, lower %d\n", + // ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower); + if (bits < ctx->frame_bits) { + if (qscale == 1) + return 1; + if (last_higher == qscale - 1) { + qscale = last_higher; + break; + } + last_lower = FFMIN(qscale, last_lower); + if (last_higher != 0) + qscale = (qscale+last_higher)>>1; + else + qscale -= down_step++; + if (qscale < 1) + qscale = 1; + up_step = 1; + } else { + if (last_lower == qscale + 1) + break; + last_higher = FFMAX(qscale, last_higher); + if (last_lower != INT_MAX) + qscale = (qscale+last_lower)>>1; + else + qscale += up_step++; + down_step = 1; + if (qscale >= ctx->m.avctx->qmax) + return -1; + } + } + //dprintf(ctx->m.avctx, "out qscale %d\n", qscale); + ctx->qscale = qscale; + return 0; +} + +static int dnxhd_rc_cmp(const void *a, const void *b) +{ + return ((const RCCMPEntry *)b)->value - ((const RCCMPEntry *)a)->value; +} + +static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx) +{ + int max_bits = 0; + int ret, x, y; + if ((ret = dnxhd_find_qscale(ctx)) < 0) + return -1; + for (y = 0; y < ctx->m.mb_height; y++) { + for (x = 0; x < ctx->m.mb_width; x++) { + int mb = y*ctx->m.mb_width+x; + int delta_bits; + ctx->mb_qscale[mb] = ctx->qscale; + ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits; + max_bits += ctx->mb_rc[ctx->qscale][mb].bits; + if (!RC_VARIANCE) { + delta_bits = ctx->mb_rc[ctx->qscale][mb].bits-ctx->mb_rc[ctx->qscale+1][mb].bits; + ctx->mb_cmp[mb].mb = mb; + ctx->mb_cmp[mb].value = delta_bits ? + ((ctx->mb_rc[ctx->qscale][mb].ssd-ctx->mb_rc[ctx->qscale+1][mb].ssd)*100)/delta_bits + : INT_MIN; //avoid increasing qscale + } + } + max_bits += 31; //worst padding + } + if (!ret) { + if (RC_VARIANCE) + avctx->execute(avctx, dnxhd_mb_var_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count); + qsort(ctx->mb_cmp, ctx->m.mb_num, sizeof(RCEntry), dnxhd_rc_cmp); + for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) { + int mb = ctx->mb_cmp[x].mb; + max_bits -= ctx->mb_rc[ctx->qscale][mb].bits - ctx->mb_rc[ctx->qscale+1][mb].bits; + ctx->mb_qscale[mb] = ctx->qscale+1; + ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits; + } + } + return 0; +} + +static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame) +{ + int i; + + for (i = 0; i < 3; i++) { + ctx->frame.data[i] = frame->data[i]; + ctx->frame.linesize[i] = frame->linesize[i]; + } + + for (i = 0; i < ctx->m.avctx->thread_count; i++) { + ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<<ctx->interlaced; + ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<<ctx->interlaced; + ctx->thread[i]->dct_y_offset = ctx->m.linesize *8; + ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8; + } + + ctx->frame.interlaced_frame = frame->interlaced_frame; + ctx->cur_field = frame->interlaced_frame && !frame->top_field_first; +} + +static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, const void *data) +{ + DNXHDEncContext *ctx = avctx->priv_data; + int first_field = 1; + int offset, i, ret; + + if (buf_size < ctx->cid_table->frame_size) { + av_log(avctx, AV_LOG_ERROR, "output buffer is too small to compress picture\n"); + return -1; + } + + dnxhd_load_picture(ctx, data); + + encode_coding_unit: + for (i = 0; i < 3; i++) { + ctx->src[i] = ctx->frame.data[i]; + if (ctx->interlaced && ctx->cur_field) + ctx->src[i] += ctx->frame.linesize[i]; + } + + dnxhd_write_header(avctx, buf); + + if (avctx->mb_decision == FF_MB_DECISION_RD) + ret = dnxhd_encode_rdo(avctx, ctx); + else + ret = dnxhd_encode_fast(avctx, ctx); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "picture could not fit ratecontrol constraints\n"); + return -1; + } + + dnxhd_setup_threads_slices(ctx, buf); + + offset = 0; + for (i = 0; i < ctx->m.mb_height; i++) { + AV_WB32(ctx->msip + i * 4, offset); + offset += ctx->slice_size[i]; + assert(!(ctx->slice_size[i] & 3)); + } + + avctx->execute(avctx, dnxhd_encode_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count); + + AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF + + if (ctx->interlaced && first_field) { + first_field = 0; + ctx->cur_field ^= 1; + buf += ctx->cid_table->coding_unit_size; + buf_size -= ctx->cid_table->coding_unit_size; + goto encode_coding_unit; + } + + return ctx->cid_table->frame_size; +} + +static int dnxhd_encode_end(AVCodecContext *avctx) +{ + DNXHDEncContext *ctx = avctx->priv_data; + int i; + + av_freep(&ctx->table_vlc_codes); + av_freep(&ctx->table_vlc_bits); + av_freep(&ctx->table_run_codes); + av_freep(&ctx->table_run_bits); + + av_freep(&ctx->mb_bits); + av_freep(&ctx->mb_qscale); + av_freep(&ctx->mb_rc); + av_freep(&ctx->mb_cmp); + av_freep(&ctx->slice_size); + + av_freep(&ctx->qmatrix_c); + av_freep(&ctx->qmatrix_l); + av_freep(&ctx->qmatrix_c16); + av_freep(&ctx->qmatrix_l16); + + for (i = 1; i < avctx->thread_count; i++) + av_freep(&ctx->thread[i]); + + return 0; +} + +AVCodec dnxhd_encoder = { + "dnxhd", + CODEC_TYPE_VIDEO, + CODEC_ID_DNXHD, + sizeof(DNXHDEncContext), + dnxhd_encode_init, + dnxhd_encode_picture, + dnxhd_encode_end, + .pix_fmts = (enum PixelFormat[]){PIX_FMT_YUV422P, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/dpcm.c b/contrib/ffmpeg/libavcodec/dpcm.c index 6243881de..01dd5cce0 100644 --- a/contrib/ffmpeg/libavcodec/dpcm.c +++ b/contrib/ffmpeg/libavcodec/dpcm.c @@ -46,8 +46,6 @@ typedef struct DPCMContext { const int *sol_table;//for SOL_DPCM } DPCMContext; -#define SATURATE_S16(x) if (x < -32768) x = -32768; \ - else if (x > 32767) x = 32767; #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; static int interplay_delta_table[] = { @@ -161,7 +159,7 @@ static int dpcm_decode_init(AVCodecContext *avctx) static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { DPCMContext *s = avctx->priv_data; int in, out = 0; @@ -175,6 +173,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, if (!buf_size) return 0; + // almost every DPCM variant expands one byte of data into two + if(*data_size/2 < buf_size) + return -1; + switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: @@ -190,7 +192,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, /* decode the samples */ for (in = 8, out = 0; in < buf_size; in++, out++) { predictor[channel_number] += s->roq_square_array[buf[in]]; - SATURATE_S16(predictor[channel_number]); + predictor[channel_number] = av_clip_int16(predictor[channel_number]); output_samples[out] = predictor[channel_number]; /* toggle channel */ @@ -213,7 +215,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, while (in < buf_size) { predictor[channel_number] += interplay_delta_table[buf[in++]]; - SATURATE_S16(predictor[channel_number]); + predictor[channel_number] = av_clip_int16(predictor[channel_number]); output_samples[out++] = predictor[channel_number]; /* toggle channel */ @@ -248,7 +250,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, diff >>= shift[channel_number]; predictor[channel_number] += diff; - SATURATE_S16(predictor[channel_number]); + predictor[channel_number] = av_clip_int16(predictor[channel_number]); output_samples[out++] = predictor[channel_number]; /* toggle channel */ @@ -258,6 +260,8 @@ static int dpcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_SOL_DPCM: in = 0; if (avctx->codec_tag != 3) { + if(*data_size/4 < buf_size) + return -1; while (in < buf_size) { int n1, n2; n1 = (buf[in] >> 4) & 0xF; @@ -277,7 +281,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, n = buf[in++]; if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F]; else s->sample[channel_number] += s->sol_table[n & 0x7F]; - SATURATE_S16(s->sample[channel_number]); + s->sample[channel_number] = av_clip_int16(s->sample[channel_number]); output_samples[out++] = s->sample[channel_number]; /* toggle channel */ channel_number ^= s->channels - 1; @@ -290,46 +294,19 @@ static int dpcm_decode_frame(AVCodecContext *avctx, return buf_size; } -AVCodec roq_dpcm_decoder = { - "roq_dpcm", - CODEC_TYPE_AUDIO, - CODEC_ID_ROQ_DPCM, - sizeof(DPCMContext), - dpcm_decode_init, - NULL, - NULL, - dpcm_decode_frame, -}; - -AVCodec interplay_dpcm_decoder = { - "interplay_dpcm", - CODEC_TYPE_AUDIO, - CODEC_ID_INTERPLAY_DPCM, - sizeof(DPCMContext), - dpcm_decode_init, - NULL, - NULL, - dpcm_decode_frame, +#define DPCM_DECODER(id, name) \ +AVCodec name ## _decoder = { \ + #name, \ + CODEC_TYPE_AUDIO, \ + id, \ + sizeof(DPCMContext), \ + dpcm_decode_init, \ + NULL, \ + NULL, \ + dpcm_decode_frame, \ }; -AVCodec xan_dpcm_decoder = { - "xan_dpcm", - CODEC_TYPE_AUDIO, - CODEC_ID_XAN_DPCM, - sizeof(DPCMContext), - dpcm_decode_init, - NULL, - NULL, - dpcm_decode_frame, -}; - -AVCodec sol_dpcm_decoder = { - "sol_dpcm", - CODEC_TYPE_AUDIO, - CODEC_ID_SOL_DPCM, - sizeof(DPCMContext), - dpcm_decode_init, - NULL, - NULL, - dpcm_decode_frame, -}; +DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm); +DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm); +DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm); +DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm); diff --git a/contrib/ffmpeg/libavcodec/dsicinav.c b/contrib/ffmpeg/libavcodec/dsicinav.c index c7c3f5627..e549487c7 100644 --- a/contrib/ffmpeg/libavcodec/dsicinav.c +++ b/contrib/ffmpeg/libavcodec/dsicinav.c @@ -25,7 +25,7 @@ */ #include "avcodec.h" -#include "common.h" +#include "bytestream.h" typedef enum CinVideoBitmapIndex { @@ -88,12 +88,11 @@ static const int16_t cinaudio_delta16_table[256] = { static int cinvideo_decode_init(AVCodecContext *avctx) { - CinVideoContext *cin = (CinVideoContext *)avctx->priv_data; + CinVideoContext *cin = avctx->priv_data; unsigned int i; cin->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; cin->frame.data[0] = NULL; @@ -196,9 +195,9 @@ static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char static int cinvideo_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - CinVideoContext *cin = (CinVideoContext *)avctx->priv_data; + CinVideoContext *cin = avctx->priv_data; int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size; cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; @@ -208,7 +207,7 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, } palette_type = buf[0]; - palette_colors_count = buf[1] | (buf[2] << 8); + palette_colors_count = AV_RL16(buf+1); bitmap_frame_type = buf[3]; buf += 4; @@ -217,13 +216,12 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, /* handle palette */ if (palette_type == 0) { for (i = 0; i < palette_colors_count; ++i) { - cin->palette[i] = (buf[2] << 16) | (buf[1] << 8) | buf[0]; - buf += 3; + cin->palette[i] = bytestream_get_le24(&buf); bitmap_frame_size -= 3; } } else { for (i = 0; i < palette_colors_count; ++i) { - cin->palette[buf[0]] = (buf[3] << 16) | (buf[2] << 8) | buf[1]; + cin->palette[buf[0]] = AV_RL24(buf+1); buf += 4; bitmap_frame_size -= 4; } @@ -288,7 +286,7 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, static int cinvideo_decode_end(AVCodecContext *avctx) { - CinVideoContext *cin = (CinVideoContext *)avctx->priv_data; + CinVideoContext *cin = avctx->priv_data; int i; if (cin->frame.data[0]) @@ -302,7 +300,7 @@ static int cinvideo_decode_end(AVCodecContext *avctx) static int cinaudio_decode_init(AVCodecContext *avctx) { - CinAudioContext *cin = (CinAudioContext *)avctx->priv_data; + CinAudioContext *cin = avctx->priv_data; cin->avctx = avctx; cin->initial_decode_frame = 1; @@ -313,12 +311,14 @@ static int cinaudio_decode_init(AVCodecContext *avctx) static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - CinAudioContext *cin = (CinAudioContext *)avctx->priv_data; - uint8_t *src = buf; + CinAudioContext *cin = avctx->priv_data; + const uint8_t *src = buf; int16_t *samples = (int16_t *)data; + buf_size = FFMIN(buf_size, *data_size/2); + if (cin->initial_decode_frame) { cin->initial_decode_frame = 0; cin->delta = (int16_t)AV_RL16(src); src += 2; @@ -327,7 +327,7 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, } while (buf_size > 0) { cin->delta += cinaudio_delta16_table[*src++]; - cin->delta = av_clip(cin->delta, -32768, 32767); + cin->delta = av_clip_int16(cin->delta); *samples++ = cin->delta; --buf_size; } diff --git a/contrib/ffmpeg/libavcodec/dsputil.c b/contrib/ffmpeg/libavcodec/dsputil.c index 3f5e845e7..055486d49 100644 --- a/contrib/ffmpeg/libavcodec/dsputil.c +++ b/contrib/ffmpeg/libavcodec/dsputil.c @@ -3,6 +3,8 @@ * Copyright (c) 2000, 2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * + * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,8 +20,6 @@ * 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 - * - * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at> */ /** @@ -32,6 +32,8 @@ #include "mpegvideo.h" #include "simple_idct.h" #include "faandct.h" +#include "faanidct.h" +#include "h263.h" #include "snow.h" /* snow.c */ @@ -40,9 +42,19 @@ void ff_spatial_dwt(int *buffer, int width, int height, int stride, int type, in /* vorbis.c */ void vorbis_inverse_coupling(float *mag, float *ang, int blocksize); +/* flacenc.c */ +void ff_flac_compute_autocorr(const int32_t *data, int len, int lag, double *autoc); + +/* pngdec.c */ +void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); + uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; uint32_t ff_squareTbl[512] = {0, }; +// 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size +#define pb_7f (~0UL/255 * 0x7f) +#define pb_80 (~0UL/255 * 0x80) + const uint8_t ff_zigzag_direct[64] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, @@ -210,7 +222,7 @@ static int pix_norm1_c(uint8_t * pix, int line_size) return s; } -static void bswap_buf(uint32_t *dst, uint32_t *src, int w){ +static void bswap_buf(uint32_t *dst, const uint32_t *src, int w){ int i; for(i=0; i+8<=w; i+=8){ @@ -592,6 +604,14 @@ static void add_pixels4_c(uint8_t *restrict pixels, DCTELEM *block, int line_siz } } +static int sum_abs_dctelem_c(DCTELEM *block) +{ + int sum=0, i; + for(i=0; i<64; i++) + sum+= FFABS(block[i]); + return sum; +} + #if 0 #define PIXOP2(OPNAME, OP) \ @@ -599,7 +619,7 @@ static void OPNAME ## _pixels(uint8_t *block, const uint8_t *pixels, int line_si {\ int i;\ for(i=0; i<h; i++){\ - OP(*((uint64_t*)block), LD64(pixels));\ + OP(*((uint64_t*)block), AV_RN64(pixels));\ pixels+=line_size;\ block +=line_size;\ }\ @@ -609,8 +629,8 @@ static void OPNAME ## _no_rnd_pixels_x2_c(uint8_t *block, const uint8_t *pixels, {\ int i;\ for(i=0; i<h; i++){\ - const uint64_t a= LD64(pixels );\ - const uint64_t b= LD64(pixels+1);\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+1);\ OP(*((uint64_t*)block), (a&b) + (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\ pixels+=line_size;\ block +=line_size;\ @@ -621,8 +641,8 @@ static void OPNAME ## _pixels_x2_c(uint8_t *block, const uint8_t *pixels, int li {\ int i;\ for(i=0; i<h; i++){\ - const uint64_t a= LD64(pixels );\ - const uint64_t b= LD64(pixels+1);\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+1);\ OP(*((uint64_t*)block), (a|b) - (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\ pixels+=line_size;\ block +=line_size;\ @@ -633,8 +653,8 @@ static void OPNAME ## _no_rnd_pixels_y2_c(uint8_t *block, const uint8_t *pixels, {\ int i;\ for(i=0; i<h; i++){\ - const uint64_t a= LD64(pixels );\ - const uint64_t b= LD64(pixels+line_size);\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+line_size);\ OP(*((uint64_t*)block), (a&b) + (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\ pixels+=line_size;\ block +=line_size;\ @@ -645,8 +665,8 @@ static void OPNAME ## _pixels_y2_c(uint8_t *block, const uint8_t *pixels, int li {\ int i;\ for(i=0; i<h; i++){\ - const uint64_t a= LD64(pixels );\ - const uint64_t b= LD64(pixels+line_size);\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+line_size);\ OP(*((uint64_t*)block), (a|b) - (((a^b)&0xFEFEFEFEFEFEFEFEULL)>>1));\ pixels+=line_size;\ block +=line_size;\ @@ -656,8 +676,8 @@ static void OPNAME ## _pixels_y2_c(uint8_t *block, const uint8_t *pixels, int li static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ {\ int i;\ - const uint64_t a= LD64(pixels );\ - const uint64_t b= LD64(pixels+1);\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+1);\ uint64_t l0= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL)\ + 0x0202020202020202ULL;\ @@ -667,8 +687,8 @@ static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int l \ pixels+=line_size;\ for(i=0; i<h; i+=2){\ - uint64_t a= LD64(pixels );\ - uint64_t b= LD64(pixels+1);\ + uint64_t a= AV_RN64(pixels );\ + uint64_t b= AV_RN64(pixels+1);\ l1= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL);\ h1= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ @@ -676,8 +696,8 @@ static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int l OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ pixels+=line_size;\ block +=line_size;\ - a= LD64(pixels );\ - b= LD64(pixels+1);\ + a= AV_RN64(pixels );\ + b= AV_RN64(pixels+1);\ l0= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL)\ + 0x0202020202020202ULL;\ @@ -692,8 +712,8 @@ static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int l static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ {\ int i;\ - const uint64_t a= LD64(pixels );\ - const uint64_t b= LD64(pixels+1);\ + const uint64_t a= AV_RN64(pixels );\ + const uint64_t b= AV_RN64(pixels+1);\ uint64_t l0= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL)\ + 0x0101010101010101ULL;\ @@ -703,8 +723,8 @@ static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels \ pixels+=line_size;\ for(i=0; i<h; i+=2){\ - uint64_t a= LD64(pixels );\ - uint64_t b= LD64(pixels+1);\ + uint64_t a= AV_RN64(pixels );\ + uint64_t b= AV_RN64(pixels+1);\ l1= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL);\ h1= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ @@ -712,8 +732,8 @@ static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ pixels+=line_size;\ block +=line_size;\ - a= LD64(pixels );\ - b= LD64(pixels+1);\ + a= AV_RN64(pixels );\ + b= AV_RN64(pixels+1);\ l0= (a&0x0303030303030303ULL)\ + (b&0x0303030303030303ULL)\ + 0x0101010101010101ULL;\ @@ -740,7 +760,7 @@ CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_c, OPNAME ## _no_rnd_pixels_xy2_c, static void OPNAME ## _pixels2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ int i;\ for(i=0; i<h; i++){\ - OP(*((uint16_t*)(block )), LD16(pixels ));\ + OP(*((uint16_t*)(block )), AV_RN16(pixels ));\ pixels+=line_size;\ block +=line_size;\ }\ @@ -748,7 +768,7 @@ static void OPNAME ## _pixels2_c(uint8_t *block, const uint8_t *pixels, int line static void OPNAME ## _pixels4_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ int i;\ for(i=0; i<h; i++){\ - OP(*((uint32_t*)(block )), LD32(pixels ));\ + OP(*((uint32_t*)(block )), AV_RN32(pixels ));\ pixels+=line_size;\ block +=line_size;\ }\ @@ -756,8 +776,8 @@ static void OPNAME ## _pixels4_c(uint8_t *block, const uint8_t *pixels, int line static void OPNAME ## _pixels8_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ int i;\ for(i=0; i<h; i++){\ - OP(*((uint32_t*)(block )), LD32(pixels ));\ - OP(*((uint32_t*)(block+4)), LD32(pixels+4));\ + OP(*((uint32_t*)(block )), AV_RN32(pixels ));\ + OP(*((uint32_t*)(block+4)), AV_RN32(pixels+4));\ pixels+=line_size;\ block +=line_size;\ }\ @@ -771,11 +791,11 @@ static inline void OPNAME ## _no_rnd_pixels8_l2(uint8_t *dst, const uint8_t *src int i;\ for(i=0; i<h; i++){\ uint32_t a,b;\ - a= LD32(&src1[i*src_stride1 ]);\ - b= LD32(&src2[i*src_stride2 ]);\ + a= AV_RN32(&src1[i*src_stride1 ]);\ + b= AV_RN32(&src2[i*src_stride2 ]);\ OP(*((uint32_t*)&dst[i*dst_stride ]), no_rnd_avg32(a, b));\ - a= LD32(&src1[i*src_stride1+4]);\ - b= LD32(&src2[i*src_stride2+4]);\ + a= AV_RN32(&src1[i*src_stride1+4]);\ + b= AV_RN32(&src2[i*src_stride2+4]);\ OP(*((uint32_t*)&dst[i*dst_stride+4]), no_rnd_avg32(a, b));\ }\ }\ @@ -785,11 +805,11 @@ static inline void OPNAME ## _pixels8_l2(uint8_t *dst, const uint8_t *src1, cons int i;\ for(i=0; i<h; i++){\ uint32_t a,b;\ - a= LD32(&src1[i*src_stride1 ]);\ - b= LD32(&src2[i*src_stride2 ]);\ + a= AV_RN32(&src1[i*src_stride1 ]);\ + b= AV_RN32(&src2[i*src_stride2 ]);\ OP(*((uint32_t*)&dst[i*dst_stride ]), rnd_avg32(a, b));\ - a= LD32(&src1[i*src_stride1+4]);\ - b= LD32(&src2[i*src_stride2+4]);\ + a= AV_RN32(&src1[i*src_stride1+4]);\ + b= AV_RN32(&src2[i*src_stride2+4]);\ OP(*((uint32_t*)&dst[i*dst_stride+4]), rnd_avg32(a, b));\ }\ }\ @@ -799,8 +819,8 @@ static inline void OPNAME ## _pixels4_l2(uint8_t *dst, const uint8_t *src1, cons int i;\ for(i=0; i<h; i++){\ uint32_t a,b;\ - a= LD32(&src1[i*src_stride1 ]);\ - b= LD32(&src2[i*src_stride2 ]);\ + a= AV_RN32(&src1[i*src_stride1 ]);\ + b= AV_RN32(&src2[i*src_stride2 ]);\ OP(*((uint32_t*)&dst[i*dst_stride ]), rnd_avg32(a, b));\ }\ }\ @@ -810,8 +830,8 @@ static inline void OPNAME ## _pixels2_l2(uint8_t *dst, const uint8_t *src1, cons int i;\ for(i=0; i<h; i++){\ uint32_t a,b;\ - a= LD16(&src1[i*src_stride1 ]);\ - b= LD16(&src2[i*src_stride2 ]);\ + a= AV_RN16(&src1[i*src_stride1 ]);\ + b= AV_RN16(&src2[i*src_stride2 ]);\ OP(*((uint16_t*)&dst[i*dst_stride ]), rnd_avg32(a, b));\ }\ }\ @@ -849,10 +869,10 @@ static inline void OPNAME ## _pixels8_l4(uint8_t *dst, const uint8_t *src1, uint int i;\ for(i=0; i<h; i++){\ uint32_t a, b, c, d, l0, l1, h0, h1;\ - a= LD32(&src1[i*src_stride1]);\ - b= LD32(&src2[i*src_stride2]);\ - c= LD32(&src3[i*src_stride3]);\ - d= LD32(&src4[i*src_stride4]);\ + a= AV_RN32(&src1[i*src_stride1]);\ + b= AV_RN32(&src2[i*src_stride2]);\ + c= AV_RN32(&src3[i*src_stride3]);\ + d= AV_RN32(&src4[i*src_stride4]);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -863,10 +883,10 @@ static inline void OPNAME ## _pixels8_l4(uint8_t *dst, const uint8_t *src1, uint h1= ((c&0xFCFCFCFCUL)>>2)\ + ((d&0xFCFCFCFCUL)>>2);\ OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ - a= LD32(&src1[i*src_stride1+4]);\ - b= LD32(&src2[i*src_stride2+4]);\ - c= LD32(&src3[i*src_stride3+4]);\ - d= LD32(&src4[i*src_stride4+4]);\ + a= AV_RN32(&src1[i*src_stride1+4]);\ + b= AV_RN32(&src2[i*src_stride2+4]);\ + c= AV_RN32(&src3[i*src_stride3+4]);\ + d= AV_RN32(&src4[i*src_stride4+4]);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -901,10 +921,10 @@ static inline void OPNAME ## _no_rnd_pixels8_l4(uint8_t *dst, const uint8_t *src int i;\ for(i=0; i<h; i++){\ uint32_t a, b, c, d, l0, l1, h0, h1;\ - a= LD32(&src1[i*src_stride1]);\ - b= LD32(&src2[i*src_stride2]);\ - c= LD32(&src3[i*src_stride3]);\ - d= LD32(&src4[i*src_stride4]);\ + a= AV_RN32(&src1[i*src_stride1]);\ + b= AV_RN32(&src2[i*src_stride2]);\ + c= AV_RN32(&src3[i*src_stride3]);\ + d= AV_RN32(&src4[i*src_stride4]);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x01010101UL;\ @@ -915,10 +935,10 @@ static inline void OPNAME ## _no_rnd_pixels8_l4(uint8_t *dst, const uint8_t *src h1= ((c&0xFCFCFCFCUL)>>2)\ + ((d&0xFCFCFCFCUL)>>2);\ OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ - a= LD32(&src1[i*src_stride1+4]);\ - b= LD32(&src2[i*src_stride2+4]);\ - c= LD32(&src3[i*src_stride3+4]);\ - d= LD32(&src4[i*src_stride4+4]);\ + a= AV_RN32(&src1[i*src_stride1+4]);\ + b= AV_RN32(&src2[i*src_stride2+4]);\ + c= AV_RN32(&src3[i*src_stride3+4]);\ + d= AV_RN32(&src4[i*src_stride4+4]);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x01010101UL;\ @@ -978,8 +998,8 @@ static inline void OPNAME ## _pixels2_xy2_c(uint8_t *block, const uint8_t *pixel static inline void OPNAME ## _pixels4_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ {\ int i;\ - const uint32_t a= LD32(pixels );\ - const uint32_t b= LD32(pixels+1);\ + const uint32_t a= AV_RN32(pixels );\ + const uint32_t b= AV_RN32(pixels+1);\ uint32_t l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -989,8 +1009,8 @@ static inline void OPNAME ## _pixels4_xy2_c(uint8_t *block, const uint8_t *pixel \ pixels+=line_size;\ for(i=0; i<h; i+=2){\ - uint32_t a= LD32(pixels );\ - uint32_t b= LD32(pixels+1);\ + uint32_t a= AV_RN32(pixels );\ + uint32_t b= AV_RN32(pixels+1);\ l1= (a&0x03030303UL)\ + (b&0x03030303UL);\ h1= ((a&0xFCFCFCFCUL)>>2)\ @@ -998,8 +1018,8 @@ static inline void OPNAME ## _pixels4_xy2_c(uint8_t *block, const uint8_t *pixel OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ pixels+=line_size;\ block +=line_size;\ - a= LD32(pixels );\ - b= LD32(pixels+1);\ + a= AV_RN32(pixels );\ + b= AV_RN32(pixels+1);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -1016,8 +1036,8 @@ static inline void OPNAME ## _pixels8_xy2_c(uint8_t *block, const uint8_t *pixel int j;\ for(j=0; j<2; j++){\ int i;\ - const uint32_t a= LD32(pixels );\ - const uint32_t b= LD32(pixels+1);\ + const uint32_t a= AV_RN32(pixels );\ + const uint32_t b= AV_RN32(pixels+1);\ uint32_t l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -1027,8 +1047,8 @@ static inline void OPNAME ## _pixels8_xy2_c(uint8_t *block, const uint8_t *pixel \ pixels+=line_size;\ for(i=0; i<h; i+=2){\ - uint32_t a= LD32(pixels );\ - uint32_t b= LD32(pixels+1);\ + uint32_t a= AV_RN32(pixels );\ + uint32_t b= AV_RN32(pixels+1);\ l1= (a&0x03030303UL)\ + (b&0x03030303UL);\ h1= ((a&0xFCFCFCFCUL)>>2)\ @@ -1036,8 +1056,8 @@ static inline void OPNAME ## _pixels8_xy2_c(uint8_t *block, const uint8_t *pixel OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ pixels+=line_size;\ block +=line_size;\ - a= LD32(pixels );\ - b= LD32(pixels+1);\ + a= AV_RN32(pixels );\ + b= AV_RN32(pixels+1);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x02020202UL;\ @@ -1057,8 +1077,8 @@ static inline void OPNAME ## _no_rnd_pixels8_xy2_c(uint8_t *block, const uint8_t int j;\ for(j=0; j<2; j++){\ int i;\ - const uint32_t a= LD32(pixels );\ - const uint32_t b= LD32(pixels+1);\ + const uint32_t a= AV_RN32(pixels );\ + const uint32_t b= AV_RN32(pixels+1);\ uint32_t l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x01010101UL;\ @@ -1068,8 +1088,8 @@ static inline void OPNAME ## _no_rnd_pixels8_xy2_c(uint8_t *block, const uint8_t \ pixels+=line_size;\ for(i=0; i<h; i+=2){\ - uint32_t a= LD32(pixels );\ - uint32_t b= LD32(pixels+1);\ + uint32_t a= AV_RN32(pixels );\ + uint32_t b= AV_RN32(pixels+1);\ l1= (a&0x03030303UL)\ + (b&0x03030303UL);\ h1= ((a&0xFCFCFCFCUL)>>2)\ @@ -1077,8 +1097,8 @@ static inline void OPNAME ## _no_rnd_pixels8_xy2_c(uint8_t *block, const uint8_t OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ pixels+=line_size;\ block +=line_size;\ - a= LD32(pixels );\ - b= LD32(pixels+1);\ + a= AV_RN32(pixels );\ + b= AV_RN32(pixels+1);\ l0= (a&0x03030303UL)\ + (b&0x03030303UL)\ + 0x01010101UL;\ @@ -1428,12 +1448,22 @@ static void OPNAME ## h264_chroma_mc2_c(uint8_t *dst/*align 8*/, uint8_t *src/*a \ assert(x<8 && y<8 && x>=0 && y>=0);\ \ - for(i=0; i<h; i++)\ - {\ - OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ - OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\ - dst+= stride;\ - src+= stride;\ + if(D){\ + for(i=0; i<h; i++){\ + OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ + OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\ + dst+= stride;\ + src+= stride;\ + }\ + }else{\ + const int E= B+C;\ + const int step= C ? stride : 1;\ + for(i=0; i<h; i++){\ + OP(dst[0], (A*src[0] + E*src[step+0]));\ + OP(dst[1], (A*src[1] + E*src[step+1]));\ + dst+= stride;\ + src+= stride;\ + }\ }\ }\ \ @@ -1446,14 +1476,26 @@ static void OPNAME ## h264_chroma_mc4_c(uint8_t *dst/*align 8*/, uint8_t *src/*a \ assert(x<8 && y<8 && x>=0 && y>=0);\ \ - for(i=0; i<h; i++)\ - {\ - OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ - OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\ - OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\ - OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\ - dst+= stride;\ - src+= stride;\ + if(D){\ + for(i=0; i<h; i++){\ + OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ + OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\ + OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\ + OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\ + dst+= stride;\ + src+= stride;\ + }\ + }else{\ + const int E= B+C;\ + const int step= C ? stride : 1;\ + for(i=0; i<h; i++){\ + OP(dst[0], (A*src[0] + E*src[step+0]));\ + OP(dst[1], (A*src[1] + E*src[step+1]));\ + OP(dst[2], (A*src[2] + E*src[step+2]));\ + OP(dst[3], (A*src[3] + E*src[step+3]));\ + dst+= stride;\ + src+= stride;\ + }\ }\ }\ \ @@ -1466,18 +1508,34 @@ static void OPNAME ## h264_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*a \ assert(x<8 && y<8 && x>=0 && y>=0);\ \ - for(i=0; i<h; i++)\ - {\ - OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ - OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\ - OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\ - OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\ - OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));\ - OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));\ - OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));\ - OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));\ - dst+= stride;\ - src+= stride;\ + if(D){\ + for(i=0; i<h; i++){\ + OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\ + OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\ + OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\ + OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\ + OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));\ + OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));\ + OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));\ + OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));\ + dst+= stride;\ + src+= stride;\ + }\ + }else{\ + const int E= B+C;\ + const int step= C ? stride : 1;\ + for(i=0; i<h; i++){\ + OP(dst[0], (A*src[0] + E*src[step+0]));\ + OP(dst[1], (A*src[1] + E*src[step+1]));\ + OP(dst[2], (A*src[2] + E*src[step+2]));\ + OP(dst[3], (A*src[3] + E*src[step+3]));\ + OP(dst[4], (A*src[4] + E*src[step+4]));\ + OP(dst[5], (A*src[5] + E*src[step+5]));\ + OP(dst[6], (A*src[6] + E*src[step+6]));\ + OP(dst[7], (A*src[7] + E*src[step+7]));\ + dst+= stride;\ + src+= stride;\ + }\ }\ } @@ -2012,7 +2070,7 @@ QPEL_MC(0, avg_ , _ , op_avg) #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){\ +static av_unused void OPNAME ## h264_qpel2_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ const int h=2;\ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i;\ @@ -2025,7 +2083,7 @@ static void OPNAME ## h264_qpel2_h_lowpass(uint8_t *dst, uint8_t *src, int dstSt }\ }\ \ -static void OPNAME ## h264_qpel2_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ +static av_unused void OPNAME ## h264_qpel2_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ const int w=2;\ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ int i;\ @@ -2045,7 +2103,7 @@ static void OPNAME ## h264_qpel2_v_lowpass(uint8_t *dst, uint8_t *src, int dstSt }\ }\ \ -static void OPNAME ## h264_qpel2_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ +static av_unused void OPNAME ## h264_qpel2_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ const int h=2;\ const int w=2;\ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ @@ -2549,10 +2607,10 @@ void ff_put_vc1_mspel_mc00_c(uint8_t *dst, uint8_t *src, int stride, int rnd) { } #endif /* CONFIG_VC1_DECODER||CONFIG_WMV3_DECODER */ -#if defined(CONFIG_H264_ENCODER) +void ff_intrax8dsp_init(DSPContext* c, AVCodecContext *avctx); + /* H264 specific */ -void ff_h264dsp_init(DSPContext* c, AVCodecContext *avctx); -#endif /* CONFIG_H264_ENCODER */ +void ff_h264dspenc_init(DSPContext* c, AVCodecContext *avctx); static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w){ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; @@ -2632,6 +2690,7 @@ static void put_mspel8_mc22_c(uint8_t *dst, uint8_t *src, int stride){ } static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale){ + if(ENABLE_ANY_H263) { int x; const int strength= ff_h263_loop_filter_strength[qscale]; @@ -2664,9 +2723,11 @@ static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale){ 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){ + if(ENABLE_ANY_H263) { int y; const int strength= ff_h263_loop_filter_strength[qscale]; @@ -2699,6 +2760,7 @@ static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){ src[y*stride-2] = p0 - d2; src[y*stride+1] = p3 + d2; } + } } static void h261_loop_filter_c(uint8_t *src, int stride){ @@ -3131,7 +3193,7 @@ void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scant DCTELEM temp[64]; if(last<=0) return; - //if(permutation[1]==1) return; //FIXME its ok but not clean and might fail for some perms + //if(permutation[1]==1) return; //FIXME it is ok but not clean and might fail for some permutations for(i=0; i<=last; i++){ const int j= scantable[i]; @@ -3219,32 +3281,47 @@ static void clear_blocks_c(DCTELEM *blocks) } static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){ - int i; - for(i=0; i+7<w; i+=8){ - dst[i+0] += src[i+0]; - dst[i+1] += src[i+1]; - dst[i+2] += src[i+2]; - dst[i+3] += src[i+3]; - dst[i+4] += src[i+4]; - dst[i+5] += src[i+5]; - dst[i+6] += src[i+6]; - dst[i+7] += src[i+7]; + long i; + for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + long a = *(long*)(src+i); + long b = *(long*)(dst+i); + *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80); } for(; i<w; i++) dst[i+0] += src[i+0]; } +static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ + long i; + for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + long a = *(long*)(src1+i); + long b = *(long*)(src2+i); + *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80); + } + for(; i<w; i++) + dst[i] = src1[i]+src2[i]; +} + static void diff_bytes_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ - int i; - for(i=0; i+7<w; i+=8){ - dst[i+0] = src1[i+0]-src2[i+0]; - dst[i+1] = src1[i+1]-src2[i+1]; - dst[i+2] = src1[i+2]-src2[i+2]; - dst[i+3] = src1[i+3]-src2[i+3]; - dst[i+4] = src1[i+4]-src2[i+4]; - dst[i+5] = src1[i+5]-src2[i+5]; - dst[i+6] = src1[i+6]-src2[i+6]; - dst[i+7] = src1[i+7]-src2[i+7]; + long i; +#ifndef HAVE_FAST_UNALIGNED + if((long)src2 & (sizeof(long)-1)){ + for(i=0; i+7<w; i+=8){ + dst[i+0] = src1[i+0]-src2[i+0]; + dst[i+1] = src1[i+1]-src2[i+1]; + dst[i+2] = src1[i+2]-src2[i+2]; + dst[i+3] = src1[i+3]-src2[i+3]; + dst[i+4] = src1[i+4]-src2[i+4]; + dst[i+5] = src1[i+5]-src2[i+5]; + dst[i+6] = src1[i+6]-src2[i+6]; + dst[i+7] = src1[i+7]-src2[i+7]; + } + }else +#endif + for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + long a = *(long*)(src1+i); + long b = *(long*)(src2+i); + *(long*)(dst+i) = ((a|pb_80) - (b&pb_7f)) ^ ((a^b^pb_80)&pb_80); } for(; i<w; i++) dst[i+0] = src1[i+0]-src2[i+0]; @@ -3385,19 +3462,14 @@ static int hadamard8_intra8x8_c(/*MpegEncContext*/ void *s, uint8_t *src, uint8_ 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]); + DECLARE_ALIGNED_16(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; + return s->dsp.sum_abs_dctelem(temp); } #ifdef CONFIG_GPL @@ -3430,11 +3502,11 @@ static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2 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]; + DCTELEM dct[8][8]; int i; int sum=0; - s->dsp.diff_pixels(dct, src1, src2, stride); + s->dsp.diff_pixels(dct[0], src1, src2, stride); #define SRC(x) dct[i][x] #define DST(x,v) dct[i][x]= v @@ -3486,7 +3558,7 @@ static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *s 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 + ff_simple_idct(temp); //FIXME for(i=0; i<64; i++) sum+= (temp[i]-bak[i])*(temp[i]-bak[i]); @@ -3694,7 +3766,8 @@ static int vsse16_c(/*MpegEncContext*/ void *c, uint8_t *s1, uint8_t *s2, int st return score; } -static int ssd_int8_vs_int16_c(int8_t *pix1, int16_t *pix2, int size){ +static int ssd_int8_vs_int16_c(const int8_t *pix1, const int16_t *pix2, + int size){ int score=0; int i; for(i=0; i<size; i++) @@ -3702,16 +3775,16 @@ static int ssd_int8_vs_int16_c(int8_t *pix1, int16_t *pix2, int size){ return score; } -WARPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c) -WARPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c) -WARPER8_16_SQ(dct_sad8x8_c, dct_sad16_c) +WRAPPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c) +WRAPPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c) +WRAPPER8_16_SQ(dct_sad8x8_c, dct_sad16_c) #ifdef CONFIG_GPL -WARPER8_16_SQ(dct264_sad8x8_c, dct264_sad16_c) +WRAPPER8_16_SQ(dct264_sad8x8_c, dct264_sad16_c) #endif -WARPER8_16_SQ(dct_max8x8_c, dct_max16_c) -WARPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c) -WARPER8_16_SQ(rd8x8_c, rd16_c) -WARPER8_16_SQ(bit8x8_c, bit16_c) +WRAPPER8_16_SQ(dct_max8x8_c, dct_max16_c) +WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c) +WRAPPER8_16_SQ(rd8x8_c, rd16_c) +WRAPPER8_16_SQ(bit8x8_c, bit16_c) static void vector_fmul_c(float *dst, const float *src, int len){ int i; @@ -3735,7 +3808,7 @@ void ff_vector_fmul_add_add_c(float *dst, const float *src0, const float *src1, void ff_float_to_int16_c(int16_t *dst, const float *src, int len){ int i; for(i=0; i<len; i++) { - int_fast32_t tmp = ((int32_t*)src)[i]; + int_fast32_t tmp = ((const int32_t*)src)[i]; if(tmp & 0xf0000){ tmp = (0x43c0ffff - tmp)>>31; // is this faster on some gcc/cpu combinations? @@ -3746,8 +3819,90 @@ void ff_float_to_int16_c(int16_t *dst, const float *src, int len){ } } +#define W0 2048 +#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ +#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ +#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ +#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */ +#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ +#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ +#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ + +static void wmv2_idct_row(short * b) +{ + int s1,s2; + int a0,a1,a2,a3,a4,a5,a6,a7; + /*step 1*/ + a1 = W1*b[1]+W7*b[7]; + a7 = W7*b[1]-W1*b[7]; + a5 = W5*b[5]+W3*b[3]; + a3 = W3*b[5]-W5*b[3]; + a2 = W2*b[2]+W6*b[6]; + a6 = W6*b[2]-W2*b[6]; + a0 = W0*b[0]+W0*b[4]; + a4 = W0*b[0]-W0*b[4]; + /*step 2*/ + s1 = (181*(a1-a5+a7-a3)+128)>>8;//1,3,5,7, + s2 = (181*(a1-a5-a7+a3)+128)>>8; + /*step 3*/ + b[0] = (a0+a2+a1+a5 + (1<<7))>>8; + b[1] = (a4+a6 +s1 + (1<<7))>>8; + b[2] = (a4-a6 +s2 + (1<<7))>>8; + b[3] = (a0-a2+a7+a3 + (1<<7))>>8; + b[4] = (a0-a2-a7-a3 + (1<<7))>>8; + b[5] = (a4-a6 -s2 + (1<<7))>>8; + b[6] = (a4+a6 -s1 + (1<<7))>>8; + b[7] = (a0+a2-a1-a5 + (1<<7))>>8; +} +static void wmv2_idct_col(short * b) +{ + int s1,s2; + int a0,a1,a2,a3,a4,a5,a6,a7; + /*step 1, with extended precision*/ + a1 = (W1*b[8*1]+W7*b[8*7] + 4)>>3; + a7 = (W7*b[8*1]-W1*b[8*7] + 4)>>3; + a5 = (W5*b[8*5]+W3*b[8*3] + 4)>>3; + a3 = (W3*b[8*5]-W5*b[8*3] + 4)>>3; + a2 = (W2*b[8*2]+W6*b[8*6] + 4)>>3; + a6 = (W6*b[8*2]-W2*b[8*6] + 4)>>3; + a0 = (W0*b[8*0]+W0*b[8*4] )>>3; + a4 = (W0*b[8*0]-W0*b[8*4] )>>3; + /*step 2*/ + s1 = (181*(a1-a5+a7-a3)+128)>>8; + s2 = (181*(a1-a5-a7+a3)+128)>>8; + /*step 3*/ + b[8*0] = (a0+a2+a1+a5 + (1<<13))>>14; + b[8*1] = (a4+a6 +s1 + (1<<13))>>14; + b[8*2] = (a4-a6 +s2 + (1<<13))>>14; + b[8*3] = (a0-a2+a7+a3 + (1<<13))>>14; + + b[8*4] = (a0-a2-a7-a3 + (1<<13))>>14; + b[8*5] = (a4-a6 -s2 + (1<<13))>>14; + b[8*6] = (a4+a6 -s1 + (1<<13))>>14; + b[8*7] = (a0+a2-a1-a5 + (1<<13))>>14; +} +void ff_wmv2_idct_c(short * block){ + int i; + + for(i=0;i<64;i+=8){ + wmv2_idct_row(block+i); + } + for(i=0;i<8;i++){ + wmv2_idct_col(block+i); + } +} /* XXX: those functions should be suppressed ASAP when all IDCTs are converted */ +static void ff_wmv2_idct_put_c(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_wmv2_idct_c(block); + put_pixels_clamped_c(block, dest, line_size); +} +static void ff_wmv2_idct_add_c(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_wmv2_idct_c(block); + add_pixels_clamped_c(block, dest, line_size); +} static void ff_jref_idct_put(uint8_t *dest, int line_size, DCTELEM *block) { j_rev_dct (block); @@ -3794,7 +3949,7 @@ static void ff_jref_idct1_add(uint8_t *dest, int line_size, DCTELEM *block) dest[0] = cm[dest[0] + ((block[0] + 4)>>3)]; } -static void just_return() { return; } +static void just_return(void *mem av_unused, int stride av_unused, int h av_unused) { return; } /* init static data */ void dsputil_static_init(void) @@ -3818,13 +3973,14 @@ int ff_check_alignment(void){ static int did_fail=0; DECLARE_ALIGNED_16(int, aligned); - if((int)&aligned & 15){ + if((long)&aligned & 15){ if(!did_fail){ #if defined(HAVE_MMX) || defined(HAVE_ALTIVEC) av_log(NULL, AV_LOG_ERROR, "Compiler did not align stack variables. Libavcodec has been miscompiled\n" "and may be very slow or crash. This is not a bug in libavcodec,\n" - "but in the compiler. Do not report crashes to FFmpeg developers.\n"); + "but in the compiler. You may try recompiling using gcc >= 4.2.\n" + "Do not report crashes to FFmpeg developers.\n"); #endif did_fail=1; } @@ -3855,7 +4011,7 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) #endif //CONFIG_ENCODERS if(avctx->lowres==1){ - if(avctx->idct_algo==FF_IDCT_INT || avctx->idct_algo==FF_IDCT_AUTO){ + if(avctx->idct_algo==FF_IDCT_INT || avctx->idct_algo==FF_IDCT_AUTO || !ENABLE_H264_DECODER){ c->idct_put= ff_jref_idct4_put; c->idct_add= ff_jref_idct4_add; }else{ @@ -3880,23 +4036,36 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) 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){ + }else if((ENABLE_VP3_DECODER || ENABLE_VP5_DECODER || ENABLE_VP6_DECODER || ENABLE_THEORA_DECODER ) && + 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 if(avctx->idct_algo==FF_IDCT_WMV2){ + c->idct_put= ff_wmv2_idct_put_c; + c->idct_add= ff_wmv2_idct_add_c; + c->idct = ff_wmv2_idct_c; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->idct_algo==FF_IDCT_FAAN){ + c->idct_put= ff_faanidct_put; + c->idct_add= ff_faanidct_add; + c->idct = ff_faanidct; + 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_put= ff_simple_idct_put; + c->idct_add= ff_simple_idct_add; + c->idct = ff_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; + if (ENABLE_H264_DECODER) { + 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; @@ -3905,6 +4074,7 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->add_pixels_clamped = add_pixels_clamped_c; c->add_pixels8 = add_pixels8_c; c->add_pixels4 = add_pixels4_c; + c->sum_abs_dctelem = sum_abs_dctelem_c; c->gmc1 = gmc1_c; c->gmc = ff_gmc_c; c->clear_blocks = clear_blocks_c; @@ -4039,8 +4209,11 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) #if defined(CONFIG_VC1_DECODER) || defined(CONFIG_WMV3_DECODER) ff_vc1dsp_init(c,avctx); #endif +#if defined(CONFIG_WMV2_DECODER) || defined(CONFIG_VC1_DECODER) || defined(CONFIG_WMV3_DECODER) + ff_intrax8dsp_init(c,avctx); +#endif #if defined(CONFIG_H264_ENCODER) - ff_h264dsp_init(c,avctx); + ff_h264dspenc_init(c,avctx); #endif c->put_mspel_pixels_tab[0]= put_mspel8_mc00_c; @@ -4087,9 +4260,13 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->ssd_int8_vs_int16 = ssd_int8_vs_int16_c; c->add_bytes= add_bytes_c; + c->add_bytes_l2= add_bytes_l2_c; c->diff_bytes= diff_bytes_c; c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; c->bswap_buf= bswap_buf; +#ifdef CONFIG_PNG_DECODER + c->add_png_paeth_prediction= ff_add_png_paeth_prediction; +#endif c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_c; c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_c; @@ -4099,8 +4276,10 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) 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; + if (ENABLE_ANY_H263) { + 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; @@ -4116,6 +4295,9 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) #ifdef CONFIG_VORBIS_DECODER c->vorbis_inverse_coupling = vorbis_inverse_coupling; #endif +#ifdef CONFIG_FLAC_ENCODER + c->flac_compute_autocorr = ff_flac_compute_autocorr; +#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; @@ -4131,33 +4313,15 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx) 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 + if (ENABLE_MMX) dsputil_init_mmx (c, avctx); + if (ENABLE_ARMV4L) dsputil_init_armv4l(c, avctx); + if (ENABLE_MLIB) dsputil_init_mlib (c, avctx); + if (ENABLE_VIS) dsputil_init_vis (c, avctx); + if (ENABLE_ALPHA) dsputil_init_alpha (c, avctx); + if (ENABLE_POWERPC) dsputil_init_ppc (c, avctx); + if (ENABLE_MMI) dsputil_init_mmi (c, avctx); + if (ENABLE_SH4) dsputil_init_sh4 (c, avctx); + if (ENABLE_BFIN) dsputil_init_bfin (c, avctx); for(i=0; i<64; i++){ if(!c->put_2tap_qpel_pixels_tab[0][i]) diff --git a/contrib/ffmpeg/libavcodec/dsputil.h b/contrib/ffmpeg/libavcodec/dsputil.h index 800669ea7..5fe169ecc 100644 --- a/contrib/ffmpeg/libavcodec/dsputil.h +++ b/contrib/ffmpeg/libavcodec/dsputil.h @@ -27,10 +27,9 @@ * absolutely necessary to call emms_c() between dsp & float/double code */ -#ifndef DSPUTIL_H -#define DSPUTIL_H +#ifndef FFMPEG_DSPUTIL_H +#define FFMPEG_DSPUTIL_H -#include "common.h" #include "avcodec.h" @@ -38,6 +37,7 @@ /* dct code */ typedef short DCTELEM; typedef int DWTELEM; +typedef short IDWTELEM; void fdct_ifast (DCTELEM *data); void fdct_ifast248 (DCTELEM *data); @@ -48,6 +48,7 @@ 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_wmv2_idct_c(DCTELEM *data); void ff_fdct_mmx(DCTELEM *block); void ff_fdct_mmx2(DCTELEM *block); @@ -145,7 +146,7 @@ static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ /* motion estimation */ // h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2 -// allthough currently h<4 is not used as functions with width <8 are not used and neither implemented +// although currently h<4 is not used as functions with width <8 are neither used nor implemented 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))*/; @@ -164,6 +165,7 @@ typedef struct DSPContext { 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); + int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/); /** * translational global motion compensation. */ @@ -200,7 +202,8 @@ typedef struct DSPContext { me_cmp_func ildct_cmp[5]; //only width 16 used me_cmp_func frame_skip_cmp[5]; //only width 8 used - int (*ssd_int8_vs_int16)(int8_t *pix1, int16_t *pix2, int size); + int (*ssd_int8_vs_int16)(const int8_t *pix1, const int16_t *pix2, + int size); /** * Halfpel motion compensation with rounding (a+b+1)>>1. @@ -301,13 +304,16 @@ typedef struct DSPContext { /* huffyuv specific */ void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); + void (*add_bytes_l2)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 16*/, int w); void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); /** * subtract huffyuv's variant of median prediction * note, this might read from src1[-1], src2[-1] */ 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); + /* this might write to dst[w] */ + void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); + void (*bswap_buf)(uint32_t *dst, const 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); @@ -324,8 +330,13 @@ typedef struct DSPContext { void (*h261_loop_filter)(uint8_t *src, int stride); + void (*x8_v_loop_filter)(uint8_t *src, int stride, int qscale); + void (*x8_h_loop_filter)(uint8_t *src, int stride, int qscale); + /* assume len is a multiple of 4, and arrays are 16-byte aligned */ void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize); + /* no alignment needed */ + void (*flac_compute_autocorr)(const int32_t *data, int len, int lag, double *autoc); /* 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); @@ -346,13 +357,13 @@ typedef struct DSPContext { /** * 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 + * @param line_size size in bytes of a horizontal 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 + * @param line_size size in bytes of a horizontal line of dest */ void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); @@ -389,8 +400,8 @@ typedef struct DSPContext { void (*h264_dct)(DCTELEM block[4][4]); /* 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 (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); + void (*horizontal_compose97i)(IDWTELEM *b, int width); void (*inner_add_yblock)(const 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); @@ -399,15 +410,21 @@ typedef struct DSPContext { /* 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_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block); + void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block); + void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); void (*vc1_v_overlap)(uint8_t* src, int stride); void (*vc1_h_overlap)(uint8_t* src, int stride); /* 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]; + + /* intrax8 functions */ + void (*x8_spatial_compensation[12])(uint8_t *src , uint8_t *dst, int linesize); + void (*x8_setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize, + int * range, int * sum, int edges); + } DSPContext; void dsputil_static_init(void); @@ -470,11 +487,17 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){ 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 +void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); + +#define DECLARE_ALIGNED_16(t, v) DECLARE_ALIGNED(16, t, v) #if defined(HAVE_MMX) @@ -497,7 +520,7 @@ void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int li static inline void emms(void) { - __asm __volatile ("emms;":::"memory"); + asm volatile ("emms;":::"memory"); } @@ -507,95 +530,36 @@ static inline void emms(void) 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 - -void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx); #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; -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 - -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 - -void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); - #elif defined(ARCH_POWERPC) #define MM_ALTIVEC 0x0001 /* standard AltiVec */ extern int mm_flags; -#if defined(HAVE_ALTIVEC) && !defined(CONFIG_DARWIN) -#define pixel altivec_pixel -#include <altivec.h> -#undef pixel -#endif - -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (16))) +#define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) #define STRIDE_ALIGN 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 DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v) #define STRIDE_ALIGN 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 - -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 +#endif -#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) -#define STRIDE_ALIGN 8 +#ifndef DECLARE_ALIGNED_8 +# define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(8, t, v) +#endif +#ifndef STRIDE_ALIGN +# define STRIDE_ALIGN 8 #endif /* PSNR */ @@ -651,6 +615,14 @@ typedef struct MDCTContext { FFTContext fft; } MDCTContext; +/** + * Generate a Kaiser-Bessel Derived Window. + * @param window pointer to half window + * @param alpha determines window shape + * @param n size of half window + */ +void ff_kbd_window_init(float *window, float alpha, int n); + int ff_mdct_init(MDCTContext *s, int nbits, int inverse); void ff_imdct_calc(MDCTContext *s, FFTSample *output, const FFTSample *input, FFTSample *tmp); @@ -662,13 +634,13 @@ void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input, FFTSample *tmp); void ff_mdct_end(MDCTContext *s); -#define WARPER8_16(name8, name16)\ +#define WRAPPER8_16(name8, name16)\ static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ return name8(s, dst , src , stride, h)\ +name8(s, dst+8 , src+8 , stride, h);\ } -#define WARPER8_16_SQ(name8, name16)\ +#define WRAPPER8_16_SQ(name8, name16)\ static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ int score=0;\ score +=name8(s, dst , src , stride, 8);\ @@ -688,7 +660,7 @@ static inline void copy_block2(uint8_t *dst, uint8_t *src, int dstStride, int sr int i; for(i=0; i<h; i++) { - ST16(dst , LD16(src )); + AV_WN16(dst , AV_RN16(src )); dst+=dstStride; src+=srcStride; } @@ -699,7 +671,7 @@ static inline void copy_block4(uint8_t *dst, uint8_t *src, int dstStride, int sr int i; for(i=0; i<h; i++) { - ST32(dst , LD32(src )); + AV_WN32(dst , AV_RN32(src )); dst+=dstStride; src+=srcStride; } @@ -710,8 +682,8 @@ static inline void copy_block8(uint8_t *dst, uint8_t *src, int dstStride, int sr int i; for(i=0; i<h; i++) { - ST32(dst , LD32(src )); - ST32(dst+4 , LD32(src+4 )); + AV_WN32(dst , AV_RN32(src )); + AV_WN32(dst+4 , AV_RN32(src+4 )); dst+=dstStride; src+=srcStride; } @@ -722,8 +694,8 @@ static inline void copy_block9(uint8_t *dst, uint8_t *src, int dstStride, int sr int i; for(i=0; i<h; i++) { - ST32(dst , LD32(src )); - ST32(dst+4 , LD32(src+4 )); + AV_WN32(dst , AV_RN32(src )); + AV_WN32(dst+4 , AV_RN32(src+4 )); dst[8]= src[8]; dst+=dstStride; src+=srcStride; @@ -735,10 +707,10 @@ static inline void copy_block16(uint8_t *dst, uint8_t *src, int dstStride, int s int i; for(i=0; i<h; i++) { - ST32(dst , LD32(src )); - ST32(dst+4 , LD32(src+4 )); - ST32(dst+8 , LD32(src+8 )); - ST32(dst+12, LD32(src+12)); + AV_WN32(dst , AV_RN32(src )); + AV_WN32(dst+4 , AV_RN32(src+4 )); + AV_WN32(dst+8 , AV_RN32(src+8 )); + AV_WN32(dst+12, AV_RN32(src+12)); dst+=dstStride; src+=srcStride; } @@ -749,14 +721,14 @@ static inline void copy_block17(uint8_t *dst, uint8_t *src, int dstStride, int s int i; for(i=0; i<h; i++) { - ST32(dst , LD32(src )); - ST32(dst+4 , LD32(src+4 )); - ST32(dst+8 , LD32(src+8 )); - ST32(dst+12, LD32(src+12)); + AV_WN32(dst , AV_RN32(src )); + AV_WN32(dst+4 , AV_RN32(src+4 )); + AV_WN32(dst+8 , AV_RN32(src+8 )); + AV_WN32(dst+12, AV_RN32(src+12)); dst[16]= src[16]; dst+=dstStride; src+=srcStride; } } -#endif +#endif /* FFMPEG_DSPUTIL_H */ diff --git a/contrib/ffmpeg/libavcodec/dtsdec.c b/contrib/ffmpeg/libavcodec/dtsdec.c deleted file mode 100644 index 6763572dd..000000000 --- a/contrib/ffmpeg/libavcodec/dtsdec.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * dtsdec.c : free DTS Coherent Acoustics stream decoder. - * Copyright (C) 2004 Benjamin Zores <ben@geexbox.org> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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 General Public License for more details. - * - * You should have received a copy of the GNU 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" -#include <dts.h> - -#include <stdlib.h> -#include <string.h> - -#define BUFFER_SIZE 18726 -#define HEADER_SIZE 14 - -#define CONVERT_LEVEL 1 -#define CONVERT_BIAS 0 - -typedef struct DTSContext { - dts_state_t *state; - uint8_t buf[BUFFER_SIZE]; - uint8_t *bufptr; - uint8_t *bufpos; -} DTSContext; - -static inline int16_t -convert(sample_t s) -{ - return s * 0x7fff; -} - -static void -convert2s16_multi(sample_t *f, int16_t *s16, int flags) -{ - int i; - - switch(flags & (DTS_CHANNEL_MASK | DTS_LFE)){ - case DTS_MONO: - for(i = 0; i < 256; i++){ - s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; - s16[5*i+4] = convert(f[i]); - } - case DTS_CHANNEL: - case DTS_STEREO: - case DTS_DOLBY: - for(i = 0; i < 256; i++){ - s16[2*i] = convert(f[i]); - s16[2*i+1] = convert(f[i+256]); - } - case DTS_3F: - for(i = 0; i < 256; i++){ - s16[5*i] = convert(f[i+256]); - s16[5*i+1] = convert(f[i+512]); - s16[5*i+2] = s16[5*i+3] = 0; - s16[5*i+4] = convert(f[i]); - } - case DTS_2F2R: - for(i = 0; i < 256; i++){ - s16[4*i] = convert(f[i]); - s16[4*i+1] = convert(f[i+256]); - s16[4*i+2] = convert(f[i+512]); - s16[4*i+3] = convert(f[i+768]); - } - case DTS_3F2R: - for(i = 0; i < 256; i++){ - s16[5*i] = convert(f[i+256]); - s16[5*i+1] = convert(f[i+512]); - s16[5*i+2] = convert(f[i+768]); - s16[5*i+3] = convert(f[i+1024]); - s16[5*i+4] = convert(f[i]); - } - case DTS_MONO | DTS_LFE: - for(i = 0; i < 256; i++){ - s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; - s16[6*i+4] = convert(f[i]); - s16[6*i+5] = convert(f[i+256]); - } - case DTS_CHANNEL | DTS_LFE: - case DTS_STEREO | DTS_LFE: - case DTS_DOLBY | DTS_LFE: - for(i = 0; i < 256; i++){ - s16[6*i] = convert(f[i]); - s16[6*i+1] = convert(f[i+256]); - s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; - s16[6*i+5] = convert(f[i+512]); - } - case DTS_3F | DTS_LFE: - for(i = 0; i < 256; i++){ - s16[6*i] = convert(f[i+256]); - s16[6*i+1] = convert(f[i+512]); - s16[6*i+2] = s16[6*i+3] = 0; - s16[6*i+4] = convert(f[i]); - s16[6*i+5] = convert(f[i+768]); - } - case DTS_2F2R | DTS_LFE: - for(i = 0; i < 256; i++){ - s16[6*i] = convert(f[i]); - s16[6*i+1] = convert(f[i+256]); - s16[6*i+2] = convert(f[i+512]); - s16[6*i+3] = convert(f[i+768]); - s16[6*i+4] = 0; - s16[6*i+5] = convert(f[i+1024]); - } - case DTS_3F2R | DTS_LFE: - for(i = 0; i < 256; i++){ - s16[6*i] = convert(f[i+256]); - s16[6*i+1] = convert(f[i+512]); - s16[6*i+2] = convert(f[i+768]); - s16[6*i+3] = convert(f[i+1024]); - s16[6*i+4] = convert(f[i]); - s16[6*i+5] = convert(f[i+1280]); - } - } -} - -static int -channels_multi(int flags) -{ - switch(flags & (DTS_CHANNEL_MASK | DTS_LFE)){ - case DTS_CHANNEL: - case DTS_STEREO: - case DTS_DOLBY: - return 2; - case DTS_2F2R: - return 4; - case DTS_MONO: - case DTS_3F: - case DTS_3F2R: - return 5; - case DTS_MONO | DTS_LFE: - case DTS_CHANNEL | DTS_LFE: - case DTS_STEREO | DTS_LFE: - case DTS_DOLBY | DTS_LFE: - case DTS_3F | DTS_LFE: - case DTS_2F2R | DTS_LFE: - case DTS_3F2R | DTS_LFE: - return 6; - } - - return -1; -} - -static int -dts_decode_frame(AVCodecContext * avctx, void *data, int *data_size, - uint8_t * buff, int buff_size) -{ - DTSContext *s = avctx->priv_data; - uint8_t *start = buff; - uint8_t *end = buff + buff_size; - int16_t *out_samples = data; - int sample_rate; - int frame_length; - int flags; - int bit_rate; - int len; - level_t level; - sample_t bias; - int nblocks; - int i; - - *data_size = 0; - - while(1) { - int length; - - len = end - start; - if(!len) - break; - if(len > s->bufpos - s->bufptr) - len = s->bufpos - s->bufptr; - memcpy(s->bufptr, start, len); - s->bufptr += len; - start += len; - if(s->bufptr != s->bufpos) - return start - buff; - if(s->bufpos != s->buf + HEADER_SIZE) - break; - - length = dts_syncinfo(s->state, s->buf, &flags, &sample_rate, - &bit_rate, &frame_length); - if(!length) { - av_log(NULL, AV_LOG_INFO, "skip\n"); - for(s->bufptr = s->buf; s->bufptr < s->buf + HEADER_SIZE - 1; s->bufptr++) - s->bufptr[0] = s->bufptr[1]; - continue; - } - s->bufpos = s->buf + length; - } - - level = CONVERT_LEVEL; - bias = CONVERT_BIAS; - - flags |= DTS_ADJUST_LEVEL; - if(dts_frame(s->state, s->buf, &flags, &level, bias)) { - av_log(avctx, AV_LOG_ERROR, "dts_frame() failed\n"); - goto end; - } - - avctx->sample_rate = sample_rate; - avctx->channels = channels_multi(flags); - avctx->bit_rate = bit_rate; - - nblocks = dts_blocks_num(s->state); - - for(i = 0; i < nblocks; i++) { - if(dts_block(s->state)) { - av_log(avctx, AV_LOG_ERROR, "dts_block() failed\n"); - goto end; - } - - convert2s16_multi(dts_samples(s->state), out_samples, flags); - - out_samples += 256 * avctx->channels; - *data_size += 256 * sizeof(int16_t) * avctx->channels; - } - -end: - s->bufptr = s->buf; - s->bufpos = s->buf + HEADER_SIZE; - return start - buff; -} - -static int -dts_decode_init(AVCodecContext * avctx) -{ - DTSContext *s = avctx->priv_data; - s->bufptr = s->buf; - s->bufpos = s->buf + HEADER_SIZE; - s->state = dts_init(0); - if(s->state == NULL) - return -1; - - return 0; -} - -static int -dts_decode_end(AVCodecContext * avctx) -{ - DTSContext *s = avctx->priv_data; - dts_free(s->state); - return 0; -} - -AVCodec dts_decoder = { - "dts", - CODEC_TYPE_AUDIO, - CODEC_ID_DTS, - sizeof(DTSContext), - dts_decode_init, - NULL, - dts_decode_end, - dts_decode_frame, -}; diff --git a/contrib/ffmpeg/libavcodec/dump_extradata_bsf.c b/contrib/ffmpeg/libavcodec/dump_extradata_bsf.c new file mode 100644 index 000000000..db263490a --- /dev/null +++ b/contrib/ffmpeg/libavcodec/dump_extradata_bsf.c @@ -0,0 +1,50 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * 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" + + +static int dump_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe){ + int cmd= args ? *args : 0; + /* cast to avoid warning about discarding qualifiers */ + if(avctx->extradata){ + if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER) && cmd=='a') + ||(keyframe && (cmd=='k' || !cmd)) + ||(cmd=='e') + /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){ + int size= buf_size + avctx->extradata_size; + *poutbuf_size= size; + *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + + memcpy(*poutbuf, avctx->extradata, avctx->extradata_size); + memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + return 1; + } + } + return 0; +} + +AVBitStreamFilter dump_extradata_bsf={ + "dump_extra", + 0, + dump_extradata, +}; diff --git a/contrib/ffmpeg/libavcodec/dv.c b/contrib/ffmpeg/libavcodec/dv.c index 19615b431..66c6d3c11 100644 --- a/contrib/ffmpeg/libavcodec/dv.c +++ b/contrib/ffmpeg/libavcodec/dv.c @@ -225,7 +225,7 @@ static int dvvideo_init(AVCodecContext *avctx) /* 248DCT setup */ s->fdct[1] = dsp.fdct248; - s->idct_put[1] = simple_idct248_put; // FIXME: need to add it to DSP + s->idct_put[1] = ff_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]; @@ -363,7 +363,7 @@ static inline void bit_copy(PutBitContext *pb, GetBitContext *gb) /* 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 uint8_t *buf_ptr1, const uint16_t *mb_pos_ptr) { int quant, dc, dct_mode, class1, j; @@ -372,7 +372,7 @@ static inline void dv_decode_video_segment(DVVideoContext *s, int c_offset; uint8_t *y_ptr; void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block); - uint8_t *buf_ptr; + const uint8_t *buf_ptr; PutBitContext pb, vs_pb; GetBitContext gb; BlockInfo mb_data[5 * 6], *mb, *mb1; @@ -1031,7 +1031,7 @@ static int dv_encode_mt(AVCodecContext *avctx, void* sl) 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) + const uint8_t *buf, int buf_size) { DVVideoContext *s = avctx->priv_data; diff --git a/contrib/ffmpeg/libavcodec/dvbsub.c b/contrib/ffmpeg/libavcodec/dvbsub.c index 44ba19d86..a1594edd0 100644 --- a/contrib/ffmpeg/libavcodec/dvbsub.c +++ b/contrib/ffmpeg/libavcodec/dvbsub.c @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" +#include "bytestream.h" +#include "colorspace.h" typedef struct DVBSubtitleContext { int hide_state; @@ -192,31 +194,6 @@ static void dvb_encode_rle4(uint8_t **pq, *pq = q; } -#define SCALEBITS 10 -#define ONE_HALF (1 << (SCALEBITS - 1)) -#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) - -#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 inline void putbe16(uint8_t **pq, uint16_t v) -{ - uint8_t *q; - q = *pq; - *q++ = v >> 8; - *q++ = v; - *pq = q; -} - static int encode_dvb_subtitles(DVBSubtitleContext *s, uint8_t *outbuf, AVSubtitle *h) { @@ -237,7 +214,7 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, *q++ = 0x0f; /* sync_byte */ *q++ = 0x10; /* segment_type */ - putbe16(&q, page_id); + bytestream_put_be16(&q, page_id); pseg_len = q; q += 2; /* segment length */ *q++ = 30; /* page_timeout (seconds) */ @@ -251,11 +228,11 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, for (region_id = 0; region_id < h->num_rects; region_id++) { *q++ = region_id; *q++ = 0xff; /* reserved */ - putbe16(&q, h->rects[region_id].x); /* left pos */ - putbe16(&q, h->rects[region_id].y); /* top pos */ + bytestream_put_be16(&q, h->rects[region_id].x); /* left pos */ + bytestream_put_be16(&q, h->rects[region_id].y); /* top pos */ } - putbe16(&pseg_len, q - pseg_len - 2); + bytestream_put_be16(&pseg_len, q - pseg_len - 2); if (!s->hide_state) { for (clut_id = 0; clut_id < h->num_rects; clut_id++) { @@ -274,7 +251,7 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, *q++ = 0x0f; /* sync byte */ *q++ = 0x12; /* CLUT definition segment */ - putbe16(&q, page_id); + bytestream_put_be16(&q, page_id); pseg_len = q; q += 2; /* segment length */ *q++ = clut_id; @@ -297,7 +274,7 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, } } - putbe16(&pseg_len, q - pseg_len - 2); + bytestream_put_be16(&pseg_len, q - pseg_len - 2); } } @@ -317,27 +294,27 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, *q++ = 0x0f; /* sync_byte */ *q++ = 0x11; /* segment_type */ - putbe16(&q, page_id); + bytestream_put_be16(&q, page_id); pseg_len = q; q += 2; /* segment length */ *q++ = region_id; *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ - putbe16(&q, h->rects[region_id].w); /* region width */ - putbe16(&q, h->rects[region_id].h); /* region height */ + bytestream_put_be16(&q, h->rects[region_id].w); /* region width */ + bytestream_put_be16(&q, h->rects[region_id].h); /* region height */ *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03; *q++ = region_id; /* clut_id == region_id */ *q++ = 0; /* 8 bit fill colors */ *q++ = 0x03; /* 4 bit and 2 bit fill colors */ if (!s->hide_state) { - putbe16(&q, region_id); /* object_id == region_id */ + bytestream_put_be16(&q, region_id); /* object_id == region_id */ *q++ = (0 << 6) | (0 << 4); *q++ = 0; *q++ = 0xf0; *q++ = 0; } - putbe16(&pseg_len, q - pseg_len - 2); + bytestream_put_be16(&pseg_len, q - pseg_len - 2); } if (!s->hide_state) { @@ -357,11 +334,11 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, *q++ = 0x0f; /* sync byte */ *q++ = 0x13; - putbe16(&q, page_id); + bytestream_put_be16(&q, page_id); pseg_len = q; q += 2; /* segment length */ - putbe16(&q, object_id); + bytestream_put_be16(&q, object_id); *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0, onject_coding_method, non_modifying_color_flag */ @@ -388,11 +365,11 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, h->rects[object_id].w * 2, h->rects[object_id].w, h->rects[object_id].h >> 1); - putbe16(&ptop_field_len, bottom_ptr - top_ptr); - putbe16(&pbottom_field_len, q - bottom_ptr); + bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr); + bytestream_put_be16(&pbottom_field_len, q - bottom_ptr); } - putbe16(&pseg_len, q - pseg_len - 2); + bytestream_put_be16(&pseg_len, q - pseg_len - 2); } } @@ -400,11 +377,11 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, *q++ = 0x0f; /* sync_byte */ *q++ = 0x80; /* segment_type */ - putbe16(&q, page_id); + bytestream_put_be16(&q, page_id); pseg_len = q; q += 2; /* segment length */ - putbe16(&pseg_len, q - pseg_len - 2); + bytestream_put_be16(&pseg_len, q - pseg_len - 2); *q++ = 0xff; /* end of PES data */ @@ -413,16 +390,6 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, return q - outbuf; } -static int dvbsub_init_decoder(AVCodecContext *avctx) -{ - return 0; -} - -static int dvbsub_close_decoder(AVCodecContext *avctx) -{ - return 0; -} - static int dvbsub_encode(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data) { @@ -439,7 +406,6 @@ AVCodec dvbsub_encoder = { CODEC_TYPE_SUBTITLE, CODEC_ID_DVB_SUBTITLE, sizeof(DVBSubtitleContext), - dvbsub_init_decoder, + NULL, dvbsub_encode, - dvbsub_close_decoder, }; diff --git a/contrib/ffmpeg/libavcodec/dvbsub_parser.c b/contrib/ffmpeg/libavcodec/dvbsub_parser.c new file mode 100644 index 000000000..312c243bf --- /dev/null +++ b/contrib/ffmpeg/libavcodec/dvbsub_parser.c @@ -0,0 +1,196 @@ +/* + * DVB subtitle parser for FFmpeg + * Copyright (c) 2005 Ian Caulfield. + * + * 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" +#include "dsputil.h" +#include "bitstream.h" + +//#define DEBUG +//#define DEBUG_PACKET_CONTENTS + +/* Parser (mostly) copied from dvdsub.c */ + +#define PARSE_BUF_SIZE (65536) + + +/* parser definition */ +typedef struct DVBSubParseContext { + uint8_t *packet_buf; + int packet_start; + int packet_index; + int in_packet; +} DVBSubParseContext; + +static int dvbsub_parse_init(AVCodecParserContext *s) +{ + DVBSubParseContext *pc = s->priv_data; + pc->packet_buf = av_malloc(PARSE_BUF_SIZE); + + return 0; +} + +static int dvbsub_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + DVBSubParseContext *pc = s->priv_data; + uint8_t *p, *p_end; + int len, buf_pos = 0; + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n", + s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]); +#endif + +#ifdef DEBUG_PACKET_CONTENTS + int i; + + for (i=0; i < buf_size; i++) + { + av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); + if (i % 16 == 15) + av_log(avctx, AV_LOG_INFO, "\n"); + } + + if (i % 16 != 0) + av_log(avctx, AV_LOG_INFO, "\n"); + +#endif + + *poutbuf = NULL; + *poutbuf_size = 0; + + s->fetch_timestamp = 1; + + if (s->last_pts != s->pts && s->last_pts != AV_NOPTS_VALUE) /* Start of a new packet */ + { + if (pc->packet_index != pc->packet_start) + { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Discarding %d bytes\n", + pc->packet_index - pc->packet_start); +#endif + } + + pc->packet_start = 0; + pc->packet_index = 0; + + if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Bad packet header\n"); +#endif + return -1; + } + + buf_pos = 2; + + pc->in_packet = 1; + } else { + if (pc->packet_start != 0) + { + if (pc->packet_index != pc->packet_start) + { + memmove(pc->packet_buf, pc->packet_buf + pc->packet_start, + pc->packet_index - pc->packet_start); + + pc->packet_index -= pc->packet_start; + pc->packet_start = 0; + } else { + pc->packet_start = 0; + pc->packet_index = 0; + } + } + } + + if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE) + return -1; + +/* if not currently in a packet, discard data */ + if (pc->in_packet == 0) + return buf_size; + + memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos); + pc->packet_index += buf_size - buf_pos; + + p = pc->packet_buf; + p_end = pc->packet_buf + pc->packet_index; + + while (p < p_end) + { + if (*p == 0x0f) + { + if (p + 6 <= p_end) + { + len = AV_RB16(p + 4); + + if (p + len + 6 <= p_end) + { + *poutbuf_size += len + 6; + + p += len + 6; + } else + break; + } else + break; + } else if (*p == 0xff) { + if (p + 1 < p_end) + { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n"); +#endif + } + pc->packet_index = p - pc->packet_buf; + pc->in_packet = 0; + break; + } else { + av_log(avctx, AV_LOG_ERROR, "Junk in packet\n"); + + pc->packet_index = p - pc->packet_buf; + pc->in_packet = 0; + break; + } + } + + if (*poutbuf_size > 0) + { + *poutbuf = pc->packet_buf; + pc->packet_start = *poutbuf_size; + } + + if (s->last_pts == AV_NOPTS_VALUE) + s->last_pts = s->pts; + + return buf_size; +} + +static void dvbsub_parse_close(AVCodecParserContext *s) +{ + DVBSubParseContext *pc = s->priv_data; + av_freep(&pc->packet_buf); +} + +AVCodecParser dvbsub_parser = { + { CODEC_ID_DVB_SUBTITLE }, + sizeof(DVBSubParseContext), + dvbsub_parse_init, + dvbsub_parse, + dvbsub_parse_close, +}; diff --git a/contrib/ffmpeg/libavcodec/dvbsubdec.c b/contrib/ffmpeg/libavcodec/dvbsubdec.c index 08ef6213e..5822564e7 100644 --- a/contrib/ffmpeg/libavcodec/dvbsubdec.c +++ b/contrib/ffmpeg/libavcodec/dvbsubdec.c @@ -21,6 +21,7 @@ #include "avcodec.h" #include "dsputil.h" #include "bitstream.h" +#include "colorspace.h" //#define DEBUG //#define DEBUG_PACKET_CONTENTS @@ -101,7 +102,7 @@ static void png_save2(const char *filename, uint32_t *bitmap, int w, int h) char fname[40], fname2[40]; char command[1024]; - snprintf(fname, 40, "%s.ppm", filename); + snprintf(fname, sizeof(fname), "%s.ppm", filename); f = fopen(fname, "w"); if (!f) { @@ -123,7 +124,7 @@ static void png_save2(const char *filename, uint32_t *bitmap, int w, int h) fclose(f); - snprintf(fname2, 40, "%s-a.pgm", filename); + snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename); f = fopen(fname2, "w"); if (!f) { @@ -142,10 +143,10 @@ static void png_save2(const char *filename, uint32_t *bitmap, int w, int h) } fclose(f); - snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); + snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); system(command); - snprintf(command, 1024, "rm %s %s", fname, fname2); + snprintf(command, sizeof(command), "rm %s %s", fname, fname2); system(command); } #endif @@ -171,8 +172,8 @@ typedef struct DVBSubObjectDisplay { int x_pos; int y_pos; - int fgcolour; - int bgcolour; + int fgcolor; + int bgcolor; struct DVBSubObjectDisplay *region_list_next; struct DVBSubObjectDisplay *object_list_next; @@ -205,7 +206,7 @@ typedef struct DVBSubRegion { int depth; int clut; - int bgcolour; + int bgcolor; uint8_t *pbuf; int buf_size; @@ -233,7 +234,7 @@ static DVBSubObject* get_object(DVBSubContext *ctx, int object_id) { DVBSubObject *ptr = ctx->object_list; - while (ptr != NULL && ptr->id != object_id) { + while (ptr && ptr->id != object_id) { ptr = ptr->next; } @@ -244,7 +245,7 @@ static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id) { DVBSubCLUT *ptr = ctx->clut_list; - while (ptr != NULL && ptr->id != clut_id) { + while (ptr && ptr->id != clut_id) { ptr = ptr->next; } @@ -255,7 +256,7 @@ static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id) { DVBSubRegion *ptr = ctx->region_list; - while (ptr != NULL && ptr->id != region_id) { + while (ptr && ptr->id != region_id) { ptr = ptr->next; } @@ -267,16 +268,16 @@ static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region) DVBSubObject *object, *obj2, **obj2_ptr; DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr; - while (region->display_list != NULL) { + while (region->display_list) { display = region->display_list; object = get_object(ctx, display->object_id); - if (object != NULL) { + if (object) { obj_disp = object->display_list; obj_disp_ptr = &object->display_list; - while (obj_disp != NULL && obj_disp != display) { + while (obj_disp && obj_disp != display) { obj_disp_ptr = &obj_disp->object_list_next; obj_disp = obj_disp->object_list_next; } @@ -284,11 +285,11 @@ static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region) if (obj_disp) { *obj_disp_ptr = obj_disp->object_list_next; - if (object->display_list == NULL) { + if (!object->display_list) { obj2 = ctx->object_list; obj2_ptr = &ctx->object_list; - while (obj2 != NULL && obj2 != object) { + while (obj2 && obj2 != object) { obj2_ptr = &obj2->next; obj2 = obj2->next; } @@ -312,21 +313,19 @@ static void delete_state(DVBSubContext *ctx) DVBSubRegion *region; DVBSubCLUT *clut; - while (ctx->region_list != NULL) - { + while (ctx->region_list) { region = ctx->region_list; ctx->region_list = region->next; delete_region_display_list(ctx, region); - if (region->pbuf != NULL) + if (region->pbuf) av_free(region->pbuf); av_free(region); } - while (ctx->clut_list != NULL) - { + while (ctx->clut_list) { clut = ctx->clut_list; ctx->clut_list = clut->next; @@ -335,7 +334,7 @@ static void delete_state(DVBSubContext *ctx) } /* Should already be null */ - if (ctx->object_list != NULL) + if (ctx->object_list) av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n"); } @@ -419,8 +418,7 @@ static int dvbsub_close_decoder(AVCodecContext *avctx) delete_state(ctx); - while (ctx->display_list != NULL) - { + while (ctx->display_list) { display = ctx->display_list; ctx->display_list = display->next; @@ -431,7 +429,7 @@ static int dvbsub_close_decoder(AVCodecContext *avctx) } static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, - uint8_t **srcbuf, int buf_size, + const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table) { GetBitContext gb; @@ -445,16 +443,16 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) { bits = get_bits(&gb, 2); - if (bits != 0) { + if (bits) { if (non_mod != 1 || bits != 1) { - if (map_table != NULL) + if (map_table) *destbuf++ = map_table[bits]; else *destbuf++ = bits; } pixels_read++; } else { - bits = get_bits(&gb, 1); + bits = get_bits1(&gb); if (bits == 1) { run_length = get_bits(&gb, 3) + 3; bits = get_bits(&gb, 2); @@ -462,7 +460,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, if (non_mod == 1 && bits == 1) pixels_read += run_length; else { - if (map_table != NULL) + if (map_table) bits = map_table[bits]; while (run_length-- > 0 && pixels_read < dbuf_len) { *destbuf++ = bits; @@ -470,7 +468,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } } } else { - bits = get_bits(&gb, 1); + bits = get_bits1(&gb); if (bits == 0) { bits = get_bits(&gb, 2); if (bits == 2) { @@ -480,7 +478,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, if (non_mod == 1 && bits == 1) pixels_read += run_length; else { - if (map_table != NULL) + if (map_table) bits = map_table[bits]; while (run_length-- > 0 && pixels_read < dbuf_len) { *destbuf++ = bits; @@ -494,7 +492,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, if (non_mod == 1 && bits == 1) pixels_read += run_length; else { - if (map_table != NULL) + if (map_table) bits = map_table[bits]; while (run_length-- > 0 && pixels_read < dbuf_len) { *destbuf++ = bits; @@ -503,7 +501,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } } else if (bits == 1) { pixels_read += 2; - if (map_table != NULL) + if (map_table) bits = map_table[0]; else bits = 0; @@ -516,7 +514,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, return pixels_read; } } else { - if (map_table != NULL) + if (map_table) bits = map_table[0]; else bits = 0; @@ -527,7 +525,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } } - if (get_bits(&gb, 6) != 0) + if (get_bits(&gb, 6)) av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; @@ -536,7 +534,7 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, - uint8_t **srcbuf, int buf_size, + const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table) { GetBitContext gb; @@ -550,16 +548,16 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) { bits = get_bits(&gb, 4); - if (bits != 0) { + if (bits) { if (non_mod != 1 || bits != 1) { - if (map_table != NULL) + if (map_table) *destbuf++ = map_table[bits]; else *destbuf++ = bits; } pixels_read++; } else { - bits = get_bits(&gb, 1); + bits = get_bits1(&gb); if (bits == 0) { run_length = get_bits(&gb, 3); @@ -570,7 +568,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, run_length += 2; - if (map_table != NULL) + if (map_table) bits = map_table[0]; else bits = 0; @@ -580,7 +578,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, pixels_read++; } } else { - bits = get_bits(&gb, 1); + bits = get_bits1(&gb); if (bits == 0) { run_length = get_bits(&gb, 2) + 4; bits = get_bits(&gb, 4); @@ -588,7 +586,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, if (non_mod == 1 && bits == 1) pixels_read += run_length; else { - if (map_table != NULL) + if (map_table) bits = map_table[bits]; while (run_length-- > 0 && pixels_read < dbuf_len) { *destbuf++ = bits; @@ -604,7 +602,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, if (non_mod == 1 && bits == 1) pixels_read += run_length; else { - if (map_table != NULL) + if (map_table) bits = map_table[bits]; while (run_length-- > 0 && pixels_read < dbuf_len) { *destbuf++ = bits; @@ -618,7 +616,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, if (non_mod == 1 && bits == 1) pixels_read += run_length; else { - if (map_table != NULL) + if (map_table) bits = map_table[bits]; while (run_length-- > 0 && pixels_read < dbuf_len) { *destbuf++ = bits; @@ -627,7 +625,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, } } else if (bits == 1) { pixels_read += 2; - if (map_table != NULL) + if (map_table) bits = map_table[0]; else bits = 0; @@ -636,7 +634,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, *destbuf++ = bits; } } else { - if (map_table != NULL) + if (map_table) bits = map_table[0]; else bits = 0; @@ -648,7 +646,7 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, } } - if (get_bits(&gb, 8) != 0) + if (get_bits(&gb, 8)) av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; @@ -657,10 +655,10 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, } static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, - uint8_t **srcbuf, int buf_size, + const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table) { - uint8_t *sbuf_end = (*srcbuf) + buf_size; + const uint8_t *sbuf_end = (*srcbuf) + buf_size; int bits; int run_length; int pixels_read = 0; @@ -668,9 +666,9 @@ static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, while (*srcbuf < sbuf_end && pixels_read < dbuf_len) { bits = *(*srcbuf)++; - if (bits != 0) { + if (bits) { if (non_mod != 1 || bits != 1) { - if (map_table != NULL) + if (map_table) *destbuf++ = map_table[bits]; else *destbuf++ = bits; @@ -684,7 +682,7 @@ static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, return pixels_read; } - if (map_table != NULL) + if (map_table) bits = map_table[0]; else bits = 0; @@ -697,7 +695,7 @@ static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, if (non_mod == 1 && bits == 1) pixels_read += run_length; - if (map_table != NULL) + if (map_table) bits = map_table[bits]; else while (run_length-- > 0 && pixels_read < dbuf_len) { *destbuf++ = bits; @@ -707,7 +705,7 @@ static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, } } - if (*(*srcbuf)++ != 0) + if (*(*srcbuf)++) av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); return pixels_read; @@ -716,12 +714,12 @@ static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display, - uint8_t *buf, int buf_size, int top_bottom, int non_mod) + const uint8_t *buf, int buf_size, int top_bottom, int non_mod) { DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; DVBSubRegion *region = get_region(ctx, display->region_id); - uint8_t *buf_end = buf + buf_size; + const uint8_t *buf_end = buf + buf_size; uint8_t *pbuf; int x_pos, y_pos; int i; @@ -738,8 +736,7 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis #endif #ifdef DEBUG_PACKET_CONTENTS - for (i = 0; i < buf_size; i++) - { + for (i = 0; i < buf_size; i++) { if (i % 16 == 0) av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i); @@ -748,7 +745,7 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis av_log(avctx, AV_LOG_INFO, "\n"); } - if (i % 16 != 0) + if (i % 16) av_log(avctx, AV_LOG_INFO, "\n"); #endif @@ -836,18 +833,18 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis } static void dvbsub_parse_object_segment(AVCodecContext *avctx, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - uint8_t *buf_end = buf + buf_size; - uint8_t *block; + const uint8_t *buf_end = buf + buf_size; + const uint8_t *block; int object_id; DVBSubObject *object; DVBSubObjectDisplay *display; int top_field_len, bottom_field_len; - int coding_method, non_modifying_colour; + int coding_method, non_modifying_color; object_id = AV_RB16(buf); buf += 2; @@ -858,7 +855,7 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx, return; coding_method = ((*buf) >> 2) & 3; - non_modifying_colour = ((*buf++) >> 1) & 1; + non_modifying_color = ((*buf++) >> 1) & 1; if (coding_method == 0) { top_field_len = AV_RB16(buf); @@ -871,11 +868,11 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx, return; } - for (display = object->display_list; display != 0; display = display->object_list_next) { + for (display = object->display_list; display; display = display->object_list_next) { block = buf; dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0, - non_modifying_colour); + non_modifying_color); if (bottom_field_len > 0) block = buf + top_field_len; @@ -883,7 +880,7 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx, bottom_field_len = top_field_len; dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1, - non_modifying_colour); + non_modifying_color); } /* } else if (coding_method == 1) {*/ @@ -894,35 +891,12 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx, } -#define SCALEBITS 10 -#define ONE_HALF (1 << (SCALEBITS - 1)) -#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) - -#define YUV_TO_RGB1_CCIR(cb1, cr1)\ -{\ - cb = (cb1) - 128;\ - cr = (cr1) - 128;\ - r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\ - g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \ - ONE_HALF;\ - b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\ -} - -#define YUV_TO_RGB2_CCIR(r, g, b, y1)\ -{\ - y = ((y1) - 16) * FIX(255.0/219.0);\ - r = cm[(y + r_add) >> SCALEBITS];\ - g = cm[(y + g_add) >> SCALEBITS];\ - b = cm[(y + b_add) >> SCALEBITS];\ -} - - static void dvbsub_parse_clut_segment(AVCodecContext *avctx, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - uint8_t *buf_end = buf + buf_size; + const uint8_t *buf_end = buf + buf_size; int clut_id; DVBSubCLUT *clut; int entry_id, depth , full_range; @@ -934,14 +908,13 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n"); - for (i=0; i < buf_size; i++) - { + for (i=0; i < buf_size; i++) { av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); if (i % 16 == 15) av_log(avctx, AV_LOG_INFO, "\n"); } - if (i % 16 != 0) + if (i % 16) av_log(avctx, AV_LOG_INFO, "\n"); #endif @@ -951,7 +924,7 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, clut = get_clut(ctx, clut_id); - if (clut == NULL) { + if (!clut) { clut = av_malloc(sizeof(DVBSubCLUT)); memcpy(clut, &default_clut, sizeof(DVBSubCLUT)); @@ -962,8 +935,7 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, ctx->clut_list = clut; } - while (buf + 4 < buf_end) - { + while (buf + 4 < buf_end) { entry_id = *buf++; depth = (*buf) & 0xe0; @@ -1010,11 +982,11 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, static void dvbsub_parse_region_segment(AVCodecContext *avctx, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; - uint8_t *buf_end = buf + buf_size; + const uint8_t *buf_end = buf + buf_size; int region_id, object_id; DVBSubRegion *region; DVBSubObject *object; @@ -1028,8 +1000,7 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, region = get_region(ctx, region_id); - if (region == NULL) - { + if (!region) { region = av_mallocz(sizeof(DVBSubRegion)); region->id = region_id; @@ -1046,7 +1017,7 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, buf += 2; if (region->width * region->height != region->buf_size) { - if (region->pbuf != 0) + if (region->pbuf) av_free(region->pbuf); region->buf_size = region->width * region->height; @@ -1057,17 +1028,21 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, } region->depth = 1 << (((*buf++) >> 2) & 7); + if(region->depth<2 || region->depth>8){ + av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth); + region->depth= 4; + } region->clut = *buf++; if (region->depth == 8) - region->bgcolour = *buf++; + region->bgcolor = *buf++; else { buf += 1; if (region->depth == 4) - region->bgcolour = (((*buf++) >> 4) & 15); + region->bgcolor = (((*buf++) >> 4) & 15); else - region->bgcolour = (((*buf++) >> 2) & 3); + region->bgcolor = (((*buf++) >> 2) & 3); } #ifdef DEBUG @@ -1075,9 +1050,9 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, #endif if (fill) { - memset(region->pbuf, region->bgcolour, region->buf_size); + memset(region->pbuf, region->bgcolor, region->buf_size); #ifdef DEBUG - av_log(avctx, AV_LOG_INFO, "Fill region (%d)\n", region->bgcolour); + av_log(avctx, AV_LOG_INFO, "Fill region (%d)\n", region->bgcolor); #endif } @@ -1089,7 +1064,7 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, object = get_object(ctx, object_id); - if (object == NULL) { + if (!object) { object = av_mallocz(sizeof(DVBSubObject)); object->id = object_id; @@ -1110,8 +1085,8 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, buf += 2; if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) { - display->fgcolour = *buf++; - display->bgcolour = *buf++; + display->fgcolor = *buf++; + display->bgcolor = *buf++; } display->region_list_next = region->display_list; @@ -1123,13 +1098,13 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, } static void dvbsub_parse_page_segment(AVCodecContext *avctx, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; DVBSubRegionDisplay *display; DVBSubRegionDisplay *tmp_display_list, **tmp_ptr; - uint8_t *buf_end = buf + buf_size; + const uint8_t *buf_end = buf + buf_size; int region_id; int page_state; @@ -1143,8 +1118,7 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx, av_log(avctx, AV_LOG_INFO, "Page time out %ds, state %d\n", ctx->time_out, page_state); #endif - if (page_state == 2) - { + if (page_state == 2) { delete_state(ctx); } @@ -1159,12 +1133,12 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx, display = tmp_display_list; tmp_ptr = &tmp_display_list; - while (display != NULL && display->region_id != region_id) { + while (display && display->region_id != region_id) { tmp_ptr = &display->next; display = display->next; } - if (display == NULL) + if (!display) display = av_mallocz(sizeof(DVBSubRegionDisplay)); display->region_id = region_id; @@ -1185,7 +1159,7 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx, #endif } - while (tmp_display_list != 0) { + while (tmp_display_list) { display = tmp_display_list; tmp_display_list = display->next; @@ -1214,7 +1188,7 @@ static void save_display_set(DVBSubContext *ctx) width = 0; height = 0; - for (display = ctx->display_list; display != NULL; display = display->next) { + for (display = ctx->display_list; display; display = display->next) { region = get_region(ctx, display->region_id); if (x_pos == -1) { @@ -1247,7 +1221,7 @@ static void save_display_set(DVBSubContext *ctx) pbuf = av_malloc(width * height * 4); - for (display = ctx->display_list; display != NULL; display = display->next) { + for (display = ctx->display_list; display; display = display->next) { region = get_region(ctx, display->region_id); x_off = display->x_pos - x_pos; @@ -1280,7 +1254,7 @@ static void save_display_set(DVBSubContext *ctx) } - snprintf(filename, 32, "dvbs.%d", fileno_index); + snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index); png_save2(filename, pbuf, width, height); @@ -1291,7 +1265,7 @@ static void save_display_set(DVBSubContext *ctx) } #endif -static int dvbsub_display_end_segment(AVCodecContext *avctx, uint8_t *buf, +static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size, AVSubtitle *sub) { DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; @@ -1315,11 +1289,11 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, uint8_t *buf, i = 0; - for (display = ctx->display_list; display != NULL; display = display->next) { + for (display = ctx->display_list; display; display = display->next) { region = get_region(ctx, display->region_id); rect = &sub->rects[i]; - if (region == NULL) + if (!region) continue; rect->x = display->x_pos; @@ -1331,7 +1305,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, uint8_t *buf, clut = get_clut(ctx, region->clut); - if (clut == NULL) + if (!clut) clut = &default_clut; switch (region->depth) { @@ -1367,11 +1341,11 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, uint8_t *buf, static int dvbsub_decode(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; AVSubtitle *sub = (AVSubtitle*) data; - uint8_t *p, *p_end; + const uint8_t *p, *p_end; int segment_type; int page_id; int segment_length; @@ -1381,14 +1355,13 @@ static int dvbsub_decode(AVCodecContext *avctx, av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n"); - for (i=0; i < buf_size; i++) - { + for (i=0; i < buf_size; i++) { av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); if (i % 16 == 15) av_log(avctx, AV_LOG_INFO, "\n"); } - if (i % 16 != 0) + if (i % 16) av_log(avctx, AV_LOG_INFO, "\n"); #endif @@ -1399,8 +1372,7 @@ static int dvbsub_decode(AVCodecContext *avctx, p = buf; p_end = buf + buf_size; - while (p < p_end && *p == 0x0f) - { + while (p < p_end && *p == 0x0f) { p += 1; segment_type = *p++; page_id = AV_RB16(p); @@ -1437,8 +1409,7 @@ static int dvbsub_decode(AVCodecContext *avctx, p += segment_length; } - if (p != p_end) - { + if (p != p_end) { #ifdef DEBUG av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n"); #endif @@ -1459,173 +1430,3 @@ AVCodec dvbsub_decoder = { dvbsub_close_decoder, dvbsub_decode, }; - -/* Parser (mostly) copied from dvdsub.c */ - -#define PARSE_BUF_SIZE (65536) - - -/* parser definition */ -typedef struct DVBSubParseContext { - uint8_t *packet_buf; - int packet_start; - int packet_index; - int in_packet; -} DVBSubParseContext; - -static int dvbsub_parse_init(AVCodecParserContext *s) -{ - DVBSubParseContext *pc = s->priv_data; - pc->packet_buf = av_malloc(PARSE_BUF_SIZE); - - return 0; -} - -static int dvbsub_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - DVBSubParseContext *pc = s->priv_data; - uint8_t *p, *p_end; - int len, buf_pos = 0; - -#ifdef DEBUG - av_log(avctx, AV_LOG_INFO, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n", - s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]); -#endif - -#ifdef DEBUG_PACKET_CONTENTS - int i; - - for (i=0; i < buf_size; i++) - { - av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); - if (i % 16 == 15) - av_log(avctx, AV_LOG_INFO, "\n"); - } - - if (i % 16 != 0) - av_log(avctx, AV_LOG_INFO, "\n"); - -#endif - - *poutbuf = NULL; - *poutbuf_size = 0; - - s->fetch_timestamp = 1; - - if (s->last_pts != s->pts && s->last_pts != AV_NOPTS_VALUE) /* Start of a new packet */ - { - if (pc->packet_index != pc->packet_start) - { -#ifdef DEBUG - av_log(avctx, AV_LOG_INFO, "Discarding %d bytes\n", - pc->packet_index - pc->packet_start); -#endif - } - - pc->packet_start = 0; - pc->packet_index = 0; - - if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) { -#ifdef DEBUG - av_log(avctx, AV_LOG_INFO, "Bad packet header\n"); -#endif - return -1; - } - - buf_pos = 2; - - pc->in_packet = 1; - } else { - if (pc->packet_start != 0) - { - if (pc->packet_index != pc->packet_start) - { - memmove(pc->packet_buf, pc->packet_buf + pc->packet_start, - pc->packet_index - pc->packet_start); - - pc->packet_index -= pc->packet_start; - pc->packet_start = 0; - } else { - pc->packet_start = 0; - pc->packet_index = 0; - } - } - } - - if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE) - return -1; - -/* if not currently in a packet, discard data */ - if (pc->in_packet == 0) - return buf_size; - - memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos); - pc->packet_index += buf_size - buf_pos; - - p = pc->packet_buf; - p_end = pc->packet_buf + pc->packet_index; - - while (p < p_end) - { - if (*p == 0x0f) - { - if (p + 6 <= p_end) - { - len = AV_RB16(p + 4); - - if (p + len + 6 <= p_end) - { - *poutbuf_size += len + 6; - - p += len + 6; - } else - break; - } else - break; - } else if (*p == 0xff) { - if (p + 1 < p_end) - { -#ifdef DEBUG - av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n"); -#endif - } - pc->packet_index = p - pc->packet_buf; - pc->in_packet = 0; - break; - } else { - av_log(avctx, AV_LOG_ERROR, "Junk in packet\n"); - - pc->packet_index = p - pc->packet_buf; - pc->in_packet = 0; - break; - } - } - - if (*poutbuf_size > 0) - { - *poutbuf = pc->packet_buf; - pc->packet_start = *poutbuf_size; - } - - if (s->last_pts == AV_NOPTS_VALUE) - s->last_pts = s->pts; - - return buf_size; -} - -static void dvbsub_parse_close(AVCodecParserContext *s) -{ - DVBSubParseContext *pc = s->priv_data; - av_freep(&pc->packet_buf); -} - -AVCodecParser dvbsub_parser = { - { CODEC_ID_DVB_SUBTITLE }, - sizeof(DVBSubParseContext), - dvbsub_parse_init, - dvbsub_parse, - dvbsub_parse_close, -}; diff --git a/contrib/ffmpeg/libavcodec/dvdata.h b/contrib/ffmpeg/libavcodec/dvdata.h index e688ffbb0..50ea537ef 100644 --- a/contrib/ffmpeg/libavcodec/dvdata.h +++ b/contrib/ffmpeg/libavcodec/dvdata.h @@ -24,6 +24,12 @@ * Constants for DV codec. */ +#ifndef FFMPEG_DVDATA_H +#define FFMPEG_DVDATA_H + +#include "avcodec.h" +#include "rational.h" + /* * DVprofile is used to express the differences between various * DV flavors. For now it's primarily used for differentiating @@ -329,7 +335,7 @@ static const uint8_t dv_quant_shifts[22][4] = { static const uint8_t dv_quant_offset[4] = { 6, 3, 0, 1 }; -/* NOTE: I prefer hardcoding the positionning of dv blocks, it is +/* NOTE: I prefer hardcoding the positioning of dv blocks, it is simpler :-) */ static const uint16_t dv_place_420[1620] = { @@ -2534,7 +2540,7 @@ static const uint8_t dv_audio_shuffle625[12][9] = { { 31, 67, 103, 21, 57, 93, 11, 47, 83}, }; -static const __attribute__((unused)) int dv_audio_frequency[3] = { +static const av_unused int dv_audio_frequency[3] = { 48000, 44100, 32000, }; @@ -2655,18 +2661,18 @@ enum dv_pack_type { /* largest possible DV frame, in bytes (PAL 50Mbps) */ #define DV_MAX_FRAME_SIZE 288000 -static inline const DVprofile* dv_frame_profile(uint8_t* frame) +static inline const DVprofile* dv_frame_profile(const uint8_t* frame) { if ((frame[3] & 0x80) == 0) { /* DSF flag */ /* it's an NTSC format */ - if ((frame[80*5 + 48 + 3] & 0x4)) { /* 4:2:2 sampling */ + if ((frame[80*5 + 48 + 3] & 0x4) && (frame[80*5 + 48] == dv_video_source)) { /* 4:2:2 sampling */ return &dv_profiles[3]; /* NTSC 50Mbps */ } else { /* 4:1:1 sampling */ return &dv_profiles[0]; /* NTSC 25Mbps */ } } else { /* it's a PAL format */ - if ((frame[80*5 + 48 + 3] & 0x4)) { /* 4:2:2 sampling */ + if ((frame[80*5 + 48 + 3] & 0x4) && (frame[80*5 + 48] == dv_video_source)) { /* 4:2:2 sampling */ return &dv_profiles[4]; /* PAL 50Mbps */ } else if ((frame[5] & 0x07) == 0) { /* APT flag */ return &dv_profiles[1]; /* PAL 25Mbps 4:2:0 */ @@ -2722,3 +2728,5 @@ static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf) buf[2] = 0xff; /* reserved -- always 1 */ return 3; } + +#endif /* FFMPEG_DVDATA_H */ diff --git a/contrib/ffmpeg/libavcodec/dvdsub_parser.c b/contrib/ffmpeg/libavcodec/dvdsub_parser.c new file mode 100644 index 000000000..0893daca6 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/dvdsub_parser.c @@ -0,0 +1,83 @@ +/* + * DVD subtitle decoding for ffmpeg + * Copyright (c) 2005 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 + */ +#include "avcodec.h" + +/* parser definition */ +typedef struct DVDSubParseContext { + uint8_t *packet; + int packet_len; + int packet_index; +} DVDSubParseContext; + +static int dvdsub_parse_init(AVCodecParserContext *s) +{ + return 0; +} + +static int dvdsub_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + DVDSubParseContext *pc = s->priv_data; + + if (pc->packet_index == 0) { + if (buf_size < 2) + return 0; + pc->packet_len = AV_RB16(buf); + if (pc->packet_len == 0) /* HD-DVD subpicture packet */ + pc->packet_len = AV_RB32(buf+2); + av_freep(&pc->packet); + pc->packet = av_malloc(pc->packet_len); + } + if (pc->packet) { + if (pc->packet_index + buf_size <= pc->packet_len) { + memcpy(pc->packet + pc->packet_index, buf, buf_size); + pc->packet_index += buf_size; + if (pc->packet_index >= pc->packet_len) { + *poutbuf = pc->packet; + *poutbuf_size = pc->packet_len; + pc->packet_index = 0; + return buf_size; + } + } else { + /* erroneous size */ + pc->packet_index = 0; + } + } + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; +} + +static void dvdsub_parse_close(AVCodecParserContext *s) +{ + DVDSubParseContext *pc = s->priv_data; + av_freep(&pc->packet); +} + +AVCodecParser dvdsub_parser = { + { CODEC_ID_DVD_SUBTITLE }, + sizeof(DVDSubParseContext), + dvdsub_parse_init, + dvdsub_parse, + dvdsub_parse_close, +}; diff --git a/contrib/ffmpeg/libavcodec/dvdsubdec.c b/contrib/ffmpeg/libavcodec/dvdsubdec.c index 3a93a6076..0927b7a17 100644 --- a/contrib/ffmpeg/libavcodec/dvdsubdec.c +++ b/contrib/ffmpeg/libavcodec/dvdsubdec.c @@ -19,50 +19,87 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" +#include "bitstream.h" +#include "colorspace.h" +#include "dsputil.h" //#define DEBUG -static int dvdsub_init_decoder(AVCodecContext *avctx) +static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values) { - return 0; + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + uint8_t r, g, b; + int i, y, cb, cr; + int r_add, g_add, b_add; + + for (i = num_values; i > 0; i--) { + y = *ycbcr++; + cb = *ycbcr++; + cr = *ycbcr++; + YUV_TO_RGB1_CCIR(cb, cr); + YUV_TO_RGB2_CCIR(r, g, b, y); + *rgba++ = (*alpha++ << 24) | (r << 16) | (g << 8) | b; + } +} + +static int decode_run_2bit(GetBitContext *gb, int *color) +{ + unsigned int v, t; + + v = 0; + for (t = 1; v < t && t <= 0x40; t <<= 2) + v = (v << 4) | get_bits(gb, 4); + *color = v & 3; + if (v < 4) { /* Code for fill rest of line */ + return INT_MAX; + } + return v >> 2; } -static int get_nibble(const uint8_t *buf, int nibble_offset) +static int decode_run_8bit(GetBitContext *gb, int *color) { - return (buf[nibble_offset >> 1] >> ((1 - (nibble_offset & 1)) << 2)) & 0xf; + int len; + int has_run = get_bits1(gb); + if (get_bits1(gb)) + *color = get_bits(gb, 8); + else + *color = get_bits(gb, 2); + if (has_run) { + if (get_bits1(gb)) { + len = get_bits(gb, 7); + if (len == 0) + len = INT_MAX; + else + len += 9; + } else + len = get_bits(gb, 3) + 2; + } else + len = 1; + return len; } static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, - const uint8_t *buf, int nibble_offset, int buf_size) + const uint8_t *buf, int start, int buf_size, int is_8bit) { - unsigned int v; - int x, y, len, color, nibble_end; + GetBitContext gb; + int bit_len; + int x, y, len, color; uint8_t *d; - nibble_end = buf_size * 2; + bit_len = (buf_size - start) * 8; + init_get_bits(&gb, buf + start, bit_len); + x = 0; y = 0; d = bitmap; for(;;) { - if (nibble_offset >= nibble_end) + if (get_bits_count(&gb) > bit_len) return -1; - v = get_nibble(buf, nibble_offset++); - if (v < 0x4) { - v = (v << 4) | get_nibble(buf, nibble_offset++); - if (v < 0x10) { - v = (v << 4) | get_nibble(buf, nibble_offset++); - if (v < 0x040) { - v = (v << 4) | get_nibble(buf, nibble_offset++); - if (v < 4) { - v |= (w - x) << 2; - } - } - } - } - len = v >> 2; - if (len > (w - x)) - len = (w - x); - color = v & 0x03; + if (is_8bit) + len = decode_run_8bit(&gb, &color); + else + len = decode_run_2bit(&gb, &color); + len = FFMIN(len, w - x); memset(d + x, color, len); x += len; if (x >= w) { @@ -72,14 +109,14 @@ static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, d += linesize; x = 0; /* byte align */ - nibble_offset += (nibble_offset & 1); + align_get_bits(&gb); } } return 0; } static void guess_palette(uint32_t *rgba_palette, - uint8_t *palette, + uint8_t *colormap, uint8_t *alpha, uint32_t subtitle_color) { @@ -92,8 +129,8 @@ static void guess_palette(uint32_t *rgba_palette, memset(color_used, 0, 16); nb_opaque_colors = 0; for(i = 0; i < 4; i++) { - if (alpha[i] != 0 && !color_used[palette[i]]) { - color_used[palette[i]] = 1; + if (alpha[i] != 0 && !color_used[colormap[i]]) { + color_used[colormap[i]] = 1; nb_opaque_colors++; } } @@ -105,47 +142,62 @@ static void guess_palette(uint32_t *rgba_palette, memset(color_used, 0, 16); for(i = 0; i < 4; i++) { if (alpha[i] != 0) { - if (!color_used[palette[i]]) { + if (!color_used[colormap[i]]) { level = (0xff * j) / nb_opaque_colors; r = (((subtitle_color >> 16) & 0xff) * level) >> 8; g = (((subtitle_color >> 8) & 0xff) * level) >> 8; b = (((subtitle_color >> 0) & 0xff) * level) >> 8; rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24); - color_used[palette[i]] = (i + 1); + color_used[colormap[i]] = (i + 1); j--; } else { - rgba_palette[i] = (rgba_palette[color_used[palette[i]] - 1] & 0x00ffffff) | + rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) | ((alpha[i] * 17) << 24); } } } } +#define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a)) + static int decode_dvd_subtitles(AVSubtitle *sub_header, const uint8_t *buf, int buf_size) { int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos; - uint8_t palette[4], alpha[4]; + int big_offsets, offset_size, is_8bit = 0; + const uint8_t *yuv_palette = 0; + uint8_t colormap[4], alpha[256]; int date; int i; int is_menu = 0; - if (buf_size < 4) + if (buf_size < 10) return -1; sub_header->rects = NULL; sub_header->num_rects = 0; sub_header->start_display_time = 0; sub_header->end_display_time = 0; - cmd_pos = AV_RB16(buf + 2); - while ((cmd_pos + 4) < buf_size) { + if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */ + big_offsets = 1; + offset_size = 4; + cmd_pos = 6; + } else { + big_offsets = 0; + offset_size = 2; + cmd_pos = 2; + } + + cmd_pos = READ_OFFSET(buf + cmd_pos); + + while ((cmd_pos + 2 + offset_size) < buf_size) { date = AV_RB16(buf + cmd_pos); - next_cmd_pos = AV_RB16(buf + cmd_pos + 2); + next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2); #ifdef DEBUG av_log(NULL, AV_LOG_INFO, "cmd_pos=0x%04x next=0x%04x date=%d\n", cmd_pos, next_cmd_pos, date); #endif - pos = cmd_pos + 4; + pos = cmd_pos + 2 + offset_size; offset1 = -1; offset2 = -1; x1 = y1 = x2 = y2 = 0; @@ -168,13 +220,13 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, sub_header->end_display_time = (date << 10) / 90; break; case 0x03: - /* set palette */ + /* set colormap */ if ((buf_size - pos) < 2) goto fail; - palette[3] = buf[pos] >> 4; - palette[2] = buf[pos] & 0x0f; - palette[1] = buf[pos + 1] >> 4; - palette[0] = buf[pos + 1] & 0x0f; + colormap[3] = buf[pos] >> 4; + colormap[2] = buf[pos] & 0x0f; + colormap[1] = buf[pos + 1] >> 4; + colormap[0] = buf[pos + 1] & 0x0f; pos += 2; break; case 0x04: @@ -191,12 +243,15 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, #endif break; case 0x05: + case 0x85: if ((buf_size - pos) < 6) goto fail; x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4); x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2]; y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4); y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5]; + if (cmd & 0x80) + is_8bit = 1; #ifdef DEBUG av_log(NULL, AV_LOG_INFO, "x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2); @@ -213,8 +268,39 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, #endif pos += 4; break; + case 0x86: + if ((buf_size - pos) < 8) + goto fail; + offset1 = AV_RB32(buf + pos); + offset2 = AV_RB32(buf + pos + 4); +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); +#endif + pos += 8; + break; + + case 0x83: + /* HD set palette */ + if ((buf_size - pos) < 768) + goto fail; + yuv_palette = buf + pos; + pos += 768; + break; + case 0x84: + /* HD set contrast (alpha) */ + if ((buf_size - pos) < 256) + goto fail; + for (i = 0; i < 256; i++) + alpha[i] = 0xFF - buf[pos+i]; + pos += 256; + break; + case 0xff: + goto the_end; default: +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "unrecognised subpicture command 0x%x\n", cmd); +#endif goto the_end; } } @@ -243,20 +329,28 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, bitmap = av_malloc(w * h); sub_header->rects = av_mallocz(sizeof(AVSubtitleRect)); sub_header->num_rects = 1; - sub_header->rects[0].rgba_palette = av_malloc(4 * 4); + sub_header->rects[0].bitmap = bitmap; decode_rle(bitmap, w * 2, w, (h + 1) / 2, - buf, offset1 * 2, buf_size); + buf, offset1, buf_size, is_8bit); decode_rle(bitmap + w, w * 2, w, h / 2, - buf, offset2 * 2, buf_size); - guess_palette(sub_header->rects[0].rgba_palette, - palette, alpha, 0xffff00); + buf, offset2, buf_size, is_8bit); + if (is_8bit) { + if (yuv_palette == 0) + goto fail; + sub_header->rects[0].rgba_palette = av_malloc(256 * 4); + sub_header->rects[0].nb_colors = 256; + yuv_a_to_rgba(yuv_palette, alpha, sub_header->rects[0].rgba_palette, 256); + } else { + sub_header->rects[0].rgba_palette = av_malloc(4 * 4); + sub_header->rects[0].nb_colors = 4; + guess_palette(sub_header->rects[0].rgba_palette, + colormap, alpha, 0xffff00); + } sub_header->rects[0].x = x1; sub_header->rects[0].y = y1; sub_header->rects[0].w = w; sub_header->rects[0].h = h; - sub_header->rects[0].nb_colors = 4; sub_header->rects[0].linesize = w; - sub_header->rects[0].bitmap = bitmap; } } if (next_cmd_pos == cmd_pos) @@ -266,6 +360,14 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, if (sub_header->num_rects > 0) return is_menu; fail: + if (sub_header->rects != NULL) { + for (i = 0; i < sub_header->num_rects; i++) { + av_free(sub_header->rects[i].bitmap); + av_free(sub_header->rects[i].rgba_palette); + } + av_freep(&sub_header->rects); + sub_header->num_rects = 0; + } return -1; } @@ -336,11 +438,6 @@ static int find_smallest_bounding_rectangle(AVSubtitle *s) return 1; } -static int dvdsub_close_decoder(AVCodecContext *avctx) -{ - return 0; -} - #ifdef DEBUG #undef fprintf static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h, @@ -372,7 +469,7 @@ static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h, static int dvdsub_decode(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { AVSubtitle *sub = (void *)data; int is_menu; @@ -405,68 +502,8 @@ AVCodec dvdsub_decoder = { CODEC_TYPE_SUBTITLE, CODEC_ID_DVD_SUBTITLE, 0, - dvdsub_init_decoder, NULL, - dvdsub_close_decoder, + NULL, + NULL, dvdsub_decode, }; - -/* parser definition */ -typedef struct DVDSubParseContext { - uint8_t *packet; - int packet_len; - int packet_index; -} DVDSubParseContext; - -static int dvdsub_parse_init(AVCodecParserContext *s) -{ - return 0; -} - -static int dvdsub_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - DVDSubParseContext *pc = s->priv_data; - - if (pc->packet_index == 0) { - if (buf_size < 2) - return 0; - pc->packet_len = AV_RB16(buf); - av_freep(&pc->packet); - pc->packet = av_malloc(pc->packet_len); - } - if (pc->packet) { - if (pc->packet_index + buf_size <= pc->packet_len) { - memcpy(pc->packet + pc->packet_index, buf, buf_size); - pc->packet_index += buf_size; - if (pc->packet_index >= pc->packet_len) { - *poutbuf = pc->packet; - *poutbuf_size = pc->packet_len; - pc->packet_index = 0; - return buf_size; - } - } else { - /* erroneous size */ - pc->packet_index = 0; - } - } - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; -} - -static void dvdsub_parse_close(AVCodecParserContext *s) -{ - DVDSubParseContext *pc = s->priv_data; - av_freep(&pc->packet); -} - -AVCodecParser dvdsub_parser = { - { CODEC_ID_DVD_SUBTITLE }, - sizeof(DVDSubParseContext), - dvdsub_parse_init, - dvdsub_parse, - dvdsub_parse_close, -}; diff --git a/contrib/ffmpeg/libavcodec/dvdsubenc.c b/contrib/ffmpeg/libavcodec/dvdsubenc.c index fac29acc2..77ea88c96 100644 --- a/contrib/ffmpeg/libavcodec/dvdsubenc.c +++ b/contrib/ffmpeg/libavcodec/dvdsubenc.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" +#include "bytestream.h" #undef NDEBUG #include <assert.h> @@ -85,14 +86,6 @@ static void dvd_encode_rle(uint8_t **pq, *pq = q; } -static inline void putbe16(uint8_t **pq, uint16_t v) -{ - uint8_t *q = *pq; - *q++ = v >> 8; - *q++ = v; - *pq = q; -} - static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size, const AVSubtitle *h) { @@ -163,11 +156,11 @@ static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size, // set data packet size qq = outbuf + 2; - putbe16(&qq, q - outbuf); + bytestream_put_be16(&qq, q - outbuf); // send start display command - putbe16(&q, (h->start_display_time*90) >> 10); - putbe16(&q, (q - outbuf) /*- 2 */ + 8 + 12*rects + 2); + bytestream_put_be16(&q, (h->start_display_time*90) >> 10); + bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12*rects + 2); *q++ = 0x03; // palette - 4 nibbles *q++ = 0x03; *q++ = 0x7f; *q++ = 0x04; // alpha - 4 nibbles @@ -192,35 +185,25 @@ static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size, *q++ = 0x06; // offset1, offset2 - putbe16(&q, offset1[object_id]); - putbe16(&q, offset2[object_id]); + bytestream_put_be16(&q, offset1[object_id]); + bytestream_put_be16(&q, offset2[object_id]); } *q++ = 0x01; // start command *q++ = 0xff; // terminating command // send stop display command last - putbe16(&q, (h->end_display_time*90) >> 10); - putbe16(&q, (q - outbuf) - 2 /*+ 4*/); + bytestream_put_be16(&q, (h->end_display_time*90) >> 10); + bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/); *q++ = 0x02; // set end *q++ = 0xff; // terminating command qq = outbuf; - putbe16(&qq, q - outbuf); + bytestream_put_be16(&qq, q - outbuf); av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - outbuf); return q - outbuf; } -static int dvdsub_init_encoder(AVCodecContext *avctx) -{ - return 0; -} - -static int dvdsub_close_encoder(AVCodecContext *avctx) -{ - return 0; -} - static int dvdsub_encode(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data) { @@ -237,11 +220,6 @@ AVCodec dvdsub_encoder = { CODEC_TYPE_SUBTITLE, CODEC_ID_DVD_SUBTITLE, 0, - dvdsub_init_encoder, + NULL, dvdsub_encode, - dvdsub_close_encoder, }; - -/* Local Variables: */ -/* c-basic-offset:4 */ -/* End: */ diff --git a/contrib/ffmpeg/libavcodec/dxa.c b/contrib/ffmpeg/libavcodec/dxa.c index fc201ccb4..46b01cd81 100644 --- a/contrib/ffmpeg/libavcodec/dxa.c +++ b/contrib/ffmpeg/libavcodec/dxa.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -28,7 +27,6 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" #include <zlib.h> @@ -189,9 +187,9 @@ static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint return 0; } -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { - DxaDecContext * const c = (DxaDecContext *)avctx->priv_data; + DxaDecContext * const c = avctx->priv_data; uint8_t *outptr, *srcptr, *tmpptr; unsigned long dsize; int i, j, compr; @@ -289,7 +287,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 static int decode_init(AVCodecContext *avctx) { - DxaDecContext * const c = (DxaDecContext *)avctx->priv_data; + DxaDecContext * const c = avctx->priv_data; c->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; @@ -309,7 +307,7 @@ static int decode_init(AVCodecContext *avctx) static int decode_end(AVCodecContext *avctx) { - DxaDecContext * const c = (DxaDecContext *)avctx->priv_data; + DxaDecContext * const c = avctx->priv_data; av_freep(&c->decomp_buf); if(c->prev.data[0]) diff --git a/contrib/ffmpeg/libavcodec/elbg.c b/contrib/ffmpeg/libavcodec/elbg.c new file mode 100644 index 000000000..cd5b5ed4f --- /dev/null +++ b/contrib/ffmpeg/libavcodec/elbg.c @@ -0,0 +1,417 @@ +/* + * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com> + * + * 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 cbook_gen.c + * Codebook Generator using the ELBG algorithm + */ + +#include <string.h> + +#include "elbg.h" +#include "avcodec.h" +#include "random.h" + +#define DELTA_ERR_MAX 0.1 ///< Precision of the ELBG algorithm (as percentual error) + +/** + * In the ELBG jargon, a cell is the set of points that are closest to a + * codebook entry. Not to be confused with a RoQ Video cell. */ +typedef struct cell_s { + int index; + struct cell_s *next; +} cell; + +/** + * ELBG internal data + */ +typedef struct{ + int error; + int dim; + int numCB; + int *codebook; + cell **cells; + int *utility; + int *utility_inc; + int *nearest_cb; + int *points; + AVRandomState *rand_state; +} elbg_data; + +static inline int distance_limited(int *a, int *b, int dim, int limit) +{ + int i, dist=0; + for (i=0; i<dim; i++) { + dist += (a[i] - b[i])*(a[i] - b[i]); + if (dist > limit) + return INT_MAX; + } + + return dist; +} + +static inline void vect_division(int *res, int *vect, int div, int dim) +{ + int i; + if (div > 1) + for (i=0; i<dim; i++) + res[i] = ROUNDED_DIV(vect[i],div); + else if (res != vect) + memcpy(res, vect, dim*sizeof(int)); + +} + +static int eval_error_cell(elbg_data *elbg, int *centroid, cell *cells) +{ + int error=0; + for (; cells; cells=cells->next) + error += distance_limited(centroid, elbg->points + cells->index*elbg->dim, elbg->dim, INT_MAX); + + return error; +} + +static int get_closest_codebook(elbg_data *elbg, int index) +{ + int i, pick=0, diff, diff_min = INT_MAX; + for (i=0; i<elbg->numCB; i++) + if (i != index) { + diff = distance_limited(elbg->codebook + i*elbg->dim, elbg->codebook + index*elbg->dim, elbg->dim, diff_min); + if (diff < diff_min) { + pick = i; + diff_min = diff; + } + } + return pick; +} + +static int get_high_utility_cell(elbg_data *elbg) +{ + int i=0; + /* Using linear search, do binary if it ever turns to be speed critical */ + int r = av_random(elbg->rand_state)%elbg->utility_inc[elbg->numCB-1]; + while (elbg->utility_inc[i] < r) + i++; + return i; +} + +/** + * Implementation of the simple LBG algorithm for just two codebooks + */ +static int simple_lbg(int dim, + int *centroid[3], + int newutility[3], + int *points, + cell *cells) +{ + int i, idx; + int numpoints[2] = {0,0}; + int newcentroid[2][dim]; + cell *tempcell; + + memset(newcentroid, 0, sizeof(newcentroid)); + + newutility[0] = + newutility[1] = 0; + + for (tempcell = cells; tempcell; tempcell=tempcell->next) { + idx = distance_limited(centroid[0], points + tempcell->index*dim, dim, INT_MAX)>= + distance_limited(centroid[1], points + tempcell->index*dim, dim, INT_MAX); + numpoints[idx]++; + for (i=0; i<dim; i++) + newcentroid[idx][i] += points[tempcell->index*dim + i]; + } + + vect_division(centroid[0], newcentroid[0], numpoints[0], dim); + vect_division(centroid[1], newcentroid[1], numpoints[1], dim); + + for (tempcell = cells; tempcell; tempcell=tempcell->next) { + int dist[2] = {distance_limited(centroid[0], points + tempcell->index*dim, dim, INT_MAX), + distance_limited(centroid[1], points + tempcell->index*dim, dim, INT_MAX)}; + int idx = dist[0] > dist[1]; + newutility[idx] += dist[idx]; + } + + return newutility[0] + newutility[1]; +} + +static void get_new_centroids(elbg_data *elbg, int huc, int *newcentroid_i, + int *newcentroid_p) +{ + cell *tempcell; + int min[elbg->dim]; + int max[elbg->dim]; + int i; + + for (i=0; i< elbg->dim; i++) { + min[i]=INT_MAX; + max[i]=0; + } + + for (tempcell = elbg->cells[huc]; tempcell; tempcell = tempcell->next) + for(i=0; i<elbg->dim; i++) { + min[i]=FFMIN(min[i], elbg->points[tempcell->index*elbg->dim + i]); + max[i]=FFMAX(max[i], elbg->points[tempcell->index*elbg->dim + i]); + } + + for (i=0; i<elbg->dim; i++) { + newcentroid_i[i] = min[i] + (max[i] - min[i])/3; + newcentroid_p[i] = min[i] + (2*(max[i] - min[i]))/3; + } +} + +/** + * Add the points in the low utility cell to its closest cell. Split the high + * utility cell, putting the separed points in the (now empty) low utility + * cell. + * + * @param elbg Internal elbg data + * @param indexes {luc, huc, cluc} + * @param newcentroid A vector with the position of the new centroids + */ +static void shift_codebook(elbg_data *elbg, int *indexes, + int *newcentroid[3]) +{ + cell *tempdata; + cell **pp = &elbg->cells[indexes[2]]; + + while(*pp) + pp= &(*pp)->next; + + *pp = elbg->cells[indexes[0]]; + + elbg->cells[indexes[0]] = NULL; + tempdata = elbg->cells[indexes[1]]; + elbg->cells[indexes[1]] = NULL; + + while(tempdata) { + cell *tempcell2 = tempdata->next; + int idx = distance_limited(elbg->points + tempdata->index*elbg->dim, + newcentroid[0], elbg->dim, INT_MAX) > + distance_limited(elbg->points + tempdata->index*elbg->dim, + newcentroid[1], elbg->dim, INT_MAX); + + tempdata->next = elbg->cells[indexes[idx]]; + elbg->cells[indexes[idx]] = tempdata; + tempdata = tempcell2; + } +} + +static void evaluate_utility_inc(elbg_data *elbg) +{ + int i, inc=0; + + for (i=0; i < elbg->numCB; i++) { + if (elbg->numCB*elbg->utility[i] > elbg->error) + inc += elbg->utility[i]; + elbg->utility_inc[i] = inc; + } +} + + +static void update_utility_and_n_cb(elbg_data *elbg, int idx, int newutility) +{ + cell *tempcell; + + elbg->utility[idx] = newutility; + for (tempcell=elbg->cells[idx]; tempcell; tempcell=tempcell->next) + elbg->nearest_cb[tempcell->index] = idx; +} + +/** + * Evaluate if a shift lower the error. If it does, call shift_codebooks + * and update elbg->error, elbg->utility and elbg->nearest_cb. + * + * @param elbg Internal elbg data + * @param indexes {luc (low utility cell, huc (high utility cell), cluc (closest cell to low utility cell)} + */ +static void try_shift_candidate(elbg_data *elbg, int idx[3]) +{ + int j, k, olderror=0, newerror, cont=0; + int newutility[3]; + int newcentroid[3][elbg->dim]; + int *newcentroid_ptrs[3] = { newcentroid[0], newcentroid[1], newcentroid[2] }; + cell *tempcell; + + for (j=0; j<3; j++) + olderror += elbg->utility[idx[j]]; + + memset(newcentroid[2], 0, elbg->dim*sizeof(int)); + + for (k=0; k<2; k++) + for (tempcell=elbg->cells[idx[2*k]]; tempcell; tempcell=tempcell->next) { + cont++; + for (j=0; j<elbg->dim; j++) + newcentroid[2][j] += elbg->points[tempcell->index*elbg->dim + j]; + } + + vect_division(newcentroid[2], newcentroid[2], cont, elbg->dim); + + get_new_centroids(elbg, idx[1], newcentroid[0], newcentroid[1]); + + newutility[2] = eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[0]]); + newutility[2] += eval_error_cell(elbg, newcentroid[2], elbg->cells[idx[2]]); + + newerror = newutility[2]; + + newerror += simple_lbg(elbg->dim, newcentroid_ptrs, newutility, elbg->points, + elbg->cells[idx[1]]); + + if (olderror > newerror) { + shift_codebook(elbg, idx, newcentroid_ptrs); + + elbg->error += newerror - olderror; + + for (j=0; j<3; j++) + update_utility_and_n_cb(elbg, idx[j], newutility[j]); + + evaluate_utility_inc(elbg); + } + } + +/** + * Implementation of the ELBG block + */ +static void do_shiftings(elbg_data *elbg) +{ + int idx[3]; + + evaluate_utility_inc(elbg); + + for (idx[0]=0; idx[0] < elbg->numCB; idx[0]++) + if (elbg->numCB*elbg->utility[idx[0]] < elbg->error) { + if (elbg->utility_inc[elbg->numCB-1] == 0) + return; + + idx[1] = get_high_utility_cell(elbg); + idx[2] = get_closest_codebook(elbg, idx[0]); + + try_shift_candidate(elbg, idx); + } +} + +#define BIG_PRIME 433494437LL + +void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, + int numCB, int max_steps, int *closest_cb, + AVRandomState *rand_state) +{ + int i, k; + + if (numpoints > 24*numCB) { + /* ELBG is very costly for a big number of points. So if we have a lot + of them, get a good initial codebook to save on iterations */ + int *temp_points = av_malloc(dim*(numpoints/8)*sizeof(int)); + for (i=0; i<numpoints/8; i++) { + k = (i*BIG_PRIME) % numpoints; + memcpy(temp_points + i*dim, points + k*dim, dim*sizeof(int)); + } + + ff_init_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state); + ff_do_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state); + + av_free(temp_points); + + } else // If not, initialize the codebook with random positions + for (i=0; i < numCB; i++) + memcpy(codebook + i*dim, points + ((i*BIG_PRIME)%numpoints)*dim, + dim*sizeof(int)); + +} + +void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, + int numCB, int max_steps, int *closest_cb, + AVRandomState *rand_state) +{ + int dist; + elbg_data elbg_d; + elbg_data *elbg = &elbg_d; + int i, j, k, last_error, steps=0; + int *dist_cb = av_malloc(numpoints*sizeof(int)); + int *size_part = av_malloc(numCB*sizeof(int)); + cell *list_buffer = av_malloc(numpoints*sizeof(cell)); + cell *free_cells; + + elbg->error = INT_MAX; + elbg->dim = dim; + elbg->numCB = numCB; + elbg->codebook = codebook; + elbg->cells = av_malloc(numCB*sizeof(cell *)); + elbg->utility = av_malloc(numCB*sizeof(int)); + elbg->nearest_cb = closest_cb; + elbg->points = points; + elbg->utility_inc = av_malloc(numCB*sizeof(int)); + + elbg->rand_state = rand_state; + + do { + free_cells = list_buffer; + last_error = elbg->error; + steps++; + memset(elbg->utility, 0, numCB*sizeof(int)); + memset(elbg->cells, 0, numCB*sizeof(cell *)); + + elbg->error = 0; + + /* This loop evaluate the actual Voronoi partition. It is the most + costly part of the algorithm. */ + for (i=0; i < numpoints; i++) { + dist_cb[i] = INT_MAX; + for (k=0; k < elbg->numCB; k++) { + dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + k*elbg->dim, dim, dist_cb[i]); + if (dist < dist_cb[i]) { + dist_cb[i] = dist; + elbg->nearest_cb[i] = k; + } + } + elbg->error += dist_cb[i]; + elbg->utility[elbg->nearest_cb[i]] += dist_cb[i]; + free_cells->index = i; + free_cells->next = elbg->cells[elbg->nearest_cb[i]]; + elbg->cells[elbg->nearest_cb[i]] = free_cells; + free_cells++; + } + + do_shiftings(elbg); + + memset(size_part, 0, numCB*sizeof(int)); + + memset(elbg->codebook, 0, elbg->numCB*dim*sizeof(int)); + + for (i=0; i < numpoints; i++) { + size_part[elbg->nearest_cb[i]]++; + for (j=0; j < elbg->dim; j++) + elbg->codebook[elbg->nearest_cb[i]*elbg->dim + j] += + elbg->points[i*elbg->dim + j]; + } + + for (i=0; i < elbg->numCB; i++) + vect_division(elbg->codebook + i*elbg->dim, + elbg->codebook + i*elbg->dim, size_part[i], elbg->dim); + + } while(((last_error - elbg->error) > DELTA_ERR_MAX*elbg->error) && + (steps < max_steps)); + + av_free(dist_cb); + av_free(size_part); + av_free(elbg->utility); + av_free(list_buffer); + av_free(elbg->cells); + av_free(elbg->utility_inc); +} diff --git a/contrib/ffmpeg/libavcodec/elbg.h b/contrib/ffmpeg/libavcodec/elbg.h new file mode 100644 index 000000000..1b2e45c4e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/elbg.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com> + * + * 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 + */ + +#ifndef FFMPEG_ELBG_H +#define FFMPEG_ELBG_H + +#include "random.h" + +/** + * Implementation of the Enhanced LBG Algorithm + * Based on the paper "Neural Networks 14:1219-1237" that can be found in + * http://citeseer.ist.psu.edu/patan01enhanced.html . + * + * @param points Input points. + * @param dim Dimension of the points. + * @param numpoints Num of points in **points. + * @param codebook Pointer to the output codebook. Must be allocated. + * @param numCB Number of points in the codebook. + * @param num_steps The maximum number of steps. One step is already a good compromise between time and quality. + * @param closest_cb Return the closest codebook to each point. Must be allocated. + * @param rand_state A random number generator state. Should be already initialised by av_init_random. + */ +void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, + int numCB, int num_steps, int *closest_cb, + AVRandomState *rand_state); + +/** + * Initialize the **codebook vector for the elbg algorithm. If you have already + * a codebook and you want to refine it, you shouldn't call this function. + * If numpoints < 8*numCB this function fills **codebook with random numbers. + * If not, it calls ff_do_elbg for a (smaller) random sample of the points in + * **points. Get the same parameters as ff_do_elbg. + */ +void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, + int numCB, int num_steps, int *closest_cb, + AVRandomState *rand_state); + +#endif /* FFMPEG_ELBG_H */ diff --git a/contrib/ffmpeg/libavcodec/error_resilience.c b/contrib/ffmpeg/libavcodec/error_resilience.c index 175ccf73a..17f04d5ab 100644 --- a/contrib/ffmpeg/libavcodec/error_resilience.c +++ b/contrib/ffmpeg/libavcodec/error_resilience.c @@ -30,7 +30,6 @@ #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" -#include "common.h" static void decode_mb(MpegEncContext *s){ s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16; @@ -109,7 +108,7 @@ static void filter181(int16_t *data, int width, int height, int stride){ } /** - * guess the dc of blocks which dont have a undamaged dc + * guess the dc of blocks which do not have an undamaged dc * @param w width in 8 pixel blocks * @param h height in 8 pixel blocks */ @@ -564,6 +563,11 @@ static int is_intra_more_likely(MpegEncContext *s){ if(undamaged_count < 5) return 0; //allmost all MBs damaged -> use temporal prediction +#ifdef HAVE_XVMC + //prevent dsp.sad() check, that requires access to the image + if(s->avctx->xvmc_acceleration && s->pict_type==I_TYPE) return 1; +#endif + skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs is_intra_likely=0; @@ -765,7 +769,7 @@ void ff_er_frame_end(MpegEncContext *s){ if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END) && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END) - && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninited + && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit end_ok=0; } diff --git a/contrib/ffmpeg/libavcodec/eval.c b/contrib/ffmpeg/libavcodec/eval.c index 877de3552..dc0012bf6 100644 --- a/contrib/ffmpeg/libavcodec/eval.c +++ b/contrib/ffmpeg/libavcodec/eval.c @@ -19,7 +19,6 @@ * 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 - * */ /** @@ -56,7 +55,7 @@ typedef struct Parser{ double (**func2)(void *, double a, double b); // NULL terminated char **func2_name; // NULL terminated void *opaque; - char **error; + const char **error; #define VARS 10 double var[VARS]; } Parser; @@ -377,10 +376,10 @@ static int verify_expr(AVEvalExpr * e) { } } -AVEvalExpr * ff_parse(char *s, const char **const_name, +AVEvalExpr * ff_parse(const char *s, const char **const_name, double (**func1)(void *, double), const char **func1_name, double (**func2)(void *, double, double), char **func2_name, - char **error){ + const char **error){ Parser p; AVEvalExpr * e; char w[strlen(s) + 1], * wp = w; @@ -414,10 +413,10 @@ double ff_parse_eval(AVEvalExpr * e, double *const_value, void *opaque) { return eval_expr(&p, e); } -double ff_eval2(char *s, double *const_value, const char **const_name, +double ff_eval2(const char *s, double *const_value, const char **const_name, double (**func1)(void *, double), const char **func1_name, double (**func2)(void *, double, double), char **func2_name, - void *opaque, char **error){ + void *opaque, const char **error){ AVEvalExpr * e = ff_parse(s, const_name, func1, func1_name, func2, func2_name, error); double d; if (!e) return NAN; @@ -431,7 +430,7 @@ attribute_deprecated double ff_eval(char *s, double *const_value, const char **c double (**func1)(void *, double), const char **func1_name, double (**func2)(void *, double, double), char **func2_name, void *opaque){ - char *error=NULL; + const char *error=NULL; double ret; ret = ff_eval2(s, const_value, const_name, func1, func1_name, func2, func2_name, opaque, &error); if (error) @@ -452,7 +451,7 @@ static const char *const_names[]={ "E", 0 }; -main(){ +int main(void){ int i; printf("%f == 12.7\n", ff_eval("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL)); printf("%f == 0.931322575\n", ff_eval("80G/80Gi", const_values, const_names, NULL, NULL, NULL, NULL, NULL)); @@ -462,5 +461,6 @@ main(){ ff_eval("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL); STOP_TIMER("ff_eval") } + return 0; } #endif diff --git a/contrib/ffmpeg/libavcodec/eval.h b/contrib/ffmpeg/libavcodec/eval.h index b52199cf4..786e950c0 100644 --- a/contrib/ffmpeg/libavcodec/eval.h +++ b/contrib/ffmpeg/libavcodec/eval.h @@ -25,10 +25,13 @@ * eval header. */ -#ifndef AVCODEC_EVAL_H -#define AVCODEC_EVAL_H +#ifndef FFMPEG_EVAL_H +#define FFMPEG_EVAL_H #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) +/** + * @deprecated Use ff_eval2 instead + */ double ff_eval(char *s, double *const_value, const char **const_name, double (**func1)(void *, double), const char **func1_name, double (**func2)(void *, double, double), char **func2_name, @@ -49,10 +52,10 @@ double ff_eval(char *s, double *const_value, const char **const_name, * @param opaque a pointer which will be passed to all functions from func1 and func2 * @return the value of the expression */ -double ff_eval2(char *s, double *const_value, const char **const_name, +double ff_eval2(const char *s, double *const_value, const char **const_name, double (**func1)(void *, double), const char **func1_name, double (**func2)(void *, double, double), char **func2_name, - void *opaque, char **error); + void *opaque, const char **error); typedef struct ff_expr_s AVEvalExpr; @@ -65,13 +68,13 @@ typedef struct ff_expr_s AVEvalExpr; * @param func1_name NULL terminated array of zero terminated strings of func1 identifers * @param func2_name NULL terminated array of zero terminated strings of func2 identifers * @param error pointer to a char* which is set to an error message if something goes wrong - * @return AVEvalExpr which must be freed with ff_eval_free by the user when its not needed anymore + * @return AVEvalExpr which must be freed with ff_eval_free by the user when it is not needed anymore * NULL if anything went wrong */ -AVEvalExpr * ff_parse(char *s, const char **const_name, +AVEvalExpr * ff_parse(const char *s, const char **const_name, double (**func1)(void *, double), const char **func1_name, double (**func2)(void *, double, double), char **func2_name, - char **error); + const char **error); /** * Evaluates a previously parsed expression. * @param const_value a zero terminated array of values for the identifers from ff_parse const_name @@ -81,4 +84,4 @@ AVEvalExpr * ff_parse(char *s, const char **const_name, double ff_parse_eval(AVEvalExpr * e, double *const_value, void *opaque); void ff_eval_free(AVEvalExpr * e); -#endif /* AVCODEC_EVAL_H */ +#endif /* FFMPEG_EVAL_H */ diff --git a/contrib/ffmpeg/libavcodec/faandct.c b/contrib/ffmpeg/libavcodec/faandct.c index 6f73ee5e9..014c2d751 100644 --- a/contrib/ffmpeg/libavcodec/faandct.c +++ b/contrib/ffmpeg/libavcodec/faandct.c @@ -2,6 +2,8 @@ * Floating point AAN DCT * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * + * this implementation is based upon the IJG integer AAN DCT (see jfdctfst.c) + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,7 +20,8 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * this implementation is based upon the IJG integer AAN DCT (see jfdctfst.c) + * The AAN DCT in this file except ff_faandct248() can also be used under the + * new (3 clause) BSD license. */ /** @@ -74,7 +77,7 @@ static av_always_inline void row_fdct(FLOAT temp[64], DCTELEM * data) { FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; FLOAT tmp10, tmp11, tmp12, tmp13; - FLOAT z1, z2, z3, z4, z5, z11, z13; + FLOAT z2, z4, z5, z11, z13; int i; for (i=0; i<8*8; i+=8) { @@ -95,21 +98,27 @@ static av_always_inline void row_fdct(FLOAT temp[64], DCTELEM * data) temp[0 + i]= tmp10 + tmp11; temp[4 + i]= tmp10 - tmp11; - z1= (tmp12 + tmp13)*A1; - temp[2 + i]= tmp13 + z1; - temp[6 + i]= tmp13 - z1; + tmp12 += tmp13; + tmp12 *= A1; + temp[2 + i]= tmp13 + tmp12; + temp[6 + i]= tmp13 - tmp12; - tmp10= tmp4 + tmp5; - tmp11= tmp5 + tmp6; - tmp12= tmp6 + tmp7; + tmp4 += tmp5; + tmp5 += tmp6; + tmp6 += tmp7; - z5= (tmp10 - tmp12) * A5; - z2= tmp10*A2 + z5; - z4= tmp12*A4 + z5; - z3= tmp11*A1; +#if 0 + z5= (tmp4 - tmp6) * A5; + z2= tmp4*A2 + z5; + z4= tmp6*A4 + z5; +#else + z2= tmp4*(A2+A5) - tmp6*A5; + z4= tmp6*(A4-A5) + tmp4*A5; +#endif + tmp5*=A1; - z11= tmp7 + z3; - z13= tmp7 - z3; + z11= tmp7 + tmp5; + z13= tmp7 - tmp5; temp[5 + i]= z13 + z2; temp[3 + i]= z13 - z2; @@ -122,7 +131,7 @@ void ff_faandct(DCTELEM * data) { FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; FLOAT tmp10, tmp11, tmp12, tmp13; - FLOAT z1, z2, z3, z4, z5, z11, z13; + FLOAT z2, z4, z5, z11, z13; FLOAT temp[64]; int i; @@ -148,21 +157,27 @@ void ff_faandct(DCTELEM * data) data[8*0 + i]= lrintf(SCALE(8*0 + i) * (tmp10 + tmp11)); data[8*4 + i]= lrintf(SCALE(8*4 + i) * (tmp10 - tmp11)); - z1= (tmp12 + tmp13)* A1; - data[8*2 + i]= lrintf(SCALE(8*2 + i) * (tmp13 + z1)); - data[8*6 + i]= lrintf(SCALE(8*6 + i) * (tmp13 - z1)); + tmp12 += tmp13; + tmp12 *= A1; + data[8*2 + i]= lrintf(SCALE(8*2 + i) * (tmp13 + tmp12)); + data[8*6 + i]= lrintf(SCALE(8*6 + i) * (tmp13 - tmp12)); - tmp10= tmp4 + tmp5; - tmp11= tmp5 + tmp6; - tmp12= tmp6 + tmp7; + tmp4 += tmp5; + tmp5 += tmp6; + tmp6 += tmp7; - z5= (tmp10 - tmp12) * A5; - z2= tmp10*A2 + z5; - z4= tmp12*A4 + z5; - z3= tmp11*A1; +#if 0 + z5= (tmp4 - tmp6) * A5; + z2= tmp4*A2 + z5; + z4= tmp6*A4 + z5; +#else + z2= tmp4*(A2+A5) - tmp6*A5; + z4= tmp6*(A4-A5) + tmp4*A5; +#endif + tmp5*=A1; - z11= tmp7 + z3; - z13= tmp7 - z3; + z11= tmp7 + tmp5; + z13= tmp7 - tmp5; data[8*5 + i]= lrintf(SCALE(8*5 + i) * (z13 + z2)); data[8*3 + i]= lrintf(SCALE(8*3 + i) * (z13 - z2)); @@ -175,7 +190,6 @@ void ff_faandct248(DCTELEM * data) { FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; FLOAT tmp10, tmp11, tmp12, tmp13; - FLOAT z1; FLOAT temp[64]; int i; @@ -201,9 +215,10 @@ void ff_faandct248(DCTELEM * data) data[8*0 + i] = lrintf(SCALE(8*0 + i) * (tmp10 + tmp11)); data[8*4 + i] = lrintf(SCALE(8*4 + i) * (tmp10 - tmp11)); - z1 = (tmp12 + tmp13)* A1; - data[8*2 + i] = lrintf(SCALE(8*2 + i) * (tmp13 + z1)); - data[8*6 + i] = lrintf(SCALE(8*6 + i) * (tmp13 - z1)); + tmp12 += tmp13; + tmp12 *= A1; + data[8*2 + i] = lrintf(SCALE(8*2 + i) * (tmp13 + tmp12)); + data[8*6 + i] = lrintf(SCALE(8*6 + i) * (tmp13 - tmp12)); tmp10 = tmp4 + tmp7; tmp11 = tmp5 + tmp6; @@ -213,8 +228,9 @@ void ff_faandct248(DCTELEM * data) data[8*1 + i] = lrintf(SCALE(8*0 + i) * (tmp10 + tmp11)); data[8*5 + i] = lrintf(SCALE(8*4 + i) * (tmp10 - tmp11)); - z1 = (tmp12 + tmp13)* A1; - data[8*3 + i] = lrintf(SCALE(8*2 + i) * (tmp13 + z1)); - data[8*7 + i] = lrintf(SCALE(8*6 + i) * (tmp13 - z1)); + tmp12 += tmp13; + tmp12 *= A1; + data[8*3 + i] = lrintf(SCALE(8*2 + i) * (tmp13 + tmp12)); + data[8*7 + i] = lrintf(SCALE(8*6 + i) * (tmp13 - tmp12)); } } diff --git a/contrib/ffmpeg/libavcodec/faandct.h b/contrib/ffmpeg/libavcodec/faandct.h index 77dd41dae..b9a4eeb3e 100644 --- a/contrib/ffmpeg/libavcodec/faandct.h +++ b/contrib/ffmpeg/libavcodec/faandct.h @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -27,7 +26,14 @@ * @author Michael Niedermayer <michaelni@gmx.at> */ +#ifndef FFMPEG_FAANDCT_H +#define FFMPEG_FAANDCT_H + +#include "dsputil.h" + #define FAAN_POSTSCALE void ff_faandct(DCTELEM * data); void ff_faandct248(DCTELEM * data); + +#endif /* FFMPEG_FAANDCT_H */ diff --git a/contrib/ffmpeg/libavcodec/faanidct.c b/contrib/ffmpeg/libavcodec/faanidct.c new file mode 100644 index 000000000..add40349a --- /dev/null +++ b/contrib/ffmpeg/libavcodec/faanidct.c @@ -0,0 +1,168 @@ +/* + * Floating point AAN IDCT + * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at> + * + * 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 "faanidct.h" + +/* To allow switching to double. */ +#define FLOAT float + +#define B0 1.0000000000000000000000 +#define B1 1.3870398453221474618216 // cos(pi*1/16)sqrt(2) +#define B2 1.3065629648763765278566 // cos(pi*2/16)sqrt(2) +#define B3 1.1758756024193587169745 // cos(pi*3/16)sqrt(2) +#define B4 1.0000000000000000000000 // cos(pi*4/16)sqrt(2) +#define B5 0.7856949583871021812779 // cos(pi*5/16)sqrt(2) +#define B6 0.5411961001461969843997 // cos(pi*6/16)sqrt(2) +#define B7 0.2758993792829430123360 // cos(pi*7/16)sqrt(2) + +#define A4 0.70710678118654752438 // cos(pi*4/16) +#define A2 0.92387953251128675613 // cos(pi*2/16) + +static const FLOAT prescale[64]={ +B0*B0/8, B0*B1/8, B0*B2/8, B0*B3/8, B0*B4/8, B0*B5/8, B0*B6/8, B0*B7/8, +B1*B0/8, B1*B1/8, B1*B2/8, B1*B3/8, B1*B4/8, B1*B5/8, B1*B6/8, B1*B7/8, +B2*B0/8, B2*B1/8, B2*B2/8, B2*B3/8, B2*B4/8, B2*B5/8, B2*B6/8, B2*B7/8, +B3*B0/8, B3*B1/8, B3*B2/8, B3*B3/8, B3*B4/8, B3*B5/8, B3*B6/8, B3*B7/8, +B4*B0/8, B4*B1/8, B4*B2/8, B4*B3/8, B4*B4/8, B4*B5/8, B4*B6/8, B4*B7/8, +B5*B0/8, B5*B1/8, B5*B2/8, B5*B3/8, B5*B4/8, B5*B5/8, B5*B6/8, B5*B7/8, +B6*B0/8, B6*B1/8, B6*B2/8, B6*B3/8, B6*B4/8, B6*B5/8, B6*B6/8, B6*B7/8, +B7*B0/8, B7*B1/8, B7*B2/8, B7*B3/8, B7*B4/8, B7*B5/8, B7*B6/8, B7*B7/8, +}; + +static inline void p8idct(DCTELEM data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){ + int i; + FLOAT tmp0; + FLOAT s04, d04, s17, d17, s26, d26, s53, d53; + FLOAT os07, os16, os25, os34; + FLOAT od07, od16, od25, od34; + + for(i=0; i<y*8; i+=y){ + s17= temp[1*x + i] + temp[7*x + i]; + d17= temp[1*x + i] - temp[7*x + i]; + s53= temp[5*x + i] + temp[3*x + i]; + d53= temp[5*x + i] - temp[3*x + i]; + + od07= s17 + s53; + od25= (s17 - s53)*(2*A4); + +#if 0 //these 2 are equivalent + tmp0= (d17 + d53)*(2*A2); + od34= d17*( 2*B6) - tmp0; + od16= d53*(-2*B2) + tmp0; +#else + od34= d17*(2*(B6-A2)) - d53*(2*A2); + od16= d53*(2*(A2-B2)) + d17*(2*A2); +#endif + + od16 -= od07; + od25 -= od16; + od34 += od25; + + s26 = temp[2*x + i] + temp[6*x + i]; + d26 = temp[2*x + i] - temp[6*x + i]; + d26*= 2*A4; + d26-= s26; + + s04= temp[0*x + i] + temp[4*x + i]; + d04= temp[0*x + i] - temp[4*x + i]; + + os07= s04 + s26; + os34= s04 - s26; + os16= d04 + d26; + os25= d04 - d26; + + if(type==0){ + temp[0*x + i]= os07 + od07; + temp[7*x + i]= os07 - od07; + temp[1*x + i]= os16 + od16; + temp[6*x + i]= os16 - od16; + temp[2*x + i]= os25 + od25; + temp[5*x + i]= os25 - od25; + temp[3*x + i]= os34 - od34; + temp[4*x + i]= os34 + od34; + }else if(type==1){ + data[0*x + i]= lrintf(os07 + od07); + data[7*x + i]= lrintf(os07 - od07); + data[1*x + i]= lrintf(os16 + od16); + data[6*x + i]= lrintf(os16 - od16); + data[2*x + i]= lrintf(os25 + od25); + data[5*x + i]= lrintf(os25 - od25); + data[3*x + i]= lrintf(os34 - od34); + data[4*x + i]= lrintf(os34 + od34); + }else if(type==2){ + dest[0*stride + i]= av_clip_uint8(((int)dest[0*stride + i]) + lrintf(os07 + od07)); + dest[7*stride + i]= av_clip_uint8(((int)dest[7*stride + i]) + lrintf(os07 - od07)); + dest[1*stride + i]= av_clip_uint8(((int)dest[1*stride + i]) + lrintf(os16 + od16)); + dest[6*stride + i]= av_clip_uint8(((int)dest[6*stride + i]) + lrintf(os16 - od16)); + dest[2*stride + i]= av_clip_uint8(((int)dest[2*stride + i]) + lrintf(os25 + od25)); + dest[5*stride + i]= av_clip_uint8(((int)dest[5*stride + i]) + lrintf(os25 - od25)); + dest[3*stride + i]= av_clip_uint8(((int)dest[3*stride + i]) + lrintf(os34 - od34)); + dest[4*stride + i]= av_clip_uint8(((int)dest[4*stride + i]) + lrintf(os34 + od34)); + }else{ + dest[0*stride + i]= av_clip_uint8(lrintf(os07 + od07)); + dest[7*stride + i]= av_clip_uint8(lrintf(os07 - od07)); + dest[1*stride + i]= av_clip_uint8(lrintf(os16 + od16)); + dest[6*stride + i]= av_clip_uint8(lrintf(os16 - od16)); + dest[2*stride + i]= av_clip_uint8(lrintf(os25 + od25)); + dest[5*stride + i]= av_clip_uint8(lrintf(os25 - od25)); + dest[3*stride + i]= av_clip_uint8(lrintf(os34 - od34)); + dest[4*stride + i]= av_clip_uint8(lrintf(os34 + od34)); + } + } +} + +void ff_faanidct(DCTELEM block[64]){ + FLOAT temp[64]; + int i; + + emms_c(); + + for(i=0; i<64; i++) + temp[i] = block[i] * prescale[i]; + + p8idct(block, temp, NULL, 0, 1, 8, 0); + p8idct(block, temp, NULL, 0, 8, 1, 1); +} + +void ff_faanidct_add(uint8_t *dest, int line_size, DCTELEM block[64]){ + FLOAT temp[64]; + int i; + + emms_c(); + + for(i=0; i<64; i++) + temp[i] = block[i] * prescale[i]; + + p8idct(block, temp, NULL, 0, 1, 8, 0); + p8idct(NULL , temp, dest, line_size, 8, 1, 2); +} + +void ff_faanidct_put(uint8_t *dest, int line_size, DCTELEM block[64]){ + FLOAT temp[64]; + int i; + + emms_c(); + + for(i=0; i<64; i++) + temp[i] = block[i] * prescale[i]; + + p8idct(block, temp, NULL, 0, 1, 8, 0); + p8idct(NULL , temp, dest, line_size, 8, 1, 3); +} diff --git a/contrib/ffmpeg/libavcodec/faanidct.h b/contrib/ffmpeg/libavcodec/faanidct.h new file mode 100644 index 000000000..817ca3121 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/faanidct.h @@ -0,0 +1,32 @@ +/* + * Floating point AAN IDCT + * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at> + * + * 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 + */ + +#ifndef FFMPEG_FAANIDCT_H +#define FFMPEG_FAANIDCT_H + +#include <stdint.h> +#include "dsputil.h" + +void ff_faanidct(DCTELEM block[64]); +void ff_faanidct_add(uint8_t *dest, int line_size, DCTELEM block[64]); +void ff_faanidct_put(uint8_t *dest, int line_size, DCTELEM block[64]); + +#endif /* FFMPEG_FAANIDCT_H */ diff --git a/contrib/ffmpeg/libavcodec/fdctref.c b/contrib/ffmpeg/libavcodec/fdctref.c index 5eff36849..c6a057b84 100644 --- a/contrib/ffmpeg/libavcodec/fdctref.c +++ b/contrib/ffmpeg/libavcodec/fdctref.c @@ -27,7 +27,6 @@ * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. - * */ #include <math.h> diff --git a/contrib/ffmpeg/libavcodec/fft-test.c b/contrib/ffmpeg/libavcodec/fft-test.c index d2497383d..8ac04611a 100644 --- a/contrib/ffmpeg/libavcodec/fft-test.c +++ b/contrib/ffmpeg/libavcodec/fft-test.c @@ -27,8 +27,11 @@ #include <math.h> #include <unistd.h> #include <sys/time.h> +#include <stdlib.h> +#include <string.h> #undef exit +#undef random int mm_flags; @@ -47,7 +50,7 @@ FFTComplex *exptab; void fft_ref_init(int nbits, int inverse) { int n, i; - float c1, s1, alpha; + double c1, s1, alpha; n = 1 << nbits; exptab = av_malloc((n / 2) * sizeof(FFTComplex)); @@ -66,7 +69,7 @@ void fft_ref_init(int nbits, int inverse) void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits) { int n, i, j, k, n2; - float tmp_re, tmp_im, s, c; + double tmp_re, tmp_im, s, c; FFTComplex *q; n = 1 << nbits; @@ -92,10 +95,11 @@ void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits) } } -void imdct_ref(float *out, float *in, int n) +void imdct_ref(float *out, float *in, int nbits) { + int n = 1<<nbits; int k, i, a; - float sum, f; + double sum, f; for(i=0;i<n;i++) { sum = 0; @@ -109,10 +113,11 @@ void imdct_ref(float *out, float *in, int n) } /* NOTE: no normalisation by 1 / N is done */ -void mdct_ref(float *output, float *input, int n) +void mdct_ref(float *output, float *input, int nbits) { + int n = 1<<nbits; int k, i; - float a, s; + double a, s; /* do it by hand */ for(k=0;k<n/2;k++) { @@ -141,13 +146,19 @@ int64_t gettime(void) void check_diff(float *tab1, float *tab2, int n) { int i; + double max= 0; + double error= 0; for(i=0;i<n;i++) { - if (fabsf(tab1[i] - tab2[i]) >= 1e-3) { + double e= fabsf(tab1[i] - tab2[i]); + if (e >= 1e-3) { av_log(NULL, AV_LOG_ERROR, "ERROR %d: %f %f\n", i, tab1[i], tab2[i]); } + error+= e*e; + if(e>max) max= e; } + av_log(NULL, AV_LOG_INFO, "max:%f e:%g\n", max, sqrt(error)/n); } @@ -237,11 +248,11 @@ int main(int argc, char **argv) if (do_mdct) { if (do_inverse) { - imdct_ref((float *)tab_ref, (float *)tab1, fft_size); + imdct_ref((float *)tab_ref, (float *)tab1, fft_nbits); ff_imdct_calc(m, tab2, (float *)tab1, tabtmp); check_diff((float *)tab_ref, tab2, fft_size); } else { - mdct_ref((float *)tab_ref, (float *)tab1, fft_size); + mdct_ref((float *)tab_ref, (float *)tab1, fft_nbits); ff_mdct_calc(m, tab2, (float *)tab1, tabtmp); diff --git a/contrib/ffmpeg/libavcodec/ffv1.c b/contrib/ffmpeg/libavcodec/ffv1.c index 45f408c87..d0f2efbfe 100644 --- a/contrib/ffmpeg/libavcodec/ffv1.c +++ b/contrib/ffmpeg/libavcodec/ffv1.c @@ -18,7 +18,6 @@ * 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 - * */ /** @@ -26,9 +25,8 @@ * FF Video Codec 1 (an experimental lossless codec) */ -#include "common.h" -#include "bitstream.h" #include "avcodec.h" +#include "bitstream.h" #include "dsputil.h" #include "rangecoder.h" #include "golomb.h" @@ -704,6 +702,7 @@ static int common_end(AVCodecContext *avctx){ PlaneContext *p= &s->plane[i]; av_freep(&p->state); + av_freep(&p->vlc_state); } return 0; @@ -937,7 +936,7 @@ static int decode_init(AVCodecContext *avctx) return 0; } -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){ +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size){ FFV1Context *f = avctx->priv_data; RangeCoder * const c= &f->c; const int width= f->width; diff --git a/contrib/ffmpeg/libavcodec/flac.c b/contrib/ffmpeg/libavcodec/flac.c index 1016ed47f..81ed55e35 100644 --- a/contrib/ffmpeg/libavcodec/flac.c +++ b/contrib/ffmpeg/libavcodec/flac.c @@ -183,7 +183,7 @@ static int metadata_parse(FLACContext *s) av_log(s->avctx, AV_LOG_DEBUG, "STREAM HEADER\n"); do { - metadata_last = get_bits(&s->gb, 1); + metadata_last = get_bits1(&s->gb); metadata_type = get_bits(&s->gb, 7); metadata_size = get_bits_long(&s->gb, 24); @@ -217,7 +217,7 @@ static int decode_residuals(FLACContext *s, int channel, int pred_order) int sample = 0, samples; method_type = get_bits(&s->gb, 2); - if (method_type != 0){ + if (method_type > 1){ av_log(s->avctx, AV_LOG_DEBUG, "illegal residual coding method %d\n", method_type); return -1; } @@ -234,8 +234,8 @@ static int decode_residuals(FLACContext *s, int channel, int pred_order) i= pred_order; for (partition = 0; partition < (1 << rice_order); partition++) { - tmp = get_bits(&s->gb, 4); - if (tmp == 15) + tmp = get_bits(&s->gb, method_type == 0 ? 4 : 5); + if (tmp == (method_type == 0 ? 15 : 31)) { av_log(s->avctx, AV_LOG_DEBUG, "fixed len partition\n"); tmp = get_bits(&s->gb, 5); @@ -259,7 +259,9 @@ static int decode_residuals(FLACContext *s, int channel, int pred_order) static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) { - int i; + const int blocksize = s->blocksize; + int32_t *decoded = s->decoded[channel]; + int a, b, c, d, i; // av_log(s->avctx, AV_LOG_DEBUG, " SUBFRAME FIXED\n"); @@ -268,38 +270,37 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) for (i = 0; i < pred_order; i++) { - s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps); + decoded[i] = get_sbits(&s->gb, s->curr_bps); // av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, s->decoded[channel][i]); } if (decode_residuals(s, channel, pred_order) < 0) return -1; + a = decoded[pred_order-1]; + b = a - decoded[pred_order-2]; + c = b - decoded[pred_order-2] + decoded[pred_order-3]; + d = c - decoded[pred_order-2] + 2*decoded[pred_order-3] - decoded[pred_order-4]; + switch(pred_order) { case 0: break; case 1: - for (i = pred_order; i < s->blocksize; i++) - s->decoded[channel][i] += s->decoded[channel][i-1]; + for (i = pred_order; i < blocksize; i++) + decoded[i] = a += decoded[i]; break; case 2: - for (i = pred_order; i < s->blocksize; i++) - s->decoded[channel][i] += 2*s->decoded[channel][i-1] - - s->decoded[channel][i-2]; + for (i = pred_order; i < blocksize; i++) + decoded[i] = a += b += decoded[i]; break; case 3: - for (i = pred_order; i < s->blocksize; i++) - s->decoded[channel][i] += 3*s->decoded[channel][i-1] - - 3*s->decoded[channel][i-2] - + s->decoded[channel][i-3]; + for (i = pred_order; i < blocksize; i++) + decoded[i] = a += b += c += decoded[i]; break; case 4: - for (i = pred_order; i < s->blocksize; i++) - s->decoded[channel][i] += 4*s->decoded[channel][i-1] - - 6*s->decoded[channel][i-2] - + 4*s->decoded[channel][i-3] - - s->decoded[channel][i-4]; + for (i = pred_order; i < blocksize; i++) + decoded[i] = a += b += c += d += decoded[i]; break; default: av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); @@ -314,6 +315,7 @@ static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) int i, j; int coeff_prec, qlevel; int coeffs[pred_order]; + int32_t *decoded = s->decoded[channel]; // av_log(s->avctx, AV_LOG_DEBUG, " SUBFRAME LPC\n"); @@ -322,8 +324,8 @@ static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) for (i = 0; i < pred_order; i++) { - s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps); -// av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, s->decoded[channel][i]); + decoded[i] = get_sbits(&s->gb, s->curr_bps); +// av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, decoded[i]); } coeff_prec = get_bits(&s->gb, 4) + 1; @@ -355,17 +357,34 @@ static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) { sum = 0; for (j = 0; j < pred_order; j++) - sum += (int64_t)coeffs[j] * s->decoded[channel][i-j-1]; - s->decoded[channel][i] += sum >> qlevel; + sum += (int64_t)coeffs[j] * decoded[i-j-1]; + decoded[i] += sum >> qlevel; } } else { - int sum; - for (i = pred_order; i < s->blocksize; i++) + for (i = pred_order; i < s->blocksize-1; i += 2) { - sum = 0; + int c; + int d = decoded[i-pred_order]; + int s0 = 0, s1 = 0; + for (j = pred_order-1; j > 0; j--) + { + c = coeffs[j]; + s0 += c*d; + d = decoded[i-j]; + s1 += c*d; + } + c = coeffs[0]; + s0 += c*d; + d = decoded[i] += s0 >> qlevel; + s1 += c*d; + decoded[i+1] += s1 >> qlevel; + } + if (i < s->blocksize) + { + int sum = 0; for (j = 0; j < pred_order; j++) - sum += coeffs[j] * s->decoded[channel][i-j-1]; - s->decoded[channel][i] += sum >> qlevel; + sum += coeffs[j] * decoded[i-j-1]; + decoded[i] += sum >> qlevel; } } @@ -539,7 +558,8 @@ static int decode_frame(FLACContext *s, int alloc_data_size) } skip_bits(&s->gb, 8); - crc8= av_crc(av_crc07, 0, s->gb.buffer, get_bits_count(&s->gb)/8); + crc8 = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, + s->gb.buffer, get_bits_count(&s->gb)/8); if(crc8){ av_log(s->avctx, AV_LOG_ERROR, "header crc mismatch crc=%2X\n", crc8); return -1; @@ -568,20 +588,9 @@ static int decode_frame(FLACContext *s, int alloc_data_size) return 0; } -static inline int16_t shift_to_16_bits(int32_t data, int bps) -{ - if (bps == 24) { - return (data >> 8); - } else if (bps == 20) { - return (data >> 4); - } else { - return data; - } -} - static int flac_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { FLACContext *s = avctx->priv_data; int tmp = 0, i, j = 0, input_buf_size = 0; @@ -620,9 +629,9 @@ static int flac_decode_frame(AVCodecContext *avctx, if (!metadata_parse(s)) { tmp = show_bits(&s->gb, 16); - if(tmp != 0xFFF8){ + if((tmp & 0xFFFE) != 0xFFF8){ av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); - while(get_bits_count(&s->gb)/8+2 < buf_size && show_bits(&s->gb, 16) != 0xFFF8) + while(get_bits_count(&s->gb)/8+2 < buf_size && (show_bits(&s->gb, 16) & 0xFFFE) != 0xFFF8) skip_bits(&s->gb, 8); goto end; // we may not have enough bits left to decode a frame, so try next time } @@ -684,8 +693,8 @@ static int flac_decode_frame(AVCodecContext *avctx, {\ int a= s->decoded[0][i];\ int b= s->decoded[1][i];\ - *(samples++) = (left ) >> (16 - s->bps);\ - *(samples++) = (right) >> (16 - s->bps);\ + *samples++ = ((left) << (24 - s->bps)) >> 8;\ + *samples++ = ((right) << (24 - s->bps)) >> 8;\ }\ break; @@ -695,7 +704,7 @@ static int flac_decode_frame(AVCodecContext *avctx, for (j = 0; j < s->blocksize; j++) { for (i = 0; i < s->channels; i++) - *(samples++) = shift_to_16_bits(s->decoded[i][j], s->bps); + *samples++ = (s->decoded[i][j] << (24 - s->bps)) >> 8; } break; case LEFT_SIDE: @@ -712,7 +721,7 @@ static int flac_decode_frame(AVCodecContext *avctx, // s->last_blocksize = s->blocksize; end: - i= (get_bits_count(&s->gb)+7)/8;; + i= (get_bits_count(&s->gb)+7)/8; if(i > buf_size){ av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size); s->bitstream_size=0; diff --git a/contrib/ffmpeg/libavcodec/flacenc.c b/contrib/ffmpeg/libavcodec/flacenc.c index 9dd6c7eb8..469b46115 100644 --- a/contrib/ffmpeg/libavcodec/flacenc.c +++ b/contrib/ffmpeg/libavcodec/flacenc.c @@ -22,6 +22,7 @@ #include "avcodec.h" #include "bitstream.h" #include "crc.h" +#include "dsputil.h" #include "golomb.h" #include "lls.h" @@ -84,7 +85,7 @@ typedef struct FlacSubframe { int shift; RiceContext rc; int32_t samples[FLAC_MAX_BLOCKSIZE]; - int32_t residual[FLAC_MAX_BLOCKSIZE]; + int32_t residual[FLAC_MAX_BLOCKSIZE+1]; } FlacSubframe; typedef struct FlacFrame { @@ -107,6 +108,7 @@ typedef struct FlacEncodeContext { FlacFrame frame; CompressionOptions options; AVCodecContext *avctx; + DSPContext dsp; } FlacEncodeContext; static const int flac_samplerates[16] = { @@ -177,6 +179,8 @@ static int flac_encode_init(AVCodecContext *avctx) s->avctx = avctx; + dsputil_init(&s->dsp, avctx); + if(avctx->sample_fmt != SAMPLE_FMT_S16) { return -1; } @@ -447,20 +451,19 @@ static void copy_samples(FlacEncodeContext *s, int16_t *samples) #define rice_encode_count(sum, n, k) (((n)*((k)+1))+((sum-(n>>1))>>(k))) +/** + * Solve for d/dk(rice_encode_count) = n-((sum-(n>>1))>>(k+1)) = 0 + */ static int find_optimal_param(uint32_t sum, int n) { - int k, k_opt; - uint32_t nbits[MAX_RICE_PARAM+1]; - - k_opt = 0; - nbits[0] = UINT32_MAX; - for(k=0; k<=MAX_RICE_PARAM; k++) { - nbits[k] = rice_encode_count(sum, n, k); - if(nbits[k] < nbits[k_opt]) { - k_opt = k; - } - } - return k_opt; + int k; + uint32_t sum2; + + if(sum <= n>>1) + return 0; + sum2 = sum-(n>>1); + k = av_log2(n<256 ? FASTDIV(sum2,n) : sum2/n); + return FFMIN(k, MAX_RICE_PARAM); } static uint32_t calc_optimal_rice_params(RiceContext *rc, int porder, @@ -471,16 +474,15 @@ static uint32_t calc_optimal_rice_params(RiceContext *rc, int porder, uint32_t all_bits; part = (1 << porder); - all_bits = 0; + all_bits = 4 * part; cnt = (n >> porder) - pred_order; for(i=0; i<part; i++) { - if(i == 1) cnt = (n >> porder); k = find_optimal_param(sums[i], cnt); rc->params[i] = k; all_bits += rice_encode_count(sums[i], cnt, k); + cnt = n >> porder; } - all_bits += (4 * part); rc->porder = porder; @@ -499,10 +501,11 @@ static void calc_sums(int pmin, int pmax, uint32_t *data, int n, int pred_order, res = &data[pred_order]; res_end = &data[n >> pmax]; for(i=0; i<parts; i++) { - sums[pmax][i] = 0; + uint32_t sum = 0; while(res < res_end){ - sums[pmax][i] += *(res++); + sum += *(res++); } + sums[pmax][i] = sum; res_end+= n >> pmax; } /* sums for lower levels */ @@ -590,13 +593,19 @@ static void apply_welch_window(const int32_t *data, int len, double *w_data) double w; double c; + assert(!(len&1)); //the optimization in r11881 does not support odd len + //if someone wants odd len extend the change in r11881 + n2 = (len >> 1); c = 2.0 / (len - 1.0); + + w_data+=n2; + data+=n2; for(i=0; i<n2; i++) { - w = c - i - 1.0; + w = c - n2 + i; w = 1.0 - (w * w); - w_data[i] = data[i] * w; - w_data[len-1-i] = data[len-1-i] * w; + w_data[-i-1] = data[-i-1] * w; + w_data[+i ] = data[+i ] * w; } } @@ -604,24 +613,36 @@ static void apply_welch_window(const int32_t *data, int len, double *w_data) * Calculates autocorrelation data from audio samples * A Welch window function is applied before calculation. */ -static void compute_autocorr(const int32_t *data, int len, int lag, - double *autoc) +void ff_flac_compute_autocorr(const int32_t *data, int len, int lag, + double *autoc) { - int i, lag_ptr; - double tmp[len + lag]; + int i, j; + double tmp[len + lag + 1]; double *data1= tmp + lag; apply_welch_window(data, len, data1); - for(i=0; i<lag; i++){ - autoc[i] = 1.0; - data1[i-lag]= 0.0; + for(j=0; j<lag; j++) + data1[j-lag]= 0.0; + data1[len] = 0.0; + + for(j=0; j<lag; j+=2){ + double sum0 = 1.0, sum1 = 1.0; + for(i=0; i<len; i++){ + sum0 += data1[i] * data1[i-j]; + sum1 += data1[i] * data1[i-j-1]; + } + autoc[j ] = sum0; + autoc[j+1] = sum1; } - for(i=0; i<len; i++){ - for(lag_ptr= i-lag; lag_ptr<=i; lag_ptr++){ - autoc[i-lag_ptr] += data1[i] * data1[lag_ptr]; + if(j==lag){ + double sum = 1.0; + for(i=0; i<len; i+=2){ + sum += data1[i ] * data1[i-j ] + + data1[i+1] * data1[i-j+1]; } + autoc[j] = sum; } } @@ -735,7 +756,8 @@ static int estimate_best_order(double *ref, int max_order) /** * Calculate LPC coefficients for multiple orders */ -static int lpc_calc_coefs(const int32_t *samples, int blocksize, int max_order, +static int lpc_calc_coefs(FlacEncodeContext *s, + const int32_t *samples, int blocksize, int max_order, int precision, int32_t coefs[][MAX_LPC_ORDER], int *shift, int use_lpc, int omethod) { @@ -748,12 +770,12 @@ static int lpc_calc_coefs(const int32_t *samples, int blocksize, int max_order, assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER); if(use_lpc == 1){ - compute_autocorr(samples, blocksize, max_order+1, autoc); + s->dsp.flac_compute_autocorr(samples, blocksize, max_order, autoc); compute_lpc_coefs(autoc, max_order, lpc, ref); }else{ LLSModel m[2]; - double var[MAX_LPC_ORDER+1], eval, weight; + double var[MAX_LPC_ORDER+1], weight; for(pass=0; pass<use_lpc-1; pass++){ av_init_lls(&m[pass&1], max_order); @@ -764,11 +786,14 @@ static int lpc_calc_coefs(const int32_t *samples, int blocksize, int max_order, var[j]= samples[i-j]; if(pass){ + double eval, inv, rinv; eval= av_evaluate_lls(&m[(pass-1)&1], var+1, max_order-1); eval= (512>>pass) + fabs(eval - var[0]); + inv = 1/eval; + rinv = sqrt(inv); for(j=0; j<=max_order; j++) - var[j]/= sqrt(eval); - weight += 1/eval; + var[j] *= rinv; + weight += inv; }else weight++; @@ -823,33 +848,142 @@ static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n, for(i=order; i<n; i++) res[i]= smp[i] - smp[i-1]; }else if(order==2){ - for(i=order; i<n; i++) - res[i]= smp[i] - 2*smp[i-1] + smp[i-2]; + int a = smp[order-1] - smp[order-2]; + for(i=order; i<n; i+=2) { + int b = smp[i] - smp[i-1]; + res[i]= b - a; + a = smp[i+1] - smp[i]; + res[i+1]= a - b; + } }else if(order==3){ - for(i=order; i<n; i++) - res[i]= smp[i] - 3*smp[i-1] + 3*smp[i-2] - smp[i-3]; + int a = smp[order-1] - smp[order-2]; + int c = smp[order-1] - 2*smp[order-2] + smp[order-3]; + for(i=order; i<n; i+=2) { + int b = smp[i] - smp[i-1]; + int d = b - a; + res[i]= d - c; + a = smp[i+1] - smp[i]; + c = a - b; + res[i+1]= c - d; + } }else{ - for(i=order; i<n; i++) - res[i]= smp[i] - 4*smp[i-1] + 6*smp[i-2] - 4*smp[i-3] + smp[i-4]; + int a = smp[order-1] - smp[order-2]; + int c = smp[order-1] - 2*smp[order-2] + smp[order-3]; + int e = smp[order-1] - 3*smp[order-2] + 3*smp[order-3] - smp[order-4]; + for(i=order; i<n; i+=2) { + int b = smp[i] - smp[i-1]; + int d = b - a; + int f = d - c; + res[i]= f - e; + a = smp[i+1] - smp[i]; + c = a - b; + e = c - d; + res[i+1]= e - f; + } + } +} + +#define LPC1(x) {\ + int c = coefs[(x)-1];\ + p0 += c*s;\ + s = smp[i-(x)+1];\ + p1 += c*s;\ +} + +static av_always_inline void encode_residual_lpc_unrolled( + int32_t *res, const int32_t *smp, int n, + int order, const int32_t *coefs, int shift, int big) +{ + int i; + for(i=order; i<n; i+=2) { + int s = smp[i-order]; + int p0 = 0, p1 = 0; + if(big) { + switch(order) { + case 32: LPC1(32) + case 31: LPC1(31) + case 30: LPC1(30) + case 29: LPC1(29) + case 28: LPC1(28) + case 27: LPC1(27) + case 26: LPC1(26) + case 25: LPC1(25) + case 24: LPC1(24) + case 23: LPC1(23) + case 22: LPC1(22) + case 21: LPC1(21) + case 20: LPC1(20) + case 19: LPC1(19) + case 18: LPC1(18) + case 17: LPC1(17) + case 16: LPC1(16) + case 15: LPC1(15) + case 14: LPC1(14) + case 13: LPC1(13) + case 12: LPC1(12) + case 11: LPC1(11) + case 10: LPC1(10) + case 9: LPC1( 9) + LPC1( 8) + LPC1( 7) + LPC1( 6) + LPC1( 5) + LPC1( 4) + LPC1( 3) + LPC1( 2) + LPC1( 1) + } + } else { + switch(order) { + case 8: LPC1( 8) + case 7: LPC1( 7) + case 6: LPC1( 6) + case 5: LPC1( 5) + case 4: LPC1( 4) + case 3: LPC1( 3) + case 2: LPC1( 2) + case 1: LPC1( 1) + } + } + res[i ] = smp[i ] - (p0 >> shift); + res[i+1] = smp[i+1] - (p1 >> shift); } } static void encode_residual_lpc(int32_t *res, const int32_t *smp, int n, int order, const int32_t *coefs, int shift) { - int i, j; - int32_t pred; - + int i; for(i=0; i<order; i++) { res[i] = smp[i]; } - for(i=order; i<n; i++) { - pred = 0; +#ifdef CONFIG_SMALL + for(i=order; i<n; i+=2) { + int j; + int s = smp[i]; + int p0 = 0, p1 = 0; for(j=0; j<order; j++) { - pred += coefs[j] * smp[i-j-1]; + int c = coefs[j]; + p1 += c*s; + s = smp[i-j-1]; + p0 += c*s; } - res[i] = smp[i] - (pred >> shift); - } + res[i ] = smp[i ] - (p0 >> shift); + res[i+1] = smp[i+1] - (p1 >> shift); + } +#else + switch(order) { + case 1: encode_residual_lpc_unrolled(res, smp, n, 1, coefs, shift, 0); break; + case 2: encode_residual_lpc_unrolled(res, smp, n, 2, coefs, shift, 0); break; + case 3: encode_residual_lpc_unrolled(res, smp, n, 3, coefs, shift, 0); break; + case 4: encode_residual_lpc_unrolled(res, smp, n, 4, coefs, shift, 0); break; + case 5: encode_residual_lpc_unrolled(res, smp, n, 5, coefs, shift, 0); break; + case 6: encode_residual_lpc_unrolled(res, smp, n, 6, coefs, shift, 0); break; + case 7: encode_residual_lpc_unrolled(res, smp, n, 7, coefs, shift, 0); break; + case 8: encode_residual_lpc_unrolled(res, smp, n, 8, coefs, shift, 0); break; + default: encode_residual_lpc_unrolled(res, smp, n, order, coefs, shift, 1); break; + } +#endif } static int encode_residual(FlacEncodeContext *ctx, int ch) @@ -919,7 +1053,7 @@ static int encode_residual(FlacEncodeContext *ctx, int ch) } /* LPC */ - opt_order = lpc_calc_coefs(smp, n, max_order, precision, coefs, shift, ctx->options.use_lpc, omethod); + opt_order = lpc_calc_coefs(ctx, smp, n, max_order, precision, coefs, shift, ctx->options.use_lpc, omethod); if(omethod == ORDER_METHOD_2LEVEL || omethod == ORDER_METHOD_4LEVEL || @@ -1155,7 +1289,8 @@ static void output_frame_header(FlacEncodeContext *s) put_bits(&s->pb, 16, s->sr_code[1]); } flush_put_bits(&s->pb); - crc = av_crc(av_crc07, 0, s->pb.buf, put_bits_count(&s->pb)>>3); + crc = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, + s->pb.buf, put_bits_count(&s->pb)>>3); put_bits(&s->pb, 8, crc); } @@ -1297,7 +1432,8 @@ static void output_frame_footer(FlacEncodeContext *s) { int crc; flush_put_bits(&s->pb); - crc = bswap_16(av_crc(av_crc8005, 0, s->pb.buf, put_bits_count(&s->pb)>>3)); + crc = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, + s->pb.buf, put_bits_count(&s->pb)>>3)); put_bits(&s->pb, 16, crc); flush_put_bits(&s->pb); } diff --git a/contrib/ffmpeg/libavcodec/flashsv.c b/contrib/ffmpeg/libavcodec/flashsv.c index 9e4aa951a..842a7ccaf 100644 --- a/contrib/ffmpeg/libavcodec/flashsv.c +++ b/contrib/ffmpeg/libavcodec/flashsv.c @@ -50,7 +50,6 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" #include "bitstream.h" @@ -82,7 +81,7 @@ static void copy_region(uint8_t *sptr, uint8_t *dptr, static int flashsv_decode_init(AVCodecContext *avctx) { - FlashSVContext *s = (FlashSVContext *)avctx->priv_data; + FlashSVContext *s = avctx->priv_data; int zret; // Zlib return code s->avctx = avctx; @@ -95,7 +94,6 @@ static int flashsv_decode_init(AVCodecContext *avctx) return 1; } avctx->pix_fmt = PIX_FMT_BGR24; - avctx->has_b_frames = 0; s->frame.data[0] = NULL; return 0; @@ -104,9 +102,9 @@ static int flashsv_decode_init(AVCodecContext *avctx) static int flashsv_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - FlashSVContext *s = (FlashSVContext *)avctx->priv_data; + FlashSVContext *s = avctx->priv_data; int h_blocks, v_blocks, h_part, v_part, i, j; GetBitContext gb; @@ -232,7 +230,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, static int flashsv_decode_end(AVCodecContext *avctx) { - FlashSVContext *s = (FlashSVContext *)avctx->priv_data; + FlashSVContext *s = avctx->priv_data; inflateEnd(&(s->zstream)); /* release the frame if needed */ if (s->frame.data[0]) diff --git a/contrib/ffmpeg/libavcodec/flashsvenc.c b/contrib/ffmpeg/libavcodec/flashsvenc.c index cbf488328..2b791c294 100644 --- a/contrib/ffmpeg/libavcodec/flashsvenc.c +++ b/contrib/ffmpeg/libavcodec/flashsvenc.c @@ -58,7 +58,6 @@ #include <stdlib.h> #include <zlib.h> -#include "common.h" #include "avcodec.h" #include "bitstream.h" #include "bytestream.h" @@ -100,7 +99,7 @@ static int copy_region_enc(uint8_t *sptr, uint8_t *dptr, static int flashsv_encode_init(AVCodecContext *avctx) { - FlashSVContext *s = (FlashSVContext *)avctx->priv_data; + FlashSVContext *s = avctx->priv_data; s->avctx = avctx; @@ -115,16 +114,6 @@ static int flashsv_encode_init(AVCodecContext *avctx) // Needed if zlib unused or init aborted before deflateInit memset(&(s->zstream), 0, sizeof(z_stream)); -/* - s->zstream.zalloc = NULL; //av_malloc; - s->zstream.zfree = NULL; //av_free; - s->zstream.opaque = NULL; - zret = deflateInit(&(s->zstream), 9); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); - return -1; - } -*/ s->last_key_frame=0; @@ -194,22 +183,7 @@ static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf, int buf //ret = deflateReset(&(s->zstream)); if (ret != Z_OK) av_log(s->avctx, AV_LOG_ERROR, "error while compressing block %dx%d\n", i, j); - /* - s->zstream.next_in = s->tmpblock; - s->zstream.avail_in = 3*ws*hs; - s->zstream.total_in = 0; - s->zstream.next_out = ptr+2; - s->zstream.avail_out = buf_size-buf_pos-2; - s->zstream.total_out = 0; - - ret = deflate(&(s->zstream), Z_FINISH); - if ((ret != Z_OK) && (ret != Z_STREAM_END)) - av_log(s->avctx, AV_LOG_ERROR, "error while compressing block %dx%d\n", i, j); - - size = s->zstream.total_out; - //av_log(avctx, AV_LOG_INFO, "compressed blocks: %d\n", size); - */ bytestream_put_be16(&ptr,(unsigned int)zsize); buf_pos += zsize+2; //av_log(avctx, AV_LOG_ERROR, "buf_pos = %d\n", buf_pos); @@ -232,9 +206,10 @@ static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf, int buf static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) { - FlashSVContext * const s = (FlashSVContext *)avctx->priv_data; + FlashSVContext * const s = avctx->priv_data; AVFrame *pict = data; AVFrame * const p = &s->frame; + uint8_t *pfptr; int res; int I_frame = 0; int opt_w, opt_h; @@ -243,7 +218,7 @@ static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_siz /* First frame needs to be a keyframe */ if (avctx->frame_number == 0) { - s->previous_frame = av_mallocz(p->linesize[0]*s->image_height); + s->previous_frame = av_mallocz(FFABS(p->linesize[0])*s->image_height); if (!s->previous_frame) { av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); return -1; @@ -251,6 +226,11 @@ static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_siz I_frame = 1; } + if (p->linesize[0] < 0) + pfptr = s->previous_frame - ((s->image_height-1) * p->linesize[0]); + else + pfptr = s->previous_frame; + /* Check the placement of keyframes */ if (avctx->gop_size > 0) { if (avctx->frame_number >= s->last_key_frame + avctx->gop_size) { @@ -258,40 +238,8 @@ static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_siz } } -#if 0 - int w, h; - int optim_sizes[16][16]; - int smallest_size; - //Try all possible combinations and store the encoded frame sizes - for (w=1 ; w<17 ; w++) { - for (h=1 ; h<17 ; h++) { - optim_sizes[w-1][h-1] = encode_bitstream(s, p, s->encbuffer, s->image_width*s->image_height*4, w*16, h*16, s->previous_frame); - //av_log(avctx, AV_LOG_ERROR, "[%d][%d]size = %d\n",w,h,optim_sizes[w-1][h-1]); - } - } - - //Search for the smallest framesize and encode the frame with those parameters - smallest_size=optim_sizes[0][0]; - opt_w = 0; - opt_h = 0; - for (w=0 ; w<16 ; w++) { - for (h=0 ; h<16 ; h++) { - if (optim_sizes[w][h] < smallest_size) { - smallest_size = optim_sizes[w][h]; - opt_w = w; - opt_h = h; - } - } - } - res = encode_bitstream(s, p, buf, buf_size, (opt_w+1)*16, (opt_h+1)*16, s->previous_frame); - av_log(avctx, AV_LOG_ERROR, "[%d][%d]optimal size = %d, res = %d|\n", opt_w, opt_h, smallest_size, res); - - if (buf_size < res) - av_log(avctx, AV_LOG_ERROR, "buf_size %d < res %d\n", buf_size, res); - -#else - opt_w=1; - opt_h=1; + opt_w=4; + opt_h=4; if (buf_size < s->image_width*s->image_height*3) { //Conservative upper bound check for compressed data @@ -299,10 +247,13 @@ static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_siz return -1; } - res = encode_bitstream(s, p, buf, buf_size, opt_w*16, opt_h*16, s->previous_frame, &I_frame); -#endif + res = encode_bitstream(s, p, buf, buf_size, opt_w*16, opt_h*16, pfptr, &I_frame); + //save the current frame - memcpy(s->previous_frame, p->data[0], s->image_height*p->linesize[0]); + if(p->linesize[0] > 0) + memcpy(s->previous_frame, p->data[0], s->image_height*p->linesize[0]); + else + memcpy(s->previous_frame, p->data[0] + p->linesize[0] * (s->image_height-1), s->image_height*FFABS(p->linesize[0])); //mark the frame type so the muxer can mux it correctly if (I_frame) { @@ -322,7 +273,7 @@ static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_siz static int flashsv_encode_end(AVCodecContext *avctx) { - FlashSVContext *s = (FlashSVContext *)avctx->priv_data; + FlashSVContext *s = avctx->priv_data; deflateEnd(&(s->zstream)); diff --git a/contrib/ffmpeg/libavcodec/flicvideo.c b/contrib/ffmpeg/libavcodec/flicvideo.c index b60e0b1c2..29116a232 100644 --- a/contrib/ffmpeg/libavcodec/flicvideo.c +++ b/contrib/ffmpeg/libavcodec/flicvideo.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -41,7 +40,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "bswap.h" @@ -80,26 +78,28 @@ typedef struct FlicDecodeContext { static int flic_decode_init(AVCodecContext *avctx) { - FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data; + FlicDecodeContext *s = avctx->priv_data; unsigned char *fli_header = (unsigned char *)avctx->extradata; int depth; s->avctx = avctx; - avctx->has_b_frames = 0; s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */ - depth = AV_RL16(&fli_header[12]); - - if (depth == 0) { - depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */ - } + depth = 0; if (s->avctx->extradata_size == 12) { /* special case for magic carpet FLIs */ s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE; + depth = 8; } else if (s->avctx->extradata_size != 128) { av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n"); return -1; + } else { + depth = AV_RL16(&fli_header[12]); + } + + if (depth == 0) { + depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */ } if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) { @@ -127,9 +127,9 @@ static int flic_decode_init(AVCodecContext *avctx) static int flic_decode_frame_8BPP(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data; + FlicDecodeContext *s = avctx->priv_data; int stream_ptr = 0; int stream_ptr_after_color_chunk; @@ -427,11 +427,11 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { /* Note, the only difference between the 15Bpp and 16Bpp */ /* Format is the pixel format, the packets are processed the same. */ - FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data; + FlicDecodeContext *s = avctx->priv_data; int stream_ptr = 0; int pixel_ptr; @@ -581,20 +581,18 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, } /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed. - * This doesnt give us any good oportunity to perform word endian conversion - * during decompression. So if its requried (ie, this isnt a LE target, we do + * This does not give us any good oportunity to perform word endian conversion + * during decompression. So if it is required (i.e., this is not a LE target, we do * a second pass over the line here, swapping the bytes. */ - pixel = 0xFF00; - if (0xFF00 != AV_RL16(&pixel)) /* Check if its not an LE Target */ - { - pixel_ptr = y_ptr; - pixel_countdown = s->avctx->width; - while (pixel_countdown > 0) { +#ifdef WORDS_BIGENDIAN + pixel_ptr = y_ptr; + pixel_countdown = s->avctx->width; + while (pixel_countdown > 0) { *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]); pixel_ptr += 2; - } } +#endif y_ptr += s->frame.linesize[0]; } break; @@ -694,7 +692,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, static int flic_decode_frame_24BPP(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n"); return -1; @@ -702,7 +700,7 @@ static int flic_decode_frame_24BPP(AVCodecContext *avctx, static int flic_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { if (avctx->pix_fmt == PIX_FMT_PAL8) { return flic_decode_frame_8BPP(avctx, data, data_size, @@ -718,11 +716,11 @@ static int flic_decode_frame(AVCodecContext *avctx, buf, buf_size); } - /* Shouldnt get here, ever as the pix_fmt is processed */ + /* Should not get here, ever as the pix_fmt is processed */ /* in flic_decode_init and the above if should deal with */ /* the finite set of possibilites allowable by here. */ - /* but in case we do, just error out. */ - av_log(avctx, AV_LOG_ERROR, "Unknown Format of FLC. My Science cant explain how this happened\n"); + /* But in case we do, just error out. */ + av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n"); return -1; } diff --git a/contrib/ffmpeg/libavcodec/fraps.c b/contrib/ffmpeg/libavcodec/fraps.c index 0a4567d05..b7db219c9 100644 --- a/contrib/ffmpeg/libavcodec/fraps.c +++ b/contrib/ffmpeg/libavcodec/fraps.c @@ -18,7 +18,6 @@ * 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 - * */ /** @@ -34,30 +33,18 @@ #include "avcodec.h" #include "bitstream.h" +#include "huffman.h" +#include "bytestream.h" #include "dsputil.h" #define FPS_TAG MKTAG('F', 'P', 'S', 'x') -/* symbol for Huffman tree node */ -#define HNODE -1 - -/** - * Huffman node - * FIXME one day this should belong to one general framework - */ -typedef struct Node{ - int16_t sym; - int16_t n0; - int count; -}Node; - /** * local variable storage */ typedef struct FrapsContext{ AVCodecContext *avctx; AVFrame frame; - Node nodes[512]; uint8_t *tmpbuf; DSPContext dsp; } FrapsContext; @@ -73,7 +60,6 @@ static int decode_init(AVCodecContext *avctx) FrapsContext * const s = avctx->priv_data; avctx->coded_frame = (AVFrame*)&s->frame; - avctx->has_b_frames = 0; avctx->pix_fmt= PIX_FMT_NONE; /* set in decode_frame */ s->avctx = avctx; @@ -89,95 +75,36 @@ static int decode_init(AVCodecContext *avctx) * Comparator - our nodes should ascend by count * but with preserved symbol order */ -static int huff_cmp(const Node *a, const Node *b){ +static int huff_cmp(const void *va, const void *vb){ + const Node *a = va, *b = vb; return (a->count - b->count)*256 + a->sym - b->sym; } -static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, Node *nodes, int node, uint32_t pfx, int pl, int *pos) -{ - int s; - - s = nodes[node].sym; - if(s != HNODE || !nodes[node].count){ - bits[*pos] = pfx; - lens[*pos] = pl; - xlat[*pos] = s; - (*pos)++; - }else{ - pfx <<= 1; - pl++; - get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0, pfx, pl, pos); - pfx |= 1; - get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0+1, pfx, pl, pos); - } -} - -static int build_huff_tree(VLC *vlc, Node *nodes, uint8_t *xlat) -{ - uint32_t bits[256]; - int16_t lens[256]; - int pos = 0; - - get_tree_codes(bits, lens, xlat, nodes, 510, 0, 0, &pos); - return init_vlc(vlc, 9, pos, lens, 2, 2, bits, 4, 4, 0); -} - - /** * decode Fraps v2 packed plane */ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, - int h, uint8_t *src, int size, int Uoff) + int h, const uint8_t *src, int size, int Uoff) { int i, j; - int cur_node; GetBitContext gb; VLC vlc; - int64_t sum = 0; - uint8_t recode[256]; - - for(i = 0; i < 256; i++){ - s->nodes[i].sym = i; - s->nodes[i].count = AV_RL32(src); - s->nodes[i].n0 = -2; - if(s->nodes[i].count < 0) { - av_log(s->avctx, AV_LOG_ERROR, "Symbol count < 0\n"); - return -1; - } - src += 4; - sum += s->nodes[i].count; - } - size -= 1024; + Node nodes[512]; - if(sum >> 31) { - av_log(s->avctx, AV_LOG_ERROR, "Too high symbol frequencies. Tree construction is not possible\n"); - return -1; - } - qsort(s->nodes, 256, sizeof(Node), huff_cmp); - cur_node = 256; - for(i = 0; i < 511; i += 2){ - s->nodes[cur_node].sym = HNODE; - s->nodes[cur_node].count = s->nodes[i].count + s->nodes[i+1].count; - s->nodes[cur_node].n0 = i; - for(j = cur_node; j > 0; j--){ - if(s->nodes[j].count >= s->nodes[j - 1].count) break; - FFSWAP(Node, s->nodes[j], s->nodes[j - 1]); - } - cur_node++; - } - if(build_huff_tree(&vlc, s->nodes, recode) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "Error building tree\n"); + for(i = 0; i < 256; i++) + nodes[i].count = bytestream_get_le32(&src); + size -= 1024; + if (ff_huff_build_tree(s->avctx, &vlc, 256, nodes, huff_cmp, 0) < 0) return -1; - } /* we have built Huffman table and are ready to decode plane */ /* convert bits so they may be used by standard bitreader */ - s->dsp.bswap_buf(s->tmpbuf, src, size >> 2); + s->dsp.bswap_buf((uint32_t *)s->tmpbuf, (const uint32_t *)src, size >> 2); init_get_bits(&gb, s->tmpbuf, size * 8); for(j = 0; j < h; j++){ for(i = 0; i < w; i++){ - dst[i] = recode[get_vlc2(&gb, vlc.table, 9, 3)]; + dst[i] = get_vlc2(&gb, vlc.table, 9, 3); /* lines are stored as deltas between previous lines * and we need to add 0x80 to the first lines of chroma planes */ @@ -201,7 +128,7 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, */ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { FrapsContext * const s = avctx->priv_data; AVFrame *frame = data; @@ -209,7 +136,7 @@ static int decode_frame(AVCodecContext *avctx, uint32_t header; unsigned int version,header_size; unsigned int x, y; - uint32_t *buf32; + const uint32_t *buf32; uint32_t *luma1,*luma2,*cb,*cr; uint32_t offs[4]; int i, is_chroma, planes; @@ -263,7 +190,7 @@ static int decode_frame(AVCodecContext *avctx, f->key_frame = f->pict_type == FF_I_TYPE; if (f->pict_type == FF_I_TYPE) { - buf32=(uint32_t*)buf; + buf32=(const uint32_t*)buf; for(y=0; y<avctx->height/2; y++){ luma1=(uint32_t*)&f->data[0][ y*2*f->linesize[0] ]; luma2=(uint32_t*)&f->data[0][ (y*2+1)*f->linesize[0] ]; diff --git a/contrib/ffmpeg/libavcodec/g726.c b/contrib/ffmpeg/libavcodec/g726.c index 07af33122..d0073c1b4 100644 --- a/contrib/ffmpeg/libavcodec/g726.c +++ b/contrib/ffmpeg/libavcodec/g726.c @@ -23,7 +23,6 @@ */ #include <limits.h> #include "avcodec.h" -#include "common.h" #include "bitstream.h" /** @@ -65,14 +64,14 @@ static inline int sgn(int value) typedef struct G726Tables { int bits; /**< bits per sample */ - int* quant; /**< quantization table */ - int* iquant; /**< inverse quantization table */ - int* W; /**< special table #1 ;-) */ - int* F; /**< special table #2 */ + const int* quant; /**< quantization table */ + const int* iquant; /**< inverse quantization table */ + const int* W; /**< special table #1 ;-) */ + const int* F; /**< special table #2 */ } G726Tables; typedef struct G726Context { - G726Tables* tbls; /**< static tables needed for computation */ + const G726Tables* tbls; /**< static tables needed for computation */ Float11 sr[2]; /**< prev. reconstructed samples */ Float11 dq[6]; /**< prev. difference */ @@ -92,53 +91,53 @@ typedef struct G726Context { int y; /**< quantizer scaling factor for the next iteration */ } G726Context; -static int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ +static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ { 260, INT_MAX }; -static int iquant_tbl16[] = +static const int iquant_tbl16[] = { 116, 365, 365, 116 }; -static int W_tbl16[] = +static const int W_tbl16[] = { -22, 439, 439, -22 }; -static int F_tbl16[] = +static const int F_tbl16[] = { 0, 7, 7, 0 }; -static int quant_tbl24[] = /**< 24kbit/s 3bits per sample */ +static const int quant_tbl24[] = /**< 24kbit/s 3bits per sample */ { 7, 217, 330, INT_MAX }; -static int iquant_tbl24[] = +static const int iquant_tbl24[] = { INT_MIN, 135, 273, 373, 373, 273, 135, INT_MIN }; -static int W_tbl24[] = +static const int W_tbl24[] = { -4, 30, 137, 582, 582, 137, 30, -4 }; -static int F_tbl24[] = +static const int F_tbl24[] = { 0, 1, 2, 7, 7, 2, 1, 0 }; -static int quant_tbl32[] = /**< 32kbit/s 4bits per sample */ +static const int quant_tbl32[] = /**< 32kbit/s 4bits per sample */ { -125, 79, 177, 245, 299, 348, 399, INT_MAX }; -static int iquant_tbl32[] = +static const int iquant_tbl32[] = { INT_MIN, 4, 135, 213, 273, 323, 373, 425, 425, 373, 323, 273, 213, 135, 4, INT_MIN }; -static int W_tbl32[] = +static const int W_tbl32[] = { -12, 18, 41, 64, 112, 198, 355, 1122, 1122, 355, 198, 112, 64, 41, 18, -12}; -static int F_tbl32[] = +static const int F_tbl32[] = { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 }; -static int quant_tbl40[] = /**< 40kbit/s 5bits per sample */ +static const int quant_tbl40[] = /**< 40kbit/s 5bits per sample */ { -122, -16, 67, 138, 197, 249, 297, 338, 377, 412, 444, 474, 501, 527, 552, INT_MAX }; -static int iquant_tbl40[] = +static const int iquant_tbl40[] = { INT_MIN, -66, 28, 104, 169, 224, 274, 318, 358, 395, 429, 459, 488, 514, 539, 566, 566, 539, 514, 488, 459, 429, 395, 358, 318, 274, 224, 169, 104, 28, -66, INT_MIN }; -static int W_tbl40[] = +static const int W_tbl40[] = { 14, 14, 24, 39, 40, 41, 58, 100, 141, 179, 219, 280, 358, 440, 529, 696, 696, 529, 440, 358, 280, 219, 179, 141, 100, 58, 41, 40, 39, 24, 14, 14 }; -static int F_tbl40[] = +static const int F_tbl40[] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; -static G726Tables G726Tables_pool[] = +static const G726Tables G726Tables_pool[] = {{ 2, quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 }, { 3, quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 }, { 4, quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 }, @@ -374,7 +373,7 @@ static int g726_encode_frame(AVCodecContext *avctx, static int g726_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { AVG726Context *c = avctx->priv_data; short *samples = data; @@ -388,7 +387,7 @@ static int g726_decode_frame(AVCodecContext *avctx, mask = (1<<c->code_size) - 1; init_get_bits(&gb, buf, buf_size * 8); if (c->bits_left) { - int s = c->code_size - c->bits_left;; + int s = c->code_size - c->bits_left; code = (c->bit_buffer << s) | get_bits(&gb, s); *samples++ = g726_decode(&c->c, code & mask); } diff --git a/contrib/ffmpeg/libavcodec/gif.c b/contrib/ffmpeg/libavcodec/gif.c index f67ab52c2..ee3a13929 100644 --- a/contrib/ffmpeg/libavcodec/gif.c +++ b/contrib/ffmpeg/libavcodec/gif.c @@ -132,15 +132,11 @@ static void gif_put_bits_rev(PutBitContext *s, int n, unsigned int value) } else { bit_buf |= value << (bit_cnt); - *s->buf_ptr = bit_buf & 0xff; - s->buf_ptr[1] = (bit_buf >> 8) & 0xff; - s->buf_ptr[2] = (bit_buf >> 16) & 0xff; - s->buf_ptr[3] = (bit_buf >> 24) & 0xff; + bytestream_put_le32(&s->buf_ptr, bit_buf); //printf("bitbuf = %08x\n", bit_buf); - s->buf_ptr+=4; if (s->buf_ptr >= s->buf_end) - puts("bit buffer overflow !!"); // should never happen ! who got rid of the callback ??? + abort(); // flush_buffer_rev(s); bit_cnt=bit_cnt + n - 32; if (bit_cnt == 0) { @@ -195,9 +191,7 @@ static int gif_image_write_header(uint8_t **bytestream, } else { for(i=0;i<256;i++) { v = palette[i]; - bytestream_put_byte(bytestream, (v >> 16) & 0xff); - bytestream_put_byte(bytestream, (v >> 8) & 0xff); - bytestream_put_byte(bytestream, (v) & 0xff); + bytestream_put_be24(bytestream, v); } } diff --git a/contrib/ffmpeg/libavcodec/gifdec.c b/contrib/ffmpeg/libavcodec/gifdec.c index 3e8a3e6bc..8f0252694 100644 --- a/contrib/ffmpeg/libavcodec/gifdec.c +++ b/contrib/ffmpeg/libavcodec/gifdec.c @@ -47,8 +47,8 @@ typedef struct GifState { int gce_delay; /* LZW compatible decoder */ - uint8_t *bytestream; - uint8_t *bytestream_end; + const uint8_t *bytestream; + const uint8_t *bytestream_end; LZWState *lzw; /* aux buffers */ @@ -96,8 +96,7 @@ static int gif_read_image(GifState *s) n = (1 << bits_per_pixel); spal = palette; for(i = 0; i < n; i++) { - s->image_palette[i] = (0xff << 24) | - (spal[0] << 16) | (spal[1] << 8) | (spal[2]); + s->image_palette[i] = (0xff << 24) | AV_RB24(spal); spal += 3; } for(; i < 256; i++) @@ -258,18 +257,15 @@ static int gif_parse_next_image(GifState *s) #endif switch (code) { case ',': - if (gif_read_image(s) < 0) - return -1; - return 0; - case ';': - /* end of image */ - return -1; + return gif_read_image(s); case '!': if (gif_read_extension(s) < 0) return -1; break; + case ';': + /* end of image */ default: - /* error or errneous EOF */ + /* error or erroneous EOF */ return -1; } } @@ -289,7 +285,7 @@ static int gif_decode_init(AVCodecContext *avctx) return 0; } -static int gif_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +static int gif_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { GifState *s = avctx->priv_data; AVFrame *picture = data; diff --git a/contrib/ffmpeg/libavcodec/golomb.c b/contrib/ffmpeg/libavcodec/golomb.c index 50df4fc40..0ac7c9514 100644 --- a/contrib/ffmpeg/libavcodec/golomb.c +++ b/contrib/ffmpeg/libavcodec/golomb.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -154,3 +153,21 @@ const int8_t ff_interleaved_se_golomb_vlc_code[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; + +const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]={ +0, 1, 0, 0, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, +4, 5, 2, 2, 6, 7, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +8, 9, 4, 4, 10,11,5, 5, 2, 2, 2, 2, 2, 2, 2, 2, +12,13,6, 6, 14,15,7, 7, 3, 3, 3, 3, 3, 3, 3, 3, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; diff --git a/contrib/ffmpeg/libavcodec/golomb.h b/contrib/ffmpeg/libavcodec/golomb.h index 9bf7aec46..f2bc7fda6 100644 --- a/contrib/ffmpeg/libavcodec/golomb.h +++ b/contrib/ffmpeg/libavcodec/golomb.h @@ -18,7 +18,6 @@ * 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 - * */ /** @@ -28,6 +27,12 @@ * @author Michael Niedermayer <michaelni@gmx.at> and Alex Beregszaszi */ +#ifndef FFMPEG_GOLOMB_H +#define FFMPEG_GOLOMB_H + +#include <stdint.h> +#include "bitstream.h" + #define INVALID_VLC 0x80000000 extern const uint8_t ff_golomb_vlc_len[512]; @@ -38,6 +43,7 @@ extern const uint8_t ff_ue_golomb_len[256]; extern const uint8_t ff_interleaved_golomb_vlc_len[256]; extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256]; extern const int8_t ff_interleaved_se_golomb_vlc_code[256]; +extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]; /** @@ -70,7 +76,6 @@ static inline int get_ue_golomb(GetBitContext *gb){ static inline int svq3_get_ue_golomb(GetBitContext *gb){ uint32_t buf; - int log; OPEN_READER(re, gb); UPDATE_CACHE(re, gb); @@ -83,21 +88,24 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){ return ff_interleaved_ue_golomb_vlc_code[buf]; }else{ - LAST_SKIP_BITS(re, gb, 8); - UPDATE_CACHE(re, gb); - buf |= 1 | (GET_CACHE(re, gb) >> 8); + int ret = 1; - if((buf & 0xAAAAAAAA) == 0) - return INVALID_VLC; + while (1) { + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); - for(log=31; (buf & 0x80000000) == 0; log--){ - buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + if (ff_interleaved_golomb_vlc_len[buf] != 9){ + ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1; + ret |= ff_interleaved_dirac_golomb_vlc_code[buf]; + break; + } + ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; + UPDATE_CACHE(re, gb); + buf = GET_CACHE(re, gb); } - LAST_SKIP_BITS(re, gb, 63 - 2*log - 8); CLOSE_READER(re, gb); - - return ((buf << log) >> log) - 1; + return ret - 1; } } @@ -187,6 +195,24 @@ static inline int svq3_get_se_golomb(GetBitContext *gb){ } } +static inline int dirac_get_se_golomb(GetBitContext *gb){ + uint32_t buf; + uint32_t ret; + + ret = svq3_get_ue_golomb(gb); + + if (ret) { + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf = SHOW_SBITS(re, gb, 1); + LAST_SKIP_BITS(re, gb, 1); + ret = (ret ^ buf) - buf; + CLOSE_READER(re, gb); + } + + return ret; +} + /** * read unsigned golomb rice code (ffv1). */ @@ -477,3 +503,5 @@ static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, int limit set_ur_golomb_jpegls(pb, v, k, limit, esc_len); } + +#endif /* FFMPEG_GOLOMB_H */ diff --git a/contrib/ffmpeg/libavcodec/h261.c b/contrib/ffmpeg/libavcodec/h261.c index 83f3136e3..b4658c58c 100644 --- a/contrib/ffmpeg/libavcodec/h261.c +++ b/contrib/ffmpeg/libavcodec/h261.c @@ -1,5 +1,5 @@ /* - * H261 decoder + * H261 common code * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Maarten Daniels * @@ -25,40 +25,13 @@ * h261codec. */ -#include "common.h" #include "dsputil.h" #include "avcodec.h" -#include "mpegvideo.h" -#include "h261data.h" +#include "h261.h" - -#define H261_MBA_VLC_BITS 9 -#define H261_MTYPE_VLC_BITS 6 -#define H261_MV_VLC_BITS 7 -#define H261_CBP_VLC_BITS 9 -#define TCOEFF_VLC_BITS 9 - -#define MBA_STUFFING 33 -#define MBA_STARTCODE 34 #define IS_FIL(a) ((a)&MB_TYPE_H261_FIL) -/** - * H261Context - */ -typedef struct H261Context{ - MpegEncContext s; - - int current_mba; - int previous_mba; - int mba_diff; - int mtype; - int current_mv_x; - int current_mv_y; - int gob_number; - int gob_start_code_skipped; // 1 if gob start code is already read before gob header is read -}H261Context; - -static uint8_t static_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; +uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; void ff_h261_loop_filter(MpegEncContext *s){ H261Context * h= (H261Context*)s; @@ -79,979 +52,3 @@ void ff_h261_loop_filter(MpegEncContext *s){ s->dsp.h261_loop_filter(dest_cr, uvlinesize); } -int ff_h261_get_picture_format(int width, int height){ - // QCIF - if (width == 176 && height == 144) - return 0; - // CIF - else if (width == 352 && height == 288) - return 1; - // ERROR - else - return -1; -} - -static void h261_encode_block(H261Context * h, DCTELEM * block, - int n); -static int h261_decode_block(H261Context *h, DCTELEM *block, - int n, int coded); - -void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ - H261Context * h = (H261Context *) s; - int format, temp_ref; - - align_put_bits(&s->pb); - - /* Update the pointer to last GOB */ - s->ptr_lastgob = pbBufPtr(&s->pb); - - put_bits(&s->pb, 20, 0x10); /* PSC */ - - temp_ref= s->picture_number * (int64_t)30000 * s->avctx->time_base.num / - (1001 * (int64_t)s->avctx->time_base.den); //FIXME maybe this should use a timestamp - put_bits(&s->pb, 5, temp_ref & 0x1f); /* TemporalReference */ - - put_bits(&s->pb, 1, 0); /* split screen off */ - put_bits(&s->pb, 1, 0); /* camera off */ - put_bits(&s->pb, 1, 0); /* freeze picture release off */ - - format = ff_h261_get_picture_format(s->width, s->height); - - put_bits(&s->pb, 1, format); /* 0 == QCIF, 1 == CIF */ - - put_bits(&s->pb, 1, 0); /* still image mode */ - put_bits(&s->pb, 1, 0); /* reserved */ - - put_bits(&s->pb, 1, 0); /* no PEI */ - if(format == 0) - h->gob_number = -1; - else - h->gob_number = 0; - h->current_mba = 0; -} - -/** - * Encodes a group of blocks header. - */ -static void h261_encode_gob_header(MpegEncContext * s, int mb_line){ - H261Context * h = (H261Context *)s; - if(ff_h261_get_picture_format(s->width, s->height) == 0){ - h->gob_number+=2; // QCIF - } - else{ - h->gob_number++; // CIF - } - put_bits(&s->pb, 16, 1); /* GBSC */ - put_bits(&s->pb, 4, h->gob_number); /* GN */ - put_bits(&s->pb, 5, s->qscale); /* GQUANT */ - put_bits(&s->pb, 1, 0); /* no GEI */ - h->current_mba = 0; - h->previous_mba = 0; - h->current_mv_x=0; - h->current_mv_y=0; -} - -void ff_h261_reorder_mb_index(MpegEncContext* s){ - int index= s->mb_x + s->mb_y*s->mb_width; - - if(index % 33 == 0) - h261_encode_gob_header(s,0); - - /* for CIF the GOB's are fragmented in the middle of a scanline - that's why we need to adjust the x and y index of the macroblocks */ - if(ff_h261_get_picture_format(s->width,s->height) == 1){ // CIF - s->mb_x = index % 11 ; index /= 11; - s->mb_y = index % 3 ; index /= 3; - s->mb_x+= 11*(index % 2); index /= 2; - s->mb_y+= 3*index; - - ff_init_block_index(s); - ff_update_block_index(s); - } -} - -static void h261_encode_motion(H261Context * h, int val){ - MpegEncContext * const s = &h->s; - int sign, code; - if(val==0){ - code = 0; - put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); - } - else{ - if(val > 15) - val -=32; - if(val < -16) - val+=32; - sign = val < 0; - code = sign ? -val : val; - put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); - put_bits(&s->pb,1,sign); - } -} - -static inline int get_cbp(MpegEncContext * s, - DCTELEM block[6][64]) -{ - int i, cbp; - cbp= 0; - for (i = 0; i < 6; i++) { - if (s->block_last_index[i] >= 0) - cbp |= 1 << (5 - i); - } - return cbp; -} -void ff_h261_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y) -{ - H261Context * h = (H261Context *)s; - int mvd, mv_diff_x, mv_diff_y, i, cbp; - cbp = 63; // avoid warning - mvd = 0; - - h->current_mba++; - h->mtype = 0; - - if (!s->mb_intra){ - /* compute cbp */ - cbp= get_cbp(s, block); - - /* mvd indicates if this block is motion compensated */ - mvd = motion_x | motion_y; - - if((cbp | mvd | s->dquant ) == 0) { - /* skip macroblock */ - s->skip_count++; - h->current_mv_x=0; - h->current_mv_y=0; - return; - } - } - - /* MB is not skipped, encode MBA */ - put_bits(&s->pb, h261_mba_bits[(h->current_mba-h->previous_mba)-1], h261_mba_code[(h->current_mba-h->previous_mba)-1]); - - /* calculate MTYPE */ - if(!s->mb_intra){ - h->mtype++; - - if(mvd || s->loop_filter) - h->mtype+=3; - if(s->loop_filter) - h->mtype+=3; - if(cbp || s->dquant) - h->mtype++; - assert(h->mtype > 1); - } - - if(s->dquant) - h->mtype++; - - put_bits(&s->pb, h261_mtype_bits[h->mtype], h261_mtype_code[h->mtype]); - - h->mtype = h261_mtype_map[h->mtype]; - - if(IS_QUANT(h->mtype)){ - ff_set_qscale(s,s->qscale+s->dquant); - put_bits(&s->pb, 5, s->qscale); - } - - if(IS_16X16(h->mtype)){ - mv_diff_x = (motion_x >> 1) - h->current_mv_x; - mv_diff_y = (motion_y >> 1) - h->current_mv_y; - h->current_mv_x = (motion_x >> 1); - h->current_mv_y = (motion_y >> 1); - h261_encode_motion(h,mv_diff_x); - h261_encode_motion(h,mv_diff_y); - } - - h->previous_mba = h->current_mba; - - if(HAS_CBP(h->mtype)){ - assert(cbp>0); - put_bits(&s->pb,h261_cbp_tab[cbp-1][1],h261_cbp_tab[cbp-1][0]); - } - for(i=0; i<6; i++) { - /* encode each block */ - h261_encode_block(h, block[i], i); - } - - if ( ( h->current_mba == 11 ) || ( h->current_mba == 22 ) || ( h->current_mba == 33 ) || ( !IS_16X16 ( h->mtype ) )){ - h->current_mv_x=0; - h->current_mv_y=0; - } -} - -void ff_h261_encode_init(MpegEncContext *s){ - static int done = 0; - - if (!done) { - done = 1; - init_rl(&h261_rl_tcoeff, static_rl_table_store); - } - - s->min_qcoeff= -127; - s->max_qcoeff= 127; - s->y_dc_scale_table= - s->c_dc_scale_table= ff_mpeg1_dc_scale_table; -} - - -/** - * encodes a 8x8 block. - * @param block the 8x8 block - * @param n block index (0-3 are luma, 4-5 are chroma) - */ -static void h261_encode_block(H261Context * h, DCTELEM * block, int n){ - MpegEncContext * const s = &h->s; - int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code; - RLTable *rl; - - rl = &h261_rl_tcoeff; - if (s->mb_intra) { - /* DC coef */ - level = block[0]; - /* 255 cannot be represented, so we clamp */ - if (level > 254) { - level = 254; - block[0] = 254; - } - /* 0 cannot be represented also */ - else if (level < 1) { - level = 1; - block[0] = 1; - } - if (level == 128) - put_bits(&s->pb, 8, 0xff); - else - put_bits(&s->pb, 8, level); - i = 1; - } else if((block[0]==1 || block[0] == -1) && (s->block_last_index[n] > -1)){ - //special case - put_bits(&s->pb,2,block[0]>0 ? 2 : 3 ); - i = 1; - } else { - i = 0; - } - - /* AC coefs */ - last_index = s->block_last_index[n]; - last_non_zero = i - 1; - for (; i <= last_index; i++) { - j = s->intra_scantable.permutated[i]; - level = block[j]; - if (level) { - run = i - last_non_zero - 1; - last = (i == last_index); - sign = 0; - slevel = level; - if (level < 0) { - sign = 1; - level = -level; - } - code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, run, level); - if(run==0 && level < 16) - code+=1; - put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - if (code == rl->n) { - put_bits(&s->pb, 6, run); - assert(slevel != 0); - assert(level <= 127); - put_bits(&s->pb, 8, slevel & 0xff); - } else { - put_bits(&s->pb, 1, sign); - } - last_non_zero = i; - } - } - if(last_index > -1){ - put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]);// END OF BLOCK - } -} - -/***********************************************/ -/* decoding */ - -static VLC h261_mba_vlc; -static VLC h261_mtype_vlc; -static VLC h261_mv_vlc; -static VLC h261_cbp_vlc; - -static void h261_decode_init_vlc(H261Context *h){ - static int done = 0; - - if(!done){ - done = 1; - init_vlc(&h261_mba_vlc, H261_MBA_VLC_BITS, 35, - h261_mba_bits, 1, 1, - h261_mba_code, 1, 1, 1); - init_vlc(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10, - h261_mtype_bits, 1, 1, - h261_mtype_code, 1, 1, 1); - init_vlc(&h261_mv_vlc, H261_MV_VLC_BITS, 17, - &h261_mv_tab[0][1], 2, 1, - &h261_mv_tab[0][0], 2, 1, 1); - init_vlc(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63, - &h261_cbp_tab[0][1], 2, 1, - &h261_cbp_tab[0][0], 2, 1, 1); - init_rl(&h261_rl_tcoeff, static_rl_table_store); - init_vlc_rl(&h261_rl_tcoeff, 1); - } -} - -static int h261_decode_init(AVCodecContext *avctx){ - H261Context *h= avctx->priv_data; - MpegEncContext * const s = &h->s; - - // set defaults - MPV_decode_defaults(s); - s->avctx = avctx; - - s->width = s->avctx->coded_width; - s->height = s->avctx->coded_height; - s->codec_id = s->avctx->codec->id; - - s->out_format = FMT_H261; - s->low_delay= 1; - avctx->pix_fmt= PIX_FMT_YUV420P; - - s->codec_id= avctx->codec->id; - - h261_decode_init_vlc(h); - - h->gob_start_code_skipped = 0; - - return 0; -} - -/** - * decodes the group of blocks header or slice header. - * @return <0 if an error occured - */ -static int h261_decode_gob_header(H261Context *h){ - unsigned int val; - MpegEncContext * const s = &h->s; - - if ( !h->gob_start_code_skipped ){ - /* Check for GOB Start Code */ - val = show_bits(&s->gb, 15); - if(val) - return -1; - - /* We have a GBSC */ - skip_bits(&s->gb, 16); - } - - h->gob_start_code_skipped = 0; - - h->gob_number = get_bits(&s->gb, 4); /* GN */ - s->qscale = get_bits(&s->gb, 5); /* GQUANT */ - - /* Check if gob_number is valid */ - if (s->mb_height==18){ //cif - if ((h->gob_number<=0) || (h->gob_number>12)) - return -1; - } - else{ //qcif - if ((h->gob_number!=1) && (h->gob_number!=3) && (h->gob_number!=5)) - return -1; - } - - /* GEI */ - while (get_bits1(&s->gb) != 0) { - skip_bits(&s->gb, 8); - } - - if(s->qscale==0) - return -1; - - // For the first transmitted macroblock in a GOB, MBA is the absolute address. For - // subsequent macroblocks, MBA is the difference between the absolute addresses of - // the macroblock and the last transmitted macroblock. - h->current_mba = 0; - h->mba_diff = 0; - - return 0; -} - -/** - * decodes the group of blocks / video packet header. - * @return <0 if no resync found - */ -static int ff_h261_resync(H261Context *h){ - MpegEncContext * const s = &h->s; - int left, ret; - - if ( h->gob_start_code_skipped ){ - ret= h261_decode_gob_header(h); - if(ret>=0) - return 0; - } - else{ - if(show_bits(&s->gb, 15)==0){ - ret= h261_decode_gob_header(h); - if(ret>=0) - return 0; - } - //ok, its not where its supposed to be ... - s->gb= s->last_resync_gb; - align_get_bits(&s->gb); - left= s->gb.size_in_bits - get_bits_count(&s->gb); - - for(;left>15+1+4+5; left-=8){ - if(show_bits(&s->gb, 15)==0){ - GetBitContext bak= s->gb; - - ret= h261_decode_gob_header(h); - if(ret>=0) - return 0; - - s->gb= bak; - } - skip_bits(&s->gb, 8); - } - } - - return -1; -} - -/** - * decodes skipped macroblocks - * @return 0 - */ -static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 ) -{ - MpegEncContext * const s = &h->s; - int i; - - s->mb_intra = 0; - - for(i=mba1; i<mba2; i++){ - int j, xy; - - s->mb_x= ((h->gob_number-1) % 2) * 11 + i % 11; - s->mb_y= ((h->gob_number-1) / 2) * 3 + i / 11; - xy = s->mb_x + s->mb_y * s->mb_stride; - ff_init_block_index(s); - ff_update_block_index(s); - - for(j=0;j<6;j++) - s->block_last_index[j] = -1; - - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - h->mtype &= ~MB_TYPE_H261_FIL; - - MPV_decode_mb(s, s->block); - } - - return 0; -} - -static int decode_mv_component(GetBitContext *gb, int v){ - int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2); - - /* check if mv_diff is valid */ - if ( mv_diff < 0 ) - return v; - - mv_diff = mvmap[mv_diff]; - - if(mv_diff && !get_bits1(gb)) - mv_diff= -mv_diff; - - v += mv_diff; - if (v <=-16) v+= 32; - else if(v >= 16) v-= 32; - - return v; -} - -static int h261_decode_mb(H261Context *h){ - MpegEncContext * const s = &h->s; - int i, cbp, xy; - - cbp = 63; - // Read mba - do{ - h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, H261_MBA_VLC_BITS, 2); - - /* Check for slice end */ - /* NOTE: GOB can be empty (no MB data) or exist only of MBA_stuffing */ - if (h->mba_diff == MBA_STARTCODE){ // start code - h->gob_start_code_skipped = 1; - return SLICE_END; - } - } - while( h->mba_diff == MBA_STUFFING ); // stuffing - - if ( h->mba_diff < 0 ){ - if ( get_bits_count(&s->gb) + 7 >= s->gb.size_in_bits ) - return SLICE_END; - - av_log(s->avctx, AV_LOG_ERROR, "illegal mba at %d %d\n", s->mb_x, s->mb_y); - return SLICE_ERROR; - } - - h->mba_diff += 1; - h->current_mba += h->mba_diff; - - if ( h->current_mba > MBA_STUFFING ) - return SLICE_ERROR; - - s->mb_x= ((h->gob_number-1) % 2) * 11 + ((h->current_mba-1) % 11); - s->mb_y= ((h->gob_number-1) / 2) * 3 + ((h->current_mba-1) / 11); - xy = s->mb_x + s->mb_y * s->mb_stride; - ff_init_block_index(s); - ff_update_block_index(s); - - // Read mtype - h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2); - h->mtype = h261_mtype_map[h->mtype]; - - // Read mquant - if ( IS_QUANT ( h->mtype ) ){ - ff_set_qscale(s, get_bits(&s->gb, 5)); - } - - s->mb_intra = IS_INTRA4x4(h->mtype); - - // Read mv - if ( IS_16X16 ( h->mtype ) ){ - // Motion vector data is included for all MC macroblocks. MVD is obtained from the macroblock vector by subtracting the - // vector of the preceding macroblock. For this calculation the vector of the preceding macroblock is regarded as zero in the - // following three situations: - // 1) evaluating MVD for macroblocks 1, 12 and 23; - // 2) evaluating MVD for macroblocks in which MBA does not represent a difference of 1; - // 3) MTYPE of the previous macroblock was not MC. - if ( ( h->current_mba == 1 ) || ( h->current_mba == 12 ) || ( h->current_mba == 23 ) || - ( h->mba_diff != 1)) - { - h->current_mv_x = 0; - h->current_mv_y = 0; - } - - h->current_mv_x= decode_mv_component(&s->gb, h->current_mv_x); - h->current_mv_y= decode_mv_component(&s->gb, h->current_mv_y); - }else{ - h->current_mv_x = 0; - h->current_mv_y = 0; - } - - // Read cbp - if ( HAS_CBP( h->mtype ) ){ - cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1; - } - - if(s->mb_intra){ - s->current_picture.mb_type[xy]= MB_TYPE_INTRA; - goto intra; - } - - //set motion vectors - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; - s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation - s->mv[0][0][1] = h->current_mv_y * 2; - -intra: - /* decode each block */ - if(s->mb_intra || HAS_CBP(h->mtype)){ - s->dsp.clear_blocks(s->block[0]); - for (i = 0; i < 6; i++) { - if (h261_decode_block(h, s->block[i], i, cbp&32) < 0){ - return SLICE_ERROR; - } - cbp+=cbp; - } - }else{ - for (i = 0; i < 6; i++) - s->block_last_index[i]= -1; - } - - MPV_decode_mb(s, s->block); - - return SLICE_OK; -} - -/** - * decodes a macroblock - * @return <0 if an error occured - */ -static int h261_decode_block(H261Context * h, DCTELEM * block, - int n, int coded) -{ - MpegEncContext * const s = &h->s; - int code, level, i, j, run; - RLTable *rl = &h261_rl_tcoeff; - const uint8_t *scan_table; - - // For the variable length encoding there are two code tables, one being used for - // the first transmitted LEVEL in INTER, INTER+MC and INTER+MC+FIL blocks, the second - // for all other LEVELs except the first one in INTRA blocks which is fixed length - // coded with 8 bits. - // NOTE: the two code tables only differ in one VLC so we handle that manually. - scan_table = s->intra_scantable.permutated; - if (s->mb_intra){ - /* DC coef */ - level = get_bits(&s->gb, 8); - // 0 (00000000b) and -128 (10000000b) are FORBIDDEN - if((level&0x7F) == 0){ - av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y); - return -1; - } - // The code 1000 0000 is not used, the reconstruction level of 1024 being coded as 1111 1111. - if (level == 255) - level = 128; - block[0] = level; - i = 1; - }else if(coded){ - // Run Level Code - // EOB Not possible for first level when cbp is available (that's why the table is different) - // 0 1 1s - // * * 0* - int check = show_bits(&s->gb, 2); - i = 0; - if ( check & 0x2 ){ - skip_bits(&s->gb, 2); - block[0] = ( check & 0x1 ) ? -1 : 1; - i = 1; - } - }else{ - i = 0; - } - if(!coded){ - s->block_last_index[n] = i - 1; - return 0; - } - for(;;){ - code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y); - return -1; - } - if (code == rl->n) { - /* escape */ - // The remaining combinations of (run, level) are encoded with a 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits level. - run = get_bits(&s->gb, 6); - level = get_sbits(&s->gb, 8); - }else if(code == 0){ - break; - }else{ - run = rl->table_run[code]; - level = rl->table_level[code]; - if (get_bits1(&s->gb)) - level = -level; - } - i += run; - if (i >= 64){ - av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", s->mb_x, s->mb_y); - return -1; - } - j = scan_table[i]; - block[j] = level; - i++; - } - s->block_last_index[n] = i-1; - return 0; -} - -/** - * decodes the H261 picture header. - * @return <0 if no startcode found - */ -static int h261_decode_picture_header(H261Context *h){ - MpegEncContext * const s = &h->s; - int format, i; - uint32_t startcode= 0; - - for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>24; i-=1){ - startcode = ((startcode << 1) | get_bits(&s->gb, 1)) & 0x000FFFFF; - - if(startcode == 0x10) - break; - } - - if (startcode != 0x10){ - av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n"); - return -1; - } - - /* temporal reference */ - i= get_bits(&s->gb, 5); /* picture timestamp */ - if(i < (s->picture_number&31)) - i += 32; - s->picture_number = (s->picture_number&~31) + i; - - s->avctx->time_base= (AVRational){1001, 30000}; - s->current_picture.pts= s->picture_number; - - - /* PTYPE starts here */ - skip_bits1(&s->gb); /* split screen off */ - skip_bits1(&s->gb); /* camera off */ - skip_bits1(&s->gb); /* freeze picture release off */ - - format = get_bits1(&s->gb); - - //only 2 formats possible - if (format == 0){//QCIF - s->width = 176; - s->height = 144; - s->mb_width = 11; - s->mb_height = 9; - }else{//CIF - s->width = 352; - s->height = 288; - s->mb_width = 22; - s->mb_height = 18; - } - - s->mb_num = s->mb_width * s->mb_height; - - skip_bits1(&s->gb); /* still image mode off */ - skip_bits1(&s->gb); /* Reserved */ - - /* PEI */ - while (get_bits1(&s->gb) != 0){ - skip_bits(&s->gb, 8); - } - - // h261 has no I-FRAMES, but if we pass I_TYPE for the first frame, the codec crashes if it does - // not contain all I-blocks (e.g. when a packet is lost) - s->pict_type = P_TYPE; - - h->gob_number = 0; - return 0; -} - -static int h261_decode_gob(H261Context *h){ - MpegEncContext * const s = &h->s; - - ff_set_qscale(s, s->qscale); - - /* decode mb's */ - while(h->current_mba <= MBA_STUFFING) - { - int ret; - /* DCT & quantize */ - ret= h261_decode_mb(h); - if(ret<0){ - if(ret==SLICE_END){ - h261_decode_mb_skipped(h, h->current_mba, 33); - return 0; - } - av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", s->mb_x + s->mb_y*s->mb_stride); - return -1; - } - - h261_decode_mb_skipped(h, h->current_mba-h->mba_diff, h->current_mba-1); - } - - return -1; -} - -#ifdef CONFIG_H261_PARSER -static int h261_find_frame_end(ParseContext *pc, AVCodecContext* avctx, const uint8_t *buf, int buf_size){ - int vop_found, i, j; - uint32_t state; - - vop_found= pc->frame_start_found; - state= pc->state; - - for(i=0; i<buf_size && !vop_found; i++){ - state= (state<<8) | buf[i]; - for(j=0; j<8; j++){ - if(((state>>j)&0xFFFFF) == 0x00010){ - vop_found=1; - break; - } - } - } - if(vop_found){ - for(; i<buf_size; i++){ - state= (state<<8) | buf[i]; - for(j=0; j<8; j++){ - if(((state>>j)&0xFFFFF) == 0x00010){ - pc->frame_start_found=0; - pc->state= state>>(2*8); - return i-1; - } - } - } - } - - pc->frame_start_found= vop_found; - pc->state= state; - return END_NOT_FOUND; -} - -static int h261_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - next= h261_find_frame_end(pc,avctx, buf, buf_size); - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - *poutbuf = (uint8_t *)buf; - *poutbuf_size = buf_size; - return next; -} -#endif - -/** - * returns the number of bytes consumed for building the current frame - */ -static int get_consumed_bytes(MpegEncContext *s, int buf_size){ - int pos= get_bits_count(&s->gb)>>3; - if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) - if(pos+10>buf_size) pos=buf_size; // oops ;) - - return pos; -} - -static int h261_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - H261Context *h= avctx->priv_data; - MpegEncContext *s = &h->s; - int ret; - AVFrame *pict = data; - -#ifdef DEBUG - av_log(avctx, AV_LOG_DEBUG, "*****frame %d size=%d\n", avctx->frame_number, buf_size); - av_log(avctx, AV_LOG_DEBUG, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); -#endif - s->flags= avctx->flags; - s->flags2= avctx->flags2; - - h->gob_start_code_skipped=0; - -retry: - - init_get_bits(&s->gb, buf, buf_size*8); - - if(!s->context_initialized){ - if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix - return -1; - } - - //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there - if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ - int i= ff_find_unused_picture(s, 0); - s->current_picture_ptr= &s->picture[i]; - } - - ret = h261_decode_picture_header(h); - - /* skip if the header was thrashed */ - if (ret < 0){ - av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); - return -1; - } - - if (s->width != avctx->coded_width || s->height != avctx->coded_height){ - ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat - s->parse_context.buffer=0; - MPV_common_end(s); - s->parse_context= pc; - } - if (!s->context_initialized) { - avcodec_set_dimensions(avctx, s->width, s->height); - - goto retry; - } - - // for hurry_up==5 - s->current_picture.pict_type= s->pict_type; - s->current_picture.key_frame= s->pict_type == I_TYPE; - - /* skip everything if we are in a hurry>=5 */ - if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size); - if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) - ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) - || avctx->skip_frame >= AVDISCARD_ALL) - return get_consumed_bytes(s, buf_size); - - if(MPV_frame_start(s, avctx) < 0) - return -1; - - ff_er_frame_start(s); - - /* decode each macroblock */ - s->mb_x=0; - s->mb_y=0; - - while(h->gob_number < (s->mb_height==18 ? 12 : 5)){ - if(ff_h261_resync(h)<0) - break; - h261_decode_gob(h); - } - MPV_frame_end(s); - -assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type); -assert(s->current_picture.pict_type == s->pict_type); - *pict= *(AVFrame*)s->current_picture_ptr; - ff_print_debug_info(s, pict); - - *data_size = sizeof(AVFrame); - - return get_consumed_bytes(s, buf_size); -} - -static int h261_decode_end(AVCodecContext *avctx) -{ - H261Context *h= avctx->priv_data; - MpegEncContext *s = &h->s; - - MPV_common_end(s); - return 0; -} - -#ifdef CONFIG_ENCODERS -AVCodec h261_encoder = { - "h261", - CODEC_TYPE_VIDEO, - CODEC_ID_H261, - sizeof(H261Context), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; -#endif - -AVCodec h261_decoder = { - "h261", - CODEC_TYPE_VIDEO, - CODEC_ID_H261, - sizeof(H261Context), - h261_decode_init, - NULL, - h261_decode_end, - h261_decode_frame, - CODEC_CAP_DR1, -}; - -#ifdef CONFIG_H261_PARSER -AVCodecParser h261_parser = { - { CODEC_ID_H261 }, - sizeof(ParseContext), - NULL, - h261_parse, - ff_parse_close, -}; -#endif diff --git a/contrib/ffmpeg/libavcodec/h261.h b/contrib/ffmpeg/libavcodec/h261.h new file mode 100644 index 000000000..f0ce7c366 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h261.h @@ -0,0 +1,51 @@ +/* + * H261 decoder + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2004 Maarten Daniels + * + * 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 h261.c + * h261codec. + */ + +#ifndef FFMPEG_H261_H +#define FFMPEG_H261_H + +#include "mpegvideo.h" + +/** + * H261Context + */ +typedef struct H261Context{ + MpegEncContext s; + + int current_mba; + int previous_mba; + int mba_diff; + int mtype; + int current_mv_x; + int current_mv_y; + int gob_number; + int gob_start_code_skipped; // 1 if gob start code is already read before gob header is read +}H261Context; + +#define MB_TYPE_H261_FIL 0x800000 + +#endif /* FFMPEG_H261_H */ diff --git a/contrib/ffmpeg/libavcodec/h261_parser.c b/contrib/ffmpeg/libavcodec/h261_parser.c new file mode 100644 index 000000000..3f3aac6e4 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h261_parser.c @@ -0,0 +1,90 @@ +/* + * H261 parser + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2004 Maarten Daniels + * + * 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 h261_parser.c + * h261codec. + */ + +#include "parser.h" + + +static int h261_find_frame_end(ParseContext *pc, AVCodecContext* avctx, const uint8_t *buf, int buf_size){ + int vop_found, i, j; + uint32_t state; + + vop_found= pc->frame_start_found; + state= pc->state; + + for(i=0; i<buf_size && !vop_found; i++){ + state= (state<<8) | buf[i]; + for(j=0; j<8; j++){ + if(((state>>j)&0xFFFFF0) == 0x000100){ + vop_found=1; + break; + } + } + } + if(vop_found){ + for(; i<buf_size; i++){ + state= (state<<8) | buf[i]; + for(j=0; j<8; j++){ + if(((state>>j)&0xFFFFF0) == 0x000100){ + pc->frame_start_found=0; + pc->state= (state>>(3*8))+0xFF00; + return i-2; + } + } + } + } + + pc->frame_start_found= vop_found; + pc->state= state; + return END_NOT_FOUND; +} + +static int h261_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + int next; + + next= h261_find_frame_end(pc,avctx, buf, buf_size); + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser h261_parser = { + { CODEC_ID_H261 }, + sizeof(ParseContext), + NULL, + h261_parse, + ff_parse_close, +}; diff --git a/contrib/ffmpeg/libavcodec/h261data.h b/contrib/ffmpeg/libavcodec/h261data.h index 2a93b73e3..a86b6df98 100644 --- a/contrib/ffmpeg/libavcodec/h261data.h +++ b/contrib/ffmpeg/libavcodec/h261data.h @@ -23,7 +23,12 @@ * @file h261data.h * H.261 tables. */ -#define MB_TYPE_H261_FIL 0x800000 + +#ifndef FFMPEG_H261DATA_H +#define FFMPEG_H261DATA_H + +#include <stdint.h> +#include "h261.h" // H.261 VLC table for macroblock addressing static const uint8_t h261_mba_code[35] = { @@ -155,3 +160,5 @@ static RLTable h261_rl_tcoeff = { h261_tcoeff_run, h261_tcoeff_level, }; + +#endif /* FFMPEG_H261DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/h261dec.c b/contrib/ffmpeg/libavcodec/h261dec.c new file mode 100644 index 000000000..264a7d3f5 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h261dec.c @@ -0,0 +1,650 @@ +/* + * H261 decoder + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2004 Maarten Daniels + * + * 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 h261dec.c + * H.261 decoder. + */ + +#include "dsputil.h" +#include "avcodec.h" +#include "mpegvideo.h" +#include "h261.h" +#include "h261data.h" + +#define H261_MBA_VLC_BITS 9 +#define H261_MTYPE_VLC_BITS 6 +#define H261_MV_VLC_BITS 7 +#define H261_CBP_VLC_BITS 9 +#define TCOEFF_VLC_BITS 9 +#define MBA_STUFFING 33 +#define MBA_STARTCODE 34 + +extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; + +static VLC h261_mba_vlc; +static VLC h261_mtype_vlc; +static VLC h261_mv_vlc; +static VLC h261_cbp_vlc; + +static int h261_decode_block(H261Context * h, DCTELEM * block, int n, int coded); + +static void h261_decode_init_vlc(H261Context *h){ + static int done = 0; + + if(!done){ + done = 1; + init_vlc(&h261_mba_vlc, H261_MBA_VLC_BITS, 35, + h261_mba_bits, 1, 1, + h261_mba_code, 1, 1, 1); + init_vlc(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10, + h261_mtype_bits, 1, 1, + h261_mtype_code, 1, 1, 1); + init_vlc(&h261_mv_vlc, H261_MV_VLC_BITS, 17, + &h261_mv_tab[0][1], 2, 1, + &h261_mv_tab[0][0], 2, 1, 1); + init_vlc(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63, + &h261_cbp_tab[0][1], 2, 1, + &h261_cbp_tab[0][0], 2, 1, 1); + init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store); + init_vlc_rl(&h261_rl_tcoeff, 1); + } +} + +static int h261_decode_init(AVCodecContext *avctx){ + H261Context *h= avctx->priv_data; + MpegEncContext * const s = &h->s; + + // set defaults + MPV_decode_defaults(s); + s->avctx = avctx; + + s->width = s->avctx->coded_width; + s->height = s->avctx->coded_height; + s->codec_id = s->avctx->codec->id; + + s->out_format = FMT_H261; + s->low_delay= 1; + avctx->pix_fmt= PIX_FMT_YUV420P; + + s->codec_id= avctx->codec->id; + + h261_decode_init_vlc(h); + + h->gob_start_code_skipped = 0; + + return 0; +} + +/** + * decodes the group of blocks header or slice header. + * @return <0 if an error occured + */ +static int h261_decode_gob_header(H261Context *h){ + unsigned int val; + MpegEncContext * const s = &h->s; + + if ( !h->gob_start_code_skipped ){ + /* Check for GOB Start Code */ + val = show_bits(&s->gb, 15); + if(val) + return -1; + + /* We have a GBSC */ + skip_bits(&s->gb, 16); + } + + h->gob_start_code_skipped = 0; + + h->gob_number = get_bits(&s->gb, 4); /* GN */ + s->qscale = get_bits(&s->gb, 5); /* GQUANT */ + + /* Check if gob_number is valid */ + if (s->mb_height==18){ //cif + if ((h->gob_number<=0) || (h->gob_number>12)) + return -1; + } + else{ //qcif + if ((h->gob_number!=1) && (h->gob_number!=3) && (h->gob_number!=5)) + return -1; + } + + /* GEI */ + while (get_bits1(&s->gb) != 0) { + skip_bits(&s->gb, 8); + } + + if(s->qscale==0) + return -1; + + // For the first transmitted macroblock in a GOB, MBA is the absolute address. For + // subsequent macroblocks, MBA is the difference between the absolute addresses of + // the macroblock and the last transmitted macroblock. + h->current_mba = 0; + h->mba_diff = 0; + + return 0; +} + +/** + * decodes the group of blocks / video packet header. + * @return <0 if no resync found + */ +static int ff_h261_resync(H261Context *h){ + MpegEncContext * const s = &h->s; + int left, ret; + + if ( h->gob_start_code_skipped ){ + ret= h261_decode_gob_header(h); + if(ret>=0) + return 0; + } + else{ + if(show_bits(&s->gb, 15)==0){ + ret= h261_decode_gob_header(h); + if(ret>=0) + return 0; + } + //OK, it is not where it is supposed to be ... + s->gb= s->last_resync_gb; + align_get_bits(&s->gb); + left= s->gb.size_in_bits - get_bits_count(&s->gb); + + for(;left>15+1+4+5; left-=8){ + if(show_bits(&s->gb, 15)==0){ + GetBitContext bak= s->gb; + + ret= h261_decode_gob_header(h); + if(ret>=0) + return 0; + + s->gb= bak; + } + skip_bits(&s->gb, 8); + } + } + + return -1; +} + +/** + * decodes skipped macroblocks + * @return 0 + */ +static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 ) +{ + MpegEncContext * const s = &h->s; + int i; + + s->mb_intra = 0; + + for(i=mba1; i<mba2; i++){ + int j, xy; + + s->mb_x= ((h->gob_number-1) % 2) * 11 + i % 11; + s->mb_y= ((h->gob_number-1) / 2) * 3 + i / 11; + xy = s->mb_x + s->mb_y * s->mb_stride; + ff_init_block_index(s); + ff_update_block_index(s); + + for(j=0;j<6;j++) + s->block_last_index[j] = -1; + + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mb_skipped = 1; + h->mtype &= ~MB_TYPE_H261_FIL; + + MPV_decode_mb(s, s->block); + } + + return 0; +} + +static int decode_mv_component(GetBitContext *gb, int v){ + int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2); + + /* check if mv_diff is valid */ + if ( mv_diff < 0 ) + return v; + + mv_diff = mvmap[mv_diff]; + + if(mv_diff && !get_bits1(gb)) + mv_diff= -mv_diff; + + v += mv_diff; + if (v <=-16) v+= 32; + else if(v >= 16) v-= 32; + + return v; +} + +static int h261_decode_mb(H261Context *h){ + MpegEncContext * const s = &h->s; + int i, cbp, xy; + + cbp = 63; + // Read mba + do{ + h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, H261_MBA_VLC_BITS, 2); + + /* Check for slice end */ + /* NOTE: GOB can be empty (no MB data) or exist only of MBA_stuffing */ + if (h->mba_diff == MBA_STARTCODE){ // start code + h->gob_start_code_skipped = 1; + return SLICE_END; + } + } + while( h->mba_diff == MBA_STUFFING ); // stuffing + + if ( h->mba_diff < 0 ){ + if ( get_bits_count(&s->gb) + 7 >= s->gb.size_in_bits ) + return SLICE_END; + + av_log(s->avctx, AV_LOG_ERROR, "illegal mba at %d %d\n", s->mb_x, s->mb_y); + return SLICE_ERROR; + } + + h->mba_diff += 1; + h->current_mba += h->mba_diff; + + if ( h->current_mba > MBA_STUFFING ) + return SLICE_ERROR; + + s->mb_x= ((h->gob_number-1) % 2) * 11 + ((h->current_mba-1) % 11); + s->mb_y= ((h->gob_number-1) / 2) * 3 + ((h->current_mba-1) / 11); + xy = s->mb_x + s->mb_y * s->mb_stride; + ff_init_block_index(s); + ff_update_block_index(s); + + // Read mtype + h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2); + h->mtype = h261_mtype_map[h->mtype]; + + // Read mquant + if ( IS_QUANT ( h->mtype ) ){ + ff_set_qscale(s, get_bits(&s->gb, 5)); + } + + s->mb_intra = IS_INTRA4x4(h->mtype); + + // Read mv + if ( IS_16X16 ( h->mtype ) ){ + // Motion vector data is included for all MC macroblocks. MVD is obtained from the macroblock vector by subtracting the + // vector of the preceding macroblock. For this calculation the vector of the preceding macroblock is regarded as zero in the + // following three situations: + // 1) evaluating MVD for macroblocks 1, 12 and 23; + // 2) evaluating MVD for macroblocks in which MBA does not represent a difference of 1; + // 3) MTYPE of the previous macroblock was not MC. + if ( ( h->current_mba == 1 ) || ( h->current_mba == 12 ) || ( h->current_mba == 23 ) || + ( h->mba_diff != 1)) + { + h->current_mv_x = 0; + h->current_mv_y = 0; + } + + h->current_mv_x= decode_mv_component(&s->gb, h->current_mv_x); + h->current_mv_y= decode_mv_component(&s->gb, h->current_mv_y); + }else{ + h->current_mv_x = 0; + h->current_mv_y = 0; + } + + // Read cbp + if ( HAS_CBP( h->mtype ) ){ + cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1; + } + + if(s->mb_intra){ + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + goto intra; + } + + //set motion vectors + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; + s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation + s->mv[0][0][1] = h->current_mv_y * 2; + +intra: + /* decode each block */ + if(s->mb_intra || HAS_CBP(h->mtype)){ + s->dsp.clear_blocks(s->block[0]); + for (i = 0; i < 6; i++) { + if (h261_decode_block(h, s->block[i], i, cbp&32) < 0){ + return SLICE_ERROR; + } + cbp+=cbp; + } + }else{ + for (i = 0; i < 6; i++) + s->block_last_index[i]= -1; + } + + MPV_decode_mb(s, s->block); + + return SLICE_OK; +} + +/** + * decodes a macroblock + * @return <0 if an error occured + */ +static int h261_decode_block(H261Context * h, DCTELEM * block, + int n, int coded) +{ + MpegEncContext * const s = &h->s; + int code, level, i, j, run; + RLTable *rl = &h261_rl_tcoeff; + const uint8_t *scan_table; + + // For the variable length encoding there are two code tables, one being used for + // the first transmitted LEVEL in INTER, INTER+MC and INTER+MC+FIL blocks, the second + // for all other LEVELs except the first one in INTRA blocks which is fixed length + // coded with 8 bits. + // NOTE: the two code tables only differ in one VLC so we handle that manually. + scan_table = s->intra_scantable.permutated; + if (s->mb_intra){ + /* DC coef */ + level = get_bits(&s->gb, 8); + // 0 (00000000b) and -128 (10000000b) are FORBIDDEN + if((level&0x7F) == 0){ + av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y); + return -1; + } + // The code 1000 0000 is not used, the reconstruction level of 1024 being coded as 1111 1111. + if (level == 255) + level = 128; + block[0] = level; + i = 1; + }else if(coded){ + // Run Level Code + // EOB Not possible for first level when cbp is available (that's why the table is different) + // 0 1 1s + // * * 0* + int check = show_bits(&s->gb, 2); + i = 0; + if ( check & 0x2 ){ + skip_bits(&s->gb, 2); + block[0] = ( check & 0x1 ) ? -1 : 1; + i = 1; + } + }else{ + i = 0; + } + if(!coded){ + s->block_last_index[n] = i - 1; + return 0; + } + for(;;){ + code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2); + if (code < 0){ + av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y); + return -1; + } + if (code == rl->n) { + /* escape */ + // The remaining combinations of (run, level) are encoded with a 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits level. + run = get_bits(&s->gb, 6); + level = get_sbits(&s->gb, 8); + }else if(code == 0){ + break; + }else{ + run = rl->table_run[code]; + level = rl->table_level[code]; + if (get_bits1(&s->gb)) + level = -level; + } + i += run; + if (i >= 64){ + av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", s->mb_x, s->mb_y); + return -1; + } + j = scan_table[i]; + block[j] = level; + i++; + } + s->block_last_index[n] = i-1; + return 0; +} + +/** + * decodes the H261 picture header. + * @return <0 if no startcode found + */ +static int h261_decode_picture_header(H261Context *h){ + MpegEncContext * const s = &h->s; + int format, i; + uint32_t startcode= 0; + + for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>24; i-=1){ + startcode = ((startcode << 1) | get_bits(&s->gb, 1)) & 0x000FFFFF; + + if(startcode == 0x10) + break; + } + + if (startcode != 0x10){ + av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n"); + return -1; + } + + /* temporal reference */ + i= get_bits(&s->gb, 5); /* picture timestamp */ + if(i < (s->picture_number&31)) + i += 32; + s->picture_number = (s->picture_number&~31) + i; + + s->avctx->time_base= (AVRational){1001, 30000}; + s->current_picture.pts= s->picture_number; + + + /* PTYPE starts here */ + skip_bits1(&s->gb); /* split screen off */ + skip_bits1(&s->gb); /* camera off */ + skip_bits1(&s->gb); /* freeze picture release off */ + + format = get_bits1(&s->gb); + + //only 2 formats possible + if (format == 0){//QCIF + s->width = 176; + s->height = 144; + s->mb_width = 11; + s->mb_height = 9; + }else{//CIF + s->width = 352; + s->height = 288; + s->mb_width = 22; + s->mb_height = 18; + } + + s->mb_num = s->mb_width * s->mb_height; + + skip_bits1(&s->gb); /* still image mode off */ + skip_bits1(&s->gb); /* Reserved */ + + /* PEI */ + while (get_bits1(&s->gb) != 0){ + skip_bits(&s->gb, 8); + } + + // h261 has no I-FRAMES, but if we pass I_TYPE for the first frame, the codec crashes if it does + // not contain all I-blocks (e.g. when a packet is lost) + s->pict_type = P_TYPE; + + h->gob_number = 0; + return 0; +} + +static int h261_decode_gob(H261Context *h){ + MpegEncContext * const s = &h->s; + + ff_set_qscale(s, s->qscale); + + /* decode mb's */ + while(h->current_mba <= MBA_STUFFING) + { + int ret; + /* DCT & quantize */ + ret= h261_decode_mb(h); + if(ret<0){ + if(ret==SLICE_END){ + h261_decode_mb_skipped(h, h->current_mba, 33); + return 0; + } + av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", s->mb_x + s->mb_y*s->mb_stride); + return -1; + } + + h261_decode_mb_skipped(h, h->current_mba-h->mba_diff, h->current_mba-1); + } + + return -1; +} + +/** + * returns the number of bytes consumed for building the current frame + */ +static int get_consumed_bytes(MpegEncContext *s, int buf_size){ + int pos= get_bits_count(&s->gb)>>3; + if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...) + if(pos+10>buf_size) pos=buf_size; // oops ;) + + return pos; +} + +static int h261_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + H261Context *h= avctx->priv_data; + MpegEncContext *s = &h->s; + int ret; + AVFrame *pict = data; + +#ifdef DEBUG + av_log(avctx, AV_LOG_DEBUG, "*****frame %d size=%d\n", avctx->frame_number, buf_size); + av_log(avctx, AV_LOG_DEBUG, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); +#endif + s->flags= avctx->flags; + s->flags2= avctx->flags2; + + h->gob_start_code_skipped=0; + +retry: + + init_get_bits(&s->gb, buf, buf_size*8); + + if(!s->context_initialized){ + if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix + return -1; + } + + //we need to set current_picture_ptr before reading the header, otherwise we cannot store anyting im there + if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ + int i= ff_find_unused_picture(s, 0); + s->current_picture_ptr= &s->picture[i]; + } + + ret = h261_decode_picture_header(h); + + /* skip if the header was thrashed */ + if (ret < 0){ + av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); + return -1; + } + + if (s->width != avctx->coded_width || s->height != avctx->coded_height){ + ParseContext pc= s->parse_context; //FIXME move this demuxing hack to libavformat + s->parse_context.buffer=0; + MPV_common_end(s); + s->parse_context= pc; + } + if (!s->context_initialized) { + avcodec_set_dimensions(avctx, s->width, s->height); + + goto retry; + } + + // for hurry_up==5 + s->current_picture.pict_type= s->pict_type; + s->current_picture.key_frame= s->pict_type == I_TYPE; + + /* skip everything if we are in a hurry>=5 */ + if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size); + if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) + ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) + || avctx->skip_frame >= AVDISCARD_ALL) + return get_consumed_bytes(s, buf_size); + + if(MPV_frame_start(s, avctx) < 0) + return -1; + + ff_er_frame_start(s); + + /* decode each macroblock */ + s->mb_x=0; + s->mb_y=0; + + while(h->gob_number < (s->mb_height==18 ? 12 : 5)){ + if(ff_h261_resync(h)<0) + break; + h261_decode_gob(h); + } + MPV_frame_end(s); + +assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type); +assert(s->current_picture.pict_type == s->pict_type); + *pict= *(AVFrame*)s->current_picture_ptr; + ff_print_debug_info(s, pict); + + *data_size = sizeof(AVFrame); + + return get_consumed_bytes(s, buf_size); +} + +static int h261_decode_end(AVCodecContext *avctx) +{ + H261Context *h= avctx->priv_data; + MpegEncContext *s = &h->s; + + MPV_common_end(s); + return 0; +} + +AVCodec h261_decoder = { + "h261", + CODEC_TYPE_VIDEO, + CODEC_ID_H261, + sizeof(H261Context), + h261_decode_init, + NULL, + h261_decode_end, + h261_decode_frame, + CODEC_CAP_DR1, +}; diff --git a/contrib/ffmpeg/libavcodec/h261enc.c b/contrib/ffmpeg/libavcodec/h261enc.c new file mode 100644 index 000000000..aea2549c7 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h261enc.c @@ -0,0 +1,334 @@ +/* + * H261 encoder + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2004 Maarten Daniels + * + * 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 h261enc.c + * H.261 encoder. + */ + +#include "dsputil.h" +#include "avcodec.h" +#include "mpegvideo.h" +#include "h261.h" +#include "h261data.h" + +extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; + +static void h261_encode_block(H261Context * h, DCTELEM * block, + int n); + +int ff_h261_get_picture_format(int width, int height){ + // QCIF + if (width == 176 && height == 144) + return 0; + // CIF + else if (width == 352 && height == 288) + return 1; + // ERROR + else + return -1; +} + +void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ + H261Context * h = (H261Context *) s; + int format, temp_ref; + + align_put_bits(&s->pb); + + /* Update the pointer to last GOB */ + s->ptr_lastgob = pbBufPtr(&s->pb); + + put_bits(&s->pb, 20, 0x10); /* PSC */ + + temp_ref= s->picture_number * (int64_t)30000 * s->avctx->time_base.num / + (1001 * (int64_t)s->avctx->time_base.den); //FIXME maybe this should use a timestamp + put_bits(&s->pb, 5, temp_ref & 0x1f); /* TemporalReference */ + + put_bits(&s->pb, 1, 0); /* split screen off */ + put_bits(&s->pb, 1, 0); /* camera off */ + put_bits(&s->pb, 1, 0); /* freeze picture release off */ + + format = ff_h261_get_picture_format(s->width, s->height); + + put_bits(&s->pb, 1, format); /* 0 == QCIF, 1 == CIF */ + + put_bits(&s->pb, 1, 0); /* still image mode */ + put_bits(&s->pb, 1, 0); /* reserved */ + + put_bits(&s->pb, 1, 0); /* no PEI */ + if(format == 0) + h->gob_number = -1; + else + h->gob_number = 0; + h->current_mba = 0; +} + +/** + * Encodes a group of blocks header. + */ +static void h261_encode_gob_header(MpegEncContext * s, int mb_line){ + H261Context * h = (H261Context *)s; + if(ff_h261_get_picture_format(s->width, s->height) == 0){ + h->gob_number+=2; // QCIF + } + else{ + h->gob_number++; // CIF + } + put_bits(&s->pb, 16, 1); /* GBSC */ + put_bits(&s->pb, 4, h->gob_number); /* GN */ + put_bits(&s->pb, 5, s->qscale); /* GQUANT */ + put_bits(&s->pb, 1, 0); /* no GEI */ + h->current_mba = 0; + h->previous_mba = 0; + h->current_mv_x=0; + h->current_mv_y=0; +} + +void ff_h261_reorder_mb_index(MpegEncContext* s){ + int index= s->mb_x + s->mb_y*s->mb_width; + + if(index % 33 == 0) + h261_encode_gob_header(s,0); + + /* for CIF the GOB's are fragmented in the middle of a scanline + that's why we need to adjust the x and y index of the macroblocks */ + if(ff_h261_get_picture_format(s->width,s->height) == 1){ // CIF + s->mb_x = index % 11 ; index /= 11; + s->mb_y = index % 3 ; index /= 3; + s->mb_x+= 11*(index % 2); index /= 2; + s->mb_y+= 3*index; + + ff_init_block_index(s); + ff_update_block_index(s); + } +} + +static void h261_encode_motion(H261Context * h, int val){ + MpegEncContext * const s = &h->s; + int sign, code; + if(val==0){ + code = 0; + put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); + } + else{ + if(val > 15) + val -=32; + if(val < -16) + val+=32; + sign = val < 0; + code = sign ? -val : val; + put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); + put_bits(&s->pb,1,sign); + } +} + +static inline int get_cbp(MpegEncContext * s, + DCTELEM block[6][64]) +{ + int i, cbp; + cbp= 0; + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + return cbp; +} +void ff_h261_encode_mb(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y) +{ + H261Context * h = (H261Context *)s; + int mvd, mv_diff_x, mv_diff_y, i, cbp; + cbp = 63; // avoid warning + mvd = 0; + + h->current_mba++; + h->mtype = 0; + + if (!s->mb_intra){ + /* compute cbp */ + cbp= get_cbp(s, block); + + /* mvd indicates if this block is motion compensated */ + mvd = motion_x | motion_y; + + if((cbp | mvd | s->dquant ) == 0) { + /* skip macroblock */ + s->skip_count++; + h->current_mv_x=0; + h->current_mv_y=0; + return; + } + } + + /* MB is not skipped, encode MBA */ + put_bits(&s->pb, h261_mba_bits[(h->current_mba-h->previous_mba)-1], h261_mba_code[(h->current_mba-h->previous_mba)-1]); + + /* calculate MTYPE */ + if(!s->mb_intra){ + h->mtype++; + + if(mvd || s->loop_filter) + h->mtype+=3; + if(s->loop_filter) + h->mtype+=3; + if(cbp || s->dquant) + h->mtype++; + assert(h->mtype > 1); + } + + if(s->dquant) + h->mtype++; + + put_bits(&s->pb, h261_mtype_bits[h->mtype], h261_mtype_code[h->mtype]); + + h->mtype = h261_mtype_map[h->mtype]; + + if(IS_QUANT(h->mtype)){ + ff_set_qscale(s,s->qscale+s->dquant); + put_bits(&s->pb, 5, s->qscale); + } + + if(IS_16X16(h->mtype)){ + mv_diff_x = (motion_x >> 1) - h->current_mv_x; + mv_diff_y = (motion_y >> 1) - h->current_mv_y; + h->current_mv_x = (motion_x >> 1); + h->current_mv_y = (motion_y >> 1); + h261_encode_motion(h,mv_diff_x); + h261_encode_motion(h,mv_diff_y); + } + + h->previous_mba = h->current_mba; + + if(HAS_CBP(h->mtype)){ + assert(cbp>0); + put_bits(&s->pb,h261_cbp_tab[cbp-1][1],h261_cbp_tab[cbp-1][0]); + } + for(i=0; i<6; i++) { + /* encode each block */ + h261_encode_block(h, block[i], i); + } + + if ( ( h->current_mba == 11 ) || ( h->current_mba == 22 ) || ( h->current_mba == 33 ) || ( !IS_16X16 ( h->mtype ) )){ + h->current_mv_x=0; + h->current_mv_y=0; + } +} + +void ff_h261_encode_init(MpegEncContext *s){ + static int done = 0; + + if (!done) { + done = 1; + init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store); + } + + s->min_qcoeff= -127; + s->max_qcoeff= 127; + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; +} + + +/** + * encodes a 8x8 block. + * @param block the 8x8 block + * @param n block index (0-3 are luma, 4-5 are chroma) + */ +static void h261_encode_block(H261Context * h, DCTELEM * block, int n){ + MpegEncContext * const s = &h->s; + int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code; + RLTable *rl; + + rl = &h261_rl_tcoeff; + if (s->mb_intra) { + /* DC coef */ + level = block[0]; + /* 255 cannot be represented, so we clamp */ + if (level > 254) { + level = 254; + block[0] = 254; + } + /* 0 cannot be represented also */ + else if (level < 1) { + level = 1; + block[0] = 1; + } + if (level == 128) + put_bits(&s->pb, 8, 0xff); + else + put_bits(&s->pb, 8, level); + i = 1; + } else if((block[0]==1 || block[0] == -1) && (s->block_last_index[n] > -1)){ + //special case + put_bits(&s->pb,2,block[0]>0 ? 2 : 3 ); + i = 1; + } else { + i = 0; + } + + /* AC coefs */ + last_index = s->block_last_index[n]; + last_non_zero = i - 1; + for (; i <= last_index; i++) { + j = s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + run = i - last_non_zero - 1; + last = (i == last_index); + sign = 0; + slevel = level; + if (level < 0) { + sign = 1; + level = -level; + } + code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, run, level); + if(run==0 && level < 16) + code+=1; + put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + if (code == rl->n) { + put_bits(&s->pb, 6, run); + assert(slevel != 0); + assert(level <= 127); + put_bits(&s->pb, 8, slevel & 0xff); + } else { + put_bits(&s->pb, 1, sign); + } + last_non_zero = i; + } + } + if(last_index > -1){ + put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]);// END OF BLOCK + } +} + +AVCodec h261_encoder = { + "h261", + CODEC_TYPE_VIDEO, + CODEC_ID_H261, + sizeof(H261Context), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; + diff --git a/contrib/ffmpeg/libavcodec/h263.c b/contrib/ffmpeg/libavcodec/h263.c index 4db89e970..6262c94da 100644 --- a/contrib/ffmpeg/libavcodec/h263.c +++ b/contrib/ffmpeg/libavcodec/h263.c @@ -5,6 +5,10 @@ * Copyright (c) 2001 Juan J. Sierralta P. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * + * ac prediction encoding, B-frame support, error resilience, optimizations, + * qpel decoding, gmc decoding, interlaced decoding + * by Michael Niedermayer <michaelni@gmx.at> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -20,10 +24,6 @@ * 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 - * - * ac prediction encoding, b-frame support, error resilience, optimizations, - * qpel decoding, gmc decoding, interlaced decoding, - * by Michael Niedermayer <michaelni@gmx.at> */ /** @@ -34,7 +34,6 @@ //#define DEBUG #include <limits.h> -#include "common.h" #include "dsputil.h" #include "avcodec.h" #include "mpegvideo.h" @@ -139,6 +138,23 @@ int h263_get_picture_format(int width, int height) return format; } +static void show_pict_info(MpegEncContext *s){ + av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s %d/%d\n", + s->qscale, av_get_pict_type_char(s->pict_type), + s->gb.size_in_bits, 1-s->no_rounding, + s->obmc ? " AP" : "", + s->umvplus ? " UMV" : "", + s->h263_long_vectors ? " LONG" : "", + s->h263_plus ? " +" : "", + s->h263_aic ? " AIC" : "", + s->alt_inter_vlc ? " AIV" : "", + s->modified_quant ? " MQ" : "", + s->loop_filter ? " LOOP" : "", + s->h263_slice_structured ? " SS" : "", + s->avctx->time_base.den, s->avctx->time_base.num + ); +} + #ifdef CONFIG_ENCODERS static void aspect_to_info(MpegEncContext * s, AVRational aspect){ @@ -213,7 +229,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) for(i=0; i<2; i++){ int div, error; div= (s->avctx->time_base.num*1800000LL + 500LL*s->avctx->time_base.den) / ((1000LL+i)*s->avctx->time_base.den); - div= av_clip(1, div, 127); + div= av_clip(div, 1, 127); error= FFABS(s->avctx->time_base.num*1800000LL - (1000LL+i)*s->avctx->time_base.den*div); if(error < best_error){ best_error= error; @@ -894,7 +910,7 @@ void mpeg4_encode_mb(MpegEncContext * s, int i, cbp; if(s->pict_type==B_TYPE){ - static const int mb_type_table[8]= {-1, 2, 3, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ + static const int mb_type_table[8]= {-1, 3, 2, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ int mb_type= mb_type_table[s->mv_dir]; if(s->mb_x==0){ @@ -1836,9 +1852,6 @@ static void init_mv_penalty_and_fcode(MpegEncContext *s) umv_fcode_tab[mv]= 1; } } -#endif - -#ifdef CONFIG_ENCODERS static void init_uni_dc_tab(void) { @@ -1892,9 +1905,6 @@ static void init_uni_dc_tab(void) } } -#endif //CONFIG_ENCODERS - -#ifdef CONFIG_ENCODERS static void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){ int slevel, run, last; @@ -2243,9 +2253,6 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) } } } -#endif - -#ifdef CONFIG_ENCODERS /***************************************************/ /** @@ -2260,25 +2267,12 @@ void ff_mpeg4_stuffing(PutBitContext * pbc) } /* must be called before writing the header */ -void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){ - int time_div, time_mod; - - assert(s->current_picture_ptr->pts != AV_NOPTS_VALUE); - s->time= s->current_picture_ptr->pts*s->avctx->time_base.num; - - time_div= s->time/s->avctx->time_base.den; - time_mod= s->time%s->avctx->time_base.den; - +void ff_set_mpeg4_time(MpegEncContext * s){ if(s->pict_type==B_TYPE){ - s->pb_time= s->pp_time - (s->last_non_b_time - s->time); - assert(s->pb_time > 0 && s->pb_time < s->pp_time); ff_mpeg4_init_direct_mv(s); }else{ s->last_time_base= s->time_base; - s->time_base= time_div; - s->pp_time= s->time - s->last_non_b_time; - s->last_non_b_time= s->time; - assert(picture_number==0 || s->pp_time > 0); + s->time_base= s->time/s->avctx->time_base.den; } } @@ -2361,6 +2355,8 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n { int vo_ver_id; + if (!ENABLE_MPEG4_ENCODER) return; + if(s->max_b_frames || s->quarter_sample){ vo_ver_id= 5; s->vo_type= ADV_SIMPLE_VO_TYPE; @@ -2518,23 +2514,6 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) #endif //CONFIG_ENCODERS /** - * set qscale and update qscale dependent variables. - */ -void ff_set_qscale(MpegEncContext * s, int qscale) -{ - if (qscale < 1) - qscale = 1; - else if (qscale > 31) - qscale = 31; - - s->qscale = qscale; - s->chroma_qscale= s->chroma_qscale_table[qscale]; - - s->y_dc_scale= s->y_dc_scale_table[ qscale ]; - s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ]; -} - -/** * predicts the dc. * encoding quantized level -> quantized diff * decoding quantized diff -> quantized level @@ -2918,59 +2897,6 @@ static VLC mb_type_b_vlc; static VLC h263_mbtype_b_vlc; static VLC cbpc_b_vlc; -void init_vlc_rl(RLTable *rl, int use_static) -{ - int i, q; - - /* Return if static table is already initialized */ - if(use_static && rl->rl_vlc[0]) - return; - - init_vlc(&rl->vlc, 9, rl->n + 1, - &rl->table_vlc[0][1], 4, 2, - &rl->table_vlc[0][0], 4, 2, use_static); - - - for(q=0; q<32; q++){ - int qmul= q*2; - int qadd= (q-1)|1; - - if(q==0){ - qmul=1; - qadd=0; - } - if(use_static) - rl->rl_vlc[q]= av_mallocz_static(rl->vlc.table_size*sizeof(RL_VLC_ELEM)); - else - rl->rl_vlc[q]= av_malloc(rl->vlc.table_size*sizeof(RL_VLC_ELEM)); - for(i=0; i<rl->vlc.table_size; i++){ - int code= rl->vlc.table[i][0]; - int len = rl->vlc.table[i][1]; - int level, run; - - if(len==0){ // illegal code - run= 66; - level= MAX_LEVEL; - }else if(len<0){ //more bits needed - run= 0; - level= code; - }else{ - if(code==rl->n){ //esc - run= 66; - level= 0; - }else{ - run= rl->table_run [code] + 1; - level= rl->table_level[code] * qmul + qadd; - if(code >= rl->last) run+=192; - } - } - rl->rl_vlc[q][i].len= len; - rl->rl_vlc[q][i].level= level; - rl->rl_vlc[q][i].run= run; - } - } -} - /* init vlcs */ /* XXX: find a better solution to handle static init */ @@ -3387,7 +3313,7 @@ int ff_h263_resync(MpegEncContext *s){ if(ret>=0) return 0; } - //ok, it's not where its supposed to be ... + //OK, it's not where it is supposed to be ... s->gb= s->last_resync_gb; align_get_bits(&s->gb); left= s->gb.size_in_bits - get_bits_count(&s->gb); @@ -4721,7 +4647,7 @@ retry: i += run; if (i >= 64){ if(s->alt_inter_vlc && rl == &rl_inter && !s->mb_intra){ - //looks like a hack but no, it's the way its supposed to work ... + //Looks like a hack but no, it's the way it is supposed to work ... rl = &rl_intra_aic; i = 0; s->gb= gb; @@ -4828,26 +4754,26 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, i = -1; ff_mpeg4_pred_dc(s, n, 0, &dc_pred_dir, 0); } - if (!coded) - goto not_coded; + if (!coded) + goto not_coded; - if(rvlc){ - rl = &rvlc_rl_intra; - rl_vlc = rvlc_rl_intra.rl_vlc[0]; - }else{ - rl = &rl_intra; - rl_vlc = rl_intra.rl_vlc[0]; - } - if (s->ac_pred) { - if (dc_pred_dir == 0) - scan_table = s->intra_v_scantable.permutated; /* left */ - else - scan_table = s->intra_h_scantable.permutated; /* top */ - } else { + if(rvlc){ + rl = &rvlc_rl_intra; + rl_vlc = rvlc_rl_intra.rl_vlc[0]; + }else{ + rl = &rl_intra; + rl_vlc = rl_intra.rl_vlc[0]; + } + if (s->ac_pred) { + if (dc_pred_dir == 0) + scan_table = s->intra_v_scantable.permutated; /* left */ + else + scan_table = s->intra_h_scantable.permutated; /* top */ + } else { scan_table = s->intra_scantable.permutated; - } - qmul=1; - qadd=0; + } + qmul=1; + qadd=0; } else { i = -1; if (!coded) { @@ -5142,7 +5068,7 @@ int h263_decode_picture_header(MpegEncContext *s) format = get_bits(&s->gb, 3); dprintf(s->avctx, "ufep=1, format: %d\n", format); s->custom_pcf= get_bits1(&s->gb); - s->umvplus = get_bits(&s->gb, 1); /* Unrestricted Motion Vector */ + s->umvplus = get_bits1(&s->gb); /* Unrestricted Motion Vector */ if (get_bits1(&s->gb) != 0) { av_log(s->avctx, AV_LOG_ERROR, "Syntax-based Arithmetic Coding (SAC) not supported\n"); } @@ -5294,20 +5220,7 @@ int h263_decode_picture_header(MpegEncContext *s) } if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s %d/%d\n", - s->qscale, av_get_pict_type_char(s->pict_type), - s->gb.size_in_bits, 1-s->no_rounding, - s->obmc ? " AP" : "", - s->umvplus ? " UMV" : "", - s->h263_long_vectors ? " LONG" : "", - s->h263_plus ? " +" : "", - s->h263_aic ? " AIC" : "", - s->alt_inter_vlc ? " AIV" : "", - s->modified_quant ? " MQ" : "", - s->loop_filter ? " LOOP" : "", - s->h263_slice_structured ? " SS" : "", - s->avctx->time_base.den, s->avctx->time_base.num - ); + show_pict_info(s); } #if 1 if (s->pict_type == I_TYPE && s->codec_tag == ff_get_fourcc("ZYGO")){ @@ -5665,6 +5578,11 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ skip_bits1(gb); /* marker */ } s->num_sprite_warping_points= get_bits(gb, 6); + if(s->num_sprite_warping_points > 3){ + av_log(s->avctx, AV_LOG_ERROR, "%d sprite_warping_points\n", s->num_sprite_warping_points); + s->num_sprite_warping_points= 0; + return -1; + } s->sprite_warping_accuracy = get_bits(gb, 2); s->sprite_brightness_change= get_bits1(gb); if(s->vol_sprite_usage==STATIC_SPRITE) @@ -6197,11 +6115,7 @@ int intel_h263_decode_picture_header(MpegEncContext *s) av_log(s->avctx, AV_LOG_ERROR, "SAC not supported\n"); return -1; /* SAC: off */ } - if (get_bits1(&s->gb) != 0) { - s->obmc= 1; - av_log(s->avctx, AV_LOG_ERROR, "Advanced Prediction Mode not supported\n"); -// return -1; /* advanced prediction mode: off */ - } + s->obmc= get_bits1(&s->gb); if (get_bits1(&s->gb) != 0) { av_log(s->avctx, AV_LOG_ERROR, "PB frame mode no supported\n"); return -1; /* PB frame mode */ @@ -6222,6 +6136,9 @@ int intel_h263_decode_picture_header(MpegEncContext *s) s->y_dc_scale_table= s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + if(s->avctx->debug&FF_DEBUG_PICT_INFO) + show_pict_info(s); + return 0; } diff --git a/contrib/ffmpeg/libavcodec/h263.h b/contrib/ffmpeg/libavcodec/h263.h new file mode 100644 index 000000000..47b168b54 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h263.h @@ -0,0 +1,46 @@ +/* + * H263/MPEG4 backend for ffmpeg encoder and decoder + * copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> + * + * 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 + */ + +#ifndef FFMPEG_H263_H +#define FFMPEG_H263_H + +#include "config.h" +#include "msmpeg4.h" + +#define ENABLE_ANY_H263_DECODER (ENABLE_H263_DECODER || \ + ENABLE_H263I_DECODER || \ + ENABLE_FLV_DECODER || \ + ENABLE_RV10_DECODER || \ + ENABLE_RV20_DECODER || \ + ENABLE_MPEG4_DECODER || \ + ENABLE_MSMPEG4_DECODER || \ + ENABLE_WMV_DECODER) +#define ENABLE_ANY_H263_ENCODER (ENABLE_H263_ENCODER || \ + ENABLE_H263P_ENCODER || \ + ENABLE_FLV_ENCODER || \ + ENABLE_RV10_ENCODER || \ + ENABLE_RV20_ENCODER || \ + ENABLE_MPEG4_ENCODER || \ + ENABLE_MSMPEG4_ENCODER || \ + ENABLE_WMV_ENCODER) +#define ENABLE_ANY_H263 (ENABLE_ANY_H263_DECODER || ENABLE_ANY_H263_ENCODER) + +#endif /* FFMPEG_H263_H */ diff --git a/contrib/ffmpeg/libavcodec/h263_parser.c b/contrib/ffmpeg/libavcodec/h263_parser.c new file mode 100644 index 000000000..bfef3b5bb --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h263_parser.c @@ -0,0 +1,91 @@ +/* + * H.263 parser + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 h263_parser.c + * H.263 parser + */ + +#include "parser.h" + +int ff_h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ + int vop_found, i; + uint32_t state; + + vop_found= pc->frame_start_found; + state= pc->state; + + i=0; + if(!vop_found){ + for(i=0; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if(state>>(32-22) == 0x20){ + i++; + vop_found=1; + break; + } + } + } + + if(vop_found){ + for(; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if(state>>(32-22) == 0x20){ + pc->frame_start_found=0; + pc->state=-1; + return i-3; + } + } + } + pc->frame_start_found= vop_found; + pc->state= state; + + return END_NOT_FOUND; +} + +static int h263_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + int next; + + next= ff_h263_find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser h263_parser = { + { CODEC_ID_H263 }, + sizeof(ParseContext), + NULL, + h263_parse, + ff_parse_close, +}; diff --git a/contrib/ffmpeg/libavcodec/h263_parser.h b/contrib/ffmpeg/libavcodec/h263_parser.h new file mode 100644 index 000000000..dc5077451 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h263_parser.h @@ -0,0 +1,29 @@ +/* + * H.263 parser + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 + */ + +#ifndef FFMPEG_H263_PARSER_H +#define FFMPEG_H263_PARSER_H + +#include "parser.h" + +int ff_h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size); + +#endif /* FFMPEG_H263_PARSER_H */ diff --git a/contrib/ffmpeg/libavcodec/h263data.h b/contrib/ffmpeg/libavcodec/h263data.h index 5eddc3b54..b6c1c163c 100644 --- a/contrib/ffmpeg/libavcodec/h263data.h +++ b/contrib/ffmpeg/libavcodec/h263data.h @@ -26,6 +26,11 @@ * H.263 tables. */ +#ifndef FFMPEG_H263DATA_H +#define FFMPEG_H263DATA_H + +#include <stdint.h> +#include "mpegvideo.h" /* intra MCBPC, mb_type = (intra), then (intraq) */ const uint8_t intra_MCBPC_code[9] = { 1, 1, 2, 3, 1, 1, 2, 3, 1 }; @@ -306,3 +311,4 @@ const uint8_t ff_h263_loop_filter_strength[32]={ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11,11,12,12,12 }; +#endif /* FFMPEG_H263DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/h263dec.c b/contrib/ffmpeg/libavcodec/h263dec.c index b385f84cd..eddaadc83 100644 --- a/contrib/ffmpeg/libavcodec/h263dec.c +++ b/contrib/ffmpeg/libavcodec/h263dec.c @@ -28,6 +28,9 @@ #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" +#include "h263_parser.h" +#include "mpeg4video_parser.h" +#include "msmpeg4.h" //#define DEBUG //#define PRINT_FRAME_TIME @@ -108,7 +111,7 @@ int ff_h263_decode_init(AVCodecContext *avctx) if (MPV_common_init(s) < 0) return -1; - if (s->h263_msmpeg4) + if (ENABLE_MSMPEG4_DECODER && s->h263_msmpeg4) ff_msmpeg4_decode_init(s); else h263_decode_init_vlc(s); @@ -138,7 +141,7 @@ static int get_consumed_bytes(MpegEncContext *s, int buf_size){ if(pos<0) pos=0; // padding is not really read so this might be -1 return pos; }else{ - if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) + if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...) if(pos+10>buf_size) pos=buf_size; // oops ;) return pos; @@ -317,108 +320,9 @@ static int decode_slice(MpegEncContext *s){ return -1; } -/** - * 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_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ - int vop_found, i; - uint32_t state; - - vop_found= pc->frame_start_found; - state= pc->state; - - i=0; - if(!vop_found){ - for(i=0; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if(state == 0x1B6){ - i++; - vop_found=1; - break; - } - } - } - - if(vop_found){ - /* EOF considered as end of frame */ - if (buf_size == 0) - return 0; - for(; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if((state&0xFFFFFF00) == 0x100){ - pc->frame_start_found=0; - pc->state=-1; - return i-3; - } - } - } - pc->frame_start_found= vop_found; - pc->state= state; - return END_NOT_FOUND; -} - -static int h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ - int vop_found, i; - uint32_t state; - - vop_found= pc->frame_start_found; - state= pc->state; - - i=0; - if(!vop_found){ - for(i=0; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if(state>>(32-22) == 0x20){ - i++; - vop_found=1; - break; - } - } - } - - if(vop_found){ - for(; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if(state>>(32-22) == 0x20){ - pc->frame_start_found=0; - pc->state=-1; - return i-3; - } - } - } - pc->frame_start_found= vop_found; - pc->state= state; - - return END_NOT_FOUND; -} - -#ifdef CONFIG_H263_PARSER -static int h263_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - next= h263_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - - *poutbuf = (uint8_t *)buf; - *poutbuf_size = buf_size; - return next; -} -#endif - int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { MpegEncContext *s = avctx->priv_data; int ret; @@ -454,13 +358,13 @@ uint64_t time= rdtsc(); if(s->codec_id==CODEC_ID_MPEG4){ next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size); }else if(s->codec_id==CODEC_ID_H263){ - next= h263_find_frame_end(&s->parse_context, buf, buf_size); + next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size); }else{ av_log(s->avctx, AV_LOG_ERROR, "this codec does not support truncated bitstreams\n"); return -1; } - if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 ) + if( ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 ) return buf_size; } @@ -478,16 +382,17 @@ retry: return -1; } - //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there + /* We need to set current_picture_ptr before reading the header, + * otherwise we cannot store anyting in there */ if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ int i= ff_find_unused_picture(s, 0); s->current_picture_ptr= &s->picture[i]; } /* let's go :-) */ - if (s->msmpeg4_version==5) { + if (ENABLE_WMV2_DECODER && s->msmpeg4_version==5) { ret= ff_wmv2_decode_picture_header(s); - } else if (s->msmpeg4_version) { + } else if (ENABLE_MSMPEG4_DECODER && s->msmpeg4_version) { ret = msmpeg4_decode_picture_header(s); } else if (s->h263_pred) { if(s->avctx->extradata_size && s->picture_number==0){ @@ -548,11 +453,11 @@ retry: s->workaround_bugs|= FF_BUG_UMP4; } - if(s->divx_version>=500){ + if(s->divx_version>=500 && s->divx_build<1814){ s->workaround_bugs|= FF_BUG_QPEL_CHROMA; } - if(s->divx_version>502){ + if(s->divx_version>502 && s->divx_build<1814){ s->workaround_bugs|= FF_BUG_QPEL_CHROMA2; } @@ -717,10 +622,11 @@ retry: ff_er_frame_start(s); //the second part of the wmv2 header contains the MB skip bits which are stored in current_picture->mb_type - //which isnt available before MPV_frame_start() - if (s->msmpeg4_version==5){ - if(ff_wmv2_decode_secondary_picture_header(s) < 0) - return -1; + //which is not available before MPV_frame_start() + if (ENABLE_WMV2_DECODER && s->msmpeg4_version==5){ + ret = ff_wmv2_decode_secondary_picture_header(s); + if(ret<0) return ret; + if(ret==1) goto intrax8_decoded; } /* decode each macroblock */ @@ -744,7 +650,7 @@ retry: } if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE) - if(msmpeg4_decode_ext_header(s, buf_size) < 0){ + if(!ENABLE_MSMPEG4_DECODER || msmpeg4_decode_ext_header(s, buf_size) < 0){ s->error_status_table[s->mb_num-1]= AC_ERROR|DC_ERROR|MV_ERROR; } @@ -777,6 +683,7 @@ retry: } } +intrax8_decoded: ff_er_frame_end(s); MPV_frame_end(s); @@ -795,7 +702,7 @@ assert(s->current_picture.pict_type == s->pict_type); } /* Return the Picture timestamp as the frame number */ - /* we substract 1 because it is added on utils.c */ + /* we subtract 1 because it is added on utils.c */ avctx->frame_number = s->picture_number - 1; #ifdef PRINT_FRAME_TIME @@ -902,13 +809,3 @@ AVCodec flv_decoder = { ff_h263_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 }; - -#ifdef CONFIG_H263_PARSER -AVCodecParser h263_parser = { - { CODEC_ID_H263 }, - sizeof(ParseContext), - NULL, - h263_parse, - ff_parse_close, -}; -#endif diff --git a/contrib/ffmpeg/libavcodec/h264.c b/contrib/ffmpeg/libavcodec/h264.c index 4d72dc2ff..cd6facb9b 100644 --- a/contrib/ffmpeg/libavcodec/h264.c +++ b/contrib/ffmpeg/libavcodec/h264.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -26,367 +25,25 @@ * @author Michael Niedermayer <michaelni@gmx.at> */ -#include "common.h" #include "dsputil.h" #include "avcodec.h" #include "mpegvideo.h" +#include "h264.h" #include "h264data.h" +#include "h264_parser.h" #include "golomb.h" +#include "rectangle.h" #include "cabac.h" //#undef NDEBUG #include <assert.h> -#define interlaced_dct interlaced_dct_is_a_bad_name -#define mb_intra mb_intra_isnt_initalized_see_mb_type - -#define LUMA_DC_BLOCK_INDEX 25 -#define CHROMA_DC_BLOCK_INDEX 26 - -#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8 -#define COEFF_TOKEN_VLC_BITS 8 -#define TOTAL_ZEROS_VLC_BITS 9 -#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3 -#define RUN_VLC_BITS 3 -#define RUN7_VLC_BITS 6 - -#define MAX_SPS_COUNT 32 -#define MAX_PPS_COUNT 256 - -#define MAX_MMCO_COUNT 66 - -/* Compiling in interlaced support reduces the speed - * of progressive decoding by about 2%. */ -#define ALLOW_INTERLACE - -#ifdef ALLOW_INTERLACE -#define MB_MBAFF h->mb_mbaff -#define MB_FIELD h->mb_field_decoding_flag -#define FRAME_MBAFF h->mb_aff_frame -#else -#define MB_MBAFF 0 -#define MB_FIELD 0 -#define FRAME_MBAFF 0 -#undef IS_INTERLACED -#define IS_INTERLACED(mb_type) 0 -#endif - -/** - * Sequence parameter set - */ -typedef struct SPS{ - - int profile_idc; - int level_idc; - int transform_bypass; ///< qpprime_y_zero_transform_bypass_flag - int log2_max_frame_num; ///< log2_max_frame_num_minus4 + 4 - int poc_type; ///< pic_order_cnt_type - int log2_max_poc_lsb; ///< log2_max_pic_order_cnt_lsb_minus4 - int delta_pic_order_always_zero_flag; - int offset_for_non_ref_pic; - int offset_for_top_to_bottom_field; - int poc_cycle_length; ///< num_ref_frames_in_pic_order_cnt_cycle - int ref_frame_count; ///< num_ref_frames - int gaps_in_frame_num_allowed_flag; - int mb_width; ///< frame_width_in_mbs_minus1 + 1 - int mb_height; ///< frame_height_in_mbs_minus1 + 1 - int frame_mbs_only_flag; - int mb_aff; ///<mb_adaptive_frame_field_flag - int direct_8x8_inference_flag; - int crop; ///< frame_cropping_flag - int crop_left; ///< frame_cropping_rect_left_offset - int crop_right; ///< frame_cropping_rect_right_offset - int crop_top; ///< frame_cropping_rect_top_offset - int crop_bottom; ///< frame_cropping_rect_bottom_offset - int vui_parameters_present_flag; - AVRational sar; - int timing_info_present_flag; - uint32_t num_units_in_tick; - uint32_t time_scale; - int fixed_frame_rate_flag; - short offset_for_ref_frame[256]; //FIXME dyn aloc? - int bitstream_restriction_flag; - int num_reorder_frames; - int scaling_matrix_present; - uint8_t scaling_matrix4[6][16]; - uint8_t scaling_matrix8[2][64]; -}SPS; - -/** - * Picture parameter set - */ -typedef struct PPS{ - unsigned int sps_id; - int cabac; ///< entropy_coding_mode_flag - int pic_order_present; ///< pic_order_present_flag - int slice_group_count; ///< num_slice_groups_minus1 + 1 - int mb_slice_group_map_type; - unsigned int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1 - int weighted_pred; ///< weighted_pred_flag - int weighted_bipred_idc; - int init_qp; ///< pic_init_qp_minus26 + 26 - int init_qs; ///< pic_init_qs_minus26 + 26 - int chroma_qp_index_offset; - int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag - int constrained_intra_pred; ///< constrained_intra_pred_flag - int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag - int transform_8x8_mode; ///< transform_8x8_mode_flag - uint8_t scaling_matrix4[6][16]; - uint8_t scaling_matrix8[2][64]; -}PPS; - -/** - * Memory management control operation opcode. - */ -typedef enum MMCOOpcode{ - MMCO_END=0, - MMCO_SHORT2UNUSED, - MMCO_LONG2UNUSED, - MMCO_SHORT2LONG, - MMCO_SET_MAX_LONG, - MMCO_RESET, - MMCO_LONG, -} MMCOOpcode; - -/** - * Memory management control operation. - */ -typedef struct MMCO{ - MMCOOpcode opcode; - int short_frame_num; - int long_index; -} MMCO; - /** - * H264Context + * Value of Picture.reference when Picture is not a reference picture, but + * is held for delayed output. */ -typedef struct H264Context{ - MpegEncContext s; - int nal_ref_idc; - int nal_unit_type; - uint8_t *rbsp_buffer; - unsigned int rbsp_buffer_size; - - /** - * Used to parse AVC variant of h264 - */ - int is_avc; ///< this flag is != 0 if codec is avc1 - int got_avcC; ///< flag used to parse avcC data only once - int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4) - - int chroma_qp; //QPc - - int prev_mb_skipped; - int next_mb_skipped; - - //prediction stuff - int chroma_pred_mode; - int intra16x16_pred_mode; - - int top_mb_xy; - int left_mb_xy[2]; - - int8_t intra4x4_pred_mode_cache[5*8]; - int8_t (*intra4x4_pred_mode)[8]; - void (*pred4x4 [9+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp? - void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride); - void (*pred8x8 [4+3])(uint8_t *src, int stride); - void (*pred16x16[4+3])(uint8_t *src, int stride); - unsigned int topleft_samples_available; - unsigned int top_samples_available; - unsigned int topright_samples_available; - unsigned int left_samples_available; - uint8_t (*top_borders[2])[16+2*8]; - uint8_t left_border[2*(17+2*9)]; - - /** - * non zero coeff count cache. - * is 64 if not available. - */ - DECLARE_ALIGNED_8(uint8_t, non_zero_count_cache[6*8]); - uint8_t (*non_zero_count)[16]; - - /** - * Motion vector cache. - */ - DECLARE_ALIGNED_8(int16_t, mv_cache[2][5*8][2]); - DECLARE_ALIGNED_8(int8_t, ref_cache[2][5*8]); -#define LIST_NOT_USED -1 //FIXME rename? -#define PART_NOT_AVAILABLE -2 - - /** - * is 1 if the specific list MV&references are set to 0,0,-2. - */ - int mv_cache_clean[2]; - - /** - * number of neighbors (top and/or left) that used 8x8 dct - */ - int neighbor_transform_size; - - /** - * block_offset[ 0..23] for frame macroblocks - * block_offset[24..47] for field macroblocks - */ - int block_offset[2*(16+8)]; - - uint32_t *mb2b_xy; //FIXME are these 4 a good idea? - uint32_t *mb2b8_xy; - int b_stride; //FIXME use s->b4_stride - int b8_stride; - - int mb_linesize; ///< may be equal to s->linesize or s->linesize*2, for mbaff - int mb_uvlinesize; - - int emu_edge_width; - int emu_edge_height; - - int halfpel_flag; - int thirdpel_flag; - - int unknown_svq3_flag; - int next_slice_index; - - SPS sps_buffer[MAX_SPS_COUNT]; - SPS sps; ///< current sps - - PPS pps_buffer[MAX_PPS_COUNT]; - /** - * current pps - */ - PPS pps; //FIXME move to Picture perhaps? (->no) do we need that? - - uint32_t dequant4_buffer[6][52][16]; - uint32_t dequant8_buffer[2][52][64]; - uint32_t (*dequant4_coeff[6])[16]; - uint32_t (*dequant8_coeff[2])[64]; - int dequant_coeff_pps; ///< reinit tables when pps changes - - int slice_num; - uint8_t *slice_table_base; - uint8_t *slice_table; ///< slice_table_base + 2*mb_stride + 1 - int slice_type; - int slice_type_fixed; - - //interlacing specific flags - int mb_aff_frame; - int mb_field_decoding_flag; - int mb_mbaff; ///< mb_aff_frame && mb_field_decoding_flag - - unsigned int sub_mb_type[4]; - - //POC stuff - int poc_lsb; - int poc_msb; - int delta_poc_bottom; - int delta_poc[2]; - int frame_num; - int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0 - int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0 - int frame_num_offset; ///< for POC type 2 - int prev_frame_num_offset; ///< for POC type 2 - int prev_frame_num; ///< frame_num of the last pic for POC type 1/2 - - /** - * frame_num for frames or 2*frame_num for field pics. - */ - int curr_pic_num; - - /** - * max_frame_num or 2*max_frame_num for field pics. - */ - int max_pic_num; - - //Weighted pred stuff - int use_weight; - int use_weight_chroma; - int luma_log2_weight_denom; - int chroma_log2_weight_denom; - int luma_weight[2][48]; - int luma_offset[2][48]; - int chroma_weight[2][48][2]; - int chroma_offset[2][48][2]; - int implicit_weight[48][48]; - - //deblock - int deblocking_filter; ///< disable_deblocking_filter_idc with 1<->0 - int slice_alpha_c0_offset; - int slice_beta_offset; - - int redundant_pic_count; - - int direct_spatial_mv_pred; - int dist_scale_factor[16]; - int dist_scale_factor_field[32]; - int map_col_to_list0[2][16]; - int map_col_to_list0_field[2][32]; - - /** - * num_ref_idx_l0/1_active_minus1 + 1 - */ - unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode - unsigned int list_count; - Picture *short_ref[32]; - Picture *long_ref[32]; - Picture default_ref_list[2][32]; - Picture ref_list[2][48]; ///< 0..15: frame refs, 16..47: mbaff field refs - Picture *delayed_pic[18]; //FIXME size? - Picture *delayed_output_pic; - - /** - * memory management control operations buffer. - */ - MMCO mmco[MAX_MMCO_COUNT]; - int mmco_index; - - int long_ref_count; ///< number of actual long term references - int short_ref_count; ///< number of actual short term references - - //data partitioning - GetBitContext intra_gb; - GetBitContext inter_gb; - GetBitContext *intra_gb_ptr; - GetBitContext *inter_gb_ptr; - - DECLARE_ALIGNED_8(DCTELEM, mb[16*24]); - DCTELEM mb_padding[256]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not to large or ensure that there is some unused stuff after mb - - /** - * Cabac - */ - CABACContext cabac; - uint8_t cabac_state[460]; - int cabac_init_idc; - - /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */ - uint16_t *cbp_table; - int cbp; - int top_cbp; - int left_cbp; - /* chroma_pred_mode for i4x4 or i16x16, else 0 */ - uint8_t *chroma_pred_mode_table; - int last_qscale_diff; - int16_t (*mvd_table[2])[2]; - DECLARE_ALIGNED_8(int16_t, mvd_cache[2][5*8][2]); - uint8_t *direct_table; - uint8_t direct_cache[5*8]; - - uint8_t zigzag_scan[16]; - uint8_t zigzag_scan8x8[64]; - uint8_t zigzag_scan8x8_cavlc[64]; - uint8_t field_scan[16]; - uint8_t field_scan8x8[64]; - uint8_t field_scan8x8_cavlc[64]; - const uint8_t *zigzag_scan_q0; - const uint8_t *zigzag_scan8x8_q0; - const uint8_t *zigzag_scan8x8_cavlc_q0; - const uint8_t *field_scan_q0; - const uint8_t *field_scan8x8_q0; - const uint8_t *field_scan8x8_cavlc_q0; - - int x264_build; -}H264Context; +#define DELAYED_PIC_REF 4 static VLC coeff_token_vlc[4]; static VLC chroma_dc_coeff_token_vlc; @@ -419,109 +76,23 @@ const uint8_t ff_div6[52]={ }; -/** - * fill a rectangle. - * @param h height of the rectangle, should be a constant - * @param w width of the rectangle, should be a constant - * @param size the size of val (1 or 4), should be a constant - */ -static av_always_inline void fill_rectangle(void *vp, int w, int h, int stride, uint32_t val, int size){ - uint8_t *p= (uint8_t*)vp; - assert(size==1 || size==4); - assert(w<=4); - - w *= size; - stride *= size; - - assert((((long)vp)&(FFMIN(w, STRIDE_ALIGN)-1)) == 0); - assert((stride&(w-1))==0); - if(w==2){ - const uint16_t v= size==4 ? val : val*0x0101; - *(uint16_t*)(p + 0*stride)= v; - if(h==1) return; - *(uint16_t*)(p + 1*stride)= v; - if(h==2) return; - *(uint16_t*)(p + 2*stride)= - *(uint16_t*)(p + 3*stride)= v; - }else if(w==4){ - const uint32_t v= size==4 ? val : val*0x01010101; - *(uint32_t*)(p + 0*stride)= v; - if(h==1) return; - *(uint32_t*)(p + 1*stride)= v; - if(h==2) return; - *(uint32_t*)(p + 2*stride)= - *(uint32_t*)(p + 3*stride)= v; - }else if(w==8){ - //gcc can't optimize 64bit math on x86_32 -#if defined(ARCH_X86_64) || (defined(MP_WORDSIZE) && MP_WORDSIZE >= 64) - const uint64_t v= val*0x0100000001ULL; - *(uint64_t*)(p + 0*stride)= v; - if(h==1) return; - *(uint64_t*)(p + 1*stride)= v; - if(h==2) return; - *(uint64_t*)(p + 2*stride)= - *(uint64_t*)(p + 3*stride)= v; - }else if(w==16){ - const uint64_t v= val*0x0100000001ULL; - *(uint64_t*)(p + 0+0*stride)= - *(uint64_t*)(p + 8+0*stride)= - *(uint64_t*)(p + 0+1*stride)= - *(uint64_t*)(p + 8+1*stride)= v; - if(h==2) return; - *(uint64_t*)(p + 0+2*stride)= - *(uint64_t*)(p + 8+2*stride)= - *(uint64_t*)(p + 0+3*stride)= - *(uint64_t*)(p + 8+3*stride)= v; -#else - *(uint32_t*)(p + 0+0*stride)= - *(uint32_t*)(p + 4+0*stride)= val; - if(h==1) return; - *(uint32_t*)(p + 0+1*stride)= - *(uint32_t*)(p + 4+1*stride)= val; - if(h==2) return; - *(uint32_t*)(p + 0+2*stride)= - *(uint32_t*)(p + 4+2*stride)= - *(uint32_t*)(p + 0+3*stride)= - *(uint32_t*)(p + 4+3*stride)= val; - }else if(w==16){ - *(uint32_t*)(p + 0+0*stride)= - *(uint32_t*)(p + 4+0*stride)= - *(uint32_t*)(p + 8+0*stride)= - *(uint32_t*)(p +12+0*stride)= - *(uint32_t*)(p + 0+1*stride)= - *(uint32_t*)(p + 4+1*stride)= - *(uint32_t*)(p + 8+1*stride)= - *(uint32_t*)(p +12+1*stride)= val; - if(h==2) return; - *(uint32_t*)(p + 0+2*stride)= - *(uint32_t*)(p + 4+2*stride)= - *(uint32_t*)(p + 8+2*stride)= - *(uint32_t*)(p +12+2*stride)= - *(uint32_t*)(p + 0+3*stride)= - *(uint32_t*)(p + 4+3*stride)= - *(uint32_t*)(p + 8+3*stride)= - *(uint32_t*)(p +12+3*stride)= val; -#endif - }else - assert(0); - assert(h==4); -} - static void fill_caches(H264Context *h, int mb_type, int for_deblock){ MpegEncContext * const s = &h->s; const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; int topleft_xy, top_xy, topright_xy, left_xy[2]; int topleft_type, top_type, topright_type, left_type[2]; int left_block[8]; + int topleft_partition= -1; int i; + top_xy = mb_xy - (s->mb_stride << FIELD_PICTURE); + //FIXME deblocking could skip the intra and nnz parts. - if(for_deblock && (h->slice_num == 1 || h->slice_table[mb_xy] == h->slice_table[mb_xy-s->mb_stride]) && !FRAME_MBAFF) + if(for_deblock && (h->slice_num == 1 || h->slice_table[mb_xy] == h->slice_table[top_xy]) && !FRAME_MBAFF) return; //wow what a mess, why didn't they simplify the interlacing&intra stuff, i can't imagine that these complex rules are worth it - top_xy = mb_xy - s->mb_stride; topleft_xy = top_xy - 1; topright_xy= top_xy + 1; left_xy[1] = left_xy[0] = mb_xy-1; @@ -556,6 +127,10 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){ : (!curr_mb_frame_flag && !topleft_mb_frame_flag) // top macroblock ) { topleft_xy -= s->mb_stride; + } else if(bottom && curr_mb_frame_flag && !left_mb_frame_flag) { + topleft_xy += s->mb_stride; + // take topleft mv from the middle of the mb, as opposed to all other modes which use the bottom-right partition + topleft_partition = 0; } if (bottom ? !curr_mb_frame_flag // bottom macroblock @@ -833,8 +408,8 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){ continue; if(USES_LIST(topleft_type, list)){ - const int b_xy = h->mb2b_xy[topleft_xy] + 3 + 3*h->b_stride; - const int b8_xy= h->mb2b8_xy[topleft_xy] + 1 + h->b8_stride; + const int b_xy = h->mb2b_xy[topleft_xy] + 3 + h->b_stride + (topleft_partition & 2*h->b_stride); + const int b8_xy= h->mb2b8_xy[topleft_xy] + 1 + (topleft_partition & h->b8_stride); *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy]; h->ref_cache[list][scan8[0] - 1 - 1*8]= s->current_picture.ref_index[list][b8_xy]; }else{ @@ -1131,7 +706,7 @@ static inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, int i, in #define SET_DIAG_MV(MV_OP, REF_OP, X4, Y4)\ const int x4 = X4, y4 = Y4;\ const int mb_type = mb_types[(x4>>2)+(y4>>2)*s->mb_stride];\ - if(!USES_LIST(mb_type,list) && !IS_8X8(mb_type))\ + if(!USES_LIST(mb_type,list))\ return LIST_NOT_USED;\ mv = s->current_picture_ptr->motion_val[list][x4 + y4*h->b_stride];\ h->mv_cache[list][scan8[0]-2][0] = mv[0];\ @@ -1152,7 +727,7 @@ static inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, int i, in && !IS_INTERLACED(mb_types[h->left_mb_xy[0]]) && i >= scan8[0]+8){ // leftshift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's ok. - SET_DIAG_MV(>>1, <<1, s->mb_x*4-1, (s->mb_y&~1)*4 - 1 + ((i-scan8[0])>>3)*2); + SET_DIAG_MV(/2, <<1, s->mb_x*4-1, (s->mb_y&~1)*4 - 1 + ((i-scan8[0])>>3)*2); } } #undef SET_DIAG_MV @@ -1447,14 +1022,76 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){ } if(ref[1] < 0){ - *mb_type &= ~MB_TYPE_P0L1; - sub_mb_type &= ~MB_TYPE_P0L1; + if(!is_b8x8) + *mb_type &= ~MB_TYPE_L1; + sub_mb_type &= ~MB_TYPE_L1; }else if(ref[0] < 0){ - *mb_type &= ~MB_TYPE_P0L0; - sub_mb_type &= ~MB_TYPE_P0L0; + if(!is_b8x8) + *mb_type &= ~MB_TYPE_L0; + sub_mb_type &= ~MB_TYPE_L0; } - if(IS_16X16(*mb_type)){ + if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col)){ + int pair_xy = s->mb_x + (s->mb_y&~1)*s->mb_stride; + int mb_types_col[2]; + int b8_stride = h->b8_stride; + int b4_stride = h->b_stride; + + *mb_type = (*mb_type & ~MB_TYPE_16x16) | MB_TYPE_8x8; + + if(IS_INTERLACED(*mb_type)){ + mb_types_col[0] = h->ref_list[1][0].mb_type[pair_xy]; + mb_types_col[1] = h->ref_list[1][0].mb_type[pair_xy+s->mb_stride]; + if(s->mb_y&1){ + l1ref0 -= 2*b8_stride; + l1ref1 -= 2*b8_stride; + l1mv0 -= 4*b4_stride; + l1mv1 -= 4*b4_stride; + } + b8_stride *= 3; + b4_stride *= 6; + }else{ + int cur_poc = s->current_picture_ptr->poc; + int *col_poc = h->ref_list[1]->field_poc; + int col_parity = FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc); + int dy = 2*col_parity - (s->mb_y&1); + mb_types_col[0] = + mb_types_col[1] = h->ref_list[1][0].mb_type[pair_xy + col_parity*s->mb_stride]; + l1ref0 += dy*b8_stride; + l1ref1 += dy*b8_stride; + l1mv0 += 2*dy*b4_stride; + l1mv1 += 2*dy*b4_stride; + b8_stride = 0; + } + + for(i8=0; i8<4; i8++){ + int x8 = i8&1; + int y8 = i8>>1; + int xy8 = x8+y8*b8_stride; + int xy4 = 3*x8+y8*b4_stride; + int a=0, b=0; + + if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) + continue; + h->sub_mb_type[i8] = sub_mb_type; + + fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1); + fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1); + if(!IS_INTRA(mb_types_col[y8]) + && ( (l1ref0[xy8] == 0 && FFABS(l1mv0[xy4][0]) <= 1 && FFABS(l1mv0[xy4][1]) <= 1) + || (l1ref0[xy8] < 0 && l1ref1[xy8] == 0 && FFABS(l1mv1[xy4][0]) <= 1 && FFABS(l1mv1[xy4][1]) <= 1))){ + if(ref[0] > 0) + a= pack16to32(mv[0][0],mv[0][1]); + if(ref[1] > 0) + b= pack16to32(mv[1][0],mv[1][1]); + }else{ + a= pack16to32(mv[0][0],mv[0][1]); + b= pack16to32(mv[1][0],mv[1][1]); + } + fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, a, 4); + fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, b, 4); + } + }else if(IS_16X16(*mb_type)){ int a=0, b=0; fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1); @@ -1738,9 +1375,10 @@ static inline void write_back_motion(H264Context *h, int mb_type){ * @param dst_length is the number of decoded bytes FIXME here or a decode rbsp tailing? * @returns decoded bytes, might be src+1 if no escapes */ -static uint8_t *decode_nal(H264Context *h, uint8_t *src, int *dst_length, int *consumed, int length){ +static const uint8_t *decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){ int i, si, di; uint8_t *dst; + int bufidx; // src[0]&0x80; //forbidden bit h->nal_ref_idc= src[0]>>5; @@ -1769,8 +1407,9 @@ static uint8_t *decode_nal(H264Context *h, uint8_t *src, int *dst_length, int *c return src; } - h->rbsp_buffer= av_fast_realloc(h->rbsp_buffer, &h->rbsp_buffer_size, length); - dst= h->rbsp_buffer; + bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0; // use second escape buffer for inter data + h->rbsp_buffer[bufidx]= av_fast_realloc(h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length); + dst= h->rbsp_buffer[bufidx]; if (dst == NULL){ return NULL; @@ -1795,7 +1434,7 @@ static uint8_t *decode_nal(H264Context *h, uint8_t *src, int *dst_length, int *c *dst_length= di; *consumed= si + 1;//+1 for the header -//FIXME store exact number of bits in the getbitcontext (its needed for decoding) +//FIXME store exact number of bits in the getbitcontext (it is needed for decoding) return dst; } @@ -1803,7 +1442,7 @@ static uint8_t *decode_nal(H264Context *h, uint8_t *src, int *dst_length, int *c * identifies the exact end of the bitstream * @return the length of the trailing, or 0 if damaged */ -static int decode_rbsp_trailing(H264Context *h, uint8_t *src){ +static int decode_rbsp_trailing(H264Context *h, const uint8_t *src){ int v= *src; int r; @@ -1946,12 +1585,11 @@ static void chroma_dc_dct_c(DCTELEM *block){ /** * gets the chroma qp. */ -static inline int get_chroma_qp(int chroma_qp_index_offset, int qscale){ - - return chroma_qp[av_clip(qscale + chroma_qp_index_offset, 0, 51)]; +static inline int get_chroma_qp(H264Context *h, int t, int qscale){ + return h->pps.chroma_qp_table[t][qscale & 0xff]; } -//FIXME need to check that this doesnt overflow signed 32 bit for low qp, i am not sure, it's very close +//FIXME need to check that this does not overflow signed 32 bit for low qp, i am not sure, it's very close //FIXME check that gcc inlines this (and optimizes intra & separate_dc stuff away) static inline int quantize_c(DCTELEM *block, uint8_t *scantable, int qscale, int intra, int separate_dc){ int i; @@ -2030,722 +1668,6 @@ static inline int quantize_c(DCTELEM *block, uint8_t *scantable, int qscale, int return last_non_zero; } -static void pred4x4_vertical_c(uint8_t *src, uint8_t *topright, int stride){ - const uint32_t a= ((uint32_t*)(src-stride))[0]; - ((uint32_t*)(src+0*stride))[0]= a; - ((uint32_t*)(src+1*stride))[0]= a; - ((uint32_t*)(src+2*stride))[0]= a; - ((uint32_t*)(src+3*stride))[0]= a; -} - -static void pred4x4_horizontal_c(uint8_t *src, uint8_t *topright, int stride){ - ((uint32_t*)(src+0*stride))[0]= src[-1+0*stride]*0x01010101; - ((uint32_t*)(src+1*stride))[0]= src[-1+1*stride]*0x01010101; - ((uint32_t*)(src+2*stride))[0]= src[-1+2*stride]*0x01010101; - ((uint32_t*)(src+3*stride))[0]= src[-1+3*stride]*0x01010101; -} - -static void pred4x4_dc_c(uint8_t *src, uint8_t *topright, int stride){ - const int dc= ( src[-stride] + src[1-stride] + src[2-stride] + src[3-stride] - + src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 4) >>3; - - ((uint32_t*)(src+0*stride))[0]= - ((uint32_t*)(src+1*stride))[0]= - ((uint32_t*)(src+2*stride))[0]= - ((uint32_t*)(src+3*stride))[0]= dc* 0x01010101; -} - -static void pred4x4_left_dc_c(uint8_t *src, uint8_t *topright, int stride){ - const int dc= ( src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 2) >>2; - - ((uint32_t*)(src+0*stride))[0]= - ((uint32_t*)(src+1*stride))[0]= - ((uint32_t*)(src+2*stride))[0]= - ((uint32_t*)(src+3*stride))[0]= dc* 0x01010101; -} - -static void pred4x4_top_dc_c(uint8_t *src, uint8_t *topright, int stride){ - const int dc= ( src[-stride] + src[1-stride] + src[2-stride] + src[3-stride] + 2) >>2; - - ((uint32_t*)(src+0*stride))[0]= - ((uint32_t*)(src+1*stride))[0]= - ((uint32_t*)(src+2*stride))[0]= - ((uint32_t*)(src+3*stride))[0]= dc* 0x01010101; -} - -static void pred4x4_128_dc_c(uint8_t *src, uint8_t *topright, int stride){ - ((uint32_t*)(src+0*stride))[0]= - ((uint32_t*)(src+1*stride))[0]= - ((uint32_t*)(src+2*stride))[0]= - ((uint32_t*)(src+3*stride))[0]= 128U*0x01010101U; -} - - -#define LOAD_TOP_RIGHT_EDGE\ - const int t4= topright[0];\ - const int t5= topright[1];\ - const int t6= topright[2];\ - const int t7= topright[3];\ - -#define LOAD_LEFT_EDGE\ - const int l0= src[-1+0*stride];\ - const int l1= src[-1+1*stride];\ - const int l2= src[-1+2*stride];\ - const int l3= src[-1+3*stride];\ - -#define LOAD_TOP_EDGE\ - const int t0= src[ 0-1*stride];\ - const int t1= src[ 1-1*stride];\ - const int t2= src[ 2-1*stride];\ - const int t3= src[ 3-1*stride];\ - -static void pred4x4_down_right_c(uint8_t *src, uint8_t *topright, int stride){ - const int lt= src[-1-1*stride]; - LOAD_TOP_EDGE - LOAD_LEFT_EDGE - - src[0+3*stride]=(l3 + 2*l2 + l1 + 2)>>2; - src[0+2*stride]= - src[1+3*stride]=(l2 + 2*l1 + l0 + 2)>>2; - src[0+1*stride]= - src[1+2*stride]= - src[2+3*stride]=(l1 + 2*l0 + lt + 2)>>2; - src[0+0*stride]= - src[1+1*stride]= - src[2+2*stride]= - src[3+3*stride]=(l0 + 2*lt + t0 + 2)>>2; - src[1+0*stride]= - src[2+1*stride]= - src[3+2*stride]=(lt + 2*t0 + t1 + 2)>>2; - src[2+0*stride]= - src[3+1*stride]=(t0 + 2*t1 + t2 + 2)>>2; - src[3+0*stride]=(t1 + 2*t2 + t3 + 2)>>2; -} - -static void pred4x4_down_left_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_TOP_EDGE - LOAD_TOP_RIGHT_EDGE -// LOAD_LEFT_EDGE - - src[0+0*stride]=(t0 + t2 + 2*t1 + 2)>>2; - src[1+0*stride]= - src[0+1*stride]=(t1 + t3 + 2*t2 + 2)>>2; - src[2+0*stride]= - src[1+1*stride]= - src[0+2*stride]=(t2 + t4 + 2*t3 + 2)>>2; - src[3+0*stride]= - src[2+1*stride]= - src[1+2*stride]= - src[0+3*stride]=(t3 + t5 + 2*t4 + 2)>>2; - src[3+1*stride]= - src[2+2*stride]= - src[1+3*stride]=(t4 + t6 + 2*t5 + 2)>>2; - src[3+2*stride]= - src[2+3*stride]=(t5 + t7 + 2*t6 + 2)>>2; - src[3+3*stride]=(t6 + 3*t7 + 2)>>2; -} - -static void pred4x4_vertical_right_c(uint8_t *src, uint8_t *topright, int stride){ - const int lt= src[-1-1*stride]; - LOAD_TOP_EDGE - LOAD_LEFT_EDGE - const __attribute__((unused)) int unu= l3; - - src[0+0*stride]= - src[1+2*stride]=(lt + t0 + 1)>>1; - src[1+0*stride]= - src[2+2*stride]=(t0 + t1 + 1)>>1; - src[2+0*stride]= - src[3+2*stride]=(t1 + t2 + 1)>>1; - src[3+0*stride]=(t2 + t3 + 1)>>1; - src[0+1*stride]= - src[1+3*stride]=(l0 + 2*lt + t0 + 2)>>2; - src[1+1*stride]= - src[2+3*stride]=(lt + 2*t0 + t1 + 2)>>2; - src[2+1*stride]= - src[3+3*stride]=(t0 + 2*t1 + t2 + 2)>>2; - src[3+1*stride]=(t1 + 2*t2 + t3 + 2)>>2; - src[0+2*stride]=(lt + 2*l0 + l1 + 2)>>2; - src[0+3*stride]=(l0 + 2*l1 + l2 + 2)>>2; -} - -static void pred4x4_vertical_left_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_TOP_EDGE - LOAD_TOP_RIGHT_EDGE - const __attribute__((unused)) int unu= t7; - - src[0+0*stride]=(t0 + t1 + 1)>>1; - src[1+0*stride]= - src[0+2*stride]=(t1 + t2 + 1)>>1; - src[2+0*stride]= - src[1+2*stride]=(t2 + t3 + 1)>>1; - src[3+0*stride]= - src[2+2*stride]=(t3 + t4+ 1)>>1; - src[3+2*stride]=(t4 + t5+ 1)>>1; - src[0+1*stride]=(t0 + 2*t1 + t2 + 2)>>2; - src[1+1*stride]= - src[0+3*stride]=(t1 + 2*t2 + t3 + 2)>>2; - src[2+1*stride]= - src[1+3*stride]=(t2 + 2*t3 + t4 + 2)>>2; - src[3+1*stride]= - src[2+3*stride]=(t3 + 2*t4 + t5 + 2)>>2; - src[3+3*stride]=(t4 + 2*t5 + t6 + 2)>>2; -} - -static void pred4x4_horizontal_up_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_LEFT_EDGE - - src[0+0*stride]=(l0 + l1 + 1)>>1; - src[1+0*stride]=(l0 + 2*l1 + l2 + 2)>>2; - src[2+0*stride]= - src[0+1*stride]=(l1 + l2 + 1)>>1; - src[3+0*stride]= - src[1+1*stride]=(l1 + 2*l2 + l3 + 2)>>2; - src[2+1*stride]= - src[0+2*stride]=(l2 + l3 + 1)>>1; - src[3+1*stride]= - src[1+2*stride]=(l2 + 2*l3 + l3 + 2)>>2; - src[3+2*stride]= - src[1+3*stride]= - src[0+3*stride]= - src[2+2*stride]= - src[2+3*stride]= - src[3+3*stride]=l3; -} - -static void pred4x4_horizontal_down_c(uint8_t *src, uint8_t *topright, int stride){ - const int lt= src[-1-1*stride]; - LOAD_TOP_EDGE - LOAD_LEFT_EDGE - const __attribute__((unused)) int unu= t3; - - src[0+0*stride]= - src[2+1*stride]=(lt + l0 + 1)>>1; - src[1+0*stride]= - src[3+1*stride]=(l0 + 2*lt + t0 + 2)>>2; - src[2+0*stride]=(lt + 2*t0 + t1 + 2)>>2; - src[3+0*stride]=(t0 + 2*t1 + t2 + 2)>>2; - src[0+1*stride]= - src[2+2*stride]=(l0 + l1 + 1)>>1; - src[1+1*stride]= - src[3+2*stride]=(lt + 2*l0 + l1 + 2)>>2; - src[0+2*stride]= - src[2+3*stride]=(l1 + l2+ 1)>>1; - src[1+2*stride]= - src[3+3*stride]=(l0 + 2*l1 + l2 + 2)>>2; - src[0+3*stride]=(l2 + l3 + 1)>>1; - src[1+3*stride]=(l1 + 2*l2 + l3 + 2)>>2; -} - -void ff_pred16x16_vertical_c(uint8_t *src, int stride){ - int i; - const uint32_t a= ((uint32_t*)(src-stride))[0]; - const uint32_t b= ((uint32_t*)(src-stride))[1]; - const uint32_t c= ((uint32_t*)(src-stride))[2]; - const uint32_t d= ((uint32_t*)(src-stride))[3]; - - for(i=0; i<16; i++){ - ((uint32_t*)(src+i*stride))[0]= a; - ((uint32_t*)(src+i*stride))[1]= b; - ((uint32_t*)(src+i*stride))[2]= c; - ((uint32_t*)(src+i*stride))[3]= d; - } -} - -void ff_pred16x16_horizontal_c(uint8_t *src, int stride){ - int i; - - for(i=0; i<16; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= - ((uint32_t*)(src+i*stride))[2]= - ((uint32_t*)(src+i*stride))[3]= src[-1+i*stride]*0x01010101; - } -} - -void ff_pred16x16_dc_c(uint8_t *src, int stride){ - int i, dc=0; - - for(i=0;i<16; i++){ - dc+= src[-1+i*stride]; - } - - for(i=0;i<16; i++){ - dc+= src[i-stride]; - } - - dc= 0x01010101*((dc + 16)>>5); - - for(i=0; i<16; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= - ((uint32_t*)(src+i*stride))[2]= - ((uint32_t*)(src+i*stride))[3]= dc; - } -} - -static void pred16x16_left_dc_c(uint8_t *src, int stride){ - int i, dc=0; - - for(i=0;i<16; i++){ - dc+= src[-1+i*stride]; - } - - dc= 0x01010101*((dc + 8)>>4); - - for(i=0; i<16; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= - ((uint32_t*)(src+i*stride))[2]= - ((uint32_t*)(src+i*stride))[3]= dc; - } -} - -static void pred16x16_top_dc_c(uint8_t *src, int stride){ - int i, dc=0; - - for(i=0;i<16; i++){ - dc+= src[i-stride]; - } - dc= 0x01010101*((dc + 8)>>4); - - for(i=0; i<16; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= - ((uint32_t*)(src+i*stride))[2]= - ((uint32_t*)(src+i*stride))[3]= dc; - } -} - -void ff_pred16x16_128_dc_c(uint8_t *src, int stride){ - int i; - - for(i=0; i<16; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= - ((uint32_t*)(src+i*stride))[2]= - ((uint32_t*)(src+i*stride))[3]= 0x01010101U*128U; - } -} - -static inline void pred16x16_plane_compat_c(uint8_t *src, int stride, const int svq3){ - int i, j, k; - int a; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - const uint8_t * const src0 = src+7-stride; - const uint8_t *src1 = src+8*stride-1; - const uint8_t *src2 = src1-2*stride; // == src+6*stride-1; - int H = src0[1] - src0[-1]; - int V = src1[0] - src2[ 0]; - for(k=2; k<=8; ++k) { - src1 += stride; src2 -= stride; - H += k*(src0[k] - src0[-k]); - V += k*(src1[0] - src2[ 0]); - } - if(svq3){ - H = ( 5*(H/4) ) / 16; - V = ( 5*(V/4) ) / 16; - - /* required for 100% accuracy */ - i = H; H = V; V = i; - }else{ - H = ( 5*H+32 ) >> 6; - V = ( 5*V+32 ) >> 6; - } - - a = 16*(src1[0] + src2[16] + 1) - 7*(V+H); - for(j=16; j>0; --j) { - int b = a; - a += V; - for(i=-16; i<0; i+=4) { - src[16+i] = cm[ (b ) >> 5 ]; - src[17+i] = cm[ (b+ H) >> 5 ]; - src[18+i] = cm[ (b+2*H) >> 5 ]; - src[19+i] = cm[ (b+3*H) >> 5 ]; - b += 4*H; - } - src += stride; - } -} - -void ff_pred16x16_plane_c(uint8_t *src, int stride){ - pred16x16_plane_compat_c(src, stride, 0); -} - -void ff_pred8x8_vertical_c(uint8_t *src, int stride){ - int i; - const uint32_t a= ((uint32_t*)(src-stride))[0]; - const uint32_t b= ((uint32_t*)(src-stride))[1]; - - for(i=0; i<8; i++){ - ((uint32_t*)(src+i*stride))[0]= a; - ((uint32_t*)(src+i*stride))[1]= b; - } -} - -void ff_pred8x8_horizontal_c(uint8_t *src, int stride){ - int i; - - for(i=0; i<8; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= src[-1+i*stride]*0x01010101; - } -} - -void ff_pred8x8_128_dc_c(uint8_t *src, int stride){ - int i; - - for(i=0; i<8; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= 0x01010101U*128U; - } -} - -static void pred8x8_left_dc_c(uint8_t *src, int stride){ - int i; - int dc0, dc2; - - dc0=dc2=0; - for(i=0;i<4; i++){ - dc0+= src[-1+i*stride]; - dc2+= src[-1+(i+4)*stride]; - } - dc0= 0x01010101*((dc0 + 2)>>2); - dc2= 0x01010101*((dc2 + 2)>>2); - - for(i=0; i<4; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= dc0; - } - for(i=4; i<8; i++){ - ((uint32_t*)(src+i*stride))[0]= - ((uint32_t*)(src+i*stride))[1]= dc2; - } -} - -static void pred8x8_top_dc_c(uint8_t *src, int stride){ - int i; - int dc0, dc1; - - dc0=dc1=0; - for(i=0;i<4; i++){ - dc0+= src[i-stride]; - dc1+= src[4+i-stride]; - } - dc0= 0x01010101*((dc0 + 2)>>2); - dc1= 0x01010101*((dc1 + 2)>>2); - - for(i=0; i<4; i++){ - ((uint32_t*)(src+i*stride))[0]= dc0; - ((uint32_t*)(src+i*stride))[1]= dc1; - } - for(i=4; i<8; i++){ - ((uint32_t*)(src+i*stride))[0]= dc0; - ((uint32_t*)(src+i*stride))[1]= dc1; - } -} - - -void ff_pred8x8_dc_c(uint8_t *src, int stride){ - int i; - int dc0, dc1, dc2, dc3; - - dc0=dc1=dc2=0; - for(i=0;i<4; i++){ - dc0+= src[-1+i*stride] + src[i-stride]; - dc1+= src[4+i-stride]; - dc2+= src[-1+(i+4)*stride]; - } - dc3= 0x01010101*((dc1 + dc2 + 4)>>3); - dc0= 0x01010101*((dc0 + 4)>>3); - dc1= 0x01010101*((dc1 + 2)>>2); - dc2= 0x01010101*((dc2 + 2)>>2); - - for(i=0; i<4; i++){ - ((uint32_t*)(src+i*stride))[0]= dc0; - ((uint32_t*)(src+i*stride))[1]= dc1; - } - for(i=4; i<8; i++){ - ((uint32_t*)(src+i*stride))[0]= dc2; - ((uint32_t*)(src+i*stride))[1]= dc3; - } -} - -void ff_pred8x8_plane_c(uint8_t *src, int stride){ - int j, k; - int a; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - const uint8_t * const src0 = src+3-stride; - const uint8_t *src1 = src+4*stride-1; - const uint8_t *src2 = src1-2*stride; // == src+2*stride-1; - int H = src0[1] - src0[-1]; - int V = src1[0] - src2[ 0]; - for(k=2; k<=4; ++k) { - src1 += stride; src2 -= stride; - H += k*(src0[k] - src0[-k]); - V += k*(src1[0] - src2[ 0]); - } - H = ( 17*H+16 ) >> 5; - V = ( 17*V+16 ) >> 5; - - a = 16*(src1[0] + src2[8]+1) - 3*(V+H); - for(j=8; j>0; --j) { - int b = a; - a += V; - src[0] = cm[ (b ) >> 5 ]; - src[1] = cm[ (b+ H) >> 5 ]; - src[2] = cm[ (b+2*H) >> 5 ]; - src[3] = cm[ (b+3*H) >> 5 ]; - src[4] = cm[ (b+4*H) >> 5 ]; - src[5] = cm[ (b+5*H) >> 5 ]; - src[6] = cm[ (b+6*H) >> 5 ]; - src[7] = cm[ (b+7*H) >> 5 ]; - src += stride; - } -} - -#define SRC(x,y) src[(x)+(y)*stride] -#define PL(y) \ - const int l##y = (SRC(-1,y-1) + 2*SRC(-1,y) + SRC(-1,y+1) + 2) >> 2; -#define PREDICT_8x8_LOAD_LEFT \ - const int l0 = ((has_topleft ? SRC(-1,-1) : SRC(-1,0)) \ - + 2*SRC(-1,0) + SRC(-1,1) + 2) >> 2; \ - PL(1) PL(2) PL(3) PL(4) PL(5) PL(6) \ - const int l7 attribute_unused = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2 - -#define PT(x) \ - const int t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2; -#define PREDICT_8x8_LOAD_TOP \ - const int t0 = ((has_topleft ? SRC(-1,-1) : SRC(0,-1)) \ - + 2*SRC(0,-1) + SRC(1,-1) + 2) >> 2; \ - PT(1) PT(2) PT(3) PT(4) PT(5) PT(6) \ - const int t7 attribute_unused = ((has_topright ? SRC(8,-1) : SRC(7,-1)) \ - + 2*SRC(7,-1) + SRC(6,-1) + 2) >> 2 - -#define PTR(x) \ - t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2; -#define PREDICT_8x8_LOAD_TOPRIGHT \ - int t8, t9, t10, t11, t12, t13, t14, t15; \ - if(has_topright) { \ - PTR(8) PTR(9) PTR(10) PTR(11) PTR(12) PTR(13) PTR(14) \ - t15 = (SRC(14,-1) + 3*SRC(15,-1) + 2) >> 2; \ - } else t8=t9=t10=t11=t12=t13=t14=t15= SRC(7,-1); - -#define PREDICT_8x8_LOAD_TOPLEFT \ - const int lt = (SRC(-1,0) + 2*SRC(-1,-1) + SRC(0,-1) + 2) >> 2 - -#define PREDICT_8x8_DC(v) \ - int y; \ - for( y = 0; y < 8; y++ ) { \ - ((uint32_t*)src)[0] = \ - ((uint32_t*)src)[1] = v; \ - src += stride; \ - } - -static void pred8x8l_128_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_DC(0x80808080); -} -static void pred8x8l_left_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_LEFT; - const uint32_t dc = ((l0+l1+l2+l3+l4+l5+l6+l7+4) >> 3) * 0x01010101; - PREDICT_8x8_DC(dc); -} -static void pred8x8l_top_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_TOP; - const uint32_t dc = ((t0+t1+t2+t3+t4+t5+t6+t7+4) >> 3) * 0x01010101; - PREDICT_8x8_DC(dc); -} -static void pred8x8l_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_LEFT; - PREDICT_8x8_LOAD_TOP; - const uint32_t dc = ((l0+l1+l2+l3+l4+l5+l6+l7 - +t0+t1+t2+t3+t4+t5+t6+t7+8) >> 4) * 0x01010101; - PREDICT_8x8_DC(dc); -} -static void pred8x8l_horizontal_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_LEFT; -#define ROW(y) ((uint32_t*)(src+y*stride))[0] =\ - ((uint32_t*)(src+y*stride))[1] = 0x01010101 * l##y - ROW(0); ROW(1); ROW(2); ROW(3); ROW(4); ROW(5); ROW(6); ROW(7); -#undef ROW -} -static void pred8x8l_vertical_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - int y; - PREDICT_8x8_LOAD_TOP; - src[0] = t0; - src[1] = t1; - src[2] = t2; - src[3] = t3; - src[4] = t4; - src[5] = t5; - src[6] = t6; - src[7] = t7; - for( y = 1; y < 8; y++ ) - *(uint64_t*)(src+y*stride) = *(uint64_t*)src; -} -static void pred8x8l_down_left_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_TOP; - PREDICT_8x8_LOAD_TOPRIGHT; - SRC(0,0)= (t0 + 2*t1 + t2 + 2) >> 2; - SRC(0,1)=SRC(1,0)= (t1 + 2*t2 + t3 + 2) >> 2; - SRC(0,2)=SRC(1,1)=SRC(2,0)= (t2 + 2*t3 + t4 + 2) >> 2; - SRC(0,3)=SRC(1,2)=SRC(2,1)=SRC(3,0)= (t3 + 2*t4 + t5 + 2) >> 2; - SRC(0,4)=SRC(1,3)=SRC(2,2)=SRC(3,1)=SRC(4,0)= (t4 + 2*t5 + t6 + 2) >> 2; - SRC(0,5)=SRC(1,4)=SRC(2,3)=SRC(3,2)=SRC(4,1)=SRC(5,0)= (t5 + 2*t6 + t7 + 2) >> 2; - SRC(0,6)=SRC(1,5)=SRC(2,4)=SRC(3,3)=SRC(4,2)=SRC(5,1)=SRC(6,0)= (t6 + 2*t7 + t8 + 2) >> 2; - SRC(0,7)=SRC(1,6)=SRC(2,5)=SRC(3,4)=SRC(4,3)=SRC(5,2)=SRC(6,1)=SRC(7,0)= (t7 + 2*t8 + t9 + 2) >> 2; - SRC(1,7)=SRC(2,6)=SRC(3,5)=SRC(4,4)=SRC(5,3)=SRC(6,2)=SRC(7,1)= (t8 + 2*t9 + t10 + 2) >> 2; - SRC(2,7)=SRC(3,6)=SRC(4,5)=SRC(5,4)=SRC(6,3)=SRC(7,2)= (t9 + 2*t10 + t11 + 2) >> 2; - SRC(3,7)=SRC(4,6)=SRC(5,5)=SRC(6,4)=SRC(7,3)= (t10 + 2*t11 + t12 + 2) >> 2; - SRC(4,7)=SRC(5,6)=SRC(6,5)=SRC(7,4)= (t11 + 2*t12 + t13 + 2) >> 2; - SRC(5,7)=SRC(6,6)=SRC(7,5)= (t12 + 2*t13 + t14 + 2) >> 2; - SRC(6,7)=SRC(7,6)= (t13 + 2*t14 + t15 + 2) >> 2; - SRC(7,7)= (t14 + 3*t15 + 2) >> 2; -} -static void pred8x8l_down_right_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_TOP; - PREDICT_8x8_LOAD_LEFT; - PREDICT_8x8_LOAD_TOPLEFT; - SRC(0,7)= (l7 + 2*l6 + l5 + 2) >> 2; - SRC(0,6)=SRC(1,7)= (l6 + 2*l5 + l4 + 2) >> 2; - SRC(0,5)=SRC(1,6)=SRC(2,7)= (l5 + 2*l4 + l3 + 2) >> 2; - SRC(0,4)=SRC(1,5)=SRC(2,6)=SRC(3,7)= (l4 + 2*l3 + l2 + 2) >> 2; - SRC(0,3)=SRC(1,4)=SRC(2,5)=SRC(3,6)=SRC(4,7)= (l3 + 2*l2 + l1 + 2) >> 2; - SRC(0,2)=SRC(1,3)=SRC(2,4)=SRC(3,5)=SRC(4,6)=SRC(5,7)= (l2 + 2*l1 + l0 + 2) >> 2; - SRC(0,1)=SRC(1,2)=SRC(2,3)=SRC(3,4)=SRC(4,5)=SRC(5,6)=SRC(6,7)= (l1 + 2*l0 + lt + 2) >> 2; - SRC(0,0)=SRC(1,1)=SRC(2,2)=SRC(3,3)=SRC(4,4)=SRC(5,5)=SRC(6,6)=SRC(7,7)= (l0 + 2*lt + t0 + 2) >> 2; - SRC(1,0)=SRC(2,1)=SRC(3,2)=SRC(4,3)=SRC(5,4)=SRC(6,5)=SRC(7,6)= (lt + 2*t0 + t1 + 2) >> 2; - SRC(2,0)=SRC(3,1)=SRC(4,2)=SRC(5,3)=SRC(6,4)=SRC(7,5)= (t0 + 2*t1 + t2 + 2) >> 2; - SRC(3,0)=SRC(4,1)=SRC(5,2)=SRC(6,3)=SRC(7,4)= (t1 + 2*t2 + t3 + 2) >> 2; - SRC(4,0)=SRC(5,1)=SRC(6,2)=SRC(7,3)= (t2 + 2*t3 + t4 + 2) >> 2; - SRC(5,0)=SRC(6,1)=SRC(7,2)= (t3 + 2*t4 + t5 + 2) >> 2; - SRC(6,0)=SRC(7,1)= (t4 + 2*t5 + t6 + 2) >> 2; - SRC(7,0)= (t5 + 2*t6 + t7 + 2) >> 2; - -} -static void pred8x8l_vertical_right_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_TOP; - PREDICT_8x8_LOAD_LEFT; - PREDICT_8x8_LOAD_TOPLEFT; - SRC(0,6)= (l5 + 2*l4 + l3 + 2) >> 2; - SRC(0,7)= (l6 + 2*l5 + l4 + 2) >> 2; - SRC(0,4)=SRC(1,6)= (l3 + 2*l2 + l1 + 2) >> 2; - SRC(0,5)=SRC(1,7)= (l4 + 2*l3 + l2 + 2) >> 2; - SRC(0,2)=SRC(1,4)=SRC(2,6)= (l1 + 2*l0 + lt + 2) >> 2; - SRC(0,3)=SRC(1,5)=SRC(2,7)= (l2 + 2*l1 + l0 + 2) >> 2; - SRC(0,1)=SRC(1,3)=SRC(2,5)=SRC(3,7)= (l0 + 2*lt + t0 + 2) >> 2; - SRC(0,0)=SRC(1,2)=SRC(2,4)=SRC(3,6)= (lt + t0 + 1) >> 1; - SRC(1,1)=SRC(2,3)=SRC(3,5)=SRC(4,7)= (lt + 2*t0 + t1 + 2) >> 2; - SRC(1,0)=SRC(2,2)=SRC(3,4)=SRC(4,6)= (t0 + t1 + 1) >> 1; - SRC(2,1)=SRC(3,3)=SRC(4,5)=SRC(5,7)= (t0 + 2*t1 + t2 + 2) >> 2; - SRC(2,0)=SRC(3,2)=SRC(4,4)=SRC(5,6)= (t1 + t2 + 1) >> 1; - SRC(3,1)=SRC(4,3)=SRC(5,5)=SRC(6,7)= (t1 + 2*t2 + t3 + 2) >> 2; - SRC(3,0)=SRC(4,2)=SRC(5,4)=SRC(6,6)= (t2 + t3 + 1) >> 1; - SRC(4,1)=SRC(5,3)=SRC(6,5)=SRC(7,7)= (t2 + 2*t3 + t4 + 2) >> 2; - SRC(4,0)=SRC(5,2)=SRC(6,4)=SRC(7,6)= (t3 + t4 + 1) >> 1; - SRC(5,1)=SRC(6,3)=SRC(7,5)= (t3 + 2*t4 + t5 + 2) >> 2; - SRC(5,0)=SRC(6,2)=SRC(7,4)= (t4 + t5 + 1) >> 1; - SRC(6,1)=SRC(7,3)= (t4 + 2*t5 + t6 + 2) >> 2; - SRC(6,0)=SRC(7,2)= (t5 + t6 + 1) >> 1; - SRC(7,1)= (t5 + 2*t6 + t7 + 2) >> 2; - SRC(7,0)= (t6 + t7 + 1) >> 1; -} -static void pred8x8l_horizontal_down_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_TOP; - PREDICT_8x8_LOAD_LEFT; - PREDICT_8x8_LOAD_TOPLEFT; - SRC(0,7)= (l6 + l7 + 1) >> 1; - SRC(1,7)= (l5 + 2*l6 + l7 + 2) >> 2; - SRC(0,6)=SRC(2,7)= (l5 + l6 + 1) >> 1; - SRC(1,6)=SRC(3,7)= (l4 + 2*l5 + l6 + 2) >> 2; - SRC(0,5)=SRC(2,6)=SRC(4,7)= (l4 + l5 + 1) >> 1; - SRC(1,5)=SRC(3,6)=SRC(5,7)= (l3 + 2*l4 + l5 + 2) >> 2; - SRC(0,4)=SRC(2,5)=SRC(4,6)=SRC(6,7)= (l3 + l4 + 1) >> 1; - SRC(1,4)=SRC(3,5)=SRC(5,6)=SRC(7,7)= (l2 + 2*l3 + l4 + 2) >> 2; - SRC(0,3)=SRC(2,4)=SRC(4,5)=SRC(6,6)= (l2 + l3 + 1) >> 1; - SRC(1,3)=SRC(3,4)=SRC(5,5)=SRC(7,6)= (l1 + 2*l2 + l3 + 2) >> 2; - SRC(0,2)=SRC(2,3)=SRC(4,4)=SRC(6,5)= (l1 + l2 + 1) >> 1; - SRC(1,2)=SRC(3,3)=SRC(5,4)=SRC(7,5)= (l0 + 2*l1 + l2 + 2) >> 2; - SRC(0,1)=SRC(2,2)=SRC(4,3)=SRC(6,4)= (l0 + l1 + 1) >> 1; - SRC(1,1)=SRC(3,2)=SRC(5,3)=SRC(7,4)= (lt + 2*l0 + l1 + 2) >> 2; - SRC(0,0)=SRC(2,1)=SRC(4,2)=SRC(6,3)= (lt + l0 + 1) >> 1; - SRC(1,0)=SRC(3,1)=SRC(5,2)=SRC(7,3)= (l0 + 2*lt + t0 + 2) >> 2; - SRC(2,0)=SRC(4,1)=SRC(6,2)= (t1 + 2*t0 + lt + 2) >> 2; - SRC(3,0)=SRC(5,1)=SRC(7,2)= (t2 + 2*t1 + t0 + 2) >> 2; - SRC(4,0)=SRC(6,1)= (t3 + 2*t2 + t1 + 2) >> 2; - SRC(5,0)=SRC(7,1)= (t4 + 2*t3 + t2 + 2) >> 2; - SRC(6,0)= (t5 + 2*t4 + t3 + 2) >> 2; - SRC(7,0)= (t6 + 2*t5 + t4 + 2) >> 2; -} -static void pred8x8l_vertical_left_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_TOP; - PREDICT_8x8_LOAD_TOPRIGHT; - SRC(0,0)= (t0 + t1 + 1) >> 1; - SRC(0,1)= (t0 + 2*t1 + t2 + 2) >> 2; - SRC(0,2)=SRC(1,0)= (t1 + t2 + 1) >> 1; - SRC(0,3)=SRC(1,1)= (t1 + 2*t2 + t3 + 2) >> 2; - SRC(0,4)=SRC(1,2)=SRC(2,0)= (t2 + t3 + 1) >> 1; - SRC(0,5)=SRC(1,3)=SRC(2,1)= (t2 + 2*t3 + t4 + 2) >> 2; - SRC(0,6)=SRC(1,4)=SRC(2,2)=SRC(3,0)= (t3 + t4 + 1) >> 1; - SRC(0,7)=SRC(1,5)=SRC(2,3)=SRC(3,1)= (t3 + 2*t4 + t5 + 2) >> 2; - SRC(1,6)=SRC(2,4)=SRC(3,2)=SRC(4,0)= (t4 + t5 + 1) >> 1; - SRC(1,7)=SRC(2,5)=SRC(3,3)=SRC(4,1)= (t4 + 2*t5 + t6 + 2) >> 2; - SRC(2,6)=SRC(3,4)=SRC(4,2)=SRC(5,0)= (t5 + t6 + 1) >> 1; - SRC(2,7)=SRC(3,5)=SRC(4,3)=SRC(5,1)= (t5 + 2*t6 + t7 + 2) >> 2; - SRC(3,6)=SRC(4,4)=SRC(5,2)=SRC(6,0)= (t6 + t7 + 1) >> 1; - SRC(3,7)=SRC(4,5)=SRC(5,3)=SRC(6,1)= (t6 + 2*t7 + t8 + 2) >> 2; - SRC(4,6)=SRC(5,4)=SRC(6,2)=SRC(7,0)= (t7 + t8 + 1) >> 1; - SRC(4,7)=SRC(5,5)=SRC(6,3)=SRC(7,1)= (t7 + 2*t8 + t9 + 2) >> 2; - SRC(5,6)=SRC(6,4)=SRC(7,2)= (t8 + t9 + 1) >> 1; - SRC(5,7)=SRC(6,5)=SRC(7,3)= (t8 + 2*t9 + t10 + 2) >> 2; - SRC(6,6)=SRC(7,4)= (t9 + t10 + 1) >> 1; - SRC(6,7)=SRC(7,5)= (t9 + 2*t10 + t11 + 2) >> 2; - SRC(7,6)= (t10 + t11 + 1) >> 1; - SRC(7,7)= (t10 + 2*t11 + t12 + 2) >> 2; -} -static void pred8x8l_horizontal_up_c(uint8_t *src, int has_topleft, int has_topright, int stride) -{ - PREDICT_8x8_LOAD_LEFT; - SRC(0,0)= (l0 + l1 + 1) >> 1; - SRC(1,0)= (l0 + 2*l1 + l2 + 2) >> 2; - SRC(0,1)=SRC(2,0)= (l1 + l2 + 1) >> 1; - SRC(1,1)=SRC(3,0)= (l1 + 2*l2 + l3 + 2) >> 2; - SRC(0,2)=SRC(2,1)=SRC(4,0)= (l2 + l3 + 1) >> 1; - SRC(1,2)=SRC(3,1)=SRC(5,0)= (l2 + 2*l3 + l4 + 2) >> 2; - SRC(0,3)=SRC(2,2)=SRC(4,1)=SRC(6,0)= (l3 + l4 + 1) >> 1; - SRC(1,3)=SRC(3,2)=SRC(5,1)=SRC(7,0)= (l3 + 2*l4 + l5 + 2) >> 2; - SRC(0,4)=SRC(2,3)=SRC(4,2)=SRC(6,1)= (l4 + l5 + 1) >> 1; - SRC(1,4)=SRC(3,3)=SRC(5,2)=SRC(7,1)= (l4 + 2*l5 + l6 + 2) >> 2; - SRC(0,5)=SRC(2,4)=SRC(4,3)=SRC(6,2)= (l5 + l6 + 1) >> 1; - SRC(1,5)=SRC(3,4)=SRC(5,3)=SRC(7,2)= (l5 + 2*l6 + l7 + 2) >> 2; - SRC(0,6)=SRC(2,5)=SRC(4,4)=SRC(6,3)= (l6 + l7 + 1) >> 1; - SRC(1,6)=SRC(3,5)=SRC(5,4)=SRC(7,3)= (l6 + 3*l7 + 2) >> 2; - SRC(0,7)=SRC(1,7)=SRC(2,6)=SRC(2,7)=SRC(3,6)= - SRC(3,7)=SRC(4,5)=SRC(4,6)=SRC(4,7)=SRC(5,5)= - SRC(5,6)=SRC(5,7)=SRC(6,4)=SRC(6,5)=SRC(6,6)= - SRC(6,7)=SRC(7,4)=SRC(7,5)=SRC(7,6)=SRC(7,7)= l7; -} -#undef PREDICT_8x8_LOAD_LEFT -#undef PREDICT_8x8_LOAD_TOP -#undef PREDICT_8x8_LOAD_TOPLEFT -#undef PREDICT_8x8_LOAD_TOPRIGHT -#undef PREDICT_8x8_DC -#undef PTR -#undef PT -#undef PL -#undef SRC - static inline void mc_dir_part(H264Context *h, Picture *pic, int n, 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, @@ -2762,7 +1684,7 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square, const int full_mx= mx>>2; const int full_my= my>>2; const int pic_width = 16*s->mb_width; - const int pic_height = 16*s->mb_height >> MB_MBAFF; + const int pic_height = 16*s->mb_height >> MB_FIELD; if(!pic->data[0]) //FIXME this is unacceptable, some senseable error concealment must be done for missing reference frames return; @@ -2784,11 +1706,11 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square, qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize); } - if(s->flags&CODEC_FLAG_GRAY) return; + if(ENABLE_GRAY && s->flags&CODEC_FLAG_GRAY) return; - if(MB_MBAFF){ + if(MB_FIELD){ // chroma offset when predicting from a field of opposite parity - my += 2 * ((s->mb_y & 1) - (h->ref_cache[list][scan8[n]] & 1)); + my += 2 * ((s->mb_y & 1) - (pic->reference - 1)); emu |= (my>>3) < 0 || (my>>3) + 8 >= (pic_height>>1); } src_cb= pic->data[1] + (mx>>3) + (my>>3)*h->mb_uvlinesize; @@ -2821,7 +1743,7 @@ static inline void mc_part_std(H264Context *h, int n, int square, int chroma_hei dest_cb += x_offset + y_offset*h->mb_uvlinesize; dest_cr += x_offset + y_offset*h->mb_uvlinesize; x_offset += 8*s->mb_x; - y_offset += 8*(s->mb_y >> MB_MBAFF); + y_offset += 8*(s->mb_y >> MB_FIELD); if(list0){ Picture *ref= &h->ref_list[0][ h->ref_cache[0][ scan8[n] ] ]; @@ -2854,7 +1776,7 @@ static inline void mc_part_weighted(H264Context *h, int n, int square, int chrom dest_cb += x_offset + y_offset*h->mb_uvlinesize; dest_cr += x_offset + y_offset*h->mb_uvlinesize; x_offset += 8*s->mb_x; - y_offset += 8*(s->mb_y >> MB_MBAFF); + y_offset += 8*(s->mb_y >> MB_FIELD); if(list0 && list1){ /* don't optimize for luma-only case, since B-frames usually @@ -3029,7 +1951,7 @@ static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t prefetch_motion(h, 1); } -static void decode_init_vlc(){ +static void decode_init_vlc(void){ static int done = 0; if (!done) { @@ -3068,56 +1990,9 @@ static void decode_init_vlc(){ } } -/** - * Sets the intra prediction function pointers. - */ -static void init_pred_ptrs(H264Context *h){ -// MpegEncContext * const s = &h->s; - - h->pred4x4[VERT_PRED ]= pred4x4_vertical_c; - h->pred4x4[HOR_PRED ]= pred4x4_horizontal_c; - h->pred4x4[DC_PRED ]= pred4x4_dc_c; - h->pred4x4[DIAG_DOWN_LEFT_PRED ]= pred4x4_down_left_c; - h->pred4x4[DIAG_DOWN_RIGHT_PRED]= pred4x4_down_right_c; - h->pred4x4[VERT_RIGHT_PRED ]= pred4x4_vertical_right_c; - h->pred4x4[HOR_DOWN_PRED ]= pred4x4_horizontal_down_c; - h->pred4x4[VERT_LEFT_PRED ]= pred4x4_vertical_left_c; - h->pred4x4[HOR_UP_PRED ]= pred4x4_horizontal_up_c; - h->pred4x4[LEFT_DC_PRED ]= pred4x4_left_dc_c; - h->pred4x4[TOP_DC_PRED ]= pred4x4_top_dc_c; - h->pred4x4[DC_128_PRED ]= pred4x4_128_dc_c; - - h->pred8x8l[VERT_PRED ]= pred8x8l_vertical_c; - h->pred8x8l[HOR_PRED ]= pred8x8l_horizontal_c; - h->pred8x8l[DC_PRED ]= pred8x8l_dc_c; - h->pred8x8l[DIAG_DOWN_LEFT_PRED ]= pred8x8l_down_left_c; - h->pred8x8l[DIAG_DOWN_RIGHT_PRED]= pred8x8l_down_right_c; - h->pred8x8l[VERT_RIGHT_PRED ]= pred8x8l_vertical_right_c; - h->pred8x8l[HOR_DOWN_PRED ]= pred8x8l_horizontal_down_c; - h->pred8x8l[VERT_LEFT_PRED ]= pred8x8l_vertical_left_c; - h->pred8x8l[HOR_UP_PRED ]= pred8x8l_horizontal_up_c; - h->pred8x8l[LEFT_DC_PRED ]= pred8x8l_left_dc_c; - h->pred8x8l[TOP_DC_PRED ]= pred8x8l_top_dc_c; - h->pred8x8l[DC_128_PRED ]= pred8x8l_128_dc_c; - - h->pred8x8[DC_PRED8x8 ]= ff_pred8x8_dc_c; - h->pred8x8[VERT_PRED8x8 ]= ff_pred8x8_vertical_c; - h->pred8x8[HOR_PRED8x8 ]= ff_pred8x8_horizontal_c; - h->pred8x8[PLANE_PRED8x8 ]= ff_pred8x8_plane_c; - h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_c; - h->pred8x8[TOP_DC_PRED8x8 ]= pred8x8_top_dc_c; - h->pred8x8[DC_128_PRED8x8 ]= ff_pred8x8_128_dc_c; - - h->pred16x16[DC_PRED8x8 ]= ff_pred16x16_dc_c; - h->pred16x16[VERT_PRED8x8 ]= ff_pred16x16_vertical_c; - h->pred16x16[HOR_PRED8x8 ]= ff_pred16x16_horizontal_c; - h->pred16x16[PLANE_PRED8x8 ]= ff_pred16x16_plane_c; - h->pred16x16[LEFT_DC_PRED8x8]= pred16x16_left_dc_c; - h->pred16x16[TOP_DC_PRED8x8 ]= pred16x16_top_dc_c; - h->pred16x16[DC_128_PRED8x8 ]= ff_pred16x16_128_dc_c; -} - static void free_tables(H264Context *h){ + int i; + H264Context *hx; av_freep(&h->intra4x4_pred_mode); av_freep(&h->chroma_pred_mode_table); av_freep(&h->cbp_table); @@ -3126,14 +2001,24 @@ static void free_tables(H264Context *h){ av_freep(&h->direct_table); av_freep(&h->non_zero_count); av_freep(&h->slice_table_base); - av_freep(&h->top_borders[1]); - av_freep(&h->top_borders[0]); h->slice_table= NULL; av_freep(&h->mb2b_xy); av_freep(&h->mb2b8_xy); - av_freep(&h->s.obmc_scratchpad); + for(i = 0; i < MAX_SPS_COUNT; i++) + av_freep(h->sps_buffers + i); + + for(i = 0; i < MAX_PPS_COUNT; i++) + av_freep(h->pps_buffers + i); + + for(i = 0; i < h->s.avctx->thread_count; i++) { + hx = h->thread_context[i]; + if(!hx) continue; + av_freep(&hx->top_borders[1]); + av_freep(&hx->top_borders[0]); + av_freep(&hx->s.obmc_scratchpad); + } } static void init_dequant8_coeff_table(H264Context *h){ @@ -3214,16 +2099,12 @@ static int alloc_tables(H264Context *h){ CHECKED_ALLOCZ(h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t)) CHECKED_ALLOCZ(h->slice_table_base , (big_mb_num+s->mb_stride) * sizeof(uint8_t)) - CHECKED_ALLOCZ(h->top_borders[0] , s->mb_width * (16+8+8) * sizeof(uint8_t)) - CHECKED_ALLOCZ(h->top_borders[1] , s->mb_width * (16+8+8) * sizeof(uint8_t)) CHECKED_ALLOCZ(h->cbp_table, big_mb_num * sizeof(uint16_t)) - if( h->pps.cabac ) { - CHECKED_ALLOCZ(h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t)) - CHECKED_ALLOCZ(h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t)); - CHECKED_ALLOCZ(h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t)); - CHECKED_ALLOCZ(h->direct_table, 32*big_mb_num * sizeof(uint8_t)); - } + CHECKED_ALLOCZ(h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t)) + CHECKED_ALLOCZ(h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t)); + CHECKED_ALLOCZ(h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t)); + CHECKED_ALLOCZ(h->direct_table, 32*big_mb_num * sizeof(uint8_t)); memset(h->slice_table_base, -1, (big_mb_num+s->mb_stride) * sizeof(uint8_t)); h->slice_table= h->slice_table_base + s->mb_stride*2 + 1; @@ -3252,6 +2133,38 @@ fail: return -1; } +/** + * Mimic alloc_tables(), but for every context thread. + */ +static void clone_tables(H264Context *dst, H264Context *src){ + dst->intra4x4_pred_mode = src->intra4x4_pred_mode; + dst->non_zero_count = src->non_zero_count; + dst->slice_table = src->slice_table; + dst->cbp_table = src->cbp_table; + dst->mb2b_xy = src->mb2b_xy; + dst->mb2b8_xy = src->mb2b8_xy; + dst->chroma_pred_mode_table = src->chroma_pred_mode_table; + dst->mvd_table[0] = src->mvd_table[0]; + dst->mvd_table[1] = src->mvd_table[1]; + dst->direct_table = src->direct_table; + + dst->s.obmc_scratchpad = NULL; + ff_h264_pred_init(&dst->hpc, src->s.codec_id); +} + +/** + * Init context + * Allocate buffers which are not shared amongst multiple threads. + */ +static int context_init(H264Context *h){ + CHECKED_ALLOCZ(h->top_borders[0], h->s.mb_width * (16+8+8) * sizeof(uint8_t)) + CHECKED_ALLOCZ(h->top_borders[1], h->s.mb_width * (16+8+8) * sizeof(uint8_t)) + + return 0; +fail: + return -1; // free_tables will clean up for us +} + static void common_init(H264Context *h){ MpegEncContext * const s = &h->s; @@ -3259,7 +2172,7 @@ static void common_init(H264Context *h){ s->height = s->avctx->height; s->codec_id= s->avctx->codec->id; - init_pred_ptrs(h); + ff_h264_pred_init(&h->hpc, s->codec_id); h->dequant_coeff_pps= -1; s->unrestricted_mv=1; @@ -3283,6 +2196,7 @@ static int decode_init(AVCodecContext *avctx){ // set defaults // s->decode_mb= ff_h263_decode_mb; + s->quarter_sample = 1; s->low_delay= 1; avctx->pix_fmt= PIX_FMT_YUV420P; @@ -3296,6 +2210,7 @@ static int decode_init(AVCodecContext *avctx){ h->is_avc = 0; } + h->thread_context[0] = h; return 0; } @@ -3306,6 +2221,13 @@ static int frame_start(H264Context *h){ if(MPV_frame_start(s, s->avctx) < 0) return -1; ff_er_frame_start(s); + /* + * MPV_frame_start uses pict_type to derive key_frame. + * This is incorrect for H.264; IDR markings must be used. + * Zero here; IDR markings per slice in frame or fields are OR'd in later. + * See decode_nal_units(). + */ + s->current_picture_ptr->key_frame= 0; assert(s->linesize && s->uvlinesize); @@ -3322,18 +2244,19 @@ static int frame_start(H264Context *h){ /* can't be in alloc_tables because linesize isn't known there. * FIXME: redo bipred weight to not require extra buffer? */ - if(!s->obmc_scratchpad) - s->obmc_scratchpad = av_malloc(16*2*s->linesize + 8*2*s->uvlinesize); + for(i = 0; i < s->avctx->thread_count; i++) + if(!h->thread_context[i]->s.obmc_scratchpad) + h->thread_context[i]->s.obmc_scratchpad = av_malloc(16*2*s->linesize + 8*2*s->uvlinesize); /* some macroblocks will be accessed before they're available */ - if(FRAME_MBAFF) + if(FRAME_MBAFF || s->avctx->thread_count > 1) memset(h->slice_table, -1, (s->mb_height*s->mb_stride-1) * sizeof(uint8_t)); // s->decode= (s->flags&CODEC_FLAG_PSNR) || !s->encoding || s->current_picture.reference /*|| h->contains_intra*/ || 1; return 0; } -static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize){ +static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int simple){ MpegEncContext * const s = &h->s; int i; @@ -3351,7 +2274,7 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src *(uint64_t*)(h->top_borders[0][s->mb_x]+0)= *(uint64_t*)(src_y + 16*linesize); *(uint64_t*)(h->top_borders[0][s->mb_x]+8)= *(uint64_t*)(src_y +8+16*linesize); - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ h->left_border[17 ]= h->top_borders[0][s->mb_x][16+7]; h->left_border[17+9]= h->top_borders[0][s->mb_x][24+7]; for(i=1; i<9; i++){ @@ -3363,12 +2286,22 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src } } -static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int xchg){ +static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int xchg, int simple){ MpegEncContext * const s = &h->s; int temp8, i; uint64_t temp64; - int deblock_left = (s->mb_x > 0); - int deblock_top = (s->mb_y > 0); + int deblock_left; + int deblock_top; + int mb_xy; + + if(h->deblocking_filter == 2) { + mb_xy = s->mb_x + s->mb_y*s->mb_stride; + deblock_left = h->slice_table[mb_xy] == h->slice_table[mb_xy - 1]; + deblock_top = h->slice_table[mb_xy] == h->slice_table[h->top_mb_xy]; + } else { + deblock_left = (s->mb_x > 0); + deblock_top = (s->mb_y > 0); + } src_y -= linesize + 1; src_cb -= uvlinesize + 1; @@ -3394,7 +2327,7 @@ b= t; } } - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if(deblock_left){ for(i = !deblock_top; i<9; i++){ XCHG(h->left_border[i+17 ], src_cb[i*uvlinesize], temp8, xchg); @@ -3429,7 +2362,7 @@ static inline void backup_pair_border(H264Context *h, uint8_t *src_y, uint8_t *s *(uint64_t*)(h->top_borders[1][s->mb_x]+0)= *(uint64_t*)(src_y + 33*linesize); *(uint64_t*)(h->top_borders[1][s->mb_x]+8)= *(uint64_t*)(src_y +8+33*linesize); - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ h->left_border[34 ]= h->top_borders[0][s->mb_x][16+7]; h->left_border[34+ 1]= h->top_borders[1][s->mb_x][16+7]; h->left_border[34+18 ]= h->top_borders[0][s->mb_x][24+7]; @@ -3481,7 +2414,7 @@ b= t; } } - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if(deblock_left){ for(i = (!deblock_top) << 1; i<18; i++){ XCHG(h->left_border[i+34 ], src_cb[i*uvlinesize], temp8, xchg); @@ -3497,7 +2430,7 @@ b= t; } } -static void av_always_inline hl_decode_mb_internal(H264Context *h, int simple){ +static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){ MpegEncContext * const s = &h->s; const int mb_x= s->mb_x; const int mb_y= s->mb_y; @@ -3535,13 +2468,13 @@ static void av_always_inline hl_decode_mb_internal(H264Context *h, int simple){ continue; if(IS_16X16(mb_type)){ int8_t *ref = &h->ref_cache[list][scan8[0]]; - fill_rectangle(ref, 4, 4, 8, 16+*ref^(s->mb_y&1), 1); + fill_rectangle(ref, 4, 4, 8, (16+*ref)^(s->mb_y&1), 1); }else{ for(i=0; i<16; i+=4){ //FIXME can refs be smaller than 8x8 when !direct_8x8_inference ? int ref = h->ref_cache[list][scan8[i]]; if(ref >= 0) - fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2, 8, 16+ref^(s->mb_y&1), 1); + fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2, 8, (16+ref)^(s->mb_y&1), 1); } } } @@ -3601,11 +2534,11 @@ static void av_always_inline hl_decode_mb_internal(H264Context *h, int simple){ } else { if(IS_INTRA(mb_type)){ if(h->deblocking_filter && (simple || !FRAME_MBAFF)) - xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 1); + xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 1, simple); - if(simple || !(s->flags&CODEC_FLAG_GRAY)){ - h->pred8x8[ h->chroma_pred_mode ](dest_cb, uvlinesize); - h->pred8x8[ h->chroma_pred_mode ](dest_cr, uvlinesize); + if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ + h->hpc.pred8x8[ h->chroma_pred_mode ](dest_cb, uvlinesize); + h->hpc.pred8x8[ h->chroma_pred_mode ](dest_cr, uvlinesize); } if(IS_INTRA4x4(mb_type)){ @@ -3615,7 +2548,7 @@ static void av_always_inline hl_decode_mb_internal(H264Context *h, int simple){ uint8_t * const ptr= dest_y + block_offset[i]; const int dir= h->intra4x4_pred_mode_cache[ scan8[i] ]; const int nnz = h->non_zero_count_cache[ scan8[i] ]; - h->pred8x8l[ dir ](ptr, (h->topleft_samples_available<<i)&0x8000, + h->hpc.pred8x8l[ dir ](ptr, (h->topleft_samples_available<<i)&0x8000, (h->topright_samples_available<<i)&0x4000, linesize); if(nnz){ if(nnz == 1 && h->mb[i*16]) @@ -3642,7 +2575,7 @@ static void av_always_inline hl_decode_mb_internal(H264Context *h, int simple){ }else topright= NULL; - h->pred4x4[ dir ](ptr, topright, linesize); + h->hpc.pred4x4[ dir ](ptr, topright, linesize); nnz = h->non_zero_count_cache[ scan8[i] ]; if(nnz){ if(is_h264){ @@ -3656,15 +2589,15 @@ static void av_always_inline hl_decode_mb_internal(H264Context *h, int simple){ } } }else{ - h->pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize); + h->hpc.pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize); if(is_h264){ if(!transform_bypass) - h264_luma_dc_dequant_idct_c(h->mb, s->qscale, h->dequant4_coeff[IS_INTRA(mb_type) ? 0:3][s->qscale][0]); + h264_luma_dc_dequant_idct_c(h->mb, s->qscale, h->dequant4_coeff[0][s->qscale][0]); }else svq3_luma_dc_dequant_idct_c(h->mb, s->qscale); } if(h->deblocking_filter && (simple || !FRAME_MBAFF)) - xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0); + xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0, simple); }else if(is_h264){ hl_motion(h, dest_y, dest_cb, dest_cr, s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab, @@ -3704,15 +2637,15 @@ static void av_always_inline hl_decode_mb_internal(H264Context *h, int simple){ } } - if(simple || !(s->flags&CODEC_FLAG_GRAY)){ + if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ uint8_t *dest[2] = {dest_cb, dest_cr}; if(transform_bypass){ idct_add = idct_dc_add = s->dsp.add_pixels4; }else{ idct_add = s->dsp.h264_idct_add; idct_dc_add = s->dsp.h264_idct_dc_add; - chroma_dc_dequant_idct_c(h->mb + 16*16, h->chroma_qp, h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp][0]); - chroma_dc_dequant_idct_c(h->mb + 16*16+4*16, h->chroma_qp, h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp][0]); + chroma_dc_dequant_idct_c(h->mb + 16*16, h->chroma_qp[0], h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp[0]][0]); + chroma_dc_dequant_idct_c(h->mb + 16*16+4*16, h->chroma_qp[1], h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp[1]][0]); } if(is_h264){ for(i=16; i<16+8; i++){ @@ -3754,17 +2687,19 @@ static void av_always_inline hl_decode_mb_internal(H264Context *h, int simple){ s->mb_y--; tprintf(h->s.avctx, "call mbaff filter_mb mb_x:%d mb_y:%d pair_dest_y = %p, dest_y = %p\n", mb_x, mb_y, pair_dest_y, dest_y); fill_caches(h, mb_type_top, 1); //FIXME don't fill stuff which isn't used by filter_mb - h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mb_xy]); + h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]); + h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]); filter_mb(h, mb_x, mb_y, pair_dest_y, pair_dest_cb, pair_dest_cr, linesize, uvlinesize); // bottom s->mb_y++; tprintf(h->s.avctx, "call mbaff filter_mb\n"); fill_caches(h, mb_type_bottom, 1); //FIXME don't fill stuff which isn't used by filter_mb - h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mb_xy+s->mb_stride]); + h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy+s->mb_stride]); + h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy+s->mb_stride]); filter_mb(h, mb_x, mb_y+1, dest_y, dest_cb, dest_cr, linesize, uvlinesize); } else { tprintf(h->s.avctx, "call filter_mb\n"); - backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize); + backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, simple); fill_caches(h, mb_type, 1); //FIXME don't fill stuff which isn't used by filter_mb filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); } @@ -3791,7 +2726,7 @@ static void hl_decode_mb(H264Context *h){ const int mb_y= s->mb_y; const int mb_xy= mb_x + mb_y*s->mb_stride; const int mb_type= s->current_picture.mb_type[mb_xy]; - int is_complex = FRAME_MBAFF || MB_FIELD || IS_INTRA_PCM(mb_type) || s->codec_id != CODEC_ID_H264 || (s->flags&CODEC_FLAG_GRAY) || s->encoding; + int is_complex = FRAME_MBAFF || MB_FIELD || IS_INTRA_PCM(mb_type) || s->codec_id != CODEC_ID_H264 || (ENABLE_GRAY && (s->flags&CODEC_FLAG_GRAY)) || s->encoding; if(!s->decode) return; @@ -3801,6 +2736,105 @@ static void hl_decode_mb(H264Context *h){ else hl_decode_mb_simple(h); } +static void pic_as_field(Picture *pic, const int parity){ + int i; + for (i = 0; i < 4; ++i) { + if (parity == PICT_BOTTOM_FIELD) + pic->data[i] += pic->linesize[i]; + pic->reference = parity; + pic->linesize[i] *= 2; + } +} + +static int split_field_copy(Picture *dest, Picture *src, + int parity, int id_add){ + int match = !!(src->reference & parity); + + if (match) { + *dest = *src; + pic_as_field(dest, parity); + dest->pic_id *= 2; + dest->pic_id += id_add; + } + + return match; +} + +/** + * Split one reference list into field parts, interleaving by parity + * as per H.264 spec section 8.2.4.2.5. Output fields have their data pointers + * set to look at the actual start of data for that field. + * + * @param dest output list + * @param dest_len maximum number of fields to put in dest + * @param src the source reference list containing fields and/or field pairs + * (aka short_ref/long_ref, or + * refFrameListXShortTerm/refFrameListLongTerm in spec-speak) + * @param src_len number of Picture's in source (pairs and unmatched fields) + * @param parity the parity of the picture being decoded/needing + * these ref pics (PICT_{TOP,BOTTOM}_FIELD) + * @return number of fields placed in dest + */ +static int split_field_half_ref_list(Picture *dest, int dest_len, + Picture *src, int src_len, int parity){ + int same_parity = 1; + int same_i = 0; + int opp_i = 0; + int out_i; + int field_output; + + for (out_i = 0; out_i < dest_len; out_i += field_output) { + if (same_parity && same_i < src_len) { + field_output = split_field_copy(dest + out_i, src + same_i, + parity, 1); + same_parity = !field_output; + same_i++; + + } else if (opp_i < src_len) { + field_output = split_field_copy(dest + out_i, src + opp_i, + PICT_FRAME - parity, 0); + same_parity = field_output; + opp_i++; + + } else { + break; + } + } + + return out_i; +} + +/** + * Split the reference frame list into a reference field list. + * This implements H.264 spec 8.2.4.2.5 for a combined input list. + * The input list contains both reference field pairs and + * unmatched reference fields; it is ordered as spec describes + * RefPicListX for frames in 8.2.4.2.1 and 8.2.4.2.3, except that + * unmatched field pairs are also present. Conceptually this is equivalent + * to concatenation of refFrameListXShortTerm with refFrameListLongTerm. + * + * @param dest output reference list where ordered fields are to be placed + * @param dest_len max number of fields to place at dest + * @param src source reference list, as described above + * @param src_len number of pictures (pairs and unmatched fields) in src + * @param parity parity of field being currently decoded + * (one of PICT_{TOP,BOTTOM}_FIELD) + * @param long_i index into src array that holds first long reference picture, + * or src_len if no long refs present. + */ +static int split_field_ref_list(Picture *dest, int dest_len, + Picture *src, int src_len, + int parity, int long_i){ + + int i = split_field_half_ref_list(dest, dest_len, src, long_i, parity); + dest += i; + dest_len -= i; + + i += split_field_half_ref_list(dest, dest_len, src + long_i, + src_len - long_i, parity); + return i; +} + /** * fills the default_ref_list. */ @@ -3808,9 +2842,25 @@ static int fill_default_ref_list(H264Context *h){ MpegEncContext * const s = &h->s; int i; int smallest_poc_greater_than_current = -1; + int structure_sel; Picture sorted_short_ref[32]; + Picture field_entry_list[2][32]; + Picture *frame_list[2]; + + if (FIELD_PICTURE) { + structure_sel = PICT_FRAME; + frame_list[0] = field_entry_list[0]; + frame_list[1] = field_entry_list[1]; + } else { + structure_sel = 0; + frame_list[0] = h->default_ref_list[0]; + frame_list[1] = h->default_ref_list[1]; + } if(h->slice_type==B_TYPE){ + int list; + int len[2]; + int short_len[2]; int out_i; int limit= INT_MIN; @@ -3838,71 +2888,92 @@ static int fill_default_ref_list(H264Context *h){ } } } - } - if(s->picture_structure == PICT_FRAME){ - if(h->slice_type==B_TYPE){ - int list; - tprintf(h->s.avctx, "current poc: %d, smallest_poc_greater_than_current: %d\n", s->current_picture_ptr->poc, smallest_poc_greater_than_current); + tprintf(h->s.avctx, "current poc: %d, smallest_poc_greater_than_current: %d\n", s->current_picture_ptr->poc, smallest_poc_greater_than_current); - // find the largest poc - for(list=0; list<2; list++){ - int index = 0; - int j= -99; - int step= list ? -1 : 1; - - for(i=0; i<h->short_ref_count && index < h->ref_count[list]; i++, j+=step) { - while(j<0 || j>= h->short_ref_count){ - if(j != -99 && step == (list ? -1 : 1)) - return -1; - step = -step; - j= smallest_poc_greater_than_current + (step>>1); - } - if(sorted_short_ref[j].reference != 3) continue; - h->default_ref_list[list][index ]= sorted_short_ref[j]; - h->default_ref_list[list][index++].pic_id= sorted_short_ref[j].frame_num; + // find the largest poc + for(list=0; list<2; list++){ + int index = 0; + int j= -99; + int step= list ? -1 : 1; + + for(i=0; i<h->short_ref_count && index < h->ref_count[list]; i++, j+=step) { + int sel; + while(j<0 || j>= h->short_ref_count){ + if(j != -99 && step == (list ? -1 : 1)) + return -1; + step = -step; + j= smallest_poc_greater_than_current + (step>>1); } + sel = sorted_short_ref[j].reference | structure_sel; + if(sel != PICT_FRAME) continue; + frame_list[list][index ]= sorted_short_ref[j]; + frame_list[list][index++].pic_id= sorted_short_ref[j].frame_num; + } + short_len[list] = index; - for(i = 0; i < 16 && index < h->ref_count[ list ]; i++){ - if(h->long_ref[i] == NULL) continue; - if(h->long_ref[i]->reference != 3) continue; + for(i = 0; i < 16 && index < h->ref_count[ list ]; i++){ + int sel; + if(h->long_ref[i] == NULL) continue; + sel = h->long_ref[i]->reference | structure_sel; + if(sel != PICT_FRAME) continue; - h->default_ref_list[ list ][index ]= *h->long_ref[i]; - h->default_ref_list[ list ][index++].pic_id= i;; - } + frame_list[ list ][index ]= *h->long_ref[i]; + frame_list[ list ][index++].pic_id= i; + } + len[list] = index; + } - if(list && (smallest_poc_greater_than_current<=0 || smallest_poc_greater_than_current>=h->short_ref_count) && (1 < index)){ - // swap the two first elements of L1 when - // L0 and L1 are identical - Picture temp= h->default_ref_list[1][0]; - h->default_ref_list[1][0] = h->default_ref_list[1][1]; - h->default_ref_list[1][1] = temp; - } + for(list=0; list<2; list++){ + if (FIELD_PICTURE) + len[list] = split_field_ref_list(h->default_ref_list[list], + h->ref_count[list], + frame_list[list], + len[list], + s->picture_structure, + short_len[list]); + + // swap the two first elements of L1 when L0 and L1 are identical + if(list && len[0] > 1 && len[0] == len[1]) + for(i=0; h->default_ref_list[0][i].data[0] == h->default_ref_list[1][i].data[0]; i++) + if(i == len[0]){ + FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]); + break; + } - if(index < h->ref_count[ list ]) - memset(&h->default_ref_list[list][index], 0, sizeof(Picture)*(h->ref_count[ list ] - index)); - } - }else{ - int index=0; - for(i=0; i<h->short_ref_count; i++){ - if(h->short_ref[i]->reference != 3) continue; //FIXME refernce field shit - h->default_ref_list[0][index ]= *h->short_ref[i]; - h->default_ref_list[0][index++].pic_id= h->short_ref[i]->frame_num; - } - for(i = 0; i < 16; i++){ - if(h->long_ref[i] == NULL) continue; - if(h->long_ref[i]->reference != 3) continue; - h->default_ref_list[0][index ]= *h->long_ref[i]; - h->default_ref_list[0][index++].pic_id= i;; - } - if(index < h->ref_count[0]) - memset(&h->default_ref_list[0][index], 0, sizeof(Picture)*(h->ref_count[0] - index)); + if(len[list] < h->ref_count[ list ]) + memset(&h->default_ref_list[list][len[list]], 0, sizeof(Picture)*(h->ref_count[ list ] - len[list])); } - }else{ //FIELD - if(h->slice_type==B_TYPE){ - }else{ - //FIXME second field balh + + + }else{ + int index=0; + int short_len; + for(i=0; i<h->short_ref_count; i++){ + int sel; + sel = h->short_ref[i]->reference | structure_sel; + if(sel != PICT_FRAME) continue; + frame_list[0][index ]= *h->short_ref[i]; + frame_list[0][index++].pic_id= h->short_ref[i]->frame_num; + } + short_len = index; + for(i = 0; i < 16; i++){ + int sel; + if(h->long_ref[i] == NULL) continue; + sel = h->long_ref[i]->reference | structure_sel; + if(sel != PICT_FRAME) continue; + frame_list[0][index ]= *h->long_ref[i]; + frame_list[0][index++].pic_id= i; } + + if (FIELD_PICTURE) + index = split_field_ref_list(h->default_ref_list[0], + h->ref_count[0], frame_list[0], + index, s->picture_structure, + short_len); + + if(index < h->ref_count[0]) + memset(&h->default_ref_list[0][index], 0, sizeof(Picture)*(h->ref_count[0] - index)); } #ifdef TRACE for (i=0; i<h->ref_count[0]; i++) { @@ -3910,7 +2981,7 @@ static int fill_default_ref_list(H264Context *h){ } if(h->slice_type==B_TYPE){ for (i=0; i<h->ref_count[1]; i++) { - tprintf(h->s.avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[0][i].data[0]); + tprintf(h->s.avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].data[0]); } } #endif @@ -3920,9 +2991,33 @@ static int fill_default_ref_list(H264Context *h){ static void print_short_term(H264Context *h); static void print_long_term(H264Context *h); +/** + * Extract structure information about the picture described by pic_num in + * the current decoding context (frame or field). Note that pic_num is + * picture number without wrapping (so, 0<=pic_num<max_pic_num). + * @param pic_num picture number for which to extract structure information + * @param structure one of PICT_XXX describing structure of picture + * with pic_num + * @return frame number (short term) or long term index of picture + * described by pic_num + */ +static int pic_num_extract(H264Context *h, int pic_num, int *structure){ + MpegEncContext * const s = &h->s; + + *structure = s->picture_structure; + if(FIELD_PICTURE){ + if (!(pic_num & 1)) + /* opposite field */ + *structure ^= PICT_FRAME; + pic_num >>= 1; + } + + return pic_num; +} + static int decode_ref_pic_list_reordering(H264Context *h){ MpegEncContext * const s = &h->s; - int list, index; + int list, index, pic_structure; print_short_term(h); print_long_term(h); @@ -3951,8 +3046,9 @@ static int decode_ref_pic_list_reordering(H264Context *h){ if(reordering_of_pic_nums_idc<3){ if(reordering_of_pic_nums_idc<2){ const unsigned int abs_diff_pic_num= get_ue_golomb(&s->gb) + 1; + int frame_num; - if(abs_diff_pic_num >= h->max_pic_num){ + if(abs_diff_pic_num > h->max_pic_num){ av_log(h->s.avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); return -1; } @@ -3961,25 +3057,34 @@ static int decode_ref_pic_list_reordering(H264Context *h){ else pred+= abs_diff_pic_num; pred &= h->max_pic_num - 1; + frame_num = pic_num_extract(h, pred, &pic_structure); + for(i= h->short_ref_count-1; i>=0; i--){ ref = h->short_ref[i]; - assert(ref->reference == 3); + assert(ref->reference); assert(!ref->long_ref); - if(ref->data[0] != NULL && ref->frame_num == pred && ref->long_ref == 0) // ignore non existing pictures by testing data[0] pointer + if(ref->data[0] != NULL && + ref->frame_num == frame_num && + (ref->reference & pic_structure) && + ref->long_ref == 0) // ignore non existing pictures by testing data[0] pointer break; } if(i>=0) - ref->pic_id= ref->frame_num; + ref->pic_id= pred; }else{ + int long_idx; pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx - if(pic_id>31){ + + long_idx= pic_num_extract(h, pic_id, &pic_structure); + + if(long_idx>31){ av_log(h->s.avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); return -1; } - ref = h->long_ref[pic_id]; - if(ref){ + ref = h->long_ref[long_idx]; + assert(!(ref && !ref->reference)); + if(ref && (ref->reference & pic_structure)){ ref->pic_id= pic_id; - assert(ref->reference == 3); assert(ref->long_ref); i=0; }else{ @@ -3999,6 +3104,9 @@ static int decode_ref_pic_list_reordering(H264Context *h){ h->ref_list[list][i]= h->ref_list[list][i-1]; } h->ref_list[list][index]= *ref; + if (FIELD_PICTURE){ + pic_as_field(&h->ref_list[list][index], pic_structure); + } } }else{ av_log(h->s.avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); @@ -4029,9 +3137,11 @@ static void fill_mbaff_ref_list(H264Context *h){ field[0] = *frame; for(j=0; j<3; j++) field[0].linesize[j] <<= 1; + field[0].reference = PICT_TOP_FIELD; field[1] = field[0]; for(j=0; j<3; j++) field[1].data[j] += frame->linesize[j]; + field[1].reference = PICT_BOTTOM_FIELD; h->luma_weight[list][16+2*i] = h->luma_weight[list][16+2*i+1] = h->luma_weight[list][i]; h->luma_offset[list][16+2*i] = h->luma_offset[list][16+2*i+1] = h->luma_offset[list][i]; @@ -4137,17 +3247,32 @@ static void implicit_weight_table(H264Context *h){ } } -static inline void unreference_pic(H264Context *h, Picture *pic){ +/** + * Mark a picture as no longer needed for reference. The refmask + * argument allows unreferencing of individual fields or the whole frame. + * If the picture becomes entirely unreferenced, but is being held for + * display purposes, it is marked as such. + * @param refmask mask of fields to unreference; the mask is bitwise + * anded with the reference marking of pic + * @return non-zero if pic becomes entirely unreferenced (except possibly + * for display purposes) zero if one of the fields remains in + * reference + */ +static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){ int i; - pic->reference=0; - if(pic == h->delayed_output_pic) - pic->reference=1; - else{ - for(i = 0; h->delayed_pic[i]; i++) - if(pic == h->delayed_pic[i]){ - pic->reference=1; - break; - } + if (pic->reference &= refmask) { + return 0; + } else { + if(pic == h->delayed_output_pic) + pic->reference=DELAYED_PIC_REF; + else{ + for(i = 0; h->delayed_pic[i]; i++) + if(pic == h->delayed_pic[i]){ + pic->reference=DELAYED_PIC_REF; + break; + } + } + return 1; } } @@ -4159,14 +3284,14 @@ static void idr(H264Context *h){ for(i=0; i<16; i++){ if (h->long_ref[i] != NULL) { - unreference_pic(h, h->long_ref[i]); + unreference_pic(h, h->long_ref[i], 0); h->long_ref[i]= NULL; } } h->long_ref_count=0; for(i=0; i<h->short_ref_count; i++){ - unreference_pic(h, h->short_ref[i]); + unreference_pic(h, h->short_ref[i], 0); h->short_ref[i]= NULL; } h->short_ref_count=0; @@ -4187,27 +3312,28 @@ static void flush_dpb(AVCodecContext *avctx){ idr(h); if(h->s.current_picture_ptr) h->s.current_picture_ptr->reference= 0; + h->s.first_field= 0; + ff_mpeg_flush(avctx); } /** - * - * @return the removed picture or NULL if an error occurs + * Find a Picture in the short term reference list by frame number. + * @param frame_num frame number to search for + * @param idx the index into h->short_ref where returned picture is found + * undefined if no picture found. + * @return pointer to the found picture, or NULL if no pic with the provided + * frame number is found */ -static Picture * remove_short(H264Context *h, int frame_num){ +static Picture * find_short(H264Context *h, int frame_num, int *idx){ MpegEncContext * const s = &h->s; int i; - if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count); - for(i=0; i<h->short_ref_count; i++){ Picture *pic= h->short_ref[i]; if(s->avctx->debug&FF_DEBUG_MMCO) av_log(h->s.avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic); - if(pic->frame_num == frame_num){ - h->short_ref[i]= NULL; - memmove(&h->short_ref[i], &h->short_ref[i+1], (h->short_ref_count - i - 1)*sizeof(Picture*)); - h->short_ref_count--; + if(pic->frame_num == frame_num) { + *idx = i; return pic; } } @@ -4215,6 +3341,49 @@ static Picture * remove_short(H264Context *h, int frame_num){ } /** + * Remove a picture from the short term reference list by its index in + * that list. This does no checking on the provided index; it is assumed + * to be valid. Other list entries are shifted down. + * @param i index into h->short_ref of picture to remove. + */ +static void remove_short_at_index(H264Context *h, int i){ + assert(i > 0 && i < h->short_ref_count); + h->short_ref[i]= NULL; + if (--h->short_ref_count) + memmove(&h->short_ref[i], &h->short_ref[i+1], (h->short_ref_count - i)*sizeof(Picture*)); +} + +/** + * + * @return the removed picture or NULL if an error occurs + */ +static Picture * remove_short(H264Context *h, int frame_num){ + MpegEncContext * const s = &h->s; + Picture *pic; + int i; + + if(s->avctx->debug&FF_DEBUG_MMCO) + av_log(h->s.avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count); + + pic = find_short(h, frame_num, &i); + if (pic) + remove_short_at_index(h, i); + + return pic; +} + +/** + * Remove a picture from the long term reference list by its index in + * that list. This does no checking on the provided index; it is assumed + * to be valid. The removed entry is set to NULL. Other entries are unaffected. + * @param i index into h->long_ref of picture to remove. + */ +static void remove_long_at_index(H264Context *h, int i){ + h->long_ref[i]= NULL; + h->long_ref_count--; +} + +/** * * @return the removed picture or NULL if an error occurs */ @@ -4222,8 +3391,8 @@ static Picture * remove_long(H264Context *h, int i){ Picture *pic; pic= h->long_ref[i]; - h->long_ref[i]= NULL; - if(pic) h->long_ref_count--; + if (pic) + remove_long_at_index(h, i); return pic; } @@ -4264,77 +3433,143 @@ static void print_long_term(H264Context *h) { static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ MpegEncContext * const s = &h->s; int i, j; - int current_is_long=0; + int current_ref_assigned=0; Picture *pic; if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0) av_log(h->s.avctx, AV_LOG_DEBUG, "no mmco here\n"); for(i=0; i<mmco_count; i++){ + int structure, frame_num, unref_pic; if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_frame_num, h->mmco[i].long_index); + av_log(h->s.avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg); switch(mmco[i].opcode){ case MMCO_SHORT2UNUSED: - pic= remove_short(h, mmco[i].short_frame_num); - if(pic) - unreference_pic(h, pic); - else if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_short() failure\n"); + if(s->avctx->debug&FF_DEBUG_MMCO) + av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count); + frame_num = pic_num_extract(h, mmco[i].short_pic_num, &structure); + pic = find_short(h, frame_num, &j); + if (pic) { + if (unreference_pic(h, pic, structure ^ PICT_FRAME)) + remove_short_at_index(h, j); + } else if(s->avctx->debug&FF_DEBUG_MMCO) + av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref short failure\n"); break; case MMCO_SHORT2LONG: - pic= remove_long(h, mmco[i].long_index); - if(pic) unreference_pic(h, pic); + if (FIELD_PICTURE && mmco[i].long_arg < h->long_ref_count && + h->long_ref[mmco[i].long_arg]->frame_num == + mmco[i].short_pic_num / 2) { + /* do nothing, we've already moved this field pair. */ + } else { + int frame_num = mmco[i].short_pic_num >> FIELD_PICTURE; - h->long_ref[ mmco[i].long_index ]= remove_short(h, mmco[i].short_frame_num); - if (h->long_ref[ mmco[i].long_index ]){ - h->long_ref[ mmco[i].long_index ]->long_ref=1; - h->long_ref_count++; + pic= remove_long(h, mmco[i].long_arg); + if(pic) unreference_pic(h, pic, 0); + + h->long_ref[ mmco[i].long_arg ]= remove_short(h, frame_num); + if (h->long_ref[ mmco[i].long_arg ]){ + h->long_ref[ mmco[i].long_arg ]->long_ref=1; + h->long_ref_count++; + } } break; case MMCO_LONG2UNUSED: - pic= remove_long(h, mmco[i].long_index); - if(pic) - unreference_pic(h, pic); - else if(s->avctx->debug&FF_DEBUG_MMCO) - av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_long() failure\n"); + j = pic_num_extract(h, mmco[i].long_arg, &structure); + pic = h->long_ref[j]; + if (pic) { + if (unreference_pic(h, pic, structure ^ PICT_FRAME)) + remove_long_at_index(h, j); + } else if(s->avctx->debug&FF_DEBUG_MMCO) + av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref long failure\n"); break; case MMCO_LONG: - pic= remove_long(h, mmco[i].long_index); - if(pic) unreference_pic(h, pic); + unref_pic = 1; + if (FIELD_PICTURE && !s->first_field) { + if (h->long_ref[mmco[i].long_arg] == s->current_picture_ptr) { + /* Just mark second field as referenced */ + unref_pic = 0; + } else if (s->current_picture_ptr->reference) { + /* First field in pair is in short term list or + * at a different long term index. + * This is not allowed; see 7.4.3, notes 2 and 3. + * Report the problem and keep the pair where it is, + * and mark this field valid. + */ + av_log(h->s.avctx, AV_LOG_ERROR, + "illegal long term reference assignment for second " + "field in complementary field pair (first field is " + "short term or has non-matching long index)\n"); + unref_pic = 0; + } + } - h->long_ref[ mmco[i].long_index ]= s->current_picture_ptr; - h->long_ref[ mmco[i].long_index ]->long_ref=1; - h->long_ref_count++; + if (unref_pic) { + pic= remove_long(h, mmco[i].long_arg); + if(pic) unreference_pic(h, pic, 0); - current_is_long=1; + h->long_ref[ mmco[i].long_arg ]= s->current_picture_ptr; + h->long_ref[ mmco[i].long_arg ]->long_ref=1; + h->long_ref_count++; + } + + s->current_picture_ptr->reference |= s->picture_structure; + current_ref_assigned=1; break; case MMCO_SET_MAX_LONG: - assert(mmco[i].long_index <= 16); + assert(mmco[i].long_arg <= 16); // just remove the long term which index is greater than new max - for(j = mmco[i].long_index; j<16; j++){ + for(j = mmco[i].long_arg; j<16; j++){ pic = remove_long(h, j); - if (pic) unreference_pic(h, pic); + if (pic) unreference_pic(h, pic, 0); } break; case MMCO_RESET: while(h->short_ref_count){ pic= remove_short(h, h->short_ref[0]->frame_num); - if(pic) unreference_pic(h, pic); + if(pic) unreference_pic(h, pic, 0); } for(j = 0; j < 16; j++) { pic= remove_long(h, j); - if(pic) unreference_pic(h, pic); + if(pic) unreference_pic(h, pic, 0); } break; default: assert(0); } } - if(!current_is_long){ + if (!current_ref_assigned && FIELD_PICTURE && + !s->first_field && s->current_picture_ptr->reference) { + + /* Second field of complementary field pair; the first field of + * which is already referenced. If short referenced, it + * should be first entry in short_ref. If not, it must exist + * in long_ref; trying to put it on the short list here is an + * error in the encoded bit stream (ref: 7.4.3, NOTE 2 and 3). + */ + if (h->short_ref_count && h->short_ref[0] == s->current_picture_ptr) { + /* Just mark the second field valid */ + s->current_picture_ptr->reference = PICT_FRAME; + } else if (s->current_picture_ptr->long_ref) { + av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term reference " + "assignment for second field " + "in complementary field pair " + "(first field is long term)\n"); + } else { + /* + * First field in reference, but not in any sensible place on our + * reference lists. This shouldn't happen unless reference + * handling somewhere else is wrong. + */ + assert(0); + } + current_ref_assigned = 1; + } + + if(!current_ref_assigned){ pic= remove_short(h, s->current_picture_ptr->frame_num); if(pic){ - unreference_pic(h, pic); + unreference_pic(h, pic, 0); av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); } @@ -4344,6 +3579,32 @@ static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ h->short_ref[0]= s->current_picture_ptr; h->short_ref[0]->long_ref=0; h->short_ref_count++; + s->current_picture_ptr->reference |= s->picture_structure; + } + + if (h->long_ref_count + h->short_ref_count > h->sps.ref_frame_count){ + + /* We have too many reference frames, probably due to corrupted + * stream. Need to discard one frame. Prevents overrun of the + * short_ref and long_ref buffers. + */ + av_log(h->s.avctx, AV_LOG_ERROR, + "number of reference frames exceeds max (probably " + "corrupt input), discarding one\n"); + + if (h->long_ref_count) { + for (i = 0; i < 16; ++i) + if (h->long_ref[i]) + break; + + assert(i < 16); + pic = h->long_ref[i]; + remove_long_at_index(h, i); + } else { + pic = h->short_ref[h->short_ref_count - 1]; + remove_short_at_index(h, h->short_ref_count - 1); + } + unreference_pic(h, pic, 0); } print_short_term(h); @@ -4351,39 +3612,39 @@ static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ return 0; } -static int decode_ref_pic_marking(H264Context *h){ +static int decode_ref_pic_marking(H264Context *h, GetBitContext *gb){ MpegEncContext * const s = &h->s; int i; if(h->nal_unit_type == NAL_IDR_SLICE){ //FIXME fields - s->broken_link= get_bits1(&s->gb) -1; - h->mmco[0].long_index= get_bits1(&s->gb) - 1; // current_long_term_idx - if(h->mmco[0].long_index == -1) + s->broken_link= get_bits1(gb) -1; + h->mmco[0].long_arg= get_bits1(gb) - 1; // current_long_term_idx + if(h->mmco[0].long_arg == -1) h->mmco_index= 0; else{ h->mmco[0].opcode= MMCO_LONG; h->mmco_index= 1; } }else{ - if(get_bits1(&s->gb)){ // adaptive_ref_pic_marking_mode_flag + if(get_bits1(gb)){ // adaptive_ref_pic_marking_mode_flag for(i= 0; i<MAX_MMCO_COUNT; i++) { - MMCOOpcode opcode= get_ue_golomb(&s->gb);; + MMCOOpcode opcode= get_ue_golomb(gb); h->mmco[i].opcode= opcode; if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG){ - h->mmco[i].short_frame_num= (h->frame_num - get_ue_golomb(&s->gb) - 1) & ((1<<h->sps.log2_max_frame_num)-1); //FIXME fields -/* if(h->mmco[i].short_frame_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_frame_num ] == NULL){ + h->mmco[i].short_pic_num= (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1); +/* if(h->mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_pic_num ] == NULL){ av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control operation %d\n", mmco); return -1; }*/ } if(opcode==MMCO_SHORT2LONG || opcode==MMCO_LONG2UNUSED || opcode==MMCO_LONG || opcode==MMCO_SET_MAX_LONG){ - unsigned int long_index= get_ue_golomb(&s->gb); - if(/*h->mmco[i].long_index >= h->long_ref_count || h->long_ref[ h->mmco[i].long_index ] == NULL*/ long_index >= 16){ + unsigned int long_arg= get_ue_golomb(gb); + if(long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal long ref in memory management control operation %d\n", opcode); return -1; } - h->mmco[i].long_index= long_index; + h->mmco[i].long_arg= long_arg; } if(opcode > (unsigned)MMCO_LONG){ @@ -4397,10 +3658,17 @@ static int decode_ref_pic_marking(H264Context *h){ }else{ assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count); - if(h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count){ //FIXME fields + if(h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count && + !(FIELD_PICTURE && !s->first_field && s->current_picture_ptr->reference)) { h->mmco[0].opcode= MMCO_SHORT2UNUSED; - h->mmco[0].short_frame_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num; + h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num; h->mmco_index= 1; + if (FIELD_PICTURE) { + h->mmco[0].short_pic_num *= 2; + h->mmco[1].opcode= MMCO_SHORT2UNUSED; + h->mmco[1].short_pic_num= h->mmco[0].short_pic_num + 1; + h->mmco_index= 2; + } }else h->mmco_index= 0; } @@ -4488,37 +3756,135 @@ static int init_poc(H264Context *h){ field_poc[1]= poc; } - if(s->picture_structure != PICT_BOTTOM_FIELD) + if(s->picture_structure != PICT_BOTTOM_FIELD) { s->current_picture_ptr->field_poc[0]= field_poc[0]; - if(s->picture_structure != PICT_TOP_FIELD) + s->current_picture_ptr->poc = field_poc[0]; + } + if(s->picture_structure != PICT_TOP_FIELD) { s->current_picture_ptr->field_poc[1]= field_poc[1]; - if(s->picture_structure == PICT_FRAME) // FIXME field pix? - s->current_picture_ptr->poc= FFMIN(field_poc[0], field_poc[1]); + s->current_picture_ptr->poc = field_poc[1]; + } + if(!FIELD_PICTURE || !s->first_field) { + Picture *cur = s->current_picture_ptr; + cur->poc= FFMIN(cur->field_poc[0], cur->field_poc[1]); + } return 0; } + +/** + * initialize scan tables + */ +static void init_scan_tables(H264Context *h){ + MpegEncContext * const s = &h->s; + int i; + if(s->dsp.h264_idct_add == ff_h264_idct_add_c){ //FIXME little ugly + memcpy(h->zigzag_scan, zigzag_scan, 16*sizeof(uint8_t)); + memcpy(h-> field_scan, field_scan, 16*sizeof(uint8_t)); + }else{ + for(i=0; i<16; i++){ +#define T(x) (x>>2) | ((x<<2) & 0xF) + h->zigzag_scan[i] = T(zigzag_scan[i]); + h-> field_scan[i] = T( field_scan[i]); +#undef T + } + } + if(s->dsp.h264_idct8_add == ff_h264_idct8_add_c){ + memcpy(h->zigzag_scan8x8, zigzag_scan8x8, 64*sizeof(uint8_t)); + memcpy(h->zigzag_scan8x8_cavlc, zigzag_scan8x8_cavlc, 64*sizeof(uint8_t)); + memcpy(h->field_scan8x8, field_scan8x8, 64*sizeof(uint8_t)); + memcpy(h->field_scan8x8_cavlc, field_scan8x8_cavlc, 64*sizeof(uint8_t)); + }else{ + for(i=0; i<64; i++){ +#define T(x) (x>>3) | ((x&7)<<3) + h->zigzag_scan8x8[i] = T(zigzag_scan8x8[i]); + h->zigzag_scan8x8_cavlc[i] = T(zigzag_scan8x8_cavlc[i]); + h->field_scan8x8[i] = T(field_scan8x8[i]); + h->field_scan8x8_cavlc[i] = T(field_scan8x8_cavlc[i]); +#undef T + } + } + if(h->sps.transform_bypass){ //FIXME same ugly + h->zigzag_scan_q0 = zigzag_scan; + h->zigzag_scan8x8_q0 = zigzag_scan8x8; + h->zigzag_scan8x8_cavlc_q0 = zigzag_scan8x8_cavlc; + h->field_scan_q0 = field_scan; + h->field_scan8x8_q0 = field_scan8x8; + h->field_scan8x8_cavlc_q0 = field_scan8x8_cavlc; + }else{ + h->zigzag_scan_q0 = h->zigzag_scan; + h->zigzag_scan8x8_q0 = h->zigzag_scan8x8; + h->zigzag_scan8x8_cavlc_q0 = h->zigzag_scan8x8_cavlc; + h->field_scan_q0 = h->field_scan; + h->field_scan8x8_q0 = h->field_scan8x8; + h->field_scan8x8_cavlc_q0 = h->field_scan8x8_cavlc; + } +} + +/** + * Replicates H264 "master" context to thread contexts. + */ +static void clone_slice(H264Context *dst, H264Context *src) +{ + memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset)); + dst->s.current_picture_ptr = src->s.current_picture_ptr; + dst->s.current_picture = src->s.current_picture; + dst->s.linesize = src->s.linesize; + dst->s.uvlinesize = src->s.uvlinesize; + dst->s.first_field = src->s.first_field; + + dst->prev_poc_msb = src->prev_poc_msb; + dst->prev_poc_lsb = src->prev_poc_lsb; + dst->prev_frame_num_offset = src->prev_frame_num_offset; + dst->prev_frame_num = src->prev_frame_num; + dst->short_ref_count = src->short_ref_count; + + memcpy(dst->short_ref, src->short_ref, sizeof(dst->short_ref)); + memcpy(dst->long_ref, src->long_ref, sizeof(dst->long_ref)); + memcpy(dst->default_ref_list, src->default_ref_list, sizeof(dst->default_ref_list)); + memcpy(dst->ref_list, src->ref_list, sizeof(dst->ref_list)); + + memcpy(dst->dequant4_coeff, src->dequant4_coeff, sizeof(src->dequant4_coeff)); + memcpy(dst->dequant8_coeff, src->dequant8_coeff, sizeof(src->dequant8_coeff)); +} + /** * decodes a slice header. * this will allso call MPV_common_init() and frame_start() as needed + * + * @param h h264context + * @param h0 h264 master context (differs from 'h' when doing sliced based parallel decoding) + * + * @return 0 if okay, <0 if an error occured, 1 if decoding must not be multithreaded */ -static int decode_slice_header(H264Context *h){ +static int decode_slice_header(H264Context *h, H264Context *h0){ MpegEncContext * const s = &h->s; + MpegEncContext * const s0 = &h0->s; unsigned int first_mb_in_slice; unsigned int pps_id; int num_ref_idx_active_override_flag; static const uint8_t slice_type_map[5]= {P_TYPE, B_TYPE, I_TYPE, SP_TYPE, SI_TYPE}; - unsigned int slice_type, tmp; + unsigned int slice_type, tmp, i; int default_ref_list_done = 0; + int last_pic_structure; - s->current_picture.reference= h->nal_ref_idc != 0; s->dropable= h->nal_ref_idc == 0; + if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !h->nal_ref_idc){ + s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab; + s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab; + }else{ + s->me.qpel_put= s->dsp.put_h264_qpel_pixels_tab; + s->me.qpel_avg= s->dsp.avg_h264_qpel_pixels_tab; + } + first_mb_in_slice= get_ue_golomb(&s->gb); if((s->flags2 & CODEC_FLAG2_CHUNKS) && first_mb_in_slice == 0){ - h->slice_num = 0; - s->current_picture_ptr= NULL; + h0->current_slice = 0; + if (!s0->first_field) + s->current_picture_ptr= NULL; } slice_type= get_ue_golomb(&s->gb); @@ -4534,31 +3900,36 @@ static int decode_slice_header(H264Context *h){ slice_type= slice_type_map[ slice_type ]; if (slice_type == I_TYPE - || (h->slice_num != 0 && slice_type == h->slice_type) ) { + || (h0->current_slice != 0 && slice_type == h0->last_slice_type) ) { default_ref_list_done = 1; } h->slice_type= slice_type; s->pict_type= h->slice_type; // to make a few old func happy, it's wrong though + if (s->pict_type == B_TYPE && s0->last_picture_ptr == NULL) { + av_log(h->s.avctx, AV_LOG_ERROR, + "B picture before any references, skipping\n"); + return -1; + } pps_id= get_ue_golomb(&s->gb); if(pps_id>=MAX_PPS_COUNT){ av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); return -1; } - h->pps= h->pps_buffer[pps_id]; - if(h->pps.slice_group_count == 0){ + if(!h0->pps_buffers[pps_id]) { av_log(h->s.avctx, AV_LOG_ERROR, "non existing PPS referenced\n"); return -1; } + h->pps= *h0->pps_buffers[pps_id]; - h->sps= h->sps_buffer[ h->pps.sps_id ]; - if(h->sps.log2_max_frame_num == 0){ + if(!h0->sps_buffers[h->pps.sps_id]) { av_log(h->s.avctx, AV_LOG_ERROR, "non existing SPS referenced\n"); return -1; } + h->sps = *h0->sps_buffers[h->pps.sps_id]; - if(h->dequant_coeff_pps != pps_id){ + if(h == h0 && h->dequant_coeff_pps != pps_id){ h->dequant_coeff_pps = pps_id; init_dequant_tables(h); } @@ -4577,58 +3948,35 @@ static int decode_slice_header(H264Context *h){ if (s->context_initialized && ( s->width != s->avctx->width || s->height != s->avctx->height)) { + if(h != h0) + return -1; // width / height changed during parallelized decoding free_tables(h); MPV_common_end(s); } if (!s->context_initialized) { + if(h != h0) + return -1; // we cant (re-)initialize context during parallel decoding if (MPV_common_init(s) < 0) return -1; + s->first_field = 0; - if(s->dsp.h264_idct_add == ff_h264_idct_add_c){ //FIXME little ugly - memcpy(h->zigzag_scan, zigzag_scan, 16*sizeof(uint8_t)); - memcpy(h-> field_scan, field_scan, 16*sizeof(uint8_t)); - }else{ - int i; - for(i=0; i<16; i++){ -#define T(x) (x>>2) | ((x<<2) & 0xF) - h->zigzag_scan[i] = T(zigzag_scan[i]); - h-> field_scan[i] = T( field_scan[i]); -#undef T - } - } - if(s->dsp.h264_idct8_add == ff_h264_idct8_add_c){ - memcpy(h->zigzag_scan8x8, zigzag_scan8x8, 64*sizeof(uint8_t)); - memcpy(h->zigzag_scan8x8_cavlc, zigzag_scan8x8_cavlc, 64*sizeof(uint8_t)); - memcpy(h->field_scan8x8, field_scan8x8, 64*sizeof(uint8_t)); - memcpy(h->field_scan8x8_cavlc, field_scan8x8_cavlc, 64*sizeof(uint8_t)); - }else{ - int i; - for(i=0; i<64; i++){ -#define T(x) (x>>3) | ((x&7)<<3) - h->zigzag_scan8x8[i] = T(zigzag_scan8x8[i]); - h->zigzag_scan8x8_cavlc[i] = T(zigzag_scan8x8_cavlc[i]); - h->field_scan8x8[i] = T(field_scan8x8[i]); - h->field_scan8x8_cavlc[i] = T(field_scan8x8_cavlc[i]); -#undef T - } - } - if(h->sps.transform_bypass){ //FIXME same ugly - h->zigzag_scan_q0 = zigzag_scan; - h->zigzag_scan8x8_q0 = zigzag_scan8x8; - h->zigzag_scan8x8_cavlc_q0 = zigzag_scan8x8_cavlc; - h->field_scan_q0 = field_scan; - h->field_scan8x8_q0 = field_scan8x8; - h->field_scan8x8_cavlc_q0 = field_scan8x8_cavlc; - }else{ - h->zigzag_scan_q0 = h->zigzag_scan; - h->zigzag_scan8x8_q0 = h->zigzag_scan8x8; - h->zigzag_scan8x8_cavlc_q0 = h->zigzag_scan8x8_cavlc; - h->field_scan_q0 = h->field_scan; - h->field_scan8x8_q0 = h->field_scan8x8; - h->field_scan8x8_cavlc_q0 = h->field_scan8x8_cavlc; + init_scan_tables(h); + alloc_tables(h); + + for(i = 1; i < s->avctx->thread_count; i++) { + H264Context *c; + c = h->thread_context[i] = av_malloc(sizeof(H264Context)); + memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext)); + memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext)); + c->sps = h->sps; + c->pps = h->pps; + init_scan_tables(c); + clone_tables(c, h); } - alloc_tables(h); + for(i = 0; i < s->avctx->thread_count; i++) + if(context_init(h->thread_context[i]) < 0) + return -1; s->avctx->width = s->width; s->avctx->height = s->height; @@ -4645,42 +3993,90 @@ static int decode_slice_header(H264Context *h){ } } - if(h->slice_num == 0){ - if(frame_start(h) < 0) - return -1; - } - - s->current_picture_ptr->frame_num= //FIXME frame_num cleanup h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num); h->mb_mbaff = 0; h->mb_aff_frame = 0; + last_pic_structure = s0->picture_structure; if(h->sps.frame_mbs_only_flag){ s->picture_structure= PICT_FRAME; }else{ if(get_bits1(&s->gb)) { //field_pic_flag s->picture_structure= PICT_TOP_FIELD + get_bits1(&s->gb); //bottom_field_flag - av_log(h->s.avctx, AV_LOG_ERROR, "PAFF interlacing is not implemented\n"); } else { s->picture_structure= PICT_FRAME; h->mb_aff_frame = h->sps.mb_aff; } } + + if(h0->current_slice == 0){ + /* See if we have a decoded first field looking for a pair... */ + if (s0->first_field) { + assert(s0->current_picture_ptr); + assert(s0->current_picture_ptr->data[0]); + assert(s0->current_picture_ptr->reference != DELAYED_PIC_REF); + + /* figure out if we have a complementary field pair */ + if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) { + /* + * Previous field is unmatched. Don't display it, but let it + * remain for reference if marked as such. + */ + s0->current_picture_ptr = NULL; + s0->first_field = FIELD_PICTURE; + + } else { + if (h->nal_ref_idc && + s0->current_picture_ptr->reference && + s0->current_picture_ptr->frame_num != h->frame_num) { + /* + * This and previous field were reference, but had + * different frame_nums. Consider this field first in + * pair. Throw away previous field except for reference + * purposes. + */ + s0->first_field = 1; + s0->current_picture_ptr = NULL; + + } else { + /* Second field in complementary pair */ + s0->first_field = 0; + } + } + + } else { + /* Frame or first field in a potentially complementary pair */ + assert(!s0->current_picture_ptr); + s0->first_field = FIELD_PICTURE; + } + + if((!FIELD_PICTURE || s0->first_field) && frame_start(h) < 0) { + s0->first_field = 0; + return -1; + } + } + if(h != h0) + clone_slice(h, h0); + + s->current_picture_ptr->frame_num= h->frame_num; //FIXME frame_num cleanup + assert(s->mb_num == s->mb_width * s->mb_height); - if(first_mb_in_slice << h->mb_aff_frame >= s->mb_num || + if(first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= s->mb_num || first_mb_in_slice >= s->mb_num){ av_log(h->s.avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n"); return -1; } s->resync_mb_x = s->mb_x = first_mb_in_slice % s->mb_width; - s->resync_mb_y = s->mb_y = (first_mb_in_slice / s->mb_width) << h->mb_aff_frame; + s->resync_mb_y = s->mb_y = (first_mb_in_slice / s->mb_width) << FIELD_OR_MBAFF_PICTURE; + if (s->picture_structure == PICT_BOTTOM_FIELD) + s->resync_mb_y = s->mb_y = s->mb_y + 1; assert(s->mb_y < s->mb_height); if(s->picture_structure==PICT_FRAME){ h->curr_pic_num= h->frame_num; h->max_pic_num= 1<< h->sps.log2_max_frame_num; }else{ - h->curr_pic_num= 2*h->frame_num; + h->curr_pic_num= 2*h->frame_num + 1; h->max_pic_num= 1<<(h->sps.log2_max_frame_num + 1); } @@ -4716,8 +4112,6 @@ static int decode_slice_header(H264Context *h){ if(h->slice_type == P_TYPE || h->slice_type == SP_TYPE || h->slice_type == B_TYPE){ if(h->slice_type == B_TYPE){ h->direct_spatial_mv_pred= get_bits1(&s->gb); - if(h->sps.mb_aff && h->direct_spatial_mv_pred) - av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF + spatial direct mode is not implemented\n"); } num_ref_idx_active_override_flag= get_bits1(&s->gb); @@ -4754,8 +4148,8 @@ static int decode_slice_header(H264Context *h){ else h->use_weight = 0; - if(s->current_picture.reference) - decode_ref_pic_marking(h); + if(h->nal_ref_idc) + decode_ref_pic_marking(h0, &s->gb); if(FRAME_MBAFF) fill_mbaff_ref_list(h); @@ -4776,7 +4170,8 @@ static int decode_slice_header(H264Context *h){ return -1; } s->qscale= tmp; - h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, s->qscale); + h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale); + h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale); //FIXME qscale / qp ... stuff if(h->slice_type == SP_TYPE){ get_bits1(&s->gb); /* sp_for_switch_flag */ @@ -4803,21 +4198,39 @@ static int decode_slice_header(H264Context *h){ h->slice_beta_offset = get_se_golomb(&s->gb) << 1; } } + if( s->avctx->skip_loop_filter >= AVDISCARD_ALL ||(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY && h->slice_type != I_TYPE) ||(s->avctx->skip_loop_filter >= AVDISCARD_BIDIR && h->slice_type == B_TYPE) ||(s->avctx->skip_loop_filter >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) h->deblocking_filter= 0; + if(h->deblocking_filter == 1 && h0->max_contexts > 1) { + if(s->avctx->flags2 & CODEC_FLAG2_FAST) { + /* Cheat slightly for speed: + Do not bother to deblock across slices. */ + h->deblocking_filter = 2; + } else { + h0->max_contexts = 1; + if(!h0->single_decode_warning) { + av_log(s->avctx, AV_LOG_INFO, "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n"); + h0->single_decode_warning = 1; + } + if(h != h0) + return 1; // deblocking switched inside frame + } + } + #if 0 //FMO if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5) slice_group_change_cycle= get_bits(&s->gb, ?); #endif - h->slice_num++; + h0->last_slice_type = slice_type; + h->slice_num = ++h0->current_slice; h->emu_edge_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16; - h->emu_edge_height= FRAME_MBAFF ? 0 : h->emu_edge_width; + h->emu_edge_height= (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width; if(s->avctx->debug&FF_DEBUG_PICT_INFO){ av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s\n", @@ -4835,14 +4248,6 @@ static int decode_slice_header(H264Context *h){ ); } - if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !s->current_picture.reference){ - s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab; - }else{ - s->me.qpel_put= s->dsp.put_h264_qpel_pixels_tab; - s->me.qpel_avg= s->dsp.avg_h264_qpel_pixels_tab; - } - return 0; } @@ -5161,7 +4566,7 @@ decode_intra_mb: if(IS_INTRA_PCM(mb_type)){ unsigned int x, y; - // we assume these blocks are very rare so we dont optimize it + // We assume these blocks are very rare so we do not optimize it. align_get_bits(&s->gb); // The pixels are stored in the same order as levels in h->mb array. @@ -5189,7 +4594,8 @@ decode_intra_mb: // In deblocking, the quantizer is 0 s->current_picture.qscale_table[mb_xy]= 0; - h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, 0); + h->chroma_qp[0] = get_chroma_qp(h, 0, 0); + h->chroma_qp[1] = get_chroma_qp(h, 1, 0); // All coeffs are present memset(h->non_zero_count[mb_xy], 16, 16); @@ -5299,8 +4705,6 @@ decode_intra_mb: dct8x8_allowed = get_dct8x8_allowed(h); for(list=0; list<h->list_count; list++){ - const int ref_count= IS_REF0(mb_type) ? 1 : h->ref_count[list]; - for(i=0; i<4; i++){ if(IS_DIRECT(h->sub_mb_type[i])) { h->ref_cache[list][ scan8[4*i] ] = h->ref_cache[list][ scan8[4*i]+1 ]; @@ -5465,7 +4869,7 @@ decode_intra_mb: if(cbp || IS_INTRA16x16(mb_type)){ int i8x8, i4x4, chroma_idx; - int chroma_qp, dquant; + int dquant; GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr; const uint8_t *scan, *scan8x8, *dc_scan; @@ -5494,7 +4898,8 @@ decode_intra_mb: else s->qscale-= 52; } - h->chroma_qp= chroma_qp= get_chroma_qp(h->pps.chroma_qp_index_offset, s->qscale); + h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale); + h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale); if(IS_INTRA16x16(mb_type)){ if( decode_residual(h, h->intra_gb_ptr, h->mb, LUMA_DC_BLOCK_INDEX, dc_scan, h->dequant4_coeff[0][s->qscale], 16) < 0){ return -1; //FIXME continue if partitioned and other return -1 too @@ -5552,9 +4957,10 @@ decode_intra_mb: if(cbp&0x20){ for(chroma_idx=0; chroma_idx<2; chroma_idx++){ + const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]]; for(i4x4=0; i4x4<4; i4x4++){ const int index= 16 + 4*chroma_idx + i4x4; - if( decode_residual(h, gb, h->mb + 16*index, index, scan + 1, h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][chroma_qp], 15) < 0){ + if( decode_residual(h, gb, h->mb + 16*index, index, scan + 1, qmul, 15) < 0){ return -1; } } @@ -5713,7 +5119,7 @@ static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) { }else{ int mb_xy = mb_x + mb_y*s->mb_stride; mba_xy = mb_xy - 1; - mbb_xy = mb_xy - s->mb_stride; + mbb_xy = mb_xy - (s->mb_stride << FIELD_PICTURE); } if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mba_xy] )) @@ -5766,65 +5172,20 @@ static int decode_cabac_mb_chroma_pre_mode( H264Context *h) { return 3; } -static const uint8_t block_idx_x[16] = { - 0, 1, 0, 1, 2, 3, 2, 3, 0, 1, 0, 1, 2, 3, 2, 3 -}; -static const uint8_t block_idx_y[16] = { - 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 -}; -static const uint8_t block_idx_xy[4][4] = { - { 0, 2, 8, 10}, - { 1, 3, 9, 11}, - { 4, 6, 12, 14}, - { 5, 7, 13, 15} -}; - static int decode_cabac_mb_cbp_luma( H264Context *h) { - int cbp = 0; - int cbp_b = -1; - int i8x8; - - if( h->slice_table[h->top_mb_xy] == h->slice_num ) { - cbp_b = h->top_cbp; - tprintf(h->s.avctx, "cbp_b = top_cbp = %x\n", cbp_b); - } - - for( i8x8 = 0; i8x8 < 4; i8x8++ ) { - int cbp_a = -1; - int x, y; - int ctx = 0; - - x = block_idx_x[4*i8x8]; - y = block_idx_y[4*i8x8]; - - if( x > 0 ) - cbp_a = cbp; - else if( h->slice_table[h->left_mb_xy[0]] == h->slice_num ) { - cbp_a = h->left_cbp; - tprintf(h->s.avctx, "cbp_a = left_cbp = %x\n", cbp_a); - } - - if( y > 0 ) - cbp_b = cbp; - - /* No need to test for skip as we put 0 for skip block */ - /* No need to test for IPCM as we put 1 for IPCM block */ - if( cbp_a >= 0 ) { - int i8x8a = block_idx_xy[(x-1)&0x03][y]/4; - if( ((cbp_a >> i8x8a)&0x01) == 0 ) - ctx++; - } - - if( cbp_b >= 0 ) { - int i8x8b = block_idx_xy[x][(y-1)&0x03]/4; - if( ((cbp_b >> i8x8b)&0x01) == 0 ) - ctx += 2; - } - - if( get_cabac( &h->cabac, &h->cabac_state[73 + ctx] ) ) { - cbp |= 1 << i8x8; - } - } + int cbp_b, cbp_a, ctx, cbp = 0; + + cbp_a = h->slice_table[h->left_mb_xy[0]] == h->slice_num ? h->left_cbp : -1; + cbp_b = h->slice_table[h->top_mb_xy] == h->slice_num ? h->top_cbp : -1; + + ctx = !(cbp_a & 0x02) + 2 * !(cbp_b & 0x04); + cbp |= get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]); + ctx = !(cbp & 0x01) + 2 * !(cbp_b & 0x08); + cbp |= get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]) << 1; + ctx = !(cbp_a & 0x08) + 2 * !(cbp & 0x01); + cbp |= get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]) << 2; + ctx = !(cbp & 0x04) + 2 * !(cbp & 0x02); + cbp |= get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]) << 3; return cbp; } static int decode_cabac_mb_cbp_chroma( H264Context *h) { @@ -5846,16 +5207,9 @@ static int decode_cabac_mb_cbp_chroma( H264Context *h) { return 1 + get_cabac_noinline( &h->cabac, &h->cabac_state[77 + ctx] ); } static int decode_cabac_mb_dqp( H264Context *h) { - MpegEncContext * const s = &h->s; - int mbn_xy; int ctx = 0; int val = 0; - if( s->mb_x > 0 ) - mbn_xy = s->mb_x + s->mb_y*s->mb_stride - 1; - else - mbn_xy = s->mb_width - 1 + (s->mb_y-1)*s->mb_stride; - if( h->last_qscale_diff != 0 ) ctx++; @@ -5978,7 +5332,7 @@ static int decode_cabac_mb_mvd( H264Context *h, int list, int n, int l ) { return get_cabac_bypass_sign( &h->cabac, -mvd ); } -static int inline get_cabac_cbf_ctx( H264Context *h, int cat, int idx ) { +static inline int get_cabac_cbf_ctx( H264Context *h, int cat, int idx ) { int nza, nzb; int ctx = 0; @@ -6006,14 +5360,14 @@ static int inline get_cabac_cbf_ctx( H264Context *h, int cat, int idx ) { return ctx + 4 * cat; } -static const __attribute((used)) uint8_t last_coeff_flag_offset_8x8[63] = { +DECLARE_ASM_CONST(1, const uint8_t, last_coeff_flag_offset_8x8[63]) = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8 }; -static int decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff) { +static void decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff) { const int mb_xy = h->s.mb_x + h->s.mb_y*h->s.mb_stride; static const int significant_coeff_flag_offset[2][6] = { { 105+0, 105+15, 105+29, 105+44, 105+47, 402 }, @@ -6039,7 +5393,7 @@ static int decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n int index[64]; - int last; + int av_unused last; int coeff_count = 0; int abslevel1 = 1; @@ -6083,7 +5437,7 @@ static int decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n h->cabac.low = cc.low ; h->cabac.bytestream= cc.bytestream; #endif - return 0; + return; } } @@ -6111,7 +5465,7 @@ static int decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n index[coeff_count++] = last;\ } const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD]; -#if defined(ARCH_X86) && defined(CONFIG_7REGS) && defined(CONFIG_EBX_AVAILABLE) && !( defined(ARCH_X86_64) && defined(PIC) ) +#if defined(ARCH_X86) && defined(HAVE_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS) coeff_count= decode_significance_8x8_x86(CC, significant_coeff_ctx_base, index, sig_off); } else { coeff_count= decode_significance_x86(CC, max_coeff, significant_coeff_ctx_base, index); @@ -6144,7 +5498,7 @@ static int decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n if( !qmul ) { block[j] = get_cabac_bypass_sign( CC, -1); }else{ - block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6;; + block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; } abslevel1++; @@ -6184,10 +5538,10 @@ static int decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n h->cabac.low = cc.low ; h->cabac.bytestream= cc.bytestream; #endif - return 0; + } -static void inline compute_mb_neighbors(H264Context *h) +static inline void compute_mb_neighbors(H264Context *h) { MpegEncContext * const s = &h->s; const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; @@ -6209,6 +5563,8 @@ static void inline compute_mb_neighbors(H264Context *h) if (left_mb_frame_flag != curr_mb_frame_flag) { h->left_mb_xy[0] = pair_xy - 1; } + } else if (FIELD_PICTURE) { + h->top_mb_xy -= s->mb_stride; } return; } @@ -6304,7 +5660,7 @@ decode_intra_mb: const uint8_t *ptr; unsigned int x, y; - // We assume these blocks are very rare so we dont optimize it. + // We assume these blocks are very rare so we do not optimize it. // FIXME The two following lines get the bitstream position in the cabac // decode, I think it should be done by a function in cabac.h (or cabac.c). ptr= h->cabac.bytestream; @@ -6343,7 +5699,8 @@ decode_intra_mb: h->chroma_pred_mode_table[mb_xy] = 0; // In deblocking, the quantizer is 0 s->current_picture.qscale_table[mb_xy]= 0; - h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, 0); + h->chroma_qp[0] = get_chroma_qp(h, 0, 0); + h->chroma_qp[1] = get_chroma_qp(h, 1, 0); // All coeffs are present memset(h->non_zero_count[mb_xy], 16, 16); s->current_picture.mb_type[mb_xy]= mb_type; @@ -6399,6 +5756,10 @@ decode_intra_mb: if( IS_DIRECT(h->sub_mb_type[0] | h->sub_mb_type[1] | h->sub_mb_type[2] | h->sub_mb_type[3]) ) { pred_direct_motion(h, &mb_type); + h->ref_cache[0][scan8[4]] = + h->ref_cache[1][scan8[4]] = + h->ref_cache[0][scan8[12]] = + h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE; if( h->ref_count[0] > 1 || h->ref_count[1] > 1 ) { for( i = 0; i < 4; i++ ) if( IS_DIRECT(h->sub_mb_type[i]) ) @@ -6434,11 +5795,11 @@ decode_intra_mb: for(list=0; list<h->list_count; list++){ for(i=0; i<4; i++){ + h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ]; if(IS_DIRECT(h->sub_mb_type[i])){ fill_rectangle(h->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 4); continue; } - h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ]; if(IS_DIR(h->sub_mb_type[i], 0, list) && !IS_DIRECT(h->sub_mb_type[i])){ const int sub_mb_type= h->sub_mb_type[i]; @@ -6597,6 +5958,7 @@ decode_intra_mb: if( cbp || IS_INTRA16x16( mb_type ) ) { const uint8_t *scan, *scan8x8, *dc_scan; + const uint32_t *qmul; int dqp; if(IS_INTERLACED(mb_type)){ @@ -6619,18 +5981,19 @@ decode_intra_mb: if(s->qscale<0) s->qscale+= 52; else s->qscale-= 52; } - h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, s->qscale); + h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale); + h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale); if( IS_INTRA16x16( mb_type ) ) { int i; //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 DC\n" ); - if( decode_cabac_residual( h, h->mb, 0, 0, dc_scan, NULL, 16) < 0) - return -1; + decode_cabac_residual( h, h->mb, 0, 0, dc_scan, NULL, 16); + if( cbp&15 ) { + qmul = h->dequant4_coeff[0][s->qscale]; for( i = 0; i < 16; i++ ) { //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 AC:%d\n", i ); - if( decode_cabac_residual(h, h->mb + 16*i, 1, i, scan + 1, h->dequant4_coeff[0][s->qscale], 15) < 0 ) - return -1; + decode_cabac_residual(h, h->mb + 16*i, 1, i, scan + 1, qmul, 15); } } else { fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1); @@ -6640,17 +6003,17 @@ decode_intra_mb: for( i8x8 = 0; i8x8 < 4; i8x8++ ) { if( cbp & (1<<i8x8) ) { if( IS_8x8DCT(mb_type) ) { - if( decode_cabac_residual(h, h->mb + 64*i8x8, 5, 4*i8x8, - scan8x8, h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 64) < 0 ) - return -1; - } else - for( i4x4 = 0; i4x4 < 4; i4x4++ ) { - const int index = 4*i8x8 + i4x4; - //av_log( s->avctx, AV_LOG_ERROR, "Luma4x4: %d\n", index ); + decode_cabac_residual(h, h->mb + 64*i8x8, 5, 4*i8x8, + scan8x8, h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 64); + } else { + qmul = h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale]; + for( i4x4 = 0; i4x4 < 4; i4x4++ ) { + const int index = 4*i8x8 + i4x4; + //av_log( s->avctx, AV_LOG_ERROR, "Luma4x4: %d\n", index ); //START_TIMER - if( decode_cabac_residual(h, h->mb + 16*index, 2, index, scan, h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale], 16) < 0 ) - return -1; + decode_cabac_residual(h, h->mb + 16*index, 2, index, scan, qmul, 16); //STOP_TIMER("decode_residual") + } } } else { uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ]; @@ -6663,19 +6026,18 @@ decode_intra_mb: int c; for( c = 0; c < 2; c++ ) { //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c ); - if( decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, NULL, 4) < 0) - return -1; + decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, NULL, 4); } } if( cbp&0x20 ) { int c, i; for( c = 0; c < 2; c++ ) { + qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[c]]; for( i = 0; i < 4; i++ ) { const int index = 16 + 4 * c + i; //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-AC %d\n",c, index - 16 ); - if( decode_cabac_residual(h, h->mb + 16*index, 4, index - 16, scan + 1, h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp], 15) < 0) - return -1; + decode_cabac_residual(h, h->mb + 16*index, 4, index - 16, scan + 1, qmul, 15); } } } else { @@ -7009,23 +6371,27 @@ static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int16_t static void filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) { MpegEncContext * const s = &h->s; + int mb_y_firstrow = s->picture_structure == PICT_BOTTOM_FIELD; int mb_xy, mb_type; int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh; - if(mb_x==0 || mb_y==0 || !s->dsp.h264_loop_filter_strength) { + mb_xy = mb_x + mb_y*s->mb_stride; + + if(mb_x==0 || mb_y==mb_y_firstrow || !s->dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff || + (h->deblocking_filter == 2 && (h->slice_table[mb_xy] != h->slice_table[h->top_mb_xy] || + h->slice_table[mb_xy] != h->slice_table[mb_xy - 1]))) { filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize); return; } assert(!FRAME_MBAFF); - mb_xy = mb_x + mb_y*s->mb_stride; mb_type = s->current_picture.mb_type[mb_xy]; qp = s->current_picture.qscale_table[mb_xy]; qp0 = s->current_picture.qscale_table[mb_xy-1]; qp1 = s->current_picture.qscale_table[h->top_mb_xy]; - qpc = get_chroma_qp( h->pps.chroma_qp_index_offset, qp ); - qpc0 = get_chroma_qp( h->pps.chroma_qp_index_offset, qp0 ); - qpc1 = get_chroma_qp( h->pps.chroma_qp_index_offset, qp1 ); + qpc = get_chroma_qp( h, 0, qp ); + qpc0 = get_chroma_qp( h, 0, qp0 ); + qpc1 = get_chroma_qp( h, 0, qp1 ); qp0 = (qp + qp0 + 1) >> 1; qp1 = (qp + qp1 + 1) >> 1; qpc0 = (qpc + qpc0 + 1) >> 1; @@ -7038,17 +6404,18 @@ static void filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, if( IS_INTRA(mb_type) ) { int16_t bS4[4] = {4,4,4,4}; int16_t bS3[4] = {3,3,3,3}; + int16_t *bSH = FIELD_PICTURE ? bS3 : bS4; if( IS_8x8DCT(mb_type) ) { filter_mb_edgev( h, &img_y[4*0], linesize, bS4, qp0 ); filter_mb_edgev( h, &img_y[4*2], linesize, bS3, qp ); - filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bS4, qp1 ); + filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bSH, qp1 ); filter_mb_edgeh( h, &img_y[4*2*linesize], linesize, bS3, qp ); } else { filter_mb_edgev( h, &img_y[4*0], linesize, bS4, qp0 ); filter_mb_edgev( h, &img_y[4*1], linesize, bS3, qp ); filter_mb_edgev( h, &img_y[4*2], linesize, bS3, qp ); filter_mb_edgev( h, &img_y[4*3], linesize, bS3, qp ); - filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bS4, qp1 ); + filter_mb_edgeh( h, &img_y[4*0*linesize], linesize, bSH, qp1 ); filter_mb_edgeh( h, &img_y[4*1*linesize], linesize, bS3, qp ); filter_mb_edgeh( h, &img_y[4*2*linesize], linesize, bS3, qp ); filter_mb_edgeh( h, &img_y[4*3*linesize], linesize, bS3, qp ); @@ -7057,9 +6424,9 @@ static void filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, filter_mb_edgecv( h, &img_cb[2*2], uvlinesize, bS3, qpc ); filter_mb_edgecv( h, &img_cr[2*0], uvlinesize, bS4, qpc0 ); filter_mb_edgecv( h, &img_cr[2*2], uvlinesize, bS3, qpc ); - filter_mb_edgech( h, &img_cb[2*0*uvlinesize], uvlinesize, bS4, qpc1 ); + filter_mb_edgech( h, &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1 ); filter_mb_edgech( h, &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc ); - filter_mb_edgech( h, &img_cr[2*0*uvlinesize], uvlinesize, bS4, qpc1 ); + filter_mb_edgech( h, &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1 ); filter_mb_edgech( h, &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc ); return; } else { @@ -7083,7 +6450,7 @@ static void filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, if( IS_INTRA(s->current_picture.mb_type[mb_xy-1]) ) bSv[0][0] = 0x0004000400040004ULL; if( IS_INTRA(s->current_picture.mb_type[h->top_mb_xy]) ) - bSv[1][0] = 0x0004000400040004ULL; + bSv[1][0] = FIELD_PICTURE ? 0x0003000300030003ULL : 0x0004000400040004ULL; #define FILTER(hv,dir,edge)\ if(bSv[dir][edge]) {\ @@ -7131,7 +6498,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 //for sufficiently low qp, filtering wouldn't do anything //this is a conservative estimate: could also check beta_offset and more accurate chroma_qp if(!FRAME_MBAFF){ - int qp_thresh = 15 - h->slice_alpha_c0_offset - FFMAX(0, h->pps.chroma_qp_index_offset); + int qp_thresh = 15 - h->slice_alpha_c0_offset - FFMAX(0, FFMAX(h->pps.chroma_qp_index_offset[0], h->pps.chroma_qp_index_offset[1])); int qp = s->current_picture.qscale_table[mb_xy]; if(qp <= qp_thresh && (mb_x == 0 || ((qp + s->current_picture.qscale_table[mb_xy-1] + 1)>>1) <= qp_thresh) @@ -7154,7 +6521,8 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 const int left_mb_xy[2] = { pair_xy-1, pair_xy-1+s->mb_stride }; int16_t bS[8]; int qp[2]; - int chroma_qp[2]; + int bqp[2]; + int rqp[2]; int mb_qp, mbn0_qp, mbn1_qp; int i; first_vertical_edge_done = 1; @@ -7180,18 +6548,22 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 mbn0_qp = s->current_picture.qscale_table[left_mb_xy[0]]; mbn1_qp = s->current_picture.qscale_table[left_mb_xy[1]]; qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1; - chroma_qp[0] = ( get_chroma_qp( h->pps.chroma_qp_index_offset, mb_qp ) + - get_chroma_qp( h->pps.chroma_qp_index_offset, mbn0_qp ) + 1 ) >> 1; + bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) + + get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1; + rqp[0] = ( get_chroma_qp( h, 1, mb_qp ) + + get_chroma_qp( h, 1, mbn0_qp ) + 1 ) >> 1; qp[1] = ( mb_qp + mbn1_qp + 1 ) >> 1; - chroma_qp[1] = ( get_chroma_qp( h->pps.chroma_qp_index_offset, mb_qp ) + - get_chroma_qp( h->pps.chroma_qp_index_offset, mbn1_qp ) + 1 ) >> 1; + bqp[1] = ( get_chroma_qp( h, 0, mb_qp ) + + get_chroma_qp( h, 0, mbn1_qp ) + 1 ) >> 1; + rqp[1] = ( get_chroma_qp( h, 1, mb_qp ) + + get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1; /* Filter edge */ - tprintf(s->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPc:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], chroma_qp[0], chroma_qp[1], linesize, uvlinesize); + tprintf(s->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize); { int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } filter_mb_mbaff_edgev ( h, &img_y [0], linesize, bS, qp ); - filter_mb_mbaff_edgecv( h, &img_cb[0], uvlinesize, bS, chroma_qp ); - filter_mb_mbaff_edgecv( h, &img_cr[0], uvlinesize, bS, chroma_qp ); + filter_mb_mbaff_edgecv( h, &img_cb[0], uvlinesize, bS, bqp ); + filter_mb_mbaff_edgecv( h, &img_cr[0], uvlinesize, bS, rqp ); } /* dir : 0 -> vertical edge, 1 -> horizontal edge */ for( dir = 0; dir < 2; dir++ ) @@ -7229,7 +6601,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 unsigned int tmp_linesize = 2 * linesize; unsigned int tmp_uvlinesize = 2 * uvlinesize; int mbn_xy = mb_xy - 2 * s->mb_stride; - int qp, chroma_qp; + int qp; int i, j; int16_t bS[4]; @@ -7253,10 +6625,10 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } filter_mb_edgeh( h, &img_y[j*linesize], tmp_linesize, bS, qp ); - chroma_qp = ( h->chroma_qp + - get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; - filter_mb_edgech( h, &img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp ); - filter_mb_edgech( h, &img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp ); + filter_mb_edgech( h, &img_cb[j*uvlinesize], tmp_uvlinesize, bS, + ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); + filter_mb_edgech( h, &img_cr[j*uvlinesize], tmp_uvlinesize, bS, + ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); } start = 1; @@ -7353,25 +6725,25 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8 if( dir == 0 ) { filter_mb_edgev( h, &img_y[4*edge], linesize, bS, qp ); if( (edge&1) == 0 ) { - int chroma_qp = ( h->chroma_qp + - get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; - filter_mb_edgecv( h, &img_cb[2*edge], uvlinesize, bS, chroma_qp ); - filter_mb_edgecv( h, &img_cr[2*edge], uvlinesize, bS, chroma_qp ); + filter_mb_edgecv( h, &img_cb[2*edge], uvlinesize, bS, + ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); + filter_mb_edgecv( h, &img_cr[2*edge], uvlinesize, bS, + ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); } } else { filter_mb_edgeh( h, &img_y[4*edge*linesize], linesize, bS, qp ); if( (edge&1) == 0 ) { - int chroma_qp = ( h->chroma_qp + - get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; - filter_mb_edgech( h, &img_cb[2*edge*uvlinesize], uvlinesize, bS, chroma_qp ); - filter_mb_edgech( h, &img_cr[2*edge*uvlinesize], uvlinesize, bS, chroma_qp ); + filter_mb_edgech( h, &img_cb[2*edge*uvlinesize], uvlinesize, bS, + ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); + filter_mb_edgech( h, &img_cr[2*edge*uvlinesize], uvlinesize, bS, + ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1); } } } } } -static int decode_slice(H264Context *h){ +static int decode_slice(struct AVCodecContext *avctx, H264Context *h){ MpegEncContext * const s = &h->s; const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F; @@ -7421,7 +6793,7 @@ static int decode_slice(H264Context *h){ eos = get_cabac_terminate( &h->cabac ); if( ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) { - av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%d)\n", s->mb_x, s->mb_y, h->cabac.bytestream_end - h->cabac.bytestream); + av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", s->mb_x, s->mb_y, h->cabac.bytestream_end - h->cabac.bytestream); ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask); return -1; } @@ -7430,7 +6802,7 @@ static int decode_slice(H264Context *h){ s->mb_x = 0; ff_draw_horiz_band(s, 16*s->mb_y, 16); ++s->mb_y; - if(FRAME_MBAFF) { + if(FIELD_OR_MBAFF_PICTURE) { ++s->mb_y; } } @@ -7467,7 +6839,7 @@ static int decode_slice(H264Context *h){ s->mb_x=0; ff_draw_horiz_band(s, 16*s->mb_y, 16); ++s->mb_y; - if(FRAME_MBAFF) { + if(FIELD_OR_MBAFF_PICTURE) { ++s->mb_y; } if(s->mb_y >= s->mb_height){ @@ -7636,7 +7008,7 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){ if( aspect_ratio_idc == EXTENDED_SAR ) { sps->sar.num= get_bits(&s->gb, 16); sps->sar.den= get_bits(&s->gb, 16); - }else if(aspect_ratio_idc < 14){ + }else if(aspect_ratio_idc < sizeof(pixel_aspect)/sizeof(*pixel_aspect)){ sps->sar= pixel_aspect[aspect_ratio_idc]; }else{ av_log(h->s.avctx, AV_LOG_ERROR, "illegal aspect ratio\n"); @@ -7753,6 +7125,26 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s } } +/** + * Returns and optionally allocates SPS / PPS structures in the supplied array 'vec' + */ +static void * +alloc_parameter_set(H264Context *h, void **vec, const unsigned int id, const unsigned int max, + const size_t size, const char *name) +{ + if(id>=max) { + av_log(h->s.avctx, AV_LOG_ERROR, "%s_id (%d) out of range\n", name, id); + return NULL; + } + + if(!vec[id]) { + vec[id] = av_mallocz(size); + if(vec[id] == NULL) + av_log(h->s.avctx, AV_LOG_ERROR, "cannot allocate memory for %s\n", name); + } + return vec[id]; +} + static inline int decode_seq_parameter_set(H264Context *h){ MpegEncContext * const s = &h->s; int profile_idc, level_idc; @@ -7769,13 +7161,10 @@ static inline int decode_seq_parameter_set(H264Context *h){ level_idc= get_bits(&s->gb, 8); sps_id= get_ue_golomb(&s->gb); - if (sps_id >= MAX_SPS_COUNT){ - // ok it has gone out of hand, someone is sending us bad stuff. - av_log(h->s.avctx, AV_LOG_ERROR, "illegal sps_id (%d)\n", sps_id); + sps = alloc_parameter_set(h, (void **)h->sps_buffers, sps_id, MAX_SPS_COUNT, sizeof(SPS), "sps"); + if(sps == NULL) return -1; - } - sps= &h->sps_buffer[ sps_id ]; sps->profile_idc= profile_idc; sps->level_idc= level_idc; @@ -7814,8 +7203,9 @@ static inline int decode_seq_parameter_set(H264Context *h){ } tmp= get_ue_golomb(&s->gb); - if(tmp > MAX_PICTURE_COUNT-2){ + if(tmp > MAX_PICTURE_COUNT-2 || tmp >= 32){ av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); + return -1; } sps->ref_frame_count= tmp; sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb); @@ -7880,19 +7270,25 @@ static inline int decode_seq_parameter_set(H264Context *h){ return 0; } +static void +build_qp_table(PPS *pps, int t, int index) +{ + int i; + for(i = 0; i < 255; i++) + pps->chroma_qp_table[t][i & 0xff] = chroma_qp[av_clip(i + index, 0, 51)]; +} + static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ MpegEncContext * const s = &h->s; unsigned int tmp, pps_id= get_ue_golomb(&s->gb); PPS *pps; - if(pps_id>=MAX_PPS_COUNT){ - av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); + pps = alloc_parameter_set(h, (void **)h->pps_buffers, pps_id, MAX_PPS_COUNT, sizeof(PPS), "pps"); + if(pps == NULL) return -1; - } - pps = &h->pps_buffer[pps_id]; tmp= get_ue_golomb(&s->gb); - if(tmp>=MAX_SPS_COUNT){ + if(tmp>=MAX_SPS_COUNT || h->sps_buffers[tmp] == NULL){ av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n"); return -1; } @@ -7950,7 +7346,7 @@ static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ pps->weighted_bipred_idc= get_bits(&s->gb, 2); pps->init_qp= get_se_golomb(&s->gb) + 26; pps->init_qs= get_se_golomb(&s->gb) + 26; - pps->chroma_qp_index_offset= get_se_golomb(&s->gb); + pps->chroma_qp_index_offset[0]= get_se_golomb(&s->gb); pps->deblocking_filter_parameters_present= get_bits1(&s->gb); pps->constrained_intra_pred= get_bits1(&s->gb); pps->redundant_pic_cnt_present = get_bits1(&s->gb); @@ -7962,18 +7358,27 @@ static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ if(get_bits_count(&s->gb) < bit_length){ pps->transform_8x8_mode= get_bits1(&s->gb); - decode_scaling_matrices(h, &h->sps_buffer[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); - get_se_golomb(&s->gb); //second_chroma_qp_index_offset + decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); + pps->chroma_qp_index_offset[1]= get_se_golomb(&s->gb); //second_chroma_qp_index_offset + } else { + pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0]; } + build_qp_table(pps, 0, pps->chroma_qp_index_offset[0]); + if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1]) { + build_qp_table(pps, 1, pps->chroma_qp_index_offset[1]); + h->pps.chroma_qp_diff= 1; + } else + memcpy(pps->chroma_qp_table[1], pps->chroma_qp_table[0], 256); + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d %s %s %s %s\n", + av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d/%d %s %s %s %s\n", pps_id, pps->sps_id, pps->cabac ? "CABAC" : "CAVLC", pps->slice_group_count, pps->ref_count[0], pps->ref_count[1], pps->weighted_pred ? "weighted" : "", - pps->init_qp, pps->init_qs, pps->chroma_qp_index_offset, + pps->init_qp, pps->init_qs, pps->chroma_qp_index_offset[0], pps->chroma_qp_index_offset[1], pps->deblocking_filter_parameters_present ? "LPAR" : "", pps->constrained_intra_pred ? "CONSTR" : "", pps->redundant_pic_cnt_present ? "REDU" : "", @@ -7985,119 +7390,49 @@ static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ } /** - * finds the end of the current frame in the bitstream. - * @return the position of the first byte of the next frame, or -1 + * Call decode_slice() for each context. + * + * @param h h264 master context + * @param context_count number of contexts to execute */ -static int find_frame_end(H264Context *h, const uint8_t *buf, int buf_size){ +static void execute_decode_slices(H264Context *h, int context_count){ + MpegEncContext * const s = &h->s; + AVCodecContext * const avctx= s->avctx; + H264Context *hx; int i; - uint32_t state; - ParseContext *pc = &(h->s.parse_context); -//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]); -// mb_addr= pc->mb_addr - 1; - state= pc->state; - if(state>13) - state= 7; - - for(i=0; i<buf_size; i++){ - if(state==7){ - for(; i<buf_size; i++){ - if(!buf[i]){ - state=2; - break; - } - } - }else if(state<=2){ - if(buf[i]==1) state^= 5; //2->7, 1->4, 0->5 - else if(buf[i]) state = 7; - else state>>=1; //2->1, 1->0, 0->0 - }else if(state<=5){ - int v= buf[i] & 0x1F; - if(v==7 || v==8 || v==9){ - if(pc->frame_start_found){ - i++; -found: - pc->state=7; - pc->frame_start_found= 0; - return i-(state&5); - } - }else if(v==1 || v==2 || v==5){ - if(pc->frame_start_found){ - state+=8; - continue; - }else - pc->frame_start_found = 1; - } - state= 7; - }else{ - if(buf[i] & 0x80) - goto found; - state= 7; - } - } - pc->state= state; - return END_NOT_FOUND; -} - -#ifdef CONFIG_H264_PARSER -static int h264_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - H264Context *h = s->priv_data; - ParseContext *pc = &h->s.parse_context; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= find_frame_end(h, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - if(next<0){ - find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state + if(context_count == 1) { + decode_slice(avctx, h); + } else { + for(i = 1; i < context_count; i++) { + hx = h->thread_context[i]; + hx->s.error_resilience = avctx->error_resilience; + hx->s.error_count = 0; } - } - - *poutbuf = (uint8_t *)buf; - *poutbuf_size = buf_size; - return next; -} -static int h264_split(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - int i; - uint32_t state = -1; - int has_sps= 0; + avctx->execute(avctx, (void *)decode_slice, + (void **)h->thread_context, NULL, context_count); - for(i=0; i<=buf_size; i++){ - if((state&0xFFFFFF1F) == 0x107) - has_sps=1; -/* if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){ - }*/ - if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){ - if(has_sps){ - while(i>4 && buf[i-5]==0) i--; - return i-4; - } - } - if (i<buf_size) - state= (state<<8) | buf[i]; + /* pull back stuff from slices to master context */ + hx = h->thread_context[context_count - 1]; + s->mb_x = hx->s.mb_x; + s->mb_y = hx->s.mb_y; + s->dropable = hx->s.dropable; + s->picture_structure = hx->s.picture_structure; + for(i = 1; i < context_count; i++) + h->s.error_count += h->thread_context[i]->s.error_count; } - return 0; } -#endif /* CONFIG_H264_PARSER */ -static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ + +static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ MpegEncContext * const s = &h->s; AVCodecContext * const avctx= s->avctx; int buf_index=0; + H264Context *hx; ///< thread context + int context_count = 0; + + h->max_contexts = avctx->thread_count; #if 0 int i; for(i=0; i<50; i++){ @@ -8105,54 +7440,58 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ } #endif if(!(s->flags2 & CODEC_FLAG2_CHUNKS)){ - h->slice_num = 0; - s->current_picture_ptr= NULL; + h->current_slice = 0; + if (!s->first_field) + s->current_picture_ptr= NULL; } for(;;){ int consumed; int dst_length; int bit_length; - uint8_t *ptr; + const uint8_t *ptr; int i, nalsize = 0; - - if(h->is_avc) { - if(buf_index >= buf_size) break; - nalsize = 0; - for(i = 0; i < h->nal_length_size; i++) - nalsize = (nalsize << 8) | buf[buf_index++]; - if(nalsize <= 1 || nalsize > buf_size){ - if(nalsize == 1){ - buf_index++; - continue; - }else{ - av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize); - break; + int err; + + if(h->is_avc) { + if(buf_index >= buf_size) break; + nalsize = 0; + for(i = 0; i < h->nal_length_size; i++) + nalsize = (nalsize << 8) | buf[buf_index++]; + if(nalsize <= 1 || (nalsize+buf_index > buf_size)){ + if(nalsize == 1){ + buf_index++; + continue; + }else{ + av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize); + break; + } + } + } else { + // start code prefix search + for(; buf_index + 3 < buf_size; buf_index++){ + // This should always succeed in the first iteration. + if(buf[buf_index] == 0 && buf[buf_index+1] == 0 && buf[buf_index+2] == 1) + break; } - } - } else { - // start code prefix search - for(; buf_index + 3 < buf_size; buf_index++){ - // this should allways succeed in the first iteration - if(buf[buf_index] == 0 && buf[buf_index+1] == 0 && buf[buf_index+2] == 1) - break; - } - if(buf_index+3 >= buf_size) break; + if(buf_index+3 >= buf_size) break; - buf_index+=3; - } + buf_index+=3; + } + + hx = h->thread_context[context_count]; - ptr= decode_nal(h, buf + buf_index, &dst_length, &consumed, h->is_avc ? nalsize : buf_size - buf_index); - if (ptr==NULL || dst_length <= 0){ + ptr= decode_nal(hx, buf + buf_index, &dst_length, &consumed, h->is_avc ? nalsize : buf_size - buf_index); + if (ptr==NULL || dst_length < 0){ return -1; } - while(ptr[dst_length - 1] == 0 && dst_length > 1) + while(ptr[dst_length - 1] == 0 && dst_length > 0) dst_length--; - bit_length= 8*dst_length - decode_rbsp_trailing(h, ptr + dst_length - 1); + bit_length= !dst_length ? 0 : (8*dst_length - decode_rbsp_trailing(h, ptr + dst_length - 1)); if(s->avctx->debug&FF_DEBUG_STARTCODE){ - av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d at %d/%d length %d\n", h->nal_unit_type, buf_index, buf_size, dst_length); + av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d at %d/%d length %d\n", hx->nal_unit_type, buf_index, buf_size, dst_length); } if (h->is_avc && (nalsize != consumed)) @@ -8160,57 +7499,60 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ buf_index += consumed; - if( (s->hurry_up == 1 && h->nal_ref_idc == 0) //FIXME dont discard SEI id + if( (s->hurry_up == 1 && h->nal_ref_idc == 0) //FIXME do not discard SEI id ||(avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) continue; - switch(h->nal_unit_type){ + again: + err = 0; + switch(hx->nal_unit_type){ case NAL_IDR_SLICE: + if (h->nal_unit_type != NAL_IDR_SLICE) { + av_log(h->s.avctx, AV_LOG_ERROR, "Invalid mix of idr and non-idr slices"); + return -1; + } idr(h); //FIXME ensure we don't loose some frames if there is reordering case NAL_SLICE: - init_get_bits(&s->gb, ptr, bit_length); - h->intra_gb_ptr= - h->inter_gb_ptr= &s->gb; - s->data_partitioning = 0; - - if(decode_slice_header(h) < 0){ - av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n"); - break; - } - s->current_picture_ptr->key_frame= (h->nal_unit_type == NAL_IDR_SLICE); - if(h->redundant_pic_count==0 && s->hurry_up < 5 - && (avctx->skip_frame < AVDISCARD_NONREF || h->nal_ref_idc) - && (avctx->skip_frame < AVDISCARD_BIDIR || h->slice_type!=B_TYPE) - && (avctx->skip_frame < AVDISCARD_NONKEY || h->slice_type==I_TYPE) + init_get_bits(&hx->s.gb, ptr, bit_length); + hx->intra_gb_ptr= + hx->inter_gb_ptr= &hx->s.gb; + hx->s.data_partitioning = 0; + + if((err = decode_slice_header(hx, h))) + break; + + s->current_picture_ptr->key_frame|= (hx->nal_unit_type == NAL_IDR_SLICE); + if(hx->redundant_pic_count==0 && hx->s.hurry_up < 5 + && (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) + && (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type!=B_TYPE) + && (avctx->skip_frame < AVDISCARD_NONKEY || hx->slice_type==I_TYPE) && avctx->skip_frame < AVDISCARD_ALL) - decode_slice(h); + context_count++; break; case NAL_DPA: - init_get_bits(&s->gb, ptr, bit_length); - h->intra_gb_ptr= - h->inter_gb_ptr= NULL; - s->data_partitioning = 1; + init_get_bits(&hx->s.gb, ptr, bit_length); + hx->intra_gb_ptr= + hx->inter_gb_ptr= NULL; + hx->s.data_partitioning = 1; - if(decode_slice_header(h) < 0){ - av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n"); - } + err = decode_slice_header(hx, h); break; case NAL_DPB: - init_get_bits(&h->intra_gb, ptr, bit_length); - h->intra_gb_ptr= &h->intra_gb; + init_get_bits(&hx->intra_gb, ptr, bit_length); + hx->intra_gb_ptr= &hx->intra_gb; break; case NAL_DPC: - init_get_bits(&h->inter_gb, ptr, bit_length); - h->inter_gb_ptr= &h->inter_gb; + init_get_bits(&hx->inter_gb, ptr, bit_length); + hx->inter_gb_ptr= &hx->inter_gb; - if(h->redundant_pic_count==0 && h->intra_gb_ptr && s->data_partitioning + if(hx->redundant_pic_count==0 && hx->intra_gb_ptr && hx->s.data_partitioning && s->context_initialized && s->hurry_up < 5 - && (avctx->skip_frame < AVDISCARD_NONREF || h->nal_ref_idc) - && (avctx->skip_frame < AVDISCARD_BIDIR || h->slice_type!=B_TYPE) - && (avctx->skip_frame < AVDISCARD_NONKEY || h->slice_type==I_TYPE) + && (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) + && (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type!=B_TYPE) + && (avctx->skip_frame < AVDISCARD_NONKEY || hx->slice_type==I_TYPE) && avctx->skip_frame < AVDISCARD_ALL) - decode_slice(h); + context_count++; break; case NAL_SEI: init_get_bits(&s->gb, ptr, bit_length); @@ -8240,10 +7582,29 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ case NAL_AUXILIARY_SLICE: break; default: - av_log(avctx, AV_LOG_ERROR, "Unknown NAL code: %d\n", h->nal_unit_type); + av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n", h->nal_unit_type, bit_length); + } + + if(context_count == h->max_contexts) { + execute_decode_slices(h, context_count); + context_count = 0; } - } + if (err < 0) + av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n"); + else if(err == 1) { + /* Slice could not be decoded in parallel mode, copy down + * NAL unit stuff to context 0 and restart. Note that + * rbsp_buffer is not transfered, but since we no longer + * run in parallel mode this should not be an issue. */ + h->nal_unit_type = hx->nal_unit_type; + h->nal_ref_idc = hx->nal_ref_idc; + hx = h; + goto again; + } + } + if(context_count) + execute_decode_slices(h, context_count); return buf_index; } @@ -8257,7 +7618,7 @@ static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size){ return pos; }else{ - if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) + if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...) if(pos+10>buf_size) pos=buf_size; // oops ;) return pos; @@ -8266,7 +7627,7 @@ static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size){ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { H264Context *h = avctx->priv_data; MpegEncContext *s = &h->s; @@ -8302,9 +7663,9 @@ static int decode_frame(AVCodecContext *avctx, } if(s->flags&CODEC_FLAG_TRUNCATED){ - int next= find_frame_end(h, buf, buf_size); + int next= ff_h264_find_frame_end(h, buf, buf_size); - if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 ) + if( ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 ) return buf_size; //printf("next:%d buf_size:%d last_index:%d\n", next, buf_size, s->parse_context.last_index); } @@ -8360,6 +7721,7 @@ static int decode_frame(AVCodecContext *avctx, return -1; if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){ + if (avctx->skip_frame >= AVDISCARD_NONREF || s->hurry_up) return 0; av_log(avctx, AV_LOG_ERROR, "no frame!\n"); return -1; } @@ -8377,87 +7739,109 @@ static int decode_frame(AVCodecContext *avctx, h->prev_frame_num_offset= h->frame_num_offset; h->prev_frame_num= h->frame_num; - if(s->current_picture_ptr->reference){ + if(!s->dropable) { h->prev_poc_msb= h->poc_msb; h->prev_poc_lsb= h->poc_lsb; - } - if(s->current_picture_ptr->reference) execute_ref_pic_marking(h, h->mmco, h->mmco_index); + } - ff_er_frame_end(s); + /* + * FIXME: Error handling code does not seem to support interlaced + * when slices span multiple rows + * The ff_er_add_slice calls don't work right for bottom + * fields; they cause massive erroneous error concealing + * Error marking covers both fields (top and bottom). + * This causes a mismatched s->error_count + * and a bad error table. Further, the error count goes to + * INT_MAX when called for bottom field, because mb_y is + * past end by one (callers fault) and resync_mb_y != 0 + * causes problems for the first MB line, too. + */ + if (!FIELD_PICTURE) + ff_er_frame_end(s); MPV_frame_end(s); - //FIXME do something with unavailable reference frames + if (s->first_field) { + /* Wait for second field. */ + *data_size = 0; -#if 0 //decode order - *data_size = sizeof(AVFrame); -#else - /* Sort B-frames into display order */ + } else { + cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE; + /* Derive top_field_first from field pocs. */ + cur->top_field_first = cur->field_poc[0] < cur->field_poc[1]; - if(h->sps.bitstream_restriction_flag - && s->avctx->has_b_frames < h->sps.num_reorder_frames){ - s->avctx->has_b_frames = h->sps.num_reorder_frames; - s->low_delay = 0; - } + //FIXME do something with unavailable reference frames - pics = 0; - while(h->delayed_pic[pics]) pics++; +#if 0 //decode order + *data_size = sizeof(AVFrame); +#else + /* Sort B-frames into display order */ - assert(pics+1 < sizeof(h->delayed_pic) / sizeof(h->delayed_pic[0])); + if(h->sps.bitstream_restriction_flag + && s->avctx->has_b_frames < h->sps.num_reorder_frames){ + s->avctx->has_b_frames = h->sps.num_reorder_frames; + s->low_delay = 0; + } - h->delayed_pic[pics++] = cur; - if(cur->reference == 0) - cur->reference = 1; + pics = 0; + while(h->delayed_pic[pics]) pics++; - cross_idr = 0; - for(i=0; h->delayed_pic[i]; i++) - if(h->delayed_pic[i]->key_frame || h->delayed_pic[i]->poc==0) - cross_idr = 1; + assert(pics+1 < sizeof(h->delayed_pic) / sizeof(h->delayed_pic[0])); - out = h->delayed_pic[0]; - out_idx = 0; - for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame; i++) - if(h->delayed_pic[i]->poc < out->poc){ - out = h->delayed_pic[i]; - out_idx = i; - } + h->delayed_pic[pics++] = cur; + if(cur->reference == 0) + cur->reference = DELAYED_PIC_REF; - out_of_order = !cross_idr && prev && out->poc < prev->poc; - if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames) - { } - else if(prev && pics <= s->avctx->has_b_frames) - out = prev; - else if((out_of_order && pics-1 == s->avctx->has_b_frames && pics < 15) - || (s->low_delay && - ((!cross_idr && prev && out->poc > prev->poc + 2) - || cur->pict_type == B_TYPE))) - { - s->low_delay = 0; - s->avctx->has_b_frames++; - out = prev; - } - else if(out_of_order) - out = prev; + cross_idr = 0; + for(i=0; h->delayed_pic[i]; i++) + if(h->delayed_pic[i]->key_frame || h->delayed_pic[i]->poc==0) + cross_idr = 1; - if(out_of_order || pics > s->avctx->has_b_frames){ - for(i=out_idx; h->delayed_pic[i]; i++) - h->delayed_pic[i] = h->delayed_pic[i+1]; - } + out = h->delayed_pic[0]; + out_idx = 0; + for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame; i++) + if(h->delayed_pic[i]->poc < out->poc){ + out = h->delayed_pic[i]; + out_idx = i; + } - if(prev == out) - *data_size = 0; - else - *data_size = sizeof(AVFrame); - if(prev && prev != out && prev->reference == 1) - prev->reference = 0; - h->delayed_output_pic = out; + out_of_order = !cross_idr && prev && out->poc < prev->poc; + if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames) + { } + else if(prev && pics <= s->avctx->has_b_frames) + out = prev; + else if((out_of_order && pics-1 == s->avctx->has_b_frames && pics < 15) + || (s->low_delay && + ((!cross_idr && prev && out->poc > prev->poc + 2) + || cur->pict_type == B_TYPE))) + { + s->low_delay = 0; + s->avctx->has_b_frames++; + out = prev; + } + else if(out_of_order) + out = prev; + + if(out_of_order || pics > s->avctx->has_b_frames){ + for(i=out_idx; h->delayed_pic[i]; i++) + h->delayed_pic[i] = h->delayed_pic[i+1]; + } + + if(prev == out) + *data_size = 0; + else + *data_size = sizeof(AVFrame); + if(prev && prev != out && prev->reference == DELAYED_PIC_REF) + prev->reference = 0; + h->delayed_output_pic = out; #endif - if(out) - *pict= *(AVFrame*)out; - else - av_log(avctx, AV_LOG_DEBUG, "no picture\n"); + if(out) + *pict= *(AVFrame*)out; + else + av_log(avctx, AV_LOG_DEBUG, "no picture\n"); + } } assert(pict->data[0] || !*data_size); @@ -8466,7 +7850,7 @@ static int decode_frame(AVCodecContext *avctx, #if 0 //? /* Return the Picture timestamp as the frame number */ - /* we substract 1 because it is added on utils.c */ + /* we subtract 1 because it is added on utils.c */ avctx->frame_number = s->picture_number - 1; #endif return get_consumed_bytes(s, buf_index, buf_size); @@ -8491,10 +7875,12 @@ static inline void fill_mb_avail(H264Context *h){ } #endif -#if 0 //selftest +#ifdef TEST +#undef printf +#undef random #define COUNT 8000 #define SIZE (COUNT*40) -int main(){ +int main(void){ int i; uint8_t temp[SIZE]; PutBitContext pb; @@ -8523,7 +7909,7 @@ int main(){ START_TIMER j= get_ue_golomb(&gb); if(j != i){ - printf("missmatch! at %d (%d should be %d) bits:%6X\n", i, j, i, s); + printf("mismatch! at %d (%d should be %d) bits:%6X\n", i, j, i, s); // return -1; } STOP_TIMER("get_ue_golomb"); @@ -8548,12 +7934,13 @@ int main(){ START_TIMER j= get_se_golomb(&gb); if(j != i - COUNT/2){ - printf("missmatch! at %d (%d should be %d) bits:%6X\n", i, j, i, s); + printf("mismatch! at %d (%d should be %d) bits:%6X\n", i, j, i, s); // return -1; } STOP_TIMER("get_se_golomb"); } +#if 0 printf("testing 4x4 (I)DCT\n"); DCTELEM block[16]; @@ -8593,14 +7980,12 @@ int main(){ } } printf("error=%f max_error=%d\n", ((float)error)/COUNT/16, (int)max_error ); -#if 0 printf("testing quantizer\n"); for(qp=0; qp<52; qp++){ for(i=0; i<16; i++) src1_block[i]= src2_block[i]= random()%255; } -#endif printf("Testing NAL layer\n"); uint8_t bitstream[COUNT]; @@ -8652,17 +8037,18 @@ int main(){ } if(memcmp(bitstream, out, COUNT)){ - printf("missmatch\n"); + printf("mismatch\n"); return -1; } } +#endif printf("Testing RBSP\n"); return 0; } -#endif +#endif /* TEST */ static int decode_end(AVCodecContext *avctx) @@ -8670,7 +8056,8 @@ static int decode_end(AVCodecContext *avctx) H264Context *h = avctx->priv_data; MpegEncContext *s = &h->s; - av_freep(&h->rbsp_buffer); + av_freep(&h->rbsp_buffer[0]); + av_freep(&h->rbsp_buffer[1]); free_tables(h); //FIXME cleanup init stuff perhaps MPV_common_end(s); @@ -8693,15 +8080,4 @@ AVCodec h264_decoder = { .flush= flush_dpb, }; -#ifdef CONFIG_H264_PARSER -AVCodecParser h264_parser = { - { CODEC_ID_H264 }, - sizeof(H264Context), - NULL, - h264_parse, - ff_parse_close, - h264_split, -}; -#endif - #include "svq3.c" diff --git a/contrib/ffmpeg/libavcodec/h264.h b/contrib/ffmpeg/libavcodec/h264.h new file mode 100644 index 000000000..f45b3a6a4 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h264.h @@ -0,0 +1,419 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * 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 h264.h + * H.264 / AVC / MPEG4 part10 codec. + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#ifndef FFMPEG_H264_H +#define FFMPEG_H264_H + +#include "dsputil.h" +#include "cabac.h" +#include "mpegvideo.h" +#include "h264pred.h" + +#define interlaced_dct interlaced_dct_is_a_bad_name +#define mb_intra mb_intra_is_not_initialized_see_mb_type + +#define LUMA_DC_BLOCK_INDEX 25 +#define CHROMA_DC_BLOCK_INDEX 26 + +#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8 +#define COEFF_TOKEN_VLC_BITS 8 +#define TOTAL_ZEROS_VLC_BITS 9 +#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3 +#define RUN_VLC_BITS 3 +#define RUN7_VLC_BITS 6 + +#define MAX_SPS_COUNT 32 +#define MAX_PPS_COUNT 256 + +#define MAX_MMCO_COUNT 66 + +/* Compiling in interlaced support reduces the speed + * of progressive decoding by about 2%. */ +#define ALLOW_INTERLACE + +#ifdef ALLOW_INTERLACE +#define MB_MBAFF h->mb_mbaff +#define MB_FIELD h->mb_field_decoding_flag +#define FRAME_MBAFF h->mb_aff_frame +#define FIELD_PICTURE (s->picture_structure != PICT_FRAME) +#else +#define MB_MBAFF 0 +#define MB_FIELD 0 +#define FRAME_MBAFF 0 +#define FIELD_PICTURE 0 +#undef IS_INTERLACED +#define IS_INTERLACED(mb_type) 0 +#endif +#define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE) + +/** + * Sequence parameter set + */ +typedef struct SPS{ + + int profile_idc; + int level_idc; + int transform_bypass; ///< qpprime_y_zero_transform_bypass_flag + int log2_max_frame_num; ///< log2_max_frame_num_minus4 + 4 + int poc_type; ///< pic_order_cnt_type + int log2_max_poc_lsb; ///< log2_max_pic_order_cnt_lsb_minus4 + int delta_pic_order_always_zero_flag; + int offset_for_non_ref_pic; + int offset_for_top_to_bottom_field; + int poc_cycle_length; ///< num_ref_frames_in_pic_order_cnt_cycle + int ref_frame_count; ///< num_ref_frames + int gaps_in_frame_num_allowed_flag; + int mb_width; ///< pic_width_in_mbs_minus1 + 1 + int mb_height; ///< pic_height_in_map_units_minus1 + 1 + int frame_mbs_only_flag; + int mb_aff; ///<mb_adaptive_frame_field_flag + int direct_8x8_inference_flag; + int crop; ///< frame_cropping_flag + int crop_left; ///< frame_cropping_rect_left_offset + int crop_right; ///< frame_cropping_rect_right_offset + int crop_top; ///< frame_cropping_rect_top_offset + int crop_bottom; ///< frame_cropping_rect_bottom_offset + int vui_parameters_present_flag; + AVRational sar; + int timing_info_present_flag; + uint32_t num_units_in_tick; + uint32_t time_scale; + int fixed_frame_rate_flag; + short offset_for_ref_frame[256]; //FIXME dyn aloc? + int bitstream_restriction_flag; + int num_reorder_frames; + int scaling_matrix_present; + uint8_t scaling_matrix4[6][16]; + uint8_t scaling_matrix8[2][64]; +}SPS; + +/** + * Picture parameter set + */ +typedef struct PPS{ + unsigned int sps_id; + int cabac; ///< entropy_coding_mode_flag + int pic_order_present; ///< pic_order_present_flag + int slice_group_count; ///< num_slice_groups_minus1 + 1 + int mb_slice_group_map_type; + unsigned int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1 + int weighted_pred; ///< weighted_pred_flag + int weighted_bipred_idc; + int init_qp; ///< pic_init_qp_minus26 + 26 + int init_qs; ///< pic_init_qs_minus26 + 26 + int chroma_qp_index_offset[2]; + int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag + int constrained_intra_pred; ///< constrained_intra_pred_flag + int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag + int transform_8x8_mode; ///< transform_8x8_mode_flag + uint8_t scaling_matrix4[6][16]; + uint8_t scaling_matrix8[2][64]; + uint8_t chroma_qp_table[2][256]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table + int chroma_qp_diff; +}PPS; + +/** + * Memory management control operation opcode. + */ +typedef enum MMCOOpcode{ + MMCO_END=0, + MMCO_SHORT2UNUSED, + MMCO_LONG2UNUSED, + MMCO_SHORT2LONG, + MMCO_SET_MAX_LONG, + MMCO_RESET, + MMCO_LONG, +} MMCOOpcode; + +/** + * Memory management control operation. + */ +typedef struct MMCO{ + MMCOOpcode opcode; + int short_pic_num; ///< pic_num without wrapping (pic_num & max_pic_num) + int long_arg; ///< index, pic_num, or num long refs depending on opcode +} MMCO; + +/** + * H264Context + */ +typedef struct H264Context{ + MpegEncContext s; + int nal_ref_idc; + int nal_unit_type; + uint8_t *rbsp_buffer[2]; + unsigned int rbsp_buffer_size[2]; + + /** + * Used to parse AVC variant of h264 + */ + int is_avc; ///< this flag is != 0 if codec is avc1 + int got_avcC; ///< flag used to parse avcC data only once + int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4) + + int chroma_qp[2]; //QPc + + int prev_mb_skipped; + int next_mb_skipped; + + //prediction stuff + int chroma_pred_mode; + int intra16x16_pred_mode; + + int top_mb_xy; + int left_mb_xy[2]; + + int8_t intra4x4_pred_mode_cache[5*8]; + int8_t (*intra4x4_pred_mode)[8]; + H264PredContext hpc; + unsigned int topleft_samples_available; + unsigned int top_samples_available; + unsigned int topright_samples_available; + unsigned int left_samples_available; + uint8_t (*top_borders[2])[16+2*8]; + uint8_t left_border[2*(17+2*9)]; + + /** + * non zero coeff count cache. + * is 64 if not available. + */ + DECLARE_ALIGNED_8(uint8_t, non_zero_count_cache[6*8]); + uint8_t (*non_zero_count)[16]; + + /** + * Motion vector cache. + */ + DECLARE_ALIGNED_8(int16_t, mv_cache[2][5*8][2]); + DECLARE_ALIGNED_8(int8_t, ref_cache[2][5*8]); +#define LIST_NOT_USED -1 //FIXME rename? +#define PART_NOT_AVAILABLE -2 + + /** + * is 1 if the specific list MV&references are set to 0,0,-2. + */ + int mv_cache_clean[2]; + + /** + * number of neighbors (top and/or left) that used 8x8 dct + */ + int neighbor_transform_size; + + /** + * block_offset[ 0..23] for frame macroblocks + * block_offset[24..47] for field macroblocks + */ + int block_offset[2*(16+8)]; + + uint32_t *mb2b_xy; //FIXME are these 4 a good idea? + uint32_t *mb2b8_xy; + int b_stride; //FIXME use s->b4_stride + int b8_stride; + + int mb_linesize; ///< may be equal to s->linesize or s->linesize*2, for mbaff + int mb_uvlinesize; + + int emu_edge_width; + int emu_edge_height; + + int halfpel_flag; + int thirdpel_flag; + + int unknown_svq3_flag; + int next_slice_index; + + SPS *sps_buffers[MAX_SPS_COUNT]; + SPS sps; ///< current sps + + PPS *pps_buffers[MAX_PPS_COUNT]; + /** + * current pps + */ + PPS pps; //FIXME move to Picture perhaps? (->no) do we need that? + + uint32_t dequant4_buffer[6][52][16]; + uint32_t dequant8_buffer[2][52][64]; + uint32_t (*dequant4_coeff[6])[16]; + uint32_t (*dequant8_coeff[2])[64]; + int dequant_coeff_pps; ///< reinit tables when pps changes + + int slice_num; + uint8_t *slice_table_base; + uint8_t *slice_table; ///< slice_table_base + 2*mb_stride + 1 + int slice_type; + int slice_type_fixed; + + //interlacing specific flags + int mb_aff_frame; + int mb_field_decoding_flag; + int mb_mbaff; ///< mb_aff_frame && mb_field_decoding_flag + + unsigned int sub_mb_type[4]; + + //POC stuff + int poc_lsb; + int poc_msb; + int delta_poc_bottom; + int delta_poc[2]; + int frame_num; + int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0 + int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0 + int frame_num_offset; ///< for POC type 2 + int prev_frame_num_offset; ///< for POC type 2 + int prev_frame_num; ///< frame_num of the last pic for POC type 1/2 + + /** + * frame_num for frames or 2*frame_num+1 for field pics. + */ + int curr_pic_num; + + /** + * max_frame_num or 2*max_frame_num for field pics. + */ + int max_pic_num; + + //Weighted pred stuff + int use_weight; + int use_weight_chroma; + int luma_log2_weight_denom; + int chroma_log2_weight_denom; + int luma_weight[2][48]; + int luma_offset[2][48]; + int chroma_weight[2][48][2]; + int chroma_offset[2][48][2]; + int implicit_weight[48][48]; + + //deblock + int deblocking_filter; ///< disable_deblocking_filter_idc with 1<->0 + int slice_alpha_c0_offset; + int slice_beta_offset; + + int redundant_pic_count; + + int direct_spatial_mv_pred; + int dist_scale_factor[16]; + int dist_scale_factor_field[32]; + int map_col_to_list0[2][16]; + int map_col_to_list0_field[2][32]; + + /** + * num_ref_idx_l0/1_active_minus1 + 1 + */ + unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode + unsigned int list_count; + Picture *short_ref[32]; + Picture *long_ref[32]; + Picture default_ref_list[2][32]; ///< base reference list for all slices of a coded picture + Picture ref_list[2][48]; /**< 0..15: frame refs, 16..47: mbaff field refs. + Reordered version of default_ref_list + according to picture reordering in slice header */ + Picture *delayed_pic[18]; //FIXME size? + Picture *delayed_output_pic; + + /** + * memory management control operations buffer. + */ + MMCO mmco[MAX_MMCO_COUNT]; + int mmco_index; + + int long_ref_count; ///< number of actual long term references + int short_ref_count; ///< number of actual short term references + + //data partitioning + GetBitContext intra_gb; + GetBitContext inter_gb; + GetBitContext *intra_gb_ptr; + GetBitContext *inter_gb_ptr; + + DECLARE_ALIGNED_16(DCTELEM, mb[16*24]); + DCTELEM mb_padding[256]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not to large or ensure that there is some unused stuff after mb + + /** + * Cabac + */ + CABACContext cabac; + uint8_t cabac_state[460]; + int cabac_init_idc; + + /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */ + uint16_t *cbp_table; + int cbp; + int top_cbp; + int left_cbp; + /* chroma_pred_mode for i4x4 or i16x16, else 0 */ + uint8_t *chroma_pred_mode_table; + int last_qscale_diff; + int16_t (*mvd_table[2])[2]; + DECLARE_ALIGNED_8(int16_t, mvd_cache[2][5*8][2]); + uint8_t *direct_table; + uint8_t direct_cache[5*8]; + + uint8_t zigzag_scan[16]; + uint8_t zigzag_scan8x8[64]; + uint8_t zigzag_scan8x8_cavlc[64]; + uint8_t field_scan[16]; + uint8_t field_scan8x8[64]; + uint8_t field_scan8x8_cavlc[64]; + const uint8_t *zigzag_scan_q0; + const uint8_t *zigzag_scan8x8_q0; + const uint8_t *zigzag_scan8x8_cavlc_q0; + const uint8_t *field_scan_q0; + const uint8_t *field_scan8x8_q0; + const uint8_t *field_scan8x8_cavlc_q0; + + int x264_build; + + /** + * @defgroup multithreading Members for slice based multithreading + * @{ + */ + struct H264Context *thread_context[MAX_THREADS]; + + /** + * current slice number, used to initalize slice_num of each thread/context + */ + int current_slice; + + /** + * Max number of threads / contexts. + * This is equal to AVCodecContext.thread_count unless + * multithreaded decoding is impossible, in which case it is + * reduced to 1. + */ + int max_contexts; + + /** + * 1 if the single thread fallback warning has already been + * displayed, 0 otherwise. + */ + int single_decode_warning; + + int last_slice_type; + /** @} */ + +}H264Context; + +#endif /* FFMPEG_H264_H */ diff --git a/contrib/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c b/contrib/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c new file mode 100644 index 000000000..03eb956ca --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h264_mp4toannexb_bsf.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2007 Benoit Fouet <benoit.fouet@purplelabs.com> + * + * 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" + +typedef struct H264BSFContext { + uint8_t length_size; + uint8_t first_idr; + uint8_t *sps_pps_data; + uint32_t size; +} H264BSFContext; + +static void alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *sps_pps, uint32_t sps_pps_size, + const uint8_t *in, uint32_t in_size) { + uint32_t offset = *poutbuf_size; + uint8_t nal_header_size = offset ? 3 : 4; + + *poutbuf_size += sps_pps_size+in_size+nal_header_size; + *poutbuf = av_realloc(*poutbuf, *poutbuf_size); + if (sps_pps) + memcpy(*poutbuf+offset, sps_pps, sps_pps_size); + memcpy(*poutbuf+sps_pps_size+nal_header_size+offset, in, in_size); + if (!offset) + AV_WB32(*poutbuf+sps_pps_size, 1); + else { + (*poutbuf+offset+sps_pps_size)[0] = (*poutbuf+offset+sps_pps_size)[1] = 0; + (*poutbuf+offset+sps_pps_size)[2] = 1; + } +} + +static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int keyframe) { + H264BSFContext *ctx = bsfc->priv_data; + uint8_t unit_type; + uint32_t nal_size, cumul_size = 0; + + /* nothing to filter */ + if (!avctx->extradata || avctx->extradata_size < 6) { + *poutbuf = (uint8_t*) buf; + *poutbuf_size = buf_size; + return 0; + } + + /* retrieve sps and pps NAL units from extradata */ + if (!ctx->sps_pps_data) { + uint16_t unit_size; + uint32_t total_size = 0; + uint8_t *out = NULL, unit_nb, sps_done = 0; + const uint8_t *extradata = avctx->extradata+4; + static const uint8_t nalu_header[4] = {0, 0, 0, 1}; + + /* retrieve length coded size */ + ctx->length_size = (*extradata++ & 0x3) + 1; + if (ctx->length_size == 3) + return AVERROR(EINVAL); + + /* retrieve sps and pps unit(s) */ + unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */ + if (!unit_nb) { + unit_nb = *extradata++; /* number of pps unit(s) */ + sps_done++; + } + while (unit_nb--) { + unit_size = AV_RB16(extradata); + total_size += unit_size+4; + if (extradata+2+unit_size > avctx->extradata+avctx->extradata_size) { + av_free(out); + return AVERROR(EINVAL); + } + out = av_realloc(out, total_size); + if (!out) + return AVERROR(ENOMEM); + memcpy(out+total_size-unit_size-4, nalu_header, 4); + memcpy(out+total_size-unit_size, extradata+2, unit_size); + extradata += 2+unit_size; + + if (!unit_nb && !sps_done++) + unit_nb = *extradata++; /* number of pps unit(s) */ + } + + ctx->sps_pps_data = out; + ctx->size = total_size; + ctx->first_idr = 1; + } + + *poutbuf_size = 0; + *poutbuf = NULL; + do { + if (ctx->length_size == 1) + nal_size = buf[0]; + else if (ctx->length_size == 2) + nal_size = AV_RB16(buf); + else + nal_size = AV_RB32(buf); + + buf += ctx->length_size; + unit_type = *buf & 0x1f; + + /* prepend only to the first type 5 NAL unit of an IDR picture */ + if (ctx->first_idr && unit_type == 5) { + alloc_and_copy(poutbuf, poutbuf_size, + ctx->sps_pps_data, ctx->size, + buf, nal_size); + ctx->first_idr = 0; + } + else { + alloc_and_copy(poutbuf, poutbuf_size, + NULL, 0, + buf, nal_size); + if (!ctx->first_idr && unit_type == 1) + ctx->first_idr = 1; + } + + buf += nal_size; + cumul_size += nal_size + ctx->length_size; + } while (cumul_size < buf_size); + + return 1; +} + +static void h264_mp4toannexb_close(AVBitStreamFilterContext *bsfc) +{ + H264BSFContext *ctx = bsfc->priv_data; + av_freep(&ctx->sps_pps_data); +} + +AVBitStreamFilter h264_mp4toannexb_bsf = { + "h264_mp4toannexb", + sizeof(H264BSFContext), + h264_mp4toannexb_filter, + h264_mp4toannexb_close, +}; + diff --git a/contrib/ffmpeg/libavcodec/h264_parser.c b/contrib/ffmpeg/libavcodec/h264_parser.c new file mode 100644 index 000000000..7a85d770c --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h264_parser.c @@ -0,0 +1,148 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... parser + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * 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 h264_parser.c + * H.264 / AVC / MPEG4 part10 parser. + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#include "parser.h" +#include "h264_parser.h" + +#include <assert.h> + + +int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size) +{ + int i; + uint32_t state; + ParseContext *pc = &(h->s.parse_context); +//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]); +// mb_addr= pc->mb_addr - 1; + state= pc->state; + if(state>13) + state= 7; + + for(i=0; i<buf_size; i++){ + if(state==7){ + for(; i<buf_size; i++){ + if(!buf[i]){ + state=2; + break; + } + } + }else if(state<=2){ + if(buf[i]==1) state^= 5; //2->7, 1->4, 0->5 + else if(buf[i]) state = 7; + else state>>=1; //2->1, 1->0, 0->0 + }else if(state<=5){ + int v= buf[i] & 0x1F; + if(v==7 || v==8 || v==9){ + if(pc->frame_start_found){ + i++; +found: + pc->state=7; + pc->frame_start_found= 0; + return i-(state&5); + } + }else if(v==1 || v==2 || v==5){ + if(pc->frame_start_found){ + state+=8; + continue; + }else + pc->frame_start_found = 1; + } + state= 7; + }else{ + if(buf[i] & 0x80) + goto found; + state= 7; + } + } + pc->state= state; + return END_NOT_FOUND; +} + +static int h264_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + H264Context *h = s->priv_data; + ParseContext *pc = &h->s.parse_context; + int next; + + if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ + next= buf_size; + }else{ + next= ff_h264_find_frame_end(h, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + if(next<0 && next != END_NOT_FOUND){ + assert(pc->last_index + next >= 0 ); + ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state + } + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +static int h264_split(AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + int i; + uint32_t state = -1; + int has_sps= 0; + + for(i=0; i<=buf_size; i++){ + if((state&0xFFFFFF1F) == 0x107) + has_sps=1; +/* if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){ + }*/ + if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){ + if(has_sps){ + while(i>4 && buf[i-5]==0) i--; + return i-4; + } + } + if (i<buf_size) + state= (state<<8) | buf[i]; + } + return 0; +} + + +AVCodecParser h264_parser = { + { CODEC_ID_H264 }, + sizeof(H264Context), + NULL, + h264_parse, + ff_parse_close, + h264_split, +}; diff --git a/contrib/ffmpeg/libavcodec/h264_parser.h b/contrib/ffmpeg/libavcodec/h264_parser.h new file mode 100644 index 000000000..0bb286ffe --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h264_parser.h @@ -0,0 +1,39 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... parser + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * 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 h264_parser.h + * H.264 / AVC / MPEG4 part10 parser. + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#ifndef FFMPEG_H264_PARSER_H +#define FFMPEG_H264_PARSER_H + +#include "h264.h" + +/** + * 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_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size); + +#endif /* FFMPEG_H264_PARSER_H */ diff --git a/contrib/ffmpeg/libavcodec/h264data.h b/contrib/ffmpeg/libavcodec/h264data.h index 74e720421..dce1666fc 100644 --- a/contrib/ffmpeg/libavcodec/h264data.h +++ b/contrib/ffmpeg/libavcodec/h264data.h @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -27,29 +26,13 @@ * @author Michael Niedermayer <michaelni@gmx.at> */ -#define VERT_PRED 0 -#define HOR_PRED 1 -#define DC_PRED 2 -#define DIAG_DOWN_LEFT_PRED 3 -#define DIAG_DOWN_RIGHT_PRED 4 -#define VERT_RIGHT_PRED 5 -#define HOR_DOWN_PRED 6 -#define VERT_LEFT_PRED 7 -#define HOR_UP_PRED 8 - -#define LEFT_DC_PRED 9 -#define TOP_DC_PRED 10 -#define DC_128_PRED 11 +#ifndef FFMPEG_H264DATA_H +#define FFMPEG_H264DATA_H +#include <stdint.h> +#include "mpegvideo.h" +#include "rational.h" -#define DC_PRED8x8 0 -#define HOR_PRED8x8 1 -#define VERT_PRED8x8 2 -#define PLANE_PRED8x8 3 - -#define LEFT_DC_PRED8x8 4 -#define TOP_DC_PRED8x8 5 -#define DC_128_PRED8x8 6 #define EXTENDED_SAR 255 @@ -71,7 +54,7 @@ NAL_SPS_EXT, NAL_AUXILIARY_SLICE=19 }; -static const AVRational pixel_aspect[14]={ +static const AVRational pixel_aspect[17]={ {0, 1}, {1, 1}, {12, 11}, @@ -86,6 +69,9 @@ static const AVRational pixel_aspect[14]={ {15, 11}, {64, 33}, {160,99}, + {4, 3}, + {3, 2}, + {2, 1}, }; static const uint8_t golomb_to_pict_type[5]= @@ -538,7 +524,7 @@ static const uint8_t default_scaling8[2][64]={ 24,25,27,28,30,32,33,35 }}; -static const int dequant4_coeff_init[6][3]={ +static const uint8_t dequant4_coeff_init[6][3]={ {10,13,16}, {11,14,18}, {13,16,20}, @@ -547,10 +533,10 @@ static const int dequant4_coeff_init[6][3]={ {18,23,29}, }; -static const int dequant8_coeff_init_scan[16] = { +static const uint8_t dequant8_coeff_init_scan[16] = { 0,3,4,3, 3,1,5,1, 4,5,2,5, 3,1,5,1 }; -static const int dequant8_coeff_init[6][6]={ +static const uint8_t dequant8_coeff_init[6][6]={ {20,18,32,19,25,24}, {22,19,35,21,28,26}, {26,23,42,24,33,31}, @@ -618,7 +604,7 @@ static const int quant_coeff[52][16]={ /* Deblocking filter (p153) */ -static const int alpha_table[52*3] = { +static const uint8_t alpha_table[52*3] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -634,7 +620,7 @@ static const int alpha_table[52*3] = { 255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255, }; -static const int beta_table[52*3] = { +static const uint8_t beta_table[52*3] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -650,7 +636,7 @@ static const int beta_table[52*3] = { 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, }; -static const int tc0_table[52*3][3] = { +static const uint8_t tc0_table[52*3][3] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, @@ -682,7 +668,7 @@ static const int tc0_table[52*3][3] = { /* Cabac pre state table */ -static const int cabac_context_init_I[460][2] = +static const int8_t cabac_context_init_I[460][2] = { /* 0 - 10 */ { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, @@ -851,7 +837,7 @@ static const int cabac_context_init_I[460][2] = { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 } }; -static const int cabac_context_init_PB[3][460][2] = +static const int8_t cabac_context_init_PB[3][460][2] = { /* i_cabac_init_idc == 0 */ { @@ -1321,3 +1307,5 @@ static const int cabac_context_init_PB[3][460][2] = { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, } }; + +#endif /* FFMPEG_H264DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/h264dsp.c b/contrib/ffmpeg/libavcodec/h264dspenc.c index 4f18afac4..061de5e10 100644 --- a/contrib/ffmpeg/libavcodec/h264dsp.c +++ b/contrib/ffmpeg/libavcodec/h264dspenc.c @@ -21,7 +21,7 @@ */ /** - * @file h264dsp.c + * @file h264dspenc.c * H.264 encoder related DSP utils * */ @@ -74,7 +74,7 @@ static void h264_dct_c(DCTELEM block[4][4]) H264_DCT_PART2(3); } -void ff_h264dsp_init(DSPContext* c, AVCodecContext *avctx) +void ff_h264dspenc_init(DSPContext* c, AVCodecContext *avctx) { c->h264_dct = h264_dct_c; } diff --git a/contrib/ffmpeg/libavcodec/h264idct.c b/contrib/ffmpeg/libavcodec/h264idct.c index a6a56d33a..571e2e91d 100644 --- a/contrib/ffmpeg/libavcodec/h264idct.c +++ b/contrib/ffmpeg/libavcodec/h264idct.c @@ -17,7 +17,6 @@ * 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 - * */ /** diff --git a/contrib/ffmpeg/libavcodec/h264pred.c b/contrib/ffmpeg/libavcodec/h264pred.c new file mode 100644 index 000000000..b3e84b72a --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h264pred.c @@ -0,0 +1,1073 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * 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 h264pred.c + * H.264 / AVC / MPEG4 part10 prediction functions. + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#include "avcodec.h" +#include "mpegvideo.h" +#include "h264pred.h" + +static void pred4x4_vertical_c(uint8_t *src, uint8_t *topright, int stride){ + const uint32_t a= ((uint32_t*)(src-stride))[0]; + ((uint32_t*)(src+0*stride))[0]= a; + ((uint32_t*)(src+1*stride))[0]= a; + ((uint32_t*)(src+2*stride))[0]= a; + ((uint32_t*)(src+3*stride))[0]= a; +} + +static void pred4x4_horizontal_c(uint8_t *src, uint8_t *topright, int stride){ + ((uint32_t*)(src+0*stride))[0]= src[-1+0*stride]*0x01010101; + ((uint32_t*)(src+1*stride))[0]= src[-1+1*stride]*0x01010101; + ((uint32_t*)(src+2*stride))[0]= src[-1+2*stride]*0x01010101; + ((uint32_t*)(src+3*stride))[0]= src[-1+3*stride]*0x01010101; +} + +static void pred4x4_dc_c(uint8_t *src, uint8_t *topright, int stride){ + const int dc= ( src[-stride] + src[1-stride] + src[2-stride] + src[3-stride] + + src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 4) >>3; + + ((uint32_t*)(src+0*stride))[0]= + ((uint32_t*)(src+1*stride))[0]= + ((uint32_t*)(src+2*stride))[0]= + ((uint32_t*)(src+3*stride))[0]= dc* 0x01010101; +} + +static void pred4x4_left_dc_c(uint8_t *src, uint8_t *topright, int stride){ + const int dc= ( src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 2) >>2; + + ((uint32_t*)(src+0*stride))[0]= + ((uint32_t*)(src+1*stride))[0]= + ((uint32_t*)(src+2*stride))[0]= + ((uint32_t*)(src+3*stride))[0]= dc* 0x01010101; +} + +static void pred4x4_top_dc_c(uint8_t *src, uint8_t *topright, int stride){ + const int dc= ( src[-stride] + src[1-stride] + src[2-stride] + src[3-stride] + 2) >>2; + + ((uint32_t*)(src+0*stride))[0]= + ((uint32_t*)(src+1*stride))[0]= + ((uint32_t*)(src+2*stride))[0]= + ((uint32_t*)(src+3*stride))[0]= dc* 0x01010101; +} + +static void pred4x4_128_dc_c(uint8_t *src, uint8_t *topright, int stride){ + ((uint32_t*)(src+0*stride))[0]= + ((uint32_t*)(src+1*stride))[0]= + ((uint32_t*)(src+2*stride))[0]= + ((uint32_t*)(src+3*stride))[0]= 128U*0x01010101U; +} + + +#define LOAD_TOP_RIGHT_EDGE\ + const int av_unused t4= topright[0];\ + const int av_unused t5= topright[1];\ + const int av_unused t6= topright[2];\ + const int av_unused t7= topright[3];\ + +#define LOAD_DOWN_LEFT_EDGE\ + const int av_unused l4= src[-1+4*stride];\ + const int av_unused l5= src[-1+5*stride];\ + const int av_unused l6= src[-1+6*stride];\ + const int av_unused l7= src[-1+7*stride];\ + +#define LOAD_LEFT_EDGE\ + const int av_unused l0= src[-1+0*stride];\ + const int av_unused l1= src[-1+1*stride];\ + const int av_unused l2= src[-1+2*stride];\ + const int av_unused l3= src[-1+3*stride];\ + +#define LOAD_TOP_EDGE\ + const int av_unused t0= src[ 0-1*stride];\ + const int av_unused t1= src[ 1-1*stride];\ + const int av_unused t2= src[ 2-1*stride];\ + const int av_unused t3= src[ 3-1*stride];\ + +static void pred4x4_down_right_c(uint8_t *src, uint8_t *topright, int stride){ + const int lt= src[-1-1*stride]; + LOAD_TOP_EDGE + LOAD_LEFT_EDGE + + src[0+3*stride]=(l3 + 2*l2 + l1 + 2)>>2; + src[0+2*stride]= + src[1+3*stride]=(l2 + 2*l1 + l0 + 2)>>2; + src[0+1*stride]= + src[1+2*stride]= + src[2+3*stride]=(l1 + 2*l0 + lt + 2)>>2; + src[0+0*stride]= + src[1+1*stride]= + src[2+2*stride]= + src[3+3*stride]=(l0 + 2*lt + t0 + 2)>>2; + src[1+0*stride]= + src[2+1*stride]= + src[3+2*stride]=(lt + 2*t0 + t1 + 2)>>2; + src[2+0*stride]= + src[3+1*stride]=(t0 + 2*t1 + t2 + 2)>>2; + src[3+0*stride]=(t1 + 2*t2 + t3 + 2)>>2; +} + +static void pred4x4_down_left_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_TOP_EDGE + LOAD_TOP_RIGHT_EDGE +// LOAD_LEFT_EDGE + + src[0+0*stride]=(t0 + t2 + 2*t1 + 2)>>2; + src[1+0*stride]= + src[0+1*stride]=(t1 + t3 + 2*t2 + 2)>>2; + src[2+0*stride]= + src[1+1*stride]= + src[0+2*stride]=(t2 + t4 + 2*t3 + 2)>>2; + src[3+0*stride]= + src[2+1*stride]= + src[1+2*stride]= + src[0+3*stride]=(t3 + t5 + 2*t4 + 2)>>2; + src[3+1*stride]= + src[2+2*stride]= + src[1+3*stride]=(t4 + t6 + 2*t5 + 2)>>2; + src[3+2*stride]= + src[2+3*stride]=(t5 + t7 + 2*t6 + 2)>>2; + src[3+3*stride]=(t6 + 3*t7 + 2)>>2; +} + +static void pred4x4_down_left_svq3_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_TOP_EDGE + LOAD_LEFT_EDGE + const av_unused int unu0= t0; + const av_unused int unu1= l0; + + src[0+0*stride]=(l1 + t1)>>1; + src[1+0*stride]= + src[0+1*stride]=(l2 + t2)>>1; + src[2+0*stride]= + src[1+1*stride]= + src[0+2*stride]= + src[3+0*stride]= + src[2+1*stride]= + src[1+2*stride]= + src[0+3*stride]= + src[3+1*stride]= + src[2+2*stride]= + src[1+3*stride]= + src[3+2*stride]= + src[2+3*stride]= + src[3+3*stride]=(l3 + t3)>>1; +} + +static void pred4x4_down_left_rv40_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_TOP_EDGE + LOAD_TOP_RIGHT_EDGE + LOAD_LEFT_EDGE + LOAD_DOWN_LEFT_EDGE + + src[0+0*stride]=(t0 + t2 + 2*t1 + 2 + l0 + l2 + 2*l1 + 2)>>3; + src[1+0*stride]= + src[0+1*stride]=(t1 + t3 + 2*t2 + 2 + l1 + l3 + 2*l2 + 2)>>3; + src[2+0*stride]= + src[1+1*stride]= + src[0+2*stride]=(t2 + t4 + 2*t3 + 2 + l2 + l4 + 2*l3 + 2)>>3; + src[3+0*stride]= + src[2+1*stride]= + src[1+2*stride]= + src[0+3*stride]=(t3 + t5 + 2*t4 + 2 + l3 + l5 + 2*l4 + 2)>>3; + src[3+1*stride]= + src[2+2*stride]= + src[1+3*stride]=(t4 + t6 + 2*t5 + 2 + l4 + l6 + 2*l5 + 2)>>3; + src[3+2*stride]= + src[2+3*stride]=(t5 + t7 + 2*t6 + 2 + l5 + l7 + 2*l6 + 2)>>3; + src[3+3*stride]=(t6 + t7 + 1 + l6 + l7 + 1)>>2; +} + +static void pred4x4_down_left_rv40_notop_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_LEFT_EDGE + LOAD_DOWN_LEFT_EDGE + + src[0+0*stride]=(l0 + l2 + 2*l1 + 2)>>2; + src[1+0*stride]= + src[0+1*stride]=(l1 + l3 + 2*l2 + 2)>>2; + src[2+0*stride]= + src[1+1*stride]= + src[0+2*stride]=(l2 + l4 + 2*l3 + 2)>>2; + src[3+0*stride]= + src[2+1*stride]= + src[1+2*stride]= + src[0+3*stride]=(l3 + l5 + 2*l4 + 2)>>2; + src[3+1*stride]= + src[2+2*stride]= + src[1+3*stride]=(l4 + l6 + 2*l5 + 2)>>2; + src[3+2*stride]= + src[2+3*stride]=(l5 + l7 + 2*l6 + 2)>>2; + src[3+3*stride]=(l6 + l7 + 1)>>1; +} + +static void pred4x4_down_left_rv40_nodown_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_TOP_EDGE + LOAD_TOP_RIGHT_EDGE + LOAD_LEFT_EDGE + + src[0+0*stride]=(t0 + t2 + 2*t1 + 2 + l0 + l2 + 2*l1 + 2)>>3; + src[1+0*stride]= + src[0+1*stride]=(t1 + t3 + 2*t2 + 2 + l1 + l3 + 2*l2 + 2)>>3; + src[2+0*stride]= + src[1+1*stride]= + src[0+2*stride]=(t2 + t4 + 2*t3 + 2 + l2 + 3*l3 + 2)>>3; + src[3+0*stride]= + src[2+1*stride]= + src[1+2*stride]= + src[0+3*stride]=(t3 + t5 + 2*t4 + 2 + l3*4 + 2)>>3; + src[3+1*stride]= + src[2+2*stride]= + src[1+3*stride]=(t4 + t6 + 2*t5 + 2 + l3*4 + 2)>>3; + src[3+2*stride]= + src[2+3*stride]=(t5 + t7 + 2*t6 + 2 + l3*4 + 2)>>3; + src[3+3*stride]=(t6 + t7 + 1 + 2*l3 + 1)>>2; +} + +static void pred4x4_vertical_right_c(uint8_t *src, uint8_t *topright, int stride){ + const int lt= src[-1-1*stride]; + LOAD_TOP_EDGE + LOAD_LEFT_EDGE + + src[0+0*stride]= + src[1+2*stride]=(lt + t0 + 1)>>1; + src[1+0*stride]= + src[2+2*stride]=(t0 + t1 + 1)>>1; + src[2+0*stride]= + src[3+2*stride]=(t1 + t2 + 1)>>1; + src[3+0*stride]=(t2 + t3 + 1)>>1; + src[0+1*stride]= + src[1+3*stride]=(l0 + 2*lt + t0 + 2)>>2; + src[1+1*stride]= + src[2+3*stride]=(lt + 2*t0 + t1 + 2)>>2; + src[2+1*stride]= + src[3+3*stride]=(t0 + 2*t1 + t2 + 2)>>2; + src[3+1*stride]=(t1 + 2*t2 + t3 + 2)>>2; + src[0+2*stride]=(lt + 2*l0 + l1 + 2)>>2; + src[0+3*stride]=(l0 + 2*l1 + l2 + 2)>>2; +} + +static void pred4x4_vertical_left_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_TOP_EDGE + LOAD_TOP_RIGHT_EDGE + + src[0+0*stride]=(t0 + t1 + 1)>>1; + src[1+0*stride]= + src[0+2*stride]=(t1 + t2 + 1)>>1; + src[2+0*stride]= + src[1+2*stride]=(t2 + t3 + 1)>>1; + src[3+0*stride]= + src[2+2*stride]=(t3 + t4+ 1)>>1; + src[3+2*stride]=(t4 + t5+ 1)>>1; + src[0+1*stride]=(t0 + 2*t1 + t2 + 2)>>2; + src[1+1*stride]= + src[0+3*stride]=(t1 + 2*t2 + t3 + 2)>>2; + src[2+1*stride]= + src[1+3*stride]=(t2 + 2*t3 + t4 + 2)>>2; + src[3+1*stride]= + src[2+3*stride]=(t3 + 2*t4 + t5 + 2)>>2; + src[3+3*stride]=(t4 + 2*t5 + t6 + 2)>>2; +} + +static void pred4x4_vertical_left_rv40(uint8_t *src, uint8_t *topright, int stride, + const int l0, const int l1, const int l2, const int l3, const int l4){ + LOAD_TOP_EDGE + LOAD_TOP_RIGHT_EDGE + + src[0+0*stride]=(2*t0 + 2*t1 + l1 + 2*l2 + l3 + 4)>>3; + src[1+0*stride]= + src[0+2*stride]=(t1 + t2 + 1)>>1; + src[2+0*stride]= + src[1+2*stride]=(t2 + t3 + 1)>>1; + src[3+0*stride]= + src[2+2*stride]=(t3 + t4+ 1)>>1; + src[3+2*stride]=(t4 + t5+ 1)>>1; + src[0+1*stride]=(t0 + 2*t1 + t2 + l2 + 2*l3 + l4 + 4)>>3; + src[1+1*stride]= + src[0+3*stride]=(t1 + 2*t2 + t3 + 2)>>2; + src[2+1*stride]= + src[1+3*stride]=(t2 + 2*t3 + t4 + 2)>>2; + src[3+1*stride]= + src[2+3*stride]=(t3 + 2*t4 + t5 + 2)>>2; + src[3+3*stride]=(t4 + 2*t5 + t6 + 2)>>2; +} + +static void pred4x4_vertical_left_rv40_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_LEFT_EDGE + LOAD_DOWN_LEFT_EDGE + + pred4x4_vertical_left_rv40(src, topright, stride, l0, l1, l2, l3, l4); +} + +static void pred4x4_vertical_left_rv40_nodown_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_LEFT_EDGE + + pred4x4_vertical_left_rv40(src, topright, stride, l0, l1, l2, l3, l3); +} + +static void pred4x4_horizontal_up_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_LEFT_EDGE + + src[0+0*stride]=(l0 + l1 + 1)>>1; + src[1+0*stride]=(l0 + 2*l1 + l2 + 2)>>2; + src[2+0*stride]= + src[0+1*stride]=(l1 + l2 + 1)>>1; + src[3+0*stride]= + src[1+1*stride]=(l1 + 2*l2 + l3 + 2)>>2; + src[2+1*stride]= + src[0+2*stride]=(l2 + l3 + 1)>>1; + src[3+1*stride]= + src[1+2*stride]=(l2 + 2*l3 + l3 + 2)>>2; + src[3+2*stride]= + src[1+3*stride]= + src[0+3*stride]= + src[2+2*stride]= + src[2+3*stride]= + src[3+3*stride]=l3; +} + +static void pred4x4_horizontal_up_rv40_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_LEFT_EDGE + LOAD_DOWN_LEFT_EDGE + LOAD_TOP_EDGE + LOAD_TOP_RIGHT_EDGE + + src[0+0*stride]=(t1 + 2*t2 + t3 + 2*l0 + 2*l1 + 4)>>3; + src[1+0*stride]=(t2 + 2*t3 + t4 + l0 + 2*l1 + l2 + 4)>>3; + src[2+0*stride]= + src[0+1*stride]=(t3 + 2*t4 + t5 + 2*l1 + 2*l2 + 4)>>3; + src[3+0*stride]= + src[1+1*stride]=(t4 + 2*t5 + t6 + l1 + 2*l2 + l3 + 4)>>3; + src[2+1*stride]= + src[0+2*stride]=(t5 + 2*t6 + t7 + 2*l2 + 2*l3 + 4)>>3; + src[3+1*stride]= + src[1+2*stride]=(t6 + 3*t7 + l2 + 3*l3 + 4)>>3; + src[3+2*stride]= + src[1+3*stride]=(l3 + 2*l4 + l5 + 2)>>2; + src[0+3*stride]= + src[2+2*stride]=(t6 + t7 + l3 + l4 + 2)>>2; + src[2+3*stride]=(l4 + l5 + 1)>>1; + src[3+3*stride]=(l4 + 2*l5 + l6 + 2)>>2; +} + +static void pred4x4_horizontal_up_rv40_nodown_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_LEFT_EDGE + LOAD_TOP_EDGE + LOAD_TOP_RIGHT_EDGE + + src[0+0*stride]=(t1 + 2*t2 + t3 + 2*l0 + 2*l1 + 4)>>3; + src[1+0*stride]=(t2 + 2*t3 + t4 + l0 + 2*l1 + l2 + 4)>>3; + src[2+0*stride]= + src[0+1*stride]=(t3 + 2*t4 + t5 + 2*l1 + 2*l2 + 4)>>3; + src[3+0*stride]= + src[1+1*stride]=(t4 + 2*t5 + t6 + l1 + 2*l2 + l3 + 4)>>3; + src[2+1*stride]= + src[0+2*stride]=(t5 + 2*t6 + t7 + 2*l2 + 2*l3 + 4)>>3; + src[3+1*stride]= + src[1+2*stride]=(t6 + 3*t7 + l2 + 3*l3 + 4)>>3; + src[3+2*stride]= + src[1+3*stride]=l3; + src[0+3*stride]= + src[2+2*stride]=(t6 + t7 + 2*l3 + 2)>>2; + src[2+3*stride]= + src[3+3*stride]=l3; +} + +static void pred4x4_horizontal_down_c(uint8_t *src, uint8_t *topright, int stride){ + const int lt= src[-1-1*stride]; + LOAD_TOP_EDGE + LOAD_LEFT_EDGE + + src[0+0*stride]= + src[2+1*stride]=(lt + l0 + 1)>>1; + src[1+0*stride]= + src[3+1*stride]=(l0 + 2*lt + t0 + 2)>>2; + src[2+0*stride]=(lt + 2*t0 + t1 + 2)>>2; + src[3+0*stride]=(t0 + 2*t1 + t2 + 2)>>2; + src[0+1*stride]= + src[2+2*stride]=(l0 + l1 + 1)>>1; + src[1+1*stride]= + src[3+2*stride]=(lt + 2*l0 + l1 + 2)>>2; + src[0+2*stride]= + src[2+3*stride]=(l1 + l2+ 1)>>1; + src[1+2*stride]= + src[3+3*stride]=(l0 + 2*l1 + l2 + 2)>>2; + src[0+3*stride]=(l2 + l3 + 1)>>1; + src[1+3*stride]=(l1 + 2*l2 + l3 + 2)>>2; +} + +static void pred16x16_vertical_c(uint8_t *src, int stride){ + int i; + const uint32_t a= ((uint32_t*)(src-stride))[0]; + const uint32_t b= ((uint32_t*)(src-stride))[1]; + const uint32_t c= ((uint32_t*)(src-stride))[2]; + const uint32_t d= ((uint32_t*)(src-stride))[3]; + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= a; + ((uint32_t*)(src+i*stride))[1]= b; + ((uint32_t*)(src+i*stride))[2]= c; + ((uint32_t*)(src+i*stride))[3]= d; + } +} + +static void pred16x16_horizontal_c(uint8_t *src, int stride){ + int i; + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= src[-1+i*stride]*0x01010101; + } +} + +static void pred16x16_dc_c(uint8_t *src, int stride){ + int i, dc=0; + + for(i=0;i<16; i++){ + dc+= src[-1+i*stride]; + } + + for(i=0;i<16; i++){ + dc+= src[i-stride]; + } + + dc= 0x01010101*((dc + 16)>>5); + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= dc; + } +} + +static void pred16x16_left_dc_c(uint8_t *src, int stride){ + int i, dc=0; + + for(i=0;i<16; i++){ + dc+= src[-1+i*stride]; + } + + dc= 0x01010101*((dc + 8)>>4); + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= dc; + } +} + +static void pred16x16_top_dc_c(uint8_t *src, int stride){ + int i, dc=0; + + for(i=0;i<16; i++){ + dc+= src[i-stride]; + } + dc= 0x01010101*((dc + 8)>>4); + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= dc; + } +} + +static void pred16x16_128_dc_c(uint8_t *src, int stride){ + int i; + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= 0x01010101U*128U; + } +} + +static inline void pred16x16_plane_compat_c(uint8_t *src, int stride, const int svq3, const int rv40){ + int i, j, k; + int a; + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t * const src0 = src+7-stride; + const uint8_t *src1 = src+8*stride-1; + const uint8_t *src2 = src1-2*stride; // == src+6*stride-1; + int H = src0[1] - src0[-1]; + int V = src1[0] - src2[ 0]; + for(k=2; k<=8; ++k) { + src1 += stride; src2 -= stride; + H += k*(src0[k] - src0[-k]); + V += k*(src1[0] - src2[ 0]); + } + if(svq3){ + H = ( 5*(H/4) ) / 16; + V = ( 5*(V/4) ) / 16; + + /* required for 100% accuracy */ + i = H; H = V; V = i; + }else if(rv40){ + H = ( H + (H>>2) ) >> 4; + V = ( V + (V>>2) ) >> 4; + }else{ + H = ( 5*H+32 ) >> 6; + V = ( 5*V+32 ) >> 6; + } + + a = 16*(src1[0] + src2[16] + 1) - 7*(V+H); + for(j=16; j>0; --j) { + int b = a; + a += V; + for(i=-16; i<0; i+=4) { + src[16+i] = cm[ (b ) >> 5 ]; + src[17+i] = cm[ (b+ H) >> 5 ]; + src[18+i] = cm[ (b+2*H) >> 5 ]; + src[19+i] = cm[ (b+3*H) >> 5 ]; + b += 4*H; + } + src += stride; + } +} + +static void pred16x16_plane_c(uint8_t *src, int stride){ + pred16x16_plane_compat_c(src, stride, 0, 0); +} + +static void pred16x16_plane_svq3_c(uint8_t *src, int stride){ + pred16x16_plane_compat_c(src, stride, 1, 0); +} + +static void pred16x16_plane_rv40_c(uint8_t *src, int stride){ + pred16x16_plane_compat_c(src, stride, 0, 1); +} + +static void pred8x8_vertical_c(uint8_t *src, int stride){ + int i; + const uint32_t a= ((uint32_t*)(src-stride))[0]; + const uint32_t b= ((uint32_t*)(src-stride))[1]; + + for(i=0; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= a; + ((uint32_t*)(src+i*stride))[1]= b; + } +} + +static void pred8x8_horizontal_c(uint8_t *src, int stride){ + int i; + + for(i=0; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= src[-1+i*stride]*0x01010101; + } +} + +static void pred8x8_128_dc_c(uint8_t *src, int stride){ + int i; + + for(i=0; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= 0x01010101U*128U; + } +} + +static void pred8x8_left_dc_c(uint8_t *src, int stride){ + int i; + int dc0, dc2; + + dc0=dc2=0; + for(i=0;i<4; i++){ + dc0+= src[-1+i*stride]; + dc2+= src[-1+(i+4)*stride]; + } + dc0= 0x01010101*((dc0 + 2)>>2); + dc2= 0x01010101*((dc2 + 2)>>2); + + for(i=0; i<4; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= dc0; + } + for(i=4; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= dc2; + } +} + +static void pred8x8_left_dc_rv40_c(uint8_t *src, int stride){ + int i; + int dc0; + + dc0=0; + for(i=0;i<8; i++) + dc0+= src[-1+i*stride]; + dc0= 0x01010101*((dc0 + 4)>>3); + + for(i=0; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= dc0; + } +} + +static void pred8x8_top_dc_c(uint8_t *src, int stride){ + int i; + int dc0, dc1; + + dc0=dc1=0; + for(i=0;i<4; i++){ + dc0+= src[i-stride]; + dc1+= src[4+i-stride]; + } + dc0= 0x01010101*((dc0 + 2)>>2); + dc1= 0x01010101*((dc1 + 2)>>2); + + for(i=0; i<4; i++){ + ((uint32_t*)(src+i*stride))[0]= dc0; + ((uint32_t*)(src+i*stride))[1]= dc1; + } + for(i=4; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= dc0; + ((uint32_t*)(src+i*stride))[1]= dc1; + } +} + +static void pred8x8_top_dc_rv40_c(uint8_t *src, int stride){ + int i; + int dc0; + + dc0=0; + for(i=0;i<8; i++) + dc0+= src[i-stride]; + dc0= 0x01010101*((dc0 + 4)>>3); + + for(i=0; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= dc0; + } +} + + +static void pred8x8_dc_c(uint8_t *src, int stride){ + int i; + int dc0, dc1, dc2, dc3; + + dc0=dc1=dc2=0; + for(i=0;i<4; i++){ + dc0+= src[-1+i*stride] + src[i-stride]; + dc1+= src[4+i-stride]; + dc2+= src[-1+(i+4)*stride]; + } + dc3= 0x01010101*((dc1 + dc2 + 4)>>3); + dc0= 0x01010101*((dc0 + 4)>>3); + dc1= 0x01010101*((dc1 + 2)>>2); + dc2= 0x01010101*((dc2 + 2)>>2); + + for(i=0; i<4; i++){ + ((uint32_t*)(src+i*stride))[0]= dc0; + ((uint32_t*)(src+i*stride))[1]= dc1; + } + for(i=4; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= dc2; + ((uint32_t*)(src+i*stride))[1]= dc3; + } +} + +static void pred8x8_dc_rv40_c(uint8_t *src, int stride){ + int i; + int dc0=0; + + for(i=0;i<4; i++){ + dc0+= src[-1+i*stride] + src[i-stride]; + dc0+= src[4+i-stride]; + dc0+= src[-1+(i+4)*stride]; + } + dc0= 0x01010101*((dc0 + 8)>>4); + + for(i=0; i<4; i++){ + ((uint32_t*)(src+i*stride))[0]= dc0; + ((uint32_t*)(src+i*stride))[1]= dc0; + } + for(i=4; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= dc0; + ((uint32_t*)(src+i*stride))[1]= dc0; + } +} + +static void pred8x8_plane_c(uint8_t *src, int stride){ + int j, k; + int a; + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t * const src0 = src+3-stride; + const uint8_t *src1 = src+4*stride-1; + const uint8_t *src2 = src1-2*stride; // == src+2*stride-1; + int H = src0[1] - src0[-1]; + int V = src1[0] - src2[ 0]; + for(k=2; k<=4; ++k) { + src1 += stride; src2 -= stride; + H += k*(src0[k] - src0[-k]); + V += k*(src1[0] - src2[ 0]); + } + H = ( 17*H+16 ) >> 5; + V = ( 17*V+16 ) >> 5; + + a = 16*(src1[0] + src2[8]+1) - 3*(V+H); + for(j=8; j>0; --j) { + int b = a; + a += V; + src[0] = cm[ (b ) >> 5 ]; + src[1] = cm[ (b+ H) >> 5 ]; + src[2] = cm[ (b+2*H) >> 5 ]; + src[3] = cm[ (b+3*H) >> 5 ]; + src[4] = cm[ (b+4*H) >> 5 ]; + src[5] = cm[ (b+5*H) >> 5 ]; + src[6] = cm[ (b+6*H) >> 5 ]; + src[7] = cm[ (b+7*H) >> 5 ]; + src += stride; + } +} + +#define SRC(x,y) src[(x)+(y)*stride] +#define PL(y) \ + const int l##y = (SRC(-1,y-1) + 2*SRC(-1,y) + SRC(-1,y+1) + 2) >> 2; +#define PREDICT_8x8_LOAD_LEFT \ + const int l0 = ((has_topleft ? SRC(-1,-1) : SRC(-1,0)) \ + + 2*SRC(-1,0) + SRC(-1,1) + 2) >> 2; \ + PL(1) PL(2) PL(3) PL(4) PL(5) PL(6) \ + const int l7 av_unused = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2 + +#define PT(x) \ + const int t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2; +#define PREDICT_8x8_LOAD_TOP \ + const int t0 = ((has_topleft ? SRC(-1,-1) : SRC(0,-1)) \ + + 2*SRC(0,-1) + SRC(1,-1) + 2) >> 2; \ + PT(1) PT(2) PT(3) PT(4) PT(5) PT(6) \ + const int t7 av_unused = ((has_topright ? SRC(8,-1) : SRC(7,-1)) \ + + 2*SRC(7,-1) + SRC(6,-1) + 2) >> 2 + +#define PTR(x) \ + t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2; +#define PREDICT_8x8_LOAD_TOPRIGHT \ + int t8, t9, t10, t11, t12, t13, t14, t15; \ + if(has_topright) { \ + PTR(8) PTR(9) PTR(10) PTR(11) PTR(12) PTR(13) PTR(14) \ + t15 = (SRC(14,-1) + 3*SRC(15,-1) + 2) >> 2; \ + } else t8=t9=t10=t11=t12=t13=t14=t15= SRC(7,-1); + +#define PREDICT_8x8_LOAD_TOPLEFT \ + const int lt = (SRC(-1,0) + 2*SRC(-1,-1) + SRC(0,-1) + 2) >> 2 + +#define PREDICT_8x8_DC(v) \ + int y; \ + for( y = 0; y < 8; y++ ) { \ + ((uint32_t*)src)[0] = \ + ((uint32_t*)src)[1] = v; \ + src += stride; \ + } + +static void pred8x8l_128_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_DC(0x80808080); +} +static void pred8x8l_left_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_LEFT; + const uint32_t dc = ((l0+l1+l2+l3+l4+l5+l6+l7+4) >> 3) * 0x01010101; + PREDICT_8x8_DC(dc); +} +static void pred8x8l_top_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + const uint32_t dc = ((t0+t1+t2+t3+t4+t5+t6+t7+4) >> 3) * 0x01010101; + PREDICT_8x8_DC(dc); +} +static void pred8x8l_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_LEFT; + PREDICT_8x8_LOAD_TOP; + const uint32_t dc = ((l0+l1+l2+l3+l4+l5+l6+l7 + +t0+t1+t2+t3+t4+t5+t6+t7+8) >> 4) * 0x01010101; + PREDICT_8x8_DC(dc); +} +static void pred8x8l_horizontal_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_LEFT; +#define ROW(y) ((uint32_t*)(src+y*stride))[0] =\ + ((uint32_t*)(src+y*stride))[1] = 0x01010101 * l##y + ROW(0); ROW(1); ROW(2); ROW(3); ROW(4); ROW(5); ROW(6); ROW(7); +#undef ROW +} +static void pred8x8l_vertical_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + int y; + PREDICT_8x8_LOAD_TOP; + src[0] = t0; + src[1] = t1; + src[2] = t2; + src[3] = t3; + src[4] = t4; + src[5] = t5; + src[6] = t6; + src[7] = t7; + for( y = 1; y < 8; y++ ) + *(uint64_t*)(src+y*stride) = *(uint64_t*)src; +} +static void pred8x8l_down_left_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_TOPRIGHT; + SRC(0,0)= (t0 + 2*t1 + t2 + 2) >> 2; + SRC(0,1)=SRC(1,0)= (t1 + 2*t2 + t3 + 2) >> 2; + SRC(0,2)=SRC(1,1)=SRC(2,0)= (t2 + 2*t3 + t4 + 2) >> 2; + SRC(0,3)=SRC(1,2)=SRC(2,1)=SRC(3,0)= (t3 + 2*t4 + t5 + 2) >> 2; + SRC(0,4)=SRC(1,3)=SRC(2,2)=SRC(3,1)=SRC(4,0)= (t4 + 2*t5 + t6 + 2) >> 2; + SRC(0,5)=SRC(1,4)=SRC(2,3)=SRC(3,2)=SRC(4,1)=SRC(5,0)= (t5 + 2*t6 + t7 + 2) >> 2; + SRC(0,6)=SRC(1,5)=SRC(2,4)=SRC(3,3)=SRC(4,2)=SRC(5,1)=SRC(6,0)= (t6 + 2*t7 + t8 + 2) >> 2; + SRC(0,7)=SRC(1,6)=SRC(2,5)=SRC(3,4)=SRC(4,3)=SRC(5,2)=SRC(6,1)=SRC(7,0)= (t7 + 2*t8 + t9 + 2) >> 2; + SRC(1,7)=SRC(2,6)=SRC(3,5)=SRC(4,4)=SRC(5,3)=SRC(6,2)=SRC(7,1)= (t8 + 2*t9 + t10 + 2) >> 2; + SRC(2,7)=SRC(3,6)=SRC(4,5)=SRC(5,4)=SRC(6,3)=SRC(7,2)= (t9 + 2*t10 + t11 + 2) >> 2; + SRC(3,7)=SRC(4,6)=SRC(5,5)=SRC(6,4)=SRC(7,3)= (t10 + 2*t11 + t12 + 2) >> 2; + SRC(4,7)=SRC(5,6)=SRC(6,5)=SRC(7,4)= (t11 + 2*t12 + t13 + 2) >> 2; + SRC(5,7)=SRC(6,6)=SRC(7,5)= (t12 + 2*t13 + t14 + 2) >> 2; + SRC(6,7)=SRC(7,6)= (t13 + 2*t14 + t15 + 2) >> 2; + SRC(7,7)= (t14 + 3*t15 + 2) >> 2; +} +static void pred8x8l_down_right_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_LEFT; + PREDICT_8x8_LOAD_TOPLEFT; + SRC(0,7)= (l7 + 2*l6 + l5 + 2) >> 2; + SRC(0,6)=SRC(1,7)= (l6 + 2*l5 + l4 + 2) >> 2; + SRC(0,5)=SRC(1,6)=SRC(2,7)= (l5 + 2*l4 + l3 + 2) >> 2; + SRC(0,4)=SRC(1,5)=SRC(2,6)=SRC(3,7)= (l4 + 2*l3 + l2 + 2) >> 2; + SRC(0,3)=SRC(1,4)=SRC(2,5)=SRC(3,6)=SRC(4,7)= (l3 + 2*l2 + l1 + 2) >> 2; + SRC(0,2)=SRC(1,3)=SRC(2,4)=SRC(3,5)=SRC(4,6)=SRC(5,7)= (l2 + 2*l1 + l0 + 2) >> 2; + SRC(0,1)=SRC(1,2)=SRC(2,3)=SRC(3,4)=SRC(4,5)=SRC(5,6)=SRC(6,7)= (l1 + 2*l0 + lt + 2) >> 2; + SRC(0,0)=SRC(1,1)=SRC(2,2)=SRC(3,3)=SRC(4,4)=SRC(5,5)=SRC(6,6)=SRC(7,7)= (l0 + 2*lt + t0 + 2) >> 2; + SRC(1,0)=SRC(2,1)=SRC(3,2)=SRC(4,3)=SRC(5,4)=SRC(6,5)=SRC(7,6)= (lt + 2*t0 + t1 + 2) >> 2; + SRC(2,0)=SRC(3,1)=SRC(4,2)=SRC(5,3)=SRC(6,4)=SRC(7,5)= (t0 + 2*t1 + t2 + 2) >> 2; + SRC(3,0)=SRC(4,1)=SRC(5,2)=SRC(6,3)=SRC(7,4)= (t1 + 2*t2 + t3 + 2) >> 2; + SRC(4,0)=SRC(5,1)=SRC(6,2)=SRC(7,3)= (t2 + 2*t3 + t4 + 2) >> 2; + SRC(5,0)=SRC(6,1)=SRC(7,2)= (t3 + 2*t4 + t5 + 2) >> 2; + SRC(6,0)=SRC(7,1)= (t4 + 2*t5 + t6 + 2) >> 2; + SRC(7,0)= (t5 + 2*t6 + t7 + 2) >> 2; + +} +static void pred8x8l_vertical_right_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_LEFT; + PREDICT_8x8_LOAD_TOPLEFT; + SRC(0,6)= (l5 + 2*l4 + l3 + 2) >> 2; + SRC(0,7)= (l6 + 2*l5 + l4 + 2) >> 2; + SRC(0,4)=SRC(1,6)= (l3 + 2*l2 + l1 + 2) >> 2; + SRC(0,5)=SRC(1,7)= (l4 + 2*l3 + l2 + 2) >> 2; + SRC(0,2)=SRC(1,4)=SRC(2,6)= (l1 + 2*l0 + lt + 2) >> 2; + SRC(0,3)=SRC(1,5)=SRC(2,7)= (l2 + 2*l1 + l0 + 2) >> 2; + SRC(0,1)=SRC(1,3)=SRC(2,5)=SRC(3,7)= (l0 + 2*lt + t0 + 2) >> 2; + SRC(0,0)=SRC(1,2)=SRC(2,4)=SRC(3,6)= (lt + t0 + 1) >> 1; + SRC(1,1)=SRC(2,3)=SRC(3,5)=SRC(4,7)= (lt + 2*t0 + t1 + 2) >> 2; + SRC(1,0)=SRC(2,2)=SRC(3,4)=SRC(4,6)= (t0 + t1 + 1) >> 1; + SRC(2,1)=SRC(3,3)=SRC(4,5)=SRC(5,7)= (t0 + 2*t1 + t2 + 2) >> 2; + SRC(2,0)=SRC(3,2)=SRC(4,4)=SRC(5,6)= (t1 + t2 + 1) >> 1; + SRC(3,1)=SRC(4,3)=SRC(5,5)=SRC(6,7)= (t1 + 2*t2 + t3 + 2) >> 2; + SRC(3,0)=SRC(4,2)=SRC(5,4)=SRC(6,6)= (t2 + t3 + 1) >> 1; + SRC(4,1)=SRC(5,3)=SRC(6,5)=SRC(7,7)= (t2 + 2*t3 + t4 + 2) >> 2; + SRC(4,0)=SRC(5,2)=SRC(6,4)=SRC(7,6)= (t3 + t4 + 1) >> 1; + SRC(5,1)=SRC(6,3)=SRC(7,5)= (t3 + 2*t4 + t5 + 2) >> 2; + SRC(5,0)=SRC(6,2)=SRC(7,4)= (t4 + t5 + 1) >> 1; + SRC(6,1)=SRC(7,3)= (t4 + 2*t5 + t6 + 2) >> 2; + SRC(6,0)=SRC(7,2)= (t5 + t6 + 1) >> 1; + SRC(7,1)= (t5 + 2*t6 + t7 + 2) >> 2; + SRC(7,0)= (t6 + t7 + 1) >> 1; +} +static void pred8x8l_horizontal_down_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_LEFT; + PREDICT_8x8_LOAD_TOPLEFT; + SRC(0,7)= (l6 + l7 + 1) >> 1; + SRC(1,7)= (l5 + 2*l6 + l7 + 2) >> 2; + SRC(0,6)=SRC(2,7)= (l5 + l6 + 1) >> 1; + SRC(1,6)=SRC(3,7)= (l4 + 2*l5 + l6 + 2) >> 2; + SRC(0,5)=SRC(2,6)=SRC(4,7)= (l4 + l5 + 1) >> 1; + SRC(1,5)=SRC(3,6)=SRC(5,7)= (l3 + 2*l4 + l5 + 2) >> 2; + SRC(0,4)=SRC(2,5)=SRC(4,6)=SRC(6,7)= (l3 + l4 + 1) >> 1; + SRC(1,4)=SRC(3,5)=SRC(5,6)=SRC(7,7)= (l2 + 2*l3 + l4 + 2) >> 2; + SRC(0,3)=SRC(2,4)=SRC(4,5)=SRC(6,6)= (l2 + l3 + 1) >> 1; + SRC(1,3)=SRC(3,4)=SRC(5,5)=SRC(7,6)= (l1 + 2*l2 + l3 + 2) >> 2; + SRC(0,2)=SRC(2,3)=SRC(4,4)=SRC(6,5)= (l1 + l2 + 1) >> 1; + SRC(1,2)=SRC(3,3)=SRC(5,4)=SRC(7,5)= (l0 + 2*l1 + l2 + 2) >> 2; + SRC(0,1)=SRC(2,2)=SRC(4,3)=SRC(6,4)= (l0 + l1 + 1) >> 1; + SRC(1,1)=SRC(3,2)=SRC(5,3)=SRC(7,4)= (lt + 2*l0 + l1 + 2) >> 2; + SRC(0,0)=SRC(2,1)=SRC(4,2)=SRC(6,3)= (lt + l0 + 1) >> 1; + SRC(1,0)=SRC(3,1)=SRC(5,2)=SRC(7,3)= (l0 + 2*lt + t0 + 2) >> 2; + SRC(2,0)=SRC(4,1)=SRC(6,2)= (t1 + 2*t0 + lt + 2) >> 2; + SRC(3,0)=SRC(5,1)=SRC(7,2)= (t2 + 2*t1 + t0 + 2) >> 2; + SRC(4,0)=SRC(6,1)= (t3 + 2*t2 + t1 + 2) >> 2; + SRC(5,0)=SRC(7,1)= (t4 + 2*t3 + t2 + 2) >> 2; + SRC(6,0)= (t5 + 2*t4 + t3 + 2) >> 2; + SRC(7,0)= (t6 + 2*t5 + t4 + 2) >> 2; +} +static void pred8x8l_vertical_left_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_TOPRIGHT; + SRC(0,0)= (t0 + t1 + 1) >> 1; + SRC(0,1)= (t0 + 2*t1 + t2 + 2) >> 2; + SRC(0,2)=SRC(1,0)= (t1 + t2 + 1) >> 1; + SRC(0,3)=SRC(1,1)= (t1 + 2*t2 + t3 + 2) >> 2; + SRC(0,4)=SRC(1,2)=SRC(2,0)= (t2 + t3 + 1) >> 1; + SRC(0,5)=SRC(1,3)=SRC(2,1)= (t2 + 2*t3 + t4 + 2) >> 2; + SRC(0,6)=SRC(1,4)=SRC(2,2)=SRC(3,0)= (t3 + t4 + 1) >> 1; + SRC(0,7)=SRC(1,5)=SRC(2,3)=SRC(3,1)= (t3 + 2*t4 + t5 + 2) >> 2; + SRC(1,6)=SRC(2,4)=SRC(3,2)=SRC(4,0)= (t4 + t5 + 1) >> 1; + SRC(1,7)=SRC(2,5)=SRC(3,3)=SRC(4,1)= (t4 + 2*t5 + t6 + 2) >> 2; + SRC(2,6)=SRC(3,4)=SRC(4,2)=SRC(5,0)= (t5 + t6 + 1) >> 1; + SRC(2,7)=SRC(3,5)=SRC(4,3)=SRC(5,1)= (t5 + 2*t6 + t7 + 2) >> 2; + SRC(3,6)=SRC(4,4)=SRC(5,2)=SRC(6,0)= (t6 + t7 + 1) >> 1; + SRC(3,7)=SRC(4,5)=SRC(5,3)=SRC(6,1)= (t6 + 2*t7 + t8 + 2) >> 2; + SRC(4,6)=SRC(5,4)=SRC(6,2)=SRC(7,0)= (t7 + t8 + 1) >> 1; + SRC(4,7)=SRC(5,5)=SRC(6,3)=SRC(7,1)= (t7 + 2*t8 + t9 + 2) >> 2; + SRC(5,6)=SRC(6,4)=SRC(7,2)= (t8 + t9 + 1) >> 1; + SRC(5,7)=SRC(6,5)=SRC(7,3)= (t8 + 2*t9 + t10 + 2) >> 2; + SRC(6,6)=SRC(7,4)= (t9 + t10 + 1) >> 1; + SRC(6,7)=SRC(7,5)= (t9 + 2*t10 + t11 + 2) >> 2; + SRC(7,6)= (t10 + t11 + 1) >> 1; + SRC(7,7)= (t10 + 2*t11 + t12 + 2) >> 2; +} +static void pred8x8l_horizontal_up_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_LEFT; + SRC(0,0)= (l0 + l1 + 1) >> 1; + SRC(1,0)= (l0 + 2*l1 + l2 + 2) >> 2; + SRC(0,1)=SRC(2,0)= (l1 + l2 + 1) >> 1; + SRC(1,1)=SRC(3,0)= (l1 + 2*l2 + l3 + 2) >> 2; + SRC(0,2)=SRC(2,1)=SRC(4,0)= (l2 + l3 + 1) >> 1; + SRC(1,2)=SRC(3,1)=SRC(5,0)= (l2 + 2*l3 + l4 + 2) >> 2; + SRC(0,3)=SRC(2,2)=SRC(4,1)=SRC(6,0)= (l3 + l4 + 1) >> 1; + SRC(1,3)=SRC(3,2)=SRC(5,1)=SRC(7,0)= (l3 + 2*l4 + l5 + 2) >> 2; + SRC(0,4)=SRC(2,3)=SRC(4,2)=SRC(6,1)= (l4 + l5 + 1) >> 1; + SRC(1,4)=SRC(3,3)=SRC(5,2)=SRC(7,1)= (l4 + 2*l5 + l6 + 2) >> 2; + SRC(0,5)=SRC(2,4)=SRC(4,3)=SRC(6,2)= (l5 + l6 + 1) >> 1; + SRC(1,5)=SRC(3,4)=SRC(5,3)=SRC(7,2)= (l5 + 2*l6 + l7 + 2) >> 2; + SRC(0,6)=SRC(2,5)=SRC(4,4)=SRC(6,3)= (l6 + l7 + 1) >> 1; + SRC(1,6)=SRC(3,5)=SRC(5,4)=SRC(7,3)= (l6 + 3*l7 + 2) >> 2; + SRC(0,7)=SRC(1,7)=SRC(2,6)=SRC(2,7)=SRC(3,6)= + SRC(3,7)=SRC(4,5)=SRC(4,6)=SRC(4,7)=SRC(5,5)= + SRC(5,6)=SRC(5,7)=SRC(6,4)=SRC(6,5)=SRC(6,6)= + SRC(6,7)=SRC(7,4)=SRC(7,5)=SRC(7,6)=SRC(7,7)= l7; +} +#undef PREDICT_8x8_LOAD_LEFT +#undef PREDICT_8x8_LOAD_TOP +#undef PREDICT_8x8_LOAD_TOPLEFT +#undef PREDICT_8x8_LOAD_TOPRIGHT +#undef PREDICT_8x8_DC +#undef PTR +#undef PT +#undef PL +#undef SRC + +/** + * Sets the intra prediction function pointers. + */ +void ff_h264_pred_init(H264PredContext *h, int codec_id){ +// MpegEncContext * const s = &h->s; + + if(codec_id != CODEC_ID_RV40){ + h->pred4x4[VERT_PRED ]= pred4x4_vertical_c; + h->pred4x4[HOR_PRED ]= pred4x4_horizontal_c; + h->pred4x4[DC_PRED ]= pred4x4_dc_c; + if(codec_id == CODEC_ID_SVQ3) + h->pred4x4[DIAG_DOWN_LEFT_PRED ]= pred4x4_down_left_svq3_c; + else + h->pred4x4[DIAG_DOWN_LEFT_PRED ]= pred4x4_down_left_c; + h->pred4x4[DIAG_DOWN_RIGHT_PRED]= pred4x4_down_right_c; + h->pred4x4[VERT_RIGHT_PRED ]= pred4x4_vertical_right_c; + h->pred4x4[HOR_DOWN_PRED ]= pred4x4_horizontal_down_c; + h->pred4x4[VERT_LEFT_PRED ]= pred4x4_vertical_left_c; + h->pred4x4[HOR_UP_PRED ]= pred4x4_horizontal_up_c; + h->pred4x4[LEFT_DC_PRED ]= pred4x4_left_dc_c; + h->pred4x4[TOP_DC_PRED ]= pred4x4_top_dc_c; + h->pred4x4[DC_128_PRED ]= pred4x4_128_dc_c; + }else{ + h->pred4x4[VERT_PRED ]= pred4x4_vertical_c; + h->pred4x4[HOR_PRED ]= pred4x4_horizontal_c; + h->pred4x4[DC_PRED ]= pred4x4_dc_c; + h->pred4x4[DIAG_DOWN_LEFT_PRED ]= pred4x4_down_left_rv40_c; + h->pred4x4[DIAG_DOWN_RIGHT_PRED]= pred4x4_down_right_c; + h->pred4x4[VERT_RIGHT_PRED ]= pred4x4_vertical_right_c; + h->pred4x4[HOR_DOWN_PRED ]= pred4x4_horizontal_down_c; + h->pred4x4[VERT_LEFT_PRED ]= pred4x4_vertical_left_rv40_c; + h->pred4x4[HOR_UP_PRED ]= pred4x4_horizontal_up_rv40_c; + h->pred4x4[LEFT_DC_PRED ]= pred4x4_left_dc_c; + h->pred4x4[TOP_DC_PRED ]= pred4x4_top_dc_c; + h->pred4x4[DC_128_PRED ]= pred4x4_128_dc_c; + h->pred4x4[DIAG_DOWN_LEFT_PRED_RV40_NODOWN]= pred4x4_down_left_rv40_nodown_c; + h->pred4x4[HOR_UP_PRED_RV40_NODOWN]= pred4x4_horizontal_up_rv40_nodown_c; + h->pred4x4[VERT_LEFT_PRED_RV40_NODOWN]= pred4x4_vertical_left_rv40_nodown_c; + } + + h->pred8x8l[VERT_PRED ]= pred8x8l_vertical_c; + h->pred8x8l[HOR_PRED ]= pred8x8l_horizontal_c; + h->pred8x8l[DC_PRED ]= pred8x8l_dc_c; + h->pred8x8l[DIAG_DOWN_LEFT_PRED ]= pred8x8l_down_left_c; + h->pred8x8l[DIAG_DOWN_RIGHT_PRED]= pred8x8l_down_right_c; + h->pred8x8l[VERT_RIGHT_PRED ]= pred8x8l_vertical_right_c; + h->pred8x8l[HOR_DOWN_PRED ]= pred8x8l_horizontal_down_c; + h->pred8x8l[VERT_LEFT_PRED ]= pred8x8l_vertical_left_c; + h->pred8x8l[HOR_UP_PRED ]= pred8x8l_horizontal_up_c; + h->pred8x8l[LEFT_DC_PRED ]= pred8x8l_left_dc_c; + h->pred8x8l[TOP_DC_PRED ]= pred8x8l_top_dc_c; + h->pred8x8l[DC_128_PRED ]= pred8x8l_128_dc_c; + + h->pred8x8[VERT_PRED8x8 ]= pred8x8_vertical_c; + h->pred8x8[HOR_PRED8x8 ]= pred8x8_horizontal_c; + h->pred8x8[PLANE_PRED8x8 ]= pred8x8_plane_c; + if(codec_id != CODEC_ID_RV40){ + h->pred8x8[DC_PRED8x8 ]= pred8x8_dc_c; + h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_c; + h->pred8x8[TOP_DC_PRED8x8 ]= pred8x8_top_dc_c; + }else{ + h->pred8x8[DC_PRED8x8 ]= pred8x8_dc_rv40_c; + h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_rv40_c; + h->pred8x8[TOP_DC_PRED8x8 ]= pred8x8_top_dc_rv40_c; + } + h->pred8x8[DC_128_PRED8x8 ]= pred8x8_128_dc_c; + + h->pred16x16[DC_PRED8x8 ]= pred16x16_dc_c; + h->pred16x16[VERT_PRED8x8 ]= pred16x16_vertical_c; + h->pred16x16[HOR_PRED8x8 ]= pred16x16_horizontal_c; + h->pred16x16[PLANE_PRED8x8 ]= pred16x16_plane_c; + switch(codec_id){ + case CODEC_ID_SVQ3: + h->pred16x16[PLANE_PRED8x8 ]= pred16x16_plane_svq3_c; + break; + case CODEC_ID_RV40: + h->pred16x16[PLANE_PRED8x8 ]= pred16x16_plane_rv40_c; + break; + default: + h->pred16x16[PLANE_PRED8x8 ]= pred16x16_plane_c; + } + h->pred16x16[LEFT_DC_PRED8x8]= pred16x16_left_dc_c; + h->pred16x16[TOP_DC_PRED8x8 ]= pred16x16_top_dc_c; + h->pred16x16[DC_128_PRED8x8 ]= pred16x16_128_dc_c; +} diff --git a/contrib/ffmpeg/libavcodec/h264pred.h b/contrib/ffmpeg/libavcodec/h264pred.h new file mode 100644 index 000000000..111e5b369 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/h264pred.h @@ -0,0 +1,77 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * 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 h264pred.h + * H.264 / AVC / MPEG4 prediction functions. + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#ifndef FFMPEG_H264PRED_H +#define FFMPEG_H264PRED_H + +#include "common.h" + +/** + * Prediction types + */ +//@{ +#define VERT_PRED 0 +#define HOR_PRED 1 +#define DC_PRED 2 +#define DIAG_DOWN_LEFT_PRED 3 +#define DIAG_DOWN_RIGHT_PRED 4 +#define VERT_RIGHT_PRED 5 +#define HOR_DOWN_PRED 6 +#define VERT_LEFT_PRED 7 +#define HOR_UP_PRED 8 + +#define LEFT_DC_PRED 9 +#define TOP_DC_PRED 10 +#define DC_128_PRED 11 + +#define DIAG_DOWN_LEFT_PRED_RV40_NODOWN 12 +#define HOR_UP_PRED_RV40_NODOWN 13 +#define VERT_LEFT_PRED_RV40_NODOWN 14 + +#define DC_PRED8x8 0 +#define HOR_PRED8x8 1 +#define VERT_PRED8x8 2 +#define PLANE_PRED8x8 3 + +#define LEFT_DC_PRED8x8 4 +#define TOP_DC_PRED8x8 5 +#define DC_128_PRED8x8 6 +//@} + +/** + * Context for storing H.264 prediction functions + */ +typedef struct H264PredContext{ + void (*pred4x4 [9+3+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp? + void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride); + void (*pred8x8 [4+3])(uint8_t *src, int stride); + void (*pred16x16[4+3])(uint8_t *src, int stride); +}H264PredContext; + +void ff_h264_pred_init(H264PredContext *h, int codec_id); + +#endif /* FFMPEG_H264PRED_H */ diff --git a/contrib/ffmpeg/libavcodec/huffman.c b/contrib/ffmpeg/libavcodec/huffman.c new file mode 100644 index 000000000..43a78558e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/huffman.c @@ -0,0 +1,105 @@ +/** + * @file huffman.c + * huffman tree builder and VLC generator + * 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" +#include "bitstream.h" +#include "huffman.h" + +/* symbol for Huffman tree node */ +#define HNODE -1 + + +static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, Node *nodes, int node, uint32_t pfx, int pl, int *pos) +{ + int s; + + s = nodes[node].sym; + if(s != HNODE || !nodes[node].count){ + bits[*pos] = pfx; + lens[*pos] = pl; + xlat[*pos] = s; + (*pos)++; + }else{ + pfx <<= 1; + pl++; + get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0, pfx, pl, pos); + pfx |= 1; + get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0+1, pfx, pl, pos); + } +} + +static int build_huff_tree(VLC *vlc, Node *nodes, int head) +{ + uint32_t bits[256]; + int16_t lens[256]; + uint8_t xlat[256]; + int pos = 0; + + get_tree_codes(bits, lens, xlat, nodes, head, 0, 0, &pos); + return init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); +} + + +/** + * nodes size must be 2*nb_codes + * first nb_codes nodes.count must be set + */ +int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, + Node *nodes, huff_cmp_t cmp, int hnode_first) +{ + int i, j; + int cur_node; + int64_t sum = 0; + + for(i = 0; i < nb_codes; i++){ + nodes[i].sym = i; + nodes[i].n0 = -2; + sum += nodes[i].count; + } + + if(sum >> 31) { + av_log(avctx, AV_LOG_ERROR, "Too high symbol frequencies. Tree construction is not possible\n"); + return -1; + } + qsort(nodes, nb_codes, sizeof(Node), cmp); + cur_node = nb_codes; + nodes[nb_codes*2-1].count = 0; + for(i = 0; i < nb_codes*2-1; i += 2){ + nodes[cur_node].sym = HNODE; + nodes[cur_node].count = nodes[i].count + nodes[i+1].count; + nodes[cur_node].n0 = i; + for(j = cur_node; j > 0; j--){ + if(nodes[j].count > nodes[j-1].count || + (nodes[j].count == nodes[j-1].count && + (!hnode_first || nodes[j].n0==j-1 || nodes[j].n0==j-2 || + (nodes[j].sym!=HNODE && nodes[j-1].sym!=HNODE)))) + break; + FFSWAP(Node, nodes[j], nodes[j-1]); + } + cur_node++; + } + if(build_huff_tree(vlc, nodes, nb_codes*2-2) < 0){ + av_log(avctx, AV_LOG_ERROR, "Error building tree\n"); + return -1; + } + return 0; +} diff --git a/contrib/ffmpeg/libavcodec/huffman.h b/contrib/ffmpeg/libavcodec/huffman.h new file mode 100644 index 000000000..57fbefa1e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/huffman.h @@ -0,0 +1,39 @@ +/** + * @file huffman.h + * huffman tree builder and VLC generator + * Copyright (C) 2007 Aurelien Jacobs <aurel@gnuage.org> + * + * 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 + */ + +#ifndef FFMPEG_HUFFMAN_H +#define FFMPEG_HUFFMAN_H + +#include "avcodec.h" +#include "bitstream.h" + +typedef struct { + int16_t sym; + int16_t n0; + uint32_t count; +} Node; + +typedef int (*huff_cmp_t)(const void *va, const void *vb); +int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, + Node *nodes, huff_cmp_t cmp, int hnode_first); + +#endif /* FFMPEG_HUFFMAN_H */ diff --git a/contrib/ffmpeg/libavcodec/huffyuv.c b/contrib/ffmpeg/libavcodec/huffyuv.c index f68d8e7ef..dddcdf1db 100644 --- a/contrib/ffmpeg/libavcodec/huffyuv.c +++ b/contrib/ffmpeg/libavcodec/huffyuv.c @@ -3,6 +3,9 @@ * * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at> * + * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of + * the algorithm used + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,9 +21,6 @@ * 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 */ /** @@ -28,9 +28,8 @@ * huffyuv codec for libavcodec. */ -#include "common.h" -#include "bitstream.h" #include "avcodec.h" +#include "bitstream.h" #include "dsputil.h" #define VLC_BITS 11 @@ -71,7 +70,8 @@ typedef struct HYuvContext{ uint64_t stats[3][256]; uint8_t len[3][256]; uint32_t bits[3][256]; - VLC vlc[3]; + uint32_t pix_bgr_map[1<<VLC_BITS]; + VLC vlc[6]; //Y,U,V,YY,YU,YV AVFrame picture; uint8_t *bitstream_buffer; unsigned int bitstream_buffer_size; @@ -262,62 +262,131 @@ static int generate_bits_table(uint32_t *dst, uint8_t *len_table){ } #ifdef CONFIG_ENCODERS +typedef struct { + uint64_t val; + int name; +} heap_elem_t; + +static void heap_sift(heap_elem_t *h, int root, int size) +{ + while(root*2+1 < size) { + int child = root*2+1; + if(child < size-1 && h[child].val > h[child+1].val) + child++; + if(h[root].val > h[child].val) { + FFSWAP(heap_elem_t, h[root], h[child]); + root = child; + } else + break; + } +} + static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){ - uint64_t counts[2*size]; + heap_elem_t h[size]; int up[2*size]; + int len[2*size]; int offset, i, next; for(offset=1; ; offset<<=1){ for(i=0; i<size; i++){ - counts[i]= stats[i] + offset - 1; + h[i].name = i; + h[i].val = (stats[i] << 8) + offset; + } + for(i=size/2-1; i>=0; i--) + heap_sift(h, i, size); + + for(next=size; next<size*2-1; next++){ + // merge the two smallest entries, and put it back in the heap + uint64_t min1v = h[0].val; + up[h[0].name] = next; + h[0].val = INT64_MAX; + heap_sift(h, 0, size); + up[h[0].name] = next; + h[0].name = next; + h[0].val += min1v; + heap_sift(h, 0, size); } - for(next=size; next<size*2; next++){ - uint64_t min1, min2; - int min1_i, min2_i; - - min1=min2= INT64_MAX; - min1_i= min2_i=-1; + len[2*size-2] = 0; + for(i=2*size-3; i>=size; i--) + len[i] = len[up[i]] + 1; + for(i=0; i<size; i++) { + dst[i] = len[up[i]] + 1; + if(dst[i] >= 32) break; + } + if(i==size) break; + } +} +#endif /* CONFIG_ENCODERS */ - for(i=0; i<next; i++){ - if(min2 > counts[i]){ - if(min1 > counts[i]){ - min2= min1; - min2_i= min1_i; - min1= counts[i]; - min1_i= i; +static void generate_joint_tables(HYuvContext *s){ + uint16_t symbols[1<<VLC_BITS]; + uint16_t bits[1<<VLC_BITS]; + uint8_t len[1<<VLC_BITS]; + if(s->bitstream_bpp < 24){ + int p, i, y, u; + for(p=0; p<3; p++){ + for(i=y=0; y<256; y++){ + int len0 = s->len[0][y]; + int limit = VLC_BITS - len0; + if(limit <= 0) + continue; + for(u=0; u<256; u++){ + int len1 = s->len[p][u]; + if(len1 > limit) + continue; + len[i] = len0 + len1; + bits[i] = (s->bits[0][y] << len1) + s->bits[p][u]; + symbols[i] = (y<<8) + u; + if(symbols[i] != 0xffff) // reserved to mean "invalid" + i++; + } + } + free_vlc(&s->vlc[3+p]); + init_vlc_sparse(&s->vlc[3+p], VLC_BITS, i, len, 1, 1, bits, 2, 2, symbols, 2, 2, 0); + } + }else{ + uint8_t (*map)[4] = (uint8_t(*)[4])s->pix_bgr_map; + int i, b, g, r, code; + int p0 = s->decorrelate; + int p1 = !s->decorrelate; + // restrict the range to +/-16 becaues that's pretty much guaranteed to + // cover all the combinations that fit in 11 bits total, and it doesn't + // matter if we miss a few rare codes. + for(i=0, g=-16; g<16; g++){ + int len0 = s->len[p0][g&255]; + int limit0 = VLC_BITS - len0; + if(limit0 < 2) + continue; + for(b=-16; b<16; b++){ + int len1 = s->len[p1][b&255]; + int limit1 = limit0 - len1; + if(limit1 < 1) + continue; + code = (s->bits[p0][g&255] << len1) + s->bits[p1][b&255]; + for(r=-16; r<16; r++){ + int len2 = s->len[2][r&255]; + if(len2 > limit1) + continue; + len[i] = len0 + len1 + len2; + bits[i] = (code << len2) + s->bits[2][r&255]; + if(s->decorrelate){ + map[i][G] = g; + map[i][B] = g+b; + map[i][R] = g+r; }else{ - min2= counts[i]; - min2_i= i; + map[i][B] = g; + map[i][G] = b; + map[i][R] = r; } + 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<size; i++){ - int len; - int index=i; - - for(len=0; up[index] != -1; len++) - index= up[index]; - - if(len >= 32) break; - - dst[i]= len; } - if(i==size) break; + free_vlc(&s->vlc[3]); + init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0); } } -#endif /* CONFIG_ENCODERS */ static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){ GetBitContext gb; @@ -340,6 +409,8 @@ printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j); init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); } + generate_joint_tables(s); + return (get_bits_count(&gb)+7)/8; } @@ -368,6 +439,8 @@ static int read_old_huffman_tables(HYuvContext *s){ init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); } + generate_joint_tables(s); + return 0; #else av_log(s->avctx, AV_LOG_DEBUG, "v1 huffyuv is not supported \n"); @@ -654,16 +727,27 @@ static int encode_init(AVCodecContext *avctx) } #endif /* CONFIG_ENCODERS */ +/* TODO instead of restarting the read when the code isn't in the first level + * of the joint table, jump into the 2nd level of the individual table. */ +#define READ_2PIX(dst0, dst1, plane1){\ + uint16_t code = get_vlc2(&s->gb, s->vlc[3+plane1].table, VLC_BITS, 1);\ + if(code != 0xffff){\ + dst0 = code>>8;\ + dst1 = code;\ + }else{\ + dst0 = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);\ + dst1 = get_vlc2(&s->gb, s->vlc[plane1].table, VLC_BITS, 3);\ + }\ +} + static void decode_422_bitstream(HYuvContext *s, int count){ int i; count/=2; for(i=0; i<count; i++){ - s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); - s->temp[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); + READ_2PIX(s->temp[0][2*i ], s->temp[1][i], 1); + READ_2PIX(s->temp[0][2*i+1], s->temp[2][i], 2); } } @@ -673,8 +757,7 @@ static void decode_gray_bitstream(HYuvContext *s, int count){ count/=2; for(i=0; i<count; i++){ - s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); - s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + READ_2PIX(s->temp[0][2*i ], s->temp[0][2*i+1], 0); } } @@ -687,34 +770,43 @@ static int encode_422_bitstream(HYuvContext *s, int count){ return -1; } +#define LOAD4\ + int y0 = s->temp[0][2*i];\ + int y1 = s->temp[0][2*i+1];\ + int u0 = s->temp[1][i];\ + int v0 = s->temp[2][i]; + count/=2; if(s->flags&CODEC_FLAG_PASS1){ for(i=0; i<count; i++){ - s->stats[0][ s->temp[0][2*i ] ]++; - s->stats[1][ s->temp[1][ i ] ]++; - s->stats[0][ s->temp[0][2*i+1] ]++; - s->stats[2][ s->temp[2][ i ] ]++; + LOAD4; + s->stats[0][y0]++; + s->stats[1][u0]++; + s->stats[0][y1]++; + s->stats[2][v0]++; } } if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) return 0; if(s->context){ for(i=0; i<count; i++){ - s->stats[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 ] ]); + LOAD4; + s->stats[0][y0]++; + put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]); + s->stats[1][u0]++; + put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]); + s->stats[0][y1]++; + put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); + s->stats[2][v0]++; + put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]); } }else{ for(i=0; i<count; i++){ - put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); - put_bits(&s->pb, s->len[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 ] ]); + LOAD4; + put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]); + put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]); + put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); + put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]); } } return 0; @@ -728,11 +820,21 @@ static int encode_gray_bitstream(HYuvContext *s, int count){ return -1; } +#define LOAD2\ + int y0 = s->temp[0][2*i];\ + int y1 = s->temp[0][2*i+1]; +#define STAT2\ + s->stats[0][y0]++;\ + s->stats[0][y1]++; +#define WRITE2\ + put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);\ + put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); + count/=2; if(s->flags&CODEC_FLAG_PASS1){ for(i=0; i<count; i++){ - s->stats[0][ s->temp[0][2*i ] ]++; - s->stats[0][ s->temp[0][2*i+1] ]++; + LOAD2; + STAT2; } } if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) @@ -740,54 +842,51 @@ static int encode_gray_bitstream(HYuvContext *s, int count){ if(s->context){ for(i=0; i<count; i++){ - s->stats[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] ]); + LOAD2; + STAT2; + WRITE2; } }else{ for(i=0; i<count; i++){ - put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); - put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]); + LOAD2; + WRITE2; } } return 0; } #endif /* CONFIG_ENCODERS */ -static void decode_bgr_bitstream(HYuvContext *s, int count){ +static av_always_inline void decode_bgr_1(HYuvContext *s, int count, int decorrelate, int alpha){ int i; - - if(s->decorrelate){ - if(s->bitstream_bpp==24){ - for(i=0; i<count; i++){ - s->temp[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]; - } + for(i=0; i<count; i++){ + int code = get_vlc2(&s->gb, s->vlc[3].table, VLC_BITS, 1); + if(code != -1){ + *(uint32_t*)&s->temp[0][4*i] = s->pix_bgr_map[code]; + }else if(decorrelate){ + s->temp[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; i<count; i++){ - s->temp[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); //?! - } + s->temp[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); } + if(alpha) + get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?! + } +} + +static void decode_bgr_bitstream(HYuvContext *s, int count){ + if(s->decorrelate){ + if(s->bitstream_bpp==24) + decode_bgr_1(s, count, 1, 0); + else + decode_bgr_1(s, count, 1, 1); }else{ - if(s->bitstream_bpp==24){ - for(i=0; i<count; i++){ - s->temp[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; i<count; i++){ - s->temp[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); //?! - } - } + if(s->bitstream_bpp==24) + decode_bgr_1(s, count, 0, 0); + else + decode_bgr_1(s, count, 0, 1); } } @@ -799,35 +898,34 @@ static int encode_bgr_bitstream(HYuvContext *s, int count){ return -1; } - if((s->flags&CODEC_FLAG_PASS1) && (s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)){ - for(i=0; i<count; i++){ - int g= s->temp[0][4*i+G]; - int b= (s->temp[0][4*i+B] - g) & 0xff; +#define LOAD3\ + int g= s->temp[0][4*i+G];\ + int b= (s->temp[0][4*i+B] - g) & 0xff;\ int r= (s->temp[0][4*i+R] - g) & 0xff; - s->stats[0][b]++; - s->stats[1][g]++; +#define STAT3\ + s->stats[0][b]++;\ + s->stats[1][g]++;\ s->stats[2][r]++; +#define WRITE3\ + put_bits(&s->pb, s->len[1][g], s->bits[1][g]);\ + put_bits(&s->pb, s->len[0][b], s->bits[0][b]);\ + put_bits(&s->pb, s->len[2][r], s->bits[2][r]); + + if((s->flags&CODEC_FLAG_PASS1) && (s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)){ + for(i=0; i<count; i++){ + LOAD3; + STAT3; } }else if(s->context || (s->flags&CODEC_FLAG_PASS1)){ for(i=0; i<count; i++){ - int g= s->temp[0][4*i+G]; - int b= (s->temp[0][4*i+B] - g) & 0xff; - int r= (s->temp[0][4*i+R] - g) & 0xff; - s->stats[0][b]++; - s->stats[1][g]++; - s->stats[2][r]++; - put_bits(&s->pb, s->len[1][g], s->bits[1][g]); - put_bits(&s->pb, s->len[0][b], s->bits[0][b]); - put_bits(&s->pb, s->len[2][r], s->bits[2][r]); + LOAD3; + STAT3; + WRITE3; } }else{ for(i=0; i<count; i++){ - int g= s->temp[0][4*i+G]; - int b= (s->temp[0][4*i+B] - g) & 0xff; - int r= (s->temp[0][4*i+R] - g) & 0xff; - put_bits(&s->pb, s->len[1][g], s->bits[1][g]); - put_bits(&s->pb, s->len[0][b], s->bits[0][b]); - put_bits(&s->pb, s->len[2][r], s->bits[2][r]); + LOAD3; + WRITE3; } } return 0; @@ -861,7 +959,7 @@ static void draw_slice(HYuvContext *s, int y){ s->last_slice_end= y + h; } -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){ +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size){ HYuvContext *s = avctx->priv_data; const int width= s->width; const int width2= s->width>>1; @@ -874,7 +972,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 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); + s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (const uint32_t*)buf, buf_size/4); if(p->data[0]) avctx->release_buffer(avctx, p); @@ -1071,7 +1169,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 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 + for(y=s->height-2; y>=0; y--){ //Yes it is 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); @@ -1120,7 +1218,7 @@ static int decode_end(AVCodecContext *avctx) common_end(s); av_freep(&s->bitstream_buffer); - for(i=0; i<3; i++){ + for(i=0; i<6; i++){ free_vlc(&s->vlc[i]); } @@ -1310,11 +1408,11 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, snprintf(p, end-p, "\n"); p++; } - } + } else + avctx->stats_out[0] = '\0'; 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++; diff --git a/contrib/ffmpeg/libavcodec/i386/cavsdsp_mmx.c b/contrib/ffmpeg/libavcodec/i386/cavsdsp_mmx.c index 51d519a5c..141382fb0 100644 --- a/contrib/ffmpeg/libavcodec/i386/cavsdsp_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/cavsdsp_mmx.c @@ -2,7 +2,7 @@ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * - * MMX optimised DSP functions, based on H.264 optimisations by + * MMX-optimized DSP functions, based on H.264 optimizations by * Michael Niedermayer and Loren Merritt * * This file is part of FFmpeg. @@ -19,41 +19,19 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" +#include "dsputil_mmx.h" #include "common.h" -DECLARE_ALIGNED_8(static const uint64_t,ff_pw_4 ) = 0x0004000400040004ULL; -DECLARE_ALIGNED_8(static const uint64_t,ff_pw_5 ) = 0x0005000500050005ULL; -DECLARE_ALIGNED_8(static const uint64_t,ff_pw_7 ) = 0x0007000700070007ULL; -DECLARE_ALIGNED_8(static const uint64_t,ff_pw_42) = 0x002A002A002A002AULL; -DECLARE_ALIGNED_8(static const uint64_t,ff_pw_64) = 0x0040004000400040ULL; -DECLARE_ALIGNED_8(static const uint64_t,ff_pw_96) = 0x0060006000600060ULL; - /***************************************************************************** * * inverse transform * ****************************************************************************/ -#define SUMSUB_BA( a, b ) \ - "paddw "#b", "#a" \n\t"\ - "paddw "#b", "#b" \n\t"\ - "psubw "#a", "#b" \n\t" - -#define SBUTTERFLY(a,b,t,n)\ - "movq " #a ", " #t " \n\t" /* abcd */\ - "punpckl" #n " " #b ", " #a " \n\t" /* aebf */\ - "punpckh" #n " " #b ", " #t " \n\t" /* cgdh */ - -#define TRANSPOSE4(a,b,c,d,t)\ - SBUTTERFLY(a,b,t,wd) /* a=aebf t=cgdh */\ - SBUTTERFLY(c,d,b,wd) /* c=imjn b=kolp */\ - SBUTTERFLY(a,c,d,dq) /* a=aeim d=bfjn */\ - SBUTTERFLY(t,b,c,dq) /* t=cgko c=dhlp */ - static inline void cavs_idct8_1d(int16_t *block, uint64_t bias) { asm volatile( diff --git a/contrib/ffmpeg/libavcodec/i386/cputest.c b/contrib/ffmpeg/libavcodec/i386/cputest.c index 0705ab3e5..57b85ff9c 100644 --- a/contrib/ffmpeg/libavcodec/i386/cputest.c +++ b/contrib/ffmpeg/libavcodec/i386/cputest.c @@ -21,7 +21,7 @@ */ #include <stdlib.h> -#include "../dsputil.h" +#include "dsputil.h" #undef printf @@ -35,7 +35,7 @@ /* ebx saving is necessary for PIC. gcc seems unable to see it alone */ #define cpuid(index,eax,ebx,ecx,edx)\ - __asm __volatile\ + asm volatile\ ("mov %%"REG_b", %%"REG_S"\n\t"\ "cpuid\n\t"\ "xchg %%"REG_b", %%"REG_S\ @@ -80,15 +80,19 @@ int mm_support(void) if(max_std_level >= 1){ cpuid(1, eax, ebx, ecx, std_caps); if (std_caps & (1<<23)) - rval |= MM_MMX; + rval |= FF_MM_MMX; if (std_caps & (1<<25)) - rval |= MM_MMXEXT | MM_SSE; + rval |= FF_MM_MMXEXT +#if !defined(__GNUC__) || __GNUC__ > 2 + | FF_MM_SSE; if (std_caps & (1<<26)) - rval |= MM_SSE2; + rval |= FF_MM_SSE2; if (ecx & 1) - rval |= MM_SSE3; + rval |= FF_MM_SSE3; if (ecx & 0x00000200 ) - rval |= MM_SSSE3; + rval |= FF_MM_SSSE3 +#endif + ; } cpuid(0x80000000, max_ext_level, ebx, ecx, edx); @@ -96,30 +100,30 @@ int mm_support(void) if(max_ext_level >= 0x80000001){ cpuid(0x80000001, eax, ebx, ecx, ext_caps); if (ext_caps & (1<<31)) - rval |= MM_3DNOW; + rval |= FF_MM_3DNOW; if (ext_caps & (1<<30)) - rval |= MM_3DNOWEXT; + rval |= FF_MM_3DNOWEXT; if (ext_caps & (1<<23)) - rval |= MM_MMX; + rval |= FF_MM_MMX; if (ext_caps & (1<<22)) - rval |= MM_MMXEXT; + rval |= FF_MM_MMXEXT; } #if 0 av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s%s%s\n", - (rval&MM_MMX) ? "MMX ":"", - (rval&MM_MMXEXT) ? "MMX2 ":"", - (rval&MM_SSE) ? "SSE ":"", - (rval&MM_SSE2) ? "SSE2 ":"", - (rval&MM_SSE3) ? "SSE3 ":"", - (rval&MM_SSSE3) ? "SSSE3 ":"", - (rval&MM_3DNOW) ? "3DNow ":"", - (rval&MM_3DNOWEXT) ? "3DNowExt ":""); + (rval&FF_MM_MMX) ? "MMX ":"", + (rval&FF_MM_MMXEXT) ? "MMX2 ":"", + (rval&FF_MM_SSE) ? "SSE ":"", + (rval&FF_MM_SSE2) ? "SSE2 ":"", + (rval&FF_MM_SSE3) ? "SSE3 ":"", + (rval&FF_MM_SSSE3) ? "SSSE3 ":"", + (rval&FF_MM_3DNOW) ? "3DNow ":"", + (rval&FF_MM_3DNOWEXT) ? "3DNowExt ":""); #endif return rval; } -#ifdef __TEST__ +#ifdef TEST int main ( void ) { int mm_flags; diff --git a/contrib/ffmpeg/libavcodec/i386/dsputil_h264_template_mmx.c b/contrib/ffmpeg/libavcodec/i386/dsputil_h264_template_mmx.c index a943a0371..e36c44075 100644 --- a/contrib/ffmpeg/libavcodec/i386/dsputil_h264_template_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/dsputil_h264_template_mmx.c @@ -25,8 +25,10 @@ * H264_CHROMA_OP must be defined to empty for put and pavgb/pavgusb for avg * H264_CHROMA_MC8_MV0 must be defined to a (put|avg)_pixels8 function */ -static void H264_CHROMA_MC8_TMPL(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) +static void H264_CHROMA_MC8_TMPL(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y, int rnd) { + DECLARE_ALIGNED_8(static const uint64_t, ff_pw_28) = 0x001C001C001C001CULL; + const uint64_t *rnd_reg; DECLARE_ALIGNED_8(uint64_t, AA); DECLARE_ALIGNED_8(uint64_t, DD); int i; @@ -44,16 +46,17 @@ static void H264_CHROMA_MC8_TMPL(uint8_t *dst/*align 8*/, uint8_t *src/*align 1* /* 1 dimensional filter only */ const int dxy = x ? 1 : stride; + rnd_reg = rnd ? &ff_pw_4 : &ff_pw_3; + asm volatile( "movd %0, %%mm5\n\t" "movq %1, %%mm4\n\t" + "movq %2, %%mm6\n\t" /* mm6 = rnd */ "punpcklwd %%mm5, %%mm5\n\t" "punpckldq %%mm5, %%mm5\n\t" /* mm5 = B = x */ - "movq %%mm4, %%mm6\n\t" "pxor %%mm7, %%mm7\n\t" "psubw %%mm5, %%mm4\n\t" /* mm4 = A = 8-x */ - "psrlw $1, %%mm6\n\t" /* mm6 = 4 */ - :: "rm"(x+y), "m"(ff_pw_8)); + :: "rm"(x+y), "m"(ff_pw_8), "m"(*rnd_reg)); for(i=0; i<h; i++) { asm volatile( @@ -95,6 +98,7 @@ static void H264_CHROMA_MC8_TMPL(uint8_t *dst/*align 8*/, uint8_t *src/*align 1* } /* general case, bilinear */ + rnd_reg = rnd ? &ff_pw_32.a : &ff_pw_28; asm volatile("movd %2, %%mm4\n\t" "movd %3, %%mm6\n\t" "punpcklwd %%mm4, %%mm4\n\t" @@ -177,7 +181,7 @@ static void H264_CHROMA_MC8_TMPL(uint8_t *dst/*align 8*/, uint8_t *src/*align 1* "packuswb %%mm3, %%mm2\n\t" H264_CHROMA_OP(%0, %%mm2) "movq %%mm2, %0\n\t" - : "=m" (dst[0]) : "m" (ff_pw_32)); + : "=m" (dst[0]) : "m" (*rnd_reg)); dst+= stride; } } @@ -251,7 +255,7 @@ static void H264_CHROMA_MC4_TMPL(uint8_t *dst/*align 4*/, uint8_t *src/*align 1* } #ifdef H264_CHROMA_MC2_TMPL -static void H264_CHROMA_MC2_TMPL(uint8_t *dst/*align 2*/, uint8_t *src/*align 1*/, long stride, int h, int x, int y) +static void H264_CHROMA_MC2_TMPL(uint8_t *dst/*align 2*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) { int tmp = ((1<<16)-1)*x + 8; int CD= tmp*y; @@ -297,7 +301,7 @@ static void H264_CHROMA_MC2_TMPL(uint8_t *dst/*align 2*/, uint8_t *src/*align 1* "sub $1, %2\n\t" "jnz 1b\n\t" : "+r" (dst), "+r"(src), "+r"(h) - : "m" (ff_pw_32), "r"(stride) + : "m" (ff_pw_32), "r"((long)stride) : "%esi"); } diff --git a/contrib/ffmpeg/libavcodec/i386/dsputil_mmx.c b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx.c index 23a717acd..30e938312 100644 --- a/contrib/ffmpeg/libavcodec/i386/dsputil_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx.c @@ -22,11 +22,15 @@ * MMX optimization by Nick Kurshev <nickols_k@mail.ru> */ -#include "../dsputil.h" -#include "../simple_idct.h" -#include "../mpegvideo.h" +#include "dsputil.h" +#include "dsputil_mmx.h" +#include "simple_idct.h" +#include "mpegvideo.h" #include "x86_cpu.h" #include "mmx.h" +#include "vp3dsp_mmx.h" +#include "vp3dsp_sse2.h" +#include "h263.h" //#undef NDEBUG //#include <assert.h> @@ -37,58 +41,58 @@ extern void ff_idct_xvid_mmx2(short *block); int mm_flags; /* multimedia extension flags */ /* pixel operations */ -static const uint64_t mm_bone attribute_used __attribute__ ((aligned(8))) = 0x0101010101010101ULL; -static const uint64_t mm_wone attribute_used __attribute__ ((aligned(8))) = 0x0001000100010001ULL; -static const uint64_t mm_wtwo attribute_used __attribute__ ((aligned(8))) = 0x0002000200020002ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_bone) = 0x0101010101010101ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_wtwo) = 0x0002000200020002ULL; -static const uint64_t ff_pdw_80000000[2] attribute_used __attribute__ ((aligned(16))) = +DECLARE_ALIGNED_16(const uint64_t, ff_pdw_80000000[2]) = {0x8000000080000000ULL, 0x8000000080000000ULL}; -static const uint64_t ff_pw_20 attribute_used __attribute__ ((aligned(8))) = 0x0014001400140014ULL; -static const uint64_t ff_pw_3 attribute_used __attribute__ ((aligned(8))) = 0x0003000300030003ULL; -static const uint64_t ff_pw_4 attribute_used __attribute__ ((aligned(8))) = 0x0004000400040004ULL; -static const uint64_t ff_pw_5 attribute_used __attribute__ ((aligned(8))) = 0x0005000500050005ULL; -static const uint64_t ff_pw_8 attribute_used __attribute__ ((aligned(8))) = 0x0008000800080008ULL; -static const uint64_t ff_pw_16 attribute_used __attribute__ ((aligned(8))) = 0x0010001000100010ULL; -static const uint64_t ff_pw_32 attribute_used __attribute__ ((aligned(8))) = 0x0020002000200020ULL; -static const uint64_t ff_pw_64 attribute_used __attribute__ ((aligned(8))) = 0x0040004000400040ULL; -static const uint64_t ff_pw_15 attribute_used __attribute__ ((aligned(8))) = 0x000F000F000F000FULL; - -static const uint64_t ff_pb_1 attribute_used __attribute__ ((aligned(8))) = 0x0101010101010101ULL; -static const uint64_t ff_pb_3 attribute_used __attribute__ ((aligned(8))) = 0x0303030303030303ULL; -static const uint64_t ff_pb_7 attribute_used __attribute__ ((aligned(8))) = 0x0707070707070707ULL; -static const uint64_t ff_pb_3F attribute_used __attribute__ ((aligned(8))) = 0x3F3F3F3F3F3F3F3FULL; -static const uint64_t ff_pb_A1 attribute_used __attribute__ ((aligned(8))) = 0xA1A1A1A1A1A1A1A1ULL; -static const uint64_t ff_pb_5F attribute_used __attribute__ ((aligned(8))) = 0x5F5F5F5F5F5F5F5FULL; -static const uint64_t ff_pb_FC attribute_used __attribute__ ((aligned(8))) = 0xFCFCFCFCFCFCFCFCULL; - -#define JUMPALIGN() __asm __volatile (ASMALIGN(3)::) -#define MOVQ_ZERO(regd) __asm __volatile ("pxor %%" #regd ", %%" #regd ::) - -#define MOVQ_WONE(regd) \ - __asm __volatile ( \ - "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ - "psrlw $15, %%" #regd ::) +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_3 ) = 0x0003000300030003ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_4 ) = 0x0004000400040004ULL; +DECLARE_ALIGNED_16(const xmm_t, ff_pw_5 ) = {0x0005000500050005ULL, 0x0005000500050005ULL}; +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_8 ) = 0x0008000800080008ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_15 ) = 0x000F000F000F000FULL; +DECLARE_ALIGNED_16(const xmm_t, ff_pw_16 ) = {0x0010001000100010ULL, 0x0010001000100010ULL}; +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_20 ) = 0x0014001400140014ULL; +DECLARE_ALIGNED_16(const xmm_t, ff_pw_32 ) = {0x0020002000200020ULL, 0x0020002000200020ULL}; +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_42 ) = 0x002A002A002A002AULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_64 ) = 0x0040004000400040ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_96 ) = 0x0060006000600060ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_128) = 0x0080008000800080ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pw_255) = 0x00ff00ff00ff00ffULL; + +DECLARE_ALIGNED_8 (const uint64_t, ff_pb_1 ) = 0x0101010101010101ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pb_3 ) = 0x0303030303030303ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pb_7 ) = 0x0707070707070707ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pb_3F ) = 0x3F3F3F3F3F3F3F3FULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pb_A1 ) = 0xA1A1A1A1A1A1A1A1ULL; +DECLARE_ALIGNED_8 (const uint64_t, ff_pb_FC ) = 0xFCFCFCFCFCFCFCFCULL; + +DECLARE_ALIGNED_16(const double, ff_pd_1[2]) = { 1.0, 1.0 }; +DECLARE_ALIGNED_16(const double, ff_pd_2[2]) = { 2.0, 2.0 }; + +#define JUMPALIGN() asm volatile (ASMALIGN(3)::) +#define MOVQ_ZERO(regd) asm volatile ("pxor %%" #regd ", %%" #regd ::) #define MOVQ_BFE(regd) \ - __asm __volatile ( \ + asm volatile ( \ "pcmpeqd %%" #regd ", %%" #regd " \n\t"\ "paddb %%" #regd ", %%" #regd " \n\t" ::) #ifndef PIC -#define MOVQ_BONE(regd) __asm __volatile ("movq %0, %%" #regd " \n\t" ::"m"(mm_bone)) -#define MOVQ_WTWO(regd) __asm __volatile ("movq %0, %%" #regd " \n\t" ::"m"(mm_wtwo)) +#define MOVQ_BONE(regd) asm volatile ("movq %0, %%" #regd " \n\t" ::"m"(ff_bone)) +#define MOVQ_WTWO(regd) asm volatile ("movq %0, %%" #regd " \n\t" ::"m"(ff_wtwo)) #else // for shared library it's better to use this way for accessing constants // pcmpeqd -> -1 #define MOVQ_BONE(regd) \ - __asm __volatile ( \ + asm volatile ( \ "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ "psrlw $15, %%" #regd " \n\t" \ "packuswb %%" #regd ", %%" #regd " \n\t" ::) #define MOVQ_WTWO(regd) \ - __asm __volatile ( \ + asm volatile ( \ "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ "psrlw $15, %%" #regd " \n\t" \ "psllw $1, %%" #regd " \n\t"::) @@ -175,7 +179,6 @@ static const uint64_t ff_pb_FC attribute_used __attribute__ ((aligned(8))) = 0xF /* 3Dnow specific */ #define DEF(x) x ## _3dnow -/* for Athlons PAVGUSB is prefered */ #define PAVGB "pavgusb" #include "dsputil_mmx_avg.h" @@ -196,73 +199,22 @@ static const uint64_t ff_pb_FC attribute_used __attribute__ ((aligned(8))) = 0xF #undef DEF #undef PAVGB -#define SBUTTERFLY(a,b,t,n)\ - "movq " #a ", " #t " \n\t" /* abcd */\ - "punpckl" #n " " #b ", " #a " \n\t" /* aebf */\ - "punpckh" #n " " #b ", " #t " \n\t" /* cgdh */\ +#define put_no_rnd_pixels16_mmx put_pixels16_mmx +#define put_no_rnd_pixels8_mmx put_pixels8_mmx +#define put_pixels16_mmx2 put_pixels16_mmx +#define put_pixels8_mmx2 put_pixels8_mmx +#define put_pixels4_mmx2 put_pixels4_mmx +#define put_no_rnd_pixels16_mmx2 put_no_rnd_pixels16_mmx +#define put_no_rnd_pixels8_mmx2 put_no_rnd_pixels8_mmx +#define put_pixels16_3dnow put_pixels16_mmx +#define put_pixels8_3dnow put_pixels8_mmx +#define put_pixels4_3dnow put_pixels4_mmx +#define put_no_rnd_pixels16_3dnow put_no_rnd_pixels16_mmx +#define put_no_rnd_pixels8_3dnow put_no_rnd_pixels8_mmx /***********************************/ /* standard MMX */ -#ifdef CONFIG_ENCODERS -static void get_pixels_mmx(DCTELEM *block, const uint8_t *pixels, int line_size) -{ - asm volatile( - "mov $-128, %%"REG_a" \n\t" - "pxor %%mm7, %%mm7 \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%0), %%mm0 \n\t" - "movq (%0, %2), %%mm2 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "movq %%mm0, (%1, %%"REG_a") \n\t" - "movq %%mm1, 8(%1, %%"REG_a") \n\t" - "movq %%mm2, 16(%1, %%"REG_a") \n\t" - "movq %%mm3, 24(%1, %%"REG_a") \n\t" - "add %3, %0 \n\t" - "add $32, %%"REG_a" \n\t" - "js 1b \n\t" - : "+r" (pixels) - : "r" (block+64), "r" ((long)line_size), "r" ((long)line_size*2) - : "%"REG_a - ); -} - -static inline void diff_pixels_mmx(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride) -{ - asm volatile( - "pxor %%mm7, %%mm7 \n\t" - "mov $-128, %%"REG_a" \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%0), %%mm0 \n\t" - "movq (%1), %%mm2 \n\t" - "movq %%mm0, %%mm1 \n\t" - "movq %%mm2, %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "psubw %%mm2, %%mm0 \n\t" - "psubw %%mm3, %%mm1 \n\t" - "movq %%mm0, (%2, %%"REG_a") \n\t" - "movq %%mm1, 8(%2, %%"REG_a") \n\t" - "add %3, %0 \n\t" - "add %3, %1 \n\t" - "add $16, %%"REG_a" \n\t" - "jnz 1b \n\t" - : "+r" (s1), "+r" (s2) - : "r" (block+64), "r" ((long)stride) - : "%"REG_a - ); -} -#endif //CONFIG_ENCODERS - void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size) { const DCTELEM *p; @@ -272,7 +224,7 @@ void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size p = block; pix = pixels; /* unrolled loop */ - __asm __volatile( + asm volatile( "movq %3, %%mm0 \n\t" "movq 8%3, %%mm1 \n\t" "movq 16%3, %%mm2 \n\t" @@ -297,7 +249,7 @@ void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size // if here would be an exact copy of the code above // compiler would generate some very strange code // thus using "r" - __asm __volatile( + asm volatile( "movq (%3), %%mm0 \n\t" "movq 8(%3), %%mm1 \n\t" "movq 16(%3), %%mm2 \n\t" @@ -348,7 +300,7 @@ void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size MOVQ_ZERO(mm7); i = 4; do { - __asm __volatile( + asm volatile( "movq (%2), %%mm0 \n\t" "movq 8(%2), %%mm1 \n\t" "movq 16(%2), %%mm2 \n\t" @@ -379,7 +331,7 @@ void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size static void put_pixels4_mmx(uint8_t *block, const uint8_t *pixels, int line_size, int h) { - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" ASMALIGN(3) "1: \n\t" @@ -405,7 +357,7 @@ static void put_pixels4_mmx(uint8_t *block, const uint8_t *pixels, int line_size static void put_pixels8_mmx(uint8_t *block, const uint8_t *pixels, int line_size, int h) { - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" ASMALIGN(3) "1: \n\t" @@ -431,7 +383,7 @@ static void put_pixels8_mmx(uint8_t *block, const uint8_t *pixels, int line_size static void put_pixels16_mmx(uint8_t *block, const uint8_t *pixels, int line_size, int h) { - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" ASMALIGN(3) "1: \n\t" @@ -463,9 +415,57 @@ static void put_pixels16_mmx(uint8_t *block, const uint8_t *pixels, int line_siz ); } +static void put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + asm volatile( + "1: \n\t" + "movdqu (%1), %%xmm0 \n\t" + "movdqu (%1,%3), %%xmm1 \n\t" + "movdqu (%1,%3,2), %%xmm2 \n\t" + "movdqu (%1,%4), %%xmm3 \n\t" + "movdqa %%xmm0, (%2) \n\t" + "movdqa %%xmm1, (%2,%3) \n\t" + "movdqa %%xmm2, (%2,%3,2) \n\t" + "movdqa %%xmm3, (%2,%4) \n\t" + "subl $4, %0 \n\t" + "lea (%1,%3,4), %1 \n\t" + "lea (%2,%3,4), %2 \n\t" + "jnz 1b \n\t" + : "+g"(h), "+r" (pixels), "+r" (block) + : "r"((long)line_size), "r"(3L*line_size) + : "memory" + ); +} + +static void avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + asm volatile( + "1: \n\t" + "movdqu (%1), %%xmm0 \n\t" + "movdqu (%1,%3), %%xmm1 \n\t" + "movdqu (%1,%3,2), %%xmm2 \n\t" + "movdqu (%1,%4), %%xmm3 \n\t" + "pavgb (%2), %%xmm0 \n\t" + "pavgb (%2,%3), %%xmm1 \n\t" + "pavgb (%2,%3,2), %%xmm2 \n\t" + "pavgb (%2,%4), %%xmm3 \n\t" + "movdqa %%xmm0, (%2) \n\t" + "movdqa %%xmm1, (%2,%3) \n\t" + "movdqa %%xmm2, (%2,%3,2) \n\t" + "movdqa %%xmm3, (%2,%4) \n\t" + "subl $4, %0 \n\t" + "lea (%1,%3,4), %1 \n\t" + "lea (%2,%3,4), %2 \n\t" + "jnz 1b \n\t" + : "+g"(h), "+r" (pixels), "+r" (block) + : "r"((long)line_size), "r"(3L*line_size) + : "memory" + ); +} + static void clear_blocks_mmx(DCTELEM *blocks) { - __asm __volatile( + asm volatile( "pxor %%mm7, %%mm7 \n\t" "mov $-128*6, %%"REG_a" \n\t" "1: \n\t" @@ -480,46 +480,6 @@ static void clear_blocks_mmx(DCTELEM *blocks) ); } -#ifdef CONFIG_ENCODERS -static int pix_sum16_mmx(uint8_t * pix, int line_size){ - const int h=16; - int sum; - long index= -line_size*h; - - __asm __volatile( - "pxor %%mm7, %%mm7 \n\t" - "pxor %%mm6, %%mm6 \n\t" - "1: \n\t" - "movq (%2, %1), %%mm0 \n\t" - "movq (%2, %1), %%mm1 \n\t" - "movq 8(%2, %1), %%mm2 \n\t" - "movq 8(%2, %1), %%mm3 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpckhbw %%mm7, %%mm1 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" - "punpckhbw %%mm7, %%mm3 \n\t" - "paddw %%mm0, %%mm1 \n\t" - "paddw %%mm2, %%mm3 \n\t" - "paddw %%mm1, %%mm3 \n\t" - "paddw %%mm3, %%mm6 \n\t" - "add %3, %1 \n\t" - " js 1b \n\t" - "movq %%mm6, %%mm5 \n\t" - "psrlq $32, %%mm6 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "movq %%mm6, %%mm5 \n\t" - "psrlq $16, %%mm6 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "movd %%mm6, %0 \n\t" - "andl $0xFFFF, %0 \n\t" - : "=&r" (sum), "+r" (index) - : "r" (pix - index), "r" ((long)line_size) - ); - - return sum; -} -#endif //CONFIG_ENCODERS - static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w){ long i=0; asm volatile( @@ -542,6 +502,26 @@ static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w){ dst[i+0] += src[i+0]; } +static void add_bytes_l2_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ + long i=0; + asm volatile( + "1: \n\t" + "movq (%2, %0), %%mm0 \n\t" + "movq 8(%2, %0), %%mm1 \n\t" + "paddb (%3, %0), %%mm0 \n\t" + "paddb 8(%3, %0), %%mm1 \n\t" + "movq %%mm0, (%1, %0) \n\t" + "movq %%mm1, 8(%1, %0) \n\t" + "add $16, %0 \n\t" + "cmp %4, %0 \n\t" + " jb 1b \n\t" + : "+r" (i) + : "r"(dst), "r"(src1), "r"(src2), "r"((long)w-15) + ); + for(; i<w; i++) + dst[i] = src1[i] + src2[i]; +} + #define H263_LOOP_FILTER \ "pxor %%mm7, %%mm7 \n\t"\ "movq %0, %%mm0 \n\t"\ @@ -614,6 +594,7 @@ static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w){ "paddb %%mm1, %%mm6 \n\t" static void h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale){ + if(ENABLE_ANY_H263) { const int strength= ff_h263_loop_filter_strength[qscale]; asm volatile( @@ -630,6 +611,7 @@ static void h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale){ "+m" (*(uint64_t*)(src + 1*stride)) : "g" (2*strength), "m"(ff_pb_FC) ); + } } static inline void transpose4x4(uint8_t *dst, uint8_t *src, int dst_stride, int src_stride){ @@ -662,8 +644,9 @@ static inline void transpose4x4(uint8_t *dst, uint8_t *src, int dst_stride, int } static void h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale){ + if(ENABLE_ANY_H263) { const int strength= ff_h263_loop_filter_strength[qscale]; - uint64_t temp[4] __attribute__ ((aligned(8))); + DECLARE_ALIGNED(8, uint64_t, temp[4]); uint8_t *btemp= (uint8_t*)temp; src -= 2; @@ -710,1062 +693,82 @@ static void h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale){ "r" ((long) stride ), "r" ((long)(3*stride)) ); + } } -#ifdef CONFIG_ENCODERS -static int pix_norm1_mmx(uint8_t *pix, int line_size) { - int tmp; - asm volatile ( - "movl $16,%%ecx\n" - "pxor %%mm0,%%mm0\n" - "pxor %%mm7,%%mm7\n" - "1:\n" - "movq (%0),%%mm2\n" /* mm2 = pix[0-7] */ - "movq 8(%0),%%mm3\n" /* mm3 = pix[8-15] */ - - "movq %%mm2,%%mm1\n" /* mm1 = mm2 = pix[0-7] */ - - "punpckhbw %%mm0,%%mm1\n" /* mm1 = [pix4-7] */ - "punpcklbw %%mm0,%%mm2\n" /* mm2 = [pix0-3] */ - - "movq %%mm3,%%mm4\n" /* mm4 = mm3 = pix[8-15] */ - "punpckhbw %%mm0,%%mm3\n" /* mm3 = [pix12-15] */ - "punpcklbw %%mm0,%%mm4\n" /* mm4 = [pix8-11] */ - - "pmaddwd %%mm1,%%mm1\n" /* mm1 = (pix0^2+pix1^2,pix2^2+pix3^2) */ - "pmaddwd %%mm2,%%mm2\n" /* mm2 = (pix4^2+pix5^2,pix6^2+pix7^2) */ - - "pmaddwd %%mm3,%%mm3\n" - "pmaddwd %%mm4,%%mm4\n" - - "paddd %%mm1,%%mm2\n" /* mm2 = (pix0^2+pix1^2+pix4^2+pix5^2, - pix2^2+pix3^2+pix6^2+pix7^2) */ - "paddd %%mm3,%%mm4\n" - "paddd %%mm2,%%mm7\n" - - "add %2, %0\n" - "paddd %%mm4,%%mm7\n" - "dec %%ecx\n" - "jnz 1b\n" - - "movq %%mm7,%%mm1\n" - "psrlq $32, %%mm7\n" /* shift hi dword to lo */ - "paddd %%mm7,%%mm1\n" - "movd %%mm1,%1\n" - : "+r" (pix), "=r"(tmp) : "r" ((long)line_size) : "%ecx" ); - return tmp; -} - -static int sse8_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - int tmp; - asm volatile ( - "movl %4,%%ecx\n" - "shr $1,%%ecx\n" - "pxor %%mm0,%%mm0\n" /* mm0 = 0 */ - "pxor %%mm7,%%mm7\n" /* mm7 holds the sum */ - "1:\n" - "movq (%0),%%mm1\n" /* mm1 = pix1[0][0-7] */ - "movq (%1),%%mm2\n" /* mm2 = pix2[0][0-7] */ - "movq (%0,%3),%%mm3\n" /* mm3 = pix1[1][0-7] */ - "movq (%1,%3),%%mm4\n" /* mm4 = pix2[1][0-7] */ - - /* todo: mm1-mm2, mm3-mm4 */ - /* algo: substract mm1 from mm2 with saturation and vice versa */ - /* OR the results to get absolute difference */ - "movq %%mm1,%%mm5\n" - "movq %%mm3,%%mm6\n" - "psubusb %%mm2,%%mm1\n" - "psubusb %%mm4,%%mm3\n" - "psubusb %%mm5,%%mm2\n" - "psubusb %%mm6,%%mm4\n" - - "por %%mm1,%%mm2\n" - "por %%mm3,%%mm4\n" - - /* now convert to 16-bit vectors so we can square them */ - "movq %%mm2,%%mm1\n" - "movq %%mm4,%%mm3\n" - - "punpckhbw %%mm0,%%mm2\n" - "punpckhbw %%mm0,%%mm4\n" - "punpcklbw %%mm0,%%mm1\n" /* mm1 now spread over (mm1,mm2) */ - "punpcklbw %%mm0,%%mm3\n" /* mm4 now spread over (mm3,mm4) */ - - "pmaddwd %%mm2,%%mm2\n" - "pmaddwd %%mm4,%%mm4\n" - "pmaddwd %%mm1,%%mm1\n" - "pmaddwd %%mm3,%%mm3\n" - - "lea (%0,%3,2), %0\n" /* pix1 += 2*line_size */ - "lea (%1,%3,2), %1\n" /* pix2 += 2*line_size */ - - "paddd %%mm2,%%mm1\n" - "paddd %%mm4,%%mm3\n" - "paddd %%mm1,%%mm7\n" - "paddd %%mm3,%%mm7\n" - - "decl %%ecx\n" - "jnz 1b\n" - - "movq %%mm7,%%mm1\n" - "psrlq $32, %%mm7\n" /* shift hi dword to lo */ - "paddd %%mm7,%%mm1\n" - "movd %%mm1,%2\n" - : "+r" (pix1), "+r" (pix2), "=r"(tmp) - : "r" ((long)line_size) , "m" (h) - : "%ecx"); - return tmp; -} - -static int sse16_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - int tmp; - asm volatile ( - "movl %4,%%ecx\n" - "pxor %%mm0,%%mm0\n" /* mm0 = 0 */ - "pxor %%mm7,%%mm7\n" /* mm7 holds the sum */ - "1:\n" - "movq (%0),%%mm1\n" /* mm1 = pix1[0-7] */ - "movq (%1),%%mm2\n" /* mm2 = pix2[0-7] */ - "movq 8(%0),%%mm3\n" /* mm3 = pix1[8-15] */ - "movq 8(%1),%%mm4\n" /* mm4 = pix2[8-15] */ - - /* todo: mm1-mm2, mm3-mm4 */ - /* algo: substract mm1 from mm2 with saturation and vice versa */ - /* OR the results to get absolute difference */ - "movq %%mm1,%%mm5\n" - "movq %%mm3,%%mm6\n" - "psubusb %%mm2,%%mm1\n" - "psubusb %%mm4,%%mm3\n" - "psubusb %%mm5,%%mm2\n" - "psubusb %%mm6,%%mm4\n" - - "por %%mm1,%%mm2\n" - "por %%mm3,%%mm4\n" - - /* now convert to 16-bit vectors so we can square them */ - "movq %%mm2,%%mm1\n" - "movq %%mm4,%%mm3\n" - - "punpckhbw %%mm0,%%mm2\n" - "punpckhbw %%mm0,%%mm4\n" - "punpcklbw %%mm0,%%mm1\n" /* mm1 now spread over (mm1,mm2) */ - "punpcklbw %%mm0,%%mm3\n" /* mm4 now spread over (mm3,mm4) */ - - "pmaddwd %%mm2,%%mm2\n" - "pmaddwd %%mm4,%%mm4\n" - "pmaddwd %%mm1,%%mm1\n" - "pmaddwd %%mm3,%%mm3\n" - - "add %3,%0\n" - "add %3,%1\n" - - "paddd %%mm2,%%mm1\n" - "paddd %%mm4,%%mm3\n" - "paddd %%mm1,%%mm7\n" - "paddd %%mm3,%%mm7\n" - - "decl %%ecx\n" - "jnz 1b\n" - - "movq %%mm7,%%mm1\n" - "psrlq $32, %%mm7\n" /* shift hi dword to lo */ - "paddd %%mm7,%%mm1\n" - "movd %%mm1,%2\n" - : "+r" (pix1), "+r" (pix2), "=r"(tmp) - : "r" ((long)line_size) , "m" (h) - : "%ecx"); - return tmp; -} - -static int sse16_sse2(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - int tmp; - asm volatile ( - "shr $1,%2\n" - "pxor %%xmm0,%%xmm0\n" /* mm0 = 0 */ - "pxor %%xmm7,%%xmm7\n" /* mm7 holds the sum */ - "1:\n" - "movdqu (%0),%%xmm1\n" /* mm1 = pix1[0][0-15] */ - "movdqu (%1),%%xmm2\n" /* mm2 = pix2[0][0-15] */ - "movdqu (%0,%4),%%xmm3\n" /* mm3 = pix1[1][0-15] */ - "movdqu (%1,%4),%%xmm4\n" /* mm4 = pix2[1][0-15] */ - - /* todo: mm1-mm2, mm3-mm4 */ - /* algo: substract mm1 from mm2 with saturation and vice versa */ - /* OR the results to get absolute difference */ - "movdqa %%xmm1,%%xmm5\n" - "movdqa %%xmm3,%%xmm6\n" - "psubusb %%xmm2,%%xmm1\n" - "psubusb %%xmm4,%%xmm3\n" - "psubusb %%xmm5,%%xmm2\n" - "psubusb %%xmm6,%%xmm4\n" - - "por %%xmm1,%%xmm2\n" - "por %%xmm3,%%xmm4\n" - - /* now convert to 16-bit vectors so we can square them */ - "movdqa %%xmm2,%%xmm1\n" - "movdqa %%xmm4,%%xmm3\n" - - "punpckhbw %%xmm0,%%xmm2\n" - "punpckhbw %%xmm0,%%xmm4\n" - "punpcklbw %%xmm0,%%xmm1\n" /* mm1 now spread over (mm1,mm2) */ - "punpcklbw %%xmm0,%%xmm3\n" /* mm4 now spread over (mm3,mm4) */ - - "pmaddwd %%xmm2,%%xmm2\n" - "pmaddwd %%xmm4,%%xmm4\n" - "pmaddwd %%xmm1,%%xmm1\n" - "pmaddwd %%xmm3,%%xmm3\n" - - "lea (%0,%4,2), %0\n" /* pix1 += 2*line_size */ - "lea (%1,%4,2), %1\n" /* pix2 += 2*line_size */ - - "paddd %%xmm2,%%xmm1\n" - "paddd %%xmm4,%%xmm3\n" - "paddd %%xmm1,%%xmm7\n" - "paddd %%xmm3,%%xmm7\n" - - "decl %2\n" - "jnz 1b\n" - - "movdqa %%xmm7,%%xmm1\n" - "psrldq $8, %%xmm7\n" /* shift hi qword to lo */ - "paddd %%xmm1,%%xmm7\n" - "movdqa %%xmm7,%%xmm1\n" - "psrldq $4, %%xmm7\n" /* shift hi dword to lo */ - "paddd %%xmm1,%%xmm7\n" - "movd %%xmm7,%3\n" - : "+r" (pix1), "+r" (pix2), "+r"(h), "=r"(tmp) - : "r" ((long)line_size)); - return tmp; -} - -static int hf_noise8_mmx(uint8_t * pix1, int line_size, int h) { - int tmp; - asm volatile ( - "movl %3,%%ecx\n" - "pxor %%mm7,%%mm7\n" - "pxor %%mm6,%%mm6\n" - - "movq (%0),%%mm0\n" - "movq %%mm0, %%mm1\n" - "psllq $8, %%mm0\n" - "psrlq $8, %%mm1\n" - "psrlq $8, %%mm0\n" - "movq %%mm0, %%mm2\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm0\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm2\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm0\n" - "psubw %%mm3, %%mm2\n" - - "add %2,%0\n" - - "movq (%0),%%mm4\n" - "movq %%mm4, %%mm1\n" - "psllq $8, %%mm4\n" - "psrlq $8, %%mm1\n" - "psrlq $8, %%mm4\n" - "movq %%mm4, %%mm5\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm4\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm5\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm4\n" - "psubw %%mm3, %%mm5\n" - "psubw %%mm4, %%mm0\n" - "psubw %%mm5, %%mm2\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm0, %%mm3\n\t" - "pcmpgtw %%mm2, %%mm1\n\t" - "pxor %%mm3, %%mm0\n" - "pxor %%mm1, %%mm2\n" - "psubw %%mm3, %%mm0\n" - "psubw %%mm1, %%mm2\n" - "paddw %%mm0, %%mm2\n" - "paddw %%mm2, %%mm6\n" - - "add %2,%0\n" - "1:\n" - - "movq (%0),%%mm0\n" - "movq %%mm0, %%mm1\n" - "psllq $8, %%mm0\n" - "psrlq $8, %%mm1\n" - "psrlq $8, %%mm0\n" - "movq %%mm0, %%mm2\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm0\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm2\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm0\n" - "psubw %%mm3, %%mm2\n" - "psubw %%mm0, %%mm4\n" - "psubw %%mm2, %%mm5\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm4, %%mm3\n\t" - "pcmpgtw %%mm5, %%mm1\n\t" - "pxor %%mm3, %%mm4\n" - "pxor %%mm1, %%mm5\n" - "psubw %%mm3, %%mm4\n" - "psubw %%mm1, %%mm5\n" - "paddw %%mm4, %%mm5\n" - "paddw %%mm5, %%mm6\n" - - "add %2,%0\n" - - "movq (%0),%%mm4\n" - "movq %%mm4, %%mm1\n" - "psllq $8, %%mm4\n" - "psrlq $8, %%mm1\n" - "psrlq $8, %%mm4\n" - "movq %%mm4, %%mm5\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm4\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm5\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm4\n" - "psubw %%mm3, %%mm5\n" - "psubw %%mm4, %%mm0\n" - "psubw %%mm5, %%mm2\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm0, %%mm3\n\t" - "pcmpgtw %%mm2, %%mm1\n\t" - "pxor %%mm3, %%mm0\n" - "pxor %%mm1, %%mm2\n" - "psubw %%mm3, %%mm0\n" - "psubw %%mm1, %%mm2\n" - "paddw %%mm0, %%mm2\n" - "paddw %%mm2, %%mm6\n" - - "add %2,%0\n" - "subl $2, %%ecx\n" - " jnz 1b\n" - - "movq %%mm6, %%mm0\n" - "punpcklwd %%mm7,%%mm0\n" - "punpckhwd %%mm7,%%mm6\n" - "paddd %%mm0, %%mm6\n" - - "movq %%mm6,%%mm0\n" - "psrlq $32, %%mm6\n" - "paddd %%mm6,%%mm0\n" - "movd %%mm0,%1\n" - : "+r" (pix1), "=r"(tmp) - : "r" ((long)line_size) , "g" (h-2) - : "%ecx"); - return tmp; -} - -static int hf_noise16_mmx(uint8_t * pix1, int line_size, int h) { - int tmp; - uint8_t * pix= pix1; - asm volatile ( - "movl %3,%%ecx\n" - "pxor %%mm7,%%mm7\n" - "pxor %%mm6,%%mm6\n" - - "movq (%0),%%mm0\n" - "movq 1(%0),%%mm1\n" - "movq %%mm0, %%mm2\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm0\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm2\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm0\n" - "psubw %%mm3, %%mm2\n" - - "add %2,%0\n" - - "movq (%0),%%mm4\n" - "movq 1(%0),%%mm1\n" - "movq %%mm4, %%mm5\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm4\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm5\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm4\n" - "psubw %%mm3, %%mm5\n" - "psubw %%mm4, %%mm0\n" - "psubw %%mm5, %%mm2\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm0, %%mm3\n\t" - "pcmpgtw %%mm2, %%mm1\n\t" - "pxor %%mm3, %%mm0\n" - "pxor %%mm1, %%mm2\n" - "psubw %%mm3, %%mm0\n" - "psubw %%mm1, %%mm2\n" - "paddw %%mm0, %%mm2\n" - "paddw %%mm2, %%mm6\n" - - "add %2,%0\n" - "1:\n" - - "movq (%0),%%mm0\n" - "movq 1(%0),%%mm1\n" - "movq %%mm0, %%mm2\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm0\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm2\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm0\n" - "psubw %%mm3, %%mm2\n" - "psubw %%mm0, %%mm4\n" - "psubw %%mm2, %%mm5\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm4, %%mm3\n\t" - "pcmpgtw %%mm5, %%mm1\n\t" - "pxor %%mm3, %%mm4\n" - "pxor %%mm1, %%mm5\n" - "psubw %%mm3, %%mm4\n" - "psubw %%mm1, %%mm5\n" - "paddw %%mm4, %%mm5\n" - "paddw %%mm5, %%mm6\n" - - "add %2,%0\n" - - "movq (%0),%%mm4\n" - "movq 1(%0),%%mm1\n" - "movq %%mm4, %%mm5\n" - "movq %%mm1, %%mm3\n" - "punpcklbw %%mm7,%%mm4\n" - "punpcklbw %%mm7,%%mm1\n" - "punpckhbw %%mm7,%%mm5\n" - "punpckhbw %%mm7,%%mm3\n" - "psubw %%mm1, %%mm4\n" - "psubw %%mm3, %%mm5\n" - "psubw %%mm4, %%mm0\n" - "psubw %%mm5, %%mm2\n" - "pxor %%mm3, %%mm3\n" - "pxor %%mm1, %%mm1\n" - "pcmpgtw %%mm0, %%mm3\n\t" - "pcmpgtw %%mm2, %%mm1\n\t" - "pxor %%mm3, %%mm0\n" - "pxor %%mm1, %%mm2\n" - "psubw %%mm3, %%mm0\n" - "psubw %%mm1, %%mm2\n" - "paddw %%mm0, %%mm2\n" - "paddw %%mm2, %%mm6\n" - - "add %2,%0\n" - "subl $2, %%ecx\n" - " jnz 1b\n" - - "movq %%mm6, %%mm0\n" - "punpcklwd %%mm7,%%mm0\n" - "punpckhwd %%mm7,%%mm6\n" - "paddd %%mm0, %%mm6\n" - - "movq %%mm6,%%mm0\n" - "psrlq $32, %%mm6\n" - "paddd %%mm6,%%mm0\n" - "movd %%mm0,%1\n" - : "+r" (pix1), "=r"(tmp) - : "r" ((long)line_size) , "g" (h-2) - : "%ecx"); - return tmp + hf_noise8_mmx(pix+8, line_size, h); -} - -static int nsse16_mmx(void *p, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - MpegEncContext *c = p; - int score1, score2; - - if(c) score1 = c->dsp.sse[0](c, pix1, pix2, line_size, h); - else score1 = sse16_mmx(c, pix1, pix2, line_size, h); - score2= hf_noise16_mmx(pix1, line_size, h) - hf_noise16_mmx(pix2, line_size, h); - - if(c) return score1 + FFABS(score2)*c->avctx->nsse_weight; - else return score1 + FFABS(score2)*8; -} - -static int nsse8_mmx(void *p, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - MpegEncContext *c = p; - int score1= sse8_mmx(c, pix1, pix2, line_size, h); - int score2= hf_noise8_mmx(pix1, line_size, h) - hf_noise8_mmx(pix2, line_size, h); - - if(c) return score1 + FFABS(score2)*c->avctx->nsse_weight; - else return score1 + FFABS(score2)*8; -} - -static int vsad_intra16_mmx(void *v, uint8_t * pix, uint8_t * dummy, int line_size, int h) { - int tmp; - - assert( (((int)pix) & 7) == 0); - assert((line_size &7) ==0); - -#define SUM(in0, in1, out0, out1) \ - "movq (%0), %%mm2\n"\ - "movq 8(%0), %%mm3\n"\ - "add %2,%0\n"\ - "movq %%mm2, " #out0 "\n"\ - "movq %%mm3, " #out1 "\n"\ - "psubusb " #in0 ", %%mm2\n"\ - "psubusb " #in1 ", %%mm3\n"\ - "psubusb " #out0 ", " #in0 "\n"\ - "psubusb " #out1 ", " #in1 "\n"\ - "por %%mm2, " #in0 "\n"\ - "por %%mm3, " #in1 "\n"\ - "movq " #in0 ", %%mm2\n"\ - "movq " #in1 ", %%mm3\n"\ - "punpcklbw %%mm7, " #in0 "\n"\ - "punpcklbw %%mm7, " #in1 "\n"\ - "punpckhbw %%mm7, %%mm2\n"\ - "punpckhbw %%mm7, %%mm3\n"\ - "paddw " #in1 ", " #in0 "\n"\ - "paddw %%mm3, %%mm2\n"\ - "paddw %%mm2, " #in0 "\n"\ - "paddw " #in0 ", %%mm6\n" - - - asm volatile ( - "movl %3,%%ecx\n" - "pxor %%mm6,%%mm6\n" - "pxor %%mm7,%%mm7\n" - "movq (%0),%%mm0\n" - "movq 8(%0),%%mm1\n" - "add %2,%0\n" - "subl $2, %%ecx\n" - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - "1:\n" - - SUM(%%mm4, %%mm5, %%mm0, %%mm1) - - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - - "subl $2, %%ecx\n" - "jnz 1b\n" - - "movq %%mm6,%%mm0\n" - "psrlq $32, %%mm6\n" - "paddw %%mm6,%%mm0\n" - "movq %%mm0,%%mm6\n" - "psrlq $16, %%mm0\n" - "paddw %%mm6,%%mm0\n" - "movd %%mm0,%1\n" - : "+r" (pix), "=r"(tmp) - : "r" ((long)line_size) , "m" (h) - : "%ecx"); - return tmp & 0xFFFF; -} -#undef SUM - -static int vsad_intra16_mmx2(void *v, uint8_t * pix, uint8_t * dummy, int line_size, int h) { - int tmp; - - assert( (((int)pix) & 7) == 0); - assert((line_size &7) ==0); - -#define SUM(in0, in1, out0, out1) \ - "movq (%0), " #out0 "\n"\ - "movq 8(%0), " #out1 "\n"\ - "add %2,%0\n"\ - "psadbw " #out0 ", " #in0 "\n"\ - "psadbw " #out1 ", " #in1 "\n"\ - "paddw " #in1 ", " #in0 "\n"\ - "paddw " #in0 ", %%mm6\n" - - asm volatile ( - "movl %3,%%ecx\n" - "pxor %%mm6,%%mm6\n" - "pxor %%mm7,%%mm7\n" - "movq (%0),%%mm0\n" - "movq 8(%0),%%mm1\n" - "add %2,%0\n" - "subl $2, %%ecx\n" - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - "1:\n" - - SUM(%%mm4, %%mm5, %%mm0, %%mm1) - - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - - "subl $2, %%ecx\n" - "jnz 1b\n" - - "movd %%mm6,%1\n" - : "+r" (pix), "=r"(tmp) - : "r" ((long)line_size) , "m" (h) - : "%ecx"); - return tmp; -} -#undef SUM - -static int vsad16_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - int tmp; - - assert( (((int)pix1) & 7) == 0); - assert( (((int)pix2) & 7) == 0); - assert((line_size &7) ==0); - -#define SUM(in0, in1, out0, out1) \ - "movq (%0),%%mm2\n"\ - "movq (%1)," #out0 "\n"\ - "movq 8(%0),%%mm3\n"\ - "movq 8(%1)," #out1 "\n"\ - "add %3,%0\n"\ - "add %3,%1\n"\ - "psubb " #out0 ", %%mm2\n"\ - "psubb " #out1 ", %%mm3\n"\ - "pxor %%mm7, %%mm2\n"\ - "pxor %%mm7, %%mm3\n"\ - "movq %%mm2, " #out0 "\n"\ - "movq %%mm3, " #out1 "\n"\ - "psubusb " #in0 ", %%mm2\n"\ - "psubusb " #in1 ", %%mm3\n"\ - "psubusb " #out0 ", " #in0 "\n"\ - "psubusb " #out1 ", " #in1 "\n"\ - "por %%mm2, " #in0 "\n"\ - "por %%mm3, " #in1 "\n"\ - "movq " #in0 ", %%mm2\n"\ - "movq " #in1 ", %%mm3\n"\ - "punpcklbw %%mm7, " #in0 "\n"\ - "punpcklbw %%mm7, " #in1 "\n"\ - "punpckhbw %%mm7, %%mm2\n"\ - "punpckhbw %%mm7, %%mm3\n"\ - "paddw " #in1 ", " #in0 "\n"\ - "paddw %%mm3, %%mm2\n"\ - "paddw %%mm2, " #in0 "\n"\ - "paddw " #in0 ", %%mm6\n" - - - asm volatile ( - "movl %4,%%ecx\n" - "pxor %%mm6,%%mm6\n" - "pcmpeqw %%mm7,%%mm7\n" - "psllw $15, %%mm7\n" - "packsswb %%mm7, %%mm7\n" - "movq (%0),%%mm0\n" - "movq (%1),%%mm2\n" - "movq 8(%0),%%mm1\n" - "movq 8(%1),%%mm3\n" - "add %3,%0\n" - "add %3,%1\n" - "subl $2, %%ecx\n" - "psubb %%mm2, %%mm0\n" - "psubb %%mm3, %%mm1\n" - "pxor %%mm7, %%mm0\n" - "pxor %%mm7, %%mm1\n" - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - "1:\n" - - SUM(%%mm4, %%mm5, %%mm0, %%mm1) - - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - - "subl $2, %%ecx\n" - "jnz 1b\n" - - "movq %%mm6,%%mm0\n" - "psrlq $32, %%mm6\n" - "paddw %%mm6,%%mm0\n" - "movq %%mm0,%%mm6\n" - "psrlq $16, %%mm0\n" - "paddw %%mm6,%%mm0\n" - "movd %%mm0,%2\n" - : "+r" (pix1), "+r" (pix2), "=r"(tmp) - : "r" ((long)line_size) , "m" (h) - : "%ecx"); - return tmp & 0x7FFF; -} -#undef SUM - -static int vsad16_mmx2(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { - int tmp; - - assert( (((int)pix1) & 7) == 0); - assert( (((int)pix2) & 7) == 0); - assert((line_size &7) ==0); - -#define SUM(in0, in1, out0, out1) \ - "movq (%0)," #out0 "\n"\ - "movq (%1),%%mm2\n"\ - "movq 8(%0)," #out1 "\n"\ - "movq 8(%1),%%mm3\n"\ - "add %3,%0\n"\ - "add %3,%1\n"\ - "psubb %%mm2, " #out0 "\n"\ - "psubb %%mm3, " #out1 "\n"\ - "pxor %%mm7, " #out0 "\n"\ - "pxor %%mm7, " #out1 "\n"\ - "psadbw " #out0 ", " #in0 "\n"\ - "psadbw " #out1 ", " #in1 "\n"\ - "paddw " #in1 ", " #in0 "\n"\ - "paddw " #in0 ", %%mm6\n" - - asm volatile ( - "movl %4,%%ecx\n" - "pxor %%mm6,%%mm6\n" - "pcmpeqw %%mm7,%%mm7\n" - "psllw $15, %%mm7\n" - "packsswb %%mm7, %%mm7\n" - "movq (%0),%%mm0\n" - "movq (%1),%%mm2\n" - "movq 8(%0),%%mm1\n" - "movq 8(%1),%%mm3\n" - "add %3,%0\n" - "add %3,%1\n" - "subl $2, %%ecx\n" - "psubb %%mm2, %%mm0\n" - "psubb %%mm3, %%mm1\n" - "pxor %%mm7, %%mm0\n" - "pxor %%mm7, %%mm1\n" - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - "1:\n" - - SUM(%%mm4, %%mm5, %%mm0, %%mm1) - - SUM(%%mm0, %%mm1, %%mm4, %%mm5) - - "subl $2, %%ecx\n" - "jnz 1b\n" - - "movd %%mm6,%2\n" - : "+r" (pix1), "+r" (pix2), "=r"(tmp) - : "r" ((long)line_size) , "m" (h) - : "%ecx"); - return tmp; -} -#undef SUM - -static void diff_bytes_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ - long i=0; - asm volatile( - "1: \n\t" - "movq (%2, %0), %%mm0 \n\t" - "movq (%1, %0), %%mm1 \n\t" - "psubb %%mm0, %%mm1 \n\t" - "movq %%mm1, (%3, %0) \n\t" - "movq 8(%2, %0), %%mm0 \n\t" - "movq 8(%1, %0), %%mm1 \n\t" - "psubb %%mm0, %%mm1 \n\t" - "movq %%mm1, 8(%3, %0) \n\t" - "add $16, %0 \n\t" - "cmp %4, %0 \n\t" - " jb 1b \n\t" - : "+r" (i) - : "r"(src1), "r"(src2), "r"(dst), "r"((long)w-15) - ); - for(; i<w; i++) - dst[i+0] = src1[i+0]-src2[i+0]; -} - -static void sub_hfyu_median_prediction_mmx2(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top){ - long i=0; - uint8_t l, lt; - - asm volatile( - "1: \n\t" - "movq -1(%1, %0), %%mm0 \n\t" // LT - "movq (%1, %0), %%mm1 \n\t" // T - "movq -1(%2, %0), %%mm2 \n\t" // L - "movq (%2, %0), %%mm3 \n\t" // X - "movq %%mm2, %%mm4 \n\t" // L - "psubb %%mm0, %%mm2 \n\t" - "paddb %%mm1, %%mm2 \n\t" // L + T - LT - "movq %%mm4, %%mm5 \n\t" // L - "pmaxub %%mm1, %%mm4 \n\t" // max(T, L) - "pminub %%mm5, %%mm1 \n\t" // min(T, L) - "pminub %%mm2, %%mm4 \n\t" - "pmaxub %%mm1, %%mm4 \n\t" - "psubb %%mm4, %%mm3 \n\t" // dst - pred - "movq %%mm3, (%3, %0) \n\t" - "add $8, %0 \n\t" - "cmp %4, %0 \n\t" - " jb 1b \n\t" - : "+r" (i) - : "r"(src1), "r"(src2), "r"(dst), "r"((long)w) - ); - - l= *left; - lt= *left_top; - - dst[0]= src2[0] - mid_pred(l, src1[0], (l + src1[0] - lt)&0xFF); - - *left_top= src1[w-1]; - *left = src2[w-1]; -} - -#define LBUTTERFLY2(a1,b1,a2,b2)\ - "paddw " #b1 ", " #a1 " \n\t"\ - "paddw " #b2 ", " #a2 " \n\t"\ - "paddw " #b1 ", " #b1 " \n\t"\ - "paddw " #b2 ", " #b2 " \n\t"\ - "psubw " #a1 ", " #b1 " \n\t"\ - "psubw " #a2 ", " #b2 " \n\t" - -#define HADAMARD48\ - LBUTTERFLY2(%%mm0, %%mm1, %%mm2, %%mm3)\ - LBUTTERFLY2(%%mm4, %%mm5, %%mm6, %%mm7)\ - LBUTTERFLY2(%%mm0, %%mm2, %%mm1, %%mm3)\ - LBUTTERFLY2(%%mm4, %%mm6, %%mm5, %%mm7)\ - LBUTTERFLY2(%%mm0, %%mm4, %%mm1, %%mm5)\ - LBUTTERFLY2(%%mm2, %%mm6, %%mm3, %%mm7)\ - -#define MMABS(a,z)\ - "pxor " #z ", " #z " \n\t"\ - "pcmpgtw " #a ", " #z " \n\t"\ - "pxor " #z ", " #a " \n\t"\ - "psubw " #z ", " #a " \n\t" - -#define MMABS_SUM(a,z, sum)\ - "pxor " #z ", " #z " \n\t"\ - "pcmpgtw " #a ", " #z " \n\t"\ - "pxor " #z ", " #a " \n\t"\ - "psubw " #z ", " #a " \n\t"\ - "paddusw " #a ", " #sum " \n\t" - -#define MMABS_MMX2(a,z)\ - "pxor " #z ", " #z " \n\t"\ - "psubw " #a ", " #z " \n\t"\ - "pmaxsw " #z ", " #a " \n\t" - -#define MMABS_SUM_MMX2(a,z, sum)\ - "pxor " #z ", " #z " \n\t"\ - "psubw " #a ", " #z " \n\t"\ - "pmaxsw " #z ", " #a " \n\t"\ - "paddusw " #a ", " #sum " \n\t" - -#define TRANSPOSE4(a,b,c,d,t)\ - SBUTTERFLY(a,b,t,wd) /* a=aebf t=cgdh */\ - SBUTTERFLY(c,d,b,wd) /* c=imjn b=kolp */\ - SBUTTERFLY(a,c,d,dq) /* a=aeim d=bfjn */\ - SBUTTERFLY(t,b,c,dq) /* t=cgko c=dhlp */ - -#define LOAD4(o, a, b, c, d)\ - "movq "#o"(%1), " #a " \n\t"\ - "movq "#o"+16(%1), " #b " \n\t"\ - "movq "#o"+32(%1), " #c " \n\t"\ - "movq "#o"+48(%1), " #d " \n\t" - -#define STORE4(o, a, b, c, d)\ - "movq "#a", "#o"(%1) \n\t"\ - "movq "#b", "#o"+16(%1) \n\t"\ - "movq "#c", "#o"+32(%1) \n\t"\ - "movq "#d", "#o"+48(%1) \n\t"\ - -static int hadamard8_diff_mmx(void *s, uint8_t *src1, uint8_t *src2, int stride, int h){ - DECLARE_ALIGNED_8(uint64_t, temp[16]); - int sum=0; - - assert(h==8); - - diff_pixels_mmx((DCTELEM*)temp, src1, src2, stride); - - asm volatile( - LOAD4(0 , %%mm0, %%mm1, %%mm2, %%mm3) - LOAD4(64, %%mm4, %%mm5, %%mm6, %%mm7) - - HADAMARD48 - - "movq %%mm7, 112(%1) \n\t" - - TRANSPOSE4(%%mm0, %%mm1, %%mm2, %%mm3, %%mm7) - STORE4(0 , %%mm0, %%mm3, %%mm7, %%mm2) - - "movq 112(%1), %%mm7 \n\t" - TRANSPOSE4(%%mm4, %%mm5, %%mm6, %%mm7, %%mm0) - STORE4(64, %%mm4, %%mm7, %%mm0, %%mm6) - - LOAD4(8 , %%mm0, %%mm1, %%mm2, %%mm3) - LOAD4(72, %%mm4, %%mm5, %%mm6, %%mm7) - - HADAMARD48 - - "movq %%mm7, 120(%1) \n\t" - - TRANSPOSE4(%%mm0, %%mm1, %%mm2, %%mm3, %%mm7) - STORE4(8 , %%mm0, %%mm3, %%mm7, %%mm2) - - "movq 120(%1), %%mm7 \n\t" - TRANSPOSE4(%%mm4, %%mm5, %%mm6, %%mm7, %%mm0) - "movq %%mm7, %%mm5 \n\t"//FIXME remove - "movq %%mm6, %%mm7 \n\t" - "movq %%mm0, %%mm6 \n\t" -// STORE4(72, %%mm4, %%mm7, %%mm0, %%mm6) //FIXME remove - - LOAD4(64, %%mm0, %%mm1, %%mm2, %%mm3) -// LOAD4(72, %%mm4, %%mm5, %%mm6, %%mm7) - - HADAMARD48 - "movq %%mm7, 64(%1) \n\t" - MMABS(%%mm0, %%mm7) - MMABS_SUM(%%mm1, %%mm7, %%mm0) - MMABS_SUM(%%mm2, %%mm7, %%mm0) - MMABS_SUM(%%mm3, %%mm7, %%mm0) - MMABS_SUM(%%mm4, %%mm7, %%mm0) - MMABS_SUM(%%mm5, %%mm7, %%mm0) - MMABS_SUM(%%mm6, %%mm7, %%mm0) - "movq 64(%1), %%mm1 \n\t" - MMABS_SUM(%%mm1, %%mm7, %%mm0) - "movq %%mm0, 64(%1) \n\t" - - LOAD4(0 , %%mm0, %%mm1, %%mm2, %%mm3) - LOAD4(8 , %%mm4, %%mm5, %%mm6, %%mm7) - - HADAMARD48 - "movq %%mm7, (%1) \n\t" - MMABS(%%mm0, %%mm7) - MMABS_SUM(%%mm1, %%mm7, %%mm0) - MMABS_SUM(%%mm2, %%mm7, %%mm0) - MMABS_SUM(%%mm3, %%mm7, %%mm0) - MMABS_SUM(%%mm4, %%mm7, %%mm0) - MMABS_SUM(%%mm5, %%mm7, %%mm0) - MMABS_SUM(%%mm6, %%mm7, %%mm0) - "movq (%1), %%mm1 \n\t" - MMABS_SUM(%%mm1, %%mm7, %%mm0) - "movq 64(%1), %%mm1 \n\t" - MMABS_SUM(%%mm1, %%mm7, %%mm0) - - "movq %%mm0, %%mm1 \n\t" - "psrlq $32, %%mm0 \n\t" - "paddusw %%mm1, %%mm0 \n\t" - "movq %%mm0, %%mm1 \n\t" - "psrlq $16, %%mm0 \n\t" - "paddusw %%mm1, %%mm0 \n\t" - "movd %%mm0, %0 \n\t" - - : "=r" (sum) - : "r"(temp) - ); - return sum&0xFFFF; -} - -static int hadamard8_diff_mmx2(void *s, uint8_t *src1, uint8_t *src2, int stride, int h){ - DECLARE_ALIGNED_8(uint64_t, temp[16]); - int sum=0; - - assert(h==8); - - diff_pixels_mmx((DCTELEM*)temp, src1, src2, stride); - - asm volatile( - LOAD4(0 , %%mm0, %%mm1, %%mm2, %%mm3) - LOAD4(64, %%mm4, %%mm5, %%mm6, %%mm7) - - HADAMARD48 - - "movq %%mm7, 112(%1) \n\t" - - TRANSPOSE4(%%mm0, %%mm1, %%mm2, %%mm3, %%mm7) - STORE4(0 , %%mm0, %%mm3, %%mm7, %%mm2) - - "movq 112(%1), %%mm7 \n\t" - TRANSPOSE4(%%mm4, %%mm5, %%mm6, %%mm7, %%mm0) - STORE4(64, %%mm4, %%mm7, %%mm0, %%mm6) - - LOAD4(8 , %%mm0, %%mm1, %%mm2, %%mm3) - LOAD4(72, %%mm4, %%mm5, %%mm6, %%mm7) - - HADAMARD48 - - "movq %%mm7, 120(%1) \n\t" - - TRANSPOSE4(%%mm0, %%mm1, %%mm2, %%mm3, %%mm7) - STORE4(8 , %%mm0, %%mm3, %%mm7, %%mm2) - - "movq 120(%1), %%mm7 \n\t" - TRANSPOSE4(%%mm4, %%mm5, %%mm6, %%mm7, %%mm0) - "movq %%mm7, %%mm5 \n\t"//FIXME remove - "movq %%mm6, %%mm7 \n\t" - "movq %%mm0, %%mm6 \n\t" -// STORE4(72, %%mm4, %%mm7, %%mm0, %%mm6) //FIXME remove - - LOAD4(64, %%mm0, %%mm1, %%mm2, %%mm3) -// LOAD4(72, %%mm4, %%mm5, %%mm6, %%mm7) - - HADAMARD48 - "movq %%mm7, 64(%1) \n\t" - MMABS_MMX2(%%mm0, %%mm7) - MMABS_SUM_MMX2(%%mm1, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm2, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm3, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm4, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm5, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm6, %%mm7, %%mm0) - "movq 64(%1), %%mm1 \n\t" - MMABS_SUM_MMX2(%%mm1, %%mm7, %%mm0) - "movq %%mm0, 64(%1) \n\t" - - LOAD4(0 , %%mm0, %%mm1, %%mm2, %%mm3) - LOAD4(8 , %%mm4, %%mm5, %%mm6, %%mm7) - - HADAMARD48 - "movq %%mm7, (%1) \n\t" - MMABS_MMX2(%%mm0, %%mm7) - MMABS_SUM_MMX2(%%mm1, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm2, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm3, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm4, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm5, %%mm7, %%mm0) - MMABS_SUM_MMX2(%%mm6, %%mm7, %%mm0) - "movq (%1), %%mm1 \n\t" - MMABS_SUM_MMX2(%%mm1, %%mm7, %%mm0) - "movq 64(%1), %%mm1 \n\t" - MMABS_SUM_MMX2(%%mm1, %%mm7, %%mm0) - - "pshufw $0x0E, %%mm0, %%mm1 \n\t" - "paddusw %%mm1, %%mm0 \n\t" - "pshufw $0x01, %%mm0, %%mm1 \n\t" - "paddusw %%mm1, %%mm0 \n\t" - "movd %%mm0, %0 \n\t" - - : "=r" (sum) - : "r"(temp) - ); - return sum&0xFFFF; -} - - -WARPER8_16_SQ(hadamard8_diff_mmx, hadamard8_diff16_mmx) -WARPER8_16_SQ(hadamard8_diff_mmx2, hadamard8_diff16_mmx2) - -static int ssd_int8_vs_int16_mmx(int8_t *pix1, int16_t *pix2, int size){ - int sum; - long i=size; - asm volatile( - "pxor %%mm4, %%mm4 \n" - "1: \n" - "sub $8, %0 \n" - "movq (%2,%0), %%mm2 \n" - "movq (%3,%0,2), %%mm0 \n" - "movq 8(%3,%0,2), %%mm1 \n" - "punpckhbw %%mm2, %%mm3 \n" - "punpcklbw %%mm2, %%mm2 \n" - "psraw $8, %%mm3 \n" - "psraw $8, %%mm2 \n" - "psubw %%mm3, %%mm1 \n" - "psubw %%mm2, %%mm0 \n" - "pmaddwd %%mm1, %%mm1 \n" - "pmaddwd %%mm0, %%mm0 \n" - "paddd %%mm1, %%mm4 \n" - "paddd %%mm0, %%mm4 \n" - "jg 1b \n" - "movq %%mm4, %%mm3 \n" - "psrlq $32, %%mm3 \n" - "paddd %%mm3, %%mm4 \n" - "movd %%mm4, %1 \n" - :"+r"(i), "=r"(sum) - :"r"(pix1), "r"(pix2) - ); - return sum; +#define PAETH(cpu, abs3)\ +void add_png_paeth_prediction_##cpu(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)\ +{\ + long i = -bpp;\ + long end = w-3;\ + asm volatile(\ + "pxor %%mm7, %%mm7 \n"\ + "movd (%1,%0), %%mm0 \n"\ + "movd (%2,%0), %%mm1 \n"\ + "punpcklbw %%mm7, %%mm0 \n"\ + "punpcklbw %%mm7, %%mm1 \n"\ + "add %4, %0 \n"\ + "1: \n"\ + "movq %%mm1, %%mm2 \n"\ + "movd (%2,%0), %%mm1 \n"\ + "movq %%mm2, %%mm3 \n"\ + "punpcklbw %%mm7, %%mm1 \n"\ + "movq %%mm2, %%mm4 \n"\ + "psubw %%mm1, %%mm3 \n"\ + "psubw %%mm0, %%mm4 \n"\ + "movq %%mm3, %%mm5 \n"\ + "paddw %%mm4, %%mm5 \n"\ + abs3\ + "movq %%mm4, %%mm6 \n"\ + "pminsw %%mm5, %%mm6 \n"\ + "pcmpgtw %%mm6, %%mm3 \n"\ + "pcmpgtw %%mm5, %%mm4 \n"\ + "movq %%mm4, %%mm6 \n"\ + "pand %%mm3, %%mm4 \n"\ + "pandn %%mm3, %%mm6 \n"\ + "pandn %%mm0, %%mm3 \n"\ + "movd (%3,%0), %%mm0 \n"\ + "pand %%mm1, %%mm6 \n"\ + "pand %%mm4, %%mm2 \n"\ + "punpcklbw %%mm7, %%mm0 \n"\ + "movq %6, %%mm5 \n"\ + "paddw %%mm6, %%mm0 \n"\ + "paddw %%mm2, %%mm3 \n"\ + "paddw %%mm3, %%mm0 \n"\ + "pand %%mm5, %%mm0 \n"\ + "movq %%mm0, %%mm3 \n"\ + "packuswb %%mm3, %%mm3 \n"\ + "movd %%mm3, (%1,%0) \n"\ + "add %4, %0 \n"\ + "cmp %5, %0 \n"\ + "jle 1b \n"\ + :"+r"(i)\ + :"r"(dst), "r"(top), "r"(src), "r"((long)bpp), "g"(end),\ + "m"(ff_pw_255)\ + :"memory"\ + );\ } -#endif //CONFIG_ENCODERS - -#define put_no_rnd_pixels8_mmx(a,b,c,d) put_pixels8_mmx(a,b,c,d) -#define put_no_rnd_pixels16_mmx(a,b,c,d) put_pixels16_mmx(a,b,c,d) +#define ABS3_MMX2\ + "psubw %%mm5, %%mm7 \n"\ + "pmaxsw %%mm7, %%mm5 \n"\ + "pxor %%mm6, %%mm6 \n"\ + "pxor %%mm7, %%mm7 \n"\ + "psubw %%mm3, %%mm6 \n"\ + "psubw %%mm4, %%mm7 \n"\ + "pmaxsw %%mm6, %%mm3 \n"\ + "pmaxsw %%mm7, %%mm4 \n"\ + "pxor %%mm7, %%mm7 \n" + +#define ABS3_SSSE3\ + "pabsw %%mm3, %%mm3 \n"\ + "pabsw %%mm4, %%mm4 \n"\ + "pabsw %%mm5, %%mm5 \n" + +PAETH(mmx2, ABS3_MMX2) +#ifdef HAVE_SSSE3 +PAETH(ssse3, ABS3_SSSE3) +#endif #define QPEL_V_LOW(m3,m4,m5,m6, pw_20, pw_3, rnd, in0, in1, in2, in7, out, OP)\ "paddw " #m4 ", " #m3 " \n\t" /* x1 */\ @@ -1903,7 +906,7 @@ static void OPNAME ## mpeg4_qpel16_h_lowpass_mmx2(uint8_t *dst, uint8_t *src, in "add %4, %1 \n\t"\ "decl %2 \n\t"\ " jnz 1b \n\t"\ - : "+a"(src), "+c"(dst), "+m"(h)\ + : "+a"(src), "+c"(dst), "+g"(h)\ : "d"((long)srcStride), "S"((long)dstStride), /*"m"(ff_pw_20), "m"(ff_pw_3),*/ "m"(temp), "m"(ROUNDER)\ : "memory"\ );\ @@ -2016,7 +1019,7 @@ static void OPNAME ## mpeg4_qpel8_h_lowpass_mmx2(uint8_t *dst, uint8_t *src, int "add %4, %1 \n\t"\ "decl %2 \n\t"\ " jnz 1b \n\t"\ - : "+a"(src), "+c"(dst), "+m"(h)\ + : "+a"(src), "+c"(dst), "+g"(h)\ : "S"((long)srcStride), "D"((long)dstStride), /*"m"(ff_pw_20), "m"(ff_pw_3),*/ "m"(temp), "m"(ROUNDER)\ : "memory"\ );\ @@ -2194,7 +1197,7 @@ static void OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, }\ \ static void OPNAME ## qpel8_mc00_ ## MMX (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels8_mmx(dst, src, stride, 8);\ + OPNAME ## pixels8_ ## MMX(dst, src, stride, 8);\ }\ \ static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ @@ -2305,7 +1308,7 @@ static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, uint8_t *src, int stride) OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, stride, 8);\ }\ static void OPNAME ## qpel16_mc00_ ## MMX (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels16_mmx(dst, src, stride, 16);\ + OPNAME ## pixels16_ ## MMX(dst, src, stride, 16);\ }\ \ static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ @@ -2487,11 +1490,6 @@ QPEL_2TAP(avg_, 8, 3dnow) static void just_return() { return; } #endif -#define SET_QPEL_FUNC(postfix1, postfix2) \ - c->put_ ## postfix1 = put_ ## postfix2;\ - c->put_no_rnd_ ## postfix1 = put_no_rnd_ ## postfix2;\ - c->avg_ ## postfix1 = avg_ ## postfix2; - static void gmc_mmx(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){ const int w = 8; @@ -2515,8 +1513,8 @@ static void gmc_mmx(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int o const int dxh = dxy*(h-1); const int dyw = dyx*(w-1); if( // non-constant fullpel offset (3% of blocks) - (ox^(ox+dxw) | ox^(ox+dxh) | ox^(ox+dxw+dxh) | - oy^(oy+dyw) | oy^(oy+dyh) | oy^(oy+dyw+dyh)) >> (16+shift) + ((ox^(ox+dxw)) | (ox^(ox+dxh)) | (ox^(ox+dxw+dxh)) | + (oy^(oy+dyw)) | (oy^(oy+dyh)) | (oy^(oy+dyw+dyh))) >> (16+shift) // uses more than 16 bits of subpel mv (only at huge resolution) || (dxx|dxy|dyx|dyy)&15 ) { @@ -2610,94 +1608,6 @@ static void gmc_mmx(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int o } } -#ifdef CONFIG_ENCODERS -static int try_8x8basis_mmx(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale){ - long i=0; - - assert(FFABS(scale) < 256); - scale<<= 16 + 1 - BASIS_SHIFT + RECON_SHIFT; - - asm volatile( - "pcmpeqw %%mm6, %%mm6 \n\t" // -1w - "psrlw $15, %%mm6 \n\t" // 1w - "pxor %%mm7, %%mm7 \n\t" - "movd %4, %%mm5 \n\t" - "punpcklwd %%mm5, %%mm5 \n\t" - "punpcklwd %%mm5, %%mm5 \n\t" - "1: \n\t" - "movq (%1, %0), %%mm0 \n\t" - "movq 8(%1, %0), %%mm1 \n\t" - "pmulhw %%mm5, %%mm0 \n\t" - "pmulhw %%mm5, %%mm1 \n\t" - "paddw %%mm6, %%mm0 \n\t" - "paddw %%mm6, %%mm1 \n\t" - "psraw $1, %%mm0 \n\t" - "psraw $1, %%mm1 \n\t" - "paddw (%2, %0), %%mm0 \n\t" - "paddw 8(%2, %0), %%mm1 \n\t" - "psraw $6, %%mm0 \n\t" - "psraw $6, %%mm1 \n\t" - "pmullw (%3, %0), %%mm0 \n\t" - "pmullw 8(%3, %0), %%mm1 \n\t" - "pmaddwd %%mm0, %%mm0 \n\t" - "pmaddwd %%mm1, %%mm1 \n\t" - "paddd %%mm1, %%mm0 \n\t" - "psrld $4, %%mm0 \n\t" - "paddd %%mm0, %%mm7 \n\t" - "add $16, %0 \n\t" - "cmp $128, %0 \n\t" //FIXME optimize & bench - " jb 1b \n\t" - "movq %%mm7, %%mm6 \n\t" - "psrlq $32, %%mm7 \n\t" - "paddd %%mm6, %%mm7 \n\t" - "psrld $2, %%mm7 \n\t" - "movd %%mm7, %0 \n\t" - - : "+r" (i) - : "r"(basis), "r"(rem), "r"(weight), "g"(scale) - ); - return i; -} - -static void add_8x8basis_mmx(int16_t rem[64], int16_t basis[64], int scale){ - long i=0; - - if(FFABS(scale) < 256){ - scale<<= 16 + 1 - BASIS_SHIFT + RECON_SHIFT; - asm volatile( - "pcmpeqw %%mm6, %%mm6 \n\t" // -1w - "psrlw $15, %%mm6 \n\t" // 1w - "movd %3, %%mm5 \n\t" - "punpcklwd %%mm5, %%mm5 \n\t" - "punpcklwd %%mm5, %%mm5 \n\t" - "1: \n\t" - "movq (%1, %0), %%mm0 \n\t" - "movq 8(%1, %0), %%mm1 \n\t" - "pmulhw %%mm5, %%mm0 \n\t" - "pmulhw %%mm5, %%mm1 \n\t" - "paddw %%mm6, %%mm0 \n\t" - "paddw %%mm6, %%mm1 \n\t" - "psraw $1, %%mm0 \n\t" - "psraw $1, %%mm1 \n\t" - "paddw (%2, %0), %%mm0 \n\t" - "paddw 8(%2, %0), %%mm1 \n\t" - "movq %%mm0, (%2, %0) \n\t" - "movq %%mm1, 8(%2, %0) \n\t" - "add $16, %0 \n\t" - "cmp $128, %0 \n\t" //FIXME optimize & bench - " jb 1b \n\t" - - : "+r" (i) - : "r"(basis), "r"(rem), "g"(scale) - ); - }else{ - for(i=0; i<8*8; i++){ - rem[i] += (basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT); - } - } -} -#endif /* CONFIG_ENCODERS */ - #define PREFETCH(name, op) \ static void name(void *mem, int stride, int h){\ const uint8_t *p= mem;\ @@ -2712,7 +1622,7 @@ PREFETCH(prefetch_3dnow, prefetch) #include "h264dsp_mmx.c" -/* AVS specific */ +/* CAVS specific */ void ff_cavsdsp_init_mmx2(DSPContext* c, AVCodecContext *avctx); void ff_put_cavs_qpel8_mc00_mmx2(uint8_t *dst, uint8_t *src, int stride) { @@ -2728,14 +1638,17 @@ void ff_avg_cavs_qpel16_mc00_mmx2(uint8_t *dst, uint8_t *src, int stride) { avg_pixels16_mmx(dst, src, stride, 16); } +/* VC1 specific */ +void ff_vc1dsp_init_mmx(DSPContext* dsp, AVCodecContext *avctx); + +void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd) { + put_pixels8_mmx(dst, src, stride, 8); +} + /* external functions, from idct_mmx.c */ void ff_mmx_idct(DCTELEM *block); void ff_mmxext_idct(DCTELEM *block); -void ff_vp3_idct_sse2(int16_t *input_data); -void ff_vp3_idct_mmx(int16_t *data); -void ff_vp3_dsp_init_mmx(void); - /* XXX: those functions should be suppressed ASAP when all IDCTs are converted */ #ifdef CONFIG_GPL @@ -2760,26 +1673,6 @@ static void ff_libmpeg2mmx2_idct_add(uint8_t *dest, int line_size, DCTELEM *bloc add_pixels_clamped_mmx(block, dest, line_size); } #endif -static void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_vp3_idct_sse2(block); - put_signed_pixels_clamped_mmx(block, dest, line_size); -} -static void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_vp3_idct_sse2(block); - add_pixels_clamped_mmx(block, dest, line_size); -} -static void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_vp3_idct_mmx(block); - put_signed_pixels_clamped_mmx(block, dest, line_size); -} -static void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block) -{ - ff_vp3_idct_mmx(block); - add_pixels_clamped_mmx(block, dest, line_size); -} static void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, DCTELEM *block) { ff_idct_xvid_mmx (block); @@ -3069,16 +1962,14 @@ static void float_to_int16_sse(int16_t *dst, const float *src, int len){ asm volatile("emms"); } -#ifdef CONFIG_SNOW_DECODER -extern void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width); -extern void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width); -extern void ff_snow_vertical_compose97i_sse2(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width); -extern void ff_snow_vertical_compose97i_mmx(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width); +extern void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, int width); +extern void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, int width); +extern void ff_snow_vertical_compose97i_sse2(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); +extern void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); extern void ff_snow_inner_add_yblock_sse2(const 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); extern void ff_snow_inner_add_yblock_mmx(const 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); -#endif void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) { @@ -3109,18 +2000,6 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) if (mm_flags & MM_MMX) { const int idct_algo= avctx->idct_algo; -#ifdef CONFIG_ENCODERS - const int dct_algo = avctx->dct_algo; - if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){ - if(mm_flags & MM_SSE2){ - c->fdct = ff_fdct_sse2; - }else if(mm_flags & MM_MMXEXT){ - c->fdct = ff_fdct_mmx2; - }else{ - c->fdct = ff_fdct_mmx; - } - } -#endif //CONFIG_ENCODERS if(avctx->lowres==0){ if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_SIMPLEMMX){ c->idct_put= ff_simple_idct_put_mmx; @@ -3140,7 +2019,8 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) } c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; #endif - }else if(idct_algo==FF_IDCT_VP3 && + }else if((ENABLE_VP3_DECODER || ENABLE_VP5_DECODER || ENABLE_VP6_DECODER) && + idct_algo==FF_IDCT_VP3 && avctx->codec->id!=CODEC_ID_THEORA && !(avctx->flags & CODEC_FLAG_BITEXACT)){ if(mm_flags & MM_SSE2){ @@ -3170,96 +2050,45 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) } } -#ifdef CONFIG_ENCODERS - c->get_pixels = get_pixels_mmx; - c->diff_pixels = diff_pixels_mmx; -#endif //CONFIG_ENCODERS c->put_pixels_clamped = put_pixels_clamped_mmx; c->put_signed_pixels_clamped = put_signed_pixels_clamped_mmx; c->add_pixels_clamped = add_pixels_clamped_mmx; c->clear_blocks = clear_blocks_mmx; -#ifdef CONFIG_ENCODERS - c->pix_sum = pix_sum16_mmx; -#endif //CONFIG_ENCODERS - - c->put_pixels_tab[0][0] = put_pixels16_mmx; - c->put_pixels_tab[0][1] = put_pixels16_x2_mmx; - c->put_pixels_tab[0][2] = put_pixels16_y2_mmx; - c->put_pixels_tab[0][3] = put_pixels16_xy2_mmx; - - c->put_no_rnd_pixels_tab[0][0] = put_pixels16_mmx; - c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmx; - c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmx; - c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_mmx; - - c->avg_pixels_tab[0][0] = avg_pixels16_mmx; - c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmx; - c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmx; - c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmx; - - c->avg_no_rnd_pixels_tab[0][0] = avg_no_rnd_pixels16_mmx; - c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x2_mmx; - c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y2_mmx; - c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy2_mmx; - - c->put_pixels_tab[1][0] = put_pixels8_mmx; - c->put_pixels_tab[1][1] = put_pixels8_x2_mmx; - c->put_pixels_tab[1][2] = put_pixels8_y2_mmx; - c->put_pixels_tab[1][3] = put_pixels8_xy2_mmx; - - c->put_no_rnd_pixels_tab[1][0] = put_pixels8_mmx; - c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_mmx; - c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_mmx; - c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_mmx; - - c->avg_pixels_tab[1][0] = avg_pixels8_mmx; - c->avg_pixels_tab[1][1] = avg_pixels8_x2_mmx; - c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmx; - c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mmx; - - c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels8_mmx; - c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels8_x2_mmx; - c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels8_y2_mmx; - c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels8_xy2_mmx; + +#define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU) \ + c->PFX ## _pixels_tab[IDX][0] = PFX ## _pixels ## SIZE ## _ ## CPU; \ + c->PFX ## _pixels_tab[IDX][1] = PFX ## _pixels ## SIZE ## _x2_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][2] = PFX ## _pixels ## SIZE ## _y2_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU + + SET_HPEL_FUNCS(put, 0, 16, mmx); + SET_HPEL_FUNCS(put_no_rnd, 0, 16, mmx); + SET_HPEL_FUNCS(avg, 0, 16, mmx); + SET_HPEL_FUNCS(avg_no_rnd, 0, 16, mmx); + SET_HPEL_FUNCS(put, 1, 8, mmx); + SET_HPEL_FUNCS(put_no_rnd, 1, 8, mmx); + SET_HPEL_FUNCS(avg, 1, 8, mmx); + SET_HPEL_FUNCS(avg_no_rnd, 1, 8, mmx); c->gmc= gmc_mmx; c->add_bytes= add_bytes_mmx; -#ifdef CONFIG_ENCODERS - c->diff_bytes= diff_bytes_mmx; - - c->hadamard8_diff[0]= hadamard8_diff16_mmx; - c->hadamard8_diff[1]= hadamard8_diff_mmx; + c->add_bytes_l2= add_bytes_l2_mmx; - c->pix_norm1 = pix_norm1_mmx; - c->sse[0] = (mm_flags & MM_SSE2) ? sse16_sse2 : sse16_mmx; - c->sse[1] = sse8_mmx; - c->vsad[4]= vsad_intra16_mmx; - - c->nsse[0] = nsse16_mmx; - c->nsse[1] = nsse8_mmx; - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->vsad[0] = vsad16_mmx; + if (ENABLE_ANY_H263) { + c->h263_v_loop_filter= h263_v_loop_filter_mmx; + c->h263_h_loop_filter= h263_h_loop_filter_mmx; } - - if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ - c->try_8x8basis= try_8x8basis_mmx; - } - c->add_8x8basis= add_8x8basis_mmx; - - c->ssd_int8_vs_int16 = ssd_int8_vs_int16_mmx; - -#endif //CONFIG_ENCODERS - - c->h263_v_loop_filter= h263_v_loop_filter_mmx; - c->h263_h_loop_filter= h263_h_loop_filter_mmx; - c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_mmx; + c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_mmx_rnd; c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_mmx; + c->put_no_rnd_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_mmx_nornd; c->h264_idct_dc_add= c->h264_idct_add= ff_h264_idct_add_mmx; c->h264_idct8_dc_add= c->h264_idct8_add= ff_h264_idct8_add_mmx; + if (mm_flags & MM_SSE2) + c->h264_idct8_add= ff_h264_idct8_add_sse2; if (mm_flags & MM_MMXEXT) { c->prefetch = prefetch_mmx2; @@ -3278,12 +2107,6 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->avg_pixels_tab[1][1] = avg_pixels8_x2_mmx2; c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmx2; -#ifdef CONFIG_ENCODERS - c->hadamard8_diff[0]= hadamard8_diff16_mmx2; - c->hadamard8_diff[1]= hadamard8_diff_mmx2; - c->vsad[4]= vsad_intra16_mmx2; -#endif //CONFIG_ENCODERS - c->h264_idct_dc_add= ff_h264_idct_dc_add_mmx2; c->h264_idct8_dc_add= ff_h264_idct8_dc_add_mmx2; @@ -3294,79 +2117,46 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_mmx2; c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmx2; c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mmx2; -#ifdef CONFIG_ENCODERS - c->vsad[0] = vsad16_mmx2; -#endif //CONFIG_ENCODERS } -#if 1 - SET_QPEL_FUNC(qpel_pixels_tab[0][ 0], qpel16_mc00_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 1], qpel16_mc10_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 2], qpel16_mc20_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 3], qpel16_mc30_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 4], qpel16_mc01_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 6], qpel16_mc21_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 8], qpel16_mc02_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][10], qpel16_mc22_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][12], qpel16_mc03_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][14], qpel16_mc23_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 0], qpel8_mc00_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 1], qpel8_mc10_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 2], qpel8_mc20_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 3], qpel8_mc30_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 4], qpel8_mc01_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 6], qpel8_mc21_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 8], qpel8_mc02_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][10], qpel8_mc22_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][12], qpel8_mc03_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][14], qpel8_mc23_mmx2) - SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_mmx2) -#endif - -//FIXME 3dnow too -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_mmx2; \ - c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_mmx2; \ - c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_mmx2; \ - c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_mmx2; \ - c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_mmx2; \ - c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_mmx2; \ - c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_mmx2; \ - c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_mmx2 - - dspfunc(put_h264_qpel, 0, 16); - dspfunc(put_h264_qpel, 1, 8); - dspfunc(put_h264_qpel, 2, 4); - dspfunc(avg_h264_qpel, 0, 16); - dspfunc(avg_h264_qpel, 1, 8); - dspfunc(avg_h264_qpel, 2, 4); - - dspfunc(put_2tap_qpel, 0, 16); - dspfunc(put_2tap_qpel, 1, 8); - dspfunc(avg_2tap_qpel, 0, 16); - dspfunc(avg_2tap_qpel, 1, 8); -#undef dspfunc - - c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_mmx2; +#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU) \ + c->PFX ## _pixels_tab[IDX][ 0] = PFX ## SIZE ## _mc00_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 1] = PFX ## SIZE ## _mc10_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 2] = PFX ## SIZE ## _mc20_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 3] = PFX ## SIZE ## _mc30_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 4] = PFX ## SIZE ## _mc01_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 5] = PFX ## SIZE ## _mc11_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 6] = PFX ## SIZE ## _mc21_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 7] = PFX ## SIZE ## _mc31_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 8] = PFX ## SIZE ## _mc02_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 9] = PFX ## SIZE ## _mc12_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][10] = PFX ## SIZE ## _mc22_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][11] = PFX ## SIZE ## _mc32_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][12] = PFX ## SIZE ## _mc03_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][13] = PFX ## SIZE ## _mc13_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][14] = PFX ## SIZE ## _mc23_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][15] = PFX ## SIZE ## _mc33_ ## CPU + + SET_QPEL_FUNCS(put_qpel, 0, 16, mmx2); + SET_QPEL_FUNCS(put_qpel, 1, 8, mmx2); + SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmx2); + SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, mmx2); + SET_QPEL_FUNCS(avg_qpel, 0, 16, mmx2); + SET_QPEL_FUNCS(avg_qpel, 1, 8, mmx2); + + SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmx2); + SET_QPEL_FUNCS(put_h264_qpel, 1, 8, mmx2); + SET_QPEL_FUNCS(put_h264_qpel, 2, 4, mmx2); + SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmx2); + SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, mmx2); + SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, mmx2); + + SET_QPEL_FUNCS(put_2tap_qpel, 0, 16, mmx2); + SET_QPEL_FUNCS(put_2tap_qpel, 1, 8, mmx2); + SET_QPEL_FUNCS(avg_2tap_qpel, 0, 16, mmx2); + SET_QPEL_FUNCS(avg_2tap_qpel, 1, 8, mmx2); + + c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_mmx2_rnd; c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_mmx2; c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_mmx2; c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_mmx2; @@ -3396,13 +2186,13 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->biweight_h264_pixels_tab[6]= ff_h264_biweight_4x4_mmx2; c->biweight_h264_pixels_tab[7]= ff_h264_biweight_4x2_mmx2; -#ifdef CONFIG_CAVS_DECODER - ff_cavsdsp_init_mmx2(c, avctx); -#endif + if (ENABLE_CAVS_DECODER) + ff_cavsdsp_init_mmx2(c, avctx); + + if (ENABLE_VC1_DECODER || ENABLE_WMV3_DECODER) + ff_vc1dsp_init_mmx(c, avctx); -#ifdef CONFIG_ENCODERS - c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_mmx2; -#endif //CONFIG_ENCODERS + c->add_png_paeth_prediction= add_png_paeth_prediction_mmx2; } else if (mm_flags & MM_3DNOW) { c->prefetch = prefetch_3dnow; @@ -3429,82 +2219,90 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->avg_pixels_tab[1][3] = avg_pixels8_xy2_3dnow; } - SET_QPEL_FUNC(qpel_pixels_tab[0][ 0], qpel16_mc00_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 1], qpel16_mc10_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 2], qpel16_mc20_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 3], qpel16_mc30_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 4], qpel16_mc01_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 6], qpel16_mc21_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 8], qpel16_mc02_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][10], qpel16_mc22_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][12], qpel16_mc03_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][14], qpel16_mc23_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 0], qpel8_mc00_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 1], qpel8_mc10_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 2], qpel8_mc20_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 3], qpel8_mc30_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 4], qpel8_mc01_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 6], qpel8_mc21_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 8], qpel8_mc02_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][10], qpel8_mc22_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][12], qpel8_mc03_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][14], qpel8_mc23_3dnow) - SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_3dnow) - -#define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_3dnow; \ - c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_3dnow; \ - c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_3dnow; \ - c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_3dnow; \ - c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_3dnow; \ - c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_3dnow; \ - c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_3dnow; \ - c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_3dnow - - dspfunc(put_h264_qpel, 0, 16); - dspfunc(put_h264_qpel, 1, 8); - dspfunc(put_h264_qpel, 2, 4); - dspfunc(avg_h264_qpel, 0, 16); - dspfunc(avg_h264_qpel, 1, 8); - dspfunc(avg_h264_qpel, 2, 4); - - dspfunc(put_2tap_qpel, 0, 16); - dspfunc(put_2tap_qpel, 1, 8); - dspfunc(avg_2tap_qpel, 0, 16); - dspfunc(avg_2tap_qpel, 1, 8); - - c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_3dnow; + SET_QPEL_FUNCS(put_qpel, 0, 16, 3dnow); + SET_QPEL_FUNCS(put_qpel, 1, 8, 3dnow); + SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, 3dnow); + SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, 3dnow); + SET_QPEL_FUNCS(avg_qpel, 0, 16, 3dnow); + SET_QPEL_FUNCS(avg_qpel, 1, 8, 3dnow); + + SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 3dnow); + SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 3dnow); + SET_QPEL_FUNCS(put_h264_qpel, 2, 4, 3dnow); + SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 3dnow); + SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 3dnow); + SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, 3dnow); + + SET_QPEL_FUNCS(put_2tap_qpel, 0, 16, 3dnow); + SET_QPEL_FUNCS(put_2tap_qpel, 1, 8, 3dnow); + SET_QPEL_FUNCS(avg_2tap_qpel, 0, 16, 3dnow); + SET_QPEL_FUNCS(avg_2tap_qpel, 1, 8, 3dnow); + + c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_3dnow_rnd; c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_3dnow; } -#ifdef CONFIG_SNOW_DECODER + +#define H264_QPEL_FUNCS(x, y, CPU)\ + c->put_h264_qpel_pixels_tab[0][x+y*4] = put_h264_qpel16_mc##x##y##_##CPU;\ + c->put_h264_qpel_pixels_tab[1][x+y*4] = put_h264_qpel8_mc##x##y##_##CPU;\ + c->avg_h264_qpel_pixels_tab[0][x+y*4] = avg_h264_qpel16_mc##x##y##_##CPU;\ + c->avg_h264_qpel_pixels_tab[1][x+y*4] = avg_h264_qpel8_mc##x##y##_##CPU; + if((mm_flags & MM_SSE2) && !(mm_flags & MM_3DNOW)){ + // these functions are slower than mmx on AMD, but faster on Intel +/* FIXME works in most codecs, but crashes svq1 due to unaligned chroma + c->put_pixels_tab[0][0] = put_pixels16_sse2; + c->avg_pixels_tab[0][0] = avg_pixels16_sse2; +*/ + H264_QPEL_FUNCS(0, 0, sse2); + } if(mm_flags & MM_SSE2){ + H264_QPEL_FUNCS(0, 1, sse2); + H264_QPEL_FUNCS(0, 2, sse2); + H264_QPEL_FUNCS(0, 3, sse2); + H264_QPEL_FUNCS(1, 1, sse2); + H264_QPEL_FUNCS(1, 2, sse2); + H264_QPEL_FUNCS(1, 3, sse2); + H264_QPEL_FUNCS(2, 1, sse2); + H264_QPEL_FUNCS(2, 2, sse2); + H264_QPEL_FUNCS(2, 3, sse2); + H264_QPEL_FUNCS(3, 1, sse2); + H264_QPEL_FUNCS(3, 2, sse2); + H264_QPEL_FUNCS(3, 3, sse2); + } +#ifdef HAVE_SSSE3 + if(mm_flags & MM_SSSE3){ + H264_QPEL_FUNCS(1, 0, ssse3); + H264_QPEL_FUNCS(1, 1, ssse3); + H264_QPEL_FUNCS(1, 2, ssse3); + H264_QPEL_FUNCS(1, 3, ssse3); + H264_QPEL_FUNCS(2, 0, ssse3); + H264_QPEL_FUNCS(2, 1, ssse3); + H264_QPEL_FUNCS(2, 2, ssse3); + H264_QPEL_FUNCS(2, 3, ssse3); + H264_QPEL_FUNCS(3, 0, ssse3); + H264_QPEL_FUNCS(3, 1, ssse3); + H264_QPEL_FUNCS(3, 2, ssse3); + H264_QPEL_FUNCS(3, 3, ssse3); + c->add_png_paeth_prediction= add_png_paeth_prediction_ssse3; + } +#endif + +#ifdef CONFIG_SNOW_DECODER + if(mm_flags & MM_SSE2 & 0){ c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2; +#ifdef HAVE_7REGS c->vertical_compose97i = ff_snow_vertical_compose97i_sse2; +#endif c->inner_add_yblock = ff_snow_inner_add_yblock_sse2; } else{ + if(mm_flags & MM_MMXEXT){ c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx; +#ifdef HAVE_7REGS c->vertical_compose97i = ff_snow_vertical_compose97i_mmx; +#endif + } c->inner_add_yblock = ff_snow_inner_add_yblock_mmx; } #endif @@ -3528,9 +2326,9 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->vector_fmul_add_add = vector_fmul_add_add_3dnow; // faster than sse } -#ifdef CONFIG_ENCODERS - dsputil_init_pix_mmx(c, avctx); -#endif //CONFIG_ENCODERS + if (ENABLE_ENCODERS) + dsputilenc_init_mmx(c, avctx); + #if 0 // for speed testing get_pixels = just_return; diff --git a/contrib/ffmpeg/libavcodec/i386/dsputil_mmx.h b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx.h new file mode 100644 index 000000000..6f0d5ef19 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx.h @@ -0,0 +1,123 @@ +/* + * MMX optimized DSP utils + * Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> + * + * 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 + */ + +#ifndef FFMPEG_DSPUTIL_MMX_H +#define FFMPEG_DSPUTIL_MMX_H + +#include <stdint.h> +#include "dsputil.h" + +typedef struct { uint64_t a, b; } xmm_t; + +extern const uint64_t ff_bone; +extern const uint64_t ff_wtwo; + +extern const uint64_t ff_pdw_80000000[2]; + +extern const uint64_t ff_pw_3; +extern const uint64_t ff_pw_4; +extern const xmm_t ff_pw_5; +extern const uint64_t ff_pw_8; +extern const uint64_t ff_pw_15; +extern const xmm_t ff_pw_16; +extern const uint64_t ff_pw_20; +extern const xmm_t ff_pw_32; +extern const uint64_t ff_pw_42; +extern const uint64_t ff_pw_64; +extern const uint64_t ff_pw_96; +extern const uint64_t ff_pw_128; +extern const uint64_t ff_pw_255; + +extern const uint64_t ff_pb_1; +extern const uint64_t ff_pb_3; +extern const uint64_t ff_pb_7; +extern const uint64_t ff_pb_3F; +extern const uint64_t ff_pb_A1; +extern const uint64_t ff_pb_FC; + +extern const double ff_pd_1[2]; +extern const double ff_pd_2[2]; + +/* in/out: mma=mma+mmb, mmb=mmb-mma */ +#define SUMSUB_BA( a, b ) \ + "paddw "#b", "#a" \n\t"\ + "paddw "#b", "#b" \n\t"\ + "psubw "#a", "#b" \n\t" + +#define SBUTTERFLY(a,b,t,n,m)\ + "mov" #m " " #a ", " #t " \n\t" /* abcd */\ + "punpckl" #n " " #b ", " #a " \n\t" /* aebf */\ + "punpckh" #n " " #b ", " #t " \n\t" /* cgdh */\ + +#define TRANSPOSE4(a,b,c,d,t)\ + SBUTTERFLY(a,b,t,wd,q) /* a=aebf t=cgdh */\ + SBUTTERFLY(c,d,b,wd,q) /* c=imjn b=kolp */\ + SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\ + SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */ + +#ifdef ARCH_X86_64 +// permutes 01234567 -> 05736421 +#define TRANSPOSE8(a,b,c,d,e,f,g,h,t)\ + SBUTTERFLY(a,b,%%xmm8,wd,dqa)\ + SBUTTERFLY(c,d,b,wd,dqa)\ + SBUTTERFLY(e,f,d,wd,dqa)\ + SBUTTERFLY(g,h,f,wd,dqa)\ + SBUTTERFLY(a,c,h,dq,dqa)\ + SBUTTERFLY(%%xmm8,b,c,dq,dqa)\ + SBUTTERFLY(e,g,b,dq,dqa)\ + SBUTTERFLY(d,f,g,dq,dqa)\ + SBUTTERFLY(a,e,f,qdq,dqa)\ + SBUTTERFLY(%%xmm8,d,e,qdq,dqa)\ + SBUTTERFLY(h,b,d,qdq,dqa)\ + SBUTTERFLY(c,g,b,qdq,dqa)\ + "movdqa %%xmm8, "#g" \n\t" +#else +#define TRANSPOSE8(a,b,c,d,e,f,g,h,t)\ + "movdqa "#h", "#t" \n\t"\ + SBUTTERFLY(a,b,h,wd,dqa)\ + "movdqa "#h", 16"#t" \n\t"\ + "movdqa "#t", "#h" \n\t"\ + SBUTTERFLY(c,d,b,wd,dqa)\ + SBUTTERFLY(e,f,d,wd,dqa)\ + SBUTTERFLY(g,h,f,wd,dqa)\ + SBUTTERFLY(a,c,h,dq,dqa)\ + "movdqa "#h", "#t" \n\t"\ + "movdqa 16"#t", "#h" \n\t"\ + SBUTTERFLY(h,b,c,dq,dqa)\ + SBUTTERFLY(e,g,b,dq,dqa)\ + SBUTTERFLY(d,f,g,dq,dqa)\ + SBUTTERFLY(a,e,f,qdq,dqa)\ + SBUTTERFLY(h,d,e,qdq,dqa)\ + "movdqa "#h", 16"#t" \n\t"\ + "movdqa "#t", "#h" \n\t"\ + SBUTTERFLY(h,b,d,qdq,dqa)\ + SBUTTERFLY(c,g,b,qdq,dqa)\ + "movdqa 16"#t", "#g" \n\t" +#endif + +#define MOVQ_WONE(regd) \ + asm volatile ( \ + "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ + "psrlw $15, %%" #regd ::) + +void dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx); + +#endif /* FFMPEG_DSPUTIL_MMX_H */ diff --git a/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_avg.h b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_avg.h index b365cea57..c6c7aaa62 100644 --- a/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_avg.h +++ b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_avg.h @@ -3,6 +3,10 @@ * Copyright (c) 2000, 2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer * + * MMX optimization by Nick Kurshev <nickols_k@mail.ru> + * mostly rewritten by Michael Niedermayer <michaelni@gmx.at> + * and improved by Zdenek Kabelac <kabi@users.sf.net> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,18 +22,18 @@ * 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 - * - * MMX optimization by Nick Kurshev <nickols_k@mail.ru> - * mostly rewritten by Michael Niedermayer <michaelni@gmx.at> - * and improved by Zdenek Kabelac <kabi@users.sf.net> */ +/* This header intentionally has no multiple inclusion guards. It is meant to + * be included multiple times and generates different code depending on the + * value of certain #defines. */ + /* XXX: we use explicit registers to avoid a gcc 2.95.2 register asm clobber bug - now it will work with 2.95.2 and also with -fPIC */ static void DEF(put_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" @@ -57,7 +61,7 @@ static void DEF(put_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_ static void DEF(put_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { - __asm __volatile( + asm volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movd (%1), %%mm0 \n\t" @@ -96,7 +100,7 @@ static void DEF(put_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int "add $16, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -108,7 +112,7 @@ static void DEF(put_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int static void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { - __asm __volatile( + asm volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" @@ -143,7 +147,7 @@ static void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int "add $32, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -158,7 +162,7 @@ static void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int static void DEF(put_no_rnd_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { - __asm __volatile( + asm volatile( "pcmpeqb %%mm6, %%mm6 \n\t" "testl $1, %0 \n\t" " jz 1f \n\t" @@ -213,7 +217,7 @@ static void DEF(put_no_rnd_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src "add $32, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -228,7 +232,7 @@ static void DEF(put_no_rnd_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src static void DEF(avg_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { - __asm __volatile( + asm volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movd (%1), %%mm0 \n\t" @@ -268,7 +272,7 @@ static void DEF(avg_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int "add $16, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -280,7 +284,7 @@ static void DEF(avg_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int static void DEF(avg_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { - __asm __volatile( + asm volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" @@ -320,7 +324,7 @@ static void DEF(avg_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int "add $32, %2 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -335,7 +339,7 @@ static void DEF(avg_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int static void DEF(put_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" @@ -375,7 +379,7 @@ static void DEF(put_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line static void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { - __asm __volatile( + asm volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" @@ -408,7 +412,7 @@ static void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int "add $32, %2 \n\t" "subl $2, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -423,7 +427,7 @@ static void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int static void DEF(avg_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { - __asm __volatile( + asm volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" @@ -462,7 +466,7 @@ static void DEF(avg_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int "add $32, %2 \n\t" "subl $2, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -477,7 +481,7 @@ static void DEF(avg_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int static void DEF(put_no_rnd_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { - __asm __volatile( + asm volatile( "pcmpeqb %%mm6, %%mm6 \n\t" "testl $1, %0 \n\t" " jz 1f \n\t" @@ -535,7 +539,7 @@ static void DEF(put_no_rnd_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *sr "add $32, %2 \n\t" "subl $2, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -552,7 +556,7 @@ static void DEF(put_no_rnd_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *sr static void DEF(put_no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BONE(mm6); - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" @@ -588,7 +592,7 @@ static void DEF(put_no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, in static void DEF(put_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" "sub %3, %2 \n\t" @@ -620,7 +624,7 @@ static void DEF(put_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_ static void DEF(put_no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BONE(mm6); - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" "sub %3, %2 \n\t" @@ -652,7 +656,7 @@ static void DEF(put_no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, in static void DEF(avg_pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%2), %%mm0 \n\t" @@ -680,7 +684,7 @@ static void DEF(avg_pixels8)(uint8_t *block, const uint8_t *pixels, int line_siz static void DEF(avg_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "1: \n\t" "movq (%1), %%mm0 \n\t" @@ -712,7 +716,7 @@ static void DEF(avg_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_ static void DEF(avg_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" "sub %3, %2 \n\t" @@ -748,11 +752,12 @@ static void DEF(avg_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_ :"%"REG_a, "memory"); } -// Note this is not correctly rounded, but this function is only used for b frames so it doesnt matter +/* Note this is not correctly rounded, but this function is only + * used for B-frames so it does not matter. */ static void DEF(avg_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BONE(mm6); - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" PAVGB" 1(%1), %%mm0 \n\t" @@ -790,6 +795,31 @@ static void DEF(avg_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line :"%"REG_a, "memory"); } +static void DEF(avg_pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + do { + asm volatile( + "movd (%1), %%mm0 \n\t" + "movd (%1, %2), %%mm1 \n\t" + "movd (%1, %2, 2), %%mm2 \n\t" + "movd (%1, %3), %%mm3 \n\t" + PAVGB" (%0), %%mm0 \n\t" + PAVGB" (%0, %2), %%mm1 \n\t" + PAVGB" (%0, %2, 2), %%mm2 \n\t" + PAVGB" (%0, %3), %%mm3 \n\t" + "movd %%mm0, (%1) \n\t" + "movd %%mm1, (%1, %2) \n\t" + "movd %%mm2, (%1, %2, 2) \n\t" + "movd %%mm3, (%1, %3) \n\t" + ::"S"(pixels), "D"(block), + "r" ((long)line_size), "r"(3L*line_size) + :"memory"); + block += 4*line_size; + pixels += 4*line_size; + h -= 4; + } while(h > 0); +} + //FIXME the following could be optimized too ... static void DEF(put_no_rnd_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ DEF(put_no_rnd_pixels8_x2)(block , pixels , line_size, h); diff --git a/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_qns.h b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_qns.h new file mode 100644 index 000000000..f01f0b08b --- /dev/null +++ b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_qns.h @@ -0,0 +1,105 @@ +/* + * DSP utils : QNS functions are compiled 3 times for mmx/3dnow/ssse3 + * Copyright (c) 2004 Michael Niedermayer + * + * MMX optimization by Michael Niedermayer <michaelni@gmx.at> + * 3DNow! and SSSE3 optimization by Zuxy Meng <zuxy.meng@gmail.com> + * + * 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 + */ + +/* This header intentionally has no multiple inclusion guards. It is meant to + * be included multiple times and generates different code depending on the + * value of certain #defines. */ + +#define MAX_ABS (512 >> (SCALE_OFFSET>0 ? SCALE_OFFSET : 0)) + +static int DEF(try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale) +{ + long i=0; + + assert(FFABS(scale) < MAX_ABS); + scale<<= 16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT; + + SET_RND(mm6); + asm volatile( + "pxor %%mm7, %%mm7 \n\t" + "movd %4, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + ASMALIGN(4) + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq 8(%1, %0), %%mm1 \n\t" + PMULHRW(%%mm0, %%mm1, %%mm5, %%mm6) + "paddw (%2, %0), %%mm0 \n\t" + "paddw 8(%2, %0), %%mm1 \n\t" + "psraw $6, %%mm0 \n\t" + "psraw $6, %%mm1 \n\t" + "pmullw (%3, %0), %%mm0 \n\t" + "pmullw 8(%3, %0), %%mm1 \n\t" + "pmaddwd %%mm0, %%mm0 \n\t" + "pmaddwd %%mm1, %%mm1 \n\t" + "paddd %%mm1, %%mm0 \n\t" + "psrld $4, %%mm0 \n\t" + "paddd %%mm0, %%mm7 \n\t" + "add $16, %0 \n\t" + "cmp $128, %0 \n\t" //FIXME optimize & bench + " jb 1b \n\t" + PHADDD(%%mm7, %%mm6) + "psrld $2, %%mm7 \n\t" + "movd %%mm7, %0 \n\t" + + : "+r" (i) + : "r"(basis), "r"(rem), "r"(weight), "g"(scale) + ); + return i; +} + +static void DEF(add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale) +{ + long i=0; + + if(FFABS(scale) < MAX_ABS){ + scale<<= 16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT; + SET_RND(mm6); + asm volatile( + "movd %3, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + ASMALIGN(4) + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq 8(%1, %0), %%mm1 \n\t" + PMULHRW(%%mm0, %%mm1, %%mm5, %%mm6) + "paddw (%2, %0), %%mm0 \n\t" + "paddw 8(%2, %0), %%mm1 \n\t" + "movq %%mm0, (%2, %0) \n\t" + "movq %%mm1, 8(%2, %0) \n\t" + "add $16, %0 \n\t" + "cmp $128, %0 \n\t" // FIXME optimize & bench + " jb 1b \n\t" + + : "+r" (i) + : "r"(basis), "r"(rem), "g"(scale) + ); + }else{ + for(i=0; i<8*8; i++){ + rem[i] += (basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT); + } + } +} diff --git a/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_rnd.h b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_rnd.h index f53b34662..33c8a2692 100644 --- a/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_rnd.h +++ b/contrib/ffmpeg/libavcodec/i386/dsputil_mmx_rnd.h @@ -3,6 +3,10 @@ * Copyright (c) 2000, 2001 Fabrice Bellard. * Copyright (c) 2003-2004 Michael Niedermayer <michaelni@gmx.at> * + * MMX optimization by Nick Kurshev <nickols_k@mail.ru> + * mostly rewritten by Michael Niedermayer <michaelni@gmx.at> + * and improved by Zdenek Kabelac <kabi@users.sf.net> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,17 +22,17 @@ * 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 - * - * MMX optimization by Nick Kurshev <nickols_k@mail.ru> - * mostly rewritten by Michael Niedermayer <michaelni@gmx.at> - * and improved by Zdenek Kabelac <kabi@users.sf.net> */ +/* This header intentionally has no multiple inclusion guards. It is meant to + * be included multiple times and generates different code depending on the + * value of certain #defines. */ + // put_pixels static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BFE(mm6); - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" ASMALIGN(3) "1: \n\t" @@ -57,10 +61,10 @@ static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line :REG_a, "memory"); } -static void attribute_unused DEF(put, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +static void av_unused DEF(put, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { MOVQ_BFE(mm6); - __asm __volatile( + asm volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" @@ -98,7 +102,7 @@ static void attribute_unused DEF(put, pixels8_l2)(uint8_t *dst, uint8_t *src1, u "add %5, %3 \n\t" "subl $4, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -110,7 +114,7 @@ static void attribute_unused DEF(put, pixels8_l2)(uint8_t *dst, uint8_t *src1, u static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BFE(mm6); - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" ASMALIGN(3) "1: \n\t" @@ -153,10 +157,10 @@ static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int lin :REG_a, "memory"); } -static void attribute_unused DEF(put, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +static void av_unused DEF(put, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { MOVQ_BFE(mm6); - __asm __volatile( + asm volatile( "testl $1, %0 \n\t" " jz 1f \n\t" "movq (%1), %%mm0 \n\t" @@ -193,7 +197,7 @@ static void attribute_unused DEF(put, pixels16_l2)(uint8_t *dst, uint8_t *src1, "add $32, %2 \n\t" "subl $2, %0 \n\t" "jnz 1b \n\t" -#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) #else :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) @@ -205,7 +209,7 @@ static void attribute_unused DEF(put, pixels16_l2)(uint8_t *dst, uint8_t *src1, static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BFE(mm6); - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" ASMALIGN(3) @@ -235,7 +239,7 @@ static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int lin { MOVQ_ZERO(mm7); SET_RND(mm6); // =2 for rnd and =1 for no_rnd version - __asm __volatile( + asm volatile( "movq (%1), %%mm0 \n\t" "movq 1(%1), %%mm4 \n\t" "movq %%mm0, %%mm1 \n\t" @@ -298,12 +302,12 @@ static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int lin } // avg_pixels -static void attribute_unused DEF(avg, pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +static void av_unused DEF(avg, pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BFE(mm6); JUMPALIGN(); do { - __asm __volatile( + asm volatile( "movd %0, %%mm0 \n\t" "movd %1, %%mm1 \n\t" PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) @@ -323,7 +327,7 @@ static void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, int line_si MOVQ_BFE(mm6); JUMPALIGN(); do { - __asm __volatile( + asm volatile( "movq %0, %%mm0 \n\t" "movq %1, %%mm1 \n\t" PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) @@ -342,7 +346,7 @@ static void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, int line_s MOVQ_BFE(mm6); JUMPALIGN(); do { - __asm __volatile( + asm volatile( "movq %0, %%mm0 \n\t" "movq %1, %%mm1 \n\t" PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) @@ -365,7 +369,7 @@ static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line MOVQ_BFE(mm6); JUMPALIGN(); do { - __asm __volatile( + asm volatile( "movq %1, %%mm0 \n\t" "movq 1%1, %%mm1 \n\t" "movq %0, %%mm3 \n\t" @@ -380,12 +384,12 @@ static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line } while (--h); } -static __attribute__((unused)) void DEF(avg, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +static av_unused void DEF(avg, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { MOVQ_BFE(mm6); JUMPALIGN(); do { - __asm __volatile( + asm volatile( "movq %1, %%mm0 \n\t" "movq %2, %%mm1 \n\t" "movq %0, %%mm3 \n\t" @@ -406,7 +410,7 @@ static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int lin MOVQ_BFE(mm6); JUMPALIGN(); do { - __asm __volatile( + asm volatile( "movq %1, %%mm0 \n\t" "movq 1%1, %%mm1 \n\t" "movq %0, %%mm3 \n\t" @@ -427,12 +431,12 @@ static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int lin } while (--h); } -static __attribute__((unused)) void DEF(avg, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +static av_unused void DEF(avg, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) { MOVQ_BFE(mm6); JUMPALIGN(); do { - __asm __volatile( + asm volatile( "movq %1, %%mm0 \n\t" "movq %2, %%mm1 \n\t" "movq %0, %%mm3 \n\t" @@ -457,7 +461,7 @@ static __attribute__((unused)) void DEF(avg, pixels16_l2)(uint8_t *dst, uint8_t static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) { MOVQ_BFE(mm6); - __asm __volatile( + asm volatile( "lea (%3, %3), %%"REG_a" \n\t" "movq (%1), %%mm0 \n\t" ASMALIGN(3) @@ -498,7 +502,7 @@ static void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int lin { MOVQ_ZERO(mm7); SET_RND(mm6); // =2 for rnd and =1 for no_rnd version - __asm __volatile( + asm volatile( "movq (%1), %%mm0 \n\t" "movq 1(%1), %%mm4 \n\t" "movq %%mm0, %%mm1 \n\t" @@ -588,5 +592,3 @@ static void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int li DEF(avg, pixels8_xy2)(block , pixels , line_size, h); DEF(avg, pixels8_xy2)(block+8, pixels+8, line_size, h); } - - diff --git a/contrib/ffmpeg/libavcodec/i386/dsputilenc_mmx.c b/contrib/ffmpeg/libavcodec/i386/dsputilenc_mmx.c new file mode 100644 index 000000000..c9fb67045 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/i386/dsputilenc_mmx.c @@ -0,0 +1,1422 @@ +/* + * MMX optimized DSP utils + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 + * + * MMX optimization by Nick Kurshev <nickols_k@mail.ru> + */ + +#include "dsputil.h" +#include "dsputil_mmx.h" +#include "mpegvideo.h" +#include "x86_cpu.h" + + +static void get_pixels_mmx(DCTELEM *block, const uint8_t *pixels, int line_size) +{ + asm volatile( + "mov $-128, %%"REG_a" \n\t" + "pxor %%mm7, %%mm7 \n\t" + ASMALIGN(4) + "1: \n\t" + "movq (%0), %%mm0 \n\t" + "movq (%0, %2), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "movq %%mm0, (%1, %%"REG_a") \n\t" + "movq %%mm1, 8(%1, %%"REG_a") \n\t" + "movq %%mm2, 16(%1, %%"REG_a") \n\t" + "movq %%mm3, 24(%1, %%"REG_a") \n\t" + "add %3, %0 \n\t" + "add $32, %%"REG_a" \n\t" + "js 1b \n\t" + : "+r" (pixels) + : "r" (block+64), "r" ((long)line_size), "r" ((long)line_size*2) + : "%"REG_a + ); +} + +static inline void diff_pixels_mmx(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride) +{ + asm volatile( + "pxor %%mm7, %%mm7 \n\t" + "mov $-128, %%"REG_a" \n\t" + ASMALIGN(4) + "1: \n\t" + "movq (%0), %%mm0 \n\t" + "movq (%1), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "movq %%mm0, (%2, %%"REG_a") \n\t" + "movq %%mm1, 8(%2, %%"REG_a") \n\t" + "add %3, %0 \n\t" + "add %3, %1 \n\t" + "add $16, %%"REG_a" \n\t" + "jnz 1b \n\t" + : "+r" (s1), "+r" (s2) + : "r" (block+64), "r" ((long)stride) + : "%"REG_a + ); +} + +static int pix_sum16_mmx(uint8_t * pix, int line_size){ + const int h=16; + int sum; + long index= -line_size*h; + + asm volatile( + "pxor %%mm7, %%mm7 \n\t" + "pxor %%mm6, %%mm6 \n\t" + "1: \n\t" + "movq (%2, %1), %%mm0 \n\t" + "movq (%2, %1), %%mm1 \n\t" + "movq 8(%2, %1), %%mm2 \n\t" + "movq 8(%2, %1), %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddw %%mm0, %%mm1 \n\t" + "paddw %%mm2, %%mm3 \n\t" + "paddw %%mm1, %%mm3 \n\t" + "paddw %%mm3, %%mm6 \n\t" + "add %3, %1 \n\t" + " js 1b \n\t" + "movq %%mm6, %%mm5 \n\t" + "psrlq $32, %%mm6 \n\t" + "paddw %%mm5, %%mm6 \n\t" + "movq %%mm6, %%mm5 \n\t" + "psrlq $16, %%mm6 \n\t" + "paddw %%mm5, %%mm6 \n\t" + "movd %%mm6, %0 \n\t" + "andl $0xFFFF, %0 \n\t" + : "=&r" (sum), "+r" (index) + : "r" (pix - index), "r" ((long)line_size) + ); + + return sum; +} + +static int pix_norm1_mmx(uint8_t *pix, int line_size) { + int tmp; + asm volatile ( + "movl $16,%%ecx\n" + "pxor %%mm0,%%mm0\n" + "pxor %%mm7,%%mm7\n" + "1:\n" + "movq (%0),%%mm2\n" /* mm2 = pix[0-7] */ + "movq 8(%0),%%mm3\n" /* mm3 = pix[8-15] */ + + "movq %%mm2,%%mm1\n" /* mm1 = mm2 = pix[0-7] */ + + "punpckhbw %%mm0,%%mm1\n" /* mm1 = [pix4-7] */ + "punpcklbw %%mm0,%%mm2\n" /* mm2 = [pix0-3] */ + + "movq %%mm3,%%mm4\n" /* mm4 = mm3 = pix[8-15] */ + "punpckhbw %%mm0,%%mm3\n" /* mm3 = [pix12-15] */ + "punpcklbw %%mm0,%%mm4\n" /* mm4 = [pix8-11] */ + + "pmaddwd %%mm1,%%mm1\n" /* mm1 = (pix0^2+pix1^2,pix2^2+pix3^2) */ + "pmaddwd %%mm2,%%mm2\n" /* mm2 = (pix4^2+pix5^2,pix6^2+pix7^2) */ + + "pmaddwd %%mm3,%%mm3\n" + "pmaddwd %%mm4,%%mm4\n" + + "paddd %%mm1,%%mm2\n" /* mm2 = (pix0^2+pix1^2+pix4^2+pix5^2, + pix2^2+pix3^2+pix6^2+pix7^2) */ + "paddd %%mm3,%%mm4\n" + "paddd %%mm2,%%mm7\n" + + "add %2, %0\n" + "paddd %%mm4,%%mm7\n" + "dec %%ecx\n" + "jnz 1b\n" + + "movq %%mm7,%%mm1\n" + "psrlq $32, %%mm7\n" /* shift hi dword to lo */ + "paddd %%mm7,%%mm1\n" + "movd %%mm1,%1\n" + : "+r" (pix), "=r"(tmp) : "r" ((long)line_size) : "%ecx" ); + return tmp; +} + +static int sse8_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + int tmp; + asm volatile ( + "movl %4,%%ecx\n" + "shr $1,%%ecx\n" + "pxor %%mm0,%%mm0\n" /* mm0 = 0 */ + "pxor %%mm7,%%mm7\n" /* mm7 holds the sum */ + "1:\n" + "movq (%0),%%mm1\n" /* mm1 = pix1[0][0-7] */ + "movq (%1),%%mm2\n" /* mm2 = pix2[0][0-7] */ + "movq (%0,%3),%%mm3\n" /* mm3 = pix1[1][0-7] */ + "movq (%1,%3),%%mm4\n" /* mm4 = pix2[1][0-7] */ + + /* todo: mm1-mm2, mm3-mm4 */ + /* algo: subtract mm1 from mm2 with saturation and vice versa */ + /* OR the results to get absolute difference */ + "movq %%mm1,%%mm5\n" + "movq %%mm3,%%mm6\n" + "psubusb %%mm2,%%mm1\n" + "psubusb %%mm4,%%mm3\n" + "psubusb %%mm5,%%mm2\n" + "psubusb %%mm6,%%mm4\n" + + "por %%mm1,%%mm2\n" + "por %%mm3,%%mm4\n" + + /* now convert to 16-bit vectors so we can square them */ + "movq %%mm2,%%mm1\n" + "movq %%mm4,%%mm3\n" + + "punpckhbw %%mm0,%%mm2\n" + "punpckhbw %%mm0,%%mm4\n" + "punpcklbw %%mm0,%%mm1\n" /* mm1 now spread over (mm1,mm2) */ + "punpcklbw %%mm0,%%mm3\n" /* mm4 now spread over (mm3,mm4) */ + + "pmaddwd %%mm2,%%mm2\n" + "pmaddwd %%mm4,%%mm4\n" + "pmaddwd %%mm1,%%mm1\n" + "pmaddwd %%mm3,%%mm3\n" + + "lea (%0,%3,2), %0\n" /* pix1 += 2*line_size */ + "lea (%1,%3,2), %1\n" /* pix2 += 2*line_size */ + + "paddd %%mm2,%%mm1\n" + "paddd %%mm4,%%mm3\n" + "paddd %%mm1,%%mm7\n" + "paddd %%mm3,%%mm7\n" + + "decl %%ecx\n" + "jnz 1b\n" + + "movq %%mm7,%%mm1\n" + "psrlq $32, %%mm7\n" /* shift hi dword to lo */ + "paddd %%mm7,%%mm1\n" + "movd %%mm1,%2\n" + : "+r" (pix1), "+r" (pix2), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp; +} + +static int sse16_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + int tmp; + asm volatile ( + "movl %4,%%ecx\n" + "pxor %%mm0,%%mm0\n" /* mm0 = 0 */ + "pxor %%mm7,%%mm7\n" /* mm7 holds the sum */ + "1:\n" + "movq (%0),%%mm1\n" /* mm1 = pix1[0-7] */ + "movq (%1),%%mm2\n" /* mm2 = pix2[0-7] */ + "movq 8(%0),%%mm3\n" /* mm3 = pix1[8-15] */ + "movq 8(%1),%%mm4\n" /* mm4 = pix2[8-15] */ + + /* todo: mm1-mm2, mm3-mm4 */ + /* algo: subtract mm1 from mm2 with saturation and vice versa */ + /* OR the results to get absolute difference */ + "movq %%mm1,%%mm5\n" + "movq %%mm3,%%mm6\n" + "psubusb %%mm2,%%mm1\n" + "psubusb %%mm4,%%mm3\n" + "psubusb %%mm5,%%mm2\n" + "psubusb %%mm6,%%mm4\n" + + "por %%mm1,%%mm2\n" + "por %%mm3,%%mm4\n" + + /* now convert to 16-bit vectors so we can square them */ + "movq %%mm2,%%mm1\n" + "movq %%mm4,%%mm3\n" + + "punpckhbw %%mm0,%%mm2\n" + "punpckhbw %%mm0,%%mm4\n" + "punpcklbw %%mm0,%%mm1\n" /* mm1 now spread over (mm1,mm2) */ + "punpcklbw %%mm0,%%mm3\n" /* mm4 now spread over (mm3,mm4) */ + + "pmaddwd %%mm2,%%mm2\n" + "pmaddwd %%mm4,%%mm4\n" + "pmaddwd %%mm1,%%mm1\n" + "pmaddwd %%mm3,%%mm3\n" + + "add %3,%0\n" + "add %3,%1\n" + + "paddd %%mm2,%%mm1\n" + "paddd %%mm4,%%mm3\n" + "paddd %%mm1,%%mm7\n" + "paddd %%mm3,%%mm7\n" + + "decl %%ecx\n" + "jnz 1b\n" + + "movq %%mm7,%%mm1\n" + "psrlq $32, %%mm7\n" /* shift hi dword to lo */ + "paddd %%mm7,%%mm1\n" + "movd %%mm1,%2\n" + : "+r" (pix1), "+r" (pix2), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp; +} + +static int sse16_sse2(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + int tmp; + asm volatile ( + "shr $1,%2\n" + "pxor %%xmm0,%%xmm0\n" /* mm0 = 0 */ + "pxor %%xmm7,%%xmm7\n" /* mm7 holds the sum */ + "1:\n" + "movdqu (%0),%%xmm1\n" /* mm1 = pix1[0][0-15] */ + "movdqu (%1),%%xmm2\n" /* mm2 = pix2[0][0-15] */ + "movdqu (%0,%4),%%xmm3\n" /* mm3 = pix1[1][0-15] */ + "movdqu (%1,%4),%%xmm4\n" /* mm4 = pix2[1][0-15] */ + + /* todo: mm1-mm2, mm3-mm4 */ + /* algo: subtract mm1 from mm2 with saturation and vice versa */ + /* OR the results to get absolute difference */ + "movdqa %%xmm1,%%xmm5\n" + "movdqa %%xmm3,%%xmm6\n" + "psubusb %%xmm2,%%xmm1\n" + "psubusb %%xmm4,%%xmm3\n" + "psubusb %%xmm5,%%xmm2\n" + "psubusb %%xmm6,%%xmm4\n" + + "por %%xmm1,%%xmm2\n" + "por %%xmm3,%%xmm4\n" + + /* now convert to 16-bit vectors so we can square them */ + "movdqa %%xmm2,%%xmm1\n" + "movdqa %%xmm4,%%xmm3\n" + + "punpckhbw %%xmm0,%%xmm2\n" + "punpckhbw %%xmm0,%%xmm4\n" + "punpcklbw %%xmm0,%%xmm1\n" /* mm1 now spread over (mm1,mm2) */ + "punpcklbw %%xmm0,%%xmm3\n" /* mm4 now spread over (mm3,mm4) */ + + "pmaddwd %%xmm2,%%xmm2\n" + "pmaddwd %%xmm4,%%xmm4\n" + "pmaddwd %%xmm1,%%xmm1\n" + "pmaddwd %%xmm3,%%xmm3\n" + + "lea (%0,%4,2), %0\n" /* pix1 += 2*line_size */ + "lea (%1,%4,2), %1\n" /* pix2 += 2*line_size */ + + "paddd %%xmm2,%%xmm1\n" + "paddd %%xmm4,%%xmm3\n" + "paddd %%xmm1,%%xmm7\n" + "paddd %%xmm3,%%xmm7\n" + + "decl %2\n" + "jnz 1b\n" + + "movdqa %%xmm7,%%xmm1\n" + "psrldq $8, %%xmm7\n" /* shift hi qword to lo */ + "paddd %%xmm1,%%xmm7\n" + "movdqa %%xmm7,%%xmm1\n" + "psrldq $4, %%xmm7\n" /* shift hi dword to lo */ + "paddd %%xmm1,%%xmm7\n" + "movd %%xmm7,%3\n" + : "+r" (pix1), "+r" (pix2), "+r"(h), "=r"(tmp) + : "r" ((long)line_size)); + return tmp; +} + +static int hf_noise8_mmx(uint8_t * pix1, int line_size, int h) { + int tmp; + asm volatile ( + "movl %3,%%ecx\n" + "pxor %%mm7,%%mm7\n" + "pxor %%mm6,%%mm6\n" + + "movq (%0),%%mm0\n" + "movq %%mm0, %%mm1\n" + "psllq $8, %%mm0\n" + "psrlq $8, %%mm1\n" + "psrlq $8, %%mm0\n" + "movq %%mm0, %%mm2\n" + "movq %%mm1, %%mm3\n" + "punpcklbw %%mm7,%%mm0\n" + "punpcklbw %%mm7,%%mm1\n" + "punpckhbw %%mm7,%%mm2\n" + "punpckhbw %%mm7,%%mm3\n" + "psubw %%mm1, %%mm0\n" + "psubw %%mm3, %%mm2\n" + + "add %2,%0\n" + + "movq (%0),%%mm4\n" + "movq %%mm4, %%mm1\n" + "psllq $8, %%mm4\n" + "psrlq $8, %%mm1\n" + "psrlq $8, %%mm4\n" + "movq %%mm4, %%mm5\n" + "movq %%mm1, %%mm3\n" + "punpcklbw %%mm7,%%mm4\n" + "punpcklbw %%mm7,%%mm1\n" + "punpckhbw %%mm7,%%mm5\n" + "punpckhbw %%mm7,%%mm3\n" + "psubw %%mm1, %%mm4\n" + "psubw %%mm3, %%mm5\n" + "psubw %%mm4, %%mm0\n" + "psubw %%mm5, %%mm2\n" + "pxor %%mm3, %%mm3\n" + "pxor %%mm1, %%mm1\n" + "pcmpgtw %%mm0, %%mm3\n\t" + "pcmpgtw %%mm2, %%mm1\n\t" + "pxor %%mm3, %%mm0\n" + "pxor %%mm1, %%mm2\n" + "psubw %%mm3, %%mm0\n" + "psubw %%mm1, %%mm2\n" + "paddw %%mm0, %%mm2\n" + "paddw %%mm2, %%mm6\n" + + "add %2,%0\n" + "1:\n" + + "movq (%0),%%mm0\n" + "movq %%mm0, %%mm1\n" + "psllq $8, %%mm0\n" + "psrlq $8, %%mm1\n" + "psrlq $8, %%mm0\n" + "movq %%mm0, %%mm2\n" + "movq %%mm1, %%mm3\n" + "punpcklbw %%mm7,%%mm0\n" + "punpcklbw %%mm7,%%mm1\n" + "punpckhbw %%mm7,%%mm2\n" + "punpckhbw %%mm7,%%mm3\n" + "psubw %%mm1, %%mm0\n" + "psubw %%mm3, %%mm2\n" + "psubw %%mm0, %%mm4\n" + "psubw %%mm2, %%mm5\n" + "pxor %%mm3, %%mm3\n" + "pxor %%mm1, %%mm1\n" + "pcmpgtw %%mm4, %%mm3\n\t" + "pcmpgtw %%mm5, %%mm1\n\t" + "pxor %%mm3, %%mm4\n" + "pxor %%mm1, %%mm5\n" + "psubw %%mm3, %%mm4\n" + "psubw %%mm1, %%mm5\n" + "paddw %%mm4, %%mm5\n" + "paddw %%mm5, %%mm6\n" + + "add %2,%0\n" + + "movq (%0),%%mm4\n" + "movq %%mm4, %%mm1\n" + "psllq $8, %%mm4\n" + "psrlq $8, %%mm1\n" + "psrlq $8, %%mm4\n" + "movq %%mm4, %%mm5\n" + "movq %%mm1, %%mm3\n" + "punpcklbw %%mm7,%%mm4\n" + "punpcklbw %%mm7,%%mm1\n" + "punpckhbw %%mm7,%%mm5\n" + "punpckhbw %%mm7,%%mm3\n" + "psubw %%mm1, %%mm4\n" + "psubw %%mm3, %%mm5\n" + "psubw %%mm4, %%mm0\n" + "psubw %%mm5, %%mm2\n" + "pxor %%mm3, %%mm3\n" + "pxor %%mm1, %%mm1\n" + "pcmpgtw %%mm0, %%mm3\n\t" + "pcmpgtw %%mm2, %%mm1\n\t" + "pxor %%mm3, %%mm0\n" + "pxor %%mm1, %%mm2\n" + "psubw %%mm3, %%mm0\n" + "psubw %%mm1, %%mm2\n" + "paddw %%mm0, %%mm2\n" + "paddw %%mm2, %%mm6\n" + + "add %2,%0\n" + "subl $2, %%ecx\n" + " jnz 1b\n" + + "movq %%mm6, %%mm0\n" + "punpcklwd %%mm7,%%mm0\n" + "punpckhwd %%mm7,%%mm6\n" + "paddd %%mm0, %%mm6\n" + + "movq %%mm6,%%mm0\n" + "psrlq $32, %%mm6\n" + "paddd %%mm6,%%mm0\n" + "movd %%mm0,%1\n" + : "+r" (pix1), "=r"(tmp) + : "r" ((long)line_size) , "g" (h-2) + : "%ecx"); + return tmp; +} + +static int hf_noise16_mmx(uint8_t * pix1, int line_size, int h) { + int tmp; + uint8_t * pix= pix1; + asm volatile ( + "movl %3,%%ecx\n" + "pxor %%mm7,%%mm7\n" + "pxor %%mm6,%%mm6\n" + + "movq (%0),%%mm0\n" + "movq 1(%0),%%mm1\n" + "movq %%mm0, %%mm2\n" + "movq %%mm1, %%mm3\n" + "punpcklbw %%mm7,%%mm0\n" + "punpcklbw %%mm7,%%mm1\n" + "punpckhbw %%mm7,%%mm2\n" + "punpckhbw %%mm7,%%mm3\n" + "psubw %%mm1, %%mm0\n" + "psubw %%mm3, %%mm2\n" + + "add %2,%0\n" + + "movq (%0),%%mm4\n" + "movq 1(%0),%%mm1\n" + "movq %%mm4, %%mm5\n" + "movq %%mm1, %%mm3\n" + "punpcklbw %%mm7,%%mm4\n" + "punpcklbw %%mm7,%%mm1\n" + "punpckhbw %%mm7,%%mm5\n" + "punpckhbw %%mm7,%%mm3\n" + "psubw %%mm1, %%mm4\n" + "psubw %%mm3, %%mm5\n" + "psubw %%mm4, %%mm0\n" + "psubw %%mm5, %%mm2\n" + "pxor %%mm3, %%mm3\n" + "pxor %%mm1, %%mm1\n" + "pcmpgtw %%mm0, %%mm3\n\t" + "pcmpgtw %%mm2, %%mm1\n\t" + "pxor %%mm3, %%mm0\n" + "pxor %%mm1, %%mm2\n" + "psubw %%mm3, %%mm0\n" + "psubw %%mm1, %%mm2\n" + "paddw %%mm0, %%mm2\n" + "paddw %%mm2, %%mm6\n" + + "add %2,%0\n" + "1:\n" + + "movq (%0),%%mm0\n" + "movq 1(%0),%%mm1\n" + "movq %%mm0, %%mm2\n" + "movq %%mm1, %%mm3\n" + "punpcklbw %%mm7,%%mm0\n" + "punpcklbw %%mm7,%%mm1\n" + "punpckhbw %%mm7,%%mm2\n" + "punpckhbw %%mm7,%%mm3\n" + "psubw %%mm1, %%mm0\n" + "psubw %%mm3, %%mm2\n" + "psubw %%mm0, %%mm4\n" + "psubw %%mm2, %%mm5\n" + "pxor %%mm3, %%mm3\n" + "pxor %%mm1, %%mm1\n" + "pcmpgtw %%mm4, %%mm3\n\t" + "pcmpgtw %%mm5, %%mm1\n\t" + "pxor %%mm3, %%mm4\n" + "pxor %%mm1, %%mm5\n" + "psubw %%mm3, %%mm4\n" + "psubw %%mm1, %%mm5\n" + "paddw %%mm4, %%mm5\n" + "paddw %%mm5, %%mm6\n" + + "add %2,%0\n" + + "movq (%0),%%mm4\n" + "movq 1(%0),%%mm1\n" + "movq %%mm4, %%mm5\n" + "movq %%mm1, %%mm3\n" + "punpcklbw %%mm7,%%mm4\n" + "punpcklbw %%mm7,%%mm1\n" + "punpckhbw %%mm7,%%mm5\n" + "punpckhbw %%mm7,%%mm3\n" + "psubw %%mm1, %%mm4\n" + "psubw %%mm3, %%mm5\n" + "psubw %%mm4, %%mm0\n" + "psubw %%mm5, %%mm2\n" + "pxor %%mm3, %%mm3\n" + "pxor %%mm1, %%mm1\n" + "pcmpgtw %%mm0, %%mm3\n\t" + "pcmpgtw %%mm2, %%mm1\n\t" + "pxor %%mm3, %%mm0\n" + "pxor %%mm1, %%mm2\n" + "psubw %%mm3, %%mm0\n" + "psubw %%mm1, %%mm2\n" + "paddw %%mm0, %%mm2\n" + "paddw %%mm2, %%mm6\n" + + "add %2,%0\n" + "subl $2, %%ecx\n" + " jnz 1b\n" + + "movq %%mm6, %%mm0\n" + "punpcklwd %%mm7,%%mm0\n" + "punpckhwd %%mm7,%%mm6\n" + "paddd %%mm0, %%mm6\n" + + "movq %%mm6,%%mm0\n" + "psrlq $32, %%mm6\n" + "paddd %%mm6,%%mm0\n" + "movd %%mm0,%1\n" + : "+r" (pix1), "=r"(tmp) + : "r" ((long)line_size) , "g" (h-2) + : "%ecx"); + return tmp + hf_noise8_mmx(pix+8, line_size, h); +} + +static int nsse16_mmx(void *p, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + MpegEncContext *c = p; + int score1, score2; + + if(c) score1 = c->dsp.sse[0](c, pix1, pix2, line_size, h); + else score1 = sse16_mmx(c, pix1, pix2, line_size, h); + score2= hf_noise16_mmx(pix1, line_size, h) - hf_noise16_mmx(pix2, line_size, h); + + if(c) return score1 + FFABS(score2)*c->avctx->nsse_weight; + else return score1 + FFABS(score2)*8; +} + +static int nsse8_mmx(void *p, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + MpegEncContext *c = p; + int score1= sse8_mmx(c, pix1, pix2, line_size, h); + int score2= hf_noise8_mmx(pix1, line_size, h) - hf_noise8_mmx(pix2, line_size, h); + + if(c) return score1 + FFABS(score2)*c->avctx->nsse_weight; + else return score1 + FFABS(score2)*8; +} + +static int vsad_intra16_mmx(void *v, uint8_t * pix, uint8_t * dummy, int line_size, int h) { + int tmp; + + assert( (((int)pix) & 7) == 0); + assert((line_size &7) ==0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0), %%mm2\n"\ + "movq 8(%0), %%mm3\n"\ + "add %2,%0\n"\ + "movq %%mm2, " #out0 "\n"\ + "movq %%mm3, " #out1 "\n"\ + "psubusb " #in0 ", %%mm2\n"\ + "psubusb " #in1 ", %%mm3\n"\ + "psubusb " #out0 ", " #in0 "\n"\ + "psubusb " #out1 ", " #in1 "\n"\ + "por %%mm2, " #in0 "\n"\ + "por %%mm3, " #in1 "\n"\ + "movq " #in0 ", %%mm2\n"\ + "movq " #in1 ", %%mm3\n"\ + "punpcklbw %%mm7, " #in0 "\n"\ + "punpcklbw %%mm7, " #in1 "\n"\ + "punpckhbw %%mm7, %%mm2\n"\ + "punpckhbw %%mm7, %%mm3\n"\ + "paddw " #in1 ", " #in0 "\n"\ + "paddw %%mm3, %%mm2\n"\ + "paddw %%mm2, " #in0 "\n"\ + "paddw " #in0 ", %%mm6\n" + + + asm volatile ( + "movl %3,%%ecx\n" + "pxor %%mm6,%%mm6\n" + "pxor %%mm7,%%mm7\n" + "movq (%0),%%mm0\n" + "movq 8(%0),%%mm1\n" + "add %2,%0\n" + "subl $2, %%ecx\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movq %%mm6,%%mm0\n" + "psrlq $32, %%mm6\n" + "paddw %%mm6,%%mm0\n" + "movq %%mm0,%%mm6\n" + "psrlq $16, %%mm0\n" + "paddw %%mm6,%%mm0\n" + "movd %%mm0,%1\n" + : "+r" (pix), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp & 0xFFFF; +} +#undef SUM + +static int vsad_intra16_mmx2(void *v, uint8_t * pix, uint8_t * dummy, int line_size, int h) { + int tmp; + + assert( (((int)pix) & 7) == 0); + assert((line_size &7) ==0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0), " #out0 "\n"\ + "movq 8(%0), " #out1 "\n"\ + "add %2,%0\n"\ + "psadbw " #out0 ", " #in0 "\n"\ + "psadbw " #out1 ", " #in1 "\n"\ + "paddw " #in1 ", " #in0 "\n"\ + "paddw " #in0 ", %%mm6\n" + + asm volatile ( + "movl %3,%%ecx\n" + "pxor %%mm6,%%mm6\n" + "pxor %%mm7,%%mm7\n" + "movq (%0),%%mm0\n" + "movq 8(%0),%%mm1\n" + "add %2,%0\n" + "subl $2, %%ecx\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movd %%mm6,%1\n" + : "+r" (pix), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp; +} +#undef SUM + +static int vsad16_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + int tmp; + + assert( (((int)pix1) & 7) == 0); + assert( (((int)pix2) & 7) == 0); + assert((line_size &7) ==0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0),%%mm2\n"\ + "movq (%1)," #out0 "\n"\ + "movq 8(%0),%%mm3\n"\ + "movq 8(%1)," #out1 "\n"\ + "add %3,%0\n"\ + "add %3,%1\n"\ + "psubb " #out0 ", %%mm2\n"\ + "psubb " #out1 ", %%mm3\n"\ + "pxor %%mm7, %%mm2\n"\ + "pxor %%mm7, %%mm3\n"\ + "movq %%mm2, " #out0 "\n"\ + "movq %%mm3, " #out1 "\n"\ + "psubusb " #in0 ", %%mm2\n"\ + "psubusb " #in1 ", %%mm3\n"\ + "psubusb " #out0 ", " #in0 "\n"\ + "psubusb " #out1 ", " #in1 "\n"\ + "por %%mm2, " #in0 "\n"\ + "por %%mm3, " #in1 "\n"\ + "movq " #in0 ", %%mm2\n"\ + "movq " #in1 ", %%mm3\n"\ + "punpcklbw %%mm7, " #in0 "\n"\ + "punpcklbw %%mm7, " #in1 "\n"\ + "punpckhbw %%mm7, %%mm2\n"\ + "punpckhbw %%mm7, %%mm3\n"\ + "paddw " #in1 ", " #in0 "\n"\ + "paddw %%mm3, %%mm2\n"\ + "paddw %%mm2, " #in0 "\n"\ + "paddw " #in0 ", %%mm6\n" + + + asm volatile ( + "movl %4,%%ecx\n" + "pxor %%mm6,%%mm6\n" + "pcmpeqw %%mm7,%%mm7\n" + "psllw $15, %%mm7\n" + "packsswb %%mm7, %%mm7\n" + "movq (%0),%%mm0\n" + "movq (%1),%%mm2\n" + "movq 8(%0),%%mm1\n" + "movq 8(%1),%%mm3\n" + "add %3,%0\n" + "add %3,%1\n" + "subl $2, %%ecx\n" + "psubb %%mm2, %%mm0\n" + "psubb %%mm3, %%mm1\n" + "pxor %%mm7, %%mm0\n" + "pxor %%mm7, %%mm1\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movq %%mm6,%%mm0\n" + "psrlq $32, %%mm6\n" + "paddw %%mm6,%%mm0\n" + "movq %%mm0,%%mm6\n" + "psrlq $16, %%mm0\n" + "paddw %%mm6,%%mm0\n" + "movd %%mm0,%2\n" + : "+r" (pix1), "+r" (pix2), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp & 0x7FFF; +} +#undef SUM + +static int vsad16_mmx2(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + int tmp; + + assert( (((int)pix1) & 7) == 0); + assert( (((int)pix2) & 7) == 0); + assert((line_size &7) ==0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0)," #out0 "\n"\ + "movq (%1),%%mm2\n"\ + "movq 8(%0)," #out1 "\n"\ + "movq 8(%1),%%mm3\n"\ + "add %3,%0\n"\ + "add %3,%1\n"\ + "psubb %%mm2, " #out0 "\n"\ + "psubb %%mm3, " #out1 "\n"\ + "pxor %%mm7, " #out0 "\n"\ + "pxor %%mm7, " #out1 "\n"\ + "psadbw " #out0 ", " #in0 "\n"\ + "psadbw " #out1 ", " #in1 "\n"\ + "paddw " #in1 ", " #in0 "\n"\ + "paddw " #in0 ", %%mm6\n" + + asm volatile ( + "movl %4,%%ecx\n" + "pxor %%mm6,%%mm6\n" + "pcmpeqw %%mm7,%%mm7\n" + "psllw $15, %%mm7\n" + "packsswb %%mm7, %%mm7\n" + "movq (%0),%%mm0\n" + "movq (%1),%%mm2\n" + "movq 8(%0),%%mm1\n" + "movq 8(%1),%%mm3\n" + "add %3,%0\n" + "add %3,%1\n" + "subl $2, %%ecx\n" + "psubb %%mm2, %%mm0\n" + "psubb %%mm3, %%mm1\n" + "pxor %%mm7, %%mm0\n" + "pxor %%mm7, %%mm1\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movd %%mm6,%2\n" + : "+r" (pix1), "+r" (pix2), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp; +} +#undef SUM + +static void diff_bytes_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ + long i=0; + asm volatile( + "1: \n\t" + "movq (%2, %0), %%mm0 \n\t" + "movq (%1, %0), %%mm1 \n\t" + "psubb %%mm0, %%mm1 \n\t" + "movq %%mm1, (%3, %0) \n\t" + "movq 8(%2, %0), %%mm0 \n\t" + "movq 8(%1, %0), %%mm1 \n\t" + "psubb %%mm0, %%mm1 \n\t" + "movq %%mm1, 8(%3, %0) \n\t" + "add $16, %0 \n\t" + "cmp %4, %0 \n\t" + " jb 1b \n\t" + : "+r" (i) + : "r"(src1), "r"(src2), "r"(dst), "r"((long)w-15) + ); + for(; i<w; i++) + dst[i+0] = src1[i+0]-src2[i+0]; +} + +static void sub_hfyu_median_prediction_mmx2(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top){ + long i=0; + uint8_t l, lt; + + asm volatile( + "1: \n\t" + "movq -1(%1, %0), %%mm0 \n\t" // LT + "movq (%1, %0), %%mm1 \n\t" // T + "movq -1(%2, %0), %%mm2 \n\t" // L + "movq (%2, %0), %%mm3 \n\t" // X + "movq %%mm2, %%mm4 \n\t" // L + "psubb %%mm0, %%mm2 \n\t" + "paddb %%mm1, %%mm2 \n\t" // L + T - LT + "movq %%mm4, %%mm5 \n\t" // L + "pmaxub %%mm1, %%mm4 \n\t" // max(T, L) + "pminub %%mm5, %%mm1 \n\t" // min(T, L) + "pminub %%mm2, %%mm4 \n\t" + "pmaxub %%mm1, %%mm4 \n\t" + "psubb %%mm4, %%mm3 \n\t" // dst - pred + "movq %%mm3, (%3, %0) \n\t" + "add $8, %0 \n\t" + "cmp %4, %0 \n\t" + " jb 1b \n\t" + : "+r" (i) + : "r"(src1), "r"(src2), "r"(dst), "r"((long)w) + ); + + l= *left; + lt= *left_top; + + dst[0]= src2[0] - mid_pred(l, src1[0], (l + src1[0] - lt)&0xFF); + + *left_top= src1[w-1]; + *left = src2[w-1]; +} + +#define DIFF_PIXELS_1(m,a,t,p1,p2)\ + "mov"#m" "#p1", "#a" \n\t"\ + "mov"#m" "#p2", "#t" \n\t"\ + "punpcklbw "#a", "#t" \n\t"\ + "punpcklbw "#a", "#a" \n\t"\ + "psubw "#t", "#a" \n\t"\ + +#define DIFF_PIXELS_8(m0,m1,mm,p1,p2,stride,temp) {\ + uint8_t *p1b=p1, *p2b=p2;\ + asm volatile(\ + DIFF_PIXELS_1(m0, mm##0, mm##7, (%1), (%2))\ + DIFF_PIXELS_1(m0, mm##1, mm##7, (%1,%3), (%2,%3))\ + DIFF_PIXELS_1(m0, mm##2, mm##7, (%1,%3,2), (%2,%3,2))\ + "add %4, %1 \n\t"\ + "add %4, %2 \n\t"\ + DIFF_PIXELS_1(m0, mm##3, mm##7, (%1), (%2))\ + DIFF_PIXELS_1(m0, mm##4, mm##7, (%1,%3), (%2,%3))\ + DIFF_PIXELS_1(m0, mm##5, mm##7, (%1,%3,2), (%2,%3,2))\ + DIFF_PIXELS_1(m0, mm##6, mm##7, (%1,%4), (%2,%4))\ + "mov"#m1" "#mm"0, %0 \n\t"\ + DIFF_PIXELS_1(m0, mm##7, mm##0, (%1,%3,4), (%2,%3,4))\ + "mov"#m1" %0, "#mm"0 \n\t"\ + : "+m"(temp), "+r"(p1b), "+r"(p2b)\ + : "r"((long)stride), "r"((long)stride*3)\ + );\ +} + //the "+m"(temp) is needed as gcc 2.95 sometimes fails to compile "=m"(temp) + +#define DIFF_PIXELS_4x8(p1,p2,stride,temp) DIFF_PIXELS_8(d, q, %%mm, p1, p2, stride, temp) +#define DIFF_PIXELS_8x8(p1,p2,stride,temp) DIFF_PIXELS_8(q, dqa, %%xmm, p1, p2, stride, temp) + +#define LBUTTERFLY2(a1,b1,a2,b2)\ + "paddw " #b1 ", " #a1 " \n\t"\ + "paddw " #b2 ", " #a2 " \n\t"\ + "paddw " #b1 ", " #b1 " \n\t"\ + "paddw " #b2 ", " #b2 " \n\t"\ + "psubw " #a1 ", " #b1 " \n\t"\ + "psubw " #a2 ", " #b2 " \n\t" + +#define HADAMARD8(m0, m1, m2, m3, m4, m5, m6, m7)\ + LBUTTERFLY2(m0, m1, m2, m3)\ + LBUTTERFLY2(m4, m5, m6, m7)\ + LBUTTERFLY2(m0, m2, m1, m3)\ + LBUTTERFLY2(m4, m6, m5, m7)\ + LBUTTERFLY2(m0, m4, m1, m5)\ + LBUTTERFLY2(m2, m6, m3, m7)\ + +#define HADAMARD48 HADAMARD8(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm6, %%mm7) + +#define MMABS_MMX(a,z)\ + "pxor " #z ", " #z " \n\t"\ + "pcmpgtw " #a ", " #z " \n\t"\ + "pxor " #z ", " #a " \n\t"\ + "psubw " #z ", " #a " \n\t" + +#define MMABS_MMX2(a,z)\ + "pxor " #z ", " #z " \n\t"\ + "psubw " #a ", " #z " \n\t"\ + "pmaxsw " #z ", " #a " \n\t" + +#define MMABS_SSSE3(a,z)\ + "pabsw " #a ", " #a " \n\t" + +#define MMABS_SUM(a,z, sum)\ + MMABS(a,z)\ + "paddusw " #a ", " #sum " \n\t" + +#define MMABS_SUM_8x8_NOSPILL\ + MMABS(%%xmm0, %%xmm8)\ + MMABS(%%xmm1, %%xmm9)\ + MMABS_SUM(%%xmm2, %%xmm8, %%xmm0)\ + MMABS_SUM(%%xmm3, %%xmm9, %%xmm1)\ + MMABS_SUM(%%xmm4, %%xmm8, %%xmm0)\ + MMABS_SUM(%%xmm5, %%xmm9, %%xmm1)\ + MMABS_SUM(%%xmm6, %%xmm8, %%xmm0)\ + MMABS_SUM(%%xmm7, %%xmm9, %%xmm1)\ + "paddusw %%xmm1, %%xmm0 \n\t" + +#ifdef ARCH_X86_64 +#define MMABS_SUM_8x8_SSE2 MMABS_SUM_8x8_NOSPILL +#else +#define MMABS_SUM_8x8_SSE2\ + "movdqa %%xmm7, (%1) \n\t"\ + MMABS(%%xmm0, %%xmm7)\ + MMABS(%%xmm1, %%xmm7)\ + MMABS_SUM(%%xmm2, %%xmm7, %%xmm0)\ + MMABS_SUM(%%xmm3, %%xmm7, %%xmm1)\ + MMABS_SUM(%%xmm4, %%xmm7, %%xmm0)\ + MMABS_SUM(%%xmm5, %%xmm7, %%xmm1)\ + MMABS_SUM(%%xmm6, %%xmm7, %%xmm0)\ + "movdqa (%1), %%xmm2 \n\t"\ + MMABS_SUM(%%xmm2, %%xmm7, %%xmm1)\ + "paddusw %%xmm1, %%xmm0 \n\t" +#endif + +#define LOAD4(o, a, b, c, d)\ + "movq "#o"(%1), "#a" \n\t"\ + "movq "#o"+8(%1), "#b" \n\t"\ + "movq "#o"+16(%1), "#c" \n\t"\ + "movq "#o"+24(%1), "#d" \n\t"\ + +#define STORE4(o, a, b, c, d)\ + "movq "#a", "#o"(%1) \n\t"\ + "movq "#b", "#o"+8(%1) \n\t"\ + "movq "#c", "#o"+16(%1) \n\t"\ + "movq "#d", "#o"+24(%1) \n\t"\ + +/* FIXME: HSUM_* saturates at 64k, while an 8x8 hadamard or dct block can get up to + * about 100k on extreme inputs. But that's very unlikely to occur in natural video, + * and it's even more unlikely to not have any alternative mvs/modes with lower cost. */ +#define HSUM_MMX(a, t, dst)\ + "movq "#a", "#t" \n\t"\ + "psrlq $32, "#a" \n\t"\ + "paddusw "#t", "#a" \n\t"\ + "movq "#a", "#t" \n\t"\ + "psrlq $16, "#a" \n\t"\ + "paddusw "#t", "#a" \n\t"\ + "movd "#a", "#dst" \n\t"\ + +#define HSUM_MMX2(a, t, dst)\ + "pshufw $0x0E, "#a", "#t" \n\t"\ + "paddusw "#t", "#a" \n\t"\ + "pshufw $0x01, "#a", "#t" \n\t"\ + "paddusw "#t", "#a" \n\t"\ + "movd "#a", "#dst" \n\t"\ + +#define HSUM_SSE2(a, t, dst)\ + "movhlps "#a", "#t" \n\t"\ + "paddusw "#t", "#a" \n\t"\ + "pshuflw $0x0E, "#a", "#t" \n\t"\ + "paddusw "#t", "#a" \n\t"\ + "pshuflw $0x01, "#a", "#t" \n\t"\ + "paddusw "#t", "#a" \n\t"\ + "movd "#a", "#dst" \n\t"\ + +#define HADAMARD8_DIFF_MMX(cpu) \ +static int hadamard8_diff_##cpu(void *s, uint8_t *src1, uint8_t *src2, int stride, int h){\ + DECLARE_ALIGNED_8(uint64_t, temp[13]);\ + int sum;\ +\ + assert(h==8);\ +\ + DIFF_PIXELS_4x8(src1, src2, stride, temp[0]);\ +\ + asm volatile(\ + HADAMARD48\ +\ + "movq %%mm7, 96(%1) \n\t"\ +\ + TRANSPOSE4(%%mm0, %%mm1, %%mm2, %%mm3, %%mm7)\ + STORE4(0 , %%mm0, %%mm3, %%mm7, %%mm2)\ +\ + "movq 96(%1), %%mm7 \n\t"\ + TRANSPOSE4(%%mm4, %%mm5, %%mm6, %%mm7, %%mm0)\ + STORE4(64, %%mm4, %%mm7, %%mm0, %%mm6)\ +\ + : "=r" (sum)\ + : "r"(temp)\ + );\ +\ + DIFF_PIXELS_4x8(src1+4, src2+4, stride, temp[4]);\ +\ + asm volatile(\ + HADAMARD48\ +\ + "movq %%mm7, 96(%1) \n\t"\ +\ + TRANSPOSE4(%%mm0, %%mm1, %%mm2, %%mm3, %%mm7)\ + STORE4(32, %%mm0, %%mm3, %%mm7, %%mm2)\ +\ + "movq 96(%1), %%mm7 \n\t"\ + TRANSPOSE4(%%mm4, %%mm5, %%mm6, %%mm7, %%mm0)\ + "movq %%mm7, %%mm5 \n\t"/*FIXME remove*/\ + "movq %%mm6, %%mm7 \n\t"\ + "movq %%mm0, %%mm6 \n\t"\ +\ + LOAD4(64, %%mm0, %%mm1, %%mm2, %%mm3)\ +\ + HADAMARD48\ + "movq %%mm7, 64(%1) \n\t"\ + MMABS(%%mm0, %%mm7)\ + MMABS(%%mm1, %%mm7)\ + MMABS_SUM(%%mm2, %%mm7, %%mm0)\ + MMABS_SUM(%%mm3, %%mm7, %%mm1)\ + MMABS_SUM(%%mm4, %%mm7, %%mm0)\ + MMABS_SUM(%%mm5, %%mm7, %%mm1)\ + MMABS_SUM(%%mm6, %%mm7, %%mm0)\ + "movq 64(%1), %%mm2 \n\t"\ + MMABS_SUM(%%mm2, %%mm7, %%mm1)\ + "paddusw %%mm1, %%mm0 \n\t"\ + "movq %%mm0, 64(%1) \n\t"\ +\ + LOAD4(0 , %%mm0, %%mm1, %%mm2, %%mm3)\ + LOAD4(32, %%mm4, %%mm5, %%mm6, %%mm7)\ +\ + HADAMARD48\ + "movq %%mm7, (%1) \n\t"\ + MMABS(%%mm0, %%mm7)\ + MMABS(%%mm1, %%mm7)\ + MMABS_SUM(%%mm2, %%mm7, %%mm0)\ + MMABS_SUM(%%mm3, %%mm7, %%mm1)\ + MMABS_SUM(%%mm4, %%mm7, %%mm0)\ + MMABS_SUM(%%mm5, %%mm7, %%mm1)\ + MMABS_SUM(%%mm6, %%mm7, %%mm0)\ + "movq (%1), %%mm2 \n\t"\ + MMABS_SUM(%%mm2, %%mm7, %%mm1)\ + "paddusw 64(%1), %%mm0 \n\t"\ + "paddusw %%mm1, %%mm0 \n\t"\ +\ + HSUM(%%mm0, %%mm1, %0)\ +\ + : "=r" (sum)\ + : "r"(temp)\ + );\ + return sum&0xFFFF;\ +}\ +WRAPPER8_16_SQ(hadamard8_diff_##cpu, hadamard8_diff16_##cpu) + +#define HADAMARD8_DIFF_SSE2(cpu) \ +static int hadamard8_diff_##cpu(void *s, uint8_t *src1, uint8_t *src2, int stride, int h){\ + DECLARE_ALIGNED_16(uint64_t, temp[4]);\ + int sum;\ +\ + assert(h==8);\ +\ + DIFF_PIXELS_8x8(src1, src2, stride, temp[0]);\ +\ + asm volatile(\ + HADAMARD8(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm6, %%xmm7)\ + TRANSPOSE8(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm6, %%xmm7, (%1))\ + HADAMARD8(%%xmm0, %%xmm5, %%xmm7, %%xmm3, %%xmm6, %%xmm4, %%xmm2, %%xmm1)\ + MMABS_SUM_8x8\ + HSUM_SSE2(%%xmm0, %%xmm1, %0)\ + : "=r" (sum)\ + : "r"(temp)\ + );\ + return sum&0xFFFF;\ +}\ +WRAPPER8_16_SQ(hadamard8_diff_##cpu, hadamard8_diff16_##cpu) + +#define MMABS(a,z) MMABS_MMX(a,z) +#define HSUM(a,t,dst) HSUM_MMX(a,t,dst) +HADAMARD8_DIFF_MMX(mmx) +#undef MMABS +#undef HSUM + +#define MMABS(a,z) MMABS_MMX2(a,z) +#define MMABS_SUM_8x8 MMABS_SUM_8x8_SSE2 +#define HSUM(a,t,dst) HSUM_MMX2(a,t,dst) +HADAMARD8_DIFF_MMX(mmx2) +HADAMARD8_DIFF_SSE2(sse2) +#undef MMABS +#undef MMABS_SUM_8x8 +#undef HSUM + +#ifdef HAVE_SSSE3 +#define MMABS(a,z) MMABS_SSSE3(a,z) +#define MMABS_SUM_8x8 MMABS_SUM_8x8_NOSPILL +HADAMARD8_DIFF_SSE2(ssse3) +#undef MMABS +#undef MMABS_SUM_8x8 +#endif + +#define DCT_SAD4(m,mm,o)\ + "mov"#m" "#o"+ 0(%1), "#mm"2 \n\t"\ + "mov"#m" "#o"+16(%1), "#mm"3 \n\t"\ + "mov"#m" "#o"+32(%1), "#mm"4 \n\t"\ + "mov"#m" "#o"+48(%1), "#mm"5 \n\t"\ + MMABS_SUM(mm##2, mm##6, mm##0)\ + MMABS_SUM(mm##3, mm##7, mm##1)\ + MMABS_SUM(mm##4, mm##6, mm##0)\ + MMABS_SUM(mm##5, mm##7, mm##1)\ + +#define DCT_SAD_MMX\ + "pxor %%mm0, %%mm0 \n\t"\ + "pxor %%mm1, %%mm1 \n\t"\ + DCT_SAD4(q, %%mm, 0)\ + DCT_SAD4(q, %%mm, 8)\ + DCT_SAD4(q, %%mm, 64)\ + DCT_SAD4(q, %%mm, 72)\ + "paddusw %%mm1, %%mm0 \n\t"\ + HSUM(%%mm0, %%mm1, %0) + +#define DCT_SAD_SSE2\ + "pxor %%xmm0, %%xmm0 \n\t"\ + "pxor %%xmm1, %%xmm1 \n\t"\ + DCT_SAD4(dqa, %%xmm, 0)\ + DCT_SAD4(dqa, %%xmm, 64)\ + "paddusw %%xmm1, %%xmm0 \n\t"\ + HSUM(%%xmm0, %%xmm1, %0) + +#define DCT_SAD_FUNC(cpu) \ +static int sum_abs_dctelem_##cpu(DCTELEM *block){\ + int sum;\ + asm volatile(\ + DCT_SAD\ + :"=r"(sum)\ + :"r"(block)\ + );\ + return sum&0xFFFF;\ +} + +#define DCT_SAD DCT_SAD_MMX +#define HSUM(a,t,dst) HSUM_MMX(a,t,dst) +#define MMABS(a,z) MMABS_MMX(a,z) +DCT_SAD_FUNC(mmx) +#undef MMABS +#undef HSUM + +#define HSUM(a,t,dst) HSUM_MMX2(a,t,dst) +#define MMABS(a,z) MMABS_MMX2(a,z) +DCT_SAD_FUNC(mmx2) +#undef HSUM +#undef DCT_SAD + +#define DCT_SAD DCT_SAD_SSE2 +#define HSUM(a,t,dst) HSUM_SSE2(a,t,dst) +DCT_SAD_FUNC(sse2) +#undef MMABS + +#ifdef HAVE_SSSE3 +#define MMABS(a,z) MMABS_SSSE3(a,z) +DCT_SAD_FUNC(ssse3) +#undef MMABS +#endif +#undef HSUM +#undef DCT_SAD + +static int ssd_int8_vs_int16_mmx(const int8_t *pix1, const int16_t *pix2, int size){ + int sum; + long i=size; + asm volatile( + "pxor %%mm4, %%mm4 \n" + "1: \n" + "sub $8, %0 \n" + "movq (%2,%0), %%mm2 \n" + "movq (%3,%0,2), %%mm0 \n" + "movq 8(%3,%0,2), %%mm1 \n" + "punpckhbw %%mm2, %%mm3 \n" + "punpcklbw %%mm2, %%mm2 \n" + "psraw $8, %%mm3 \n" + "psraw $8, %%mm2 \n" + "psubw %%mm3, %%mm1 \n" + "psubw %%mm2, %%mm0 \n" + "pmaddwd %%mm1, %%mm1 \n" + "pmaddwd %%mm0, %%mm0 \n" + "paddd %%mm1, %%mm4 \n" + "paddd %%mm0, %%mm4 \n" + "jg 1b \n" + "movq %%mm4, %%mm3 \n" + "psrlq $32, %%mm3 \n" + "paddd %%mm3, %%mm4 \n" + "movd %%mm4, %1 \n" + :"+r"(i), "=r"(sum) + :"r"(pix1), "r"(pix2) + ); + return sum; +} + +#define PHADDD(a, t)\ + "movq "#a", "#t" \n\t"\ + "psrlq $32, "#a" \n\t"\ + "paddd "#t", "#a" \n\t" +/* + pmulhw: dst[0-15]=(src[0-15]*dst[0-15])[16-31] + pmulhrw: dst[0-15]=(src[0-15]*dst[0-15] + 0x8000)[16-31] + pmulhrsw: dst[0-15]=(src[0-15]*dst[0-15] + 0x4000)[15-30] + */ +#define PMULHRW(x, y, s, o)\ + "pmulhw " #s ", "#x " \n\t"\ + "pmulhw " #s ", "#y " \n\t"\ + "paddw " #o ", "#x " \n\t"\ + "paddw " #o ", "#y " \n\t"\ + "psraw $1, "#x " \n\t"\ + "psraw $1, "#y " \n\t" +#define DEF(x) x ## _mmx +#define SET_RND MOVQ_WONE +#define SCALE_OFFSET 1 + +#include "dsputil_mmx_qns.h" + +#undef DEF +#undef SET_RND +#undef SCALE_OFFSET +#undef PMULHRW + +#define DEF(x) x ## _3dnow +#define SET_RND(x) +#define SCALE_OFFSET 0 +#define PMULHRW(x, y, s, o)\ + "pmulhrw " #s ", "#x " \n\t"\ + "pmulhrw " #s ", "#y " \n\t" + +#include "dsputil_mmx_qns.h" + +#undef DEF +#undef SET_RND +#undef SCALE_OFFSET +#undef PMULHRW + +#ifdef HAVE_SSSE3 +#undef PHADDD +#define DEF(x) x ## _ssse3 +#define SET_RND(x) +#define SCALE_OFFSET -1 +#define PHADDD(a, t)\ + "pshufw $0x0E, "#a", "#t" \n\t"\ + "paddd "#t", "#a" \n\t" /* faster than phaddd on core2 */ +#define PMULHRW(x, y, s, o)\ + "pmulhrsw " #s ", "#x " \n\t"\ + "pmulhrsw " #s ", "#y " \n\t" + +#include "dsputil_mmx_qns.h" + +#undef DEF +#undef SET_RND +#undef SCALE_OFFSET +#undef PMULHRW +#undef PHADDD +#endif //HAVE_SSSE3 + + +/* FLAC specific */ +void ff_flac_compute_autocorr_sse2(const int32_t *data, int len, int lag, + double *autoc); + + +void dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx) +{ + if (mm_flags & MM_MMX) { + const int dct_algo = avctx->dct_algo; + if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){ + if(mm_flags & MM_SSE2){ + c->fdct = ff_fdct_sse2; + }else if(mm_flags & MM_MMXEXT){ + c->fdct = ff_fdct_mmx2; + }else{ + c->fdct = ff_fdct_mmx; + } + } + + c->get_pixels = get_pixels_mmx; + c->diff_pixels = diff_pixels_mmx; + c->pix_sum = pix_sum16_mmx; + + c->diff_bytes= diff_bytes_mmx; + c->sum_abs_dctelem= sum_abs_dctelem_mmx; + + c->hadamard8_diff[0]= hadamard8_diff16_mmx; + c->hadamard8_diff[1]= hadamard8_diff_mmx; + + c->pix_norm1 = pix_norm1_mmx; + c->sse[0] = (mm_flags & MM_SSE2) ? sse16_sse2 : sse16_mmx; + c->sse[1] = sse8_mmx; + c->vsad[4]= vsad_intra16_mmx; + + c->nsse[0] = nsse16_mmx; + c->nsse[1] = nsse8_mmx; + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->vsad[0] = vsad16_mmx; + } + + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->try_8x8basis= try_8x8basis_mmx; + } + c->add_8x8basis= add_8x8basis_mmx; + + c->ssd_int8_vs_int16 = ssd_int8_vs_int16_mmx; + + + if (mm_flags & MM_MMXEXT) { + c->sum_abs_dctelem= sum_abs_dctelem_mmx2; + c->hadamard8_diff[0]= hadamard8_diff16_mmx2; + c->hadamard8_diff[1]= hadamard8_diff_mmx2; + c->vsad[4]= vsad_intra16_mmx2; + + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->vsad[0] = vsad16_mmx2; + } + + c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_mmx2; + } + + if(mm_flags & MM_SSE2){ + c->sum_abs_dctelem= sum_abs_dctelem_sse2; + c->hadamard8_diff[0]= hadamard8_diff16_sse2; + c->hadamard8_diff[1]= hadamard8_diff_sse2; + if (ENABLE_FLAC_ENCODER) + c->flac_compute_autocorr = ff_flac_compute_autocorr_sse2; + } + +#ifdef HAVE_SSSE3 + if(mm_flags & MM_SSSE3){ + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->try_8x8basis= try_8x8basis_ssse3; + } + c->add_8x8basis= add_8x8basis_ssse3; + c->sum_abs_dctelem= sum_abs_dctelem_ssse3; + c->hadamard8_diff[0]= hadamard8_diff16_ssse3; + c->hadamard8_diff[1]= hadamard8_diff_ssse3; + } +#endif + + if(mm_flags & MM_3DNOW){ + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->try_8x8basis= try_8x8basis_3dnow; + } + c->add_8x8basis= add_8x8basis_3dnow; + } + } + + dsputil_init_pix_mmx(c, avctx); +} diff --git a/contrib/ffmpeg/libavcodec/i386/fdct_mmx.c b/contrib/ffmpeg/libavcodec/i386/fdct_mmx.c index 7e2682a4a..f93c3c937 100644 --- a/contrib/ffmpeg/libavcodec/i386/fdct_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/fdct_mmx.c @@ -30,7 +30,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "common.h" -#include "../dsputil.h" +#include "dsputil.h" #include "mmx.h" #define ATTR_ALIGN(align) __attribute__ ((__aligned__ (align))) @@ -52,18 +52,20 @@ #define RND_FRW_ROW (1 << (SHIFT_FRW_ROW-1)) //#define RND_FRW_COL (1 << (SHIFT_FRW_COL-1)) +#define X8(x) x,x,x,x,x,x,x,x + //concatenated table, for forward DCT transformation -static const int16_t fdct_tg_all_16[] ATTR_ALIGN(8) = { - 13036, 13036, 13036, 13036, // tg * (2<<16) + 0.5 - 27146, 27146, 27146, 27146, // tg * (2<<16) + 0.5 - -21746, -21746, -21746, -21746, // tg * (2<<16) + 0.5 +static const int16_t fdct_tg_all_16[24] ATTR_ALIGN(16) = { + X8(13036), // tg * (2<<16) + 0.5 + X8(27146), // tg * (2<<16) + 0.5 + X8(-21746) // tg * (2<<16) + 0.5 }; -static const int16_t ocos_4_16[4] ATTR_ALIGN(8) = { - 23170, 23170, 23170, 23170, //cos * (2<<15) + 0.5 +static const int16_t ocos_4_16[8] ATTR_ALIGN(16) = { + X8(23170) //cos * (2<<15) + 0.5 }; -static const int64_t fdct_one_corr ATTR_ALIGN(8) = 0x0001000100010001LL; +static const int16_t fdct_one_corr[8] ATTR_ALIGN(16) = { X8(1) }; static const int32_t fdct_r_row[2] ATTR_ALIGN(8) = {RND_FRW_ROW, RND_FRW_ROW }; @@ -283,86 +285,88 @@ TABLE_SSE2 TABLE_SSE2 }}; - -static av_always_inline void fdct_col(const int16_t *in, int16_t *out, int offset) -{ - movq_m2r(*(in + offset + 1 * 8), mm0); - movq_m2r(*(in + offset + 6 * 8), mm1); - movq_r2r(mm0, mm2); - movq_m2r(*(in + offset + 2 * 8), mm3); - paddsw_r2r(mm1, mm0); - movq_m2r(*(in + offset + 5 * 8), mm4); - psllw_i2r(SHIFT_FRW_COL, mm0); - movq_m2r(*(in + offset + 0 * 8), mm5); - paddsw_r2r(mm3, mm4); - paddsw_m2r(*(in + offset + 7 * 8), mm5); - psllw_i2r(SHIFT_FRW_COL, mm4); - movq_r2r(mm0, mm6); - psubsw_r2r(mm1, mm2); - movq_m2r(*(fdct_tg_all_16 + 4), mm1); - psubsw_r2r(mm4, mm0); - movq_m2r(*(in + offset + 3 * 8), mm7); - pmulhw_r2r(mm0, mm1); - paddsw_m2r(*(in + offset + 4 * 8), mm7); - psllw_i2r(SHIFT_FRW_COL, mm5); - paddsw_r2r(mm4, mm6); - psllw_i2r(SHIFT_FRW_COL, mm7); - movq_r2r(mm5, mm4); - psubsw_r2r(mm7, mm5); - paddsw_r2r(mm5, mm1); - paddsw_r2r(mm7, mm4); - por_m2r(fdct_one_corr, mm1); - psllw_i2r(SHIFT_FRW_COL + 1, mm2); - pmulhw_m2r(*(fdct_tg_all_16 + 4), mm5); - movq_r2r(mm4, mm7); - psubsw_m2r(*(in + offset + 5 * 8), mm3); - psubsw_r2r(mm6, mm4); - movq_r2m(mm1, *(out + offset + 2 * 8)); - paddsw_r2r(mm6, mm7); - movq_m2r(*(in + offset + 3 * 8), mm1); - psllw_i2r(SHIFT_FRW_COL + 1, mm3); - psubsw_m2r(*(in + offset + 4 * 8), mm1); - movq_r2r(mm2, mm6); - movq_r2m(mm4, *(out + offset + 4 * 8)); - paddsw_r2r(mm3, mm2); - pmulhw_m2r(*ocos_4_16, mm2); - psubsw_r2r(mm3, mm6); - pmulhw_m2r(*ocos_4_16, mm6); - psubsw_r2r(mm0, mm5); - por_m2r(fdct_one_corr, mm5); - psllw_i2r(SHIFT_FRW_COL, mm1); - por_m2r(fdct_one_corr, mm2); - movq_r2r(mm1, mm4); - movq_m2r(*(in + offset + 0 * 8), mm3); - paddsw_r2r(mm6, mm1); - psubsw_m2r(*(in + offset + 7 * 8), mm3); - psubsw_r2r(mm6, mm4); - movq_m2r(*(fdct_tg_all_16 + 0), mm0); - psllw_i2r(SHIFT_FRW_COL, mm3); - movq_m2r(*(fdct_tg_all_16 + 8), mm6); - pmulhw_r2r(mm1, mm0); - movq_r2m(mm7, *(out + offset + 0 * 8)); - pmulhw_r2r(mm4, mm6); - movq_r2m(mm5, *(out + offset + 6 * 8)); - movq_r2r(mm3, mm7); - movq_m2r(*(fdct_tg_all_16 + 8), mm5); - psubsw_r2r(mm2, mm7); - paddsw_r2r(mm2, mm3); - pmulhw_r2r(mm7, mm5); - paddsw_r2r(mm3, mm0); - paddsw_r2r(mm4, mm6); - pmulhw_m2r(*(fdct_tg_all_16 + 0), mm3); - por_m2r(fdct_one_corr, mm0); - paddsw_r2r(mm7, mm5); - psubsw_r2r(mm6, mm7); - movq_r2m(mm0, *(out + offset + 1 * 8)); - paddsw_r2r(mm4, mm5); - movq_r2m(mm7, *(out + offset + 3 * 8)); - psubsw_r2r(mm1, mm3); - movq_r2m(mm5, *(out + offset + 5 * 8)); - movq_r2m(mm3, *(out + offset + 7 * 8)); +#define FDCT_COL(cpu, mm, mov)\ +static av_always_inline void fdct_col_##cpu(const int16_t *in, int16_t *out, int offset)\ +{\ + mov##_m2r(*(in + offset + 1 * 8), mm##0);\ + mov##_m2r(*(in + offset + 6 * 8), mm##1);\ + mov##_r2r(mm##0, mm##2);\ + mov##_m2r(*(in + offset + 2 * 8), mm##3);\ + paddsw_r2r(mm##1, mm##0);\ + mov##_m2r(*(in + offset + 5 * 8), mm##4);\ + psllw_i2r(SHIFT_FRW_COL, mm##0);\ + mov##_m2r(*(in + offset + 0 * 8), mm##5);\ + paddsw_r2r(mm##3, mm##4);\ + paddsw_m2r(*(in + offset + 7 * 8), mm##5);\ + psllw_i2r(SHIFT_FRW_COL, mm##4);\ + mov##_r2r(mm##0, mm##6);\ + psubsw_r2r(mm##1, mm##2);\ + mov##_m2r(*(fdct_tg_all_16 + 8), mm##1);\ + psubsw_r2r(mm##4, mm##0);\ + mov##_m2r(*(in + offset + 3 * 8), mm##7);\ + pmulhw_r2r(mm##0, mm##1);\ + paddsw_m2r(*(in + offset + 4 * 8), mm##7);\ + psllw_i2r(SHIFT_FRW_COL, mm##5);\ + paddsw_r2r(mm##4, mm##6);\ + psllw_i2r(SHIFT_FRW_COL, mm##7);\ + mov##_r2r(mm##5, mm##4);\ + psubsw_r2r(mm##7, mm##5);\ + paddsw_r2r(mm##5, mm##1);\ + paddsw_r2r(mm##7, mm##4);\ + por_m2r(*fdct_one_corr, mm##1);\ + psllw_i2r(SHIFT_FRW_COL + 1, mm##2);\ + pmulhw_m2r(*(fdct_tg_all_16 + 8), mm##5);\ + mov##_r2r(mm##4, mm##7);\ + psubsw_m2r(*(in + offset + 5 * 8), mm##3);\ + psubsw_r2r(mm##6, mm##4);\ + mov##_r2m(mm##1, *(out + offset + 2 * 8));\ + paddsw_r2r(mm##6, mm##7);\ + mov##_m2r(*(in + offset + 3 * 8), mm##1);\ + psllw_i2r(SHIFT_FRW_COL + 1, mm##3);\ + psubsw_m2r(*(in + offset + 4 * 8), mm##1);\ + mov##_r2r(mm##2, mm##6);\ + mov##_r2m(mm##4, *(out + offset + 4 * 8));\ + paddsw_r2r(mm##3, mm##2);\ + pmulhw_m2r(*ocos_4_16, mm##2);\ + psubsw_r2r(mm##3, mm##6);\ + pmulhw_m2r(*ocos_4_16, mm##6);\ + psubsw_r2r(mm##0, mm##5);\ + por_m2r(*fdct_one_corr, mm##5);\ + psllw_i2r(SHIFT_FRW_COL, mm##1);\ + por_m2r(*fdct_one_corr, mm##2);\ + mov##_r2r(mm##1, mm##4);\ + mov##_m2r(*(in + offset + 0 * 8), mm##3);\ + paddsw_r2r(mm##6, mm##1);\ + psubsw_m2r(*(in + offset + 7 * 8), mm##3);\ + psubsw_r2r(mm##6, mm##4);\ + mov##_m2r(*(fdct_tg_all_16 + 0), mm##0);\ + psllw_i2r(SHIFT_FRW_COL, mm##3);\ + mov##_m2r(*(fdct_tg_all_16 + 16), mm##6);\ + pmulhw_r2r(mm##1, mm##0);\ + mov##_r2m(mm##7, *(out + offset + 0 * 8));\ + pmulhw_r2r(mm##4, mm##6);\ + mov##_r2m(mm##5, *(out + offset + 6 * 8));\ + mov##_r2r(mm##3, mm##7);\ + mov##_m2r(*(fdct_tg_all_16 + 16), mm##5);\ + psubsw_r2r(mm##2, mm##7);\ + paddsw_r2r(mm##2, mm##3);\ + pmulhw_r2r(mm##7, mm##5);\ + paddsw_r2r(mm##3, mm##0);\ + paddsw_r2r(mm##4, mm##6);\ + pmulhw_m2r(*(fdct_tg_all_16 + 0), mm##3);\ + por_m2r(*fdct_one_corr, mm##0);\ + paddsw_r2r(mm##7, mm##5);\ + psubsw_r2r(mm##6, mm##7);\ + mov##_r2m(mm##0, *(out + offset + 1 * 8));\ + paddsw_r2r(mm##4, mm##5);\ + mov##_r2m(mm##7, *(out + offset + 3 * 8));\ + psubsw_r2r(mm##1, mm##3);\ + mov##_r2m(mm##5, *(out + offset + 5 * 8));\ + mov##_r2m(mm##3, *(out + offset + 7 * 8));\ } +FDCT_COL(mmx, mm, movq) +FDCT_COL(sse2, xmm, movdqa) static av_always_inline void fdct_row_sse2(const int16_t *in, int16_t *out) { @@ -471,7 +475,7 @@ static av_always_inline void fdct_row_mmx2(const int16_t *in, int16_t *out, cons static av_always_inline void fdct_row_mmx(const int16_t *in, int16_t *out, const int16_t *table) { -//FIXME reorder (i dont have a old mmx only cpu here to benchmark ...) +//FIXME reorder (I do not have an old MMX-only CPU here to benchmark ...) movd_m2r(*(in + 6), mm1); punpcklwd_m2r(*(in + 4), mm1); movq_r2r(mm1, mm2); @@ -524,8 +528,8 @@ void ff_fdct_mmx(int16_t *block) const int16_t *table= tab_frw_01234567; int i; - fdct_col(block, block1, 0); - fdct_col(block, block1, 4); + fdct_col_mmx(block, block1, 0); + fdct_col_mmx(block, block1, 4); for(i=8;i>0;i--) { fdct_row_mmx(block1, block, table); @@ -542,8 +546,8 @@ void ff_fdct_mmx2(int16_t *block) const int16_t *table= tab_frw_01234567; int i; - fdct_col(block, block1, 0); - fdct_col(block, block1, 4); + fdct_col_mmx(block, block1, 0); + fdct_col_mmx(block, block1, 4); for(i=8;i>0;i--) { fdct_row_mmx2(block1, block, table); @@ -558,9 +562,7 @@ void ff_fdct_sse2(int16_t *block) int64_t align_tmp[16] ATTR_ALIGN(16); int16_t * const block1= (int16_t*)align_tmp; - fdct_col(block, block1, 0); - fdct_col(block, block1, 4); - + fdct_col_sse2(block, block1, 0); fdct_row_sse2(block1, block); } diff --git a/contrib/ffmpeg/libavcodec/i386/fft_3dn.c b/contrib/ffmpeg/libavcodec/i386/fft_3dn.c index 8087f1932..4231d855a 100644 --- a/contrib/ffmpeg/libavcodec/i386/fft_3dn.c +++ b/contrib/ffmpeg/libavcodec/i386/fft_3dn.c @@ -19,7 +19,7 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" static const int p1m1[2] __attribute__((aligned(8))) = { 0, 1 << 31 }; diff --git a/contrib/ffmpeg/libavcodec/i386/fft_3dn2.c b/contrib/ffmpeg/libavcodec/i386/fft_3dn2.c index a4fe5f0b6..6d063321d 100644 --- a/contrib/ffmpeg/libavcodec/i386/fft_3dn2.c +++ b/contrib/ffmpeg/libavcodec/i386/fft_3dn2.c @@ -19,7 +19,7 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" static const int p1m1[2] __attribute__((aligned(8))) = { 0, 1 << 31 }; diff --git a/contrib/ffmpeg/libavcodec/i386/fft_sse.c b/contrib/ffmpeg/libavcodec/i386/fft_sse.c index 0dc0c61c1..39e64c700 100644 --- a/contrib/ffmpeg/libavcodec/i386/fft_sse.c +++ b/contrib/ffmpeg/libavcodec/i386/fft_sse.c @@ -18,7 +18,7 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" static const int p1p1p1m1[4] __attribute__((aligned(16))) = { 0, 0, 0, 1 << 31 }; @@ -100,20 +100,33 @@ void ff_fft_calc_sse(FFTContext *s, FFTComplex *z) i = nloops*8; asm volatile( "1: \n\t" - "sub $16, %0 \n\t" + "sub $32, %0 \n\t" "movaps (%2,%0), %%xmm1 \n\t" "movaps (%1,%0), %%xmm0 \n\t" + "movaps 16(%2,%0), %%xmm5 \n\t" + "movaps 16(%1,%0), %%xmm4 \n\t" "movaps %%xmm1, %%xmm2 \n\t" + "movaps %%xmm5, %%xmm6 \n\t" "shufps $0xA0, %%xmm1, %%xmm1 \n\t" "shufps $0xF5, %%xmm2, %%xmm2 \n\t" + "shufps $0xA0, %%xmm5, %%xmm5 \n\t" + "shufps $0xF5, %%xmm6, %%xmm6 \n\t" "mulps (%3,%0,2), %%xmm1 \n\t" // cre*re cim*re "mulps 16(%3,%0,2), %%xmm2 \n\t" // -cim*im cre*im + "mulps 32(%3,%0,2), %%xmm5 \n\t" // cre*re cim*re + "mulps 48(%3,%0,2), %%xmm6 \n\t" // -cim*im cre*im "addps %%xmm2, %%xmm1 \n\t" + "addps %%xmm6, %%xmm5 \n\t" "movaps %%xmm0, %%xmm3 \n\t" + "movaps %%xmm4, %%xmm7 \n\t" "addps %%xmm1, %%xmm0 \n\t" "subps %%xmm1, %%xmm3 \n\t" + "addps %%xmm5, %%xmm4 \n\t" + "subps %%xmm5, %%xmm7 \n\t" "movaps %%xmm0, (%1,%0) \n\t" "movaps %%xmm3, (%2,%0) \n\t" + "movaps %%xmm4, 16(%1,%0) \n\t" + "movaps %%xmm7, 16(%2,%0) \n\t" "jg 1b \n\t" :"+r"(i) :"r"(p), "r"(p + nloops), "r"(cptr) @@ -141,67 +154,106 @@ void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, n4 = n >> 2; n8 = n >> 3; - asm volatile ("movaps %0, %%xmm7\n\t"::"m"(*p1m1p1m1)); +#ifdef ARCH_X86_64 + asm volatile ("movaps %0, %%xmm8\n\t"::"m"(*p1m1p1m1)); +#define P1M1P1M1 "%%xmm8" +#else +#define P1M1P1M1 "%4" +#endif /* pre rotation */ in1 = input; in2 = input + n2 - 4; - /* Complex multiplication - Two complex products per iteration, we could have 4 with 8 xmm - registers, 8 with 16 xmm registers. - Maybe we should unroll more. - */ - for (k = 0; k < n4; k += 2) { + /* Complex multiplication */ + for (k = 0; k < n4; k += 4) { asm volatile ( "movaps %0, %%xmm0 \n\t" // xmm0 = r0 X r1 X : in2 "movaps %1, %%xmm3 \n\t" // xmm3 = X i1 X i0: in1 + "movaps -16+1*%0, %%xmm4 \n\t" // xmm4 = r0 X r1 X : in2 + "movaps 16+1*%1, %%xmm7 \n\t" // xmm7 = X i1 X i0: in1 "movlps %2, %%xmm1 \n\t" // xmm1 = X X R1 R0: tcos "movlps %3, %%xmm2 \n\t" // xmm2 = X X I1 I0: tsin + "movlps 8+1*%2, %%xmm5 \n\t" // xmm5 = X X R1 R0: tcos + "movlps 8+1*%3, %%xmm6 \n\t" // xmm6 = X X I1 I0: tsin "shufps $95, %%xmm0, %%xmm0 \n\t" // xmm0 = r1 r1 r0 r0 "shufps $160,%%xmm3, %%xmm3 \n\t" // xmm3 = i1 i1 i0 i0 + "shufps $95, %%xmm4, %%xmm4 \n\t" // xmm4 = r1 r1 r0 r0 + "shufps $160,%%xmm7, %%xmm7 \n\t" // xmm7 = i1 i1 i0 i0 "unpcklps %%xmm2, %%xmm1 \n\t" // xmm1 = I1 R1 I0 R0 + "unpcklps %%xmm6, %%xmm5 \n\t" // xmm5 = I1 R1 I0 R0 "movaps %%xmm1, %%xmm2 \n\t" // xmm2 = I1 R1 I0 R0 - "xorps %%xmm7, %%xmm2 \n\t" // xmm2 = -I1 R1 -I0 R0 + "movaps %%xmm5, %%xmm6 \n\t" // xmm6 = I1 R1 I0 R0 + "xorps "P1M1P1M1", %%xmm2 \n\t" // xmm2 = -I1 R1 -I0 R0 + "xorps "P1M1P1M1", %%xmm6 \n\t" // xmm6 = -I1 R1 -I0 R0 "mulps %%xmm1, %%xmm0 \n\t" // xmm0 = rI rR rI rR + "mulps %%xmm5, %%xmm4 \n\t" // xmm4 = rI rR rI rR "shufps $177,%%xmm2, %%xmm2 \n\t" // xmm2 = R1 -I1 R0 -I0 + "shufps $177,%%xmm6, %%xmm6 \n\t" // xmm6 = R1 -I1 R0 -I0 "mulps %%xmm2, %%xmm3 \n\t" // xmm3 = Ri -Ii Ri -Ii + "mulps %%xmm6, %%xmm7 \n\t" // xmm7 = Ri -Ii Ri -Ii "addps %%xmm3, %%xmm0 \n\t" // xmm0 = result + "addps %%xmm7, %%xmm4 \n\t" // xmm4 = result ::"m"(in2[-2*k]), "m"(in1[2*k]), "m"(tcos[k]), "m"(tsin[k]) +#ifndef ARCH_X86_64 + ,"m"(*p1m1p1m1) +#endif ); /* Should be in the same block, hack for gcc2.95 & gcc3 */ asm ( "movlps %%xmm0, %0 \n\t" "movhps %%xmm0, %1 \n\t" - :"=m"(z[revtab[k]]), "=m"(z[revtab[k + 1]]) + "movlps %%xmm4, %2 \n\t" + "movhps %%xmm4, %3 \n\t" + :"=m"(z[revtab[k]]), "=m"(z[revtab[k + 1]]), + "=m"(z[revtab[k + 2]]), "=m"(z[revtab[k + 3]]) ); } ff_fft_calc_sse(&s->fft, z); - /* Not currently needed, added for safety */ - asm volatile ("movaps %0, %%xmm7\n\t"::"m"(*p1m1p1m1)); +#ifndef ARCH_X86_64 +#undef P1M1P1M1 +#define P1M1P1M1 "%3" +#endif /* post rotation + reordering */ - for (k = 0; k < n4; k += 2) { + for (k = 0; k < n4; k += 4) { asm ( "movaps %0, %%xmm0 \n\t" // xmm0 = i1 r1 i0 r0: z + "movaps 16+1*%0, %%xmm4 \n\t" // xmm4 = i1 r1 i0 r0: z "movlps %1, %%xmm1 \n\t" // xmm1 = X X R1 R0: tcos + "movlps 8+1*%1, %%xmm5 \n\t" // xmm5 = X X R1 R0: tcos "movaps %%xmm0, %%xmm3 \n\t" // xmm3 = i1 r1 i0 r0 + "movaps %%xmm4, %%xmm7 \n\t" // xmm7 = i1 r1 i0 r0 "movlps %2, %%xmm2 \n\t" // xmm2 = X X I1 I0: tsin + "movlps 8+1*%2, %%xmm6 \n\t" // xmm6 = X X I1 I0: tsin "shufps $160,%%xmm0, %%xmm0 \n\t" // xmm0 = r1 r1 r0 r0 "shufps $245,%%xmm3, %%xmm3 \n\t" // xmm3 = i1 i1 i0 i0 + "shufps $160,%%xmm4, %%xmm4 \n\t" // xmm4 = r1 r1 r0 r0 + "shufps $245,%%xmm7, %%xmm7 \n\t" // xmm7 = i1 i1 i0 i0 "unpcklps %%xmm2, %%xmm1 \n\t" // xmm1 = I1 R1 I0 R0 + "unpcklps %%xmm6, %%xmm5 \n\t" // xmm5 = I1 R1 I0 R0 "movaps %%xmm1, %%xmm2 \n\t" // xmm2 = I1 R1 I0 R0 - "xorps %%xmm7, %%xmm2 \n\t" // xmm2 = -I1 R1 -I0 R0 + "movaps %%xmm5, %%xmm6 \n\t" // xmm6 = I1 R1 I0 R0 + "xorps "P1M1P1M1", %%xmm2 \n\t" // xmm2 = -I1 R1 -I0 R0 "mulps %%xmm1, %%xmm0 \n\t" // xmm0 = rI rR rI rR + "xorps "P1M1P1M1", %%xmm6 \n\t" // xmm6 = -I1 R1 -I0 R0 + "mulps %%xmm5, %%xmm4 \n\t" // xmm4 = rI rR rI rR "shufps $177,%%xmm2, %%xmm2 \n\t" // xmm2 = R1 -I1 R0 -I0 + "shufps $177,%%xmm6, %%xmm6 \n\t" // xmm6 = R1 -I1 R0 -I0 "mulps %%xmm2, %%xmm3 \n\t" // xmm3 = Ri -Ii Ri -Ii + "mulps %%xmm6, %%xmm7 \n\t" // xmm7 = Ri -Ii Ri -Ii "addps %%xmm3, %%xmm0 \n\t" // xmm0 = result + "addps %%xmm7, %%xmm4 \n\t" // xmm4 = result "movaps %%xmm0, %0 \n\t" + "movaps %%xmm4, 16+1*%0\n\t" :"+m"(z[k]) :"m"(tcos[k]), "m"(tsin[k]) +#ifndef ARCH_X86_64 + ,"m"(*p1m1p1m1) +#endif ); } diff --git a/contrib/ffmpeg/libavcodec/i386/flacdsp_mmx.c b/contrib/ffmpeg/libavcodec/i386/flacdsp_mmx.c new file mode 100644 index 000000000..e799ce421 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/i386/flacdsp_mmx.c @@ -0,0 +1,138 @@ +/* + * MMX optimized FLAC DSP utils + * Copyright (c) 2007 Loren Merritt + * + * 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 "dsputil_mmx.h" + +static void apply_welch_window_sse2(const int32_t *data, int len, double *w_data) +{ + double c = 2.0 / (len-1.0); + int n2 = len>>1; + long i = -n2*sizeof(int32_t); + long j = n2*sizeof(int32_t); + asm volatile( + "movsd %0, %%xmm7 \n\t" + "movapd %1, %%xmm6 \n\t" + "movapd %2, %%xmm5 \n\t" + "movlhps %%xmm7, %%xmm7 \n\t" + "subpd %%xmm5, %%xmm7 \n\t" + "addsd %%xmm6, %%xmm7 \n\t" + ::"m"(c), "m"(*ff_pd_1), "m"(*ff_pd_2) + ); +#define WELCH(MOVPD, offset)\ + asm volatile(\ + "1: \n\t"\ + "movapd %%xmm7, %%xmm1 \n\t"\ + "mulpd %%xmm1, %%xmm1 \n\t"\ + "movapd %%xmm6, %%xmm0 \n\t"\ + "subpd %%xmm1, %%xmm0 \n\t"\ + "pshufd $0x4e, %%xmm0, %%xmm1 \n\t"\ + "cvtpi2pd (%3,%0), %%xmm2 \n\t"\ + "cvtpi2pd "#offset"*4(%3,%1), %%xmm3 \n\t"\ + "mulpd %%xmm0, %%xmm2 \n\t"\ + "mulpd %%xmm1, %%xmm3 \n\t"\ + "movapd %%xmm2, (%2,%0,2) \n\t"\ + MOVPD" %%xmm3, "#offset"*8(%2,%1,2) \n\t"\ + "subpd %%xmm5, %%xmm7 \n\t"\ + "sub $8, %1 \n\t"\ + "add $8, %0 \n\t"\ + "jl 1b \n\t"\ + :"+&r"(i), "+&r"(j)\ + :"r"(w_data+n2), "r"(data+n2)\ + ); + if(len&1) + WELCH("movupd", -1) + else + WELCH("movapd", -2) +#undef WELCH +} + +void ff_flac_compute_autocorr_sse2(const int32_t *data, int len, int lag, + double *autoc) +{ + double tmp[len + lag + 2]; + double *data1 = tmp + lag; + int j; + + if((long)data1 & 15) + data1++; + + apply_welch_window_sse2(data, len, data1); + + for(j=0; j<lag; j++) + data1[j-lag]= 0.0; + data1[len] = 0.0; + + for(j=0; j<lag; j+=2){ + long i = -len*sizeof(double); + if(j == lag-2) { + asm volatile( + "movsd %6, %%xmm0 \n\t" + "movsd %6, %%xmm1 \n\t" + "movsd %6, %%xmm2 \n\t" + "1: \n\t" + "movapd (%4,%0), %%xmm3 \n\t" + "movupd -8(%5,%0), %%xmm4 \n\t" + "movapd (%5,%0), %%xmm5 \n\t" + "mulpd %%xmm3, %%xmm4 \n\t" + "mulpd %%xmm3, %%xmm5 \n\t" + "mulpd -16(%5,%0), %%xmm3 \n\t" + "addpd %%xmm4, %%xmm1 \n\t" + "addpd %%xmm5, %%xmm0 \n\t" + "addpd %%xmm3, %%xmm2 \n\t" + "add $16, %0 \n\t" + "jl 1b \n\t" + "movhlps %%xmm0, %%xmm3 \n\t" + "movhlps %%xmm1, %%xmm4 \n\t" + "movhlps %%xmm2, %%xmm5 \n\t" + "addsd %%xmm3, %%xmm0 \n\t" + "addsd %%xmm4, %%xmm1 \n\t" + "addsd %%xmm5, %%xmm2 \n\t" + "movsd %%xmm0, %1 \n\t" + "movsd %%xmm1, %2 \n\t" + "movsd %%xmm2, %3 \n\t" + :"+&r"(i), "=m"(autoc[j]), "=m"(autoc[j+1]), "=m"(autoc[j+2]) + :"r"(data1+len), "r"(data1+len-j), "m"(*ff_pd_1) + ); + } else { + asm volatile( + "movsd %5, %%xmm0 \n\t" + "movsd %5, %%xmm1 \n\t" + "1: \n\t" + "movapd (%3,%0), %%xmm3 \n\t" + "movupd -8(%4,%0), %%xmm4 \n\t" + "mulpd %%xmm3, %%xmm4 \n\t" + "mulpd (%4,%0), %%xmm3 \n\t" + "addpd %%xmm4, %%xmm1 \n\t" + "addpd %%xmm3, %%xmm0 \n\t" + "add $16, %0 \n\t" + "jl 1b \n\t" + "movhlps %%xmm0, %%xmm3 \n\t" + "movhlps %%xmm1, %%xmm4 \n\t" + "addsd %%xmm3, %%xmm0 \n\t" + "addsd %%xmm4, %%xmm1 \n\t" + "movsd %%xmm0, %1 \n\t" + "movsd %%xmm1, %2 \n\t" + :"+&r"(i), "=m"(autoc[j]), "=m"(autoc[j+1]) + :"r"(data1+len), "r"(data1+len-j), "m"(*ff_pd_1) + ); + } + } +} diff --git a/contrib/ffmpeg/libavcodec/i386/h264dsp_mmx.c b/contrib/ffmpeg/libavcodec/i386/h264dsp_mmx.c index 56004b674..7f5c5a95b 100644 --- a/contrib/ffmpeg/libavcodec/i386/h264dsp_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/h264dsp_mmx.c @@ -18,16 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "dsputil_mmx.h" /***********************************/ /* IDCT */ -/* in/out: mma=mma+mmb, mmb=mmb-mma */ -#define SUMSUB_BA( a, b ) \ - "paddw "#b", "#a" \n\t"\ - "paddw "#b", "#b" \n\t"\ - "psubw "#a", "#b" \n\t" - #define SUMSUB_BADC( a, b, c, d ) \ "paddw "#b", "#a" \n\t"\ "paddw "#d", "#c" \n\t"\ @@ -48,12 +43,6 @@ SUMSUBD2_AB( s13, d13, t )\ SUMSUB_BADC( d13, s02, s13, d02 ) -#define TRANSPOSE4(a,b,c,d,t)\ - SBUTTERFLY(a,b,t,wd) /* a=aebf t=cgdh */\ - SBUTTERFLY(c,d,b,wd) /* c=imjn b=kolp */\ - SBUTTERFLY(a,c,d,dq) /* a=aeim d=bfjn */\ - SBUTTERFLY(t,b,c,dq) /* t=cgko c=dhlp */ - #define STORE_DIFF_4P( p, t, z ) \ "psraw $6, "#p" \n\t"\ "movd (%0), "#t" \n\t"\ @@ -105,44 +94,38 @@ static inline void h264_idct8_1d(int16_t *block) { asm volatile( "movq 112(%0), %%mm7 \n\t" - "movq 80(%0), %%mm5 \n\t" + "movq 80(%0), %%mm0 \n\t" "movq 48(%0), %%mm3 \n\t" - "movq 16(%0), %%mm1 \n\t" + "movq 16(%0), %%mm5 \n\t" - "movq %%mm7, %%mm4 \n\t" - "movq %%mm3, %%mm6 \n\t" - "movq %%mm5, %%mm0 \n\t" - "movq %%mm7, %%mm2 \n\t" + "movq %%mm0, %%mm4 \n\t" + "movq %%mm5, %%mm1 \n\t" "psraw $1, %%mm4 \n\t" - "psraw $1, %%mm6 \n\t" - "psubw %%mm7, %%mm0 \n\t" - "psubw %%mm6, %%mm2 \n\t" - "psubw %%mm4, %%mm0 \n\t" - "psubw %%mm3, %%mm2 \n\t" - "psubw %%mm3, %%mm0 \n\t" - "paddw %%mm1, %%mm2 \n\t" - - "movq %%mm5, %%mm4 \n\t" - "movq %%mm1, %%mm6 \n\t" - "psraw $1, %%mm4 \n\t" - "psraw $1, %%mm6 \n\t" - "paddw %%mm5, %%mm4 \n\t" - "paddw %%mm1, %%mm6 \n\t" + "psraw $1, %%mm1 \n\t" + "paddw %%mm0, %%mm4 \n\t" + "paddw %%mm5, %%mm1 \n\t" "paddw %%mm7, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "psubw %%mm1, %%mm4 \n\t" - "paddw %%mm3, %%mm6 \n\t" + "paddw %%mm0, %%mm1 \n\t" + "psubw %%mm5, %%mm4 \n\t" + "paddw %%mm3, %%mm1 \n\t" + + "psubw %%mm3, %%mm5 \n\t" + "psubw %%mm3, %%mm0 \n\t" + "paddw %%mm7, %%mm5 \n\t" + "psubw %%mm7, %%mm0 \n\t" + "psraw $1, %%mm3 \n\t" + "psraw $1, %%mm7 \n\t" + "psubw %%mm3, %%mm5 \n\t" + "psubw %%mm7, %%mm0 \n\t" - "movq %%mm0, %%mm1 \n\t" "movq %%mm4, %%mm3 \n\t" - "movq %%mm2, %%mm5 \n\t" - "movq %%mm6, %%mm7 \n\t" - "psraw $2, %%mm6 \n\t" + "movq %%mm1, %%mm7 \n\t" + "psraw $2, %%mm1 \n\t" "psraw $2, %%mm3 \n\t" + "paddw %%mm5, %%mm3 \n\t" "psraw $2, %%mm5 \n\t" + "paddw %%mm0, %%mm1 \n\t" "psraw $2, %%mm0 \n\t" - "paddw %%mm6, %%mm1 \n\t" - "paddw %%mm2, %%mm3 \n\t" "psubw %%mm4, %%mm5 \n\t" "psubw %%mm0, %%mm7 \n\t" @@ -228,6 +211,93 @@ static void ff_h264_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride) add_pixels_clamped_mmx(b2, dst, stride); } +#define STORE_DIFF_8P( p, d, t, z )\ + "movq "#d", "#t" \n"\ + "psraw $6, "#p" \n"\ + "punpcklbw "#z", "#t" \n"\ + "paddsw "#t", "#p" \n"\ + "packuswb "#p", "#p" \n"\ + "movq "#p", "#d" \n" + +#define H264_IDCT8_1D_SSE2(a,b,c,d,e,f,g,h)\ + "movdqa "#c", "#a" \n"\ + "movdqa "#g", "#e" \n"\ + "psraw $1, "#c" \n"\ + "psraw $1, "#g" \n"\ + "psubw "#e", "#c" \n"\ + "paddw "#a", "#g" \n"\ + "movdqa "#b", "#e" \n"\ + "psraw $1, "#e" \n"\ + "paddw "#b", "#e" \n"\ + "paddw "#d", "#e" \n"\ + "paddw "#f", "#e" \n"\ + "movdqa "#f", "#a" \n"\ + "psraw $1, "#a" \n"\ + "paddw "#f", "#a" \n"\ + "paddw "#h", "#a" \n"\ + "psubw "#b", "#a" \n"\ + "psubw "#d", "#b" \n"\ + "psubw "#d", "#f" \n"\ + "paddw "#h", "#b" \n"\ + "psubw "#h", "#f" \n"\ + "psraw $1, "#d" \n"\ + "psraw $1, "#h" \n"\ + "psubw "#d", "#b" \n"\ + "psubw "#h", "#f" \n"\ + "movdqa "#e", "#d" \n"\ + "movdqa "#a", "#h" \n"\ + "psraw $2, "#d" \n"\ + "psraw $2, "#h" \n"\ + "paddw "#f", "#d" \n"\ + "paddw "#b", "#h" \n"\ + "psraw $2, "#f" \n"\ + "psraw $2, "#b" \n"\ + "psubw "#f", "#e" \n"\ + "psubw "#a", "#b" \n"\ + "movdqa 0x00(%1), "#a" \n"\ + "movdqa 0x40(%1), "#f" \n"\ + SUMSUB_BA(f, a)\ + SUMSUB_BA(g, f)\ + SUMSUB_BA(c, a)\ + SUMSUB_BA(e, g)\ + SUMSUB_BA(b, c)\ + SUMSUB_BA(h, a)\ + SUMSUB_BA(d, f) + +static void ff_h264_idct8_add_sse2(uint8_t *dst, int16_t *block, int stride) +{ + asm volatile( + "movdqa 0x10(%1), %%xmm1 \n" + "movdqa 0x20(%1), %%xmm2 \n" + "movdqa 0x30(%1), %%xmm3 \n" + "movdqa 0x50(%1), %%xmm5 \n" + "movdqa 0x60(%1), %%xmm6 \n" + "movdqa 0x70(%1), %%xmm7 \n" + H264_IDCT8_1D_SSE2(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm6, %%xmm7) + TRANSPOSE8(%%xmm4, %%xmm1, %%xmm7, %%xmm3, %%xmm5, %%xmm0, %%xmm2, %%xmm6, (%1)) + "paddw %4, %%xmm4 \n" + "movdqa %%xmm4, 0x00(%1) \n" + "movdqa %%xmm2, 0x40(%1) \n" + H264_IDCT8_1D_SSE2(%%xmm4, %%xmm0, %%xmm6, %%xmm3, %%xmm2, %%xmm5, %%xmm7, %%xmm1) + "movdqa %%xmm6, 0x60(%1) \n" + "movdqa %%xmm7, 0x70(%1) \n" + "pxor %%xmm7, %%xmm7 \n" + STORE_DIFF_8P(%%xmm2, (%0), %%xmm6, %%xmm7) + STORE_DIFF_8P(%%xmm0, (%0,%2), %%xmm6, %%xmm7) + STORE_DIFF_8P(%%xmm1, (%0,%2,2), %%xmm6, %%xmm7) + STORE_DIFF_8P(%%xmm3, (%0,%3), %%xmm6, %%xmm7) + "lea (%0,%2,4), %0 \n" + STORE_DIFF_8P(%%xmm5, (%0), %%xmm6, %%xmm7) + STORE_DIFF_8P(%%xmm4, (%0,%2), %%xmm6, %%xmm7) + "movdqa 0x60(%1), %%xmm0 \n" + "movdqa 0x70(%1), %%xmm1 \n" + STORE_DIFF_8P(%%xmm0, (%0,%2,2), %%xmm6, %%xmm7) + STORE_DIFF_8P(%%xmm1, (%0,%3), %%xmm6, %%xmm7) + :"+r"(dst) + :"r"(block), "r"((long)stride), "r"(3L*stride), "m"(ff_pw_32) + ); +} + static void ff_h264_idct_dc_add_mmx2(uint8_t *dst, int16_t *block, int stride) { int dc = (block[0] + 32) >> 6; @@ -369,8 +439,8 @@ static void ff_h264_idct8_dc_add_mmx2(uint8_t *dst, int16_t *block, int stride) "paddusb %%mm3 , %%mm1 \n\t"\ "paddusb %%mm6 , %%mm2 \n\t" -// in: mm0=p1 mm1=p0 mm2=q0 mm3=q1 mm7=(tc&mask) %8=mm_bone -// out: (q1addr) = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 ) +// in: mm0=p1 mm1=p0 mm2=q0 mm3=q1 mm7=(tc&mask) %8=ff_bone +// out: (q1addr) = av_clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 ) // clobbers: q2, tmp, tc0 #define H264_DEBLOCK_Q1(p1, q2, q2addr, q1addr, tc0, tmp)\ "movq %%mm1, "#tmp" \n\t"\ @@ -435,7 +505,7 @@ static inline void h264_loop_filter_luma_mmx2(uint8_t *pix, int stride, int alph : "=m"(*tmp0) : "r"(pix-3*stride), "r"(pix), "r"((long)stride), "m"(*tmp0/*unused*/), "m"(*(uint32_t*)tc0), "m"(alpha1), "m"(beta1), - "m"(mm_bone) + "m"(ff_bone) ); } @@ -482,7 +552,7 @@ static inline void h264_loop_filter_chroma_mmx2(uint8_t *pix, int stride, int al :: "r"(pix-2*stride), "r"(pix), "r"((long)stride), "r"(*(uint32_t*)tc0), - "m"(alpha1), "m"(beta1), "m"(mm_bone), "m"(ff_pb_3F) + "m"(alpha1), "m"(beta1), "m"(ff_bone), "m"(ff_pb_3F) ); } @@ -532,7 +602,7 @@ static inline void h264_loop_filter_chroma_intra_mmx2(uint8_t *pix, int stride, "movq %%mm1, (%0,%2) \n\t" "movq %%mm2, (%1) \n\t" :: "r"(pix-2*stride), "r"(pix), "r"((long)stride), - "m"(alpha1), "m"(beta1), "m"(mm_bone) + "m"(alpha1), "m"(beta1), "m"(ff_bone) ); } @@ -651,37 +721,44 @@ static void h264_loop_filter_strength_mmx2( int16_t bS[2][4][4], uint8_t nnz[40] /***********************************/ /* motion compensation */ -#define QPEL_H264V(A,B,C,D,E,F,OP)\ - "movd (%0), "#F" \n\t"\ - "movq "#C", %%mm6 \n\t"\ - "paddw "#D", %%mm6 \n\t"\ - "psllw $2, %%mm6 \n\t"\ - "psubw "#B", %%mm6 \n\t"\ - "psubw "#E", %%mm6 \n\t"\ - "pmullw %4, %%mm6 \n\t"\ - "add %2, %0 \n\t"\ - "punpcklbw %%mm7, "#F" \n\t"\ +#define QPEL_H264V_MM(A,B,C,D,E,F,OP,T,Z,d,q)\ + "mov"#q" "#C", "#T" \n\t"\ + "mov"#d" (%0), "#F" \n\t"\ + "paddw "#D", "#T" \n\t"\ + "psllw $2, "#T" \n\t"\ + "psubw "#B", "#T" \n\t"\ + "psubw "#E", "#T" \n\t"\ + "punpcklbw "#Z", "#F" \n\t"\ + "pmullw %4, "#T" \n\t"\ "paddw %5, "#A" \n\t"\ + "add %2, %0 \n\t"\ "paddw "#F", "#A" \n\t"\ - "paddw "#A", %%mm6 \n\t"\ - "psraw $5, %%mm6 \n\t"\ - "packuswb %%mm6, %%mm6 \n\t"\ - OP(%%mm6, (%1), A, d)\ + "paddw "#A", "#T" \n\t"\ + "psraw $5, "#T" \n\t"\ + "packuswb "#T", "#T" \n\t"\ + OP(T, (%1), A, d)\ "add %3, %1 \n\t" -#define QPEL_H264HV(A,B,C,D,E,F,OF)\ - "movd (%0), "#F" \n\t"\ - "movq "#C", %%mm6 \n\t"\ - "paddw "#D", %%mm6 \n\t"\ - "psllw $2, %%mm6 \n\t"\ - "psubw "#B", %%mm6 \n\t"\ - "psubw "#E", %%mm6 \n\t"\ - "pmullw %3, %%mm6 \n\t"\ - "add %2, %0 \n\t"\ - "punpcklbw %%mm7, "#F" \n\t"\ +#define QPEL_H264HV_MM(A,B,C,D,E,F,OF,T,Z,d,q)\ + "mov"#q" "#C", "#T" \n\t"\ + "mov"#d" (%0), "#F" \n\t"\ + "paddw "#D", "#T" \n\t"\ + "psllw $2, "#T" \n\t"\ + "paddw %4, "#A" \n\t"\ + "psubw "#B", "#T" \n\t"\ + "psubw "#E", "#T" \n\t"\ + "punpcklbw "#Z", "#F" \n\t"\ + "pmullw %3, "#T" \n\t"\ "paddw "#F", "#A" \n\t"\ - "paddw "#A", %%mm6 \n\t"\ - "movq %%mm6, "#OF"(%1) \n\t" + "add %2, %0 \n\t"\ + "paddw "#A", "#T" \n\t"\ + "mov"#q" "#T", "#OF"(%1) \n\t" + +#define QPEL_H264V(A,B,C,D,E,F,OP) QPEL_H264V_MM(A,B,C,D,E,F,OP,%%mm6,%%mm7,d,q) +#define QPEL_H264HV(A,B,C,D,E,F,OF) QPEL_H264HV_MM(A,B,C,D,E,F,OF,%%mm6,%%mm7,d,q) +#define QPEL_H264V_XMM(A,B,C,D,E,F,OP) QPEL_H264V_MM(A,B,C,D,E,F,OP,%%xmm6,%%xmm7,q,dqa) +#define QPEL_H264HV_XMM(A,B,C,D,E,F,OF) QPEL_H264HV_MM(A,B,C,D,E,F,OF,%%xmm6,%%xmm7,q,dqa) + #define QPEL_H264(OPNAME, OP, MMX)\ static av_noinline void OPNAME ## h264_qpel4_h_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ @@ -719,7 +796,7 @@ static av_noinline void OPNAME ## h264_qpel4_h_lowpass_ ## MMX(uint8_t *dst, uin "add %4, %1 \n\t"\ "decl %2 \n\t"\ " jnz 1b \n\t"\ - : "+a"(src), "+c"(dst), "+m"(h)\ + : "+a"(src), "+c"(dst), "+g"(h)\ : "d"((long)srcStride), "S"((long)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ : "memory"\ );\ @@ -825,7 +902,7 @@ static av_noinline void OPNAME ## h264_qpel4_hv_lowpass_ ## MMX(uint8_t *dst, in QPEL_H264HV(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, 3*8*3)\ \ : "+a"(src)\ - : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5)\ + : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5), "m"(ff_pw_16)\ : "memory"\ );\ tmp += 4;\ @@ -833,7 +910,6 @@ static av_noinline void OPNAME ## h264_qpel4_hv_lowpass_ ## MMX(uint8_t *dst, in }\ tmp -= 3*4;\ asm volatile(\ - "movq %4, %%mm6 \n\t"\ "1: \n\t"\ "movq (%0), %%mm0 \n\t"\ "paddw 10(%0), %%mm0 \n\t"\ @@ -846,8 +922,7 @@ static av_noinline void OPNAME ## h264_qpel4_hv_lowpass_ ## MMX(uint8_t *dst, in "psubw %%mm1, %%mm0 \n\t"/*(a-b)/4-b */\ "paddsw %%mm2, %%mm0 \n\t"\ "psraw $2, %%mm0 \n\t"/*((a-b)/4-b+c)/4 */\ - "paddw %%mm6, %%mm2 \n\t"\ - "paddw %%mm2, %%mm0 \n\t"/*(a-5*b+20*c)/16 +32 */\ + "paddw %%mm2, %%mm0 \n\t"/*(a-5*b+20*c)/16 */\ "psraw $6, %%mm0 \n\t"\ "packuswb %%mm0, %%mm0 \n\t"\ OP(%%mm0, (%1),%%mm7, d)\ @@ -855,8 +930,8 @@ static av_noinline void OPNAME ## h264_qpel4_hv_lowpass_ ## MMX(uint8_t *dst, in "add %3, %1 \n\t"\ "decl %2 \n\t"\ " jnz 1b \n\t"\ - : "+a"(tmp), "+c"(dst), "+m"(h)\ - : "S"((long)dstStride), "m"(ff_pw_32)\ + : "+a"(tmp), "+c"(dst), "+g"(h)\ + : "S"((long)dstStride)\ : "memory"\ );\ }\ @@ -912,7 +987,7 @@ static av_noinline void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uin "add %4, %1 \n\t"\ "decl %2 \n\t"\ " jnz 1b \n\t"\ - : "+a"(src), "+c"(dst), "+m"(h)\ + : "+a"(src), "+c"(dst), "+g"(h)\ : "d"((long)srcStride), "S"((long)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ : "memory"\ );\ @@ -1036,8 +1111,7 @@ static av_noinline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst, dst += 4-h*dstStride;\ }\ }\ -static av_noinline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ - int h = size;\ +static av_always_inline void OPNAME ## h264_qpel8or16_hv1_lowpass_ ## MMX(int16_t *tmp, uint8_t *src, int tmpStride, int srcStride, int size){\ int w = (size+8)>>2;\ src -= 2*srcStride+2;\ while(w--){\ @@ -1067,7 +1141,7 @@ static av_noinline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst QPEL_H264HV(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, 6*48)\ QPEL_H264HV(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, 7*48)\ : "+a"(src)\ - : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5)\ + : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5), "m"(ff_pw_16)\ : "memory"\ );\ if(size==16){\ @@ -1081,19 +1155,19 @@ static av_noinline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst QPEL_H264HV(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, 14*48)\ QPEL_H264HV(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, 15*48)\ : "+a"(src)\ - : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5)\ + : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5), "m"(ff_pw_16)\ : "memory"\ );\ }\ tmp += 4;\ src += 4 - (size+5)*srcStride;\ }\ - tmp -= size+8;\ - w = size>>4;\ +}\ +static av_always_inline void OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, int dstStride, int tmpStride, int size){\ + int w = size>>4;\ do{\ - h = size;\ + int h = size;\ asm volatile(\ - "movq %4, %%mm6 \n\t"\ "1: \n\t"\ "movq (%0), %%mm0 \n\t"\ "movq 8(%0), %%mm3 \n\t"\ @@ -1117,8 +1191,6 @@ static av_noinline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst "paddsw %%mm5, %%mm3 \n\t"\ "psraw $2, %%mm0 \n\t"\ "psraw $2, %%mm3 \n\t"\ - "paddw %%mm6, %%mm2 \n\t"\ - "paddw %%mm6, %%mm5 \n\t"\ "paddw %%mm2, %%mm0 \n\t"\ "paddw %%mm5, %%mm3 \n\t"\ "psraw $6, %%mm0 \n\t"\ @@ -1129,8 +1201,8 @@ static av_noinline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst "add %3, %1 \n\t"\ "decl %2 \n\t"\ " jnz 1b \n\t"\ - : "+a"(tmp), "+c"(dst), "+m"(h)\ - : "S"((long)dstStride), "m"(ff_pw_32)\ + : "+a"(tmp), "+c"(dst), "+g"(h)\ + : "S"((long)dstStride)\ : "memory"\ );\ tmp += 8 - size*24;\ @@ -1146,7 +1218,7 @@ static av_noinline void OPNAME ## h264_qpel16_v_lowpass_ ## MMX(uint8_t *dst, ui OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ }\ \ -static av_noinline void OPNAME ## h264_qpel16_h_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ +static void OPNAME ## h264_qpel16_h_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ src += 8*srcStride;\ @@ -1165,6 +1237,10 @@ static av_noinline void OPNAME ## h264_qpel16_h_lowpass_l2_ ## MMX(uint8_t *dst, OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ }\ \ +static av_noinline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ + put_h264_qpel8or16_hv1_lowpass_ ## MMX(tmp, src, tmpStride, srcStride, size);\ + OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\ +}\ static void OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst , tmp , src , dstStride, tmpStride, srcStride, 8);\ }\ @@ -1176,11 +1252,8 @@ static void OPNAME ## h264_qpel16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, static av_noinline void OPNAME ## pixels4_l2_shift5_ ## MMX(uint8_t *dst, int16_t *src16, uint8_t *src8, int dstStride, int src8Stride, int h)\ {\ asm volatile(\ - "movq %5, %%mm6 \n\t"\ "movq (%1), %%mm0 \n\t"\ "movq 24(%1), %%mm1 \n\t"\ - "paddw %%mm6, %%mm0 \n\t"\ - "paddw %%mm6, %%mm1 \n\t"\ "psraw $5, %%mm0 \n\t"\ "psraw $5, %%mm1 \n\t"\ "packuswb %%mm0, %%mm0 \n\t"\ @@ -1193,8 +1266,6 @@ static av_noinline void OPNAME ## pixels4_l2_shift5_ ## MMX(uint8_t *dst, int16_ "lea (%2,%4,2), %2 \n\t"\ "movq 48(%1), %%mm0 \n\t"\ "movq 72(%1), %%mm1 \n\t"\ - "paddw %%mm6, %%mm0 \n\t"\ - "paddw %%mm6, %%mm1 \n\t"\ "psraw $5, %%mm0 \n\t"\ "psraw $5, %%mm1 \n\t"\ "packuswb %%mm0, %%mm0 \n\t"\ @@ -1204,32 +1275,34 @@ static av_noinline void OPNAME ## pixels4_l2_shift5_ ## MMX(uint8_t *dst, int16_ OP(%%mm0, (%2), %%mm4, d)\ OP(%%mm1, (%2,%4), %%mm5, d)\ :"+a"(src8), "+c"(src16), "+d"(dst)\ - :"S"((long)src8Stride), "D"((long)dstStride), "m"(ff_pw_16)\ + :"S"((long)src8Stride), "D"((long)dstStride)\ :"memory");\ }\ static av_noinline void OPNAME ## pixels8_l2_shift5_ ## MMX(uint8_t *dst, int16_t *src16, uint8_t *src8, int dstStride, int src8Stride, int h)\ {\ - asm volatile(\ - "movq %0, %%mm6 \n\t"\ - ::"m"(ff_pw_16)\ - );\ - while(h--){\ + do{\ asm volatile(\ "movq (%1), %%mm0 \n\t"\ "movq 8(%1), %%mm1 \n\t"\ - "paddw %%mm6, %%mm0 \n\t"\ - "paddw %%mm6, %%mm1 \n\t"\ + "movq 48(%1), %%mm2 \n\t"\ + "movq 8+48(%1), %%mm3 \n\t"\ "psraw $5, %%mm0 \n\t"\ "psraw $5, %%mm1 \n\t"\ + "psraw $5, %%mm2 \n\t"\ + "psraw $5, %%mm3 \n\t"\ "packuswb %%mm1, %%mm0 \n\t"\ + "packuswb %%mm3, %%mm2 \n\t"\ PAVGB" (%0), %%mm0 \n\t"\ + PAVGB" (%0,%3), %%mm2 \n\t"\ OP(%%mm0, (%2), %%mm5, q)\ - ::"a"(src8), "c"(src16), "d"(dst)\ + OP(%%mm2, (%2,%4), %%mm5, q)\ + ::"a"(src8), "c"(src16), "d"(dst),\ + "r"((long)src8Stride), "r"((long)dstStride)\ :"memory");\ - src8 += src8Stride;\ - src16 += 24;\ - dst += dstStride;\ - }\ + src8 += 2L*src8Stride;\ + src16 += 48;\ + dst += 2L*dstStride;\ + }while(h-=2);\ }\ static void OPNAME ## pixels16_l2_shift5_ ## MMX(uint8_t *dst, int16_t *src16, uint8_t *src8, int dstStride, int src8Stride, int h)\ {\ @@ -1238,11 +1311,453 @@ static void OPNAME ## pixels16_l2_shift5_ ## MMX(uint8_t *dst, int16_t *src16, u }\ -#define H264_MC(OPNAME, SIZE, MMX) \ -static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## MMX (uint8_t *dst, uint8_t *src, int stride){\ - OPNAME ## pixels ## SIZE ## _mmx(dst, src, stride, SIZE);\ +#ifdef ARCH_X86_64 +#define QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ +static av_noinline void OPNAME ## h264_qpel16_h_lowpass_l2_ ## MMX(uint8_t *dst, uint8_t *src, uint8_t *src2, int dstStride, int src2Stride){\ + int h=16;\ + asm volatile(\ + "pxor %%xmm15, %%xmm15 \n\t"\ + "movdqa %6, %%xmm14 \n\t"\ + "movdqa %7, %%xmm13 \n\t"\ + "1: \n\t"\ + "lddqu 3(%0), %%xmm1 \n\t"\ + "lddqu -5(%0), %%xmm7 \n\t"\ + "movdqa %%xmm1, %%xmm0 \n\t"\ + "punpckhbw %%xmm15, %%xmm1 \n\t"\ + "punpcklbw %%xmm15, %%xmm0 \n\t"\ + "punpcklbw %%xmm15, %%xmm7 \n\t"\ + "movdqa %%xmm1, %%xmm2 \n\t"\ + "movdqa %%xmm0, %%xmm6 \n\t"\ + "movdqa %%xmm1, %%xmm3 \n\t"\ + "movdqa %%xmm0, %%xmm8 \n\t"\ + "movdqa %%xmm1, %%xmm4 \n\t"\ + "movdqa %%xmm0, %%xmm9 \n\t"\ + "movdqa %%xmm1, %%xmm5 \n\t"\ + "movdqa %%xmm0, %%xmm10 \n\t"\ + "palignr $6, %%xmm0, %%xmm5 \n\t"\ + "palignr $6, %%xmm7, %%xmm10\n\t"\ + "palignr $8, %%xmm0, %%xmm4 \n\t"\ + "palignr $8, %%xmm7, %%xmm9 \n\t"\ + "palignr $10,%%xmm0, %%xmm3 \n\t"\ + "palignr $10,%%xmm7, %%xmm8 \n\t"\ + "paddw %%xmm1, %%xmm5 \n\t"\ + "paddw %%xmm0, %%xmm10 \n\t"\ + "palignr $12,%%xmm0, %%xmm2 \n\t"\ + "palignr $12,%%xmm7, %%xmm6 \n\t"\ + "palignr $14,%%xmm0, %%xmm1 \n\t"\ + "palignr $14,%%xmm7, %%xmm0 \n\t"\ + "paddw %%xmm3, %%xmm2 \n\t"\ + "paddw %%xmm8, %%xmm6 \n\t"\ + "paddw %%xmm4, %%xmm1 \n\t"\ + "paddw %%xmm9, %%xmm0 \n\t"\ + "psllw $2, %%xmm2 \n\t"\ + "psllw $2, %%xmm6 \n\t"\ + "psubw %%xmm1, %%xmm2 \n\t"\ + "psubw %%xmm0, %%xmm6 \n\t"\ + "paddw %%xmm13,%%xmm5 \n\t"\ + "paddw %%xmm13,%%xmm10 \n\t"\ + "pmullw %%xmm14,%%xmm2 \n\t"\ + "pmullw %%xmm14,%%xmm6 \n\t"\ + "lddqu (%2), %%xmm3 \n\t"\ + "paddw %%xmm5, %%xmm2 \n\t"\ + "paddw %%xmm10,%%xmm6 \n\t"\ + "psraw $5, %%xmm2 \n\t"\ + "psraw $5, %%xmm6 \n\t"\ + "packuswb %%xmm2,%%xmm6 \n\t"\ + "pavgb %%xmm3, %%xmm6 \n\t"\ + OP(%%xmm6, (%1), %%xmm4, dqa)\ + "add %5, %0 \n\t"\ + "add %5, %1 \n\t"\ + "add %4, %2 \n\t"\ + "decl %3 \n\t"\ + "jg 1b \n\t"\ + : "+a"(src), "+c"(dst), "+d"(src2), "+g"(h)\ + : "D"((long)src2Stride), "S"((long)dstStride),\ + "m"(ff_pw_5), "m"(ff_pw_16)\ + : "memory"\ + );\ +} +#else // ARCH_X86_64 +#define QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ +static av_noinline void OPNAME ## h264_qpel16_h_lowpass_l2_ ## MMX(uint8_t *dst, uint8_t *src, uint8_t *src2, int dstStride, int src2Stride){\ + OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ + src += 8*dstStride;\ + dst += 8*dstStride;\ + src2 += 8*src2Stride;\ + OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ +} +#endif // ARCH_X86_64 + +#define QPEL_H264_H_XMM(OPNAME, OP, MMX)\ +static av_noinline void OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(uint8_t *dst, uint8_t *src, uint8_t *src2, int dstStride, int src2Stride){\ + int h=8;\ + asm volatile(\ + "pxor %%xmm7, %%xmm7 \n\t"\ + "movdqa %0, %%xmm6 \n\t"\ + :: "m"(ff_pw_5)\ + );\ + do{\ + asm volatile(\ + "lddqu -5(%0), %%xmm1 \n\t"\ + "movdqa %%xmm1, %%xmm0 \n\t"\ + "punpckhbw %%xmm7, %%xmm1 \n\t"\ + "punpcklbw %%xmm7, %%xmm0 \n\t"\ + "movdqa %%xmm1, %%xmm2 \n\t"\ + "movdqa %%xmm1, %%xmm3 \n\t"\ + "movdqa %%xmm1, %%xmm4 \n\t"\ + "movdqa %%xmm1, %%xmm5 \n\t"\ + "palignr $6, %%xmm0, %%xmm5 \n\t"\ + "palignr $8, %%xmm0, %%xmm4 \n\t"\ + "palignr $10,%%xmm0, %%xmm3 \n\t"\ + "paddw %%xmm1, %%xmm5 \n\t"\ + "palignr $12,%%xmm0, %%xmm2 \n\t"\ + "palignr $14,%%xmm0, %%xmm1 \n\t"\ + "paddw %%xmm3, %%xmm2 \n\t"\ + "paddw %%xmm4, %%xmm1 \n\t"\ + "psllw $2, %%xmm2 \n\t"\ + "movq (%2), %%xmm3 \n\t"\ + "psubw %%xmm1, %%xmm2 \n\t"\ + "paddw %5, %%xmm5 \n\t"\ + "pmullw %%xmm6, %%xmm2 \n\t"\ + "paddw %%xmm5, %%xmm2 \n\t"\ + "psraw $5, %%xmm2 \n\t"\ + "packuswb %%xmm2, %%xmm2 \n\t"\ + "pavgb %%xmm3, %%xmm2 \n\t"\ + OP(%%xmm2, (%1), %%xmm4, q)\ + "add %4, %0 \n\t"\ + "add %4, %1 \n\t"\ + "add %3, %2 \n\t"\ + : "+a"(src), "+c"(dst), "+d"(src2)\ + : "D"((long)src2Stride), "S"((long)dstStride),\ + "m"(ff_pw_16)\ + : "memory"\ + );\ + }while(--h);\ }\ +QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ \ +static av_noinline void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + int h=8;\ + asm volatile(\ + "pxor %%xmm7, %%xmm7 \n\t"\ + "movdqa %5, %%xmm6 \n\t"\ + "1: \n\t"\ + "lddqu -5(%0), %%xmm1 \n\t"\ + "movdqa %%xmm1, %%xmm0 \n\t"\ + "punpckhbw %%xmm7, %%xmm1 \n\t"\ + "punpcklbw %%xmm7, %%xmm0 \n\t"\ + "movdqa %%xmm1, %%xmm2 \n\t"\ + "movdqa %%xmm1, %%xmm3 \n\t"\ + "movdqa %%xmm1, %%xmm4 \n\t"\ + "movdqa %%xmm1, %%xmm5 \n\t"\ + "palignr $6, %%xmm0, %%xmm5 \n\t"\ + "palignr $8, %%xmm0, %%xmm4 \n\t"\ + "palignr $10,%%xmm0, %%xmm3 \n\t"\ + "paddw %%xmm1, %%xmm5 \n\t"\ + "palignr $12,%%xmm0, %%xmm2 \n\t"\ + "palignr $14,%%xmm0, %%xmm1 \n\t"\ + "paddw %%xmm3, %%xmm2 \n\t"\ + "paddw %%xmm4, %%xmm1 \n\t"\ + "psllw $2, %%xmm2 \n\t"\ + "psubw %%xmm1, %%xmm2 \n\t"\ + "paddw %6, %%xmm5 \n\t"\ + "pmullw %%xmm6, %%xmm2 \n\t"\ + "paddw %%xmm5, %%xmm2 \n\t"\ + "psraw $5, %%xmm2 \n\t"\ + "packuswb %%xmm2, %%xmm2 \n\t"\ + OP(%%xmm2, (%1), %%xmm4, q)\ + "add %3, %0 \n\t"\ + "add %4, %1 \n\t"\ + "decl %2 \n\t"\ + " jnz 1b \n\t"\ + : "+a"(src), "+c"(dst), "+g"(h)\ + : "D"((long)srcStride), "S"((long)dstStride),\ + "m"(ff_pw_5), "m"(ff_pw_16)\ + : "memory"\ + );\ +}\ +static void OPNAME ## h264_qpel16_h_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ +}\ + +#define QPEL_H264_V_XMM(OPNAME, OP, MMX)\ +static av_noinline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ + src -= 2*srcStride;\ + \ + asm volatile(\ + "pxor %%xmm7, %%xmm7 \n\t"\ + "movq (%0), %%xmm0 \n\t"\ + "add %2, %0 \n\t"\ + "movq (%0), %%xmm1 \n\t"\ + "add %2, %0 \n\t"\ + "movq (%0), %%xmm2 \n\t"\ + "add %2, %0 \n\t"\ + "movq (%0), %%xmm3 \n\t"\ + "add %2, %0 \n\t"\ + "movq (%0), %%xmm4 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%xmm7, %%xmm0 \n\t"\ + "punpcklbw %%xmm7, %%xmm1 \n\t"\ + "punpcklbw %%xmm7, %%xmm2 \n\t"\ + "punpcklbw %%xmm7, %%xmm3 \n\t"\ + "punpcklbw %%xmm7, %%xmm4 \n\t"\ + QPEL_H264V_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, OP)\ + QPEL_H264V_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, OP)\ + QPEL_H264V_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, OP)\ + QPEL_H264V_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, OP)\ + QPEL_H264V_XMM(%%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, OP)\ + QPEL_H264V_XMM(%%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, OP)\ + QPEL_H264V_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, OP)\ + QPEL_H264V_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, OP)\ + \ + : "+a"(src), "+c"(dst)\ + : "S"((long)srcStride), "D"((long)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ + : "memory"\ + );\ + if(h==16){\ + asm volatile(\ + QPEL_H264V_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, OP)\ + QPEL_H264V_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, OP)\ + QPEL_H264V_XMM(%%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, OP)\ + QPEL_H264V_XMM(%%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, OP)\ + QPEL_H264V_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, OP)\ + QPEL_H264V_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, OP)\ + QPEL_H264V_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, OP)\ + QPEL_H264V_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, OP)\ + \ + : "+a"(src), "+c"(dst)\ + : "S"((long)srcStride), "D"((long)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ + : "memory"\ + );\ + }\ +}\ +static void OPNAME ## h264_qpel8_v_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static av_noinline void OPNAME ## h264_qpel16_v_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 16);\ + OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +} + +static av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, uint8_t *src, int tmpStride, int srcStride, int size){ + int w = (size+8)>>3; + src -= 2*srcStride+2; + while(w--){ + asm volatile( + "pxor %%xmm7, %%xmm7 \n\t" + "movq (%0), %%xmm0 \n\t" + "add %2, %0 \n\t" + "movq (%0), %%xmm1 \n\t" + "add %2, %0 \n\t" + "movq (%0), %%xmm2 \n\t" + "add %2, %0 \n\t" + "movq (%0), %%xmm3 \n\t" + "add %2, %0 \n\t" + "movq (%0), %%xmm4 \n\t" + "add %2, %0 \n\t" + "punpcklbw %%xmm7, %%xmm0 \n\t" + "punpcklbw %%xmm7, %%xmm1 \n\t" + "punpcklbw %%xmm7, %%xmm2 \n\t" + "punpcklbw %%xmm7, %%xmm3 \n\t" + "punpcklbw %%xmm7, %%xmm4 \n\t" + QPEL_H264HV_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, 0*48) + QPEL_H264HV_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, 1*48) + QPEL_H264HV_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, 2*48) + QPEL_H264HV_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, 3*48) + QPEL_H264HV_XMM(%%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, 4*48) + QPEL_H264HV_XMM(%%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, 5*48) + QPEL_H264HV_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, 6*48) + QPEL_H264HV_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, 7*48) + : "+a"(src) + : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5), "m"(ff_pw_16) + : "memory" + ); + if(size==16){ + asm volatile( + QPEL_H264HV_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, 8*48) + QPEL_H264HV_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, 9*48) + QPEL_H264HV_XMM(%%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, 10*48) + QPEL_H264HV_XMM(%%xmm5, %%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, 11*48) + QPEL_H264HV_XMM(%%xmm0, %%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, 12*48) + QPEL_H264HV_XMM(%%xmm1, %%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, 13*48) + QPEL_H264HV_XMM(%%xmm2, %%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, 14*48) + QPEL_H264HV_XMM(%%xmm3, %%xmm4, %%xmm5, %%xmm0, %%xmm1, %%xmm2, 15*48) + : "+a"(src) + : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5), "m"(ff_pw_16) + : "memory" + ); + } + tmp += 8; + src += 8 - (size+5)*srcStride; + } +} + +#define QPEL_H264_HV2_XMM(OPNAME, OP, MMX)\ +static av_always_inline void OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, int dstStride, int tmpStride, int size){\ + int h = size;\ + if(size == 16){\ + asm volatile(\ + "1: \n\t"\ + "movdqa 32(%0), %%xmm4 \n\t"\ + "movdqa 16(%0), %%xmm5 \n\t"\ + "movdqa (%0), %%xmm7 \n\t"\ + "movdqa %%xmm4, %%xmm3 \n\t"\ + "movdqa %%xmm4, %%xmm2 \n\t"\ + "movdqa %%xmm4, %%xmm1 \n\t"\ + "movdqa %%xmm4, %%xmm0 \n\t"\ + "palignr $10, %%xmm5, %%xmm0 \n\t"\ + "palignr $8, %%xmm5, %%xmm1 \n\t"\ + "palignr $6, %%xmm5, %%xmm2 \n\t"\ + "palignr $4, %%xmm5, %%xmm3 \n\t"\ + "palignr $2, %%xmm5, %%xmm4 \n\t"\ + "paddw %%xmm5, %%xmm0 \n\t"\ + "paddw %%xmm4, %%xmm1 \n\t"\ + "paddw %%xmm3, %%xmm2 \n\t"\ + "movdqa %%xmm5, %%xmm6 \n\t"\ + "movdqa %%xmm5, %%xmm4 \n\t"\ + "movdqa %%xmm5, %%xmm3 \n\t"\ + "palignr $8, %%xmm7, %%xmm4 \n\t"\ + "palignr $2, %%xmm7, %%xmm6 \n\t"\ + "palignr $10, %%xmm7, %%xmm3 \n\t"\ + "paddw %%xmm6, %%xmm4 \n\t"\ + "movdqa %%xmm5, %%xmm6 \n\t"\ + "palignr $6, %%xmm7, %%xmm5 \n\t"\ + "palignr $4, %%xmm7, %%xmm6 \n\t"\ + "paddw %%xmm7, %%xmm3 \n\t"\ + "paddw %%xmm6, %%xmm5 \n\t"\ + \ + "psubw %%xmm1, %%xmm0 \n\t"\ + "psubw %%xmm4, %%xmm3 \n\t"\ + "psraw $2, %%xmm0 \n\t"\ + "psraw $2, %%xmm3 \n\t"\ + "psubw %%xmm1, %%xmm0 \n\t"\ + "psubw %%xmm4, %%xmm3 \n\t"\ + "paddw %%xmm2, %%xmm0 \n\t"\ + "paddw %%xmm5, %%xmm3 \n\t"\ + "psraw $2, %%xmm0 \n\t"\ + "psraw $2, %%xmm3 \n\t"\ + "paddw %%xmm2, %%xmm0 \n\t"\ + "paddw %%xmm5, %%xmm3 \n\t"\ + "psraw $6, %%xmm0 \n\t"\ + "psraw $6, %%xmm3 \n\t"\ + "packuswb %%xmm0, %%xmm3 \n\t"\ + OP(%%xmm3, (%1), %%xmm7, dqa)\ + "add $48, %0 \n\t"\ + "add %3, %1 \n\t"\ + "decl %2 \n\t"\ + " jnz 1b \n\t"\ + : "+a"(tmp), "+c"(dst), "+g"(h)\ + : "S"((long)dstStride)\ + : "memory"\ + );\ + }else{\ + asm volatile(\ + "1: \n\t"\ + "movdqa 16(%0), %%xmm1 \n\t"\ + "movdqa (%0), %%xmm0 \n\t"\ + "movdqa %%xmm1, %%xmm2 \n\t"\ + "movdqa %%xmm1, %%xmm3 \n\t"\ + "movdqa %%xmm1, %%xmm4 \n\t"\ + "movdqa %%xmm1, %%xmm5 \n\t"\ + "palignr $10, %%xmm0, %%xmm5 \n\t"\ + "palignr $8, %%xmm0, %%xmm4 \n\t"\ + "palignr $6, %%xmm0, %%xmm3 \n\t"\ + "palignr $4, %%xmm0, %%xmm2 \n\t"\ + "palignr $2, %%xmm0, %%xmm1 \n\t"\ + "paddw %%xmm5, %%xmm0 \n\t"\ + "paddw %%xmm4, %%xmm1 \n\t"\ + "paddw %%xmm3, %%xmm2 \n\t"\ + "psubw %%xmm1, %%xmm0 \n\t"\ + "psraw $2, %%xmm0 \n\t"\ + "psubw %%xmm1, %%xmm0 \n\t"\ + "paddw %%xmm2, %%xmm0 \n\t"\ + "psraw $2, %%xmm0 \n\t"\ + "paddw %%xmm2, %%xmm0 \n\t"\ + "psraw $6, %%xmm0 \n\t"\ + "packuswb %%xmm0, %%xmm0 \n\t"\ + OP(%%xmm0, (%1), %%xmm7, q)\ + "add $48, %0 \n\t"\ + "add %3, %1 \n\t"\ + "decl %2 \n\t"\ + " jnz 1b \n\t"\ + : "+a"(tmp), "+c"(dst), "+g"(h)\ + : "S"((long)dstStride)\ + : "memory"\ + );\ + }\ +} + +#define QPEL_H264_HV_XMM(OPNAME, OP, MMX)\ +static av_noinline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ + put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\ + OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\ +}\ +static void OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst, tmp, src, dstStride, tmpStride, srcStride, 8);\ +}\ +static void OPNAME ## h264_qpel16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst, tmp, src, dstStride, tmpStride, srcStride, 16);\ +}\ + +#define put_pixels8_l2_sse2 put_pixels8_l2_mmx2 +#define avg_pixels8_l2_sse2 avg_pixels8_l2_mmx2 +#define put_pixels16_l2_sse2 put_pixels16_l2_mmx2 +#define avg_pixels16_l2_sse2 avg_pixels16_l2_mmx2 +#define put_pixels8_l2_ssse3 put_pixels8_l2_mmx2 +#define avg_pixels8_l2_ssse3 avg_pixels8_l2_mmx2 +#define put_pixels16_l2_ssse3 put_pixels16_l2_mmx2 +#define avg_pixels16_l2_ssse3 avg_pixels16_l2_mmx2 + +#define put_pixels8_l2_shift5_sse2 put_pixels8_l2_shift5_mmx2 +#define avg_pixels8_l2_shift5_sse2 avg_pixels8_l2_shift5_mmx2 +#define put_pixels16_l2_shift5_sse2 put_pixels16_l2_shift5_mmx2 +#define avg_pixels16_l2_shift5_sse2 avg_pixels16_l2_shift5_mmx2 +#define put_pixels8_l2_shift5_ssse3 put_pixels8_l2_shift5_mmx2 +#define avg_pixels8_l2_shift5_ssse3 avg_pixels8_l2_shift5_mmx2 +#define put_pixels16_l2_shift5_ssse3 put_pixels16_l2_shift5_mmx2 +#define avg_pixels16_l2_shift5_ssse3 avg_pixels16_l2_shift5_mmx2 + +#define put_h264_qpel8_h_lowpass_l2_sse2 put_h264_qpel8_h_lowpass_l2_mmx2 +#define avg_h264_qpel8_h_lowpass_l2_sse2 avg_h264_qpel8_h_lowpass_l2_mmx2 +#define put_h264_qpel16_h_lowpass_l2_sse2 put_h264_qpel16_h_lowpass_l2_mmx2 +#define avg_h264_qpel16_h_lowpass_l2_sse2 avg_h264_qpel16_h_lowpass_l2_mmx2 + +#define put_h264_qpel8_v_lowpass_ssse3 put_h264_qpel8_v_lowpass_sse2 +#define avg_h264_qpel8_v_lowpass_ssse3 avg_h264_qpel8_v_lowpass_sse2 +#define put_h264_qpel16_v_lowpass_ssse3 put_h264_qpel16_v_lowpass_sse2 +#define avg_h264_qpel16_v_lowpass_ssse3 avg_h264_qpel16_v_lowpass_sse2 + +#define put_h264_qpel8or16_hv2_lowpass_sse2 put_h264_qpel8or16_hv2_lowpass_mmx2 +#define avg_h264_qpel8or16_hv2_lowpass_sse2 avg_h264_qpel8or16_hv2_lowpass_mmx2 + +#define H264_MC(OPNAME, SIZE, MMX, ALIGN) \ +H264_MC_C(OPNAME, SIZE, MMX, ALIGN)\ +H264_MC_V(OPNAME, SIZE, MMX, ALIGN)\ +H264_MC_H(OPNAME, SIZE, MMX, ALIGN)\ +H264_MC_HV(OPNAME, SIZE, MMX, ALIGN)\ + +static void put_h264_qpel16_mc00_sse2 (uint8_t *dst, uint8_t *src, int stride){ + put_pixels16_sse2(dst, src, stride, 16); +} +static void avg_h264_qpel16_mc00_sse2 (uint8_t *dst, uint8_t *src, int stride){ + avg_pixels16_sse2(dst, src, stride, 16); +} +#define put_h264_qpel8_mc00_sse2 put_h264_qpel8_mc00_mmx2 +#define avg_h264_qpel8_mc00_sse2 avg_h264_qpel8_mc00_mmx2 + +#define H264_MC_C(OPNAME, SIZE, MMX, ALIGN) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## MMX (uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## pixels ## SIZE ## _ ## MMX(dst, src, stride, SIZE);\ +}\ + +#define H264_MC_H(OPNAME, SIZE, MMX, ALIGN) \ static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src, stride, stride);\ }\ @@ -1254,12 +1769,12 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t * static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src+1, stride, stride);\ }\ -\ + +#define H264_MC_V(OPNAME, SIZE, MMX, ALIGN) \ static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*SIZE/8];\ - uint8_t * const half= (uint8_t*)temp;\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src, half, stride, stride, SIZE);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src, temp, stride, stride, SIZE);\ }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ @@ -1267,82 +1782,91 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t * }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*SIZE/8];\ - uint8_t * const half= (uint8_t*)temp;\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(half, src, SIZE, stride);\ - OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src+stride, half, stride, stride, SIZE);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src+stride, temp, stride, stride, SIZE);\ }\ -\ + +#define H264_MC_HV(OPNAME, SIZE, MMX, ALIGN) \ static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*SIZE/8];\ - uint8_t * const halfV= (uint8_t*)temp;\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(halfV, src, SIZE, stride);\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfV, stride, SIZE);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\ }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*SIZE/8];\ - uint8_t * const halfV= (uint8_t*)temp;\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(halfV, src+1, SIZE, stride);\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfV, stride, SIZE);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\ }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*SIZE/8];\ - uint8_t * const halfV= (uint8_t*)temp;\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(halfV, src, SIZE, stride);\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfV, stride, SIZE);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\ }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*SIZE/8];\ - uint8_t * const halfV= (uint8_t*)temp;\ - put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(halfV, src+1, SIZE, stride);\ - OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfV, stride, SIZE);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*SIZE]);\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\ }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*(SIZE<8?12:24)/4];\ - int16_t * const tmp= (int16_t*)temp;\ - OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(dst, tmp, src, stride, SIZE, stride);\ + DECLARE_ALIGNED(ALIGN, uint16_t, temp[SIZE*(SIZE<8?12:24)]);\ + OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(dst, temp, src, stride, SIZE, stride);\ }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*(SIZE<8?12:24)/4 + SIZE*SIZE/8];\ - uint8_t * const halfHV= (uint8_t*)temp;\ - int16_t * const tmp= ((int16_t*)temp) + SIZE*SIZE/2;\ - assert((int)temp & 7 == 0);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, tmp, src, SIZE, SIZE, stride);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + assert(((int)temp & 7) == 0);\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfHV, stride, SIZE);\ }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*(SIZE<8?12:24)/4 + SIZE*SIZE/8];\ - uint8_t * const halfHV= (uint8_t*)temp;\ - int16_t * const tmp= ((int16_t*)temp) + SIZE*SIZE/2;\ - assert((int)temp & 7 == 0);\ - put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, tmp, src, SIZE, SIZE, stride);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + assert(((int)temp & 7) == 0);\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfHV, stride, SIZE);\ }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*(SIZE<8?12:24)/4 + SIZE*SIZE/8];\ - int16_t * const halfV= ((int16_t*)temp) + SIZE*SIZE/2;\ - uint8_t * const halfHV= ((uint8_t*)temp);\ - assert((int)temp & 7 == 0);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + assert(((int)temp & 7) == 0);\ put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ OPNAME ## pixels ## SIZE ## _l2_shift5_ ## MMX(dst, halfV+2, halfHV, stride, SIZE, SIZE);\ }\ \ static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ - uint64_t temp[SIZE*(SIZE<8?12:24)/4 + SIZE*SIZE/8];\ - int16_t * const halfV= ((int16_t*)temp) + SIZE*SIZE/2;\ - uint8_t * const halfHV= ((uint8_t*)temp);\ - assert((int)temp & 7 == 0);\ + DECLARE_ALIGNED(ALIGN, uint8_t, temp[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + assert(((int)temp & 7) == 0);\ put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ OPNAME ## pixels ## SIZE ## _l2_shift5_ ## MMX(dst, halfV+3, halfHV, stride, SIZE, SIZE);\ }\ +#define H264_MC_4816(MMX)\ +H264_MC(put_, 4, MMX, 8)\ +H264_MC(put_, 8, MMX, 8)\ +H264_MC(put_, 16,MMX, 8)\ +H264_MC(avg_, 4, MMX, 8)\ +H264_MC(avg_, 8, MMX, 8)\ +H264_MC(avg_, 16,MMX, 8)\ + +#define H264_MC_816(QPEL, XMM)\ +QPEL(put_, 8, XMM, 16)\ +QPEL(put_, 16,XMM, 16)\ +QPEL(avg_, 8, XMM, 16)\ +QPEL(avg_, 16,XMM, 16)\ + #define AVG_3DNOW_OP(a,b,temp, size) \ "mov" #size " " #b ", " #temp " \n\t"\ @@ -1360,20 +1884,28 @@ QPEL_H264(avg_, AVG_3DNOW_OP, 3dnow) #define PAVGB "pavgb" QPEL_H264(put_, PUT_OP, mmx2) QPEL_H264(avg_, AVG_MMX2_OP, mmx2) +QPEL_H264_V_XMM(put_, PUT_OP, sse2) +QPEL_H264_V_XMM(avg_, AVG_MMX2_OP, sse2) +QPEL_H264_HV_XMM(put_, PUT_OP, sse2) +QPEL_H264_HV_XMM(avg_, AVG_MMX2_OP, sse2) +#ifdef HAVE_SSSE3 +QPEL_H264_H_XMM(put_, PUT_OP, ssse3) +QPEL_H264_H_XMM(avg_, AVG_MMX2_OP, ssse3) +QPEL_H264_HV2_XMM(put_, PUT_OP, ssse3) +QPEL_H264_HV2_XMM(avg_, AVG_MMX2_OP, ssse3) +QPEL_H264_HV_XMM(put_, PUT_OP, ssse3) +QPEL_H264_HV_XMM(avg_, AVG_MMX2_OP, ssse3) +#endif #undef PAVGB -H264_MC(put_, 4, 3dnow) -H264_MC(put_, 8, 3dnow) -H264_MC(put_, 16,3dnow) -H264_MC(avg_, 4, 3dnow) -H264_MC(avg_, 8, 3dnow) -H264_MC(avg_, 16,3dnow) -H264_MC(put_, 4, mmx2) -H264_MC(put_, 8, mmx2) -H264_MC(put_, 16,mmx2) -H264_MC(avg_, 4, mmx2) -H264_MC(avg_, 8, mmx2) -H264_MC(avg_, 16,mmx2) +H264_MC_4816(3dnow) +H264_MC_4816(mmx2) +H264_MC_816(H264_MC_V, sse2) +H264_MC_816(H264_MC_HV, sse2) +#ifdef HAVE_SSSE3 +H264_MC_816(H264_MC_H, ssse3) +H264_MC_816(H264_MC_HV, ssse3) +#endif #define H264_CHROMA_OP(S,D) @@ -1383,6 +1915,16 @@ H264_MC(avg_, 16,mmx2) #define H264_CHROMA_MC2_TMPL put_h264_chroma_mc2_mmx2 #define H264_CHROMA_MC8_MV0 put_pixels8_mmx #include "dsputil_h264_template_mmx.c" + +static void put_h264_chroma_mc8_mmx_rnd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) +{ + put_h264_chroma_mc8_mmx(dst, src, stride, h, x, y, 1); +} +static void put_h264_chroma_mc8_mmx_nornd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) +{ + put_h264_chroma_mc8_mmx(dst, src, stride, h, x, y, 0); +} + #undef H264_CHROMA_OP #undef H264_CHROMA_OP4 #undef H264_CHROMA_MC8_TMPL @@ -1398,6 +1940,10 @@ H264_MC(avg_, 16,mmx2) #define H264_CHROMA_MC2_TMPL avg_h264_chroma_mc2_mmx2 #define H264_CHROMA_MC8_MV0 avg_pixels8_mmx2 #include "dsputil_h264_template_mmx.c" +static void avg_h264_chroma_mc8_mmx2_rnd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) +{ + avg_h264_chroma_mc8_mmx2(dst, src, stride, h, x, y, 1); +} #undef H264_CHROMA_OP #undef H264_CHROMA_OP4 #undef H264_CHROMA_MC8_TMPL @@ -1412,6 +1958,10 @@ H264_MC(avg_, 16,mmx2) #define H264_CHROMA_MC4_TMPL avg_h264_chroma_mc4_3dnow #define H264_CHROMA_MC8_MV0 avg_pixels8_3dnow #include "dsputil_h264_template_mmx.c" +static void avg_h264_chroma_mc8_3dnow_rnd(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) +{ + avg_h264_chroma_mc8_3dnow(dst, src, stride, h, x, y, 1); +} #undef H264_CHROMA_OP #undef H264_CHROMA_OP4 #undef H264_CHROMA_MC8_TMPL diff --git a/contrib/ffmpeg/libavcodec/i386/idct_mmx.c b/contrib/ffmpeg/libavcodec/i386/idct_mmx.c index 4c548fdce..005a42ded 100644 --- a/contrib/ffmpeg/libavcodec/i386/idct_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/idct_mmx.c @@ -20,7 +20,7 @@ */ #include "common.h" -#include "../dsputil.h" +#include "dsputil.h" #include "mmx.h" @@ -33,7 +33,7 @@ #define rounder(bias) {round (bias), round (bias)} #if 0 -/* C row IDCT - its just here to document the MMXEXT and MMX versions */ +/* C row IDCT - it is just here to document the MMXEXT and MMX versions */ static inline void idct_row (int16_t * row, int offset, int16_t * table, int32_t * rounder) { @@ -85,102 +85,102 @@ static inline void idct_row (int16_t * row, int offset, static inline void mmxext_row_head (int16_t * row, int offset, const int16_t * table) { - movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ - movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 - movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ + movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ - movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 - movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + movq_m2r (*table, mm3); /* mm3 = -C2 -C4 C2 C4 */ + movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ - movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 - pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 + movq_m2r (*(table+4), mm4); /* mm4 = C6 C4 C6 C4 */ + pmaddwd_r2r (mm0, mm3); /* mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 */ - pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 + pshufw_r2r (mm2, mm2, 0x4e); /* mm2 = x2 x0 x6 x4 */ } static inline void mmxext_row (const int16_t * table, const int32_t * rounder) { - movq_m2r (*(table+8), mm1); // mm1 = -C5 -C1 C3 C1 - pmaddwd_r2r (mm2, mm4); // mm4 = C4*x0+C6*x2 C4*x4+C6*x6 + movq_m2r (*(table+8), mm1); /* mm1 = -C5 -C1 C3 C1 */ + pmaddwd_r2r (mm2, mm4); /* mm4 = C4*x0+C6*x2 C4*x4+C6*x6 */ - pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x4-C6*x6 C4*x0-C6*x2 - pshufw_r2r (mm6, mm6, 0x4e); // mm6 = x3 x1 x7 x5 + pmaddwd_m2r (*(table+16), mm0); /* mm0 = C4*x4-C6*x6 C4*x0-C6*x2 */ + pshufw_r2r (mm6, mm6, 0x4e); /* mm6 = x3 x1 x7 x5 */ - movq_m2r (*(table+12), mm7); // mm7 = -C7 C3 C7 C5 - pmaddwd_r2r (mm5, mm1); // mm1 = -C1*x5-C5*x7 C1*x1+C3*x3 + movq_m2r (*(table+12), mm7); /* mm7 = -C7 C3 C7 C5 */ + pmaddwd_r2r (mm5, mm1); /* mm1 = -C1*x5-C5*x7 C1*x1+C3*x3 */ - paddd_m2r (*rounder, mm3); // mm3 += rounder - pmaddwd_r2r (mm6, mm7); // mm7 = C3*x1-C7*x3 C5*x5+C7*x7 + paddd_m2r (*rounder, mm3); /* mm3 += rounder */ + pmaddwd_r2r (mm6, mm7); /* mm7 = C3*x1-C7*x3 C5*x5+C7*x7 */ - pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x0-C2*x2 -C4*x4+C2*x6 - paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder + pmaddwd_m2r (*(table+20), mm2); /* mm2 = C4*x0-C2*x2 -C4*x4+C2*x6 */ + paddd_r2r (mm4, mm3); /* mm3 = a1 a0 + rounder */ - pmaddwd_m2r (*(table+24), mm5); // mm5 = C3*x5-C1*x7 C5*x1-C1*x3 - movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder + pmaddwd_m2r (*(table+24), mm5); /* mm5 = C3*x5-C1*x7 C5*x1-C1*x3 */ + movq_r2r (mm3, mm4); /* mm4 = a1 a0 + rounder */ - pmaddwd_m2r (*(table+28), mm6); // mm6 = C7*x1-C5*x3 C7*x5+C3*x7 - paddd_r2r (mm7, mm1); // mm1 = b1 b0 + pmaddwd_m2r (*(table+28), mm6); /* mm6 = C7*x1-C5*x3 C7*x5+C3*x7 */ + paddd_r2r (mm7, mm1); /* mm1 = b1 b0 */ - paddd_m2r (*rounder, mm0); // mm0 += rounder - psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder + paddd_m2r (*rounder, mm0); /* mm0 += rounder */ + psubd_r2r (mm1, mm3); /* mm3 = a1-b1 a0-b0 + rounder */ - psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 - paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder + psrad_i2r (ROW_SHIFT, mm3); /* mm3 = y6 y7 */ + paddd_r2r (mm4, mm1); /* mm1 = a1+b1 a0+b0 + rounder */ - paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder - psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 + paddd_r2r (mm2, mm0); /* mm0 = a3 a2 + rounder */ + psrad_i2r (ROW_SHIFT, mm1); /* mm1 = y1 y0 */ - paddd_r2r (mm6, mm5); // mm5 = b3 b2 - movq_r2r (mm0, mm4); // mm4 = a3 a2 + rounder + paddd_r2r (mm6, mm5); /* mm5 = b3 b2 */ + movq_r2r (mm0, mm4); /* mm4 = a3 a2 + rounder */ - paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder - psubd_r2r (mm5, mm4); // mm4 = a3-b3 a2-b2 + rounder + paddd_r2r (mm5, mm0); /* mm0 = a3+b3 a2+b2 + rounder */ + psubd_r2r (mm5, mm4); /* mm4 = a3-b3 a2-b2 + rounder */ } static inline void mmxext_row_tail (int16_t * row, int store) { - psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ - psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 + psrad_i2r (ROW_SHIFT, mm4); /* mm4 = y4 y5 */ - packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ - packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 + packssdw_r2r (mm3, mm4); /* mm4 = y6 y7 y4 y5 */ - movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 - pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 + movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ + pshufw_r2r (mm4, mm4, 0xb1); /* mm4 = y7 y6 y5 y4 */ /* slot */ - movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 + movq_r2m (mm4, *(row+store+4)); /* save y7 y6 y5 y4 */ } static inline void mmxext_row_mid (int16_t * row, int store, int offset, const int16_t * table) { - movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 - psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ + psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ - movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 - psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 + movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ + psrad_i2r (ROW_SHIFT, mm4); /* mm4 = y4 y5 */ - packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 - movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ + movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ - packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 - movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + packssdw_r2r (mm3, mm4); /* mm4 = y6 y7 y4 y5 */ + movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ - movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 - pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 + movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ + pshufw_r2r (mm4, mm4, 0xb1); /* mm4 = y7 y6 y5 y4 */ - movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 - movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 + movq_m2r (*table, mm3); /* mm3 = -C2 -C4 C2 C4 */ + movq_r2m (mm4, *(row+store+4)); /* save y7 y6 y5 y4 */ - pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 + pmaddwd_r2r (mm0, mm3); /* mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 */ - movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 - pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 + movq_m2r (*(table+4), mm4); /* mm4 = C6 C4 C6 C4 */ + pshufw_r2r (mm2, mm2, 0x4e); /* mm2 = x2 x0 x6 x4 */ } @@ -197,123 +197,123 @@ static inline void mmxext_row_mid (int16_t * row, int store, static inline void mmx_row_head (int16_t * row, int offset, const int16_t * table) { - movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ - movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 - movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ + movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ - movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 - movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + movq_m2r (*table, mm3); /* mm3 = C6 C4 C2 C4 */ + movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ - punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 + punpckldq_r2r (mm0, mm0); /* mm0 = x2 x0 x2 x0 */ - movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 - pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 + movq_m2r (*(table+4), mm4); /* mm4 = -C2 -C4 C6 C4 */ + pmaddwd_r2r (mm0, mm3); /* mm3 = C4*x0+C6*x2 C4*x0+C2*x2 */ - movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 - punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 + movq_m2r (*(table+8), mm1); /* mm1 = -C7 C3 C3 C1 */ + punpckhdq_r2r (mm2, mm2); /* mm2 = x6 x4 x6 x4 */ } static inline void mmx_row (const int16_t * table, const int32_t * rounder) { - pmaddwd_r2r (mm2, mm4); // mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 - punpckldq_r2r (mm5, mm5); // mm5 = x3 x1 x3 x1 + pmaddwd_r2r (mm2, mm4); /* mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 */ + punpckldq_r2r (mm5, mm5); /* mm5 = x3 x1 x3 x1 */ - pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x0-C2*x2 C4*x0-C6*x2 - punpckhdq_r2r (mm6, mm6); // mm6 = x7 x5 x7 x5 + pmaddwd_m2r (*(table+16), mm0); /* mm0 = C4*x0-C2*x2 C4*x0-C6*x2 */ + punpckhdq_r2r (mm6, mm6); /* mm6 = x7 x5 x7 x5 */ - movq_m2r (*(table+12), mm7); // mm7 = -C5 -C1 C7 C5 - pmaddwd_r2r (mm5, mm1); // mm1 = C3*x1-C7*x3 C1*x1+C3*x3 + movq_m2r (*(table+12), mm7); /* mm7 = -C5 -C1 C7 C5 */ + pmaddwd_r2r (mm5, mm1); /* mm1 = C3*x1-C7*x3 C1*x1+C3*x3 */ - paddd_m2r (*rounder, mm3); // mm3 += rounder - pmaddwd_r2r (mm6, mm7); // mm7 = -C1*x5-C5*x7 C5*x5+C7*x7 + paddd_m2r (*rounder, mm3); /* mm3 += rounder */ + pmaddwd_r2r (mm6, mm7); /* mm7 = -C1*x5-C5*x7 C5*x5+C7*x7 */ - pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x4-C6*x6 -C4*x4+C2*x6 - paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder + pmaddwd_m2r (*(table+20), mm2); /* mm2 = C4*x4-C6*x6 -C4*x4+C2*x6 */ + paddd_r2r (mm4, mm3); /* mm3 = a1 a0 + rounder */ - pmaddwd_m2r (*(table+24), mm5); // mm5 = C7*x1-C5*x3 C5*x1-C1*x3 - movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder + pmaddwd_m2r (*(table+24), mm5); /* mm5 = C7*x1-C5*x3 C5*x1-C1*x3 */ + movq_r2r (mm3, mm4); /* mm4 = a1 a0 + rounder */ - pmaddwd_m2r (*(table+28), mm6); // mm6 = C3*x5-C1*x7 C7*x5+C3*x7 - paddd_r2r (mm7, mm1); // mm1 = b1 b0 + pmaddwd_m2r (*(table+28), mm6); /* mm6 = C3*x5-C1*x7 C7*x5+C3*x7 */ + paddd_r2r (mm7, mm1); /* mm1 = b1 b0 */ - paddd_m2r (*rounder, mm0); // mm0 += rounder - psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder + paddd_m2r (*rounder, mm0); /* mm0 += rounder */ + psubd_r2r (mm1, mm3); /* mm3 = a1-b1 a0-b0 + rounder */ - psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 - paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder + psrad_i2r (ROW_SHIFT, mm3); /* mm3 = y6 y7 */ + paddd_r2r (mm4, mm1); /* mm1 = a1+b1 a0+b0 + rounder */ - paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder - psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 + paddd_r2r (mm2, mm0); /* mm0 = a3 a2 + rounder */ + psrad_i2r (ROW_SHIFT, mm1); /* mm1 = y1 y0 */ - paddd_r2r (mm6, mm5); // mm5 = b3 b2 - movq_r2r (mm0, mm7); // mm7 = a3 a2 + rounder + paddd_r2r (mm6, mm5); /* mm5 = b3 b2 */ + movq_r2r (mm0, mm7); /* mm7 = a3 a2 + rounder */ - paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder - psubd_r2r (mm5, mm7); // mm7 = a3-b3 a2-b2 + rounder + paddd_r2r (mm5, mm0); /* mm0 = a3+b3 a2+b2 + rounder */ + psubd_r2r (mm5, mm7); /* mm7 = a3-b3 a2-b2 + rounder */ } static inline void mmx_row_tail (int16_t * row, int store) { - psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ - psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 + psrad_i2r (ROW_SHIFT, mm7); /* mm7 = y4 y5 */ - packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ - packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 + packssdw_r2r (mm3, mm7); /* mm7 = y6 y7 y4 y5 */ - movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 - movq_r2r (mm7, mm4); // mm4 = y6 y7 y4 y5 + movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ + movq_r2r (mm7, mm4); /* mm4 = y6 y7 y4 y5 */ - pslld_i2r (16, mm7); // mm7 = y7 0 y5 0 + pslld_i2r (16, mm7); /* mm7 = y7 0 y5 0 */ - psrld_i2r (16, mm4); // mm4 = 0 y6 0 y4 + psrld_i2r (16, mm4); /* mm4 = 0 y6 0 y4 */ - por_r2r (mm4, mm7); // mm7 = y7 y6 y5 y4 + por_r2r (mm4, mm7); /* mm7 = y7 y6 y5 y4 */ /* slot */ - movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 + movq_r2m (mm7, *(row+store+4)); /* save y7 y6 y5 y4 */ } static inline void mmx_row_mid (int16_t * row, int store, int offset, const int16_t * table) { - movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 - psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ + psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ - movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 - psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 + movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ + psrad_i2r (ROW_SHIFT, mm7); /* mm7 = y4 y5 */ - packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 - movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ + movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ - packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 - movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + packssdw_r2r (mm3, mm7); /* mm7 = y6 y7 y4 y5 */ + movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ - movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 - movq_r2r (mm7, mm1); // mm1 = y6 y7 y4 y5 + movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ + movq_r2r (mm7, mm1); /* mm1 = y6 y7 y4 y5 */ - punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 - psrld_i2r (16, mm7); // mm7 = 0 y6 0 y4 + punpckldq_r2r (mm0, mm0); /* mm0 = x2 x0 x2 x0 */ + psrld_i2r (16, mm7); /* mm7 = 0 y6 0 y4 */ - movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 - pslld_i2r (16, mm1); // mm1 = y7 0 y5 0 + movq_m2r (*table, mm3); /* mm3 = C6 C4 C2 C4 */ + pslld_i2r (16, mm1); /* mm1 = y7 0 y5 0 */ - movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 - por_r2r (mm1, mm7); // mm7 = y7 y6 y5 y4 + movq_m2r (*(table+4), mm4); /* mm4 = -C2 -C4 C6 C4 */ + por_r2r (mm1, mm7); /* mm7 = y7 y6 y5 y4 */ - movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 - punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 + movq_m2r (*(table+8), mm1); /* mm1 = -C7 C3 C3 C1 */ + punpckhdq_r2r (mm2, mm2); /* mm2 = x6 x4 x6 x4 */ - movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 - pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 + movq_r2m (mm7, *(row+store+4)); /* save y7 y6 y5 y4 */ + pmaddwd_r2r (mm0, mm3); /* mm3 = C4*x0+C6*x2 C4*x0+C2*x2 */ } #if 0 -// C column IDCT - its just here to document the MMXEXT and MMX versions +/* C column IDCT - it is just here to document the MMXEXT and MMX versions */ static inline void idct_col (int16_t * col, int offset) { /* multiplication - as implemented on mmx */ @@ -384,7 +384,7 @@ static inline void idct_col (int16_t * col, int offset) #endif -// MMX column IDCT +/* MMX column IDCT */ static inline void idct_col (int16_t * col, int offset) { #define T1 13036 @@ -392,140 +392,140 @@ static inline void idct_col (int16_t * col, int offset) #define T3 43790 #define C4 23170 - static const short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; - static const short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; - static const short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; - static const short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; + static const short t1_vector[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; + static const short t2_vector[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; + static const short t3_vector[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; + static const short c4_vector[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; - /* column code adapted from peter gubanov */ + /* column code adapted from Peter Gubanov */ /* http://www.elecard.com/peter/idct.shtml */ - movq_m2r (*_T1, mm0); // mm0 = T1 + movq_m2r (*t1_vector, mm0); /* mm0 = T1 */ - movq_m2r (*(col+offset+1*8), mm1); // mm1 = x1 - movq_r2r (mm0, mm2); // mm2 = T1 + movq_m2r (*(col+offset+1*8), mm1); /* mm1 = x1 */ + movq_r2r (mm0, mm2); /* mm2 = T1 */ - movq_m2r (*(col+offset+7*8), mm4); // mm4 = x7 - pmulhw_r2r (mm1, mm0); // mm0 = T1*x1 + movq_m2r (*(col+offset+7*8), mm4); /* mm4 = x7 */ + pmulhw_r2r (mm1, mm0); /* mm0 = T1*x1 */ - movq_m2r (*_T3, mm5); // mm5 = T3 - pmulhw_r2r (mm4, mm2); // mm2 = T1*x7 + movq_m2r (*t3_vector, mm5); /* mm5 = T3 */ + pmulhw_r2r (mm4, mm2); /* mm2 = T1*x7 */ - movq_m2r (*(col+offset+5*8), mm6); // mm6 = x5 - movq_r2r (mm5, mm7); // mm7 = T3-1 + movq_m2r (*(col+offset+5*8), mm6); /* mm6 = x5 */ + movq_r2r (mm5, mm7); /* mm7 = T3-1 */ - movq_m2r (*(col+offset+3*8), mm3); // mm3 = x3 - psubsw_r2r (mm4, mm0); // mm0 = v17 + movq_m2r (*(col+offset+3*8), mm3); /* mm3 = x3 */ + psubsw_r2r (mm4, mm0); /* mm0 = v17 */ - movq_m2r (*_T2, mm4); // mm4 = T2 - pmulhw_r2r (mm3, mm5); // mm5 = (T3-1)*x3 + movq_m2r (*t2_vector, mm4); /* mm4 = T2 */ + pmulhw_r2r (mm3, mm5); /* mm5 = (T3-1)*x3 */ - paddsw_r2r (mm2, mm1); // mm1 = u17 - pmulhw_r2r (mm6, mm7); // mm7 = (T3-1)*x5 + paddsw_r2r (mm2, mm1); /* mm1 = u17 */ + pmulhw_r2r (mm6, mm7); /* mm7 = (T3-1)*x5 */ /* slot */ - movq_r2r (mm4, mm2); // mm2 = T2 - paddsw_r2r (mm3, mm5); // mm5 = T3*x3 + movq_r2r (mm4, mm2); /* mm2 = T2 */ + paddsw_r2r (mm3, mm5); /* mm5 = T3*x3 */ - pmulhw_m2r (*(col+offset+2*8), mm4);// mm4 = T2*x2 - paddsw_r2r (mm6, mm7); // mm7 = T3*x5 + pmulhw_m2r (*(col+offset+2*8), mm4);/* mm4 = T2*x2 */ + paddsw_r2r (mm6, mm7); /* mm7 = T3*x5 */ - psubsw_r2r (mm6, mm5); // mm5 = v35 - paddsw_r2r (mm3, mm7); // mm7 = u35 + psubsw_r2r (mm6, mm5); /* mm5 = v35 */ + paddsw_r2r (mm3, mm7); /* mm7 = u35 */ - movq_m2r (*(col+offset+6*8), mm3); // mm3 = x6 - movq_r2r (mm0, mm6); // mm6 = v17 + movq_m2r (*(col+offset+6*8), mm3); /* mm3 = x6 */ + movq_r2r (mm0, mm6); /* mm6 = v17 */ - pmulhw_r2r (mm3, mm2); // mm2 = T2*x6 - psubsw_r2r (mm5, mm0); // mm0 = b3 + pmulhw_r2r (mm3, mm2); /* mm2 = T2*x6 */ + psubsw_r2r (mm5, mm0); /* mm0 = b3 */ - psubsw_r2r (mm3, mm4); // mm4 = v26 - paddsw_r2r (mm6, mm5); // mm5 = v12 + psubsw_r2r (mm3, mm4); /* mm4 = v26 */ + paddsw_r2r (mm6, mm5); /* mm5 = v12 */ - movq_r2m (mm0, *(col+offset+3*8)); // save b3 in scratch0 - movq_r2r (mm1, mm6); // mm6 = u17 + movq_r2m (mm0, *(col+offset+3*8)); /* save b3 in scratch0 */ + movq_r2r (mm1, mm6); /* mm6 = u17 */ - paddsw_m2r (*(col+offset+2*8), mm2);// mm2 = u26 - paddsw_r2r (mm7, mm6); // mm6 = b0 + paddsw_m2r (*(col+offset+2*8), mm2);/* mm2 = u26 */ + paddsw_r2r (mm7, mm6); /* mm6 = b0 */ - psubsw_r2r (mm7, mm1); // mm1 = u12 - movq_r2r (mm1, mm7); // mm7 = u12 + psubsw_r2r (mm7, mm1); /* mm1 = u12 */ + movq_r2r (mm1, mm7); /* mm7 = u12 */ - movq_m2r (*(col+offset+0*8), mm3); // mm3 = x0 - paddsw_r2r (mm5, mm1); // mm1 = u12+v12 + movq_m2r (*(col+offset+0*8), mm3); /* mm3 = x0 */ + paddsw_r2r (mm5, mm1); /* mm1 = u12+v12 */ - movq_m2r (*_C4, mm0); // mm0 = C4/2 - psubsw_r2r (mm5, mm7); // mm7 = u12-v12 + movq_m2r (*c4_vector, mm0); /* mm0 = C4/2 */ + psubsw_r2r (mm5, mm7); /* mm7 = u12-v12 */ - movq_r2m (mm6, *(col+offset+5*8)); // save b0 in scratch1 - pmulhw_r2r (mm0, mm1); // mm1 = b1/2 + movq_r2m (mm6, *(col+offset+5*8)); /* save b0 in scratch1 */ + pmulhw_r2r (mm0, mm1); /* mm1 = b1/2 */ - movq_r2r (mm4, mm6); // mm6 = v26 - pmulhw_r2r (mm0, mm7); // mm7 = b2/2 + movq_r2r (mm4, mm6); /* mm6 = v26 */ + pmulhw_r2r (mm0, mm7); /* mm7 = b2/2 */ - movq_m2r (*(col+offset+4*8), mm5); // mm5 = x4 - movq_r2r (mm3, mm0); // mm0 = x0 + movq_m2r (*(col+offset+4*8), mm5); /* mm5 = x4 */ + movq_r2r (mm3, mm0); /* mm0 = x0 */ - psubsw_r2r (mm5, mm3); // mm3 = v04 - paddsw_r2r (mm5, mm0); // mm0 = u04 + psubsw_r2r (mm5, mm3); /* mm3 = v04 */ + paddsw_r2r (mm5, mm0); /* mm0 = u04 */ - paddsw_r2r (mm3, mm4); // mm4 = a1 - movq_r2r (mm0, mm5); // mm5 = u04 + paddsw_r2r (mm3, mm4); /* mm4 = a1 */ + movq_r2r (mm0, mm5); /* mm5 = u04 */ - psubsw_r2r (mm6, mm3); // mm3 = a2 - paddsw_r2r (mm2, mm5); // mm5 = a0 + psubsw_r2r (mm6, mm3); /* mm3 = a2 */ + paddsw_r2r (mm2, mm5); /* mm5 = a0 */ - paddsw_r2r (mm1, mm1); // mm1 = b1 - psubsw_r2r (mm2, mm0); // mm0 = a3 + paddsw_r2r (mm1, mm1); /* mm1 = b1 */ + psubsw_r2r (mm2, mm0); /* mm0 = a3 */ - paddsw_r2r (mm7, mm7); // mm7 = b2 - movq_r2r (mm3, mm2); // mm2 = a2 + paddsw_r2r (mm7, mm7); /* mm7 = b2 */ + movq_r2r (mm3, mm2); /* mm2 = a2 */ - movq_r2r (mm4, mm6); // mm6 = a1 - paddsw_r2r (mm7, mm3); // mm3 = a2+b2 + movq_r2r (mm4, mm6); /* mm6 = a1 */ + paddsw_r2r (mm7, mm3); /* mm3 = a2+b2 */ - psraw_i2r (COL_SHIFT, mm3); // mm3 = y2 - paddsw_r2r (mm1, mm4); // mm4 = a1+b1 + psraw_i2r (COL_SHIFT, mm3); /* mm3 = y2 */ + paddsw_r2r (mm1, mm4); /* mm4 = a1+b1 */ - psraw_i2r (COL_SHIFT, mm4); // mm4 = y1 - psubsw_r2r (mm1, mm6); // mm6 = a1-b1 + psraw_i2r (COL_SHIFT, mm4); /* mm4 = y1 */ + psubsw_r2r (mm1, mm6); /* mm6 = a1-b1 */ - movq_m2r (*(col+offset+5*8), mm1); // mm1 = b0 - psubsw_r2r (mm7, mm2); // mm2 = a2-b2 + movq_m2r (*(col+offset+5*8), mm1); /* mm1 = b0 */ + psubsw_r2r (mm7, mm2); /* mm2 = a2-b2 */ - psraw_i2r (COL_SHIFT, mm6); // mm6 = y6 - movq_r2r (mm5, mm7); // mm7 = a0 + psraw_i2r (COL_SHIFT, mm6); /* mm6 = y6 */ + movq_r2r (mm5, mm7); /* mm7 = a0 */ - movq_r2m (mm4, *(col+offset+1*8)); // save y1 - psraw_i2r (COL_SHIFT, mm2); // mm2 = y5 + movq_r2m (mm4, *(col+offset+1*8)); /* save y1 */ + psraw_i2r (COL_SHIFT, mm2); /* mm2 = y5 */ - movq_r2m (mm3, *(col+offset+2*8)); // save y2 - paddsw_r2r (mm1, mm5); // mm5 = a0+b0 + movq_r2m (mm3, *(col+offset+2*8)); /* save y2 */ + paddsw_r2r (mm1, mm5); /* mm5 = a0+b0 */ - movq_m2r (*(col+offset+3*8), mm4); // mm4 = b3 - psubsw_r2r (mm1, mm7); // mm7 = a0-b0 + movq_m2r (*(col+offset+3*8), mm4); /* mm4 = b3 */ + psubsw_r2r (mm1, mm7); /* mm7 = a0-b0 */ - psraw_i2r (COL_SHIFT, mm5); // mm5 = y0 - movq_r2r (mm0, mm3); // mm3 = a3 + psraw_i2r (COL_SHIFT, mm5); /* mm5 = y0 */ + movq_r2r (mm0, mm3); /* mm3 = a3 */ - movq_r2m (mm2, *(col+offset+5*8)); // save y5 - psubsw_r2r (mm4, mm3); // mm3 = a3-b3 + movq_r2m (mm2, *(col+offset+5*8)); /* save y5 */ + psubsw_r2r (mm4, mm3); /* mm3 = a3-b3 */ - psraw_i2r (COL_SHIFT, mm7); // mm7 = y7 - paddsw_r2r (mm0, mm4); // mm4 = a3+b3 + psraw_i2r (COL_SHIFT, mm7); /* mm7 = y7 */ + paddsw_r2r (mm0, mm4); /* mm4 = a3+b3 */ - movq_r2m (mm5, *(col+offset+0*8)); // save y0 - psraw_i2r (COL_SHIFT, mm3); // mm3 = y4 + movq_r2m (mm5, *(col+offset+0*8)); /* save y0 */ + psraw_i2r (COL_SHIFT, mm3); /* mm3 = y4 */ - movq_r2m (mm6, *(col+offset+6*8)); // save y6 - psraw_i2r (COL_SHIFT, mm4); // mm4 = y3 + movq_r2m (mm6, *(col+offset+6*8)); /* save y6 */ + psraw_i2r (COL_SHIFT, mm4); /* mm4 = y3 */ - movq_r2m (mm7, *(col+offset+7*8)); // save y7 + movq_r2m (mm7, *(col+offset+7*8)); /* save y7 */ - movq_r2m (mm3, *(col+offset+4*8)); // save y4 + movq_r2m (mm3, *(col+offset+4*8)); /* save y4 */ - movq_r2m (mm4, *(col+offset+3*8)); // save y3 + movq_r2m (mm4, *(col+offset+3*8)); /* save y3 */ #undef T1 #undef T2 diff --git a/contrib/ffmpeg/libavcodec/i386/idct_mmx_xvid.c b/contrib/ffmpeg/libavcodec/i386/idct_mmx_xvid.c index 85cfbc9cd..15e5290e7 100644 --- a/contrib/ffmpeg/libavcodec/i386/idct_mmx_xvid.c +++ b/contrib/ffmpeg/libavcodec/i386/idct_mmx_xvid.c @@ -1,56 +1,46 @@ -///**************************************************************************** -// * -// * XVID MPEG-4 VIDEO CODEC -// * - MMX and XMM forward discrete cosine transform - -// * -// * Copyright(C) 2001 Peter Ross <pross@xvid.org> -// * -// * 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 -// * -// * $Id: idct_mmx_xvid.c 6577 2006-10-07 15:30:46Z diego $ -// * -// ***************************************************************************/ - -// **************************************************************************** -// -// Originally provided by Intel at AP-922 -// http://developer.intel.com/vtune/cbts/strmsimd/922down.htm -// (See more app notes at http://developer.intel.com/vtune/cbts/strmsimd/appnotes.htm) -// but in a limited edition. -// New macro implements a column part for precise iDCT -// The routine precision now satisfies IEEE standard 1180-1990. -// -// Copyright(C) 2000-2001 Peter Gubanov <peter@elecard.net.ru> -// Rounding trick Copyright(C) 2000 Michel Lespinasse <walken@zoy.org> -// -// http://www.elecard.com/peter/idct.html -// http://www.linuxvideo.org/mpeg2dec/ -// -// ***************************************************************************/ -// -// These examples contain code fragments for first stage iDCT 8x8 -// (for rows) and first stage DCT 8x8 (for columns) -// - -// conversion to gcc syntax by michael niedermayer - +/* + * XVID MPEG-4 VIDEO CODEC + * - MMX and XMM forward discrete cosine transform - + * + * Copyright(C) 2001 Peter Ross <pross@xvid.org> + * + * Originally provided by Intel at AP-922 + * http://developer.intel.com/vtune/cbts/strmsimd/922down.htm + * (See more app notes at http://developer.intel.com/vtune/cbts/strmsimd/appnotes.htm) + * but in a limited edition. + * New macro implements a column part for precise iDCT + * The routine precision now satisfies IEEE standard 1180-1990. + * + * Copyright(C) 2000-2001 Peter Gubanov <peter@elecard.net.ru> + * Rounding trick Copyright(C) 2000 Michel Lespinasse <walken@zoy.org> + * + * http://www.elecard.com/peter/idct.html + * http://www.linuxvideo.org/mpeg2dec/ + * + * These examples contain code fragments for first stage iDCT 8x8 + * (for rows) and first stage DCT 8x8 (for columns) + * + * conversion to gcc syntax by 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 + */ #include <inttypes.h> -#include "../avcodec.h" +#include "avcodec.h" //============================================================================= // Macros and other preprocessor constants @@ -74,13 +64,13 @@ //----------------------------------------------------------------------------- -static const int16_t tg_1_16[4*4] attribute_used __attribute__ ((aligned(8))) = { +DECLARE_ALIGNED(8, static const int16_t, tg_1_16[4*4]) = { 13036,13036,13036,13036, // tg * (2<<16) + 0.5 27146,27146,27146,27146, // tg * (2<<16) + 0.5 -21746,-21746,-21746,-21746, // tg * (2<<16) + 0.5 23170,23170,23170,23170}; // cos * (2<<15) + 0.5 -static const int32_t rounder_0[2*8] attribute_used __attribute__ ((aligned(8))) = { +DECLARE_ALIGNED(8, static const int32_t, rounder_0[2*8]) = { 65536,65536, 3597,3597, 2260,2260, @@ -150,7 +140,7 @@ static const int32_t rounder_0[2*8] attribute_used __attribute__ ((aligned(8))) //----------------------------------------------------------------------------- // Table for rows 0,4 - constants are multiplied by cos_4_16 -static const int16_t tab_i_04_mmx[32*4] attribute_used __attribute__ ((aligned(8))) = { +DECLARE_ALIGNED(8, static const int16_t, tab_i_04_mmx[32*4]) = { 16384,16384,16384,-16384, // movq-> w06 w04 w02 w00 21407,8867,8867,-21407, // w07 w05 w03 w01 16384,-16384,16384,16384, // w14 w12 w10 w08 @@ -192,7 +182,7 @@ static const int16_t tab_i_04_mmx[32*4] attribute_used __attribute__ ((aligned(8 //----------------------------------------------------------------------------- // %3 for rows 0,4 - constants are multiplied by cos_4_16 -static const int16_t tab_i_04_xmm[32*4] attribute_used __attribute__ ((aligned(8))) = { +DECLARE_ALIGNED(8, static const int16_t, tab_i_04_xmm[32*4]) = { 16384,21407,16384,8867, // movq-> w05 w04 w01 w00 16384,8867,-16384,-21407, // w07 w06 w03 w02 16384,-8867,16384,-21407, // w13 w12 w09 w08 diff --git a/contrib/ffmpeg/libavcodec/i386/mathops.h b/contrib/ffmpeg/libavcodec/i386/mathops.h index 3553a4025..51d59396e 100644 --- a/contrib/ffmpeg/libavcodec/i386/mathops.h +++ b/contrib/ffmpeg/libavcodec/i386/mathops.h @@ -19,6 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_I386_MATHOPS_H +#define FFMPEG_I386_MATHOPS_H + #ifdef FRAC_BITS # define MULL(ra, rb) \ ({ int rt, dummy; asm (\ @@ -39,3 +42,4 @@ asm ("imull %2\n\t" : "=A"(rt) : "a" (ra), "g" (rb));\ rt; }) +#endif /* FFMPEG_I386_MATHOPS_H */ diff --git a/contrib/ffmpeg/libavcodec/i386/mmx.h b/contrib/ffmpeg/libavcodec/i386/mmx.h index 41aae6c21..2e029d1aa 100644 --- a/contrib/ffmpeg/libavcodec/i386/mmx.h +++ b/contrib/ffmpeg/libavcodec/i386/mmx.h @@ -18,8 +18,10 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVCODEC_I386MMX_H -#define AVCODEC_I386MMX_H +#ifndef FFMPEG_MMX_H +#define FFMPEG_MMX_H + +#warning Everything in this header is deprecated, use plain asm()! New code using this header will be rejected. /* * The type of an value that fits in an MMX register (note that long @@ -280,4 +282,4 @@ typedef union { #define punpckhqdq_r2r(regs,regd) mmx_r2r (punpckhqdq, regs, regd) -#endif /* AVCODEC_I386MMX_H */ +#endif /* FFMPEG_MMX_H */ diff --git a/contrib/ffmpeg/libavcodec/i386/motion_est_mmx.c b/contrib/ffmpeg/libavcodec/i386/motion_est_mmx.c index e33870e0f..888d891d9 100644 --- a/contrib/ffmpeg/libavcodec/i386/motion_est_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/motion_est_mmx.c @@ -3,6 +3,8 @@ * Copyright (c) 2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer * + * mostly by Michael Niedermayer <michaelni@gmx.at> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,19 +20,17 @@ * 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 - * - * mostly by Michael Niedermayer <michaelni@gmx.at> */ -#include "../dsputil.h" +#include "dsputil.h" #include "x86_cpu.h" -static const __attribute__ ((aligned(8))) uint64_t round_tab[3]={ +DECLARE_ASM_CONST(8, uint64_t, round_tab[3])={ 0x0000000000000000ULL, 0x0001000100010001ULL, 0x0002000200020002ULL, }; -static attribute_used __attribute__ ((aligned(8))) uint64_t bone= 0x0101010101010101LL; +DECLARE_ASM_CONST(8, uint64_t, bone)= 0x0101010101010101LL; static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) { @@ -70,86 +70,127 @@ static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) static inline void sad8_1_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) { - long len= -(stride*h); asm volatile( ASMALIGN(4) "1: \n\t" - "movq (%1, %%"REG_a"), %%mm0 \n\t" - "movq (%2, %%"REG_a"), %%mm2 \n\t" - "psadbw %%mm2, %%mm0 \n\t" - "add %3, %%"REG_a" \n\t" - "movq (%1, %%"REG_a"), %%mm1 \n\t" - "movq (%2, %%"REG_a"), %%mm3 \n\t" - "psadbw %%mm1, %%mm3 \n\t" - "paddw %%mm3, %%mm0 \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "psadbw (%2), %%mm0 \n\t" + "psadbw (%2, %3), %%mm1 \n\t" "paddw %%mm0, %%mm6 \n\t" - "add %3, %%"REG_a" \n\t" - " js 1b \n\t" - : "+a" (len) - : "r" (blk1 - len), "r" (blk2 - len), "r" ((long)stride) + "paddw %%mm1, %%mm6 \n\t" + "lea (%1,%3,2), %1 \n\t" + "lea (%2,%3,2), %2 \n\t" + "sub $2, %0 \n\t" + " jg 1b \n\t" + : "+r" (h), "+r" (blk1), "+r" (blk2) + : "r" ((long)stride) ); } -static inline void sad8_2_mmx2(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, int stride, int h) +static int sad16_sse2(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h) { - long len= -(stride*h); + int ret; asm volatile( + "pxor %%xmm6, %%xmm6 \n\t" ASMALIGN(4) "1: \n\t" - "movq (%1, %%"REG_a"), %%mm0 \n\t" - "movq (%2, %%"REG_a"), %%mm2 \n\t" - "pavgb %%mm2, %%mm0 \n\t" - "movq (%3, %%"REG_a"), %%mm2 \n\t" - "psadbw %%mm2, %%mm0 \n\t" - "add %4, %%"REG_a" \n\t" - "movq (%1, %%"REG_a"), %%mm1 \n\t" - "movq (%2, %%"REG_a"), %%mm3 \n\t" - "pavgb %%mm1, %%mm3 \n\t" - "movq (%3, %%"REG_a"), %%mm1 \n\t" - "psadbw %%mm1, %%mm3 \n\t" - "paddw %%mm3, %%mm0 \n\t" + "movdqu (%1), %%xmm0 \n\t" + "movdqu (%1, %3), %%xmm1 \n\t" + "psadbw (%2), %%xmm0 \n\t" + "psadbw (%2, %3), %%xmm1 \n\t" + "paddw %%xmm0, %%xmm6 \n\t" + "paddw %%xmm1, %%xmm6 \n\t" + "lea (%1,%3,2), %1 \n\t" + "lea (%2,%3,2), %2 \n\t" + "sub $2, %0 \n\t" + " jg 1b \n\t" + : "+r" (h), "+r" (blk1), "+r" (blk2) + : "r" ((long)stride) + ); + asm volatile( + "movhlps %%xmm6, %%xmm0 \n\t" + "paddw %%xmm0, %%xmm6 \n\t" + "movd %%xmm6, %0 \n\t" + : "=r"(ret) + ); + return ret; +} + +static inline void sad8_x2a_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) +{ + asm volatile( + ASMALIGN(4) + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "pavgb 1(%1), %%mm0 \n\t" + "pavgb 1(%1, %3), %%mm1 \n\t" + "psadbw (%2), %%mm0 \n\t" + "psadbw (%2, %3), %%mm1 \n\t" "paddw %%mm0, %%mm6 \n\t" - "add %4, %%"REG_a" \n\t" - " js 1b \n\t" - : "+a" (len) - : "r" (blk1a - len), "r" (blk1b -len), "r" (blk2 - len), "r" ((long)stride) + "paddw %%mm1, %%mm6 \n\t" + "lea (%1,%3,2), %1 \n\t" + "lea (%2,%3,2), %2 \n\t" + "sub $2, %0 \n\t" + " jg 1b \n\t" + : "+r" (h), "+r" (blk1), "+r" (blk2) + : "r" ((long)stride) ); } -static inline void sad8_4_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) -{ //FIXME reuse src - long len= -(stride*h); +static inline void sad8_y2a_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) +{ asm volatile( + "movq (%1), %%mm0 \n\t" + "add %3, %1 \n\t" ASMALIGN(4) + "1: \n\t" + "movq (%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "pavgb %%mm1, %%mm0 \n\t" + "pavgb %%mm2, %%mm1 \n\t" + "psadbw (%2), %%mm0 \n\t" + "psadbw (%2, %3), %%mm1 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "paddw %%mm1, %%mm6 \n\t" + "movq %%mm2, %%mm0 \n\t" + "lea (%1,%3,2), %1 \n\t" + "lea (%2,%3,2), %2 \n\t" + "sub $2, %0 \n\t" + " jg 1b \n\t" + : "+r" (h), "+r" (blk1), "+r" (blk2) + : "r" ((long)stride) + ); +} + +static inline void sad8_4_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) +{ + asm volatile( "movq "MANGLE(bone)", %%mm5 \n\t" + "movq (%1), %%mm0 \n\t" + "pavgb 1(%1), %%mm0 \n\t" + "add %3, %1 \n\t" + ASMALIGN(4) "1: \n\t" - "movq (%1, %%"REG_a"), %%mm0 \n\t" - "movq (%2, %%"REG_a"), %%mm2 \n\t" - "movq 1(%1, %%"REG_a"), %%mm1 \n\t" - "movq 1(%2, %%"REG_a"), %%mm3 \n\t" - "pavgb %%mm2, %%mm0 \n\t" - "pavgb %%mm1, %%mm3 \n\t" - "psubusb %%mm5, %%mm3 \n\t" - "pavgb %%mm3, %%mm0 \n\t" - "movq (%3, %%"REG_a"), %%mm2 \n\t" - "psadbw %%mm2, %%mm0 \n\t" - "add %4, %%"REG_a" \n\t" - "movq (%1, %%"REG_a"), %%mm1 \n\t" - "movq (%2, %%"REG_a"), %%mm3 \n\t" - "movq 1(%1, %%"REG_a"), %%mm2 \n\t" - "movq 1(%2, %%"REG_a"), %%mm4 \n\t" - "pavgb %%mm3, %%mm1 \n\t" - "pavgb %%mm4, %%mm2 \n\t" - "psubusb %%mm5, %%mm2 \n\t" - "pavgb %%mm1, %%mm2 \n\t" - "movq (%3, %%"REG_a"), %%mm1 \n\t" - "psadbw %%mm1, %%mm2 \n\t" - "paddw %%mm2, %%mm0 \n\t" + "movq (%1), %%mm1 \n\t" + "movq (%1,%3), %%mm2 \n\t" + "pavgb 1(%1), %%mm1 \n\t" + "pavgb 1(%1,%3), %%mm2 \n\t" + "psubusb %%mm5, %%mm1 \n\t" + "pavgb %%mm1, %%mm0 \n\t" + "pavgb %%mm2, %%mm1 \n\t" + "psadbw (%2), %%mm0 \n\t" + "psadbw (%2,%3), %%mm1 \n\t" "paddw %%mm0, %%mm6 \n\t" - "add %4, %%"REG_a" \n\t" - " js 1b \n\t" - : "+a" (len) - : "r" (blk1 - len), "r" (blk1 - len + stride), "r" (blk2 - len), "r" ((long)stride) + "paddw %%mm1, %%mm6 \n\t" + "movq %%mm2, %%mm0 \n\t" + "lea (%1,%3,2), %1 \n\t" + "lea (%2,%3,2), %2 \n\t" + "sub $2, %0 \n\t" + " jg 1b \n\t" + : "+r" (h), "+r" (blk1), "+r" (blk2) + : "r" ((long)stride) ); } @@ -195,45 +236,48 @@ static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) { long len= -(stride*h); asm volatile( - ASMALIGN(4) - "1: \n\t" "movq (%1, %%"REG_a"), %%mm0 \n\t" - "movq (%2, %%"REG_a"), %%mm1 \n\t" - "movq %%mm0, %%mm4 \n\t" - "movq %%mm1, %%mm2 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - "punpckhbw %%mm7, %%mm4 \n\t" - "punpckhbw %%mm7, %%mm2 \n\t" - "paddw %%mm1, %%mm0 \n\t" - "paddw %%mm2, %%mm4 \n\t" "movq 1(%1, %%"REG_a"), %%mm2 \n\t" - "movq 1(%2, %%"REG_a"), %%mm3 \n\t" - "movq %%mm2, %%mm1 \n\t" - "punpcklbw %%mm7, %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" "punpckhbw %%mm7, %%mm1 \n\t" - "paddw %%mm0, %%mm2 \n\t" - "paddw %%mm4, %%mm1 \n\t" - "movq %%mm3, %%mm4 \n\t" - "punpcklbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm4 \n\t" - "paddw %%mm3, %%mm2 \n\t" - "paddw %%mm4, %%mm1 \n\t" - "movq (%3, %%"REG_a"), %%mm3 \n\t" - "movq (%3, %%"REG_a"), %%mm4 \n\t" - "paddw %%mm5, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm3, %%mm1 \n\t" + ASMALIGN(4) + "1: \n\t" + "movq (%2, %%"REG_a"), %%mm2 \n\t" + "movq 1(%2, %%"REG_a"), %%mm4 \n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddw %%mm4, %%mm2 \n\t" + "paddw %%mm5, %%mm3 \n\t" + "movq 16+"MANGLE(round_tab)", %%mm5 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm3, %%mm1 \n\t" + "paddw %%mm5, %%mm0 \n\t" "paddw %%mm5, %%mm1 \n\t" - "psrlw $2, %%mm2 \n\t" + "movq (%3, %%"REG_a"), %%mm4 \n\t" + "movq (%3, %%"REG_a"), %%mm5 \n\t" + "psrlw $2, %%mm0 \n\t" "psrlw $2, %%mm1 \n\t" - "packuswb %%mm1, %%mm2 \n\t" - "psubusb %%mm2, %%mm3 \n\t" - "psubusb %%mm4, %%mm2 \n\t" - "por %%mm3, %%mm2 \n\t" - "movq %%mm2, %%mm0 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "psubusb %%mm0, %%mm4 \n\t" + "psubusb %%mm5, %%mm0 \n\t" + "por %%mm4, %%mm0 \n\t" + "movq %%mm0, %%mm4 \n\t" "punpcklbw %%mm7, %%mm0 \n\t" - "punpckhbw %%mm7, %%mm2 \n\t" - "paddw %%mm2, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm4 \n\t" "paddw %%mm0, %%mm6 \n\t" + "paddw %%mm4, %%mm6 \n\t" + "movq %%mm2, %%mm0 \n\t" + "movq %%mm3, %%mm1 \n\t" "add %4, %%"REG_a" \n\t" " js 1b \n\t" : "+a" (len) @@ -267,6 +311,15 @@ static inline int sum_mmx2(void) return ret; } +static inline void sad8_x2a_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) +{ + sad8_2_mmx(blk1, blk1+1, blk2, stride, h); +} +static inline void sad8_y2a_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) +{ + sad8_2_mmx(blk1, blk1+stride, blk2, stride, h); +} + #define PIX_SAD(suf)\ static int sad8_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\ @@ -288,7 +341,7 @@ static int sad8_x2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, in :: "m"(round_tab[1]) \ );\ \ - sad8_2_ ## suf(blk1, blk1+1, blk2, stride, 8);\ + sad8_x2a_ ## suf(blk1, blk2, stride, 8);\ \ return sum_ ## suf();\ }\ @@ -302,7 +355,7 @@ static int sad8_y2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, in :: "m"(round_tab[1]) \ );\ \ - sad8_2_ ## suf(blk1, blk1+stride, blk2, stride, 8);\ + sad8_y2a_ ## suf(blk1, blk2, stride, 8);\ \ return sum_ ## suf();\ }\ @@ -312,9 +365,7 @@ static int sad8_xy2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, i assert(h==8);\ asm volatile("pxor %%mm7, %%mm7 \n\t"\ "pxor %%mm6, %%mm6 \n\t"\ - "movq %0, %%mm5 \n\t"\ - :: "m"(round_tab[2]) \ - );\ + ::);\ \ sad8_4_ ## suf(blk1, blk2, stride, 8);\ \ @@ -339,8 +390,8 @@ static int sad16_x2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, i :: "m"(round_tab[1]) \ );\ \ - sad8_2_ ## suf(blk1 , blk1+1, blk2 , stride, h);\ - sad8_2_ ## suf(blk1+8, blk1+9, blk2+8, stride, h);\ + sad8_x2a_ ## suf(blk1 , blk2 , stride, h);\ + sad8_x2a_ ## suf(blk1+8, blk2+8, stride, h);\ \ return sum_ ## suf();\ }\ @@ -352,8 +403,8 @@ static int sad16_y2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, i :: "m"(round_tab[1]) \ );\ \ - sad8_2_ ## suf(blk1 , blk1+stride, blk2 , stride, h);\ - sad8_2_ ## suf(blk1+8, blk1+stride+8,blk2+8, stride, h);\ + sad8_y2a_ ## suf(blk1 , blk2 , stride, h);\ + sad8_y2a_ ## suf(blk1+8, blk2+8, stride, h);\ \ return sum_ ## suf();\ }\ @@ -361,9 +412,7 @@ static int sad16_xy2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, {\ asm volatile("pxor %%mm7, %%mm7 \n\t"\ "pxor %%mm6, %%mm6 \n\t"\ - "movq %0, %%mm5 \n\t"\ - :: "m"(round_tab[2]) \ - );\ + ::);\ \ sad8_4_ ## suf(blk1 , blk2 , stride, h);\ sad8_4_ ## suf(blk1+8, blk2+8, stride, h);\ @@ -405,4 +454,7 @@ void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx) c->pix_abs[1][3] = sad8_xy2_mmx2; } } + if ((mm_flags & MM_SSE2) && !(mm_flags & MM_3DNOW)) { + c->sad[0]= sad16_sse2; + } } diff --git a/contrib/ffmpeg/libavcodec/i386/mpegvideo_mmx.c b/contrib/ffmpeg/libavcodec/i386/mpegvideo_mmx.c index 1b7b1c19f..90b553aa2 100644 --- a/contrib/ffmpeg/libavcodec/i386/mpegvideo_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/mpegvideo_mmx.c @@ -2,6 +2,9 @@ * The simplest mpeg encoder (well, it was the simplest!) * Copyright (c) 2000,2001 Fabrice Bellard. * + * Optimized for ia32 CPUs by Nick Kurshev <nickols_k@mail.ru> + * h263, mpeg1, mpeg2 dequantizer & draw_edges by Michael Niedermayer <michaelni@gmx.at> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -17,21 +20,16 @@ * 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 - * - * Optimized for ia32 cpus by Nick Kurshev <nickols_k@mail.ru> - * h263, mpeg1, mpeg2 dequantizer & draw_edges by Michael Niedermayer <michaelni@gmx.at> */ -#include "../dsputil.h" -#include "../mpegvideo.h" -#include "../avcodec.h" +#include "dsputil.h" +#include "dsputil_mmx.h" +#include "mpegvideo.h" +#include "avcodec.h" #include "x86_cpu.h" extern uint16_t inv_zigzag_direct16[64]; -static const unsigned long long int mm_wabs __attribute__ ((aligned(8))) = 0xffffffffffffffffULL; -static const unsigned long long int mm_wone __attribute__ ((aligned(8))) = 0x0001000100010001ULL; - static void dct_unquantize_h263_intra_mmx(MpegEncContext *s, DCTELEM *block, int n, int qscale) @@ -179,7 +177,7 @@ asm volatile( if (level < -2048 || level > 2047) fprintf(stderr, "unquant error %d %d\n", i, level); #endif - We can suppose that result of two multiplications can't be greate of 0xFFFF + We can suppose that result of two multiplications can't be greater than 0xFFFF i.e. is 16-bit, so we use here only PMULLW instruction and can avoid a complex multiplication. ===================================================== @@ -397,7 +395,7 @@ asm volatile( : "%"REG_a, "memory" ); block[0]= block0; - //Note, we dont do mismatch control for intra as errors cannot accumulate + //Note, we do not do mismatch control for intra as errors cannot accumulate } static void dct_unquantize_mpeg2_inter_mmx(MpegEncContext *s, @@ -673,6 +671,12 @@ static void denoise_dct_sse2(MpegEncContext *s, DCTELEM *block){ ); } +#ifdef HAVE_SSSE3 +#define HAVE_SSSE3_BAK +#endif +#undef HAVE_SSSE3 + +#undef HAVE_SSE2 #undef HAVE_MMX2 #define RENAME(a) a ## _MMX #define RENAMEl(a) a ## _mmx @@ -685,12 +689,22 @@ static void denoise_dct_sse2(MpegEncContext *s, DCTELEM *block){ #define RENAMEl(a) a ## _mmx2 #include "mpegvideo_mmx_template.c" +#define HAVE_SSE2 #undef RENAME #undef RENAMEl #define RENAME(a) a ## _SSE2 #define RENAMEl(a) a ## _sse2 #include "mpegvideo_mmx_template.c" +#ifdef HAVE_SSSE3_BAK +#define HAVE_SSSE3 +#undef RENAME +#undef RENAMEl +#define RENAME(a) a ## _SSSE3 +#define RENAMEl(a) a ## _sse2 +#include "mpegvideo_mmx_template.c" +#endif + void MPV_common_init_mmx(MpegEncContext *s) { if (mm_flags & MM_MMX) { @@ -713,6 +727,11 @@ void MPV_common_init_mmx(MpegEncContext *s) } if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){ +#ifdef HAVE_SSSE3 + if(mm_flags & MM_SSSE3){ + s->dct_quantize= dct_quantize_SSSE3; + } else +#endif if(mm_flags & MM_SSE2){ s->dct_quantize= dct_quantize_SSE2; } else if(mm_flags & MM_MMXEXT){ diff --git a/contrib/ffmpeg/libavcodec/i386/mpegvideo_mmx_template.c b/contrib/ffmpeg/libavcodec/i386/mpegvideo_mmx_template.c index d59b6efd9..9c9c763b2 100644 --- a/contrib/ffmpeg/libavcodec/i386/mpegvideo_mmx_template.c +++ b/contrib/ffmpeg/libavcodec/i386/mpegvideo_mmx_template.c @@ -19,47 +19,91 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#undef MMREG_WIDTH +#undef MM +#undef MOVQ #undef SPREADW #undef PMAXW #undef PMAX -#ifdef HAVE_MMX2 -#define SPREADW(a) "pshufw $0, " #a ", " #a " \n\t" -#define PMAXW(a,b) "pmaxsw " #a ", " #b " \n\t" +#undef SAVE_SIGN +#undef RESTORE_SIGN + +#if defined(HAVE_SSE2) +#define MMREG_WIDTH "16" +#define MM "%%xmm" +#define MOVQ "movdqa" +#define SPREADW(a) \ + "pshuflw $0, "a", "a" \n\t"\ + "punpcklwd "a", "a" \n\t" +#define PMAXW(a,b) "pmaxsw "a", "b" \n\t" #define PMAX(a,b) \ - "pshufw $0x0E," #a ", " #b " \n\t"\ + "movhlps "a", "b" \n\t"\ PMAXW(b, a)\ - "pshufw $0x01," #a ", " #b " \n\t"\ + "pshuflw $0x0E, "a", "b" \n\t"\ + PMAXW(b, a)\ + "pshuflw $0x01, "a", "b" \n\t"\ + PMAXW(b, a) +#else +#define MMREG_WIDTH "8" +#define MM "%%mm" +#define MOVQ "movq" +#if defined(HAVE_MMX2) +#define SPREADW(a) "pshufw $0, "a", "a" \n\t" +#define PMAXW(a,b) "pmaxsw "a", "b" \n\t" +#define PMAX(a,b) \ + "pshufw $0x0E, "a", "b" \n\t"\ + PMAXW(b, a)\ + "pshufw $0x01, "a", "b" \n\t"\ PMAXW(b, a) #else #define SPREADW(a) \ - "punpcklwd " #a ", " #a " \n\t"\ - "punpcklwd " #a ", " #a " \n\t" + "punpcklwd "a", "a" \n\t"\ + "punpcklwd "a", "a" \n\t" #define PMAXW(a,b) \ - "psubusw " #a ", " #b " \n\t"\ - "paddw " #a ", " #b " \n\t" + "psubusw "a", "b" \n\t"\ + "paddw "a", "b" \n\t" #define PMAX(a,b) \ - "movq " #a ", " #b " \n\t"\ - "psrlq $32, " #a " \n\t"\ + "movq "a", "b" \n\t"\ + "psrlq $32, "a" \n\t"\ PMAXW(b, a)\ - "movq " #a ", " #b " \n\t"\ - "psrlq $16, " #a " \n\t"\ + "movq "a", "b" \n\t"\ + "psrlq $16, "a" \n\t"\ PMAXW(b, a) #endif +#endif + +#ifdef HAVE_SSSE3 +#define SAVE_SIGN(a,b) \ + "movdqa "b", "a" \n\t"\ + "pabsw "b", "b" \n\t" +#define RESTORE_SIGN(a,b) \ + "psignw "a", "b" \n\t" +#else +#define SAVE_SIGN(a,b) \ + "pxor "a", "a" \n\t"\ + "pcmpgtw "b", "a" \n\t" /* block[i] <= 0 ? 0xFF : 0x00 */\ + "pxor "a", "b" \n\t"\ + "psubw "a", "b" \n\t" /* ABS(block[i]) */ +#define RESTORE_SIGN(a,b) \ + "pxor "a", "b" \n\t"\ + "psubw "a", "b" \n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) +#endif static int RENAME(dct_quantize)(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow) { long last_non_zero_p1; - int level=0, q; //=0 is cuz gcc says uninitalized ... + int level=0, q; //=0 is cuz gcc says uninitialized ... const uint16_t *qmat, *bias; - DECLARE_ALIGNED_8(int16_t, temp_block[64]); + DECLARE_ALIGNED_16(int16_t, temp_block[64]); assert((7&(int)(&temp_block[0])) == 0); //did gcc align it correctly? //s->fdct (block); - RENAMEl(ff_fdct) (block); //cant be anything else ... + RENAMEl(ff_fdct) (block); //cannot be anything else ... if(s->dct_error_sum) s->denoise_dct(s, block); @@ -106,98 +150,82 @@ static int RENAME(dct_quantize)(MpegEncContext *s, if((s->out_format == FMT_H263 || s->out_format == FMT_H261) && s->mpeg_quant==0){ asm volatile( - "movd %%"REG_a", %%mm3 \n\t" // last_non_zero_p1 - SPREADW(%%mm3) - "pxor %%mm7, %%mm7 \n\t" // 0 - "pxor %%mm4, %%mm4 \n\t" // 0 - "movq (%2), %%mm5 \n\t" // qmat[0] - "pxor %%mm6, %%mm6 \n\t" - "psubw (%3), %%mm6 \n\t" // -bias[0] + "movd %%"REG_a", "MM"3 \n\t" // last_non_zero_p1 + SPREADW(MM"3") + "pxor "MM"7, "MM"7 \n\t" // 0 + "pxor "MM"4, "MM"4 \n\t" // 0 + MOVQ" (%2), "MM"5 \n\t" // qmat[0] + "pxor "MM"6, "MM"6 \n\t" + "psubw (%3), "MM"6 \n\t" // -bias[0] "mov $-128, %%"REG_a" \n\t" ASMALIGN(4) "1: \n\t" - "pxor %%mm1, %%mm1 \n\t" // 0 - "movq (%1, %%"REG_a"), %%mm0 \n\t" // block[i] - "pcmpgtw %%mm0, %%mm1 \n\t" // block[i] <= 0 ? 0xFF : 0x00 - "pxor %%mm1, %%mm0 \n\t" - "psubw %%mm1, %%mm0 \n\t" // ABS(block[i]) - "psubusw %%mm6, %%mm0 \n\t" // ABS(block[i]) + bias[0] - "pmulhw %%mm5, %%mm0 \n\t" // (ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16 - "por %%mm0, %%mm4 \n\t" - "pxor %%mm1, %%mm0 \n\t" - "psubw %%mm1, %%mm0 \n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) - "movq %%mm0, (%5, %%"REG_a") \n\t" - "pcmpeqw %%mm7, %%mm0 \n\t" // out==0 ? 0xFF : 0x00 - "movq (%4, %%"REG_a"), %%mm1 \n\t" - "movq %%mm7, (%1, %%"REG_a") \n\t" // 0 - "pandn %%mm1, %%mm0 \n\t" - PMAXW(%%mm0, %%mm3) - "add $8, %%"REG_a" \n\t" + MOVQ" (%1, %%"REG_a"), "MM"0 \n\t" // block[i] + SAVE_SIGN(MM"1", MM"0") // ABS(block[i]) + "psubusw "MM"6, "MM"0 \n\t" // ABS(block[i]) + bias[0] + "pmulhw "MM"5, "MM"0 \n\t" // (ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16 + "por "MM"0, "MM"4 \n\t" + RESTORE_SIGN(MM"1", MM"0") // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) + MOVQ" "MM"0, (%5, %%"REG_a") \n\t" + "pcmpeqw "MM"7, "MM"0 \n\t" // out==0 ? 0xFF : 0x00 + MOVQ" (%4, %%"REG_a"), "MM"1 \n\t" + MOVQ" "MM"7, (%1, %%"REG_a") \n\t" // 0 + "pandn "MM"1, "MM"0 \n\t" + PMAXW(MM"0", MM"3") + "add $"MMREG_WIDTH", %%"REG_a" \n\t" " js 1b \n\t" - PMAX(%%mm3, %%mm0) - "movd %%mm3, %%"REG_a" \n\t" + PMAX(MM"3", MM"0") + "movd "MM"3, %%"REG_a" \n\t" "movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1 : "+a" (last_non_zero_p1) : "r" (block+64), "r" (qmat), "r" (bias), "r" (inv_zigzag_direct16+64), "r" (temp_block+64) ); - // note the asm is split cuz gcc doesnt like that many operands ... - asm volatile( - "movd %1, %%mm1 \n\t" // max_qcoeff - SPREADW(%%mm1) - "psubusw %%mm1, %%mm4 \n\t" - "packuswb %%mm4, %%mm4 \n\t" - "movd %%mm4, %0 \n\t" // *overflow - : "=g" (*overflow) - : "g" (s->max_qcoeff) - ); }else{ // FMT_H263 asm volatile( - "movd %%"REG_a", %%mm3 \n\t" // last_non_zero_p1 - SPREADW(%%mm3) - "pxor %%mm7, %%mm7 \n\t" // 0 - "pxor %%mm4, %%mm4 \n\t" // 0 + "movd %%"REG_a", "MM"3 \n\t" // last_non_zero_p1 + SPREADW(MM"3") + "pxor "MM"7, "MM"7 \n\t" // 0 + "pxor "MM"4, "MM"4 \n\t" // 0 "mov $-128, %%"REG_a" \n\t" ASMALIGN(4) "1: \n\t" - "pxor %%mm1, %%mm1 \n\t" // 0 - "movq (%1, %%"REG_a"), %%mm0 \n\t" // block[i] - "pcmpgtw %%mm0, %%mm1 \n\t" // block[i] <= 0 ? 0xFF : 0x00 - "pxor %%mm1, %%mm0 \n\t" - "psubw %%mm1, %%mm0 \n\t" // ABS(block[i]) - "movq (%3, %%"REG_a"), %%mm6 \n\t" // bias[0] - "paddusw %%mm6, %%mm0 \n\t" // ABS(block[i]) + bias[0] - "movq (%2, %%"REG_a"), %%mm5 \n\t" // qmat[i] - "pmulhw %%mm5, %%mm0 \n\t" // (ABS(block[i])*qmat[0] + bias[0]*qmat[0])>>16 - "por %%mm0, %%mm4 \n\t" - "pxor %%mm1, %%mm0 \n\t" - "psubw %%mm1, %%mm0 \n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) - "movq %%mm0, (%5, %%"REG_a") \n\t" - "pcmpeqw %%mm7, %%mm0 \n\t" // out==0 ? 0xFF : 0x00 - "movq (%4, %%"REG_a"), %%mm1 \n\t" - "movq %%mm7, (%1, %%"REG_a") \n\t" // 0 - "pandn %%mm1, %%mm0 \n\t" - PMAXW(%%mm0, %%mm3) - "add $8, %%"REG_a" \n\t" + MOVQ" (%1, %%"REG_a"), "MM"0 \n\t" // block[i] + SAVE_SIGN(MM"1", MM"0") // ABS(block[i]) + MOVQ" (%3, %%"REG_a"), "MM"6 \n\t" // bias[0] + "paddusw "MM"6, "MM"0 \n\t" // ABS(block[i]) + bias[0] + MOVQ" (%2, %%"REG_a"), "MM"5 \n\t" // qmat[i] + "pmulhw "MM"5, "MM"0 \n\t" // (ABS(block[i])*qmat[0] + bias[0]*qmat[0])>>16 + "por "MM"0, "MM"4 \n\t" + RESTORE_SIGN(MM"1", MM"0") // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) + MOVQ" "MM"0, (%5, %%"REG_a") \n\t" + "pcmpeqw "MM"7, "MM"0 \n\t" // out==0 ? 0xFF : 0x00 + MOVQ" (%4, %%"REG_a"), "MM"1 \n\t" + MOVQ" "MM"7, (%1, %%"REG_a") \n\t" // 0 + "pandn "MM"1, "MM"0 \n\t" + PMAXW(MM"0", MM"3") + "add $"MMREG_WIDTH", %%"REG_a" \n\t" " js 1b \n\t" - PMAX(%%mm3, %%mm0) - "movd %%mm3, %%"REG_a" \n\t" + PMAX(MM"3", MM"0") + "movd "MM"3, %%"REG_a" \n\t" "movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1 : "+a" (last_non_zero_p1) : "r" (block+64), "r" (qmat+64), "r" (bias+64), "r" (inv_zigzag_direct16+64), "r" (temp_block+64) ); - // note the asm is split cuz gcc doesnt like that many operands ... - asm volatile( - "movd %1, %%mm1 \n\t" // max_qcoeff - SPREADW(%%mm1) - "psubusw %%mm1, %%mm4 \n\t" - "packuswb %%mm4, %%mm4 \n\t" - "movd %%mm4, %0 \n\t" // *overflow + } + asm volatile( + "movd %1, "MM"1 \n\t" // max_qcoeff + SPREADW(MM"1") + "psubusw "MM"1, "MM"4 \n\t" + "packuswb "MM"4, "MM"4 \n\t" +#ifdef HAVE_SSE2 + "packuswb "MM"4, "MM"4 \n\t" +#endif + "movd "MM"4, %0 \n\t" // *overflow : "=g" (*overflow) : "g" (s->max_qcoeff) - ); - } + ); if(s->mb_intra) block[0]= level; else block[0]= temp_block[0]; diff --git a/contrib/ffmpeg/libavcodec/i386/simple_idct_mmx.c b/contrib/ffmpeg/libavcodec/i386/simple_idct_mmx.c index 525ef34f7..059f473a0 100644 --- a/contrib/ffmpeg/libavcodec/i386/simple_idct_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/simple_idct_mmx.c @@ -19,8 +19,8 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" -#include "../simple_idct.h" +#include "dsputil.h" +#include "simple_idct.h" /* 23170.475006 @@ -48,10 +48,10 @@ #define ROW_SHIFT 11 #define COL_SHIFT 20 // 6 -static const uint64_t attribute_used __attribute__((aligned(8))) wm1010= 0xFFFF0000FFFF0000ULL; -static const uint64_t attribute_used __attribute__((aligned(8))) d40000= 0x0000000000040000ULL; +DECLARE_ASM_CONST(8, uint64_t, wm1010)= 0xFFFF0000FFFF0000ULL; +DECLARE_ASM_CONST(8, uint64_t, d40000)= 0x0000000000040000ULL; -static const int16_t __attribute__((aligned(8))) coeffs[]= { +DECLARE_ALIGNED(8, static const int16_t, coeffs[])= { 1<<(ROW_SHIFT-1), 0, 1<<(ROW_SHIFT-1), 0, // 1<<(COL_SHIFT-1), 0, 1<<(COL_SHIFT-1), 0, // 0, 1<<(COL_SHIFT-1-16), 0, 1<<(COL_SHIFT-1-16), @@ -209,7 +209,7 @@ row[7] = input[13]; static inline void idct(int16_t *block) { - int64_t __attribute__((aligned(8))) align_tmp[16]; + DECLARE_ALIGNED(8, int64_t, align_tmp[16]); int16_t * const temp= (int16_t*)align_tmp; asm volatile( diff --git a/contrib/ffmpeg/libavcodec/i386/snowdsp_mmx.c b/contrib/ffmpeg/libavcodec/i386/snowdsp_mmx.c index 8f182303d..e43f7e9de 100644 --- a/contrib/ffmpeg/libavcodec/i386/snowdsp_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/snowdsp_mmx.c @@ -19,22 +19,20 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../avcodec.h" -#include "../snow.h" +#include "avcodec.h" +#include "snow.h" #include "x86_cpu.h" -void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width){ +void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, int width){ const int w2= (width+1)>>1; - // SSE2 code runs faster with pointers aligned on a 32-byte boundary. - DWTELEM temp_buf[(width>>1) + 4]; - DWTELEM * const temp = temp_buf + 4 - (((int)temp_buf & 0xF) >> 2); + DECLARE_ALIGNED_16(IDWTELEM, temp[width>>1]); const int w_l= (width>>1); const int w_r= w2 - 1; int i; { // Lift 0 - DWTELEM * const ref = b + w2 - 1; - DWTELEM b_0 = b[0]; //By allowing the first entry in b[0] to be calculated twice + IDWTELEM * const ref = b + w2 - 1; + IDWTELEM b_0 = b[0]; //By allowing the first entry in b[0] to be calculated twice // (the first time erroneously), we allow the SSE2 code to run an extra pass. // The savings in code and time are well worth having to store this value and // calculate b[0] correctly afterwards. @@ -42,33 +40,27 @@ void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width){ i = 0; asm volatile( "pcmpeqd %%xmm7, %%xmm7 \n\t" - "pslld $31, %%xmm7 \n\t" - "psrld $29, %%xmm7 \n\t" + "pcmpeqd %%xmm3, %%xmm3 \n\t" + "psllw $1, %%xmm3 \n\t" + "paddw %%xmm7, %%xmm3 \n\t" + "psllw $13, %%xmm3 \n\t" ::); - for(; i<w_l-7; i+=8){ + for(; i<w_l-15; i+=16){ asm volatile( "movdqu (%1), %%xmm1 \n\t" "movdqu 16(%1), %%xmm5 \n\t" - "movdqu 4(%1), %%xmm2 \n\t" - "movdqu 20(%1), %%xmm6 \n\t" - "paddd %%xmm1, %%xmm2 \n\t" - "paddd %%xmm5, %%xmm6 \n\t" - "movdqa %%xmm2, %%xmm0 \n\t" - "movdqa %%xmm6, %%xmm4 \n\t" - "paddd %%xmm2, %%xmm2 \n\t" - "paddd %%xmm6, %%xmm6 \n\t" - "paddd %%xmm0, %%xmm2 \n\t" - "paddd %%xmm4, %%xmm6 \n\t" - "paddd %%xmm7, %%xmm2 \n\t" - "paddd %%xmm7, %%xmm6 \n\t" - "psrad $3, %%xmm2 \n\t" - "psrad $3, %%xmm6 \n\t" - "movdqa (%0), %%xmm0 \n\t" - "movdqa 16(%0), %%xmm4 \n\t" - "psubd %%xmm2, %%xmm0 \n\t" - "psubd %%xmm6, %%xmm4 \n\t" - "movdqa %%xmm0, (%0) \n\t" - "movdqa %%xmm4, 16(%0) \n\t" + "movdqu 2(%1), %%xmm2 \n\t" + "movdqu 18(%1), %%xmm6 \n\t" + "paddw %%xmm1, %%xmm2 \n\t" + "paddw %%xmm5, %%xmm6 \n\t" + "paddw %%xmm7, %%xmm2 \n\t" + "paddw %%xmm7, %%xmm6 \n\t" + "pmulhw %%xmm3, %%xmm2 \n\t" + "pmulhw %%xmm3, %%xmm6 \n\t" + "paddw (%0), %%xmm2 \n\t" + "paddw 16(%0), %%xmm6 \n\t" + "movdqa %%xmm2, (%0) \n\t" + "movdqa %%xmm6, 16(%0) \n\t" :: "r"(&b[i]), "r"(&ref[i]) : "memory" ); @@ -78,24 +70,24 @@ void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width){ } { // Lift 1 - DWTELEM * const dst = b+w2; + IDWTELEM * const dst = b+w2; i = 0; - for(; (((long)&dst[i]) & 0xF) && i<w_r; i++){ + for(; (((long)&dst[i]) & 0x1F) && i<w_r; i++){ dst[i] = dst[i] - (b[i] + b[i + 1]); } - for(; i<w_r-7; i+=8){ + for(; i<w_r-15; i+=16){ asm volatile( "movdqu (%1), %%xmm1 \n\t" "movdqu 16(%1), %%xmm5 \n\t" - "movdqu 4(%1), %%xmm2 \n\t" - "movdqu 20(%1), %%xmm6 \n\t" - "paddd %%xmm1, %%xmm2 \n\t" - "paddd %%xmm5, %%xmm6 \n\t" + "movdqu 2(%1), %%xmm2 \n\t" + "movdqu 18(%1), %%xmm6 \n\t" + "paddw %%xmm1, %%xmm2 \n\t" + "paddw %%xmm5, %%xmm6 \n\t" "movdqa (%0), %%xmm0 \n\t" "movdqa 16(%0), %%xmm4 \n\t" - "psubd %%xmm2, %%xmm0 \n\t" - "psubd %%xmm6, %%xmm4 \n\t" + "psubw %%xmm2, %%xmm0 \n\t" + "psubw %%xmm6, %%xmm4 \n\t" "movdqa %%xmm0, (%0) \n\t" "movdqa %%xmm4, 16(%0) \n\t" :: "r"(&dst[i]), "r"(&b[i]) @@ -106,37 +98,40 @@ void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width){ } { // Lift 2 - DWTELEM * const ref = b+w2 - 1; - DWTELEM b_0 = b[0]; + IDWTELEM * const ref = b+w2 - 1; + IDWTELEM b_0 = b[0]; i = 0; asm volatile( - "pslld $1, %%xmm7 \n\t" /* xmm7 already holds a '4' from 2 lifts ago. */ + "psllw $15, %%xmm7 \n\t" + "pcmpeqw %%xmm6, %%xmm6 \n\t" + "psrlw $13, %%xmm6 \n\t" + "paddw %%xmm7, %%xmm6 \n\t" ::); - for(; i<w_l-7; i+=8){ + for(; i<w_l-15; i+=16){ asm volatile( - "movdqu (%1), %%xmm1 \n\t" - "movdqu 16(%1), %%xmm5 \n\t" - "movdqu 4(%1), %%xmm0 \n\t" - "movdqu 20(%1), %%xmm4 \n\t" - "paddd %%xmm1, %%xmm0 \n\t" - "paddd %%xmm5, %%xmm4 \n\t" - "movdqa %%xmm7, %%xmm1 \n\t" - "movdqa %%xmm7, %%xmm5 \n\t" - "psubd %%xmm0, %%xmm1 \n\t" - "psubd %%xmm4, %%xmm5 \n\t" - "movdqa (%0), %%xmm0 \n\t" - "movdqa 16(%0), %%xmm4 \n\t" - "pslld $2, %%xmm0 \n\t" - "pslld $2, %%xmm4 \n\t" - "psubd %%xmm0, %%xmm1 \n\t" - "psubd %%xmm4, %%xmm5 \n\t" - "psrad $4, %%xmm1 \n\t" - "psrad $4, %%xmm5 \n\t" - "movdqa (%0), %%xmm0 \n\t" - "movdqa 16(%0), %%xmm4 \n\t" - "psubd %%xmm1, %%xmm0 \n\t" - "psubd %%xmm5, %%xmm4 \n\t" + "movdqu (%1), %%xmm0 \n\t" + "movdqu 16(%1), %%xmm4 \n\t" + "movdqu 2(%1), %%xmm1 \n\t" + "movdqu 18(%1), %%xmm5 \n\t" //FIXME try aligned reads and shifts + "paddw %%xmm6, %%xmm0 \n\t" + "paddw %%xmm6, %%xmm4 \n\t" + "paddw %%xmm7, %%xmm1 \n\t" + "paddw %%xmm7, %%xmm5 \n\t" + "pavgw %%xmm1, %%xmm0 \n\t" + "pavgw %%xmm5, %%xmm4 \n\t" + "psubw %%xmm7, %%xmm0 \n\t" + "psubw %%xmm7, %%xmm4 \n\t" + "psraw $1, %%xmm0 \n\t" + "psraw $1, %%xmm4 \n\t" + "movdqa (%0), %%xmm1 \n\t" + "movdqa 16(%0), %%xmm5 \n\t" + "paddw %%xmm1, %%xmm0 \n\t" + "paddw %%xmm5, %%xmm4 \n\t" + "psraw $2, %%xmm0 \n\t" + "psraw $2, %%xmm4 \n\t" + "paddw %%xmm1, %%xmm0 \n\t" + "paddw %%xmm5, %%xmm4 \n\t" "movdqa %%xmm0, (%0) \n\t" "movdqa %%xmm4, 16(%0) \n\t" :: "r"(&b[i]), "r"(&ref[i]) @@ -144,51 +139,47 @@ void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width){ ); } snow_horizontal_compose_liftS_lead_out(i, b, b, ref, width, w_l); - b[0] = b_0 - (((-2 * ref[1] + W_BO) - 4 * b_0) >> W_BS); + b[0] = b_0 + ((2 * ref[1] + W_BO-1 + 4 * b_0) >> W_BS); } { // Lift 3 - DWTELEM * const src = b+w2; + IDWTELEM * const src = b+w2; i = 0; - for(; (((long)&temp[i]) & 0xF) && i<w_r; i++){ + for(; (((long)&temp[i]) & 0x1F) && i<w_r; i++){ temp[i] = src[i] - ((-W_AM*(b[i] + b[i+1]))>>W_AS); } for(; i<w_r-7; i+=8){ asm volatile( - "movdqu 4(%1), %%xmm2 \n\t" - "movdqu 20(%1), %%xmm6 \n\t" - "paddd (%1), %%xmm2 \n\t" - "paddd 16(%1), %%xmm6 \n\t" - "movdqa %%xmm2, %%xmm0 \n\t" - "movdqa %%xmm6, %%xmm4 \n\t" - "pslld $2, %%xmm2 \n\t" - "pslld $2, %%xmm6 \n\t" - "psubd %%xmm2, %%xmm0 \n\t" - "psubd %%xmm6, %%xmm4 \n\t" - "psrad $1, %%xmm0 \n\t" - "psrad $1, %%xmm4 \n\t" - "movdqu (%0), %%xmm2 \n\t" - "movdqu 16(%0), %%xmm6 \n\t" - "psubd %%xmm0, %%xmm2 \n\t" - "psubd %%xmm4, %%xmm6 \n\t" + "movdqu 2(%1), %%xmm2 \n\t" + "movdqu 18(%1), %%xmm6 \n\t" + "paddw (%1), %%xmm2 \n\t" + "paddw 16(%1), %%xmm6 \n\t" + "movdqu (%0), %%xmm0 \n\t" + "movdqu 16(%0), %%xmm4 \n\t" + "paddw %%xmm2, %%xmm0 \n\t" + "paddw %%xmm6, %%xmm4 \n\t" + "psraw $1, %%xmm2 \n\t" + "psraw $1, %%xmm6 \n\t" + "paddw %%xmm0, %%xmm2 \n\t" + "paddw %%xmm4, %%xmm6 \n\t" "movdqa %%xmm2, (%2) \n\t" "movdqa %%xmm6, 16(%2) \n\t" :: "r"(&src[i]), "r"(&b[i]), "r"(&temp[i]) : "memory" ); } - snow_horizontal_compose_lift_lead_out(i, temp, src, b, width, w_r, 1, -W_AM, W_AO, W_AS); + snow_horizontal_compose_lift_lead_out(i, temp, src, b, width, w_r, 1, -W_AM, W_AO+1, W_AS); } { snow_interleave_line_header(&i, width, b, temp); - for (; (i & 0x1E) != 0x1E; i-=2){ + for (; (i & 0x3E) != 0x3E; i-=2){ b[i+1] = temp[i>>1]; b[i] = b[i>>1]; } - for (i-=30; i>=0; i-=32){ + for (i-=62; i>=0; i-=64){ asm volatile( "movdqa (%1), %%xmm0 \n\t" "movdqa 16(%1), %%xmm2 \n\t" @@ -198,18 +189,18 @@ void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width){ "movdqa 16(%1), %%xmm3 \n\t" "movdqa 32(%1), %%xmm5 \n\t" "movdqa 48(%1), %%xmm7 \n\t" - "punpckldq (%2), %%xmm0 \n\t" - "punpckldq 16(%2), %%xmm2 \n\t" - "punpckldq 32(%2), %%xmm4 \n\t" - "punpckldq 48(%2), %%xmm6 \n\t" + "punpcklwd (%2), %%xmm0 \n\t" + "punpcklwd 16(%2), %%xmm2 \n\t" + "punpcklwd 32(%2), %%xmm4 \n\t" + "punpcklwd 48(%2), %%xmm6 \n\t" "movdqa %%xmm0, (%0) \n\t" "movdqa %%xmm2, 32(%0) \n\t" "movdqa %%xmm4, 64(%0) \n\t" "movdqa %%xmm6, 96(%0) \n\t" - "punpckhdq (%2), %%xmm1 \n\t" - "punpckhdq 16(%2), %%xmm3 \n\t" - "punpckhdq 32(%2), %%xmm5 \n\t" - "punpckhdq 48(%2), %%xmm7 \n\t" + "punpckhwd (%2), %%xmm1 \n\t" + "punpckhwd 16(%2), %%xmm3 \n\t" + "punpckhwd 32(%2), %%xmm5 \n\t" + "punpckhwd 48(%2), %%xmm7 \n\t" "movdqa %%xmm1, 16(%0) \n\t" "movdqa %%xmm3, 48(%0) \n\t" "movdqa %%xmm5, 80(%0) \n\t" @@ -221,45 +212,39 @@ void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width){ } } -void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width){ +void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, int width){ const int w2= (width+1)>>1; - DWTELEM temp[width >> 1]; + IDWTELEM temp[width >> 1]; const int w_l= (width>>1); const int w_r= w2 - 1; int i; { // Lift 0 - DWTELEM * const ref = b + w2 - 1; + IDWTELEM * const ref = b + w2 - 1; i = 1; b[0] = b[0] - ((W_DM * 2 * ref[1]+W_DO)>>W_DS); asm volatile( - "pcmpeqd %%mm7, %%mm7 \n\t" - "pslld $31, %%mm7 \n\t" - "psrld $29, %%mm7 \n\t" + "pcmpeqw %%mm7, %%mm7 \n\t" + "pcmpeqw %%mm3, %%mm3 \n\t" + "psllw $1, %%mm3 \n\t" + "paddw %%mm7, %%mm3 \n\t" + "psllw $13, %%mm3 \n\t" ::); - for(; i<w_l-3; i+=4){ + for(; i<w_l-7; i+=8){ asm volatile( "movq (%1), %%mm2 \n\t" "movq 8(%1), %%mm6 \n\t" - "paddd 4(%1), %%mm2 \n\t" - "paddd 12(%1), %%mm6 \n\t" - "movq %%mm2, %%mm0 \n\t" - "movq %%mm6, %%mm4 \n\t" - "paddd %%mm2, %%mm2 \n\t" - "paddd %%mm6, %%mm6 \n\t" - "paddd %%mm0, %%mm2 \n\t" - "paddd %%mm4, %%mm6 \n\t" - "paddd %%mm7, %%mm2 \n\t" - "paddd %%mm7, %%mm6 \n\t" - "psrad $3, %%mm2 \n\t" - "psrad $3, %%mm6 \n\t" - "movq (%0), %%mm0 \n\t" - "movq 8(%0), %%mm4 \n\t" - "psubd %%mm2, %%mm0 \n\t" - "psubd %%mm6, %%mm4 \n\t" - "movq %%mm0, (%0) \n\t" - "movq %%mm4, 8(%0) \n\t" + "paddw 2(%1), %%mm2 \n\t" + "paddw 10(%1), %%mm6 \n\t" + "paddw %%mm7, %%mm2 \n\t" + "paddw %%mm7, %%mm6 \n\t" + "pmulhw %%mm3, %%mm2 \n\t" + "pmulhw %%mm3, %%mm6 \n\t" + "paddw (%0), %%mm2 \n\t" + "paddw 8(%0), %%mm6 \n\t" + "movq %%mm2, (%0) \n\t" + "movq %%mm6, 8(%0) \n\t" :: "r"(&b[i]), "r"(&ref[i]) : "memory" ); @@ -268,19 +253,19 @@ void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width){ } { // Lift 1 - DWTELEM * const dst = b+w2; + IDWTELEM * const dst = b+w2; i = 0; - for(; i<w_r-3; i+=4){ + for(; i<w_r-7; i+=8){ asm volatile( "movq (%1), %%mm2 \n\t" "movq 8(%1), %%mm6 \n\t" - "paddd 4(%1), %%mm2 \n\t" - "paddd 12(%1), %%mm6 \n\t" + "paddw 2(%1), %%mm2 \n\t" + "paddw 10(%1), %%mm6 \n\t" "movq (%0), %%mm0 \n\t" "movq 8(%0), %%mm4 \n\t" - "psubd %%mm2, %%mm0 \n\t" - "psubd %%mm6, %%mm4 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm6, %%mm4 \n\t" "movq %%mm0, (%0) \n\t" "movq %%mm4, 8(%0) \n\t" :: "r"(&dst[i]), "r"(&b[i]) @@ -291,35 +276,40 @@ void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width){ } { // Lift 2 - DWTELEM * const ref = b+w2 - 1; + IDWTELEM * const ref = b+w2 - 1; i = 1; - b[0] = b[0] - (((-2 * ref[1] + W_BO) - 4 * b[0]) >> W_BS); + b[0] = b[0] + (((2 * ref[1] + W_BO) + 4 * b[0]) >> W_BS); asm volatile( - "pslld $1, %%mm7 \n\t" /* xmm7 already holds a '4' from 2 lifts ago. */ + "psllw $15, %%mm7 \n\t" + "pcmpeqw %%mm6, %%mm6 \n\t" + "psrlw $13, %%mm6 \n\t" + "paddw %%mm7, %%mm6 \n\t" ::); - for(; i<w_l-3; i+=4){ + for(; i<w_l-7; i+=8){ asm volatile( "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm4 \n\t" - "paddd 4(%1), %%mm0 \n\t" - "paddd 12(%1), %%mm4 \n\t" - "movq %%mm7, %%mm1 \n\t" - "movq %%mm7, %%mm5 \n\t" - "psubd %%mm0, %%mm1 \n\t" - "psubd %%mm4, %%mm5 \n\t" - "movq (%0), %%mm0 \n\t" - "movq 8(%0), %%mm4 \n\t" - "pslld $2, %%mm0 \n\t" - "pslld $2, %%mm4 \n\t" - "psubd %%mm0, %%mm1 \n\t" - "psubd %%mm4, %%mm5 \n\t" - "psrad $4, %%mm1 \n\t" - "psrad $4, %%mm5 \n\t" - "movq (%0), %%mm0 \n\t" - "movq 8(%0), %%mm4 \n\t" - "psubd %%mm1, %%mm0 \n\t" - "psubd %%mm5, %%mm4 \n\t" + "movq 2(%1), %%mm1 \n\t" + "movq 10(%1), %%mm5 \n\t" + "paddw %%mm6, %%mm0 \n\t" + "paddw %%mm6, %%mm4 \n\t" + "paddw %%mm7, %%mm1 \n\t" + "paddw %%mm7, %%mm5 \n\t" + "pavgw %%mm1, %%mm0 \n\t" + "pavgw %%mm5, %%mm4 \n\t" + "psubw %%mm7, %%mm0 \n\t" + "psubw %%mm7, %%mm4 \n\t" + "psraw $1, %%mm0 \n\t" + "psraw $1, %%mm4 \n\t" + "movq (%0), %%mm1 \n\t" + "movq 8(%0), %%mm5 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm4 \n\t" + "psraw $2, %%mm0 \n\t" + "psraw $2, %%mm4 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm5, %%mm4 \n\t" "movq %%mm0, (%0) \n\t" "movq %%mm4, 8(%0) \n\t" :: "r"(&b[i]), "r"(&ref[i]) @@ -330,44 +320,40 @@ void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width){ } { // Lift 3 - DWTELEM * const src = b+w2; + IDWTELEM * const src = b+w2; i = 0; - for(; i<w_r-3; i+=4){ + for(; i<w_r-7; i+=8){ asm volatile( - "movq 4(%1), %%mm2 \n\t" - "movq 12(%1), %%mm6 \n\t" - "paddd (%1), %%mm2 \n\t" - "paddd 8(%1), %%mm6 \n\t" - "movq %%mm2, %%mm0 \n\t" - "movq %%mm6, %%mm4 \n\t" - "pslld $2, %%mm2 \n\t" - "pslld $2, %%mm6 \n\t" - "psubd %%mm2, %%mm0 \n\t" - "psubd %%mm6, %%mm4 \n\t" - "psrad $1, %%mm0 \n\t" - "psrad $1, %%mm4 \n\t" - "movq (%0), %%mm2 \n\t" - "movq 8(%0), %%mm6 \n\t" - "psubd %%mm0, %%mm2 \n\t" - "psubd %%mm4, %%mm6 \n\t" + "movq 2(%1), %%mm2 \n\t" + "movq 10(%1), %%mm6 \n\t" + "paddw (%1), %%mm2 \n\t" + "paddw 8(%1), %%mm6 \n\t" + "movq (%0), %%mm0 \n\t" + "movq 8(%0), %%mm4 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm6, %%mm4 \n\t" + "psraw $1, %%mm2 \n\t" + "psraw $1, %%mm6 \n\t" + "paddw %%mm0, %%mm2 \n\t" + "paddw %%mm4, %%mm6 \n\t" "movq %%mm2, (%2) \n\t" "movq %%mm6, 8(%2) \n\t" :: "r"(&src[i]), "r"(&b[i]), "r"(&temp[i]) : "memory" ); } - snow_horizontal_compose_lift_lead_out(i, temp, src, b, width, w_r, 1, -W_AM, W_AO, W_AS); + snow_horizontal_compose_lift_lead_out(i, temp, src, b, width, w_r, 1, -W_AM, W_AO+1, W_AS); } { snow_interleave_line_header(&i, width, b, temp); - for (; (i & 0xE) != 0xE; i-=2){ + for (; (i & 0x1E) != 0x1E; i-=2){ b[i+1] = temp[i>>1]; b[i] = b[i>>1]; } - for (i-=14; i>=0; i-=16){ + for (i-=30; i>=0; i-=32){ asm volatile( "movq (%1), %%mm0 \n\t" "movq 8(%1), %%mm2 \n\t" @@ -377,18 +363,18 @@ void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width){ "movq 8(%1), %%mm3 \n\t" "movq 16(%1), %%mm5 \n\t" "movq 24(%1), %%mm7 \n\t" - "punpckldq (%2), %%mm0 \n\t" - "punpckldq 8(%2), %%mm2 \n\t" - "punpckldq 16(%2), %%mm4 \n\t" - "punpckldq 24(%2), %%mm6 \n\t" + "punpcklwd (%2), %%mm0 \n\t" + "punpcklwd 8(%2), %%mm2 \n\t" + "punpcklwd 16(%2), %%mm4 \n\t" + "punpcklwd 24(%2), %%mm6 \n\t" "movq %%mm0, (%0) \n\t" "movq %%mm2, 16(%0) \n\t" "movq %%mm4, 32(%0) \n\t" "movq %%mm6, 48(%0) \n\t" - "punpckhdq (%2), %%mm1 \n\t" - "punpckhdq 8(%2), %%mm3 \n\t" - "punpckhdq 16(%2), %%mm5 \n\t" - "punpckhdq 24(%2), %%mm7 \n\t" + "punpckhwd (%2), %%mm1 \n\t" + "punpckhwd 8(%2), %%mm3 \n\t" + "punpckhwd 16(%2), %%mm5 \n\t" + "punpckhwd 24(%2), %%mm7 \n\t" "movq %%mm1, 8(%0) \n\t" "movq %%mm3, 24(%0) \n\t" "movq %%mm5, 40(%0) \n\t" @@ -400,47 +386,48 @@ void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width){ } } +#ifdef HAVE_7REGS #define snow_vertical_compose_sse2_load_add(op,r,t0,t1,t2,t3)\ - ""op" (%%"r",%%"REG_d",4), %%"t0" \n\t"\ - ""op" 16(%%"r",%%"REG_d",4), %%"t1" \n\t"\ - ""op" 32(%%"r",%%"REG_d",4), %%"t2" \n\t"\ - ""op" 48(%%"r",%%"REG_d",4), %%"t3" \n\t" + ""op" ("r",%%"REG_d"), %%"t0" \n\t"\ + ""op" 16("r",%%"REG_d"), %%"t1" \n\t"\ + ""op" 32("r",%%"REG_d"), %%"t2" \n\t"\ + ""op" 48("r",%%"REG_d"), %%"t3" \n\t" #define snow_vertical_compose_sse2_load(r,t0,t1,t2,t3)\ snow_vertical_compose_sse2_load_add("movdqa",r,t0,t1,t2,t3) #define snow_vertical_compose_sse2_add(r,t0,t1,t2,t3)\ - snow_vertical_compose_sse2_load_add("paddd",r,t0,t1,t2,t3) + snow_vertical_compose_sse2_load_add("paddw",r,t0,t1,t2,t3) -#define snow_vertical_compose_sse2_sub(s0,s1,s2,s3,t0,t1,t2,t3)\ - "psubd %%"s0", %%"t0" \n\t"\ - "psubd %%"s1", %%"t1" \n\t"\ - "psubd %%"s2", %%"t2" \n\t"\ - "psubd %%"s3", %%"t3" \n\t" +#define snow_vertical_compose_r2r_sub(s0,s1,s2,s3,t0,t1,t2,t3)\ + "psubw %%"s0", %%"t0" \n\t"\ + "psubw %%"s1", %%"t1" \n\t"\ + "psubw %%"s2", %%"t2" \n\t"\ + "psubw %%"s3", %%"t3" \n\t" #define snow_vertical_compose_sse2_store(w,s0,s1,s2,s3)\ - "movdqa %%"s0", (%%"w",%%"REG_d",4) \n\t"\ - "movdqa %%"s1", 16(%%"w",%%"REG_d",4) \n\t"\ - "movdqa %%"s2", 32(%%"w",%%"REG_d",4) \n\t"\ - "movdqa %%"s3", 48(%%"w",%%"REG_d",4) \n\t" - -#define snow_vertical_compose_sse2_sra(n,t0,t1,t2,t3)\ - "psrad $"n", %%"t0" \n\t"\ - "psrad $"n", %%"t1" \n\t"\ - "psrad $"n", %%"t2" \n\t"\ - "psrad $"n", %%"t3" \n\t" - -#define snow_vertical_compose_sse2_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3)\ - "paddd %%"s0", %%"t0" \n\t"\ - "paddd %%"s1", %%"t1" \n\t"\ - "paddd %%"s2", %%"t2" \n\t"\ - "paddd %%"s3", %%"t3" \n\t" - -#define snow_vertical_compose_sse2_sll(n,t0,t1,t2,t3)\ - "pslld $"n", %%"t0" \n\t"\ - "pslld $"n", %%"t1" \n\t"\ - "pslld $"n", %%"t2" \n\t"\ - "pslld $"n", %%"t3" \n\t" + "movdqa %%"s0", ("w",%%"REG_d") \n\t"\ + "movdqa %%"s1", 16("w",%%"REG_d") \n\t"\ + "movdqa %%"s2", 32("w",%%"REG_d") \n\t"\ + "movdqa %%"s3", 48("w",%%"REG_d") \n\t" + +#define snow_vertical_compose_sra(n,t0,t1,t2,t3)\ + "psraw $"n", %%"t0" \n\t"\ + "psraw $"n", %%"t1" \n\t"\ + "psraw $"n", %%"t2" \n\t"\ + "psraw $"n", %%"t3" \n\t" + +#define snow_vertical_compose_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3)\ + "paddw %%"s0", %%"t0" \n\t"\ + "paddw %%"s1", %%"t1" \n\t"\ + "paddw %%"s2", %%"t2" \n\t"\ + "paddw %%"s3", %%"t3" \n\t" + +#define snow_vertical_compose_r2r_pmulhw(s0,s1,s2,s3,t0,t1,t2,t3)\ + "pmulhw %%"s0", %%"t0" \n\t"\ + "pmulhw %%"s1", %%"t1" \n\t"\ + "pmulhw %%"s2", %%"t2" \n\t"\ + "pmulhw %%"s3", %%"t3" \n\t" #define snow_vertical_compose_sse2_move(s0,s1,s2,s3,t0,t1,t2,t3)\ "movdqa %%"s0", %%"t0" \n\t"\ @@ -448,10 +435,10 @@ void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width){ "movdqa %%"s2", %%"t2" \n\t"\ "movdqa %%"s3", %%"t3" \n\t" -void ff_snow_vertical_compose97i_sse2(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width){ +void ff_snow_vertical_compose97i_sse2(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ long i = width; - while(i & 0xF) + while(i & 0x1F) { i--; b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; @@ -459,96 +446,85 @@ void ff_snow_vertical_compose97i_sse2(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWT b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; } + i+=i; asm volatile ( "jmp 2f \n\t" "1: \n\t" - - "mov %6, %%"REG_a" \n\t" - "mov %4, %%"REG_S" \n\t" - - snow_vertical_compose_sse2_load(REG_S,"xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add(REG_a,"xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_move("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sse2_sll("1","xmm0","xmm2","xmm4","xmm6")\ - snow_vertical_compose_sse2_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") - - "pcmpeqd %%xmm1, %%xmm1 \n\t" - "pslld $31, %%xmm1 \n\t" - "psrld $29, %%xmm1 \n\t" - "mov %5, %%"REG_a" \n\t" - - snow_vertical_compose_sse2_r2r_add("xmm1","xmm1","xmm1","xmm1","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_sra("3","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_load(REG_a,"xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sse2_sub("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sse2_store(REG_a,"xmm1","xmm3","xmm5","xmm7") - "mov %3, %%"REG_c" \n\t" - snow_vertical_compose_sse2_load(REG_S,"xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add(REG_c,"xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sse2_sub("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_store(REG_S,"xmm0","xmm2","xmm4","xmm6") - "mov %2, %%"REG_a" \n\t" - snow_vertical_compose_sse2_load(REG_c,"xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sse2_add(REG_a,"xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_sll("2","xmm1","xmm3","xmm5","xmm7")\ - snow_vertical_compose_sse2_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") - - "pcmpeqd %%xmm1, %%xmm1 \n\t" - "pslld $31, %%xmm1 \n\t" - "psrld $28, %%xmm1 \n\t" - "mov %1, %%"REG_S" \n\t" - - snow_vertical_compose_sse2_r2r_add("xmm1","xmm1","xmm1","xmm1","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_sra("4","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add(REG_c,"xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_store(REG_c,"xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add(REG_S,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%6","xmm0","xmm2","xmm4","xmm6") + + + "pcmpeqw %%xmm0, %%xmm0 \n\t" + "pcmpeqw %%xmm2, %%xmm2 \n\t" + "paddw %%xmm2, %%xmm2 \n\t" + "paddw %%xmm0, %%xmm2 \n\t" + "psllw $13, %%xmm2 \n\t" + snow_vertical_compose_r2r_add("xmm0","xmm0","xmm0","xmm0","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_r2r_pmulhw("xmm2","xmm2","xmm2","xmm2","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_add("%5","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_store("%5","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%3","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_r2r_sub("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store("%4","xmm0","xmm2","xmm4","xmm6") + + "pcmpeqw %%xmm7, %%xmm7 \n\t" + "pcmpeqw %%xmm5, %%xmm5 \n\t" + "psllw $15, %%xmm7 \n\t" + "psrlw $13, %%xmm5 \n\t" + "paddw %%xmm7, %%xmm5 \n\t" + snow_vertical_compose_r2r_add("xmm5","xmm5","xmm5","xmm5","xmm0","xmm2","xmm4","xmm6") + "movq (%2,%%"REG_d"), %%xmm1 \n\t" + "movq 8(%2,%%"REG_d"), %%xmm3 \n\t" + "paddw %%xmm7, %%xmm1 \n\t" + "paddw %%xmm7, %%xmm3 \n\t" + "pavgw %%xmm1, %%xmm0 \n\t" + "pavgw %%xmm3, %%xmm2 \n\t" + "movq 16(%2,%%"REG_d"), %%xmm1 \n\t" + "movq 24(%2,%%"REG_d"), %%xmm3 \n\t" + "paddw %%xmm7, %%xmm1 \n\t" + "paddw %%xmm7, %%xmm3 \n\t" + "pavgw %%xmm1, %%xmm4 \n\t" + "pavgw %%xmm3, %%xmm6 \n\t" + snow_vertical_compose_r2r_sub("xmm7","xmm7","xmm7","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6") + + snow_vertical_compose_sra("2","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store("%3","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%1","xmm0","xmm2","xmm4","xmm6") snow_vertical_compose_sse2_move("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7") - snow_vertical_compose_sse2_sll("1","xmm0","xmm2","xmm4","xmm6")\ - snow_vertical_compose_sse2_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_sra("1","xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_add(REG_a,"xmm0","xmm2","xmm4","xmm6") - snow_vertical_compose_sse2_store(REG_a,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%2","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store("%2","xmm0","xmm2","xmm4","xmm6") "2: \n\t" - "sub $16, %%"REG_d" \n\t" + "sub $64, %%"REG_d" \n\t" "jge 1b \n\t" :"+d"(i) - : - "m"(b0),"m"(b1),"m"(b2),"m"(b3),"m"(b4),"m"(b5): - "%"REG_a"","%"REG_S"","%"REG_c""); + :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5)); } #define snow_vertical_compose_mmx_load_add(op,r,t0,t1,t2,t3)\ - ""op" (%%"r",%%"REG_d",4), %%"t0" \n\t"\ - ""op" 8(%%"r",%%"REG_d",4), %%"t1" \n\t"\ - ""op" 16(%%"r",%%"REG_d",4), %%"t2" \n\t"\ - ""op" 24(%%"r",%%"REG_d",4), %%"t3" \n\t" + ""op" ("r",%%"REG_d"), %%"t0" \n\t"\ + ""op" 8("r",%%"REG_d"), %%"t1" \n\t"\ + ""op" 16("r",%%"REG_d"), %%"t2" \n\t"\ + ""op" 24("r",%%"REG_d"), %%"t3" \n\t" #define snow_vertical_compose_mmx_load(r,t0,t1,t2,t3)\ snow_vertical_compose_mmx_load_add("movq",r,t0,t1,t2,t3) #define snow_vertical_compose_mmx_add(r,t0,t1,t2,t3)\ - snow_vertical_compose_mmx_load_add("paddd",r,t0,t1,t2,t3) - -#define snow_vertical_compose_mmx_sub(s0,s1,s2,s3,t0,t1,t2,t3)\ - snow_vertical_compose_sse2_sub(s0,s1,s2,s3,t0,t1,t2,t3) + snow_vertical_compose_mmx_load_add("paddw",r,t0,t1,t2,t3) #define snow_vertical_compose_mmx_store(w,s0,s1,s2,s3)\ - "movq %%"s0", (%%"w",%%"REG_d",4) \n\t"\ - "movq %%"s1", 8(%%"w",%%"REG_d",4) \n\t"\ - "movq %%"s2", 16(%%"w",%%"REG_d",4) \n\t"\ - "movq %%"s3", 24(%%"w",%%"REG_d",4) \n\t" - -#define snow_vertical_compose_mmx_sra(n,t0,t1,t2,t3)\ - snow_vertical_compose_sse2_sra(n,t0,t1,t2,t3) - -#define snow_vertical_compose_mmx_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3)\ - snow_vertical_compose_sse2_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3) - -#define snow_vertical_compose_mmx_sll(n,t0,t1,t2,t3)\ - snow_vertical_compose_sse2_sll(n,t0,t1,t2,t3) + "movq %%"s0", ("w",%%"REG_d") \n\t"\ + "movq %%"s1", 8("w",%%"REG_d") \n\t"\ + "movq %%"s2", 16("w",%%"REG_d") \n\t"\ + "movq %%"s3", 24("w",%%"REG_d") \n\t" #define snow_vertical_compose_mmx_move(s0,s1,s2,s3,t0,t1,t2,t3)\ "movq %%"s0", %%"t0" \n\t"\ @@ -556,9 +532,10 @@ void ff_snow_vertical_compose97i_sse2(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWT "movq %%"s2", %%"t2" \n\t"\ "movq %%"s3", %%"t3" \n\t" -void ff_snow_vertical_compose97i_mmx(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width){ + +void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ long i = width; - while(i & 0x7) + while(i & 15) { i--; b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; @@ -566,69 +543,68 @@ void ff_snow_vertical_compose97i_mmx(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTE b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; } - + i+=i; asm volatile( "jmp 2f \n\t" "1: \n\t" - "mov %6, %%"REG_a" \n\t" - "mov %4, %%"REG_S" \n\t" - - snow_vertical_compose_mmx_load(REG_S,"mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add(REG_a,"mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_load("%4","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_add("%6","mm1","mm3","mm5","mm7") + "pcmpeqw %%mm0, %%mm0 \n\t" + "pcmpeqw %%mm2, %%mm2 \n\t" + "paddw %%mm2, %%mm2 \n\t" + "paddw %%mm0, %%mm2 \n\t" + "psllw $13, %%mm2 \n\t" + snow_vertical_compose_r2r_add("mm0","mm0","mm0","mm0","mm1","mm3","mm5","mm7") + snow_vertical_compose_r2r_pmulhw("mm2","mm2","mm2","mm2","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_add("%5","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_store("%5","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_load("%4","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%3","mm1","mm3","mm5","mm7") + snow_vertical_compose_r2r_sub("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store("%4","mm0","mm2","mm4","mm6") + "pcmpeqw %%mm7, %%mm7 \n\t" + "pcmpeqw %%mm5, %%mm5 \n\t" + "psllw $15, %%mm7 \n\t" + "psrlw $13, %%mm5 \n\t" + "paddw %%mm7, %%mm5 \n\t" + snow_vertical_compose_r2r_add("mm5","mm5","mm5","mm5","mm0","mm2","mm4","mm6") + "movq (%2,%%"REG_d"), %%mm1 \n\t" + "movq 8(%2,%%"REG_d"), %%mm3 \n\t" + "paddw %%mm7, %%mm1 \n\t" + "paddw %%mm7, %%mm3 \n\t" + "pavgw %%mm1, %%mm0 \n\t" + "pavgw %%mm3, %%mm2 \n\t" + "movq 16(%2,%%"REG_d"), %%mm1 \n\t" + "movq 24(%2,%%"REG_d"), %%mm3 \n\t" + "paddw %%mm7, %%mm1 \n\t" + "paddw %%mm7, %%mm3 \n\t" + "pavgw %%mm1, %%mm4 \n\t" + "pavgw %%mm3, %%mm6 \n\t" + snow_vertical_compose_r2r_sub("mm7","mm7","mm7","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6") + + snow_vertical_compose_sra("2","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store("%3","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%1","mm0","mm2","mm4","mm6") snow_vertical_compose_mmx_move("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_sll("1","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") - - "pcmpeqd %%mm1, %%mm1 \n\t" - "pslld $31, %%mm1 \n\t" - "psrld $29, %%mm1 \n\t" - "mov %5, %%"REG_a" \n\t" - - snow_vertical_compose_mmx_r2r_add("mm1","mm1","mm1","mm1","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_sra("3","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_load(REG_a,"mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_sub("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_store(REG_a,"mm1","mm3","mm5","mm7") - "mov %3, %%"REG_c" \n\t" - snow_vertical_compose_mmx_load(REG_S,"mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add(REG_c,"mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_sub("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_store(REG_S,"mm0","mm2","mm4","mm6") - "mov %2, %%"REG_a" \n\t" - snow_vertical_compose_mmx_load(REG_c,"mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_add(REG_a,"mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_sll("2","mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") - - "pcmpeqd %%mm1, %%mm1 \n\t" - "pslld $31, %%mm1 \n\t" - "psrld $28, %%mm1 \n\t" - "mov %1, %%"REG_S" \n\t" - - snow_vertical_compose_mmx_r2r_add("mm1","mm1","mm1","mm1","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_sra("4","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add(REG_c,"mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_store(REG_c,"mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add(REG_S,"mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_move("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7") - snow_vertical_compose_mmx_sll("1","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_sra("1","mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_add(REG_a,"mm0","mm2","mm4","mm6") - snow_vertical_compose_mmx_store(REG_a,"mm0","mm2","mm4","mm6") + snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6") + snow_vertical_compose_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%2","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store("%2","mm0","mm2","mm4","mm6") "2: \n\t" - "sub $8, %%"REG_d" \n\t" + "sub $32, %%"REG_d" \n\t" "jge 1b \n\t" :"+d"(i) - : - "m"(b0),"m"(b1),"m"(b2),"m"(b3),"m"(b4),"m"(b5): - "%"REG_a"","%"REG_S"","%"REG_c""); + :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5)); } +#endif //HAVE_7REGS #define snow_inner_add_yblock_sse2_header \ - DWTELEM * * dst_array = sb->line + src_y;\ + IDWTELEM * * dst_array = sb->line + src_y;\ long tmp;\ asm volatile(\ "mov %7, %%"REG_c" \n\t"\ @@ -636,8 +612,8 @@ void ff_snow_vertical_compose97i_mmx(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTE "mov %4, %%"REG_S" \n\t"\ "pxor %%xmm7, %%xmm7 \n\t" /* 0 */\ "pcmpeqd %%xmm3, %%xmm3 \n\t"\ - "pslld $31, %%xmm3 \n\t"\ - "psrld $24, %%xmm3 \n\t" /* FRAC_BITS >> 1 */\ + "psllw $15, %%xmm3 \n\t"\ + "psrlw $12, %%xmm3 \n\t" /* FRAC_BITS >> 1 */\ "1: \n\t"\ "mov %1, %%"REG_D" \n\t"\ "mov (%%"REG_D"), %%"REG_D" \n\t"\ @@ -691,7 +667,7 @@ void ff_snow_vertical_compose97i_mmx(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTE "jnz 1b \n\t"\ :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\ :\ - "rm"((long)(src_x<<2)),"m"(obmc),"a"(block),"m"((long)b_h),"m"((long)src_stride):\ + "rm"((long)(src_x<<1)),"m"(obmc),"a"(block),"m"((long)b_h),"m"((long)src_stride):\ "%"REG_c"","%"REG_S"","%"REG_D"","%"REG_d""); #define snow_inner_add_yblock_sse2_end_8\ @@ -765,36 +741,23 @@ snow_inner_add_yblock_sse2_accum_16("1", "512") snow_inner_add_yblock_sse2_accum_16("0", "528") "mov %0, %%"REG_d" \n\t" - "movdqa %%xmm1, %%xmm0 \n\t" - "movdqa %%xmm5, %%xmm4 \n\t" - "punpcklwd %%xmm7, %%xmm0 \n\t" - "paddd (%%"REG_D"), %%xmm0 \n\t" - "punpckhwd %%xmm7, %%xmm1 \n\t" - "paddd 16(%%"REG_D"), %%xmm1 \n\t" - "punpcklwd %%xmm7, %%xmm4 \n\t" - "paddd 32(%%"REG_D"), %%xmm4 \n\t" - "punpckhwd %%xmm7, %%xmm5 \n\t" - "paddd 48(%%"REG_D"), %%xmm5 \n\t" - "paddd %%xmm3, %%xmm0 \n\t" - "paddd %%xmm3, %%xmm1 \n\t" - "paddd %%xmm3, %%xmm4 \n\t" - "paddd %%xmm3, %%xmm5 \n\t" - "psrad $8, %%xmm0 \n\t" /* FRAC_BITS. */ - "psrad $8, %%xmm1 \n\t" /* FRAC_BITS. */ - "psrad $8, %%xmm4 \n\t" /* FRAC_BITS. */ - "psrad $8, %%xmm5 \n\t" /* FRAC_BITS. */ - - "packssdw %%xmm1, %%xmm0 \n\t" - "packssdw %%xmm5, %%xmm4 \n\t" - "packuswb %%xmm4, %%xmm0 \n\t" - - "movdqu %%xmm0, (%%"REG_d") \n\t" + "psrlw $4, %%xmm1 \n\t" + "psrlw $4, %%xmm5 \n\t" + "paddw (%%"REG_D"), %%xmm1 \n\t" + "paddw 16(%%"REG_D"), %%xmm5 \n\t" + "paddw %%xmm3, %%xmm1 \n\t" + "paddw %%xmm3, %%xmm5 \n\t" + "psraw $4, %%xmm1 \n\t" /* FRAC_BITS. */ + "psraw $4, %%xmm5 \n\t" /* FRAC_BITS. */ + "packuswb %%xmm5, %%xmm1 \n\t" + + "movdqu %%xmm1, (%%"REG_d") \n\t" snow_inner_add_yblock_sse2_end_16 } #define snow_inner_add_yblock_mmx_header \ - DWTELEM * * dst_array = sb->line + src_y;\ + IDWTELEM * * dst_array = sb->line + src_y;\ long tmp;\ asm volatile(\ "mov %7, %%"REG_c" \n\t"\ @@ -802,8 +765,8 @@ snow_inner_add_yblock_sse2_end_16 "mov %4, %%"REG_S" \n\t"\ "pxor %%mm7, %%mm7 \n\t" /* 0 */\ "pcmpeqd %%mm3, %%mm3 \n\t"\ - "pslld $31, %%mm3 \n\t"\ - "psrld $24, %%mm3 \n\t" /* FRAC_BITS >> 1 */\ + "psllw $15, %%mm3 \n\t"\ + "psrlw $12, %%mm3 \n\t" /* FRAC_BITS >> 1 */\ "1: \n\t"\ "mov %1, %%"REG_D" \n\t"\ "mov (%%"REG_D"), %%"REG_D" \n\t"\ @@ -829,29 +792,16 @@ snow_inner_add_yblock_sse2_end_16 #define snow_inner_add_yblock_mmx_mix(read_offset, write_offset)\ "mov %0, %%"REG_d" \n\t"\ - "movq %%mm1, %%mm0 \n\t"\ - "movq %%mm5, %%mm4 \n\t"\ - "punpcklwd %%mm7, %%mm0 \n\t"\ - "paddd "read_offset"(%%"REG_D"), %%mm0 \n\t"\ - "punpckhwd %%mm7, %%mm1 \n\t"\ - "paddd "read_offset"+8(%%"REG_D"), %%mm1 \n\t"\ - "punpcklwd %%mm7, %%mm4 \n\t"\ - "paddd "read_offset"+16(%%"REG_D"), %%mm4 \n\t"\ - "punpckhwd %%mm7, %%mm5 \n\t"\ - "paddd "read_offset"+24(%%"REG_D"), %%mm5 \n\t"\ - "paddd %%mm3, %%mm0 \n\t"\ - "paddd %%mm3, %%mm1 \n\t"\ - "paddd %%mm3, %%mm4 \n\t"\ - "paddd %%mm3, %%mm5 \n\t"\ - "psrad $8, %%mm0 \n\t"\ - "psrad $8, %%mm1 \n\t"\ - "psrad $8, %%mm4 \n\t"\ - "psrad $8, %%mm5 \n\t"\ -\ - "packssdw %%mm1, %%mm0 \n\t"\ - "packssdw %%mm5, %%mm4 \n\t"\ - "packuswb %%mm4, %%mm0 \n\t"\ - "movq %%mm0, "write_offset"(%%"REG_d") \n\t" + "psrlw $4, %%mm1 \n\t"\ + "psrlw $4, %%mm5 \n\t"\ + "paddw "read_offset"(%%"REG_D"), %%mm1 \n\t"\ + "paddw "read_offset"+8(%%"REG_D"), %%mm5 \n\t"\ + "paddw %%mm3, %%mm1 \n\t"\ + "paddw %%mm3, %%mm5 \n\t"\ + "psraw $4, %%mm1 \n\t"\ + "psraw $4, %%mm5 \n\t"\ + "packuswb %%mm5, %%mm1 \n\t"\ + "movq %%mm1, "write_offset"(%%"REG_d") \n\t" #define snow_inner_add_yblock_mmx_end(s_step)\ "add $"s_step", %%"REG_S" \n\t"\ @@ -865,7 +815,7 @@ snow_inner_add_yblock_sse2_end_16 "jnz 1b \n\t"\ :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\ :\ - "rm"((long)(src_x<<2)),"m"(obmc),"a"(block),"m"((long)b_h),"m"((long)src_stride):\ + "rm"((long)(src_x<<1)),"m"(obmc),"a"(block),"m"((long)b_h),"m"((long)src_stride):\ "%"REG_c"","%"REG_S"","%"REG_D"","%"REG_d""); static void inner_add_yblock_bw_8_obmc_16_mmx(const uint8_t *obmc, const long obmc_stride, uint8_t * * block, int b_w, long b_h, @@ -892,7 +842,7 @@ snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "8", "8") snow_inner_add_yblock_mmx_accum("2", "24", "8") snow_inner_add_yblock_mmx_accum("1", "520", "8") snow_inner_add_yblock_mmx_accum("0", "536", "8") -snow_inner_add_yblock_mmx_mix("32", "8") +snow_inner_add_yblock_mmx_mix("16", "8") snow_inner_add_yblock_mmx_end("32") } diff --git a/contrib/ffmpeg/libavcodec/i386/vc1dsp_mmx.c b/contrib/ffmpeg/libavcodec/i386/vc1dsp_mmx.c new file mode 100644 index 000000000..16fabd3e2 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/i386/vc1dsp_mmx.c @@ -0,0 +1,490 @@ +/* + * VC-1 and WMV3 - DSP functions MMX-optimized + * Copyright (c) 2007 Christophe GISQUET <christophe.gisquet@free.fr> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "dsputil.h" +#include "dsputil_mmx.h" +#include "x86_cpu.h" + +/** Add rounder from mm7 to mm3 and pack result at destination */ +#define NORMALIZE_MMX(SHIFT) \ + "paddw %%mm7, %%mm3 \n\t" /* +bias-r */ \ + "paddw %%mm7, %%mm4 \n\t" /* +bias-r */ \ + "psraw "SHIFT", %%mm3 \n\t" \ + "psraw "SHIFT", %%mm4 \n\t" + +#define TRANSFER_DO_PACK \ + "packuswb %%mm4, %%mm3 \n\t" \ + "movq %%mm3, (%2) \n\t" + +#define TRANSFER_DONT_PACK \ + "movq %%mm3, 0(%2) \n\t" \ + "movq %%mm4, 8(%2) \n\t" + +/** @see MSPEL_FILTER13_CORE for use as UNPACK macro */ +#define DO_UNPACK(reg) "punpcklbw %%mm0, " reg "\n\t" +#define DONT_UNPACK(reg) + +/** Compute the rounder 32-r or 8-r and unpacks it to mm7 */ +#define LOAD_ROUNDER_MMX(ROUND) \ + "movd "ROUND", %%mm7 \n\t" \ + "punpcklwd %%mm7, %%mm7 \n\t" \ + "punpckldq %%mm7, %%mm7 \n\t" + +#define SHIFT2_LINE(OFF, R0,R1,R2,R3) \ + "paddw %%mm"#R2", %%mm"#R1" \n\t" \ + "movd (%0,%3), %%mm"#R0" \n\t" \ + "pmullw %%mm6, %%mm"#R1" \n\t" \ + "punpcklbw %%mm0, %%mm"#R0" \n\t" \ + "movd (%0,%2), %%mm"#R3" \n\t" \ + "psubw %%mm"#R0", %%mm"#R1" \n\t" \ + "punpcklbw %%mm0, %%mm"#R3" \n\t" \ + "paddw %%mm7, %%mm"#R1" \n\t" \ + "psubw %%mm"#R3", %%mm"#R1" \n\t" \ + "psraw %4, %%mm"#R1" \n\t" \ + "movq %%mm"#R1", "#OFF"(%1) \n\t" \ + "add %2, %0 \n\t" + +DECLARE_ALIGNED_16(const uint64_t, ff_pw_9) = 0x0009000900090009ULL; + +/** Sacrifying mm6 allows to pipeline loads from src */ +static void vc1_put_ver_16b_shift2_mmx(int16_t *dst, + const uint8_t *src, long int stride, + int rnd, int64_t shift) +{ + asm volatile( + "mov $3, %%"REG_c" \n\t" + LOAD_ROUNDER_MMX("%5") + "movq "MANGLE(ff_pw_9)", %%mm6 \n\t" + "1: \n\t" + "movd (%0), %%mm2 \n\t" + "add %2, %0 \n\t" + "movd (%0), %%mm3 \n\t" + "punpcklbw %%mm0, %%mm2 \n\t" + "punpcklbw %%mm0, %%mm3 \n\t" + SHIFT2_LINE( 0, 1, 2, 3, 4) + SHIFT2_LINE( 24, 2, 3, 4, 1) + SHIFT2_LINE( 48, 3, 4, 1, 2) + SHIFT2_LINE( 72, 4, 1, 2, 3) + SHIFT2_LINE( 96, 1, 2, 3, 4) + SHIFT2_LINE(120, 2, 3, 4, 1) + SHIFT2_LINE(144, 3, 4, 1, 2) + SHIFT2_LINE(168, 4, 1, 2, 3) + "sub %6, %0 \n\t" + "add $8, %1 \n\t" + "dec %%"REG_c" \n\t" + "jnz 1b \n\t" + : "+r"(src), "+r"(dst) + : "r"(stride), "r"(-2*stride), + "m"(shift), "m"(rnd), "r"(9*stride-4) + : "%"REG_c, "memory" + ); +} + +/** + * Data is already unpacked, so some operations can directly be made from + * memory. + */ +static void vc1_put_hor_16b_shift2_mmx(uint8_t *dst, long int stride, + const int16_t *src, int rnd) +{ + int h = 8; + + src -= 1; + rnd -= (-1+9+9-1)*1024; /* Add -1024 bias */ + asm volatile( + LOAD_ROUNDER_MMX("%4") + "movq "MANGLE(ff_pw_128)", %%mm6\n\t" + "movq "MANGLE(ff_pw_9)", %%mm5 \n\t" + "1: \n\t" + "movq 2*0+0(%1), %%mm1 \n\t" + "movq 2*0+8(%1), %%mm2 \n\t" + "movq 2*1+0(%1), %%mm3 \n\t" + "movq 2*1+8(%1), %%mm4 \n\t" + "paddw 2*3+0(%1), %%mm1 \n\t" + "paddw 2*3+8(%1), %%mm2 \n\t" + "paddw 2*2+0(%1), %%mm3 \n\t" + "paddw 2*2+8(%1), %%mm4 \n\t" + "pmullw %%mm5, %%mm3 \n\t" + "pmullw %%mm5, %%mm4 \n\t" + "psubw %%mm1, %%mm3 \n\t" + "psubw %%mm2, %%mm4 \n\t" + NORMALIZE_MMX("$7") + /* Remove bias */ + "paddw %%mm6, %%mm3 \n\t" + "paddw %%mm6, %%mm4 \n\t" + TRANSFER_DO_PACK + "add $24, %1 \n\t" + "add %3, %2 \n\t" + "decl %0 \n\t" + "jnz 1b \n\t" + : "+r"(h), "+r" (src), "+r" (dst) + : "r"(stride), "m"(rnd) + : "memory" + ); +} + + +/** + * Purely vertical or horizontal 1/2 shift interpolation. + * Sacrify mm6 for *9 factor. + */ +static void vc1_put_shift2_mmx(uint8_t *dst, const uint8_t *src, + long int stride, int rnd, long int offset) +{ + rnd = 8-rnd; + asm volatile( + "mov $8, %%"REG_c" \n\t" + LOAD_ROUNDER_MMX("%5") + "movq "MANGLE(ff_pw_9)", %%mm6\n\t" + "1: \n\t" + "movd 0(%0 ), %%mm3 \n\t" + "movd 4(%0 ), %%mm4 \n\t" + "movd 0(%0,%2), %%mm1 \n\t" + "movd 4(%0,%2), %%mm2 \n\t" + "add %2, %0 \n\t" + "punpcklbw %%mm0, %%mm3 \n\t" + "punpcklbw %%mm0, %%mm4 \n\t" + "punpcklbw %%mm0, %%mm1 \n\t" + "punpcklbw %%mm0, %%mm2 \n\t" + "paddw %%mm1, %%mm3 \n\t" + "paddw %%mm2, %%mm4 \n\t" + "movd 0(%0,%3), %%mm1 \n\t" + "movd 4(%0,%3), %%mm2 \n\t" + "pmullw %%mm6, %%mm3 \n\t" /* 0,9,9,0*/ + "pmullw %%mm6, %%mm4 \n\t" /* 0,9,9,0*/ + "punpcklbw %%mm0, %%mm1 \n\t" + "punpcklbw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" /*-1,9,9,0*/ + "psubw %%mm2, %%mm4 \n\t" /*-1,9,9,0*/ + "movd 0(%0,%2), %%mm1 \n\t" + "movd 4(%0,%2), %%mm2 \n\t" + "punpcklbw %%mm0, %%mm1 \n\t" + "punpcklbw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" /*-1,9,9,-1*/ + "psubw %%mm2, %%mm4 \n\t" /*-1,9,9,-1*/ + NORMALIZE_MMX("$4") + "packuswb %%mm4, %%mm3 \n\t" + "movq %%mm3, (%1) \n\t" + "add %6, %0 \n\t" + "add %4, %1 \n\t" + "dec %%"REG_c" \n\t" + "jnz 1b \n\t" + : "+r"(src), "+r"(dst) + : "r"(offset), "r"(-2*offset), "g"(stride), "m"(rnd), + "g"(stride-offset) + : "%"REG_c, "memory" + ); +} + +/** + * Filter coefficients made global to allow access by all 1 or 3 quarter shift + * interpolation functions. + */ +DECLARE_ALIGNED_16(const uint64_t, ff_pw_53) = 0x0035003500350035ULL; +DECLARE_ALIGNED_16(const uint64_t, ff_pw_18) = 0x0012001200120012ULL; + +/** + * Core of the 1/4 and 3/4 shift bicubic interpolation. + * + * @param UNPACK Macro unpacking arguments from 8 to 16bits (can be empty). + * @param MOVQ "movd 1" or "movq 2", if data read is already unpacked. + * @param A1 Address of 1st tap (beware of unpacked/packed). + * @param A2 Address of 2nd tap + * @param A3 Address of 3rd tap + * @param A4 Address of 4th tap + */ +#define MSPEL_FILTER13_CORE(UNPACK, MOVQ, A1, A2, A3, A4) \ + MOVQ "*0+"A1", %%mm1 \n\t" \ + MOVQ "*4+"A1", %%mm2 \n\t" \ + UNPACK("%%mm1") \ + UNPACK("%%mm2") \ + "pmullw "MANGLE(ff_pw_3)", %%mm1\n\t" \ + "pmullw "MANGLE(ff_pw_3)", %%mm2\n\t" \ + MOVQ "*0+"A2", %%mm3 \n\t" \ + MOVQ "*4+"A2", %%mm4 \n\t" \ + UNPACK("%%mm3") \ + UNPACK("%%mm4") \ + "pmullw %%mm6, %%mm3 \n\t" /* *18 */ \ + "pmullw %%mm6, %%mm4 \n\t" /* *18 */ \ + "psubw %%mm1, %%mm3 \n\t" /* 18,-3 */ \ + "psubw %%mm2, %%mm4 \n\t" /* 18,-3 */ \ + MOVQ "*0+"A4", %%mm1 \n\t" \ + MOVQ "*4+"A4", %%mm2 \n\t" \ + UNPACK("%%mm1") \ + UNPACK("%%mm2") \ + "psllw $2, %%mm1 \n\t" /* 4* */ \ + "psllw $2, %%mm2 \n\t" /* 4* */ \ + "psubw %%mm1, %%mm3 \n\t" /* -4,18,-3 */ \ + "psubw %%mm2, %%mm4 \n\t" /* -4,18,-3 */ \ + MOVQ "*0+"A3", %%mm1 \n\t" \ + MOVQ "*4+"A3", %%mm2 \n\t" \ + UNPACK("%%mm1") \ + UNPACK("%%mm2") \ + "pmullw %%mm5, %%mm1 \n\t" /* *53 */ \ + "pmullw %%mm5, %%mm2 \n\t" /* *53 */ \ + "paddw %%mm1, %%mm3 \n\t" /* 4,53,18,-3 */ \ + "paddw %%mm2, %%mm4 \n\t" /* 4,53,18,-3 */ + +/** + * Macro to build the vertical 16bits version of vc1_put_shift[13]. + * Here, offset=src_stride. Parameters passed A1 to A4 must use + * %3 (src_stride) and %4 (3*src_stride). + * + * @param NAME Either 1 or 3 + * @see MSPEL_FILTER13_CORE for information on A1->A4 + */ +#define MSPEL_FILTER13_VER_16B(NAME, A1, A2, A3, A4) \ +static void \ +vc1_put_ver_16b_ ## NAME ## _mmx(int16_t *dst, const uint8_t *src, \ + long int src_stride, \ + int rnd, int64_t shift) \ +{ \ + int h = 8; \ + src -= src_stride; \ + asm volatile( \ + LOAD_ROUNDER_MMX("%5") \ + "movq "MANGLE(ff_pw_53)", %%mm5\n\t" \ + "movq "MANGLE(ff_pw_18)", %%mm6\n\t" \ + ASMALIGN(3) \ + "1: \n\t" \ + MSPEL_FILTER13_CORE(DO_UNPACK, "movd 1", A1, A2, A3, A4) \ + NORMALIZE_MMX("%6") \ + TRANSFER_DONT_PACK \ + /* Last 3 (in fact 4) bytes on the line */ \ + "movd 8+"A1", %%mm1 \n\t" \ + DO_UNPACK("%%mm1") \ + "movq %%mm1, %%mm3 \n\t" \ + "paddw %%mm1, %%mm1 \n\t" \ + "paddw %%mm3, %%mm1 \n\t" /* 3* */ \ + "movd 8+"A2", %%mm3 \n\t" \ + DO_UNPACK("%%mm3") \ + "pmullw %%mm6, %%mm3 \n\t" /* *18 */ \ + "psubw %%mm1, %%mm3 \n\t" /*18,-3 */ \ + "movd 8+"A3", %%mm1 \n\t" \ + DO_UNPACK("%%mm1") \ + "pmullw %%mm5, %%mm1 \n\t" /* *53 */ \ + "paddw %%mm1, %%mm3 \n\t" /*53,18,-3 */ \ + "movd 8+"A4", %%mm1 \n\t" \ + DO_UNPACK("%%mm1") \ + "psllw $2, %%mm1 \n\t" /* 4* */ \ + "psubw %%mm1, %%mm3 \n\t" \ + "paddw %%mm7, %%mm3 \n\t" \ + "psraw %6, %%mm3 \n\t" \ + "movq %%mm3, 16(%2) \n\t" \ + "add %3, %1 \n\t" \ + "add $24, %2 \n\t" \ + "decl %0 \n\t" \ + "jnz 1b \n\t" \ + : "+r"(h), "+r" (src), "+r" (dst) \ + : "r"(src_stride), "r"(3*src_stride), \ + "m"(rnd), "m"(shift) \ + : "memory" \ + ); \ +} + +/** + * Macro to build the horizontal 16bits version of vc1_put_shift[13]. + * Here, offset=16bits, so parameters passed A1 to A4 should be simple. + * + * @param NAME Either 1 or 3 + * @see MSPEL_FILTER13_CORE for information on A1->A4 + */ +#define MSPEL_FILTER13_HOR_16B(NAME, A1, A2, A3, A4) \ +static void \ +vc1_put_hor_16b_ ## NAME ## _mmx(uint8_t *dst, long int stride, \ + const int16_t *src, int rnd) \ +{ \ + int h = 8; \ + src -= 1; \ + rnd -= (-4+58+13-3)*256; /* Add -256 bias */ \ + asm volatile( \ + LOAD_ROUNDER_MMX("%4") \ + "movq "MANGLE(ff_pw_18)", %%mm6 \n\t" \ + "movq "MANGLE(ff_pw_53)", %%mm5 \n\t" \ + ASMALIGN(3) \ + "1: \n\t" \ + MSPEL_FILTER13_CORE(DONT_UNPACK, "movq 2", A1, A2, A3, A4) \ + NORMALIZE_MMX("$7") \ + /* Remove bias */ \ + "paddw "MANGLE(ff_pw_128)", %%mm3 \n\t" \ + "paddw "MANGLE(ff_pw_128)", %%mm4 \n\t" \ + TRANSFER_DO_PACK \ + "add $24, %1 \n\t" \ + "add %3, %2 \n\t" \ + "decl %0 \n\t" \ + "jnz 1b \n\t" \ + : "+r"(h), "+r" (src), "+r" (dst) \ + : "r"(stride), "m"(rnd) \ + : "memory" \ + ); \ +} + +/** + * Macro to build the 8bits, any direction, version of vc1_put_shift[13]. + * Here, offset=src_stride. Parameters passed A1 to A4 must use + * %3 (offset) and %4 (3*offset). + * + * @param NAME Either 1 or 3 + * @see MSPEL_FILTER13_CORE for information on A1->A4 + */ +#define MSPEL_FILTER13_8B(NAME, A1, A2, A3, A4) \ +static void \ +vc1_put_## NAME ## _mmx(uint8_t *dst, const uint8_t *src, \ + long int stride, int rnd, long int offset) \ +{ \ + int h = 8; \ + src -= offset; \ + rnd = 32-rnd; \ + asm volatile ( \ + LOAD_ROUNDER_MMX("%6") \ + "movq "MANGLE(ff_pw_53)", %%mm5 \n\t" \ + "movq "MANGLE(ff_pw_18)", %%mm6 \n\t" \ + ASMALIGN(3) \ + "1: \n\t" \ + MSPEL_FILTER13_CORE(DO_UNPACK, "movd 1", A1, A2, A3, A4) \ + NORMALIZE_MMX("$6") \ + TRANSFER_DO_PACK \ + "add %5, %1 \n\t" \ + "add %5, %2 \n\t" \ + "decl %0 \n\t" \ + "jnz 1b \n\t" \ + : "+r"(h), "+r" (src), "+r" (dst) \ + : "r"(offset), "r"(3*offset), "g"(stride), "m"(rnd) \ + : "memory" \ + ); \ +} + +/** 1/4 shift bicubic interpolation */ +MSPEL_FILTER13_8B (shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )") +MSPEL_FILTER13_VER_16B(shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )") +MSPEL_FILTER13_HOR_16B(shift1, "2*3(%1)", "2*2(%1)", "2*1(%1)", "2*0(%1)") + +/** 3/4 shift bicubic interpolation */ +MSPEL_FILTER13_8B (shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )") +MSPEL_FILTER13_VER_16B(shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )") +MSPEL_FILTER13_HOR_16B(shift3, "2*0(%1)", "2*1(%1)", "2*2(%1)", "2*3(%1)") + +typedef void (*vc1_mspel_mc_filter_ver_16bits)(int16_t *dst, const uint8_t *src, long int src_stride, int rnd, int64_t shift); +typedef void (*vc1_mspel_mc_filter_hor_16bits)(uint8_t *dst, long int dst_stride, const int16_t *src, int rnd); +typedef void (*vc1_mspel_mc_filter_8bits)(uint8_t *dst, const uint8_t *src, long int stride, int rnd, long int offset); + +/** + * Interpolates fractional pel values by applying proper vertical then + * horizontal filter. + * + * @param dst Destination buffer for interpolated pels. + * @param src Source buffer. + * @param stride Stride for both src and dst buffers. + * @param hmode Horizontal filter (expressed in quarter pixels shift). + * @param hmode Vertical filter. + * @param rnd Rounding bias. + */ +static void vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, + int hmode, int vmode, int rnd) +{ + static const vc1_mspel_mc_filter_ver_16bits vc1_put_shift_ver_16bits[] = + { NULL, vc1_put_ver_16b_shift1_mmx, vc1_put_ver_16b_shift2_mmx, vc1_put_ver_16b_shift3_mmx }; + static const vc1_mspel_mc_filter_hor_16bits vc1_put_shift_hor_16bits[] = + { NULL, vc1_put_hor_16b_shift1_mmx, vc1_put_hor_16b_shift2_mmx, vc1_put_hor_16b_shift3_mmx }; + static const vc1_mspel_mc_filter_8bits vc1_put_shift_8bits[] = + { NULL, vc1_put_shift1_mmx, vc1_put_shift2_mmx, vc1_put_shift3_mmx }; + + asm volatile( + "pxor %%mm0, %%mm0 \n\t" + ::: "memory" + ); + + if (vmode) { /* Vertical filter to apply */ + if (hmode) { /* Horizontal filter to apply, output to tmp */ + static const int shift_value[] = { 0, 5, 1, 5 }; + int shift = (shift_value[hmode]+shift_value[vmode])>>1; + int r; + DECLARE_ALIGNED_16(int16_t, tmp[12*8]); + + r = (1<<(shift-1)) + rnd-1; + vc1_put_shift_ver_16bits[vmode](tmp, src-1, stride, r, shift); + + vc1_put_shift_hor_16bits[hmode](dst, stride, tmp+1, 64-rnd); + return; + } + else { /* No horizontal filter, output 8 lines to dst */ + vc1_put_shift_8bits[vmode](dst, src, stride, 1-rnd, stride); + return; + } + } + + /* Horizontal mode with no vertical mode */ + vc1_put_shift_8bits[hmode](dst, src, stride, rnd, 1); +} + +void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd); + +/** Macro to ease bicubic filter interpolation functions declarations */ +#define DECLARE_FUNCTION(a, b) \ +static void put_vc1_mspel_mc ## a ## b ## _mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \ + vc1_mspel_mc(dst, src, stride, a, b, rnd); \ +} + +DECLARE_FUNCTION(0, 1) +DECLARE_FUNCTION(0, 2) +DECLARE_FUNCTION(0, 3) + +DECLARE_FUNCTION(1, 0) +DECLARE_FUNCTION(1, 1) +DECLARE_FUNCTION(1, 2) +DECLARE_FUNCTION(1, 3) + +DECLARE_FUNCTION(2, 0) +DECLARE_FUNCTION(2, 1) +DECLARE_FUNCTION(2, 2) +DECLARE_FUNCTION(2, 3) + +DECLARE_FUNCTION(3, 0) +DECLARE_FUNCTION(3, 1) +DECLARE_FUNCTION(3, 2) +DECLARE_FUNCTION(3, 3) + +void ff_vc1dsp_init_mmx(DSPContext* dsp, AVCodecContext *avctx) { + dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_mmx; + dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_mmx; + dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_mmx; + dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_mmx; + + dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_mmx; + dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_mmx; + dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_mmx; + dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_mmx; + + dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_mmx; + dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_mmx; + dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_mmx; + dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_mmx; + + dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_mmx; + dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_mmx; + dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_mmx; + dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_mmx; +} diff --git a/contrib/ffmpeg/libavcodec/i386/vp3dsp_mmx.c b/contrib/ffmpeg/libavcodec/i386/vp3dsp_mmx.c index f715dc803..d71a2b414 100644 --- a/contrib/ffmpeg/libavcodec/i386/vp3dsp_mmx.c +++ b/contrib/ffmpeg/libavcodec/i386/vp3dsp_mmx.c @@ -23,7 +23,7 @@ * MMX-optimized functions cribbed from the original VP3 source code. */ -#include "../dsputil.h" +#include "dsputil.h" #include "mmx.h" #define IdctAdjustBeforeShift 8 @@ -322,3 +322,15 @@ void ff_vp3_idct_mmx(int16_t *output_data) #undef J } + +void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_vp3_idct_mmx(block); + put_signed_pixels_clamped_mmx(block, dest, line_size); +} + +void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_vp3_idct_mmx(block); + add_pixels_clamped_mmx(block, dest, line_size); +} diff --git a/contrib/ffmpeg/libavcodec/i386/vp3dsp_mmx.h b/contrib/ffmpeg/libavcodec/i386/vp3dsp_mmx.h new file mode 100644 index 000000000..7c2bc601b --- /dev/null +++ b/contrib/ffmpeg/libavcodec/i386/vp3dsp_mmx.h @@ -0,0 +1,32 @@ +/* + * vp3dsp MMX function declarations + * Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> + * + * 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 + */ + +#ifndef FFMPEG_VP3DSP_MMX_H +#define FFMPEG_VP3DSP_MMX_H + +#include "dsputil.h" + +void ff_vp3_idct_mmx(int16_t *data); +void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block); +void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block); +void ff_vp3_dsp_init_mmx(void); + +#endif /* FFMPEG_VP3DSP_MMX_H */ diff --git a/contrib/ffmpeg/libavcodec/i386/vp3dsp_sse2.c b/contrib/ffmpeg/libavcodec/i386/vp3dsp_sse2.c index bd2911d59..3105e7f5f 100644 --- a/contrib/ffmpeg/libavcodec/i386/vp3dsp_sse2.c +++ b/contrib/ffmpeg/libavcodec/i386/vp3dsp_sse2.c @@ -23,7 +23,7 @@ * SSE2-optimized functions cribbed from the original VP3 source code. */ -#include "../dsputil.h" +#include "dsputil.h" #include "mmx.h" static DECLARE_ALIGNED_16(const unsigned short, SSE2_dequant_const[]) = @@ -802,8 +802,8 @@ void ff_vp3_idct_sse2(int16_t *input_data) { unsigned char *input_bytes = (unsigned char *)input_data; unsigned char *output_data_bytes = (unsigned char *)input_data; - unsigned char *idct_data_bytes = (unsigned char *)SSE2_idct_data; - unsigned char *Eight = (unsigned char *)eight_data; + const unsigned char *idct_data_bytes = (const unsigned char *)SSE2_idct_data; + const unsigned char *Eight = (const unsigned char *)eight_data; #define eax input_bytes //#define ebx dequant_matrix_bytes @@ -825,3 +825,15 @@ void ff_vp3_idct_sse2(int16_t *input_data) SSE2_Column_IDCT(); } + +void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_vp3_idct_sse2(block); + put_signed_pixels_clamped_mmx(block, dest, line_size); +} + +void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_vp3_idct_sse2(block); + add_pixels_clamped_mmx(block, dest, line_size); +} diff --git a/contrib/ffmpeg/libavcodec/i386/vp3dsp_sse2.h b/contrib/ffmpeg/libavcodec/i386/vp3dsp_sse2.h new file mode 100644 index 000000000..d02918f45 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/i386/vp3dsp_sse2.h @@ -0,0 +1,31 @@ +/* + * vp3dsp SSE2 function declarations + * Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> + * + * 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 + */ + +#ifndef FFMPEG_VP3DSP_SSE2_H +#define FFMPEG_VP3DSP_SSE2_H + +#include "dsputil.h" + +void ff_vp3_idct_sse2(int16_t *input_data); +void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block); +void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block); + +#endif /* FFMPEG_VP3DSP_SSE2_H */ diff --git a/contrib/ffmpeg/libavcodec/idcinvideo.c b/contrib/ffmpeg/libavcodec/idcinvideo.c index 112da7bc6..79ed6fb17 100644 --- a/contrib/ffmpeg/libavcodec/idcinvideo.c +++ b/contrib/ffmpeg/libavcodec/idcinvideo.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -50,7 +49,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -71,7 +69,7 @@ typedef struct IdcinContext { DSPContext dsp; AVFrame frame; - unsigned char *buf; + const unsigned char *buf; int size; hnode_t huff_nodes[256][HUF_TOKENS*2]; @@ -149,13 +147,12 @@ static void huff_build_tree(IdcinContext *s, int prev) { static int idcin_decode_init(AVCodecContext *avctx) { - IdcinContext *s = (IdcinContext *)avctx->priv_data; + IdcinContext *s = avctx->priv_data; int i, j, histogram_index = 0; unsigned char *histograms; s->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; dsputil_init(&s->dsp, avctx); /* make sure the Huffman tables make it */ @@ -215,9 +212,9 @@ static void idcin_decode_vlcs(IdcinContext *s) static int idcin_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - IdcinContext *s = (IdcinContext *)avctx->priv_data; + IdcinContext *s = avctx->priv_data; AVPaletteControl *palette_control = avctx->palctrl; s->buf = buf; @@ -250,7 +247,7 @@ static int idcin_decode_frame(AVCodecContext *avctx, static int idcin_decode_end(AVCodecContext *avctx) { - IdcinContext *s = (IdcinContext *)avctx->priv_data; + IdcinContext *s = avctx->priv_data; if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); diff --git a/contrib/ffmpeg/libavcodec/imc.c b/contrib/ffmpeg/libavcodec/imc.c index 6140130b1..237ff6816 100644 --- a/contrib/ffmpeg/libavcodec/imc.c +++ b/contrib/ffmpeg/libavcodec/imc.c @@ -19,7 +19,6 @@ * 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 - * */ /** @@ -42,6 +41,7 @@ #include "imcdata.h" +#define IMC_BLOCK_SIZE 64 #define IMC_FRAME_ID 0x21 #define BANDS 32 #define COEFFS 256 @@ -455,7 +455,7 @@ static void imc_get_skip_coeff(IMCContext* q) { q->skipFlagBits[i] = band_tab[i+1] - band_tab[i]; for(j = band_tab[i]; j < band_tab[i+1]; j++) { - if ((q->skipFlags[j] = get_bits(&q->gb,1))) + if ((q->skipFlags[j] = get_bits1(&q->gb))) q->skipFlagCount[i]++; } } else { @@ -486,7 +486,7 @@ static void imc_get_skip_coeff(IMCContext* q) { if (j < band_tab[i+1]) { q->skipFlagBits[i]++; - if ((q->skipFlags[j] = get_bits(&q->gb,1))) + if ((q->skipFlags[j] = get_bits1(&q->gb))) q->skipFlagCount[i]++; } } @@ -626,7 +626,7 @@ static int imc_get_coeffs (IMCContext* q) { static int imc_decode_frame(AVCodecContext * avctx, void *data, int *data_size, - uint8_t * buf, int buf_size) + const uint8_t * buf, int buf_size) { IMCContext *q = avctx->priv_data; @@ -636,13 +636,16 @@ static int imc_decode_frame(AVCodecContext * avctx, int flag; int bits, summer; int counter, bitscount; - uint16_t *buf16 = (uint16_t *) buf; + uint16_t buf16[IMC_BLOCK_SIZE / 2]; - /* FIXME: input should not be modified */ - for(i = 0; i < FFMIN(buf_size, avctx->block_align) / 2; i++) - buf16[i] = bswap_16(buf16[i]); + if (buf_size < IMC_BLOCK_SIZE) { + av_log(avctx, AV_LOG_ERROR, "imc frame too small!\n"); + return -1; + } + for(i = 0; i < IMC_BLOCK_SIZE / 2; i++) + buf16[i] = bswap_16(((const uint16_t*)buf)[i]); - init_get_bits(&q->gb, buf, 512); + init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8); /* Check the frame header */ imc_hdr = get_bits(&q->gb, 9); @@ -789,7 +792,7 @@ static int imc_decode_frame(AVCodecContext * avctx, *data_size = COEFFS * sizeof(int16_t); - return avctx->block_align; + return IMC_BLOCK_SIZE; } diff --git a/contrib/ffmpeg/libavcodec/imcdata.h b/contrib/ffmpeg/libavcodec/imcdata.h index 92ed275f1..75f4fd744 100644 --- a/contrib/ffmpeg/libavcodec/imcdata.h +++ b/contrib/ffmpeg/libavcodec/imcdata.h @@ -19,9 +19,13 @@ * 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 - * */ +#ifndef FFMPEG_IMCDATA_H +#define FFMPEG_IMCDATA_H + +#include <stdint.h> + static const uint16_t band_tab[33] = { 0, 3, 6, 9, 12, 16, 20, 24, 29, 34, 40, 46, 53, 60, 68, 76, 84, 93, 102, 111, 121, 131, @@ -162,3 +166,4 @@ static const uint16_t imc_huffman_bits[4][4][18] = { } }; +#endif /* FFMPEG_IMCDATA_H */ diff --git a/contrib/ffmpeg/libavcodec/imgconvert.c b/contrib/ffmpeg/libavcodec/imgconvert.c index 2971afaa8..468035f36 100644 --- a/contrib/ffmpeg/libavcodec/imgconvert.c +++ b/contrib/ffmpeg/libavcodec/imgconvert.c @@ -1,5 +1,5 @@ /* - * Misc image convertion routines + * Misc image conversion routines * Copyright (c) 2001, 2002, 2003 Fabrice Bellard. * * This file is part of FFmpeg. @@ -21,7 +21,7 @@ /** * @file imgconvert.c - * Misc image convertion routines. + * misc image conversion routines */ /* TODO: @@ -32,10 +32,7 @@ #include "avcodec.h" #include "dsputil.h" - -#ifdef USE_FASTMEMCPY -#include "libvo/fastmemcpy.h" -#endif +#include "colorspace.h" #ifdef HAVE_MMX #include "i386/mmx.h" @@ -123,6 +120,24 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { .depth = 8, .x_chroma_shift = 2, .y_chroma_shift = 0, }, + [PIX_FMT_YUV440P] = { + .name = "yuv440p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 0, .y_chroma_shift = 1, + }, + + /* YUV formats with alpha plane */ + [PIX_FMT_YUVA420P] = { + .name = "yuva420p", + .nb_channels = 4, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, /* JPEG YUV */ [PIX_FMT_YUVJ420P] = { @@ -149,6 +164,14 @@ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { .depth = 8, .x_chroma_shift = 0, .y_chroma_shift = 0, }, + [PIX_FMT_YUVJ440P] = { + .name = "yuvj440p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV_JPEG, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 0, .y_chroma_shift = 1, + }, /* RGB formats */ [PIX_FMT_RGB24] = { @@ -382,64 +405,74 @@ enum PixelFormat avcodec_get_pix_fmt(const char* name) return i; } -int avpicture_fill(AVPicture *picture, uint8_t *ptr, - int pix_fmt, int width, int height) +void avcodec_pix_fmt_string (char *buf, int buf_size, int pix_fmt) +{ + PixFmtInfo info= pix_fmt_info[pix_fmt]; + + char is_alpha_char= info.is_alpha ? 'y' : 'n'; + + /* print header */ + if (pix_fmt < 0) + snprintf (buf, buf_size, + "name " " nb_channels" " depth" " is_alpha" + ); + else + snprintf (buf, buf_size, + "%-10s" " %1d " " %2d " " %c ", + info.name, + info.nb_channels, + info.depth, + is_alpha_char + ); +} + +int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width) { - int size, w2, h2, size2; + int w2; const PixFmtInfo *pinfo; - if(avcodec_check_dimensions(NULL, width, height)) - goto fail; + memset(picture->linesize, 0, sizeof(picture->linesize)); 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_YUV440P: case PIX_FMT_YUVJ420P: case PIX_FMT_YUVJ422P: case PIX_FMT_YUVJ444P: + case PIX_FMT_YUVJ440P: 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; + break; + case PIX_FMT_YUVA420P: + w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift; + picture->linesize[0] = width; + picture->linesize[1] = w2; + picture->linesize[2] = w2; + picture->linesize[3] = width; + break; 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; + break; 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; + break; case PIX_FMT_RGB32: 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; + break; case PIX_FMT_GRAY16BE: case PIX_FMT_GRAY16LE: case PIX_FMT_BGR555: @@ -447,57 +480,119 @@ int avpicture_fill(AVPicture *picture, uint8_t *ptr, case PIX_FMT_RGB555: case PIX_FMT_RGB565: case PIX_FMT_YUYV422: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; picture->linesize[0] = width * 2; - return size * 2; + break; case PIX_FMT_UYVY422: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; picture->linesize[0] = width * 2; - return size * 2; + break; case PIX_FMT_UYYVYY411: - picture->data[0] = ptr; - picture->data[1] = NULL; - picture->data[2] = NULL; picture->linesize[0] = width + width/2; - return size + size/2; + break; 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; + break; case PIX_FMT_RGB4: case PIX_FMT_BGR4: + picture->linesize[0] = width / 2; + break; + case PIX_FMT_MONOWHITE: + case PIX_FMT_MONOBLACK: + picture->linesize[0] = (width + 7) >> 3; + break; + case PIX_FMT_PAL8: + picture->linesize[0] = width; + picture->linesize[1] = 4; + break; + default: + return -1; + } + return 0; +} + +int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt, + int height) +{ + int size, h2, size2; + const PixFmtInfo *pinfo; + + pinfo = &pix_fmt_info[pix_fmt]; + size = picture->linesize[0] * 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_YUV440P: + case PIX_FMT_YUVJ420P: + case PIX_FMT_YUVJ422P: + case PIX_FMT_YUVJ444P: + case PIX_FMT_YUVJ440P: + h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; + size2 = picture->linesize[1] * h2; picture->data[0] = ptr; - picture->data[1] = NULL; + picture->data[1] = picture->data[0] + size; + picture->data[2] = picture->data[1] + size2; + picture->data[3] = NULL; + return size + 2 * size2; + case PIX_FMT_YUVA420P: + h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; + size2 = picture->linesize[1] * h2; + picture->data[0] = ptr; + picture->data[1] = picture->data[0] + size; + picture->data[2] = picture->data[1] + size2; + picture->data[3] = picture->data[1] + size2 + size2; + return 2 * size + 2 * size2; + case PIX_FMT_NV12: + case PIX_FMT_NV21: + h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; + size2 = picture->linesize[1] * h2 * 2; + picture->data[0] = ptr; + picture->data[1] = picture->data[0] + size; picture->data[2] = NULL; - picture->linesize[0] = width / 2; - return size / 2; + picture->data[3] = NULL; + return size + 2 * size2; + case PIX_FMT_RGB24: + case PIX_FMT_BGR24: + case PIX_FMT_RGB32: + case PIX_FMT_BGR32: + case PIX_FMT_RGB32_1: + case PIX_FMT_BGR32_1: + case PIX_FMT_GRAY16BE: + case PIX_FMT_GRAY16LE: + case PIX_FMT_BGR555: + case PIX_FMT_BGR565: + case PIX_FMT_RGB555: + case PIX_FMT_RGB565: + case PIX_FMT_YUYV422: + case PIX_FMT_UYVY422: + case PIX_FMT_UYYVYY411: + case PIX_FMT_RGB8: + case PIX_FMT_BGR8: + case PIX_FMT_RGB4_BYTE: + case PIX_FMT_BGR4_BYTE: + case PIX_FMT_GRAY8: + case PIX_FMT_RGB4: + case PIX_FMT_BGR4: 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; + picture->data[3] = NULL; + return size; 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; + picture->data[3] = NULL; return size2 + 256 * 4; default: -fail: picture->data[0] = NULL; picture->data[1] = NULL; picture->data[2] = NULL; @@ -506,6 +601,19 @@ fail: } } +int avpicture_fill(AVPicture *picture, uint8_t *ptr, + int pix_fmt, int width, int height) +{ + + if(avcodec_check_dimensions(NULL, width, height)) + return -1; + + if (ff_fill_linesize(picture, pix_fmt, width)) + return -1; + + return ff_fill_pointer(picture, ptr, pix_fmt, height); +} + int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, unsigned char *dest, int dest_size) { @@ -733,10 +841,9 @@ void ff_img_copy_plane(uint8_t *dst, int dst_wrap, } } -void av_picture_copy(AVPicture *dst, const AVPicture *src, - int pix_fmt, int width, int height) +int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane) { - int bwidth, bits, i; + int bits; const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; pf = &pix_fmt_info[pix_fmt]; @@ -758,21 +865,42 @@ void av_picture_copy(AVPicture *dst, const AVPicture *src, 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); + return (width * bits + 7) >> 3; break; case FF_PIXEL_PLANAR: + if (plane == 1 || plane == 2) + width >>= pf->x_chroma_shift; + + return (width * pf->depth + 7) >> 3; + break; + case FF_PIXEL_PALETTE: + if (plane == 0) + return width; + break; + } + + return -1; +} + +void av_picture_copy(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height) +{ + int i; + const PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; + + pf = &pix_fmt_info[pix_fmt]; + switch(pf->pixel_type) { + case FF_PIXEL_PACKED: + case FF_PIXEL_PLANAR: for(i = 0; i < pf->nb_channels; i++) { int w, h; + int bwidth = ff_get_plane_bytewidth(pix_fmt, width, i); 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); @@ -1141,87 +1269,6 @@ static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src, } } -#define SCALEBITS 10 -#define ONE_HALF (1 << (SCALEBITS - 1)) -#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5)) - -#define YUV_TO_RGB1_CCIR(cb1, cr1)\ -{\ - cb = (cb1) - 128;\ - cr = (cr1) - 128;\ - r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;\ - g_add = - FIX(0.34414*255.0/224.0) * cb - FIX(0.71414*255.0/224.0) * cr + \ - ONE_HALF;\ - b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\ -} - -#define YUV_TO_RGB2_CCIR(r, g, b, y1)\ -{\ - y = ((y1) - 16) * FIX(255.0/219.0);\ - r = cm[(y + r_add) >> 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]; @@ -1501,6 +1548,20 @@ static void grow21(uint8_t *dst, int dst_wrap, } } +/* 1x1 -> 1x2 */ +static void grow12(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + for(;height > 0; height-=2) { + memcpy(dst, src, width); + dst += dst_wrap; + memcpy(dst, src, width); + dst += dst_wrap; + src += src_wrap; + } +} + /* 1x1 -> 2x2 */ static void grow22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, @@ -1886,7 +1947,9 @@ static void gray16be_to_gray(AVPicture *dst, const AVPicture *src, static void gray16le_to_gray(AVPicture *dst, const AVPicture *src, int width, int height) { - gray16_to_gray(dst, src + 1, width, height); + AVPicture tmpsrc = *src; + tmpsrc.data[0]++; + gray16_to_gray(dst, &tmpsrc, width, height); } static void gray16_to_gray16(AVPicture *dst, const AVPicture *src, @@ -1894,9 +1957,9 @@ static void gray16_to_gray16(AVPicture *dst, const AVPicture *src, { int x, y, src_wrap, dst_wrap; uint16_t *s, *d; - s = src->data[0]; + s = (uint16_t*)src->data[0]; src_wrap = (src->linesize[0] - width * 2)/2; - d = dst->data[0]; + d = (uint16_t*)dst->data[0]; dst_wrap = (dst->linesize[0] - width * 2)/2; for(y=0; y<height; y++){ for(x=0; x<width; x++){ @@ -1913,7 +1976,7 @@ typedef struct ConvertEntry { const AVPicture *src, int width, int height); } ConvertEntry; -/* Add each new convertion function in this table. In order to be able +/* Add each new conversion function in this table. In order to be able to convert from any format to any format, the following constraints must be satisfied: @@ -1928,7 +1991,7 @@ typedef struct ConvertEntry { - PIX_FMT_422 must convert to and from PIX_FMT_422P. - The other conversion functions are just optimisations for common cases. + The other conversion functions are just optimizations for common cases. */ static const ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = { [PIX_FMT_YUV420P] = { @@ -2323,7 +2386,7 @@ 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; + static int initialized; int i, ret, dst_width, dst_height, int_pix_fmt; const PixFmtInfo *src_pix, *dst_pix; const ConvertEntry *ce; @@ -2335,8 +2398,8 @@ int img_convert(AVPicture *dst, int dst_pix_fmt, if (src_width <= 0 || src_height <= 0) return 0; - if (!inited) { - inited = 1; + if (!initialized) { + initialized = 1; img_convert_init(); } @@ -2451,6 +2514,9 @@ int img_convert(AVPicture *dst, int dst_pix_fmt, case 0xf0: resize_func = grow21; break; + case 0x0f: + resize_func = grow12; + break; case 0xe0: resize_func = grow41; break; @@ -2545,6 +2611,8 @@ int img_convert(AVPicture *dst, int dst_pix_fmt, else int_pix_fmt = PIX_FMT_RGB24; } + if (src_pix_fmt == int_pix_fmt) + return -1; if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0) return -1; ret = -1; @@ -2814,7 +2882,8 @@ int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, if (pix_fmt != PIX_FMT_YUV420P && pix_fmt != PIX_FMT_YUV422P && pix_fmt != PIX_FMT_YUV444P && - pix_fmt != PIX_FMT_YUV411P) + pix_fmt != PIX_FMT_YUV411P && + pix_fmt != PIX_FMT_GRAY8) return -1; if ((width & 3) != 0 || (height & 3) != 0) return -1; @@ -2835,6 +2904,9 @@ int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, default: break; } + if (pix_fmt == PIX_FMT_GRAY8) { + break; + } } if (src == dst) { deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], @@ -2845,10 +2917,7 @@ int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, width, height); } } -#ifdef HAVE_MMX - emms(); -#endif + emms_c(); return 0; } -#undef FIX diff --git a/contrib/ffmpeg/libavcodec/imgconvert.h b/contrib/ffmpeg/libavcodec/imgconvert.h new file mode 100644 index 000000000..2370aa6f7 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/imgconvert.h @@ -0,0 +1,33 @@ +/* + * Misc image conversion routines + * most functionality is exported to the public API, see avcodec.h + * + * Copyright (c) 2008 Vitor Sessak + * + * 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 + */ + +#ifndef FFMPEG_IMGCONVERT_H +#define FFMPEG_IMGCONVERT_H + +int ff_fill_linesize(AVPicture *picture, int pix_fmt, int width); + +int ff_fill_pointer(AVPicture *picture, uint8_t *ptr, int pix_fmt, int height); + +int ff_get_plane_bytewidth(enum PixelFormat pix_fmt, int width, int plane); + +#endif /* FFMPEG_IMGCONVERT_H */ diff --git a/contrib/ffmpeg/libavcodec/imgconvert_template.h b/contrib/ffmpeg/libavcodec/imgconvert_template.h index 70c090bad..2d23be87b 100644 --- a/contrib/ffmpeg/libavcodec/imgconvert_template.h +++ b/contrib/ffmpeg/libavcodec/imgconvert_template.h @@ -1,5 +1,5 @@ /* - * Templates for image convertion routines + * templates for image conversion routines * Copyright (c) 2001, 2002, 2003 Fabrice Bellard. * * This file is part of FFmpeg. @@ -19,6 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/* This header intentionally has no multiple inclusion guards. It is meant to + * be included multiple times and generates different code depending on the + * value of certain #defines. */ + #ifndef RGB_OUT #define RGB_OUT(d, r, g, b) RGBA_OUT(d, r, g, b, 0xff) #endif @@ -410,7 +414,7 @@ static void glue(pal8_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src, } } -// RGB24 has optimised routines +// RGB24 has optimized routines #if !defined(FMT_RGB32) && !defined(FMT_RGB24) /* alpha support */ diff --git a/contrib/ffmpeg/libavcodec/imgresample.c b/contrib/ffmpeg/libavcodec/imgresample.c index 2722d5acf..c481e9df3 100644 --- a/contrib/ffmpeg/libavcodec/imgresample.c +++ b/contrib/ffmpeg/libavcodec/imgresample.c @@ -28,8 +28,8 @@ #include "swscale.h" #include "dsputil.h" -#ifdef USE_FASTMEMCPY -#include "libvo/fastmemcpy.h" +#ifdef HAVE_ALTIVEC +#include "ppc/imgresample_altivec.h" #endif #define NB_COMPONENTS 3 @@ -48,6 +48,7 @@ #define LINE_BUF_HEIGHT (NB_TAPS * 4) struct SwsContext { + AVClass *av_class; struct ImgReSampleContext *resampling_ctx; enum PixelFormat src_pix_fmt, dst_pix_fmt; }; @@ -282,136 +283,9 @@ static void v_resample4_mmx(uint8_t *dst, int dst_width, const uint8_t *src, } 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); - +#endif /* HAVE_MMX */ - /* - 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 */ +/* slow version to handle limit cases. Does not need optimization */ 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) @@ -517,7 +391,7 @@ static void component_resample(ImgReSampleContext *s, h_resample(new_line, owidth, src_line, iwidth, - FCENTER * POS_FRAC, s->h_incr, &s->h_filters[0][0]); - /* handle ring buffer wraping */ + /* handle ring buffer wrapping */ if (ring_y >= LINE_BUF_HEIGHT) { memcpy(s->line_buf + (ring_y - LINE_BUF_HEIGHT) * owidth, new_line, owidth); @@ -646,7 +520,9 @@ struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, struct SwsContext *ctx; ctx = av_malloc(sizeof(struct SwsContext)); - if (ctx == NULL) { + if (ctx) + ctx->av_class = av_mallocz(sizeof(AVClass)); + if (!ctx || !ctx->av_class) { av_log(NULL, AV_LOG_ERROR, "Cannot allocate a resampling context!\n"); return NULL; @@ -680,6 +556,7 @@ void sws_freeContext(struct SwsContext *ctx) } else { av_free(ctx->resampling_ctx); } + av_free(ctx->av_class); av_free(ctx); } @@ -815,6 +692,7 @@ the_end: #ifdef TEST #include <stdio.h> +#undef exit /* input */ #define XSIZE 256 @@ -942,8 +820,8 @@ int main(int argc, char **argv) exit(1); } av_log(NULL, AV_LOG_INFO, "MMX OK\n"); -#endif +#endif /* HAVE_MMX */ return 0; } -#endif +#endif /* TEST */ diff --git a/contrib/ffmpeg/libavcodec/imx_dump_header_bsf.c b/contrib/ffmpeg/libavcodec/imx_dump_header_bsf.c new file mode 100644 index 000000000..5a844407b --- /dev/null +++ b/contrib/ffmpeg/libavcodec/imx_dump_header_bsf.c @@ -0,0 +1,59 @@ +/* + * imx dump header bitstream filter + * Copyright (c) 2007 Baptiste Coudurier. + * + * 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 imx_dump_header_bsf.c + * imx dump header bitstream filter + * modifies bitstream to fit in mov and be decoded by final cut pro decoder + */ + +#include "avcodec.h" +#include "bytestream.h" + + +static int imx_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe) +{ + /* MXF essence element key */ + static const uint8_t imx_header[16] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }; + uint8_t *poutbufp; + + if (avctx->codec_id != CODEC_ID_MPEG2VIDEO) { + av_log(avctx, AV_LOG_ERROR, "imx bitstream filter only applies to mpeg2video codec\n"); + return 0; + } + + *poutbuf = av_malloc(buf_size + 20 + FF_INPUT_BUFFER_PADDING_SIZE); + poutbufp = *poutbuf; + bytestream_put_buffer(&poutbufp, imx_header, 16); + bytestream_put_byte(&poutbufp, 0x83); /* KLV BER long form */ + bytestream_put_be24(&poutbufp, buf_size); + bytestream_put_buffer(&poutbufp, buf, buf_size); + *poutbuf_size = poutbufp - *poutbuf; + return 1; +} + +AVBitStreamFilter imx_dump_header_bsf = { + "imxdump", + 0, + imx_dump_header, +}; diff --git a/contrib/ffmpeg/libavcodec/indeo2.c b/contrib/ffmpeg/libavcodec/indeo2.c index 2b129d141..4a7e2d01f 100644 --- a/contrib/ffmpeg/libavcodec/indeo2.c +++ b/contrib/ffmpeg/libavcodec/indeo2.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -137,7 +136,7 @@ static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_ static int ir2_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { Ir2Context * const s = avctx->priv_data; AVFrame *picture = data; @@ -197,11 +196,13 @@ static int ir2_decode_init(AVCodecContext *avctx){ avctx->pix_fmt= PIX_FMT_YUV410P; if (!ir2_vlc.table) +#ifdef ALT_BITSTREAM_READER_LE init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, &ir2_codes[0][1], 4, 2, -#ifdef ALT_BITSTREAM_READER_LE &ir2_codes[0][0], 4, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); #else + init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, + &ir2_codes[0][1], 4, 2, &ir2_codes[0][0], 4, 2, INIT_VLC_USE_STATIC); #endif diff --git a/contrib/ffmpeg/libavcodec/indeo2data.h b/contrib/ffmpeg/libavcodec/indeo2data.h index 71d250af7..2be32dfc9 100644 --- a/contrib/ffmpeg/libavcodec/indeo2data.h +++ b/contrib/ffmpeg/libavcodec/indeo2data.h @@ -19,6 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_INDEO2DATA_H +#define FFMPEG_INDEO2DATA_H + +#include <stdint.h> + #define IR2_CODES 143 static const uint16_t ir2_codes[IR2_CODES][2] = { #ifdef ALT_BITSTREAM_READER_LE @@ -132,3 +137,5 @@ static const uint8_t ir2_luma_table[256] = { 0x28, 0x5C, 0x6C, 0xC1, 0x94, 0x3F, 0xC1, 0x6C, 0x3F, 0x94, 0xD9, 0xD9, 0x27, 0x27, 0x80, 0x80 }; + +#endif /* FFMPEG_INDEO2DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/indeo3.c b/contrib/ffmpeg/libavcodec/indeo3.c index 1b1914406..9237b5ec2 100644 --- a/contrib/ffmpeg/libavcodec/indeo3.c +++ b/contrib/ffmpeg/libavcodec/indeo3.c @@ -24,10 +24,10 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" +#include "bytestream.h" #include "indeo3data.h" @@ -55,13 +55,13 @@ typedef struct Indeo3DecodeContext { unsigned short *corrector_type; } Indeo3DecodeContext; -static int corrector_type_0[24] = { +static const int corrector_type_0[24] = { 195, 159, 133, 115, 101, 93, 87, 77, 195, 159, 133, 115, 101, 93, 87, 77, 128, 79, 79, 79, 79, 79, 79, 79 }; -static int corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 }; +static const int corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 }; static void build_modpred(Indeo3DecodeContext *s) { @@ -93,9 +93,9 @@ static void build_modpred(Indeo3DecodeContext *s) } static void iv_Decode_Chunk(Indeo3DecodeContext *s, unsigned char *cur, - unsigned char *ref, int width, int height, unsigned char *buf1, - long fflags2, unsigned char *hdr, - unsigned char *buf2, int min_width_160); + unsigned char *ref, int width, int height, const unsigned char *buf1, + long fflags2, const unsigned char *hdr, + const unsigned char *buf2, int min_width_160); /* ---------------------------------------------------------------------- */ static void iv_alloc_frames(Indeo3DecodeContext *s) @@ -177,38 +177,32 @@ static void iv_free_func(Indeo3DecodeContext *s) /* ---------------------------------------------------------------------- */ static unsigned long iv_decode_frame(Indeo3DecodeContext *s, - unsigned char *buf, int buf_size) + const unsigned char *buf, int buf_size) { unsigned int hdr_width, hdr_height, chroma_width, chroma_height; unsigned long fflags1, fflags2, fflags3, offs1, offs2, offs3, offs; - unsigned char *hdr_pos, *buf_pos; + const unsigned char *hdr_pos, *buf_pos; buf_pos = buf; buf_pos += 18; - fflags1 = le2me_16(*(uint16_t *)buf_pos); - buf_pos += 2; - fflags3 = le2me_32(*(uint32_t *)buf_pos); - buf_pos += 4; + fflags1 = bytestream_get_le16(&buf_pos); + fflags3 = bytestream_get_le32(&buf_pos); fflags2 = *buf_pos++; buf_pos += 3; - hdr_height = le2me_16(*(uint16_t *)buf_pos); - buf_pos += 2; - hdr_width = le2me_16(*(uint16_t *)buf_pos); + hdr_height = bytestream_get_le16(&buf_pos); + hdr_width = bytestream_get_le16(&buf_pos); if(avcodec_check_dimensions(NULL, hdr_width, hdr_height)) return -1; - buf_pos += 2; chroma_height = ((hdr_height >> 2) + 3) & 0x7ffc; chroma_width = ((hdr_width >> 2) + 3) & 0x7ffc; - offs1 = le2me_32(*(uint32_t *)buf_pos); - buf_pos += 4; - offs2 = le2me_32(*(uint32_t *)buf_pos); + offs1 = bytestream_get_le32(&buf_pos); + offs2 = bytestream_get_le32(&buf_pos); + offs3 = bytestream_get_le32(&buf_pos); buf_pos += 4; - offs3 = le2me_32(*(uint32_t *)buf_pos); - buf_pos += 8; hdr_pos = buf_pos; if(fflags3 == 0x80) return 4; @@ -221,8 +215,7 @@ static unsigned long iv_decode_frame(Indeo3DecodeContext *s, } buf_pos = buf + 16 + offs1; - offs = le2me_32(*(uint32_t *)buf_pos); - buf_pos += 4; + offs = bytestream_get_le32(&buf_pos); iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, hdr_width, hdr_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, @@ -232,16 +225,14 @@ static unsigned long iv_decode_frame(Indeo3DecodeContext *s, { buf_pos = buf + 16 + offs2; - offs = le2me_32(*(uint32_t *)buf_pos); - buf_pos += 4; + offs = bytestream_get_le32(&buf_pos); iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width, chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, FFMIN(chroma_width, 40)); buf_pos = buf + 16 + offs3; - offs = le2me_32(*(uint32_t *)buf_pos); - buf_pos += 4; + offs = bytestream_get_le32(&buf_pos); iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width, chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, @@ -308,13 +299,13 @@ typedef struct { static void iv_Decode_Chunk(Indeo3DecodeContext *s, unsigned char *cur, unsigned char *ref, int width, int height, - unsigned char *buf1, long fflags2, unsigned char *hdr, - unsigned char *buf2, int min_width_160) + const unsigned char *buf1, long fflags2, const unsigned char *hdr, + const unsigned char *buf2, int min_width_160) { unsigned char bit_buf; unsigned long bit_pos, lv, lv1, lv2; long *width_tbl, width_tbl_arr[10]; - signed char *ref_vectors; + const signed char *ref_vectors; unsigned char *cur_frm_pos, *ref_frm_pos, *cp, *cp2; uint32_t *cur_lp, *ref_lp; const uint32_t *correction_lp[2], *correctionloworder_lp[2], *correctionhighorder_lp[2]; @@ -379,7 +370,7 @@ static void iv_Decode_Chunk(Indeo3DecodeContext *s, } else if(cmd == 3) { if(strip->usl7 == 0) { strip->usl7 = 1; - ref_vectors = (signed char*)buf2 + (*buf1 * 2); + ref_vectors = (const signed char*)buf2 + (*buf1 * 2); buf1++; continue; } @@ -1066,7 +1057,6 @@ static int indeo3_decode_init(AVCodecContext *avctx) s->width = avctx->width; s->height = avctx->height; avctx->pix_fmt = PIX_FMT_YUV410P; - avctx->has_b_frames = 0; build_modpred(s); iv_alloc_frames(s); @@ -1076,7 +1066,7 @@ static int indeo3_decode_init(AVCodecContext *avctx) static int indeo3_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - unsigned char *buf, int buf_size) + const unsigned char *buf, int buf_size) { Indeo3DecodeContext *s=avctx->priv_data; unsigned char *src, *dest; diff --git a/contrib/ffmpeg/libavcodec/indeo3data.h b/contrib/ffmpeg/libavcodec/indeo3data.h index e69a09f0e..eb9a8c19e 100644 --- a/contrib/ffmpeg/libavcodec/indeo3data.h +++ b/contrib/ffmpeg/libavcodec/indeo3data.h @@ -19,6 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_INDEO3DATA_H +#define FFMPEG_INDEO3DATA_H + +#include <stdint.h> + static const uint32_t correction[] = { 0x00000000, 0x00000202, 0xfffffdfe, 0x000002ff, 0xfffffd01, 0xffffff03, 0x000000fd, 0x00000404, 0xfffffbfc, 0x00000501, 0xfffffaff, 0x00000105, 0xfffffefb, 0x000003fc, 0xfffffc04, 0x000005fe, @@ -2333,3 +2338,5 @@ static const uint32_t correctionhighorder[] = { 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + +#endif /* FFMPEG_INDEO3DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/interplayvideo.c b/contrib/ffmpeg/libavcodec/interplayvideo.c index 95059c365..3731fb275 100644 --- a/contrib/ffmpeg/libavcodec/interplayvideo.c +++ b/contrib/ffmpeg/libavcodec/interplayvideo.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -40,8 +39,8 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" +#include "bytestream.h" #include "dsputil.h" #define PALETTE_COUNT 256 @@ -61,14 +60,14 @@ typedef struct IpvideoContext { AVFrame second_last_frame; AVFrame last_frame; AVFrame current_frame; - unsigned char *decoding_map; + const unsigned char *decoding_map; int decoding_map_size; - unsigned char *buf; + const unsigned char *buf; int size; - unsigned char *stream_ptr; - unsigned char *stream_end; + const unsigned char *stream_ptr; + const unsigned char *stream_end; unsigned char *pixel_ptr; int line_inc; int stride; @@ -298,10 +297,8 @@ static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s) /* need 2 more bytes from the stream */ CHECK_STREAM_PTR(2); - B[0] = *s->stream_ptr++; - B[1] = *s->stream_ptr++; - flags = (B[1] << 8) | B[0]; + flags = bytestream_get_le16(&s->stream_ptr); bitmask = 0x0001; for (y = 0; y < 8; y += 2) { for (x = 0; x < 8; x += 2, bitmask <<= 1) { @@ -479,7 +476,6 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s) { int x, y; unsigned char P[4]; - unsigned char B[4]; unsigned int flags = 0; int shifter = 0; unsigned char pix; @@ -497,8 +493,7 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s) for (y = 0; y < 8; y++) { /* get the next set of 8 2-bit flags */ - flags = (s->stream_ptr[1] << 8) | s->stream_ptr[0]; - s->stream_ptr += 2; + flags = bytestream_get_le16(&s->stream_ptr); for (x = 0, shifter = 0; x < 8; x++, shifter += 2) { *s->pixel_ptr++ = P[(flags >> shifter) & 0x03]; } @@ -510,11 +505,7 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s) /* 1 of 4 colors for each 2x2 block, need 4 more bytes */ CHECK_STREAM_PTR(4); - B[0] = *s->stream_ptr++; - B[1] = *s->stream_ptr++; - B[2] = *s->stream_ptr++; - B[3] = *s->stream_ptr++; - flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + flags = bytestream_get_le32(&s->stream_ptr); shifter = 0; for (y = 0; y < 8; y += 2) { @@ -536,11 +527,7 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s) for (y = 0; y < 8; y++) { /* time to reload flags? */ if ((y == 0) || (y == 4)) { - B[0] = *s->stream_ptr++; - B[1] = *s->stream_ptr++; - B[2] = *s->stream_ptr++; - B[3] = *s->stream_ptr++; - flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + flags = bytestream_get_le32(&s->stream_ptr); shifter = 0; } for (x = 0; x < 8; x += 2, shifter += 2) { @@ -559,11 +546,7 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s) for (y = 0; y < 8; y += 2) { /* time to reload flags? */ if ((y == 0) || (y == 4)) { - B[0] = *s->stream_ptr++; - B[1] = *s->stream_ptr++; - B[2] = *s->stream_ptr++; - B[3] = *s->stream_ptr++; - flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + flags = bytestream_get_le32(&s->stream_ptr); shifter = 0; } for (x = 0; x < 8; x++, shifter += 2) { @@ -865,7 +848,6 @@ static int ipvideo_decode_init(AVCodecContext *avctx) } avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; dsputil_init(&s->dsp, avctx); /* decoding map contains 4 bits of information per 8x8 block */ @@ -897,7 +879,7 @@ static int ipvideo_decode_init(AVCodecContext *avctx) static int ipvideo_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { IpvideoContext *s = avctx->priv_data; AVPaletteControl *palette_control = avctx->palctrl; diff --git a/contrib/ffmpeg/libavcodec/intrax8.c b/contrib/ffmpeg/libavcodec/intrax8.c new file mode 100644 index 000000000..0436deb4c --- /dev/null +++ b/contrib/ffmpeg/libavcodec/intrax8.c @@ -0,0 +1,764 @@ +/* + * 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 intrax8.c + * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1 + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "mpegvideo.h" +#include "msmpeg4data.h" +#include "intrax8huf.h" +#include "intrax8.h" + +#define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits) + +#define DC_VLC_BITS 9 +#define AC_VLC_BITS 9 +#define OR_VLC_BITS 7 + +#define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS) +#define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS) +#define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS) + +static VLC j_ac_vlc[2][2][8]; //[quant<13],[intra/inter],[select] +static VLC j_dc_vlc[2][8]; //[quant], [select] +static VLC j_orient_vlc[2][4]; //[quant], [select] + +static void x8_vlc_init(){ + int i; + +#define init_ac_vlc(dst,src) \ + init_vlc(&dst, \ + AC_VLC_BITS,77, \ + &src[1],4,2, \ + &src[0],4,2, \ + 1) +//set ac tables + for(i=0;i<8;i++){ + init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] ); + init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] ); + init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] ); + init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] ); + } +#undef init_ac_vlc + +//set dc tables +#define init_dc_vlc(dst,src) \ + init_vlc(&dst, \ + DC_VLC_BITS,34, \ + &src[1],4,2, \ + &src[0],4,2, \ + 1); + for(i=0;i<8;i++){ + init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]); + init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]); + } +#undef init_dc_vlc + +//set orient tables +#define init_or_vlc(dst,src) \ + init_vlc(&dst, \ + OR_VLC_BITS,12, \ + &src[1],4,2, \ + &src[0],4,2, \ + 1); + for(i=0;i<2;i++){ + init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]); + } + for(i=0;i<4;i++){ + init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0]) + } +} +#undef init_or_vlc + +static void x8_reset_vlc_tables(IntraX8Context * w){ + memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc)); + memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc)); + w->j_orient_vlc=NULL; +} + +static inline void x8_select_ac_table(IntraX8Context * const w , int mode){ + MpegEncContext * const s= w->s; + int table_index; + + assert(mode<4); + + if( w->j_ac_vlc[mode] ) return; + + table_index = get_bits(&s->gb, 3); + w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables + assert(w->j_ac_vlc[mode]); +} + +static inline int x8_get_orient_vlc(IntraX8Context * w){ + MpegEncContext * const s= w->s; + int table_index; + + if(!w->j_orient_vlc ){ + table_index = get_bits(&s->gb, 1+(w->quant<13) ); + w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index]; + } + assert(w->j_orient_vlc); + assert(w->j_orient_vlc->table); + + return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD); +} + +#define extra_bits(eb) (eb) +#define extra_run (0xFF<<8) +#define extra_level (0x00<<8) +#define run_offset(r) ((r)<<16) +#define level_offset(l) ((l)<<24) +static const uint32_t ac_decode_table[]={ + /*46*/ extra_bits(3) | extra_run | run_offset(16) | level_offset( 0), + /*47*/ extra_bits(3) | extra_run | run_offset(24) | level_offset( 0), + /*48*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1), + /*49*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1), + + /*50*/ extra_bits(5) | extra_run | run_offset(32) | level_offset( 0), + /*51*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1), + + /*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4), + /*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8), + /*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12), + /*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16), + /*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24), + + /*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3), + /*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7), + + /*59*/ extra_bits(2) | extra_run | run_offset(16) | level_offset( 0), + /*60*/ extra_bits(2) | extra_run | run_offset(20) | level_offset( 0), + /*61*/ extra_bits(2) | extra_run | run_offset(24) | level_offset( 0), + /*62*/ extra_bits(2) | extra_run | run_offset(28) | level_offset( 0), + /*63*/ extra_bits(4) | extra_run | run_offset(32) | level_offset( 0), + /*64*/ extra_bits(4) | extra_run | run_offset(48) | level_offset( 0), + + /*65*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1), + /*66*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1), + /*67*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1), + + /*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4), + /*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8), + /*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16), + + /*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3), + /*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7), +}; +//extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits; +#undef extra_bits +#undef extra_run +#undef extra_level +#undef run_offset +#undef level_offset + +static void x8_get_ac_rlf(IntraX8Context * const w, const int mode, + int * const run, int * const level, int * const final){ + MpegEncContext * const s= w->s; + int i,e; + +// x8_select_ac_table(w,mode); + i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD); + + if(i<46){ //[0-45] + int t,l; + if(i<0){ + (*level)=(*final)=//prevent 'may be used unilitialized' + (*run)=64;//this would cause error exit in the ac loop + return; + } + + (*final) = t = (i>22); + i-=23*t; +/* + i== 0-15 r=0-15 l=0 ;r=i& %01111 + i==16-19 r=0-3 l=1 ;r=i& %00011 + i==20-21 r=0-1 l=2 ;r=i& %00001 + i==22 r=0 l=3 ;r=i& %00000 +l=lut_l[i/2]={0,0,0,0,0,0,0,0,1,1,2,3}[i>>1];// 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 +t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */ + l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/ + t=(0x01030F>>(l<<3)); + + (*run) = i&t; + (*level) = l; + }else if(i<73){//[46-72] + uint32_t sm; + uint32_t mask; + + i-=46; + sm=ac_decode_table[i]; + + e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits + mask=sm&0xff;sm>>=8; //1bit + + (*run) =(sm&0xff) + (e&( mask));//6bits + (*level)=(sm>>8) + (e&(~mask));//5bits + (*final)=i>(58-46); + }else if(i<75){//[73-74] + static const uint8_t crazy_mix_runlevel[32]={ + 0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63, + 0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83, + 0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64, + 0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84}; + + (*final)=!(i&1); + e=get_bits(&s->gb,5);//get the extra bits + (*run) =crazy_mix_runlevel[e]>>4; + (*level)=crazy_mix_runlevel[e]&0x0F; + }else{ + (*level)=get_bits( &s->gb, 7-3*(i&1)); + (*run) =get_bits( &s->gb, 6); + (*final)=get_bits1(&s->gb); + } + return; +} + +//static const uint8_t dc_extra_sbits[] ={0, 1,1, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 }; +static const uint8_t dc_index_offset[] ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193}; + +static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){ + MpegEncContext * const s= w->s; + int i,e,c; + + assert(mode<3); + if( !w->j_dc_vlc[mode] ) { + int table_index; + table_index = get_bits(&s->gb, 3); + //4 modes, same table + w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index]; + } + assert(w->j_dc_vlc); + assert(w->j_dc_vlc[mode]->table); + + i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD); + + /*(i>=17) {i-=17;final=1;}*/ + c= i>16; + (*final)=c; + i-=17*c; + + if(i<=0){ + (*level)=0; + return -i; + } + c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[] + c-=c>1; + + e=get_bits(&s->gb,c);//get the extra bits + i=dc_index_offset[i]+(e>>1); + + e= -(e & 1);//0,0xffffff + (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1) + return 0; +} +//end of huffman + +static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){ + MpegEncContext * const s= w->s; + int range; + int sum; + int quant; + + s->dsp.x8_setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer, + s->current_picture.linesize[chroma>0], + &range, &sum, w->edges); + if(chroma){ + w->orient=w->chroma_orient; + quant=w->quant_dc_chroma; + }else{ + quant=w->quant; + } + + w->flat_dc=0; + if(range < quant || range < 3){ + w->orient=0; + if(range < 3){//yep you read right, a +-1 idct error may break decoding! + w->flat_dc=1; + sum+=9; + w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899 + } + } + if(chroma) + return 0; + + assert(w->orient < 3); + if(range < 2*w->quant){ + if( (w->edges&3) == 0){ + if(w->orient==1) w->orient=11; + if(w->orient==2) w->orient=10; + }else{ + w->orient=0; + } + w->raw_orient=0; + }else{ + static const uint8_t prediction_table[3][12]={ + {0,8,4, 10,11, 2,6,9,1,3,5,7}, + {4,0,8, 11,10, 3,5,2,6,9,1,7}, + {8,0,4, 10,11, 1,7,2,6,9,3,5} + }; + w->raw_orient=x8_get_orient_vlc(w); + if(w->raw_orient<0) return -1; + assert(w->raw_orient < 12 ); + assert(w->orient<3); + w->orient=prediction_table[w->orient][w->raw_orient]; + } + return 0; +} + +static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){ + MpegEncContext * const s= w->s; + + w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8); +/* + y=2n+0 ->//0 2 4 + y=2n+1 ->//1 3 5 +*/ +} +static void x8_get_prediction_chroma(IntraX8Context * const w){ + MpegEncContext * const s= w->s; + + w->edges = 1*( !(s->mb_x>>1) ); + w->edges|= 2*( !(s->mb_y>>1) ); + w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd + + w->raw_orient=0; + if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC + w->chroma_orient=4<<((0xCC>>w->edges)&1); + return; + } + w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)] +} + +static void x8_get_prediction(IntraX8Context * const w){ + MpegEncContext * const s= w->s; + int a,b,c,i; + + w->edges = 1*( !s->mb_x ); + w->edges|= 2*( !s->mb_y ); + w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) ); + + switch(w->edges&3){ + case 0: + break; + case 1: + //take the one from the above block[0][y-1] + w->est_run = w->prediction_table[!(s->mb_y&1)]>>2; + w->orient = 1; + return; + case 2: + //take the one from the previous block[x-1][0] + w->est_run = w->prediction_table[2*s->mb_x-2]>>2; + w->orient = 2; + return; + case 3: + w->est_run = 16; + w->orient = 0; + return; + } + //no edge cases + b= w->prediction_table[2*s->mb_x + !(s->mb_y&1) ];//block[x ][y-1] + a= w->prediction_table[2*s->mb_x-2 + (s->mb_y&1) ];//block[x-1][y ] + c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1] + + w->est_run = FFMIN(b,a); + /* This condition has nothing to do with w->edges, even if it looks + similar it would trigger if e.g. x=3;y=2; + I guess somebody wrote something wrong and it became standard. */ + if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run); + w->est_run>>=2; + + a&=3; + b&=3; + c&=3; + + i=( 0xFFEAF4C4>>(2*b+8*a) )&3; + if(i!=3) w->orient=i; + else w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3; +/* +lut1[b][a]={ +->{0, 1, 0, pad}, + {0, 1, X, pad}, + {2, 2, 2, pad}} + pad 2 2 2; pad X 1 0; pad 0 1 0 <- +-> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4 + +lut2[q>12][c]={ + ->{0,2,1,pad}, + {2,2,2,pad}} + pad 2 2 2; pad 1 2 0 <- +-> 11 10'10 10 '11 01'10 00=>0xEAD8 +*/ +} + + +static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){ + MpegEncContext * const s= w->s; + int t; +#define B(x,y) s->block[0][s->dsp.idct_permutation[(x)+(y)*8]] +#define T(x) ((x) * dc_level + 0x8000) >> 16; + switch(direction){ + case 0: + t = T(3811);//h + B(1,0) -= t; + B(0,1) -= t; + + t = T(487);//e + B(2,0) -= t; + B(0,2) -= t; + + t = T(506);//f + B(3,0) -= t; + B(0,3) -= t; + + t = T(135);//c + B(4,0) -= t; + B(0,4) -= t; + B(2,1) += t; + B(1,2) += t; + B(3,1) += t; + B(1,3) += t; + + t = T(173);//d + B(5,0) -= t; + B(0,5) -= t; + + t = T(61);//b + B(6,0) -= t; + B(0,6) -= t; + B(5,1) += t; + B(1,5) += t; + + t = T(42); //a + B(7,0) -= t; + B(0,7) -= t; + B(4,1) += t; + B(1,4) += t; + B(4,4) += t; + + t = T(1084);//g + B(1,1) += t; + + s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8); + break; + case 1: + B(0,1) -= T(6269); + B(0,3) -= T( 708); + B(0,5) -= T( 172); + B(0,7) -= T( 73); + + s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8); + break; + case 2: + B(1,0) -= T(6269); + B(3,0) -= T( 708); + B(5,0) -= T( 172); + B(7,0) -= T( 73); + + s->block_last_index[0] = FFMAX(s->block_last_index[0], 7); + break; + } +#undef B +#undef T +} + +static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){ + int k; + for(k=0;k<8;k++){ + memset(dst,pix,8); + dst+=linesize; + } +} + +static const int16_t quant_table[64] = { + 256, 256, 256, 256, 256, 256, 259, 262, + 265, 269, 272, 275, 278, 282, 285, 288, + 292, 295, 299, 303, 306, 310, 314, 317, + 321, 325, 329, 333, 337, 341, 345, 349, + 353, 358, 362, 366, 371, 375, 379, 384, + 389, 393, 398, 403, 408, 413, 417, 422, + 428, 433, 438, 443, 448, 454, 459, 465, + 470, 476, 482, 488, 493, 499, 505, 511 +}; + +static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){ + MpegEncContext * const s= w->s; + + uint8_t * scantable; + int final,run,level; + int ac_mode,dc_mode,est_run,dc_level; + int pos,n; + int zeros_only; + int use_quant_matrix; + int sign; + + assert(w->orient<12); + memset(s->block[0],0x00,64*sizeof(DCTELEM)); + + if(chroma){ + dc_mode=2; + }else{ + dc_mode=!!w->est_run;//0,1 + } + + if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1; + n=0; + zeros_only=0; + if(!final){//decode ac + use_quant_matrix=w->use_quant_matrix; + if(chroma){ + ac_mode = 1; + est_run = 64;//not used + }else{ + if (w->raw_orient < 3){ + use_quant_matrix = 0; + } + if(w->raw_orient > 4){ + ac_mode = 0; + est_run = 64; + }else{ + if(w->est_run > 1){ + ac_mode = 2; + est_run=w->est_run; + }else{ + ac_mode = 3; + est_run = 64; + } + } + } + x8_select_ac_table(w,ac_mode); + /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<- + -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */ + scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated; + pos=0; + do { + n++; + if( n >= est_run ){ + ac_mode=3; + x8_select_ac_table(w,3); + } + + x8_get_ac_rlf(w,ac_mode,&run,&level,&final); + + pos+=run+1; + if(pos>63){ + //this also handles vlc error in x8_get_ac_rlf + return -1; + } + level= (level+1) * w->dquant; + level+= w->qsum; + + sign = - get_bits1(&s->gb); + level = (level ^ sign) - sign; + + if(use_quant_matrix){ + level = (level*quant_table[pos])>>8; + } + s->block[0][ scantable[pos] ]=level; + }while(!final); + + s->block_last_index[0]=pos; + }else{//DC only + s->block_last_index[0]=0; + if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1] + int32_t divide_quant= !chroma ? w->divide_quant_dc_luma: + w->divide_quant_dc_chroma; + int32_t dc_quant = !chroma ? w->quant: + w->quant_dc_chroma; + + //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding + dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13; + + dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3), + s->dest[chroma], s->current_picture.linesize[!!chroma]); + + goto block_placed; + } + zeros_only = (dc_level == 0); + } + if(!chroma){ + s->block[0][0] = dc_level*w->quant; + }else{ + s->block[0][0] = dc_level*w->quant_dc_chroma; + } + + //there is !zero_only check in the original, but dc_level check is enough + if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){ + int direction; + /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<- + -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */ + direction= (0x6A017C>>(w->orient*2))&3; + if (direction != 3){ + x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[] + } + } + + if(w->flat_dc){ + dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.linesize[!!chroma]); + }else{ + s->dsp.x8_spatial_compensation[w->orient]( s->edge_emu_buffer, + s->dest[chroma], + s->current_picture.linesize[!!chroma] ); + } + if(!zeros_only) + s->dsp.idct_add ( s->dest[chroma], + s->current_picture.linesize[!!chroma], + s->block[0] ); + +block_placed: + + if(!chroma){ + x8_update_predictions(w,w->orient,n); + } + + if(s->loop_filter){ + uint8_t* ptr = s->dest[chroma]; + int linesize = s->current_picture.linesize[!!chroma]; + + if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){ + s->dsp.x8_h_loop_filter(ptr, linesize, w->quant); + } + if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){ + s->dsp.x8_v_loop_filter(ptr, linesize, w->quant); + } + } + return 0; +} + +static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_* +//not s->linesize as this would be wrong for field pics +//not that IntraX8 has interlacing support ;) + const int linesize = s->current_picture.linesize[0]; + const int uvlinesize= s->current_picture.linesize[1]; + + s->dest[0] = s->current_picture.data[0]; + s->dest[1] = s->current_picture.data[1]; + s->dest[2] = s->current_picture.data[2]; + + s->dest[0] += s->mb_y * linesize << 3; + s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows + s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2; +} + +/** + * Initialize IntraX8 frame decoder. + * Requires valid MpegEncContext with valid s->mb_width before calling. + * @param w pointer to IntraX8Context + * @param s pointer to MpegEncContext of the parent codec + */ +void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){ + + w->s=s; + x8_vlc_init(); + assert(s->mb_width>0); + w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb + + ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], wmv1_scantable[0]); + ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], wmv1_scantable[2]); + ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], wmv1_scantable[3]); +} + +/** + * Destroy IntraX8 frame structure. + * @param w pointer to IntraX8Context + */ +void ff_intrax8_common_end(IntraX8Context * w) +{ + av_freep(&w->prediction_table); +} + +/** + * Decode single IntraX8 frame. + * The parent codec must fill s->loopfilter and s->gb (bitstream). + * The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function. + * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function. + * This function does not use MPV_decode_mb(). + * lowres decoding is theoretically impossible. + * @param w pointer to IntraX8Context + * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1. + * @param quant_offset offset away from zero + */ +//FIXME extern uint8_t wmv3_dc_scale_table[32]; +int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){ + MpegEncContext * const s= w->s; + int mb_xy; + assert(s); + w->use_quant_matrix = get_bits1(&s->gb); + + w->dquant = dquant; + w->quant = dquant >> 1; + w->qsum = quant_offset; + + w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant; + if(w->quant < 5){ + w->quant_dc_chroma = w->quant; + w->divide_quant_dc_chroma = w->divide_quant_dc_luma; + }else{ + w->quant_dc_chroma = w->quant+((w->quant+3)>>3); + w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma; + } + x8_reset_vlc_tables(w); + + s->resync_mb_x=0; + s->resync_mb_y=0; + + for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){ + x8_init_block_index(s); + mb_xy=(s->mb_y>>1)*s->mb_stride; + + for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){ + x8_get_prediction(w); + if(x8_setup_spatial_predictor(w,0)) goto error; + if(x8_decode_intra_mb(w,0)) goto error; + + if( s->mb_x & s->mb_y & 1 ){ + x8_get_prediction_chroma(w); + + /*when setting up chroma, no vlc is read, + so no error condition can be reached*/ + x8_setup_spatial_predictor(w,1); + if(x8_decode_intra_mb(w,1)) goto error; + + x8_setup_spatial_predictor(w,2); + if(x8_decode_intra_mb(w,2)) goto error; + + s->dest[1]+= 8; + s->dest[2]+= 8; + + /*emulate MB info in the relevant tables*/ + s->mbskip_table [mb_xy]=0; + s->mbintra_table[mb_xy]=1; + s->current_picture.qscale_table[mb_xy]=w->quant; + mb_xy++; + } + s->dest[0]+= 8; + } + if(s->mb_y&1){ + ff_draw_horiz_band(s, (s->mb_y-1)*8, 16); + } + } + +error: + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, + (s->mb_x>>1)-1, (s->mb_y>>1)-1, + (AC_END|DC_END|MV_END) ); + return 0; +} diff --git a/contrib/ffmpeg/libavcodec/intrax8.h b/contrib/ffmpeg/libavcodec/intrax8.h new file mode 100644 index 000000000..3f6de67da --- /dev/null +++ b/contrib/ffmpeg/libavcodec/intrax8.h @@ -0,0 +1,57 @@ +/* + * 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 + */ + +#ifndef FFMPEG_INTRAX8_H +#define FFMPEG_INTRAX8_H + +#include "bitstream.h" +#include "mpegvideo.h" + +typedef struct{ + VLC * j_ac_vlc[4];//they point to the static j_mb_vlc + VLC * j_orient_vlc; + VLC * j_dc_vlc[3]; + + int use_quant_matrix; +//set by ff_intrax8_common_init + uint8_t * prediction_table;//2*(mb_w*2) + ScanTable scantable[3]; +//set by the caller codec + MpegEncContext * s; + int quant; + int dquant; + int qsum; +//calculated per frame + int quant_dc_chroma; + int divide_quant_dc_luma; + int divide_quant_dc_chroma; +//changed per block + int edges; + int flat_dc; + int predicted_dc; + int raw_orient; + int chroma_orient; + int orient; + int est_run; +} IntraX8Context; + +void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s); +void ff_intrax8_common_end(IntraX8Context * w); +int ff_intrax8_decode_picture(IntraX8Context * w, int quant, int halfpq); + +#endif /* FFMPEG_INTRAX8_H */ diff --git a/contrib/ffmpeg/libavcodec/intrax8dsp.c b/contrib/ffmpeg/libavcodec/intrax8dsp.c new file mode 100644 index 000000000..f90c0fdf0 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/intrax8dsp.c @@ -0,0 +1,432 @@ +/* + * 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 intrax8dsp.c + *@brief IntraX8 frame subdecoder image manipulation routines + */ + +#include "dsputil.h" + +/* +area positions, #3 is 1 pixel only, other are 8 pixels + |66666666| + 3|44444444|55555555| +- -+--------+--------+ +1 2|XXXXXXXX| +1 2|XXXXXXXX| +1 2|XXXXXXXX| +1 2|XXXXXXXX| +1 2|XXXXXXXX| +1 2|XXXXXXXX| +1 2|XXXXXXXX| +1 2|XXXXXXXX| +^-start +*/ + +#define area1 (0) +#define area2 (8) +#define area3 (8+8) +#define area4 (8+8+1) +#define area5 (8+8+1+8) +#define area6 (8+8+1+16) + +/** + Collect statistics and prepare the edge pixels required by the other spatial compensation functions. + + * @param src pointer to the beginning of the processed block + * @param dst pointer to emu_edge, edge pixels are stored the way other compensation routines do. + * @param linesize byte offset between 2 vertical pixels in the source image + * @param range pointer to the variable where the edge pixel range is to be stored (max-min values) + * @param psum pointer to the variable where the edge pixel sum is to be stored + * @param edges Informs this routine that the block is on an image border, so it has to interpolate the missing edge pixels. + and some of the edge pixels should be interpolated, the flag has the following meaning: + 1 - mb_x==0 - first block in the row, interpolate area #1,#2,#3; + 2 - mb_y==0 - first row, interpolate area #3,#4,#5,#6; + note: 1|2 - mb_x==mb_y==0 - first block, use 0x80 value for all areas; + 4 - mb_x>= (mb_width-1) last block in the row, interpolate area #5; +*/ +static void x8_setup_spatial_compensation(uint8_t *src, uint8_t *dst, int linesize, + int * range, int * psum, int edges){ + uint8_t * ptr; + int sum; + int i; + int min_pix,max_pix; + uint8_t c; + + if((edges&3)==3){ + *psum=0x80*(8+1+8+2); + *range=0; + memset(dst,0x80,16+1+16+8); + //this triggers flat_dc for sure. + //flat_dc avoids all (other) prediction modes, but requires dc_level decoding. + return; + } + + min_pix=256; + max_pix=-1; + + sum=0; + + if(!(edges&1)){//(mb_x!=0)//there is previous block on this row + ptr=src-1;//left column, area 2 + for(i=7;i>=0;i--){ + c=*(ptr-1);//area1, same mb as area2, no need to check + dst[area1+i]=c; + c=*(ptr); + + sum+=c; + min_pix=FFMIN(min_pix,c); + max_pix=FFMAX(max_pix,c); + dst[area2+i]=c; + + ptr+=linesize; + } + } + + if(!(edges&2)){ //(mb_y!=0)//there is row above + ptr=src-linesize;//top line + for(i=0;i<8;i++){ + c=*(ptr+i); + sum+=c; + min_pix=FFMIN(min_pix, c); + max_pix=FFMAX(max_pix, c); + } + if(edges&4){//last block on the row? + memset(dst+area5,c,8);//set with last pixel fr + memcpy(dst+area4, ptr, 8); + }else{ + memcpy(dst+area4, ptr, 16);//both area4 and 5 + } + memcpy(dst+area6, ptr-linesize, 8);//area6 always present in the above block + } + //now calculate the stuff we need + if(edges&3){//mb_x==0 || mb_y==0){ + int avg=(sum+4)>>3; + if(edges&1){ //(mb_x==0) {//implies mb_y!=0 + memset(dst+area1,avg,8+8+1);//areas 1,2 and 3 are averaged + }else{//implies y==0 x!=0 + memset(dst+area3,avg, 1+16+8);//areas 3, 4,5,6 + } + sum+=avg*9; + }else{ + uint8_t c=*(src-1-linesize);//the edge pixel, in the top line and left column + dst[area3]=c; + sum+=c; + //edge pixel is not part of min/max + } + (*range) = max_pix - min_pix; + sum += *(dst+area5) + *(dst+area5+1); + *psum = sum; +} + + +static const uint16_t zero_prediction_weights[64*2] = { + 640, 640, 669, 480, 708, 354, 748, 257, 792, 198, 760, 143, 808, 101, 772, 72, + 480, 669, 537, 537, 598, 416, 661, 316, 719, 250, 707, 185, 768, 134, 745, 97, + 354, 708, 416, 598, 488, 488, 564, 388, 634, 317, 642, 241, 716, 179, 706, 132, + 257, 748, 316, 661, 388, 564, 469, 469, 543, 395, 571, 311, 655, 238, 660, 180, + 198, 792, 250, 719, 317, 634, 395, 543, 469, 469, 507, 380, 597, 299, 616, 231, + 161, 855, 206, 788, 266, 710, 340, 623, 411, 548, 455, 455, 548, 366, 576, 288, + 122, 972, 159, 914, 211, 842, 276, 758, 341, 682, 389, 584, 483, 483, 520, 390, + 110, 1172, 144, 1107, 193, 1028, 254, 932, 317, 846, 366, 731, 458, 611, 499, 499 +}; + +static void spatial_compensation_0(uint8_t *src , uint8_t *dst, int linesize){ + int i,j; + int x,y; + unsigned int p;//power divided by 2 + int a; + uint16_t left_sum[2][8]; + uint16_t top_sum[2][8]; + memset(left_sum,0,2*8*sizeof(uint16_t)); + memset( top_sum,0,2*8*sizeof(uint16_t)); + + for(i=0;i<8;i++){ + a=src[area2+7-i]<<4; + for(j=0;j<8;j++){ + p=abs(i-j); + left_sum[p&1][j]+= a>>(p>>1); + } + } + + for(i=0;i<8;i++){ + a=src[area4+i]<<4; + for(j=0;j<8;j++){ + p=abs(i-j); + top_sum[p&1][j]+= a>>(p>>1); + } + } + for(;i<10;i++){ + a=src[area4+i]<<4; + for(j=5;j<8;j++){ + p=abs(i-j); + top_sum[p&1][j]+= a>>(p>>1); + } + } + for(;i<12;i++){ + a=src[area4+i]<<4; + for(j=7;j<8;j++){ + p=abs(i-j); + top_sum[p&1][j]+= a>>(p>>1); + } + } + + for(i=0;i<8;i++){ + top_sum [0][i]+=(top_sum [1][i]*181 + 128 )>>8;//181 is sqrt(2)/2 + left_sum[0][i]+=(left_sum[1][i]*181 + 128 )>>8; + } + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x] = ( + (uint32_t)top_sum [0][x]*zero_prediction_weights[y*16+x*2+0] + + (uint32_t)left_sum[0][y]*zero_prediction_weights[y*16+x*2+1] + + 0x8000 + )>>16; + } + dst+=linesize; + } +} +static void spatial_compensation_1(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x]=src[area4 + FFMIN(2*y+x+2, 15) ]; + } + dst+=linesize; + } +} +static void spatial_compensation_2(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x]=src[area4 +1+y+x]; + } + dst+=linesize; + } +} +static void spatial_compensation_3(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x]=src[area4 +((y+1)>>1)+x]; + } + dst+=linesize; + } +} +static void spatial_compensation_4(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x]=( src[area4+x] + src[area6+x] + 1 )>>1; + } + dst+=linesize; + } +} +static void spatial_compensation_5(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + if(2*x-y<0){ + dst[x]=src[area2+9+2*x-y]; + }else{ + dst[x]=src[area4 +x-((y+1)>>1)]; + } + } + dst+=linesize; + } +} +static void spatial_compensation_6(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x]=src[area3+x-y]; + } + dst+=linesize; + } +} +static void spatial_compensation_7(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + if(x-2*y>0){ + dst[x]=( src[area3-1+x-2*y] + src[area3+x-2*y] + 1)>>1; + }else{ + dst[x]=src[area2+8-y +(x>>1)]; + } + } + dst+=linesize; + } +} +static void spatial_compensation_8(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x]=( src[area1+7-y] + src[area2+7-y] + 1 )>>1; + } + dst+=linesize; + } +} +static void spatial_compensation_9(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x]=src[area2+6-FFMIN(x+y,6)]; + } + dst+=linesize; + } +} +static void spatial_compensation_10(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x]=(src[area2+7-y]*(8-x)+src[area4+x]*x+4)>>3; + } + dst+=linesize; + } +} +static void spatial_compensation_11(uint8_t *src , uint8_t *dst, int linesize){ + int x,y; + + for(y=0;y<8;y++){ + for(x=0;x<8;x++){ + dst[x]=(src[area2+7-y]*y+src[area4+x]*(8-y)+4)>>3; + } + dst+=linesize; + } +} + +static void x8_loop_filter(uint8_t * ptr, const int a_stride, const int b_stride, int quant){ + int i,t; + int p0,p1,p2,p3,p4,p5,p6,p7,p8,p9; + int ql=(quant+10)>>3; + + for(i=0; i<8; i++,ptr+=b_stride){ + p0=ptr[-5*a_stride]; + p1=ptr[-4*a_stride]; + p2=ptr[-3*a_stride]; + p3=ptr[-2*a_stride]; + p4=ptr[-1*a_stride]; + p5=ptr[ 0 ]; + p6=ptr[ 1*a_stride]; + p7=ptr[ 2*a_stride]; + p8=ptr[ 3*a_stride]; + p9=ptr[ 4*a_stride]; + + t= + (FFABS(p1-p2) <= ql) + + (FFABS(p2-p3) <= ql) + + (FFABS(p3-p4) <= ql) + + (FFABS(p4-p5) <= ql); + if(t>0){//You need at least 1 to be able to reach a total score of 6. + t+= + (FFABS(p5-p6) <= ql) + + (FFABS(p6-p7) <= ql) + + (FFABS(p7-p8) <= ql) + + (FFABS(p8-p9) <= ql) + + (FFABS(p0-p1) <= ql); + if(t>=6){ + int min,max; + + min=max=p1; + min=FFMIN(min,p3); max=FFMAX(max,p3); + min=FFMIN(min,p5); max=FFMAX(max,p5); + min=FFMIN(min,p8); max=FFMAX(max,p8); + if(max-min<2*quant){//early stop + min=FFMIN(min,p2); max=FFMAX(max,p2); + min=FFMIN(min,p4); max=FFMAX(max,p4); + min=FFMIN(min,p6); max=FFMAX(max,p6); + min=FFMIN(min,p7); max=FFMAX(max,p7); + if(max-min<2*quant){ + ptr[-2*a_stride]=(4*p2 + 3*p3 + 1*p7 + 4)>>3; + ptr[-1*a_stride]=(3*p2 + 3*p4 + 2*p7 + 4)>>3; + ptr[ 0 ]=(2*p2 + 3*p5 + 3*p7 + 4)>>3; + ptr[ 1*a_stride]=(1*p2 + 3*p6 + 4*p7 + 4)>>3; + continue; + }; + } + } + } + { + int x,x0,x1,x2; + int m; + + x0 = (2*p3 - 5*p4 + 5*p5 - 2*p6 + 4)>>3; + if(FFABS(x0) < quant){ + x1=(2*p1 - 5*p2 + 5*p3 - 2*p4 + 4)>>3; + x2=(2*p5 - 5*p6 + 5*p7 - 2*p8 + 4)>>3; + + x=FFABS(x0) - FFMIN( FFABS(x1), FFABS(x2) ); + m=p4-p5; + + if( x > 0 && (m^x0) <0){ + int32_t sign; + + sign=m>>31; + m=(m^sign)-sign;//abs(m) + m>>=1; + + x=(5*x)>>3; + + if(x>m) x=m; + + x=(x^sign)-sign; + + ptr[-1*a_stride] -= x; + ptr[ 0] += x; + } + } + } + } +} + +static void x8_h_loop_filter(uint8_t *src, int stride, int qscale){ + x8_loop_filter(src, stride, 1, qscale); +} + +static void x8_v_loop_filter(uint8_t *src, int stride, int qscale){ + x8_loop_filter(src, 1, stride, qscale); +} + +void ff_intrax8dsp_init(DSPContext* dsp, AVCodecContext *avctx) { + dsp->x8_h_loop_filter=x8_h_loop_filter; + dsp->x8_v_loop_filter=x8_v_loop_filter; + dsp->x8_setup_spatial_compensation=x8_setup_spatial_compensation; + dsp->x8_spatial_compensation[0]=spatial_compensation_0; + dsp->x8_spatial_compensation[1]=spatial_compensation_1; + dsp->x8_spatial_compensation[2]=spatial_compensation_2; + dsp->x8_spatial_compensation[3]=spatial_compensation_3; + dsp->x8_spatial_compensation[4]=spatial_compensation_4; + dsp->x8_spatial_compensation[5]=spatial_compensation_5; + dsp->x8_spatial_compensation[6]=spatial_compensation_6; + dsp->x8_spatial_compensation[7]=spatial_compensation_7; + dsp->x8_spatial_compensation[8]=spatial_compensation_8; + dsp->x8_spatial_compensation[9]=spatial_compensation_9; + dsp->x8_spatial_compensation[10]=spatial_compensation_10; + dsp->x8_spatial_compensation[11]=spatial_compensation_11; +} diff --git a/contrib/ffmpeg/libavcodec/intrax8huf.h b/contrib/ffmpeg/libavcodec/intrax8huf.h new file mode 100644 index 000000000..f8c830d95 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/intrax8huf.h @@ -0,0 +1,918 @@ +/* + * 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 + */ + +#ifndef FFMPEG_INTRAX8HUF_H +#define FFMPEG_INTRAX8HUF_H + +#include <inttypes.h> + + +static const uint16_t x8_orient_lowquant_table[4][12][2]={ + {//0 + {0x0000, 1}, {0x0004, 3}, {0x0005, 3}, {0x000C, 4}, + {0x000D, 4}, {0x0038, 6}, {0x001D, 5}, {0x0039, 6}, + {0x003C, 6}, {0x003D, 6}, {0x003E, 6}, {0x003F, 6}, + },{//1 + {0x0000, 5}, {0x0001, 5}, {0x0002, 5}, {0x0001, 2}, + {0x0002, 2}, {0x0002, 4}, {0x0003, 5}, {0x0006, 3}, + {0x0003, 4}, {0x000E, 4}, {0x001E, 5}, {0x001F, 5}, + },{//2 + {0x0000, 2}, {0x0001, 2}, {0x0004, 3}, {0x0005, 3}, + {0x0006, 3}, {0x0038, 6}, {0x0039, 6}, {0x001D, 5}, + {0x003C, 6}, {0x003D, 6}, {0x003E, 6}, {0x003F, 6}, + },{//3 + {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0001, 2}, + {0x0002, 2}, {0x0018, 5}, {0x0019, 5}, {0x000D, 4}, + {0x001C, 5}, {0x001D, 5}, {0x001E, 5}, {0x001F, 5}, + } +}; + +static const uint16_t x8_orient_highquant_table[2][12][2]={ + {//0 + {0x0000, 2}, {0x0001, 2}, {0x0004, 3}, {0x0005, 3}, + {0x0006, 3}, {0x0038, 6}, {0x001D, 5}, {0x0039, 6}, + {0x003C, 6}, {0x003D, 6}, {0x003E, 6}, {0x003F, 6}, + },{//1 + {0x0000, 1}, {0x0002, 2}, {0x0006, 3}, {0x001C, 5}, + {0x001D, 5}, {0x0078, 7}, {0x003D, 6}, {0x0079, 7}, + {0x007C, 7}, {0x007D, 7}, {0x007E, 7}, {0x007F, 7}, + } +}; +#define MAX_OR_VLC_BITS 7 + + +static const uint16_t x8_dc_lowquant_table[8][34][2]={ + {//0 + {0x0000, 5}, {0x0001, 4}, {0x0001, 5}, {0x0004, 5}, + {0x0005, 5}, {0x0006, 5}, {0x000E, 6}, {0x000F, 6}, + {0x0040, 8}, {0x0041, 8}, {0x0840, 13}, {0x0841, 13}, + {0x0842, 13}, {0x0843, 13}, {0x0844, 13}, {0x0845, 13}, + {0x0846, 13}, {0x0002, 2}, {0x0003, 2}, {0x0003, 3}, + {0x0005, 4}, {0x0009, 5}, {0x0011, 6}, {0x0043, 8}, + {0x0085, 9}, {0x0847, 13}, {0x0848, 13}, {0x0849, 13}, + {0x084A, 13}, {0x084B, 13}, {0x084C, 13}, {0x084D, 13}, + {0x084E, 13}, {0x084F, 13}, + },{//1 + {0x0000, 4}, {0x0001, 3}, {0x0002, 3}, {0x0001, 4}, + {0x0006, 4}, {0x0004, 3}, {0x0007, 4}, {0x0005, 3}, + {0x000C, 4}, {0x000D, 4}, {0x001C, 5}, {0x003A, 6}, + {0x01D8, 9}, {0x01D9, 9}, {0x1DA0, 13}, {0x1DA1, 13}, + {0x1DA2, 13}, {0x003C, 6}, {0x003D, 6}, {0x003E, 6}, + {0x0077, 7}, {0x01DB, 9}, {0x007E, 7}, {0x00FE, 8}, + {0x01FE, 9}, {0x1DA3, 13}, {0x1DA4, 13}, {0x1DA5, 13}, + {0x0ED3, 12}, {0x0ED4, 12}, {0x01FF, 9}, {0x0ED5, 12}, + {0x0ED6, 12}, {0x0ED7, 12}, + },{//2 + {0x0000, 4}, {0x0001, 3}, {0x0002, 3}, {0x0001, 4}, + {0x0006, 4}, {0x0007, 4}, {0x0008, 4}, {0x0009, 4}, + {0x0028, 6}, {0x0029, 6}, {0x0054, 7}, {0x0055, 7}, + {0x0AC0, 12}, {0x0AC1, 12}, {0x0AC2, 12}, {0x0AC3, 12}, + {0x0AC4, 12}, {0x000B, 4}, {0x0006, 3}, {0x000E, 4}, + {0x001E, 5}, {0x003E, 6}, {0x003F, 6}, {0x0057, 7}, + {0x00AD, 8}, {0x0AC5, 12}, {0x0AC6, 12}, {0x0AC7, 12}, + {0x0AC8, 12}, {0x0AC9, 12}, {0x0ACA, 12}, {0x0ACB, 12}, + {0x0566, 11}, {0x0567, 11}, + },{//3 + {0x0000, 4}, {0x0001, 2}, {0x0001, 3}, {0x0004, 3}, + {0x0005, 3}, {0x0006, 3}, {0x0001, 4}, {0x000E, 4}, + {0x003C, 6}, {0x003D, 6}, {0x007C, 7}, {0x00FA, 8}, + {0x3EC0, 14}, {0x3EC1, 14}, {0x3EC2, 14}, {0x3EC3, 14}, + {0x1F62, 13}, {0x01F7, 9}, {0x007E, 7}, {0x00FE, 8}, + {0x00FF, 8}, {0x1F63, 13}, {0x1F64, 13}, {0x1F65, 13}, + {0x1F66, 13}, {0x1F67, 13}, {0x1F68, 13}, {0x1F69, 13}, + {0x1F6A, 13}, {0x1F6B, 13}, {0x1F6C, 13}, {0x1F6D, 13}, + {0x1F6E, 13}, {0x1F6F, 13}, + },{//4 + {0x0000, 7}, {0x0001, 7}, {0x0002, 7}, {0x0003, 7}, + {0x0004, 7}, {0x0005, 7}, {0x0006, 7}, {0x0007, 7}, + {0x0008, 7}, {0x0009, 7}, {0x000A, 7}, {0x000B, 7}, + {0x000C, 7}, {0x000D, 7}, {0x000E, 7}, {0x000F, 7}, + {0x0010, 7}, {0x0001, 1}, {0x0001, 2}, {0x0011, 7}, + {0x0012, 7}, {0x0013, 7}, {0x0014, 7}, {0x0015, 7}, + {0x0016, 7}, {0x0017, 7}, {0x0018, 7}, {0x0019, 7}, + {0x001A, 7}, {0x001B, 7}, {0x001C, 7}, {0x001D, 7}, + {0x001E, 7}, {0x001F, 7}, + },{//5 + {0x0000, 5}, {0x0001, 4}, {0x0001, 5}, {0x0008, 6}, + {0x0009, 6}, {0x000A, 6}, {0x0016, 7}, {0x000C, 6}, + {0x0017, 7}, {0x000D, 6}, {0x0038, 8}, {0x001D, 7}, + {0x0039, 8}, {0x0780, 13}, {0x0781, 13}, {0x0782, 13}, + {0x0783, 13}, {0x0002, 3}, {0x0001, 1}, {0x0003, 3}, + {0x001F, 7}, {0x003D, 8}, {0x0079, 9}, {0x0784, 13}, + {0x0785, 13}, {0x0786, 13}, {0x0787, 13}, {0x0788, 13}, + {0x0789, 13}, {0x078A, 13}, {0x078B, 13}, {0x078C, 13}, + {0x078D, 13}, {0x03C7, 12}, + },{//6 + {0x0000, 4}, {0x0001, 2}, {0x0001, 3}, {0x0004, 3}, + {0x0001, 4}, {0x000A, 4}, {0x0016, 5}, {0x002E, 6}, + {0x005E, 7}, {0x005F, 7}, {0x00C0, 8}, {0x3040, 14}, + {0x3041, 14}, {0x0305, 10}, {0x0183, 9}, {0x3042, 14}, + {0x3043, 14}, {0x000D, 4}, {0x0007, 3}, {0x0019, 5}, + {0x0031, 6}, {0x00C2, 8}, {0x00C3, 8}, {0x3044, 14}, + {0x3045, 14}, {0x3046, 14}, {0x3047, 14}, {0x3048, 14}, + {0x3049, 14}, {0x304A, 14}, {0x304B, 14}, {0x304C, 14}, + {0x304D, 14}, {0x1827, 13}, + },{//7 + {0x0000, 6}, {0x0001, 6}, {0x0002, 6}, {0x0006, 7}, + {0x0007, 7}, {0x0004, 6}, {0x0005, 6}, {0x0006, 6}, + {0x000E, 7}, {0x001E, 8}, {0x001F, 8}, {0x0040, 9}, + {0x0082, 10}, {0x0830, 14}, {0x0831, 14}, {0x0832, 14}, + {0x0833, 14}, {0x0001, 1}, {0x0001, 2}, {0x0003, 4}, + {0x0005, 5}, {0x0009, 6}, {0x0011, 7}, {0x0021, 8}, + {0x0834, 14}, {0x0835, 14}, {0x0836, 14}, {0x0837, 14}, + {0x0838, 14}, {0x0839, 14}, {0x083A, 14}, {0x083B, 14}, + {0x041E, 13}, {0x041F, 13}, + } +}; + +static const uint16_t x8_dc_highquant_table[8][34][2]={ + {//0 + {0x0000, 5}, {0x0001, 4}, {0x0002, 4}, {0x0001, 5}, + {0x0006, 5}, {0x0004, 4}, {0x0007, 5}, {0x000A, 5}, + {0x002C, 7}, {0x002D, 7}, {0x05C0, 12}, {0x05C1, 12}, + {0x05C2, 12}, {0x05C3, 12}, {0x05C4, 12}, {0x05C5, 12}, + {0x05C6, 12}, {0x0003, 3}, {0x0002, 2}, {0x0006, 3}, + {0x000E, 4}, {0x001E, 5}, {0x001F, 5}, {0x002F, 7}, + {0x005D, 8}, {0x05C7, 12}, {0x05C8, 12}, {0x05C9, 12}, + {0x05CA, 12}, {0x05CB, 12}, {0x05CC, 12}, {0x05CD, 12}, + {0x05CE, 12}, {0x05CF, 12}, + },{//1 + {0x0000, 3}, {0x0001, 3}, {0x0002, 3}, {0x0006, 4}, + {0x0007, 4}, {0x0004, 3}, {0x000A, 4}, {0x000B, 4}, + {0x0030, 6}, {0x0062, 7}, {0x0063, 7}, {0x0640, 11}, + {0x0641, 11}, {0x0642, 11}, {0x0643, 11}, {0x0644, 11}, + {0x0645, 11}, {0x0033, 6}, {0x000D, 4}, {0x001C, 5}, + {0x001D, 5}, {0x003C, 6}, {0x001F, 5}, {0x0065, 7}, + {0x007A, 7}, {0x0646, 11}, {0x007B, 7}, {0x0647, 11}, + {0x0648, 11}, {0x0649, 11}, {0x064A, 11}, {0x064B, 11}, + {0x0326, 10}, {0x0327, 10}, + },{//2 + {0x0000, 7}, {0x0001, 7}, {0x0001, 6}, {0x0004, 7}, + {0x0003, 6}, {0x0005, 7}, {0x0010, 8}, {0x0011, 8}, + {0x0240, 13}, {0x0241, 13}, {0x0242, 13}, {0x0243, 13}, + {0x0244, 13}, {0x0245, 13}, {0x0246, 13}, {0x0247, 13}, + {0x0124, 12}, {0x0001, 1}, {0x0001, 2}, {0x0001, 3}, + {0x0003, 5}, {0x0005, 6}, {0x0013, 8}, {0x0125, 12}, + {0x0126, 12}, {0x0127, 12}, {0x0128, 12}, {0x0129, 12}, + {0x012A, 12}, {0x012B, 12}, {0x012C, 12}, {0x012D, 12}, + {0x012E, 12}, {0x012F, 12}, + },{//3 + {0x0000, 4}, {0x0001, 3}, {0x0002, 3}, {0x0001, 4}, + {0x0006, 4}, {0x0004, 3}, {0x0005, 3}, {0x0006, 3}, + {0x000E, 5}, {0x000F, 5}, {0x0070, 7}, {0x0710, 11}, + {0x0711, 11}, {0x0712, 11}, {0x0713, 11}, {0x0714, 11}, + {0x0715, 11}, {0x001D, 5}, {0x0072, 7}, {0x003C, 6}, + {0x003D, 6}, {0x0073, 7}, {0x007C, 7}, {0x007D, 7}, + {0x007E, 7}, {0x0716, 11}, {0x0717, 11}, {0x0718, 11}, + {0x007F, 7}, {0x0719, 11}, {0x071A, 11}, {0x071B, 11}, + {0x038E, 10}, {0x038F, 10}, + },{//4 + {0x0000, 8}, {0x0001, 7}, {0x0002, 7}, {0x0003, 7}, + {0x0002, 9}, {0x0008, 8}, {0x0003, 9}, {0x0240, 14}, + {0x0241, 14}, {0x0242, 14}, {0x0243, 14}, {0x0244, 14}, + {0x0245, 14}, {0x0246, 14}, {0x0247, 14}, {0x0124, 13}, + {0x0125, 13}, {0x0001, 2}, {0x0001, 1}, {0x0001, 3}, + {0x0001, 4}, {0x0003, 6}, {0x0005, 7}, {0x0013, 9}, + {0x0126, 13}, {0x0127, 13}, {0x0128, 13}, {0x0129, 13}, + {0x012A, 13}, {0x012B, 13}, {0x012C, 13}, {0x012D, 13}, + {0x012E, 13}, {0x012F, 13}, + },{//5 + {0x0000, 7}, {0x0001, 7}, {0x0001, 6}, {0x0002, 6}, + {0x0003, 6}, {0x0004, 6}, {0x0005, 6}, {0x0006, 6}, + {0x0007, 6}, {0x0008, 6}, {0x0009, 6}, {0x000A, 6}, + {0x000B, 6}, {0x000C, 6}, {0x000D, 6}, {0x000E, 6}, + {0x000F, 6}, {0x0010, 6}, {0x0011, 6}, {0x0012, 6}, + {0x0013, 6}, {0x0014, 6}, {0x0015, 6}, {0x0016, 6}, + {0x0017, 6}, {0x0018, 6}, {0x0019, 6}, {0x0001, 1}, + {0x001A, 6}, {0x001B, 6}, {0x001C, 6}, {0x001D, 6}, + {0x001E, 6}, {0x001F, 6}, + },{//6 + {0x0000, 5}, {0x0001, 4}, {0x0001, 5}, {0x0004, 5}, + {0x000A, 6}, {0x0006, 5}, {0x000B, 6}, {0x000E, 6}, + {0x003C, 8}, {0x003D, 8}, {0x07C0, 13}, {0x07C1, 13}, + {0x07C2, 13}, {0x07C3, 13}, {0x07C4, 13}, {0x07C5, 13}, + {0x07C6, 13}, {0x0001, 2}, {0x0002, 2}, {0x0006, 3}, + {0x000E, 4}, {0x001E, 5}, {0x001F, 5}, {0x003F, 8}, + {0x007D, 9}, {0x07C7, 13}, {0x07C8, 13}, {0x07C9, 13}, + {0x07CA, 13}, {0x07CB, 13}, {0x07CC, 13}, {0x07CD, 13}, + {0x07CE, 13}, {0x07CF, 13}, + },{//7 + {0x0000, 7}, {0x0001, 7}, {0x0002, 7}, {0x0003, 7}, + {0x0004, 7}, {0x0005, 7}, {0x0006, 7}, {0x0007, 7}, + {0x0008, 7}, {0x0009, 7}, {0x000A, 7}, {0x000B, 7}, + {0x000C, 7}, {0x000D, 7}, {0x000E, 7}, {0x000F, 7}, + {0x0010, 7}, {0x0001, 1}, {0x0001, 2}, {0x0011, 7}, + {0x0012, 7}, {0x0013, 7}, {0x0014, 7}, {0x0015, 7}, + {0x0016, 7}, {0x0017, 7}, {0x0018, 7}, {0x0019, 7}, + {0x001A, 7}, {0x001B, 7}, {0x001C, 7}, {0x001D, 7}, + {0x001E, 7}, {0x001F, 7}, + } +}; +#define MAX_DC_VLC_BITS 14 + + +static const uint16_t x8_ac0_lowquant_table[8][77][2]={ + {//0 + {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5}, + {0x001E, 6}, {0x003E, 7}, {0x003F, 7}, {0x0040, 7}, + {0x0104, 9}, {0x0083, 8}, {0x0084, 8}, {0x0085, 8}, + {0x020A, 10}, {0x020B, 10}, {0x0218, 10}, {0x0219, 10}, + {0x0009, 4}, {0x0044, 7}, {0x010D, 9}, {0x021C, 10}, + {0x0023, 6}, {0x0045, 7}, {0x0050, 7}, {0x000B, 4}, + {0x000C, 4}, {0x0015, 5}, {0x001A, 5}, {0x001B, 5}, + {0x0029, 6}, {0x0038, 6}, {0x0039, 6}, {0x003A, 6}, + {0x0051, 7}, {0x0076, 7}, {0x0077, 7}, {0x0078, 7}, + {0x0079, 7}, {0x007A, 7}, {0x007B, 7}, {0x00F8, 8}, + {0x010F, 9}, {0x021D, 10}, {0x3E40, 14}, {0x3E41, 14}, + {0x3E42, 14}, {0x3E43, 14}, {0x03E5, 10}, {0x3E44, 14}, + {0x01F3, 9}, {0x3E45, 14}, {0x3E46, 14}, {0x3E47, 14}, + {0x00FA, 8}, {0x3E48, 14}, {0x3E49, 14}, {0x3E4A, 14}, + {0x3E4B, 14}, {0x03EC, 10}, {0x3E4C, 14}, {0x007E, 7}, + {0x00FE, 8}, {0x00FF, 8}, {0x01F7, 9}, {0x3E4D, 14}, + {0x3E4E, 14}, {0x3E4F, 14}, {0x3ED0, 14}, {0x3ED1, 14}, + {0x3ED2, 14}, {0x3ED3, 14}, {0x3ED4, 14}, {0x3ED5, 14}, + {0x1F6B, 13}, {0x1F6C, 13}, {0x1F6D, 13}, {0x1F6E, 13}, + {0x1F6F, 13}, + },{//1 + {0x0000, 3}, {0x0004, 5}, {0x0014, 7}, {0x000B, 6}, + {0x000C, 6}, {0x002A, 8}, {0x002B, 8}, {0x0034, 8}, + {0x0D40, 14}, {0x0D41, 14}, {0x001B, 7}, {0x0D42, 14}, + {0x0D43, 14}, {0x0D44, 14}, {0x0D45, 14}, {0x0D46, 14}, + {0x000E, 6}, {0x003C, 8}, {0x0D47, 14}, {0x003D, 8}, + {0x0D48, 14}, {0x0D49, 14}, {0x0D4A, 14}, {0x0001, 2}, + {0x0004, 3}, {0x0014, 5}, {0x000B, 4}, {0x000C, 4}, + {0x000D, 4}, {0x002A, 6}, {0x001F, 7}, {0x0056, 7}, + {0x0057, 7}, {0x0070, 7}, {0x00E2, 8}, {0x0072, 7}, + {0x003A, 6}, {0x003B, 6}, {0x003C, 6}, {0x003D, 6}, + {0x00E3, 8}, {0x0D4B, 14}, {0x00E6, 8}, {0x00E7, 8}, + {0x00F8, 8}, {0x0D4C, 14}, {0x0D4D, 14}, {0x0D4E, 14}, + {0x00F9, 8}, {0x0D4F, 14}, {0x0D50, 14}, {0x0D51, 14}, + {0x06A9, 13}, {0x06AA, 13}, {0x06AB, 13}, {0x06AC, 13}, + {0x06AD, 13}, {0x06AE, 13}, {0x06AF, 13}, {0x003F, 6}, + {0x06B0, 13}, {0x06B1, 13}, {0x06B2, 13}, {0x06B3, 13}, + {0x06B4, 13}, {0x007D, 7}, {0x06B5, 13}, {0x06B6, 13}, + {0x06B7, 13}, {0x06B8, 13}, {0x06B9, 13}, {0x06BA, 13}, + {0x06BB, 13}, {0x06BC, 13}, {0x06BD, 13}, {0x06BE, 13}, + {0x06BF, 13}, + },{//2 + {0x0000, 2}, {0x0002, 3}, {0x0003, 3}, {0x0008, 4}, + {0x0012, 5}, {0x0013, 5}, {0x0028, 6}, {0x0029, 6}, + {0x0054, 7}, {0x0055, 7}, {0x0056, 7}, {0x00AE, 8}, + {0x00AF, 8}, {0x00B0, 8}, {0x0162, 9}, {0x02C6, 10}, + {0x000C, 4}, {0x002D, 6}, {0x00B2, 8}, {0x0166, 9}, + {0x002E, 6}, {0x0167, 9}, {0x00BC, 8}, {0x001A, 5}, + {0x0036, 6}, {0x0037, 6}, {0x0038, 6}, {0x005F, 7}, + {0x0072, 7}, {0x0073, 7}, {0x0074, 7}, {0x0075, 7}, + {0x0076, 7}, {0x0077, 7}, {0x0078, 7}, {0x0079, 7}, + {0x007A, 7}, {0x007B, 7}, {0x00BD, 8}, {0xB1C0, 16}, + {0xB1C1, 16}, {0x58E1, 15}, {0x0B1D, 12}, {0x58E2, 15}, + {0x58E3, 15}, {0x58E4, 15}, {0x00F8, 8}, {0x03E4, 10}, + {0x01F3, 9}, {0x0B1E, 12}, {0x58E5, 15}, {0x58E6, 15}, + {0x00FA, 8}, {0x58E7, 15}, {0x58F8, 15}, {0x58F9, 15}, + {0x58FA, 15}, {0x01F6, 9}, {0x58FB, 15}, {0x007E, 7}, + {0x00FE, 8}, {0x00FF, 8}, {0x07CA, 11}, {0x0F96, 12}, + {0x58FC, 15}, {0x58FD, 15}, {0x58FE, 15}, {0x58FF, 15}, + {0x7CB8, 15}, {0x7CB9, 15}, {0x7CBA, 15}, {0x7CBB, 15}, + {0x7CBC, 15}, {0x01F7, 9}, {0x7CBD, 15}, {0x7CBE, 15}, + {0x7CBF, 15}, + },{//3 + {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5}, + {0x000F, 5}, {0x0020, 6}, {0x0021, 6}, {0x0044, 7}, + {0x0045, 7}, {0x008C, 8}, {0x008D, 8}, {0x011C, 9}, + {0x011D, 9}, {0x011E, 9}, {0x023E, 10}, {0x023F, 10}, + {0x0005, 3}, {0x0012, 5}, {0x004C, 7}, {0x004D, 7}, + {0x000C, 4}, {0x004E, 7}, {0x001A, 5}, {0x0036, 6}, + {0x004F, 7}, {0x006E, 7}, {0x006F, 7}, {0x00E0, 8}, + {0x00E1, 8}, {0x00E2, 8}, {0x00E3, 8}, {0x00E4, 8}, + {0x00E5, 8}, {0x01CC, 9}, {0x00E7, 8}, {0x00E8, 8}, + {0x00E9, 8}, {0x01CD, 9}, {0x0750, 11}, {0x03A9, 10}, + {0x0751, 11}, {0x7540, 15}, {0x03AB, 10}, {0x7541, 15}, + {0x7542, 15}, {0x7543, 15}, {0x01D6, 9}, {0x0755, 11}, + {0x0076, 7}, {0x0EA9, 12}, {0x7544, 15}, {0x7545, 15}, + {0x001E, 5}, {0x0077, 7}, {0x00F8, 8}, {0x03AE, 10}, + {0x075E, 11}, {0x007D, 7}, {0x03E4, 10}, {0x00FC, 8}, + {0x00FD, 8}, {0x03E5, 10}, {0x03E6, 10}, {0x0EBE, 12}, + {0x7546, 15}, {0x07CE, 11}, {0x7547, 15}, {0x75F8, 15}, + {0x75F9, 15}, {0x75FA, 15}, {0x75FB, 15}, {0x75FC, 15}, + {0x75FD, 15}, {0x007F, 7}, {0x3AFF, 14}, {0x0F9E, 12}, + {0x0F9F, 12}, + },{//4 + {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, + {0x0012, 6}, {0x0013, 6}, {0x0014, 6}, {0x002A, 7}, + {0x0016, 6}, {0x002B, 7}, {0x005C, 8}, {0x005D, 8}, + {0x005E, 8}, {0x00BE, 9}, {0x00BF, 9}, {0x0060, 8}, + {0x0007, 4}, {0x000D, 5}, {0x0019, 6}, {0x0020, 6}, + {0x0009, 4}, {0x0021, 6}, {0x0011, 5}, {0x0014, 5}, + {0x002A, 6}, {0x002B, 6}, {0x002C, 6}, {0x002D, 6}, + {0x002E, 6}, {0x002F, 6}, {0x0030, 6}, {0x0031, 7}, + {0x0062, 7}, {0x0063, 7}, {0x0064, 7}, {0x0065, 7}, + {0x0066, 7}, {0x0061, 8}, {0x0670, 11}, {0x0068, 7}, + {0x0069, 7}, {0x00CF, 8}, {0x019D, 9}, {0x01A8, 9}, + {0x01A9, 9}, {0x0339, 10}, {0x01AA, 9}, {0x0356, 10}, + {0x0036, 6}, {0x00D6, 8}, {0x6710, 15}, {0x6711, 15}, + {0x000E, 4}, {0x006E, 7}, {0x01AE, 9}, {0x6712, 15}, + {0x6713, 15}, {0x003C, 6}, {0x0357, 10}, {0x006F, 7}, + {0x00F4, 8}, {0x00F5, 8}, {0x035E, 10}, {0x01EC, 9}, + {0x6714, 15}, {0x01ED, 9}, {0x035F, 10}, {0x03DC, 10}, + {0x03DD, 10}, {0x6715, 15}, {0x338B, 14}, {0x338C, 14}, + {0x338D, 14}, {0x001F, 5}, {0x01EF, 9}, {0x338E, 14}, + {0x338F, 14}, + },{//5 + {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5}, + {0x0018, 6}, {0x0019, 6}, {0x0034, 7}, {0x006A, 8}, + {0x006B, 8}, {0x006C, 8}, {0x00DA, 9}, {0x036C, 11}, + {0x006E, 8}, {0x01B7, 10}, {0x036D, 11}, {0x3780, 15}, + {0x0004, 3}, {0x000E, 5}, {0x001E, 6}, {0x003E, 7}, + {0x000A, 4}, {0x002C, 6}, {0x0017, 5}, {0x002D, 6}, + {0x003F, 7}, {0x00C0, 8}, {0x0061, 7}, {0x00C1, 8}, + {0x0062, 7}, {0x00C6, 8}, {0x0064, 7}, {0x00C7, 8}, + {0x00CA, 8}, {0x00DF, 9}, {0x0196, 9}, {0x0197, 9}, + {0x0198, 9}, {0x0199, 9}, {0x0379, 11}, {0x019A, 9}, + {0x01BD, 10}, {0x066C, 11}, {0x3781, 15}, {0x0337, 10}, + {0x066D, 11}, {0x0670, 11}, {0x0339, 10}, {0x0671, 11}, + {0x0034, 6}, {0x00CF, 8}, {0x3782, 15}, {0x3783, 15}, + {0x000E, 4}, {0x001B, 5}, {0x006A, 7}, {0x006B, 7}, + {0x019D, 9}, {0x003C, 6}, {0x00F4, 8}, {0x00F5, 8}, + {0x03D8, 10}, {0x07B2, 11}, {0x3784, 15}, {0x03DA, 10}, + {0x3785, 15}, {0x03DB, 10}, {0x03DC, 10}, {0x3786, 15}, + {0x3787, 15}, {0x1BC4, 14}, {0x1BC5, 14}, {0x1BC6, 14}, + {0x1BC7, 14}, {0x001F, 5}, {0x03DD, 10}, {0x07B3, 11}, + {0x01EF, 9}, + },{//6 + {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x0016, 6}, + {0x0017, 6}, {0x0060, 8}, {0x00C2, 9}, {0x0186, 10}, + {0x0187, 10}, {0x00C4, 9}, {0x3140, 15}, {0x3141, 15}, + {0x018B, 10}, {0x3142, 15}, {0x018C, 10}, {0x3143, 15}, + {0x0007, 4}, {0x000D, 5}, {0x0064, 8}, {0x0065, 8}, + {0x0010, 5}, {0x00C7, 9}, {0x0066, 8}, {0x0005, 3}, + {0x0006, 3}, {0x0009, 4}, {0x0011, 5}, {0x0038, 6}, + {0x0039, 6}, {0x0074, 7}, {0x0075, 7}, {0x0076, 7}, + {0x0067, 8}, {0x00EE, 8}, {0x01DE, 9}, {0x00F0, 8}, + {0x018D, 10}, {0x3144, 15}, {0x01DF, 9}, {0x003D, 6}, + {0x003E, 6}, {0x01E2, 9}, {0x03C6, 10}, {0x00F2, 8}, + {0x00F3, 8}, {0x03C7, 10}, {0x3145, 15}, {0x3146, 15}, + {0x01F8, 9}, {0x3147, 15}, {0x3148, 15}, {0x3149, 15}, + {0x00FD, 8}, {0x314A, 15}, {0x314B, 15}, {0x314C, 15}, + {0x314D, 15}, {0x01F9, 9}, {0x314E, 15}, {0x01FC, 9}, + {0x314F, 15}, {0x3150, 15}, {0x3151, 15}, {0x3152, 15}, + {0x3153, 15}, {0x03FA, 10}, {0x03FB, 10}, {0x3154, 15}, + {0x3155, 15}, {0x3156, 15}, {0x3157, 15}, {0x3158, 15}, + {0x3159, 15}, {0x00FF, 8}, {0x18AD, 14}, {0x18AE, 14}, + {0x18AF, 14}, + },{//7 + {0x0000, 4}, {0x0080, 11}, {0x0081, 11}, {0x0082, 11}, + {0x0083, 11}, {0x0084, 11}, {0x0085, 11}, {0x0086, 11}, + {0x0087, 11}, {0x0088, 11}, {0x0089, 11}, {0x008A, 11}, + {0x008B, 11}, {0x008C, 11}, {0x008D, 11}, {0x008E, 11}, + {0x008F, 11}, {0x0048, 10}, {0x0049, 10}, {0x004A, 10}, + {0x004B, 10}, {0x004C, 10}, {0x004D, 10}, {0x0001, 1}, + {0x0001, 2}, {0x004E, 10}, {0x0002, 4}, {0x0003, 4}, + {0x004F, 10}, {0x0050, 10}, {0x0051, 10}, {0x0052, 10}, + {0x0053, 10}, {0x0054, 10}, {0x0055, 10}, {0x0056, 10}, + {0x0057, 10}, {0x0058, 10}, {0x0059, 10}, {0x005A, 10}, + {0x005B, 10}, {0x005C, 10}, {0x005D, 10}, {0x005E, 10}, + {0x005F, 10}, {0x0060, 10}, {0x0061, 10}, {0x0062, 10}, + {0x0063, 10}, {0x0064, 10}, {0x0065, 10}, {0x0066, 10}, + {0x0067, 10}, {0x0068, 10}, {0x0069, 10}, {0x006A, 10}, + {0x006B, 10}, {0x006C, 10}, {0x006D, 10}, {0x006E, 10}, + {0x006F, 10}, {0x0070, 10}, {0x0071, 10}, {0x0072, 10}, + {0x0073, 10}, {0x0074, 10}, {0x0075, 10}, {0x0076, 10}, + {0x0077, 10}, {0x0078, 10}, {0x0079, 10}, {0x007A, 10}, + {0x007B, 10}, {0x007C, 10}, {0x007D, 10}, {0x007E, 10}, + {0x007F, 10}, + } +}; + +static const uint16_t x8_ac0_highquant_table[8][77][2]={ + {//0 + {0x0000, 3}, {0x0002, 4}, {0x000C, 6}, {0x000D, 6}, + {0x001C, 7}, {0x000F, 6}, {0x1D00, 15}, {0x003B, 8}, + {0x1D01, 15}, {0x0075, 9}, {0x1D02, 15}, {0x0080, 9}, + {0x1D03, 15}, {0x1D04, 15}, {0x1D05, 15}, {0x0E83, 14}, + {0x0009, 5}, {0x0011, 6}, {0x0081, 9}, {0x0082, 9}, + {0x0021, 7}, {0x0028, 7}, {0x0083, 9}, {0x0002, 2}, + {0x0003, 3}, {0x000C, 4}, {0x000D, 4}, {0x000B, 5}, + {0x0015, 6}, {0x0052, 8}, {0x0070, 7}, {0x0039, 6}, + {0x0071, 7}, {0x0053, 8}, {0x0E84, 14}, {0x0074, 7}, + {0x0075, 7}, {0x0076, 7}, {0x01DC, 9}, {0x001E, 5}, + {0x003E, 6}, {0x01DD, 9}, {0x00EF, 8}, {0x01F8, 9}, + {0x01F9, 9}, {0x0E85, 14}, {0x0E86, 14}, {0x0E87, 14}, + {0x00FD, 8}, {0x0E88, 14}, {0x0E89, 14}, {0x0E8A, 14}, + {0x0E8B, 14}, {0x0E8C, 14}, {0x0E8D, 14}, {0x0E8E, 14}, + {0x0E8F, 14}, {0x0E90, 14}, {0x0E91, 14}, {0x01FC, 9}, + {0x0E92, 14}, {0x0E93, 14}, {0x0E94, 14}, {0x0E95, 14}, + {0x0E96, 14}, {0x0E97, 14}, {0x01FD, 9}, {0x0E98, 14}, + {0x01FE, 9}, {0x0E99, 14}, {0x0E9A, 14}, {0x0E9B, 14}, + {0x0E9C, 14}, {0x01FF, 9}, {0x0E9D, 14}, {0x0E9E, 14}, + {0x0E9F, 14}, + },{//1 + {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, + {0x0012, 6}, {0x0013, 6}, {0x0014, 6}, {0x0015, 6}, + {0x002C, 7}, {0x005A, 8}, {0x005B, 8}, {0x005C, 8}, + {0x005D, 8}, {0x1780, 14}, {0x0179, 10}, {0x017A, 10}, + {0x0006, 4}, {0x000E, 5}, {0x001E, 6}, {0x003E, 7}, + {0x0010, 5}, {0x0022, 6}, {0x0012, 5}, {0x000A, 4}, + {0x0013, 5}, {0x0016, 5}, {0x0023, 6}, {0x002E, 6}, + {0x002F, 6}, {0x0030, 6}, {0x0031, 6}, {0x003F, 7}, + {0x005F, 8}, {0x00C8, 8}, {0x0065, 7}, {0x0066, 7}, + {0x0067, 7}, {0x0068, 7}, {0x00C9, 8}, {0x0069, 7}, + {0x006A, 7}, {0x00D6, 8}, {0x00D7, 8}, {0x00D8, 8}, + {0x1781, 14}, {0x017B, 10}, {0x01B2, 9}, {0x1782, 14}, + {0x001C, 5}, {0x01B3, 9}, {0x1783, 14}, {0x1784, 14}, + {0x001D, 5}, {0x00DA, 8}, {0x1785, 14}, {0x1786, 14}, + {0x1787, 14}, {0x0037, 6}, {0x00DB, 8}, {0x0078, 7}, + {0x00F2, 8}, {0x01E6, 9}, {0x00F4, 8}, {0x1788, 14}, + {0x1789, 14}, {0x00F5, 8}, {0x01E7, 9}, {0x178A, 14}, + {0x178B, 14}, {0x178C, 14}, {0x178D, 14}, {0x01EC, 9}, + {0x178E, 14}, {0x001F, 5}, {0x00F7, 8}, {0x01ED, 9}, + {0x178F, 14}, + },{//2 + {0x0000, 4}, {0x0002, 5}, {0x0180, 12}, {0x0181, 12}, + {0x0182, 12}, {0x0183, 12}, {0x0184, 12}, {0x0185, 12}, + {0x0186, 12}, {0x0187, 12}, {0x0188, 12}, {0x0189, 12}, + {0x00C5, 11}, {0x00C6, 11}, {0x00C7, 11}, {0x00C8, 11}, + {0x00C9, 11}, {0x00CA, 11}, {0x00CB, 11}, {0x00CC, 11}, + {0x00CD, 11}, {0x00CE, 11}, {0x00CF, 11}, {0x0001, 1}, + {0x0001, 2}, {0x0004, 5}, {0x0005, 5}, {0x0006, 5}, + {0x00D0, 11}, {0x00D1, 11}, {0x00D2, 11}, {0x00D3, 11}, + {0x00D4, 11}, {0x00D5, 11}, {0x00D6, 11}, {0x00D7, 11}, + {0x00D8, 11}, {0x00D9, 11}, {0x00DA, 11}, {0x0007, 5}, + {0x00DB, 11}, {0x00DC, 11}, {0x00DD, 11}, {0x00DE, 11}, + {0x00DF, 11}, {0x00E0, 11}, {0x00E1, 11}, {0x00E2, 11}, + {0x00E3, 11}, {0x00E4, 11}, {0x00E5, 11}, {0x00E6, 11}, + {0x00E7, 11}, {0x00E8, 11}, {0x00E9, 11}, {0x00EA, 11}, + {0x00EB, 11}, {0x00EC, 11}, {0x00ED, 11}, {0x00EE, 11}, + {0x00EF, 11}, {0x00F0, 11}, {0x00F1, 11}, {0x00F2, 11}, + {0x00F3, 11}, {0x00F4, 11}, {0x00F5, 11}, {0x00F6, 11}, + {0x00F7, 11}, {0x00F8, 11}, {0x00F9, 11}, {0x00FA, 11}, + {0x00FB, 11}, {0x00FC, 11}, {0x00FD, 11}, {0x00FE, 11}, + {0x00FF, 11}, + },{//3 + {0x0000, 8}, {0x0001, 8}, {0x0002, 8}, {0x0003, 8}, + {0x0004, 8}, {0x0005, 8}, {0x0006, 8}, {0x0007, 8}, + {0x0008, 8}, {0x0009, 8}, {0x000A, 8}, {0x000B, 8}, + {0x000C, 8}, {0x000D, 8}, {0x000E, 8}, {0x000F, 8}, + {0x0010, 8}, {0x0011, 8}, {0x0012, 8}, {0x0013, 8}, + {0x0014, 8}, {0x0015, 8}, {0x0016, 8}, {0x0001, 1}, + {0x0017, 8}, {0x000C, 7}, {0x000D, 7}, {0x000E, 7}, + {0x000F, 7}, {0x0010, 7}, {0x0011, 7}, {0x0012, 7}, + {0x0013, 7}, {0x0014, 7}, {0x0015, 7}, {0x0016, 7}, + {0x0017, 7}, {0x0018, 7}, {0x0019, 7}, {0x001A, 7}, + {0x001B, 7}, {0x001C, 7}, {0x001D, 7}, {0x001E, 7}, + {0x001F, 7}, {0x0020, 7}, {0x0021, 7}, {0x0022, 7}, + {0x0023, 7}, {0x0024, 7}, {0x0025, 7}, {0x0026, 7}, + {0x0027, 7}, {0x0028, 7}, {0x0029, 7}, {0x002A, 7}, + {0x002B, 7}, {0x002C, 7}, {0x002D, 7}, {0x002E, 7}, + {0x002F, 7}, {0x0030, 7}, {0x0031, 7}, {0x0032, 7}, + {0x0033, 7}, {0x0034, 7}, {0x0035, 7}, {0x0036, 7}, + {0x0037, 7}, {0x0038, 7}, {0x0039, 7}, {0x003A, 7}, + {0x003B, 7}, {0x003C, 7}, {0x003D, 7}, {0x003E, 7}, + {0x003F, 7}, + },{//4 + {0x0000, 9}, {0x0001, 9}, {0x0002, 9}, {0x0003, 9}, + {0x0004, 9}, {0x0005, 9}, {0x0006, 9}, {0x0007, 9}, + {0x0008, 9}, {0x0009, 9}, {0x000A, 9}, {0x000B, 9}, + {0x000C, 9}, {0x000D, 9}, {0x000E, 9}, {0x000F, 9}, + {0x0010, 9}, {0x0011, 9}, {0x0012, 9}, {0x0013, 9}, + {0x0014, 9}, {0x0015, 9}, {0x000B, 8}, {0x0001, 2}, + {0x0001, 1}, {0x000C, 8}, {0x000D, 8}, {0x000E, 8}, + {0x000F, 8}, {0x0010, 8}, {0x0011, 8}, {0x0012, 8}, + {0x0013, 8}, {0x0014, 8}, {0x0015, 8}, {0x0016, 8}, + {0x0017, 8}, {0x0018, 8}, {0x0019, 8}, {0x001A, 8}, + {0x001B, 8}, {0x001C, 8}, {0x001D, 8}, {0x001E, 8}, + {0x001F, 8}, {0x0020, 8}, {0x0021, 8}, {0x0022, 8}, + {0x0023, 8}, {0x0024, 8}, {0x0025, 8}, {0x0026, 8}, + {0x0027, 8}, {0x0028, 8}, {0x0029, 8}, {0x002A, 8}, + {0x002B, 8}, {0x002C, 8}, {0x002D, 8}, {0x002E, 8}, + {0x002F, 8}, {0x0030, 8}, {0x0031, 8}, {0x0032, 8}, + {0x0033, 8}, {0x0034, 8}, {0x0035, 8}, {0x0036, 8}, + {0x0037, 8}, {0x0038, 8}, {0x0039, 8}, {0x003A, 8}, + {0x003B, 8}, {0x003C, 8}, {0x003D, 8}, {0x003E, 8}, + {0x003F, 8}, + },{//5 + {0x0000, 10}, {0x0001, 10}, {0x0002, 10}, {0x0003, 10}, + {0x0004, 10}, {0x0005, 10}, {0x0006, 10}, {0x0007, 10}, + {0x0008, 10}, {0x0009, 10}, {0x000A, 10}, {0x000B, 10}, + {0x000C, 10}, {0x000D, 10}, {0x000E, 10}, {0x000F, 10}, + {0x0010, 10}, {0x0011, 10}, {0x0012, 10}, {0x0013, 10}, + {0x000A, 9}, {0x000B, 9}, {0x000C, 9}, {0x0001, 1}, + {0x0001, 3}, {0x000D, 9}, {0x000E, 9}, {0x0001, 2}, + {0x000F, 9}, {0x0010, 9}, {0x0011, 9}, {0x0012, 9}, + {0x0013, 9}, {0x0014, 9}, {0x0015, 9}, {0x0016, 9}, + {0x0017, 9}, {0x0018, 9}, {0x0019, 9}, {0x001A, 9}, + {0x001B, 9}, {0x001C, 9}, {0x001D, 9}, {0x001E, 9}, + {0x001F, 9}, {0x0020, 9}, {0x0021, 9}, {0x0022, 9}, + {0x0023, 9}, {0x0024, 9}, {0x0025, 9}, {0x0026, 9}, + {0x0027, 9}, {0x0028, 9}, {0x0029, 9}, {0x002A, 9}, + {0x002B, 9}, {0x002C, 9}, {0x002D, 9}, {0x002E, 9}, + {0x002F, 9}, {0x0030, 9}, {0x0031, 9}, {0x0032, 9}, + {0x0033, 9}, {0x0034, 9}, {0x0035, 9}, {0x0036, 9}, + {0x0037, 9}, {0x0038, 9}, {0x0039, 9}, {0x003A, 9}, + {0x003B, 9}, {0x003C, 9}, {0x003D, 9}, {0x003E, 9}, + {0x003F, 9}, + },{//6 + {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5}, + {0x0018, 6}, {0x0019, 6}, {0x0034, 7}, {0x006A, 8}, + {0x006B, 8}, {0x006C, 8}, {0x00DA, 9}, {0x00DB, 9}, + {0x01B8, 10}, {0x00DD, 9}, {0x01B9, 10}, {0x3780, 15}, + {0x0004, 3}, {0x000E, 5}, {0x001E, 6}, {0x001F, 6}, + {0x000A, 4}, {0x0058, 7}, {0x0017, 5}, {0x0018, 5}, + {0x0059, 7}, {0x005A, 7}, {0x005B, 7}, {0x00C8, 8}, + {0x0065, 7}, {0x0066, 7}, {0x00C9, 8}, {0x00CE, 8}, + {0x00CF, 8}, {0x00D0, 8}, {0x00D1, 8}, {0x00D2, 8}, + {0x00D3, 8}, {0x00DF, 9}, {0x00D4, 8}, {0x00D5, 8}, + {0x00D6, 8}, {0x01AE, 9}, {0x3781, 15}, {0x01BD, 10}, + {0x035E, 10}, {0x035F, 10}, {0x3782, 15}, {0x0360, 10}, + {0x0037, 6}, {0x01B1, 9}, {0x3783, 15}, {0x3784, 15}, + {0x000E, 4}, {0x003C, 6}, {0x0361, 10}, {0x3785, 15}, + {0x1BC3, 14}, {0x003D, 6}, {0x00D9, 8}, {0x1BC4, 14}, + {0x0368, 10}, {0x1BC5, 14}, {0x1BC6, 14}, {0x1BC7, 14}, + {0x1BC8, 14}, {0x00DB, 8}, {0x0369, 10}, {0x036A, 10}, + {0x1BC9, 14}, {0x1BCA, 14}, {0x1BCB, 14}, {0x1BCC, 14}, + {0x1BCD, 14}, {0x001F, 5}, {0x036B, 10}, {0x1BCE, 14}, + {0x1BCF, 14}, + },{//7 + {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x0007, 5}, + {0x0010, 6}, {0x0044, 8}, {0x0023, 7}, {0x0012, 6}, + {0x0026, 7}, {0x08A0, 13}, {0x004E, 8}, {0x004F, 8}, + {0x08A1, 13}, {0x08A2, 13}, {0x08A3, 13}, {0x0050, 8}, + {0x0006, 4}, {0x000B, 5}, {0x0029, 7}, {0x0015, 6}, + {0x001C, 6}, {0x003A, 7}, {0x001E, 6}, {0x0004, 3}, + {0x0014, 5}, {0x0015, 5}, {0x000B, 4}, {0x001F, 6}, + {0x0030, 6}, {0x0031, 6}, {0x0019, 5}, {0x0051, 8}, + {0x0034, 6}, {0x0035, 6}, {0x0036, 6}, {0x0037, 6}, + {0x0076, 8}, {0x0077, 8}, {0x0070, 7}, {0x001D, 5}, + {0x0071, 7}, {0x0072, 7}, {0x08A4, 13}, {0x0073, 7}, + {0x00F0, 8}, {0x08A5, 13}, {0x08A6, 13}, {0x08A7, 13}, + {0x0079, 7}, {0x007A, 7}, {0x08A8, 13}, {0x08A9, 13}, + {0x00F1, 8}, {0x08AA, 13}, {0x08AB, 13}, {0x08AC, 13}, + {0x08AD, 13}, {0x00F6, 8}, {0x08AE, 13}, {0x007C, 7}, + {0x00F7, 8}, {0x08AF, 13}, {0x08B0, 13}, {0x08B1, 13}, + {0x08B2, 13}, {0x00FA, 8}, {0x08B3, 13}, {0x08B4, 13}, + {0x08B5, 13}, {0x08B6, 13}, {0x08B7, 13}, {0x00FB, 8}, + {0x045C, 12}, {0x003F, 6}, {0x045D, 12}, {0x045E, 12}, + {0x045F, 12}, + } +}; + +static const uint16_t x8_ac1_lowquant_table[8][77][2]={ + {//0 + {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, + {0x0012, 6}, {0x0026, 7}, {0x0014, 6}, {0x004E, 8}, + {0x004F, 8}, {0x00A8, 9}, {0x0152, 10}, {0x00AA, 9}, + {0x00AB, 9}, {0x00AC, 9}, {0x2A60, 15}, {0x02A7, 11}, + {0x0006, 4}, {0x000B, 5}, {0x001C, 6}, {0x003A, 7}, + {0x000F, 5}, {0x003B, 7}, {0x0010, 5}, {0x0005, 3}, + {0x0009, 4}, {0x0011, 5}, {0x0018, 5}, {0x0019, 5}, + {0x001A, 5}, {0x0036, 6}, {0x0037, 6}, {0x0070, 7}, + {0x0057, 8}, {0x00E2, 8}, {0x00E3, 8}, {0x00E4, 8}, + {0x00E5, 8}, {0x00AD, 9}, {0x0398, 10}, {0x003A, 6}, + {0x0076, 7}, {0x00E7, 8}, {0x00EE, 8}, {0x00EF, 8}, + {0x0732, 11}, {0x039A, 10}, {0x0733, 11}, {0x2A61, 15}, + {0x0078, 7}, {0x1531, 14}, {0x1532, 14}, {0x1533, 14}, + {0x003D, 6}, {0x039B, 10}, {0x1534, 14}, {0x1535, 14}, + {0x1536, 14}, {0x0079, 7}, {0x1537, 14}, {0x00F8, 8}, + {0x01F2, 9}, {0x07CC, 11}, {0x03E7, 10}, {0x07CD, 11}, + {0x3E80, 14}, {0x00FB, 8}, {0x03E9, 10}, {0x3E81, 14}, + {0x3E82, 14}, {0x3E83, 14}, {0x3E84, 14}, {0x3E85, 14}, + {0x3E86, 14}, {0x003F, 6}, {0x01F5, 9}, {0x07D1, 11}, + {0x3E87, 14}, + },{//1 + {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5}, + {0x001E, 6}, {0x001F, 6}, {0x0040, 7}, {0x0082, 8}, + {0x0083, 8}, {0x0084, 8}, {0x010A, 9}, {0x010B, 9}, + {0x0430, 11}, {0x0431, 11}, {0x0432, 11}, {0x0433, 11}, + {0x0005, 3}, {0x0011, 5}, {0x0024, 6}, {0x004A, 7}, + {0x000C, 4}, {0x0026, 6}, {0x000D, 4}, {0x0087, 8}, + {0x010D, 9}, {0x0258, 10}, {0x012D, 9}, {0x0259, 10}, + {0x025C, 10}, {0x0974, 12}, {0x025E, 10}, {0x025F, 10}, + {0x0270, 10}, {0x0271, 10}, {0x04BB, 11}, {0x0975, 12}, + {0x0272, 10}, {0x09CC, 12}, {0x09CD, 12}, {0x4E70, 15}, + {0x4E71, 15}, {0x4E72, 15}, {0x4E73, 15}, {0x273A, 14}, + {0x273B, 14}, {0x273C, 14}, {0x04E8, 11}, {0x04E9, 11}, + {0x009E, 8}, {0x0275, 10}, {0x09D8, 12}, {0x273D, 14}, + {0x000E, 4}, {0x003C, 6}, {0x007A, 7}, {0x009F, 8}, + {0x0277, 10}, {0x003E, 6}, {0x00F6, 8}, {0x04ED, 11}, + {0x03DC, 10}, {0x273E, 14}, {0x07BA, 11}, {0x09D9, 12}, + {0x273F, 14}, {0x3DD8, 14}, {0x3DD9, 14}, {0x3DDA, 14}, + {0x3DDB, 14}, {0x3DDC, 14}, {0x3DDD, 14}, {0x3DDE, 14}, + {0x3DDF, 14}, {0x003F, 6}, {0x07BC, 11}, {0x07BD, 11}, + {0x03DF, 10}, + },{//2 + {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x000E, 6}, + {0x001E, 7}, {0x003E, 8}, {0x003F, 8}, {0x0040, 8}, + {0x0104, 10}, {0x0083, 9}, {0x0105, 10}, {0x0108, 10}, + {0x4240, 16}, {0x010A, 10}, {0x010B, 10}, {0x4241, 16}, + {0x0003, 3}, {0x0009, 5}, {0x0011, 6}, {0x0043, 8}, + {0x0004, 3}, {0x000A, 5}, {0x000A, 4}, {0x002C, 7}, + {0x00B4, 9}, {0x00B5, 9}, {0x00B6, 9}, {0x00B7, 9}, + {0x00B8, 9}, {0x0172, 10}, {0x0173, 10}, {0x0174, 10}, + {0x0175, 10}, {0x0176, 10}, {0x0177, 10}, {0x00BC, 9}, + {0x017A, 10}, {0x0213, 11}, {0x4242, 16}, {0x017B, 10}, + {0x02F8, 11}, {0x017D, 10}, {0x02F9, 11}, {0x017E, 10}, + {0x4243, 16}, {0x02FE, 11}, {0x2122, 15}, {0x2123, 15}, + {0x0058, 7}, {0x0164, 9}, {0x2124, 15}, {0x2125, 15}, + {0x0006, 3}, {0x000E, 4}, {0x002D, 6}, {0x002E, 6}, + {0x00B3, 8}, {0x001E, 5}, {0x005E, 7}, {0x2126, 15}, + {0x2127, 15}, {0x2128, 15}, {0x2129, 15}, {0x02FF, 11}, + {0x212A, 15}, {0x0594, 11}, {0x0595, 11}, {0x0596, 11}, + {0x212B, 15}, {0x212C, 15}, {0x212D, 15}, {0x212E, 15}, + {0x212F, 15}, {0x001F, 5}, {0x0597, 11}, {0x00BE, 8}, + {0x00BF, 8}, + },{//3 + {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x0007, 4}, + {0x0010, 5}, {0x0011, 5}, {0x0024, 6}, {0x0025, 6}, + {0x0026, 6}, {0x0027, 6}, {0x0050, 7}, {0x0051, 7}, + {0x00A4, 8}, {0x00A5, 8}, {0x00A6, 8}, {0x014E, 9}, + {0x000B, 4}, {0x002A, 6}, {0x0056, 7}, {0x014F, 9}, + {0x0030, 6}, {0x00AE, 8}, {0x0062, 7}, {0x0032, 6}, + {0x0033, 6}, {0x0034, 6}, {0x0035, 6}, {0x0036, 6}, + {0x0063, 7}, {0x006E, 7}, {0x006F, 7}, {0x0070, 7}, + {0x0071, 7}, {0x0072, 7}, {0x0073, 7}, {0x0074, 7}, + {0x00AF, 8}, {0x00EA, 8}, {0x01D6, 9}, {0x075C, 11}, + {0x03AF, 10}, {0x75D0, 15}, {0x75D1, 15}, {0x75D2, 15}, + {0x75D3, 15}, {0x75D4, 15}, {0x0076, 7}, {0x00EE, 8}, + {0x00EF, 8}, {0x0EBB, 12}, {0x01E0, 9}, {0x75D5, 15}, + {0x0079, 7}, {0x01E1, 9}, {0x75D6, 15}, {0x75D7, 15}, + {0x7880, 15}, {0x00F4, 8}, {0x0789, 11}, {0x003E, 6}, + {0x007B, 7}, {0x00F5, 8}, {0x00FC, 8}, {0x007F, 7}, + {0x01E3, 9}, {0x078A, 11}, {0x078B, 11}, {0x7881, 15}, + {0x7882, 15}, {0x7883, 15}, {0x3C42, 14}, {0x3C43, 14}, + {0x3C44, 14}, {0x00FD, 8}, {0x3C45, 14}, {0x3C46, 14}, + {0x3C47, 14}, + },{//4 + {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x0016, 6}, + {0x0017, 6}, {0x0030, 7}, {0x0031, 7}, {0x0064, 8}, + {0x0065, 8}, {0x0066, 8}, {0x00CE, 9}, {0x00CF, 9}, + {0x01A0, 10}, {0x01A1, 10}, {0x1A20, 14}, {0x0689, 12}, + {0x0004, 3}, {0x000E, 5}, {0x001B, 6}, {0x0035, 7}, + {0x000A, 4}, {0x001E, 6}, {0x0016, 5}, {0x0017, 5}, + {0x001F, 6}, {0x0030, 6}, {0x0031, 6}, {0x0064, 7}, + {0x0065, 7}, {0x0069, 8}, {0x0066, 7}, {0x00CE, 8}, + {0x00CF, 8}, {0x00D0, 8}, {0x00D1, 8}, {0x00D2, 8}, + {0x01A6, 9}, {0x01A3, 10}, {0x034E, 10}, {0x006A, 7}, + {0x00D6, 8}, {0x01AE, 9}, {0x01AF, 9}, {0x034F, 10}, + {0x0345, 11}, {0x01B0, 9}, {0x01B1, 9}, {0x0364, 10}, + {0x006D, 7}, {0x00DC, 8}, {0x0D94, 12}, {0x0D95, 12}, + {0x000E, 4}, {0x003C, 6}, {0x00DD, 8}, {0x00DE, 8}, + {0x01B3, 9}, {0x003D, 6}, {0x00DF, 8}, {0x01F0, 9}, + {0x03E2, 10}, {0x03E3, 10}, {0x06CB, 11}, {0x03E4, 10}, + {0x07CA, 11}, {0x01F3, 9}, {0x01F4, 9}, {0x07CB, 11}, + {0x07D4, 11}, {0x1A21, 14}, {0x1A22, 14}, {0x07D5, 11}, + {0x1A23, 14}, {0x003F, 6}, {0x01F6, 9}, {0x01F7, 9}, + {0x03EB, 10}, + },{//5 + {0x0000, 2}, {0x0002, 3}, {0x0006, 4}, {0x000E, 5}, + {0x000F, 5}, {0x0020, 6}, {0x0021, 6}, {0x0044, 7}, + {0x0045, 7}, {0x0046, 7}, {0x008E, 8}, {0x008F, 8}, + {0x0090, 8}, {0x0122, 9}, {0x0246, 10}, {0x0124, 9}, + {0x0005, 3}, {0x0013, 5}, {0x004A, 7}, {0x0093, 8}, + {0x0018, 5}, {0x004B, 7}, {0x0032, 6}, {0x001A, 5}, + {0x0033, 6}, {0x006C, 7}, {0x006D, 7}, {0x006E, 7}, + {0x00DE, 8}, {0x00DF, 8}, {0x0070, 7}, {0x00E2, 8}, + {0x00E3, 8}, {0x00E4, 8}, {0x00E5, 8}, {0x00E6, 8}, + {0x00E7, 8}, {0x0125, 9}, {0x01D0, 9}, {0x048E, 11}, + {0x091E, 12}, {0x091F, 12}, {0x7440, 15}, {0x1D11, 13}, + {0x7441, 15}, {0x7442, 15}, {0x00E9, 8}, {0x01D4, 9}, + {0x00EB, 8}, {0x03A3, 10}, {0x01D5, 9}, {0x1D12, 13}, + {0x001E, 5}, {0x0076, 7}, {0x01DC, 9}, {0x01DD, 9}, + {0x7443, 15}, {0x007C, 7}, {0x0745, 11}, {0x00EF, 8}, + {0x00FA, 8}, {0x00FB, 8}, {0x01F8, 9}, {0x00FD, 8}, + {0x07E4, 11}, {0x0FCA, 12}, {0x1D13, 13}, {0x7E58, 15}, + {0x7E59, 15}, {0x7E5A, 15}, {0x7E5B, 15}, {0x7E5C, 15}, + {0x7E5D, 15}, {0x007F, 7}, {0x3F2F, 14}, {0x07E6, 11}, + {0x07E7, 11}, + },{//6 + {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, + {0x0009, 5}, {0x0014, 6}, {0x0015, 6}, {0x002C, 7}, + {0x005A, 8}, {0x005B, 8}, {0x005C, 8}, {0x00BA, 9}, + {0x00BB, 9}, {0x00BC, 9}, {0x02F4, 11}, {0x05EA, 12}, + {0x0003, 3}, {0x0010, 5}, {0x0022, 6}, {0x0046, 7}, + {0x0009, 4}, {0x0028, 6}, {0x0015, 5}, {0x000B, 4}, + {0x0018, 5}, {0x0029, 6}, {0x0032, 6}, {0x0047, 7}, + {0x0066, 7}, {0x0067, 7}, {0x0068, 7}, {0x0069, 7}, + {0x006A, 7}, {0x005F, 8}, {0x00D6, 8}, {0x00D7, 8}, + {0x01B0, 9}, {0x00D9, 8}, {0x017B, 10}, {0x006D, 7}, + {0x00DC, 8}, {0x01B1, 9}, {0x06E8, 11}, {0x01BB, 9}, + {0x0375, 10}, {0x05EB, 12}, {0x01BC, 9}, {0x6E90, 15}, + {0x0038, 6}, {0x0072, 7}, {0x6E91, 15}, {0x6E92, 15}, + {0x001D, 5}, {0x0073, 7}, {0x01BD, 9}, {0x06F8, 11}, + {0x6E93, 15}, {0x003C, 6}, {0x01BF, 9}, {0x00F4, 8}, + {0x01EA, 9}, {0x037D, 10}, {0x03D6, 10}, {0x06F9, 11}, + {0x6E94, 15}, {0x00F6, 8}, {0x01EE, 9}, {0x6E95, 15}, + {0x6E96, 15}, {0x6E97, 15}, {0x374C, 14}, {0x374D, 14}, + {0x374E, 14}, {0x001F, 5}, {0x03D7, 10}, {0x01EF, 9}, + {0x374F, 14}, + },{//7 + {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x0016, 6}, + {0x002E, 7}, {0x002F, 7}, {0x0060, 8}, {0x0061, 8}, + {0x00C4, 9}, {0x00C5, 9}, {0x00C6, 9}, {0x018E, 10}, + {0x31E0, 15}, {0x31E1, 15}, {0x31E2, 15}, {0x31E3, 15}, + {0x0004, 3}, {0x000D, 5}, {0x0019, 6}, {0x0038, 7}, + {0x000A, 4}, {0x001D, 6}, {0x000B, 4}, {0x0072, 8}, + {0x0073, 8}, {0x00F0, 9}, {0x01E2, 10}, {0x00F2, 9}, + {0x01E3, 10}, {0x00F3, 9}, {0x01E8, 10}, {0x01E9, 10}, + {0x31E4, 15}, {0x01EA, 10}, {0x031F, 11}, {0x03D6, 11}, + {0x31E5, 15}, {0x01EC, 10}, {0x31E6, 15}, {0x00F7, 9}, + {0x03D7, 11}, {0x31E7, 15}, {0x31E8, 15}, {0x03DA, 11}, + {0x03DB, 11}, {0x31E9, 15}, {0x03E0, 11}, {0x31EA, 15}, + {0x003F, 7}, {0x01F1, 10}, {0x31EB, 15}, {0x31EC, 15}, + {0x0006, 3}, {0x001C, 5}, {0x0074, 7}, {0x0075, 7}, + {0x00F9, 9}, {0x001E, 5}, {0x0076, 7}, {0x00FA, 9}, + {0x03E1, 11}, {0x31ED, 15}, {0x18F7, 14}, {0x1F60, 14}, + {0x1F61, 14}, {0x01DC, 9}, {0x01DD, 9}, {0x1F62, 14}, + {0x1F63, 14}, {0x1F64, 14}, {0x1F65, 14}, {0x1F66, 14}, + {0x1F67, 14}, {0x001F, 5}, {0x03ED, 11}, {0x00EF, 8}, + {0x01F7, 10}, + } +}; + +static const uint16_t x8_ac1_highquant_table[8][77][2]={ + {//0 + {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x0007, 5}, + {0x0008, 5}, {0x0009, 5}, {0x0014, 6}, {0x002A, 7}, + {0x0016, 6}, {0x002B, 7}, {0x005C, 8}, {0x002F, 7}, + {0x0030, 7}, {0x005D, 8}, {0x0062, 8}, {0x00C6, 9}, + {0x0007, 4}, {0x0019, 6}, {0x001A, 6}, {0x0036, 7}, + {0x0010, 5}, {0x006E, 8}, {0x0022, 6}, {0x0009, 4}, + {0x000A, 4}, {0x0016, 5}, {0x0023, 6}, {0x002E, 6}, + {0x002F, 6}, {0x0030, 6}, {0x0062, 7}, {0x0063, 7}, + {0x0064, 7}, {0x0065, 7}, {0x0066, 7}, {0x0067, 7}, + {0x0068, 7}, {0x0069, 7}, {0x006A, 7}, {0x006B, 7}, + {0x006C, 7}, {0x00C7, 9}, {0x00DE, 9}, {0x00DF, 9}, + {0x06D0, 11}, {0x01B5, 9}, {0x0037, 6}, {0x00DB, 8}, + {0x001C, 5}, {0x0074, 7}, {0x01D4, 9}, {0x01D5, 9}, + {0x0076, 7}, {0x0369, 10}, {0x3688, 14}, {0x3689, 14}, + {0x368A, 14}, {0x0077, 7}, {0x03AC, 10}, {0x0078, 7}, + {0x00F2, 8}, {0x01D7, 9}, {0x00F3, 8}, {0x007A, 7}, + {0x368B, 14}, {0x007B, 7}, {0x007C, 7}, {0x03AD, 10}, + {0x03E8, 10}, {0x368C, 14}, {0x368D, 14}, {0x03E9, 10}, + {0x368E, 14}, {0x003F, 6}, {0x01F5, 9}, {0x00FB, 8}, + {0x368F, 14}, + },{//1 + {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5}, + {0x0018, 6}, {0x0032, 7}, {0x0033, 7}, {0x0034, 7}, + {0x006A, 8}, {0x00D6, 9}, {0x00D7, 9}, {0x00D8, 9}, + {0x00D9, 9}, {0x3680, 15}, {0x01B5, 10}, {0x0369, 11}, + {0x0004, 3}, {0x000E, 5}, {0x001E, 6}, {0x0037, 7}, + {0x000A, 4}, {0x0016, 5}, {0x000C, 4}, {0x001F, 6}, + {0x005C, 7}, {0x005D, 7}, {0x00BC, 8}, {0x00BD, 8}, + {0x005F, 7}, {0x00D0, 8}, {0x00DB, 9}, {0x00D1, 8}, + {0x01A4, 9}, {0x01A5, 9}, {0x01A6, 9}, {0x01A7, 9}, + {0x0350, 10}, {0x06A2, 11}, {0x06A3, 11}, {0x01A9, 9}, + {0x01AA, 9}, {0x06AC, 11}, {0x3681, 15}, {0x0357, 10}, + {0x3682, 15}, {0x3683, 15}, {0x3684, 15}, {0x3685, 15}, + {0x0036, 6}, {0x00D6, 8}, {0x3686, 15}, {0x3687, 15}, + {0x000E, 4}, {0x006E, 7}, {0x00D7, 8}, {0x06AD, 11}, + {0x3688, 15}, {0x001E, 5}, {0x00DE, 8}, {0x06F8, 11}, + {0x037D, 10}, {0x3689, 15}, {0x368A, 15}, {0x368B, 15}, + {0x368C, 15}, {0x01BF, 9}, {0x368D, 15}, {0x1B47, 14}, + {0x37C8, 14}, {0x37C9, 14}, {0x37CA, 14}, {0x37CB, 14}, + {0x37CC, 14}, {0x001F, 5}, {0x37CD, 14}, {0x37CE, 14}, + {0x37CF, 14}, + },{//2 + {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, + {0x0012, 6}, {0x0026, 7}, {0x0014, 6}, {0x0027, 7}, + {0x00A8, 9}, {0x00A9, 9}, {0x0055, 8}, {0x2B00, 15}, + {0x00AD, 9}, {0x2B01, 15}, {0x2B02, 15}, {0x2B03, 15}, + {0x0003, 3}, {0x000B, 5}, {0x0040, 7}, {0x0041, 7}, + {0x0009, 4}, {0x0021, 6}, {0x0011, 5}, {0x000A, 4}, + {0x000B, 4}, {0x0018, 5}, {0x0032, 6}, {0x0033, 6}, + {0x0034, 6}, {0x0035, 6}, {0x006C, 7}, {0x0057, 8}, + {0x006D, 7}, {0x00DC, 8}, {0x0159, 10}, {0x00DD, 8}, + {0x01BC, 9}, {0x037A, 10}, {0x037B, 10}, {0x0038, 6}, + {0x0072, 7}, {0x01BE, 9}, {0x01BF, 9}, {0x00E6, 8}, + {0x039C, 10}, {0x01CF, 9}, {0x2B04, 15}, {0x2B05, 15}, + {0x0074, 7}, {0x01D4, 9}, {0x2B06, 15}, {0x2B07, 15}, + {0x001E, 5}, {0x00EB, 8}, {0x1584, 14}, {0x1585, 14}, + {0x1586, 14}, {0x003B, 6}, {0x01D5, 9}, {0x01F0, 9}, + {0x039D, 10}, {0x03E2, 10}, {0x1587, 14}, {0x1588, 14}, + {0x1589, 14}, {0x00F9, 8}, {0x158A, 14}, {0x158B, 14}, + {0x03E3, 10}, {0x158C, 14}, {0x158D, 14}, {0x01F4, 9}, + {0x158E, 14}, {0x003F, 6}, {0x00FB, 8}, {0x01F5, 9}, + {0x158F, 14}, + },{//3 + {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x0007, 5}, + {0x0010, 6}, {0x0011, 6}, {0x0024, 7}, {0x0025, 7}, + {0x0013, 6}, {0x0014, 6}, {0x002A, 7}, {0x002B, 7}, + {0x00B0, 9}, {0x00B1, 9}, {0x002D, 7}, {0x0059, 8}, + {0x000C, 5}, {0x0017, 6}, {0x00D0, 9}, {0x0035, 7}, + {0x001B, 6}, {0x0038, 7}, {0x0039, 7}, {0x0004, 3}, + {0x0005, 3}, {0x000F, 5}, {0x0018, 5}, {0x001D, 6}, + {0x0032, 6}, {0x0033, 6}, {0x0068, 7}, {0x0069, 7}, + {0x0069, 8}, {0x00D4, 8}, {0x00D5, 8}, {0x00D6, 8}, + {0x006C, 7}, {0x0037, 6}, {0x006D, 7}, {0x0070, 7}, + {0x0039, 6}, {0x00D7, 8}, {0x00D1, 9}, {0x3880, 14}, + {0x3881, 14}, {0x3882, 14}, {0x0074, 7}, {0x01C5, 9}, + {0x0075, 7}, {0x00E3, 8}, {0x3883, 14}, {0x3884, 14}, + {0x00EC, 8}, {0x3885, 14}, {0x1C43, 13}, {0x1C44, 13}, + {0x1C45, 13}, {0x00ED, 8}, {0x1C46, 13}, {0x003C, 6}, + {0x0077, 7}, {0x01E8, 9}, {0x003E, 6}, {0x007B, 7}, + {0x1C47, 13}, {0x007E, 7}, {0x007F, 7}, {0x1C48, 13}, + {0x1C49, 13}, {0x1C4A, 13}, {0x1C4B, 13}, {0x1C4C, 13}, + {0x1C4D, 13}, {0x00F5, 8}, {0x1C4E, 13}, {0x01E9, 9}, + {0x1C4F, 13}, + },{//4 + {0x0000, 2}, {0x0004, 4}, {0x000A, 5}, {0x000B, 5}, + {0x0018, 6}, {0x0019, 6}, {0x0034, 7}, {0x0035, 7}, + {0x0036, 7}, {0x006E, 8}, {0x00DE, 9}, {0x00DF, 9}, + {0x01C0, 10}, {0x01C1, 10}, {0x01C2, 10}, {0x3860, 15}, + {0x0004, 3}, {0x000F, 5}, {0x001D, 6}, {0x0039, 7}, + {0x000A, 4}, {0x002C, 6}, {0x002D, 6}, {0x000C, 4}, + {0x0017, 5}, {0x0034, 6}, {0x0035, 6}, {0x0036, 6}, + {0x006E, 7}, {0x006F, 7}, {0x0070, 7}, {0x0071, 7}, + {0x0071, 8}, {0x00E4, 8}, {0x00E5, 8}, {0x00E6, 8}, + {0x00E7, 8}, {0x00E8, 8}, {0x03A4, 10}, {0x0075, 7}, + {0x00EC, 8}, {0x01D3, 9}, {0x01DA, 9}, {0x03A5, 10}, + {0x03B6, 10}, {0x070D, 12}, {0x03B7, 10}, {0x070E, 12}, + {0x003C, 6}, {0x00EE, 8}, {0x3861, 15}, {0x3862, 15}, + {0x003D, 6}, {0x01DE, 9}, {0x3863, 15}, {0x3864, 15}, + {0x3865, 15}, {0x007C, 7}, {0x070F, 12}, {0x03BE, 10}, + {0x03BF, 10}, {0x3866, 15}, {0x0FA0, 12}, {0x07D1, 11}, + {0x3867, 15}, {0x00FB, 8}, {0x01F5, 9}, {0x7D08, 15}, + {0x0FA4, 12}, {0x7D09, 15}, {0x7D0A, 15}, {0x7D0B, 15}, + {0x3E86, 14}, {0x003F, 6}, {0x0FA5, 12}, {0x07D3, 11}, + {0x3E87, 14}, + },{//5 + {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, + {0x0009, 5}, {0x0014, 6}, {0x002A, 7}, {0x0056, 8}, + {0x02B8, 11}, {0x00AF, 9}, {0x02B9, 11}, {0x015D, 10}, + {0x02C0, 11}, {0x2C10, 15}, {0x2C11, 15}, {0x2C12, 15}, + {0x0006, 4}, {0x000E, 5}, {0x0017, 6}, {0x002D, 7}, + {0x000F, 5}, {0x0040, 7}, {0x0021, 6}, {0x0005, 3}, + {0x0009, 4}, {0x0011, 5}, {0x0018, 5}, {0x0019, 5}, + {0x001A, 5}, {0x0036, 6}, {0x0037, 6}, {0x0041, 7}, + {0x0059, 8}, {0x00E0, 8}, {0x00E1, 8}, {0x0071, 7}, + {0x00E4, 8}, {0x00B1, 9}, {0x02C2, 11}, {0x001D, 5}, + {0x0073, 7}, {0x00E5, 8}, {0x00F0, 8}, {0x0079, 7}, + {0x03C4, 10}, {0x01E3, 9}, {0x01E8, 9}, {0x2C13, 15}, + {0x007B, 7}, {0x2C14, 15}, {0x2C15, 15}, {0x2C16, 15}, + {0x007C, 7}, {0x02C3, 11}, {0x2C17, 15}, {0x160C, 14}, + {0x160D, 14}, {0x007D, 7}, {0x160E, 14}, {0x01E9, 9}, + {0x03C5, 10}, {0x03D4, 10}, {0x01EB, 9}, {0x160F, 14}, + {0x3D50, 14}, {0x00FC, 8}, {0x07AB, 11}, {0x3D51, 14}, + {0x3D52, 14}, {0x3D53, 14}, {0x3D54, 14}, {0x01FA, 9}, + {0x3D55, 14}, {0x007F, 7}, {0x01FB, 9}, {0x3D56, 14}, + {0x3D57, 14}, + },{//6 + {0x0000, 3}, {0x0002, 4}, {0x0003, 4}, {0x0008, 5}, + {0x0009, 5}, {0x000A, 5}, {0x000B, 5}, {0x0018, 6}, + {0x0032, 7}, {0x000D, 5}, {0x0033, 7}, {0x0E00, 13}, + {0x0039, 7}, {0x0E01, 13}, {0x003A, 7}, {0x0E02, 13}, + {0x0008, 4}, {0x001E, 6}, {0x003B, 7}, {0x003E, 7}, + {0x0012, 5}, {0x003F, 7}, {0x0013, 5}, {0x0028, 6}, + {0x0029, 6}, {0x0054, 7}, {0x002B, 6}, {0x0055, 7}, + {0x0058, 7}, {0x0E03, 13}, {0x0059, 7}, {0x005A, 7}, + {0x0E04, 13}, {0x0E05, 13}, {0x0703, 12}, {0x005B, 7}, + {0x005C, 7}, {0x0704, 12}, {0x0705, 12}, {0x005D, 7}, + {0x0706, 12}, {0x0707, 12}, {0x0708, 12}, {0x0709, 12}, + {0x070A, 12}, {0x070B, 12}, {0x0018, 5}, {0x002F, 6}, + {0x000D, 4}, {0x0019, 5}, {0x070C, 12}, {0x0070, 7}, + {0x001D, 5}, {0x070D, 12}, {0x070E, 12}, {0x070F, 12}, + {0x0710, 12}, {0x0039, 6}, {0x0711, 12}, {0x003C, 6}, + {0x0712, 12}, {0x0713, 12}, {0x0714, 12}, {0x0715, 12}, + {0x0716, 12}, {0x003D, 6}, {0x0717, 12}, {0x0718, 12}, + {0x0719, 12}, {0x071A, 12}, {0x071B, 12}, {0x071C, 12}, + {0x071D, 12}, {0x001F, 5}, {0x071E, 12}, {0x0071, 7}, + {0x071F, 12}, + },{//7 + {0x0000, 3}, {0x0002, 4}, {0x0006, 5}, {0x000E, 6}, + {0x000F, 6}, {0x0040, 8}, {0x0041, 8}, {0x0042, 8}, + {0x0218, 11}, {0x2190, 15}, {0x2191, 15}, {0x2192, 15}, + {0x2193, 15}, {0x2194, 15}, {0x2195, 15}, {0x2196, 15}, + {0x0005, 4}, {0x0011, 6}, {0x0024, 7}, {0x0087, 9}, + {0x000C, 5}, {0x004A, 8}, {0x004B, 8}, {0x0002, 2}, + {0x0006, 3}, {0x000D, 5}, {0x000E, 5}, {0x000F, 5}, + {0x0013, 6}, {0x0038, 6}, {0x00E4, 8}, {0x00E5, 8}, + {0x01CC, 9}, {0x00E7, 8}, {0x0074, 7}, {0x00EA, 8}, + {0x01CD, 9}, {0x021A, 11}, {0x2197, 15}, {0x001E, 5}, + {0x0076, 7}, {0x00EB, 8}, {0x01DC, 9}, {0x00EF, 8}, + {0x01DD, 9}, {0x01F0, 9}, {0x2198, 15}, {0x2199, 15}, + {0x00F9, 8}, {0x03E2, 10}, {0x219A, 15}, {0x219B, 15}, + {0x00FA, 8}, {0x219C, 15}, {0x219D, 15}, {0x219E, 15}, + {0x219F, 15}, {0x01F6, 9}, {0x21B0, 15}, {0x00FC, 8}, + {0x01F7, 9}, {0x21B1, 15}, {0x21B2, 15}, {0x21B3, 15}, + {0x21B4, 15}, {0x01FA, 9}, {0x21B5, 15}, {0x21B6, 15}, + {0x21B7, 15}, {0x21B8, 15}, {0x21B9, 15}, {0x03E3, 10}, + {0x10DD, 14}, {0x007F, 7}, {0x01FB, 9}, {0x10DE, 14}, + {0x10DF, 14}, + } +}; +#define MAX_AC_VLC_BITS 16 + +#endif /* FFMPEG_INTRAX8HUF_H */ diff --git a/contrib/ffmpeg/libavcodec/jpeg_ls.c b/contrib/ffmpeg/libavcodec/jpeg_ls.c deleted file mode 100644 index 136e3fb80..000000000 --- a/contrib/ffmpeg/libavcodec/jpeg_ls.c +++ /dev/null @@ -1,860 +0,0 @@ -/* - * JPEG-LS encoder and decoder - * Copyright (c) 2003 Michael Niedermayer - * 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 "golomb.h" - -/** - * @file jpeg_ls.c - * JPEG-LS encoder and decoder. - */ - -typedef struct JpeglsContext{ - AVCodecContext *avctx; - AVFrame picture; -}JpeglsContext; - -typedef struct JLSState{ - int T1, T2, T3; - int A[367], B[367], C[365], N[367]; - int limit, reset, bpp, qbpp, maxval, range; - int near, twonear; - int run_index[3]; -}JLSState; - -static const uint8_t log2_run[32]={ - 0, 0, 0, 0, 1, 1, 1, 1, - 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, - 8, 9,10,11,12,13,14,15 -}; - -/* -* Uncomment this to significantly speed up decoding of broken JPEG-LS -* (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit. -* -* There is no Golomb code with length >= 32 bits possible, so check and -* avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow -* on this errors. -*/ -//#define JLS_BROKEN - -/********** Functions for both encoder and decoder **********/ - -/** - * Calculate initial JPEG-LS parameters - */ -static void ls_init_state(JLSState *state){ - int i; - - state->twonear = state->near * 2 + 1; - state->range = ((state->maxval + state->twonear - 1) / state->twonear) + 1; - - // QBPP = ceil(log2(RANGE)) - for(state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++); - - if(state->bpp < 8) - state->limit = 16 + 2 * state->bpp - state->qbpp; - else - state->limit = (4 * state->bpp) - state->qbpp; - - for(i = 0; i < 367; i++) { - state->A[i] = FFMAX((state->range + 32) >> 6, 2); - state->N[i] = 1; - } - -} - -/** - * Calculate quantized gradient value, used for context determination - */ -static inline int quantize(JLSState *s, int v){ //FIXME optimize - if(v==0) return 0; - if(v < 0){ - if(v <= -s->T3) return -4; - if(v <= -s->T2) return -3; - if(v <= -s->T1) return -2; - if(v < -s->near) return -1; - return 0; - }else{ - if(v <= s->near) return 0; - if(v < s->T1) return 1; - if(v < s->T2) return 2; - if(v < s->T3) return 3; - return 4; - } -} - -/** - * Custom value clipping function used in T1, T2, T3 calculation - */ -static inline int iso_clip(int v, int vmin, int vmax){ - if(v > vmax || v < vmin) return vmin; - else return v; -} - -/** - * Calculate JPEG-LS codec values - */ -static void reset_ls_coding_parameters(JLSState *s, int reset_all){ - const int basic_t1= 3; - const int basic_t2= 7; - const int basic_t3= 21; - int factor; - - if(s->maxval==0 || reset_all) s->maxval= (1 << s->bpp) - 1; - - if(s->maxval >=128){ - factor= (FFMIN(s->maxval, 4095) + 128)>>8; - - if(s->T1==0 || reset_all) - s->T1= iso_clip(factor*(basic_t1-2) + 2 + 3*s->near, s->near+1, s->maxval); - if(s->T2==0 || reset_all) - s->T2= iso_clip(factor*(basic_t2-3) + 3 + 5*s->near, s->T1, s->maxval); - if(s->T3==0 || reset_all) - s->T3= iso_clip(factor*(basic_t3-4) + 4 + 7*s->near, s->T2, s->maxval); - }else{ - factor= 256 / (s->maxval + 1); - - if(s->T1==0 || reset_all) - s->T1= iso_clip(FFMAX(2, basic_t1/factor + 3*s->near), s->near+1, s->maxval); - if(s->T2==0 || reset_all) - s->T2= iso_clip(FFMAX(3, basic_t2/factor + 5*s->near), s->T1, s->maxval); - if(s->T3==0 || reset_all) - s->T3= iso_clip(FFMAX(4, basic_t3/factor + 6*s->near), s->T2, s->maxval); - } - - if(s->reset==0 || reset_all) s->reset= 64; -// av_log(NULL, AV_LOG_DEBUG, "[JPEG-LS RESET] T=%i,%i,%i\n", s->T1, s->T2, s->T3); -} - - -/********** Decoder-specific functions **********/ - -/** - * Decode LSE block with initialization parameters - */ -static int decode_lse(MJpegDecodeContext *s) -{ - int len, id; - - /* XXX: verify len field validity */ - len = get_bits(&s->gb, 16); - id = get_bits(&s->gb, 8); - - switch(id){ - case 1: - s->maxval= get_bits(&s->gb, 16); - s->t1= get_bits(&s->gb, 16); - s->t2= get_bits(&s->gb, 16); - s->t3= get_bits(&s->gb, 16); - s->reset= get_bits(&s->gb, 16); - -// reset_ls_coding_parameters(s, 0); - //FIXME quant table? - break; - case 2: - case 3: - av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n"); - return -1; - case 4: - av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n"); - return -1; - default: - av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id); - return -1; - } -// av_log(s->avctx, AV_LOG_DEBUG, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3); - - return 0; -} - -static void inline downscale_state(JLSState *state, int Q){ - if(state->N[Q] == state->reset){ - state->A[Q] >>=1; - state->B[Q] >>=1; - state->N[Q] >>=1; - } - state->N[Q]++; -} - -static inline int update_state_regular(JLSState *state, int Q, int err){ - state->A[Q] += FFABS(err); - err *= state->twonear; - state->B[Q] += err; - - downscale_state(state, Q); - - if(state->B[Q] <= -state->N[Q]) { - state->B[Q]= FFMAX(state->B[Q] + state->N[Q], 1-state->N[Q]); - if(state->C[Q] > -128) - state->C[Q]--; - }else if(state->B[Q] > 0){ - state->B[Q]= FFMIN(state->B[Q] - state->N[Q], 0); - if(state->C[Q] < 127) - state->C[Q]++; - } - - return err; -} - -/** - * Get context-dependent Golomb code, decode it and update context - */ -static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q){ - int k, ret; - - for(k = 0; (state->N[Q] << k) < state->A[Q]; k++); - -#ifdef JLS_BROKEN - if(!show_bits_long(gb, 32))return -1; -#endif - ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp); - - /* decode mapped error */ - if(ret & 1) - ret = -((ret + 1) >> 1); - else - ret >>= 1; - - /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */ - if(!state->near && !k && (2 * state->B[Q] <= -state->N[Q])) - ret = -(ret + 1); - - ret= update_state_regular(state, Q, ret); - - return ret; -} - -/** - * Get Golomb code, decode it and update state for run termination - */ -static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RItype, int limit_add){ - int k, ret, temp, map; - int Q = 365 + RItype; - - temp= state->A[Q]; - if(RItype) - temp += state->N[Q] >> 1; - - for(k = 0; (state->N[Q] << k) < temp; k++); - -#ifdef JLS_BROKEN - if(!show_bits_long(gb, 32))return -1; -#endif - ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp); - - /* decode mapped error */ - map = 0; - if(!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q])) - map = 1; - ret += RItype + map; - - if(ret & 1){ - ret = map - ((ret + 1) >> 1); - state->B[Q]++; - } else { - ret = ret >> 1; - } - - /* update state */ - state->A[Q] += FFABS(ret) - RItype; - ret *= state->twonear; - downscale_state(state, Q); - - return ret; -} - -#define R(a, i ) (bits == 8 ? ((uint8_t*)(a))[i] : ((uint16_t*)(a))[i] ) -#define W(a, i, v) (bits == 8 ? (((uint8_t*)(a))[i]=v) : (((uint16_t*)(a))[i]=v)) -/** - * Decode one line of image - */ -static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *last, void *dst, int last2, int w, int stride, int comp, int bits){ - int i, x = 0; - int Ra, Rb, Rc, Rd; - int D0, D1, D2; - - while(x < w) { - int err, pred; - - /* compute gradients */ - Ra = x ? R(dst, x - stride) : R(last, x); - Rb = R(last, x); - Rc = x ? R(last, x - stride) : last2; - Rd = (x >= w - stride) ? R(last, x) : R(last, x + stride); - D0 = Rd - Rb; - D1 = Rb - Rc; - D2 = Rc - Ra; - /* run mode */ - if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) { - int r; - int RItype; - - /* decode full runs while available */ - while(get_bits1(&s->gb)) { - int r; - r = 1 << log2_run[state->run_index[comp]]; - if(x + r * stride > w) { - r = (w - x) / stride; - } - for(i = 0; i < r; i++) { - W(dst, x, Ra); - x += stride; - } - /* if EOL reached, we stop decoding */ - if(r != (1 << log2_run[state->run_index[comp]])) - return; - if(state->run_index[comp] < 31) - state->run_index[comp]++; - if(x + stride > w) - return; - } - /* decode aborted run */ - r = log2_run[state->run_index[comp]]; - if(r) - r = get_bits_long(&s->gb, r); - for(i = 0; i < r; i++) { - W(dst, x, Ra); - x += stride; - } - - /* decode run termination value */ - Rb = R(last, x); - RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0; - err = ls_get_code_runterm(&s->gb, state, RItype, log2_run[state->run_index[comp]]); - if(state->run_index[comp]) - state->run_index[comp]--; - - if(state->near && RItype){ - pred = Ra + err; - } else { - if(Rb < Ra) - pred = Rb - err; - else - pred = Rb + err; - } - } else { /* regular mode */ - int context, sign; - - context = quantize(state, D0) * 81 + quantize(state, D1) * 9 + quantize(state, D2); - pred = mid_pred(Ra, Ra + Rb - Rc, Rb); - - if(context < 0){ - context = -context; - sign = 1; - }else{ - sign = 0; - } - - if(sign){ - pred = av_clip(pred - state->C[context], 0, state->maxval); - err = -ls_get_code_regular(&s->gb, state, context); - } else { - pred = av_clip(pred + state->C[context], 0, state->maxval); - err = ls_get_code_regular(&s->gb, state, context); - } - - /* we have to do something more for near-lossless coding */ - pred += err; - } - if(state->near){ - if(pred < -state->near) - pred += state->range * state->twonear; - else if(pred > state->maxval + state->near) - pred -= state->range * state->twonear; - pred = av_clip(pred, 0, state->maxval); - } - - pred &= state->maxval; - W(dst, x, pred); - x += stride; - } -} - -static int ls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){ - int i, t = 0; - uint8_t *zero, *last, *cur; - JLSState *state; - int off = 0, stride = 1, width, shift; - - zero = av_mallocz(s->picture.linesize[0]); - last = zero; - cur = s->picture.data[0]; - - state = av_mallocz(sizeof(JLSState)); - /* initialize JPEG-LS state from JPEG parameters */ - state->near = near; - state->bpp = (s->bits < 2) ? 2 : s->bits; - state->maxval = s->maxval; - state->T1 = s->t1; - state->T2 = s->t2; - state->T3 = s->t3; - state->reset = s->reset; - reset_ls_coding_parameters(state, 0); - ls_init_state(state); - - if(s->bits <= 8) - shift = point_transform + (8 - s->bits); - else - shift = point_transform + (16 - s->bits); - -// av_log(s->avctx, AV_LOG_DEBUG, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",s->width,s->height,state->near,state->maxval,state->T1,state->T2,state->T3,state->reset,state->limit,state->qbpp, state->range); -// av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n", ilv, point_transform, s->bits, s->cur_scan); - if(ilv == 0) { /* separate planes */ - off = s->cur_scan - 1; - stride = (s->nb_components > 1) ? 3 : 1; - width = s->width * stride; - cur += off; - for(i = 0; i < s->height; i++) { - if(s->bits <= 8){ - ls_decode_line(state, s, last, cur, t, width, stride, off, 8); - t = last[0]; - }else{ - ls_decode_line(state, s, last, cur, t, width, stride, off, 16); - t = *((uint16_t*)last); - } - last = cur; - cur += s->picture.linesize[0]; - - if (s->restart_interval && !--s->restart_count) { - align_get_bits(&s->gb); - skip_bits(&s->gb, 16); /* skip RSTn */ - } - } - } else if(ilv == 1) { /* line interleaving */ - int j; - int Rc[3] = {0, 0, 0}; - memset(cur, 0, s->picture.linesize[0]); - width = s->width * 3; - for(i = 0; i < s->height; i++) { - for(j = 0; j < 3; j++) { - ls_decode_line(state, s, last + j, cur + j, Rc[j], width, 3, j, 8); - Rc[j] = last[j]; - - if (s->restart_interval && !--s->restart_count) { - align_get_bits(&s->gb); - skip_bits(&s->gb, 16); /* skip RSTn */ - } - } - last = cur; - cur += s->picture.linesize[0]; - } - } else if(ilv == 2) { /* sample interleaving */ - av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n"); - av_free(state); - av_free(zero); - return -1; - } - - if(shift){ /* we need to do point transform or normalize samples */ - int x, w; - - w = s->width * s->nb_components; - - if(s->bits <= 8){ - uint8_t *src = s->picture.data[0]; - - for(i = 0; i < s->height; i++){ - for(x = off; x < w; x+= stride){ - src[x] <<= shift; - } - src += s->picture.linesize[0]; - } - }else{ - uint16_t *src = (uint16_t*) s->picture.data[0]; - - for(i = 0; i < s->height; i++){ - for(x = 0; x < w; x++){ - src[x] <<= shift; - } - src += s->picture.linesize[0]/2; - } - } - } - av_free(state); - av_free(zero); - - return 0; -} - -#if defined(CONFIG_ENCODERS) && defined(CONFIG_JPEGLS_ENCODER) -/********** Encoder-specific functions **********/ - -/** - * Encode error from regular symbol - */ -static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q, int err){ - int k; - int val; - int map; - - for(k = 0; (state->N[Q] << k) < state->A[Q]; k++); - - map = !state->near && !k && (2 * state->B[Q] <= -state->N[Q]); - - if(err < 0) - err += state->range; - if(err >= ((state->range + 1) >> 1)) { - err -= state->range; - val = 2 * FFABS(err) - 1 - map; - } else - val = 2 * err + map; - - set_ur_golomb_jpegls(pb, val, k, state->limit, state->qbpp); - - update_state_regular(state, Q, err); -} - -/** - * Encode error from run termination - */ -static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RItype, int err, int limit_add){ - int k; - int val, map; - int Q = 365 + RItype; - int temp; - - temp = state->A[Q]; - if(RItype) - temp += state->N[Q] >> 1; - for(k = 0; (state->N[Q] << k) < temp; k++); - map = 0; - if(!k && err && (2 * state->B[Q] < state->N[Q])) - map = 1; - - if(err < 0) - val = - (2 * err) - 1 - RItype + map; - else - val = 2 * err - RItype - map; - set_ur_golomb_jpegls(pb, val, k, state->limit - limit_add - 1, state->qbpp); - - if(err < 0) - state->B[Q]++; - state->A[Q] += (val + 1 - RItype) >> 1; - - downscale_state(state, Q); -} - -/** - * Encode run value as specified by JPEG-LS standard - */ -static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, int comp, int trail){ - while(run >= (1 << log2_run[state->run_index[comp]])){ - put_bits(pb, 1, 1); - run -= 1 << log2_run[state->run_index[comp]]; - if(state->run_index[comp] < 31) - state->run_index[comp]++; - } - /* if hit EOL, encode another full run, else encode aborted run */ - if(!trail && run) { - put_bits(pb, 1, 1); - }else if(trail){ - put_bits(pb, 1, 0); - if(log2_run[state->run_index[comp]]) - put_bits(pb, log2_run[state->run_index[comp]], run); - } -} - -/** - * Encode one line of image - */ -static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last, void *cur, int last2, int w, int stride, int comp, int bits){ - int x = 0; - int Ra, Rb, Rc, Rd; - int D0, D1, D2; - - while(x < w) { - int err, pred, sign; - - /* compute gradients */ - Ra = x ? R(cur, x - stride) : R(last, x); - Rb = R(last, x); - Rc = x ? R(last, x - stride) : last2; - Rd = (x >= w - stride) ? R(last, x) : R(last, x + stride); - D0 = Rd - Rb; - D1 = Rb - Rc; - D2 = Rc - Ra; - - /* run mode */ - if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) { - int RUNval, RItype, run; - - run = 0; - RUNval = Ra; - while(x < w && (FFABS(R(cur, x) - RUNval) <= state->near)){ - run++; - W(cur, x, Ra); - x += stride; - } - ls_encode_run(state, pb, run, comp, x < w); - if(x >= w) - return; - Rb = R(last, x); - RItype = (FFABS(Ra - Rb) <= state->near); - pred = RItype ? Ra : Rb; - err = R(cur, x) - pred; - - if(!RItype && Ra > Rb) - err = -err; - - if(state->near){ - if(err > 0) - err = (state->near + err) / state->twonear; - else - err = -(state->near - err) / state->twonear; - - if(RItype || (Rb >= Ra)) - Ra = av_clip(pred + err * state->twonear, 0, state->maxval); - else - Ra = av_clip(pred - err * state->twonear, 0, state->maxval); - W(cur, x, Ra); - } - if(err < 0) - err += state->range; - if(err >= ((state->range + 1) >> 1)) - err -= state->range; - - ls_encode_runterm(state, pb, RItype, err, log2_run[state->run_index[comp]]); - - if(state->run_index[comp] > 0) - state->run_index[comp]--; - } else { /* regular mode */ - int context; - - context = quantize(state, D0) * 81 + quantize(state, D1) * 9 + quantize(state, D2); - pred = mid_pred(Ra, Ra + Rb - Rc, Rb); - - if(context < 0){ - context = -context; - sign = 1; - pred = av_clip(pred - state->C[context], 0, state->maxval); - err = pred - R(cur, x); - }else{ - sign = 0; - pred = av_clip(pred + state->C[context], 0, state->maxval); - err = R(cur, x) - pred; - } - - if(state->near){ - if(err > 0) - err = (state->near + err) / state->twonear; - else - err = -(state->near - err) / state->twonear; - if(!sign) - Ra = av_clip(pred + err * state->twonear, 0, state->maxval); - else - Ra = av_clip(pred - err * state->twonear, 0, state->maxval); - W(cur, x, Ra); - } - - ls_encode_regular(state, pb, context, err); - } - x += stride; - } -} - -static void ls_store_lse(JLSState *state, PutBitContext *pb){ - /* Test if we have default params and don't need to store LSE */ - JLSState state2; - memset(&state2, 0, sizeof(JLSState)); - state2.bpp = state->bpp; - state2.near = state->near; - reset_ls_coding_parameters(&state2, 1); - if(state->T1 == state2.T1 && state->T2 == state2.T2 && state->T3 == state2.T3 && state->reset == state2.reset) - return; - /* store LSE type 1 */ - put_marker(pb, LSE); - put_bits(pb, 16, 13); - put_bits(pb, 8, 1); - put_bits(pb, 16, state->maxval); - put_bits(pb, 16, state->T1); - put_bits(pb, 16, state->T2); - put_bits(pb, 16, state->T3); - put_bits(pb, 16, state->reset); -} - -static int encode_picture_ls(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - JpeglsContext * const s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&s->picture; - const int near = avctx->prediction_method; - PutBitContext pb, pb2; - GetBitContext gb; - uint8_t *buf2, *zero, *cur, *last; - JLSState *state; - int i, size; - int comps; - - buf2 = av_malloc(buf_size); - - init_put_bits(&pb, buf, buf_size); - init_put_bits(&pb2, buf2, buf_size); - - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - if(avctx->pix_fmt == PIX_FMT_GRAY8 || avctx->pix_fmt == PIX_FMT_GRAY16) - comps = 1; - else - comps = 3; - - /* write our own JPEG header, can't use mjpeg_picture_header */ - put_marker(&pb, SOI); - put_marker(&pb, SOF48); - put_bits(&pb, 16, 8 + comps * 3); // header size depends on components - put_bits(&pb, 8, (avctx->pix_fmt == PIX_FMT_GRAY16) ? 16 : 8); // bpp - put_bits(&pb, 16, avctx->height); - put_bits(&pb, 16, avctx->width); - put_bits(&pb, 8, comps); // components - for(i = 1; i <= comps; i++) { - put_bits(&pb, 8, i); // component ID - put_bits(&pb, 8, 0x11); // subsampling: none - put_bits(&pb, 8, 0); // Tiq, used by JPEG-LS ext - } - - put_marker(&pb, SOS); - put_bits(&pb, 16, 6 + comps * 2); - put_bits(&pb, 8, comps); - for(i = 1; i <= comps; i++) { - put_bits(&pb, 8, i); // component ID - put_bits(&pb, 8, 0); // mapping index: none - } - put_bits(&pb, 8, near); - put_bits(&pb, 8, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line - put_bits(&pb, 8, 0); // point transform: none - - state = av_mallocz(sizeof(JLSState)); - /* initialize JPEG-LS state from JPEG parameters */ - state->near = near; - state->bpp = (avctx->pix_fmt == PIX_FMT_GRAY16) ? 16 : 8; - reset_ls_coding_parameters(state, 0); - ls_init_state(state); - - ls_store_lse(state, &pb); - - zero = av_mallocz(p->linesize[0]); - last = zero; - cur = p->data[0]; - if(avctx->pix_fmt == PIX_FMT_GRAY8){ - int t = 0; - - for(i = 0; i < avctx->height; i++) { - ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 8); - t = last[0]; - last = cur; - cur += p->linesize[0]; - } - }else if(avctx->pix_fmt == PIX_FMT_GRAY16){ - int t = 0; - - for(i = 0; i < avctx->height; i++) { - ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16); - t = *((uint16_t*)last); - last = cur; - cur += p->linesize[0]; - } - }else if(avctx->pix_fmt == PIX_FMT_RGB24){ - int j, width; - int Rc[3] = {0, 0, 0}; - - width = avctx->width * 3; - for(i = 0; i < avctx->height; i++) { - for(j = 0; j < 3; j++) { - ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8); - Rc[j] = last[j]; - } - last = cur; - cur += s->picture.linesize[0]; - } - }else if(avctx->pix_fmt == PIX_FMT_BGR24){ - int j, width; - int Rc[3] = {0, 0, 0}; - - width = avctx->width * 3; - for(i = 0; i < avctx->height; i++) { - for(j = 2; j >= 0; j--) { - ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8); - Rc[j] = last[j]; - } - last = cur; - cur += s->picture.linesize[0]; - } - } - - av_free(zero); - av_free(state); - - // the specification says that after doing 0xff escaping unused bits in the - // last byte must be set to 0, so just append 7 "optional" zero-bits to - // avoid special-casing. - put_bits(&pb2, 7, 0); - size = put_bits_count(&pb2); - flush_put_bits(&pb2); - /* do escape coding */ - init_get_bits(&gb, buf2, size); - size -= 7; - while(get_bits_count(&gb) < size){ - int v; - v = get_bits(&gb, 8); - put_bits(&pb, 8, v); - if(v == 0xFF){ - v = get_bits(&gb, 7); - put_bits(&pb, 8, v); - } - } - align_put_bits(&pb); - av_free(buf2); - - /* End of image */ - put_marker(&pb, EOI); - flush_put_bits(&pb); - - emms_c(); - - return put_bits_count(&pb) >> 3; -} - -static int encode_init_ls(AVCodecContext *ctx) { - JpeglsContext *c = (JpeglsContext*)ctx->priv_data; - - c->avctx = ctx; - ctx->coded_frame = &c->picture; - - if(ctx->pix_fmt != PIX_FMT_GRAY8 && ctx->pix_fmt != PIX_FMT_GRAY16 && ctx->pix_fmt != PIX_FMT_RGB24 && ctx->pix_fmt != PIX_FMT_BGR24){ - av_log(ctx, AV_LOG_ERROR, "Only grayscale and RGB24/BGR24 images are supported\n"); - return -1; - } - return 0; -} - -AVCodec jpegls_encoder = { //FIXME avoid MPV_* lossless jpeg shouldnt need them - "jpegls", - CODEC_TYPE_VIDEO, - CODEC_ID_JPEGLS, - sizeof(JpeglsContext), - encode_init_ls, - encode_picture_ls, - NULL, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_RGB24, PIX_FMT_GRAY8, PIX_FMT_GRAY16, -1}, -}; -#endif diff --git a/contrib/ffmpeg/libavcodec/jpegls.c b/contrib/ffmpeg/libavcodec/jpegls.c new file mode 100644 index 000000000..8a6f5065c --- /dev/null +++ b/contrib/ffmpeg/libavcodec/jpegls.c @@ -0,0 +1,96 @@ +/* + * JPEG-LS common code + * Copyright (c) 2003 Michael Niedermayer + * 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 + */ + +/** + * @file jpegls.c + * JPEG-LS common code. + */ + +#include "jpegls.h" + +const uint8_t ff_log2_run[32]={ + 0, 0, 0, 0, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9,10,11,12,13,14,15 +}; + +void ff_jpegls_init_state(JLSState *state){ + int i; + + state->twonear = state->near * 2 + 1; + state->range = ((state->maxval + state->twonear - 1) / state->twonear) + 1; + + // QBPP = ceil(log2(RANGE)) + for(state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++); + + if(state->bpp < 8) + state->limit = 16 + 2 * state->bpp - state->qbpp; + else + state->limit = (4 * state->bpp) - state->qbpp; + + for(i = 0; i < 367; i++) { + state->A[i] = FFMAX((state->range + 32) >> 6, 2); + state->N[i] = 1; + } + +} + +/** + * Custom value clipping function used in T1, T2, T3 calculation + */ +static inline int iso_clip(int v, int vmin, int vmax){ + if(v > vmax || v < vmin) return vmin; + else return v; +} + +void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all){ + const int basic_t1= 3; + const int basic_t2= 7; + const int basic_t3= 21; + int factor; + + if(s->maxval==0 || reset_all) s->maxval= (1 << s->bpp) - 1; + + if(s->maxval >=128){ + factor= (FFMIN(s->maxval, 4095) + 128)>>8; + + if(s->T1==0 || reset_all) + s->T1= iso_clip(factor*(basic_t1-2) + 2 + 3*s->near, s->near+1, s->maxval); + if(s->T2==0 || reset_all) + s->T2= iso_clip(factor*(basic_t2-3) + 3 + 5*s->near, s->T1, s->maxval); + if(s->T3==0 || reset_all) + s->T3= iso_clip(factor*(basic_t3-4) + 4 + 7*s->near, s->T2, s->maxval); + }else{ + factor= 256 / (s->maxval + 1); + + if(s->T1==0 || reset_all) + s->T1= iso_clip(FFMAX(2, basic_t1/factor + 3*s->near), s->near+1, s->maxval); + if(s->T2==0 || reset_all) + s->T2= iso_clip(FFMAX(3, basic_t2/factor + 5*s->near), s->T1, s->maxval); + if(s->T3==0 || reset_all) + s->T3= iso_clip(FFMAX(4, basic_t3/factor + 6*s->near), s->T2, s->maxval); + } + + if(s->reset==0 || reset_all) s->reset= 64; +// av_log(NULL, AV_LOG_DEBUG, "[JPEG-LS RESET] T=%i,%i,%i\n", s->T1, s->T2, s->T3); +} diff --git a/contrib/ffmpeg/libavcodec/jpegls.h b/contrib/ffmpeg/libavcodec/jpegls.h new file mode 100644 index 000000000..792d2be3b --- /dev/null +++ b/contrib/ffmpeg/libavcodec/jpegls.h @@ -0,0 +1,111 @@ +/* + * JPEG-LS common code + * Copyright (c) 2003 Michael Niedermayer + * 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 + */ + +/** + * @file jpegls.h + * JPEG-LS common code. + */ + +#ifndef FFMPEG_JPEGLS_H +#define FFMPEG_JPEGLS_H + +#include "avcodec.h" + +typedef struct JpeglsContext{ + AVCodecContext *avctx; + AVFrame picture; +}JpeglsContext; + +typedef struct JLSState{ + int T1, T2, T3; + int A[367], B[367], C[365], N[367]; + int limit, reset, bpp, qbpp, maxval, range; + int near, twonear; + int run_index[3]; +}JLSState; + +extern const uint8_t ff_log2_run[32]; + +/** + * Calculate initial JPEG-LS parameters + */ +void ff_jpegls_init_state(JLSState *state); + +/** + * Calculate quantized gradient value, used for context determination + */ +static inline int ff_jpegls_quantize(JLSState *s, int v){ //FIXME optimize + if(v==0) return 0; + if(v < 0){ + if(v <= -s->T3) return -4; + if(v <= -s->T2) return -3; + if(v <= -s->T1) return -2; + if(v < -s->near) return -1; + return 0; + }else{ + if(v <= s->near) return 0; + if(v < s->T1) return 1; + if(v < s->T2) return 2; + if(v < s->T3) return 3; + return 4; + } +} + +/** + * Calculate JPEG-LS codec values + */ +void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all); + + +static inline void ff_jpegls_downscale_state(JLSState *state, int Q){ + if(state->N[Q] == state->reset){ + state->A[Q] >>=1; + state->B[Q] >>=1; + state->N[Q] >>=1; + } + state->N[Q]++; +} + +static inline int ff_jpegls_update_state_regular(JLSState *state, int Q, int err){ + state->A[Q] += FFABS(err); + err *= state->twonear; + state->B[Q] += err; + + ff_jpegls_downscale_state(state, Q); + + if(state->B[Q] <= -state->N[Q]) { + state->B[Q]= FFMAX(state->B[Q] + state->N[Q], 1-state->N[Q]); + if(state->C[Q] > -128) + state->C[Q]--; + }else if(state->B[Q] > 0){ + state->B[Q]= FFMIN(state->B[Q] - state->N[Q], 0); + if(state->C[Q] < 127) + state->C[Q]++; + } + + return err; +} + +#define R(a, i ) (bits == 8 ? ((uint8_t*)(a))[i] : ((uint16_t*)(a))[i] ) +#define W(a, i, v) (bits == 8 ? (((uint8_t*)(a))[i]=v) : (((uint16_t*)(a))[i]=v)) + +#endif /* FFMPEG_JPEGLS_H */ diff --git a/contrib/ffmpeg/libavcodec/jpeglsdec.c b/contrib/ffmpeg/libavcodec/jpeglsdec.c new file mode 100644 index 000000000..ac40903da --- /dev/null +++ b/contrib/ffmpeg/libavcodec/jpeglsdec.c @@ -0,0 +1,375 @@ +/* + * JPEG-LS decoder + * Copyright (c) 2003 Michael Niedermayer + * 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 + */ + +/** + * @file jpeglsdec.c + * JPEG-LS decoder. + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "golomb.h" +#include "mjpeg.h" +#include "mjpegdec.h" +#include "jpegls.h" +#include "jpeglsdec.h" + + +/* +* Uncomment this to significantly speed up decoding of broken JPEG-LS +* (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit. +* +* There is no Golomb code with length >= 32 bits possible, so check and +* avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow +* on this errors. +*/ +//#define JLS_BROKEN + + +/** + * Decode LSE block with initialization parameters + */ +int ff_jpegls_decode_lse(MJpegDecodeContext *s) +{ + int len, id; + + /* XXX: verify len field validity */ + len = get_bits(&s->gb, 16); + id = get_bits(&s->gb, 8); + + switch(id){ + case 1: + s->maxval= get_bits(&s->gb, 16); + s->t1= get_bits(&s->gb, 16); + s->t2= get_bits(&s->gb, 16); + s->t3= get_bits(&s->gb, 16); + s->reset= get_bits(&s->gb, 16); + +// ff_jpegls_reset_coding_parameters(s, 0); + //FIXME quant table? + break; + case 2: + case 3: + av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n"); + return -1; + case 4: + av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n"); + return -1; + default: + av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id); + return -1; + } +// av_log(s->avctx, AV_LOG_DEBUG, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3); + + return 0; +} + +/** + * Get context-dependent Golomb code, decode it and update context + */ +static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q){ + int k, ret; + + for(k = 0; (state->N[Q] << k) < state->A[Q]; k++); + +#ifdef JLS_BROKEN + if(!show_bits_long(gb, 32))return -1; +#endif + ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp); + + /* decode mapped error */ + if(ret & 1) + ret = -((ret + 1) >> 1); + else + ret >>= 1; + + /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */ + if(!state->near && !k && (2 * state->B[Q] <= -state->N[Q])) + ret = -(ret + 1); + + ret= ff_jpegls_update_state_regular(state, Q, ret); + + return ret; +} + +/** + * Get Golomb code, decode it and update state for run termination + */ +static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RItype, int limit_add){ + int k, ret, temp, map; + int Q = 365 + RItype; + + temp= state->A[Q]; + if(RItype) + temp += state->N[Q] >> 1; + + for(k = 0; (state->N[Q] << k) < temp; k++); + +#ifdef JLS_BROKEN + if(!show_bits_long(gb, 32))return -1; +#endif + ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp); + + /* decode mapped error */ + map = 0; + if(!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q])) + map = 1; + ret += RItype + map; + + if(ret & 1){ + ret = map - ((ret + 1) >> 1); + state->B[Q]++; + } else { + ret = ret >> 1; + } + + /* update state */ + state->A[Q] += FFABS(ret) - RItype; + ret *= state->twonear; + ff_jpegls_downscale_state(state, Q); + + return ret; +} + +/** + * Decode one line of image + */ +static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *last, void *dst, int last2, int w, int stride, int comp, int bits){ + int i, x = 0; + int Ra, Rb, Rc, Rd; + int D0, D1, D2; + + while(x < w) { + int err, pred; + + /* compute gradients */ + Ra = x ? R(dst, x - stride) : R(last, x); + Rb = R(last, x); + Rc = x ? R(last, x - stride) : last2; + Rd = (x >= w - stride) ? R(last, x) : R(last, x + stride); + D0 = Rd - Rb; + D1 = Rb - Rc; + D2 = Rc - Ra; + /* run mode */ + if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) { + int r; + int RItype; + + /* decode full runs while available */ + while(get_bits1(&s->gb)) { + int r; + r = 1 << ff_log2_run[state->run_index[comp]]; + if(x + r * stride > w) { + r = (w - x) / stride; + } + for(i = 0; i < r; i++) { + W(dst, x, Ra); + x += stride; + } + /* if EOL reached, we stop decoding */ + if(r != (1 << ff_log2_run[state->run_index[comp]])) + return; + if(state->run_index[comp] < 31) + state->run_index[comp]++; + if(x + stride > w) + return; + } + /* decode aborted run */ + r = ff_log2_run[state->run_index[comp]]; + if(r) + r = get_bits_long(&s->gb, r); + for(i = 0; i < r; i++) { + W(dst, x, Ra); + x += stride; + } + + /* decode run termination value */ + Rb = R(last, x); + RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0; + err = ls_get_code_runterm(&s->gb, state, RItype, ff_log2_run[state->run_index[comp]]); + if(state->run_index[comp]) + state->run_index[comp]--; + + if(state->near && RItype){ + pred = Ra + err; + } else { + if(Rb < Ra) + pred = Rb - err; + else + pred = Rb + err; + } + } else { /* regular mode */ + int context, sign; + + context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2); + pred = mid_pred(Ra, Ra + Rb - Rc, Rb); + + if(context < 0){ + context = -context; + sign = 1; + }else{ + sign = 0; + } + + if(sign){ + pred = av_clip(pred - state->C[context], 0, state->maxval); + err = -ls_get_code_regular(&s->gb, state, context); + } else { + pred = av_clip(pred + state->C[context], 0, state->maxval); + err = ls_get_code_regular(&s->gb, state, context); + } + + /* we have to do something more for near-lossless coding */ + pred += err; + } + if(state->near){ + if(pred < -state->near) + pred += state->range * state->twonear; + else if(pred > state->maxval + state->near) + pred -= state->range * state->twonear; + pred = av_clip(pred, 0, state->maxval); + } + + pred &= state->maxval; + W(dst, x, pred); + x += stride; + } +} + +int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){ + int i, t = 0; + uint8_t *zero, *last, *cur; + JLSState *state; + int off = 0, stride = 1, width, shift; + + zero = av_mallocz(s->picture.linesize[0]); + last = zero; + cur = s->picture.data[0]; + + state = av_mallocz(sizeof(JLSState)); + /* initialize JPEG-LS state from JPEG parameters */ + state->near = near; + state->bpp = (s->bits < 2) ? 2 : s->bits; + state->maxval = s->maxval; + state->T1 = s->t1; + state->T2 = s->t2; + state->T3 = s->t3; + state->reset = s->reset; + ff_jpegls_reset_coding_parameters(state, 0); + ff_jpegls_init_state(state); + + if(s->bits <= 8) + shift = point_transform + (8 - s->bits); + else + shift = point_transform + (16 - s->bits); + +// av_log(s->avctx, AV_LOG_DEBUG, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",s->width,s->height,state->near,state->maxval,state->T1,state->T2,state->T3,state->reset,state->limit,state->qbpp, state->range); +// av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n", ilv, point_transform, s->bits, s->cur_scan); + if(ilv == 0) { /* separate planes */ + off = s->cur_scan - 1; + stride = (s->nb_components > 1) ? 3 : 1; + width = s->width * stride; + cur += off; + for(i = 0; i < s->height; i++) { + if(s->bits <= 8){ + ls_decode_line(state, s, last, cur, t, width, stride, off, 8); + t = last[0]; + }else{ + ls_decode_line(state, s, last, cur, t, width, stride, off, 16); + t = *((uint16_t*)last); + } + last = cur; + cur += s->picture.linesize[0]; + + if (s->restart_interval && !--s->restart_count) { + align_get_bits(&s->gb); + skip_bits(&s->gb, 16); /* skip RSTn */ + } + } + } else if(ilv == 1) { /* line interleaving */ + int j; + int Rc[3] = {0, 0, 0}; + memset(cur, 0, s->picture.linesize[0]); + width = s->width * 3; + for(i = 0; i < s->height; i++) { + for(j = 0; j < 3; j++) { + ls_decode_line(state, s, last + j, cur + j, Rc[j], width, 3, j, 8); + Rc[j] = last[j]; + + if (s->restart_interval && !--s->restart_count) { + align_get_bits(&s->gb); + skip_bits(&s->gb, 16); /* skip RSTn */ + } + } + last = cur; + cur += s->picture.linesize[0]; + } + } else if(ilv == 2) { /* sample interleaving */ + av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n"); + av_free(state); + av_free(zero); + return -1; + } + + if(shift){ /* we need to do point transform or normalize samples */ + int x, w; + + w = s->width * s->nb_components; + + if(s->bits <= 8){ + uint8_t *src = s->picture.data[0]; + + for(i = 0; i < s->height; i++){ + for(x = off; x < w; x+= stride){ + src[x] <<= shift; + } + src += s->picture.linesize[0]; + } + }else{ + uint16_t *src = (uint16_t*) s->picture.data[0]; + + for(i = 0; i < s->height; i++){ + for(x = 0; x < w; x++){ + src[x] <<= shift; + } + src += s->picture.linesize[0]/2; + } + } + } + av_free(state); + av_free(zero); + + return 0; +} + + +AVCodec jpegls_decoder = { + "jpegls", + CODEC_TYPE_VIDEO, + CODEC_ID_JPEGLS, + sizeof(MJpegDecodeContext), + ff_mjpeg_decode_init, + NULL, + ff_mjpeg_decode_end, + ff_mjpeg_decode_frame, + CODEC_CAP_DR1, +}; diff --git a/contrib/ffmpeg/libavcodec/jpeglsdec.h b/contrib/ffmpeg/libavcodec/jpeglsdec.h new file mode 100644 index 000000000..362a0feb5 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/jpeglsdec.h @@ -0,0 +1,41 @@ +/* + * JPEG-LS decoder + * Copyright (c) 2003 Michael Niedermayer + * 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 + */ + +/** + * @file jpeglsdec.h + * JPEG-LS decoder. + */ + +#ifndef FFMPEG_JPEGLSDEC_H +#define FFMPEG_JPEGLSDEC_H + +#include "mjpeg.h" +#include "mjpegdec.h" + +/** + * Decode LSE block with initialization parameters + */ +int ff_jpegls_decode_lse(MJpegDecodeContext *s); + +int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv); + +#endif /* FFMPEG_JPEGLSDEC_H */ diff --git a/contrib/ffmpeg/libavcodec/jpeglsenc.c b/contrib/ffmpeg/libavcodec/jpeglsenc.c new file mode 100644 index 000000000..a759a7048 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/jpeglsenc.c @@ -0,0 +1,393 @@ +/* + * JPEG-LS encoder + * Copyright (c) 2003 Michael Niedermayer + * 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 + */ + +/** + * @file jpeglsenc.c + * JPEG-LS encoder. + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "golomb.h" +#include "dsputil.h" +#include "mjpeg.h" +#include "jpegls.h" + + +/** + * Encode error from regular symbol + */ +static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q, int err){ + int k; + int val; + int map; + + for(k = 0; (state->N[Q] << k) < state->A[Q]; k++); + + map = !state->near && !k && (2 * state->B[Q] <= -state->N[Q]); + + if(err < 0) + err += state->range; + if(err >= ((state->range + 1) >> 1)) { + err -= state->range; + val = 2 * FFABS(err) - 1 - map; + } else + val = 2 * err + map; + + set_ur_golomb_jpegls(pb, val, k, state->limit, state->qbpp); + + ff_jpegls_update_state_regular(state, Q, err); +} + +/** + * Encode error from run termination + */ +static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RItype, int err, int limit_add){ + int k; + int val, map; + int Q = 365 + RItype; + int temp; + + temp = state->A[Q]; + if(RItype) + temp += state->N[Q] >> 1; + for(k = 0; (state->N[Q] << k) < temp; k++); + map = 0; + if(!k && err && (2 * state->B[Q] < state->N[Q])) + map = 1; + + if(err < 0) + val = - (2 * err) - 1 - RItype + map; + else + val = 2 * err - RItype - map; + set_ur_golomb_jpegls(pb, val, k, state->limit - limit_add - 1, state->qbpp); + + if(err < 0) + state->B[Q]++; + state->A[Q] += (val + 1 - RItype) >> 1; + + ff_jpegls_downscale_state(state, Q); +} + +/** + * Encode run value as specified by JPEG-LS standard + */ +static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, int comp, int trail){ + while(run >= (1 << ff_log2_run[state->run_index[comp]])){ + put_bits(pb, 1, 1); + run -= 1 << ff_log2_run[state->run_index[comp]]; + if(state->run_index[comp] < 31) + state->run_index[comp]++; + } + /* if hit EOL, encode another full run, else encode aborted run */ + if(!trail && run) { + put_bits(pb, 1, 1); + }else if(trail){ + put_bits(pb, 1, 0); + if(ff_log2_run[state->run_index[comp]]) + put_bits(pb, ff_log2_run[state->run_index[comp]], run); + } +} + +/** + * Encode one line of image + */ +static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last, void *cur, int last2, int w, int stride, int comp, int bits){ + int x = 0; + int Ra, Rb, Rc, Rd; + int D0, D1, D2; + + while(x < w) { + int err, pred, sign; + + /* compute gradients */ + Ra = x ? R(cur, x - stride) : R(last, x); + Rb = R(last, x); + Rc = x ? R(last, x - stride) : last2; + Rd = (x >= w - stride) ? R(last, x) : R(last, x + stride); + D0 = Rd - Rb; + D1 = Rb - Rc; + D2 = Rc - Ra; + + /* run mode */ + if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) { + int RUNval, RItype, run; + + run = 0; + RUNval = Ra; + while(x < w && (FFABS(R(cur, x) - RUNval) <= state->near)){ + run++; + W(cur, x, Ra); + x += stride; + } + ls_encode_run(state, pb, run, comp, x < w); + if(x >= w) + return; + Rb = R(last, x); + RItype = (FFABS(Ra - Rb) <= state->near); + pred = RItype ? Ra : Rb; + err = R(cur, x) - pred; + + if(!RItype && Ra > Rb) + err = -err; + + if(state->near){ + if(err > 0) + err = (state->near + err) / state->twonear; + else + err = -(state->near - err) / state->twonear; + + if(RItype || (Rb >= Ra)) + Ra = av_clip(pred + err * state->twonear, 0, state->maxval); + else + Ra = av_clip(pred - err * state->twonear, 0, state->maxval); + W(cur, x, Ra); + } + if(err < 0) + err += state->range; + if(err >= ((state->range + 1) >> 1)) + err -= state->range; + + ls_encode_runterm(state, pb, RItype, err, ff_log2_run[state->run_index[comp]]); + + if(state->run_index[comp] > 0) + state->run_index[comp]--; + } else { /* regular mode */ + int context; + + context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2); + pred = mid_pred(Ra, Ra + Rb - Rc, Rb); + + if(context < 0){ + context = -context; + sign = 1; + pred = av_clip(pred - state->C[context], 0, state->maxval); + err = pred - R(cur, x); + }else{ + sign = 0; + pred = av_clip(pred + state->C[context], 0, state->maxval); + err = R(cur, x) - pred; + } + + if(state->near){ + if(err > 0) + err = (state->near + err) / state->twonear; + else + err = -(state->near - err) / state->twonear; + if(!sign) + Ra = av_clip(pred + err * state->twonear, 0, state->maxval); + else + Ra = av_clip(pred - err * state->twonear, 0, state->maxval); + W(cur, x, Ra); + } + + ls_encode_regular(state, pb, context, err); + } + x += stride; + } +} + +static void ls_store_lse(JLSState *state, PutBitContext *pb){ + /* Test if we have default params and don't need to store LSE */ + JLSState state2; + memset(&state2, 0, sizeof(JLSState)); + state2.bpp = state->bpp; + state2.near = state->near; + ff_jpegls_reset_coding_parameters(&state2, 1); + if(state->T1 == state2.T1 && state->T2 == state2.T2 && state->T3 == state2.T3 && state->reset == state2.reset) + return; + /* store LSE type 1 */ + put_marker(pb, LSE); + put_bits(pb, 16, 13); + put_bits(pb, 8, 1); + put_bits(pb, 16, state->maxval); + put_bits(pb, 16, state->T1); + put_bits(pb, 16, state->T2); + put_bits(pb, 16, state->T3); + put_bits(pb, 16, state->reset); +} + +static int encode_picture_ls(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + JpeglsContext * const s = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p= (AVFrame*)&s->picture; + const int near = avctx->prediction_method; + PutBitContext pb, pb2; + GetBitContext gb; + uint8_t *buf2, *zero, *cur, *last; + JLSState *state; + int i, size; + int comps; + + buf2 = av_malloc(buf_size); + + init_put_bits(&pb, buf, buf_size); + init_put_bits(&pb2, buf2, buf_size); + + *p = *pict; + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + + if(avctx->pix_fmt == PIX_FMT_GRAY8 || avctx->pix_fmt == PIX_FMT_GRAY16) + comps = 1; + else + comps = 3; + + /* write our own JPEG header, can't use mjpeg_picture_header */ + put_marker(&pb, SOI); + put_marker(&pb, SOF48); + put_bits(&pb, 16, 8 + comps * 3); // header size depends on components + put_bits(&pb, 8, (avctx->pix_fmt == PIX_FMT_GRAY16) ? 16 : 8); // bpp + put_bits(&pb, 16, avctx->height); + put_bits(&pb, 16, avctx->width); + put_bits(&pb, 8, comps); // components + for(i = 1; i <= comps; i++) { + put_bits(&pb, 8, i); // component ID + put_bits(&pb, 8, 0x11); // subsampling: none + put_bits(&pb, 8, 0); // Tiq, used by JPEG-LS ext + } + + put_marker(&pb, SOS); + put_bits(&pb, 16, 6 + comps * 2); + put_bits(&pb, 8, comps); + for(i = 1; i <= comps; i++) { + put_bits(&pb, 8, i); // component ID + put_bits(&pb, 8, 0); // mapping index: none + } + put_bits(&pb, 8, near); + put_bits(&pb, 8, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line + put_bits(&pb, 8, 0); // point transform: none + + state = av_mallocz(sizeof(JLSState)); + /* initialize JPEG-LS state from JPEG parameters */ + state->near = near; + state->bpp = (avctx->pix_fmt == PIX_FMT_GRAY16) ? 16 : 8; + ff_jpegls_reset_coding_parameters(state, 0); + ff_jpegls_init_state(state); + + ls_store_lse(state, &pb); + + zero = av_mallocz(p->linesize[0]); + last = zero; + cur = p->data[0]; + if(avctx->pix_fmt == PIX_FMT_GRAY8){ + int t = 0; + + for(i = 0; i < avctx->height; i++) { + ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 8); + t = last[0]; + last = cur; + cur += p->linesize[0]; + } + }else if(avctx->pix_fmt == PIX_FMT_GRAY16){ + int t = 0; + + for(i = 0; i < avctx->height; i++) { + ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16); + t = *((uint16_t*)last); + last = cur; + cur += p->linesize[0]; + } + }else if(avctx->pix_fmt == PIX_FMT_RGB24){ + int j, width; + int Rc[3] = {0, 0, 0}; + + width = avctx->width * 3; + for(i = 0; i < avctx->height; i++) { + for(j = 0; j < 3; j++) { + ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8); + Rc[j] = last[j]; + } + last = cur; + cur += s->picture.linesize[0]; + } + }else if(avctx->pix_fmt == PIX_FMT_BGR24){ + int j, width; + int Rc[3] = {0, 0, 0}; + + width = avctx->width * 3; + for(i = 0; i < avctx->height; i++) { + for(j = 2; j >= 0; j--) { + ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8); + Rc[j] = last[j]; + } + last = cur; + cur += s->picture.linesize[0]; + } + } + + av_free(zero); + av_free(state); + + // the specification says that after doing 0xff escaping unused bits in the + // last byte must be set to 0, so just append 7 "optional" zero-bits to + // avoid special-casing. + put_bits(&pb2, 7, 0); + size = put_bits_count(&pb2); + flush_put_bits(&pb2); + /* do escape coding */ + init_get_bits(&gb, buf2, size); + size -= 7; + while(get_bits_count(&gb) < size){ + int v; + v = get_bits(&gb, 8); + put_bits(&pb, 8, v); + if(v == 0xFF){ + v = get_bits(&gb, 7); + put_bits(&pb, 8, v); + } + } + align_put_bits(&pb); + av_free(buf2); + + /* End of image */ + put_marker(&pb, EOI); + flush_put_bits(&pb); + + emms_c(); + + return put_bits_count(&pb) >> 3; +} + +static int encode_init_ls(AVCodecContext *ctx) { + JpeglsContext *c = (JpeglsContext*)ctx->priv_data; + + c->avctx = ctx; + ctx->coded_frame = &c->picture; + + if(ctx->pix_fmt != PIX_FMT_GRAY8 && ctx->pix_fmt != PIX_FMT_GRAY16 && ctx->pix_fmt != PIX_FMT_RGB24 && ctx->pix_fmt != PIX_FMT_BGR24){ + av_log(ctx, AV_LOG_ERROR, "Only grayscale and RGB24/BGR24 images are supported\n"); + return -1; + } + return 0; +} + +AVCodec jpegls_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them + "jpegls", + CODEC_TYPE_VIDEO, + CODEC_ID_JPEGLS, + sizeof(JpeglsContext), + encode_init_ls, + encode_picture_ls, + NULL, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_RGB24, PIX_FMT_GRAY8, PIX_FMT_GRAY16, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/kmvc.c b/contrib/ffmpeg/libavcodec/kmvc.c index 08de05188..395ca2cb9 100644 --- a/contrib/ffmpeg/libavcodec/kmvc.c +++ b/contrib/ffmpeg/libavcodec/kmvc.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -28,8 +27,8 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" +#include "bytestream.h" #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 @@ -68,7 +67,7 @@ typedef struct BitBuf { } \ } -static void kmvc_decode_intra_8x8(KmvcContext * ctx, uint8_t * src, int w, int h) +static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h) { BitBuf bb; int res, val; @@ -143,7 +142,7 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, uint8_t * src, int w, int h } } -static void kmvc_decode_inter_8x8(KmvcContext * ctx, uint8_t * src, int w, int h) +static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h) { BitBuf bb; int res, val; @@ -225,10 +224,10 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, uint8_t * src, int w, int h } } -static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t * buf, +static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, const uint8_t * buf, int buf_size) { - KmvcContext *const ctx = (KmvcContext *) avctx->priv_data; + KmvcContext *const ctx = avctx->priv_data; uint8_t *out, *src; int i; int header; @@ -250,7 +249,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint if (buf[0] == 127) { buf += 3; for (i = 0; i < 127; i++) { - ctx->pal[i + (header & 0x81)] = (buf[0] << 16) | (buf[1] << 8) | buf[2]; + ctx->pal[i + (header & 0x81)] = AV_RB24(buf); buf += 4; } buf -= 127 * 4 + 3; @@ -275,8 +274,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint ctx->pic.palette_has_changed = 1; // palette starts from index 1 and has 127 entries for (i = 1; i <= ctx->palsize; i++) { - ctx->pal[i] = (buf[0] << 16) | (buf[1] << 8) | buf[2]; - buf += 3; + ctx->pal[i] = bytestream_get_be24(&buf); } } @@ -342,7 +340,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint */ static int decode_init(AVCodecContext * avctx) { - KmvcContext *const c = (KmvcContext *) avctx->priv_data; + KmvcContext *const c = avctx->priv_data; int i; c->avctx = avctx; @@ -394,7 +392,7 @@ static int decode_init(AVCodecContext * avctx) */ static int decode_end(AVCodecContext * avctx) { - KmvcContext *const c = (KmvcContext *) avctx->priv_data; + KmvcContext *const c = avctx->priv_data; av_freep(&c->frm0); av_freep(&c->frm1); diff --git a/contrib/ffmpeg/libavcodec/lcl.c b/contrib/ffmpeg/libavcodec/lcl.c deleted file mode 100644 index b02ea1543..000000000 --- a/contrib/ffmpeg/libavcodec/lcl.c +++ /dev/null @@ -1,928 +0,0 @@ -/* - * LCL (LossLess Codec Library) Codec - * Copyright (c) 2002-2004 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 lcl.c - * LCL (LossLess Codec Library) Video Codec - * Decoder for MSZH and ZLIB codecs - * Experimental encoder for ZLIB RGB24 - * - * Fourcc: MSZH, ZLIB - * - * Original Win32 dll: - * Ver2.23 By Kenji Oshima 2000.09.20 - * avimszh.dll, avizlib.dll - * - * A description of the decoding algorithm can be found here: - * http://www.pcisys.net/~melanson/codecs - * - * Supports: BGR24 (RGB 24bpp) - * - */ - -#include <stdio.h> -#include <stdlib.h> - -#include "common.h" -#include "bitstream.h" -#include "avcodec.h" - -#ifdef CONFIG_ZLIB -#include <zlib.h> -#endif - - -#define BMPTYPE_YUV 1 -#define BMPTYPE_RGB 2 - -#define IMGTYPE_YUV111 0 -#define IMGTYPE_YUV422 1 -#define IMGTYPE_RGB24 2 -#define IMGTYPE_YUV411 3 -#define IMGTYPE_YUV211 4 -#define IMGTYPE_YUV420 5 - -#define COMP_MSZH 0 -#define COMP_MSZH_NOCOMP 1 -#define COMP_ZLIB_HISPEED 1 -#define COMP_ZLIB_HICOMP 9 -#define COMP_ZLIB_NORMAL -1 - -#define FLAG_MULTITHREAD 1 -#define FLAG_NULLFRAME 2 -#define FLAG_PNGFILTER 4 -#define FLAGMASK_UNUSED 0xf8 - -#define CODEC_MSZH 1 -#define CODEC_ZLIB 3 - -#define FOURCC_MSZH mmioFOURCC('M','S','Z','H') -#define FOURCC_ZLIB mmioFOURCC('Z','L','I','B') - -/* - * Decoder context - */ -typedef struct LclContext { - - AVCodecContext *avctx; - AVFrame pic; - PutBitContext pb; - - // Image type - int imgtype; - // Compression type - int compression; - // Flags - int flags; - // Decompressed data size - unsigned int decomp_size; - // Decompression buffer - unsigned char* decomp_buf; - // Maximum compressed data size - unsigned int max_comp_size; - // Compression buffer - unsigned char* comp_buf; -#ifdef CONFIG_ZLIB - z_stream zstream; -#endif -} LclContext; - - -/* - * - * Helper functions - * - */ -static inline unsigned char fix (int pix14) -{ - int tmp; - - tmp = (pix14 + 0x80000) >> 20; - if (tmp < 0) - return 0; - if (tmp > 255) - return 255; - return tmp; -} - - - -static inline unsigned char get_b (unsigned char yq, signed char bq) -{ - return fix((yq << 20) + bq * 1858076); -} - - - -static inline unsigned char get_g (unsigned char yq, signed char bq, signed char rq) -{ - return fix((yq << 20) - bq * 360857 - rq * 748830); -} - - - -static inline unsigned char get_r (unsigned char yq, signed char rq) -{ - return fix((yq << 20) + rq * 1470103); -} - - - -static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) -{ - unsigned char *destptr_bak = destptr; - unsigned char *destptr_end = destptr + destsize; - unsigned char mask = 0; - unsigned char maskbit = 0; - unsigned int ofs, cnt; - - while ((srclen > 0) && (destptr < destptr_end)) { - if (maskbit == 0) { - mask = *(srcptr++); - maskbit = 8; - srclen--; - continue; - } - if ((mask & (1 << (--maskbit))) == 0) { - if (destptr + 4 > destptr_end) - break; - *(int*)destptr = *(int*)srcptr; - srclen -= 4; - destptr += 4; - srcptr += 4; - } else { - ofs = *(srcptr++); - cnt = *(srcptr++); - ofs += cnt * 256;; - cnt = ((cnt >> 3) & 0x1f) + 1; - ofs &= 0x7ff; - srclen -= 2; - cnt *= 4; - if (destptr + cnt > destptr_end) { - cnt = destptr_end - destptr; - } - for (; cnt > 0; cnt--) { - *(destptr) = *(destptr - ofs); - destptr++; - } - } - } - - return (destptr - destptr_bak); -} - - - -#ifdef CONFIG_DECODERS -/* - * - * Decode a frame - * - */ -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) -{ - LclContext * const c = (LclContext *)avctx->priv_data; - unsigned char *encoded = (unsigned char *)buf; - unsigned int pixel_ptr; - int row, col; - unsigned char *outptr; - unsigned int width = avctx->width; // Real image width - unsigned int height = avctx->height; // Real image height - unsigned int mszh_dlen; - unsigned char yq, y1q, uq, vq; - int uqvq; - unsigned int mthread_inlen, mthread_outlen; -#ifdef CONFIG_ZLIB - int zret; // Zlib return code -#endif - unsigned int len = buf_size; - - 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; - } - - outptr = c->pic.data[0]; // Output image pointer - - /* Decompress frame */ - switch (avctx->codec_id) { - case CODEC_ID_MSZH: - switch (c->compression) { - case COMP_MSZH: - if (c->flags & FLAG_MULTITHREAD) { - mthread_inlen = *((unsigned int*)encoded); - mthread_outlen = *((unsigned int*)(encoded+4)); - if (mthread_outlen > c->decomp_size) // this should not happen - mthread_outlen = c->decomp_size; - mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size); - if (mthread_outlen != mszh_dlen) { - av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", - mthread_outlen, mszh_dlen); - return -1; - } - mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen, - c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); - if (mthread_outlen != mszh_dlen) { - av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", - mthread_outlen, mszh_dlen); - return -1; - } - encoded = c->decomp_buf; - len = c->decomp_size; - } else { - mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); - if (c->decomp_size != mszh_dlen) { - av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", - c->decomp_size, mszh_dlen); - return -1; - } - encoded = c->decomp_buf; - len = mszh_dlen; - } - break; - case COMP_MSZH_NOCOMP: - break; - default: - av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); - return -1; - } - break; - case CODEC_ID_ZLIB: -#ifdef CONFIG_ZLIB - /* Using the original dll with normal compression (-1) and RGB format - * gives a file with ZLIB fourcc, but frame is really uncompressed. - * To be sure that's true check also frame size */ - if ((c->compression == COMP_ZLIB_NORMAL) && (c->imgtype == IMGTYPE_RGB24) && - (len == width * height * 3)) - break; - zret = inflateReset(&(c->zstream)); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); - return -1; - } - if (c->flags & FLAG_MULTITHREAD) { - mthread_inlen = *((unsigned int*)encoded); - mthread_outlen = *((unsigned int*)(encoded+4)); - if (mthread_outlen > c->decomp_size) - mthread_outlen = c->decomp_size; - c->zstream.next_in = encoded + 8; - c->zstream.avail_in = mthread_inlen; - c->zstream.next_out = c->decomp_buf; - c->zstream.avail_out = c->decomp_size; - zret = inflate(&(c->zstream), Z_FINISH); - if ((zret != Z_OK) && (zret != Z_STREAM_END)) { - av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret); - return -1; - } - if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { - av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n", - mthread_outlen, c->zstream.total_out); - return -1; - } - zret = inflateReset(&(c->zstream)); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret); - return -1; - } - c->zstream.next_in = encoded + 8 + mthread_inlen; - c->zstream.avail_in = len - mthread_inlen; - c->zstream.next_out = c->decomp_buf + mthread_outlen; - c->zstream.avail_out = c->decomp_size - mthread_outlen; - zret = inflate(&(c->zstream), Z_FINISH); - if ((zret != Z_OK) && (zret != Z_STREAM_END)) { - av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret); - return -1; - } - if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { - av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n", - mthread_outlen, c->zstream.total_out); - return -1; - } - } else { - c->zstream.next_in = encoded; - c->zstream.avail_in = len; - c->zstream.next_out = c->decomp_buf; - c->zstream.avail_out = c->decomp_size; - zret = inflate(&(c->zstream), Z_FINISH); - if ((zret != Z_OK) && (zret != Z_STREAM_END)) { - av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); - return -1; - } - if (c->decomp_size != (unsigned int)(c->zstream.total_out)) { - av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", - c->decomp_size, c->zstream.total_out); - return -1; - } - } - encoded = c->decomp_buf; - len = c->decomp_size;; -#else - av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); - return -1; -#endif - break; - default: - av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n"); - return -1; - } - - - /* Apply PNG filter */ - if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) { - switch (c->imgtype) { - case IMGTYPE_YUV111: - case IMGTYPE_RGB24: - for (row = 0; row < height; row++) { - pixel_ptr = row * width * 3; - yq = encoded[pixel_ptr++]; - uqvq = encoded[pixel_ptr++]; - uqvq+=(encoded[pixel_ptr++] << 8); - for (col = 1; col < width; col++) { - encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; - uqvq -= (encoded[pixel_ptr+1] | (encoded[pixel_ptr+2]<<8)); - encoded[pixel_ptr+1] = (uqvq) & 0xff; - encoded[pixel_ptr+2] = ((uqvq)>>8) & 0xff; - pixel_ptr += 3; - } - } - break; - case IMGTYPE_YUV422: - for (row = 0; row < height; row++) { - pixel_ptr = row * width * 2; - yq = uq = vq =0; - for (col = 0; col < width/4; col++) { - encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; - encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; - encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; - encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; - encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; - encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; - encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; - encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; - pixel_ptr += 8; - } - } - break; - case IMGTYPE_YUV411: - for (row = 0; row < height; row++) { - pixel_ptr = row * width / 2 * 3; - yq = uq = vq =0; - for (col = 0; col < width/4; col++) { - encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; - encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; - encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; - encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; - encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; - encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; - pixel_ptr += 6; - } - } - break; - case IMGTYPE_YUV211: - for (row = 0; row < height; row++) { - pixel_ptr = row * width * 2; - yq = uq = vq =0; - for (col = 0; col < width/2; col++) { - encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; - encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; - encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; - encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; - pixel_ptr += 4; - } - } - break; - case IMGTYPE_YUV420: - for (row = 0; row < height/2; row++) { - pixel_ptr = row * width * 3; - yq = y1q = uq = vq =0; - for (col = 0; col < width/2; col++) { - encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; - encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; - encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; - encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; - encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; - encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; - pixel_ptr += 6; - } - } - break; - default: - av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n"); - return -1; - } - } - - /* Convert colorspace */ - switch (c->imgtype) { - case IMGTYPE_YUV111: - for (row = height - 1; row >= 0; row--) { - pixel_ptr = row * c->pic.linesize[0]; - for (col = 0; col < width; col++) { - outptr[pixel_ptr++] = get_b(encoded[0], encoded[1]); - outptr[pixel_ptr++] = get_g(encoded[0], encoded[1], encoded[2]); - outptr[pixel_ptr++] = get_r(encoded[0], encoded[2]); - encoded += 3; - } - } - break; - case IMGTYPE_YUV422: - for (row = height - 1; row >= 0; row--) { - pixel_ptr = row * c->pic.linesize[0]; - for (col = 0; col < width/4; col++) { - outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); - outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[6]); - outptr[pixel_ptr++] = get_r(encoded[0], encoded[6]); - outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); - outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[6]); - outptr[pixel_ptr++] = get_r(encoded[1], encoded[6]); - outptr[pixel_ptr++] = get_b(encoded[2], encoded[5]); - outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]); - outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]); - outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]); - outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]); - outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]); - encoded += 8; - } - } - break; - case IMGTYPE_RGB24: - for (row = height - 1; row >= 0; row--) { - pixel_ptr = row * c->pic.linesize[0]; - for (col = 0; col < width; col++) { - outptr[pixel_ptr++] = encoded[0]; - outptr[pixel_ptr++] = encoded[1]; - outptr[pixel_ptr++] = encoded[2]; - encoded += 3; - } - } - break; - case IMGTYPE_YUV411: - for (row = height - 1; row >= 0; row--) { - pixel_ptr = row * c->pic.linesize[0]; - for (col = 0; col < width/4; col++) { - outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); - outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]); - outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]); - outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); - outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]); - outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]); - outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]); - outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]); - outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]); - outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]); - outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]); - outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]); - encoded += 6; - } - } - break; - case IMGTYPE_YUV211: - for (row = height - 1; row >= 0; row--) { - pixel_ptr = row * c->pic.linesize[0]; - for (col = 0; col < width/2; col++) { - outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]); - outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]); - outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]); - outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]); - outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]); - outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]); - encoded += 4; - } - } - break; - case IMGTYPE_YUV420: - for (row = height / 2 - 1; row >= 0; row--) { - pixel_ptr = 2 * row * c->pic.linesize[0]; - for (col = 0; col < width/2; col++) { - outptr[pixel_ptr] = get_b(encoded[0], encoded[4]); - outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]); - outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]); - outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]); - outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]); - outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]); - outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]); - outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]); - outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]); - outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]); - outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]); - outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]); - pixel_ptr += 6; - encoded += 6; - } - } - break; - default: - av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); - return -1; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; - - /* always report that the buffer was completely consumed */ - return buf_size; -} -#endif - -#ifdef CONFIG_ENCODERS -/* - * - * Encode a frame - * - */ -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - LclContext *c = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p = &c->pic; - int i; - int zret; // Zlib return code - -#ifndef CONFIG_ZLIB - av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled in.\n"); - return -1; -#else - - init_put_bits(&c->pb, buf, buf_size); - - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - if(avctx->pix_fmt != PIX_FMT_BGR24){ - av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); - return -1; - } - - zret = deflateReset(&(c->zstream)); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret); - return -1; - } - c->zstream.next_out = c->comp_buf; - c->zstream.avail_out = c->max_comp_size; - - for(i = avctx->height - 1; i >= 0; i--) { - c->zstream.next_in = p->data[0]+p->linesize[0]*i; - c->zstream.avail_in = avctx->width*3; - zret = deflate(&(c->zstream), Z_NO_FLUSH); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); - return -1; - } - } - zret = deflate(&(c->zstream), Z_FINISH); - if (zret != Z_STREAM_END) { - av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); - return -1; - } - - for (i = 0; i < c->zstream.total_out; i++) - put_bits(&c->pb, 8, c->comp_buf[i]); - flush_put_bits(&c->pb); - - return c->zstream.total_out; -#endif -} -#endif /* CONFIG_ENCODERS */ - -#ifdef CONFIG_DECODERS -/* - * - * Init lcl decoder - * - */ -static int decode_init(AVCodecContext *avctx) -{ - LclContext * const c = (LclContext *)avctx->priv_data; - unsigned int basesize = avctx->width * avctx->height; - unsigned int max_basesize = ((avctx->width + 3) & ~3) * ((avctx->height + 3) & ~3); - unsigned int max_decomp_size; - int zret; // Zlib return code - - c->avctx = avctx; - avctx->has_b_frames = 0; - - c->pic.data[0] = NULL; - -#ifdef CONFIG_ZLIB - // Needed if zlib unused or init aborted before inflateInit - memset(&(c->zstream), 0, sizeof(z_stream)); -#endif - - if (avctx->extradata_size < 8) { - av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); - return 1; - } - - if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { - return 1; - } - - /* Check codec type */ - if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) || - ((avctx->codec_id == CODEC_ID_ZLIB) && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) { - av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); - } - - /* Detect image type */ - switch (c->imgtype = *((char *)avctx->extradata + 4)) { - case IMGTYPE_YUV111: - c->decomp_size = basesize * 3; - max_decomp_size = max_basesize * 3; - av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); - break; - case IMGTYPE_YUV422: - c->decomp_size = basesize * 2; - max_decomp_size = max_basesize * 2; - av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); - break; - case IMGTYPE_RGB24: - c->decomp_size = basesize * 3; - max_decomp_size = max_basesize * 3; - av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); - break; - case IMGTYPE_YUV411: - c->decomp_size = basesize / 2 * 3; - max_decomp_size = max_basesize / 2 * 3; - av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); - break; - case IMGTYPE_YUV211: - c->decomp_size = basesize * 2; - max_decomp_size = max_basesize * 2; - av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); - break; - case IMGTYPE_YUV420: - c->decomp_size = basesize / 2 * 3; - max_decomp_size = max_basesize / 2 * 3; - av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); - return 1; - } - - /* Detect compression method */ - c->compression = *((char *)avctx->extradata + 5); - switch (avctx->codec_id) { - case CODEC_ID_MSZH: - switch (c->compression) { - case COMP_MSZH: - av_log(avctx, AV_LOG_INFO, "Compression enabled.\n"); - break; - case COMP_MSZH_NOCOMP: - c->decomp_size = 0; - av_log(avctx, AV_LOG_INFO, "No compression.\n"); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); - return 1; - } - break; - case CODEC_ID_ZLIB: -#ifdef CONFIG_ZLIB - switch (c->compression) { - case COMP_ZLIB_HISPEED: - av_log(avctx, AV_LOG_INFO, "High speed compression.\n"); - break; - case COMP_ZLIB_HICOMP: - av_log(avctx, AV_LOG_INFO, "High compression.\n"); - break; - case COMP_ZLIB_NORMAL: - av_log(avctx, AV_LOG_INFO, "Normal compression.\n"); - break; - default: - if ((c->compression < Z_NO_COMPRESSION) || (c->compression > Z_BEST_COMPRESSION)) { - av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); - return 1; - } - av_log(avctx, AV_LOG_INFO, "Compression level for ZLIB: (%d).\n", c->compression); - } -#else - av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); - return 1; -#endif - break; - default: - av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); - return 1; - } - - /* Allocate decompression buffer */ - if (c->decomp_size) { - if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; - } - } - - /* Detect flags */ - c->flags = *((char *)avctx->extradata + 6); - if (c->flags & FLAG_MULTITHREAD) - av_log(avctx, AV_LOG_INFO, "Multithread encoder flag set.\n"); - if (c->flags & FLAG_NULLFRAME) - av_log(avctx, AV_LOG_INFO, "Nullframe insertion flag set.\n"); - if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) - av_log(avctx, AV_LOG_INFO, "PNG filter flag set.\n"); - if (c->flags & FLAGMASK_UNUSED) - av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); - - /* If needed init zlib */ - if (avctx->codec_id == CODEC_ID_ZLIB) { -#ifdef CONFIG_ZLIB - c->zstream.zalloc = Z_NULL; - c->zstream.zfree = Z_NULL; - c->zstream.opaque = Z_NULL; - zret = inflateInit(&(c->zstream)); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); - return 1; - } -#else - av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); - return 1; -#endif - } - - avctx->pix_fmt = PIX_FMT_BGR24; - - return 0; -} -#endif /* CONFIG_DECODERS */ - -#ifdef CONFIG_ENCODERS -/* - * - * Init lcl encoder - * - */ -static int encode_init(AVCodecContext *avctx) -{ - LclContext *c = avctx->priv_data; - int zret; // Zlib return code - -#ifndef CONFIG_ZLIB - av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); - return 1; -#else - - c->avctx= avctx; - - assert(avctx->width && avctx->height); - - avctx->extradata= av_mallocz(8); - avctx->coded_frame= &c->pic; - - // Will be user settable someday - c->compression = 6; - c->flags = 0; - - switch(avctx->pix_fmt){ - case PIX_FMT_BGR24: - c->imgtype = IMGTYPE_RGB24; - c->decomp_size = avctx->width * avctx->height * 3; - avctx->bits_per_sample= 24; - break; - default: - av_log(avctx, AV_LOG_ERROR, "Format %d not supported\n", avctx->pix_fmt); - return -1; - } - - ((uint8_t*)avctx->extradata)[0]= 4; - ((uint8_t*)avctx->extradata)[1]= 0; - ((uint8_t*)avctx->extradata)[2]= 0; - ((uint8_t*)avctx->extradata)[3]= 0; - ((uint8_t*)avctx->extradata)[4]= c->imgtype; - ((uint8_t*)avctx->extradata)[5]= c->compression; - ((uint8_t*)avctx->extradata)[6]= c->flags; - ((uint8_t*)avctx->extradata)[7]= CODEC_ZLIB; - c->avctx->extradata_size= 8; - - c->zstream.zalloc = Z_NULL; - c->zstream.zfree = Z_NULL; - c->zstream.opaque = Z_NULL; - zret = deflateInit(&(c->zstream), c->compression); - if (zret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); - return 1; - } - - /* Conservative upper bound taken from zlib v1.2.1 source */ - c->max_comp_size = c->decomp_size + ((c->decomp_size + 7) >> 3) + - ((c->decomp_size + 63) >> 6) + 11; - if ((c->comp_buf = av_malloc(c->max_comp_size)) == NULL) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n"); - return 1; - } - - return 0; -#endif -} -#endif /* CONFIG_ENCODERS */ - - - -#ifdef CONFIG_DECODERS -/* - * - * Uninit lcl decoder - * - */ -static int decode_end(AVCodecContext *avctx) -{ - LclContext * const c = (LclContext *)avctx->priv_data; - - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); -#ifdef CONFIG_ZLIB - inflateEnd(&(c->zstream)); -#endif - - return 0; -} -#endif - -#ifdef CONFIG_ENCODERS -/* - * - * Uninit lcl encoder - * - */ -static int encode_end(AVCodecContext *avctx) -{ - LclContext *c = avctx->priv_data; - - av_freep(&avctx->extradata); - av_freep(&c->comp_buf); -#ifdef CONFIG_ZLIB - deflateEnd(&(c->zstream)); -#endif - - return 0; -} -#endif - -#ifdef CONFIG_MSZH_DECODER -AVCodec mszh_decoder = { - "mszh", - CODEC_TYPE_VIDEO, - CODEC_ID_MSZH, - sizeof(LclContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, -}; -#endif - -#ifdef CONFIG_ZLIB_DECODER -AVCodec zlib_decoder = { - "zlib", - CODEC_TYPE_VIDEO, - CODEC_ID_ZLIB, - sizeof(LclContext), - decode_init, - NULL, - decode_end, - decode_frame, - CODEC_CAP_DR1, -}; -#endif - -#ifdef CONFIG_ENCODERS - -AVCodec zlib_encoder = { - "zlib", - CODEC_TYPE_VIDEO, - CODEC_ID_ZLIB, - sizeof(LclContext), - encode_init, - encode_frame, - encode_end, -}; - -#endif //CONFIG_ENCODERS diff --git a/contrib/ffmpeg/libavcodec/lcl.h b/contrib/ffmpeg/libavcodec/lcl.h new file mode 100644 index 000000000..7d5a76a78 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/lcl.h @@ -0,0 +1,49 @@ +/* + * LCL (LossLess Codec Library) Codec + * Copyright (c) 2002-2004 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 + */ + +#ifndef FFMPEG_LCL_H +#define FFMPEG_LCL_H + +#define BMPTYPE_YUV 1 +#define BMPTYPE_RGB 2 + +#define IMGTYPE_YUV111 0 +#define IMGTYPE_YUV422 1 +#define IMGTYPE_RGB24 2 +#define IMGTYPE_YUV411 3 +#define IMGTYPE_YUV211 4 +#define IMGTYPE_YUV420 5 + +#define COMP_MSZH 0 +#define COMP_MSZH_NOCOMP 1 +#define COMP_ZLIB_HISPEED 1 +#define COMP_ZLIB_HICOMP 9 +#define COMP_ZLIB_NORMAL -1 + +#define FLAG_MULTITHREAD 1 +#define FLAG_NULLFRAME 2 +#define FLAG_PNGFILTER 4 +#define FLAGMASK_UNUSED 0xf8 + +#define CODEC_MSZH 1 +#define CODEC_ZLIB 3 + +#endif /* FFMPEG_LCL_H */ diff --git a/contrib/ffmpeg/libavcodec/lcldec.c b/contrib/ffmpeg/libavcodec/lcldec.c new file mode 100644 index 000000000..4abb0cd41 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/lcldec.c @@ -0,0 +1,715 @@ +/* + * LCL (LossLess Codec Library) Codec + * Copyright (c) 2002-2004 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 lcl.c + * LCL (LossLess Codec Library) Video Codec + * Decoder for MSZH and ZLIB codecs + * Experimental encoder for ZLIB RGB24 + * + * Fourcc: MSZH, ZLIB + * + * Original Win32 dll: + * Ver2.23 By Kenji Oshima 2000.09.20 + * avimszh.dll, avizlib.dll + * + * A description of the decoding algorithm can be found here: + * http://www.pcisys.net/~melanson/codecs + * + * Supports: BGR24 (RGB 24bpp) + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "avcodec.h" +#include "bitstream.h" +#include "lcl.h" + +#ifdef CONFIG_ZLIB +#include <zlib.h> +#endif + +/* + * Decoder context + */ +typedef struct LclDecContext { + AVFrame pic; + + // Image type + int imgtype; + // Compression type + int compression; + // Flags + int flags; + // Decompressed data size + unsigned int decomp_size; + // Decompression buffer + unsigned char* decomp_buf; +#ifdef CONFIG_ZLIB + z_stream zstream; +#endif +} LclDecContext; + + +/* + * + * Helper functions + * + */ +static inline unsigned char fix (int pix14) +{ + int tmp; + + tmp = (pix14 + 0x80000) >> 20; + if (tmp < 0) + return 0; + if (tmp > 255) + return 255; + return tmp; +} + + + +static inline unsigned char get_b (unsigned char yq, signed char bq) +{ + return fix((yq << 20) + bq * 1858076); +} + + + +static inline unsigned char get_g (unsigned char yq, signed char bq, signed char rq) +{ + return fix((yq << 20) - bq * 360857 - rq * 748830); +} + + + +static inline unsigned char get_r (unsigned char yq, signed char rq) +{ + return fix((yq << 20) + rq * 1470103); +} + + + +static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) +{ + unsigned char *destptr_bak = destptr; + unsigned char *destptr_end = destptr + destsize; + unsigned char mask = 0; + unsigned char maskbit = 0; + unsigned int ofs, cnt; + + while ((srclen > 0) && (destptr < destptr_end)) { + if (maskbit == 0) { + mask = *(srcptr++); + maskbit = 8; + srclen--; + continue; + } + if ((mask & (1 << (--maskbit))) == 0) { + if (destptr + 4 > destptr_end) + break; + *(int*)destptr = *(int*)srcptr; + srclen -= 4; + destptr += 4; + srcptr += 4; + } else { + ofs = *(srcptr++); + cnt = *(srcptr++); + ofs += cnt * 256; + cnt = ((cnt >> 3) & 0x1f) + 1; + ofs &= 0x7ff; + srclen -= 2; + cnt *= 4; + if (destptr + cnt > destptr_end) { + cnt = destptr_end - destptr; + } + for (; cnt > 0; cnt--) { + *(destptr) = *(destptr - ofs); + destptr++; + } + } + } + + return (destptr - destptr_bak); +} + + + +/* + * + * Decode a frame + * + */ +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) +{ + LclDecContext * const c = avctx->priv_data; + unsigned char *encoded = (unsigned char *)buf; + unsigned int pixel_ptr; + int row, col; + unsigned char *outptr; + unsigned int width = avctx->width; // Real image width + unsigned int height = avctx->height; // Real image height + unsigned int mszh_dlen; + unsigned char yq, y1q, uq, vq; + int uqvq; + unsigned int mthread_inlen, mthread_outlen; +#ifdef CONFIG_ZLIB + int zret; // Zlib return code +#endif + unsigned int len = buf_size; + + 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; + } + + outptr = c->pic.data[0]; // Output image pointer + + /* Decompress frame */ + switch (avctx->codec_id) { + case CODEC_ID_MSZH: + switch (c->compression) { + case COMP_MSZH: + if (c->flags & FLAG_MULTITHREAD) { + mthread_inlen = *((unsigned int*)encoded); + mthread_outlen = *((unsigned int*)(encoded+4)); + if (mthread_outlen > c->decomp_size) // this should not happen + mthread_outlen = c->decomp_size; + mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size); + if (mthread_outlen != mszh_dlen) { + av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", + mthread_outlen, mszh_dlen); + return -1; + } + mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen, + c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); + if (mthread_outlen != mszh_dlen) { + av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", + mthread_outlen, mszh_dlen); + return -1; + } + encoded = c->decomp_buf; + len = c->decomp_size; + } else { + mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); + if (c->decomp_size != mszh_dlen) { + av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", + c->decomp_size, mszh_dlen); + return -1; + } + encoded = c->decomp_buf; + len = mszh_dlen; + } + break; + case COMP_MSZH_NOCOMP: + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); + return -1; + } + break; + case CODEC_ID_ZLIB: +#ifdef CONFIG_ZLIB + /* Using the original dll with normal compression (-1) and RGB format + * gives a file with ZLIB fourcc, but frame is really uncompressed. + * To be sure that's true check also frame size */ + if ((c->compression == COMP_ZLIB_NORMAL) && (c->imgtype == IMGTYPE_RGB24) && + (len == width * height * 3)) + break; + zret = inflateReset(&(c->zstream)); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); + return -1; + } + if (c->flags & FLAG_MULTITHREAD) { + mthread_inlen = *((unsigned int*)encoded); + mthread_outlen = *((unsigned int*)(encoded+4)); + if (mthread_outlen > c->decomp_size) + mthread_outlen = c->decomp_size; + c->zstream.next_in = encoded + 8; + c->zstream.avail_in = mthread_inlen; + c->zstream.next_out = c->decomp_buf; + c->zstream.avail_out = c->decomp_size; + zret = inflate(&(c->zstream), Z_FINISH); + if ((zret != Z_OK) && (zret != Z_STREAM_END)) { + av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret); + return -1; + } + if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { + av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n", + mthread_outlen, c->zstream.total_out); + return -1; + } + zret = inflateReset(&(c->zstream)); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret); + return -1; + } + c->zstream.next_in = encoded + 8 + mthread_inlen; + c->zstream.avail_in = len - mthread_inlen; + c->zstream.next_out = c->decomp_buf + mthread_outlen; + c->zstream.avail_out = c->decomp_size - mthread_outlen; + zret = inflate(&(c->zstream), Z_FINISH); + if ((zret != Z_OK) && (zret != Z_STREAM_END)) { + av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret); + return -1; + } + if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { + av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n", + mthread_outlen, c->zstream.total_out); + return -1; + } + } else { + c->zstream.next_in = encoded; + c->zstream.avail_in = len; + c->zstream.next_out = c->decomp_buf; + c->zstream.avail_out = c->decomp_size; + zret = inflate(&(c->zstream), Z_FINISH); + if ((zret != Z_OK) && (zret != Z_STREAM_END)) { + av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); + return -1; + } + if (c->decomp_size != (unsigned int)(c->zstream.total_out)) { + av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", + c->decomp_size, c->zstream.total_out); + return -1; + } + } + encoded = c->decomp_buf; + len = c->decomp_size; +#else + av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); + return -1; +#endif + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n"); + return -1; + } + + + /* Apply PNG filter */ + if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) { + switch (c->imgtype) { + case IMGTYPE_YUV111: + case IMGTYPE_RGB24: + for (row = 0; row < height; row++) { + pixel_ptr = row * width * 3; + yq = encoded[pixel_ptr++]; + uqvq = AV_RL16(encoded+pixel_ptr); + pixel_ptr += 2; + for (col = 1; col < width; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + uqvq -= AV_RL16(encoded+pixel_ptr+1); + AV_WL16(encoded+pixel_ptr+1, uqvq); + pixel_ptr += 3; + } + } + break; + case IMGTYPE_YUV422: + for (row = 0; row < height; row++) { + pixel_ptr = row * width * 2; + yq = uq = vq =0; + for (col = 0; col < width/4; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; + encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; + encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; + encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; + encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; + encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; + encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; + pixel_ptr += 8; + } + } + break; + case IMGTYPE_YUV411: + for (row = 0; row < height; row++) { + pixel_ptr = row * width / 2 * 3; + yq = uq = vq =0; + for (col = 0; col < width/4; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; + encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; + encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; + encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; + encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; + pixel_ptr += 6; + } + } + break; + case IMGTYPE_YUV211: + for (row = 0; row < height; row++) { + pixel_ptr = row * width * 2; + yq = uq = vq =0; + for (col = 0; col < width/2; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; + encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; + encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; + pixel_ptr += 4; + } + } + break; + case IMGTYPE_YUV420: + for (row = 0; row < height/2; row++) { + pixel_ptr = row * width * 3; + yq = y1q = uq = vq =0; + for (col = 0; col < width/2; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; + encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; + encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; + encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; + encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; + pixel_ptr += 6; + } + } + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n"); + return -1; + } + } + + /* Convert colorspace */ + switch (c->imgtype) { + case IMGTYPE_YUV111: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width; col++) { + outptr[pixel_ptr++] = get_b(encoded[0], encoded[1]); + outptr[pixel_ptr++] = get_g(encoded[0], encoded[1], encoded[2]); + outptr[pixel_ptr++] = get_r(encoded[0], encoded[2]); + encoded += 3; + } + } + break; + case IMGTYPE_YUV422: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width/4; col++) { + outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[6]); + outptr[pixel_ptr++] = get_r(encoded[0], encoded[6]); + outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[6]); + outptr[pixel_ptr++] = get_r(encoded[1], encoded[6]); + outptr[pixel_ptr++] = get_b(encoded[2], encoded[5]); + outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]); + outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]); + outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]); + outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]); + outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]); + encoded += 8; + } + } + break; + case IMGTYPE_RGB24: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width; col++) { + outptr[pixel_ptr++] = encoded[0]; + outptr[pixel_ptr++] = encoded[1]; + outptr[pixel_ptr++] = encoded[2]; + encoded += 3; + } + } + break; + case IMGTYPE_YUV411: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width/4; col++) { + outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]); + outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]); + outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]); + outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]); + outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]); + outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]); + outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]); + outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]); + encoded += 6; + } + } + break; + case IMGTYPE_YUV211: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width/2; col++) { + outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]); + outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]); + outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]); + outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]); + outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]); + outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]); + encoded += 4; + } + } + break; + case IMGTYPE_YUV420: + for (row = height / 2 - 1; row >= 0; row--) { + pixel_ptr = 2 * row * c->pic.linesize[0]; + for (col = 0; col < width/2; col++) { + outptr[pixel_ptr] = get_b(encoded[0], encoded[4]); + outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]); + outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]); + outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]); + outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]); + outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]); + outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]); + outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]); + outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]); + outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]); + outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]); + outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]); + pixel_ptr += 6; + encoded += 6; + } + } + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); + return -1; + } + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = c->pic; + + /* always report that the buffer was completely consumed */ + return buf_size; +} + +/* + * + * Init lcl decoder + * + */ +static int decode_init(AVCodecContext *avctx) +{ + LclDecContext * const c = avctx->priv_data; + unsigned int basesize = avctx->width * avctx->height; + unsigned int max_basesize = ((avctx->width + 3) & ~3) * ((avctx->height + 3) & ~3); + unsigned int max_decomp_size; + int zret; // Zlib return code + + c->pic.data[0] = NULL; + +#ifdef CONFIG_ZLIB + // Needed if zlib unused or init aborted before inflateInit + memset(&(c->zstream), 0, sizeof(z_stream)); +#endif + + if (avctx->extradata_size < 8) { + av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); + return 1; + } + + if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { + return 1; + } + + /* Check codec type */ + if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) || + ((avctx->codec_id == CODEC_ID_ZLIB) && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) { + av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); + } + + /* Detect image type */ + switch (c->imgtype = *((char *)avctx->extradata + 4)) { + case IMGTYPE_YUV111: + c->decomp_size = basesize * 3; + max_decomp_size = max_basesize * 3; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); + break; + case IMGTYPE_YUV422: + c->decomp_size = basesize * 2; + max_decomp_size = max_basesize * 2; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); + break; + case IMGTYPE_RGB24: + c->decomp_size = basesize * 3; + max_decomp_size = max_basesize * 3; + av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); + break; + case IMGTYPE_YUV411: + c->decomp_size = basesize / 2 * 3; + max_decomp_size = max_basesize / 2 * 3; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); + break; + case IMGTYPE_YUV211: + c->decomp_size = basesize * 2; + max_decomp_size = max_basesize * 2; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); + break; + case IMGTYPE_YUV420: + c->decomp_size = basesize / 2 * 3; + max_decomp_size = max_basesize / 2 * 3; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); + return 1; + } + + /* Detect compression method */ + c->compression = *((char *)avctx->extradata + 5); + switch (avctx->codec_id) { + case CODEC_ID_MSZH: + switch (c->compression) { + case COMP_MSZH: + av_log(avctx, AV_LOG_INFO, "Compression enabled.\n"); + break; + case COMP_MSZH_NOCOMP: + c->decomp_size = 0; + av_log(avctx, AV_LOG_INFO, "No compression.\n"); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); + return 1; + } + break; + case CODEC_ID_ZLIB: +#ifdef CONFIG_ZLIB + switch (c->compression) { + case COMP_ZLIB_HISPEED: + av_log(avctx, AV_LOG_INFO, "High speed compression.\n"); + break; + case COMP_ZLIB_HICOMP: + av_log(avctx, AV_LOG_INFO, "High compression.\n"); + break; + case COMP_ZLIB_NORMAL: + av_log(avctx, AV_LOG_INFO, "Normal compression.\n"); + break; + default: + if ((c->compression < Z_NO_COMPRESSION) || (c->compression > Z_BEST_COMPRESSION)) { + av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); + return 1; + } + av_log(avctx, AV_LOG_INFO, "Compression level for ZLIB: (%d).\n", c->compression); + } +#else + av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); + return 1; +#endif + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); + return 1; + } + + /* Allocate decompression buffer */ + if (c->decomp_size) { + if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { + av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); + return 1; + } + } + + /* Detect flags */ + c->flags = *((char *)avctx->extradata + 6); + if (c->flags & FLAG_MULTITHREAD) + av_log(avctx, AV_LOG_INFO, "Multithread encoder flag set.\n"); + if (c->flags & FLAG_NULLFRAME) + av_log(avctx, AV_LOG_INFO, "Nullframe insertion flag set.\n"); + if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) + av_log(avctx, AV_LOG_INFO, "PNG filter flag set.\n"); + if (c->flags & FLAGMASK_UNUSED) + av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); + + /* If needed init zlib */ + if (avctx->codec_id == CODEC_ID_ZLIB) { +#ifdef CONFIG_ZLIB + c->zstream.zalloc = Z_NULL; + c->zstream.zfree = Z_NULL; + c->zstream.opaque = Z_NULL; + zret = inflateInit(&(c->zstream)); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); + return 1; + } +#else + av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); + return 1; +#endif + } + + avctx->pix_fmt = PIX_FMT_BGR24; + + return 0; +} + +/* + * + * Uninit lcl decoder + * + */ +static int decode_end(AVCodecContext *avctx) +{ + LclDecContext * const c = avctx->priv_data; + + if (c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); +#ifdef CONFIG_ZLIB + inflateEnd(&(c->zstream)); +#endif + + return 0; +} + +#ifdef CONFIG_MSZH_DECODER +AVCodec mszh_decoder = { + "mszh", + CODEC_TYPE_VIDEO, + CODEC_ID_MSZH, + sizeof(LclDecContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; +#endif + +#ifdef CONFIG_ZLIB_DECODER +AVCodec zlib_decoder = { + "zlib", + CODEC_TYPE_VIDEO, + CODEC_ID_ZLIB, + sizeof(LclDecContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; +#endif diff --git a/contrib/ffmpeg/libavcodec/lclenc.c b/contrib/ffmpeg/libavcodec/lclenc.c new file mode 100644 index 000000000..e8349052a --- /dev/null +++ b/contrib/ffmpeg/libavcodec/lclenc.c @@ -0,0 +1,231 @@ +/* + * LCL (LossLess Codec Library) Codec + * Copyright (c) 2002-2004 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 lcl.c + * LCL (LossLess Codec Library) Video Codec + * Decoder for MSZH and ZLIB codecs + * Experimental encoder for ZLIB RGB24 + * + * Fourcc: MSZH, ZLIB + * + * Original Win32 dll: + * Ver2.23 By Kenji Oshima 2000.09.20 + * avimszh.dll, avizlib.dll + * + * A description of the decoding algorithm can be found here: + * http://www.pcisys.net/~melanson/codecs + * + * Supports: BGR24 (RGB 24bpp) + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "avcodec.h" +#include "bitstream.h" +#include "lcl.h" + +#ifdef CONFIG_ZLIB +#include <zlib.h> +#endif + +/* + * Decoder context + */ +typedef struct LclEncContext { + + AVCodecContext *avctx; + AVFrame pic; + PutBitContext pb; + + // Image type + int imgtype; + // Compression type + int compression; + // Flags + int flags; + // Decompressed data size + unsigned int decomp_size; + // Maximum compressed data size + unsigned int max_comp_size; + // Compression buffer + unsigned char* comp_buf; +#ifdef CONFIG_ZLIB + z_stream zstream; +#endif +} LclEncContext; + +/* + * + * Encode a frame + * + */ +static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + LclEncContext *c = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p = &c->pic; + int i; + int zret; // Zlib return code + +#ifndef CONFIG_ZLIB + av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled in.\n"); + return -1; +#else + + init_put_bits(&c->pb, buf, buf_size); + + *p = *pict; + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + + if(avctx->pix_fmt != PIX_FMT_BGR24){ + av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); + return -1; + } + + zret = deflateReset(&(c->zstream)); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret); + return -1; + } + c->zstream.next_out = c->comp_buf; + c->zstream.avail_out = c->max_comp_size; + + for(i = avctx->height - 1; i >= 0; i--) { + c->zstream.next_in = p->data[0]+p->linesize[0]*i; + c->zstream.avail_in = avctx->width*3; + zret = deflate(&(c->zstream), Z_NO_FLUSH); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); + return -1; + } + } + zret = deflate(&(c->zstream), Z_FINISH); + if (zret != Z_STREAM_END) { + av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); + return -1; + } + + for (i = 0; i < c->zstream.total_out; i++) + put_bits(&c->pb, 8, c->comp_buf[i]); + flush_put_bits(&c->pb); + + return c->zstream.total_out; +#endif +} + +/* + * + * Init lcl encoder + * + */ +static int encode_init(AVCodecContext *avctx) +{ + LclEncContext *c = avctx->priv_data; + int zret; // Zlib return code + +#ifndef CONFIG_ZLIB + av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); + return 1; +#else + + c->avctx= avctx; + + assert(avctx->width && avctx->height); + + avctx->extradata= av_mallocz(8); + avctx->coded_frame= &c->pic; + + // Will be user settable someday + c->compression = 6; + c->flags = 0; + + switch(avctx->pix_fmt){ + case PIX_FMT_BGR24: + c->imgtype = IMGTYPE_RGB24; + c->decomp_size = avctx->width * avctx->height * 3; + avctx->bits_per_sample= 24; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Format %d not supported\n", avctx->pix_fmt); + return -1; + } + + ((uint8_t*)avctx->extradata)[0]= 4; + ((uint8_t*)avctx->extradata)[1]= 0; + ((uint8_t*)avctx->extradata)[2]= 0; + ((uint8_t*)avctx->extradata)[3]= 0; + ((uint8_t*)avctx->extradata)[4]= c->imgtype; + ((uint8_t*)avctx->extradata)[5]= c->compression; + ((uint8_t*)avctx->extradata)[6]= c->flags; + ((uint8_t*)avctx->extradata)[7]= CODEC_ZLIB; + c->avctx->extradata_size= 8; + + c->zstream.zalloc = Z_NULL; + c->zstream.zfree = Z_NULL; + c->zstream.opaque = Z_NULL; + zret = deflateInit(&(c->zstream), c->compression); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); + return 1; + } + + /* Conservative upper bound taken from zlib v1.2.1 source */ + c->max_comp_size = c->decomp_size + ((c->decomp_size + 7) >> 3) + + ((c->decomp_size + 63) >> 6) + 11; + if ((c->comp_buf = av_malloc(c->max_comp_size)) == NULL) { + av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n"); + return 1; + } + + return 0; +#endif +} + +/* + * + * Uninit lcl encoder + * + */ +static int encode_end(AVCodecContext *avctx) +{ + LclEncContext *c = avctx->priv_data; + + av_freep(&avctx->extradata); + av_freep(&c->comp_buf); +#ifdef CONFIG_ZLIB + deflateEnd(&(c->zstream)); +#endif + + return 0; +} + +AVCodec zlib_encoder = { + "zlib", + CODEC_TYPE_VIDEO, + CODEC_ID_ZLIB, + sizeof(LclEncContext), + encode_init, + encode_frame, + encode_end, +}; diff --git a/contrib/ffmpeg/libavcodec/a52dec.c b/contrib/ffmpeg/libavcodec/liba52.c index c2da2283d..86b013602 100644 --- a/contrib/ffmpeg/libavcodec/a52dec.c +++ b/contrib/ffmpeg/libavcodec/liba52.c @@ -37,9 +37,6 @@ static const char* liba52name = "liba52.so.0"; * released under the GPL license. */ typedef struct AC3DecodeState { - uint8_t inbuf[4096]; /* input buffer */ - uint8_t *inbuf_ptr; - int frame_size; int flags; int channels; a52_state_t* state; @@ -114,22 +111,18 @@ static int a52_decode_init(AVCodecContext *avctx) #endif s->state = s->a52_init(0); /* later use CPU flags */ s->samples = s->a52_samples(s->state); - s->inbuf_ptr = s->inbuf; - s->frame_size = 0; - return 0; -} + /* allow downmixing to stereo or mono */ + if (avctx->channels > 0 && avctx->request_channels > 0 && + avctx->request_channels < avctx->channels && + avctx->request_channels <= 2) { + avctx->channels = avctx->request_channels; + } -/**** the following two functions comes from a52dec */ -static inline int blah (int32_t i) -{ - if (i > 0x43c07fff) - return 32767; - else if (i < 0x43bf8000) - return -32768; - return i - 0x43c00000; + return 0; } +/**** the following function comes from a52dec */ static inline void float_to_int (float * _f, int16_t * s16, int nchannels) { int i, j, c; @@ -139,7 +132,7 @@ static inline void float_to_int (float * _f, int16_t * s16, int nchannels) nchannels *= 256; for (i = 0; i < 256; i++) { for (c = 0; c < nchannels; c += 256) - s16[j++] = blah (f[i + c]); + s16[j++] = av_clip_int16(f[i + c] - 0x43c00000); } } @@ -152,7 +145,6 @@ static int a52_decode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size) { AC3DecodeState *s = avctx->priv_data; - uint8_t *buf_ptr; int flags, i, len; int sample_rate, bit_rate; short *out_samples = data; @@ -163,78 +155,52 @@ static int a52_decode_frame(AVCodecContext *avctx, *data_size= 0; - buf_ptr = buf; - while (buf_size > 0) { - len = s->inbuf_ptr - s->inbuf; - if (s->frame_size == 0) { - /* no header seen : find one. We need at least 7 bytes to parse it */ - len = HEADER_SIZE - len; - if (len > buf_size) - len = buf_size; - memcpy(s->inbuf_ptr, buf_ptr, len); - buf_ptr += len; - s->inbuf_ptr += len; - buf_size -= len; - if ((s->inbuf_ptr - s->inbuf) == HEADER_SIZE) { - len = s->a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate); - if (len == 0) { - /* no sync found : move by one byte (inefficient, but simple!) */ - memcpy(s->inbuf, s->inbuf + 1, HEADER_SIZE - 1); - s->inbuf_ptr--; - } else { - s->frame_size = len; - /* update codec info */ - avctx->sample_rate = sample_rate; - s->channels = ac3_channels[s->flags & 7]; - if (s->flags & A52_LFE) - s->channels++; - if (avctx->channels == 0) - /* No specific number of channel requested */ - avctx->channels = s->channels; - else if (s->channels < avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "ac3dec: AC3 Source channels are less than specified: output to %d channels.. (frmsize: %d)\n", s->channels, len); - avctx->channels = s->channels; - } - avctx->bit_rate = bit_rate; - } - } - } else if (len < s->frame_size) { - len = s->frame_size - len; - if (len > buf_size) - len = buf_size; - - memcpy(s->inbuf_ptr, buf_ptr, len); - buf_ptr += len; - s->inbuf_ptr += len; - buf_size -= len; - } else { - flags = s->flags; - if (avctx->channels == 1) - flags = A52_MONO; - else if (avctx->channels == 2) - flags = A52_STEREO; - else - flags |= A52_ADJUST_LEVEL; - level = 1; - if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { - fail: - av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); - s->inbuf_ptr = s->inbuf; - s->frame_size = 0; - continue; - } - for (i = 0; i < 6; i++) { - if (s->a52_block(s->state)) - goto fail; - float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); - } - s->inbuf_ptr = s->inbuf; - s->frame_size = 0; - *data_size = 6 * avctx->channels * 256 * sizeof(int16_t); - break; - } + if (buf_size < HEADER_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Error decoding frame, not enough bytes for header\n"); + return -1; + } + len = s->a52_syncinfo(buf, &s->flags, &sample_rate, &bit_rate); + if (len == 0) { + av_log(avctx, AV_LOG_ERROR, "Error decoding frame, no sync byte at begin\n"); + return -1; + } + if (buf_size < len) { + av_log(avctx, AV_LOG_ERROR, "Error decoding frame, not enough bytes\n"); + return -1; + } + /* update codec info */ + avctx->sample_rate = sample_rate; + s->channels = ac3_channels[s->flags & 7]; + if (s->flags & A52_LFE) + s->channels++; + if (avctx->request_channels > 0 && + avctx->request_channels <= 2 && + avctx->request_channels < s->channels) { + avctx->channels = avctx->request_channels; + } else { + avctx->channels = s->channels; + } + avctx->bit_rate = bit_rate; + flags = s->flags; + if (avctx->channels == 1) + flags = A52_MONO; + else if (avctx->channels == 2) + flags = A52_STEREO; + else + flags |= A52_ADJUST_LEVEL; + level = 1; + if (s->a52_frame(s->state, buf, &flags, &level, 384)) { + fail: + av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); + return -1; + } + for (i = 0; i < 6; i++) { + if (s->a52_block(s->state)) + goto fail; + float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); } - return buf_ptr - buf; + *data_size = 6 * avctx->channels * 256 * sizeof(int16_t); + return len; } static int a52_decode_end(AVCodecContext *avctx) @@ -248,7 +214,7 @@ static int a52_decode_end(AVCodecContext *avctx) } AVCodec liba52_decoder = { - "ac3", + "liba52", CODEC_TYPE_AUDIO, CODEC_ID_AC3, sizeof(AC3DecodeState), diff --git a/contrib/ffmpeg/libavcodec/amr.c b/contrib/ffmpeg/libavcodec/libamr.c index 6a8193f0b..5a5145060 100644 --- a/contrib/ffmpeg/libavcodec/amr.c +++ b/contrib/ffmpeg/libavcodec/libamr.c @@ -26,23 +26,20 @@ * (AMR-WB) audio encoder/decoder through external reference code from * http://www.3gpp.org/. The license of the code from 3gpp is unclear so you * have to download the code separately. Two versions exists: One fixed-point - * and one with floats. For some reason the float-encoder is significant faster - * at least on a P4 1.5GHz (0.9s instead of 9.9s on a 30s audio clip at MR102). - * Both float and fixed point are supported for AMR-NB, but only float for - * AMR-WB. + * and one floating-point. For some reason the float encoder is significantly + * faster at least on a P4 1.5GHz (0.9s instead of 9.9s on a 30s audio clip + * at MR102). Both float and fixed point are supported for AMR-NB, but only + * float for AMR-WB. * * \section AMR-NB * * \subsection Float * The float version (default) can be downloaded from: * http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-610.zip - * Extract the source into \c "ffmpeg/libavcodec/amr_float". * * \subsection Fixed-point * The fixed-point (TS26.073) can be downloaded from: - * http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-510.zip. - * Extract the source into \c "ffmpeg/libavcodec/amr". - * To use the fixed version run \c "./configure" with \c "--enable-amr_nb-fixed". + * http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-600.zip * * \subsection Specification * The specification for AMR-NB can be found in TS 26.071 @@ -50,11 +47,10 @@ * info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm. * * \section AMR-WB + * * \subsection Float * The reference code can be downloaded from: * http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-600.zip - * It should be extracted to \c "ffmpeg/libavcodec/amrwb_float". Enable it with - * \c "--enable-amr_wb". * * \subsection Fixed-point * If someone wants to use the fixed point version it can be downloaded from: @@ -69,7 +65,7 @@ #include "avcodec.h" -#ifdef CONFIG_AMR_NB_FIXED +#ifdef CONFIG_LIBAMR_NB_FIXED #define MMS_IO @@ -81,10 +77,15 @@ #include "amr/e_homing.h" #else -#include "amr_float/interf_dec.h" -#include "amr_float/interf_enc.h" +#include <amrnb/interf_dec.h> +#include <amrnb/interf_enc.h> #endif +static const char *nb_bitrate_unsupported = + "bitrate not supported: use one of 4.75k, 5.15k, 5.9k, 6.7k, 7.4k, 7.95k, 10.2k or 12.2k\n"; +static const char *wb_bitrate_unsupported = + "bitrate not supported: use one of 6.6k, 8.85k, 12.65k, 14.25k, 15.85k, 18.25k, 19.85k, 23.05k, or 23.85k\n"; + /* Common code for fixed and float version*/ typedef struct AMR_bitrates { @@ -135,7 +136,7 @@ static void amr_decode_fix_avctx(AVCodecContext * avctx) avctx->frame_size = 160 * is_amr_wb; } -#ifdef CONFIG_AMR_NB_FIXED +#ifdef CONFIG_LIBAMR_NB_FIXED /* fixed point version*/ /* frame size in serial bitstream file (frame type + serial stream + flags) */ #define SERIAL_FRAMESIZE (1+MAX_SERIAL_SIZE+5) @@ -216,7 +217,7 @@ static int amr_nb_encode_init(AVCodecContext * avctx) if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0) { - av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); + av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported); return -1; } @@ -259,73 +260,69 @@ static int amr_nb_decode_frame(AVCodecContext * avctx, synth=data; -// while(offset<buf_size) - { - toc=amrData[offset]; - /* read rest of the frame based on ToC byte */ - q = (toc >> 2) & 0x01; - ft = (toc >> 3) & 0x0F; + toc=amrData[offset]; + /* read rest of the frame based on ToC byte */ + q = (toc >> 2) & 0x01; + ft = (toc >> 3) & 0x0F; - //printf("offset=%d, packet_size=%d amrData= 0x%X %X %X %X\n",offset,packed_size[ft],amrData[offset],amrData[offset+1],amrData[offset+2],amrData[offset+3]); + //printf("offset=%d, packet_size=%d amrData= 0x%X %X %X %X\n",offset,packed_size[ft],amrData[offset],amrData[offset+1],amrData[offset+2],amrData[offset+3]); - offset++; + offset++; - packed_bits=amrData+offset; + packed_bits=amrData+offset; - offset+=packed_size[ft]; + offset+=packed_size[ft]; - //Unsort and unpack bits - s->rx_type = UnpackBits(q, ft, packed_bits, &s->mode, &serial[1]); + //Unsort and unpack bits + s->rx_type = UnpackBits(q, ft, packed_bits, &s->mode, &serial[1]); - //We have a new frame - s->frameCount++; + //We have a new frame + s->frameCount++; - if (s->rx_type == RX_NO_DATA) - { - s->mode = s->speech_decoder_state->prev_mode; - } - else { - s->speech_decoder_state->prev_mode = s->mode; - } + if (s->rx_type == RX_NO_DATA) + { + s->mode = s->speech_decoder_state->prev_mode; + } + else { + s->speech_decoder_state->prev_mode = s->mode; + } - /* if homed: check if this frame is another homing frame */ - if (s->reset_flag_old == 1) - { - /* only check until end of first subframe */ - s->reset_flag = decoder_homing_frame_test_first(&serial[1], s->mode); - } - /* produce encoder homing frame if homed & input=decoder homing frame */ - if ((s->reset_flag != 0) && (s->reset_flag_old != 0)) - { - for (i = 0; i < L_FRAME; i++) - { - synth[i] = EHF_MASK; - } - } - else + /* if homed: check if this frame is another homing frame */ + if (s->reset_flag_old == 1) + { + /* only check until end of first subframe */ + s->reset_flag = decoder_homing_frame_test_first(&serial[1], s->mode); + } + /* produce encoder homing frame if homed & input=decoder homing frame */ + if ((s->reset_flag != 0) && (s->reset_flag_old != 0)) + { + for (i = 0; i < L_FRAME; i++) { - /* decode frame */ - Speech_Decode_Frame(s->speech_decoder_state, s->mode, &serial[1], s->rx_type, synth); + synth[i] = EHF_MASK; } + } + else + { + /* decode frame */ + Speech_Decode_Frame(s->speech_decoder_state, s->mode, &serial[1], s->rx_type, synth); + } - //Each AMR-frame results in 160 16-bit samples - *data_size+=160*2; - synth+=160; - - /* if not homed: check whether current frame is a homing frame */ - if (s->reset_flag_old == 0) - { - /* check whole frame */ - s->reset_flag = decoder_homing_frame_test(&serial[1], s->mode); - } - /* reset decoder if current frame is a homing frame */ - if (s->reset_flag != 0) - { - Speech_Decode_Frame_reset(s->speech_decoder_state); - } - s->reset_flag_old = s->reset_flag; + //Each AMR-frame results in 160 16-bit samples + *data_size=160*2; + /* if not homed: check whether current frame is a homing frame */ + if (s->reset_flag_old == 0) + { + /* check whole frame */ + s->reset_flag = decoder_homing_frame_test(&serial[1], s->mode); + } + /* reset decoder if current frame is a homing frame */ + if (s->reset_flag != 0) + { + Speech_Decode_Frame_reset(s->speech_decoder_state); } + s->reset_flag_old = s->reset_flag; + return offset; } @@ -355,7 +352,7 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, } -#elif defined(CONFIG_AMR_NB) /* Float point version*/ +#elif defined(CONFIG_LIBAMR_NB) /* Float point version*/ typedef struct AMRContext { int frameCount; @@ -417,7 +414,7 @@ static int amr_nb_encode_init(AVCodecContext * avctx) if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0) { - av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); + av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported); return -1; } @@ -447,7 +444,7 @@ static int amr_nb_decode_frame(AVCodecContext * avctx, { AMRContext *s = avctx->priv_data; uint8_t*amrData=buf; - static short block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 }; + static const uint8_t block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 }; enum Mode dec_mode; int packet_size; @@ -478,7 +475,7 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0) { - av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); + av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported); return -1; } @@ -494,11 +491,11 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, #endif -#if defined(CONFIG_AMR_NB) || defined(CONFIG_AMR_NB_FIXED) +#if defined(CONFIG_LIBAMR_NB) || defined(CONFIG_LIBAMR_NB_FIXED) -AVCodec amr_nb_decoder = +AVCodec libamr_nb_decoder = { - "amr_nb", + "libamr_nb", CODEC_TYPE_AUDIO, CODEC_ID_AMR_NB, sizeof(AMRContext), @@ -508,9 +505,9 @@ AVCodec amr_nb_decoder = amr_nb_decode_frame, }; -AVCodec amr_nb_encoder = +AVCodec libamr_nb_encoder = { - "amr_nb", + "libamr_nb", CODEC_TYPE_AUDIO, CODEC_ID_AMR_NB, sizeof(AMRContext), @@ -523,15 +520,16 @@ AVCodec amr_nb_encoder = #endif /* -----------AMR wideband ------------*/ -#ifdef CONFIG_AMR_WB +#ifdef CONFIG_LIBAMR_WB #ifdef _TYPEDEF_H -//To avoid duplicate typedefs from typdef in amr-nb +//To avoid duplicate typedefs from typedef in amr-nb #define typedef_h #endif -#include "amrwb_float/enc_if.h" -#include "amrwb_float/dec_if.h" +#include <amrwb/enc_if.h> +#include <amrwb/dec_if.h> +#include <amrwb/if_rom.h> /* Common code for fixed and float version*/ typedef struct AMRWB_bitrates @@ -594,7 +592,7 @@ static int amr_wb_encode_init(AVCodecContext * avctx) if((s->mode=getWBBitrateMode(avctx->bit_rate))<0) { - av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); + av_log(avctx, AV_LOG_ERROR, wb_bitrate_unsupported); return -1; } @@ -625,7 +623,7 @@ static int amr_wb_encode_frame(AVCodecContext *avctx, if((s->mode=getWBBitrateMode(avctx->bit_rate))<0) { - av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); + av_log(avctx, AV_LOG_ERROR, wb_bitrate_unsupported); return -1; } size = E_IF_encode(s->state, s->mode, data, frame, s->allow_dtx); @@ -650,8 +648,6 @@ static int amr_wb_decode_init(AVCodecContext * avctx) return 0; } -extern const UWord8 block_size[]; - static int amr_wb_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t * buf, int buf_size) @@ -660,6 +656,7 @@ static int amr_wb_decode_frame(AVCodecContext * avctx, uint8_t*amrData=buf; int mode; int packet_size; + static const uint8_t block_size[16] = {18, 23, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1}; if(buf_size==0) { /* nothing to do */ @@ -688,9 +685,9 @@ static int amr_wb_decode_close(AVCodecContext * avctx) return 0; } -AVCodec amr_wb_decoder = +AVCodec libamr_wb_decoder = { - "amr_wb", + "libamr_wb", CODEC_TYPE_AUDIO, CODEC_ID_AMR_WB, sizeof(AMRWBContext), @@ -700,9 +697,9 @@ AVCodec amr_wb_decoder = amr_wb_decode_frame, }; -AVCodec amr_wb_encoder = +AVCodec libamr_wb_encoder = { - "amr_wb", + "libamr_wb", CODEC_TYPE_AUDIO, CODEC_ID_AMR_WB, sizeof(AMRWBContext), @@ -712,4 +709,4 @@ AVCodec amr_wb_encoder = NULL, }; -#endif //CONFIG_AMR_WB +#endif //CONFIG_LIBAMR_WB diff --git a/contrib/ffmpeg/libavcodec/faac.c b/contrib/ffmpeg/libavcodec/libfaac.c index 9ff9f5ed0..e2802b398 100644 --- a/contrib/ffmpeg/libavcodec/faac.c +++ b/contrib/ffmpeg/libavcodec/libfaac.c @@ -20,7 +20,7 @@ */ /** - * @file faacaudio.c + * @file libfaac.c * Interface to libfaac for aac encoding. */ @@ -54,7 +54,25 @@ static int Faac_encode_init(AVCodecContext *avctx) } /* put the options in the configuration struct */ - faac_cfg->aacObjectType = LOW; + switch(avctx->profile) { + case FF_PROFILE_AAC_MAIN: + faac_cfg->aacObjectType = MAIN; + break; + case FF_PROFILE_UNKNOWN: + case FF_PROFILE_AAC_LOW: + faac_cfg->aacObjectType = LOW; + break; + case FF_PROFILE_AAC_SSR: + faac_cfg->aacObjectType = SSR; + break; + case FF_PROFILE_AAC_LTP: + faac_cfg->aacObjectType = LTP; + break; + default: + av_log(avctx, AV_LOG_ERROR, "invalid AAC profile\n"); + faacEncClose(s->faac_handle); + return -1; + } faac_cfg->mpegVersion = MPEG4; faac_cfg->useTns = 0; faac_cfg->allowMidside = 1; @@ -125,8 +143,8 @@ static int Faac_encode_close(AVCodecContext *avctx) return 0; } -AVCodec faac_encoder = { - "aac", +AVCodec libfaac_encoder = { + "libfaac", CODEC_TYPE_AUDIO, CODEC_ID_AAC, sizeof(FaacAudioContext), diff --git a/contrib/ffmpeg/libavcodec/faad.c b/contrib/ffmpeg/libavcodec/libfaad.c index 01cbd40e7..f8d7c6573 100644 --- a/contrib/ffmpeg/libavcodec/faad.c +++ b/contrib/ffmpeg/libavcodec/libfaad.c @@ -42,7 +42,7 @@ #ifdef CONFIG_LIBFAADBIN #include <dlfcn.h> -static const char* libfaadname = "libfaad.so.0"; +static const char* libfaadname = "libfaad.so"; #else #define dlopen(a) #define dlclose(a) @@ -58,36 +58,36 @@ typedef struct { faacDecHandle FAADAPI (*faacDecOpen)(void); faacDecConfigurationPtr FAADAPI (*faacDecGetCurrentConfiguration)(faacDecHandle hDecoder); #ifndef FAAD2_VERSION - int FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, + int FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, faacDecConfigurationPtr config); - int FAADAPI (*faacDecInit)(faacDecHandle hDecoder, - unsigned char *buffer, - unsigned long *samplerate, - unsigned long *channels); - int FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, + int FAADAPI (*faacDecInit)(faacDecHandle hDecoder, + unsigned char *buffer, + unsigned long *samplerate, + unsigned long *channels); + int FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, unsigned long SizeOfDecoderSpecificInfo, unsigned long *samplerate, unsigned long *channels); - int FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, - unsigned char *buffer, - unsigned long *bytesconsumed, - short *sample_buffer, - unsigned long *samples); + int FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, + unsigned char *buffer, + unsigned long *bytesconsumed, + short *sample_buffer, + unsigned long *samples); #else - unsigned char FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, + unsigned char FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, faacDecConfigurationPtr config); - long FAADAPI (*faacDecInit)(faacDecHandle hDecoder, - unsigned char *buffer, - unsigned long buffer_size, - unsigned long *samplerate, - unsigned char *channels); - char FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, + long FAADAPI (*faacDecInit)(faacDecHandle hDecoder, + unsigned char *buffer, + unsigned long buffer_size, + unsigned long *samplerate, + unsigned char *channels); + char FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, unsigned long SizeOfDecoderSpecificInfo, unsigned long *samplerate, unsigned char *channels); - void *FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, - faacDecFrameInfo *hInfo, - unsigned char *buffer, - unsigned long buffer_size); - char* FAADAPI (*faacDecGetErrorMessage)(unsigned char errcode); + void *FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, + faacDecFrameInfo *hInfo, + unsigned char *buffer, + unsigned long buffer_size); + char* FAADAPI (*faacDecGetErrorMessage)(unsigned char errcode); #endif void FAADAPI (*faacDecClose)(faacDecHandle hDecoder); @@ -101,9 +101,24 @@ static const unsigned long faac_srates[] = 24000, 22050, 16000, 12000, 11025, 8000 }; +static void channel_setup(AVCodecContext *avctx) +{ +#ifdef FAAD2_VERSION + FAACContext *s = avctx->priv_data; + if (avctx->request_channels > 0 && avctx->request_channels == 2 && + avctx->request_channels < avctx->channels) { + faacDecConfigurationPtr faac_cfg; + avctx->channels = 2; + faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); + faac_cfg->downMatrix = 1; + s->faacDecSetConfiguration(s->faac_handle, faac_cfg); + } +#endif +} + static int faac_init_mp4(AVCodecContext *avctx) { - FAACContext *s = (FAACContext *) avctx->priv_data; + FAACContext *s = avctx->priv_data; unsigned long samplerate; #ifndef FAAD2_VERSION unsigned long channels; @@ -123,6 +138,7 @@ static int faac_init_mp4(AVCodecContext *avctx) } else { avctx->sample_rate = samplerate; avctx->channels = channels; + channel_setup(avctx); s->init = 1; } } @@ -134,7 +150,7 @@ static int faac_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) { - FAACContext *s = (FAACContext *) avctx->priv_data; + FAACContext *s = avctx->priv_data; #ifndef FAAD2_VERSION unsigned long bytesconsumed; short *sample_buffer = NULL; @@ -170,6 +186,7 @@ static int faac_decode_frame(AVCodecContext *avctx, } avctx->sample_rate = srate; avctx->channels = channels; + channel_setup(avctx); s->init = 1; } @@ -177,7 +194,7 @@ static int faac_decode_frame(AVCodecContext *avctx, if (frame_info.error > 0) { av_log(avctx, AV_LOG_ERROR, "faac: frame decoding failed: %s\n", - s->faacDecGetErrorMessage(frame_info.error)); + s->faacDecGetErrorMessage(frame_info.error)); return -1; } @@ -194,7 +211,7 @@ static int faac_decode_frame(AVCodecContext *avctx, static int faac_decode_end(AVCodecContext *avctx) { - FAACContext *s = (FAACContext *) avctx->priv_data; + FAACContext *s = avctx->priv_data; s->faacDecClose(s->faac_handle); @@ -204,7 +221,7 @@ static int faac_decode_end(AVCodecContext *avctx) static int faac_decode_init(AVCodecContext *avctx) { - FAACContext *s = (FAACContext *) avctx->priv_data; + FAACContext *s = avctx->priv_data; faacDecConfigurationPtr faac_cfg; #ifdef CONFIG_LIBFAADBIN @@ -214,54 +231,39 @@ static int faac_decode_init(AVCodecContext *avctx) if (!s->handle) { av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n", - libfaadname, dlerror()); + libfaadname, dlerror()); return -1; } -#define dfaac(a, b) \ - do { static const char* n = "faacDec" #a; \ - if ((s->faacDec ## a = b dlsym( s->handle, n )) == NULL) { err = n; break; } } while(0) - for(;;) { + +#define dfaac(a) do { \ + const char* n = AV_STRINGIFY(faacDec ## a); \ + if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \ + err = n; \ + } \ + } while(0) #else /* !CONFIG_LIBFAADBIN */ -#define dfaac(a, b) s->faacDec ## a = faacDec ## a +#define dfaac(a) s->faacDec ## a = faacDec ## a #endif /* CONFIG_LIBFAADBIN */ - // resolve all needed function calls - dfaac(Open, (faacDecHandle FAADAPI (*)(void))); - dfaac(Close, (void FAADAPI (*)(faacDecHandle hDecoder))); - dfaac(GetCurrentConfiguration, (faacDecConfigurationPtr - FAADAPI (*)(faacDecHandle))); -#ifndef FAAD2_VERSION - dfaac(SetConfiguration, (int FAADAPI (*)(faacDecHandle, - faacDecConfigurationPtr))); - - dfaac(Init, (int FAADAPI (*)(faacDecHandle, unsigned char*, - unsigned long*, unsigned long*))); - dfaac(Init2, (int FAADAPI (*)(faacDecHandle, unsigned char*, - unsigned long, unsigned long*, - unsigned long*))); - dfaac(Decode, (int FAADAPI (*)(faacDecHandle, unsigned char*, - unsigned long*, short*, unsigned long*))); -#else - dfaac(SetConfiguration, (unsigned char FAADAPI (*)(faacDecHandle, - faacDecConfigurationPtr))); - dfaac(Init, (long FAADAPI (*)(faacDecHandle, unsigned char*, - unsigned long, unsigned long*, unsigned char*))); - dfaac(Init2, (char FAADAPI (*)(faacDecHandle, unsigned char*, - unsigned long, unsigned long*, - unsigned char*))); - dfaac(Decode, (void *FAADAPI (*)(faacDecHandle, faacDecFrameInfo*, - unsigned char*, unsigned long))); - dfaac(GetErrorMessage, (char* FAADAPI (*)(unsigned char))); + // resolve all needed function calls + dfaac(Open); + dfaac(Close); + dfaac(GetCurrentConfiguration); + dfaac(SetConfiguration); + dfaac(Init); + dfaac(Init2); + dfaac(Decode); +#ifdef FAAD2_VERSION + dfaac(GetErrorMessage); #endif -#undef dfacc + +#undef dfaac #ifdef CONFIG_LIBFAADBIN - break; - } if (err) { dlclose(s->handle); av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n", - err, libfaadname); + err, libfaadname); return -1; } #endif @@ -308,6 +310,9 @@ static int faac_decode_init(AVCodecContext *avctx) faac_init_mp4(avctx); + if(!s->init && avctx->channels > 0) + channel_setup(avctx); + return 0; } @@ -324,7 +329,7 @@ AVCodec name ## _decoder = { \ } // FIXME - raw AAC files - maybe just one entry will be enough -AAC_CODEC(CODEC_ID_AAC, aac); +AAC_CODEC(CODEC_ID_AAC, libfaad); #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) // If it's mp4 file - usually embeded into Qt Mov AAC_CODEC(CODEC_ID_MPEG4AAC, mpeg4aac); diff --git a/contrib/ffmpeg/libavcodec/libgsm.c b/contrib/ffmpeg/libavcodec/libgsm.c index 86dfce575..4fe2b384b 100644 --- a/contrib/ffmpeg/libavcodec/libgsm.c +++ b/contrib/ffmpeg/libavcodec/libgsm.c @@ -30,7 +30,7 @@ #include "avcodec.h" #include <gsm.h> -// gsm.h miss some essential constants +// gsm.h misses some essential constants #define GSM_BLOCK_SIZE 33 #define GSM_MS_BLOCK_SIZE 65 #define GSM_FRAME_SIZE 160 @@ -84,7 +84,7 @@ static int libgsm_encode_frame(AVCodecContext *avctx, AVCodec libgsm_encoder = { - "gsm", + "libgsm", CODEC_TYPE_AUDIO, CODEC_ID_GSM, 0, @@ -94,7 +94,7 @@ AVCodec libgsm_encoder = { }; AVCodec libgsm_ms_encoder = { - "gsm", + "libgsm_ms", CODEC_TYPE_AUDIO, CODEC_ID_GSM_MS, 0, @@ -123,7 +123,7 @@ static int libgsm_decode_frame(AVCodecContext *avctx, } AVCodec libgsm_decoder = { - "gsm", + "libgsm", CODEC_TYPE_AUDIO, CODEC_ID_GSM, 0, @@ -134,7 +134,7 @@ AVCodec libgsm_decoder = { }; AVCodec libgsm_ms_decoder = { - "gsm_ms", + "libgsm_ms", CODEC_TYPE_AUDIO, CODEC_ID_GSM_MS, 0, diff --git a/contrib/ffmpeg/libavcodec/mp3lameaudio.c b/contrib/ffmpeg/libavcodec/libmp3lame.c index d13350265..6fbf2e23d 100644 --- a/contrib/ffmpeg/libavcodec/mp3lameaudio.c +++ b/contrib/ffmpeg/libavcodec/libmp3lame.c @@ -28,7 +28,7 @@ #include "mpegaudio.h" #include <lame/lame.h> -#define BUFFER_SIZE (2*MPA_FRAME_SIZE) +#define BUFFER_SIZE (7200 + MPA_FRAME_SIZE + MPA_FRAME_SIZE/4) typedef struct Mp3AudioContext { lame_global_flags *gfp; int stereo; @@ -61,6 +61,7 @@ static int MP3lame_encode_init(AVCodecContext *avctx) lame_set_VBR_q(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA); } lame_set_bWriteVbrTag(s->gfp,0); + lame_set_disable_reservoir(s->gfp, avctx->flags2 & CODEC_FLAG2_BIT_RESERVOIR ? 0 : 1); if (lame_init_params(s->gfp) < 0) goto err_close; @@ -106,8 +107,7 @@ static const int sBitsPerSlot[3] = { static int mp3len(void *data, int *samplesPerFrame, int *sampleRate) { - uint8_t *dataTmp = (uint8_t *)data; - uint32_t header = ( (uint32_t)dataTmp[0] << 24 ) | ( (uint32_t)dataTmp[1] << 16 ) | ( (uint32_t)dataTmp[2] << 8 ) | (uint32_t)dataTmp[3]; + uint32_t header = AV_RB32(data); int layerID = 3 - ((header >> 17) & 0x03); int bitRateID = ((header >> 12) & 0x0f); int sampleRateID = ((header >> 10) & 0x03); @@ -189,7 +189,7 @@ static int MP3lame_encode_frame(AVCodecContext *avctx, s->buffer_index -= len; memmove(s->buffer, s->buffer+len, s->buffer_index); - //FIXME fix the audio codec API, so we dont need the memcpy() + //FIXME fix the audio codec API, so we do not need the memcpy() /*for(i=0; i<len; i++){ av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]); }*/ @@ -209,8 +209,8 @@ static int MP3lame_encode_close(AVCodecContext *avctx) } -AVCodec mp3lame_encoder = { - "mp3", +AVCodec libmp3lame_encoder = { + "libmp3lame", CODEC_TYPE_AUDIO, CODEC_ID_MP3, sizeof(Mp3AudioContext), diff --git a/contrib/ffmpeg/libavcodec/libtheoraenc.c b/contrib/ffmpeg/libavcodec/libtheoraenc.c index 7f531dbee..c3d848f31 100644 --- a/contrib/ffmpeg/libavcodec/libtheoraenc.c +++ b/contrib/ffmpeg/libavcodec/libtheoraenc.c @@ -15,7 +15,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /*! @@ -69,8 +69,8 @@ static int concatenate_packet(unsigned int* offset, AVCodecContext* avc_context, avc_context->extradata = newdata; avc_context->extradata_size = newsize; - avc_context->extradata[ (*offset)++ ] = packet->bytes >> 8; - avc_context->extradata[ (*offset)++ ] = packet->bytes & 0xff; + AV_WB16(avc_context->extradata + (*offset), packet->bytes); + *offset += 2; memcpy( avc_context->extradata + (*offset), packet->packet, packet->bytes ); (*offset) += packet->bytes; return 0; diff --git a/contrib/ffmpeg/libavcodec/oggvorbis.c b/contrib/ffmpeg/libavcodec/libvorbis.c index da97e9a78..3fb507dad 100644 --- a/contrib/ffmpeg/libavcodec/oggvorbis.c +++ b/contrib/ffmpeg/libavcodec/libvorbis.c @@ -15,7 +15,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -27,6 +27,7 @@ #include <vorbis/vorbisenc.h> #include "avcodec.h" +#include "bytestream.h" #undef NDEBUG #include <assert.h> @@ -207,8 +208,8 @@ static int oggvorbis_encode_close(AVCodecContext *avccontext) { } -AVCodec oggvorbis_encoder = { - "vorbis", +AVCodec libvorbis_encoder = { + "libvorbis", CODEC_TYPE_AUDIO, CODEC_ID_VORBIS, sizeof(OggVorbisContext), @@ -217,167 +218,3 @@ AVCodec oggvorbis_encoder = { oggvorbis_encode_close, .capabilities= CODEC_CAP_DELAY, } ; - -static int oggvorbis_decode_init(AVCodecContext *avccontext) { - OggVorbisContext *context = avccontext->priv_data ; - uint8_t *p= avccontext->extradata; - int i, hsizes[3]; - unsigned char *headers[3], *extradata = avccontext->extradata; - - vorbis_info_init(&context->vi) ; - vorbis_comment_init(&context->vc) ; - - if(! avccontext->extradata_size || ! p) { - av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n"); - return -1; - } - - if(p[0] == 0 && p[1] == 30) { - for(i = 0; i < 3; i++){ - hsizes[i] = *p++ << 8; - hsizes[i] += *p++; - headers[i] = p; - p += hsizes[i]; - } - } else if(*p == 2) { - unsigned int offset = 1; - p++; - for(i=0; i<2; i++) { - hsizes[i] = 0; - while((*p == 0xFF) && (offset < avccontext->extradata_size)) { - hsizes[i] += 0xFF; - offset++; - p++; - } - if(offset >= avccontext->extradata_size - 1) { - av_log(avccontext, AV_LOG_ERROR, - "vorbis header sizes damaged\n"); - return -1; - } - hsizes[i] += *p; - offset++; - p++; - } - hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset; -#if 0 - av_log(avccontext, AV_LOG_DEBUG, - "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n", - hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size); -#endif - headers[0] = extradata + offset; - headers[1] = extradata + offset + hsizes[0]; - headers[2] = extradata + offset + hsizes[0] + hsizes[1]; - } else { - av_log(avccontext, AV_LOG_ERROR, - "vorbis initial header len is wrong: %d\n", *p); - return -1; - } - - for(i=0; i<3; i++){ - context->op.b_o_s= i==0; - context->op.bytes = hsizes[i]; - context->op.packet = headers[i]; - if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){ - av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1); - return -1; - } - } - - avccontext->channels = context->vi.channels; - avccontext->sample_rate = context->vi.rate; - avccontext->time_base= (AVRational){1, avccontext->sample_rate}; - - vorbis_synthesis_init(&context->vd, &context->vi); - vorbis_block_init(&context->vd, &context->vb); - - return 0 ; -} - - -static inline int conv(int samples, float **pcm, char *buf, int channels) { - int i, j, val ; - ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ; - float *mono ; - - for(i = 0 ; i < channels ; i++){ - ptr = &data[i]; - mono = pcm[i] ; - - for(j = 0 ; j < samples ; j++) { - - val = mono[j] * 32767.f; - - if(val > 32767) val = 32767 ; - if(val < -32768) val = -32768 ; - - *ptr = val ; - ptr += channels; - } - } - - return 0 ; -} - - -static int oggvorbis_decode_frame(AVCodecContext *avccontext, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - OggVorbisContext *context = avccontext->priv_data ; - float **pcm ; - ogg_packet *op= &context->op; - int samples, total_samples, total_bytes; - - if(!buf_size){ - //FIXME flush - return 0; - } - - op->packet = buf; - op->bytes = buf_size; - -// av_log(avccontext, AV_LOG_DEBUG, "%d %d %d %"PRId64" %"PRId64" %d %d\n", op->bytes, op->b_o_s, op->e_o_s, op->granulepos, op->packetno, buf_size, context->vi.rate); - -/* for(i=0; i<op->bytes; i++) - av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]); - av_log(avccontext, AV_LOG_DEBUG, "\n");*/ - - if(vorbis_synthesis(&context->vb, op) == 0) - vorbis_synthesis_blockin(&context->vd, &context->vb) ; - - total_samples = 0 ; - total_bytes = 0 ; - - while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) { - conv(samples, pcm, (char*)data + total_bytes, context->vi.channels) ; - total_bytes += samples * 2 * context->vi.channels ; - total_samples += samples ; - vorbis_synthesis_read(&context->vd, samples) ; - } - - *data_size = total_bytes ; - return buf_size ; -} - - -static int oggvorbis_decode_close(AVCodecContext *avccontext) { - OggVorbisContext *context = avccontext->priv_data ; - - vorbis_info_clear(&context->vi) ; - vorbis_comment_clear(&context->vc) ; - - return 0 ; -} - - -AVCodec oggvorbis_decoder = { - "vorbis", - CODEC_TYPE_AUDIO, - CODEC_ID_VORBIS, - sizeof(OggVorbisContext), - oggvorbis_decode_init, - NULL, - oggvorbis_decode_close, - oggvorbis_decode_frame, - .capabilities= CODEC_CAP_DELAY, -} ; diff --git a/contrib/ffmpeg/libavcodec/x264.c b/contrib/ffmpeg/libavcodec/libx264.c index c9df820f5..eb897eba2 100644 --- a/contrib/ffmpeg/libavcodec/x264.c +++ b/contrib/ffmpeg/libavcodec/libx264.c @@ -1,6 +1,6 @@ /* * H.264 encoding using the x264 library - * Copyright (C) 2005 Mans Rullgard <mru@inprovide.com> + * Copyright (C) 2005 Mans Rullgard <mans@mansr.com> * * This file is part of FFmpeg. * @@ -38,7 +38,7 @@ X264_log(void *p, int level, const char *fmt, va_list args) { static const int level_map[] = { [X264_LOG_ERROR] = AV_LOG_ERROR, - [X264_LOG_WARNING] = AV_LOG_ERROR, + [X264_LOG_WARNING] = AV_LOG_WARNING, [X264_LOG_INFO] = AV_LOG_INFO, [X264_LOG_DEBUG] = AV_LOG_DEBUG }; @@ -287,8 +287,8 @@ X264_init(AVCodecContext *avctx) return 0; } -AVCodec x264_encoder = { - .name = "h264", +AVCodec libx264_encoder = { + .name = "libx264", .type = CODEC_TYPE_VIDEO, .id = CODEC_ID_H264, .priv_data_size = sizeof(X264Context), diff --git a/contrib/ffmpeg/libavcodec/xvid_internal.h b/contrib/ffmpeg/libavcodec/libxvid_internal.h index 49c59c205..a7d5a9646 100644 --- a/contrib/ffmpeg/libavcodec/xvid_internal.h +++ b/contrib/ffmpeg/libavcodec/libxvid_internal.h @@ -18,15 +18,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef XVID_INTERNAL_H -#define XVID_INTERNAL_H +#ifndef FFMPEG_LIBXVID_INTERNAL_H +#define FFMPEG_LIBXVID_INTERNAL_H /** - * @file xvid_internal.h + * @file libxvid_internal.h * common functions for use with the XviD wrappers */ int av_tempfile(char *prefix, char **filename); -#endif /* XVID_INTERNAL_H */ +#endif /* FFMPEG_LIBXVID_INTERNAL_H */ diff --git a/contrib/ffmpeg/libavcodec/xvid_rc.c b/contrib/ffmpeg/libavcodec/libxvid_rc.c index 6a0029e6d..f06f5b960 100644 --- a/contrib/ffmpeg/libavcodec/xvid_rc.c +++ b/contrib/ffmpeg/libavcodec/libxvid_rc.c @@ -23,7 +23,7 @@ #include <xvid.h> #include <unistd.h> #include "avcodec.h" -#include "xvid_internal.h" +#include "libxvid_internal.h" //#include "dsputil.h" #include "mpegvideo.h" diff --git a/contrib/ffmpeg/libavcodec/xvidff.c b/contrib/ffmpeg/libavcodec/libxvidff.c index 590fe4b30..f3a1a5bb9 100644 --- a/contrib/ffmpeg/libavcodec/xvidff.c +++ b/contrib/ffmpeg/libavcodec/libxvidff.c @@ -27,9 +27,8 @@ #include <xvid.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" -#include "xvid_internal.h" +#include "libxvid_internal.h" /** * Buffer management macros. @@ -39,9 +38,7 @@ #define BUFFER_CAT(x) (&((x)[strlen(x)])) /* For PPC Use */ -#if HAVE_ALTIVEC==1 extern int has_altivec(void); -#endif /** * Structure for the private XviD context. @@ -170,7 +167,7 @@ int ff_xvid_encode_init(AVCodecContext *avctx) { #ifdef ARCH_POWERPC /* XviD's PPC support is borked, use libavcodec to detect */ -#if HAVE_ALTIVEC==1 +#ifdef HAVE_ALTIVEC if( has_altivec() ) { xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ALTIVEC; } else @@ -756,8 +753,8 @@ int xvid_ff_2pass(void *ref, int cmd, void *p1, void *p2) { /** * XviD codec definition for libavcodec. */ -AVCodec xvid_encoder = { - "xvid", +AVCodec libxvid_encoder = { + "libxvid", CODEC_TYPE_VIDEO, CODEC_ID_XVID, sizeof(xvid_context_t), diff --git a/contrib/ffmpeg/libavcodec/ljpegenc.c b/contrib/ffmpeg/libavcodec/ljpegenc.c new file mode 100644 index 000000000..0e717397b --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ljpegenc.c @@ -0,0 +1,197 @@ +/* + * lossless JPEG encoder + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-2004 Michael Niedermayer + * + * Support for external huffman table, various fixes (AVID workaround), + * aspecting, new decode_frame mechanism and apple mjpeg-b support + * by 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 ljpegenc.c + * lossless JPEG encoder. + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "mjpeg.h" +#include "mjpegenc.h" + + +static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + MpegEncContext * const s = avctx->priv_data; + MJpegContext * const m = s->mjpeg_ctx; + AVFrame *pict = data; + const int width= s->width; + const int height= s->height; + AVFrame * const p= (AVFrame*)&s->current_picture; + const int predictor= avctx->prediction_method+1; + + init_put_bits(&s->pb, buf, buf_size); + + *p = *pict; + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + + ff_mjpeg_encode_picture_header(s); + + s->header_bits= put_bits_count(&s->pb); + + if(avctx->pix_fmt == PIX_FMT_RGB32){ + int x, y, i; + const int linesize= p->linesize[0]; + uint16_t (*buffer)[4]= (void *) s->rd_scratchpad; + int left[3], top[3], topleft[3]; + + for(i=0; i<3; i++){ + buffer[0][i]= 1 << (9 - 1); + } + + for(y = 0; y < height; y++) { + const int modified_predictor= y ? predictor : 1; + uint8_t *ptr = p->data[0] + (linesize * y); + + if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){ + av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + + for(i=0; i<3; i++){ + top[i]= left[i]= topleft[i]= buffer[0][i]; + } + for(x = 0; x < width; x++) { + buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100; + buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100; + buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2; + + for(i=0;i<3;i++) { + int pred, diff; + + PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); + + topleft[i]= top[i]; + top[i]= buffer[x+1][i]; + + left[i]= buffer[x][i]; + + diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100; + + if(i==0) + ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly + else + ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); + } + } + } + }else{ + int mb_x, mb_y, i; + const int mb_width = (width + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0]; + const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0]; + + for(mb_y = 0; mb_y < mb_height; mb_y++) { + if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){ + av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + for(mb_x = 0; mb_x < mb_width; mb_x++) { + if(mb_x==0 || mb_y==0){ + for(i=0;i<3;i++) { + uint8_t *ptr; + int x, y, h, v, linesize; + h = s->mjpeg_hsample[i]; + v = s->mjpeg_vsample[i]; + linesize= p->linesize[i]; + + for(y=0; y<v; y++){ + for(x=0; x<h; x++){ + int pred; + + ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap + if(y==0 && mb_y==0){ + if(x==0 && mb_x==0){ + pred= 128; + }else{ + pred= ptr[-1]; + } + }else{ + if(x==0 && mb_x==0){ + pred= ptr[-linesize]; + }else{ + PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); + } + } + + if(i==0) + ff_mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly + else + ff_mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); + } + } + } + }else{ + for(i=0;i<3;i++) { + uint8_t *ptr; + int x, y, h, v, linesize; + h = s->mjpeg_hsample[i]; + v = s->mjpeg_vsample[i]; + linesize= p->linesize[i]; + + for(y=0; y<v; y++){ + for(x=0; x<h; x++){ + int pred; + + ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap +//printf("%d %d %d %d %8X\n", mb_x, mb_y, x, y, ptr); + PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); + + if(i==0) + ff_mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly + else + ff_mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); + } + } + } + } + } + } + } + + emms_c(); + + ff_mjpeg_encode_picture_trailer(s); + s->picture_number++; + + flush_put_bits(&s->pb); + return pbBufPtr(&s->pb) - s->pb.buf; +// return (put_bits_count(&f->pb)+7)/8; +} + + +AVCodec ljpeg_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them + "ljpeg", + CODEC_TYPE_VIDEO, + CODEC_ID_LJPEG, + sizeof(MpegEncContext), + MPV_encode_init, + encode_picture_lossless, + MPV_encode_end, +}; diff --git a/contrib/ffmpeg/libavcodec/loco.c b/contrib/ffmpeg/libavcodec/loco.c index 760699d45..14be6f019 100644 --- a/contrib/ffmpeg/libavcodec/loco.c +++ b/contrib/ffmpeg/libavcodec/loco.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -26,7 +25,6 @@ */ #include "avcodec.h" -#include "common.h" #include "bitstream.h" #include "golomb.h" @@ -118,7 +116,7 @@ static inline int loco_predict(uint8_t* data, int stride, int step) } static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int height, - int stride, uint8_t *buf, int buf_size, int step) + int stride, const uint8_t *buf, int buf_size, int step) { RICEContext rc; int val; @@ -159,7 +157,7 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { LOCOContext * const l = avctx->priv_data; AVFrame * const p= (AVFrame*)&l->pic; diff --git a/contrib/ffmpeg/libavcodec/lzw.c b/contrib/ffmpeg/libavcodec/lzw.c index 6bc0b9a48..833c9d0ab 100644 --- a/contrib/ffmpeg/libavcodec/lzw.c +++ b/contrib/ffmpeg/libavcodec/lzw.c @@ -42,7 +42,7 @@ static const uint16_t mask[17] = }; struct LZWState { - uint8_t *pbuf, *ebuf; + const uint8_t *pbuf, *ebuf; int bbits; unsigned int bbuf; @@ -91,7 +91,7 @@ static int lzw_get_code(struct LZWState * s) return c & s->curmask; } -uint8_t* ff_lzw_cur_ptr(LZWState *p) +const uint8_t* ff_lzw_cur_ptr(LZWState *p) { return ((struct LZWState*)p)->pbuf; } @@ -127,7 +127,7 @@ void ff_lzw_decode_close(LZWState **p) * @param buf_size input data size * @param mode decoder working mode - either GIF or TIFF */ -int ff_lzw_decode_init(LZWState *p, int csize, uint8_t *buf, int buf_size, int mode) +int ff_lzw_decode_init(LZWState *p, int csize, const uint8_t *buf, int buf_size, int mode) { struct LZWState *s = (struct LZWState *)p; diff --git a/contrib/ffmpeg/libavcodec/lzw.h b/contrib/ffmpeg/libavcodec/lzw.h index 60f115caf..161f0dce5 100644 --- a/contrib/ffmpeg/libavcodec/lzw.h +++ b/contrib/ffmpeg/libavcodec/lzw.h @@ -27,8 +27,10 @@ * Modified for use in TIFF by Konstantin Shishkov */ -#ifndef LZW_H -#define LZW_H +#ifndef FFMPEG_LZW_H +#define FFMPEG_LZW_H + +#include "bitstream.h" enum FF_LZW_MODES{ FF_LZW_GIF, @@ -41,9 +43,17 @@ typedef void LZWState; /* first two functions de/allocate memory for LZWState */ void ff_lzw_decode_open(LZWState **p); void ff_lzw_decode_close(LZWState **p); -int ff_lzw_decode_init(LZWState *s, int csize, uint8_t *buf, int buf_size, int mode); +int ff_lzw_decode_init(LZWState *s, int csize, const uint8_t *buf, int buf_size, int mode); int ff_lzw_decode(LZWState *s, uint8_t *buf, int len); -uint8_t* ff_lzw_cur_ptr(LZWState *lzw); +const uint8_t* ff_lzw_cur_ptr(LZWState *lzw); void ff_lzw_decode_tail(LZWState *lzw); -#endif +/** LZW encode state */ +struct LZWEncodeState; +extern const int ff_lzw_encode_state_size; + +void ff_lzw_encode_init(struct LZWEncodeState * s, uint8_t * outbuf, int outsize, int maxbits); +int ff_lzw_encode(struct LZWEncodeState * s, const uint8_t * inbuf, int insize); +int ff_lzw_encode_flush(struct LZWEncodeState * s); + +#endif /* FFMPEG_LZW_H */ diff --git a/contrib/ffmpeg/libavcodec/lzwenc.c b/contrib/ffmpeg/libavcodec/lzwenc.c new file mode 100644 index 000000000..3a24af347 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/lzwenc.c @@ -0,0 +1,262 @@ +/* + * LZW encoder + * Copyright (c) 2007 Bartlomiej Wolowiec + * + * 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 + */ + +/** + * LZW encoder + * @file lzwenc.c + * @author Bartlomiej Wolowiec + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "lzw.h" + +#define LZW_MAXBITS 12 +#define LZW_SIZTABLE (1<<LZW_MAXBITS) +#define LZW_HASH_SIZE 16411 +#define LZW_HASH_SHIFT 6 + +#define LZW_PREFIX_EMPTY -1 +#define LZW_PREFIX_FREE -2 + +/** One code in hash table */ +typedef struct Code{ + /// Hash code of prefix, LZW_PREFIX_EMPTY if empty prefix, or LZW_PREFIX_FREE if no code + int hash_prefix; + int code; ///< LZW code + uint8_t suffix; ///< Last character in code block +}Code; + +/** LZW encode state */ +typedef struct LZWEncodeState { + int clear_code; ///< Value of clear code + int end_code; ///< Value of end code + Code tab[LZW_HASH_SIZE]; ///< Hash table + int tabsize; ///< Number of values in hash table + int bits; ///< Actual bits code + int bufsize; ///< Size of output buffer + PutBitContext pb; ///< Put bit context for output + int maxbits; ///< Max bits code + int maxcode; ///< Max value of code + int output_bytes; ///< Number of written bytes + int last_code; ///< Value of last output code or LZW_PREFIX_EMPTY +}LZWEncodeState; + + +const int ff_lzw_encode_state_size = sizeof(LZWEncodeState); + +/** + * Hash function adding character + * @param head LZW code for prefix + * @param add Character to add + * @return New hash value + */ +static inline int hash(int head, const int add) +{ + head ^= (add << LZW_HASH_SHIFT); + if (head >= LZW_HASH_SIZE) + head -= LZW_HASH_SIZE; + assert(head >= 0 && head < LZW_HASH_SIZE); + return head; +} + +/** + * Hash function calculates next hash value + * @param head Actual hash code + * @param offset Offset calculated by hashOffset + * @return New hash value + */ +static inline int hashNext(int head, const int offset) +{ + head -= offset; + if(head < 0) + head += LZW_HASH_SIZE; + return head; +} + +/** + * Hash function calculates hash offset + * @param head Actual hash code + * @return Hash offset + */ +static inline int hashOffset(const int head) +{ + return head ? LZW_HASH_SIZE - head : 1; +} + +/** + * Write one code to stream + * @param s LZW state + * @param c code to write + */ +static inline void writeCode(LZWEncodeState * s, int c) +{ + assert(0 <= c && c < 1 << s->bits); + put_bits(&s->pb, s->bits, c); +} + + +/** + * Find LZW code for block + * @param s LZW state + * @param c Last character in block + * @param hash_prefix LZW code for prefix + * @return LZW code for block or -1 if not found in table + */ +static inline int findCode(LZWEncodeState * s, uint8_t c, int hash_prefix) +{ + int h = hash(FFMAX(hash_prefix, 0), c); + int hash_offset = hashOffset(h); + + while (s->tab[h].hash_prefix != LZW_PREFIX_FREE) { + if ((s->tab[h].suffix == c) + && (s->tab[h].hash_prefix == hash_prefix)) + return h; + h = hashNext(h, hash_offset); + } + + return h; +} + +/** + * Add block to LZW code table + * @param s LZW state + * @param c Last character in block + * @param hash_prefix LZW code for prefix + * @param hash_code LZW code for bytes block + */ +static inline void addCode(LZWEncodeState * s, uint8_t c, int hash_prefix, int hash_code) +{ + s->tab[hash_code].code = s->tabsize; + s->tab[hash_code].suffix = c; + s->tab[hash_code].hash_prefix = hash_prefix; + + s->tabsize++; + + if (s->tabsize >= 1 << s->bits) + s->bits++; +} + +/** + * Clear LZW code table + * @param s LZW state + */ +static void clearTable(LZWEncodeState * s) +{ + int i, h; + + writeCode(s, s->clear_code); + s->bits = 9; + for (i = 0; i < LZW_HASH_SIZE; i++) { + s->tab[i].hash_prefix = LZW_PREFIX_FREE; + } + for (i = 0; i < 256; i++) { + h = hash(0, i); + s->tab[h].code = i; + s->tab[h].suffix = i; + s->tab[h].hash_prefix = LZW_PREFIX_EMPTY; + } + s->tabsize = 258; +} + +/** + * Calculate number of bytes written + * @param s LZW encode state + * @return Number of bytes written + */ +static int writtenBytes(LZWEncodeState *s){ + int ret = put_bits_count(&s->pb) >> 3; + ret -= s->output_bytes; + s->output_bytes += ret; + return ret; +} + +/** + * Initialize LZW encoder. Please set s->clear_code, s->end_code and s->maxbits before run. + * @param s LZW state + * @param outbuf Output buffer + * @param outsize Size of output buffer + * @param maxbits Maximum length of code + */ +void ff_lzw_encode_init(LZWEncodeState * s, uint8_t * outbuf, int outsize, int maxbits) +{ + s->clear_code = 256; + s->end_code = 257; + s->maxbits = maxbits; + init_put_bits(&s->pb, outbuf, outsize); + s->bufsize = outsize; + assert(9 <= s->maxbits && s->maxbits <= s->maxbits); + s->maxcode = 1 << s->maxbits; + s->output_bytes = 0; + s->last_code = LZW_PREFIX_EMPTY; + s->bits = 9; +} + +/** + * LZW main compress function + * @param s LZW state + * @param inbuf Input buffer + * @param insize Size of input buffer + * @return Number of bytes written or -1 on error + */ +int ff_lzw_encode(LZWEncodeState * s, const uint8_t * inbuf, int insize) +{ + int i; + + if(insize * 3 > (s->bufsize - s->output_bytes) * 2){ + return -1; + } + + if (s->last_code == LZW_PREFIX_EMPTY) + clearTable(s); + + for (i = 0; i < insize; i++) { + uint8_t c = *inbuf++; + int code = findCode(s, c, s->last_code); + if (s->tab[code].hash_prefix == LZW_PREFIX_FREE) { + writeCode(s, s->last_code); + addCode(s, c, s->last_code, code); + code= hash(0, c); + } + s->last_code = s->tab[code].code; + if (s->tabsize >= s->maxcode - 1) { + clearTable(s); + } + } + + return writtenBytes(s); +} + +/** + * Write end code and flush bitstream + * @param s LZW state + * @return Number of bytes written or -1 on error + */ +int ff_lzw_encode_flush(LZWEncodeState * s) +{ + if (s->last_code != -1) + writeCode(s, s->last_code); + writeCode(s, s->end_code); + flush_put_bits(&s->pb); + s->last_code = -1; + + return writtenBytes(s); +} diff --git a/contrib/ffmpeg/libavcodec/mace.c b/contrib/ffmpeg/libavcodec/mace.c index 95839379a..7256f7678 100644 --- a/contrib/ffmpeg/libavcodec/mace.c +++ b/contrib/ffmpeg/libavcodec/mace.c @@ -263,7 +263,7 @@ static void chomp3(MACEContext *ctx, /* /// "Exp1to3()" */ static void Exp1to3(MACEContext *ctx, - uint8_t *inBuffer, + const uint8_t *inBuffer, void *outBuffer, uint32_t cnt, uint32_t numChannels, @@ -347,7 +347,7 @@ static void chomp6(MACEContext *ctx, /* /// "Exp1to6()" */ static void Exp1to6(MACEContext *ctx, - uint8_t *inBuffer, + const uint8_t *inBuffer, void *outBuffer, uint32_t cnt, uint32_t numChannels, @@ -401,7 +401,7 @@ static int mace_decode_init(AVCodecContext * avctx) static int mace_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { short *samples; MACEContext *c = avctx->priv_data; @@ -409,18 +409,14 @@ static int mace_decode_frame(AVCodecContext *avctx, samples = (short *)data; switch (avctx->codec->id) { case CODEC_ID_MACE3: -#ifdef DEBUG -puts("mace_decode_frame[3]()"); -#endif + dprintf(avctx, "mace_decode_frame[3]()"); Exp1to3(c, buf, samples, buf_size / 2 / avctx->channels, avctx->channels, 1); if (avctx->channels == 2) Exp1to3(c, buf, samples+1, buf_size / 2 / 2, 2, 2); *data_size = 2 * 3 * buf_size; break; case CODEC_ID_MACE6: -#ifdef DEBUG -puts("mace_decode_frame[6]()"); -#endif + dprintf(avctx, "mace_decode_frame[6]()"); Exp1to6(c, buf, samples, buf_size / avctx->channels, avctx->channels, 1); if (avctx->channels == 2) Exp1to6(c, buf, samples+1, buf_size / 2, 2, 2); diff --git a/contrib/ffmpeg/libavcodec/mathops.h b/contrib/ffmpeg/libavcodec/mathops.h index c6ec70597..38b1f5c65 100644 --- a/contrib/ffmpeg/libavcodec/mathops.h +++ b/contrib/ffmpeg/libavcodec/mathops.h @@ -19,8 +19,10 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef MATHOPS_H -#define MATHOPS_H +#ifndef FFMPEG_MATHOPS_H +#define FFMPEG_MATHOPS_H + +#include "common.h" #ifdef ARCH_X86_32 @@ -34,6 +36,10 @@ #include "ppc/mathops.h" +#elif defined(ARCH_BFIN) + +#include "bfin/mathops.h" + #endif /* generic implementation */ @@ -65,5 +71,5 @@ static av_always_inline int MULH(int a, int b){ # define MUL16(ra, rb) ((ra) * (rb)) #endif -#endif //MATHOPS_H +#endif /* FFMPEG_MATHOPS_H */ diff --git a/contrib/ffmpeg/libavcodec/mdct.c b/contrib/ffmpeg/libavcodec/mdct.c index de3275289..e809fcdcb 100644 --- a/contrib/ffmpeg/libavcodec/mdct.c +++ b/contrib/ffmpeg/libavcodec/mdct.c @@ -25,6 +25,29 @@ * MDCT/IMDCT transforms. */ +// Generate a Kaiser-Bessel Derived Window. +#define BESSEL_I0_ITER 50 // default: 50 iterations of Bessel I0 approximation +void ff_kbd_window_init(float *window, float alpha, int n) +{ + int i, j; + double sum = 0.0, bessel, tmp; + double local_window[n]; + double alpha2 = (alpha * M_PI / n) * (alpha * M_PI / n); + + for (i = 0; i < n; i++) { + tmp = i * (n - i) * alpha2; + bessel = 1.0; + for (j = BESSEL_I0_ITER; j > 0; j--) + bessel = bessel * tmp / (j * j) + 1; + sum += bessel; + local_window[i] = sum; + } + + sum++; + for (i = 0; i < n; i++) + window[i] = sqrt(local_window[i] / sum); +} + /** * init MDCT or IMDCT computation. */ diff --git a/contrib/ffmpeg/libavcodec/mdec.c b/contrib/ffmpeg/libavcodec/mdec.c index ee43b2777..ed2476213 100644 --- a/contrib/ffmpeg/libavcodec/mdec.c +++ b/contrib/ffmpeg/libavcodec/mdec.c @@ -2,6 +2,8 @@ * PSX MDEC codec * Copyright (c) 2003 Michael Niedermayer * + * based upon code from Sebastian Jedruszkiewicz <elf@frogger.rules.pl> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -17,8 +19,6 @@ * 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 - * - * based upon code from Sebastian Jedruszkiewicz <elf@frogger.rules.pl> */ /** @@ -60,7 +60,7 @@ static inline int mdec_decode_block_intra(MDECContext *a, DCTELEM *block, int n) { int level, diff, i, j, run; int component; - RLTable *rl = &rl_mpeg1; + RLTable *rl = &ff_rl_mpeg1; uint8_t * const scantable= a->scantable.permutated; const uint16_t *quant_matrix= ff_mpeg1_default_intra_matrix; const int qscale= a->qscale; @@ -158,7 +158,7 @@ static inline void idct_put(MDECContext *a, int mb_x, int mb_y){ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { MDECContext * const a = avctx->priv_data; AVFrame *picture = data; @@ -175,9 +175,6 @@ static int decode_frame(AVCodecContext *avctx, } p->pict_type= I_TYPE; p->key_frame= 1; - a->last_dc[0]= - a->last_dc[1]= - a->last_dc[2]= 0; a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); for(i=0; i<buf_size; i+=2){ @@ -192,6 +189,10 @@ static int decode_frame(AVCodecContext *avctx, a->qscale= get_bits(&a->gb, 16); a->version= get_bits(&a->gb, 16); + a->last_dc[0]= + a->last_dc[1]= + a->last_dc[2]= 128; + // printf("qscale:%d (0x%X), version:%d (0x%X)\n", a->qscale, a->qscale, a->version, a->version); for(a->mb_x=0; a->mb_x<a->mb_width; a->mb_x++){ diff --git a/contrib/ffmpeg/libavcodec/mjpeg.c b/contrib/ffmpeg/libavcodec/mjpeg.c index e3583e54e..08ffb95a7 100644 --- a/contrib/ffmpeg/libavcodec/mjpeg.c +++ b/contrib/ffmpeg/libavcodec/mjpeg.c @@ -4,6 +4,10 @@ * Copyright (c) 2003 Alex Beregszaszi * Copyright (c) 2003-2004 Michael Niedermayer * + * Support for external huffman table, various fixes (AVID workaround), + * aspecting, new decode_frame mechanism and apple mjpeg-b support + * by Alex Beregszaszi + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -19,10 +23,6 @@ * 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 - * - * Support for external huffman table, various fixes (AVID workaround), - * aspecting, new decode_frame mechanism and apple mjpeg-b support - * by Alex Beregszaszi <alex@naxine.org> */ /** @@ -30,118 +30,15 @@ * MJPEG encoder and decoder. */ -//#define DEBUG -#include <assert.h> - -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "bytestream.h" - -/* use two quantizer tables (one for luminance and one for chrominance) */ -/* not yet working */ -#undef TWOMATRIXES - -typedef struct MJpegContext { - uint8_t huff_size_dc_luminance[12]; //FIXME use array [3] instead of lumi / chrom, for easier addressing - uint16_t huff_code_dc_luminance[12]; - uint8_t huff_size_dc_chrominance[12]; - uint16_t huff_code_dc_chrominance[12]; - - uint8_t huff_size_ac_luminance[256]; - uint16_t huff_code_ac_luminance[256]; - uint8_t huff_size_ac_chrominance[256]; - uint16_t huff_code_ac_chrominance[256]; -} MJpegContext; - -/* JPEG marker codes */ -typedef enum { - /* start of frame */ - SOF0 = 0xc0, /* baseline */ - SOF1 = 0xc1, /* extended sequential, huffman */ - SOF2 = 0xc2, /* progressive, huffman */ - SOF3 = 0xc3, /* lossless, huffman */ - - SOF5 = 0xc5, /* differential sequential, huffman */ - SOF6 = 0xc6, /* differential progressive, huffman */ - SOF7 = 0xc7, /* differential lossless, huffman */ - JPG = 0xc8, /* reserved for JPEG extension */ - SOF9 = 0xc9, /* extended sequential, arithmetic */ - SOF10 = 0xca, /* progressive, arithmetic */ - SOF11 = 0xcb, /* lossless, arithmetic */ - - SOF13 = 0xcd, /* differential sequential, arithmetic */ - SOF14 = 0xce, /* differential progressive, arithmetic */ - SOF15 = 0xcf, /* differential lossless, arithmetic */ - - DHT = 0xc4, /* define huffman tables */ - - DAC = 0xcc, /* define arithmetic-coding conditioning */ - - /* restart with modulo 8 count "m" */ - RST0 = 0xd0, - RST1 = 0xd1, - RST2 = 0xd2, - RST3 = 0xd3, - RST4 = 0xd4, - RST5 = 0xd5, - RST6 = 0xd6, - RST7 = 0xd7, - - SOI = 0xd8, /* start of image */ - EOI = 0xd9, /* end of image */ - SOS = 0xda, /* start of scan */ - DQT = 0xdb, /* define quantization tables */ - DNL = 0xdc, /* define number of lines */ - DRI = 0xdd, /* define restart interval */ - DHP = 0xde, /* define hierarchical progression */ - EXP = 0xdf, /* expand reference components */ - - APP0 = 0xe0, - APP1 = 0xe1, - APP2 = 0xe2, - APP3 = 0xe3, - APP4 = 0xe4, - APP5 = 0xe5, - APP6 = 0xe6, - APP7 = 0xe7, - APP8 = 0xe8, - APP9 = 0xe9, - APP10 = 0xea, - APP11 = 0xeb, - APP12 = 0xec, - APP13 = 0xed, - APP14 = 0xee, - APP15 = 0xef, +#include "mjpeg.h" - JPG0 = 0xf0, - JPG1 = 0xf1, - JPG2 = 0xf2, - JPG3 = 0xf3, - JPG4 = 0xf4, - JPG5 = 0xf5, - JPG6 = 0xf6, - SOF48 = 0xf7, ///< JPEG-LS - LSE = 0xf8, ///< JPEG-LS extension parameters - JPG9 = 0xf9, - JPG10 = 0xfa, - JPG11 = 0xfb, - JPG12 = 0xfc, - JPG13 = 0xfd, - - COM = 0xfe, /* comment */ - - TEM = 0x01, /* temporary private use for arithmetic coding */ - - /* 0x02 -> 0xbf reserved */ -} JPEG_MARKER; #if 0 /* These are the sample quantization tables given in JPEG spec section K.1. * The spec says that the values given produce "good" quality, and * when divided by 2, "very good" quality. */ -static const unsigned char std_luminance_quant_tbl[64] = { +const unsigned char std_luminance_quant_tbl[64] = { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, @@ -151,7 +48,7 @@ static const unsigned char std_luminance_quant_tbl[64] = { 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99 }; -static const unsigned char std_chrominance_quant_tbl[64] = { +const unsigned char std_chrominance_quant_tbl[64] = { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, @@ -165,19 +62,19 @@ static const unsigned char std_chrominance_quant_tbl[64] = { /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ /* IMPORTANT: these are only valid for 8-bit data precision! */ -static const uint8_t bits_dc_luminance[17] = +const uint8_t ff_mjpeg_bits_dc_luminance[17] = { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; -static const uint8_t val_dc_luminance[] = +const uint8_t ff_mjpeg_val_dc_luminance[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; -static const uint8_t bits_dc_chrominance[17] = +const uint8_t ff_mjpeg_bits_dc_chrominance[17] = { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; -static const uint8_t val_dc_chrominance[] = +const uint8_t ff_mjpeg_val_dc_chrominance[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; -static const uint8_t bits_ac_luminance[17] = +const uint8_t ff_mjpeg_bits_ac_luminance[17] = { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; -static const uint8_t val_ac_luminance[] = +const uint8_t ff_mjpeg_val_ac_luminance[] = { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, @@ -201,10 +98,10 @@ static const uint8_t val_ac_luminance[] = 0xf9, 0xfa }; -static const uint8_t bits_ac_chrominance[17] = +const uint8_t ff_mjpeg_bits_ac_chrominance[17] = { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; -static const uint8_t val_ac_chrominance[] = +const uint8_t ff_mjpeg_val_ac_chrominance[] = { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, @@ -229,8 +126,9 @@ static const uint8_t val_ac_chrominance[] = }; /* isn't this function nicer than the one in the libjpeg ? */ -static void build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, - const uint8_t *bits_table, const uint8_t *val_table) +void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, + const uint8_t *bits_table, + const uint8_t *val_table) { int i, j, k,nb, code, sym; @@ -247,2405 +145,3 @@ static void build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, code <<= 1; } } - -#ifdef CONFIG_ENCODERS -int mjpeg_init(MpegEncContext *s) -{ - MJpegContext *m; - - m = av_malloc(sizeof(MJpegContext)); - if (!m) - return -1; - - s->min_qcoeff=-1023; - s->max_qcoeff= 1023; - - /* build all the huffman tables */ - build_huffman_codes(m->huff_size_dc_luminance, - m->huff_code_dc_luminance, - bits_dc_luminance, - val_dc_luminance); - build_huffman_codes(m->huff_size_dc_chrominance, - m->huff_code_dc_chrominance, - bits_dc_chrominance, - val_dc_chrominance); - build_huffman_codes(m->huff_size_ac_luminance, - m->huff_code_ac_luminance, - bits_ac_luminance, - val_ac_luminance); - build_huffman_codes(m->huff_size_ac_chrominance, - m->huff_code_ac_chrominance, - bits_ac_chrominance, - val_ac_chrominance); - - s->mjpeg_ctx = m; - return 0; -} - -void mjpeg_close(MpegEncContext *s) -{ - av_free(s->mjpeg_ctx); -} -#endif //CONFIG_ENCODERS - -#define PREDICT(ret, topleft, top, left, predictor)\ - switch(predictor){\ - case 1: ret= left; break;\ - case 2: ret= top; break;\ - case 3: ret= topleft; break;\ - case 4: ret= left + top - topleft; break;\ - case 5: ret= left + ((top - topleft)>>1); break;\ - case 6: ret= top + ((left - topleft)>>1); break;\ - default:\ - case 7: ret= (left + top)>>1; break;\ - } - -#ifdef CONFIG_ENCODERS -static inline void put_marker(PutBitContext *p, int code) -{ - put_bits(p, 8, 0xff); - put_bits(p, 8, code); -} - -/* table_class: 0 = DC coef, 1 = AC coefs */ -static int put_huffman_table(MpegEncContext *s, int table_class, int table_id, - const uint8_t *bits_table, const uint8_t *value_table) -{ - PutBitContext *p = &s->pb; - int n, i; - - put_bits(p, 4, table_class); - put_bits(p, 4, table_id); - - n = 0; - for(i=1;i<=16;i++) { - n += bits_table[i]; - put_bits(p, 8, bits_table[i]); - } - - for(i=0;i<n;i++) - put_bits(p, 8, value_table[i]); - - return n + 17; -} - -static void jpeg_table_header(MpegEncContext *s) -{ - PutBitContext *p = &s->pb; - int i, j, size; - uint8_t *ptr; - - /* quant matrixes */ - put_marker(p, DQT); -#ifdef TWOMATRIXES - put_bits(p, 16, 2 + 2 * (1 + 64)); -#else - put_bits(p, 16, 2 + 1 * (1 + 64)); -#endif - put_bits(p, 4, 0); /* 8 bit precision */ - put_bits(p, 4, 0); /* table 0 */ - for(i=0;i<64;i++) { - j = s->intra_scantable.permutated[i]; - put_bits(p, 8, s->intra_matrix[j]); - } -#ifdef TWOMATRIXES - put_bits(p, 4, 0); /* 8 bit precision */ - put_bits(p, 4, 1); /* table 1 */ - for(i=0;i<64;i++) { - j = s->intra_scantable.permutated[i]; - put_bits(p, 8, s->chroma_intra_matrix[j]); - } -#endif - - /* huffman table */ - put_marker(p, DHT); - flush_put_bits(p); - ptr = pbBufPtr(p); - put_bits(p, 16, 0); /* patched later */ - size = 2; - size += put_huffman_table(s, 0, 0, bits_dc_luminance, val_dc_luminance); - size += put_huffman_table(s, 0, 1, bits_dc_chrominance, val_dc_chrominance); - - size += put_huffman_table(s, 1, 0, bits_ac_luminance, val_ac_luminance); - size += put_huffman_table(s, 1, 1, bits_ac_chrominance, val_ac_chrominance); - ptr[0] = size >> 8; - ptr[1] = size; -} - -static void jpeg_put_comments(MpegEncContext *s) -{ - PutBitContext *p = &s->pb; - int size; - uint8_t *ptr; - - if (s->aspect_ratio_info /* && !lossless */) - { - /* JFIF header */ - put_marker(p, APP0); - put_bits(p, 16, 16); - ff_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ - put_bits(p, 16, 0x0201); /* v 1.02 */ - put_bits(p, 8, 0); /* units type: 0 - aspect ratio */ - put_bits(p, 16, s->avctx->sample_aspect_ratio.num); - put_bits(p, 16, s->avctx->sample_aspect_ratio.den); - put_bits(p, 8, 0); /* thumbnail width */ - put_bits(p, 8, 0); /* thumbnail height */ - } - - /* comment */ - if(!(s->flags & CODEC_FLAG_BITEXACT)){ - put_marker(p, COM); - flush_put_bits(p); - ptr = pbBufPtr(p); - put_bits(p, 16, 0); /* patched later */ - ff_put_string(p, LIBAVCODEC_IDENT, 1); - size = strlen(LIBAVCODEC_IDENT)+3; - ptr[0] = size >> 8; - ptr[1] = size; - } - - if( s->avctx->pix_fmt == PIX_FMT_YUV420P - ||s->avctx->pix_fmt == PIX_FMT_YUV422P - ||s->avctx->pix_fmt == PIX_FMT_YUV444P){ - put_marker(p, COM); - flush_put_bits(p); - ptr = pbBufPtr(p); - put_bits(p, 16, 0); /* patched later */ - ff_put_string(p, "CS=ITU601", 1); - size = strlen("CS=ITU601")+3; - ptr[0] = size >> 8; - ptr[1] = size; - } -} - -void mjpeg_picture_header(MpegEncContext *s) -{ - const int lossless= s->avctx->codec_id != CODEC_ID_MJPEG; - const int ls = s->avctx->codec_id == CODEC_ID_JPEGLS; - - assert(!(ls && s->mjpeg_write_tables)); - - put_marker(&s->pb, SOI); - - if (!s->mjpeg_data_only_frames) - { - jpeg_put_comments(s); - - if (s->mjpeg_write_tables) jpeg_table_header(s); - - switch(s->avctx->codec_id){ - case CODEC_ID_MJPEG: put_marker(&s->pb, SOF0 ); break; - case CODEC_ID_LJPEG: put_marker(&s->pb, SOF3 ); break; - case CODEC_ID_JPEGLS: put_marker(&s->pb, SOF48); break; - default: assert(0); - } - - put_bits(&s->pb, 16, 17); - if(lossless && s->avctx->pix_fmt == PIX_FMT_RGB32) - put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */ - else - put_bits(&s->pb, 8, 8); /* 8 bits/component */ - put_bits(&s->pb, 16, s->height); - put_bits(&s->pb, 16, s->width); - put_bits(&s->pb, 8, 3); /* 3 components */ - - /* Y component */ - put_bits(&s->pb, 8, 1); /* component number */ - put_bits(&s->pb, 4, s->mjpeg_hsample[0]); /* H factor */ - put_bits(&s->pb, 4, s->mjpeg_vsample[0]); /* V factor */ - put_bits(&s->pb, 8, 0); /* select matrix */ - - /* Cb component */ - put_bits(&s->pb, 8, 2); /* component number */ - put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */ - put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */ -#ifdef TWOMATRIXES - put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ -#else - put_bits(&s->pb, 8, 0); /* select matrix */ -#endif - - /* Cr component */ - put_bits(&s->pb, 8, 3); /* component number */ - put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */ - put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */ -#ifdef TWOMATRIXES - put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ -#else - put_bits(&s->pb, 8, 0); /* select matrix */ -#endif - } - - /* scan header */ - put_marker(&s->pb, SOS); - put_bits(&s->pb, 16, 12); /* length */ - put_bits(&s->pb, 8, 3); /* 3 components */ - - /* Y component */ - put_bits(&s->pb, 8, 1); /* index */ - put_bits(&s->pb, 4, 0); /* DC huffman table index */ - put_bits(&s->pb, 4, 0); /* AC huffman table index */ - - /* Cb component */ - put_bits(&s->pb, 8, 2); /* index */ - put_bits(&s->pb, 4, 1); /* DC huffman table index */ - put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ - - /* Cr component */ - put_bits(&s->pb, 8, 3); /* index */ - put_bits(&s->pb, 4, 1); /* DC huffman table index */ - put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ - - put_bits(&s->pb, 8, (lossless && !ls) ? s->avctx->prediction_method+1 : 0); /* Ss (not used) */ - - switch(s->avctx->codec_id){ - case CODEC_ID_MJPEG: put_bits(&s->pb, 8, 63); break; /* Se (not used) */ - case CODEC_ID_LJPEG: put_bits(&s->pb, 8, 0); break; /* not used */ - case CODEC_ID_JPEGLS: put_bits(&s->pb, 8, 1); break; /* ILV = line interleaved */ - default: assert(0); - } - - put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ - - //FIXME DC/AC entropy table selectors stuff in jpegls -} - -static void escape_FF(MpegEncContext *s, int start) -{ - int size= put_bits_count(&s->pb) - start*8; - int i, ff_count; - uint8_t *buf= s->pb.buf + start; - int align= (-(size_t)(buf))&3; - - assert((size&7) == 0); - size >>= 3; - - ff_count=0; - for(i=0; i<size && i<align; i++){ - if(buf[i]==0xFF) ff_count++; - } - for(; i<size-15; i+=16){ - int acc, v; - - v= *(uint32_t*)(&buf[i]); - acc= (((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; - v= *(uint32_t*)(&buf[i+4]); - acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; - v= *(uint32_t*)(&buf[i+8]); - acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; - v= *(uint32_t*)(&buf[i+12]); - acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; - - acc>>=4; - acc+= (acc>>16); - acc+= (acc>>8); - ff_count+= acc&0xFF; - } - for(; i<size; i++){ - if(buf[i]==0xFF) ff_count++; - } - - if(ff_count==0) return; - - /* skip put bits */ - for(i=0; i<ff_count-3; i+=4) - put_bits(&s->pb, 32, 0); - put_bits(&s->pb, (ff_count-i)*8, 0); - flush_put_bits(&s->pb); - - for(i=size-1; ff_count; i--){ - int v= buf[i]; - - if(v==0xFF){ -//printf("%d %d\n", i, ff_count); - buf[i+ff_count]= 0; - ff_count--; - } - - buf[i+ff_count]= v; - } -} - -void ff_mjpeg_stuffing(PutBitContext * pbc) -{ - int length; - length= (-put_bits_count(pbc))&7; - if(length) put_bits(pbc, length, (1<<length)-1); -} - -void mjpeg_picture_trailer(MpegEncContext *s) -{ - ff_mjpeg_stuffing(&s->pb); - flush_put_bits(&s->pb); - - assert((s->header_bits&7)==0); - - escape_FF(s, s->header_bits>>3); - - put_marker(&s->pb, EOI); -} - -static inline void mjpeg_encode_dc(MpegEncContext *s, int val, - uint8_t *huff_size, uint16_t *huff_code) -{ - int mant, nbits; - - if (val == 0) { - put_bits(&s->pb, huff_size[0], huff_code[0]); - } else { - mant = val; - if (val < 0) { - val = -val; - mant--; - } - - nbits= av_log2_16bit(val) + 1; - - put_bits(&s->pb, huff_size[nbits], huff_code[nbits]); - - put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); - } -} - -static void encode_block(MpegEncContext *s, DCTELEM *block, int n) -{ - int mant, nbits, code, i, j; - int component, dc, run, last_index, val; - MJpegContext *m = s->mjpeg_ctx; - uint8_t *huff_size_ac; - uint16_t *huff_code_ac; - - /* DC coef */ - component = (n <= 3 ? 0 : (n&1) + 1); - dc = block[0]; /* overflow is impossible */ - val = dc - s->last_dc[component]; - if (n < 4) { - mjpeg_encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance); - huff_size_ac = m->huff_size_ac_luminance; - huff_code_ac = m->huff_code_ac_luminance; - } else { - mjpeg_encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - huff_size_ac = m->huff_size_ac_chrominance; - huff_code_ac = m->huff_code_ac_chrominance; - } - s->last_dc[component] = dc; - - /* AC coefs */ - - run = 0; - last_index = s->block_last_index[n]; - for(i=1;i<=last_index;i++) { - j = s->intra_scantable.permutated[i]; - val = block[j]; - if (val == 0) { - run++; - } else { - while (run >= 16) { - put_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]); - run -= 16; - } - mant = val; - if (val < 0) { - val = -val; - mant--; - } - - nbits= av_log2(val) + 1; - code = (run << 4) | nbits; - - put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]); - - put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); - run = 0; - } - } - - /* output EOB only if not already 64 values */ - if (last_index < 63 || run != 0) - put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]); -} - -void mjpeg_encode_mb(MpegEncContext *s, - DCTELEM block[6][64]) -{ - int i; - for(i=0;i<5;i++) { - encode_block(s, block[i], i); - } - if (s->chroma_format == CHROMA_420) { - encode_block(s, block[5], 5); - } else { - encode_block(s, block[6], 6); - encode_block(s, block[5], 5); - encode_block(s, block[7], 7); - } -} - -static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - MpegEncContext * const s = avctx->priv_data; - MJpegContext * const m = s->mjpeg_ctx; - AVFrame *pict = data; - const int width= s->width; - const int height= s->height; - AVFrame * const p= (AVFrame*)&s->current_picture; - const int predictor= avctx->prediction_method+1; - - init_put_bits(&s->pb, buf, buf_size); - - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - mjpeg_picture_header(s); - - s->header_bits= put_bits_count(&s->pb); - - if(avctx->pix_fmt == PIX_FMT_RGB32){ - int x, y, i; - const int linesize= p->linesize[0]; - uint16_t (*buffer)[4]= (void *) s->rd_scratchpad; - int left[3], top[3], topleft[3]; - - for(i=0; i<3; i++){ - buffer[0][i]= 1 << (9 - 1); - } - - for(y = 0; y < height; y++) { - const int modified_predictor= y ? predictor : 1; - uint8_t *ptr = p->data[0] + (linesize * y); - - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - for(i=0; i<3; i++){ - top[i]= left[i]= topleft[i]= buffer[0][i]; - } - for(x = 0; x < width; x++) { - buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100; - buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100; - buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2; - - for(i=0;i<3;i++) { - int pred, diff; - - PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); - - topleft[i]= top[i]; - top[i]= buffer[x+1][i]; - - left[i]= buffer[x][i]; - - diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100; - - if(i==0) - mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly - else - mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - } - } - } - }else{ - int mb_x, mb_y, i; - const int mb_width = (width + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0]; - const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0]; - - for(mb_y = 0; mb_y < mb_height; mb_y++) { - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - for(mb_x = 0; mb_x < mb_width; mb_x++) { - if(mb_x==0 || mb_y==0){ - for(i=0;i<3;i++) { - uint8_t *ptr; - int x, y, h, v, linesize; - h = s->mjpeg_hsample[i]; - v = s->mjpeg_vsample[i]; - linesize= p->linesize[i]; - - for(y=0; y<v; y++){ - for(x=0; x<h; x++){ - int pred; - - ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap - if(y==0 && mb_y==0){ - if(x==0 && mb_x==0){ - pred= 128; - }else{ - pred= ptr[-1]; - } - }else{ - if(x==0 && mb_x==0){ - pred= ptr[-linesize]; - }else{ - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - } - } - - if(i==0) - mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly - else - mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - } - } - } - }else{ - for(i=0;i<3;i++) { - uint8_t *ptr; - int x, y, h, v, linesize; - h = s->mjpeg_hsample[i]; - v = s->mjpeg_vsample[i]; - linesize= p->linesize[i]; - - for(y=0; y<v; y++){ - for(x=0; x<h; x++){ - int pred; - - ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap -//printf("%d %d %d %d %8X\n", mb_x, mb_y, x, y, ptr); - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - - if(i==0) - mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly - else - mjpeg_encode_dc(s, (int8_t)(*ptr - pred), m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); - } - } - } - } - } - } - } - - emms_c(); - - mjpeg_picture_trailer(s); - s->picture_number++; - - flush_put_bits(&s->pb); - return pbBufPtr(&s->pb) - s->pb.buf; -// return (put_bits_count(&f->pb)+7)/8; -} - -#endif //CONFIG_ENCODERS - -/******************************************/ -/* decoding */ - -#define MAX_COMPONENTS 4 - -typedef struct MJpegDecodeContext { - AVCodecContext *avctx; - GetBitContext gb; - int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ - - int start_code; /* current start code */ - int buffer_size; - uint8_t *buffer; - - int16_t quant_matrixes[4][64]; - VLC vlcs[2][4]; - int qscale[4]; ///< quantizer scale calculated from quant_matrixes - - int org_height; /* size given at codec init */ - int first_picture; /* true if decoding first picture */ - int interlaced; /* true if interlaced */ - int bottom_field; /* true if bottom field */ - int lossless; - int ls; - int progressive; - int rgb; - int rct; /* standard rct */ - int pegasus_rct; /* pegasus reversible colorspace transform */ - int bits; /* bits per component */ - - int maxval; - int near; ///< near lossless bound (si 0 for lossless) - int t1,t2,t3; - int reset; ///< context halfing intervall ?rename - - int width, height; - int mb_width, mb_height; - int nb_components; - int component_id[MAX_COMPONENTS]; - int h_count[MAX_COMPONENTS]; /* horizontal and vertical count for each component */ - int v_count[MAX_COMPONENTS]; - int comp_index[MAX_COMPONENTS]; - int dc_index[MAX_COMPONENTS]; - int ac_index[MAX_COMPONENTS]; - int nb_blocks[MAX_COMPONENTS]; - int h_scount[MAX_COMPONENTS]; - int v_scount[MAX_COMPONENTS]; - int h_max, v_max; /* maximum h and v counts */ - int quant_index[4]; /* quant table index for each component */ - int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */ - AVFrame picture; /* picture structure */ - int linesize[MAX_COMPONENTS]; ///< linesize << interlaced - int8_t *qscale_table; - DECLARE_ALIGNED_8(DCTELEM, block[64]); - ScanTable scantable; - void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); - void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); - - int restart_interval; - int restart_count; - - int buggy_avid; - int cs_itu601; - int interlace_polarity; - - int mjpb_skiptosod; - - int cur_scan; /* current scan, used by JPEG-LS */ -} MJpegDecodeContext; - -#include "jpeg_ls.c" //FIXME make jpeg-ls more independent - -static int mjpeg_decode_dht(MJpegDecodeContext *s); - -static int build_vlc(VLC *vlc, const uint8_t *bits_table, const uint8_t *val_table, - int nb_codes, int use_static, int is_ac) -{ - uint8_t huff_size[256+16]; - uint16_t huff_code[256+16]; - - assert(nb_codes <= 256); - - memset(huff_size, 0, sizeof(huff_size)); - build_huffman_codes(huff_size, huff_code, bits_table, val_table); - - if(is_ac){ - memmove(huff_size+16, huff_size, sizeof(uint8_t)*nb_codes); - memmove(huff_code+16, huff_code, sizeof(uint16_t)*nb_codes); - memset(huff_size, 0, sizeof(uint8_t)*16); - memset(huff_code, 0, sizeof(uint16_t)*16); - nb_codes += 16; - } - - return init_vlc(vlc, 9, nb_codes, huff_size, 1, 1, huff_code, 2, 2, use_static); -} - -static int mjpeg_decode_init(AVCodecContext *avctx) -{ - MJpegDecodeContext *s = avctx->priv_data; - MpegEncContext s2; - memset(s, 0, sizeof(MJpegDecodeContext)); - - s->avctx = avctx; - - /* ugly way to get the idct & scantable FIXME */ - memset(&s2, 0, sizeof(MpegEncContext)); - s2.avctx= avctx; -// s2->out_format = FMT_MJPEG; - dsputil_init(&s2.dsp, avctx); - DCT_common_init(&s2); - - s->scantable= s2.intra_scantable; - s->idct_put= s2.dsp.idct_put; - s->idct_add= s2.dsp.idct_add; - - s->mpeg_enc_ctx_allocated = 0; - s->buffer_size = 0; - s->buffer = NULL; - s->start_code = -1; - s->first_picture = 1; - s->org_height = avctx->coded_height; - - build_vlc(&s->vlcs[0][0], bits_dc_luminance, val_dc_luminance, 12, 0, 0); - build_vlc(&s->vlcs[0][1], bits_dc_chrominance, val_dc_chrominance, 12, 0, 0); - build_vlc(&s->vlcs[1][0], bits_ac_luminance, val_ac_luminance, 251, 0, 1); - build_vlc(&s->vlcs[1][1], bits_ac_chrominance, val_ac_chrominance, 251, 0, 1); - - if (avctx->flags & CODEC_FLAG_EXTERN_HUFF) - { - av_log(avctx, AV_LOG_INFO, "mjpeg: using external huffman table\n"); - init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8); - mjpeg_decode_dht(s); - /* should check for error - but dunno */ - } - if (avctx->extradata_size > 9 && - AV_RL32(avctx->extradata + 4) == MKTAG('f','i','e','l')) { - if (avctx->extradata[9] == 6) { /* quicktime icefloe 019 */ - s->interlace_polarity = 1; /* bottom field first */ - av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n"); - } - } - - 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 - */ -static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ - int vop_found, i; - uint16_t state; - - vop_found= pc->frame_start_found; - state= pc->state; - - i=0; - if(!vop_found){ - for(i=0; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if(state == 0xFFD8){ - i++; - vop_found=1; - break; - } - } - } - - if(vop_found){ - /* EOF considered as end of frame */ - if (buf_size == 0) - return 0; - for(; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if(state == 0xFFD8){ - pc->frame_start_found=0; - pc->state=0; - return i-1; - } - } - } - pc->frame_start_found= vop_found; - pc->state= state; - return END_NOT_FOUND; -} - -static int jpeg_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - next= find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - - *poutbuf = (uint8_t *)buf; - *poutbuf_size = buf_size; - return next; -} - -/* quantize tables */ -static int mjpeg_decode_dqt(MJpegDecodeContext *s) -{ - int len, index, i, j; - - len = get_bits(&s->gb, 16) - 2; - - while (len >= 65) { - /* only 8 bit precision handled */ - if (get_bits(&s->gb, 4) != 0) - { - av_log(s->avctx, AV_LOG_ERROR, "dqt: 16bit precision\n"); - return -1; - } - index = get_bits(&s->gb, 4); - if (index >= 4) - return -1; - av_log(s->avctx, AV_LOG_DEBUG, "index=%d\n", index); - /* read quant table */ - for(i=0;i<64;i++) { - j = s->scantable.permutated[i]; - s->quant_matrixes[index][j] = get_bits(&s->gb, 8); - } - - //XXX FIXME finetune, and perhaps add dc too - s->qscale[index]= FFMAX( - s->quant_matrixes[index][s->scantable.permutated[1]], - s->quant_matrixes[index][s->scantable.permutated[8]]) >> 1; - av_log(s->avctx, AV_LOG_DEBUG, "qscale[%d]: %d\n", index, s->qscale[index]); - len -= 65; - } - - return 0; -} - -/* decode huffman tables and build VLC decoders */ -static int mjpeg_decode_dht(MJpegDecodeContext *s) -{ - int len, index, i, class, n, v, code_max; - uint8_t bits_table[17]; - uint8_t val_table[256]; - - len = get_bits(&s->gb, 16) - 2; - - while (len > 0) { - if (len < 17) - return -1; - class = get_bits(&s->gb, 4); - if (class >= 2) - return -1; - index = get_bits(&s->gb, 4); - if (index >= 4) - return -1; - n = 0; - for(i=1;i<=16;i++) { - bits_table[i] = get_bits(&s->gb, 8); - n += bits_table[i]; - } - len -= 17; - if (len < n || n > 256) - return -1; - - code_max = 0; - for(i=0;i<n;i++) { - v = get_bits(&s->gb, 8); - if (v > code_max) - code_max = v; - val_table[i] = v; - } - len -= n; - - /* build VLC and flush previous vlc if present */ - free_vlc(&s->vlcs[class][index]); - av_log(s->avctx, AV_LOG_DEBUG, "class=%d index=%d nb_codes=%d\n", - class, index, code_max + 1); - if(build_vlc(&s->vlcs[class][index], bits_table, val_table, code_max + 1, 0, class > 0) < 0){ - return -1; - } - } - return 0; -} - -static int mjpeg_decode_sof(MJpegDecodeContext *s) -{ - int len, nb_components, i, width, height, pix_fmt_id; - - /* XXX: verify len field validity */ - len = get_bits(&s->gb, 16); - s->bits= get_bits(&s->gb, 8); - - if(s->pegasus_rct) s->bits=9; - if(s->bits==9 && !s->pegasus_rct) s->rct=1; //FIXME ugly - - if (s->bits != 8 && !s->lossless){ - av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n"); - return -1; - } - - height = get_bits(&s->gb, 16); - width = get_bits(&s->gb, 16); - - av_log(s->avctx, AV_LOG_DEBUG, "sof0: picture: %dx%d\n", width, height); - if(avcodec_check_dimensions(s->avctx, width, height)) - return -1; - - nb_components = get_bits(&s->gb, 8); - if (nb_components <= 0 || - nb_components > MAX_COMPONENTS) - return -1; - if (s->ls && !(s->bits <= 8 || nb_components == 1)){ - av_log(s->avctx, AV_LOG_ERROR, "only <= 8 bits/component or 16-bit gray accepted for JPEG-LS\n"); - return -1; - } - s->nb_components = nb_components; - s->h_max = 1; - s->v_max = 1; - for(i=0;i<nb_components;i++) { - /* component id */ - s->component_id[i] = get_bits(&s->gb, 8) - 1; - s->h_count[i] = get_bits(&s->gb, 4); - s->v_count[i] = get_bits(&s->gb, 4); - /* compute hmax and vmax (only used in interleaved case) */ - if (s->h_count[i] > s->h_max) - s->h_max = s->h_count[i]; - if (s->v_count[i] > s->v_max) - s->v_max = s->v_count[i]; - s->quant_index[i] = get_bits(&s->gb, 8); - if (s->quant_index[i] >= 4) - return -1; - av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n", i, s->h_count[i], - s->v_count[i], s->component_id[i], s->quant_index[i]); - } - - if(s->ls && (s->h_max > 1 || s->v_max > 1)) { - av_log(s->avctx, AV_LOG_ERROR, "Subsampling in JPEG-LS is not supported.\n"); - return -1; - } - - if(s->v_max==1 && s->h_max==1 && s->lossless==1) s->rgb=1; - - /* if different size, realloc/alloc picture */ - /* XXX: also check h_count and v_count */ - if (width != s->width || height != s->height) { - av_freep(&s->qscale_table); - - s->width = width; - s->height = height; - - /* test interlaced mode */ - if (s->first_picture && - s->org_height != 0 && - s->height < ((s->org_height * 3) / 4)) { - s->interlaced = 1; - s->bottom_field = s->interlace_polarity; - s->picture.interlaced_frame = 1; - s->picture.top_field_first = !s->interlace_polarity; - height *= 2; - } - - avcodec_set_dimensions(s->avctx, width, height); - - s->qscale_table= av_mallocz((s->width+15)/16); - - s->first_picture = 0; - } - - if(s->interlaced && (s->bottom_field == !s->interlace_polarity)) - return 0; - - /* XXX: not complete test ! */ - pix_fmt_id = (s->h_count[0] << 20) | (s->v_count[0] << 16) | - (s->h_count[1] << 12) | (s->v_count[1] << 8) | - (s->h_count[2] << 4) | s->v_count[2]; - av_log(s->avctx, AV_LOG_DEBUG, "pix fmt id %x\n", pix_fmt_id); - switch(pix_fmt_id){ - case 0x222222: - case 0x111111: - if(s->rgb){ - s->avctx->pix_fmt = PIX_FMT_RGB32; - }else if(s->nb_components==3) - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P; - else - s->avctx->pix_fmt = PIX_FMT_GRAY8; - break; - case 0x211111: - case 0x221212: - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P; - break; - default: - case 0x221111: - s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420P; - break; - } - if(s->ls){ - if(s->nb_components > 1) - s->avctx->pix_fmt = PIX_FMT_RGB24; - else if(s->bits <= 8) - s->avctx->pix_fmt = PIX_FMT_GRAY8; - else - s->avctx->pix_fmt = PIX_FMT_GRAY16; - } - - if(s->picture.data[0]) - s->avctx->release_buffer(s->avctx, &s->picture); - - s->picture.reference= 0; - if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){ - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - s->picture.pict_type= I_TYPE; - s->picture.key_frame= 1; - - for(i=0; i<3; i++){ - s->linesize[i]= s->picture.linesize[i] << s->interlaced; - } - -// printf("%d %d %d %d %d %d\n", s->width, s->height, s->linesize[0], s->linesize[1], s->interlaced, s->avctx->height); - - if (len != (8+(3*nb_components))) - { - av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len); - } - - /* totally blank picture as progressive JPEG will only add details to it */ - if(s->progressive){ - memset(s->picture.data[0], 0, s->picture.linesize[0] * s->height); - memset(s->picture.data[1], 0, s->picture.linesize[1] * s->height >> (s->v_max - s->v_count[1])); - memset(s->picture.data[2], 0, s->picture.linesize[2] * s->height >> (s->v_max - s->v_count[2])); - } - return 0; -} - -static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index) -{ - int code; - code = get_vlc2(&s->gb, s->vlcs[0][dc_index].table, 9, 2); - if (code < 0) - { - av_log(s->avctx, AV_LOG_WARNING, "mjpeg_decode_dc: bad vlc: %d:%d (%p)\n", 0, dc_index, - &s->vlcs[0][dc_index]); - return 0xffff; - } - - if(code) - return get_xbits(&s->gb, code); - else - return 0; -} - -/* decode block and dequantize */ -static int decode_block(MJpegDecodeContext *s, DCTELEM *block, - int component, int dc_index, int ac_index, int16_t *quant_matrix) -{ - int code, i, j, level, val; - - /* DC coef */ - val = mjpeg_decode_dc(s, dc_index); - if (val == 0xffff) { - av_log(s->avctx, AV_LOG_ERROR, "error dc\n"); - return -1; - } - val = val * quant_matrix[0] + s->last_dc[component]; - s->last_dc[component] = val; - block[0] = val; - /* AC coefs */ - i = 0; - {OPEN_READER(re, &s->gb) - for(;;) { - UPDATE_CACHE(re, &s->gb); - GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2) - - /* EOB */ - if (code == 0x10) - break; - i += ((unsigned)code) >> 4; - if(code != 0x100){ - code &= 0xf; - if(code > MIN_CACHE_BITS - 16){ - UPDATE_CACHE(re, &s->gb) - } - { - int cache=GET_CACHE(re,&s->gb); - int sign=(~cache)>>31; - level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign; - } - - LAST_SKIP_BITS(re, &s->gb, code) - - if (i >= 63) { - if(i == 63){ - j = s->scantable.permutated[63]; - block[j] = level * quant_matrix[j]; - break; - } - av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); - return -1; - } - j = s->scantable.permutated[i]; - block[j] = level * quant_matrix[j]; - } - } - CLOSE_READER(re, &s->gb)} - - return 0; -} - -/* decode block and dequantize - progressive JPEG version */ -static int decode_block_progressive(MJpegDecodeContext *s, DCTELEM *block, - int component, int dc_index, int ac_index, int16_t *quant_matrix, - int ss, int se, int Ah, int Al, int *EOBRUN) -{ - int code, i, j, level, val, run; - - /* DC coef */ - if(!ss){ - val = mjpeg_decode_dc(s, dc_index); - if (val == 0xffff) { - av_log(s->avctx, AV_LOG_ERROR, "error dc\n"); - return -1; - } - val = (val * quant_matrix[0] << Al) + s->last_dc[component]; - }else - val = 0; - s->last_dc[component] = val; - block[0] = val; - if(!se) return 0; - /* AC coefs */ - if(*EOBRUN){ - (*EOBRUN)--; - return 0; - } - {OPEN_READER(re, &s->gb) - for(i=ss;;i++) { - UPDATE_CACHE(re, &s->gb); - GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2) - /* Progressive JPEG use AC coeffs from zero and this decoder sets offset 16 by default */ - code -= 16; - if(code & 0xF) { - i += ((unsigned) code) >> 4; - code &= 0xf; - if(code > MIN_CACHE_BITS - 16){ - UPDATE_CACHE(re, &s->gb) - } - { - int cache=GET_CACHE(re,&s->gb); - int sign=(~cache)>>31; - level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign; - } - - LAST_SKIP_BITS(re, &s->gb, code) - - if (i >= se) { - if(i == se){ - j = s->scantable.permutated[se]; - block[j] = level * quant_matrix[j] << Al; - break; - } - av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); - return -1; - } - j = s->scantable.permutated[i]; - block[j] = level * quant_matrix[j] << Al; - }else{ - run = ((unsigned) code) >> 4; - if(run == 0xF){// ZRL - skip 15 coefficients - i += 15; - }else{ - val = run; - run = (1 << run); - UPDATE_CACHE(re, &s->gb); - run += (GET_CACHE(re, &s->gb) >> (32 - val)) & (run - 1); - if(val) - LAST_SKIP_BITS(re, &s->gb, val); - *EOBRUN = run - 1; - break; - } - } - } - CLOSE_READER(re, &s->gb)} - - return 0; -} - -static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, int point_transform){ - int i, mb_x, mb_y; - uint16_t buffer[32768][4]; - int left[3], top[3], topleft[3]; - const int linesize= s->linesize[0]; - const int mask= (1<<s->bits)-1; - - if((unsigned)s->mb_width > 32768) //dynamic alloc - return -1; - - for(i=0; i<3; i++){ - buffer[0][i]= 1 << (s->bits + point_transform - 1); - } - for(mb_y = 0; mb_y < s->mb_height; mb_y++) { - const int modified_predictor= mb_y ? predictor : 1; - uint8_t *ptr = s->picture.data[0] + (linesize * mb_y); - - if (s->interlaced && s->bottom_field) - ptr += linesize >> 1; - - for(i=0; i<3; i++){ - top[i]= left[i]= topleft[i]= buffer[0][i]; - } - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - if (s->restart_interval && !s->restart_count) - s->restart_count = s->restart_interval; - - for(i=0;i<3;i++) { - int pred; - - topleft[i]= top[i]; - top[i]= buffer[mb_x][i]; - - PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); - - left[i]= - buffer[mb_x][i]= mask & (pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform)); - } - - if (s->restart_interval && !--s->restart_count) { - align_get_bits(&s->gb); - skip_bits(&s->gb, 16); /* skip RSTn */ - } - } - - if(s->rct){ - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200)>>2); - ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1]; - ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1]; - } - }else if(s->pegasus_rct){ - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2])>>2); - ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1]; - ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1]; - } - }else{ - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - ptr[4*mb_x+0] = buffer[mb_x][0]; - ptr[4*mb_x+1] = buffer[mb_x][1]; - ptr[4*mb_x+2] = buffer[mb_x][2]; - } - } - } - return 0; -} - -static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point_transform){ - int i, mb_x, mb_y; - const int nb_components=3; - - for(mb_y = 0; mb_y < s->mb_height; mb_y++) { - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - if (s->restart_interval && !s->restart_count) - s->restart_count = s->restart_interval; - - if(mb_x==0 || mb_y==0 || s->interlaced){ - for(i=0;i<nb_components;i++) { - uint8_t *ptr; - int n, h, v, x, y, c, j, linesize; - n = s->nb_blocks[i]; - c = s->comp_index[i]; - h = s->h_scount[i]; - v = s->v_scount[i]; - x = 0; - y = 0; - linesize= s->linesize[c]; - - for(j=0; j<n; j++) { - int pred; - - ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap - if(y==0 && mb_y==0){ - if(x==0 && mb_x==0){ - pred= 128 << point_transform; - }else{ - pred= ptr[-1]; - } - }else{ - if(x==0 && mb_x==0){ - pred= ptr[-linesize]; - }else{ - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - } - } - - if (s->interlaced && s->bottom_field) - ptr += linesize >> 1; - *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform); - - if (++x == h) { - x = 0; - y++; - } - } - } - }else{ - for(i=0;i<nb_components;i++) { - uint8_t *ptr; - int n, h, v, x, y, c, j, linesize; - n = s->nb_blocks[i]; - c = s->comp_index[i]; - h = s->h_scount[i]; - v = s->v_scount[i]; - x = 0; - y = 0; - linesize= s->linesize[c]; - - for(j=0; j<n; j++) { - int pred; - - ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap - PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); - *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform); - if (++x == h) { - x = 0; - y++; - } - } - } - } - if (s->restart_interval && !--s->restart_count) { - align_get_bits(&s->gb); - skip_bits(&s->gb, 16); /* skip RSTn */ - } - } - } - return 0; -} - -static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int ss, int se, int Ah, int Al){ - int i, mb_x, mb_y; - int EOBRUN = 0; - - if(Ah) return 0; /* TODO decode refinement planes too */ - for(mb_y = 0; mb_y < s->mb_height; mb_y++) { - for(mb_x = 0; mb_x < s->mb_width; mb_x++) { - if (s->restart_interval && !s->restart_count) - s->restart_count = s->restart_interval; - - for(i=0;i<nb_components;i++) { - uint8_t *ptr; - int n, h, v, x, y, c, j; - n = s->nb_blocks[i]; - c = s->comp_index[i]; - h = s->h_scount[i]; - v = s->v_scount[i]; - x = 0; - y = 0; - for(j=0;j<n;j++) { - memset(s->block, 0, sizeof(s->block)); - if (!s->progressive && decode_block(s, s->block, i, - s->dc_index[i], s->ac_index[i], - s->quant_matrixes[ s->quant_index[c] ]) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); - return -1; - } - if (s->progressive && decode_block_progressive(s, s->block, i, - s->dc_index[i], s->ac_index[i], - s->quant_matrixes[ s->quant_index[c] ], ss, se, Ah, Al, &EOBRUN) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); - return -1; - } -// av_log(s->avctx, AV_LOG_DEBUG, "mb: %d %d processed\n", mb_y, mb_x); - ptr = s->picture.data[c] + - (((s->linesize[c] * (v * mb_y + y) * 8) + - (h * mb_x + x) * 8) >> s->avctx->lowres); - if (s->interlaced && s->bottom_field) - ptr += s->linesize[c] >> 1; -//av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d \n", mb_x, mb_y, x, y, c, s->bottom_field, (v * mb_y + y) * 8, (h * mb_x + x) * 8); - if(!s->progressive) - s->idct_put(ptr, s->linesize[c], s->block); - else - s->idct_add(ptr, s->linesize[c], s->block); - if (++x == h) { - x = 0; - y++; - } - } - } - /* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */ - if (s->restart_interval && (s->restart_interval < 1350) && - !--s->restart_count) { - align_get_bits(&s->gb); - skip_bits(&s->gb, 16); /* skip RSTn */ - for (i=0; i<nb_components; i++) /* reset dc */ - s->last_dc[i] = 1024; - } - } - } - return 0; -} - -static int mjpeg_decode_sos(MJpegDecodeContext *s) -{ - int len, nb_components, i, h, v, predictor, point_transform; - int vmax, hmax, index, id; - const int block_size= s->lossless ? 1 : 8; - int ilv, prev_shift; - - /* XXX: verify len field validity */ - len = get_bits(&s->gb, 16); - nb_components = get_bits(&s->gb, 8); - if (len != 6+2*nb_components) - { - av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len); - return -1; - } - vmax = 0; - hmax = 0; - for(i=0;i<nb_components;i++) { - id = get_bits(&s->gb, 8) - 1; - av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id); - /* find component index */ - for(index=0;index<s->nb_components;index++) - if (id == s->component_id[index]) - break; - if (index == s->nb_components) - { - av_log(s->avctx, AV_LOG_ERROR, "decode_sos: index(%d) out of components\n", index); - return -1; - } - - s->comp_index[i] = index; - - s->nb_blocks[i] = s->h_count[index] * s->v_count[index]; - s->h_scount[i] = s->h_count[index]; - s->v_scount[i] = s->v_count[index]; - - s->dc_index[i] = get_bits(&s->gb, 4); - s->ac_index[i] = get_bits(&s->gb, 4); - - if (s->dc_index[i] < 0 || s->ac_index[i] < 0 || - s->dc_index[i] >= 4 || s->ac_index[i] >= 4) - goto out_of_range; -#if 0 //buggy - switch(s->start_code) - { - case SOF0: - if (dc_index[i] > 1 || ac_index[i] > 1) - goto out_of_range; - break; - case SOF1: - case SOF2: - if (dc_index[i] > 3 || ac_index[i] > 3) - goto out_of_range; - break; - case SOF3: - if (dc_index[i] > 3 || ac_index[i] != 0) - goto out_of_range; - break; - } -#endif - } - - predictor= get_bits(&s->gb, 8); /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */ - ilv= get_bits(&s->gb, 8); /* JPEG Se / JPEG-LS ILV */ - prev_shift = get_bits(&s->gb, 4); /* Ah */ - point_transform= get_bits(&s->gb, 4); /* Al */ - - for(i=0;i<nb_components;i++) - s->last_dc[i] = 1024; - - if (nb_components > 1) { - /* interleaved stream */ - s->mb_width = (s->width + s->h_max * block_size - 1) / (s->h_max * block_size); - s->mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size); - } else if(!s->ls) { /* skip this for JPEG-LS */ - h = s->h_max / s->h_scount[0]; - v = s->v_max / s->v_scount[0]; - s->mb_width = (s->width + h * block_size - 1) / (h * block_size); - s->mb_height = (s->height + v * block_size - 1) / (v * block_size); - s->nb_blocks[0] = 1; - s->h_scount[0] = 1; - s->v_scount[0] = 1; - } - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d %s\n", s->lossless ? "lossless" : "sequencial DCT", s->rgb ? "RGB" : "", - predictor, point_transform, ilv, s->bits, - s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : "")); - - - /* mjpeg-b can have padding bytes between sos and image data, skip them */ - for (i = s->mjpb_skiptosod; i > 0; i--) - skip_bits(&s->gb, 8); - - if(s->lossless){ - if(s->ls){ -// for(){ -// reset_ls_coding_parameters(s, 0); - - ls_decode_picture(s, predictor, point_transform, ilv); - }else{ - if(s->rgb){ - if(ljpeg_decode_rgb_scan(s, predictor, point_transform) < 0) - return -1; - }else{ - if(ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0) - return -1; - } - } - }else{ - if(mjpeg_decode_scan(s, nb_components, predictor, ilv, prev_shift, point_transform) < 0) - return -1; - } - emms_c(); - return 0; - out_of_range: - av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n"); - return -1; -} - -static int mjpeg_decode_dri(MJpegDecodeContext *s) -{ - if (get_bits(&s->gb, 16) != 4) - return -1; - s->restart_interval = get_bits(&s->gb, 16); - s->restart_count = 0; - av_log(s->avctx, AV_LOG_DEBUG, "restart interval: %d\n", s->restart_interval); - - return 0; -} - -static int mjpeg_decode_app(MJpegDecodeContext *s) -{ - int len, id; - - len = get_bits(&s->gb, 16); - if (len < 5) - return -1; - if(8*len + get_bits_count(&s->gb) > s->gb.size_in_bits) - return -1; - - id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); - id = be2me_32(id); - len -= 6; - - if(s->avctx->debug & FF_DEBUG_STARTCODE){ - av_log(s->avctx, AV_LOG_DEBUG, "APPx %8X\n", id); - } - - /* buggy AVID, it puts EOI only at every 10th frame */ - /* also this fourcc is used by non-avid files too, it holds some - informations, but it's always present in AVID creates files */ - if (id == ff_get_fourcc("AVI1")) - { - /* structure: - 4bytes AVI1 - 1bytes polarity - 1bytes always zero - 4bytes field_size - 4bytes field_size_less_padding - */ - s->buggy_avid = 1; -// if (s->first_picture) -// printf("mjpeg: workarounding buggy AVID\n"); - s->interlace_polarity = get_bits(&s->gb, 8); -#if 0 - skip_bits(&s->gb, 8); - skip_bits(&s->gb, 32); - skip_bits(&s->gb, 32); - len -= 10; -#endif -// if (s->interlace_polarity) -// printf("mjpeg: interlace polarity: %d\n", s->interlace_polarity); - goto out; - } - -// len -= 2; - - if (id == ff_get_fourcc("JFIF")) - { - int t_w, t_h, v1, v2; - skip_bits(&s->gb, 8); /* the trailing zero-byte */ - v1= get_bits(&s->gb, 8); - v2= get_bits(&s->gb, 8); - skip_bits(&s->gb, 8); - - s->avctx->sample_aspect_ratio.num= get_bits(&s->gb, 16); - s->avctx->sample_aspect_ratio.den= get_bits(&s->gb, 16); - - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "mjpeg: JFIF header found (version: %x.%x) SAR=%d/%d\n", - v1, v2, - s->avctx->sample_aspect_ratio.num, - s->avctx->sample_aspect_ratio.den - ); - - t_w = get_bits(&s->gb, 8); - t_h = get_bits(&s->gb, 8); - if (t_w && t_h) - { - /* skip thumbnail */ - if (len-10-(t_w*t_h*3) > 0) - len -= t_w*t_h*3; - } - len -= 10; - goto out; - } - - if (id == ff_get_fourcc("Adob") && (get_bits(&s->gb, 8) == 'e')) - { - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "mjpeg: Adobe header found\n"); - skip_bits(&s->gb, 16); /* version */ - skip_bits(&s->gb, 16); /* flags0 */ - skip_bits(&s->gb, 16); /* flags1 */ - skip_bits(&s->gb, 8); /* transform */ - len -= 7; - goto out; - } - - if (id == ff_get_fourcc("LJIF")){ - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "Pegasus lossless jpeg header found\n"); - skip_bits(&s->gb, 16); /* version ? */ - skip_bits(&s->gb, 16); /* unknwon always 0? */ - skip_bits(&s->gb, 16); /* unknwon always 0? */ - skip_bits(&s->gb, 16); /* unknwon always 0? */ - switch( get_bits(&s->gb, 8)){ - case 1: - s->rgb= 1; - s->pegasus_rct=0; - break; - case 2: - s->rgb= 1; - s->pegasus_rct=1; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace\n"); - } - len -= 9; - goto out; - } - - /* Apple MJPEG-A */ - if ((s->start_code == APP1) && (len > (0x28 - 8))) - { - id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); - id = be2me_32(id); - len -= 4; - if (id == ff_get_fourcc("mjpg")) /* Apple MJPEG-A */ - { -#if 0 - skip_bits(&s->gb, 32); /* field size */ - skip_bits(&s->gb, 32); /* pad field size */ - skip_bits(&s->gb, 32); /* next off */ - skip_bits(&s->gb, 32); /* quant off */ - skip_bits(&s->gb, 32); /* huff off */ - skip_bits(&s->gb, 32); /* image off */ - skip_bits(&s->gb, 32); /* scan off */ - skip_bits(&s->gb, 32); /* data off */ -#endif - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "mjpeg: Apple MJPEG-A header found\n"); - } - } - -out: - /* slow but needed for extreme adobe jpegs */ - if (len < 0) - av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error, decode_app parser read over the end\n"); - while(--len > 0) - skip_bits(&s->gb, 8); - - return 0; -} - -static int mjpeg_decode_com(MJpegDecodeContext *s) -{ - int len = get_bits(&s->gb, 16); - if (len >= 2 && 8*len - 16 + get_bits_count(&s->gb) <= s->gb.size_in_bits) { - char *cbuf = av_malloc(len - 1); - if (cbuf) { - int i; - for (i = 0; i < len - 2; i++) - cbuf[i] = get_bits(&s->gb, 8); - if (i > 0 && cbuf[i-1] == '\n') - cbuf[i-1] = 0; - else - cbuf[i] = 0; - - if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_INFO, "mjpeg comment: '%s'\n", cbuf); - - /* buggy avid, it puts EOI only at every 10th frame */ - if (!strcmp(cbuf, "AVID")) - { - s->buggy_avid = 1; - // if (s->first_picture) - // printf("mjpeg: workarounding buggy AVID\n"); - } - else if(!strcmp(cbuf, "CS=ITU601")){ - s->cs_itu601= 1; - } - - av_free(cbuf); - } - } - - return 0; -} - -#if 0 -static int valid_marker_list[] = -{ - /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f */ -/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* c */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* d */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, -} -#endif - -/* return the 8 bit start code value and update the search - state. Return -1 if no start code found */ -static int find_marker(uint8_t **pbuf_ptr, uint8_t *buf_end) -{ - uint8_t *buf_ptr; - unsigned int v, v2; - int val; -#ifdef DEBUG - int skipped=0; -#endif - - buf_ptr = *pbuf_ptr; - while (buf_ptr < buf_end) { - v = *buf_ptr++; - v2 = *buf_ptr; - if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe) && buf_ptr < buf_end) { - val = *buf_ptr++; - goto found; - } -#ifdef DEBUG - skipped++; -#endif - } - val = -1; -found: -#ifdef DEBUG - av_log(NULL, AV_LOG_VERBOSE, "find_marker skipped %d bytes\n", skipped); -#endif - *pbuf_ptr = buf_ptr; - return val; -} - -static int mjpeg_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - MJpegDecodeContext *s = avctx->priv_data; - uint8_t *buf_end, *buf_ptr; - int start_code; - AVFrame *picture = data; - - buf_ptr = buf; - buf_end = buf + buf_size; - while (buf_ptr < buf_end) { - /* find start next marker */ - start_code = find_marker(&buf_ptr, buf_end); - { - /* EOF */ - if (start_code < 0) { - goto the_end; - } else { - av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%d\n", start_code, buf_end - buf_ptr); - - if ((buf_end - buf_ptr) > s->buffer_size) - { - av_free(s->buffer); - s->buffer_size = buf_end-buf_ptr; - s->buffer = av_malloc(s->buffer_size + FF_INPUT_BUFFER_PADDING_SIZE); - av_log(avctx, AV_LOG_DEBUG, "buffer too small, expanding to %d bytes\n", - s->buffer_size); - } - - /* unescape buffer of SOS, use special treatment for JPEG-LS */ - if (start_code == SOS && !s->ls) - { - uint8_t *src = buf_ptr; - uint8_t *dst = s->buffer; - - while (src<buf_end) - { - uint8_t x = *(src++); - - *(dst++) = x; - if (avctx->codec_id != CODEC_ID_THP) - { - if (x == 0xff) { - while (src < buf_end && x == 0xff) - x = *(src++); - - if (x >= 0xd0 && x <= 0xd7) - *(dst++) = x; - else if (x) - break; - } - } - } - init_get_bits(&s->gb, s->buffer, (dst - s->buffer)*8); - - av_log(avctx, AV_LOG_DEBUG, "escaping removed %d bytes\n", - (buf_end - buf_ptr) - (dst - s->buffer)); - } - else if(start_code == SOS && s->ls){ - uint8_t *src = buf_ptr; - uint8_t *dst = s->buffer; - int bit_count = 0; - int t = 0, b = 0; - PutBitContext pb; - - s->cur_scan++; - - /* find marker */ - while (src + t < buf_end){ - uint8_t x = src[t++]; - if (x == 0xff){ - while((src + t < buf_end) && x == 0xff) - x = src[t++]; - if (x & 0x80) { - t -= 2; - break; - } - } - } - bit_count = t * 8; - - init_put_bits(&pb, dst, t); - - /* unescape bitstream */ - while(b < t){ - uint8_t x = src[b++]; - put_bits(&pb, 8, x); - if(x == 0xFF){ - x = src[b++]; - put_bits(&pb, 7, x); - bit_count--; - } - } - flush_put_bits(&pb); - - init_get_bits(&s->gb, dst, bit_count); - } - else - init_get_bits(&s->gb, buf_ptr, (buf_end - buf_ptr)*8); - - s->start_code = start_code; - if(s->avctx->debug & FF_DEBUG_STARTCODE){ - av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); - } - - /* process markers */ - if (start_code >= 0xd0 && start_code <= 0xd7) { - av_log(avctx, AV_LOG_DEBUG, "restart marker: %d\n", start_code&0x0f); - /* APP fields */ - } else if (start_code >= APP0 && start_code <= APP15) { - mjpeg_decode_app(s); - /* Comment */ - } else if (start_code == COM){ - mjpeg_decode_com(s); - } - - switch(start_code) { - case SOI: - s->restart_interval = 0; - - s->restart_count = 0; - /* nothing to do on SOI */ - break; - case DQT: - mjpeg_decode_dqt(s); - break; - case DHT: - if(mjpeg_decode_dht(s) < 0){ - av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n"); - return -1; - } - break; - case SOF0: - s->lossless=0; - s->ls=0; - s->progressive=0; - if (mjpeg_decode_sof(s) < 0) - return -1; - break; - case SOF2: - s->lossless=0; - s->ls=0; - s->progressive=1; - if (mjpeg_decode_sof(s) < 0) - return -1; - break; - case SOF3: - s->lossless=1; - s->ls=0; - s->progressive=0; - if (mjpeg_decode_sof(s) < 0) - return -1; - break; - case SOF48: - s->lossless=1; - s->ls=1; - s->progressive=0; - if (mjpeg_decode_sof(s) < 0) - return -1; - break; - case LSE: - if (decode_lse(s) < 0) - return -1; - break; - case EOI: - s->cur_scan = 0; - if ((s->buggy_avid && !s->interlaced) || s->restart_interval) - break; -eoi_parser: - { - if (s->interlaced) { - s->bottom_field ^= 1; - /* if not bottom field, do not output image yet */ - if (s->bottom_field == !s->interlace_polarity) - goto not_the_end; - } - *picture = s->picture; - *data_size = sizeof(AVFrame); - - if(!s->lossless){ - picture->quality= FFMAX(FFMAX(s->qscale[0], s->qscale[1]), s->qscale[2]); - picture->qstride= 0; - picture->qscale_table= s->qscale_table; - memset(picture->qscale_table, picture->quality, (s->width+15)/16); - if(avctx->debug & FF_DEBUG_QP) - av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality); - picture->quality*= FF_QP2LAMBDA; - } - - goto the_end; - } - break; - case SOS: - mjpeg_decode_sos(s); - /* buggy avid puts EOI every 10-20th frame */ - /* if restart period is over process EOI */ - if ((s->buggy_avid && !s->interlaced) || s->restart_interval) - goto eoi_parser; - break; - case DRI: - mjpeg_decode_dri(s); - break; - case SOF1: - case SOF5: - case SOF6: - case SOF7: - case SOF9: - case SOF10: - case SOF11: - case SOF13: - case SOF14: - case SOF15: - case JPG: - av_log(avctx, AV_LOG_ERROR, "mjpeg: unsupported coding type (%x)\n", start_code); - break; -// default: -// printf("mjpeg: unsupported marker (%x)\n", start_code); -// break; - } - -not_the_end: - /* eof process start code */ - buf_ptr += (get_bits_count(&s->gb)+7)/8; - av_log(avctx, AV_LOG_DEBUG, "marker parser used %d bytes (%d bits)\n", - (get_bits_count(&s->gb)+7)/8, get_bits_count(&s->gb)); - } - } - } -the_end: - av_log(avctx, AV_LOG_DEBUG, "mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr); -// return buf_end - buf_ptr; - return buf_ptr - buf; -} - -static int mjpegb_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - MJpegDecodeContext *s = avctx->priv_data; - uint8_t *buf_end, *buf_ptr; - AVFrame *picture = data; - GetBitContext hgb; /* for the header */ - uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs; - uint32_t field_size, sod_offs; - - buf_ptr = buf; - buf_end = buf + buf_size; - -read_header: - /* reset on every SOI */ - s->restart_interval = 0; - s->restart_count = 0; - s->mjpb_skiptosod = 0; - - init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8); - - skip_bits(&hgb, 32); /* reserved zeros */ - - if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) - { - av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n"); - return 0; - } - - field_size = get_bits_long(&hgb, 32); /* field size */ - av_log(avctx, AV_LOG_DEBUG, "field size: 0x%x\n", field_size); - skip_bits(&hgb, 32); /* padded field size */ - second_field_offs = get_bits_long(&hgb, 32); - av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%x\n", second_field_offs); - if (second_field_offs) - s->interlaced = 1; - - dqt_offs = get_bits_long(&hgb, 32); - av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%x\n", dqt_offs); - if (dqt_offs) - { - init_get_bits(&s->gb, buf+dqt_offs, (buf_end - (buf+dqt_offs))*8); - s->start_code = DQT; - mjpeg_decode_dqt(s); - } - - dht_offs = get_bits_long(&hgb, 32); - av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%x\n", dht_offs); - if (dht_offs) - { - init_get_bits(&s->gb, buf+dht_offs, (buf_end - (buf+dht_offs))*8); - s->start_code = DHT; - mjpeg_decode_dht(s); - } - - sof_offs = get_bits_long(&hgb, 32); - av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%x\n", sof_offs); - if (sof_offs) - { - init_get_bits(&s->gb, buf+sof_offs, (buf_end - (buf+sof_offs))*8); - s->start_code = SOF0; - if (mjpeg_decode_sof(s) < 0) - return -1; - } - - sos_offs = get_bits_long(&hgb, 32); - av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%x\n", sos_offs); - sod_offs = get_bits_long(&hgb, 32); - av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs); - if (sos_offs) - { -// init_get_bits(&s->gb, buf+sos_offs, (buf_end - (buf+sos_offs))*8); - init_get_bits(&s->gb, buf+sos_offs, field_size*8); - s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); - s->start_code = SOS; - mjpeg_decode_sos(s); - } - - if (s->interlaced) { - s->bottom_field ^= 1; - /* if not bottom field, do not output image yet */ - if (s->bottom_field && second_field_offs) - { - buf_ptr = buf + second_field_offs; - second_field_offs = 0; - goto read_header; - } - } - - //XXX FIXME factorize, this looks very similar to the EOI code - - *picture= s->picture; - *data_size = sizeof(AVFrame); - - if(!s->lossless){ - picture->quality= FFMAX(FFMAX(s->qscale[0], s->qscale[1]), s->qscale[2]); - picture->qstride= 0; - picture->qscale_table= s->qscale_table; - memset(picture->qscale_table, picture->quality, (s->width+15)/16); - if(avctx->debug & FF_DEBUG_QP) - av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality); - picture->quality*= FF_QP2LAMBDA; - } - - return buf_ptr - buf; -} - -#include "sp5x.h" - -static int sp5x_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ -#if 0 - MJpegDecodeContext *s = avctx->priv_data; -#endif - const int qscale = 5; - uint8_t *buf_ptr, *buf_end, *recoded; - int i = 0, j = 0; - - if (!avctx->width || !avctx->height) - return -1; - - buf_ptr = buf; - buf_end = buf + buf_size; - -#if 1 - recoded = av_mallocz(buf_size + 1024); - if (!recoded) - return -1; - - /* SOI */ - recoded[j++] = 0xFF; - recoded[j++] = 0xD8; - - memcpy(recoded+j, &sp5x_data_dqt[0], sizeof(sp5x_data_dqt)); - memcpy(recoded+j+5, &sp5x_quant_table[qscale * 2], 64); - memcpy(recoded+j+70, &sp5x_quant_table[(qscale * 2) + 1], 64); - j += sizeof(sp5x_data_dqt); - - memcpy(recoded+j, &sp5x_data_dht[0], sizeof(sp5x_data_dht)); - j += sizeof(sp5x_data_dht); - - memcpy(recoded+j, &sp5x_data_sof[0], sizeof(sp5x_data_sof)); - recoded[j+5] = (avctx->coded_height >> 8) & 0xFF; - recoded[j+6] = avctx->coded_height & 0xFF; - recoded[j+7] = (avctx->coded_width >> 8) & 0xFF; - recoded[j+8] = avctx->coded_width & 0xFF; - j += sizeof(sp5x_data_sof); - - memcpy(recoded+j, &sp5x_data_sos[0], sizeof(sp5x_data_sos)); - j += sizeof(sp5x_data_sos); - - for (i = 14; i < buf_size && j < buf_size+1024-2; i++) - { - recoded[j++] = buf[i]; - if (buf[i] == 0xff) - recoded[j++] = 0; - } - - /* EOI */ - recoded[j++] = 0xFF; - recoded[j++] = 0xD9; - - i = mjpeg_decode_frame(avctx, data, data_size, recoded, j); - - av_free(recoded); - -#else - /* SOF */ - s->bits = 8; - s->width = avctx->coded_width; - s->height = avctx->coded_height; - s->nb_components = 3; - s->component_id[0] = 0; - s->h_count[0] = 2; - s->v_count[0] = 2; - s->quant_index[0] = 0; - s->component_id[1] = 1; - s->h_count[1] = 1; - s->v_count[1] = 1; - s->quant_index[1] = 1; - s->component_id[2] = 2; - s->h_count[2] = 1; - s->v_count[2] = 1; - s->quant_index[2] = 1; - s->h_max = 2; - s->v_max = 2; - - s->qscale_table = av_mallocz((s->width+15)/16); - avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420; - s->interlaced = 0; - - s->picture.reference = 0; - if (avctx->get_buffer(avctx, &s->picture) < 0) - { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - s->picture.pict_type = I_TYPE; - s->picture.key_frame = 1; - - for (i = 0; i < 3; i++) - s->linesize[i] = s->picture.linesize[i] << s->interlaced; - - /* DQT */ - for (i = 0; i < 64; i++) - { - j = s->scantable.permutated[i]; - s->quant_matrixes[0][j] = sp5x_quant_table[(qscale * 2) + i]; - } - s->qscale[0] = FFMAX( - s->quant_matrixes[0][s->scantable.permutated[1]], - s->quant_matrixes[0][s->scantable.permutated[8]]) >> 1; - - for (i = 0; i < 64; i++) - { - j = s->scantable.permutated[i]; - s->quant_matrixes[1][j] = sp5x_quant_table[(qscale * 2) + 1 + i]; - } - s->qscale[1] = FFMAX( - s->quant_matrixes[1][s->scantable.permutated[1]], - s->quant_matrixes[1][s->scantable.permutated[8]]) >> 1; - - /* DHT */ - - /* SOS */ - s->comp_index[0] = 0; - s->nb_blocks[0] = s->h_count[0] * s->v_count[0]; - s->h_scount[0] = s->h_count[0]; - s->v_scount[0] = s->v_count[0]; - s->dc_index[0] = 0; - s->ac_index[0] = 0; - - s->comp_index[1] = 1; - s->nb_blocks[1] = s->h_count[1] * s->v_count[1]; - s->h_scount[1] = s->h_count[1]; - s->v_scount[1] = s->v_count[1]; - s->dc_index[1] = 1; - s->ac_index[1] = 1; - - s->comp_index[2] = 2; - s->nb_blocks[2] = s->h_count[2] * s->v_count[2]; - s->h_scount[2] = s->h_count[2]; - s->v_scount[2] = s->v_count[2]; - s->dc_index[2] = 1; - s->ac_index[2] = 1; - - for (i = 0; i < 3; i++) - s->last_dc[i] = 1024; - - s->mb_width = (s->width * s->h_max * 8 -1) / (s->h_max * 8); - s->mb_height = (s->height * s->v_max * 8 -1) / (s->v_max * 8); - - init_get_bits(&s->gb, buf+14, (buf_size-14)*8); - - return mjpeg_decode_scan(s); -#endif - - return i; -} - -static int mjpeg_decode_end(AVCodecContext *avctx) -{ - MJpegDecodeContext *s = avctx->priv_data; - int i, j; - - av_free(s->buffer); - av_free(s->qscale_table); - - for(i=0;i<2;i++) { - for(j=0;j<4;j++) - free_vlc(&s->vlcs[i][j]); - } - return 0; -} - -static int mjpega_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe) -{ - uint8_t *poutbufp; - int i; - - if (avctx->codec_id != CODEC_ID_MJPEG) { - av_log(avctx, AV_LOG_ERROR, "mjpega bitstream filter only applies to mjpeg codec\n"); - return 0; - } - - *poutbuf_size = 0; - *poutbuf = av_malloc(buf_size + 44 + FF_INPUT_BUFFER_PADDING_SIZE); - poutbufp = *poutbuf; - bytestream_put_byte(&poutbufp, 0xff); - bytestream_put_byte(&poutbufp, SOI); - bytestream_put_byte(&poutbufp, 0xff); - bytestream_put_byte(&poutbufp, APP1); - bytestream_put_be16(&poutbufp, 42); /* size */ - bytestream_put_be32(&poutbufp, 0); - bytestream_put_buffer(&poutbufp, "mjpg", 4); - bytestream_put_be32(&poutbufp, buf_size + 44); /* field size */ - bytestream_put_be32(&poutbufp, buf_size + 44); /* pad field size */ - bytestream_put_be32(&poutbufp, 0); /* next ptr */ - - for (i = 0; i < buf_size - 1; i++) { - if (buf[i] == 0xff) { - switch (buf[i + 1]) { - case DQT: /* quant off */ - case DHT: /* huff off */ - case SOF0: /* image off */ - bytestream_put_be32(&poutbufp, i + 46); - break; - case SOS: - bytestream_put_be32(&poutbufp, i + 46); /* scan off */ - bytestream_put_be32(&poutbufp, i + 46 + AV_RB16(buf + i + 2)); /* data off */ - bytestream_put_buffer(&poutbufp, buf + 2, buf_size - 2); /* skip already written SOI */ - *poutbuf_size = poutbufp - *poutbuf; - return 1; - case APP1: - if (i + 8 < buf_size && AV_RL32(buf + i + 8) == ff_get_fourcc("mjpg")) { - av_log(avctx, AV_LOG_ERROR, "bitstream already formatted\n"); - memcpy(*poutbuf, buf, buf_size); - *poutbuf_size = buf_size; - return 1; - } - } - } - } - av_freep(poutbuf); - av_log(avctx, AV_LOG_ERROR, "could not find SOS marker in bitstream\n"); - return 0; -} - -AVCodec mjpeg_decoder = { - "mjpeg", - CODEC_TYPE_VIDEO, - CODEC_ID_MJPEG, - sizeof(MJpegDecodeContext), - mjpeg_decode_init, - NULL, - mjpeg_decode_end, - mjpeg_decode_frame, - CODEC_CAP_DR1, - NULL -}; - -AVCodec thp_decoder = { - "thp", - CODEC_TYPE_VIDEO, - CODEC_ID_THP, - sizeof(MJpegDecodeContext), - mjpeg_decode_init, - NULL, - mjpeg_decode_end, - mjpeg_decode_frame, - CODEC_CAP_DR1, - NULL -}; - -AVCodec mjpegb_decoder = { - "mjpegb", - CODEC_TYPE_VIDEO, - CODEC_ID_MJPEGB, - sizeof(MJpegDecodeContext), - mjpeg_decode_init, - NULL, - mjpeg_decode_end, - mjpegb_decode_frame, - CODEC_CAP_DR1, - NULL -}; - -AVCodec sp5x_decoder = { - "sp5x", - CODEC_TYPE_VIDEO, - CODEC_ID_SP5X, - sizeof(MJpegDecodeContext), - mjpeg_decode_init, - NULL, - mjpeg_decode_end, - sp5x_decode_frame, - CODEC_CAP_DR1, - NULL -}; - -#ifdef CONFIG_ENCODERS -AVCodec ljpeg_encoder = { //FIXME avoid MPV_* lossless jpeg shouldnt need them - "ljpeg", - CODEC_TYPE_VIDEO, - CODEC_ID_LJPEG, - sizeof(MpegEncContext), - MPV_encode_init, - encode_picture_lossless, - MPV_encode_end, -}; -#endif - -AVCodecParser mjpeg_parser = { - { CODEC_ID_MJPEG }, - sizeof(ParseContext), - NULL, - jpeg_parse, - ff_parse_close, -}; - -AVBitStreamFilter mjpega_dump_header_bsf = { - "mjpegadump", - 0, - mjpega_dump_header, -}; diff --git a/contrib/ffmpeg/libavcodec/mjpeg.h b/contrib/ffmpeg/libavcodec/mjpeg.h new file mode 100644 index 000000000..1916fd0cf --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mjpeg.h @@ -0,0 +1,156 @@ +/* + * MJPEG encoder and decoder + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-2004 Michael Niedermayer + * + * Support for external huffman table, various fixes (AVID workaround), + * aspecting, new decode_frame mechanism and apple mjpeg-b support + * by 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 mjpeg.h + * MJPEG encoder and decoder. + */ + +#ifndef FFMPEG_MJPEG_H +#define FFMPEG_MJPEG_H + +#include "avcodec.h" +#include "bitstream.h" + + +/* JPEG marker codes */ +typedef enum { + /* start of frame */ + SOF0 = 0xc0, /* baseline */ + SOF1 = 0xc1, /* extended sequential, huffman */ + SOF2 = 0xc2, /* progressive, huffman */ + SOF3 = 0xc3, /* lossless, huffman */ + + SOF5 = 0xc5, /* differential sequential, huffman */ + SOF6 = 0xc6, /* differential progressive, huffman */ + SOF7 = 0xc7, /* differential lossless, huffman */ + JPG = 0xc8, /* reserved for JPEG extension */ + SOF9 = 0xc9, /* extended sequential, arithmetic */ + SOF10 = 0xca, /* progressive, arithmetic */ + SOF11 = 0xcb, /* lossless, arithmetic */ + + SOF13 = 0xcd, /* differential sequential, arithmetic */ + SOF14 = 0xce, /* differential progressive, arithmetic */ + SOF15 = 0xcf, /* differential lossless, arithmetic */ + + DHT = 0xc4, /* define huffman tables */ + + DAC = 0xcc, /* define arithmetic-coding conditioning */ + + /* restart with modulo 8 count "m" */ + RST0 = 0xd0, + RST1 = 0xd1, + RST2 = 0xd2, + RST3 = 0xd3, + RST4 = 0xd4, + RST5 = 0xd5, + RST6 = 0xd6, + RST7 = 0xd7, + + SOI = 0xd8, /* start of image */ + EOI = 0xd9, /* end of image */ + SOS = 0xda, /* start of scan */ + DQT = 0xdb, /* define quantization tables */ + DNL = 0xdc, /* define number of lines */ + DRI = 0xdd, /* define restart interval */ + DHP = 0xde, /* define hierarchical progression */ + EXP = 0xdf, /* expand reference components */ + + APP0 = 0xe0, + APP1 = 0xe1, + APP2 = 0xe2, + APP3 = 0xe3, + APP4 = 0xe4, + APP5 = 0xe5, + APP6 = 0xe6, + APP7 = 0xe7, + APP8 = 0xe8, + APP9 = 0xe9, + APP10 = 0xea, + APP11 = 0xeb, + APP12 = 0xec, + APP13 = 0xed, + APP14 = 0xee, + APP15 = 0xef, + + JPG0 = 0xf0, + JPG1 = 0xf1, + JPG2 = 0xf2, + JPG3 = 0xf3, + JPG4 = 0xf4, + JPG5 = 0xf5, + JPG6 = 0xf6, + SOF48 = 0xf7, ///< JPEG-LS + LSE = 0xf8, ///< JPEG-LS extension parameters + JPG9 = 0xf9, + JPG10 = 0xfa, + JPG11 = 0xfb, + JPG12 = 0xfc, + JPG13 = 0xfd, + + COM = 0xfe, /* comment */ + + TEM = 0x01, /* temporary private use for arithmetic coding */ + + /* 0x02 -> 0xbf reserved */ +} JPEG_MARKER; + +static inline void put_marker(PutBitContext *p, int code) +{ + put_bits(p, 8, 0xff); + put_bits(p, 8, code); +} + +#define PREDICT(ret, topleft, top, left, predictor)\ + switch(predictor){\ + case 1: ret= left; break;\ + case 2: ret= top; break;\ + case 3: ret= topleft; break;\ + case 4: ret= left + top - topleft; break;\ + case 5: ret= left + ((top - topleft)>>1); break;\ + case 6: ret= top + ((left - topleft)>>1); break;\ + default:\ + case 7: ret= (left + top)>>1; break;\ + } + +extern const uint8_t ff_mjpeg_bits_dc_luminance[]; +extern const uint8_t ff_mjpeg_val_dc_luminance[]; + +extern const uint8_t ff_mjpeg_bits_dc_chrominance[]; +extern const uint8_t ff_mjpeg_val_dc_chrominance[]; + +extern const uint8_t ff_mjpeg_bits_ac_luminance[]; +extern const uint8_t ff_mjpeg_val_ac_luminance[]; + +extern const uint8_t ff_mjpeg_bits_ac_chrominance[]; +extern const uint8_t ff_mjpeg_val_ac_chrominance[]; + +void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code, + const uint8_t *bits_table, + const uint8_t *val_table); + +#endif /* FFMPEG_MJPEG_H */ diff --git a/contrib/ffmpeg/libavcodec/mjpeg_parser.c b/contrib/ffmpeg/libavcodec/mjpeg_parser.c new file mode 100644 index 000000000..aad112eb9 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mjpeg_parser.c @@ -0,0 +1,101 @@ +/* + * MJPEG parser + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-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 mjpeg_parser.c + * MJPEG parser. + */ + +#include "parser.h" + + +/** + * finds the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ + int vop_found, i; + uint16_t state; + + vop_found= pc->frame_start_found; + state= pc->state; + + i=0; + if(!vop_found){ + for(i=0; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if(state == 0xFFD8){ + i++; + vop_found=1; + break; + } + } + } + + if(vop_found){ + /* EOF considered as end of frame */ + if (buf_size == 0) + return 0; + for(; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if(state == 0xFFD8){ + pc->frame_start_found=0; + pc->state=0; + return i-1; + } + } + } + pc->frame_start_found= vop_found; + pc->state= state; + return END_NOT_FOUND; +} + +static int jpeg_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + int next; + + next= find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + + +AVCodecParser mjpeg_parser = { + { CODEC_ID_MJPEG }, + sizeof(ParseContext), + NULL, + jpeg_parse, + ff_parse_close, +}; diff --git a/contrib/ffmpeg/libavcodec/mjpega_dump_header_bsf.c b/contrib/ffmpeg/libavcodec/mjpega_dump_header_bsf.c new file mode 100644 index 000000000..a3f013174 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mjpega_dump_header_bsf.c @@ -0,0 +1,92 @@ +/* + * MJPEG A dump header bitstream filter + * Copyright (c) 2006 Baptiste Coudurier. + * + * 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 mjpega_dump_header_bsf.c + * MJPEG A dump header bitstream filter + * modifies bitstream to be decoded by quicktime + */ + +#include "avcodec.h" +#include "bytestream.h" +#include "mjpeg.h" + + +static int mjpega_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe) +{ + uint8_t *poutbufp; + int i; + + if (avctx->codec_id != CODEC_ID_MJPEG) { + av_log(avctx, AV_LOG_ERROR, "mjpega bitstream filter only applies to mjpeg codec\n"); + return 0; + } + + *poutbuf_size = 0; + *poutbuf = av_malloc(buf_size + 44 + FF_INPUT_BUFFER_PADDING_SIZE); + poutbufp = *poutbuf; + bytestream_put_byte(&poutbufp, 0xff); + bytestream_put_byte(&poutbufp, SOI); + bytestream_put_byte(&poutbufp, 0xff); + bytestream_put_byte(&poutbufp, APP1); + bytestream_put_be16(&poutbufp, 42); /* size */ + bytestream_put_be32(&poutbufp, 0); + bytestream_put_buffer(&poutbufp, "mjpg", 4); + bytestream_put_be32(&poutbufp, buf_size + 44); /* field size */ + bytestream_put_be32(&poutbufp, buf_size + 44); /* pad field size */ + bytestream_put_be32(&poutbufp, 0); /* next ptr */ + + for (i = 0; i < buf_size - 1; i++) { + if (buf[i] == 0xff) { + switch (buf[i + 1]) { + case DQT: /* quant off */ + case DHT: /* huff off */ + case SOF0: /* image off */ + bytestream_put_be32(&poutbufp, i + 46); + break; + case SOS: + bytestream_put_be32(&poutbufp, i + 46); /* scan off */ + bytestream_put_be32(&poutbufp, i + 46 + AV_RB16(buf + i + 2)); /* data off */ + bytestream_put_buffer(&poutbufp, buf + 2, buf_size - 2); /* skip already written SOI */ + *poutbuf_size = poutbufp - *poutbuf; + return 1; + case APP1: + if (i + 8 < buf_size && AV_RL32(buf + i + 8) == ff_get_fourcc("mjpg")) { + av_log(avctx, AV_LOG_ERROR, "bitstream already formatted\n"); + memcpy(*poutbuf, buf, buf_size); + *poutbuf_size = buf_size; + return 1; + } + } + } + } + av_freep(poutbuf); + av_log(avctx, AV_LOG_ERROR, "could not find SOS marker in bitstream\n"); + return 0; +} + +AVBitStreamFilter mjpega_dump_header_bsf = { + "mjpegadump", + 0, + mjpega_dump_header, +}; diff --git a/contrib/ffmpeg/libavcodec/mjpegbdec.c b/contrib/ffmpeg/libavcodec/mjpegbdec.c new file mode 100644 index 000000000..0f27379f3 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mjpegbdec.c @@ -0,0 +1,149 @@ +/* + * Apple MJPEG-B decoder + * Copyright (c) 2002 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 mjpegbdec.c + * Apple MJPEG-B decoder. + */ + +#include "avcodec.h" +#include "mjpeg.h" +#include "mjpegdec.h" + + +static int mjpegb_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + MJpegDecodeContext *s = avctx->priv_data; + const uint8_t *buf_end, *buf_ptr; + AVFrame *picture = data; + GetBitContext hgb; /* for the header */ + uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs; + uint32_t field_size, sod_offs; + + buf_ptr = buf; + buf_end = buf + buf_size; + +read_header: + /* reset on every SOI */ + s->restart_interval = 0; + s->restart_count = 0; + s->mjpb_skiptosod = 0; + + init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8); + + skip_bits(&hgb, 32); /* reserved zeros */ + + if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) + { + av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n"); + return 0; + } + + field_size = get_bits_long(&hgb, 32); /* field size */ + av_log(avctx, AV_LOG_DEBUG, "field size: 0x%x\n", field_size); + skip_bits(&hgb, 32); /* padded field size */ + second_field_offs = get_bits_long(&hgb, 32); + av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%x\n", second_field_offs); + + dqt_offs = get_bits_long(&hgb, 32); + av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%x\n", dqt_offs); + if (dqt_offs) + { + init_get_bits(&s->gb, buf_ptr+dqt_offs, (buf_end - (buf_ptr+dqt_offs))*8); + s->start_code = DQT; + ff_mjpeg_decode_dqt(s); + } + + dht_offs = get_bits_long(&hgb, 32); + av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%x\n", dht_offs); + if (dht_offs) + { + init_get_bits(&s->gb, buf_ptr+dht_offs, (buf_end - (buf_ptr+dht_offs))*8); + s->start_code = DHT; + ff_mjpeg_decode_dht(s); + } + + sof_offs = get_bits_long(&hgb, 32); + av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%x\n", sof_offs); + if (sof_offs) + { + init_get_bits(&s->gb, buf_ptr+sof_offs, (buf_end - (buf_ptr+sof_offs))*8); + s->start_code = SOF0; + if (ff_mjpeg_decode_sof(s) < 0) + return -1; + } + + sos_offs = get_bits_long(&hgb, 32); + av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%x\n", sos_offs); + sod_offs = get_bits_long(&hgb, 32); + av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs); + if (sos_offs) + { +// init_get_bits(&s->gb, buf+sos_offs, (buf_end - (buf+sos_offs))*8); + init_get_bits(&s->gb, buf_ptr+sos_offs, field_size*8); + s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); + s->start_code = SOS; + ff_mjpeg_decode_sos(s); + } + + if (s->interlaced) { + s->bottom_field ^= 1; + /* if not bottom field, do not output image yet */ + if (s->bottom_field != s->interlace_polarity && second_field_offs) + { + buf_ptr = buf + second_field_offs; + second_field_offs = 0; + goto read_header; + } + } + + //XXX FIXME factorize, this looks very similar to the EOI code + + *picture= s->picture; + *data_size = sizeof(AVFrame); + + if(!s->lossless){ + picture->quality= FFMAX(FFMAX(s->qscale[0], s->qscale[1]), s->qscale[2]); + picture->qstride= 0; + picture->qscale_table= s->qscale_table; + memset(picture->qscale_table, picture->quality, (s->width+15)/16); + if(avctx->debug & FF_DEBUG_QP) + av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality); + picture->quality*= FF_QP2LAMBDA; + } + + return buf_ptr - buf; +} + +AVCodec mjpegb_decoder = { + "mjpegb", + CODEC_TYPE_VIDEO, + CODEC_ID_MJPEGB, + sizeof(MJpegDecodeContext), + ff_mjpeg_decode_init, + NULL, + ff_mjpeg_decode_end, + mjpegb_decode_frame, + CODEC_CAP_DR1, + NULL +}; diff --git a/contrib/ffmpeg/libavcodec/mjpegdec.c b/contrib/ffmpeg/libavcodec/mjpegdec.c new file mode 100644 index 000000000..e4184d54b --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mjpegdec.c @@ -0,0 +1,1380 @@ +/* + * MJPEG decoder + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-2004 Michael Niedermayer + * + * Support for external huffman table, various fixes (AVID workaround), + * aspecting, new decode_frame mechanism and apple mjpeg-b support + * by 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 mjpegdec.c + * MJPEG decoder. + */ + +//#define DEBUG +#include <assert.h> + +#include "avcodec.h" +#include "dsputil.h" +#include "mjpeg.h" +#include "mjpegdec.h" +#include "jpeglsdec.h" + + +static int build_vlc(VLC *vlc, const uint8_t *bits_table, const uint8_t *val_table, + int nb_codes, int use_static, int is_ac) +{ + uint8_t huff_size[256+16]; + uint16_t huff_code[256+16]; + + assert(nb_codes <= 256); + + memset(huff_size, 0, sizeof(huff_size)); + ff_mjpeg_build_huffman_codes(huff_size, huff_code, bits_table, val_table); + + if(is_ac){ + memmove(huff_size+16, huff_size, sizeof(uint8_t)*nb_codes); + memmove(huff_code+16, huff_code, sizeof(uint16_t)*nb_codes); + memset(huff_size, 0, sizeof(uint8_t)*16); + memset(huff_code, 0, sizeof(uint16_t)*16); + nb_codes += 16; + } + + return init_vlc(vlc, 9, nb_codes, huff_size, 1, 1, huff_code, 2, 2, use_static); +} + +static void build_basic_mjpeg_vlc(MJpegDecodeContext * s) { + build_vlc(&s->vlcs[0][0], ff_mjpeg_bits_dc_luminance, + ff_mjpeg_val_dc_luminance, 12, 0, 0); + build_vlc(&s->vlcs[0][1], ff_mjpeg_bits_dc_chrominance, + ff_mjpeg_val_dc_chrominance, 12, 0, 0); + build_vlc(&s->vlcs[1][0], ff_mjpeg_bits_ac_luminance, + ff_mjpeg_val_ac_luminance, 251, 0, 1); + build_vlc(&s->vlcs[1][1], ff_mjpeg_bits_ac_chrominance, + ff_mjpeg_val_ac_chrominance, 251, 0, 1); +} + +int ff_mjpeg_decode_init(AVCodecContext *avctx) +{ + MJpegDecodeContext *s = avctx->priv_data; + + s->avctx = avctx; + dsputil_init(&s->dsp, avctx); + ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); + s->buffer_size = 0; + s->buffer = NULL; + s->start_code = -1; + s->first_picture = 1; + s->org_height = avctx->coded_height; + + build_basic_mjpeg_vlc(s); + + if (avctx->flags & CODEC_FLAG_EXTERN_HUFF) + { + av_log(avctx, AV_LOG_INFO, "mjpeg: using external huffman table\n"); + init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8); + if (ff_mjpeg_decode_dht(s)) { + av_log(avctx, AV_LOG_ERROR, "mjpeg: error using external huffman table, switching back to internal\n"); + build_basic_mjpeg_vlc(s); + } + } + if (avctx->extradata_size > 9 && + AV_RL32(avctx->extradata + 4) == MKTAG('f','i','e','l')) { + if (avctx->extradata[9] == 6) { /* quicktime icefloe 019 */ + s->interlace_polarity = 1; /* bottom field first */ + av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n"); + } + } + + return 0; +} + + +/* quantize tables */ +int ff_mjpeg_decode_dqt(MJpegDecodeContext *s) +{ + int len, index, i, j; + + len = get_bits(&s->gb, 16) - 2; + + while (len >= 65) { + /* only 8 bit precision handled */ + if (get_bits(&s->gb, 4) != 0) + { + av_log(s->avctx, AV_LOG_ERROR, "dqt: 16bit precision\n"); + return -1; + } + index = get_bits(&s->gb, 4); + if (index >= 4) + return -1; + av_log(s->avctx, AV_LOG_DEBUG, "index=%d\n", index); + /* read quant table */ + for(i=0;i<64;i++) { + j = s->scantable.permutated[i]; + s->quant_matrixes[index][j] = get_bits(&s->gb, 8); + } + + //XXX FIXME finetune, and perhaps add dc too + s->qscale[index]= FFMAX( + s->quant_matrixes[index][s->scantable.permutated[1]], + s->quant_matrixes[index][s->scantable.permutated[8]]) >> 1; + av_log(s->avctx, AV_LOG_DEBUG, "qscale[%d]: %d\n", index, s->qscale[index]); + len -= 65; + } + + return 0; +} + +/* decode huffman tables and build VLC decoders */ +int ff_mjpeg_decode_dht(MJpegDecodeContext *s) +{ + int len, index, i, class, n, v, code_max; + uint8_t bits_table[17]; + uint8_t val_table[256]; + + len = get_bits(&s->gb, 16) - 2; + + while (len > 0) { + if (len < 17) + return -1; + class = get_bits(&s->gb, 4); + if (class >= 2) + return -1; + index = get_bits(&s->gb, 4); + if (index >= 4) + return -1; + n = 0; + for(i=1;i<=16;i++) { + bits_table[i] = get_bits(&s->gb, 8); + n += bits_table[i]; + } + len -= 17; + if (len < n || n > 256) + return -1; + + code_max = 0; + for(i=0;i<n;i++) { + v = get_bits(&s->gb, 8); + if (v > code_max) + code_max = v; + val_table[i] = v; + } + len -= n; + + /* build VLC and flush previous vlc if present */ + free_vlc(&s->vlcs[class][index]); + av_log(s->avctx, AV_LOG_DEBUG, "class=%d index=%d nb_codes=%d\n", + class, index, code_max + 1); + if(build_vlc(&s->vlcs[class][index], bits_table, val_table, code_max + 1, 0, class > 0) < 0){ + return -1; + } + } + return 0; +} + +int ff_mjpeg_decode_sof(MJpegDecodeContext *s) +{ + int len, nb_components, i, width, height, pix_fmt_id; + + /* XXX: verify len field validity */ + len = get_bits(&s->gb, 16); + s->bits= get_bits(&s->gb, 8); + + if(s->pegasus_rct) s->bits=9; + if(s->bits==9 && !s->pegasus_rct) s->rct=1; //FIXME ugly + + if (s->bits != 8 && !s->lossless){ + av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n"); + return -1; + } + + height = get_bits(&s->gb, 16); + width = get_bits(&s->gb, 16); + + //HACK for odd_height.mov + if(s->interlaced && s->width == width && s->height == height + 1) + height= s->height; + + av_log(s->avctx, AV_LOG_DEBUG, "sof0: picture: %dx%d\n", width, height); + if(avcodec_check_dimensions(s->avctx, width, height)) + return -1; + + nb_components = get_bits(&s->gb, 8); + if (nb_components <= 0 || + nb_components > MAX_COMPONENTS) + return -1; + if (s->ls && !(s->bits <= 8 || nb_components == 1)){ + av_log(s->avctx, AV_LOG_ERROR, "only <= 8 bits/component or 16-bit gray accepted for JPEG-LS\n"); + return -1; + } + s->nb_components = nb_components; + s->h_max = 1; + s->v_max = 1; + for(i=0;i<nb_components;i++) { + /* component id */ + s->component_id[i] = get_bits(&s->gb, 8) - 1; + s->h_count[i] = get_bits(&s->gb, 4); + s->v_count[i] = get_bits(&s->gb, 4); + /* compute hmax and vmax (only used in interleaved case) */ + if (s->h_count[i] > s->h_max) + s->h_max = s->h_count[i]; + if (s->v_count[i] > s->v_max) + s->v_max = s->v_count[i]; + s->quant_index[i] = get_bits(&s->gb, 8); + if (s->quant_index[i] >= 4) + return -1; + av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n", i, s->h_count[i], + s->v_count[i], s->component_id[i], s->quant_index[i]); + } + + if(s->ls && (s->h_max > 1 || s->v_max > 1)) { + av_log(s->avctx, AV_LOG_ERROR, "Subsampling in JPEG-LS is not supported.\n"); + return -1; + } + + if(s->v_max==1 && s->h_max==1 && s->lossless==1) s->rgb=1; + + /* if different size, realloc/alloc picture */ + /* XXX: also check h_count and v_count */ + if (width != s->width || height != s->height) { + av_freep(&s->qscale_table); + + s->width = width; + s->height = height; + s->interlaced = 0; + + /* test interlaced mode */ + if (s->first_picture && + s->org_height != 0 && + s->height < ((s->org_height * 3) / 4)) { + s->interlaced = 1; + s->bottom_field = s->interlace_polarity; + s->picture.interlaced_frame = 1; + s->picture.top_field_first = !s->interlace_polarity; + height *= 2; + } + + avcodec_set_dimensions(s->avctx, width, height); + + s->qscale_table= av_mallocz((s->width+15)/16); + + s->first_picture = 0; + } + + if(s->interlaced && (s->bottom_field == !s->interlace_polarity)) + return 0; + + /* XXX: not complete test ! */ + pix_fmt_id = (s->h_count[0] << 20) | (s->v_count[0] << 16) | + (s->h_count[1] << 12) | (s->v_count[1] << 8) | + (s->h_count[2] << 4) | s->v_count[2]; + av_log(s->avctx, AV_LOG_DEBUG, "pix fmt id %x\n", pix_fmt_id); + switch(pix_fmt_id){ + case 0x222222: + case 0x111111: + if(s->rgb){ + s->avctx->pix_fmt = PIX_FMT_RGB32; + }else if(s->nb_components==3) + s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P; + else + s->avctx->pix_fmt = PIX_FMT_GRAY8; + break; + case 0x110000: + s->avctx->pix_fmt = PIX_FMT_GRAY8; + break; + case 0x121111: + s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV440P : PIX_FMT_YUVJ440P; + break; + case 0x211111: + case 0x221212: + s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P; + break; + case 0x221111: + s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420P; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id); + return -1; + } + if(s->ls){ + if(s->nb_components > 1) + s->avctx->pix_fmt = PIX_FMT_RGB24; + else if(s->bits <= 8) + s->avctx->pix_fmt = PIX_FMT_GRAY8; + else + s->avctx->pix_fmt = PIX_FMT_GRAY16; + } + + if(s->picture.data[0]) + s->avctx->release_buffer(s->avctx, &s->picture); + + s->picture.reference= 0; + if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){ + av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + s->picture.pict_type= I_TYPE; + s->picture.key_frame= 1; + + for(i=0; i<3; i++){ + s->linesize[i]= s->picture.linesize[i] << s->interlaced; + } + +// printf("%d %d %d %d %d %d\n", s->width, s->height, s->linesize[0], s->linesize[1], s->interlaced, s->avctx->height); + + if (len != (8+(3*nb_components))) + { + av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len); + } + + /* totally blank picture as progressive JPEG will only add details to it */ + if(s->progressive){ + memset(s->picture.data[0], 0, s->picture.linesize[0] * s->height); + memset(s->picture.data[1], 0, s->picture.linesize[1] * s->height >> (s->v_max - s->v_count[1])); + memset(s->picture.data[2], 0, s->picture.linesize[2] * s->height >> (s->v_max - s->v_count[2])); + } + return 0; +} + +static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index) +{ + int code; + code = get_vlc2(&s->gb, s->vlcs[0][dc_index].table, 9, 2); + if (code < 0) + { + av_log(s->avctx, AV_LOG_WARNING, "mjpeg_decode_dc: bad vlc: %d:%d (%p)\n", 0, dc_index, + &s->vlcs[0][dc_index]); + return 0xffff; + } + + if(code) + return get_xbits(&s->gb, code); + else + return 0; +} + +/* decode block and dequantize */ +static int decode_block(MJpegDecodeContext *s, DCTELEM *block, + int component, int dc_index, int ac_index, int16_t *quant_matrix) +{ + int code, i, j, level, val; + + /* DC coef */ + val = mjpeg_decode_dc(s, dc_index); + if (val == 0xffff) { + av_log(s->avctx, AV_LOG_ERROR, "error dc\n"); + return -1; + } + val = val * quant_matrix[0] + s->last_dc[component]; + s->last_dc[component] = val; + block[0] = val; + /* AC coefs */ + i = 0; + {OPEN_READER(re, &s->gb) + for(;;) { + UPDATE_CACHE(re, &s->gb); + GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2) + + /* EOB */ + if (code == 0x10) + break; + i += ((unsigned)code) >> 4; + if(code != 0x100){ + code &= 0xf; + if(code > MIN_CACHE_BITS - 16){ + UPDATE_CACHE(re, &s->gb) + } + { + int cache=GET_CACHE(re,&s->gb); + int sign=(~cache)>>31; + level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign; + } + + LAST_SKIP_BITS(re, &s->gb, code) + + if (i >= 63) { + if(i == 63){ + j = s->scantable.permutated[63]; + block[j] = level * quant_matrix[j]; + break; + } + av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); + return -1; + } + j = s->scantable.permutated[i]; + block[j] = level * quant_matrix[j]; + } + } + CLOSE_READER(re, &s->gb)} + + return 0; +} + +/* decode block and dequantize - progressive JPEG version */ +static int decode_block_progressive(MJpegDecodeContext *s, DCTELEM *block, + int component, int dc_index, int ac_index, int16_t *quant_matrix, + int ss, int se, int Ah, int Al, int *EOBRUN) +{ + int code, i, j, level, val, run; + + /* DC coef */ + if(!ss){ + val = mjpeg_decode_dc(s, dc_index); + if (val == 0xffff) { + av_log(s->avctx, AV_LOG_ERROR, "error dc\n"); + return -1; + } + val = (val * quant_matrix[0] << Al) + s->last_dc[component]; + }else + val = 0; + s->last_dc[component] = val; + block[0] = val; + if(!se) return 0; + /* AC coefs */ + if(*EOBRUN){ + (*EOBRUN)--; + return 0; + } + {OPEN_READER(re, &s->gb) + for(i=ss;;i++) { + UPDATE_CACHE(re, &s->gb); + GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2) + /* Progressive JPEG use AC coeffs from zero and this decoder sets offset 16 by default */ + code -= 16; + if(code & 0xF) { + i += ((unsigned) code) >> 4; + code &= 0xf; + if(code > MIN_CACHE_BITS - 16){ + UPDATE_CACHE(re, &s->gb) + } + { + int cache=GET_CACHE(re,&s->gb); + int sign=(~cache)>>31; + level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign; + } + + LAST_SKIP_BITS(re, &s->gb, code) + + if (i >= se) { + if(i == se){ + j = s->scantable.permutated[se]; + block[j] = level * quant_matrix[j] << Al; + break; + } + av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); + return -1; + } + j = s->scantable.permutated[i]; + block[j] = level * quant_matrix[j] << Al; + }else{ + run = ((unsigned) code) >> 4; + if(run == 0xF){// ZRL - skip 15 coefficients + i += 15; + }else{ + val = run; + run = (1 << run); + UPDATE_CACHE(re, &s->gb); + run += (GET_CACHE(re, &s->gb) >> (32 - val)) & (run - 1); + if(val) + LAST_SKIP_BITS(re, &s->gb, val); + *EOBRUN = run - 1; + break; + } + } + } + CLOSE_READER(re, &s->gb)} + + return 0; +} + +static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, int point_transform){ + int i, mb_x, mb_y; + uint16_t buffer[32768][4]; + int left[3], top[3], topleft[3]; + const int linesize= s->linesize[0]; + const int mask= (1<<s->bits)-1; + + if((unsigned)s->mb_width > 32768) //dynamic alloc + return -1; + + for(i=0; i<3; i++){ + buffer[0][i]= 1 << (s->bits + point_transform - 1); + } + for(mb_y = 0; mb_y < s->mb_height; mb_y++) { + const int modified_predictor= mb_y ? predictor : 1; + uint8_t *ptr = s->picture.data[0] + (linesize * mb_y); + + if (s->interlaced && s->bottom_field) + ptr += linesize >> 1; + + for(i=0; i<3; i++){ + top[i]= left[i]= topleft[i]= buffer[0][i]; + } + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + if (s->restart_interval && !s->restart_count) + s->restart_count = s->restart_interval; + + for(i=0;i<3;i++) { + int pred; + + topleft[i]= top[i]; + top[i]= buffer[mb_x][i]; + + PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); + + left[i]= + buffer[mb_x][i]= mask & (pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform)); + } + + if (s->restart_interval && !--s->restart_count) { + align_get_bits(&s->gb); + skip_bits(&s->gb, 16); /* skip RSTn */ + } + } + + if(s->rct){ + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200)>>2); + ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1]; + ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1]; + } + }else if(s->pegasus_rct){ + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + ptr[4*mb_x+1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2])>>2); + ptr[4*mb_x+0] = buffer[mb_x][1] + ptr[4*mb_x+1]; + ptr[4*mb_x+2] = buffer[mb_x][2] + ptr[4*mb_x+1]; + } + }else{ + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + ptr[4*mb_x+0] = buffer[mb_x][0]; + ptr[4*mb_x+1] = buffer[mb_x][1]; + ptr[4*mb_x+2] = buffer[mb_x][2]; + } + } + } + return 0; +} + +static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point_transform){ + int i, mb_x, mb_y; + const int nb_components=3; + + for(mb_y = 0; mb_y < s->mb_height; mb_y++) { + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + if (s->restart_interval && !s->restart_count) + s->restart_count = s->restart_interval; + + if(mb_x==0 || mb_y==0 || s->interlaced){ + for(i=0;i<nb_components;i++) { + uint8_t *ptr; + int n, h, v, x, y, c, j, linesize; + n = s->nb_blocks[i]; + c = s->comp_index[i]; + h = s->h_scount[i]; + v = s->v_scount[i]; + x = 0; + y = 0; + linesize= s->linesize[c]; + + for(j=0; j<n; j++) { + int pred; + + ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap + if(y==0 && mb_y==0){ + if(x==0 && mb_x==0){ + pred= 128 << point_transform; + }else{ + pred= ptr[-1]; + } + }else{ + if(x==0 && mb_x==0){ + pred= ptr[-linesize]; + }else{ + PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); + } + } + + if (s->interlaced && s->bottom_field) + ptr += linesize >> 1; + *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform); + + if (++x == h) { + x = 0; + y++; + } + } + } + }else{ + for(i=0;i<nb_components;i++) { + uint8_t *ptr; + int n, h, v, x, y, c, j, linesize; + n = s->nb_blocks[i]; + c = s->comp_index[i]; + h = s->h_scount[i]; + v = s->v_scount[i]; + x = 0; + y = 0; + linesize= s->linesize[c]; + + for(j=0; j<n; j++) { + int pred; + + ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap + PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); + *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform); + if (++x == h) { + x = 0; + y++; + } + } + } + } + if (s->restart_interval && !--s->restart_count) { + align_get_bits(&s->gb); + skip_bits(&s->gb, 16); /* skip RSTn */ + } + } + } + return 0; +} + +static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int ss, int se, int Ah, int Al){ + int i, mb_x, mb_y; + int EOBRUN = 0; + uint8_t* data[MAX_COMPONENTS]; + int linesize[MAX_COMPONENTS]; + + if(Ah) return 0; /* TODO decode refinement planes too */ + + for(i=0; i < nb_components; i++) { + int c = s->comp_index[i]; + data[c] = s->picture.data[c]; + linesize[c]=s->linesize[c]; + if(s->avctx->codec->id==CODEC_ID_AMV) { + //picture should be flipped upside-down for this codec + assert(!(s->avctx->flags & CODEC_FLAG_EMU_EDGE)); + data[c] += (linesize[c] * (s->v_scount[i] * (8 * s->mb_height -((s->height/s->v_max)&7)) - 1 )); + linesize[c] *= -1; + } + } + + for(mb_y = 0; mb_y < s->mb_height; mb_y++) { + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + if (s->restart_interval && !s->restart_count) + s->restart_count = s->restart_interval; + + for(i=0;i<nb_components;i++) { + uint8_t *ptr; + int n, h, v, x, y, c, j; + n = s->nb_blocks[i]; + c = s->comp_index[i]; + h = s->h_scount[i]; + v = s->v_scount[i]; + x = 0; + y = 0; + for(j=0;j<n;j++) { + memset(s->block, 0, sizeof(s->block)); + if (!s->progressive && decode_block(s, s->block, i, + s->dc_index[i], s->ac_index[i], + s->quant_matrixes[ s->quant_index[c] ]) < 0) { + av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); + return -1; + } + if (s->progressive && decode_block_progressive(s, s->block, i, + s->dc_index[i], s->ac_index[i], + s->quant_matrixes[ s->quant_index[c] ], ss, se, Ah, Al, &EOBRUN) < 0) { + av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); + return -1; + } +// av_log(s->avctx, AV_LOG_DEBUG, "mb: %d %d processed\n", mb_y, mb_x); + ptr = data[c] + + (((linesize[c] * (v * mb_y + y) * 8) + + (h * mb_x + x) * 8) >> s->avctx->lowres); + if (s->interlaced && s->bottom_field) + ptr += linesize[c] >> 1; +//av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d \n", mb_x, mb_y, x, y, c, s->bottom_field, (v * mb_y + y) * 8, (h * mb_x + x) * 8); + if(!s->progressive) + s->dsp.idct_put(ptr, linesize[c], s->block); + else + s->dsp.idct_add(ptr, linesize[c], s->block); + if (++x == h) { + x = 0; + y++; + } + } + } + /* (< 1350) buggy workaround for Spectralfan.mov, should be fixed */ + if (s->restart_interval && (s->restart_interval < 1350) && + !--s->restart_count) { + align_get_bits(&s->gb); + skip_bits(&s->gb, 16); /* skip RSTn */ + for (i=0; i<nb_components; i++) /* reset dc */ + s->last_dc[i] = 1024; + } + } + } + return 0; +} + +int ff_mjpeg_decode_sos(MJpegDecodeContext *s) +{ + int len, nb_components, i, h, v, predictor, point_transform; + int vmax, hmax, index, id; + const int block_size= s->lossless ? 1 : 8; + int ilv, prev_shift; + + /* XXX: verify len field validity */ + len = get_bits(&s->gb, 16); + nb_components = get_bits(&s->gb, 8); + if (len != 6+2*nb_components) + { + av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len); + return -1; + } + vmax = 0; + hmax = 0; + for(i=0;i<nb_components;i++) { + id = get_bits(&s->gb, 8) - 1; + av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id); + /* find component index */ + for(index=0;index<s->nb_components;index++) + if (id == s->component_id[index]) + break; + if (index == s->nb_components) + { + av_log(s->avctx, AV_LOG_ERROR, "decode_sos: index(%d) out of components\n", index); + return -1; + } + + s->comp_index[i] = index; + + s->nb_blocks[i] = s->h_count[index] * s->v_count[index]; + s->h_scount[i] = s->h_count[index]; + s->v_scount[i] = s->v_count[index]; + + s->dc_index[i] = get_bits(&s->gb, 4); + s->ac_index[i] = get_bits(&s->gb, 4); + + if (s->dc_index[i] < 0 || s->ac_index[i] < 0 || + s->dc_index[i] >= 4 || s->ac_index[i] >= 4) + goto out_of_range; +#if 0 //buggy + switch(s->start_code) + { + case SOF0: + if (dc_index[i] > 1 || ac_index[i] > 1) + goto out_of_range; + break; + case SOF1: + case SOF2: + if (dc_index[i] > 3 || ac_index[i] > 3) + goto out_of_range; + break; + case SOF3: + if (dc_index[i] > 3 || ac_index[i] != 0) + goto out_of_range; + break; + } +#endif + } + + predictor= get_bits(&s->gb, 8); /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */ + ilv= get_bits(&s->gb, 8); /* JPEG Se / JPEG-LS ILV */ + prev_shift = get_bits(&s->gb, 4); /* Ah */ + point_transform= get_bits(&s->gb, 4); /* Al */ + + for(i=0;i<nb_components;i++) + s->last_dc[i] = 1024; + + if (nb_components > 1) { + /* interleaved stream */ + s->mb_width = (s->width + s->h_max * block_size - 1) / (s->h_max * block_size); + s->mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size); + } else if(!s->ls) { /* skip this for JPEG-LS */ + h = s->h_max / s->h_scount[0]; + v = s->v_max / s->v_scount[0]; + s->mb_width = (s->width + h * block_size - 1) / (h * block_size); + s->mb_height = (s->height + v * block_size - 1) / (v * block_size); + s->nb_blocks[0] = 1; + s->h_scount[0] = 1; + s->v_scount[0] = 1; + } + + if(s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d %s\n", s->lossless ? "lossless" : "sequencial DCT", s->rgb ? "RGB" : "", + predictor, point_transform, ilv, s->bits, + s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : "")); + + + /* mjpeg-b can have padding bytes between sos and image data, skip them */ + for (i = s->mjpb_skiptosod; i > 0; i--) + skip_bits(&s->gb, 8); + + if(s->lossless){ + if(ENABLE_JPEGLS_DECODER && s->ls){ +// for(){ +// reset_ls_coding_parameters(s, 0); + + ff_jpegls_decode_picture(s, predictor, point_transform, ilv); + }else{ + if(s->rgb){ + if(ljpeg_decode_rgb_scan(s, predictor, point_transform) < 0) + return -1; + }else{ + if(ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0) + return -1; + } + } + }else{ + if(mjpeg_decode_scan(s, nb_components, predictor, ilv, prev_shift, point_transform) < 0) + return -1; + } + emms_c(); + return 0; + out_of_range: + av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n"); + return -1; +} + +static int mjpeg_decode_dri(MJpegDecodeContext *s) +{ + if (get_bits(&s->gb, 16) != 4) + return -1; + s->restart_interval = get_bits(&s->gb, 16); + s->restart_count = 0; + av_log(s->avctx, AV_LOG_DEBUG, "restart interval: %d\n", s->restart_interval); + + return 0; +} + +static int mjpeg_decode_app(MJpegDecodeContext *s) +{ + int len, id, i; + + len = get_bits(&s->gb, 16); + if (len < 5) + return -1; + if(8*len + get_bits_count(&s->gb) > s->gb.size_in_bits) + return -1; + + id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); + id = be2me_32(id); + len -= 6; + + if(s->avctx->debug & FF_DEBUG_STARTCODE){ + av_log(s->avctx, AV_LOG_DEBUG, "APPx %8X\n", id); + } + + /* buggy AVID, it puts EOI only at every 10th frame */ + /* also this fourcc is used by non-avid files too, it holds some + informations, but it's always present in AVID creates files */ + if (id == ff_get_fourcc("AVI1")) + { + /* structure: + 4bytes AVI1 + 1bytes polarity + 1bytes always zero + 4bytes field_size + 4bytes field_size_less_padding + */ + s->buggy_avid = 1; +// if (s->first_picture) +// printf("mjpeg: workarounding buggy AVID\n"); + i = get_bits(&s->gb, 8); + if (i==2) s->bottom_field= 1; + else if(i==1) s->bottom_field= 0; +#if 0 + skip_bits(&s->gb, 8); + skip_bits(&s->gb, 32); + skip_bits(&s->gb, 32); + len -= 10; +#endif +// if (s->interlace_polarity) +// printf("mjpeg: interlace polarity: %d\n", s->interlace_polarity); + goto out; + } + +// len -= 2; + + if (id == ff_get_fourcc("JFIF")) + { + int t_w, t_h, v1, v2; + skip_bits(&s->gb, 8); /* the trailing zero-byte */ + v1= get_bits(&s->gb, 8); + v2= get_bits(&s->gb, 8); + skip_bits(&s->gb, 8); + + s->avctx->sample_aspect_ratio.num= get_bits(&s->gb, 16); + s->avctx->sample_aspect_ratio.den= get_bits(&s->gb, 16); + + if (s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_INFO, "mjpeg: JFIF header found (version: %x.%x) SAR=%d/%d\n", + v1, v2, + s->avctx->sample_aspect_ratio.num, + s->avctx->sample_aspect_ratio.den + ); + + t_w = get_bits(&s->gb, 8); + t_h = get_bits(&s->gb, 8); + if (t_w && t_h) + { + /* skip thumbnail */ + if (len-10-(t_w*t_h*3) > 0) + len -= t_w*t_h*3; + } + len -= 10; + goto out; + } + + if (id == ff_get_fourcc("Adob") && (get_bits(&s->gb, 8) == 'e')) + { + if (s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_INFO, "mjpeg: Adobe header found\n"); + skip_bits(&s->gb, 16); /* version */ + skip_bits(&s->gb, 16); /* flags0 */ + skip_bits(&s->gb, 16); /* flags1 */ + skip_bits(&s->gb, 8); /* transform */ + len -= 7; + goto out; + } + + if (id == ff_get_fourcc("LJIF")){ + if (s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_INFO, "Pegasus lossless jpeg header found\n"); + skip_bits(&s->gb, 16); /* version ? */ + skip_bits(&s->gb, 16); /* unknwon always 0? */ + skip_bits(&s->gb, 16); /* unknwon always 0? */ + skip_bits(&s->gb, 16); /* unknwon always 0? */ + switch( get_bits(&s->gb, 8)){ + case 1: + s->rgb= 1; + s->pegasus_rct=0; + break; + case 2: + s->rgb= 1; + s->pegasus_rct=1; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace\n"); + } + len -= 9; + goto out; + } + + /* Apple MJPEG-A */ + if ((s->start_code == APP1) && (len > (0x28 - 8))) + { + id = (get_bits(&s->gb, 16) << 16) | get_bits(&s->gb, 16); + id = be2me_32(id); + len -= 4; + if (id == ff_get_fourcc("mjpg")) /* Apple MJPEG-A */ + { +#if 0 + skip_bits(&s->gb, 32); /* field size */ + skip_bits(&s->gb, 32); /* pad field size */ + skip_bits(&s->gb, 32); /* next off */ + skip_bits(&s->gb, 32); /* quant off */ + skip_bits(&s->gb, 32); /* huff off */ + skip_bits(&s->gb, 32); /* image off */ + skip_bits(&s->gb, 32); /* scan off */ + skip_bits(&s->gb, 32); /* data off */ +#endif + if (s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_INFO, "mjpeg: Apple MJPEG-A header found\n"); + } + } + +out: + /* slow but needed for extreme adobe jpegs */ + if (len < 0) + av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error, decode_app parser read over the end\n"); + while(--len > 0) + skip_bits(&s->gb, 8); + + return 0; +} + +static int mjpeg_decode_com(MJpegDecodeContext *s) +{ + int len = get_bits(&s->gb, 16); + if (len >= 2 && 8*len - 16 + get_bits_count(&s->gb) <= s->gb.size_in_bits) { + char *cbuf = av_malloc(len - 1); + if (cbuf) { + int i; + for (i = 0; i < len - 2; i++) + cbuf[i] = get_bits(&s->gb, 8); + if (i > 0 && cbuf[i-1] == '\n') + cbuf[i-1] = 0; + else + cbuf[i] = 0; + + if(s->avctx->debug & FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_INFO, "mjpeg comment: '%s'\n", cbuf); + + /* buggy avid, it puts EOI only at every 10th frame */ + if (!strcmp(cbuf, "AVID")) + { + s->buggy_avid = 1; + // if (s->first_picture) + // printf("mjpeg: workarounding buggy AVID\n"); + } + else if(!strcmp(cbuf, "CS=ITU601")){ + s->cs_itu601= 1; + } + + av_free(cbuf); + } + } + + return 0; +} + +#if 0 +static int valid_marker_list[] = +{ + /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f */ +/* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* c */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* d */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* f */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, +} +#endif + +/* return the 8 bit start code value and update the search + state. Return -1 if no start code found */ +static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end) +{ + const uint8_t *buf_ptr; + unsigned int v, v2; + int val; +#ifdef DEBUG + int skipped=0; +#endif + + buf_ptr = *pbuf_ptr; + while (buf_ptr < buf_end) { + v = *buf_ptr++; + v2 = *buf_ptr; + if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe) && buf_ptr < buf_end) { + val = *buf_ptr++; + goto found; + } +#ifdef DEBUG + skipped++; +#endif + } + val = -1; +found: +#ifdef DEBUG + av_log(NULL, AV_LOG_VERBOSE, "find_marker skipped %d bytes\n", skipped); +#endif + *pbuf_ptr = buf_ptr; + return val; +} + +int ff_mjpeg_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + MJpegDecodeContext *s = avctx->priv_data; + const uint8_t *buf_end, *buf_ptr; + int start_code; + AVFrame *picture = data; + + buf_ptr = buf; + buf_end = buf + buf_size; + while (buf_ptr < buf_end) { + /* find start next marker */ + start_code = find_marker(&buf_ptr, buf_end); + { + /* EOF */ + if (start_code < 0) { + goto the_end; + } else { + av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", start_code, buf_end - buf_ptr); + + if ((buf_end - buf_ptr) > s->buffer_size) + { + av_free(s->buffer); + s->buffer_size = buf_end-buf_ptr; + s->buffer = av_malloc(s->buffer_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_log(avctx, AV_LOG_DEBUG, "buffer too small, expanding to %d bytes\n", + s->buffer_size); + } + + /* unescape buffer of SOS, use special treatment for JPEG-LS */ + if (start_code == SOS && !s->ls) + { + const uint8_t *src = buf_ptr; + uint8_t *dst = s->buffer; + + while (src<buf_end) + { + uint8_t x = *(src++); + + *(dst++) = x; + if (avctx->codec_id != CODEC_ID_THP) + { + if (x == 0xff) { + while (src < buf_end && x == 0xff) + x = *(src++); + + if (x >= 0xd0 && x <= 0xd7) + *(dst++) = x; + else if (x) + break; + } + } + } + init_get_bits(&s->gb, s->buffer, (dst - s->buffer)*8); + + av_log(avctx, AV_LOG_DEBUG, "escaping removed %td bytes\n", + (buf_end - buf_ptr) - (dst - s->buffer)); + } + else if(start_code == SOS && s->ls){ + const uint8_t *src = buf_ptr; + uint8_t *dst = s->buffer; + int bit_count = 0; + int t = 0, b = 0; + PutBitContext pb; + + s->cur_scan++; + + /* find marker */ + while (src + t < buf_end){ + uint8_t x = src[t++]; + if (x == 0xff){ + while((src + t < buf_end) && x == 0xff) + x = src[t++]; + if (x & 0x80) { + t -= 2; + break; + } + } + } + bit_count = t * 8; + + init_put_bits(&pb, dst, t); + + /* unescape bitstream */ + while(b < t){ + uint8_t x = src[b++]; + put_bits(&pb, 8, x); + if(x == 0xFF){ + x = src[b++]; + put_bits(&pb, 7, x); + bit_count--; + } + } + flush_put_bits(&pb); + + init_get_bits(&s->gb, dst, bit_count); + } + else + init_get_bits(&s->gb, buf_ptr, (buf_end - buf_ptr)*8); + + s->start_code = start_code; + if(s->avctx->debug & FF_DEBUG_STARTCODE){ + av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code); + } + + /* process markers */ + if (start_code >= 0xd0 && start_code <= 0xd7) { + av_log(avctx, AV_LOG_DEBUG, "restart marker: %d\n", start_code&0x0f); + /* APP fields */ + } else if (start_code >= APP0 && start_code <= APP15) { + mjpeg_decode_app(s); + /* Comment */ + } else if (start_code == COM){ + mjpeg_decode_com(s); + } + + switch(start_code) { + case SOI: + s->restart_interval = 0; + + s->restart_count = 0; + /* nothing to do on SOI */ + break; + case DQT: + ff_mjpeg_decode_dqt(s); + break; + case DHT: + if(ff_mjpeg_decode_dht(s) < 0){ + av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n"); + return -1; + } + break; + case SOF0: + s->lossless=0; + s->ls=0; + s->progressive=0; + if (ff_mjpeg_decode_sof(s) < 0) + return -1; + break; + case SOF2: + s->lossless=0; + s->ls=0; + s->progressive=1; + if (ff_mjpeg_decode_sof(s) < 0) + return -1; + break; + case SOF3: + s->lossless=1; + s->ls=0; + s->progressive=0; + if (ff_mjpeg_decode_sof(s) < 0) + return -1; + break; + case SOF48: + s->lossless=1; + s->ls=1; + s->progressive=0; + if (ff_mjpeg_decode_sof(s) < 0) + return -1; + break; + case LSE: + if (!ENABLE_JPEGLS_DECODER || ff_jpegls_decode_lse(s) < 0) + return -1; + break; + case EOI: + s->cur_scan = 0; + if ((s->buggy_avid && !s->interlaced) || s->restart_interval) + break; +eoi_parser: + { + if (s->interlaced) { + s->bottom_field ^= 1; + /* if not bottom field, do not output image yet */ + if (s->bottom_field == !s->interlace_polarity) + goto not_the_end; + } + *picture = s->picture; + *data_size = sizeof(AVFrame); + + if(!s->lossless){ + picture->quality= FFMAX(FFMAX(s->qscale[0], s->qscale[1]), s->qscale[2]); + picture->qstride= 0; + picture->qscale_table= s->qscale_table; + memset(picture->qscale_table, picture->quality, (s->width+15)/16); + if(avctx->debug & FF_DEBUG_QP) + av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality); + picture->quality*= FF_QP2LAMBDA; + } + + goto the_end; + } + break; + case SOS: + ff_mjpeg_decode_sos(s); + /* buggy avid puts EOI every 10-20th frame */ + /* if restart period is over process EOI */ + if ((s->buggy_avid && !s->interlaced) || s->restart_interval) + goto eoi_parser; + break; + case DRI: + mjpeg_decode_dri(s); + break; + case SOF1: + case SOF5: + case SOF6: + case SOF7: + case SOF9: + case SOF10: + case SOF11: + case SOF13: + case SOF14: + case SOF15: + case JPG: + av_log(avctx, AV_LOG_ERROR, "mjpeg: unsupported coding type (%x)\n", start_code); + break; +// default: +// printf("mjpeg: unsupported marker (%x)\n", start_code); +// break; + } + +not_the_end: + /* eof process start code */ + buf_ptr += (get_bits_count(&s->gb)+7)/8; + av_log(avctx, AV_LOG_DEBUG, "marker parser used %d bytes (%d bits)\n", + (get_bits_count(&s->gb)+7)/8, get_bits_count(&s->gb)); + } + } + } +the_end: + av_log(avctx, AV_LOG_DEBUG, "mjpeg decode frame unused %td bytes\n", buf_end - buf_ptr); +// return buf_end - buf_ptr; + return buf_ptr - buf; +} + +int ff_mjpeg_decode_end(AVCodecContext *avctx) +{ + MJpegDecodeContext *s = avctx->priv_data; + int i, j; + + av_free(s->buffer); + av_free(s->qscale_table); + + for(i=0;i<2;i++) { + for(j=0;j<4;j++) + free_vlc(&s->vlcs[i][j]); + } + return 0; +} + +AVCodec mjpeg_decoder = { + "mjpeg", + CODEC_TYPE_VIDEO, + CODEC_ID_MJPEG, + sizeof(MJpegDecodeContext), + ff_mjpeg_decode_init, + NULL, + ff_mjpeg_decode_end, + ff_mjpeg_decode_frame, + CODEC_CAP_DR1, + NULL +}; + +AVCodec thp_decoder = { + "thp", + CODEC_TYPE_VIDEO, + CODEC_ID_THP, + sizeof(MJpegDecodeContext), + ff_mjpeg_decode_init, + NULL, + ff_mjpeg_decode_end, + ff_mjpeg_decode_frame, + CODEC_CAP_DR1, + NULL +}; diff --git a/contrib/ffmpeg/libavcodec/mjpegdec.h b/contrib/ffmpeg/libavcodec/mjpegdec.h new file mode 100644 index 000000000..d97b176a9 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mjpegdec.h @@ -0,0 +1,112 @@ +/* + * MJPEG decoder + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-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 mjpegdec.h + * MJPEG decoder. + */ + +#ifndef FFMPEG_MJPEGDEC_H +#define FFMPEG_MJPEGDEC_H + +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" +#include "mpegvideo.h" + +#define MAX_COMPONENTS 4 + +typedef struct MJpegDecodeContext { + AVCodecContext *avctx; + GetBitContext gb; + + int start_code; /* current start code */ + int buffer_size; + uint8_t *buffer; + + int16_t quant_matrixes[4][64]; + VLC vlcs[2][4]; + int qscale[4]; ///< quantizer scale calculated from quant_matrixes + + int org_height; /* size given at codec init */ + int first_picture; /* true if decoding first picture */ + int interlaced; /* true if interlaced */ + int bottom_field; /* true if bottom field */ + int lossless; + int ls; + int progressive; + int rgb; + int rct; /* standard rct */ + int pegasus_rct; /* pegasus reversible colorspace transform */ + int bits; /* bits per component */ + + int maxval; + int near; ///< near lossless bound (si 0 for lossless) + int t1,t2,t3; + int reset; ///< context halfing intervall ?rename + + int width, height; + int mb_width, mb_height; + int nb_components; + int component_id[MAX_COMPONENTS]; + int h_count[MAX_COMPONENTS]; /* horizontal and vertical count for each component */ + int v_count[MAX_COMPONENTS]; + int comp_index[MAX_COMPONENTS]; + int dc_index[MAX_COMPONENTS]; + int ac_index[MAX_COMPONENTS]; + int nb_blocks[MAX_COMPONENTS]; + int h_scount[MAX_COMPONENTS]; + int v_scount[MAX_COMPONENTS]; + int h_max, v_max; /* maximum h and v counts */ + int quant_index[4]; /* quant table index for each component */ + int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */ + AVFrame picture; /* picture structure */ + int linesize[MAX_COMPONENTS]; ///< linesize << interlaced + int8_t *qscale_table; + DECLARE_ALIGNED_8(DCTELEM, block[64]); + ScanTable scantable; + DSPContext dsp; + + int restart_interval; + int restart_count; + + int buggy_avid; + int cs_itu601; + int interlace_polarity; + + int mjpb_skiptosod; + + int cur_scan; /* current scan, used by JPEG-LS */ +} MJpegDecodeContext; + +int ff_mjpeg_decode_init(AVCodecContext *avctx); +int ff_mjpeg_decode_end(AVCodecContext *avctx); +int ff_mjpeg_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size); +int ff_mjpeg_decode_dqt(MJpegDecodeContext *s); +int ff_mjpeg_decode_dht(MJpegDecodeContext *s); +int ff_mjpeg_decode_sof(MJpegDecodeContext *s); +int ff_mjpeg_decode_sos(MJpegDecodeContext *s); + +#endif /* FFMPEG_MJPEGDEC_H */ diff --git a/contrib/ffmpeg/libavcodec/mjpegenc.c b/contrib/ffmpeg/libavcodec/mjpegenc.c new file mode 100644 index 000000000..b5e5a827d --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mjpegenc.c @@ -0,0 +1,458 @@ +/* + * MJPEG encoder + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-2004 Michael Niedermayer + * + * Support for external huffman table, various fixes (AVID workaround), + * aspecting, new decode_frame mechanism and apple mjpeg-b support + * by 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 mjpegenc.c + * MJPEG encoder. + */ + +//#define DEBUG +#include <assert.h> + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "mjpeg.h" +#include "mjpegenc.h" + +/* use two quantizer tables (one for luminance and one for chrominance) */ +/* not yet working */ +#undef TWOMATRIXES + + +int ff_mjpeg_encode_init(MpegEncContext *s) +{ + MJpegContext *m; + + m = av_malloc(sizeof(MJpegContext)); + if (!m) + return -1; + + s->min_qcoeff=-1023; + s->max_qcoeff= 1023; + + /* build all the huffman tables */ + ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance, + m->huff_code_dc_luminance, + ff_mjpeg_bits_dc_luminance, + ff_mjpeg_val_dc_luminance); + ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance, + m->huff_code_dc_chrominance, + ff_mjpeg_bits_dc_chrominance, + ff_mjpeg_val_dc_chrominance); + ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance, + m->huff_code_ac_luminance, + ff_mjpeg_bits_ac_luminance, + ff_mjpeg_val_ac_luminance); + ff_mjpeg_build_huffman_codes(m->huff_size_ac_chrominance, + m->huff_code_ac_chrominance, + ff_mjpeg_bits_ac_chrominance, + ff_mjpeg_val_ac_chrominance); + + s->mjpeg_ctx = m; + return 0; +} + +void ff_mjpeg_encode_close(MpegEncContext *s) +{ + av_free(s->mjpeg_ctx); +} + +/* table_class: 0 = DC coef, 1 = AC coefs */ +static int put_huffman_table(MpegEncContext *s, int table_class, int table_id, + const uint8_t *bits_table, const uint8_t *value_table) +{ + PutBitContext *p = &s->pb; + int n, i; + + put_bits(p, 4, table_class); + put_bits(p, 4, table_id); + + n = 0; + for(i=1;i<=16;i++) { + n += bits_table[i]; + put_bits(p, 8, bits_table[i]); + } + + for(i=0;i<n;i++) + put_bits(p, 8, value_table[i]); + + return n + 17; +} + +static void jpeg_table_header(MpegEncContext *s) +{ + PutBitContext *p = &s->pb; + int i, j, size; + uint8_t *ptr; + + /* quant matrixes */ + put_marker(p, DQT); +#ifdef TWOMATRIXES + put_bits(p, 16, 2 + 2 * (1 + 64)); +#else + put_bits(p, 16, 2 + 1 * (1 + 64)); +#endif + put_bits(p, 4, 0); /* 8 bit precision */ + put_bits(p, 4, 0); /* table 0 */ + for(i=0;i<64;i++) { + j = s->intra_scantable.permutated[i]; + put_bits(p, 8, s->intra_matrix[j]); + } +#ifdef TWOMATRIXES + put_bits(p, 4, 0); /* 8 bit precision */ + put_bits(p, 4, 1); /* table 1 */ + for(i=0;i<64;i++) { + j = s->intra_scantable.permutated[i]; + put_bits(p, 8, s->chroma_intra_matrix[j]); + } +#endif + + /* huffman table */ + put_marker(p, DHT); + flush_put_bits(p); + ptr = pbBufPtr(p); + put_bits(p, 16, 0); /* patched later */ + size = 2; + size += put_huffman_table(s, 0, 0, ff_mjpeg_bits_dc_luminance, + ff_mjpeg_val_dc_luminance); + size += put_huffman_table(s, 0, 1, ff_mjpeg_bits_dc_chrominance, + ff_mjpeg_val_dc_chrominance); + + size += put_huffman_table(s, 1, 0, ff_mjpeg_bits_ac_luminance, + ff_mjpeg_val_ac_luminance); + size += put_huffman_table(s, 1, 1, ff_mjpeg_bits_ac_chrominance, + ff_mjpeg_val_ac_chrominance); + AV_WB16(ptr, size); +} + +static void jpeg_put_comments(MpegEncContext *s) +{ + PutBitContext *p = &s->pb; + int size; + uint8_t *ptr; + + if (s->aspect_ratio_info /* && !lossless */) + { + /* JFIF header */ + put_marker(p, APP0); + put_bits(p, 16, 16); + ff_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ + put_bits(p, 16, 0x0201); /* v 1.02 */ + put_bits(p, 8, 0); /* units type: 0 - aspect ratio */ + put_bits(p, 16, s->avctx->sample_aspect_ratio.num); + put_bits(p, 16, s->avctx->sample_aspect_ratio.den); + put_bits(p, 8, 0); /* thumbnail width */ + put_bits(p, 8, 0); /* thumbnail height */ + } + + /* comment */ + if(!(s->flags & CODEC_FLAG_BITEXACT)){ + put_marker(p, COM); + flush_put_bits(p); + ptr = pbBufPtr(p); + put_bits(p, 16, 0); /* patched later */ + ff_put_string(p, LIBAVCODEC_IDENT, 1); + size = strlen(LIBAVCODEC_IDENT)+3; + AV_WB16(ptr, size); + } + + if( s->avctx->pix_fmt == PIX_FMT_YUV420P + ||s->avctx->pix_fmt == PIX_FMT_YUV422P + ||s->avctx->pix_fmt == PIX_FMT_YUV444P){ + put_marker(p, COM); + flush_put_bits(p); + ptr = pbBufPtr(p); + put_bits(p, 16, 0); /* patched later */ + ff_put_string(p, "CS=ITU601", 1); + size = strlen("CS=ITU601")+3; + AV_WB16(ptr, size); + } +} + +void ff_mjpeg_encode_picture_header(MpegEncContext *s) +{ + const int lossless= s->avctx->codec_id != CODEC_ID_MJPEG; + + put_marker(&s->pb, SOI); + + jpeg_put_comments(s); + + jpeg_table_header(s); + + switch(s->avctx->codec_id){ + case CODEC_ID_MJPEG: put_marker(&s->pb, SOF0 ); break; + case CODEC_ID_LJPEG: put_marker(&s->pb, SOF3 ); break; + default: assert(0); + } + + put_bits(&s->pb, 16, 17); + if(lossless && s->avctx->pix_fmt == PIX_FMT_RGB32) + put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */ + else + put_bits(&s->pb, 8, 8); /* 8 bits/component */ + put_bits(&s->pb, 16, s->height); + put_bits(&s->pb, 16, s->width); + put_bits(&s->pb, 8, 3); /* 3 components */ + + /* Y component */ + put_bits(&s->pb, 8, 1); /* component number */ + put_bits(&s->pb, 4, s->mjpeg_hsample[0]); /* H factor */ + put_bits(&s->pb, 4, s->mjpeg_vsample[0]); /* V factor */ + put_bits(&s->pb, 8, 0); /* select matrix */ + + /* Cb component */ + put_bits(&s->pb, 8, 2); /* component number */ + put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */ + put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */ +#ifdef TWOMATRIXES + put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ +#else + put_bits(&s->pb, 8, 0); /* select matrix */ +#endif + + /* Cr component */ + put_bits(&s->pb, 8, 3); /* component number */ + put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */ + put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */ +#ifdef TWOMATRIXES + put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */ +#else + put_bits(&s->pb, 8, 0); /* select matrix */ +#endif + + /* scan header */ + put_marker(&s->pb, SOS); + put_bits(&s->pb, 16, 12); /* length */ + put_bits(&s->pb, 8, 3); /* 3 components */ + + /* Y component */ + put_bits(&s->pb, 8, 1); /* index */ + put_bits(&s->pb, 4, 0); /* DC huffman table index */ + put_bits(&s->pb, 4, 0); /* AC huffman table index */ + + /* Cb component */ + put_bits(&s->pb, 8, 2); /* index */ + put_bits(&s->pb, 4, 1); /* DC huffman table index */ + put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ + + /* Cr component */ + put_bits(&s->pb, 8, 3); /* index */ + put_bits(&s->pb, 4, 1); /* DC huffman table index */ + put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */ + + put_bits(&s->pb, 8, lossless ? s->avctx->prediction_method+1 : 0); /* Ss (not used) */ + + switch(s->avctx->codec_id){ + case CODEC_ID_MJPEG: put_bits(&s->pb, 8, 63); break; /* Se (not used) */ + case CODEC_ID_LJPEG: put_bits(&s->pb, 8, 0); break; /* not used */ + default: assert(0); + } + + put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ +} + +static void escape_FF(MpegEncContext *s, int start) +{ + int size= put_bits_count(&s->pb) - start*8; + int i, ff_count; + uint8_t *buf= s->pb.buf + start; + int align= (-(size_t)(buf))&3; + + assert((size&7) == 0); + size >>= 3; + + ff_count=0; + for(i=0; i<size && i<align; i++){ + if(buf[i]==0xFF) ff_count++; + } + for(; i<size-15; i+=16){ + int acc, v; + + v= *(uint32_t*)(&buf[i]); + acc= (((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; + v= *(uint32_t*)(&buf[i+4]); + acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; + v= *(uint32_t*)(&buf[i+8]); + acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; + v= *(uint32_t*)(&buf[i+12]); + acc+=(((v & (v>>4))&0x0F0F0F0F)+0x01010101)&0x10101010; + + acc>>=4; + acc+= (acc>>16); + acc+= (acc>>8); + ff_count+= acc&0xFF; + } + for(; i<size; i++){ + if(buf[i]==0xFF) ff_count++; + } + + if(ff_count==0) return; + + /* skip put bits */ + for(i=0; i<ff_count-3; i+=4) + put_bits(&s->pb, 32, 0); + put_bits(&s->pb, (ff_count-i)*8, 0); + flush_put_bits(&s->pb); + + for(i=size-1; ff_count; i--){ + int v= buf[i]; + + if(v==0xFF){ +//printf("%d %d\n", i, ff_count); + buf[i+ff_count]= 0; + ff_count--; + } + + buf[i+ff_count]= v; + } +} + +void ff_mjpeg_encode_stuffing(PutBitContext * pbc) +{ + int length; + length= (-put_bits_count(pbc))&7; + if(length) put_bits(pbc, length, (1<<length)-1); +} + +void ff_mjpeg_encode_picture_trailer(MpegEncContext *s) +{ + ff_mjpeg_encode_stuffing(&s->pb); + flush_put_bits(&s->pb); + + assert((s->header_bits&7)==0); + + escape_FF(s, s->header_bits>>3); + + put_marker(&s->pb, EOI); +} + +void ff_mjpeg_encode_dc(MpegEncContext *s, int val, + uint8_t *huff_size, uint16_t *huff_code) +{ + int mant, nbits; + + if (val == 0) { + put_bits(&s->pb, huff_size[0], huff_code[0]); + } else { + mant = val; + if (val < 0) { + val = -val; + mant--; + } + + nbits= av_log2_16bit(val) + 1; + + put_bits(&s->pb, huff_size[nbits], huff_code[nbits]); + + put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); + } +} + +static void encode_block(MpegEncContext *s, DCTELEM *block, int n) +{ + int mant, nbits, code, i, j; + int component, dc, run, last_index, val; + MJpegContext *m = s->mjpeg_ctx; + uint8_t *huff_size_ac; + uint16_t *huff_code_ac; + + /* DC coef */ + component = (n <= 3 ? 0 : (n&1) + 1); + dc = block[0]; /* overflow is impossible */ + val = dc - s->last_dc[component]; + if (n < 4) { + ff_mjpeg_encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance); + huff_size_ac = m->huff_size_ac_luminance; + huff_code_ac = m->huff_code_ac_luminance; + } else { + ff_mjpeg_encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); + huff_size_ac = m->huff_size_ac_chrominance; + huff_code_ac = m->huff_code_ac_chrominance; + } + s->last_dc[component] = dc; + + /* AC coefs */ + + run = 0; + last_index = s->block_last_index[n]; + for(i=1;i<=last_index;i++) { + j = s->intra_scantable.permutated[i]; + val = block[j]; + if (val == 0) { + run++; + } else { + while (run >= 16) { + put_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]); + run -= 16; + } + mant = val; + if (val < 0) { + val = -val; + mant--; + } + + nbits= av_log2(val) + 1; + code = (run << 4) | nbits; + + put_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]); + + put_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); + run = 0; + } + } + + /* output EOB only if not already 64 values */ + if (last_index < 63 || run != 0) + put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]); +} + +void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]) +{ + int i; + for(i=0;i<5;i++) { + encode_block(s, block[i], i); + } + if (s->chroma_format == CHROMA_420) { + encode_block(s, block[5], 5); + } else { + encode_block(s, block[6], 6); + encode_block(s, block[5], 5); + encode_block(s, block[7], 7); + } +} + +AVCodec mjpeg_encoder = { + "mjpeg", + CODEC_TYPE_VIDEO, + CODEC_ID_MJPEG, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/mjpegenc.h b/contrib/ffmpeg/libavcodec/mjpegenc.h new file mode 100644 index 000000000..02f8a714c --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mjpegenc.h @@ -0,0 +1,60 @@ +/* + * MJPEG encoder + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-2004 Michael Niedermayer + * + * Support for external huffman table, various fixes (AVID workaround), + * aspecting, new decode_frame mechanism and apple mjpeg-b support + * by 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 mjpegenc.h + * MJPEG encoder. + */ + +#ifndef FFMPEG_MJPEGENC_H +#define FFMPEG_MJPEGENC_H + +#include "dsputil.h" +#include "mpegvideo.h" + +typedef struct MJpegContext { + uint8_t huff_size_dc_luminance[12]; //FIXME use array [3] instead of lumi / chrom, for easier addressing + uint16_t huff_code_dc_luminance[12]; + uint8_t huff_size_dc_chrominance[12]; + uint16_t huff_code_dc_chrominance[12]; + + uint8_t huff_size_ac_luminance[256]; + uint16_t huff_code_ac_luminance[256]; + uint8_t huff_size_ac_chrominance[256]; + uint16_t huff_code_ac_chrominance[256]; +} MJpegContext; + +int ff_mjpeg_encode_init(MpegEncContext *s); +void ff_mjpeg_encode_close(MpegEncContext *s); +void ff_mjpeg_encode_picture_header(MpegEncContext *s); +void ff_mjpeg_encode_picture_trailer(MpegEncContext *s); +void ff_mjpeg_encode_stuffing(PutBitContext *pbc); +void ff_mjpeg_encode_dc(MpegEncContext *s, int val, + uint8_t *huff_size, uint16_t *huff_code); +void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]); + +#endif /* FFMPEG_MJPEGENC_H */ diff --git a/contrib/ffmpeg/libavcodec/mlib/dsputil_mlib.c b/contrib/ffmpeg/libavcodec/mlib/dsputil_mlib.c index b78a54e0e..203a8da53 100644 --- a/contrib/ffmpeg/libavcodec/mlib/dsputil_mlib.c +++ b/contrib/ffmpeg/libavcodec/mlib/dsputil_mlib.c @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" -#include "../mpegvideo.h" +#include "dsputil.h" +#include "mpegvideo.h" #include <mlib_types.h> #include <mlib_status.h> @@ -374,7 +374,7 @@ static void avg_pixels8_xy2_mlib(uint8_t * dest, const uint8_t * ref, /* swap byte order of a buffer */ -static void bswap_buf_mlib(uint32_t *dst, uint32_t *src, int w) +static void bswap_buf_mlib(uint32_t *dst, const uint32_t *src, int w) { mlib_VectorReverseByteOrder_U32_U32(dst, src, w); } diff --git a/contrib/ffmpeg/libavcodec/mlp_parser.c b/contrib/ffmpeg/libavcodec/mlp_parser.c new file mode 100644 index 000000000..96dbc5943 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mlp_parser.c @@ -0,0 +1,307 @@ +/* + * MLP parser + * Copyright (c) 2007 Ian Caulfield + * + * 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 mlp_parser.c + * MLP parser + */ + +#include "bitstream.h" +#include "parser.h" +#include "crc.h" +#include "mlp_parser.h" + +static const uint8_t mlp_quants[16] = { + 16, 20, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static const uint8_t mlp_channels[32] = { + 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4, + 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static const uint8_t thd_chancount[13] = { +// LR C LFE LRs LRvh LRc LRrs Cs Ts LRsd LRw Cvh LFE2 + 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1 +}; + +static int mlp_samplerate(int in) +{ + if (in == 0xF) + return 0; + + return (in & 8 ? 44100 : 48000) << (in & 7) ; +} + +static int truehd_channels(int chanmap) +{ + int channels = 0, i; + + for (i = 0; i < 13; i++) + channels += thd_chancount[i] * ((chanmap >> i) & 1); + + return channels; +} + +static int crc_init = 0; +static AVCRC crc_2D[1024]; + +/** MLP uses checksums that seem to be based on the standard CRC algorithm, + * but not (in implementation terms, the table lookup and XOR are reversed). + * We can implement this behavior using a standard av_crc on all but the + * last element, then XOR that with the last element. + */ + +static uint16_t mlp_checksum16(const uint8_t *buf, unsigned int buf_size) +{ + uint16_t crc; + + if (!crc_init) { + av_crc_init(crc_2D, 0, 16, 0x002D, sizeof(crc_2D)); + crc_init = 1; + } + + crc = av_crc(crc_2D, 0, buf, buf_size - 2); + crc ^= AV_RL16(buf + buf_size - 2); + return crc; +} + +/** Read a major sync info header - contains high level information about + * the stream - sample rate, channel arrangement etc. Most of this + * information is not actually necessary for decoding, only for playback. + */ + +int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, const uint8_t *buf, + unsigned int buf_size) +{ + GetBitContext gb; + int ratebits; + uint16_t checksum; + + if (buf_size < 28) { + av_log(log, AV_LOG_ERROR, "Packet too short, unable to read major sync\n"); + return -1; + } + + checksum = mlp_checksum16(buf, 26); + if (checksum != AV_RL16(buf+26)) { + av_log(log, AV_LOG_ERROR, "Major sync info header checksum error\n"); + return -1; + } + + init_get_bits(&gb, buf, buf_size * 8); + + if (get_bits_long(&gb, 24) != 0xf8726f) /* Sync words */ + return -1; + + mh->stream_type = get_bits(&gb, 8); + + if (mh->stream_type == 0xbb) { + mh->group1_bits = mlp_quants[get_bits(&gb, 4)]; + mh->group2_bits = mlp_quants[get_bits(&gb, 4)]; + + ratebits = get_bits(&gb, 4); + mh->group1_samplerate = mlp_samplerate(ratebits); + mh->group2_samplerate = mlp_samplerate(get_bits(&gb, 4)); + + skip_bits(&gb, 11); + + mh->channels_mlp = get_bits(&gb, 5); + } else if (mh->stream_type == 0xba) { + mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere? + mh->group2_bits = 0; + + ratebits = get_bits(&gb, 4); + mh->group1_samplerate = mlp_samplerate(ratebits); + mh->group2_samplerate = 0; + + skip_bits(&gb, 8); + + mh->channels_thd_stream1 = get_bits(&gb, 5); + + skip_bits(&gb, 2); + + mh->channels_thd_stream2 = get_bits(&gb, 13); + } else + return -1; + + mh->access_unit_size = 40 << (ratebits & 7); + mh->access_unit_size_pow2 = 64 << (ratebits & 7); + + skip_bits_long(&gb, 48); + + mh->is_vbr = get_bits1(&gb); + + mh->peak_bitrate = (get_bits(&gb, 15) * mh->group1_samplerate + 8) >> 4; + + mh->num_substreams = get_bits(&gb, 4); + + skip_bits_long(&gb, 4 + 11 * 8); + + return 0; +} + +typedef struct MLPParseContext +{ + ParseContext pc; + + int bytes_left; + + int in_sync; + + int num_substreams; +} MLPParseContext; + +static int mlp_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + MLPParseContext *mp = s->priv_data; + int sync_present; + uint8_t parity_bits; + int next; + int i, p = 0; + + *poutbuf_size = 0; + if (buf_size == 0) + return 0; + + if (!mp->in_sync) { + // Not in sync - find a major sync header + + for (i = 0; i < buf_size; i++) { + mp->pc.state = (mp->pc.state << 8) | buf[i]; + if ((mp->pc.state & 0xfffffffe) == 0xf8726fba) { + mp->in_sync = 1; + mp->bytes_left = 0; + break; + } + } + + if (!mp->in_sync) { + ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size); + return buf_size; + } + + ff_combine_frame(&mp->pc, i - 7, &buf, &buf_size); + + return i - 7; + } + + if (mp->bytes_left == 0) { + // Find length of this packet + + /* Copy overread bytes from last frame into buffer. */ + for(; mp->pc.overread>0; mp->pc.overread--) { + mp->pc.buffer[mp->pc.index++]= mp->pc.buffer[mp->pc.overread_index++]; + } + + if (mp->pc.index + buf_size < 2) { + ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size); + return buf_size; + } + + mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8) + | (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]); + mp->bytes_left = (mp->bytes_left & 0xfff) * 2; + mp->bytes_left -= mp->pc.index; + } + + next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left; + + if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) { + mp->bytes_left -= buf_size; + return buf_size; + } + + mp->bytes_left = 0; + + sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba; + + if (!sync_present) { + // First nibble of a frame is a parity check of the first few nibbles. + // Only check when this isn't a sync frame - syncs have a checksum. + + parity_bits = 0; + for (i = 0; i <= mp->num_substreams; i++) { + parity_bits ^= buf[p++]; + parity_bits ^= buf[p++]; + + if (i == 0 || buf[p-2] & 0x80) { + parity_bits ^= buf[p++]; + parity_bits ^= buf[p++]; + } + } + + if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) { + av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n"); + goto lost_sync; + } + } else { + MLPHeaderInfo mh; + + if (ff_mlp_read_major_sync(avctx, &mh, buf + 4, buf_size - 4) < 0) + goto lost_sync; + +#ifdef CONFIG_AUDIO_NONSHORT + avctx->bits_per_sample = mh.group1_bits; + if (avctx->bits_per_sample > 16) + avctx->sample_fmt = SAMPLE_FMT_S32; +#endif + avctx->sample_rate = mh.group1_samplerate; + avctx->frame_size = mh.access_unit_size; + + if (mh.stream_type == 0xbb) { + /* MLP stream */ + avctx->channels = mlp_channels[mh.channels_mlp]; + } else { /* mh.stream_type == 0xba */ + /* TrueHD stream */ + if (mh.channels_thd_stream2) + avctx->channels = truehd_channels(mh.channels_thd_stream2); + else + avctx->channels = truehd_channels(mh.channels_thd_stream1); + } + + if (!mh.is_vbr) /* Stream is CBR */ + avctx->bit_rate = mh.peak_bitrate; + + mp->num_substreams = mh.num_substreams; + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + + return next; + +lost_sync: + mp->in_sync = 0; + return -1; +} + +AVCodecParser mlp_parser = { + { CODEC_ID_MLP }, + sizeof(MLPParseContext), + NULL, + mlp_parse, + NULL, +}; diff --git a/contrib/ffmpeg/libavcodec/mlp_parser.h b/contrib/ffmpeg/libavcodec/mlp_parser.h new file mode 100644 index 000000000..d690b4f45 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mlp_parser.h @@ -0,0 +1,60 @@ +/* + * MLP parser prototypes + * Copyright (c) 2007 Ian Caulfield + * + * 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 mlp_parser.h + * MLP parser prototypes + */ + +#ifndef FFMPEG_MLP_PARSER_H +#define FFMPEG_MLP_PARSER_H + +#include <inttypes.h> + +typedef struct MLPHeaderInfo +{ + int stream_type; ///< 0xBB for MLP, 0xBA for TrueHD + + int group1_bits; ///< The bit depth of the first substream + int group2_bits; ///< Bit depth of the second substream (MLP only) + + int group1_samplerate; ///< Sample rate of first substream + int group2_samplerate; ///< Sample rate of second substream (MLP only) + + int channels_mlp; ///< Channel arrangement for MLP streams + int channels_thd_stream1; ///< Channel arrangement for substream 1 of TrueHD streams (5.1) + int channels_thd_stream2; ///< Channel arrangement for substream 2 of TrueHD streams (7.1) + + int access_unit_size; ///< Number of samples per coded frame + int access_unit_size_pow2; ///< Next power of two above number of samples per frame + + int is_vbr; ///< Stream is VBR instead of CBR + int peak_bitrate; ///< Peak bitrate for VBR, actual bitrate (==peak) for CBR + + int num_substreams; ///< Number of substreams within stream +} MLPHeaderInfo; + + +int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, const uint8_t *buf, + unsigned int buf_size); + +#endif /* FFMPEG_MLP_PARSER_H */ + diff --git a/contrib/ffmpeg/libavcodec/mmvideo.c b/contrib/ffmpeg/libavcodec/mmvideo.c index 7ba1321cb..9c169a004 100644 --- a/contrib/ffmpeg/libavcodec/mmvideo.c +++ b/contrib/ffmpeg/libavcodec/mmvideo.c @@ -16,7 +16,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -59,7 +59,6 @@ static int mm_decode_init(AVCodecContext *avctx) } avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; if (avcodec_check_dimensions(avctx, avctx->width, avctx->height)) return -1; @@ -151,7 +150,7 @@ static void mm_decode_inter(MmContext * s, int half_horiz, int half_vert, const static int mm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { MmContext *s = avctx->priv_data; AVPaletteControl *palette_control = avctx->palctrl; diff --git a/contrib/ffmpeg/libavcodec/motion_test.c b/contrib/ffmpeg/libavcodec/motion-test.c index ecdb62a4e..69791500b 100644 --- a/contrib/ffmpeg/libavcodec/motion_test.c +++ b/contrib/ffmpeg/libavcodec/motion-test.c @@ -35,21 +35,7 @@ #undef exit #undef printf - -int pix_abs16x16_mmx(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_mmx1(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_c(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_x2_mmx(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_x2_mmx1(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_x2_c(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_y2_mmx(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_y2_mmx1(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_y2_c(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_xy2_mmx(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_xy2_mmx1(uint8_t *blk1, uint8_t *blk2, int lx); -int pix_abs16x16_xy2_c(uint8_t *blk1, uint8_t *blk2, int lx); - -typedef int motion_func(uint8_t *blk1, uint8_t *blk2, int lx); +#undef random #define WIDTH 64 #define HEIGHT 64 @@ -88,7 +74,7 @@ int64_t gettime(void) int dummy; void test_motion(const char *name, - motion_func *test_func, motion_func *ref_func) + me_cmp_func test_func, me_cmp_func ref_func) { int x, y, d1, d2, it; uint8_t *ptr; @@ -104,15 +90,15 @@ void test_motion(const char *name, for(y=0;y<HEIGHT-17;y++) { for(x=0;x<WIDTH-17;x++) { ptr = img2 + y * WIDTH + x; - d1 = test_func(img1, ptr, WIDTH); - d2 = ref_func(img1, ptr, WIDTH); + d1 = test_func(NULL, img1, ptr, WIDTH, 1); + d2 = ref_func(NULL, img1, ptr, WIDTH, 1); if (d1 != d2) { printf("error: mmx=%d c=%d\n", d1, d2); } } } } - emms(); + emms_c(); /* speed test */ ti = gettime(); @@ -121,12 +107,12 @@ void test_motion(const char *name, for(y=0;y<HEIGHT-17;y++) { for(x=0;x<WIDTH-17;x++) { ptr = img2 + y * WIDTH + x; - d1 += test_func(img1, ptr, WIDTH); + d1 += test_func(NULL, img1, ptr, WIDTH, 1); } } } - emms(); - dummy = d1; /* avoid optimisation */ + emms_c(); + dummy = d1; /* avoid optimization */ ti = gettime() - ti; printf(" %0.0f kop/s\n", @@ -137,7 +123,10 @@ void test_motion(const char *name, int main(int argc, char **argv) { + AVCodecContext *ctx; int c; + DSPContext cctx, mmxctx; + int flags[2] = { FF_MM_MMX, FF_MM_MMXEXT }; for(;;) { c = getopt(argc, argv, "h"); @@ -152,9 +141,24 @@ int main(int argc, char **argv) printf("ffmpeg motion test\n"); - test_motion("mmx", pix_abs16x16_mmx, pix_abs16x16_c); - test_motion("mmx_x2", pix_abs16x16_x2_mmx, pix_abs16x16_x2_c); - test_motion("mmx_y2", pix_abs16x16_y2_mmx, pix_abs16x16_y2_c); - test_motion("mmx_xy2", pix_abs16x16_xy2_mmx, pix_abs16x16_xy2_c); + ctx = avcodec_alloc_context(); + ctx->dsp_mask = FF_MM_FORCE; + dsputil_init(&cctx, ctx); + for (c = 0; c < 2; c++) { + int x; + ctx->dsp_mask = FF_MM_FORCE | flags[c]; + dsputil_init(&mmxctx, ctx); + + for (x = 0; x < 2; x++) { + printf("%s for %dx%d pixels\n", c ? "mmx2" : "mmx", + x ? 8 : 16, x ? 8 : 16); + test_motion("mmx", mmxctx.pix_abs[x][0], cctx.pix_abs[x][0]); + test_motion("mmx_x2", mmxctx.pix_abs[x][1], cctx.pix_abs[x][1]); + test_motion("mmx_y2", mmxctx.pix_abs[x][2], cctx.pix_abs[x][2]); + test_motion("mmx_xy2", mmxctx.pix_abs[x][3], cctx.pix_abs[x][3]); + } + } + av_free(ctx); + return 0; } diff --git a/contrib/ffmpeg/libavcodec/motion_est.c b/contrib/ffmpeg/libavcodec/motion_est.c index a042f4916..16db0f87c 100644 --- a/contrib/ffmpeg/libavcodec/motion_est.c +++ b/contrib/ffmpeg/libavcodec/motion_est.c @@ -3,6 +3,7 @@ * Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer * + * new motion estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at> * * This file is part of FFmpeg. * @@ -19,8 +20,6 @@ * 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 - * - * new Motion Estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at> */ /** @@ -279,7 +278,9 @@ void ff_init_me(MpegEncContext *s){ c->uvstride= 8*s->mb_width + 16; } - // 8x8 fullpel search would need a 4x4 chroma compare, which we dont have yet, and even if we had the motion estimation code doesnt expect it + /* 8x8 fullpel search would need a 4x4 chroma compare, which we do + * not have yet, and even if we had, the motion estimation code + * does not expect it. */ if(s->codec_id != CODEC_ID_SNOW){ if((c->avctx->me_cmp&FF_CMP_CHROMA)/* && !s->dsp.me_cmp[2]*/){ s->dsp.me_cmp[2]= zero_cmp; @@ -1805,7 +1806,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) P_LEFT[1] = av_clip(mv_table[mot_xy - 1][1], ymin<<shift, ymax<<shift); /* special case for first line */ - if (!s->first_slice_line) { //FIXME maybe allow this over thread boundary as its clipped + if (!s->first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin<<shift, xmax<<shift); P_TOP[1] = av_clip(mv_table[mot_xy - mot_stride ][1], ymin<<shift, ymax<<shift); P_TOPRIGHT[0] = av_clip(mv_table[mot_xy - mot_stride + 1 ][0], xmin<<shift, xmax<<shift); @@ -1980,7 +1981,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, type |= CANDIDATE_MB_TYPE_BIDIR_I; } //FIXME something smarter - if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //dont try direct mode if its invalid for this MB + if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //do not try direct mode if it is invalid for this MB if(s->codec_id == CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT && s->flags&CODEC_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy]) type |= CANDIDATE_MB_TYPE_DIRECT0; #if 0 diff --git a/contrib/ffmpeg/libavcodec/motion_est_template.c b/contrib/ffmpeg/libavcodec/motion_est_template.c index 37443b022..70b4f824a 100644 --- a/contrib/ffmpeg/libavcodec/motion_est_template.c +++ b/contrib/ffmpeg/libavcodec/motion_est_template.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -27,11 +26,11 @@ //lets hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...) #define LOAD_COMMON\ - uint32_t attribute_unused * const score_map= c->score_map;\ - const int attribute_unused xmin= c->xmin;\ - const int attribute_unused ymin= c->ymin;\ - const int attribute_unused xmax= c->xmax;\ - const int attribute_unused ymax= c->ymax;\ + uint32_t av_unused * const score_map= c->score_map;\ + const int av_unused xmin= c->xmin;\ + const int av_unused ymin= c->ymin;\ + const int av_unused xmax= c->xmax;\ + const int av_unused ymax= c->ymax;\ uint8_t *mv_penalty= c->current_mv_penalty;\ const int pred_x= c->pred_x;\ const int pred_y= c->pred_y;\ diff --git a/contrib/ffmpeg/libavcodec/movsub_bsf.c b/contrib/ffmpeg/libavcodec/movsub_bsf.c new file mode 100644 index 000000000..99e8135f5 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/movsub_bsf.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2008 Reimar Döffinger + * + * 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" + + +static int text2movsub(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe){ + if (buf_size > 0xffff) return 0; + *poutbuf_size = buf_size + 2; + *poutbuf = av_malloc(*poutbuf_size + FF_INPUT_BUFFER_PADDING_SIZE); + AV_WB16(*poutbuf, buf_size); + memcpy(*poutbuf + 2, buf, buf_size); + return 1; +} + +AVBitStreamFilter text2movsub_bsf={ + "text2movsub", + 0, + text2movsub, +}; + +static int mov2textsub(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe){ + if (buf_size < 2) return 0; + *poutbuf_size = FFMIN(buf_size - 2, AV_RB16(buf)); + *poutbuf = av_malloc(*poutbuf_size + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(*poutbuf, buf + 2, *poutbuf_size); + return 1; +} + +AVBitStreamFilter mov2textsub_bsf={ + "mov2textsub", + 0, + mov2textsub, +}; diff --git a/contrib/ffmpeg/libavcodec/mp3_header_compress_bsf.c b/contrib/ffmpeg/libavcodec/mp3_header_compress_bsf.c new file mode 100644 index 000000000..f5c513834 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mp3_header_compress_bsf.c @@ -0,0 +1,86 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * 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" +#include "mpegaudio.h" + + +static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe){ + uint32_t header, extraheader; + int mode_extension, header_size; + + if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ + av_log(avctx, AV_LOG_ERROR, "not standards compliant\n"); + return -1; + } + + header = AV_RB32(buf); + mode_extension= (header>>4)&3; + + if(ff_mpa_check_header(header) < 0 || (header&0x60000) != 0x20000){ +output_unchanged: + *poutbuf= (uint8_t *) buf; + *poutbuf_size= buf_size; + + av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header); + return 0; + } + + if(avctx->extradata_size == 0){ + avctx->extradata_size=15; + avctx->extradata= av_malloc(avctx->extradata_size); + strcpy(avctx->extradata, "FFCMP3 0.0"); + memcpy(avctx->extradata+11, buf, 4); + } + if(avctx->extradata_size != 15){ + av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n"); + return -1; + } + extraheader = AV_RB32(avctx->extradata+11); + if((extraheader&MP3_MASK) != (header&MP3_MASK)) + goto output_unchanged; + + header_size= (header&0x10000) ? 4 : 6; + + *poutbuf_size= buf_size - header_size; + *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE); + + if(avctx->channels==2){ + if((header & (3<<19)) != 3<<19){ + (*poutbuf)[1] &= 0x3F; + (*poutbuf)[1] |= mode_extension<<6; + FFSWAP(int, (*poutbuf)[1], (*poutbuf)[2]); + }else{ + (*poutbuf)[1] &= 0x8F; + (*poutbuf)[1] |= mode_extension<<4; + } + } + + return 1; +} + +AVBitStreamFilter mp3_header_compress_bsf={ + "mp3comp", + 0, + mp3_header_compress, +}; diff --git a/contrib/ffmpeg/libavcodec/mp3_header_decompress_bsf.c b/contrib/ffmpeg/libavcodec/mp3_header_decompress_bsf.c new file mode 100644 index 000000000..d897ed985 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mp3_header_decompress_bsf.c @@ -0,0 +1,96 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * 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" +#include "mpegaudio.h" +#include "mpegaudiodata.h" + + +static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe){ + uint32_t header; + int sample_rate= avctx->sample_rate; + int sample_rate_index=0; + int lsf, mpeg25, bitrate_index, frame_size; + + header = AV_RB32(buf); + if(ff_mpa_check_header(header) >= 0){ + *poutbuf= (uint8_t *) buf; + *poutbuf_size= buf_size; + + return 0; + } + + if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){ + av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size); + return -1; + } + + header= AV_RB32(avctx->extradata+11) & MP3_MASK; + + lsf = sample_rate < (24000+32000)/2; + mpeg25 = sample_rate < (12000+16000)/2; + sample_rate_index= (header>>10)&3; + sample_rate= ff_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off + + for(bitrate_index=2; bitrate_index<30; bitrate_index++){ + frame_size = ff_mpa_bitrate_tab[lsf][2][bitrate_index>>1]; + frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1); + if(frame_size == buf_size + 4) + break; + if(frame_size == buf_size + 6) + break; + } + if(bitrate_index == 30){ + av_log(avctx, AV_LOG_ERROR, "Could not find bitrate_index.\n"); + return -1; + } + + header |= (bitrate_index&1)<<9; + header |= (bitrate_index>>1)<<12; + header |= (frame_size == buf_size + 4)<<16; //FIXME actually set a correct crc instead of 0 + + *poutbuf_size= frame_size; + *poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + + if(avctx->channels==2){ + uint8_t *p= *poutbuf + frame_size - buf_size; + if(lsf){ + FFSWAP(int, p[1], p[2]); + header |= (p[1] & 0xC0)>>2; + p[1] &= 0x3F; + }else{ + header |= p[1] & 0x30; + p[1] &= 0xCF; + } + } + + AV_WB32(*poutbuf, header); + + return 1; +} + +AVBitStreamFilter mp3_header_decompress_bsf={ + "mp3decomp", + 0, + mp3_header_decompress, +}; diff --git a/contrib/ffmpeg/libavcodec/mpc.c b/contrib/ffmpeg/libavcodec/mpc.c index f351c549f..96e1a20b0 100644 --- a/contrib/ffmpeg/libavcodec/mpc.c +++ b/contrib/ffmpeg/libavcodec/mpc.c @@ -1,5 +1,5 @@ /* - * Musepack decoder + * Musepack decoder core * Copyright (c) 2006 Konstantin Shishkov * * This file is part of FFmpeg. @@ -17,11 +17,10 @@ * 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 mpc.c Musepack decoder + * @file mpc.c Musepack decoder core * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples * divided into 32 subbands. */ @@ -36,109 +35,18 @@ #endif #include "mpegaudio.h" +#include "mpc.h" #include "mpcdata.h" -#define BANDS 32 -#define SAMPLES_PER_BAND 36 -#define MPC_FRAME_SIZE (BANDS * SAMPLES_PER_BAND) - -static VLC scfi_vlc, dscf_vlc, hdr_vlc, quant_vlc[MPC7_QUANT_VLC_TABLES][2]; - static DECLARE_ALIGNED_16(MPA_INT, mpa_window[512]); -typedef struct { - DSPContext dsp; - int IS, MSS, gapless; - int lastframelen, bands; - int oldDSCF[2][BANDS]; - AVRandomState rnd; - int frames_to_skip; - /* for synthesis */ - DECLARE_ALIGNED_16(MPA_INT, synth_buf[MPA_MAX_CHANNELS][512*2]); - int synth_buf_offset[MPA_MAX_CHANNELS]; - DECLARE_ALIGNED_16(int32_t, sb_samples[MPA_MAX_CHANNELS][36][SBLIMIT]); -} MPCContext; - -/** Subband structure - hold all variables for each subband */ -typedef struct { - int msf; ///< mid-stereo flag - int res[2]; - int scfi[2]; - int scf_idx[2][3]; - int Q[2]; -}Band; - -static int mpc7_decode_init(AVCodecContext * avctx) +void ff_mpc_init() { - int i, j; - MPCContext *c = avctx->priv_data; - GetBitContext gb; - uint8_t buf[16]; - float f1=1.20050805774840750476 * 256; - static int vlc_inited = 0; - - if(avctx->extradata_size < 16){ - av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size); - return -1; - } - memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); - av_init_random(0xDEADBEEF, &c->rnd); - dsputil_init(&c->dsp, avctx); - c->dsp.bswap_buf(buf, avctx->extradata, 4); ff_mpa_synth_init(mpa_window); - init_get_bits(&gb, buf, 128); - - c->IS = get_bits1(&gb); - c->MSS = get_bits1(&gb); - c->bands = get_bits(&gb, 6); - if(c->bands >= BANDS){ - av_log(avctx, AV_LOG_ERROR, "Too many bands: %i\n", c->bands); - return -1; - } - skip_bits(&gb, 88); - c->gapless = get_bits1(&gb); - c->lastframelen = get_bits(&gb, 11); - av_log(avctx, AV_LOG_DEBUG, "IS: %d, MSS: %d, TG: %d, LFL: %d, bands: %d\n", - c->IS, c->MSS, c->gapless, c->lastframelen, c->bands); - c->frames_to_skip = 0; - - if(vlc_inited) return 0; - av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); - if(init_vlc(&scfi_vlc, MPC7_SCFI_BITS, MPC7_SCFI_SIZE, - &mpc7_scfi[1], 2, 1, - &mpc7_scfi[0], 2, 1, INIT_VLC_USE_STATIC)){ - av_log(avctx, AV_LOG_ERROR, "Cannot init SCFI VLC\n"); - return -1; - } - if(init_vlc(&dscf_vlc, MPC7_DSCF_BITS, MPC7_DSCF_SIZE, - &mpc7_dscf[1], 2, 1, - &mpc7_dscf[0], 2, 1, INIT_VLC_USE_STATIC)){ - av_log(avctx, AV_LOG_ERROR, "Cannot init DSCF VLC\n"); - return -1; - } - if(init_vlc(&hdr_vlc, MPC7_HDR_BITS, MPC7_HDR_SIZE, - &mpc7_hdr[1], 2, 1, - &mpc7_hdr[0], 2, 1, INIT_VLC_USE_STATIC)){ - av_log(avctx, AV_LOG_ERROR, "Cannot init HDR VLC\n"); - return -1; - } - for(i = 0; i < MPC7_QUANT_VLC_TABLES; i++){ - for(j = 0; j < 2; j++){ - if(init_vlc(&quant_vlc[i][j], 9, mpc7_quant_vlc_sizes[i], - &mpc7_quant_vlc[i][j][1], 4, 2, - &mpc7_quant_vlc[i][j][0], 4, 2, INIT_VLC_USE_STATIC)){ - av_log(avctx, AV_LOG_ERROR, "Cannot init QUANT VLC %i,%i\n",i,j); - return -1; - } - } - } - vlc_inited = 1; - return 0; } /** * Process decoded Musepack data and produce PCM - * @todo make it available for MPC8 and MPC6 */ static void mpc_synth(MPCContext *c, int16_t *out) { @@ -160,147 +68,29 @@ static void mpc_synth(MPCContext *c, int16_t *out) *out++=samples[i]; } -/** - * Fill samples for given subband - */ -static void inline idx_to_quant(MPCContext *c, GetBitContext *gb, int idx, int *dst) -{ - int i, i1, t; - switch(idx){ - case -1: - for(i = 0; i < SAMPLES_PER_BAND; i++){ - *dst++ = (av_random(&c->rnd) & 0x3FC) - 510; - } - break; - case 1: - i1 = get_bits1(gb); - for(i = 0; i < SAMPLES_PER_BAND/3; i++){ - t = get_vlc2(gb, quant_vlc[0][i1].table, 9, 2); - *dst++ = mpc_idx30[t]; - *dst++ = mpc_idx31[t]; - *dst++ = mpc_idx32[t]; - } - break; - case 2: - i1 = get_bits1(gb); - for(i = 0; i < SAMPLES_PER_BAND/2; i++){ - t = get_vlc2(gb, quant_vlc[1][i1].table, 9, 2); - *dst++ = mpc_idx50[t]; - *dst++ = mpc_idx51[t]; - } - break; - case 3: case 4: case 5: case 6: case 7: - i1 = get_bits1(gb); - for(i = 0; i < SAMPLES_PER_BAND; i++) - *dst++ = get_vlc2(gb, quant_vlc[idx-1][i1].table, 9, 2) - mpc7_quant_vlc_off[idx-1]; - break; - case 8: case 9: case 10: case 11: case 12: - case 13: case 14: case 15: case 16: case 17: - t = (1 << (idx - 2)) - 1; - for(i = 0; i < SAMPLES_PER_BAND; i++) - *dst++ = get_bits(gb, idx - 1) - t; - break; - default: // case 0 and -2..-17 - return; - } -} - -static int mpc7_decode_frame(AVCodecContext * avctx, - void *data, int *data_size, - uint8_t * buf, int buf_size) +void ff_mpc_dequantize_and_synth(MPCContext * c, int maxband, void *data) { - MPCContext *c = avctx->priv_data; - GetBitContext gb; - uint8_t *bits; - int i, j, ch, t; - int mb = -1; - Band bands[BANDS]; - int Q[2][MPC_FRAME_SIZE]; + int i, j, ch; + Band *bands = c->bands; int off; float mul; - int bits_used, bits_avail; - memset(bands, 0, sizeof(bands)); - if(buf_size <= 4){ - av_log(avctx, AV_LOG_ERROR, "Too small buffer passed (%i bytes)\n", buf_size); - } - - bits = av_malloc(((buf_size - 1) & ~3) + FF_INPUT_BUFFER_PADDING_SIZE); - c->dsp.bswap_buf(bits, buf + 4, (buf_size - 4) >> 2); - init_get_bits(&gb, bits, (buf_size - 4)* 8); - skip_bits(&gb, buf[0]); - - /* read subband indexes */ - for(i = 0; i <= c->bands; i++){ - for(ch = 0; ch < 2; ch++){ - if(i) t = get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5; - if(!i || (t == 4)) bands[i].res[ch] = get_bits(&gb, 4); - else bands[i].res[ch] = bands[i-1].res[ch] + t; - } - - if(bands[i].res[0] || bands[i].res[1]){ - mb = i; - if(c->MSS) bands[i].msf = get_bits1(&gb); - } - } - /* get scale indexes coding method */ - for(i = 0; i <= mb; i++) - for(ch = 0; ch < 2; ch++) - if(bands[i].res[ch]) bands[i].scfi[ch] = get_vlc2(&gb, scfi_vlc.table, MPC7_SCFI_BITS, 1); - /* get scale indexes */ - for(i = 0; i <= mb; i++){ - for(ch = 0; ch < 2; ch++){ - if(bands[i].res[ch]){ - bands[i].scf_idx[ch][2] = c->oldDSCF[ch][i]; - t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; - bands[i].scf_idx[ch][0] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][2] + t); - switch(bands[i].scfi[ch]){ - case 0: - t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; - bands[i].scf_idx[ch][1] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][0] + t); - t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; - bands[i].scf_idx[ch][2] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][1] + t); - break; - case 1: - t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; - bands[i].scf_idx[ch][1] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][0] + t); - bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1]; - break; - case 2: - bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; - t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; - bands[i].scf_idx[ch][2] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][1] + t); - break; - case 3: - bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; - break; - } - c->oldDSCF[ch][i] = bands[i].scf_idx[ch][2]; - } - } - } - /* get quantizers */ - memset(Q, 0, sizeof(Q)); - off = 0; - for(i = 0; i < BANDS; i++, off += SAMPLES_PER_BAND) - for(ch = 0; ch < 2; ch++) - idx_to_quant(c, &gb, bands[i].res[ch], Q[ch] + off); /* dequantize */ memset(c->sb_samples, 0, sizeof(c->sb_samples)); off = 0; - for(i = 0; i <= mb; i++, off += SAMPLES_PER_BAND){ + for(i = 0; i <= maxband; i++, off += SAMPLES_PER_BAND){ for(ch = 0; ch < 2; ch++){ if(bands[i].res[ch]){ j = 0; - mul = mpc_CC[bands[i].res[ch]] * mpc7_SCF[bands[i].scf_idx[ch][0]]; + mul = mpc_CC[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][0]]; for(; j < 12; j++) - c->sb_samples[ch][j][i] = mul * Q[ch][j + off]; - mul = mpc_CC[bands[i].res[ch]] * mpc7_SCF[bands[i].scf_idx[ch][1]]; + c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; + mul = mpc_CC[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][1]]; for(; j < 24; j++) - c->sb_samples[ch][j][i] = mul * Q[ch][j + off]; - mul = mpc_CC[bands[i].res[ch]] * mpc7_SCF[bands[i].scf_idx[ch][2]]; + c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; + mul = mpc_CC[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][2]]; for(; j < 36; j++) - c->sb_samples[ch][j][i] = mul * Q[ch][j + off]; + c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; } } if(bands[i].msf){ @@ -315,41 +105,4 @@ static int mpc7_decode_frame(AVCodecContext * avctx, } mpc_synth(c, data); - - av_free(bits); - - bits_used = get_bits_count(&gb); - bits_avail = (buf_size - 4) * 8; - if(!buf[1] && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))){ - av_log(NULL,0, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail); - return -1; - } - if(c->frames_to_skip){ - c->frames_to_skip--; - *data_size = 0; - return buf_size; - } - *data_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4; - - return buf_size; -} - -static void mpc7_decode_flush(AVCodecContext *avctx) -{ - MPCContext *c = avctx->priv_data; - - memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); - c->frames_to_skip = 32; } - -AVCodec mpc7_decoder = { - "mpc sv7", - CODEC_TYPE_AUDIO, - CODEC_ID_MUSEPACK7, - sizeof(MPCContext), - mpc7_decode_init, - NULL, - NULL, - mpc7_decode_frame, - .flush = mpc7_decode_flush, -}; diff --git a/contrib/ffmpeg/libavcodec/mpc.h b/contrib/ffmpeg/libavcodec/mpc.h new file mode 100644 index 000000000..ce438e3af --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpc.h @@ -0,0 +1,80 @@ +/* + * Musepack 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 + */ + +/** + * @file mpc.h Musepack decoder + * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples + * divided into 32 subbands. + */ + +#ifndef FFMPEG_MPC_H +#define FFMPEG_MPC_H + +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" +#include "random.h" + +#ifdef CONFIG_MPEGAUDIO_HP +#define USE_HIGHPRECISION +#endif +#include "mpegaudio.h" + +#include "mpcdata.h" + +#define BANDS 32 +#define SAMPLES_PER_BAND 36 +#define MPC_FRAME_SIZE (BANDS * SAMPLES_PER_BAND) + +/** Subband structure - hold all variables for each subband */ +typedef struct { + int msf; ///< mid-stereo flag + int res[2]; + int scfi[2]; + int scf_idx[2][3]; + int Q[2]; +}Band; + +typedef struct { + DSPContext dsp; + GetBitContext gb; + int IS, MSS, gapless; + int lastframelen; + int maxbands, last_max_band; + int last_bits_used; + int oldDSCF[2][BANDS]; + Band bands[BANDS]; + int Q[2][MPC_FRAME_SIZE]; + int cur_frame, frames; + uint8_t *bits; + int buf_size; + AVRandomState rnd; + int frames_to_skip; + /* for synthesis */ + DECLARE_ALIGNED_16(MPA_INT, synth_buf[MPA_MAX_CHANNELS][512*2]); + int synth_buf_offset[MPA_MAX_CHANNELS]; + DECLARE_ALIGNED_16(int32_t, sb_samples[MPA_MAX_CHANNELS][36][SBLIMIT]); +} MPCContext; + +extern void ff_mpc_init(); +extern void ff_mpc_dequantize_and_synth(MPCContext *c, int maxband, void *dst); + +#endif /* FFMPEG_MPC_H */ diff --git a/contrib/ffmpeg/libavcodec/mpc7.c b/contrib/ffmpeg/libavcodec/mpc7.c new file mode 100644 index 000000000..37bdb5f39 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpc7.c @@ -0,0 +1,276 @@ +/* + * Musepack SV7 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 + */ + +/** + * @file mpc7.c Musepack SV7 decoder + * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples + * divided into 32 subbands. + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" +#include "random.h" + +#ifdef CONFIG_MPEGAUDIO_HP +#define USE_HIGHPRECISION +#endif +#include "mpegaudio.h" + +#include "mpc.h" +#include "mpc7data.h" + +#define BANDS 32 +#define SAMPLES_PER_BAND 36 +#define MPC_FRAME_SIZE (BANDS * SAMPLES_PER_BAND) + +static VLC scfi_vlc, dscf_vlc, hdr_vlc, quant_vlc[MPC7_QUANT_VLC_TABLES][2]; + +static int mpc7_decode_init(AVCodecContext * avctx) +{ + int i, j; + MPCContext *c = avctx->priv_data; + GetBitContext gb; + uint8_t buf[16]; + static int vlc_initialized = 0; + + if(avctx->extradata_size < 16){ + av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size); + return -1; + } + memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); + av_init_random(0xDEADBEEF, &c->rnd); + dsputil_init(&c->dsp, avctx); + c->dsp.bswap_buf((uint32_t*)buf, (const uint32_t*)avctx->extradata, 4); + ff_mpc_init(); + init_get_bits(&gb, buf, 128); + + c->IS = get_bits1(&gb); + c->MSS = get_bits1(&gb); + c->maxbands = get_bits(&gb, 6); + if(c->maxbands >= BANDS){ + av_log(avctx, AV_LOG_ERROR, "Too many bands: %i\n", c->maxbands); + return -1; + } + skip_bits(&gb, 88); + c->gapless = get_bits1(&gb); + c->lastframelen = get_bits(&gb, 11); + av_log(avctx, AV_LOG_DEBUG, "IS: %d, MSS: %d, TG: %d, LFL: %d, bands: %d\n", + c->IS, c->MSS, c->gapless, c->lastframelen, c->maxbands); + c->frames_to_skip = 0; + + if(vlc_initialized) return 0; + av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); + if(init_vlc(&scfi_vlc, MPC7_SCFI_BITS, MPC7_SCFI_SIZE, + &mpc7_scfi[1], 2, 1, + &mpc7_scfi[0], 2, 1, INIT_VLC_USE_STATIC)){ + av_log(avctx, AV_LOG_ERROR, "Cannot init SCFI VLC\n"); + return -1; + } + if(init_vlc(&dscf_vlc, MPC7_DSCF_BITS, MPC7_DSCF_SIZE, + &mpc7_dscf[1], 2, 1, + &mpc7_dscf[0], 2, 1, INIT_VLC_USE_STATIC)){ + av_log(avctx, AV_LOG_ERROR, "Cannot init DSCF VLC\n"); + return -1; + } + if(init_vlc(&hdr_vlc, MPC7_HDR_BITS, MPC7_HDR_SIZE, + &mpc7_hdr[1], 2, 1, + &mpc7_hdr[0], 2, 1, INIT_VLC_USE_STATIC)){ + av_log(avctx, AV_LOG_ERROR, "Cannot init HDR VLC\n"); + return -1; + } + for(i = 0; i < MPC7_QUANT_VLC_TABLES; i++){ + for(j = 0; j < 2; j++){ + if(init_vlc(&quant_vlc[i][j], 9, mpc7_quant_vlc_sizes[i], + &mpc7_quant_vlc[i][j][1], 4, 2, + &mpc7_quant_vlc[i][j][0], 4, 2, INIT_VLC_USE_STATIC)){ + av_log(avctx, AV_LOG_ERROR, "Cannot init QUANT VLC %i,%i\n",i,j); + return -1; + } + } + } + vlc_initialized = 1; + return 0; +} + +/** + * Fill samples for given subband + */ +static inline void idx_to_quant(MPCContext *c, GetBitContext *gb, int idx, int *dst) +{ + int i, i1, t; + switch(idx){ + case -1: + for(i = 0; i < SAMPLES_PER_BAND; i++){ + *dst++ = (av_random(&c->rnd) & 0x3FC) - 510; + } + break; + case 1: + i1 = get_bits1(gb); + for(i = 0; i < SAMPLES_PER_BAND/3; i++){ + t = get_vlc2(gb, quant_vlc[0][i1].table, 9, 2); + *dst++ = mpc7_idx30[t]; + *dst++ = mpc7_idx31[t]; + *dst++ = mpc7_idx32[t]; + } + break; + case 2: + i1 = get_bits1(gb); + for(i = 0; i < SAMPLES_PER_BAND/2; i++){ + t = get_vlc2(gb, quant_vlc[1][i1].table, 9, 2); + *dst++ = mpc7_idx50[t]; + *dst++ = mpc7_idx51[t]; + } + break; + case 3: case 4: case 5: case 6: case 7: + i1 = get_bits1(gb); + for(i = 0; i < SAMPLES_PER_BAND; i++) + *dst++ = get_vlc2(gb, quant_vlc[idx-1][i1].table, 9, 2) - mpc7_quant_vlc_off[idx-1]; + break; + case 8: case 9: case 10: case 11: case 12: + case 13: case 14: case 15: case 16: case 17: + t = (1 << (idx - 2)) - 1; + for(i = 0; i < SAMPLES_PER_BAND; i++) + *dst++ = get_bits(gb, idx - 1) - t; + break; + default: // case 0 and -2..-17 + return; + } +} + +static int mpc7_decode_frame(AVCodecContext * avctx, + void *data, int *data_size, + const uint8_t * buf, int buf_size) +{ + MPCContext *c = avctx->priv_data; + GetBitContext gb; + uint8_t *bits; + int i, ch, t; + int mb = -1; + Band *bands = c->bands; + int off; + int bits_used, bits_avail; + + memset(bands, 0, sizeof(bands)); + if(buf_size <= 4){ + av_log(avctx, AV_LOG_ERROR, "Too small buffer passed (%i bytes)\n", buf_size); + } + + bits = av_malloc(((buf_size - 1) & ~3) + FF_INPUT_BUFFER_PADDING_SIZE); + c->dsp.bswap_buf((uint32_t*)bits, (const uint32_t*)(buf + 4), (buf_size - 4) >> 2); + init_get_bits(&gb, bits, (buf_size - 4)* 8); + skip_bits(&gb, buf[0]); + + /* read subband indexes */ + for(i = 0; i <= c->maxbands; i++){ + for(ch = 0; ch < 2; ch++){ + if(i) t = get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5; + if(!i || (t == 4)) bands[i].res[ch] = get_bits(&gb, 4); + else bands[i].res[ch] = bands[i-1].res[ch] + t; + } + + if(bands[i].res[0] || bands[i].res[1]){ + mb = i; + if(c->MSS) bands[i].msf = get_bits1(&gb); + } + } + /* get scale indexes coding method */ + for(i = 0; i <= mb; i++) + for(ch = 0; ch < 2; ch++) + if(bands[i].res[ch]) bands[i].scfi[ch] = get_vlc2(&gb, scfi_vlc.table, MPC7_SCFI_BITS, 1); + /* get scale indexes */ + for(i = 0; i <= mb; i++){ + for(ch = 0; ch < 2; ch++){ + if(bands[i].res[ch]){ + bands[i].scf_idx[ch][2] = c->oldDSCF[ch][i]; + t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; + bands[i].scf_idx[ch][0] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][2] + t); + switch(bands[i].scfi[ch]){ + case 0: + t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; + bands[i].scf_idx[ch][1] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][0] + t); + t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; + bands[i].scf_idx[ch][2] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][1] + t); + break; + case 1: + t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; + bands[i].scf_idx[ch][1] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][0] + t); + bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1]; + break; + case 2: + bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; + t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; + bands[i].scf_idx[ch][2] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][1] + t); + break; + case 3: + bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; + break; + } + c->oldDSCF[ch][i] = bands[i].scf_idx[ch][2]; + } + } + } + /* get quantizers */ + memset(c->Q, 0, sizeof(c->Q)); + off = 0; + for(i = 0; i < BANDS; i++, off += SAMPLES_PER_BAND) + for(ch = 0; ch < 2; ch++) + idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off); + + ff_mpc_dequantize_and_synth(c, mb, data); + + av_free(bits); + + bits_used = get_bits_count(&gb); + bits_avail = (buf_size - 4) * 8; + if(!buf[1] && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))){ + av_log(NULL,0, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail); + return -1; + } + if(c->frames_to_skip){ + c->frames_to_skip--; + *data_size = 0; + return buf_size; + } + *data_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4; + + return buf_size; +} + +static void mpc7_decode_flush(AVCodecContext *avctx) +{ + MPCContext *c = avctx->priv_data; + + memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); + c->frames_to_skip = 32; +} + +AVCodec mpc7_decoder = { + "mpc sv7", + CODEC_TYPE_AUDIO, + CODEC_ID_MUSEPACK7, + sizeof(MPCContext), + mpc7_decode_init, + NULL, + NULL, + mpc7_decode_frame, + .flush = mpc7_decode_flush, +}; diff --git a/contrib/ffmpeg/libavcodec/mpc7data.h b/contrib/ffmpeg/libavcodec/mpc7data.h new file mode 100644 index 000000000..b9e64702e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpc7data.h @@ -0,0 +1,171 @@ +/* + * Musepack 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 + */ + +#ifndef FFMPEG_MPC7DATA_H +#define FFMPEG_MPC7DATA_H + +#include <stdint.h> + +static const int8_t mpc7_idx30[] = { -1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1}; +static const int8_t mpc7_idx31[] = { -1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1}; +static const int8_t mpc7_idx32[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}; +static const int8_t mpc7_idx50[] = { -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; +static const int8_t mpc7_idx51[] = { -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; + +#define MPC7_SCFI_SIZE 4 +#define MPC7_SCFI_BITS 3 +static const uint8_t mpc7_scfi[MPC7_SCFI_SIZE * 2] = { + 0x2, 3, 0x1, 1, 0x3, 3, 0x0, 2 +}; + +#define MPC7_DSCF_SIZE 16 +#define MPC7_DSCF_BITS 6 +static const uint8_t mpc7_dscf[MPC7_DSCF_SIZE * 2] = { + 0x20, 6, 0x04, 5, 0x11, 5, 0x1E, 5, 0x0D, 4, 0x00, 3, 0x03, 3, 0x09, 4, + 0x05, 3, 0x02, 3, 0x0E, 4, 0x03, 4, 0x1F, 5, 0x05, 5, 0x21, 6, 0x0C, 4 +}; + +#define MPC7_HDR_SIZE 10 +#define MPC7_HDR_BITS 9 +static const uint8_t mpc7_hdr[MPC7_HDR_SIZE * 2] = { + 0x5C, 8, 0x2F, 7, 0x0A, 5, 0x04, 4, 0x00, 2, + 0x01, 1, 0x03, 3, 0x16, 6, 0xBB, 9, 0xBA, 9 +}; + +#define MPC7_QUANT_VLC_TABLES 7 +static const uint8_t mpc7_quant_vlc_sizes[MPC7_QUANT_VLC_TABLES * 2] = { + 27, 25, 7, 9, 15, 31, 63 +}; + +static const uint8_t mpc7_quant_vlc_off[MPC7_QUANT_VLC_TABLES] = { + 0, 0, 3, 4, 7, 15, 31 +}; + +static const uint16_t mpc7_quant_vlc[MPC7_QUANT_VLC_TABLES][2][64 * 2] = { +{ + { + 0x0036, 6, 0x0009, 5, 0x0020, 6, 0x0005, 5, 0x000A, 4, 0x0007, 5, + 0x0034, 6, 0x0000, 5, 0x0023, 6, 0x000A, 5, 0x0006, 4, 0x0004, 5, + 0x000B, 4, 0x0007, 3, 0x000C, 4, 0x0003, 5, 0x0007, 4, 0x000B, 5, + 0x0022, 6, 0x0001, 5, 0x0035, 6, 0x0006, 5, 0x0009, 4, 0x0002, 5, + 0x0021, 6, 0x0008, 5, 0x0037, 6 + }, + { + 0x0067, 8, 0x003E, 7, 0x00E1, 9, 0x0037, 7, 0x0003, 4, 0x0034, 7, + 0x0065, 8, 0x003C, 7, 0x00E3, 9, 0x0018, 6, 0x0000, 4, 0x003D, 7, + 0x0004, 4, 0x0001, 1, 0x0005, 4, 0x003F, 7, 0x0001, 4, 0x003B, 7, + 0x00E2, 9, 0x0039, 7, 0x0064, 8, 0x0035, 7, 0x0002, 4, 0x0036, 7, + 0x00E0, 9, 0x003A, 7, 0x0066, 8 + } +}, +{ + { + 0x0059, 7, 0x002F, 6, 0x000F, 5, 0x0000, 5, 0x005B, 7, 0x0004, 5, + 0x0006, 4, 0x000D, 4, 0x0004, 4, 0x0005, 5, 0x0014, 5, 0x000C, 4, + 0x0004, 3, 0x000F, 4, 0x000E, 5, 0x0003, 5, 0x0003, 4, 0x000E, 4, + 0x0005, 4, 0x0001, 5, 0x005A, 7, 0x0002, 5, 0x0015, 5, 0x002E, 6, + 0x0058, 7 + }, + { + 0x0399, 10, 0x0071, 7, 0x0033, 6, 0x00E7, 8, 0x039A, 10, 0x0068, 7, + 0x001E, 5, 0x0000, 3, 0x001D, 5, 0x0069, 7, 0x0032, 6, 0x0001, 3, + 0x0002, 2, 0x0003, 3, 0x0031, 6, 0x006B, 7, 0x001B, 5, 0x0002, 3, + 0x001F, 5, 0x0070, 7, 0x0398, 10, 0x006A, 7, 0x0030, 6, 0x0072, 7, + 0x039B, 10 + } +}, +{ + { + 0x000C, 4, 0x0004, 3, 0x0000, 2, 0x0001, 2, 0x0007, 3, 0x0005, 3, 0x000D, 4 + }, + { + 0x0004, 5, 0x0003, 4, 0x0002, 2, 0x0003, 2, 0x0001, 2, 0x0000, 3, 0x0005, 5 + } +}, +{ + { + 0x0005, 4, 0x0000, 3, 0x0004, 3, 0x0006, 3, 0x0007, 3, 0x0005, 3, 0x0003, 3, 0x0001, 3, 0x0004, 4 + }, + { + 0x0009, 5, 0x000C, 4, 0x0003, 3, 0x0000, 2, 0x0002, 2, 0x0007, 3, 0x000D, 4, 0x0005, 4, 0x0008, 5 + } +}, +{ + { + 0x0039, 6, 0x0017, 5, 0x0008, 4, 0x000A, 4, 0x000D, 4, 0x0000, 3, + 0x0002, 3, 0x0003, 3, 0x0001, 3, 0x000F, 4, 0x000C, 4, 0x0009, 4, + 0x001D, 5, 0x0016, 5, 0x0038, 6, + }, + { + 0x00E5, 8, 0x0038, 6, 0x0007, 5, 0x0002, 4, 0x0000, 3, 0x0003, 3, + 0x0005, 3, 0x0006, 3, 0x0004, 3, 0x0002, 3, 0x000F, 4, 0x001D, 5, + 0x0006, 5, 0x0073, 7, 0x00E4, 8, + }, +}, +{ + { + 0x0041, 7, 0x0006, 6, 0x002C, 6, 0x002D, 6, 0x003B, 6, 0x000D, 5, + 0x0011, 5, 0x0013, 5, 0x0017, 5, 0x0015, 5, 0x001A, 5, 0x001E, 5, + 0x0000, 4, 0x0002, 4, 0x0005, 4, 0x0007, 4, 0x0003, 4, 0x0004, 4, + 0x001F, 5, 0x001C, 5, 0x0019, 5, 0x001B, 5, 0x0018, 5, 0x0014, 5, + 0x0012, 5, 0x000C, 5, 0x0002, 5, 0x003A, 6, 0x0021, 6, 0x0007, 6, + 0x0040, 7 + }, + { + 0x1948, 13, 0x194A, 13, 0x0328, 10, 0x0195, 9, 0x00CB, 8, 0x0066, 7, + 0x0031, 6, 0x0009, 5, 0x000F, 5, 0x001F, 5, 0x0002, 4, 0x0006, 4, + 0x0008, 4, 0x000B, 4, 0x000D, 4, 0x0000, 3, 0x000E, 4, 0x000A, 4, + 0x0009, 4, 0x0005, 4, 0x0003, 4, 0x001E, 5, 0x000E, 5, 0x0008, 5, + 0x0030, 6, 0x0067, 7, 0x00C9, 8, 0x00C8, 8, 0x0653, 11, 0x1949, 13, + 0x194B, 13 + } +}, +{ + { + 0x0067, 8, 0x0099, 8, 0x00B5, 8, 0x00E9, 8, 0x0040, 7, 0x0041, 7, + 0x004D, 7, 0x0051, 7, 0x005B, 7, 0x0071, 7, 0x0070, 7, 0x0018, 6, + 0x001D, 6, 0x0023, 6, 0x0025, 6, 0x0029, 6, 0x002C, 6, 0x002E, 6, + 0x0033, 6, 0x0031, 6, 0x0036, 6, 0x0037, 6, 0x0039, 6, 0x003C, 6, + 0x0000, 5, 0x0002, 5, 0x000A, 5, 0x0005, 5, 0x0009, 5, 0x0006, 5, + 0x000D, 5, 0x0007, 5, 0x000B, 5, 0x000F, 5, 0x0008, 5, 0x0004, 5, + 0x0003, 5, 0x0001, 5, 0x003F, 6, 0x003E, 6, 0x003D, 6, 0x0035, 6, + 0x003B, 6, 0x0034, 6, 0x0030, 6, 0x002F, 6, 0x002B, 6, 0x002A, 6, + 0x0027, 6, 0x0024, 6, 0x0021, 6, 0x001C, 6, 0x0075, 7, 0x0065, 7, + 0x0064, 7, 0x0050, 7, 0x0045, 7, 0x0044, 7, 0x0032, 7, 0x00E8, 8, + 0x00B4, 8, 0x0098, 8, 0x0066, 8 + }, + { + 0x37A4, 14, 0x37AD, 14, 0x37A6, 14, 0x37AE, 14, 0x0DEA, 12, 0x02F0, 10, + 0x02F1, 10, 0x00A0, 9, 0x00A2, 9, 0x01BC, 9, 0x007A, 8, 0x00DF, 8, + 0x003C, 7, 0x0049, 7, 0x006E, 7, 0x000E, 6, 0x0018, 6, 0x0019, 6, + 0x0022, 6, 0x0025, 6, 0x0036, 6, 0x0003, 5, 0x0009, 5, 0x000B, 5, + 0x0010, 5, 0x0013, 5, 0x0015, 5, 0x0018, 5, 0x001A, 5, 0x001D, 5, + 0x001F, 5, 0x0002, 4, 0x0000, 4, 0x001E, 5, 0x001C, 5, 0x0019, 5, + 0x0016, 5, 0x0014, 5, 0x000E, 5, 0x000D, 5, 0x0008, 5, 0x0006, 5, + 0x0002, 5, 0x002E, 6, 0x0023, 6, 0x001F, 6, 0x0015, 6, 0x000F, 6, + 0x005F, 7, 0x0048, 7, 0x0029, 7, 0x00BD, 8, 0x007B, 8, 0x0179, 9, + 0x00A1, 9, 0x037B, 10, 0x0147, 10, 0x0146, 10, 0x0DE8, 12, 0x37AF, 14, + 0x37A7, 14, 0x37AC, 14, 0x37A5, 14 + } +} +}; + +#endif /* FFMPEG_MPC7DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/mpc8.c b/contrib/ffmpeg/libavcodec/mpc8.c new file mode 100644 index 000000000..3dfa5c9f3 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpc8.c @@ -0,0 +1,364 @@ +/* + * Musepack SV8 decoder + * Copyright (c) 2007 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 + */ + +/** + * @file mpc8.c Musepack SV8 decoder + * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples + * divided into 32 subbands. + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" +#include "random.h" + +#ifdef CONFIG_MPEGAUDIO_HP +#define USE_HIGHPRECISION +#endif +#include "mpegaudio.h" + +#include "mpc.h" +#include "mpcdata.h" +#include "mpc8data.h" +#include "mpc8huff.h" + +static VLC band_vlc, scfi_vlc[2], dscf_vlc[2], res_vlc[2]; +static VLC q1_vlc, q2_vlc[2], q3_vlc[2], quant_vlc[4][2], q9up_vlc; + +static const int q3_offsets[2] = { MPC8_Q3_OFFSET, MPC8_Q4_OFFSET }; +static const int quant_offsets[6] = { MPC8_Q5_OFFSET, MPC8_Q6_OFFSET, MPC8_Q7_OFFSET, MPC8_Q8_OFFSET }; + +static inline int mpc8_dec_base(GetBitContext *gb, int k, int n) +{ + int code = get_bits(gb, mpc8_cnk_len[k-1][n-1] - 1); + + if (code >= mpc8_cnk_lost[k-1][n-1]) + code = ((code << 1) | get_bits1(gb)) - mpc8_cnk_lost[k-1][n-1]; + + return code; +} + +static inline int mpc8_dec_enum(GetBitContext *gb, int k, int n) +{ + int bits = 0; + const uint32_t * C = mpc8_cnk[k-1]; + int code = mpc8_dec_base(gb, k, n); + + do { + n--; + if (code >= C[n]) { + bits |= 1 << n; + code -= C[n]; + C -= 32; + k--; + } + } while(k > 0); + + return bits; +} + +static inline int mpc8_get_mod_golomb(GetBitContext *gb, int m) +{ + if(mpc8_cnk_len[0][m] < 1) return 0; + return mpc8_dec_base(gb, 1, m+1); +} + +static int mpc8_get_mask(GetBitContext *gb, int size, int t) +{ + int mask = 0; + + if(t && t != size) + mask = mpc8_dec_enum(gb, FFMIN(t, size - t), size); + if((t << 1) > size) mask = ~mask; + + return mask; +} + +static int mpc8_decode_init(AVCodecContext * avctx) +{ + int i; + MPCContext *c = avctx->priv_data; + GetBitContext gb; + static int vlc_initialized = 0; + + if(avctx->extradata_size < 2){ + av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size); + return -1; + } + memset(c->oldDSCF, 0, sizeof(c->oldDSCF)); + av_init_random(0xDEADBEEF, &c->rnd); + dsputil_init(&c->dsp, avctx); + + ff_mpc_init(); + + init_get_bits(&gb, avctx->extradata, 16); + + skip_bits(&gb, 3);//sample rate + c->maxbands = get_bits(&gb, 5) + 1; + skip_bits(&gb, 4);//channels + c->MSS = get_bits1(&gb); + c->frames = 1 << (get_bits(&gb, 3) * 2); + + if(vlc_initialized) return 0; + av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); + + init_vlc(&band_vlc, MPC8_BANDS_BITS, MPC8_BANDS_SIZE, + mpc8_bands_bits, 1, 1, + mpc8_bands_codes, 1, 1, INIT_VLC_USE_STATIC); + + init_vlc(&q1_vlc, MPC8_Q1_BITS, MPC8_Q1_SIZE, + mpc8_q1_bits, 1, 1, + mpc8_q1_codes, 1, 1, INIT_VLC_USE_STATIC); + init_vlc(&q9up_vlc, MPC8_Q9UP_BITS, MPC8_Q9UP_SIZE, + mpc8_q9up_bits, 1, 1, + mpc8_q9up_codes, 1, 1, INIT_VLC_USE_STATIC); + + init_vlc(&scfi_vlc[0], MPC8_SCFI0_BITS, MPC8_SCFI0_SIZE, + mpc8_scfi0_bits, 1, 1, + mpc8_scfi0_codes, 1, 1, INIT_VLC_USE_STATIC); + init_vlc(&scfi_vlc[1], MPC8_SCFI1_BITS, MPC8_SCFI1_SIZE, + mpc8_scfi1_bits, 1, 1, + mpc8_scfi1_codes, 1, 1, INIT_VLC_USE_STATIC); + + init_vlc(&dscf_vlc[0], MPC8_DSCF0_BITS, MPC8_DSCF0_SIZE, + mpc8_dscf0_bits, 1, 1, + mpc8_dscf0_codes, 1, 1, INIT_VLC_USE_STATIC); + init_vlc(&dscf_vlc[1], MPC8_DSCF1_BITS, MPC8_DSCF1_SIZE, + mpc8_dscf1_bits, 1, 1, + mpc8_dscf1_codes, 1, 1, INIT_VLC_USE_STATIC); + + init_vlc_sparse(&q3_vlc[0], MPC8_Q3_BITS, MPC8_Q3_SIZE, + mpc8_q3_bits, 1, 1, + mpc8_q3_codes, 1, 1, + mpc8_q3_syms, 1, 1, INIT_VLC_USE_STATIC); + init_vlc_sparse(&q3_vlc[1], MPC8_Q4_BITS, MPC8_Q4_SIZE, + mpc8_q4_bits, 1, 1, + mpc8_q4_codes, 1, 1, + mpc8_q4_syms, 1, 1, INIT_VLC_USE_STATIC); + + for(i = 0; i < 2; i++){ + init_vlc(&res_vlc[i], MPC8_RES_BITS, MPC8_RES_SIZE, + &mpc8_res_bits[i], 1, 1, + &mpc8_res_codes[i], 1, 1, INIT_VLC_USE_STATIC); + + init_vlc(&q2_vlc[i], MPC8_Q2_BITS, MPC8_Q2_SIZE, + &mpc8_q2_bits[i], 1, 1, + &mpc8_q2_codes[i], 1, 1, INIT_VLC_USE_STATIC); + + init_vlc(&quant_vlc[0][i], MPC8_Q5_BITS, MPC8_Q5_SIZE, + &mpc8_q5_bits[i], 1, 1, + &mpc8_q5_codes[i], 1, 1, INIT_VLC_USE_STATIC); + init_vlc(&quant_vlc[1][i], MPC8_Q6_BITS, MPC8_Q6_SIZE, + &mpc8_q6_bits[i], 1, 1, + &mpc8_q6_codes[i], 1, 1, INIT_VLC_USE_STATIC); + init_vlc(&quant_vlc[2][i], MPC8_Q7_BITS, MPC8_Q7_SIZE, + &mpc8_q7_bits[i], 1, 1, + &mpc8_q7_codes[i], 1, 1, INIT_VLC_USE_STATIC); + init_vlc(&quant_vlc[3][i], MPC8_Q8_BITS, MPC8_Q8_SIZE, + &mpc8_q8_bits[i], 1, 1, + &mpc8_q8_codes[i], 1, 1, INIT_VLC_USE_STATIC); + } + vlc_initialized = 1; + return 0; +} + +static int mpc8_decode_frame(AVCodecContext * avctx, + void *data, int *data_size, + const uint8_t * buf, int buf_size) +{ + MPCContext *c = avctx->priv_data; + GetBitContext gb2, *gb = &gb2; + int i, j, k, ch, cnt, res, t; + Band *bands = c->bands; + int off; + int maxband, keyframe; + int last[2]; + + keyframe = c->cur_frame == 0; + + if(keyframe){ + memset(c->Q, 0, sizeof(c->Q)); + c->last_bits_used = 0; + } + init_get_bits(gb, buf, buf_size * 8); + skip_bits(gb, c->last_bits_used & 7); + + if(keyframe) + maxband = mpc8_get_mod_golomb(gb, c->maxbands + 1); + else{ + maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2); + if(maxband > 32) maxband -= 33; + } + c->last_max_band = maxband; + + /* read subband indexes */ + if(maxband){ + last[0] = last[1] = 0; + for(i = maxband - 1; i >= 0; i--){ + for(ch = 0; ch < 2; ch++){ + last[ch] = get_vlc2(gb, res_vlc[last[ch] > 2].table, MPC8_RES_BITS, 2) + last[ch]; + if(last[ch] > 15) last[ch] -= 17; + bands[i].res[ch] = last[ch]; + } + } + if(c->MSS){ + int mask; + + cnt = 0; + for(i = 0; i < maxband; i++) + if(bands[i].res[0] || bands[i].res[1]) + cnt++; + t = mpc8_get_mod_golomb(gb, cnt); + mask = mpc8_get_mask(gb, cnt, t); + for(i = maxband - 1; i >= 0; i--) + if(bands[i].res[0] || bands[i].res[1]){ + bands[i].msf = mask & 1; + mask >>= 1; + } + } + } + for(i = maxband; i < c->maxbands; i++) + bands[i].res[0] = bands[i].res[1] = 0; + + if(keyframe){ + for(i = 0; i < 32; i++) + c->oldDSCF[0][i] = c->oldDSCF[1][i] = 1; + } + + for(i = 0; i < maxband; i++){ + if(bands[i].res[0] || bands[i].res[1]){ + cnt = !!bands[i].res[0] + !!bands[i].res[1] - 1; + if(cnt >= 0){ + t = get_vlc2(gb, scfi_vlc[cnt].table, scfi_vlc[cnt].bits, 1); + if(bands[i].res[0]) bands[i].scfi[0] = t >> (2 * cnt); + if(bands[i].res[1]) bands[i].scfi[1] = t & 3; + } + } + } + + for(i = 0; i < maxband; i++){ + for(ch = 0; ch < 2; ch++){ + if(!bands[i].res[ch]) continue; + + if(c->oldDSCF[ch][i]){ + bands[i].scf_idx[ch][0] = get_bits(gb, 7) - 6; + c->oldDSCF[ch][i] = 0; + }else{ + t = get_vlc2(gb, dscf_vlc[1].table, MPC8_DSCF1_BITS, 2); + if(t == 64) + t += get_bits(gb, 6); + bands[i].scf_idx[ch][0] = ((bands[i].scf_idx[ch][2] + t - 25) & 0x7F) - 6; + } + for(j = 0; j < 2; j++){ + if((bands[i].scfi[ch] << j) & 2) + bands[i].scf_idx[ch][j + 1] = bands[i].scf_idx[ch][j]; + else{ + t = get_vlc2(gb, dscf_vlc[0].table, MPC8_DSCF0_BITS, 2); + if(t == 31) + t = 64 + get_bits(gb, 6); + bands[i].scf_idx[ch][j + 1] = ((bands[i].scf_idx[ch][j] + t - 25) & 0x7F) - 6; + } + } + } + } + + for(i = 0, off = 0; i < maxband; i++, off += SAMPLES_PER_BAND){ + for(ch = 0; ch < 2; ch++){ + res = bands[i].res[ch]; + switch(res){ + case -1: + for(j = 0; j < SAMPLES_PER_BAND; j++) + c->Q[ch][off + j] = (av_random(&c->rnd) & 0x3FC) - 510; + break; + case 0: + break; + case 1: + for(j = 0; j < SAMPLES_PER_BAND; j += SAMPLES_PER_BAND / 2){ + cnt = get_vlc2(gb, q1_vlc.table, MPC8_Q1_BITS, 2); + t = mpc8_get_mask(gb, 18, cnt); + for(k = 0; k < SAMPLES_PER_BAND / 2; k++, t <<= 1) + c->Q[ch][off + j + k] = (t & 0x20000) ? (get_bits1(gb) << 1) - 1 : 0; + } + break; + case 2: + cnt = 6;//2*mpc8_thres[res] + for(j = 0; j < SAMPLES_PER_BAND; j += 3){ + t = get_vlc2(gb, q2_vlc[cnt > 3].table, MPC8_Q2_BITS, 2); + c->Q[ch][off + j + 0] = mpc8_idx50[t]; + c->Q[ch][off + j + 1] = mpc8_idx51[t]; + c->Q[ch][off + j + 2] = mpc8_idx52[t]; + cnt = (cnt >> 1) + mpc8_huffq2[t]; + } + break; + case 3: + case 4: + for(j = 0; j < SAMPLES_PER_BAND; j += 2){ + t = get_vlc2(gb, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2) + q3_offsets[res - 3]; + c->Q[ch][off + j + 1] = t >> 4; + c->Q[ch][off + j + 0] = (t & 8) ? (t & 0xF) - 16 : (t & 0xF); + } + break; + case 5: + case 6: + case 7: + case 8: + cnt = 2 * mpc8_thres[res]; + for(j = 0; j < SAMPLES_PER_BAND; j++){ + t = get_vlc2(gb, quant_vlc[res - 5][cnt > mpc8_thres[res]].table, quant_vlc[res - 5][cnt > mpc8_thres[res]].bits, 2) + quant_offsets[res - 5]; + c->Q[ch][off + j] = t; + cnt = (cnt >> 1) + FFABS(c->Q[ch][off + j]); + } + break; + default: + for(j = 0; j < SAMPLES_PER_BAND; j++){ + c->Q[ch][off + j] = get_vlc2(gb, q9up_vlc.table, MPC8_Q9UP_BITS, 2); + if(res != 9){ + c->Q[ch][off + j] <<= res - 9; + c->Q[ch][off + j] |= get_bits(gb, res - 9); + } + c->Q[ch][off + j] -= (1 << (res - 2)) - 1; + } + } + } + } + + ff_mpc_dequantize_and_synth(c, maxband, data); + + c->cur_frame++; + + c->last_bits_used = get_bits_count(gb); + if(c->cur_frame >= c->frames) + c->cur_frame = 0; + *data_size = MPC_FRAME_SIZE * 4; + + return c->cur_frame ? c->last_bits_used >> 3 : buf_size; +} + +AVCodec mpc8_decoder = { + "mpc sv8", + CODEC_TYPE_AUDIO, + CODEC_ID_MUSEPACK8, + sizeof(MPCContext), + mpc8_decode_init, + NULL, + NULL, + mpc8_decode_frame, +}; diff --git a/contrib/ffmpeg/libavcodec/mpc8data.h b/contrib/ffmpeg/libavcodec/mpc8data.h new file mode 100644 index 000000000..280dd6ffd --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpc8data.h @@ -0,0 +1,121 @@ +/* + * Musepack SV8 decoder + * Copyright (c) 2007 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 + */ + +#ifndef FFMPEG_MPC8DATA_H +#define FFMPEG_MPC8DATA_H + +#include <stdint.h> + +static const int8_t mpc8_idx50[125] = { + -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, + -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, + -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, + -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, + -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2 +}; +static const int8_t mpc8_idx51[125] = { + -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 +}; +static const int8_t mpc8_idx52[125] = { + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +static const unsigned int mpc8_thres[] = {0, 0, 3, 0, 0, 1, 3, 4, 8}; +static const int8_t mpc8_huffq2[5*5*5] = { + 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, + 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, + 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 2, 3, 4, 3, + 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, + 4, 3, 4, 5, 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, + 6, 5, 4, 5, 6 +}; + + +static const uint32_t mpc8_cnk[16][32] = +{ + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + {0, 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465}, + {0, 0, 0, 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455, 560, 680, 816, 969, 1140, 1330, 1540, 1771, 2024, 2300, 2600, 2925, 3276, 3654, 4060, 4495}, + {0, 0, 0, 0, 1, 5, 15, 35, 70, 126, 210, 330, 495, 715, 1001, 1365, 1820, 2380, 3060, 3876, 4845, 5985, 7315, 8855, 10626, 12650, 14950, 17550, 20475, 23751, 27405, 31465}, + {0, 0, 0, 0, 0, 1, 6, 21, 56, 126, 252, 462, 792, 1287, 2002, 3003, 4368, 6188, 8568, 11628, 15504, 20349, 26334, 33649, 42504, 53130, 65780, 80730, 98280, 118755, 142506, 169911}, + {0, 0, 0, 0, 0, 0, 1, 7, 28, 84, 210, 462, 924, 1716, 3003, 5005, 8008, 12376, 18564, 27132, 38760, 54264, 74613, 100947, 134596, 177100, 230230, 296010, 376740, 475020, 593775, 736281}, + {0, 0, 0, 0, 0, 0, 0, 1, 8, 36, 120, 330, 792, 1716, 3432, 6435, 11440, 19448, 31824, 50388, 77520, 116280, 170544, 245157, 346104, 480700, 657800, 888030, 1184040, 1560780, 2035800, 2629575}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 45, 165, 495, 1287, 3003, 6435, 12870, 24310, 43758, 75582, 125970, 203490, 319770, 490314, 735471, 1081575, 1562275, 2220075, 3108105, 4292145, 5852925, 7888725}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 55, 220, 715, 2002, 5005, 11440, 24310, 48620, 92378, 167960, 293930, 497420, 817190, 1307504, 2042975, 3124550, 4686825, 6906900, 10015005, 14307150, 20160075}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 66, 286, 1001, 3003, 8008, 19448, 43758, 92378, 184756, 352716, 646646, 1144066, 1961256, 3268760, 5311735, 8436285, 13123110, 20030010, 30045015, 44352165}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 78, 364, 1365, 4368, 12376, 31824, 75582, 167960, 352716, 705432, 1352078, 2496144, 4457400, 7726160, 13037895, 21474180, 34597290, 54627300, 84672315}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13, 91, 455, 1820, 6188, 18564, 50388, 125970, 293930, 646646, 1352078, 2704156, 5200300, 9657700, 17383860, 30421755, 51895935, 86493225, 141120525}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 105, 560, 2380, 8568, 27132, 77520, 203490, 497420, 1144066, 2496144, 5200300, 10400600, 20058300, 37442160, 67863915, 119759850, 206253075}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 15, 120, 680, 3060, 11628, 38760, 116280, 319770, 817190, 1961256, 4457400, 9657700, 20058300, 40116600, 77558760, 145422675, 265182525}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 136, 816, 3876, 15504, 54264, 170544, 490314, 1307504, 3268760, 7726160, 17383860, 37442160, 77558760, 155117520, 300540195}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 153, 969, 4845, 20349, 74613, 245157, 735471, 2042975, 5311735, 13037895, 30421755, 67863915, 145422675, 300540195} +}; + +const static uint8_t mpc8_cnk_len[16][33] = +{ + {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6}, + {0, 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0}, + {0, 0, 0, 2, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 0}, + {0, 0, 0, 0, 3, 4, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 0}, + {0, 0, 0, 0, 0, 3, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 0}, + {0, 0, 0, 0, 0, 0, 3, 5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 0}, + {0, 0, 0, 0, 0, 0, 0, 3, 6, 7, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 23, 23, 23, 24, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 10, 11, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 24, 25, 25, 26, 26, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 27, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 28, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 15, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 27, 28, 29, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 16, 17, 19, 20, 21, 23, 24, 25, 26, 27, 28, 28, 29, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 10, 12, 14, 16, 18, 19, 21, 22, 23, 25, 26, 27, 28, 29, 30, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 13, 15, 17, 18, 20, 21, 23, 24, 25, 27, 28, 29, 30, 0} + +}; + +const static uint32_t mpc8_cnk_lost[16][33] = +{ + {0, 0, 1, 0, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 31}, + {0, 0, 1, 2, 6, 1, 11, 4, 28, 19, 9, 62, 50, 37, 23, 8, 120, 103, 85, 66, 46, 25, 3, 236, 212, 187, 161, 134, 106, 77, 47, 16, 0}, + {0, 0, 0, 0, 6, 12, 29, 8, 44, 8, 91, 36, 226, 148, 57, 464, 344, 208, 55, 908, 718, 508, 277, 24, 1796, 1496, 1171, 820, 442, 36, 3697, 3232, 0}, + {0, 0, 0, 0, 3, 1, 29, 58, 2, 46, 182, 17, 309, 23, 683, 228, 1716, 1036, 220, 3347, 2207, 877, 7529, 5758, 3734, 1434, 15218, 12293, 9017, 5363, 1303, 29576, 0}, + {0, 0, 0, 0, 0, 2, 11, 8, 2, 4, 50, 232, 761, 46, 1093, 3824, 2004, 7816, 4756, 880, 12419, 6434, 31887, 23032, 12406, 65292, 50342, 32792, 12317, 119638, 92233, 60768, 0}, + {0, 0, 0, 0, 0, 0, 1, 4, 44, 46, 50, 100, 332, 1093, 3187, 184, 4008, 14204, 5636, 26776, 11272, 56459, 30125, 127548, 85044, 31914, 228278, 147548, 49268, 454801, 312295, 142384, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 28, 8, 182, 232, 332, 664, 1757, 4944, 13320, 944, 15148, 53552, 14792, 91600, 16987, 178184, 43588, 390776, 160546, 913112, 536372, 61352, 1564729, 828448, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 7, 19, 91, 17, 761, 1093, 1757, 3514, 8458, 21778, 55490, 5102, 58654, 204518, 33974, 313105, 1015577, 534877, 1974229, 1086199, 4096463, 2535683, 499883, 6258916, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9, 36, 309, 46, 3187, 4944, 8458, 16916, 38694, 94184, 230358, 26868, 231386, 789648, 54177, 1069754, 3701783, 1481708, 6762211, 2470066, 13394357, 5505632, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 62, 226, 23, 1093, 184, 13320, 21778, 38694, 77388, 171572, 401930, 953086, 135896, 925544, 3076873, 8340931, 3654106, 13524422, 3509417, 22756699, 2596624, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 50, 148, 683, 3824, 4008, 944, 55490, 94184, 171572, 343144, 745074, 1698160, 3931208, 662448, 3739321, 12080252, 32511574, 12481564, 49545413, 5193248, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 37, 57, 228, 2004, 14204, 15148, 5102, 230358, 401930, 745074, 1490148, 3188308, 7119516, 16170572, 3132677, 15212929, 47724503, 127314931, 42642616, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 23, 464, 1716, 7816, 5636, 53552, 58654, 26868, 953086, 1698160, 3188308, 6376616, 13496132, 29666704, 66353813, 14457878, 62182381, 189497312, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 344, 1036, 4756, 26776, 14792, 204518, 231386, 135896, 3931208, 7119516, 13496132, 26992264, 56658968, 123012781, 3252931, 65435312, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 208, 220, 880, 11272, 91600, 33974, 789648, 925544, 662448, 16170572, 29666704, 56658968, 113317936, 236330717, 508019104, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 103, 55, 3347, 12419, 56459, 16987, 313105, 54177, 3076873, 3739321, 3132677, 66353813, 123012781, 236330717, 0} +}; + +#endif /* FFMPEG_MPC8DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/mpc8huff.h b/contrib/ffmpeg/libavcodec/mpc8huff.h new file mode 100644 index 000000000..21e7730ce --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpc8huff.h @@ -0,0 +1,578 @@ +/* + * Musepack SV8 decoder + * Copyright (c) 2007 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 + */ + +#ifndef FFMPEG_MPC8HUFF_H +#define FFMPEG_MPC8HUFF_H + +#include <stdint.h> + +#define MPC8_BANDS_SIZE 33 +#define MPC8_BANDS_BITS 9 + +static const uint8_t mpc8_bands_codes[MPC8_BANDS_SIZE] = { + 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, + 0x05, 0x06, 0x01, 0x02, 0x03, 0x00, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x01, 0x09, 0x0A, 0x0B, 0x07, + 0x08, 0x09, 0x06, 0x07, 0x05, 0x05, 0x03, 0x03, + 0x01, +}; +static const int8_t mpc8_bands_bits[MPC8_BANDS_SIZE] = { + 1, 3, 5, 6, 7, 8, 8, 9, + 10, 11, 12, 12, 12, 13, 12, 12, + 12, 12, 12, 13, 12, 12, 12, 11, + 11, 11, 10, 10, 9, 8, 6, 5, + 2, +}; + +#define MPC8_SCFI0_SIZE 4 +#define MPC8_SCFI0_BITS 3 + +static const uint8_t mpc8_scfi0_codes[MPC8_SCFI0_SIZE] = { + 0x00, 0x01, 0x01, 0x01, +}; +static const int8_t mpc8_scfi0_bits[MPC8_SCFI0_SIZE] = { + 3, 3, 1, 2, +}; + +#define MPC8_SCFI1_SIZE 16 +#define MPC8_SCFI1_BITS 7 + +static const uint8_t mpc8_scfi1_codes[MPC8_SCFI1_SIZE] = { + 0x01, 0x00, 0x02, 0x03, 0x01, 0x03, 0x04, 0x05, + 0x04, 0x06, 0x02, 0x02, 0x05, 0x07, 0x03, 0x03, + +}; +static const int8_t mpc8_scfi1_bits[MPC8_SCFI1_SIZE] = { + 6, 7, 6, 6, 7, 5, 5, 5, + 6, 5, 2, 3, 6, 5, 3, 2, + +}; + +#define MPC8_DSCF0_SIZE 64 +#define MPC8_DSCF0_BITS 9 + +static const uint8_t mpc8_dscf0_codes[MPC8_DSCF0_SIZE] = { + 0x03, 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x07, 0x08, 0x09, 0x0A, 0x07, + 0x08, 0x09, 0x0A, 0x07, 0x08, 0x09, 0x0A, 0x06, + 0x07, 0x05, 0x04, 0x05, 0x06, 0x06, 0x07, 0x0A, + 0x08, 0x05, 0x06, 0x07, 0x09, 0x07, 0x08, 0x09, + 0x0B, 0x0B, 0x0C, 0x0D, 0x0B, 0x0C, 0x0D, 0x0B, + 0x0C, 0x0D, 0x07, 0x08, 0x09, 0x06, 0x07, 0x03, + 0x04, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, +}; +static const int8_t mpc8_dscf0_bits[MPC8_DSCF0_SIZE] = { + 12, 12, 12, 11, 11, 11, 10, 10, + 10, 10, 10, 9, 9, 9, 9, 8, + 8, 8, 8, 7, 7, 7, 7, 6, + 6, 5, 4, 4, 5, 4, 4, 10, + 4, 3, 3, 3, 4, 5, 6, 6, + 7, 8, 8, 8, 9, 9, 9, 10, + 10, 10, 11, 11, 11, 12, 12, 13, + 13, 13, 14, 14, 14, 14, 14, 14, + +}; + +#define MPC8_DSCF1_SIZE 65 +#define MPC8_DSCF1_BITS 9 + +static const uint8_t mpc8_dscf1_codes[MPC8_DSCF1_SIZE] = { + 0x00, 0x03, 0x04, 0x04, 0x05, 0x06, 0x05, 0x06, + 0x07, 0x08, 0x07, 0x08, 0x09, 0x0A, 0x07, 0x08, + 0x09, 0x0A, 0x07, 0x08, 0x09, 0x06, 0x07, 0x05, + 0x06, 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x05, 0x04, 0x05, 0x05, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0B, 0x0C, 0x0D, 0x0B, 0x0C, + 0x0D, 0x09, 0x0A, 0x0B, 0x0C, 0x07, 0x08, 0x09, + 0x05, 0x06, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x0D, +}; +static const int8_t mpc8_dscf1_bits[MPC8_DSCF1_SIZE] = { + 15, 14, 14, 13, 13, 13, 12, 12, + 12, 12, 11, 11, 11, 11, 10, 10, + 10, 10, 9, 9, 9, 8, 8, 7, + 7, 6, 5, 4, 4, 3, 3, 3, + 3, 3, 4, 5, 5, 6, 7, 8, + 8, 9, 9, 10, 10, 10, 11, 11, + 11, 12, 12, 12, 12, 13, 13, 13, + 14, 14, 14, 15, 15, 15, 15, 15, + 12, +}; + +#define MPC8_RES_SIZE 17 +#define MPC8_RES_BITS 9 + +static const uint8_t mpc8_res_codes[2][MPC8_RES_SIZE] = { + { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, + 0x01, + }, + { + 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, 0x01, + 0x03, + } +}; +static const int8_t mpc8_res_bits[2][MPC8_RES_SIZE] = { + { + 1, 2, 4, 5, 6, 7, 9, 10, + 11, 12, 13, 14, 15, 16, 16, 8, + 3, + }, + { + 2, 2, 3, 5, 7, 8, 10, 12, + 14, 14, 14, 14, 11, 9, 6, 4, + 2, + } +}; + +#define MPC8_Q1_SIZE 19 +#define MPC8_Q1_BITS 9 + +static const uint8_t mpc8_q1_codes[MPC8_Q1_SIZE] = { + 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x03, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x01, +}; +static const int8_t mpc8_q1_bits[MPC8_Q1_SIZE] = { + 6, 4, 4, 3, 3, 3, 3, 3, + 4, 4, 4, 5, 7, 8, 9, 10, + 11, 12, 12, +}; + +#define MPC8_Q9UP_SIZE 256 +#define MPC8_Q9UP_BITS 9 + +static const uint8_t mpc8_q9up_codes[MPC8_Q9UP_SIZE] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x26, 0x27, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, + 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x28, 0x26, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, + 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, + 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, + 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, + 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6A, 0x56, 0x57, 0x58, 0x59, + 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x3E, + 0x3F, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x6B, 0x7B, 0x6C, 0x6D, 0x6E, + 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, + 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, + 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, + 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, + 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, + 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0x27, 0x28, 0x29, + 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, + 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4A, 0x4B, 0x06, 0x07, 0x08, 0x09, 0x00, 0x01, +}; +static const int8_t mpc8_q9up_bits[MPC8_Q9UP_SIZE] = { + 10, 10, 10, 10, 10, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 8, 9, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 6, + 6, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 8, 7, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 11, 11, +}; + +#define MPC8_Q2_SIZE 125 +#define MPC8_Q2_BITS 9 + +static const uint8_t mpc8_q2_codes[2][MPC8_Q2_SIZE] = { +{ + 0x02, 0x03, 0x0F, 0x04, 0x00, 0x05, 0x0C, 0x12, + 0x0D, 0x06, 0x07, 0x13, 0x15, 0x14, 0x08, 0x09, + 0x0E, 0x15, 0x0F, 0x0A, 0x03, 0x0B, 0x10, 0x0C, + 0x01, 0x0D, 0x10, 0x16, 0x11, 0x0E, 0x12, 0x0F, + 0x10, 0x16, 0x13, 0x17, 0x11, 0x08, 0x12, 0x18, + 0x14, 0x13, 0x14, 0x17, 0x15, 0x0F, 0x16, 0x19, + 0x17, 0x10, 0x11, 0x1A, 0x18, 0x1B, 0x12, 0x1C, + 0x15, 0x09, 0x16, 0x1D, 0x19, 0x0A, 0x07, 0x0B, + 0x1A, 0x1E, 0x17, 0x0C, 0x18, 0x1F, 0x13, 0x20, + 0x1B, 0x21, 0x14, 0x11, 0x18, 0x22, 0x19, 0x12, + 0x1A, 0x19, 0x1A, 0x1B, 0x1B, 0x23, 0x1C, 0x0D, + 0x1D, 0x24, 0x1C, 0x1C, 0x1E, 0x1F, 0x1D, 0x13, + 0x1E, 0x25, 0x1F, 0x14, 0x02, 0x15, 0x15, 0x16, + 0x04, 0x17, 0x20, 0x26, 0x21, 0x18, 0x16, 0x27, + 0x1D, 0x28, 0x19, 0x1A, 0x22, 0x29, 0x23, 0x1B, + 0x03, 0x1C, 0x17, 0x1D, 0x05, +}, +{ + 0x02, 0x03, 0x0F, 0x04, 0x00, 0x05, 0x0C, 0x0D, + 0x0E, 0x06, 0x07, 0x0F, 0x1E, 0x10, 0x10, 0x08, + 0x11, 0x12, 0x13, 0x09, 0x03, 0x0A, 0x11, 0x0B, + 0x01, 0x0C, 0x14, 0x15, 0x16, 0x0D, 0x17, 0x12, + 0x0E, 0x13, 0x18, 0x19, 0x14, 0x0F, 0x10, 0x1A, + 0x1B, 0x15, 0x11, 0x16, 0x1C, 0x0E, 0x1D, 0x1E, + 0x1F, 0x0F, 0x12, 0x20, 0x1F, 0x21, 0x13, 0x22, + 0x12, 0x13, 0x14, 0x23, 0x20, 0x15, 0x0F, 0x16, + 0x21, 0x24, 0x17, 0x18, 0x19, 0x25, 0x14, 0x26, + 0x22, 0x27, 0x15, 0x10, 0x28, 0x29, 0x2A, 0x11, + 0x2B, 0x17, 0x1A, 0x18, 0x2C, 0x2D, 0x1B, 0x1C, + 0x19, 0x2E, 0x2F, 0x1A, 0x1D, 0x1B, 0x30, 0x12, + 0x31, 0x32, 0x33, 0x13, 0x02, 0x14, 0x15, 0x16, + 0x04, 0x17, 0x34, 0x35, 0x36, 0x18, 0x16, 0x37, + 0x23, 0x38, 0x19, 0x1A, 0x39, 0x3A, 0x3B, 0x1B, + 0x03, 0x1C, 0x17, 0x1D, 0x05, +} +}; +static const int8_t mpc8_q2_bits[2][MPC8_Q2_SIZE] = { +{ + 12, 11, 10, 11, 13, 11, 9, 8, + 9, 11, 11, 8, 7, 8, 11, 11, + 9, 8, 9, 11, 12, 11, 10, 11, + 13, 11, 9, 8, 9, 11, 9, 6, + 6, 7, 9, 8, 6, 4, 6, 8, + 9, 6, 6, 7, 9, 11, 9, 8, + 9, 11, 10, 8, 7, 8, 10, 8, + 6, 4, 6, 8, 7, 4, 3, 4, + 7, 8, 6, 4, 6, 8, 10, 8, + 7, 8, 10, 11, 9, 8, 9, 11, + 9, 6, 6, 6, 9, 8, 6, 4, + 6, 8, 9, 7, 6, 6, 9, 11, + 9, 8, 9, 11, 13, 11, 10, 11, + 12, 11, 9, 8, 9, 11, 10, 8, + 7, 8, 11, 11, 9, 8, 9, 11, + 13, 11, 10, 11, 12, +}, +{ + 11, 10, 9, 10, 12, 10, 8, 8, + 8, 10, 10, 8, 7, 8, 9, 10, + 8, 8, 8, 10, 11, 10, 9, 10, + 12, 10, 8, 8, 8, 10, 8, 6, + 5, 6, 8, 8, 6, 5, 5, 8, + 8, 6, 5, 6, 8, 10, 8, 8, + 8, 10, 9, 8, 7, 8, 9, 8, + 5, 5, 5, 8, 7, 5, 4, 5, + 7, 8, 5, 5, 5, 8, 9, 8, + 7, 8, 9, 10, 8, 8, 8, 10, + 8, 6, 5, 6, 8, 8, 5, 5, + 6, 8, 8, 6, 5, 6, 8, 10, + 8, 8, 8, 10, 12, 10, 10, 10, + 11, 10, 8, 8, 8, 10, 9, 8, + 7, 8, 10, 10, 8, 8, 8, 10, + 12, 10, 9, 10, 11, +} +}; + +#define MPC8_Q3_SIZE 49 +#define MPC8_Q3_BITS 9 +#define MPC8_Q3_OFFSET -48 + +static const uint8_t mpc8_q3_codes[MPC8_Q3_SIZE] = { + 0x07, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x0F, + 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x13, 0x12, 0x11, + 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, + 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, + 0x09, 0x08, 0x07, 0x06, 0x05, 0x09, 0x08, 0x07, + 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, + 0x00, +}; +static const int8_t mpc8_q3_bits[MPC8_Q3_SIZE] = { + 3, 4, 4, 4, 4, 4, 4, 5, + 5, 5, 5, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, + 9, +}; +static const int8_t mpc8_q3_syms[MPC8_Q3_SIZE] = { + 48, 65, 64, 49, 63, 32, 47, 80, + 79, 50, 62, 33, 16, 82, 81, 95, + 94, 66, 78, 34, 46, 17, 31, 30, + 97, 96, 111, 67, 77, 51, 61, 35, + 45, 18, 1, 0, 15, 98, 110, 83, + 93, 19, 29, 2, 14, 99, 109, 3, + 13, +}; + +#define MPC8_Q4_SIZE 81 +#define MPC8_Q4_BITS 9 +#define MPC8_Q4_OFFSET -64 + +static const uint8_t mpc8_q4_codes[MPC8_Q4_SIZE] = { + 0x0F, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, + 0x16, 0x15, 0x14, 0x13, 0x12, 0x23, 0x22, 0x21, + 0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, + 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, + 0x10, 0x0F, 0x0E, 0x0D, 0x19, 0x18, 0x17, 0x16, + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, + 0x0D, 0x0C, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, + 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, + 0x09, 0x08, 0x07, 0x06, 0x05, 0x09, 0x08, 0x07, + 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x01, + 0x00, +}; +static const int8_t mpc8_q4_bits[MPC8_Q4_SIZE] = { + 4, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 10, 10, 10, + 10, +}; +static const int8_t mpc8_q4_syms[MPC8_Q4_SIZE] = { + 64, 96, 81, 80, 95, 66, 65, 79, + 78, 49, 48, 63, 32, 113, 112, 98, + 97, 111, 110, 83, 82, 94, 93, 67, + 77, 51, 50, 62, 61, 34, 33, 47, + 46, 17, 16, 31, 128, 114, 127, 126, + 99, 109, 68, 76, 35, 45, 18, 30, + 0, 15, 130, 129, 143, 142, 115, 125, + 100, 108, 84, 92, 52, 60, 36, 44, + 19, 29, 2, 1, 14, 131, 141, 116, + 124, 20, 28, 3, 13, 132, 140, 4, + 12, +}; + +#define MPC8_Q5_SIZE 15 +#define MPC8_Q5_BITS 7 +#define MPC8_Q5_OFFSET -7 + +static const uint8_t mpc8_q5_codes[2][MPC8_Q5_SIZE] = { +{ + 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, + 0x04, 0x05, 0x03, 0x03, 0x03, 0x02, 0x03, +}, +{ + 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x04, 0x05, 0x03, 0x02, 0x03, +} +}; +static const int8_t mpc8_q5_bits[2][MPC8_Q5_SIZE] = { +{ + 7, 7, 6, 5, 4, 3, 3, 2, + 3, 3, 4, 5, 6, 7, 7, +}, +{ + 6, 6, 5, 4, 4, 3, 3, 3, + 3, 3, 4, 4, 5, 6, 6, +} +}; + +#define MPC8_Q6_SIZE 31 +#define MPC8_Q6_BITS 9 +#define MPC8_Q6_OFFSET -15 + +static const uint8_t mpc8_q6_codes[2][MPC8_Q6_SIZE] = { +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x03, + 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x04, 0x03, + 0x05, 0x06, 0x07, 0x07, 0x06, 0x07, 0x08, 0x09, + 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07, +}, +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x04, 0x05, 0x04, + 0x05, 0x06, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x07, 0x08, 0x09, + 0x06, 0x07, 0x05, 0x06, 0x07, 0x02, 0x03, +} +}; +static const int8_t mpc8_q6_bits[2][MPC8_Q6_SIZE] = { +{ + 9, 9, 9, 9, 8, 8, 7, 6, + 6, 6, 5, 5, 4, 4, 3, 2, + 3, 4, 4, 5, 6, 6, 6, 6, + 7, 8, 8, 9, 9, 9, 9, +}, +{ + 8, 8, 7, 7, 7, 6, 6, 5, + 5, 5, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 7, 7, 8, 8, +} +}; + +#define MPC8_Q7_SIZE 63 +#define MPC8_Q7_BITS 9 +#define MPC8_Q7_OFFSET -31 + +static const uint8_t mpc8_q7_codes[2][MPC8_Q7_SIZE] = { +{ + 0x00, 0x01, 0x02, 0x08, 0x09, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x0A, 0x0B, 0x0C, 0x0D, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0A, 0x0B, 0x0C, 0x08, 0x09, 0x06, 0x04, 0x03, + 0x05, 0x07, 0x0A, 0x0B, 0x0D, 0x0E, 0x0F, 0x0F, + 0x10, 0x11, 0x12, 0x0F, 0x13, 0x10, 0x11, 0x12, + 0x13, 0x0E, 0x0F, 0x10, 0x11, 0x08, 0x09, 0x0A, + 0x0B, 0x0C, 0x12, 0x13, 0x0D, 0x0E, 0x0F, +}, +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x09, 0x0A, + 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, + 0x1E, 0x1F, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x09, 0x0A, + 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x02, 0x03, +} +}; +static const int8_t mpc8_q7_bits[2][MPC8_Q7_SIZE] = { +{ + 10, 10, 10, 9, 9, 10, 10, 10, + 10, 10, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 7, 7, 7, 7, 7, + 6, 6, 6, 5, 5, 4, 3, 2, + 3, 4, 5, 5, 6, 6, 6, 7, + 7, 7, 7, 8, 7, 8, 8, 8, + 8, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 9, 9, 10, 10, 10, +}, +{ + 9, 9, 8, 8, 8, 8, 8, 8, + 8, 7, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 6, 6, 6, 6, 6, 6, + 6, 7, 7, 7, 7, 7, 8, 8, + 8, 8, 8, 8, 8, 9, 9, +} +}; + +#define MPC8_Q8_SIZE 127 +#define MPC8_Q8_BITS 9 +#define MPC8_Q8_OFFSET -63 + +static const uint8_t mpc8_q8_codes[2][MPC8_Q8_SIZE] = { +{ + 0x03, 0x04, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x1A, + 0x0F, 0x1B, 0x10, 0x00, 0x01, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x11, 0x0C, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1C, 0x1A, + 0x1B, 0x1C, 0x1D, 0x1E, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x19, 0x25, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F, 0x14, 0x15, 0x16, 0x17, + 0x0E, 0x0F, 0x10, 0x11, 0x0B, 0x07, 0x04, 0x03, + 0x05, 0x0C, 0x0D, 0x12, 0x13, 0x14, 0x15, 0x18, + 0x19, 0x1A, 0x1B, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x26, 0x27, 0x28, 0x29, 0x2A, + 0x2B, 0x2C, 0x2D, 0x2E, 0x1F, 0x20, 0x2F, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x0D, 0x0E, 0x2A, 0x0F, 0x10, 0x11, 0x12, 0x02, + 0x13, 0x03, 0x04, 0x05, 0x2B, 0x2C, 0x30, 0x31, + 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, +}, +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, + 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, + 0x2F, 0x30, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, + 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x31, 0x3F, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, + 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x16, + 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, + 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x04, 0x05, 0x06, 0x07, +} +}; +static const int8_t mpc8_q8_bits[2][MPC8_Q8_SIZE] = { +{ + 11, 11, 10, 10, 10, 10, 10, 9, + 10, 9, 10, 12, 12, 11, 11, 11, + 11, 11, 11, 11, 10, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 9, 10, + 10, 10, 10, 10, 9, 9, 9, 9, + 9, 9, 9, 9, 8, 9, 8, 8, + 8, 8, 8, 8, 7, 7, 7, 7, + 6, 6, 6, 6, 5, 4, 3, 2, + 3, 5, 5, 6, 6, 6, 6, 7, + 7, 7, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 10, 10, 9, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 10, 11, 11, 11, 11, 12, + 11, 12, 12, 12, 10, 10, 9, 9, + 10, 10, 10, 10, 10, 10, 10, +}, +{ + 9, 9, 9, 9, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 9, 9, 9, 9, +} +}; + +#endif /* FFMPEG_MPC8HUFF_H */ diff --git a/contrib/ffmpeg/libavcodec/mpcdata.h b/contrib/ffmpeg/libavcodec/mpcdata.h index 2b74765ed..23ad06d9c 100644 --- a/contrib/ffmpeg/libavcodec/mpcdata.h +++ b/contrib/ffmpeg/libavcodec/mpcdata.h @@ -17,14 +17,12 @@ * 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 - * */ -static const int8_t mpc_idx30[] = { -1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1}; -static const int8_t mpc_idx31[] = { -1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1}; -static const int8_t mpc_idx32[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}; -static const int8_t mpc_idx50[] = { -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; -static const int8_t mpc_idx51[] = { -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; +#ifndef FFMPEG_MPCDATA_H +#define FFMPEG_MPCDATA_H + +#include <stdint.h> static const float mpc_CC[18] = { 65536.0000, 21845.3333, 13107.2000, 9362.2857, 7281.7778, 4369.0667, 2114.0645, @@ -32,145 +30,7 @@ static const float mpc_CC[18] = { 4.0002, 2.0001, 1.0000 }; -#define MPC7_SCFI_SIZE 4 -#define MPC7_SCFI_BITS 3 -static const uint8_t mpc7_scfi[MPC7_SCFI_SIZE * 2] = { - 0x2, 3, 0x1, 1, 0x3, 3, 0x0, 2 -}; - -#define MPC7_DSCF_SIZE 16 -#define MPC7_DSCF_BITS 6 -static const uint8_t mpc7_dscf[MPC7_DSCF_SIZE * 2] = { - 0x20, 6, 0x04, 5, 0x11, 5, 0x1E, 5, 0x0D, 4, 0x00, 3, 0x03, 3, 0x09, 4, - 0x05, 3, 0x02, 3, 0x0E, 4, 0x03, 4, 0x1F, 5, 0x05, 5, 0x21, 6, 0x0C, 4 -}; - -#define MPC7_HDR_SIZE 10 -#define MPC7_HDR_BITS 9 -static const uint8_t mpc7_hdr[MPC7_HDR_SIZE * 2] = { - 0x5C, 8, 0x2F, 7, 0x0A, 5, 0x04, 4, 0x00, 2, - 0x01, 1, 0x03, 3, 0x16, 6, 0xBB, 9, 0xBA, 9 -}; - -#define MPC7_QUANT_VLC_TABLES 7 -static const uint8_t mpc7_quant_vlc_sizes[MPC7_QUANT_VLC_TABLES * 2] = { - 27, 25, 7, 9, 15, 31, 63 -}; - -static const uint8_t mpc7_quant_vlc_off[MPC7_QUANT_VLC_TABLES] = { - 0, 0, 3, 4, 7, 15, 31 -}; - -static const uint16_t mpc7_quant_vlc[MPC7_QUANT_VLC_TABLES][2][64 * 2] = { -{ - { - 0x0036, 6, 0x0009, 5, 0x0020, 6, 0x0005, 5, 0x000A, 4, 0x0007, 5, - 0x0034, 6, 0x0000, 5, 0x0023, 6, 0x000A, 5, 0x0006, 4, 0x0004, 5, - 0x000B, 4, 0x0007, 3, 0x000C, 4, 0x0003, 5, 0x0007, 4, 0x000B, 5, - 0x0022, 6, 0x0001, 5, 0x0035, 6, 0x0006, 5, 0x0009, 4, 0x0002, 5, - 0x0021, 6, 0x0008, 5, 0x0037, 6 - }, - { - 0x0067, 8, 0x003E, 7, 0x00E1, 9, 0x0037, 7, 0x0003, 4, 0x0034, 7, - 0x0065, 8, 0x003C, 7, 0x00E3, 9, 0x0018, 6, 0x0000, 4, 0x003D, 7, - 0x0004, 4, 0x0001, 1, 0x0005, 4, 0x003F, 7, 0x0001, 4, 0x003B, 7, - 0x00E2, 9, 0x0039, 7, 0x0064, 8, 0x0035, 7, 0x0002, 4, 0x0036, 7, - 0x00E0, 9, 0x003A, 7, 0x0066, 8 - } -}, -{ - { - 0x0059, 7, 0x002F, 6, 0x000F, 5, 0x0000, 5, 0x005B, 7, 0x0004, 5, - 0x0006, 4, 0x000D, 4, 0x0004, 4, 0x0005, 5, 0x0014, 5, 0x000C, 4, - 0x0004, 3, 0x000F, 4, 0x000E, 5, 0x0003, 5, 0x0003, 4, 0x000E, 4, - 0x0005, 4, 0x0001, 5, 0x005A, 7, 0x0002, 5, 0x0015, 5, 0x002E, 6, - 0x0058, 7 - }, - { - 0x0399, 10, 0x0071, 7, 0x0033, 6, 0x00E7, 8, 0x039A, 10, 0x0068, 7, - 0x001E, 5, 0x0000, 3, 0x001D, 5, 0x0069, 7, 0x0032, 6, 0x0001, 3, - 0x0002, 2, 0x0003, 3, 0x0031, 6, 0x006B, 7, 0x001B, 5, 0x0002, 3, - 0x001F, 5, 0x0070, 7, 0x0398, 10, 0x006A, 7, 0x0030, 6, 0x0072, 7, - 0x039B, 10 - } -}, -{ - { - 0x000C, 4, 0x0004, 3, 0x0000, 2, 0x0001, 2, 0x0007, 3, 0x0005, 3, 0x000D, 4 - }, - { - 0x0004, 5, 0x0003, 4, 0x0002, 2, 0x0003, 2, 0x0001, 2, 0x0000, 3, 0x0005, 5 - } -}, -{ - { - 0x0005, 4, 0x0000, 3, 0x0004, 3, 0x0006, 3, 0x0007, 3, 0x0005, 3, 0x0003, 3, 0x0001, 3, 0x0004, 4 - }, - { - 0x0009, 5, 0x000C, 4, 0x0003, 3, 0x0000, 2, 0x0002, 2, 0x0007, 3, 0x000D, 4, 0x0005, 4, 0x0008, 5 - } -}, -{ - { - 0x0039, 6, 0x0017, 5, 0x0008, 4, 0x000A, 4, 0x000D, 4, 0x0000, 3, - 0x0002, 3, 0x0003, 3, 0x0001, 3, 0x000F, 4, 0x000C, 4, 0x0009, 4, - 0x001D, 5, 0x0016, 5, 0x0038, 6, - }, - { - 0x00E5, 8, 0x0038, 6, 0x0007, 5, 0x0002, 4, 0x0000, 3, 0x0003, 3, - 0x0005, 3, 0x0006, 3, 0x0004, 3, 0x0002, 3, 0x000F, 4, 0x001D, 5, - 0x0006, 5, 0x0073, 7, 0x00E4, 8, - }, -}, -{ - { - 0x0041, 7, 0x0006, 6, 0x002C, 6, 0x002D, 6, 0x003B, 6, 0x000D, 5, - 0x0011, 5, 0x0013, 5, 0x0017, 5, 0x0015, 5, 0x001A, 5, 0x001E, 5, - 0x0000, 4, 0x0002, 4, 0x0005, 4, 0x0007, 4, 0x0003, 4, 0x0004, 4, - 0x001F, 5, 0x001C, 5, 0x0019, 5, 0x001B, 5, 0x0018, 5, 0x0014, 5, - 0x0012, 5, 0x000C, 5, 0x0002, 5, 0x003A, 6, 0x0021, 6, 0x0007, 6, - 0x0040, 7 - }, - { - 0x1948, 13, 0x194A, 13, 0x0328, 10, 0x0195, 9, 0x00CB, 8, 0x0066, 7, - 0x0031, 6, 0x0009, 5, 0x000F, 5, 0x001F, 5, 0x0002, 4, 0x0006, 4, - 0x0008, 4, 0x000B, 4, 0x000D, 4, 0x0000, 3, 0x000E, 4, 0x000A, 4, - 0x0009, 4, 0x0005, 4, 0x0003, 4, 0x001E, 5, 0x000E, 5, 0x0008, 5, - 0x0030, 6, 0x0067, 7, 0x00C9, 8, 0x00C8, 8, 0x0653, 11, 0x1949, 13, - 0x194B, 13 - } -}, -{ - { - 0x0067, 8, 0x0099, 8, 0x00B5, 8, 0x00E9, 8, 0x0040, 7, 0x0041, 7, - 0x004D, 7, 0x0051, 7, 0x005B, 7, 0x0071, 7, 0x0070, 7, 0x0018, 6, - 0x001D, 6, 0x0023, 6, 0x0025, 6, 0x0029, 6, 0x002C, 6, 0x002E, 6, - 0x0033, 6, 0x0031, 6, 0x0036, 6, 0x0037, 6, 0x0039, 6, 0x003C, 6, - 0x0000, 5, 0x0002, 5, 0x000A, 5, 0x0005, 5, 0x0009, 5, 0x0006, 5, - 0x000D, 5, 0x0007, 5, 0x000B, 5, 0x000F, 5, 0x0008, 5, 0x0004, 5, - 0x0003, 5, 0x0001, 5, 0x003F, 6, 0x003E, 6, 0x003D, 6, 0x0035, 6, - 0x003B, 6, 0x0034, 6, 0x0030, 6, 0x002F, 6, 0x002B, 6, 0x002A, 6, - 0x0027, 6, 0x0024, 6, 0x0021, 6, 0x001C, 6, 0x0075, 7, 0x0065, 7, - 0x0064, 7, 0x0050, 7, 0x0045, 7, 0x0044, 7, 0x0032, 7, 0x00E8, 8, - 0x00B4, 8, 0x0098, 8, 0x0066, 8 - }, - { - 0x37A4, 14, 0x37AD, 14, 0x37A6, 14, 0x37AE, 14, 0x0DEA, 12, 0x02F0, 10, - 0x02F1, 10, 0x00A0, 9, 0x00A2, 9, 0x01BC, 9, 0x007A, 8, 0x00DF, 8, - 0x003C, 7, 0x0049, 7, 0x006E, 7, 0x000E, 6, 0x0018, 6, 0x0019, 6, - 0x0022, 6, 0x0025, 6, 0x0036, 6, 0x0003, 5, 0x0009, 5, 0x000B, 5, - 0x0010, 5, 0x0013, 5, 0x0015, 5, 0x0018, 5, 0x001A, 5, 0x001D, 5, - 0x001F, 5, 0x0002, 4, 0x0000, 4, 0x001E, 5, 0x001C, 5, 0x0019, 5, - 0x0016, 5, 0x0014, 5, 0x000E, 5, 0x000D, 5, 0x0008, 5, 0x0006, 5, - 0x0002, 5, 0x002E, 6, 0x0023, 6, 0x001F, 6, 0x0015, 6, 0x000F, 6, - 0x005F, 7, 0x0048, 7, 0x0029, 7, 0x00BD, 8, 0x007B, 8, 0x0179, 9, - 0x00A1, 9, 0x037B, 10, 0x0147, 10, 0x0146, 10, 0x0DE8, 12, 0x37AF, 14, - 0x37A7, 14, 0x37AC, 14, 0x37A5, 14 - } -} -}; - -static const float mpc7_SCF[128] = { +static const float mpc_SCF[128] = { 307.330047607421875000, 255.999984741210937500, 213.243041992187500000, 177.627334594726562500, 147.960128784179687500, 123.247924804687500000, 102.663139343261718750, 85.516410827636718750, 71.233520507812500000, 59.336143493652343750, 49.425861358642578125, 41.170787811279296875, @@ -204,3 +64,5 @@ static const float mpc7_SCF[128] = { 0.000000092001613439, 0.000000076635565449, 0.000000063835940978, 0.000000053174105119, 0.000000044293003043, 0.000000036895215771, 0.000000030733001921, 0.000000025599996789 }; + +#endif /* FFMPEG_MPCDATA_H */ diff --git a/contrib/ffmpeg/libavcodec/mpeg12.c b/contrib/ffmpeg/libavcodec/mpeg12.c index c0fa7e4bc..56b456a07 100644 --- a/contrib/ffmpeg/libavcodec/mpeg12.c +++ b/contrib/ffmpeg/libavcodec/mpeg12.c @@ -1,5 +1,5 @@ /* - * MPEG1 codec / MPEG2 decoder + * MPEG1/2 decoder * Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * @@ -22,7 +22,7 @@ /** * @file mpeg12.c - * MPEG1/2 codec + * MPEG1/2 decoder */ //#define DEBUG @@ -30,23 +30,15 @@ #include "dsputil.h" #include "mpegvideo.h" +#include "mpeg12.h" #include "mpeg12data.h" +#include "mpeg12decdata.h" #include "bytestream.h" //#undef NDEBUG //#include <assert.h> -/* Start codes. */ -#define SEQ_END_CODE 0x000001b7 -#define SEQ_START_CODE 0x000001b3 -#define GOP_START_CODE 0x000001b8 -#define PICTURE_START_CODE 0x00000100 -#define SLICE_MIN_START_CODE 0x00000101 -#define SLICE_MAX_START_CODE 0x000001af -#define EXT_START_CODE 0x000001b5 -#define USER_START_CODE 0x000001b2 - #define DC_VLC_BITS 9 #define MV_VLC_BITS 9 #define MBINCR_VLC_BITS 9 @@ -55,12 +47,6 @@ #define MB_BTYPE_VLC_BITS 6 #define TEX_VLC_BITS 9 -#ifdef CONFIG_ENCODERS -static void mpeg1_encode_block(MpegEncContext *s, - DCTELEM *block, - int component); -static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added -#endif //CONFIG_ENCODERS static inline int mpeg1_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n); @@ -79,12 +65,10 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred); static void exchange_uv(MpegEncContext *s); -#ifdef HAVE_XVMC extern int XVMC_field_start(MpegEncContext *s, AVCodecContext *avctx); extern int XVMC_field_end(MpegEncContext *s); extern void XVMC_pack_pblocks(MpegEncContext *s,int cbp); extern void XVMC_init_block(MpegEncContext *s);//set s->block -#endif static const enum PixelFormat pixfmt_yuv_420[]= {PIX_FMT_YUV420P,-1}; static const enum PixelFormat pixfmt_yuv_422[]= {PIX_FMT_YUV422P,-1}; @@ -93,22 +77,8 @@ static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = { PIX_FMT_XVMC_MPEG2_IDCT, PIX_FMT_XVMC_MPEG2_MC, -1}; -#ifdef CONFIG_ENCODERS -static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; -static uint8_t fcode_tab[MAX_MV*2+1]; - -static uint8_t uni_mpeg1_ac_vlc_len [64*64*2]; -static uint8_t uni_mpeg2_ac_vlc_len [64*64*2]; -/* simple include everything table for dc, first byte is bits number next 3 are code*/ -static uint32_t mpeg1_lum_dc_uni[512]; -static uint32_t mpeg1_chr_dc_uni[512]; - -static uint8_t mpeg1_index_run[2][64]; -static int8_t mpeg1_max_level[2][64]; -#endif //CONFIG_ENCODERS - -static uint8_t static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; +uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; static void init_2d_vlc_rl(RLTable *rl, int use_static) { @@ -152,260 +122,7 @@ static void init_2d_vlc_rl(RLTable *rl, int use_static) } } -#ifdef CONFIG_ENCODERS -static void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len){ - int i; - - for(i=0; i<128; i++){ - int level= i-64; - int run; - for(run=0; run<64; run++){ - int len, bits, code; - - int alevel= FFABS(level); - int sign= (level>>31)&1; - - if (alevel > rl->max_level[0][run]) - code= 111; /*rl->n*/ - else - code= rl->index_run[0][run] + alevel - 1; - - if (code < 111 /* rl->n */) { - /* store the vlc & sign at once */ - len= rl->table_vlc[code][1]+1; - bits= (rl->table_vlc[code][0]<<1) + sign; - } else { - len= rl->table_vlc[111/*rl->n*/][1]+6; - bits= rl->table_vlc[111/*rl->n*/][0]<<6; - - bits|= run; - if (alevel < 128) { - bits<<=8; len+=8; - bits|= level & 0xff; - } else { - bits<<=16; len+=16; - bits|= level & 0xff; - if (level < 0) { - bits|= 0x8001 + level + 255; - } else { - bits|= level & 0xffff; - } - } - } - - uni_ac_vlc_len [UNI_AC_ENC_INDEX(run, i)]= len; - } - } -} - - -static int find_frame_rate_index(MpegEncContext *s){ - int i; - int64_t dmin= INT64_MAX; - int64_t d; - - for(i=1;i<14;i++) { - int64_t n0= 1001LL/ff_frame_rate_tab[i].den*ff_frame_rate_tab[i].num*s->avctx->time_base.num; - int64_t n1= 1001LL*s->avctx->time_base.den; - if(s->avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL && i>=9) break; - - d = FFABS(n0 - n1); - if(d < dmin){ - dmin=d; - s->frame_rate_index= i; - } - } - if(dmin) - return -1; - else - return 0; -} - -static int encode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - - if(MPV_encode_init(avctx) < 0) - return -1; - - if(find_frame_rate_index(s) < 0){ - if(s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->time_base.den, avctx->time_base.num); - return -1; - }else{ - av_log(avctx, AV_LOG_INFO, "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n", avctx->time_base.den, avctx->time_base.num); - } - } - - if(avctx->profile == FF_PROFILE_UNKNOWN){ - if(avctx->level != FF_LEVEL_UNKNOWN){ - av_log(avctx, AV_LOG_ERROR, "Set profile and level\n"); - return -1; - } - avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; /* Main or 4:2:2 */ - } - - if(avctx->level == FF_LEVEL_UNKNOWN){ - if(avctx->profile == 0){ /* 4:2:2 */ - if(avctx->width <= 720 && avctx->height <= 608) avctx->level = 5; /* Main */ - else avctx->level = 2; /* High */ - }else{ - if(avctx->profile != 1 && s->chroma_format != CHROMA_420){ - av_log(avctx, AV_LOG_ERROR, "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n"); - return -1; - } - if(avctx->width <= 720 && avctx->height <= 576) avctx->level = 8; /* Main */ - else if(avctx->width <= 1440) avctx->level = 6; /* High 1440 */ - else avctx->level = 4; /* High */ - } - } - - if((avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) && s->frame_rate_index != 4){ - av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n"); - return -1; - } - - return 0; -} - -static void put_header(MpegEncContext *s, int header) -{ - align_put_bits(&s->pb); - put_bits(&s->pb, 16, header>>16); - put_bits(&s->pb, 16, header&0xFFFF); -} - -/* put sequence header if needed */ -static void mpeg1_encode_sequence_header(MpegEncContext *s) -{ - unsigned int vbv_buffer_size; - unsigned int fps, v; - int i; - uint64_t time_code; - float best_aspect_error= 1E10; - float aspect_ratio= av_q2d(s->avctx->sample_aspect_ratio); - int constraint_parameter_flag; - - if(aspect_ratio==0.0) aspect_ratio= 1.0; //pixel aspect 1:1 (VGA) - - if (s->current_picture.key_frame) { - AVRational framerate= ff_frame_rate_tab[s->frame_rate_index]; - - /* mpeg1 header repeated every gop */ - put_header(s, SEQ_START_CODE); - - put_bits(&s->pb, 12, s->width); - put_bits(&s->pb, 12, s->height); - - for(i=1; i<15; i++){ - float error= aspect_ratio; - if(s->codec_id == CODEC_ID_MPEG1VIDEO || i <=1) - error-= 1.0/mpeg1_aspect[i]; - else - error-= av_q2d(mpeg2_aspect[i])*s->height/s->width; - - error= FFABS(error); - - if(error < best_aspect_error){ - best_aspect_error= error; - s->aspect_ratio_info= i; - } - } - - put_bits(&s->pb, 4, s->aspect_ratio_info); - put_bits(&s->pb, 4, s->frame_rate_index); - - if(s->avctx->rc_max_rate){ - v = (s->avctx->rc_max_rate + 399) / 400; - if (v > 0x3ffff && s->codec_id == CODEC_ID_MPEG1VIDEO) - v = 0x3ffff; - }else{ - v= 0x3FFFF; - } - - if(s->avctx->rc_buffer_size) - vbv_buffer_size = s->avctx->rc_buffer_size; - else - /* VBV calculation: Scaled so that a VCD has the proper VBV size of 40 kilobytes */ - vbv_buffer_size = (( 20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024; - vbv_buffer_size= (vbv_buffer_size + 16383) / 16384; - - put_bits(&s->pb, 18, v & 0x3FFFF); - put_bits(&s->pb, 1, 1); /* marker */ - put_bits(&s->pb, 10, vbv_buffer_size & 0x3FF); - - constraint_parameter_flag= - s->width <= 768 && s->height <= 576 && - s->mb_width * s->mb_height <= 396 && - s->mb_width * s->mb_height * framerate.num <= framerate.den*396*25 && - framerate.num <= framerate.den*30 && - s->avctx->me_range && s->avctx->me_range < 128 && - vbv_buffer_size <= 20 && - v <= 1856000/400 && - s->codec_id == CODEC_ID_MPEG1VIDEO; - - put_bits(&s->pb, 1, constraint_parameter_flag); - - ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); - ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); - - if(s->codec_id == CODEC_ID_MPEG2VIDEO){ - put_header(s, EXT_START_CODE); - put_bits(&s->pb, 4, 1); //seq ext - - put_bits(&s->pb, 1, s->avctx->profile == 0); //escx 1 for 4:2:2 profile */ - - put_bits(&s->pb, 3, s->avctx->profile); //profile - put_bits(&s->pb, 4, s->avctx->level); //level - - put_bits(&s->pb, 1, s->progressive_sequence); - put_bits(&s->pb, 2, s->chroma_format); - put_bits(&s->pb, 2, 0); //horizontal size ext - put_bits(&s->pb, 2, 0); //vertical size ext - put_bits(&s->pb, 12, v>>18); //bitrate ext - put_bits(&s->pb, 1, 1); //marker - put_bits(&s->pb, 8, vbv_buffer_size >>10); //vbv buffer ext - put_bits(&s->pb, 1, s->low_delay); - put_bits(&s->pb, 2, 0); // frame_rate_ext_n - put_bits(&s->pb, 5, 0); // frame_rate_ext_d - } - - put_header(s, GOP_START_CODE); - put_bits(&s->pb, 1, !!(s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE)); /* drop frame flag */ - /* time code : we must convert from the real frame rate to a - fake mpeg frame rate in case of low frame rate */ - fps = (framerate.num + framerate.den/2)/ framerate.den; - time_code = s->current_picture_ptr->coded_picture_number + s->avctx->timecode_frame_start; - - s->gop_picture_number = s->current_picture_ptr->coded_picture_number; - if (s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) { - /* only works for NTSC 29.97 */ - int d = time_code / 17982; - int m = time_code % 17982; - //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */ - time_code += 18 * d + 2 * ((m - 2) / 1798); - } - put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); - put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); - put_bits(&s->pb, 1, 1); - put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60)); - put_bits(&s->pb, 6, (uint32_t)((time_code % fps))); - put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP)); - put_bits(&s->pb, 1, 0); /* broken link */ - } -} - -static inline void encode_mb_skip_run(MpegEncContext *s, int run){ - while (run >= 33) { - put_bits(&s->pb, 11, 0x008); - run -= 33; - } - put_bits(&s->pb, mbAddrIncrTable[run][1], - mbAddrIncrTable[run][0]); -} -#endif //CONFIG_ENCODERS - -static void common_init(MpegEncContext *s) +void ff_mpeg12_common_init(MpegEncContext *s) { s->y_dc_scale_table= @@ -420,621 +137,6 @@ void ff_mpeg1_clean_buffers(MpegEncContext *s){ memset(s->last_mv, 0, sizeof(s->last_mv)); } -#ifdef CONFIG_ENCODERS - -static av_always_inline void put_qscale(MpegEncContext *s) -{ - if(s->q_scale_type){ - assert(s->qscale>=1 && s->qscale <=12); - put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]); - }else{ - put_bits(&s->pb, 5, s->qscale); - } -} - -void ff_mpeg1_encode_slice_header(MpegEncContext *s){ - put_header(s, SLICE_MIN_START_CODE + s->mb_y); - put_qscale(s); - put_bits(&s->pb, 1, 0); /* slice extra information */ -} - -void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) -{ - mpeg1_encode_sequence_header(s); - - /* mpeg1 picture header */ - put_header(s, PICTURE_START_CODE); - /* temporal reference */ - - // RAL: s->picture_number instead of s->fake_picture_number - put_bits(&s->pb, 10, (s->picture_number - - s->gop_picture_number) & 0x3ff); - put_bits(&s->pb, 3, s->pict_type); - - s->vbv_delay_ptr= s->pb.buf + put_bits_count(&s->pb)/8; - put_bits(&s->pb, 16, 0xFFFF); /* vbv_delay */ - - // RAL: Forward f_code also needed for B frames - if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { - put_bits(&s->pb, 1, 0); /* half pel coordinates */ - if(s->codec_id == CODEC_ID_MPEG1VIDEO) - put_bits(&s->pb, 3, s->f_code); /* forward_f_code */ - else - put_bits(&s->pb, 3, 7); /* forward_f_code */ - } - - // RAL: Backward f_code necessary for B frames - if (s->pict_type == B_TYPE) { - put_bits(&s->pb, 1, 0); /* half pel coordinates */ - if(s->codec_id == CODEC_ID_MPEG1VIDEO) - put_bits(&s->pb, 3, s->b_code); /* backward_f_code */ - else - put_bits(&s->pb, 3, 7); /* backward_f_code */ - } - - put_bits(&s->pb, 1, 0); /* extra bit picture */ - - s->frame_pred_frame_dct = 1; - if(s->codec_id == CODEC_ID_MPEG2VIDEO){ - put_header(s, EXT_START_CODE); - put_bits(&s->pb, 4, 8); //pic ext - if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { - put_bits(&s->pb, 4, s->f_code); - put_bits(&s->pb, 4, s->f_code); - }else{ - put_bits(&s->pb, 8, 255); - } - if (s->pict_type == B_TYPE) { - put_bits(&s->pb, 4, s->b_code); - put_bits(&s->pb, 4, s->b_code); - }else{ - put_bits(&s->pb, 8, 255); - } - put_bits(&s->pb, 2, s->intra_dc_precision); - - assert(s->picture_structure == PICT_FRAME); - put_bits(&s->pb, 2, s->picture_structure); - if (s->progressive_sequence) { - put_bits(&s->pb, 1, 0); /* no repeat */ - } else { - put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first); - } - /* XXX: optimize the generation of this flag with entropy - measures */ - s->frame_pred_frame_dct = s->progressive_sequence; - - put_bits(&s->pb, 1, s->frame_pred_frame_dct); - put_bits(&s->pb, 1, s->concealment_motion_vectors); - put_bits(&s->pb, 1, s->q_scale_type); - put_bits(&s->pb, 1, s->intra_vlc_format); - put_bits(&s->pb, 1, s->alternate_scan); - put_bits(&s->pb, 1, s->repeat_first_field); - s->progressive_frame = s->progressive_sequence; - put_bits(&s->pb, 1, s->chroma_format == CHROMA_420 ? s->progressive_frame : 0); /* chroma_420_type */ - put_bits(&s->pb, 1, s->progressive_frame); - put_bits(&s->pb, 1, 0); //composite_display_flag - } - if(s->flags & CODEC_FLAG_SVCD_SCAN_OFFSET){ - int i; - - put_header(s, USER_START_CODE); - for(i=0; i<sizeof(svcd_scan_offset_placeholder); i++){ - put_bits(&s->pb, 8, svcd_scan_offset_placeholder[i]); - } - } - - s->mb_y=0; - ff_mpeg1_encode_slice_header(s); -} - -static inline void put_mb_modes(MpegEncContext *s, int n, int bits, - int has_mv, int field_motion) -{ - put_bits(&s->pb, n, bits); - if (!s->frame_pred_frame_dct) { - if (has_mv) - put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */ - put_bits(&s->pb, 1, s->interlaced_dct); - } -} - -static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y, - int mb_block_count) -{ - int i, cbp; - const int mb_x = s->mb_x; - const int mb_y = s->mb_y; - const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y; - - /* compute cbp */ - cbp = 0; - for(i=0;i<mb_block_count;i++) { - if (s->block_last_index[i] >= 0) - cbp |= 1 << (mb_block_count - 1 - i); - } - - if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 && - (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) && - ((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) || - (s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | - ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { - s->mb_skip_run++; - s->qscale -= s->dquant; - s->skip_count++; - s->misc_bits++; - s->last_bits++; - if(s->pict_type == P_TYPE){ - s->last_mv[0][1][0]= s->last_mv[0][0][0]= - s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0; - } - } else { - if(first_mb){ - assert(s->mb_skip_run == 0); - encode_mb_skip_run(s, s->mb_x); - }else{ - encode_mb_skip_run(s, s->mb_skip_run); - } - - if (s->pict_type == I_TYPE) { - if(s->dquant && cbp){ - put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */ - put_qscale(s); - }else{ - put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */ - s->qscale -= s->dquant; - } - s->misc_bits+= get_bits_diff(s); - s->i_count++; - } else if (s->mb_intra) { - if(s->dquant && cbp){ - put_mb_modes(s, 6, 0x01, 0, 0); - put_qscale(s); - }else{ - put_mb_modes(s, 5, 0x03, 0, 0); - s->qscale -= s->dquant; - } - s->misc_bits+= get_bits_diff(s); - s->i_count++; - memset(s->last_mv, 0, sizeof(s->last_mv)); - } else if (s->pict_type == P_TYPE) { - if(s->mv_type == MV_TYPE_16X16){ - if (cbp != 0) { - if ((motion_x|motion_y) == 0) { - if(s->dquant){ - put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */ - put_qscale(s); - }else{ - put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */ - } - s->misc_bits+= get_bits_diff(s); - } else { - if(s->dquant){ - put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */ - put_qscale(s); - }else{ - put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */ - } - s->misc_bits+= get_bits_diff(s); - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added - s->mv_bits+= get_bits_diff(s); - } - } else { - put_bits(&s->pb, 3, 1); /* motion only */ - if (!s->frame_pred_frame_dct) - put_bits(&s->pb, 2, 2); /* motion_type: frame */ - s->misc_bits+= get_bits_diff(s); - mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added - mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added - s->qscale -= s->dquant; - s->mv_bits+= get_bits_diff(s); - } - s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x; - s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y; - }else{ - assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD); - - if (cbp) { - if(s->dquant){ - put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */ - put_qscale(s); - }else{ - put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */ - } - } else { - put_bits(&s->pb, 3, 1); /* motion only */ - put_bits(&s->pb, 2, 1); /* motion_type: field */ - s->qscale -= s->dquant; - } - s->misc_bits+= get_bits_diff(s); - for(i=0; i<2; i++){ - put_bits(&s->pb, 1, s->field_select[0][i]); - mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); - mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); - s->last_mv[0][i][0]= s->mv[0][i][0]; - s->last_mv[0][i][1]= 2*s->mv[0][i][1]; - } - s->mv_bits+= get_bits_diff(s); - } - if(cbp) { - if (s->chroma_y_shift) { - put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]); - } else { - put_bits(&s->pb, mbPatTable[cbp>>2][1], mbPatTable[cbp>>2][0]); - put_bits(&s->pb, 2, cbp & 3); - } - } - s->f_count++; - } else{ - static const int mb_type_len[4]={0,3,4,2}; //bak,for,bi - - if(s->mv_type == MV_TYPE_16X16){ - if (cbp){ // With coded bloc pattern - if (s->dquant) { - if(s->mv_dir == MV_DIR_FORWARD) - put_mb_modes(s, 6, 3, 1, 0); - else - put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 0); - put_qscale(s); - } else { - put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 0); - } - }else{ // No coded bloc pattern - put_bits(&s->pb, mb_type_len[s->mv_dir], 2); - if (!s->frame_pred_frame_dct) - put_bits(&s->pb, 2, 2); /* motion_type: frame */ - s->qscale -= s->dquant; - } - s->misc_bits += get_bits_diff(s); - if (s->mv_dir&MV_DIR_FORWARD){ - mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); - mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); - s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0]; - s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1]; - s->f_count++; - } - if (s->mv_dir&MV_DIR_BACKWARD){ - mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); - mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); - s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0]; - s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1]; - s->b_count++; - } - }else{ - assert(s->mv_type == MV_TYPE_FIELD); - assert(!s->frame_pred_frame_dct); - if (cbp){ // With coded bloc pattern - if (s->dquant) { - if(s->mv_dir == MV_DIR_FORWARD) - put_mb_modes(s, 6, 3, 1, 1); - else - put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 1); - put_qscale(s); - } else { - put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 1); - } - }else{ // No coded bloc pattern - put_bits(&s->pb, mb_type_len[s->mv_dir], 2); - put_bits(&s->pb, 2, 1); /* motion_type: field */ - s->qscale -= s->dquant; - } - s->misc_bits += get_bits_diff(s); - if (s->mv_dir&MV_DIR_FORWARD){ - for(i=0; i<2; i++){ - put_bits(&s->pb, 1, s->field_select[0][i]); - mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); - mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); - s->last_mv[0][i][0]= s->mv[0][i][0]; - s->last_mv[0][i][1]= 2*s->mv[0][i][1]; - } - s->f_count++; - } - if (s->mv_dir&MV_DIR_BACKWARD){ - for(i=0; i<2; i++){ - put_bits(&s->pb, 1, s->field_select[1][i]); - mpeg1_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code); - mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code); - s->last_mv[1][i][0]= s->mv[1][i][0]; - s->last_mv[1][i][1]= 2*s->mv[1][i][1]; - } - s->b_count++; - } - } - s->mv_bits += get_bits_diff(s); - if(cbp) { - if (s->chroma_y_shift) { - put_bits(&s->pb, mbPatTable[cbp][1], mbPatTable[cbp][0]); - } else { - put_bits(&s->pb, mbPatTable[cbp>>2][1], mbPatTable[cbp>>2][0]); - put_bits(&s->pb, 2, cbp & 3); - } - } - } - for(i=0;i<mb_block_count;i++) { - if (cbp & (1 << (mb_block_count - 1 - i))) { - mpeg1_encode_block(s, block[i], i); - } - } - s->mb_skip_run = 0; - if(s->mb_intra) - s->i_tex_bits+= get_bits_diff(s); - else - s->p_tex_bits+= get_bits_diff(s); - } -} - -void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y) -{ - if (s->chroma_format == CHROMA_420) mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6); - else mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8); -} - -// RAL: Parameter added: f_or_b_code -static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code) -{ - int code, bit_size, l, bits, range, sign; - - if (val == 0) { - /* zero vector */ - code = 0; - put_bits(&s->pb, - mbMotionVectorTable[0][1], - mbMotionVectorTable[0][0]); - } else { - bit_size = f_or_b_code - 1; - range = 1 << bit_size; - /* modulo encoding */ - l= INT_BIT - 5 - bit_size; - val= (val<<l)>>l; - - if (val >= 0) { - val--; - code = (val >> bit_size) + 1; - bits = val & (range - 1); - sign = 0; - } else { - val = -val; - val--; - code = (val >> bit_size) + 1; - bits = val & (range - 1); - sign = 1; - } - - assert(code > 0 && code <= 16); - - put_bits(&s->pb, - mbMotionVectorTable[code][1], - mbMotionVectorTable[code][0]); - - put_bits(&s->pb, 1, sign); - if (bit_size > 0) { - put_bits(&s->pb, bit_size, bits); - } - } -} - -void ff_mpeg1_encode_init(MpegEncContext *s) -{ - static int done=0; - - common_init(s); - - if(!done){ - int f_code; - int mv; - int i; - - done=1; - init_rl(&rl_mpeg1, static_rl_table_store[0]); - init_rl(&rl_mpeg2, static_rl_table_store[1]); - - for(i=0; i<64; i++) - { - mpeg1_max_level[0][i]= rl_mpeg1.max_level[0][i]; - mpeg1_index_run[0][i]= rl_mpeg1.index_run[0][i]; - } - - init_uni_ac_vlc(&rl_mpeg1, uni_mpeg1_ac_vlc_len); - if(s->intra_vlc_format) - init_uni_ac_vlc(&rl_mpeg2, uni_mpeg2_ac_vlc_len); - - /* build unified dc encoding tables */ - for(i=-255; i<256; i++) - { - int adiff, index; - int bits, code; - int diff=i; - - adiff = FFABS(diff); - if(diff<0) diff--; - index = av_log2(2*adiff); - - bits= vlc_dc_lum_bits[index] + index; - code= (vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1)); - mpeg1_lum_dc_uni[i+255]= bits + (code<<8); - - bits= vlc_dc_chroma_bits[index] + index; - code= (vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1)); - mpeg1_chr_dc_uni[i+255]= bits + (code<<8); - } - - for(f_code=1; f_code<=MAX_FCODE; f_code++){ - for(mv=-MAX_MV; mv<=MAX_MV; mv++){ - int len; - - if(mv==0) len= mbMotionVectorTable[0][1]; - else{ - int val, bit_size, range, code; - - bit_size = f_code - 1; - range = 1 << bit_size; - - val=mv; - if (val < 0) - val = -val; - val--; - code = (val >> bit_size) + 1; - if(code<17){ - len= mbMotionVectorTable[code][1] + 1 + bit_size; - }else{ - len= mbMotionVectorTable[16][1] + 2 + bit_size; - } - } - - mv_penalty[f_code][mv+MAX_MV]= len; - } - } - - - for(f_code=MAX_FCODE; f_code>0; f_code--){ - for(mv=-(8<<f_code); mv<(8<<f_code); mv++){ - fcode_tab[mv+MAX_MV]= f_code; - } - } - } - s->me.mv_penalty= mv_penalty; - s->fcode_tab= fcode_tab; - if(s->codec_id == CODEC_ID_MPEG1VIDEO){ - s->min_qcoeff=-255; - s->max_qcoeff= 255; - }else{ - s->min_qcoeff=-2047; - s->max_qcoeff= 2047; - } - if (s->intra_vlc_format) { - s->intra_ac_vlc_length= - s->intra_ac_vlc_last_length= uni_mpeg2_ac_vlc_len; - } else { - s->intra_ac_vlc_length= - s->intra_ac_vlc_last_length= uni_mpeg1_ac_vlc_len; - } - s->inter_ac_vlc_length= - s->inter_ac_vlc_last_length= uni_mpeg1_ac_vlc_len; -} - -static inline void encode_dc(MpegEncContext *s, int diff, int component) -{ - if(((unsigned) (diff+255)) >= 511){ - int index; - - if(diff<0){ - index= av_log2_16bit(-2*diff); - diff--; - }else{ - index= av_log2_16bit(2*diff); - } - if (component == 0) { - put_bits( - &s->pb, - vlc_dc_lum_bits[index] + index, - (vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1))); - }else{ - put_bits( - &s->pb, - vlc_dc_chroma_bits[index] + index, - (vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1))); - } - }else{ - if (component == 0) { - put_bits( - &s->pb, - mpeg1_lum_dc_uni[diff+255]&0xFF, - mpeg1_lum_dc_uni[diff+255]>>8); - } else { - put_bits( - &s->pb, - mpeg1_chr_dc_uni[diff+255]&0xFF, - mpeg1_chr_dc_uni[diff+255]>>8); - } - } -} - -static void mpeg1_encode_block(MpegEncContext *s, - DCTELEM *block, - int n) -{ - int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign; - int code, component; - const uint16_t (*table_vlc)[2] = rl_mpeg1.table_vlc; - - last_index = s->block_last_index[n]; - - /* DC coef */ - if (s->mb_intra) { - component = (n <= 3 ? 0 : (n&1) + 1); - dc = block[0]; /* overflow is impossible */ - diff = dc - s->last_dc[component]; - encode_dc(s, diff, component); - s->last_dc[component] = dc; - i = 1; - if (s->intra_vlc_format) - table_vlc = rl_mpeg2.table_vlc; - } else { - /* encode the first coefficient : needs to be done here because - it is handled slightly differently */ - level = block[0]; - if (abs(level) == 1) { - code = ((uint32_t)level >> 31); /* the sign bit */ - put_bits(&s->pb, 2, code | 0x02); - i = 1; - } else { - i = 0; - last_non_zero = -1; - goto next_coef; - } - } - - /* now quantify & encode AC coefs */ - last_non_zero = i - 1; - - for(;i<=last_index;i++) { - j = s->intra_scantable.permutated[i]; - level = block[j]; - next_coef: -#if 0 - if (level != 0) - dprintf(s->avctx, "level[%d]=%d\n", i, level); -#endif - /* encode using VLC */ - if (level != 0) { - run = i - last_non_zero - 1; - - alevel= level; - MASK_ABS(sign, alevel) - sign&=1; - - if (alevel <= mpeg1_max_level[0][run]){ - code= mpeg1_index_run[0][run] + alevel - 1; - /* store the vlc & sign at once */ - put_bits(&s->pb, table_vlc[code][1]+1, (table_vlc[code][0]<<1) + sign); - } else { - /* escape seems to be pretty rare <5% so i dont optimize it */ - put_bits(&s->pb, table_vlc[111][1], table_vlc[111][0]); - /* escape: only clip in this case */ - put_bits(&s->pb, 6, run); - if(s->codec_id == CODEC_ID_MPEG1VIDEO){ - if (alevel < 128) { - put_bits(&s->pb, 8, level & 0xff); - } else { - if (level < 0) { - put_bits(&s->pb, 16, 0x8001 + level + 255); - } else { - put_bits(&s->pb, 16, level & 0xffff); - } - } - }else{ - put_bits(&s->pb, 12, level & 0xfff); - } - } - last_non_zero = i; - } - } - /* end of block */ - put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]); -} -#endif //CONFIG_ENCODERS /******************************************/ /* decoding */ @@ -1055,20 +157,20 @@ static void init_vlcs(void) done = 1; init_vlc(&dc_lum_vlc, DC_VLC_BITS, 12, - vlc_dc_lum_bits, 1, 1, - vlc_dc_lum_code, 2, 2, 1); + ff_mpeg12_vlc_dc_lum_bits, 1, 1, + ff_mpeg12_vlc_dc_lum_code, 2, 2, 1); init_vlc(&dc_chroma_vlc, DC_VLC_BITS, 12, - vlc_dc_chroma_bits, 1, 1, - vlc_dc_chroma_code, 2, 2, 1); + ff_mpeg12_vlc_dc_chroma_bits, 1, 1, + ff_mpeg12_vlc_dc_chroma_code, 2, 2, 1); init_vlc(&mv_vlc, MV_VLC_BITS, 17, - &mbMotionVectorTable[0][1], 2, 1, - &mbMotionVectorTable[0][0], 2, 1, 1); + &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1, + &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 1); init_vlc(&mbincr_vlc, MBINCR_VLC_BITS, 36, - &mbAddrIncrTable[0][1], 2, 1, - &mbAddrIncrTable[0][0], 2, 1, 1); + &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1, + &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 1); init_vlc(&mb_pat_vlc, MB_PAT_VLC_BITS, 64, - &mbPatTable[0][1], 2, 1, - &mbPatTable[0][0], 2, 1, 1); + &ff_mpeg12_mbPatTable[0][1], 2, 1, + &ff_mpeg12_mbPatTable[0][0], 2, 1, 1); init_vlc(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7, &table_mb_ptype[0][1], 2, 1, @@ -1076,11 +178,11 @@ static void init_vlcs(void) init_vlc(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, &table_mb_btype[0][1], 2, 1, &table_mb_btype[0][0], 2, 1, 1); - init_rl(&rl_mpeg1, static_rl_table_store[0]); - init_rl(&rl_mpeg2, static_rl_table_store[1]); + init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); + init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); - init_2d_vlc_rl(&rl_mpeg1, 1); - init_2d_vlc_rl(&rl_mpeg2, 1); + init_2d_vlc_rl(&ff_rl_mpeg1, 1); + init_2d_vlc_rl(&ff_rl_mpeg2, 1); } } @@ -1119,26 +221,7 @@ static int mpeg_decode_mb(MpegEncContext *s, assert(s->mb_skipped==0); if (s->mb_skip_run-- != 0) { - if(s->pict_type == I_TYPE){ - av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - - /* skip mb */ - s->mb_intra = 0; - for(i=0;i<12;i++) - s->block_last_index[i] = -1; - if(s->picture_structure == PICT_FRAME) - s->mv_type = MV_TYPE_16X16; - else - s->mv_type = MV_TYPE_FIELD; if (s->pict_type == P_TYPE) { - /* if P type, zero motion vector is implied */ - s->mv_dir = MV_DIR_FORWARD; - s->mv[0][0][0] = s->mv[0][0][1] = 0; - s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; - s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; - s->field_select[0][0]= s->picture_structure - 1; s->mb_skipped = 1; s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; } else { @@ -1151,12 +234,6 @@ static int mpeg_decode_mb(MpegEncContext *s, if(IS_INTRA(mb_type)) return -1; - /* if B type, reuse previous vectors and directions */ - s->mv[0][0][0] = s->last_mv[0][0][0]; - s->mv[0][0][1] = s->last_mv[0][0][1]; - s->mv[1][0][0] = s->last_mv[1][0][0]; - s->mv[1][0][1] = s->last_mv[1][0][1]; - s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]= mb_type | MB_TYPE_SKIP; // assert(s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride - 1]&(MB_TYPE_16x16|MB_TYPE_16x8)); @@ -1261,23 +338,20 @@ static int mpeg_decode_mb(MpegEncContext *s, if (mb_type & MB_TYPE_ZERO_MV){ assert(mb_type & MB_TYPE_CBP); - /* compute dct type */ - if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? - !s->frame_pred_frame_dct) { - s->interlaced_dct = get_bits1(&s->gb); - } - - if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); - s->mv_dir = MV_DIR_FORWARD; - if(s->picture_structure == PICT_FRAME) + if(s->picture_structure == PICT_FRAME){ + if(!s->frame_pred_frame_dct) + s->interlaced_dct = get_bits1(&s->gb); s->mv_type = MV_TYPE_16X16; - else{ + }else{ s->mv_type = MV_TYPE_FIELD; mb_type |= MB_TYPE_INTERLACED; s->field_select[0][0]= s->picture_structure - 1; } + + if (IS_QUANT(mb_type)) + s->qscale = get_qscale(s); + s->last_mv[0][0][0] = 0; s->last_mv[0][0][1] = 0; s->last_mv[0][1][0] = 0; @@ -1287,34 +361,29 @@ static int mpeg_decode_mb(MpegEncContext *s, }else{ assert(mb_type & MB_TYPE_L0L1); //FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED - /* get additionnal motion vector type */ + /* get additional motion vector type */ if (s->frame_pred_frame_dct) motion_type = MT_FRAME; else{ motion_type = get_bits(&s->gb, 2); - } - - /* compute dct type */ - if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var? - !s->frame_pred_frame_dct && HAS_CBP(mb_type)) { - s->interlaced_dct = get_bits1(&s->gb); + if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type)) + s->interlaced_dct = get_bits1(&s->gb); } if (IS_QUANT(mb_type)) s->qscale = get_qscale(s); /* motion vectors */ - s->mv_dir = 0; - for(i=0;i<2;i++) { - if (USES_LIST(mb_type, i)) { - s->mv_dir |= (MV_DIR_FORWARD >> i); - dprintf(s->avctx, "motion_type=%d\n", motion_type); - switch(motion_type) { - case MT_FRAME: /* or MT_16X8 */ - if (s->picture_structure == PICT_FRAME) { + s->mv_dir= (mb_type>>13)&3; + dprintf(s->avctx, "motion_type=%d\n", motion_type); + switch(motion_type) { + case MT_FRAME: /* or MT_16X8 */ + if (s->picture_structure == PICT_FRAME) { + mb_type |= MB_TYPE_16x16; + s->mv_type = MV_TYPE_16X16; + for(i=0;i<2;i++) { + if (USES_LIST(mb_type, i)) { /* MT_FRAME */ - mb_type |= MB_TYPE_16x16; - s->mv_type = MV_TYPE_16X16; s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] = mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]); s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] = @@ -1324,10 +393,14 @@ static int mpeg_decode_mb(MpegEncContext *s, s->mv[i][0][0] <<= 1; s->mv[i][0][1] <<= 1; } - } else { + } + } + } else { + mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; + s->mv_type = MV_TYPE_16X8; + for(i=0;i<2;i++) { + if (USES_LIST(mb_type, i)) { /* MT_16X8 */ - mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; - s->mv_type = MV_TYPE_16X8; for(j=0;j<2;j++) { s->field_select[i][j] = get_bits1(&s->gb); for(k=0;k<2;k++) { @@ -1338,11 +411,15 @@ static int mpeg_decode_mb(MpegEncContext *s, } } } - break; - case MT_FIELD: - s->mv_type = MV_TYPE_FIELD; - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; + } + } + break; + case MT_FIELD: + s->mv_type = MV_TYPE_FIELD; + if (s->picture_structure == PICT_FRAME) { + mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; + for(i=0;i<2;i++) { + if (USES_LIST(mb_type, i)) { for(j=0;j<2;j++) { s->field_select[i][j] = get_bits1(&s->gb); val = mpeg_decode_motion(s, s->mpeg_f_code[i][0], @@ -1356,8 +433,12 @@ static int mpeg_decode_mb(MpegEncContext *s, s->mv[i][j][1] = val; dprintf(s->avctx, "fmy=%d\n", val); } - } else { - mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; + } + } + } else { + mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; + for(i=0;i<2;i++) { + if (USES_LIST(mb_type, i)) { s->field_select[i][0] = get_bits1(&s->gb); for(k=0;k<2;k++) { val = mpeg_decode_motion(s, s->mpeg_f_code[i][k], @@ -1367,59 +448,60 @@ static int mpeg_decode_mb(MpegEncContext *s, s->mv[i][0][k] = val; } } - break; - case MT_DMV: - { - int dmx, dmy, mx, my, m; - - mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0], - s->last_mv[i][0][0]); - s->last_mv[i][0][0] = mx; - s->last_mv[i][1][0] = mx; - dmx = get_dmv(s); - my = mpeg_decode_motion(s, s->mpeg_f_code[i][1], - s->last_mv[i][0][1] >> 1); - dmy = get_dmv(s); - s->mv_type = MV_TYPE_DMV; - - - s->last_mv[i][0][1] = my<<1; - s->last_mv[i][1][1] = my<<1; - - s->mv[i][0][0] = mx; - s->mv[i][0][1] = my; - s->mv[i][1][0] = mx;//not used - s->mv[i][1][1] = my;//not used - - if (s->picture_structure == PICT_FRAME) { - mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; - - //m = 1 + 2 * s->top_field_first; - m = s->top_field_first ? 1 : 3; - - /* top -> top pred */ - s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx; - s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1; - m = 4 - m; - s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx; - s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1; - } else { - mb_type |= MB_TYPE_16x16; - - s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx; - s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy; - if(s->picture_structure == PICT_TOP_FIELD) - s->mv[i][2][1]--; - else - s->mv[i][2][1]++; - } + } + } + break; + case MT_DMV: + s->mv_type = MV_TYPE_DMV; + for(i=0;i<2;i++) { + if (USES_LIST(mb_type, i)) { + int dmx, dmy, mx, my, m; + mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0], + s->last_mv[i][0][0]); + s->last_mv[i][0][0] = mx; + s->last_mv[i][1][0] = mx; + dmx = get_dmv(s); + my = mpeg_decode_motion(s, s->mpeg_f_code[i][1], + s->last_mv[i][0][1] >> 1); + dmy = get_dmv(s); + + + s->last_mv[i][0][1] = my<<1; + s->last_mv[i][1][1] = my<<1; + + s->mv[i][0][0] = mx; + s->mv[i][0][1] = my; + s->mv[i][1][0] = mx;//not used + s->mv[i][1][1] = my;//not used + + if (s->picture_structure == PICT_FRAME) { + mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; + + //m = 1 + 2 * s->top_field_first; + m = s->top_field_first ? 1 : 3; + + /* top -> top pred */ + s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx; + s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1; + m = 4 - m; + s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx; + s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1; + } else { + mb_type |= MB_TYPE_16x16; + + s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx; + s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy; + if(s->picture_structure == PICT_TOP_FIELD) + s->mv[i][2][1]--; + else + s->mv[i][2][1]++; } - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y); - return -1; } } + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y); + return -1; } } @@ -1427,18 +509,15 @@ static int mpeg_decode_mb(MpegEncContext *s, if (HAS_CBP(mb_type)) { s->dsp.clear_blocks(s->block[0]); - if(!s->chroma_y_shift){ - s->dsp.clear_blocks(s->block[6]); - } - cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1); - if (cbp < 0 || ((cbp == 0) && (s->chroma_format < 2)) ){ - av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y); - return -1; - } if(mb_block_count > 6){ cbp<<= mb_block_count-6; cbp |= get_bits(&s->gb, mb_block_count-6); + s->dsp.clear_blocks(s->block[6]); + } + if (cbp <= 0){ + av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y); + return -1; } #ifdef HAVE_XVMC @@ -1565,7 +644,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, { int level, dc, diff, i, j, run; int component; - RLTable *rl = &rl_mpeg1; + RLTable *rl = &ff_rl_mpeg1; uint8_t * const scantable= s->intra_scantable.permutated; const uint16_t *quant_matrix= s->intra_matrix; const int qscale= s->qscale; @@ -1637,7 +716,7 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s, int n) { int level, i, j, run; - RLTable *rl = &rl_mpeg1; + RLTable *rl = &ff_rl_mpeg1; uint8_t * const scantable= s->intra_scantable.permutated; const uint16_t *quant_matrix= s->inter_matrix; const int qscale= s->qscale; @@ -1658,7 +737,9 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s, if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) goto end; } - +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif /* now quantify & encode AC coefs */ for(;;) { GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0); @@ -1698,9 +779,14 @@ static inline int mpeg1_decode_block_inter(MpegEncContext *s, } block[j] = level; +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) break; +#if MIN_CACHE_BITS >= 19 UPDATE_CACHE(re, &s->gb); +#endif } end: LAST_SKIP_BITS(re, &s->gb, 2); @@ -1713,7 +799,7 @@ end: static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n) { int level, i, j, run; - RLTable *rl = &rl_mpeg1; + RLTable *rl = &ff_rl_mpeg1; uint8_t * const scantable= s->intra_scantable.permutated; const int qscale= s->qscale; @@ -1733,6 +819,9 @@ static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *bloc if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) goto end; } +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif /* now quantify & encode AC coefs */ for(;;) { @@ -1769,9 +858,14 @@ static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *bloc } block[j] = level; +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) break; +#if MIN_CACHE_BITS >= 19 UPDATE_CACHE(re, &s->gb); +#endif } end: LAST_SKIP_BITS(re, &s->gb, 2); @@ -1787,7 +881,7 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, int n) { int level, i, j, run; - RLTable *rl = &rl_mpeg1; + RLTable *rl = &ff_rl_mpeg1; uint8_t * const scantable= s->intra_scantable.permutated; const uint16_t *quant_matrix; const int qscale= s->qscale; @@ -1816,6 +910,9 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) goto end; } +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif /* now quantify & encode AC coefs */ for(;;) { @@ -1849,9 +946,14 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, mismatch ^= level; block[j] = level; +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) break; +#if MIN_CACHE_BITS >= 19 UPDATE_CACHE(re, &s->gb); +#endif } end: LAST_SKIP_BITS(re, &s->gb, 2); @@ -1868,7 +970,7 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, int n) { int level, i, j, run; - RLTable *rl = &rl_mpeg1; + RLTable *rl = &ff_rl_mpeg1; uint8_t * const scantable= s->intra_scantable.permutated; const int qscale= s->qscale; OPEN_READER(re, &s->gb); @@ -1886,6 +988,9 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) goto end; } +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif /* now quantify & encode AC coefs */ for(;;) { @@ -1914,9 +1019,14 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, } block[j] = level; +#if MIN_CACHE_BITS < 19 + UPDATE_CACHE(re, &s->gb); +#endif if(((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF) break; +#if MIN_CACHE_BITS >=19 UPDATE_CACHE(re, &s->gb); +#endif } end: LAST_SKIP_BITS(re, &s->gb, 2); @@ -1957,9 +1067,9 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, mismatch = block[0] ^ 1; i = 0; if (s->intra_vlc_format) - rl = &rl_mpeg2; + rl = &ff_rl_mpeg2; else - rl = &rl_mpeg1; + rl = &ff_rl_mpeg1; { OPEN_READER(re, &s->gb); @@ -2033,9 +1143,9 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, s->last_dc[component] = dc; block[0] = dc << (3 - s->intra_dc_precision); if (s->intra_vlc_format) - rl = &rl_mpeg2; + rl = &ff_rl_mpeg2; else - rl = &rl_mpeg1; + rl = &ff_rl_mpeg1; { OPEN_READER(re, &s->gb); @@ -2084,6 +1194,7 @@ typedef struct Mpeg1Context { int slice_count; int swap_uv;//indicate VCR2 int save_aspect_info; + int save_width, save_height; AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator } Mpeg1Context; @@ -2105,7 +1216,7 @@ static int mpeg_decode_init(AVCodecContext *avctx) s->mpeg_enc_ctx.avctx= avctx; s->mpeg_enc_ctx.flags= avctx->flags; s->mpeg_enc_ctx.flags2= avctx->flags2; - common_init(&s->mpeg_enc_ctx); + ff_mpeg12_common_init(&s->mpeg_enc_ctx); init_vlcs(); s->mpeg_enc_ctx_allocated = 0; @@ -2138,6 +1249,8 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ (s1->mpeg_enc_ctx_allocated == 0)|| avctx->coded_width != s->width || avctx->coded_height != s->height|| + s1->save_width != s->width || + s1->save_height != s->height || s1->save_aspect_info != s->aspect_ratio_info|| 0) { @@ -2155,6 +1268,8 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ avcodec_set_dimensions(avctx, s->width, s->height); avctx->bit_rate = s->bit_rate; s1->save_aspect_info = s->aspect_ratio_info; + s1->save_width = s->width; + s1->save_height = s->height; //low_delay may be forced, in this case we will have B frames //that behave like P frames @@ -2166,7 +1281,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ avctx->time_base.num= ff_frame_rate_tab[s->frame_rate_index].den; //mpeg1 aspect avctx->sample_aspect_ratio= av_d2q( - 1.0/mpeg1_aspect[s->aspect_ratio_info], 255); + 1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255); }else{//mpeg2 //mpeg2 fps @@ -2181,19 +1296,19 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){ if( (s1->pan_scan.width == 0 )||(s1->pan_scan.height == 0) ){ s->avctx->sample_aspect_ratio= av_div_q( - mpeg2_aspect[s->aspect_ratio_info], + ff_mpeg2_aspect[s->aspect_ratio_info], (AVRational){s->width, s->height} ); }else{ s->avctx->sample_aspect_ratio= av_div_q( - mpeg2_aspect[s->aspect_ratio_info], + ff_mpeg2_aspect[s->aspect_ratio_info], (AVRational){s1->pan_scan.width, s1->pan_scan.height} ); } }else{ s->avctx->sample_aspect_ratio= - mpeg2_aspect[s->aspect_ratio_info]; + ff_mpeg2_aspect[s->aspect_ratio_info]; } }//mpeg2 @@ -2556,7 +1671,6 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, { MpegEncContext *s = &s1->mpeg_enc_ctx; AVCodecContext *avctx= s->avctx; - int ret; const int field_pic= s->picture_structure != PICT_FRAME; const int lowres= s->avctx->lowres; @@ -2631,11 +1745,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, XVMC_init_block(s);//set s->block #endif - ret = mpeg_decode_mb(s, s->block); - s->chroma_qscale= s->qscale; - - dprintf(s->avctx, "ret=%d\n", ret); - if (ret < 0) + if(mpeg_decode_mb(s, s->block) < 0) return -1; if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs @@ -2670,8 +1780,8 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, } s->dest[0] += 16 >> lowres; - s->dest[1] += 16 >> (s->chroma_x_shift + lowres); - s->dest[2] += 16 >> (s->chroma_x_shift + lowres); + s->dest[1] +=(16 >> lowres) >> s->chroma_x_shift; + s->dest[2] +=(16 >> lowres) >> s->chroma_x_shift; MPV_decode_mb(s, s->block); @@ -2726,10 +1836,40 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, break; } } + if(s->mb_skip_run){ + int i; + if(s->pict_type == I_TYPE){ + av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + /* skip mb */ + s->mb_intra = 0; + for(i=0;i<12;i++) + s->block_last_index[i] = -1; + if(s->picture_structure == PICT_FRAME) + s->mv_type = MV_TYPE_16X16; + else + s->mv_type = MV_TYPE_FIELD; + if (s->pict_type == P_TYPE) { + /* if P type, zero motion vector is implied */ + s->mv_dir = MV_DIR_FORWARD; + s->mv[0][0][0] = s->mv[0][0][1] = 0; + s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0; + s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; + s->field_select[0][0]= s->picture_structure - 1; + } else { + /* if B type, reuse previous vectors and directions */ + s->mv[0][0][0] = s->last_mv[0][0][0]; + s->mv[0][0][1] = s->last_mv[0][0][1]; + s->mv[1][0][0] = s->last_mv[1][0][0]; + s->mv[1][0][1] = s->last_mv[1][0][1]; + } + } } } eos: // end of slice - *buf += get_bits_count(&s->gb)/8 - 1; + *buf += (get_bits_count(&s->gb)-1)/8; //printf("y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y); return 0; } @@ -3037,30 +2177,48 @@ static void mpeg_decode_gop(AVCodecContext *avctx, * finds the end of the current frame in the bitstream. * @return the position of the first byte of the next frame, or -1 */ -static int mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) +int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) { int i; uint32_t state= pc->state; - i=0; - if(!pc->frame_start_found){ - for(i=0; i<buf_size; i++){ + /* EOF considered as end of frame */ + if (buf_size == 0) + return 0; + +/* + 0 frame start -> 1/4 + 1 first_SEQEXT -> 0/2 + 2 first field start -> 3/0 + 3 second_SEQEXT -> 2/0 + 4 searching end +*/ + + for(i=0; i<buf_size; i++){ + assert(pc->frame_start_found>=0 && pc->frame_start_found<=4); + if(pc->frame_start_found&1){ + if(state == EXT_START_CODE && (buf[i]&0xF0) != 0x80) + pc->frame_start_found--; + else if(state == EXT_START_CODE+2){ + if((buf[i]&3) == 3) pc->frame_start_found= 0; + else pc->frame_start_found= (pc->frame_start_found+1)&3; + } + state++; + }else{ i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1; - if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){ + if(pc->frame_start_found==0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){ i++; - pc->frame_start_found=1; - break; + pc->frame_start_found=4; } - } - } - - if(pc->frame_start_found){ - /* EOF considered as end of frame */ - if (buf_size == 0) - return 0; - for(; i<buf_size; i++){ - i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1; - if((state&0xFFFFFF00) == 0x100){ + if(state == SEQ_END_CODE){ + pc->state=-1; + return i+1; + } + if(pc->frame_start_found==2 && state == SEQ_START_CODE) + pc->frame_start_found= 0; + if(pc->frame_start_found<4 && state == EXT_START_CODE) + pc->frame_start_found++; + if(pc->frame_start_found == 4 && (state&0xFFFFFF00) == 0x100){ if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){ pc->frame_start_found=0; pc->state=-1; @@ -3076,7 +2234,7 @@ static int mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_si /* handle buffering and image synchronisation */ static int mpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { Mpeg1Context *s = avctx->priv_data; const uint8_t *buf_end; @@ -3087,7 +2245,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, MpegEncContext *s2 = &s->mpeg_enc_ctx; dprintf(avctx, "fill_buffer\n"); - if (buf_size == 0) { + if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) { /* special case for last picture */ if (s2->low_delay==0 && s2->next_picture_ptr) { *picture= *(AVFrame*)s2->next_picture_ptr; @@ -3095,13 +2253,13 @@ static int mpeg_decode_frame(AVCodecContext *avctx, *data_size = sizeof(AVFrame); } - return 0; + return buf_size; } if(s2->flags&CODEC_FLAG_TRUNCATED){ - int next= mpeg1_find_frame_end(&s2->parse_context, buf, buf_size); + int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size); - if( ff_combine_frame(&s2->parse_context, next, &buf, &buf_size) < 0 ) + if( ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 ) return buf_size; } @@ -3183,18 +2341,20 @@ static int mpeg_decode_frame(AVCodecContext *avctx, int mb_y= start_code - SLICE_MIN_START_CODE; if(s2->last_picture_ptr==NULL){ - /* skip b frames if we dont have reference frames */ + /* Skip B-frames if we do not have reference frames. */ if(s2->pict_type==B_TYPE) break; - /* skip P frames if we dont have reference frame no valid header */ -// if(s2->pict_type==P_TYPE && s2->first_field && !s2->first_slice) break; } - /* skip b frames if we are in a hurry */ + if(s2->next_picture_ptr==NULL){ + /* Skip P-frames if we do not have reference frame no valid header. */ + if(s2->pict_type==P_TYPE && (s2->first_field || s2->picture_structure==PICT_FRAME)) break; + } + /* Skip B-frames if we are in a hurry. */ if(avctx->hurry_up && s2->pict_type==B_TYPE) break; if( (avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type==B_TYPE) ||(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type!=I_TYPE) || avctx->skip_frame >= AVDISCARD_ALL) break; - /* skip everything if we are in a hurry>=5 */ + /* Skip everything if we are in a hurry>=5. */ if(avctx->hurry_up>=5) break; if (!s->mpeg_enc_ctx_allocated) break; @@ -3210,7 +2370,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, return -1; } if(!s2->current_picture_ptr){ - av_log(avctx, AV_LOG_ERROR, "current_picture not initalized\n"); + av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n"); return -1; } @@ -3295,35 +2455,6 @@ AVCodec mpegvideo_decoder = { .flush= ff_mpeg_flush, }; -#ifdef CONFIG_ENCODERS - -AVCodec mpeg1video_encoder = { - "mpeg1video", - CODEC_TYPE_VIDEO, - CODEC_ID_MPEG1VIDEO, - sizeof(MpegEncContext), - encode_init, - MPV_encode_picture, - MPV_encode_end, - .supported_framerates= ff_frame_rate_tab+1, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, - .capabilities= CODEC_CAP_DELAY, -}; - -AVCodec mpeg2video_encoder = { - "mpeg2video", - CODEC_TYPE_VIDEO, - CODEC_ID_MPEG2VIDEO, - sizeof(MpegEncContext), - encode_init, - MPV_encode_picture, - MPV_encode_end, - .supported_framerates= ff_frame_rate_tab+1, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, -1}, - .capabilities= CODEC_CAP_DELAY, -}; -#endif - #ifdef HAVE_XVMC static int mpeg_mc_decode_init(AVCodecContext *avctx){ Mpeg1Context *s; @@ -3359,198 +2490,6 @@ AVCodec mpeg_xvmc_decoder = { #endif -#ifdef CONFIG_MPEGVIDEO_PARSER -static void mpegvideo_extract_headers(AVCodecParserContext *s, - AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - ParseContext1 *pc = s->priv_data; - const uint8_t *buf_end; - uint32_t start_code; - int frame_rate_index, ext_type, bytes_left; - int frame_rate_ext_n, frame_rate_ext_d; - int picture_structure, top_field_first, repeat_first_field, progressive_frame; - int horiz_size_ext, vert_size_ext, bit_rate_ext; -//FIXME replace the crap with get_bits() - s->repeat_pict = 0; - buf_end = buf + buf_size; - while (buf < buf_end) { - start_code= -1; - buf= ff_find_start_code(buf, buf_end, &start_code); - bytes_left = buf_end - buf; - switch(start_code) { - case PICTURE_START_CODE: - if (bytes_left >= 2) { - s->pict_type = (buf[1] >> 3) & 7; - } - break; - case SEQ_START_CODE: - if (bytes_left >= 7) { - pc->width = (buf[0] << 4) | (buf[1] >> 4); - pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; - avcodec_set_dimensions(avctx, pc->width, pc->height); - frame_rate_index = buf[3] & 0xf; - pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num; - pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den; - avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400; - avctx->codec_id = CODEC_ID_MPEG1VIDEO; - avctx->sub_id = 1; - } - break; - case EXT_START_CODE: - if (bytes_left >= 1) { - ext_type = (buf[0] >> 4); - switch(ext_type) { - case 0x1: /* sequence extension */ - if (bytes_left >= 6) { - horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); - vert_size_ext = (buf[2] >> 5) & 3; - bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1); - frame_rate_ext_n = (buf[5] >> 5) & 3; - frame_rate_ext_d = (buf[5] & 0x1f); - pc->progressive_sequence = buf[1] & (1 << 3); - avctx->has_b_frames= !(buf[5] >> 7); - - pc->width |=(horiz_size_ext << 12); - pc->height |=( vert_size_ext << 12); - avctx->bit_rate += (bit_rate_ext << 18) * 400; - avcodec_set_dimensions(avctx, pc->width, pc->height); - avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1); - avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1); - avctx->codec_id = CODEC_ID_MPEG2VIDEO; - avctx->sub_id = 2; /* forces MPEG2 */ - } - break; - case 0x8: /* picture coding extension */ - if (bytes_left >= 5) { - picture_structure = buf[2]&3; - top_field_first = buf[3] & (1 << 7); - repeat_first_field = buf[3] & (1 << 1); - progressive_frame = buf[4] & (1 << 7); - - /* check if we must repeat the frame */ - if (repeat_first_field) { - if (pc->progressive_sequence) { - if (top_field_first) - s->repeat_pict = 4; - else - s->repeat_pict = 2; - } else if (progressive_frame) { - s->repeat_pict = 1; - } - } - - /* the packet only represents half a frame - XXX,FIXME maybe find a different solution */ - if(picture_structure != 3) - s->repeat_pict = -1; - } - break; - } - } - break; - case -1: - goto the_end; - default: - /* we stop parsing when we encounter a slice. It ensures - that this function takes a negligible amount of time */ - if (start_code >= SLICE_MIN_START_CODE && - start_code <= SLICE_MAX_START_CODE) - goto the_end; - break; - } - } - the_end: ; -} - -static int mpegvideo_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext1 *pc1 = s->priv_data; - ParseContext *pc= &pc1->pc; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= mpeg1_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - - } - /* we have a full frame : we just parse the first few MPEG headers - to have the full timing information. The time take by this - function should be negligible for uncorrupted streams */ - mpegvideo_extract_headers(s, avctx, buf, buf_size); -#if 0 - printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", - s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict); -#endif - - *poutbuf = (uint8_t *)buf; - *poutbuf_size = buf_size; - return next; -} - -static int mpegvideo_split(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - int i; - uint32_t state= -1; - - for(i=0; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100) - return i-3; - } - return 0; -} - -AVCodecParser mpegvideo_parser = { - { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, - sizeof(ParseContext1), - NULL, - mpegvideo_parse, - ff_parse1_close, - mpegvideo_split, -}; -#endif /* !CONFIG_MPEGVIDEO_PARSER */ - -static int imx_dump_header(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe) -{ - /* MXF essence element key */ - static const uint8_t imx_header[16] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }; - uint8_t *poutbufp; - - if (avctx->codec_id != CODEC_ID_MPEG2VIDEO) { - av_log(avctx, AV_LOG_ERROR, "imx bitstream filter only applies to mpeg2video codec\n"); - return 0; - } - - *poutbuf = av_malloc(buf_size + 20 + FF_INPUT_BUFFER_PADDING_SIZE); - poutbufp = *poutbuf; - bytestream_put_buffer(&poutbufp, imx_header, 16); - bytestream_put_byte(&poutbufp, 0x83); /* KLV BER long form */ - bytestream_put_be24(&poutbufp, buf_size); - bytestream_put_buffer(&poutbufp, buf, buf_size); - *poutbuf_size = poutbufp - *poutbuf; - return 1; -} - -AVBitStreamFilter imx_dump_header_bsf = { - "imxdump", - 0, - imx_dump_header, -}; - /* this is ugly i know, but the alternative is too make hundreds of vars global and prefix them with ff_mpeg1_ which is far uglier. */ diff --git a/contrib/ffmpeg/libavcodec/mpeg12.h b/contrib/ffmpeg/libavcodec/mpeg12.h new file mode 100644 index 000000000..662e3b38f --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpeg12.h @@ -0,0 +1,31 @@ +/* + * MPEG1/2 common code + * Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> + * + * 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 + */ + +#ifndef FFMPEG_MPEG12_H +#define FFMPEG_MPEG12_H + +#include "mpegvideo.h" + +extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; + +void ff_mpeg12_common_init(MpegEncContext *s); + +#endif /* FFMPEG_MPEG12_H */ diff --git a/contrib/ffmpeg/libavcodec/mpeg12data.c b/contrib/ffmpeg/libavcodec/mpeg12data.c new file mode 100644 index 000000000..93d491f3c --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpeg12data.c @@ -0,0 +1,374 @@ +/* + * MPEG1/2 tables + * copyright (c) 2000,2001 Fabrice Bellard + * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 mpeg12data.c + * MPEG1/2 tables. + */ + +#include "mpeg12data.h" + +const uint16_t ff_mpeg1_default_intra_matrix[64] = { + 8, 16, 19, 22, 26, 27, 29, 34, + 16, 16, 22, 24, 27, 29, 34, 37, + 19, 22, 26, 27, 29, 34, 34, 38, + 22, 22, 26, 27, 29, 34, 37, 40, + 22, 26, 27, 29, 32, 35, 40, 48, + 26, 27, 29, 32, 35, 40, 48, 58, + 26, 27, 29, 34, 38, 46, 56, 69, + 27, 29, 35, 38, 46, 56, 69, 83 +}; + +const uint16_t ff_mpeg1_default_non_intra_matrix[64] = { + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, +}; + +const uint16_t ff_mpeg12_vlc_dc_lum_code[12] = { + 0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x1ff, +}; +const unsigned char ff_mpeg12_vlc_dc_lum_bits[12] = { + 3, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 9, +}; + +const uint16_t ff_mpeg12_vlc_dc_chroma_code[12] = { + 0x0, 0x1, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x3fe, 0x3ff, +}; +const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12] = { + 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, +}; + +static const uint16_t mpeg1_vlc[113][2] = { + { 0x3, 2 }, { 0x4, 4 }, { 0x5, 5 }, { 0x6, 7 }, + { 0x26, 8 }, { 0x21, 8 }, { 0xa, 10 }, { 0x1d, 12 }, + { 0x18, 12 }, { 0x13, 12 }, { 0x10, 12 }, { 0x1a, 13 }, + { 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, { 0x1f, 14 }, + { 0x1e, 14 }, { 0x1d, 14 }, { 0x1c, 14 }, { 0x1b, 14 }, + { 0x1a, 14 }, { 0x19, 14 }, { 0x18, 14 }, { 0x17, 14 }, + { 0x16, 14 }, { 0x15, 14 }, { 0x14, 14 }, { 0x13, 14 }, + { 0x12, 14 }, { 0x11, 14 }, { 0x10, 14 }, { 0x18, 15 }, + { 0x17, 15 }, { 0x16, 15 }, { 0x15, 15 }, { 0x14, 15 }, + { 0x13, 15 }, { 0x12, 15 }, { 0x11, 15 }, { 0x10, 15 }, + { 0x3, 3 }, { 0x6, 6 }, { 0x25, 8 }, { 0xc, 10 }, + { 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x1f, 15 }, + { 0x1e, 15 }, { 0x1d, 15 }, { 0x1c, 15 }, { 0x1b, 15 }, + { 0x1a, 15 }, { 0x19, 15 }, { 0x13, 16 }, { 0x12, 16 }, + { 0x11, 16 }, { 0x10, 16 }, { 0x5, 4 }, { 0x4, 7 }, + { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, { 0x7, 5 }, + { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, { 0x6, 5 }, + { 0xf, 10 }, { 0x12, 12 }, { 0x7, 6 }, { 0x9, 10 }, + { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, { 0x14, 16 }, + { 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12 }, + { 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 }, + { 0x23, 8 }, { 0x1a, 16 }, { 0x22, 8 }, { 0x19, 16 }, + { 0x20, 8 }, { 0x18, 16 }, { 0xe, 10 }, { 0x17, 16 }, + { 0xd, 10 }, { 0x16, 16 }, { 0x8, 10 }, { 0x15, 16 }, + { 0x1f, 12 }, { 0x1a, 12 }, { 0x19, 12 }, { 0x17, 12 }, + { 0x16, 12 }, { 0x1f, 13 }, { 0x1e, 13 }, { 0x1d, 13 }, + { 0x1c, 13 }, { 0x1b, 13 }, { 0x1f, 16 }, { 0x1e, 16 }, + { 0x1d, 16 }, { 0x1c, 16 }, { 0x1b, 16 }, + { 0x1, 6 }, /* escape */ + { 0x2, 2 }, /* EOB */ +}; + +static const uint16_t mpeg2_vlc[113][2] = { + {0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5}, + {0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7}, + {0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8}, + {0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14}, + {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14}, + {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14}, + {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14}, + {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15}, + {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15}, + {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15}, + {0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8}, + {0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15}, + {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15}, + {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16}, + {0x11,16}, {0x10,16}, {0x05, 5}, {0x07, 7}, + {0xfc, 8}, {0x0c,10}, {0x14,13}, {0x07, 5}, + {0x26, 8}, {0x1c,12}, {0x13,13}, {0x06, 6}, + {0xfd, 8}, {0x12,12}, {0x07, 6}, {0x04, 9}, + {0x12,13}, {0x06, 7}, {0x1e,12}, {0x14,16}, + {0x04, 7}, {0x15,12}, {0x05, 7}, {0x11,12}, + {0x78, 7}, {0x11,13}, {0x7a, 7}, {0x10,13}, + {0x21, 8}, {0x1a,16}, {0x25, 8}, {0x19,16}, + {0x24, 8}, {0x18,16}, {0x05, 9}, {0x17,16}, + {0x07, 9}, {0x16,16}, {0x0d,10}, {0x15,16}, + {0x1f,12}, {0x1a,12}, {0x19,12}, {0x17,12}, + {0x16,12}, {0x1f,13}, {0x1e,13}, {0x1d,13}, + {0x1c,13}, {0x1b,13}, {0x1f,16}, {0x1e,16}, + {0x1d,16}, {0x1c,16}, {0x1b,16}, + {0x01,6}, /* escape */ + {0x06,4}, /* EOB */ +}; + +static const int8_t mpeg1_level[111] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 1, 2, 3, 4, 5, 1, + 2, 3, 4, 1, 2, 3, 1, 2, + 3, 1, 2, 3, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, +}; + +static const int8_t mpeg1_run[111] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 3, + 3, 3, 3, 4, 4, 4, 5, 5, + 5, 6, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, + 13, 13, 14, 14, 15, 15, 16, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, +}; + +RLTable ff_rl_mpeg1 = { + 111, + 111, + mpeg1_vlc, + mpeg1_run, + mpeg1_level, +}; + +RLTable ff_rl_mpeg2 = { + 111, + 111, + mpeg2_vlc, + mpeg1_run, + mpeg1_level, +}; + +const uint8_t ff_mpeg12_mbAddrIncrTable[36][2] = { + {0x1, 1}, + {0x3, 3}, + {0x2, 3}, + {0x3, 4}, + {0x2, 4}, + {0x3, 5}, + {0x2, 5}, + {0x7, 7}, + {0x6, 7}, + {0xb, 8}, + {0xa, 8}, + {0x9, 8}, + {0x8, 8}, + {0x7, 8}, + {0x6, 8}, + {0x17, 10}, + {0x16, 10}, + {0x15, 10}, + {0x14, 10}, + {0x13, 10}, + {0x12, 10}, + {0x23, 11}, + {0x22, 11}, + {0x21, 11}, + {0x20, 11}, + {0x1f, 11}, + {0x1e, 11}, + {0x1d, 11}, + {0x1c, 11}, + {0x1b, 11}, + {0x1a, 11}, + {0x19, 11}, + {0x18, 11}, + {0x8, 11}, /* escape */ + {0xf, 11}, /* stuffing */ + {0x0, 8}, /* end (and 15 more 0 bits should follow) */ +}; + +const uint8_t ff_mpeg12_mbPatTable[64][2] = { + {0x1, 9}, + {0xb, 5}, + {0x9, 5}, + {0xd, 6}, + {0xd, 4}, + {0x17, 7}, + {0x13, 7}, + {0x1f, 8}, + {0xc, 4}, + {0x16, 7}, + {0x12, 7}, + {0x1e, 8}, + {0x13, 5}, + {0x1b, 8}, + {0x17, 8}, + {0x13, 8}, + {0xb, 4}, + {0x15, 7}, + {0x11, 7}, + {0x1d, 8}, + {0x11, 5}, + {0x19, 8}, + {0x15, 8}, + {0x11, 8}, + {0xf, 6}, + {0xf, 8}, + {0xd, 8}, + {0x3, 9}, + {0xf, 5}, + {0xb, 8}, + {0x7, 8}, + {0x7, 9}, + {0xa, 4}, + {0x14, 7}, + {0x10, 7}, + {0x1c, 8}, + {0xe, 6}, + {0xe, 8}, + {0xc, 8}, + {0x2, 9}, + {0x10, 5}, + {0x18, 8}, + {0x14, 8}, + {0x10, 8}, + {0xe, 5}, + {0xa, 8}, + {0x6, 8}, + {0x6, 9}, + {0x12, 5}, + {0x1a, 8}, + {0x16, 8}, + {0x12, 8}, + {0xd, 5}, + {0x9, 8}, + {0x5, 8}, + {0x5, 9}, + {0xc, 5}, + {0x8, 8}, + {0x4, 8}, + {0x4, 9}, + {0x7, 3}, + {0xa, 5}, + {0x8, 5}, + {0xc, 6} +}; + +const uint8_t ff_mpeg12_mbMotionVectorTable[17][2] = { +{ 0x1, 1 }, +{ 0x1, 2 }, +{ 0x1, 3 }, +{ 0x1, 4 }, +{ 0x3, 6 }, +{ 0x5, 7 }, +{ 0x4, 7 }, +{ 0x3, 7 }, +{ 0xb, 9 }, +{ 0xa, 9 }, +{ 0x9, 9 }, +{ 0x11, 10 }, +{ 0x10, 10 }, +{ 0xf, 10 }, +{ 0xe, 10 }, +{ 0xd, 10 }, +{ 0xc, 10 }, +}; + +const AVRational ff_frame_rate_tab[] = { + { 0, 0}, + {24000, 1001}, + { 24, 1}, + { 25, 1}, + {30000, 1001}, + { 30, 1}, + { 50, 1}, + {60000, 1001}, + { 60, 1}, + // Xing's 15fps: (9) + { 15, 1}, + // libmpeg3's "Unofficial economy rates": (10-13) + { 5, 1}, + { 10, 1}, + { 12, 1}, + { 15, 1}, + { 0, 0}, +}; + +const uint8_t ff_mpeg1_dc_scale_table[128]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +}; + +const float ff_mpeg1_aspect[16]={ + 0.0000, + 1.0000, + 0.6735, + 0.7031, + + 0.7615, + 0.8055, + 0.8437, + 0.8935, + + 0.9157, + 0.9815, + 1.0255, + 1.0695, + + 1.0950, + 1.1575, + 1.2015, +}; + +const AVRational ff_mpeg2_aspect[16]={ + {0,1}, + {1,1}, + {4,3}, + {16,9}, + {221,100}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, + {0,1}, +}; diff --git a/contrib/ffmpeg/libavcodec/mpeg12data.h b/contrib/ffmpeg/libavcodec/mpeg12data.h index 1176a75fa..190817f64 100644 --- a/contrib/ffmpeg/libavcodec/mpeg12data.h +++ b/contrib/ffmpeg/libavcodec/mpeg12data.h @@ -1,5 +1,5 @@ /* - * MPEG1 codec / MPEG2 decoder + * MPEG1/2 tables * copyright (c) 2000,2001 Fabrice Bellard * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * @@ -25,450 +25,26 @@ * MPEG1/2 tables. */ -const uint16_t ff_mpeg1_default_intra_matrix[64] = { - 8, 16, 19, 22, 26, 27, 29, 34, - 16, 16, 22, 24, 27, 29, 34, 37, - 19, 22, 26, 27, 29, 34, 34, 38, - 22, 22, 26, 27, 29, 34, 37, 40, - 22, 26, 27, 29, 32, 35, 40, 48, - 26, 27, 29, 32, 35, 40, 48, 58, - 26, 27, 29, 34, 38, 46, 56, 69, - 27, 29, 35, 38, 46, 56, 69, 83 -}; +#ifndef FFMPEG_MPEG12DATA_H +#define FFMPEG_MPEG12DATA_H -const uint16_t ff_mpeg1_default_non_intra_matrix[64] = { - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, -}; +#include <stdint.h> +#include "mpegvideo.h" -static const uint16_t vlc_dc_lum_code[12] = { - 0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x1ff, -}; -static const unsigned char vlc_dc_lum_bits[12] = { - 3, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 9, -}; +extern const uint16_t ff_mpeg12_vlc_dc_lum_code[12]; +extern const unsigned char ff_mpeg12_vlc_dc_lum_bits[12]; +extern const uint16_t ff_mpeg12_vlc_dc_chroma_code[12]; +extern const unsigned char ff_mpeg12_vlc_dc_chroma_bits[12]; -static const uint16_t vlc_dc_chroma_code[12] = { - 0x0, 0x1, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe, 0x3fe, 0x3ff, -}; -static const unsigned char vlc_dc_chroma_bits[12] = { - 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, -}; +extern RLTable ff_rl_mpeg1; +extern RLTable ff_rl_mpeg2; -static const uint16_t mpeg1_vlc[113][2] = { - { 0x3, 2 }, { 0x4, 4 }, { 0x5, 5 }, { 0x6, 7 }, - { 0x26, 8 }, { 0x21, 8 }, { 0xa, 10 }, { 0x1d, 12 }, - { 0x18, 12 }, { 0x13, 12 }, { 0x10, 12 }, { 0x1a, 13 }, - { 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, { 0x1f, 14 }, - { 0x1e, 14 }, { 0x1d, 14 }, { 0x1c, 14 }, { 0x1b, 14 }, - { 0x1a, 14 }, { 0x19, 14 }, { 0x18, 14 }, { 0x17, 14 }, - { 0x16, 14 }, { 0x15, 14 }, { 0x14, 14 }, { 0x13, 14 }, - { 0x12, 14 }, { 0x11, 14 }, { 0x10, 14 }, { 0x18, 15 }, - { 0x17, 15 }, { 0x16, 15 }, { 0x15, 15 }, { 0x14, 15 }, - { 0x13, 15 }, { 0x12, 15 }, { 0x11, 15 }, { 0x10, 15 }, - { 0x3, 3 }, { 0x6, 6 }, { 0x25, 8 }, { 0xc, 10 }, - { 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x1f, 15 }, - { 0x1e, 15 }, { 0x1d, 15 }, { 0x1c, 15 }, { 0x1b, 15 }, - { 0x1a, 15 }, { 0x19, 15 }, { 0x13, 16 }, { 0x12, 16 }, - { 0x11, 16 }, { 0x10, 16 }, { 0x5, 4 }, { 0x4, 7 }, - { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, { 0x7, 5 }, - { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, { 0x6, 5 }, - { 0xf, 10 }, { 0x12, 12 }, { 0x7, 6 }, { 0x9, 10 }, - { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, { 0x14, 16 }, - { 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12 }, - { 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 }, - { 0x23, 8 }, { 0x1a, 16 }, { 0x22, 8 }, { 0x19, 16 }, - { 0x20, 8 }, { 0x18, 16 }, { 0xe, 10 }, { 0x17, 16 }, - { 0xd, 10 }, { 0x16, 16 }, { 0x8, 10 }, { 0x15, 16 }, - { 0x1f, 12 }, { 0x1a, 12 }, { 0x19, 12 }, { 0x17, 12 }, - { 0x16, 12 }, { 0x1f, 13 }, { 0x1e, 13 }, { 0x1d, 13 }, - { 0x1c, 13 }, { 0x1b, 13 }, { 0x1f, 16 }, { 0x1e, 16 }, - { 0x1d, 16 }, { 0x1c, 16 }, { 0x1b, 16 }, - { 0x1, 6 }, /* escape */ - { 0x2, 2 }, /* EOB */ -}; +extern const uint8_t ff_mpeg12_mbAddrIncrTable[36][2]; +extern const uint8_t ff_mpeg12_mbPatTable[64][2]; -static const uint16_t mpeg2_vlc[113][2] = { - {0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5}, - {0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7}, - {0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8}, - {0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14}, - {0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14}, - {0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14}, - {0x16,14}, {0x15,14}, {0x14,14}, {0x13,14}, - {0x12,14}, {0x11,14}, {0x10,14}, {0x18,15}, - {0x17,15}, {0x16,15}, {0x15,15}, {0x14,15}, - {0x13,15}, {0x12,15}, {0x11,15}, {0x10,15}, - {0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8}, - {0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15}, - {0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15}, - {0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16}, - {0x11,16}, {0x10,16}, {0x05, 5}, {0x07, 7}, - {0xfc, 8}, {0x0c,10}, {0x14,13}, {0x07, 5}, - {0x26, 8}, {0x1c,12}, {0x13,13}, {0x06, 6}, - {0xfd, 8}, {0x12,12}, {0x07, 6}, {0x04, 9}, - {0x12,13}, {0x06, 7}, {0x1e,12}, {0x14,16}, - {0x04, 7}, {0x15,12}, {0x05, 7}, {0x11,12}, - {0x78, 7}, {0x11,13}, {0x7a, 7}, {0x10,13}, - {0x21, 8}, {0x1a,16}, {0x25, 8}, {0x19,16}, - {0x24, 8}, {0x18,16}, {0x05, 9}, {0x17,16}, - {0x07, 9}, {0x16,16}, {0x0d,10}, {0x15,16}, - {0x1f,12}, {0x1a,12}, {0x19,12}, {0x17,12}, - {0x16,12}, {0x1f,13}, {0x1e,13}, {0x1d,13}, - {0x1c,13}, {0x1b,13}, {0x1f,16}, {0x1e,16}, - {0x1d,16}, {0x1c,16}, {0x1b,16}, - {0x01,6}, /* escape */ - {0x06,4}, /* EOB */ -}; +extern const uint8_t ff_mpeg12_mbMotionVectorTable[17][2]; -static const int8_t mpeg1_level[111] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 1, 2, 3, 4, 5, 1, - 2, 3, 4, 1, 2, 3, 1, 2, - 3, 1, 2, 3, 1, 2, 1, 2, - 1, 2, 1, 2, 1, 2, 1, 2, - 1, 2, 1, 2, 1, 2, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, -}; +extern const float ff_mpeg1_aspect[16]; +extern const AVRational ff_mpeg2_aspect[16]; -static const int8_t mpeg1_run[111] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 2, 3, - 3, 3, 3, 4, 4, 4, 5, 5, - 5, 6, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, - 13, 13, 14, 14, 15, 15, 16, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, -}; - -static RLTable rl_mpeg1 = { - 111, - 111, - mpeg1_vlc, - mpeg1_run, - mpeg1_level, -}; - -static RLTable rl_mpeg2 = { - 111, - 111, - mpeg2_vlc, - mpeg1_run, - mpeg1_level, -}; - -static const uint8_t mbAddrIncrTable[36][2] = { - {0x1, 1}, - {0x3, 3}, - {0x2, 3}, - {0x3, 4}, - {0x2, 4}, - {0x3, 5}, - {0x2, 5}, - {0x7, 7}, - {0x6, 7}, - {0xb, 8}, - {0xa, 8}, - {0x9, 8}, - {0x8, 8}, - {0x7, 8}, - {0x6, 8}, - {0x17, 10}, - {0x16, 10}, - {0x15, 10}, - {0x14, 10}, - {0x13, 10}, - {0x12, 10}, - {0x23, 11}, - {0x22, 11}, - {0x21, 11}, - {0x20, 11}, - {0x1f, 11}, - {0x1e, 11}, - {0x1d, 11}, - {0x1c, 11}, - {0x1b, 11}, - {0x1a, 11}, - {0x19, 11}, - {0x18, 11}, - {0x8, 11}, /* escape */ - {0xf, 11}, /* stuffing */ - {0x0, 8}, /* end (and 15 more 0 bits should follow) */ -}; - -static const uint8_t mbPatTable[64][2] = { - {0x1, 9}, - {0xb, 5}, - {0x9, 5}, - {0xd, 6}, - {0xd, 4}, - {0x17, 7}, - {0x13, 7}, - {0x1f, 8}, - {0xc, 4}, - {0x16, 7}, - {0x12, 7}, - {0x1e, 8}, - {0x13, 5}, - {0x1b, 8}, - {0x17, 8}, - {0x13, 8}, - {0xb, 4}, - {0x15, 7}, - {0x11, 7}, - {0x1d, 8}, - {0x11, 5}, - {0x19, 8}, - {0x15, 8}, - {0x11, 8}, - {0xf, 6}, - {0xf, 8}, - {0xd, 8}, - {0x3, 9}, - {0xf, 5}, - {0xb, 8}, - {0x7, 8}, - {0x7, 9}, - {0xa, 4}, - {0x14, 7}, - {0x10, 7}, - {0x1c, 8}, - {0xe, 6}, - {0xe, 8}, - {0xc, 8}, - {0x2, 9}, - {0x10, 5}, - {0x18, 8}, - {0x14, 8}, - {0x10, 8}, - {0xe, 5}, - {0xa, 8}, - {0x6, 8}, - {0x6, 9}, - {0x12, 5}, - {0x1a, 8}, - {0x16, 8}, - {0x12, 8}, - {0xd, 5}, - {0x9, 8}, - {0x5, 8}, - {0x5, 9}, - {0xc, 5}, - {0x8, 8}, - {0x4, 8}, - {0x4, 9}, - {0x7, 3}, - {0xa, 5}, - {0x8, 5}, - {0xc, 6} -}; - -#define MB_TYPE_ZERO_MV 0x20000000 -#define IS_ZERO_MV(a) ((a)&MB_TYPE_ZERO_MV) - -static const uint8_t table_mb_ptype[7][2] = { - { 3, 5 }, // 0x01 MB_INTRA - { 1, 2 }, // 0x02 MB_PAT - { 1, 3 }, // 0x08 MB_FOR - { 1, 1 }, // 0x0A MB_FOR|MB_PAT - { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA - { 1, 5 }, // 0x12 MB_QUANT|MB_PAT - { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT -}; - -static const uint32_t ptype2mb_type[7] = { - MB_TYPE_INTRA, - MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16, - MB_TYPE_L0, - MB_TYPE_L0 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_INTRA, - MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16, - MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP, -}; - -static const uint8_t table_mb_btype[11][2] = { - { 3, 5 }, // 0x01 MB_INTRA - { 2, 3 }, // 0x04 MB_BACK - { 3, 3 }, // 0x06 MB_BACK|MB_PAT - { 2, 4 }, // 0x08 MB_FOR - { 3, 4 }, // 0x0A MB_FOR|MB_PAT - { 2, 2 }, // 0x0C MB_FOR|MB_BACK - { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT - { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA - { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT - { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT - { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT -}; - -static const uint32_t btype2mb_type[11] = { - MB_TYPE_INTRA, - MB_TYPE_L1, - MB_TYPE_L1 | MB_TYPE_CBP, - MB_TYPE_L0, - MB_TYPE_L0 | MB_TYPE_CBP, - MB_TYPE_L0L1, - MB_TYPE_L0L1 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_INTRA, - MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP, - MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP, -}; - -static const uint8_t mbMotionVectorTable[17][2] = { -{ 0x1, 1 }, -{ 0x1, 2 }, -{ 0x1, 3 }, -{ 0x1, 4 }, -{ 0x3, 6 }, -{ 0x5, 7 }, -{ 0x4, 7 }, -{ 0x3, 7 }, -{ 0xb, 9 }, -{ 0xa, 9 }, -{ 0x9, 9 }, -{ 0x11, 10 }, -{ 0x10, 10 }, -{ 0xf, 10 }, -{ 0xe, 10 }, -{ 0xd, 10 }, -{ 0xc, 10 }, -}; - -const AVRational ff_frame_rate_tab[] = { - { 0, 0}, - {24000, 1001}, - { 24, 1}, - { 25, 1}, - {30000, 1001}, - { 30, 1}, - { 50, 1}, - {60000, 1001}, - { 60, 1}, - // Xing's 15fps: (9) - { 15, 1}, - // libmpeg3's "Unofficial economy rates": (10-13) - { 5, 1}, - { 10, 1}, - { 12, 1}, - { 15, 1}, - { 0, 0}, -}; - -static const uint8_t non_linear_qscale[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8,10,12,14,16,18,20,22, - 24,28,32,36,40,44,48,52, - 56,64,72,80,88,96,104,112, -}; - -static const uint8_t inv_non_linear_qscale[13] = { - 0, 2, 4, 6, 8, - 9,10,11,12,13,14,15,16, -}; - -const uint8_t ff_mpeg1_dc_scale_table[128]={ -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -}; - -static const uint8_t mpeg2_dc_scale_table1[128]={ -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, -}; - -static const uint8_t mpeg2_dc_scale_table2[128]={ -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -}; - -static const uint8_t mpeg2_dc_scale_table3[128]={ -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const uint8_t *mpeg2_dc_scale_table[4]={ - ff_mpeg1_dc_scale_table, - mpeg2_dc_scale_table1, - mpeg2_dc_scale_table2, - mpeg2_dc_scale_table3, -}; - -static const float mpeg1_aspect[16]={ - 0.0000, - 1.0000, - 0.6735, - 0.7031, - - 0.7615, - 0.8055, - 0.8437, - 0.8935, - - 0.9157, - 0.9815, - 1.0255, - 1.0695, - - 1.0950, - 1.1575, - 1.2015, -}; - -static const AVRational mpeg2_aspect[16]={ - {0,1}, - {1,1}, - {4,3}, - {16,9}, - {221,100}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, -}; - -static const uint8_t svcd_scan_offset_placeholder[14]={ - 0x10, 0x0E, - 0x00, 0x80, 0x81, - 0x00, 0x80, 0x81, - 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, -}; +#endif /* FFMPEG_MPEG12DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/mpeg12decdata.h b/contrib/ffmpeg/libavcodec/mpeg12decdata.h new file mode 100644 index 000000000..52816d416 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpeg12decdata.h @@ -0,0 +1,124 @@ +/* + * MPEG1/2 decoder tables + * copyright (c) 2000,2001 Fabrice Bellard + * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 mpeg12decdata.h + * MPEG1/2 decoder tables. + */ + +#ifndef FFMPEG_MPEG12DECDATA_H +#define FFMPEG_MPEG12DECDATA_H + +#include <stdint.h> +#include "mpegvideo.h" + + +#define MB_TYPE_ZERO_MV 0x20000000 +#define IS_ZERO_MV(a) ((a)&MB_TYPE_ZERO_MV) + +static const uint8_t table_mb_ptype[7][2] = { + { 3, 5 }, // 0x01 MB_INTRA + { 1, 2 }, // 0x02 MB_PAT + { 1, 3 }, // 0x08 MB_FOR + { 1, 1 }, // 0x0A MB_FOR|MB_PAT + { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA + { 1, 5 }, // 0x12 MB_QUANT|MB_PAT + { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT +}; + +static const uint32_t ptype2mb_type[7] = { + MB_TYPE_INTRA, + MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16, + MB_TYPE_L0, + MB_TYPE_L0 | MB_TYPE_CBP, + MB_TYPE_QUANT | MB_TYPE_INTRA, + MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16, + MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP, +}; + +static const uint8_t table_mb_btype[11][2] = { + { 3, 5 }, // 0x01 MB_INTRA + { 2, 3 }, // 0x04 MB_BACK + { 3, 3 }, // 0x06 MB_BACK|MB_PAT + { 2, 4 }, // 0x08 MB_FOR + { 3, 4 }, // 0x0A MB_FOR|MB_PAT + { 2, 2 }, // 0x0C MB_FOR|MB_BACK + { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT + { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA + { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT + { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT + { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT +}; + +static const uint32_t btype2mb_type[11] = { + MB_TYPE_INTRA, + MB_TYPE_L1, + MB_TYPE_L1 | MB_TYPE_CBP, + MB_TYPE_L0, + MB_TYPE_L0 | MB_TYPE_CBP, + MB_TYPE_L0L1, + MB_TYPE_L0L1 | MB_TYPE_CBP, + MB_TYPE_QUANT | MB_TYPE_INTRA, + MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_CBP, + MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP, + MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP, +}; + +static const uint8_t non_linear_qscale[32] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8,10,12,14,16,18,20,22, + 24,28,32,36,40,44,48,52, + 56,64,72,80,88,96,104,112, +}; + +static const uint8_t mpeg2_dc_scale_table1[128]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +}; + +static const uint8_t mpeg2_dc_scale_table2[128]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +}; + +static const uint8_t mpeg2_dc_scale_table3[128]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const uint8_t *mpeg2_dc_scale_table[4]={ + ff_mpeg1_dc_scale_table, + mpeg2_dc_scale_table1, + mpeg2_dc_scale_table2, + mpeg2_dc_scale_table3, +}; + +#endif /* FFMPEG_MPEG12DECDATA_H */ diff --git a/contrib/ffmpeg/libavcodec/mpeg12enc.c b/contrib/ffmpeg/libavcodec/mpeg12enc.c new file mode 100644 index 000000000..aac90e04e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpeg12enc.c @@ -0,0 +1,954 @@ +/* + * MPEG1/2 encoder + * Copyright (c) 2000,2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 mpeg12enc.c + * MPEG1/2 encoder + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + +#include "mpeg12.h" +#include "mpeg12data.h" +#include "bytestream.h" + + +static const uint8_t inv_non_linear_qscale[13] = { + 0, 2, 4, 6, 8, + 9,10,11,12,13,14,15,16, +}; + +static const uint8_t svcd_scan_offset_placeholder[14] = { + 0x10, 0x0E, + 0x00, 0x80, 0x81, + 0x00, 0x80, 0x81, + 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, +}; + +static void mpeg1_encode_block(MpegEncContext *s, + DCTELEM *block, + int component); +static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code); // RAL: f_code parameter added + +static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; +static uint8_t fcode_tab[MAX_MV*2+1]; + +static uint8_t uni_mpeg1_ac_vlc_len [64*64*2]; +static uint8_t uni_mpeg2_ac_vlc_len [64*64*2]; + +/* simple include everything table for dc, first byte is bits number next 3 are code*/ +static uint32_t mpeg1_lum_dc_uni[512]; +static uint32_t mpeg1_chr_dc_uni[512]; + +static uint8_t mpeg1_index_run[2][64]; +static int8_t mpeg1_max_level[2][64]; + +static void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len){ + int i; + + for(i=0; i<128; i++){ + int level= i-64; + int run; + for(run=0; run<64; run++){ + int len, bits, code; + + int alevel= FFABS(level); + int sign= (level>>31)&1; + + if (alevel > rl->max_level[0][run]) + code= 111; /*rl->n*/ + else + code= rl->index_run[0][run] + alevel - 1; + + if (code < 111 /* rl->n */) { + /* store the vlc & sign at once */ + len= rl->table_vlc[code][1]+1; + bits= (rl->table_vlc[code][0]<<1) + sign; + } else { + len= rl->table_vlc[111/*rl->n*/][1]+6; + bits= rl->table_vlc[111/*rl->n*/][0]<<6; + + bits|= run; + if (alevel < 128) { + bits<<=8; len+=8; + bits|= level & 0xff; + } else { + bits<<=16; len+=16; + bits|= level & 0xff; + if (level < 0) { + bits|= 0x8001 + level + 255; + } else { + bits|= level & 0xffff; + } + } + } + + uni_ac_vlc_len [UNI_AC_ENC_INDEX(run, i)]= len; + } + } +} + + +static int find_frame_rate_index(MpegEncContext *s){ + int i; + int64_t dmin= INT64_MAX; + int64_t d; + + for(i=1;i<14;i++) { + int64_t n0= 1001LL/ff_frame_rate_tab[i].den*ff_frame_rate_tab[i].num*s->avctx->time_base.num; + int64_t n1= 1001LL*s->avctx->time_base.den; + if(s->avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL && i>=9) break; + + d = FFABS(n0 - n1); + if(d < dmin){ + dmin=d; + s->frame_rate_index= i; + } + } + if(dmin) + return -1; + else + return 0; +} + +static int encode_init(AVCodecContext *avctx) +{ + MpegEncContext *s = avctx->priv_data; + + if(MPV_encode_init(avctx) < 0) + return -1; + + if(find_frame_rate_index(s) < 0){ + if(s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ + av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->time_base.den, avctx->time_base.num); + return -1; + }else{ + av_log(avctx, AV_LOG_INFO, "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n", avctx->time_base.den, avctx->time_base.num); + } + } + + if(avctx->profile == FF_PROFILE_UNKNOWN){ + if(avctx->level != FF_LEVEL_UNKNOWN){ + av_log(avctx, AV_LOG_ERROR, "Set profile and level\n"); + return -1; + } + avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; /* Main or 4:2:2 */ + } + + if(avctx->level == FF_LEVEL_UNKNOWN){ + if(avctx->profile == 0){ /* 4:2:2 */ + if(avctx->width <= 720 && avctx->height <= 608) avctx->level = 5; /* Main */ + else avctx->level = 2; /* High */ + }else{ + if(avctx->profile != 1 && s->chroma_format != CHROMA_420){ + av_log(avctx, AV_LOG_ERROR, "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n"); + return -1; + } + if(avctx->width <= 720 && avctx->height <= 576) avctx->level = 8; /* Main */ + else if(avctx->width <= 1440) avctx->level = 6; /* High 1440 */ + else avctx->level = 4; /* High */ + } + } + + if((avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) && s->frame_rate_index != 4){ + av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n"); + return -1; + } + + return 0; +} + +static void put_header(MpegEncContext *s, int header) +{ + align_put_bits(&s->pb); + put_bits(&s->pb, 16, header>>16); + put_bits(&s->pb, 16, header&0xFFFF); +} + +/* put sequence header if needed */ +static void mpeg1_encode_sequence_header(MpegEncContext *s) +{ + unsigned int vbv_buffer_size; + unsigned int fps, v; + int i; + uint64_t time_code; + float best_aspect_error= 1E10; + float aspect_ratio= av_q2d(s->avctx->sample_aspect_ratio); + int constraint_parameter_flag; + + if(aspect_ratio==0.0) aspect_ratio= 1.0; //pixel aspect 1:1 (VGA) + + if (s->current_picture.key_frame) { + AVRational framerate= ff_frame_rate_tab[s->frame_rate_index]; + + /* mpeg1 header repeated every gop */ + put_header(s, SEQ_START_CODE); + + put_bits(&s->pb, 12, s->width); + put_bits(&s->pb, 12, s->height); + + for(i=1; i<15; i++){ + float error= aspect_ratio; + if(s->codec_id == CODEC_ID_MPEG1VIDEO || i <=1) + error-= 1.0/ff_mpeg1_aspect[i]; + else + error-= av_q2d(ff_mpeg2_aspect[i])*s->height/s->width; + + error= FFABS(error); + + if(error < best_aspect_error){ + best_aspect_error= error; + s->aspect_ratio_info= i; + } + } + + put_bits(&s->pb, 4, s->aspect_ratio_info); + put_bits(&s->pb, 4, s->frame_rate_index); + + if(s->avctx->rc_max_rate){ + v = (s->avctx->rc_max_rate + 399) / 400; + if (v > 0x3ffff && s->codec_id == CODEC_ID_MPEG1VIDEO) + v = 0x3ffff; + }else{ + v= 0x3FFFF; + } + + if(s->avctx->rc_buffer_size) + vbv_buffer_size = s->avctx->rc_buffer_size; + else + /* VBV calculation: Scaled so that a VCD has the proper VBV size of 40 kilobytes */ + vbv_buffer_size = (( 20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024; + vbv_buffer_size= (vbv_buffer_size + 16383) / 16384; + + put_bits(&s->pb, 18, v & 0x3FFFF); + put_bits(&s->pb, 1, 1); /* marker */ + put_bits(&s->pb, 10, vbv_buffer_size & 0x3FF); + + constraint_parameter_flag= + s->width <= 768 && s->height <= 576 && + s->mb_width * s->mb_height <= 396 && + s->mb_width * s->mb_height * framerate.num <= framerate.den*396*25 && + framerate.num <= framerate.den*30 && + s->avctx->me_range && s->avctx->me_range < 128 && + vbv_buffer_size <= 20 && + v <= 1856000/400 && + s->codec_id == CODEC_ID_MPEG1VIDEO; + + put_bits(&s->pb, 1, constraint_parameter_flag); + + ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); + ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); + + if(s->codec_id == CODEC_ID_MPEG2VIDEO){ + put_header(s, EXT_START_CODE); + put_bits(&s->pb, 4, 1); //seq ext + + put_bits(&s->pb, 1, s->avctx->profile == 0); //escx 1 for 4:2:2 profile */ + + put_bits(&s->pb, 3, s->avctx->profile); //profile + put_bits(&s->pb, 4, s->avctx->level); //level + + put_bits(&s->pb, 1, s->progressive_sequence); + put_bits(&s->pb, 2, s->chroma_format); + put_bits(&s->pb, 2, 0); //horizontal size ext + put_bits(&s->pb, 2, 0); //vertical size ext + put_bits(&s->pb, 12, v>>18); //bitrate ext + put_bits(&s->pb, 1, 1); //marker + put_bits(&s->pb, 8, vbv_buffer_size >>10); //vbv buffer ext + put_bits(&s->pb, 1, s->low_delay); + put_bits(&s->pb, 2, 0); // frame_rate_ext_n + put_bits(&s->pb, 5, 0); // frame_rate_ext_d + } + + put_header(s, GOP_START_CODE); + put_bits(&s->pb, 1, !!(s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE)); /* drop frame flag */ + /* time code : we must convert from the real frame rate to a + fake mpeg frame rate in case of low frame rate */ + fps = (framerate.num + framerate.den/2)/ framerate.den; + time_code = s->current_picture_ptr->coded_picture_number + s->avctx->timecode_frame_start; + + s->gop_picture_number = s->current_picture_ptr->coded_picture_number; + if (s->avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE) { + /* only works for NTSC 29.97 */ + int d = time_code / 17982; + int m = time_code % 17982; + //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */ + time_code += 18 * d + 2 * ((m - 2) / 1798); + } + put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); + put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60)); + put_bits(&s->pb, 6, (uint32_t)((time_code % fps))); + put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP)); + put_bits(&s->pb, 1, 0); /* broken link */ + } +} + +static inline void encode_mb_skip_run(MpegEncContext *s, int run){ + while (run >= 33) { + put_bits(&s->pb, 11, 0x008); + run -= 33; + } + put_bits(&s->pb, ff_mpeg12_mbAddrIncrTable[run][1], + ff_mpeg12_mbAddrIncrTable[run][0]); +} + +static av_always_inline void put_qscale(MpegEncContext *s) +{ + if(s->q_scale_type){ + assert(s->qscale>=1 && s->qscale <=12); + put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]); + }else{ + put_bits(&s->pb, 5, s->qscale); + } +} + +void ff_mpeg1_encode_slice_header(MpegEncContext *s){ + put_header(s, SLICE_MIN_START_CODE + s->mb_y); + put_qscale(s); + put_bits(&s->pb, 1, 0); /* slice extra information */ +} + +void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) +{ + mpeg1_encode_sequence_header(s); + + /* mpeg1 picture header */ + put_header(s, PICTURE_START_CODE); + /* temporal reference */ + + // RAL: s->picture_number instead of s->fake_picture_number + put_bits(&s->pb, 10, (s->picture_number - + s->gop_picture_number) & 0x3ff); + put_bits(&s->pb, 3, s->pict_type); + + s->vbv_delay_ptr= s->pb.buf + put_bits_count(&s->pb)/8; + put_bits(&s->pb, 16, 0xFFFF); /* vbv_delay */ + + // RAL: Forward f_code also needed for B frames + if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { + put_bits(&s->pb, 1, 0); /* half pel coordinates */ + if(s->codec_id == CODEC_ID_MPEG1VIDEO) + put_bits(&s->pb, 3, s->f_code); /* forward_f_code */ + else + put_bits(&s->pb, 3, 7); /* forward_f_code */ + } + + // RAL: Backward f_code necessary for B frames + if (s->pict_type == B_TYPE) { + put_bits(&s->pb, 1, 0); /* half pel coordinates */ + if(s->codec_id == CODEC_ID_MPEG1VIDEO) + put_bits(&s->pb, 3, s->b_code); /* backward_f_code */ + else + put_bits(&s->pb, 3, 7); /* backward_f_code */ + } + + put_bits(&s->pb, 1, 0); /* extra bit picture */ + + s->frame_pred_frame_dct = 1; + if(s->codec_id == CODEC_ID_MPEG2VIDEO){ + put_header(s, EXT_START_CODE); + put_bits(&s->pb, 4, 8); //pic ext + if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { + put_bits(&s->pb, 4, s->f_code); + put_bits(&s->pb, 4, s->f_code); + }else{ + put_bits(&s->pb, 8, 255); + } + if (s->pict_type == B_TYPE) { + put_bits(&s->pb, 4, s->b_code); + put_bits(&s->pb, 4, s->b_code); + }else{ + put_bits(&s->pb, 8, 255); + } + put_bits(&s->pb, 2, s->intra_dc_precision); + + assert(s->picture_structure == PICT_FRAME); + put_bits(&s->pb, 2, s->picture_structure); + if (s->progressive_sequence) { + put_bits(&s->pb, 1, 0); /* no repeat */ + } else { + put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first); + } + /* XXX: optimize the generation of this flag with entropy + measures */ + s->frame_pred_frame_dct = s->progressive_sequence; + + put_bits(&s->pb, 1, s->frame_pred_frame_dct); + put_bits(&s->pb, 1, s->concealment_motion_vectors); + put_bits(&s->pb, 1, s->q_scale_type); + put_bits(&s->pb, 1, s->intra_vlc_format); + put_bits(&s->pb, 1, s->alternate_scan); + put_bits(&s->pb, 1, s->repeat_first_field); + s->progressive_frame = s->progressive_sequence; + put_bits(&s->pb, 1, s->chroma_format == CHROMA_420 ? s->progressive_frame : 0); /* chroma_420_type */ + put_bits(&s->pb, 1, s->progressive_frame); + put_bits(&s->pb, 1, 0); //composite_display_flag + } + if(s->flags & CODEC_FLAG_SVCD_SCAN_OFFSET){ + int i; + + put_header(s, USER_START_CODE); + for(i=0; i<sizeof(svcd_scan_offset_placeholder); i++){ + put_bits(&s->pb, 8, svcd_scan_offset_placeholder[i]); + } + } + + s->mb_y=0; + ff_mpeg1_encode_slice_header(s); +} + +static inline void put_mb_modes(MpegEncContext *s, int n, int bits, + int has_mv, int field_motion) +{ + put_bits(&s->pb, n, bits); + if (!s->frame_pred_frame_dct) { + if (has_mv) + put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */ + put_bits(&s->pb, 1, s->interlaced_dct); + } +} + +static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, + DCTELEM block[6][64], + int motion_x, int motion_y, + int mb_block_count) +{ + int i, cbp; + const int mb_x = s->mb_x; + const int mb_y = s->mb_y; + const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y; + + /* compute cbp */ + cbp = 0; + for(i=0;i<mb_block_count;i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (mb_block_count - 1 - i); + } + + if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 && + (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) && + ((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) || + (s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | + ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { + s->mb_skip_run++; + s->qscale -= s->dquant; + s->skip_count++; + s->misc_bits++; + s->last_bits++; + if(s->pict_type == P_TYPE){ + s->last_mv[0][1][0]= s->last_mv[0][0][0]= + s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0; + } + } else { + if(first_mb){ + assert(s->mb_skip_run == 0); + encode_mb_skip_run(s, s->mb_x); + }else{ + encode_mb_skip_run(s, s->mb_skip_run); + } + + if (s->pict_type == I_TYPE) { + if(s->dquant && cbp){ + put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */ + put_qscale(s); + }else{ + put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */ + s->qscale -= s->dquant; + } + s->misc_bits+= get_bits_diff(s); + s->i_count++; + } else if (s->mb_intra) { + if(s->dquant && cbp){ + put_mb_modes(s, 6, 0x01, 0, 0); + put_qscale(s); + }else{ + put_mb_modes(s, 5, 0x03, 0, 0); + s->qscale -= s->dquant; + } + s->misc_bits+= get_bits_diff(s); + s->i_count++; + memset(s->last_mv, 0, sizeof(s->last_mv)); + } else if (s->pict_type == P_TYPE) { + if(s->mv_type == MV_TYPE_16X16){ + if (cbp != 0) { + if ((motion_x|motion_y) == 0) { + if(s->dquant){ + put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */ + put_qscale(s); + }else{ + put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */ + } + s->misc_bits+= get_bits_diff(s); + } else { + if(s->dquant){ + put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */ + put_qscale(s); + }else{ + put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */ + } + s->misc_bits+= get_bits_diff(s); + mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added + mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added + s->mv_bits+= get_bits_diff(s); + } + } else { + put_bits(&s->pb, 3, 1); /* motion only */ + if (!s->frame_pred_frame_dct) + put_bits(&s->pb, 2, 2); /* motion_type: frame */ + s->misc_bits+= get_bits_diff(s); + mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added + mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added + s->qscale -= s->dquant; + s->mv_bits+= get_bits_diff(s); + } + s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x; + s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y; + }else{ + assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD); + + if (cbp) { + if(s->dquant){ + put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */ + put_qscale(s); + }else{ + put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */ + } + } else { + put_bits(&s->pb, 3, 1); /* motion only */ + put_bits(&s->pb, 2, 1); /* motion_type: field */ + s->qscale -= s->dquant; + } + s->misc_bits+= get_bits_diff(s); + for(i=0; i<2; i++){ + put_bits(&s->pb, 1, s->field_select[0][i]); + mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); + mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); + s->last_mv[0][i][0]= s->mv[0][i][0]; + s->last_mv[0][i][1]= 2*s->mv[0][i][1]; + } + s->mv_bits+= get_bits_diff(s); + } + if(cbp) { + if (s->chroma_y_shift) { + put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]); + } else { + put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]); + put_bits(&s->pb, 2, cbp & 3); + } + } + s->f_count++; + } else{ + if(s->mv_type == MV_TYPE_16X16){ + if (cbp){ // With coded bloc pattern + if (s->dquant) { + if(s->mv_dir == MV_DIR_FORWARD) + put_mb_modes(s, 6, 3, 1, 0); + else + put_mb_modes(s, 8-s->mv_dir, 2, 1, 0); + put_qscale(s); + } else { + put_mb_modes(s, 5-s->mv_dir, 3, 1, 0); + } + }else{ // No coded bloc pattern + put_bits(&s->pb, 5-s->mv_dir, 2); + if (!s->frame_pred_frame_dct) + put_bits(&s->pb, 2, 2); /* motion_type: frame */ + s->qscale -= s->dquant; + } + s->misc_bits += get_bits_diff(s); + if (s->mv_dir&MV_DIR_FORWARD){ + mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); + mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); + s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0]; + s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1]; + s->f_count++; + } + if (s->mv_dir&MV_DIR_BACKWARD){ + mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); + mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); + s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0]; + s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1]; + s->b_count++; + } + }else{ + assert(s->mv_type == MV_TYPE_FIELD); + assert(!s->frame_pred_frame_dct); + if (cbp){ // With coded bloc pattern + if (s->dquant) { + if(s->mv_dir == MV_DIR_FORWARD) + put_mb_modes(s, 6, 3, 1, 1); + else + put_mb_modes(s, 8-s->mv_dir, 2, 1, 1); + put_qscale(s); + } else { + put_mb_modes(s, 5-s->mv_dir, 3, 1, 1); + } + }else{ // No coded bloc pattern + put_bits(&s->pb, 5-s->mv_dir, 2); + put_bits(&s->pb, 2, 1); /* motion_type: field */ + s->qscale -= s->dquant; + } + s->misc_bits += get_bits_diff(s); + if (s->mv_dir&MV_DIR_FORWARD){ + for(i=0; i<2; i++){ + put_bits(&s->pb, 1, s->field_select[0][i]); + mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); + mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); + s->last_mv[0][i][0]= s->mv[0][i][0]; + s->last_mv[0][i][1]= 2*s->mv[0][i][1]; + } + s->f_count++; + } + if (s->mv_dir&MV_DIR_BACKWARD){ + for(i=0; i<2; i++){ + put_bits(&s->pb, 1, s->field_select[1][i]); + mpeg1_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code); + mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code); + s->last_mv[1][i][0]= s->mv[1][i][0]; + s->last_mv[1][i][1]= 2*s->mv[1][i][1]; + } + s->b_count++; + } + } + s->mv_bits += get_bits_diff(s); + if(cbp) { + if (s->chroma_y_shift) { + put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]); + } else { + put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]); + put_bits(&s->pb, 2, cbp & 3); + } + } + } + for(i=0;i<mb_block_count;i++) { + if (cbp & (1 << (mb_block_count - 1 - i))) { + mpeg1_encode_block(s, block[i], i); + } + } + s->mb_skip_run = 0; + if(s->mb_intra) + s->i_tex_bits+= get_bits_diff(s); + else + s->p_tex_bits+= get_bits_diff(s); + } +} + +void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y) +{ + if (s->chroma_format == CHROMA_420) mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6); + else mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8); +} + +// RAL: Parameter added: f_or_b_code +static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code) +{ + int code, bit_size, l, bits, range, sign; + + if (val == 0) { + /* zero vector */ + code = 0; + put_bits(&s->pb, + ff_mpeg12_mbMotionVectorTable[0][1], + ff_mpeg12_mbMotionVectorTable[0][0]); + } else { + bit_size = f_or_b_code - 1; + range = 1 << bit_size; + /* modulo encoding */ + l= INT_BIT - 5 - bit_size; + val= (val<<l)>>l; + + if (val >= 0) { + val--; + code = (val >> bit_size) + 1; + bits = val & (range - 1); + sign = 0; + } else { + val = -val; + val--; + code = (val >> bit_size) + 1; + bits = val & (range - 1); + sign = 1; + } + + assert(code > 0 && code <= 16); + + put_bits(&s->pb, + ff_mpeg12_mbMotionVectorTable[code][1], + ff_mpeg12_mbMotionVectorTable[code][0]); + + put_bits(&s->pb, 1, sign); + if (bit_size > 0) { + put_bits(&s->pb, bit_size, bits); + } + } +} + +void ff_mpeg1_encode_init(MpegEncContext *s) +{ + static int done=0; + + ff_mpeg12_common_init(s); + + if(!done){ + int f_code; + int mv; + int i; + + done=1; + init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); + init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); + + for(i=0; i<64; i++) + { + mpeg1_max_level[0][i]= ff_rl_mpeg1.max_level[0][i]; + mpeg1_index_run[0][i]= ff_rl_mpeg1.index_run[0][i]; + } + + init_uni_ac_vlc(&ff_rl_mpeg1, uni_mpeg1_ac_vlc_len); + if(s->intra_vlc_format) + init_uni_ac_vlc(&ff_rl_mpeg2, uni_mpeg2_ac_vlc_len); + + /* build unified dc encoding tables */ + for(i=-255; i<256; i++) + { + int adiff, index; + int bits, code; + int diff=i; + + adiff = FFABS(diff); + if(diff<0) diff--; + index = av_log2(2*adiff); + + bits= ff_mpeg12_vlc_dc_lum_bits[index] + index; + code= (ff_mpeg12_vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1)); + mpeg1_lum_dc_uni[i+255]= bits + (code<<8); + + bits= ff_mpeg12_vlc_dc_chroma_bits[index] + index; + code= (ff_mpeg12_vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1)); + mpeg1_chr_dc_uni[i+255]= bits + (code<<8); + } + + for(f_code=1; f_code<=MAX_FCODE; f_code++){ + for(mv=-MAX_MV; mv<=MAX_MV; mv++){ + int len; + + if(mv==0) len= ff_mpeg12_mbMotionVectorTable[0][1]; + else{ + int val, bit_size, range, code; + + bit_size = f_code - 1; + range = 1 << bit_size; + + val=mv; + if (val < 0) + val = -val; + val--; + code = (val >> bit_size) + 1; + if(code<17){ + len= ff_mpeg12_mbMotionVectorTable[code][1] + 1 + bit_size; + }else{ + len= ff_mpeg12_mbMotionVectorTable[16][1] + 2 + bit_size; + } + } + + mv_penalty[f_code][mv+MAX_MV]= len; + } + } + + + for(f_code=MAX_FCODE; f_code>0; f_code--){ + for(mv=-(8<<f_code); mv<(8<<f_code); mv++){ + fcode_tab[mv+MAX_MV]= f_code; + } + } + } + s->me.mv_penalty= mv_penalty; + s->fcode_tab= fcode_tab; + if(s->codec_id == CODEC_ID_MPEG1VIDEO){ + s->min_qcoeff=-255; + s->max_qcoeff= 255; + }else{ + s->min_qcoeff=-2047; + s->max_qcoeff= 2047; + } + if (s->intra_vlc_format) { + s->intra_ac_vlc_length= + s->intra_ac_vlc_last_length= uni_mpeg2_ac_vlc_len; + } else { + s->intra_ac_vlc_length= + s->intra_ac_vlc_last_length= uni_mpeg1_ac_vlc_len; + } + s->inter_ac_vlc_length= + s->inter_ac_vlc_last_length= uni_mpeg1_ac_vlc_len; +} + +static inline void encode_dc(MpegEncContext *s, int diff, int component) +{ + if(((unsigned) (diff+255)) >= 511){ + int index; + + if(diff<0){ + index= av_log2_16bit(-2*diff); + diff--; + }else{ + index= av_log2_16bit(2*diff); + } + if (component == 0) { + put_bits( + &s->pb, + ff_mpeg12_vlc_dc_lum_bits[index] + index, + (ff_mpeg12_vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1))); + }else{ + put_bits( + &s->pb, + ff_mpeg12_vlc_dc_chroma_bits[index] + index, + (ff_mpeg12_vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1))); + } + }else{ + if (component == 0) { + put_bits( + &s->pb, + mpeg1_lum_dc_uni[diff+255]&0xFF, + mpeg1_lum_dc_uni[diff+255]>>8); + } else { + put_bits( + &s->pb, + mpeg1_chr_dc_uni[diff+255]&0xFF, + mpeg1_chr_dc_uni[diff+255]>>8); + } + } +} + +static void mpeg1_encode_block(MpegEncContext *s, + DCTELEM *block, + int n) +{ + int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign; + int code, component; + const uint16_t (*table_vlc)[2] = ff_rl_mpeg1.table_vlc; + + last_index = s->block_last_index[n]; + + /* DC coef */ + if (s->mb_intra) { + component = (n <= 3 ? 0 : (n&1) + 1); + dc = block[0]; /* overflow is impossible */ + diff = dc - s->last_dc[component]; + encode_dc(s, diff, component); + s->last_dc[component] = dc; + i = 1; + if (s->intra_vlc_format) + table_vlc = ff_rl_mpeg2.table_vlc; + } else { + /* encode the first coefficient : needs to be done here because + it is handled slightly differently */ + level = block[0]; + if (abs(level) == 1) { + code = ((uint32_t)level >> 31); /* the sign bit */ + put_bits(&s->pb, 2, code | 0x02); + i = 1; + } else { + i = 0; + last_non_zero = -1; + goto next_coef; + } + } + + /* now quantify & encode AC coefs */ + last_non_zero = i - 1; + + for(;i<=last_index;i++) { + j = s->intra_scantable.permutated[i]; + level = block[j]; + next_coef: +#if 0 + if (level != 0) + dprintf(s->avctx, "level[%d]=%d\n", i, level); +#endif + /* encode using VLC */ + if (level != 0) { + run = i - last_non_zero - 1; + + alevel= level; + MASK_ABS(sign, alevel) + sign&=1; + + if (alevel <= mpeg1_max_level[0][run]){ + code= mpeg1_index_run[0][run] + alevel - 1; + /* store the vlc & sign at once */ + put_bits(&s->pb, table_vlc[code][1]+1, (table_vlc[code][0]<<1) + sign); + } else { + /* escape seems to be pretty rare <5% so I do not optimize it */ + put_bits(&s->pb, table_vlc[111][1], table_vlc[111][0]); + /* escape: only clip in this case */ + put_bits(&s->pb, 6, run); + if(s->codec_id == CODEC_ID_MPEG1VIDEO){ + if (alevel < 128) { + put_bits(&s->pb, 8, level & 0xff); + } else { + if (level < 0) { + put_bits(&s->pb, 16, 0x8001 + level + 255); + } else { + put_bits(&s->pb, 16, level & 0xffff); + } + } + }else{ + put_bits(&s->pb, 12, level & 0xfff); + } + } + last_non_zero = i; + } + } + /* end of block */ + put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]); +} + +AVCodec mpeg1video_encoder = { + "mpeg1video", + CODEC_TYPE_VIDEO, + CODEC_ID_MPEG1VIDEO, + sizeof(MpegEncContext), + encode_init, + MPV_encode_picture, + MPV_encode_end, + .supported_framerates= ff_frame_rate_tab+1, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, + .capabilities= CODEC_CAP_DELAY, +}; + +AVCodec mpeg2video_encoder = { + "mpeg2video", + CODEC_TYPE_VIDEO, + CODEC_ID_MPEG2VIDEO, + sizeof(MpegEncContext), + encode_init, + MPV_encode_picture, + MPV_encode_end, + .supported_framerates= ff_frame_rate_tab+1, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, -1}, + .capabilities= CODEC_CAP_DELAY, +}; diff --git a/contrib/ffmpeg/libavcodec/mpeg4data.h b/contrib/ffmpeg/libavcodec/mpeg4data.h index e199c6a14..ba8f9463c 100644 --- a/contrib/ffmpeg/libavcodec/mpeg4data.h +++ b/contrib/ffmpeg/libavcodec/mpeg4data.h @@ -25,6 +25,12 @@ * mpeg4 tables. */ +#ifndef FFMPEG_MPEG4DATA_H +#define FFMPEG_MPEG4DATA_H + +#include <stdint.h> +#include "mpegvideo.h" + // shapes #define RECT_SHAPE 0 #define BIN_SHAPE 1 @@ -145,7 +151,8 @@ static RLTable rl_intra = { intra_level, }; -static const uint16_t inter_rvlc[170][2]={ //note this is identical to the intra rvlc except that its reordered +/* Note this is identical to the intra rvlc except that it is reordered. */ +static const uint16_t inter_rvlc[170][2]={ {0x0006, 3},{0x0001, 4},{0x0004, 5},{0x001C, 7}, {0x003C, 8},{0x003D, 8},{0x007C, 9},{0x00FC, 10}, {0x00FD, 10},{0x01FC, 11},{0x01FD, 11},{0x03FC, 12}, @@ -421,3 +428,5 @@ const uint16_t ff_mpeg4_resync_prefix[8]={ static const uint8_t mpeg4_dc_threshold[8]={ 99, 13, 15, 17, 19, 21, 23, 0 }; + +#endif /* FFMPEG_MPEG4DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/mpeg4video_parser.c b/contrib/ffmpeg/libavcodec/mpeg4video_parser.c new file mode 100644 index 000000000..9accc9126 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpeg4video_parser.c @@ -0,0 +1,138 @@ +/* + * MPEG4 Video frame extraction + * Copyright (c) 2003 Fabrice Bellard. + * 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 + */ + +#include "parser.h" +#include "mpegvideo.h" +#include "mpeg4video_parser.h" + + +int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ + int vop_found, i; + uint32_t state; + + vop_found= pc->frame_start_found; + state= pc->state; + + i=0; + if(!vop_found){ + for(i=0; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if(state == 0x1B6){ + i++; + vop_found=1; + break; + } + } + } + + if(vop_found){ + /* EOF considered as end of frame */ + if (buf_size == 0) + return 0; + for(; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if((state&0xFFFFFF00) == 0x100){ + pc->frame_start_found=0; + pc->state=-1; + return i-3; + } + } + } + pc->frame_start_found= vop_found; + pc->state= state; + return END_NOT_FOUND; +} + +/* XXX: make it use less memory */ +static int av_mpeg4_decode_header(AVCodecParserContext *s1, + AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + ParseContext1 *pc = s1->priv_data; + MpegEncContext *s = pc->enc; + GetBitContext gb1, *gb = &gb1; + int ret; + + s->avctx = avctx; + s->current_picture_ptr = &s->current_picture; + + if (avctx->extradata_size && pc->first_picture){ + init_get_bits(gb, avctx->extradata, avctx->extradata_size*8); + ret = ff_mpeg4_decode_picture_header(s, gb); + } + + init_get_bits(gb, buf, 8 * buf_size); + ret = ff_mpeg4_decode_picture_header(s, gb); + if (s->width) { + avcodec_set_dimensions(avctx, s->width, s->height); + } + s1->pict_type= s->pict_type; + pc->first_picture = 0; + return ret; +} + +static int mpeg4video_parse_init(AVCodecParserContext *s) +{ + ParseContext1 *pc = s->priv_data; + + pc->enc = av_mallocz(sizeof(MpegEncContext)); + if (!pc->enc) + return -1; + pc->first_picture = 1; + return 0; +} + +static int mpeg4video_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + int next; + + if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ + next= buf_size; + }else{ + next= ff_mpeg4_find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + av_mpeg4_decode_header(s, avctx, buf, buf_size); + + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + + +AVCodecParser mpeg4video_parser = { + { CODEC_ID_MPEG4 }, + sizeof(ParseContext1), + mpeg4video_parse_init, + mpeg4video_parse, + ff_parse1_close, + ff_mpeg4video_split, +}; diff --git a/contrib/ffmpeg/libavcodec/mpeg4video_parser.h b/contrib/ffmpeg/libavcodec/mpeg4video_parser.h new file mode 100644 index 000000000..125f6aa50 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpeg4video_parser.h @@ -0,0 +1,34 @@ +/* + * MPEG4 video parser prototypes + * Copyright (c) 2003 Fabrice Bellard. + * 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 + */ + +#ifndef FFMPEG_MPEG4VIDEO_PARSER_H +#define FFMPEG_MPEG4VIDEO_PARSER_H + +#include "parser.h" + +/** + * 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_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size); + +#endif /* FFMPEG_MPEG4VIDEO_PARSER_H */ diff --git a/contrib/ffmpeg/libavcodec/mpegaudio.c b/contrib/ffmpeg/libavcodec/mpegaudio.c index aa93442d5..663427a43 100644 --- a/contrib/ffmpeg/libavcodec/mpegaudio.c +++ b/contrib/ffmpeg/libavcodec/mpegaudio.c @@ -1,6 +1,6 @@ /* - * The simplest mpeg audio layer 2 encoder - * Copyright (c) 2000, 2001 Fabrice Bellard. + * MPEG Audio common code + * Copyright (c) 2001, 2002 Fabrice Bellard. * * This file is part of FFmpeg. * @@ -21,779 +21,30 @@ /** * @file mpegaudio.c - * The simplest mpeg audio layer 2 encoder. + * MPEG Audio common code. */ -#include "avcodec.h" -#include "bitstream.h" #include "mpegaudio.h" -/* currently, cannot change these constants (need to modify - quantization stage) */ -#define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS) -#define FIX(a) ((int)((a) * (1 << FRAC_BITS))) -#define SAMPLES_BUF_SIZE 4096 - -typedef struct MpegAudioContext { - PutBitContext pb; - int nb_channels; - int freq, bit_rate; - int lsf; /* 1 if mpeg2 low bitrate selected */ - int bitrate_index; /* bit rate */ - int freq_index; - int frame_size; /* frame size, in bits, without padding */ - int64_t nb_samples; /* total number of samples encoded */ - /* padding computation */ - int frame_frac, frame_frac_incr, do_padding; - short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */ - int samples_offset[MPA_MAX_CHANNELS]; /* offset in samples_buf */ - int sb_samples[MPA_MAX_CHANNELS][3][12][SBLIMIT]; - unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3]; /* scale factors */ - /* code to group 3 scale factors */ - unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT]; - int sblimit; /* number of used subbands */ - const unsigned char *alloc_table; -} MpegAudioContext; - -/* define it to use floats in quantization (I don't like floats !) */ -//#define USE_FLOATS - -#include "mpegaudiotab.h" - -static int MPA_encode_init(AVCodecContext *avctx) +/* bitrate is in kb/s */ +int ff_mpa_l2_select_table(int bitrate, int nb_channels, int freq, int lsf) { - MpegAudioContext *s = avctx->priv_data; - int freq = avctx->sample_rate; - int bitrate = avctx->bit_rate; - int channels = avctx->channels; - int i, v, table; - float a; - - if (channels > 2) - return -1; - bitrate = bitrate / 1000; - s->nb_channels = channels; - s->freq = freq; - s->bit_rate = bitrate * 1000; - avctx->frame_size = MPA_FRAME_SIZE; - - /* encoding freq */ - s->lsf = 0; - for(i=0;i<3;i++) { - if (mpa_freq_tab[i] == freq) - break; - if ((mpa_freq_tab[i] / 2) == freq) { - s->lsf = 1; - break; - } - } - if (i == 3){ - av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq); - return -1; - } - s->freq_index = i; - - /* encoding bitrate & frequency */ - for(i=0;i<15;i++) { - if (mpa_bitrate_tab[s->lsf][1][i] == bitrate) - break; - } - if (i == 15){ - av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate); - return -1; - } - s->bitrate_index = i; - - /* compute total header size & pad bit */ - - a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0); - s->frame_size = ((int)a) * 8; - - /* frame fractional size to compute padding */ - s->frame_frac = 0; - s->frame_frac_incr = (int)((a - floor(a)) * 65536.0); - - /* select the right allocation table */ - table = l2_select_table(bitrate, s->nb_channels, freq, s->lsf); - - /* number of used subbands */ - s->sblimit = sblimit_table[table]; - s->alloc_table = alloc_tables[table]; + int ch_bitrate, table; -#ifdef DEBUG - av_log(avctx, AV_LOG_DEBUG, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n", - bitrate, freq, s->frame_size, table, s->frame_frac_incr); -#endif - - for(i=0;i<s->nb_channels;i++) - s->samples_offset[i] = 0; - - for(i=0;i<257;i++) { - int v; - v = mpa_enwindow[i]; -#if WFRAC_BITS != 16 - v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS); -#endif - filter_bank[i] = v; - if ((i & 63) != 0) - v = -v; - if (i != 0) - filter_bank[512 - i] = v; - } - - for(i=0;i<64;i++) { - v = (int)(pow(2.0, (3 - i) / 3.0) * (1 << 20)); - if (v <= 0) - v = 1; - scale_factor_table[i] = v; -#ifdef USE_FLOATS - scale_factor_inv_table[i] = pow(2.0, -(3 - i) / 3.0) / (float)(1 << 20); -#else -#define P 15 - scale_factor_shift[i] = 21 - P - (i / 3); - scale_factor_mult[i] = (1 << P) * pow(2.0, (i % 3) / 3.0); -#endif - } - for(i=0;i<128;i++) { - v = i - 64; - if (v <= -3) - v = 0; - else if (v < 0) - v = 1; - else if (v == 0) - v = 2; - else if (v < 3) - v = 3; - else - v = 4; - scale_diff_table[i] = v; - } - - for(i=0;i<17;i++) { - v = quant_bits[i]; - if (v < 0) - v = -v; + ch_bitrate = bitrate / nb_channels; + if (!lsf) { + if ((freq == 48000 && ch_bitrate >= 56) || + (ch_bitrate >= 56 && ch_bitrate <= 80)) + table = 0; + else if (freq != 48000 && ch_bitrate >= 96) + table = 1; + else if (freq != 32000 && ch_bitrate <= 48) + table = 2; else - v = v * 3; - total_quant_bits[i] = 12 * v; - } - - avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; - - return 0; -} - -/* 32 point floating point IDCT without 1/sqrt(2) coef zero scaling */ -static void idct32(int *out, int *tab) -{ - int i, j; - int *t, *t1, xr; - const int *xp = costab32; - - for(j=31;j>=3;j-=2) tab[j] += tab[j - 2]; - - t = tab + 30; - t1 = tab + 2; - do { - t[0] += t[-4]; - t[1] += t[1 - 4]; - t -= 4; - } while (t != t1); - - t = tab + 28; - t1 = tab + 4; - do { - t[0] += t[-8]; - t[1] += t[1-8]; - t[2] += t[2-8]; - t[3] += t[3-8]; - t -= 8; - } while (t != t1); - - t = tab; - t1 = tab + 32; - do { - t[ 3] = -t[ 3]; - t[ 6] = -t[ 6]; - - t[11] = -t[11]; - t[12] = -t[12]; - t[13] = -t[13]; - t[15] = -t[15]; - t += 16; - } while (t != t1); - - - t = tab; - t1 = tab + 8; - do { - int x1, x2, x3, x4; - - x3 = MUL(t[16], FIX(SQRT2*0.5)); - x4 = t[0] - x3; - x3 = t[0] + x3; - - x2 = MUL(-(t[24] + t[8]), FIX(SQRT2*0.5)); - x1 = MUL((t[8] - x2), xp[0]); - x2 = MUL((t[8] + x2), xp[1]); - - t[ 0] = x3 + x1; - t[ 8] = x4 - x2; - t[16] = x4 + x2; - t[24] = x3 - x1; - t++; - } while (t != t1); - - xp += 2; - t = tab; - t1 = tab + 4; - do { - xr = MUL(t[28],xp[0]); - t[28] = (t[0] - xr); - t[0] = (t[0] + xr); - - xr = MUL(t[4],xp[1]); - t[ 4] = (t[24] - xr); - t[24] = (t[24] + xr); - - xr = MUL(t[20],xp[2]); - t[20] = (t[8] - xr); - t[ 8] = (t[8] + xr); - - xr = MUL(t[12],xp[3]); - t[12] = (t[16] - xr); - t[16] = (t[16] + xr); - t++; - } while (t != t1); - xp += 4; - - for (i = 0; i < 4; i++) { - xr = MUL(tab[30-i*4],xp[0]); - tab[30-i*4] = (tab[i*4] - xr); - tab[ i*4] = (tab[i*4] + xr); - - xr = MUL(tab[ 2+i*4],xp[1]); - tab[ 2+i*4] = (tab[28-i*4] - xr); - tab[28-i*4] = (tab[28-i*4] + xr); - - xr = MUL(tab[31-i*4],xp[0]); - tab[31-i*4] = (tab[1+i*4] - xr); - tab[ 1+i*4] = (tab[1+i*4] + xr); - - xr = MUL(tab[ 3+i*4],xp[1]); - tab[ 3+i*4] = (tab[29-i*4] - xr); - tab[29-i*4] = (tab[29-i*4] + xr); - - xp += 2; - } - - t = tab + 30; - t1 = tab + 1; - do { - xr = MUL(t1[0], *xp); - t1[0] = (t[0] - xr); - t[0] = (t[0] + xr); - t -= 2; - t1 += 2; - xp++; - } while (t >= tab); - - for(i=0;i<32;i++) { - out[i] = tab[bitinv32[i]]; - } -} - -#define WSHIFT (WFRAC_BITS + 15 - FRAC_BITS) - -static void filter(MpegAudioContext *s, int ch, short *samples, int incr) -{ - short *p, *q; - int sum, offset, i, j; - int tmp[64]; - int tmp1[32]; - int *out; - - // print_pow1(samples, 1152); - - offset = s->samples_offset[ch]; - out = &s->sb_samples[ch][0][0][0]; - for(j=0;j<36;j++) { - /* 32 samples at once */ - for(i=0;i<32;i++) { - s->samples_buf[ch][offset + (31 - i)] = samples[0]; - samples += incr; - } - - /* filter */ - p = s->samples_buf[ch] + offset; - q = filter_bank; - /* maxsum = 23169 */ - for(i=0;i<64;i++) { - sum = p[0*64] * q[0*64]; - sum += p[1*64] * q[1*64]; - sum += p[2*64] * q[2*64]; - sum += p[3*64] * q[3*64]; - sum += p[4*64] * q[4*64]; - sum += p[5*64] * q[5*64]; - sum += p[6*64] * q[6*64]; - sum += p[7*64] * q[7*64]; - tmp[i] = sum; - p++; - q++; - } - tmp1[0] = tmp[16] >> WSHIFT; - for( i=1; i<=16; i++ ) tmp1[i] = (tmp[i+16]+tmp[16-i]) >> WSHIFT; - for( i=17; i<=31; i++ ) tmp1[i] = (tmp[i+16]-tmp[80-i]) >> WSHIFT; - - idct32(out, tmp1); - - /* advance of 32 samples */ - offset -= 32; - out += 32; - /* handle the wrap around */ - if (offset < 0) { - memmove(s->samples_buf[ch] + SAMPLES_BUF_SIZE - (512 - 32), - s->samples_buf[ch], (512 - 32) * 2); - offset = SAMPLES_BUF_SIZE - 512; - } - } - s->samples_offset[ch] = offset; - - // print_pow(s->sb_samples, 1152); -} - -static void compute_scale_factors(unsigned char scale_code[SBLIMIT], - unsigned char scale_factors[SBLIMIT][3], - int sb_samples[3][12][SBLIMIT], - int sblimit) -{ - int *p, vmax, v, n, i, j, k, code; - int index, d1, d2; - unsigned char *sf = &scale_factors[0][0]; - - for(j=0;j<sblimit;j++) { - for(i=0;i<3;i++) { - /* find the max absolute value */ - p = &sb_samples[i][0][j]; - vmax = abs(*p); - for(k=1;k<12;k++) { - p += SBLIMIT; - v = abs(*p); - if (v > vmax) - vmax = v; - } - /* compute the scale factor index using log 2 computations */ - if (vmax > 0) { - n = av_log2(vmax); - /* n is the position of the MSB of vmax. now - use at most 2 compares to find the index */ - index = (21 - n) * 3 - 3; - if (index >= 0) { - while (vmax <= scale_factor_table[index+1]) - index++; - } else { - index = 0; /* very unlikely case of overflow */ - } - } else { - index = 62; /* value 63 is not allowed */ - } - -#if 0 - printf("%2d:%d in=%x %x %d\n", - j, i, vmax, scale_factor_table[index], index); -#endif - /* store the scale factor */ - assert(index >=0 && index <= 63); - sf[i] = index; - } - - /* compute the transmission factor : look if the scale factors - are close enough to each other */ - d1 = scale_diff_table[sf[0] - sf[1] + 64]; - d2 = scale_diff_table[sf[1] - sf[2] + 64]; - - /* handle the 25 cases */ - switch(d1 * 5 + d2) { - case 0*5+0: - case 0*5+4: - case 3*5+4: - case 4*5+0: - case 4*5+4: - code = 0; - break; - case 0*5+1: - case 0*5+2: - case 4*5+1: - case 4*5+2: - code = 3; - sf[2] = sf[1]; - break; - case 0*5+3: - case 4*5+3: - code = 3; - sf[1] = sf[2]; - break; - case 1*5+0: - case 1*5+4: - case 2*5+4: - code = 1; - sf[1] = sf[0]; - break; - case 1*5+1: - case 1*5+2: - case 2*5+0: - case 2*5+1: - case 2*5+2: - code = 2; - sf[1] = sf[2] = sf[0]; - break; - case 2*5+3: - case 3*5+3: - code = 2; - sf[0] = sf[1] = sf[2]; - break; - case 3*5+0: - case 3*5+1: - case 3*5+2: - code = 2; - sf[0] = sf[2] = sf[1]; - break; - case 1*5+3: - code = 2; - if (sf[0] > sf[2]) - sf[0] = sf[2]; - sf[1] = sf[2] = sf[0]; - break; - default: - assert(0); //cant happen - code = 0; /* kill warning */ - } - -#if 0 - printf("%d: %2d %2d %2d %d %d -> %d\n", j, - sf[0], sf[1], sf[2], d1, d2, code); -#endif - scale_code[j] = code; - sf += 3; - } -} - -/* The most important function : psycho acoustic module. In this - encoder there is basically none, so this is the worst you can do, - but also this is the simpler. */ -static void psycho_acoustic_model(MpegAudioContext *s, short smr[SBLIMIT]) -{ - int i; - - for(i=0;i<s->sblimit;i++) { - smr[i] = (int)(fixed_smr[i] * 10); - } -} - - -#define SB_NOTALLOCATED 0 -#define SB_ALLOCATED 1 -#define SB_NOMORE 2 - -/* Try to maximize the smr while using a number of bits inferior to - the frame size. I tried to make the code simpler, faster and - smaller than other encoders :-) */ -static void compute_bit_allocation(MpegAudioContext *s, - short smr1[MPA_MAX_CHANNELS][SBLIMIT], - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], - int *padding) -{ - int i, ch, b, max_smr, max_ch, max_sb, current_frame_size, max_frame_size; - int incr; - short smr[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char subband_status[MPA_MAX_CHANNELS][SBLIMIT]; - const unsigned char *alloc; - - memcpy(smr, smr1, s->nb_channels * sizeof(short) * SBLIMIT); - memset(subband_status, SB_NOTALLOCATED, s->nb_channels * SBLIMIT); - memset(bit_alloc, 0, s->nb_channels * SBLIMIT); - - /* compute frame size and padding */ - max_frame_size = s->frame_size; - s->frame_frac += s->frame_frac_incr; - if (s->frame_frac >= 65536) { - s->frame_frac -= 65536; - s->do_padding = 1; - max_frame_size += 8; + table = 3; } else { - s->do_padding = 0; - } - - /* compute the header + bit alloc size */ - current_frame_size = 32; - alloc = s->alloc_table; - for(i=0;i<s->sblimit;i++) { - incr = alloc[0]; - current_frame_size += incr * s->nb_channels; - alloc += 1 << incr; - } - for(;;) { - /* look for the subband with the largest signal to mask ratio */ - max_sb = -1; - max_ch = -1; - max_smr = 0x80000000; - for(ch=0;ch<s->nb_channels;ch++) { - for(i=0;i<s->sblimit;i++) { - if (smr[ch][i] > max_smr && subband_status[ch][i] != SB_NOMORE) { - max_smr = smr[ch][i]; - max_sb = i; - max_ch = ch; - } - } - } -#if 0 - printf("current=%d max=%d max_sb=%d alloc=%d\n", - current_frame_size, max_frame_size, max_sb, - bit_alloc[max_sb]); -#endif - if (max_sb < 0) - break; - - /* find alloc table entry (XXX: not optimal, should use - pointer table) */ - alloc = s->alloc_table; - for(i=0;i<max_sb;i++) { - alloc += 1 << alloc[0]; - } - - if (subband_status[max_ch][max_sb] == SB_NOTALLOCATED) { - /* nothing was coded for this band: add the necessary bits */ - incr = 2 + nb_scale_factors[s->scale_code[max_ch][max_sb]] * 6; - incr += total_quant_bits[alloc[1]]; - } else { - /* increments bit allocation */ - b = bit_alloc[max_ch][max_sb]; - incr = total_quant_bits[alloc[b + 1]] - - total_quant_bits[alloc[b]]; - } - - if (current_frame_size + incr <= max_frame_size) { - /* can increase size */ - b = ++bit_alloc[max_ch][max_sb]; - current_frame_size += incr; - /* decrease smr by the resolution we added */ - smr[max_ch][max_sb] = smr1[max_ch][max_sb] - quant_snr[alloc[b]]; - /* max allocation size reached ? */ - if (b == ((1 << alloc[0]) - 1)) - subband_status[max_ch][max_sb] = SB_NOMORE; - else - subband_status[max_ch][max_sb] = SB_ALLOCATED; - } else { - /* cannot increase the size of this subband */ - subband_status[max_ch][max_sb] = SB_NOMORE; - } - } - *padding = max_frame_size - current_frame_size; - assert(*padding >= 0); - -#if 0 - for(i=0;i<s->sblimit;i++) { - printf("%d ", bit_alloc[i]); - } - printf("\n"); -#endif -} - -/* - * Output the mpeg audio layer 2 frame. Note how the code is small - * compared to other encoders :-) - */ -static void encode_frame(MpegAudioContext *s, - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], - int padding) -{ - int i, j, k, l, bit_alloc_bits, b, ch; - unsigned char *sf; - int q[3]; - PutBitContext *p = &s->pb; - - /* header */ - - put_bits(p, 12, 0xfff); - put_bits(p, 1, 1 - s->lsf); /* 1 = mpeg1 ID, 0 = mpeg2 lsf ID */ - put_bits(p, 2, 4-2); /* layer 2 */ - put_bits(p, 1, 1); /* no error protection */ - put_bits(p, 4, s->bitrate_index); - put_bits(p, 2, s->freq_index); - put_bits(p, 1, s->do_padding); /* use padding */ - put_bits(p, 1, 0); /* private_bit */ - put_bits(p, 2, s->nb_channels == 2 ? MPA_STEREO : MPA_MONO); - put_bits(p, 2, 0); /* mode_ext */ - put_bits(p, 1, 0); /* no copyright */ - put_bits(p, 1, 1); /* original */ - put_bits(p, 2, 0); /* no emphasis */ - - /* bit allocation */ - j = 0; - for(i=0;i<s->sblimit;i++) { - bit_alloc_bits = s->alloc_table[j]; - for(ch=0;ch<s->nb_channels;ch++) { - put_bits(p, bit_alloc_bits, bit_alloc[ch][i]); - } - j += 1 << bit_alloc_bits; - } - - /* scale codes */ - for(i=0;i<s->sblimit;i++) { - for(ch=0;ch<s->nb_channels;ch++) { - if (bit_alloc[ch][i]) - put_bits(p, 2, s->scale_code[ch][i]); - } - } - - /* scale factors */ - for(i=0;i<s->sblimit;i++) { - for(ch=0;ch<s->nb_channels;ch++) { - if (bit_alloc[ch][i]) { - sf = &s->scale_factors[ch][i][0]; - switch(s->scale_code[ch][i]) { - case 0: - put_bits(p, 6, sf[0]); - put_bits(p, 6, sf[1]); - put_bits(p, 6, sf[2]); - break; - case 3: - case 1: - put_bits(p, 6, sf[0]); - put_bits(p, 6, sf[2]); - break; - case 2: - put_bits(p, 6, sf[0]); - break; - } - } - } - } - - /* quantization & write sub band samples */ - - for(k=0;k<3;k++) { - for(l=0;l<12;l+=3) { - j = 0; - for(i=0;i<s->sblimit;i++) { - bit_alloc_bits = s->alloc_table[j]; - for(ch=0;ch<s->nb_channels;ch++) { - b = bit_alloc[ch][i]; - if (b) { - int qindex, steps, m, sample, bits; - /* we encode 3 sub band samples of the same sub band at a time */ - qindex = s->alloc_table[j+b]; - steps = quant_steps[qindex]; - for(m=0;m<3;m++) { - sample = s->sb_samples[ch][k][l + m][i]; - /* divide by scale factor */ -#ifdef USE_FLOATS - { - float a; - a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]]; - q[m] = (int)((a + 1.0) * steps * 0.5); - } -#else - { - int q1, e, shift, mult; - e = s->scale_factors[ch][i][k]; - shift = scale_factor_shift[e]; - mult = scale_factor_mult[e]; - - /* normalize to P bits */ - if (shift < 0) - q1 = sample << (-shift); - else - q1 = sample >> shift; - q1 = (q1 * mult) >> P; - q[m] = ((q1 + (1 << P)) * steps) >> (P + 1); - } -#endif - if (q[m] >= steps) - q[m] = steps - 1; - assert(q[m] >= 0 && q[m] < steps); - } - bits = quant_bits[qindex]; - if (bits < 0) { - /* group the 3 values to save bits */ - put_bits(p, -bits, - q[0] + steps * (q[1] + steps * q[2])); -#if 0 - printf("%d: gr1 %d\n", - i, q[0] + steps * (q[1] + steps * q[2])); -#endif - } else { -#if 0 - printf("%d: gr3 %d %d %d\n", - i, q[0], q[1], q[2]); -#endif - put_bits(p, bits, q[0]); - put_bits(p, bits, q[1]); - put_bits(p, bits, q[2]); - } - } - } - /* next subband in alloc table */ - j += 1 << bit_alloc_bits; - } - } - } - - /* padding */ - for(i=0;i<padding;i++) - put_bits(p, 1, 0); - - /* flush */ - flush_put_bits(p); -} - -static int MPA_encode_frame(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) -{ - MpegAudioContext *s = avctx->priv_data; - short *samples = data; - short smr[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT]; - int padding, i; - - for(i=0;i<s->nb_channels;i++) { - filter(s, i, samples + i, s->nb_channels); - } - - for(i=0;i<s->nb_channels;i++) { - compute_scale_factors(s->scale_code[i], s->scale_factors[i], - s->sb_samples[i], s->sblimit); - } - for(i=0;i<s->nb_channels;i++) { - psycho_acoustic_model(s, smr[i]); + table = 4; } - compute_bit_allocation(s, smr, bit_alloc, &padding); - - init_put_bits(&s->pb, frame, MPA_MAX_CODED_FRAME_SIZE); - - encode_frame(s, bit_alloc, padding); - - s->nb_samples += MPA_FRAME_SIZE; - return pbBufPtr(&s->pb) - s->pb.buf; -} - -static int MPA_encode_close(AVCodecContext *avctx) -{ - av_freep(&avctx->coded_frame); - return 0; + return table; } - -AVCodec mp2_encoder = { - "mp2", - CODEC_TYPE_AUDIO, - CODEC_ID_MP2, - sizeof(MpegAudioContext), - MPA_encode_init, - MPA_encode_frame, - MPA_encode_close, - NULL, -}; - -#undef FIX diff --git a/contrib/ffmpeg/libavcodec/mpegaudio.h b/contrib/ffmpeg/libavcodec/mpegaudio.h index 3eadf92a8..6d602a1dc 100644 --- a/contrib/ffmpeg/libavcodec/mpegaudio.h +++ b/contrib/ffmpeg/libavcodec/mpegaudio.h @@ -23,6 +23,13 @@ * mpeg audio declarations for both encoder and decoder. */ +#ifndef FFMPEG_MPEGAUDIO_H +#define FFMPEG_MPEGAUDIO_H + +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" + /* max frame size, in samples */ #define MPA_FRAME_SIZE 1152 @@ -42,6 +49,8 @@ #define SAME_HEADER_MASK \ (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19)) +#define MP3_MASK 0xFFFE0CCF + /* define USE_HIGHPRECISION to have a bit exact (but slower) mpeg audio decoder */ @@ -53,6 +62,10 @@ #define WFRAC_BITS 14 /* fractional bits for window */ #endif +#define FRAC_ONE (1 << FRAC_BITS) + +#define FIX(a) ((int)((a) * FRAC_ONE)) + #if defined(USE_HIGHPRECISION) && defined(CONFIG_AUDIO_NONSHORT) typedef int32_t OUT_INT; #define OUT_MAX INT32_MAX @@ -71,23 +84,57 @@ typedef int16_t MPA_INT; typedef int32_t MPA_INT; #endif -int l2_select_table(int bitrate, int nb_channels, int freq, int lsf); -int mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate); +#define BACKSTEP_SIZE 512 +#define EXTRABYTES 24 + +struct GranuleDef; + +typedef struct MPADecodeContext { + DECLARE_ALIGNED_8(uint8_t, last_buf[2*BACKSTEP_SIZE + EXTRABYTES]); + int last_buf_size; + int frame_size; + /* next header (used in free format parsing) */ + uint32_t free_format_next_header; + int error_protection; + int layer; + int sample_rate; + int sample_rate_index; /* between 0 and 8 */ + int bit_rate; + GetBitContext gb; + GetBitContext in_gb; + int nb_channels; + int mode; + int mode_ext; + int lsf; + DECLARE_ALIGNED_16(MPA_INT, synth_buf[MPA_MAX_CHANNELS][512 * 2]); + int synth_buf_offset[MPA_MAX_CHANNELS]; + DECLARE_ALIGNED_16(int32_t, sb_samples[MPA_MAX_CHANNELS][36][SBLIMIT]); + int32_t mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */ +#ifdef DEBUG + int frame_count; +#endif + void (*compute_antialias)(struct MPADecodeContext *s, struct GranuleDef *g); + int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3 + int dither_state; + int error_resilience; + AVCodecContext* avctx; +} MPADecodeContext; + +/* layer 3 huffman tables */ +typedef struct HuffTable { + int xsize; + const uint8_t *bits; + const uint16_t *codes; +} HuffTable; + +int ff_mpa_l2_select_table(int bitrate, int nb_channels, int freq, int lsf); +int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate); void ff_mpa_synth_init(MPA_INT *window); void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset, MPA_INT *window, int *dither_state, OUT_INT *samples, int incr, int32_t sb_samples[SBLIMIT]); -extern const uint16_t mpa_bitrate_tab[2][3][15]; -extern const uint16_t mpa_freq_tab[3]; -extern const unsigned char *alloc_tables[5]; -extern const double enwindow[512]; -extern const int sblimit_table[5]; -extern const int quant_steps[17]; -extern const int quant_bits[17]; -extern const int32_t mpa_enwindow[257]; - /* fast header check for resync */ static inline int ff_mpa_check_header(uint32_t header){ /* header */ @@ -104,3 +151,5 @@ static inline int ff_mpa_check_header(uint32_t header){ return -1; return 0; } + +#endif /* FFMPEG_MPEGAUDIO_H */ diff --git a/contrib/ffmpeg/libavcodec/mpegaudio_parser.c b/contrib/ffmpeg/libavcodec/mpegaudio_parser.c new file mode 100644 index 000000000..e7cb7439e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpegaudio_parser.c @@ -0,0 +1,252 @@ +/* + * MPEG Audio parser + * Copyright (c) 2003 Fabrice Bellard. + * 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 + */ + +#include "parser.h" +#include "mpegaudio.h" +#include "mpegaudiodecheader.h" + + +typedef struct MpegAudioParseContext { + uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ + uint8_t *inbuf_ptr; + int frame_size; + int free_format_frame_size; + int free_format_next_header; + uint32_t header; + int header_count; +} MpegAudioParseContext; + +#define MPA_HEADER_SIZE 4 + +/* header + layer + bitrate + freq + lsf/mpeg25 */ +#undef SAME_HEADER_MASK /* mpegaudio.h defines different version */ +#define SAME_HEADER_MASK \ + (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) + +/* useful helper to get mpeg audio stream infos. Return -1 if error in + header, otherwise the coded frame size in bytes */ +int ff_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate) +{ + MPADecodeContext s1, *s = &s1; + s1.avctx = avctx; + + if (ff_mpa_check_header(head) != 0) + return -1; + + if (ff_mpegaudio_decode_header(s, head) != 0) { + return -1; + } + + switch(s->layer) { + case 1: + avctx->frame_size = 384; + break; + case 2: + avctx->frame_size = 1152; + break; + default: + case 3: + if (s->lsf) + avctx->frame_size = 576; + else + avctx->frame_size = 1152; + break; + } + + *sample_rate = s->sample_rate; + avctx->channels = s->nb_channels; + avctx->bit_rate = s->bit_rate; + avctx->sub_id = s->layer; + return s->frame_size; +} + +static int mpegaudio_parse_init(AVCodecParserContext *s1) +{ + MpegAudioParseContext *s = s1->priv_data; + s->inbuf_ptr = s->inbuf; + return 0; +} + +static int mpegaudio_parse(AVCodecParserContext *s1, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + MpegAudioParseContext *s = s1->priv_data; + int len, ret, sr; + uint32_t header; + const uint8_t *buf_ptr; + + *poutbuf = NULL; + *poutbuf_size = 0; + buf_ptr = buf; + while (buf_size > 0) { + len = s->inbuf_ptr - s->inbuf; + if (s->frame_size == 0) { + /* special case for next header for first frame in free + format case (XXX: find a simpler method) */ + if (s->free_format_next_header != 0) { + AV_WB32(s->inbuf, s->free_format_next_header); + s->inbuf_ptr = s->inbuf + 4; + s->free_format_next_header = 0; + goto got_header; + } + /* no header seen : find one. We need at least MPA_HEADER_SIZE + bytes to parse it */ + len = FFMIN(MPA_HEADER_SIZE - len, buf_size); + if (len > 0) { + memcpy(s->inbuf_ptr, buf_ptr, len); + buf_ptr += len; + buf_size -= len; + s->inbuf_ptr += len; + } + if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { + got_header: + header = AV_RB32(s->inbuf); + + ret = ff_mpa_decode_header(avctx, header, &sr); + if (ret < 0) { + s->header_count= -2; + /* no sync found : move by one byte (inefficient, but simple!) */ + memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); + s->inbuf_ptr--; + dprintf(avctx, "skip %x\n", header); + /* reset free format frame size to give a chance + to get a new bitrate */ + s->free_format_frame_size = 0; + } else { + if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) + s->header_count= -3; + s->header= header; + s->header_count++; + s->frame_size = ret; + +#if 0 + /* free format: prepare to compute frame size */ + if (ff_mpegaudio_decode_header(s, header) == 1) { + s->frame_size = -1; + } +#endif + if(s->header_count > 1) + avctx->sample_rate= sr; + } + } + } else +#if 0 + if (s->frame_size == -1) { + /* free format : find next sync to compute frame size */ + len = MPA_MAX_CODED_FRAME_SIZE - len; + if (len > buf_size) + len = buf_size; + if (len == 0) { + /* frame too long: resync */ + s->frame_size = 0; + memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); + s->inbuf_ptr--; + } else { + uint8_t *p, *pend; + uint32_t header1; + int padding; + + memcpy(s->inbuf_ptr, buf_ptr, len); + /* check for header */ + p = s->inbuf_ptr - 3; + pend = s->inbuf_ptr + len - 4; + while (p <= pend) { + header = AV_RB32(p); + header1 = AV_RB32(s->inbuf); + /* check with high probability that we have a + valid header */ + if ((header & SAME_HEADER_MASK) == + (header1 & SAME_HEADER_MASK)) { + /* header found: update pointers */ + len = (p + 4) - s->inbuf_ptr; + buf_ptr += len; + buf_size -= len; + s->inbuf_ptr = p; + /* compute frame size */ + s->free_format_next_header = header; + s->free_format_frame_size = s->inbuf_ptr - s->inbuf; + padding = (header1 >> 9) & 1; + if (s->layer == 1) + s->free_format_frame_size -= padding * 4; + else + s->free_format_frame_size -= padding; + dprintf(avctx, "free frame size=%d padding=%d\n", + s->free_format_frame_size, padding); + ff_mpegaudio_decode_header(s, header1); + goto next_data; + } + p++; + } + /* not found: simply increase pointers */ + buf_ptr += len; + s->inbuf_ptr += len; + buf_size -= len; + } + } else +#endif + if (len < s->frame_size) { + if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) + s->frame_size = MPA_MAX_CODED_FRAME_SIZE; + len = FFMIN(s->frame_size - len, buf_size); + memcpy(s->inbuf_ptr, buf_ptr, len); + buf_ptr += len; + s->inbuf_ptr += len; + buf_size -= len; + } + + if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf + && buf_size + buf_ptr - buf >= s->frame_size){ + if(s->header_count > 0){ + *poutbuf = buf; + *poutbuf_size = s->frame_size; + } + buf_ptr = buf + s->frame_size; + s->inbuf_ptr = s->inbuf; + s->frame_size = 0; + break; + } + + // next_data: + if (s->frame_size > 0 && + (s->inbuf_ptr - s->inbuf) >= s->frame_size) { + if(s->header_count > 0){ + *poutbuf = s->inbuf; + *poutbuf_size = s->inbuf_ptr - s->inbuf; + } + s->inbuf_ptr = s->inbuf; + s->frame_size = 0; + break; + } + } + return buf_ptr - buf; +} + + +AVCodecParser mpegaudio_parser = { + { CODEC_ID_MP2, CODEC_ID_MP3 }, + sizeof(MpegAudioParseContext), + mpegaudio_parse_init, + mpegaudio_parse, + NULL, +}; diff --git a/contrib/ffmpeg/libavcodec/mpegaudiodata.c b/contrib/ffmpeg/libavcodec/mpegaudiodata.c new file mode 100644 index 000000000..5089c9567 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpegaudiodata.c @@ -0,0 +1,225 @@ +/* + * MPEG Audio common tables + * copyright (c) 2002 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 mpegaudiodata.c + * mpeg audio layer common tables. + */ + +#include "mpegaudiodata.h" + + +const uint16_t ff_mpa_bitrate_tab[2][3][15] = { + { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, + {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } }, + { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} + } +}; + +const uint16_t ff_mpa_freq_tab[3] = { 44100, 48000, 32000 }; + +/*******************************************************/ +/* half mpeg encoding window (full precision) */ +const int32_t ff_mpa_enwindow[257] = { + 0, -1, -1, -1, -1, -1, -1, -2, + -2, -2, -2, -3, -3, -4, -4, -5, + -5, -6, -7, -7, -8, -9, -10, -11, + -13, -14, -16, -17, -19, -21, -24, -26, + -29, -31, -35, -38, -41, -45, -49, -53, + -58, -63, -68, -73, -79, -85, -91, -97, + -104, -111, -117, -125, -132, -139, -147, -154, + -161, -169, -176, -183, -190, -196, -202, -208, + 213, 218, 222, 225, 227, 228, 228, 227, + 224, 221, 215, 208, 200, 189, 177, 163, + 146, 127, 106, 83, 57, 29, -2, -36, + -72, -111, -153, -197, -244, -294, -347, -401, + -459, -519, -581, -645, -711, -779, -848, -919, + -991, -1064, -1137, -1210, -1283, -1356, -1428, -1498, + -1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962, + -2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063, + 2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535, + 1414, 1280, 1131, 970, 794, 605, 402, 185, + -45, -288, -545, -814, -1095, -1388, -1692, -2006, + -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, + -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, + -7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585, + -9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750, + -9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134, + 6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082, + 70, -998, -2122, -3300, -4533, -5818, -7154, -8540, + -9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189, +-22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640, +-37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137, +-51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684, +-64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420, +-72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992, + 75038, +}; + +/*******************************************************/ +/* layer 2 tables */ + +const int ff_mpa_sblimit_table[5] = { 27 , 30 , 8, 12 , 30 }; + +const int ff_mpa_quant_steps[17] = { + 3, 5, 7, 9, 15, + 31, 63, 127, 255, 511, + 1023, 2047, 4095, 8191, 16383, + 32767, 65535 +}; + +/* we use a negative value if grouped */ +const int ff_mpa_quant_bits[17] = { + -5, -7, 3, -10, 4, + 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, + 15, 16 +}; + +/* encoding tables which give the quantization index. Note how it is + possible to store them efficiently ! */ +static const unsigned char alloc_table_0[] = { + 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 2, 0, 1, 16, + 2, 0, 1, 16, + 2, 0, 1, 16, + 2, 0, 1, 16, +}; + +static const unsigned char alloc_table_1[] = { + 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 3, 0, 1, 2, 3, 4, 5, 16, + 2, 0, 1, 16, + 2, 0, 1, 16, + 2, 0, 1, 16, + 2, 0, 1, 16, + 2, 0, 1, 16, + 2, 0, 1, 16, + 2, 0, 1, 16, +}; + +static const unsigned char alloc_table_2[] = { + 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, +}; + +static const unsigned char alloc_table_3[] = { + 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, +}; + +static const unsigned char alloc_table_4[] = { + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 3, 0, 1, 3, 4, 5, 6, 7, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, + 2, 0, 1, 3, +}; + +const unsigned char *ff_mpa_alloc_tables[5] = +{ alloc_table_0, alloc_table_1, alloc_table_2, alloc_table_3, alloc_table_4, }; diff --git a/contrib/ffmpeg/libavcodec/mpegaudiodata.h b/contrib/ffmpeg/libavcodec/mpegaudiodata.h new file mode 100644 index 000000000..d513645b5 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpegaudiodata.h @@ -0,0 +1,43 @@ +/* + * MPEG Audio common tables + * copyright (c) 2002 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 mpegaudiodata.h + * mpeg audio layer common tables. + */ + +#ifndef FFMPEG_MPEGAUDIODATA_H +#define FFMPEG_MPEGAUDIODATA_H + +#include "common.h" + +#define MODE_EXT_MS_STEREO 2 +#define MODE_EXT_I_STEREO 1 + +extern const uint16_t ff_mpa_bitrate_tab[2][3][15]; +extern const uint16_t ff_mpa_freq_tab[3]; +extern const int32_t ff_mpa_enwindow[257]; +extern const int ff_mpa_sblimit_table[5]; +extern const int ff_mpa_quant_steps[17]; +extern const int ff_mpa_quant_bits[17]; +extern const unsigned char *ff_mpa_alloc_tables[5]; + +#endif /* FFMPEG_MPEGAUDIODATA_H */ diff --git a/contrib/ffmpeg/libavcodec/mpegaudiodec.c b/contrib/ffmpeg/libavcodec/mpegaudiodec.c index d64c9f611..98f7f3b5e 100644 --- a/contrib/ffmpeg/libavcodec/mpegaudiodec.c +++ b/contrib/ffmpeg/libavcodec/mpegaudiodec.c @@ -42,12 +42,10 @@ #endif #include "mpegaudio.h" +#include "mpegaudiodecheader.h" #include "mathops.h" -#define FRAC_ONE (1 << FRAC_BITS) - -#define FIX(a) ((int)((a) * FRAC_ONE)) /* WARNING: only correct for posititive numbers */ #define FIXR(a) ((int)((a) * FRAC_ONE + 0.5)) #define FRAC_RND(a) (((a) + (FRAC_ONE/2)) >> FRAC_BITS) @@ -57,41 +55,6 @@ /****************/ #define HEADER_SIZE 4 -#define BACKSTEP_SIZE 512 -#define EXTRABYTES 24 - -struct GranuleDef; - -typedef struct MPADecodeContext { - DECLARE_ALIGNED_8(uint8_t, last_buf[2*BACKSTEP_SIZE + EXTRABYTES]); - int last_buf_size; - int frame_size; - /* next header (used in free format parsing) */ - uint32_t free_format_next_header; - int error_protection; - int layer; - int sample_rate; - int sample_rate_index; /* between 0 and 8 */ - int bit_rate; - GetBitContext gb; - GetBitContext in_gb; - int nb_channels; - int mode; - int mode_ext; - int lsf; - MPA_INT synth_buf[MPA_MAX_CHANNELS][512 * 2] __attribute__((aligned(16))); - int synth_buf_offset[MPA_MAX_CHANNELS]; - int32_t sb_samples[MPA_MAX_CHANNELS][36][SBLIMIT] __attribute__((aligned(16))); - int32_t mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */ -#ifdef DEBUG - int frame_count; -#endif - void (*compute_antialias)(struct MPADecodeContext *s, struct GranuleDef *g); - int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3 - int dither_state; - int error_resilience; - AVCodecContext* avctx; -} MPADecodeContext; /** * Context for MP3On4 decoder @@ -122,16 +85,7 @@ typedef struct GranuleDef { int32_t sb_hybrid[SBLIMIT * 18]; /* 576 samples */ } GranuleDef; -#define MODE_EXT_MS_STEREO 2 -#define MODE_EXT_I_STEREO 1 - -/* layer 3 huffman tables */ -typedef struct HuffTable { - int xsize; - const uint8_t *bits; - const uint16_t *codes; -} HuffTable; - +#include "mpegaudiodata.h" #include "mpegaudiodectab.h" static void compute_antialias_integer(MPADecodeContext *s, GranuleDef *g); @@ -170,7 +124,69 @@ static const int32_t scale_factor_mult2[3][3] = { SCALE_GEN(4.0 / 9.0), /* 9 steps */ }; -static MPA_INT window[512] __attribute__((aligned(16))); +static DECLARE_ALIGNED_16(MPA_INT, window[512]); + +/** + * Convert region offsets to region sizes and truncate + * size to big_values. + */ +void ff_region_offset2size(GranuleDef *g){ + int i, k, j=0; + g->region_size[2] = (576 / 2); + for(i=0;i<3;i++) { + k = FFMIN(g->region_size[i], g->big_values); + g->region_size[i] = k - j; + j = k; + } +} + +void ff_init_short_region(MPADecodeContext *s, GranuleDef *g){ + if (g->block_type == 2) + g->region_size[0] = (36 / 2); + else { + if (s->sample_rate_index <= 2) + g->region_size[0] = (36 / 2); + else if (s->sample_rate_index != 8) + g->region_size[0] = (54 / 2); + else + g->region_size[0] = (108 / 2); + } + g->region_size[1] = (576 / 2); +} + +void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2){ + int l; + g->region_size[0] = + band_index_long[s->sample_rate_index][ra1 + 1] >> 1; + /* should not overflow */ + l = FFMIN(ra1 + ra2 + 2, 22); + g->region_size[1] = + band_index_long[s->sample_rate_index][l] >> 1; +} + +void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g){ + if (g->block_type == 2) { + if (g->switch_point) { + /* if switched mode, we handle the 36 first samples as + long blocks. For 8000Hz, we handle the 48 first + exponents as long blocks (XXX: check this!) */ + if (s->sample_rate_index <= 2) + g->long_end = 8; + else if (s->sample_rate_index != 8) + g->long_end = 6; + else + g->long_end = 4; /* 8000 Hz */ + + g->short_start = 2 + (s->sample_rate_index != 8); + } else { + g->long_end = 0; + g->short_start = 0; + } + } else { + g->short_start = 13; + g->long_end = 22; + } +} /* layer 1 unscaling */ /* n = number of bits of the mantissa minus 1 */ @@ -824,7 +840,7 @@ void ff_mpa_synth_init(MPA_INT *window) /* max = 18760, max sum over all 16 coefs : 44736 */ for(i=0;i<257;i++) { int v; - v = mpa_enwindow[i]; + v = ff_mpa_enwindow[i]; #if WFRAC_BITS < 16 v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS); #endif @@ -865,10 +881,7 @@ void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset, #if FRAC_BITS <= 15 /* NOTE: can cause a loss in precision if very high amplitude sound */ - if (v > 32767) - v = 32767; - else if (v < -32768) - v = -32768; + v = av_clip_int16(v); #endif synth_buf[j] = v; } @@ -1106,124 +1119,6 @@ static void imdct36(int *out, int *buf, int *in, int *win) buf[8 - 4] = MULH(t0, win[18 + 8 - 4]); } -/* header decoding. MUST check the header before because no - consistency check is done there. Return 1 if free format found and - that the frame size must be computed externally */ -static int decode_header(MPADecodeContext *s, uint32_t header) -{ - int sample_rate, frame_size, mpeg25, padding; - int sample_rate_index, bitrate_index; - if (header & (1<<20)) { - s->lsf = (header & (1<<19)) ? 0 : 1; - mpeg25 = 0; - } else { - s->lsf = 1; - mpeg25 = 1; - } - - s->layer = 4 - ((header >> 17) & 3); - /* extract frequency */ - sample_rate_index = (header >> 10) & 3; - sample_rate = mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25); - sample_rate_index += 3 * (s->lsf + mpeg25); - s->sample_rate_index = sample_rate_index; - s->error_protection = ((header >> 16) & 1) ^ 1; - s->sample_rate = sample_rate; - - bitrate_index = (header >> 12) & 0xf; - padding = (header >> 9) & 1; - //extension = (header >> 8) & 1; - s->mode = (header >> 6) & 3; - s->mode_ext = (header >> 4) & 3; - //copyright = (header >> 3) & 1; - //original = (header >> 2) & 1; - //emphasis = header & 3; - - if (s->mode == MPA_MONO) - s->nb_channels = 1; - else - s->nb_channels = 2; - - if (bitrate_index != 0) { - frame_size = mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index]; - s->bit_rate = frame_size * 1000; - switch(s->layer) { - case 1: - frame_size = (frame_size * 12000) / sample_rate; - frame_size = (frame_size + padding) * 4; - break; - case 2: - frame_size = (frame_size * 144000) / sample_rate; - frame_size += padding; - break; - default: - case 3: - frame_size = (frame_size * 144000) / (sample_rate << s->lsf); - frame_size += padding; - break; - } - s->frame_size = frame_size; - } else { - /* if no frame size computed, signal it */ - return 1; - } - -#if defined(DEBUG) - dprintf(s->avctx, "layer%d, %d Hz, %d kbits/s, ", - s->layer, s->sample_rate, s->bit_rate); - if (s->nb_channels == 2) { - if (s->layer == 3) { - if (s->mode_ext & MODE_EXT_MS_STEREO) - dprintf(s->avctx, "ms-"); - if (s->mode_ext & MODE_EXT_I_STEREO) - dprintf(s->avctx, "i-"); - } - dprintf(s->avctx, "stereo"); - } else { - dprintf(s->avctx, "mono"); - } - dprintf(s->avctx, "\n"); -#endif - return 0; -} - -/* useful helper to get mpeg audio stream infos. Return -1 if error in - header, otherwise the coded frame size in bytes */ -int mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate) -{ - MPADecodeContext s1, *s = &s1; - s1.avctx = avctx; - - if (ff_mpa_check_header(head) != 0) - return -1; - - if (decode_header(s, head) != 0) { - return -1; - } - - switch(s->layer) { - case 1: - avctx->frame_size = 384; - break; - case 2: - avctx->frame_size = 1152; - break; - default: - case 3: - if (s->lsf) - avctx->frame_size = 576; - else - avctx->frame_size = 1152; - break; - } - - *sample_rate = s->sample_rate; - avctx->channels = s->nb_channels; - avctx->bit_rate = s->bit_rate; - avctx->sub_id = s->layer; - return s->frame_size; -} - /* return the number of decoded frames */ static int mp_decode_layer1(MPADecodeContext *s) { @@ -1291,28 +1186,6 @@ static int mp_decode_layer1(MPADecodeContext *s) return 12; } -/* bitrate is in kb/s */ -int l2_select_table(int bitrate, int nb_channels, int freq, int lsf) -{ - int ch_bitrate, table; - - ch_bitrate = bitrate / nb_channels; - if (!lsf) { - if ((freq == 48000 && ch_bitrate >= 56) || - (ch_bitrate >= 56 && ch_bitrate <= 80)) - table = 0; - else if (freq != 48000 && ch_bitrate >= 96) - table = 1; - else if (freq != 32000 && ch_bitrate <= 48) - table = 2; - else - table = 3; - } else { - table = 4; - } - return table; -} - static int mp_decode_layer2(MPADecodeContext *s) { int sblimit; /* number of used subbands */ @@ -1324,10 +1197,10 @@ static int mp_decode_layer2(MPADecodeContext *s) int scale, qindex, bits, steps, k, l, m, b; /* select decoding table */ - table = l2_select_table(s->bit_rate / 1000, s->nb_channels, + table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels, s->sample_rate, s->lsf); - sblimit = sblimit_table[table]; - alloc_table = alloc_tables[table]; + sblimit = ff_mpa_sblimit_table[table]; + alloc_table = ff_mpa_alloc_tables[table]; if (s->mode == MPA_JSTEREO) bound = (s->mode_ext + 1) * 4; @@ -1431,11 +1304,11 @@ static int mp_decode_layer2(MPADecodeContext *s) if (b) { scale = scale_factors[ch][i][k]; qindex = alloc_table[j+b]; - bits = quant_bits[qindex]; + bits = ff_mpa_quant_bits[qindex]; if (bits < 0) { /* 3 values at the same time */ v = get_bits(&s->gb, -bits); - steps = quant_steps[qindex]; + steps = ff_mpa_quant_steps[qindex]; s->sb_samples[ch][k * 12 + l + 0][i] = l2_unscale_group(steps, v % steps, scale); v = v / steps; @@ -1469,11 +1342,11 @@ static int mp_decode_layer2(MPADecodeContext *s) scale0 = scale_factors[0][i][k]; scale1 = scale_factors[1][i][k]; qindex = alloc_table[j+b]; - bits = quant_bits[qindex]; + bits = ff_mpa_quant_bits[qindex]; if (bits < 0) { /* 3 values at the same time */ v = get_bits(&s->gb, -bits); - steps = quant_steps[qindex]; + steps = ff_mpa_quant_steps[qindex]; mant = v % steps; v = v / steps; s->sb_samples[0][k * 12 + l + 0][i] = @@ -1729,7 +1602,7 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, g->sb_hybrid[s_index+2]= g->sb_hybrid[s_index+3]= 0; while(code){ - const static int idxtab[16]={3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0}; + static const int idxtab[16]={3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0}; int v; int pos= s_index+idxtab[code]; code ^= 8>>idxtab[code]; @@ -2185,32 +2058,21 @@ static int mp_decode_layer3(MPADecodeContext *s) g->scalefac_compress = get_bits(&s->gb, 9); else g->scalefac_compress = get_bits(&s->gb, 4); - blocksplit_flag = get_bits(&s->gb, 1); + blocksplit_flag = get_bits1(&s->gb); if (blocksplit_flag) { g->block_type = get_bits(&s->gb, 2); if (g->block_type == 0){ av_log(NULL, AV_LOG_ERROR, "invalid block type\n"); return -1; } - g->switch_point = get_bits(&s->gb, 1); + g->switch_point = get_bits1(&s->gb); for(i=0;i<2;i++) g->table_select[i] = get_bits(&s->gb, 5); for(i=0;i<3;i++) g->subblock_gain[i] = get_bits(&s->gb, 3); - /* compute huffman coded region sizes */ - if (g->block_type == 2) - g->region_size[0] = (36 / 2); - else { - if (s->sample_rate_index <= 2) - g->region_size[0] = (36 / 2); - else if (s->sample_rate_index != 8) - g->region_size[0] = (54 / 2); - else - g->region_size[0] = (108 / 2); - } - g->region_size[1] = (576 / 2); + ff_init_short_region(s, g); } else { - int region_address1, region_address2, l; + int region_address1, region_address2; g->block_type = 0; g->switch_point = 0; for(i=0;i<3;i++) @@ -2220,53 +2082,16 @@ static int mp_decode_layer3(MPADecodeContext *s) region_address2 = get_bits(&s->gb, 3); dprintf(s->avctx, "region1=%d region2=%d\n", region_address1, region_address2); - g->region_size[0] = - band_index_long[s->sample_rate_index][region_address1 + 1] >> 1; - l = region_address1 + region_address2 + 2; - /* should not overflow */ - if (l > 22) - l = 22; - g->region_size[1] = - band_index_long[s->sample_rate_index][l] >> 1; - } - /* convert region offsets to region sizes and truncate - size to big_values */ - g->region_size[2] = (576 / 2); - j = 0; - for(i=0;i<3;i++) { - k = FFMIN(g->region_size[i], g->big_values); - g->region_size[i] = k - j; - j = k; - } - - /* compute band indexes */ - if (g->block_type == 2) { - if (g->switch_point) { - /* if switched mode, we handle the 36 first samples as - long blocks. For 8000Hz, we handle the 48 first - exponents as long blocks (XXX: check this!) */ - if (s->sample_rate_index <= 2) - g->long_end = 8; - else if (s->sample_rate_index != 8) - g->long_end = 6; - else - g->long_end = 4; /* 8000 Hz */ - - g->short_start = 2 + (s->sample_rate_index != 8); - } else { - g->long_end = 0; - g->short_start = 0; - } - } else { - g->short_start = 13; - g->long_end = 22; + ff_init_long_region(s, g, region_address1, region_address2); } + ff_region_offset2size(g); + ff_compute_band_indexes(s, g); g->preflag = 0; if (!s->lsf) - g->preflag = get_bits(&s->gb, 1); - g->scalefac_scale = get_bits(&s->gb, 1); - g->count1table_select = get_bits(&s->gb, 1); + g->preflag = get_bits1(&s->gb); + g->scalefac_scale = get_bits1(&s->gb); + g->count1table_select = get_bits1(&s->gb); dprintf(s->avctx, "block_type=%d switch_point=%d\n", g->block_type, g->switch_point); } @@ -2289,7 +2114,7 @@ static int mp_decode_layer3(MPADecodeContext *s) for(ch=0;ch<s->nb_channels;ch++) { g = &granules[ch][gr]; if(get_bits_count(&s->gb)<0){ - av_log(NULL, AV_LOG_ERROR, "mdb:%d, lastbuf:%d skiping granule %d\n", + av_log(NULL, AV_LOG_ERROR, "mdb:%d, lastbuf:%d skipping granule %d\n", main_data_begin, s->last_buf_size, gr); skip_bits_long(&s->gb, g->part2_3_length); memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid)); @@ -2471,7 +2296,7 @@ static int mp_decode_frame(MPADecodeContext *s, /* skip error protection field */ if (s->error_protection) - get_bits(&s->gb, 16); + skip_bits(&s->gb, 16); dprintf(s->avctx, "frame %d:\n", s->frame_count); switch(s->layer) { @@ -2542,7 +2367,7 @@ static int mp_decode_frame(MPADecodeContext *s, static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, - uint8_t * buf, int buf_size) + const uint8_t * buf, int buf_size) { MPADecodeContext *s = avctx->priv_data; uint32_t header; @@ -2553,7 +2378,7 @@ retry: if(buf_size < HEADER_SIZE) return -1; - header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + header = AV_RB32(buf); if(ff_mpa_check_header(header) < 0){ buf++; // buf_size--; @@ -2561,7 +2386,7 @@ retry: goto retry; } - if (decode_header(s, header) == 1) { + if (ff_mpegaudio_decode_header(s, header) == 1) { /* free format: prepare to compute frame size */ s->frame_size = -1; return -1; @@ -2590,6 +2415,7 @@ retry: return -1; }else if(s->frame_size < buf_size){ av_log(avctx, AV_LOG_ERROR, "incorrect frame size\n"); + buf_size= s->frame_size; } out_size = mp_decode_frame(s, out_samples, buf, buf_size); @@ -2605,13 +2431,14 @@ retry: static void flush(AVCodecContext *avctx){ MPADecodeContext *s = avctx->priv_data; + memset(s->synth_buf, 0, sizeof(s->synth_buf)); s->last_buf_size= 0; } #ifdef CONFIG_MP3ADU_DECODER static int decode_frame_adu(AVCodecContext * avctx, void *data, int *data_size, - uint8_t * buf, int buf_size) + const uint8_t * buf, int buf_size) { MPADecodeContext *s = avctx->priv_data; uint32_t header; @@ -2631,14 +2458,14 @@ static int decode_frame_adu(AVCodecContext * avctx, len = MPA_MAX_CODED_FRAME_SIZE; // Get header and restore sync word - header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3] | 0xffe00000; + header = AV_RB32(buf) | 0xffe00000; if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame *data_size = 0; return buf_size; } - decode_header(s, header); + ff_mpegaudio_decode_header(s, header); /* update codec info */ avctx->sample_rate = s->sample_rate; avctx->channels = s->nb_channels; @@ -2697,7 +2524,7 @@ static int decode_init_mp3on4(AVCodecContext * avctx) /* Init the first mp3 decoder in standard way, so that all tables get builded * We replace avctx->priv_data with the context of the first decoder so that * decode_init() does not have to be changed. - * Other decoders will be inited here copying data from the first context + * Other decoders will be initialized here copying data from the first context */ // Allocate zeroed memory for the first decoder context s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext)); @@ -2737,7 +2564,7 @@ static int decode_close_mp3on4(AVCodecContext * avctx) static int decode_frame_mp3on4(AVCodecContext * avctx, void *data, int *data_size, - uint8_t * buf, int buf_size) + const uint8_t * buf, int buf_size) { MP3On4DecodeContext *s = avctx->priv_data; MPADecodeContext *m; @@ -2747,7 +2574,7 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, OUT_INT decoded_buf[MPA_FRAME_SIZE * MPA_MAX_CHANNELS]; OUT_INT *outptr, *bp; int fsize; - unsigned char *start2 = buf, *start; + const unsigned char *start2 = buf, *start; int fr, i, j, n; int off = avctx->channels; int *coff = chan_offset[s->chan_cfg]; @@ -2776,14 +2603,14 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, assert (m != NULL); // Get header - header = (start[0] << 24) | (start[1] << 16) | (start[2] << 8) | start[3] | 0xfff00000; + header = AV_RB32(start) | 0xfff00000; if (ff_mpa_check_header(header) < 0) { // Bad header, discard block *data_size = 0; return buf_size; } - decode_header(m, header); + ff_mpegaudio_decode_header(m, header); mp_decode_frame(m, decoded_buf, start, fsize); n = MPA_FRAME_SIZE * m->nb_channels; @@ -2830,6 +2657,7 @@ AVCodec mp2_decoder = NULL, decode_frame, CODEC_CAP_PARSE_ONLY, + .flush= flush, }; #endif #ifdef CONFIG_MP3_DECODER diff --git a/contrib/ffmpeg/libavcodec/mpegaudiodecheader.c b/contrib/ffmpeg/libavcodec/mpegaudiodecheader.c new file mode 100644 index 000000000..efea49961 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpegaudiodecheader.c @@ -0,0 +1,109 @@ +/* + * MPEG Audio header decoder + * Copyright (c) 2001, 2002 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 mpegaudiodecheader.c + * MPEG Audio header decoder. + */ + +//#define DEBUG +#include "avcodec.h" +#include "mpegaudio.h" +#include "mpegaudiodata.h" + + +int ff_mpegaudio_decode_header(MPADecodeContext *s, uint32_t header) +{ + int sample_rate, frame_size, mpeg25, padding; + int sample_rate_index, bitrate_index; + if (header & (1<<20)) { + s->lsf = (header & (1<<19)) ? 0 : 1; + mpeg25 = 0; + } else { + s->lsf = 1; + mpeg25 = 1; + } + + s->layer = 4 - ((header >> 17) & 3); + /* extract frequency */ + sample_rate_index = (header >> 10) & 3; + sample_rate = ff_mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25); + sample_rate_index += 3 * (s->lsf + mpeg25); + s->sample_rate_index = sample_rate_index; + s->error_protection = ((header >> 16) & 1) ^ 1; + s->sample_rate = sample_rate; + + bitrate_index = (header >> 12) & 0xf; + padding = (header >> 9) & 1; + //extension = (header >> 8) & 1; + s->mode = (header >> 6) & 3; + s->mode_ext = (header >> 4) & 3; + //copyright = (header >> 3) & 1; + //original = (header >> 2) & 1; + //emphasis = header & 3; + + if (s->mode == MPA_MONO) + s->nb_channels = 1; + else + s->nb_channels = 2; + + if (bitrate_index != 0) { + frame_size = ff_mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index]; + s->bit_rate = frame_size * 1000; + switch(s->layer) { + case 1: + frame_size = (frame_size * 12000) / sample_rate; + frame_size = (frame_size + padding) * 4; + break; + case 2: + frame_size = (frame_size * 144000) / sample_rate; + frame_size += padding; + break; + default: + case 3: + frame_size = (frame_size * 144000) / (sample_rate << s->lsf); + frame_size += padding; + break; + } + s->frame_size = frame_size; + } else { + /* if no frame size computed, signal it */ + return 1; + } + +#if defined(DEBUG) + dprintf(s->avctx, "layer%d, %d Hz, %d kbits/s, ", + s->layer, s->sample_rate, s->bit_rate); + if (s->nb_channels == 2) { + if (s->layer == 3) { + if (s->mode_ext & MODE_EXT_MS_STEREO) + dprintf(s->avctx, "ms-"); + if (s->mode_ext & MODE_EXT_I_STEREO) + dprintf(s->avctx, "i-"); + } + dprintf(s->avctx, "stereo"); + } else { + dprintf(s->avctx, "mono"); + } + dprintf(s->avctx, "\n"); +#endif + return 0; +} diff --git a/contrib/ffmpeg/libavcodec/mpegaudiodecheader.h b/contrib/ffmpeg/libavcodec/mpegaudiodecheader.h new file mode 100644 index 000000000..21e8cf016 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpegaudiodecheader.h @@ -0,0 +1,39 @@ +/* + * MPEG Audio header decoder + * Copyright (c) 2001, 2002 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 mpegaudiodecheader.c + * MPEG Audio header decoder. + */ + +#ifndef FFMPEG_MPEGAUDIODECHEADER_H +#define FFMPEG_MPEGAUDIODECHEADER_H + +#include "common.h" +#include "mpegaudio.h" + + +/* header decoding. MUST check the header before because no + consistency check is done there. Return 1 if free format found and + that the frame size must be computed externally */ +int ff_mpegaudio_decode_header(MPADecodeContext *s, uint32_t header); + +#endif /* FFMPEG_MPEGAUDIODECHEADER_H */ diff --git a/contrib/ffmpeg/libavcodec/mpegaudiodectab.h b/contrib/ffmpeg/libavcodec/mpegaudiodectab.h index fdd1096fc..a41ff7aaa 100644 --- a/contrib/ffmpeg/libavcodec/mpegaudiodectab.h +++ b/contrib/ffmpeg/libavcodec/mpegaudiodectab.h @@ -24,202 +24,11 @@ * mpeg audio layer decoder tables. */ -const uint16_t mpa_bitrate_tab[2][3][15] = { - { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, - {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, - {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } }, - { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} - } -}; - -const uint16_t mpa_freq_tab[3] = { 44100, 48000, 32000 }; +#ifndef FFMPEG_MPEGAUDIODECTAB_H +#define FFMPEG_MPEGAUDIODECTAB_H -/*******************************************************/ -/* half mpeg encoding window (full precision) */ -const int32_t mpa_enwindow[257] = { - 0, -1, -1, -1, -1, -1, -1, -2, - -2, -2, -2, -3, -3, -4, -4, -5, - -5, -6, -7, -7, -8, -9, -10, -11, - -13, -14, -16, -17, -19, -21, -24, -26, - -29, -31, -35, -38, -41, -45, -49, -53, - -58, -63, -68, -73, -79, -85, -91, -97, - -104, -111, -117, -125, -132, -139, -147, -154, - -161, -169, -176, -183, -190, -196, -202, -208, - 213, 218, 222, 225, 227, 228, 228, 227, - 224, 221, 215, 208, 200, 189, 177, 163, - 146, 127, 106, 83, 57, 29, -2, -36, - -72, -111, -153, -197, -244, -294, -347, -401, - -459, -519, -581, -645, -711, -779, -848, -919, - -991, -1064, -1137, -1210, -1283, -1356, -1428, -1498, - -1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962, - -2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063, - 2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535, - 1414, 1280, 1131, 970, 794, 605, 402, 185, - -45, -288, -545, -814, -1095, -1388, -1692, -2006, - -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, - -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, - -7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585, - -9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750, - -9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134, - 6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082, - 70, -998, -2122, -3300, -4533, -5818, -7154, -8540, - -9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189, --22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640, --37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137, --51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684, --64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420, --72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992, - 75038, -}; - -/*******************************************************/ -/* layer 2 tables */ - -const int sblimit_table[5] = { 27 , 30 , 8, 12 , 30 }; - -const int quant_steps[17] = { - 3, 5, 7, 9, 15, - 31, 63, 127, 255, 511, - 1023, 2047, 4095, 8191, 16383, - 32767, 65535 -}; - -/* we use a negative value if grouped */ -const int quant_bits[17] = { - -5, -7, 3, -10, 4, - 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, - 15, 16 -}; - -/* encoding tables which give the quantization index. Note how it is - possible to store them efficiently ! */ -static const unsigned char alloc_table_0[] = { - 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, -}; - -static const unsigned char alloc_table_1[] = { - 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 3, 0, 1, 2, 3, 4, 5, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, - 2, 0, 1, 16, -}; - -static const unsigned char alloc_table_2[] = { - 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, -}; - -static const unsigned char alloc_table_3[] = { - 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, -}; - -static const unsigned char alloc_table_4[] = { - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 3, 0, 1, 3, 4, 5, 6, 7, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, - 2, 0, 1, 3, -}; - -const unsigned char *alloc_tables[5] = -{ alloc_table_0, alloc_table_1, alloc_table_2, alloc_table_3, alloc_table_4, }; +#include <stdint.h> +#include "mpegaudio.h" /*******************************************************/ /* layer 3 tables */ @@ -793,3 +602,5 @@ static const uint8_t mpa_pretab[2][22] = { static const float ci_table[8] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037, }; + +#endif /* FFMPEG_MPEGAUDIODECTAB_H */ diff --git a/contrib/ffmpeg/libavcodec/mpegaudioenc.c b/contrib/ffmpeg/libavcodec/mpegaudioenc.c new file mode 100644 index 000000000..ede44927c --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpegaudioenc.c @@ -0,0 +1,801 @@ +/* + * The simplest mpeg audio layer 2 encoder + * Copyright (c) 2000, 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 mpegaudio.c + * The simplest mpeg audio layer 2 encoder. + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "mpegaudio.h" + +/* currently, cannot change these constants (need to modify + quantization stage) */ +#define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS) + +#define SAMPLES_BUF_SIZE 4096 + +typedef struct MpegAudioContext { + PutBitContext pb; + int nb_channels; + int freq, bit_rate; + int lsf; /* 1 if mpeg2 low bitrate selected */ + int bitrate_index; /* bit rate */ + int freq_index; + int frame_size; /* frame size, in bits, without padding */ + int64_t nb_samples; /* total number of samples encoded */ + /* padding computation */ + int frame_frac, frame_frac_incr, do_padding; + short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */ + int samples_offset[MPA_MAX_CHANNELS]; /* offset in samples_buf */ + int sb_samples[MPA_MAX_CHANNELS][3][12][SBLIMIT]; + unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3]; /* scale factors */ + /* code to group 3 scale factors */ + unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT]; + int sblimit; /* number of used subbands */ + const unsigned char *alloc_table; +} MpegAudioContext; + +/* define it to use floats in quantization (I don't like floats !) */ +//#define USE_FLOATS + +#include "mpegaudiodata.h" +#include "mpegaudiotab.h" + +static int MPA_encode_init(AVCodecContext *avctx) +{ + MpegAudioContext *s = avctx->priv_data; + int freq = avctx->sample_rate; + int bitrate = avctx->bit_rate; + int channels = avctx->channels; + int i, v, table; + float a; + + if (channels <= 0 || channels > 2){ + av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels); + return -1; + } + bitrate = bitrate / 1000; + s->nb_channels = channels; + s->freq = freq; + s->bit_rate = bitrate * 1000; + avctx->frame_size = MPA_FRAME_SIZE; + + /* encoding freq */ + s->lsf = 0; + for(i=0;i<3;i++) { + if (ff_mpa_freq_tab[i] == freq) + break; + if ((ff_mpa_freq_tab[i] / 2) == freq) { + s->lsf = 1; + break; + } + } + if (i == 3){ + av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq); + return -1; + } + s->freq_index = i; + + /* encoding bitrate & frequency */ + for(i=0;i<15;i++) { + if (ff_mpa_bitrate_tab[s->lsf][1][i] == bitrate) + break; + } + if (i == 15){ + av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate); + return -1; + } + s->bitrate_index = i; + + /* compute total header size & pad bit */ + + a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0); + s->frame_size = ((int)a) * 8; + + /* frame fractional size to compute padding */ + s->frame_frac = 0; + s->frame_frac_incr = (int)((a - floor(a)) * 65536.0); + + /* select the right allocation table */ + table = ff_mpa_l2_select_table(bitrate, s->nb_channels, freq, s->lsf); + + /* number of used subbands */ + s->sblimit = ff_mpa_sblimit_table[table]; + s->alloc_table = ff_mpa_alloc_tables[table]; + +#ifdef DEBUG + av_log(avctx, AV_LOG_DEBUG, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n", + bitrate, freq, s->frame_size, table, s->frame_frac_incr); +#endif + + for(i=0;i<s->nb_channels;i++) + s->samples_offset[i] = 0; + + for(i=0;i<257;i++) { + int v; + v = ff_mpa_enwindow[i]; +#if WFRAC_BITS != 16 + v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS); +#endif + filter_bank[i] = v; + if ((i & 63) != 0) + v = -v; + if (i != 0) + filter_bank[512 - i] = v; + } + + for(i=0;i<64;i++) { + v = (int)(pow(2.0, (3 - i) / 3.0) * (1 << 20)); + if (v <= 0) + v = 1; + scale_factor_table[i] = v; +#ifdef USE_FLOATS + scale_factor_inv_table[i] = pow(2.0, -(3 - i) / 3.0) / (float)(1 << 20); +#else +#define P 15 + scale_factor_shift[i] = 21 - P - (i / 3); + scale_factor_mult[i] = (1 << P) * pow(2.0, (i % 3) / 3.0); +#endif + } + for(i=0;i<128;i++) { + v = i - 64; + if (v <= -3) + v = 0; + else if (v < 0) + v = 1; + else if (v == 0) + v = 2; + else if (v < 3) + v = 3; + else + v = 4; + scale_diff_table[i] = v; + } + + for(i=0;i<17;i++) { + v = ff_mpa_quant_bits[i]; + if (v < 0) + v = -v; + else + v = v * 3; + total_quant_bits[i] = 12 * v; + } + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + + return 0; +} + +/* 32 point floating point IDCT without 1/sqrt(2) coef zero scaling */ +static void idct32(int *out, int *tab) +{ + int i, j; + int *t, *t1, xr; + const int *xp = costab32; + + for(j=31;j>=3;j-=2) tab[j] += tab[j - 2]; + + t = tab + 30; + t1 = tab + 2; + do { + t[0] += t[-4]; + t[1] += t[1 - 4]; + t -= 4; + } while (t != t1); + + t = tab + 28; + t1 = tab + 4; + do { + t[0] += t[-8]; + t[1] += t[1-8]; + t[2] += t[2-8]; + t[3] += t[3-8]; + t -= 8; + } while (t != t1); + + t = tab; + t1 = tab + 32; + do { + t[ 3] = -t[ 3]; + t[ 6] = -t[ 6]; + + t[11] = -t[11]; + t[12] = -t[12]; + t[13] = -t[13]; + t[15] = -t[15]; + t += 16; + } while (t != t1); + + + t = tab; + t1 = tab + 8; + do { + int x1, x2, x3, x4; + + x3 = MUL(t[16], FIX(SQRT2*0.5)); + x4 = t[0] - x3; + x3 = t[0] + x3; + + x2 = MUL(-(t[24] + t[8]), FIX(SQRT2*0.5)); + x1 = MUL((t[8] - x2), xp[0]); + x2 = MUL((t[8] + x2), xp[1]); + + t[ 0] = x3 + x1; + t[ 8] = x4 - x2; + t[16] = x4 + x2; + t[24] = x3 - x1; + t++; + } while (t != t1); + + xp += 2; + t = tab; + t1 = tab + 4; + do { + xr = MUL(t[28],xp[0]); + t[28] = (t[0] - xr); + t[0] = (t[0] + xr); + + xr = MUL(t[4],xp[1]); + t[ 4] = (t[24] - xr); + t[24] = (t[24] + xr); + + xr = MUL(t[20],xp[2]); + t[20] = (t[8] - xr); + t[ 8] = (t[8] + xr); + + xr = MUL(t[12],xp[3]); + t[12] = (t[16] - xr); + t[16] = (t[16] + xr); + t++; + } while (t != t1); + xp += 4; + + for (i = 0; i < 4; i++) { + xr = MUL(tab[30-i*4],xp[0]); + tab[30-i*4] = (tab[i*4] - xr); + tab[ i*4] = (tab[i*4] + xr); + + xr = MUL(tab[ 2+i*4],xp[1]); + tab[ 2+i*4] = (tab[28-i*4] - xr); + tab[28-i*4] = (tab[28-i*4] + xr); + + xr = MUL(tab[31-i*4],xp[0]); + tab[31-i*4] = (tab[1+i*4] - xr); + tab[ 1+i*4] = (tab[1+i*4] + xr); + + xr = MUL(tab[ 3+i*4],xp[1]); + tab[ 3+i*4] = (tab[29-i*4] - xr); + tab[29-i*4] = (tab[29-i*4] + xr); + + xp += 2; + } + + t = tab + 30; + t1 = tab + 1; + do { + xr = MUL(t1[0], *xp); + t1[0] = (t[0] - xr); + t[0] = (t[0] + xr); + t -= 2; + t1 += 2; + xp++; + } while (t >= tab); + + for(i=0;i<32;i++) { + out[i] = tab[bitinv32[i]]; + } +} + +#define WSHIFT (WFRAC_BITS + 15 - FRAC_BITS) + +static void filter(MpegAudioContext *s, int ch, short *samples, int incr) +{ + short *p, *q; + int sum, offset, i, j; + int tmp[64]; + int tmp1[32]; + int *out; + + // print_pow1(samples, 1152); + + offset = s->samples_offset[ch]; + out = &s->sb_samples[ch][0][0][0]; + for(j=0;j<36;j++) { + /* 32 samples at once */ + for(i=0;i<32;i++) { + s->samples_buf[ch][offset + (31 - i)] = samples[0]; + samples += incr; + } + + /* filter */ + p = s->samples_buf[ch] + offset; + q = filter_bank; + /* maxsum = 23169 */ + for(i=0;i<64;i++) { + sum = p[0*64] * q[0*64]; + sum += p[1*64] * q[1*64]; + sum += p[2*64] * q[2*64]; + sum += p[3*64] * q[3*64]; + sum += p[4*64] * q[4*64]; + sum += p[5*64] * q[5*64]; + sum += p[6*64] * q[6*64]; + sum += p[7*64] * q[7*64]; + tmp[i] = sum; + p++; + q++; + } + tmp1[0] = tmp[16] >> WSHIFT; + for( i=1; i<=16; i++ ) tmp1[i] = (tmp[i+16]+tmp[16-i]) >> WSHIFT; + for( i=17; i<=31; i++ ) tmp1[i] = (tmp[i+16]-tmp[80-i]) >> WSHIFT; + + idct32(out, tmp1); + + /* advance of 32 samples */ + offset -= 32; + out += 32; + /* handle the wrap around */ + if (offset < 0) { + memmove(s->samples_buf[ch] + SAMPLES_BUF_SIZE - (512 - 32), + s->samples_buf[ch], (512 - 32) * 2); + offset = SAMPLES_BUF_SIZE - 512; + } + } + s->samples_offset[ch] = offset; + + // print_pow(s->sb_samples, 1152); +} + +static void compute_scale_factors(unsigned char scale_code[SBLIMIT], + unsigned char scale_factors[SBLIMIT][3], + int sb_samples[3][12][SBLIMIT], + int sblimit) +{ + int *p, vmax, v, n, i, j, k, code; + int index, d1, d2; + unsigned char *sf = &scale_factors[0][0]; + + for(j=0;j<sblimit;j++) { + for(i=0;i<3;i++) { + /* find the max absolute value */ + p = &sb_samples[i][0][j]; + vmax = abs(*p); + for(k=1;k<12;k++) { + p += SBLIMIT; + v = abs(*p); + if (v > vmax) + vmax = v; + } + /* compute the scale factor index using log 2 computations */ + if (vmax > 0) { + n = av_log2(vmax); + /* n is the position of the MSB of vmax. now + use at most 2 compares to find the index */ + index = (21 - n) * 3 - 3; + if (index >= 0) { + while (vmax <= scale_factor_table[index+1]) + index++; + } else { + index = 0; /* very unlikely case of overflow */ + } + } else { + index = 62; /* value 63 is not allowed */ + } + +#if 0 + printf("%2d:%d in=%x %x %d\n", + j, i, vmax, scale_factor_table[index], index); +#endif + /* store the scale factor */ + assert(index >=0 && index <= 63); + sf[i] = index; + } + + /* compute the transmission factor : look if the scale factors + are close enough to each other */ + d1 = scale_diff_table[sf[0] - sf[1] + 64]; + d2 = scale_diff_table[sf[1] - sf[2] + 64]; + + /* handle the 25 cases */ + switch(d1 * 5 + d2) { + case 0*5+0: + case 0*5+4: + case 3*5+4: + case 4*5+0: + case 4*5+4: + code = 0; + break; + case 0*5+1: + case 0*5+2: + case 4*5+1: + case 4*5+2: + code = 3; + sf[2] = sf[1]; + break; + case 0*5+3: + case 4*5+3: + code = 3; + sf[1] = sf[2]; + break; + case 1*5+0: + case 1*5+4: + case 2*5+4: + code = 1; + sf[1] = sf[0]; + break; + case 1*5+1: + case 1*5+2: + case 2*5+0: + case 2*5+1: + case 2*5+2: + code = 2; + sf[1] = sf[2] = sf[0]; + break; + case 2*5+3: + case 3*5+3: + code = 2; + sf[0] = sf[1] = sf[2]; + break; + case 3*5+0: + case 3*5+1: + case 3*5+2: + code = 2; + sf[0] = sf[2] = sf[1]; + break; + case 1*5+3: + code = 2; + if (sf[0] > sf[2]) + sf[0] = sf[2]; + sf[1] = sf[2] = sf[0]; + break; + default: + assert(0); //cannot happen + code = 0; /* kill warning */ + } + +#if 0 + printf("%d: %2d %2d %2d %d %d -> %d\n", j, + sf[0], sf[1], sf[2], d1, d2, code); +#endif + scale_code[j] = code; + sf += 3; + } +} + +/* The most important function : psycho acoustic module. In this + encoder there is basically none, so this is the worst you can do, + but also this is the simpler. */ +static void psycho_acoustic_model(MpegAudioContext *s, short smr[SBLIMIT]) +{ + int i; + + for(i=0;i<s->sblimit;i++) { + smr[i] = (int)(fixed_smr[i] * 10); + } +} + + +#define SB_NOTALLOCATED 0 +#define SB_ALLOCATED 1 +#define SB_NOMORE 2 + +/* Try to maximize the smr while using a number of bits inferior to + the frame size. I tried to make the code simpler, faster and + smaller than other encoders :-) */ +static void compute_bit_allocation(MpegAudioContext *s, + short smr1[MPA_MAX_CHANNELS][SBLIMIT], + unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], + int *padding) +{ + int i, ch, b, max_smr, max_ch, max_sb, current_frame_size, max_frame_size; + int incr; + short smr[MPA_MAX_CHANNELS][SBLIMIT]; + unsigned char subband_status[MPA_MAX_CHANNELS][SBLIMIT]; + const unsigned char *alloc; + + memcpy(smr, smr1, s->nb_channels * sizeof(short) * SBLIMIT); + memset(subband_status, SB_NOTALLOCATED, s->nb_channels * SBLIMIT); + memset(bit_alloc, 0, s->nb_channels * SBLIMIT); + + /* compute frame size and padding */ + max_frame_size = s->frame_size; + s->frame_frac += s->frame_frac_incr; + if (s->frame_frac >= 65536) { + s->frame_frac -= 65536; + s->do_padding = 1; + max_frame_size += 8; + } else { + s->do_padding = 0; + } + + /* compute the header + bit alloc size */ + current_frame_size = 32; + alloc = s->alloc_table; + for(i=0;i<s->sblimit;i++) { + incr = alloc[0]; + current_frame_size += incr * s->nb_channels; + alloc += 1 << incr; + } + for(;;) { + /* look for the subband with the largest signal to mask ratio */ + max_sb = -1; + max_ch = -1; + max_smr = 0x80000000; + for(ch=0;ch<s->nb_channels;ch++) { + for(i=0;i<s->sblimit;i++) { + if (smr[ch][i] > max_smr && subband_status[ch][i] != SB_NOMORE) { + max_smr = smr[ch][i]; + max_sb = i; + max_ch = ch; + } + } + } +#if 0 + printf("current=%d max=%d max_sb=%d alloc=%d\n", + current_frame_size, max_frame_size, max_sb, + bit_alloc[max_sb]); +#endif + if (max_sb < 0) + break; + + /* find alloc table entry (XXX: not optimal, should use + pointer table) */ + alloc = s->alloc_table; + for(i=0;i<max_sb;i++) { + alloc += 1 << alloc[0]; + } + + if (subband_status[max_ch][max_sb] == SB_NOTALLOCATED) { + /* nothing was coded for this band: add the necessary bits */ + incr = 2 + nb_scale_factors[s->scale_code[max_ch][max_sb]] * 6; + incr += total_quant_bits[alloc[1]]; + } else { + /* increments bit allocation */ + b = bit_alloc[max_ch][max_sb]; + incr = total_quant_bits[alloc[b + 1]] - + total_quant_bits[alloc[b]]; + } + + if (current_frame_size + incr <= max_frame_size) { + /* can increase size */ + b = ++bit_alloc[max_ch][max_sb]; + current_frame_size += incr; + /* decrease smr by the resolution we added */ + smr[max_ch][max_sb] = smr1[max_ch][max_sb] - quant_snr[alloc[b]]; + /* max allocation size reached ? */ + if (b == ((1 << alloc[0]) - 1)) + subband_status[max_ch][max_sb] = SB_NOMORE; + else + subband_status[max_ch][max_sb] = SB_ALLOCATED; + } else { + /* cannot increase the size of this subband */ + subband_status[max_ch][max_sb] = SB_NOMORE; + } + } + *padding = max_frame_size - current_frame_size; + assert(*padding >= 0); + +#if 0 + for(i=0;i<s->sblimit;i++) { + printf("%d ", bit_alloc[i]); + } + printf("\n"); +#endif +} + +/* + * Output the mpeg audio layer 2 frame. Note how the code is small + * compared to other encoders :-) + */ +static void encode_frame(MpegAudioContext *s, + unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], + int padding) +{ + int i, j, k, l, bit_alloc_bits, b, ch; + unsigned char *sf; + int q[3]; + PutBitContext *p = &s->pb; + + /* header */ + + put_bits(p, 12, 0xfff); + put_bits(p, 1, 1 - s->lsf); /* 1 = mpeg1 ID, 0 = mpeg2 lsf ID */ + put_bits(p, 2, 4-2); /* layer 2 */ + put_bits(p, 1, 1); /* no error protection */ + put_bits(p, 4, s->bitrate_index); + put_bits(p, 2, s->freq_index); + put_bits(p, 1, s->do_padding); /* use padding */ + put_bits(p, 1, 0); /* private_bit */ + put_bits(p, 2, s->nb_channels == 2 ? MPA_STEREO : MPA_MONO); + put_bits(p, 2, 0); /* mode_ext */ + put_bits(p, 1, 0); /* no copyright */ + put_bits(p, 1, 1); /* original */ + put_bits(p, 2, 0); /* no emphasis */ + + /* bit allocation */ + j = 0; + for(i=0;i<s->sblimit;i++) { + bit_alloc_bits = s->alloc_table[j]; + for(ch=0;ch<s->nb_channels;ch++) { + put_bits(p, bit_alloc_bits, bit_alloc[ch][i]); + } + j += 1 << bit_alloc_bits; + } + + /* scale codes */ + for(i=0;i<s->sblimit;i++) { + for(ch=0;ch<s->nb_channels;ch++) { + if (bit_alloc[ch][i]) + put_bits(p, 2, s->scale_code[ch][i]); + } + } + + /* scale factors */ + for(i=0;i<s->sblimit;i++) { + for(ch=0;ch<s->nb_channels;ch++) { + if (bit_alloc[ch][i]) { + sf = &s->scale_factors[ch][i][0]; + switch(s->scale_code[ch][i]) { + case 0: + put_bits(p, 6, sf[0]); + put_bits(p, 6, sf[1]); + put_bits(p, 6, sf[2]); + break; + case 3: + case 1: + put_bits(p, 6, sf[0]); + put_bits(p, 6, sf[2]); + break; + case 2: + put_bits(p, 6, sf[0]); + break; + } + } + } + } + + /* quantization & write sub band samples */ + + for(k=0;k<3;k++) { + for(l=0;l<12;l+=3) { + j = 0; + for(i=0;i<s->sblimit;i++) { + bit_alloc_bits = s->alloc_table[j]; + for(ch=0;ch<s->nb_channels;ch++) { + b = bit_alloc[ch][i]; + if (b) { + int qindex, steps, m, sample, bits; + /* we encode 3 sub band samples of the same sub band at a time */ + qindex = s->alloc_table[j+b]; + steps = ff_mpa_quant_steps[qindex]; + for(m=0;m<3;m++) { + sample = s->sb_samples[ch][k][l + m][i]; + /* divide by scale factor */ +#ifdef USE_FLOATS + { + float a; + a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]]; + q[m] = (int)((a + 1.0) * steps * 0.5); + } +#else + { + int q1, e, shift, mult; + e = s->scale_factors[ch][i][k]; + shift = scale_factor_shift[e]; + mult = scale_factor_mult[e]; + + /* normalize to P bits */ + if (shift < 0) + q1 = sample << (-shift); + else + q1 = sample >> shift; + q1 = (q1 * mult) >> P; + q[m] = ((q1 + (1 << P)) * steps) >> (P + 1); + } +#endif + if (q[m] >= steps) + q[m] = steps - 1; + assert(q[m] >= 0 && q[m] < steps); + } + bits = ff_mpa_quant_bits[qindex]; + if (bits < 0) { + /* group the 3 values to save bits */ + put_bits(p, -bits, + q[0] + steps * (q[1] + steps * q[2])); +#if 0 + printf("%d: gr1 %d\n", + i, q[0] + steps * (q[1] + steps * q[2])); +#endif + } else { +#if 0 + printf("%d: gr3 %d %d %d\n", + i, q[0], q[1], q[2]); +#endif + put_bits(p, bits, q[0]); + put_bits(p, bits, q[1]); + put_bits(p, bits, q[2]); + } + } + } + /* next subband in alloc table */ + j += 1 << bit_alloc_bits; + } + } + } + + /* padding */ + for(i=0;i<padding;i++) + put_bits(p, 1, 0); + + /* flush */ + flush_put_bits(p); +} + +static int MPA_encode_frame(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) +{ + MpegAudioContext *s = avctx->priv_data; + short *samples = data; + short smr[MPA_MAX_CHANNELS][SBLIMIT]; + unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT]; + int padding, i; + + for(i=0;i<s->nb_channels;i++) { + filter(s, i, samples + i, s->nb_channels); + } + + for(i=0;i<s->nb_channels;i++) { + compute_scale_factors(s->scale_code[i], s->scale_factors[i], + s->sb_samples[i], s->sblimit); + } + for(i=0;i<s->nb_channels;i++) { + psycho_acoustic_model(s, smr[i]); + } + compute_bit_allocation(s, smr, bit_alloc, &padding); + + init_put_bits(&s->pb, frame, MPA_MAX_CODED_FRAME_SIZE); + + encode_frame(s, bit_alloc, padding); + + s->nb_samples += MPA_FRAME_SIZE; + return pbBufPtr(&s->pb) - s->pb.buf; +} + +static int MPA_encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + return 0; +} + +AVCodec mp2_encoder = { + "mp2", + CODEC_TYPE_AUDIO, + CODEC_ID_MP2, + sizeof(MpegAudioContext), + MPA_encode_init, + MPA_encode_frame, + MPA_encode_close, + NULL, +}; + +#undef FIX diff --git a/contrib/ffmpeg/libavcodec/mpegaudiotab.h b/contrib/ffmpeg/libavcodec/mpegaudiotab.h index 8fb37ddff..61ea471b1 100644 --- a/contrib/ffmpeg/libavcodec/mpegaudiotab.h +++ b/contrib/ffmpeg/libavcodec/mpegaudiotab.h @@ -27,6 +27,12 @@ * Most of them come from the mpeg audio specification. */ +#ifndef FFMPEG_MPEGAUDIOTAB_H +#define FFMPEG_MPEGAUDIOTAB_H + +#include <stdint.h> +#include "mpegaudio.h" + #define SQRT2 1.41421356237309514547 static const int costab32[30] = { @@ -109,3 +115,4 @@ static const float fixed_smr[SBLIMIT] = { static const unsigned char nb_scale_factors[4] = { 3, 2, 1, 2 }; +#endif /* FFMPEG_MPEGAUDIOTAB_H */ diff --git a/contrib/ffmpeg/libavcodec/mpegvideo.c b/contrib/ffmpeg/libavcodec/mpegvideo.c index f0069fa1e..76a17d56d 100644 --- a/contrib/ffmpeg/libavcodec/mpegvideo.c +++ b/contrib/ffmpeg/libavcodec/mpegvideo.c @@ -3,6 +3,8 @@ * Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * + * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,8 +20,6 @@ * 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 - * - * 4MV & hq & b-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> */ /** @@ -30,19 +30,15 @@ #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" +#include "mpegvideo_common.h" +#include "mjpegenc.h" +#include "msmpeg4.h" #include "faandct.h" #include <limits.h> -#ifdef USE_FASTMEMCPY -#include "libvo/fastmemcpy.h" -#endif - //#undef NDEBUG //#include <assert.h> -#ifdef CONFIG_ENCODERS -static int encode_picture(MpegEncContext *s, int picture_number); -#endif //CONFIG_ENCODERS static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s, DCTELEM *block, int n, int qscale); static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s, @@ -58,19 +54,10 @@ static void dct_unquantize_h263_intra_c(MpegEncContext *s, static void dct_unquantize_h263_inter_c(MpegEncContext *s, DCTELEM *block, int n, int qscale); static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w); -#ifdef CONFIG_ENCODERS -static int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); -static int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); -static int dct_quantize_refine(MpegEncContext *s, DCTELEM *block, int16_t *weight, DCTELEM *orig, int n, int qscale); -static int sse_mb(MpegEncContext *s); -static void denoise_dct_c(MpegEncContext *s, DCTELEM *block); -#endif //CONFIG_ENCODERS -#ifdef HAVE_XVMC extern int XVMC_field_start(MpegEncContext*s, AVCodecContext *avctx); extern void XVMC_field_end(MpegEncContext *s); extern void XVMC_decode_mb(MpegEncContext *s); -#endif void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w)= draw_edges_c; @@ -81,119 +68,11 @@ void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w)= draw_e //#define DEBUG -/* for jpeg fast DCT */ -#define CONST_BITS 14 - -static const uint16_t aanscales[64] = { - /* precomputed values scaled up by 14 bits */ - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, - 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, - 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, - 8867 , 12299, 11585, 10426, 8867, 6967, 4799, 2446, - 4520 , 6270, 5906, 5315, 4520, 3552, 2446, 1247 -}; - -static const uint8_t h263_chroma_roundtab[16] = { -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, -}; - static const uint8_t ff_default_chroma_qscale_table[32]={ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }; -#ifdef CONFIG_ENCODERS -static uint8_t default_mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; -static uint8_t default_fcode_tab[MAX_MV*2+1]; - -enum PixelFormat ff_yuv420p_list[2]= {PIX_FMT_YUV420P, -1}; - -static void convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64], - const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra) -{ - int qscale; - int shift=0; - - for(qscale=qmin; qscale<=qmax; qscale++){ - int i; - if (dsp->fdct == ff_jpeg_fdct_islow -#ifdef FAAN_POSTSCALE - || dsp->fdct == ff_faandct -#endif - ) { - for(i=0;i<64;i++) { - const int j= dsp->idct_permutation[i]; - /* 16 <= qscale * quant_matrix[i] <= 7905 */ - /* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */ - /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */ - /* 3444240 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */ - - qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / - (qscale * quant_matrix[j])); - } - } else if (dsp->fdct == fdct_ifast -#ifndef FAAN_POSTSCALE - || dsp->fdct == ff_faandct -#endif - ) { - for(i=0;i<64;i++) { - const int j= dsp->idct_permutation[i]; - /* 16 <= qscale * quant_matrix[i] <= 7905 */ - /* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */ - /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */ - /* 3444240 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */ - - qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) / - (aanscales[i] * qscale * quant_matrix[j])); - } - } else { - for(i=0;i<64;i++) { - const int j= dsp->idct_permutation[i]; - /* We can safely suppose that 16 <= quant_matrix[i] <= 255 - So 16 <= qscale * quant_matrix[i] <= 7905 - so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905 - so 32768 >= (1<<19) / (qscale * quant_matrix[i]) >= 67 - */ - qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / (qscale * quant_matrix[j])); -// qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]); - qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]); - - if(qmat16[qscale][0][i]==0 || qmat16[qscale][0][i]==128*256) qmat16[qscale][0][i]=128*256-1; - qmat16[qscale][1][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][0][i]); - } - } - - for(i=intra; i<64; i++){ - int64_t max= 8191; - if (dsp->fdct == fdct_ifast -#ifndef FAAN_POSTSCALE - || dsp->fdct == ff_faandct -#endif - ) { - max= (8191LL*aanscales[i]) >> 14; - } - while(((max * qmat[qscale][i]) >> shift) > INT_MAX){ - shift++; - } - } - } - if(shift){ - av_log(NULL, AV_LOG_INFO, "Warning, QMAT_SHIFT is larger than %d, overflows possible\n", QMAT_SHIFT - shift); - } -} - -static inline void update_qscale(MpegEncContext *s){ - s->qscale= (s->lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); - s->qscale= av_clip(s->qscale, s->avctx->qmin, s->avctx->qmax); - - s->lambda2= (s->lambda*s->lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT; -} -#endif //CONFIG_ENCODERS - void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){ int i; int end; @@ -218,20 +97,6 @@ void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_s } } -#ifdef CONFIG_ENCODERS -void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix){ - int i; - - if(matrix){ - put_bits(pb, 1, 1); - for(i=0;i<64;i++) { - put_bits(pb, 8, matrix[ ff_zigzag_direct[i] ]); - } - }else - put_bits(pb, 1, 0); -} -#endif //CONFIG_ENCODERS - const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){ int i; @@ -257,13 +122,13 @@ const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end } p= FFMIN(p, end)-4; - *state= be2me_32(unaligned32(p)); + *state= AV_RB32(p); return p+4; } /* init common dct for both encoder and decoder */ -int DCT_common_init(MpegEncContext *s) +int ff_dct_common_init(MpegEncContext *s) { s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c; s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c; @@ -274,38 +139,21 @@ int DCT_common_init(MpegEncContext *s) s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact; s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c; -#ifdef CONFIG_ENCODERS - s->dct_quantize= dct_quantize_c; - s->denoise_dct= denoise_dct_c; -#endif //CONFIG_ENCODERS - -#ifdef HAVE_MMX +#if defined(HAVE_MMX) MPV_common_init_mmx(s); -#endif -#ifdef ARCH_ALPHA +#elif defined(ARCH_ALPHA) MPV_common_init_axp(s); -#endif -#ifdef HAVE_MLIB +#elif defined(HAVE_MLIB) MPV_common_init_mlib(s); -#endif -#ifdef HAVE_MMI +#elif defined(HAVE_MMI) MPV_common_init_mmi(s); -#endif -#ifdef ARCH_ARMV4L +#elif defined(ARCH_ARMV4L) MPV_common_init_armv4l(s); +#elif defined(HAVE_ALTIVEC) + MPV_common_init_altivec(s); +#elif defined(ARCH_BFIN) + MPV_common_init_bfin(s); #endif -#ifdef ARCH_POWERPC - MPV_common_init_ppc(s); -#endif - -#ifdef CONFIG_ENCODERS - s->fast_dct_quantize= s->dct_quantize; - - if(s->flags&CODEC_FLAG_TRELLIS_QUANT){ - s->dct_quantize= dct_quantize_trellis_c; //move before MPV_common_init_* - } - -#endif //CONFIG_ENCODERS /* load & permutate scantables note: only wmv uses different ones @@ -323,70 +171,28 @@ int DCT_common_init(MpegEncContext *s) return 0; } -static void copy_picture(Picture *dst, Picture *src){ +void copy_picture(Picture *dst, Picture *src){ *dst = *src; dst->type= FF_BUFFER_TYPE_COPY; } -#ifdef CONFIG_ENCODERS -static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst, AVFrame *src){ - int i; - - dst->pict_type = src->pict_type; - dst->quality = src->quality; - dst->coded_picture_number = src->coded_picture_number; - dst->display_picture_number = src->display_picture_number; -// dst->reference = src->reference; - dst->pts = src->pts; - dst->interlaced_frame = src->interlaced_frame; - dst->top_field_first = src->top_field_first; - - if(s->avctx->me_threshold){ - if(!src->motion_val[0]) - av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_val not set!\n"); - if(!src->mb_type) - av_log(s->avctx, AV_LOG_ERROR, "AVFrame.mb_type not set!\n"); - if(!src->ref_index[0]) - av_log(s->avctx, AV_LOG_ERROR, "AVFrame.ref_index not set!\n"); - if(src->motion_subsample_log2 != dst->motion_subsample_log2) - av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_subsample_log2 doesn't match! (%d!=%d)\n", - src->motion_subsample_log2, dst->motion_subsample_log2); - - memcpy(dst->mb_type, src->mb_type, s->mb_stride * s->mb_height * sizeof(dst->mb_type[0])); - - for(i=0; i<2; i++){ - int stride= ((16*s->mb_width )>>src->motion_subsample_log2) + 1; - int height= ((16*s->mb_height)>>src->motion_subsample_log2); - - if(src->motion_val[i] && src->motion_val[i] != dst->motion_val[i]){ - memcpy(dst->motion_val[i], src->motion_val[i], 2*stride*height*sizeof(int16_t)); - } - if(src->ref_index[i] && src->ref_index[i] != dst->ref_index[i]){ - memcpy(dst->ref_index[i], src->ref_index[i], s->b8_stride*2*s->mb_height*sizeof(int8_t)); - } - } - } -} -#endif - /** * allocates a Picture * The pixels are allocated/set by calling get_buffer() if shared=0 */ -static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){ - const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) doesnt sig11 +int alloc_picture(MpegEncContext *s, Picture *pic, int shared){ + const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) does not sig11 const int mb_array_size= s->mb_stride*s->mb_height; const int b8_array_size= s->b8_stride*s->mb_height*2; const int b4_array_size= s->b4_stride*s->mb_height*4; int i; + int r= -1; if(shared){ assert(pic->data[0]); assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED); pic->type= FF_BUFFER_TYPE_SHARED; }else{ - int r; - assert(!pic->data[0]); r= s->avctx->get_buffer(s->avctx, (AVFrame*)pic); @@ -398,11 +204,13 @@ static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){ if(s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1])){ av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (stride changed)\n"); + s->avctx->release_buffer(s->avctx, (AVFrame*)pic); return -1; } if(pic->linesize[1] != pic->linesize[2]){ av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride mismatch)\n"); + s->avctx->release_buffer(s->avctx, (AVFrame*)pic); return -1; } @@ -419,8 +227,8 @@ static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){ CHECKED_ALLOCZ(pic->mbskip_table , mb_array_size * sizeof(uint8_t)+2) //the +2 is for the slice end check CHECKED_ALLOCZ(pic->qscale_table , mb_array_size * sizeof(uint8_t)) - CHECKED_ALLOCZ(pic->mb_type_base , big_mb_num * sizeof(uint32_t)) - pic->mb_type= pic->mb_type_base + s->mb_stride+1; + CHECKED_ALLOCZ(pic->mb_type_base , (big_mb_num + s->mb_stride) * sizeof(uint32_t)) + pic->mb_type= pic->mb_type_base + 2*s->mb_stride+1; if(s->out_format == FMT_H264){ for(i=0; i<2; i++){ CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b4_array_size+4) * sizeof(int16_t)) @@ -443,14 +251,17 @@ static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){ CHECKED_ALLOCZ(pic->pan_scan , 1 * sizeof(AVPanScan)) } - //it might be nicer if the application would keep track of these but it would require a API change + /* It might be nicer if the application would keep track of these + * but it would require an API change. */ memmove(s->prev_pict_types+1, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE-1); s->prev_pict_types[0]= s->pict_type; if(pic->age < PREV_PICT_TYPES_BUFFER_SIZE && s->prev_pict_types[pic->age] == B_TYPE) - pic->age= INT_MAX; // skipped MBs in b frames are quite rare in mpeg1/2 and its a bit tricky to skip them anyway + pic->age= INT_MAX; // Skipped MBs in B-frames are quite rare in MPEG-1/2 and it is a bit tricky to skip them anyway. return 0; fail: //for the CHECKED_ALLOCZ macro + if(r>=0) + s->avctx->release_buffer(s->avctx, (AVFrame*)pic); return -1; } @@ -494,7 +305,7 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){ CHECKED_ALLOCZ(s->allocated_edge_emu_buffer, (s->width+64)*2*21*2); //(width + edge + align)*interlaced*MBsize*tolerance s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21; - //FIXME should be linesize instead of s->width*2 but that isnt known before get_buffer() + //FIXME should be linesize instead of s->width*2 but that is not known before get_buffer() CHECKED_ALLOCZ(s->me.scratchpad, (s->width+64)*4*16*2*sizeof(uint8_t)) s->rd_scratchpad= s->me.scratchpad; s->b_scratchpad= s->me.scratchpad; @@ -569,30 +380,11 @@ void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src){ //STOP_TIMER("update_duplicate_context") //about 10k cycles / 0.01 sec for 1000frames on 1ghz with 2 threads } -#ifdef CONFIG_ENCODERS -static void update_duplicate_context_after_me(MpegEncContext *dst, MpegEncContext *src){ -#define COPY(a) dst->a= src->a - COPY(pict_type); - COPY(current_picture); - COPY(f_code); - COPY(b_code); - COPY(qscale); - COPY(lambda); - COPY(lambda2); - COPY(picture_in_gop_number); - COPY(gop_picture_number); - COPY(frame_pred_frame_dct); //FIXME don't set in encode_header - COPY(progressive_frame); //FIXME don't set in encode_header - COPY(partitioned_frame); //FIXME don't set in encode_header -#undef COPY -} -#endif - /** * sets the given MpegEncContext to common defaults (same for encoding and decoding). * the changed fields will not depend upon the prior state of the MpegEncContext. */ -static void MPV_common_defaults(MpegEncContext *s){ +void MPV_common_defaults(MpegEncContext *s){ s->y_dc_scale_table= s->c_dc_scale_table= ff_mpeg1_dc_scale_table; s->chroma_qscale_table= ff_default_chroma_qscale_table; @@ -619,30 +411,12 @@ void MPV_decode_defaults(MpegEncContext *s){ } /** - * sets the given MpegEncContext to defaults for encoding. - * the changed fields will not depend upon the prior state of the MpegEncContext. - */ - -#ifdef CONFIG_ENCODERS -static void MPV_encode_defaults(MpegEncContext *s){ - int i; - MPV_common_defaults(s); - - for(i=-16; i<16; i++){ - default_fcode_tab[i + MAX_MV]= 1; - } - s->me.mv_penalty= default_mv_penalty; - s->fcode_tab= default_fcode_tab; -} -#endif //CONFIG_ENCODERS - -/** * init common structure for both encoder and decoder. * this assumes that some variables like width/height are already set */ int MPV_common_init(MpegEncContext *s) { - int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; + int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y, threads; s->mb_height = (s->height + 15) / 16; @@ -655,7 +429,7 @@ int MPV_common_init(MpegEncContext *s) return -1; dsputil_init(&s->dsp, s->avctx); - DCT_common_init(s); + ff_dct_common_init(s); s->flags= s->avctx->flags; s->flags2= s->avctx->flags2; @@ -811,12 +585,14 @@ int MPV_common_init(MpegEncContext *s) s->context_initialized = 1; s->thread_context[0]= s; - for(i=1; i<s->avctx->thread_count; i++){ + threads = s->avctx->thread_count; + + for(i=1; i<threads; i++){ s->thread_context[i]= av_malloc(sizeof(MpegEncContext)); memcpy(s->thread_context[i], s, sizeof(MpegEncContext)); } - for(i=0; i<s->avctx->thread_count; i++){ + for(i=0; i<threads; i++){ if(init_duplicate_context(s->thread_context[i], s) < 0) goto fail; s->thread_context[i]->start_mb_y= (s->mb_height*(i ) + s->avctx->thread_count/2) / s->avctx->thread_count; @@ -913,504 +689,6 @@ void MPV_common_end(MpegEncContext *s) avcodec_default_free_buffers(s->avctx); } -#ifdef CONFIG_ENCODERS - -/* init video encoder */ -int MPV_encode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - int i; - int chroma_h_shift, chroma_v_shift; - - MPV_encode_defaults(s); - - switch (avctx->codec_id) { - case CODEC_ID_MPEG2VIDEO: - if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){ - av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n"); - return -1; - } - break; - case CODEC_ID_LJPEG: - case CODEC_ID_MJPEG: - if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P && - ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P) || avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL)){ - av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n"); - return -1; - } - break; - default: - if(avctx->pix_fmt != PIX_FMT_YUV420P){ - av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n"); - return -1; - } - } - - switch (avctx->pix_fmt) { - case PIX_FMT_YUVJ422P: - case PIX_FMT_YUV422P: - s->chroma_format = CHROMA_422; - break; - case PIX_FMT_YUVJ420P: - case PIX_FMT_YUV420P: - default: - s->chroma_format = CHROMA_420; - break; - } - - s->bit_rate = avctx->bit_rate; - s->width = avctx->width; - s->height = avctx->height; - if(avctx->gop_size > 600 && avctx->strict_std_compliance>FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "Warning keyframe interval too large! reducing it ...\n"); - avctx->gop_size=600; - } - s->gop_size = avctx->gop_size; - s->avctx = avctx; - s->flags= avctx->flags; - s->flags2= avctx->flags2; - s->max_b_frames= avctx->max_b_frames; - s->codec_id= avctx->codec->id; - s->luma_elim_threshold = avctx->luma_elim_threshold; - s->chroma_elim_threshold= avctx->chroma_elim_threshold; - s->strict_std_compliance= avctx->strict_std_compliance; - s->data_partitioning= avctx->flags & CODEC_FLAG_PART; - s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0; - s->mpeg_quant= avctx->mpeg_quant; - s->rtp_mode= !!avctx->rtp_payload_size; - s->intra_dc_precision= avctx->intra_dc_precision; - s->user_specified_pts = AV_NOPTS_VALUE; - - if (s->gop_size <= 1) { - s->intra_only = 1; - s->gop_size = 12; - } else { - s->intra_only = 0; - } - - s->me_method = avctx->me_method; - - /* Fixed QSCALE */ - s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE); - - s->adaptive_quant= ( s->avctx->lumi_masking - || s->avctx->dark_masking - || s->avctx->temporal_cplx_masking - || s->avctx->spatial_cplx_masking - || s->avctx->p_masking - || s->avctx->border_masking - || (s->flags&CODEC_FLAG_QP_RD)) - && !s->fixed_qscale; - - s->obmc= !!(s->flags & CODEC_FLAG_OBMC); - s->loop_filter= !!(s->flags & CODEC_FLAG_LOOP_FILTER); - s->alternate_scan= !!(s->flags & CODEC_FLAG_ALT_SCAN); - s->intra_vlc_format= !!(s->flags2 & CODEC_FLAG2_INTRA_VLC); - s->q_scale_type= !!(s->flags2 & CODEC_FLAG2_NON_LINEAR_QUANT); - - if(avctx->rc_max_rate && !avctx->rc_buffer_size){ - av_log(avctx, AV_LOG_ERROR, "a vbv buffer size is needed, for encoding with a maximum bitrate\n"); - return -1; - } - - if(avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate){ - av_log(avctx, AV_LOG_INFO, "Warning min_rate > 0 but min_rate != max_rate isn't recommended!\n"); - } - - if(avctx->rc_min_rate && avctx->rc_min_rate > avctx->bit_rate){ - av_log(avctx, AV_LOG_INFO, "bitrate below min bitrate\n"); - return -1; - } - - if(avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate){ - av_log(avctx, AV_LOG_INFO, "bitrate above max bitrate\n"); - return -1; - } - - if( s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate - && (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO) - && 90000LL * (avctx->rc_buffer_size-1) > s->avctx->rc_max_rate*0xFFFFLL){ - - av_log(avctx, AV_LOG_INFO, "Warning vbv_delay will be set to 0xFFFF (=VBR) as the specified vbv buffer is too large for the given bitrate!\n"); - } - - if((s->flags & CODEC_FLAG_4MV) && s->codec_id != CODEC_ID_MPEG4 - && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P && s->codec_id != CODEC_ID_FLV1){ - av_log(avctx, AV_LOG_ERROR, "4MV not supported by codec\n"); - return -1; - } - - if(s->obmc && s->avctx->mb_decision != FF_MB_DECISION_SIMPLE){ - av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with simple mb decision\n"); - return -1; - } - - if(s->obmc && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P){ - av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with H263(+)\n"); - return -1; - } - - if(s->quarter_sample && s->codec_id != CODEC_ID_MPEG4){ - av_log(avctx, AV_LOG_ERROR, "qpel not supported by codec\n"); - return -1; - } - - if(s->data_partitioning && s->codec_id != CODEC_ID_MPEG4){ - av_log(avctx, AV_LOG_ERROR, "data partitioning not supported by codec\n"); - return -1; - } - - if(s->max_b_frames && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO){ - av_log(avctx, AV_LOG_ERROR, "b frames not supported by codec\n"); - return -1; - } - - if((s->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN)) - && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG2VIDEO){ - av_log(avctx, AV_LOG_ERROR, "interlacing not supported by codec\n"); - return -1; - } - - if(s->mpeg_quant && s->codec_id != CODEC_ID_MPEG4){ //FIXME mpeg2 uses that too - av_log(avctx, AV_LOG_ERROR, "mpeg2 style quantization not supported by codec\n"); - return -1; - } - - if((s->flags & CODEC_FLAG_CBP_RD) && !(s->flags & CODEC_FLAG_TRELLIS_QUANT)){ - av_log(avctx, AV_LOG_ERROR, "CBP RD needs trellis quant\n"); - return -1; - } - - if((s->flags & CODEC_FLAG_QP_RD) && s->avctx->mb_decision != FF_MB_DECISION_RD){ - av_log(avctx, AV_LOG_ERROR, "QP RD needs mbd=2\n"); - return -1; - } - - if(s->avctx->scenechange_threshold < 1000000000 && (s->flags & CODEC_FLAG_CLOSED_GOP)){ - av_log(avctx, AV_LOG_ERROR, "closed gop with scene change detection arent supported yet, set threshold to 1000000000\n"); - return -1; - } - - if((s->flags2 & CODEC_FLAG2_INTRA_VLC) && s->codec_id != CODEC_ID_MPEG2VIDEO){ - av_log(avctx, AV_LOG_ERROR, "intra vlc table not supported by codec\n"); - return -1; - } - - if(s->flags & CODEC_FLAG_LOW_DELAY){ - if (s->codec_id != CODEC_ID_MPEG2VIDEO && s->codec_id != CODEC_ID_MPEG1VIDEO){ - av_log(avctx, AV_LOG_ERROR, "low delay forcing is only available for mpeg1/2\n"); - return -1; - } - if (s->max_b_frames != 0){ - av_log(avctx, AV_LOG_ERROR, "b frames cannot be used with low delay\n"); - return -1; - } - } - - if(s->q_scale_type == 1){ - if(s->codec_id != CODEC_ID_MPEG2VIDEO){ - av_log(avctx, AV_LOG_ERROR, "non linear quant is only available for mpeg2\n"); - return -1; - } - if(avctx->qmax > 12){ - av_log(avctx, AV_LOG_ERROR, "non linear quant only supports qmax <= 12 currently\n"); - return -1; - } - } - - if(s->avctx->thread_count > 1 && s->codec_id != CODEC_ID_MPEG4 - && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO - && (s->codec_id != CODEC_ID_H263P || !(s->flags & CODEC_FLAG_H263P_SLICE_STRUCT))){ - av_log(avctx, AV_LOG_ERROR, "multi threaded encoding not supported by codec\n"); - return -1; - } - - if(s->avctx->thread_count > 1) - s->rtp_mode= 1; - - if(!avctx->time_base.den || !avctx->time_base.num){ - av_log(avctx, AV_LOG_ERROR, "framerate not set\n"); - return -1; - } - - i= (INT_MAX/2+128)>>8; - if(avctx->me_threshold >= i){ - av_log(avctx, AV_LOG_ERROR, "me_threshold too large, max is %d\n", i - 1); - return -1; - } - if(avctx->mb_threshold >= i){ - av_log(avctx, AV_LOG_ERROR, "mb_threshold too large, max is %d\n", i - 1); - return -1; - } - - if(avctx->b_frame_strategy && (avctx->flags&CODEC_FLAG_PASS2)){ - av_log(avctx, AV_LOG_INFO, "notice: b_frame_strategy only affects the first pass\n"); - avctx->b_frame_strategy = 0; - } - - i= ff_gcd(avctx->time_base.den, avctx->time_base.num); - if(i > 1){ - av_log(avctx, AV_LOG_INFO, "removing common factors from framerate\n"); - avctx->time_base.den /= i; - avctx->time_base.num /= i; -// return -1; - } - - if(s->codec_id==CODEC_ID_MJPEG){ - s->intra_quant_bias= 1<<(QUANT_BIAS_SHIFT-1); //(a + x/2)/x - s->inter_quant_bias= 0; - }else if(s->mpeg_quant || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO){ - s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x - s->inter_quant_bias= 0; - }else{ - s->intra_quant_bias=0; - s->inter_quant_bias=-(1<<(QUANT_BIAS_SHIFT-2)); //(a - x/4)/x - } - - if(avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS) - s->intra_quant_bias= avctx->intra_quant_bias; - if(avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS) - s->inter_quant_bias= avctx->inter_quant_bias; - - avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift); - - if(avctx->codec_id == CODEC_ID_MPEG4 && s->avctx->time_base.den > (1<<16)-1){ - av_log(avctx, AV_LOG_ERROR, "timebase not supported by mpeg 4 standard\n"); - return -1; - } - s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; - - switch(avctx->codec->id) { - case CODEC_ID_MPEG1VIDEO: - s->out_format = FMT_MPEG1; - s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY); - avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); - break; - case CODEC_ID_MPEG2VIDEO: - s->out_format = FMT_MPEG1; - s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY); - avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); - s->rtp_mode= 1; - break; - case CODEC_ID_LJPEG: - case CODEC_ID_JPEGLS: - case CODEC_ID_MJPEG: - s->out_format = FMT_MJPEG; - s->intra_only = 1; /* force intra only for jpeg */ - s->mjpeg_write_tables = avctx->codec->id != CODEC_ID_JPEGLS; - s->mjpeg_data_only_frames = 0; /* write all the needed headers */ - s->mjpeg_vsample[0] = 2; - s->mjpeg_vsample[1] = 2>>chroma_v_shift; - s->mjpeg_vsample[2] = 2>>chroma_v_shift; - s->mjpeg_hsample[0] = 2; - s->mjpeg_hsample[1] = 2>>chroma_h_shift; - s->mjpeg_hsample[2] = 2>>chroma_h_shift; - if (mjpeg_init(s) < 0) - return -1; - avctx->delay=0; - s->low_delay=1; - break; -#ifdef CONFIG_H261_ENCODER - case CODEC_ID_H261: - if (ff_h261_get_picture_format(s->width, s->height) < 0) { - av_log(avctx, AV_LOG_ERROR, "The specified picture size of %dx%d is not valid for the H.261 codec.\nValid sizes are 176x144, 352x288\n", s->width, s->height); - return -1; - } - s->out_format = FMT_H261; - avctx->delay=0; - s->low_delay=1; - break; -#endif - case CODEC_ID_H263: - if (h263_get_picture_format(s->width, s->height) == 7) { - av_log(avctx, AV_LOG_INFO, "The specified picture size of %dx%d is not valid for the H.263 codec.\nValid sizes are 128x96, 176x144, 352x288, 704x576, and 1408x1152. Try H.263+.\n", s->width, s->height); - return -1; - } - s->out_format = FMT_H263; - s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_H263P: - s->out_format = FMT_H263; - s->h263_plus = 1; - /* Fx */ - s->umvplus = (avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0; - s->h263_aic= (avctx->flags & CODEC_FLAG_AC_PRED) ? 1:0; - s->modified_quant= s->h263_aic; - s->alt_inter_vlc= (avctx->flags & CODEC_FLAG_H263P_AIV) ? 1:0; - s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0; - s->loop_filter= (avctx->flags & CODEC_FLAG_LOOP_FILTER) ? 1:0; - s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus; - s->h263_slice_structured= (s->flags & CODEC_FLAG_H263P_SLICE_STRUCT) ? 1:0; - - /* /Fx */ - /* These are just to be sure */ - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_FLV1: - s->out_format = FMT_H263; - s->h263_flv = 2; /* format = 1; 11-bit codes */ - s->unrestricted_mv = 1; - s->rtp_mode=0; /* don't allow GOB */ - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_RV10: - s->out_format = FMT_H263; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_RV20: - s->out_format = FMT_H263; - avctx->delay=0; - s->low_delay=1; - s->modified_quant=1; - s->h263_aic=1; - s->h263_plus=1; - s->loop_filter=1; - s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus; - break; - case CODEC_ID_MPEG4: - s->out_format = FMT_H263; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->low_delay= s->max_b_frames ? 0 : 1; - avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); - break; - case CODEC_ID_MSMPEG4V1: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 1; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_MSMPEG4V2: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 2; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_MSMPEG4V3: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 3; - s->flipflop_rounding=1; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_WMV1: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 4; - s->flipflop_rounding=1; - avctx->delay=0; - s->low_delay=1; - break; - case CODEC_ID_WMV2: - s->out_format = FMT_H263; - s->h263_msmpeg4 = 1; - s->h263_pred = 1; - s->unrestricted_mv = 1; - s->msmpeg4_version= 5; - s->flipflop_rounding=1; - avctx->delay=0; - s->low_delay=1; - break; - default: - return -1; - } - - avctx->has_b_frames= !s->low_delay; - - s->encoding = 1; - - /* init */ - if (MPV_common_init(s) < 0) - return -1; - - if(s->modified_quant) - s->chroma_qscale_table= ff_h263_chroma_qscale_table; - s->progressive_frame= - s->progressive_sequence= !(avctx->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN)); - s->quant_precision=5; - - ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp); - ff_set_cmp(&s->dsp, s->dsp.frame_skip_cmp, s->avctx->frame_skip_cmp); - -#ifdef CONFIG_H261_ENCODER - if (s->out_format == FMT_H261) - ff_h261_encode_init(s); -#endif - if (s->out_format == FMT_H263) - h263_encode_init(s); - if(s->msmpeg4_version) - ff_msmpeg4_encode_init(s); - if (s->out_format == FMT_MPEG1) - ff_mpeg1_encode_init(s); - - /* init q matrix */ - for(i=0;i<64;i++) { - int j= s->dsp.idct_permutation[i]; - if(s->codec_id==CODEC_ID_MPEG4 && s->mpeg_quant){ - s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i]; - s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i]; - }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ - s->intra_matrix[j] = - s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; - }else - { /* mpeg1/2 */ - s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i]; - s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; - } - if(s->avctx->intra_matrix) - s->intra_matrix[j] = s->avctx->intra_matrix[i]; - if(s->avctx->inter_matrix) - s->inter_matrix[j] = s->avctx->inter_matrix[i]; - } - - /* precompute matrix */ - /* for mjpeg, we do include qscale in the matrix */ - if (s->out_format != FMT_MJPEG) { - convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16, - s->intra_matrix, s->intra_quant_bias, avctx->qmin, 31, 1); - convert_matrix(&s->dsp, s->q_inter_matrix, s->q_inter_matrix16, - s->inter_matrix, s->inter_quant_bias, avctx->qmin, 31, 0); - } - - if(ff_rate_control_init(s) < 0) - return -1; - - return 0; -} - -int MPV_encode_end(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - - ff_rate_control_uninit(s); - - MPV_common_end(s); - if (s->out_format == FMT_MJPEG) - mjpeg_close(s); - - av_freep(&avctx->extradata); - - return 0; -} - -#endif //CONFIG_ENCODERS - void init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]) { int8_t max_level[MAX_RUN+1], max_run[MAX_LEVEL+1]; @@ -1462,6 +740,59 @@ void init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]) } } +void init_vlc_rl(RLTable *rl, int use_static) +{ + int i, q; + + /* Return if static table is already initialized */ + if(use_static && rl->rl_vlc[0]) + return; + + init_vlc(&rl->vlc, 9, rl->n + 1, + &rl->table_vlc[0][1], 4, 2, + &rl->table_vlc[0][0], 4, 2, use_static); + + + for(q=0; q<32; q++){ + int qmul= q*2; + int qadd= (q-1)|1; + + if(q==0){ + qmul=1; + qadd=0; + } + if(use_static) + rl->rl_vlc[q]= av_mallocz_static(rl->vlc.table_size*sizeof(RL_VLC_ELEM)); + else + rl->rl_vlc[q]= av_malloc(rl->vlc.table_size*sizeof(RL_VLC_ELEM)); + for(i=0; i<rl->vlc.table_size; i++){ + int code= rl->vlc.table[i][0]; + int len = rl->vlc.table[i][1]; + int level, run; + + if(len==0){ // illegal code + run= 66; + level= MAX_LEVEL; + }else if(len<0){ //more bits needed + run= 0; + level= code; + }else{ + if(code==rl->n){ //esc + run= 66; + level= 0; + }else{ + run= rl->table_run [code] + 1; + level= rl->table_level[code] * qmul + qadd; + if(code >= rl->last) run+=192; + } + } + rl->rl_vlc[q][i].len= len; + rl->rl_vlc[q][i].level= level; + rl->rl_vlc[q][i].run= run; + } + } +} + /* draw the edges of width 'w' of an image of size width, height */ //FIXME check that this is ok for mpeg4 interlaced static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w) @@ -1507,7 +838,19 @@ int ff_find_unused_picture(MpegEncContext *s, int shared){ } } - assert(0); + av_log(s->avctx, AV_LOG_FATAL, "Internal error, picture buffer overflow\n"); + /* We could return -1, but the codec would crash trying to draw into a + * non-existing frame anyway. This is safer than waiting for a random crash. + * Also the return of this is never useful, an encoder must only allocate + * as much as allowed in the specification. This has no relationship to how + * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large + * enough for such valid streams). + * Plus, a decoder has to check stream validity and remove frames if too + * many reference frames are around. Waiting for "OOM" is not correct at + * all. Similarly, missing reference frames have to be replaced by + * interpolated/MC frames, anything else is a bug in the codec ... + */ + abort(); return -1; } @@ -1572,8 +915,13 @@ alloc: pic= (AVFrame*)&s->picture[i]; } - pic->reference= (s->pict_type != B_TYPE || s->codec_id == CODEC_ID_H264) - && !s->dropable ? 3 : 0; + pic->reference= 0; + if (!s->dropable){ + if (s->codec_id == CODEC_ID_H264) + pic->reference = s->picture_structure; + else if (s->pict_type != B_TYPE) + pic->reference = 3; + } pic->coded_picture_number= s->coded_picture_number++; @@ -1614,7 +962,7 @@ alloc: assert(s->pict_type == I_TYPE || (s->last_picture_ptr && s->last_picture_ptr->data[0])); - if(s->picture_structure!=PICT_FRAME){ + if(s->picture_structure!=PICT_FRAME && s->out_format != FMT_H264){ int i; for(i=0; i<4; i++){ if(s->picture_structure == PICT_BOTTOM_FIELD){ @@ -1630,7 +978,7 @@ alloc: s->error_resilience= avctx->error_resilience; /* set dequantizer, we can't do it during init as it might change for mpeg4 - and we can't do it in the header decode as init isnt called for mpeg4 there yet */ + and we can't do it in the header decode as init is not called for mpeg4 there yet */ if(s->mpeg_quant || s->codec_id == CODEC_ID_MPEG2VIDEO){ s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra; s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter; @@ -1749,8 +1097,8 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int h for(y= 0; y <= ey; y++){ x = (y*f)>>16; fr= (y*f)&0xFFFF; - buf[y*stride + x ]+= (color*(0x10000-fr))>>16;; - buf[y*stride + x+1]+= (color* fr )>>16;; + buf[y*stride + x ]+= (color*(0x10000-fr))>>16; + buf[y*stride + x+1]+= (color* fr )>>16; } } } @@ -2049,751 +1397,6 @@ v= (int)(128 + r*sin(theta*3.141592/180)); } } -#ifdef CONFIG_ENCODERS - -static int get_sae(uint8_t *src, int ref, int stride){ - int x,y; - int acc=0; - - for(y=0; y<16; y++){ - for(x=0; x<16; x++){ - acc+= FFABS(src[x+y*stride] - ref); - } - } - - return acc; -} - -static int get_intra_count(MpegEncContext *s, uint8_t *src, uint8_t *ref, int stride){ - int x, y, w, h; - int acc=0; - - w= s->width &~15; - h= s->height&~15; - - for(y=0; y<h; y+=16){ - for(x=0; x<w; x+=16){ - int offset= x + y*stride; - int sad = s->dsp.sad[0](NULL, src + offset, ref + offset, stride, 16); - int mean= (s->dsp.pix_sum(src + offset, stride) + 128)>>8; - int sae = get_sae(src + offset, mean, stride); - - acc+= sae + 500 < sad; - } - } - return acc; -} - - -static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){ - AVFrame *pic=NULL; - int64_t pts; - int i; - const int encoding_delay= s->max_b_frames; - int direct=1; - - if(pic_arg){ - pts= pic_arg->pts; - pic_arg->display_picture_number= s->input_picture_number++; - - if(pts != AV_NOPTS_VALUE){ - if(s->user_specified_pts != AV_NOPTS_VALUE){ - int64_t time= pts; - int64_t last= s->user_specified_pts; - - if(time <= last){ - av_log(s->avctx, AV_LOG_ERROR, "Error, Invalid timestamp=%"PRId64", last=%"PRId64"\n", pts, s->user_specified_pts); - return -1; - } - } - s->user_specified_pts= pts; - }else{ - if(s->user_specified_pts != AV_NOPTS_VALUE){ - s->user_specified_pts= - pts= s->user_specified_pts + 1; - av_log(s->avctx, AV_LOG_INFO, "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n", pts); - }else{ - pts= pic_arg->display_picture_number; - } - } - } - - if(pic_arg){ - if(encoding_delay && !(s->flags&CODEC_FLAG_INPUT_PRESERVED)) direct=0; - if(pic_arg->linesize[0] != s->linesize) direct=0; - if(pic_arg->linesize[1] != s->uvlinesize) direct=0; - if(pic_arg->linesize[2] != s->uvlinesize) direct=0; - -// av_log(AV_LOG_DEBUG, "%d %d %d %d\n",pic_arg->linesize[0], pic_arg->linesize[1], s->linesize, s->uvlinesize); - - if(direct){ - i= ff_find_unused_picture(s, 1); - - pic= (AVFrame*)&s->picture[i]; - pic->reference= 3; - - for(i=0; i<4; i++){ - pic->data[i]= pic_arg->data[i]; - pic->linesize[i]= pic_arg->linesize[i]; - } - alloc_picture(s, (Picture*)pic, 1); - }else{ - i= ff_find_unused_picture(s, 0); - - pic= (AVFrame*)&s->picture[i]; - pic->reference= 3; - - alloc_picture(s, (Picture*)pic, 0); - - if( pic->data[0] + INPLACE_OFFSET == pic_arg->data[0] - && pic->data[1] + INPLACE_OFFSET == pic_arg->data[1] - && pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]){ - // empty - }else{ - int h_chroma_shift, v_chroma_shift; - avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); - - for(i=0; i<3; i++){ - int src_stride= pic_arg->linesize[i]; - int dst_stride= i ? s->uvlinesize : s->linesize; - int h_shift= i ? h_chroma_shift : 0; - int v_shift= i ? v_chroma_shift : 0; - int w= s->width >>h_shift; - int h= s->height>>v_shift; - uint8_t *src= pic_arg->data[i]; - uint8_t *dst= pic->data[i]; - - if(!s->avctx->rc_buffer_size) - dst +=INPLACE_OFFSET; - - if(src_stride==dst_stride) - memcpy(dst, src, src_stride*h); - else{ - while(h--){ - memcpy(dst, src, w); - dst += dst_stride; - src += src_stride; - } - } - } - } - } - copy_picture_attributes(s, pic, pic_arg); - pic->pts= pts; //we set this here to avoid modifiying pic_arg - } - - /* shift buffer entries */ - for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++) - s->input_picture[i-1]= s->input_picture[i]; - - s->input_picture[encoding_delay]= (Picture*)pic; - - return 0; -} - -static int skip_check(MpegEncContext *s, Picture *p, Picture *ref){ - int x, y, plane; - int score=0; - int64_t score64=0; - - for(plane=0; plane<3; plane++){ - const int stride= p->linesize[plane]; - const int bw= plane ? 1 : 2; - for(y=0; y<s->mb_height*bw; y++){ - for(x=0; x<s->mb_width*bw; x++){ - int off= p->type == FF_BUFFER_TYPE_SHARED ? 0: 16; - int v= s->dsp.frame_skip_cmp[1](s, p->data[plane] + 8*(x + y*stride)+off, ref->data[plane] + 8*(x + y*stride), stride, 8); - - switch(s->avctx->frame_skip_exp){ - case 0: score= FFMAX(score, v); break; - case 1: score+= FFABS(v);break; - case 2: score+= v*v;break; - case 3: score64+= FFABS(v*v*(int64_t)v);break; - case 4: score64+= v*v*(int64_t)(v*v);break; - } - } - } - } - - if(score) score64= score; - - if(score64 < s->avctx->frame_skip_threshold) - return 1; - if(score64 < ((s->avctx->frame_skip_factor * (int64_t)s->lambda)>>8)) - return 1; - return 0; -} - -static int estimate_best_b_count(MpegEncContext *s){ - AVCodec *codec= avcodec_find_encoder(s->avctx->codec_id); - AVCodecContext *c= avcodec_alloc_context(); - AVFrame input[FF_MAX_B_FRAMES+2]; - const int scale= s->avctx->brd_scale; - int i, j, out_size, p_lambda, b_lambda, lambda2; - int outbuf_size= s->width * s->height; //FIXME - uint8_t *outbuf= av_malloc(outbuf_size); - int64_t best_rd= INT64_MAX; - int best_b_count= -1; - - assert(scale>=0 && scale <=3); - -// emms_c(); - p_lambda= s->last_lambda_for[P_TYPE]; //s->next_picture_ptr->quality; - b_lambda= s->last_lambda_for[B_TYPE]; //p_lambda *FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset; - if(!b_lambda) b_lambda= p_lambda; //FIXME we should do this somewhere else - lambda2= (b_lambda*b_lambda + (1<<FF_LAMBDA_SHIFT)/2 ) >> FF_LAMBDA_SHIFT; - - c->width = s->width >> scale; - c->height= s->height>> scale; - c->flags= CODEC_FLAG_QSCALE | CODEC_FLAG_PSNR | CODEC_FLAG_INPUT_PRESERVED /*| CODEC_FLAG_EMU_EDGE*/; - c->flags|= s->avctx->flags & CODEC_FLAG_QPEL; - c->mb_decision= s->avctx->mb_decision; - c->me_cmp= s->avctx->me_cmp; - c->mb_cmp= s->avctx->mb_cmp; - c->me_sub_cmp= s->avctx->me_sub_cmp; - c->pix_fmt = PIX_FMT_YUV420P; - c->time_base= s->avctx->time_base; - c->max_b_frames= s->max_b_frames; - - if (avcodec_open(c, codec) < 0) - return -1; - - for(i=0; i<s->max_b_frames+2; i++){ - int ysize= c->width*c->height; - int csize= (c->width/2)*(c->height/2); - Picture pre_input, *pre_input_ptr= i ? s->input_picture[i-1] : s->next_picture_ptr; - - avcodec_get_frame_defaults(&input[i]); - input[i].data[0]= av_malloc(ysize + 2*csize); - input[i].data[1]= input[i].data[0] + ysize; - input[i].data[2]= input[i].data[1] + csize; - input[i].linesize[0]= c->width; - input[i].linesize[1]= - input[i].linesize[2]= c->width/2; - - if(pre_input_ptr && (!i || s->input_picture[i-1])) { - pre_input= *pre_input_ptr; - - if(pre_input.type != FF_BUFFER_TYPE_SHARED && i) { - pre_input.data[0]+=INPLACE_OFFSET; - pre_input.data[1]+=INPLACE_OFFSET; - pre_input.data[2]+=INPLACE_OFFSET; - } - - s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0], pre_input.data[0], pre_input.linesize[0], c->width, c->height); - s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1], pre_input.data[1], pre_input.linesize[1], c->width>>1, c->height>>1); - s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2], pre_input.data[2], pre_input.linesize[2], c->width>>1, c->height>>1); - } - } - - for(j=0; j<s->max_b_frames+1; j++){ - int64_t rd=0; - - if(!s->input_picture[j]) - break; - - c->error[0]= c->error[1]= c->error[2]= 0; - - input[0].pict_type= I_TYPE; - input[0].quality= 1 * FF_QP2LAMBDA; - out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[0]); -// rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT; - - for(i=0; i<s->max_b_frames+1; i++){ - int is_p= i % (j+1) == j || i==s->max_b_frames; - - input[i+1].pict_type= is_p ? P_TYPE : B_TYPE; - input[i+1].quality= is_p ? p_lambda : b_lambda; - out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[i+1]); - rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); - } - - /* get the delayed frames */ - while(out_size){ - out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); - rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); - } - - rd += c->error[0] + c->error[1] + c->error[2]; - - if(rd < best_rd){ - best_rd= rd; - best_b_count= j; - } - } - - av_freep(&outbuf); - avcodec_close(c); - av_freep(&c); - - for(i=0; i<s->max_b_frames+2; i++){ - av_freep(&input[i].data[0]); - } - - return best_b_count; -} - -static void select_input_picture(MpegEncContext *s){ - int i; - - for(i=1; i<MAX_PICTURE_COUNT; i++) - s->reordered_input_picture[i-1]= s->reordered_input_picture[i]; - s->reordered_input_picture[MAX_PICTURE_COUNT-1]= NULL; - - /* set next picture type & ordering */ - if(s->reordered_input_picture[0]==NULL && s->input_picture[0]){ - if(/*s->picture_in_gop_number >= s->gop_size ||*/ s->next_picture_ptr==NULL || s->intra_only){ - s->reordered_input_picture[0]= s->input_picture[0]; - s->reordered_input_picture[0]->pict_type= I_TYPE; - s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++; - }else{ - int b_frames; - - if(s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor){ - if(s->picture_in_gop_number < s->gop_size && skip_check(s, s->input_picture[0], s->next_picture_ptr)){ - //FIXME check that te gop check above is +-1 correct -//av_log(NULL, AV_LOG_DEBUG, "skip %p %"PRId64"\n", s->input_picture[0]->data[0], s->input_picture[0]->pts); - - if(s->input_picture[0]->type == FF_BUFFER_TYPE_SHARED){ - for(i=0; i<4; i++) - s->input_picture[0]->data[i]= NULL; - s->input_picture[0]->type= 0; - }else{ - assert( s->input_picture[0]->type==FF_BUFFER_TYPE_USER - || s->input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL); - - s->avctx->release_buffer(s->avctx, (AVFrame*)s->input_picture[0]); - } - - emms_c(); - ff_vbv_update(s, 0); - - goto no_output_pic; - } - } - - if(s->flags&CODEC_FLAG_PASS2){ - for(i=0; i<s->max_b_frames+1; i++){ - int pict_num= s->input_picture[0]->display_picture_number + i; - - if(pict_num >= s->rc_context.num_entries) - break; - if(!s->input_picture[i]){ - s->rc_context.entry[pict_num-1].new_pict_type = P_TYPE; - break; - } - - s->input_picture[i]->pict_type= - s->rc_context.entry[pict_num].new_pict_type; - } - } - - if(s->avctx->b_frame_strategy==0){ - b_frames= s->max_b_frames; - while(b_frames && !s->input_picture[b_frames]) b_frames--; - }else if(s->avctx->b_frame_strategy==1){ - for(i=1; i<s->max_b_frames+1; i++){ - if(s->input_picture[i] && s->input_picture[i]->b_frame_score==0){ - s->input_picture[i]->b_frame_score= - get_intra_count(s, s->input_picture[i ]->data[0], - s->input_picture[i-1]->data[0], s->linesize) + 1; - } - } - for(i=0; i<s->max_b_frames+1; i++){ - if(s->input_picture[i]==NULL || s->input_picture[i]->b_frame_score - 1 > s->mb_num/s->avctx->b_sensitivity) break; - } - - b_frames= FFMAX(0, i-1); - - /* reset scores */ - for(i=0; i<b_frames+1; i++){ - s->input_picture[i]->b_frame_score=0; - } - }else if(s->avctx->b_frame_strategy==2){ - b_frames= estimate_best_b_count(s); - }else{ - av_log(s->avctx, AV_LOG_ERROR, "illegal b frame strategy\n"); - b_frames=0; - } - - emms_c(); -//static int b_count=0; -//b_count+= b_frames; -//av_log(s->avctx, AV_LOG_DEBUG, "b_frames: %d\n", b_count); - - for(i= b_frames - 1; i>=0; i--){ - int type= s->input_picture[i]->pict_type; - if(type && type != B_TYPE) - b_frames= i; - } - if(s->input_picture[b_frames]->pict_type == B_TYPE && b_frames == s->max_b_frames){ - av_log(s->avctx, AV_LOG_ERROR, "warning, too many b frames in a row\n"); - } - - if(s->picture_in_gop_number + b_frames >= s->gop_size){ - if((s->flags2 & CODEC_FLAG2_STRICT_GOP) && s->gop_size > s->picture_in_gop_number){ - b_frames= s->gop_size - s->picture_in_gop_number - 1; - }else{ - if(s->flags & CODEC_FLAG_CLOSED_GOP) - b_frames=0; - s->input_picture[b_frames]->pict_type= I_TYPE; - } - } - - if( (s->flags & CODEC_FLAG_CLOSED_GOP) - && b_frames - && s->input_picture[b_frames]->pict_type== I_TYPE) - b_frames--; - - s->reordered_input_picture[0]= s->input_picture[b_frames]; - if(s->reordered_input_picture[0]->pict_type != I_TYPE) - s->reordered_input_picture[0]->pict_type= P_TYPE; - s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++; - for(i=0; i<b_frames; i++){ - s->reordered_input_picture[i+1]= s->input_picture[i]; - s->reordered_input_picture[i+1]->pict_type= B_TYPE; - s->reordered_input_picture[i+1]->coded_picture_number= s->coded_picture_number++; - } - } - } -no_output_pic: - if(s->reordered_input_picture[0]){ - s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=B_TYPE ? 3 : 0; - - copy_picture(&s->new_picture, s->reordered_input_picture[0]); - - if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_SHARED || s->avctx->rc_buffer_size){ - // input is a shared pix, so we can't modifiy it -> alloc a new one & ensure that the shared one is reuseable - - int i= ff_find_unused_picture(s, 0); - Picture *pic= &s->picture[i]; - - pic->reference = s->reordered_input_picture[0]->reference; - alloc_picture(s, pic, 0); - - /* mark us unused / free shared pic */ - if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_INTERNAL) - s->avctx->release_buffer(s->avctx, (AVFrame*)s->reordered_input_picture[0]); - for(i=0; i<4; i++) - s->reordered_input_picture[0]->data[i]= NULL; - s->reordered_input_picture[0]->type= 0; - - copy_picture_attributes(s, (AVFrame*)pic, (AVFrame*)s->reordered_input_picture[0]); - - s->current_picture_ptr= pic; - }else{ - // input is not a shared pix -> reuse buffer for current_pix - - assert( s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_USER - || s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL); - - s->current_picture_ptr= s->reordered_input_picture[0]; - for(i=0; i<4; i++){ - s->new_picture.data[i]+= INPLACE_OFFSET; - } - } - copy_picture(&s->current_picture, s->current_picture_ptr); - - s->picture_number= s->new_picture.display_picture_number; -//printf("dpn:%d\n", s->picture_number); - }else{ - memset(&s->new_picture, 0, sizeof(Picture)); - } -} - -int MPV_encode_picture(AVCodecContext *avctx, - unsigned char *buf, int buf_size, void *data) -{ - MpegEncContext *s = avctx->priv_data; - AVFrame *pic_arg = data; - int i, stuffing_count; - - for(i=0; i<avctx->thread_count; i++){ - int start_y= s->thread_context[i]->start_mb_y; - int end_y= s->thread_context[i]-> end_mb_y; - int h= s->mb_height; - uint8_t *start= buf + (size_t)(((int64_t) buf_size)*start_y/h); - uint8_t *end = buf + (size_t)(((int64_t) buf_size)* end_y/h); - - init_put_bits(&s->thread_context[i]->pb, start, end - start); - } - - s->picture_in_gop_number++; - - if(load_input_picture(s, pic_arg) < 0) - return -1; - - select_input_picture(s); - - /* output? */ - if(s->new_picture.data[0]){ - s->pict_type= s->new_picture.pict_type; -//emms_c(); -//printf("qs:%f %f %d\n", s->new_picture.quality, s->current_picture.quality, s->qscale); - MPV_frame_start(s, avctx); -vbv_retry: - if (encode_picture(s, s->picture_number) < 0) - return -1; - - avctx->real_pict_num = s->picture_number; - avctx->header_bits = s->header_bits; - avctx->mv_bits = s->mv_bits; - avctx->misc_bits = s->misc_bits; - avctx->i_tex_bits = s->i_tex_bits; - avctx->p_tex_bits = s->p_tex_bits; - avctx->i_count = s->i_count; - avctx->p_count = s->mb_num - s->i_count - s->skip_count; //FIXME f/b_count in avctx - avctx->skip_count = s->skip_count; - - MPV_frame_end(s); - - if (s->out_format == FMT_MJPEG) - mjpeg_picture_trailer(s); - - if(avctx->rc_buffer_size){ - RateControlContext *rcc= &s->rc_context; - int max_size= rcc->buffer_index/3; - - if(put_bits_count(&s->pb) > max_size && s->lambda < s->avctx->lmax){ - s->next_lambda= FFMAX(s->lambda+1, s->lambda*(s->qscale+1) / s->qscale); - if(s->adaptive_quant){ - int i; - for(i=0; i<s->mb_height*s->mb_stride; i++) - s->lambda_table[i]= FFMAX(s->lambda_table[i]+1, s->lambda_table[i]*(s->qscale+1) / s->qscale); - } - s->mb_skipped = 0; //done in MPV_frame_start() - if(s->pict_type==P_TYPE){ //done in encode_picture() so we must undo it - if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4) - s->no_rounding ^= 1; - } - if(s->pict_type!=B_TYPE){ - s->time_base= s->last_time_base; - s->last_non_b_time= s->time - s->pp_time; - } -// av_log(NULL, AV_LOG_ERROR, "R:%d ", s->next_lambda); - for(i=0; i<avctx->thread_count; i++){ - PutBitContext *pb= &s->thread_context[i]->pb; - init_put_bits(pb, pb->buf, pb->buf_end - pb->buf); - } - goto vbv_retry; - } - - assert(s->avctx->rc_max_rate); - } - - if(s->flags&CODEC_FLAG_PASS1) - ff_write_pass1_stats(s); - - for(i=0; i<4; i++){ - s->current_picture_ptr->error[i]= s->current_picture.error[i]; - avctx->error[i] += s->current_picture_ptr->error[i]; - } - - if(s->flags&CODEC_FLAG_PASS1) - assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits + avctx->i_tex_bits + avctx->p_tex_bits == put_bits_count(&s->pb)); - flush_put_bits(&s->pb); - s->frame_bits = put_bits_count(&s->pb); - - stuffing_count= ff_vbv_update(s, s->frame_bits); - if(stuffing_count){ - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < stuffing_count + 50){ - av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n"); - return -1; - } - - switch(s->codec_id){ - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - while(stuffing_count--){ - put_bits(&s->pb, 8, 0); - } - break; - case CODEC_ID_MPEG4: - put_bits(&s->pb, 16, 0); - put_bits(&s->pb, 16, 0x1C3); - stuffing_count -= 4; - while(stuffing_count--){ - put_bits(&s->pb, 8, 0xFF); - } - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n"); - } - flush_put_bits(&s->pb); - s->frame_bits = put_bits_count(&s->pb); - } - - /* update mpeg1/2 vbv_delay for CBR */ - if(s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate && s->out_format == FMT_MPEG1 - && 90000LL * (avctx->rc_buffer_size-1) <= s->avctx->rc_max_rate*0xFFFFLL){ - int vbv_delay; - - assert(s->repeat_first_field==0); - - vbv_delay= lrintf(90000 * s->rc_context.buffer_index / s->avctx->rc_max_rate); - assert(vbv_delay < 0xFFFF); - - s->vbv_delay_ptr[0] &= 0xF8; - s->vbv_delay_ptr[0] |= vbv_delay>>13; - s->vbv_delay_ptr[1] = vbv_delay>>5; - s->vbv_delay_ptr[2] &= 0x07; - s->vbv_delay_ptr[2] |= vbv_delay<<3; - } - s->total_bits += s->frame_bits; - avctx->frame_bits = s->frame_bits; - }else{ - assert((pbBufPtr(&s->pb) == s->pb.buf)); - s->frame_bits=0; - } - assert((s->frame_bits&7)==0); - - return s->frame_bits/8; -} - -#endif //CONFIG_ENCODERS - -static inline void gmc1_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture) -{ - uint8_t *ptr; - int offset, src_x, src_y, linesize, uvlinesize; - int motion_x, motion_y; - int emu=0; - - motion_x= s->sprite_offset[0][0]; - motion_y= s->sprite_offset[0][1]; - src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1)); - src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1)); - motion_x<<=(3-s->sprite_warping_accuracy); - motion_y<<=(3-s->sprite_warping_accuracy); - src_x = av_clip(src_x, -16, s->width); - if (src_x == s->width) - motion_x =0; - src_y = av_clip(src_y, -16, s->height); - if (src_y == s->height) - motion_y =0; - - linesize = s->linesize; - uvlinesize = s->uvlinesize; - - ptr = ref_picture[0] + (src_y * linesize) + src_x; - - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x >= s->h_edge_pos - 17 - || (unsigned)src_y >= s->v_edge_pos - 17){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos); - ptr= s->edge_emu_buffer; - } - } - - if((motion_x|motion_y)&7){ - s->dsp.gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); - s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); - }else{ - int dxy; - - dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2); - if (s->no_rounding){ - s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16); - }else{ - s->dsp.put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16); - } - } - - if(s->flags&CODEC_FLAG_GRAY) return; - - motion_x= s->sprite_offset[1][0]; - motion_y= s->sprite_offset[1][1]; - src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1)); - src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1)); - motion_x<<=(3-s->sprite_warping_accuracy); - motion_y<<=(3-s->sprite_warping_accuracy); - src_x = av_clip(src_x, -8, s->width>>1); - if (src_x == s->width>>1) - motion_x =0; - src_y = av_clip(src_y, -8, s->height>>1); - if (src_y == s->height>>1) - motion_y =0; - - offset = (src_y * uvlinesize) + src_x; - ptr = ref_picture[1] + offset; - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x >= (s->h_edge_pos>>1) - 9 - || (unsigned)src_y >= (s->v_edge_pos>>1) - 9){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - emu=1; - } - } - s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); - - ptr = ref_picture[2] + offset; - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - } - s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); - - return; -} - -static inline void gmc_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture) -{ - uint8_t *ptr; - int linesize, uvlinesize; - const int a= s->sprite_warping_accuracy; - int ox, oy; - - linesize = s->linesize; - uvlinesize = s->uvlinesize; - - ptr = ref_picture[0]; - - ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16; - oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16; - - s->dsp.gmc(dest_y, ptr, linesize, 16, - ox, - oy, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos, s->v_edge_pos); - s->dsp.gmc(dest_y+8, ptr, linesize, 16, - ox + s->sprite_delta[0][0]*8, - oy + s->sprite_delta[1][0]*8, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos, s->v_edge_pos); - - if(s->flags&CODEC_FLAG_GRAY) return; - - ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8; - oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8; - - ptr = ref_picture[1]; - s->dsp.gmc(dest_cb, ptr, uvlinesize, 8, - ox, - oy, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos>>1, s->v_edge_pos>>1); - - ptr = ref_picture[2]; - s->dsp.gmc(dest_cr, ptr, uvlinesize, 8, - ox, - oy, - s->sprite_delta[0][0], s->sprite_delta[0][1], - s->sprite_delta[1][0], s->sprite_delta[1][1], - a+1, (1<<(2*a+1)) - s->no_rounding, - s->h_edge_pos>>1, s->v_edge_pos>>1); -} - /** * Copies a rectangular area of samples to a temporary buffer and replicates the boarder samples. * @param buf destination buffer @@ -2865,46 +1468,6 @@ void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w, } } -static inline int hpel_motion(MpegEncContext *s, - uint8_t *dest, uint8_t *src, - int field_based, int field_select, - int src_x, int src_y, - int width, int height, int stride, - int h_edge_pos, int v_edge_pos, - int w, int h, op_pixels_func *pix_op, - int motion_x, int motion_y) -{ - int dxy; - int emu=0; - - dxy = ((motion_y & 1) << 1) | (motion_x & 1); - src_x += motion_x >> 1; - src_y += motion_y >> 1; - - /* WARNING: do no forget half pels */ - src_x = av_clip(src_x, -16, width); //FIXME unneeded for emu? - if (src_x == width) - dxy &= ~1; - src_y = av_clip(src_y, -16, height); - if (src_y == height) - dxy &= ~2; - src += src_y * stride + src_x; - - if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){ - if( (unsigned)src_x > h_edge_pos - (motion_x&1) - w - || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){ - ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based, - src_x, src_y<<field_based, h_edge_pos, s->v_edge_pos); - src= s->edge_emu_buffer; - emu=1; - } - } - if(field_select) - src += s->linesize; - pix_op[dxy](dest, src, stride, h); - return emu; -} - static inline int hpel_motion_lowres(MpegEncContext *s, uint8_t *dest, uint8_t *src, int field_based, int field_select, @@ -2948,123 +1511,6 @@ static inline int hpel_motion_lowres(MpegEncContext *s, } /* apply one mpeg motion vector to the three components */ -static av_always_inline void mpeg_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int field_based, int bottom_field, int field_select, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - int motion_x, int motion_y, int h) -{ - uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize; - -#if 0 -if(s->quarter_sample) -{ - motion_x>>=1; - motion_y>>=1; -} -#endif - - v_edge_pos = s->v_edge_pos >> field_based; - linesize = s->current_picture.linesize[0] << field_based; - uvlinesize = s->current_picture.linesize[1] << field_based; - - dxy = ((motion_y & 1) << 1) | (motion_x & 1); - src_x = s->mb_x* 16 + (motion_x >> 1); - src_y =(s->mb_y<<(4-field_based)) + (motion_y >> 1); - - if (s->out_format == FMT_H263) { - if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){ - mx = (motion_x>>1)|(motion_x&1); - my = motion_y >>1; - uvdxy = ((my & 1) << 1) | (mx & 1); - uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1); - }else{ - uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); - uvsrc_x = src_x>>1; - uvsrc_y = src_y>>1; - } - }else if(s->out_format == FMT_H261){//even chroma mv's are full pel in H261 - mx = motion_x / 4; - my = motion_y / 4; - uvdxy = 0; - uvsrc_x = s->mb_x*8 + mx; - uvsrc_y = s->mb_y*8 + my; - } else { - if(s->chroma_y_shift){ - mx = motion_x / 2; - my = motion_y / 2; - uvdxy = ((my & 1) << 1) | (mx & 1); - uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1); - } else { - if(s->chroma_x_shift){ - //Chroma422 - mx = motion_x / 2; - uvdxy = ((motion_y & 1) << 1) | (mx & 1); - uvsrc_x = s->mb_x* 8 + (mx >> 1); - uvsrc_y = src_y; - } else { - //Chroma444 - uvdxy = dxy; - uvsrc_x = src_x; - uvsrc_y = src_y; - } - } - } - - ptr_y = ref_picture[0] + src_y * linesize + src_x; - ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; - ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; - - if( (unsigned)src_x > s->h_edge_pos - (motion_x&1) - 16 - || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){ - if(s->codec_id == CODEC_ID_MPEG2VIDEO || - s->codec_id == CODEC_ID_MPEG1VIDEO){ - av_log(s->avctx,AV_LOG_DEBUG,"MPEG motion vector out of boundary\n"); - return ; - } - ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based, - src_x, src_y<<field_based, s->h_edge_pos, s->v_edge_pos); - ptr_y = s->edge_emu_buffer; - if(!(s->flags&CODEC_FLAG_GRAY)){ - uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize; - ff_emulated_edge_mc(uvbuf , ptr_cb, s->uvlinesize, 9, 9+field_based, - uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); - ff_emulated_edge_mc(uvbuf+16, ptr_cr, s->uvlinesize, 9, 9+field_based, - uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr_cb= uvbuf; - ptr_cr= uvbuf+16; - } - } - - if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data - dest_y += s->linesize; - dest_cb+= s->uvlinesize; - dest_cr+= s->uvlinesize; - } - - if(field_select){ - ptr_y += s->linesize; - ptr_cb+= s->uvlinesize; - ptr_cr+= s->uvlinesize; - } - - pix_op[0][dxy](dest_y, ptr_y, linesize, h); - - if(!(s->flags&CODEC_FLAG_GRAY)){ - pix_op[s->chroma_x_shift][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift); - pix_op[s->chroma_x_shift][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift); - } -#if defined(CONFIG_H261_ENCODER) || defined(CONFIG_H261_DECODER) - if(s->out_format == FMT_H261){ - ff_h261_loop_filter(s); - } -#endif -} - -/* apply one mpeg motion vector to the three components */ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int field_based, int bottom_field, int field_select, @@ -3125,7 +1571,7 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based, src_x, src_y<<field_based, h_edge_pos, v_edge_pos); ptr_y = s->edge_emu_buffer; - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize; ff_emulated_edge_mc(uvbuf , ptr_cb, s->uvlinesize, 9, 9+field_based, uvsrc_x, uvsrc_y<<field_based, h_edge_pos>>1, v_edge_pos>>1); @@ -3152,7 +1598,7 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, sy <<= 2 - lowres; pix_op[lowres-1](dest_y, ptr_y, linesize, h, sx, sy); - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ uvsx <<= 2 - lowres; uvsy <<= 2 - lowres; pix_op[lowres](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy); @@ -3161,233 +1607,6 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, //FIXME h261 lowres loop filter } -//FIXME move to dsputil, avg variant, 16x16 version -static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){ - int x; - uint8_t * const top = src[1]; - uint8_t * const left = src[2]; - uint8_t * const mid = src[0]; - uint8_t * const right = src[3]; - uint8_t * const bottom= src[4]; -#define OBMC_FILTER(x, t, l, m, r, b)\ - dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3 -#define OBMC_FILTER4(x, t, l, m, r, b)\ - OBMC_FILTER(x , t, l, m, r, b);\ - OBMC_FILTER(x+1 , t, l, m, r, b);\ - OBMC_FILTER(x +stride, t, l, m, r, b);\ - OBMC_FILTER(x+1+stride, t, l, m, r, b); - - x=0; - OBMC_FILTER (x , 2, 2, 4, 0, 0); - OBMC_FILTER (x+1, 2, 1, 5, 0, 0); - OBMC_FILTER4(x+2, 2, 1, 5, 0, 0); - OBMC_FILTER4(x+4, 2, 0, 5, 1, 0); - OBMC_FILTER (x+6, 2, 0, 5, 1, 0); - OBMC_FILTER (x+7, 2, 0, 4, 2, 0); - x+= stride; - OBMC_FILTER (x , 1, 2, 5, 0, 0); - OBMC_FILTER (x+1, 1, 2, 5, 0, 0); - OBMC_FILTER (x+6, 1, 0, 5, 2, 0); - OBMC_FILTER (x+7, 1, 0, 5, 2, 0); - x+= stride; - OBMC_FILTER4(x , 1, 2, 5, 0, 0); - OBMC_FILTER4(x+2, 1, 1, 6, 0, 0); - OBMC_FILTER4(x+4, 1, 0, 6, 1, 0); - OBMC_FILTER4(x+6, 1, 0, 5, 2, 0); - x+= 2*stride; - OBMC_FILTER4(x , 0, 2, 5, 0, 1); - OBMC_FILTER4(x+2, 0, 1, 6, 0, 1); - OBMC_FILTER4(x+4, 0, 0, 6, 1, 1); - OBMC_FILTER4(x+6, 0, 0, 5, 2, 1); - x+= 2*stride; - OBMC_FILTER (x , 0, 2, 5, 0, 1); - OBMC_FILTER (x+1, 0, 2, 5, 0, 1); - OBMC_FILTER4(x+2, 0, 1, 5, 0, 2); - OBMC_FILTER4(x+4, 0, 0, 5, 1, 2); - OBMC_FILTER (x+6, 0, 0, 5, 2, 1); - OBMC_FILTER (x+7, 0, 0, 5, 2, 1); - x+= stride; - OBMC_FILTER (x , 0, 2, 4, 0, 2); - OBMC_FILTER (x+1, 0, 1, 5, 0, 2); - OBMC_FILTER (x+6, 0, 0, 5, 1, 2); - OBMC_FILTER (x+7, 0, 0, 4, 2, 2); -} - -/* obmc for 1 8x8 luma block */ -static inline void obmc_motion(MpegEncContext *s, - uint8_t *dest, uint8_t *src, - int src_x, int src_y, - op_pixels_func *pix_op, - int16_t mv[5][2]/* mid top left right bottom*/) -#define MID 0 -{ - int i; - uint8_t *ptr[5]; - - assert(s->quarter_sample==0); - - for(i=0; i<5; i++){ - if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){ - ptr[i]= ptr[MID]; - }else{ - ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1); - hpel_motion(s, ptr[i], src, 0, 0, - src_x, src_y, - s->width, s->height, s->linesize, - s->h_edge_pos, s->v_edge_pos, - 8, 8, pix_op, - mv[i][0], mv[i][1]); - } - } - - put_obmc(dest, ptr, s->linesize); -} - -static inline void qpel_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int field_based, int bottom_field, int field_select, - uint8_t **ref_picture, op_pixels_func (*pix_op)[4], - qpel_mc_func (*qpix_op)[16], - int motion_x, int motion_y, int h) -{ - uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, linesize, uvlinesize; - - dxy = ((motion_y & 3) << 2) | (motion_x & 3); - src_x = s->mb_x * 16 + (motion_x >> 2); - src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2); - - v_edge_pos = s->v_edge_pos >> field_based; - linesize = s->linesize << field_based; - uvlinesize = s->uvlinesize << field_based; - - if(field_based){ - mx= motion_x/2; - my= motion_y>>1; - }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){ - static const int rtab[8]= {0,0,1,1,0,0,0,1}; - mx= (motion_x>>1) + rtab[motion_x&7]; - my= (motion_y>>1) + rtab[motion_y&7]; - }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){ - mx= (motion_x>>1)|(motion_x&1); - my= (motion_y>>1)|(motion_y&1); - }else{ - mx= motion_x/2; - my= motion_y/2; - } - mx= (mx>>1)|(mx&1); - my= (my>>1)|(my&1); - - uvdxy= (mx&1) | ((my&1)<<1); - mx>>=1; - my>>=1; - - uvsrc_x = s->mb_x * 8 + mx; - uvsrc_y = s->mb_y * (8 >> field_based) + my; - - ptr_y = ref_picture[0] + src_y * linesize + src_x; - ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; - ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; - - if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16 - || (unsigned)src_y > v_edge_pos - (motion_y&3) - h ){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based, - src_x, src_y<<field_based, s->h_edge_pos, s->v_edge_pos); - ptr_y= s->edge_emu_buffer; - if(!(s->flags&CODEC_FLAG_GRAY)){ - uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize; - ff_emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize, 9, 9 + field_based, - uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); - ff_emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize, 9, 9 + field_based, - uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr_cb= uvbuf; - ptr_cr= uvbuf + 16; - } - } - - if(!field_based) - qpix_op[0][dxy](dest_y, ptr_y, linesize); - else{ - if(bottom_field){ - dest_y += s->linesize; - dest_cb+= s->uvlinesize; - dest_cr+= s->uvlinesize; - } - - if(field_select){ - ptr_y += s->linesize; - ptr_cb += s->uvlinesize; - ptr_cr += s->uvlinesize; - } - //damn interlaced mode - //FIXME boundary mirroring is not exactly correct here - qpix_op[1][dxy](dest_y , ptr_y , linesize); - qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize); - } - if(!(s->flags&CODEC_FLAG_GRAY)){ - pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1); - pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1); - } -} - -inline int ff_h263_round_chroma(int x){ - if (x >= 0) - return (h263_chroma_roundtab[x & 0xf] + ((x >> 3) & ~1)); - else { - x = -x; - return -(h263_chroma_roundtab[x & 0xf] + ((x >> 3) & ~1)); - } -} - -/** - * h263 chorma 4mv motion compensation. - */ -static inline void chroma_4mv_motion(MpegEncContext *s, - uint8_t *dest_cb, uint8_t *dest_cr, - uint8_t **ref_picture, - op_pixels_func *pix_op, - int mx, int my){ - int dxy, emu=0, src_x, src_y, offset; - uint8_t *ptr; - - /* In case of 8X8, we construct a single chroma motion vector - with a special rounding */ - mx= ff_h263_round_chroma(mx); - my= ff_h263_round_chroma(my); - - dxy = ((my & 1) << 1) | (mx & 1); - mx >>= 1; - my >>= 1; - - src_x = s->mb_x * 8 + mx; - src_y = s->mb_y * 8 + my; - src_x = av_clip(src_x, -8, s->width/2); - if (src_x == s->width/2) - dxy &= ~1; - src_y = av_clip(src_y, -8, s->height/2); - if (src_y == s->height/2) - dxy &= ~2; - - offset = (src_y * (s->uvlinesize)) + src_x; - ptr = ref_picture[1] + offset; - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x > (s->h_edge_pos>>1) - (dxy &1) - 8 - || (unsigned)src_y > (s->v_edge_pos>>1) - (dxy>>1) - 8){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - emu=1; - } - } - pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8); - - ptr = ref_picture[2] + offset; - if(emu){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); - ptr= s->edge_emu_buffer; - } - pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8); -} - static inline void chroma_4mv_motion_lowres(MpegEncContext *s, uint8_t *dest_cb, uint8_t *dest_cr, uint8_t **ref_picture, @@ -3438,269 +1657,6 @@ static inline void chroma_4mv_motion_lowres(MpegEncContext *s, pix_op[lowres](dest_cr, ptr, s->uvlinesize, block_s, sx, sy); } -static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){ - /* fetch pixels for estimated mv 4 macroblocks ahead - * optimized for 64byte cache lines */ - const int shift = s->quarter_sample ? 2 : 1; - const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8; - const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y; - int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64; - s->dsp.prefetch(pix[0]+off, s->linesize, 4); - off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64; - s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2); -} - -/** - * motion compensation of a single macroblock - * @param s context - * @param dest_y luma destination pointer - * @param dest_cb chroma cb/u destination pointer - * @param dest_cr chroma cr/v destination pointer - * @param dir direction (0->forward, 1->backward) - * @param ref_picture array[3] of pointers to the 3 planes of the reference picture - * @param pic_op halfpel motion compensation function (average or put normally) - * @param pic_op qpel motion compensation function (average or put normally) - * the motion vectors are taken from s->mv and the MV type from s->mv_type - */ -static inline void MPV_motion(MpegEncContext *s, - uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, - int dir, uint8_t **ref_picture, - op_pixels_func (*pix_op)[4], qpel_mc_func (*qpix_op)[16]) -{ - int dxy, mx, my, src_x, src_y, motion_x, motion_y; - int mb_x, mb_y, i; - uint8_t *ptr, *dest; - - mb_x = s->mb_x; - mb_y = s->mb_y; - - prefetch_motion(s, ref_picture, dir); - - if(s->obmc && s->pict_type != B_TYPE){ - int16_t mv_cache[4][4][2]; - const int xy= s->mb_x + s->mb_y*s->mb_stride; - const int mot_stride= s->b8_stride; - const int mot_xy= mb_x*2 + mb_y*2*mot_stride; - - assert(!s->mb_skipped); - - memcpy(mv_cache[1][1], s->current_picture.motion_val[0][mot_xy ], sizeof(int16_t)*4); - memcpy(mv_cache[2][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4); - memcpy(mv_cache[3][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4); - - if(mb_y==0 || IS_INTRA(s->current_picture.mb_type[xy-s->mb_stride])){ - memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4); - }else{ - memcpy(mv_cache[0][1], s->current_picture.motion_val[0][mot_xy-mot_stride], sizeof(int16_t)*4); - } - - if(mb_x==0 || IS_INTRA(s->current_picture.mb_type[xy-1])){ - *(int32_t*)mv_cache[1][0]= *(int32_t*)mv_cache[1][1]; - *(int32_t*)mv_cache[2][0]= *(int32_t*)mv_cache[2][1]; - }else{ - *(int32_t*)mv_cache[1][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1]; - *(int32_t*)mv_cache[2][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1+mot_stride]; - } - - if(mb_x+1>=s->mb_width || IS_INTRA(s->current_picture.mb_type[xy+1])){ - *(int32_t*)mv_cache[1][3]= *(int32_t*)mv_cache[1][2]; - *(int32_t*)mv_cache[2][3]= *(int32_t*)mv_cache[2][2]; - }else{ - *(int32_t*)mv_cache[1][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2]; - *(int32_t*)mv_cache[2][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2+mot_stride]; - } - - mx = 0; - my = 0; - for(i=0;i<4;i++) { - const int x= (i&1)+1; - const int y= (i>>1)+1; - int16_t mv[5][2]= { - {mv_cache[y][x ][0], mv_cache[y][x ][1]}, - {mv_cache[y-1][x][0], mv_cache[y-1][x][1]}, - {mv_cache[y][x-1][0], mv_cache[y][x-1][1]}, - {mv_cache[y][x+1][0], mv_cache[y][x+1][1]}, - {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}}; - //FIXME cleanup - obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, - ref_picture[0], - mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, - pix_op[1], - mv); - - mx += mv[0][0]; - my += mv[0][1]; - } - if(!(s->flags&CODEC_FLAG_GRAY)) - chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); - - return; - } - - switch(s->mv_type) { - case MV_TYPE_16X16: - if(s->mcsel){ - if(s->real_sprite_warping_points==1){ - gmc1_motion(s, dest_y, dest_cb, dest_cr, - ref_picture); - }else{ - gmc_motion(s, dest_y, dest_cb, dest_cr, - ref_picture); - } - }else if(s->quarter_sample){ - qpel_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, 0, - ref_picture, pix_op, qpix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16); - }else if(s->mspel){ - ff_mspel_motion(s, dest_y, dest_cb, dest_cr, - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16); - }else - { - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, 0, - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16); - } - break; - case MV_TYPE_8X8: - mx = 0; - my = 0; - if(s->quarter_sample){ - for(i=0;i<4;i++) { - motion_x = s->mv[dir][i][0]; - motion_y = s->mv[dir][i][1]; - - dxy = ((motion_y & 3) << 2) | (motion_x & 3); - src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8; - src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8; - - /* WARNING: do no forget half pels */ - src_x = av_clip(src_x, -16, s->width); - if (src_x == s->width) - dxy &= ~3; - src_y = av_clip(src_y, -16, s->height); - if (src_y == s->height) - dxy &= ~12; - - ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); - if(s->flags&CODEC_FLAG_EMU_EDGE){ - if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 8 - || (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 8 ){ - ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos); - ptr= s->edge_emu_buffer; - } - } - dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; - qpix_op[1][dxy](dest, ptr, s->linesize); - - mx += s->mv[dir][i][0]/2; - my += s->mv[dir][i][1]/2; - } - }else{ - for(i=0;i<4;i++) { - hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, - ref_picture[0], 0, 0, - mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, - s->width, s->height, s->linesize, - s->h_edge_pos, s->v_edge_pos, - 8, 8, pix_op[1], - s->mv[dir][i][0], s->mv[dir][i][1]); - - mx += s->mv[dir][i][0]; - my += s->mv[dir][i][1]; - } - } - - if(!(s->flags&CODEC_FLAG_GRAY)) - chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); - break; - case MV_TYPE_FIELD: - if (s->picture_structure == PICT_FRAME) { - if(s->quarter_sample){ - for(i=0; i<2; i++){ - qpel_motion(s, dest_y, dest_cb, dest_cr, - 1, i, s->field_select[dir][i], - ref_picture, pix_op, qpix_op, - s->mv[dir][i][0], s->mv[dir][i][1], 8); - } - }else{ - /* top field */ - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 1, 0, s->field_select[dir][0], - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 8); - /* bottom field */ - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 1, 1, s->field_select[dir][1], - ref_picture, pix_op, - s->mv[dir][1][0], s->mv[dir][1][1], 8); - } - } else { - if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != B_TYPE && !s->first_field){ - ref_picture= s->current_picture_ptr->data; - } - - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, s->field_select[dir][0], - ref_picture, pix_op, - s->mv[dir][0][0], s->mv[dir][0][1], 16); - } - break; - case MV_TYPE_16X8: - for(i=0; i<2; i++){ - uint8_t ** ref2picture; - - if(s->picture_structure == s->field_select[dir][i] + 1 || s->pict_type == B_TYPE || s->first_field){ - ref2picture= ref_picture; - }else{ - ref2picture= s->current_picture_ptr->data; - } - - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, s->field_select[dir][i], - ref2picture, pix_op, - s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8); - - dest_y += 16*s->linesize; - dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize; - dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize; - } - break; - case MV_TYPE_DMV: - if(s->picture_structure == PICT_FRAME){ - for(i=0; i<2; i++){ - int j; - for(j=0; j<2; j++){ - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 1, j, j^i, - ref_picture, pix_op, - s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8); - } - pix_op = s->dsp.avg_pixels_tab; - } - }else{ - for(i=0; i<2; i++){ - mpeg_motion(s, dest_y, dest_cb, dest_cr, - 0, 0, s->picture_structure != i+1, - ref_picture, pix_op, - s->mv[dir][2*i][0],s->mv[dir][2*i][1],16); - - // after put we make avg of the same block - pix_op=s->dsp.avg_pixels_tab; - - //opposite parity is always in the same frame if this is second field - if(!s->first_field){ - ref_picture = s->current_picture_ptr->data; - } - } - } - break; - default: assert(0); - } -} - /** * motion compensation of a single macroblock * @param s context @@ -3748,7 +1704,7 @@ static inline void MPV_motion_lowres(MpegEncContext *s, my += s->mv[dir][i][1]; } - if(!(s->flags&CODEC_FLAG_GRAY)) + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)) chroma_4mv_motion_lowres(s, dest_cb, dest_cr, ref_picture, pix_op, mx, my); break; case MV_TYPE_FIELD: @@ -4035,7 +1991,7 @@ static av_always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM b add_dequant_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); add_dequant_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if (s->chroma_y_shift){ add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); @@ -4054,7 +2010,7 @@ static av_always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM b add_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize); add_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize); - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if(s->chroma_y_shift){//Chroma420 add_dct(s, block[4], 4, dest_cb, uvlinesize); add_dct(s, block[5], 5, dest_cr, uvlinesize); @@ -4076,7 +2032,7 @@ static av_always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM b } }//fi gray } - else{ + else if (ENABLE_WMV2) { ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr); } } else { @@ -4087,7 +2043,7 @@ static av_always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM b put_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); put_dct(s, block[3], 3, dest_y + dct_offset + block_size, dct_linesize, s->qscale); - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if(s->chroma_y_shift){ put_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); put_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); @@ -4106,7 +2062,7 @@ static av_always_inline void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM b s->dsp.idct_put(dest_y + dct_offset , dct_linesize, block[2]); s->dsp.idct_put(dest_y + dct_offset + block_size, dct_linesize, block[3]); - if(!(s->flags&CODEC_FLAG_GRAY)){ + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if(s->chroma_y_shift){ s->dsp.idct_put(dest_cb, uvlinesize, block[4]); s->dsp.idct_put(dest_cr, uvlinesize, block[5]); @@ -4143,90 +2099,6 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){ else MPV_decode_mb_internal(s, block, 0); } -#ifdef CONFIG_ENCODERS - -static inline void dct_single_coeff_elimination(MpegEncContext *s, int n, int threshold) -{ - static const char tab[64]= - {3,2,2,1,1,1,1,1, - 1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0}; - int score=0; - int run=0; - int i; - DCTELEM *block= s->block[n]; - const int last_index= s->block_last_index[n]; - int skip_dc; - - if(threshold<0){ - skip_dc=0; - threshold= -threshold; - }else - skip_dc=1; - - /* are all which we could set to zero are allready zero? */ - if(last_index<=skip_dc - 1) return; - - for(i=0; i<=last_index; i++){ - const int j = s->intra_scantable.permutated[i]; - const int level = FFABS(block[j]); - if(level==1){ - if(skip_dc && i==0) continue; - score+= tab[run]; - run=0; - }else if(level>1){ - return; - }else{ - run++; - } - } - if(score >= threshold) return; - for(i=skip_dc; i<=last_index; i++){ - const int j = s->intra_scantable.permutated[i]; - block[j]=0; - } - if(block[0]) s->block_last_index[n]= 0; - else s->block_last_index[n]= -1; -} - -static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block, int last_index) -{ - int i; - const int maxlevel= s->max_qcoeff; - const int minlevel= s->min_qcoeff; - int overflow=0; - - if(s->mb_intra){ - i=1; //skip clipping of intra dc - }else - i=0; - - for(;i<=last_index; i++){ - const int j= s->intra_scantable.permutated[i]; - int level = block[j]; - - if (level>maxlevel){ - level=maxlevel; - overflow++; - }else if(level<minlevel){ - level=minlevel; - overflow++; - } - - block[j]= level; - } - - if(overflow && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE) - av_log(s->avctx, AV_LOG_INFO, "warning, clipping %d dct coefficients to %d..%d\n", overflow, minlevel, maxlevel); -} - -#endif //CONFIG_ENCODERS - /** * * @param h is the normal height, this will be reduced automatically if needed for the last row @@ -4257,7 +2129,7 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ offset[2]= offset[3]= 0; }else{ - offset[0]= y * s->linesize;; + offset[0]= y * s->linesize; offset[1]= offset[2]= (y >> s->chroma_y_shift) * s->uvlinesize; offset[3]= 0; @@ -4295,320 +2167,6 @@ void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename } } -#ifdef CONFIG_ENCODERS - -static void get_vissual_weight(int16_t *weight, uint8_t *ptr, int stride){ - int x, y; -//FIXME optimize - for(y=0; y<8; y++){ - for(x=0; x<8; x++){ - int x2, y2; - int sum=0; - int sqr=0; - int count=0; - - for(y2= FFMAX(y-1, 0); y2 < FFMIN(8, y+2); y2++){ - for(x2= FFMAX(x-1, 0); x2 < FFMIN(8, x+2); x2++){ - int v= ptr[x2 + y2*stride]; - sum += v; - sqr += v*v; - count++; - } - } - weight[x + 8*y]= (36*ff_sqrt(count*sqr - sum*sum)) / count; - } - } -} - -static av_always_inline void encode_mb_internal(MpegEncContext *s, int motion_x, int motion_y, int mb_block_height, int mb_block_count) -{ - int16_t weight[8][64]; - DCTELEM orig[8][64]; - const int mb_x= s->mb_x; - const int mb_y= s->mb_y; - int i; - int skip_dct[8]; - int dct_offset = s->linesize*8; //default for progressive frames - uint8_t *ptr_y, *ptr_cb, *ptr_cr; - int wrap_y, wrap_c; - - for(i=0; i<mb_block_count; i++) skip_dct[i]=s->skipdct; - - if(s->adaptive_quant){ - const int last_qp= s->qscale; - const int mb_xy= mb_x + mb_y*s->mb_stride; - - s->lambda= s->lambda_table[mb_xy]; - update_qscale(s); - - if(!(s->flags&CODEC_FLAG_QP_RD)){ - s->qscale= s->current_picture_ptr->qscale_table[mb_xy]; - s->dquant= s->qscale - last_qp; - - if(s->out_format==FMT_H263){ - s->dquant= av_clip(s->dquant, -2, 2); - - if(s->codec_id==CODEC_ID_MPEG4){ - if(!s->mb_intra){ - if(s->pict_type == B_TYPE){ - if(s->dquant&1 || s->mv_dir&MV_DIRECT) - s->dquant= 0; - } - if(s->mv_type==MV_TYPE_8X8) - s->dquant=0; - } - } - } - } - ff_set_qscale(s, last_qp + s->dquant); - }else if(s->flags&CODEC_FLAG_QP_RD) - ff_set_qscale(s, s->qscale + s->dquant); - - wrap_y = s->linesize; - wrap_c = s->uvlinesize; - ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16; - ptr_cb = s->new_picture.data[1] + (mb_y * mb_block_height * wrap_c) + mb_x * 8; - ptr_cr = s->new_picture.data[2] + (mb_y * mb_block_height * wrap_c) + mb_x * 8; - - if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ - uint8_t *ebuf= s->edge_emu_buffer + 32; - ff_emulated_edge_mc(ebuf , ptr_y , wrap_y,16,16,mb_x*16,mb_y*16, s->width , s->height); - ptr_y= ebuf; - ff_emulated_edge_mc(ebuf+18*wrap_y , ptr_cb, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1); - ptr_cb= ebuf+18*wrap_y; - ff_emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1); - ptr_cr= ebuf+18*wrap_y+8; - } - - if (s->mb_intra) { - if(s->flags&CODEC_FLAG_INTERLACED_DCT){ - int progressive_score, interlaced_score; - - s->interlaced_dct=0; - progressive_score= s->dsp.ildct_cmp[4](s, ptr_y , NULL, wrap_y, 8) - +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y*8, NULL, wrap_y, 8) - 400; - - if(progressive_score > 0){ - interlaced_score = s->dsp.ildct_cmp[4](s, ptr_y , NULL, wrap_y*2, 8) - +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y , NULL, wrap_y*2, 8); - if(progressive_score > interlaced_score){ - s->interlaced_dct=1; - - dct_offset= wrap_y; - wrap_y<<=1; - if (s->chroma_format == CHROMA_422) - wrap_c<<=1; - } - } - } - - s->dsp.get_pixels(s->block[0], ptr_y , wrap_y); - s->dsp.get_pixels(s->block[1], ptr_y + 8, wrap_y); - s->dsp.get_pixels(s->block[2], ptr_y + dct_offset , wrap_y); - s->dsp.get_pixels(s->block[3], ptr_y + dct_offset + 8, wrap_y); - - if(s->flags&CODEC_FLAG_GRAY){ - skip_dct[4]= 1; - skip_dct[5]= 1; - }else{ - s->dsp.get_pixels(s->block[4], ptr_cb, wrap_c); - s->dsp.get_pixels(s->block[5], ptr_cr, wrap_c); - if(!s->chroma_y_shift){ /* 422 */ - s->dsp.get_pixels(s->block[6], ptr_cb + (dct_offset>>1), wrap_c); - s->dsp.get_pixels(s->block[7], ptr_cr + (dct_offset>>1), wrap_c); - } - } - }else{ - op_pixels_func (*op_pix)[4]; - qpel_mc_func (*op_qpix)[16]; - uint8_t *dest_y, *dest_cb, *dest_cr; - - dest_y = s->dest[0]; - dest_cb = s->dest[1]; - dest_cr = s->dest[2]; - - if ((!s->no_rounding) || s->pict_type==B_TYPE){ - op_pix = s->dsp.put_pixels_tab; - op_qpix= s->dsp.put_qpel_pixels_tab; - }else{ - op_pix = s->dsp.put_no_rnd_pixels_tab; - op_qpix= s->dsp.put_no_rnd_qpel_pixels_tab; - } - - if (s->mv_dir & MV_DIR_FORWARD) { - MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix); - op_pix = s->dsp.avg_pixels_tab; - op_qpix= s->dsp.avg_qpel_pixels_tab; - } - if (s->mv_dir & MV_DIR_BACKWARD) { - MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix); - } - - if(s->flags&CODEC_FLAG_INTERLACED_DCT){ - int progressive_score, interlaced_score; - - s->interlaced_dct=0; - progressive_score= s->dsp.ildct_cmp[0](s, dest_y , ptr_y , wrap_y, 8) - +s->dsp.ildct_cmp[0](s, dest_y + wrap_y*8, ptr_y + wrap_y*8, wrap_y, 8) - 400; - - if(s->avctx->ildct_cmp == FF_CMP_VSSE) progressive_score -= 400; - - if(progressive_score>0){ - interlaced_score = s->dsp.ildct_cmp[0](s, dest_y , ptr_y , wrap_y*2, 8) - +s->dsp.ildct_cmp[0](s, dest_y + wrap_y , ptr_y + wrap_y , wrap_y*2, 8); - - if(progressive_score > interlaced_score){ - s->interlaced_dct=1; - - dct_offset= wrap_y; - wrap_y<<=1; - if (s->chroma_format == CHROMA_422) - wrap_c<<=1; - } - } - } - - s->dsp.diff_pixels(s->block[0], ptr_y , dest_y , wrap_y); - s->dsp.diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y); - s->dsp.diff_pixels(s->block[2], ptr_y + dct_offset , dest_y + dct_offset , wrap_y); - s->dsp.diff_pixels(s->block[3], ptr_y + dct_offset + 8, dest_y + dct_offset + 8, wrap_y); - - if(s->flags&CODEC_FLAG_GRAY){ - skip_dct[4]= 1; - skip_dct[5]= 1; - }else{ - s->dsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c); - s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c); - if(!s->chroma_y_shift){ /* 422 */ - s->dsp.diff_pixels(s->block[6], ptr_cb + (dct_offset>>1), dest_cb + (dct_offset>>1), wrap_c); - s->dsp.diff_pixels(s->block[7], ptr_cr + (dct_offset>>1), dest_cr + (dct_offset>>1), wrap_c); - } - } - /* pre quantization */ - if(s->current_picture.mc_mb_var[s->mb_stride*mb_y+ mb_x]<2*s->qscale*s->qscale){ - //FIXME optimize - if(s->dsp.sad[1](NULL, ptr_y , dest_y , wrap_y, 8) < 20*s->qscale) skip_dct[0]= 1; - if(s->dsp.sad[1](NULL, ptr_y + 8, dest_y + 8, wrap_y, 8) < 20*s->qscale) skip_dct[1]= 1; - if(s->dsp.sad[1](NULL, ptr_y +dct_offset , dest_y +dct_offset , wrap_y, 8) < 20*s->qscale) skip_dct[2]= 1; - if(s->dsp.sad[1](NULL, ptr_y +dct_offset+ 8, dest_y +dct_offset+ 8, wrap_y, 8) < 20*s->qscale) skip_dct[3]= 1; - if(s->dsp.sad[1](NULL, ptr_cb , dest_cb , wrap_c, 8) < 20*s->qscale) skip_dct[4]= 1; - if(s->dsp.sad[1](NULL, ptr_cr , dest_cr , wrap_c, 8) < 20*s->qscale) skip_dct[5]= 1; - if(!s->chroma_y_shift){ /* 422 */ - if(s->dsp.sad[1](NULL, ptr_cb +(dct_offset>>1), dest_cb +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[6]= 1; - if(s->dsp.sad[1](NULL, ptr_cr +(dct_offset>>1), dest_cr +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[7]= 1; - } - } - } - - if(s->avctx->quantizer_noise_shaping){ - if(!skip_dct[0]) get_vissual_weight(weight[0], ptr_y , wrap_y); - if(!skip_dct[1]) get_vissual_weight(weight[1], ptr_y + 8, wrap_y); - if(!skip_dct[2]) get_vissual_weight(weight[2], ptr_y + dct_offset , wrap_y); - if(!skip_dct[3]) get_vissual_weight(weight[3], ptr_y + dct_offset + 8, wrap_y); - if(!skip_dct[4]) get_vissual_weight(weight[4], ptr_cb , wrap_c); - if(!skip_dct[5]) get_vissual_weight(weight[5], ptr_cr , wrap_c); - if(!s->chroma_y_shift){ /* 422 */ - if(!skip_dct[6]) get_vissual_weight(weight[6], ptr_cb + (dct_offset>>1), wrap_c); - if(!skip_dct[7]) get_vissual_weight(weight[7], ptr_cr + (dct_offset>>1), wrap_c); - } - memcpy(orig[0], s->block[0], sizeof(DCTELEM)*64*mb_block_count); - } - - /* DCT & quantize */ - assert(s->out_format!=FMT_MJPEG || s->qscale==8); - { - for(i=0;i<mb_block_count;i++) { - if(!skip_dct[i]){ - int overflow; - s->block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow); - // FIXME we could decide to change to quantizer instead of clipping - // JS: I don't think that would be a good idea it could lower quality instead - // of improve it. Just INTRADC clipping deserves changes in quantizer - if (overflow) clip_coeffs(s, s->block[i], s->block_last_index[i]); - }else - s->block_last_index[i]= -1; - } - if(s->avctx->quantizer_noise_shaping){ - for(i=0;i<mb_block_count;i++) { - if(!skip_dct[i]){ - s->block_last_index[i] = dct_quantize_refine(s, s->block[i], weight[i], orig[i], i, s->qscale); - } - } - } - - if(s->luma_elim_threshold && !s->mb_intra) - for(i=0; i<4; i++) - dct_single_coeff_elimination(s, i, s->luma_elim_threshold); - if(s->chroma_elim_threshold && !s->mb_intra) - for(i=4; i<mb_block_count; i++) - dct_single_coeff_elimination(s, i, s->chroma_elim_threshold); - - if(s->flags & CODEC_FLAG_CBP_RD){ - for(i=0;i<mb_block_count;i++) { - if(s->block_last_index[i] == -1) - s->coded_score[i]= INT_MAX/256; - } - } - } - - if((s->flags&CODEC_FLAG_GRAY) && s->mb_intra){ - s->block_last_index[4]= - s->block_last_index[5]= 0; - s->block[4][0]= - s->block[5][0]= (1024 + s->c_dc_scale/2)/ s->c_dc_scale; - } - - //non c quantize code returns incorrect block_last_index FIXME - if(s->alternate_scan && s->dct_quantize != dct_quantize_c){ - for(i=0; i<mb_block_count; i++){ - int j; - if(s->block_last_index[i]>0){ - for(j=63; j>0; j--){ - if(s->block[i][ s->intra_scantable.permutated[j] ]) break; - } - s->block_last_index[i]= j; - } - } - } - - /* huffman encode */ - switch(s->codec_id){ //FIXME funct ptr could be slightly faster - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - mpeg1_encode_mb(s, s->block, motion_x, motion_y); break; - case CODEC_ID_MPEG4: - mpeg4_encode_mb(s, s->block, motion_x, motion_y); break; - case CODEC_ID_MSMPEG4V2: - case CODEC_ID_MSMPEG4V3: - case CODEC_ID_WMV1: - msmpeg4_encode_mb(s, s->block, motion_x, motion_y); break; - case CODEC_ID_WMV2: - ff_wmv2_encode_mb(s, s->block, motion_x, motion_y); break; -#ifdef CONFIG_H261_ENCODER - case CODEC_ID_H261: - ff_h261_encode_mb(s, s->block, motion_x, motion_y); break; -#endif - case CODEC_ID_H263: - case CODEC_ID_H263P: - case CODEC_ID_FLV1: - case CODEC_ID_RV10: - case CODEC_ID_RV20: - h263_encode_mb(s, s->block, motion_x, motion_y); break; - case CODEC_ID_MJPEG: - mjpeg_encode_mb(s, s->block); break; - default: - assert(0); - } -} - -static av_always_inline void encode_mb(MpegEncContext *s, int motion_x, int motion_y) -{ - if (s->chroma_format == CHROMA_420) encode_mb_internal(s, motion_x, motion_y, 8, 6); - else encode_mb_internal(s, motion_x, motion_y, 16, 8); -} - -#endif //CONFIG_ENCODERS - void ff_mpeg_flush(AVCodecContext *avctx){ int i; MpegEncContext *s = avctx->priv_data; @@ -4635,1976 +2193,6 @@ void ff_mpeg_flush(AVCodecContext *avctx){ s->pp_time=0; } -#ifdef CONFIG_ENCODERS -void ff_copy_bits(PutBitContext *pb, uint8_t *src, int length) -{ - const uint16_t *srcw= (uint16_t*)src; - int words= length>>4; - int bits= length&15; - int i; - - if(length==0) return; - - if(words < 16){ - for(i=0; i<words; i++) put_bits(pb, 16, be2me_16(srcw[i])); - }else if(put_bits_count(pb)&7){ - for(i=0; i<words; i++) put_bits(pb, 16, be2me_16(srcw[i])); - }else{ - for(i=0; put_bits_count(pb)&31; i++) - put_bits(pb, 8, src[i]); - flush_put_bits(pb); - memcpy(pbBufPtr(pb), src+i, 2*words-i); - skip_put_bytes(pb, 2*words-i); - } - - put_bits(pb, bits, be2me_16(srcw[words])>>(16-bits)); -} - -static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){ - int i; - - memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? - - /* mpeg1 */ - d->mb_skip_run= s->mb_skip_run; - for(i=0; i<3; i++) - d->last_dc[i]= s->last_dc[i]; - - /* statistics */ - d->mv_bits= s->mv_bits; - d->i_tex_bits= s->i_tex_bits; - d->p_tex_bits= s->p_tex_bits; - d->i_count= s->i_count; - d->f_count= s->f_count; - d->b_count= s->b_count; - d->skip_count= s->skip_count; - d->misc_bits= s->misc_bits; - d->last_bits= 0; - - d->mb_skipped= 0; - d->qscale= s->qscale; - d->dquant= s->dquant; -} - -static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int type){ - int i; - - memcpy(d->mv, s->mv, 2*4*2*sizeof(int)); - memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? - - /* mpeg1 */ - d->mb_skip_run= s->mb_skip_run; - for(i=0; i<3; i++) - d->last_dc[i]= s->last_dc[i]; - - /* statistics */ - d->mv_bits= s->mv_bits; - d->i_tex_bits= s->i_tex_bits; - d->p_tex_bits= s->p_tex_bits; - d->i_count= s->i_count; - d->f_count= s->f_count; - d->b_count= s->b_count; - d->skip_count= s->skip_count; - d->misc_bits= s->misc_bits; - - d->mb_intra= s->mb_intra; - d->mb_skipped= s->mb_skipped; - d->mv_type= s->mv_type; - d->mv_dir= s->mv_dir; - d->pb= s->pb; - if(s->data_partitioning){ - d->pb2= s->pb2; - d->tex_pb= s->tex_pb; - } - d->block= s->block; - for(i=0; i<8; i++) - d->block_last_index[i]= s->block_last_index[i]; - d->interlaced_dct= s->interlaced_dct; - d->qscale= s->qscale; -} - -static inline void encode_mb_hq(MpegEncContext *s, MpegEncContext *backup, MpegEncContext *best, int type, - PutBitContext pb[2], PutBitContext pb2[2], PutBitContext tex_pb[2], - int *dmin, int *next_block, int motion_x, int motion_y) -{ - int score; - uint8_t *dest_backup[3]; - - copy_context_before_encode(s, backup, type); - - s->block= s->blocks[*next_block]; - s->pb= pb[*next_block]; - if(s->data_partitioning){ - s->pb2 = pb2 [*next_block]; - s->tex_pb= tex_pb[*next_block]; - } - - if(*next_block){ - memcpy(dest_backup, s->dest, sizeof(s->dest)); - s->dest[0] = s->rd_scratchpad; - s->dest[1] = s->rd_scratchpad + 16*s->linesize; - s->dest[2] = s->rd_scratchpad + 16*s->linesize + 8; - assert(s->linesize >= 32); //FIXME - } - - encode_mb(s, motion_x, motion_y); - - score= put_bits_count(&s->pb); - if(s->data_partitioning){ - score+= put_bits_count(&s->pb2); - score+= put_bits_count(&s->tex_pb); - } - - if(s->avctx->mb_decision == FF_MB_DECISION_RD){ - MPV_decode_mb(s, s->block); - - score *= s->lambda2; - score += sse_mb(s) << FF_LAMBDA_SHIFT; - } - - if(*next_block){ - memcpy(s->dest, dest_backup, sizeof(s->dest)); - } - - if(score<*dmin){ - *dmin= score; - *next_block^=1; - - copy_context_after_encode(best, s, type); - } -} - -static int sse(MpegEncContext *s, uint8_t *src1, uint8_t *src2, int w, int h, int stride){ - uint32_t *sq = ff_squareTbl + 256; - int acc=0; - int x,y; - - if(w==16 && h==16) - return s->dsp.sse[0](NULL, src1, src2, stride, 16); - else if(w==8 && h==8) - return s->dsp.sse[1](NULL, src1, src2, stride, 8); - - for(y=0; y<h; y++){ - for(x=0; x<w; x++){ - acc+= sq[src1[x + y*stride] - src2[x + y*stride]]; - } - } - - assert(acc>=0); - - return acc; -} - -static int sse_mb(MpegEncContext *s){ - int w= 16; - int h= 16; - - if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16; - if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16; - - if(w==16 && h==16) - if(s->avctx->mb_cmp == FF_CMP_NSSE){ - return s->dsp.nsse[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16) - +s->dsp.nsse[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8) - +s->dsp.nsse[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8); - }else{ - return s->dsp.sse[0](NULL, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16) - +s->dsp.sse[1](NULL, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8) - +s->dsp.sse[1](NULL, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8); - } - else - return sse(s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], w, h, s->linesize) - +sse(s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], w>>1, h>>1, s->uvlinesize) - +sse(s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], w>>1, h>>1, s->uvlinesize); -} - -static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= arg; - - - s->me.pre_pass=1; - s->me.dia_size= s->avctx->pre_dia_size; - s->first_slice_line=1; - for(s->mb_y= s->end_mb_y-1; s->mb_y >= s->start_mb_y; s->mb_y--) { - for(s->mb_x=s->mb_width-1; s->mb_x >=0 ;s->mb_x--) { - ff_pre_estimate_p_frame_motion(s, s->mb_x, s->mb_y); - } - s->first_slice_line=0; - } - - s->me.pre_pass=0; - - return 0; -} - -static int estimate_motion_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= arg; - - ff_check_alignment(); - - s->me.dia_size= s->avctx->dia_size; - s->first_slice_line=1; - for(s->mb_y= s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { - s->mb_x=0; //for block init below - ff_init_block_index(s); - for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) { - s->block_index[0]+=2; - s->block_index[1]+=2; - s->block_index[2]+=2; - s->block_index[3]+=2; - - /* compute motion vector & mb_type and store in context */ - if(s->pict_type==B_TYPE) - ff_estimate_b_frame_motion(s, s->mb_x, s->mb_y); - else - ff_estimate_p_frame_motion(s, s->mb_x, s->mb_y); - } - s->first_slice_line=0; - } - return 0; -} - -static int mb_var_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= arg; - int mb_x, mb_y; - - ff_check_alignment(); - - for(mb_y=s->start_mb_y; mb_y < s->end_mb_y; mb_y++) { - for(mb_x=0; mb_x < s->mb_width; mb_x++) { - int xx = mb_x * 16; - int yy = mb_y * 16; - uint8_t *pix = s->new_picture.data[0] + (yy * s->linesize) + xx; - int varc; - int sum = s->dsp.pix_sum(pix, s->linesize); - - varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; - - s->current_picture.mb_var [s->mb_stride * mb_y + mb_x] = varc; - s->current_picture.mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8; - s->me.mb_var_sum_temp += varc; - } - } - return 0; -} - -static void write_slice_end(MpegEncContext *s){ - if(s->codec_id==CODEC_ID_MPEG4){ - if(s->partitioned_frame){ - ff_mpeg4_merge_partitions(s); - } - - ff_mpeg4_stuffing(&s->pb); - }else if(s->out_format == FMT_MJPEG){ - ff_mjpeg_stuffing(&s->pb); - } - - align_put_bits(&s->pb); - flush_put_bits(&s->pb); - - if((s->flags&CODEC_FLAG_PASS1) && !s->partitioned_frame) - s->misc_bits+= get_bits_diff(s); -} - -static int encode_thread(AVCodecContext *c, void *arg){ - MpegEncContext *s= arg; - int mb_x, mb_y, pdif = 0; - int i, j; - MpegEncContext best_s, backup_s; - uint8_t bit_buf[2][MAX_MB_BYTES]; - uint8_t bit_buf2[2][MAX_MB_BYTES]; - uint8_t bit_buf_tex[2][MAX_MB_BYTES]; - PutBitContext pb[2], pb2[2], tex_pb[2]; -//printf("%d->%d\n", s->resync_mb_y, s->end_mb_y); - - ff_check_alignment(); - - for(i=0; i<2; i++){ - init_put_bits(&pb [i], bit_buf [i], MAX_MB_BYTES); - init_put_bits(&pb2 [i], bit_buf2 [i], MAX_MB_BYTES); - init_put_bits(&tex_pb[i], bit_buf_tex[i], MAX_MB_BYTES); - } - - s->last_bits= put_bits_count(&s->pb); - s->mv_bits=0; - s->misc_bits=0; - s->i_tex_bits=0; - s->p_tex_bits=0; - s->i_count=0; - s->f_count=0; - s->b_count=0; - s->skip_count=0; - - for(i=0; i<3; i++){ - /* init last dc values */ - /* note: quant matrix value (8) is implied here */ - s->last_dc[i] = 128 << s->intra_dc_precision; - - s->current_picture.error[i] = 0; - } - s->mb_skip_run = 0; - memset(s->last_mv, 0, sizeof(s->last_mv)); - - s->last_mv_dir = 0; - - switch(s->codec_id){ - case CODEC_ID_H263: - case CODEC_ID_H263P: - case CODEC_ID_FLV1: - s->gob_index = ff_h263_get_gob_height(s); - break; - case CODEC_ID_MPEG4: - if(s->partitioned_frame) - ff_mpeg4_init_partitions(s); - break; - } - - s->resync_mb_x=0; - s->resync_mb_y=0; - s->first_slice_line = 1; - s->ptr_lastgob = s->pb.buf; - for(mb_y= s->start_mb_y; mb_y < s->end_mb_y; mb_y++) { -// printf("row %d at %X\n", s->mb_y, (int)s); - s->mb_x=0; - s->mb_y= mb_y; - - ff_set_qscale(s, s->qscale); - ff_init_block_index(s); - - for(mb_x=0; mb_x < s->mb_width; mb_x++) { - int xy= mb_y*s->mb_stride + mb_x; // removed const, H261 needs to adjust this - int mb_type= s->mb_type[xy]; -// int d; - int dmin= INT_MAX; - int dir; - - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - if(s->data_partitioning){ - if( s->pb2 .buf_end - s->pb2 .buf - (put_bits_count(&s-> pb2)>>3) < MAX_MB_BYTES - || s->tex_pb.buf_end - s->tex_pb.buf - (put_bits_count(&s->tex_pb )>>3) < MAX_MB_BYTES){ - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - } - - s->mb_x = mb_x; - s->mb_y = mb_y; // moved into loop, can get changed by H.261 - ff_update_block_index(s); - -#ifdef CONFIG_H261_ENCODER - if(s->codec_id == CODEC_ID_H261){ - ff_h261_reorder_mb_index(s); - xy= s->mb_y*s->mb_stride + s->mb_x; - mb_type= s->mb_type[xy]; - } -#endif - - /* write gob / video packet header */ - if(s->rtp_mode){ - int current_packet_size, is_gob_start; - - current_packet_size= ((put_bits_count(&s->pb)+7)>>3) - (s->ptr_lastgob - s->pb.buf); - - is_gob_start= s->avctx->rtp_payload_size && current_packet_size >= s->avctx->rtp_payload_size && mb_y + mb_x>0; - - if(s->start_mb_y == mb_y && mb_y > 0 && mb_x==0) is_gob_start=1; - - switch(s->codec_id){ - case CODEC_ID_H263: - case CODEC_ID_H263P: - if(!s->h263_slice_structured) - if(s->mb_x || s->mb_y%s->gob_index) is_gob_start=0; - break; - case CODEC_ID_MPEG2VIDEO: - if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1; - case CODEC_ID_MPEG1VIDEO: - if(s->mb_skip_run) is_gob_start=0; - break; - } - - if(is_gob_start){ - if(s->start_mb_y != mb_y || mb_x!=0){ - write_slice_end(s); - - if(s->codec_id==CODEC_ID_MPEG4 && s->partitioned_frame){ - ff_mpeg4_init_partitions(s); - } - } - - assert((put_bits_count(&s->pb)&7) == 0); - current_packet_size= pbBufPtr(&s->pb) - s->ptr_lastgob; - - if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){ - int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y; - int d= 100 / s->avctx->error_rate; - if(r % d == 0){ - current_packet_size=0; -#ifndef ALT_BITSTREAM_WRITER - s->pb.buf_ptr= s->ptr_lastgob; -#endif - assert(pbBufPtr(&s->pb) == s->ptr_lastgob); - } - } - - if (s->avctx->rtp_callback){ - int number_mb = (mb_y - s->resync_mb_y)*s->mb_width + mb_x - s->resync_mb_x; - s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, number_mb); - } - - switch(s->codec_id){ - case CODEC_ID_MPEG4: - ff_mpeg4_encode_video_packet_header(s); - ff_mpeg4_clean_buffers(s); - break; - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_MPEG2VIDEO: - ff_mpeg1_encode_slice_header(s); - ff_mpeg1_clean_buffers(s); - break; - case CODEC_ID_H263: - case CODEC_ID_H263P: - h263_encode_gob_header(s, mb_y); - break; - } - - if(s->flags&CODEC_FLAG_PASS1){ - int bits= put_bits_count(&s->pb); - s->misc_bits+= bits - s->last_bits; - s->last_bits= bits; - } - - s->ptr_lastgob += current_packet_size; - s->first_slice_line=1; - s->resync_mb_x=mb_x; - s->resync_mb_y=mb_y; - } - } - - if( (s->resync_mb_x == s->mb_x) - && s->resync_mb_y+1 == s->mb_y){ - s->first_slice_line=0; - } - - s->mb_skipped=0; - s->dquant=0; //only for QP_RD - - if(mb_type & (mb_type-1) || (s->flags & CODEC_FLAG_QP_RD)){ // more than 1 MB type possible or CODEC_FLAG_QP_RD - int next_block=0; - int pb_bits_count, pb2_bits_count, tex_pb_bits_count; - - copy_context_before_encode(&backup_s, s, -1); - backup_s.pb= s->pb; - best_s.data_partitioning= s->data_partitioning; - best_s.partitioned_frame= s->partitioned_frame; - if(s->data_partitioning){ - backup_s.pb2= s->pb2; - backup_s.tex_pb= s->tex_pb; - } - - if(mb_type&CANDIDATE_MB_TYPE_INTER){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[0][0][0] = s->p_mv_table[xy][0]; - s->mv[0][0][1] = s->p_mv_table[xy][1]; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]); - } - if(mb_type&CANDIDATE_MB_TYPE_INTER_I){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[0][i] = s->p_field_select_table[i][xy]; - s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0]; - s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1]; - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER_I, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_SKIPPED){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_SKIPPED, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]); - } - if(mb_type&CANDIDATE_MB_TYPE_INTER4V){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_8X8; - s->mb_intra= 0; - for(i=0; i<4; i++){ - s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0]; - s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1]; - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_FORWARD){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[0][0][0] = s->b_forw_mv_table[xy][0]; - s->mv[0][0][1] = s->b_forw_mv_table[xy][1]; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]); - } - if(mb_type&CANDIDATE_MB_TYPE_BACKWARD){ - s->mv_dir = MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[1][0][0] = s->b_back_mv_table[xy][0]; - s->mv[1][0][1] = s->b_back_mv_table[xy][1]; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[1][0][0], s->mv[1][0][1]); - } - if(mb_type&CANDIDATE_MB_TYPE_BIDIR){ - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 0; - s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0]; - s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1]; - s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0]; - s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1]; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_FORWARD_I){ - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[0][i] = s->b_field_select_table[0][i][xy]; - s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0]; - s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1]; - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD_I, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_BACKWARD_I){ - s->mv_dir = MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[1][i] = s->b_field_select_table[1][i][xy]; - s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0]; - s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1]; - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD_I, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_BIDIR_I){ - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(dir=0; dir<2; dir++){ - for(i=0; i<2; i++){ - j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy]; - s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0]; - s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1]; - } - } - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR_I, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(mb_type&CANDIDATE_MB_TYPE_INTRA){ - s->mv_dir = 0; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= 1; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTRA, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - if(s->h263_pred || s->h263_aic){ - if(best_s.mb_intra) - s->mbintra_table[mb_x + mb_y*s->mb_stride]=1; - else - ff_clean_intra_table_entries(s); //old mode? - } - } - - if((s->flags & CODEC_FLAG_QP_RD) && dmin < INT_MAX){ - if(best_s.mv_type==MV_TYPE_16X16){ //FIXME move 4mv after QPRD - const int last_qp= backup_s.qscale; - int qpi, qp, dc[6]; - DCTELEM ac[6][16]; - const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0; - static const int dquant_tab[4]={-1,1,-2,2}; - - assert(backup_s.dquant == 0); - - //FIXME intra - s->mv_dir= best_s.mv_dir; - s->mv_type = MV_TYPE_16X16; - s->mb_intra= best_s.mb_intra; - s->mv[0][0][0] = best_s.mv[0][0][0]; - s->mv[0][0][1] = best_s.mv[0][0][1]; - s->mv[1][0][0] = best_s.mv[1][0][0]; - s->mv[1][0][1] = best_s.mv[1][0][1]; - - qpi = s->pict_type == B_TYPE ? 2 : 0; - for(; qpi<4; qpi++){ - int dquant= dquant_tab[qpi]; - qp= last_qp + dquant; - if(qp < s->avctx->qmin || qp > s->avctx->qmax) - continue; - backup_s.dquant= dquant; - if(s->mb_intra && s->dc_val[0]){ - for(i=0; i<6; i++){ - dc[i]= s->dc_val[0][ s->block_index[i] ]; - memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(DCTELEM)*16); - } - } - - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER /* wrong but unused */, pb, pb2, tex_pb, - &dmin, &next_block, s->mv[mvdir][0][0], s->mv[mvdir][0][1]); - if(best_s.qscale != qp){ - if(s->mb_intra && s->dc_val[0]){ - for(i=0; i<6; i++){ - s->dc_val[0][ s->block_index[i] ]= dc[i]; - memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(DCTELEM)*16); - } - } - } - } - } - } - if(mb_type&CANDIDATE_MB_TYPE_DIRECT){ - int mx= s->b_direct_mv_table[xy][0]; - int my= s->b_direct_mv_table[xy][1]; - - backup_s.dquant = 0; - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; - s->mb_intra= 0; - ff_mpeg4_set_direct_mv(s, mx, my); - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb, - &dmin, &next_block, mx, my); - } - if(mb_type&CANDIDATE_MB_TYPE_DIRECT0){ - backup_s.dquant = 0; - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; - s->mb_intra= 0; - ff_mpeg4_set_direct_mv(s, 0, 0); - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb, - &dmin, &next_block, 0, 0); - } - if(!best_s.mb_intra && s->flags2&CODEC_FLAG2_SKIP_RD){ - int coded=0; - for(i=0; i<6; i++) - coded |= s->block_last_index[i]; - if(coded){ - int mx,my; - memcpy(s->mv, best_s.mv, sizeof(s->mv)); - if(best_s.mv_dir & MV_DIRECT){ - mx=my=0; //FIXME find the one we actually used - ff_mpeg4_set_direct_mv(s, mx, my); - }else if(best_s.mv_dir&MV_DIR_BACKWARD){ - mx= s->mv[1][0][0]; - my= s->mv[1][0][1]; - }else{ - mx= s->mv[0][0][0]; - my= s->mv[0][0][1]; - } - - s->mv_dir= best_s.mv_dir; - s->mv_type = best_s.mv_type; - s->mb_intra= 0; -/* s->mv[0][0][0] = best_s.mv[0][0][0]; - s->mv[0][0][1] = best_s.mv[0][0][1]; - s->mv[1][0][0] = best_s.mv[1][0][0]; - s->mv[1][0][1] = best_s.mv[1][0][1];*/ - backup_s.dquant= 0; - s->skipdct=1; - encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER /* wrong but unused */, pb, pb2, tex_pb, - &dmin, &next_block, mx, my); - s->skipdct=0; - } - } - - s->current_picture.qscale_table[xy]= best_s.qscale; - - copy_context_after_encode(s, &best_s, -1); - - pb_bits_count= put_bits_count(&s->pb); - flush_put_bits(&s->pb); - ff_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count); - s->pb= backup_s.pb; - - if(s->data_partitioning){ - pb2_bits_count= put_bits_count(&s->pb2); - flush_put_bits(&s->pb2); - ff_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count); - s->pb2= backup_s.pb2; - - tex_pb_bits_count= put_bits_count(&s->tex_pb); - flush_put_bits(&s->tex_pb); - ff_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count); - s->tex_pb= backup_s.tex_pb; - } - s->last_bits= put_bits_count(&s->pb); - - if (s->out_format == FMT_H263 && s->pict_type!=B_TYPE) - ff_h263_update_motion_val(s); - - if(next_block==0){ //FIXME 16 vs linesize16 - s->dsp.put_pixels_tab[0][0](s->dest[0], s->rd_scratchpad , s->linesize ,16); - s->dsp.put_pixels_tab[1][0](s->dest[1], s->rd_scratchpad + 16*s->linesize , s->uvlinesize, 8); - s->dsp.put_pixels_tab[1][0](s->dest[2], s->rd_scratchpad + 16*s->linesize + 8, s->uvlinesize, 8); - } - - if(s->avctx->mb_decision == FF_MB_DECISION_BITS) - MPV_decode_mb(s, s->block); - } else { - int motion_x = 0, motion_y = 0; - s->mv_type=MV_TYPE_16X16; - // only one MB-Type possible - - switch(mb_type){ - case CANDIDATE_MB_TYPE_INTRA: - s->mv_dir = 0; - s->mb_intra= 1; - motion_x= s->mv[0][0][0] = 0; - motion_y= s->mv[0][0][1] = 0; - break; - case CANDIDATE_MB_TYPE_INTER: - s->mv_dir = MV_DIR_FORWARD; - s->mb_intra= 0; - motion_x= s->mv[0][0][0] = s->p_mv_table[xy][0]; - motion_y= s->mv[0][0][1] = s->p_mv_table[xy][1]; - break; - case CANDIDATE_MB_TYPE_INTER_I: - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[0][i] = s->p_field_select_table[i][xy]; - s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0]; - s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1]; - } - break; - case CANDIDATE_MB_TYPE_INTER4V: - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_8X8; - s->mb_intra= 0; - for(i=0; i<4; i++){ - s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0]; - s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1]; - } - break; - case CANDIDATE_MB_TYPE_DIRECT: - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; - s->mb_intra= 0; - motion_x=s->b_direct_mv_table[xy][0]; - motion_y=s->b_direct_mv_table[xy][1]; - ff_mpeg4_set_direct_mv(s, motion_x, motion_y); - break; - case CANDIDATE_MB_TYPE_DIRECT0: - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; - s->mb_intra= 0; - ff_mpeg4_set_direct_mv(s, 0, 0); - break; - case CANDIDATE_MB_TYPE_BIDIR: - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; - s->mb_intra= 0; - s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0]; - s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1]; - s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0]; - s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1]; - break; - case CANDIDATE_MB_TYPE_BACKWARD: - s->mv_dir = MV_DIR_BACKWARD; - s->mb_intra= 0; - motion_x= s->mv[1][0][0] = s->b_back_mv_table[xy][0]; - motion_y= s->mv[1][0][1] = s->b_back_mv_table[xy][1]; - break; - case CANDIDATE_MB_TYPE_FORWARD: - s->mv_dir = MV_DIR_FORWARD; - s->mb_intra= 0; - motion_x= s->mv[0][0][0] = s->b_forw_mv_table[xy][0]; - motion_y= s->mv[0][0][1] = s->b_forw_mv_table[xy][1]; -// printf(" %d %d ", motion_x, motion_y); - break; - case CANDIDATE_MB_TYPE_FORWARD_I: - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[0][i] = s->b_field_select_table[0][i][xy]; - s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0]; - s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1]; - } - break; - case CANDIDATE_MB_TYPE_BACKWARD_I: - s->mv_dir = MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(i=0; i<2; i++){ - j= s->field_select[1][i] = s->b_field_select_table[1][i][xy]; - s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0]; - s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1]; - } - break; - case CANDIDATE_MB_TYPE_BIDIR_I: - s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; - s->mv_type = MV_TYPE_FIELD; - s->mb_intra= 0; - for(dir=0; dir<2; dir++){ - for(i=0; i<2; i++){ - j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy]; - s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0]; - s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1]; - } - } - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "illegal MB type\n"); - } - - encode_mb(s, motion_x, motion_y); - - // RAL: Update last macroblock type - s->last_mv_dir = s->mv_dir; - - if (s->out_format == FMT_H263 && s->pict_type!=B_TYPE) - ff_h263_update_motion_val(s); - - MPV_decode_mb(s, s->block); - } - - /* clean the MV table in IPS frames for direct mode in B frames */ - if(s->mb_intra /* && I,P,S_TYPE */){ - s->p_mv_table[xy][0]=0; - s->p_mv_table[xy][1]=0; - } - - if(s->flags&CODEC_FLAG_PSNR){ - int w= 16; - int h= 16; - - if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16; - if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16; - - s->current_picture.error[0] += sse( - s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, - s->dest[0], w, h, s->linesize); - s->current_picture.error[1] += sse( - s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8, - s->dest[1], w>>1, h>>1, s->uvlinesize); - s->current_picture.error[2] += sse( - s, s->new_picture .data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8, - s->dest[2], w>>1, h>>1, s->uvlinesize); - } - if(s->loop_filter){ - if(s->out_format == FMT_H263) - ff_h263_loop_filter(s); - } -//printf("MB %d %d bits\n", s->mb_x+s->mb_y*s->mb_stride, put_bits_count(&s->pb)); - } - } - - //not beautiful here but we must write it before flushing so it has to be here - if (s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type == I_TYPE) - msmpeg4_encode_ext_header(s); - - write_slice_end(s); - - /* Send the last GOB if RTP */ - if (s->avctx->rtp_callback) { - int number_mb = (mb_y - s->resync_mb_y)*s->mb_width - s->resync_mb_x; - pdif = pbBufPtr(&s->pb) - s->ptr_lastgob; - /* Call the RTP callback to send the last GOB */ - emms_c(); - s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, pdif, number_mb); - } - - return 0; -} - -#define MERGE(field) dst->field += src->field; src->field=0 -static void merge_context_after_me(MpegEncContext *dst, MpegEncContext *src){ - MERGE(me.scene_change_score); - MERGE(me.mc_mb_var_sum_temp); - MERGE(me.mb_var_sum_temp); -} - -static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src){ - int i; - - MERGE(dct_count[0]); //note, the other dct vars are not part of the context - MERGE(dct_count[1]); - MERGE(mv_bits); - MERGE(i_tex_bits); - MERGE(p_tex_bits); - MERGE(i_count); - MERGE(f_count); - MERGE(b_count); - MERGE(skip_count); - MERGE(misc_bits); - MERGE(error_count); - MERGE(padding_bug_score); - MERGE(current_picture.error[0]); - MERGE(current_picture.error[1]); - MERGE(current_picture.error[2]); - - if(dst->avctx->noise_reduction){ - for(i=0; i<64; i++){ - MERGE(dct_error_sum[0][i]); - MERGE(dct_error_sum[1][i]); - } - } - - assert(put_bits_count(&src->pb) % 8 ==0); - assert(put_bits_count(&dst->pb) % 8 ==0); - ff_copy_bits(&dst->pb, src->pb.buf, put_bits_count(&src->pb)); - flush_put_bits(&dst->pb); -} - -static int estimate_qp(MpegEncContext *s, int dry_run){ - if (s->next_lambda){ - s->current_picture_ptr->quality= - s->current_picture.quality = s->next_lambda; - if(!dry_run) s->next_lambda= 0; - } else if (!s->fixed_qscale) { - s->current_picture_ptr->quality= - s->current_picture.quality = ff_rate_estimate_qscale(s, dry_run); - if (s->current_picture.quality < 0) - return -1; - } - - if(s->adaptive_quant){ - switch(s->codec_id){ - case CODEC_ID_MPEG4: - ff_clean_mpeg4_qscales(s); - break; - case CODEC_ID_H263: - case CODEC_ID_H263P: - case CODEC_ID_FLV1: - ff_clean_h263_qscales(s); - break; - } - - s->lambda= s->lambda_table[0]; - //FIXME broken - }else - s->lambda= s->current_picture.quality; -//printf("%d %d\n", s->avctx->global_quality, s->current_picture.quality); - update_qscale(s); - return 0; -} - -static int encode_picture(MpegEncContext *s, int picture_number) -{ - int i; - int bits; - - s->picture_number = picture_number; - - /* Reset the average MB variance */ - s->me.mb_var_sum_temp = - s->me.mc_mb_var_sum_temp = 0; - - /* we need to initialize some time vars before we can encode b-frames */ - // RAL: Condition added for MPEG1VIDEO - if (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO || (s->h263_pred && !s->h263_msmpeg4)) - ff_set_mpeg4_time(s, s->picture_number); //FIXME rename and use has_b_frames or similar - - s->me.scene_change_score=0; - -// s->lambda= s->current_picture_ptr->quality; //FIXME qscale / ... stuff for ME ratedistoration - - if(s->pict_type==I_TYPE){ - if(s->msmpeg4_version >= 3) s->no_rounding=1; - else s->no_rounding=0; - }else if(s->pict_type!=B_TYPE){ - if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4) - s->no_rounding ^= 1; - } - - if(s->flags & CODEC_FLAG_PASS2){ - if (estimate_qp(s,1) < 0) - return -1; - ff_get_2pass_fcode(s); - }else if(!(s->flags & CODEC_FLAG_QSCALE)){ - if(s->pict_type==B_TYPE) - s->lambda= s->last_lambda_for[s->pict_type]; - else - s->lambda= s->last_lambda_for[s->last_non_b_pict_type]; - update_qscale(s); - } - - s->mb_intra=0; //for the rate distortion & bit compare functions - for(i=1; i<s->avctx->thread_count; i++){ - ff_update_duplicate_context(s->thread_context[i], s); - } - - ff_init_me(s); - - /* Estimate motion for every MB */ - if(s->pict_type != I_TYPE){ - s->lambda = (s->lambda * s->avctx->me_penalty_compensation + 128)>>8; - s->lambda2= (s->lambda2* (int64_t)s->avctx->me_penalty_compensation + 128)>>8; - if(s->pict_type != B_TYPE && s->avctx->me_threshold==0){ - if((s->avctx->pre_me && s->last_non_b_pict_type==I_TYPE) || s->avctx->pre_me==2){ - s->avctx->execute(s->avctx, pre_estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count); - } - } - - s->avctx->execute(s->avctx, estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count); - }else /* if(s->pict_type == I_TYPE) */{ - /* I-Frame */ - for(i=0; i<s->mb_stride*s->mb_height; i++) - s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA; - - if(!s->fixed_qscale){ - /* finding spatial complexity for I-frame rate control */ - s->avctx->execute(s->avctx, mb_var_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count); - } - } - for(i=1; i<s->avctx->thread_count; i++){ - merge_context_after_me(s, s->thread_context[i]); - } - s->current_picture.mc_mb_var_sum= s->current_picture_ptr->mc_mb_var_sum= s->me.mc_mb_var_sum_temp; - s->current_picture. mb_var_sum= s->current_picture_ptr-> mb_var_sum= s->me. mb_var_sum_temp; - emms_c(); - - if(s->me.scene_change_score > s->avctx->scenechange_threshold && s->pict_type == P_TYPE){ - s->pict_type= I_TYPE; - for(i=0; i<s->mb_stride*s->mb_height; i++) - s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA; -//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum); - } - - if(!s->umvplus){ - if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) { - s->f_code= ff_get_best_fcode(s, s->p_mv_table, CANDIDATE_MB_TYPE_INTER); - - if(s->flags & CODEC_FLAG_INTERLACED_ME){ - int a,b; - a= ff_get_best_fcode(s, s->p_field_mv_table[0][0], CANDIDATE_MB_TYPE_INTER_I); //FIXME field_select - b= ff_get_best_fcode(s, s->p_field_mv_table[1][1], CANDIDATE_MB_TYPE_INTER_I); - s->f_code= FFMAX(s->f_code, FFMAX(a,b)); - } - - ff_fix_long_p_mvs(s); - ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, 0); - if(s->flags & CODEC_FLAG_INTERLACED_ME){ - int j; - for(i=0; i<2; i++){ - for(j=0; j<2; j++) - ff_fix_long_mvs(s, s->p_field_select_table[i], j, - s->p_field_mv_table[i][j], s->f_code, CANDIDATE_MB_TYPE_INTER_I, 0); - } - } - } - - if(s->pict_type==B_TYPE){ - int a, b; - - a = ff_get_best_fcode(s, s->b_forw_mv_table, CANDIDATE_MB_TYPE_FORWARD); - b = ff_get_best_fcode(s, s->b_bidir_forw_mv_table, CANDIDATE_MB_TYPE_BIDIR); - s->f_code = FFMAX(a, b); - - a = ff_get_best_fcode(s, s->b_back_mv_table, CANDIDATE_MB_TYPE_BACKWARD); - b = ff_get_best_fcode(s, s->b_bidir_back_mv_table, CANDIDATE_MB_TYPE_BIDIR); - s->b_code = FFMAX(a, b); - - ff_fix_long_mvs(s, NULL, 0, s->b_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_FORWARD, 1); - ff_fix_long_mvs(s, NULL, 0, s->b_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BACKWARD, 1); - ff_fix_long_mvs(s, NULL, 0, s->b_bidir_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_BIDIR, 1); - ff_fix_long_mvs(s, NULL, 0, s->b_bidir_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BIDIR, 1); - if(s->flags & CODEC_FLAG_INTERLACED_ME){ - int dir, j; - for(dir=0; dir<2; dir++){ - for(i=0; i<2; i++){ - for(j=0; j<2; j++){ - int type= dir ? (CANDIDATE_MB_TYPE_BACKWARD_I|CANDIDATE_MB_TYPE_BIDIR_I) - : (CANDIDATE_MB_TYPE_FORWARD_I |CANDIDATE_MB_TYPE_BIDIR_I); - ff_fix_long_mvs(s, s->b_field_select_table[dir][i], j, - s->b_field_mv_table[dir][i][j], dir ? s->b_code : s->f_code, type, 1); - } - } - } - } - } - } - - if (estimate_qp(s, 0) < 0) - return -1; - - if(s->qscale < 3 && s->max_qcoeff<=128 && s->pict_type==I_TYPE && !(s->flags & CODEC_FLAG_QSCALE)) - s->qscale= 3; //reduce clipping problems - - if (s->out_format == FMT_MJPEG) { - /* for mjpeg, we do include qscale in the matrix */ - s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0]; - for(i=1;i<64;i++){ - int j= s->dsp.idct_permutation[i]; - - s->intra_matrix[j] = av_clip_uint8((ff_mpeg1_default_intra_matrix[i] * s->qscale) >> 3); - } - convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16, - s->intra_matrix, s->intra_quant_bias, 8, 8, 1); - s->qscale= 8; - } - - //FIXME var duplication - s->current_picture_ptr->key_frame= - s->current_picture.key_frame= s->pict_type == I_TYPE; //FIXME pic_ptr - s->current_picture_ptr->pict_type= - s->current_picture.pict_type= s->pict_type; - - if(s->current_picture.key_frame) - s->picture_in_gop_number=0; - - s->last_bits= put_bits_count(&s->pb); - switch(s->out_format) { - case FMT_MJPEG: - mjpeg_picture_header(s); - break; -#ifdef CONFIG_H261_ENCODER - case FMT_H261: - ff_h261_encode_picture_header(s, picture_number); - break; -#endif - case FMT_H263: - if (s->codec_id == CODEC_ID_WMV2) - ff_wmv2_encode_picture_header(s, picture_number); - else if (s->h263_msmpeg4) - msmpeg4_encode_picture_header(s, picture_number); - else if (s->h263_pred) - mpeg4_encode_picture_header(s, picture_number); -#ifdef CONFIG_RV10_ENCODER - else if (s->codec_id == CODEC_ID_RV10) - rv10_encode_picture_header(s, picture_number); -#endif -#ifdef CONFIG_RV20_ENCODER - else if (s->codec_id == CODEC_ID_RV20) - rv20_encode_picture_header(s, picture_number); -#endif - else if (s->codec_id == CODEC_ID_FLV1) - ff_flv_encode_picture_header(s, picture_number); - else - h263_encode_picture_header(s, picture_number); - break; - case FMT_MPEG1: - mpeg1_encode_picture_header(s, picture_number); - break; - case FMT_H264: - break; - default: - assert(0); - } - bits= put_bits_count(&s->pb); - s->header_bits= bits - s->last_bits; - - for(i=1; i<s->avctx->thread_count; i++){ - update_duplicate_context_after_me(s->thread_context[i], s); - } - s->avctx->execute(s->avctx, encode_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count); - for(i=1; i<s->avctx->thread_count; i++){ - merge_context_after_encode(s, s->thread_context[i]); - } - emms_c(); - return 0; -} - -static void denoise_dct_c(MpegEncContext *s, DCTELEM *block){ - const int intra= s->mb_intra; - int i; - - s->dct_count[intra]++; - - for(i=0; i<64; i++){ - int level= block[i]; - - if(level){ - if(level>0){ - s->dct_error_sum[intra][i] += level; - level -= s->dct_offset[intra][i]; - if(level<0) level=0; - }else{ - s->dct_error_sum[intra][i] -= level; - level += s->dct_offset[intra][i]; - if(level>0) level=0; - } - block[i]= level; - } - } -} - -static int dct_quantize_trellis_c(MpegEncContext *s, - DCTELEM *block, int n, - int qscale, int *overflow){ - const int *qmat; - const uint8_t *scantable= s->intra_scantable.scantable; - const uint8_t *perm_scantable= s->intra_scantable.permutated; - int max=0; - unsigned int threshold1, threshold2; - int bias=0; - int run_tab[65]; - int level_tab[65]; - int score_tab[65]; - int survivor[65]; - int survivor_count; - int last_run=0; - int last_level=0; - int last_score= 0; - int last_i; - int coeff[2][64]; - int coeff_count[64]; - int qmul, qadd, start_i, last_non_zero, i, dc; - const int esc_length= s->ac_esc_length; - uint8_t * length; - uint8_t * last_length; - const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6); - - s->dsp.fdct (block); - - if(s->dct_error_sum) - s->denoise_dct(s, block); - qmul= qscale*16; - qadd= ((qscale-1)|1)*8; - - if (s->mb_intra) { - int q; - if (!s->h263_aic) { - if (n < 4) - q = s->y_dc_scale; - else - q = s->c_dc_scale; - q = q << 3; - } else{ - /* For AIC we skip quant/dequant of INTRADC */ - q = 1 << 3; - qadd=0; - } - - /* note: block[0] is assumed to be positive */ - block[0] = (block[0] + (q >> 1)) / q; - start_i = 1; - last_non_zero = 0; - qmat = s->q_intra_matrix[qscale]; - if(s->mpeg_quant || s->out_format == FMT_MPEG1) - bias= 1<<(QMAT_SHIFT-1); - length = s->intra_ac_vlc_length; - last_length= s->intra_ac_vlc_last_length; - } else { - start_i = 0; - last_non_zero = -1; - qmat = s->q_inter_matrix[qscale]; - length = s->inter_ac_vlc_length; - last_length= s->inter_ac_vlc_last_length; - } - last_i= start_i; - - threshold1= (1<<QMAT_SHIFT) - bias - 1; - threshold2= (threshold1<<1); - - for(i=63; i>=start_i; i--) { - const int j = scantable[i]; - int level = block[j] * qmat[j]; - - if(((unsigned)(level+threshold1))>threshold2){ - last_non_zero = i; - break; - } - } - - for(i=start_i; i<=last_non_zero; i++) { - const int j = scantable[i]; - int level = block[j] * qmat[j]; - -// if( bias+level >= (1<<(QMAT_SHIFT - 3)) -// || bias-level >= (1<<(QMAT_SHIFT - 3))){ - if(((unsigned)(level+threshold1))>threshold2){ - if(level>0){ - level= (bias + level)>>QMAT_SHIFT; - coeff[0][i]= level; - coeff[1][i]= level-1; -// coeff[2][k]= level-2; - }else{ - level= (bias - level)>>QMAT_SHIFT; - coeff[0][i]= -level; - coeff[1][i]= -level+1; -// coeff[2][k]= -level+2; - } - coeff_count[i]= FFMIN(level, 2); - assert(coeff_count[i]); - max |=level; - }else{ - coeff[0][i]= (level>>31)|1; - coeff_count[i]= 1; - } - } - - *overflow= s->max_qcoeff < max; //overflow might have happened - - if(last_non_zero < start_i){ - memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM)); - return last_non_zero; - } - - score_tab[start_i]= 0; - survivor[0]= start_i; - survivor_count= 1; - - for(i=start_i; i<=last_non_zero; i++){ - int level_index, j; - const int dct_coeff= FFABS(block[ scantable[i] ]); - const int zero_distoration= dct_coeff*dct_coeff; - int best_score=256*256*256*120; - for(level_index=0; level_index < coeff_count[i]; level_index++){ - int distoration; - int level= coeff[level_index][i]; - const int alevel= FFABS(level); - int unquant_coeff; - - assert(level); - - if(s->out_format == FMT_H263){ - unquant_coeff= alevel*qmul + qadd; - }else{ //MPEG1 - j= s->dsp.idct_permutation[ scantable[i] ]; //FIXME optimize - if(s->mb_intra){ - unquant_coeff = (int)( alevel * qscale * s->intra_matrix[j]) >> 3; - unquant_coeff = (unquant_coeff - 1) | 1; - }else{ - unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) s->inter_matrix[j])) >> 4; - unquant_coeff = (unquant_coeff - 1) | 1; - } - unquant_coeff<<= 3; - } - - distoration= (unquant_coeff - dct_coeff) * (unquant_coeff - dct_coeff) - zero_distoration; - level+=64; - if((level&(~127)) == 0){ - for(j=survivor_count-1; j>=0; j--){ - int run= i - survivor[j]; - int score= distoration + length[UNI_AC_ENC_INDEX(run, level)]*lambda; - score += score_tab[i-run]; - - if(score < best_score){ - best_score= score; - run_tab[i+1]= run; - level_tab[i+1]= level-64; - } - } - - if(s->out_format == FMT_H263){ - for(j=survivor_count-1; j>=0; j--){ - int run= i - survivor[j]; - int score= distoration + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda; - score += score_tab[i-run]; - if(score < last_score){ - last_score= score; - last_run= run; - last_level= level-64; - last_i= i+1; - } - } - } - }else{ - distoration += esc_length*lambda; - for(j=survivor_count-1; j>=0; j--){ - int run= i - survivor[j]; - int score= distoration + score_tab[i-run]; - - if(score < best_score){ - best_score= score; - run_tab[i+1]= run; - level_tab[i+1]= level-64; - } - } - - if(s->out_format == FMT_H263){ - for(j=survivor_count-1; j>=0; j--){ - int run= i - survivor[j]; - int score= distoration + score_tab[i-run]; - if(score < last_score){ - last_score= score; - last_run= run; - last_level= level-64; - last_i= i+1; - } - } - } - } - } - - score_tab[i+1]= best_score; - - //Note: there is a vlc code in mpeg4 which is 1 bit shorter then another one with a shorter run and the same level - if(last_non_zero <= 27){ - for(; survivor_count; survivor_count--){ - if(score_tab[ survivor[survivor_count-1] ] <= best_score) - break; - } - }else{ - for(; survivor_count; survivor_count--){ - if(score_tab[ survivor[survivor_count-1] ] <= best_score + lambda) - break; - } - } - - survivor[ survivor_count++ ]= i+1; - } - - if(s->out_format != FMT_H263){ - last_score= 256*256*256*120; - for(i= survivor[0]; i<=last_non_zero + 1; i++){ - int score= score_tab[i]; - if(i) score += lambda*2; //FIXME exacter? - - if(score < last_score){ - last_score= score; - last_i= i; - last_level= level_tab[i]; - last_run= run_tab[i]; - } - } - } - - s->coded_score[n] = last_score; - - dc= FFABS(block[0]); - last_non_zero= last_i - 1; - memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM)); - - if(last_non_zero < start_i) - return last_non_zero; - - if(last_non_zero == 0 && start_i == 0){ - int best_level= 0; - int best_score= dc * dc; - - for(i=0; i<coeff_count[0]; i++){ - int level= coeff[i][0]; - int alevel= FFABS(level); - int unquant_coeff, score, distortion; - - if(s->out_format == FMT_H263){ - unquant_coeff= (alevel*qmul + qadd)>>3; - }else{ //MPEG1 - unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) s->inter_matrix[0])) >> 4; - unquant_coeff = (unquant_coeff - 1) | 1; - } - unquant_coeff = (unquant_coeff + 4) >> 3; - unquant_coeff<<= 3 + 3; - - distortion= (unquant_coeff - dc) * (unquant_coeff - dc); - level+=64; - if((level&(~127)) == 0) score= distortion + last_length[UNI_AC_ENC_INDEX(0, level)]*lambda; - else score= distortion + esc_length*lambda; - - if(score < best_score){ - best_score= score; - best_level= level - 64; - } - } - block[0]= best_level; - s->coded_score[n] = best_score - dc*dc; - if(best_level == 0) return -1; - else return last_non_zero; - } - - i= last_i; - assert(last_level); - - block[ perm_scantable[last_non_zero] ]= last_level; - i -= last_run + 1; - - for(; i>start_i; i -= run_tab[i] + 1){ - block[ perm_scantable[i-1] ]= level_tab[i]; - } - - return last_non_zero; -} - -//#define REFINE_STATS 1 -static int16_t basis[64][64]; - -static void build_basis(uint8_t *perm){ - int i, j, x, y; - emms_c(); - for(i=0; i<8; i++){ - for(j=0; j<8; j++){ - for(y=0; y<8; y++){ - for(x=0; x<8; x++){ - double s= 0.25*(1<<BASIS_SHIFT); - int index= 8*i + j; - int perm_index= perm[index]; - if(i==0) s*= sqrt(0.5); - if(j==0) s*= sqrt(0.5); - basis[perm_index][8*x + y]= lrintf(s * cos((M_PI/8.0)*i*(x+0.5)) * cos((M_PI/8.0)*j*(y+0.5))); - } - } - } - } -} - -static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise? - DCTELEM *block, int16_t *weight, DCTELEM *orig, - int n, int qscale){ - int16_t rem[64]; - DECLARE_ALIGNED_16(DCTELEM, d1[64]); - const int *qmat; - const uint8_t *scantable= s->intra_scantable.scantable; - const uint8_t *perm_scantable= s->intra_scantable.permutated; -// unsigned int threshold1, threshold2; -// int bias=0; - int run_tab[65]; - int prev_run=0; - int prev_level=0; - int qmul, qadd, start_i, last_non_zero, i, dc; - uint8_t * length; - uint8_t * last_length; - int lambda; - int rle_index, run, q = 1, sum; //q is only used when s->mb_intra is true -#ifdef REFINE_STATS -static int count=0; -static int after_last=0; -static int to_zero=0; -static int from_zero=0; -static int raise=0; -static int lower=0; -static int messed_sign=0; -#endif - - if(basis[0][0] == 0) - build_basis(s->dsp.idct_permutation); - - qmul= qscale*2; - qadd= (qscale-1)|1; - if (s->mb_intra) { - if (!s->h263_aic) { - if (n < 4) - q = s->y_dc_scale; - else - q = s->c_dc_scale; - } else{ - /* For AIC we skip quant/dequant of INTRADC */ - q = 1; - qadd=0; - } - q <<= RECON_SHIFT-3; - /* note: block[0] is assumed to be positive */ - dc= block[0]*q; -// block[0] = (block[0] + (q >> 1)) / q; - start_i = 1; - qmat = s->q_intra_matrix[qscale]; -// if(s->mpeg_quant || s->out_format == FMT_MPEG1) -// bias= 1<<(QMAT_SHIFT-1); - length = s->intra_ac_vlc_length; - last_length= s->intra_ac_vlc_last_length; - } else { - dc= 0; - start_i = 0; - qmat = s->q_inter_matrix[qscale]; - length = s->inter_ac_vlc_length; - last_length= s->inter_ac_vlc_last_length; - } - last_non_zero = s->block_last_index[n]; - -#ifdef REFINE_STATS -{START_TIMER -#endif - dc += (1<<(RECON_SHIFT-1)); - for(i=0; i<64; i++){ - rem[i]= dc - (orig[i]<<RECON_SHIFT); //FIXME use orig dirrectly instead of copying to rem[] - } -#ifdef REFINE_STATS -STOP_TIMER("memset rem[]")} -#endif - sum=0; - for(i=0; i<64; i++){ - int one= 36; - int qns=4; - int w; - - w= FFABS(weight[i]) + qns*one; - w= 15 + (48*qns*one + w/2)/w; // 16 .. 63 - - weight[i] = w; -// w=weight[i] = (63*qns + (w/2)) / w; - - assert(w>0); - assert(w<(1<<6)); - sum += w*w; - } - lambda= sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6); -#ifdef REFINE_STATS -{START_TIMER -#endif - run=0; - rle_index=0; - for(i=start_i; i<=last_non_zero; i++){ - int j= perm_scantable[i]; - const int level= block[j]; - int coeff; - - if(level){ - if(level<0) coeff= qmul*level - qadd; - else coeff= qmul*level + qadd; - run_tab[rle_index++]=run; - run=0; - - s->dsp.add_8x8basis(rem, basis[j], coeff); - }else{ - run++; - } - } -#ifdef REFINE_STATS -if(last_non_zero>0){ -STOP_TIMER("init rem[]") -} -} - -{START_TIMER -#endif - for(;;){ - int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0); - int best_coeff=0; - int best_change=0; - int run2, best_unquant_change=0, analyze_gradient; -#ifdef REFINE_STATS -{START_TIMER -#endif - analyze_gradient = last_non_zero > 2 || s->avctx->quantizer_noise_shaping >= 3; - - if(analyze_gradient){ -#ifdef REFINE_STATS -{START_TIMER -#endif - for(i=0; i<64; i++){ - int w= weight[i]; - - d1[i] = (rem[i]*w*w + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12); - } -#ifdef REFINE_STATS -STOP_TIMER("rem*w*w")} -{START_TIMER -#endif - s->dsp.fdct(d1); -#ifdef REFINE_STATS -STOP_TIMER("dct")} -#endif - } - - if(start_i){ - const int level= block[0]; - int change, old_coeff; - - assert(s->mb_intra); - - old_coeff= q*level; - - for(change=-1; change<=1; change+=2){ - int new_level= level + change; - int score, new_coeff; - - new_coeff= q*new_level; - if(new_coeff >= 2048 || new_coeff < 0) - continue; - - score= s->dsp.try_8x8basis(rem, weight, basis[0], new_coeff - old_coeff); - if(score<best_score){ - best_score= score; - best_coeff= 0; - best_change= change; - best_unquant_change= new_coeff - old_coeff; - } - } - } - - run=0; - rle_index=0; - run2= run_tab[rle_index++]; - prev_level=0; - prev_run=0; - - for(i=start_i; i<64; i++){ - int j= perm_scantable[i]; - const int level= block[j]; - int change, old_coeff; - - if(s->avctx->quantizer_noise_shaping < 3 && i > last_non_zero + 1) - break; - - if(level){ - if(level<0) old_coeff= qmul*level - qadd; - else old_coeff= qmul*level + qadd; - run2= run_tab[rle_index++]; //FIXME ! maybe after last - }else{ - old_coeff=0; - run2--; - assert(run2>=0 || i >= last_non_zero ); - } - - for(change=-1; change<=1; change+=2){ - int new_level= level + change; - int score, new_coeff, unquant_change; - - score=0; - if(s->avctx->quantizer_noise_shaping < 2 && FFABS(new_level) > FFABS(level)) - continue; - - if(new_level){ - if(new_level<0) new_coeff= qmul*new_level - qadd; - else new_coeff= qmul*new_level + qadd; - if(new_coeff >= 2048 || new_coeff <= -2048) - continue; - //FIXME check for overflow - - if(level){ - if(level < 63 && level > -63){ - if(i < last_non_zero) - score += length[UNI_AC_ENC_INDEX(run, new_level+64)] - - length[UNI_AC_ENC_INDEX(run, level+64)]; - else - score += last_length[UNI_AC_ENC_INDEX(run, new_level+64)] - - last_length[UNI_AC_ENC_INDEX(run, level+64)]; - } - }else{ - assert(FFABS(new_level)==1); - - if(analyze_gradient){ - int g= d1[ scantable[i] ]; - if(g && (g^new_level) >= 0) - continue; - } - - if(i < last_non_zero){ - int next_i= i + run2 + 1; - int next_level= block[ perm_scantable[next_i] ] + 64; - - if(next_level&(~127)) - next_level= 0; - - if(next_i < last_non_zero) - score += length[UNI_AC_ENC_INDEX(run, 65)] - + length[UNI_AC_ENC_INDEX(run2, next_level)] - - length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]; - else - score += length[UNI_AC_ENC_INDEX(run, 65)] - + last_length[UNI_AC_ENC_INDEX(run2, next_level)] - - last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]; - }else{ - score += last_length[UNI_AC_ENC_INDEX(run, 65)]; - if(prev_level){ - score += length[UNI_AC_ENC_INDEX(prev_run, prev_level)] - - last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)]; - } - } - } - }else{ - new_coeff=0; - assert(FFABS(level)==1); - - if(i < last_non_zero){ - int next_i= i + run2 + 1; - int next_level= block[ perm_scantable[next_i] ] + 64; - - if(next_level&(~127)) - next_level= 0; - - if(next_i < last_non_zero) - score += length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)] - - length[UNI_AC_ENC_INDEX(run2, next_level)] - - length[UNI_AC_ENC_INDEX(run, 65)]; - else - score += last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)] - - last_length[UNI_AC_ENC_INDEX(run2, next_level)] - - length[UNI_AC_ENC_INDEX(run, 65)]; - }else{ - score += -last_length[UNI_AC_ENC_INDEX(run, 65)]; - if(prev_level){ - score += last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)] - - length[UNI_AC_ENC_INDEX(prev_run, prev_level)]; - } - } - } - - score *= lambda; - - unquant_change= new_coeff - old_coeff; - assert((score < 100*lambda && score > -100*lambda) || lambda==0); - - score+= s->dsp.try_8x8basis(rem, weight, basis[j], unquant_change); - if(score<best_score){ - best_score= score; - best_coeff= i; - best_change= change; - best_unquant_change= unquant_change; - } - } - if(level){ - prev_level= level + 64; - if(prev_level&(~127)) - prev_level= 0; - prev_run= run; - run=0; - }else{ - run++; - } - } -#ifdef REFINE_STATS -STOP_TIMER("iterative step")} -#endif - - if(best_change){ - int j= perm_scantable[ best_coeff ]; - - block[j] += best_change; - - if(best_coeff > last_non_zero){ - last_non_zero= best_coeff; - assert(block[j]); -#ifdef REFINE_STATS -after_last++; -#endif - }else{ -#ifdef REFINE_STATS -if(block[j]){ - if(block[j] - best_change){ - if(FFABS(block[j]) > FFABS(block[j] - best_change)){ - raise++; - }else{ - lower++; - } - }else{ - from_zero++; - } -}else{ - to_zero++; -} -#endif - for(; last_non_zero>=start_i; last_non_zero--){ - if(block[perm_scantable[last_non_zero]]) - break; - } - } -#ifdef REFINE_STATS -count++; -if(256*256*256*64 % count == 0){ - printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\n", after_last, to_zero, from_zero, raise, lower, messed_sign, s->mb_x, s->mb_y, s->picture_number); -} -#endif - run=0; - rle_index=0; - for(i=start_i; i<=last_non_zero; i++){ - int j= perm_scantable[i]; - const int level= block[j]; - - if(level){ - run_tab[rle_index++]=run; - run=0; - }else{ - run++; - } - } - - s->dsp.add_8x8basis(rem, basis[j], best_unquant_change); - }else{ - break; - } - } -#ifdef REFINE_STATS -if(last_non_zero>0){ -STOP_TIMER("iterative search") -} -} -#endif - - return last_non_zero; -} - -static int dct_quantize_c(MpegEncContext *s, - DCTELEM *block, int n, - int qscale, int *overflow) -{ - int i, j, level, last_non_zero, q, start_i; - const int *qmat; - const uint8_t *scantable= s->intra_scantable.scantable; - int bias; - int max=0; - unsigned int threshold1, threshold2; - - s->dsp.fdct (block); - - if(s->dct_error_sum) - s->denoise_dct(s, block); - - if (s->mb_intra) { - if (!s->h263_aic) { - if (n < 4) - q = s->y_dc_scale; - else - q = s->c_dc_scale; - q = q << 3; - } else - /* For AIC we skip quant/dequant of INTRADC */ - q = 1 << 3; - - /* note: block[0] is assumed to be positive */ - block[0] = (block[0] + (q >> 1)) / q; - start_i = 1; - last_non_zero = 0; - qmat = s->q_intra_matrix[qscale]; - bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT); - } else { - start_i = 0; - last_non_zero = -1; - qmat = s->q_inter_matrix[qscale]; - bias= s->inter_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT); - } - threshold1= (1<<QMAT_SHIFT) - bias - 1; - threshold2= (threshold1<<1); - for(i=63;i>=start_i;i--) { - j = scantable[i]; - level = block[j] * qmat[j]; - - if(((unsigned)(level+threshold1))>threshold2){ - last_non_zero = i; - break; - }else{ - block[j]=0; - } - } - for(i=start_i; i<=last_non_zero; i++) { - j = scantable[i]; - level = block[j] * qmat[j]; - -// if( bias+level >= (1<<QMAT_SHIFT) -// || bias-level >= (1<<QMAT_SHIFT)){ - if(((unsigned)(level+threshold1))>threshold2){ - if(level>0){ - level= (bias + level)>>QMAT_SHIFT; - block[j]= level; - }else{ - level= (bias - level)>>QMAT_SHIFT; - block[j]= -level; - } - max |=level; - }else{ - block[j]=0; - } - } - *overflow= s->max_qcoeff < max; //overflow might have happened - - /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */ - if (s->dsp.idct_permutation_type != FF_NO_IDCT_PERM) - ff_block_permute(block, s->dsp.idct_permutation, scantable, last_non_zero); - - return last_non_zero; -} - -#endif //CONFIG_ENCODERS - static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s, DCTELEM *block, int n, int qscale) { @@ -6823,127 +2411,19 @@ static void dct_unquantize_h263_inter_c(MpegEncContext *s, } } -#ifdef CONFIG_ENCODERS -AVCodec h263_encoder = { - "h263", - CODEC_TYPE_VIDEO, - CODEC_ID_H263, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -AVCodec h263p_encoder = { - "h263p", - CODEC_TYPE_VIDEO, - CODEC_ID_H263P, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -AVCodec flv_encoder = { - "flv", - CODEC_TYPE_VIDEO, - CODEC_ID_FLV1, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -AVCodec rv10_encoder = { - "rv10", - CODEC_TYPE_VIDEO, - CODEC_ID_RV10, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -AVCodec rv20_encoder = { - "rv20", - CODEC_TYPE_VIDEO, - CODEC_ID_RV20, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -AVCodec mpeg4_encoder = { - "mpeg4", - CODEC_TYPE_VIDEO, - CODEC_ID_MPEG4, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, - .capabilities= CODEC_CAP_DELAY, -}; - -AVCodec msmpeg4v1_encoder = { - "msmpeg4v1", - CODEC_TYPE_VIDEO, - CODEC_ID_MSMPEG4V1, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -AVCodec msmpeg4v2_encoder = { - "msmpeg4v2", - CODEC_TYPE_VIDEO, - CODEC_ID_MSMPEG4V2, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -AVCodec msmpeg4v3_encoder = { - "msmpeg4", - CODEC_TYPE_VIDEO, - CODEC_ID_MSMPEG4V3, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; - -AVCodec wmv1_encoder = { - "wmv1", - CODEC_TYPE_VIDEO, - CODEC_ID_WMV1, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; +/** + * set qscale and update qscale dependent variables. + */ +void ff_set_qscale(MpegEncContext * s, int qscale) +{ + if (qscale < 1) + qscale = 1; + else if (qscale > 31) + qscale = 31; -AVCodec mjpeg_encoder = { - "mjpeg", - CODEC_TYPE_VIDEO, - CODEC_ID_MJPEG, - sizeof(MpegEncContext), - MPV_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, -1}, -}; + s->qscale = qscale; + s->chroma_qscale= s->chroma_qscale_table[qscale]; -#endif //CONFIG_ENCODERS + s->y_dc_scale= s->y_dc_scale_table[ qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ]; +} diff --git a/contrib/ffmpeg/libavcodec/mpegvideo.h b/contrib/ffmpeg/libavcodec/mpegvideo.h index 80e0f9065..37c60ca57 100644 --- a/contrib/ffmpeg/libavcodec/mpegvideo.h +++ b/contrib/ffmpeg/libavcodec/mpegvideo.h @@ -25,8 +25,8 @@ * mpegvideo header. */ -#ifndef AVCODEC_MPEGVIDEO_H -#define AVCODEC_MPEGVIDEO_H +#ifndef FFMPEG_MPEGVIDEO_H +#define FFMPEG_MPEGVIDEO_H #include "dsputil.h" #include "bitstream.h" @@ -76,6 +76,16 @@ enum OutputFormat { #define INPLACE_OFFSET 16 +/* Start codes. */ +#define SEQ_END_CODE 0x000001b7 +#define SEQ_START_CODE 0x000001b3 +#define GOP_START_CODE 0x000001b8 +#define PICTURE_START_CODE 0x00000100 +#define SLICE_MIN_START_CODE 0x00000101 +#define SLICE_MAX_START_CODE 0x000001af +#define EXT_START_CODE 0x000001b5 +#define USER_START_CODE 0x000001b2 + /** * Scantable. */ @@ -84,7 +94,7 @@ typedef struct ScanTable{ uint8_t permutated[64]; uint8_t raster_end[64]; #ifdef ARCH_POWERPC - /** Used by dct_quantise_alitvec to find last-non-zero */ + /** Used by dct_quantize_altivec to find last-non-zero */ DECLARE_ALIGNED_8(uint8_t, inverse[64]); #endif } ScanTable; @@ -101,7 +111,7 @@ typedef struct Picture{ 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 MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if there is 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) @@ -123,13 +133,14 @@ typedef struct Picture{ #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 USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0|MB_TYPE_P1L0)<<(2*(list)))) ///< does this mb use listX, note does not 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 frame_num; ///< h264 frame_num (raw frame_num from slice header) + int pic_id; /**< h264 pic_num (short -> no wrap version of pic_num, + pic_num & max_pic_num; long -> long_pic_num) */ 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 @@ -151,9 +162,9 @@ struct MpegEncContext; 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 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 *scratchpad; ///< data area for the ME algo, so that the ME does not need to malloc/free uint8_t *best_mb; uint8_t *temp_mb[2]; uint8_t *temp; @@ -238,8 +249,8 @@ typedef struct MpegEncContext { /* 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 input_picture_number; ///< used to set pic->display_picture_number, should not be used for/by anything else + int coded_picture_number; ///< used to set pic->coded_picture_number, should not 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 @@ -358,8 +369,8 @@ typedef struct MpegEncContext { 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_DIR_FORWARD 1 +#define MV_DIR_BACKWARD 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 @@ -381,7 +392,7 @@ typedef struct MpegEncContext { MotionEstContext me; int no_rounding; /**< apply no rounding to motion compensation (MPEG4, msmpeg4, ...) - for b-frames rounding mode is allways 0 */ + for b-frames rounding mode is always 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 */ @@ -579,8 +590,6 @@ typedef struct MpegEncContext { 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; @@ -681,7 +690,6 @@ typedef struct MpegEncContext { } MpegEncContext; -int DCT_common_init(MpegEncContext *s); void MPV_decode_defaults(MpegEncContext *s); int MPV_common_init(MpegEncContext *s); void MPV_common_end(MpegEncContext *s); @@ -691,26 +699,13 @@ void MPV_frame_end(MpegEncContext *s); int MPV_encode_init(AVCodecContext *avctx); int MPV_encode_end(AVCodecContext *avctx); int MPV_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data); -#ifdef HAVE_MMX void MPV_common_init_mmx(MpegEncContext *s); -#endif -#ifdef ARCH_ALPHA void MPV_common_init_axp(MpegEncContext *s); -#endif -#ifdef HAVE_MLIB void MPV_common_init_mlib(MpegEncContext *s); -#endif -#ifdef HAVE_MMI void MPV_common_init_mmi(MpegEncContext *s); -#endif -#ifdef ARCH_ARMV4L void MPV_common_init_armv4l(MpegEncContext *s); -#endif -#ifdef ARCH_POWERPC -void MPV_common_init_ppc(MpegEncContext *s); -#endif +void MPV_common_init_altivec(MpegEncContext *s); extern void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w); -void ff_copy_bits(PutBitContext *pb, uint8_t *src, int length); void ff_clean_intra_table_entries(MpegEncContext *s); void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable); void ff_draw_horiz_band(MpegEncContext *s, int y, int h); @@ -728,8 +723,9 @@ void ff_er_frame_start(MpegEncContext *s); void ff_er_frame_end(MpegEncContext *s); void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status); - -extern enum PixelFormat ff_yuv420p_list[2]; +int ff_dct_common_init(MpegEncContext *s); +void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64], + const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra); void ff_init_block_index(MpegEncContext *s); @@ -756,6 +752,14 @@ static inline int get_bits_diff(MpegEncContext *s){ return bits - last; } +static inline int ff_h263_round_chroma(int x){ + static const uint8_t h263_chroma_roundtab[16] = { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, + }; + return h263_chroma_roundtab[x & 0xf] + (x >> 3); +} + /* motion_est.c */ void ff_estimate_p_frame_motion(MpegEncContext * s, int mb_x, int mb_y); @@ -767,16 +771,17 @@ void ff_fix_long_mvs(MpegEncContext * s, uint8_t *field_select_table, int field_ 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 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 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]; +extern const AVRational ff_frame_rate_tab[]; void mpeg1_encode_picture_header(MpegEncContext *s, int picture_number); void mpeg1_encode_mb(MpegEncContext *s, @@ -785,6 +790,7 @@ void mpeg1_encode_mb(MpegEncContext *s, 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); #include "rl.h" @@ -811,7 +817,7 @@ int ff_h261_get_picture_format(int width, int height); 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); + const uint8_t *buf, int buf_size); int ff_h263_decode_end(AVCodecContext *avctx); void h263_encode_mb(MpegEncContext *s, DCTELEM block[6][64], @@ -826,13 +832,9 @@ 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 ff_set_mpeg4_time(MpegEncContext * s); 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); @@ -863,7 +865,6 @@ 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); @@ -895,14 +896,5 @@ 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); - -#endif /* AVCODEC_MPEGVIDEO_H */ +#endif /* FFMPEG_MPEGVIDEO_H */ diff --git a/contrib/ffmpeg/libavcodec/mpegvideo_common.h b/contrib/ffmpeg/libavcodec/mpegvideo_common.h new file mode 100644 index 000000000..f2655a954 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpegvideo_common.h @@ -0,0 +1,836 @@ +/* + * The simplest mpeg encoder (well, it was the simplest!) + * Copyright (c) 2000,2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> + * + * 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_common.h + * The simplest mpeg encoder (well, it was the simplest!). + */ + +#ifndef FFMPEG_MPEGVIDEO_COMMON_H +#define FFMPEG_MPEGVIDEO_COMMON_H + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "mjpegenc.h" +#include "msmpeg4.h" +#include "faandct.h" +#include <limits.h> + +int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); +int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); +void denoise_dct_c(MpegEncContext *s, DCTELEM *block); +void copy_picture(Picture *dst, Picture *src); + +/** + * allocates a Picture + * The pixels are allocated/set by calling get_buffer() if shared=0 + */ +int alloc_picture(MpegEncContext *s, Picture *pic, int shared); + +/** + * sets the given MpegEncContext to common defaults (same for encoding and decoding). + * the changed fields will not depend upon the prior state of the MpegEncContext. + */ +void MPV_common_defaults(MpegEncContext *s); + +static inline void gmc1_motion(MpegEncContext *s, + uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + uint8_t **ref_picture) +{ + uint8_t *ptr; + int offset, src_x, src_y, linesize, uvlinesize; + int motion_x, motion_y; + int emu=0; + + motion_x= s->sprite_offset[0][0]; + motion_y= s->sprite_offset[0][1]; + src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1)); + src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1)); + motion_x<<=(3-s->sprite_warping_accuracy); + motion_y<<=(3-s->sprite_warping_accuracy); + src_x = av_clip(src_x, -16, s->width); + if (src_x == s->width) + motion_x =0; + src_y = av_clip(src_y, -16, s->height); + if (src_y == s->height) + motion_y =0; + + linesize = s->linesize; + uvlinesize = s->uvlinesize; + + ptr = ref_picture[0] + (src_y * linesize) + src_x; + + if(s->flags&CODEC_FLAG_EMU_EDGE){ + if( (unsigned)src_x >= s->h_edge_pos - 17 + || (unsigned)src_y >= s->v_edge_pos - 17){ + ff_emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos); + ptr= s->edge_emu_buffer; + } + } + + if((motion_x|motion_y)&7){ + s->dsp.gmc1(dest_y , ptr , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); + s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding); + }else{ + int dxy; + + dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2); + if (s->no_rounding){ + s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16); + }else{ + s->dsp.put_pixels_tab [0][dxy](dest_y, ptr, linesize, 16); + } + } + + if(ENABLE_GRAY && s->flags&CODEC_FLAG_GRAY) return; + + motion_x= s->sprite_offset[1][0]; + motion_y= s->sprite_offset[1][1]; + src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1)); + src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1)); + motion_x<<=(3-s->sprite_warping_accuracy); + motion_y<<=(3-s->sprite_warping_accuracy); + src_x = av_clip(src_x, -8, s->width>>1); + if (src_x == s->width>>1) + motion_x =0; + src_y = av_clip(src_y, -8, s->height>>1); + if (src_y == s->height>>1) + motion_y =0; + + offset = (src_y * uvlinesize) + src_x; + ptr = ref_picture[1] + offset; + if(s->flags&CODEC_FLAG_EMU_EDGE){ + if( (unsigned)src_x >= (s->h_edge_pos>>1) - 9 + || (unsigned)src_y >= (s->v_edge_pos>>1) - 9){ + ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); + ptr= s->edge_emu_buffer; + emu=1; + } + } + s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); + + ptr = ref_picture[2] + offset; + if(emu){ + ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); + ptr= s->edge_emu_buffer; + } + s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding); + + return; +} + +static inline void gmc_motion(MpegEncContext *s, + uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + uint8_t **ref_picture) +{ + uint8_t *ptr; + int linesize, uvlinesize; + const int a= s->sprite_warping_accuracy; + int ox, oy; + + linesize = s->linesize; + uvlinesize = s->uvlinesize; + + ptr = ref_picture[0]; + + ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16; + oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16; + + s->dsp.gmc(dest_y, ptr, linesize, 16, + ox, + oy, + s->sprite_delta[0][0], s->sprite_delta[0][1], + s->sprite_delta[1][0], s->sprite_delta[1][1], + a+1, (1<<(2*a+1)) - s->no_rounding, + s->h_edge_pos, s->v_edge_pos); + s->dsp.gmc(dest_y+8, ptr, linesize, 16, + ox + s->sprite_delta[0][0]*8, + oy + s->sprite_delta[1][0]*8, + s->sprite_delta[0][0], s->sprite_delta[0][1], + s->sprite_delta[1][0], s->sprite_delta[1][1], + a+1, (1<<(2*a+1)) - s->no_rounding, + s->h_edge_pos, s->v_edge_pos); + + if(ENABLE_GRAY && s->flags&CODEC_FLAG_GRAY) return; + + ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8; + oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8; + + ptr = ref_picture[1]; + s->dsp.gmc(dest_cb, ptr, uvlinesize, 8, + ox, + oy, + s->sprite_delta[0][0], s->sprite_delta[0][1], + s->sprite_delta[1][0], s->sprite_delta[1][1], + a+1, (1<<(2*a+1)) - s->no_rounding, + s->h_edge_pos>>1, s->v_edge_pos>>1); + + ptr = ref_picture[2]; + s->dsp.gmc(dest_cr, ptr, uvlinesize, 8, + ox, + oy, + s->sprite_delta[0][0], s->sprite_delta[0][1], + s->sprite_delta[1][0], s->sprite_delta[1][1], + a+1, (1<<(2*a+1)) - s->no_rounding, + s->h_edge_pos>>1, s->v_edge_pos>>1); +} + +static inline int hpel_motion(MpegEncContext *s, + uint8_t *dest, uint8_t *src, + int field_based, int field_select, + int src_x, int src_y, + int width, int height, int stride, + int h_edge_pos, int v_edge_pos, + int w, int h, op_pixels_func *pix_op, + int motion_x, int motion_y) +{ + int dxy; + int emu=0; + + dxy = ((motion_y & 1) << 1) | (motion_x & 1); + src_x += motion_x >> 1; + src_y += motion_y >> 1; + + /* WARNING: do no forget half pels */ + src_x = av_clip(src_x, -16, width); //FIXME unneeded for emu? + if (src_x == width) + dxy &= ~1; + src_y = av_clip(src_y, -16, height); + if (src_y == height) + dxy &= ~2; + src += src_y * stride + src_x; + + if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){ + if( (unsigned)src_x > h_edge_pos - (motion_x&1) - w + || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){ + ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based, + src_x, src_y<<field_based, h_edge_pos, s->v_edge_pos); + src= s->edge_emu_buffer; + emu=1; + } + } + if(field_select) + src += s->linesize; + pix_op[dxy](dest, src, stride, h); + return emu; +} + +/* apply one mpeg motion vector to the three components */ +static av_always_inline void mpeg_motion(MpegEncContext *s, + uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + int field_based, int bottom_field, int field_select, + uint8_t **ref_picture, op_pixels_func (*pix_op)[4], + int motion_x, int motion_y, int h) +{ + uint8_t *ptr_y, *ptr_cb, *ptr_cr; + int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize; + +#if 0 +if(s->quarter_sample) +{ + motion_x>>=1; + motion_y>>=1; +} +#endif + + v_edge_pos = s->v_edge_pos >> field_based; + linesize = s->current_picture.linesize[0] << field_based; + uvlinesize = s->current_picture.linesize[1] << field_based; + + dxy = ((motion_y & 1) << 1) | (motion_x & 1); + src_x = s->mb_x* 16 + (motion_x >> 1); + src_y =(s->mb_y<<(4-field_based)) + (motion_y >> 1); + + if (s->out_format == FMT_H263) { + if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){ + mx = (motion_x>>1)|(motion_x&1); + my = motion_y >>1; + uvdxy = ((my & 1) << 1) | (mx & 1); + uvsrc_x = s->mb_x* 8 + (mx >> 1); + uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1); + }else{ + uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); + uvsrc_x = src_x>>1; + uvsrc_y = src_y>>1; + } + }else if(s->out_format == FMT_H261){//even chroma mv's are full pel in H261 + mx = motion_x / 4; + my = motion_y / 4; + uvdxy = 0; + uvsrc_x = s->mb_x*8 + mx; + uvsrc_y = s->mb_y*8 + my; + } else { + if(s->chroma_y_shift){ + mx = motion_x / 2; + my = motion_y / 2; + uvdxy = ((my & 1) << 1) | (mx & 1); + uvsrc_x = s->mb_x* 8 + (mx >> 1); + uvsrc_y = (s->mb_y<<(3-field_based)) + (my >> 1); + } else { + if(s->chroma_x_shift){ + //Chroma422 + mx = motion_x / 2; + uvdxy = ((motion_y & 1) << 1) | (mx & 1); + uvsrc_x = s->mb_x* 8 + (mx >> 1); + uvsrc_y = src_y; + } else { + //Chroma444 + uvdxy = dxy; + uvsrc_x = src_x; + uvsrc_y = src_y; + } + } + } + + ptr_y = ref_picture[0] + src_y * linesize + src_x; + ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; + ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; + + if( (unsigned)src_x > s->h_edge_pos - (motion_x&1) - 16 + || (unsigned)src_y > v_edge_pos - (motion_y&1) - h){ + if(s->codec_id == CODEC_ID_MPEG2VIDEO || + s->codec_id == CODEC_ID_MPEG1VIDEO){ + av_log(s->avctx,AV_LOG_DEBUG,"MPEG motion vector out of boundary\n"); + return ; + } + ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based, + src_x, src_y<<field_based, s->h_edge_pos, s->v_edge_pos); + ptr_y = s->edge_emu_buffer; + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ + uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize; + ff_emulated_edge_mc(uvbuf , ptr_cb, s->uvlinesize, 9, 9+field_based, + uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); + ff_emulated_edge_mc(uvbuf+16, ptr_cr, s->uvlinesize, 9, 9+field_based, + uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); + ptr_cb= uvbuf; + ptr_cr= uvbuf+16; + } + } + + if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data + dest_y += s->linesize; + dest_cb+= s->uvlinesize; + dest_cr+= s->uvlinesize; + } + + if(field_select){ + ptr_y += s->linesize; + ptr_cb+= s->uvlinesize; + ptr_cr+= s->uvlinesize; + } + + pix_op[0][dxy](dest_y, ptr_y, linesize, h); + + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ + pix_op[s->chroma_x_shift][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift); + pix_op[s->chroma_x_shift][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift); + } + if((ENABLE_H261_ENCODER || ENABLE_H261_DECODER) && s->out_format == FMT_H261){ + ff_h261_loop_filter(s); + } +} + +//FIXME move to dsputil, avg variant, 16x16 version +static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){ + int x; + uint8_t * const top = src[1]; + uint8_t * const left = src[2]; + uint8_t * const mid = src[0]; + uint8_t * const right = src[3]; + uint8_t * const bottom= src[4]; +#define OBMC_FILTER(x, t, l, m, r, b)\ + dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3 +#define OBMC_FILTER4(x, t, l, m, r, b)\ + OBMC_FILTER(x , t, l, m, r, b);\ + OBMC_FILTER(x+1 , t, l, m, r, b);\ + OBMC_FILTER(x +stride, t, l, m, r, b);\ + OBMC_FILTER(x+1+stride, t, l, m, r, b); + + x=0; + OBMC_FILTER (x , 2, 2, 4, 0, 0); + OBMC_FILTER (x+1, 2, 1, 5, 0, 0); + OBMC_FILTER4(x+2, 2, 1, 5, 0, 0); + OBMC_FILTER4(x+4, 2, 0, 5, 1, 0); + OBMC_FILTER (x+6, 2, 0, 5, 1, 0); + OBMC_FILTER (x+7, 2, 0, 4, 2, 0); + x+= stride; + OBMC_FILTER (x , 1, 2, 5, 0, 0); + OBMC_FILTER (x+1, 1, 2, 5, 0, 0); + OBMC_FILTER (x+6, 1, 0, 5, 2, 0); + OBMC_FILTER (x+7, 1, 0, 5, 2, 0); + x+= stride; + OBMC_FILTER4(x , 1, 2, 5, 0, 0); + OBMC_FILTER4(x+2, 1, 1, 6, 0, 0); + OBMC_FILTER4(x+4, 1, 0, 6, 1, 0); + OBMC_FILTER4(x+6, 1, 0, 5, 2, 0); + x+= 2*stride; + OBMC_FILTER4(x , 0, 2, 5, 0, 1); + OBMC_FILTER4(x+2, 0, 1, 6, 0, 1); + OBMC_FILTER4(x+4, 0, 0, 6, 1, 1); + OBMC_FILTER4(x+6, 0, 0, 5, 2, 1); + x+= 2*stride; + OBMC_FILTER (x , 0, 2, 5, 0, 1); + OBMC_FILTER (x+1, 0, 2, 5, 0, 1); + OBMC_FILTER4(x+2, 0, 1, 5, 0, 2); + OBMC_FILTER4(x+4, 0, 0, 5, 1, 2); + OBMC_FILTER (x+6, 0, 0, 5, 2, 1); + OBMC_FILTER (x+7, 0, 0, 5, 2, 1); + x+= stride; + OBMC_FILTER (x , 0, 2, 4, 0, 2); + OBMC_FILTER (x+1, 0, 1, 5, 0, 2); + OBMC_FILTER (x+6, 0, 0, 5, 1, 2); + OBMC_FILTER (x+7, 0, 0, 4, 2, 2); +} + +/* obmc for 1 8x8 luma block */ +static inline void obmc_motion(MpegEncContext *s, + uint8_t *dest, uint8_t *src, + int src_x, int src_y, + op_pixels_func *pix_op, + int16_t mv[5][2]/* mid top left right bottom*/) +#define MID 0 +{ + int i; + uint8_t *ptr[5]; + + assert(s->quarter_sample==0); + + for(i=0; i<5; i++){ + if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){ + ptr[i]= ptr[MID]; + }else{ + ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1); + hpel_motion(s, ptr[i], src, 0, 0, + src_x, src_y, + s->width, s->height, s->linesize, + s->h_edge_pos, s->v_edge_pos, + 8, 8, pix_op, + mv[i][0], mv[i][1]); + } + } + + put_obmc(dest, ptr, s->linesize); +} + +static inline void qpel_motion(MpegEncContext *s, + uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + int field_based, int bottom_field, int field_select, + uint8_t **ref_picture, op_pixels_func (*pix_op)[4], + qpel_mc_func (*qpix_op)[16], + int motion_x, int motion_y, int h) +{ + uint8_t *ptr_y, *ptr_cb, *ptr_cr; + int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, linesize, uvlinesize; + + dxy = ((motion_y & 3) << 2) | (motion_x & 3); + src_x = s->mb_x * 16 + (motion_x >> 2); + src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2); + + v_edge_pos = s->v_edge_pos >> field_based; + linesize = s->linesize << field_based; + uvlinesize = s->uvlinesize << field_based; + + if(field_based){ + mx= motion_x/2; + my= motion_y>>1; + }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){ + static const int rtab[8]= {0,0,1,1,0,0,0,1}; + mx= (motion_x>>1) + rtab[motion_x&7]; + my= (motion_y>>1) + rtab[motion_y&7]; + }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){ + mx= (motion_x>>1)|(motion_x&1); + my= (motion_y>>1)|(motion_y&1); + }else{ + mx= motion_x/2; + my= motion_y/2; + } + mx= (mx>>1)|(mx&1); + my= (my>>1)|(my&1); + + uvdxy= (mx&1) | ((my&1)<<1); + mx>>=1; + my>>=1; + + uvsrc_x = s->mb_x * 8 + mx; + uvsrc_y = s->mb_y * (8 >> field_based) + my; + + ptr_y = ref_picture[0] + src_y * linesize + src_x; + ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; + ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; + + if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16 + || (unsigned)src_y > v_edge_pos - (motion_y&3) - h ){ + ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based, + src_x, src_y<<field_based, s->h_edge_pos, s->v_edge_pos); + ptr_y= s->edge_emu_buffer; + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ + uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize; + ff_emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize, 9, 9 + field_based, + uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); + ff_emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize, 9, 9 + field_based, + uvsrc_x, uvsrc_y<<field_based, s->h_edge_pos>>1, s->v_edge_pos>>1); + ptr_cb= uvbuf; + ptr_cr= uvbuf + 16; + } + } + + if(!field_based) + qpix_op[0][dxy](dest_y, ptr_y, linesize); + else{ + if(bottom_field){ + dest_y += s->linesize; + dest_cb+= s->uvlinesize; + dest_cr+= s->uvlinesize; + } + + if(field_select){ + ptr_y += s->linesize; + ptr_cb += s->uvlinesize; + ptr_cr += s->uvlinesize; + } + //damn interlaced mode + //FIXME boundary mirroring is not exactly correct here + qpix_op[1][dxy](dest_y , ptr_y , linesize); + qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize); + } + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ + pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1); + pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1); + } +} + +/** + * h263 chroma 4mv motion compensation. + */ +static inline void chroma_4mv_motion(MpegEncContext *s, + uint8_t *dest_cb, uint8_t *dest_cr, + uint8_t **ref_picture, + op_pixels_func *pix_op, + int mx, int my){ + int dxy, emu=0, src_x, src_y, offset; + uint8_t *ptr; + + /* In case of 8X8, we construct a single chroma motion vector + with a special rounding */ + mx= ff_h263_round_chroma(mx); + my= ff_h263_round_chroma(my); + + dxy = ((my & 1) << 1) | (mx & 1); + mx >>= 1; + my >>= 1; + + src_x = s->mb_x * 8 + mx; + src_y = s->mb_y * 8 + my; + src_x = av_clip(src_x, -8, s->width/2); + if (src_x == s->width/2) + dxy &= ~1; + src_y = av_clip(src_y, -8, s->height/2); + if (src_y == s->height/2) + dxy &= ~2; + + offset = (src_y * (s->uvlinesize)) + src_x; + ptr = ref_picture[1] + offset; + if(s->flags&CODEC_FLAG_EMU_EDGE){ + if( (unsigned)src_x > (s->h_edge_pos>>1) - (dxy &1) - 8 + || (unsigned)src_y > (s->v_edge_pos>>1) - (dxy>>1) - 8){ + ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); + ptr= s->edge_emu_buffer; + emu=1; + } + } + pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8); + + ptr = ref_picture[2] + offset; + if(emu){ + ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1); + ptr= s->edge_emu_buffer; + } + pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8); +} + +static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){ + /* fetch pixels for estimated mv 4 macroblocks ahead + * optimized for 64byte cache lines */ + const int shift = s->quarter_sample ? 2 : 1; + const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8; + const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y; + int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64; + s->dsp.prefetch(pix[0]+off, s->linesize, 4); + off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64; + s->dsp.prefetch(pix[1]+off, pix[2]-pix[1], 2); +} + +/** + * motion compensation of a single macroblock + * @param s context + * @param dest_y luma destination pointer + * @param dest_cb chroma cb/u destination pointer + * @param dest_cr chroma cr/v destination pointer + * @param dir direction (0->forward, 1->backward) + * @param ref_picture array[3] of pointers to the 3 planes of the reference picture + * @param pic_op halfpel motion compensation function (average or put normally) + * @param pic_op qpel motion compensation function (average or put normally) + * the motion vectors are taken from s->mv and the MV type from s->mv_type + */ +static inline void MPV_motion(MpegEncContext *s, + uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + int dir, uint8_t **ref_picture, + op_pixels_func (*pix_op)[4], qpel_mc_func (*qpix_op)[16]) +{ + int dxy, mx, my, src_x, src_y, motion_x, motion_y; + int mb_x, mb_y, i; + uint8_t *ptr, *dest; + + mb_x = s->mb_x; + mb_y = s->mb_y; + + prefetch_motion(s, ref_picture, dir); + + if(s->obmc && s->pict_type != B_TYPE){ + int16_t mv_cache[4][4][2]; + const int xy= s->mb_x + s->mb_y*s->mb_stride; + const int mot_stride= s->b8_stride; + const int mot_xy= mb_x*2 + mb_y*2*mot_stride; + + assert(!s->mb_skipped); + + memcpy(mv_cache[1][1], s->current_picture.motion_val[0][mot_xy ], sizeof(int16_t)*4); + memcpy(mv_cache[2][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4); + memcpy(mv_cache[3][1], s->current_picture.motion_val[0][mot_xy+mot_stride], sizeof(int16_t)*4); + + if(mb_y==0 || IS_INTRA(s->current_picture.mb_type[xy-s->mb_stride])){ + memcpy(mv_cache[0][1], mv_cache[1][1], sizeof(int16_t)*4); + }else{ + memcpy(mv_cache[0][1], s->current_picture.motion_val[0][mot_xy-mot_stride], sizeof(int16_t)*4); + } + + if(mb_x==0 || IS_INTRA(s->current_picture.mb_type[xy-1])){ + *(int32_t*)mv_cache[1][0]= *(int32_t*)mv_cache[1][1]; + *(int32_t*)mv_cache[2][0]= *(int32_t*)mv_cache[2][1]; + }else{ + *(int32_t*)mv_cache[1][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1]; + *(int32_t*)mv_cache[2][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1+mot_stride]; + } + + if(mb_x+1>=s->mb_width || IS_INTRA(s->current_picture.mb_type[xy+1])){ + *(int32_t*)mv_cache[1][3]= *(int32_t*)mv_cache[1][2]; + *(int32_t*)mv_cache[2][3]= *(int32_t*)mv_cache[2][2]; + }else{ + *(int32_t*)mv_cache[1][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2]; + *(int32_t*)mv_cache[2][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2+mot_stride]; + } + + mx = 0; + my = 0; + for(i=0;i<4;i++) { + const int x= (i&1)+1; + const int y= (i>>1)+1; + int16_t mv[5][2]= { + {mv_cache[y][x ][0], mv_cache[y][x ][1]}, + {mv_cache[y-1][x][0], mv_cache[y-1][x][1]}, + {mv_cache[y][x-1][0], mv_cache[y][x-1][1]}, + {mv_cache[y][x+1][0], mv_cache[y][x+1][1]}, + {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}}; + //FIXME cleanup + obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, + ref_picture[0], + mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, + pix_op[1], + mv); + + mx += mv[0][0]; + my += mv[0][1]; + } + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)) + chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); + + return; + } + + switch(s->mv_type) { + case MV_TYPE_16X16: + if(s->mcsel){ + if(s->real_sprite_warping_points==1){ + gmc1_motion(s, dest_y, dest_cb, dest_cr, + ref_picture); + }else{ + gmc_motion(s, dest_y, dest_cb, dest_cr, + ref_picture); + } + }else if(s->quarter_sample){ + qpel_motion(s, dest_y, dest_cb, dest_cr, + 0, 0, 0, + ref_picture, pix_op, qpix_op, + s->mv[dir][0][0], s->mv[dir][0][1], 16); + }else if(ENABLE_WMV2 && s->mspel){ + ff_mspel_motion(s, dest_y, dest_cb, dest_cr, + ref_picture, pix_op, + s->mv[dir][0][0], s->mv[dir][0][1], 16); + }else + { + mpeg_motion(s, dest_y, dest_cb, dest_cr, + 0, 0, 0, + ref_picture, pix_op, + s->mv[dir][0][0], s->mv[dir][0][1], 16); + } + break; + case MV_TYPE_8X8: + mx = 0; + my = 0; + if(s->quarter_sample){ + for(i=0;i<4;i++) { + motion_x = s->mv[dir][i][0]; + motion_y = s->mv[dir][i][1]; + + dxy = ((motion_y & 3) << 2) | (motion_x & 3); + src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8; + src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8; + + /* WARNING: do no forget half pels */ + src_x = av_clip(src_x, -16, s->width); + if (src_x == s->width) + dxy &= ~3; + src_y = av_clip(src_y, -16, s->height); + if (src_y == s->height) + dxy &= ~12; + + ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); + if(s->flags&CODEC_FLAG_EMU_EDGE){ + if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 8 + || (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 8 ){ + ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos); + ptr= s->edge_emu_buffer; + } + } + dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; + qpix_op[1][dxy](dest, ptr, s->linesize); + + mx += s->mv[dir][i][0]/2; + my += s->mv[dir][i][1]/2; + } + }else{ + for(i=0;i<4;i++) { + hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, + ref_picture[0], 0, 0, + mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8, + s->width, s->height, s->linesize, + s->h_edge_pos, s->v_edge_pos, + 8, 8, pix_op[1], + s->mv[dir][i][0], s->mv[dir][i][1]); + + mx += s->mv[dir][i][0]; + my += s->mv[dir][i][1]; + } + } + + if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)) + chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); + break; + case MV_TYPE_FIELD: + if (s->picture_structure == PICT_FRAME) { + if(s->quarter_sample){ + for(i=0; i<2; i++){ + qpel_motion(s, dest_y, dest_cb, dest_cr, + 1, i, s->field_select[dir][i], + ref_picture, pix_op, qpix_op, + s->mv[dir][i][0], s->mv[dir][i][1], 8); + } + }else{ + /* top field */ + mpeg_motion(s, dest_y, dest_cb, dest_cr, + 1, 0, s->field_select[dir][0], + ref_picture, pix_op, + s->mv[dir][0][0], s->mv[dir][0][1], 8); + /* bottom field */ + mpeg_motion(s, dest_y, dest_cb, dest_cr, + 1, 1, s->field_select[dir][1], + ref_picture, pix_op, + s->mv[dir][1][0], s->mv[dir][1][1], 8); + } + } else { + if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != B_TYPE && !s->first_field){ + ref_picture= s->current_picture_ptr->data; + } + + mpeg_motion(s, dest_y, dest_cb, dest_cr, + 0, 0, s->field_select[dir][0], + ref_picture, pix_op, + s->mv[dir][0][0], s->mv[dir][0][1], 16); + } + break; + case MV_TYPE_16X8: + for(i=0; i<2; i++){ + uint8_t ** ref2picture; + + if(s->picture_structure == s->field_select[dir][i] + 1 || s->pict_type == B_TYPE || s->first_field){ + ref2picture= ref_picture; + }else{ + ref2picture= s->current_picture_ptr->data; + } + + mpeg_motion(s, dest_y, dest_cb, dest_cr, + 0, 0, s->field_select[dir][i], + ref2picture, pix_op, + s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8); + + dest_y += 16*s->linesize; + dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize; + dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize; + } + break; + case MV_TYPE_DMV: + if(s->picture_structure == PICT_FRAME){ + for(i=0; i<2; i++){ + int j; + for(j=0; j<2; j++){ + mpeg_motion(s, dest_y, dest_cb, dest_cr, + 1, j, j^i, + ref_picture, pix_op, + s->mv[dir][2*i + j][0], s->mv[dir][2*i + j][1], 8); + } + pix_op = s->dsp.avg_pixels_tab; + } + }else{ + for(i=0; i<2; i++){ + mpeg_motion(s, dest_y, dest_cb, dest_cr, + 0, 0, s->picture_structure != i+1, + ref_picture, pix_op, + s->mv[dir][2*i][0],s->mv[dir][2*i][1],16); + + // after put we make avg of the same block + pix_op=s->dsp.avg_pixels_tab; + + //opposite parity is always in the same frame if this is second field + if(!s->first_field){ + ref_picture = s->current_picture_ptr->data; + } + } + } + break; + default: assert(0); + } +} + +#endif /* FFMPEG_MPEGVIDEO_COMMON_H */ diff --git a/contrib/ffmpeg/libavcodec/mpegvideo_enc.c b/contrib/ffmpeg/libavcodec/mpegvideo_enc.c new file mode 100644 index 000000000..bebdf71f3 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpegvideo_enc.c @@ -0,0 +1,3847 @@ +/* + * The simplest mpeg encoder (well, it was the simplest!) + * Copyright (c) 2000,2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> + * + * 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_enc.c + * The simplest mpeg encoder (well, it was the simplest!). + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "mpegvideo_common.h" +#include "mjpegenc.h" +#include "msmpeg4.h" +#include "h263.h" +#include "faandct.h" +#include <limits.h> + +//#undef NDEBUG +//#include <assert.h> + +static int encode_picture(MpegEncContext *s, int picture_number); +static int dct_quantize_refine(MpegEncContext *s, DCTELEM *block, int16_t *weight, DCTELEM *orig, int n, int qscale); +static int sse_mb(MpegEncContext *s); + +/* enable all paranoid tests for rounding, overflows, etc... */ +//#define PARANOID + +//#define DEBUG + +static const uint16_t aanscales[64] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867 , 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520 , 6270, 5906, 5315, 4520, 3552, 2446, 1247 +}; + +static const uint16_t inv_aanscales[64] = { + 4096, 2953, 3135, 3483, 4096, 5213, 7568, 14846, + 2953, 2129, 2260, 2511, 2953, 3759, 5457, 10703, + 3135, 2260, 2399, 2666, 3135, 3990, 5793, 11363, + 3483, 2511, 2666, 2962, 3483, 4433, 6436, 12625, + 4096, 2953, 3135, 3483, 4096, 5213, 7568, 14846, + 5213, 3759, 3990, 4433, 5213, 6635, 9633, 18895, + 7568, 5457, 5793, 6436, 7568, 9633, 13985, 27432, + 14846, 10703, 11363, 12625, 14846, 18895, 27432, 53809, +}; + +static uint8_t default_mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; +static uint8_t default_fcode_tab[MAX_MV*2+1]; + +void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64], + const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra) +{ + int qscale; + int shift=0; + + for(qscale=qmin; qscale<=qmax; qscale++){ + int i; + if (dsp->fdct == ff_jpeg_fdct_islow +#ifdef FAAN_POSTSCALE + || dsp->fdct == ff_faandct +#endif + ) { + for(i=0;i<64;i++) { + const int j= dsp->idct_permutation[i]; + /* 16 <= qscale * quant_matrix[i] <= 7905 */ + /* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */ + /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */ + /* 3444240 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */ + + qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / + (qscale * quant_matrix[j])); + } + } else if (dsp->fdct == fdct_ifast +#ifndef FAAN_POSTSCALE + || dsp->fdct == ff_faandct +#endif + ) { + for(i=0;i<64;i++) { + const int j= dsp->idct_permutation[i]; + /* 16 <= qscale * quant_matrix[i] <= 7905 */ + /* 19952 <= aanscales[i] * qscale * quant_matrix[i] <= 249205026 */ + /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */ + /* 3444240 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */ + + qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) / + (aanscales[i] * qscale * quant_matrix[j])); + } + } else { + for(i=0;i<64;i++) { + const int j= dsp->idct_permutation[i]; + /* We can safely suppose that 16 <= quant_matrix[i] <= 255 + So 16 <= qscale * quant_matrix[i] <= 7905 + so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905 + so 32768 >= (1<<19) / (qscale * quant_matrix[i]) >= 67 + */ + qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / (qscale * quant_matrix[j])); +// qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]); + qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]); + + if(qmat16[qscale][0][i]==0 || qmat16[qscale][0][i]==128*256) qmat16[qscale][0][i]=128*256-1; + qmat16[qscale][1][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][0][i]); + } + } + + for(i=intra; i<64; i++){ + int64_t max= 8191; + if (dsp->fdct == fdct_ifast +#ifndef FAAN_POSTSCALE + || dsp->fdct == ff_faandct +#endif + ) { + max= (8191LL*aanscales[i]) >> 14; + } + while(((max * qmat[qscale][i]) >> shift) > INT_MAX){ + shift++; + } + } + } + if(shift){ + av_log(NULL, AV_LOG_INFO, "Warning, QMAT_SHIFT is larger than %d, overflows possible\n", QMAT_SHIFT - shift); + } +} + +static inline void update_qscale(MpegEncContext *s){ + s->qscale= (s->lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); + s->qscale= av_clip(s->qscale, s->avctx->qmin, s->avctx->qmax); + + s->lambda2= (s->lambda*s->lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT; +} + +void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix){ + int i; + + if(matrix){ + put_bits(pb, 1, 1); + for(i=0;i<64;i++) { + put_bits(pb, 8, matrix[ ff_zigzag_direct[i] ]); + } + }else + put_bits(pb, 1, 0); +} + +static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst, AVFrame *src){ + int i; + + dst->pict_type = src->pict_type; + dst->quality = src->quality; + dst->coded_picture_number = src->coded_picture_number; + dst->display_picture_number = src->display_picture_number; +// dst->reference = src->reference; + dst->pts = src->pts; + dst->interlaced_frame = src->interlaced_frame; + dst->top_field_first = src->top_field_first; + + if(s->avctx->me_threshold){ + if(!src->motion_val[0]) + av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_val not set!\n"); + if(!src->mb_type) + av_log(s->avctx, AV_LOG_ERROR, "AVFrame.mb_type not set!\n"); + if(!src->ref_index[0]) + av_log(s->avctx, AV_LOG_ERROR, "AVFrame.ref_index not set!\n"); + if(src->motion_subsample_log2 != dst->motion_subsample_log2) + av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_subsample_log2 doesn't match! (%d!=%d)\n", + src->motion_subsample_log2, dst->motion_subsample_log2); + + memcpy(dst->mb_type, src->mb_type, s->mb_stride * s->mb_height * sizeof(dst->mb_type[0])); + + for(i=0; i<2; i++){ + int stride= ((16*s->mb_width )>>src->motion_subsample_log2) + 1; + int height= ((16*s->mb_height)>>src->motion_subsample_log2); + + if(src->motion_val[i] && src->motion_val[i] != dst->motion_val[i]){ + memcpy(dst->motion_val[i], src->motion_val[i], 2*stride*height*sizeof(int16_t)); + } + if(src->ref_index[i] && src->ref_index[i] != dst->ref_index[i]){ + memcpy(dst->ref_index[i], src->ref_index[i], s->b8_stride*2*s->mb_height*sizeof(int8_t)); + } + } + } +} + +static void update_duplicate_context_after_me(MpegEncContext *dst, MpegEncContext *src){ +#define COPY(a) dst->a= src->a + COPY(pict_type); + COPY(current_picture); + COPY(f_code); + COPY(b_code); + COPY(qscale); + COPY(lambda); + COPY(lambda2); + COPY(picture_in_gop_number); + COPY(gop_picture_number); + COPY(frame_pred_frame_dct); //FIXME don't set in encode_header + COPY(progressive_frame); //FIXME don't set in encode_header + COPY(partitioned_frame); //FIXME don't set in encode_header +#undef COPY +} + +/** + * sets the given MpegEncContext to defaults for encoding. + * the changed fields will not depend upon the prior state of the MpegEncContext. + */ +static void MPV_encode_defaults(MpegEncContext *s){ + int i; + MPV_common_defaults(s); + + for(i=-16; i<16; i++){ + default_fcode_tab[i + MAX_MV]= 1; + } + s->me.mv_penalty= default_mv_penalty; + s->fcode_tab= default_fcode_tab; +} + +/* init video encoder */ +int MPV_encode_init(AVCodecContext *avctx) +{ + MpegEncContext *s = avctx->priv_data; + int i; + int chroma_h_shift, chroma_v_shift; + + MPV_encode_defaults(s); + + switch (avctx->codec_id) { + case CODEC_ID_MPEG2VIDEO: + if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){ + av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n"); + return -1; + } + break; + case CODEC_ID_LJPEG: + case CODEC_ID_MJPEG: + if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P && + ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P) || avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL)){ + av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n"); + return -1; + } + break; + default: + if(avctx->pix_fmt != PIX_FMT_YUV420P){ + av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n"); + return -1; + } + } + + switch (avctx->pix_fmt) { + case PIX_FMT_YUVJ422P: + case PIX_FMT_YUV422P: + s->chroma_format = CHROMA_422; + break; + case PIX_FMT_YUVJ420P: + case PIX_FMT_YUV420P: + default: + s->chroma_format = CHROMA_420; + break; + } + + s->bit_rate = avctx->bit_rate; + s->width = avctx->width; + s->height = avctx->height; + if(avctx->gop_size > 600 && avctx->strict_std_compliance>FF_COMPLIANCE_EXPERIMENTAL){ + av_log(avctx, AV_LOG_ERROR, "Warning keyframe interval too large! reducing it ...\n"); + avctx->gop_size=600; + } + s->gop_size = avctx->gop_size; + s->avctx = avctx; + s->flags= avctx->flags; + s->flags2= avctx->flags2; + s->max_b_frames= avctx->max_b_frames; + s->codec_id= avctx->codec->id; + s->luma_elim_threshold = avctx->luma_elim_threshold; + s->chroma_elim_threshold= avctx->chroma_elim_threshold; + s->strict_std_compliance= avctx->strict_std_compliance; + s->data_partitioning= avctx->flags & CODEC_FLAG_PART; + s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0; + s->mpeg_quant= avctx->mpeg_quant; + s->rtp_mode= !!avctx->rtp_payload_size; + s->intra_dc_precision= avctx->intra_dc_precision; + s->user_specified_pts = AV_NOPTS_VALUE; + + if (s->gop_size <= 1) { + s->intra_only = 1; + s->gop_size = 12; + } else { + s->intra_only = 0; + } + + s->me_method = avctx->me_method; + + /* Fixed QSCALE */ + s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE); + + s->adaptive_quant= ( s->avctx->lumi_masking + || s->avctx->dark_masking + || s->avctx->temporal_cplx_masking + || s->avctx->spatial_cplx_masking + || s->avctx->p_masking + || s->avctx->border_masking + || (s->flags&CODEC_FLAG_QP_RD)) + && !s->fixed_qscale; + + s->obmc= !!(s->flags & CODEC_FLAG_OBMC); + s->loop_filter= !!(s->flags & CODEC_FLAG_LOOP_FILTER); + s->alternate_scan= !!(s->flags & CODEC_FLAG_ALT_SCAN); + s->intra_vlc_format= !!(s->flags2 & CODEC_FLAG2_INTRA_VLC); + s->q_scale_type= !!(s->flags2 & CODEC_FLAG2_NON_LINEAR_QUANT); + + if(avctx->rc_max_rate && !avctx->rc_buffer_size){ + av_log(avctx, AV_LOG_ERROR, "a vbv buffer size is needed, for encoding with a maximum bitrate\n"); + return -1; + } + + if(avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate){ + av_log(avctx, AV_LOG_INFO, "Warning min_rate > 0 but min_rate != max_rate isn't recommended!\n"); + } + + if(avctx->rc_min_rate && avctx->rc_min_rate > avctx->bit_rate){ + av_log(avctx, AV_LOG_ERROR, "bitrate below min bitrate\n"); + return -1; + } + + if(avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate){ + av_log(avctx, AV_LOG_INFO, "bitrate above max bitrate\n"); + return -1; + } + + if(avctx->rc_max_rate && avctx->rc_max_rate == avctx->bit_rate && avctx->rc_max_rate != avctx->rc_min_rate){ + av_log(avctx, AV_LOG_INFO, "impossible bitrate constraints, this will fail\n"); + } + + if(avctx->rc_buffer_size && avctx->bit_rate*av_q2d(avctx->time_base) > avctx->rc_buffer_size){ + av_log(avctx, AV_LOG_ERROR, "VBV buffer too small for bitrate\n"); + return -1; + } + + if(avctx->bit_rate*av_q2d(avctx->time_base) > avctx->bit_rate_tolerance){ + av_log(avctx, AV_LOG_ERROR, "bitrate tolerance too small for bitrate\n"); + return -1; + } + + if( s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate + && (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO) + && 90000LL * (avctx->rc_buffer_size-1) > s->avctx->rc_max_rate*0xFFFFLL){ + + av_log(avctx, AV_LOG_INFO, "Warning vbv_delay will be set to 0xFFFF (=VBR) as the specified vbv buffer is too large for the given bitrate!\n"); + } + + if((s->flags & CODEC_FLAG_4MV) && s->codec_id != CODEC_ID_MPEG4 + && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P && s->codec_id != CODEC_ID_FLV1){ + av_log(avctx, AV_LOG_ERROR, "4MV not supported by codec\n"); + return -1; + } + + if(s->obmc && s->avctx->mb_decision != FF_MB_DECISION_SIMPLE){ + av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with simple mb decision\n"); + return -1; + } + + if(s->obmc && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P){ + av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with H263(+)\n"); + return -1; + } + + if(s->quarter_sample && s->codec_id != CODEC_ID_MPEG4){ + av_log(avctx, AV_LOG_ERROR, "qpel not supported by codec\n"); + return -1; + } + + if(s->data_partitioning && s->codec_id != CODEC_ID_MPEG4){ + av_log(avctx, AV_LOG_ERROR, "data partitioning not supported by codec\n"); + return -1; + } + + if(s->max_b_frames && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO){ + av_log(avctx, AV_LOG_ERROR, "b frames not supported by codec\n"); + return -1; + } + + if((s->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN)) + && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG2VIDEO){ + av_log(avctx, AV_LOG_ERROR, "interlacing not supported by codec\n"); + return -1; + } + + if(s->mpeg_quant && s->codec_id != CODEC_ID_MPEG4){ //FIXME mpeg2 uses that too + av_log(avctx, AV_LOG_ERROR, "mpeg2 style quantization not supported by codec\n"); + return -1; + } + + if((s->flags & CODEC_FLAG_CBP_RD) && !(s->flags & CODEC_FLAG_TRELLIS_QUANT)){ + av_log(avctx, AV_LOG_ERROR, "CBP RD needs trellis quant\n"); + return -1; + } + + if((s->flags & CODEC_FLAG_QP_RD) && s->avctx->mb_decision != FF_MB_DECISION_RD){ + av_log(avctx, AV_LOG_ERROR, "QP RD needs mbd=2\n"); + return -1; + } + + if(s->avctx->scenechange_threshold < 1000000000 && (s->flags & CODEC_FLAG_CLOSED_GOP)){ + av_log(avctx, AV_LOG_ERROR, "closed gop with scene change detection arent supported yet, set threshold to 1000000000\n"); + return -1; + } + + if((s->flags2 & CODEC_FLAG2_INTRA_VLC) && s->codec_id != CODEC_ID_MPEG2VIDEO){ + av_log(avctx, AV_LOG_ERROR, "intra vlc table not supported by codec\n"); + return -1; + } + + if(s->flags & CODEC_FLAG_LOW_DELAY){ + if (s->codec_id != CODEC_ID_MPEG2VIDEO && s->codec_id != CODEC_ID_MPEG1VIDEO){ + av_log(avctx, AV_LOG_ERROR, "low delay forcing is only available for mpeg1/2\n"); + return -1; + } + if (s->max_b_frames != 0){ + av_log(avctx, AV_LOG_ERROR, "b frames cannot be used with low delay\n"); + return -1; + } + } + + if(s->q_scale_type == 1){ + if(s->codec_id != CODEC_ID_MPEG2VIDEO){ + av_log(avctx, AV_LOG_ERROR, "non linear quant is only available for mpeg2\n"); + return -1; + } + if(avctx->qmax > 12){ + av_log(avctx, AV_LOG_ERROR, "non linear quant only supports qmax <= 12 currently\n"); + return -1; + } + } + + if(s->avctx->thread_count > 1 && s->codec_id != CODEC_ID_MPEG4 + && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO + && (s->codec_id != CODEC_ID_H263P || !(s->flags & CODEC_FLAG_H263P_SLICE_STRUCT))){ + av_log(avctx, AV_LOG_ERROR, "multi threaded encoding not supported by codec\n"); + return -1; + } + + if(s->avctx->thread_count > 1) + s->rtp_mode= 1; + + if(!avctx->time_base.den || !avctx->time_base.num){ + av_log(avctx, AV_LOG_ERROR, "framerate not set\n"); + return -1; + } + + i= (INT_MAX/2+128)>>8; + if(avctx->me_threshold >= i){ + av_log(avctx, AV_LOG_ERROR, "me_threshold too large, max is %d\n", i - 1); + return -1; + } + if(avctx->mb_threshold >= i){ + av_log(avctx, AV_LOG_ERROR, "mb_threshold too large, max is %d\n", i - 1); + return -1; + } + + if(avctx->b_frame_strategy && (avctx->flags&CODEC_FLAG_PASS2)){ + av_log(avctx, AV_LOG_INFO, "notice: b_frame_strategy only affects the first pass\n"); + avctx->b_frame_strategy = 0; + } + + i= ff_gcd(avctx->time_base.den, avctx->time_base.num); + if(i > 1){ + av_log(avctx, AV_LOG_INFO, "removing common factors from framerate\n"); + avctx->time_base.den /= i; + avctx->time_base.num /= i; +// return -1; + } + + if(s->codec_id==CODEC_ID_MJPEG){ + s->intra_quant_bias= 1<<(QUANT_BIAS_SHIFT-1); //(a + x/2)/x + s->inter_quant_bias= 0; + }else if(s->mpeg_quant || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO){ + s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x + s->inter_quant_bias= 0; + }else{ + s->intra_quant_bias=0; + s->inter_quant_bias=-(1<<(QUANT_BIAS_SHIFT-2)); //(a - x/4)/x + } + + if(avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS) + s->intra_quant_bias= avctx->intra_quant_bias; + if(avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS) + s->inter_quant_bias= avctx->inter_quant_bias; + + avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift); + + if(avctx->codec_id == CODEC_ID_MPEG4 && s->avctx->time_base.den > (1<<16)-1){ + av_log(avctx, AV_LOG_ERROR, "timebase not supported by mpeg 4 standard\n"); + return -1; + } + s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; + + switch(avctx->codec->id) { + case CODEC_ID_MPEG1VIDEO: + s->out_format = FMT_MPEG1; + s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY); + avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); + break; + case CODEC_ID_MPEG2VIDEO: + s->out_format = FMT_MPEG1; + s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY); + avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); + s->rtp_mode= 1; + break; + case CODEC_ID_LJPEG: + case CODEC_ID_MJPEG: + s->out_format = FMT_MJPEG; + s->intra_only = 1; /* force intra only for jpeg */ + s->mjpeg_vsample[0] = 2; + s->mjpeg_vsample[1] = 2>>chroma_v_shift; + s->mjpeg_vsample[2] = 2>>chroma_v_shift; + s->mjpeg_hsample[0] = 2; + s->mjpeg_hsample[1] = 2>>chroma_h_shift; + s->mjpeg_hsample[2] = 2>>chroma_h_shift; + if (!(ENABLE_MJPEG_ENCODER || ENABLE_LJPEG_ENCODER) + || ff_mjpeg_encode_init(s) < 0) + return -1; + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_H261: + if (!ENABLE_H261_ENCODER) return -1; + if (ff_h261_get_picture_format(s->width, s->height) < 0) { + av_log(avctx, AV_LOG_ERROR, "The specified picture size of %dx%d is not valid for the H.261 codec.\nValid sizes are 176x144, 352x288\n", s->width, s->height); + return -1; + } + s->out_format = FMT_H261; + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_H263: + if (!ENABLE_H263_ENCODER) return -1; + if (h263_get_picture_format(s->width, s->height) == 7) { + av_log(avctx, AV_LOG_INFO, "The specified picture size of %dx%d is not valid for the H.263 codec.\nValid sizes are 128x96, 176x144, 352x288, 704x576, and 1408x1152. Try H.263+.\n", s->width, s->height); + return -1; + } + s->out_format = FMT_H263; + s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0; + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_H263P: + s->out_format = FMT_H263; + s->h263_plus = 1; + /* Fx */ + s->umvplus = (avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0; + s->h263_aic= (avctx->flags & CODEC_FLAG_AC_PRED) ? 1:0; + s->modified_quant= s->h263_aic; + s->alt_inter_vlc= (avctx->flags & CODEC_FLAG_H263P_AIV) ? 1:0; + s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0; + s->loop_filter= (avctx->flags & CODEC_FLAG_LOOP_FILTER) ? 1:0; + s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus; + s->h263_slice_structured= (s->flags & CODEC_FLAG_H263P_SLICE_STRUCT) ? 1:0; + + /* /Fx */ + /* These are just to be sure */ + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_FLV1: + s->out_format = FMT_H263; + s->h263_flv = 2; /* format = 1; 11-bit codes */ + s->unrestricted_mv = 1; + s->rtp_mode=0; /* don't allow GOB */ + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_RV10: + s->out_format = FMT_H263; + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_RV20: + s->out_format = FMT_H263; + avctx->delay=0; + s->low_delay=1; + s->modified_quant=1; + s->h263_aic=1; + s->h263_plus=1; + s->loop_filter=1; + s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus; + break; + case CODEC_ID_MPEG4: + s->out_format = FMT_H263; + s->h263_pred = 1; + s->unrestricted_mv = 1; + s->low_delay= s->max_b_frames ? 0 : 1; + avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); + break; + case CODEC_ID_MSMPEG4V1: + s->out_format = FMT_H263; + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->unrestricted_mv = 1; + s->msmpeg4_version= 1; + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_MSMPEG4V2: + s->out_format = FMT_H263; + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->unrestricted_mv = 1; + s->msmpeg4_version= 2; + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_MSMPEG4V3: + s->out_format = FMT_H263; + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->unrestricted_mv = 1; + s->msmpeg4_version= 3; + s->flipflop_rounding=1; + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_WMV1: + s->out_format = FMT_H263; + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->unrestricted_mv = 1; + s->msmpeg4_version= 4; + s->flipflop_rounding=1; + avctx->delay=0; + s->low_delay=1; + break; + case CODEC_ID_WMV2: + s->out_format = FMT_H263; + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->unrestricted_mv = 1; + s->msmpeg4_version= 5; + s->flipflop_rounding=1; + avctx->delay=0; + s->low_delay=1; + break; + default: + return -1; + } + + avctx->has_b_frames= !s->low_delay; + + s->encoding = 1; + + /* init */ + if (MPV_common_init(s) < 0) + return -1; + + if(!s->dct_quantize) + s->dct_quantize = dct_quantize_c; + if(!s->denoise_dct) + s->denoise_dct = denoise_dct_c; + s->fast_dct_quantize = s->dct_quantize; + if(s->flags & CODEC_FLAG_TRELLIS_QUANT) + s->dct_quantize = dct_quantize_trellis_c; + + if((ENABLE_H263P_ENCODER || ENABLE_RV20_ENCODER) && s->modified_quant) + s->chroma_qscale_table= ff_h263_chroma_qscale_table; + s->progressive_frame= + s->progressive_sequence= !(avctx->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN)); + s->quant_precision=5; + + ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp); + ff_set_cmp(&s->dsp, s->dsp.frame_skip_cmp, s->avctx->frame_skip_cmp); + + if (ENABLE_H261_ENCODER && s->out_format == FMT_H261) + ff_h261_encode_init(s); + if (ENABLE_ANY_H263_ENCODER && s->out_format == FMT_H263) + h263_encode_init(s); + if (ENABLE_MSMPEG4_ENCODER && s->msmpeg4_version) + ff_msmpeg4_encode_init(s); + if ((ENABLE_MPEG1VIDEO_ENCODER || ENABLE_MPEG2VIDEO_ENCODER) + && s->out_format == FMT_MPEG1) + ff_mpeg1_encode_init(s); + + /* init q matrix */ + for(i=0;i<64;i++) { + int j= s->dsp.idct_permutation[i]; + if(ENABLE_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->mpeg_quant){ + s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i]; + s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i]; + }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ + s->intra_matrix[j] = + s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; + }else + { /* mpeg1/2 */ + s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i]; + s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; + } + if(s->avctx->intra_matrix) + s->intra_matrix[j] = s->avctx->intra_matrix[i]; + if(s->avctx->inter_matrix) + s->inter_matrix[j] = s->avctx->inter_matrix[i]; + } + + /* precompute matrix */ + /* for mjpeg, we do include qscale in the matrix */ + if (s->out_format != FMT_MJPEG) { + ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16, + s->intra_matrix, s->intra_quant_bias, avctx->qmin, 31, 1); + ff_convert_matrix(&s->dsp, s->q_inter_matrix, s->q_inter_matrix16, + s->inter_matrix, s->inter_quant_bias, avctx->qmin, 31, 0); + } + + if(ff_rate_control_init(s) < 0) + return -1; + + return 0; +} + +int MPV_encode_end(AVCodecContext *avctx) +{ + MpegEncContext *s = avctx->priv_data; + + ff_rate_control_uninit(s); + + MPV_common_end(s); + if ((ENABLE_MJPEG_ENCODER || ENABLE_LJPEG_ENCODER) && s->out_format == FMT_MJPEG) + ff_mjpeg_encode_close(s); + + av_freep(&avctx->extradata); + + return 0; +} + +static int get_sae(uint8_t *src, int ref, int stride){ + int x,y; + int acc=0; + + for(y=0; y<16; y++){ + for(x=0; x<16; x++){ + acc+= FFABS(src[x+y*stride] - ref); + } + } + + return acc; +} + +static int get_intra_count(MpegEncContext *s, uint8_t *src, uint8_t *ref, int stride){ + int x, y, w, h; + int acc=0; + + w= s->width &~15; + h= s->height&~15; + + for(y=0; y<h; y+=16){ + for(x=0; x<w; x+=16){ + int offset= x + y*stride; + int sad = s->dsp.sad[0](NULL, src + offset, ref + offset, stride, 16); + int mean= (s->dsp.pix_sum(src + offset, stride) + 128)>>8; + int sae = get_sae(src + offset, mean, stride); + + acc+= sae + 500 < sad; + } + } + return acc; +} + + +static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){ + AVFrame *pic=NULL; + int64_t pts; + int i; + const int encoding_delay= s->max_b_frames; + int direct=1; + + if(pic_arg){ + pts= pic_arg->pts; + pic_arg->display_picture_number= s->input_picture_number++; + + if(pts != AV_NOPTS_VALUE){ + if(s->user_specified_pts != AV_NOPTS_VALUE){ + int64_t time= pts; + int64_t last= s->user_specified_pts; + + if(time <= last){ + av_log(s->avctx, AV_LOG_ERROR, "Error, Invalid timestamp=%"PRId64", last=%"PRId64"\n", pts, s->user_specified_pts); + return -1; + } + } + s->user_specified_pts= pts; + }else{ + if(s->user_specified_pts != AV_NOPTS_VALUE){ + s->user_specified_pts= + pts= s->user_specified_pts + 1; + av_log(s->avctx, AV_LOG_INFO, "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n", pts); + }else{ + pts= pic_arg->display_picture_number; + } + } + } + + if(pic_arg){ + if(encoding_delay && !(s->flags&CODEC_FLAG_INPUT_PRESERVED)) direct=0; + if(pic_arg->linesize[0] != s->linesize) direct=0; + if(pic_arg->linesize[1] != s->uvlinesize) direct=0; + if(pic_arg->linesize[2] != s->uvlinesize) direct=0; + +// av_log(AV_LOG_DEBUG, "%d %d %d %d\n",pic_arg->linesize[0], pic_arg->linesize[1], s->linesize, s->uvlinesize); + + if(direct){ + i= ff_find_unused_picture(s, 1); + + pic= (AVFrame*)&s->picture[i]; + pic->reference= 3; + + for(i=0; i<4; i++){ + pic->data[i]= pic_arg->data[i]; + pic->linesize[i]= pic_arg->linesize[i]; + } + alloc_picture(s, (Picture*)pic, 1); + }else{ + i= ff_find_unused_picture(s, 0); + + pic= (AVFrame*)&s->picture[i]; + pic->reference= 3; + + alloc_picture(s, (Picture*)pic, 0); + + if( pic->data[0] + INPLACE_OFFSET == pic_arg->data[0] + && pic->data[1] + INPLACE_OFFSET == pic_arg->data[1] + && pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]){ + // empty + }else{ + int h_chroma_shift, v_chroma_shift; + avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); + + for(i=0; i<3; i++){ + int src_stride= pic_arg->linesize[i]; + int dst_stride= i ? s->uvlinesize : s->linesize; + int h_shift= i ? h_chroma_shift : 0; + int v_shift= i ? v_chroma_shift : 0; + int w= s->width >>h_shift; + int h= s->height>>v_shift; + uint8_t *src= pic_arg->data[i]; + uint8_t *dst= pic->data[i]; + + if(!s->avctx->rc_buffer_size) + dst +=INPLACE_OFFSET; + + if(src_stride==dst_stride) + memcpy(dst, src, src_stride*h); + else{ + while(h--){ + memcpy(dst, src, w); + dst += dst_stride; + src += src_stride; + } + } + } + } + } + copy_picture_attributes(s, pic, pic_arg); + pic->pts= pts; //we set this here to avoid modifiying pic_arg + } + + /* shift buffer entries */ + for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++) + s->input_picture[i-1]= s->input_picture[i]; + + s->input_picture[encoding_delay]= (Picture*)pic; + + return 0; +} + +static int skip_check(MpegEncContext *s, Picture *p, Picture *ref){ + int x, y, plane; + int score=0; + int64_t score64=0; + + for(plane=0; plane<3; plane++){ + const int stride= p->linesize[plane]; + const int bw= plane ? 1 : 2; + for(y=0; y<s->mb_height*bw; y++){ + for(x=0; x<s->mb_width*bw; x++){ + int off= p->type == FF_BUFFER_TYPE_SHARED ? 0: 16; + int v= s->dsp.frame_skip_cmp[1](s, p->data[plane] + 8*(x + y*stride)+off, ref->data[plane] + 8*(x + y*stride), stride, 8); + + switch(s->avctx->frame_skip_exp){ + case 0: score= FFMAX(score, v); break; + case 1: score+= FFABS(v);break; + case 2: score+= v*v;break; + case 3: score64+= FFABS(v*v*(int64_t)v);break; + case 4: score64+= v*v*(int64_t)(v*v);break; + } + } + } + } + + if(score) score64= score; + + if(score64 < s->avctx->frame_skip_threshold) + return 1; + if(score64 < ((s->avctx->frame_skip_factor * (int64_t)s->lambda)>>8)) + return 1; + return 0; +} + +static int estimate_best_b_count(MpegEncContext *s){ + AVCodec *codec= avcodec_find_encoder(s->avctx->codec_id); + AVCodecContext *c= avcodec_alloc_context(); + AVFrame input[FF_MAX_B_FRAMES+2]; + const int scale= s->avctx->brd_scale; + int i, j, out_size, p_lambda, b_lambda, lambda2; + int outbuf_size= s->width * s->height; //FIXME + uint8_t *outbuf= av_malloc(outbuf_size); + int64_t best_rd= INT64_MAX; + int best_b_count= -1; + + assert(scale>=0 && scale <=3); + +// emms_c(); + p_lambda= s->last_lambda_for[P_TYPE]; //s->next_picture_ptr->quality; + b_lambda= s->last_lambda_for[B_TYPE]; //p_lambda *FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset; + if(!b_lambda) b_lambda= p_lambda; //FIXME we should do this somewhere else + lambda2= (b_lambda*b_lambda + (1<<FF_LAMBDA_SHIFT)/2 ) >> FF_LAMBDA_SHIFT; + + c->width = s->width >> scale; + c->height= s->height>> scale; + c->flags= CODEC_FLAG_QSCALE | CODEC_FLAG_PSNR | CODEC_FLAG_INPUT_PRESERVED /*| CODEC_FLAG_EMU_EDGE*/; + c->flags|= s->avctx->flags & CODEC_FLAG_QPEL; + c->mb_decision= s->avctx->mb_decision; + c->me_cmp= s->avctx->me_cmp; + c->mb_cmp= s->avctx->mb_cmp; + c->me_sub_cmp= s->avctx->me_sub_cmp; + c->pix_fmt = PIX_FMT_YUV420P; + c->time_base= s->avctx->time_base; + c->max_b_frames= s->max_b_frames; + + if (avcodec_open(c, codec) < 0) + return -1; + + for(i=0; i<s->max_b_frames+2; i++){ + int ysize= c->width*c->height; + int csize= (c->width/2)*(c->height/2); + Picture pre_input, *pre_input_ptr= i ? s->input_picture[i-1] : s->next_picture_ptr; + + avcodec_get_frame_defaults(&input[i]); + input[i].data[0]= av_malloc(ysize + 2*csize); + input[i].data[1]= input[i].data[0] + ysize; + input[i].data[2]= input[i].data[1] + csize; + input[i].linesize[0]= c->width; + input[i].linesize[1]= + input[i].linesize[2]= c->width/2; + + if(pre_input_ptr && (!i || s->input_picture[i-1])) { + pre_input= *pre_input_ptr; + + if(pre_input.type != FF_BUFFER_TYPE_SHARED && i) { + pre_input.data[0]+=INPLACE_OFFSET; + pre_input.data[1]+=INPLACE_OFFSET; + pre_input.data[2]+=INPLACE_OFFSET; + } + + s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0], pre_input.data[0], pre_input.linesize[0], c->width, c->height); + s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1], pre_input.data[1], pre_input.linesize[1], c->width>>1, c->height>>1); + s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2], pre_input.data[2], pre_input.linesize[2], c->width>>1, c->height>>1); + } + } + + for(j=0; j<s->max_b_frames+1; j++){ + int64_t rd=0; + + if(!s->input_picture[j]) + break; + + c->error[0]= c->error[1]= c->error[2]= 0; + + input[0].pict_type= I_TYPE; + input[0].quality= 1 * FF_QP2LAMBDA; + out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[0]); +// rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT; + + for(i=0; i<s->max_b_frames+1; i++){ + int is_p= i % (j+1) == j || i==s->max_b_frames; + + input[i+1].pict_type= is_p ? P_TYPE : B_TYPE; + input[i+1].quality= is_p ? p_lambda : b_lambda; + out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[i+1]); + rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); + } + + /* get the delayed frames */ + while(out_size){ + out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); + rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); + } + + rd += c->error[0] + c->error[1] + c->error[2]; + + if(rd < best_rd){ + best_rd= rd; + best_b_count= j; + } + } + + av_freep(&outbuf); + avcodec_close(c); + av_freep(&c); + + for(i=0; i<s->max_b_frames+2; i++){ + av_freep(&input[i].data[0]); + } + + return best_b_count; +} + +static void select_input_picture(MpegEncContext *s){ + int i; + + for(i=1; i<MAX_PICTURE_COUNT; i++) + s->reordered_input_picture[i-1]= s->reordered_input_picture[i]; + s->reordered_input_picture[MAX_PICTURE_COUNT-1]= NULL; + + /* set next picture type & ordering */ + if(s->reordered_input_picture[0]==NULL && s->input_picture[0]){ + if(/*s->picture_in_gop_number >= s->gop_size ||*/ s->next_picture_ptr==NULL || s->intra_only){ + s->reordered_input_picture[0]= s->input_picture[0]; + s->reordered_input_picture[0]->pict_type= I_TYPE; + s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++; + }else{ + int b_frames; + + if(s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor){ + if(s->picture_in_gop_number < s->gop_size && skip_check(s, s->input_picture[0], s->next_picture_ptr)){ + //FIXME check that te gop check above is +-1 correct +//av_log(NULL, AV_LOG_DEBUG, "skip %p %"PRId64"\n", s->input_picture[0]->data[0], s->input_picture[0]->pts); + + if(s->input_picture[0]->type == FF_BUFFER_TYPE_SHARED){ + for(i=0; i<4; i++) + s->input_picture[0]->data[i]= NULL; + s->input_picture[0]->type= 0; + }else{ + assert( s->input_picture[0]->type==FF_BUFFER_TYPE_USER + || s->input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL); + + s->avctx->release_buffer(s->avctx, (AVFrame*)s->input_picture[0]); + } + + emms_c(); + ff_vbv_update(s, 0); + + goto no_output_pic; + } + } + + if(s->flags&CODEC_FLAG_PASS2){ + for(i=0; i<s->max_b_frames+1; i++){ + int pict_num= s->input_picture[0]->display_picture_number + i; + + if(pict_num >= s->rc_context.num_entries) + break; + if(!s->input_picture[i]){ + s->rc_context.entry[pict_num-1].new_pict_type = P_TYPE; + break; + } + + s->input_picture[i]->pict_type= + s->rc_context.entry[pict_num].new_pict_type; + } + } + + if(s->avctx->b_frame_strategy==0){ + b_frames= s->max_b_frames; + while(b_frames && !s->input_picture[b_frames]) b_frames--; + }else if(s->avctx->b_frame_strategy==1){ + for(i=1; i<s->max_b_frames+1; i++){ + if(s->input_picture[i] && s->input_picture[i]->b_frame_score==0){ + s->input_picture[i]->b_frame_score= + get_intra_count(s, s->input_picture[i ]->data[0], + s->input_picture[i-1]->data[0], s->linesize) + 1; + } + } + for(i=0; i<s->max_b_frames+1; i++){ + if(s->input_picture[i]==NULL || s->input_picture[i]->b_frame_score - 1 > s->mb_num/s->avctx->b_sensitivity) break; + } + + b_frames= FFMAX(0, i-1); + + /* reset scores */ + for(i=0; i<b_frames+1; i++){ + s->input_picture[i]->b_frame_score=0; + } + }else if(s->avctx->b_frame_strategy==2){ + b_frames= estimate_best_b_count(s); + }else{ + av_log(s->avctx, AV_LOG_ERROR, "illegal b frame strategy\n"); + b_frames=0; + } + + emms_c(); +//static int b_count=0; +//b_count+= b_frames; +//av_log(s->avctx, AV_LOG_DEBUG, "b_frames: %d\n", b_count); + + for(i= b_frames - 1; i>=0; i--){ + int type= s->input_picture[i]->pict_type; + if(type && type != B_TYPE) + b_frames= i; + } + if(s->input_picture[b_frames]->pict_type == B_TYPE && b_frames == s->max_b_frames){ + av_log(s->avctx, AV_LOG_ERROR, "warning, too many b frames in a row\n"); + } + + if(s->picture_in_gop_number + b_frames >= s->gop_size){ + if((s->flags2 & CODEC_FLAG2_STRICT_GOP) && s->gop_size > s->picture_in_gop_number){ + b_frames= s->gop_size - s->picture_in_gop_number - 1; + }else{ + if(s->flags & CODEC_FLAG_CLOSED_GOP) + b_frames=0; + s->input_picture[b_frames]->pict_type= I_TYPE; + } + } + + if( (s->flags & CODEC_FLAG_CLOSED_GOP) + && b_frames + && s->input_picture[b_frames]->pict_type== I_TYPE) + b_frames--; + + s->reordered_input_picture[0]= s->input_picture[b_frames]; + if(s->reordered_input_picture[0]->pict_type != I_TYPE) + s->reordered_input_picture[0]->pict_type= P_TYPE; + s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++; + for(i=0; i<b_frames; i++){ + s->reordered_input_picture[i+1]= s->input_picture[i]; + s->reordered_input_picture[i+1]->pict_type= B_TYPE; + s->reordered_input_picture[i+1]->coded_picture_number= s->coded_picture_number++; + } + } + } +no_output_pic: + if(s->reordered_input_picture[0]){ + s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=B_TYPE ? 3 : 0; + + copy_picture(&s->new_picture, s->reordered_input_picture[0]); + + if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_SHARED || s->avctx->rc_buffer_size){ + // input is a shared pix, so we can't modifiy it -> alloc a new one & ensure that the shared one is reuseable + + int i= ff_find_unused_picture(s, 0); + Picture *pic= &s->picture[i]; + + pic->reference = s->reordered_input_picture[0]->reference; + alloc_picture(s, pic, 0); + + /* mark us unused / free shared pic */ + if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_INTERNAL) + s->avctx->release_buffer(s->avctx, (AVFrame*)s->reordered_input_picture[0]); + for(i=0; i<4; i++) + s->reordered_input_picture[0]->data[i]= NULL; + s->reordered_input_picture[0]->type= 0; + + copy_picture_attributes(s, (AVFrame*)pic, (AVFrame*)s->reordered_input_picture[0]); + + s->current_picture_ptr= pic; + }else{ + // input is not a shared pix -> reuse buffer for current_pix + + assert( s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_USER + || s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL); + + s->current_picture_ptr= s->reordered_input_picture[0]; + for(i=0; i<4; i++){ + s->new_picture.data[i]+= INPLACE_OFFSET; + } + } + copy_picture(&s->current_picture, s->current_picture_ptr); + + s->picture_number= s->new_picture.display_picture_number; +//printf("dpn:%d\n", s->picture_number); + }else{ + memset(&s->new_picture, 0, sizeof(Picture)); + } +} + +int MPV_encode_picture(AVCodecContext *avctx, + unsigned char *buf, int buf_size, void *data) +{ + MpegEncContext *s = avctx->priv_data; + AVFrame *pic_arg = data; + int i, stuffing_count; + + for(i=0; i<avctx->thread_count; i++){ + int start_y= s->thread_context[i]->start_mb_y; + int end_y= s->thread_context[i]-> end_mb_y; + int h= s->mb_height; + uint8_t *start= buf + (size_t)(((int64_t) buf_size)*start_y/h); + uint8_t *end = buf + (size_t)(((int64_t) buf_size)* end_y/h); + + init_put_bits(&s->thread_context[i]->pb, start, end - start); + } + + s->picture_in_gop_number++; + + if(load_input_picture(s, pic_arg) < 0) + return -1; + + select_input_picture(s); + + /* output? */ + if(s->new_picture.data[0]){ + s->pict_type= s->new_picture.pict_type; +//emms_c(); +//printf("qs:%f %f %d\n", s->new_picture.quality, s->current_picture.quality, s->qscale); + MPV_frame_start(s, avctx); +vbv_retry: + if (encode_picture(s, s->picture_number) < 0) + return -1; + + avctx->real_pict_num = s->picture_number; + avctx->header_bits = s->header_bits; + avctx->mv_bits = s->mv_bits; + avctx->misc_bits = s->misc_bits; + avctx->i_tex_bits = s->i_tex_bits; + avctx->p_tex_bits = s->p_tex_bits; + avctx->i_count = s->i_count; + avctx->p_count = s->mb_num - s->i_count - s->skip_count; //FIXME f/b_count in avctx + avctx->skip_count = s->skip_count; + + MPV_frame_end(s); + + if (ENABLE_MJPEG_ENCODER && s->out_format == FMT_MJPEG) + ff_mjpeg_encode_picture_trailer(s); + + if(avctx->rc_buffer_size){ + RateControlContext *rcc= &s->rc_context; + int max_size= rcc->buffer_index/3; + + if(put_bits_count(&s->pb) > max_size && s->lambda < s->avctx->lmax){ + s->next_lambda= FFMAX(s->lambda+1, s->lambda*(s->qscale+1) / s->qscale); + if(s->adaptive_quant){ + int i; + for(i=0; i<s->mb_height*s->mb_stride; i++) + s->lambda_table[i]= FFMAX(s->lambda_table[i]+1, s->lambda_table[i]*(s->qscale+1) / s->qscale); + } + s->mb_skipped = 0; //done in MPV_frame_start() + if(s->pict_type==P_TYPE){ //done in encode_picture() so we must undo it + if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4) + s->no_rounding ^= 1; + } + if(s->pict_type!=B_TYPE){ + s->time_base= s->last_time_base; + s->last_non_b_time= s->time - s->pp_time; + } +// av_log(NULL, AV_LOG_ERROR, "R:%d ", s->next_lambda); + for(i=0; i<avctx->thread_count; i++){ + PutBitContext *pb= &s->thread_context[i]->pb; + init_put_bits(pb, pb->buf, pb->buf_end - pb->buf); + } + goto vbv_retry; + } + + assert(s->avctx->rc_max_rate); + } + + if(s->flags&CODEC_FLAG_PASS1) + ff_write_pass1_stats(s); + + for(i=0; i<4; i++){ + s->current_picture_ptr->error[i]= s->current_picture.error[i]; + avctx->error[i] += s->current_picture_ptr->error[i]; + } + + if(s->flags&CODEC_FLAG_PASS1) + assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits + avctx->i_tex_bits + avctx->p_tex_bits == put_bits_count(&s->pb)); + flush_put_bits(&s->pb); + s->frame_bits = put_bits_count(&s->pb); + + stuffing_count= ff_vbv_update(s, s->frame_bits); + if(stuffing_count){ + if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < stuffing_count + 50){ + av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n"); + return -1; + } + + switch(s->codec_id){ + case CODEC_ID_MPEG1VIDEO: + case CODEC_ID_MPEG2VIDEO: + while(stuffing_count--){ + put_bits(&s->pb, 8, 0); + } + break; + case CODEC_ID_MPEG4: + put_bits(&s->pb, 16, 0); + put_bits(&s->pb, 16, 0x1C3); + stuffing_count -= 4; + while(stuffing_count--){ + put_bits(&s->pb, 8, 0xFF); + } + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n"); + } + flush_put_bits(&s->pb); + s->frame_bits = put_bits_count(&s->pb); + } + + /* update mpeg1/2 vbv_delay for CBR */ + if(s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate && s->out_format == FMT_MPEG1 + && 90000LL * (avctx->rc_buffer_size-1) <= s->avctx->rc_max_rate*0xFFFFLL){ + int vbv_delay; + + assert(s->repeat_first_field==0); + + vbv_delay= lrintf(90000 * s->rc_context.buffer_index / s->avctx->rc_max_rate); + assert(vbv_delay < 0xFFFF); + + s->vbv_delay_ptr[0] &= 0xF8; + s->vbv_delay_ptr[0] |= vbv_delay>>13; + s->vbv_delay_ptr[1] = vbv_delay>>5; + s->vbv_delay_ptr[2] &= 0x07; + s->vbv_delay_ptr[2] |= vbv_delay<<3; + } + s->total_bits += s->frame_bits; + avctx->frame_bits = s->frame_bits; + }else{ + assert((pbBufPtr(&s->pb) == s->pb.buf)); + s->frame_bits=0; + } + assert((s->frame_bits&7)==0); + + return s->frame_bits/8; +} + +static inline void dct_single_coeff_elimination(MpegEncContext *s, int n, int threshold) +{ + static const char tab[64]= + {3,2,2,1,1,1,1,1, + 1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0}; + int score=0; + int run=0; + int i; + DCTELEM *block= s->block[n]; + const int last_index= s->block_last_index[n]; + int skip_dc; + + if(threshold<0){ + skip_dc=0; + threshold= -threshold; + }else + skip_dc=1; + + /* are all which we could set to zero are allready zero? */ + if(last_index<=skip_dc - 1) return; + + for(i=0; i<=last_index; i++){ + const int j = s->intra_scantable.permutated[i]; + const int level = FFABS(block[j]); + if(level==1){ + if(skip_dc && i==0) continue; + score+= tab[run]; + run=0; + }else if(level>1){ + return; + }else{ + run++; + } + } + if(score >= threshold) return; + for(i=skip_dc; i<=last_index; i++){ + const int j = s->intra_scantable.permutated[i]; + block[j]=0; + } + if(block[0]) s->block_last_index[n]= 0; + else s->block_last_index[n]= -1; +} + +static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block, int last_index) +{ + int i; + const int maxlevel= s->max_qcoeff; + const int minlevel= s->min_qcoeff; + int overflow=0; + + if(s->mb_intra){ + i=1; //skip clipping of intra dc + }else + i=0; + + for(;i<=last_index; i++){ + const int j= s->intra_scantable.permutated[i]; + int level = block[j]; + + if (level>maxlevel){ + level=maxlevel; + overflow++; + }else if(level<minlevel){ + level=minlevel; + overflow++; + } + + block[j]= level; + } + + if(overflow && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE) + av_log(s->avctx, AV_LOG_INFO, "warning, clipping %d dct coefficients to %d..%d\n", overflow, minlevel, maxlevel); +} + +static void get_visual_weight(int16_t *weight, uint8_t *ptr, int stride){ + int x, y; +//FIXME optimize + for(y=0; y<8; y++){ + for(x=0; x<8; x++){ + int x2, y2; + int sum=0; + int sqr=0; + int count=0; + + for(y2= FFMAX(y-1, 0); y2 < FFMIN(8, y+2); y2++){ + for(x2= FFMAX(x-1, 0); x2 < FFMIN(8, x+2); x2++){ + int v= ptr[x2 + y2*stride]; + sum += v; + sqr += v*v; + count++; + } + } + weight[x + 8*y]= (36*ff_sqrt(count*sqr - sum*sum)) / count; + } + } +} + +static av_always_inline void encode_mb_internal(MpegEncContext *s, int motion_x, int motion_y, int mb_block_height, int mb_block_count) +{ + int16_t weight[8][64]; + DCTELEM orig[8][64]; + const int mb_x= s->mb_x; + const int mb_y= s->mb_y; + int i; + int skip_dct[8]; + int dct_offset = s->linesize*8; //default for progressive frames + uint8_t *ptr_y, *ptr_cb, *ptr_cr; + int wrap_y, wrap_c; + + for(i=0; i<mb_block_count; i++) skip_dct[i]=s->skipdct; + + if(s->adaptive_quant){ + const int last_qp= s->qscale; + const int mb_xy= mb_x + mb_y*s->mb_stride; + + s->lambda= s->lambda_table[mb_xy]; + update_qscale(s); + + if(!(s->flags&CODEC_FLAG_QP_RD)){ + s->qscale= s->current_picture_ptr->qscale_table[mb_xy]; + s->dquant= s->qscale - last_qp; + + if(s->out_format==FMT_H263){ + s->dquant= av_clip(s->dquant, -2, 2); + + if(s->codec_id==CODEC_ID_MPEG4){ + if(!s->mb_intra){ + if(s->pict_type == B_TYPE){ + if(s->dquant&1 || s->mv_dir&MV_DIRECT) + s->dquant= 0; + } + if(s->mv_type==MV_TYPE_8X8) + s->dquant=0; + } + } + } + } + ff_set_qscale(s, last_qp + s->dquant); + }else if(s->flags&CODEC_FLAG_QP_RD) + ff_set_qscale(s, s->qscale + s->dquant); + + wrap_y = s->linesize; + wrap_c = s->uvlinesize; + ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16; + ptr_cb = s->new_picture.data[1] + (mb_y * mb_block_height * wrap_c) + mb_x * 8; + ptr_cr = s->new_picture.data[2] + (mb_y * mb_block_height * wrap_c) + mb_x * 8; + + if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ + uint8_t *ebuf= s->edge_emu_buffer + 32; + ff_emulated_edge_mc(ebuf , ptr_y , wrap_y,16,16,mb_x*16,mb_y*16, s->width , s->height); + ptr_y= ebuf; + ff_emulated_edge_mc(ebuf+18*wrap_y , ptr_cb, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1); + ptr_cb= ebuf+18*wrap_y; + ff_emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1); + ptr_cr= ebuf+18*wrap_y+8; + } + + if (s->mb_intra) { + if(s->flags&CODEC_FLAG_INTERLACED_DCT){ + int progressive_score, interlaced_score; + + s->interlaced_dct=0; + progressive_score= s->dsp.ildct_cmp[4](s, ptr_y , NULL, wrap_y, 8) + +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y*8, NULL, wrap_y, 8) - 400; + + if(progressive_score > 0){ + interlaced_score = s->dsp.ildct_cmp[4](s, ptr_y , NULL, wrap_y*2, 8) + +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y , NULL, wrap_y*2, 8); + if(progressive_score > interlaced_score){ + s->interlaced_dct=1; + + dct_offset= wrap_y; + wrap_y<<=1; + if (s->chroma_format == CHROMA_422) + wrap_c<<=1; + } + } + } + + s->dsp.get_pixels(s->block[0], ptr_y , wrap_y); + s->dsp.get_pixels(s->block[1], ptr_y + 8, wrap_y); + s->dsp.get_pixels(s->block[2], ptr_y + dct_offset , wrap_y); + s->dsp.get_pixels(s->block[3], ptr_y + dct_offset + 8, wrap_y); + + if(s->flags&CODEC_FLAG_GRAY){ + skip_dct[4]= 1; + skip_dct[5]= 1; + }else{ + s->dsp.get_pixels(s->block[4], ptr_cb, wrap_c); + s->dsp.get_pixels(s->block[5], ptr_cr, wrap_c); + if(!s->chroma_y_shift){ /* 422 */ + s->dsp.get_pixels(s->block[6], ptr_cb + (dct_offset>>1), wrap_c); + s->dsp.get_pixels(s->block[7], ptr_cr + (dct_offset>>1), wrap_c); + } + } + }else{ + op_pixels_func (*op_pix)[4]; + qpel_mc_func (*op_qpix)[16]; + uint8_t *dest_y, *dest_cb, *dest_cr; + + dest_y = s->dest[0]; + dest_cb = s->dest[1]; + dest_cr = s->dest[2]; + + if ((!s->no_rounding) || s->pict_type==B_TYPE){ + op_pix = s->dsp.put_pixels_tab; + op_qpix= s->dsp.put_qpel_pixels_tab; + }else{ + op_pix = s->dsp.put_no_rnd_pixels_tab; + op_qpix= s->dsp.put_no_rnd_qpel_pixels_tab; + } + + if (s->mv_dir & MV_DIR_FORWARD) { + MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix); + op_pix = s->dsp.avg_pixels_tab; + op_qpix= s->dsp.avg_qpel_pixels_tab; + } + if (s->mv_dir & MV_DIR_BACKWARD) { + MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix); + } + + if(s->flags&CODEC_FLAG_INTERLACED_DCT){ + int progressive_score, interlaced_score; + + s->interlaced_dct=0; + progressive_score= s->dsp.ildct_cmp[0](s, dest_y , ptr_y , wrap_y, 8) + +s->dsp.ildct_cmp[0](s, dest_y + wrap_y*8, ptr_y + wrap_y*8, wrap_y, 8) - 400; + + if(s->avctx->ildct_cmp == FF_CMP_VSSE) progressive_score -= 400; + + if(progressive_score>0){ + interlaced_score = s->dsp.ildct_cmp[0](s, dest_y , ptr_y , wrap_y*2, 8) + +s->dsp.ildct_cmp[0](s, dest_y + wrap_y , ptr_y + wrap_y , wrap_y*2, 8); + + if(progressive_score > interlaced_score){ + s->interlaced_dct=1; + + dct_offset= wrap_y; + wrap_y<<=1; + if (s->chroma_format == CHROMA_422) + wrap_c<<=1; + } + } + } + + s->dsp.diff_pixels(s->block[0], ptr_y , dest_y , wrap_y); + s->dsp.diff_pixels(s->block[1], ptr_y + 8, dest_y + 8, wrap_y); + s->dsp.diff_pixels(s->block[2], ptr_y + dct_offset , dest_y + dct_offset , wrap_y); + s->dsp.diff_pixels(s->block[3], ptr_y + dct_offset + 8, dest_y + dct_offset + 8, wrap_y); + + if(s->flags&CODEC_FLAG_GRAY){ + skip_dct[4]= 1; + skip_dct[5]= 1; + }else{ + s->dsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c); + s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c); + if(!s->chroma_y_shift){ /* 422 */ + s->dsp.diff_pixels(s->block[6], ptr_cb + (dct_offset>>1), dest_cb + (dct_offset>>1), wrap_c); + s->dsp.diff_pixels(s->block[7], ptr_cr + (dct_offset>>1), dest_cr + (dct_offset>>1), wrap_c); + } + } + /* pre quantization */ + if(s->current_picture.mc_mb_var[s->mb_stride*mb_y+ mb_x]<2*s->qscale*s->qscale){ + //FIXME optimize + if(s->dsp.sad[1](NULL, ptr_y , dest_y , wrap_y, 8) < 20*s->qscale) skip_dct[0]= 1; + if(s->dsp.sad[1](NULL, ptr_y + 8, dest_y + 8, wrap_y, 8) < 20*s->qscale) skip_dct[1]= 1; + if(s->dsp.sad[1](NULL, ptr_y +dct_offset , dest_y +dct_offset , wrap_y, 8) < 20*s->qscale) skip_dct[2]= 1; + if(s->dsp.sad[1](NULL, ptr_y +dct_offset+ 8, dest_y +dct_offset+ 8, wrap_y, 8) < 20*s->qscale) skip_dct[3]= 1; + if(s->dsp.sad[1](NULL, ptr_cb , dest_cb , wrap_c, 8) < 20*s->qscale) skip_dct[4]= 1; + if(s->dsp.sad[1](NULL, ptr_cr , dest_cr , wrap_c, 8) < 20*s->qscale) skip_dct[5]= 1; + if(!s->chroma_y_shift){ /* 422 */ + if(s->dsp.sad[1](NULL, ptr_cb +(dct_offset>>1), dest_cb +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[6]= 1; + if(s->dsp.sad[1](NULL, ptr_cr +(dct_offset>>1), dest_cr +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[7]= 1; + } + } + } + + if(s->avctx->quantizer_noise_shaping){ + if(!skip_dct[0]) get_visual_weight(weight[0], ptr_y , wrap_y); + if(!skip_dct[1]) get_visual_weight(weight[1], ptr_y + 8, wrap_y); + if(!skip_dct[2]) get_visual_weight(weight[2], ptr_y + dct_offset , wrap_y); + if(!skip_dct[3]) get_visual_weight(weight[3], ptr_y + dct_offset + 8, wrap_y); + if(!skip_dct[4]) get_visual_weight(weight[4], ptr_cb , wrap_c); + if(!skip_dct[5]) get_visual_weight(weight[5], ptr_cr , wrap_c); + if(!s->chroma_y_shift){ /* 422 */ + if(!skip_dct[6]) get_visual_weight(weight[6], ptr_cb + (dct_offset>>1), wrap_c); + if(!skip_dct[7]) get_visual_weight(weight[7], ptr_cr + (dct_offset>>1), wrap_c); + } + memcpy(orig[0], s->block[0], sizeof(DCTELEM)*64*mb_block_count); + } + + /* DCT & quantize */ + assert(s->out_format!=FMT_MJPEG || s->qscale==8); + { + for(i=0;i<mb_block_count;i++) { + if(!skip_dct[i]){ + int overflow; + s->block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow); + // FIXME we could decide to change to quantizer instead of clipping + // JS: I don't think that would be a good idea it could lower quality instead + // of improve it. Just INTRADC clipping deserves changes in quantizer + if (overflow) clip_coeffs(s, s->block[i], s->block_last_index[i]); + }else + s->block_last_index[i]= -1; + } + if(s->avctx->quantizer_noise_shaping){ + for(i=0;i<mb_block_count;i++) { + if(!skip_dct[i]){ + s->block_last_index[i] = dct_quantize_refine(s, s->block[i], weight[i], orig[i], i, s->qscale); + } + } + } + + if(s->luma_elim_threshold && !s->mb_intra) + for(i=0; i<4; i++) + dct_single_coeff_elimination(s, i, s->luma_elim_threshold); + if(s->chroma_elim_threshold && !s->mb_intra) + for(i=4; i<mb_block_count; i++) + dct_single_coeff_elimination(s, i, s->chroma_elim_threshold); + + if(s->flags & CODEC_FLAG_CBP_RD){ + for(i=0;i<mb_block_count;i++) { + if(s->block_last_index[i] == -1) + s->coded_score[i]= INT_MAX/256; + } + } + } + + if((s->flags&CODEC_FLAG_GRAY) && s->mb_intra){ + s->block_last_index[4]= + s->block_last_index[5]= 0; + s->block[4][0]= + s->block[5][0]= (1024 + s->c_dc_scale/2)/ s->c_dc_scale; + } + + //non c quantize code returns incorrect block_last_index FIXME + if(s->alternate_scan && s->dct_quantize != dct_quantize_c){ + for(i=0; i<mb_block_count; i++){ + int j; + if(s->block_last_index[i]>0){ + for(j=63; j>0; j--){ + if(s->block[i][ s->intra_scantable.permutated[j] ]) break; + } + s->block_last_index[i]= j; + } + } + } + + /* huffman encode */ + switch(s->codec_id){ //FIXME funct ptr could be slightly faster + case CODEC_ID_MPEG1VIDEO: + case CODEC_ID_MPEG2VIDEO: + if (ENABLE_MPEG1VIDEO_ENCODER || ENABLE_MPEG2VIDEO_ENCODER) + mpeg1_encode_mb(s, s->block, motion_x, motion_y); + break; + case CODEC_ID_MPEG4: + if (ENABLE_MPEG4_ENCODER) + mpeg4_encode_mb(s, s->block, motion_x, motion_y); + break; + case CODEC_ID_MSMPEG4V2: + case CODEC_ID_MSMPEG4V3: + case CODEC_ID_WMV1: + if (ENABLE_MSMPEG4_ENCODER) + msmpeg4_encode_mb(s, s->block, motion_x, motion_y); + break; + case CODEC_ID_WMV2: + if (ENABLE_WMV2_ENCODER) + ff_wmv2_encode_mb(s, s->block, motion_x, motion_y); + break; + case CODEC_ID_H261: + if (ENABLE_H261_ENCODER) + ff_h261_encode_mb(s, s->block, motion_x, motion_y); + break; + case CODEC_ID_H263: + case CODEC_ID_H263P: + case CODEC_ID_FLV1: + case CODEC_ID_RV10: + case CODEC_ID_RV20: + if (ENABLE_H263_ENCODER || ENABLE_H263P_ENCODER || + ENABLE_FLV_ENCODER || ENABLE_RV10_ENCODER || ENABLE_RV20_ENCODER) + h263_encode_mb(s, s->block, motion_x, motion_y); + break; + case CODEC_ID_MJPEG: + if (ENABLE_MJPEG_ENCODER) + ff_mjpeg_encode_mb(s, s->block); + break; + default: + assert(0); + } +} + +static av_always_inline void encode_mb(MpegEncContext *s, int motion_x, int motion_y) +{ + if (s->chroma_format == CHROMA_420) encode_mb_internal(s, motion_x, motion_y, 8, 6); + else encode_mb_internal(s, motion_x, motion_y, 16, 8); +} + +static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){ + int i; + + memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? + + /* mpeg1 */ + d->mb_skip_run= s->mb_skip_run; + for(i=0; i<3; i++) + d->last_dc[i]= s->last_dc[i]; + + /* statistics */ + d->mv_bits= s->mv_bits; + d->i_tex_bits= s->i_tex_bits; + d->p_tex_bits= s->p_tex_bits; + d->i_count= s->i_count; + d->f_count= s->f_count; + d->b_count= s->b_count; + d->skip_count= s->skip_count; + d->misc_bits= s->misc_bits; + d->last_bits= 0; + + d->mb_skipped= 0; + d->qscale= s->qscale; + d->dquant= s->dquant; + + d->esc3_level_length= s->esc3_level_length; +} + +static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int type){ + int i; + + memcpy(d->mv, s->mv, 2*4*2*sizeof(int)); + memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop? + + /* mpeg1 */ + d->mb_skip_run= s->mb_skip_run; + for(i=0; i<3; i++) + d->last_dc[i]= s->last_dc[i]; + + /* statistics */ + d->mv_bits= s->mv_bits; + d->i_tex_bits= s->i_tex_bits; + d->p_tex_bits= s->p_tex_bits; + d->i_count= s->i_count; + d->f_count= s->f_count; + d->b_count= s->b_count; + d->skip_count= s->skip_count; + d->misc_bits= s->misc_bits; + + d->mb_intra= s->mb_intra; + d->mb_skipped= s->mb_skipped; + d->mv_type= s->mv_type; + d->mv_dir= s->mv_dir; + d->pb= s->pb; + if(s->data_partitioning){ + d->pb2= s->pb2; + d->tex_pb= s->tex_pb; + } + d->block= s->block; + for(i=0; i<8; i++) + d->block_last_index[i]= s->block_last_index[i]; + d->interlaced_dct= s->interlaced_dct; + d->qscale= s->qscale; + + d->esc3_level_length= s->esc3_level_length; +} + +static inline void encode_mb_hq(MpegEncContext *s, MpegEncContext *backup, MpegEncContext *best, int type, + PutBitContext pb[2], PutBitContext pb2[2], PutBitContext tex_pb[2], + int *dmin, int *next_block, int motion_x, int motion_y) +{ + int score; + uint8_t *dest_backup[3]; + + copy_context_before_encode(s, backup, type); + + s->block= s->blocks[*next_block]; + s->pb= pb[*next_block]; + if(s->data_partitioning){ + s->pb2 = pb2 [*next_block]; + s->tex_pb= tex_pb[*next_block]; + } + + if(*next_block){ + memcpy(dest_backup, s->dest, sizeof(s->dest)); + s->dest[0] = s->rd_scratchpad; + s->dest[1] = s->rd_scratchpad + 16*s->linesize; + s->dest[2] = s->rd_scratchpad + 16*s->linesize + 8; + assert(s->linesize >= 32); //FIXME + } + + encode_mb(s, motion_x, motion_y); + + score= put_bits_count(&s->pb); + if(s->data_partitioning){ + score+= put_bits_count(&s->pb2); + score+= put_bits_count(&s->tex_pb); + } + + if(s->avctx->mb_decision == FF_MB_DECISION_RD){ + MPV_decode_mb(s, s->block); + + score *= s->lambda2; + score += sse_mb(s) << FF_LAMBDA_SHIFT; + } + + if(*next_block){ + memcpy(s->dest, dest_backup, sizeof(s->dest)); + } + + if(score<*dmin){ + *dmin= score; + *next_block^=1; + + copy_context_after_encode(best, s, type); + } +} + +static int sse(MpegEncContext *s, uint8_t *src1, uint8_t *src2, int w, int h, int stride){ + uint32_t *sq = ff_squareTbl + 256; + int acc=0; + int x,y; + + if(w==16 && h==16) + return s->dsp.sse[0](NULL, src1, src2, stride, 16); + else if(w==8 && h==8) + return s->dsp.sse[1](NULL, src1, src2, stride, 8); + + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + acc+= sq[src1[x + y*stride] - src2[x + y*stride]]; + } + } + + assert(acc>=0); + + return acc; +} + +static int sse_mb(MpegEncContext *s){ + int w= 16; + int h= 16; + + if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16; + if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16; + + if(w==16 && h==16) + if(s->avctx->mb_cmp == FF_CMP_NSSE){ + return s->dsp.nsse[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16) + +s->dsp.nsse[1](s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8) + +s->dsp.nsse[1](s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8); + }else{ + return s->dsp.sse[0](NULL, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16) + +s->dsp.sse[1](NULL, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8) + +s->dsp.sse[1](NULL, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8); + } + else + return sse(s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], w, h, s->linesize) + +sse(s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[1], w>>1, h>>1, s->uvlinesize) + +sse(s, s->new_picture.data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8,s->dest[2], w>>1, h>>1, s->uvlinesize); +} + +static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){ + MpegEncContext *s= arg; + + + s->me.pre_pass=1; + s->me.dia_size= s->avctx->pre_dia_size; + s->first_slice_line=1; + for(s->mb_y= s->end_mb_y-1; s->mb_y >= s->start_mb_y; s->mb_y--) { + for(s->mb_x=s->mb_width-1; s->mb_x >=0 ;s->mb_x--) { + ff_pre_estimate_p_frame_motion(s, s->mb_x, s->mb_y); + } + s->first_slice_line=0; + } + + s->me.pre_pass=0; + + return 0; +} + +static int estimate_motion_thread(AVCodecContext *c, void *arg){ + MpegEncContext *s= arg; + + ff_check_alignment(); + + s->me.dia_size= s->avctx->dia_size; + s->first_slice_line=1; + for(s->mb_y= s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { + s->mb_x=0; //for block init below + ff_init_block_index(s); + for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) { + s->block_index[0]+=2; + s->block_index[1]+=2; + s->block_index[2]+=2; + s->block_index[3]+=2; + + /* compute motion vector & mb_type and store in context */ + if(s->pict_type==B_TYPE) + ff_estimate_b_frame_motion(s, s->mb_x, s->mb_y); + else + ff_estimate_p_frame_motion(s, s->mb_x, s->mb_y); + } + s->first_slice_line=0; + } + return 0; +} + +static int mb_var_thread(AVCodecContext *c, void *arg){ + MpegEncContext *s= arg; + int mb_x, mb_y; + + ff_check_alignment(); + + for(mb_y=s->start_mb_y; mb_y < s->end_mb_y; mb_y++) { + for(mb_x=0; mb_x < s->mb_width; mb_x++) { + int xx = mb_x * 16; + int yy = mb_y * 16; + uint8_t *pix = s->new_picture.data[0] + (yy * s->linesize) + xx; + int varc; + int sum = s->dsp.pix_sum(pix, s->linesize); + + varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; + + s->current_picture.mb_var [s->mb_stride * mb_y + mb_x] = varc; + s->current_picture.mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8; + s->me.mb_var_sum_temp += varc; + } + } + return 0; +} + +static void write_slice_end(MpegEncContext *s){ + if(ENABLE_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4){ + if(s->partitioned_frame){ + ff_mpeg4_merge_partitions(s); + } + + ff_mpeg4_stuffing(&s->pb); + }else if(ENABLE_MJPEG_ENCODER && s->out_format == FMT_MJPEG){ + ff_mjpeg_encode_stuffing(&s->pb); + } + + align_put_bits(&s->pb); + flush_put_bits(&s->pb); + + if((s->flags&CODEC_FLAG_PASS1) && !s->partitioned_frame) + s->misc_bits+= get_bits_diff(s); +} + +static int encode_thread(AVCodecContext *c, void *arg){ + MpegEncContext *s= arg; + int mb_x, mb_y, pdif = 0; + int i, j; + MpegEncContext best_s, backup_s; + uint8_t bit_buf[2][MAX_MB_BYTES]; + uint8_t bit_buf2[2][MAX_MB_BYTES]; + uint8_t bit_buf_tex[2][MAX_MB_BYTES]; + PutBitContext pb[2], pb2[2], tex_pb[2]; +//printf("%d->%d\n", s->resync_mb_y, s->end_mb_y); + + ff_check_alignment(); + + for(i=0; i<2; i++){ + init_put_bits(&pb [i], bit_buf [i], MAX_MB_BYTES); + init_put_bits(&pb2 [i], bit_buf2 [i], MAX_MB_BYTES); + init_put_bits(&tex_pb[i], bit_buf_tex[i], MAX_MB_BYTES); + } + + s->last_bits= put_bits_count(&s->pb); + s->mv_bits=0; + s->misc_bits=0; + s->i_tex_bits=0; + s->p_tex_bits=0; + s->i_count=0; + s->f_count=0; + s->b_count=0; + s->skip_count=0; + + for(i=0; i<3; i++){ + /* init last dc values */ + /* note: quant matrix value (8) is implied here */ + s->last_dc[i] = 128 << s->intra_dc_precision; + + s->current_picture.error[i] = 0; + } + s->mb_skip_run = 0; + memset(s->last_mv, 0, sizeof(s->last_mv)); + + s->last_mv_dir = 0; + + switch(s->codec_id){ + case CODEC_ID_H263: + case CODEC_ID_H263P: + case CODEC_ID_FLV1: + if (ENABLE_H263_ENCODER || ENABLE_H263P_ENCODER || ENABLE_FLV_ENCODER) + s->gob_index = ff_h263_get_gob_height(s); + break; + case CODEC_ID_MPEG4: + if(ENABLE_MPEG4_ENCODER && s->partitioned_frame) + ff_mpeg4_init_partitions(s); + break; + } + + s->resync_mb_x=0; + s->resync_mb_y=0; + s->first_slice_line = 1; + s->ptr_lastgob = s->pb.buf; + for(mb_y= s->start_mb_y; mb_y < s->end_mb_y; mb_y++) { +// printf("row %d at %X\n", s->mb_y, (int)s); + s->mb_x=0; + s->mb_y= mb_y; + + ff_set_qscale(s, s->qscale); + ff_init_block_index(s); + + for(mb_x=0; mb_x < s->mb_width; mb_x++) { + int xy= mb_y*s->mb_stride + mb_x; // removed const, H261 needs to adjust this + int mb_type= s->mb_type[xy]; +// int d; + int dmin= INT_MAX; + int dir; + + if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){ + av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + if(s->data_partitioning){ + if( s->pb2 .buf_end - s->pb2 .buf - (put_bits_count(&s-> pb2)>>3) < MAX_MB_BYTES + || s->tex_pb.buf_end - s->tex_pb.buf - (put_bits_count(&s->tex_pb )>>3) < MAX_MB_BYTES){ + av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + } + + s->mb_x = mb_x; + s->mb_y = mb_y; // moved into loop, can get changed by H.261 + ff_update_block_index(s); + + if(ENABLE_H261_ENCODER && s->codec_id == CODEC_ID_H261){ + ff_h261_reorder_mb_index(s); + xy= s->mb_y*s->mb_stride + s->mb_x; + mb_type= s->mb_type[xy]; + } + + /* write gob / video packet header */ + if(s->rtp_mode){ + int current_packet_size, is_gob_start; + + current_packet_size= ((put_bits_count(&s->pb)+7)>>3) - (s->ptr_lastgob - s->pb.buf); + + is_gob_start= s->avctx->rtp_payload_size && current_packet_size >= s->avctx->rtp_payload_size && mb_y + mb_x>0; + + if(s->start_mb_y == mb_y && mb_y > 0 && mb_x==0) is_gob_start=1; + + switch(s->codec_id){ + case CODEC_ID_H263: + case CODEC_ID_H263P: + if(!s->h263_slice_structured) + if(s->mb_x || s->mb_y%s->gob_index) is_gob_start=0; + break; + case CODEC_ID_MPEG2VIDEO: + if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1; + case CODEC_ID_MPEG1VIDEO: + if(s->mb_skip_run) is_gob_start=0; + break; + } + + if(is_gob_start){ + if(s->start_mb_y != mb_y || mb_x!=0){ + write_slice_end(s); + + if(ENABLE_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->partitioned_frame){ + ff_mpeg4_init_partitions(s); + } + } + + assert((put_bits_count(&s->pb)&7) == 0); + current_packet_size= pbBufPtr(&s->pb) - s->ptr_lastgob; + + if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){ + int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y; + int d= 100 / s->avctx->error_rate; + if(r % d == 0){ + current_packet_size=0; +#ifndef ALT_BITSTREAM_WRITER + s->pb.buf_ptr= s->ptr_lastgob; +#endif + assert(pbBufPtr(&s->pb) == s->ptr_lastgob); + } + } + + if (s->avctx->rtp_callback){ + int number_mb = (mb_y - s->resync_mb_y)*s->mb_width + mb_x - s->resync_mb_x; + s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, number_mb); + } + + switch(s->codec_id){ + case CODEC_ID_MPEG4: + if (ENABLE_MPEG4_ENCODER) { + ff_mpeg4_encode_video_packet_header(s); + ff_mpeg4_clean_buffers(s); + } + break; + case CODEC_ID_MPEG1VIDEO: + case CODEC_ID_MPEG2VIDEO: + if (ENABLE_MPEG1VIDEO_ENCODER || ENABLE_MPEG2VIDEO_ENCODER) { + ff_mpeg1_encode_slice_header(s); + ff_mpeg1_clean_buffers(s); + } + break; + case CODEC_ID_H263: + case CODEC_ID_H263P: + if (ENABLE_H263_ENCODER || ENABLE_H263P_ENCODER) + h263_encode_gob_header(s, mb_y); + break; + } + + if(s->flags&CODEC_FLAG_PASS1){ + int bits= put_bits_count(&s->pb); + s->misc_bits+= bits - s->last_bits; + s->last_bits= bits; + } + + s->ptr_lastgob += current_packet_size; + s->first_slice_line=1; + s->resync_mb_x=mb_x; + s->resync_mb_y=mb_y; + } + } + + if( (s->resync_mb_x == s->mb_x) + && s->resync_mb_y+1 == s->mb_y){ + s->first_slice_line=0; + } + + s->mb_skipped=0; + s->dquant=0; //only for QP_RD + + if(mb_type & (mb_type-1) || (s->flags & CODEC_FLAG_QP_RD)){ // more than 1 MB type possible or CODEC_FLAG_QP_RD + int next_block=0; + int pb_bits_count, pb2_bits_count, tex_pb_bits_count; + + copy_context_before_encode(&backup_s, s, -1); + backup_s.pb= s->pb; + best_s.data_partitioning= s->data_partitioning; + best_s.partitioned_frame= s->partitioned_frame; + if(s->data_partitioning){ + backup_s.pb2= s->pb2; + backup_s.tex_pb= s->tex_pb; + } + + if(mb_type&CANDIDATE_MB_TYPE_INTER){ + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mb_intra= 0; + s->mv[0][0][0] = s->p_mv_table[xy][0]; + s->mv[0][0][1] = s->p_mv_table[xy][1]; + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER, pb, pb2, tex_pb, + &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]); + } + if(mb_type&CANDIDATE_MB_TYPE_INTER_I){ + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_FIELD; + s->mb_intra= 0; + for(i=0; i<2; i++){ + j= s->field_select[0][i] = s->p_field_select_table[i][xy]; + s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0]; + s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1]; + } + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER_I, pb, pb2, tex_pb, + &dmin, &next_block, 0, 0); + } + if(mb_type&CANDIDATE_MB_TYPE_SKIPPED){ + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mb_intra= 0; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_SKIPPED, pb, pb2, tex_pb, + &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]); + } + if(mb_type&CANDIDATE_MB_TYPE_INTER4V){ + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_8X8; + s->mb_intra= 0; + for(i=0; i<4; i++){ + s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0]; + s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1]; + } + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb, + &dmin, &next_block, 0, 0); + } + if(mb_type&CANDIDATE_MB_TYPE_FORWARD){ + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mb_intra= 0; + s->mv[0][0][0] = s->b_forw_mv_table[xy][0]; + s->mv[0][0][1] = s->b_forw_mv_table[xy][1]; + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD, pb, pb2, tex_pb, + &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]); + } + if(mb_type&CANDIDATE_MB_TYPE_BACKWARD){ + s->mv_dir = MV_DIR_BACKWARD; + s->mv_type = MV_TYPE_16X16; + s->mb_intra= 0; + s->mv[1][0][0] = s->b_back_mv_table[xy][0]; + s->mv[1][0][1] = s->b_back_mv_table[xy][1]; + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD, pb, pb2, tex_pb, + &dmin, &next_block, s->mv[1][0][0], s->mv[1][0][1]); + } + if(mb_type&CANDIDATE_MB_TYPE_BIDIR){ + s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; + s->mv_type = MV_TYPE_16X16; + s->mb_intra= 0; + s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0]; + s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1]; + s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0]; + s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1]; + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR, pb, pb2, tex_pb, + &dmin, &next_block, 0, 0); + } + if(mb_type&CANDIDATE_MB_TYPE_FORWARD_I){ + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_FIELD; + s->mb_intra= 0; + for(i=0; i<2; i++){ + j= s->field_select[0][i] = s->b_field_select_table[0][i][xy]; + s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0]; + s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1]; + } + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD_I, pb, pb2, tex_pb, + &dmin, &next_block, 0, 0); + } + if(mb_type&CANDIDATE_MB_TYPE_BACKWARD_I){ + s->mv_dir = MV_DIR_BACKWARD; + s->mv_type = MV_TYPE_FIELD; + s->mb_intra= 0; + for(i=0; i<2; i++){ + j= s->field_select[1][i] = s->b_field_select_table[1][i][xy]; + s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0]; + s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1]; + } + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD_I, pb, pb2, tex_pb, + &dmin, &next_block, 0, 0); + } + if(mb_type&CANDIDATE_MB_TYPE_BIDIR_I){ + s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; + s->mv_type = MV_TYPE_FIELD; + s->mb_intra= 0; + for(dir=0; dir<2; dir++){ + for(i=0; i<2; i++){ + j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy]; + s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0]; + s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1]; + } + } + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR_I, pb, pb2, tex_pb, + &dmin, &next_block, 0, 0); + } + if(mb_type&CANDIDATE_MB_TYPE_INTRA){ + s->mv_dir = 0; + s->mv_type = MV_TYPE_16X16; + s->mb_intra= 1; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTRA, pb, pb2, tex_pb, + &dmin, &next_block, 0, 0); + if(s->h263_pred || s->h263_aic){ + if(best_s.mb_intra) + s->mbintra_table[mb_x + mb_y*s->mb_stride]=1; + else + ff_clean_intra_table_entries(s); //old mode? + } + } + + if((s->flags & CODEC_FLAG_QP_RD) && dmin < INT_MAX){ + if(best_s.mv_type==MV_TYPE_16X16){ //FIXME move 4mv after QPRD + const int last_qp= backup_s.qscale; + int qpi, qp, dc[6]; + DCTELEM ac[6][16]; + const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0; + static const int dquant_tab[4]={-1,1,-2,2}; + + assert(backup_s.dquant == 0); + + //FIXME intra + s->mv_dir= best_s.mv_dir; + s->mv_type = MV_TYPE_16X16; + s->mb_intra= best_s.mb_intra; + s->mv[0][0][0] = best_s.mv[0][0][0]; + s->mv[0][0][1] = best_s.mv[0][0][1]; + s->mv[1][0][0] = best_s.mv[1][0][0]; + s->mv[1][0][1] = best_s.mv[1][0][1]; + + qpi = s->pict_type == B_TYPE ? 2 : 0; + for(; qpi<4; qpi++){ + int dquant= dquant_tab[qpi]; + qp= last_qp + dquant; + if(qp < s->avctx->qmin || qp > s->avctx->qmax) + continue; + backup_s.dquant= dquant; + if(s->mb_intra && s->dc_val[0]){ + for(i=0; i<6; i++){ + dc[i]= s->dc_val[0][ s->block_index[i] ]; + memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(DCTELEM)*16); + } + } + + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER /* wrong but unused */, pb, pb2, tex_pb, + &dmin, &next_block, s->mv[mvdir][0][0], s->mv[mvdir][0][1]); + if(best_s.qscale != qp){ + if(s->mb_intra && s->dc_val[0]){ + for(i=0; i<6; i++){ + s->dc_val[0][ s->block_index[i] ]= dc[i]; + memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(DCTELEM)*16); + } + } + } + } + } + } + if(ENABLE_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT){ + int mx= s->b_direct_mv_table[xy][0]; + int my= s->b_direct_mv_table[xy][1]; + + backup_s.dquant = 0; + s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; + s->mb_intra= 0; + ff_mpeg4_set_direct_mv(s, mx, my); + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb, + &dmin, &next_block, mx, my); + } + if(ENABLE_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT0){ + backup_s.dquant = 0; + s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; + s->mb_intra= 0; + ff_mpeg4_set_direct_mv(s, 0, 0); + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb, + &dmin, &next_block, 0, 0); + } + if(!best_s.mb_intra && s->flags2&CODEC_FLAG2_SKIP_RD){ + int coded=0; + for(i=0; i<6; i++) + coded |= s->block_last_index[i]; + if(coded){ + int mx,my; + memcpy(s->mv, best_s.mv, sizeof(s->mv)); + if(ENABLE_MPEG4_ENCODER && best_s.mv_dir & MV_DIRECT){ + mx=my=0; //FIXME find the one we actually used + ff_mpeg4_set_direct_mv(s, mx, my); + }else if(best_s.mv_dir&MV_DIR_BACKWARD){ + mx= s->mv[1][0][0]; + my= s->mv[1][0][1]; + }else{ + mx= s->mv[0][0][0]; + my= s->mv[0][0][1]; + } + + s->mv_dir= best_s.mv_dir; + s->mv_type = best_s.mv_type; + s->mb_intra= 0; +/* s->mv[0][0][0] = best_s.mv[0][0][0]; + s->mv[0][0][1] = best_s.mv[0][0][1]; + s->mv[1][0][0] = best_s.mv[1][0][0]; + s->mv[1][0][1] = best_s.mv[1][0][1];*/ + backup_s.dquant= 0; + s->skipdct=1; + encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER /* wrong but unused */, pb, pb2, tex_pb, + &dmin, &next_block, mx, my); + s->skipdct=0; + } + } + + s->current_picture.qscale_table[xy]= best_s.qscale; + + copy_context_after_encode(s, &best_s, -1); + + pb_bits_count= put_bits_count(&s->pb); + flush_put_bits(&s->pb); + ff_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count); + s->pb= backup_s.pb; + + if(s->data_partitioning){ + pb2_bits_count= put_bits_count(&s->pb2); + flush_put_bits(&s->pb2); + ff_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count); + s->pb2= backup_s.pb2; + + tex_pb_bits_count= put_bits_count(&s->tex_pb); + flush_put_bits(&s->tex_pb); + ff_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count); + s->tex_pb= backup_s.tex_pb; + } + s->last_bits= put_bits_count(&s->pb); + + if (ENABLE_ANY_H263_ENCODER && + s->out_format == FMT_H263 && s->pict_type!=B_TYPE) + ff_h263_update_motion_val(s); + + if(next_block==0){ //FIXME 16 vs linesize16 + s->dsp.put_pixels_tab[0][0](s->dest[0], s->rd_scratchpad , s->linesize ,16); + s->dsp.put_pixels_tab[1][0](s->dest[1], s->rd_scratchpad + 16*s->linesize , s->uvlinesize, 8); + s->dsp.put_pixels_tab[1][0](s->dest[2], s->rd_scratchpad + 16*s->linesize + 8, s->uvlinesize, 8); + } + + if(s->avctx->mb_decision == FF_MB_DECISION_BITS) + MPV_decode_mb(s, s->block); + } else { + int motion_x = 0, motion_y = 0; + s->mv_type=MV_TYPE_16X16; + // only one MB-Type possible + + switch(mb_type){ + case CANDIDATE_MB_TYPE_INTRA: + s->mv_dir = 0; + s->mb_intra= 1; + motion_x= s->mv[0][0][0] = 0; + motion_y= s->mv[0][0][1] = 0; + break; + case CANDIDATE_MB_TYPE_INTER: + s->mv_dir = MV_DIR_FORWARD; + s->mb_intra= 0; + motion_x= s->mv[0][0][0] = s->p_mv_table[xy][0]; + motion_y= s->mv[0][0][1] = s->p_mv_table[xy][1]; + break; + case CANDIDATE_MB_TYPE_INTER_I: + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_FIELD; + s->mb_intra= 0; + for(i=0; i<2; i++){ + j= s->field_select[0][i] = s->p_field_select_table[i][xy]; + s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0]; + s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1]; + } + break; + case CANDIDATE_MB_TYPE_INTER4V: + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_8X8; + s->mb_intra= 0; + for(i=0; i<4; i++){ + s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0]; + s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1]; + } + break; + case CANDIDATE_MB_TYPE_DIRECT: + if (ENABLE_MPEG4_ENCODER) { + s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT; + s->mb_intra= 0; + motion_x=s->b_direct_mv_table[xy][0]; + motion_y=s->b_direct_mv_table[xy][1]; + ff_mpeg4_set_direct_mv(s, motion_x, motion_y); + } + break; + case CANDIDATE_MB_TYPE_DIRECT0: + if (ENABLE_MPEG4_ENCODER) { + s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT; + s->mb_intra= 0; + ff_mpeg4_set_direct_mv(s, 0, 0); + } + break; + case CANDIDATE_MB_TYPE_BIDIR: + s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; + s->mb_intra= 0; + s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0]; + s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1]; + s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0]; + s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1]; + break; + case CANDIDATE_MB_TYPE_BACKWARD: + s->mv_dir = MV_DIR_BACKWARD; + s->mb_intra= 0; + motion_x= s->mv[1][0][0] = s->b_back_mv_table[xy][0]; + motion_y= s->mv[1][0][1] = s->b_back_mv_table[xy][1]; + break; + case CANDIDATE_MB_TYPE_FORWARD: + s->mv_dir = MV_DIR_FORWARD; + s->mb_intra= 0; + motion_x= s->mv[0][0][0] = s->b_forw_mv_table[xy][0]; + motion_y= s->mv[0][0][1] = s->b_forw_mv_table[xy][1]; +// printf(" %d %d ", motion_x, motion_y); + break; + case CANDIDATE_MB_TYPE_FORWARD_I: + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_FIELD; + s->mb_intra= 0; + for(i=0; i<2; i++){ + j= s->field_select[0][i] = s->b_field_select_table[0][i][xy]; + s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0]; + s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1]; + } + break; + case CANDIDATE_MB_TYPE_BACKWARD_I: + s->mv_dir = MV_DIR_BACKWARD; + s->mv_type = MV_TYPE_FIELD; + s->mb_intra= 0; + for(i=0; i<2; i++){ + j= s->field_select[1][i] = s->b_field_select_table[1][i][xy]; + s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0]; + s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1]; + } + break; + case CANDIDATE_MB_TYPE_BIDIR_I: + s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD; + s->mv_type = MV_TYPE_FIELD; + s->mb_intra= 0; + for(dir=0; dir<2; dir++){ + for(i=0; i<2; i++){ + j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy]; + s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0]; + s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1]; + } + } + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "illegal MB type\n"); + } + + encode_mb(s, motion_x, motion_y); + + // RAL: Update last macroblock type + s->last_mv_dir = s->mv_dir; + + if (ENABLE_ANY_H263_ENCODER && + s->out_format == FMT_H263 && s->pict_type!=B_TYPE) + ff_h263_update_motion_val(s); + + MPV_decode_mb(s, s->block); + } + + /* clean the MV table in IPS frames for direct mode in B frames */ + if(s->mb_intra /* && I,P,S_TYPE */){ + s->p_mv_table[xy][0]=0; + s->p_mv_table[xy][1]=0; + } + + if(s->flags&CODEC_FLAG_PSNR){ + int w= 16; + int h= 16; + + if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16; + if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16; + + s->current_picture.error[0] += sse( + s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, + s->dest[0], w, h, s->linesize); + s->current_picture.error[1] += sse( + s, s->new_picture.data[1] + s->mb_x*8 + s->mb_y*s->uvlinesize*8, + s->dest[1], w>>1, h>>1, s->uvlinesize); + s->current_picture.error[2] += sse( + s, s->new_picture .data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8, + s->dest[2], w>>1, h>>1, s->uvlinesize); + } + if(s->loop_filter){ + if(ENABLE_ANY_H263_ENCODER && s->out_format == FMT_H263) + ff_h263_loop_filter(s); + } +//printf("MB %d %d bits\n", s->mb_x+s->mb_y*s->mb_stride, put_bits_count(&s->pb)); + } + } + + //not beautiful here but we must write it before flushing so it has to be here + if (ENABLE_MSMPEG4_ENCODER && s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type == I_TYPE) + msmpeg4_encode_ext_header(s); + + write_slice_end(s); + + /* Send the last GOB if RTP */ + if (s->avctx->rtp_callback) { + int number_mb = (mb_y - s->resync_mb_y)*s->mb_width - s->resync_mb_x; + pdif = pbBufPtr(&s->pb) - s->ptr_lastgob; + /* Call the RTP callback to send the last GOB */ + emms_c(); + s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, pdif, number_mb); + } + + return 0; +} + +#define MERGE(field) dst->field += src->field; src->field=0 +static void merge_context_after_me(MpegEncContext *dst, MpegEncContext *src){ + MERGE(me.scene_change_score); + MERGE(me.mc_mb_var_sum_temp); + MERGE(me.mb_var_sum_temp); +} + +static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src){ + int i; + + MERGE(dct_count[0]); //note, the other dct vars are not part of the context + MERGE(dct_count[1]); + MERGE(mv_bits); + MERGE(i_tex_bits); + MERGE(p_tex_bits); + MERGE(i_count); + MERGE(f_count); + MERGE(b_count); + MERGE(skip_count); + MERGE(misc_bits); + MERGE(error_count); + MERGE(padding_bug_score); + MERGE(current_picture.error[0]); + MERGE(current_picture.error[1]); + MERGE(current_picture.error[2]); + + if(dst->avctx->noise_reduction){ + for(i=0; i<64; i++){ + MERGE(dct_error_sum[0][i]); + MERGE(dct_error_sum[1][i]); + } + } + + assert(put_bits_count(&src->pb) % 8 ==0); + assert(put_bits_count(&dst->pb) % 8 ==0); + ff_copy_bits(&dst->pb, src->pb.buf, put_bits_count(&src->pb)); + flush_put_bits(&dst->pb); +} + +static int estimate_qp(MpegEncContext *s, int dry_run){ + if (s->next_lambda){ + s->current_picture_ptr->quality= + s->current_picture.quality = s->next_lambda; + if(!dry_run) s->next_lambda= 0; + } else if (!s->fixed_qscale) { + s->current_picture_ptr->quality= + s->current_picture.quality = ff_rate_estimate_qscale(s, dry_run); + if (s->current_picture.quality < 0) + return -1; + } + + if(s->adaptive_quant){ + switch(s->codec_id){ + case CODEC_ID_MPEG4: + if (ENABLE_MPEG4_ENCODER) + ff_clean_mpeg4_qscales(s); + break; + case CODEC_ID_H263: + case CODEC_ID_H263P: + case CODEC_ID_FLV1: + if (ENABLE_H263_ENCODER||ENABLE_H263P_ENCODER||ENABLE_FLV_ENCODER) + ff_clean_h263_qscales(s); + break; + } + + s->lambda= s->lambda_table[0]; + //FIXME broken + }else + s->lambda= s->current_picture.quality; +//printf("%d %d\n", s->avctx->global_quality, s->current_picture.quality); + update_qscale(s); + return 0; +} + +/* must be called before writing the header */ +static void set_frame_distances(MpegEncContext * s){ + assert(s->current_picture_ptr->pts != AV_NOPTS_VALUE); + s->time= s->current_picture_ptr->pts*s->avctx->time_base.num; + + if(s->pict_type==B_TYPE){ + s->pb_time= s->pp_time - (s->last_non_b_time - s->time); + assert(s->pb_time > 0 && s->pb_time < s->pp_time); + }else{ + s->pp_time= s->time - s->last_non_b_time; + s->last_non_b_time= s->time; + assert(s->picture_number==0 || s->pp_time > 0); + } +} + +static int encode_picture(MpegEncContext *s, int picture_number) +{ + int i; + int bits; + + s->picture_number = picture_number; + + /* Reset the average MB variance */ + s->me.mb_var_sum_temp = + s->me.mc_mb_var_sum_temp = 0; + + /* we need to initialize some time vars before we can encode b-frames */ + // RAL: Condition added for MPEG1VIDEO + if (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO || (s->h263_pred && !s->h263_msmpeg4)) + set_frame_distances(s); + if(ENABLE_MPEG4_ENCODER && s->codec_id == CODEC_ID_MPEG4) + ff_set_mpeg4_time(s); + + s->me.scene_change_score=0; + +// s->lambda= s->current_picture_ptr->quality; //FIXME qscale / ... stuff for ME ratedistoration + + if(s->pict_type==I_TYPE){ + if(s->msmpeg4_version >= 3) s->no_rounding=1; + else s->no_rounding=0; + }else if(s->pict_type!=B_TYPE){ + if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4) + s->no_rounding ^= 1; + } + + if(s->flags & CODEC_FLAG_PASS2){ + if (estimate_qp(s,1) < 0) + return -1; + ff_get_2pass_fcode(s); + }else if(!(s->flags & CODEC_FLAG_QSCALE)){ + if(s->pict_type==B_TYPE) + s->lambda= s->last_lambda_for[s->pict_type]; + else + s->lambda= s->last_lambda_for[s->last_non_b_pict_type]; + update_qscale(s); + } + + s->mb_intra=0; //for the rate distortion & bit compare functions + for(i=1; i<s->avctx->thread_count; i++){ + ff_update_duplicate_context(s->thread_context[i], s); + } + + ff_init_me(s); + + /* Estimate motion for every MB */ + if(s->pict_type != I_TYPE){ + s->lambda = (s->lambda * s->avctx->me_penalty_compensation + 128)>>8; + s->lambda2= (s->lambda2* (int64_t)s->avctx->me_penalty_compensation + 128)>>8; + if(s->pict_type != B_TYPE && s->avctx->me_threshold==0){ + if((s->avctx->pre_me && s->last_non_b_pict_type==I_TYPE) || s->avctx->pre_me==2){ + s->avctx->execute(s->avctx, pre_estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count); + } + } + + s->avctx->execute(s->avctx, estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count); + }else /* if(s->pict_type == I_TYPE) */{ + /* I-Frame */ + for(i=0; i<s->mb_stride*s->mb_height; i++) + s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA; + + if(!s->fixed_qscale){ + /* finding spatial complexity for I-frame rate control */ + s->avctx->execute(s->avctx, mb_var_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count); + } + } + for(i=1; i<s->avctx->thread_count; i++){ + merge_context_after_me(s, s->thread_context[i]); + } + s->current_picture.mc_mb_var_sum= s->current_picture_ptr->mc_mb_var_sum= s->me.mc_mb_var_sum_temp; + s->current_picture. mb_var_sum= s->current_picture_ptr-> mb_var_sum= s->me. mb_var_sum_temp; + emms_c(); + + if(s->me.scene_change_score > s->avctx->scenechange_threshold && s->pict_type == P_TYPE){ + s->pict_type= I_TYPE; + for(i=0; i<s->mb_stride*s->mb_height; i++) + s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA; +//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum); + } + + if(!s->umvplus){ + if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) { + s->f_code= ff_get_best_fcode(s, s->p_mv_table, CANDIDATE_MB_TYPE_INTER); + + if(s->flags & CODEC_FLAG_INTERLACED_ME){ + int a,b; + a= ff_get_best_fcode(s, s->p_field_mv_table[0][0], CANDIDATE_MB_TYPE_INTER_I); //FIXME field_select + b= ff_get_best_fcode(s, s->p_field_mv_table[1][1], CANDIDATE_MB_TYPE_INTER_I); + s->f_code= FFMAX(s->f_code, FFMAX(a,b)); + } + + ff_fix_long_p_mvs(s); + ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, 0); + if(s->flags & CODEC_FLAG_INTERLACED_ME){ + int j; + for(i=0; i<2; i++){ + for(j=0; j<2; j++) + ff_fix_long_mvs(s, s->p_field_select_table[i], j, + s->p_field_mv_table[i][j], s->f_code, CANDIDATE_MB_TYPE_INTER_I, 0); + } + } + } + + if(s->pict_type==B_TYPE){ + int a, b; + + a = ff_get_best_fcode(s, s->b_forw_mv_table, CANDIDATE_MB_TYPE_FORWARD); + b = ff_get_best_fcode(s, s->b_bidir_forw_mv_table, CANDIDATE_MB_TYPE_BIDIR); + s->f_code = FFMAX(a, b); + + a = ff_get_best_fcode(s, s->b_back_mv_table, CANDIDATE_MB_TYPE_BACKWARD); + b = ff_get_best_fcode(s, s->b_bidir_back_mv_table, CANDIDATE_MB_TYPE_BIDIR); + s->b_code = FFMAX(a, b); + + ff_fix_long_mvs(s, NULL, 0, s->b_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_FORWARD, 1); + ff_fix_long_mvs(s, NULL, 0, s->b_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BACKWARD, 1); + ff_fix_long_mvs(s, NULL, 0, s->b_bidir_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_BIDIR, 1); + ff_fix_long_mvs(s, NULL, 0, s->b_bidir_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BIDIR, 1); + if(s->flags & CODEC_FLAG_INTERLACED_ME){ + int dir, j; + for(dir=0; dir<2; dir++){ + for(i=0; i<2; i++){ + for(j=0; j<2; j++){ + int type= dir ? (CANDIDATE_MB_TYPE_BACKWARD_I|CANDIDATE_MB_TYPE_BIDIR_I) + : (CANDIDATE_MB_TYPE_FORWARD_I |CANDIDATE_MB_TYPE_BIDIR_I); + ff_fix_long_mvs(s, s->b_field_select_table[dir][i], j, + s->b_field_mv_table[dir][i][j], dir ? s->b_code : s->f_code, type, 1); + } + } + } + } + } + } + + if (estimate_qp(s, 0) < 0) + return -1; + + if(s->qscale < 3 && s->max_qcoeff<=128 && s->pict_type==I_TYPE && !(s->flags & CODEC_FLAG_QSCALE)) + s->qscale= 3; //reduce clipping problems + + if (s->out_format == FMT_MJPEG) { + /* for mjpeg, we do include qscale in the matrix */ + s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0]; + for(i=1;i<64;i++){ + int j= s->dsp.idct_permutation[i]; + + s->intra_matrix[j] = av_clip_uint8((ff_mpeg1_default_intra_matrix[i] * s->qscale) >> 3); + } + ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16, + s->intra_matrix, s->intra_quant_bias, 8, 8, 1); + s->qscale= 8; + } + + //FIXME var duplication + s->current_picture_ptr->key_frame= + s->current_picture.key_frame= s->pict_type == I_TYPE; //FIXME pic_ptr + s->current_picture_ptr->pict_type= + s->current_picture.pict_type= s->pict_type; + + if(s->current_picture.key_frame) + s->picture_in_gop_number=0; + + s->last_bits= put_bits_count(&s->pb); + switch(s->out_format) { + case FMT_MJPEG: + if (ENABLE_MJPEG_ENCODER) + ff_mjpeg_encode_picture_header(s); + break; + case FMT_H261: + if (ENABLE_H261_ENCODER) + ff_h261_encode_picture_header(s, picture_number); + break; + case FMT_H263: + if (ENABLE_WMV2_ENCODER && s->codec_id == CODEC_ID_WMV2) + ff_wmv2_encode_picture_header(s, picture_number); + else if (ENABLE_MSMPEG4_ENCODER && s->h263_msmpeg4) + msmpeg4_encode_picture_header(s, picture_number); + else if (ENABLE_MPEG4_ENCODER && s->h263_pred) + mpeg4_encode_picture_header(s, picture_number); + else if (ENABLE_RV10_ENCODER && s->codec_id == CODEC_ID_RV10) + rv10_encode_picture_header(s, picture_number); + else if (ENABLE_RV20_ENCODER && s->codec_id == CODEC_ID_RV20) + rv20_encode_picture_header(s, picture_number); + else if (ENABLE_FLV_ENCODER && s->codec_id == CODEC_ID_FLV1) + ff_flv_encode_picture_header(s, picture_number); + else if (ENABLE_ANY_H263_ENCODER) + h263_encode_picture_header(s, picture_number); + break; + case FMT_MPEG1: + if (ENABLE_MPEG1VIDEO_ENCODER || ENABLE_MPEG2VIDEO_ENCODER) + mpeg1_encode_picture_header(s, picture_number); + break; + case FMT_H264: + break; + default: + assert(0); + } + bits= put_bits_count(&s->pb); + s->header_bits= bits - s->last_bits; + + for(i=1; i<s->avctx->thread_count; i++){ + update_duplicate_context_after_me(s->thread_context[i], s); + } + s->avctx->execute(s->avctx, encode_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count); + for(i=1; i<s->avctx->thread_count; i++){ + merge_context_after_encode(s, s->thread_context[i]); + } + emms_c(); + return 0; +} + +void denoise_dct_c(MpegEncContext *s, DCTELEM *block){ + const int intra= s->mb_intra; + int i; + + s->dct_count[intra]++; + + for(i=0; i<64; i++){ + int level= block[i]; + + if(level){ + if(level>0){ + s->dct_error_sum[intra][i] += level; + level -= s->dct_offset[intra][i]; + if(level<0) level=0; + }else{ + s->dct_error_sum[intra][i] -= level; + level += s->dct_offset[intra][i]; + if(level>0) level=0; + } + block[i]= level; + } + } +} + +int dct_quantize_trellis_c(MpegEncContext *s, + DCTELEM *block, int n, + int qscale, int *overflow){ + const int *qmat; + const uint8_t *scantable= s->intra_scantable.scantable; + const uint8_t *perm_scantable= s->intra_scantable.permutated; + int max=0; + unsigned int threshold1, threshold2; + int bias=0; + int run_tab[65]; + int level_tab[65]; + int score_tab[65]; + int survivor[65]; + int survivor_count; + int last_run=0; + int last_level=0; + int last_score= 0; + int last_i; + int coeff[2][64]; + int coeff_count[64]; + int qmul, qadd, start_i, last_non_zero, i, dc; + const int esc_length= s->ac_esc_length; + uint8_t * length; + uint8_t * last_length; + const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6); + + s->dsp.fdct (block); + + if(s->dct_error_sum) + s->denoise_dct(s, block); + qmul= qscale*16; + qadd= ((qscale-1)|1)*8; + + if (s->mb_intra) { + int q; + if (!s->h263_aic) { + if (n < 4) + q = s->y_dc_scale; + else + q = s->c_dc_scale; + q = q << 3; + } else{ + /* For AIC we skip quant/dequant of INTRADC */ + q = 1 << 3; + qadd=0; + } + + /* note: block[0] is assumed to be positive */ + block[0] = (block[0] + (q >> 1)) / q; + start_i = 1; + last_non_zero = 0; + qmat = s->q_intra_matrix[qscale]; + if(s->mpeg_quant || s->out_format == FMT_MPEG1) + bias= 1<<(QMAT_SHIFT-1); + length = s->intra_ac_vlc_length; + last_length= s->intra_ac_vlc_last_length; + } else { + start_i = 0; + last_non_zero = -1; + qmat = s->q_inter_matrix[qscale]; + length = s->inter_ac_vlc_length; + last_length= s->inter_ac_vlc_last_length; + } + last_i= start_i; + + threshold1= (1<<QMAT_SHIFT) - bias - 1; + threshold2= (threshold1<<1); + + for(i=63; i>=start_i; i--) { + const int j = scantable[i]; + int level = block[j] * qmat[j]; + + if(((unsigned)(level+threshold1))>threshold2){ + last_non_zero = i; + break; + } + } + + for(i=start_i; i<=last_non_zero; i++) { + const int j = scantable[i]; + int level = block[j] * qmat[j]; + +// if( bias+level >= (1<<(QMAT_SHIFT - 3)) +// || bias-level >= (1<<(QMAT_SHIFT - 3))){ + if(((unsigned)(level+threshold1))>threshold2){ + if(level>0){ + level= (bias + level)>>QMAT_SHIFT; + coeff[0][i]= level; + coeff[1][i]= level-1; +// coeff[2][k]= level-2; + }else{ + level= (bias - level)>>QMAT_SHIFT; + coeff[0][i]= -level; + coeff[1][i]= -level+1; +// coeff[2][k]= -level+2; + } + coeff_count[i]= FFMIN(level, 2); + assert(coeff_count[i]); + max |=level; + }else{ + coeff[0][i]= (level>>31)|1; + coeff_count[i]= 1; + } + } + + *overflow= s->max_qcoeff < max; //overflow might have happened + + if(last_non_zero < start_i){ + memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM)); + return last_non_zero; + } + + score_tab[start_i]= 0; + survivor[0]= start_i; + survivor_count= 1; + + for(i=start_i; i<=last_non_zero; i++){ + int level_index, j, zero_distoration; + int dct_coeff= FFABS(block[ scantable[i] ]); + int best_score=256*256*256*120; + + if ( s->dsp.fdct == fdct_ifast +#ifndef FAAN_POSTSCALE + || s->dsp.fdct == ff_faandct +#endif + ) + dct_coeff= (dct_coeff*inv_aanscales[ scantable[i] ]) >> 12; + zero_distoration= dct_coeff*dct_coeff; + + for(level_index=0; level_index < coeff_count[i]; level_index++){ + int distoration; + int level= coeff[level_index][i]; + const int alevel= FFABS(level); + int unquant_coeff; + + assert(level); + + if(s->out_format == FMT_H263){ + unquant_coeff= alevel*qmul + qadd; + }else{ //MPEG1 + j= s->dsp.idct_permutation[ scantable[i] ]; //FIXME optimize + if(s->mb_intra){ + unquant_coeff = (int)( alevel * qscale * s->intra_matrix[j]) >> 3; + unquant_coeff = (unquant_coeff - 1) | 1; + }else{ + unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) s->inter_matrix[j])) >> 4; + unquant_coeff = (unquant_coeff - 1) | 1; + } + unquant_coeff<<= 3; + } + + distoration= (unquant_coeff - dct_coeff) * (unquant_coeff - dct_coeff) - zero_distoration; + level+=64; + if((level&(~127)) == 0){ + for(j=survivor_count-1; j>=0; j--){ + int run= i - survivor[j]; + int score= distoration + length[UNI_AC_ENC_INDEX(run, level)]*lambda; + score += score_tab[i-run]; + + if(score < best_score){ + best_score= score; + run_tab[i+1]= run; + level_tab[i+1]= level-64; + } + } + + if(s->out_format == FMT_H263){ + for(j=survivor_count-1; j>=0; j--){ + int run= i - survivor[j]; + int score= distoration + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda; + score += score_tab[i-run]; + if(score < last_score){ + last_score= score; + last_run= run; + last_level= level-64; + last_i= i+1; + } + } + } + }else{ + distoration += esc_length*lambda; + for(j=survivor_count-1; j>=0; j--){ + int run= i - survivor[j]; + int score= distoration + score_tab[i-run]; + + if(score < best_score){ + best_score= score; + run_tab[i+1]= run; + level_tab[i+1]= level-64; + } + } + + if(s->out_format == FMT_H263){ + for(j=survivor_count-1; j>=0; j--){ + int run= i - survivor[j]; + int score= distoration + score_tab[i-run]; + if(score < last_score){ + last_score= score; + last_run= run; + last_level= level-64; + last_i= i+1; + } + } + } + } + } + + score_tab[i+1]= best_score; + + //Note: there is a vlc code in mpeg4 which is 1 bit shorter then another one with a shorter run and the same level + if(last_non_zero <= 27){ + for(; survivor_count; survivor_count--){ + if(score_tab[ survivor[survivor_count-1] ] <= best_score) + break; + } + }else{ + for(; survivor_count; survivor_count--){ + if(score_tab[ survivor[survivor_count-1] ] <= best_score + lambda) + break; + } + } + + survivor[ survivor_count++ ]= i+1; + } + + if(s->out_format != FMT_H263){ + last_score= 256*256*256*120; + for(i= survivor[0]; i<=last_non_zero + 1; i++){ + int score= score_tab[i]; + if(i) score += lambda*2; //FIXME exacter? + + if(score < last_score){ + last_score= score; + last_i= i; + last_level= level_tab[i]; + last_run= run_tab[i]; + } + } + } + + s->coded_score[n] = last_score; + + dc= FFABS(block[0]); + last_non_zero= last_i - 1; + memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM)); + + if(last_non_zero < start_i) + return last_non_zero; + + if(last_non_zero == 0 && start_i == 0){ + int best_level= 0; + int best_score= dc * dc; + + for(i=0; i<coeff_count[0]; i++){ + int level= coeff[i][0]; + int alevel= FFABS(level); + int unquant_coeff, score, distortion; + + if(s->out_format == FMT_H263){ + unquant_coeff= (alevel*qmul + qadd)>>3; + }else{ //MPEG1 + unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) s->inter_matrix[0])) >> 4; + unquant_coeff = (unquant_coeff - 1) | 1; + } + unquant_coeff = (unquant_coeff + 4) >> 3; + unquant_coeff<<= 3 + 3; + + distortion= (unquant_coeff - dc) * (unquant_coeff - dc); + level+=64; + if((level&(~127)) == 0) score= distortion + last_length[UNI_AC_ENC_INDEX(0, level)]*lambda; + else score= distortion + esc_length*lambda; + + if(score < best_score){ + best_score= score; + best_level= level - 64; + } + } + block[0]= best_level; + s->coded_score[n] = best_score - dc*dc; + if(best_level == 0) return -1; + else return last_non_zero; + } + + i= last_i; + assert(last_level); + + block[ perm_scantable[last_non_zero] ]= last_level; + i -= last_run + 1; + + for(; i>start_i; i -= run_tab[i] + 1){ + block[ perm_scantable[i-1] ]= level_tab[i]; + } + + return last_non_zero; +} + +//#define REFINE_STATS 1 +static int16_t basis[64][64]; + +static void build_basis(uint8_t *perm){ + int i, j, x, y; + emms_c(); + for(i=0; i<8; i++){ + for(j=0; j<8; j++){ + for(y=0; y<8; y++){ + for(x=0; x<8; x++){ + double s= 0.25*(1<<BASIS_SHIFT); + int index= 8*i + j; + int perm_index= perm[index]; + if(i==0) s*= sqrt(0.5); + if(j==0) s*= sqrt(0.5); + basis[perm_index][8*x + y]= lrintf(s * cos((M_PI/8.0)*i*(x+0.5)) * cos((M_PI/8.0)*j*(y+0.5))); + } + } + } + } +} + +static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise? + DCTELEM *block, int16_t *weight, DCTELEM *orig, + int n, int qscale){ + int16_t rem[64]; + DECLARE_ALIGNED_16(DCTELEM, d1[64]); + const int *qmat; + const uint8_t *scantable= s->intra_scantable.scantable; + const uint8_t *perm_scantable= s->intra_scantable.permutated; +// unsigned int threshold1, threshold2; +// int bias=0; + int run_tab[65]; + int prev_run=0; + int prev_level=0; + int qmul, qadd, start_i, last_non_zero, i, dc; + uint8_t * length; + uint8_t * last_length; + int lambda; + int rle_index, run, q = 1, sum; //q is only used when s->mb_intra is true +#ifdef REFINE_STATS +static int count=0; +static int after_last=0; +static int to_zero=0; +static int from_zero=0; +static int raise=0; +static int lower=0; +static int messed_sign=0; +#endif + + if(basis[0][0] == 0) + build_basis(s->dsp.idct_permutation); + + qmul= qscale*2; + qadd= (qscale-1)|1; + if (s->mb_intra) { + if (!s->h263_aic) { + if (n < 4) + q = s->y_dc_scale; + else + q = s->c_dc_scale; + } else{ + /* For AIC we skip quant/dequant of INTRADC */ + q = 1; + qadd=0; + } + q <<= RECON_SHIFT-3; + /* note: block[0] is assumed to be positive */ + dc= block[0]*q; +// block[0] = (block[0] + (q >> 1)) / q; + start_i = 1; + qmat = s->q_intra_matrix[qscale]; +// if(s->mpeg_quant || s->out_format == FMT_MPEG1) +// bias= 1<<(QMAT_SHIFT-1); + length = s->intra_ac_vlc_length; + last_length= s->intra_ac_vlc_last_length; + } else { + dc= 0; + start_i = 0; + qmat = s->q_inter_matrix[qscale]; + length = s->inter_ac_vlc_length; + last_length= s->inter_ac_vlc_last_length; + } + last_non_zero = s->block_last_index[n]; + +#ifdef REFINE_STATS +{START_TIMER +#endif + dc += (1<<(RECON_SHIFT-1)); + for(i=0; i<64; i++){ + rem[i]= dc - (orig[i]<<RECON_SHIFT); //FIXME use orig dirrectly instead of copying to rem[] + } +#ifdef REFINE_STATS +STOP_TIMER("memset rem[]")} +#endif + sum=0; + for(i=0; i<64; i++){ + int one= 36; + int qns=4; + int w; + + w= FFABS(weight[i]) + qns*one; + w= 15 + (48*qns*one + w/2)/w; // 16 .. 63 + + weight[i] = w; +// w=weight[i] = (63*qns + (w/2)) / w; + + assert(w>0); + assert(w<(1<<6)); + sum += w*w; + } + lambda= sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6); +#ifdef REFINE_STATS +{START_TIMER +#endif + run=0; + rle_index=0; + for(i=start_i; i<=last_non_zero; i++){ + int j= perm_scantable[i]; + const int level= block[j]; + int coeff; + + if(level){ + if(level<0) coeff= qmul*level - qadd; + else coeff= qmul*level + qadd; + run_tab[rle_index++]=run; + run=0; + + s->dsp.add_8x8basis(rem, basis[j], coeff); + }else{ + run++; + } + } +#ifdef REFINE_STATS +if(last_non_zero>0){ +STOP_TIMER("init rem[]") +} +} + +{START_TIMER +#endif + for(;;){ + int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0); + int best_coeff=0; + int best_change=0; + int run2, best_unquant_change=0, analyze_gradient; +#ifdef REFINE_STATS +{START_TIMER +#endif + analyze_gradient = last_non_zero > 2 || s->avctx->quantizer_noise_shaping >= 3; + + if(analyze_gradient){ +#ifdef REFINE_STATS +{START_TIMER +#endif + for(i=0; i<64; i++){ + int w= weight[i]; + + d1[i] = (rem[i]*w*w + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12); + } +#ifdef REFINE_STATS +STOP_TIMER("rem*w*w")} +{START_TIMER +#endif + s->dsp.fdct(d1); +#ifdef REFINE_STATS +STOP_TIMER("dct")} +#endif + } + + if(start_i){ + const int level= block[0]; + int change, old_coeff; + + assert(s->mb_intra); + + old_coeff= q*level; + + for(change=-1; change<=1; change+=2){ + int new_level= level + change; + int score, new_coeff; + + new_coeff= q*new_level; + if(new_coeff >= 2048 || new_coeff < 0) + continue; + + score= s->dsp.try_8x8basis(rem, weight, basis[0], new_coeff - old_coeff); + if(score<best_score){ + best_score= score; + best_coeff= 0; + best_change= change; + best_unquant_change= new_coeff - old_coeff; + } + } + } + + run=0; + rle_index=0; + run2= run_tab[rle_index++]; + prev_level=0; + prev_run=0; + + for(i=start_i; i<64; i++){ + int j= perm_scantable[i]; + const int level= block[j]; + int change, old_coeff; + + if(s->avctx->quantizer_noise_shaping < 3 && i > last_non_zero + 1) + break; + + if(level){ + if(level<0) old_coeff= qmul*level - qadd; + else old_coeff= qmul*level + qadd; + run2= run_tab[rle_index++]; //FIXME ! maybe after last + }else{ + old_coeff=0; + run2--; + assert(run2>=0 || i >= last_non_zero ); + } + + for(change=-1; change<=1; change+=2){ + int new_level= level + change; + int score, new_coeff, unquant_change; + + score=0; + if(s->avctx->quantizer_noise_shaping < 2 && FFABS(new_level) > FFABS(level)) + continue; + + if(new_level){ + if(new_level<0) new_coeff= qmul*new_level - qadd; + else new_coeff= qmul*new_level + qadd; + if(new_coeff >= 2048 || new_coeff <= -2048) + continue; + //FIXME check for overflow + + if(level){ + if(level < 63 && level > -63){ + if(i < last_non_zero) + score += length[UNI_AC_ENC_INDEX(run, new_level+64)] + - length[UNI_AC_ENC_INDEX(run, level+64)]; + else + score += last_length[UNI_AC_ENC_INDEX(run, new_level+64)] + - last_length[UNI_AC_ENC_INDEX(run, level+64)]; + } + }else{ + assert(FFABS(new_level)==1); + + if(analyze_gradient){ + int g= d1[ scantable[i] ]; + if(g && (g^new_level) >= 0) + continue; + } + + if(i < last_non_zero){ + int next_i= i + run2 + 1; + int next_level= block[ perm_scantable[next_i] ] + 64; + + if(next_level&(~127)) + next_level= 0; + + if(next_i < last_non_zero) + score += length[UNI_AC_ENC_INDEX(run, 65)] + + length[UNI_AC_ENC_INDEX(run2, next_level)] + - length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]; + else + score += length[UNI_AC_ENC_INDEX(run, 65)] + + last_length[UNI_AC_ENC_INDEX(run2, next_level)] + - last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]; + }else{ + score += last_length[UNI_AC_ENC_INDEX(run, 65)]; + if(prev_level){ + score += length[UNI_AC_ENC_INDEX(prev_run, prev_level)] + - last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)]; + } + } + } + }else{ + new_coeff=0; + assert(FFABS(level)==1); + + if(i < last_non_zero){ + int next_i= i + run2 + 1; + int next_level= block[ perm_scantable[next_i] ] + 64; + + if(next_level&(~127)) + next_level= 0; + + if(next_i < last_non_zero) + score += length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)] + - length[UNI_AC_ENC_INDEX(run2, next_level)] + - length[UNI_AC_ENC_INDEX(run, 65)]; + else + score += last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)] + - last_length[UNI_AC_ENC_INDEX(run2, next_level)] + - length[UNI_AC_ENC_INDEX(run, 65)]; + }else{ + score += -last_length[UNI_AC_ENC_INDEX(run, 65)]; + if(prev_level){ + score += last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)] + - length[UNI_AC_ENC_INDEX(prev_run, prev_level)]; + } + } + } + + score *= lambda; + + unquant_change= new_coeff - old_coeff; + assert((score < 100*lambda && score > -100*lambda) || lambda==0); + + score+= s->dsp.try_8x8basis(rem, weight, basis[j], unquant_change); + if(score<best_score){ + best_score= score; + best_coeff= i; + best_change= change; + best_unquant_change= unquant_change; + } + } + if(level){ + prev_level= level + 64; + if(prev_level&(~127)) + prev_level= 0; + prev_run= run; + run=0; + }else{ + run++; + } + } +#ifdef REFINE_STATS +STOP_TIMER("iterative step")} +#endif + + if(best_change){ + int j= perm_scantable[ best_coeff ]; + + block[j] += best_change; + + if(best_coeff > last_non_zero){ + last_non_zero= best_coeff; + assert(block[j]); +#ifdef REFINE_STATS +after_last++; +#endif + }else{ +#ifdef REFINE_STATS +if(block[j]){ + if(block[j] - best_change){ + if(FFABS(block[j]) > FFABS(block[j] - best_change)){ + raise++; + }else{ + lower++; + } + }else{ + from_zero++; + } +}else{ + to_zero++; +} +#endif + for(; last_non_zero>=start_i; last_non_zero--){ + if(block[perm_scantable[last_non_zero]]) + break; + } + } +#ifdef REFINE_STATS +count++; +if(256*256*256*64 % count == 0){ + printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\n", after_last, to_zero, from_zero, raise, lower, messed_sign, s->mb_x, s->mb_y, s->picture_number); +} +#endif + run=0; + rle_index=0; + for(i=start_i; i<=last_non_zero; i++){ + int j= perm_scantable[i]; + const int level= block[j]; + + if(level){ + run_tab[rle_index++]=run; + run=0; + }else{ + run++; + } + } + + s->dsp.add_8x8basis(rem, basis[j], best_unquant_change); + }else{ + break; + } + } +#ifdef REFINE_STATS +if(last_non_zero>0){ +STOP_TIMER("iterative search") +} +} +#endif + + return last_non_zero; +} + +int dct_quantize_c(MpegEncContext *s, + DCTELEM *block, int n, + int qscale, int *overflow) +{ + int i, j, level, last_non_zero, q, start_i; + const int *qmat; + const uint8_t *scantable= s->intra_scantable.scantable; + int bias; + int max=0; + unsigned int threshold1, threshold2; + + s->dsp.fdct (block); + + if(s->dct_error_sum) + s->denoise_dct(s, block); + + if (s->mb_intra) { + if (!s->h263_aic) { + if (n < 4) + q = s->y_dc_scale; + else + q = s->c_dc_scale; + q = q << 3; + } else + /* For AIC we skip quant/dequant of INTRADC */ + q = 1 << 3; + + /* note: block[0] is assumed to be positive */ + block[0] = (block[0] + (q >> 1)) / q; + start_i = 1; + last_non_zero = 0; + qmat = s->q_intra_matrix[qscale]; + bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT); + } else { + start_i = 0; + last_non_zero = -1; + qmat = s->q_inter_matrix[qscale]; + bias= s->inter_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT); + } + threshold1= (1<<QMAT_SHIFT) - bias - 1; + threshold2= (threshold1<<1); + for(i=63;i>=start_i;i--) { + j = scantable[i]; + level = block[j] * qmat[j]; + + if(((unsigned)(level+threshold1))>threshold2){ + last_non_zero = i; + break; + }else{ + block[j]=0; + } + } + for(i=start_i; i<=last_non_zero; i++) { + j = scantable[i]; + level = block[j] * qmat[j]; + +// if( bias+level >= (1<<QMAT_SHIFT) +// || bias-level >= (1<<QMAT_SHIFT)){ + if(((unsigned)(level+threshold1))>threshold2){ + if(level>0){ + level= (bias + level)>>QMAT_SHIFT; + block[j]= level; + }else{ + level= (bias - level)>>QMAT_SHIFT; + block[j]= -level; + } + max |=level; + }else{ + block[j]=0; + } + } + *overflow= s->max_qcoeff < max; //overflow might have happened + + /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */ + if (s->dsp.idct_permutation_type != FF_NO_IDCT_PERM) + ff_block_permute(block, s->dsp.idct_permutation, scantable, last_non_zero); + + return last_non_zero; +} + +AVCodec h263_encoder = { + "h263", + CODEC_TYPE_VIDEO, + CODEC_ID_H263, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; + +AVCodec h263p_encoder = { + "h263p", + CODEC_TYPE_VIDEO, + CODEC_ID_H263P, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; + +AVCodec flv_encoder = { + "flv", + CODEC_TYPE_VIDEO, + CODEC_ID_FLV1, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; + +AVCodec rv10_encoder = { + "rv10", + CODEC_TYPE_VIDEO, + CODEC_ID_RV10, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; + +AVCodec rv20_encoder = { + "rv20", + CODEC_TYPE_VIDEO, + CODEC_ID_RV20, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; + +AVCodec mpeg4_encoder = { + "mpeg4", + CODEC_TYPE_VIDEO, + CODEC_ID_MPEG4, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, + .capabilities= CODEC_CAP_DELAY, +}; + +AVCodec msmpeg4v1_encoder = { + "msmpeg4v1", + CODEC_TYPE_VIDEO, + CODEC_ID_MSMPEG4V1, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; + +AVCodec msmpeg4v2_encoder = { + "msmpeg4v2", + CODEC_TYPE_VIDEO, + CODEC_ID_MSMPEG4V2, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; + +AVCodec msmpeg4v3_encoder = { + "msmpeg4", + CODEC_TYPE_VIDEO, + CODEC_ID_MSMPEG4V3, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; + +AVCodec wmv1_encoder = { + "wmv1", + CODEC_TYPE_VIDEO, + CODEC_ID_WMV1, + sizeof(MpegEncContext), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/mpegvideo_parser.c b/contrib/ffmpeg/libavcodec/mpegvideo_parser.c new file mode 100644 index 000000000..a7ce09d4c --- /dev/null +++ b/contrib/ffmpeg/libavcodec/mpegvideo_parser.c @@ -0,0 +1,180 @@ +/* + * MPEG1 / MPEG2 video parser + * Copyright (c) 2000,2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 "parser.h" +#include "mpegvideo.h" + +static void mpegvideo_extract_headers(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + ParseContext1 *pc = s->priv_data; + const uint8_t *buf_end; + uint32_t start_code; + int frame_rate_index, ext_type, bytes_left; + int frame_rate_ext_n, frame_rate_ext_d; + int picture_structure, top_field_first, repeat_first_field, progressive_frame; + int horiz_size_ext, vert_size_ext, bit_rate_ext; +//FIXME replace the crap with get_bits() + s->repeat_pict = 0; + buf_end = buf + buf_size; + while (buf < buf_end) { + start_code= -1; + buf= ff_find_start_code(buf, buf_end, &start_code); + bytes_left = buf_end - buf; + switch(start_code) { + case PICTURE_START_CODE: + if (bytes_left >= 2) { + s->pict_type = (buf[1] >> 3) & 7; + } + break; + case SEQ_START_CODE: + if (bytes_left >= 7) { + pc->width = (buf[0] << 4) | (buf[1] >> 4); + pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; + avcodec_set_dimensions(avctx, pc->width, pc->height); + frame_rate_index = buf[3] & 0xf; + pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num; + pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den; + avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400; + avctx->codec_id = CODEC_ID_MPEG1VIDEO; + avctx->sub_id = 1; + } + break; + case EXT_START_CODE: + if (bytes_left >= 1) { + ext_type = (buf[0] >> 4); + switch(ext_type) { + case 0x1: /* sequence extension */ + if (bytes_left >= 6) { + horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); + vert_size_ext = (buf[2] >> 5) & 3; + bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1); + frame_rate_ext_n = (buf[5] >> 5) & 3; + frame_rate_ext_d = (buf[5] & 0x1f); + pc->progressive_sequence = buf[1] & (1 << 3); + avctx->has_b_frames= !(buf[5] >> 7); + + pc->width |=(horiz_size_ext << 12); + pc->height |=( vert_size_ext << 12); + avctx->bit_rate += (bit_rate_ext << 18) * 400; + avcodec_set_dimensions(avctx, pc->width, pc->height); + avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1); + avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1); + avctx->codec_id = CODEC_ID_MPEG2VIDEO; + avctx->sub_id = 2; /* forces MPEG2 */ + } + break; + case 0x8: /* picture coding extension */ + if (bytes_left >= 5) { + picture_structure = buf[2]&3; + top_field_first = buf[3] & (1 << 7); + repeat_first_field = buf[3] & (1 << 1); + progressive_frame = buf[4] & (1 << 7); + + /* check if we must repeat the frame */ + if (repeat_first_field) { + if (pc->progressive_sequence) { + if (top_field_first) + s->repeat_pict = 4; + else + s->repeat_pict = 2; + } else if (progressive_frame) { + s->repeat_pict = 1; + } + } + } + break; + } + } + break; + case -1: + goto the_end; + default: + /* we stop parsing when we encounter a slice. It ensures + that this function takes a negligible amount of time */ + if (start_code >= SLICE_MIN_START_CODE && + start_code <= SLICE_MAX_START_CODE) + goto the_end; + break; + } + } + the_end: ; +} + +static int mpegvideo_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext1 *pc1 = s->priv_data; + ParseContext *pc= &pc1->pc; + int next; + + if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ + next= buf_size; + }else{ + next= ff_mpeg1_find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + } + /* we have a full frame : we just parse the first few MPEG headers + to have the full timing information. The time take by this + function should be negligible for uncorrupted streams */ + mpegvideo_extract_headers(s, avctx, buf, buf_size); +#if 0 + printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", + s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict); +#endif + + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +static int mpegvideo_split(AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + int i; + uint32_t state= -1; + + for(i=0; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100) + return i-3; + } + return 0; +} + +AVCodecParser mpegvideo_parser = { + { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, + sizeof(ParseContext1), + NULL, + mpegvideo_parse, + ff_parse1_close, + mpegvideo_split, +}; diff --git a/contrib/ffmpeg/libavcodec/msmpeg4.c b/contrib/ffmpeg/libavcodec/msmpeg4.c index 62076d140..0ffcc6040 100644 --- a/contrib/ffmpeg/libavcodec/msmpeg4.c +++ b/contrib/ffmpeg/libavcodec/msmpeg4.c @@ -3,6 +3,8 @@ * Copyright (c) 2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * + * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,8 +20,6 @@ * 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 - * - * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> */ /** @@ -30,6 +30,7 @@ #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" +#include "msmpeg4.h" /* * You can also call this codec : MPEG4 with a twist ! @@ -42,7 +43,6 @@ #define DC_VLC_BITS 9 #define CBPY_VLC_BITS 6 -#define INTER_INTRA_VLC_BITS 3 #define V1_INTRA_CBPC_VLC_BITS 6 #define V1_INTER_CBPC_VLC_BITS 6 #define V2_INTRA_CBPC_VLC_BITS 3 @@ -50,8 +50,6 @@ #define MV_VLC_BITS 9 #define V2_MV_VLC_BITS 9 #define TEX_VLC_BITS 9 -#define MB_NON_INTRA_VLC_BITS 9 -#define MB_INTRA_VLC_BITS 9 #define II_BITRATE 128*1024 #define MBAC_BITRATE 50*1024 @@ -61,12 +59,7 @@ static uint32_t v2_dc_lum_table[512][2]; static uint32_t v2_dc_chroma_table[512][2]; -static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n); -static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded, const uint8_t *scantable); static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); -static int msmpeg4_decode_motion(MpegEncContext * s, - int *mx_ptr, int *my_ptr); static void init_h263_dc_for_msmpeg4(void); static inline void msmpeg4_memsetw(short *tab, int val, int n); #ifdef CONFIG_ENCODERS @@ -75,10 +68,9 @@ static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, #endif //CONFIG_ENCODERS static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); -static int wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); /* vc1 externs */ -extern uint8_t wmv3_dc_scale_table[32]; +extern const uint8_t wmv3_dc_scale_table[32]; #ifdef DEBUG int intra_count = 0; @@ -87,7 +79,7 @@ int frame_count = 0; #include "msmpeg4data.h" -#ifdef CONFIG_ENCODERS //strangely gcc includes this even if its not references +#ifdef CONFIG_ENCODERS //strangely gcc includes this even if it is not references static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2]; #endif //CONFIG_ENCODERS @@ -95,7 +87,7 @@ static uint8_t static_rl_table_store[NB_RL_TABLES][2][2*MAX_RUN + MAX_LEVEL + 3] static void common_init(MpegEncContext * s) { - static int inited=0; + static int initialized=0; switch(s->msmpeg4_version){ case 1: @@ -135,8 +127,8 @@ static void common_init(MpegEncContext * s) } //Note the default tables are set in common_init in mpegvideo.c - if(!inited){ - inited=1; + if(!initialized){ + initialized=1; init_h263_dc_for_msmpeg4(); } @@ -161,7 +153,7 @@ static void init_mv_table(MVTable *tab) } } -static void code012(PutBitContext *pb, int n) +void ff_msmpeg4_code012(PutBitContext *pb, int n) { if (n == 0) { put_bits(pb, 1, 0); @@ -246,7 +238,7 @@ static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, return size; } -static void find_best_tables(MpegEncContext * s) +void ff_find_best_tables(MpegEncContext * s) { int i; int best =-1, best_size =9999999; @@ -316,7 +308,7 @@ static void find_best_tables(MpegEncContext * s) /* write MSMPEG4 compatible frame header */ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) { - find_best_tables(s); + ff_find_best_tables(s); align_put_bits(&s->pb); put_bits(&s->pb, 2, s->pict_type - 1); @@ -347,8 +339,8 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) if(s->msmpeg4_version>2){ if(!s->per_mb_rl_table){ - code012(&s->pb, s->rl_chroma_table_index); - code012(&s->pb, s->rl_table_index); + ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index); + ff_msmpeg4_code012(&s->pb, s->rl_table_index); } put_bits(&s->pb, 1, s->dc_table_index); @@ -361,7 +353,7 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) if(s->msmpeg4_version>2){ if(!s->per_mb_rl_table) - code012(&s->pb, s->rl_table_index); + ff_msmpeg4_code012(&s->pb, s->rl_table_index); put_bits(&s->pb, 1, s->dc_table_index); @@ -393,7 +385,7 @@ void msmpeg4_encode_ext_header(MpegEncContext * s) #endif //CONFIG_ENCODERS /* predict coded block */ -static inline int coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr) +int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr) { int xy, wrap, pred, a, b, c; @@ -421,7 +413,7 @@ static inline int coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_bl #ifdef CONFIG_ENCODERS -static void msmpeg4_encode_motion(MpegEncContext * s, +void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my) { int code; @@ -453,13 +445,13 @@ static void msmpeg4_encode_motion(MpegEncContext * s, mv->table_mv_bits[code], mv->table_mv_code[code]); if (code == mv->n) { - /* escape : code litterally */ + /* escape : code literally */ put_bits(&s->pb, 6, mx); put_bits(&s->pb, 6, my); } } -static inline void handle_slices(MpegEncContext *s){ +void ff_msmpeg4_handle_slices(MpegEncContext *s){ if (s->mb_x == 0) { if (s->slice_height && (s->mb_y % s->slice_height) == 0) { if(s->msmpeg4_version < 4){ @@ -480,7 +472,7 @@ void msmpeg4_encode_mb(MpegEncContext * s, int pred_x, pred_y; uint8_t *coded_block; - handle_slices(s); + ff_msmpeg4_handle_slices(s); if (!s->mb_intra) { /* compute cbp */ @@ -526,14 +518,14 @@ void msmpeg4_encode_mb(MpegEncContext * s, /* motion vector */ h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - msmpeg4_encode_motion(s, motion_x - pred_x, + ff_msmpeg4_encode_motion(s, motion_x - pred_x, motion_y - pred_y); } s->mv_bits += get_bits_diff(s); for (i = 0; i < 6; i++) { - msmpeg4_encode_block(s, block[i], i); + ff_msmpeg4_encode_block(s, block[i], i); } s->p_tex_bits += get_bits_diff(s); } else { @@ -546,7 +538,7 @@ void msmpeg4_encode_mb(MpegEncContext * s, cbp |= val << (5 - i); if (i < 4) { /* predict value for close blocks only for luma */ - pred = coded_block_pred(s, i, &coded_block); + pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); *coded_block = val; val = val ^ pred; } @@ -592,7 +584,7 @@ void msmpeg4_encode_mb(MpegEncContext * s, s->misc_bits += get_bits_diff(s); for (i = 0; i < 6; i++) { - msmpeg4_encode_block(s, block[i], i); + ff_msmpeg4_encode_block(s, block[i], i); } s->i_tex_bits += get_bits_diff(s); s->i_count++; @@ -782,7 +774,8 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr) { int sign, code; - int pred; + int pred, extquant; + int extrabits = 0; if(s->msmpeg4_version==1){ int32_t *dc_val; @@ -824,6 +817,15 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr code = level; if (code > DC_MAX) code = DC_MAX; + else if( s->msmpeg4_version>=6 ) { + if( s->qscale == 1 ) { + extquant = (level + 3) & 0x3; + code = ((level+3)>>2); + } else if( s->qscale == 2 ) { + extquant = (level + 1) & 0x1; + code = ((level+1)>>1); + } + } if (s->dc_table_index == 0) { if (n < 4) { @@ -839,8 +841,13 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr } } + if(s->msmpeg4_version>=6 && s->qscale<=2) + extrabits = 3 - s->qscale; + if (code == DC_MAX) - put_bits(&s->pb, 8, level); + put_bits(&s->pb, 8 + extrabits, level); + else if(extrabits > 0)//== VC1 && s->qscale<=2 + put_bits(&s->pb, extrabits, extquant); if (level != 0) { put_bits(&s->pb, 1, sign); @@ -851,7 +858,7 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr /* Encoding of a block. Very similar to MPEG4 except for a different escape coding (same as H263) and more vlc tables. */ -static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) +void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) { int level, run, last, i, j, last_index; int last_non_zero, sign, slevel; @@ -867,7 +874,7 @@ static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int } else { rl = &rl_table[3 + s->rl_chroma_table_index]; } - run_diff = 0; + run_diff = s->msmpeg4_version>=4; scantable= s->intra_scantable.permutated; } else { i = 0; @@ -880,7 +887,7 @@ static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int } /* recalculate block_last_index for M$ wmv1 */ - if(s->msmpeg4_version>=4 && s->block_last_index[n]>0){ + if(s->msmpeg4_version>=4 && s->msmpeg4_version<6 && s->block_last_index[n]>0){ for(last_index=63; last_index>=0; last_index--){ if(block[scantable[last_index]]) break; } @@ -926,6 +933,9 @@ else run1 = run - rl->max_run[last][level] - run_diff; if (run1 < 0) goto esc3; + code = get_rl_index(rl, last, run1+1, level); + if (s->msmpeg4_version == 4 && code == rl->n) + goto esc3; code = get_rl_index(rl, last, run1, level); if (code == rl->n) { esc3: @@ -936,8 +946,9 @@ else if(s->esc3_level_length==0){ s->esc3_level_length=8; s->esc3_run_length= 6; + //ESCLVLSZ + ESCRUNSZ if(s->qscale<8) - put_bits(&s->pb, 6, 3); + put_bits(&s->pb, 6 + (s->msmpeg4_version>=6), 3); else put_bits(&s->pb, 8, 3); } @@ -971,10 +982,7 @@ else /****************************************/ /* decoding stuff */ -static VLC mb_non_intra_vlc[4]; -VLC ff_msmp4_mb_i_vlc; -VLC ff_msmp4_dc_luma_vlc[2]; -VLC ff_msmp4_dc_chroma_vlc[2]; +VLC ff_mb_non_intra_vlc[4]; static VLC v2_dc_lum_vlc; static VLC v2_dc_chroma_vlc; static VLC cbpy_vlc; @@ -983,9 +991,10 @@ static VLC v2_mb_type_vlc; static VLC v2_mv_vlc; static VLC v1_intra_cbpc_vlc; static VLC v1_inter_cbpc_vlc; -static VLC inter_intra_vlc; +VLC ff_inter_intra_vlc; -/* this table is practically identical to the one from h263 except that its inverted */ +/* This table is practically identical to the one from h263 + * except that it is inverted. */ static void init_h263_dc_for_msmpeg4(void) { int level, uni_code, uni_len; @@ -1008,7 +1017,7 @@ static void init_h263_dc_for_msmpeg4(void) /* luminance h263 */ uni_code= DCtab_lum[size][0]; uni_len = DCtab_lum[size][1]; - uni_code ^= (1<<uni_len)-1; //M$ doesnt like compatibility + uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility if (size > 0) { uni_code<<=size; uni_code|=l; @@ -1024,7 +1033,7 @@ static void init_h263_dc_for_msmpeg4(void) /* chrominance h263 */ uni_code= DCtab_chrom[size][0]; uni_len = DCtab_chrom[size][1]; - uni_code ^= (1<<uni_len)-1; //M$ doesnt like compatibility + uni_code ^= (1<<uni_len)-1; //M$ does not like compatibility if (size > 0) { uni_code<<=size; uni_code|=l; @@ -1097,7 +1106,7 @@ int ff_msmpeg4_decode_init(MpegEncContext *s) &mvtab[0][0], 2, 1, 1); for(i=0; i<4; i++){ - init_vlc(&mb_non_intra_vlc[i], MB_NON_INTRA_VLC_BITS, 128, + init_vlc(&ff_mb_non_intra_vlc[i], MB_NON_INTRA_VLC_BITS, 128, &wmv2_inter_table[i][0][1], 8, 4, &wmv2_inter_table[i][0][0], 8, 4, 1); //FIXME name? } @@ -1113,7 +1122,7 @@ int ff_msmpeg4_decode_init(MpegEncContext *s) inter_MCBPC_bits, 1, 1, inter_MCBPC_code, 1, 1, 1); - init_vlc(&inter_intra_vlc, INTER_INTRA_VLC_BITS, 4, + init_vlc(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4, &table_inter_intra[0][1], 2, 1, &table_inter_intra[0][0], 2, 1, 1); } @@ -1128,13 +1137,14 @@ int ff_msmpeg4_decode_init(MpegEncContext *s) s->decode_mb= msmpeg4v34_decode_mb; break; case 5: - s->decode_mb= wmv2_decode_mb; + if (ENABLE_WMV2_DECODER) + s->decode_mb= ff_wmv2_decode_mb; case 6: //FIXME + TODO VC1 decode mb break; } - s->slice_height= s->mb_height; //to avoid 1/0 if the first frame isnt a keyframe + s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe return 0; } @@ -1382,7 +1392,7 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val) } #endif -/* this is identical to h263 except that its range is multiplied by 2 */ +/* This is identical to h263 except that its range is multiplied by 2. */ static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code) { int code, val, sign, shift; @@ -1491,7 +1501,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) s->dsp.clear_blocks(s->block[0]); for (i = 0; i < 6; i++) { - if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) + if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) { av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); return -1; @@ -1524,7 +1534,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) } } - code = get_vlc2(&s->gb, mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3); + code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3); if (code < 0) return -1; //s->mb_intra = (code & 0x40) ? 0 : 1; @@ -1541,7 +1551,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) for(i=0;i<6;i++) { int val = ((code >> (5 - i)) & 1); if (i < 4) { - int pred = coded_block_pred(s, i, &coded_val); + int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val); val = val ^ pred; *coded_val = val; } @@ -1557,7 +1567,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) s->rl_chroma_table_index = s->rl_table_index; } h263_pred_motion(s, 0, 0, &mx, &my); - if (msmpeg4_decode_motion(s, &mx, &my) < 0) + if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0) return -1; s->mv_dir = MV_DIR_FORWARD; s->mv_type = MV_TYPE_16X16; @@ -1569,7 +1579,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) s->ac_pred = get_bits1(&s->gb); *mb_type_ptr = MB_TYPE_INTRA; if(s->inter_intra_pred){ - s->h263_aic_dir= get_vlc2(&s->gb, inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); + s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); // printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); } if(s->per_mb_rl_table && cbp){ @@ -1580,7 +1590,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) s->dsp.clear_blocks(s->block[0]); for (i = 0; i < 6; i++) { - if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) + if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) { av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); return -1; @@ -1590,7 +1600,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) return 0; } //#define ERROR_DETAILS -static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, +int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded, const uint8_t *scan_table) { int level, i, last, run, run_diff; @@ -1626,7 +1636,7 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, } block[0] = level; - run_diff = 0; + run_diff = s->msmpeg4_version >= 4; i = 0; if (!coded) { goto not_coded; @@ -1894,7 +1904,7 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) return level; } -static int msmpeg4_decode_motion(MpegEncContext * s, +int ff_msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr) { MVTable *mv; @@ -1932,9 +1942,3 @@ static int msmpeg4_decode_motion(MpegEncContext * s, *my_ptr = my; return 0; } - -/* cleanest way to support it - * there is too much shared between versions so that we cant have 1 file per version & 1 common - * as allmost everything would be in the common file - */ -#include "wmv2.c" diff --git a/contrib/ffmpeg/libavcodec/msmpeg4.h b/contrib/ffmpeg/libavcodec/msmpeg4.h new file mode 100644 index 000000000..17288b8e2 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/msmpeg4.h @@ -0,0 +1,65 @@ +/* + * MSMPEG4 backend for ffmpeg encoder and decoder + * copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> + * + * 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 msmpeg4.h + */ + +#ifndef FFMPEG_MSMPEG4_H +#define FFMPEG_MSMPEG4_H + +#include "config.h" +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + +#define INTER_INTRA_VLC_BITS 3 +#define MB_NON_INTRA_VLC_BITS 9 +#define MB_INTRA_VLC_BITS 9 + +extern VLC ff_mb_non_intra_vlc[4]; +extern VLC ff_inter_intra_vlc; + +void ff_msmpeg4_code012(PutBitContext *pb, int n); +void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n); +void ff_msmpeg4_handle_slices(MpegEncContext *s); +void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my); +int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, + uint8_t **coded_block_ptr); +int ff_msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr); +int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, + int n, int coded, const uint8_t *scan_table); +int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); + +#define ENABLE_MSMPEG4_DECODER (ENABLE_MSMPEG4V1_DECODER || \ + ENABLE_MSMPEG4V2_DECODER || \ + ENABLE_MSMPEG4V3_DECODER || \ + ENABLE_WMV2_DECODER) +#define ENABLE_MSMPEG4_ENCODER (ENABLE_MSMPEG4V1_ENCODER || \ + ENABLE_MSMPEG4V2_ENCODER || \ + ENABLE_MSMPEG4V3_ENCODER || \ + ENABLE_WMV2_ENCODER) +#define ENABLE_MSMPEG4 (ENABLE_MSMPEG4_DECODER || ENABLE_MSMPEG4_ENCODER) +#define ENABLE_WMV2 (ENABLE_WMV2_DECODER || ENABLE_WMV2_ENCODER) +#define ENABLE_WMV_DECODER (ENABLE_WMV1_DECODER || ENABLE_WMV2_DECODER) +#define ENABLE_WMV_ENCODER (ENABLE_WMV1_ENCODER || ENABLE_WMV2_ENCODER) + +#endif /* FFMPEG_MSMPEG4_H */ diff --git a/contrib/ffmpeg/libavcodec/msmpeg4data.c b/contrib/ffmpeg/libavcodec/msmpeg4data.c new file mode 100644 index 000000000..8ad462c03 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/msmpeg4data.c @@ -0,0 +1,2005 @@ +/* + * MSMPEG4 backend for ffmpeg encoder and decoder + * copyright (c) 2001 Fabrice Bellard + * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * + * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> + * + * 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 msmpeg4data.c + * MSMPEG4 data tables. + */ + +#include "msmpeg4data.h" + +VLC ff_msmp4_mb_i_vlc; +VLC ff_msmp4_dc_luma_vlc[2]; +VLC ff_msmp4_dc_chroma_vlc[2]; + +/* intra picture macro block coded block pattern */ +const uint16_t ff_msmp4_mb_i_table[64][2] = { +{ 0x1, 1 },{ 0x17, 6 },{ 0x9, 5 },{ 0x5, 5 }, +{ 0x6, 5 },{ 0x47, 9 },{ 0x20, 7 },{ 0x10, 7 }, +{ 0x2, 5 },{ 0x7c, 9 },{ 0x3a, 7 },{ 0x1d, 7 }, +{ 0x2, 6 },{ 0xec, 9 },{ 0x77, 8 },{ 0x0, 8 }, +{ 0x3, 5 },{ 0xb7, 9 },{ 0x2c, 7 },{ 0x13, 7 }, +{ 0x1, 6 },{ 0x168, 10 },{ 0x46, 8 },{ 0x3f, 8 }, +{ 0x1e, 6 },{ 0x712, 13 },{ 0xb5, 9 },{ 0x42, 8 }, +{ 0x22, 7 },{ 0x1c5, 11 },{ 0x11e, 10 },{ 0x87, 9 }, +{ 0x6, 4 },{ 0x3, 9 },{ 0x1e, 7 },{ 0x1c, 6 }, +{ 0x12, 7 },{ 0x388, 12 },{ 0x44, 9 },{ 0x70, 9 }, +{ 0x1f, 6 },{ 0x23e, 11 },{ 0x39, 8 },{ 0x8e, 9 }, +{ 0x1, 7 },{ 0x1c6, 11 },{ 0xb6, 9 },{ 0x45, 9 }, +{ 0x14, 6 },{ 0x23f, 11 },{ 0x7d, 9 },{ 0x18, 9 }, +{ 0x7, 7 },{ 0x1c7, 11 },{ 0x86, 9 },{ 0x19, 9 }, +{ 0x15, 6 },{ 0x1db, 10 },{ 0x2, 9 },{ 0x46, 9 }, +{ 0xd, 8 },{ 0x713, 13 },{ 0x1da, 10 },{ 0x169, 10 }, +}; + +/* non intra picture macro block coded block pattern + mb type */ +const uint32_t table_mb_non_intra[128][2] = { +{ 0x40, 7 },{ 0x13c9, 13 },{ 0x9fd, 12 },{ 0x1fc, 15 }, +{ 0x9fc, 12 },{ 0xa83, 18 },{ 0x12d34, 17 },{ 0x83bc, 16 }, +{ 0x83a, 12 },{ 0x7f8, 17 },{ 0x3fd, 16 },{ 0x3ff, 16 }, +{ 0x79, 13 },{ 0xa82, 18 },{ 0x969d, 16 },{ 0x2a4, 16 }, +{ 0x978, 12 },{ 0x543, 17 },{ 0x41df, 15 },{ 0x7f9, 17 }, +{ 0x12f3, 13 },{ 0x25a6b, 18 },{ 0x25ef9, 18 },{ 0x3fa, 16 }, +{ 0x20ee, 14 },{ 0x969ab, 20 },{ 0x969c, 16 },{ 0x25ef8, 18 }, +{ 0x12d2, 13 },{ 0xa85, 18 },{ 0x969e, 16 },{ 0x4bc8, 15 }, +{ 0x3d, 12 },{ 0x12f7f, 17 },{ 0x2a2, 16 },{ 0x969f, 16 }, +{ 0x25ee, 14 },{ 0x12d355, 21 },{ 0x12f7d, 17 },{ 0x12f7e, 17 }, +{ 0x9e5, 12 },{ 0xa81, 18 },{ 0x4b4d4, 19 },{ 0x83bd, 16 }, +{ 0x78, 13 },{ 0x969b, 16 },{ 0x3fe, 16 },{ 0x2a5, 16 }, +{ 0x7e, 13 },{ 0xa80, 18 },{ 0x2a3, 16 },{ 0x3fb, 16 }, +{ 0x1076, 13 },{ 0xa84, 18 },{ 0x153, 15 },{ 0x4bc9, 15 }, +{ 0x55, 13 },{ 0x12d354, 21 },{ 0x4bde, 15 },{ 0x25e5, 14 }, +{ 0x25b, 10 },{ 0x4b4c, 15 },{ 0x96b, 12 },{ 0x96a, 12 }, +{ 0x1, 2 },{ 0x0, 7 },{ 0x26, 6 },{ 0x12b, 9 }, +{ 0x7, 3 },{ 0x20f, 10 },{ 0x4, 9 },{ 0x28, 12 }, +{ 0x6, 3 },{ 0x20a, 10 },{ 0x128, 9 },{ 0x2b, 12 }, +{ 0x11, 5 },{ 0x1b, 11 },{ 0x13a, 9 },{ 0x4ff, 11 }, +{ 0x3, 4 },{ 0x277, 10 },{ 0x106, 9 },{ 0x839, 12 }, +{ 0xb, 4 },{ 0x27b, 10 },{ 0x12c, 9 },{ 0x4bf, 11 }, +{ 0x9, 6 },{ 0x35, 12 },{ 0x27e, 10 },{ 0x13c8, 13 }, +{ 0x1, 6 },{ 0x4aa, 11 },{ 0x208, 10 },{ 0x29, 12 }, +{ 0x1, 4 },{ 0x254, 10 },{ 0x12e, 9 },{ 0x838, 12 }, +{ 0x24, 6 },{ 0x4f3, 11 },{ 0x276, 10 },{ 0x12f6, 13 }, +{ 0x1, 5 },{ 0x27a, 10 },{ 0x13e, 9 },{ 0x3e, 12 }, +{ 0x8, 6 },{ 0x413, 11 },{ 0xc, 10 },{ 0x4be, 11 }, +{ 0x14, 5 },{ 0x412, 11 },{ 0x253, 10 },{ 0x97a, 12 }, +{ 0x21, 6 },{ 0x4ab, 11 },{ 0x20b, 10 },{ 0x34, 12 }, +{ 0x15, 5 },{ 0x278, 10 },{ 0x252, 10 },{ 0x968, 12 }, +{ 0x5, 5 },{ 0xb, 10 },{ 0x9c, 8 },{ 0xe, 10 }, +}; + +/* dc table 0 */ + +const uint32_t ff_table0_dc_lum[120][2] = { +{ 0x1, 1 },{ 0x1, 2 },{ 0x1, 4 },{ 0x1, 5 }, +{ 0x5, 5 },{ 0x7, 5 },{ 0x8, 6 },{ 0xc, 6 }, +{ 0x0, 7 },{ 0x2, 7 },{ 0x12, 7 },{ 0x1a, 7 }, +{ 0x3, 8 },{ 0x7, 8 },{ 0x27, 8 },{ 0x37, 8 }, +{ 0x5, 9 },{ 0x4c, 9 },{ 0x6c, 9 },{ 0x6d, 9 }, +{ 0x8, 10 },{ 0x19, 10 },{ 0x9b, 10 },{ 0x1b, 10 }, +{ 0x9a, 10 },{ 0x13, 11 },{ 0x34, 11 },{ 0x35, 11 }, +{ 0x61, 12 },{ 0x48, 13 },{ 0xc4, 13 },{ 0x4a, 13 }, +{ 0xc6, 13 },{ 0xc7, 13 },{ 0x92, 14 },{ 0x18b, 14 }, +{ 0x93, 14 },{ 0x183, 14 },{ 0x182, 14 },{ 0x96, 14 }, +{ 0x97, 14 },{ 0x180, 14 },{ 0x314, 15 },{ 0x315, 15 }, +{ 0x605, 16 },{ 0x604, 16 },{ 0x606, 16 },{ 0xc0e, 17 }, +{ 0x303cd, 23 },{ 0x303c9, 23 },{ 0x303c8, 23 },{ 0x303ca, 23 }, +{ 0x303cb, 23 },{ 0x303cc, 23 },{ 0x303ce, 23 },{ 0x303cf, 23 }, +{ 0x303d0, 23 },{ 0x303d1, 23 },{ 0x303d2, 23 },{ 0x303d3, 23 }, +{ 0x303d4, 23 },{ 0x303d5, 23 },{ 0x303d6, 23 },{ 0x303d7, 23 }, +{ 0x303d8, 23 },{ 0x303d9, 23 },{ 0x303da, 23 },{ 0x303db, 23 }, +{ 0x303dc, 23 },{ 0x303dd, 23 },{ 0x303de, 23 },{ 0x303df, 23 }, +{ 0x303e0, 23 },{ 0x303e1, 23 },{ 0x303e2, 23 },{ 0x303e3, 23 }, +{ 0x303e4, 23 },{ 0x303e5, 23 },{ 0x303e6, 23 },{ 0x303e7, 23 }, +{ 0x303e8, 23 },{ 0x303e9, 23 },{ 0x303ea, 23 },{ 0x303eb, 23 }, +{ 0x303ec, 23 },{ 0x303ed, 23 },{ 0x303ee, 23 },{ 0x303ef, 23 }, +{ 0x303f0, 23 },{ 0x303f1, 23 },{ 0x303f2, 23 },{ 0x303f3, 23 }, +{ 0x303f4, 23 },{ 0x303f5, 23 },{ 0x303f6, 23 },{ 0x303f7, 23 }, +{ 0x303f8, 23 },{ 0x303f9, 23 },{ 0x303fa, 23 },{ 0x303fb, 23 }, +{ 0x303fc, 23 },{ 0x303fd, 23 },{ 0x303fe, 23 },{ 0x303ff, 23 }, +{ 0x60780, 24 },{ 0x60781, 24 },{ 0x60782, 24 },{ 0x60783, 24 }, +{ 0x60784, 24 },{ 0x60785, 24 },{ 0x60786, 24 },{ 0x60787, 24 }, +{ 0x60788, 24 },{ 0x60789, 24 },{ 0x6078a, 24 },{ 0x6078b, 24 }, +{ 0x6078c, 24 },{ 0x6078d, 24 },{ 0x6078e, 24 },{ 0x6078f, 24 }, +}; + +const uint32_t ff_table0_dc_chroma[120][2] = { +{ 0x0, 2 },{ 0x1, 2 },{ 0x5, 3 },{ 0x9, 4 }, +{ 0xd, 4 },{ 0x11, 5 },{ 0x1d, 5 },{ 0x1f, 5 }, +{ 0x21, 6 },{ 0x31, 6 },{ 0x38, 6 },{ 0x33, 6 }, +{ 0x39, 6 },{ 0x3d, 6 },{ 0x61, 7 },{ 0x79, 7 }, +{ 0x80, 8 },{ 0xc8, 8 },{ 0xca, 8 },{ 0xf0, 8 }, +{ 0x81, 8 },{ 0xc0, 8 },{ 0xc9, 8 },{ 0x107, 9 }, +{ 0x106, 9 },{ 0x196, 9 },{ 0x183, 9 },{ 0x1e3, 9 }, +{ 0x1e2, 9 },{ 0x20a, 10 },{ 0x20b, 10 },{ 0x609, 11 }, +{ 0x412, 11 },{ 0x413, 11 },{ 0x60b, 11 },{ 0x411, 11 }, +{ 0x60a, 11 },{ 0x65f, 11 },{ 0x410, 11 },{ 0x65d, 11 }, +{ 0x65e, 11 },{ 0xcb8, 12 },{ 0xc10, 12 },{ 0xcb9, 12 }, +{ 0x1823, 13 },{ 0x3045, 14 },{ 0x6089, 15 },{ 0xc110, 16 }, +{ 0x304448, 22 },{ 0x304449, 22 },{ 0x30444a, 22 },{ 0x30444b, 22 }, +{ 0x30444c, 22 },{ 0x30444d, 22 },{ 0x30444e, 22 },{ 0x30444f, 22 }, +{ 0x304450, 22 },{ 0x304451, 22 },{ 0x304452, 22 },{ 0x304453, 22 }, +{ 0x304454, 22 },{ 0x304455, 22 },{ 0x304456, 22 },{ 0x304457, 22 }, +{ 0x304458, 22 },{ 0x304459, 22 },{ 0x30445a, 22 },{ 0x30445b, 22 }, +{ 0x30445c, 22 },{ 0x30445d, 22 },{ 0x30445e, 22 },{ 0x30445f, 22 }, +{ 0x304460, 22 },{ 0x304461, 22 },{ 0x304462, 22 },{ 0x304463, 22 }, +{ 0x304464, 22 },{ 0x304465, 22 },{ 0x304466, 22 },{ 0x304467, 22 }, +{ 0x304468, 22 },{ 0x304469, 22 },{ 0x30446a, 22 },{ 0x30446b, 22 }, +{ 0x30446c, 22 },{ 0x30446d, 22 },{ 0x30446e, 22 },{ 0x30446f, 22 }, +{ 0x304470, 22 },{ 0x304471, 22 },{ 0x304472, 22 },{ 0x304473, 22 }, +{ 0x304474, 22 },{ 0x304475, 22 },{ 0x304476, 22 },{ 0x304477, 22 }, +{ 0x304478, 22 },{ 0x304479, 22 },{ 0x30447a, 22 },{ 0x30447b, 22 }, +{ 0x30447c, 22 },{ 0x30447d, 22 },{ 0x30447e, 22 },{ 0x30447f, 22 }, +{ 0x608880, 23 },{ 0x608881, 23 },{ 0x608882, 23 },{ 0x608883, 23 }, +{ 0x608884, 23 },{ 0x608885, 23 },{ 0x608886, 23 },{ 0x608887, 23 }, +{ 0x608888, 23 },{ 0x608889, 23 },{ 0x60888a, 23 },{ 0x60888b, 23 }, +{ 0x60888c, 23 },{ 0x60888d, 23 },{ 0x60888e, 23 },{ 0x60888f, 23 }, +}; + +/* dc table 1 */ + +const uint32_t ff_table1_dc_lum[120][2] = { +{ 0x2, 2 },{ 0x3, 2 },{ 0x3, 3 },{ 0x2, 4 }, +{ 0x5, 4 },{ 0x1, 5 },{ 0x3, 5 },{ 0x8, 5 }, +{ 0x0, 6 },{ 0x5, 6 },{ 0xd, 6 },{ 0xf, 6 }, +{ 0x13, 6 },{ 0x8, 7 },{ 0x18, 7 },{ 0x1c, 7 }, +{ 0x24, 7 },{ 0x4, 8 },{ 0x6, 8 },{ 0x12, 8 }, +{ 0x32, 8 },{ 0x3b, 8 },{ 0x4a, 8 },{ 0x4b, 8 }, +{ 0xb, 9 },{ 0x26, 9 },{ 0x27, 9 },{ 0x66, 9 }, +{ 0x74, 9 },{ 0x75, 9 },{ 0x14, 10 },{ 0x1c, 10 }, +{ 0x1f, 10 },{ 0x1d, 10 },{ 0x2b, 11 },{ 0x3d, 11 }, +{ 0x19d, 11 },{ 0x19f, 11 },{ 0x54, 12 },{ 0x339, 12 }, +{ 0x338, 12 },{ 0x33d, 12 },{ 0xab, 13 },{ 0xf1, 13 }, +{ 0x678, 13 },{ 0xf2, 13 },{ 0x1e0, 14 },{ 0x1e1, 14 }, +{ 0x154, 14 },{ 0xcf2, 14 },{ 0x3cc, 15 },{ 0x2ab, 15 }, +{ 0x19e7, 15 },{ 0x3ce, 15 },{ 0x19e6, 15 },{ 0x554, 16 }, +{ 0x79f, 16 },{ 0x555, 16 },{ 0xf3d, 17 },{ 0xf37, 17 }, +{ 0xf3c, 17 },{ 0xf35, 17 },{ 0x1e6d, 18 },{ 0x1e68, 18 }, +{ 0x3cd8, 19 },{ 0x3cd3, 19 },{ 0x3cd9, 19 },{ 0x79a4, 20 }, +{ 0xf34ba, 25 },{ 0xf34b4, 25 },{ 0xf34b5, 25 },{ 0xf34b6, 25 }, +{ 0xf34b7, 25 },{ 0xf34b8, 25 },{ 0xf34b9, 25 },{ 0xf34bb, 25 }, +{ 0xf34bc, 25 },{ 0xf34bd, 25 },{ 0xf34be, 25 },{ 0xf34bf, 25 }, +{ 0x1e6940, 26 },{ 0x1e6941, 26 },{ 0x1e6942, 26 },{ 0x1e6943, 26 }, +{ 0x1e6944, 26 },{ 0x1e6945, 26 },{ 0x1e6946, 26 },{ 0x1e6947, 26 }, +{ 0x1e6948, 26 },{ 0x1e6949, 26 },{ 0x1e694a, 26 },{ 0x1e694b, 26 }, +{ 0x1e694c, 26 },{ 0x1e694d, 26 },{ 0x1e694e, 26 },{ 0x1e694f, 26 }, +{ 0x1e6950, 26 },{ 0x1e6951, 26 },{ 0x1e6952, 26 },{ 0x1e6953, 26 }, +{ 0x1e6954, 26 },{ 0x1e6955, 26 },{ 0x1e6956, 26 },{ 0x1e6957, 26 }, +{ 0x1e6958, 26 },{ 0x1e6959, 26 },{ 0x1e695a, 26 },{ 0x1e695b, 26 }, +{ 0x1e695c, 26 },{ 0x1e695d, 26 },{ 0x1e695e, 26 },{ 0x1e695f, 26 }, +{ 0x1e6960, 26 },{ 0x1e6961, 26 },{ 0x1e6962, 26 },{ 0x1e6963, 26 }, +{ 0x1e6964, 26 },{ 0x1e6965, 26 },{ 0x1e6966, 26 },{ 0x1e6967, 26 }, +}; + +const uint32_t ff_table1_dc_chroma[120][2] = { +{ 0x0, 2 },{ 0x1, 2 },{ 0x4, 3 },{ 0x7, 3 }, +{ 0xb, 4 },{ 0xd, 4 },{ 0x15, 5 },{ 0x28, 6 }, +{ 0x30, 6 },{ 0x32, 6 },{ 0x52, 7 },{ 0x62, 7 }, +{ 0x66, 7 },{ 0xa6, 8 },{ 0xc6, 8 },{ 0xcf, 8 }, +{ 0x14f, 9 },{ 0x18e, 9 },{ 0x19c, 9 },{ 0x29d, 10 }, +{ 0x33a, 10 },{ 0x538, 11 },{ 0x63c, 11 },{ 0x63e, 11 }, +{ 0x63f, 11 },{ 0x676, 11 },{ 0xa73, 12 },{ 0xc7a, 12 }, +{ 0xcef, 12 },{ 0x14e5, 13 },{ 0x19dd, 13 },{ 0x29c8, 14 }, +{ 0x29c9, 14 },{ 0x63dd, 15 },{ 0x33b8, 14 },{ 0x33b9, 14 }, +{ 0xc7b6, 16 },{ 0x63d8, 15 },{ 0x63df, 15 },{ 0xc7b3, 16 }, +{ 0xc7b4, 16 },{ 0xc7b5, 16 },{ 0x63de, 15 },{ 0xc7b7, 16 }, +{ 0xc7b8, 16 },{ 0xc7b9, 16 },{ 0x18f65, 17 },{ 0x31ec8, 18 }, +{ 0xc7b248, 24 },{ 0xc7b249, 24 },{ 0xc7b24a, 24 },{ 0xc7b24b, 24 }, +{ 0xc7b24c, 24 },{ 0xc7b24d, 24 },{ 0xc7b24e, 24 },{ 0xc7b24f, 24 }, +{ 0xc7b250, 24 },{ 0xc7b251, 24 },{ 0xc7b252, 24 },{ 0xc7b253, 24 }, +{ 0xc7b254, 24 },{ 0xc7b255, 24 },{ 0xc7b256, 24 },{ 0xc7b257, 24 }, +{ 0xc7b258, 24 },{ 0xc7b259, 24 },{ 0xc7b25a, 24 },{ 0xc7b25b, 24 }, +{ 0xc7b25c, 24 },{ 0xc7b25d, 24 },{ 0xc7b25e, 24 },{ 0xc7b25f, 24 }, +{ 0xc7b260, 24 },{ 0xc7b261, 24 },{ 0xc7b262, 24 },{ 0xc7b263, 24 }, +{ 0xc7b264, 24 },{ 0xc7b265, 24 },{ 0xc7b266, 24 },{ 0xc7b267, 24 }, +{ 0xc7b268, 24 },{ 0xc7b269, 24 },{ 0xc7b26a, 24 },{ 0xc7b26b, 24 }, +{ 0xc7b26c, 24 },{ 0xc7b26d, 24 },{ 0xc7b26e, 24 },{ 0xc7b26f, 24 }, +{ 0xc7b270, 24 },{ 0xc7b271, 24 },{ 0xc7b272, 24 },{ 0xc7b273, 24 }, +{ 0xc7b274, 24 },{ 0xc7b275, 24 },{ 0xc7b276, 24 },{ 0xc7b277, 24 }, +{ 0xc7b278, 24 },{ 0xc7b279, 24 },{ 0xc7b27a, 24 },{ 0xc7b27b, 24 }, +{ 0xc7b27c, 24 },{ 0xc7b27d, 24 },{ 0xc7b27e, 24 },{ 0xc7b27f, 24 }, +{ 0x18f6480, 25 },{ 0x18f6481, 25 },{ 0x18f6482, 25 },{ 0x18f6483, 25 }, +{ 0x18f6484, 25 },{ 0x18f6485, 25 },{ 0x18f6486, 25 },{ 0x18f6487, 25 }, +{ 0x18f6488, 25 },{ 0x18f6489, 25 },{ 0x18f648a, 25 },{ 0x18f648b, 25 }, +{ 0x18f648c, 25 },{ 0x18f648d, 25 },{ 0x18f648e, 25 },{ 0x18f648f, 25 }, +}; + +/* vlc table 0, for intra luma */ + +static const uint16_t table0_vlc[133][2] = { +{ 0x1, 2 },{ 0x6, 3 },{ 0xf, 4 },{ 0x16, 5 }, +{ 0x20, 6 },{ 0x18, 7 },{ 0x8, 8 },{ 0x9a, 8 }, +{ 0x56, 9 },{ 0x13e, 9 },{ 0xf0, 10 },{ 0x3a5, 10 }, +{ 0x77, 11 },{ 0x1ef, 11 },{ 0x9a, 12 },{ 0x5d, 13 }, +{ 0x1, 4 },{ 0x11, 5 },{ 0x2, 7 },{ 0xb, 8 }, +{ 0x12, 9 },{ 0x1d6, 9 },{ 0x27e, 10 },{ 0x191, 11 }, +{ 0xea, 12 },{ 0x3dc, 12 },{ 0x13b, 13 },{ 0x4, 5 }, +{ 0x14, 7 },{ 0x9e, 8 },{ 0x9, 10 },{ 0x1ac, 11 }, +{ 0x1e2, 11 },{ 0x3ca, 12 },{ 0x5f, 13 },{ 0x17, 5 }, +{ 0x4e, 7 },{ 0x5e, 9 },{ 0xf3, 10 },{ 0x1ad, 11 }, +{ 0xec, 12 },{ 0x5f0, 13 },{ 0xe, 6 },{ 0xe1, 8 }, +{ 0x3a4, 10 },{ 0x9c, 12 },{ 0x13d, 13 },{ 0x3b, 6 }, +{ 0x1c, 9 },{ 0x14, 11 },{ 0x9be, 12 },{ 0x6, 7 }, +{ 0x7a, 9 },{ 0x190, 11 },{ 0x137, 13 },{ 0x1b, 7 }, +{ 0x8, 10 },{ 0x75c, 11 },{ 0x71, 7 },{ 0xd7, 10 }, +{ 0x9bf, 12 },{ 0x7, 8 },{ 0xaf, 10 },{ 0x4cc, 11 }, +{ 0x34, 8 },{ 0x265, 10 },{ 0x9f, 12 },{ 0xe0, 8 }, +{ 0x16, 11 },{ 0x327, 12 },{ 0x15, 9 },{ 0x17d, 11 }, +{ 0xebb, 12 },{ 0x14, 9 },{ 0xf6, 10 },{ 0x1e4, 11 }, +{ 0xcb, 10 },{ 0x99d, 12 },{ 0xca, 10 },{ 0x2fc, 12 }, +{ 0x17f, 11 },{ 0x4cd, 11 },{ 0x2fd, 12 },{ 0x4fe, 11 }, +{ 0x13a, 13 },{ 0xa, 4 },{ 0x42, 7 },{ 0x1d3, 9 }, +{ 0x4dd, 11 },{ 0x12, 5 },{ 0xe8, 8 },{ 0x4c, 11 }, +{ 0x136, 13 },{ 0x39, 6 },{ 0x264, 10 },{ 0xeba, 12 }, +{ 0x0, 7 },{ 0xae, 10 },{ 0x99c, 12 },{ 0x1f, 7 }, +{ 0x4de, 11 },{ 0x43, 7 },{ 0x4dc, 11 },{ 0x3, 8 }, +{ 0x3cb, 12 },{ 0x6, 8 },{ 0x99e, 12 },{ 0x2a, 8 }, +{ 0x5f1, 13 },{ 0xf, 8 },{ 0x9fe, 12 },{ 0x33, 8 }, +{ 0x9ff, 12 },{ 0x98, 8 },{ 0x99f, 12 },{ 0xea, 8 }, +{ 0x13c, 13 },{ 0x2e, 8 },{ 0x192, 11 },{ 0x136, 9 }, +{ 0x6a, 9 },{ 0x15, 11 },{ 0x3af, 10 },{ 0x1e3, 11 }, +{ 0x74, 11 },{ 0xeb, 12 },{ 0x2f9, 12 },{ 0x5c, 13 }, +{ 0xed, 12 },{ 0x3dd, 12 },{ 0x326, 12 },{ 0x5e, 13 }, +{ 0x16, 7 }, +}; + +static const int8_t table0_level[132] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 1, 2, 3, 4, 5, + 6, 7, 8, 1, 2, 3, 4, 5, + 6, 7, 1, 2, 3, 4, 5, 1, + 2, 3, 4, 1, 2, 3, 4, 1, + 2, 3, 1, 2, 3, 1, 2, 3, + 1, 2, 3, 1, 2, 3, 1, 2, + 3, 1, 2, 3, 1, 2, 1, 2, + 1, 1, 1, 1, 1, 1, 2, 3, + 4, 1, 2, 3, 4, 1, 2, 3, + 1, 2, 3, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, +}; + +static const int8_t table0_run[132] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 3, 3, 3, 3, 3, + 3, 3, 4, 4, 4, 4, 4, 5, + 5, 5, 5, 6, 6, 6, 6, 7, + 7, 7, 8, 8, 8, 9, 9, 9, + 10, 10, 10, 11, 11, 11, 12, 12, + 12, 13, 13, 13, 14, 14, 15, 15, + 16, 17, 18, 19, 20, 0, 0, 0, + 0, 1, 1, 1, 1, 2, 2, 2, + 3, 3, 3, 4, 4, 5, 5, 6, + 6, 7, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, +}; + +/* vlc table 1, for intra chroma and P macro blocks */ + +static const uint16_t table1_vlc[149][2] = { +{ 0x4, 3 },{ 0x14, 5 },{ 0x17, 7 },{ 0x7f, 8 }, +{ 0x154, 9 },{ 0x1f2, 10 },{ 0xbf, 11 },{ 0x65, 12 }, +{ 0xaaa, 12 },{ 0x630, 13 },{ 0x1597, 13 },{ 0x3b7, 14 }, +{ 0x2b22, 14 },{ 0xbe6, 15 },{ 0xb, 4 },{ 0x37, 7 }, +{ 0x62, 9 },{ 0x7, 11 },{ 0x166, 12 },{ 0xce, 13 }, +{ 0x1590, 13 },{ 0x5f6, 14 },{ 0xbe7, 15 },{ 0x7, 5 }, +{ 0x6d, 8 },{ 0x3, 11 },{ 0x31f, 12 },{ 0x5f2, 14 }, +{ 0x2, 6 },{ 0x61, 9 },{ 0x55, 12 },{ 0x1df, 14 }, +{ 0x1a, 6 },{ 0x1e, 10 },{ 0xac9, 12 },{ 0x2b23, 14 }, +{ 0x1e, 6 },{ 0x1f, 10 },{ 0xac3, 12 },{ 0x2b2b, 14 }, +{ 0x6, 7 },{ 0x4, 11 },{ 0x2f8, 13 },{ 0x19, 7 }, +{ 0x6, 11 },{ 0x63d, 13 },{ 0x57, 7 },{ 0x182, 11 }, +{ 0x2aa2, 14 },{ 0x4, 8 },{ 0x180, 11 },{ 0x59c, 14 }, +{ 0x7d, 8 },{ 0x164, 12 },{ 0x76d, 15 },{ 0x2, 9 }, +{ 0x18d, 11 },{ 0x1581, 13 },{ 0xad, 8 },{ 0x60, 12 }, +{ 0xc67, 14 },{ 0x1c, 9 },{ 0xee, 13 },{ 0x3, 9 }, +{ 0x2cf, 13 },{ 0xd9, 9 },{ 0x1580, 13 },{ 0x2, 11 }, +{ 0x183, 11 },{ 0x57, 12 },{ 0x61, 12 },{ 0x31, 11 }, +{ 0x66, 12 },{ 0x631, 13 },{ 0x632, 13 },{ 0xac, 13 }, +{ 0x31d, 12 },{ 0x76, 12 },{ 0x3a, 11 },{ 0x165, 12 }, +{ 0xc66, 14 },{ 0x3, 2 },{ 0x54, 7 },{ 0x2ab, 10 }, +{ 0x16, 13 },{ 0x5f7, 14 },{ 0x5, 4 },{ 0xf8, 9 }, +{ 0xaa9, 12 },{ 0x5f, 15 },{ 0x4, 4 },{ 0x1c, 10 }, +{ 0x1550, 13 },{ 0x4, 5 },{ 0x77, 11 },{ 0x76c, 15 }, +{ 0xe, 5 },{ 0xa, 12 },{ 0xc, 5 },{ 0x562, 11 }, +{ 0x4, 6 },{ 0x31c, 12 },{ 0x6, 6 },{ 0xc8, 13 }, +{ 0xd, 6 },{ 0x1da, 13 },{ 0x7, 6 },{ 0xc9, 13 }, +{ 0x1, 7 },{ 0x2e, 14 },{ 0x14, 7 },{ 0x1596, 13 }, +{ 0xa, 7 },{ 0xac2, 12 },{ 0x16, 7 },{ 0x15b, 14 }, +{ 0x15, 7 },{ 0x15a, 14 },{ 0xf, 8 },{ 0x5e, 15 }, +{ 0x7e, 8 },{ 0xab, 8 },{ 0x2d, 9 },{ 0xd8, 9 }, +{ 0xb, 9 },{ 0x14, 10 },{ 0x2b3, 10 },{ 0x1f3, 10 }, +{ 0x3a, 10 },{ 0x0, 10 },{ 0x58, 10 },{ 0x2e, 9 }, +{ 0x5e, 10 },{ 0x563, 11 },{ 0xec, 12 },{ 0x54, 12 }, +{ 0xac1, 12 },{ 0x1556, 13 },{ 0x2fa, 13 },{ 0x181, 11 }, +{ 0x1557, 13 },{ 0x59d, 14 },{ 0x2aa3, 14 },{ 0x2b2a, 14 }, +{ 0x1de, 14 },{ 0x63c, 13 },{ 0xcf, 13 },{ 0x1594, 13 }, +{ 0xd, 9 }, +}; + +static const int8_t table1_level[148] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 1, + 2, 3, 4, 5, 1, 2, 3, 4, + 1, 2, 3, 4, 1, 2, 3, 4, + 1, 2, 3, 1, 2, 3, 1, 2, + 3, 1, 2, 3, 1, 2, 3, 1, + 2, 3, 1, 2, 3, 1, 2, 1, + 2, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 3, 4, 5, 1, 2, + 3, 4, 1, 2, 3, 1, 2, 3, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, +}; + +static const int8_t table1_run[148] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 8, 8, + 8, 9, 9, 9, 10, 10, 10, 11, + 11, 11, 12, 12, 12, 13, 13, 14, + 14, 15, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 2, 2, 2, 3, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13, 14, 14, 15, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, +}; + +/* third vlc table */ + +static const uint16_t table2_vlc[186][2] = { +{ 0x1, 2 },{ 0x5, 3 },{ 0xd, 4 },{ 0x12, 5 }, +{ 0xe, 6 },{ 0x15, 7 },{ 0x13, 8 },{ 0x3f, 8 }, +{ 0x4b, 9 },{ 0x11f, 9 },{ 0xb8, 10 },{ 0x3e3, 10 }, +{ 0x172, 11 },{ 0x24d, 12 },{ 0x3da, 12 },{ 0x2dd, 13 }, +{ 0x1f55, 13 },{ 0x5b9, 14 },{ 0x3eae, 14 },{ 0x0, 4 }, +{ 0x10, 5 },{ 0x8, 7 },{ 0x20, 8 },{ 0x29, 9 }, +{ 0x1f4, 9 },{ 0x233, 10 },{ 0x1e0, 11 },{ 0x12a, 12 }, +{ 0x3dd, 12 },{ 0x50a, 13 },{ 0x1f29, 13 },{ 0xa42, 14 }, +{ 0x1272, 15 },{ 0x1737, 15 },{ 0x3, 5 },{ 0x11, 7 }, +{ 0xc4, 8 },{ 0x4b, 10 },{ 0xb4, 11 },{ 0x7d4, 11 }, +{ 0x345, 12 },{ 0x2d7, 13 },{ 0x7bf, 13 },{ 0x938, 14 }, +{ 0xbbb, 14 },{ 0x95e, 15 },{ 0x13, 5 },{ 0x78, 7 }, +{ 0x69, 9 },{ 0x232, 10 },{ 0x461, 11 },{ 0x3ec, 12 }, +{ 0x520, 13 },{ 0x1f2a, 13 },{ 0x3e50, 14 },{ 0x3e51, 14 }, +{ 0x1486, 15 },{ 0xc, 6 },{ 0x24, 9 },{ 0x94, 11 }, +{ 0x8c0, 12 },{ 0xf09, 14 },{ 0x1ef0, 15 },{ 0x3d, 6 }, +{ 0x53, 9 },{ 0x1a0, 11 },{ 0x2d6, 13 },{ 0xf08, 14 }, +{ 0x13, 7 },{ 0x7c, 9 },{ 0x7c1, 11 },{ 0x4ac, 14 }, +{ 0x1b, 7 },{ 0xa0, 10 },{ 0x344, 12 },{ 0xf79, 14 }, +{ 0x79, 7 },{ 0x3e1, 10 },{ 0x2d4, 13 },{ 0x2306, 14 }, +{ 0x21, 8 },{ 0x23c, 10 },{ 0xfae, 12 },{ 0x23de, 14 }, +{ 0x35, 8 },{ 0x175, 11 },{ 0x7b3, 13 },{ 0xc5, 8 }, +{ 0x174, 11 },{ 0x785, 13 },{ 0x48, 9 },{ 0x1a3, 11 }, +{ 0x49e, 13 },{ 0x2c, 9 },{ 0xfa, 10 },{ 0x7d6, 11 }, +{ 0x92, 10 },{ 0x5cc, 13 },{ 0x1ef1, 15 },{ 0xa3, 10 }, +{ 0x3ed, 12 },{ 0x93e, 14 },{ 0x1e2, 11 },{ 0x1273, 15 }, +{ 0x7c4, 11 },{ 0x1487, 15 },{ 0x291, 12 },{ 0x293, 12 }, +{ 0xf8a, 12 },{ 0x509, 13 },{ 0x508, 13 },{ 0x78d, 13 }, +{ 0x7be, 13 },{ 0x78c, 13 },{ 0x4ae, 14 },{ 0xbba, 14 }, +{ 0x2307, 14 },{ 0xb9a, 14 },{ 0x1736, 15 },{ 0xe, 4 }, +{ 0x45, 7 },{ 0x1f3, 9 },{ 0x47a, 11 },{ 0x5dc, 13 }, +{ 0x23df, 14 },{ 0x19, 5 },{ 0x28, 9 },{ 0x176, 11 }, +{ 0x49d, 13 },{ 0x23dd, 14 },{ 0x30, 6 },{ 0xa2, 10 }, +{ 0x2ef, 12 },{ 0x5b8, 14 },{ 0x3f, 6 },{ 0xa5, 10 }, +{ 0x3db, 12 },{ 0x93f, 14 },{ 0x44, 7 },{ 0x7cb, 11 }, +{ 0x95f, 15 },{ 0x63, 7 },{ 0x3c3, 12 },{ 0x15, 8 }, +{ 0x8f6, 12 },{ 0x17, 8 },{ 0x498, 13 },{ 0x2c, 8 }, +{ 0x7b2, 13 },{ 0x2f, 8 },{ 0x1f54, 13 },{ 0x8d, 8 }, +{ 0x7bd, 13 },{ 0x8e, 8 },{ 0x1182, 13 },{ 0xfb, 8 }, +{ 0x50b, 13 },{ 0x2d, 8 },{ 0x7c0, 11 },{ 0x79, 9 }, +{ 0x1f5f, 13 },{ 0x7a, 9 },{ 0x1f56, 13 },{ 0x231, 10 }, +{ 0x3e4, 10 },{ 0x1a1, 11 },{ 0x143, 11 },{ 0x1f7, 11 }, +{ 0x16f, 12 },{ 0x292, 12 },{ 0x2e7, 12 },{ 0x16c, 12 }, +{ 0x16d, 12 },{ 0x3dc, 12 },{ 0xf8b, 12 },{ 0x499, 13 }, +{ 0x3d8, 12 },{ 0x78e, 13 },{ 0x2d5, 13 },{ 0x1f5e, 13 }, +{ 0x1f2b, 13 },{ 0x78f, 13 },{ 0x4ad, 14 },{ 0x3eaf, 14 }, +{ 0x23dc, 14 },{ 0x4a, 9 }, +}; + +static const int8_t table2_level[185] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, + 11, 1, 2, 3, 4, 5, 6, 1, + 2, 3, 4, 5, 1, 2, 3, 4, + 1, 2, 3, 4, 1, 2, 3, 4, + 1, 2, 3, 4, 1, 2, 3, 1, + 2, 3, 1, 2, 3, 1, 2, 3, + 1, 2, 3, 1, 2, 3, 1, 2, + 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 4, 5, 6, 1, 2, 3, + 4, 5, 1, 2, 3, 4, 1, 2, + 3, 4, 1, 2, 3, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, +}; + +static const int8_t table2_run[185] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 5, + 5, 5, 5, 5, 6, 6, 6, 6, + 7, 7, 7, 7, 8, 8, 8, 8, + 9, 9, 9, 9, 10, 10, 10, 11, + 11, 11, 12, 12, 12, 13, 13, 13, + 14, 14, 14, 15, 15, 15, 16, 16, + 17, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 0, + 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 3, 3, + 3, 3, 4, 4, 4, 5, 5, 6, + 6, 7, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, + 14, 15, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, + 37, +}; + +/* second non intra vlc table */ +static const uint16_t table4_vlc[169][2] = { +{ 0x0, 3 },{ 0x3, 4 },{ 0xb, 5 },{ 0x14, 6 }, +{ 0x3f, 6 },{ 0x5d, 7 },{ 0xa2, 8 },{ 0xac, 9 }, +{ 0x16e, 9 },{ 0x20a, 10 },{ 0x2e2, 10 },{ 0x432, 11 }, +{ 0x5c9, 11 },{ 0x827, 12 },{ 0xb54, 12 },{ 0x4e6, 13 }, +{ 0x105f, 13 },{ 0x172a, 13 },{ 0x20b2, 14 },{ 0x2d4e, 14 }, +{ 0x39f0, 14 },{ 0x4175, 15 },{ 0x5a9e, 15 },{ 0x4, 4 }, +{ 0x1e, 5 },{ 0x42, 7 },{ 0xb6, 8 },{ 0x173, 9 }, +{ 0x395, 10 },{ 0x72e, 11 },{ 0xb94, 12 },{ 0x16a4, 13 }, +{ 0x20b3, 14 },{ 0x2e45, 14 },{ 0x5, 5 },{ 0x40, 7 }, +{ 0x49, 9 },{ 0x28f, 10 },{ 0x5cb, 11 },{ 0x48a, 13 }, +{ 0x9dd, 14 },{ 0x73e2, 15 },{ 0x18, 5 },{ 0x25, 8 }, +{ 0x8a, 10 },{ 0x51b, 11 },{ 0xe5f, 12 },{ 0x9c9, 14 }, +{ 0x139c, 15 },{ 0x29, 6 },{ 0x4f, 9 },{ 0x412, 11 }, +{ 0x48d, 13 },{ 0x2e41, 14 },{ 0x38, 6 },{ 0x10e, 9 }, +{ 0x5a8, 11 },{ 0x105c, 13 },{ 0x39f2, 14 },{ 0x58, 7 }, +{ 0x21f, 10 },{ 0xe7e, 12 },{ 0x39ff, 14 },{ 0x23, 8 }, +{ 0x2e3, 10 },{ 0x4e5, 13 },{ 0x2e40, 14 },{ 0xa1, 8 }, +{ 0x5be, 11 },{ 0x9c8, 14 },{ 0x83, 8 },{ 0x13a, 11 }, +{ 0x1721, 13 },{ 0x44, 9 },{ 0x276, 12 },{ 0x39f6, 14 }, +{ 0x8b, 10 },{ 0x4ef, 13 },{ 0x5a9b, 15 },{ 0x208, 10 }, +{ 0x1cfe, 13 },{ 0x399, 10 },{ 0x1cb4, 13 },{ 0x39e, 10 }, +{ 0x39f3, 14 },{ 0x5ab, 11 },{ 0x73e3, 15 },{ 0x737, 11 }, +{ 0x5a9f, 15 },{ 0x82d, 12 },{ 0xe69, 12 },{ 0xe68, 12 }, +{ 0x433, 11 },{ 0xb7b, 12 },{ 0x2df8, 14 },{ 0x2e56, 14 }, +{ 0x2e57, 14 },{ 0x39f7, 14 },{ 0x51a5, 15 },{ 0x3, 3 }, +{ 0x2a, 6 },{ 0xe4, 8 },{ 0x28e, 10 },{ 0x735, 11 }, +{ 0x1058, 13 },{ 0x1cfa, 13 },{ 0x2df9, 14 },{ 0x4174, 15 }, +{ 0x9, 4 },{ 0x54, 8 },{ 0x398, 10 },{ 0x48b, 13 }, +{ 0x139d, 15 },{ 0xd, 4 },{ 0xad, 9 },{ 0x826, 12 }, +{ 0x2d4c, 14 },{ 0x11, 5 },{ 0x16b, 9 },{ 0xb7f, 12 }, +{ 0x51a4, 15 },{ 0x19, 5 },{ 0x21b, 10 },{ 0x16fd, 13 }, +{ 0x1d, 5 },{ 0x394, 10 },{ 0x28d3, 14 },{ 0x2b, 6 }, +{ 0x5bc, 11 },{ 0x5a9a, 15 },{ 0x2f, 6 },{ 0x247, 12 }, +{ 0x10, 7 },{ 0xa35, 12 },{ 0x3e, 6 },{ 0xb7a, 12 }, +{ 0x59, 7 },{ 0x105e, 13 },{ 0x26, 8 },{ 0x9cf, 14 }, +{ 0x55, 8 },{ 0x1cb5, 13 },{ 0x57, 8 },{ 0xe5b, 12 }, +{ 0xa0, 8 },{ 0x1468, 13 },{ 0x170, 9 },{ 0x90, 10 }, +{ 0x1ce, 9 },{ 0x21a, 10 },{ 0x218, 10 },{ 0x168, 9 }, +{ 0x21e, 10 },{ 0x244, 12 },{ 0x736, 11 },{ 0x138, 11 }, +{ 0x519, 11 },{ 0xe5e, 12 },{ 0x72c, 11 },{ 0xb55, 12 }, +{ 0x9dc, 14 },{ 0x20bb, 14 },{ 0x48c, 13 },{ 0x1723, 13 }, +{ 0x2e44, 14 },{ 0x16a5, 13 },{ 0x518, 11 },{ 0x39fe, 14 }, +{ 0x169, 9 }, +}; + +static const int8_t table4_level[168] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 1, + 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 1, 2, 3, 4, 5, 6, + 7, 8, 1, 2, 3, 4, 5, 6, + 7, 1, 2, 3, 4, 5, 1, 2, + 3, 4, 5, 1, 2, 3, 4, 1, + 2, 3, 4, 1, 2, 3, 1, 2, + 3, 1, 2, 3, 1, 2, 3, 1, + 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 1, 2, 3, 4, + 5, 1, 2, 3, 4, 1, 2, 3, + 4, 1, 2, 3, 1, 2, 3, 1, + 2, 3, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static const int8_t table4_run[168] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 5, 5, + 5, 5, 5, 6, 6, 6, 6, 7, + 7, 7, 7, 8, 8, 8, 9, 9, + 9, 10, 10, 10, 11, 11, 11, 12, + 12, 13, 13, 14, 14, 15, 15, 16, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 3, 3, 3, + 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 8, 8, 9, 9, + 10, 10, 11, 11, 12, 12, 13, 13, + 14, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, +}; + +extern const uint16_t inter_vlc[103][2]; +extern const int8_t inter_level[102]; +extern const int8_t inter_run[102]; + +extern const uint16_t intra_vlc[103][2]; +extern const int8_t intra_level[102]; +extern const int8_t intra_run[102]; + +RLTable rl_table[NB_RL_TABLES] = { + /* intra luminance tables */ + /* low motion */ + { + 132, + 85, + table0_vlc, + table0_run, + table0_level, + }, + /* high motion */ + { + 185, + 119, + table2_vlc, + table2_run, + table2_level, + }, + /* mid-rate */ + { + 102, + 67, + intra_vlc, + intra_run, + intra_level, + }, + /* intra chrominance / non intra tables */ + /* low motion inter */ + { + 148, + 81, + table1_vlc, + table1_run, + table1_level, + }, + /* high motion inter */ + { + 168, + 99, + table4_vlc, + table4_run, + table4_level, + }, + /* mid rate inter */ + { + 102, + 58, + inter_vlc, + inter_run, + inter_level, + }, +}; + +/* motion vector table 0 */ + +static const uint16_t table0_mv_code[1100] = { + 0x0001, 0x0003, 0x0005, 0x0007, 0x0003, 0x0008, 0x000c, 0x0001, + 0x0002, 0x001b, 0x0006, 0x000b, 0x0015, 0x0002, 0x000e, 0x000f, + 0x0014, 0x0020, 0x0022, 0x0025, 0x0027, 0x0029, 0x002d, 0x004b, + 0x004d, 0x0003, 0x0022, 0x0023, 0x0025, 0x0027, 0x0042, 0x0048, + 0x0049, 0x0050, 0x005c, 0x0091, 0x009f, 0x000e, 0x0043, 0x004c, + 0x0054, 0x0056, 0x008c, 0x0098, 0x009a, 0x009b, 0x00b1, 0x00b2, + 0x0120, 0x0121, 0x0126, 0x0133, 0x0139, 0x01a1, 0x01a4, 0x01a5, + 0x01a6, 0x01a7, 0x01ae, 0x01af, 0x000b, 0x0019, 0x0085, 0x0090, + 0x009b, 0x00aa, 0x00af, 0x010c, 0x010e, 0x011c, 0x011e, 0x0133, + 0x0144, 0x0160, 0x0174, 0x0175, 0x0177, 0x0178, 0x0249, 0x024b, + 0x0252, 0x0261, 0x0265, 0x0270, 0x0352, 0x0353, 0x0355, 0x0359, + 0x0010, 0x0011, 0x0013, 0x0034, 0x0035, 0x0036, 0x0037, 0x003d, + 0x003e, 0x0109, 0x0126, 0x0156, 0x021a, 0x021e, 0x023a, 0x023e, + 0x028e, 0x028f, 0x02cf, 0x0491, 0x0494, 0x049f, 0x04a0, 0x04a3, + 0x04a6, 0x04a7, 0x04ad, 0x04ae, 0x04c0, 0x04c4, 0x04c6, 0x04c8, + 0x04c9, 0x04f5, 0x04f6, 0x04f7, 0x0680, 0x0682, 0x0683, 0x0688, + 0x0689, 0x068d, 0x068e, 0x068f, 0x06a2, 0x06a3, 0x06a9, 0x06b0, + 0x06b1, 0x06b4, 0x06b5, 0x0024, 0x0060, 0x0063, 0x0078, 0x0079, + 0x0211, 0x0244, 0x0245, 0x0247, 0x0248, 0x0249, 0x024a, 0x024b, + 0x026b, 0x02af, 0x02b8, 0x02bb, 0x0436, 0x0476, 0x0477, 0x047e, + 0x04c8, 0x04c9, 0x04ca, 0x0514, 0x0586, 0x0587, 0x0598, 0x059d, + 0x05d9, 0x05da, 0x0920, 0x0921, 0x093b, 0x093c, 0x093d, 0x0942, + 0x0943, 0x0944, 0x0945, 0x0959, 0x095e, 0x095f, 0x0982, 0x0983, + 0x098e, 0x098f, 0x09c4, 0x09e7, 0x09e8, 0x09e9, 0x0d02, 0x0d17, + 0x0d18, 0x0d19, 0x0d41, 0x0d42, 0x0d43, 0x0d50, 0x0d5f, 0x0d6d, + 0x0d6e, 0x0d6f, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x041e, 0x041f, 0x0420, 0x0421, + 0x048c, 0x048d, 0x04d3, 0x04d4, 0x04d5, 0x055c, 0x055d, 0x0572, + 0x0573, 0x0574, 0x0575, 0x08de, 0x08df, 0x08fe, 0x08ff, 0x0996, + 0x0a36, 0x0a37, 0x0b08, 0x0b09, 0x0b0a, 0x0b0b, 0x0b32, 0x0b33, + 0x0b34, 0x0b35, 0x0b36, 0x0b37, 0x0b38, 0x0b39, 0x0bb0, 0x0bf7, + 0x0bf8, 0x0bf9, 0x0bfa, 0x0bfb, 0x0bfc, 0x0bfd, 0x0bfe, 0x0bff, + 0x1254, 0x1255, 0x1256, 0x1257, 0x1270, 0x1271, 0x1272, 0x1273, + 0x1274, 0x1275, 0x12ab, 0x12ac, 0x12ad, 0x12ae, 0x12af, 0x12b0, + 0x12b1, 0x1315, 0x1316, 0x1317, 0x13bf, 0x13c0, 0x13c1, 0x13c2, + 0x13c3, 0x13c4, 0x13c5, 0x13c6, 0x13c7, 0x13c8, 0x13c9, 0x13ca, + 0x13cb, 0x13cc, 0x13cd, 0x1a06, 0x1a07, 0x1a28, 0x1a29, 0x1a2a, + 0x1a2b, 0x1a2c, 0x1a2d, 0x1a80, 0x1abb, 0x1abc, 0x1abd, 0x1ad8, + 0x1ad9, 0x0094, 0x0095, 0x0096, 0x0097, 0x00a0, 0x00a1, 0x00a2, + 0x00a3, 0x0831, 0x0832, 0x0833, 0x0834, 0x0835, 0x0836, 0x0837, + 0x0838, 0x0839, 0x083a, 0x083b, 0x0939, 0x093a, 0x093b, 0x093c, + 0x093d, 0x093e, 0x093f, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x09a4, + 0x09a5, 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, + 0x11b3, 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, + 0x11bb, 0x132f, 0x1454, 0x1455, 0x1456, 0x1457, 0x1458, 0x1459, + 0x145a, 0x145b, 0x145c, 0x145d, 0x145e, 0x145f, 0x1460, 0x1461, + 0x1462, 0x1463, 0x1464, 0x1465, 0x1466, 0x1467, 0x1468, 0x1469, + 0x146a, 0x146b, 0x17de, 0x17df, 0x17e0, 0x17e1, 0x17e2, 0x17e3, + 0x17e4, 0x17e5, 0x17e6, 0x17e7, 0x17e8, 0x17e9, 0x17ea, 0x17eb, + 0x17ec, 0x17ed, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, + 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, + 0x254e, 0x254f, 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, + 0x2628, 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c, + 0x276d, 0x276e, 0x276f, 0x2770, 0x2771, 0x2772, 0x2773, 0x2774, + 0x2775, 0x2776, 0x2777, 0x2778, 0x2779, 0x277a, 0x277b, 0x277c, + 0x277d, 0x3503, 0x3544, 0x3545, 0x3546, 0x3547, 0x3560, 0x3561, + 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567, 0x3568, 0x3569, + 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f, 0x3570, 0x3571, + 0x3572, 0x3573, 0x3574, 0x3575, 0x03f0, 0x103d, 0x103e, 0x103f, + 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, + 0x1048, 0x1049, 0x104a, 0x104b, 0x104c, 0x104d, 0x104e, 0x104f, + 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, + 0x1058, 0x1059, 0x105a, 0x105b, 0x105c, 0x105d, 0x105e, 0x105f, + 0x1060, 0x1061, 0x1270, 0x1271, 0x21b8, 0x21b9, 0x21ba, 0x21bb, + 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x21f0, 0x21f1, 0x21f2, 0x21f3, + 0x21f4, 0x21f5, 0x21f6, 0x21f7, 0x21f8, 0x21f9, 0x21fa, 0x21fb, + 0x21fc, 0x21fd, 0x21fe, 0x21ff, 0x2340, 0x2341, 0x2342, 0x2343, + 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b, + 0x234c, 0x234d, 0x234e, 0x234f, 0x2350, 0x2351, 0x2352, 0x2353, + 0x2354, 0x2355, 0x2356, 0x2357, 0x265c, 0x2f88, 0x2f89, 0x2f8a, + 0x2f8b, 0x2f8c, 0x2f8d, 0x2f8e, 0x2f8f, 0x2f90, 0x2f91, 0x2f92, + 0x2f93, 0x2f94, 0x2f95, 0x2f96, 0x2f97, 0x2f98, 0x2f99, 0x2f9a, + 0x2f9b, 0x2f9c, 0x2f9d, 0x2f9e, 0x2f9f, 0x2fa0, 0x2fa1, 0x2fa2, + 0x2fa3, 0x2fa4, 0x2fa5, 0x2fa6, 0x2fa7, 0x2fa8, 0x2fa9, 0x2faa, + 0x2fab, 0x2fac, 0x2fad, 0x2fae, 0x2faf, 0x2fb0, 0x2fb1, 0x2fb2, + 0x2fb3, 0x2fb4, 0x2fb5, 0x2fb6, 0x2fb7, 0x2fb8, 0x2fb9, 0x2fba, + 0x2fbb, 0x4c52, 0x4c53, 0x4e28, 0x4e29, 0x4e2a, 0x4e2b, 0x4e2c, + 0x4e2d, 0x4e2e, 0x4e2f, 0x4e30, 0x4e31, 0x4e32, 0x4e33, 0x4e34, + 0x4e35, 0x4e36, 0x4e37, 0x4e38, 0x4e39, 0x4e3a, 0x4e3b, 0x4e3c, + 0x4e3d, 0x4e3e, 0x4e3f, 0x4e80, 0x4e81, 0x4e82, 0x4e83, 0x4e84, + 0x4e85, 0x4e86, 0x4e87, 0x4e88, 0x4e89, 0x4e8a, 0x4e8b, 0x4e8c, + 0x4e8d, 0x4e8e, 0x4e8f, 0x4e90, 0x4e91, 0x4e92, 0x4e93, 0x4e94, + 0x4e95, 0x4e96, 0x4e97, 0x4e98, 0x4e99, 0x4e9a, 0x4e9b, 0x4e9c, + 0x4e9d, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea1, 0x4ea2, 0x4ea3, 0x4ea4, + 0x4ea5, 0x4ea6, 0x4ea7, 0x4ea8, 0x4ea9, 0x4eaa, 0x4eab, 0x4eac, + 0x4ead, 0x4eae, 0x4eaf, 0x4eb0, 0x4eb1, 0x4eb2, 0x4eb3, 0x4eb4, + 0x4eb5, 0x4eb6, 0x4eb7, 0x4eb8, 0x4eb9, 0x4eba, 0x4ebb, 0x4ebc, + 0x4ebd, 0x4ebe, 0x4ebf, 0x4ec0, 0x4ec1, 0x4ec2, 0x4ec3, 0x4ec4, + 0x4ec5, 0x4ec6, 0x4ec7, 0x4ec8, 0x4ec9, 0x4eca, 0x4ecb, 0x6a04, + 0x6a05, 0x07e2, 0x07e3, 0x07e4, 0x07e5, 0x07e6, 0x07e7, 0x07e8, + 0x07e9, 0x07ea, 0x07eb, 0x07ec, 0x07ed, 0x07ee, 0x07ef, 0x07f0, + 0x07f1, 0x07f2, 0x07f3, 0x07f4, 0x07f5, 0x07f6, 0x07f7, 0x07f8, + 0x07f9, 0x07fa, 0x07fb, 0x07fc, 0x07fd, 0x07fe, 0x07ff, 0x2000, + 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, + 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x200e, 0x200f, 0x2010, + 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017, 0x2018, + 0x2019, 0x201a, 0x201b, 0x201c, 0x201d, 0x201e, 0x201f, 0x2020, + 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027, 0x2028, + 0x2029, 0x202a, 0x202b, 0x202c, 0x202d, 0x202e, 0x202f, 0x2030, + 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037, 0x2038, + 0x2039, 0x203a, 0x203b, 0x203c, 0x203d, 0x203e, 0x203f, 0x2040, + 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047, 0x2048, + 0x2049, 0x204a, 0x204b, 0x204c, 0x204d, 0x204e, 0x204f, 0x2050, + 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057, 0x2058, + 0x2059, 0x205a, 0x205b, 0x205c, 0x205d, 0x205e, 0x205f, 0x2060, + 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 0x2068, + 0x2069, 0x206a, 0x206b, 0x206c, 0x206d, 0x206e, 0x206f, 0x2070, + 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, + 0x2079, 0x4cba, 0x4cbb, 0x5d88, 0x5d89, 0x5d8a, 0x5d8b, 0x5d8c, + 0x5d8d, 0x5d8e, 0x5d8f, 0x5db0, 0x5db1, 0x5db2, 0x5db3, 0x5db4, + 0x5db5, 0x5db6, 0x5db7, 0x5db8, 0x5db9, 0x5dba, 0x5dbb, 0x5dbc, + 0x5dbd, 0x5dbe, 0x5dbf, 0x5e40, 0x5e41, 0x5e42, 0x5e43, 0x5e44, + 0x5e45, 0x5e46, 0x5e47, 0x5e48, 0x5e49, 0x5e4a, 0x5e4b, 0x5e4c, + 0x5e4d, 0x5e4e, 0x5e4f, 0x5e50, 0x5e51, 0x5e52, 0x5e53, 0x5e54, + 0x5e55, 0x5e56, 0x5e57, 0x5e58, 0x5e59, 0x5e5a, 0x5e5b, 0x5e5c, + 0x5e5d, 0x5e5e, 0x5e5f, 0x5e60, 0x5e61, 0x5e62, 0x5e63, 0x5e64, + 0x5e65, 0x5e66, 0x5e67, 0x5e68, 0x5e69, 0x5e6a, 0x5e6b, 0x5e6c, + 0x5e6d, 0x5e6e, 0x5e6f, 0x5e70, 0x5e71, 0x5e72, 0x5e73, 0x5e74, + 0x5e75, 0x5e76, 0x5e77, 0x5e78, 0x5e79, 0x5e7a, 0x5e7b, 0x5e7c, + 0x5e7d, 0x5e7e, 0x5e7f, 0x5e80, 0x5e81, 0x5e82, 0x5e83, 0x5e84, + 0x5e85, 0x5e86, 0x5e87, 0x5e88, 0x5e89, 0x5e8a, 0x5e8b, 0x5e8c, + 0x5e8d, 0x5e8e, 0x5e8f, 0x5e90, 0x5e91, 0x5e92, 0x5e93, 0x5e94, + 0x5e95, 0x5e96, 0x5e97, 0x5e98, 0x5e99, 0x5e9a, 0x5e9b, 0x5e9c, + 0x5e9d, 0x5e9e, 0x5e9f, 0x5ea0, 0x5ea1, 0x5ea2, 0x5ea3, 0x5ea4, + 0x5ea5, 0x5ea6, 0x5ea7, 0x5ea8, 0x5ea9, 0x5eaa, 0x5eab, 0x5eac, + 0x5ead, 0x5eae, 0x5eaf, 0x5eb0, 0x5eb1, 0x5eb2, 0x5eb3, 0x5eb4, + 0x5eb5, 0x5eb6, 0x5eb7, 0x5eb8, 0x5eb9, 0x5eba, 0x5ebb, 0x5ebc, + 0x5ebd, 0x5ebe, 0x5ebf, 0x5ec0, 0x5ec1, 0x5ec2, 0x5ec3, 0x5ec4, + 0x5ec5, 0x5ec6, 0x5ec7, 0x5ec8, 0x5ec9, 0x5eca, 0x5ecb, 0x5ecc, + 0x5ecd, 0x5ece, 0x5ecf, 0x5ed0, 0x5ed1, 0x5ed2, 0x5ed3, 0x5ed4, + 0x5ed5, 0x5ed6, 0x5ed7, 0x5ed8, 0x5ed9, 0x5eda, 0x5edb, 0x5edc, + 0x5edd, 0x5ede, 0x5edf, 0x5ee0, 0x5ee1, 0x5ee2, 0x5ee3, 0x5ee4, + 0x5ee5, 0x5ee6, 0x5ee7, 0x5ee8, 0x5ee9, 0x5eea, 0x5eeb, 0x5eec, + 0x5eed, 0x5eee, 0x5eef, 0x5ef0, 0x5ef1, 0x5ef2, 0x5ef3, 0x5ef4, + 0x5ef5, 0x5ef6, 0x5ef7, 0x5ef8, 0x5ef9, 0x5efa, 0x5efb, 0x5efc, + 0x5efd, 0x5efe, 0x5eff, 0x5f00, 0x5f01, 0x5f02, 0x5f03, 0x5f04, + 0x5f05, 0x5f06, 0x5f07, 0x5f08, 0x5f09, 0x5f0a, 0x5f0b, 0x5f0c, + 0x5f0d, 0x5f0e, 0x5f0f, 0x0000, +}; + +static const uint8_t table0_mv_bits[1100] = { + 1, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 16, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 8, +}; + +static const uint8_t table0_mvx[1099] = { + 32, 32, 31, 32, 33, 31, 33, 31, + 33, 32, 34, 32, 30, 32, 31, 34, + 35, 32, 34, 33, 29, 33, 30, 30, + 31, 31, 35, 29, 33, 35, 33, 34, + 31, 29, 30, 34, 30, 36, 28, 32, + 34, 37, 30, 27, 32, 25, 39, 32, + 34, 32, 35, 35, 35, 31, 35, 29, + 32, 29, 30, 29, 37, 27, 36, 38, + 37, 33, 32, 31, 29, 31, 28, 36, + 33, 30, 34, 33, 33, 28, 27, 25, + 31, 26, 39, 32, 32, 31, 33, 39, + 31, 38, 28, 36, 21, 23, 43, 36, + 34, 41, 30, 25, 28, 31, 30, 34, + 38, 35, 61, 34, 28, 30, 37, 37, + 35, 27, 36, 3, 59, 38, 37, 32, + 31, 29, 26, 33, 37, 33, 27, 27, + 35, 34, 34, 40, 42, 33, 32, 29, + 4, 5, 28, 24, 25, 35, 39, 38, + 32, 23, 27, 32, 30, 35, 26, 34, + 60, 36, 29, 22, 26, 41, 7, 30, + 38, 30, 36, 29, 30, 41, 26, 25, + 32, 34, 24, 39, 1, 25, 39, 32, + 28, 29, 32, 38, 26, 36, 28, 63, + 28, 39, 23, 21, 26, 35, 31, 35, + 57, 31, 29, 29, 28, 30, 27, 35, + 2, 38, 40, 34, 37, 29, 38, 43, + 26, 32, 33, 42, 24, 40, 28, 32, + 32, 32, 36, 32, 43, 25, 21, 31, + 30, 31, 41, 29, 33, 37, 26, 37, + 27, 59, 23, 33, 35, 31, 31, 37, + 38, 39, 32, 23, 32, 27, 37, 36, + 31, 40, 25, 27, 38, 31, 36, 28, + 31, 36, 25, 45, 3, 34, 38, 39, + 40, 38, 30, 32, 19, 24, 25, 26, + 45, 20, 24, 33, 33, 31, 41, 34, + 39, 47, 40, 58, 59, 41, 33, 3, + 17, 61, 42, 30, 26, 29, 36, 61, + 33, 37, 62, 28, 25, 38, 25, 38, + 17, 23, 34, 33, 21, 33, 49, 27, + 32, 23, 27, 22, 24, 22, 39, 43, + 27, 37, 6, 42, 47, 26, 30, 31, + 41, 39, 33, 22, 45, 36, 32, 45, + 19, 22, 30, 5, 5, 17, 29, 22, + 31, 31, 43, 37, 27, 32, 32, 32, + 33, 34, 43, 35, 29, 26, 22, 32, + 19, 32, 25, 31, 41, 49, 28, 34, + 28, 39, 34, 19, 37, 38, 29, 21, + 36, 42, 24, 48, 16, 28, 49, 22, + 34, 31, 38, 39, 44, 11, 35, 30, + 33, 33, 23, 28, 33, 46, 15, 13, + 24, 41, 24, 34, 34, 30, 26, 24, + 14, 60, 21, 29, 39, 23, 35, 37, + 63, 45, 33, 34, 47, 41, 22, 42, + 35, 35, 23, 32, 35, 43, 32, 7, + 31, 41, 20, 31, 16, 13, 63, 25, + 30, 32, 35, 30, 30, 31, 42, 47, + 39, 38, 40, 40, 51, 55, 56, 18, + 21, 39, 39, 33, 17, 41, 23, 24, + 43, 25, 31, 20, 19, 45, 1, 34, + 31, 22, 35, 15, 46, 46, 35, 31, + 28, 29, 29, 23, 41, 27, 14, 53, + 53, 27, 24, 32, 57, 32, 17, 42, + 37, 29, 33, 1, 25, 32, 32, 63, + 26, 40, 44, 36, 31, 39, 20, 20, + 44, 23, 33, 34, 35, 33, 33, 28, + 41, 23, 41, 41, 29, 25, 26, 49, + 29, 24, 37, 49, 50, 51, 51, 26, + 39, 25, 26, 15, 39, 18, 42, 17, + 4, 31, 32, 32, 60, 1, 42, 32, + 0, 12, 19, 35, 21, 41, 17, 26, + 20, 45, 46, 32, 37, 22, 47, 29, + 31, 27, 29, 30, 21, 33, 35, 18, + 25, 33, 50, 51, 42, 2, 15, 51, + 53, 33, 25, 29, 55, 37, 38, 33, + 38, 59, 38, 33, 39, 13, 32, 40, + 61, 61, 32, 9, 44, 3, 31, 29, + 25, 31, 27, 23, 9, 25, 9, 29, + 20, 30, 30, 42, 18, 28, 25, 28, + 28, 21, 29, 43, 29, 43, 26, 44, + 44, 21, 38, 21, 24, 45, 45, 35, + 39, 22, 35, 36, 34, 34, 45, 34, + 29, 31, 46, 25, 46, 16, 17, 31, + 20, 32, 47, 47, 47, 32, 49, 49, + 49, 31, 1, 27, 28, 39, 39, 21, + 36, 23, 51, 2, 40, 51, 32, 53, + 24, 30, 24, 30, 21, 40, 57, 57, + 31, 41, 58, 32, 12, 4, 32, 34, + 59, 31, 32, 13, 9, 35, 26, 35, + 37, 61, 37, 63, 26, 29, 41, 38, + 23, 20, 41, 26, 41, 42, 42, 42, + 26, 26, 26, 26, 1, 26, 37, 37, + 37, 23, 34, 42, 27, 43, 34, 27, + 31, 24, 33, 16, 3, 31, 24, 33, + 24, 4, 44, 44, 11, 44, 31, 13, + 13, 44, 45, 13, 25, 22, 38, 26, + 38, 38, 39, 32, 30, 39, 30, 22, + 32, 26, 30, 47, 47, 47, 19, 47, + 30, 31, 35, 8, 23, 47, 47, 27, + 35, 47, 31, 48, 35, 19, 36, 49, + 49, 33, 31, 39, 27, 39, 49, 49, + 50, 50, 50, 39, 31, 51, 51, 39, + 28, 33, 33, 21, 40, 31, 52, 53, + 40, 53, 9, 33, 31, 53, 54, 54, + 54, 55, 55, 34, 15, 56, 25, 56, + 21, 21, 40, 40, 25, 40, 58, 36, + 5, 41, 41, 12, 60, 41, 41, 37, + 22, 61, 18, 29, 29, 30, 61, 30, + 61, 62, 62, 30, 30, 63, 18, 13, + 30, 23, 19, 20, 20, 41, 13, 2, + 5, 5, 1, 5, 32, 6, 32, 35, + 20, 35, 27, 35, 35, 36, 36, 13, + 36, 41, 41, 41, 3, 30, 42, 27, + 20, 30, 27, 28, 30, 21, 33, 33, + 14, 24, 30, 42, 24, 33, 25, 42, + 43, 14, 43, 43, 14, 43, 7, 36, + 37, 37, 37, 37, 7, 14, 25, 43, + 43, 44, 15, 37, 7, 7, 3, 1, + 8, 15, 15, 8, 44, 44, 44, 45, + 45, 45, 45, 8, 8, 45, 21, 45, + 28, 28, 28, 21, 28, 28, 22, 37, + 46, 46, 37, 8, 29, 37, 29, 22, + 46, 37, 22, 29, 47, 47, 38, 38, + 16, 38, 38, 33, 38, 22, 47, 47, + 29, 25, 16, 0, 48, 1, 34, 48, + 48, 34, 25, 26, 26, 49, 49, 26, + 1, 49, 4, 26, 4, 49, 1, 9, + 49, 49, 49, 10, 49, 17, 38, 17, + 17, 50, 38, 50, 50, 22, 38, 51, + 38, 38, 51, 39, 39, 18, 22, 39, + 51, 22, 52, 52, 52, 39, 53, 53, + 10, 23, 18, 29, 10, 53, 29, 54, + 11, 54, 11, 11, 55, 1, 18, 55, + 55, 55, 55, 55, 55, 29, 34, 18, + 29, 56, 56, 34, 57, 34, 34, 29, + 29, 57, 57, 35, 35, 35, 35, 35, + 39, 35, 59, 59, 18, 59, 39, 30, + 18, 40, 60, 60, 61, 30, 18, 61, + 61, 19, 19, +}; + +static const uint8_t table0_mvy[1099] = { + 32, 31, 32, 33, 32, 31, 31, 33, + 33, 34, 32, 30, 32, 35, 34, 31, + 32, 29, 33, 30, 32, 34, 33, 31, + 30, 35, 31, 31, 29, 33, 35, 30, + 29, 33, 34, 34, 30, 32, 32, 36, + 29, 32, 35, 32, 28, 32, 32, 27, + 35, 37, 34, 29, 30, 36, 35, 34, + 25, 30, 29, 35, 33, 31, 31, 32, + 31, 28, 39, 28, 29, 37, 31, 33, + 27, 36, 28, 36, 37, 33, 33, 31, + 27, 32, 31, 38, 26, 25, 25, 33, + 39, 31, 34, 30, 32, 32, 32, 34, + 36, 32, 28, 33, 30, 38, 37, 27, + 33, 28, 32, 37, 35, 38, 29, 34, + 27, 29, 29, 32, 32, 34, 35, 3, + 26, 36, 31, 38, 30, 26, 35, 34, + 37, 26, 25, 32, 32, 39, 23, 37, + 32, 32, 29, 32, 29, 36, 29, 30, + 41, 31, 30, 21, 39, 25, 34, 38, + 32, 35, 39, 32, 33, 33, 32, 27, + 29, 25, 28, 27, 26, 31, 30, 35, + 24, 24, 31, 34, 32, 30, 35, 40, + 28, 38, 5, 35, 29, 36, 36, 32, + 38, 30, 33, 31, 35, 26, 23, 38, + 32, 41, 28, 25, 37, 40, 37, 39, + 32, 36, 33, 39, 25, 26, 28, 31, + 28, 42, 23, 31, 33, 31, 39, 1, + 59, 22, 27, 4, 33, 34, 33, 24, + 41, 3, 35, 41, 41, 28, 36, 36, + 28, 33, 35, 21, 23, 21, 22, 37, + 27, 27, 43, 29, 60, 39, 27, 25, + 59, 34, 27, 27, 26, 40, 37, 27, + 61, 26, 39, 33, 31, 22, 37, 25, + 30, 25, 24, 61, 31, 34, 25, 38, + 32, 32, 30, 3, 61, 43, 29, 23, + 28, 32, 28, 32, 31, 34, 5, 33, + 32, 33, 33, 42, 37, 23, 38, 31, + 40, 26, 32, 26, 37, 38, 36, 24, + 29, 30, 20, 22, 29, 24, 32, 41, + 2, 34, 25, 33, 29, 31, 39, 35, + 36, 24, 32, 30, 33, 27, 44, 60, + 30, 36, 19, 34, 31, 24, 16, 35, + 32, 38, 21, 33, 31, 31, 21, 35, + 5, 17, 29, 38, 38, 18, 58, 19, + 43, 41, 30, 41, 43, 39, 29, 7, + 29, 17, 28, 19, 28, 31, 25, 19, + 40, 26, 21, 33, 39, 23, 40, 30, + 39, 34, 35, 32, 32, 24, 33, 30, + 40, 47, 39, 37, 32, 33, 24, 23, + 45, 47, 27, 23, 42, 32, 32, 33, + 36, 37, 37, 17, 18, 22, 40, 38, + 32, 31, 35, 24, 17, 25, 17, 23, + 33, 34, 51, 42, 31, 36, 36, 29, + 21, 22, 37, 44, 43, 25, 47, 33, + 45, 27, 31, 58, 31, 32, 31, 38, + 43, 20, 47, 45, 54, 1, 26, 34, + 38, 14, 22, 24, 33, 34, 32, 32, + 37, 21, 23, 49, 35, 23, 28, 39, + 39, 23, 55, 33, 30, 30, 63, 16, + 42, 28, 13, 33, 33, 35, 19, 46, + 43, 17, 19, 36, 39, 24, 31, 32, + 33, 26, 28, 62, 33, 63, 33, 39, + 19, 49, 17, 31, 43, 13, 15, 29, + 25, 35, 33, 23, 49, 41, 28, 29, + 34, 38, 7, 61, 11, 50, 13, 41, + 19, 47, 25, 26, 15, 42, 41, 29, + 45, 27, 17, 35, 32, 29, 32, 24, + 13, 26, 26, 31, 24, 33, 28, 30, + 31, 11, 45, 46, 33, 33, 35, 57, + 32, 32, 35, 45, 34, 11, 37, 42, + 39, 37, 31, 49, 21, 27, 29, 47, + 53, 40, 51, 16, 26, 1, 40, 30, + 41, 44, 34, 25, 27, 31, 35, 35, + 31, 15, 49, 1, 35, 40, 5, 58, + 21, 29, 22, 59, 45, 31, 9, 26, + 9, 29, 11, 32, 30, 3, 13, 20, + 18, 20, 11, 3, 29, 40, 31, 53, + 30, 17, 20, 37, 31, 42, 47, 47, + 54, 38, 9, 34, 13, 37, 21, 25, + 27, 43, 42, 45, 40, 25, 27, 46, + 22, 25, 53, 20, 2, 14, 39, 15, + 22, 44, 34, 21, 38, 33, 27, 48, + 34, 52, 35, 47, 49, 54, 2, 13, + 23, 52, 29, 45, 22, 49, 54, 21, + 40, 42, 31, 30, 29, 34, 0, 25, + 23, 51, 24, 59, 28, 38, 29, 31, + 2, 13, 31, 8, 31, 33, 12, 45, + 41, 7, 14, 30, 25, 18, 43, 20, + 43, 35, 44, 1, 49, 42, 42, 18, + 41, 38, 41, 44, 53, 11, 20, 25, + 45, 46, 47, 48, 39, 52, 46, 49, + 63, 55, 44, 38, 13, 13, 57, 22, + 51, 16, 12, 28, 35, 57, 25, 20, + 26, 28, 28, 29, 32, 31, 62, 34, + 35, 35, 19, 49, 48, 39, 40, 18, + 43, 46, 11, 6, 48, 19, 49, 41, + 10, 23, 58, 17, 21, 23, 34, 30, + 60, 0, 44, 34, 26, 37, 46, 43, + 49, 59, 4, 34, 59, 37, 22, 25, + 28, 46, 6, 40, 59, 42, 36, 61, + 28, 30, 31, 43, 10, 22, 23, 47, + 20, 52, 55, 36, 25, 16, 1, 11, + 27, 29, 5, 63, 18, 41, 31, 34, + 38, 1, 5, 13, 28, 31, 17, 38, + 39, 41, 36, 37, 22, 39, 33, 43, + 43, 15, 17, 49, 30, 21, 22, 20, + 10, 17, 25, 54, 57, 3, 34, 8, + 36, 25, 31, 14, 15, 19, 29, 25, + 18, 39, 53, 22, 27, 20, 29, 33, + 41, 42, 35, 62, 50, 29, 53, 50, + 35, 55, 42, 61, 63, 4, 7, 42, + 21, 46, 47, 49, 27, 46, 17, 55, + 41, 50, 63, 4, 56, 18, 8, 10, + 18, 51, 63, 36, 55, 18, 5, 55, + 9, 29, 17, 21, 30, 27, 1, 59, + 7, 11, 12, 15, 5, 42, 24, 41, + 43, 7, 27, 22, 25, 31, 30, 37, + 22, 39, 53, 29, 36, 37, 48, 0, + 5, 13, 17, 31, 32, 26, 46, 28, + 44, 45, 46, 53, 49, 51, 3, 41, + 3, 22, 42, 33, 5, 45, 7, 22, + 40, 53, 24, 14, 25, 27, 10, 12, + 34, 16, 17, 53, 20, 26, 39, 45, + 18, 45, 35, 33, 31, 49, 4, 39, + 42, 11, 51, 5, 13, 26, 27, 17, + 52, 30, 0, 22, 12, 34, 62, 36, + 38, 41, 47, 30, 63, 38, 41, 43, + 59, 33, 45, 37, 38, 40, 47, 24, + 48, 49, 30, 1, 10, 22, 49, 15, + 39, 59, 31, 32, 33, 18, 13, 15, + 31, 21, 27, 44, 42, 39, 46, 17, + 26, 32, 30, 31, 0, 30, 34, 9, + 12, 13, 25, 31, 32, 55, 43, 35, + 61, 33, 35, 46, 25, 47, 48, 62, + 63, 38, 61, 1, 2, 5, 7, 9, + 46, 10, 34, 35, 36, 55, 51, 7, + 40, 23, 34, 37, 5, 13, 42, 18, + 25, 27, 28, +}; + +/* motion vector table 1 */ +static const uint16_t table1_mv_code[1100] = { + 0x0000, 0x0007, 0x0009, 0x000f, 0x000a, 0x0011, 0x001a, 0x001c, + 0x0011, 0x0031, 0x0025, 0x002d, 0x002f, 0x006f, 0x0075, 0x0041, + 0x004c, 0x004e, 0x005c, 0x0060, 0x0062, 0x0066, 0x0068, 0x0069, + 0x006b, 0x00a6, 0x00c1, 0x00cb, 0x00cc, 0x00ce, 0x00da, 0x00e8, + 0x00ee, 0x0087, 0x0090, 0x009e, 0x009f, 0x00ba, 0x00ca, 0x00d8, + 0x00db, 0x00df, 0x0104, 0x0109, 0x010c, 0x0143, 0x0145, 0x014a, + 0x0156, 0x015c, 0x01b3, 0x01d3, 0x01da, 0x0103, 0x0109, 0x010b, + 0x0122, 0x0127, 0x0134, 0x0161, 0x0164, 0x0176, 0x0184, 0x018d, + 0x018e, 0x018f, 0x0190, 0x0193, 0x0196, 0x019d, 0x019e, 0x019f, + 0x01a9, 0x01b2, 0x01b4, 0x01ba, 0x01bb, 0x01bc, 0x0201, 0x0202, + 0x0205, 0x0207, 0x020d, 0x0210, 0x0211, 0x0215, 0x021b, 0x021f, + 0x0281, 0x0285, 0x0290, 0x029c, 0x029d, 0x02a2, 0x02a7, 0x02a8, + 0x02aa, 0x02b0, 0x02b1, 0x02b4, 0x02bc, 0x02bf, 0x0320, 0x0326, + 0x0327, 0x0329, 0x032a, 0x0336, 0x0360, 0x0362, 0x0363, 0x0372, + 0x03b2, 0x03bc, 0x03bd, 0x0203, 0x0205, 0x021a, 0x0249, 0x024a, + 0x024c, 0x02c7, 0x02ca, 0x02ce, 0x02ef, 0x030d, 0x0322, 0x0325, + 0x0338, 0x0373, 0x037a, 0x0409, 0x0415, 0x0416, 0x0418, 0x0428, + 0x042d, 0x042f, 0x0434, 0x0508, 0x0509, 0x0510, 0x0511, 0x051c, + 0x051e, 0x0524, 0x0541, 0x0543, 0x0546, 0x0547, 0x054d, 0x0557, + 0x055f, 0x056a, 0x056c, 0x056d, 0x056f, 0x0576, 0x0577, 0x057a, + 0x057b, 0x057c, 0x057d, 0x0600, 0x0601, 0x0603, 0x0614, 0x0616, + 0x0617, 0x061c, 0x061f, 0x0642, 0x0648, 0x0649, 0x064a, 0x064b, + 0x0657, 0x0668, 0x0669, 0x066b, 0x066e, 0x067f, 0x06c2, 0x06c8, + 0x06cb, 0x06de, 0x06df, 0x06e2, 0x06e3, 0x06ef, 0x0748, 0x074b, + 0x076e, 0x076f, 0x077c, 0x0409, 0x0423, 0x0428, 0x0429, 0x042a, + 0x042b, 0x0432, 0x0433, 0x0496, 0x049a, 0x04d5, 0x04db, 0x0581, + 0x0582, 0x058b, 0x058c, 0x058d, 0x0598, 0x0599, 0x059a, 0x059e, + 0x05dd, 0x0619, 0x0632, 0x0633, 0x0648, 0x0672, 0x06a1, 0x06a2, + 0x06a3, 0x06af, 0x06e2, 0x06e3, 0x06e4, 0x0800, 0x0801, 0x0802, + 0x0803, 0x081a, 0x081b, 0x0829, 0x082f, 0x0832, 0x083e, 0x083f, + 0x0852, 0x0853, 0x0858, 0x086b, 0x0877, 0x0878, 0x0879, 0x087a, + 0x087b, 0x0a00, 0x0a01, 0x0a0d, 0x0a0e, 0x0a0f, 0x0a24, 0x0a37, + 0x0a3a, 0x0a3b, 0x0a3e, 0x0a46, 0x0a47, 0x0a4a, 0x0a4b, 0x0a5f, + 0x0a79, 0x0a7a, 0x0a7b, 0x0a80, 0x0a81, 0x0a84, 0x0a85, 0x0a99, + 0x0aa5, 0x0aa6, 0x0ab8, 0x0aba, 0x0abb, 0x0abc, 0x0abd, 0x0ac8, + 0x0ace, 0x0acf, 0x0ad7, 0x0adc, 0x0aeb, 0x0c04, 0x0c25, 0x0c26, + 0x0c27, 0x0c2a, 0x0c2b, 0x0c3a, 0x0c3b, 0x0c3c, 0x0c3d, 0x0ca0, + 0x0cad, 0x0cd4, 0x0cd5, 0x0cfc, 0x0cfd, 0x0d86, 0x0d92, 0x0d93, + 0x0d94, 0x0d95, 0x0db0, 0x0db8, 0x0db9, 0x0dba, 0x0dbb, 0x0dc0, + 0x0dc2, 0x0dc3, 0x0dda, 0x0ddb, 0x0ddc, 0x0ddd, 0x0e92, 0x0e93, + 0x0e94, 0x0e95, 0x0ec7, 0x0ecc, 0x0ece, 0x0ecf, 0x0ed8, 0x0ed9, + 0x0eda, 0x0edb, 0x0808, 0x0809, 0x080a, 0x0810, 0x0811, 0x0844, + 0x0845, 0x0861, 0x0862, 0x0863, 0x086c, 0x0922, 0x0923, 0x092e, + 0x092f, 0x0936, 0x0937, 0x09b1, 0x09b2, 0x09b3, 0x09b4, 0x09b5, + 0x09b8, 0x09b9, 0x09ba, 0x09bb, 0x09bc, 0x09bd, 0x09be, 0x09bf, + 0x0b00, 0x0b15, 0x0b2c, 0x0b2d, 0x0b2e, 0x0b2f, 0x0b36, 0x0bb9, + 0x0c28, 0x0c2a, 0x0c2b, 0x0c2c, 0x0c2d, 0x0c2e, 0x0c2f, 0x0c30, + 0x0c31, 0x0c38, 0x0c60, 0x0c61, 0x0c62, 0x0c63, 0x0c8d, 0x0c8e, + 0x0c8f, 0x0c92, 0x0cbe, 0x0cbf, 0x0ce6, 0x0ce7, 0x0d40, 0x0d41, + 0x0d57, 0x0d58, 0x0d59, 0x0d5a, 0x0d5b, 0x0d5c, 0x0d5d, 0x0d98, + 0x0d99, 0x0d9a, 0x0d9b, 0x0d9c, 0x0d9d, 0x0dad, 0x0dae, 0x0daf, + 0x0dc0, 0x0dc1, 0x0dc2, 0x0dc3, 0x0dca, 0x0dcb, 0x0dec, 0x0ded, + 0x0dee, 0x0def, 0x1018, 0x1022, 0x1023, 0x1030, 0x1031, 0x1032, + 0x1033, 0x1050, 0x1051, 0x105c, 0x1074, 0x1075, 0x1076, 0x1077, + 0x1078, 0x1079, 0x107a, 0x107b, 0x10b2, 0x10b3, 0x10b8, 0x10b9, + 0x10ba, 0x10bb, 0x10d4, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x1404, + 0x1405, 0x1406, 0x1407, 0x1410, 0x1411, 0x1412, 0x1413, 0x1414, + 0x1415, 0x1416, 0x1417, 0x1418, 0x1419, 0x1466, 0x1467, 0x1468, + 0x1469, 0x146a, 0x146b, 0x146c, 0x146d, 0x147e, 0x147f, 0x1488, + 0x1489, 0x148a, 0x148b, 0x14b6, 0x14b7, 0x14b8, 0x14b9, 0x14ba, + 0x14bb, 0x14bc, 0x14bd, 0x14f0, 0x14f1, 0x14f8, 0x14f9, 0x14fa, + 0x14fb, 0x14fc, 0x14fd, 0x14fe, 0x14ff, 0x152a, 0x152b, 0x152c, + 0x152d, 0x152e, 0x152f, 0x1530, 0x1531, 0x1548, 0x1549, 0x154e, + 0x154f, 0x1558, 0x1559, 0x155a, 0x155b, 0x1572, 0x159a, 0x159b, + 0x15ac, 0x15ba, 0x15bb, 0x15d0, 0x15d1, 0x15d2, 0x15d3, 0x15d4, + 0x15d5, 0x181d, 0x181e, 0x181f, 0x1840, 0x1841, 0x1842, 0x1843, + 0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x1861, 0x1862, + 0x1863, 0x1864, 0x1865, 0x1866, 0x1867, 0x1868, 0x1869, 0x186a, + 0x186b, 0x186c, 0x186d, 0x186e, 0x191b, 0x191c, 0x191d, 0x191e, + 0x191f, 0x1942, 0x1943, 0x1944, 0x1945, 0x1946, 0x1947, 0x1958, + 0x1959, 0x19ed, 0x19ee, 0x19ef, 0x19f0, 0x19f1, 0x19f2, 0x19f3, + 0x19f4, 0x19f5, 0x19f6, 0x19f7, 0x1b0e, 0x1b0f, 0x1b62, 0x1b63, + 0x1b64, 0x1b65, 0x1b66, 0x1b67, 0x1b68, 0x1b69, 0x1b6a, 0x1b6b, + 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b82, 0x1ba8, 0x1ba9, 0x1baa, + 0x1bab, 0x1bac, 0x1bad, 0x1bae, 0x1baf, 0x1bb0, 0x1bb1, 0x1bb2, + 0x1bb3, 0x1d80, 0x1d81, 0x1d82, 0x1d83, 0x1d84, 0x1d85, 0x1d86, + 0x1d87, 0x1d88, 0x1d89, 0x1d8a, 0x1d8b, 0x1d8c, 0x1d8d, 0x1007, + 0x1008, 0x1009, 0x100a, 0x100b, 0x100c, 0x100d, 0x100e, 0x100f, + 0x1016, 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, + 0x1087, 0x10c0, 0x123a, 0x123b, 0x123c, 0x123d, 0x123e, 0x123f, + 0x1240, 0x1241, 0x1242, 0x1243, 0x1350, 0x1352, 0x1353, 0x1358, + 0x1359, 0x135a, 0x135b, 0x135c, 0x135d, 0x135e, 0x135f, 0x1360, + 0x1361, 0x1602, 0x1603, 0x160c, 0x160d, 0x160e, 0x160f, 0x1620, + 0x1621, 0x1622, 0x1623, 0x1624, 0x1625, 0x1626, 0x1627, 0x1628, + 0x1629, 0x166e, 0x166f, 0x167c, 0x167d, 0x167e, 0x167f, 0x1770, + 0x1771, 0x1852, 0x1853, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, + 0x1877, 0x1878, 0x1879, 0x187a, 0x187b, 0x187c, 0x187d, 0x187e, + 0x187f, 0x1918, 0x1919, 0x1926, 0x1927, 0x1970, 0x1971, 0x1972, + 0x1973, 0x1974, 0x1975, 0x1976, 0x1977, 0x1978, 0x1979, 0x197a, + 0x197b, 0x1aa0, 0x1aa1, 0x1aa2, 0x1aa3, 0x1aa4, 0x1aa5, 0x1aa6, + 0x1aa7, 0x1aa8, 0x1aa9, 0x1aaa, 0x1aab, 0x1aac, 0x1aad, 0x1b3c, + 0x1b3d, 0x1b3e, 0x1b3f, 0x1b50, 0x1b51, 0x1b52, 0x1b53, 0x1b54, + 0x1b55, 0x1b56, 0x1b57, 0x1b58, 0x1b59, 0x2032, 0x2033, 0x2034, + 0x2035, 0x2036, 0x2037, 0x2038, 0x2039, 0x203a, 0x203b, 0x203c, + 0x203d, 0x203e, 0x203f, 0x2040, 0x2041, 0x2042, 0x2043, 0x20ba, + 0x20bb, 0x20cc, 0x20cd, 0x20ce, 0x20cf, 0x20e0, 0x20e1, 0x20e2, + 0x20e3, 0x20e4, 0x20e5, 0x20e6, 0x20e7, 0x21aa, 0x21ab, 0x21c0, + 0x21c1, 0x21c2, 0x21c3, 0x21c4, 0x21c5, 0x21c6, 0x21c7, 0x21c8, + 0x21c9, 0x21ca, 0x21cb, 0x21cc, 0x21cd, 0x21ce, 0x21cf, 0x21d0, + 0x21d1, 0x21d2, 0x21d3, 0x2894, 0x2895, 0x2896, 0x2897, 0x2898, + 0x2899, 0x289a, 0x289b, 0x289c, 0x289d, 0x289e, 0x289f, 0x28c0, + 0x28c1, 0x28c2, 0x28c3, 0x28c4, 0x28c5, 0x28c6, 0x28c7, 0x28c8, + 0x28c9, 0x28ca, 0x28cb, 0x2930, 0x2931, 0x2932, 0x2933, 0x2934, + 0x2935, 0x2936, 0x2937, 0x2938, 0x2939, 0x293a, 0x293b, 0x293c, + 0x293d, 0x293e, 0x293f, 0x2960, 0x2961, 0x2962, 0x2963, 0x2964, + 0x2965, 0x2966, 0x2967, 0x2968, 0x2969, 0x296a, 0x296b, 0x2a40, + 0x2a41, 0x2a42, 0x2a43, 0x2a44, 0x2a45, 0x2a46, 0x2a47, 0x2a48, + 0x2a49, 0x2a4a, 0x2a4b, 0x2a4c, 0x2a4d, 0x2a4e, 0x2a4f, 0x2a50, + 0x2a51, 0x2a52, 0x2a53, 0x2ae6, 0x2ae7, 0x2b24, 0x2b25, 0x2b26, + 0x2b27, 0x2b28, 0x2b29, 0x2b2a, 0x2b2b, 0x2b2c, 0x2b2d, 0x2b2e, + 0x2b2f, 0x2b30, 0x2b31, 0x2b32, 0x2b33, 0x2b5a, 0x2b5b, 0x3014, + 0x3015, 0x3016, 0x3017, 0x3020, 0x3021, 0x3022, 0x3023, 0x3024, + 0x3025, 0x3026, 0x3027, 0x3028, 0x3029, 0x302a, 0x302b, 0x302c, + 0x302d, 0x302e, 0x302f, 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, + 0x3035, 0x3036, 0x3037, 0x3038, 0x3039, 0x30c0, 0x30c1, 0x30de, + 0x30df, 0x3218, 0x3219, 0x321a, 0x321b, 0x321c, 0x321d, 0x321e, + 0x321f, 0x3220, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226, + 0x3227, 0x3228, 0x3229, 0x322a, 0x322b, 0x322c, 0x322d, 0x322e, + 0x322f, 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3378, + 0x3379, 0x337a, 0x337b, 0x337c, 0x337d, 0x337e, 0x337f, 0x33c0, + 0x33c1, 0x33c2, 0x33c3, 0x33c4, 0x33c5, 0x33c6, 0x33c7, 0x33c8, + 0x33c9, 0x33ca, 0x33cb, 0x33cc, 0x33cd, 0x33ce, 0x33cf, 0x33d0, + 0x33d1, 0x33d2, 0x33d3, 0x33d4, 0x33d5, 0x33d6, 0x33d7, 0x33d8, + 0x33d9, 0x3706, 0x3707, 0x3730, 0x3731, 0x3732, 0x3733, 0x3734, + 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, 0x373a, 0x373b, 0x373c, + 0x373d, 0x373e, 0x373f, 0x3740, 0x3741, 0x3742, 0x3743, 0x3744, + 0x3745, 0x3746, 0x3747, 0x3748, 0x3749, 0x374a, 0x374b, 0x374c, + 0x374d, 0x374e, 0x374f, 0x3b34, 0x3b35, 0x3b36, 0x3b37, 0x3be8, + 0x3be9, 0x3bea, 0x3beb, 0x3bec, 0x3bed, 0x3bee, 0x3bef, 0x3bf0, + 0x3bf1, 0x3bf2, 0x3bf3, 0x3bf4, 0x3bf5, 0x3bf6, 0x3bf7, 0x3bf8, + 0x3bf9, 0x3bfa, 0x3bfb, 0x3bfc, 0x3bfd, 0x3bfe, 0x3bff, 0x2000, + 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, + 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x202e, 0x202f, 0x2182, + 0x2183, 0x21b4, 0x21b5, 0x21b6, 0x21b7, 0x21b8, 0x21b9, 0x21ba, + 0x21bb, 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x2460, 0x2461, 0x2462, + 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246a, + 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, 0x2472, + 0x2473, 0x26a2, 0x26a3, 0x000b, +}; + +static const uint8_t table1_mv_bits[1100] = { + 2, 4, 4, 4, 5, 5, 5, 5, + 6, 6, 7, 7, 7, 7, 7, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 4, +}; + +static const uint8_t table1_mvx[1099] = { + 32, 31, 32, 31, 33, 32, 33, 33, + 31, 34, 30, 32, 32, 34, 35, 32, + 34, 33, 29, 30, 30, 32, 31, 31, + 33, 35, 35, 33, 31, 29, 29, 33, + 34, 30, 31, 28, 36, 30, 34, 32, + 32, 37, 32, 32, 25, 27, 39, 32, + 32, 32, 38, 35, 36, 32, 37, 61, + 26, 32, 34, 35, 3, 35, 27, 28, + 29, 34, 28, 37, 31, 36, 32, 27, + 31, 30, 29, 39, 33, 29, 33, 35, + 25, 25, 29, 33, 31, 31, 31, 33, + 32, 30, 32, 32, 41, 39, 33, 36, + 32, 28, 34, 36, 38, 24, 60, 31, + 23, 28, 32, 33, 59, 32, 40, 30, + 5, 34, 32, 38, 32, 30, 43, 4, + 32, 32, 42, 31, 31, 32, 26, 38, + 26, 22, 21, 37, 61, 63, 37, 31, + 32, 33, 2, 1, 23, 33, 41, 27, + 35, 30, 38, 23, 33, 3, 28, 34, + 34, 27, 41, 29, 39, 35, 36, 29, + 32, 27, 30, 32, 24, 61, 37, 26, + 59, 25, 35, 27, 36, 37, 30, 31, + 34, 40, 3, 28, 34, 39, 32, 31, + 32, 30, 24, 28, 35, 36, 26, 32, + 31, 33, 29, 33, 39, 25, 30, 24, + 35, 59, 29, 34, 25, 30, 21, 35, + 43, 40, 32, 29, 5, 28, 31, 62, + 33, 33, 25, 31, 21, 31, 43, 31, + 34, 33, 20, 40, 39, 31, 31, 57, + 38, 32, 42, 33, 32, 31, 32, 29, + 30, 44, 5, 31, 22, 34, 36, 17, + 38, 58, 38, 35, 32, 60, 35, 24, + 32, 38, 16, 45, 42, 32, 31, 29, + 4, 30, 17, 40, 46, 48, 63, 32, + 42, 19, 41, 22, 28, 36, 45, 33, + 33, 32, 29, 7, 41, 42, 18, 33, + 33, 32, 22, 37, 1, 26, 22, 23, + 49, 28, 26, 27, 32, 33, 27, 23, + 28, 36, 15, 6, 34, 27, 31, 26, + 23, 2, 33, 32, 34, 41, 28, 32, + 41, 0, 36, 38, 34, 31, 47, 32, + 17, 31, 39, 33, 37, 51, 30, 47, + 32, 50, 32, 19, 63, 30, 25, 27, + 33, 62, 24, 31, 27, 30, 37, 31, + 45, 32, 39, 20, 46, 47, 35, 19, + 34, 1, 49, 21, 21, 14, 51, 26, + 23, 31, 36, 35, 58, 29, 29, 21, + 20, 42, 13, 28, 12, 40, 31, 33, + 39, 60, 32, 44, 33, 31, 28, 37, + 29, 32, 30, 49, 43, 28, 39, 25, + 32, 48, 2, 15, 20, 25, 31, 28, + 21, 24, 25, 15, 31, 17, 37, 43, + 18, 32, 33, 24, 33, 36, 13, 33, + 31, 39, 11, 31, 33, 32, 39, 37, + 32, 32, 29, 17, 44, 46, 36, 35, + 26, 37, 58, 32, 34, 38, 8, 38, + 38, 22, 29, 25, 16, 35, 32, 35, + 33, 43, 18, 46, 38, 50, 33, 18, + 53, 60, 13, 32, 36, 33, 51, 36, + 43, 45, 27, 42, 29, 24, 30, 25, + 31, 52, 31, 35, 38, 9, 22, 34, + 4, 17, 28, 55, 42, 25, 17, 20, + 47, 34, 33, 16, 40, 25, 16, 30, + 53, 29, 10, 11, 14, 26, 33, 4, + 35, 44, 26, 16, 31, 26, 34, 38, + 29, 31, 30, 24, 22, 61, 32, 9, + 45, 34, 31, 19, 9, 31, 46, 31, + 35, 54, 29, 57, 30, 50, 3, 31, + 63, 34, 47, 41, 51, 18, 31, 14, + 37, 38, 31, 24, 32, 31, 50, 33, + 31, 54, 27, 9, 33, 23, 19, 32, + 29, 29, 33, 28, 47, 49, 30, 47, + 33, 27, 25, 54, 44, 45, 50, 58, + 51, 48, 33, 59, 33, 34, 57, 13, + 26, 33, 13, 48, 30, 11, 7, 56, + 34, 55, 26, 0, 26, 35, 1, 51, + 33, 53, 31, 45, 12, 29, 29, 51, + 31, 48, 2, 6, 34, 30, 28, 33, + 60, 40, 27, 46, 31, 9, 35, 29, + 31, 39, 55, 46, 19, 37, 62, 34, + 30, 16, 19, 49, 41, 41, 39, 37, + 14, 5, 13, 35, 55, 30, 40, 40, + 42, 8, 20, 25, 45, 35, 33, 36, + 54, 38, 27, 37, 62, 40, 15, 59, + 49, 31, 29, 34, 34, 39, 24, 29, + 25, 29, 21, 29, 10, 61, 33, 49, + 35, 34, 3, 38, 39, 29, 7, 41, + 1, 35, 4, 23, 15, 23, 11, 37, + 28, 35, 30, 30, 24, 1, 43, 56, + 8, 34, 42, 24, 45, 30, 20, 23, + 8, 38, 22, 33, 17, 52, 34, 22, + 53, 43, 44, 1, 27, 31, 41, 43, + 41, 30, 31, 36, 30, 5, 55, 31, + 33, 30, 40, 23, 15, 29, 34, 34, + 59, 34, 30, 11, 13, 38, 5, 0, + 30, 42, 5, 30, 29, 34, 10, 44, + 30, 63, 35, 12, 3, 26, 15, 17, + 25, 34, 43, 39, 34, 56, 29, 23, + 30, 12, 30, 10, 35, 9, 24, 58, + 10, 12, 54, 33, 37, 20, 41, 35, + 29, 18, 61, 30, 40, 24, 39, 53, + 62, 26, 29, 33, 34, 53, 49, 21, + 27, 11, 63, 20, 26, 23, 7, 13, + 6, 47, 29, 30, 9, 51, 22, 34, + 21, 25, 33, 56, 57, 30, 38, 51, + 51, 38, 63, 28, 40, 35, 33, 18, + 33, 33, 24, 58, 58, 34, 49, 29, + 43, 4, 1, 4, 42, 35, 35, 30, + 17, 5, 56, 61, 25, 37, 36, 55, + 28, 35, 29, 50, 48, 52, 2, 42, + 34, 40, 46, 46, 43, 35, 29, 48, + 20, 29, 31, 41, 7, 30, 35, 19, + 14, 21, 8, 39, 39, 40, 46, 55, + 34, 6, 30, 34, 37, 25, 37, 33, + 22, 44, 52, 17, 35, 29, 36, 35, + 40, 37, 28, 30, 50, 14, 28, 55, + 6, 23, 19, 14, 30, 3, 30, 28, + 28, 61, 61, 47, 45, 48, 40, 40, + 34, 34, 25, 30, 29, 35, 4, 26, + 53, 50, 26, 41, 27, 59, 27, 38, + 39, 3, 50, 43, 47, 23, 33, 55, + 35, 21, 23, 35, 61, 33, 46, 52, + 35, 34, 24, 30, 43, 16, 37, 21, + 2, 24, 45, 34, 30, 55, 55, 1, + 29, 29, 26, 28, 25, 31, 36, 22, + 17, 30, 52, 2, 44, 44, 57, 26, + 62, 41, 39, 57, 26, 46, 49, 11, + 16, 19, 5, 59, 38, 39, 58, 38, + 25, 49, 50, 22, 28, 59, 9, 59, + 7, 28, 55, 17, 4, 35, 50, 21, + 29, 44, 47, 18, 24, 19, 25, 42, + 35, 3, 51, 35, 16, 35, 30, 63, + 57, 39, 39, 25, 35, 38, 9, 16, + 36, 45, 31, 60, 14, 34, 42, 24, + 0, 37, 18, 61, 57, 37, 28, 53, + 20, 46, 14, 47, 38, 38, 38, 9, + 34, 39, 43, 17, 39, 59, 5, 27, + 0, 12, 27, +}; + +static const uint8_t table1_mvy[1099] = { + 32, 32, 31, 31, 32, 33, 31, 33, + 33, 32, 32, 30, 34, 31, 32, 29, + 33, 30, 32, 33, 31, 35, 34, 30, + 34, 31, 33, 29, 29, 31, 33, 35, + 30, 30, 35, 32, 32, 34, 34, 28, + 25, 32, 36, 27, 32, 32, 32, 37, + 39, 3, 32, 30, 31, 26, 31, 32, + 32, 38, 29, 29, 32, 34, 31, 31, + 34, 35, 33, 33, 28, 33, 1, 33, + 27, 29, 30, 31, 28, 29, 37, 35, + 31, 33, 35, 27, 36, 37, 25, 25, + 61, 35, 4, 5, 32, 33, 36, 30, + 23, 30, 28, 34, 31, 32, 32, 39, + 32, 34, 21, 39, 32, 59, 32, 28, + 32, 36, 60, 33, 24, 36, 32, 32, + 41, 2, 32, 38, 26, 22, 33, 30, + 31, 32, 32, 30, 31, 32, 29, 3, + 40, 38, 32, 32, 33, 26, 31, 34, + 28, 38, 34, 31, 3, 31, 35, 38, + 27, 35, 33, 28, 29, 27, 29, 27, + 43, 29, 37, 63, 31, 33, 34, 30, + 31, 30, 37, 30, 35, 35, 26, 41, + 37, 31, 33, 28, 26, 30, 42, 24, + 7, 27, 33, 29, 36, 28, 34, 57, + 23, 41, 36, 23, 35, 34, 25, 30, + 25, 33, 25, 25, 29, 24, 33, 39, + 33, 33, 0, 37, 31, 36, 21, 32, + 61, 24, 35, 61, 31, 5, 31, 59, + 39, 21, 32, 30, 34, 22, 40, 32, + 29, 16, 31, 5, 62, 2, 20, 39, + 39, 32, 33, 1, 31, 24, 36, 32, + 36, 32, 28, 26, 6, 31, 38, 34, + 58, 35, 32, 33, 33, 17, 43, 26, + 31, 40, 31, 34, 32, 32, 31, 19, + 30, 32, 29, 33, 38, 38, 32, 59, + 40, 18, 38, 32, 35, 34, 32, 17, + 1, 15, 30, 28, 31, 28, 34, 29, + 32, 27, 35, 27, 49, 22, 37, 34, + 37, 26, 32, 32, 22, 28, 45, 29, + 30, 31, 43, 46, 41, 30, 26, 13, + 34, 32, 27, 38, 42, 42, 33, 47, + 33, 60, 27, 42, 25, 32, 22, 32, + 48, 32, 45, 33, 33, 41, 27, 25, + 19, 31, 35, 19, 36, 42, 27, 17, + 31, 44, 28, 33, 33, 31, 23, 31, + 40, 33, 31, 34, 30, 32, 33, 36, + 35, 47, 37, 41, 31, 23, 41, 29, + 30, 35, 32, 25, 32, 28, 58, 2, + 37, 33, 14, 33, 49, 20, 39, 36, + 21, 9, 23, 33, 35, 24, 39, 37, + 11, 33, 30, 31, 31, 28, 51, 40, + 35, 29, 25, 33, 46, 35, 37, 30, + 30, 8, 63, 28, 15, 40, 33, 45, + 49, 25, 32, 4, 47, 51, 36, 39, + 53, 10, 24, 29, 30, 31, 25, 40, + 38, 38, 33, 56, 23, 27, 32, 37, + 26, 29, 43, 36, 33, 24, 55, 43, + 9, 29, 34, 34, 24, 33, 18, 33, + 33, 30, 31, 50, 24, 60, 30, 39, + 34, 30, 39, 28, 22, 38, 2, 26, + 63, 32, 57, 21, 39, 33, 28, 18, + 30, 34, 22, 33, 29, 41, 30, 34, + 35, 21, 13, 34, 35, 39, 30, 46, + 32, 42, 32, 31, 33, 26, 11, 33, + 22, 31, 25, 31, 53, 27, 43, 25, + 40, 50, 21, 36, 38, 30, 12, 31, + 34, 20, 15, 29, 32, 62, 30, 13, + 17, 32, 19, 31, 20, 31, 30, 7, + 1, 17, 34, 37, 31, 31, 44, 34, + 26, 40, 16, 37, 52, 48, 30, 20, + 18, 33, 38, 29, 7, 25, 30, 54, + 45, 47, 46, 41, 29, 29, 16, 30, + 14, 26, 38, 34, 34, 29, 34, 30, + 29, 30, 57, 30, 4, 46, 33, 29, + 39, 44, 30, 31, 50, 33, 31, 32, + 19, 32, 40, 31, 37, 47, 1, 35, + 16, 31, 0, 35, 33, 1, 17, 34, + 9, 34, 33, 31, 49, 43, 42, 51, + 34, 29, 23, 29, 14, 30, 45, 49, + 11, 24, 31, 28, 35, 41, 30, 44, + 18, 29, 34, 35, 36, 25, 26, 21, + 31, 30, 34, 19, 34, 44, 36, 38, + 25, 31, 28, 23, 37, 3, 55, 41, + 30, 22, 41, 24, 33, 26, 35, 35, + 30, 55, 51, 47, 48, 38, 24, 15, + 21, 50, 25, 46, 30, 29, 10, 34, + 42, 45, 29, 42, 22, 3, 33, 27, + 34, 1, 34, 28, 34, 36, 35, 23, + 23, 13, 58, 3, 26, 63, 25, 31, + 34, 61, 38, 39, 25, 61, 29, 37, + 30, 41, 26, 48, 28, 33, 50, 35, + 30, 37, 29, 29, 40, 6, 39, 28, + 28, 19, 8, 22, 45, 34, 35, 10, + 58, 17, 37, 39, 30, 18, 54, 14, + 29, 16, 59, 30, 35, 23, 35, 30, + 47, 36, 29, 55, 20, 12, 31, 35, + 14, 29, 18, 34, 34, 24, 29, 26, + 22, 2, 27, 23, 8, 30, 55, 38, + 60, 31, 4, 34, 49, 34, 27, 34, + 33, 30, 31, 54, 42, 35, 38, 46, + 44, 26, 27, 9, 39, 25, 21, 29, + 28, 42, 13, 0, 5, 34, 37, 28, + 24, 29, 63, 26, 22, 27, 29, 25, + 33, 25, 61, 0, 35, 25, 36, 15, + 27, 40, 53, 33, 3, 10, 16, 37, + 38, 18, 30, 46, 27, 9, 6, 29, + 62, 8, 42, 28, 29, 3, 25, 16, + 26, 29, 35, 28, 27, 51, 61, 48, + 37, 9, 34, 7, 49, 45, 20, 29, + 21, 5, 5, 29, 28, 34, 29, 24, + 10, 24, 35, 36, 38, 55, 11, 36, + 38, 53, 54, 26, 30, 49, 20, 27, + 30, 39, 33, 41, 49, 22, 38, 38, + 4, 30, 8, 9, 3, 24, 22, 50, + 37, 36, 31, 27, 2, 9, 42, 63, + 25, 19, 44, 1, 28, 28, 48, 30, + 34, 41, 41, 38, 12, 27, 15, 0, + 16, 34, 35, 38, 28, 29, 40, 42, + 51, 52, 45, 54, 59, 59, 42, 44, + 37, 26, 46, 24, 15, 39, 22, 46, + 19, 35, 38, 17, 37, 23, 52, 55, + 50, 37, 26, 11, 37, 12, 24, 30, + 16, 13, 22, 13, 36, 35, 40, 41, + 34, 41, 26, 53, 51, 5, 21, 30, + 2, 63, 41, 20, 1, 56, 21, 24, + 25, 5, 28, 35, 26, 28, 30, 18, + 29, 23, 40, 34, 20, 42, 39, 34, + 28, 61, 38, 27, 62, 9, 36, 17, + 9, 49, 24, 25, 54, 34, 39, 37, + 3, 1, 25, 38, 38, 44, 35, 36, + 12, 60, 36, 38, 40, 25, 43, 39, + 53, 28, 39, 57, 46, 10, 52, 27, + 35, 42, 45, 59, 15, 60, 38, 24, + 23, 39, 12, 29, 24, 0, 20, 16, + 28, 43, 35, 28, 1, 49, 4, 21, + 42, 39, 29, 3, 44, 21, 53, 55, + 11, 5, 3, 39, 53, 28, 25, 19, + 34, 28, 21, +}; + +MVTable mv_tables[2] = { + { + 1099, + table0_mv_code, + table0_mv_bits, + table0_mvx, + table0_mvy, + }, + { + 1099, + table1_mv_code, + table1_mv_bits, + table1_mvx, + table1_mvy, + } +}; + +const uint8_t v2_mb_type[8][2] = { + {1, 1}, {0 , 2}, {3 , 3}, {9 , 5}, + {5, 4}, {0x21, 7}, {0x20, 7}, {0x11, 6}, +}; + +const uint8_t v2_intra_cbpc[4][2] = { + {1, 1}, {0, 3}, {1, 3}, {1, 2}, +}; + +const uint8_t wmv1_y_dc_scale_table[32]={ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + 0, 8, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21 +}; +const uint8_t wmv1_c_dc_scale_table[32]={ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 + 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22 +}; + +const uint8_t old_ff_y_dc_scale_table[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 8, 8, 8, 8,10,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 +}; +const uint8_t old_ff_c_dc_scale_table[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22 +}; + +const uint8_t wmv1_scantable[WMV1_SCANTABLE_COUNT][64]={ + { + 0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, + 0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28, + 0x30, 0x38, 0x29, 0x21, 0x1A, 0x13, 0x0C, 0x05, + 0x06, 0x0D, 0x14, 0x1B, 0x22, 0x31, 0x39, 0x3A, + 0x32, 0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, + 0x16, 0x1D, 0x24, 0x2B, 0x33, 0x3B, 0x3C, 0x34, + 0x2C, 0x25, 0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x35, + 0x3D, 0x3E, 0x36, 0x2E, 0x27, 0x2F, 0x37, 0x3F, + }, + { + 0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, + 0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28, + 0x21, 0x30, 0x1A, 0x13, 0x0C, 0x05, 0x06, 0x0D, + 0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39, 0x2A, + 0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, 0x16, 0x1D, + 0x24, 0x2B, 0x32, 0x3A, 0x33, 0x3B, 0x2C, 0x25, + 0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3C, 0x35, + 0x3D, 0x2E, 0x27, 0x2F, 0x36, 0x3E, 0x37, 0x3F, + }, + { + 0x00, 0x01, 0x08, 0x02, 0x03, 0x09, 0x10, 0x18, + 0x11, 0x0A, 0x04, 0x05, 0x0B, 0x12, 0x19, 0x20, + 0x28, 0x30, 0x21, 0x1A, 0x13, 0x0C, 0x06, 0x07, + 0x0D, 0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39, + 0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x0F, 0x16, 0x1D, + 0x24, 0x2B, 0x32, 0x3A, 0x33, 0x2C, 0x25, 0x1E, + 0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x3C, 0x35, + 0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F, + }, + { + 0x00, 0x08, 0x10, 0x01, 0x18, 0x20, 0x28, 0x09, + 0x02, 0x03, 0x0A, 0x11, 0x19, 0x30, 0x38, 0x29, + 0x21, 0x1A, 0x12, 0x0B, 0x04, 0x05, 0x0C, 0x13, + 0x1B, 0x22, 0x31, 0x39, 0x32, 0x2A, 0x23, 0x1C, + 0x14, 0x0D, 0x06, 0x07, 0x0E, 0x15, 0x1D, 0x24, + 0x2B, 0x33, 0x3A, 0x3B, 0x34, 0x2C, 0x25, 0x1E, + 0x16, 0x0F, 0x17, 0x1F, 0x26, 0x2D, 0x3C, 0x35, + 0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F, + } +}; + +const uint8_t table_inter_intra[4][2]={ + {0,1} /*Luma-Left Chroma-Left*/, + {2,2} /*Luma-Top Chroma-Left*/, + {6,3} /*luma-Left Chroma-Top */, + {7,3} /*luma-Top Chroma-Top */ +}; + +static const uint32_t table_mb_non_intra2[128][2] = { +{0x0000A7, 14}, {0x01B2B8, 18}, {0x01B28E, 18}, {0x036575, 19}, +{0x006CAC, 16}, {0x000A69, 18}, {0x002934, 20}, {0x00526B, 21}, +{0x006CA1, 16}, {0x01B2B9, 18}, {0x0029AD, 20}, {0x029353, 24}, +{0x006CA7, 16}, {0x006CAB, 16}, {0x01B2BB, 18}, {0x00029B, 16}, +{0x00D944, 17}, {0x000A6A, 18}, {0x0149A8, 23}, {0x03651F, 19}, +{0x006CAF, 16}, {0x000A4C, 18}, {0x03651E, 19}, {0x000A48, 18}, +{0x00299C, 20}, {0x00299F, 20}, {0x029352, 24}, {0x0029AC, 20}, +{0x000296, 16}, {0x00D946, 17}, {0x000A68, 18}, {0x000298, 16}, +{0x000527, 17}, {0x00D94D, 17}, {0x0014D7, 19}, {0x036574, 19}, +{0x000A5C, 18}, {0x01B299, 18}, {0x00299D, 20}, {0x00299E, 20}, +{0x000525, 17}, {0x000A66, 18}, {0x00A4D5, 22}, {0x00149B, 19}, +{0x000295, 16}, {0x006CAD, 16}, {0x000A49, 18}, {0x000521, 17}, +{0x006CAA, 16}, {0x00D945, 17}, {0x01B298, 18}, {0x00052F, 17}, +{0x003654, 15}, {0x006CA0, 16}, {0x000532, 17}, {0x000291, 16}, +{0x003652, 15}, {0x000520, 17}, {0x000A5D, 18}, {0x000294, 16}, +{0x00009B, 11}, {0x0006E2, 12}, {0x000028, 12}, {0x0001B0, 10}, +{0x000001, 3}, {0x000010, 8}, {0x00002F, 6}, {0x00004C, 10}, +{0x00000D, 4}, {0x000000, 10}, {0x000006, 9}, {0x000134, 12}, +{0x00000C, 4}, {0x000007, 10}, {0x000007, 9}, {0x0006E1, 12}, +{0x00000E, 5}, {0x0000DA, 9}, {0x000022, 9}, {0x000364, 11}, +{0x00000F, 4}, {0x000006, 10}, {0x00000F, 9}, {0x000135, 12}, +{0x000014, 5}, {0x0000DD, 9}, {0x000004, 9}, {0x000015, 11}, +{0x00001A, 6}, {0x0001B3, 10}, {0x000005, 10}, {0x0006E3, 12}, +{0x00000C, 5}, {0x0000B9, 8}, {0x000004, 8}, {0x0000DB, 9}, +{0x00000E, 4}, {0x00000B, 10}, {0x000023, 9}, {0x0006CB, 12}, +{0x000005, 6}, {0x0001B1, 10}, {0x000001, 10}, {0x0006E0, 12}, +{0x000011, 5}, {0x0000DF, 9}, {0x00000E, 9}, {0x000373, 11}, +{0x000003, 5}, {0x0000B8, 8}, {0x000006, 8}, {0x000175, 9}, +{0x000015, 5}, {0x000174, 9}, {0x000027, 9}, {0x000372, 11}, +{0x000010, 5}, {0x0000BB, 8}, {0x000005, 8}, {0x0000DE, 9}, +{0x00000F, 5}, {0x000001, 9}, {0x000012, 8}, {0x000004, 10}, +{0x000002, 3}, {0x000016, 5}, {0x000009, 4}, {0x000001, 5}, +}; + +static const uint32_t table_mb_non_intra3[128][2] = { +{0x0002A1, 10}, {0x005740, 15}, {0x01A0BF, 18}, {0x015D19, 17}, +{0x001514, 13}, {0x00461E, 15}, {0x015176, 17}, {0x015177, 17}, +{0x0011AD, 13}, {0x00682E, 16}, {0x0682F9, 20}, {0x03417D, 19}, +{0x001A36, 14}, {0x002A2D, 14}, {0x00D05E, 17}, {0x006824, 16}, +{0x001515, 13}, {0x00545C, 15}, {0x0230E9, 18}, {0x011AFA, 17}, +{0x0015D7, 13}, {0x005747, 15}, {0x008D79, 16}, {0x006825, 16}, +{0x002BA2, 14}, {0x00A8BA, 16}, {0x0235F6, 18}, {0x015D18, 17}, +{0x0011AE, 13}, {0x00346F, 15}, {0x008C3B, 16}, {0x00346E, 15}, +{0x000D1A, 13}, {0x00461F, 15}, {0x0682F8, 20}, {0x011875, 17}, +{0x002BA1, 14}, {0x008D61, 16}, {0x0235F7, 18}, {0x0230E8, 18}, +{0x001513, 13}, {0x008D7B, 16}, {0x011AF4, 17}, {0x011AF5, 17}, +{0x001185, 13}, {0x0046BF, 15}, {0x008D60, 16}, {0x008D7C, 16}, +{0x001512, 13}, {0x00461C, 15}, {0x00AE8D, 16}, {0x008D78, 16}, +{0x000D0E, 13}, {0x003413, 15}, {0x0046B1, 15}, {0x003416, 15}, +{0x000AEA, 12}, {0x002A2C, 14}, {0x005741, 15}, {0x002A2F, 14}, +{0x000158, 9}, {0x0008D2, 12}, {0x00054C, 11}, {0x000686, 12}, +{0x000000, 2}, {0x000069, 8}, {0x00006B, 8}, {0x00068C, 12}, +{0x000007, 3}, {0x00015E, 9}, {0x0002A3, 10}, {0x000AE9, 12}, +{0x000006, 3}, {0x000231, 10}, {0x0002B8, 10}, {0x001A08, 14}, +{0x000010, 5}, {0x0001A9, 10}, {0x000342, 11}, {0x000A88, 12}, +{0x000004, 4}, {0x0001A2, 10}, {0x0002A4, 10}, {0x001184, 13}, +{0x000012, 5}, {0x000232, 10}, {0x0002B2, 10}, {0x000680, 12}, +{0x00001B, 6}, {0x00046A, 11}, {0x00068E, 12}, {0x002359, 14}, +{0x000016, 5}, {0x00015F, 9}, {0x0002A0, 10}, {0x00054D, 11}, +{0x000005, 4}, {0x000233, 10}, {0x0002B9, 10}, {0x0015D6, 13}, +{0x000022, 6}, {0x000468, 11}, {0x000683, 12}, {0x001A0A, 14}, +{0x000013, 5}, {0x000236, 10}, {0x0002BB, 10}, {0x001186, 13}, +{0x000017, 5}, {0x0001AB, 10}, {0x0002A7, 10}, {0x0008D3, 12}, +{0x000014, 5}, {0x000237, 10}, {0x000460, 11}, {0x000D0F, 13}, +{0x000019, 6}, {0x0001AA, 10}, {0x0002B3, 10}, {0x000681, 12}, +{0x000018, 6}, {0x0001A8, 10}, {0x0002A5, 10}, {0x00068F, 12}, +{0x000007, 4}, {0x000055, 7}, {0x000047, 7}, {0x0000AD, 8}, +}; + +static const uint32_t table_mb_non_intra4[128][2] = { +{0x0000D4, 8}, {0x0021C5, 14}, {0x00F18A, 16}, {0x00D5BC, 16}, +{0x000879, 12}, {0x00354D, 14}, {0x010E3F, 17}, {0x010F54, 17}, +{0x000866, 12}, {0x00356E, 14}, {0x010F55, 17}, {0x010E3E, 17}, +{0x0010CE, 13}, {0x003C84, 14}, {0x00D5BD, 16}, {0x00F18B, 16}, +{0x000868, 12}, {0x00438C, 15}, {0x0087AB, 16}, {0x00790B, 15}, +{0x000F10, 12}, {0x00433D, 15}, {0x006AD3, 15}, {0x00790A, 15}, +{0x001AA7, 13}, {0x0043D4, 15}, {0x00871E, 16}, {0x006ADF, 15}, +{0x000D7C, 12}, {0x003C94, 14}, {0x00438D, 15}, {0x006AD2, 15}, +{0x0006BC, 11}, {0x0021E9, 14}, {0x006ADA, 15}, {0x006A99, 15}, +{0x0010F7, 13}, {0x004389, 15}, {0x006ADB, 15}, {0x0078C4, 15}, +{0x000D56, 12}, {0x0035F7, 14}, {0x00438E, 15}, {0x006A98, 15}, +{0x000D52, 12}, {0x003C95, 14}, {0x004388, 15}, {0x00433C, 15}, +{0x000D54, 12}, {0x001E4B, 13}, {0x003C63, 14}, {0x003C83, 14}, +{0x000861, 12}, {0x0021EB, 14}, {0x00356C, 14}, {0x0035F6, 14}, +{0x000863, 12}, {0x00219F, 14}, {0x003568, 14}, {0x003C82, 14}, +{0x0001AE, 9}, {0x0010C0, 13}, {0x000F11, 12}, {0x001AFA, 13}, +{0x000000, 1}, {0x0000F0, 8}, {0x0001AD, 9}, {0x0010C1, 13}, +{0x00000A, 4}, {0x0003C5, 10}, {0x000789, 11}, {0x001AB5, 13}, +{0x000009, 4}, {0x000435, 11}, {0x000793, 11}, {0x001E40, 13}, +{0x00001D, 5}, {0x0003CB, 10}, {0x000878, 12}, {0x001AAF, 13}, +{0x00000B, 4}, {0x0003C7, 10}, {0x000791, 11}, {0x001AAB, 13}, +{0x00001F, 5}, {0x000436, 11}, {0x0006BF, 11}, {0x000F19, 12}, +{0x00003D, 6}, {0x000D51, 12}, {0x0010C4, 13}, {0x0021E8, 14}, +{0x000036, 6}, {0x000437, 11}, {0x0006AF, 11}, {0x0010C5, 13}, +{0x00000C, 4}, {0x000432, 11}, {0x000794, 11}, {0x001E30, 13}, +{0x000042, 7}, {0x000870, 12}, {0x000F24, 12}, {0x001E43, 13}, +{0x000020, 6}, {0x00043E, 11}, {0x000795, 11}, {0x001AAA, 13}, +{0x000037, 6}, {0x0006AC, 11}, {0x0006AE, 11}, {0x0010F6, 13}, +{0x000034, 6}, {0x00043A, 11}, {0x000D50, 12}, {0x001AAE, 13}, +{0x000039, 6}, {0x00043F, 11}, {0x00078D, 11}, {0x0010D2, 13}, +{0x000038, 6}, {0x00043B, 11}, {0x0006BD, 11}, {0x0010D3, 13}, +{0x000011, 5}, {0x0001AC, 9}, {0x0000F3, 8}, {0x000439, 11}, +}; + +const uint32_t (*wmv2_inter_table[WMV2_INTER_CBP_TABLE_COUNT])[2]={ + table_mb_non_intra2, + table_mb_non_intra3, + table_mb_non_intra4, + table_mb_non_intra, +}; + +const uint8_t wmv2_scantableA[64]={ +0x00, 0x01, 0x02, 0x08, 0x03, 0x09, 0x0A, 0x10, +0x04, 0x0B, 0x11, 0x18, 0x12, 0x0C, 0x05, 0x13, +0x19, 0x0D, 0x14, 0x1A, 0x1B, 0x06, 0x15, 0x1C, +0x0E, 0x16, 0x1D, 0x07, 0x1E, 0x0F, 0x17, 0x1F, +}; + +const uint8_t wmv2_scantableB[64]={ +0x00, 0x08, 0x01, 0x10, 0x09, 0x18, 0x11, 0x02, +0x20, 0x0A, 0x19, 0x28, 0x12, 0x30, 0x21, 0x1A, +0x38, 0x29, 0x22, 0x03, 0x31, 0x39, 0x0B, 0x2A, +0x13, 0x32, 0x1B, 0x3A, 0x23, 0x2B, 0x33, 0x3B, +}; diff --git a/contrib/ffmpeg/libavcodec/msmpeg4data.h b/contrib/ffmpeg/libavcodec/msmpeg4data.h index d1ff70371..9bfb1ba99 100644 --- a/contrib/ffmpeg/libavcodec/msmpeg4data.h +++ b/contrib/ffmpeg/libavcodec/msmpeg4data.h @@ -3,6 +3,8 @@ * copyright (c) 2001 Fabrice Bellard * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * + * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,8 +20,6 @@ * 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 - * - * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> */ /** @@ -27,1764 +27,12 @@ * MSMPEG4 data tables. */ -/* intra picture macro block coded block pattern */ -const uint16_t ff_msmp4_mb_i_table[64][2] = { -{ 0x1, 1 },{ 0x17, 6 },{ 0x9, 5 },{ 0x5, 5 }, -{ 0x6, 5 },{ 0x47, 9 },{ 0x20, 7 },{ 0x10, 7 }, -{ 0x2, 5 },{ 0x7c, 9 },{ 0x3a, 7 },{ 0x1d, 7 }, -{ 0x2, 6 },{ 0xec, 9 },{ 0x77, 8 },{ 0x0, 8 }, -{ 0x3, 5 },{ 0xb7, 9 },{ 0x2c, 7 },{ 0x13, 7 }, -{ 0x1, 6 },{ 0x168, 10 },{ 0x46, 8 },{ 0x3f, 8 }, -{ 0x1e, 6 },{ 0x712, 13 },{ 0xb5, 9 },{ 0x42, 8 }, -{ 0x22, 7 },{ 0x1c5, 11 },{ 0x11e, 10 },{ 0x87, 9 }, -{ 0x6, 4 },{ 0x3, 9 },{ 0x1e, 7 },{ 0x1c, 6 }, -{ 0x12, 7 },{ 0x388, 12 },{ 0x44, 9 },{ 0x70, 9 }, -{ 0x1f, 6 },{ 0x23e, 11 },{ 0x39, 8 },{ 0x8e, 9 }, -{ 0x1, 7 },{ 0x1c6, 11 },{ 0xb6, 9 },{ 0x45, 9 }, -{ 0x14, 6 },{ 0x23f, 11 },{ 0x7d, 9 },{ 0x18, 9 }, -{ 0x7, 7 },{ 0x1c7, 11 },{ 0x86, 9 },{ 0x19, 9 }, -{ 0x15, 6 },{ 0x1db, 10 },{ 0x2, 9 },{ 0x46, 9 }, -{ 0xd, 8 },{ 0x713, 13 },{ 0x1da, 10 },{ 0x169, 10 }, -}; - -/* non intra picture macro block coded block pattern + mb type */ -static const uint32_t table_mb_non_intra[128][2] = { -{ 0x40, 7 },{ 0x13c9, 13 },{ 0x9fd, 12 },{ 0x1fc, 15 }, -{ 0x9fc, 12 },{ 0xa83, 18 },{ 0x12d34, 17 },{ 0x83bc, 16 }, -{ 0x83a, 12 },{ 0x7f8, 17 },{ 0x3fd, 16 },{ 0x3ff, 16 }, -{ 0x79, 13 },{ 0xa82, 18 },{ 0x969d, 16 },{ 0x2a4, 16 }, -{ 0x978, 12 },{ 0x543, 17 },{ 0x41df, 15 },{ 0x7f9, 17 }, -{ 0x12f3, 13 },{ 0x25a6b, 18 },{ 0x25ef9, 18 },{ 0x3fa, 16 }, -{ 0x20ee, 14 },{ 0x969ab, 20 },{ 0x969c, 16 },{ 0x25ef8, 18 }, -{ 0x12d2, 13 },{ 0xa85, 18 },{ 0x969e, 16 },{ 0x4bc8, 15 }, -{ 0x3d, 12 },{ 0x12f7f, 17 },{ 0x2a2, 16 },{ 0x969f, 16 }, -{ 0x25ee, 14 },{ 0x12d355, 21 },{ 0x12f7d, 17 },{ 0x12f7e, 17 }, -{ 0x9e5, 12 },{ 0xa81, 18 },{ 0x4b4d4, 19 },{ 0x83bd, 16 }, -{ 0x78, 13 },{ 0x969b, 16 },{ 0x3fe, 16 },{ 0x2a5, 16 }, -{ 0x7e, 13 },{ 0xa80, 18 },{ 0x2a3, 16 },{ 0x3fb, 16 }, -{ 0x1076, 13 },{ 0xa84, 18 },{ 0x153, 15 },{ 0x4bc9, 15 }, -{ 0x55, 13 },{ 0x12d354, 21 },{ 0x4bde, 15 },{ 0x25e5, 14 }, -{ 0x25b, 10 },{ 0x4b4c, 15 },{ 0x96b, 12 },{ 0x96a, 12 }, -{ 0x1, 2 },{ 0x0, 7 },{ 0x26, 6 },{ 0x12b, 9 }, -{ 0x7, 3 },{ 0x20f, 10 },{ 0x4, 9 },{ 0x28, 12 }, -{ 0x6, 3 },{ 0x20a, 10 },{ 0x128, 9 },{ 0x2b, 12 }, -{ 0x11, 5 },{ 0x1b, 11 },{ 0x13a, 9 },{ 0x4ff, 11 }, -{ 0x3, 4 },{ 0x277, 10 },{ 0x106, 9 },{ 0x839, 12 }, -{ 0xb, 4 },{ 0x27b, 10 },{ 0x12c, 9 },{ 0x4bf, 11 }, -{ 0x9, 6 },{ 0x35, 12 },{ 0x27e, 10 },{ 0x13c8, 13 }, -{ 0x1, 6 },{ 0x4aa, 11 },{ 0x208, 10 },{ 0x29, 12 }, -{ 0x1, 4 },{ 0x254, 10 },{ 0x12e, 9 },{ 0x838, 12 }, -{ 0x24, 6 },{ 0x4f3, 11 },{ 0x276, 10 },{ 0x12f6, 13 }, -{ 0x1, 5 },{ 0x27a, 10 },{ 0x13e, 9 },{ 0x3e, 12 }, -{ 0x8, 6 },{ 0x413, 11 },{ 0xc, 10 },{ 0x4be, 11 }, -{ 0x14, 5 },{ 0x412, 11 },{ 0x253, 10 },{ 0x97a, 12 }, -{ 0x21, 6 },{ 0x4ab, 11 },{ 0x20b, 10 },{ 0x34, 12 }, -{ 0x15, 5 },{ 0x278, 10 },{ 0x252, 10 },{ 0x968, 12 }, -{ 0x5, 5 },{ 0xb, 10 },{ 0x9c, 8 },{ 0xe, 10 }, -}; - -/* dc table 0 */ - -const uint32_t ff_table0_dc_lum[120][2] = { -{ 0x1, 1 },{ 0x1, 2 },{ 0x1, 4 },{ 0x1, 5 }, -{ 0x5, 5 },{ 0x7, 5 },{ 0x8, 6 },{ 0xc, 6 }, -{ 0x0, 7 },{ 0x2, 7 },{ 0x12, 7 },{ 0x1a, 7 }, -{ 0x3, 8 },{ 0x7, 8 },{ 0x27, 8 },{ 0x37, 8 }, -{ 0x5, 9 },{ 0x4c, 9 },{ 0x6c, 9 },{ 0x6d, 9 }, -{ 0x8, 10 },{ 0x19, 10 },{ 0x9b, 10 },{ 0x1b, 10 }, -{ 0x9a, 10 },{ 0x13, 11 },{ 0x34, 11 },{ 0x35, 11 }, -{ 0x61, 12 },{ 0x48, 13 },{ 0xc4, 13 },{ 0x4a, 13 }, -{ 0xc6, 13 },{ 0xc7, 13 },{ 0x92, 14 },{ 0x18b, 14 }, -{ 0x93, 14 },{ 0x183, 14 },{ 0x182, 14 },{ 0x96, 14 }, -{ 0x97, 14 },{ 0x180, 14 },{ 0x314, 15 },{ 0x315, 15 }, -{ 0x605, 16 },{ 0x604, 16 },{ 0x606, 16 },{ 0xc0e, 17 }, -{ 0x303cd, 23 },{ 0x303c9, 23 },{ 0x303c8, 23 },{ 0x303ca, 23 }, -{ 0x303cb, 23 },{ 0x303cc, 23 },{ 0x303ce, 23 },{ 0x303cf, 23 }, -{ 0x303d0, 23 },{ 0x303d1, 23 },{ 0x303d2, 23 },{ 0x303d3, 23 }, -{ 0x303d4, 23 },{ 0x303d5, 23 },{ 0x303d6, 23 },{ 0x303d7, 23 }, -{ 0x303d8, 23 },{ 0x303d9, 23 },{ 0x303da, 23 },{ 0x303db, 23 }, -{ 0x303dc, 23 },{ 0x303dd, 23 },{ 0x303de, 23 },{ 0x303df, 23 }, -{ 0x303e0, 23 },{ 0x303e1, 23 },{ 0x303e2, 23 },{ 0x303e3, 23 }, -{ 0x303e4, 23 },{ 0x303e5, 23 },{ 0x303e6, 23 },{ 0x303e7, 23 }, -{ 0x303e8, 23 },{ 0x303e9, 23 },{ 0x303ea, 23 },{ 0x303eb, 23 }, -{ 0x303ec, 23 },{ 0x303ed, 23 },{ 0x303ee, 23 },{ 0x303ef, 23 }, -{ 0x303f0, 23 },{ 0x303f1, 23 },{ 0x303f2, 23 },{ 0x303f3, 23 }, -{ 0x303f4, 23 },{ 0x303f5, 23 },{ 0x303f6, 23 },{ 0x303f7, 23 }, -{ 0x303f8, 23 },{ 0x303f9, 23 },{ 0x303fa, 23 },{ 0x303fb, 23 }, -{ 0x303fc, 23 },{ 0x303fd, 23 },{ 0x303fe, 23 },{ 0x303ff, 23 }, -{ 0x60780, 24 },{ 0x60781, 24 },{ 0x60782, 24 },{ 0x60783, 24 }, -{ 0x60784, 24 },{ 0x60785, 24 },{ 0x60786, 24 },{ 0x60787, 24 }, -{ 0x60788, 24 },{ 0x60789, 24 },{ 0x6078a, 24 },{ 0x6078b, 24 }, -{ 0x6078c, 24 },{ 0x6078d, 24 },{ 0x6078e, 24 },{ 0x6078f, 24 }, -}; - -const uint32_t ff_table0_dc_chroma[120][2] = { -{ 0x0, 2 },{ 0x1, 2 },{ 0x5, 3 },{ 0x9, 4 }, -{ 0xd, 4 },{ 0x11, 5 },{ 0x1d, 5 },{ 0x1f, 5 }, -{ 0x21, 6 },{ 0x31, 6 },{ 0x38, 6 },{ 0x33, 6 }, -{ 0x39, 6 },{ 0x3d, 6 },{ 0x61, 7 },{ 0x79, 7 }, -{ 0x80, 8 },{ 0xc8, 8 },{ 0xca, 8 },{ 0xf0, 8 }, -{ 0x81, 8 },{ 0xc0, 8 },{ 0xc9, 8 },{ 0x107, 9 }, -{ 0x106, 9 },{ 0x196, 9 },{ 0x183, 9 },{ 0x1e3, 9 }, -{ 0x1e2, 9 },{ 0x20a, 10 },{ 0x20b, 10 },{ 0x609, 11 }, -{ 0x412, 11 },{ 0x413, 11 },{ 0x60b, 11 },{ 0x411, 11 }, -{ 0x60a, 11 },{ 0x65f, 11 },{ 0x410, 11 },{ 0x65d, 11 }, -{ 0x65e, 11 },{ 0xcb8, 12 },{ 0xc10, 12 },{ 0xcb9, 12 }, -{ 0x1823, 13 },{ 0x3045, 14 },{ 0x6089, 15 },{ 0xc110, 16 }, -{ 0x304448, 22 },{ 0x304449, 22 },{ 0x30444a, 22 },{ 0x30444b, 22 }, -{ 0x30444c, 22 },{ 0x30444d, 22 },{ 0x30444e, 22 },{ 0x30444f, 22 }, -{ 0x304450, 22 },{ 0x304451, 22 },{ 0x304452, 22 },{ 0x304453, 22 }, -{ 0x304454, 22 },{ 0x304455, 22 },{ 0x304456, 22 },{ 0x304457, 22 }, -{ 0x304458, 22 },{ 0x304459, 22 },{ 0x30445a, 22 },{ 0x30445b, 22 }, -{ 0x30445c, 22 },{ 0x30445d, 22 },{ 0x30445e, 22 },{ 0x30445f, 22 }, -{ 0x304460, 22 },{ 0x304461, 22 },{ 0x304462, 22 },{ 0x304463, 22 }, -{ 0x304464, 22 },{ 0x304465, 22 },{ 0x304466, 22 },{ 0x304467, 22 }, -{ 0x304468, 22 },{ 0x304469, 22 },{ 0x30446a, 22 },{ 0x30446b, 22 }, -{ 0x30446c, 22 },{ 0x30446d, 22 },{ 0x30446e, 22 },{ 0x30446f, 22 }, -{ 0x304470, 22 },{ 0x304471, 22 },{ 0x304472, 22 },{ 0x304473, 22 }, -{ 0x304474, 22 },{ 0x304475, 22 },{ 0x304476, 22 },{ 0x304477, 22 }, -{ 0x304478, 22 },{ 0x304479, 22 },{ 0x30447a, 22 },{ 0x30447b, 22 }, -{ 0x30447c, 22 },{ 0x30447d, 22 },{ 0x30447e, 22 },{ 0x30447f, 22 }, -{ 0x608880, 23 },{ 0x608881, 23 },{ 0x608882, 23 },{ 0x608883, 23 }, -{ 0x608884, 23 },{ 0x608885, 23 },{ 0x608886, 23 },{ 0x608887, 23 }, -{ 0x608888, 23 },{ 0x608889, 23 },{ 0x60888a, 23 },{ 0x60888b, 23 }, -{ 0x60888c, 23 },{ 0x60888d, 23 },{ 0x60888e, 23 },{ 0x60888f, 23 }, -}; - -/* dc table 1 */ - -const uint32_t ff_table1_dc_lum[120][2] = { -{ 0x2, 2 },{ 0x3, 2 },{ 0x3, 3 },{ 0x2, 4 }, -{ 0x5, 4 },{ 0x1, 5 },{ 0x3, 5 },{ 0x8, 5 }, -{ 0x0, 6 },{ 0x5, 6 },{ 0xd, 6 },{ 0xf, 6 }, -{ 0x13, 6 },{ 0x8, 7 },{ 0x18, 7 },{ 0x1c, 7 }, -{ 0x24, 7 },{ 0x4, 8 },{ 0x6, 8 },{ 0x12, 8 }, -{ 0x32, 8 },{ 0x3b, 8 },{ 0x4a, 8 },{ 0x4b, 8 }, -{ 0xb, 9 },{ 0x26, 9 },{ 0x27, 9 },{ 0x66, 9 }, -{ 0x74, 9 },{ 0x75, 9 },{ 0x14, 10 },{ 0x1c, 10 }, -{ 0x1f, 10 },{ 0x1d, 10 },{ 0x2b, 11 },{ 0x3d, 11 }, -{ 0x19d, 11 },{ 0x19f, 11 },{ 0x54, 12 },{ 0x339, 12 }, -{ 0x338, 12 },{ 0x33d, 12 },{ 0xab, 13 },{ 0xf1, 13 }, -{ 0x678, 13 },{ 0xf2, 13 },{ 0x1e0, 14 },{ 0x1e1, 14 }, -{ 0x154, 14 },{ 0xcf2, 14 },{ 0x3cc, 15 },{ 0x2ab, 15 }, -{ 0x19e7, 15 },{ 0x3ce, 15 },{ 0x19e6, 15 },{ 0x554, 16 }, -{ 0x79f, 16 },{ 0x555, 16 },{ 0xf3d, 17 },{ 0xf37, 17 }, -{ 0xf3c, 17 },{ 0xf35, 17 },{ 0x1e6d, 18 },{ 0x1e68, 18 }, -{ 0x3cd8, 19 },{ 0x3cd3, 19 },{ 0x3cd9, 19 },{ 0x79a4, 20 }, -{ 0xf34ba, 25 },{ 0xf34b4, 25 },{ 0xf34b5, 25 },{ 0xf34b6, 25 }, -{ 0xf34b7, 25 },{ 0xf34b8, 25 },{ 0xf34b9, 25 },{ 0xf34bb, 25 }, -{ 0xf34bc, 25 },{ 0xf34bd, 25 },{ 0xf34be, 25 },{ 0xf34bf, 25 }, -{ 0x1e6940, 26 },{ 0x1e6941, 26 },{ 0x1e6942, 26 },{ 0x1e6943, 26 }, -{ 0x1e6944, 26 },{ 0x1e6945, 26 },{ 0x1e6946, 26 },{ 0x1e6947, 26 }, -{ 0x1e6948, 26 },{ 0x1e6949, 26 },{ 0x1e694a, 26 },{ 0x1e694b, 26 }, -{ 0x1e694c, 26 },{ 0x1e694d, 26 },{ 0x1e694e, 26 },{ 0x1e694f, 26 }, -{ 0x1e6950, 26 },{ 0x1e6951, 26 },{ 0x1e6952, 26 },{ 0x1e6953, 26 }, -{ 0x1e6954, 26 },{ 0x1e6955, 26 },{ 0x1e6956, 26 },{ 0x1e6957, 26 }, -{ 0x1e6958, 26 },{ 0x1e6959, 26 },{ 0x1e695a, 26 },{ 0x1e695b, 26 }, -{ 0x1e695c, 26 },{ 0x1e695d, 26 },{ 0x1e695e, 26 },{ 0x1e695f, 26 }, -{ 0x1e6960, 26 },{ 0x1e6961, 26 },{ 0x1e6962, 26 },{ 0x1e6963, 26 }, -{ 0x1e6964, 26 },{ 0x1e6965, 26 },{ 0x1e6966, 26 },{ 0x1e6967, 26 }, -}; - -const uint32_t ff_table1_dc_chroma[120][2] = { -{ 0x0, 2 },{ 0x1, 2 },{ 0x4, 3 },{ 0x7, 3 }, -{ 0xb, 4 },{ 0xd, 4 },{ 0x15, 5 },{ 0x28, 6 }, -{ 0x30, 6 },{ 0x32, 6 },{ 0x52, 7 },{ 0x62, 7 }, -{ 0x66, 7 },{ 0xa6, 8 },{ 0xc6, 8 },{ 0xcf, 8 }, -{ 0x14f, 9 },{ 0x18e, 9 },{ 0x19c, 9 },{ 0x29d, 10 }, -{ 0x33a, 10 },{ 0x538, 11 },{ 0x63c, 11 },{ 0x63e, 11 }, -{ 0x63f, 11 },{ 0x676, 11 },{ 0xa73, 12 },{ 0xc7a, 12 }, -{ 0xcef, 12 },{ 0x14e5, 13 },{ 0x19dd, 13 },{ 0x29c8, 14 }, -{ 0x29c9, 14 },{ 0x63dd, 15 },{ 0x33b8, 14 },{ 0x33b9, 14 }, -{ 0xc7b6, 16 },{ 0x63d8, 15 },{ 0x63df, 15 },{ 0xc7b3, 16 }, -{ 0xc7b4, 16 },{ 0xc7b5, 16 },{ 0x63de, 15 },{ 0xc7b7, 16 }, -{ 0xc7b8, 16 },{ 0xc7b9, 16 },{ 0x18f65, 17 },{ 0x31ec8, 18 }, -{ 0xc7b248, 24 },{ 0xc7b249, 24 },{ 0xc7b24a, 24 },{ 0xc7b24b, 24 }, -{ 0xc7b24c, 24 },{ 0xc7b24d, 24 },{ 0xc7b24e, 24 },{ 0xc7b24f, 24 }, -{ 0xc7b250, 24 },{ 0xc7b251, 24 },{ 0xc7b252, 24 },{ 0xc7b253, 24 }, -{ 0xc7b254, 24 },{ 0xc7b255, 24 },{ 0xc7b256, 24 },{ 0xc7b257, 24 }, -{ 0xc7b258, 24 },{ 0xc7b259, 24 },{ 0xc7b25a, 24 },{ 0xc7b25b, 24 }, -{ 0xc7b25c, 24 },{ 0xc7b25d, 24 },{ 0xc7b25e, 24 },{ 0xc7b25f, 24 }, -{ 0xc7b260, 24 },{ 0xc7b261, 24 },{ 0xc7b262, 24 },{ 0xc7b263, 24 }, -{ 0xc7b264, 24 },{ 0xc7b265, 24 },{ 0xc7b266, 24 },{ 0xc7b267, 24 }, -{ 0xc7b268, 24 },{ 0xc7b269, 24 },{ 0xc7b26a, 24 },{ 0xc7b26b, 24 }, -{ 0xc7b26c, 24 },{ 0xc7b26d, 24 },{ 0xc7b26e, 24 },{ 0xc7b26f, 24 }, -{ 0xc7b270, 24 },{ 0xc7b271, 24 },{ 0xc7b272, 24 },{ 0xc7b273, 24 }, -{ 0xc7b274, 24 },{ 0xc7b275, 24 },{ 0xc7b276, 24 },{ 0xc7b277, 24 }, -{ 0xc7b278, 24 },{ 0xc7b279, 24 },{ 0xc7b27a, 24 },{ 0xc7b27b, 24 }, -{ 0xc7b27c, 24 },{ 0xc7b27d, 24 },{ 0xc7b27e, 24 },{ 0xc7b27f, 24 }, -{ 0x18f6480, 25 },{ 0x18f6481, 25 },{ 0x18f6482, 25 },{ 0x18f6483, 25 }, -{ 0x18f6484, 25 },{ 0x18f6485, 25 },{ 0x18f6486, 25 },{ 0x18f6487, 25 }, -{ 0x18f6488, 25 },{ 0x18f6489, 25 },{ 0x18f648a, 25 },{ 0x18f648b, 25 }, -{ 0x18f648c, 25 },{ 0x18f648d, 25 },{ 0x18f648e, 25 },{ 0x18f648f, 25 }, -}; - -/* vlc table 0, for intra luma */ - -static const uint16_t table0_vlc[133][2] = { -{ 0x1, 2 },{ 0x6, 3 },{ 0xf, 4 },{ 0x16, 5 }, -{ 0x20, 6 },{ 0x18, 7 },{ 0x8, 8 },{ 0x9a, 8 }, -{ 0x56, 9 },{ 0x13e, 9 },{ 0xf0, 10 },{ 0x3a5, 10 }, -{ 0x77, 11 },{ 0x1ef, 11 },{ 0x9a, 12 },{ 0x5d, 13 }, -{ 0x1, 4 },{ 0x11, 5 },{ 0x2, 7 },{ 0xb, 8 }, -{ 0x12, 9 },{ 0x1d6, 9 },{ 0x27e, 10 },{ 0x191, 11 }, -{ 0xea, 12 },{ 0x3dc, 12 },{ 0x13b, 13 },{ 0x4, 5 }, -{ 0x14, 7 },{ 0x9e, 8 },{ 0x9, 10 },{ 0x1ac, 11 }, -{ 0x1e2, 11 },{ 0x3ca, 12 },{ 0x5f, 13 },{ 0x17, 5 }, -{ 0x4e, 7 },{ 0x5e, 9 },{ 0xf3, 10 },{ 0x1ad, 11 }, -{ 0xec, 12 },{ 0x5f0, 13 },{ 0xe, 6 },{ 0xe1, 8 }, -{ 0x3a4, 10 },{ 0x9c, 12 },{ 0x13d, 13 },{ 0x3b, 6 }, -{ 0x1c, 9 },{ 0x14, 11 },{ 0x9be, 12 },{ 0x6, 7 }, -{ 0x7a, 9 },{ 0x190, 11 },{ 0x137, 13 },{ 0x1b, 7 }, -{ 0x8, 10 },{ 0x75c, 11 },{ 0x71, 7 },{ 0xd7, 10 }, -{ 0x9bf, 12 },{ 0x7, 8 },{ 0xaf, 10 },{ 0x4cc, 11 }, -{ 0x34, 8 },{ 0x265, 10 },{ 0x9f, 12 },{ 0xe0, 8 }, -{ 0x16, 11 },{ 0x327, 12 },{ 0x15, 9 },{ 0x17d, 11 }, -{ 0xebb, 12 },{ 0x14, 9 },{ 0xf6, 10 },{ 0x1e4, 11 }, -{ 0xcb, 10 },{ 0x99d, 12 },{ 0xca, 10 },{ 0x2fc, 12 }, -{ 0x17f, 11 },{ 0x4cd, 11 },{ 0x2fd, 12 },{ 0x4fe, 11 }, -{ 0x13a, 13 },{ 0xa, 4 },{ 0x42, 7 },{ 0x1d3, 9 }, -{ 0x4dd, 11 },{ 0x12, 5 },{ 0xe8, 8 },{ 0x4c, 11 }, -{ 0x136, 13 },{ 0x39, 6 },{ 0x264, 10 },{ 0xeba, 12 }, -{ 0x0, 7 },{ 0xae, 10 },{ 0x99c, 12 },{ 0x1f, 7 }, -{ 0x4de, 11 },{ 0x43, 7 },{ 0x4dc, 11 },{ 0x3, 8 }, -{ 0x3cb, 12 },{ 0x6, 8 },{ 0x99e, 12 },{ 0x2a, 8 }, -{ 0x5f1, 13 },{ 0xf, 8 },{ 0x9fe, 12 },{ 0x33, 8 }, -{ 0x9ff, 12 },{ 0x98, 8 },{ 0x99f, 12 },{ 0xea, 8 }, -{ 0x13c, 13 },{ 0x2e, 8 },{ 0x192, 11 },{ 0x136, 9 }, -{ 0x6a, 9 },{ 0x15, 11 },{ 0x3af, 10 },{ 0x1e3, 11 }, -{ 0x74, 11 },{ 0xeb, 12 },{ 0x2f9, 12 },{ 0x5c, 13 }, -{ 0xed, 12 },{ 0x3dd, 12 },{ 0x326, 12 },{ 0x5e, 13 }, -{ 0x16, 7 }, -}; - -static const int8_t table0_level[132] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 1, 2, 3, 4, 5, - 6, 7, 8, 1, 2, 3, 4, 5, - 6, 7, 1, 2, 3, 4, 5, 1, - 2, 3, 4, 1, 2, 3, 4, 1, - 2, 3, 1, 2, 3, 1, 2, 3, - 1, 2, 3, 1, 2, 3, 1, 2, - 3, 1, 2, 3, 1, 2, 1, 2, - 1, 1, 1, 1, 1, 1, 2, 3, - 4, 1, 2, 3, 4, 1, 2, 3, - 1, 2, 3, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, -}; - -static const int8_t table0_run[132] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 3, - 3, 3, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 6, 6, 6, 6, 7, - 7, 7, 8, 8, 8, 9, 9, 9, - 10, 10, 10, 11, 11, 11, 12, 12, - 12, 13, 13, 13, 14, 14, 15, 15, - 16, 17, 18, 19, 20, 0, 0, 0, - 0, 1, 1, 1, 1, 2, 2, 2, - 3, 3, 3, 4, 4, 5, 5, 6, - 6, 7, 7, 8, 8, 9, 9, 10, - 10, 11, 11, 12, 12, 13, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, -}; - -/* vlc table 1, for intra chroma and P macro blocks */ - -static const uint16_t table1_vlc[149][2] = { -{ 0x4, 3 },{ 0x14, 5 },{ 0x17, 7 },{ 0x7f, 8 }, -{ 0x154, 9 },{ 0x1f2, 10 },{ 0xbf, 11 },{ 0x65, 12 }, -{ 0xaaa, 12 },{ 0x630, 13 },{ 0x1597, 13 },{ 0x3b7, 14 }, -{ 0x2b22, 14 },{ 0xbe6, 15 },{ 0xb, 4 },{ 0x37, 7 }, -{ 0x62, 9 },{ 0x7, 11 },{ 0x166, 12 },{ 0xce, 13 }, -{ 0x1590, 13 },{ 0x5f6, 14 },{ 0xbe7, 15 },{ 0x7, 5 }, -{ 0x6d, 8 },{ 0x3, 11 },{ 0x31f, 12 },{ 0x5f2, 14 }, -{ 0x2, 6 },{ 0x61, 9 },{ 0x55, 12 },{ 0x1df, 14 }, -{ 0x1a, 6 },{ 0x1e, 10 },{ 0xac9, 12 },{ 0x2b23, 14 }, -{ 0x1e, 6 },{ 0x1f, 10 },{ 0xac3, 12 },{ 0x2b2b, 14 }, -{ 0x6, 7 },{ 0x4, 11 },{ 0x2f8, 13 },{ 0x19, 7 }, -{ 0x6, 11 },{ 0x63d, 13 },{ 0x57, 7 },{ 0x182, 11 }, -{ 0x2aa2, 14 },{ 0x4, 8 },{ 0x180, 11 },{ 0x59c, 14 }, -{ 0x7d, 8 },{ 0x164, 12 },{ 0x76d, 15 },{ 0x2, 9 }, -{ 0x18d, 11 },{ 0x1581, 13 },{ 0xad, 8 },{ 0x60, 12 }, -{ 0xc67, 14 },{ 0x1c, 9 },{ 0xee, 13 },{ 0x3, 9 }, -{ 0x2cf, 13 },{ 0xd9, 9 },{ 0x1580, 13 },{ 0x2, 11 }, -{ 0x183, 11 },{ 0x57, 12 },{ 0x61, 12 },{ 0x31, 11 }, -{ 0x66, 12 },{ 0x631, 13 },{ 0x632, 13 },{ 0xac, 13 }, -{ 0x31d, 12 },{ 0x76, 12 },{ 0x3a, 11 },{ 0x165, 12 }, -{ 0xc66, 14 },{ 0x3, 2 },{ 0x54, 7 },{ 0x2ab, 10 }, -{ 0x16, 13 },{ 0x5f7, 14 },{ 0x5, 4 },{ 0xf8, 9 }, -{ 0xaa9, 12 },{ 0x5f, 15 },{ 0x4, 4 },{ 0x1c, 10 }, -{ 0x1550, 13 },{ 0x4, 5 },{ 0x77, 11 },{ 0x76c, 15 }, -{ 0xe, 5 },{ 0xa, 12 },{ 0xc, 5 },{ 0x562, 11 }, -{ 0x4, 6 },{ 0x31c, 12 },{ 0x6, 6 },{ 0xc8, 13 }, -{ 0xd, 6 },{ 0x1da, 13 },{ 0x7, 6 },{ 0xc9, 13 }, -{ 0x1, 7 },{ 0x2e, 14 },{ 0x14, 7 },{ 0x1596, 13 }, -{ 0xa, 7 },{ 0xac2, 12 },{ 0x16, 7 },{ 0x15b, 14 }, -{ 0x15, 7 },{ 0x15a, 14 },{ 0xf, 8 },{ 0x5e, 15 }, -{ 0x7e, 8 },{ 0xab, 8 },{ 0x2d, 9 },{ 0xd8, 9 }, -{ 0xb, 9 },{ 0x14, 10 },{ 0x2b3, 10 },{ 0x1f3, 10 }, -{ 0x3a, 10 },{ 0x0, 10 },{ 0x58, 10 },{ 0x2e, 9 }, -{ 0x5e, 10 },{ 0x563, 11 },{ 0xec, 12 },{ 0x54, 12 }, -{ 0xac1, 12 },{ 0x1556, 13 },{ 0x2fa, 13 },{ 0x181, 11 }, -{ 0x1557, 13 },{ 0x59d, 14 },{ 0x2aa3, 14 },{ 0x2b2a, 14 }, -{ 0x1de, 14 },{ 0x63c, 13 },{ 0xcf, 13 },{ 0x1594, 13 }, -{ 0xd, 9 }, -}; - -static const int8_t table1_level[148] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 1, - 2, 3, 4, 5, 1, 2, 3, 4, - 1, 2, 3, 4, 1, 2, 3, 4, - 1, 2, 3, 1, 2, 3, 1, 2, - 3, 1, 2, 3, 1, 2, 3, 1, - 2, 3, 1, 2, 3, 1, 2, 1, - 2, 1, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 3, 4, 5, 1, 2, - 3, 4, 1, 2, 3, 1, 2, 3, - 1, 2, 1, 2, 1, 2, 1, 2, - 1, 2, 1, 2, 1, 2, 1, 2, - 1, 2, 1, 2, 1, 2, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, -}; - -static const int8_t table1_run[148] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, - 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, - 6, 6, 6, 7, 7, 7, 8, 8, - 8, 9, 9, 9, 10, 10, 10, 11, - 11, 11, 12, 12, 12, 13, 13, 14, - 14, 15, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, - 29, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 2, 2, 2, 3, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, - 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13, 14, 14, 15, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, -}; - -/* third vlc table */ - -static const uint16_t table2_vlc[186][2] = { -{ 0x1, 2 },{ 0x5, 3 },{ 0xd, 4 },{ 0x12, 5 }, -{ 0xe, 6 },{ 0x15, 7 },{ 0x13, 8 },{ 0x3f, 8 }, -{ 0x4b, 9 },{ 0x11f, 9 },{ 0xb8, 10 },{ 0x3e3, 10 }, -{ 0x172, 11 },{ 0x24d, 12 },{ 0x3da, 12 },{ 0x2dd, 13 }, -{ 0x1f55, 13 },{ 0x5b9, 14 },{ 0x3eae, 14 },{ 0x0, 4 }, -{ 0x10, 5 },{ 0x8, 7 },{ 0x20, 8 },{ 0x29, 9 }, -{ 0x1f4, 9 },{ 0x233, 10 },{ 0x1e0, 11 },{ 0x12a, 12 }, -{ 0x3dd, 12 },{ 0x50a, 13 },{ 0x1f29, 13 },{ 0xa42, 14 }, -{ 0x1272, 15 },{ 0x1737, 15 },{ 0x3, 5 },{ 0x11, 7 }, -{ 0xc4, 8 },{ 0x4b, 10 },{ 0xb4, 11 },{ 0x7d4, 11 }, -{ 0x345, 12 },{ 0x2d7, 13 },{ 0x7bf, 13 },{ 0x938, 14 }, -{ 0xbbb, 14 },{ 0x95e, 15 },{ 0x13, 5 },{ 0x78, 7 }, -{ 0x69, 9 },{ 0x232, 10 },{ 0x461, 11 },{ 0x3ec, 12 }, -{ 0x520, 13 },{ 0x1f2a, 13 },{ 0x3e50, 14 },{ 0x3e51, 14 }, -{ 0x1486, 15 },{ 0xc, 6 },{ 0x24, 9 },{ 0x94, 11 }, -{ 0x8c0, 12 },{ 0xf09, 14 },{ 0x1ef0, 15 },{ 0x3d, 6 }, -{ 0x53, 9 },{ 0x1a0, 11 },{ 0x2d6, 13 },{ 0xf08, 14 }, -{ 0x13, 7 },{ 0x7c, 9 },{ 0x7c1, 11 },{ 0x4ac, 14 }, -{ 0x1b, 7 },{ 0xa0, 10 },{ 0x344, 12 },{ 0xf79, 14 }, -{ 0x79, 7 },{ 0x3e1, 10 },{ 0x2d4, 13 },{ 0x2306, 14 }, -{ 0x21, 8 },{ 0x23c, 10 },{ 0xfae, 12 },{ 0x23de, 14 }, -{ 0x35, 8 },{ 0x175, 11 },{ 0x7b3, 13 },{ 0xc5, 8 }, -{ 0x174, 11 },{ 0x785, 13 },{ 0x48, 9 },{ 0x1a3, 11 }, -{ 0x49e, 13 },{ 0x2c, 9 },{ 0xfa, 10 },{ 0x7d6, 11 }, -{ 0x92, 10 },{ 0x5cc, 13 },{ 0x1ef1, 15 },{ 0xa3, 10 }, -{ 0x3ed, 12 },{ 0x93e, 14 },{ 0x1e2, 11 },{ 0x1273, 15 }, -{ 0x7c4, 11 },{ 0x1487, 15 },{ 0x291, 12 },{ 0x293, 12 }, -{ 0xf8a, 12 },{ 0x509, 13 },{ 0x508, 13 },{ 0x78d, 13 }, -{ 0x7be, 13 },{ 0x78c, 13 },{ 0x4ae, 14 },{ 0xbba, 14 }, -{ 0x2307, 14 },{ 0xb9a, 14 },{ 0x1736, 15 },{ 0xe, 4 }, -{ 0x45, 7 },{ 0x1f3, 9 },{ 0x47a, 11 },{ 0x5dc, 13 }, -{ 0x23df, 14 },{ 0x19, 5 },{ 0x28, 9 },{ 0x176, 11 }, -{ 0x49d, 13 },{ 0x23dd, 14 },{ 0x30, 6 },{ 0xa2, 10 }, -{ 0x2ef, 12 },{ 0x5b8, 14 },{ 0x3f, 6 },{ 0xa5, 10 }, -{ 0x3db, 12 },{ 0x93f, 14 },{ 0x44, 7 },{ 0x7cb, 11 }, -{ 0x95f, 15 },{ 0x63, 7 },{ 0x3c3, 12 },{ 0x15, 8 }, -{ 0x8f6, 12 },{ 0x17, 8 },{ 0x498, 13 },{ 0x2c, 8 }, -{ 0x7b2, 13 },{ 0x2f, 8 },{ 0x1f54, 13 },{ 0x8d, 8 }, -{ 0x7bd, 13 },{ 0x8e, 8 },{ 0x1182, 13 },{ 0xfb, 8 }, -{ 0x50b, 13 },{ 0x2d, 8 },{ 0x7c0, 11 },{ 0x79, 9 }, -{ 0x1f5f, 13 },{ 0x7a, 9 },{ 0x1f56, 13 },{ 0x231, 10 }, -{ 0x3e4, 10 },{ 0x1a1, 11 },{ 0x143, 11 },{ 0x1f7, 11 }, -{ 0x16f, 12 },{ 0x292, 12 },{ 0x2e7, 12 },{ 0x16c, 12 }, -{ 0x16d, 12 },{ 0x3dc, 12 },{ 0xf8b, 12 },{ 0x499, 13 }, -{ 0x3d8, 12 },{ 0x78e, 13 },{ 0x2d5, 13 },{ 0x1f5e, 13 }, -{ 0x1f2b, 13 },{ 0x78f, 13 },{ 0x4ad, 14 },{ 0x3eaf, 14 }, -{ 0x23dc, 14 },{ 0x4a, 9 }, -}; - -static const int8_t table2_level[185] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, - 11, 1, 2, 3, 4, 5, 6, 1, - 2, 3, 4, 5, 1, 2, 3, 4, - 1, 2, 3, 4, 1, 2, 3, 4, - 1, 2, 3, 4, 1, 2, 3, 1, - 2, 3, 1, 2, 3, 1, 2, 3, - 1, 2, 3, 1, 2, 3, 1, 2, - 1, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 4, 5, 6, 1, 2, 3, - 4, 5, 1, 2, 3, 4, 1, 2, - 3, 4, 1, 2, 3, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 2, 1, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, -}; - -static const int8_t table2_run[185] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 3, 4, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 5, 6, 6, 6, 6, - 7, 7, 7, 7, 8, 8, 8, 8, - 9, 9, 9, 9, 10, 10, 10, 11, - 11, 11, 12, 12, 12, 13, 13, 13, - 14, 14, 14, 15, 15, 15, 16, 16, - 17, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 0, - 0, 0, 0, 0, 0, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 3, 3, - 3, 3, 4, 4, 4, 5, 5, 6, - 6, 7, 7, 8, 8, 9, 9, 10, - 10, 11, 11, 12, 12, 13, 13, 14, - 14, 15, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, - 37, -}; - -/* second non intra vlc table */ -static const uint16_t table4_vlc[169][2] = { -{ 0x0, 3 },{ 0x3, 4 },{ 0xb, 5 },{ 0x14, 6 }, -{ 0x3f, 6 },{ 0x5d, 7 },{ 0xa2, 8 },{ 0xac, 9 }, -{ 0x16e, 9 },{ 0x20a, 10 },{ 0x2e2, 10 },{ 0x432, 11 }, -{ 0x5c9, 11 },{ 0x827, 12 },{ 0xb54, 12 },{ 0x4e6, 13 }, -{ 0x105f, 13 },{ 0x172a, 13 },{ 0x20b2, 14 },{ 0x2d4e, 14 }, -{ 0x39f0, 14 },{ 0x4175, 15 },{ 0x5a9e, 15 },{ 0x4, 4 }, -{ 0x1e, 5 },{ 0x42, 7 },{ 0xb6, 8 },{ 0x173, 9 }, -{ 0x395, 10 },{ 0x72e, 11 },{ 0xb94, 12 },{ 0x16a4, 13 }, -{ 0x20b3, 14 },{ 0x2e45, 14 },{ 0x5, 5 },{ 0x40, 7 }, -{ 0x49, 9 },{ 0x28f, 10 },{ 0x5cb, 11 },{ 0x48a, 13 }, -{ 0x9dd, 14 },{ 0x73e2, 15 },{ 0x18, 5 },{ 0x25, 8 }, -{ 0x8a, 10 },{ 0x51b, 11 },{ 0xe5f, 12 },{ 0x9c9, 14 }, -{ 0x139c, 15 },{ 0x29, 6 },{ 0x4f, 9 },{ 0x412, 11 }, -{ 0x48d, 13 },{ 0x2e41, 14 },{ 0x38, 6 },{ 0x10e, 9 }, -{ 0x5a8, 11 },{ 0x105c, 13 },{ 0x39f2, 14 },{ 0x58, 7 }, -{ 0x21f, 10 },{ 0xe7e, 12 },{ 0x39ff, 14 },{ 0x23, 8 }, -{ 0x2e3, 10 },{ 0x4e5, 13 },{ 0x2e40, 14 },{ 0xa1, 8 }, -{ 0x5be, 11 },{ 0x9c8, 14 },{ 0x83, 8 },{ 0x13a, 11 }, -{ 0x1721, 13 },{ 0x44, 9 },{ 0x276, 12 },{ 0x39f6, 14 }, -{ 0x8b, 10 },{ 0x4ef, 13 },{ 0x5a9b, 15 },{ 0x208, 10 }, -{ 0x1cfe, 13 },{ 0x399, 10 },{ 0x1cb4, 13 },{ 0x39e, 10 }, -{ 0x39f3, 14 },{ 0x5ab, 11 },{ 0x73e3, 15 },{ 0x737, 11 }, -{ 0x5a9f, 15 },{ 0x82d, 12 },{ 0xe69, 12 },{ 0xe68, 12 }, -{ 0x433, 11 },{ 0xb7b, 12 },{ 0x2df8, 14 },{ 0x2e56, 14 }, -{ 0x2e57, 14 },{ 0x39f7, 14 },{ 0x51a5, 15 },{ 0x3, 3 }, -{ 0x2a, 6 },{ 0xe4, 8 },{ 0x28e, 10 },{ 0x735, 11 }, -{ 0x1058, 13 },{ 0x1cfa, 13 },{ 0x2df9, 14 },{ 0x4174, 15 }, -{ 0x9, 4 },{ 0x54, 8 },{ 0x398, 10 },{ 0x48b, 13 }, -{ 0x139d, 15 },{ 0xd, 4 },{ 0xad, 9 },{ 0x826, 12 }, -{ 0x2d4c, 14 },{ 0x11, 5 },{ 0x16b, 9 },{ 0xb7f, 12 }, -{ 0x51a4, 15 },{ 0x19, 5 },{ 0x21b, 10 },{ 0x16fd, 13 }, -{ 0x1d, 5 },{ 0x394, 10 },{ 0x28d3, 14 },{ 0x2b, 6 }, -{ 0x5bc, 11 },{ 0x5a9a, 15 },{ 0x2f, 6 },{ 0x247, 12 }, -{ 0x10, 7 },{ 0xa35, 12 },{ 0x3e, 6 },{ 0xb7a, 12 }, -{ 0x59, 7 },{ 0x105e, 13 },{ 0x26, 8 },{ 0x9cf, 14 }, -{ 0x55, 8 },{ 0x1cb5, 13 },{ 0x57, 8 },{ 0xe5b, 12 }, -{ 0xa0, 8 },{ 0x1468, 13 },{ 0x170, 9 },{ 0x90, 10 }, -{ 0x1ce, 9 },{ 0x21a, 10 },{ 0x218, 10 },{ 0x168, 9 }, -{ 0x21e, 10 },{ 0x244, 12 },{ 0x736, 11 },{ 0x138, 11 }, -{ 0x519, 11 },{ 0xe5e, 12 },{ 0x72c, 11 },{ 0xb55, 12 }, -{ 0x9dc, 14 },{ 0x20bb, 14 },{ 0x48c, 13 },{ 0x1723, 13 }, -{ 0x2e44, 14 },{ 0x16a5, 13 },{ 0x518, 11 },{ 0x39fe, 14 }, -{ 0x169, 9 }, -}; - -static const int8_t table4_level[168] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 1, - 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 1, 2, 3, 4, 5, 6, - 7, 8, 1, 2, 3, 4, 5, 6, - 7, 1, 2, 3, 4, 5, 1, 2, - 3, 4, 5, 1, 2, 3, 4, 1, - 2, 3, 4, 1, 2, 3, 1, 2, - 3, 1, 2, 3, 1, 2, 3, 1, - 2, 1, 2, 1, 2, 1, 2, 1, - 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 1, 2, 3, 4, - 5, 1, 2, 3, 4, 1, 2, 3, - 4, 1, 2, 3, 1, 2, 3, 1, - 2, 3, 1, 2, 1, 2, 1, 2, - 1, 2, 1, 2, 1, 2, 1, 2, - 1, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, -}; - -static const int8_t table4_run[168] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 3, 3, - 3, 4, 4, 4, 4, 4, 5, 5, - 5, 5, 5, 6, 6, 6, 6, 7, - 7, 7, 7, 8, 8, 8, 9, 9, - 9, 10, 10, 10, 11, 11, 11, 12, - 12, 13, 13, 14, 14, 15, 15, 16, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 3, 3, 3, - 3, 4, 4, 4, 5, 5, 5, 6, - 6, 6, 7, 7, 8, 8, 9, 9, - 10, 10, 11, 11, 12, 12, 13, 13, - 14, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, -}; - -extern const uint16_t inter_vlc[103][2]; -extern const int8_t inter_level[102]; -extern const int8_t inter_run[102]; - -extern const uint16_t intra_vlc[103][2]; -extern const int8_t intra_level[102]; -extern const int8_t intra_run[102]; - -extern const uint8_t DCtab_lum[13][2]; -extern const uint8_t DCtab_chrom[13][2]; - -extern const uint8_t cbpy_tab[16][2]; -extern const uint8_t mvtab[33][2]; - -extern const uint8_t intra_MCBPC_code[9]; -extern const uint8_t intra_MCBPC_bits[9]; - -extern const uint8_t inter_MCBPC_code[28]; -extern const uint8_t inter_MCBPC_bits[28]; - -#define NB_RL_TABLES 6 - -static RLTable rl_table[NB_RL_TABLES] = { - /* intra luminance tables */ - { - 132, - 85, - table0_vlc, - table0_run, - table0_level, - }, - { - 185, - 119, - table2_vlc, - table2_run, - table2_level, - }, - { - 102, - 67, - intra_vlc, - intra_run, - intra_level, - }, - /* intra chrominance / non intra tables */ - { - 148, - 81, - table1_vlc, - table1_run, - table1_level, - }, - { - 168, - 99, - table4_vlc, - table4_run, - table4_level, - }, - { - 102, - 58, - inter_vlc, - inter_run, - inter_level, - }, -}; - -/* motion vector table 0 */ - -static const uint16_t table0_mv_code[1100] = { - 0x0001, 0x0003, 0x0005, 0x0007, 0x0003, 0x0008, 0x000c, 0x0001, - 0x0002, 0x001b, 0x0006, 0x000b, 0x0015, 0x0002, 0x000e, 0x000f, - 0x0014, 0x0020, 0x0022, 0x0025, 0x0027, 0x0029, 0x002d, 0x004b, - 0x004d, 0x0003, 0x0022, 0x0023, 0x0025, 0x0027, 0x0042, 0x0048, - 0x0049, 0x0050, 0x005c, 0x0091, 0x009f, 0x000e, 0x0043, 0x004c, - 0x0054, 0x0056, 0x008c, 0x0098, 0x009a, 0x009b, 0x00b1, 0x00b2, - 0x0120, 0x0121, 0x0126, 0x0133, 0x0139, 0x01a1, 0x01a4, 0x01a5, - 0x01a6, 0x01a7, 0x01ae, 0x01af, 0x000b, 0x0019, 0x0085, 0x0090, - 0x009b, 0x00aa, 0x00af, 0x010c, 0x010e, 0x011c, 0x011e, 0x0133, - 0x0144, 0x0160, 0x0174, 0x0175, 0x0177, 0x0178, 0x0249, 0x024b, - 0x0252, 0x0261, 0x0265, 0x0270, 0x0352, 0x0353, 0x0355, 0x0359, - 0x0010, 0x0011, 0x0013, 0x0034, 0x0035, 0x0036, 0x0037, 0x003d, - 0x003e, 0x0109, 0x0126, 0x0156, 0x021a, 0x021e, 0x023a, 0x023e, - 0x028e, 0x028f, 0x02cf, 0x0491, 0x0494, 0x049f, 0x04a0, 0x04a3, - 0x04a6, 0x04a7, 0x04ad, 0x04ae, 0x04c0, 0x04c4, 0x04c6, 0x04c8, - 0x04c9, 0x04f5, 0x04f6, 0x04f7, 0x0680, 0x0682, 0x0683, 0x0688, - 0x0689, 0x068d, 0x068e, 0x068f, 0x06a2, 0x06a3, 0x06a9, 0x06b0, - 0x06b1, 0x06b4, 0x06b5, 0x0024, 0x0060, 0x0063, 0x0078, 0x0079, - 0x0211, 0x0244, 0x0245, 0x0247, 0x0248, 0x0249, 0x024a, 0x024b, - 0x026b, 0x02af, 0x02b8, 0x02bb, 0x0436, 0x0476, 0x0477, 0x047e, - 0x04c8, 0x04c9, 0x04ca, 0x0514, 0x0586, 0x0587, 0x0598, 0x059d, - 0x05d9, 0x05da, 0x0920, 0x0921, 0x093b, 0x093c, 0x093d, 0x0942, - 0x0943, 0x0944, 0x0945, 0x0959, 0x095e, 0x095f, 0x0982, 0x0983, - 0x098e, 0x098f, 0x09c4, 0x09e7, 0x09e8, 0x09e9, 0x0d02, 0x0d17, - 0x0d18, 0x0d19, 0x0d41, 0x0d42, 0x0d43, 0x0d50, 0x0d5f, 0x0d6d, - 0x0d6e, 0x0d6f, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x041e, 0x041f, 0x0420, 0x0421, - 0x048c, 0x048d, 0x04d3, 0x04d4, 0x04d5, 0x055c, 0x055d, 0x0572, - 0x0573, 0x0574, 0x0575, 0x08de, 0x08df, 0x08fe, 0x08ff, 0x0996, - 0x0a36, 0x0a37, 0x0b08, 0x0b09, 0x0b0a, 0x0b0b, 0x0b32, 0x0b33, - 0x0b34, 0x0b35, 0x0b36, 0x0b37, 0x0b38, 0x0b39, 0x0bb0, 0x0bf7, - 0x0bf8, 0x0bf9, 0x0bfa, 0x0bfb, 0x0bfc, 0x0bfd, 0x0bfe, 0x0bff, - 0x1254, 0x1255, 0x1256, 0x1257, 0x1270, 0x1271, 0x1272, 0x1273, - 0x1274, 0x1275, 0x12ab, 0x12ac, 0x12ad, 0x12ae, 0x12af, 0x12b0, - 0x12b1, 0x1315, 0x1316, 0x1317, 0x13bf, 0x13c0, 0x13c1, 0x13c2, - 0x13c3, 0x13c4, 0x13c5, 0x13c6, 0x13c7, 0x13c8, 0x13c9, 0x13ca, - 0x13cb, 0x13cc, 0x13cd, 0x1a06, 0x1a07, 0x1a28, 0x1a29, 0x1a2a, - 0x1a2b, 0x1a2c, 0x1a2d, 0x1a80, 0x1abb, 0x1abc, 0x1abd, 0x1ad8, - 0x1ad9, 0x0094, 0x0095, 0x0096, 0x0097, 0x00a0, 0x00a1, 0x00a2, - 0x00a3, 0x0831, 0x0832, 0x0833, 0x0834, 0x0835, 0x0836, 0x0837, - 0x0838, 0x0839, 0x083a, 0x083b, 0x0939, 0x093a, 0x093b, 0x093c, - 0x093d, 0x093e, 0x093f, 0x09a0, 0x09a1, 0x09a2, 0x09a3, 0x09a4, - 0x09a5, 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, - 0x11b3, 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, - 0x11bb, 0x132f, 0x1454, 0x1455, 0x1456, 0x1457, 0x1458, 0x1459, - 0x145a, 0x145b, 0x145c, 0x145d, 0x145e, 0x145f, 0x1460, 0x1461, - 0x1462, 0x1463, 0x1464, 0x1465, 0x1466, 0x1467, 0x1468, 0x1469, - 0x146a, 0x146b, 0x17de, 0x17df, 0x17e0, 0x17e1, 0x17e2, 0x17e3, - 0x17e4, 0x17e5, 0x17e6, 0x17e7, 0x17e8, 0x17e9, 0x17ea, 0x17eb, - 0x17ec, 0x17ed, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, - 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, - 0x254e, 0x254f, 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, - 0x2628, 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c, - 0x276d, 0x276e, 0x276f, 0x2770, 0x2771, 0x2772, 0x2773, 0x2774, - 0x2775, 0x2776, 0x2777, 0x2778, 0x2779, 0x277a, 0x277b, 0x277c, - 0x277d, 0x3503, 0x3544, 0x3545, 0x3546, 0x3547, 0x3560, 0x3561, - 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567, 0x3568, 0x3569, - 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f, 0x3570, 0x3571, - 0x3572, 0x3573, 0x3574, 0x3575, 0x03f0, 0x103d, 0x103e, 0x103f, - 0x1040, 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, - 0x1048, 0x1049, 0x104a, 0x104b, 0x104c, 0x104d, 0x104e, 0x104f, - 0x1050, 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, - 0x1058, 0x1059, 0x105a, 0x105b, 0x105c, 0x105d, 0x105e, 0x105f, - 0x1060, 0x1061, 0x1270, 0x1271, 0x21b8, 0x21b9, 0x21ba, 0x21bb, - 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x21f0, 0x21f1, 0x21f2, 0x21f3, - 0x21f4, 0x21f5, 0x21f6, 0x21f7, 0x21f8, 0x21f9, 0x21fa, 0x21fb, - 0x21fc, 0x21fd, 0x21fe, 0x21ff, 0x2340, 0x2341, 0x2342, 0x2343, - 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b, - 0x234c, 0x234d, 0x234e, 0x234f, 0x2350, 0x2351, 0x2352, 0x2353, - 0x2354, 0x2355, 0x2356, 0x2357, 0x265c, 0x2f88, 0x2f89, 0x2f8a, - 0x2f8b, 0x2f8c, 0x2f8d, 0x2f8e, 0x2f8f, 0x2f90, 0x2f91, 0x2f92, - 0x2f93, 0x2f94, 0x2f95, 0x2f96, 0x2f97, 0x2f98, 0x2f99, 0x2f9a, - 0x2f9b, 0x2f9c, 0x2f9d, 0x2f9e, 0x2f9f, 0x2fa0, 0x2fa1, 0x2fa2, - 0x2fa3, 0x2fa4, 0x2fa5, 0x2fa6, 0x2fa7, 0x2fa8, 0x2fa9, 0x2faa, - 0x2fab, 0x2fac, 0x2fad, 0x2fae, 0x2faf, 0x2fb0, 0x2fb1, 0x2fb2, - 0x2fb3, 0x2fb4, 0x2fb5, 0x2fb6, 0x2fb7, 0x2fb8, 0x2fb9, 0x2fba, - 0x2fbb, 0x4c52, 0x4c53, 0x4e28, 0x4e29, 0x4e2a, 0x4e2b, 0x4e2c, - 0x4e2d, 0x4e2e, 0x4e2f, 0x4e30, 0x4e31, 0x4e32, 0x4e33, 0x4e34, - 0x4e35, 0x4e36, 0x4e37, 0x4e38, 0x4e39, 0x4e3a, 0x4e3b, 0x4e3c, - 0x4e3d, 0x4e3e, 0x4e3f, 0x4e80, 0x4e81, 0x4e82, 0x4e83, 0x4e84, - 0x4e85, 0x4e86, 0x4e87, 0x4e88, 0x4e89, 0x4e8a, 0x4e8b, 0x4e8c, - 0x4e8d, 0x4e8e, 0x4e8f, 0x4e90, 0x4e91, 0x4e92, 0x4e93, 0x4e94, - 0x4e95, 0x4e96, 0x4e97, 0x4e98, 0x4e99, 0x4e9a, 0x4e9b, 0x4e9c, - 0x4e9d, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea1, 0x4ea2, 0x4ea3, 0x4ea4, - 0x4ea5, 0x4ea6, 0x4ea7, 0x4ea8, 0x4ea9, 0x4eaa, 0x4eab, 0x4eac, - 0x4ead, 0x4eae, 0x4eaf, 0x4eb0, 0x4eb1, 0x4eb2, 0x4eb3, 0x4eb4, - 0x4eb5, 0x4eb6, 0x4eb7, 0x4eb8, 0x4eb9, 0x4eba, 0x4ebb, 0x4ebc, - 0x4ebd, 0x4ebe, 0x4ebf, 0x4ec0, 0x4ec1, 0x4ec2, 0x4ec3, 0x4ec4, - 0x4ec5, 0x4ec6, 0x4ec7, 0x4ec8, 0x4ec9, 0x4eca, 0x4ecb, 0x6a04, - 0x6a05, 0x07e2, 0x07e3, 0x07e4, 0x07e5, 0x07e6, 0x07e7, 0x07e8, - 0x07e9, 0x07ea, 0x07eb, 0x07ec, 0x07ed, 0x07ee, 0x07ef, 0x07f0, - 0x07f1, 0x07f2, 0x07f3, 0x07f4, 0x07f5, 0x07f6, 0x07f7, 0x07f8, - 0x07f9, 0x07fa, 0x07fb, 0x07fc, 0x07fd, 0x07fe, 0x07ff, 0x2000, - 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, - 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x200e, 0x200f, 0x2010, - 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2016, 0x2017, 0x2018, - 0x2019, 0x201a, 0x201b, 0x201c, 0x201d, 0x201e, 0x201f, 0x2020, - 0x2021, 0x2022, 0x2023, 0x2024, 0x2025, 0x2026, 0x2027, 0x2028, - 0x2029, 0x202a, 0x202b, 0x202c, 0x202d, 0x202e, 0x202f, 0x2030, - 0x2031, 0x2032, 0x2033, 0x2034, 0x2035, 0x2036, 0x2037, 0x2038, - 0x2039, 0x203a, 0x203b, 0x203c, 0x203d, 0x203e, 0x203f, 0x2040, - 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046, 0x2047, 0x2048, - 0x2049, 0x204a, 0x204b, 0x204c, 0x204d, 0x204e, 0x204f, 0x2050, - 0x2051, 0x2052, 0x2053, 0x2054, 0x2055, 0x2056, 0x2057, 0x2058, - 0x2059, 0x205a, 0x205b, 0x205c, 0x205d, 0x205e, 0x205f, 0x2060, - 0x2061, 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 0x2068, - 0x2069, 0x206a, 0x206b, 0x206c, 0x206d, 0x206e, 0x206f, 0x2070, - 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, - 0x2079, 0x4cba, 0x4cbb, 0x5d88, 0x5d89, 0x5d8a, 0x5d8b, 0x5d8c, - 0x5d8d, 0x5d8e, 0x5d8f, 0x5db0, 0x5db1, 0x5db2, 0x5db3, 0x5db4, - 0x5db5, 0x5db6, 0x5db7, 0x5db8, 0x5db9, 0x5dba, 0x5dbb, 0x5dbc, - 0x5dbd, 0x5dbe, 0x5dbf, 0x5e40, 0x5e41, 0x5e42, 0x5e43, 0x5e44, - 0x5e45, 0x5e46, 0x5e47, 0x5e48, 0x5e49, 0x5e4a, 0x5e4b, 0x5e4c, - 0x5e4d, 0x5e4e, 0x5e4f, 0x5e50, 0x5e51, 0x5e52, 0x5e53, 0x5e54, - 0x5e55, 0x5e56, 0x5e57, 0x5e58, 0x5e59, 0x5e5a, 0x5e5b, 0x5e5c, - 0x5e5d, 0x5e5e, 0x5e5f, 0x5e60, 0x5e61, 0x5e62, 0x5e63, 0x5e64, - 0x5e65, 0x5e66, 0x5e67, 0x5e68, 0x5e69, 0x5e6a, 0x5e6b, 0x5e6c, - 0x5e6d, 0x5e6e, 0x5e6f, 0x5e70, 0x5e71, 0x5e72, 0x5e73, 0x5e74, - 0x5e75, 0x5e76, 0x5e77, 0x5e78, 0x5e79, 0x5e7a, 0x5e7b, 0x5e7c, - 0x5e7d, 0x5e7e, 0x5e7f, 0x5e80, 0x5e81, 0x5e82, 0x5e83, 0x5e84, - 0x5e85, 0x5e86, 0x5e87, 0x5e88, 0x5e89, 0x5e8a, 0x5e8b, 0x5e8c, - 0x5e8d, 0x5e8e, 0x5e8f, 0x5e90, 0x5e91, 0x5e92, 0x5e93, 0x5e94, - 0x5e95, 0x5e96, 0x5e97, 0x5e98, 0x5e99, 0x5e9a, 0x5e9b, 0x5e9c, - 0x5e9d, 0x5e9e, 0x5e9f, 0x5ea0, 0x5ea1, 0x5ea2, 0x5ea3, 0x5ea4, - 0x5ea5, 0x5ea6, 0x5ea7, 0x5ea8, 0x5ea9, 0x5eaa, 0x5eab, 0x5eac, - 0x5ead, 0x5eae, 0x5eaf, 0x5eb0, 0x5eb1, 0x5eb2, 0x5eb3, 0x5eb4, - 0x5eb5, 0x5eb6, 0x5eb7, 0x5eb8, 0x5eb9, 0x5eba, 0x5ebb, 0x5ebc, - 0x5ebd, 0x5ebe, 0x5ebf, 0x5ec0, 0x5ec1, 0x5ec2, 0x5ec3, 0x5ec4, - 0x5ec5, 0x5ec6, 0x5ec7, 0x5ec8, 0x5ec9, 0x5eca, 0x5ecb, 0x5ecc, - 0x5ecd, 0x5ece, 0x5ecf, 0x5ed0, 0x5ed1, 0x5ed2, 0x5ed3, 0x5ed4, - 0x5ed5, 0x5ed6, 0x5ed7, 0x5ed8, 0x5ed9, 0x5eda, 0x5edb, 0x5edc, - 0x5edd, 0x5ede, 0x5edf, 0x5ee0, 0x5ee1, 0x5ee2, 0x5ee3, 0x5ee4, - 0x5ee5, 0x5ee6, 0x5ee7, 0x5ee8, 0x5ee9, 0x5eea, 0x5eeb, 0x5eec, - 0x5eed, 0x5eee, 0x5eef, 0x5ef0, 0x5ef1, 0x5ef2, 0x5ef3, 0x5ef4, - 0x5ef5, 0x5ef6, 0x5ef7, 0x5ef8, 0x5ef9, 0x5efa, 0x5efb, 0x5efc, - 0x5efd, 0x5efe, 0x5eff, 0x5f00, 0x5f01, 0x5f02, 0x5f03, 0x5f04, - 0x5f05, 0x5f06, 0x5f07, 0x5f08, 0x5f09, 0x5f0a, 0x5f0b, 0x5f0c, - 0x5f0d, 0x5f0e, 0x5f0f, 0x0000, -}; - -static const uint8_t table0_mv_bits[1100] = { - 1, 4, 4, 4, 5, 5, 5, 6, - 6, 6, 7, 7, 7, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 8, -}; - -static const uint8_t table0_mvx[1099] = { - 32, 32, 31, 32, 33, 31, 33, 31, - 33, 32, 34, 32, 30, 32, 31, 34, - 35, 32, 34, 33, 29, 33, 30, 30, - 31, 31, 35, 29, 33, 35, 33, 34, - 31, 29, 30, 34, 30, 36, 28, 32, - 34, 37, 30, 27, 32, 25, 39, 32, - 34, 32, 35, 35, 35, 31, 35, 29, - 32, 29, 30, 29, 37, 27, 36, 38, - 37, 33, 32, 31, 29, 31, 28, 36, - 33, 30, 34, 33, 33, 28, 27, 25, - 31, 26, 39, 32, 32, 31, 33, 39, - 31, 38, 28, 36, 21, 23, 43, 36, - 34, 41, 30, 25, 28, 31, 30, 34, - 38, 35, 61, 34, 28, 30, 37, 37, - 35, 27, 36, 3, 59, 38, 37, 32, - 31, 29, 26, 33, 37, 33, 27, 27, - 35, 34, 34, 40, 42, 33, 32, 29, - 4, 5, 28, 24, 25, 35, 39, 38, - 32, 23, 27, 32, 30, 35, 26, 34, - 60, 36, 29, 22, 26, 41, 7, 30, - 38, 30, 36, 29, 30, 41, 26, 25, - 32, 34, 24, 39, 1, 25, 39, 32, - 28, 29, 32, 38, 26, 36, 28, 63, - 28, 39, 23, 21, 26, 35, 31, 35, - 57, 31, 29, 29, 28, 30, 27, 35, - 2, 38, 40, 34, 37, 29, 38, 43, - 26, 32, 33, 42, 24, 40, 28, 32, - 32, 32, 36, 32, 43, 25, 21, 31, - 30, 31, 41, 29, 33, 37, 26, 37, - 27, 59, 23, 33, 35, 31, 31, 37, - 38, 39, 32, 23, 32, 27, 37, 36, - 31, 40, 25, 27, 38, 31, 36, 28, - 31, 36, 25, 45, 3, 34, 38, 39, - 40, 38, 30, 32, 19, 24, 25, 26, - 45, 20, 24, 33, 33, 31, 41, 34, - 39, 47, 40, 58, 59, 41, 33, 3, - 17, 61, 42, 30, 26, 29, 36, 61, - 33, 37, 62, 28, 25, 38, 25, 38, - 17, 23, 34, 33, 21, 33, 49, 27, - 32, 23, 27, 22, 24, 22, 39, 43, - 27, 37, 6, 42, 47, 26, 30, 31, - 41, 39, 33, 22, 45, 36, 32, 45, - 19, 22, 30, 5, 5, 17, 29, 22, - 31, 31, 43, 37, 27, 32, 32, 32, - 33, 34, 43, 35, 29, 26, 22, 32, - 19, 32, 25, 31, 41, 49, 28, 34, - 28, 39, 34, 19, 37, 38, 29, 21, - 36, 42, 24, 48, 16, 28, 49, 22, - 34, 31, 38, 39, 44, 11, 35, 30, - 33, 33, 23, 28, 33, 46, 15, 13, - 24, 41, 24, 34, 34, 30, 26, 24, - 14, 60, 21, 29, 39, 23, 35, 37, - 63, 45, 33, 34, 47, 41, 22, 42, - 35, 35, 23, 32, 35, 43, 32, 7, - 31, 41, 20, 31, 16, 13, 63, 25, - 30, 32, 35, 30, 30, 31, 42, 47, - 39, 38, 40, 40, 51, 55, 56, 18, - 21, 39, 39, 33, 17, 41, 23, 24, - 43, 25, 31, 20, 19, 45, 1, 34, - 31, 22, 35, 15, 46, 46, 35, 31, - 28, 29, 29, 23, 41, 27, 14, 53, - 53, 27, 24, 32, 57, 32, 17, 42, - 37, 29, 33, 1, 25, 32, 32, 63, - 26, 40, 44, 36, 31, 39, 20, 20, - 44, 23, 33, 34, 35, 33, 33, 28, - 41, 23, 41, 41, 29, 25, 26, 49, - 29, 24, 37, 49, 50, 51, 51, 26, - 39, 25, 26, 15, 39, 18, 42, 17, - 4, 31, 32, 32, 60, 1, 42, 32, - 0, 12, 19, 35, 21, 41, 17, 26, - 20, 45, 46, 32, 37, 22, 47, 29, - 31, 27, 29, 30, 21, 33, 35, 18, - 25, 33, 50, 51, 42, 2, 15, 51, - 53, 33, 25, 29, 55, 37, 38, 33, - 38, 59, 38, 33, 39, 13, 32, 40, - 61, 61, 32, 9, 44, 3, 31, 29, - 25, 31, 27, 23, 9, 25, 9, 29, - 20, 30, 30, 42, 18, 28, 25, 28, - 28, 21, 29, 43, 29, 43, 26, 44, - 44, 21, 38, 21, 24, 45, 45, 35, - 39, 22, 35, 36, 34, 34, 45, 34, - 29, 31, 46, 25, 46, 16, 17, 31, - 20, 32, 47, 47, 47, 32, 49, 49, - 49, 31, 1, 27, 28, 39, 39, 21, - 36, 23, 51, 2, 40, 51, 32, 53, - 24, 30, 24, 30, 21, 40, 57, 57, - 31, 41, 58, 32, 12, 4, 32, 34, - 59, 31, 32, 13, 9, 35, 26, 35, - 37, 61, 37, 63, 26, 29, 41, 38, - 23, 20, 41, 26, 41, 42, 42, 42, - 26, 26, 26, 26, 1, 26, 37, 37, - 37, 23, 34, 42, 27, 43, 34, 27, - 31, 24, 33, 16, 3, 31, 24, 33, - 24, 4, 44, 44, 11, 44, 31, 13, - 13, 44, 45, 13, 25, 22, 38, 26, - 38, 38, 39, 32, 30, 39, 30, 22, - 32, 26, 30, 47, 47, 47, 19, 47, - 30, 31, 35, 8, 23, 47, 47, 27, - 35, 47, 31, 48, 35, 19, 36, 49, - 49, 33, 31, 39, 27, 39, 49, 49, - 50, 50, 50, 39, 31, 51, 51, 39, - 28, 33, 33, 21, 40, 31, 52, 53, - 40, 53, 9, 33, 31, 53, 54, 54, - 54, 55, 55, 34, 15, 56, 25, 56, - 21, 21, 40, 40, 25, 40, 58, 36, - 5, 41, 41, 12, 60, 41, 41, 37, - 22, 61, 18, 29, 29, 30, 61, 30, - 61, 62, 62, 30, 30, 63, 18, 13, - 30, 23, 19, 20, 20, 41, 13, 2, - 5, 5, 1, 5, 32, 6, 32, 35, - 20, 35, 27, 35, 35, 36, 36, 13, - 36, 41, 41, 41, 3, 30, 42, 27, - 20, 30, 27, 28, 30, 21, 33, 33, - 14, 24, 30, 42, 24, 33, 25, 42, - 43, 14, 43, 43, 14, 43, 7, 36, - 37, 37, 37, 37, 7, 14, 25, 43, - 43, 44, 15, 37, 7, 7, 3, 1, - 8, 15, 15, 8, 44, 44, 44, 45, - 45, 45, 45, 8, 8, 45, 21, 45, - 28, 28, 28, 21, 28, 28, 22, 37, - 46, 46, 37, 8, 29, 37, 29, 22, - 46, 37, 22, 29, 47, 47, 38, 38, - 16, 38, 38, 33, 38, 22, 47, 47, - 29, 25, 16, 0, 48, 1, 34, 48, - 48, 34, 25, 26, 26, 49, 49, 26, - 1, 49, 4, 26, 4, 49, 1, 9, - 49, 49, 49, 10, 49, 17, 38, 17, - 17, 50, 38, 50, 50, 22, 38, 51, - 38, 38, 51, 39, 39, 18, 22, 39, - 51, 22, 52, 52, 52, 39, 53, 53, - 10, 23, 18, 29, 10, 53, 29, 54, - 11, 54, 11, 11, 55, 1, 18, 55, - 55, 55, 55, 55, 55, 29, 34, 18, - 29, 56, 56, 34, 57, 34, 34, 29, - 29, 57, 57, 35, 35, 35, 35, 35, - 39, 35, 59, 59, 18, 59, 39, 30, - 18, 40, 60, 60, 61, 30, 18, 61, - 61, 19, 19, -}; - -static const uint8_t table0_mvy[1099] = { - 32, 31, 32, 33, 32, 31, 31, 33, - 33, 34, 32, 30, 32, 35, 34, 31, - 32, 29, 33, 30, 32, 34, 33, 31, - 30, 35, 31, 31, 29, 33, 35, 30, - 29, 33, 34, 34, 30, 32, 32, 36, - 29, 32, 35, 32, 28, 32, 32, 27, - 35, 37, 34, 29, 30, 36, 35, 34, - 25, 30, 29, 35, 33, 31, 31, 32, - 31, 28, 39, 28, 29, 37, 31, 33, - 27, 36, 28, 36, 37, 33, 33, 31, - 27, 32, 31, 38, 26, 25, 25, 33, - 39, 31, 34, 30, 32, 32, 32, 34, - 36, 32, 28, 33, 30, 38, 37, 27, - 33, 28, 32, 37, 35, 38, 29, 34, - 27, 29, 29, 32, 32, 34, 35, 3, - 26, 36, 31, 38, 30, 26, 35, 34, - 37, 26, 25, 32, 32, 39, 23, 37, - 32, 32, 29, 32, 29, 36, 29, 30, - 41, 31, 30, 21, 39, 25, 34, 38, - 32, 35, 39, 32, 33, 33, 32, 27, - 29, 25, 28, 27, 26, 31, 30, 35, - 24, 24, 31, 34, 32, 30, 35, 40, - 28, 38, 5, 35, 29, 36, 36, 32, - 38, 30, 33, 31, 35, 26, 23, 38, - 32, 41, 28, 25, 37, 40, 37, 39, - 32, 36, 33, 39, 25, 26, 28, 31, - 28, 42, 23, 31, 33, 31, 39, 1, - 59, 22, 27, 4, 33, 34, 33, 24, - 41, 3, 35, 41, 41, 28, 36, 36, - 28, 33, 35, 21, 23, 21, 22, 37, - 27, 27, 43, 29, 60, 39, 27, 25, - 59, 34, 27, 27, 26, 40, 37, 27, - 61, 26, 39, 33, 31, 22, 37, 25, - 30, 25, 24, 61, 31, 34, 25, 38, - 32, 32, 30, 3, 61, 43, 29, 23, - 28, 32, 28, 32, 31, 34, 5, 33, - 32, 33, 33, 42, 37, 23, 38, 31, - 40, 26, 32, 26, 37, 38, 36, 24, - 29, 30, 20, 22, 29, 24, 32, 41, - 2, 34, 25, 33, 29, 31, 39, 35, - 36, 24, 32, 30, 33, 27, 44, 60, - 30, 36, 19, 34, 31, 24, 16, 35, - 32, 38, 21, 33, 31, 31, 21, 35, - 5, 17, 29, 38, 38, 18, 58, 19, - 43, 41, 30, 41, 43, 39, 29, 7, - 29, 17, 28, 19, 28, 31, 25, 19, - 40, 26, 21, 33, 39, 23, 40, 30, - 39, 34, 35, 32, 32, 24, 33, 30, - 40, 47, 39, 37, 32, 33, 24, 23, - 45, 47, 27, 23, 42, 32, 32, 33, - 36, 37, 37, 17, 18, 22, 40, 38, - 32, 31, 35, 24, 17, 25, 17, 23, - 33, 34, 51, 42, 31, 36, 36, 29, - 21, 22, 37, 44, 43, 25, 47, 33, - 45, 27, 31, 58, 31, 32, 31, 38, - 43, 20, 47, 45, 54, 1, 26, 34, - 38, 14, 22, 24, 33, 34, 32, 32, - 37, 21, 23, 49, 35, 23, 28, 39, - 39, 23, 55, 33, 30, 30, 63, 16, - 42, 28, 13, 33, 33, 35, 19, 46, - 43, 17, 19, 36, 39, 24, 31, 32, - 33, 26, 28, 62, 33, 63, 33, 39, - 19, 49, 17, 31, 43, 13, 15, 29, - 25, 35, 33, 23, 49, 41, 28, 29, - 34, 38, 7, 61, 11, 50, 13, 41, - 19, 47, 25, 26, 15, 42, 41, 29, - 45, 27, 17, 35, 32, 29, 32, 24, - 13, 26, 26, 31, 24, 33, 28, 30, - 31, 11, 45, 46, 33, 33, 35, 57, - 32, 32, 35, 45, 34, 11, 37, 42, - 39, 37, 31, 49, 21, 27, 29, 47, - 53, 40, 51, 16, 26, 1, 40, 30, - 41, 44, 34, 25, 27, 31, 35, 35, - 31, 15, 49, 1, 35, 40, 5, 58, - 21, 29, 22, 59, 45, 31, 9, 26, - 9, 29, 11, 32, 30, 3, 13, 20, - 18, 20, 11, 3, 29, 40, 31, 53, - 30, 17, 20, 37, 31, 42, 47, 47, - 54, 38, 9, 34, 13, 37, 21, 25, - 27, 43, 42, 45, 40, 25, 27, 46, - 22, 25, 53, 20, 2, 14, 39, 15, - 22, 44, 34, 21, 38, 33, 27, 48, - 34, 52, 35, 47, 49, 54, 2, 13, - 23, 52, 29, 45, 22, 49, 54, 21, - 40, 42, 31, 30, 29, 34, 0, 25, - 23, 51, 24, 59, 28, 38, 29, 31, - 2, 13, 31, 8, 31, 33, 12, 45, - 41, 7, 14, 30, 25, 18, 43, 20, - 43, 35, 44, 1, 49, 42, 42, 18, - 41, 38, 41, 44, 53, 11, 20, 25, - 45, 46, 47, 48, 39, 52, 46, 49, - 63, 55, 44, 38, 13, 13, 57, 22, - 51, 16, 12, 28, 35, 57, 25, 20, - 26, 28, 28, 29, 32, 31, 62, 34, - 35, 35, 19, 49, 48, 39, 40, 18, - 43, 46, 11, 6, 48, 19, 49, 41, - 10, 23, 58, 17, 21, 23, 34, 30, - 60, 0, 44, 34, 26, 37, 46, 43, - 49, 59, 4, 34, 59, 37, 22, 25, - 28, 46, 6, 40, 59, 42, 36, 61, - 28, 30, 31, 43, 10, 22, 23, 47, - 20, 52, 55, 36, 25, 16, 1, 11, - 27, 29, 5, 63, 18, 41, 31, 34, - 38, 1, 5, 13, 28, 31, 17, 38, - 39, 41, 36, 37, 22, 39, 33, 43, - 43, 15, 17, 49, 30, 21, 22, 20, - 10, 17, 25, 54, 57, 3, 34, 8, - 36, 25, 31, 14, 15, 19, 29, 25, - 18, 39, 53, 22, 27, 20, 29, 33, - 41, 42, 35, 62, 50, 29, 53, 50, - 35, 55, 42, 61, 63, 4, 7, 42, - 21, 46, 47, 49, 27, 46, 17, 55, - 41, 50, 63, 4, 56, 18, 8, 10, - 18, 51, 63, 36, 55, 18, 5, 55, - 9, 29, 17, 21, 30, 27, 1, 59, - 7, 11, 12, 15, 5, 42, 24, 41, - 43, 7, 27, 22, 25, 31, 30, 37, - 22, 39, 53, 29, 36, 37, 48, 0, - 5, 13, 17, 31, 32, 26, 46, 28, - 44, 45, 46, 53, 49, 51, 3, 41, - 3, 22, 42, 33, 5, 45, 7, 22, - 40, 53, 24, 14, 25, 27, 10, 12, - 34, 16, 17, 53, 20, 26, 39, 45, - 18, 45, 35, 33, 31, 49, 4, 39, - 42, 11, 51, 5, 13, 26, 27, 17, - 52, 30, 0, 22, 12, 34, 62, 36, - 38, 41, 47, 30, 63, 38, 41, 43, - 59, 33, 45, 37, 38, 40, 47, 24, - 48, 49, 30, 1, 10, 22, 49, 15, - 39, 59, 31, 32, 33, 18, 13, 15, - 31, 21, 27, 44, 42, 39, 46, 17, - 26, 32, 30, 31, 0, 30, 34, 9, - 12, 13, 25, 31, 32, 55, 43, 35, - 61, 33, 35, 46, 25, 47, 48, 62, - 63, 38, 61, 1, 2, 5, 7, 9, - 46, 10, 34, 35, 36, 55, 51, 7, - 40, 23, 34, 37, 5, 13, 42, 18, - 25, 27, 28, -}; - -/* motion vector table 1 */ -static const uint16_t table1_mv_code[1100] = { - 0x0000, 0x0007, 0x0009, 0x000f, 0x000a, 0x0011, 0x001a, 0x001c, - 0x0011, 0x0031, 0x0025, 0x002d, 0x002f, 0x006f, 0x0075, 0x0041, - 0x004c, 0x004e, 0x005c, 0x0060, 0x0062, 0x0066, 0x0068, 0x0069, - 0x006b, 0x00a6, 0x00c1, 0x00cb, 0x00cc, 0x00ce, 0x00da, 0x00e8, - 0x00ee, 0x0087, 0x0090, 0x009e, 0x009f, 0x00ba, 0x00ca, 0x00d8, - 0x00db, 0x00df, 0x0104, 0x0109, 0x010c, 0x0143, 0x0145, 0x014a, - 0x0156, 0x015c, 0x01b3, 0x01d3, 0x01da, 0x0103, 0x0109, 0x010b, - 0x0122, 0x0127, 0x0134, 0x0161, 0x0164, 0x0176, 0x0184, 0x018d, - 0x018e, 0x018f, 0x0190, 0x0193, 0x0196, 0x019d, 0x019e, 0x019f, - 0x01a9, 0x01b2, 0x01b4, 0x01ba, 0x01bb, 0x01bc, 0x0201, 0x0202, - 0x0205, 0x0207, 0x020d, 0x0210, 0x0211, 0x0215, 0x021b, 0x021f, - 0x0281, 0x0285, 0x0290, 0x029c, 0x029d, 0x02a2, 0x02a7, 0x02a8, - 0x02aa, 0x02b0, 0x02b1, 0x02b4, 0x02bc, 0x02bf, 0x0320, 0x0326, - 0x0327, 0x0329, 0x032a, 0x0336, 0x0360, 0x0362, 0x0363, 0x0372, - 0x03b2, 0x03bc, 0x03bd, 0x0203, 0x0205, 0x021a, 0x0249, 0x024a, - 0x024c, 0x02c7, 0x02ca, 0x02ce, 0x02ef, 0x030d, 0x0322, 0x0325, - 0x0338, 0x0373, 0x037a, 0x0409, 0x0415, 0x0416, 0x0418, 0x0428, - 0x042d, 0x042f, 0x0434, 0x0508, 0x0509, 0x0510, 0x0511, 0x051c, - 0x051e, 0x0524, 0x0541, 0x0543, 0x0546, 0x0547, 0x054d, 0x0557, - 0x055f, 0x056a, 0x056c, 0x056d, 0x056f, 0x0576, 0x0577, 0x057a, - 0x057b, 0x057c, 0x057d, 0x0600, 0x0601, 0x0603, 0x0614, 0x0616, - 0x0617, 0x061c, 0x061f, 0x0642, 0x0648, 0x0649, 0x064a, 0x064b, - 0x0657, 0x0668, 0x0669, 0x066b, 0x066e, 0x067f, 0x06c2, 0x06c8, - 0x06cb, 0x06de, 0x06df, 0x06e2, 0x06e3, 0x06ef, 0x0748, 0x074b, - 0x076e, 0x076f, 0x077c, 0x0409, 0x0423, 0x0428, 0x0429, 0x042a, - 0x042b, 0x0432, 0x0433, 0x0496, 0x049a, 0x04d5, 0x04db, 0x0581, - 0x0582, 0x058b, 0x058c, 0x058d, 0x0598, 0x0599, 0x059a, 0x059e, - 0x05dd, 0x0619, 0x0632, 0x0633, 0x0648, 0x0672, 0x06a1, 0x06a2, - 0x06a3, 0x06af, 0x06e2, 0x06e3, 0x06e4, 0x0800, 0x0801, 0x0802, - 0x0803, 0x081a, 0x081b, 0x0829, 0x082f, 0x0832, 0x083e, 0x083f, - 0x0852, 0x0853, 0x0858, 0x086b, 0x0877, 0x0878, 0x0879, 0x087a, - 0x087b, 0x0a00, 0x0a01, 0x0a0d, 0x0a0e, 0x0a0f, 0x0a24, 0x0a37, - 0x0a3a, 0x0a3b, 0x0a3e, 0x0a46, 0x0a47, 0x0a4a, 0x0a4b, 0x0a5f, - 0x0a79, 0x0a7a, 0x0a7b, 0x0a80, 0x0a81, 0x0a84, 0x0a85, 0x0a99, - 0x0aa5, 0x0aa6, 0x0ab8, 0x0aba, 0x0abb, 0x0abc, 0x0abd, 0x0ac8, - 0x0ace, 0x0acf, 0x0ad7, 0x0adc, 0x0aeb, 0x0c04, 0x0c25, 0x0c26, - 0x0c27, 0x0c2a, 0x0c2b, 0x0c3a, 0x0c3b, 0x0c3c, 0x0c3d, 0x0ca0, - 0x0cad, 0x0cd4, 0x0cd5, 0x0cfc, 0x0cfd, 0x0d86, 0x0d92, 0x0d93, - 0x0d94, 0x0d95, 0x0db0, 0x0db8, 0x0db9, 0x0dba, 0x0dbb, 0x0dc0, - 0x0dc2, 0x0dc3, 0x0dda, 0x0ddb, 0x0ddc, 0x0ddd, 0x0e92, 0x0e93, - 0x0e94, 0x0e95, 0x0ec7, 0x0ecc, 0x0ece, 0x0ecf, 0x0ed8, 0x0ed9, - 0x0eda, 0x0edb, 0x0808, 0x0809, 0x080a, 0x0810, 0x0811, 0x0844, - 0x0845, 0x0861, 0x0862, 0x0863, 0x086c, 0x0922, 0x0923, 0x092e, - 0x092f, 0x0936, 0x0937, 0x09b1, 0x09b2, 0x09b3, 0x09b4, 0x09b5, - 0x09b8, 0x09b9, 0x09ba, 0x09bb, 0x09bc, 0x09bd, 0x09be, 0x09bf, - 0x0b00, 0x0b15, 0x0b2c, 0x0b2d, 0x0b2e, 0x0b2f, 0x0b36, 0x0bb9, - 0x0c28, 0x0c2a, 0x0c2b, 0x0c2c, 0x0c2d, 0x0c2e, 0x0c2f, 0x0c30, - 0x0c31, 0x0c38, 0x0c60, 0x0c61, 0x0c62, 0x0c63, 0x0c8d, 0x0c8e, - 0x0c8f, 0x0c92, 0x0cbe, 0x0cbf, 0x0ce6, 0x0ce7, 0x0d40, 0x0d41, - 0x0d57, 0x0d58, 0x0d59, 0x0d5a, 0x0d5b, 0x0d5c, 0x0d5d, 0x0d98, - 0x0d99, 0x0d9a, 0x0d9b, 0x0d9c, 0x0d9d, 0x0dad, 0x0dae, 0x0daf, - 0x0dc0, 0x0dc1, 0x0dc2, 0x0dc3, 0x0dca, 0x0dcb, 0x0dec, 0x0ded, - 0x0dee, 0x0def, 0x1018, 0x1022, 0x1023, 0x1030, 0x1031, 0x1032, - 0x1033, 0x1050, 0x1051, 0x105c, 0x1074, 0x1075, 0x1076, 0x1077, - 0x1078, 0x1079, 0x107a, 0x107b, 0x10b2, 0x10b3, 0x10b8, 0x10b9, - 0x10ba, 0x10bb, 0x10d4, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x1404, - 0x1405, 0x1406, 0x1407, 0x1410, 0x1411, 0x1412, 0x1413, 0x1414, - 0x1415, 0x1416, 0x1417, 0x1418, 0x1419, 0x1466, 0x1467, 0x1468, - 0x1469, 0x146a, 0x146b, 0x146c, 0x146d, 0x147e, 0x147f, 0x1488, - 0x1489, 0x148a, 0x148b, 0x14b6, 0x14b7, 0x14b8, 0x14b9, 0x14ba, - 0x14bb, 0x14bc, 0x14bd, 0x14f0, 0x14f1, 0x14f8, 0x14f9, 0x14fa, - 0x14fb, 0x14fc, 0x14fd, 0x14fe, 0x14ff, 0x152a, 0x152b, 0x152c, - 0x152d, 0x152e, 0x152f, 0x1530, 0x1531, 0x1548, 0x1549, 0x154e, - 0x154f, 0x1558, 0x1559, 0x155a, 0x155b, 0x1572, 0x159a, 0x159b, - 0x15ac, 0x15ba, 0x15bb, 0x15d0, 0x15d1, 0x15d2, 0x15d3, 0x15d4, - 0x15d5, 0x181d, 0x181e, 0x181f, 0x1840, 0x1841, 0x1842, 0x1843, - 0x1844, 0x1845, 0x1846, 0x1847, 0x1848, 0x1849, 0x1861, 0x1862, - 0x1863, 0x1864, 0x1865, 0x1866, 0x1867, 0x1868, 0x1869, 0x186a, - 0x186b, 0x186c, 0x186d, 0x186e, 0x191b, 0x191c, 0x191d, 0x191e, - 0x191f, 0x1942, 0x1943, 0x1944, 0x1945, 0x1946, 0x1947, 0x1958, - 0x1959, 0x19ed, 0x19ee, 0x19ef, 0x19f0, 0x19f1, 0x19f2, 0x19f3, - 0x19f4, 0x19f5, 0x19f6, 0x19f7, 0x1b0e, 0x1b0f, 0x1b62, 0x1b63, - 0x1b64, 0x1b65, 0x1b66, 0x1b67, 0x1b68, 0x1b69, 0x1b6a, 0x1b6b, - 0x1b6c, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b82, 0x1ba8, 0x1ba9, 0x1baa, - 0x1bab, 0x1bac, 0x1bad, 0x1bae, 0x1baf, 0x1bb0, 0x1bb1, 0x1bb2, - 0x1bb3, 0x1d80, 0x1d81, 0x1d82, 0x1d83, 0x1d84, 0x1d85, 0x1d86, - 0x1d87, 0x1d88, 0x1d89, 0x1d8a, 0x1d8b, 0x1d8c, 0x1d8d, 0x1007, - 0x1008, 0x1009, 0x100a, 0x100b, 0x100c, 0x100d, 0x100e, 0x100f, - 0x1016, 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, - 0x1087, 0x10c0, 0x123a, 0x123b, 0x123c, 0x123d, 0x123e, 0x123f, - 0x1240, 0x1241, 0x1242, 0x1243, 0x1350, 0x1352, 0x1353, 0x1358, - 0x1359, 0x135a, 0x135b, 0x135c, 0x135d, 0x135e, 0x135f, 0x1360, - 0x1361, 0x1602, 0x1603, 0x160c, 0x160d, 0x160e, 0x160f, 0x1620, - 0x1621, 0x1622, 0x1623, 0x1624, 0x1625, 0x1626, 0x1627, 0x1628, - 0x1629, 0x166e, 0x166f, 0x167c, 0x167d, 0x167e, 0x167f, 0x1770, - 0x1771, 0x1852, 0x1853, 0x1872, 0x1873, 0x1874, 0x1875, 0x1876, - 0x1877, 0x1878, 0x1879, 0x187a, 0x187b, 0x187c, 0x187d, 0x187e, - 0x187f, 0x1918, 0x1919, 0x1926, 0x1927, 0x1970, 0x1971, 0x1972, - 0x1973, 0x1974, 0x1975, 0x1976, 0x1977, 0x1978, 0x1979, 0x197a, - 0x197b, 0x1aa0, 0x1aa1, 0x1aa2, 0x1aa3, 0x1aa4, 0x1aa5, 0x1aa6, - 0x1aa7, 0x1aa8, 0x1aa9, 0x1aaa, 0x1aab, 0x1aac, 0x1aad, 0x1b3c, - 0x1b3d, 0x1b3e, 0x1b3f, 0x1b50, 0x1b51, 0x1b52, 0x1b53, 0x1b54, - 0x1b55, 0x1b56, 0x1b57, 0x1b58, 0x1b59, 0x2032, 0x2033, 0x2034, - 0x2035, 0x2036, 0x2037, 0x2038, 0x2039, 0x203a, 0x203b, 0x203c, - 0x203d, 0x203e, 0x203f, 0x2040, 0x2041, 0x2042, 0x2043, 0x20ba, - 0x20bb, 0x20cc, 0x20cd, 0x20ce, 0x20cf, 0x20e0, 0x20e1, 0x20e2, - 0x20e3, 0x20e4, 0x20e5, 0x20e6, 0x20e7, 0x21aa, 0x21ab, 0x21c0, - 0x21c1, 0x21c2, 0x21c3, 0x21c4, 0x21c5, 0x21c6, 0x21c7, 0x21c8, - 0x21c9, 0x21ca, 0x21cb, 0x21cc, 0x21cd, 0x21ce, 0x21cf, 0x21d0, - 0x21d1, 0x21d2, 0x21d3, 0x2894, 0x2895, 0x2896, 0x2897, 0x2898, - 0x2899, 0x289a, 0x289b, 0x289c, 0x289d, 0x289e, 0x289f, 0x28c0, - 0x28c1, 0x28c2, 0x28c3, 0x28c4, 0x28c5, 0x28c6, 0x28c7, 0x28c8, - 0x28c9, 0x28ca, 0x28cb, 0x2930, 0x2931, 0x2932, 0x2933, 0x2934, - 0x2935, 0x2936, 0x2937, 0x2938, 0x2939, 0x293a, 0x293b, 0x293c, - 0x293d, 0x293e, 0x293f, 0x2960, 0x2961, 0x2962, 0x2963, 0x2964, - 0x2965, 0x2966, 0x2967, 0x2968, 0x2969, 0x296a, 0x296b, 0x2a40, - 0x2a41, 0x2a42, 0x2a43, 0x2a44, 0x2a45, 0x2a46, 0x2a47, 0x2a48, - 0x2a49, 0x2a4a, 0x2a4b, 0x2a4c, 0x2a4d, 0x2a4e, 0x2a4f, 0x2a50, - 0x2a51, 0x2a52, 0x2a53, 0x2ae6, 0x2ae7, 0x2b24, 0x2b25, 0x2b26, - 0x2b27, 0x2b28, 0x2b29, 0x2b2a, 0x2b2b, 0x2b2c, 0x2b2d, 0x2b2e, - 0x2b2f, 0x2b30, 0x2b31, 0x2b32, 0x2b33, 0x2b5a, 0x2b5b, 0x3014, - 0x3015, 0x3016, 0x3017, 0x3020, 0x3021, 0x3022, 0x3023, 0x3024, - 0x3025, 0x3026, 0x3027, 0x3028, 0x3029, 0x302a, 0x302b, 0x302c, - 0x302d, 0x302e, 0x302f, 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, - 0x3035, 0x3036, 0x3037, 0x3038, 0x3039, 0x30c0, 0x30c1, 0x30de, - 0x30df, 0x3218, 0x3219, 0x321a, 0x321b, 0x321c, 0x321d, 0x321e, - 0x321f, 0x3220, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226, - 0x3227, 0x3228, 0x3229, 0x322a, 0x322b, 0x322c, 0x322d, 0x322e, - 0x322f, 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3378, - 0x3379, 0x337a, 0x337b, 0x337c, 0x337d, 0x337e, 0x337f, 0x33c0, - 0x33c1, 0x33c2, 0x33c3, 0x33c4, 0x33c5, 0x33c6, 0x33c7, 0x33c8, - 0x33c9, 0x33ca, 0x33cb, 0x33cc, 0x33cd, 0x33ce, 0x33cf, 0x33d0, - 0x33d1, 0x33d2, 0x33d3, 0x33d4, 0x33d5, 0x33d6, 0x33d7, 0x33d8, - 0x33d9, 0x3706, 0x3707, 0x3730, 0x3731, 0x3732, 0x3733, 0x3734, - 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, 0x373a, 0x373b, 0x373c, - 0x373d, 0x373e, 0x373f, 0x3740, 0x3741, 0x3742, 0x3743, 0x3744, - 0x3745, 0x3746, 0x3747, 0x3748, 0x3749, 0x374a, 0x374b, 0x374c, - 0x374d, 0x374e, 0x374f, 0x3b34, 0x3b35, 0x3b36, 0x3b37, 0x3be8, - 0x3be9, 0x3bea, 0x3beb, 0x3bec, 0x3bed, 0x3bee, 0x3bef, 0x3bf0, - 0x3bf1, 0x3bf2, 0x3bf3, 0x3bf4, 0x3bf5, 0x3bf6, 0x3bf7, 0x3bf8, - 0x3bf9, 0x3bfa, 0x3bfb, 0x3bfc, 0x3bfd, 0x3bfe, 0x3bff, 0x2000, - 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, - 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x202e, 0x202f, 0x2182, - 0x2183, 0x21b4, 0x21b5, 0x21b6, 0x21b7, 0x21b8, 0x21b9, 0x21ba, - 0x21bb, 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x2460, 0x2461, 0x2462, - 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246a, - 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, 0x2472, - 0x2473, 0x26a2, 0x26a3, 0x000b, -}; +#ifndef FFMPEG_MSMPEG4DATA_H +#define FFMPEG_MSMPEG4DATA_H -static const uint8_t table1_mv_bits[1100] = { - 2, 4, 4, 4, 5, 5, 5, 5, - 6, 6, 7, 7, 7, 7, 7, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 4, -}; - -static const uint8_t table1_mvx[1099] = { - 32, 31, 32, 31, 33, 32, 33, 33, - 31, 34, 30, 32, 32, 34, 35, 32, - 34, 33, 29, 30, 30, 32, 31, 31, - 33, 35, 35, 33, 31, 29, 29, 33, - 34, 30, 31, 28, 36, 30, 34, 32, - 32, 37, 32, 32, 25, 27, 39, 32, - 32, 32, 38, 35, 36, 32, 37, 61, - 26, 32, 34, 35, 3, 35, 27, 28, - 29, 34, 28, 37, 31, 36, 32, 27, - 31, 30, 29, 39, 33, 29, 33, 35, - 25, 25, 29, 33, 31, 31, 31, 33, - 32, 30, 32, 32, 41, 39, 33, 36, - 32, 28, 34, 36, 38, 24, 60, 31, - 23, 28, 32, 33, 59, 32, 40, 30, - 5, 34, 32, 38, 32, 30, 43, 4, - 32, 32, 42, 31, 31, 32, 26, 38, - 26, 22, 21, 37, 61, 63, 37, 31, - 32, 33, 2, 1, 23, 33, 41, 27, - 35, 30, 38, 23, 33, 3, 28, 34, - 34, 27, 41, 29, 39, 35, 36, 29, - 32, 27, 30, 32, 24, 61, 37, 26, - 59, 25, 35, 27, 36, 37, 30, 31, - 34, 40, 3, 28, 34, 39, 32, 31, - 32, 30, 24, 28, 35, 36, 26, 32, - 31, 33, 29, 33, 39, 25, 30, 24, - 35, 59, 29, 34, 25, 30, 21, 35, - 43, 40, 32, 29, 5, 28, 31, 62, - 33, 33, 25, 31, 21, 31, 43, 31, - 34, 33, 20, 40, 39, 31, 31, 57, - 38, 32, 42, 33, 32, 31, 32, 29, - 30, 44, 5, 31, 22, 34, 36, 17, - 38, 58, 38, 35, 32, 60, 35, 24, - 32, 38, 16, 45, 42, 32, 31, 29, - 4, 30, 17, 40, 46, 48, 63, 32, - 42, 19, 41, 22, 28, 36, 45, 33, - 33, 32, 29, 7, 41, 42, 18, 33, - 33, 32, 22, 37, 1, 26, 22, 23, - 49, 28, 26, 27, 32, 33, 27, 23, - 28, 36, 15, 6, 34, 27, 31, 26, - 23, 2, 33, 32, 34, 41, 28, 32, - 41, 0, 36, 38, 34, 31, 47, 32, - 17, 31, 39, 33, 37, 51, 30, 47, - 32, 50, 32, 19, 63, 30, 25, 27, - 33, 62, 24, 31, 27, 30, 37, 31, - 45, 32, 39, 20, 46, 47, 35, 19, - 34, 1, 49, 21, 21, 14, 51, 26, - 23, 31, 36, 35, 58, 29, 29, 21, - 20, 42, 13, 28, 12, 40, 31, 33, - 39, 60, 32, 44, 33, 31, 28, 37, - 29, 32, 30, 49, 43, 28, 39, 25, - 32, 48, 2, 15, 20, 25, 31, 28, - 21, 24, 25, 15, 31, 17, 37, 43, - 18, 32, 33, 24, 33, 36, 13, 33, - 31, 39, 11, 31, 33, 32, 39, 37, - 32, 32, 29, 17, 44, 46, 36, 35, - 26, 37, 58, 32, 34, 38, 8, 38, - 38, 22, 29, 25, 16, 35, 32, 35, - 33, 43, 18, 46, 38, 50, 33, 18, - 53, 60, 13, 32, 36, 33, 51, 36, - 43, 45, 27, 42, 29, 24, 30, 25, - 31, 52, 31, 35, 38, 9, 22, 34, - 4, 17, 28, 55, 42, 25, 17, 20, - 47, 34, 33, 16, 40, 25, 16, 30, - 53, 29, 10, 11, 14, 26, 33, 4, - 35, 44, 26, 16, 31, 26, 34, 38, - 29, 31, 30, 24, 22, 61, 32, 9, - 45, 34, 31, 19, 9, 31, 46, 31, - 35, 54, 29, 57, 30, 50, 3, 31, - 63, 34, 47, 41, 51, 18, 31, 14, - 37, 38, 31, 24, 32, 31, 50, 33, - 31, 54, 27, 9, 33, 23, 19, 32, - 29, 29, 33, 28, 47, 49, 30, 47, - 33, 27, 25, 54, 44, 45, 50, 58, - 51, 48, 33, 59, 33, 34, 57, 13, - 26, 33, 13, 48, 30, 11, 7, 56, - 34, 55, 26, 0, 26, 35, 1, 51, - 33, 53, 31, 45, 12, 29, 29, 51, - 31, 48, 2, 6, 34, 30, 28, 33, - 60, 40, 27, 46, 31, 9, 35, 29, - 31, 39, 55, 46, 19, 37, 62, 34, - 30, 16, 19, 49, 41, 41, 39, 37, - 14, 5, 13, 35, 55, 30, 40, 40, - 42, 8, 20, 25, 45, 35, 33, 36, - 54, 38, 27, 37, 62, 40, 15, 59, - 49, 31, 29, 34, 34, 39, 24, 29, - 25, 29, 21, 29, 10, 61, 33, 49, - 35, 34, 3, 38, 39, 29, 7, 41, - 1, 35, 4, 23, 15, 23, 11, 37, - 28, 35, 30, 30, 24, 1, 43, 56, - 8, 34, 42, 24, 45, 30, 20, 23, - 8, 38, 22, 33, 17, 52, 34, 22, - 53, 43, 44, 1, 27, 31, 41, 43, - 41, 30, 31, 36, 30, 5, 55, 31, - 33, 30, 40, 23, 15, 29, 34, 34, - 59, 34, 30, 11, 13, 38, 5, 0, - 30, 42, 5, 30, 29, 34, 10, 44, - 30, 63, 35, 12, 3, 26, 15, 17, - 25, 34, 43, 39, 34, 56, 29, 23, - 30, 12, 30, 10, 35, 9, 24, 58, - 10, 12, 54, 33, 37, 20, 41, 35, - 29, 18, 61, 30, 40, 24, 39, 53, - 62, 26, 29, 33, 34, 53, 49, 21, - 27, 11, 63, 20, 26, 23, 7, 13, - 6, 47, 29, 30, 9, 51, 22, 34, - 21, 25, 33, 56, 57, 30, 38, 51, - 51, 38, 63, 28, 40, 35, 33, 18, - 33, 33, 24, 58, 58, 34, 49, 29, - 43, 4, 1, 4, 42, 35, 35, 30, - 17, 5, 56, 61, 25, 37, 36, 55, - 28, 35, 29, 50, 48, 52, 2, 42, - 34, 40, 46, 46, 43, 35, 29, 48, - 20, 29, 31, 41, 7, 30, 35, 19, - 14, 21, 8, 39, 39, 40, 46, 55, - 34, 6, 30, 34, 37, 25, 37, 33, - 22, 44, 52, 17, 35, 29, 36, 35, - 40, 37, 28, 30, 50, 14, 28, 55, - 6, 23, 19, 14, 30, 3, 30, 28, - 28, 61, 61, 47, 45, 48, 40, 40, - 34, 34, 25, 30, 29, 35, 4, 26, - 53, 50, 26, 41, 27, 59, 27, 38, - 39, 3, 50, 43, 47, 23, 33, 55, - 35, 21, 23, 35, 61, 33, 46, 52, - 35, 34, 24, 30, 43, 16, 37, 21, - 2, 24, 45, 34, 30, 55, 55, 1, - 29, 29, 26, 28, 25, 31, 36, 22, - 17, 30, 52, 2, 44, 44, 57, 26, - 62, 41, 39, 57, 26, 46, 49, 11, - 16, 19, 5, 59, 38, 39, 58, 38, - 25, 49, 50, 22, 28, 59, 9, 59, - 7, 28, 55, 17, 4, 35, 50, 21, - 29, 44, 47, 18, 24, 19, 25, 42, - 35, 3, 51, 35, 16, 35, 30, 63, - 57, 39, 39, 25, 35, 38, 9, 16, - 36, 45, 31, 60, 14, 34, 42, 24, - 0, 37, 18, 61, 57, 37, 28, 53, - 20, 46, 14, 47, 38, 38, 38, 9, - 34, 39, 43, 17, 39, 59, 5, 27, - 0, 12, 27, -}; - -static const uint8_t table1_mvy[1099] = { - 32, 32, 31, 31, 32, 33, 31, 33, - 33, 32, 32, 30, 34, 31, 32, 29, - 33, 30, 32, 33, 31, 35, 34, 30, - 34, 31, 33, 29, 29, 31, 33, 35, - 30, 30, 35, 32, 32, 34, 34, 28, - 25, 32, 36, 27, 32, 32, 32, 37, - 39, 3, 32, 30, 31, 26, 31, 32, - 32, 38, 29, 29, 32, 34, 31, 31, - 34, 35, 33, 33, 28, 33, 1, 33, - 27, 29, 30, 31, 28, 29, 37, 35, - 31, 33, 35, 27, 36, 37, 25, 25, - 61, 35, 4, 5, 32, 33, 36, 30, - 23, 30, 28, 34, 31, 32, 32, 39, - 32, 34, 21, 39, 32, 59, 32, 28, - 32, 36, 60, 33, 24, 36, 32, 32, - 41, 2, 32, 38, 26, 22, 33, 30, - 31, 32, 32, 30, 31, 32, 29, 3, - 40, 38, 32, 32, 33, 26, 31, 34, - 28, 38, 34, 31, 3, 31, 35, 38, - 27, 35, 33, 28, 29, 27, 29, 27, - 43, 29, 37, 63, 31, 33, 34, 30, - 31, 30, 37, 30, 35, 35, 26, 41, - 37, 31, 33, 28, 26, 30, 42, 24, - 7, 27, 33, 29, 36, 28, 34, 57, - 23, 41, 36, 23, 35, 34, 25, 30, - 25, 33, 25, 25, 29, 24, 33, 39, - 33, 33, 0, 37, 31, 36, 21, 32, - 61, 24, 35, 61, 31, 5, 31, 59, - 39, 21, 32, 30, 34, 22, 40, 32, - 29, 16, 31, 5, 62, 2, 20, 39, - 39, 32, 33, 1, 31, 24, 36, 32, - 36, 32, 28, 26, 6, 31, 38, 34, - 58, 35, 32, 33, 33, 17, 43, 26, - 31, 40, 31, 34, 32, 32, 31, 19, - 30, 32, 29, 33, 38, 38, 32, 59, - 40, 18, 38, 32, 35, 34, 32, 17, - 1, 15, 30, 28, 31, 28, 34, 29, - 32, 27, 35, 27, 49, 22, 37, 34, - 37, 26, 32, 32, 22, 28, 45, 29, - 30, 31, 43, 46, 41, 30, 26, 13, - 34, 32, 27, 38, 42, 42, 33, 47, - 33, 60, 27, 42, 25, 32, 22, 32, - 48, 32, 45, 33, 33, 41, 27, 25, - 19, 31, 35, 19, 36, 42, 27, 17, - 31, 44, 28, 33, 33, 31, 23, 31, - 40, 33, 31, 34, 30, 32, 33, 36, - 35, 47, 37, 41, 31, 23, 41, 29, - 30, 35, 32, 25, 32, 28, 58, 2, - 37, 33, 14, 33, 49, 20, 39, 36, - 21, 9, 23, 33, 35, 24, 39, 37, - 11, 33, 30, 31, 31, 28, 51, 40, - 35, 29, 25, 33, 46, 35, 37, 30, - 30, 8, 63, 28, 15, 40, 33, 45, - 49, 25, 32, 4, 47, 51, 36, 39, - 53, 10, 24, 29, 30, 31, 25, 40, - 38, 38, 33, 56, 23, 27, 32, 37, - 26, 29, 43, 36, 33, 24, 55, 43, - 9, 29, 34, 34, 24, 33, 18, 33, - 33, 30, 31, 50, 24, 60, 30, 39, - 34, 30, 39, 28, 22, 38, 2, 26, - 63, 32, 57, 21, 39, 33, 28, 18, - 30, 34, 22, 33, 29, 41, 30, 34, - 35, 21, 13, 34, 35, 39, 30, 46, - 32, 42, 32, 31, 33, 26, 11, 33, - 22, 31, 25, 31, 53, 27, 43, 25, - 40, 50, 21, 36, 38, 30, 12, 31, - 34, 20, 15, 29, 32, 62, 30, 13, - 17, 32, 19, 31, 20, 31, 30, 7, - 1, 17, 34, 37, 31, 31, 44, 34, - 26, 40, 16, 37, 52, 48, 30, 20, - 18, 33, 38, 29, 7, 25, 30, 54, - 45, 47, 46, 41, 29, 29, 16, 30, - 14, 26, 38, 34, 34, 29, 34, 30, - 29, 30, 57, 30, 4, 46, 33, 29, - 39, 44, 30, 31, 50, 33, 31, 32, - 19, 32, 40, 31, 37, 47, 1, 35, - 16, 31, 0, 35, 33, 1, 17, 34, - 9, 34, 33, 31, 49, 43, 42, 51, - 34, 29, 23, 29, 14, 30, 45, 49, - 11, 24, 31, 28, 35, 41, 30, 44, - 18, 29, 34, 35, 36, 25, 26, 21, - 31, 30, 34, 19, 34, 44, 36, 38, - 25, 31, 28, 23, 37, 3, 55, 41, - 30, 22, 41, 24, 33, 26, 35, 35, - 30, 55, 51, 47, 48, 38, 24, 15, - 21, 50, 25, 46, 30, 29, 10, 34, - 42, 45, 29, 42, 22, 3, 33, 27, - 34, 1, 34, 28, 34, 36, 35, 23, - 23, 13, 58, 3, 26, 63, 25, 31, - 34, 61, 38, 39, 25, 61, 29, 37, - 30, 41, 26, 48, 28, 33, 50, 35, - 30, 37, 29, 29, 40, 6, 39, 28, - 28, 19, 8, 22, 45, 34, 35, 10, - 58, 17, 37, 39, 30, 18, 54, 14, - 29, 16, 59, 30, 35, 23, 35, 30, - 47, 36, 29, 55, 20, 12, 31, 35, - 14, 29, 18, 34, 34, 24, 29, 26, - 22, 2, 27, 23, 8, 30, 55, 38, - 60, 31, 4, 34, 49, 34, 27, 34, - 33, 30, 31, 54, 42, 35, 38, 46, - 44, 26, 27, 9, 39, 25, 21, 29, - 28, 42, 13, 0, 5, 34, 37, 28, - 24, 29, 63, 26, 22, 27, 29, 25, - 33, 25, 61, 0, 35, 25, 36, 15, - 27, 40, 53, 33, 3, 10, 16, 37, - 38, 18, 30, 46, 27, 9, 6, 29, - 62, 8, 42, 28, 29, 3, 25, 16, - 26, 29, 35, 28, 27, 51, 61, 48, - 37, 9, 34, 7, 49, 45, 20, 29, - 21, 5, 5, 29, 28, 34, 29, 24, - 10, 24, 35, 36, 38, 55, 11, 36, - 38, 53, 54, 26, 30, 49, 20, 27, - 30, 39, 33, 41, 49, 22, 38, 38, - 4, 30, 8, 9, 3, 24, 22, 50, - 37, 36, 31, 27, 2, 9, 42, 63, - 25, 19, 44, 1, 28, 28, 48, 30, - 34, 41, 41, 38, 12, 27, 15, 0, - 16, 34, 35, 38, 28, 29, 40, 42, - 51, 52, 45, 54, 59, 59, 42, 44, - 37, 26, 46, 24, 15, 39, 22, 46, - 19, 35, 38, 17, 37, 23, 52, 55, - 50, 37, 26, 11, 37, 12, 24, 30, - 16, 13, 22, 13, 36, 35, 40, 41, - 34, 41, 26, 53, 51, 5, 21, 30, - 2, 63, 41, 20, 1, 56, 21, 24, - 25, 5, 28, 35, 26, 28, 30, 18, - 29, 23, 40, 34, 20, 42, 39, 34, - 28, 61, 38, 27, 62, 9, 36, 17, - 9, 49, 24, 25, 54, 34, 39, 37, - 3, 1, 25, 38, 38, 44, 35, 36, - 12, 60, 36, 38, 40, 25, 43, 39, - 53, 28, 39, 57, 46, 10, 52, 27, - 35, 42, 45, 59, 15, 60, 38, 24, - 23, 39, 12, 29, 24, 0, 20, 16, - 28, 43, 35, 28, 1, 49, 4, 21, - 42, 39, 29, 3, 44, 21, 53, 55, - 11, 5, 3, 39, 53, 28, 25, 19, - 34, 28, 21, -}; +#include "common.h" +#include "bitstream.h" +#include "rl.h" /* motion vector table */ typedef struct MVTable { @@ -1797,232 +45,56 @@ typedef struct MVTable { VLC vlc; /* decoding: vlc */ } MVTable; -static MVTable mv_tables[2] = { - { - 1099, - table0_mv_code, - table0_mv_bits, - table0_mvx, - table0_mvy, - }, - { - 1099, - table1_mv_code, - table1_mv_bits, - table1_mvx, - table1_mvy, - } -}; +extern VLC ff_msmp4_mb_i_vlc; +extern VLC ff_msmp4_dc_luma_vlc[2]; +extern VLC ff_msmp4_dc_chroma_vlc[2]; + +/* intra picture macro block coded block pattern */ +extern const uint16_t ff_msmp4_mb_i_table[64][2]; -static const uint8_t v2_mb_type[8][2] = { - {1, 1}, {0 , 2}, {3 , 3}, {9 , 5}, - {5, 4}, {0x21, 7}, {0x20, 7}, {0x11, 6}, -}; +extern const uint8_t cbpy_tab[16][2]; -static const uint8_t v2_intra_cbpc[4][2] = { - {1, 1}, {0, 3}, {1, 3}, {1, 2}, -}; +extern const uint8_t DCtab_lum[13][2]; +extern const uint8_t DCtab_chrom[13][2]; -static const uint8_t wmv1_y_dc_scale_table[32]={ -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 - 0, 8, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21 -}; -static const uint8_t wmv1_c_dc_scale_table[32]={ -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 - 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22 -}; +extern const uint8_t mvtab[33][2]; -static const uint8_t old_ff_y_dc_scale_table[32]={ -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 0, 8, 8, 8, 8,10,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 -}; -static const uint8_t old_ff_c_dc_scale_table[32]={ -// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 - 0, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22 -}; +extern const uint8_t intra_MCBPC_code[9]; +extern const uint8_t intra_MCBPC_bits[9]; +extern const uint8_t inter_MCBPC_code[28]; +extern const uint8_t inter_MCBPC_bits[28]; #define WMV1_SCANTABLE_COUNT 4 -static const uint8_t wmv1_scantable00[64]= { -0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, -0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28, -0x30, 0x38, 0x29, 0x21, 0x1A, 0x13, 0x0C, 0x05, -0x06, 0x0D, 0x14, 0x1B, 0x22, 0x31, 0x39, 0x3A, -0x32, 0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, -0x16, 0x1D, 0x24, 0x2B, 0x33, 0x3B, 0x3C, 0x34, -0x2C, 0x25, 0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x35, -0x3D, 0x3E, 0x36, 0x2E, 0x27, 0x2F, 0x37, 0x3F, -}; -static const uint8_t wmv1_scantable01[64]= { -0x00, 0x08, 0x01, 0x02, 0x09, 0x10, 0x18, 0x11, -0x0A, 0x03, 0x04, 0x0B, 0x12, 0x19, 0x20, 0x28, -0x21, 0x30, 0x1A, 0x13, 0x0C, 0x05, 0x06, 0x0D, -0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39, 0x2A, -0x23, 0x1C, 0x15, 0x0E, 0x07, 0x0F, 0x16, 0x1D, -0x24, 0x2B, 0x32, 0x3A, 0x33, 0x3B, 0x2C, 0x25, -0x1E, 0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3C, 0x35, -0x3D, 0x2E, 0x27, 0x2F, 0x36, 0x3E, 0x37, 0x3F, -}; -static const uint8_t wmv1_scantable02[64]= { -0x00, 0x01, 0x08, 0x02, 0x03, 0x09, 0x10, 0x18, -0x11, 0x0A, 0x04, 0x05, 0x0B, 0x12, 0x19, 0x20, -0x28, 0x30, 0x21, 0x1A, 0x13, 0x0C, 0x06, 0x07, -0x0D, 0x14, 0x1B, 0x22, 0x29, 0x38, 0x31, 0x39, -0x2A, 0x23, 0x1C, 0x15, 0x0E, 0x0F, 0x16, 0x1D, -0x24, 0x2B, 0x32, 0x3A, 0x33, 0x2C, 0x25, 0x1E, -0x17, 0x1F, 0x26, 0x2D, 0x34, 0x3B, 0x3C, 0x35, -0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F, -}; -static const uint8_t wmv1_scantable03[64]= { -0x00, 0x08, 0x10, 0x01, 0x18, 0x20, 0x28, 0x09, -0x02, 0x03, 0x0A, 0x11, 0x19, 0x30, 0x38, 0x29, -0x21, 0x1A, 0x12, 0x0B, 0x04, 0x05, 0x0C, 0x13, -0x1B, 0x22, 0x31, 0x39, 0x32, 0x2A, 0x23, 0x1C, -0x14, 0x0D, 0x06, 0x07, 0x0E, 0x15, 0x1D, 0x24, -0x2B, 0x33, 0x3A, 0x3B, 0x34, 0x2C, 0x25, 0x1E, -0x16, 0x0F, 0x17, 0x1F, 0x26, 0x2D, 0x3C, 0x35, -0x2E, 0x27, 0x2F, 0x36, 0x3D, 0x3E, 0x37, 0x3F, -}; +extern const uint8_t wmv1_scantable[WMV1_SCANTABLE_COUNT][64]; -static const uint8_t *wmv1_scantable[WMV1_SCANTABLE_COUNT+1]={ - wmv1_scantable00, - wmv1_scantable01, - wmv1_scantable02, - wmv1_scantable03, -}; +#define NB_RL_TABLES 6 -static const uint8_t table_inter_intra[4][2]={ - {0,1} /*Luma-Left Chroma-Left*/, - {2,2} /*Luma-Top Chroma-Left*/, - {6,3} /*luma-Left Chroma-Top */, - {7,3} /*luma-Top Chroma-Top */ -}; +extern RLTable rl_table[NB_RL_TABLES]; -#define WMV2_INTER_CBP_TABLE_COUNT 4 +extern const uint8_t wmv1_y_dc_scale_table[32]; +extern const uint8_t wmv1_c_dc_scale_table[32]; +extern const uint8_t old_ff_y_dc_scale_table[32]; +extern const uint8_t old_ff_c_dc_scale_table[32]; -static const uint32_t table_mb_non_intra2[128][2] = { -{0x0000A7, 14}, {0x01B2B8, 18}, {0x01B28E, 18}, {0x036575, 19}, -{0x006CAC, 16}, {0x000A69, 18}, {0x002934, 20}, {0x00526B, 21}, -{0x006CA1, 16}, {0x01B2B9, 18}, {0x0029AD, 20}, {0x029353, 24}, -{0x006CA7, 16}, {0x006CAB, 16}, {0x01B2BB, 18}, {0x00029B, 16}, -{0x00D944, 17}, {0x000A6A, 18}, {0x0149A8, 23}, {0x03651F, 19}, -{0x006CAF, 16}, {0x000A4C, 18}, {0x03651E, 19}, {0x000A48, 18}, -{0x00299C, 20}, {0x00299F, 20}, {0x029352, 24}, {0x0029AC, 20}, -{0x000296, 16}, {0x00D946, 17}, {0x000A68, 18}, {0x000298, 16}, -{0x000527, 17}, {0x00D94D, 17}, {0x0014D7, 19}, {0x036574, 19}, -{0x000A5C, 18}, {0x01B299, 18}, {0x00299D, 20}, {0x00299E, 20}, -{0x000525, 17}, {0x000A66, 18}, {0x00A4D5, 22}, {0x00149B, 19}, -{0x000295, 16}, {0x006CAD, 16}, {0x000A49, 18}, {0x000521, 17}, -{0x006CAA, 16}, {0x00D945, 17}, {0x01B298, 18}, {0x00052F, 17}, -{0x003654, 15}, {0x006CA0, 16}, {0x000532, 17}, {0x000291, 16}, -{0x003652, 15}, {0x000520, 17}, {0x000A5D, 18}, {0x000294, 16}, -{0x00009B, 11}, {0x0006E2, 12}, {0x000028, 12}, {0x0001B0, 10}, -{0x000001, 3}, {0x000010, 8}, {0x00002F, 6}, {0x00004C, 10}, -{0x00000D, 4}, {0x000000, 10}, {0x000006, 9}, {0x000134, 12}, -{0x00000C, 4}, {0x000007, 10}, {0x000007, 9}, {0x0006E1, 12}, -{0x00000E, 5}, {0x0000DA, 9}, {0x000022, 9}, {0x000364, 11}, -{0x00000F, 4}, {0x000006, 10}, {0x00000F, 9}, {0x000135, 12}, -{0x000014, 5}, {0x0000DD, 9}, {0x000004, 9}, {0x000015, 11}, -{0x00001A, 6}, {0x0001B3, 10}, {0x000005, 10}, {0x0006E3, 12}, -{0x00000C, 5}, {0x0000B9, 8}, {0x000004, 8}, {0x0000DB, 9}, -{0x00000E, 4}, {0x00000B, 10}, {0x000023, 9}, {0x0006CB, 12}, -{0x000005, 6}, {0x0001B1, 10}, {0x000001, 10}, {0x0006E0, 12}, -{0x000011, 5}, {0x0000DF, 9}, {0x00000E, 9}, {0x000373, 11}, -{0x000003, 5}, {0x0000B8, 8}, {0x000006, 8}, {0x000175, 9}, -{0x000015, 5}, {0x000174, 9}, {0x000027, 9}, {0x000372, 11}, -{0x000010, 5}, {0x0000BB, 8}, {0x000005, 8}, {0x0000DE, 9}, -{0x00000F, 5}, {0x000001, 9}, {0x000012, 8}, {0x000004, 10}, -{0x000002, 3}, {0x000016, 5}, {0x000009, 4}, {0x000001, 5}, -}; +extern MVTable mv_tables[2]; -static const uint32_t table_mb_non_intra3[128][2] = { -{0x0002A1, 10}, {0x005740, 15}, {0x01A0BF, 18}, {0x015D19, 17}, -{0x001514, 13}, {0x00461E, 15}, {0x015176, 17}, {0x015177, 17}, -{0x0011AD, 13}, {0x00682E, 16}, {0x0682F9, 20}, {0x03417D, 19}, -{0x001A36, 14}, {0x002A2D, 14}, {0x00D05E, 17}, {0x006824, 16}, -{0x001515, 13}, {0x00545C, 15}, {0x0230E9, 18}, {0x011AFA, 17}, -{0x0015D7, 13}, {0x005747, 15}, {0x008D79, 16}, {0x006825, 16}, -{0x002BA2, 14}, {0x00A8BA, 16}, {0x0235F6, 18}, {0x015D18, 17}, -{0x0011AE, 13}, {0x00346F, 15}, {0x008C3B, 16}, {0x00346E, 15}, -{0x000D1A, 13}, {0x00461F, 15}, {0x0682F8, 20}, {0x011875, 17}, -{0x002BA1, 14}, {0x008D61, 16}, {0x0235F7, 18}, {0x0230E8, 18}, -{0x001513, 13}, {0x008D7B, 16}, {0x011AF4, 17}, {0x011AF5, 17}, -{0x001185, 13}, {0x0046BF, 15}, {0x008D60, 16}, {0x008D7C, 16}, -{0x001512, 13}, {0x00461C, 15}, {0x00AE8D, 16}, {0x008D78, 16}, -{0x000D0E, 13}, {0x003413, 15}, {0x0046B1, 15}, {0x003416, 15}, -{0x000AEA, 12}, {0x002A2C, 14}, {0x005741, 15}, {0x002A2F, 14}, -{0x000158, 9}, {0x0008D2, 12}, {0x00054C, 11}, {0x000686, 12}, -{0x000000, 2}, {0x000069, 8}, {0x00006B, 8}, {0x00068C, 12}, -{0x000007, 3}, {0x00015E, 9}, {0x0002A3, 10}, {0x000AE9, 12}, -{0x000006, 3}, {0x000231, 10}, {0x0002B8, 10}, {0x001A08, 14}, -{0x000010, 5}, {0x0001A9, 10}, {0x000342, 11}, {0x000A88, 12}, -{0x000004, 4}, {0x0001A2, 10}, {0x0002A4, 10}, {0x001184, 13}, -{0x000012, 5}, {0x000232, 10}, {0x0002B2, 10}, {0x000680, 12}, -{0x00001B, 6}, {0x00046A, 11}, {0x00068E, 12}, {0x002359, 14}, -{0x000016, 5}, {0x00015F, 9}, {0x0002A0, 10}, {0x00054D, 11}, -{0x000005, 4}, {0x000233, 10}, {0x0002B9, 10}, {0x0015D6, 13}, -{0x000022, 6}, {0x000468, 11}, {0x000683, 12}, {0x001A0A, 14}, -{0x000013, 5}, {0x000236, 10}, {0x0002BB, 10}, {0x001186, 13}, -{0x000017, 5}, {0x0001AB, 10}, {0x0002A7, 10}, {0x0008D3, 12}, -{0x000014, 5}, {0x000237, 10}, {0x000460, 11}, {0x000D0F, 13}, -{0x000019, 6}, {0x0001AA, 10}, {0x0002B3, 10}, {0x000681, 12}, -{0x000018, 6}, {0x0001A8, 10}, {0x0002A5, 10}, {0x00068F, 12}, -{0x000007, 4}, {0x000055, 7}, {0x000047, 7}, {0x0000AD, 8}, -}; +extern const uint8_t v2_mb_type[8][2]; +extern const uint8_t v2_intra_cbpc[4][2]; -static const uint32_t table_mb_non_intra4[128][2] = { -{0x0000D4, 8}, {0x0021C5, 14}, {0x00F18A, 16}, {0x00D5BC, 16}, -{0x000879, 12}, {0x00354D, 14}, {0x010E3F, 17}, {0x010F54, 17}, -{0x000866, 12}, {0x00356E, 14}, {0x010F55, 17}, {0x010E3E, 17}, -{0x0010CE, 13}, {0x003C84, 14}, {0x00D5BD, 16}, {0x00F18B, 16}, -{0x000868, 12}, {0x00438C, 15}, {0x0087AB, 16}, {0x00790B, 15}, -{0x000F10, 12}, {0x00433D, 15}, {0x006AD3, 15}, {0x00790A, 15}, -{0x001AA7, 13}, {0x0043D4, 15}, {0x00871E, 16}, {0x006ADF, 15}, -{0x000D7C, 12}, {0x003C94, 14}, {0x00438D, 15}, {0x006AD2, 15}, -{0x0006BC, 11}, {0x0021E9, 14}, {0x006ADA, 15}, {0x006A99, 15}, -{0x0010F7, 13}, {0x004389, 15}, {0x006ADB, 15}, {0x0078C4, 15}, -{0x000D56, 12}, {0x0035F7, 14}, {0x00438E, 15}, {0x006A98, 15}, -{0x000D52, 12}, {0x003C95, 14}, {0x004388, 15}, {0x00433C, 15}, -{0x000D54, 12}, {0x001E4B, 13}, {0x003C63, 14}, {0x003C83, 14}, -{0x000861, 12}, {0x0021EB, 14}, {0x00356C, 14}, {0x0035F6, 14}, -{0x000863, 12}, {0x00219F, 14}, {0x003568, 14}, {0x003C82, 14}, -{0x0001AE, 9}, {0x0010C0, 13}, {0x000F11, 12}, {0x001AFA, 13}, -{0x000000, 1}, {0x0000F0, 8}, {0x0001AD, 9}, {0x0010C1, 13}, -{0x00000A, 4}, {0x0003C5, 10}, {0x000789, 11}, {0x001AB5, 13}, -{0x000009, 4}, {0x000435, 11}, {0x000793, 11}, {0x001E40, 13}, -{0x00001D, 5}, {0x0003CB, 10}, {0x000878, 12}, {0x001AAF, 13}, -{0x00000B, 4}, {0x0003C7, 10}, {0x000791, 11}, {0x001AAB, 13}, -{0x00001F, 5}, {0x000436, 11}, {0x0006BF, 11}, {0x000F19, 12}, -{0x00003D, 6}, {0x000D51, 12}, {0x0010C4, 13}, {0x0021E8, 14}, -{0x000036, 6}, {0x000437, 11}, {0x0006AF, 11}, {0x0010C5, 13}, -{0x00000C, 4}, {0x000432, 11}, {0x000794, 11}, {0x001E30, 13}, -{0x000042, 7}, {0x000870, 12}, {0x000F24, 12}, {0x001E43, 13}, -{0x000020, 6}, {0x00043E, 11}, {0x000795, 11}, {0x001AAA, 13}, -{0x000037, 6}, {0x0006AC, 11}, {0x0006AE, 11}, {0x0010F6, 13}, -{0x000034, 6}, {0x00043A, 11}, {0x000D50, 12}, {0x001AAE, 13}, -{0x000039, 6}, {0x00043F, 11}, {0x00078D, 11}, {0x0010D2, 13}, -{0x000038, 6}, {0x00043B, 11}, {0x0006BD, 11}, {0x0010D3, 13}, -{0x000011, 5}, {0x0001AC, 9}, {0x0000F3, 8}, {0x000439, 11}, -}; +extern const uint32_t table_mb_non_intra[128][2]; +extern const uint8_t table_inter_intra[4][2]; -static const uint32_t (*wmv2_inter_table[WMV2_INTER_CBP_TABLE_COUNT])[2]={ - table_mb_non_intra2, - table_mb_non_intra3, - table_mb_non_intra4, - table_mb_non_intra, -}; +extern const uint32_t ff_table0_dc_lum[120][2]; +extern const uint32_t ff_table1_dc_lum[120][2]; +extern const uint32_t ff_table0_dc_chroma[120][2]; +extern const uint32_t ff_table1_dc_chroma[120][2]; + +#define WMV2_INTER_CBP_TABLE_COUNT 4 +extern const uint32_t (*wmv2_inter_table[WMV2_INTER_CBP_TABLE_COUNT])[2]; -static const uint8_t wmv2_scantableA[64]={ -0x00, 0x01, 0x02, 0x08, 0x03, 0x09, 0x0A, 0x10, -0x04, 0x0B, 0x11, 0x18, 0x12, 0x0C, 0x05, 0x13, -0x19, 0x0D, 0x14, 0x1A, 0x1B, 0x06, 0x15, 0x1C, -0x0E, 0x16, 0x1D, 0x07, 0x1E, 0x0F, 0x17, 0x1F, -}; +extern const uint8_t wmv2_scantableA[64]; +extern const uint8_t wmv2_scantableB[64]; -static const uint8_t wmv2_scantableB[64]={ -0x00, 0x08, 0x01, 0x10, 0x09, 0x18, 0x11, 0x02, -0x20, 0x0A, 0x19, 0x28, 0x12, 0x30, 0x21, 0x1A, -0x38, 0x29, 0x22, 0x03, 0x31, 0x39, 0x0B, 0x2A, -0x13, 0x32, 0x1B, 0x3A, 0x23, 0x2B, 0x33, 0x3B, -}; +#endif /* FFMPEG_MSMPEG4DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/msrle.c b/contrib/ffmpeg/libavcodec/msrle.c index fae5616e5..51893cbb7 100644 --- a/contrib/ffmpeg/libavcodec/msrle.c +++ b/contrib/ffmpeg/libavcodec/msrle.c @@ -36,7 +36,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -44,7 +43,7 @@ typedef struct MsrleContext { AVCodecContext *avctx; AVFrame frame; - unsigned char *buf; + const unsigned char *buf; int size; } MsrleContext; @@ -239,12 +238,11 @@ static void msrle_decode_pal8(MsrleContext *s) static int msrle_decode_init(AVCodecContext *avctx) { - MsrleContext *s = (MsrleContext *)avctx->priv_data; + MsrleContext *s = avctx->priv_data; s->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; s->frame.data[0] = NULL; return 0; @@ -252,9 +250,9 @@ static int msrle_decode_init(AVCodecContext *avctx) static int msrle_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - MsrleContext *s = (MsrleContext *)avctx->priv_data; + MsrleContext *s = avctx->priv_data; s->buf = buf; s->size = buf_size; @@ -287,7 +285,7 @@ static int msrle_decode_frame(AVCodecContext *avctx, static int msrle_decode_end(AVCodecContext *avctx) { - MsrleContext *s = (MsrleContext *)avctx->priv_data; + MsrleContext *s = avctx->priv_data; /* release the last frame */ if (s->frame.data[0]) diff --git a/contrib/ffmpeg/libavcodec/msvideo1.c b/contrib/ffmpeg/libavcodec/msvideo1.c index 1e3f6cce2..baac48a85 100644 --- a/contrib/ffmpeg/libavcodec/msvideo1.c +++ b/contrib/ffmpeg/libavcodec/msvideo1.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -36,7 +35,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -54,7 +52,7 @@ typedef struct Msvideo1Context { DSPContext dsp; AVFrame frame; - unsigned char *buf; + const unsigned char *buf; int size; int mode_8bit; /* if it's not 8-bit, it's 16-bit */ @@ -63,7 +61,7 @@ typedef struct Msvideo1Context { static int msvideo1_decode_init(AVCodecContext *avctx) { - Msvideo1Context *s = (Msvideo1Context *)avctx->priv_data; + Msvideo1Context *s = avctx->priv_data; s->avctx = avctx; @@ -76,7 +74,6 @@ static int msvideo1_decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_RGB555; } - avctx->has_b_frames = 0; dsputil_init(&s->dsp, avctx); s->frame.data[0] = NULL; @@ -300,9 +297,9 @@ static void msvideo1_decode_16bit(Msvideo1Context *s) static int msvideo1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - Msvideo1Context *s = (Msvideo1Context *)avctx->priv_data; + Msvideo1Context *s = avctx->priv_data; s->buf = buf; s->size = buf_size; @@ -328,7 +325,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, static int msvideo1_decode_end(AVCodecContext *avctx) { - Msvideo1Context *s = (Msvideo1Context *)avctx->priv_data; + Msvideo1Context *s = avctx->priv_data; if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); diff --git a/contrib/ffmpeg/libavcodec/nellymoserdec.c b/contrib/ffmpeg/libavcodec/nellymoserdec.c new file mode 100644 index 000000000..7c83bd562 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/nellymoserdec.c @@ -0,0 +1,411 @@ +/* + * NellyMoser audio decoder + * Copyright (c) 2007 a840bda5870ba11f19698ff6eb9581dfb0f95fa5, + * 539459aeb7d425140b62a3ec7dbf6dc8e408a306, and + * 520e17cd55896441042b14df2566a6eb610ed444 + * Copyright (c) 2007 Loic Minier <lool at dooz.org> + * Benjamin Larsson + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * @file nellymoserdec.c + * The 3 alphanumeric copyright notices are md5summed they are from the original + * implementors. The original code is available from http://code.google.com/p/nelly2pcm/ + */ +#include "avcodec.h" +#include "random.h" +#include "dsputil.h" + +#define ALT_BITSTREAM_READER_LE +#include "bitstream.h" + +#define NELLY_BANDS 23 +#define NELLY_BLOCK_LEN 64 +#define NELLY_HEADER_BITS 116 +#define NELLY_DETAIL_BITS 198 +#define NELLY_BUF_LEN 128 +#define NELLY_FILL_LEN 124 +#define NELLY_BIT_CAP 6 +#define NELLY_BASE_OFF 4228 +#define NELLY_BASE_SHIFT 19 +#define NELLY_SAMPLES (2 * NELLY_BUF_LEN) + +static const float dequantization_table[127] = { +0.0000000000,-0.8472560048, 0.7224709988, -1.5247479677, -0.4531480074, 0.3753609955, 1.4717899561, +-1.9822579622, -1.1929379702, -0.5829370022, -0.0693780035, 0.3909569979,0.9069200158, 1.4862740040, + 2.2215409279, -2.3887870312, -1.8067539930, -1.4105420113, -1.0773609877, -0.7995010018,-0.5558109879, +-0.3334020078, -0.1324490011, 0.0568020009, 0.2548770010, 0.4773550034, 0.7386850119, 1.0443060398, +1.3954459429, 1.8098750114, 2.3918759823,-2.3893830776, -1.9884680510, -1.7514040470, -1.5643119812, +-1.3922129869,-1.2164649963, -1.0469499826, -0.8905100226, -0.7645580173, -0.6454579830, -0.5259280205, +-0.4059549868, -0.3029719889, -0.2096900046, -0.1239869967, -0.0479229987, 0.0257730000, 0.1001340002, +0.1737180054, 0.2585540116, 0.3522900045, 0.4569880068, 0.5767750144, 0.7003160119, 0.8425520062, +1.0093879700, 1.1821349859, 1.3534560204, 1.5320819616, 1.7332619429, 1.9722349644, 2.3978140354, +-2.5756309032, -2.0573320389, -1.8984919786, -1.7727810144, -1.6662600040, -1.5742180347, -1.4993319511, +-1.4316639900, -1.3652280569, -1.3000990152, -1.2280930281, -1.1588579416, -1.0921250582, -1.0135740042, +-0.9202849865, -0.8287050128, -0.7374889851, -0.6447759867, -0.5590940118, -0.4857139885, -0.4110319912, +-0.3459700048, -0.2851159871, -0.2341620028, -0.1870580018, -0.1442500055, -0.1107169986, -0.0739680007, +-0.0365610011, -0.0073290002, 0.0203610007, 0.0479039997, 0.0751969963, 0.0980999991, 0.1220389977, +0.1458999962, 0.1694349945, 0.1970459968, 0.2252430022, 0.2556869984, 0.2870100141, 0.3197099864, +0.3525829911, 0.3889069855, 0.4334920049, 0.4769459963, 0.5204820037, 0.5644530058, 0.6122040153, +0.6685929894, 0.7341650128, 0.8032159805, 0.8784040213, 0.9566209912, 1.0397069454, 1.1293770075, +1.2211159468, 1.3080279827, 1.4024800062, 1.5056819916, 1.6227730513, 1.7724959850, 1.9430880547, + 2.2903931141 +}; + +static const uint8_t nelly_band_sizes_table[NELLY_BANDS] = { +2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 12, 14, 15 +}; + +static const uint16_t nelly_init_table[64] = { +3134, 5342, 6870, 7792, 8569, 9185, 9744, 10191, 10631, 11061, 11434, 11770, +12116, 12513, 12925, 13300, 13674, 14027, 14352, 14716, 15117, 15477, 15824, +16157, 16513, 16804, 17090, 17401, 17679, 17948, 18238, 18520, 18764, 19078, +19381, 19640, 19921, 20205, 20500, 20813, 21162, 21465, 21794, 22137, 22453, +22756, 23067, 23350, 23636, 23926, 24227, 24521, 24819, 25107, 25414, 25730, +26120, 26497, 26895, 27344, 27877, 28463, 29426, 31355 +}; + +static const int16_t nelly_delta_table[32] = { +-11725, -9420, -7910, -6801, -5948, -5233, -4599, -4039, -3507, -3030, -2596, +-2170, -1774, -1383, -1016, -660, -329, -1, 337, 696, 1085, 1512, 1962, 2433, +2968, 3569, 4314, 5279, 6622, 8154, 10076, 12975 +}; + +typedef struct NellyMoserDecodeContext { + AVCodecContext* avctx; + DECLARE_ALIGNED_16(float,float_buf[NELLY_SAMPLES]); + float state[64]; + AVRandomState random_state; + GetBitContext gb; + int add_bias; + int scale_bias; + DSPContext dsp; + MDCTContext imdct_ctx; + DECLARE_ALIGNED_16(float,imdct_tmp[NELLY_BUF_LEN]); + DECLARE_ALIGNED_16(float,imdct_out[NELLY_BUF_LEN * 2]); +} NellyMoserDecodeContext; + +static DECLARE_ALIGNED_16(float,sine_window[128]); + +static inline int signed_shift(int i, int shift) { + if (shift > 0) + return i << shift; + return i >> -shift; +} + +static void overlap_and_window(NellyMoserDecodeContext *s, float *state, float *audio) +{ + int bot, mid_up, mid_down, top; + float s_bot, s_top; + + bot = 0; + top = NELLY_BUF_LEN-1; + mid_up = NELLY_BUF_LEN/2; + mid_down = (NELLY_BUF_LEN/2)-1; + + while (bot < NELLY_BUF_LEN/4) { + s_bot = audio[bot]; + s_top = -audio[top]; + audio[bot] = (-audio[mid_up]*sine_window[bot]-state[bot ]*sine_window[top])/s->scale_bias + s->add_bias; + audio[top] = (-state[bot ]*sine_window[bot]+audio[mid_up]*sine_window[top])/s->scale_bias + s->add_bias; + state[bot] = audio[mid_down]; + + audio[mid_down] = (s_top *sine_window[mid_down]-state[mid_down]*sine_window[mid_up])/s->scale_bias + s->add_bias; + audio[mid_up ] = (-state[mid_down]*sine_window[mid_down]-s_top *sine_window[mid_up])/s->scale_bias + s->add_bias; + state[mid_down] = s_bot; + + bot++; + mid_up++; + mid_down--; + top--; + } +} + +static int sum_bits(short *buf, short shift, short off) +{ + int b, i = 0, ret = 0; + + for (i = 0; i < NELLY_FILL_LEN; i++) { + b = buf[i]-off; + b = ((b>>(shift-1))+1)>>1; + ret += av_clip(b, 0, NELLY_BIT_CAP); + } + + return ret; +} + +static int headroom(int *la) +{ + int l; + if (*la == 0) { + return 31; + } + l = 30 - av_log2(FFABS(*la)); + *la <<= l; + return l; +} + + +static void get_sample_bits(const float *buf, int *bits) +{ + int i, j; + short sbuf[128]; + int bitsum = 0, last_bitsum, small_bitsum, big_bitsum; + short shift, shift_saved; + int max, sum, last_off, tmp; + int big_off, small_off; + int off; + + max = 0; + for (i = 0; i < NELLY_FILL_LEN; i++) { + max = FFMAX(max, buf[i]); + } + shift = -16; + shift += headroom(&max); + + sum = 0; + for (i = 0; i < NELLY_FILL_LEN; i++) { + sbuf[i] = signed_shift(buf[i], shift); + sbuf[i] = (3*sbuf[i])>>2; + sum += sbuf[i]; + } + + shift += 11; + shift_saved = shift; + sum -= NELLY_DETAIL_BITS << shift; + shift += headroom(&sum); + small_off = (NELLY_BASE_OFF * (sum>>16)) >> 15; + shift = shift_saved - (NELLY_BASE_SHIFT+shift-31); + + small_off = signed_shift(small_off, shift); + + bitsum = sum_bits(sbuf, shift_saved, small_off); + + if (bitsum != NELLY_DETAIL_BITS) { + shift = 0; + off = bitsum - NELLY_DETAIL_BITS; + + for(shift=0; FFABS(off) <= 16383; shift++) + off *= 2; + + off = (off * NELLY_BASE_OFF) >> 15; + shift = shift_saved-(NELLY_BASE_SHIFT+shift-15); + + off = signed_shift(off, shift); + + for (j = 1; j < 20; j++) { + last_off = small_off; + small_off += off; + last_bitsum = bitsum; + + bitsum = sum_bits(sbuf, shift_saved, small_off); + + if ((bitsum-NELLY_DETAIL_BITS) * (last_bitsum-NELLY_DETAIL_BITS) <= 0) + break; + } + + if (bitsum > NELLY_DETAIL_BITS) { + big_off = small_off; + small_off = last_off; + big_bitsum=bitsum; + small_bitsum=last_bitsum; + } else { + big_off = last_off; + big_bitsum=last_bitsum; + small_bitsum=bitsum; + } + + while (bitsum != NELLY_DETAIL_BITS && j <= 19) { + off = (big_off+small_off)>>1; + bitsum = sum_bits(sbuf, shift_saved, off); + if (bitsum > NELLY_DETAIL_BITS) { + big_off=off; + big_bitsum=bitsum; + } else { + small_off = off; + small_bitsum=bitsum; + } + j++; + } + + if (abs(big_bitsum-NELLY_DETAIL_BITS) >= + abs(small_bitsum-NELLY_DETAIL_BITS)) { + bitsum = small_bitsum; + } else { + small_off = big_off; + bitsum = big_bitsum; + } + } + + for (i = 0; i < NELLY_FILL_LEN; i++) { + tmp = sbuf[i]-small_off; + tmp = ((tmp>>(shift_saved-1))+1)>>1; + bits[i] = av_clip(tmp, 0, NELLY_BIT_CAP); + } + + if (bitsum > NELLY_DETAIL_BITS) { + tmp = i = 0; + while (tmp < NELLY_DETAIL_BITS) { + tmp += bits[i]; + i++; + } + + bits[i-1] -= tmp - NELLY_DETAIL_BITS; + for(; i < NELLY_FILL_LEN; i++) + bits[i] = 0; + } +} + +void nelly_decode_block(NellyMoserDecodeContext *s, const unsigned char block[NELLY_BLOCK_LEN], float audio[NELLY_SAMPLES]) +{ + int i,j; + float buf[NELLY_FILL_LEN], pows[NELLY_FILL_LEN]; + float *aptr, *bptr, *pptr, val, pval; + int bits[NELLY_BUF_LEN]; + unsigned char v; + + init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); + + bptr = buf; + pptr = pows; + val = nelly_init_table[get_bits(&s->gb, 6)]; + for (i=0 ; i<NELLY_BANDS ; i++) { + if (i > 0) + val += nelly_delta_table[get_bits(&s->gb, 5)]; + pval = pow(2, val/2048); + for (j = 0; j < nelly_band_sizes_table[i]; j++) { + *bptr++ = val; + *pptr++ = pval; + } + + } + + get_sample_bits(buf, bits); + + for (i = 0; i < 2; i++) { + aptr = audio + i * NELLY_BUF_LEN; + + init_get_bits(&s->gb, block, NELLY_BLOCK_LEN * 8); + skip_bits(&s->gb, NELLY_HEADER_BITS + i*NELLY_DETAIL_BITS); + + for (j = 0; j < NELLY_FILL_LEN; j++) { + if (bits[j] <= 0) { + aptr[j] = M_SQRT1_2*pows[j]; + if (av_random(&s->random_state) & 1) + aptr[j] *= -1.0; + } else { + v = get_bits(&s->gb, bits[j]); + aptr[j] = dequantization_table[(1<<bits[j])-1+v]*pows[j]; + } + } + memset(&aptr[NELLY_FILL_LEN], 0, + (NELLY_BUF_LEN - NELLY_FILL_LEN) * sizeof(float)); + + s->imdct_ctx.fft.imdct_calc(&s->imdct_ctx, s->imdct_out, + aptr, s->imdct_tmp); + /* XXX: overlapping and windowing should be part of a more + generic imdct function */ + memcpy(&aptr[0],&s->imdct_out[NELLY_BUF_LEN+NELLY_BUF_LEN/2], (NELLY_BUF_LEN/2)*sizeof(float)); + memcpy(&aptr[NELLY_BUF_LEN / 2],&s->imdct_out[0],(NELLY_BUF_LEN/2)*sizeof(float)); + overlap_and_window(s, s->state, aptr); + } +} + +static int decode_init(AVCodecContext * avctx) { + NellyMoserDecodeContext *s = avctx->priv_data; + int i; + + s->avctx = avctx; + av_init_random(0, &s->random_state); + ff_mdct_init(&s->imdct_ctx, 8, 1); + + dsputil_init(&s->dsp, avctx); + + if(s->dsp.float_to_int16 == ff_float_to_int16_c) { + s->add_bias = 385; + s->scale_bias = 8*32768; + } else { + s->add_bias = 0; + s->scale_bias = 1*8; + } + + /* Generate overlap window */ + if (!sine_window[0]) + for (i=0 ; i<128; i++) { + sine_window[i] = sin((i + 0.5) / 256.0 * M_PI); + } + + return 0; +} + +static int decode_tag(AVCodecContext * avctx, + void *data, int *data_size, + const uint8_t * buf, int buf_size) { + NellyMoserDecodeContext *s = avctx->priv_data; + int blocks, i; + int16_t* samples; + *data_size = 0; + samples = (int16_t*)data; + + if (buf_size < avctx->block_align) + return buf_size; + + switch (buf_size) { + case 64: // 8000Hz + blocks = 1; break; + case 128: // 11025Hz + blocks = 2; break; + case 256: // 22050Hz + blocks = 4; break; + case 512: // 44100Hz + blocks = 8; break; + default: + av_log(avctx, AV_LOG_ERROR, "Tag size %d unknown, report sample!\n", buf_size); + return buf_size; + } + + for (i=0 ; i<blocks ; i++) { + nelly_decode_block(s, &buf[i*NELLY_BLOCK_LEN], s->float_buf); + s->dsp.float_to_int16(&samples[i*NELLY_SAMPLES], s->float_buf, NELLY_SAMPLES); + *data_size += NELLY_SAMPLES*sizeof(int16_t); + } + + return buf_size; +} + +static int decode_end(AVCodecContext * avctx) { + NellyMoserDecodeContext *s = avctx->priv_data; + + ff_mdct_end(&s->imdct_ctx); + return 0; +} + +AVCodec nellymoser_decoder = { + "nellymoser", + CODEC_TYPE_AUDIO, + CODEC_ID_NELLYMOSER, + sizeof(NellyMoserDecodeContext), + decode_init, + NULL, + decode_end, + decode_tag, +}; + diff --git a/contrib/ffmpeg/libavcodec/noise_bsf.c b/contrib/ffmpeg/libavcodec/noise_bsf.c new file mode 100644 index 000000000..c49dd1f9d --- /dev/null +++ b/contrib/ffmpeg/libavcodec/noise_bsf.c @@ -0,0 +1,46 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * 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" + + +static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe){ + unsigned int *state= bsfc->priv_data; + int amount= args ? atoi(args) : (*state % 10001+1); + int i; + + *poutbuf= av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + + memcpy(*poutbuf, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + for(i=0; i<buf_size; i++){ + (*state) += (*poutbuf)[i] + 1; + if(*state % amount == 0) + (*poutbuf)[i] = *state; + } + return 1; +} + +AVBitStreamFilter noise_bsf={ + "noise", + sizeof(int), + noise, +}; diff --git a/contrib/ffmpeg/libavcodec/nuv.c b/contrib/ffmpeg/libavcodec/nuv.c index 5989c6cc2..6193806fa 100644 --- a/contrib/ffmpeg/libavcodec/nuv.c +++ b/contrib/ffmpeg/libavcodec/nuv.c @@ -21,7 +21,6 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" #include "bswap.h" @@ -31,6 +30,8 @@ typedef struct { AVFrame pic; + int codec_frameheader; + int quality; int width, height; unsigned int decomp_size; unsigned char* decomp_buf; @@ -39,6 +40,28 @@ typedef struct { DSPContext dsp; } NuvContext; +static const uint8_t fallback_lquant[] = { + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68, 109, 103, 77, + 24, 35, 55, 64, 81, 104, 113, 92, + 49, 64, 78, 87, 103, 121, 120, 101, + 72, 92, 95, 98, 112, 100, 103, 99 +}; + +static const uint8_t fallback_cquant[] = { + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 +}; + /** * \brief copy frame data from buffer to AVFrame, handling stride. * \param f destination AVFrame @@ -46,7 +69,7 @@ typedef struct { * \param width width of the video frame * \param height height of the video frame */ -static void copy_frame(AVFrame *f, uint8_t *src, +static void copy_frame(AVFrame *f, const uint8_t *src, int width, int height) { AVPicture pic; avpicture_fill(&pic, src, PIX_FMT_YUV420P, width, height); @@ -57,7 +80,7 @@ static void copy_frame(AVFrame *f, uint8_t *src, * \brief extract quantization tables from codec data into our context */ static int get_quant(AVCodecContext *avctx, NuvContext *c, - uint8_t *buf, int size) { + const uint8_t *buf, int size) { int i; if (size < 2 * 64 * 4) { av_log(avctx, AV_LOG_ERROR, "insufficient rtjpeg quant data\n"); @@ -70,9 +93,44 @@ static int get_quant(AVCodecContext *avctx, NuvContext *c, return 0; } +/** + * \brief set quantization tables from a quality value + */ +static void get_quant_quality(NuvContext *c, int quality) { + int i; + quality = FFMAX(quality, 1); + for (i = 0; i < 64; i++) { + c->lq[i] = (fallback_lquant[i] << 7) / quality; + c->cq[i] = (fallback_cquant[i] << 7) / quality; + } +} + +static int codec_reinit(AVCodecContext *avctx, int width, int height, int quality) { + NuvContext *c = avctx->priv_data; + width = (width + 1) & ~1; + height = (height + 1) & ~1; + if (quality >= 0) + get_quant_quality(c, quality); + if (width != c->width || height != c->height) { + if (avcodec_check_dimensions(avctx, height, width) < 0) + return 0; + avctx->width = c->width = width; + avctx->height = c->height = height; + c->decomp_size = c->height * c->width * 3 / 2; + c->decomp_buf = av_realloc(c->decomp_buf, c->decomp_size + LZO_OUTPUT_PADDING); + if (!c->decomp_buf) { + av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); + return 0; + } + rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); + } else if (quality != c->quality) + rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); + return 1; +} + static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) { - NuvContext *c = (NuvContext *)avctx->priv_data; + const uint8_t *buf, int buf_size) { + NuvContext *c = avctx->priv_data; AVFrame *picture = data; int orig_size = buf_size; enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1', @@ -84,16 +142,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, return -1; } - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - c->pic.reference = 1; - c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | - FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->get_buffer(avctx, &c->pic) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - // codec data (rtjpeg quant tables) if (buf[0] == 'D' && buf[1] == 'R') { int ret; @@ -115,11 +163,43 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, // skip rest of the frameheader. buf = &buf[12]; buf_size -= 12; + if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) { + int outlen = c->decomp_size, inlen = buf_size; + if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) + av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); + buf = c->decomp_buf; + buf_size = c->decomp_size; + } + if (c->codec_frameheader) { + int w, h, q; + if (buf_size < 12) { + av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n"); + return -1; + } + w = AV_RL16(&buf[6]); + h = AV_RL16(&buf[8]); + q = buf[10]; + if (!codec_reinit(avctx, w, h, q)) + return -1; + buf = &buf[12]; + buf_size -= 12; + } + + if (c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + c->pic.reference = 1; + c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | + FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->get_buffer(avctx, &c->pic) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } c->pic.pict_type = FF_I_TYPE; c->pic.key_frame = 1; // decompress/copy/whatever data switch (comptype) { + case NUV_LZO: case NUV_UNCOMPRESSED: { int height = c->height; if (buf_size < c->width * height * 3 / 2) { @@ -129,24 +209,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, copy_frame(&c->pic, buf, c->width, height); break; } + case NUV_RTJPEG_IN_LZO: case NUV_RTJPEG: { rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size); break; } - case NUV_RTJPEG_IN_LZO: { - int outlen = c->decomp_size, inlen = buf_size; - if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) - av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); - rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, c->decomp_buf, c->decomp_size); - break; - } - case NUV_LZO: { - int outlen = c->decomp_size, inlen = buf_size; - if (lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) - av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); - copy_frame(&c->pic, c->decomp_buf, c->width, c->height); - break; - } case NUV_BLACK: { memset(c->pic.data[0], 0, c->width * c->height); memset(c->pic.data[1], 128, c->width * c->height / 4); @@ -170,32 +237,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, } static int decode_init(AVCodecContext *avctx) { - NuvContext *c = (NuvContext *)avctx->priv_data; - avctx->width = (avctx->width + 1) & ~1; - avctx->height = (avctx->height + 1) & ~1; - if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) { - return 1; - } - avctx->has_b_frames = 0; + NuvContext *c = avctx->priv_data; avctx->pix_fmt = PIX_FMT_YUV420P; c->pic.data[0] = NULL; - c->width = avctx->width; - c->height = avctx->height; - c->decomp_size = c->height * c->width * 3 / 2; - c->decomp_buf = av_malloc(c->decomp_size + LZO_OUTPUT_PADDING); - if (!c->decomp_buf) { - av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; - } - dsputil_init(&c->dsp, avctx); + c->decomp_buf = NULL; + c->quality = -1; + c->width = 0; + c->height = 0; + c->codec_frameheader = avctx->codec_tag == MKTAG('R', 'J', 'P', 'G'); if (avctx->extradata_size) get_quant(avctx, c, avctx->extradata, avctx->extradata_size); - rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); + dsputil_init(&c->dsp, avctx); + if (!codec_reinit(avctx, avctx->width, avctx->height, -1)) + return 1; return 0; } static int decode_end(AVCodecContext *avctx) { - NuvContext *c = (NuvContext *)avctx->priv_data; + NuvContext *c = avctx->priv_data; av_freep(&c->decomp_buf); if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); diff --git a/contrib/ffmpeg/libavcodec/opt.c b/contrib/ffmpeg/libavcodec/opt.c index 97b593cb2..42e8eff9f 100644 --- a/contrib/ffmpeg/libavcodec/opt.c +++ b/contrib/ffmpeg/libavcodec/opt.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -70,6 +69,7 @@ static const AVOption *av_set_number(void *obj, const char *name, double num, in case FF_OPT_TYPE_RATIONAL: if((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den}; else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); + break; default: return NULL; } @@ -108,6 +108,13 @@ static const char *const_names[]={ 0 }; +static int hexchar2int(char c) { + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return -1; +} + const AVOption *av_set_string(void *obj, const char *name, const char *val){ const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ @@ -115,13 +122,36 @@ const AVOption *av_set_string(void *obj, const char *name, const char *val){ } if(!o || !val || o->offset<=0) return NULL; + if(o->type == FF_OPT_TYPE_BINARY){ + uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset); + int *lendst = (int *)(dst + 1); + uint8_t *bin, *ptr; + int len = strlen(val); + av_freep(dst); + *lendst = 0; + if (len & 1) return NULL; + len /= 2; + ptr = bin = av_malloc(len); + while (*val) { + int a = hexchar2int(*val++); + int b = hexchar2int(*val++); + if (a < 0 || b < 0) { + av_free(bin); + return NULL; + } + *ptr++ = (a << 4) | b; + } + *dst = bin; + *lendst = len; + return o; + } if(o->type != FF_OPT_TYPE_STRING){ for(;;){ int i; char buf[256]; int cmd=0; double d; - char *error = NULL; + const char *error = NULL; if(*val == '+' || *val == '-') cmd= *(val++); @@ -160,7 +190,7 @@ const AVOption *av_set_string(void *obj, const char *name, const char *val){ return NULL; } - memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); + memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val)); return o; } @@ -184,6 +214,8 @@ const AVOption *av_set_int(void *obj, const char *name, int64_t n){ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len){ const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); void *dst; + uint8_t *bin; + int len, i; if(!o || o->offset<=0) return NULL; if(o->type != FF_OPT_TYPE_STRING && (!buf || !buf_len)) @@ -192,9 +224,6 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c dst= ((uint8_t*)obj) + o->offset; if(o_out) *o_out= o; - if(o->type == FF_OPT_TYPE_STRING) - return dst; - switch(o->type){ case FF_OPT_TYPE_FLAGS: snprintf(buf, buf_len, "0x%08X",*(int *)dst);break; case FF_OPT_TYPE_INT: snprintf(buf, buf_len, "%d" , *(int *)dst);break; @@ -202,6 +231,13 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c case FF_OPT_TYPE_FLOAT: snprintf(buf, buf_len, "%f" , *(float *)dst);break; case FF_OPT_TYPE_DOUBLE: snprintf(buf, buf_len, "%f" , *(double *)dst);break; case FF_OPT_TYPE_RATIONAL: snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; + case FF_OPT_TYPE_STRING: return *(void**)dst; + case FF_OPT_TYPE_BINARY: + len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *)); + if(len >= (buf_len + 1)/2) return NULL; + bin = *(uint8_t**)dst; + for(i = 0; i < len; i++) snprintf(buf + i*2, 3, "%02X", bin[i]); + break; default: return NULL; } return buf; @@ -308,6 +344,9 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit) case FF_OPT_TYPE_RATIONAL: av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<rational>" ); break; + case FF_OPT_TYPE_BINARY: + av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "<binary>" ); + break; case FF_OPT_TYPE_CONST: default: av_log( av_log_obj, AV_LOG_INFO, "%-7s ", "" ); @@ -375,6 +414,7 @@ void av_opt_set_defaults2(void *s, int mask, int flags) } break; case FF_OPT_TYPE_STRING: + case FF_OPT_TYPE_BINARY: /* Cannot set default for string as default_val is of type * double */ break; default: diff --git a/contrib/ffmpeg/libavcodec/opt.h b/contrib/ffmpeg/libavcodec/opt.h index 151dbb788..4691d1dfb 100644 --- a/contrib/ffmpeg/libavcodec/opt.h +++ b/contrib/ffmpeg/libavcodec/opt.h @@ -19,14 +19,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVOPT_H -#define AVOPT_H +#ifndef FFMPEG_OPT_H +#define FFMPEG_OPT_H /** * @file opt.h * AVOptions */ +#include "libavutil/rational.h" + enum AVOptionType{ FF_OPT_TYPE_FLAGS, FF_OPT_TYPE_INT, @@ -35,6 +37,7 @@ enum AVOptionType{ FF_OPT_TYPE_FLOAT, FF_OPT_TYPE_STRING, FF_OPT_TYPE_RATIONAL, + FF_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length FF_OPT_TYPE_CONST=128, }; @@ -46,7 +49,7 @@ typedef struct AVOption { /** * short English text help. - * @fixme what about other languages + * @todo what about other languages */ const char *help; int offset; ///< offset to context structure where the parsed value should be stored @@ -82,4 +85,4 @@ int av_opt_show(void *obj, void *av_log_obj); void av_opt_set_defaults(void *s); void av_opt_set_defaults2(void *s, int mask, int flags); -#endif +#endif /* FFMPEG_OPT_H */ diff --git a/contrib/ffmpeg/libavcodec/os2thread.c b/contrib/ffmpeg/libavcodec/os2thread.c index c52b7ae02..5c74a7d65 100644 --- a/contrib/ffmpeg/libavcodec/os2thread.c +++ b/contrib/ffmpeg/libavcodec/os2thread.c @@ -15,15 +15,13 @@ * * 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 - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ //#define DEBUG // Ported by Vlad Stelmahovsky #include "avcodec.h" -#include "common.h" #define INCL_DOS #define INCL_DOSERRORS @@ -63,7 +61,7 @@ void thread_func(void *v){ /** * free what has been allocated by avcodec_thread_init(). - * must be called after decoding has finished, especially dont call while avcodec_thread_execute() is running + * must be called after decoding has finished, especially do not call while avcodec_thread_execute() is running */ void avcodec_thread_free(AVCodecContext *s){ ThreadContext *c= s->thread_opaque; diff --git a/contrib/ffmpeg/libavcodec/parser.c b/contrib/ffmpeg/libavcodec/parser.c index f3e7ee335..b0a6a2a1b 100644 --- a/contrib/ffmpeg/libavcodec/parser.c +++ b/contrib/ffmpeg/libavcodec/parser.c @@ -19,14 +19,16 @@ * 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" -#include "mpegvideo.h" -#include "mpegaudio.h" -#include "ac3.h" + #include "parser.h" AVCodecParser *av_first_parser = NULL; +AVCodecParser* av_parser_next(AVCodecParser *p){ + if(p) return p->next; + else return av_first_parser; +} + void av_register_codec_parser(AVCodecParser *parser) { parser->next = av_first_parser; @@ -124,13 +126,14 @@ int av_parser_parse(AVCodecParserContext *s, s->fetch_timestamp=0; s->last_pts = pts; s->last_dts = dts; + s->last_offset = 0; s->cur_frame_pts[k] = s->cur_frame_dts[k] = AV_NOPTS_VALUE; } } /* WARNING: the returned index can be negative */ - index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size); + index = s->parser->parser_parse(s, avctx, (const uint8_t **)poutbuf, poutbuf_size, buf, buf_size); //av_log(NULL, AV_LOG_DEBUG, "parser: in:%"PRId64", %"PRId64", out:%"PRId64", %"PRId64", in:%d out:%d id:%d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id); /* update the file pointer */ if (*poutbuf_size) { @@ -138,6 +141,7 @@ int av_parser_parse(AVCodecParserContext *s, s->frame_offset = s->last_frame_offset; s->pts = s->last_pts; s->dts = s->last_dts; + s->offset = s->last_offset; /* offset of the next frame */ s->last_frame_offset = s->cur_offset + index; @@ -156,6 +160,7 @@ int av_parser_parse(AVCodecParserContext *s, s->last_pts = s->cur_frame_pts[k]; s->last_dts = s->cur_frame_dts[k]; + s->last_offset = s->last_frame_offset - s->cur_frame_offset[k]; /* some parsers tell us the packet size even before seeing the first byte of the next packet, so the next pts/dts is in the next chunk */ @@ -221,7 +226,7 @@ void av_parser_close(AVCodecParserContext *s) * combines the (truncated) bitstream to a complete frame * @returns -1 if no complete frame could be created */ -int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) +int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) { #if 0 if(pc->overread){ @@ -230,7 +235,7 @@ int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) } #endif - /* copy overreaded bytes from last frame into buffer */ + /* Copy overread bytes from last frame into buffer. */ for(; pc->overread>0; pc->overread--){ pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; } @@ -296,74 +301,6 @@ void ff_parse1_close(AVCodecParserContext *s) /*************************/ -#ifdef CONFIG_MPEG4VIDEO_PARSER -/* used by parser */ -/* XXX: make it use less memory */ -static int av_mpeg4_decode_header(AVCodecParserContext *s1, - AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - ParseContext1 *pc = s1->priv_data; - MpegEncContext *s = pc->enc; - GetBitContext gb1, *gb = &gb1; - int ret; - - s->avctx = avctx; - s->current_picture_ptr = &s->current_picture; - - if (avctx->extradata_size && pc->first_picture){ - init_get_bits(gb, avctx->extradata, avctx->extradata_size*8); - ret = ff_mpeg4_decode_picture_header(s, gb); - } - - init_get_bits(gb, buf, 8 * buf_size); - ret = ff_mpeg4_decode_picture_header(s, gb); - if (s->width) { - avcodec_set_dimensions(avctx, s->width, s->height); - } - s1->pict_type= s->pict_type; - pc->first_picture = 0; - return ret; -} - -static int mpeg4video_parse_init(AVCodecParserContext *s) -{ - ParseContext1 *pc = s->priv_data; - - pc->enc = av_mallocz(sizeof(MpegEncContext)); - if (!pc->enc) - return -1; - pc->first_picture = 1; - return 0; -} - -static int mpeg4video_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= ff_mpeg4_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - av_mpeg4_decode_header(s, avctx, buf, buf_size); - - *poutbuf = (uint8_t *)buf; - *poutbuf_size = buf_size; - return next; -} -#endif - int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size) { @@ -377,458 +314,3 @@ int ff_mpeg4video_split(AVCodecContext *avctx, } return 0; } - -/*************************/ - -#ifdef CONFIG_MPEGAUDIO_PARSER -typedef struct MpegAudioParseContext { - uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */ - uint8_t *inbuf_ptr; - int frame_size; - int free_format_frame_size; - int free_format_next_header; - uint32_t header; - int header_count; -} MpegAudioParseContext; - -#define MPA_HEADER_SIZE 4 - -/* header + layer + bitrate + freq + lsf/mpeg25 */ -#undef SAME_HEADER_MASK /* mpegaudio.h defines different version */ -#define SAME_HEADER_MASK \ - (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19)) - -static int mpegaudio_parse_init(AVCodecParserContext *s1) -{ - MpegAudioParseContext *s = s1->priv_data; - s->inbuf_ptr = s->inbuf; - return 0; -} - -static int mpegaudio_parse(AVCodecParserContext *s1, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - MpegAudioParseContext *s = s1->priv_data; - int len, ret, sr; - uint32_t header; - const uint8_t *buf_ptr; - - *poutbuf = NULL; - *poutbuf_size = 0; - buf_ptr = buf; - while (buf_size > 0) { - len = s->inbuf_ptr - s->inbuf; - if (s->frame_size == 0) { - /* special case for next header for first frame in free - format case (XXX: find a simpler method) */ - if (s->free_format_next_header != 0) { - s->inbuf[0] = s->free_format_next_header >> 24; - s->inbuf[1] = s->free_format_next_header >> 16; - s->inbuf[2] = s->free_format_next_header >> 8; - s->inbuf[3] = s->free_format_next_header; - s->inbuf_ptr = s->inbuf + 4; - s->free_format_next_header = 0; - goto got_header; - } - /* no header seen : find one. We need at least MPA_HEADER_SIZE - bytes to parse it */ - len = FFMIN(MPA_HEADER_SIZE - len, buf_size); - if (len > 0) { - memcpy(s->inbuf_ptr, buf_ptr, len); - buf_ptr += len; - buf_size -= len; - s->inbuf_ptr += len; - } - if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) { - got_header: - header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | - (s->inbuf[2] << 8) | s->inbuf[3]; - - ret = mpa_decode_header(avctx, header, &sr); - if (ret < 0) { - s->header_count= -2; - /* no sync found : move by one byte (inefficient, but simple!) */ - memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); - s->inbuf_ptr--; - dprintf(avctx, "skip %x\n", header); - /* reset free format frame size to give a chance - to get a new bitrate */ - s->free_format_frame_size = 0; - } else { - if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) - s->header_count= -3; - s->header= header; - s->header_count++; - s->frame_size = ret; - -#if 0 - /* free format: prepare to compute frame size */ - if (decode_header(s, header) == 1) { - s->frame_size = -1; - } -#endif - } - if(s->header_count > 1) - avctx->sample_rate= sr; - } - } else -#if 0 - if (s->frame_size == -1) { - /* free format : find next sync to compute frame size */ - len = MPA_MAX_CODED_FRAME_SIZE - len; - if (len > buf_size) - len = buf_size; - if (len == 0) { - /* frame too long: resync */ - s->frame_size = 0; - memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1); - s->inbuf_ptr--; - } else { - uint8_t *p, *pend; - uint32_t header1; - int padding; - - memcpy(s->inbuf_ptr, buf_ptr, len); - /* check for header */ - p = s->inbuf_ptr - 3; - pend = s->inbuf_ptr + len - 4; - while (p <= pend) { - header = (p[0] << 24) | (p[1] << 16) | - (p[2] << 8) | p[3]; - header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) | - (s->inbuf[2] << 8) | s->inbuf[3]; - /* check with high probability that we have a - valid header */ - if ((header & SAME_HEADER_MASK) == - (header1 & SAME_HEADER_MASK)) { - /* header found: update pointers */ - len = (p + 4) - s->inbuf_ptr; - buf_ptr += len; - buf_size -= len; - s->inbuf_ptr = p; - /* compute frame size */ - s->free_format_next_header = header; - s->free_format_frame_size = s->inbuf_ptr - s->inbuf; - padding = (header1 >> 9) & 1; - if (s->layer == 1) - s->free_format_frame_size -= padding * 4; - else - s->free_format_frame_size -= padding; - dprintf(avctx, "free frame size=%d padding=%d\n", - s->free_format_frame_size, padding); - decode_header(s, header1); - goto next_data; - } - p++; - } - /* not found: simply increase pointers */ - buf_ptr += len; - s->inbuf_ptr += len; - buf_size -= len; - } - } else -#endif - if (len < s->frame_size) { - if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE) - s->frame_size = MPA_MAX_CODED_FRAME_SIZE; - len = FFMIN(s->frame_size - len, buf_size); - memcpy(s->inbuf_ptr, buf_ptr, len); - buf_ptr += len; - s->inbuf_ptr += len; - buf_size -= len; - } - - if(s->frame_size > 0 && buf_ptr - buf == s->inbuf_ptr - s->inbuf - && buf_size + buf_ptr - buf >= s->frame_size){ - if(s->header_count > 0){ - *poutbuf = buf; - *poutbuf_size = s->frame_size; - } - buf_ptr = buf + s->frame_size; - s->inbuf_ptr = s->inbuf; - s->frame_size = 0; - break; - } - - // next_data: - if (s->frame_size > 0 && - (s->inbuf_ptr - s->inbuf) >= s->frame_size) { - if(s->header_count > 0){ - *poutbuf = s->inbuf; - *poutbuf_size = s->inbuf_ptr - s->inbuf; - } - s->inbuf_ptr = s->inbuf; - s->frame_size = 0; - break; - } - } - return buf_ptr - buf; -} -#endif /* CONFIG_MPEGAUDIO_PARSER */ - -#if defined(CONFIG_AC3_PARSER) || defined(CONFIG_AAC_PARSER) -/* also used for ADTS AAC */ -typedef struct AC3ParseContext { - uint8_t *inbuf_ptr; - int frame_size; - int header_size; - int (*sync)(const uint8_t *buf, int *channels, int *sample_rate, - int *bit_rate, int *samples); - uint8_t inbuf[8192]; /* input buffer */ -} AC3ParseContext; - -#define AC3_HEADER_SIZE 7 -#define AAC_HEADER_SIZE 7 - -#ifdef CONFIG_AC3_PARSER - -static const uint8_t eac3_blocks[4] = { - 1, 2, 3, 6 -}; - -#endif /* CONFIG_AC3_PARSER */ - -#ifdef CONFIG_AAC_PARSER -static const int aac_sample_rates[16] = { - 96000, 88200, 64000, 48000, 44100, 32000, - 24000, 22050, 16000, 12000, 11025, 8000, 7350 -}; - -static const int aac_channels[8] = { - 0, 1, 2, 3, 4, 5, 6, 8 -}; -#endif - -#ifdef CONFIG_AC3_PARSER -static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, - int *bit_rate, int *samples) -{ - int err; - unsigned int fscod, acmod, bsid, lfeon; - unsigned int strmtyp, substreamid, frmsiz, fscod2, numblkscod; - GetBitContext bits; - AC3HeaderInfo hdr; - - err = ff_ac3_parse_header(buf, &hdr); - - if(err < 0 && err != -2) - return 0; - - bsid = hdr.bsid; - if(bsid <= 10) { /* Normal AC-3 */ - *sample_rate = hdr.sample_rate; - *bit_rate = hdr.bit_rate; - *channels = hdr.channels; - *samples = AC3_FRAME_SIZE; - return hdr.frame_size; - } else if (bsid > 10 && bsid <= 16) { /* Enhanced AC-3 */ - init_get_bits(&bits, &buf[2], (AC3_HEADER_SIZE-2) * 8); - strmtyp = get_bits(&bits, 2); - substreamid = get_bits(&bits, 3); - - if (strmtyp != 0 || substreamid != 0) - return 0; /* Currently don't support additional streams */ - - frmsiz = get_bits(&bits, 11) + 1; - fscod = get_bits(&bits, 2); - if (fscod == 3) { - fscod2 = get_bits(&bits, 2); - numblkscod = 3; - - if(fscod2 == 3) - return 0; - - *sample_rate = ff_ac3_freqs[fscod2] / 2; - } else { - numblkscod = get_bits(&bits, 2); - - *sample_rate = ff_ac3_freqs[fscod]; - } - - acmod = get_bits(&bits, 3); - lfeon = get_bits1(&bits); - - *samples = eac3_blocks[numblkscod] * 256; - *bit_rate = frmsiz * (*sample_rate) * 16 / (*samples); - *channels = ff_ac3_channels[acmod] + lfeon; - - return frmsiz * 2; - } - - /* Unsupported bitstream version */ - return 0; -} -#endif /* CONFIG_AC3_PARSER */ - -#ifdef CONFIG_AAC_PARSER -static int aac_sync(const uint8_t *buf, int *channels, int *sample_rate, - int *bit_rate, int *samples) -{ - GetBitContext bits; - int size, rdb, ch, sr; - - init_get_bits(&bits, buf, AAC_HEADER_SIZE * 8); - - if(get_bits(&bits, 12) != 0xfff) - return 0; - - skip_bits1(&bits); /* id */ - skip_bits(&bits, 2); /* layer */ - skip_bits1(&bits); /* protection_absent */ - skip_bits(&bits, 2); /* profile_objecttype */ - sr = get_bits(&bits, 4); /* sample_frequency_index */ - if(!aac_sample_rates[sr]) - return 0; - skip_bits1(&bits); /* private_bit */ - ch = get_bits(&bits, 3); /* channel_configuration */ - if(!aac_channels[ch]) - return 0; - skip_bits1(&bits); /* original/copy */ - skip_bits1(&bits); /* home */ - - /* adts_variable_header */ - skip_bits1(&bits); /* copyright_identification_bit */ - skip_bits1(&bits); /* copyright_identification_start */ - size = get_bits(&bits, 13); /* aac_frame_length */ - skip_bits(&bits, 11); /* adts_buffer_fullness */ - rdb = get_bits(&bits, 2); /* number_of_raw_data_blocks_in_frame */ - - *channels = aac_channels[ch]; - *sample_rate = aac_sample_rates[sr]; - *samples = (rdb + 1) * 1024; - *bit_rate = size * 8 * *sample_rate / *samples; - - return size; -} -#endif /* CONFIG_AAC_PARSER */ - -#ifdef CONFIG_AC3_PARSER -static int ac3_parse_init(AVCodecParserContext *s1) -{ - AC3ParseContext *s = s1->priv_data; - s->inbuf_ptr = s->inbuf; - s->header_size = AC3_HEADER_SIZE; - s->sync = ac3_sync; - return 0; -} -#endif - -#ifdef CONFIG_AAC_PARSER -static int aac_parse_init(AVCodecParserContext *s1) -{ - AC3ParseContext *s = s1->priv_data; - s->inbuf_ptr = s->inbuf; - s->header_size = AAC_HEADER_SIZE; - s->sync = aac_sync; - return 0; -} -#endif - -/* also used for ADTS AAC */ -static int ac3_parse(AVCodecParserContext *s1, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - AC3ParseContext *s = s1->priv_data; - const uint8_t *buf_ptr; - int len, sample_rate, bit_rate, channels, samples; - - *poutbuf = NULL; - *poutbuf_size = 0; - - buf_ptr = buf; - while (buf_size > 0) { - len = s->inbuf_ptr - s->inbuf; - if (s->frame_size == 0) { - /* no header seen : find one. We need at least s->header_size - bytes to parse it */ - len = FFMIN(s->header_size - len, buf_size); - - memcpy(s->inbuf_ptr, buf_ptr, len); - buf_ptr += len; - s->inbuf_ptr += len; - buf_size -= len; - if ((s->inbuf_ptr - s->inbuf) == s->header_size) { - len = s->sync(s->inbuf, &channels, &sample_rate, &bit_rate, - &samples); - if (len == 0) { - /* no sync found : move by one byte (inefficient, but simple!) */ - memmove(s->inbuf, s->inbuf + 1, s->header_size - 1); - s->inbuf_ptr--; - } else { - s->frame_size = len; - /* update codec info */ - avctx->sample_rate = sample_rate; - /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */ - if(avctx->codec_id == CODEC_ID_AC3){ - if(avctx->channels!=1 && avctx->channels!=2){ - avctx->channels = channels; - } - } else { - avctx->channels = channels; - } - avctx->bit_rate = bit_rate; - avctx->frame_size = samples; - } - } - } else { - len = FFMIN(s->frame_size - len, buf_size); - - memcpy(s->inbuf_ptr, buf_ptr, len); - buf_ptr += len; - s->inbuf_ptr += len; - buf_size -= len; - - if(s->inbuf_ptr - s->inbuf == s->frame_size){ - *poutbuf = s->inbuf; - *poutbuf_size = s->frame_size; - s->inbuf_ptr = s->inbuf; - s->frame_size = 0; - break; - } - } - } - return buf_ptr - buf; -} -#endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ - -#ifdef CONFIG_MPEG4VIDEO_PARSER -AVCodecParser mpeg4video_parser = { - { CODEC_ID_MPEG4 }, - sizeof(ParseContext1), - mpeg4video_parse_init, - mpeg4video_parse, - ff_parse1_close, - ff_mpeg4video_split, -}; -#endif -#ifdef CONFIG_MPEGAUDIO_PARSER -AVCodecParser mpegaudio_parser = { - { CODEC_ID_MP2, CODEC_ID_MP3 }, - sizeof(MpegAudioParseContext), - mpegaudio_parse_init, - mpegaudio_parse, - NULL, -}; -#endif -#ifdef CONFIG_AC3_PARSER -AVCodecParser ac3_parser = { - { CODEC_ID_AC3 }, - sizeof(AC3ParseContext), - ac3_parse_init, - ac3_parse, - NULL, -}; -#endif -#ifdef CONFIG_AAC_PARSER -AVCodecParser aac_parser = { - { CODEC_ID_AAC }, - sizeof(AC3ParseContext), - aac_parse_init, - ac3_parse, - NULL, -}; -#endif diff --git a/contrib/ffmpeg/libavcodec/parser.h b/contrib/ffmpeg/libavcodec/parser.h index 3496b341f..47eeb4cde 100644 --- a/contrib/ffmpeg/libavcodec/parser.h +++ b/contrib/ffmpeg/libavcodec/parser.h @@ -23,6 +23,8 @@ #ifndef FFMPEG_PARSER_H #define FFMPEG_PARSER_H +#include "avcodec.h" + typedef struct ParseContext{ uint8_t *buffer; int index; @@ -31,7 +33,7 @@ typedef struct ParseContext{ 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 + int overread_index; ///< the index into ParseContext.buffer of the overread bytes } ParseContext; struct MpegEncContext; @@ -51,13 +53,10 @@ typedef struct ParseContext1{ #define END_NOT_FOUND (-100) -int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size); +int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size); int ff_mpeg4video_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size); void ff_parse_close(AVCodecParserContext *s); void ff_parse1_close(AVCodecParserContext *s); -/* h263dec.c */ -int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size); - -#endif /* !FFMPEG_PARSER_H */ +#endif /* FFMPEG_PARSER_H */ diff --git a/contrib/ffmpeg/libavcodec/pcm.c b/contrib/ffmpeg/libavcodec/pcm.c index 5570c01bd..926c6f010 100644 --- a/contrib/ffmpeg/libavcodec/pcm.c +++ b/contrib/ffmpeg/libavcodec/pcm.c @@ -26,6 +26,9 @@ #include "avcodec.h" #include "bitstream.h" // for ff_reverse +#include "bytestream.h" + +#define MAX_CHANNELS 64 /* from g711.c by SUN microsystems (unrestricted use) */ @@ -169,14 +172,15 @@ static int pcm_encode_close(AVCodecContext *avctx) */ static inline void encode_from16(int bps, int le, int us, short **samples, uint8_t **dst, int n) { + int usum = us ? 0x8000 : 0; if (bps > 2) memset(*dst, 0, n * bps); if (le) *dst += bps - 2; for(;n>0;n--) { register int v = *(*samples)++; - if (us) v += 0x8000; - (*dst)[le] = v >> 8; - (*dst)[1 - le] = v; + v += usum; + if (le) AV_WL16(*dst, v); + else AV_WB16(*dst, v); *dst += bps; } if (le) *dst -= bps - 2; @@ -247,74 +251,66 @@ static int pcm_encode_frame(AVCodecContext *avctx, uint32_t tmp = ff_reverse[*samples >> 8] + (ff_reverse[*samples & 0xff] << 8); tmp <<= 4; // sync flags would go here - dst[2] = tmp & 0xff; - tmp >>= 8; - dst[1] = tmp & 0xff; - dst[0] = tmp >> 8; + bytestream_put_be24(&dst, tmp); samples++; - dst += 3; } break; case CODEC_ID_PCM_S16LE: for(;n>0;n--) { v = *samples++; - dst[0] = v & 0xff; - dst[1] = v >> 8; - dst += 2; + bytestream_put_le16(&dst, v); } break; case CODEC_ID_PCM_S16BE: for(;n>0;n--) { v = *samples++; - dst[0] = v >> 8; - dst[1] = v; - dst += 2; + bytestream_put_be16(&dst, v); } break; case CODEC_ID_PCM_U16LE: for(;n>0;n--) { v = *samples++; v += 0x8000; - dst[0] = v & 0xff; - dst[1] = v >> 8; - dst += 2; + bytestream_put_le16(&dst, v); } break; case CODEC_ID_PCM_U16BE: for(;n>0;n--) { v = *samples++; v += 0x8000; - dst[0] = v >> 8; - dst[1] = v; - dst += 2; + bytestream_put_be16(&dst, v); } break; case CODEC_ID_PCM_S8: for(;n>0;n--) { v = *samples++; - dst[0] = v >> 8; - dst++; + *dst++ = v >> 8; } break; case CODEC_ID_PCM_U8: for(;n>0;n--) { v = *samples++; - dst[0] = (v >> 8) + 128; - dst++; + *dst++ = (v >> 8) + 128; + } + break; + case CODEC_ID_PCM_ZORK: + for(;n>0;n--) { + v= *samples++ >> 8; + if(v<0) v = -v; + else v+= 128; + *dst++ = v; } break; case CODEC_ID_PCM_ALAW: for(;n>0;n--) { v = *samples++; - dst[0] = linear_to_alaw[(v + 32768) >> 2]; - dst++; + *dst++ = linear_to_alaw[(v + 32768) >> 2]; } break; case CODEC_ID_PCM_MULAW: for(;n>0;n--) { v = *samples++; - dst[0] = linear_to_ulaw[(v + 32768) >> 2]; - dst++; + *dst++ = linear_to_ulaw[(v + 32768) >> 2]; } break; default: @@ -359,12 +355,17 @@ static int pcm_decode_init(AVCodecContext * avctx) * \param src_len number of bytes in src */ static inline void decode_to16(int bps, int le, int us, - uint8_t **src, short **samples, int src_len) + const uint8_t **src, short **samples, int src_len) { + int usum = us ? -0x8000 : 0; register int n = src_len / bps; if (le) *src += bps - 2; for(;n>0;n--) { - *(*samples)++ = ((*src)[le] << 8 | (*src)[1 - le]) - (us?0x8000:0); + register int v; + if (le) v = AV_RL16(*src); + else v = AV_RB16(*src); + v += usum; + *(*samples)++ = v; *src += bps; } if (le) *src -= bps - 2; @@ -372,12 +373,12 @@ static inline void decode_to16(int bps, int le, int us, static int pcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { PCMDecode *s = avctx->priv_data; - int n; + int c, n; short *samples; - uint8_t *src; + const uint8_t *src, *src2[MAX_CHANNELS]; samples = data; src = buf; @@ -387,10 +388,18 @@ static int pcm_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n"); return -1; } + if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){ + av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n"); + return -1; + } buf_size= FFMIN(buf_size, *data_size/2); *data_size=0; + n = buf_size/avctx->channels; + for(c=0;c<avctx->channels;c++) + src2[c] = &src[c*n]; + switch(avctx->codec->id) { case CODEC_ID_PCM_S32LE: decode_to16(4, 1, 0, &src, &samples, buf_size); @@ -419,61 +428,68 @@ static int pcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_PCM_S24DAUD: n = buf_size / 3; for(;n>0;n--) { - uint32_t v = src[0] << 16 | src[1] << 8 | src[2]; + uint32_t v = bytestream_get_be24(&src); v >>= 4; // sync flags are here *samples++ = ff_reverse[(v >> 8) & 0xff] + (ff_reverse[v & 0xff] << 8); - src += 3; } break; case CODEC_ID_PCM_S16LE: n = buf_size >> 1; for(;n>0;n--) { - *samples++ = src[0] | (src[1] << 8); - src += 2; + *samples++ = bytestream_get_le16(&src); } break; + case CODEC_ID_PCM_S16LE_PLANAR: + for(n>>=1;n>0;n--) + for(c=0;c<avctx->channels;c++) + *samples++ = bytestream_get_le16(&src2[c]); + src = src2[avctx->channels-1]; + break; case CODEC_ID_PCM_S16BE: n = buf_size >> 1; for(;n>0;n--) { - *samples++ = (src[0] << 8) | src[1]; - src += 2; + *samples++ = bytestream_get_be16(&src); } break; case CODEC_ID_PCM_U16LE: n = buf_size >> 1; for(;n>0;n--) { - *samples++ = (src[0] | (src[1] << 8)) - 0x8000; - src += 2; + *samples++ = bytestream_get_le16(&src) - 0x8000; } break; case CODEC_ID_PCM_U16BE: n = buf_size >> 1; for(;n>0;n--) { - *samples++ = ((src[0] << 8) | src[1]) - 0x8000; - src += 2; + *samples++ = bytestream_get_be16(&src) - 0x8000; } break; case CODEC_ID_PCM_S8: n = buf_size; for(;n>0;n--) { - *samples++ = src[0] << 8; - src++; + *samples++ = *src++ << 8; } break; case CODEC_ID_PCM_U8: n = buf_size; for(;n>0;n--) { - *samples++ = ((int)src[0] - 128) << 8; - src++; + *samples++ = ((int)*src++ - 128) << 8; + } + break; + case CODEC_ID_PCM_ZORK: + n = buf_size; + for(;n>0;n--) { + int x= *src++; + if(x&128) x-= 128; + else x = -x; + *samples++ = x << 8; } break; case CODEC_ID_PCM_ALAW: case CODEC_ID_PCM_MULAW: n = buf_size; for(;n>0;n--) { - *samples++ = s->table[src[0]]; - src++; + *samples++ = s->table[*src++]; } break; default: @@ -483,7 +499,8 @@ static int pcm_decode_frame(AVCodecContext *avctx, return src - buf; } -#define PCM_CODEC(id, name) \ +#ifdef CONFIG_ENCODERS +#define PCM_ENCODER(id,name) \ AVCodec name ## _encoder = { \ #name, \ CODEC_TYPE_AUDIO, \ @@ -493,7 +510,13 @@ AVCodec name ## _encoder = { \ pcm_encode_frame, \ pcm_encode_close, \ NULL, \ -}; \ +}; +#else +#define PCM_ENCODER(id,name) +#endif + +#ifdef CONFIG_DECODERS +#define PCM_DECODER(id,name) \ AVCodec name ## _decoder = { \ #name, \ CODEC_TYPE_AUDIO, \ @@ -503,24 +526,30 @@ AVCodec name ## _decoder = { \ NULL, \ NULL, \ pcm_decode_frame, \ -} +}; +#else +#define PCM_DECODER(id,name) +#endif -PCM_CODEC(CODEC_ID_PCM_S32LE, pcm_s32le); -PCM_CODEC(CODEC_ID_PCM_S32BE, pcm_s32be); -PCM_CODEC(CODEC_ID_PCM_U32LE, pcm_u32le); -PCM_CODEC(CODEC_ID_PCM_U32BE, pcm_u32be); -PCM_CODEC(CODEC_ID_PCM_S24LE, pcm_s24le); -PCM_CODEC(CODEC_ID_PCM_S24BE, pcm_s24be); -PCM_CODEC(CODEC_ID_PCM_U24LE, pcm_u24le); -PCM_CODEC(CODEC_ID_PCM_U24BE, pcm_u24be); -PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); -PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); -PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); -PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); -PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); -PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); -PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); -PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); -PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); - -#undef PCM_CODEC +#define PCM_CODEC(id, name) \ +PCM_ENCODER(id,name) PCM_DECODER(id,name) + +PCM_CODEC (CODEC_ID_PCM_S32LE, pcm_s32le); +PCM_CODEC (CODEC_ID_PCM_S32BE, pcm_s32be); +PCM_CODEC (CODEC_ID_PCM_U32LE, pcm_u32le); +PCM_CODEC (CODEC_ID_PCM_U32BE, pcm_u32be); +PCM_CODEC (CODEC_ID_PCM_S24LE, pcm_s24le); +PCM_CODEC (CODEC_ID_PCM_S24BE, pcm_s24be); +PCM_CODEC (CODEC_ID_PCM_U24LE, pcm_u24le); +PCM_CODEC (CODEC_ID_PCM_U24BE, pcm_u24be); +PCM_CODEC (CODEC_ID_PCM_S24DAUD, pcm_s24daud); +PCM_CODEC (CODEC_ID_PCM_S16LE, pcm_s16le); +PCM_DECODER(CODEC_ID_PCM_S16LE_PLANAR, pcm_s16le_planar); +PCM_CODEC (CODEC_ID_PCM_S16BE, pcm_s16be); +PCM_CODEC (CODEC_ID_PCM_U16LE, pcm_u16le); +PCM_CODEC (CODEC_ID_PCM_U16BE, pcm_u16be); +PCM_CODEC (CODEC_ID_PCM_S8, pcm_s8); +PCM_CODEC (CODEC_ID_PCM_U8, pcm_u8); +PCM_CODEC (CODEC_ID_PCM_ALAW, pcm_alaw); +PCM_CODEC (CODEC_ID_PCM_MULAW, pcm_mulaw); +PCM_CODEC (CODEC_ID_PCM_ZORK, pcm_zork); diff --git a/contrib/ffmpeg/libavcodec/pcx.c b/contrib/ffmpeg/libavcodec/pcx.c new file mode 100644 index 000000000..5aa7b0846 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/pcx.c @@ -0,0 +1,247 @@ +/* + * PC Paintbrush PCX (.pcx) image decoder + * Copyright (c) 2007, 2008 Ivo van Poorten + * + * This decoder does not support CGA palettes. I am unable to find samples + * and Netpbm cannot generate them. + * + * 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" +#include "bytestream.h" +#include "bitstream.h" + +typedef struct PCXContext { + AVFrame picture; +} PCXContext; + +static int pcx_init(AVCodecContext *avctx) { + PCXContext *s = avctx->priv_data; + + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame= &s->picture; + + return 0; +} + +/** + * @return advanced src pointer + */ +static const char *pcx_rle_decode(const uint8_t *src, uint8_t *dst, + unsigned int bytes_per_scanline) { + unsigned int i = 0; + unsigned char run, value; + + while (i<bytes_per_scanline) { + run = 1; + value = *src++; + if (value >= 0xc0) { + run = value & 0x3f; + value = *src++; + } + while (i<bytes_per_scanline && run--) + dst[i++] = value; + } + + return src; +} + +static void pcx_palette(const uint8_t **src, uint32_t *dst, unsigned int pallen) { + unsigned int i; + + for (i=0; i<pallen; i++) + *dst++ = bytestream_get_be24(src); + memset(dst, 0, (256 - pallen) * sizeof(*dst)); +} + +static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + const uint8_t *buf, int buf_size) { + PCXContext * const s = avctx->priv_data; + AVFrame *picture = data; + AVFrame * const p = &s->picture; + int xmin, ymin, xmax, ymax; + unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x, + bytes_per_scanline; + uint8_t *ptr; + uint8_t const *bufstart = buf; + + if (buf[0] != 0x0a || buf[1] > 5 || buf[1] == 1 || buf[2] != 1) { + av_log(avctx, AV_LOG_ERROR, "this is not PCX encoded data\n"); + return -1; + } + + xmin = AV_RL16(buf+ 4); + ymin = AV_RL16(buf+ 6); + xmax = AV_RL16(buf+ 8); + ymax = AV_RL16(buf+10); + + if (xmax < xmin || ymax < ymin) { + av_log(avctx, AV_LOG_ERROR, "invalid image dimensions\n"); + return -1; + } + + w = xmax - xmin + 1; + h = ymax - ymin + 1; + + bits_per_pixel = buf[3]; + bytes_per_line = AV_RL16(buf+66); + nplanes = buf[65]; + bytes_per_scanline = nplanes * bytes_per_line; + + if (bytes_per_scanline < w * bits_per_pixel * nplanes / 8) { + av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n"); + return -1; + } + + switch ((nplanes<<8) + bits_per_pixel) { + case 0x0308: + avctx->pix_fmt = PIX_FMT_RGB24; + break; + case 0x0108: + case 0x0104: + case 0x0102: + case 0x0101: + case 0x0401: + case 0x0301: + case 0x0201: + avctx->pix_fmt = PIX_FMT_PAL8; + break; + default: + av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n"); + return -1; + } + + buf += 128; + + if (p->data[0]) + avctx->release_buffer(avctx, p); + + 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; + } + + p->pict_type = FF_I_TYPE; + + ptr = p->data[0]; + stride = p->linesize[0]; + + if (nplanes == 3 && bits_per_pixel == 8) { + uint8_t scanline[bytes_per_scanline]; + + for (y=0; y<h; y++) { + buf = pcx_rle_decode(buf, scanline, bytes_per_scanline); + + for (x=0; x<w; x++) { + ptr[3*x ] = scanline[x ]; + ptr[3*x+1] = scanline[x+ bytes_per_line ]; + ptr[3*x+2] = scanline[x+(bytes_per_line<<1)]; + } + + ptr += stride; + } + + } else if (nplanes == 1 && bits_per_pixel == 8) { + uint8_t scanline[bytes_per_scanline]; + const uint8_t *palstart = bufstart + buf_size - 769; + + for (y=0; y<h; y++, ptr+=stride) { + buf = pcx_rle_decode(buf, scanline, bytes_per_scanline); + memcpy(ptr, scanline, w); + } + + if (buf != palstart) { + av_log(avctx, AV_LOG_WARNING, "image data possibly corrupted\n"); + buf = palstart; + } + if (*buf++ != 12) { + av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n"); + return -1; + } + + } else if (nplanes == 1) { /* all packed formats, max. 16 colors */ + uint8_t scanline[bytes_per_scanline]; + GetBitContext s; + + for (y=0; y<h; y++) { + init_get_bits(&s, scanline, bytes_per_scanline<<3); + + buf = pcx_rle_decode(buf, scanline, bytes_per_scanline); + + for (x=0; x<w; x++) + ptr[x] = get_bits(&s, bits_per_pixel); + ptr += stride; + } + + } else { /* planar, 4, 8 or 16 colors */ + uint8_t scanline[bytes_per_scanline]; + int i; + + for (y=0; y<h; y++) { + buf = pcx_rle_decode(buf, scanline, bytes_per_scanline); + + for (x=0; x<w; x++) { + int m = 0x80 >> (x&7), v = 0; + for (i=nplanes - 1; i>=0; i--) { + v <<= 1; + v += !!(scanline[i*bytes_per_line + (x>>3)] & m); + } + ptr[x] = v; + } + ptr += stride; + } + } + + if (nplanes == 1 && bits_per_pixel == 8) { + pcx_palette(&buf, (uint32_t *) p->data[1], 256); + } else if (bits_per_pixel < 8) { + const uint8_t *palette = bufstart+16; + pcx_palette(&palette, (uint32_t *) p->data[1], 16); + } + + *picture = s->picture; + *data_size = sizeof(AVFrame); + + return buf - bufstart; +} + +static int pcx_end(AVCodecContext *avctx) { + PCXContext *s = avctx->priv_data; + + if(s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + + return 0; +} + +AVCodec pcx_decoder = { + "pcx", + CODEC_TYPE_VIDEO, + CODEC_ID_PCX, + sizeof(PCXContext), + pcx_init, + NULL, + pcx_end, + pcx_decode_frame, + 0, + NULL +}; diff --git a/contrib/ffmpeg/libavcodec/png.c b/contrib/ffmpeg/libavcodec/png.c index 05b4512b7..c95ba3e10 100644 --- a/contrib/ffmpeg/libavcodec/png.c +++ b/contrib/ffmpeg/libavcodec/png.c @@ -19,141 +19,45 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" +#include "bytestream.h" +#include "png.h" -/* TODO: - * - add 2, 4 and 16 bit depth support - * - use filters when generating a png (better compression) - */ - -#include <zlib.h> - -//#define DEBUG - -#define PNG_COLOR_MASK_PALETTE 1 -#define PNG_COLOR_MASK_COLOR 2 -#define PNG_COLOR_MASK_ALPHA 4 - -#define PNG_COLOR_TYPE_GRAY 0 -#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) -#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) -#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) -#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) - -#define PNG_FILTER_VALUE_NONE 0 -#define PNG_FILTER_VALUE_SUB 1 -#define PNG_FILTER_VALUE_UP 2 -#define PNG_FILTER_VALUE_AVG 3 -#define PNG_FILTER_VALUE_PAETH 4 - -#define PNG_IHDR 0x0001 -#define PNG_IDAT 0x0002 -#define PNG_ALLIMAGE 0x0004 -#define PNG_PLTE 0x0008 - -#define NB_PASSES 7 - -#define IOBUF_SIZE 4096 - -typedef struct PNGContext { - uint8_t *bytestream; - uint8_t *bytestream_start; - uint8_t *bytestream_end; - AVFrame picture; - - int state; - int width, height; - int bit_depth; - int color_type; - int compression_type; - int interlace_type; - int filter_type; - int channels; - int bits_per_pixel; - int bpp; - - uint8_t *image_buf; - int image_linesize; - uint32_t palette[256]; - uint8_t *crow_buf; - uint8_t *last_row; - uint8_t *tmp_row; - int pass; - int crow_size; /* compressed row size (include filter type) */ - int row_size; /* decompressed row size */ - int pass_row_size; /* decompress row size of the current pass */ - int y; - z_stream zstream; - uint8_t buf[IOBUF_SIZE]; -} PNGContext; - -static unsigned int get32(uint8_t **b){ - (*b) += 4; - return ((*b)[-4]<<24) + ((*b)[-3]<<16) + ((*b)[-2]<<8) + (*b)[-1]; -} - -#ifdef CONFIG_ENCODERS -static void put32(uint8_t **b, unsigned int v){ - *(*b)++= v>>24; - *(*b)++= v>>16; - *(*b)++= v>>8; - *(*b)++= v; -} -#endif - -static const uint8_t pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; +const uint8_t ff_pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; +const uint8_t ff_mngsig[8] = {138, 77, 78, 71, 13, 10, 26, 10}; /* Mask to determine which y pixels are valid in a pass */ -static const uint8_t png_pass_ymask[NB_PASSES] = { +const uint8_t ff_png_pass_ymask[NB_PASSES] = { 0x80, 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, }; -/* Mask to determine which y pixels can be written in a pass */ -static const uint8_t png_pass_dsp_ymask[NB_PASSES] = { - 0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55, -}; - /* minimum x value */ -static const uint8_t png_pass_xmin[NB_PASSES] = { +const uint8_t ff_png_pass_xmin[NB_PASSES] = { 0, 4, 0, 2, 0, 1, 0 }; /* x shift to get row width */ -static const uint8_t png_pass_xshift[NB_PASSES] = { +const uint8_t ff_png_pass_xshift[NB_PASSES] = { 3, 3, 2, 2, 1, 1, 0 }; /* Mask to determine which pixels are valid in a pass */ -static const uint8_t png_pass_mask[NB_PASSES] = { +const uint8_t ff_png_pass_mask[NB_PASSES] = { 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff }; -/* Mask to determine which pixels to overwrite while displaying */ -static const uint8_t png_pass_dsp_mask[NB_PASSES] = { - 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff -}; -#if 0 -static int png_probe(AVProbeData *pd) -{ - if (pd->buf_size >= 8 && - memcmp(pd->buf, pngsig, 8) == 0) - return AVPROBE_SCORE_MAX; - else - return 0; -} -#endif -static void *png_zalloc(void *opaque, unsigned int items, unsigned int size) +void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size) { if(items >= UINT_MAX / size) return NULL; return av_malloc(items * size); } -static void png_zfree(void *opaque, void *ptr) +void ff_png_zfree(void *opaque, void *ptr) { av_free(ptr); } -static int png_get_nb_channels(int color_type) +int ff_png_get_nb_channels(int color_type) { int channels; channels = 1; @@ -166,801 +70,14 @@ static int png_get_nb_channels(int color_type) } /* compute the row size of an interleaved pass */ -static int png_pass_row_size(int pass, int bits_per_pixel, int width) +int ff_png_pass_row_size(int pass, int bits_per_pixel, int width) { int shift, xmin, pass_width; - xmin = png_pass_xmin[pass]; + xmin = ff_png_pass_xmin[pass]; if (width <= xmin) return 0; - shift = png_pass_xshift[pass]; + shift = ff_png_pass_xshift[pass]; pass_width = (width - xmin + (1 << shift) - 1) >> shift; return (pass_width * bits_per_pixel + 7) >> 3; } - -/* NOTE: we try to construct a good looking image at each pass. width - is the original image width. We also do pixel format convertion at - this stage */ -static void png_put_interlaced_row(uint8_t *dst, int width, - int bits_per_pixel, int pass, - int color_type, const uint8_t *src) -{ - int x, mask, dsp_mask, j, src_x, b, bpp; - uint8_t *d; - const uint8_t *s; - - mask = png_pass_mask[pass]; - dsp_mask = png_pass_dsp_mask[pass]; - switch(bits_per_pixel) { - case 1: - /* we must intialize the line to zero before writing to it */ - if (pass == 0) - memset(dst, 0, (width + 7) >> 3); - src_x = 0; - for(x = 0; x < width; x++) { - j = (x & 7); - if ((dsp_mask << j) & 0x80) { - b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1; - dst[x >> 3] |= b << (7 - j); - } - if ((mask << j) & 0x80) - src_x++; - } - break; - default: - bpp = bits_per_pixel >> 3; - d = dst; - s = src; - if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - for(x = 0; x < width; x++) { - j = x & 7; - if ((dsp_mask << j) & 0x80) { - *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2]; - } - d += bpp; - if ((mask << j) & 0x80) - s += bpp; - } - } else { - for(x = 0; x < width; x++) { - j = x & 7; - if ((dsp_mask << j) & 0x80) { - memcpy(d, s, bpp); - } - d += bpp; - if ((mask << j) & 0x80) - s += bpp; - } - } - break; - } -} - -#ifdef CONFIG_ENCODERS -static void png_get_interlaced_row(uint8_t *dst, int row_size, - int bits_per_pixel, int pass, - const uint8_t *src, int width) -{ - int x, mask, dst_x, j, b, bpp; - uint8_t *d; - const uint8_t *s; - - mask = png_pass_mask[pass]; - switch(bits_per_pixel) { - case 1: - memset(dst, 0, row_size); - dst_x = 0; - for(x = 0; x < width; x++) { - j = (x & 7); - if ((mask << j) & 0x80) { - b = (src[x >> 3] >> (7 - j)) & 1; - dst[dst_x >> 3] |= b << (7 - (dst_x & 7)); - dst_x++; - } - } - break; - default: - bpp = bits_per_pixel >> 3; - d = dst; - s = src; - for(x = 0; x < width; x++) { - j = x & 7; - if ((mask << j) & 0x80) { - memcpy(d, s, bpp); - d += bpp; - } - s += bpp; - } - break; - } -} -#endif - -/* XXX: optimize */ -/* NOTE: 'dst' can be equal to 'last' */ -static void png_filter_row(uint8_t *dst, int filter_type, - uint8_t *src, uint8_t *last, int size, int bpp) -{ - int i, p; - - switch(filter_type) { - case PNG_FILTER_VALUE_NONE: - memcpy(dst, src, size); - break; - case PNG_FILTER_VALUE_SUB: - for(i = 0; i < bpp; i++) { - dst[i] = src[i]; - } - for(i = bpp; i < size; i++) { - p = dst[i - bpp]; - dst[i] = p + src[i]; - } - break; - case PNG_FILTER_VALUE_UP: - for(i = 0; i < size; i++) { - p = last[i]; - dst[i] = p + src[i]; - } - break; - case PNG_FILTER_VALUE_AVG: - for(i = 0; i < bpp; i++) { - p = (last[i] >> 1); - dst[i] = p + src[i]; - } - for(i = bpp; i < size; i++) { - p = ((dst[i - bpp] + last[i]) >> 1); - dst[i] = p + src[i]; - } - break; - case PNG_FILTER_VALUE_PAETH: - for(i = 0; i < bpp; i++) { - p = last[i]; - dst[i] = p + src[i]; - } - for(i = bpp; i < size; i++) { - int a, b, c, pa, pb, pc; - - a = dst[i - bpp]; - b = last[i]; - c = last[i - bpp]; - - p = b - c; - pc = a - c; - - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); - - if (pa <= pb && pa <= pc) - p = a; - else if (pb <= pc) - p = b; - else - p = c; - dst[i] = p + src[i]; - } - break; - } -} - -#ifdef CONFIG_ENCODERS -static void convert_from_rgb32(uint8_t *dst, const uint8_t *src, int width) -{ - uint8_t *d; - int j; - unsigned int v; - - d = dst; - for(j = 0; j < width; j++) { - v = ((const uint32_t *)src)[j]; - d[0] = v >> 16; - d[1] = v >> 8; - d[2] = v; - d[3] = v >> 24; - d += 4; - } -} -#endif - -#ifdef CONFIG_DECODERS -static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width) -{ - int j; - unsigned int r, g, b, a; - - for(j = 0;j < width; j++) { - r = src[0]; - g = src[1]; - b = src[2]; - a = src[3]; - *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b; - dst += 4; - src += 4; - } -} - -/* process exactly one decompressed row */ -static void png_handle_row(PNGContext *s) -{ - uint8_t *ptr, *last_row; - int got_line; - - if (!s->interlace_type) { - ptr = s->image_buf + s->image_linesize * s->y; - /* need to swap bytes correctly for RGB_ALPHA */ - if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, - s->last_row, s->row_size, s->bpp); - memcpy(s->last_row, s->tmp_row, s->row_size); - convert_to_rgb32(ptr, s->tmp_row, s->width); - } else { - /* in normal case, we avoid one copy */ - if (s->y == 0) - last_row = s->last_row; - else - last_row = ptr - s->image_linesize; - - png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1, - last_row, s->row_size, s->bpp); - } - s->y++; - if (s->y == s->height) { - s->state |= PNG_ALLIMAGE; - } - } else { - got_line = 0; - for(;;) { - ptr = s->image_buf + s->image_linesize * s->y; - if ((png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) { - /* if we already read one row, it is time to stop to - wait for the next one */ - if (got_line) - break; - png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, - s->last_row, s->pass_row_size, s->bpp); - memcpy(s->last_row, s->tmp_row, s->pass_row_size); - got_line = 1; - } - if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) { - /* NOTE: RGB32 is handled directly in png_put_interlaced_row */ - png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass, - s->color_type, s->last_row); - } - s->y++; - if (s->y == s->height) { - for(;;) { - if (s->pass == NB_PASSES - 1) { - s->state |= PNG_ALLIMAGE; - goto the_end; - } else { - s->pass++; - s->y = 0; - s->pass_row_size = png_pass_row_size(s->pass, - s->bits_per_pixel, - s->width); - s->crow_size = s->pass_row_size + 1; - if (s->pass_row_size != 0) - break; - /* skip pass if empty row */ - } - } - } - } - the_end: ; - } -} - -static int png_decode_idat(PNGContext *s, int length) -{ - int ret; - s->zstream.avail_in = length; - s->zstream.next_in = s->bytestream; - s->bytestream += length; - - if(s->bytestream > s->bytestream_end) - return -1; - - /* decode one line if possible */ - while (s->zstream.avail_in > 0) { - ret = inflate(&s->zstream, Z_PARTIAL_FLUSH); - if (ret != Z_OK && ret != Z_STREAM_END) { - return -1; - } - if (s->zstream.avail_out == 0) { - if (!(s->state & PNG_ALLIMAGE)) { - png_handle_row(s); - } - s->zstream.avail_out = s->crow_size; - s->zstream.next_out = s->crow_buf; - } - } - return 0; -} - -static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - PNGContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; - uint32_t tag, length; - int ret, crc; - - s->bytestream_start= - s->bytestream= buf; - s->bytestream_end= buf + buf_size; - - /* check signature */ - if (memcmp(s->bytestream, pngsig, 8) != 0) - return -1; - s->bytestream+= 8; - s->y= - s->state=0; -// memset(s, 0, sizeof(PNGContext)); - /* init the zlib */ - s->zstream.zalloc = png_zalloc; - s->zstream.zfree = png_zfree; - s->zstream.opaque = NULL; - ret = inflateInit(&s->zstream); - if (ret != Z_OK) - return -1; - for(;;) { - int tag32; - if (s->bytestream >= s->bytestream_end) - goto fail; - length = get32(&s->bytestream); - if (length > 0x7fffffff) - goto fail; - tag32 = get32(&s->bytestream); - tag = bswap_32(tag32); -#ifdef DEBUG - av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n", - (tag & 0xff), - ((tag >> 8) & 0xff), - ((tag >> 16) & 0xff), - ((tag >> 24) & 0xff), length); -#endif - switch(tag) { - case MKTAG('I', 'H', 'D', 'R'): - if (length != 13) - goto fail; - s->width = get32(&s->bytestream); - s->height = get32(&s->bytestream); - if(avcodec_check_dimensions(avctx, s->width, s->height)){ - s->width= s->height= 0; - goto fail; - } - s->bit_depth = *s->bytestream++; - s->color_type = *s->bytestream++; - s->compression_type = *s->bytestream++; - s->filter_type = *s->bytestream++; - s->interlace_type = *s->bytestream++; - crc = get32(&s->bytestream); - s->state |= PNG_IHDR; -#ifdef DEBUG - av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n", - s->width, s->height, s->bit_depth, s->color_type, - s->compression_type, s->filter_type, s->interlace_type); -#endif - break; - case MKTAG('I', 'D', 'A', 'T'): - if (!(s->state & PNG_IHDR)) - goto fail; - if (!(s->state & PNG_IDAT)) { - /* init image info */ - avctx->width = s->width; - avctx->height = s->height; - - s->channels = png_get_nb_channels(s->color_type); - s->bits_per_pixel = s->bit_depth * s->channels; - s->bpp = (s->bits_per_pixel + 7) >> 3; - s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3; - - if (s->bit_depth == 8 && - s->color_type == PNG_COLOR_TYPE_RGB) { - avctx->pix_fmt = PIX_FMT_RGB24; - } else if (s->bit_depth == 8 && - s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - avctx->pix_fmt = PIX_FMT_RGB32; - } else if (s->bit_depth == 8 && - s->color_type == PNG_COLOR_TYPE_GRAY) { - avctx->pix_fmt = PIX_FMT_GRAY8; - } else if (s->bit_depth == 16 && - s->color_type == PNG_COLOR_TYPE_GRAY) { - avctx->pix_fmt = PIX_FMT_GRAY16BE; - } else if (s->bit_depth == 1 && - s->color_type == PNG_COLOR_TYPE_GRAY) { - avctx->pix_fmt = PIX_FMT_MONOBLACK; - } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { - avctx->pix_fmt = PIX_FMT_PAL8; - } else { - goto fail; - } - 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"); - goto fail; - } - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - p->interlaced_frame = !!s->interlace_type; - - /* compute the compressed row size */ - if (!s->interlace_type) { - s->crow_size = s->row_size + 1; - } else { - s->pass = 0; - s->pass_row_size = png_pass_row_size(s->pass, - s->bits_per_pixel, - s->width); - s->crow_size = s->pass_row_size + 1; - } -#ifdef DEBUG - av_log(avctx, AV_LOG_DEBUG, "row_size=%d crow_size =%d\n", - s->row_size, s->crow_size); -#endif - s->image_buf = p->data[0]; - s->image_linesize = p->linesize[0]; - /* copy the palette if needed */ - if (s->color_type == PNG_COLOR_TYPE_PALETTE) - memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t)); - /* empty row is used if differencing to the first row */ - s->last_row = av_mallocz(s->row_size); - if (!s->last_row) - goto fail; - if (s->interlace_type || - s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - s->tmp_row = av_malloc(s->row_size); - if (!s->tmp_row) - goto fail; - } - /* compressed row */ - s->crow_buf = av_malloc(s->row_size + 1); - if (!s->crow_buf) - goto fail; - s->zstream.avail_out = s->crow_size; - s->zstream.next_out = s->crow_buf; - } - s->state |= PNG_IDAT; - if (png_decode_idat(s, length) < 0) - goto fail; - /* skip crc */ - crc = get32(&s->bytestream); - break; - case MKTAG('P', 'L', 'T', 'E'): - { - int n, i, r, g, b; - - if ((length % 3) != 0 || length > 256 * 3) - goto skip_tag; - /* read the palette */ - n = length / 3; - for(i=0;i<n;i++) { - r = *s->bytestream++; - g = *s->bytestream++; - b = *s->bytestream++; - s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b; - } - for(;i<256;i++) { - s->palette[i] = (0xff << 24); - } - s->state |= PNG_PLTE; - crc = get32(&s->bytestream); - } - break; - case MKTAG('t', 'R', 'N', 'S'): - { - int v, i; - - /* read the transparency. XXX: Only palette mode supported */ - if (s->color_type != PNG_COLOR_TYPE_PALETTE || - length > 256 || - !(s->state & PNG_PLTE)) - goto skip_tag; - for(i=0;i<length;i++) { - v = *s->bytestream++; - s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24); - } - crc = get32(&s->bytestream); - } - break; - case MKTAG('I', 'E', 'N', 'D'): - if (!(s->state & PNG_ALLIMAGE)) - goto fail; - crc = get32(&s->bytestream); - goto exit_loop; - default: - /* skip tag */ - skip_tag: - s->bytestream += length + 4; - break; - } - } - exit_loop: - *picture= *(AVFrame*)&s->picture; - *data_size = sizeof(AVPicture); - - ret = s->bytestream - s->bytestream_start; - the_end: - inflateEnd(&s->zstream); - av_freep(&s->crow_buf); - av_freep(&s->last_row); - av_freep(&s->tmp_row); - return ret; - fail: - ret = -1; - goto the_end; -} -#endif - -#ifdef CONFIG_ENCODERS -static void png_write_chunk(uint8_t **f, uint32_t tag, - const uint8_t *buf, int length) -{ - uint32_t crc; - uint8_t tagbuf[4]; - - put32(f, length); - crc = crc32(0, Z_NULL, 0); - tagbuf[0] = tag; - tagbuf[1] = tag >> 8; - tagbuf[2] = tag >> 16; - tagbuf[3] = tag >> 24; - crc = crc32(crc, tagbuf, 4); - put32(f, bswap_32(tag)); - if (length > 0) { - crc = crc32(crc, buf, length); - memcpy(*f, buf, length); - *f += length; - } - put32(f, crc); -} - -/* XXX: use avcodec generic function ? */ -static void to_be32(uint8_t *p, uint32_t v) -{ - p[0] = v >> 24; - p[1] = v >> 16; - p[2] = v >> 8; - p[3] = v; -} - -/* XXX: do filtering */ -static int png_write_row(PNGContext *s, const uint8_t *data, int size) -{ - int ret; - - s->zstream.avail_in = size; - s->zstream.next_in = (uint8_t *)data; - while (s->zstream.avail_in > 0) { - ret = deflate(&s->zstream, Z_NO_FLUSH); - if (ret != Z_OK) - return -1; - if (s->zstream.avail_out == 0) { - if(s->bytestream_end - s->bytestream > IOBUF_SIZE + 100) - png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, IOBUF_SIZE); - s->zstream.avail_out = IOBUF_SIZE; - s->zstream.next_out = s->buf; - } - } - return 0; -} -#endif /* CONFIG_ENCODERS */ - -static int common_init(AVCodecContext *avctx){ - PNGContext *s = avctx->priv_data; - - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; -// s->avctx= avctx; - - return 0; -} - -#ifdef CONFIG_ENCODERS -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ - PNGContext *s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&s->picture; - int bit_depth, color_type, y, len, row_size, ret, is_progressive; - int bits_per_pixel, pass_row_size; - uint8_t *ptr; - uint8_t *crow_buf = NULL; - uint8_t *tmp_buf = NULL; - - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - s->bytestream_start= - s->bytestream= buf; - s->bytestream_end= buf+buf_size; - - is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); - switch(avctx->pix_fmt) { - case PIX_FMT_RGB32: - bit_depth = 8; - color_type = PNG_COLOR_TYPE_RGB_ALPHA; - break; - case PIX_FMT_RGB24: - bit_depth = 8; - color_type = PNG_COLOR_TYPE_RGB; - break; - case PIX_FMT_GRAY8: - bit_depth = 8; - color_type = PNG_COLOR_TYPE_GRAY; - break; - case PIX_FMT_MONOBLACK: - bit_depth = 1; - color_type = PNG_COLOR_TYPE_GRAY; - break; - case PIX_FMT_PAL8: - bit_depth = 8; - color_type = PNG_COLOR_TYPE_PALETTE; - break; - default: - return -1; - } - bits_per_pixel = png_get_nb_channels(color_type) * bit_depth; - row_size = (avctx->width * bits_per_pixel + 7) >> 3; - - s->zstream.zalloc = png_zalloc; - s->zstream.zfree = png_zfree; - s->zstream.opaque = NULL; - ret = deflateInit2(&s->zstream, Z_DEFAULT_COMPRESSION, - Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY); - if (ret != Z_OK) - return -1; - crow_buf = av_malloc(row_size + 1); - if (!crow_buf) - goto fail; - if (is_progressive) { - tmp_buf = av_malloc(row_size + 1); - if (!tmp_buf) - goto fail; - } - - /* write png header */ - memcpy(s->bytestream, pngsig, 8); - s->bytestream += 8; - - to_be32(s->buf, avctx->width); - to_be32(s->buf + 4, avctx->height); - s->buf[8] = bit_depth; - s->buf[9] = color_type; - s->buf[10] = 0; /* compression type */ - s->buf[11] = 0; /* filter type */ - s->buf[12] = is_progressive; /* interlace type */ - - png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13); - - /* put the palette if needed */ - if (color_type == PNG_COLOR_TYPE_PALETTE) { - int has_alpha, alpha, i; - unsigned int v; - uint32_t *palette; - uint8_t *alpha_ptr; - - palette = (uint32_t *)p->data[1]; - ptr = s->buf; - alpha_ptr = s->buf + 256 * 3; - has_alpha = 0; - for(i = 0; i < 256; i++) { - v = palette[i]; - alpha = v >> 24; - if (alpha && alpha != 0xff) - has_alpha = 1; - *alpha_ptr++ = alpha; - ptr[0] = v >> 16; - ptr[1] = v >> 8; - ptr[2] = v; - ptr += 3; - } - png_write_chunk(&s->bytestream, MKTAG('P', 'L', 'T', 'E'), s->buf, 256 * 3); - if (has_alpha) { - png_write_chunk(&s->bytestream, MKTAG('t', 'R', 'N', 'S'), s->buf + 256 * 3, 256); - } - } - - /* now put each row */ - s->zstream.avail_out = IOBUF_SIZE; - s->zstream.next_out = s->buf; - if (is_progressive) { - uint8_t *ptr1; - int pass; - - for(pass = 0; pass < NB_PASSES; pass++) { - /* NOTE: a pass is completely omited if no pixels would be - output */ - pass_row_size = png_pass_row_size(pass, bits_per_pixel, avctx->width); - if (pass_row_size > 0) { - for(y = 0; y < avctx->height; y++) { - if ((png_pass_ymask[pass] << (y & 7)) & 0x80) { - ptr = p->data[0] + y * p->linesize[0]; - if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - convert_from_rgb32(tmp_buf, ptr, avctx->width); - ptr1 = tmp_buf; - } else { - ptr1 = ptr; - } - png_get_interlaced_row(crow_buf + 1, pass_row_size, - bits_per_pixel, pass, - ptr1, avctx->width); - crow_buf[0] = PNG_FILTER_VALUE_NONE; - png_write_row(s, crow_buf, pass_row_size + 1); - } - } - } - } - } else { - for(y = 0; y < avctx->height; y++) { - ptr = p->data[0] + y * p->linesize[0]; - if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) - convert_from_rgb32(crow_buf + 1, ptr, avctx->width); - else - memcpy(crow_buf + 1, ptr, row_size); - crow_buf[0] = PNG_FILTER_VALUE_NONE; - png_write_row(s, crow_buf, row_size + 1); - } - } - /* compress last bytes */ - for(;;) { - ret = deflate(&s->zstream, Z_FINISH); - if (ret == Z_OK || ret == Z_STREAM_END) { - len = IOBUF_SIZE - s->zstream.avail_out; - if (len > 0 && s->bytestream_end - s->bytestream > len + 100) { - png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, len); - } - s->zstream.avail_out = IOBUF_SIZE; - s->zstream.next_out = s->buf; - if (ret == Z_STREAM_END) - break; - } else { - goto fail; - } - } - png_write_chunk(&s->bytestream, MKTAG('I', 'E', 'N', 'D'), NULL, 0); - - ret = s->bytestream - s->bytestream_start; - the_end: - av_free(crow_buf); - av_free(tmp_buf); - deflateEnd(&s->zstream); - return ret; - fail: - ret = -1; - goto the_end; -} -#endif - -#ifdef CONFIG_PNG_DECODER -AVCodec png_decoder = { - "png", - CODEC_TYPE_VIDEO, - CODEC_ID_PNG, - sizeof(PNGContext), - common_init, - NULL, - NULL, //decode_end, - decode_frame, - 0 /*CODEC_CAP_DR1*/ /*| CODEC_CAP_DRAW_HORIZ_BAND*/, - NULL -}; -#endif - -#ifdef CONFIG_PNG_ENCODER -AVCodec png_encoder = { - "png", - CODEC_TYPE_VIDEO, - CODEC_ID_PNG, - sizeof(PNGContext), - common_init, - encode_frame, - NULL, //encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_MONOBLACK, -1}, -}; -#endif // CONFIG_PNG_ENCODER diff --git a/contrib/ffmpeg/libavcodec/png.h b/contrib/ffmpeg/libavcodec/png.h new file mode 100644 index 000000000..6e16f62e0 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/png.h @@ -0,0 +1,77 @@ +/* + * PNG image format + * Copyright (c) 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 + */ + +#ifndef FFMPEG_PNG_H +#define FFMPEG_PNG_H + +#include <stdint.h> + +#define PNG_COLOR_MASK_PALETTE 1 +#define PNG_COLOR_MASK_COLOR 2 +#define PNG_COLOR_MASK_ALPHA 4 + +#define PNG_COLOR_TYPE_GRAY 0 +#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) +#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) + +#define PNG_FILTER_TYPE_LOCO 64 +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_MIXED 5 + +#define PNG_IHDR 0x0001 +#define PNG_IDAT 0x0002 +#define PNG_ALLIMAGE 0x0004 +#define PNG_PLTE 0x0008 + +#define NB_PASSES 7 + +extern const uint8_t ff_pngsig[8]; +extern const uint8_t ff_mngsig[8]; + +/* Mask to determine which y pixels are valid in a pass */ +extern const uint8_t ff_png_pass_ymask[NB_PASSES]; + +/* minimum x value */ +extern const uint8_t ff_png_pass_xmin[NB_PASSES]; + +/* x shift to get row width */ +extern const uint8_t ff_png_pass_xshift[NB_PASSES]; + +/* Mask to determine which pixels are valid in a pass */ +extern const uint8_t ff_png_pass_mask[NB_PASSES]; + +extern void *ff_png_zalloc(void *opaque, unsigned int items, + unsigned int size); + +extern void ff_png_zfree(void *opaque, void *ptr); + +extern int ff_png_get_nb_channels(int color_type); + +/* compute the row size of an interleaved pass */ +extern int ff_png_pass_row_size(int pass, int bits_per_pixel, int width); + +#endif /* FFMPEG_PNG_H */ diff --git a/contrib/ffmpeg/libavcodec/pngdec.c b/contrib/ffmpeg/libavcodec/pngdec.c new file mode 100644 index 000000000..90dac4dfa --- /dev/null +++ b/contrib/ffmpeg/libavcodec/pngdec.c @@ -0,0 +1,621 @@ +/* + * PNG image format + * Copyright (c) 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 + */ +#include "avcodec.h" +#include "bytestream.h" +#include "png.h" +#include "dsputil.h" + +/* TODO: + * - add 2, 4 and 16 bit depth support + */ + +#include <zlib.h> + +//#define DEBUG + +typedef struct PNGDecContext { + DSPContext dsp; + + const uint8_t *bytestream; + const uint8_t *bytestream_start; + const uint8_t *bytestream_end; + AVFrame picture; + + int state; + int width, height; + int bit_depth; + int color_type; + int compression_type; + int interlace_type; + int filter_type; + int channels; + int bits_per_pixel; + int bpp; + + uint8_t *image_buf; + int image_linesize; + uint32_t palette[256]; + uint8_t *crow_buf; + uint8_t *last_row; + uint8_t *tmp_row; + int pass; + int crow_size; /* compressed row size (include filter type) */ + int row_size; /* decompressed row size */ + int pass_row_size; /* decompress row size of the current pass */ + int y; + z_stream zstream; +} PNGDecContext; + +/* Mask to determine which y pixels can be written in a pass */ +static const uint8_t png_pass_dsp_ymask[NB_PASSES] = { + 0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55, +}; + +/* Mask to determine which pixels to overwrite while displaying */ +static const uint8_t png_pass_dsp_mask[NB_PASSES] = { + 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff +}; + +/* NOTE: we try to construct a good looking image at each pass. width + is the original image width. We also do pixel format conversion at + this stage */ +static void png_put_interlaced_row(uint8_t *dst, int width, + int bits_per_pixel, int pass, + int color_type, const uint8_t *src) +{ + int x, mask, dsp_mask, j, src_x, b, bpp; + uint8_t *d; + const uint8_t *s; + + mask = ff_png_pass_mask[pass]; + dsp_mask = png_pass_dsp_mask[pass]; + switch(bits_per_pixel) { + case 1: + /* we must initialize the line to zero before writing to it */ + if (pass == 0) + memset(dst, 0, (width + 7) >> 3); + src_x = 0; + for(x = 0; x < width; x++) { + j = (x & 7); + if ((dsp_mask << j) & 0x80) { + b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1; + dst[x >> 3] |= b << (7 - j); + } + if ((mask << j) & 0x80) + src_x++; + } + break; + default: + bpp = bits_per_pixel >> 3; + d = dst; + s = src; + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + for(x = 0; x < width; x++) { + j = x & 7; + if ((dsp_mask << j) & 0x80) { + *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2]; + } + d += bpp; + if ((mask << j) & 0x80) + s += bpp; + } + } else { + for(x = 0; x < width; x++) { + j = x & 7; + if ((dsp_mask << j) & 0x80) { + memcpy(d, s, bpp); + } + d += bpp; + if ((mask << j) & 0x80) + s += bpp; + } + } + break; + } +} + +void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp) +{ + int i; + for(i = 0; i < w; i++) { + int a, b, c, p, pa, pb, pc; + + a = dst[i - bpp]; + b = top[i]; + c = top[i - bpp]; + + p = b - c; + pc = a - c; + + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); + + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; + dst[i] = p + src[i]; + } +} + +#define UNROLL1(bpp, op) {\ + r = dst[0];\ + if(bpp >= 2) g = dst[1];\ + if(bpp >= 3) b = dst[2];\ + if(bpp >= 4) a = dst[3];\ + for(; i < size; i+=bpp) {\ + dst[i+0] = r = op(r, src[i+0], last[i+0]);\ + if(bpp == 1) continue;\ + dst[i+1] = g = op(g, src[i+1], last[i+1]);\ + if(bpp == 2) continue;\ + dst[i+2] = b = op(b, src[i+2], last[i+2]);\ + if(bpp == 3) continue;\ + dst[i+3] = a = op(a, src[i+3], last[i+3]);\ + }\ +} + +#define UNROLL_FILTER(op)\ + if(bpp == 1) UNROLL1(1, op)\ + else if(bpp == 2) UNROLL1(2, op)\ + else if(bpp == 3) UNROLL1(3, op)\ + else if(bpp == 4) UNROLL1(4, op)\ + +/* NOTE: 'dst' can be equal to 'last' */ +static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type, + uint8_t *src, uint8_t *last, int size, int bpp) +{ + int i, p, r, g, b, a; + + switch(filter_type) { + case PNG_FILTER_VALUE_NONE: + memcpy(dst, src, size); + break; + case PNG_FILTER_VALUE_SUB: + for(i = 0; i < bpp; i++) { + dst[i] = src[i]; + } + if(bpp == 4) { + p = *(int*)dst; + for(; i < size; i+=bpp) { + int s = *(int*)(src+i); + p = ((s&0x7f7f7f7f) + (p&0x7f7f7f7f)) ^ ((s^p)&0x80808080); + *(int*)(dst+i) = p; + } + } else { +#define OP_SUB(x,s,l) x+s + UNROLL_FILTER(OP_SUB); + } + break; + case PNG_FILTER_VALUE_UP: + dsp->add_bytes_l2(dst, src, last, size); + break; + case PNG_FILTER_VALUE_AVG: + for(i = 0; i < bpp; i++) { + p = (last[i] >> 1); + dst[i] = p + src[i]; + } +#define OP_AVG(x,s,l) (((x + l) >> 1) + s) & 0xff + UNROLL_FILTER(OP_AVG); + break; + case PNG_FILTER_VALUE_PAETH: + for(i = 0; i < bpp; i++) { + p = last[i]; + dst[i] = p + src[i]; + } + if(bpp > 1 && size > 4) { + // would write off the end of the array if we let it process the last pixel with bpp=3 + int w = bpp==4 ? size : size-3; + dsp->add_png_paeth_prediction(dst+i, src+i, last+i, w-i, bpp); + i = w; + } + ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp); + break; + } +} + +static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *src, int width, int loco) +{ + int j; + unsigned int r, g, b, a; + + for(j = 0;j < width; j++) { + r = src[0]; + g = src[1]; + b = src[2]; + a = src[3]; + if(loco) { + r = (r+g)&0xff; + b = (b+g)&0xff; + } + *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b; + dst += 4; + src += 4; + } +} + +static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int loco) +{ + if(loco) + convert_to_rgb32_loco(dst, src, width, 1); + else + convert_to_rgb32_loco(dst, src, width, 0); +} + +static void deloco_rgb24(uint8_t *dst, int size) +{ + int i; + for(i=0; i<size; i+=3) { + int g = dst[i+1]; + dst[i+0] += g; + dst[i+2] += g; + } +} + +/* process exactly one decompressed row */ +static void png_handle_row(PNGDecContext *s) +{ + uint8_t *ptr, *last_row; + int got_line; + + if (!s->interlace_type) { + ptr = s->image_buf + s->image_linesize * s->y; + /* need to swap bytes correctly for RGB_ALPHA */ + if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1, + s->last_row, s->row_size, s->bpp); + convert_to_rgb32(ptr, s->tmp_row, s->width, s->filter_type == PNG_FILTER_TYPE_LOCO); + FFSWAP(uint8_t*, s->last_row, s->tmp_row); + } else { + /* in normal case, we avoid one copy */ + if (s->y == 0) + last_row = s->last_row; + else + last_row = ptr - s->image_linesize; + + png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1, + last_row, s->row_size, s->bpp); + } + /* loco lags by 1 row so that it doesn't interfere with top prediction */ + if (s->filter_type == PNG_FILTER_TYPE_LOCO && + s->color_type == PNG_COLOR_TYPE_RGB && s->y > 0) + deloco_rgb24(ptr - s->image_linesize, s->row_size); + s->y++; + if (s->y == s->height) { + s->state |= PNG_ALLIMAGE; + if (s->filter_type == PNG_FILTER_TYPE_LOCO && + s->color_type == PNG_COLOR_TYPE_RGB) + deloco_rgb24(ptr, s->row_size); + } + } else { + got_line = 0; + for(;;) { + ptr = s->image_buf + s->image_linesize * s->y; + if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) { + /* if we already read one row, it is time to stop to + wait for the next one */ + if (got_line) + break; + png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1, + s->last_row, s->pass_row_size, s->bpp); + FFSWAP(uint8_t*, s->last_row, s->tmp_row); + got_line = 1; + } + if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) { + /* NOTE: RGB32 is handled directly in png_put_interlaced_row */ + png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass, + s->color_type, s->last_row); + } + s->y++; + if (s->y == s->height) { + for(;;) { + if (s->pass == NB_PASSES - 1) { + s->state |= PNG_ALLIMAGE; + goto the_end; + } else { + s->pass++; + s->y = 0; + s->pass_row_size = ff_png_pass_row_size(s->pass, + s->bits_per_pixel, + s->width); + s->crow_size = s->pass_row_size + 1; + if (s->pass_row_size != 0) + break; + /* skip pass if empty row */ + } + } + } + } + the_end: ; + } +} + +static int png_decode_idat(PNGDecContext *s, int length) +{ + int ret; + s->zstream.avail_in = length; + s->zstream.next_in = s->bytestream; + s->bytestream += length; + + if(s->bytestream > s->bytestream_end) + return -1; + + /* decode one line if possible */ + while (s->zstream.avail_in > 0) { + ret = inflate(&s->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) { + return -1; + } + if (s->zstream.avail_out == 0) { + if (!(s->state & PNG_ALLIMAGE)) { + png_handle_row(s); + } + s->zstream.avail_out = s->crow_size; + s->zstream.next_out = s->crow_buf; + } + } + return 0; +} + +static int decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + PNGDecContext * const s = avctx->priv_data; + AVFrame *picture = data; + AVFrame * const p= (AVFrame*)&s->picture; + uint32_t tag, length; + int ret, crc; + + s->bytestream_start= + s->bytestream= buf; + s->bytestream_end= buf + buf_size; + + /* check signature */ + if (memcmp(s->bytestream, ff_pngsig, 8) != 0 && + memcmp(s->bytestream, ff_mngsig, 8) != 0) + return -1; + s->bytestream+= 8; + s->y= + s->state=0; +// memset(s, 0, sizeof(PNGDecContext)); + /* init the zlib */ + s->zstream.zalloc = ff_png_zalloc; + s->zstream.zfree = ff_png_zfree; + s->zstream.opaque = NULL; + ret = inflateInit(&s->zstream); + if (ret != Z_OK) + return -1; + for(;;) { + int tag32; + if (s->bytestream >= s->bytestream_end) + goto fail; + length = bytestream_get_be32(&s->bytestream); + if (length > 0x7fffffff) + goto fail; + tag32 = bytestream_get_be32(&s->bytestream); + tag = bswap_32(tag32); +#ifdef DEBUG + av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n", + (tag & 0xff), + ((tag >> 8) & 0xff), + ((tag >> 16) & 0xff), + ((tag >> 24) & 0xff), length); +#endif + switch(tag) { + case MKTAG('I', 'H', 'D', 'R'): + if (length != 13) + goto fail; + s->width = bytestream_get_be32(&s->bytestream); + s->height = bytestream_get_be32(&s->bytestream); + if(avcodec_check_dimensions(avctx, s->width, s->height)){ + s->width= s->height= 0; + goto fail; + } + s->bit_depth = *s->bytestream++; + s->color_type = *s->bytestream++; + s->compression_type = *s->bytestream++; + s->filter_type = *s->bytestream++; + s->interlace_type = *s->bytestream++; + crc = bytestream_get_be32(&s->bytestream); + s->state |= PNG_IHDR; +#ifdef DEBUG + av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n", + s->width, s->height, s->bit_depth, s->color_type, + s->compression_type, s->filter_type, s->interlace_type); +#endif + break; + case MKTAG('I', 'D', 'A', 'T'): + if (!(s->state & PNG_IHDR)) + goto fail; + if (!(s->state & PNG_IDAT)) { + /* init image info */ + avctx->width = s->width; + avctx->height = s->height; + + s->channels = ff_png_get_nb_channels(s->color_type); + s->bits_per_pixel = s->bit_depth * s->channels; + s->bpp = (s->bits_per_pixel + 7) >> 3; + s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3; + + if (s->bit_depth == 8 && + s->color_type == PNG_COLOR_TYPE_RGB) { + avctx->pix_fmt = PIX_FMT_RGB24; + } else if (s->bit_depth == 8 && + s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + avctx->pix_fmt = PIX_FMT_RGB32; + } else if (s->bit_depth == 8 && + s->color_type == PNG_COLOR_TYPE_GRAY) { + avctx->pix_fmt = PIX_FMT_GRAY8; + } else if (s->bit_depth == 16 && + s->color_type == PNG_COLOR_TYPE_GRAY) { + avctx->pix_fmt = PIX_FMT_GRAY16BE; + } else if (s->bit_depth == 1 && + s->color_type == PNG_COLOR_TYPE_GRAY) { + avctx->pix_fmt = PIX_FMT_MONOBLACK; + } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { + avctx->pix_fmt = PIX_FMT_PAL8; + } else { + goto fail; + } + 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"); + goto fail; + } + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + p->interlaced_frame = !!s->interlace_type; + + /* compute the compressed row size */ + if (!s->interlace_type) { + s->crow_size = s->row_size + 1; + } else { + s->pass = 0; + s->pass_row_size = ff_png_pass_row_size(s->pass, + s->bits_per_pixel, + s->width); + s->crow_size = s->pass_row_size + 1; + } +#ifdef DEBUG + av_log(avctx, AV_LOG_DEBUG, "row_size=%d crow_size =%d\n", + s->row_size, s->crow_size); +#endif + s->image_buf = p->data[0]; + s->image_linesize = p->linesize[0]; + /* copy the palette if needed */ + if (s->color_type == PNG_COLOR_TYPE_PALETTE) + memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t)); + /* empty row is used if differencing to the first row */ + s->last_row = av_mallocz(s->row_size); + if (!s->last_row) + goto fail; + if (s->interlace_type || + s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + s->tmp_row = av_malloc(s->row_size); + if (!s->tmp_row) + goto fail; + } + /* compressed row */ + s->crow_buf = av_malloc(s->row_size + 1); + if (!s->crow_buf) + goto fail; + s->zstream.avail_out = s->crow_size; + s->zstream.next_out = s->crow_buf; + } + s->state |= PNG_IDAT; + if (png_decode_idat(s, length) < 0) + goto fail; + /* skip crc */ + crc = bytestream_get_be32(&s->bytestream); + break; + case MKTAG('P', 'L', 'T', 'E'): + { + int n, i, r, g, b; + + if ((length % 3) != 0 || length > 256 * 3) + goto skip_tag; + /* read the palette */ + n = length / 3; + for(i=0;i<n;i++) { + r = *s->bytestream++; + g = *s->bytestream++; + b = *s->bytestream++; + s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b; + } + for(;i<256;i++) { + s->palette[i] = (0xff << 24); + } + s->state |= PNG_PLTE; + crc = bytestream_get_be32(&s->bytestream); + } + break; + case MKTAG('t', 'R', 'N', 'S'): + { + int v, i; + + /* read the transparency. XXX: Only palette mode supported */ + if (s->color_type != PNG_COLOR_TYPE_PALETTE || + length > 256 || + !(s->state & PNG_PLTE)) + goto skip_tag; + for(i=0;i<length;i++) { + v = *s->bytestream++; + s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24); + } + crc = bytestream_get_be32(&s->bytestream); + } + break; + case MKTAG('I', 'E', 'N', 'D'): + if (!(s->state & PNG_ALLIMAGE)) + goto fail; + crc = bytestream_get_be32(&s->bytestream); + goto exit_loop; + default: + /* skip tag */ + skip_tag: + s->bytestream += length + 4; + break; + } + } + exit_loop: + *picture= *(AVFrame*)&s->picture; + *data_size = sizeof(AVPicture); + + ret = s->bytestream - s->bytestream_start; + the_end: + inflateEnd(&s->zstream); + av_freep(&s->crow_buf); + av_freep(&s->last_row); + av_freep(&s->tmp_row); + return ret; + fail: + ret = -1; + goto the_end; +} + +static int png_dec_init(AVCodecContext *avctx){ + PNGDecContext *s = avctx->priv_data; + + avcodec_get_frame_defaults((AVFrame*)&s->picture); + avctx->coded_frame= (AVFrame*)&s->picture; + dsputil_init(&s->dsp, avctx); + + return 0; +} + +AVCodec png_decoder = { + "png", + CODEC_TYPE_VIDEO, + CODEC_ID_PNG, + sizeof(PNGDecContext), + png_dec_init, + NULL, + NULL, //decode_end, + decode_frame, + 0 /*CODEC_CAP_DR1*/ /*| CODEC_CAP_DRAW_HORIZ_BAND*/, + NULL +}; diff --git a/contrib/ffmpeg/libavcodec/pngenc.c b/contrib/ffmpeg/libavcodec/pngenc.c new file mode 100644 index 000000000..703371d85 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/pngenc.c @@ -0,0 +1,448 @@ +/* + * PNG image format + * Copyright (c) 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 + */ +#include "avcodec.h" +#include "bytestream.h" +#include "png.h" +#include <dsputil.h> + +/* TODO: + * - add 2, 4 and 16 bit depth support + */ + +#include <zlib.h> + +//#define DEBUG + +#define IOBUF_SIZE 4096 + +typedef struct PNGEncContext { + DSPContext dsp; + + uint8_t *bytestream; + uint8_t *bytestream_start; + uint8_t *bytestream_end; + AVFrame picture; + + int filter_type; + + z_stream zstream; + uint8_t buf[IOBUF_SIZE]; +} PNGEncContext; + +static void png_get_interlaced_row(uint8_t *dst, int row_size, + int bits_per_pixel, int pass, + const uint8_t *src, int width) +{ + int x, mask, dst_x, j, b, bpp; + uint8_t *d; + const uint8_t *s; + + mask = ff_png_pass_mask[pass]; + switch(bits_per_pixel) { + case 1: + memset(dst, 0, row_size); + dst_x = 0; + for(x = 0; x < width; x++) { + j = (x & 7); + if ((mask << j) & 0x80) { + b = (src[x >> 3] >> (7 - j)) & 1; + dst[dst_x >> 3] |= b << (7 - (dst_x & 7)); + dst_x++; + } + } + break; + default: + bpp = bits_per_pixel >> 3; + d = dst; + s = src; + for(x = 0; x < width; x++) { + j = x & 7; + if ((mask << j) & 0x80) { + memcpy(d, s, bpp); + d += bpp; + } + s += bpp; + } + break; + } +} + +static void sub_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp) +{ + int i; + for(i = 0; i < w; i++) { + int a, b, c, p, pa, pb, pc; + + a = src[i - bpp]; + b = top[i]; + c = top[i - bpp]; + + p = b - c; + pc = a - c; + + pa = abs(p); + pb = abs(pc); + pc = abs(p + pc); + + if (pa <= pb && pa <= pc) + p = a; + else if (pb <= pc) + p = b; + else + p = c; + dst[i] = src[i] - p; + } +} + +static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type, + uint8_t *src, uint8_t *top, int size, int bpp) +{ + int i; + + switch(filter_type) { + case PNG_FILTER_VALUE_NONE: + memcpy(dst, src, size); + break; + case PNG_FILTER_VALUE_SUB: + dsp->diff_bytes(dst, src, src-bpp, size); + memcpy(dst, src, bpp); + break; + case PNG_FILTER_VALUE_UP: + dsp->diff_bytes(dst, src, top, size); + break; + case PNG_FILTER_VALUE_AVG: + for(i = 0; i < bpp; i++) + dst[i] = src[i] - (top[i] >> 1); + for(; i < size; i++) + dst[i] = src[i] - ((src[i-bpp] + top[i]) >> 1); + break; + case PNG_FILTER_VALUE_PAETH: + for(i = 0; i < bpp; i++) + dst[i] = src[i] - top[i]; + sub_png_paeth_prediction(dst+i, src+i, top+i, size-i, bpp); + break; + } +} + +static uint8_t *png_choose_filter(PNGEncContext *s, uint8_t *dst, + uint8_t *src, uint8_t *top, int size, int bpp) +{ + int pred = s->filter_type; + assert(bpp || !pred); + if(!top && pred) + pred = PNG_FILTER_VALUE_SUB; + if(pred == PNG_FILTER_VALUE_MIXED) { + int i; + int cost, bcost = INT_MAX; + uint8_t *buf1 = dst, *buf2 = dst + size + 16; + for(pred=0; pred<5; pred++) { + png_filter_row(&s->dsp, buf1+1, pred, src, top, size, bpp); + buf1[0] = pred; + cost = 0; + for(i=0; i<=size; i++) + cost += abs((int8_t)buf1[i]); + if(cost < bcost) { + bcost = cost; + FFSWAP(uint8_t*, buf1, buf2); + } + } + return buf2; + } else { + png_filter_row(&s->dsp, dst+1, pred, src, top, size, bpp); + dst[0] = pred; + return dst; + } +} + +static void convert_from_rgb32(uint8_t *dst, const uint8_t *src, int width) +{ + uint8_t *d; + int j; + unsigned int v; + + d = dst; + for(j = 0; j < width; j++) { + v = ((const uint32_t *)src)[j]; + d[0] = v >> 16; + d[1] = v >> 8; + d[2] = v; + d[3] = v >> 24; + d += 4; + } +} + +static void png_write_chunk(uint8_t **f, uint32_t tag, + const uint8_t *buf, int length) +{ + uint32_t crc; + uint8_t tagbuf[4]; + + bytestream_put_be32(f, length); + crc = crc32(0, Z_NULL, 0); + AV_WL32(tagbuf, tag); + crc = crc32(crc, tagbuf, 4); + bytestream_put_be32(f, bswap_32(tag)); + if (length > 0) { + crc = crc32(crc, buf, length); + memcpy(*f, buf, length); + *f += length; + } + bytestream_put_be32(f, crc); +} + +/* XXX: do filtering */ +static int png_write_row(PNGEncContext *s, const uint8_t *data, int size) +{ + int ret; + + s->zstream.avail_in = size; + s->zstream.next_in = (uint8_t *)data; + while (s->zstream.avail_in > 0) { + ret = deflate(&s->zstream, Z_NO_FLUSH); + if (ret != Z_OK) + return -1; + if (s->zstream.avail_out == 0) { + if(s->bytestream_end - s->bytestream > IOBUF_SIZE + 100) + png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, IOBUF_SIZE); + s->zstream.avail_out = IOBUF_SIZE; + s->zstream.next_out = s->buf; + } + } + return 0; +} + +static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + PNGEncContext *s = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p= (AVFrame*)&s->picture; + int bit_depth, color_type, y, len, row_size, ret, is_progressive; + int bits_per_pixel, pass_row_size; + int compression_level; + uint8_t *ptr, *top; + uint8_t *crow_base = NULL, *crow_buf, *crow; + uint8_t *progressive_buf = NULL; + uint8_t *rgba_buf = NULL; + uint8_t *top_buf = NULL; + + *p = *pict; + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + + s->bytestream_start= + s->bytestream= buf; + s->bytestream_end= buf+buf_size; + + is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); + switch(avctx->pix_fmt) { + case PIX_FMT_RGB32: + bit_depth = 8; + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + break; + case PIX_FMT_RGB24: + bit_depth = 8; + color_type = PNG_COLOR_TYPE_RGB; + break; + case PIX_FMT_GRAY8: + bit_depth = 8; + color_type = PNG_COLOR_TYPE_GRAY; + break; + case PIX_FMT_MONOBLACK: + bit_depth = 1; + color_type = PNG_COLOR_TYPE_GRAY; + break; + case PIX_FMT_PAL8: + bit_depth = 8; + color_type = PNG_COLOR_TYPE_PALETTE; + break; + default: + return -1; + } + bits_per_pixel = ff_png_get_nb_channels(color_type) * bit_depth; + row_size = (avctx->width * bits_per_pixel + 7) >> 3; + + s->zstream.zalloc = ff_png_zalloc; + s->zstream.zfree = ff_png_zfree; + s->zstream.opaque = NULL; + compression_level = avctx->compression_level == FF_COMPRESSION_DEFAULT ? + Z_DEFAULT_COMPRESSION : + av_clip(avctx->compression_level, 0, 9); + ret = deflateInit2(&s->zstream, compression_level, + Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY); + if (ret != Z_OK) + return -1; + crow_base = av_malloc((row_size + 32) << (s->filter_type == PNG_FILTER_VALUE_MIXED)); + if (!crow_base) + goto fail; + crow_buf = crow_base + 15; // pixel data should be aligned, but there's a control byte before it + if (is_progressive) { + progressive_buf = av_malloc(row_size + 1); + if (!progressive_buf) + goto fail; + } + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + rgba_buf = av_malloc(row_size + 1); + if (!rgba_buf) + goto fail; + } + if (is_progressive || color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + top_buf = av_malloc(row_size + 1); + if (!top_buf) + goto fail; + } + + /* write png header */ + memcpy(s->bytestream, ff_pngsig, 8); + s->bytestream += 8; + + AV_WB32(s->buf, avctx->width); + AV_WB32(s->buf + 4, avctx->height); + s->buf[8] = bit_depth; + s->buf[9] = color_type; + s->buf[10] = 0; /* compression type */ + s->buf[11] = 0; /* filter type */ + s->buf[12] = is_progressive; /* interlace type */ + + png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13); + + /* put the palette if needed */ + if (color_type == PNG_COLOR_TYPE_PALETTE) { + int has_alpha, alpha, i; + unsigned int v; + uint32_t *palette; + uint8_t *alpha_ptr; + + palette = (uint32_t *)p->data[1]; + ptr = s->buf; + alpha_ptr = s->buf + 256 * 3; + has_alpha = 0; + for(i = 0; i < 256; i++) { + v = palette[i]; + alpha = v >> 24; + if (alpha && alpha != 0xff) + has_alpha = 1; + *alpha_ptr++ = alpha; + bytestream_put_be24(&ptr, v); + } + png_write_chunk(&s->bytestream, MKTAG('P', 'L', 'T', 'E'), s->buf, 256 * 3); + if (has_alpha) { + png_write_chunk(&s->bytestream, MKTAG('t', 'R', 'N', 'S'), s->buf + 256 * 3, 256); + } + } + + /* now put each row */ + s->zstream.avail_out = IOBUF_SIZE; + s->zstream.next_out = s->buf; + if (is_progressive) { + int pass; + + for(pass = 0; pass < NB_PASSES; pass++) { + /* NOTE: a pass is completely omited if no pixels would be + output */ + pass_row_size = ff_png_pass_row_size(pass, bits_per_pixel, avctx->width); + if (pass_row_size > 0) { + top = NULL; + for(y = 0; y < avctx->height; y++) { + if ((ff_png_pass_ymask[pass] << (y & 7)) & 0x80) { + ptr = p->data[0] + y * p->linesize[0]; + FFSWAP(uint8_t*, progressive_buf, top_buf); + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + convert_from_rgb32(rgba_buf, ptr, avctx->width); + ptr = rgba_buf; + } + png_get_interlaced_row(progressive_buf, pass_row_size, + bits_per_pixel, pass, + ptr, avctx->width); + crow = png_choose_filter(s, crow_buf, progressive_buf, top, pass_row_size, bits_per_pixel>>3); + png_write_row(s, crow, pass_row_size + 1); + top = progressive_buf; + } + } + } + } + } else { + top = NULL; + for(y = 0; y < avctx->height; y++) { + ptr = p->data[0] + y * p->linesize[0]; + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + FFSWAP(uint8_t*, rgba_buf, top_buf); + convert_from_rgb32(rgba_buf, ptr, avctx->width); + ptr = rgba_buf; + } + crow = png_choose_filter(s, crow_buf, ptr, top, row_size, bits_per_pixel>>3); + png_write_row(s, crow, row_size + 1); + top = ptr; + } + } + /* compress last bytes */ + for(;;) { + ret = deflate(&s->zstream, Z_FINISH); + if (ret == Z_OK || ret == Z_STREAM_END) { + len = IOBUF_SIZE - s->zstream.avail_out; + if (len > 0 && s->bytestream_end - s->bytestream > len + 100) { + png_write_chunk(&s->bytestream, MKTAG('I', 'D', 'A', 'T'), s->buf, len); + } + s->zstream.avail_out = IOBUF_SIZE; + s->zstream.next_out = s->buf; + if (ret == Z_STREAM_END) + break; + } else { + goto fail; + } + } + png_write_chunk(&s->bytestream, MKTAG('I', 'E', 'N', 'D'), NULL, 0); + + ret = s->bytestream - s->bytestream_start; + the_end: + av_free(crow_base); + av_free(progressive_buf); + av_free(rgba_buf); + av_free(top_buf); + deflateEnd(&s->zstream); + return ret; + fail: + ret = -1; + goto the_end; +} + +static int png_enc_init(AVCodecContext *avctx){ + PNGEncContext *s = avctx->priv_data; + + avcodec_get_frame_defaults((AVFrame*)&s->picture); + avctx->coded_frame= (AVFrame*)&s->picture; + dsputil_init(&s->dsp, avctx); + + s->filter_type = av_clip(avctx->prediction_method, PNG_FILTER_VALUE_NONE, PNG_FILTER_VALUE_MIXED); + if(avctx->pix_fmt == PIX_FMT_MONOBLACK) + s->filter_type = PNG_FILTER_VALUE_NONE; + + return 0; +} + +AVCodec png_encoder = { + "png", + CODEC_TYPE_VIDEO, + CODEC_ID_PNG, + sizeof(PNGEncContext), + png_enc_init, + encode_frame, + NULL, //encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_MONOBLACK, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/pnm.c b/contrib/ffmpeg/libavcodec/pnm.c index 4c9c46fee..1f28aced6 100644 --- a/contrib/ffmpeg/libavcodec/pnm.c +++ b/contrib/ffmpeg/libavcodec/pnm.c @@ -19,14 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" -#include "parser.h" //for ParseContext - -typedef struct PNMContext { - uint8_t *bytestream; - uint8_t *bytestream_start; - uint8_t *bytestream_end; - AVFrame picture; -} PNMContext; +#include "pnm.h" static inline int pnm_space(int c) { @@ -59,16 +52,7 @@ static void pnm_get(PNMContext *sc, char *str, int buf_size) *s = '\0'; } -static int common_init(AVCodecContext *avctx){ - PNMContext *s = avctx->priv_data; - - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; - - return 0; -} - -static int pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){ +int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){ char buf1[32], tuple_type[32]; int h, w, depth, maxval; @@ -142,8 +126,12 @@ static int pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){ return -1; if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { pnm_get(s, buf1, sizeof(buf1)); - if(atoi(buf1) == 65535 && avctx->pix_fmt == PIX_FMT_GRAY8) + s->maxval = atoi(buf1); + if(s->maxval >= 256 && avctx->pix_fmt == PIX_FMT_GRAY8) { avctx->pix_fmt = PIX_FMT_GRAY16BE; + if (s->maxval != 65535) + avctx->pix_fmt = PIX_FMT_GRAY16; + } } /* more check if YUV420 */ if (avctx->pix_fmt == PIX_FMT_YUV420P) { @@ -157,450 +145,3 @@ static int pnm_decode_header(AVCodecContext *avctx, PNMContext * const s){ } return 0; } - -static int pnm_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - PNMContext * const s = avctx->priv_data; - AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; - int i, n, linesize, h; - unsigned char *ptr; - - s->bytestream_start= - s->bytestream= buf; - s->bytestream_end= buf + buf_size; - - if(pnm_decode_header(avctx, s) < 0) - return -1; - - 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= FF_I_TYPE; - p->key_frame= 1; - - switch(avctx->pix_fmt) { - default: - return -1; - case PIX_FMT_RGB24: - n = avctx->width * 3; - goto do_read; - case PIX_FMT_GRAY8: - n = avctx->width; - goto do_read; - case PIX_FMT_GRAY16BE: - n = avctx->width * 2; - goto do_read; - case PIX_FMT_MONOWHITE: - case PIX_FMT_MONOBLACK: - n = (avctx->width + 7) >> 3; - do_read: - ptr = p->data[0]; - linesize = p->linesize[0]; - if(s->bytestream + n*avctx->height > s->bytestream_end) - return -1; - for(i = 0; i < avctx->height; i++) { - memcpy(ptr, s->bytestream, n); - s->bytestream += n; - ptr += linesize; - } - break; - case PIX_FMT_YUV420P: - { - unsigned char *ptr1, *ptr2; - - n = avctx->width; - ptr = p->data[0]; - linesize = p->linesize[0]; - if(s->bytestream + n*avctx->height*3/2 > s->bytestream_end) - return -1; - for(i = 0; i < avctx->height; i++) { - memcpy(ptr, s->bytestream, n); - s->bytestream += n; - ptr += linesize; - } - ptr1 = p->data[1]; - ptr2 = p->data[2]; - n >>= 1; - h = avctx->height >> 1; - for(i = 0; i < h; i++) { - memcpy(ptr1, s->bytestream, n); - s->bytestream += n; - memcpy(ptr2, s->bytestream, n); - s->bytestream += n; - ptr1 += p->linesize[1]; - ptr2 += p->linesize[2]; - } - } - break; - case PIX_FMT_RGB32: - ptr = p->data[0]; - linesize = p->linesize[0]; - if(s->bytestream + avctx->width*avctx->height*4 > s->bytestream_end) - return -1; - for(i = 0; i < avctx->height; i++) { - int j, r, g, b, a; - - for(j = 0;j < avctx->width; j++) { - r = *s->bytestream++; - g = *s->bytestream++; - b = *s->bytestream++; - a = *s->bytestream++; - ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b; - } - ptr += linesize; - } - break; - } - *picture= *(AVFrame*)&s->picture; - *data_size = sizeof(AVPicture); - - return s->bytestream - s->bytestream_start; -} - -static int pnm_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data){ - PNMContext *s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&s->picture; - int i, h, h1, c, n, linesize; - uint8_t *ptr, *ptr1, *ptr2; - - if(buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200){ - av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - s->bytestream_start= - s->bytestream= outbuf; - s->bytestream_end= outbuf+buf_size; - - h = avctx->height; - h1 = h; - switch(avctx->pix_fmt) { - case PIX_FMT_MONOWHITE: - c = '4'; - n = (avctx->width + 7) >> 3; - break; - case PIX_FMT_GRAY8: - c = '5'; - n = avctx->width; - break; - case PIX_FMT_GRAY16BE: - c = '5'; - n = avctx->width * 2; - break; - case PIX_FMT_RGB24: - c = '6'; - n = avctx->width * 3; - break; - case PIX_FMT_YUV420P: - c = '5'; - n = avctx->width; - h1 = (h * 3) / 2; - break; - default: - return -1; - } - snprintf(s->bytestream, s->bytestream_end - s->bytestream, - "P%c\n%d %d\n", - c, avctx->width, h1); - s->bytestream += strlen(s->bytestream); - if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { - snprintf(s->bytestream, s->bytestream_end - s->bytestream, - "%d\n", (avctx->pix_fmt != PIX_FMT_GRAY16BE) ? 255 : 65535); - s->bytestream += strlen(s->bytestream); - } - - ptr = p->data[0]; - linesize = p->linesize[0]; - for(i=0;i<h;i++) { - memcpy(s->bytestream, ptr, n); - s->bytestream += n; - ptr += linesize; - } - - if (avctx->pix_fmt == PIX_FMT_YUV420P) { - h >>= 1; - n >>= 1; - ptr1 = p->data[1]; - ptr2 = p->data[2]; - for(i=0;i<h;i++) { - memcpy(s->bytestream, ptr1, n); - s->bytestream += n; - memcpy(s->bytestream, ptr2, n); - s->bytestream += n; - ptr1 += p->linesize[1]; - ptr2 += p->linesize[2]; - } - } - return s->bytestream - s->bytestream_start; -} - -static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data){ - PNMContext *s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&s->picture; - int i, h, w, n, linesize, depth, maxval; - const char *tuple_type; - uint8_t *ptr; - - if(buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200){ - av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - *p = *pict; - p->pict_type= FF_I_TYPE; - p->key_frame= 1; - - s->bytestream_start= - s->bytestream= outbuf; - s->bytestream_end= outbuf+buf_size; - - h = avctx->height; - w = avctx->width; - switch(avctx->pix_fmt) { - case PIX_FMT_MONOWHITE: - n = (w + 7) >> 3; - depth = 1; - maxval = 1; - tuple_type = "BLACKANDWHITE"; - break; - case PIX_FMT_GRAY8: - n = w; - depth = 1; - maxval = 255; - tuple_type = "GRAYSCALE"; - break; - case PIX_FMT_RGB24: - n = w * 3; - depth = 3; - maxval = 255; - tuple_type = "RGB"; - break; - case PIX_FMT_RGB32: - n = w * 4; - depth = 4; - maxval = 255; - tuple_type = "RGB_ALPHA"; - break; - default: - return -1; - } - snprintf(s->bytestream, s->bytestream_end - s->bytestream, - "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLETYPE %s\nENDHDR\n", - w, h, depth, maxval, tuple_type); - s->bytestream += strlen(s->bytestream); - - ptr = p->data[0]; - linesize = p->linesize[0]; - - if (avctx->pix_fmt == PIX_FMT_RGB32) { - int j; - unsigned int v; - - for(i=0;i<h;i++) { - for(j=0;j<w;j++) { - v = ((uint32_t *)ptr)[j]; - *s->bytestream++ = v >> 16; - *s->bytestream++ = v >> 8; - *s->bytestream++ = v; - *s->bytestream++ = v >> 24; - } - ptr += linesize; - } - } else { - for(i=0;i<h;i++) { - memcpy(s->bytestream, ptr, n); - s->bytestream += n; - ptr += linesize; - } - } - return s->bytestream - s->bytestream_start; -} - -#if 0 -static int pnm_probe(AVProbeData *pd) -{ - const char *p = pd->buf; - if (pd->buf_size >= 8 && - p[0] == 'P' && - p[1] >= '4' && p[1] <= '6' && - pnm_space(p[2]) ) - return AVPROBE_SCORE_MAX - 1; /* to permit pgmyuv probe */ - else - return 0; -} - -static int pgmyuv_probe(AVProbeData *pd) -{ - if (match_ext(pd->filename, "pgmyuv")) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int pam_probe(AVProbeData *pd) -{ - const char *p = pd->buf; - if (pd->buf_size >= 8 && - p[0] == 'P' && - p[1] == '7' && - p[2] == '\n') - return AVPROBE_SCORE_MAX; - else - return 0; -} -#endif - -#ifdef CONFIG_PNM_PARSER -static int pnm_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - PNMContext pnmctx; - int next; - - for(; pc->overread>0; pc->overread--){ - pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; - } -retry: - if(pc->index){ - pnmctx.bytestream_start= - pnmctx.bytestream= pc->buffer; - pnmctx.bytestream_end= pc->buffer + pc->index; - }else{ - pnmctx.bytestream_start= - pnmctx.bytestream= (uint8_t *) buf; /* casts avoid warnings */ - pnmctx.bytestream_end= (uint8_t *) buf + buf_size; - } - if(pnm_decode_header(avctx, &pnmctx) < 0){ - if(pnmctx.bytestream < pnmctx.bytestream_end){ - if(pc->index){ - pc->index=0; - }else{ - buf++; - buf_size--; - } - goto retry; - } -#if 0 - if(pc->index && pc->index*2 + FF_INPUT_BUFFER_PADDING_SIZE < pc->buffer_size && buf_size > pc->index){ - memcpy(pc->buffer + pc->index, buf, pc->index); - pc->index += pc->index; - buf += pc->index; - buf_size -= pc->index; - goto retry; - } -#endif - next= END_NOT_FOUND; - }else{ - next= pnmctx.bytestream - pnmctx.bytestream_start - + avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); - if(pnmctx.bytestream_start!=buf) - next-= pc->index; - if(next > buf_size) - next= END_NOT_FOUND; - } - - if(ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size)<0){ - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - *poutbuf = (uint8_t *)buf; - *poutbuf_size = buf_size; - return next; -} - -AVCodecParser pnm_parser = { - { CODEC_ID_PGM, CODEC_ID_PGMYUV, CODEC_ID_PPM, CODEC_ID_PBM, CODEC_ID_PAM}, - sizeof(ParseContext), - NULL, - pnm_parse, - ff_parse_close, -}; -#endif /* CONFIG_PNM_PARSER */ - -#ifdef CONFIG_PGM_ENCODER -AVCodec pgm_encoder = { - "pgm", - CODEC_TYPE_VIDEO, - CODEC_ID_PGM, - sizeof(PNMContext), - common_init, - pnm_encode_frame, - NULL, //encode_end, - pnm_decode_frame, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_GRAY8, PIX_FMT_GRAY16BE, -1}, -}; -#endif // CONFIG_PGM_ENCODER - -#ifdef CONFIG_PGMYUV_ENCODER -AVCodec pgmyuv_encoder = { - "pgmyuv", - CODEC_TYPE_VIDEO, - CODEC_ID_PGMYUV, - sizeof(PNMContext), - common_init, - pnm_encode_frame, - NULL, //encode_end, - pnm_decode_frame, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; -#endif // CONFIG_PGMYUV_ENCODER - -#ifdef CONFIG_PPM_ENCODER -AVCodec ppm_encoder = { - "ppm", - CODEC_TYPE_VIDEO, - CODEC_ID_PPM, - sizeof(PNMContext), - common_init, - pnm_encode_frame, - NULL, //encode_end, - pnm_decode_frame, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, -1}, -}; -#endif // CONFIG_PPM_ENCODER - -#ifdef CONFIG_PBM_ENCODER -AVCodec pbm_encoder = { - "pbm", - CODEC_TYPE_VIDEO, - CODEC_ID_PBM, - sizeof(PNMContext), - common_init, - pnm_encode_frame, - NULL, //encode_end, - pnm_decode_frame, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_MONOWHITE, -1}, -}; -#endif // CONFIG_PBM_ENCODER - -#ifdef CONFIG_PAM_ENCODER -AVCodec pam_encoder = { - "pam", - CODEC_TYPE_VIDEO, - CODEC_ID_PAM, - sizeof(PNMContext), - common_init, - pam_encode_frame, - NULL, //encode_end, - pnm_decode_frame, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, -1}, -}; -#endif // CONFIG_PAM_ENCODER diff --git a/contrib/ffmpeg/libavcodec/pnm.h b/contrib/ffmpeg/libavcodec/pnm.h new file mode 100644 index 000000000..c77bcca09 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/pnm.h @@ -0,0 +1,37 @@ +/* + * PNM image format + * Copyright (c) 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 + */ + +#ifndef FFMPEG_PNM_H +#define FFMPEG_PNM_H + +#include "avcodec.h" + +typedef struct PNMContext { + uint8_t *bytestream; + uint8_t *bytestream_start; + uint8_t *bytestream_end; + AVFrame picture; + int maxval; ///< maximum value of a pixel +} PNMContext; + +int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s); + +#endif /* FFMPEG_PNM_H */ diff --git a/contrib/ffmpeg/libavcodec/pnm_parser.c b/contrib/ffmpeg/libavcodec/pnm_parser.c new file mode 100644 index 000000000..f5212f024 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/pnm_parser.c @@ -0,0 +1,93 @@ +/* + * PNM image parser + * Copyright (c) 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 + */ + +#include "parser.h" //for ParseContext +#include "pnm.h" + + +static int pnm_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + PNMContext pnmctx; + int next; + + for(; pc->overread>0; pc->overread--){ + pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; + } +retry: + if(pc->index){ + pnmctx.bytestream_start= + pnmctx.bytestream= pc->buffer; + pnmctx.bytestream_end= pc->buffer + pc->index; + }else{ + pnmctx.bytestream_start= + pnmctx.bytestream= (uint8_t *) buf; /* casts avoid warnings */ + pnmctx.bytestream_end= (uint8_t *) buf + buf_size; + } + if(ff_pnm_decode_header(avctx, &pnmctx) < 0){ + if(pnmctx.bytestream < pnmctx.bytestream_end){ + if(pc->index){ + pc->index=0; + }else{ + buf++; + buf_size--; + } + goto retry; + } +#if 0 + if(pc->index && pc->index*2 + FF_INPUT_BUFFER_PADDING_SIZE < pc->buffer_size && buf_size > pc->index){ + memcpy(pc->buffer + pc->index, buf, pc->index); + pc->index += pc->index; + buf += pc->index; + buf_size -= pc->index; + goto retry; + } +#endif + next= END_NOT_FOUND; + }else{ + next= pnmctx.bytestream - pnmctx.bytestream_start + + avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); + if(pnmctx.bytestream_start!=buf) + next-= pc->index; + if(next > buf_size) + next= END_NOT_FOUND; + } + + if(ff_combine_frame(pc, next, &buf, &buf_size)<0){ + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +AVCodecParser pnm_parser = { + { CODEC_ID_PGM, CODEC_ID_PGMYUV, CODEC_ID_PPM, CODEC_ID_PBM, CODEC_ID_PAM}, + sizeof(ParseContext), + NULL, + pnm_parse, + ff_parse_close, +}; diff --git a/contrib/ffmpeg/libavcodec/pnmenc.c b/contrib/ffmpeg/libavcodec/pnmenc.c new file mode 100644 index 000000000..c5061f2e7 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/pnmenc.c @@ -0,0 +1,425 @@ +/* + * PNM image format + * Copyright (c) 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 + */ +#include "avcodec.h" +#include "bytestream.h" +#include "pnm.h" + + +static int common_init(AVCodecContext *avctx){ + PNMContext *s = avctx->priv_data; + + avcodec_get_frame_defaults((AVFrame*)&s->picture); + avctx->coded_frame= (AVFrame*)&s->picture; + + return 0; +} + +static int pnm_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + PNMContext * const s = avctx->priv_data; + AVFrame *picture = data; + AVFrame * const p= (AVFrame*)&s->picture; + int i, n, linesize, h, upgrade = 0; + unsigned char *ptr; + + s->bytestream_start= + s->bytestream= buf; + s->bytestream_end= buf + buf_size; + + if(ff_pnm_decode_header(avctx, s) < 0) + return -1; + + 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= FF_I_TYPE; + p->key_frame= 1; + + switch(avctx->pix_fmt) { + default: + return -1; + case PIX_FMT_RGB24: + n = avctx->width * 3; + goto do_read; + case PIX_FMT_GRAY8: + n = avctx->width; + if (s->maxval < 255) + upgrade = 1; + goto do_read; + case PIX_FMT_GRAY16BE: + case PIX_FMT_GRAY16LE: + n = avctx->width * 2; + if (s->maxval < 65535) + upgrade = 2; + goto do_read; + case PIX_FMT_MONOWHITE: + case PIX_FMT_MONOBLACK: + n = (avctx->width + 7) >> 3; + do_read: + ptr = p->data[0]; + linesize = p->linesize[0]; + if(s->bytestream + n*avctx->height > s->bytestream_end) + return -1; + for(i = 0; i < avctx->height; i++) { + if (!upgrade) + memcpy(ptr, s->bytestream, n); + else if (upgrade == 1) { + unsigned int j, f = (255*128 + s->maxval/2) / s->maxval; + for (j=0; j<n; j++) + ptr[j] = (s->bytestream[j] * f + 64) >> 7; + } else if (upgrade == 2) { + unsigned int j, v, f = (65535*32768 + s->maxval/2) / s->maxval; + for (j=0; j<n/2; j++) { + v = be2me_16(((uint16_t *)s->bytestream)[j]); + ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15; + } + } + s->bytestream += n; + ptr += linesize; + } + break; + case PIX_FMT_YUV420P: + { + unsigned char *ptr1, *ptr2; + + n = avctx->width; + ptr = p->data[0]; + linesize = p->linesize[0]; + if(s->bytestream + n*avctx->height*3/2 > s->bytestream_end) + return -1; + for(i = 0; i < avctx->height; i++) { + memcpy(ptr, s->bytestream, n); + s->bytestream += n; + ptr += linesize; + } + ptr1 = p->data[1]; + ptr2 = p->data[2]; + n >>= 1; + h = avctx->height >> 1; + for(i = 0; i < h; i++) { + memcpy(ptr1, s->bytestream, n); + s->bytestream += n; + memcpy(ptr2, s->bytestream, n); + s->bytestream += n; + ptr1 += p->linesize[1]; + ptr2 += p->linesize[2]; + } + } + break; + case PIX_FMT_RGB32: + ptr = p->data[0]; + linesize = p->linesize[0]; + if(s->bytestream + avctx->width*avctx->height*4 > s->bytestream_end) + return -1; + for(i = 0; i < avctx->height; i++) { + int j, r, g, b, a; + + for(j = 0;j < avctx->width; j++) { + r = *s->bytestream++; + g = *s->bytestream++; + b = *s->bytestream++; + a = *s->bytestream++; + ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b; + } + ptr += linesize; + } + break; + } + *picture= *(AVFrame*)&s->picture; + *data_size = sizeof(AVPicture); + + return s->bytestream - s->bytestream_start; +} + +static int pnm_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data){ + PNMContext *s = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p= (AVFrame*)&s->picture; + int i, h, h1, c, n, linesize; + uint8_t *ptr, *ptr1, *ptr2; + + if(buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200){ + av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + + *p = *pict; + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + + s->bytestream_start= + s->bytestream= outbuf; + s->bytestream_end= outbuf+buf_size; + + h = avctx->height; + h1 = h; + switch(avctx->pix_fmt) { + case PIX_FMT_MONOWHITE: + c = '4'; + n = (avctx->width + 7) >> 3; + break; + case PIX_FMT_GRAY8: + c = '5'; + n = avctx->width; + break; + case PIX_FMT_GRAY16BE: + c = '5'; + n = avctx->width * 2; + break; + case PIX_FMT_RGB24: + c = '6'; + n = avctx->width * 3; + break; + case PIX_FMT_YUV420P: + c = '5'; + n = avctx->width; + h1 = (h * 3) / 2; + break; + default: + return -1; + } + snprintf(s->bytestream, s->bytestream_end - s->bytestream, + "P%c\n%d %d\n", + c, avctx->width, h1); + s->bytestream += strlen(s->bytestream); + if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { + snprintf(s->bytestream, s->bytestream_end - s->bytestream, + "%d\n", (avctx->pix_fmt != PIX_FMT_GRAY16BE) ? 255 : 65535); + s->bytestream += strlen(s->bytestream); + } + + ptr = p->data[0]; + linesize = p->linesize[0]; + for(i=0;i<h;i++) { + memcpy(s->bytestream, ptr, n); + s->bytestream += n; + ptr += linesize; + } + + if (avctx->pix_fmt == PIX_FMT_YUV420P) { + h >>= 1; + n >>= 1; + ptr1 = p->data[1]; + ptr2 = p->data[2]; + for(i=0;i<h;i++) { + memcpy(s->bytestream, ptr1, n); + s->bytestream += n; + memcpy(s->bytestream, ptr2, n); + s->bytestream += n; + ptr1 += p->linesize[1]; + ptr2 += p->linesize[2]; + } + } + return s->bytestream - s->bytestream_start; +} + +static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data){ + PNMContext *s = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p= (AVFrame*)&s->picture; + int i, h, w, n, linesize, depth, maxval; + const char *tuple_type; + uint8_t *ptr; + + if(buf_size < avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height) + 200){ + av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + + *p = *pict; + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + + s->bytestream_start= + s->bytestream= outbuf; + s->bytestream_end= outbuf+buf_size; + + h = avctx->height; + w = avctx->width; + switch(avctx->pix_fmt) { + case PIX_FMT_MONOWHITE: + n = (w + 7) >> 3; + depth = 1; + maxval = 1; + tuple_type = "BLACKANDWHITE"; + break; + case PIX_FMT_GRAY8: + n = w; + depth = 1; + maxval = 255; + tuple_type = "GRAYSCALE"; + break; + case PIX_FMT_RGB24: + n = w * 3; + depth = 3; + maxval = 255; + tuple_type = "RGB"; + break; + case PIX_FMT_RGB32: + n = w * 4; + depth = 4; + maxval = 255; + tuple_type = "RGB_ALPHA"; + break; + default: + return -1; + } + snprintf(s->bytestream, s->bytestream_end - s->bytestream, + "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLETYPE %s\nENDHDR\n", + w, h, depth, maxval, tuple_type); + s->bytestream += strlen(s->bytestream); + + ptr = p->data[0]; + linesize = p->linesize[0]; + + if (avctx->pix_fmt == PIX_FMT_RGB32) { + int j; + unsigned int v; + + for(i=0;i<h;i++) { + for(j=0;j<w;j++) { + v = ((uint32_t *)ptr)[j]; + bytestream_put_be24(&s->bytestream, v); + *s->bytestream++ = v >> 24; + } + ptr += linesize; + } + } else { + for(i=0;i<h;i++) { + memcpy(s->bytestream, ptr, n); + s->bytestream += n; + ptr += linesize; + } + } + return s->bytestream - s->bytestream_start; +} + +#if 0 +static int pnm_probe(AVProbeData *pd) +{ + const char *p = pd->buf; + if (pd->buf_size >= 8 && + p[0] == 'P' && + p[1] >= '4' && p[1] <= '6' && + pnm_space(p[2]) ) + return AVPROBE_SCORE_MAX - 1; /* to permit pgmyuv probe */ + else + return 0; +} + +static int pgmyuv_probe(AVProbeData *pd) +{ + if (match_ext(pd->filename, "pgmyuv")) + return AVPROBE_SCORE_MAX; + else + return 0; +} + +static int pam_probe(AVProbeData *pd) +{ + const char *p = pd->buf; + if (pd->buf_size >= 8 && + p[0] == 'P' && + p[1] == '7' && + p[2] == '\n') + return AVPROBE_SCORE_MAX; + else + return 0; +} +#endif + + +#ifdef CONFIG_PGM_ENCODER +AVCodec pgm_encoder = { + "pgm", + CODEC_TYPE_VIDEO, + CODEC_ID_PGM, + sizeof(PNMContext), + common_init, + pnm_encode_frame, + NULL, //encode_end, + pnm_decode_frame, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_GRAY8, PIX_FMT_GRAY16BE, -1}, +}; +#endif // CONFIG_PGM_ENCODER + +#ifdef CONFIG_PGMYUV_ENCODER +AVCodec pgmyuv_encoder = { + "pgmyuv", + CODEC_TYPE_VIDEO, + CODEC_ID_PGMYUV, + sizeof(PNMContext), + common_init, + pnm_encode_frame, + NULL, //encode_end, + pnm_decode_frame, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; +#endif // CONFIG_PGMYUV_ENCODER + +#ifdef CONFIG_PPM_ENCODER +AVCodec ppm_encoder = { + "ppm", + CODEC_TYPE_VIDEO, + CODEC_ID_PPM, + sizeof(PNMContext), + common_init, + pnm_encode_frame, + NULL, //encode_end, + pnm_decode_frame, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, -1}, +}; +#endif // CONFIG_PPM_ENCODER + +#ifdef CONFIG_PBM_ENCODER +AVCodec pbm_encoder = { + "pbm", + CODEC_TYPE_VIDEO, + CODEC_ID_PBM, + sizeof(PNMContext), + common_init, + pnm_encode_frame, + NULL, //encode_end, + pnm_decode_frame, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_MONOWHITE, -1}, +}; +#endif // CONFIG_PBM_ENCODER + +#ifdef CONFIG_PAM_ENCODER +AVCodec pam_encoder = { + "pam", + CODEC_TYPE_VIDEO, + CODEC_ID_PAM, + sizeof(PNMContext), + common_init, + pam_encode_frame, + NULL, //encode_end, + pnm_decode_frame, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, -1}, +}; +#endif // CONFIG_PAM_ENCODER diff --git a/contrib/ffmpeg/libavcodec/ppc/check_altivec.c b/contrib/ffmpeg/libavcodec/ppc/check_altivec.c new file mode 100644 index 000000000..cf55b9a1d --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ppc/check_altivec.c @@ -0,0 +1,75 @@ +/* + * 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 check_altivec.c + * Checks for AltiVec presence. + */ + +#ifdef __APPLE__ +#include <sys/sysctl.h> +#elif __AMIGAOS4__ +#include <exec/exec.h> +#include <interfaces/exec.h> +#include <proto/exec.h> +#endif /* __APPLE__ */ + +/** + * This function MAY rely on signal() or fork() in order to make sure altivec + * is present + */ + +int has_altivec(void) +{ +#ifdef __AMIGAOS4__ + ULONG result = 0; + extern struct ExecIFace *IExec; + + IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE); + if (result == VECTORTYPE_ALTIVEC) return 1; + return 0; +#elif __APPLE__ + int sels[2] = {CTL_HW, HW_VECTORUNIT}; + int has_vu = 0; + size_t len = sizeof(has_vu); + int err; + + err = sysctl(sels, 2, &has_vu, &len, NULL, 0); + + if (err == 0) return (has_vu != 0); + return 0; +#elif defined(RUNTIME_CPUDETECT) + int proc_ver; + // support of mfspr PVR emulation added in Linux 2.6.17 + asm volatile("mfspr %0, 287" : "=r" (proc_ver)); + proc_ver >>= 16; + if (proc_ver & 0x8000 || + proc_ver == 0x000c || + proc_ver == 0x0039 || proc_ver == 0x003c || + proc_ver == 0x0044 || proc_ver == 0x0045 || + proc_ver == 0x0070) + return 1; + return 0; +#else + // since we were compiled for altivec, just assume we have it + // until someone comes up with a proper way (not involving signal hacks). + return 1; +#endif /* __AMIGAOS4__ */ +} + diff --git a/contrib/ffmpeg/libavcodec/ppc/dsputil_altivec.c b/contrib/ffmpeg/libavcodec/ppc/dsputil_altivec.c index bbc53d761..3d79c3ab5 100644 --- a/contrib/ffmpeg/libavcodec/ppc/dsputil_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/dsputil_altivec.c @@ -20,44 +20,18 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" #include "gcc_fixes.h" -#include "dsputil_altivec.h" - -#ifdef CONFIG_DARWIN -#include <sys/sysctl.h> -#else /* CONFIG_DARWIN */ -#ifdef __AMIGAOS4__ -#include <exec/exec.h> -#include <interfaces/exec.h> -#include <proto/exec.h> -#else /* __AMIGAOS4__ */ -#include <signal.h> -#include <setjmp.h> - -static sigjmp_buf jmpbuf; -static volatile sig_atomic_t canjump = 0; - -static void sigill_handler (int sig) -{ - if (!canjump) { - signal (sig, SIG_DFL); - raise (sig); - } - - canjump = 0; - siglongjmp (jmpbuf, 1); -} -#endif /* CONFIG_DARWIN */ -#endif /* __AMIGAOS4__ */ +#include "dsputil_ppc.h" +#include "util_altivec.h" int sad16_x2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) { int i; - int s __attribute__((aligned(16))); - const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0); + DECLARE_ALIGNED_16(int, s); + const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); vector unsigned char *tv; vector unsigned char pix1v, pix2v, pix2iv, avgv, t5; vector unsigned int sad; @@ -103,8 +77,8 @@ int sad16_x2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h int sad16_y2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) { int i; - int s __attribute__((aligned(16))); - const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0); + DECLARE_ALIGNED_16(int, s); + const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); vector unsigned char *tv; vector unsigned char pix1v, pix2v, pix3v, avgv, t5; vector unsigned int sad; @@ -163,10 +137,10 @@ int sad16_y2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h int sad16_xy2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) { int i; - int s __attribute__((aligned(16))); + DECLARE_ALIGNED_16(int, s); uint8_t *pix3 = pix2 + line_size; - const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0); - const_vector unsigned short two = (const_vector unsigned short)vec_splat_u16(2); + const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); + const vector unsigned short two = (const vector unsigned short)vec_splat_u16(2); vector unsigned char *tv, avgv, t5; vector unsigned char pix1v, pix2v, pix3v, pix2iv, pix3iv; vector unsigned short pix2lv, pix2hv, pix2ilv, pix2ihv; @@ -218,7 +192,7 @@ int sad16_xy2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int pix3iv = vec_perm(tv[0], tv[1], vec_lvsl(0, &pix3[1])); /* - Note that Altivec does have vec_avg, but this works on vector pairs + Note that AltiVec does have vec_avg, but this works on vector pairs and rounds up. We could do avg(avg(a,b),avg(c,d)), but the rounding would mean that, for example, avg(3,0,0,1) = 2, when it should be 1. Instead, we have to split the pixel vectors into vectors of shorts, @@ -264,8 +238,8 @@ int sad16_xy2_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int int sad16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) { int i; - int s __attribute__((aligned(16))); - const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0); + DECLARE_ALIGNED_16(int, s); + const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); vector unsigned char perm1, perm2, *pix1v, *pix2v; vector unsigned char t1, t2, t3,t4, t5; vector unsigned int sad; @@ -306,8 +280,8 @@ int sad16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) int sad8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) { int i; - int s __attribute__((aligned(16))); - const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0); + DECLARE_ALIGNED_16(int, s); + const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v; vector unsigned char t1, t2, t3,t4, t5; vector unsigned int sad; @@ -351,8 +325,8 @@ int sad8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) int pix_norm1_altivec(uint8_t *pix, int line_size) { int i; - int s __attribute__((aligned(16))); - const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0); + DECLARE_ALIGNED_16(int, s); + const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); vector unsigned char *tv; vector unsigned char pixv; vector unsigned int sv; @@ -387,8 +361,8 @@ int pix_norm1_altivec(uint8_t *pix, int line_size) int sse8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) { int i; - int s __attribute__((aligned(16))); - const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0); + DECLARE_ALIGNED_16(int, s); + const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); vector unsigned char perm1, perm2, permclear, *pix1v, *pix2v; vector unsigned char t1, t2, t3,t4, t5; vector unsigned int sum; @@ -443,8 +417,8 @@ int sse8_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) int sse16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) { int i; - int s __attribute__((aligned(16))); - const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0); + DECLARE_ALIGNED_16(int, s); + const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); vector unsigned char perm1, perm2, *pix1v, *pix2v; vector unsigned char t1, t2, t3,t4, t5; vector unsigned int sum; @@ -488,14 +462,14 @@ int sse16_altivec(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) int pix_sum_altivec(uint8_t * pix, int line_size) { - const_vector unsigned int zero = (const_vector unsigned int)vec_splat_u32(0); + const vector unsigned int zero = (const vector unsigned int)vec_splat_u32(0); vector unsigned char perm, *pixv; vector unsigned char t1; vector unsigned int sad; vector signed int sumdiffs; int i; - int s __attribute__((aligned(16))); + DECLARE_ALIGNED_16(int, s); sad = (vector unsigned int)vec_splat_u32(0); @@ -523,7 +497,7 @@ void get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, int line { int i; vector unsigned char perm, bytes, *pixv; - const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0); + const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); vector signed short shorts; for(i=0;i<8;i++) @@ -550,7 +524,7 @@ void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1, { int i; vector unsigned char perm, bytes, *pixv; - const_vector unsigned char zero = (const_vector unsigned char)vec_splat_u8(0); + const vector unsigned char zero = (const vector unsigned char)vec_splat_u8(0); vector signed short shorts1, shorts2; for(i=0;i<4;i++) @@ -769,8 +743,8 @@ POWERPC_PERF_DECLARE(altivec_put_pixels8_xy2_num, 1); blockv, temp1, temp2; register vector unsigned short pixelssum1, pixelssum2, temp3; - register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0); - register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2); + register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); + register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); temp1 = vec_ld(0, pixels); temp2 = vec_ld(16, pixels); @@ -845,9 +819,9 @@ POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels8_xy2_num, 1); blockv, temp1, temp2; register vector unsigned short pixelssum1, pixelssum2, temp3; - register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0); - register const_vector unsigned short vcone = (const_vector unsigned short)vec_splat_u16(1); - register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2); + register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); + register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1); + register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); temp1 = vec_ld(0, pixels); temp2 = vec_ld(16, pixels); @@ -922,8 +896,8 @@ POWERPC_PERF_DECLARE(altivec_put_pixels16_xy2_num, 1); register vector unsigned short pixelssum1, pixelssum2, temp3, pixelssum3, pixelssum4, temp4; - register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0); - register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2); + register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); + register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); POWERPC_PERF_START_COUNT(altivec_put_pixels16_xy2_num, 1); @@ -1004,9 +978,9 @@ POWERPC_PERF_DECLARE(altivec_put_no_rnd_pixels16_xy2_num, 1); register vector unsigned short pixelssum1, pixelssum2, temp3, pixelssum3, pixelssum4, temp4; - register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0); - register const_vector unsigned short vcone = (const_vector unsigned short)vec_splat_u16(1); - register const_vector unsigned short vctwo = (const_vector unsigned short)vec_splat_u16(2); + register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); + register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1); + register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2); POWERPC_PERF_START_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1); @@ -1078,25 +1052,25 @@ POWERPC_PERF_STOP_COUNT(altivec_put_no_rnd_pixels16_xy2_num, 1); int hadamard8_diff8x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h){ POWERPC_PERF_DECLARE(altivec_hadamard8_diff8x8_num, 1); int sum; - register const_vector unsigned char vzero = - (const_vector unsigned char)vec_splat_u8(0); + register const vector unsigned char vzero = + (const vector unsigned char)vec_splat_u8(0); register vector signed short temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; POWERPC_PERF_START_COUNT(altivec_hadamard8_diff8x8_num, 1); { - register const_vector signed short vprod1 =(const_vector signed short) + register const vector signed short vprod1 =(const vector signed short) AVV( 1,-1, 1,-1, 1,-1, 1,-1); - register const_vector signed short vprod2 =(const_vector signed short) + register const vector signed short vprod2 =(const vector signed short) AVV( 1, 1,-1,-1, 1, 1,-1,-1); - register const_vector signed short vprod3 =(const_vector signed short) + register const vector signed short vprod3 =(const vector signed short) AVV( 1, 1, 1, 1,-1,-1,-1,-1); - register const_vector unsigned char perm1 = (const_vector unsigned char) + register const vector unsigned char perm1 = (const vector unsigned char) AVV(0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D); - register const_vector unsigned char perm2 = (const_vector unsigned char) + register const vector unsigned char perm2 = (const vector unsigned char) AVV(0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B); - register const_vector unsigned char perm3 = (const_vector unsigned char) + register const vector unsigned char perm3 = (const vector unsigned char) AVV(0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07); @@ -1120,7 +1094,7 @@ POWERPC_PERF_START_COUNT(altivec_hadamard8_diff8x8_num, 1); dstV = \ (vector signed short)vec_mergeh((vector signed char)vzero, \ (vector signed char)dstO); \ - /* substractions inside the first butterfly */ \ + /* subtractions inside the first butterfly */ \ but0 = vec_sub(srcV, dstV); \ op1 = vec_perm(but0, but0, perm1); \ but1 = vec_mladd(but0, vprod1, op1); \ @@ -1201,7 +1175,7 @@ POWERPC_PERF_STOP_COUNT(altivec_hadamard8_diff8x8_num, 1); schedule for the 7450, and its code isn't much faster than gcc-3.3 on the 7450 (but uses 25% less instructions...) - On the 970, the hand-made RA is still a win (arount 690 + On the 970, the hand-made RA is still a win (around 690 vs. around 780), but xlc goes to around 660 on the regular C code... */ @@ -1226,25 +1200,25 @@ static int hadamard8_diff16x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, temp5S REG_v(v13), temp6S REG_v(v14), temp7S REG_v(v15); - register const_vector unsigned char vzero REG_v(v31)= - (const_vector unsigned char)vec_splat_u8(0); + register const vector unsigned char vzero REG_v(v31)= + (const vector unsigned char)vec_splat_u8(0); { - register const_vector signed short vprod1 REG_v(v16)= - (const_vector signed short)AVV( 1,-1, 1,-1, 1,-1, 1,-1); - register const_vector signed short vprod2 REG_v(v17)= - (const_vector signed short)AVV( 1, 1,-1,-1, 1, 1,-1,-1); - register const_vector signed short vprod3 REG_v(v18)= - (const_vector signed short)AVV( 1, 1, 1, 1,-1,-1,-1,-1); - register const_vector unsigned char perm1 REG_v(v19)= - (const_vector unsigned char) + register const vector signed short vprod1 REG_v(v16)= + (const vector signed short)AVV( 1,-1, 1,-1, 1,-1, 1,-1); + register const vector signed short vprod2 REG_v(v17)= + (const vector signed short)AVV( 1, 1,-1,-1, 1, 1,-1,-1); + register const vector signed short vprod3 REG_v(v18)= + (const vector signed short)AVV( 1, 1, 1, 1,-1,-1,-1,-1); + register const vector unsigned char perm1 REG_v(v19)= + (const vector unsigned char) AVV(0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D); - register const_vector unsigned char perm2 REG_v(v20)= - (const_vector unsigned char) + register const vector unsigned char perm2 REG_v(v20)= + (const vector unsigned char) AVV(0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B); - register const_vector unsigned char perm3 REG_v(v21)= - (const_vector unsigned char) + register const vector unsigned char perm3 REG_v(v21)= + (const vector unsigned char) AVV(0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07); @@ -1293,7 +1267,7 @@ static int hadamard8_diff16x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, dstW = \ (vector signed short)vec_mergel((vector signed char)vzero, \ (vector signed char)dstO); \ - /* substractions inside the first butterfly */ \ + /* subtractions inside the first butterfly */ \ but0 = vec_sub(srcV, dstV); \ but0S = vec_sub(srcW, dstW); \ op1 = vec_perm(but0, but0, perm1); \ @@ -1419,50 +1393,6 @@ POWERPC_PERF_STOP_COUNT(altivec_hadamard8_diff16_num, 1); return score; } -int has_altivec(void) -{ -#ifdef __AMIGAOS4__ - ULONG result = 0; - extern struct ExecIFace *IExec; - - IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE); - if (result == VECTORTYPE_ALTIVEC) return 1; - return 0; -#else /* __AMIGAOS4__ */ - -#ifdef CONFIG_DARWIN - int sels[2] = {CTL_HW, HW_VECTORUNIT}; - int has_vu = 0; - size_t len = sizeof(has_vu); - int err; - - err = sysctl(sels, 2, &has_vu, &len, NULL, 0); - - if (err == 0) return (has_vu != 0); -#else /* CONFIG_DARWIN */ -/* no Darwin, do it the brute-force way */ -/* this is borrowed from the libmpeg2 library */ - { - signal (SIGILL, sigill_handler); - if (sigsetjmp (jmpbuf, 1)) { - signal (SIGILL, SIG_DFL); - } else { - canjump = 1; - - asm volatile ("mtspr 256, %0\n\t" - "vand %%v0, %%v0, %%v0" - : - : "r" (-1)); - - signal (SIGILL, SIG_DFL); - return 1; - } - } -#endif /* CONFIG_DARWIN */ - return 0; -#endif /* __AMIGAOS4__ */ -} - static void vorbis_inverse_coupling_altivec(float *mag, float *ang, int blocksize) { @@ -1495,9 +1425,9 @@ POWERPC_PERF_DECLARE(altivec_avg_pixels8_xy2_num, 1); register vector unsigned char blockv, temp1, temp2, blocktemp; register vector unsigned short pixelssum1, pixelssum2, temp3; - register const_vector unsigned char vczero = (const_vector unsigned char) + register const vector unsigned char vczero = (const vector unsigned char) vec_splat_u8(0); - register const_vector unsigned short vctwo = (const_vector unsigned short) + register const vector unsigned short vctwo = (const vector unsigned short) vec_splat_u16(2); temp1 = vec_ld(0, pixels); @@ -1583,7 +1513,6 @@ void dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx) c->hadamard8_diff[0] = hadamard8_diff16_altivec; c->hadamard8_diff[1] = hadamard8_diff8x8_altivec; -#ifdef CONFIG_VORBIS_DECODER - c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec; -#endif + if (ENABLE_VORBIS_DECODER) + c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec; } diff --git a/contrib/ffmpeg/libavcodec/ppc/dsputil_altivec.h b/contrib/ffmpeg/libavcodec/ppc/dsputil_altivec.h index 560d778bb..43bd5abab 100644 --- a/contrib/ffmpeg/libavcodec/ppc/dsputil_altivec.h +++ b/contrib/ffmpeg/libavcodec/ppc/dsputil_altivec.h @@ -20,12 +20,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _DSPUTIL_ALTIVEC_ -#define _DSPUTIL_ALTIVEC_ +#ifndef FFMPEG_DSPUTIL_ALTIVEC_H +#define FFMPEG_DSPUTIL_ALTIVEC_H -#include "dsputil_ppc.h" - -#ifdef HAVE_ALTIVEC +#include <stdint.h> extern int has_altivec(void); @@ -33,74 +31,4 @@ void put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, void avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h); -// used to build registers permutation vectors (vcprm) -// the 's' are for words in the _s_econd vector -#define WORD_0 0x00,0x01,0x02,0x03 -#define WORD_1 0x04,0x05,0x06,0x07 -#define WORD_2 0x08,0x09,0x0a,0x0b -#define WORD_3 0x0c,0x0d,0x0e,0x0f -#define WORD_s0 0x10,0x11,0x12,0x13 -#define WORD_s1 0x14,0x15,0x16,0x17 -#define WORD_s2 0x18,0x19,0x1a,0x1b -#define WORD_s3 0x1c,0x1d,0x1e,0x1f - -#ifdef CONFIG_DARWIN -#define vcprm(a,b,c,d) (const vector unsigned char)(WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d) -#else -#define vcprm(a,b,c,d) (const vector unsigned char){WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d} -#endif - -// vcprmle is used to keep the same index as in the SSE version. -// it's the same as vcprm, with the index inversed -// ('le' is Little Endian) -#define vcprmle(a,b,c,d) vcprm(d,c,b,a) - -// used to build inverse/identity vectors (vcii) -// n is _n_egative, p is _p_ositive -#define FLOAT_n -1. -#define FLOAT_p 1. - - -#ifdef CONFIG_DARWIN -#define vcii(a,b,c,d) (const vector float)(FLOAT_ ## a, FLOAT_ ## b, FLOAT_ ## c, FLOAT_ ## d) -#else -#define vcii(a,b,c,d) (const vector float){FLOAT_ ## a, FLOAT_ ## b, FLOAT_ ## c, FLOAT_ ## d} -#endif - -// Transpose 8x8 matrix of 16-bit elements (in-place) -#define TRANSPOSE8(a,b,c,d,e,f,g,h) \ -do { \ - vector signed short A1, B1, C1, D1, E1, F1, G1, H1; \ - vector signed short A2, B2, C2, D2, E2, F2, G2, H2; \ - \ - A1 = vec_mergeh (a, e); \ - B1 = vec_mergel (a, e); \ - C1 = vec_mergeh (b, f); \ - D1 = vec_mergel (b, f); \ - E1 = vec_mergeh (c, g); \ - F1 = vec_mergel (c, g); \ - G1 = vec_mergeh (d, h); \ - H1 = vec_mergel (d, h); \ - \ - A2 = vec_mergeh (A1, E1); \ - B2 = vec_mergel (A1, E1); \ - C2 = vec_mergeh (B1, F1); \ - D2 = vec_mergel (B1, F1); \ - E2 = vec_mergeh (C1, G1); \ - F2 = vec_mergel (C1, G1); \ - G2 = vec_mergeh (D1, H1); \ - H2 = vec_mergel (D1, H1); \ - \ - a = vec_mergeh (A2, E2); \ - b = vec_mergel (A2, E2); \ - c = vec_mergeh (B2, F2); \ - d = vec_mergel (B2, F2); \ - e = vec_mergeh (C2, G2); \ - f = vec_mergel (C2, G2); \ - g = vec_mergeh (D2, H2); \ - h = vec_mergel (D2, H2); \ -} while (0) - -#endif /* HAVE_ALTIVEC */ - -#endif /* _DSPUTIL_ALTIVEC_ */ +#endif /* FFMPEG_DSPUTIL_ALTIVEC_H */ diff --git a/contrib/ffmpeg/libavcodec/ppc/dsputil_ppc.c b/contrib/ffmpeg/libavcodec/ppc/dsputil_ppc.c index 117a7adf1..13dea06a1 100644 --- a/contrib/ffmpeg/libavcodec/ppc/dsputil_ppc.c +++ b/contrib/ffmpeg/libavcodec/ppc/dsputil_ppc.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" #include "dsputil_ppc.h" @@ -39,6 +39,7 @@ void dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx); void vc1dsp_init_altivec(DSPContext* c, AVCodecContext *avctx); void snow_init_altivec(DSPContext* c, AVCodecContext *avctx); void float_init_altivec(DSPContext* c, AVCodecContext *avctx); +void int_init_altivec(DSPContext* c, AVCodecContext *avctx); #endif @@ -154,11 +155,7 @@ POWERPC_PERF_START_COUNT(powerpc_clear_blocks_dcbz32, 1); i += 16; } for ( ; i < sizeof(DCTELEM)*6*64-31 ; i += 32) { -#ifndef __MWERKS__ asm volatile("dcbz %0,%1" : : "b" (blocks), "r" (i) : "memory"); -#else - __dcbz( blocks, i ); -#endif } if (misal) { ((unsigned long*)blocks)[188] = 0L; @@ -213,7 +210,7 @@ void clear_blocks_dcbz128_ppc(DCTELEM *blocks) knows about dcbzl ... */ long check_dcbzl_effect(void) { - register char *fakedata = (char*)av_malloc(1024); + register char *fakedata = av_malloc(1024); register char *fakedata_middle; register long zero = 0; register long i = 0; @@ -260,7 +257,7 @@ static void prefetch_ppc(void *mem, int stride, int h) void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx) { - // Common optimizations whether Altivec is available or not + // Common optimizations whether AltiVec is available or not c->prefetch = prefetch_ppc; switch (check_dcbzl_effect()) { case 32: @@ -284,6 +281,7 @@ void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx) if(ENABLE_VC1_DECODER || ENABLE_WMV3_DECODER) vc1dsp_init_altivec(c, avctx); float_init_altivec(c, avctx); + int_init_altivec(c, avctx); c->gmc1 = gmc1_altivec; #ifdef CONFIG_ENCODERS diff --git a/contrib/ffmpeg/libavcodec/ppc/dsputil_ppc.h b/contrib/ffmpeg/libavcodec/ppc/dsputil_ppc.h index 5b25732b2..d8f6b27f9 100644 --- a/contrib/ffmpeg/libavcodec/ppc/dsputil_ppc.h +++ b/contrib/ffmpeg/libavcodec/ppc/dsputil_ppc.h @@ -18,14 +18,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _DSPUTIL_PPC_ -#define _DSPUTIL_PPC_ +#ifndef FFMPEG_DSPUTIL_PPC_H +#define FFMPEG_DSPUTIL_PPC_H #ifdef CONFIG_POWERPC_PERF void powerpc_display_perf_report(void); /* the 604* have 2, the G3* have 4, the G4s have 6, and the G5 are completely different (they MUST use - POWERPC_MODE_64BITS, and let's hope all future 64 bis PPC + HAVE_PPC64, and let's hope all future 64 bis PPC will use the same PMCs... */ #define POWERPC_NUM_PMC_ENABLED 6 /* if you add to the enum below, also add to the perfname array @@ -68,7 +68,7 @@ enum powerpc_data_index { }; extern unsigned long long perfdata[POWERPC_NUM_PMC_ENABLED][powerpc_perf_total][powerpc_data_total]; -#ifndef POWERPC_MODE_64BITS +#ifndef HAVE_PPC64 #define POWERP_PMC_DATATYPE unsigned long #define POWERPC_GET_PMC1(a) asm volatile("mfspr %0, 937" : "=r" (a)) #define POWERPC_GET_PMC2(a) asm volatile("mfspr %0, 938" : "=r" (a)) @@ -86,7 +86,7 @@ extern unsigned long long perfdata[POWERPC_NUM_PMC_ENABLED][powerpc_perf_total][ #define POWERPC_GET_PMC5(a) do {} while (0) #define POWERPC_GET_PMC6(a) do {} while (0) #endif -#else /* POWERPC_MODE_64BITS */ +#else /* HAVE_PPC64 */ #define POWERP_PMC_DATATYPE unsigned long long #define POWERPC_GET_PMC1(a) asm volatile("mfspr %0, 771" : "=r" (a)) #define POWERPC_GET_PMC2(a) asm volatile("mfspr %0, 772" : "=r" (a)) @@ -104,7 +104,7 @@ extern unsigned long long perfdata[POWERPC_NUM_PMC_ENABLED][powerpc_perf_total][ #define POWERPC_GET_PMC5(a) do {} while (0) #define POWERPC_GET_PMC6(a) do {} while (0) #endif -#endif /* POWERPC_MODE_64BITS */ +#endif /* HAVE_PPC64 */ #define POWERPC_PERF_DECLARE(a, cond) \ POWERP_PMC_DATATYPE \ pmc_start[POWERPC_NUM_PMC_ENABLED], \ @@ -152,4 +152,4 @@ extern unsigned long long perfdata[POWERPC_NUM_PMC_ENABLED][powerpc_perf_total][ #define POWERPC_PERF_STOP_COUNT(a, cond) do {} while (0) #endif /* CONFIG_POWERPC_PERF */ -#endif /* _DSPUTIL_PPC_ */ +#endif /* FFMPEG_DSPUTIL_PPC_H */ diff --git a/contrib/ffmpeg/libavcodec/ppc/fdct_altivec.c b/contrib/ffmpeg/libavcodec/ppc/fdct_altivec.c index 2418c32bb..6b9a35ba8 100644 --- a/contrib/ffmpeg/libavcodec/ppc/fdct_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/fdct_altivec.c @@ -21,8 +21,8 @@ #include "common.h" -#include "../dsputil.h" -#include "dsputil_altivec.h" +#include "dsputil.h" +#include "dsputil_ppc.h" #include "gcc_fixes.h" diff --git a/contrib/ffmpeg/libavcodec/ppc/fft_altivec.c b/contrib/ffmpeg/libavcodec/ppc/fft_altivec.c index 384a774ff..e0b77807f 100644 --- a/contrib/ffmpeg/libavcodec/ppc/fft_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/fft_altivec.c @@ -20,12 +20,12 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" #include "gcc_fixes.h" -#include "dsputil_altivec.h" - +#include "dsputil_ppc.h" +#include "util_altivec.h" /* those three macros are from libavcodec/fft.c and are required for the reference C code diff --git a/contrib/ffmpeg/libavcodec/ppc/float_altivec.c b/contrib/ffmpeg/libavcodec/ppc/float_altivec.c index 22c2de61a..750e6d7f9 100644 --- a/contrib/ffmpeg/libavcodec/ppc/float_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/float_altivec.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" #include "gcc_fixes.h" diff --git a/contrib/ffmpeg/libavcodec/ppc/gcc_fixes.h b/contrib/ffmpeg/libavcodec/ppc/gcc_fixes.h index 5a4a55188..b8a908a61 100644 --- a/contrib/ffmpeg/libavcodec/ppc/gcc_fixes.h +++ b/contrib/ffmpeg/libavcodec/ppc/gcc_fixes.h @@ -20,31 +20,22 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _GCC_FIXES_ -#define _GCC_FIXES_ +#ifndef FFMPEG_GCC_FIXES_H +#define FFMPEG_GCC_FIXES_H + +#include "config.h" #ifdef HAVE_ALTIVEC_H #include <altivec.h> #endif -#ifdef CONFIG_DARWIN -# ifndef __MWERKS__ -# define AVV(x...) (x) -# else -# define AVV -# endif -#define REG_v(a) asm ( #a ) -#else - -#define AVV(x...) {x} - #if (__GNUC__ < 4) # define REG_v(a) #else # define REG_v(a) asm ( #a ) #endif -#if (__GNUC__ * 100 + __GNUC_MINOR__ < 303) +#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) /* This code was provided to me by Bartosch Pixa * as a separate header file (broken_mergel.h). @@ -106,14 +97,6 @@ __ch (__bin_args_eq (vector unsigned int, (a1), vector unsigned int, (a2)), \ ((vector unsigned int) ff_vmrglw ((vector signed int) (a1), (vector signed int) (a2))), \ __altivec_link_error_invalid_argument ()))))))) -#endif - -#endif /* CONFIG_DARWIN */ - -#ifndef __MWERKS__ -#define const_vector const vector -#else -#define const_vector vector -#endif +#endif /* (__GNUC__ == 3 && __GNUC_MINOR__ < 3) */ -#endif /* _GCC_FIXES_ */ +#endif /* FFMPEG_GCC_FIXES_H */ diff --git a/contrib/ffmpeg/libavcodec/ppc/gmc_altivec.c b/contrib/ffmpeg/libavcodec/ppc/gmc_altivec.c index 42c936bb3..8151410d4 100644 --- a/contrib/ffmpeg/libavcodec/ppc/gmc_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/gmc_altivec.c @@ -20,24 +20,25 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" #include "gcc_fixes.h" -#include "dsputil_altivec.h" +#include "dsputil_ppc.h" +#include "util_altivec.h" /* altivec-enhanced gmc1. ATM this code assume stride is a multiple of 8, - to preserve proper dst alignement. + to preserve proper dst alignment. */ #define GMC1_PERF_COND (h==8) void gmc1_altivec(uint8_t *dst /* align 8 */, uint8_t *src /* align1 */, int stride, int h, int x16, int y16, int rounder) { POWERPC_PERF_DECLARE(altivec_gmc1_num, GMC1_PERF_COND); - const unsigned short __attribute__ ((aligned(16))) rounder_a[8] = + const DECLARE_ALIGNED_16(unsigned short, rounder_a[8]) = {rounder, rounder, rounder, rounder, rounder, rounder, rounder, rounder}; - const unsigned short __attribute__ ((aligned(16))) ABCD[8] = + const DECLARE_ALIGNED_16(unsigned short, ABCD[8]) = { (16-x16)*(16-y16), /* A */ ( x16)*(16-y16), /* B */ @@ -45,8 +46,8 @@ POWERPC_PERF_DECLARE(altivec_gmc1_num, GMC1_PERF_COND); ( x16)*( y16), /* D */ 0, 0, 0, 0 /* padding */ }; - register const_vector unsigned char vczero = (const_vector unsigned char)vec_splat_u8(0); - register const_vector unsigned short vcsr8 = (const_vector unsigned short)vec_splat_u16(8); + register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0); + register const vector unsigned short vcsr8 = (const vector unsigned short)vec_splat_u16(8); register vector unsigned char dstv, dstv2, src_0, src_1, srcvA, srcvB, srcvC, srcvD; register vector unsigned short Av, Bv, Cv, Dv, rounderV, tempA, tempB, tempC, tempD; int i; diff --git a/contrib/ffmpeg/libavcodec/ppc/h264_altivec.c b/contrib/ffmpeg/libavcodec/ppc/h264_altivec.c index bac620e82..c716b1e33 100644 --- a/contrib/ffmpeg/libavcodec/ppc/h264_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/h264_altivec.c @@ -18,11 +18,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" #include "gcc_fixes.h" +#include "dsputil_ppc.h" #include "dsputil_altivec.h" +#include "util_altivec.h" #include "types_altivec.h" #define PUT_OP_U8_ALTIVEC(d, s, dst) d = s @@ -180,130 +182,124 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## CODETYPE(uint8_t *dst, uint /* this code assume that stride % 16 == 0 */ void put_no_rnd_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) { - signed int ABCD[4] __attribute__((aligned(16))) = + DECLARE_ALIGNED_16(signed int, ABCD[4]) = {((8 - x) * (8 - y)), - ((x) * (8 - y)), - ((8 - x) * (y)), - ((x) * (y))}; + ((x) * (8 - y)), + ((8 - x) * (y)), + ((x) * (y))}; register int i; - vector unsigned char fperm; - const vector signed int vABCD = vec_ld(0, ABCD); - const vector signed short vA = vec_splat((vector signed short)vABCD, 1); - const vector signed short vB = vec_splat((vector signed short)vABCD, 3); - const vector signed short vC = vec_splat((vector signed short)vABCD, 5); - const vector signed short vD = vec_splat((vector signed short)vABCD, 7); - const vector signed int vzero = vec_splat_s32(0); - const vector signed short v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4)); - const vector unsigned short v6us = vec_splat_u16(6); - register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1; + vec_u8_t fperm; + const vec_s32_t vABCD = vec_ld(0, ABCD); + const vec_s16_t vA = vec_splat((vec_s16_t)vABCD, 1); + const vec_s16_t vB = vec_splat((vec_s16_t)vABCD, 3); + const vec_s16_t vC = vec_splat((vec_s16_t)vABCD, 5); + const vec_s16_t vD = vec_splat((vec_s16_t)vABCD, 7); + LOAD_ZERO; + const vec_s16_t v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4)); + const vec_u16_t v6us = vec_splat_u16(6); + register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1; register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0; - vector unsigned char vsrcAuc, vsrcBuc, vsrcperm0, vsrcperm1; - vector unsigned char vsrc0uc, vsrc1uc; - vector signed short vsrc0ssH, vsrc1ssH; - vector unsigned char vsrcCuc, vsrc2uc, vsrc3uc; - vector signed short vsrc2ssH, vsrc3ssH, psum; - vector unsigned char vdst, ppsum, fsum; + vec_u8_t vsrcAuc, vsrcBuc, vsrcperm0, vsrcperm1; + vec_u8_t vsrc0uc, vsrc1uc; + vec_s16_t vsrc0ssH, vsrc1ssH; + vec_u8_t vsrcCuc, vsrc2uc, vsrc3uc; + vec_s16_t vsrc2ssH, vsrc3ssH, psum; + vec_u8_t vdst, ppsum, fsum; if (((unsigned long)dst) % 16 == 0) { - fperm = (vector unsigned char)AVV(0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x08, 0x09, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0F); + fperm = (vec_u8_t)AVV(0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F); } else { - fperm = (vector unsigned char)AVV(0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F); + fperm = (vec_u8_t)AVV(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F); } vsrcAuc = vec_ld(0, src); if (loadSecond) - vsrcBuc = vec_ld(16, src); + vsrcBuc = vec_ld(16, src); vsrcperm0 = vec_lvsl(0, src); vsrcperm1 = vec_lvsl(1, src); vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0); if (reallyBadAlign) - vsrc1uc = vsrcBuc; + vsrc1uc = vsrcBuc; else - vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1); + vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1); - vsrc0ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc0uc); - vsrc1ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc1uc); + vsrc0ssH = (vec_s16_t)vec_mergeh(zero_u8v, (vec_u8_t)vsrc0uc); + vsrc1ssH = (vec_s16_t)vec_mergeh(zero_u8v, (vec_u8_t)vsrc1uc); if (!loadSecond) {// -> !reallyBadAlign - for (i = 0 ; i < h ; i++) { + for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(stride + 0, src); + vsrcCuc = vec_ld(stride + 0, src); - vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); - vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); + vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); + vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); - vsrc2ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc2uc); - vsrc3ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc3uc); + vsrc2ssH = (vec_s16_t)vec_mergeh(zero_u8v, (vec_u8_t)vsrc2uc); + vsrc3ssH = (vec_s16_t)vec_mergeh(zero_u8v, (vec_u8_t)vsrc3uc); - psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); - psum = vec_mladd(vB, vsrc1ssH, psum); - psum = vec_mladd(vC, vsrc2ssH, psum); - psum = vec_mladd(vD, vsrc3ssH, psum); - psum = vec_add(v28ss, psum); - psum = vec_sra(psum, v6us); + psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); + psum = vec_mladd(vB, vsrc1ssH, psum); + psum = vec_mladd(vC, vsrc2ssH, psum); + psum = vec_mladd(vD, vsrc3ssH, psum); + psum = vec_add(v28ss, psum); + psum = vec_sra(psum, v6us); - vdst = vec_ld(0, dst); - ppsum = (vector unsigned char)vec_packsu(psum, psum); - fsum = vec_perm(vdst, ppsum, fperm); + vdst = vec_ld(0, dst); + ppsum = (vec_u8_t)vec_packsu(psum, psum); + fsum = vec_perm(vdst, ppsum, fperm); - vec_st(fsum, 0, dst); + vec_st(fsum, 0, dst); - vsrc0ssH = vsrc2ssH; - vsrc1ssH = vsrc3ssH; + vsrc0ssH = vsrc2ssH; + vsrc1ssH = vsrc3ssH; - dst += stride; - src += stride; - } + dst += stride; + src += stride; + } } else { - vector unsigned char vsrcDuc; - for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(stride + 0, src); - vsrcDuc = vec_ld(stride + 16, src); - - vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); - if (reallyBadAlign) - vsrc3uc = vsrcDuc; - else - vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); - - vsrc2ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc2uc); - vsrc3ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc3uc); - - psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); - psum = vec_mladd(vB, vsrc1ssH, psum); - psum = vec_mladd(vC, vsrc2ssH, psum); - psum = vec_mladd(vD, vsrc3ssH, psum); - psum = vec_add(v28ss, psum); - psum = vec_sr(psum, v6us); - - vdst = vec_ld(0, dst); - ppsum = (vector unsigned char)vec_pack(psum, psum); - fsum = vec_perm(vdst, ppsum, fperm); - - vec_st(fsum, 0, dst); - - vsrc0ssH = vsrc2ssH; - vsrc1ssH = vsrc3ssH; - - dst += stride; - src += stride; - } + vec_u8_t vsrcDuc; + for (i = 0 ; i < h ; i++) { + vsrcCuc = vec_ld(stride + 0, src); + vsrcDuc = vec_ld(stride + 16, src); + + vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); + if (reallyBadAlign) + vsrc3uc = vsrcDuc; + else + vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); + + vsrc2ssH = (vec_s16_t)vec_mergeh(zero_u8v, (vec_u8_t)vsrc2uc); + vsrc3ssH = (vec_s16_t)vec_mergeh(zero_u8v, (vec_u8_t)vsrc3uc); + + psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); + psum = vec_mladd(vB, vsrc1ssH, psum); + psum = vec_mladd(vC, vsrc2ssH, psum); + psum = vec_mladd(vD, vsrc3ssH, psum); + psum = vec_add(v28ss, psum); + psum = vec_sr(psum, v6us); + + vdst = vec_ld(0, dst); + ppsum = (vec_u8_t)vec_pack(psum, psum); + fsum = vec_perm(vdst, ppsum, fperm); + + vec_st(fsum, 0, dst); + + vsrc0ssH = vsrc2ssH; + vsrc1ssH = vsrc3ssH; + + dst += stride; + src += stride; + } } } @@ -312,7 +308,7 @@ static inline void put_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, int src_stride1, int h) { int i; - vector unsigned char a, b, d, tmp1, tmp2, mask, mask_, edges, align; + vec_u8_t a, b, d, tmp1, tmp2, mask, mask_, edges, align; mask_ = vec_lvsl(0, src2); @@ -354,7 +350,7 @@ static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, int src_stride1, int h) { int i; - vector unsigned char a, b, d, tmp1, tmp2, mask, mask_, edges, align; + vec_u8_t a, b, d, tmp1, tmp2, mask, mask_, edges, align; mask_ = vec_lvsl(0, src2); @@ -404,6 +400,82 @@ static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1, * IDCT transform: ****************************************************************************/ +#define VEC_1D_DCT(vb0,vb1,vb2,vb3,va0,va1,va2,va3) \ + /* 1st stage */ \ + vz0 = vec_add(vb0,vb2); /* temp[0] = Y[0] + Y[2] */ \ + vz1 = vec_sub(vb0,vb2); /* temp[1] = Y[0] - Y[2] */ \ + vz2 = vec_sra(vb1,vec_splat_u16(1)); \ + vz2 = vec_sub(vz2,vb3); /* temp[2] = Y[1].1/2 - Y[3] */ \ + vz3 = vec_sra(vb3,vec_splat_u16(1)); \ + vz3 = vec_add(vb1,vz3); /* temp[3] = Y[1] + Y[3].1/2 */ \ + /* 2nd stage: output */ \ + va0 = vec_add(vz0,vz3); /* x[0] = temp[0] + temp[3] */ \ + va1 = vec_add(vz1,vz2); /* x[1] = temp[1] + temp[2] */ \ + va2 = vec_sub(vz1,vz2); /* x[2] = temp[1] - temp[2] */ \ + va3 = vec_sub(vz0,vz3) /* x[3] = temp[0] - temp[3] */ + +#define VEC_TRANSPOSE_4(a0,a1,a2,a3,b0,b1,b2,b3) \ + b0 = vec_mergeh( a0, a0 ); \ + b1 = vec_mergeh( a1, a0 ); \ + b2 = vec_mergeh( a2, a0 ); \ + b3 = vec_mergeh( a3, a0 ); \ + a0 = vec_mergeh( b0, b2 ); \ + a1 = vec_mergel( b0, b2 ); \ + a2 = vec_mergeh( b1, b3 ); \ + a3 = vec_mergel( b1, b3 ); \ + b0 = vec_mergeh( a0, a2 ); \ + b1 = vec_mergel( a0, a2 ); \ + b2 = vec_mergeh( a1, a3 ); \ + b3 = vec_mergel( a1, a3 ) + +#define VEC_LOAD_U8_ADD_S16_STORE_U8(va) \ + vdst_orig = vec_ld(0, dst); \ + vdst = vec_perm(vdst_orig, zero_u8v, vdst_mask); \ + vdst_ss = (vec_s16_t) vec_mergeh(zero_u8v, vdst); \ + va = vec_add(va, vdst_ss); \ + va_u8 = vec_packsu(va, zero_s16v); \ + va_u32 = vec_splat((vec_u32_t)va_u8, 0); \ + vec_ste(va_u32, element, (uint32_t*)dst); + +static void ff_h264_idct_add_altivec(uint8_t *dst, DCTELEM *block, int stride) +{ + vec_s16_t va0, va1, va2, va3; + vec_s16_t vz0, vz1, vz2, vz3; + vec_s16_t vtmp0, vtmp1, vtmp2, vtmp3; + vec_u8_t va_u8; + vec_u32_t va_u32; + vec_s16_t vdst_ss; + const vec_u16_t v6us = vec_splat_u16(6); + vec_u8_t vdst, vdst_orig; + vec_u8_t vdst_mask = vec_lvsl(0, dst); + int element = ((unsigned long)dst & 0xf) >> 2; + LOAD_ZERO; + + block[0] += 32; /* add 32 as a DC-level for rounding */ + + vtmp0 = vec_ld(0,block); + vtmp1 = vec_sld(vtmp0, vtmp0, 8); + vtmp2 = vec_ld(16,block); + vtmp3 = vec_sld(vtmp2, vtmp2, 8); + + VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3); + VEC_TRANSPOSE_4(va0,va1,va2,va3,vtmp0,vtmp1,vtmp2,vtmp3); + VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3); + + va0 = vec_sra(va0,v6us); + va1 = vec_sra(va1,v6us); + va2 = vec_sra(va2,v6us); + va3 = vec_sra(va3,v6us); + + VEC_LOAD_U8_ADD_S16_STORE_U8(va0); + dst += stride; + VEC_LOAD_U8_ADD_S16_STORE_U8(va1); + dst += stride; + VEC_LOAD_U8_ADD_S16_STORE_U8(va2); + dst += stride; + VEC_LOAD_U8_ADD_S16_STORE_U8(va3); +} + #define IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7, d0, d1, d2, d3, d4, d5, d6, d7) {\ /* a0 = SRC(0) + SRC(4); */ \ vec_s16_t a0v = vec_add(s0, s4); \ @@ -491,8 +563,7 @@ void ff_h264_idct8_add_altivec( uint8_t *dst, DCTELEM *dct, int stride ) { const vec_u16_t twov = vec_splat_u16(2); const vec_u16_t sixv = vec_splat_u16(6); - const vec_u8_t sel = (vec_u8_t) AVV(0,0,0,0,0,0,0,0, - -1,-1,-1,-1,-1,-1,-1,-1); + const vec_u8_t sel = (vec_u8_t) AVV(0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1); LOAD_ZERO; dct[0] += 32; // rounding for the >>6 at the end @@ -524,42 +595,310 @@ void ff_h264_idct8_add_altivec( uint8_t *dst, DCTELEM *dct, int stride ) { ALTIVEC_STORE_SUM_CLIP(&dst[7*stride], idct7, perm_ldv, perm_stv, sel); } +#define transpose4x16(r0, r1, r2, r3) { \ + register vec_u8_t r4; \ + register vec_u8_t r5; \ + register vec_u8_t r6; \ + register vec_u8_t r7; \ + \ + r4 = vec_mergeh(r0, r2); /*0, 2 set 0*/ \ + r5 = vec_mergel(r0, r2); /*0, 2 set 1*/ \ + r6 = vec_mergeh(r1, r3); /*1, 3 set 0*/ \ + r7 = vec_mergel(r1, r3); /*1, 3 set 1*/ \ + \ + r0 = vec_mergeh(r4, r6); /*all set 0*/ \ + r1 = vec_mergel(r4, r6); /*all set 1*/ \ + r2 = vec_mergeh(r5, r7); /*all set 2*/ \ + r3 = vec_mergel(r5, r7); /*all set 3*/ \ +} + +static inline void write16x4(uint8_t *dst, int dst_stride, + register vec_u8_t r0, register vec_u8_t r1, + register vec_u8_t r2, register vec_u8_t r3) { + DECLARE_ALIGNED_16(unsigned char, result[64]); + uint32_t *src_int = (uint32_t *)result, *dst_int = (uint32_t *)dst; + int int_dst_stride = dst_stride/4; + + vec_st(r0, 0, result); + vec_st(r1, 16, result); + vec_st(r2, 32, result); + vec_st(r3, 48, result); + /* FIXME: there has to be a better way!!!! */ + *dst_int = *src_int; + *(dst_int+ int_dst_stride) = *(src_int + 1); + *(dst_int+ 2*int_dst_stride) = *(src_int + 2); + *(dst_int+ 3*int_dst_stride) = *(src_int + 3); + *(dst_int+ 4*int_dst_stride) = *(src_int + 4); + *(dst_int+ 5*int_dst_stride) = *(src_int + 5); + *(dst_int+ 6*int_dst_stride) = *(src_int + 6); + *(dst_int+ 7*int_dst_stride) = *(src_int + 7); + *(dst_int+ 8*int_dst_stride) = *(src_int + 8); + *(dst_int+ 9*int_dst_stride) = *(src_int + 9); + *(dst_int+10*int_dst_stride) = *(src_int + 10); + *(dst_int+11*int_dst_stride) = *(src_int + 11); + *(dst_int+12*int_dst_stride) = *(src_int + 12); + *(dst_int+13*int_dst_stride) = *(src_int + 13); + *(dst_int+14*int_dst_stride) = *(src_int + 14); + *(dst_int+15*int_dst_stride) = *(src_int + 15); +} + +/** \brief performs a 6x16 transpose of data in src, and stores it to dst + \todo FIXME: see if we can't spare some vec_lvsl() by them factorizing + out of unaligned_load() */ +#define readAndTranspose16x6(src, src_stride, r8, r9, r10, r11, r12, r13) {\ + register vec_u8_t r0 = unaligned_load(0, src); \ + register vec_u8_t r1 = unaligned_load( src_stride, src); \ + register vec_u8_t r2 = unaligned_load(2* src_stride, src); \ + register vec_u8_t r3 = unaligned_load(3* src_stride, src); \ + register vec_u8_t r4 = unaligned_load(4* src_stride, src); \ + register vec_u8_t r5 = unaligned_load(5* src_stride, src); \ + register vec_u8_t r6 = unaligned_load(6* src_stride, src); \ + register vec_u8_t r7 = unaligned_load(7* src_stride, src); \ + register vec_u8_t r14 = unaligned_load(14*src_stride, src); \ + register vec_u8_t r15 = unaligned_load(15*src_stride, src); \ + \ + r8 = unaligned_load( 8*src_stride, src); \ + r9 = unaligned_load( 9*src_stride, src); \ + r10 = unaligned_load(10*src_stride, src); \ + r11 = unaligned_load(11*src_stride, src); \ + r12 = unaligned_load(12*src_stride, src); \ + r13 = unaligned_load(13*src_stride, src); \ + \ + /*Merge first pairs*/ \ + r0 = vec_mergeh(r0, r8); /*0, 8*/ \ + r1 = vec_mergeh(r1, r9); /*1, 9*/ \ + r2 = vec_mergeh(r2, r10); /*2,10*/ \ + r3 = vec_mergeh(r3, r11); /*3,11*/ \ + r4 = vec_mergeh(r4, r12); /*4,12*/ \ + r5 = vec_mergeh(r5, r13); /*5,13*/ \ + r6 = vec_mergeh(r6, r14); /*6,14*/ \ + r7 = vec_mergeh(r7, r15); /*7,15*/ \ + \ + /*Merge second pairs*/ \ + r8 = vec_mergeh(r0, r4); /*0,4, 8,12 set 0*/ \ + r9 = vec_mergel(r0, r4); /*0,4, 8,12 set 1*/ \ + r10 = vec_mergeh(r1, r5); /*1,5, 9,13 set 0*/ \ + r11 = vec_mergel(r1, r5); /*1,5, 9,13 set 1*/ \ + r12 = vec_mergeh(r2, r6); /*2,6,10,14 set 0*/ \ + r13 = vec_mergel(r2, r6); /*2,6,10,14 set 1*/ \ + r14 = vec_mergeh(r3, r7); /*3,7,11,15 set 0*/ \ + r15 = vec_mergel(r3, r7); /*3,7,11,15 set 1*/ \ + \ + /*Third merge*/ \ + r0 = vec_mergeh(r8, r12); /*0,2,4,6,8,10,12,14 set 0*/ \ + r1 = vec_mergel(r8, r12); /*0,2,4,6,8,10,12,14 set 1*/ \ + r2 = vec_mergeh(r9, r13); /*0,2,4,6,8,10,12,14 set 2*/ \ + r4 = vec_mergeh(r10, r14); /*1,3,5,7,9,11,13,15 set 0*/ \ + r5 = vec_mergel(r10, r14); /*1,3,5,7,9,11,13,15 set 1*/ \ + r6 = vec_mergeh(r11, r15); /*1,3,5,7,9,11,13,15 set 2*/ \ + /* Don't need to compute 3 and 7*/ \ + \ + /*Final merge*/ \ + r8 = vec_mergeh(r0, r4); /*all set 0*/ \ + r9 = vec_mergel(r0, r4); /*all set 1*/ \ + r10 = vec_mergeh(r1, r5); /*all set 2*/ \ + r11 = vec_mergel(r1, r5); /*all set 3*/ \ + r12 = vec_mergeh(r2, r6); /*all set 4*/ \ + r13 = vec_mergel(r2, r6); /*all set 5*/ \ + /* Don't need to compute 14 and 15*/ \ + \ +} + +// out: o = |x-y| < a +static inline vec_u8_t diff_lt_altivec ( register vec_u8_t x, + register vec_u8_t y, + register vec_u8_t a) { + + register vec_u8_t diff = vec_subs(x, y); + register vec_u8_t diffneg = vec_subs(y, x); + register vec_u8_t o = vec_or(diff, diffneg); /* |x-y| */ + o = (vec_u8_t)vec_cmplt(o, a); + return o; +} + +static inline vec_u8_t h264_deblock_mask ( register vec_u8_t p0, + register vec_u8_t p1, + register vec_u8_t q0, + register vec_u8_t q1, + register vec_u8_t alpha, + register vec_u8_t beta) { + + register vec_u8_t mask; + register vec_u8_t tempmask; + + mask = diff_lt_altivec(p0, q0, alpha); + tempmask = diff_lt_altivec(p1, p0, beta); + mask = vec_and(mask, tempmask); + tempmask = diff_lt_altivec(q1, q0, beta); + mask = vec_and(mask, tempmask); + + return mask; +} + +// out: newp1 = clip((p2 + ((p0 + q0 + 1) >> 1)) >> 1, p1-tc0, p1+tc0) +static inline vec_u8_t h264_deblock_q1(register vec_u8_t p0, + register vec_u8_t p1, + register vec_u8_t p2, + register vec_u8_t q0, + register vec_u8_t tc0) { + + register vec_u8_t average = vec_avg(p0, q0); + register vec_u8_t temp; + register vec_u8_t uncliped; + register vec_u8_t ones; + register vec_u8_t max; + register vec_u8_t min; + register vec_u8_t newp1; + + temp = vec_xor(average, p2); + average = vec_avg(average, p2); /*avg(p2, avg(p0, q0)) */ + ones = vec_splat_u8(1); + temp = vec_and(temp, ones); /*(p2^avg(p0, q0)) & 1 */ + uncliped = vec_subs(average, temp); /*(p2+((p0+q0+1)>>1))>>1 */ + max = vec_adds(p1, tc0); + min = vec_subs(p1, tc0); + newp1 = vec_max(min, uncliped); + newp1 = vec_min(max, newp1); + return newp1; +} + +#define h264_deblock_p0_q0(p0, p1, q0, q1, tc0masked) { \ + \ + const vec_u8_t A0v = vec_sl(vec_splat_u8(10), vec_splat_u8(4)); \ + \ + register vec_u8_t pq0bit = vec_xor(p0,q0); \ + register vec_u8_t q1minus; \ + register vec_u8_t p0minus; \ + register vec_u8_t stage1; \ + register vec_u8_t stage2; \ + register vec_u8_t vec160; \ + register vec_u8_t delta; \ + register vec_u8_t deltaneg; \ + \ + q1minus = vec_nor(q1, q1); /* 255 - q1 */ \ + stage1 = vec_avg(p1, q1minus); /* (p1 - q1 + 256)>>1 */ \ + stage2 = vec_sr(stage1, vec_splat_u8(1)); /* (p1 - q1 + 256)>>2 = 64 + (p1 - q1) >> 2 */ \ + p0minus = vec_nor(p0, p0); /* 255 - p0 */ \ + stage1 = vec_avg(q0, p0minus); /* (q0 - p0 + 256)>>1 */ \ + pq0bit = vec_and(pq0bit, vec_splat_u8(1)); \ + stage2 = vec_avg(stage2, pq0bit); /* 32 + ((q0 - p0)&1 + (p1 - q1) >> 2 + 1) >> 1 */ \ + stage2 = vec_adds(stage2, stage1); /* 160 + ((p0 - q0) + (p1 - q1) >> 2 + 1) >> 1 */ \ + vec160 = vec_ld(0, &A0v); \ + deltaneg = vec_subs(vec160, stage2); /* -d */ \ + delta = vec_subs(stage2, vec160); /* d */ \ + deltaneg = vec_min(tc0masked, deltaneg); \ + delta = vec_min(tc0masked, delta); \ + p0 = vec_subs(p0, deltaneg); \ + q0 = vec_subs(q0, delta); \ + p0 = vec_adds(p0, delta); \ + q0 = vec_adds(q0, deltaneg); \ +} + +#define h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0) { \ + DECLARE_ALIGNED_16(unsigned char, temp[16]); \ + register vec_u8_t alphavec; \ + register vec_u8_t betavec; \ + register vec_u8_t mask; \ + register vec_u8_t p1mask; \ + register vec_u8_t q1mask; \ + register vector signed char tc0vec; \ + register vec_u8_t finaltc0; \ + register vec_u8_t tc0masked; \ + register vec_u8_t newp1; \ + register vec_u8_t newq1; \ + \ + temp[0] = alpha; \ + temp[1] = beta; \ + alphavec = vec_ld(0, temp); \ + betavec = vec_splat(alphavec, 0x1); \ + alphavec = vec_splat(alphavec, 0x0); \ + mask = h264_deblock_mask(p0, p1, q0, q1, alphavec, betavec); /*if in block */ \ + \ + *((int *)temp) = *((int *)tc0); \ + tc0vec = vec_ld(0, (signed char*)temp); \ + tc0vec = vec_mergeh(tc0vec, tc0vec); \ + tc0vec = vec_mergeh(tc0vec, tc0vec); \ + mask = vec_and(mask, vec_cmpgt(tc0vec, vec_splat_s8(-1))); /* if tc0[i] >= 0 */ \ + finaltc0 = vec_and((vec_u8_t)tc0vec, mask); /* tc = tc0 */ \ + \ + p1mask = diff_lt_altivec(p2, p0, betavec); \ + p1mask = vec_and(p1mask, mask); /* if ( |p2 - p0| < beta) */ \ + tc0masked = vec_and(p1mask, (vec_u8_t)tc0vec); \ + finaltc0 = vec_sub(finaltc0, p1mask); /* tc++ */ \ + newp1 = h264_deblock_q1(p0, p1, p2, q0, tc0masked); \ + /*end if*/ \ + \ + q1mask = diff_lt_altivec(q2, q0, betavec); \ + q1mask = vec_and(q1mask, mask); /* if ( |q2 - q0| < beta ) */\ + tc0masked = vec_and(q1mask, (vec_u8_t)tc0vec); \ + finaltc0 = vec_sub(finaltc0, q1mask); /* tc++ */ \ + newq1 = h264_deblock_q1(p0, q1, q2, q0, tc0masked); \ + /*end if*/ \ + \ + h264_deblock_p0_q0(p0, p1, q0, q1, finaltc0); \ + p1 = newp1; \ + q1 = newq1; \ +} + +static void h264_v_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) { + + if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) >= 0) { + register vec_u8_t p2 = vec_ld(-3*stride, pix); + register vec_u8_t p1 = vec_ld(-2*stride, pix); + register vec_u8_t p0 = vec_ld(-1*stride, pix); + register vec_u8_t q0 = vec_ld(0, pix); + register vec_u8_t q1 = vec_ld(stride, pix); + register vec_u8_t q2 = vec_ld(2*stride, pix); + h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0); + vec_st(p1, -2*stride, pix); + vec_st(p0, -1*stride, pix); + vec_st(q0, 0, pix); + vec_st(q1, stride, pix); + } +} + +static void h264_h_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) { + + register vec_u8_t line0, line1, line2, line3, line4, line5; + if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) < 0) + return; + readAndTranspose16x6(pix-3, stride, line0, line1, line2, line3, line4, line5); + h264_loop_filter_luma_altivec(line0, line1, line2, line3, line4, line5, alpha, beta, tc0); + transpose4x16(line1, line2, line3, line4); + write16x4(pix-2, stride, line1, line2, line3, line4); +} + void dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx) { -#ifdef HAVE_ALTIVEC - if (has_altivec()) { - c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec; - c->put_no_rnd_h264_chroma_pixels_tab[0] = put_no_rnd_h264_chroma_mc8_altivec; - c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec; - c->h264_idct8_add = ff_h264_idct8_add_altivec; + if (has_altivec()) { + c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec; + c->put_no_rnd_h264_chroma_pixels_tab[0] = put_no_rnd_h264_chroma_mc8_altivec; + c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec; + c->h264_idct_add = ff_h264_idct_add_altivec; + c->h264_idct8_add = ff_h264_idct8_add_altivec; + c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_altivec; + c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_altivec; #define dspfunc(PFX, IDX, NUM) \ - c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \ - c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \ - c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \ - c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \ - c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \ - c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \ - c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \ - c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \ - c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \ - c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \ - c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \ - c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \ - c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \ - c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \ - c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \ - c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec - - dspfunc(put_h264_qpel, 0, 16); - dspfunc(avg_h264_qpel, 0, 16); + c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \ + c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \ + c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \ + c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \ + c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \ + c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \ + c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \ + c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \ + c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \ + c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \ + c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \ + c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \ + c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \ + c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \ + c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \ + c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec + + dspfunc(put_h264_qpel, 0, 16); + dspfunc(avg_h264_qpel, 0, 16); #undef dspfunc - - } else -#endif /* HAVE_ALTIVEC */ - { - // Non-AltiVec PPC optimisations - - // ... pending ... - } + } } diff --git a/contrib/ffmpeg/libavcodec/ppc/h264_template_altivec.c b/contrib/ffmpeg/libavcodec/ppc/h264_template_altivec.c index e8ad67f2f..d8ad96419 100644 --- a/contrib/ffmpeg/libavcodec/ppc/h264_template_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/h264_template_altivec.c @@ -18,186 +18,227 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +//#define DEBUG_ALIGNMENT +#ifdef DEBUG_ALIGNMENT +#define ASSERT_ALIGNED(ptr) assert(((unsigned long)ptr&0x0000000F)); +#else +#define ASSERT_ALIGNED(ptr) ; +#endif + /* this code assume that stride % 16 == 0 */ -void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) { + +#define CHROMA_MC8_ALTIVEC_CORE \ + vsrc2ssH = (vec_s16_t)vec_mergeh(zero_u8v,(vec_u8_t)vsrc2uc);\ + vsrc3ssH = (vec_s16_t)vec_mergeh(zero_u8v,(vec_u8_t)vsrc3uc);\ +\ + psum = vec_mladd(vA, vsrc0ssH, v32ss);\ + psum = vec_mladd(vB, vsrc1ssH, psum);\ + psum = vec_mladd(vC, vsrc2ssH, psum);\ + psum = vec_mladd(vD, vsrc3ssH, psum);\ + psum = vec_sr(psum, v6us);\ +\ + vdst = vec_ld(0, dst);\ + ppsum = (vec_u8_t)vec_pack(psum, psum);\ + vfdst = vec_perm(vdst, ppsum, fperm);\ +\ + OP_U8_ALTIVEC(fsum, vfdst, vdst);\ +\ + vec_st(fsum, 0, dst);\ +\ + vsrc0ssH = vsrc2ssH;\ + vsrc1ssH = vsrc3ssH;\ +\ + dst += stride;\ + src += stride; + +#define CHROMA_MC8_ALTIVEC_CORE_SIMPLE \ +\ + vsrc0ssH = (vec_s16_t)vec_mergeh(zero_u8v,(vec_u8_t)vsrc0uc);\ + vsrc1ssH = (vec_s16_t)vec_mergeh(zero_u8v,(vec_u8_t)vsrc1uc);\ +\ + psum = vec_mladd(vA, vsrc0ssH, v32ss);\ + psum = vec_mladd(vE, vsrc1ssH, psum);\ + psum = vec_sr(psum, v6us);\ +\ + vdst = vec_ld(0, dst);\ + ppsum = (vec_u8_t)vec_pack(psum, psum);\ + vfdst = vec_perm(vdst, ppsum, fperm);\ +\ + OP_U8_ALTIVEC(fsum, vfdst, vdst);\ +\ + vec_st(fsum, 0, dst);\ +\ + dst += stride;\ + src += stride; + +void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, + int stride, int h, int x, int y) { POWERPC_PERF_DECLARE(PREFIX_h264_chroma_mc8_num, 1); - signed int ABCD[4] __attribute__((aligned(16))) = + DECLARE_ALIGNED_16(signed int, ABCD[4]) = {((8 - x) * (8 - y)), - ((x) * (8 - y)), - ((8 - x) * (y)), - ((x) * (y))}; + (( x) * (8 - y)), + ((8 - x) * ( y)), + (( x) * ( y))}; register int i; - vector unsigned char fperm; - const vector signed int vABCD = vec_ld(0, ABCD); - const vector signed short vA = vec_splat((vector signed short)vABCD, 1); - const vector signed short vB = vec_splat((vector signed short)vABCD, 3); - const vector signed short vC = vec_splat((vector signed short)vABCD, 5); - const vector signed short vD = vec_splat((vector signed short)vABCD, 7); - const vector signed int vzero = vec_splat_s32(0); - const vector signed short v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5)); - const vector unsigned short v6us = vec_splat_u16(6); + vec_u8_t fperm; + const vec_s32_t vABCD = vec_ld(0, ABCD); + const vec_s16_t vA = vec_splat((vec_s16_t)vABCD, 1); + const vec_s16_t vB = vec_splat((vec_s16_t)vABCD, 3); + const vec_s16_t vC = vec_splat((vec_s16_t)vABCD, 5); + const vec_s16_t vD = vec_splat((vec_s16_t)vABCD, 7); + LOAD_ZERO; + const vec_s16_t v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5)); + const vec_u16_t v6us = vec_splat_u16(6); register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1; register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0; - vector unsigned char vsrcAuc, vsrcBuc, vsrcperm0, vsrcperm1; - vector unsigned char vsrc0uc, vsrc1uc; - vector signed short vsrc0ssH, vsrc1ssH; - vector unsigned char vsrcCuc, vsrc2uc, vsrc3uc; - vector signed short vsrc2ssH, vsrc3ssH, psum; - vector unsigned char vdst, ppsum, vfdst, fsum; + vec_u8_t vsrcAuc, vsrcBuc, vsrcperm0, vsrcperm1; + vec_u8_t vsrc0uc, vsrc1uc; + vec_s16_t vsrc0ssH, vsrc1ssH; + vec_u8_t vsrcCuc, vsrc2uc, vsrc3uc; + vec_s16_t vsrc2ssH, vsrc3ssH, psum; + vec_u8_t vdst, ppsum, vfdst, fsum; POWERPC_PERF_START_COUNT(PREFIX_h264_chroma_mc8_num, 1); if (((unsigned long)dst) % 16 == 0) { - fperm = (vector unsigned char)AVV(0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, - 0x08, 0x09, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0F); + fperm = (vec_u8_t)AVV(0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, + 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F); } else { - fperm = (vector unsigned char)AVV(0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, - 0x18, 0x19, 0x1A, 0x1B, - 0x1C, 0x1D, 0x1E, 0x1F); + fperm = (vec_u8_t)AVV(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x18, 0x19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F); } vsrcAuc = vec_ld(0, src); if (loadSecond) - vsrcBuc = vec_ld(16, src); + vsrcBuc = vec_ld(16, src); vsrcperm0 = vec_lvsl(0, src); vsrcperm1 = vec_lvsl(1, src); vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0); if (reallyBadAlign) - vsrc1uc = vsrcBuc; + vsrc1uc = vsrcBuc; else - vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1); - - vsrc0ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc0uc); - vsrc1ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc1uc); - - if (!loadSecond) {// -> !reallyBadAlign - for (i = 0 ; i < h ; i++) { - - - vsrcCuc = vec_ld(stride + 0, src); - - vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); - vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); - - vsrc2ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc2uc); - vsrc3ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc3uc); - - psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); - psum = vec_mladd(vB, vsrc1ssH, psum); - psum = vec_mladd(vC, vsrc2ssH, psum); - psum = vec_mladd(vD, vsrc3ssH, psum); - psum = vec_add(v32ss, psum); - psum = vec_sra(psum, v6us); - - vdst = vec_ld(0, dst); - ppsum = (vector unsigned char)vec_packsu(psum, psum); - vfdst = vec_perm(vdst, ppsum, fperm); - - OP_U8_ALTIVEC(fsum, vfdst, vdst); - - vec_st(fsum, 0, dst); - - vsrc0ssH = vsrc2ssH; - vsrc1ssH = vsrc3ssH; - - dst += stride; - src += stride; - } + vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1); + + vsrc0ssH = (vec_s16_t)vec_mergeh(zero_u8v,(vec_u8_t)vsrc0uc); + vsrc1ssH = (vec_s16_t)vec_mergeh(zero_u8v,(vec_u8_t)vsrc1uc); + + if (ABCD[3]) { + if (!loadSecond) {// -> !reallyBadAlign + for (i = 0 ; i < h ; i++) { + vsrcCuc = vec_ld(stride + 0, src); + vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); + vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); + + CHROMA_MC8_ALTIVEC_CORE + } + } else { + vec_u8_t vsrcDuc; + for (i = 0 ; i < h ; i++) { + vsrcCuc = vec_ld(stride + 0, src); + vsrcDuc = vec_ld(stride + 16, src); + vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); + if (reallyBadAlign) + vsrc3uc = vsrcDuc; + else + vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); + + CHROMA_MC8_ALTIVEC_CORE + } + } } else { - vector unsigned char vsrcDuc; - for (i = 0 ; i < h ; i++) { - vsrcCuc = vec_ld(stride + 0, src); - vsrcDuc = vec_ld(stride + 16, src); - - vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); - if (reallyBadAlign) - vsrc3uc = vsrcDuc; - else - vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); - - vsrc2ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc2uc); - vsrc3ssH = (vector signed short)vec_mergeh((vector unsigned char)vzero, - (vector unsigned char)vsrc3uc); - - psum = vec_mladd(vA, vsrc0ssH, vec_splat_s16(0)); - psum = vec_mladd(vB, vsrc1ssH, psum); - psum = vec_mladd(vC, vsrc2ssH, psum); - psum = vec_mladd(vD, vsrc3ssH, psum); - psum = vec_add(v32ss, psum); - psum = vec_sr(psum, v6us); - - vdst = vec_ld(0, dst); - ppsum = (vector unsigned char)vec_pack(psum, psum); - vfdst = vec_perm(vdst, ppsum, fperm); - - OP_U8_ALTIVEC(fsum, vfdst, vdst); - - vec_st(fsum, 0, dst); - - vsrc0ssH = vsrc2ssH; - vsrc1ssH = vsrc3ssH; - - dst += stride; - src += stride; - } + const vec_s16_t vE = vec_add(vB, vC); + if (ABCD[2]) { // x == 0 B == 0 + if (!loadSecond) {// -> !reallyBadAlign + for (i = 0 ; i < h ; i++) { + vsrcCuc = vec_ld(stride + 0, src); + vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); + CHROMA_MC8_ALTIVEC_CORE_SIMPLE + + vsrc0uc = vsrc1uc; + } + } else { + vec_u8_t vsrcDuc; + for (i = 0 ; i < h ; i++) { + vsrcCuc = vec_ld(stride + 0, src); + vsrcDuc = vec_ld(stride + 15, src); + vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); + CHROMA_MC8_ALTIVEC_CORE_SIMPLE + + vsrc0uc = vsrc1uc; + } + } + } else { // y == 0 C == 0 + if (!loadSecond) {// -> !reallyBadAlign + for (i = 0 ; i < h ; i++) { + vsrcCuc = vec_ld(0, src); + vsrc0uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0); + vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1); + + CHROMA_MC8_ALTIVEC_CORE_SIMPLE + } + } else { + vec_u8_t vsrcDuc; + for (i = 0 ; i < h ; i++) { + vsrcCuc = vec_ld(0, src); + vsrcDuc = vec_ld(15, src); + vsrc0uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0); + if (reallyBadAlign) + vsrc1uc = vsrcDuc; + else + vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1); + + CHROMA_MC8_ALTIVEC_CORE_SIMPLE + } + } + } } POWERPC_PERF_STOP_COUNT(PREFIX_h264_chroma_mc8_num, 1); } +#undef CHROMA_MC8_ALTIVEC_CORE + /* this code assume stride % 16 == 0 */ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) { POWERPC_PERF_DECLARE(PREFIX_h264_qpel16_h_lowpass_num, 1); register int i; - const vector signed int vzero = vec_splat_s32(0); - const vector unsigned char permM2 = vec_lvsl(-2, src); - const vector unsigned char permM1 = vec_lvsl(-1, src); - const vector unsigned char permP0 = vec_lvsl(+0, src); - const vector unsigned char permP1 = vec_lvsl(+1, src); - const vector unsigned char permP2 = vec_lvsl(+2, src); - const vector unsigned char permP3 = vec_lvsl(+3, src); - const vector signed short v5ss = vec_splat_s16(5); - const vector unsigned short v5us = vec_splat_u16(5); - const vector signed short v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); - const vector signed short v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); - const vector unsigned char dstperm = vec_lvsr(0, dst); - const vector unsigned char neg1 = - (const vector unsigned char) vec_splat_s8(-1); - - const vector unsigned char dstmask = - vec_perm((const vector unsigned char)vzero, - neg1, dstperm); - - vector unsigned char srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; + LOAD_ZERO; + const vec_u8_t permM2 = vec_lvsl(-2, src); + const vec_u8_t permM1 = vec_lvsl(-1, src); + const vec_u8_t permP0 = vec_lvsl(+0, src); + const vec_u8_t permP1 = vec_lvsl(+1, src); + const vec_u8_t permP2 = vec_lvsl(+2, src); + const vec_u8_t permP3 = vec_lvsl(+3, src); + const vec_s16_t v5ss = vec_splat_s16(5); + const vec_u16_t v5us = vec_splat_u16(5); + const vec_s16_t v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); + const vec_s16_t v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); + + vec_u8_t srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; register int align = ((((unsigned long)src) - 2) % 16); - vector signed short srcP0A, srcP0B, srcP1A, srcP1B, + vec_s16_t srcP0A, srcP0B, srcP1A, srcP1B, srcP2A, srcP2B, srcP3A, srcP3B, srcM1A, srcM1B, srcM2A, srcM2B, sum1A, sum1B, sum2A, sum2B, sum3A, sum3B, pp1A, pp1B, pp2A, pp2B, pp3A, pp3B, psumA, psumB, sumA, sumB; - vector unsigned char sum, dst1, dst2, vdst, fsum, - rsum, fdst1, fdst2; + vec_u8_t sum, vdst, fsum; POWERPC_PERF_START_COUNT(PREFIX_h264_qpel16_h_lowpass_num, 1); for (i = 0 ; i < 16 ; i ++) { - vector unsigned char srcR1 = vec_ld(-2, src); - vector unsigned char srcR2 = vec_ld(14, src); + vec_u8_t srcR1 = vec_ld(-2, src); + vec_u8_t srcR2 = vec_ld(14, src); switch (align) { default: { @@ -217,7 +258,7 @@ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, i srcP3 = srcR2; } break; case 12: { - vector unsigned char srcR3 = vec_ld(30, src); + vec_u8_t srcR3 = vec_ld(30, src); srcM2 = vec_perm(srcR1, srcR2, permM2); srcM1 = vec_perm(srcR1, srcR2, permM1); srcP0 = vec_perm(srcR1, srcR2, permP0); @@ -226,7 +267,7 @@ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, i srcP3 = vec_perm(srcR2, srcR3, permP3); } break; case 13: { - vector unsigned char srcR3 = vec_ld(30, src); + vec_u8_t srcR3 = vec_ld(30, src); srcM2 = vec_perm(srcR1, srcR2, permM2); srcM1 = vec_perm(srcR1, srcR2, permM1); srcP0 = vec_perm(srcR1, srcR2, permP0); @@ -235,7 +276,7 @@ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, i srcP3 = vec_perm(srcR2, srcR3, permP3); } break; case 14: { - vector unsigned char srcR3 = vec_ld(30, src); + vec_u8_t srcR3 = vec_ld(30, src); srcM2 = vec_perm(srcR1, srcR2, permM2); srcM1 = vec_perm(srcR1, srcR2, permM1); srcP0 = srcR2; @@ -244,7 +285,7 @@ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, i srcP3 = vec_perm(srcR2, srcR3, permP3); } break; case 15: { - vector unsigned char srcR3 = vec_ld(30, src); + vec_u8_t srcR3 = vec_ld(30, src); srcM2 = vec_perm(srcR1, srcR2, permM2); srcM1 = srcR2; srcP0 = vec_perm(srcR2, srcR3, permP0); @@ -254,32 +295,20 @@ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, i } break; } - srcP0A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP0); - srcP0B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP0); - srcP1A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP1); - srcP1B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP1); - - srcP2A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP2); - srcP2B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP2); - srcP3A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP3); - srcP3B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP3); - - srcM1A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcM1); - srcM1B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcM1); - srcM2A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcM2); - srcM2B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcM2); + srcP0A = (vec_s16_t) vec_mergeh(zero_u8v, srcP0); + srcP0B = (vec_s16_t) vec_mergel(zero_u8v, srcP0); + srcP1A = (vec_s16_t) vec_mergeh(zero_u8v, srcP1); + srcP1B = (vec_s16_t) vec_mergel(zero_u8v, srcP1); + + srcP2A = (vec_s16_t) vec_mergeh(zero_u8v, srcP2); + srcP2B = (vec_s16_t) vec_mergel(zero_u8v, srcP2); + srcP3A = (vec_s16_t) vec_mergeh(zero_u8v, srcP3); + srcP3B = (vec_s16_t) vec_mergel(zero_u8v, srcP3); + + srcM1A = (vec_s16_t) vec_mergeh(zero_u8v, srcM1); + srcM1B = (vec_s16_t) vec_mergel(zero_u8v, srcM1); + srcM2A = (vec_s16_t) vec_mergeh(zero_u8v, srcM2); + srcM2B = (vec_s16_t) vec_mergel(zero_u8v, srcM2); sum1A = vec_adds(srcP0A, srcP1A); sum1B = vec_adds(srcP0B, srcP1B); @@ -291,8 +320,8 @@ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, i pp1A = vec_mladd(sum1A, v20ss, v16ss); pp1B = vec_mladd(sum1B, v20ss, v16ss); - pp2A = vec_mladd(sum2A, v5ss, (vector signed short)vzero); - pp2B = vec_mladd(sum2B, v5ss, (vector signed short)vzero); + pp2A = vec_mladd(sum2A, v5ss, zero_s16v); + pp2B = vec_mladd(sum2B, v5ss, zero_s16v); pp3A = vec_add(sum3A, pp1A); pp3B = vec_add(sum3B, pp1B); @@ -305,18 +334,12 @@ static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, i sum = vec_packsu(sumA, sumB); - dst1 = vec_ld(0, dst); - dst2 = vec_ld(16, dst); - vdst = vec_perm(dst1, dst2, vec_lvsl(0, dst)); + ASSERT_ALIGNED(dst); + vdst = vec_ld(0, dst); OP_U8_ALTIVEC(fsum, sum, vdst); - rsum = vec_perm(fsum, fsum, dstperm); - fdst1 = vec_sel(dst1, rsum, dstmask); - fdst2 = vec_sel(rsum, dst2, dstmask); - - vec_st(fdst1, 0, dst); - vec_st(fdst2, 16, dst); + vec_st(fsum, 0, dst); src += srcStride; dst += dstStride; @@ -330,67 +353,53 @@ static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, i register int i; - const vector signed int vzero = vec_splat_s32(0); - const vector unsigned char perm = vec_lvsl(0, src); - const vector signed short v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); - const vector unsigned short v5us = vec_splat_u16(5); - const vector signed short v5ss = vec_splat_s16(5); - const vector signed short v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); - const vector unsigned char dstperm = vec_lvsr(0, dst); - const vector unsigned char neg1 = (const vector unsigned char)vec_splat_s8(-1); - const vector unsigned char dstmask = vec_perm((const vector unsigned char)vzero, neg1, dstperm); + LOAD_ZERO; + const vec_u8_t perm = vec_lvsl(0, src); + const vec_s16_t v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); + const vec_u16_t v5us = vec_splat_u16(5); + const vec_s16_t v5ss = vec_splat_s16(5); + const vec_s16_t v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4)); uint8_t *srcbis = src - (srcStride * 2); - const vector unsigned char srcM2a = vec_ld(0, srcbis); - const vector unsigned char srcM2b = vec_ld(16, srcbis); - const vector unsigned char srcM2 = vec_perm(srcM2a, srcM2b, perm); + const vec_u8_t srcM2a = vec_ld(0, srcbis); + const vec_u8_t srcM2b = vec_ld(16, srcbis); + const vec_u8_t srcM2 = vec_perm(srcM2a, srcM2b, perm); // srcbis += srcStride; - const vector unsigned char srcM1a = vec_ld(0, srcbis += srcStride); - const vector unsigned char srcM1b = vec_ld(16, srcbis); - const vector unsigned char srcM1 = vec_perm(srcM1a, srcM1b, perm); + const vec_u8_t srcM1a = vec_ld(0, srcbis += srcStride); + const vec_u8_t srcM1b = vec_ld(16, srcbis); + const vec_u8_t srcM1 = vec_perm(srcM1a, srcM1b, perm); // srcbis += srcStride; - const vector unsigned char srcP0a = vec_ld(0, srcbis += srcStride); - const vector unsigned char srcP0b = vec_ld(16, srcbis); - const vector unsigned char srcP0 = vec_perm(srcP0a, srcP0b, perm); + const vec_u8_t srcP0a = vec_ld(0, srcbis += srcStride); + const vec_u8_t srcP0b = vec_ld(16, srcbis); + const vec_u8_t srcP0 = vec_perm(srcP0a, srcP0b, perm); // srcbis += srcStride; - const vector unsigned char srcP1a = vec_ld(0, srcbis += srcStride); - const vector unsigned char srcP1b = vec_ld(16, srcbis); - const vector unsigned char srcP1 = vec_perm(srcP1a, srcP1b, perm); + const vec_u8_t srcP1a = vec_ld(0, srcbis += srcStride); + const vec_u8_t srcP1b = vec_ld(16, srcbis); + const vec_u8_t srcP1 = vec_perm(srcP1a, srcP1b, perm); // srcbis += srcStride; - const vector unsigned char srcP2a = vec_ld(0, srcbis += srcStride); - const vector unsigned char srcP2b = vec_ld(16, srcbis); - const vector unsigned char srcP2 = vec_perm(srcP2a, srcP2b, perm); + const vec_u8_t srcP2a = vec_ld(0, srcbis += srcStride); + const vec_u8_t srcP2b = vec_ld(16, srcbis); + const vec_u8_t srcP2 = vec_perm(srcP2a, srcP2b, perm); // srcbis += srcStride; - vector signed short srcM2ssA = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcM2); - vector signed short srcM2ssB = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcM2); - vector signed short srcM1ssA = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcM1); - vector signed short srcM1ssB = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcM1); - vector signed short srcP0ssA = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP0); - vector signed short srcP0ssB = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP0); - vector signed short srcP1ssA = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP1); - vector signed short srcP1ssB = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP1); - vector signed short srcP2ssA = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP2); - vector signed short srcP2ssB = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP2); - - vector signed short pp1A, pp1B, pp2A, pp2B, pp3A, pp3B, + vec_s16_t srcM2ssA = (vec_s16_t) vec_mergeh(zero_u8v, srcM2); + vec_s16_t srcM2ssB = (vec_s16_t) vec_mergel(zero_u8v, srcM2); + vec_s16_t srcM1ssA = (vec_s16_t) vec_mergeh(zero_u8v, srcM1); + vec_s16_t srcM1ssB = (vec_s16_t) vec_mergel(zero_u8v, srcM1); + vec_s16_t srcP0ssA = (vec_s16_t) vec_mergeh(zero_u8v, srcP0); + vec_s16_t srcP0ssB = (vec_s16_t) vec_mergel(zero_u8v, srcP0); + vec_s16_t srcP1ssA = (vec_s16_t) vec_mergeh(zero_u8v, srcP1); + vec_s16_t srcP1ssB = (vec_s16_t) vec_mergel(zero_u8v, srcP1); + vec_s16_t srcP2ssA = (vec_s16_t) vec_mergeh(zero_u8v, srcP2); + vec_s16_t srcP2ssB = (vec_s16_t) vec_mergel(zero_u8v, srcP2); + + vec_s16_t pp1A, pp1B, pp2A, pp2B, pp3A, pp3B, psumA, psumB, sumA, sumB, srcP3ssA, srcP3ssB, sum1A, sum1B, sum2A, sum2B, sum3A, sum3B; - vector unsigned char sum, dst1, dst2, vdst, fsum, rsum, fdst1, fdst2, - srcP3a, srcP3b, srcP3; + vec_u8_t sum, vdst, fsum, srcP3a, srcP3b, srcP3; POWERPC_PERF_START_COUNT(PREFIX_h264_qpel16_v_lowpass_num, 1); @@ -398,10 +407,8 @@ static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, i srcP3a = vec_ld(0, srcbis += srcStride); srcP3b = vec_ld(16, srcbis); srcP3 = vec_perm(srcP3a, srcP3b, perm); - srcP3ssA = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP3); - srcP3ssB = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP3); + srcP3ssA = (vec_s16_t) vec_mergeh(zero_u8v, srcP3); + srcP3ssB = (vec_s16_t) vec_mergel(zero_u8v, srcP3); // srcbis += srcStride; sum1A = vec_adds(srcP0ssA, srcP1ssA); @@ -425,8 +432,8 @@ static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, i pp1A = vec_mladd(sum1A, v20ss, v16ss); pp1B = vec_mladd(sum1B, v20ss, v16ss); - pp2A = vec_mladd(sum2A, v5ss, (vector signed short)vzero); - pp2B = vec_mladd(sum2B, v5ss, (vector signed short)vzero); + pp2A = vec_mladd(sum2A, v5ss, zero_s16v); + pp2B = vec_mladd(sum2B, v5ss, zero_s16v); pp3A = vec_add(sum3A, pp1A); pp3B = vec_add(sum3B, pp1B); @@ -439,18 +446,12 @@ static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, i sum = vec_packsu(sumA, sumB); - dst1 = vec_ld(0, dst); - dst2 = vec_ld(16, dst); - vdst = vec_perm(dst1, dst2, vec_lvsl(0, dst)); + ASSERT_ALIGNED(dst); + vdst = vec_ld(0, dst); OP_U8_ALTIVEC(fsum, sum, vdst); - rsum = vec_perm(fsum, fsum, dstperm); - fdst1 = vec_sel(dst1, rsum, dstmask); - fdst2 = vec_sel(rsum, dst2, dstmask); - - vec_st(fdst1, 0, dst); - vec_st(fdst2, 16, dst); + vec_st(fsum, 0, dst); dst += dstStride; } @@ -461,58 +462,50 @@ static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, i static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, uint8_t * src, int dstStride, int tmpStride, int srcStride) { POWERPC_PERF_DECLARE(PREFIX_h264_qpel16_hv_lowpass_num, 1); register int i; - const vector signed int vzero = vec_splat_s32(0); - const vector unsigned char permM2 = vec_lvsl(-2, src); - const vector unsigned char permM1 = vec_lvsl(-1, src); - const vector unsigned char permP0 = vec_lvsl(+0, src); - const vector unsigned char permP1 = vec_lvsl(+1, src); - const vector unsigned char permP2 = vec_lvsl(+2, src); - const vector unsigned char permP3 = vec_lvsl(+3, src); - const vector signed short v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); - const vector unsigned int v10ui = vec_splat_u32(10); - const vector signed short v5ss = vec_splat_s16(5); - const vector signed short v1ss = vec_splat_s16(1); - const vector signed int v512si = vec_sl(vec_splat_s32(1),vec_splat_u32(9)); - const vector unsigned int v16ui = vec_sl(vec_splat_u32(1),vec_splat_u32(4)); + LOAD_ZERO; + const vec_u8_t permM2 = vec_lvsl(-2, src); + const vec_u8_t permM1 = vec_lvsl(-1, src); + const vec_u8_t permP0 = vec_lvsl(+0, src); + const vec_u8_t permP1 = vec_lvsl(+1, src); + const vec_u8_t permP2 = vec_lvsl(+2, src); + const vec_u8_t permP3 = vec_lvsl(+3, src); + const vec_s16_t v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2)); + const vec_u32_t v10ui = vec_splat_u32(10); + const vec_s16_t v5ss = vec_splat_s16(5); + const vec_s16_t v1ss = vec_splat_s16(1); + const vec_s32_t v512si = vec_sl(vec_splat_s32(1),vec_splat_u32(9)); + const vec_u32_t v16ui = vec_sl(vec_splat_u32(1),vec_splat_u32(4)); register int align = ((((unsigned long)src) - 2) % 16); - const vector unsigned char neg1 = (const vector unsigned char) - vec_splat_s8(-1); - - vector signed short srcP0A, srcP0B, srcP1A, srcP1B, + vec_s16_t srcP0A, srcP0B, srcP1A, srcP1B, srcP2A, srcP2B, srcP3A, srcP3B, srcM1A, srcM1B, srcM2A, srcM2B, sum1A, sum1B, sum2A, sum2B, sum3A, sum3B, pp1A, pp1B, pp2A, pp2B, psumA, psumB; - const vector unsigned char dstperm = vec_lvsr(0, dst); - - const vector unsigned char dstmask = vec_perm((const vector unsigned char)vzero, neg1, dstperm); - - const vector unsigned char mperm = (const vector unsigned char) + const vec_u8_t mperm = (const vec_u8_t) AVV(0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B, 0x04, 0x0C, 0x05, 0x0D, 0x06, 0x0E, 0x07, 0x0F); int16_t *tmpbis = tmp; - vector signed short tmpM1ssA, tmpM1ssB, tmpM2ssA, tmpM2ssB, + vec_s16_t tmpM1ssA, tmpM1ssB, tmpM2ssA, tmpM2ssB, tmpP0ssA, tmpP0ssB, tmpP1ssA, tmpP1ssB, tmpP2ssA, tmpP2ssB; - vector signed int pp1Ae, pp1Ao, pp1Be, pp1Bo, pp2Ae, pp2Ao, pp2Be, pp2Bo, + vec_s32_t pp1Ae, pp1Ao, pp1Be, pp1Bo, pp2Ae, pp2Ao, pp2Be, pp2Bo, pp3Ae, pp3Ao, pp3Be, pp3Bo, pp1cAe, pp1cAo, pp1cBe, pp1cBo, pp32Ae, pp32Ao, pp32Be, pp32Bo, sumAe, sumAo, sumBe, sumBo, ssumAe, ssumAo, ssumBe, ssumBo; - vector unsigned char fsum, sumv, sum, dst1, dst2, vdst, - rsum, fdst1, fdst2; - vector signed short ssume, ssumo; + vec_u8_t fsum, sumv, sum, vdst; + vec_s16_t ssume, ssumo; POWERPC_PERF_START_COUNT(PREFIX_h264_qpel16_hv_lowpass_num, 1); src -= (2 * srcStride); for (i = 0 ; i < 21 ; i ++) { - vector unsigned char srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; - vector unsigned char srcR1 = vec_ld(-2, src); - vector unsigned char srcR2 = vec_ld(14, src); + vec_u8_t srcM2, srcM1, srcP0, srcP1, srcP2, srcP3; + vec_u8_t srcR1 = vec_ld(-2, src); + vec_u8_t srcR2 = vec_ld(14, src); switch (align) { default: { @@ -532,7 +525,7 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, srcP3 = srcR2; } break; case 12: { - vector unsigned char srcR3 = vec_ld(30, src); + vec_u8_t srcR3 = vec_ld(30, src); srcM2 = vec_perm(srcR1, srcR2, permM2); srcM1 = vec_perm(srcR1, srcR2, permM1); srcP0 = vec_perm(srcR1, srcR2, permP0); @@ -541,7 +534,7 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, srcP3 = vec_perm(srcR2, srcR3, permP3); } break; case 13: { - vector unsigned char srcR3 = vec_ld(30, src); + vec_u8_t srcR3 = vec_ld(30, src); srcM2 = vec_perm(srcR1, srcR2, permM2); srcM1 = vec_perm(srcR1, srcR2, permM1); srcP0 = vec_perm(srcR1, srcR2, permP0); @@ -550,7 +543,7 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, srcP3 = vec_perm(srcR2, srcR3, permP3); } break; case 14: { - vector unsigned char srcR3 = vec_ld(30, src); + vec_u8_t srcR3 = vec_ld(30, src); srcM2 = vec_perm(srcR1, srcR2, permM2); srcM1 = vec_perm(srcR1, srcR2, permM1); srcP0 = srcR2; @@ -559,7 +552,7 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, srcP3 = vec_perm(srcR2, srcR3, permP3); } break; case 15: { - vector unsigned char srcR3 = vec_ld(30, src); + vec_u8_t srcR3 = vec_ld(30, src); srcM2 = vec_perm(srcR1, srcR2, permM2); srcM1 = srcR2; srcP0 = vec_perm(srcR2, srcR3, permP0); @@ -569,32 +562,20 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, } break; } - srcP0A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP0); - srcP0B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP0); - srcP1A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP1); - srcP1B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP1); - - srcP2A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP2); - srcP2B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP2); - srcP3A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcP3); - srcP3B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcP3); - - srcM1A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcM1); - srcM1B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcM1); - srcM2A = (vector signed short) - vec_mergeh((vector unsigned char)vzero, srcM2); - srcM2B = (vector signed short) - vec_mergel((vector unsigned char)vzero, srcM2); + srcP0A = (vec_s16_t) vec_mergeh(zero_u8v, srcP0); + srcP0B = (vec_s16_t) vec_mergel(zero_u8v, srcP0); + srcP1A = (vec_s16_t) vec_mergeh(zero_u8v, srcP1); + srcP1B = (vec_s16_t) vec_mergel(zero_u8v, srcP1); + + srcP2A = (vec_s16_t) vec_mergeh(zero_u8v, srcP2); + srcP2B = (vec_s16_t) vec_mergel(zero_u8v, srcP2); + srcP3A = (vec_s16_t) vec_mergeh(zero_u8v, srcP3); + srcP3B = (vec_s16_t) vec_mergel(zero_u8v, srcP3); + + srcM1A = (vec_s16_t) vec_mergeh(zero_u8v, srcM1); + srcM1B = (vec_s16_t) vec_mergel(zero_u8v, srcM1); + srcM2A = (vec_s16_t) vec_mergeh(zero_u8v, srcM2); + srcM2B = (vec_s16_t) vec_mergel(zero_u8v, srcM2); sum1A = vec_adds(srcP0A, srcP1A); sum1B = vec_adds(srcP0B, srcP1B); @@ -606,8 +587,8 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, pp1A = vec_mladd(sum1A, v20ss, sum3A); pp1B = vec_mladd(sum1B, v20ss, sum3B); - pp2A = vec_mladd(sum2A, v5ss, (vector signed short)vzero); - pp2B = vec_mladd(sum2B, v5ss, (vector signed short)vzero); + pp2A = vec_mladd(sum2A, v5ss, zero_s16v); + pp2B = vec_mladd(sum2B, v5ss, zero_s16v); psumA = vec_sub(pp1A, pp2A); psumB = vec_sub(pp1B, pp2B); @@ -636,15 +617,15 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, tmpbis += tmpStride; for (i = 0 ; i < 16 ; i++) { - const vector signed short tmpP3ssA = vec_ld(0, tmpbis); - const vector signed short tmpP3ssB = vec_ld(16, tmpbis); + const vec_s16_t tmpP3ssA = vec_ld(0, tmpbis); + const vec_s16_t tmpP3ssB = vec_ld(16, tmpbis); - const vector signed short sum1A = vec_adds(tmpP0ssA, tmpP1ssA); - const vector signed short sum1B = vec_adds(tmpP0ssB, tmpP1ssB); - const vector signed short sum2A = vec_adds(tmpM1ssA, tmpP2ssA); - const vector signed short sum2B = vec_adds(tmpM1ssB, tmpP2ssB); - const vector signed short sum3A = vec_adds(tmpM2ssA, tmpP3ssA); - const vector signed short sum3B = vec_adds(tmpM2ssB, tmpP3ssB); + const vec_s16_t sum1A = vec_adds(tmpP0ssA, tmpP1ssA); + const vec_s16_t sum1B = vec_adds(tmpP0ssB, tmpP1ssB); + const vec_s16_t sum2A = vec_adds(tmpM1ssA, tmpP2ssA); + const vec_s16_t sum2B = vec_adds(tmpM1ssB, tmpP2ssB); + const vec_s16_t sum3A = vec_adds(tmpM2ssA, tmpP3ssA); + const vec_s16_t sum3B = vec_adds(tmpM2ssB, tmpP3ssB); tmpbis += tmpStride; @@ -669,9 +650,9 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, pp2Be = vec_mule(sum2B, v5ss); pp2Bo = vec_mulo(sum2B, v5ss); - pp3Ae = vec_sra((vector signed int)sum3A, v16ui); + pp3Ae = vec_sra((vec_s32_t)sum3A, v16ui); pp3Ao = vec_mulo(sum3A, v1ss); - pp3Be = vec_sra((vector signed int)sum3B, v16ui); + pp3Be = vec_sra((vec_s32_t)sum3B, v16ui); pp3Bo = vec_mulo(sum3B, v1ss); pp1cAe = vec_add(pp1Ae, v512si); @@ -700,18 +681,12 @@ static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, sumv = vec_packsu(ssume, ssumo); sum = vec_perm(sumv, sumv, mperm); - dst1 = vec_ld(0, dst); - dst2 = vec_ld(16, dst); - vdst = vec_perm(dst1, dst2, vec_lvsl(0, dst)); + ASSERT_ALIGNED(dst); + vdst = vec_ld(0, dst); OP_U8_ALTIVEC(fsum, sum, vdst); - rsum = vec_perm(fsum, fsum, dstperm); - fdst1 = vec_sel(dst1, rsum, dstmask); - fdst2 = vec_sel(rsum, dst2, dstmask); - - vec_st(fdst1, 0, dst); - vec_st(fdst2, 16, dst); + vec_st(fsum, 0, dst); dst += dstStride; } diff --git a/contrib/ffmpeg/libavcodec/ppc/idct_altivec.c b/contrib/ffmpeg/libavcodec/ppc/idct_altivec.c index 66c8082f7..37b2f62c3 100644 --- a/contrib/ffmpeg/libavcodec/ppc/idct_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/idct_altivec.c @@ -16,7 +16,6 @@ * 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 - * */ /* @@ -39,14 +38,14 @@ #include <stdlib.h> /* malloc(), free() */ #include <string.h> -#include "../dsputil.h" +#include "dsputil.h" #include "gcc_fixes.h" -#include "dsputil_altivec.h" +#include "dsputil_ppc.h" #define vector_s16_t vector signed short -#define const_vector_s16_t const_vector signed short +#define const_vector_s16_t const vector signed short #define vector_u16_t vector unsigned short #define vector_s8_t vector signed char #define vector_u8_t vector unsigned char diff --git a/contrib/ffmpeg/libavcodec/ppc/imgresample_altivec.c b/contrib/ffmpeg/libavcodec/ppc/imgresample_altivec.c new file mode 100644 index 000000000..3b161c5a6 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ppc/imgresample_altivec.c @@ -0,0 +1,153 @@ +/* + * 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_altivec.c + * High quality image resampling with polyphase filters - AltiVec bits + */ + +#include "gcc_fixes.h" + +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--; + } +} + diff --git a/contrib/ffmpeg/libavcodec/ppc/imgresample_altivec.h b/contrib/ffmpeg/libavcodec/ppc/imgresample_altivec.h new file mode 100644 index 000000000..538c1bee6 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ppc/imgresample_altivec.h @@ -0,0 +1,26 @@ +/* + * 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 + */ + +#ifndef FFMPEG_IMGRESAMPLE_ALTIVEC_H +#define FFMPEG_IMGRESAMPLE_ALTIVEC_H + +#include <stdint.h> + +void v_resample16_altivec(uint8_t *dst, int dst_width, const uint8_t *src, + int wrap, int16_t *filter); +#endif /* FFMPEG_IMGRESAMPLE_ALTIVEC_H */ diff --git a/contrib/ffmpeg/libavcodec/ppc/int_altivec.c b/contrib/ffmpeg/libavcodec/ppc/int_altivec.c new file mode 100644 index 000000000..95497c99a --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ppc/int_altivec.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2007 Luca Barbato <lu_zero@gentoo.org> + * + * 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 int_altivec.c + ** integer misc ops. + **/ + +#include "dsputil.h" + +#include "gcc_fixes.h" + +#include "dsputil_altivec.h" + +static int ssd_int8_vs_int16_altivec(const int8_t *pix1, const int16_t *pix2, + int size) { + int i, size16; + vector signed char vpix1; + vector signed short vpix2, vdiff, vpix1l,vpix1h; + union { vector signed int vscore; + int32_t score[4]; + } u; + u.vscore = vec_splat_s32(0); +// +//XXX lazy way, fix it later + +#define vec_unaligned_load(b) \ + vec_perm(vec_ld(0,b),vec_ld(15,b),vec_lvsl(0, b)); + + size16 = size >> 4; + while(size16) { +// score += (pix1[i]-pix2[i])*(pix1[i]-pix2[i]); + //load pix1 and the first batch of pix2 + + vpix1 = vec_unaligned_load(pix1); + vpix2 = vec_unaligned_load(pix2); + pix2 += 8; + //unpack + vpix1h = vec_unpackh(vpix1); + vdiff = vec_sub(vpix1h, vpix2); + vpix1l = vec_unpackl(vpix1); + // load another batch from pix2 + vpix2 = vec_unaligned_load(pix2); + u.vscore = vec_msum(vdiff, vdiff, u.vscore); + vdiff = vec_sub(vpix1l, vpix2); + u.vscore = vec_msum(vdiff, vdiff, u.vscore); + pix1 += 16; + pix2 += 8; + size16--; + } + u.vscore = vec_sums(u.vscore, vec_splat_s32(0)); + + size %= 16; + for (i = 0; i < size; i++) { + u.score[3] += (pix1[i]-pix2[i])*(pix1[i]-pix2[i]); + } + return u.score[3]; +} + +void int_init_altivec(DSPContext* c, AVCodecContext *avctx) +{ + c->ssd_int8_vs_int16 = ssd_int8_vs_int16_altivec; +} diff --git a/contrib/ffmpeg/libavcodec/ppc/mathops.h b/contrib/ffmpeg/libavcodec/ppc/mathops.h index 6af23f246..d7cc85365 100644 --- a/contrib/ffmpeg/libavcodec/ppc/mathops.h +++ b/contrib/ffmpeg/libavcodec/ppc/mathops.h @@ -20,6 +20,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_PPC_MATHOPS_H +#define FFMPEG_PPC_MATHOPS_H + #if defined(ARCH_POWERPC_405) /* signed 16x16 -> 32 multiply add accumulate */ # define MAC16(rt, ra, rb) \ @@ -31,3 +34,5 @@ asm ("mullhw %0, %1, %2" : "=r" (__rt) : "r" (ra), "r" (rb)); __rt; }) #endif + +#endif /* FFMPEG_PPC_MATHOPS_H */ diff --git a/contrib/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c b/contrib/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c index 3822cb20e..a2ba5e125 100644 --- a/contrib/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/mpegvideo_altivec.c @@ -23,13 +23,13 @@ #include <stdlib.h> #include <stdio.h> -#include "../dsputil.h" -#include "../mpegvideo.h" +#include "dsputil.h" +#include "mpegvideo.h" #include "gcc_fixes.h" -#include "dsputil_altivec.h" - +#include "dsputil_ppc.h" +#include "util_altivec.h" // Swaps two variables (used for altivec registers) #define SWAP(a,b) \ do { \ @@ -66,12 +66,8 @@ do { \ } -#ifdef CONFIG_DARWIN -#define FOUROF(a) (a) -#else -// slower, for dumb non-apple GCC -#define FOUROF(a) {a,a,a,a} -#endif +#define FOUROF(a) AVV(a,a,a,a) + int dct_quantize_altivec(MpegEncContext* s, DCTELEM* data, int n, int qscale, int* overflow) @@ -79,8 +75,8 @@ int dct_quantize_altivec(MpegEncContext* s, int lastNonZero; vector float row0, row1, row2, row3, row4, row5, row6, row7; vector float alt0, alt1, alt2, alt3, alt4, alt5, alt6, alt7; - const_vector float zero = (const_vector float)FOUROF(0.); - // used after quantise step + const vector float zero = (const vector float)FOUROF(0.); + // used after quantize step int oldBaseValue = 0; // Load the data into the row/alt vectors @@ -258,7 +254,7 @@ int dct_quantize_altivec(MpegEncContext* s, } } - // perform the quantise step, using the floating point data + // perform the quantize step, using the floating point data // still in the row/alt registers { const int* biasAddr; @@ -474,7 +470,7 @@ int dct_quantize_altivec(MpegEncContext* s, data[0] = (oldBaseValue + 4) >> 3; } - // We handled the tranpose permutation above and we don't + // We handled the transpose permutation above and we don't // need to permute the "no" permutation case. if ((lastNonZero > 0) && (s->dsp.idct_permutation_type != FF_TRANSPOSE_IDCT_PERM) && @@ -486,7 +482,6 @@ int dct_quantize_altivec(MpegEncContext* s, return lastNonZero; } -#undef FOUROF /* AltiVec version of dct_unquantize_h263 @@ -515,25 +510,25 @@ POWERPC_PERF_START_COUNT(altivec_dct_unquantize_h263_num, 1); }else qadd = 0; i = 1; - nCoeffs= 63; //does not allways use zigzag table + nCoeffs= 63; //does not always use zigzag table } else { i = 0; nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; } { - register const_vector signed short vczero = (const_vector signed short)vec_splat_s16(0); - short __attribute__ ((aligned(16))) qmul8[] = + register const vector signed short vczero = (const vector signed short)vec_splat_s16(0); + DECLARE_ALIGNED_16(short, qmul8[]) = { qmul, qmul, qmul, qmul, qmul, qmul, qmul, qmul }; - short __attribute__ ((aligned(16))) qadd8[] = + DECLARE_ALIGNED_16(short, qadd8[]) = { qadd, qadd, qadd, qadd, qadd, qadd, qadd, qadd }; - short __attribute__ ((aligned(16))) nqadd8[] = + DECLARE_ALIGNED_16(short, nqadd8[]) = { -qadd, -qadd, -qadd, -qadd, -qadd, -qadd, -qadd, -qadd @@ -601,3 +596,50 @@ POWERPC_PERF_START_COUNT(altivec_dct_unquantize_h263_num, 1); } POWERPC_PERF_STOP_COUNT(altivec_dct_unquantize_h263_num, nCoeffs == 63); } + + +extern void idct_put_altivec(uint8_t *dest, int line_size, int16_t *block); +extern void idct_add_altivec(uint8_t *dest, int line_size, int16_t *block); + +void MPV_common_init_altivec(MpegEncContext *s) +{ + if ((mm_flags & MM_ALTIVEC) == 0) return; + + if (s->avctx->lowres==0) + { + if ((s->avctx->idct_algo == FF_IDCT_AUTO) || + (s->avctx->idct_algo == FF_IDCT_ALTIVEC)) + { + s->dsp.idct_put = idct_put_altivec; + s->dsp.idct_add = idct_add_altivec; + s->dsp.idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; + } + } + + // Test to make sure that the dct required alignments are met. + if ((((long)(s->q_intra_matrix) & 0x0f) != 0) || + (((long)(s->q_inter_matrix) & 0x0f) != 0)) + { + av_log(s->avctx, AV_LOG_INFO, "Internal Error: q-matrix blocks must be 16-byte aligned " + "to use AltiVec DCT. Reverting to non-AltiVec version.\n"); + return; + } + + if (((long)(s->intra_scantable.inverse) & 0x0f) != 0) + { + av_log(s->avctx, AV_LOG_INFO, "Internal Error: scan table blocks must be 16-byte aligned " + "to use AltiVec DCT. Reverting to non-AltiVec version.\n"); + return; + } + + + if ((s->avctx->dct_algo == FF_DCT_AUTO) || + (s->avctx->dct_algo == FF_DCT_ALTIVEC)) + { +#if 0 /* seems to cause trouble under some circumstances */ + s->dct_quantize = dct_quantize_altivec; +#endif + s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec; + s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec; + } +} diff --git a/contrib/ffmpeg/libavcodec/ppc/mpegvideo_ppc.c b/contrib/ffmpeg/libavcodec/ppc/mpegvideo_ppc.c deleted file mode 100644 index c5e822f77..000000000 --- a/contrib/ffmpeg/libavcodec/ppc/mpegvideo_ppc.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2002 Dieter Shirley - * - * 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 "../dsputil.h" -#include "../mpegvideo.h" -#include <time.h> - -#ifdef HAVE_ALTIVEC -#include "dsputil_altivec.h" -#endif - -extern int dct_quantize_altivec(MpegEncContext *s, - DCTELEM *block, int n, - int qscale, int *overflow); -extern void dct_unquantize_h263_altivec(MpegEncContext *s, - DCTELEM *block, int n, int qscale); - -extern void idct_put_altivec(uint8_t *dest, int line_size, int16_t *block); -extern void idct_add_altivec(uint8_t *dest, int line_size, int16_t *block); - - -void MPV_common_init_ppc(MpegEncContext *s) -{ -#ifdef HAVE_ALTIVEC - if (has_altivec()) - { - if (s->avctx->lowres==0) - { - if ((s->avctx->idct_algo == FF_IDCT_AUTO) || - (s->avctx->idct_algo == FF_IDCT_ALTIVEC)) - { - s->dsp.idct_put = idct_put_altivec; - s->dsp.idct_add = idct_add_altivec; - s->dsp.idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; - } - } - - // Test to make sure that the dct required alignments are met. - if ((((long)(s->q_intra_matrix) & 0x0f) != 0) || - (((long)(s->q_inter_matrix) & 0x0f) != 0)) - { - av_log(s->avctx, AV_LOG_INFO, "Internal Error: q-matrix blocks must be 16-byte aligned " - "to use Altivec DCT. Reverting to non-altivec version.\n"); - return; - } - - if (((long)(s->intra_scantable.inverse) & 0x0f) != 0) - { - av_log(s->avctx, AV_LOG_INFO, "Internal Error: scan table blocks must be 16-byte aligned " - "to use Altivec DCT. Reverting to non-altivec version.\n"); - return; - } - - - if ((s->avctx->dct_algo == FF_DCT_AUTO) || - (s->avctx->dct_algo == FF_DCT_ALTIVEC)) - { -#if 0 /* seems to cause trouble under some circumstances */ - s->dct_quantize = dct_quantize_altivec; -#endif - s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec; - s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec; - } - } else -#endif - { - /* Non-AltiVec PPC optimisations here */ - } -} - diff --git a/contrib/ffmpeg/libavcodec/ppc/snow_altivec.c b/contrib/ffmpeg/libavcodec/ppc/snow_altivec.c index b15672ffe..8770f05f5 100644 --- a/contrib/ffmpeg/libavcodec/ppc/snow_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/snow_altivec.c @@ -1,5 +1,5 @@ /* - * Altivec optimized snow DSP utils + * AltiVec-optimized snow DSP utils * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org> * * This file is part of FFmpeg. @@ -17,15 +17,13 @@ * 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 "../dsputil.h" +#include "dsputil.h" #include "gcc_fixes.h" #include "dsputil_altivec.h" -#include "../snow.h" +#include "snow.h" #undef NDEBUG #include <assert.h> @@ -60,57 +58,56 @@ static DWTELEM * slice_buffer_load_line(slice_buffer * buf, int line) //altivec code -void ff_snow_horizontal_compose97i_altivec(DWTELEM *b, int width) +void ff_snow_horizontal_compose97i_altivec(IDWTELEM *b, int width) { +#if 0 const int w2= (width+1)>>1; - DECLARE_ALIGNED_16(DWTELEM, temp[(width>>1)]); + DECLARE_ALIGNED_16(IDWTELEM, temp[(width>>1)]); const int w_l= (width>>1); const int w_r= w2 - 1; int i; - vector signed int t1, t2, x, y, tmp1, tmp2; - vector signed int *vbuf, *vtmp; + vector signed short t1, t2, x, y, tmp1, tmp2; + vector signed short *vbuf, *vtmp; vector unsigned char align; - - { // Lift 0 - DWTELEM * const ref = b + w2 - 1; - DWTELEM b_0 = b[0]; - vbuf = (vector signed int *)b; + IDWTELEM * const ref = b + w2 - 1; + IDWTELEM b_0 = b[0]; + vector signed short v7 = vec_splat_s16(7); + vbuf = (vector signed short *)b; tmp1 = vec_ld (0, ref); align = vec_lvsl (0, ref); tmp2 = vec_ld (15, ref); - t1= vec_perm(tmp1, tmp2, align); - - i = 0; + t1 = vec_perm(tmp1, tmp2, align); for (i=0; i<w_l-15; i+=16) { #if 0 - b[i+0] = b[i+0] - ((3 * (ref[i+0] + ref[i+1]) + 4) >> 3); +/* b[i+0] = b[i+0] - ((3 * (ref[i+0] + ref[i+1]) + 4) >> 3); b[i+1] = b[i+1] - ((3 * (ref[i+1] + ref[i+2]) + 4) >> 3); b[i+2] = b[i+2] - ((3 * (ref[i+2] + ref[i+3]) + 4) >> 3); - b[i+3] = b[i+3] - ((3 * (ref[i+3] + ref[i+4]) + 4) >> 3); + b[i+3] = b[i+3] - ((3 * (ref[i+3] + ref[i+4]) + 4) >> 3);*/ + b[i+0] = b[i+0] + ((7 * (ref[i+0] + ref[i+1])-1) >> 8); #else - tmp1 = vec_ld (0, ref+4+i); - tmp2 = vec_ld (15, ref+4+i); + tmp1 = vec_ld (0, ref+8+i); + tmp2 = vec_ld (15, ref+8+i); t2 = vec_perm(tmp1, tmp2, align); - y = vec_add(t1,vec_sld(t1,t2,4)); - y = vec_add(vec_add(y,y),y); + y = vec_add(t1, vec_sld(t1,t2,2)); +// y = vec_add(vec_add(y,y),y); - tmp1 = vec_ld (0, ref+8+i); + tmp1 = vec_ld (0, ref+12+i); y = vec_add(y, vec_splat_s32(4)); y = vec_sra(y, vec_splat_u32(3)); - tmp2 = vec_ld (15, ref+8+i); + tmp2 = vec_ld (15, ref+12+i); *vbuf = vec_sub(*vbuf, y); - t1=t2; + t1 = t2; vbuf++; @@ -164,6 +161,7 @@ void ff_snow_horizontal_compose97i_altivec(DWTELEM *b, int width) vbuf++; #endif + } snow_horizontal_compose_lift_lead_out(i, b, b, ref, width, w_l, 0, W_DM, W_DO, W_DS); @@ -365,6 +363,7 @@ void ff_snow_horizontal_compose97i_altivec(DWTELEM *b, int width) } } +#endif } void ff_snow_vertical_compose97i_altivec(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width) @@ -524,7 +523,7 @@ static void inner_add_yblock_bw_8_obmc_16_altivec(uint8_t *obmc, vector signed int *v = (vector signed int *)vbuf, *d; for(y=0; y<b_h; y++){ - //FIXME ugly missue of obmc_stride + //FIXME ugly misuse of obmc_stride uint8_t *obmc1= obmc + y*obmc_stride; uint8_t *obmc2= obmc1+ (obmc_stride>>1); @@ -590,7 +589,7 @@ static void inner_add_yblock_bw_16_obmc_32_altivec(uint8_t *obmc, vector signed int *v = (vector signed int *)vbuf, *d; for(y=0; y<b_h; y++){ - //FIXME ugly missue of obmc_stride + //FIXME ugly misuse of obmc_stride uint8_t *obmc1= obmc + y*obmc_stride; uint8_t *obmc2= obmc1+ (obmc_stride>>1); @@ -673,7 +672,7 @@ static void inner_add_yblock_a_bw_8_obmc_16_altivec(uint8_t *obmc, vector signed int *v = (vector signed int *)vbuf, *d; for(y=0; y<b_h; y++){ - //FIXME ugly missue of obmc_stride + //FIXME ugly misuse of obmc_stride uint8_t *obmc1= obmc + y*obmc_stride; uint8_t *obmc2= obmc1+ (obmc_stride>>1); @@ -719,7 +718,7 @@ static void inner_add_yblock_a_bw_16_obmc_32_altivec(uint8_t *obmc, vector signed int *v = (vector signed int *)vbuf, *d; for(y=0; y<b_h; y++){ - //FIXME ugly missue of obmc_stride + //FIXME ugly misuse of obmc_stride uint8_t *obmc1= obmc + y*obmc_stride; uint8_t *obmc2= obmc1+ (obmc_stride>>1); @@ -782,7 +781,9 @@ void ff_snow_inner_add_yblock_altivec(uint8_t *obmc, const int obmc_stride, void snow_init_altivec(DSPContext* c, AVCodecContext *avctx) { +#if 0 c->horizontal_compose97i = ff_snow_horizontal_compose97i_altivec; c->vertical_compose97i = ff_snow_vertical_compose97i_altivec; c->inner_add_yblock = ff_snow_inner_add_yblock_altivec; +#endif } diff --git a/contrib/ffmpeg/libavcodec/ppc/types_altivec.h b/contrib/ffmpeg/libavcodec/ppc/types_altivec.h index f29026e04..6d41a928b 100644 --- a/contrib/ffmpeg/libavcodec/ppc/types_altivec.h +++ b/contrib/ffmpeg/libavcodec/ppc/types_altivec.h @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_TYPES_ALTIVEC_H +#define FFMPEG_TYPES_ALTIVEC_H + /*********************************************************************** * Vector types **********************************************************************/ @@ -39,3 +42,5 @@ #define zero_s16v (vec_s16_t) zerov #define zero_u32v (vec_u32_t) zerov #define zero_s32v (vec_s32_t) zerov + +#endif /* FFMPEG_TYPES_ALTIVEC_H */ diff --git a/contrib/ffmpeg/libavcodec/ppc/util_altivec.h b/contrib/ffmpeg/libavcodec/ppc/util_altivec.h new file mode 100644 index 000000000..6a8afb1b2 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ppc/util_altivec.h @@ -0,0 +1,105 @@ +/* + * 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 util_altivec.h + * Contains misc utility macros and inline functions + */ + +#ifndef FFMPEG_UTIL_ALTIVEC_H +#define FFMPEG_UTIL_ALTIVEC_H + +#include <stdint.h> + +#include "config.h" + +#ifdef HAVE_ALTIVEC_H +#include <altivec.h> +#endif + +// used to build registers permutation vectors (vcprm) +// the 's' are for words in the _s_econd vector +#define WORD_0 0x00,0x01,0x02,0x03 +#define WORD_1 0x04,0x05,0x06,0x07 +#define WORD_2 0x08,0x09,0x0a,0x0b +#define WORD_3 0x0c,0x0d,0x0e,0x0f +#define WORD_s0 0x10,0x11,0x12,0x13 +#define WORD_s1 0x14,0x15,0x16,0x17 +#define WORD_s2 0x18,0x19,0x1a,0x1b +#define WORD_s3 0x1c,0x1d,0x1e,0x1f + +#define vcprm(a,b,c,d) (const vector unsigned char)AVV(WORD_ ## a, WORD_ ## b, WORD_ ## c, WORD_ ## d) +#define vcii(a,b,c,d) (const vector float)AVV(FLOAT_ ## a, FLOAT_ ## b, FLOAT_ ## c, FLOAT_ ## d) + +// vcprmle is used to keep the same index as in the SSE version. +// it's the same as vcprm, with the index inversed +// ('le' is Little Endian) +#define vcprmle(a,b,c,d) vcprm(d,c,b,a) + +// used to build inverse/identity vectors (vcii) +// n is _n_egative, p is _p_ositive +#define FLOAT_n -1. +#define FLOAT_p 1. + + +// Transpose 8x8 matrix of 16-bit elements (in-place) +#define TRANSPOSE8(a,b,c,d,e,f,g,h) \ +do { \ + vector signed short A1, B1, C1, D1, E1, F1, G1, H1; \ + vector signed short A2, B2, C2, D2, E2, F2, G2, H2; \ + \ + A1 = vec_mergeh (a, e); \ + B1 = vec_mergel (a, e); \ + C1 = vec_mergeh (b, f); \ + D1 = vec_mergel (b, f); \ + E1 = vec_mergeh (c, g); \ + F1 = vec_mergel (c, g); \ + G1 = vec_mergeh (d, h); \ + H1 = vec_mergel (d, h); \ + \ + A2 = vec_mergeh (A1, E1); \ + B2 = vec_mergel (A1, E1); \ + C2 = vec_mergeh (B1, F1); \ + D2 = vec_mergel (B1, F1); \ + E2 = vec_mergeh (C1, G1); \ + F2 = vec_mergel (C1, G1); \ + G2 = vec_mergeh (D1, H1); \ + H2 = vec_mergel (D1, H1); \ + \ + a = vec_mergeh (A2, E2); \ + b = vec_mergel (A2, E2); \ + c = vec_mergeh (B2, F2); \ + d = vec_mergel (B2, F2); \ + e = vec_mergeh (C2, G2); \ + f = vec_mergel (C2, G2); \ + g = vec_mergeh (D2, H2); \ + h = vec_mergel (D2, H2); \ +} while (0) + + +/** \brief loads unaligned vector \a *src with offset \a offset + and returns it */ +static inline vector unsigned char unaligned_load(int offset, uint8_t *src) +{ + register vector unsigned char first = vec_ld(offset, src); + register vector unsigned char second = vec_ld(offset+15, src); + register vector unsigned char mask = vec_lvsl(offset, src); + return vec_perm(first, second, mask); +} + +#endif /* FFMPEG_UTIL_ALTIVEC_H */ diff --git a/contrib/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c b/contrib/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c index 114c9d41f..87bef808e 100644 --- a/contrib/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c +++ b/contrib/ffmpeg/libavcodec/ppc/vc1dsp_altivec.c @@ -17,14 +17,13 @@ * 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 "../dsputil.h" +#include "dsputil.h" #include "gcc_fixes.h" -#include "dsputil_altivec.h" +#include "util_altivec.h" // main steps of 8x8 transform #define STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_rnd) \ @@ -139,7 +138,6 @@ static void vc1_inv_trans_8x8_altivec(DCTELEM block[64]) vector signed int t0, t1, t2, t3, t4, t5, t6, t7; const vector signed int vec_64 = vec_sl(vec_splat_s32(4), vec_splat_u32(4)); const vector unsigned int vec_7 = vec_splat_u32(7); - const vector unsigned int vec_5 = vec_splat_u32(5); const vector unsigned int vec_4 = vec_splat_u32(4); const vector signed int vec_4s = vec_splat_s32(4); const vector unsigned int vec_3 = vec_splat_u32(3); @@ -229,7 +227,7 @@ static void vc1_inv_trans_8x8_altivec(DCTELEM block[64]) /** Do inverse transform on 8x4 part of block */ -static void vc1_inv_trans_8x4_altivec(DCTELEM block[64], int n) +static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, DCTELEM *block) { vector signed short src0, src1, src2, src3, src4, src5, src6, src7; vector signed int s0, s1, s2, s3, s4, s5, s6, s7; @@ -243,6 +241,9 @@ static void vc1_inv_trans_8x4_altivec(DCTELEM block[64], int n) const vector unsigned int vec_3 = vec_splat_u32(3); const vector unsigned int vec_2 = vec_splat_u32(2); const vector unsigned int vec_1 = vec_splat_u32(1); + vector unsigned char tmp; + vector signed short tmp2, tmp3; + vector unsigned char perm0, perm1, p0, p1, p; src0 = vec_ld( 0, block); src1 = vec_ld( 16, block); @@ -284,51 +285,42 @@ static void vc1_inv_trans_8x4_altivec(DCTELEM block[64], int n) src7 = vec_pack(sF, s7); TRANSPOSE8(src0, src1, src2, src3, src4, src5, src6, src7); - if(!n){ // upper half of block - s0 = vec_unpackh(src0); - s1 = vec_unpackh(src1); - s2 = vec_unpackh(src2); - s3 = vec_unpackh(src3); - s8 = vec_unpackl(src0); - s9 = vec_unpackl(src1); - sA = vec_unpackl(src2); - sB = vec_unpackl(src3); - STEP4(s0, s1, s2, s3, vec_64); - SHIFT_VERT4(s0, s1, s2, s3); - STEP4(s8, s9, sA, sB, vec_64); - SHIFT_VERT4(s8, s9, sA, sB); - src0 = vec_pack(s0, s8); - src1 = vec_pack(s1, s9); - src2 = vec_pack(s2, sA); - src3 = vec_pack(s3, sB); + s0 = vec_unpackh(src0); + s1 = vec_unpackh(src1); + s2 = vec_unpackh(src2); + s3 = vec_unpackh(src3); + s8 = vec_unpackl(src0); + s9 = vec_unpackl(src1); + sA = vec_unpackl(src2); + sB = vec_unpackl(src3); + STEP4(s0, s1, s2, s3, vec_64); + SHIFT_VERT4(s0, s1, s2, s3); + STEP4(s8, s9, sA, sB, vec_64); + SHIFT_VERT4(s8, s9, sA, sB); + src0 = vec_pack(s0, s8); + src1 = vec_pack(s1, s9); + src2 = vec_pack(s2, sA); + src3 = vec_pack(s3, sB); + + p0 = vec_lvsl (0, dest); + p1 = vec_lvsl (stride, dest); + p = vec_splat_u8 (-1); + perm0 = vec_mergeh (p, p0); + perm1 = vec_mergeh (p, p1); - vec_st(src0, 0, block); - vec_st(src1, 16, block); - vec_st(src2, 32, block); - vec_st(src3, 48, block); - } else { //lower half of block - s0 = vec_unpackh(src4); - s1 = vec_unpackh(src5); - s2 = vec_unpackh(src6); - s3 = vec_unpackh(src7); - s8 = vec_unpackl(src4); - s9 = vec_unpackl(src5); - sA = vec_unpackl(src6); - sB = vec_unpackl(src7); - STEP4(s0, s1, s2, s3, vec_64); - SHIFT_VERT4(s0, s1, s2, s3); - STEP4(s8, s9, sA, sB, vec_64); - SHIFT_VERT4(s8, s9, sA, sB); - src4 = vec_pack(s0, s8); - src5 = vec_pack(s1, s9); - src6 = vec_pack(s2, sA); - src7 = vec_pack(s3, sB); +#define ADD(dest,src,perm) \ + /* *(uint64_t *)&tmp = *(uint64_t *)dest; */ \ + tmp = vec_ld (0, dest); \ + tmp2 = (vector signed short)vec_perm (tmp, vec_splat_u8(0), perm); \ + tmp3 = vec_adds (tmp2, src); \ + tmp = vec_packsu (tmp3, tmp3); \ + vec_ste ((vector unsigned int)tmp, 0, (unsigned int *)dest); \ + vec_ste ((vector unsigned int)tmp, 4, (unsigned int *)dest); - vec_st(src4, 64, block); - vec_st(src5, 80, block); - vec_st(src6, 96, block); - vec_st(src7,112, block); - } + ADD (dest, src0, perm0) dest += stride; + ADD (dest, src1, perm1) dest += stride; + ADD (dest, src2, perm0) dest += stride; + ADD (dest, src3, perm1) } diff --git a/contrib/ffmpeg/libavcodec/ps2/dsputil_mmi.c b/contrib/ffmpeg/libavcodec/ps2/dsputil_mmi.c index 0d72ae88c..6a0582fe4 100644 --- a/contrib/ffmpeg/libavcodec/ps2/dsputil_mmi.c +++ b/contrib/ffmpeg/libavcodec/ps2/dsputil_mmi.c @@ -2,6 +2,9 @@ * MMI optimized DSP utils * Copyright (c) 2000, 2001 Fabrice Bellard. * + * MMI optimization by Leon van Stuivenberg + * clear_blocks_mmi() by BroadQ + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -17,12 +20,9 @@ * 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 - * - * MMI optimization by Leon van Stuivenberg - * clear_blocks_mmi() by BroadQ */ -#include "../dsputil.h" +#include "dsputil.h" #include "mmi.h" void ff_mmi_idct_put(uint8_t *dest, int line_size, DCTELEM *block); diff --git a/contrib/ffmpeg/libavcodec/ps2/idct_mmi.c b/contrib/ffmpeg/libavcodec/ps2/idct_mmi.c index dfe9b3726..2ba2ad02d 100644 --- a/contrib/ffmpeg/libavcodec/ps2/idct_mmi.c +++ b/contrib/ffmpeg/libavcodec/ps2/idct_mmi.c @@ -23,11 +23,10 @@ * 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 "../dsputil.h" +#include "common.h" +#include "dsputil.h" #include "mmi.h" #define BITS_INV_ACC 5 // 4 or 5 for IEEE diff --git a/contrib/ffmpeg/libavcodec/ps2/mmi.h b/contrib/ffmpeg/libavcodec/ps2/mmi.h index e2e49a86c..1e0a504f8 100644 --- a/contrib/ffmpeg/libavcodec/ps2/mmi.h +++ b/contrib/ffmpeg/libavcodec/ps2/mmi.h @@ -18,8 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef __mmi_H -#define __mmi_H +#ifndef FFMPEG_MMI_H +#define FFMPEG_MMI_H #define align16 __attribute__ ((aligned (16))) @@ -168,5 +168,4 @@ #define pextlb(rs, rt, rd) \ __asm__ __volatile__ ("pextlb " #rd ", " #rs ", " #rt ) -#endif - +#endif /* FFMPEG_MMI_H */ diff --git a/contrib/ffmpeg/libavcodec/ps2/mpegvideo_mmi.c b/contrib/ffmpeg/libavcodec/ps2/mpegvideo_mmi.c index 1e5f08aae..7f62e6e6d 100644 --- a/contrib/ffmpeg/libavcodec/ps2/mpegvideo_mmi.c +++ b/contrib/ffmpeg/libavcodec/ps2/mpegvideo_mmi.c @@ -1,6 +1,8 @@ /* * Copyright (c) 2000,2001 Fabrice Bellard. * + * MMI optimization by Leon van Stuivenberg + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -16,13 +18,11 @@ * 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 - * - * MMI optimization by Leon van Stuivenberg */ -#include "../dsputil.h" -#include "../mpegvideo.h" -#include "../avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "avcodec.h" static void dct_unquantize_h263_mmi(MpegEncContext *s, DCTELEM *block, int n, int qscale) @@ -45,7 +45,7 @@ static void dct_unquantize_h263_mmi(MpegEncContext *s, qadd = 0; level = block[0]; } - nCoeffs= 63; //does not allways use zigzag table + nCoeffs= 63; //does not always use zigzag table } else { nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; } diff --git a/contrib/ffmpeg/libavcodec/pthread.c b/contrib/ffmpeg/libavcodec/pthread.c index f2c636bbe..702adb533 100644 --- a/contrib/ffmpeg/libavcodec/pthread.c +++ b/contrib/ffmpeg/libavcodec/pthread.c @@ -20,12 +20,10 @@ * 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 <pthread.h> #include "avcodec.h" -#include "common.h" typedef int (action_t)(AVCodecContext *c, void *arg); @@ -44,7 +42,7 @@ typedef struct ThreadContext { int done; } ThreadContext; -static void* worker(void *v) +static void* attribute_align_arg worker(void *v) { AVCodecContext *avctx = v; ThreadContext *c = avctx->thread_opaque; @@ -99,7 +97,7 @@ void avcodec_thread_free(AVCodecContext *avctx) pthread_cond_destroy(&c->current_job_cond); pthread_cond_destroy(&c->last_job_cond); av_free(c->workers); - av_free(c); + av_freep(&avctx->thread_opaque); } int avcodec_thread_execute(AVCodecContext *avctx, action_t* func, void **arg, int *ret, int job_count) diff --git a/contrib/ffmpeg/libavcodec/ptx.c b/contrib/ffmpeg/libavcodec/ptx.c new file mode 100644 index 000000000..22bb46178 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/ptx.c @@ -0,0 +1,117 @@ +/* + * V.Flash PTX (.ptx) image decoder + * Copyright (c) 2007 Ivo van Poorten + * + * 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" + +typedef struct PTXContext { + AVFrame picture; +} PTXContext; + +static int ptx_init(AVCodecContext *avctx) { + PTXContext *s = avctx->priv_data; + + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame= &s->picture; + + return 0; +} + +static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + const uint8_t *buf, int buf_size) { + PTXContext * const s = avctx->priv_data; + AVFrame *picture = data; + AVFrame * const p = &s->picture; + unsigned int offset, w, h, y, stride, bytes_per_pixel; + uint8_t *ptr; + + offset = AV_RL16(buf); + w = AV_RL16(buf+8); + h = AV_RL16(buf+10); + bytes_per_pixel = AV_RL16(buf+12) >> 3; + + if (bytes_per_pixel != 2) { + av_log(avctx, AV_LOG_ERROR, "image format is not rgb15, please report on ffmpeg-users mailing list\n"); + return -1; + } + + avctx->pix_fmt = PIX_FMT_RGB555; + + if (offset != 0x2c) + av_log(avctx, AV_LOG_WARNING, "offset != 0x2c, untested due to lack of sample files\n"); + + buf += offset; + + if (p->data[0]) + avctx->release_buffer(avctx, p); + + 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; + } + + p->pict_type = FF_I_TYPE; + + ptr = p->data[0]; + stride = p->linesize[0]; + + for (y=0; y<h; y++) { +#ifdef WORDS_BIGENDIAN + unsigned int x; + for (x=0; x<w*bytes_per_pixel; x+=bytes_per_pixel) + AV_WN16(ptr+x, AV_RL16(buf+x)); +#else + memcpy(ptr, buf, w*bytes_per_pixel); +#endif + ptr += stride; + buf += w*bytes_per_pixel; + } + + *picture = s->picture; + *data_size = sizeof(AVPicture); + + return offset + w*h*bytes_per_pixel; +} + +static int ptx_end(AVCodecContext *avctx) { + PTXContext *s = avctx->priv_data; + + if(s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + + return 0; +} + +AVCodec ptx_decoder = { + "ptx", + CODEC_TYPE_VIDEO, + CODEC_ID_PTX, + sizeof(PTXContext), + ptx_init, + NULL, + ptx_end, + ptx_decode_frame, + 0, + NULL +}; diff --git a/contrib/ffmpeg/libavcodec/qdm2.c b/contrib/ffmpeg/libavcodec/qdm2.c index a2630fe7f..55ddbef45 100644 --- a/contrib/ffmpeg/libavcodec/qdm2.c +++ b/contrib/ffmpeg/libavcodec/qdm2.c @@ -20,7 +20,6 @@ * 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 - * */ /** @@ -98,16 +97,16 @@ typedef struct { /** * A node in the subpacket list */ -typedef struct _QDM2SubPNode { +typedef struct QDM2SubPNode { QDM2SubPacket *packet; ///< packet - struct _QDM2SubPNode *next; ///< pointer to next packet in the list, NULL if leaf node + struct QDM2SubPNode *next; ///< pointer to next packet in the list, NULL if leaf node } QDM2SubPNode; typedef struct { float level; float *samples_im; float *samples_re; - float *table; + const float *table; int phase; int phase_shift; int duration; @@ -129,7 +128,7 @@ typedef struct { } QDM2Complex; typedef struct { - QDM2Complex complex[256 + 1] __attribute__((aligned(16))); + DECLARE_ALIGNED_16(QDM2Complex, complex[256 + 1]); float samples_im[MPA_MAX_CHANNELS][256]; float samples_re[MPA_MAX_CHANNELS][256]; } QDM2FFT; @@ -177,14 +176,14 @@ typedef struct { QDM2FFT fft; /// I/O data - uint8_t *compressed_data; + const uint8_t *compressed_data; int compressed_size; float output_buffer[1024]; /// Synthesis filter - MPA_INT synth_buf[MPA_MAX_CHANNELS][512*2] __attribute__((aligned(16))); + DECLARE_ALIGNED_16(MPA_INT, synth_buf[MPA_MAX_CHANNELS][512*2]); int synth_buf_offset[MPA_MAX_CHANNELS]; - int32_t sb_samples[MPA_MAX_CHANNELS][128][SBLIMIT] __attribute__((aligned(16))); + DECLARE_ALIGNED_16(int32_t, sb_samples[MPA_MAX_CHANNELS][128][SBLIMIT]); /// Mixed temporary data used in decoding float tone_level[MPA_MAX_CHANNELS][30][64]; @@ -229,7 +228,7 @@ static uint8_t random_dequant_index[256][5]; static uint8_t random_dequant_type24[128][3]; static float noise_samples[128]; -static MPA_INT mpa_window[512] __attribute__((aligned(16))); +static DECLARE_ALIGNED_16(MPA_INT, mpa_window[512]); static void softclip_table_init(void) { @@ -405,7 +404,7 @@ static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth) * * @return 0 if checksum is OK */ -static uint16_t qdm2_packet_checksum (uint8_t *data, int length, int value) { +static uint16_t qdm2_packet_checksum (const uint8_t *data, int length, int value) { int i; for (i=0; i < length; i++) @@ -1599,7 +1598,7 @@ static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet) tone.level = (q->fft_coefs[j].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[j].exp & 63]; tone.samples_im = &q->fft.samples_im[ch][offset]; tone.samples_re = &q->fft.samples_re[ch][offset]; - tone.table = (float*)fft_tone_sample_table[i][q->fft_coefs[j].offset - (offset << four_i)]; + tone.table = fft_tone_sample_table[i][q->fft_coefs[j].offset - (offset << four_i)]; tone.phase = 64 * q->fft_coefs[j].phase - (offset << 8) - 128; tone.phase_shift = (2 * q->fft_coefs[j].offset + 1) << (7 - four_i); tone.duration = i; @@ -1693,11 +1692,11 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) * @param q context */ static void qdm2_init(QDM2Context *q) { - static int inited = 0; + static int initialized = 0; - if (inited != 0) + if (initialized != 0) return; - inited = 1; + initialized = 1; qdm2_init_vlc(); ff_mpa_synth_init(mpa_window); @@ -1944,7 +1943,7 @@ static int qdm2_decode_close(AVCodecContext *avctx) } -static void qdm2_decode (QDM2Context *q, uint8_t *in, int16_t *out) +static void qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out) { int ch, i; const int frame_size = (q->frame_size * q->channels); @@ -2006,7 +2005,7 @@ static void qdm2_decode (QDM2Context *q, uint8_t *in, int16_t *out) static int qdm2_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { QDM2Context *s = avctx->priv_data; diff --git a/contrib/ffmpeg/libavcodec/qdm2data.h b/contrib/ffmpeg/libavcodec/qdm2data.h index 6d7d07463..8edb246e4 100644 --- a/contrib/ffmpeg/libavcodec/qdm2data.h +++ b/contrib/ffmpeg/libavcodec/qdm2data.h @@ -20,7 +20,6 @@ * 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 - * */ /** @@ -28,8 +27,10 @@ * Various QDM2 tables. */ -#ifndef QDM2DATA_H -#define QDM2DATA_H +#ifndef FFMPEG_QDM2DATA_H +#define FFMPEG_QDM2DATA_H + +#include <stdint.h> /** VLC TABLES **/ @@ -527,4 +528,4 @@ static const float type34_delta[10] = { // FIXME: covers 8 entries.. 0.138071194291115f,0.333333343267441f,0.60947573184967f,1.0f,0.0f, }; -#endif /* QDM2DATA_H */ +#endif /* FFMPEG_QDM2DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/qdrw.c b/contrib/ffmpeg/libavcodec/qdrw.c index 664be2f4f..0ee9a8f7c 100644 --- a/contrib/ffmpeg/libavcodec/qdrw.c +++ b/contrib/ffmpeg/libavcodec/qdrw.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -31,18 +30,19 @@ typedef struct QdrawContext{ AVCodecContext *avctx; AVFrame pic; - uint8_t palette[256*3]; } QdrawContext; static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { QdrawContext * const a = avctx->priv_data; AVFrame * const p= (AVFrame*)&a->pic; uint8_t* outdata; int colors; int i; + uint32_t *pal; + int r, g, b; if(p->data[0]) avctx->release_buffer(avctx, p); @@ -66,6 +66,7 @@ static int decode_frame(AVCodecContext *avctx, return -1; } + pal = (uint32_t*)p->data[1]; for (i = 0; i <= colors; i++) { unsigned int idx; idx = AV_RB16(buf); /* color index */ @@ -76,18 +77,20 @@ static int decode_frame(AVCodecContext *avctx, buf += 6; continue; } - a->palette[idx * 3 + 0] = *buf++; + r = *buf++; buf++; - a->palette[idx * 3 + 1] = *buf++; + g = *buf++; buf++; - a->palette[idx * 3 + 2] = *buf++; + b = *buf++; buf++; + pal[idx] = (r << 16) | (g << 8) | b; } + p->palette_has_changed = 1; buf += 18; /* skip unneeded data */ for (i = 0; i < avctx->height; i++) { int size, left, code, pix; - uint8_t *next; + const uint8_t *next; uint8_t *out; int tsize = 0; @@ -100,27 +103,19 @@ static int decode_frame(AVCodecContext *avctx, while (left > 0) { code = *buf++; if (code & 0x80 ) { /* run */ - int i; pix = *buf++; - if ((out + (257 - code) * 3) > (outdata + a->pic.linesize[0])) + if ((out + (257 - code)) > (outdata + a->pic.linesize[0])) break; - for (i = 0; i < 257 - code; i++) { - *out++ = a->palette[pix * 3 + 0]; - *out++ = a->palette[pix * 3 + 1]; - *out++ = a->palette[pix * 3 + 2]; - } + memset(out, pix, 257 - code); + out += 257 - code; tsize += 257 - code; left -= 2; } else { /* copy */ - int i, pix; - if ((out + code * 3) > (outdata + a->pic.linesize[0])) + if ((out + code) > (outdata + a->pic.linesize[0])) break; - for (i = 0; i <= code; i++) { - pix = *buf++; - *out++ = a->palette[pix * 3 + 0]; - *out++ = a->palette[pix * 3 + 1]; - *out++ = a->palette[pix * 3 + 2]; - } + memcpy(out, buf, code + 1); + out += code + 1; + buf += code + 1; left -= 2 + code; tsize += code + 1; } @@ -142,7 +137,7 @@ static int decode_init(AVCodecContext *avctx){ return 1; } - avctx->pix_fmt= PIX_FMT_RGB24; + avctx->pix_fmt= PIX_FMT_PAL8; return 0; } diff --git a/contrib/ffmpeg/libavcodec/qpeg.c b/contrib/ffmpeg/libavcodec/qpeg.c index d995bc3b7..5f902e304 100644 --- a/contrib/ffmpeg/libavcodec/qpeg.c +++ b/contrib/ffmpeg/libavcodec/qpeg.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -34,7 +33,7 @@ typedef struct QpegContext{ uint8_t *refdata; } QpegContext; -static void qpeg_decode_intra(uint8_t *src, uint8_t *dst, int size, +static void qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size, int stride, int width, int height) { int i; @@ -116,22 +115,20 @@ static int qpeg_table_w[16] = { 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04}; /* Decodes delta frames */ -static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size, +static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, int stride, int width, int height, - int delta, uint8_t *ctable, uint8_t *refdata) + int delta, const uint8_t *ctable, uint8_t *refdata) { int i, j; int code; int filled = 0; int orig_height; - uint8_t *blkdata; /* copy prev frame */ for(i = 0; i < height; i++) memcpy(refdata + (i * width), dst + (i * stride), width); orig_height = height; - blkdata = src - 0x86; height--; dst = dst + height * stride; @@ -252,7 +249,7 @@ static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size, static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { QpegContext * const a = avctx->priv_data; AVFrame * const p= (AVFrame*)&a->pic; diff --git a/contrib/ffmpeg/libavcodec/qtrle.c b/contrib/ffmpeg/libavcodec/qtrle.c index 415f08098..84482bac7 100644 --- a/contrib/ffmpeg/libavcodec/qtrle.c +++ b/contrib/ffmpeg/libavcodec/qtrle.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -37,7 +36,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -47,7 +45,7 @@ typedef struct QtrleContext { DSPContext dsp; AVFrame frame; - unsigned char *buf; + const unsigned char *buf; int size; } QtrleContext; @@ -491,7 +489,7 @@ static void qtrle_decode_32bpp(QtrleContext *s) static int qtrle_decode_init(AVCodecContext *avctx) { - QtrleContext *s = (QtrleContext *)avctx->priv_data; + QtrleContext *s = avctx->priv_data; s->avctx = avctx; switch (avctx->bits_per_sample) { @@ -523,7 +521,6 @@ static int qtrle_decode_init(AVCodecContext *avctx) avctx->bits_per_sample); break; } - avctx->has_b_frames = 0; dsputil_init(&s->dsp, avctx); s->frame.data[0] = NULL; @@ -533,9 +530,9 @@ static int qtrle_decode_init(AVCodecContext *avctx) static int qtrle_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - QtrleContext *s = (QtrleContext *)avctx->priv_data; + QtrleContext *s = avctx->priv_data; s->buf = buf; s->size = buf_size; @@ -608,7 +605,7 @@ static int qtrle_decode_frame(AVCodecContext *avctx, static int qtrle_decode_end(AVCodecContext *avctx) { - QtrleContext *s = (QtrleContext *)avctx->priv_data; + QtrleContext *s = avctx->priv_data; if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); diff --git a/contrib/ffmpeg/libavcodec/qtrleenc.c b/contrib/ffmpeg/libavcodec/qtrleenc.c new file mode 100644 index 000000000..2f41f3ce1 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/qtrleenc.c @@ -0,0 +1,326 @@ +/* + * Quicktime Animation (RLE) Video Encoder + * Copyright (C) 2007 Clemens Fruhwirth + * Copyright (C) 2007 Alexis Ballier + * + * This file is part of FFmpeg. + * + * This file is based on flashsvenc.c + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License, version 2.1, as published by the Free Software Foundation + * + * 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" +#include "bytestream.h" + +/** Maximum RLE code for bulk copy */ +#define MAX_RLE_BULK 127 +/** Maximum RLE code for repeat */ +#define MAX_RLE_REPEAT 128 +/** Maximum RLE code for skip */ +#define MAX_RLE_SKIP 254 + +typedef struct QtrleEncContext { + AVCodecContext *avctx; + AVFrame frame; + int pixel_size; + AVPicture previous_frame; + unsigned int max_buf_size; + /** + * This array will contain at ith position the value of the best RLE code + * if the line started at pixel i + * There can be 3 values : + * skip (0) : skip as much as possible pixels because they are equal to the + * previous frame ones + * repeat (<-1) : repeat that pixel -rle_code times, still as much as + * possible + * copy (>0) : copy the raw next rle_code pixels */ + signed char *rlecode_table; + /** + * This array will contain the length of the best rle encoding of the line + * starting at ith pixel */ + int *length_table; + /** + * Will contain at ith position the number of consecutive pixels equal to the previous + * frame starting from pixel i */ + uint8_t* skip_table; +} QtrleEncContext; + +static int qtrle_encode_init(AVCodecContext *avctx) +{ + QtrleEncContext *s = avctx->priv_data; + + if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { + return -1; + } + s->avctx=avctx; + + switch (avctx->pix_fmt) { +/* case PIX_FMT_RGB555: + s->pixel_size = 2; + break;*/ + case PIX_FMT_RGB24: + s->pixel_size = 3; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unsupported colorspace.\n"); + break; + } + avctx->bits_per_sample = s->pixel_size*8; + + s->rlecode_table = av_mallocz(s->avctx->width); + s->skip_table = av_mallocz(s->avctx->width); + s->length_table = av_mallocz((s->avctx->width + 1)*sizeof(int)); + if (!s->skip_table || !s->length_table || !s->rlecode_table) { + av_log(avctx, AV_LOG_ERROR, "Error allocating memory.\n"); + return -1; + } + if (avpicture_alloc(&s->previous_frame, avctx->pix_fmt, avctx->width, avctx->height) < 0) { + av_log(avctx, AV_LOG_ERROR, "Error allocating picture\n"); + return -1; + } + + s->max_buf_size = s->avctx->width*s->avctx->height*s->pixel_size /* image base material */ + + 15 /* header + footer */ + + s->avctx->height*2 /* skip code+rle end */ + + s->avctx->width/MAX_RLE_BULK + 1 /* rle codes */; + avctx->coded_frame = &s->frame; + return 0; +} + +/** + * Computes the best RLE sequence for a line + */ +static void qtrle_encode_line(QtrleEncContext *s, AVFrame *p, int line, uint8_t **buf) +{ + int width=s->avctx->width; + int i; + signed char rlecode; + + /* We will use it to compute the best bulk copy sequence */ + unsigned int bulkcount; + /* This will be the number of pixels equal to the preivous frame one's + * starting from the ith pixel */ + unsigned int skipcount; + /* This will be the number of consecutive equal pixels in the current + * frame, starting from the ith one also */ + unsigned int repeatcount; + + /* The cost of the three different possibilities */ + int total_bulk_cost; + int total_skip_cost; + int total_repeat_cost; + + int temp_cost; + int j; + + uint8_t *this_line = p-> data[0] + line*p->linesize[0] + (width - 1)*s->pixel_size; + uint8_t *prev_line = s->previous_frame.data[0] + line*p->linesize[0] + (width - 1)*s->pixel_size; + + s->length_table[width] = 0; + skipcount = 0; + + for (i = width - 1; i >= 0; i--) { + + if (!s->frame.key_frame && !memcmp(this_line, prev_line, s->pixel_size)) + skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP); + else + skipcount = 0; + + total_skip_cost = s->length_table[i + skipcount] + 2; + s->skip_table[i] = skipcount; + + + if (i < width - 1 && !memcmp(this_line, this_line + s->pixel_size, s->pixel_size)) + repeatcount = FFMIN(repeatcount + 1, MAX_RLE_REPEAT); + else + repeatcount = 1; + + total_repeat_cost = s->length_table[i + repeatcount] + 1 + s->pixel_size; + + /* skip code is free for the first pixel, it costs one byte for repeat and bulk copy + * so let's make it aware */ + if (i == 0) { + total_skip_cost--; + total_repeat_cost++; + } + + if (repeatcount > 1 && (skipcount == 0 || total_repeat_cost < total_skip_cost)) { + /* repeat is the best */ + s->length_table[i] = total_repeat_cost; + s->rlecode_table[i] = -repeatcount; + } + else if (skipcount > 0) { + /* skip is the best choice here */ + s->length_table[i] = total_skip_cost; + s->rlecode_table[i] = 0; + } + else { + /* We cannot do neither skip nor repeat + * thus we search for the best bulk copy to do */ + + int limit = FFMIN(width - i, MAX_RLE_BULK); + + temp_cost = 1 + s->pixel_size + !i; + total_bulk_cost = INT_MAX; + + for (j = 1; j <= limit; j++) { + if (s->length_table[i + j] + temp_cost < total_bulk_cost) { + /* We have found a better bulk copy ... */ + total_bulk_cost = s->length_table[i + j] + temp_cost; + bulkcount = j; + } + temp_cost += s->pixel_size; + } + + s->length_table[i] = total_bulk_cost; + s->rlecode_table[i] = bulkcount; + } + + this_line -= s->pixel_size; + prev_line -= s->pixel_size; + } + + /* Good ! Now we have the best sequence for this line, let's ouput it */ + + /* We do a special case for the first pixel so that we avoid testing it in + * the whole loop */ + + i=0; + this_line = p-> data[0] + line*p->linesize[0]; + prev_line = s->previous_frame.data[0] + line*p->linesize[0]; + + if (s->rlecode_table[0] == 0) { + bytestream_put_byte(buf, s->skip_table[0] + 1); + i += s->skip_table[0]; + } + else bytestream_put_byte(buf, 1); + + + while (i < width) { + rlecode = s->rlecode_table[i]; + bytestream_put_byte(buf, rlecode); + if (rlecode == 0) { + /* Write a skip sequence */ + bytestream_put_byte(buf, s->skip_table[i] + 1); + i += s->skip_table[i]; + } + else if (rlecode > 0) { + /* bulk copy */ + bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size); + i += rlecode; + } + else { + /* repeat the bits */ + bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size); + i -= rlecode; + } + } + bytestream_put_byte(buf, -1); // end RLE line +} + +/** Encodes frame including header */ +static int encode_frame(QtrleEncContext *s, AVFrame *p, uint8_t *buf) +{ + int i; + int start_line = 0; + int end_line = s->avctx->height; + uint8_t *orig_buf = buf; + + if (!s->frame.key_frame) { + for (start_line = 0; start_line < s->avctx->height; start_line++) + if (memcmp(p->data[0] + start_line*p->linesize[0], + s->previous_frame.data[0] + start_line*p->linesize[0], + p->linesize[0])) + break; + + for (end_line=s->avctx->height; end_line > start_line; end_line--) + if (memcmp(p->data[0] + (end_line - 1)*p->linesize[0], + s->previous_frame.data[0] + (end_line - 1)*p->linesize[0], + p->linesize[0])) + break; + } + + bytestream_put_be32(&buf, 0); // CHUNK SIZE, patched later + + if ((start_line == 0 && end_line == s->avctx->height) || start_line == s->avctx->height) + bytestream_put_be16(&buf, 0); // header + else { + bytestream_put_be16(&buf, 8); // header + bytestream_put_be16(&buf, start_line); // starting line + bytestream_put_be16(&buf, 0); // unknown + bytestream_put_be16(&buf, end_line - start_line); // lines to update + bytestream_put_be16(&buf, 0); // unknown + } + for (i = start_line; i < end_line; i++) + qtrle_encode_line(s, p, i, &buf); + + bytestream_put_byte(&buf, 0); // zero skip code = frame finished + AV_WB32(orig_buf, buf - orig_buf); // patch the chunk size + return buf - orig_buf; +} + +static int qtrle_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) +{ + QtrleEncContext * const s = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p = &s->frame; + int chunksize; + + *p = *pict; + + if (buf_size < s->max_buf_size) { + /* Upper bound check for compressed data */ + av_log(avctx, AV_LOG_ERROR, "buf_size %d < %d\n", buf_size, s->max_buf_size); + return -1; + } + + if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) { + /* I-Frame */ + p->pict_type = FF_I_TYPE; + p->key_frame = 1; + } else { + /* P-Frame */ + p->pict_type = FF_P_TYPE; + p->key_frame = 0; + } + + chunksize = encode_frame(s, pict, buf); + + /* save the current frame */ + av_picture_copy(&s->previous_frame, (AVPicture *)p, avctx->pix_fmt, avctx->width, avctx->height); + return chunksize; +} + +static int qtrle_encode_end(AVCodecContext *avctx) +{ + QtrleEncContext *s = avctx->priv_data; + + avpicture_free(&s->previous_frame); + av_free(s->rlecode_table); + av_free(s->length_table); + av_free(s->skip_table); + return 0; +} + +AVCodec qtrle_encoder = { + "qtrle", + CODEC_TYPE_VIDEO, + CODEC_ID_QTRLE, + sizeof(QtrleEncContext), + qtrle_encode_init, + qtrle_encode_frame, + qtrle_encode_end, + .pix_fmts = (enum PixelFormat[]){PIX_FMT_RGB24, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/ra144.c b/contrib/ffmpeg/libavcodec/ra144.c index c4f4b813b..30fd4a417 100644 --- a/contrib/ffmpeg/libavcodec/ra144.c +++ b/contrib/ffmpeg/libavcodec/ra144.c @@ -251,7 +251,7 @@ static void final(Real144_internal *glob, short *i1, short *i2, void *out, int * } /* Decode 20-byte input */ -static void unpack_input(unsigned char *input, unsigned int *output) +static void unpack_input(const unsigned char *input, unsigned int *output) { unsigned int outbuffer[28]; unsigned short inbuffer[10]; @@ -427,10 +427,9 @@ static void dec2(Real144_internal *glob, int *data, int *inp, int n, int f, int /* Uncompress one block (20 bytes -> 160*2 bytes) */ static int ra144_decode_frame(AVCodecContext * avctx, void *vdata, int *data_size, - uint8_t * buf, int buf_size) + const uint8_t * buf, int buf_size) { unsigned int a,b,c; - long s; signed short *shptr; unsigned int *lptr,*temp; const short **dptr; @@ -484,13 +483,8 @@ static int ra144_decode_frame(AVCodecContext * avctx, glob->resetflag=0; shptr=glob->output_buffer; - while (shptr<glob->output_buffer+BLOCKSIZE) { - s=*(shptr++)<<2; - *data=s; - if (s>32767) *data=32767; - if (s<-32767) *data=-32768; - data++; - } + while (shptr<glob->output_buffer+BLOCKSIZE) + *data++=av_clip_int16(*(shptr++)<<2); b+=30; } diff --git a/contrib/ffmpeg/libavcodec/ra144.h b/contrib/ffmpeg/libavcodec/ra144.h index 6d477b2f8..0d7a14a4f 100644 --- a/contrib/ffmpeg/libavcodec/ra144.h +++ b/contrib/ffmpeg/libavcodec/ra144.h @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef RA144TABLES_H -#define RA144TABLES_H +#ifndef FFMPEG_RA144_H +#define FFMPEG_RA144_H /* 14.4 data tables */ static const unsigned short sqrt_table[4096]={ @@ -2425,4 +2425,4 @@ decodetable1,decodetable2,decodetable3,decodetable4,decodetable5, decodetable6,decodetable7,decodetable8,decodetable9,decodetable10, decodetable11}; -#endif /* RA144TABLES_H */ +#endif /* FFMPEG_RA144_H */ diff --git a/contrib/ffmpeg/libavcodec/ra288.c b/contrib/ffmpeg/libavcodec/ra288.c index 9ba5209ab..ad36ff2ec 100644 --- a/contrib/ffmpeg/libavcodec/ra288.c +++ b/contrib/ffmpeg/libavcodec/ra288.c @@ -49,7 +49,7 @@ static void colmult(float *tgt, float *m1, const float *m2, int n); /* initial decode */ -static void unpack(unsigned short *tgt, unsigned char *src, unsigned int len) +static void unpack(unsigned short *tgt, const unsigned char *src, unsigned int len) { int x,y,z; int n,temp; @@ -208,7 +208,7 @@ static void prodsum(float *tgt, float *src, int len, int n) } } -static void * decode_block(AVCodecContext * avctx, unsigned char *in, signed short int *out,unsigned len) +static void * decode_block(AVCodecContext * avctx, const unsigned char *in, signed short int *out,unsigned len) { int x,y; Real288_internal *glob=avctx->priv_data; @@ -228,7 +228,7 @@ static void * decode_block(AVCodecContext * avctx, unsigned char *in, signed sho /* Decode a block (celp) */ static int ra288_decode_frame(AVCodecContext * avctx, void *data, int *data_size, - uint8_t * buf, int buf_size) + const uint8_t * buf, int buf_size) { void *datao; diff --git a/contrib/ffmpeg/libavcodec/ra288.h b/contrib/ffmpeg/libavcodec/ra288.h index 8cc290397..e222035a2 100644 --- a/contrib/ffmpeg/libavcodec/ra288.h +++ b/contrib/ffmpeg/libavcodec/ra288.h @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef RA288TABLES_H -#define RA288TABLES_H +#ifndef FFMPEG_RA288_H +#define FFMPEG_RA288_H static const float amptable[8]={ 0.515625, 0.90234375, 1.57910156, 2.76342773, -0.515625,-0.90234375,-1.57910156,-2.76342773 }; @@ -202,4 +202,4 @@ static const float table2a[10]={ 0.553955078, 0.50201416, 0.454956055, 0.41229248, 0.373657227 }; -#endif /* RA288TABLES_H */ +#endif /* FFMPEG_RA288_H */ diff --git a/contrib/ffmpeg/libavcodec/rangecoder.c b/contrib/ffmpeg/libavcodec/rangecoder.c index fcd564ace..34cda723f 100644 --- a/contrib/ffmpeg/libavcodec/rangecoder.c +++ b/contrib/ffmpeg/libavcodec/rangecoder.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -35,8 +34,8 @@ #include <string.h> #include "avcodec.h" -#include "common.h" #include "rangecoder.h" +#include "bytestream.h" void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size){ @@ -54,8 +53,7 @@ void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size){ /* cast to avoid compiler warning */ ff_init_range_encoder(c, (uint8_t *) buf, buf_size); - c->low =(*c->bytestream++)<<8; - c->low+= *c->bytestream++; + c->low = bytestream_get_be16(&c->bytestream); } void ff_build_rac_states(RangeCoder *c, int factor, int max_p){ @@ -111,9 +109,10 @@ int ff_rac_terminate(RangeCoder *c){ return c->bytestream - c->bytestream_start; } -#if 0 //selftest +#ifdef TEST #define SIZE 10240 -int main(){ +#undef random +int main(void){ RangeCoder c; uint8_t b[9*SIZE]; uint8_t r[9*SIZE]; @@ -135,7 +134,7 @@ START_TIMER STOP_TIMER("put_rac") } - ff_put_rac_terminate(&c); + ff_rac_terminate(&c); ff_init_range_decoder(&c, b, SIZE); @@ -150,4 +149,4 @@ STOP_TIMER("get_rac") return 0; } -#endif +#endif /* TEST */ diff --git a/contrib/ffmpeg/libavcodec/rangecoder.h b/contrib/ffmpeg/libavcodec/rangecoder.h index 68bd3b60e..4726afb56 100644 --- a/contrib/ffmpeg/libavcodec/rangecoder.h +++ b/contrib/ffmpeg/libavcodec/rangecoder.h @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -25,6 +24,13 @@ * Range coder. */ +#ifndef FFMPEG_RANGECODER_H +#define FFMPEG_RANGECODER_H + +#include <stdint.h> +#include <assert.h> +#include "common.h" + typedef struct RangeCoder{ int low; int range; @@ -66,6 +72,13 @@ static inline void renorm_encoder(RangeCoder *c){ } } +static inline int get_rac_count(RangeCoder *c){ + int x= c->bytestream - c->bytestream_start + c->outstanding_count; + if(c->outstanding_byte >= 0) + x++; + return 8*x - av_log2(c->range); +} + static inline void put_rac(RangeCoder *c, uint8_t * const state, int bit){ int range1= (c->range * (*state)) >> 8; @@ -96,7 +109,7 @@ static inline void refill(RangeCoder *c){ static inline int get_rac(RangeCoder *c, uint8_t * const state){ int range1= (c->range * (*state)) >> 8; - int attribute_unused one_mask; + int av_unused one_mask; c->range -= range1; #if 1 @@ -125,3 +138,4 @@ static inline int get_rac(RangeCoder *c, uint8_t * const state){ #endif } +#endif /* FFMPEG_RANGECODER_H */ diff --git a/contrib/ffmpeg/libavcodec/ratecontrol.c b/contrib/ffmpeg/libavcodec/ratecontrol.c index 6d9270da8..d289a19cb 100644 --- a/contrib/ffmpeg/libavcodec/ratecontrol.c +++ b/contrib/ffmpeg/libavcodec/ratecontrol.c @@ -31,7 +31,7 @@ #include "mpegvideo.h" #include "eval.h" -#undef NDEBUG // allways check asserts, the speed effect is far too small to disable them +#undef NDEBUG // Always check asserts, the speed effect is far too small to disable them. #include <assert.h> #ifndef M_E @@ -66,7 +66,7 @@ int ff_rate_control_init(MpegEncContext *s) { RateControlContext *rcc= &s->rc_context; int i; - char *error = NULL; + const char *error = NULL; static const char *const_names[]={ "PI", "E", @@ -138,7 +138,7 @@ int ff_rate_control_init(MpegEncContext *s) i+= s->max_b_frames; if(i<=0 || i>=INT_MAX / sizeof(RateControlEntry)) return -1; - rcc->entry = (RateControlEntry*)av_mallocz(i*sizeof(RateControlEntry)); + rcc->entry = av_mallocz(i*sizeof(RateControlEntry)); rcc->num_entries= i; /* init all to skipped p frames (with b frames we might have a not encoded frame at the end FIXME) */ @@ -160,7 +160,7 @@ int ff_rate_control_init(MpegEncContext *s) next= strchr(p, ';'); if(next){ - (*next)=0; //sscanf in unbelieavle slow on looong strings //FIXME copy / dont write + (*next)=0; //sscanf in unbelievably slow on looong strings //FIXME copy / do not write next++; } e= sscanf(p, " in:%d ", &picture_number); @@ -184,7 +184,7 @@ int ff_rate_control_init(MpegEncContext *s) //FIXME maybe move to end if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) { -#ifdef CONFIG_XVID +#ifdef CONFIG_LIBXVID return ff_xvid_rate_control_init(s); #else av_log(s->avctx, AV_LOG_ERROR, "XviD ratecontrol requires libavcodec compiled with XviD support\n"); @@ -201,6 +201,10 @@ int ff_rate_control_init(MpegEncContext *s) rcc->pass1_rc_eq_output_sum= 0.001; rcc->pass1_wanted_bits=0.001; + if(s->avctx->qblur > 1.0){ + av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n"); + return -1; + } /* init stuff with the user specified complexity */ if(s->avctx->rc_initial_cplx){ for(i=0; i<60*30; i++){ @@ -239,7 +243,7 @@ int ff_rate_control_init(MpegEncContext *s) bits= rce.i_tex_bits + rce.p_tex_bits; q= get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i); - rcc->pass1_wanted_bits+= s->bit_rate/(1/av_q2d(s->avctx->time_base)); //FIXME missbehaves a little for variable fps + rcc->pass1_wanted_bits+= s->bit_rate/(1/av_q2d(s->avctx->time_base)); //FIXME misbehaves a little for variable fps } } @@ -256,7 +260,7 @@ void ff_rate_control_uninit(MpegEncContext *s) ff_eval_free(rcc->rc_eq_eval); av_freep(&rcc->entry); -#ifdef CONFIG_XVID +#ifdef CONFIG_LIBXVID if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) ff_xvid_rate_control_uninit(s); #endif @@ -367,6 +371,7 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_f q= -q*s->avctx->i_quant_factor + s->avctx->i_quant_offset; else if(pict_type==B_TYPE && s->avctx->b_quant_factor<0.0) q= -q*s->avctx->b_quant_factor + s->avctx->b_quant_offset; + if(q<1) q=1; return q; } @@ -382,6 +387,7 @@ static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, doubl q= last_p_q *FFABS(a->i_quant_factor) + a->i_quant_offset; else if(pict_type==B_TYPE && a->b_quant_factor>0.0) q= last_non_b_q* a->b_quant_factor + a->b_quant_offset; + if(q<1) q=1; /* last qscale / qdiff stuff */ if(rcc->last_non_b_pict_type==pict_type || pict_type!=I_TYPE){ @@ -392,7 +398,7 @@ static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, doubl else if(q < last_q - maxdiff) q= last_q - maxdiff; } - rcc->last_qscale_for[pict_type]= q; //Note we cant do that after blurring + rcc->last_qscale_for[pict_type]= q; //Note we cannot do that after blurring if(pict_type!=B_TYPE) rcc->last_non_b_pict_type= pict_type; @@ -601,7 +607,7 @@ static void adaptive_quantization(MpegEncContext *s, double q){ bits_tab[i]= bits; } - /* handle qmin/qmax cliping */ + /* handle qmin/qmax clipping */ if(s->flags&CODEC_FLAG_NORMALIZE_AQP){ float factor= bits_sum/cplx_sum; for(i=0; i<s->mb_num; i++){ @@ -672,7 +678,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) Picture * const pic= &s->current_picture; emms_c(); -#ifdef CONFIG_XVID +#ifdef CONFIG_LIBXVID if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) return ff_xvid_rate_estimate_qscale(s, dry_run); #endif @@ -693,8 +699,23 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) rce= &rcc->entry[picture_number]; wanted_bits= rce->expected_bits; }else{ + Picture *dts_pic; rce= &local_rce; - wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps); + + //FIXME add a dts field to AVFrame and ensure its set and use it here instead of reordering + //but the reordering is simpler for now until h.264 b pyramid must be handeld + if(s->pict_type == B_TYPE || s->low_delay) + dts_pic= s->current_picture_ptr; + else + dts_pic= s->last_picture_ptr; + +//if(dts_pic) +// av_log(NULL, AV_LOG_ERROR, "%Ld %Ld %Ld %d\n", s->current_picture_ptr->pts, s->user_specified_pts, dts_pic->pts, picture_number); + + if(!dts_pic || dts_pic->pts == AV_NOPTS_VALUE) + wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps); + else + wanted_bits= (uint64_t)(s->bit_rate*(double)dts_pic->pts/fps); } diff= s->total_bits - wanted_bits; diff --git a/contrib/ffmpeg/libavcodec/ratecontrol.h b/contrib/ffmpeg/libavcodec/ratecontrol.h index c428923a5..8704b4301 100644 --- a/contrib/ffmpeg/libavcodec/ratecontrol.h +++ b/contrib/ffmpeg/libavcodec/ratecontrol.h @@ -20,14 +20,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AVCODEC_RATECONTROL_H -#define AVCODEC_RATECONTROL_H +#ifndef FFMPEG_RATECONTROL_H +#define FFMPEG_RATECONTROL_H /** * @file ratecontrol.h * ratecontrol header. */ +#include <stdio.h> +#include <stdint.h> #include "eval.h" typedef struct Predictor{ @@ -99,5 +101,5 @@ int ff_xvid_rate_control_init(struct MpegEncContext *s); void ff_xvid_rate_control_uninit(struct MpegEncContext *s); float ff_xvid_rate_estimate_qscale(struct MpegEncContext *s, int dry_run); -#endif /* AVCODEC_RATECONTROL_H */ +#endif /* FFMPEG_RATECONTROL_H */ diff --git a/contrib/ffmpeg/libavcodec/raw.c b/contrib/ffmpeg/libavcodec/raw.c index 268779803..d0cf50d9e 100644 --- a/contrib/ffmpeg/libavcodec/raw.c +++ b/contrib/ffmpeg/libavcodec/raw.c @@ -25,19 +25,9 @@ */ #include "avcodec.h" +#include "raw.h" -typedef struct RawVideoContext { - unsigned char * buffer; /* block of memory for holding one frame */ - int length; /* number of bytes in buffer */ - AVFrame pic; ///< AVCodecContext.coded_frame -} RawVideoContext; - -typedef struct PixelFormatTag { - int pix_fmt; - unsigned int fourcc; -} PixelFormatTag; - -static const PixelFormatTag pixelFormatTags[] = { +const PixelFormatTag ff_raw_pixelFormatTags[] = { { PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */ { PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') }, { PIX_FMT_YUV420P, MKTAG('Y', 'V', '1', '2') }, @@ -51,6 +41,7 @@ static const PixelFormatTag pixelFormatTags[] = { { PIX_FMT_YUYV422, MKTAG('Y', 'U', 'Y', '2') }, /* Packed formats */ { PIX_FMT_YUYV422, MKTAG('Y', '4', '2', '2') }, { PIX_FMT_UYVY422, MKTAG('U', 'Y', 'V', 'Y') }, + { PIX_FMT_UYVY422, MKTAG('H', 'D', 'Y', 'C') }, { PIX_FMT_GRAY8, MKTAG('G', 'R', 'E', 'Y') }, { PIX_FMT_RGB555, MKTAG('R', 'G', 'B', 15) }, { PIX_FMT_BGR555, MKTAG('B', 'G', 'R', 15) }, @@ -64,38 +55,9 @@ static const PixelFormatTag pixelFormatTags[] = { { -1, 0 }, }; -static const PixelFormatTag pixelFormatBpsAVI[] = { - { PIX_FMT_PAL8, 8 }, - { PIX_FMT_RGB555, 15 }, - { PIX_FMT_RGB555, 16 }, - { PIX_FMT_BGR24, 24 }, - { PIX_FMT_RGB32, 32 }, - { -1, 0 }, -}; - -static const PixelFormatTag pixelFormatBpsMOV[] = { - /* FIXME fix swscaler to support those */ - /* http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/chapter_4_section_2.html */ - { PIX_FMT_PAL8, 8 }, - { PIX_FMT_BGR555, 16 }, - { PIX_FMT_RGB24, 24 }, - { PIX_FMT_BGR32_1, 32 }, - { -1, 0 }, -}; - -static int findPixelFormat(const PixelFormatTag *tags, unsigned int fourcc) -{ - while (tags->pix_fmt >= 0) { - if (tags->fourcc == fourcc) - return tags->pix_fmt; - tags++; - } - return PIX_FMT_YUV420P; -} - unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat fmt) { - const PixelFormatTag * tags = pixelFormatTags; + const PixelFormatTag * tags = ff_raw_pixelFormatTags; while (tags->pix_fmt >= 0) { if (tags->pix_fmt == fmt) return tags->fourcc; @@ -103,122 +65,3 @@ unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat fmt) } return 0; } - -/* RAW Decoder Implementation */ - -static int raw_init_decoder(AVCodecContext *avctx) -{ - RawVideoContext *context = avctx->priv_data; - - if (avctx->codec_tag == MKTAG('r','a','w',' ')) - avctx->pix_fmt = findPixelFormat(pixelFormatBpsMOV, avctx->bits_per_sample); - else if (avctx->codec_tag) - avctx->pix_fmt = findPixelFormat(pixelFormatTags, avctx->codec_tag); - else if (avctx->bits_per_sample) - avctx->pix_fmt = findPixelFormat(pixelFormatBpsAVI, avctx->bits_per_sample); - - context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); - context->buffer = av_malloc(context->length); - context->pic.pict_type = FF_I_TYPE; - context->pic.key_frame = 1; - - avctx->coded_frame= &context->pic; - - if (!context->buffer) - return -1; - - return 0; -} - -static void flip(AVCodecContext *avctx, AVPicture * picture){ - if(!avctx->codec_tag && avctx->bits_per_sample && picture->linesize[2]==0){ - picture->data[0] += picture->linesize[0] * (avctx->height-1); - picture->linesize[0] *= -1; - } -} - -static int raw_decode(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - RawVideoContext *context = avctx->priv_data; - - AVFrame * frame = (AVFrame *) data; - AVPicture * picture = (AVPicture *) data; - - frame->interlaced_frame = avctx->coded_frame->interlaced_frame; - frame->top_field_first = avctx->coded_frame->top_field_first; - - if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) - return -1; - - avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height); - if(avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length){ - frame->data[1]= context->buffer; - } - if (avctx->palctrl && avctx->palctrl->palette_changed) { - memcpy(frame->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); - avctx->palctrl->palette_changed = 0; - } - - flip(avctx, picture); - - if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2')) - { - // swap fields - unsigned char *tmp = picture->data[1]; - picture->data[1] = picture->data[2]; - picture->data[2] = tmp; - } - - *data_size = sizeof(AVPicture); - return buf_size; -} - -static int raw_close_decoder(AVCodecContext *avctx) -{ - RawVideoContext *context = avctx->priv_data; - - av_freep(&context->buffer); - return 0; -} - -/* RAW Encoder Implementation */ -#ifdef CONFIG_RAWVIDEO_ENCODER -static int raw_init_encoder(AVCodecContext *avctx) -{ - avctx->coded_frame = (AVFrame *)avctx->priv_data; - avctx->coded_frame->pict_type = FF_I_TYPE; - avctx->coded_frame->key_frame = 1; - if(!avctx->codec_tag) - avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt); - return 0; -} - -static int raw_encode(AVCodecContext *avctx, - unsigned char *frame, int buf_size, void *data) -{ - return avpicture_layout((AVPicture *)data, avctx->pix_fmt, avctx->width, - avctx->height, frame, buf_size); -} - -AVCodec rawvideo_encoder = { - "rawvideo", - CODEC_TYPE_VIDEO, - CODEC_ID_RAWVIDEO, - sizeof(AVFrame), - raw_init_encoder, - raw_encode, -}; -#endif // CONFIG_RAWVIDEO_ENCODER - -AVCodec rawvideo_decoder = { - "rawvideo", - CODEC_TYPE_VIDEO, - CODEC_ID_RAWVIDEO, - sizeof(RawVideoContext), - raw_init_decoder, - NULL, - raw_close_decoder, - raw_decode, -}; diff --git a/contrib/ffmpeg/libavcodec/raw.h b/contrib/ffmpeg/libavcodec/raw.h new file mode 100644 index 000000000..1110114e2 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/raw.h @@ -0,0 +1,39 @@ +/* + * Raw Video Codec + * 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 raw.h + * Raw Video Codec + */ + +#ifndef FFMPEG_RAW_H +#define FFMPEG_RAW_H + +#include "avcodec.h" + +typedef struct PixelFormatTag { + int pix_fmt; + unsigned int fourcc; +} PixelFormatTag; + +extern const PixelFormatTag ff_raw_pixelFormatTags[]; + +#endif /* FFMPEG_RAW_H */ diff --git a/contrib/ffmpeg/libavcodec/rawdec.c b/contrib/ffmpeg/libavcodec/rawdec.c new file mode 100644 index 000000000..11d2a185e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rawdec.c @@ -0,0 +1,165 @@ +/* + * Raw Video Decoder + * 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 rawdec.c + * Raw Video Decoder + */ + +#include "avcodec.h" +#include "raw.h" + +typedef struct RawVideoContext { + unsigned char * buffer; /* block of memory for holding one frame */ + int length; /* number of bytes in buffer */ + AVFrame pic; ///< AVCodecContext.coded_frame +} RawVideoContext; + +static const PixelFormatTag pixelFormatBpsAVI[] = { + { PIX_FMT_PAL8, 4 }, + { PIX_FMT_PAL8, 8 }, + { PIX_FMT_RGB555, 15 }, + { PIX_FMT_RGB555, 16 }, + { PIX_FMT_BGR24, 24 }, + { PIX_FMT_RGB32, 32 }, + { -1, 0 }, +}; + +static const PixelFormatTag pixelFormatBpsMOV[] = { + /* FIXME fix swscaler to support those */ + /* http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/chapter_4_section_2.html */ + { PIX_FMT_PAL8, 4 }, + { PIX_FMT_PAL8, 8 }, + { PIX_FMT_BGR555, 16 }, + { PIX_FMT_RGB24, 24 }, + { PIX_FMT_BGR32_1, 32 }, + { -1, 0 }, +}; + +static int findPixelFormat(const PixelFormatTag *tags, unsigned int fourcc) +{ + while (tags->pix_fmt >= 0) { + if (tags->fourcc == fourcc) + return tags->pix_fmt; + tags++; + } + return PIX_FMT_YUV420P; +} + +static int raw_init_decoder(AVCodecContext *avctx) +{ + RawVideoContext *context = avctx->priv_data; + + if (avctx->codec_tag == MKTAG('r','a','w',' ')) + avctx->pix_fmt = findPixelFormat(pixelFormatBpsMOV, avctx->bits_per_sample); + else if (avctx->codec_tag) + avctx->pix_fmt = findPixelFormat(ff_raw_pixelFormatTags, avctx->codec_tag); + else if (avctx->bits_per_sample) + avctx->pix_fmt = findPixelFormat(pixelFormatBpsAVI, avctx->bits_per_sample); + + context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); + context->buffer = av_malloc(context->length); + context->pic.pict_type = FF_I_TYPE; + context->pic.key_frame = 1; + + avctx->coded_frame= &context->pic; + + if (!context->buffer) + return -1; + + return 0; +} + +static void flip(AVCodecContext *avctx, AVPicture * picture){ + if(!avctx->codec_tag && avctx->bits_per_sample && picture->linesize[2]==0){ + picture->data[0] += picture->linesize[0] * (avctx->height-1); + picture->linesize[0] *= -1; + } +} + +static int raw_decode(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + RawVideoContext *context = avctx->priv_data; + + AVFrame * frame = (AVFrame *) data; + AVPicture * picture = (AVPicture *) data; + + frame->interlaced_frame = avctx->coded_frame->interlaced_frame; + frame->top_field_first = avctx->coded_frame->top_field_first; + + //4bpp raw in avi and mov (yes this is ugly ...) + if(avctx->bits_per_sample == 4 && avctx->pix_fmt==PIX_FMT_PAL8 && + (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))){ + int i; + for(i=256*2; i+1 < context->length>>1; i++){ + context->buffer[2*i+0]= buf[i-256*2]>>4; + context->buffer[2*i+1]= buf[i-256*2]&15; + } + buf= context->buffer + 256*4; + buf_size= context->length - 256*4; + } + + if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) + return -1; + + avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height); + if(avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length){ + frame->data[1]= context->buffer; + } + if (avctx->palctrl && avctx->palctrl->palette_changed) { + memcpy(frame->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); + avctx->palctrl->palette_changed = 0; + } + + flip(avctx, picture); + + if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2')) + { + // swap fields + unsigned char *tmp = picture->data[1]; + picture->data[1] = picture->data[2]; + picture->data[2] = tmp; + } + + *data_size = sizeof(AVPicture); + return buf_size; +} + +static int raw_close_decoder(AVCodecContext *avctx) +{ + RawVideoContext *context = avctx->priv_data; + + av_freep(&context->buffer); + return 0; +} + +AVCodec rawvideo_decoder = { + "rawvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_RAWVIDEO, + sizeof(RawVideoContext), + raw_init_decoder, + NULL, + raw_close_decoder, + raw_decode, +}; diff --git a/contrib/ffmpeg/libavcodec/rawenc.c b/contrib/ffmpeg/libavcodec/rawenc.c new file mode 100644 index 000000000..61608bcc3 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rawenc.c @@ -0,0 +1,54 @@ +/* + * Raw Video Encoder + * 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 rawenc.c + * Raw Video Encoder + */ + +#include "avcodec.h" +#include "raw.h" + +static int raw_init_encoder(AVCodecContext *avctx) +{ + avctx->coded_frame = (AVFrame *)avctx->priv_data; + avctx->coded_frame->pict_type = FF_I_TYPE; + avctx->coded_frame->key_frame = 1; + if(!avctx->codec_tag) + avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt); + return 0; +} + +static int raw_encode(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) +{ + return avpicture_layout((AVPicture *)data, avctx->pix_fmt, avctx->width, + avctx->height, frame, buf_size); +} + +AVCodec rawvideo_encoder = { + "rawvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_RAWVIDEO, + sizeof(AVFrame), + raw_init_encoder, + raw_encode, +}; diff --git a/contrib/ffmpeg/libavcodec/rectangle.h b/contrib/ffmpeg/libavcodec/rectangle.h new file mode 100644 index 000000000..4dd9028f1 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rectangle.h @@ -0,0 +1,121 @@ +/* + * rectangle filling function + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> + * + * 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 rectangle.h + * useful rectangle filling function + * @author Michael Niedermayer <michaelni@gmx.at> + */ + +#ifndef FFMPEG_RECTANGLE_H +#define FFMPEG_RECTANGLE_H + +#include "common.h" + +/** + * fill a rectangle. + * @param h height of the rectangle, should be a constant + * @param w width of the rectangle, should be a constant + * @param size the size of val (1 or 4), should be a constant + */ +static av_always_inline void fill_rectangle(void *vp, int w, int h, int stride, uint32_t val, int size){ + uint8_t *p= (uint8_t*)vp; + assert(size==1 || size==4); + assert(w<=4); + + w *= size; + stride *= size; + + assert((((long)vp)&(FFMIN(w, STRIDE_ALIGN)-1)) == 0); + assert((stride&(w-1))==0); + if(w==2){ + const uint16_t v= size==4 ? val : val*0x0101; + *(uint16_t*)(p + 0*stride)= v; + if(h==1) return; + *(uint16_t*)(p + 1*stride)= v; + if(h==2) return; + *(uint16_t*)(p + 2*stride)= v; + *(uint16_t*)(p + 3*stride)= v; + }else if(w==4){ + const uint32_t v= size==4 ? val : val*0x01010101; + *(uint32_t*)(p + 0*stride)= v; + if(h==1) return; + *(uint32_t*)(p + 1*stride)= v; + if(h==2) return; + *(uint32_t*)(p + 2*stride)= v; + *(uint32_t*)(p + 3*stride)= v; + }else if(w==8){ + //gcc can't optimize 64bit math on x86_32 +#if defined(ARCH_X86_64) || (defined(MP_WORDSIZE) && MP_WORDSIZE >= 64) + const uint64_t v= val*0x0100000001ULL; + *(uint64_t*)(p + 0*stride)= v; + if(h==1) return; + *(uint64_t*)(p + 1*stride)= v; + if(h==2) return; + *(uint64_t*)(p + 2*stride)= v; + *(uint64_t*)(p + 3*stride)= v; + }else if(w==16){ + const uint64_t v= val*0x0100000001ULL; + *(uint64_t*)(p + 0+0*stride)= v; + *(uint64_t*)(p + 8+0*stride)= v; + *(uint64_t*)(p + 0+1*stride)= v; + *(uint64_t*)(p + 8+1*stride)= v; + if(h==2) return; + *(uint64_t*)(p + 0+2*stride)= v; + *(uint64_t*)(p + 8+2*stride)= v; + *(uint64_t*)(p + 0+3*stride)= v; + *(uint64_t*)(p + 8+3*stride)= v; +#else + *(uint32_t*)(p + 0+0*stride)= val; + *(uint32_t*)(p + 4+0*stride)= val; + if(h==1) return; + *(uint32_t*)(p + 0+1*stride)= val; + *(uint32_t*)(p + 4+1*stride)= val; + if(h==2) return; + *(uint32_t*)(p + 0+2*stride)= val; + *(uint32_t*)(p + 4+2*stride)= val; + *(uint32_t*)(p + 0+3*stride)= val; + *(uint32_t*)(p + 4+3*stride)= val; + }else if(w==16){ + *(uint32_t*)(p + 0+0*stride)= val; + *(uint32_t*)(p + 4+0*stride)= val; + *(uint32_t*)(p + 8+0*stride)= val; + *(uint32_t*)(p +12+0*stride)= val; + *(uint32_t*)(p + 0+1*stride)= val; + *(uint32_t*)(p + 4+1*stride)= val; + *(uint32_t*)(p + 8+1*stride)= val; + *(uint32_t*)(p +12+1*stride)= val; + if(h==2) return; + *(uint32_t*)(p + 0+2*stride)= val; + *(uint32_t*)(p + 4+2*stride)= val; + *(uint32_t*)(p + 8+2*stride)= val; + *(uint32_t*)(p +12+2*stride)= val; + *(uint32_t*)(p + 0+3*stride)= val; + *(uint32_t*)(p + 4+3*stride)= val; + *(uint32_t*)(p + 8+3*stride)= val; + *(uint32_t*)(p +12+3*stride)= val; +#endif + }else + assert(0); + assert(h==4); +} + +#endif /* FFMPEG_RECTANGLE_H */ diff --git a/contrib/ffmpeg/libavcodec/remove_extradata_bsf.c b/contrib/ffmpeg/libavcodec/remove_extradata_bsf.c new file mode 100644 index 000000000..95bd98bef --- /dev/null +++ b/contrib/ffmpeg/libavcodec/remove_extradata_bsf.c @@ -0,0 +1,55 @@ +/* + * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> + * + * 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" + + +static int remove_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe){ + int cmd= args ? *args : 0; + AVCodecParserContext *s; + + if(!bsfc->parser){ + bsfc->parser= av_parser_init(avctx->codec_id); + } + s= bsfc->parser; + + if(s && s->parser->split){ + if( (((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)) && cmd=='a') + ||(!keyframe && cmd=='k') + ||(cmd=='e' || !cmd) + ){ + int i= s->parser->split(avctx, buf, buf_size); + buf += i; + buf_size -= i; + } + } + *poutbuf= (uint8_t *) buf; + *poutbuf_size= buf_size; + + return 0; +} + +AVBitStreamFilter remove_extradata_bsf={ + "remove_extra", + 0, + remove_extradata, +}; diff --git a/contrib/ffmpeg/libavcodec/resample.c b/contrib/ffmpeg/libavcodec/resample.c index ea5c6d61c..c6547d8d8 100644 --- a/contrib/ffmpeg/libavcodec/resample.c +++ b/contrib/ffmpeg/libavcodec/resample.c @@ -1,5 +1,5 @@ /* - * Sample rate convertion for both audio and video + * samplerate conversion for both audio and video * Copyright (c) 2000 Fabrice Bellard. * * This file is part of FFmpeg. @@ -21,7 +21,7 @@ /** * @file resample.c - * Sample rate convertion for both audio and video. + * samplerate conversion for both audio and video */ #include "avcodec.h" @@ -133,14 +133,14 @@ ReSampleContext *audio_resample_init(int output_channels, int input_channels, if ( input_channels > 2) { - av_log(NULL, AV_LOG_ERROR, "Resampling with input channels greater than 2 unsupported."); + av_log(NULL, AV_LOG_ERROR, "Resampling with input channels greater than 2 unsupported.\n"); return NULL; } s = av_mallocz(sizeof(ReSampleContext)); if (!s) { - av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for resample context."); + av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for resample context.\n"); return NULL; } @@ -185,15 +185,15 @@ int audio_resample(ReSampleContext *s, short *output, short *input, int nb_sampl /* XXX: move those malloc to resample init code */ for(i=0; i<s->filter_channels; i++){ - bufin[i]= (short*) av_malloc( (nb_samples + s->temp_len) * sizeof(short) ); + bufin[i]= av_malloc( (nb_samples + s->temp_len) * sizeof(short) ); memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short)); buftmp2[i] = bufin[i] + s->temp_len; } /* make some zoom to avoid round pb */ - lenout= (int)(nb_samples * s->ratio) + 16; - bufout[0]= (short*) av_malloc( lenout * sizeof(short) ); - bufout[1]= (short*) av_malloc( lenout * sizeof(short) ); + lenout= 4*nb_samples * s->ratio + 16; + bufout[0]= av_malloc( lenout * sizeof(short) ); + bufout[1]= av_malloc( lenout * sizeof(short) ); if (s->input_channels == 2 && s->output_channels == 1) { diff --git a/contrib/ffmpeg/libavcodec/resample2.c b/contrib/ffmpeg/libavcodec/resample2.c index 4209b9705..da1443d98 100644 --- a/contrib/ffmpeg/libavcodec/resample2.c +++ b/contrib/ffmpeg/libavcodec/resample2.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -27,7 +26,6 @@ */ #include "avcodec.h" -#include "common.h" #include "dsputil.h" #ifndef CONFIG_RESAMPLE_HP @@ -95,7 +93,7 @@ static double bessel(double x){ * @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16 */ void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){ - int ph, i, v; + int ph, i; double x, y, w, tab[tap_count]; const int center= (tap_count-1)/2; @@ -178,8 +176,8 @@ void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_coun } /** - * initalizes a audio resampler. - * note, if either rate is not a integer then simply scale both rates up so they are + * Initializes an audio resampler. + * Note, if either rate is not an integer then simply scale both rates up so they are. */ AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){ AVResampleContext *c= av_mallocz(sizeof(AVResampleContext)); @@ -281,7 +279,7 @@ int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int } #ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE - dst[dst_index] = av_clip(lrintf(val), -32768, 32767); + dst[dst_index] = av_clip_int16(lrintf(val)); #else val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT; dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val; diff --git a/contrib/ffmpeg/libavcodec/rl.h b/contrib/ffmpeg/libavcodec/rl.h index 1c2aae25a..ecea2c891 100644 --- a/contrib/ffmpeg/libavcodec/rl.h +++ b/contrib/ffmpeg/libavcodec/rl.h @@ -1,10 +1,35 @@ +/* + * Copyright (c) 2000-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 rl.h * rl header. */ -#ifndef AVCODEC_RL_H -#define AVCODEC_RL_H +#ifndef FFMPEG_RL_H +#define FFMPEG_RL_H + +#include <stdint.h> +#include "bitstream.h" +#include "mpegvideo.h" /** RLTable. */ typedef struct RLTable { @@ -16,7 +41,7 @@ typedef struct RLTable { 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 + VLC vlc; ///< decoding only deprecated FIXME remove RL_VLC_ELEM *rl_vlc[32]; ///< decoding only } RLTable; @@ -39,4 +64,4 @@ static inline int get_rl_index(const RLTable *rl, int last, int run, int level) return index + level - 1; } -#endif +#endif /* FFMPEG_RL_H */ diff --git a/contrib/ffmpeg/libavcodec/rle.c b/contrib/ffmpeg/libavcodec/rle.c new file mode 100644 index 000000000..2fb0d0e48 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rle.c @@ -0,0 +1,84 @@ +/* + * RLE encoder + * Copyright (c) 2007 Bobby Bingham + * + * 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" +#include "rle.h" + +/** + * Count up to 127 consecutive pixels which are either all the same or + * all differ from the previous and next pixels. + * @param start Pointer to the first pixel + * @param len Maximum number of pixels + * @param bpp Bytes per pixel + * @param same 1 if searching for identical pixel values. 0 for differing + * @return Number of matching consecutive pixels found + */ +static int count_pixels(const uint8_t *start, int len, int bpp, int same) +{ + const uint8_t *pos; + int count = 1; + + for(pos = start + bpp; count < FFMIN(128, len); pos += bpp, count ++) { + if(same != !memcmp(pos-bpp, pos, bpp)) { + if(!same) { + /* if bpp == 1, then 0 1 1 0 is more efficiently encoded as a single + * raw block of pixels. for larger bpp, RLE is as good or better */ + if(bpp == 1 && count + 1 < FFMIN(128, len) && *pos != *(pos+1)) + continue; + + /* if RLE can encode the next block better than as a raw block, + * back up and leave _all_ the identical pixels for RLE */ + count --; + } + break; + } + } + + return count; +} + +int ff_rle_encode(uint8_t *outbuf, int out_size, const uint8_t *ptr , int bpp, int w, + int add_rep, int xor_rep, int add_raw, int xor_raw) +{ + int count, x; + uint8_t *out = outbuf; + + for(x = 0; x < w; x += count) { + /* see if we can encode the next set of pixels with RLE */ + if((count = count_pixels(ptr, w-x, bpp, 1)) > 1) { + if(out + bpp + 1 > outbuf + out_size) return -1; + *out++ = (count ^ xor_rep) + add_rep; + memcpy(out, ptr, bpp); + out += bpp; + } else { + /* fall back on uncompressed */ + count = count_pixels(ptr, w-x, bpp, 0); + *out++ = (count ^ xor_raw) + add_raw; + + if(out + bpp*count > outbuf + out_size) return -1; + memcpy(out, ptr, bpp * count); + out += bpp * count; + } + + ptr += count * bpp; + } + + return out - outbuf; +} diff --git a/contrib/ffmpeg/libavcodec/rle.h b/contrib/ffmpeg/libavcodec/rle.h new file mode 100644 index 000000000..14d07084f --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rle.h @@ -0,0 +1,39 @@ +/* + * RLE encoder + * + * 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 + */ + +#ifndef FFMPEG_RLE_H +#define FFMPEG_RLE_H + +#include <stdint.h> + +/** + * RLE compress the row, with maximum size of out_size. Value before repeated bytes is (count ^ xor_rep) + add_rep. + * Value before raw bytes is (count ^ xor_raw) + add_raw. + * @param outbuf Output buffer + * @param out_size Maximum output size + * @param ptr Input buffer + * @param bpp Bytes per pixel + * @param w Image width + * @return Size of output in bytes, or -1 if larger than out_size + */ +int ff_rle_encode(uint8_t *outbuf, int out_size, const uint8_t *inbuf, int bpp, int w, + int add_rep, int xor_rep, int add_raw, int xor_raw); + +#endif /* FFMPEG_RLE_H */ diff --git a/contrib/ffmpeg/libavcodec/roqaudioenc.c b/contrib/ffmpeg/libavcodec/roqaudioenc.c new file mode 100644 index 000000000..f76079e1d --- /dev/null +++ b/contrib/ffmpeg/libavcodec/roqaudioenc.c @@ -0,0 +1,177 @@ +/* + * RoQ audio encoder + * + * Copyright (c) 2005 Eric Lasota + * Based on RoQ specs (c)2001 Tim Ferguson + * + * 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" +#include "bytestream.h" + +#define ROQ_FIRST_FRAME_SIZE (735*8) +#define ROQ_FRAME_SIZE 735 + + +#define MAX_DPCM (127*127) +static unsigned char dpcmValues[MAX_DPCM]; + + +typedef struct +{ + short lastSample[2]; +} ROQDPCMContext_t; + +static void roq_dpcm_table_init(void) +{ + int i; + + /* Create a table of quick DPCM values */ + for (i=0; i<MAX_DPCM; i++) { + int s= ff_sqrt(i); + int mid= s*s + s; + dpcmValues[i]= s + (i>mid); + } +} + +static int roq_dpcm_encode_init(AVCodecContext *avctx) +{ + ROQDPCMContext_t *context = avctx->priv_data; + + if (avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, "Audio must be mono or stereo\n"); + return -1; + } + if (avctx->sample_rate != 22050) { + av_log(avctx, AV_LOG_ERROR, "Audio must be 22050 Hz\n"); + return -1; + } + if (avctx->sample_fmt != SAMPLE_FMT_S16) { + av_log(avctx, AV_LOG_ERROR, "Audio must be signed 16-bit\n"); + return -1; + } + + roq_dpcm_table_init(); + + avctx->frame_size = ROQ_FIRST_FRAME_SIZE; + + context->lastSample[0] = context->lastSample[1] = 0; + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + + return 0; +} + +static unsigned char dpcm_predict(short *previous, short current) +{ + int diff; + int negative; + int result; + int predicted; + + diff = current - *previous; + + negative = diff<0; + diff = FFABS(diff); + + if (diff >= MAX_DPCM) + result = 127; + else + result = dpcmValues[diff]; + + /* See if this overflows */ + retry: + diff = result*result; + if (negative) + diff = -diff; + predicted = *previous + diff; + + /* If it overflows, back off a step */ + if (predicted > 32767 || predicted < -32768) { + result--; + goto retry; + } + + /* Add the sign bit */ + result |= negative << 7; //if (negative) result |= 128; + + *previous = predicted; + + return result; +} + +static int roq_dpcm_encode_frame(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) +{ + int i, samples, stereo, ch; + short *in; + unsigned char *out; + + ROQDPCMContext_t *context = avctx->priv_data; + + stereo = (avctx->channels == 2); + + if (stereo) { + context->lastSample[0] &= 0xFF00; + context->lastSample[1] &= 0xFF00; + } + + out = frame; + in = data; + + bytestream_put_byte(&out, stereo ? 0x21 : 0x20); + bytestream_put_byte(&out, 0x10); + bytestream_put_le32(&out, avctx->frame_size*avctx->channels); + + if (stereo) { + bytestream_put_byte(&out, (context->lastSample[1])>>8); + bytestream_put_byte(&out, (context->lastSample[0])>>8); + } else + bytestream_put_le16(&out, context->lastSample[0]); + + /* Write the actual samples */ + samples = avctx->frame_size; + for (i=0; i<samples; i++) + for (ch=0; ch<avctx->channels; ch++) + *out++ = dpcm_predict(&context->lastSample[ch], *in++); + + /* Use smaller frames from now on */ + avctx->frame_size = ROQ_FRAME_SIZE; + + /* Return the result size */ + return out - frame; +} + +static int roq_dpcm_encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + + return 0; +} + +AVCodec roq_dpcm_encoder = { + "roq_dpcm", + CODEC_TYPE_AUDIO, + CODEC_ID_ROQ_DPCM, + sizeof(ROQDPCMContext_t), + roq_dpcm_encode_init, + roq_dpcm_encode_frame, + roq_dpcm_encode_close, + NULL, +}; diff --git a/contrib/ffmpeg/libavcodec/roqvideo.c b/contrib/ffmpeg/libavcodec/roqvideo.c index 2a9aa6242..53d60a19e 100644 --- a/contrib/ffmpeg/libavcodec/roqvideo.c +++ b/contrib/ffmpeg/libavcodec/roqvideo.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2003 the ffmpeg project + * Copyright (C) 2003 Mike Melanson + * Copyright (C) 2003 Dr. Tim Ferguson * * This file is part of FFmpeg. * @@ -16,462 +17,122 @@ * 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 roqvideo.c - * Id RoQ Video Decoder by Dr. Tim Ferguson - * For more information about the Id RoQ format, visit: - * http://www.csse.monash.edu.au/~timf/ + * Id RoQ Video common functions based on work by Dr. Tim Ferguson */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "common.h" #include "avcodec.h" -#include "dsputil.h" - -typedef struct { - unsigned char y0, y1, y2, y3, u, v; -} roq_cell; - -typedef struct { - int idx[4]; -} roq_qcell; - -static int uiclip[1024], *uiclp; /* clipping table */ -#define avg2(a,b) uiclp[(((int)(a)+(int)(b)+1)>>1)] -#define avg4(a,b,c,d) uiclp[(((int)(a)+(int)(b)+(int)(c)+(int)(d)+2)>>2)] - -typedef struct RoqContext { - - AVCodecContext *avctx; - DSPContext dsp; - AVFrame frames[2]; - AVFrame *last_frame; - AVFrame *current_frame; - int first_frame; - int y_stride; - int c_stride; - - roq_cell cells[256]; - roq_qcell qcells[256]; - - unsigned char *buf; - int size; - -} RoqContext; +#include "roqvideo.h" -#define RoQ_INFO 0x1001 -#define RoQ_QUAD_CODEBOOK 0x1002 -#define RoQ_QUAD_VQ 0x1011 -#define RoQ_SOUND_MONO 0x1020 -#define RoQ_SOUND_STEREO 0x1021 - -#define RoQ_ID_MOT 0x00 -#define RoQ_ID_FCC 0x01 -#define RoQ_ID_SLD 0x02 -#define RoQ_ID_CCC 0x03 - -#define get_byte(in_buffer) *(in_buffer++) -#define get_word(in_buffer) ((unsigned short)(in_buffer += 2, \ - (in_buffer[-1] << 8 | in_buffer[-2]))) -#define get_long(in_buffer) ((unsigned long)(in_buffer += 4, \ - (in_buffer[-1] << 24 | in_buffer[-2] << 16 | in_buffer[-3] << 8 | in_buffer[-4]))) - - -static void apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) +static inline void block_copy(unsigned char *out, unsigned char *in, + int outstride, int instride, int sz) { - unsigned char *yptr; - - yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x; - *yptr++ = cell->y0; - *yptr++ = cell->y1; - yptr += (ri->y_stride - 2); - *yptr++ = cell->y2; - *yptr++ = cell->y3; - ri->current_frame->data[1][(y/2) * (ri->c_stride) + x/2] = cell->u; - ri->current_frame->data[2][(y/2) * (ri->c_stride) + x/2] = cell->v; + int rows = sz; + while(rows--) { + memcpy(out, in, sz); + out += outstride; + in += instride; + } } -static void apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) +void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell) { - unsigned long row_inc, c_row_inc; - register unsigned char y0, y1, u, v; - unsigned char *yptr, *uptr, *vptr; - - yptr = ri->current_frame->data[0] + (y * ri->y_stride) + x; - uptr = ri->current_frame->data[1] + (y/2) * (ri->c_stride) + x/2; - vptr = ri->current_frame->data[2] + (y/2) * (ri->c_stride) + x/2; - - row_inc = ri->y_stride - 4; - c_row_inc = (ri->c_stride) - 2; - *yptr++ = y0 = cell->y0; *uptr++ = u = cell->u; *vptr++ = v = cell->v; - *yptr++ = y0; - *yptr++ = y1 = cell->y1; *uptr++ = u; *vptr++ = v; - *yptr++ = y1; - - yptr += row_inc; - - *yptr++ = y0; - *yptr++ = y0; - *yptr++ = y1; - *yptr++ = y1; - - yptr += row_inc; uptr += c_row_inc; vptr += c_row_inc; - - *yptr++ = y0 = cell->y2; *uptr++ = u; *vptr++ = v; - *yptr++ = y0; - *yptr++ = y1 = cell->y3; *uptr++ = u; *vptr++ = v; - *yptr++ = y1; - - yptr += row_inc; - - *yptr++ = y0; - *yptr++ = y0; - *yptr++ = y1; - *yptr++ = y1; + unsigned char *bptr; + int boffs,stride; + + stride = ri->current_frame->linesize[0]; + boffs = y*stride + x; + + bptr = ri->current_frame->data[0] + boffs; + bptr[0 ] = cell->y[0]; + bptr[1 ] = cell->y[1]; + bptr[stride ] = cell->y[2]; + bptr[stride+1] = cell->y[3]; + + stride = ri->current_frame->linesize[1]; + boffs = y*stride + x; + + bptr = ri->current_frame->data[1] + boffs; + bptr[0 ] = + bptr[1 ] = + bptr[stride ] = + bptr[stride+1] = cell->u; + + bptr = ri->current_frame->data[2] + boffs; + bptr[0 ] = + bptr[1 ] = + bptr[stride ] = + bptr[stride+1] = cell->v; } -static void apply_motion_4x4(RoqContext *ri, int x, int y, unsigned char mv, - signed char mean_x, signed char mean_y) +void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell) { - int i, hw, mx, my; - unsigned char *pa, *pb; - - mx = x + 8 - (mv >> 4) - mean_x; - my = y + 8 - (mv & 0xf) - mean_y; - - /* check MV against frame boundaries */ - if ((mx < 0) || (mx > ri->avctx->width - 4) || - (my < 0) || (my > ri->avctx->height - 4)) { - av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", - mx, my, ri->avctx->width, ri->avctx->height); - return; - } - - pa = ri->current_frame->data[0] + (y * ri->y_stride) + x; - pb = ri->last_frame->data[0] + (my * ri->y_stride) + mx; - for(i = 0; i < 4; i++) { - pa[0] = pb[0]; - pa[1] = pb[1]; - pa[2] = pb[2]; - pa[3] = pb[3]; - pa += ri->y_stride; - pb += ri->y_stride; - } - - hw = ri->y_stride/2; - pa = ri->current_frame->data[1] + (y * ri->y_stride)/4 + x/2; - pb = ri->last_frame->data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; - - for(i = 0; i < 2; i++) { - switch(((my & 0x01) << 1) | (mx & 0x01)) { - - case 0: - pa[0] = pb[0]; - pa[1] = pb[1]; - pa[hw] = pb[hw]; - pa[hw+1] = pb[hw+1]; - break; - - case 1: - pa[0] = avg2(pb[0], pb[1]); - pa[1] = avg2(pb[1], pb[2]); - pa[hw] = avg2(pb[hw], pb[hw+1]); - pa[hw+1] = avg2(pb[hw+1], pb[hw+2]); - break; - - case 2: - pa[0] = avg2(pb[0], pb[hw]); - pa[1] = avg2(pb[1], pb[hw+1]); - pa[hw] = avg2(pb[hw], pb[hw*2]); - pa[hw+1] = avg2(pb[hw+1], pb[(hw*2)+1]); - break; - - case 3: - pa[0] = avg4(pb[0], pb[1], pb[hw], pb[hw+1]); - pa[1] = avg4(pb[1], pb[2], pb[hw+1], pb[hw+2]); - pa[hw] = avg4(pb[hw], pb[hw+1], pb[hw*2], pb[(hw*2)+1]); - pa[hw+1] = avg4(pb[hw+1], pb[hw+2], pb[(hw*2)+1], pb[(hw*2)+1]); - break; - } - - pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2; - pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; - } + unsigned char *bptr; + int boffs,stride; + + stride = ri->current_frame->linesize[0]; + boffs = y*stride + x; + + bptr = ri->current_frame->data[0] + boffs; + bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = cell->y[0]; + bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = cell->y[1]; + bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = cell->y[2]; + bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->y[3]; + + stride = ri->current_frame->linesize[1]; + boffs = y*stride + x; + + bptr = ri->current_frame->data[1] + boffs; + bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = + bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = + bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = + bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->u; + + bptr = ri->current_frame->data[2] + boffs; + bptr[ 0] = bptr[ 1] = bptr[stride ] = bptr[stride +1] = + bptr[ 2] = bptr[ 3] = bptr[stride +2] = bptr[stride +3] = + bptr[stride*2 ] = bptr[stride*2+1] = bptr[stride*3 ] = bptr[stride*3+1] = + bptr[stride*2+2] = bptr[stride*2+3] = bptr[stride*3+2] = bptr[stride*3+3] = cell->v; } -static void apply_motion_8x8(RoqContext *ri, int x, int y, - unsigned char mv, signed char mean_x, signed char mean_y) + +static inline void apply_motion_generic(RoqContext *ri, int x, int y, int deltax, + int deltay, int sz) { - int mx, my, i, j, hw; - unsigned char *pa, *pb; + int mx, my, cp; - mx = x + 8 - (mv >> 4) - mean_x; - my = y + 8 - (mv & 0xf) - mean_y; + mx = x + deltax; + my = y + deltay; /* check MV against frame boundaries */ - if ((mx < 0) || (mx > ri->avctx->width - 8) || - (my < 0) || (my > ri->avctx->height - 8)) { + if ((mx < 0) || (mx > ri->width - sz) || + (my < 0) || (my > ri->height - sz)) { av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n", - mx, my, ri->avctx->width, ri->avctx->height); + mx, my, ri->width, ri->height); return; } - pa = ri->current_frame->data[0] + (y * ri->y_stride) + x; - pb = ri->last_frame->data[0] + (my * ri->y_stride) + mx; - for(i = 0; i < 8; i++) { - pa[0] = pb[0]; - pa[1] = pb[1]; - pa[2] = pb[2]; - pa[3] = pb[3]; - pa[4] = pb[4]; - pa[5] = pb[5]; - pa[6] = pb[6]; - pa[7] = pb[7]; - pa += ri->y_stride; - pb += ri->y_stride; - } - - hw = ri->c_stride; - pa = ri->current_frame->data[1] + (y * ri->y_stride)/4 + x/2; - pb = ri->last_frame->data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; - for(j = 0; j < 2; j++) { - for(i = 0; i < 4; i++) { - switch(((my & 0x01) << 1) | (mx & 0x01)) { - - case 0: - pa[0] = pb[0]; - pa[1] = pb[1]; - pa[2] = pb[2]; - pa[3] = pb[3]; - break; - - case 1: - pa[0] = avg2(pb[0], pb[1]); - pa[1] = avg2(pb[1], pb[2]); - pa[2] = avg2(pb[2], pb[3]); - pa[3] = avg2(pb[3], pb[4]); - break; - - case 2: - pa[0] = avg2(pb[0], pb[hw]); - pa[1] = avg2(pb[1], pb[hw+1]); - pa[2] = avg2(pb[2], pb[hw+2]); - pa[3] = avg2(pb[3], pb[hw+3]); - break; - - case 3: - pa[0] = avg4(pb[0], pb[1], pb[hw], pb[hw+1]); - pa[1] = avg4(pb[1], pb[2], pb[hw+1], pb[hw+2]); - pa[2] = avg4(pb[2], pb[3], pb[hw+2], pb[hw+3]); - pa[3] = avg4(pb[3], pb[4], pb[hw+3], pb[hw+4]); - break; - } - pa += ri->c_stride; - pb += ri->c_stride; - } - - pa = ri->current_frame->data[2] + (y * ri->y_stride)/4 + x/2; - pb = ri->last_frame->data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2; + for(cp = 0; cp < 3; cp++) { + int outstride = ri->current_frame->linesize[cp]; + int instride = ri->last_frame ->linesize[cp]; + block_copy(ri->current_frame->data[cp] + y*outstride + x, + ri->last_frame->data[cp] + my*instride + mx, + outstride, instride, sz); } } -static void roqvideo_decode_frame(RoqContext *ri) -{ - unsigned int chunk_id = 0, chunk_arg = 0; - unsigned long chunk_size = 0; - int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1; - int vqid, bpos, xpos, ypos, xp, yp, x, y; - int frame_stats[2][4] = {{0},{0}}; - roq_qcell *qcell; - unsigned char *buf = ri->buf; - unsigned char *buf_end = ri->buf + ri->size; - - while (buf < buf_end) { - chunk_id = get_word(buf); - chunk_size = get_long(buf); - chunk_arg = get_word(buf); - - if(chunk_id == RoQ_QUAD_VQ) - break; - if(chunk_id == RoQ_QUAD_CODEBOOK) { - if((nv1 = chunk_arg >> 8) == 0) - nv1 = 256; - if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size) - nv2 = 256; - for(i = 0; i < nv1; i++) { - ri->cells[i].y0 = get_byte(buf); - ri->cells[i].y1 = get_byte(buf); - ri->cells[i].y2 = get_byte(buf); - ri->cells[i].y3 = get_byte(buf); - ri->cells[i].u = get_byte(buf); - ri->cells[i].v = get_byte(buf); - } - for(i = 0; i < nv2; i++) - for(j = 0; j < 4; j++) - ri->qcells[i].idx[j] = get_byte(buf); - } - } - - bpos = xpos = ypos = 0; - while(bpos < chunk_size) { - for (yp = ypos; yp < ypos + 16; yp += 8) - for (xp = xpos; xp < xpos + 16; xp += 8) { - if (vqflg_pos < 0) { - vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8); - vqflg_pos = 7; - } - vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; - frame_stats[0][vqid]++; - vqflg_pos--; - switch(vqid) { - case RoQ_ID_MOT: - apply_motion_8x8(ri, xp, yp, 0, 8, 8); - break; - case RoQ_ID_FCC: - apply_motion_8x8(ri, xp, yp, buf[bpos++], chunk_arg >> 8, - chunk_arg & 0xff); - break; - case RoQ_ID_SLD: - qcell = ri->qcells + buf[bpos++]; - apply_vector_4x4(ri, xp, yp, ri->cells + qcell->idx[0]); - apply_vector_4x4(ri, xp+4, yp, ri->cells + qcell->idx[1]); - apply_vector_4x4(ri, xp, yp+4, ri->cells + qcell->idx[2]); - apply_vector_4x4(ri, xp+4, yp+4, ri->cells + qcell->idx[3]); - break; - case RoQ_ID_CCC: - for (k = 0; k < 4; k++) { - x = xp; y = yp; - if(k & 0x01) x += 4; - if(k & 0x02) y += 4; - - if (vqflg_pos < 0) { - vqflg = buf[bpos++]; - vqflg |= (buf[bpos++] << 8); - vqflg_pos = 7; - } - vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; - frame_stats[1][vqid]++; - vqflg_pos--; - switch(vqid) { - case RoQ_ID_MOT: - apply_motion_4x4(ri, x, y, 0, 8, 8); - break; - case RoQ_ID_FCC: - apply_motion_4x4(ri, x, y, buf[bpos++], - chunk_arg >> 8, chunk_arg & 0xff); - break; - case RoQ_ID_SLD: - qcell = ri->qcells + buf[bpos++]; - apply_vector_2x2(ri, x, y, ri->cells + qcell->idx[0]); - apply_vector_2x2(ri, x+2, y, ri->cells + qcell->idx[1]); - apply_vector_2x2(ri, x, y+2, ri->cells + qcell->idx[2]); - apply_vector_2x2(ri, x+2, y+2, ri->cells + qcell->idx[3]); - break; - case RoQ_ID_CCC: - apply_vector_2x2(ri, x, y, ri->cells + buf[bpos]); - apply_vector_2x2(ri, x+2, y, ri->cells + buf[bpos+1]); - apply_vector_2x2(ri, x, y+2, ri->cells + buf[bpos+2]); - apply_vector_2x2(ri, x+2, y+2, ri->cells + buf[bpos+3]); - bpos += 4; - break; - } - } - break; - default: - av_log(ri->avctx, AV_LOG_ERROR, "Unknown vq code: %d\n", vqid); - } - } - - xpos += 16; - if (xpos >= ri->avctx->width) { - xpos -= ri->avctx->width; - ypos += 16; - } - if(ypos >= ri->avctx->height) - break; - } -} - - -static int roq_decode_init(AVCodecContext *avctx) +void ff_apply_motion_4x4(RoqContext *ri, int x, int y, + int deltax, int deltay) { - RoqContext *s = avctx->priv_data; - int i; - - s->avctx = avctx; - s->first_frame = 1; - s->last_frame = &s->frames[0]; - s->current_frame = &s->frames[1]; - avctx->pix_fmt = PIX_FMT_YUV420P; - avctx->has_b_frames = 0; - dsputil_init(&s->dsp, avctx); - - uiclp = uiclip+512; - for(i = -512; i < 512; i++) - uiclp[i] = (i < 0 ? 0 : (i > 255 ? 255 : i)); - - return 0; -} - -static int roq_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - RoqContext *s = avctx->priv_data; - - if (avctx->get_buffer(avctx, s->current_frame)) { - av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); - return -1; - } - s->y_stride = s->current_frame->linesize[0]; - s->c_stride = s->current_frame->linesize[1]; - - s->buf = buf; - s->size = buf_size; - roqvideo_decode_frame(s); - - /* release the last frame if it is allocated */ - if (s->first_frame) - s->first_frame = 0; - else - avctx->release_buffer(avctx, s->last_frame); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = *s->current_frame; - - /* shuffle frames */ - FFSWAP(AVFrame *, s->current_frame, s->last_frame); - - return buf_size; + apply_motion_generic(ri, x, y, deltax, deltay, 4); } -static int roq_decode_end(AVCodecContext *avctx) +void ff_apply_motion_8x8(RoqContext *ri, int x, int y, + int deltax, int deltay) { - RoqContext *s = avctx->priv_data; - - /* release the last frame */ - if (s->last_frame->data[0]) - avctx->release_buffer(avctx, s->last_frame); - - return 0; + apply_motion_generic(ri, x, y, deltax, deltay, 8); } - -AVCodec roq_decoder = { - "roqvideo", - CODEC_TYPE_VIDEO, - CODEC_ID_ROQ, - sizeof(RoqContext), - roq_decode_init, - NULL, - roq_decode_end, - roq_decode_frame, - CODEC_CAP_DR1, -}; diff --git a/contrib/ffmpeg/libavcodec/roqvideo.h b/contrib/ffmpeg/libavcodec/roqvideo.h new file mode 100644 index 000000000..3345635ee --- /dev/null +++ b/contrib/ffmpeg/libavcodec/roqvideo.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2003 Mike Melanson + * Copyright (C) 2003 Dr. Tim Ferguson + * + * 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 + */ + +#ifndef FFMPEG_ROQVIDEO_H +#define FFMPEG_ROQVIDEO_H + +#include "avcodec.h" +#include "dsputil.h" +#include "random.h" + +typedef struct { + unsigned char y[4]; + unsigned char u, v; +} roq_cell; + +typedef struct { + int idx[4]; +} roq_qcell; + +typedef struct { + int d[2]; +} motion_vect; + +typedef struct RoqContext { + + AVCodecContext *avctx; + DSPContext dsp; + AVFrame frames[2]; + AVFrame *last_frame; + AVFrame *current_frame; + int first_frame; + + roq_cell cb2x2[256]; + roq_qcell cb4x4[256]; + + const unsigned char *buf; + int size; + int width, height; + + /* Encoder only data */ + AVRandomState randctx; + uint64_t lambda; + + motion_vect *this_motion4; + motion_vect *last_motion4; + + motion_vect *this_motion8; + motion_vect *last_motion8; + + unsigned int framesSinceKeyframe; + + AVFrame *frame_to_enc; + uint8_t *out_buf; +} RoqContext; + +#define RoQ_INFO 0x1001 +#define RoQ_QUAD_CODEBOOK 0x1002 +#define RoQ_QUAD_VQ 0x1011 +#define RoQ_SOUND_MONO 0x1020 +#define RoQ_SOUND_STEREO 0x1021 + +#define RoQ_ID_MOT 0x00 +#define RoQ_ID_FCC 0x01 +#define RoQ_ID_SLD 0x02 +#define RoQ_ID_CCC 0x03 + +void ff_apply_vector_2x2(RoqContext *ri, int x, int y, roq_cell *cell); +void ff_apply_vector_4x4(RoqContext *ri, int x, int y, roq_cell *cell); + +void ff_apply_motion_4x4(RoqContext *ri, int x, int y, int deltax, int deltay); + +void ff_apply_motion_8x8(RoqContext *ri, int x, int y, int deltax, int deltay); + +#endif /* FFMPEG_ROQVIDEO_H */ diff --git a/contrib/ffmpeg/libavcodec/roqvideodec.c b/contrib/ffmpeg/libavcodec/roqvideodec.c new file mode 100644 index 000000000..a4e32c3fa --- /dev/null +++ b/contrib/ffmpeg/libavcodec/roqvideodec.c @@ -0,0 +1,224 @@ +/* + * 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 + */ + +/** + * @file roqvideodec.c + * Id RoQ Video Decoder by Dr. Tim Ferguson + * For more information about the Id RoQ format, visit: + * http://www.csse.monash.edu.au/~timf/ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "avcodec.h" +#include "bytestream.h" +#include "dsputil.h" +#include "roqvideo.h" + +static void roqvideo_decode_frame(RoqContext *ri) +{ + unsigned int chunk_id = 0, chunk_arg = 0; + unsigned long chunk_size = 0; + int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1; + int vqid, bpos, xpos, ypos, xp, yp, x, y, mx, my; + int frame_stats[2][4] = {{0},{0}}; + roq_qcell *qcell; + const unsigned char *buf = ri->buf; + const unsigned char *buf_end = ri->buf + ri->size; + + while (buf < buf_end) { + chunk_id = bytestream_get_le16(&buf); + chunk_size = bytestream_get_le32(&buf); + chunk_arg = bytestream_get_le16(&buf); + + if(chunk_id == RoQ_QUAD_VQ) + break; + if(chunk_id == RoQ_QUAD_CODEBOOK) { + if((nv1 = chunk_arg >> 8) == 0) + nv1 = 256; + if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size) + nv2 = 256; + for(i = 0; i < nv1; i++) { + ri->cb2x2[i].y[0] = *buf++; + ri->cb2x2[i].y[1] = *buf++; + ri->cb2x2[i].y[2] = *buf++; + ri->cb2x2[i].y[3] = *buf++; + ri->cb2x2[i].u = *buf++; + ri->cb2x2[i].v = *buf++; + } + for(i = 0; i < nv2; i++) + for(j = 0; j < 4; j++) + ri->cb4x4[i].idx[j] = *buf++; + } + } + + bpos = xpos = ypos = 0; + while(bpos < chunk_size) { + for (yp = ypos; yp < ypos + 16; yp += 8) + for (xp = xpos; xp < xpos + 16; xp += 8) { + if (vqflg_pos < 0) { + vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8); + vqflg_pos = 7; + } + vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; + frame_stats[0][vqid]++; + vqflg_pos--; + + switch(vqid) { + case RoQ_ID_MOT: + break; + case RoQ_ID_FCC: + mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8)); + my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg); + ff_apply_motion_8x8(ri, xp, yp, mx, my); + break; + case RoQ_ID_SLD: + qcell = ri->cb4x4 + buf[bpos++]; + ff_apply_vector_4x4(ri, xp, yp, ri->cb2x2 + qcell->idx[0]); + ff_apply_vector_4x4(ri, xp+4, yp, ri->cb2x2 + qcell->idx[1]); + ff_apply_vector_4x4(ri, xp, yp+4, ri->cb2x2 + qcell->idx[2]); + ff_apply_vector_4x4(ri, xp+4, yp+4, ri->cb2x2 + qcell->idx[3]); + break; + case RoQ_ID_CCC: + for (k = 0; k < 4; k++) { + x = xp; y = yp; + if(k & 0x01) x += 4; + if(k & 0x02) y += 4; + + if (vqflg_pos < 0) { + vqflg = buf[bpos++]; + vqflg |= (buf[bpos++] << 8); + vqflg_pos = 7; + } + vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; + frame_stats[1][vqid]++; + vqflg_pos--; + switch(vqid) { + case RoQ_ID_MOT: + break; + case RoQ_ID_FCC: + mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8)); + my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg); + ff_apply_motion_4x4(ri, x, y, mx, my); + break; + case RoQ_ID_SLD: + qcell = ri->cb4x4 + buf[bpos++]; + ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + qcell->idx[0]); + ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + qcell->idx[1]); + ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + qcell->idx[2]); + ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + qcell->idx[3]); + break; + case RoQ_ID_CCC: + ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + buf[bpos]); + ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + buf[bpos+1]); + ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + buf[bpos+2]); + ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + buf[bpos+3]); + bpos += 4; + break; + } + } + break; + default: + av_log(ri->avctx, AV_LOG_ERROR, "Unknown vq code: %d\n", vqid); + } + } + + xpos += 16; + if (xpos >= ri->width) { + xpos -= ri->width; + ypos += 16; + } + if(ypos >= ri->height) + break; + } +} + + +static int roq_decode_init(AVCodecContext *avctx) +{ + RoqContext *s = avctx->priv_data; + + s->avctx = avctx; + s->width = avctx->width; + s->height = avctx->height; + s->last_frame = &s->frames[0]; + s->current_frame = &s->frames[1]; + avctx->pix_fmt = PIX_FMT_YUV444P; + dsputil_init(&s->dsp, avctx); + + return 0; +} + +static int roq_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + RoqContext *s = avctx->priv_data; + int copy= !s->current_frame->data[0]; + + if (avctx->reget_buffer(avctx, s->current_frame)) { + av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); + return -1; + } + + if(copy) + av_picture_copy((AVPicture*)s->current_frame, (AVPicture*)s->last_frame, + avctx->pix_fmt, avctx->width, avctx->height); + + s->buf = buf; + s->size = buf_size; + roqvideo_decode_frame(s); + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = *s->current_frame; + + /* shuffle frames */ + FFSWAP(AVFrame *, s->current_frame, s->last_frame); + + return buf_size; +} + +static int roq_decode_end(AVCodecContext *avctx) +{ + RoqContext *s = avctx->priv_data; + + /* release the last frame */ + if (s->last_frame->data[0]) + avctx->release_buffer(avctx, s->last_frame); + if (s->current_frame->data[0]) + avctx->release_buffer(avctx, s->current_frame); + + return 0; +} + +AVCodec roq_decoder = { + "roqvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_ROQ, + sizeof(RoqContext), + roq_decode_init, + NULL, + roq_decode_end, + roq_decode_frame, + CODEC_CAP_DR1, +}; diff --git a/contrib/ffmpeg/libavcodec/roqvideoenc.c b/contrib/ffmpeg/libavcodec/roqvideoenc.c new file mode 100644 index 000000000..ca939b9c4 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/roqvideoenc.c @@ -0,0 +1,1069 @@ +/* + * RoQ Video Encoder. + * + * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com> + * Copyright (C) 2004-2007 Eric Lasota + * Based on RoQ specs (C) 2001 Tim Ferguson + * + * 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 roqvideoenc.c + * Id RoQ encoder by Vitor. Based on the Switchblade3 library and the + * Switchblade3 FFmpeg glue by Eric Lasota. + */ + +/* + * COSTS: + * Level 1: + * SKIP - 2 bits + * MOTION - 2 + 8 bits + * CODEBOOK - 2 + 8 bits + * SUBDIVIDE - 2 + combined subcel cost + * + * Level 2: + * SKIP - 2 bits + * MOTION - 2 + 8 bits + * CODEBOOK - 2 + 8 bits + * SUBDIVIDE - 2 + 4*8 bits + * + * Maximum cost: 138 bits per cel + * + * Proper evaluation requires LCD fraction comparison, which requires + * Squared Error (SE) loss * savings increase + * + * Maximum savings increase: 136 bits + * Maximum SE loss without overflow: 31580641 + * Components in 8x8 supercel: 192 + * Maximum SE precision per component: 164482 + * >65025, so no truncation is needed (phew) + */ + +#include <string.h> +#include <unistd.h> + +#include "roqvideo.h" +#include "bytestream.h" +#include "elbg.h" + +#define CHROMA_BIAS 1 + +/** + * Maximum number of generated 4x4 codebooks. Can't be 256 to workaround a + * Quake 3 bug. + */ +#define MAX_CBS_4x4 255 + +#define MAX_CBS_2x2 256 ///< Maximum number of 2x2 codebooks. + +/* The cast is useful when multiplying it by INT_MAX */ +#define ROQ_LAMBDA_SCALE ((uint64_t) FF_LAMBDA_SCALE) + +/* Macroblock support functions */ +static void unpack_roq_cell(roq_cell *cell, uint8_t u[4*3]) +{ + memcpy(u , cell->y, 4); + memset(u+4, cell->u, 4); + memset(u+8, cell->v, 4); +} + +static void unpack_roq_qcell(uint8_t cb2[], roq_qcell *qcell, uint8_t u[4*4*3]) +{ + int i,cp; + static const int offsets[4] = {0, 2, 8, 10}; + + for (cp=0; cp<3; cp++) + for (i=0; i<4; i++) { + u[4*4*cp + offsets[i] ] = cb2[qcell->idx[i]*2*2*3 + 4*cp ]; + u[4*4*cp + offsets[i]+1] = cb2[qcell->idx[i]*2*2*3 + 4*cp+1]; + u[4*4*cp + offsets[i]+4] = cb2[qcell->idx[i]*2*2*3 + 4*cp+2]; + u[4*4*cp + offsets[i]+5] = cb2[qcell->idx[i]*2*2*3 + 4*cp+3]; + } +} + + +static void enlarge_roq_mb4(uint8_t base[3*16], uint8_t u[3*64]) +{ + int x,y,cp; + + for(cp=0; cp<3; cp++) + for(y=0; y<8; y++) + for(x=0; x<8; x++) + *u++ = base[(y/2)*4 + (x/2) + 16*cp]; +} + +static inline int square(int x) +{ + return x*x; +} + +static inline int eval_sse(uint8_t *a, uint8_t *b, int count) +{ + int diff=0; + + while(count--) + diff += square(*b++ - *a++); + + return diff; +} + +// FIXME Could use DSPContext.sse, but it is not so speed critical (used +// just for motion estimation). +static int block_sse(uint8_t **buf1, uint8_t **buf2, int x1, int y1, int x2, + int y2, int *stride1, int *stride2, int size) +{ + int i, k; + int sse=0; + + for (k=0; k<3; k++) { + int bias = (k ? CHROMA_BIAS : 4); + for (i=0; i<size; i++) + sse += bias*eval_sse(buf1[k] + (y1+i)*stride1[k] + x1, + buf2[k] + (y2+i)*stride2[k] + x2, size); + } + + return sse; +} + +static int eval_motion_dist(RoqContext *enc, int x, int y, motion_vect vect, + int size) +{ + int mx=vect.d[0]; + int my=vect.d[1]; + + if (mx < -7 || mx > 7) + return INT_MAX; + + if (my < -7 || my > 7) + return INT_MAX; + + mx += x; + my += y; + + if ((unsigned) mx > enc->width-size || (unsigned) my > enc->height-size) + return INT_MAX; + + return block_sse(enc->frame_to_enc->data, enc->last_frame->data, x, y, + mx, my, + enc->frame_to_enc->linesize, enc->last_frame->linesize, + size); +} + +/** + * Returns distortion between two macroblocks + */ +static inline int squared_diff_macroblock(uint8_t a[], uint8_t b[], int size) +{ + int cp, sdiff=0; + + for(cp=0;cp<3;cp++) { + int bias = (cp ? CHROMA_BIAS : 4); + sdiff += bias*eval_sse(a, b, size*size); + a += size*size; + b += size*size; + } + + return sdiff; +} + +typedef struct +{ + int eval_dist[4]; + int best_bit_use; + int best_coding; + + int subCels[4]; + motion_vect motion; + int cbEntry; +} subcel_evaluation_t; + +typedef struct +{ + int eval_dist[4]; + int best_coding; + + subcel_evaluation_t subCels[4]; + + motion_vect motion; + int cbEntry; + + int sourceX, sourceY; +} cel_evaluation_t; + +typedef struct +{ + int numCB4; + int numCB2; + int usedCB2[MAX_CBS_2x2]; + int usedCB4[MAX_CBS_4x4]; + uint8_t unpacked_cb2[MAX_CBS_2x2*2*2*3]; + uint8_t unpacked_cb4[MAX_CBS_4x4*4*4*3]; + uint8_t unpacked_cb4_enlarged[MAX_CBS_4x4*8*8*3]; +} roq_codebooks_t; + +/** + * Temporary vars + */ +typedef struct +{ + cel_evaluation_t *cel_evals; + + int f2i4[MAX_CBS_4x4]; + int i2f4[MAX_CBS_4x4]; + int f2i2[MAX_CBS_2x2]; + int i2f2[MAX_CBS_2x2]; + + int mainChunkSize; + + int numCB4; + int numCB2; + + roq_codebooks_t codebooks; + + int *closest_cb2; + int used_option[4]; +} roq_tempdata_t; + +/** + * Initializes cel evaluators and sets their source coordinates + */ +static void create_cel_evals(RoqContext *enc, roq_tempdata_t *tempData) +{ + int n=0, x, y, i; + + tempData->cel_evals = av_malloc(enc->width*enc->height/64 * sizeof(cel_evaluation_t)); + + /* Map to the ROQ quadtree order */ + for (y=0; y<enc->height; y+=16) + for (x=0; x<enc->width; x+=16) + for(i=0; i<4; i++) { + tempData->cel_evals[n ].sourceX = x + (i&1)*8; + tempData->cel_evals[n++].sourceY = y + (i&2)*4; + } +} + +/** + * Get macroblocks from parts of the image + */ +static void get_frame_mb(AVFrame *frame, int x, int y, uint8_t mb[], int dim) +{ + int i, j, cp; + + for (cp=0; cp<3; cp++) { + int stride = frame->linesize[cp]; + for (i=0; i<dim; i++) + for (j=0; j<dim; j++) + *mb++ = frame->data[cp][(y+i)*stride + x + j]; + } +} + +/** + * Find the codebook with the lowest distortion from an image + */ +static int index_mb(uint8_t cluster[], uint8_t cb[], int numCB, + int *outIndex, int dim) +{ + int i, lDiff = INT_MAX, pick=0; + + /* Diff against the others */ + for (i=0; i<numCB; i++) { + int diff = squared_diff_macroblock(cluster, cb + i*dim*dim*3, dim); + if (diff < lDiff) { + lDiff = diff; + pick = i; + } + } + + *outIndex = pick; + return lDiff; +} + +#define EVAL_MOTION(MOTION) \ + do { \ + diff = eval_motion_dist(enc, j, i, MOTION, blocksize); \ + \ + if (diff < lowestdiff) { \ + lowestdiff = diff; \ + bestpick = MOTION; \ + } \ + } while(0) + +static void motion_search(RoqContext *enc, int blocksize) +{ + static const motion_vect offsets[8] = { + {{ 0,-1}}, + {{ 0, 1}}, + {{-1, 0}}, + {{ 1, 0}}, + {{-1, 1}}, + {{ 1,-1}}, + {{-1,-1}}, + {{ 1, 1}}, + }; + + int diff, lowestdiff, oldbest; + int off[3]; + motion_vect bestpick = {{0,0}}; + int i, j, k, offset; + + motion_vect *last_motion; + motion_vect *this_motion; + motion_vect vect, vect2; + + int max=(enc->width/blocksize)*enc->height/blocksize; + + if (blocksize == 4) { + last_motion = enc->last_motion4; + this_motion = enc->this_motion4; + } else { + last_motion = enc->last_motion8; + this_motion = enc->this_motion8; + } + + for (i=0; i<enc->height; i+=blocksize) + for (j=0; j<enc->width; j+=blocksize) { + lowestdiff = eval_motion_dist(enc, j, i, (motion_vect) {{0,0}}, + blocksize); + bestpick.d[0] = 0; + bestpick.d[1] = 0; + + if (blocksize == 4) + EVAL_MOTION(enc->this_motion8[(i/8)*(enc->width/8) + j/8]); + + offset = (i/blocksize)*enc->width/blocksize + j/blocksize; + if (offset < max && offset >= 0) + EVAL_MOTION(last_motion[offset]); + + offset++; + if (offset < max && offset >= 0) + EVAL_MOTION(last_motion[offset]); + + offset = (i/blocksize + 1)*enc->width/blocksize + j/blocksize; + if (offset < max && offset >= 0) + EVAL_MOTION(last_motion[offset]); + + off[0]= (i/blocksize)*enc->width/blocksize + j/blocksize - 1; + off[1]= off[0] - enc->width/blocksize + 1; + off[2]= off[1] + 1; + + if (i) { + + for(k=0; k<2; k++) + vect.d[k]= mid_pred(this_motion[off[0]].d[k], + this_motion[off[1]].d[k], + this_motion[off[2]].d[k]); + + EVAL_MOTION(vect); + for(k=0; k<3; k++) + EVAL_MOTION(this_motion[off[k]]); + } else if(j) + EVAL_MOTION(this_motion[off[0]]); + + vect = bestpick; + + oldbest = -1; + while (oldbest != lowestdiff) { + oldbest = lowestdiff; + for (k=0; k<8; k++) { + vect2 = vect; + vect2.d[0] += offsets[k].d[0]; + vect2.d[1] += offsets[k].d[1]; + EVAL_MOTION(vect2); + } + vect = bestpick; + } + offset = (i/blocksize)*enc->width/blocksize + j/blocksize; + this_motion[offset] = bestpick; + } +} + +/** + * Gets distortion for all options available to a subcel + */ +static void gather_data_for_subcel(subcel_evaluation_t *subcel, int x, + int y, RoqContext *enc, roq_tempdata_t *tempData) +{ + uint8_t mb4[4*4*3]; + uint8_t mb2[2*2*3]; + int cluster_index; + int i, best_dist; + + static const int bitsUsed[4] = {2, 10, 10, 34}; + + if (enc->framesSinceKeyframe >= 1) { + subcel->motion = enc->this_motion4[y*enc->width/16 + x/4]; + + subcel->eval_dist[RoQ_ID_FCC] = + eval_motion_dist(enc, x, y, + enc->this_motion4[y*enc->width/16 + x/4], 4); + } else + subcel->eval_dist[RoQ_ID_FCC] = INT_MAX; + + if (enc->framesSinceKeyframe >= 2) + subcel->eval_dist[RoQ_ID_MOT] = block_sse(enc->frame_to_enc->data, + enc->current_frame->data, x, + y, x, y, + enc->frame_to_enc->linesize, + enc->current_frame->linesize, + 4); + else + subcel->eval_dist[RoQ_ID_MOT] = INT_MAX; + + cluster_index = y*enc->width/16 + x/4; + + get_frame_mb(enc->frame_to_enc, x, y, mb4, 4); + + subcel->eval_dist[RoQ_ID_SLD] = index_mb(mb4, + tempData->codebooks.unpacked_cb4, + tempData->codebooks.numCB4, + &subcel->cbEntry, 4); + + subcel->eval_dist[RoQ_ID_CCC] = 0; + + for(i=0;i<4;i++) { + subcel->subCels[i] = tempData->closest_cb2[cluster_index*4+i]; + + get_frame_mb(enc->frame_to_enc, x+2*(i&1), + y+(i&2), mb2, 2); + + subcel->eval_dist[RoQ_ID_CCC] += + squared_diff_macroblock(tempData->codebooks.unpacked_cb2 + subcel->subCels[i]*2*2*3, mb2, 2); + } + + best_dist = INT_MAX; + for (i=0; i<4; i++) + if (ROQ_LAMBDA_SCALE*subcel->eval_dist[i] + enc->lambda*bitsUsed[i] < + best_dist) { + subcel->best_coding = i; + subcel->best_bit_use = bitsUsed[i]; + best_dist = ROQ_LAMBDA_SCALE*subcel->eval_dist[i] + + enc->lambda*bitsUsed[i]; + } +} + +/** + * Gets distortion for all options available to a cel + */ +static void gather_data_for_cel(cel_evaluation_t *cel, RoqContext *enc, + roq_tempdata_t *tempData) +{ + uint8_t mb8[8*8*3]; + int index = cel->sourceY*enc->width/64 + cel->sourceX/8; + int i, j, best_dist, divide_bit_use; + + int bitsUsed[4] = {2, 10, 10, 0}; + + if (enc->framesSinceKeyframe >= 1) { + cel->motion = enc->this_motion8[index]; + + cel->eval_dist[RoQ_ID_FCC] = + eval_motion_dist(enc, cel->sourceX, cel->sourceY, + enc->this_motion8[index], 8); + } else + cel->eval_dist[RoQ_ID_FCC] = INT_MAX; + + if (enc->framesSinceKeyframe >= 2) + cel->eval_dist[RoQ_ID_MOT] = block_sse(enc->frame_to_enc->data, + enc->current_frame->data, + cel->sourceX, cel->sourceY, + cel->sourceX, cel->sourceY, + enc->frame_to_enc->linesize, + enc->current_frame->linesize,8); + else + cel->eval_dist[RoQ_ID_MOT] = INT_MAX; + + get_frame_mb(enc->frame_to_enc, cel->sourceX, cel->sourceY, mb8, 8); + + cel->eval_dist[RoQ_ID_SLD] = + index_mb(mb8, tempData->codebooks.unpacked_cb4_enlarged, + tempData->codebooks.numCB4, &cel->cbEntry, 8); + + gather_data_for_subcel(cel->subCels + 0, cel->sourceX+0, cel->sourceY+0, enc, tempData); + gather_data_for_subcel(cel->subCels + 1, cel->sourceX+4, cel->sourceY+0, enc, tempData); + gather_data_for_subcel(cel->subCels + 2, cel->sourceX+0, cel->sourceY+4, enc, tempData); + gather_data_for_subcel(cel->subCels + 3, cel->sourceX+4, cel->sourceY+4, enc, tempData); + + cel->eval_dist[RoQ_ID_CCC] = 0; + divide_bit_use = 0; + for (i=0; i<4; i++) { + cel->eval_dist[RoQ_ID_CCC] += + cel->subCels[i].eval_dist[cel->subCels[i].best_coding]; + divide_bit_use += cel->subCels[i].best_bit_use; + } + + best_dist = INT_MAX; + bitsUsed[3] = 2 + divide_bit_use; + + for (i=0; i<4; i++) + if (ROQ_LAMBDA_SCALE*cel->eval_dist[i] + enc->lambda*bitsUsed[i] < + best_dist) { + cel->best_coding = i; + best_dist = ROQ_LAMBDA_SCALE*cel->eval_dist[i] + + enc->lambda*bitsUsed[i]; + } + + tempData->used_option[cel->best_coding]++; + tempData->mainChunkSize += bitsUsed[cel->best_coding]; + + if (cel->best_coding == RoQ_ID_SLD) + tempData->codebooks.usedCB4[cel->cbEntry]++; + + if (cel->best_coding == RoQ_ID_CCC) + for (i=0; i<4; i++) { + if (cel->subCels[i].best_coding == RoQ_ID_SLD) + tempData->codebooks.usedCB4[cel->subCels[i].cbEntry]++; + else if (cel->subCels[i].best_coding == RoQ_ID_CCC) + for (j=0; j<4; j++) + tempData->codebooks.usedCB2[cel->subCels[i].subCels[j]]++; + } +} + +static void remap_codebooks(RoqContext *enc, roq_tempdata_t *tempData) +{ + int i, j, idx=0; + + /* Make remaps for the final codebook usage */ + for (i=0; i<MAX_CBS_4x4; i++) { + if (tempData->codebooks.usedCB4[i]) { + tempData->i2f4[i] = idx; + tempData->f2i4[idx] = i; + for (j=0; j<4; j++) + tempData->codebooks.usedCB2[enc->cb4x4[i].idx[j]]++; + idx++; + } + } + + tempData->numCB4 = idx; + + idx = 0; + for (i=0; i<MAX_CBS_2x2; i++) { + if (tempData->codebooks.usedCB2[i]) { + tempData->i2f2[i] = idx; + tempData->f2i2[idx] = i; + idx++; + } + } + tempData->numCB2 = idx; + +} + +/** + * Write codebook chunk + */ +static void write_codebooks(RoqContext *enc, roq_tempdata_t *tempData) +{ + int i, j; + uint8_t **outp= &enc->out_buf; + + if (tempData->numCB2) { + bytestream_put_le16(outp, RoQ_QUAD_CODEBOOK); + bytestream_put_le32(outp, tempData->numCB2*6 + tempData->numCB4*4); + bytestream_put_byte(outp, tempData->numCB4); + bytestream_put_byte(outp, tempData->numCB2); + + for (i=0; i<tempData->numCB2; i++) { + bytestream_put_buffer(outp, enc->cb2x2[tempData->f2i2[i]].y, 4); + bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].u); + bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].v); + } + + for (i=0; i<tempData->numCB4; i++) + for (j=0; j<4; j++) + bytestream_put_byte(outp, tempData->i2f2[enc->cb4x4[tempData->f2i4[i]].idx[j]]); + + } +} + +static inline uint8_t motion_arg(motion_vect mot) +{ + uint8_t ax = 8 - ((uint8_t) mot.d[0]); + uint8_t ay = 8 - ((uint8_t) mot.d[1]); + return ((ax&15)<<4) | (ay&15); +} + +typedef struct +{ + int typeSpool; + int typeSpoolLength; + uint8_t argumentSpool[64]; + uint8_t *args; + uint8_t **pout; +} CodingSpool; + +/* NOTE: Typecodes must be spooled AFTER arguments!! */ +static void write_typecode(CodingSpool *s, uint8_t type) +{ + s->typeSpool |= (type & 3) << (14 - s->typeSpoolLength); + s->typeSpoolLength += 2; + if (s->typeSpoolLength == 16) { + bytestream_put_le16(s->pout, s->typeSpool); + bytestream_put_buffer(s->pout, s->argumentSpool, + s->args - s->argumentSpool); + s->typeSpoolLength = 0; + s->typeSpool = 0; + s->args = s->argumentSpool; + } +} + +static void reconstruct_and_encode_image(RoqContext *enc, roq_tempdata_t *tempData, int w, int h, int numBlocks) +{ + int i, j, k; + int x, y; + int subX, subY; + int dist=0; + + roq_qcell *qcell; + cel_evaluation_t *eval; + + CodingSpool spool; + + spool.typeSpool=0; + spool.typeSpoolLength=0; + spool.args = spool.argumentSpool; + spool.pout = &enc->out_buf; + + if (tempData->used_option[RoQ_ID_CCC]%2) + tempData->mainChunkSize+=8; //FIXME + + /* Write the video chunk header */ + bytestream_put_le16(&enc->out_buf, RoQ_QUAD_VQ); + bytestream_put_le32(&enc->out_buf, tempData->mainChunkSize/8); + bytestream_put_byte(&enc->out_buf, 0x0); + bytestream_put_byte(&enc->out_buf, 0x0); + + for (i=0; i<numBlocks; i++) { + eval = tempData->cel_evals + i; + + x = eval->sourceX; + y = eval->sourceY; + dist += eval->eval_dist[eval->best_coding]; + + switch (eval->best_coding) { + case RoQ_ID_MOT: + write_typecode(&spool, RoQ_ID_MOT); + break; + + case RoQ_ID_FCC: + bytestream_put_byte(&spool.args, motion_arg(eval->motion)); + + write_typecode(&spool, RoQ_ID_FCC); + ff_apply_motion_8x8(enc, x, y, + eval->motion.d[0], eval->motion.d[1]); + break; + + case RoQ_ID_SLD: + bytestream_put_byte(&spool.args, tempData->i2f4[eval->cbEntry]); + write_typecode(&spool, RoQ_ID_SLD); + + qcell = enc->cb4x4 + eval->cbEntry; + ff_apply_vector_4x4(enc, x , y , enc->cb2x2 + qcell->idx[0]); + ff_apply_vector_4x4(enc, x+4, y , enc->cb2x2 + qcell->idx[1]); + ff_apply_vector_4x4(enc, x , y+4, enc->cb2x2 + qcell->idx[2]); + ff_apply_vector_4x4(enc, x+4, y+4, enc->cb2x2 + qcell->idx[3]); + break; + + case RoQ_ID_CCC: + write_typecode(&spool, RoQ_ID_CCC); + + for (j=0; j<4; j++) { + subX = x + 4*(j&1); + subY = y + 2*(j&2); + + switch(eval->subCels[j].best_coding) { + case RoQ_ID_MOT: + break; + + case RoQ_ID_FCC: + bytestream_put_byte(&spool.args, + motion_arg(eval->subCels[j].motion)); + + ff_apply_motion_4x4(enc, subX, subY, + eval->subCels[j].motion.d[0], + eval->subCels[j].motion.d[1]); + break; + + case RoQ_ID_SLD: + bytestream_put_byte(&spool.args, + tempData->i2f4[eval->subCels[j].cbEntry]); + + qcell = enc->cb4x4 + eval->subCels[j].cbEntry; + + ff_apply_vector_2x2(enc, subX , subY , + enc->cb2x2 + qcell->idx[0]); + ff_apply_vector_2x2(enc, subX+2, subY , + enc->cb2x2 + qcell->idx[1]); + ff_apply_vector_2x2(enc, subX , subY+2, + enc->cb2x2 + qcell->idx[2]); + ff_apply_vector_2x2(enc, subX+2, subY+2, + enc->cb2x2 + qcell->idx[3]); + break; + + case RoQ_ID_CCC: + for (k=0; k<4; k++) { + int cb_idx = eval->subCels[j].subCels[k]; + bytestream_put_byte(&spool.args, + tempData->i2f2[cb_idx]); + + ff_apply_vector_2x2(enc, subX + 2*(k&1), subY + (k&2), + enc->cb2x2 + cb_idx); + } + break; + } + write_typecode(&spool, eval->subCels[j].best_coding); + } + break; + } + } + + /* Flush the remainder of the argument/type spool */ + while (spool.typeSpoolLength) + write_typecode(&spool, 0x0); + +#if 0 + uint8_t *fdata[3] = {enc->frame_to_enc->data[0], + enc->frame_to_enc->data[1], + enc->frame_to_enc->data[2]}; + uint8_t *cdata[3] = {enc->current_frame->data[0], + enc->current_frame->data[1], + enc->current_frame->data[2]}; + av_log(enc->avctx, AV_LOG_ERROR, "Expected distortion: %i Actual: %i\n", + dist, + block_sse(fdata, cdata, 0, 0, 0, 0, + enc->frame_to_enc->linesize, + enc->current_frame->linesize, + enc->width)); //WARNING: Square dimensions implied... +#endif +} + + +/** + * Create a single YUV cell from a 2x2 section of the image + */ +static inline void frame_block_to_cell(uint8_t *block, uint8_t **data, + int top, int left, int *stride) +{ + int i, j, u=0, v=0; + + for (i=0; i<2; i++) + for (j=0; j<2; j++) { + int x = (top+i)*stride[0] + left + j; + *block++ = data[0][x]; + x = (top+i)*stride[1] + left + j; + u += data[1][x]; + v += data[2][x]; + } + + *block++ = (u+2)/4; + *block++ = (v+2)/4; +} + +/** + * Creates YUV clusters for the entire image + */ +static void create_clusters(AVFrame *frame, int w, int h, uint8_t *yuvClusters) +{ + int i, j, k, l; + + for (i=0; i<h; i+=4) + for (j=0; j<w; j+=4) { + for (k=0; k < 2; k++) + for (l=0; l < 2; l++) + frame_block_to_cell(yuvClusters + (l + 2*k)*6, frame->data, + i+2*k, j+2*l, frame->linesize); + yuvClusters += 24; + } +} + +static void generate_codebook(RoqContext *enc, roq_tempdata_t *tempdata, + int *points, int inputCount, roq_cell *results, + int size, int cbsize) +{ + int i, j, k; + int c_size = size*size/4; + int *buf = points; + int *codebook = av_malloc(6*c_size*cbsize*sizeof(int)); + int *closest_cb; + + if (size == 4) + closest_cb = av_malloc(6*c_size*inputCount*sizeof(int)); + else + closest_cb = tempdata->closest_cb2; + + ff_init_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); + ff_do_elbg(points, 6*c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); + + if (size == 4) + av_free(closest_cb); + + buf = codebook; + for (i=0; i<cbsize; i++) + for (k=0; k<c_size; k++) { + for(j=0; j<4; j++) + results->y[j] = *buf++; + + results->u = (*buf++ + CHROMA_BIAS/2)/CHROMA_BIAS; + results->v = (*buf++ + CHROMA_BIAS/2)/CHROMA_BIAS; + results++; + } + + av_free(codebook); +} + +static void generate_new_codebooks(RoqContext *enc, roq_tempdata_t *tempData) +{ + int i,j; + roq_codebooks_t *codebooks = &tempData->codebooks; + int max = enc->width*enc->height/16; + uint8_t mb2[3*4]; + roq_cell *results4 = av_malloc(sizeof(roq_cell)*MAX_CBS_4x4*4); + uint8_t *yuvClusters=av_malloc(sizeof(int)*max*6*4); + int *points = av_malloc(max*6*4*sizeof(int)); + int bias; + + /* Subsample YUV data */ + create_clusters(enc->frame_to_enc, enc->width, enc->height, yuvClusters); + + /* Cast to integer and apply chroma bias */ + for (i=0; i<max*24; i++) { + bias = ((i%6)<4) ? 1 : CHROMA_BIAS; + points[i] = bias*yuvClusters[i]; + } + + /* Create 4x4 codebooks */ + generate_codebook(enc, tempData, points, max, results4, 4, MAX_CBS_4x4); + + codebooks->numCB4 = MAX_CBS_4x4; + + tempData->closest_cb2 = av_malloc(max*4*sizeof(int)); + + /* Create 2x2 codebooks */ + generate_codebook(enc, tempData, points, max*4, enc->cb2x2, 2, MAX_CBS_2x2); + + codebooks->numCB2 = MAX_CBS_2x2; + + /* Unpack 2x2 codebook clusters */ + for (i=0; i<codebooks->numCB2; i++) + unpack_roq_cell(enc->cb2x2 + i, codebooks->unpacked_cb2 + i*2*2*3); + + /* Index all 4x4 entries to the 2x2 entries, unpack, and enlarge */ + for (i=0; i<codebooks->numCB4; i++) { + for (j=0; j<4; j++) { + unpack_roq_cell(&results4[4*i + j], mb2); + index_mb(mb2, codebooks->unpacked_cb2, codebooks->numCB2, + &enc->cb4x4[i].idx[j], 2); + } + unpack_roq_qcell(codebooks->unpacked_cb2, enc->cb4x4 + i, + codebooks->unpacked_cb4 + i*4*4*3); + enlarge_roq_mb4(codebooks->unpacked_cb4 + i*4*4*3, + codebooks->unpacked_cb4_enlarged + i*8*8*3); + } + + av_free(yuvClusters); + av_free(points); + av_free(results4); +} + +static void roq_encode_video(RoqContext *enc) +{ + roq_tempdata_t tempData; + int i; + + memset(&tempData, 0, sizeof(tempData)); + + create_cel_evals(enc, &tempData); + + generate_new_codebooks(enc, &tempData); + + if (enc->framesSinceKeyframe >= 1) { + motion_search(enc, 8); + motion_search(enc, 4); + } + + retry_encode: + for (i=0; i<enc->width*enc->height/64; i++) + gather_data_for_cel(tempData.cel_evals + i, enc, &tempData); + + /* Quake 3 can't handle chunks bigger than 65536 bytes */ + if (tempData.mainChunkSize/8 > 65536) { + enc->lambda *= .8; + goto retry_encode; + } + + remap_codebooks(enc, &tempData); + + write_codebooks(enc, &tempData); + + reconstruct_and_encode_image(enc, &tempData, enc->width, enc->height, + enc->width*enc->height/64); + + /* Rotate frame history */ + FFSWAP(AVFrame *, enc->current_frame, enc->last_frame); + FFSWAP(motion_vect *, enc->last_motion4, enc->this_motion4); + FFSWAP(motion_vect *, enc->last_motion8, enc->this_motion8); + + av_free(tempData.cel_evals); + av_free(tempData.closest_cb2); + + enc->framesSinceKeyframe++; +} + +static int roq_encode_init(AVCodecContext *avctx) +{ + RoqContext *enc = avctx->priv_data; + + av_init_random(1, &enc->randctx); + + enc->framesSinceKeyframe = 0; + if ((avctx->width & 0xf) || (avctx->height & 0xf)) { + av_log(avctx, AV_LOG_ERROR, "Dimensions must be divisible by 16\n"); + return -1; + } + + if (((avctx->width)&(avctx->width-1))||((avctx->height)&(avctx->height-1))) + av_log(avctx, AV_LOG_ERROR, "Warning: dimensions not power of two\n"); + + if (avcodec_check_dimensions(avctx, avctx->width, avctx->height)) { + av_log(avctx, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n", + avctx->width, avctx->height); + return -1; + } + + enc->width = avctx->width; + enc->height = avctx->height; + + enc->framesSinceKeyframe = 0; + enc->first_frame = 1; + + enc->last_frame = &enc->frames[0]; + enc->current_frame = &enc->frames[1]; + + enc->this_motion4 = + av_mallocz((enc->width*enc->height/16)*sizeof(motion_vect)); + + enc->last_motion4 = + av_malloc ((enc->width*enc->height/16)*sizeof(motion_vect)); + + enc->this_motion8 = + av_mallocz((enc->width*enc->height/64)*sizeof(motion_vect)); + + enc->last_motion8 = + av_malloc ((enc->width*enc->height/64)*sizeof(motion_vect)); + + return 0; +} + +static void roq_write_video_info_chunk(RoqContext *enc) +{ + /* ROQ info chunk */ + bytestream_put_le16(&enc->out_buf, RoQ_INFO); + + /* Size: 8 bytes */ + bytestream_put_le32(&enc->out_buf, 8); + + /* Unused argument */ + bytestream_put_byte(&enc->out_buf, 0x00); + bytestream_put_byte(&enc->out_buf, 0x00); + + /* Width */ + bytestream_put_le16(&enc->out_buf, enc->width); + + /* Height */ + bytestream_put_le16(&enc->out_buf, enc->height); + + /* Unused in Quake 3, mimics the output of the real encoder */ + bytestream_put_byte(&enc->out_buf, 0x08); + bytestream_put_byte(&enc->out_buf, 0x00); + bytestream_put_byte(&enc->out_buf, 0x04); + bytestream_put_byte(&enc->out_buf, 0x00); +} + +static int roq_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data) +{ + RoqContext *enc = avctx->priv_data; + AVFrame *frame= data; + uint8_t *buf_start = buf; + + enc->out_buf = buf; + enc->avctx = avctx; + + enc->frame_to_enc = frame; + + if (frame->quality) + enc->lambda = frame->quality - 1; + else + enc->lambda = 2*ROQ_LAMBDA_SCALE; + + /* 138 bits max per 8x8 block + + * 256 codebooks*(6 bytes 2x2 + 4 bytes 4x4) + 8 bytes frame header */ + if (((enc->width*enc->height/64)*138+7)/8 + 256*(6+4) + 8 > buf_size) { + av_log(avctx, AV_LOG_ERROR, " RoQ: Output buffer too small!\n"); + return -1; + } + + /* Check for I frame */ + if (enc->framesSinceKeyframe == avctx->gop_size) + enc->framesSinceKeyframe = 0; + + if (enc->first_frame) { + /* Alloc memory for the reconstruction data (we must know the stride + for that) */ + if (avctx->get_buffer(avctx, enc->current_frame) || + avctx->get_buffer(avctx, enc->last_frame)) { + av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); + return -1; + } + + /* Before the first video frame, write a "video info" chunk */ + roq_write_video_info_chunk(enc); + + enc->first_frame = 0; + } + + /* Encode the actual frame */ + roq_encode_video(enc); + + return enc->out_buf - buf_start; +} + +static int roq_encode_end(AVCodecContext *avctx) +{ + RoqContext *enc = avctx->priv_data; + + avctx->release_buffer(avctx, enc->last_frame); + avctx->release_buffer(avctx, enc->current_frame); + + av_free(enc->this_motion4); + av_free(enc->last_motion4); + av_free(enc->this_motion8); + av_free(enc->last_motion8); + + return 0; +} + +AVCodec roq_encoder = +{ + "roqvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_ROQ, + sizeof(RoqContext), + roq_encode_init, + roq_encode_frame, + roq_encode_end, + .supported_framerates = (AVRational[]){{30,1}, {0,0}}, + .pix_fmts = (enum PixelFormat[]){PIX_FMT_YUV444P, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/rpza.c b/contrib/ffmpeg/libavcodec/rpza.c index 8ab5dbb92..ea36393aa 100644 --- a/contrib/ffmpeg/libavcodec/rpza.c +++ b/contrib/ffmpeg/libavcodec/rpza.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -40,7 +39,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -50,7 +48,7 @@ typedef struct RpzaContext { DSPContext dsp; AVFrame frame; - unsigned char *buf; + const unsigned char *buf; int size; } RpzaContext; @@ -232,11 +230,10 @@ static void rpza_decode_stream(RpzaContext *s) static int rpza_decode_init(AVCodecContext *avctx) { - RpzaContext *s = (RpzaContext *)avctx->priv_data; + RpzaContext *s = avctx->priv_data; s->avctx = avctx; avctx->pix_fmt = PIX_FMT_RGB555; - avctx->has_b_frames = 0; dsputil_init(&s->dsp, avctx); s->frame.data[0] = NULL; @@ -246,9 +243,9 @@ static int rpza_decode_init(AVCodecContext *avctx) static int rpza_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - RpzaContext *s = (RpzaContext *)avctx->priv_data; + RpzaContext *s = avctx->priv_data; s->buf = buf; s->size = buf_size; @@ -271,7 +268,7 @@ static int rpza_decode_frame(AVCodecContext *avctx, static int rpza_decode_end(AVCodecContext *avctx) { - RpzaContext *s = (RpzaContext *)avctx->priv_data; + RpzaContext *s = avctx->priv_data; if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); diff --git a/contrib/ffmpeg/libavcodec/rtjpeg.c b/contrib/ffmpeg/libavcodec/rtjpeg.c index dbc6cfd88..48fb35c95 100644 --- a/contrib/ffmpeg/libavcodec/rtjpeg.c +++ b/contrib/ffmpeg/libavcodec/rtjpeg.c @@ -43,8 +43,8 @@ * 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) { +static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *scan, + const uint32_t *quant) { int coeff, i, n; int8_t ac; uint8_t dc = get_bits(gb, 8); @@ -97,7 +97,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, uint8_t *scan, * \return number of bytes consumed from the input buffer */ int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, - uint8_t *buf, int buf_size) { + const uint8_t *buf, int buf_size) { DECLARE_ALIGNED_16(DCTELEM, block[64]); GetBitContext gb; int w = c->w / 16, h = c->h / 16; @@ -147,7 +147,7 @@ int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, */ void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp, int width, int height, - uint32_t *lquant, uint32_t *cquant) { + const uint32_t *lquant, const uint32_t *cquant) { int i; c->dsp = dsp; for (i = 0; i < 64; i++) { diff --git a/contrib/ffmpeg/libavcodec/rtjpeg.h b/contrib/ffmpeg/libavcodec/rtjpeg.h index daecc8a75..0c23eced5 100644 --- a/contrib/ffmpeg/libavcodec/rtjpeg.h +++ b/contrib/ffmpeg/libavcodec/rtjpeg.h @@ -19,8 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef RTJPEG_H -#define RTJPEG_H +#ifndef FFMPEG_RTJPEG_H +#define FFMPEG_RTJPEG_H + +#include <stdint.h> +#include <dsputil.h> typedef struct { int w, h; @@ -32,8 +35,8 @@ typedef struct { void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp, int width, int height, - uint32_t *lquant, uint32_t *cquant); + const uint32_t *lquant, const uint32_t *cquant); int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f, - uint8_t *buf, int buf_size); -#endif + const uint8_t *buf, int buf_size); +#endif /* FFMPEG_RTJPEG_H */ diff --git a/contrib/ffmpeg/libavcodec/rv10.c b/contrib/ffmpeg/libavcodec/rv10.c index e1e8287d5..7ee812a7e 100644 --- a/contrib/ffmpeg/libavcodec/rv10.c +++ b/contrib/ffmpeg/libavcodec/rv10.c @@ -195,12 +195,12 @@ int rv_decode_dc(MpegEncContext *s, int n) } else if (code == 0x7d) { code = -128 + get_bits(&s->gb, 7); } else if (code == 0x7e) { - if (get_bits(&s->gb, 1) == 0) + if (get_bits1(&s->gb) == 0) code = (int8_t)(get_bits(&s->gb, 8) + 1); else code = (int8_t)(get_bits(&s->gb, 8)); } else if (code == 0x7f) { - get_bits(&s->gb, 11); + skip_bits(&s->gb, 11); code = 1; } } else { @@ -216,7 +216,7 @@ int rv_decode_dc(MpegEncContext *s, int n) } else if (code == 0x1fd) { code = -128 + get_bits(&s->gb, 7); } else if (code == 0x1fe) { - get_bits(&s->gb, 9); + skip_bits(&s->gb, 9); code = 1; } else { av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n"); @@ -312,15 +312,15 @@ static int rv10_decode_picture_header(MpegEncContext *s) int mb_count, pb_frame, marker, unk, mb_xy; //printf("ff:%d\n", full_frame); - marker = get_bits(&s->gb, 1); + marker = get_bits1(&s->gb); - if (get_bits(&s->gb, 1)) + if (get_bits1(&s->gb)) s->pict_type = P_TYPE; else s->pict_type = I_TYPE; //printf("h:%X ver:%d\n",h,s->rv10_version); if(!marker) av_log(s->avctx, AV_LOG_ERROR, "marker missing\n"); - pb_frame = get_bits(&s->gb, 1); + pb_frame = get_bits1(&s->gb); #ifdef DEBUG av_log(s->avctx, AV_LOG_DEBUG, "pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame); @@ -416,7 +416,7 @@ static int rv20_decode_picture_header(MpegEncContext *s) return -1; } - if (get_bits(&s->gb, 1)){ + if (get_bits1(&s->gb)){ av_log(s->avctx, AV_LOG_ERROR, "unknown bit set\n"); return -1; } @@ -427,7 +427,7 @@ static int rv20_decode_picture_header(MpegEncContext *s) return -1; } if(s->avctx->sub_id == 0x30203002){ - if (get_bits(&s->gb, 1)){ + if (get_bits1(&s->gb)){ av_log(s->avctx, AV_LOG_ERROR, "unknown bit2 set\n"); return -1; } @@ -437,7 +437,7 @@ static int rv20_decode_picture_header(MpegEncContext *s) int f, new_w, new_h; int v= s->avctx->extradata_size >= 4 ? 7&((uint8_t*)s->avctx->extradata)[1] : 0; - if (get_bits(&s->gb, 1)){ + if (get_bits1(&s->gb)){ av_log(s->avctx, AV_LOG_ERROR, "unknown bit3 set\n"); // return -1; } @@ -539,43 +539,29 @@ static int rv10_decode_init(AVCodecContext *avctx) s->h263_long_vectors= ((uint8_t*)avctx->extradata)[3] & 1; avctx->sub_id= AV_RB32((uint8_t*)avctx->extradata + 4); - switch(avctx->sub_id){ - case 0x10000000: + if (avctx->sub_id == 0x10000000) { s->rv10_version= 0; s->low_delay=1; - break; - case 0x10002000: + } else if (avctx->sub_id == 0x10002000) { s->rv10_version= 3; s->low_delay=1; s->obmc=1; - break; - case 0x10003000: + } else if (avctx->sub_id == 0x10003000) { s->rv10_version= 3; s->low_delay=1; - break; - case 0x10003001: + } else if (avctx->sub_id == 0x10003001) { s->rv10_version= 3; s->low_delay=1; - break; - case 0x20001000: /* real rv20 decoder fail on this id */ - /*case 0x20100001: - case 0x20101001: - case 0x20103001:*/ - case 0x20100000 ... 0x2019ffff: + } else if ( avctx->sub_id == 0x20001000 + || (avctx->sub_id >= 0x20100000 && avctx->sub_id < 0x201a0000)) { s->low_delay=1; - break; - /*case 0x20200002: - case 0x20201002: - case 0x20203002:*/ - case 0x20200002 ... 0x202fffff: - case 0x30202002: - case 0x30203002: + } else if ( avctx->sub_id == 0x30202002 + || avctx->sub_id == 0x30203002 + || (avctx->sub_id >= 0x20200002 && avctx->sub_id < 0x20300000)) { s->low_delay=0; s->avctx->has_b_frames=1; - break; - default: + } else av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", avctx->sub_id); - } if(avctx->debug & FF_DEBUG_PICT_INFO){ av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", avctx->sub_id, avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1); @@ -611,7 +597,7 @@ static int rv10_decode_end(AVCodecContext *avctx) } static int rv10_decode_packet(AVCodecContext *avctx, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { MpegEncContext *s = avctx->priv_data; int mb_count, mb_pos, left, start_mb_x; @@ -725,13 +711,21 @@ static int rv10_decode_packet(AVCodecContext *avctx, return buf_size; } +static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n) +{ + if(avctx->slice_count) return avctx->slice_offset[n]; + else return AV_RL32(buf + n*8); +} + static int rv10_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { MpegEncContext *s = avctx->priv_data; int i; AVFrame *pict = data; + int slice_count; + const uint8_t *slices_hdr = NULL; #ifdef DEBUG av_log(avctx, AV_LOG_DEBUG, "*****frame %d size=%d\n", avctx->frame_number, buf_size); @@ -742,20 +736,23 @@ static int rv10_decode_frame(AVCodecContext *avctx, return 0; } - if(avctx->slice_count){ - for(i=0; i<avctx->slice_count; i++){ - int offset= avctx->slice_offset[i]; - int size; + if(!avctx->slice_count){ + slice_count = (*buf++) + 1; + slices_hdr = buf + 4; + buf += 8 * slice_count; + }else + slice_count = avctx->slice_count; - if(i+1 == avctx->slice_count) - size= buf_size - offset; - else - size= avctx->slice_offset[i+1] - offset; + for(i=0; i<slice_count; i++){ + int offset= get_slice_offset(avctx, slices_hdr, i); + int size; - rv10_decode_packet(avctx, buf+offset, size); - } - }else{ - rv10_decode_packet(avctx, buf, buf_size); + if(i+1 == slice_count) + size= buf_size - offset; + else + size= get_slice_offset(avctx, slices_hdr, i+1) - offset; + + rv10_decode_packet(avctx, buf+offset, size); } if(s->current_picture_ptr != NULL && s->mb_y>=s->mb_height){ diff --git a/contrib/ffmpeg/libavcodec/rv30.c b/contrib/ffmpeg/libavcodec/rv30.c new file mode 100644 index 000000000..ff7b32d1e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv30.c @@ -0,0 +1,147 @@ +/* + * RV30 decoder + * Copyright (c) 2007 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 + */ + +/** + * @file rv30.c + * RV30 decoder + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "golomb.h" + +#include "rv34.h" +#include "rv30data.h" + + +static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) +{ + int mb_bits; + int w = r->s.width, h = r->s.height; + int mb_size; + + memset(si, 0, sizeof(SliceInfo)); + skip_bits(gb, 3); + si->type = get_bits(gb, 2); + if(si->type == 1) si->type = 0; + if(get_bits1(gb)) + return -1; + si->quant = get_bits(gb, 5); + skip_bits1(gb); + skip_bits(gb, 13); // timestamp + skip_bits(gb, r->rpr); + si->width = w; + si->height = h; + mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); + mb_bits = ff_rv34_get_start_offset(gb, mb_size); + si->start = get_bits(gb, mb_bits); + skip_bits1(gb); + return 0; +} + +/** + * Decode 4x4 intra types array. + */ +static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst) +{ + int i, j, k; + + for(i = 0; i < 4; i++, dst += r->s.b4_stride - 4){ + for(j = 0; j < 4; j+= 2){ + int code = svq3_get_ue_golomb(gb) << 1; + if(code >= 81*2){ + av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n"); + return -1; + } + for(k = 0; k < 2; k++){ + int A = dst[-r->s.b4_stride] + 1; + int B = dst[-1] + 1; + *dst++ = rv30_itype_from_context[A * 90 + B * 9 + rv30_itype_code[code + k]]; + if(dst[-1] == 9){ + av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction mode\n"); + return -1; + } + } + } + } + return 0; +} + +/** + * Decode macroblock information. + */ +static int rv30_decode_mb_info(RV34DecContext *r) +{ + static const int rv30_p_types[6] = { RV34_MB_SKIP, RV34_MB_P_16x16, RV34_MB_P_8x8, -1, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 }; + static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_DIRECT, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 }; + MpegEncContext *s = &r->s; + GetBitContext *gb = &s->gb; + int code = svq3_get_ue_golomb(gb); + + if(code > 11){ + av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n"); + return -1; + } + if(code > 5){ + av_log(s->avctx, AV_LOG_ERROR, "dquant needed\n"); + code -= 6; + } + if(s->pict_type != B_TYPE) + return rv30_p_types[code]; + else + return rv30_b_types[code]; +} + +/** + * Initialize decoder. + */ +static int rv30_decode_init(AVCodecContext *avctx) +{ + RV34DecContext *r = avctx->priv_data; + + r->rv30 = 1; + ff_rv34_decode_init(avctx); + if(avctx->extradata_size < 2){ + av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); + return -1; + } + r->rpr = (avctx->extradata[1] & 7) >> 1; + r->rpr = FFMIN(r->rpr + 1, 3); + r->parse_slice_header = rv30_parse_slice_header; + r->decode_intra_types = rv30_decode_intra_types; + r->decode_mb_info = rv30_decode_mb_info; + r->luma_dc_quant_i = rv30_luma_dc_quant; + r->luma_dc_quant_p = rv30_luma_dc_quant; + return 0; +} + +AVCodec rv30_decoder = { + "rv30", + CODEC_TYPE_VIDEO, + CODEC_ID_RV30, + sizeof(RV34DecContext), + rv30_decode_init, + NULL, + ff_rv34_decode_end, + ff_rv34_decode_frame, + CODEC_CAP_DR1 | CODEC_CAP_DELAY, +}; diff --git a/contrib/ffmpeg/libavcodec/rv30data.h b/contrib/ffmpeg/libavcodec/rv30data.h new file mode 100644 index 000000000..98ccb352d --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv30data.h @@ -0,0 +1,174 @@ +/* + * RealVideo 3 decoder + * copyright (c) 2007 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 + */ + +/** + * @file rv30data.h + * miscellaneous RV30 tables + */ + +#ifndef FFMPEG_RV30DATA_H +#define FFMPEG_RV30DATA_H + +#include <stdint.h> + +/** DC quantizer mapping for RV30 */ +static const uint8_t rv30_luma_dc_quant[32] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 22, 22, 23, 23, 23, 24, 24, 25, 25 +}; + +/** + * This table is used for storing the differences + * between the predicted and the real intra type. + */ +static const uint8_t rv30_itype_code[9*9*2] = { + 0, 0, 0, 1, 1, 0, 1, 1, 0, 2, 2, 0, 0, 3, 3, 0, 1, 2, + 2, 1, 0, 4, 4, 0, 3, 1, 1, 3, 0, 5, 5, 0, 2, 2, 1, 4, + 4, 1, 0, 6, 3, 2, 1, 5, 2, 3, 5, 1, 6, 0, 0, 7, 4, 2, + 2, 4, 3, 3, 6, 1, 1, 6, 7, 0, 0, 8, 5, 2, 4, 3, 2, 5, + 3, 4, 1, 7, 4, 4, 7, 1, 8, 0, 6, 2, 3, 5, 5, 3, 2, 6, + 1, 8, 2, 7, 7, 2, 8, 1, 5, 4, 4, 5, 3, 6, 6, 3, 8, 2, + 4, 6, 5, 5, 6, 4, 2, 8, 7, 3, 3, 7, 6, 5, 5, 6, 7, 4, + 4, 7, 8, 3, 3, 8, 7, 5, 8, 4, 5, 7, 4, 8, 6, 6, 7, 6, + 5, 8, 8, 5, 6, 7, 8, 6, 7, 7, 6, 8, 8, 7, 7, 8, 8, 8, +}; + +/** + * This table is used for retrieving the current intra type + * based on its neighbors and adjustment provided by + * code read and decoded before. + * + * This is really a three-dimensional matrix with dimensions + * [-1..9][-1..9][0..9]. The first and second coordinates are + * detemined by the top and left neighbors (-1 if unavailable). + */ +static const uint8_t rv30_itype_from_context[900] = { + 0, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 2, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 2, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, + + 0, 1, 9, 9, 9, 9, 9, 9, 9, + 0, 2, 1, 6, 4, 8, 5, 7, 3, + 1, 0, 2, 6, 5, 4, 3, 8, 7, + 2, 8, 0, 1, 7, 4, 3, 6, 5, + 2, 0, 1, 3, 8, 5, 4, 7, 6, + 2, 0, 1, 4, 6, 7, 8, 3, 5, + 0, 1, 5, 2, 6, 3, 8, 4, 7, + 0, 1, 6, 2, 4, 7, 5, 8, 3, + 2, 7, 0, 1, 4, 8, 6, 3, 5, + 2, 8, 0, 1, 7, 3, 4, 5, 6, + + 1, 0, 9, 9, 9, 9, 9, 9, 9, + 1, 2, 5, 6, 3, 0, 4, 8, 7, + 1, 6, 2, 5, 3, 0, 4, 8, 7, + 2, 1, 7, 6, 8, 3, 5, 0, 4, + 1, 2, 5, 3, 6, 8, 4, 7, 0, + 1, 6, 2, 0, 4, 5, 8, 7, 3, + 1, 5, 2, 6, 3, 8, 4, 0, 7, + 1, 6, 0, 2, 4, 5, 7, 3, 8, + 2, 1, 7, 6, 0, 8, 5, 4, 3, + 1, 2, 7, 8, 3, 4, 5, 6, 0, + + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 2, 1, 8, 7, 6, 5, 4, 3, + 1, 2, 0, 6, 5, 7, 4, 8, 3, + 2, 8, 7, 1, 0, 6, 4, 3, 5, + 2, 0, 8, 1, 3, 7, 5, 4, 6, + 2, 0, 4, 1, 7, 8, 6, 3, 5, + 2, 0, 1, 5, 8, 4, 6, 7, 3, + 2, 0, 6, 1, 4, 7, 8, 5, 3, + 2, 7, 8, 1, 0, 5, 4, 6, 3, + 2, 8, 7, 1, 0, 4, 3, 6, 5, + + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 2, 1, 3, 5, 8, 6, 4, 7, + 1, 0, 2, 5, 3, 6, 4, 8, 7, + 2, 8, 1, 0, 3, 5, 7, 6, 4, + 3, 2, 5, 8, 1, 4, 6, 7, 0, + 4, 2, 0, 6, 1, 5, 8, 3, 7, + 5, 3, 1, 2, 8, 6, 4, 0, 7, + 1, 6, 0, 2, 4, 5, 8, 3, 7, + 2, 7, 0, 1, 5, 4, 8, 6, 3, + 2, 8, 3, 5, 1, 0, 7, 6, 4, + + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 2, 0, 6, 1, 4, 7, 5, 8, 3, + 1, 6, 2, 0, 4, 5, 3, 7, 8, + 2, 8, 7, 6, 4, 0, 1, 5, 3, + 4, 2, 1, 0, 6, 8, 3, 5, 7, + 4, 2, 6, 0, 1, 5, 7, 8, 3, + 1, 2, 5, 0, 6, 3, 4, 7, 8, + 6, 4, 0, 1, 2, 7, 5, 3, 8, + 2, 7, 4, 6, 0, 1, 8, 5, 3, + 2, 8, 7, 4, 6, 1, 3, 5, 0, + + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 5, 1, 2, 3, 6, 8, 0, 4, 7, + 1, 5, 6, 3, 2, 0, 4, 8, 7, + 2, 1, 5, 3, 6, 8, 7, 4, 0, + 5, 3, 1, 2, 6, 8, 4, 7, 0, + 1, 6, 2, 4, 5, 8, 0, 3, 7, + 5, 1, 3, 6, 2, 0, 8, 4, 7, + 1, 6, 5, 2, 0, 4, 3, 7, 8, + 2, 7, 1, 6, 5, 0, 8, 3, 4, + 2, 5, 1, 3, 6, 8, 4, 0, 7, + + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 1, 6, 2, 0, 5, 4, 3, 7, 8, + 1, 6, 5, 4, 2, 3, 0, 7, 8, + 2, 1, 6, 7, 4, 8, 5, 3, 0, + 2, 1, 6, 5, 8, 4, 3, 0, 7, + 6, 4, 1, 2, 0, 5, 7, 8, 3, + 1, 6, 5, 2, 3, 0, 4, 8, 7, + 6, 1, 4, 0, 2, 7, 5, 3, 8, + 2, 7, 4, 6, 1, 5, 0, 8, 3, + 2, 1, 6, 8, 4, 7, 3, 5, 0, + + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 2, 0, 4, 7, 6, 1, 8, 5, 3, + 6, 1, 2, 0, 4, 7, 5, 8, 3, + 2, 7, 8, 0, 1, 6, 4, 3, 5, + 2, 4, 0, 8, 3, 1, 7, 6, 5, + 4, 2, 7, 0, 6, 1, 8, 5, 3, + 2, 1, 0, 8, 5, 6, 7, 4, 3, + 2, 6, 4, 1, 7, 0, 5, 8, 3, + 2, 7, 4, 0, 8, 6, 1, 5, 3, + 2, 8, 7, 4, 1, 0, 3, 6, 5, + + 9, 9, 9, 9, 9, 9, 9, 9, 9, + 2, 0, 8, 1, 3, 4, 6, 5, 7, + 1, 2, 0, 6, 8, 5, 7, 3, 4, + 2, 8, 7, 1, 0, 3, 6, 5, 4, + 8, 3, 2, 5, 1, 0, 4, 7, 6, + 2, 0, 4, 8, 5, 1, 7, 6, 3, + 2, 1, 0, 8, 5, 3, 6, 4, 7, + 2, 1, 6, 0, 8, 4, 5, 7, 3, + 2, 7, 8, 4, 0, 6, 1, 5, 3, + 2, 8, 3, 0, 7, 4, 1, 6, 5, +}; +#endif /* FFMPEG_RV30DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/rv30dsp.c b/contrib/ffmpeg/libavcodec/rv30dsp.c new file mode 100644 index 000000000..13b218b88 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv30dsp.c @@ -0,0 +1,249 @@ +/* + * RV30 decoder motion compensation functions + * Copyright (c) 2007 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 + */ + +/** + * @file rv30dsp.c + * RV30 decoder motion compensation functions + */ + +#include "avcodec.h" +#include "dsputil.h" + +#define RV30_LOWPASS(OPNAME, OP) \ +static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ + const int h=8;\ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + int i;\ + for(i=0; i<h; i++)\ + {\ + OP(dst[0], -(src[-1]+src[2]) + src[0]*C1 + src[1]*C2);\ + OP(dst[1], -(src[ 0]+src[3]) + src[1]*C1 + src[2]*C2);\ + OP(dst[2], -(src[ 1]+src[4]) + src[2]*C1 + src[3]*C2);\ + OP(dst[3], -(src[ 2]+src[5]) + src[3]*C1 + src[4]*C2);\ + OP(dst[4], -(src[ 3]+src[6]) + src[4]*C1 + src[5]*C2);\ + OP(dst[5], -(src[ 4]+src[7]) + src[5]*C1 + src[6]*C2);\ + OP(dst[6], -(src[ 5]+src[8]) + src[6]*C1 + src[7]*C2);\ + OP(dst[7], -(src[ 6]+src[9]) + src[7]*C1 + src[8]*C2);\ + dst+=dstStride;\ + src+=srcStride;\ + }\ +}\ +\ +static void OPNAME ## rv30_tpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ + const int w=8;\ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + int i;\ + for(i=0; i<w; i++)\ + {\ + const int srcA= src[-1*srcStride];\ + const int src0= src[0 *srcStride];\ + const int src1= src[1 *srcStride];\ + const int src2= src[2 *srcStride];\ + const int src3= src[3 *srcStride];\ + const int src4= src[4 *srcStride];\ + const int src5= src[5 *srcStride];\ + const int src6= src[6 *srcStride];\ + const int src7= src[7 *srcStride];\ + const int src8= src[8 *srcStride];\ + const int src9= src[9 *srcStride];\ + OP(dst[0*dstStride], -(srcA+src2) + src0*C1 + src1*C2);\ + OP(dst[1*dstStride], -(src0+src3) + src1*C1 + src2*C2);\ + OP(dst[2*dstStride], -(src1+src4) + src2*C1 + src3*C2);\ + OP(dst[3*dstStride], -(src2+src5) + src3*C1 + src4*C2);\ + OP(dst[4*dstStride], -(src3+src6) + src4*C1 + src5*C2);\ + OP(dst[5*dstStride], -(src4+src7) + src5*C1 + src6*C2);\ + OP(dst[6*dstStride], -(src5+src8) + src6*C1 + src7*C2);\ + OP(dst[7*dstStride], -(src6+src9) + src7*C1 + src8*C2);\ + dst++;\ + src++;\ + }\ +}\ +\ +static void OPNAME ## rv30_tpel8_h3_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + const int h=8+2;\ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + int i;\ + for(i=0; i<h; i++)\ + {\ + OP(dst[0], 6*src[0]+9*src[1]+src[2]);\ + OP(dst[1], 6*src[1]+9*src[2]+src[3]);\ + OP(dst[2], 6*src[2]+9*src[3]+src[4]);\ + OP(dst[3], 6*src[3]+9*src[4]+src[5]);\ + OP(dst[4], 6*src[4]+9*src[5]+src[6]);\ + OP(dst[5], 6*src[5]+9*src[6]+src[7]);\ + OP(dst[6], 6*src[6]+9*src[7]+src[8]);\ + OP(dst[7], 6*src[7]+9*src[8]+src[9]);\ + dst+=dstStride;\ + src+=srcStride;\ + }\ +}\ +\ +static void OPNAME ## rv30_tpel8_v3_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + const int w=8;\ + uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\ + int i;\ + for(i=0; i<w; i++)\ + {\ + const int src0= src[0 *srcStride];\ + const int src1= src[1 *srcStride];\ + const int src2= src[2 *srcStride];\ + const int src3= src[3 *srcStride];\ + const int src4= src[4 *srcStride];\ + const int src5= src[5 *srcStride];\ + const int src6= src[6 *srcStride];\ + const int src7= src[7 *srcStride];\ + const int src8= src[8 *srcStride];\ + const int src9= src[9 *srcStride];\ + OP(dst[0*dstStride], 6*src0 + 9*src1 + src2);\ + OP(dst[1*dstStride], 6*src1 + 9*src2 + src3);\ + OP(dst[2*dstStride], 6*src2 + 9*src3 + src4);\ + OP(dst[3*dstStride], 6*src3 + 9*src4 + src5);\ + OP(dst[4*dstStride], 6*src4 + 9*src5 + src6);\ + OP(dst[5*dstStride], 6*src5 + 9*src6 + src7);\ + OP(dst[6*dstStride], 6*src6 + 9*src7 + src8);\ + OP(dst[7*dstStride], 6*src7 + 9*src8 + src9);\ + dst ++;\ + src ++;\ + }\ +}\ +\ +static void OPNAME ## rv30_tpel8_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + uint8_t half[8*10];\ + put_rv30_tpel8_h3_lowpass(half, src, 8, srcStride);\ + OPNAME ## rv30_tpel8_v3_lowpass(dst, half, dstStride, 8);\ +}\ +\ +static void OPNAME ## rv30_tpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ + OPNAME ## rv30_tpel8_v_lowpass(dst , src , dstStride, srcStride, C1, C2);\ + OPNAME ## rv30_tpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + OPNAME ## rv30_tpel8_v_lowpass(dst , src , dstStride, srcStride, C1, C2);\ + OPNAME ## rv30_tpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ +}\ +\ +static void OPNAME ## rv30_tpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\ + OPNAME ## rv30_tpel8_h_lowpass(dst , src , dstStride, srcStride, C1, C2);\ + OPNAME ## rv30_tpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + OPNAME ## rv30_tpel8_h_lowpass(dst , src , dstStride, srcStride, C1, C2);\ + OPNAME ## rv30_tpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, C1, C2);\ +}\ +\ +static void OPNAME ## rv30_tpel16_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + OPNAME ## rv30_tpel8_hv_lowpass(dst , src , dstStride, srcStride);\ + OPNAME ## rv30_tpel8_hv_lowpass(dst+8, src+8, dstStride, srcStride);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + OPNAME ## rv30_tpel8_hv_lowpass(dst , src , dstStride, srcStride);\ + OPNAME ## rv30_tpel8_hv_lowpass(dst+8, src+8, dstStride, srcStride);\ +}\ +\ + +#define RV30_MC(OPNAME, SIZE) \ +static void OPNAME ## rv30_tpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 12, 6);\ +}\ +\ +static void OPNAME ## rv30_tpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 6, 12);\ +}\ +\ +static void OPNAME ## rv30_tpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 12, 6);\ +}\ +\ +static void OPNAME ## rv30_tpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 6, 12);\ +}\ +\ +static void OPNAME ## rv30_tpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, int stride){\ + uint8_t half[SIZE*SIZE];\ + put_rv30_tpel ## SIZE ## _h_lowpass(half, src, SIZE, stride, 12, 6);\ + OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 12, 6);\ +}\ +\ +static void OPNAME ## rv30_tpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, int stride){\ + uint8_t half[SIZE*SIZE];\ + put_rv30_tpel ## SIZE ## _h_lowpass(half, src, SIZE, stride, 12, 6);\ + OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 6, 12);\ +}\ +\ +static void OPNAME ## rv30_tpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, int stride){\ + uint8_t half[SIZE*SIZE];\ + put_rv30_tpel ## SIZE ## _h_lowpass(half, src, SIZE, stride, 6, 12);\ + OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 12, 6);\ +}\ +\ +static void OPNAME ## rv30_tpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## rv30_tpel ## SIZE ## _hv_lowpass(dst, src, stride, stride);\ +}\ +\ + +#define op_avg(a, b) a = (((a)+cm[((b) + 8)>>4]+1)>>1) +#define op_put(a, b) a = cm[((b) + 8)>>4] + +RV30_LOWPASS(put_ , op_put) +RV30_LOWPASS(avg_ , op_avg) +RV30_MC(put_, 8) +RV30_MC(put_, 16) +RV30_MC(avg_, 8) +RV30_MC(avg_, 16) + +void ff_rv30dsp_init(DSPContext* c, AVCodecContext *avctx) { + c->put_rv30_tpel_pixels_tab[0][ 0] = c->put_h264_qpel_pixels_tab[0][0]; + c->put_rv30_tpel_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c; + c->put_rv30_tpel_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c; + c->put_rv30_tpel_pixels_tab[0][ 4] = put_rv30_tpel16_mc01_c; + c->put_rv30_tpel_pixels_tab[0][ 5] = put_rv30_tpel16_mc11_c; + c->put_rv30_tpel_pixels_tab[0][ 6] = put_rv30_tpel16_mc21_c; + c->put_rv30_tpel_pixels_tab[0][ 8] = put_rv30_tpel16_mc02_c; + c->put_rv30_tpel_pixels_tab[0][ 9] = put_rv30_tpel16_mc12_c; + c->put_rv30_tpel_pixels_tab[0][10] = put_rv30_tpel16_mc22_c; + c->avg_rv30_tpel_pixels_tab[0][ 0] = c->avg_h264_qpel_pixels_tab[0][0]; + c->avg_rv30_tpel_pixels_tab[0][ 1] = avg_rv30_tpel16_mc10_c; + c->avg_rv30_tpel_pixels_tab[0][ 2] = avg_rv30_tpel16_mc20_c; + c->avg_rv30_tpel_pixels_tab[0][ 4] = avg_rv30_tpel16_mc01_c; + c->avg_rv30_tpel_pixels_tab[0][ 5] = avg_rv30_tpel16_mc11_c; + c->avg_rv30_tpel_pixels_tab[0][ 6] = avg_rv30_tpel16_mc21_c; + c->avg_rv30_tpel_pixels_tab[0][ 8] = avg_rv30_tpel16_mc02_c; + c->avg_rv30_tpel_pixels_tab[0][ 9] = avg_rv30_tpel16_mc12_c; + c->avg_rv30_tpel_pixels_tab[0][10] = avg_rv30_tpel16_mc22_c; + c->put_rv30_tpel_pixels_tab[1][ 0] = c->put_h264_qpel_pixels_tab[1][0]; + c->put_rv30_tpel_pixels_tab[1][ 1] = put_rv30_tpel8_mc10_c; + c->put_rv30_tpel_pixels_tab[1][ 2] = put_rv30_tpel8_mc20_c; + c->put_rv30_tpel_pixels_tab[1][ 4] = put_rv30_tpel8_mc01_c; + c->put_rv30_tpel_pixels_tab[1][ 5] = put_rv30_tpel8_mc11_c; + c->put_rv30_tpel_pixels_tab[1][ 6] = put_rv30_tpel8_mc21_c; + c->put_rv30_tpel_pixels_tab[1][ 8] = put_rv30_tpel8_mc02_c; + c->put_rv30_tpel_pixels_tab[1][ 9] = put_rv30_tpel8_mc12_c; + c->put_rv30_tpel_pixels_tab[1][10] = put_rv30_tpel8_mc22_c; + c->avg_rv30_tpel_pixels_tab[1][ 0] = c->avg_h264_qpel_pixels_tab[1][0]; + c->avg_rv30_tpel_pixels_tab[1][ 1] = avg_rv30_tpel8_mc10_c; + c->avg_rv30_tpel_pixels_tab[1][ 2] = avg_rv30_tpel8_mc20_c; + c->avg_rv30_tpel_pixels_tab[1][ 4] = avg_rv30_tpel8_mc01_c; + c->avg_rv30_tpel_pixels_tab[1][ 5] = avg_rv30_tpel8_mc11_c; + c->avg_rv30_tpel_pixels_tab[1][ 6] = avg_rv30_tpel8_mc21_c; + c->avg_rv30_tpel_pixels_tab[1][ 8] = avg_rv30_tpel8_mc02_c; + c->avg_rv30_tpel_pixels_tab[1][ 9] = avg_rv30_tpel8_mc12_c; + c->avg_rv30_tpel_pixels_tab[1][10] = avg_rv30_tpel8_mc22_c; +} diff --git a/contrib/ffmpeg/libavcodec/rv34.c b/contrib/ffmpeg/libavcodec/rv34.c new file mode 100644 index 000000000..5b5849896 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv34.c @@ -0,0 +1,1299 @@ +/* + * RV30/40 decoder common data + * Copyright (c) 2007 Mike Melanson, 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 + */ + +/** + * @file rv34.c + * RV30/40 decoder common data + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "golomb.h" +#include "rectangle.h" + +#include "rv34vlc.h" +#include "rv34data.h" +#include "rv34.h" + +//#define DEBUG + +/** translation of RV30/40 macroblock types to lavc ones */ +static const int rv34_mb_type_to_lavc[12] = { + MB_TYPE_INTRA, + MB_TYPE_INTRA16x16, + MB_TYPE_16x16 | MB_TYPE_L0, + MB_TYPE_8x8 | MB_TYPE_L0, + MB_TYPE_16x16 | MB_TYPE_L0, + MB_TYPE_16x16 | MB_TYPE_L1, + MB_TYPE_SKIP, + MB_TYPE_DIRECT2 | MB_TYPE_16x16, + MB_TYPE_16x8 | MB_TYPE_L0, + MB_TYPE_8x16 | MB_TYPE_L0, + MB_TYPE_16x16 | MB_TYPE_L0L1, + MB_TYPE_16x16 | MB_TYPE_L0 +}; + + +static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES]; + +/** + * @defgroup vlc RV30/40 VLC generating functions + * @{ + */ + +/** + * Generate VLC from codeword lengths. + * @param bits codeword lengths (zeroes are accepted) + * @param size length of input data + * @param insyms symbols for input codes (NULL for default ones) + */ +static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t *insyms) +{ + int i; + int counts[17] = {0}, codes[17]; + uint16_t cw[size], syms[size]; + uint8_t bits2[size]; + int maxbits = 0, realsize = 0; + + for(i = 0; i < size; i++){ + if(bits[i]){ + bits2[realsize] = bits[i]; + syms[realsize] = insyms ? insyms[i] : i; + realsize++; + maxbits = FFMAX(maxbits, bits[i]); + counts[bits[i]]++; + } + } + + codes[0] = 0; + for(i = 0; i < 16; i++) + codes[i+1] = (codes[i] + counts[i]) << 1; + for(i = 0; i < realsize; i++) + cw[i] = codes[bits2[i]]++; + + init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize, + bits2, 1, 1, + cw, 2, 2, + syms, 2, 2, INIT_VLC_USE_STATIC); +} + +/** + * Initialize all tables. + */ +static void rv34_init_tables() +{ + int i, j, k; + + for(i = 0; i < NUM_INTRA_TABLES; i++){ + for(j = 0; j < 2; j++){ + rv34_gen_vlc(rv34_table_intra_cbppat [i][j], CBPPAT_VLC_SIZE, &intra_vlcs[i].cbppattern[j], NULL); + rv34_gen_vlc(rv34_table_intra_secondpat[i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].second_pattern[j], NULL); + rv34_gen_vlc(rv34_table_intra_thirdpat [i][j], OTHERBLK_VLC_SIZE, &intra_vlcs[i].third_pattern[j], NULL); + for(k = 0; k < 4; k++) + rv34_gen_vlc(rv34_table_intra_cbp[i][j+k*2], CBP_VLC_SIZE, &intra_vlcs[i].cbp[j][k], rv34_cbp_code); + } + for(j = 0; j < 4; j++) + rv34_gen_vlc(rv34_table_intra_firstpat[i][j], FIRSTBLK_VLC_SIZE, &intra_vlcs[i].first_pattern[j], NULL); + rv34_gen_vlc(rv34_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL); + } + + for(i = 0; i < NUM_INTER_TABLES; i++){ + rv34_gen_vlc(rv34_inter_cbppat[i], CBPPAT_VLC_SIZE, &inter_vlcs[i].cbppattern[0], NULL); + for(j = 0; j < 4; j++) + rv34_gen_vlc(rv34_inter_cbp[i][j], CBP_VLC_SIZE, &inter_vlcs[i].cbp[0][j], rv34_cbp_code); + for(j = 0; j < 2; j++){ + rv34_gen_vlc(rv34_table_inter_firstpat [i][j], FIRSTBLK_VLC_SIZE, &inter_vlcs[i].first_pattern[j], NULL); + rv34_gen_vlc(rv34_table_inter_secondpat[i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].second_pattern[j], NULL); + rv34_gen_vlc(rv34_table_inter_thirdpat [i][j], OTHERBLK_VLC_SIZE, &inter_vlcs[i].third_pattern[j], NULL); + } + rv34_gen_vlc(rv34_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL); + } +} + +/** @} */ // vlc group + + +/** + * @defgroup transform RV30/40 inverse transform functions + * @{ + */ + +static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block) +{ + int i; + + for(i=0; i<4; i++){ + const int z0= 13*(block[i+8*0] + block[i+8*2]); + const int z1= 13*(block[i+8*0] - block[i+8*2]); + const int z2= 7* block[i+8*1] - 17*block[i+8*3]; + const int z3= 17* block[i+8*1] + 7*block[i+8*3]; + + temp[4*i+0]= z0+z3; + temp[4*i+1]= z1+z2; + temp[4*i+2]= z1-z2; + temp[4*i+3]= z0-z3; + } +} + +/** + * Real Video 3.0/4.0 inverse transform + * Code is almost the same as in SVQ3, only scaling is different. + */ +static void rv34_inv_transform(DCTELEM *block){ + int temp[16]; + int i; + + rv34_row_transform(temp, block); + + for(i=0; i<4; i++){ + const int z0= 13*(temp[4*0+i] + temp[4*2+i]) + 0x200; + const int z1= 13*(temp[4*0+i] - temp[4*2+i]) + 0x200; + const int z2= 7* temp[4*1+i] - 17*temp[4*3+i]; + const int z3= 17* temp[4*1+i] + 7*temp[4*3+i]; + + block[i*8+0]= (z0 + z3)>>10; + block[i*8+1]= (z1 + z2)>>10; + block[i*8+2]= (z1 - z2)>>10; + block[i*8+3]= (z0 - z3)>>10; + } + +} + +/** + * RealVideo 3.0/4.0 inverse transform for DC block + * + * Code is almost the same as rv34_inv_transform() + * but final coefficients are multiplied by 1.5 and have no rounding. + */ +static void rv34_inv_transform_noround(DCTELEM *block){ + int temp[16]; + int i; + + rv34_row_transform(temp, block); + + for(i=0; i<4; i++){ + const int z0= 13*(temp[4*0+i] + temp[4*2+i]); + const int z1= 13*(temp[4*0+i] - temp[4*2+i]); + const int z2= 7* temp[4*1+i] - 17*temp[4*3+i]; + const int z3= 17* temp[4*1+i] + 7*temp[4*3+i]; + + block[i*8+0]= ((z0 + z3)*3)>>11; + block[i*8+1]= ((z1 + z2)*3)>>11; + block[i*8+2]= ((z1 - z2)*3)>>11; + block[i*8+3]= ((z0 - z3)*3)>>11; + } + +} + +/** @} */ // transform + + +/** + * @defgroup block RV30/40 4x4 block decoding functions + * @{ + */ + +/** + * Decode coded block pattern. + */ +static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table) +{ + int pattern, code, cbp=0; + int ones; + static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000}; + static const int shifts[4] = { 0, 2, 8, 10 }; + int *curshift = shifts; + int i, t, mask; + + code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2); + pattern = code & 0xF; + code >>= 4; + + ones = rv34_count_ones[pattern]; + + for(mask = 8; mask; mask >>= 1, curshift++){ + if(pattern & mask) + cbp |= get_vlc2(gb, vlc->cbp[table][ones].table, vlc->cbp[table][ones].bits, 1) << curshift[0]; + } + + for(i = 0; i < 4; i++){ + t = modulo_three_table[code][i]; + if(t == 1) + cbp |= cbp_masks[get_bits1(gb)] << i; + if(t == 2) + cbp |= cbp_masks[2] << i; + } + return cbp; +} + +/** + * Get one coefficient value from the bistream and store it. + */ +static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc) +{ + if(coef){ + if(coef == esc){ + coef = get_vlc2(gb, vlc->table, 9, 2); + if(coef > 23){ + coef -= 23; + coef = 22 + ((1 << coef) | get_bits(gb, coef)); + } + coef += esc; + } + if(get_bits1(gb)) + coef = -coef; + *dst = coef; + } +} + +/** + * Decode 2x2 subblock of coefficients. + */ +static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc) +{ + int coeffs[4]; + + coeffs[0] = modulo_three_table[code][0]; + coeffs[1] = modulo_three_table[code][1]; + coeffs[2] = modulo_three_table[code][2]; + coeffs[3] = modulo_three_table[code][3]; + decode_coeff(dst , coeffs[0], 3, gb, vlc); + if(is_block2){ + decode_coeff(dst+8, coeffs[1], 2, gb, vlc); + decode_coeff(dst+1, coeffs[2], 2, gb, vlc); + }else{ + decode_coeff(dst+1, coeffs[1], 2, gb, vlc); + decode_coeff(dst+8, coeffs[2], 2, gb, vlc); + } + decode_coeff(dst+9, coeffs[3], 2, gb, vlc); +} + +/** + * Decode coefficients for 4x4 block. + * + * This is done by filling 2x2 subblocks with decoded coefficients + * in this order (the same for subblocks and subblock coefficients): + * o--o + * / + * / + * o--o + */ + +static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc) +{ + int code, pattern; + + code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2); + + pattern = code & 0x7; + + code >>= 3; + decode_subblock(dst, code, 0, gb, &rvlc->coefficient); + + if(pattern & 4){ + code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2); + decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient); + } + if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block + code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2); + decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient); + } + if(pattern & 1){ + code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2); + decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient); + } + +} + +/** + * Dequantize ordinary 4x4 block. + * @todo optimize + */ +static inline void rv34_dequant4x4(DCTELEM *block, int Qdc, int Q) +{ + int i, j; + + block[0] = (block[0] * Qdc + 8) >> 4; + for(i = 0; i < 4; i++) + for(j = !i; j < 4; j++) + block[j + i*8] = (block[j + i*8] * Q + 8) >> 4; +} + +/** + * Dequantize 4x4 block of DC values for 16x16 macroblock. + * @todo optimize + */ +static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q) +{ + int i; + + for(i = 0; i < 3; i++) + block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4; + for(; i < 16; i++) + block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4; +} +/** @} */ //block functions + + +/** + * @defgroup bitstream RV30/40 bitstream parsing + * @{ + */ + +/** + * Decode starting slice position. + * @todo Maybe replace with ff_h263_decode_mba() ? + */ +int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size) +{ + int i; + for(i = 0; i < 5; i++) + if(rv34_mb_max_sizes[i] > mb_size) + break; + return rv34_mb_bits_sizes[i]; +} + +/** + * Select VLC set for decoding from current quantizer, modifier and frame type. + */ +static inline RV34VLC* choose_vlc_set(int quant, int mod, int type) +{ + if(mod == 2 && quant < 19) quant += 10; + else if(mod && quant < 26) quant += 5; + return type ? &inter_vlcs[rv34_quant_to_vlc_set[1][av_clip(quant, 0, 30)]] + : &intra_vlcs[rv34_quant_to_vlc_set[0][av_clip(quant, 0, 30)]]; +} + +/** + * Decode quantizer difference and return modified quantizer. + */ +static inline int rv34_decode_dquant(GetBitContext *gb, int quant) +{ + if(get_bits1(gb)) + return rv34_dquant_tab[get_bits1(gb)][quant]; + else + return get_bits(gb, 5); +} + +/** @} */ //bitstream functions + +/** + * @defgroup mv motion vector related code (prediction, reconstruction, motion compensation) + * @{ + */ + +/** macroblock partition width in 8x8 blocks */ +static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2 }; + +/** macroblock partition height in 8x8 blocks */ +static const uint8_t part_sizes_h[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 }; + +/** availability index for subblocks */ +static const uint8_t avail_indexes[4] = { 5, 6, 9, 10 }; + +/** + * motion vector prediction + * + * Motion prediction performed for the block by using median prediction of + * motion vectors from the left, top and right top blocks but in corner cases + * some other vectors may be used instead. + */ +static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int dmv_no) +{ + MpegEncContext *s = &r->s; + int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; + int A[2] = {0}, B[2], C[2]; + int i, j; + int mx, my; + int avail_index = avail_indexes[subblock_no]; + int c_off = part_sizes_w[block_type]; + + mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride; + if(subblock_no == 3) + c_off = -1; + + if(r->avail_cache[avail_index - 1]){ + A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0]; + A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1]; + } + if(r->avail_cache[avail_index - 4]){ + B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0]; + B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1]; + }else{ + B[0] = A[0]; + B[1] = A[1]; + } + if(!r->avail_cache[avail_index - 4 + c_off]){ + if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1] || r->rv30)){ + C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0]; + C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1]; + }else{ + C[0] = A[0]; + C[1] = A[1]; + } + }else{ + C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0]; + C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1]; + } + mx = mid_pred(A[0], B[0], C[0]); + my = mid_pred(A[1], B[1], C[1]); + mx += r->dmv[dmv_no][0]; + my += r->dmv[dmv_no][1]; + for(j = 0; j < part_sizes_h[block_type]; j++){ + for(i = 0; i < part_sizes_w[block_type]; i++){ + s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx; + s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my; + } + } +} + +/** + * Calculate motion vector component that should be added for direct blocks. + */ +static int calc_add_mv(MpegEncContext *s, int dir, int component) +{ + int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; + int sum; + + sum = (s->next_picture_ptr->motion_val[0][mv_pos][component] + + s->next_picture_ptr->motion_val[0][mv_pos + 1][component] + + s->next_picture_ptr->motion_val[0][mv_pos + s->b8_stride][component] + + s->next_picture_ptr->motion_val[0][mv_pos + s->b8_stride + 1][component]) >> 2; + return dir ? -(sum >> 1) : ((sum + 1) >> 1); +} + +/** + * Predict motion vector for B-frame macroblock. + */ +static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2], + int A_avail, int B_avail, int C_avail, + int *mx, int *my) +{ + if(A_avail + B_avail + C_avail != 3){ + *mx = A[0] + B[0] + C[0]; + *my = A[1] + B[1] + C[1]; + if(A_avail + B_avail + C_avail == 2){ + *mx /= 2; + *my /= 2; + } + }else{ + *mx = mid_pred(A[0], B[0], C[0]); + *my = mid_pred(A[1], B[1], C[1]); + } +} + +/** + * motion vector prediction for B-frames + */ +static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir) +{ + MpegEncContext *s = &r->s; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; + int A[2], B[2], C[2]; + int has_A = 0, has_B = 0, has_C = 0; + int mx, my; + int i, j; + Picture *cur_pic = s->current_picture_ptr; + const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0; + int type = cur_pic->mb_type[mb_pos]; + + memset(A, 0, sizeof(A)); + memset(B, 0, sizeof(B)); + memset(C, 0, sizeof(C)); + if((r->avail_cache[5-1] & type) & mask){ + A[0] = cur_pic->motion_val[dir][mv_pos - 1][0]; + A[1] = cur_pic->motion_val[dir][mv_pos - 1][1]; + has_A = 1; + } + if((r->avail_cache[5-4] & type) & mask){ + B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0]; + B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1]; + has_B = 1; + } + if((r->avail_cache[5-2] & type) & mask){ + C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0]; + C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1]; + has_C = 1; + }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[5-5] & type) & mask){ + C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0]; + C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1]; + has_C = 1; + } + + rv34_pred_b_vector(A, B, C, has_A, has_B, has_C, &mx, &my); + + mx += r->dmv[dir][0]; + my += r->dmv[dir][1]; + + if(block_type == RV34_MB_B_DIRECT){ + mx += calc_add_mv(s, dir, 0); + my += calc_add_mv(s, dir, 1); + } + for(j = 0; j < 2; j++){ + for(i = 0; i < 2; i++){ + cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx; + cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my; + } + } + if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD) + fill_rectangle(cur_pic->motion_val[!dir][mv_pos], 2, 2, s->b8_stride, 0, 4); +} + +static const int chroma_coeffs[3] = { 8, 5, 3 }; + +/** + * generic motion compensation function + * + * @param r decoder context + * @param block_type type of the current block + * @param xoff horizontal offset from the start of the current block + * @param yoff vertical offset from the start of the current block + * @param mv_off offset to the motion vector information + * @param width width of the current partition in 8x8 blocks + * @param height height of the current partition in 8x8 blocks + */ +static inline void rv34_mc(RV34DecContext *r, const int block_type, + const int xoff, const int yoff, int mv_off, + const int width, const int height, int dir, + const int thirdpel, + qpel_mc_func (*qpel_mc)[16], + h264_chroma_mc_func (*chroma_mc)) +{ + MpegEncContext *s = &r->s; + uint8_t *Y, *U, *V, *srcY, *srcU, *srcV; + int dxy, mx, my, lx, ly, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; + int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + mv_off; + int is16x16 = 1; + + if(thirdpel){ + mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24); + my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24); + lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3; + ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3; + uvmx = chroma_coeffs[(3*(mx&1) + lx) >> 1]; + uvmy = chroma_coeffs[(3*(my&1) + ly) >> 1]; + }else{ + mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2; + my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2; + lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3; + ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3; + uvmx = mx & 6; + uvmy = my & 6; + } + dxy = ly*4 + lx; + srcY = dir ? s->next_picture_ptr->data[0] : s->last_picture_ptr->data[0]; + srcU = dir ? s->next_picture_ptr->data[1] : s->last_picture_ptr->data[1]; + srcV = dir ? s->next_picture_ptr->data[2] : s->last_picture_ptr->data[2]; + src_x = s->mb_x * 16 + xoff + mx; + src_y = s->mb_y * 16 + yoff + my; + uvsrc_x = s->mb_x * 8 + (xoff >> 1) + (mx >> 1); + uvsrc_y = s->mb_y * 8 + (yoff >> 1) + (my >> 1); + srcY += src_y * s->linesize + src_x; + srcU += uvsrc_y * s->uvlinesize + uvsrc_x; + srcV += uvsrc_y * s->uvlinesize + uvsrc_x; + if( (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 3 + || (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 3){ + uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize; + + srcY -= 2 + 2*s->linesize; + ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+4, (height<<3)+4, + src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos); + srcY = s->edge_emu_buffer + 2 + 2*s->linesize; + ff_emulated_edge_mc(uvbuf , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1, + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); + ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1, + uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1); + srcU = uvbuf; + srcV = uvbuf + 16; + } + Y = s->dest[0] + xoff + yoff *s->linesize; + U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize; + V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize; + + if(block_type == RV34_MB_P_16x8){ + qpel_mc[1][dxy](Y, srcY, s->linesize); + Y += 8; + srcY += 8; + }else if(block_type == RV34_MB_P_8x16){ + qpel_mc[1][dxy](Y, srcY, s->linesize); + Y += 8 * s->linesize; + srcY += 8 * s->linesize; + } + is16x16 = (block_type != RV34_MB_P_8x8) && (block_type != RV34_MB_P_16x8) && (block_type != RV34_MB_P_8x16); + qpel_mc[!is16x16][dxy](Y, srcY, s->linesize); + chroma_mc[2-width] (U, srcU, s->uvlinesize, height*4, uvmx, uvmy); + chroma_mc[2-width] (V, srcV, s->uvlinesize, height*4, uvmx, uvmy); +} + +static void rv34_mc_1mv(RV34DecContext *r, const int block_type, + const int xoff, const int yoff, int mv_off, + const int width, const int height, int dir) +{ + rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30, + r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab + : r->s.dsp.put_h264_qpel_pixels_tab, + r->s.dsp.put_h264_chroma_pixels_tab); +} + +static void rv34_mc_2mv(RV34DecContext *r, const int block_type) +{ + rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30, + r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab + : r->s.dsp.put_h264_qpel_pixels_tab, + r->s.dsp.put_h264_chroma_pixels_tab); + rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, + r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab + : r->s.dsp.avg_h264_qpel_pixels_tab, + r->s.dsp.avg_h264_chroma_pixels_tab); +} + +/** number of motion vectors in each macroblock type */ +static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 }; + +/** + * Decode motion vector differences + * and perform motion vector reconstruction and motion compensation. + */ +static int rv34_decode_mv(RV34DecContext *r, int block_type) +{ + MpegEncContext *s = &r->s; + GetBitContext *gb = &s->gb; + int i; + + memset(r->dmv, 0, sizeof(r->dmv)); + for(i = 0; i < num_mvs[block_type]; i++){ + r->dmv[i][0] = svq3_get_se_golomb(gb); + r->dmv[i][1] = svq3_get_se_golomb(gb); + } + switch(block_type){ + case RV34_MB_TYPE_INTRA: + case RV34_MB_TYPE_INTRA16x16: + fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); + return 0; + case RV34_MB_SKIP: + if(s->pict_type == P_TYPE){ + fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4); + rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0); + break; + } + case RV34_MB_B_DIRECT: + rv34_pred_mv_b (r, RV34_MB_B_DIRECT, 0); + rv34_pred_mv_b (r, RV34_MB_B_DIRECT, 1); + rv34_mc_2mv (r, RV34_MB_B_DIRECT); + break; + case RV34_MB_P_16x16: + case RV34_MB_P_MIX16x16: + rv34_pred_mv(r, block_type, 0, 0); + rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0); + break; + case RV34_MB_B_FORWARD: + case RV34_MB_B_BACKWARD: + r->dmv[1][0] = r->dmv[0][0]; + r->dmv[1][1] = r->dmv[0][1]; + rv34_pred_mv_b (r, block_type, block_type == RV34_MB_B_BACKWARD); + rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD); + break; + case RV34_MB_P_16x8: + case RV34_MB_P_8x16: + rv34_pred_mv(r, block_type, 0, 0); + rv34_pred_mv(r, block_type, 1 + (block_type == RV34_MB_P_16x8), 1); + if(block_type == RV34_MB_P_16x8){ + rv34_mc_1mv(r, block_type, 0, 0, 0, 2, 1, 0); + rv34_mc_1mv(r, block_type, 0, 8, s->b8_stride, 2, 1, 0); + } + if(block_type == RV34_MB_P_8x16){ + rv34_mc_1mv(r, block_type, 0, 0, 0, 1, 2, 0); + rv34_mc_1mv(r, block_type, 8, 0, 1, 1, 2, 0); + } + break; + case RV34_MB_B_BIDIR: + rv34_pred_mv_b (r, block_type, 0); + rv34_pred_mv_b (r, block_type, 1); + rv34_mc_2mv (r, block_type); + break; + case RV34_MB_P_8x8: + for(i=0;i< 4;i++){ + rv34_pred_mv(r, block_type, i, i); + rv34_mc_1mv (r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1, 0); + } + break; + } + + return 0; +} +/** @} */ // mv group + +/** + * @defgroup recons Macroblock reconstruction functions + * @{ + */ +/** mapping of RV30/40 intra prediction types to standard H.264 types */ +static const int ittrans[9] = { + DC_PRED, VERT_PRED, HOR_PRED, DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_LEFT_PRED, + VERT_RIGHT_PRED, VERT_LEFT_PRED, HOR_UP_PRED, HOR_DOWN_PRED, +}; + +/** mapping of RV30/40 intra 16x16 prediction types to standard H.264 types */ +static const int ittrans16[4] = { + DC_PRED8x8, VERT_PRED8x8, HOR_PRED8x8, PLANE_PRED8x8, +}; + +/** + * Perform 4x4 intra prediction. + */ +static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int itype, int up, int left, int down, int right) +{ + uint8_t *prev = dst - stride + 4; + uint32_t topleft; + + if(!up && !left) + itype = DC_128_PRED; + else if(!up){ + if(itype == VERT_PRED) itype = HOR_PRED; + if(itype == DC_PRED) itype = LEFT_DC_PRED; + }else if(!left){ + if(itype == HOR_PRED) itype = VERT_PRED; + if(itype == DC_PRED) itype = TOP_DC_PRED; + if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN; + } + if(!down){ + if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN; + if(itype == HOR_UP_PRED) itype = HOR_UP_PRED_RV40_NODOWN; + if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN; + } + if(!right && up){ + topleft = dst[-stride + 3] * 0x01010101; + prev = &topleft; + } + r->h.pred4x4[itype](dst, prev, stride); +} + +/** add_pixels_clamped for 4x4 block */ +static void rv34_add_4x4_block(uint8_t *dst, int stride, DCTELEM block[64], int off) +{ + int x, y; + for(y = 0; y < 4; y++) + for(x = 0; x < 4; x++) + dst[x + y*stride] = av_clip_uint8(dst[x + y*stride] + block[off + x+y*8]); +} + +static inline int adjust_pred16(int itype, int up, int left) +{ + if(!up && !left) + itype = DC_128_PRED8x8; + else if(!up){ + if(itype == PLANE_PRED8x8)itype = HOR_PRED8x8; + if(itype == VERT_PRED8x8) itype = HOR_PRED8x8; + if(itype == DC_PRED8x8) itype = LEFT_DC_PRED8x8; + }else if(!left){ + if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8; + if(itype == HOR_PRED8x8) itype = VERT_PRED8x8; + if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8; + } + return itype; +} + +static void rv34_output_macroblock(RV34DecContext *r, int8_t *intra_types, int cbp, int is16) +{ + MpegEncContext *s = &r->s; + DSPContext *dsp = &s->dsp; + int i, j; + uint8_t *Y, *U, *V; + int itype; + int avail[6*8] = {0}; + int idx; + + // Set neighbour information. + if(r->avail_cache[0]) + avail[0] = 1; + if(r->avail_cache[1]) + avail[1] = avail[2] = 1; + if(r->avail_cache[2]) + avail[3] = avail[4] = 1; + if(r->avail_cache[3]) + avail[5] = 1; + if(r->avail_cache[4]) + avail[8] = avail[16] = 1; + if(r->avail_cache[8]) + avail[24] = avail[32] = 1; + + Y = s->dest[0]; + U = s->dest[1]; + V = s->dest[2]; + if(!is16){ + for(j = 0; j < 4; j++){ + idx = 9 + j*8; + for(i = 0; i < 4; i++, cbp >>= 1, Y += 4, idx++){ + rv34_pred_4x4_block(r, Y, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]); + avail[idx] = 1; + if(cbp & 1) + rv34_add_4x4_block(Y, s->linesize, s->block[(i>>1)+(j&2)], (i&1)*4+(j&1)*32); + } + Y += s->linesize * 4 - 4*4; + intra_types += s->b4_stride; + } + intra_types -= s->b4_stride * 4; + fill_rectangle(r->avail_cache + 5, 2, 2, 4, 0, 4); + for(j = 0; j < 2; j++){ + idx = 5 + j*4; + for(i = 0; i < 2; i++, cbp >>= 1, idx++){ + rv34_pred_4x4_block(r, U + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*s->b4_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); + rv34_pred_4x4_block(r, V + i*4 + j*4*s->uvlinesize, s->uvlinesize, ittrans[intra_types[i*2+j*2*s->b4_stride]], r->avail_cache[idx-4], r->avail_cache[idx-1], !i && !j, r->avail_cache[idx-3]); + r->avail_cache[idx] = 1; + if(cbp & 0x01) + rv34_add_4x4_block(U + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[4], i*4+j*32); + if(cbp & 0x10) + rv34_add_4x4_block(V + i*4 + j*4*s->uvlinesize, s->uvlinesize, s->block[5], i*4+j*32); + } + } + }else{ + itype = ittrans16[intra_types[0]]; + itype = adjust_pred16(itype, r->avail_cache[5-4], r->avail_cache[5-1]); + r->h.pred16x16[itype](Y, s->linesize); + dsp->add_pixels_clamped(s->block[0], Y, s->current_picture.linesize[0]); + dsp->add_pixels_clamped(s->block[1], Y + 8, s->current_picture.linesize[0]); + Y += s->current_picture.linesize[0] * 8; + dsp->add_pixels_clamped(s->block[2], Y, s->current_picture.linesize[0]); + dsp->add_pixels_clamped(s->block[3], Y + 8, s->current_picture.linesize[0]); + + itype = ittrans16[intra_types[0]]; + if(itype == PLANE_PRED8x8) itype = DC_PRED8x8; + itype = adjust_pred16(itype, r->avail_cache[5-4], r->avail_cache[5-1]); + r->h.pred8x8[itype](U, s->uvlinesize); + dsp->add_pixels_clamped(s->block[4], U, s->uvlinesize); + r->h.pred8x8[itype](V, s->uvlinesize); + dsp->add_pixels_clamped(s->block[5], V, s->uvlinesize); + } +} + +/** @} */ // recons group + +/** + * @addtogroup bitstream + * Decode macroblock header and return CBP in case of success, -1 otherwise. + */ +static int rv34_decode_mb_header(RV34DecContext *r, int8_t *intra_types) +{ + MpegEncContext *s = &r->s; + GetBitContext *gb = &s->gb; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + int i, t; + + if(!r->si.type){ + r->is16 = get_bits1(gb); + if(!r->is16 && !r->rv30){ + if(!get_bits1(gb)) + av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n"); + } + s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA; + r->block_type = r->is16 ? RV34_MB_TYPE_INTRA16x16 : RV34_MB_TYPE_INTRA; + }else{ + r->block_type = r->decode_mb_info(r); + if(r->block_type == -1) + return -1; + s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type]; + r->mb_type[mb_pos] = r->block_type; + if(r->block_type == RV34_MB_SKIP){ + if(s->pict_type == P_TYPE) + r->mb_type[mb_pos] = RV34_MB_P_16x16; + if(s->pict_type == B_TYPE) + r->mb_type[mb_pos] = RV34_MB_B_DIRECT; + } + r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]); + rv34_decode_mv(r, r->block_type); + if(r->block_type == RV34_MB_SKIP){ + fill_rectangle(intra_types, 4, 4, s->b4_stride, 0, sizeof(intra_types[0])); + return 0; + } + r->chroma_vlc = 1; + r->luma_vlc = 0; + } + if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){ + if(r->is16){ + t = get_bits(gb, 2); + fill_rectangle(intra_types, 4, 4, s->b4_stride, t, sizeof(intra_types[0])); + r->luma_vlc = 2; + }else{ + if(r->decode_intra_types(r, gb, intra_types) < 0) + return -1; + r->luma_vlc = 1; + } + r->chroma_vlc = 0; + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); + }else{ + for(i = 0; i < 16; i++) + intra_types[(i & 3) + (i>>2) * s->b4_stride] = 0; + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); + if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){ + r->is16 = 1; + r->chroma_vlc = 1; + r->luma_vlc = 2; + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0); + } + } + + return rv34_decode_cbp(gb, r->cur_vlcs, r->is16); +} + +/** + * @addtogroup recons + * @{ + */ +/** + * mask for retrieving all bits in coded block pattern + * corresponding to one 8x8 block + */ +#define LUMA_CBP_BLOCK_MASK 0x303 + +#define U_CBP_MASK 0x0F0000 +#define V_CBP_MASK 0xF00000 + + +static void rv34_apply_differences(RV34DecContext *r, int cbp) +{ + static const int shifts[4] = { 0, 2, 8, 10 }; + MpegEncContext *s = &r->s; + int i; + + for(i = 0; i < 4; i++) + if(cbp & (LUMA_CBP_BLOCK_MASK << shifts[i])) + s->dsp.add_pixels_clamped(s->block[i], s->dest[0] + (i & 1)*8 + (i&2)*4*s->linesize, s->linesize); + if(cbp & U_CBP_MASK) + s->dsp.add_pixels_clamped(s->block[4], s->dest[1], s->uvlinesize); + if(cbp & V_CBP_MASK) + s->dsp.add_pixels_clamped(s->block[5], s->dest[2], s->uvlinesize); +} + +static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types) +{ + MpegEncContext *s = &r->s; + GetBitContext *gb = &s->gb; + int cbp, cbp2; + int i, blknum, blkoff; + DCTELEM block16[64]; + int luma_dc_quant; + int dist; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + + // Calculate which neighbours are available. Maybe it's worth optimizing too. + memset(r->avail_cache, 0, sizeof(r->avail_cache)); + fill_rectangle(r->avail_cache + 5, 2, 2, 4, 1, 4); + dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width; + if(s->mb_x && dist) + r->avail_cache[4] = + r->avail_cache[8] = s->current_picture_ptr->mb_type[mb_pos - 1]; + if(dist >= s->mb_width) + r->avail_cache[1] = + r->avail_cache[2] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride]; + if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1) + r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1]; + if(s->mb_x && dist > s->mb_width) + r->avail_cache[0] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1]; + + s->qscale = r->si.quant; + cbp = cbp2 = rv34_decode_mb_header(r, intra_types); + r->cbp_luma [s->mb_x + s->mb_y * s->mb_stride] = cbp; + r->cbp_chroma[s->mb_x + s->mb_y * s->mb_stride] = cbp >> 16; + s->current_picture.qscale_table[s->mb_x + s->mb_y * s->mb_stride] = s->qscale; + + if(cbp == -1) + return -1; + + luma_dc_quant = r->si.type ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale]; + if(r->is16){ + memset(block16, 0, sizeof(block16)); + rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0); + rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]); + rv34_inv_transform_noround(block16); + } + + for(i = 0; i < 16; i++, cbp >>= 1){ + if(!r->is16 && !(cbp & 1)) continue; + blknum = ((i & 2) >> 1) + ((i & 8) >> 2); + blkoff = ((i & 1) << 2) + ((i & 4) << 3); + if(cbp & 1) + rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0); + rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]); + if(r->is16) //FIXME: optimize + s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)]; + rv34_inv_transform(s->block[blknum] + blkoff); + } + if(r->block_type == RV34_MB_P_MIX16x16) + r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1); + for(; i < 24; i++, cbp >>= 1){ + if(!(cbp & 1)) continue; + blknum = ((i & 4) >> 2) + 4; + blkoff = ((i & 1) << 2) + ((i & 2) << 4); + rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1); + rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]); + rv34_inv_transform(s->block[blknum] + blkoff); + } + if(IS_INTRA(s->current_picture_ptr->mb_type[s->mb_x + s->mb_y*s->mb_stride])) + rv34_output_macroblock(r, intra_types, cbp2, r->is16); + else + rv34_apply_differences(r, cbp2); + + return 0; +} + +static int check_slice_end(RV34DecContext *r, MpegEncContext *s) +{ + int bits; + if(s->mb_y >= s->mb_height) + return 1; + if(!s->mb_num_left) + return 1; + if(r->s.mb_skip_run > 1) + return 0; + bits = r->bits - get_bits_count(&s->gb); + if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits))) + return 1; + return 0; +} + +static inline int slice_compare(SliceInfo *si1, SliceInfo *si2) +{ + return si1->type != si2->type || + si1->start >= si2->start || + si1->width != si2->width || + si1->height != si2->height; +} + +static int rv34_decode_slice(RV34DecContext *r, int end, uint8_t* buf, int buf_size) +{ + MpegEncContext *s = &r->s; + GetBitContext *gb = &s->gb; + int mb_pos; + int res; + + init_get_bits(&r->s.gb, buf, buf_size*8); + res = r->parse_slice_header(r, gb, &r->si); + if(res < 0){ + av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n"); + return -1; + } + + if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) { + if(s->width != r->si.width || s->height != r->si.height){ + av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height); + MPV_common_end(s); + s->width = r->si.width; + s->height = r->si.height; + if(MPV_common_init(s) < 0) + return -1; + r->intra_types_hist = av_realloc(r->intra_types_hist, s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist)); + r->intra_types = r->intra_types_hist + s->b4_stride * 4; + r->mb_type = av_realloc(r->mb_type, r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type)); + r->cbp_luma = av_realloc(r->cbp_luma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma)); + r->cbp_chroma = av_realloc(r->cbp_chroma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma)); + } + s->pict_type = r->si.type ? r->si.type : I_TYPE; + if(MPV_frame_start(s, s->avctx) < 0) + return -1; + ff_er_frame_start(s); + s->current_picture_ptr = &s->current_picture; + s->mb_x = s->mb_y = 0; + } + + r->si.end = end; + s->qscale = r->si.quant; + r->bits = buf_size*8; + s->mb_num_left = r->si.end - r->si.start; + r->s.mb_skip_run = 0; + + mb_pos = s->mb_x + s->mb_y * s->mb_width; + if(r->si.start != mb_pos){ + av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->si.start, mb_pos); + s->mb_x = r->si.start % s->mb_width; + s->mb_y = r->si.start / s->mb_width; + } + memset(r->intra_types_hist, -1, s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist)); + s->first_slice_line = 1; + s->resync_mb_x= s->mb_x; + s->resync_mb_y= s->mb_y; + + ff_init_block_index(s); + while(!check_slice_end(r, s)) { + ff_update_block_index(s); + s->dsp.clear_blocks(s->block[0]); + + if(rv34_decode_macroblock(r, r->intra_types + s->mb_x * 4 + 1) < 0){ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_ERROR|DC_ERROR|MV_ERROR); + return -1; + } + if (++s->mb_x == s->mb_width) { + s->mb_x = 0; + s->mb_y++; + ff_init_block_index(s); + + memmove(r->intra_types_hist, r->intra_types, s->b4_stride * 4 * sizeof(*r->intra_types_hist)); + memset(r->intra_types, -1, s->b4_stride * 4 * sizeof(*r->intra_types_hist)); + } + if(s->mb_x == s->resync_mb_x) + s->first_slice_line=0; + s->mb_num_left--; + } + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END); + + return (s->mb_y == s->mb_height); +} + +/** @} */ // recons group end + +/** + * Initialize decoder. + */ +int ff_rv34_decode_init(AVCodecContext *avctx) +{ + RV34DecContext *r = avctx->priv_data; + MpegEncContext *s = &r->s; + + MPV_decode_defaults(s); + s->avctx= avctx; + s->out_format = FMT_H263; + s->codec_id= avctx->codec_id; + + s->width = avctx->width; + s->height = avctx->height; + + r->s.avctx = avctx; + avctx->flags |= CODEC_FLAG_EMU_EDGE; + r->s.flags |= CODEC_FLAG_EMU_EDGE; + avctx->pix_fmt = PIX_FMT_YUV420P; + avctx->has_b_frames = 1; + s->low_delay = 0; + + if (MPV_common_init(s) < 0) + return -1; + + ff_h264_pred_init(&r->h, CODEC_ID_RV40); + + r->intra_types_hist = av_malloc(s->b4_stride * 4 * 2 * sizeof(*r->intra_types_hist)); + r->intra_types = r->intra_types_hist + s->b4_stride * 4; + + r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type)); + + r->cbp_luma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma)); + r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma)); + + if(!intra_vlcs[0].cbppattern[0].bits) + rv34_init_tables(); + + return 0; +} + +static int get_slice_offset(AVCodecContext *avctx, uint8_t *buf, int n) +{ + if(avctx->slice_count) return avctx->slice_offset[n]; + else return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) : AV_RB32(buf + n*8); +} + +int ff_rv34_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + RV34DecContext *r = avctx->priv_data; + MpegEncContext *s = &r->s; + AVFrame *pict = data; + SliceInfo si; + int i; + int slice_count; + uint8_t *slices_hdr = NULL; + int last = 0; + + /* no supplementary picture */ + if (buf_size == 0) { + /* special case for last picture */ + if (s->low_delay==0 && s->next_picture_ptr) { + *pict= *(AVFrame*)s->next_picture_ptr; + s->next_picture_ptr= NULL; + + *data_size = sizeof(AVFrame); + } + return 0; + } + + if(!avctx->slice_count){ + slice_count = (*buf++) + 1; + slices_hdr = buf + 4; + buf += 8 * slice_count; + }else + slice_count = avctx->slice_count; + + for(i=0; i<slice_count; i++){ + int offset= get_slice_offset(avctx, slices_hdr, i); + int size; + if(i+1 == slice_count) + size= buf_size - offset; + else + size= get_slice_offset(avctx, slices_hdr, i+1) - offset; + + r->si.end = s->mb_width * s->mb_height; + if(i+1 < slice_count){ + init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8); + if(r->parse_slice_header(r, &r->s.gb, &si) < 0){ + if(i+2 < slice_count) + size = get_slice_offset(avctx, slices_hdr, i+2) - offset; + else + size = buf_size - offset; + }else + r->si.end = si.start; + } + last = rv34_decode_slice(r, r->si.end, buf + offset, size); + s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start; + if(last) + break; + } + + if(last){ + if(r->loop_filter) + r->loop_filter(r); + ff_er_frame_end(s); + MPV_frame_end(s); + if (s->pict_type == B_TYPE || s->low_delay) { + *pict= *(AVFrame*)s->current_picture_ptr; + } else if (s->last_picture_ptr != NULL) { + *pict= *(AVFrame*)s->last_picture_ptr; + } + + if(s->last_picture_ptr || s->low_delay){ + *data_size = sizeof(AVFrame); + ff_print_debug_info(s, pict); + } + s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) + } + return buf_size; +} + +int ff_rv34_decode_end(AVCodecContext *avctx) +{ + RV34DecContext *r = avctx->priv_data; + + MPV_common_end(&r->s); + + av_freep(&r->intra_types_hist); + r->intra_types = NULL; + av_freep(&r->mb_type); + + return 0; +} diff --git a/contrib/ffmpeg/libavcodec/rv34.h b/contrib/ffmpeg/libavcodec/rv34.h new file mode 100644 index 000000000..dff36f29e --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv34.h @@ -0,0 +1,122 @@ +/* + * RV30/40 decoder common data declarations + * Copyright (c) 2007 Mike Melanson, 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 + */ + +/** + * @file rv34.h + * RV30 and RV40 decoder common data declarations + */ + +#ifndef FFMPEG_RV34_H +#define FFMPEG_RV34_H + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + +#include "h264pred.h" + +/** + * RV30 and RV40 Macroblock types + */ +enum RV40BlockTypes{ + RV34_MB_TYPE_INTRA, ///< Intra macroblock + RV34_MB_TYPE_INTRA16x16, ///< Intra macroblock with DCs in a separate 4x4 block + RV34_MB_P_16x16, ///< P-frame macroblock, one motion frame + RV34_MB_P_8x8, ///< P-frame macroblock, 8x8 motion compensation partitions + RV34_MB_B_FORWARD, ///< B-frame macroblock, forward prediction + RV34_MB_B_BACKWARD, ///< B-frame macroblock, backward prediction + RV34_MB_SKIP, ///< Skipped block + RV34_MB_B_DIRECT, ///< Bidirectionally predicted B-frame macroblock, no motion vectors + RV34_MB_P_16x8, ///< P-frame macroblock, 16x8 motion compensation partitions + RV34_MB_P_8x16, ///< P-frame macroblock, 8x16 motion compensation partitions + RV34_MB_B_BIDIR, ///< Bidirectionally predicted B-frame macroblock, two motion vectors + RV34_MB_P_MIX16x16, ///< P-frame macroblock with DCs in a separate 4x4 block, one motion vector + RV34_MB_TYPES +}; + +/** + * VLC tables used by the decoder + * + * Intra frame VLC sets do not contain some of those tables. + */ +typedef struct RV34VLC{ + VLC cbppattern[2]; ///< VLCs used for pattern of coded block patterns decoding + VLC cbp[2][4]; ///< VLCs used for coded block patterns decoding + VLC first_pattern[4]; ///< VLCs used for decoding coefficients in the first subblock + VLC second_pattern[2]; ///< VLCs used for decoding coefficients in the subblocks 2 and 3 + VLC third_pattern[2]; ///< VLCs used for decoding coefficients in the last subblock + VLC coefficient; ///< VLCs used for decoding big coefficients +}RV34VLC; + +/** essential slice information */ +typedef struct SliceInfo{ + int type; ///< slice type (intra, inter) + int quant; ///< quantizer used for this slice + int vlc_set; ///< VLCs used for this slice + int start, end; ///< start and end macroblocks of the slice + int width; ///< coded width + int height; ///< coded height +}SliceInfo; + +/** decoder context */ +typedef struct RV34DecContext{ + MpegEncContext s; + int8_t *intra_types_hist;///< old block types, used for prediction + int8_t *intra_types; ///< block types + const uint8_t *luma_dc_quant_i;///< luma subblock DC quantizer for intraframes + const uint8_t *luma_dc_quant_p;///< luma subblock DC quantizer for interframes + + RV34VLC *cur_vlcs; ///< VLC set used for current frame decoding + int bits; ///< slice size in bits + H264PredContext h; ///< functions for 4x4 and 16x16 intra block prediction + SliceInfo si; ///< current slice information + + int *mb_type; ///< internal macroblock types + int block_type; ///< current block type + int luma_vlc; ///< which VLC set will be used for decoding of luma blocks + int chroma_vlc; ///< which VLC set will be used for decoding of chroma blocks + int is16; ///< current block has additional 16x16 specific features or not + int dmv[4][2]; ///< differential motion vectors for the current macroblock + + int rv30; ///< indicates which RV variasnt is currently decoded + int rpr; ///< one field size in RV30 slice header + + uint16_t *cbp_luma; ///< CBP values for luma subblocks + uint8_t *cbp_chroma; ///< CBP values for chroma subblocks + + /** 8x8 block available flags (for MV prediction) */ + DECLARE_ALIGNED_8(uint32_t, avail_cache[3*4]); + + int (*parse_slice_header)(struct RV34DecContext *r, GetBitContext *gb, SliceInfo *si); + int (*decode_mb_info)(struct RV34DecContext *r); + int (*decode_intra_types)(struct RV34DecContext *r, GetBitContext *gb, int8_t *dst); + void (*loop_filter)(struct RV34DecContext *r); +}RV34DecContext; + +/** + * common decoding functions + */ +int ff_rv34_get_start_offset(GetBitContext *gb, int blocks); +int ff_rv34_decode_init(AVCodecContext *avctx); +int ff_rv34_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size); +int ff_rv34_decode_end(AVCodecContext *avctx); + +#endif /* FFMPEG_RV34_H */ diff --git a/contrib/ffmpeg/libavcodec/rv34data.h b/contrib/ffmpeg/libavcodec/rv34data.h new file mode 100644 index 000000000..25256e23d --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv34data.h @@ -0,0 +1,148 @@ +/* + * RealVideo 4 decoder + * copyright (c) 2007 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 + */ + +/** + * @file rv34data.h + * miscellaneous RV30/40 tables + */ + +#ifndef FFMPEG_RV34DATA_H +#define FFMPEG_RV34DATA_H + +#include <stdint.h> + +/** + * number of ones in nibble minus one + */ +static const uint8_t rv34_count_ones[16] = { + 0, 0, 0, 1, 0, 1, 1, 2, 0, 1, 1, 2, 1, 2, 2, 3 +}; + +/** + * values used to reconstruct coded block pattern + */ +static const uint8_t rv34_cbp_code[16] = { + 0x00, 0x20, 0x10, 0x30, 0x02, 0x22, 0x12, 0x32, + 0x01, 0x21, 0x11, 0x31, 0x03, 0x23, 0x13, 0x33 +}; + +/** + * precalculated results of division by three and modulo three for values 0-107 + * + * A lot of four-tuples in RV40 are represented as c0*27+c1*9+c2*3+c3. + * This table allows conversion from a value back to a vector. + */ +static const uint8_t modulo_three_table[108][4] = { + { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0, 2 }, { 0, 0, 1, 0 }, + { 0, 0, 1, 1 }, { 0, 0, 1, 2 }, { 0, 0, 2, 0 }, { 0, 0, 2, 1 }, + { 0, 0, 2, 2 }, { 0, 1, 0, 0 }, { 0, 1, 0, 1 }, { 0, 1, 0, 2 }, + { 0, 1, 1, 0 }, { 0, 1, 1, 1 }, { 0, 1, 1, 2 }, { 0, 1, 2, 0 }, + { 0, 1, 2, 1 }, { 0, 1, 2, 2 }, { 0, 2, 0, 0 }, { 0, 2, 0, 1 }, + { 0, 2, 0, 2 }, { 0, 2, 1, 0 }, { 0, 2, 1, 1 }, { 0, 2, 1, 2 }, + { 0, 2, 2, 0 }, { 0, 2, 2, 1 }, { 0, 2, 2, 2 }, { 1, 0, 0, 0 }, + { 1, 0, 0, 1 }, { 1, 0, 0, 2 }, { 1, 0, 1, 0 }, { 1, 0, 1, 1 }, + { 1, 0, 1, 2 }, { 1, 0, 2, 0 }, { 1, 0, 2, 1 }, { 1, 0, 2, 2 }, + { 1, 1, 0, 0 }, { 1, 1, 0, 1 }, { 1, 1, 0, 2 }, { 1, 1, 1, 0 }, + { 1, 1, 1, 1 }, { 1, 1, 1, 2 }, { 1, 1, 2, 0 }, { 1, 1, 2, 1 }, + { 1, 1, 2, 2 }, { 1, 2, 0, 0 }, { 1, 2, 0, 1 }, { 1, 2, 0, 2 }, + { 1, 2, 1, 0 }, { 1, 2, 1, 1 }, { 1, 2, 1, 2 }, { 1, 2, 2, 0 }, + { 1, 2, 2, 1 }, { 1, 2, 2, 2 }, { 2, 0, 0, 0 }, { 2, 0, 0, 1 }, + { 2, 0, 0, 2 }, { 2, 0, 1, 0 }, { 2, 0, 1, 1 }, { 2, 0, 1, 2 }, + { 2, 0, 2, 0 }, { 2, 0, 2, 1 }, { 2, 0, 2, 2 }, { 2, 1, 0, 0 }, + { 2, 1, 0, 1 }, { 2, 1, 0, 2 }, { 2, 1, 1, 0 }, { 2, 1, 1, 1 }, + { 2, 1, 1, 2 }, { 2, 1, 2, 0 }, { 2, 1, 2, 1 }, { 2, 1, 2, 2 }, + { 2, 2, 0, 0 }, { 2, 2, 0, 1 }, { 2, 2, 0, 2 }, { 2, 2, 1, 0 }, + { 2, 2, 1, 1 }, { 2, 2, 1, 2 }, { 2, 2, 2, 0 }, { 2, 2, 2, 1 }, + { 2, 2, 2, 2 }, { 3, 0, 0, 0 }, { 3, 0, 0, 1 }, { 3, 0, 0, 2 }, + { 3, 0, 1, 0 }, { 3, 0, 1, 1 }, { 3, 0, 1, 2 }, { 3, 0, 2, 0 }, + { 3, 0, 2, 1 }, { 3, 0, 2, 2 }, { 3, 1, 0, 0 }, { 3, 1, 0, 1 }, + { 3, 1, 0, 2 }, { 3, 1, 1, 0 }, { 3, 1, 1, 1 }, { 3, 1, 1, 2 }, + { 3, 1, 2, 0 }, { 3, 1, 2, 1 }, { 3, 1, 2, 2 }, { 3, 2, 0, 0 }, + { 3, 2, 0, 1 }, { 3, 2, 0, 2 }, { 3, 2, 1, 0 }, { 3, 2, 1, 1 }, + { 3, 2, 1, 2 }, { 3, 2, 2, 0 }, { 3, 2, 2, 1 }, { 3, 2, 2, 2 }, +}; + +/** + * quantizer values used for AC and DC coefficients in chroma blocks + */ +static const uint8_t rv34_chroma_quant[2][32] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25 }, + { 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 15, 16, 17, 18, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23 } +}; + +/** + * This table is used for dequantizing. + */ +static const uint16_t rv34_qscale_tab[32] = { + 60, 67, 76, 85, 96, 108, 121, 136, + 152, 171, 192, 216, 242, 272, 305, 341, + 383, 432, 481, 544, 606, 683, 767, 854, + 963, 1074, 1212, 1392, 1566, 1708, 1978, 2211 +}; + +/** + * 4x4 dezigzag pattern + */ +static const uint8_t rv34_dezigzag[16] = { + 0, 1, 8, 16, + 9, 2, 3, 10, + 17, 24, 25, 18, + 11, 19, 26, 27 +}; + +/** + * tables used to translate a quantizer value into a VLC set for decoding + * The first table is used for intraframes. + */ +static const uint8_t rv34_quant_to_vlc_set[2][31] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, + 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6 }, +}; + +/** + * table for obtaining the quantizer difference + * @todo Use with modified_quant_tab from h263data.h. + */ +static const uint8_t rv34_dquant_tab[2][32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +{ + 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9,10,11,12,13,14,15,16,17,18,18,19,20,21,22,23,24,25,26,27,28 +},{ + 0, 2, 3, 4, 5, 6, 7, 8, 9,10,11,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,29,30,31,31,31,26 +} +}; + +/** + * maximum number of macroblocks for each of the possible slice offset sizes + * @todo This is the same as ff_mba_max, maybe use it instead. + */ +static const uint16_t rv34_mb_max_sizes[6] = { 0x2F, 0x68, 0x18B, 0x62F, 0x18BF, 0x23FF }; +/** + * bits needed to code the slice offset for the given size + * @todo This is the same as ff_mba_length, maybe use it instead. + */ +static const uint8_t rv34_mb_bits_sizes[6] = { 6, 7, 9, 11, 13, 14 }; + +#endif /* FFMPEG_RV34DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/rv34vlc.h b/contrib/ffmpeg/libavcodec/rv34vlc.h new file mode 100644 index 000000000..ef3cfbab3 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv34vlc.h @@ -0,0 +1,4054 @@ +/* + * RealVideo 3/4 decoder + * Copyright (c) 2007 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 + */ + +/** + * @file rv34vlc.h + * RV30/40 VLC tables + */ + +#ifndef FFMPEG_RV34VLC_H +#define FFMPEG_RV34VLC_H + +#include <stdint.h> + +#define NUM_INTRA_TABLES 5 +#define NUM_INTER_TABLES 7 + +#define CBPPAT_VLC_SIZE 1296 +#define CBP_VLC_SIZE 16 +#define FIRSTBLK_VLC_SIZE 864 +#define OTHERBLK_VLC_SIZE 108 +#define COEFF_VLC_SIZE 32 + +static const uint8_t rv34_table_intra_cbppat[NUM_INTRA_TABLES][2][CBPPAT_VLC_SIZE] = { + { + { + 8, 10, 10, 10, 10, 10, 11, 10, 10, 11, 10, 10, 10, 10, 10, 6, + 12, 12, 13, 12, 13, 12, 13, 11, 13, 13, 13, 12, 13, 12, 12, 8, + 14, 13, 16, 13, 15, 13, 16, 12, 16, 16, 16, 14, 16, 13, 14, 10, + 12, 13, 12, 12, 13, 13, 13, 12, 13, 13, 12, 12, 13, 12, 12, 8, + 13, 14, 14, 12, 14, 14, 14, 12, 14, 15, 14, 12, 14, 13, 13, 8, + 16, 16, 16, 12, 16, 16, 16, 13, 16, 16, 16, 13, 16, 14, 14, 9, + 14, 16, 13, 13, 16, 16, 16, 14, 15, 16, 14, 13, 15, 15, 14, 10, + 16, 16, 14, 13, 16, 16, 16, 13, 16, 16, 16, 13, 16, 15, 14, 10, + 16, 16, 16, 11, 16, 16, 16, 12, 16, 16, 16, 12, 16, 16, 15, 9, + 12, 13, 13, 13, 12, 12, 14, 12, 12, 14, 13, 12, 12, 12, 12, 8, + 14, 14, 16, 14, 13, 12, 14, 12, 14, 15, 14, 13, 13, 12, 13, 8, + 16, 16, 16, 15, 16, 13, 16, 13, 16, 16, 16, 15, 16, 13, 15, 10, + 14, 16, 14, 14, 14, 14, 15, 13, 14, 16, 14, 13, 13, 13, 13, 9, + 16, 16, 16, 14, 16, 14, 16, 12, 16, 16, 14, 13, 14, 13, 13, 8, + 16, 16, 16, 14, 16, 14, 16, 13, 16, 16, 16, 14, 16, 14, 14, 9, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 14, 10, + 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 16, 14, 16, 15, 14, 9, + 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 16, 13, 16, 15, 15, 8, + 14, 16, 16, 16, 14, 14, 16, 14, 16, 16, 16, 15, 13, 13, 14, 10, + 16, 16, 16, 16, 15, 13, 16, 13, 16, 16, 16, 16, 16, 13, 14, 10, + 16, 16, 16, 16, 16, 11, 16, 12, 16, 16, 16, 16, 16, 12, 16, 9, + 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 14, 14, 10, + 16, 16, 16, 16, 16, 15, 16, 13, 16, 16, 16, 15, 16, 13, 14, 9, + 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 16, 16, 13, 14, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 11, + 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, 9, + 16, 16, 16, 14, 16, 15, 16, 11, 16, 16, 16, 14, 16, 14, 14, 8, + 12, 13, 13, 13, 13, 13, 14, 12, 12, 13, 12, 12, 12, 12, 12, 8, + 14, 14, 16, 14, 15, 14, 16, 13, 14, 15, 14, 13, 14, 13, 13, 9, + 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 16, 14, 16, 14, 16, 10, + 14, 15, 14, 14, 15, 14, 15, 13, 14, 14, 13, 12, 13, 13, 13, 9, + 15, 16, 15, 14, 16, 16, 16, 13, 15, 16, 14, 12, 14, 13, 13, 8, + 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 16, 13, 16, 14, 14, 9, + 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 13, 13, 16, 16, 14, 10, + 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 15, 13, 16, 14, 14, 9, + 16, 16, 16, 12, 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 15, 8, + 13, 14, 14, 14, 14, 14, 16, 13, 13, 14, 14, 13, 12, 12, 12, 8, + 16, 16, 16, 14, 15, 14, 16, 13, 15, 16, 14, 13, 13, 12, 13, 8, + 16, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 14, 16, 13, 14, 9, + 15, 16, 16, 15, 16, 15, 16, 13, 14, 16, 14, 13, 13, 13, 12, 8, + 16, 16, 16, 14, 16, 14, 15, 12, 15, 15, 14, 12, 13, 12, 12, 7, + 16, 16, 16, 14, 16, 14, 16, 12, 16, 16, 16, 13, 16, 13, 13, 7, + 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 14, 14, 16, 14, 13, 9, + 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 14, 12, 16, 13, 12, 7, + 16, 16, 16, 12, 16, 16, 16, 11, 16, 16, 15, 12, 16, 13, 13, 6, + 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 15, 13, 13, 14, 10, + 16, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 14, 13, 14, 9, + 16, 16, 16, 16, 16, 13, 16, 13, 16, 16, 16, 16, 16, 12, 14, 8, + 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 14, 13, 13, 9, + 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 13, 14, 12, 12, 7, + 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 13, 14, 12, 13, 6, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 14, 9, + 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 13, 15, 13, 12, 7, + 16, 16, 16, 13, 16, 14, 16, 11, 16, 16, 16, 12, 16, 12, 12, 5, + 14, 16, 15, 16, 16, 16, 16, 15, 14, 15, 14, 14, 13, 14, 13, 10, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 14, 16, 10, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, + 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 14, 14, 15, 14, 13, 10, + 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 14, 13, 16, 14, 14, 9, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 15, 9, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, 13, 16, 16, 13, 10, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 13, 16, 16, 13, 9, + 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 15, 12, 16, 16, 14, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 15, 14, 13, 13, 13, 9, + 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 14, 13, 13, 9, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 15, 9, + 16, 16, 16, 16, 16, 16, 16, 15, 15, 16, 14, 14, 14, 13, 13, 9, + 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 14, 12, 13, 12, 12, 7, + 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 13, 16, 13, 13, 7, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 13, 16, 14, 13, 9, + 16, 16, 16, 15, 16, 16, 16, 13, 16, 16, 13, 12, 14, 13, 12, 6, + 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 14, 10, 15, 12, 12, 5, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, 13, 13, 9, + 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 15, 13, 12, 13, 8, + 16, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 15, 12, 14, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 13, 13, 13, 8, + 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 15, 13, 12, 11, 12, 6, + 16, 16, 16, 15, 16, 14, 16, 12, 16, 16, 16, 12, 13, 10, 12, 5, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 13, 14, 12, 8, + 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 13, 12, 13, 12, 10, 5, + 16, 16, 16, 13, 16, 13, 16, 10, 16, 16, 13, 10, 13, 10, 10, 1, + }, + { + 2, 7, 7, 8, 7, 8, 9, 8, 7, 9, 8, 8, 8, 8, 9, 7, + 6, 9, 10, 10, 10, 10, 11, 10, 10, 11, 11, 11, 10, 11, 11, 9, + 9, 11, 12, 12, 12, 13, 14, 13, 13, 14, 14, 13, 13, 13, 14, 11, + 6, 10, 9, 10, 10, 11, 11, 11, 10, 11, 10, 11, 11, 11, 11, 9, + 6, 9, 10, 10, 10, 11, 12, 11, 10, 12, 11, 11, 11, 11, 11, 8, + 9, 11, 12, 12, 12, 13, 13, 13, 12, 14, 14, 13, 13, 13, 13, 10, + 9, 13, 11, 13, 13, 14, 14, 13, 13, 14, 13, 13, 14, 14, 14, 12, + 9, 12, 12, 12, 12, 14, 14, 13, 13, 14, 13, 13, 13, 14, 13, 11, + 8, 12, 12, 11, 12, 14, 14, 12, 13, 14, 14, 13, 13, 13, 14, 11, + 6, 10, 10, 11, 9, 10, 12, 11, 10, 12, 11, 11, 10, 11, 11, 9, + 7, 10, 10, 11, 10, 11, 12, 11, 11, 12, 11, 11, 11, 11, 11, 9, + 9, 12, 13, 13, 12, 12, 14, 13, 13, 14, 14, 13, 14, 13, 14, 11, + 8, 11, 11, 12, 11, 12, 12, 12, 11, 13, 12, 12, 12, 12, 12, 10, + 7, 10, 10, 11, 10, 11, 12, 11, 10, 12, 11, 11, 11, 11, 11, 8, + 9, 11, 12, 12, 12, 12, 13, 12, 12, 13, 13, 12, 13, 12, 13, 10, + 10, 13, 13, 14, 14, 14, 15, 14, 14, 15, 14, 15, 14, 14, 14, 12, + 9, 12, 12, 13, 12, 13, 14, 13, 12, 13, 13, 12, 13, 13, 13, 10, + 9, 12, 12, 12, 12, 13, 14, 12, 12, 14, 13, 12, 13, 13, 13, 10, + 9, 12, 13, 13, 11, 13, 14, 13, 13, 14, 14, 14, 12, 13, 13, 11, + 10, 12, 13, 13, 12, 12, 14, 13, 13, 14, 14, 14, 13, 13, 14, 11, + 10, 13, 14, 14, 13, 12, 15, 13, 14, 14, 14, 14, 15, 13, 14, 11, + 11, 14, 14, 14, 13, 14, 15, 14, 14, 15, 15, 14, 13, 14, 14, 12, + 10, 13, 12, 13, 12, 12, 14, 13, 13, 14, 13, 13, 13, 13, 13, 10, + 10, 12, 13, 13, 13, 12, 14, 12, 13, 14, 14, 13, 13, 13, 13, 10, + 13, 15, 16, 16, 15, 15, 16, 16, 15, 16, 15, 16, 16, 16, 16, 14, + 11, 14, 14, 14, 14, 14, 15, 14, 14, 15, 15, 14, 14, 14, 15, 11, + 10, 13, 13, 13, 13, 13, 14, 12, 13, 14, 14, 13, 13, 13, 13, 10, + 6, 10, 10, 11, 10, 11, 12, 11, 10, 12, 10, 11, 10, 11, 11, 9, + 8, 11, 11, 12, 11, 12, 13, 12, 11, 12, 12, 12, 12, 12, 12, 10, + 11, 13, 14, 14, 13, 14, 15, 14, 13, 15, 15, 14, 14, 14, 15, 12, + 7, 11, 10, 12, 11, 12, 12, 12, 11, 12, 11, 12, 11, 12, 12, 10, + 7, 10, 10, 11, 10, 11, 12, 11, 11, 12, 11, 11, 11, 11, 11, 9, + 10, 12, 13, 13, 12, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 10, + 10, 13, 12, 14, 13, 14, 14, 14, 13, 14, 12, 14, 15, 14, 14, 11, + 10, 12, 12, 12, 12, 13, 14, 13, 13, 14, 13, 12, 13, 13, 13, 10, + 9, 12, 13, 13, 13, 14, 14, 13, 13, 14, 14, 13, 13, 13, 13, 10, + 7, 10, 10, 11, 10, 11, 12, 11, 10, 12, 12, 11, 9, 11, 11, 9, + 7, 10, 11, 11, 10, 11, 12, 11, 10, 12, 12, 11, 11, 11, 11, 9, + 10, 12, 13, 13, 13, 13, 15, 13, 13, 14, 13, 13, 13, 13, 13, 10, + 8, 11, 11, 11, 11, 11, 12, 11, 11, 12, 12, 11, 11, 12, 11, 9, + 6, 9, 9, 10, 9, 10, 10, 10, 9, 11, 10, 10, 9, 10, 10, 7, + 8, 10, 11, 11, 11, 11, 12, 11, 11, 12, 12, 11, 11, 11, 11, 8, + 10, 13, 13, 13, 13, 14, 14, 13, 13, 14, 13, 13, 13, 13, 13, 11, + 8, 11, 11, 11, 11, 12, 12, 11, 11, 12, 11, 11, 11, 11, 11, 8, + 8, 11, 11, 11, 11, 12, 12, 10, 11, 12, 12, 11, 11, 11, 11, 8, + 10, 13, 13, 13, 12, 13, 14, 13, 12, 14, 14, 14, 10, 13, 13, 11, + 10, 12, 12, 13, 12, 13, 14, 12, 12, 13, 13, 13, 12, 12, 13, 10, + 11, 13, 14, 14, 13, 13, 14, 13, 13, 15, 14, 13, 13, 13, 13, 10, + 10, 12, 13, 13, 12, 13, 14, 13, 13, 14, 14, 13, 12, 13, 13, 11, + 8, 11, 11, 11, 11, 11, 12, 11, 11, 12, 12, 11, 11, 11, 11, 8, + 9, 11, 12, 12, 11, 11, 12, 11, 12, 12, 12, 11, 12, 11, 11, 8, + 12, 15, 14, 14, 14, 15, 15, 14, 14, 15, 15, 14, 14, 14, 15, 12, + 10, 12, 12, 12, 12, 12, 13, 12, 12, 13, 13, 12, 12, 12, 12, 9, + 9, 11, 11, 11, 11, 11, 12, 10, 11, 12, 12, 11, 11, 11, 11, 7, + 10, 13, 13, 13, 13, 14, 15, 14, 13, 14, 14, 14, 12, 14, 15, 12, + 11, 14, 14, 14, 14, 15, 15, 14, 14, 15, 15, 15, 14, 15, 15, 12, + 13, 16, 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 14, + 10, 13, 13, 14, 13, 15, 14, 14, 13, 15, 13, 14, 14, 14, 14, 12, + 10, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 13, 13, 14, 11, + 12, 14, 14, 14, 14, 15, 15, 14, 14, 15, 15, 14, 15, 14, 14, 12, + 11, 14, 14, 15, 14, 15, 15, 14, 14, 15, 12, 14, 15, 16, 15, 12, + 11, 13, 13, 14, 13, 14, 14, 14, 14, 14, 13, 13, 14, 14, 14, 11, + 11, 14, 14, 14, 14, 15, 15, 14, 14, 16, 14, 13, 14, 14, 14, 11, + 10, 13, 13, 13, 12, 14, 14, 14, 12, 15, 14, 14, 11, 13, 13, 12, + 10, 12, 13, 14, 12, 13, 14, 13, 13, 14, 14, 13, 12, 13, 13, 11, + 12, 14, 14, 15, 14, 15, 16, 15, 15, 15, 15, 15, 14, 14, 15, 12, + 10, 13, 13, 13, 12, 13, 14, 13, 13, 14, 13, 13, 12, 13, 13, 11, + 9, 11, 11, 12, 11, 12, 12, 11, 11, 12, 12, 11, 11, 11, 11, 9, + 10, 12, 12, 12, 12, 12, 13, 12, 12, 13, 13, 12, 13, 12, 12, 9, + 11, 13, 13, 15, 14, 14, 15, 14, 14, 15, 14, 14, 14, 14, 14, 11, + 10, 12, 12, 12, 12, 12, 13, 12, 12, 13, 11, 11, 12, 12, 12, 8, + 9, 12, 12, 11, 12, 12, 13, 11, 12, 12, 12, 11, 12, 11, 11, 8, + 10, 13, 13, 14, 12, 14, 15, 14, 13, 15, 15, 14, 10, 13, 13, 11, + 11, 13, 14, 13, 13, 14, 14, 13, 13, 14, 14, 14, 11, 13, 13, 11, + 12, 14, 14, 14, 14, 14, 15, 14, 15, 16, 15, 14, 13, 13, 14, 11, + 11, 14, 13, 14, 13, 14, 15, 14, 13, 15, 14, 14, 11, 13, 13, 11, + 9, 12, 12, 12, 11, 12, 13, 11, 12, 13, 12, 11, 10, 11, 11, 8, + 10, 12, 12, 12, 12, 12, 13, 11, 12, 12, 12, 11, 11, 11, 11, 8, + 12, 15, 14, 15, 14, 15, 16, 15, 15, 15, 15, 14, 14, 14, 14, 12, + 10, 12, 12, 12, 12, 12, 13, 11, 12, 13, 12, 11, 11, 11, 11, 8, + 8, 10, 10, 10, 10, 10, 11, 9, 10, 11, 10, 9, 10, 9, 9, 5, + }, + }, + { + { + 12, 12, 11, 9, 11, 10, 11, 9, 11, 11, 10, 9, 9, 8, 9, 5, + 14, 13, 14, 11, 14, 11, 13, 10, 14, 13, 12, 10, 12, 10, 11, 6, + 16, 13, 16, 12, 16, 12, 16, 11, 16, 14, 16, 12, 15, 12, 13, 8, + 14, 14, 12, 11, 14, 12, 13, 10, 13, 13, 11, 10, 12, 11, 10, 6, + 16, 15, 14, 11, 16, 13, 14, 10, 15, 14, 13, 10, 13, 11, 11, 7, + 16, 16, 16, 11, 16, 14, 16, 11, 16, 16, 15, 12, 15, 13, 13, 8, + 16, 16, 13, 12, 16, 16, 15, 12, 16, 16, 12, 11, 15, 13, 12, 8, + 16, 16, 14, 11, 16, 16, 16, 11, 16, 16, 14, 11, 15, 14, 13, 8, + 16, 16, 15, 10, 16, 16, 16, 10, 16, 16, 15, 11, 16, 14, 14, 8, + 14, 14, 14, 12, 13, 11, 13, 10, 13, 13, 12, 11, 11, 10, 10, 6, + 16, 15, 16, 13, 13, 11, 14, 11, 15, 14, 13, 11, 12, 10, 11, 7, + 16, 15, 16, 14, 16, 11, 16, 11, 16, 16, 16, 13, 16, 12, 13, 8, + 16, 16, 14, 13, 15, 13, 14, 11, 14, 15, 13, 11, 13, 11, 11, 7, + 16, 16, 15, 13, 15, 13, 14, 11, 16, 15, 14, 11, 13, 11, 11, 7, + 16, 16, 16, 13, 16, 13, 16, 11, 16, 16, 16, 12, 16, 12, 13, 8, + 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 14, 13, 15, 14, 13, 9, + 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 14, 12, 15, 13, 13, 8, + 16, 16, 16, 12, 16, 16, 16, 11, 16, 16, 15, 12, 16, 13, 13, 7, + 16, 16, 16, 16, 13, 12, 16, 12, 16, 16, 14, 13, 12, 11, 12, 8, + 16, 16, 16, 15, 14, 11, 16, 11, 16, 16, 16, 13, 14, 11, 13, 8, + 16, 16, 16, 16, 15, 10, 16, 11, 16, 16, 16, 14, 15, 11, 13, 8, + 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 14, 14, 14, 12, 13, 9, + 16, 16, 16, 15, 16, 13, 16, 12, 16, 16, 16, 13, 14, 12, 13, 8, + 16, 16, 16, 14, 16, 12, 16, 11, 16, 16, 16, 13, 15, 12, 13, 7, + 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 15, 16, 14, 13, 9, + 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 14, 16, 13, 13, 8, + 16, 16, 16, 14, 16, 14, 16, 10, 16, 16, 16, 13, 16, 13, 13, 7, + 14, 14, 13, 12, 13, 12, 13, 11, 12, 13, 11, 10, 11, 10, 10, 6, + 16, 16, 15, 13, 16, 13, 15, 11, 14, 14, 13, 11, 13, 11, 11, 7, + 16, 16, 16, 14, 16, 14, 16, 12, 16, 16, 16, 13, 16, 13, 14, 9, + 16, 16, 13, 13, 15, 14, 14, 11, 13, 14, 11, 11, 12, 11, 11, 7, + 16, 16, 15, 12, 16, 14, 15, 11, 14, 14, 12, 11, 13, 11, 11, 7, + 16, 16, 16, 13, 16, 14, 16, 12, 16, 16, 14, 12, 16, 13, 13, 8, + 16, 16, 14, 14, 16, 16, 16, 13, 16, 16, 12, 11, 15, 13, 12, 8, + 16, 16, 15, 13, 16, 16, 16, 12, 16, 16, 13, 11, 16, 13, 12, 8, + 16, 16, 16, 11, 16, 16, 16, 11, 16, 16, 14, 11, 16, 14, 13, 7, + 16, 16, 15, 13, 14, 13, 14, 11, 14, 14, 12, 11, 11, 10, 11, 7, + 16, 16, 16, 13, 14, 12, 15, 11, 15, 14, 13, 11, 12, 11, 11, 7, + 16, 16, 16, 14, 16, 13, 16, 12, 16, 16, 16, 13, 14, 12, 13, 8, + 16, 16, 15, 13, 15, 14, 14, 12, 14, 14, 12, 11, 12, 11, 11, 7, + 16, 16, 14, 12, 15, 13, 14, 11, 15, 14, 13, 11, 12, 11, 11, 6, + 16, 16, 16, 13, 16, 13, 16, 11, 16, 15, 14, 11, 14, 11, 12, 6, + 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 13, 12, 14, 13, 12, 8, + 16, 16, 15, 13, 16, 14, 15, 11, 16, 16, 13, 11, 14, 12, 11, 6, + 16, 16, 16, 12, 16, 14, 15, 11, 16, 16, 13, 10, 14, 12, 12, 6, + 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 14, 13, 12, 11, 12, 8, + 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 15, 13, 13, 11, 12, 8, + 16, 16, 16, 15, 16, 12, 16, 12, 16, 16, 16, 14, 14, 11, 13, 7, + 16, 16, 16, 16, 16, 15, 16, 13, 16, 16, 14, 13, 13, 12, 12, 8, + 16, 16, 16, 14, 15, 13, 15, 11, 16, 15, 14, 12, 13, 11, 11, 6, + 16, 16, 16, 14, 16, 12, 15, 11, 16, 16, 15, 12, 14, 11, 12, 6, + 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 15, 13, 14, 13, 12, 8, + 16, 16, 16, 14, 16, 14, 16, 12, 16, 16, 14, 12, 13, 12, 11, 6, + 16, 16, 16, 13, 16, 13, 15, 10, 16, 16, 14, 11, 14, 11, 11, 5, + 16, 16, 15, 14, 16, 16, 16, 13, 14, 14, 12, 12, 12, 12, 12, 8, + 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 14, 13, 14, 13, 13, 9, + 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 16, 13, 15, 9, + 16, 16, 14, 15, 16, 16, 16, 14, 14, 16, 12, 12, 13, 13, 12, 8, + 16, 16, 16, 14, 16, 16, 16, 13, 16, 15, 13, 12, 14, 12, 12, 8, + 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 14, 12, 16, 13, 13, 8, + 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 11, 11, 15, 14, 12, 8, + 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 12, 11, 15, 13, 12, 8, + 16, 16, 16, 13, 16, 16, 16, 12, 16, 16, 13, 10, 16, 13, 12, 7, + 16, 16, 16, 16, 16, 15, 16, 13, 14, 16, 13, 13, 12, 12, 12, 8, + 16, 16, 16, 15, 16, 14, 16, 13, 16, 16, 14, 13, 13, 12, 12, 8, + 16, 16, 16, 16, 16, 15, 16, 13, 16, 16, 16, 13, 15, 12, 14, 8, + 16, 16, 16, 15, 16, 16, 16, 13, 14, 16, 13, 12, 12, 12, 11, 8, + 16, 16, 16, 14, 16, 14, 16, 12, 14, 14, 13, 11, 13, 11, 11, 6, + 16, 16, 16, 14, 16, 14, 16, 12, 16, 15, 14, 11, 14, 11, 12, 6, + 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 12, 12, 14, 13, 11, 8, + 16, 16, 15, 14, 16, 16, 16, 12, 16, 15, 12, 11, 13, 12, 11, 6, + 16, 16, 16, 13, 16, 14, 16, 11, 16, 14, 13, 10, 14, 11, 11, 5, + 16, 16, 16, 16, 16, 16, 16, 14, 14, 16, 15, 13, 11, 11, 11, 8, + 16, 16, 16, 16, 16, 15, 16, 13, 16, 16, 16, 13, 12, 11, 12, 7, + 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 13, 13, 11, 13, 7, + 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 14, 13, 12, 12, 11, 7, + 16, 16, 16, 15, 16, 14, 15, 12, 16, 14, 13, 12, 12, 11, 11, 6, + 16, 16, 16, 14, 16, 13, 15, 11, 16, 14, 14, 11, 13, 10, 11, 5, + 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 13, 12, 12, 12, 11, 7, + 16, 16, 16, 14, 16, 14, 15, 12, 16, 15, 12, 11, 12, 11, 10, 5, + 16, 16, 16, 13, 16, 13, 14, 10, 16, 14, 12, 9, 12, 10, 9, 3, + }, + { + 2, 6, 6, 7, 6, 7, 8, 7, 7, 8, 7, 8, 7, 8, 8, 5, + 5, 8, 9, 9, 9, 9, 12, 10, 10, 11, 10, 10, 10, 11, 11, 8, + 9, 10, 13, 12, 13, 12, 15, 13, 13, 14, 13, 14, 13, 13, 14, 11, + 5, 10, 9, 10, 10, 10, 12, 10, 10, 12, 10, 11, 11, 11, 11, 8, + 6, 9, 10, 9, 10, 11, 12, 10, 10, 12, 11, 11, 10, 11, 11, 8, + 9, 11, 12, 11, 12, 13, 14, 12, 13, 14, 14, 12, 13, 13, 13, 11, + 10, 13, 11, 12, 14, 14, 15, 13, 13, 15, 12, 13, 14, 14, 14, 12, + 9, 12, 12, 12, 13, 13, 15, 13, 13, 14, 13, 13, 14, 13, 15, 11, + 8, 11, 12, 10, 12, 13, 14, 12, 13, 14, 14, 13, 13, 13, 14, 11, + 5, 9, 10, 10, 9, 10, 12, 11, 10, 12, 11, 11, 9, 11, 11, 9, + 6, 10, 10, 11, 10, 10, 12, 11, 11, 12, 11, 11, 11, 11, 11, 9, + 9, 11, 13, 13, 12, 11, 14, 12, 13, 15, 13, 13, 14, 13, 14, 11, + 8, 11, 11, 12, 11, 12, 13, 12, 12, 13, 12, 13, 12, 12, 12, 10, + 7, 10, 10, 11, 10, 11, 12, 11, 11, 12, 11, 11, 11, 11, 12, 9, + 9, 12, 12, 12, 12, 12, 14, 12, 13, 14, 13, 13, 13, 13, 13, 11, + 11, 14, 13, 15, 15, 16, 16, 15, 15, 16, 15, 15, 16, 16, 15, 13, + 10, 12, 13, 13, 13, 14, 15, 13, 13, 14, 13, 13, 14, 14, 14, 11, + 9, 12, 12, 12, 13, 13, 14, 12, 13, 14, 14, 13, 13, 13, 14, 11, + 9, 13, 13, 13, 11, 12, 15, 13, 13, 15, 14, 14, 11, 13, 14, 11, + 10, 13, 13, 13, 12, 12, 15, 13, 13, 15, 14, 14, 13, 13, 14, 11, + 10, 12, 13, 13, 12, 11, 14, 12, 13, 15, 13, 13, 13, 13, 14, 11, + 11, 14, 15, 15, 13, 14, 16, 14, 14, 16, 16, 14, 14, 15, 15, 13, + 10, 13, 13, 13, 12, 13, 14, 13, 13, 14, 14, 14, 13, 13, 14, 11, + 10, 12, 13, 13, 13, 12, 14, 13, 13, 14, 14, 13, 13, 13, 13, 11, + 13, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, + 12, 15, 15, 15, 14, 15, 16, 14, 15, 16, 16, 15, 16, 15, 15, 13, + 10, 12, 12, 12, 13, 13, 14, 12, 13, 14, 13, 13, 13, 13, 13, 11, + 6, 10, 10, 11, 10, 11, 12, 11, 10, 12, 11, 11, 10, 11, 11, 9, + 8, 11, 12, 12, 12, 12, 13, 12, 12, 13, 12, 13, 12, 13, 13, 10, + 11, 13, 15, 14, 15, 14, 16, 14, 15, 16, 16, 14, 15, 15, 15, 13, + 7, 11, 10, 12, 11, 11, 13, 11, 11, 13, 10, 11, 12, 12, 12, 10, + 7, 11, 11, 11, 11, 11, 13, 11, 11, 13, 11, 12, 12, 12, 12, 9, + 10, 12, 13, 13, 13, 13, 15, 13, 14, 15, 14, 14, 14, 14, 15, 11, + 10, 13, 12, 14, 14, 14, 15, 13, 13, 15, 12, 13, 15, 15, 14, 12, + 10, 13, 12, 12, 13, 13, 15, 14, 13, 15, 13, 13, 14, 14, 14, 11, + 10, 13, 13, 12, 13, 14, 15, 13, 13, 15, 13, 13, 14, 14, 14, 11, + 7, 10, 11, 11, 10, 11, 12, 11, 10, 12, 12, 12, 9, 11, 12, 9, + 7, 11, 11, 11, 11, 11, 13, 11, 11, 13, 12, 12, 11, 12, 12, 9, + 10, 12, 14, 13, 13, 13, 16, 13, 14, 16, 14, 14, 13, 13, 14, 11, + 8, 11, 11, 12, 11, 12, 13, 12, 12, 13, 12, 12, 12, 12, 12, 10, + 6, 9, 9, 10, 9, 10, 11, 10, 10, 11, 10, 10, 10, 10, 10, 8, + 8, 11, 11, 11, 12, 11, 13, 11, 12, 13, 12, 12, 12, 12, 12, 10, + 11, 14, 13, 14, 14, 14, 16, 14, 14, 16, 14, 14, 15, 15, 14, 12, + 9, 12, 11, 12, 12, 12, 13, 12, 12, 13, 12, 12, 12, 12, 12, 10, + 8, 11, 11, 11, 11, 11, 13, 11, 12, 12, 12, 12, 12, 12, 12, 9, + 10, 13, 14, 13, 11, 13, 14, 14, 13, 15, 15, 14, 10, 13, 14, 11, + 10, 13, 13, 13, 12, 13, 14, 13, 13, 14, 14, 14, 13, 13, 13, 11, + 10, 13, 14, 13, 13, 12, 15, 13, 14, 15, 14, 14, 14, 13, 14, 12, + 11, 14, 14, 14, 13, 13, 15, 14, 14, 15, 14, 15, 13, 14, 14, 12, + 9, 11, 12, 12, 11, 11, 13, 12, 12, 13, 12, 12, 12, 12, 12, 10, + 9, 11, 12, 12, 12, 11, 13, 11, 12, 13, 12, 12, 12, 12, 12, 10, + 13, 15, 15, 16, 15, 16, 16, 15, 16, 16, 16, 15, 15, 15, 16, 14, + 10, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 13, 13, 13, 13, 11, + 8, 11, 11, 11, 11, 11, 12, 11, 11, 12, 12, 11, 12, 11, 12, 9, + 11, 14, 14, 15, 14, 15, 15, 14, 13, 15, 14, 15, 12, 14, 15, 13, + 12, 15, 15, 15, 15, 15, 16, 15, 15, 16, 16, 16, 15, 16, 15, 13, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, + 11, 14, 13, 15, 14, 14, 16, 14, 14, 16, 13, 14, 15, 14, 15, 12, + 11, 14, 13, 14, 14, 14, 16, 15, 14, 16, 14, 14, 15, 15, 15, 12, + 13, 15, 15, 15, 15, 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 13, + 11, 14, 13, 14, 14, 14, 15, 14, 14, 16, 12, 14, 16, 16, 14, 12, + 11, 14, 14, 14, 14, 15, 16, 15, 14, 16, 13, 14, 16, 15, 14, 12, + 12, 14, 14, 14, 14, 14, 16, 14, 15, 16, 14, 14, 14, 15, 15, 12, + 11, 14, 14, 14, 13, 14, 16, 15, 13, 16, 15, 15, 11, 14, 14, 12, + 11, 14, 14, 15, 14, 14, 16, 14, 14, 15, 14, 14, 13, 15, 15, 12, + 13, 15, 16, 15, 15, 15, 16, 15, 16, 16, 16, 16, 15, 15, 16, 13, + 11, 14, 14, 14, 14, 14, 15, 14, 14, 16, 14, 14, 14, 15, 14, 12, + 9, 12, 12, 12, 12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 12, 10, + 11, 13, 13, 13, 13, 13, 14, 13, 13, 14, 13, 14, 13, 13, 14, 11, + 12, 15, 14, 15, 15, 15, 16, 15, 14, 16, 14, 14, 16, 16, 14, 13, + 10, 12, 12, 12, 12, 12, 14, 12, 13, 13, 12, 12, 13, 13, 13, 10, + 10, 12, 12, 12, 12, 12, 14, 12, 12, 13, 12, 12, 12, 12, 12, 10, + 10, 14, 14, 14, 12, 14, 16, 14, 13, 16, 16, 16, 10, 13, 14, 12, + 11, 14, 14, 14, 13, 14, 16, 14, 14, 16, 15, 14, 12, 13, 14, 12, + 12, 14, 14, 14, 14, 14, 16, 14, 14, 16, 15, 15, 14, 14, 15, 12, + 12, 14, 15, 15, 14, 15, 16, 14, 15, 15, 15, 15, 13, 15, 14, 12, + 9, 12, 12, 12, 12, 13, 13, 12, 12, 13, 13, 12, 11, 12, 12, 10, + 10, 12, 12, 12, 12, 12, 13, 12, 12, 13, 12, 12, 12, 12, 12, 10, + 13, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 15, 16, 15, 13, + 10, 12, 12, 13, 12, 13, 13, 12, 13, 14, 13, 13, 12, 13, 13, 10, + 7, 10, 10, 10, 10, 10, 11, 10, 10, 11, 10, 10, 10, 10, 10, 7, + }, + }, + { + { + 10, 10, 9, 8, 9, 8, 9, 7, 9, 9, 8, 7, 8, 7, 7, 4, + 13, 11, 12, 9, 12, 9, 12, 9, 12, 11, 11, 9, 10, 9, 9, 6, + 15, 12, 15, 11, 14, 10, 14, 10, 14, 13, 13, 11, 13, 11, 12, 7, + 13, 12, 11, 9, 12, 11, 12, 9, 12, 12, 10, 9, 10, 10, 9, 6, + 14, 13, 12, 10, 13, 12, 13, 9, 13, 12, 11, 10, 12, 11, 10, 6, + 16, 14, 14, 10, 15, 13, 14, 10, 15, 15, 14, 11, 14, 12, 12, 8, + 15, 14, 12, 11, 15, 14, 13, 11, 14, 14, 11, 10, 13, 12, 11, 8, + 15, 16, 13, 11, 16, 14, 14, 11, 15, 15, 12, 10, 14, 13, 12, 8, + 16, 15, 14, 10, 16, 14, 14, 10, 16, 15, 14, 10, 14, 13, 12, 7, + 13, 12, 12, 11, 11, 9, 12, 9, 12, 12, 11, 10, 10, 9, 9, 6, + 13, 13, 14, 12, 12, 10, 12, 10, 14, 13, 12, 11, 11, 10, 10, 7, + 16, 14, 16, 13, 14, 11, 15, 10, 16, 15, 14, 12, 14, 11, 12, 8, + 14, 14, 13, 12, 13, 12, 13, 10, 13, 13, 12, 11, 11, 10, 10, 7, + 15, 14, 14, 12, 14, 12, 13, 10, 14, 13, 12, 11, 12, 11, 11, 7, + 16, 15, 16, 13, 15, 13, 15, 10, 16, 15, 14, 12, 14, 12, 12, 7, + 15, 16, 14, 13, 16, 14, 14, 12, 15, 15, 12, 12, 13, 12, 12, 8, + 16, 16, 14, 13, 16, 14, 14, 11, 15, 15, 14, 11, 14, 12, 12, 8, + 16, 16, 15, 12, 16, 14, 15, 10, 16, 16, 13, 12, 14, 13, 12, 7, + 14, 14, 14, 13, 13, 11, 13, 11, 14, 14, 13, 12, 11, 10, 11, 8, + 16, 15, 16, 13, 13, 11, 14, 11, 15, 14, 14, 13, 12, 11, 12, 8, + 15, 15, 16, 14, 14, 10, 14, 10, 16, 15, 15, 13, 14, 10, 12, 8, + 16, 16, 16, 14, 15, 13, 14, 12, 15, 15, 13, 13, 13, 12, 12, 8, + 16, 16, 16, 14, 15, 13, 14, 11, 16, 16, 14, 13, 13, 12, 12, 8, + 16, 16, 16, 14, 16, 12, 15, 11, 16, 15, 15, 13, 14, 12, 12, 8, + 16, 16, 16, 16, 16, 15, 15, 13, 16, 16, 14, 13, 14, 13, 12, 9, + 16, 16, 16, 14, 16, 15, 15, 11, 16, 16, 14, 13, 15, 13, 12, 8, + 16, 16, 16, 14, 16, 14, 14, 10, 16, 16, 15, 13, 14, 12, 12, 7, + 12, 12, 12, 11, 12, 11, 12, 10, 11, 11, 10, 9, 9, 9, 9, 6, + 14, 13, 14, 12, 13, 12, 13, 10, 13, 13, 12, 10, 12, 10, 11, 7, + 16, 14, 16, 13, 15, 13, 16, 12, 15, 14, 14, 12, 14, 12, 13, 8, + 14, 14, 13, 11, 14, 12, 13, 11, 12, 12, 10, 10, 11, 10, 10, 7, + 14, 14, 13, 12, 14, 12, 13, 11, 13, 13, 12, 10, 12, 11, 10, 7, + 16, 15, 15, 12, 16, 14, 15, 11, 16, 14, 13, 11, 14, 12, 12, 8, + 16, 16, 13, 13, 16, 15, 14, 12, 14, 14, 11, 11, 13, 12, 11, 8, + 16, 16, 14, 12, 16, 14, 14, 12, 15, 14, 12, 11, 14, 12, 12, 8, + 16, 15, 14, 11, 16, 15, 15, 11, 16, 15, 13, 11, 14, 13, 12, 8, + 14, 13, 13, 12, 13, 11, 13, 10, 12, 13, 11, 10, 10, 10, 10, 7, + 15, 14, 14, 13, 13, 12, 13, 11, 14, 13, 12, 11, 12, 10, 11, 7, + 16, 15, 16, 14, 15, 12, 15, 11, 16, 14, 14, 12, 14, 11, 12, 8, + 14, 15, 13, 12, 14, 13, 13, 11, 13, 13, 11, 11, 11, 10, 10, 7, + 14, 14, 14, 12, 14, 13, 13, 10, 14, 13, 12, 10, 12, 10, 10, 6, + 16, 15, 15, 13, 16, 13, 15, 11, 15, 14, 13, 11, 13, 11, 11, 7, + 16, 16, 14, 13, 16, 15, 14, 12, 15, 15, 12, 11, 13, 12, 11, 8, + 16, 16, 14, 13, 16, 14, 14, 11, 15, 14, 12, 11, 13, 12, 11, 7, + 16, 16, 15, 12, 16, 14, 14, 11, 15, 15, 13, 11, 14, 12, 11, 6, + 16, 15, 15, 14, 14, 12, 14, 12, 13, 14, 13, 12, 11, 11, 11, 8, + 16, 16, 16, 14, 14, 12, 15, 12, 15, 14, 14, 12, 12, 11, 12, 8, + 16, 16, 16, 15, 14, 12, 15, 12, 16, 15, 14, 13, 13, 11, 12, 8, + 16, 16, 16, 15, 15, 14, 15, 12, 14, 14, 13, 12, 12, 11, 11, 8, + 16, 16, 15, 14, 14, 12, 14, 11, 14, 14, 13, 12, 12, 11, 11, 7, + 16, 16, 16, 14, 15, 12, 14, 11, 15, 15, 14, 12, 13, 11, 12, 7, + 16, 16, 16, 16, 16, 15, 16, 13, 15, 15, 14, 12, 13, 12, 11, 8, + 16, 16, 16, 14, 15, 14, 14, 12, 16, 15, 13, 12, 13, 12, 11, 7, + 16, 16, 16, 13, 16, 13, 14, 10, 16, 15, 14, 11, 13, 11, 11, 6, + 14, 15, 13, 13, 14, 13, 14, 12, 12, 13, 11, 11, 11, 11, 10, 8, + 16, 16, 15, 13, 16, 14, 16, 13, 14, 14, 13, 12, 13, 12, 12, 8, + 16, 16, 16, 14, 16, 14, 16, 13, 16, 14, 15, 13, 15, 13, 13, 9, + 15, 15, 14, 14, 15, 14, 14, 12, 13, 14, 11, 11, 12, 12, 11, 8, + 15, 16, 15, 13, 15, 14, 14, 12, 14, 14, 12, 11, 13, 12, 12, 8, + 16, 16, 16, 13, 16, 15, 15, 13, 16, 15, 14, 11, 15, 12, 13, 8, + 16, 16, 14, 13, 16, 15, 15, 13, 14, 14, 10, 11, 14, 12, 11, 8, + 16, 16, 15, 13, 16, 16, 15, 13, 15, 14, 12, 11, 14, 13, 12, 8, + 16, 16, 15, 13, 16, 15, 16, 12, 16, 14, 13, 10, 15, 13, 12, 7, + 15, 15, 15, 14, 14, 14, 15, 12, 13, 14, 12, 12, 11, 11, 11, 8, + 16, 15, 16, 14, 15, 13, 15, 12, 14, 14, 13, 12, 12, 11, 12, 8, + 16, 16, 16, 15, 16, 14, 16, 13, 16, 15, 14, 12, 14, 11, 13, 8, + 16, 16, 15, 14, 16, 14, 15, 13, 14, 14, 12, 11, 12, 11, 11, 8, + 15, 16, 15, 14, 15, 14, 14, 12, 14, 13, 12, 11, 12, 11, 11, 7, + 16, 16, 16, 14, 16, 13, 16, 12, 15, 14, 13, 11, 13, 11, 12, 7, + 16, 16, 15, 14, 16, 15, 15, 13, 14, 15, 11, 11, 13, 12, 11, 8, + 16, 16, 15, 13, 16, 14, 15, 12, 15, 14, 12, 11, 13, 11, 11, 7, + 16, 16, 15, 13, 16, 14, 16, 12, 15, 14, 13, 10, 13, 11, 11, 6, + 16, 16, 16, 14, 14, 14, 15, 13, 14, 14, 14, 12, 11, 11, 11, 8, + 16, 16, 16, 14, 15, 14, 16, 13, 15, 14, 14, 13, 12, 11, 11, 7, + 16, 16, 16, 16, 15, 13, 16, 12, 15, 15, 14, 12, 13, 10, 12, 7, + 16, 16, 16, 14, 15, 15, 14, 13, 14, 14, 13, 12, 12, 11, 11, 8, + 16, 15, 16, 14, 16, 13, 15, 12, 14, 14, 13, 12, 12, 10, 10, 6, + 16, 15, 16, 14, 16, 13, 16, 11, 16, 14, 13, 11, 13, 10, 11, 6, + 16, 16, 16, 15, 16, 16, 15, 13, 14, 16, 12, 12, 12, 12, 10, 7, + 16, 16, 16, 14, 16, 14, 14, 12, 15, 15, 12, 11, 12, 11, 10, 6, + 16, 16, 16, 13, 16, 13, 15, 10, 15, 14, 13, 10, 13, 10, 10, 4, + }, + { + 1, 6, 6, 7, 6, 7, 9, 8, 7, 9, 7, 8, 7, 8, 8, 6, + 6, 9, 10, 10, 10, 10, 12, 11, 10, 12, 11, 11, 11, 11, 12, 9, + 9, 10, 13, 11, 13, 12, 14, 13, 14, 14, 14, 14, 14, 14, 14, 12, + 6, 10, 9, 10, 10, 11, 13, 11, 11, 13, 10, 12, 11, 12, 12, 9, + 6, 10, 10, 10, 10, 11, 13, 11, 11, 13, 12, 12, 11, 12, 12, 9, + 9, 11, 13, 12, 13, 14, 15, 13, 14, 16, 14, 14, 14, 14, 15, 12, + 10, 13, 11, 13, 14, 14, 16, 14, 14, 15, 13, 14, 15, 15, 16, 12, + 9, 13, 12, 12, 14, 14, 16, 14, 14, 15, 14, 14, 15, 15, 15, 12, + 8, 11, 12, 11, 13, 14, 15, 13, 13, 15, 14, 14, 13, 15, 15, 11, + 6, 10, 10, 11, 9, 10, 13, 11, 10, 13, 11, 12, 10, 12, 12, 9, + 6, 10, 10, 11, 11, 10, 13, 11, 11, 13, 11, 12, 12, 12, 13, 10, + 9, 12, 13, 13, 13, 12, 16, 13, 14, 15, 14, 14, 15, 14, 15, 12, + 8, 12, 12, 13, 12, 13, 15, 14, 13, 15, 13, 14, 13, 13, 14, 11, + 7, 11, 11, 12, 11, 12, 13, 12, 12, 13, 12, 13, 12, 13, 13, 10, + 9, 12, 13, 13, 13, 13, 16, 13, 13, 15, 14, 14, 14, 15, 15, 12, + 11, 15, 14, 15, 15, 16, 16, 16, 15, 16, 15, 16, 16, 16, 16, 14, + 10, 13, 13, 14, 14, 14, 16, 15, 14, 16, 15, 15, 15, 15, 16, 13, + 9, 12, 13, 13, 13, 14, 16, 14, 13, 15, 14, 14, 14, 16, 15, 12, + 10, 13, 14, 14, 11, 13, 16, 14, 14, 16, 15, 15, 12, 14, 15, 12, + 10, 13, 14, 14, 12, 12, 16, 15, 14, 16, 15, 15, 14, 14, 16, 12, + 9, 12, 13, 14, 13, 11, 16, 13, 14, 15, 13, 14, 14, 14, 15, 12, + 11, 15, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 13, 14, 14, 13, 14, 16, 15, 14, 16, 16, 16, 14, 15, 16, 13, + 10, 13, 13, 14, 13, 13, 16, 13, 13, 14, 14, 15, 15, 14, 15, 13, + 13, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, + 12, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 12, 13, 14, 13, 13, 14, 13, 13, 14, 13, 14, 14, 14, 15, 12, + 6, 10, 11, 11, 10, 11, 13, 12, 11, 13, 11, 12, 11, 12, 12, 10, + 8, 12, 13, 13, 12, 13, 14, 14, 13, 15, 14, 14, 14, 14, 15, 12, + 12, 14, 16, 15, 15, 15, 16, 15, 16, 16, 16, 16, 16, 16, 16, 14, + 7, 11, 11, 12, 12, 12, 14, 13, 12, 14, 11, 12, 13, 13, 13, 11, + 8, 11, 12, 12, 12, 12, 14, 13, 12, 14, 12, 13, 13, 14, 14, 11, + 11, 13, 14, 14, 14, 14, 16, 15, 15, 16, 15, 15, 16, 16, 16, 13, + 10, 14, 12, 14, 14, 15, 16, 15, 13, 16, 12, 14, 16, 16, 15, 13, + 10, 13, 13, 14, 14, 15, 16, 15, 14, 16, 14, 15, 15, 16, 16, 12, + 10, 13, 14, 13, 14, 14, 16, 15, 14, 16, 15, 15, 14, 16, 16, 13, + 7, 11, 11, 11, 10, 12, 14, 13, 11, 14, 13, 13, 10, 12, 13, 10, + 8, 11, 12, 12, 11, 12, 14, 13, 12, 15, 13, 13, 12, 13, 14, 11, + 11, 13, 14, 14, 14, 14, 16, 15, 14, 16, 15, 16, 16, 16, 16, 14, + 8, 12, 12, 13, 12, 13, 15, 14, 12, 15, 13, 13, 13, 14, 14, 11, + 6, 10, 10, 11, 10, 11, 13, 12, 11, 13, 11, 12, 11, 12, 12, 9, + 9, 12, 13, 13, 13, 13, 14, 13, 13, 15, 14, 14, 14, 14, 14, 12, + 11, 15, 14, 15, 14, 15, 16, 16, 16, 16, 15, 16, 16, 16, 16, 14, + 9, 13, 12, 13, 13, 13, 15, 14, 13, 14, 13, 14, 14, 15, 14, 12, + 9, 12, 12, 12, 12, 13, 14, 13, 13, 14, 13, 13, 13, 13, 14, 11, + 10, 13, 15, 14, 12, 14, 16, 14, 14, 16, 15, 15, 12, 14, 16, 12, + 10, 14, 14, 14, 13, 14, 16, 15, 14, 16, 16, 16, 13, 14, 16, 13, + 11, 13, 14, 14, 14, 13, 16, 14, 14, 16, 15, 15, 15, 15, 16, 13, + 11, 15, 15, 15, 14, 15, 16, 16, 15, 16, 16, 16, 14, 16, 16, 13, + 9, 13, 13, 13, 12, 13, 15, 14, 13, 15, 14, 14, 13, 14, 15, 11, + 9, 12, 12, 13, 12, 12, 14, 13, 13, 14, 13, 14, 14, 14, 14, 11, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, + 11, 14, 14, 15, 15, 14, 16, 16, 14, 16, 14, 15, 15, 16, 16, 12, + 9, 12, 12, 13, 12, 12, 14, 12, 12, 14, 13, 13, 13, 13, 14, 11, + 11, 14, 14, 16, 14, 16, 16, 16, 13, 16, 14, 16, 14, 16, 16, 13, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 15, 14, 16, 14, 15, 16, 16, 15, 16, 14, 15, 16, 16, 16, 13, + 11, 15, 14, 16, 15, 16, 16, 16, 15, 16, 15, 16, 16, 16, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 11, 14, 13, 14, 15, 14, 16, 15, 14, 16, 12, 14, 16, 16, 15, 13, + 11, 14, 14, 16, 14, 15, 16, 16, 15, 16, 14, 15, 16, 16, 16, 14, + 12, 14, 14, 15, 14, 16, 16, 15, 14, 16, 15, 15, 15, 16, 16, 13, + 11, 14, 15, 15, 13, 15, 16, 16, 14, 16, 16, 16, 12, 15, 15, 13, + 11, 15, 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, + 11, 15, 14, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, + 10, 13, 13, 14, 14, 14, 16, 15, 14, 16, 14, 15, 14, 14, 15, 12, + 12, 15, 14, 16, 14, 15, 16, 15, 15, 16, 15, 15, 16, 15, 16, 13, + 12, 16, 14, 16, 15, 16, 16, 16, 16, 16, 14, 15, 16, 16, 16, 14, + 10, 13, 13, 14, 14, 13, 16, 14, 13, 16, 13, 14, 15, 15, 15, 12, + 10, 13, 13, 14, 13, 13, 16, 14, 14, 15, 14, 14, 14, 14, 15, 12, + 10, 14, 15, 14, 13, 15, 16, 15, 14, 16, 16, 16, 11, 14, 16, 12, + 11, 14, 14, 16, 14, 15, 16, 15, 15, 16, 16, 16, 13, 15, 16, 13, + 12, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 15, 16, 13, + 12, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 13, + 10, 13, 14, 14, 13, 14, 16, 14, 13, 16, 15, 14, 12, 14, 16, 11, + 10, 13, 13, 14, 13, 14, 16, 14, 14, 15, 14, 14, 13, 14, 14, 11, + 13, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 11, 13, 14, 15, 14, 14, 16, 15, 14, 16, 14, 15, 14, 15, 16, 12, + 8, 11, 11, 11, 11, 12, 13, 12, 11, 13, 11, 12, 11, 12, 12, 9, + }, + }, + { + { + 8, 8, 8, 7, 8, 7, 8, 6, 8, 8, 7, 6, 7, 6, 6, 4, + 11, 10, 11, 9, 11, 9, 11, 8, 11, 10, 10, 9, 10, 8, 9, 6, + 13, 11, 13, 10, 12, 10, 13, 9, 13, 12, 13, 10, 12, 10, 11, 7, + 11, 11, 10, 9, 11, 10, 11, 9, 10, 11, 9, 8, 10, 9, 9, 6, + 12, 12, 11, 9, 12, 11, 12, 9, 12, 12, 11, 9, 11, 10, 10, 7, + 14, 13, 13, 10, 15, 12, 13, 10, 15, 13, 13, 10, 13, 12, 12, 8, + 13, 13, 11, 10, 14, 13, 12, 10, 13, 13, 10, 10, 12, 11, 10, 8, + 15, 14, 13, 10, 14, 13, 13, 10, 14, 13, 12, 10, 13, 12, 11, 8, + 14, 14, 13, 10, 16, 13, 13, 10, 15, 14, 13, 10, 13, 12, 12, 8, + 11, 11, 11, 10, 10, 9, 10, 9, 10, 10, 10, 9, 9, 8, 9, 6, + 12, 12, 12, 11, 11, 9, 12, 9, 12, 12, 11, 10, 11, 9, 10, 7, + 14, 13, 14, 12, 13, 10, 13, 10, 15, 13, 14, 12, 12, 10, 12, 8, + 13, 13, 12, 11, 12, 11, 12, 10, 12, 12, 11, 10, 11, 10, 10, 7, + 14, 13, 13, 11, 13, 12, 12, 10, 13, 13, 12, 11, 12, 10, 10, 7, + 16, 15, 15, 12, 14, 12, 13, 10, 15, 14, 13, 12, 13, 12, 12, 8, + 15, 15, 13, 13, 14, 14, 14, 12, 14, 14, 12, 11, 13, 12, 11, 8, + 15, 16, 14, 12, 15, 14, 13, 11, 15, 15, 13, 12, 13, 12, 11, 8, + 16, 15, 15, 12, 16, 14, 14, 10, 15, 15, 14, 12, 14, 12, 12, 8, + 13, 13, 13, 13, 11, 10, 12, 10, 12, 13, 12, 11, 10, 10, 10, 8, + 14, 13, 14, 13, 12, 10, 13, 10, 14, 14, 13, 12, 12, 10, 11, 8, + 15, 14, 16, 14, 13, 10, 14, 10, 16, 14, 14, 13, 13, 10, 12, 8, + 15, 15, 14, 14, 14, 13, 13, 12, 14, 14, 13, 12, 12, 11, 11, 9, + 15, 15, 15, 14, 14, 12, 14, 11, 15, 14, 13, 13, 13, 11, 11, 8, + 16, 15, 16, 14, 15, 12, 14, 11, 16, 16, 15, 13, 14, 12, 12, 8, + 16, 16, 16, 14, 15, 14, 14, 12, 15, 15, 14, 13, 13, 12, 11, 9, + 16, 16, 15, 15, 16, 14, 14, 11, 16, 16, 14, 13, 14, 12, 12, 8, + 16, 16, 16, 13, 15, 13, 14, 10, 16, 16, 15, 13, 14, 12, 12, 8, + 11, 11, 11, 10, 11, 10, 11, 9, 10, 10, 9, 8, 9, 9, 9, 6, + 12, 12, 13, 11, 12, 11, 12, 10, 12, 12, 11, 10, 11, 10, 10, 7, + 15, 13, 15, 12, 14, 13, 14, 11, 14, 13, 13, 11, 13, 11, 12, 8, + 12, 13, 12, 11, 13, 11, 12, 10, 11, 12, 10, 9, 11, 10, 10, 7, + 14, 13, 13, 11, 14, 12, 13, 11, 12, 12, 11, 10, 12, 11, 10, 7, + 15, 14, 15, 12, 15, 13, 15, 11, 15, 14, 13, 11, 13, 12, 12, 8, + 14, 14, 13, 12, 15, 14, 13, 12, 13, 13, 11, 10, 13, 12, 11, 8, + 16, 15, 13, 12, 15, 14, 14, 12, 14, 14, 12, 11, 14, 12, 11, 8, + 16, 15, 14, 12, 16, 15, 15, 11, 15, 14, 13, 11, 14, 13, 12, 8, + 12, 12, 12, 11, 12, 11, 12, 10, 11, 11, 11, 10, 10, 9, 9, 7, + 13, 13, 14, 12, 13, 11, 13, 11, 13, 12, 12, 11, 11, 10, 10, 7, + 15, 14, 16, 13, 14, 12, 14, 11, 14, 14, 14, 12, 13, 11, 12, 8, + 13, 13, 13, 12, 13, 12, 13, 11, 12, 12, 11, 10, 11, 10, 10, 7, + 14, 14, 13, 12, 13, 12, 13, 10, 13, 13, 11, 10, 12, 10, 10, 7, + 16, 15, 15, 13, 15, 12, 14, 11, 15, 14, 13, 11, 13, 11, 11, 7, + 15, 16, 14, 13, 15, 14, 14, 12, 14, 14, 12, 11, 13, 12, 11, 8, + 16, 15, 14, 13, 15, 14, 14, 11, 14, 14, 12, 11, 13, 12, 11, 7, + 16, 15, 15, 12, 16, 14, 14, 11, 15, 14, 13, 11, 14, 12, 11, 7, + 14, 15, 14, 14, 13, 12, 13, 12, 13, 13, 12, 12, 11, 10, 11, 8, + 15, 15, 15, 14, 13, 12, 14, 12, 14, 14, 13, 12, 12, 11, 11, 8, + 16, 15, 16, 14, 14, 12, 15, 12, 16, 14, 14, 13, 13, 11, 12, 8, + 15, 15, 15, 14, 14, 13, 14, 12, 14, 14, 13, 12, 12, 11, 11, 8, + 15, 15, 15, 14, 14, 13, 14, 12, 14, 14, 13, 12, 12, 11, 11, 7, + 16, 15, 16, 14, 15, 12, 15, 11, 15, 14, 14, 12, 13, 11, 12, 7, + 16, 16, 16, 15, 16, 15, 14, 13, 15, 15, 13, 12, 13, 12, 11, 9, + 16, 16, 16, 14, 15, 14, 14, 12, 15, 15, 13, 12, 14, 12, 11, 8, + 16, 16, 16, 14, 16, 14, 14, 11, 15, 15, 14, 12, 14, 12, 11, 7, + 13, 13, 13, 12, 13, 12, 13, 11, 11, 12, 11, 10, 10, 10, 10, 8, + 15, 14, 14, 13, 14, 13, 14, 12, 13, 13, 12, 11, 13, 11, 11, 8, + 16, 15, 16, 14, 16, 14, 16, 13, 15, 14, 14, 12, 14, 12, 13, 9, + 14, 15, 13, 13, 14, 13, 14, 12, 12, 13, 11, 11, 12, 11, 11, 8, + 15, 15, 14, 13, 15, 14, 14, 12, 13, 13, 12, 11, 13, 12, 11, 8, + 16, 16, 16, 13, 16, 15, 16, 13, 15, 14, 14, 12, 14, 13, 13, 9, + 14, 15, 13, 13, 16, 15, 15, 13, 13, 14, 11, 11, 13, 12, 11, 9, + 16, 16, 14, 13, 16, 15, 16, 13, 14, 14, 12, 11, 14, 13, 12, 8, + 16, 16, 15, 12, 16, 15, 15, 12, 15, 14, 13, 11, 14, 13, 12, 8, + 14, 14, 14, 13, 14, 13, 14, 12, 12, 13, 12, 11, 11, 11, 11, 8, + 15, 15, 15, 14, 14, 13, 15, 12, 14, 13, 13, 12, 12, 11, 11, 8, + 16, 16, 16, 15, 15, 14, 16, 13, 15, 14, 14, 12, 14, 12, 12, 9, + 15, 15, 14, 14, 14, 14, 14, 13, 13, 14, 12, 11, 12, 11, 11, 8, + 15, 15, 15, 13, 15, 14, 14, 12, 13, 13, 12, 11, 12, 11, 11, 7, + 16, 15, 16, 14, 16, 14, 15, 12, 15, 14, 14, 12, 13, 12, 12, 8, + 16, 16, 15, 14, 16, 15, 15, 13, 14, 14, 12, 11, 13, 12, 11, 8, + 16, 16, 15, 13, 16, 14, 14, 12, 14, 15, 12, 11, 13, 12, 11, 7, + 16, 16, 16, 13, 16, 15, 15, 12, 15, 14, 13, 11, 14, 12, 11, 7, + 15, 15, 15, 14, 13, 13, 14, 13, 13, 14, 13, 12, 11, 11, 11, 8, + 16, 16, 16, 14, 15, 13, 15, 12, 14, 14, 14, 13, 12, 11, 12, 8, + 16, 16, 16, 14, 15, 13, 15, 12, 15, 14, 14, 12, 13, 11, 12, 8, + 15, 16, 16, 14, 15, 14, 15, 13, 14, 14, 12, 12, 11, 11, 11, 8, + 16, 15, 15, 14, 15, 14, 14, 12, 14, 14, 13, 12, 12, 11, 11, 7, + 16, 16, 16, 13, 15, 13, 15, 12, 15, 14, 14, 12, 13, 11, 11, 7, + 16, 16, 16, 15, 15, 16, 15, 13, 14, 14, 12, 12, 12, 12, 11, 8, + 16, 16, 16, 14, 16, 14, 14, 12, 15, 15, 13, 11, 12, 11, 10, 7, + 16, 16, 15, 13, 16, 14, 14, 11, 15, 14, 13, 10, 13, 11, 10, 5, + }, + { + 1, 6, 6, 7, 6, 7, 9, 7, 6, 9, 7, 8, 7, 8, 8, 5, + 5, 8, 10, 10, 10, 10, 12, 11, 11, 12, 11, 11, 11, 12, 12, 9, + 9, 10, 12, 11, 13, 12, 15, 13, 14, 15, 15, 14, 14, 15, 15, 12, + 6, 10, 9, 10, 10, 11, 13, 12, 11, 13, 11, 12, 12, 12, 12, 10, + 6, 10, 10, 10, 11, 11, 13, 11, 11, 13, 12, 12, 11, 12, 12, 10, + 9, 12, 13, 12, 13, 13, 16, 13, 14, 16, 15, 14, 14, 15, 16, 12, + 9, 13, 11, 13, 14, 14, 16, 15, 14, 16, 13, 15, 15, 15, 15, 12, + 9, 13, 12, 13, 14, 15, 16, 15, 14, 16, 15, 15, 15, 15, 16, 12, + 8, 12, 12, 11, 13, 14, 15, 13, 13, 15, 14, 14, 14, 14, 14, 12, + 6, 10, 10, 11, 9, 10, 13, 11, 11, 13, 12, 12, 10, 12, 12, 9, + 6, 10, 11, 11, 11, 10, 13, 12, 11, 13, 12, 12, 12, 12, 13, 10, + 9, 12, 13, 13, 13, 12, 16, 13, 14, 16, 14, 15, 16, 14, 15, 12, + 8, 12, 13, 13, 13, 13, 16, 14, 13, 16, 13, 14, 14, 14, 14, 12, + 7, 11, 11, 12, 11, 12, 14, 13, 12, 14, 13, 13, 12, 13, 13, 11, + 9, 12, 13, 13, 13, 13, 15, 14, 14, 16, 16, 15, 15, 15, 16, 12, + 11, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 14, 14, 15, 15, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 13, + 9, 13, 13, 13, 14, 14, 16, 14, 14, 16, 15, 14, 14, 16, 16, 13, + 9, 13, 14, 14, 11, 13, 16, 14, 13, 16, 15, 16, 13, 14, 15, 12, + 10, 13, 14, 15, 13, 12, 16, 14, 14, 16, 15, 15, 14, 14, 16, 13, + 9, 12, 13, 14, 12, 11, 15, 13, 13, 15, 13, 14, 15, 14, 16, 12, + 11, 15, 16, 16, 14, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 13, + 11, 14, 14, 15, 13, 14, 16, 15, 15, 16, 16, 16, 16, 16, 16, 13, + 10, 12, 13, 14, 13, 13, 16, 14, 14, 14, 14, 16, 15, 14, 16, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 9, 12, 13, 14, 13, 13, 16, 13, 13, 15, 15, 16, 15, 15, 16, 12, + 6, 11, 11, 12, 10, 12, 13, 12, 11, 13, 11, 12, 11, 12, 13, 10, + 9, 12, 13, 13, 13, 13, 16, 14, 14, 15, 14, 14, 14, 14, 14, 12, + 12, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 7, 11, 11, 12, 12, 12, 14, 13, 12, 14, 11, 13, 13, 13, 13, 11, + 8, 12, 12, 13, 12, 13, 14, 13, 13, 14, 13, 13, 13, 14, 14, 11, + 11, 14, 14, 15, 16, 15, 16, 16, 15, 16, 16, 16, 16, 16, 16, 13, + 10, 14, 12, 14, 15, 15, 16, 16, 14, 16, 12, 15, 16, 16, 16, 13, + 11, 14, 13, 15, 15, 15, 16, 16, 14, 16, 14, 14, 16, 16, 16, 13, + 11, 14, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 13, + 7, 11, 12, 11, 10, 12, 14, 13, 12, 14, 13, 13, 10, 12, 13, 10, + 8, 12, 12, 13, 12, 12, 15, 13, 13, 14, 13, 13, 13, 13, 14, 11, + 11, 13, 15, 16, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, + 9, 12, 13, 13, 13, 13, 15, 14, 13, 15, 13, 14, 13, 14, 14, 12, + 7, 11, 11, 11, 11, 11, 13, 12, 11, 13, 11, 12, 11, 12, 12, 10, + 9, 12, 13, 13, 13, 13, 16, 13, 14, 16, 15, 14, 14, 14, 16, 12, + 12, 14, 14, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 14, + 10, 13, 13, 14, 14, 14, 16, 15, 14, 16, 14, 14, 16, 15, 15, 12, + 9, 12, 13, 13, 13, 15, 16, 14, 13, 16, 14, 13, 13, 14, 14, 11, + 10, 14, 15, 14, 12, 14, 16, 15, 13, 16, 16, 16, 12, 14, 16, 12, + 11, 14, 14, 14, 14, 14, 16, 15, 15, 16, 16, 16, 14, 15, 16, 13, + 11, 14, 14, 16, 14, 13, 16, 15, 14, 16, 15, 16, 15, 15, 16, 13, + 12, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 14, + 10, 13, 14, 14, 13, 14, 16, 14, 13, 16, 15, 15, 13, 14, 14, 12, + 9, 12, 13, 14, 13, 12, 16, 14, 13, 16, 14, 14, 14, 14, 15, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, + 9, 12, 13, 13, 13, 13, 14, 13, 12, 15, 14, 14, 14, 14, 14, 11, + 11, 14, 14, 16, 14, 16, 16, 16, 13, 16, 14, 16, 14, 16, 16, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 14, 14, 16, 16, 15, 16, 16, 15, 16, 14, 16, 16, 16, 16, 14, + 12, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 14, 12, 15, 15, 15, 16, 16, 14, 16, 12, 14, 16, 16, 15, 14, + 12, 15, 14, 16, 16, 16, 16, 16, 15, 16, 14, 16, 16, 16, 16, 14, + 12, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, + 11, 15, 15, 16, 14, 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 13, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 11, 15, 14, 16, 14, 14, 16, 15, 14, 16, 15, 16, 15, 16, 16, 12, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, + 12, 16, 15, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 14, + 10, 14, 13, 14, 15, 14, 16, 15, 14, 16, 13, 16, 16, 16, 15, 13, + 10, 14, 14, 14, 13, 14, 16, 15, 15, 16, 14, 14, 14, 16, 16, 12, + 10, 14, 15, 14, 13, 16, 16, 15, 13, 16, 16, 16, 12, 14, 16, 12, + 11, 16, 16, 16, 14, 15, 16, 16, 16, 16, 16, 16, 14, 16, 16, 13, + 12, 15, 14, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 14, + 11, 14, 14, 14, 14, 15, 16, 14, 14, 16, 16, 16, 13, 15, 15, 12, + 10, 14, 13, 14, 14, 14, 16, 15, 14, 16, 15, 15, 14, 14, 16, 12, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 12, 14, 14, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 13, + 8, 11, 11, 12, 12, 12, 13, 12, 11, 13, 12, 12, 12, 13, 12, 10, + }, + }, + { + { + 5, 6, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 6, 4, + 9, 9, 9, 8, 9, 8, 10, 8, 10, 10, 9, 9, 9, 8, 9, 6, + 11, 10, 12, 10, 11, 10, 12, 9, 12, 11, 11, 10, 11, 10, 11, 8, + 9, 10, 9, 8, 10, 10, 10, 9, 9, 10, 8, 8, 9, 9, 8, 7, + 10, 11, 10, 9, 11, 11, 11, 9, 11, 11, 10, 9, 10, 10, 10, 7, + 13, 12, 12, 10, 13, 12, 13, 10, 13, 12, 12, 11, 13, 12, 11, 9, + 11, 12, 10, 10, 12, 12, 11, 10, 11, 12, 10, 10, 11, 11, 10, 8, + 12, 12, 11, 10, 13, 13, 13, 10, 13, 13, 12, 11, 13, 12, 11, 9, + 12, 12, 12, 10, 13, 13, 13, 10, 13, 13, 12, 10, 13, 12, 12, 9, + 9, 9, 10, 10, 9, 8, 10, 9, 9, 10, 9, 9, 8, 8, 9, 6, + 10, 11, 11, 11, 10, 9, 11, 9, 11, 11, 11, 10, 10, 9, 10, 7, + 12, 12, 13, 12, 12, 10, 13, 10, 13, 13, 13, 12, 12, 11, 11, 9, + 11, 12, 11, 11, 11, 11, 11, 10, 11, 12, 10, 10, 10, 10, 10, 8, + 12, 12, 12, 11, 12, 11, 11, 10, 12, 12, 11, 11, 11, 11, 10, 8, + 14, 13, 13, 12, 13, 12, 13, 10, 14, 14, 13, 12, 13, 12, 12, 9, + 13, 14, 13, 12, 13, 13, 13, 12, 13, 13, 12, 12, 12, 12, 11, 9, + 14, 14, 13, 12, 13, 13, 13, 11, 14, 14, 13, 12, 13, 12, 12, 9, + 14, 15, 14, 12, 15, 13, 13, 11, 15, 14, 14, 12, 14, 13, 12, 9, + 11, 11, 12, 12, 10, 10, 12, 11, 11, 12, 11, 11, 10, 10, 10, 8, + 12, 12, 14, 13, 11, 10, 12, 11, 13, 13, 13, 12, 12, 10, 11, 9, + 13, 13, 14, 14, 12, 10, 13, 11, 14, 14, 14, 13, 12, 11, 12, 9, + 13, 13, 13, 13, 12, 13, 13, 12, 13, 14, 12, 12, 12, 12, 11, 9, + 13, 14, 14, 13, 13, 12, 13, 11, 14, 14, 13, 12, 13, 12, 12, 9, + 14, 14, 14, 14, 14, 12, 13, 11, 15, 15, 15, 13, 14, 12, 12, 9, + 14, 15, 15, 13, 14, 14, 13, 12, 13, 14, 13, 13, 12, 12, 11, 10, + 16, 16, 15, 14, 15, 14, 13, 11, 15, 15, 14, 13, 13, 13, 12, 9, + 15, 15, 15, 13, 14, 13, 13, 11, 15, 15, 15, 13, 14, 13, 12, 9, + 8, 9, 9, 9, 9, 9, 10, 9, 8, 10, 9, 9, 8, 8, 9, 7, + 11, 11, 11, 11, 11, 11, 12, 10, 11, 11, 11, 10, 10, 10, 10, 8, + 13, 13, 14, 12, 13, 12, 14, 11, 13, 13, 13, 12, 13, 11, 12, 9, + 10, 11, 10, 11, 11, 11, 12, 10, 10, 11, 10, 10, 10, 10, 10, 8, + 12, 12, 12, 11, 12, 12, 12, 11, 11, 12, 11, 10, 11, 11, 10, 8, + 14, 13, 14, 12, 14, 13, 14, 12, 14, 13, 13, 11, 13, 12, 12, 9, + 12, 13, 12, 12, 13, 13, 13, 12, 12, 13, 11, 11, 12, 12, 11, 9, + 13, 14, 13, 12, 14, 14, 14, 12, 14, 13, 12, 11, 13, 12, 12, 9, + 14, 14, 13, 12, 15, 14, 15, 12, 14, 14, 13, 11, 13, 13, 12, 9, + 10, 11, 11, 11, 10, 10, 12, 10, 10, 11, 10, 10, 9, 9, 10, 7, + 12, 12, 13, 12, 12, 11, 12, 11, 12, 12, 12, 11, 11, 10, 10, 8, + 14, 13, 14, 13, 14, 12, 13, 12, 14, 13, 14, 12, 13, 11, 12, 9, + 12, 13, 12, 12, 12, 12, 12, 11, 11, 12, 11, 10, 10, 10, 10, 8, + 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 11, 10, 11, 10, 10, 7, + 14, 14, 14, 12, 14, 12, 14, 11, 14, 13, 13, 11, 13, 11, 11, 8, + 13, 15, 13, 13, 14, 14, 14, 12, 13, 14, 12, 12, 12, 12, 11, 9, + 14, 15, 13, 12, 14, 13, 13, 11, 13, 13, 12, 11, 13, 12, 11, 8, + 15, 15, 15, 12, 15, 14, 14, 11, 14, 14, 13, 11, 13, 12, 12, 8, + 12, 13, 13, 13, 12, 12, 13, 12, 12, 13, 12, 12, 11, 11, 11, 9, + 13, 14, 15, 14, 13, 12, 14, 12, 13, 13, 14, 12, 12, 11, 12, 9, + 14, 14, 15, 14, 14, 12, 14, 12, 14, 14, 14, 13, 13, 11, 12, 9, + 13, 14, 14, 14, 13, 13, 14, 13, 13, 13, 12, 12, 12, 12, 11, 9, + 14, 14, 14, 13, 13, 13, 13, 12, 13, 14, 13, 12, 12, 11, 11, 8, + 15, 14, 15, 14, 14, 13, 14, 11, 15, 14, 14, 12, 13, 11, 12, 8, + 14, 15, 14, 14, 15, 14, 14, 13, 14, 15, 13, 13, 12, 12, 11, 10, + 16, 15, 14, 14, 14, 14, 13, 12, 14, 14, 13, 12, 13, 12, 11, 9, + 15, 15, 15, 14, 16, 14, 14, 11, 15, 15, 14, 12, 13, 12, 11, 8, + 11, 12, 11, 12, 12, 12, 12, 11, 10, 11, 10, 10, 10, 10, 10, 8, + 13, 13, 13, 13, 13, 13, 14, 12, 12, 12, 12, 12, 12, 11, 12, 9, + 14, 14, 14, 13, 15, 13, 15, 13, 14, 14, 14, 12, 14, 12, 13, 10, + 12, 13, 12, 13, 13, 13, 13, 12, 11, 12, 11, 11, 12, 11, 11, 9, + 14, 14, 13, 13, 14, 14, 14, 12, 12, 13, 12, 11, 13, 12, 12, 9, + 14, 14, 15, 13, 15, 15, 15, 13, 15, 13, 13, 12, 14, 12, 13, 10, + 13, 15, 12, 13, 14, 14, 14, 13, 12, 13, 11, 11, 13, 12, 11, 10, + 14, 15, 14, 13, 15, 14, 15, 13, 14, 14, 12, 11, 13, 13, 12, 9, + 14, 15, 14, 13, 15, 14, 15, 13, 14, 14, 13, 11, 14, 13, 12, 9, + 12, 13, 13, 13, 12, 13, 13, 12, 11, 12, 12, 11, 11, 11, 11, 9, + 13, 14, 14, 13, 14, 13, 14, 12, 13, 13, 13, 12, 12, 11, 11, 9, + 15, 15, 16, 14, 15, 14, 14, 13, 15, 14, 14, 13, 13, 12, 13, 10, + 13, 14, 14, 13, 13, 14, 14, 13, 12, 13, 12, 12, 11, 11, 11, 9, + 14, 14, 14, 13, 14, 13, 14, 12, 13, 13, 12, 11, 12, 11, 11, 8, + 15, 15, 15, 13, 15, 14, 14, 12, 14, 13, 13, 12, 13, 12, 12, 9, + 14, 15, 14, 14, 15, 15, 14, 13, 13, 14, 12, 12, 13, 12, 12, 9, + 15, 15, 14, 13, 15, 14, 14, 13, 14, 14, 12, 11, 13, 12, 11, 8, + 15, 16, 14, 13, 15, 15, 15, 12, 14, 14, 13, 11, 14, 12, 12, 8, + 12, 14, 13, 13, 13, 13, 14, 12, 12, 13, 12, 12, 10, 11, 11, 9, + 14, 15, 15, 14, 13, 13, 15, 13, 13, 14, 14, 12, 12, 11, 12, 9, + 15, 15, 16, 14, 14, 13, 15, 13, 14, 14, 14, 13, 13, 11, 12, 9, + 14, 15, 14, 14, 14, 14, 14, 13, 13, 14, 13, 12, 12, 12, 11, 9, + 14, 15, 15, 14, 14, 14, 14, 12, 13, 14, 13, 12, 12, 11, 11, 8, + 15, 15, 15, 14, 14, 13, 15, 12, 15, 14, 14, 12, 13, 11, 11, 8, + 14, 16, 14, 14, 14, 15, 14, 13, 13, 14, 12, 12, 12, 12, 11, 9, + 15, 15, 15, 14, 15, 14, 14, 12, 14, 14, 13, 12, 12, 11, 11, 8, + 15, 15, 14, 13, 15, 13, 14, 12, 14, 14, 13, 11, 13, 11, 11, 7, + }, + { + 1, 5, 6, 7, 6, 7, 9, 8, 6, 9, 8, 8, 7, 8, 8, 6, + 5, 8, 10, 10, 10, 11, 13, 12, 11, 13, 12, 12, 12, 12, 13, 10, + 8, 10, 13, 12, 13, 13, 16, 14, 14, 16, 16, 14, 16, 16, 16, 12, + 5, 10, 9, 11, 11, 12, 13, 12, 11, 13, 11, 12, 12, 12, 13, 10, + 6, 10, 11, 11, 11, 12, 14, 12, 11, 13, 13, 13, 12, 13, 13, 11, + 8, 12, 13, 12, 14, 14, 16, 14, 14, 16, 16, 16, 16, 16, 16, 13, + 9, 13, 11, 14, 14, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 13, + 9, 13, 13, 13, 14, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 14, + 8, 12, 13, 12, 13, 14, 16, 14, 14, 16, 16, 16, 14, 16, 16, 13, + 5, 10, 11, 12, 9, 11, 13, 12, 11, 13, 13, 13, 11, 12, 13, 10, + 6, 10, 11, 12, 11, 11, 14, 13, 12, 14, 12, 13, 13, 13, 13, 11, + 9, 12, 14, 15, 13, 13, 16, 16, 14, 16, 16, 16, 16, 16, 16, 13, + 8, 13, 13, 14, 13, 14, 16, 16, 14, 16, 14, 16, 14, 16, 14, 13, + 7, 11, 12, 13, 12, 12, 14, 13, 12, 14, 13, 14, 13, 14, 14, 12, + 9, 13, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 15, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 9, 13, 14, 14, 14, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, + 9, 13, 14, 15, 11, 13, 16, 14, 14, 16, 16, 16, 13, 14, 16, 13, + 9, 13, 14, 16, 13, 13, 16, 16, 14, 16, 16, 16, 16, 15, 16, 14, + 8, 12, 13, 16, 13, 12, 16, 14, 13, 16, 14, 16, 16, 16, 16, 13, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 14, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 9, 13, 16, 16, 14, 14, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 13, 14, 15, 14, 14, 16, 14, 13, 16, 16, 16, 14, 16, 16, 14, + 6, 11, 11, 12, 11, 12, 14, 13, 11, 14, 12, 13, 12, 13, 13, 11, + 9, 13, 13, 14, 13, 14, 16, 16, 14, 16, 16, 16, 15, 16, 16, 13, + 11, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 7, 11, 11, 13, 12, 13, 16, 14, 12, 16, 12, 14, 14, 14, 14, 12, + 8, 12, 12, 13, 12, 14, 16, 14, 13, 16, 14, 14, 14, 14, 14, 12, + 11, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 14, 13, 16, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 16, + 10, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 7, 11, 12, 12, 11, 13, 16, 14, 12, 15, 14, 14, 11, 13, 13, 12, + 8, 12, 12, 13, 13, 13, 16, 14, 13, 16, 13, 15, 13, 14, 14, 12, + 11, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 8, 12, 13, 14, 13, 14, 16, 16, 14, 16, 14, 16, 14, 16, 15, 13, + 6, 11, 11, 12, 11, 12, 13, 13, 11, 13, 12, 13, 12, 13, 13, 11, + 9, 13, 14, 14, 14, 14, 16, 14, 14, 16, 16, 16, 16, 16, 14, 13, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 14, 13, 14, 14, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 13, + 9, 13, 14, 13, 13, 16, 16, 14, 13, 16, 16, 16, 13, 16, 14, 13, + 10, 14, 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 13, 14, 16, 14, + 11, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 14, 16, 16, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 14, 14, 14, 14, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 13, + 9, 13, 13, 16, 14, 14, 16, 16, 14, 16, 14, 16, 16, 16, 16, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 13, 14, 14, 13, 16, 16, 14, 13, 16, 14, 16, 14, 14, 16, 12, + 10, 14, 14, 16, 16, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 14, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 14, 13, 16, 16, 16, 16, 16, 14, 16, 12, 16, 16, 16, 16, 14, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 14, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, + 11, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 15, 14, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 14, + 10, 14, 14, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, + 10, 14, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, 12, 16, 16, 14, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 15, 14, 16, 14, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 13, + 10, 15, 14, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 8, 12, 12, 13, 12, 14, 14, 14, 12, 16, 13, 14, 12, 14, 14, 11, + }, + }, +}; + + +static const uint8_t rv34_table_intra_cbp[NUM_INTRA_TABLES][8][CBP_VLC_SIZE] = { + { + { 0, 3, 3, 4, 3, 5, 5, 5, 2, 5, 4, 6, 4, 6, 6, 6, }, + { 0, 2, 3, 4, 2, 5, 6, 7, 3, 6, 5, 7, 4, 7, 8, 8, }, + { 0, 3, 4, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 3, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 6, 3, 5, 6, 5, }, + { 0, 4, 4, 4, 4, 5, 5, 4, 4, 5, 4, 5, 4, 4, 4, 2, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, + { 0, 6, 6, 5, 6, 5, 6, 4, 6, 6, 5, 4, 4, 4, 4, 1, }, + { 0, 4, 4, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 2, }, + }, + { + { 0, 4, 3, 4, 3, 4, 5, 4, 3, 5, 4, 5, 3, 5, 5, 5, }, + { 0, 2, 3, 4, 2, 5, 6, 7, 3, 6, 5, 7, 4, 7, 8, 8, }, + { 0, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 3, 4, 4, 3, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 6, 3, 5, 6, 5, }, + { 0, 4, 4, 4, 4, 4, 5, 4, 4, 5, 5, 5, 4, 4, 4, 2, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, + { 0, 5, 6, 5, 5, 5, 6, 4, 6, 6, 5, 4, 5, 4, 4, 1, }, + { 0, 4, 4, 4, 4, 4, 5, 4, 4, 5, 5, 4, 4, 4, 5, 2, }, + }, + { + { 0, 3, 3, 4, 3, 4, 4, 5, 3, 5, 4, 5, 4, 5, 5, 5, }, + { 0, 2, 3, 4, 2, 4, 6, 7, 3, 6, 5, 7, 5, 7, 8, 8, }, + { 0, 4, 4, 4, 4, 4, 5, 4, 3, 5, 4, 4, 4, 4, 4, 3, }, + { 0, 3, 3, 4, 3, 3, 6, 6, 3, 6, 4, 6, 3, 6, 6, 5, }, + { 0, 4, 4, 4, 3, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, + { 0, 5, 5, 5, 5, 5, 6, 4, 5, 6, 5, 5, 5, 4, 4, 1, }, + { 0, 4, 4, 4, 4, 4, 6, 4, 4, 6, 5, 4, 4, 4, 4, 2, }, + }, + { + { 0, 3, 3, 4, 3, 4, 4, 5, 3, 5, 4, 5, 4, 5, 5, 5, }, + { 0, 2, 3, 4, 2, 4, 7, 6, 3, 7, 5, 7, 5, 7, 7, 7, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, + { 0, 3, 3, 3, 3, 4, 6, 6, 3, 6, 4, 6, 3, 6, 6, 5, }, + { 0, 3, 4, 4, 3, 4, 5, 4, 4, 5, 4, 5, 4, 5, 4, 3, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, + { 0, 4, 5, 4, 4, 4, 5, 4, 4, 5, 5, 4, 4, 4, 4, 2, }, + { 0, 4, 4, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 2, }, + }, + { + { 0, 3, 3, 4, 3, 4, 5, 6, 2, 5, 4, 7, 4, 6, 6, 7, }, + { 0, 2, 3, 4, 2, 4, 6, 7, 3, 7, 5, 7, 5, 7, 7, 7, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, + { 0, 2, 3, 4, 3, 4, 6, 5, 3, 6, 4, 6, 4, 6, 6, 6, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, + { 0, 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, }, + { 0, 4, 4, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 2, }, + { 0, 3, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3, }, + }, +}; + + +static const uint8_t rv34_table_intra_firstpat[NUM_INTRA_TABLES][4][FIRSTBLK_VLC_SIZE] = { + { + { + 0, 10, 5, 10, 7, 12, 9, 11, 8, 13, 9, 12, 10, 13, 11, 12, + 16, 16, 14, 15, 15, 16, 13, 14, 5, 12, 6, 11, 9, 13, 10, 11, + 9, 14, 9, 12, 11, 14, 11, 12, 16, 16, 14, 15, 15, 16, 13, 13, + 10, 15, 9, 12, 12, 16, 11, 12, 12, 16, 10, 13, 13, 16, 11, 12, + 16, 16, 13, 14, 15, 16, 13, 12, 6, 12, 8, 11, 8, 12, 10, 11, + 9, 14, 10, 12, 10, 13, 11, 12, 15, 16, 14, 15, 14, 16, 13, 13, + 8, 13, 9, 12, 10, 13, 10, 12, 10, 14, 9, 12, 11, 14, 10, 12, + 15, 16, 13, 15, 14, 16, 13, 13, 11, 16, 10, 13, 13, 16, 11, 12, + 12, 16, 11, 13, 13, 16, 11, 12, 16, 16, 13, 14, 15, 16, 12, 12, + 10, 16, 12, 14, 10, 14, 11, 12, 12, 16, 13, 14, 11, 14, 12, 12, + 16, 16, 15, 16, 14, 15, 13, 13, 11, 16, 12, 14, 11, 14, 11, 12, + 12, 16, 12, 14, 11, 14, 11, 12, 16, 16, 14, 15, 13, 15, 13, 12, + 14, 16, 13, 14, 13, 16, 12, 12, 14, 16, 13, 14, 13, 16, 12, 12, + 16, 16, 14, 14, 14, 15, 12, 11, 2, 10, 6, 10, 7, 12, 9, 11, + 8, 12, 9, 11, 10, 13, 10, 11, 15, 16, 14, 15, 14, 16, 13, 13, + 5, 12, 6, 11, 9, 13, 10, 11, 9, 13, 9, 11, 10, 13, 10, 11, + 15, 16, 13, 14, 14, 16, 13, 13, 9, 15, 8, 12, 12, 15, 11, 11, + 11, 16, 10, 12, 13, 15, 11, 11, 15, 16, 13, 14, 15, 16, 12, 12, + 6, 12, 8, 11, 8, 12, 9, 11, 9, 14, 9, 12, 10, 13, 10, 11, + 15, 16, 14, 15, 14, 16, 13, 13, 7, 13, 8, 11, 9, 13, 10, 11, + 9, 14, 9, 12, 10, 13, 10, 11, 14, 16, 13, 14, 13, 16, 12, 12, + 11, 16, 10, 12, 12, 15, 11, 11, 11, 16, 10, 12, 12, 15, 11, 11, + 15, 16, 12, 13, 14, 16, 12, 11, 9, 15, 11, 13, 9, 13, 11, 12, + 11, 16, 12, 14, 10, 14, 11, 12, 16, 16, 14, 15, 13, 15, 12, 12, + 11, 16, 11, 14, 10, 14, 11, 12, 11, 16, 12, 13, 11, 14, 11, 11, + 15, 16, 14, 15, 13, 14, 12, 12, 13, 16, 12, 14, 13, 15, 11, 11, + 13, 16, 12, 14, 13, 15, 11, 11, 16, 16, 13, 14, 13, 15, 11, 10, + 5, 12, 7, 11, 8, 13, 10, 11, 9, 13, 9, 12, 10, 14, 11, 12, + 16, 16, 14, 15, 14, 16, 13, 13, 7, 13, 7, 11, 9, 13, 10, 11, + 9, 14, 9, 12, 11, 14, 11, 12, 16, 16, 14, 14, 14, 16, 13, 13, + 9, 15, 8, 12, 12, 15, 11, 12, 11, 16, 10, 12, 13, 16, 11, 12, + 16, 16, 13, 14, 15, 16, 12, 12, 7, 13, 8, 12, 9, 13, 10, 11, + 10, 14, 10, 12, 10, 14, 11, 12, 16, 16, 14, 15, 14, 16, 13, 13, + 8, 14, 9, 12, 10, 13, 10, 11, 9, 14, 9, 12, 10, 14, 10, 11, + 15, 16, 13, 14, 14, 16, 12, 12, 11, 16, 10, 12, 12, 15, 11, 12, + 11, 16, 10, 12, 12, 15, 11, 11, 15, 16, 12, 14, 14, 16, 12, 11, + 10, 16, 11, 13, 9, 14, 11, 12, 12, 16, 12, 14, 11, 14, 11, 12, + 16, 16, 14, 16, 14, 15, 13, 12, 11, 16, 11, 14, 10, 14, 11, 12, + 11, 16, 12, 14, 11, 14, 11, 11, 15, 16, 14, 15, 13, 15, 12, 12, + 13, 16, 12, 14, 13, 15, 11, 11, 13, 16, 12, 14, 12, 14, 11, 11, + 15, 16, 12, 13, 13, 14, 11, 10, 6, 13, 8, 11, 9, 13, 10, 11, + 10, 14, 10, 12, 10, 13, 10, 11, 15, 16, 13, 13, 13, 14, 12, 11, + 7, 13, 8, 11, 9, 13, 9, 11, 10, 14, 9, 11, 10, 13, 10, 11, + 15, 16, 13, 13, 13, 14, 11, 11, 9, 14, 8, 11, 10, 13, 9, 10, + 11, 15, 9, 11, 11, 13, 9, 10, 15, 16, 12, 13, 13, 14, 10, 9, + 7, 13, 8, 11, 9, 13, 9, 11, 10, 14, 10, 12, 10, 13, 10, 11, + 15, 16, 13, 13, 13, 14, 11, 11, 8, 13, 8, 11, 9, 13, 9, 10, + 9, 14, 9, 11, 10, 13, 9, 10, 14, 16, 12, 13, 13, 14, 11, 10, + 9, 14, 8, 11, 10, 13, 9, 9, 10, 14, 8, 11, 10, 13, 9, 9, + 14, 16, 11, 12, 12, 14, 10, 9, 9, 14, 9, 12, 8, 12, 9, 10, + 11, 15, 10, 12, 10, 13, 9, 10, 15, 16, 13, 13, 12, 13, 11, 10, + 9, 14, 9, 12, 9, 12, 9, 10, 10, 14, 10, 12, 9, 12, 9, 9, + 14, 16, 12, 13, 11, 13, 10, 9, 10, 14, 9, 11, 10, 12, 8, 8, + 10, 14, 9, 11, 10, 12, 8, 8, 12, 14, 9, 10, 10, 11, 8, 7, + }, + { + 0, 9, 6, 9, 6, 10, 8, 9, 7, 11, 8, 11, 9, 11, 9, 10, + 14, 16, 13, 14, 13, 14, 12, 11, 5, 11, 7, 10, 8, 10, 8, 9, + 8, 12, 8, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, + 10, 14, 9, 11, 11, 13, 10, 10, 11, 15, 9, 11, 12, 13, 10, 10, + 15, 16, 12, 12, 13, 14, 11, 9, 6, 11, 7, 10, 7, 10, 8, 9, + 8, 12, 9, 11, 9, 11, 9, 10, 14, 16, 13, 13, 13, 14, 11, 11, + 7, 12, 8, 11, 8, 11, 9, 9, 9, 13, 9, 11, 9, 12, 9, 10, + 14, 16, 12, 13, 12, 14, 11, 10, 11, 14, 10, 12, 11, 13, 10, 10, + 12, 15, 10, 12, 12, 13, 10, 10, 15, 16, 12, 12, 13, 14, 10, 9, + 10, 14, 11, 13, 9, 12, 10, 10, 11, 15, 12, 13, 10, 12, 10, 10, + 14, 16, 13, 14, 12, 13, 11, 10, 11, 14, 11, 13, 10, 12, 10, 10, + 12, 15, 11, 13, 10, 12, 10, 10, 15, 16, 13, 13, 12, 13, 11, 9, + 13, 16, 12, 13, 12, 13, 10, 9, 14, 16, 12, 13, 12, 13, 10, 9, + 16, 16, 12, 12, 13, 13, 10, 7, 4, 10, 6, 9, 7, 10, 8, 9, + 8, 12, 9, 11, 9, 11, 9, 9, 14, 16, 13, 13, 13, 14, 11, 11, + 6, 11, 7, 10, 8, 11, 8, 9, 9, 12, 9, 11, 9, 12, 9, 9, + 14, 16, 12, 13, 13, 14, 11, 10, 10, 14, 9, 11, 11, 13, 9, 9, + 11, 14, 9, 11, 11, 13, 10, 9, 14, 16, 11, 12, 13, 14, 10, 9, + 6, 11, 8, 10, 7, 10, 8, 9, 9, 12, 9, 11, 9, 11, 9, 9, + 14, 16, 13, 13, 12, 13, 11, 10, 8, 12, 8, 10, 8, 11, 9, 9, + 9, 12, 9, 11, 9, 11, 9, 9, 14, 16, 12, 13, 12, 13, 11, 10, + 11, 14, 10, 11, 11, 13, 9, 9, 11, 14, 10, 11, 11, 13, 9, 9, + 14, 16, 11, 12, 13, 14, 10, 8, 10, 14, 11, 12, 9, 12, 10, 10, + 11, 14, 11, 13, 10, 12, 10, 10, 14, 16, 13, 14, 12, 13, 11, 9, + 11, 14, 11, 12, 10, 12, 10, 10, 11, 14, 11, 12, 10, 12, 10, 9, + 14, 16, 13, 13, 11, 12, 10, 9, 13, 16, 12, 13, 12, 13, 10, 9, + 13, 16, 11, 12, 11, 13, 10, 8, 15, 16, 12, 12, 12, 12, 9, 7, + 8, 12, 8, 11, 9, 12, 9, 10, 10, 14, 10, 12, 11, 13, 10, 10, + 16, 16, 14, 14, 14, 14, 12, 11, 8, 13, 8, 11, 9, 12, 10, 10, + 11, 14, 10, 12, 11, 13, 10, 10, 16, 16, 13, 14, 14, 14, 12, 11, + 11, 14, 9, 12, 11, 13, 10, 10, 12, 15, 10, 12, 12, 14, 10, 10, + 15, 16, 12, 12, 14, 14, 11, 9, 9, 13, 9, 11, 9, 12, 10, 10, + 11, 14, 10, 12, 10, 12, 10, 10, 15, 16, 14, 14, 13, 14, 12, 11, + 9, 13, 9, 11, 10, 12, 10, 10, 10, 14, 10, 12, 10, 12, 10, 10, + 15, 16, 13, 13, 13, 14, 11, 10, 11, 15, 10, 12, 11, 13, 10, 10, + 11, 15, 10, 12, 12, 13, 10, 9, 15, 16, 11, 12, 13, 14, 10, 9, + 11, 15, 11, 13, 10, 12, 10, 10, 12, 16, 12, 13, 11, 13, 10, 10, + 16, 16, 14, 14, 12, 13, 11, 9, 11, 15, 11, 13, 10, 13, 10, 10, + 12, 15, 12, 13, 10, 12, 10, 10, 14, 16, 13, 13, 12, 13, 10, 9, + 13, 16, 12, 13, 12, 13, 10, 9, 13, 16, 11, 12, 11, 13, 10, 9, + 14, 16, 11, 12, 12, 12, 9, 7, 10, 15, 10, 12, 11, 13, 10, 10, + 12, 16, 12, 13, 12, 13, 11, 10, 16, 16, 14, 14, 14, 15, 12, 10, + 10, 14, 10, 12, 10, 13, 10, 10, 12, 15, 11, 12, 11, 13, 10, 10, + 16, 16, 14, 13, 14, 14, 11, 9, 11, 14, 10, 11, 11, 12, 9, 9, + 12, 15, 10, 11, 11, 13, 9, 8, 16, 16, 12, 12, 13, 13, 10, 7, + 10, 15, 10, 12, 10, 13, 10, 10, 12, 15, 11, 12, 11, 13, 10, 10, + 16, 16, 14, 13, 14, 14, 11, 9, 10, 14, 10, 12, 10, 12, 10, 10, + 12, 15, 11, 12, 11, 13, 10, 10, 16, 16, 13, 13, 13, 14, 11, 9, + 11, 14, 10, 11, 10, 12, 9, 8, 11, 14, 9, 11, 11, 12, 9, 8, + 14, 16, 10, 11, 12, 13, 9, 7, 11, 15, 11, 12, 10, 12, 10, 9, + 13, 16, 11, 12, 11, 12, 10, 9, 16, 16, 13, 13, 12, 13, 10, 7, + 11, 15, 10, 12, 10, 12, 9, 8, 12, 15, 11, 12, 10, 12, 9, 8, + 14, 16, 12, 12, 11, 12, 9, 7, 11, 14, 10, 11, 10, 12, 8, 7, + 11, 14, 9, 10, 10, 11, 8, 6, 12, 15, 9, 9, 9, 10, 7, 4, + }, + { + 0, 6, 3, 7, 3, 7, 6, 7, 5, 9, 6, 9, 7, 9, 8, 8, + 16, 16, 16, 16, 16, 16, 16, 11, 3, 8, 5, 8, 6, 8, 7, 7, + 7, 11, 7, 10, 8, 10, 8, 9, 16, 16, 16, 16, 16, 16, 14, 10, + 8, 16, 7, 11, 10, 16, 9, 9, 11, 16, 9, 14, 16, 16, 10, 9, + 16, 16, 16, 16, 16, 16, 16, 10, 3, 8, 5, 8, 5, 8, 7, 7, + 7, 11, 8, 10, 8, 10, 8, 9, 16, 16, 16, 16, 16, 16, 16, 11, + 6, 10, 7, 9, 7, 10, 8, 8, 8, 11, 8, 10, 8, 11, 8, 8, + 16, 16, 16, 16, 16, 16, 11, 10, 10, 16, 9, 13, 11, 16, 10, 9, + 11, 16, 9, 11, 16, 16, 10, 9, 16, 16, 11, 16, 16, 16, 11, 9, + 9, 16, 10, 11, 8, 11, 9, 9, 11, 16, 12, 16, 10, 16, 10, 10, + 16, 16, 16, 16, 16, 16, 16, 10, 10, 16, 11, 16, 10, 16, 10, 10, + 11, 16, 11, 16, 10, 16, 10, 9, 16, 16, 16, 16, 16, 16, 11, 9, + 16, 16, 16, 16, 16, 16, 11, 9, 16, 16, 16, 16, 16, 16, 11, 9, + 16, 16, 11, 16, 16, 16, 9, 7, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 2, 8, 5, 9, 6, 9, 8, 8, 8, 12, 9, 11, 9, 11, 10, 10, + 16, 16, 14, 16, 14, 16, 14, 12, 5, 10, 6, 9, 8, 10, 8, 9, + 9, 12, 9, 11, 10, 12, 10, 10, 16, 16, 14, 15, 15, 16, 13, 12, + 10, 13, 9, 12, 11, 12, 10, 10, 12, 15, 11, 12, 12, 13, 11, 10, + 16, 16, 15, 14, 15, 16, 13, 12, 6, 10, 8, 10, 7, 10, 8, 9, + 9, 13, 10, 11, 10, 12, 10, 10, 16, 16, 14, 16, 14, 16, 13, 12, + 7, 11, 8, 11, 9, 11, 9, 9, 10, 13, 10, 11, 10, 12, 10, 9, + 16, 16, 14, 14, 14, 15, 12, 11, 11, 14, 11, 12, 11, 13, 10, 10, + 12, 15, 11, 13, 12, 13, 11, 10, 16, 16, 14, 16, 15, 15, 13, 11, + 10, 13, 11, 12, 10, 12, 10, 10, 12, 15, 12, 13, 11, 13, 11, 11, + 16, 16, 15, 16, 14, 15, 13, 11, 11, 14, 11, 13, 11, 12, 11, 10, + 12, 16, 12, 13, 12, 13, 11, 10, 16, 16, 15, 16, 13, 15, 12, 11, + 13, 15, 12, 13, 13, 14, 11, 11, 14, 16, 13, 13, 13, 14, 11, 11, + 16, 16, 15, 14, 15, 15, 12, 10, 3, 8, 6, 9, 7, 9, 8, 8, + 8, 12, 9, 11, 9, 11, 9, 9, 16, 16, 15, 15, 15, 16, 13, 12, + 6, 10, 7, 9, 8, 10, 8, 8, 9, 12, 9, 11, 10, 12, 10, 9, + 16, 16, 14, 14, 14, 15, 13, 11, 10, 13, 9, 11, 11, 12, 10, 10, + 12, 14, 11, 12, 12, 13, 11, 10, 16, 16, 14, 14, 15, 15, 13, 11, + 6, 10, 8, 10, 7, 10, 8, 9, 10, 12, 10, 11, 10, 11, 10, 9, + 16, 16, 14, 15, 14, 15, 13, 11, 8, 11, 8, 10, 9, 11, 9, 9, + 9, 13, 9, 11, 10, 11, 9, 9, 16, 16, 13, 14, 14, 14, 12, 10, + 11, 14, 10, 12, 11, 12, 10, 10, 12, 14, 11, 12, 12, 13, 10, 10, + 16, 16, 13, 14, 15, 15, 12, 10, 10, 13, 11, 12, 10, 12, 10, 10, + 12, 14, 12, 13, 11, 13, 11, 10, 16, 16, 15, 14, 14, 14, 12, 11, + 11, 14, 11, 12, 10, 12, 10, 10, 12, 15, 12, 12, 11, 13, 10, 10, + 16, 16, 14, 15, 13, 14, 12, 10, 13, 15, 12, 13, 12, 13, 11, 10, + 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 13, 14, 13, 15, 11, 9, + 6, 10, 8, 10, 8, 11, 9, 10, 11, 13, 11, 12, 11, 13, 11, 10, + 16, 16, 16, 16, 16, 16, 13, 12, 8, 11, 9, 11, 9, 11, 10, 10, + 11, 14, 11, 12, 11, 12, 11, 10, 16, 16, 15, 15, 16, 16, 13, 12, + 11, 14, 10, 12, 12, 13, 11, 10, 13, 16, 12, 13, 13, 14, 11, 11, + 16, 16, 15, 16, 16, 16, 13, 12, 8, 12, 9, 11, 9, 11, 10, 10, + 11, 14, 11, 12, 11, 12, 11, 10, 16, 16, 16, 16, 16, 16, 13, 12, + 9, 12, 10, 11, 10, 12, 10, 10, 11, 14, 11, 12, 11, 13, 10, 10, + 16, 16, 15, 14, 15, 15, 13, 11, 12, 14, 11, 13, 12, 13, 11, 10, + 12, 15, 11, 12, 13, 13, 11, 10, 16, 16, 14, 15, 16, 15, 13, 11, + 11, 15, 12, 13, 11, 13, 11, 10, 13, 16, 13, 14, 12, 14, 11, 11, + 16, 16, 16, 16, 15, 15, 13, 12, 12, 14, 12, 13, 11, 13, 11, 10, + 13, 15, 12, 13, 11, 13, 11, 10, 16, 16, 15, 15, 13, 15, 13, 11, + 13, 16, 13, 13, 13, 13, 12, 11, 13, 16, 13, 13, 13, 13, 11, 10, + 16, 16, 13, 15, 14, 14, 12, 9, 9, 13, 10, 12, 11, 13, 11, 11, + 13, 16, 13, 14, 13, 14, 12, 11, 16, 16, 16, 16, 16, 16, 14, 12, + 10, 14, 11, 13, 11, 13, 11, 10, 13, 16, 13, 13, 13, 14, 12, 11, + 16, 16, 16, 16, 16, 16, 14, 12, 11, 15, 11, 13, 12, 13, 11, 10, + 14, 16, 12, 13, 13, 14, 12, 10, 16, 16, 15, 16, 16, 16, 13, 11, + 10, 14, 11, 12, 11, 13, 11, 10, 13, 16, 12, 13, 12, 14, 12, 11, + 16, 16, 16, 16, 16, 16, 14, 12, 11, 14, 11, 12, 11, 13, 11, 10, + 13, 15, 12, 13, 12, 13, 11, 10, 16, 16, 15, 15, 16, 16, 13, 11, + 12, 15, 12, 13, 12, 13, 11, 10, 13, 16, 12, 13, 13, 13, 11, 10, + 16, 16, 14, 14, 16, 15, 13, 10, 12, 15, 12, 13, 12, 13, 11, 10, + 14, 16, 13, 14, 13, 14, 12, 11, 16, 16, 16, 16, 15, 16, 13, 11, + 12, 16, 12, 13, 12, 13, 11, 10, 13, 16, 13, 13, 12, 14, 11, 10, + 16, 16, 15, 16, 14, 15, 13, 10, 12, 15, 12, 14, 12, 13, 11, 10, + 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 13, 14, 13, 14, 11, 8, + }, + }, + { + { + 0, 11, 5, 11, 7, 13, 10, 12, 7, 13, 9, 13, 10, 14, 12, 13, + 16, 16, 15, 16, 16, 16, 15, 15, 4, 13, 6, 12, 10, 14, 11, 12, + 8, 14, 9, 13, 11, 15, 12, 13, 16, 16, 15, 16, 15, 16, 15, 14, + 9, 16, 9, 13, 13, 16, 12, 13, 12, 16, 10, 14, 14, 16, 13, 13, + 16, 16, 14, 16, 16, 16, 14, 14, 5, 13, 8, 13, 8, 13, 11, 12, + 9, 14, 10, 13, 10, 14, 12, 13, 16, 16, 15, 16, 15, 16, 14, 15, + 7, 14, 9, 13, 10, 14, 11, 13, 9, 15, 10, 13, 11, 14, 12, 13, + 16, 16, 14, 16, 15, 16, 14, 14, 11, 16, 11, 14, 13, 16, 12, 13, + 12, 16, 11, 14, 14, 16, 12, 13, 16, 16, 14, 15, 16, 16, 14, 13, + 10, 16, 12, 15, 10, 15, 12, 14, 12, 16, 13, 16, 11, 15, 13, 14, + 16, 16, 16, 16, 14, 16, 14, 14, 11, 16, 12, 15, 11, 16, 12, 13, + 12, 16, 13, 15, 12, 16, 12, 13, 16, 16, 16, 16, 14, 16, 14, 14, + 14, 16, 13, 15, 14, 16, 13, 13, 14, 16, 14, 15, 14, 16, 13, 13, + 16, 16, 15, 16, 15, 16, 13, 13, 2, 12, 6, 11, 7, 13, 10, 12, + 7, 13, 9, 12, 10, 14, 11, 12, 16, 16, 15, 16, 15, 16, 14, 15, + 5, 13, 6, 12, 9, 13, 10, 12, 8, 14, 9, 13, 11, 14, 11, 13, + 16, 16, 14, 16, 15, 16, 14, 14, 9, 16, 8, 13, 12, 16, 11, 13, + 11, 16, 10, 13, 13, 16, 12, 13, 16, 16, 13, 15, 16, 16, 13, 13, + 5, 13, 8, 12, 7, 13, 10, 12, 8, 14, 10, 13, 10, 14, 11, 13, + 16, 16, 14, 16, 15, 16, 14, 14, 7, 14, 8, 12, 9, 14, 11, 12, + 8, 14, 9, 13, 10, 14, 11, 12, 15, 16, 14, 15, 14, 16, 13, 14, + 11, 16, 10, 13, 13, 16, 12, 13, 11, 16, 10, 13, 13, 16, 12, 13, + 16, 16, 13, 15, 15, 16, 13, 13, 9, 16, 12, 15, 9, 14, 11, 13, + 11, 16, 13, 15, 11, 14, 12, 13, 16, 16, 15, 16, 14, 16, 14, 14, + 11, 16, 12, 14, 11, 15, 12, 13, 11, 16, 12, 14, 11, 15, 12, 13, + 16, 16, 15, 16, 14, 16, 13, 13, 13, 16, 13, 15, 13, 16, 12, 13, + 14, 16, 13, 15, 13, 16, 12, 12, 16, 16, 14, 15, 14, 16, 12, 12, + 4, 13, 7, 12, 8, 14, 11, 12, 9, 14, 10, 13, 11, 14, 12, 13, + 16, 16, 15, 16, 16, 16, 15, 15, 6, 14, 7, 12, 10, 14, 11, 12, + 9, 15, 10, 13, 11, 15, 12, 13, 16, 16, 15, 16, 16, 16, 14, 14, + 9, 16, 8, 13, 12, 16, 11, 13, 12, 16, 10, 14, 13, 16, 12, 13, + 16, 16, 14, 16, 16, 16, 14, 14, 6, 14, 8, 13, 8, 14, 11, 13, + 9, 15, 10, 13, 11, 14, 12, 13, 16, 16, 15, 16, 16, 16, 14, 14, + 7, 15, 9, 13, 10, 14, 11, 13, 9, 15, 10, 13, 11, 14, 11, 13, + 16, 16, 14, 16, 15, 16, 14, 14, 10, 16, 10, 13, 12, 16, 12, 13, + 11, 16, 10, 13, 13, 16, 12, 13, 16, 16, 13, 14, 15, 16, 13, 13, + 9, 16, 12, 14, 9, 14, 11, 13, 12, 16, 12, 15, 11, 15, 12, 13, + 16, 16, 16, 16, 15, 16, 14, 14, 10, 16, 12, 15, 11, 15, 12, 13, + 11, 16, 12, 14, 11, 15, 12, 13, 16, 16, 14, 16, 13, 16, 13, 13, + 13, 16, 13, 15, 13, 16, 12, 13, 13, 16, 12, 14, 13, 16, 12, 12, + 15, 16, 13, 14, 13, 16, 12, 12, 6, 14, 8, 13, 9, 14, 10, 12, + 10, 15, 10, 12, 11, 14, 11, 12, 16, 16, 14, 14, 14, 16, 13, 13, + 7, 15, 8, 13, 9, 14, 10, 12, 10, 15, 10, 13, 11, 14, 11, 12, + 16, 16, 14, 14, 14, 16, 13, 12, 9, 16, 8, 12, 11, 14, 10, 11, + 11, 16, 10, 13, 11, 14, 10, 11, 16, 16, 13, 14, 14, 16, 12, 11, + 7, 14, 9, 13, 9, 14, 10, 12, 10, 16, 10, 13, 11, 14, 11, 12, + 16, 16, 14, 14, 14, 15, 13, 12, 7, 14, 9, 13, 9, 14, 10, 12, + 9, 14, 10, 12, 10, 14, 11, 12, 15, 16, 13, 14, 14, 15, 12, 12, + 9, 15, 9, 12, 11, 14, 10, 11, 10, 15, 9, 12, 11, 14, 10, 11, + 14, 16, 11, 13, 13, 15, 11, 11, 9, 16, 10, 13, 9, 14, 10, 11, + 11, 16, 11, 13, 10, 14, 10, 11, 16, 16, 14, 15, 13, 15, 12, 12, + 9, 16, 10, 13, 9, 13, 10, 11, 10, 15, 10, 13, 10, 13, 10, 11, + 14, 16, 13, 14, 12, 14, 11, 11, 11, 16, 10, 13, 11, 13, 9, 10, + 11, 14, 10, 12, 10, 13, 9, 9, 13, 15, 10, 11, 11, 12, 9, 8, + }, + { + 0, 10, 5, 10, 6, 11, 8, 10, 7, 12, 8, 11, 9, 12, 9, 10, + 14, 16, 13, 13, 13, 14, 12, 11, 5, 12, 6, 10, 8, 12, 9, 10, + 8, 13, 8, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, + 9, 15, 8, 12, 11, 14, 10, 10, 11, 16, 9, 12, 12, 14, 10, 10, + 14, 16, 11, 12, 13, 14, 11, 10, 5, 12, 8, 11, 7, 11, 9, 10, + 8, 13, 9, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, + 7, 13, 8, 11, 9, 12, 9, 10, 9, 13, 9, 11, 9, 12, 9, 10, + 14, 16, 12, 13, 12, 13, 11, 10, 11, 15, 10, 12, 12, 14, 10, 10, + 12, 16, 10, 12, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 10, 9, + 10, 15, 11, 13, 9, 13, 10, 10, 11, 15, 12, 13, 10, 12, 10, 10, + 14, 16, 13, 14, 12, 13, 11, 10, 11, 16, 11, 13, 10, 13, 10, 10, + 11, 16, 11, 13, 10, 13, 10, 10, 14, 16, 13, 14, 12, 13, 11, 9, + 13, 16, 12, 13, 12, 14, 11, 10, 14, 16, 12, 13, 12, 14, 10, 9, + 16, 16, 12, 13, 13, 13, 10, 8, 3, 11, 6, 10, 7, 11, 9, 10, + 8, 12, 8, 11, 9, 12, 9, 10, 14, 16, 13, 13, 13, 14, 11, 11, + 5, 12, 6, 10, 8, 12, 9, 10, 8, 13, 8, 11, 9, 12, 9, 10, + 14, 16, 12, 13, 13, 14, 11, 10, 9, 14, 8, 11, 11, 14, 10, 10, + 11, 15, 9, 11, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 11, 9, + 6, 12, 8, 11, 7, 11, 9, 10, 8, 13, 9, 11, 9, 12, 9, 10, + 14, 16, 12, 13, 13, 13, 11, 10, 7, 13, 8, 11, 8, 12, 9, 10, + 9, 13, 9, 11, 9, 12, 9, 9, 14, 16, 12, 13, 12, 13, 11, 10, + 10, 15, 9, 12, 11, 14, 10, 10, 11, 15, 9, 11, 11, 13, 10, 9, + 14, 16, 11, 12, 13, 14, 10, 9, 9, 15, 11, 13, 9, 12, 10, 10, + 11, 15, 11, 13, 9, 12, 10, 10, 14, 16, 13, 14, 12, 13, 11, 10, + 10, 15, 11, 13, 10, 13, 10, 10, 11, 15, 11, 13, 10, 12, 10, 10, + 14, 16, 12, 13, 11, 12, 10, 9, 13, 16, 12, 13, 12, 14, 10, 9, + 13, 16, 11, 12, 12, 13, 10, 9, 14, 16, 11, 12, 12, 13, 9, 8, + 7, 13, 8, 12, 9, 13, 10, 11, 10, 14, 10, 12, 11, 13, 11, 11, + 16, 16, 13, 14, 14, 14, 12, 11, 8, 14, 8, 12, 9, 13, 10, 10, + 10, 14, 10, 12, 11, 13, 10, 10, 16, 16, 13, 13, 14, 14, 12, 11, + 10, 15, 9, 12, 11, 14, 10, 10, 12, 16, 10, 12, 12, 14, 10, 10, + 16, 16, 12, 13, 14, 15, 11, 10, 8, 14, 9, 12, 9, 13, 10, 11, + 10, 15, 10, 12, 10, 13, 10, 11, 16, 16, 13, 14, 14, 14, 12, 11, + 8, 14, 9, 12, 9, 13, 10, 10, 10, 14, 10, 12, 10, 13, 10, 10, + 15, 16, 13, 13, 13, 14, 11, 10, 10, 15, 10, 12, 12, 14, 10, 10, + 11, 16, 9, 12, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 10, 9, + 11, 16, 11, 13, 10, 13, 10, 10, 12, 16, 12, 13, 10, 13, 11, 10, + 15, 16, 14, 14, 12, 13, 11, 10, 11, 16, 11, 13, 10, 13, 10, 10, + 11, 16, 12, 13, 10, 12, 10, 10, 14, 16, 13, 14, 11, 13, 11, 9, + 13, 16, 12, 13, 12, 14, 10, 10, 12, 16, 11, 12, 12, 13, 10, 9, + 14, 16, 11, 12, 11, 12, 9, 8, 10, 16, 10, 13, 11, 14, 11, 11, + 12, 16, 11, 13, 12, 14, 11, 11, 16, 16, 14, 13, 14, 14, 12, 10, + 10, 15, 10, 13, 10, 13, 10, 11, 12, 16, 11, 13, 11, 13, 11, 10, + 16, 16, 14, 13, 14, 14, 12, 10, 11, 15, 9, 12, 11, 13, 10, 9, + 12, 16, 10, 12, 12, 13, 10, 9, 16, 16, 12, 12, 13, 14, 10, 8, + 10, 16, 10, 13, 10, 14, 11, 11, 12, 16, 11, 13, 12, 14, 11, 10, + 16, 16, 14, 13, 14, 14, 12, 10, 9, 15, 9, 12, 10, 13, 10, 10, + 11, 16, 10, 12, 11, 13, 10, 10, 16, 16, 13, 13, 13, 14, 11, 9, + 10, 15, 9, 11, 11, 13, 9, 9, 11, 15, 9, 11, 11, 13, 9, 8, + 14, 16, 10, 11, 13, 13, 10, 8, 11, 16, 11, 13, 10, 13, 10, 9, + 13, 16, 11, 13, 11, 13, 10, 9, 16, 16, 13, 13, 13, 13, 10, 8, + 11, 16, 10, 12, 10, 13, 10, 9, 11, 16, 11, 12, 10, 12, 9, 9, + 15, 16, 12, 13, 11, 12, 10, 8, 11, 16, 10, 12, 11, 12, 9, 8, + 11, 15, 9, 11, 10, 12, 9, 7, 13, 15, 9, 9, 10, 10, 7, 5, + }, + { + 0, 7, 3, 8, 4, 9, 7, 8, 5, 10, 7, 10, 8, 11, 8, 9, + 16, 16, 16, 16, 16, 16, 11, 10, 2, 10, 4, 9, 7, 10, 7, 8, + 7, 16, 7, 10, 9, 16, 8, 9, 16, 16, 16, 16, 16, 16, 11, 10, + 8, 16, 7, 10, 10, 16, 9, 8, 10, 16, 9, 11, 16, 16, 9, 9, + 16, 16, 16, 16, 16, 16, 11, 9, 3, 10, 6, 9, 6, 11, 8, 8, + 7, 16, 8, 10, 9, 16, 9, 9, 16, 16, 16, 16, 16, 16, 11, 10, + 5, 16, 7, 10, 8, 11, 8, 8, 8, 16, 8, 10, 9, 16, 8, 8, + 16, 16, 11, 16, 16, 16, 10, 9, 9, 16, 9, 11, 11, 16, 9, 9, + 11, 16, 9, 11, 11, 16, 9, 8, 16, 16, 10, 16, 16, 16, 10, 9, + 8, 16, 10, 16, 8, 16, 10, 9, 12, 16, 11, 16, 10, 16, 10, 9, + 16, 16, 16, 16, 16, 16, 12, 10, 10, 16, 11, 16, 10, 16, 10, 9, + 11, 16, 11, 16, 10, 16, 10, 9, 16, 16, 16, 16, 16, 16, 11, 9, + 16, 16, 16, 16, 16, 16, 10, 9, 16, 16, 11, 16, 16, 16, 10, 9, + 16, 16, 10, 11, 11, 16, 9, 7, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 2, 9, 6, 9, 6, 10, 8, 9, 8, 12, 9, 11, 9, 12, 10, 10, + 16, 16, 14, 14, 15, 15, 13, 12, 5, 11, 7, 10, 8, 11, 9, 9, + 9, 13, 9, 11, 10, 12, 10, 10, 15, 16, 14, 14, 14, 16, 12, 11, + 10, 14, 9, 11, 11, 13, 10, 10, 12, 15, 10, 12, 12, 13, 11, 10, + 16, 16, 14, 15, 14, 15, 12, 11, 5, 11, 8, 10, 7, 11, 9, 9, + 9, 13, 9, 12, 9, 12, 10, 10, 15, 16, 13, 14, 13, 16, 12, 11, + 7, 12, 8, 11, 9, 11, 9, 10, 9, 13, 9, 11, 10, 12, 9, 9, + 16, 16, 13, 14, 13, 14, 11, 11, 10, 14, 10, 12, 11, 13, 10, 10, + 11, 16, 11, 12, 12, 13, 10, 10, 16, 16, 13, 14, 13, 14, 12, 11, + 10, 14, 11, 13, 10, 13, 10, 11, 12, 16, 12, 13, 10, 12, 11, 11, + 16, 16, 14, 15, 13, 14, 12, 11, 11, 15, 11, 13, 11, 13, 10, 10, + 12, 15, 12, 13, 11, 13, 11, 10, 15, 16, 14, 15, 13, 15, 12, 11, + 12, 16, 12, 13, 12, 14, 11, 11, 13, 16, 12, 13, 12, 14, 11, 10, + 16, 16, 13, 14, 13, 14, 11, 10, 3, 10, 6, 9, 7, 10, 8, 9, + 9, 12, 9, 11, 10, 12, 9, 10, 15, 16, 14, 14, 14, 14, 12, 11, + 6, 11, 7, 10, 8, 10, 9, 9, 9, 13, 9, 11, 10, 12, 9, 9, + 15, 16, 13, 14, 14, 15, 12, 11, 10, 14, 9, 11, 11, 12, 10, 10, + 12, 14, 10, 12, 11, 13, 10, 10, 15, 16, 13, 14, 14, 16, 12, 11, + 6, 11, 8, 10, 7, 11, 9, 9, 9, 13, 9, 11, 9, 12, 9, 9, + 15, 16, 14, 14, 13, 14, 12, 11, 7, 11, 8, 11, 8, 11, 9, 9, + 9, 12, 9, 11, 9, 12, 9, 9, 15, 16, 13, 13, 13, 14, 11, 10, + 10, 13, 10, 12, 11, 13, 10, 10, 11, 15, 10, 12, 11, 13, 10, 10, + 14, 16, 12, 13, 13, 14, 11, 10, 10, 14, 11, 12, 9, 12, 10, 10, + 11, 15, 11, 13, 10, 13, 10, 10, 15, 16, 14, 14, 13, 14, 12, 11, + 10, 14, 10, 12, 10, 12, 10, 10, 11, 15, 11, 12, 10, 12, 10, 10, + 15, 16, 13, 14, 12, 14, 11, 10, 12, 16, 11, 13, 12, 14, 11, 10, + 12, 16, 12, 13, 11, 13, 10, 10, 15, 16, 12, 14, 12, 14, 11, 9, + 7, 12, 9, 11, 9, 12, 10, 10, 11, 14, 11, 12, 11, 13, 11, 11, + 16, 16, 15, 16, 15, 16, 13, 12, 8, 12, 9, 11, 9, 12, 10, 10, + 11, 14, 11, 12, 11, 13, 10, 10, 16, 16, 14, 15, 15, 16, 13, 12, + 11, 14, 10, 12, 11, 13, 10, 10, 12, 16, 11, 13, 12, 14, 11, 10, + 16, 16, 14, 15, 14, 16, 12, 11, 8, 13, 9, 11, 9, 12, 10, 10, + 11, 14, 11, 12, 11, 13, 10, 10, 16, 16, 15, 15, 14, 15, 13, 12, + 9, 13, 9, 12, 9, 12, 10, 10, 11, 14, 10, 12, 10, 12, 10, 10, + 16, 16, 14, 15, 14, 14, 12, 11, 11, 15, 11, 12, 11, 13, 11, 10, + 12, 16, 11, 12, 12, 13, 11, 10, 16, 16, 13, 15, 14, 15, 11, 11, + 11, 16, 11, 13, 10, 13, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, + 16, 16, 14, 15, 14, 15, 13, 11, 11, 16, 11, 13, 11, 13, 11, 10, + 12, 16, 12, 13, 10, 13, 11, 10, 16, 16, 14, 14, 12, 14, 12, 10, + 12, 16, 12, 14, 12, 14, 11, 11, 13, 16, 12, 14, 12, 14, 11, 10, + 15, 16, 12, 14, 12, 14, 11, 9, 9, 14, 11, 13, 11, 13, 11, 11, + 13, 16, 12, 14, 13, 14, 12, 11, 16, 16, 16, 16, 16, 16, 14, 12, + 9, 14, 10, 12, 10, 13, 11, 11, 12, 16, 12, 13, 13, 14, 11, 11, + 16, 16, 16, 16, 16, 14, 13, 12, 10, 15, 11, 13, 11, 14, 11, 10, + 13, 16, 12, 13, 12, 15, 11, 10, 16, 16, 14, 16, 15, 16, 13, 11, + 10, 14, 10, 13, 11, 14, 11, 11, 13, 16, 12, 13, 12, 14, 11, 11, + 16, 16, 16, 16, 15, 16, 13, 12, 10, 14, 10, 12, 10, 13, 10, 11, + 12, 15, 12, 13, 12, 13, 11, 10, 16, 16, 14, 14, 15, 15, 13, 11, + 11, 16, 11, 13, 11, 14, 11, 10, 12, 16, 11, 13, 12, 14, 11, 10, + 16, 16, 13, 14, 14, 15, 12, 10, 11, 16, 12, 13, 11, 14, 11, 10, + 13, 16, 13, 14, 12, 14, 11, 11, 16, 16, 15, 16, 15, 15, 12, 11, + 11, 16, 12, 13, 11, 14, 11, 10, 13, 16, 12, 13, 11, 14, 11, 10, + 16, 16, 14, 15, 13, 14, 12, 10, 12, 16, 12, 14, 12, 14, 10, 10, + 12, 16, 11, 13, 11, 14, 10, 10, 14, 16, 11, 13, 12, 13, 10, 8, + }, + }, + { + { + 0, 12, 6, 13, 7, 14, 11, 14, 8, 14, 10, 14, 11, 15, 13, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 5, 14, 7, 13, 10, 16, 12, 14, + 9, 16, 10, 14, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 9, 14, 14, 16, 13, 16, 12, 16, 11, 16, 16, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 5, 14, 9, 14, 8, 14, 12, 14, + 9, 16, 11, 14, 11, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 10, 14, 11, 16, 12, 14, 10, 16, 11, 15, 12, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 12, 16, 14, 16, 14, 16, + 13, 16, 12, 16, 15, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 13, 16, 11, 16, 14, 16, 13, 16, 14, 16, 13, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 14, 16, 13, 16, 14, 16, + 13, 16, 14, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 15, 16, 16, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 1, 12, 6, 12, 8, 14, 11, 13, + 8, 14, 10, 13, 11, 14, 13, 14, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 14, 7, 13, 10, 14, 11, 14, 9, 16, 10, 14, 12, 16, 13, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 9, 14, 13, 16, 13, 14, + 12, 16, 11, 15, 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 14, 9, 13, 8, 14, 12, 14, 9, 16, 11, 14, 11, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 7, 15, 9, 14, 10, 16, 12, 14, + 9, 16, 10, 14, 11, 16, 12, 14, 16, 16, 16, 16, 16, 16, 15, 16, + 11, 16, 11, 15, 14, 16, 13, 15, 12, 16, 11, 15, 14, 16, 13, 14, + 16, 16, 14, 16, 16, 16, 14, 16, 10, 16, 13, 16, 10, 16, 13, 16, + 12, 16, 14, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 13, 16, 12, 16, 13, 16, 12, 16, 13, 16, 12, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 15, 16, 14, 16, 14, 16, 16, 16, 14, 16, + 15, 16, 14, 16, 14, 16, 14, 16, 16, 16, 16, 16, 16, 16, 14, 14, + 4, 14, 8, 13, 9, 16, 12, 14, 9, 16, 11, 14, 11, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 15, 8, 13, 10, 16, 12, 14, + 10, 16, 11, 14, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 16, 9, 14, 13, 16, 13, 15, 12, 16, 11, 16, 14, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 9, 14, 9, 16, 12, 14, + 10, 16, 11, 15, 12, 16, 13, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 10, 14, 11, 16, 12, 14, 10, 16, 11, 14, 12, 16, 13, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 15, 14, 16, 13, 15, + 12, 16, 11, 15, 14, 16, 13, 14, 16, 16, 14, 16, 16, 16, 14, 16, + 10, 16, 13, 16, 10, 16, 13, 15, 13, 16, 14, 16, 12, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 12, 16, 13, 16, + 12, 16, 13, 16, 11, 16, 13, 16, 16, 16, 16, 16, 15, 16, 15, 16, + 14, 16, 14, 16, 15, 16, 14, 16, 14, 16, 14, 16, 14, 16, 14, 14, + 16, 16, 14, 16, 15, 16, 14, 14, 6, 16, 9, 14, 10, 16, 12, 14, + 10, 16, 11, 13, 12, 16, 13, 14, 16, 16, 16, 16, 16, 16, 14, 14, + 7, 16, 9, 14, 10, 16, 12, 13, 11, 16, 11, 14, 12, 16, 12, 14, + 16, 16, 16, 16, 16, 16, 14, 14, 9, 16, 9, 14, 12, 16, 11, 13, + 12, 16, 11, 14, 12, 16, 12, 13, 16, 16, 14, 16, 16, 16, 13, 14, + 7, 16, 10, 14, 10, 16, 12, 14, 11, 16, 11, 14, 11, 16, 12, 14, + 16, 16, 16, 16, 16, 16, 14, 14, 8, 16, 10, 14, 10, 16, 11, 13, + 10, 16, 11, 13, 11, 16, 12, 13, 16, 16, 14, 16, 16, 16, 14, 14, + 10, 16, 9, 13, 12, 16, 11, 13, 11, 16, 10, 13, 12, 16, 11, 12, + 16, 16, 13, 15, 15, 16, 13, 13, 9, 16, 11, 14, 9, 16, 11, 13, + 12, 16, 12, 16, 12, 16, 12, 13, 16, 16, 16, 16, 15, 16, 14, 14, + 10, 16, 11, 14, 10, 16, 11, 13, 11, 16, 12, 14, 10, 15, 11, 13, + 16, 16, 15, 16, 13, 16, 13, 13, 12, 16, 11, 13, 12, 16, 11, 12, + 12, 16, 11, 13, 11, 14, 11, 11, 13, 16, 12, 13, 12, 14, 11, 11, + }, + { + 0, 10, 5, 10, 6, 11, 8, 10, 7, 12, 8, 11, 8, 12, 9, 10, + 14, 16, 13, 13, 13, 14, 12, 11, 4, 12, 6, 10, 8, 12, 9, 10, + 8, 13, 8, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, + 9, 15, 8, 12, 12, 14, 10, 11, 11, 16, 9, 12, 12, 14, 10, 10, + 14, 16, 11, 13, 13, 15, 11, 11, 4, 12, 8, 11, 6, 11, 9, 10, + 8, 13, 9, 11, 8, 12, 9, 10, 14, 16, 12, 13, 13, 14, 11, 11, + 7, 13, 8, 11, 9, 12, 9, 10, 8, 13, 9, 11, 9, 12, 9, 10, + 14, 16, 12, 13, 12, 13, 11, 10, 11, 16, 10, 12, 12, 14, 10, 11, + 11, 16, 10, 12, 12, 14, 10, 10, 15, 16, 11, 13, 13, 14, 11, 10, + 10, 16, 11, 13, 9, 13, 10, 11, 11, 15, 12, 13, 10, 12, 10, 11, + 15, 16, 13, 14, 12, 13, 11, 11, 11, 16, 11, 13, 10, 13, 10, 11, + 12, 16, 11, 13, 10, 13, 10, 10, 15, 16, 13, 14, 12, 13, 11, 10, + 13, 16, 12, 13, 13, 14, 11, 11, 14, 16, 12, 13, 12, 14, 11, 10, + 16, 16, 13, 13, 13, 14, 11, 9, 3, 11, 6, 10, 6, 11, 9, 10, + 8, 12, 8, 11, 9, 12, 9, 10, 14, 16, 13, 13, 13, 13, 12, 11, + 5, 12, 6, 10, 8, 12, 9, 10, 8, 13, 8, 11, 9, 12, 9, 10, + 14, 16, 12, 13, 13, 14, 11, 11, 9, 15, 8, 11, 11, 14, 10, 10, + 11, 15, 9, 11, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 11, 10, + 5, 12, 8, 11, 7, 11, 9, 10, 8, 13, 9, 11, 9, 12, 9, 10, + 14, 16, 12, 13, 13, 13, 11, 11, 7, 13, 8, 11, 8, 12, 9, 10, + 8, 13, 8, 11, 9, 12, 9, 9, 13, 16, 11, 13, 12, 13, 11, 10, + 10, 15, 9, 12, 11, 14, 10, 10, 11, 15, 9, 11, 11, 13, 10, 10, + 14, 16, 11, 12, 13, 14, 10, 10, 9, 16, 11, 13, 9, 12, 10, 10, + 11, 16, 11, 13, 9, 12, 10, 10, 15, 16, 13, 14, 12, 13, 11, 10, + 11, 16, 11, 13, 10, 13, 10, 10, 11, 15, 11, 13, 9, 12, 10, 10, + 14, 16, 12, 13, 11, 13, 10, 10, 13, 16, 12, 13, 12, 14, 11, 10, + 13, 16, 11, 13, 12, 13, 10, 10, 14, 16, 11, 12, 12, 13, 10, 9, + 7, 14, 8, 12, 9, 13, 10, 11, 10, 14, 10, 12, 11, 13, 11, 11, + 16, 16, 14, 14, 14, 14, 12, 12, 7, 14, 8, 12, 9, 13, 10, 11, + 10, 14, 10, 12, 11, 13, 10, 11, 16, 16, 13, 13, 14, 14, 12, 11, + 10, 15, 9, 12, 12, 14, 10, 10, 12, 16, 9, 12, 12, 14, 10, 10, + 16, 16, 12, 13, 14, 15, 12, 11, 8, 14, 9, 12, 9, 13, 10, 11, + 10, 15, 10, 12, 10, 13, 10, 11, 16, 16, 14, 14, 14, 14, 12, 11, + 8, 14, 9, 12, 9, 13, 10, 11, 10, 14, 10, 12, 10, 13, 10, 10, + 15, 16, 13, 13, 13, 14, 12, 11, 10, 15, 10, 12, 12, 14, 10, 10, + 11, 16, 9, 12, 12, 14, 10, 10, 14, 16, 11, 12, 13, 14, 11, 10, + 11, 16, 11, 14, 9, 13, 10, 11, 12, 16, 12, 14, 10, 13, 11, 11, + 16, 16, 14, 15, 13, 14, 12, 11, 11, 16, 12, 14, 10, 13, 11, 11, + 11, 16, 11, 13, 10, 13, 10, 10, 15, 16, 13, 14, 12, 13, 11, 10, + 13, 16, 12, 14, 13, 14, 11, 10, 12, 16, 11, 13, 12, 13, 10, 10, + 14, 16, 11, 12, 11, 13, 10, 9, 10, 16, 10, 13, 11, 14, 11, 11, + 12, 16, 11, 13, 12, 14, 11, 11, 16, 16, 14, 13, 14, 15, 12, 11, + 10, 16, 10, 13, 10, 14, 11, 11, 12, 16, 11, 13, 11, 14, 11, 11, + 16, 16, 14, 13, 14, 14, 12, 11, 11, 15, 9, 12, 11, 14, 10, 10, + 13, 16, 10, 12, 12, 14, 10, 10, 16, 16, 13, 13, 14, 14, 11, 10, + 10, 16, 10, 13, 11, 14, 11, 11, 12, 16, 11, 13, 12, 14, 11, 11, + 16, 16, 14, 14, 14, 14, 12, 11, 9, 16, 10, 13, 10, 14, 11, 11, + 11, 15, 11, 12, 11, 13, 11, 11, 16, 16, 13, 13, 14, 14, 12, 10, + 10, 15, 9, 12, 11, 14, 10, 10, 11, 16, 9, 11, 11, 13, 10, 9, + 15, 16, 11, 12, 13, 14, 10, 9, 11, 16, 11, 13, 10, 13, 10, 10, + 13, 16, 12, 13, 11, 13, 10, 10, 16, 16, 14, 14, 13, 13, 11, 10, + 11, 16, 11, 13, 10, 13, 10, 10, 12, 16, 11, 13, 10, 13, 10, 10, + 15, 16, 13, 13, 12, 13, 11, 9, 11, 16, 11, 12, 11, 13, 10, 9, + 11, 15, 10, 11, 11, 12, 9, 8, 13, 15, 10, 10, 10, 11, 8, 7, + }, + { + 0, 9, 3, 8, 5, 9, 7, 8, 5, 11, 6, 9, 8, 11, 8, 9, + 16, 16, 16, 16, 16, 16, 11, 10, 2, 10, 4, 9, 7, 10, 7, 8, + 7, 16, 7, 10, 9, 11, 8, 9, 16, 16, 11, 16, 16, 16, 11, 10, + 7, 16, 7, 10, 10, 16, 8, 9, 10, 16, 8, 10, 11, 16, 9, 9, + 16, 16, 16, 16, 16, 16, 11, 10, 3, 11, 6, 9, 6, 11, 8, 8, + 7, 16, 8, 10, 8, 11, 8, 9, 16, 16, 15, 16, 16, 16, 11, 10, + 5, 11, 7, 9, 8, 11, 8, 8, 7, 16, 7, 10, 8, 11, 8, 8, + 16, 16, 11, 16, 16, 16, 10, 9, 9, 16, 8, 11, 11, 16, 9, 9, + 10, 16, 8, 11, 11, 16, 9, 9, 16, 16, 10, 16, 16, 16, 10, 9, + 8, 16, 10, 11, 8, 16, 9, 9, 11, 16, 11, 16, 10, 16, 10, 9, + 16, 16, 16, 16, 16, 16, 11, 10, 9, 16, 10, 16, 10, 16, 9, 9, + 10, 16, 10, 16, 9, 16, 9, 9, 16, 16, 16, 16, 15, 16, 10, 9, + 16, 16, 11, 16, 16, 16, 10, 10, 13, 16, 11, 16, 11, 16, 10, 9, + 16, 16, 10, 11, 11, 16, 9, 8, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 1, 10, 6, 10, 7, 11, 9, 10, 8, 12, 9, 12, 9, 12, 10, 10, + 16, 16, 14, 16, 14, 15, 13, 12, 5, 12, 7, 10, 9, 11, 9, 10, + 9, 13, 9, 12, 10, 13, 10, 10, 16, 16, 14, 15, 14, 14, 13, 12, + 10, 15, 10, 12, 12, 14, 11, 11, 12, 16, 11, 13, 12, 14, 11, 11, + 16, 16, 14, 16, 15, 16, 13, 12, 6, 12, 8, 11, 8, 11, 10, 10, + 9, 13, 10, 12, 10, 12, 10, 10, 15, 16, 13, 15, 13, 14, 12, 12, + 7, 13, 9, 11, 9, 12, 10, 10, 9, 14, 10, 12, 10, 13, 10, 10, + 15, 16, 13, 15, 13, 14, 12, 11, 11, 15, 11, 13, 12, 14, 11, 11, + 12, 16, 11, 13, 12, 14, 11, 11, 16, 16, 13, 15, 14, 16, 12, 11, + 10, 16, 12, 14, 10, 13, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, + 16, 16, 15, 16, 14, 16, 13, 12, 11, 16, 12, 14, 11, 14, 11, 11, + 12, 16, 12, 14, 11, 14, 11, 11, 16, 16, 14, 15, 13, 15, 12, 12, + 13, 16, 13, 15, 13, 15, 12, 12, 13, 16, 12, 15, 12, 15, 11, 11, + 16, 16, 13, 16, 13, 15, 12, 11, 4, 11, 7, 10, 7, 11, 9, 10, + 9, 13, 9, 12, 10, 12, 10, 10, 15, 16, 14, 15, 14, 15, 13, 12, + 6, 12, 7, 11, 9, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 10, + 15, 16, 14, 15, 14, 15, 12, 12, 10, 15, 9, 12, 12, 13, 11, 11, + 12, 15, 11, 13, 12, 14, 11, 11, 16, 16, 13, 15, 14, 16, 12, 12, + 6, 12, 8, 11, 8, 11, 9, 10, 9, 14, 10, 12, 10, 12, 10, 10, + 14, 16, 13, 14, 13, 14, 12, 12, 8, 13, 9, 11, 9, 12, 10, 10, + 9, 13, 9, 12, 9, 12, 9, 10, 14, 16, 13, 14, 13, 14, 12, 11, + 11, 15, 11, 13, 11, 14, 11, 11, 12, 16, 10, 13, 12, 13, 11, 10, + 15, 16, 12, 15, 13, 16, 12, 11, 10, 15, 11, 13, 10, 13, 11, 11, + 12, 16, 12, 14, 11, 13, 11, 11, 16, 16, 14, 15, 13, 16, 13, 12, + 11, 16, 11, 14, 11, 13, 11, 11, 12, 16, 12, 14, 10, 13, 11, 11, + 15, 16, 13, 16, 12, 14, 12, 11, 12, 16, 12, 14, 12, 15, 11, 11, + 13, 16, 12, 14, 12, 14, 11, 11, 15, 16, 13, 15, 13, 15, 11, 10, + 7, 13, 9, 12, 10, 13, 11, 11, 11, 15, 12, 13, 12, 13, 11, 11, + 16, 16, 15, 16, 16, 16, 14, 13, 8, 13, 9, 12, 10, 13, 11, 11, + 12, 15, 11, 13, 12, 13, 11, 11, 16, 16, 14, 15, 15, 16, 13, 12, + 11, 16, 11, 13, 12, 14, 11, 11, 13, 16, 12, 14, 13, 15, 12, 11, + 16, 16, 14, 16, 15, 16, 13, 12, 9, 15, 10, 13, 10, 13, 11, 11, + 12, 15, 11, 13, 11, 13, 11, 11, 16, 16, 14, 16, 16, 16, 13, 12, + 9, 14, 10, 13, 10, 13, 11, 11, 11, 14, 11, 13, 11, 13, 11, 11, + 16, 16, 14, 16, 14, 16, 12, 12, 11, 16, 11, 14, 12, 14, 12, 11, + 12, 16, 11, 13, 13, 14, 11, 11, 16, 16, 13, 15, 14, 16, 12, 11, + 12, 16, 12, 14, 11, 14, 11, 11, 13, 16, 13, 14, 12, 15, 12, 11, + 16, 16, 16, 16, 14, 16, 13, 12, 12, 16, 12, 14, 11, 14, 12, 11, + 12, 16, 12, 15, 11, 14, 11, 11, 16, 16, 14, 16, 13, 15, 12, 12, + 13, 16, 13, 16, 13, 16, 12, 12, 13, 16, 12, 15, 12, 16, 11, 11, + 14, 16, 12, 15, 12, 15, 11, 10, 9, 16, 11, 14, 12, 14, 12, 12, + 13, 16, 13, 15, 14, 16, 12, 12, 16, 16, 16, 16, 16, 16, 14, 13, + 10, 16, 11, 14, 12, 14, 12, 12, 13, 16, 13, 14, 13, 16, 12, 12, + 16, 16, 15, 16, 16, 16, 13, 12, 11, 16, 11, 14, 12, 15, 12, 11, + 13, 16, 12, 14, 13, 16, 12, 11, 16, 16, 14, 16, 16, 16, 13, 12, + 11, 16, 11, 14, 12, 14, 12, 12, 13, 16, 12, 15, 13, 16, 12, 12, + 16, 16, 16, 16, 16, 16, 14, 13, 10, 16, 11, 14, 11, 15, 11, 11, + 13, 16, 12, 14, 12, 14, 12, 11, 16, 16, 14, 16, 16, 16, 13, 12, + 11, 16, 11, 15, 12, 15, 12, 11, 13, 16, 11, 14, 13, 15, 12, 11, + 16, 16, 13, 16, 14, 16, 12, 11, 12, 16, 12, 15, 11, 15, 12, 11, + 14, 16, 13, 15, 12, 16, 12, 11, 16, 16, 15, 16, 14, 16, 13, 12, + 11, 16, 12, 15, 11, 15, 11, 11, 13, 16, 13, 16, 11, 15, 11, 11, + 16, 16, 14, 16, 13, 15, 12, 11, 12, 16, 12, 15, 12, 16, 11, 11, + 12, 16, 11, 15, 12, 14, 11, 11, 13, 16, 12, 13, 11, 13, 10, 9, + }, + }, + { + { + 0, 13, 6, 13, 8, 14, 12, 16, 8, 16, 11, 16, 12, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 16, 7, 14, 11, 16, 13, 16, + 9, 16, 11, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 10, 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 5, 16, 10, 16, 8, 16, 13, 16, + 10, 16, 12, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 10, 16, 11, 16, 13, 16, 10, 16, 12, 16, 12, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 12, 16, 16, 16, 16, 16, + 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 11, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, + 14, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 1, 13, 7, 13, 8, 16, 12, 16, + 8, 16, 10, 16, 11, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 4, 16, 7, 14, 10, 16, 12, 16, 9, 16, 10, 16, 12, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 9, 16, 14, 16, 14, 16, + 13, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 16, 9, 16, 8, 16, 12, 16, 9, 16, 11, 16, 11, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 7, 16, 10, 16, 11, 16, 13, 16, + 9, 16, 11, 16, 11, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 12, 16, 16, 16, 14, 16, 13, 16, 12, 16, 16, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 13, 16, 11, 16, 14, 16, + 13, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 14, 16, 13, 16, 14, 16, 13, 16, 14, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 4, 16, 8, 16, 9, 16, 13, 16, 10, 16, 11, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 8, 16, 11, 16, 13, 16, + 10, 16, 11, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 16, 9, 16, 13, 16, 13, 16, 13, 16, 12, 16, 16, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 10, 16, 10, 16, 13, 16, + 10, 16, 12, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 10, 16, 11, 16, 13, 16, 10, 16, 11, 16, 12, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 16, 16, 16, 14, 16, + 12, 16, 11, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 13, 16, 10, 16, 13, 16, 13, 16, 16, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 13, 16, 12, 16, 14, 16, + 12, 16, 15, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 10, 16, 10, 16, 13, 16, + 11, 16, 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 9, 16, 11, 16, 12, 16, 11, 16, 11, 16, 12, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 9, 16, 12, 16, 12, 16, + 13, 16, 11, 16, 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 10, 16, 10, 16, 12, 16, 11, 16, 12, 16, 12, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 10, 16, 11, 16, 12, 16, + 10, 16, 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 10, 14, 12, 16, 12, 16, 11, 16, 10, 14, 13, 16, 12, 14, + 16, 16, 14, 16, 16, 16, 14, 16, 9, 16, 12, 16, 10, 16, 12, 16, + 13, 16, 13, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 12, 16, 11, 16, 12, 16, 11, 16, 12, 16, 11, 16, 12, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 12, 16, 13, 16, 12, 13, + 12, 16, 12, 16, 12, 16, 12, 13, 16, 16, 13, 14, 13, 16, 13, 13, + }, + { + 0, 10, 5, 10, 5, 10, 8, 10, 6, 11, 8, 11, 8, 11, 9, 10, + 14, 16, 13, 14, 13, 14, 12, 12, 4, 12, 5, 10, 8, 12, 9, 10, + 7, 12, 8, 11, 9, 12, 9, 10, 14, 16, 12, 13, 13, 14, 12, 12, + 9, 16, 8, 12, 12, 14, 10, 11, 11, 16, 9, 12, 12, 14, 11, 11, + 14, 16, 12, 13, 14, 15, 12, 12, 4, 12, 7, 11, 6, 11, 9, 10, + 8, 12, 9, 11, 8, 11, 9, 10, 14, 16, 12, 14, 13, 14, 12, 12, + 7, 13, 8, 11, 8, 12, 9, 10, 8, 13, 8, 11, 9, 12, 9, 10, + 14, 16, 12, 13, 12, 13, 11, 11, 11, 16, 10, 12, 12, 14, 11, 11, + 12, 16, 10, 12, 12, 14, 11, 11, 16, 16, 12, 13, 14, 15, 12, 11, + 10, 16, 11, 14, 9, 13, 10, 11, 11, 16, 12, 14, 10, 13, 11, 11, + 15, 16, 13, 14, 13, 14, 12, 12, 11, 16, 12, 14, 10, 13, 11, 11, + 12, 16, 12, 14, 11, 13, 11, 11, 15, 16, 13, 14, 13, 14, 12, 11, + 14, 16, 13, 14, 13, 15, 12, 12, 14, 16, 12, 14, 13, 15, 11, 11, + 16, 16, 13, 14, 14, 15, 12, 11, 3, 11, 5, 10, 6, 11, 9, 10, + 7, 12, 8, 11, 9, 11, 9, 10, 14, 16, 13, 13, 13, 14, 12, 12, + 5, 12, 6, 10, 8, 12, 9, 10, 8, 13, 8, 11, 9, 12, 9, 10, + 14, 16, 12, 13, 13, 14, 12, 12, 9, 16, 8, 11, 11, 14, 10, 11, + 11, 16, 9, 12, 12, 14, 10, 11, 15, 16, 12, 13, 14, 15, 12, 11, + 5, 12, 7, 11, 6, 11, 9, 10, 8, 13, 9, 11, 8, 11, 9, 10, + 14, 16, 12, 14, 13, 13, 12, 12, 7, 13, 8, 11, 8, 12, 9, 10, + 8, 12, 8, 11, 9, 12, 9, 10, 13, 16, 12, 13, 12, 13, 11, 11, + 10, 16, 9, 12, 12, 14, 10, 11, 11, 15, 9, 12, 12, 14, 10, 11, + 14, 16, 11, 13, 13, 14, 11, 11, 9, 16, 11, 14, 8, 13, 10, 11, + 11, 16, 12, 13, 10, 13, 10, 11, 16, 16, 13, 15, 13, 14, 12, 12, + 11, 16, 11, 14, 10, 13, 10, 11, 11, 16, 11, 13, 10, 13, 10, 11, + 14, 16, 13, 14, 12, 13, 11, 11, 14, 16, 12, 14, 13, 15, 11, 11, + 13, 16, 12, 13, 12, 14, 11, 11, 14, 16, 12, 13, 12, 13, 11, 10, + 6, 14, 8, 12, 9, 13, 10, 11, 10, 14, 10, 12, 11, 13, 11, 12, + 16, 16, 14, 14, 14, 14, 13, 12, 7, 14, 8, 12, 9, 13, 10, 11, + 10, 14, 10, 12, 11, 13, 11, 11, 16, 16, 13, 14, 14, 15, 13, 12, + 10, 16, 8, 12, 12, 14, 10, 11, 12, 16, 10, 12, 13, 15, 11, 11, + 16, 16, 13, 14, 15, 16, 12, 12, 8, 15, 9, 13, 9, 13, 10, 11, + 10, 15, 10, 13, 10, 13, 11, 11, 16, 16, 14, 14, 14, 14, 13, 12, + 8, 15, 9, 12, 10, 13, 10, 11, 10, 14, 10, 12, 10, 13, 10, 11, + 16, 16, 13, 14, 13, 14, 12, 12, 10, 16, 10, 13, 12, 15, 11, 11, + 11, 16, 9, 12, 12, 14, 11, 11, 14, 16, 11, 13, 14, 16, 12, 11, + 10, 16, 12, 14, 9, 13, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, + 16, 16, 15, 16, 14, 14, 13, 12, 11, 16, 12, 14, 11, 14, 11, 11, + 11, 16, 12, 14, 10, 13, 11, 11, 15, 16, 13, 15, 12, 14, 12, 11, + 14, 16, 13, 14, 13, 16, 12, 12, 12, 16, 12, 13, 12, 14, 11, 11, + 14, 16, 11, 12, 12, 13, 10, 10, 9, 16, 10, 14, 11, 15, 12, 12, + 12, 16, 11, 13, 12, 15, 12, 12, 16, 16, 14, 13, 15, 15, 13, 12, + 10, 16, 10, 14, 11, 15, 11, 12, 12, 16, 11, 13, 12, 14, 12, 12, + 16, 16, 14, 13, 15, 14, 13, 12, 11, 16, 9, 12, 12, 14, 11, 11, + 13, 16, 11, 13, 13, 15, 11, 11, 16, 16, 14, 14, 16, 16, 12, 12, + 10, 16, 10, 14, 11, 14, 11, 12, 12, 16, 11, 13, 12, 14, 12, 12, + 16, 16, 14, 14, 15, 15, 13, 12, 10, 16, 10, 13, 11, 14, 11, 12, + 11, 16, 11, 13, 11, 14, 11, 12, 16, 16, 14, 14, 14, 14, 13, 12, + 11, 16, 10, 12, 12, 15, 11, 11, 12, 16, 9, 12, 12, 14, 10, 11, + 16, 16, 12, 13, 14, 15, 11, 11, 11, 16, 12, 14, 10, 14, 11, 11, + 13, 16, 12, 14, 12, 14, 11, 11, 16, 16, 15, 15, 14, 15, 12, 12, + 11, 16, 12, 14, 11, 14, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, + 16, 16, 14, 14, 13, 14, 12, 11, 12, 16, 11, 13, 12, 14, 10, 10, + 12, 15, 11, 12, 12, 13, 10, 10, 14, 15, 11, 11, 12, 12, 10, 9, + }, + { + 0, 8, 3, 8, 5, 9, 7, 8, 5, 10, 6, 10, 8, 11, 8, 9, + 16, 16, 15, 16, 16, 16, 11, 11, 2, 10, 4, 9, 7, 10, 7, 8, + 7, 16, 7, 10, 9, 11, 8, 9, 16, 16, 15, 16, 16, 16, 11, 11, + 7, 16, 6, 11, 10, 16, 9, 10, 10, 16, 9, 11, 11, 16, 9, 10, + 16, 16, 16, 16, 16, 16, 16, 11, 3, 10, 6, 9, 5, 10, 7, 9, + 7, 16, 8, 10, 8, 11, 8, 9, 16, 16, 16, 16, 16, 16, 11, 11, + 5, 11, 7, 10, 8, 11, 8, 9, 7, 14, 7, 10, 8, 11, 8, 9, + 16, 16, 11, 16, 16, 16, 10, 11, 9, 16, 9, 11, 11, 16, 9, 10, + 10, 16, 8, 11, 11, 16, 9, 10, 16, 16, 11, 16, 16, 16, 11, 10, + 8, 16, 9, 16, 7, 16, 9, 10, 11, 16, 11, 16, 10, 16, 10, 10, + 16, 16, 16, 16, 16, 16, 16, 11, 9, 16, 10, 16, 9, 16, 9, 10, + 10, 16, 10, 16, 9, 16, 9, 10, 16, 16, 16, 16, 11, 16, 11, 11, + 16, 16, 16, 16, 16, 16, 10, 10, 11, 16, 11, 16, 11, 16, 10, 10, + 16, 16, 11, 16, 11, 16, 10, 9, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 1, 10, 6, 10, 7, 11, 9, 10, 8, 12, 9, 12, 9, 12, 10, 10, + 15, 16, 14, 15, 14, 16, 13, 12, 5, 12, 7, 11, 8, 11, 9, 10, + 9, 13, 9, 12, 10, 12, 10, 10, 16, 16, 14, 15, 13, 16, 13, 12, + 10, 15, 10, 13, 12, 14, 11, 11, 12, 16, 11, 13, 12, 14, 11, 11, + 16, 16, 14, 16, 14, 16, 13, 12, 5, 12, 8, 11, 7, 11, 9, 10, + 9, 13, 10, 12, 9, 12, 10, 10, 14, 16, 14, 15, 13, 14, 13, 12, + 7, 13, 9, 12, 9, 12, 10, 10, 9, 13, 9, 12, 9, 12, 10, 10, + 14, 16, 13, 14, 13, 15, 12, 12, 11, 16, 11, 13, 12, 14, 11, 11, + 12, 16, 11, 14, 12, 14, 11, 11, 16, 16, 14, 16, 14, 16, 13, 12, + 10, 16, 11, 14, 10, 13, 11, 11, 12, 16, 12, 14, 11, 13, 11, 11, + 15, 16, 15, 16, 14, 16, 13, 12, 11, 16, 12, 14, 11, 14, 11, 12, + 12, 16, 12, 14, 11, 14, 11, 11, 15, 16, 14, 16, 13, 16, 13, 12, + 13, 16, 13, 16, 13, 16, 12, 12, 13, 16, 13, 16, 13, 16, 12, 12, + 16, 16, 14, 15, 14, 16, 13, 12, 4, 11, 7, 10, 7, 11, 9, 10, + 9, 13, 9, 11, 9, 12, 10, 10, 15, 16, 14, 15, 14, 15, 13, 12, + 6, 12, 7, 11, 8, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 10, + 15, 16, 13, 14, 14, 15, 12, 12, 10, 14, 10, 12, 12, 13, 11, 11, + 12, 16, 11, 13, 12, 14, 11, 11, 16, 16, 14, 15, 15, 16, 13, 12, + 6, 12, 8, 11, 8, 11, 9, 10, 9, 13, 10, 12, 9, 12, 10, 10, + 16, 16, 14, 15, 13, 14, 12, 12, 8, 13, 9, 11, 9, 12, 9, 10, + 9, 13, 9, 12, 9, 12, 9, 10, 14, 16, 13, 14, 13, 14, 12, 11, + 11, 15, 11, 13, 12, 14, 11, 11, 11, 16, 10, 13, 12, 14, 11, 11, + 15, 16, 13, 15, 14, 16, 12, 11, 10, 16, 12, 13, 10, 13, 11, 11, + 11, 16, 12, 14, 10, 13, 11, 11, 16, 16, 14, 16, 13, 16, 13, 12, + 11, 16, 12, 14, 10, 14, 11, 11, 11, 16, 12, 14, 10, 13, 11, 11, + 16, 16, 14, 16, 12, 15, 12, 11, 13, 16, 13, 15, 13, 15, 12, 12, + 13, 16, 12, 15, 12, 15, 12, 11, 15, 16, 13, 16, 13, 16, 12, 11, + 8, 14, 9, 12, 10, 13, 11, 11, 11, 16, 11, 13, 11, 13, 11, 11, + 16, 16, 16, 16, 16, 16, 14, 13, 9, 14, 10, 12, 10, 13, 11, 11, + 11, 16, 11, 13, 12, 13, 11, 11, 16, 16, 15, 16, 15, 16, 14, 12, + 11, 16, 11, 13, 12, 14, 12, 11, 13, 16, 12, 14, 13, 14, 12, 11, + 16, 16, 15, 16, 16, 16, 14, 13, 9, 14, 10, 13, 10, 13, 11, 11, + 11, 16, 11, 13, 11, 13, 11, 11, 16, 16, 15, 16, 14, 15, 14, 13, + 9, 14, 10, 13, 10, 13, 11, 11, 11, 15, 11, 13, 11, 13, 11, 11, + 16, 16, 14, 16, 14, 16, 13, 12, 12, 16, 12, 14, 13, 14, 12, 11, + 12, 16, 11, 14, 12, 15, 12, 11, 16, 16, 13, 16, 15, 16, 13, 11, + 11, 16, 12, 14, 11, 14, 12, 11, 13, 16, 13, 15, 12, 14, 12, 12, + 16, 16, 16, 16, 14, 16, 14, 13, 12, 16, 13, 15, 11, 14, 12, 12, + 12, 16, 13, 14, 11, 15, 12, 11, 16, 16, 15, 16, 13, 15, 13, 12, + 13, 16, 13, 15, 13, 16, 12, 12, 13, 16, 13, 15, 13, 15, 12, 12, + 15, 16, 13, 16, 13, 15, 11, 10, 10, 16, 12, 14, 12, 15, 12, 12, + 14, 16, 13, 15, 13, 16, 13, 12, 16, 16, 16, 16, 16, 16, 15, 13, + 10, 16, 12, 14, 12, 15, 12, 12, 13, 16, 13, 15, 13, 15, 13, 12, + 16, 16, 16, 16, 16, 16, 14, 13, 11, 16, 12, 15, 13, 16, 12, 12, + 14, 16, 13, 16, 13, 16, 12, 12, 16, 16, 15, 16, 15, 16, 14, 12, + 11, 16, 12, 14, 12, 16, 12, 12, 14, 16, 13, 15, 13, 15, 13, 12, + 16, 16, 16, 16, 16, 16, 15, 13, 11, 16, 12, 14, 12, 15, 12, 12, + 13, 16, 12, 14, 12, 15, 12, 12, 16, 16, 16, 16, 16, 16, 14, 12, + 12, 16, 12, 15, 13, 16, 12, 12, 13, 16, 12, 15, 13, 15, 12, 11, + 16, 16, 14, 16, 15, 16, 13, 12, 12, 16, 13, 16, 12, 16, 12, 12, + 15, 16, 14, 16, 13, 16, 12, 12, 16, 16, 16, 16, 16, 16, 14, 13, + 12, 16, 13, 15, 12, 16, 12, 12, 13, 16, 13, 15, 12, 15, 12, 12, + 16, 16, 15, 16, 14, 16, 13, 12, 13, 16, 13, 16, 12, 16, 12, 12, + 13, 16, 12, 16, 12, 15, 12, 12, 14, 16, 12, 14, 12, 14, 11, 10, + }, + }, + { + { + 0, 16, 6, 16, 8, 16, 16, 16, 9, 16, 11, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 16, 7, 16, 11, 16, 16, 16, + 10, 16, 11, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 10, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 5, 16, 10, 16, 9, 16, 16, 16, + 10, 16, 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 11, 16, 12, 16, 16, 16, 10, 16, 12, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 7, 16, 8, 16, 13, 16, + 9, 16, 11, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 4, 16, 7, 16, 11, 16, 13, 16, 9, 16, 11, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 9, 16, 16, 16, 16, 16, + 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 4, 16, 10, 16, 8, 16, 16, 16, 10, 16, 12, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 7, 16, 10, 16, 11, 16, 16, 16, + 9, 16, 11, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 12, 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 16, 16, 11, 16, 16, 16, + 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 4, 16, 8, 16, 10, 16, 16, 16, 10, 16, 11, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 8, 16, 11, 16, 16, 16, + 10, 16, 12, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 16, 9, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 10, 16, 10, 16, 16, 16, + 11, 16, 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 11, 16, 11, 16, 16, 16, 10, 16, 12, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 12, 16, 16, 16, 16, 16, + 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 16, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 12, 16, 16, 16, + 12, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 10, 16, 11, 16, 16, 16, + 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 9, 16, 11, 16, 13, 16, 11, 16, 12, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 9, 16, 13, 16, 12, 16, + 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 10, 16, 10, 16, 14, 16, 12, 16, 12, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 11, 16, 11, 16, 13, 16, + 10, 16, 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 10, 16, 13, 16, 12, 16, 12, 16, 11, 16, 16, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 12, 16, 10, 16, 13, 16, + 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 13, 16, 11, 16, 13, 16, 12, 16, 13, 16, 12, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 13, 16, 16, 16, 12, 16, + 13, 16, 12, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 0, 10, 4, 10, 5, 11, 9, 11, 6, 11, 8, 11, 8, 12, 10, 12, + 15, 16, 13, 15, 14, 15, 13, 14, 4, 12, 5, 11, 8, 12, 9, 11, + 7, 13, 8, 12, 9, 13, 10, 12, 15, 16, 13, 15, 14, 16, 13, 14, + 10, 16, 9, 13, 12, 16, 11, 13, 11, 16, 10, 14, 13, 16, 12, 13, + 16, 16, 14, 16, 15, 16, 14, 15, 4, 12, 7, 12, 6, 12, 9, 11, + 8, 13, 9, 12, 9, 12, 10, 12, 15, 16, 13, 15, 14, 15, 13, 14, + 7, 13, 8, 12, 9, 13, 10, 12, 8, 13, 9, 12, 9, 13, 10, 12, + 14, 16, 13, 15, 13, 15, 13, 14, 12, 16, 11, 14, 13, 16, 12, 13, + 12, 16, 11, 14, 13, 16, 12, 13, 16, 16, 14, 16, 15, 16, 14, 15, + 10, 16, 12, 16, 10, 14, 12, 13, 12, 16, 13, 16, 11, 14, 12, 13, + 16, 16, 16, 16, 15, 16, 14, 15, 12, 16, 13, 16, 11, 15, 12, 13, + 13, 16, 13, 16, 12, 15, 12, 14, 16, 16, 16, 16, 14, 16, 13, 14, + 16, 16, 14, 16, 14, 16, 13, 15, 16, 16, 14, 16, 14, 16, 13, 15, + 16, 16, 16, 16, 16, 16, 14, 16, 2, 11, 5, 11, 6, 11, 9, 11, + 7, 12, 8, 11, 9, 12, 10, 12, 15, 16, 14, 14, 14, 14, 13, 14, + 4, 13, 6, 11, 8, 12, 9, 11, 8, 13, 8, 12, 10, 13, 10, 12, + 15, 16, 13, 15, 14, 15, 13, 14, 9, 16, 8, 13, 12, 15, 11, 12, + 11, 16, 10, 14, 13, 16, 12, 13, 16, 16, 14, 16, 16, 16, 14, 15, + 5, 13, 8, 12, 7, 12, 9, 11, 8, 13, 9, 12, 9, 12, 10, 12, + 16, 16, 14, 15, 14, 15, 13, 13, 7, 13, 8, 12, 9, 13, 10, 12, + 8, 13, 8, 12, 9, 13, 10, 12, 14, 16, 13, 14, 13, 15, 12, 13, + 11, 16, 10, 14, 13, 16, 12, 13, 11, 16, 10, 13, 12, 15, 11, 13, + 14, 16, 12, 14, 14, 16, 13, 14, 10, 16, 12, 15, 9, 14, 11, 13, + 12, 16, 12, 16, 11, 14, 12, 13, 16, 16, 15, 16, 16, 16, 14, 15, + 11, 16, 12, 15, 11, 15, 12, 13, 12, 16, 12, 15, 11, 14, 12, 13, + 16, 16, 14, 16, 13, 15, 13, 14, 15, 16, 14, 16, 14, 16, 13, 14, + 14, 16, 13, 16, 14, 16, 13, 14, 16, 16, 14, 16, 14, 16, 13, 14, + 7, 15, 8, 13, 9, 14, 11, 13, 10, 14, 10, 13, 11, 14, 12, 13, + 16, 16, 15, 16, 15, 16, 15, 14, 7, 16, 8, 13, 10, 14, 11, 13, + 11, 15, 10, 13, 12, 14, 12, 13, 16, 16, 16, 16, 16, 16, 15, 15, + 10, 16, 9, 13, 13, 16, 12, 13, 13, 16, 11, 14, 14, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 15, 16, 8, 16, 10, 14, 9, 14, 11, 13, + 11, 16, 11, 14, 11, 14, 12, 13, 16, 16, 16, 16, 16, 16, 14, 15, + 8, 16, 10, 14, 10, 14, 11, 13, 10, 15, 10, 14, 11, 14, 12, 13, + 16, 16, 14, 16, 15, 16, 14, 14, 11, 16, 10, 14, 13, 16, 12, 13, + 11, 16, 10, 13, 13, 16, 12, 13, 16, 16, 13, 16, 16, 16, 14, 14, + 11, 16, 12, 16, 10, 15, 12, 13, 14, 16, 14, 16, 12, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 13, 16, 11, 16, 12, 14, + 12, 16, 13, 16, 11, 14, 12, 13, 16, 16, 16, 16, 14, 16, 14, 14, + 15, 16, 14, 16, 16, 16, 13, 14, 13, 16, 13, 15, 14, 16, 13, 14, + 14, 16, 13, 14, 14, 15, 13, 14, 9, 16, 11, 16, 12, 16, 13, 14, + 12, 16, 12, 15, 13, 16, 13, 14, 16, 16, 16, 15, 16, 16, 15, 15, + 10, 16, 10, 16, 12, 16, 12, 14, 12, 16, 12, 14, 13, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 15, 15, 11, 16, 10, 14, 14, 16, 12, 13, + 14, 16, 12, 16, 14, 16, 13, 14, 16, 16, 16, 16, 16, 16, 16, 15, + 10, 16, 12, 16, 11, 16, 12, 14, 13, 16, 12, 15, 13, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 16, 15, 10, 16, 11, 16, 12, 16, 12, 14, + 12, 16, 12, 15, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 14, 14, + 11, 16, 10, 14, 14, 16, 12, 13, 13, 16, 11, 14, 14, 16, 12, 13, + 16, 16, 15, 16, 16, 16, 14, 14, 12, 16, 13, 16, 11, 16, 12, 14, + 15, 16, 14, 16, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 14, 16, + 12, 16, 13, 16, 12, 16, 12, 14, 13, 16, 13, 16, 12, 16, 12, 13, + 16, 16, 16, 16, 16, 16, 14, 15, 13, 16, 13, 16, 14, 16, 12, 13, + 13, 16, 13, 14, 14, 16, 12, 13, 16, 16, 14, 14, 14, 15, 13, 13, + }, + { + 0, 9, 3, 9, 5, 9, 7, 9, 5, 10, 7, 11, 8, 11, 9, 10, + 16, 16, 16, 16, 16, 16, 16, 16, 2, 11, 4, 10, 7, 11, 8, 10, + 7, 16, 7, 11, 9, 16, 9, 11, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 7, 16, 11, 16, 10, 11, 11, 16, 10, 16, 16, 16, 11, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 2, 11, 6, 10, 6, 10, 8, 10, + 7, 16, 8, 16, 8, 11, 9, 11, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 13, 7, 11, 8, 11, 9, 11, 6, 12, 8, 12, 8, 12, 9, 11, + 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 10, 16, 12, 16, 10, 13, + 10, 16, 9, 16, 11, 16, 11, 12, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 10, 16, 8, 16, 10, 12, 11, 16, 12, 16, 10, 16, 11, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 11, 16, 10, 16, 11, 16, + 11, 16, 12, 16, 10, 16, 11, 12, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 1, 10, 5, 10, 6, 10, 9, 10, 7, 12, 9, 12, 9, 12, 10, 10, + 16, 16, 15, 16, 14, 16, 13, 13, 5, 12, 7, 11, 8, 11, 9, 10, + 8, 13, 9, 12, 10, 12, 10, 11, 16, 16, 16, 16, 14, 16, 13, 12, + 10, 16, 10, 13, 12, 14, 12, 12, 12, 16, 11, 14, 13, 15, 12, 12, + 16, 16, 16, 15, 16, 16, 14, 13, 5, 12, 8, 11, 7, 11, 9, 10, + 8, 13, 10, 12, 9, 12, 10, 10, 15, 16, 14, 15, 14, 14, 13, 13, + 7, 13, 9, 12, 9, 12, 10, 10, 9, 13, 10, 13, 10, 13, 10, 10, + 14, 16, 14, 15, 14, 16, 13, 12, 11, 16, 12, 14, 12, 15, 12, 12, + 12, 16, 12, 15, 13, 16, 12, 12, 16, 16, 15, 16, 16, 16, 14, 13, + 10, 16, 12, 14, 10, 14, 12, 12, 12, 16, 13, 14, 11, 14, 12, 12, + 16, 16, 16, 16, 14, 16, 14, 13, 11, 16, 12, 14, 11, 14, 12, 12, + 12, 16, 13, 16, 11, 15, 12, 12, 16, 16, 16, 16, 14, 16, 14, 13, + 13, 16, 14, 16, 14, 16, 13, 13, 13, 16, 13, 16, 13, 16, 13, 12, + 16, 16, 16, 16, 16, 16, 13, 13, 4, 11, 7, 10, 7, 11, 9, 10, + 8, 12, 9, 12, 9, 12, 10, 11, 15, 16, 14, 15, 14, 16, 13, 13, + 6, 12, 7, 11, 8, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 10, + 16, 16, 15, 16, 15, 16, 13, 12, 10, 16, 10, 13, 12, 14, 12, 11, + 12, 16, 11, 14, 13, 14, 12, 12, 16, 16, 16, 14, 16, 16, 14, 13, + 6, 12, 8, 11, 7, 11, 9, 10, 9, 14, 10, 12, 9, 12, 10, 10, + 15, 16, 14, 16, 14, 16, 14, 13, 7, 13, 9, 12, 9, 12, 10, 10, + 9, 13, 9, 12, 9, 12, 10, 10, 14, 16, 13, 14, 14, 16, 12, 11, + 11, 16, 11, 14, 12, 14, 12, 12, 12, 16, 11, 14, 12, 14, 12, 11, + 16, 16, 13, 16, 14, 16, 13, 12, 10, 16, 12, 14, 10, 14, 11, 11, + 12, 16, 13, 14, 11, 14, 12, 12, 16, 16, 16, 16, 14, 16, 13, 13, + 11, 16, 12, 16, 11, 14, 12, 12, 12, 16, 12, 14, 11, 14, 12, 11, + 16, 16, 15, 16, 13, 15, 13, 12, 13, 16, 14, 16, 13, 16, 13, 12, + 13, 16, 13, 16, 13, 16, 13, 12, 16, 16, 14, 16, 14, 16, 12, 11, + 8, 13, 10, 12, 10, 13, 11, 11, 11, 14, 12, 14, 12, 14, 12, 12, + 16, 16, 16, 16, 16, 16, 14, 13, 9, 14, 10, 13, 10, 13, 11, 11, + 12, 16, 12, 13, 12, 13, 12, 11, 16, 16, 16, 16, 16, 16, 15, 14, + 12, 16, 11, 14, 13, 15, 12, 12, 13, 16, 12, 15, 14, 15, 13, 12, + 16, 16, 16, 16, 16, 16, 15, 13, 9, 14, 11, 13, 10, 13, 11, 11, + 11, 16, 12, 14, 12, 14, 12, 12, 16, 16, 16, 16, 16, 16, 16, 13, + 10, 15, 11, 13, 11, 14, 12, 11, 11, 16, 12, 14, 11, 14, 12, 11, + 16, 16, 16, 16, 16, 16, 14, 12, 12, 16, 12, 14, 13, 15, 13, 12, + 12, 16, 12, 14, 13, 15, 12, 12, 16, 16, 14, 16, 16, 16, 14, 12, + 12, 16, 13, 16, 11, 14, 12, 12, 14, 16, 14, 16, 12, 16, 13, 12, + 16, 16, 16, 16, 16, 16, 16, 13, 12, 16, 13, 16, 12, 16, 13, 12, + 12, 16, 13, 16, 12, 16, 12, 12, 16, 16, 16, 16, 14, 16, 14, 12, + 14, 16, 14, 16, 14, 16, 14, 13, 13, 16, 13, 16, 13, 16, 13, 12, + 16, 16, 13, 16, 13, 16, 12, 11, 9, 16, 12, 15, 13, 16, 13, 12, + 13, 16, 14, 16, 14, 16, 14, 13, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 16, 12, 15, 12, 15, 13, 12, 13, 16, 14, 16, 13, 16, 13, 12, + 16, 16, 16, 16, 16, 16, 16, 13, 12, 16, 12, 16, 13, 16, 13, 12, + 14, 16, 13, 16, 14, 16, 13, 12, 16, 16, 16, 16, 16, 16, 16, 13, + 11, 16, 12, 15, 12, 16, 13, 12, 14, 16, 14, 16, 13, 16, 13, 13, + 16, 16, 16, 16, 16, 16, 15, 13, 11, 16, 12, 16, 12, 16, 13, 12, + 13, 16, 13, 15, 13, 16, 13, 12, 16, 16, 16, 16, 16, 16, 15, 13, + 12, 16, 12, 16, 13, 16, 13, 12, 13, 16, 12, 16, 13, 16, 13, 12, + 16, 16, 14, 16, 16, 16, 14, 12, 12, 16, 14, 16, 11, 16, 13, 12, + 14, 16, 14, 16, 13, 16, 13, 12, 16, 16, 16, 16, 16, 16, 16, 13, + 12, 16, 13, 16, 12, 16, 13, 12, 13, 16, 13, 16, 12, 16, 13, 12, + 16, 16, 16, 16, 14, 16, 14, 12, 13, 16, 13, 16, 13, 16, 13, 13, + 13, 16, 12, 16, 12, 16, 12, 12, 14, 16, 13, 15, 13, 16, 12, 11, + }, + }, +}; + + +static const uint8_t rv34_table_intra_secondpat[NUM_INTRA_TABLES][2][OTHERBLK_VLC_SIZE] = { + { + { + 0, 5, 10, 3, 6, 10, 7, 8, 9, 4, 6, 10, 6, 7, 9, 8, + 8, 9, 8, 8, 9, 8, 9, 9, 9, 9, 8, 3, 6, 10, 4, 6, + 10, 7, 7, 9, 5, 7, 10, 6, 7, 9, 7, 7, 8, 7, 8, 9, + 8, 8, 9, 8, 8, 7, 6, 8, 10, 6, 8, 10, 7, 8, 9, 7, + 8, 10, 7, 8, 10, 8, 8, 8, 8, 9, 9, 8, 8, 9, 9, 8, + 7, 7, 8, 9, 7, 8, 9, 7, 7, 7, 8, 8, 9, 7, 8, 9, + 7, 7, 7, 8, 8, 8, 7, 7, 7, 7, 6, 5, + }, + { + 0, 5, 11, 3, 6, 11, 8, 9, 11, 3, 6, 10, 6, 7, 11, 9, + 9, 11, 7, 9, 11, 9, 9, 11, 10, 10, 11, 2, 6, 10, 4, 7, + 10, 7, 9, 11, 4, 7, 11, 6, 7, 10, 9, 9, 11, 7, 9, 11, + 8, 9, 10, 10, 10, 10, 5, 8, 11, 6, 8, 11, 8, 9, 11, 6, + 8, 11, 7, 8, 11, 9, 9, 11, 8, 10, 11, 9, 9, 11, 10, 10, + 10, 8, 9, 11, 8, 9, 11, 9, 9, 10, 8, 9, 11, 8, 9, 11, + 9, 9, 10, 8, 9, 10, 9, 9, 10, 9, 9, 8, + }, + }, + { + { + 0, 5, 10, 4, 6, 10, 7, 8, 10, 4, 6, 10, 6, 7, 9, 8, + 8, 9, 8, 8, 9, 8, 9, 9, 9, 9, 9, 2, 6, 10, 4, 6, + 10, 7, 7, 9, 5, 7, 10, 6, 7, 9, 7, 7, 9, 7, 8, 9, + 8, 8, 9, 9, 8, 8, 6, 8, 10, 6, 8, 10, 7, 8, 9, 6, + 8, 10, 7, 8, 10, 8, 8, 9, 8, 9, 10, 8, 8, 9, 9, 9, + 8, 8, 8, 10, 7, 8, 9, 7, 8, 8, 7, 8, 10, 7, 8, 9, + 7, 7, 8, 8, 8, 9, 8, 8, 8, 7, 7, 6, + }, + { + 0, 5, 12, 4, 7, 12, 8, 10, 13, 4, 7, 12, 6, 8, 12, 10, + 10, 12, 8, 9, 12, 10, 10, 12, 12, 12, 12, 1, 6, 12, 4, 7, + 12, 8, 9, 12, 4, 7, 12, 6, 8, 11, 9, 10, 12, 8, 9, 12, + 9, 10, 11, 11, 11, 12, 6, 8, 12, 7, 9, 12, 9, 10, 13, 6, + 9, 12, 8, 9, 12, 10, 10, 12, 9, 10, 12, 10, 10, 12, 12, 12, + 12, 8, 10, 12, 9, 10, 12, 10, 10, 12, 8, 10, 12, 9, 10, 12, + 10, 10, 11, 9, 10, 12, 10, 10, 11, 11, 10, 10, + }, + }, + { + { + 0, 5, 10, 3, 6, 10, 7, 8, 11, 4, 6, 10, 6, 7, 10, 8, + 9, 10, 8, 8, 10, 9, 9, 10, 10, 10, 10, 2, 6, 10, 4, 6, + 10, 7, 8, 10, 4, 7, 10, 6, 7, 10, 8, 8, 10, 7, 8, 10, + 8, 8, 9, 10, 9, 9, 5, 8, 11, 6, 8, 10, 7, 9, 10, 6, + 8, 11, 7, 8, 10, 8, 8, 10, 8, 9, 11, 9, 9, 10, 10, 9, + 9, 8, 9, 10, 8, 9, 10, 8, 9, 10, 8, 9, 10, 8, 8, 10, + 8, 8, 9, 8, 9, 10, 8, 8, 9, 9, 8, 8, + }, + { + 0, 6, 13, 4, 7, 14, 9, 11, 14, 3, 7, 13, 7, 8, 13, 11, + 11, 14, 8, 10, 13, 10, 11, 13, 13, 13, 14, 1, 6, 12, 4, 8, + 13, 9, 10, 15, 4, 8, 13, 7, 8, 12, 11, 11, 14, 8, 10, 13, + 10, 10, 13, 13, 13, 14, 5, 9, 13, 7, 9, 13, 10, 11, 14, 6, + 10, 14, 8, 10, 14, 11, 11, 14, 9, 11, 14, 11, 11, 13, 13, 13, + 14, 9, 10, 14, 9, 11, 13, 11, 12, 14, 9, 11, 13, 9, 11, 14, + 11, 12, 13, 10, 12, 15, 11, 11, 13, 13, 12, 13, + }, + }, + { + { + 0, 5, 11, 3, 6, 11, 7, 9, 12, 3, 6, 11, 6, 7, 11, 9, + 9, 11, 8, 9, 11, 9, 9, 11, 11, 11, 12, 2, 6, 11, 4, 6, + 11, 7, 9, 11, 4, 7, 11, 5, 7, 10, 9, 9, 11, 7, 8, 11, + 9, 9, 10, 11, 11, 11, 5, 8, 11, 6, 8, 11, 8, 9, 12, 6, + 8, 11, 7, 8, 11, 9, 9, 11, 8, 9, 12, 9, 9, 11, 11, 11, + 11, 8, 10, 12, 8, 10, 11, 9, 10, 12, 8, 10, 12, 8, 9, 12, + 10, 10, 12, 9, 10, 12, 9, 9, 11, 11, 10, 11, + }, + { + 0, 6, 13, 3, 8, 14, 10, 12, 16, 3, 8, 15, 7, 9, 15, 12, + 13, 15, 9, 11, 15, 11, 12, 16, 14, 16, 16, 1, 7, 13, 4, 8, + 14, 9, 11, 15, 4, 8, 14, 7, 9, 14, 12, 13, 15, 8, 10, 14, + 11, 11, 14, 16, 14, 16, 6, 9, 14, 7, 10, 14, 11, 13, 15, 7, + 10, 14, 9, 10, 13, 12, 12, 15, 10, 11, 14, 11, 11, 14, 14, 14, + 16, 9, 11, 14, 10, 11, 14, 13, 14, 15, 9, 12, 14, 10, 12, 16, + 13, 14, 16, 10, 13, 16, 12, 12, 14, 15, 14, 15, + }, + }, + { + { + 0, 6, 12, 3, 7, 12, 9, 11, 13, 4, 7, 12, 6, 8, 12, 10, + 11, 13, 8, 10, 13, 10, 11, 13, 13, 13, 14, 1, 6, 12, 4, 7, + 12, 9, 10, 14, 4, 7, 12, 6, 7, 12, 10, 11, 13, 8, 9, 13, + 10, 10, 12, 13, 13, 14, 6, 9, 13, 7, 9, 13, 10, 12, 14, 7, + 9, 13, 8, 10, 13, 11, 11, 14, 9, 11, 13, 11, 11, 14, 13, 13, + 14, 10, 12, 14, 10, 12, 14, 12, 13, 15, 10, 12, 14, 10, 12, 14, + 12, 13, 15, 11, 13, 15, 12, 12, 15, 14, 14, 14, + }, + { + 0, 6, 16, 3, 8, 16, 10, 13, 16, 3, 8, 16, 7, 9, 16, 13, + 16, 16, 8, 10, 16, 11, 13, 16, 16, 16, 16, 1, 7, 14, 4, 8, + 16, 10, 12, 16, 4, 8, 13, 7, 9, 16, 13, 14, 16, 8, 10, 16, + 11, 11, 14, 16, 16, 16, 6, 9, 14, 8, 10, 14, 12, 16, 16, 6, + 10, 13, 9, 11, 16, 13, 14, 16, 9, 12, 16, 12, 11, 16, 16, 16, + 16, 10, 12, 16, 11, 12, 16, 16, 14, 16, 9, 12, 16, 11, 12, 16, + 16, 15, 16, 10, 13, 16, 12, 13, 16, 16, 16, 16, + }, + }, +}; + +static const uint8_t rv34_table_intra_thirdpat[NUM_INTRA_TABLES][2][OTHERBLK_VLC_SIZE] = { + { + { + 0, 5, 10, 3, 6, 10, 7, 8, 10, 4, 7, 10, 6, 7, 10, 8, + 8, 10, 8, 9, 10, 9, 9, 10, 9, 9, 9, 2, 6, 10, 4, 7, + 10, 7, 8, 9, 5, 7, 10, 6, 7, 10, 8, 8, 9, 8, 9, 10, + 8, 8, 9, 9, 9, 8, 6, 8, 11, 6, 8, 10, 7, 8, 10, 6, + 8, 11, 7, 8, 10, 8, 8, 9, 8, 9, 10, 9, 9, 10, 9, 9, + 9, 7, 8, 10, 7, 8, 10, 7, 8, 8, 7, 8, 10, 7, 8, 9, + 7, 8, 8, 8, 8, 9, 8, 8, 8, 7, 7, 7, + }, + { + 0, 4, 10, 3, 6, 10, 7, 8, 11, 3, 6, 10, 5, 7, 10, 9, + 9, 11, 9, 10, 11, 9, 10, 11, 11, 11, 11, 2, 6, 10, 4, 6, + 10, 7, 8, 10, 4, 7, 10, 6, 7, 10, 8, 9, 10, 8, 9, 11, + 9, 9, 11, 10, 10, 11, 6, 8, 11, 6, 8, 11, 8, 9, 11, 7, + 9, 11, 7, 8, 11, 9, 9, 11, 9, 10, 12, 10, 10, 12, 11, 11, + 11, 8, 9, 11, 8, 9, 11, 9, 9, 11, 9, 10, 11, 9, 10, 11, + 9, 10, 11, 10, 11, 12, 10, 10, 12, 10, 10, 10, + }, + }, + { + { + 0, 5, 10, 3, 6, 10, 7, 8, 10, 4, 7, 10, 6, 7, 10, 8, + 9, 10, 8, 9, 11, 8, 9, 10, 10, 10, 10, 2, 6, 10, 4, 6, + 10, 7, 8, 10, 4, 7, 10, 5, 7, 10, 8, 8, 10, 8, 9, 10, + 8, 9, 10, 9, 9, 9, 5, 7, 11, 6, 8, 11, 7, 8, 11, 6, + 8, 11, 7, 8, 10, 8, 9, 10, 8, 9, 11, 9, 9, 10, 10, 9, + 10, 7, 8, 10, 7, 8, 10, 8, 9, 10, 8, 9, 10, 8, 9, 10, + 8, 8, 10, 9, 9, 10, 9, 9, 10, 9, 9, 9, + }, + { + 0, 5, 11, 3, 6, 11, 8, 9, 12, 4, 7, 12, 6, 7, 12, 9, + 10, 13, 10, 11, 13, 10, 11, 14, 12, 13, 14, 1, 6, 11, 4, 7, + 11, 8, 9, 12, 5, 7, 11, 6, 8, 12, 9, 10, 13, 10, 11, 14, + 10, 11, 13, 12, 12, 14, 6, 8, 12, 7, 9, 13, 9, 10, 14, 7, + 10, 13, 8, 10, 12, 11, 11, 13, 11, 13, 14, 11, 12, 14, 13, 13, + 15, 9, 10, 12, 9, 11, 14, 10, 11, 14, 11, 11, 13, 10, 11, 13, + 11, 12, 14, 12, 14, 15, 13, 13, 14, 13, 13, 14, + }, + }, + { + { + 0, 5, 11, 3, 6, 11, 7, 9, 11, 4, 6, 11, 5, 7, 10, 9, + 9, 11, 8, 9, 11, 9, 10, 11, 11, 11, 11, 2, 6, 10, 3, 6, + 10, 7, 9, 11, 4, 7, 10, 5, 7, 10, 8, 9, 11, 8, 9, 11, + 9, 9, 11, 11, 11, 11, 5, 8, 11, 6, 8, 11, 8, 10, 12, 6, + 8, 11, 7, 8, 11, 9, 10, 11, 9, 10, 12, 9, 10, 11, 11, 11, + 11, 8, 9, 11, 8, 10, 12, 9, 11, 12, 8, 10, 12, 9, 10, 12, + 10, 11, 12, 10, 11, 12, 10, 10, 11, 11, 11, 11, + }, + { + 0, 5, 13, 2, 7, 16, 9, 11, 16, 4, 8, 16, 7, 9, 16, 12, + 12, 16, 12, 16, 16, 12, 16, 16, 16, 16, 16, 1, 6, 13, 4, 8, + 16, 9, 11, 16, 6, 9, 16, 7, 10, 16, 13, 13, 16, 13, 15, 16, + 12, 16, 16, 16, 16, 16, 7, 9, 16, 8, 11, 15, 11, 13, 16, 10, + 12, 16, 10, 12, 16, 16, 13, 16, 16, 16, 16, 14, 16, 16, 16, 16, + 16, 12, 12, 16, 12, 16, 16, 16, 16, 16, 13, 14, 16, 12, 13, 16, + 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, + }, + }, + { + { + 0, 6, 11, 3, 7, 11, 8, 10, 12, 4, 7, 11, 6, 8, 11, 10, + 11, 12, 9, 10, 12, 10, 10, 12, 12, 12, 13, 1, 6, 11, 4, 7, + 11, 8, 10, 12, 4, 7, 11, 6, 8, 11, 10, 10, 12, 9, 10, 12, + 10, 10, 12, 13, 13, 13, 6, 8, 12, 7, 10, 12, 10, 12, 13, 7, + 9, 12, 8, 10, 12, 11, 11, 13, 11, 12, 14, 11, 11, 13, 13, 13, + 13, 9, 11, 13, 10, 12, 14, 12, 13, 15, 10, 12, 14, 11, 12, 14, + 13, 13, 14, 12, 13, 15, 13, 13, 14, 14, 14, 14, + }, + { + 0, 5, 16, 2, 6, 16, 10, 14, 16, 4, 8, 16, 7, 9, 16, 11, + 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 1, 6, 12, 4, 8, + 12, 12, 12, 16, 6, 8, 16, 8, 10, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 12, 16, 16, 7, 10, 16, 8, 11, 14, 16, 16, 16, 10, + 12, 16, 10, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + }, + { + { + 0, 5, 11, 3, 6, 11, 10, 10, 12, 3, 7, 11, 6, 8, 11, 11, + 11, 12, 10, 10, 12, 11, 11, 13, 14, 13, 14, 1, 6, 11, 4, 7, + 11, 10, 11, 13, 5, 7, 11, 7, 8, 11, 11, 11, 13, 10, 11, 13, + 11, 11, 12, 13, 13, 14, 7, 10, 12, 9, 11, 13, 12, 13, 14, 9, + 10, 13, 9, 10, 13, 12, 11, 13, 12, 13, 16, 12, 13, 13, 14, 14, + 14, 11, 14, 16, 12, 14, 15, 14, 13, 16, 13, 13, 15, 13, 14, 16, + 14, 13, 16, 13, 13, 16, 13, 14, 15, 15, 14, 15, + }, + { + 0, 4, 16, 2, 7, 16, 10, 16, 16, 4, 10, 16, 7, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 6, 13, 4, 11, + 16, 16, 16, 16, 6, 10, 16, 8, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 8, 16, 16, 10, 16, 16, 16, 16, 16, 10, + 16, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + }, +}; + + +static const uint8_t rv34_intra_coeff[NUM_INTRA_TABLES][COEFF_VLC_SIZE] = { +{ + 1, 3, 3, 4, 4, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, + 9, 9, 10, 10, 10, 11, 11, 11, 10, 10, 10, 12, 13, 14, 15, 15, +}, +{ + 1, 2, 3, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 10, 10, 11, + 11, 11, 12, 12, 13, 13, 13, 13, 13, 13, 13, 14, 16, 16, 16, 16, +}, +{ + 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 10, 10, 11, 12, 12, 12, + 13, 13, 14, 14, 14, 14, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, +}, +{ + 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 10, 10, 11, 12, 12, 12, + 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, 14, 12, 16, 16, 16, 16, +}, +{ + 1, 2, 3, 4, 5, 7, 7, 8, 8, 9, 10, 10, 12, 11, 13, 12, + 15, 13, 14, 13, 12, 15, 14, 13, 12, 12, 10, 11, 16, 16, 16, 16, +} +}; + + +static const uint8_t rv34_inter_cbppat[NUM_INTER_TABLES][CBPPAT_VLC_SIZE] = { +{ + 7, 9, 9, 8, 9, 8, 9, 8, 9, 9, 8, 8, 8, 8, 8, 4, + 7, 10, 11, 10, 11, 10, 12, 10, 12, 11, 11, 10, 11, 10, 10, 7, + 10, 11, 15, 12, 15, 12, 15, 12, 15, 14, 14, 12, 14, 12, 14, 9, + 7, 11, 10, 10, 12, 11, 11, 10, 11, 12, 10, 10, 11, 10, 10, 7, + 8, 12, 12, 11, 13, 12, 12, 10, 13, 13, 12, 10, 12, 11, 11, 7, + 11, 13, 15, 11, 15, 13, 15, 12, 16, 14, 14, 12, 15, 13, 13, 9, + 10, 15, 11, 12, 15, 14, 14, 12, 15, 15, 12, 12, 14, 14, 12, 9, + 11, 15, 13, 12, 16, 15, 14, 12, 15, 15, 13, 12, 15, 14, 13, 9, + 13, 15, 14, 10, 16, 15, 16, 11, 16, 16, 15, 12, 16, 15, 15, 9, + 7, 11, 11, 11, 11, 10, 11, 10, 11, 12, 11, 10, 10, 10, 10, 7, + 9, 12, 13, 12, 12, 11, 13, 10, 13, 13, 12, 11, 12, 10, 11, 7, + 12, 13, 16, 14, 15, 12, 16, 12, 16, 15, 15, 13, 15, 12, 14, 9, + 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 7, + 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 13, 11, 12, 11, 11, 7, + 12, 14, 15, 13, 16, 13, 15, 11, 16, 14, 15, 12, 15, 12, 13, 8, + 12, 16, 14, 14, 16, 15, 15, 13, 16, 15, 14, 13, 15, 14, 13, 9, + 12, 15, 14, 13, 15, 14, 15, 12, 16, 15, 14, 12, 14, 13, 13, 8, + 13, 16, 16, 12, 16, 14, 16, 11, 16, 16, 15, 12, 16, 14, 14, 8, + 10, 15, 15, 15, 12, 12, 14, 12, 14, 15, 15, 14, 12, 12, 13, 9, + 11, 15, 16, 14, 13, 12, 15, 12, 16, 15, 15, 14, 14, 12, 13, 9, + 14, 15, 16, 16, 15, 11, 16, 12, 16, 16, 16, 15, 16, 12, 15, 9, + 12, 16, 16, 15, 14, 14, 14, 13, 16, 16, 15, 14, 14, 13, 13, 9, + 12, 15, 15, 14, 14, 13, 15, 12, 16, 15, 14, 13, 14, 13, 13, 8, + 13, 16, 16, 15, 16, 12, 16, 11, 16, 16, 16, 14, 16, 13, 14, 8, + 14, 16, 16, 16, 16, 16, 15, 14, 16, 16, 16, 15, 16, 15, 14, 11, + 13, 16, 16, 15, 16, 15, 15, 12, 16, 16, 16, 14, 15, 14, 14, 9, + 14, 16, 16, 13, 16, 14, 16, 10, 16, 16, 16, 13, 16, 14, 14, 8, + 7, 12, 11, 11, 11, 11, 12, 10, 11, 11, 10, 10, 10, 10, 10, 7, + 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 8, + 12, 14, 16, 14, 16, 14, 16, 13, 16, 14, 15, 13, 15, 13, 14, 9, + 9, 13, 12, 12, 13, 12, 13, 11, 12, 13, 11, 10, 12, 11, 11, 7, + 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 7, + 12, 14, 16, 13, 16, 14, 15, 12, 15, 15, 14, 12, 15, 13, 13, 8, + 11, 15, 13, 14, 15, 15, 14, 13, 15, 15, 12, 12, 14, 14, 12, 9, + 11, 15, 14, 13, 15, 14, 14, 12, 15, 14, 13, 11, 14, 13, 12, 8, + 13, 16, 15, 12, 16, 15, 16, 12, 16, 16, 14, 11, 15, 14, 14, 8, + 8, 13, 13, 12, 12, 12, 13, 11, 12, 13, 12, 11, 11, 10, 10, 7, + 9, 13, 14, 12, 13, 12, 13, 11, 13, 13, 13, 11, 12, 11, 11, 7, + 12, 14, 16, 14, 15, 13, 15, 12, 15, 15, 15, 13, 14, 12, 13, 8, + 9, 13, 13, 12, 13, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 7, + 9, 13, 12, 12, 13, 12, 12, 10, 13, 13, 12, 10, 12, 10, 10, 6, + 11, 14, 14, 12, 14, 12, 14, 11, 14, 14, 13, 11, 13, 11, 12, 7, + 12, 16, 14, 14, 15, 15, 14, 13, 15, 15, 13, 12, 14, 13, 12, 8, + 11, 14, 13, 12, 14, 13, 13, 11, 14, 14, 13, 11, 13, 12, 11, 7, + 11, 14, 14, 12, 15, 13, 14, 11, 15, 14, 13, 11, 14, 12, 12, 6, + 11, 16, 15, 15, 13, 14, 15, 13, 14, 15, 15, 13, 12, 12, 12, 9, + 12, 15, 15, 14, 14, 13, 15, 12, 15, 15, 14, 13, 13, 11, 12, 8, + 13, 16, 16, 15, 16, 13, 16, 13, 16, 16, 15, 14, 14, 12, 14, 8, + 11, 16, 15, 14, 14, 14, 14, 13, 15, 15, 14, 13, 13, 12, 12, 8, + 11, 14, 14, 13, 13, 12, 14, 11, 14, 14, 13, 12, 12, 11, 11, 7, + 12, 14, 15, 13, 14, 12, 14, 11, 15, 14, 14, 12, 13, 11, 12, 7, + 13, 16, 16, 16, 16, 15, 16, 14, 16, 16, 15, 14, 15, 14, 13, 9, + 12, 15, 14, 13, 15, 13, 14, 12, 15, 15, 13, 12, 13, 12, 12, 7, + 11, 15, 14, 12, 14, 13, 14, 10, 15, 14, 13, 11, 13, 11, 11, 5, + 10, 15, 15, 15, 15, 14, 15, 13, 12, 14, 12, 12, 12, 13, 12, 9, + 12, 16, 16, 15, 16, 15, 16, 14, 14, 15, 14, 13, 14, 13, 13, 9, + 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 16, 14, 15, 11, + 11, 15, 15, 14, 15, 15, 15, 14, 14, 15, 12, 12, 13, 13, 12, 9, + 12, 15, 15, 14, 16, 14, 15, 13, 14, 14, 13, 12, 14, 13, 12, 8, + 13, 16, 16, 15, 16, 16, 16, 14, 16, 16, 15, 12, 16, 14, 14, 9, + 13, 16, 14, 16, 16, 16, 16, 15, 15, 16, 11, 12, 16, 15, 12, 9, + 13, 16, 15, 14, 16, 15, 16, 14, 15, 16, 12, 11, 15, 14, 13, 8, + 13, 16, 16, 13, 16, 16, 16, 13, 16, 16, 13, 11, 16, 14, 14, 8, + 11, 15, 15, 15, 14, 14, 15, 13, 13, 15, 14, 13, 12, 12, 12, 9, + 11, 15, 16, 14, 15, 14, 15, 13, 14, 14, 14, 13, 13, 12, 13, 8, + 13, 16, 16, 16, 16, 15, 16, 14, 16, 16, 16, 13, 15, 12, 14, 9, + 11, 16, 15, 14, 14, 14, 15, 13, 14, 14, 13, 12, 13, 12, 11, 8, + 11, 14, 14, 13, 14, 13, 14, 12, 13, 13, 12, 11, 12, 11, 11, 7, + 12, 15, 15, 13, 15, 14, 15, 12, 15, 14, 14, 11, 13, 12, 12, 7, + 13, 16, 15, 15, 16, 16, 16, 14, 15, 16, 12, 12, 14, 14, 12, 8, + 11, 15, 14, 13, 15, 13, 14, 12, 14, 14, 12, 11, 13, 12, 11, 6, + 11, 14, 14, 12, 15, 13, 14, 11, 15, 14, 12, 10, 13, 11, 11, 5, + 12, 16, 16, 16, 15, 15, 16, 15, 14, 16, 15, 15, 10, 12, 12, 9, + 13, 16, 16, 16, 15, 14, 16, 13, 15, 15, 15, 14, 12, 11, 13, 8, + 14, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 14, 14, 11, 14, 8, + 13, 16, 16, 15, 15, 15, 15, 14, 15, 16, 14, 13, 12, 12, 11, 8, + 11, 15, 15, 13, 14, 13, 14, 12, 14, 14, 13, 12, 12, 11, 11, 6, + 11, 15, 15, 13, 15, 12, 14, 11, 14, 14, 13, 11, 12, 10, 11, 5, + 13, 16, 16, 15, 16, 16, 16, 14, 16, 16, 14, 14, 14, 13, 11, 8, + 11, 14, 14, 13, 14, 13, 14, 11, 14, 14, 12, 11, 12, 11, 10, 5, + 10, 13, 13, 11, 13, 12, 13, 9, 13, 13, 12, 9, 12, 10, 10, 3, +}, +{ + 5, 7, 7, 7, 7, 7, 8, 7, 7, 8, 7, 7, 7, 7, 7, 4, + 7, 9, 11, 9, 11, 9, 11, 9, 11, 10, 10, 9, 10, 9, 10, 6, + 11, 11, 14, 11, 14, 11, 14, 11, 15, 13, 14, 12, 14, 12, 13, 9, + 6, 11, 10, 9, 11, 10, 11, 9, 11, 11, 9, 9, 10, 10, 9, 6, + 8, 11, 11, 10, 12, 11, 12, 10, 12, 12, 11, 10, 12, 11, 11, 7, + 11, 13, 14, 11, 15, 13, 15, 11, 15, 14, 14, 12, 14, 13, 13, 9, + 10, 14, 11, 11, 15, 14, 13, 12, 14, 14, 11, 11, 14, 13, 12, 9, + 11, 14, 13, 11, 15, 14, 14, 11, 15, 15, 13, 11, 14, 14, 13, 9, + 12, 14, 14, 10, 16, 15, 16, 11, 16, 16, 15, 11, 16, 15, 14, 9, + 6, 10, 11, 10, 10, 9, 11, 9, 10, 11, 10, 10, 9, 9, 9, 6, + 9, 12, 12, 11, 12, 10, 12, 10, 12, 12, 12, 11, 11, 10, 11, 7, + 12, 13, 15, 13, 14, 11, 15, 11, 15, 15, 14, 13, 14, 12, 14, 9, + 9, 12, 12, 11, 12, 11, 12, 11, 12, 13, 11, 11, 12, 11, 11, 7, + 9, 12, 12, 11, 13, 11, 12, 10, 13, 13, 12, 11, 12, 11, 11, 7, + 12, 14, 15, 12, 15, 12, 14, 11, 15, 15, 14, 12, 14, 13, 13, 8, + 12, 15, 14, 13, 15, 14, 14, 13, 16, 16, 14, 13, 15, 14, 13, 9, + 12, 15, 14, 13, 15, 14, 14, 12, 15, 15, 13, 12, 14, 13, 13, 9, + 13, 15, 15, 12, 16, 14, 15, 11, 16, 16, 15, 12, 15, 14, 14, 9, + 10, 14, 14, 14, 12, 11, 13, 12, 14, 15, 14, 13, 12, 11, 12, 9, + 12, 14, 15, 14, 13, 11, 14, 12, 15, 15, 15, 14, 13, 11, 13, 9, + 13, 15, 16, 15, 14, 11, 16, 11, 16, 16, 16, 14, 15, 12, 15, 9, + 12, 15, 15, 14, 14, 14, 14, 13, 15, 15, 14, 14, 14, 13, 13, 9, + 12, 15, 15, 14, 14, 13, 14, 12, 15, 15, 14, 13, 14, 13, 13, 9, + 13, 15, 16, 14, 15, 13, 16, 11, 16, 16, 15, 14, 15, 13, 14, 9, + 14, 16, 16, 16, 16, 16, 15, 14, 16, 16, 16, 16, 16, 16, 14, 11, + 14, 16, 16, 14, 16, 15, 15, 12, 16, 16, 16, 14, 15, 14, 14, 9, + 14, 16, 16, 14, 16, 14, 16, 11, 16, 16, 16, 14, 16, 14, 14, 9, + 6, 11, 10, 10, 10, 10, 11, 10, 10, 11, 9, 9, 9, 9, 9, 6, + 9, 12, 12, 11, 13, 11, 13, 11, 12, 12, 11, 11, 12, 11, 11, 7, + 12, 14, 16, 13, 16, 14, 16, 13, 15, 14, 15, 12, 15, 13, 14, 9, + 8, 12, 11, 11, 12, 12, 12, 11, 11, 12, 10, 10, 11, 11, 10, 7, + 9, 12, 12, 11, 13, 12, 13, 11, 13, 12, 11, 10, 12, 11, 11, 7, + 12, 14, 15, 12, 15, 14, 15, 12, 15, 14, 14, 12, 14, 13, 13, 9, + 11, 15, 13, 13, 15, 14, 14, 13, 14, 15, 11, 11, 14, 14, 12, 9, + 11, 14, 13, 12, 15, 14, 14, 12, 14, 14, 12, 11, 14, 13, 12, 8, + 13, 15, 15, 12, 16, 15, 15, 12, 15, 15, 14, 11, 15, 14, 14, 8, + 8, 12, 12, 11, 11, 11, 12, 11, 11, 12, 11, 11, 10, 10, 10, 7, + 9, 13, 13, 12, 13, 11, 13, 11, 12, 13, 12, 11, 11, 10, 11, 7, + 12, 14, 15, 14, 15, 13, 15, 12, 15, 14, 14, 13, 14, 12, 13, 9, + 9, 13, 12, 12, 12, 12, 12, 11, 12, 13, 11, 11, 11, 11, 10, 7, + 9, 12, 12, 11, 12, 11, 12, 10, 12, 12, 11, 10, 11, 10, 10, 7, + 11, 13, 14, 12, 14, 12, 14, 11, 14, 13, 13, 11, 13, 11, 12, 7, + 12, 15, 14, 13, 15, 14, 14, 13, 15, 15, 13, 12, 13, 13, 12, 9, + 11, 14, 13, 12, 14, 13, 13, 11, 14, 14, 12, 11, 13, 12, 11, 7, + 11, 14, 14, 12, 14, 13, 14, 11, 14, 14, 13, 11, 13, 12, 12, 7, + 11, 15, 15, 14, 13, 13, 14, 13, 14, 15, 14, 13, 11, 11, 12, 9, + 12, 15, 15, 14, 14, 12, 14, 12, 14, 14, 14, 13, 12, 11, 12, 8, + 13, 16, 16, 15, 15, 12, 16, 13, 16, 15, 15, 14, 14, 12, 14, 9, + 12, 15, 15, 14, 14, 14, 14, 13, 15, 15, 14, 13, 12, 12, 12, 9, + 11, 14, 14, 13, 13, 12, 13, 11, 14, 13, 13, 12, 12, 11, 11, 7, + 12, 14, 15, 13, 14, 12, 14, 11, 15, 14, 13, 12, 13, 11, 12, 7, + 13, 16, 16, 15, 16, 15, 15, 14, 16, 16, 15, 14, 14, 14, 12, 9, + 12, 15, 14, 13, 14, 13, 14, 12, 15, 14, 13, 12, 13, 12, 12, 8, + 12, 14, 14, 13, 15, 13, 14, 11, 14, 14, 13, 12, 13, 12, 12, 6, + 10, 14, 14, 13, 14, 14, 14, 13, 12, 13, 12, 12, 12, 12, 11, 9, + 12, 15, 15, 14, 15, 14, 16, 14, 14, 14, 13, 12, 14, 13, 13, 9, + 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 16, 14, 16, 11, + 11, 15, 14, 14, 15, 14, 14, 14, 13, 14, 11, 12, 13, 13, 12, 9, + 12, 15, 14, 14, 15, 14, 15, 13, 14, 14, 13, 12, 14, 13, 13, 9, + 13, 16, 16, 14, 16, 15, 16, 14, 16, 15, 15, 12, 16, 14, 14, 9, + 13, 16, 14, 15, 16, 16, 16, 14, 14, 16, 11, 12, 15, 14, 12, 9, + 13, 16, 15, 14, 16, 15, 16, 14, 15, 15, 12, 11, 15, 14, 13, 9, + 14, 16, 16, 13, 16, 16, 16, 14, 16, 15, 13, 11, 16, 14, 14, 9, + 11, 15, 15, 14, 14, 14, 14, 13, 13, 14, 13, 13, 11, 11, 11, 9, + 12, 15, 15, 14, 15, 14, 15, 13, 14, 14, 13, 13, 13, 12, 12, 9, + 13, 16, 16, 16, 16, 14, 16, 14, 16, 15, 16, 14, 15, 12, 14, 9, + 11, 15, 14, 14, 15, 14, 14, 13, 14, 14, 12, 12, 12, 12, 11, 8, + 11, 14, 14, 13, 14, 13, 13, 12, 13, 13, 12, 11, 12, 11, 11, 7, + 12, 14, 15, 13, 15, 13, 14, 13, 14, 14, 13, 12, 13, 12, 12, 8, + 13, 16, 15, 15, 16, 15, 15, 14, 15, 16, 12, 12, 14, 14, 11, 9, + 12, 15, 14, 13, 15, 13, 14, 12, 14, 14, 12, 11, 13, 12, 11, 7, + 12, 14, 14, 13, 15, 13, 14, 12, 15, 14, 13, 10, 13, 12, 12, 6, + 12, 16, 16, 15, 14, 14, 15, 14, 13, 15, 14, 14, 10, 11, 11, 9, + 13, 16, 16, 15, 15, 14, 15, 14, 15, 15, 15, 14, 12, 11, 12, 8, + 14, 16, 16, 16, 16, 14, 16, 14, 16, 15, 15, 14, 14, 11, 14, 8, + 12, 16, 16, 15, 15, 14, 15, 14, 14, 16, 14, 14, 12, 12, 11, 8, + 11, 14, 14, 13, 14, 13, 14, 12, 14, 14, 13, 12, 12, 11, 11, 7, + 12, 14, 15, 13, 14, 13, 14, 12, 14, 14, 13, 12, 13, 11, 12, 6, + 14, 16, 16, 16, 16, 16, 15, 14, 16, 16, 14, 13, 13, 13, 11, 8, + 12, 15, 15, 13, 15, 13, 14, 12, 14, 14, 13, 12, 13, 12, 10, 6, + 11, 14, 13, 12, 14, 12, 13, 10, 14, 13, 12, 10, 12, 10, 10, 4, +}, +{ + 4, 6, 6, 6, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 6, 3, + 6, 9, 10, 9, 10, 9, 11, 9, 10, 10, 10, 9, 10, 9, 10, 6, + 10, 11, 14, 11, 14, 11, 14, 11, 14, 13, 14, 11, 14, 11, 13, 9, + 6, 10, 9, 9, 10, 10, 10, 9, 10, 11, 9, 9, 10, 10, 9, 6, + 8, 11, 11, 9, 12, 11, 12, 10, 12, 12, 11, 10, 12, 11, 11, 7, + 11, 13, 14, 11, 15, 13, 15, 11, 15, 14, 14, 11, 15, 13, 14, 9, + 10, 13, 11, 11, 14, 14, 13, 11, 14, 14, 11, 11, 13, 13, 11, 9, + 11, 14, 12, 11, 15, 14, 14, 11, 15, 15, 13, 11, 14, 14, 13, 9, + 12, 14, 13, 10, 16, 15, 16, 11, 16, 16, 14, 11, 16, 14, 14, 9, + 6, 10, 10, 10, 9, 9, 10, 9, 10, 11, 10, 10, 9, 9, 9, 6, + 8, 11, 12, 11, 11, 10, 12, 10, 12, 12, 12, 11, 11, 10, 11, 7, + 11, 13, 15, 13, 14, 11, 15, 11, 15, 14, 14, 13, 14, 12, 14, 9, + 8, 12, 12, 12, 12, 12, 12, 11, 12, 13, 11, 11, 11, 11, 11, 8, + 9, 12, 12, 11, 12, 12, 13, 11, 13, 13, 12, 11, 12, 11, 11, 8, + 11, 14, 15, 13, 14, 13, 15, 11, 15, 15, 14, 13, 15, 13, 14, 9, + 12, 16, 14, 14, 15, 15, 14, 12, 15, 16, 14, 13, 14, 14, 13, 10, + 11, 15, 14, 13, 15, 14, 15, 12, 15, 16, 14, 13, 15, 14, 13, 9, + 13, 15, 15, 12, 16, 15, 16, 12, 16, 16, 15, 13, 15, 14, 14, 9, + 10, 14, 14, 14, 11, 11, 13, 11, 14, 14, 14, 13, 11, 11, 11, 9, + 11, 14, 15, 14, 13, 11, 14, 12, 15, 15, 15, 14, 13, 11, 13, 9, + 13, 14, 16, 15, 14, 11, 16, 12, 16, 16, 16, 14, 15, 12, 15, 10, + 12, 16, 15, 15, 14, 14, 14, 12, 16, 16, 14, 14, 14, 13, 13, 10, + 12, 15, 15, 14, 14, 13, 14, 12, 15, 16, 14, 14, 14, 13, 13, 9, + 13, 16, 16, 14, 16, 13, 16, 12, 16, 16, 16, 14, 16, 13, 15, 10, + 14, 16, 16, 16, 16, 16, 15, 14, 16, 16, 16, 16, 16, 16, 14, 11, + 13, 16, 16, 15, 16, 16, 16, 13, 16, 16, 16, 15, 16, 15, 14, 10, + 14, 16, 16, 14, 16, 14, 16, 12, 16, 16, 16, 15, 16, 15, 15, 10, + 6, 10, 10, 10, 10, 10, 11, 10, 9, 10, 9, 9, 9, 9, 9, 6, + 9, 12, 12, 11, 12, 11, 13, 11, 12, 12, 11, 10, 12, 11, 11, 8, + 12, 14, 15, 14, 15, 14, 16, 13, 15, 14, 14, 12, 15, 13, 14, 10, + 8, 12, 11, 11, 12, 12, 12, 11, 11, 12, 10, 10, 11, 11, 10, 7, + 9, 12, 12, 11, 13, 12, 13, 11, 12, 13, 11, 10, 12, 12, 11, 8, + 11, 14, 14, 13, 15, 14, 15, 13, 15, 14, 14, 12, 15, 13, 14, 9, + 11, 15, 12, 13, 15, 15, 14, 13, 14, 15, 11, 11, 14, 14, 12, 9, + 11, 14, 13, 13, 15, 14, 15, 13, 15, 15, 13, 11, 15, 14, 13, 9, + 13, 15, 15, 12, 16, 15, 16, 13, 16, 15, 14, 11, 16, 15, 14, 9, + 8, 12, 12, 11, 11, 11, 12, 11, 11, 12, 11, 11, 9, 10, 10, 7, + 9, 12, 13, 12, 12, 11, 13, 11, 12, 13, 12, 12, 11, 11, 11, 8, + 12, 14, 15, 14, 15, 13, 16, 13, 15, 14, 15, 13, 14, 12, 14, 9, + 9, 13, 12, 12, 12, 12, 13, 12, 12, 13, 11, 11, 11, 11, 10, 8, + 9, 12, 12, 12, 12, 12, 13, 11, 12, 13, 11, 11, 12, 11, 11, 7, + 11, 13, 14, 13, 14, 13, 15, 12, 14, 14, 14, 12, 14, 12, 13, 8, + 12, 15, 14, 14, 15, 15, 14, 13, 15, 16, 13, 13, 14, 14, 12, 9, + 11, 14, 13, 13, 14, 14, 14, 12, 14, 15, 13, 12, 14, 13, 12, 8, + 11, 14, 14, 13, 15, 14, 15, 12, 15, 15, 14, 12, 14, 13, 13, 8, + 11, 14, 14, 14, 13, 13, 14, 13, 13, 14, 14, 13, 11, 11, 11, 9, + 11, 15, 15, 14, 14, 13, 15, 13, 14, 15, 14, 14, 13, 11, 13, 9, + 13, 16, 16, 16, 15, 13, 16, 13, 16, 16, 16, 15, 15, 12, 15, 10, + 11, 15, 15, 15, 14, 14, 14, 13, 15, 15, 14, 14, 13, 13, 12, 9, + 11, 14, 14, 13, 13, 13, 14, 12, 14, 14, 13, 13, 13, 12, 12, 8, + 12, 15, 15, 14, 15, 13, 15, 12, 15, 15, 14, 13, 14, 12, 13, 8, + 13, 16, 16, 16, 16, 16, 16, 14, 16, 16, 15, 15, 15, 15, 13, 10, + 12, 15, 15, 14, 15, 14, 15, 13, 15, 16, 14, 13, 14, 14, 13, 9, + 12, 15, 15, 14, 15, 14, 15, 12, 15, 15, 14, 13, 14, 13, 13, 8, + 10, 14, 13, 13, 14, 13, 14, 13, 11, 13, 11, 11, 11, 11, 11, 9, + 12, 15, 16, 14, 15, 14, 16, 14, 14, 14, 14, 13, 14, 13, 13, 10, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 13, 16, 14, 16, 11, + 11, 15, 14, 14, 15, 14, 15, 14, 13, 14, 11, 12, 13, 13, 11, 9, + 12, 15, 15, 14, 15, 15, 16, 14, 14, 14, 13, 12, 14, 13, 13, 9, + 13, 16, 16, 15, 16, 16, 16, 15, 16, 15, 15, 12, 16, 14, 15, 10, + 12, 16, 14, 15, 16, 16, 16, 14, 14, 16, 11, 12, 14, 15, 12, 9, + 13, 16, 15, 14, 16, 16, 16, 14, 15, 16, 13, 12, 15, 15, 13, 9, + 14, 16, 16, 14, 16, 16, 16, 15, 16, 16, 14, 12, 16, 15, 15, 10, + 11, 14, 14, 14, 14, 14, 14, 13, 12, 14, 13, 13, 11, 11, 11, 9, + 11, 15, 15, 14, 14, 14, 16, 14, 14, 14, 14, 13, 13, 12, 13, 9, + 13, 16, 16, 16, 16, 15, 16, 15, 16, 15, 16, 14, 15, 13, 15, 10, + 11, 15, 15, 14, 14, 14, 15, 14, 14, 15, 13, 13, 12, 13, 11, 9, + 11, 14, 14, 13, 14, 14, 14, 13, 13, 14, 13, 12, 13, 12, 12, 8, + 12, 15, 15, 14, 16, 14, 16, 14, 15, 15, 15, 13, 14, 13, 14, 9, + 13, 16, 15, 16, 16, 16, 16, 15, 15, 16, 13, 13, 14, 14, 12, 9, + 12, 15, 14, 14, 15, 15, 15, 13, 14, 15, 13, 12, 14, 13, 12, 8, + 12, 15, 14, 14, 15, 15, 15, 13, 15, 15, 14, 12, 14, 13, 13, 8, + 12, 16, 15, 15, 13, 14, 15, 14, 13, 15, 14, 14, 10, 11, 11, 9, + 12, 16, 16, 15, 15, 14, 16, 14, 15, 15, 15, 14, 13, 12, 13, 9, + 14, 16, 16, 16, 16, 14, 16, 15, 16, 15, 16, 15, 14, 12, 15, 10, + 12, 16, 15, 15, 15, 15, 15, 14, 15, 16, 14, 14, 12, 13, 11, 9, + 11, 15, 15, 14, 14, 14, 15, 13, 14, 15, 14, 13, 13, 12, 12, 8, + 12, 15, 15, 14, 15, 14, 15, 13, 15, 15, 14, 13, 14, 12, 13, 8, + 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 14, 14, 14, 14, 11, 9, + 12, 15, 15, 14, 15, 15, 15, 13, 15, 15, 14, 13, 14, 13, 12, 8, + 11, 14, 14, 13, 14, 13, 14, 12, 13, 14, 13, 12, 13, 12, 12, 7, +}, +{ + 2, 6, 6, 5, 6, 6, 7, 6, 6, 7, 6, 6, 6, 6, 6, 3, + 6, 9, 10, 9, 10, 9, 11, 9, 10, 10, 10, 9, 10, 9, 10, 7, + 10, 11, 14, 11, 14, 11, 14, 11, 14, 13, 14, 12, 14, 12, 13, 9, + 6, 10, 9, 9, 10, 10, 10, 9, 10, 11, 9, 9, 10, 10, 9, 7, + 8, 11, 11, 9, 12, 11, 12, 10, 12, 12, 11, 10, 12, 11, 11, 8, + 11, 13, 14, 11, 16, 13, 15, 12, 16, 14, 14, 12, 15, 13, 14, 10, + 10, 13, 11, 11, 14, 14, 13, 11, 13, 14, 11, 11, 13, 13, 11, 9, + 11, 13, 13, 11, 15, 14, 14, 12, 15, 15, 13, 12, 15, 14, 13, 10, + 12, 14, 14, 11, 16, 15, 16, 12, 16, 16, 15, 12, 16, 15, 15, 10, + 6, 10, 10, 10, 9, 9, 10, 9, 10, 11, 10, 10, 9, 9, 9, 7, + 8, 11, 12, 11, 11, 10, 12, 10, 12, 12, 12, 11, 11, 10, 11, 8, + 12, 13, 16, 13, 14, 11, 16, 12, 16, 15, 15, 13, 14, 12, 14, 10, + 9, 13, 12, 12, 12, 12, 12, 11, 13, 13, 12, 12, 12, 12, 11, 8, + 10, 13, 13, 12, 13, 12, 13, 11, 14, 14, 13, 12, 13, 12, 12, 9, + 12, 14, 16, 13, 15, 13, 15, 12, 16, 16, 16, 13, 16, 14, 14, 10, + 12, 16, 14, 14, 16, 15, 14, 13, 16, 16, 14, 14, 15, 15, 13, 11, + 12, 16, 15, 14, 16, 15, 15, 12, 16, 16, 15, 14, 16, 15, 14, 10, + 14, 16, 16, 14, 16, 15, 16, 13, 16, 16, 16, 14, 16, 16, 15, 11, + 10, 14, 14, 13, 11, 11, 13, 12, 14, 14, 13, 13, 11, 11, 12, 9, + 12, 14, 16, 14, 13, 11, 14, 12, 16, 15, 15, 14, 14, 12, 13, 10, + 13, 14, 16, 15, 14, 11, 16, 12, 16, 16, 16, 15, 16, 13, 15, 11, + 12, 16, 15, 15, 14, 14, 14, 13, 16, 16, 15, 15, 14, 14, 13, 11, + 13, 16, 16, 15, 14, 14, 15, 13, 16, 16, 16, 15, 15, 14, 14, 11, + 14, 16, 16, 15, 16, 14, 16, 13, 16, 16, 16, 15, 16, 14, 15, 11, + 15, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, 12, + 15, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 15, 12, + 15, 16, 16, 15, 16, 15, 16, 13, 16, 16, 16, 16, 16, 16, 16, 11, + 6, 10, 10, 10, 10, 10, 11, 10, 9, 10, 9, 9, 9, 9, 9, 7, + 9, 12, 13, 12, 13, 12, 14, 12, 12, 12, 12, 11, 12, 11, 11, 8, + 12, 14, 16, 14, 16, 14, 16, 14, 15, 14, 15, 13, 16, 13, 14, 11, + 8, 12, 11, 11, 12, 12, 12, 11, 11, 12, 10, 10, 11, 11, 10, 8, + 10, 13, 13, 12, 14, 13, 14, 12, 13, 13, 12, 11, 13, 12, 12, 9, + 12, 15, 15, 13, 16, 15, 16, 14, 16, 15, 15, 12, 16, 14, 15, 10, + 11, 15, 13, 13, 16, 15, 14, 13, 14, 15, 11, 12, 14, 14, 12, 10, + 12, 16, 14, 13, 16, 16, 16, 14, 16, 15, 13, 12, 15, 15, 14, 10, + 14, 16, 16, 14, 16, 16, 16, 14, 16, 16, 15, 13, 16, 16, 15, 11, + 8, 12, 12, 12, 11, 11, 12, 11, 11, 12, 11, 11, 9, 10, 10, 8, + 10, 13, 14, 13, 13, 12, 14, 12, 13, 13, 13, 12, 12, 11, 12, 9, + 13, 15, 16, 15, 16, 14, 16, 14, 16, 15, 16, 14, 15, 13, 15, 11, + 10, 13, 13, 13, 13, 13, 13, 12, 13, 14, 12, 12, 12, 12, 11, 9, + 10, 13, 13, 13, 13, 13, 14, 12, 13, 14, 13, 12, 12, 12, 12, 9, + 12, 15, 15, 14, 16, 14, 16, 13, 16, 15, 15, 13, 15, 13, 14, 10, + 13, 16, 15, 15, 16, 16, 15, 14, 16, 16, 13, 14, 15, 15, 12, 10, + 12, 16, 14, 14, 16, 16, 15, 13, 16, 16, 14, 13, 15, 14, 13, 10, + 13, 16, 16, 14, 16, 15, 16, 13, 16, 16, 16, 13, 16, 15, 15, 10, + 11, 15, 15, 14, 13, 13, 14, 13, 13, 15, 14, 14, 11, 12, 12, 10, + 12, 15, 16, 15, 14, 13, 16, 14, 16, 15, 16, 14, 13, 12, 13, 10, + 14, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 16, 13, 16, 11, + 12, 16, 16, 16, 15, 15, 15, 14, 15, 16, 14, 14, 13, 14, 12, 10, + 12, 16, 16, 15, 15, 14, 16, 13, 16, 16, 15, 14, 14, 13, 13, 10, + 13, 16, 16, 15, 16, 14, 16, 13, 16, 16, 16, 15, 16, 14, 15, 10, + 15, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 13, 12, + 14, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 15, 16, 15, 14, 11, + 14, 16, 16, 15, 16, 16, 16, 13, 16, 16, 16, 15, 16, 15, 14, 10, + 10, 14, 13, 13, 13, 13, 14, 13, 11, 13, 11, 11, 11, 11, 11, 9, + 12, 15, 16, 15, 16, 15, 16, 14, 14, 14, 14, 13, 14, 13, 14, 11, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 14, 16, 12, + 11, 15, 14, 14, 15, 15, 15, 14, 13, 14, 11, 12, 13, 13, 12, 10, + 13, 16, 15, 15, 16, 16, 16, 15, 15, 15, 13, 12, 15, 14, 13, 10, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 12, + 13, 16, 14, 15, 16, 16, 16, 15, 14, 16, 11, 12, 15, 15, 12, 10, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 13, 16, 16, 14, 11, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 11, + 11, 15, 15, 14, 13, 14, 14, 14, 13, 14, 13, 13, 11, 12, 11, 10, + 12, 16, 16, 16, 16, 15, 16, 15, 15, 15, 15, 14, 13, 12, 14, 10, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 14, 16, 12, + 12, 16, 15, 15, 16, 16, 16, 14, 14, 15, 13, 13, 13, 13, 12, 10, + 12, 16, 16, 15, 15, 15, 16, 14, 14, 15, 14, 13, 14, 13, 13, 10, + 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 16, 14, 15, 11, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 15, 15, 12, 11, + 13, 16, 16, 15, 16, 16, 16, 14, 16, 16, 14, 13, 16, 14, 13, 10, + 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 16, 14, 15, 10, + 12, 16, 16, 15, 14, 15, 16, 14, 13, 15, 14, 14, 11, 12, 12, 10, + 13, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 15, 13, 12, 14, 11, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 11, + 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 15, 15, 13, 14, 12, 11, + 13, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, 14, 13, 13, 10, + 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 15, 15, 14, 14, 10, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 15, 16, 13, 11, + 14, 16, 16, 16, 16, 16, 16, 14, 16, 16, 15, 14, 15, 14, 13, 10, + 12, 15, 15, 14, 15, 14, 16, 14, 14, 16, 15, 13, 14, 13, 13, 9, +}, +{ + 2, 5, 5, 5, 5, 5, 6, 6, 5, 6, 5, 6, 5, 6, 6, 4, + 6, 8, 10, 8, 10, 9, 11, 9, 10, 10, 10, 9, 10, 9, 10, 8, + 10, 11, 13, 11, 13, 11, 14, 11, 14, 13, 13, 12, 13, 12, 13, 10, + 6, 10, 8, 9, 10, 10, 10, 9, 10, 11, 9, 9, 10, 10, 9, 7, + 8, 11, 11, 10, 12, 11, 12, 10, 12, 12, 11, 10, 12, 12, 11, 9, + 11, 13, 14, 11, 15, 14, 15, 12, 16, 14, 14, 12, 15, 14, 14, 11, + 10, 13, 11, 11, 14, 13, 13, 12, 13, 14, 11, 11, 13, 13, 12, 10, + 11, 14, 13, 11, 16, 14, 14, 12, 15, 15, 14, 12, 15, 14, 14, 11, + 12, 14, 14, 11, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 15, 12, + 6, 10, 10, 10, 8, 9, 10, 9, 10, 11, 10, 10, 9, 9, 9, 8, + 8, 11, 12, 12, 11, 10, 12, 11, 12, 12, 12, 12, 12, 11, 12, 9, + 11, 13, 16, 14, 14, 12, 15, 12, 16, 15, 16, 14, 14, 13, 14, 11, + 9, 13, 12, 12, 12, 12, 12, 11, 13, 13, 12, 12, 12, 12, 11, 10, + 10, 13, 13, 12, 13, 12, 13, 11, 14, 14, 13, 13, 13, 13, 12, 10, + 13, 14, 16, 14, 15, 14, 16, 13, 16, 16, 16, 14, 16, 14, 15, 12, + 12, 16, 14, 14, 16, 15, 14, 13, 16, 16, 14, 14, 15, 15, 13, 12, + 13, 16, 15, 14, 16, 16, 15, 13, 16, 16, 15, 14, 16, 16, 14, 12, + 14, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 12, + 10, 13, 14, 13, 11, 11, 13, 12, 13, 14, 13, 13, 11, 12, 12, 10, + 11, 14, 15, 15, 13, 12, 14, 13, 16, 16, 16, 15, 14, 13, 14, 11, + 12, 14, 16, 16, 14, 12, 16, 13, 16, 16, 16, 16, 15, 13, 16, 12, + 12, 16, 15, 16, 14, 15, 14, 14, 16, 16, 15, 16, 14, 14, 13, 12, + 13, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 16, 16, 14, 15, 12, + 14, 16, 16, 16, 16, 14, 16, 14, 16, 16, 16, 16, 16, 15, 16, 13, + 15, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 15, 13, + 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 13, + 15, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 13, + 6, 10, 10, 10, 10, 10, 10, 10, 8, 10, 9, 9, 8, 9, 9, 7, + 9, 12, 13, 12, 13, 12, 13, 12, 12, 12, 12, 11, 12, 11, 12, 10, + 12, 14, 16, 14, 16, 14, 16, 14, 16, 15, 15, 14, 16, 14, 15, 12, + 8, 12, 11, 11, 12, 12, 12, 11, 11, 12, 10, 10, 11, 12, 10, 9, + 10, 13, 13, 12, 14, 13, 14, 12, 13, 13, 12, 11, 13, 13, 12, 10, + 13, 15, 16, 14, 16, 16, 16, 14, 16, 15, 15, 13, 16, 15, 15, 12, + 11, 15, 13, 13, 15, 15, 15, 14, 14, 14, 11, 12, 14, 14, 12, 11, + 13, 16, 14, 14, 16, 16, 16, 14, 16, 15, 13, 13, 16, 14, 14, 11, + 14, 16, 16, 14, 16, 16, 16, 15, 16, 16, 16, 14, 16, 16, 16, 12, + 8, 12, 12, 12, 11, 11, 12, 12, 11, 12, 11, 11, 9, 10, 10, 9, + 10, 13, 14, 13, 13, 12, 14, 13, 13, 13, 13, 13, 12, 11, 12, 10, + 13, 15, 16, 15, 16, 14, 16, 14, 16, 16, 16, 15, 16, 13, 15, 12, + 10, 14, 13, 13, 13, 13, 13, 13, 13, 14, 12, 12, 12, 12, 11, 10, + 10, 13, 13, 13, 13, 13, 14, 12, 13, 14, 13, 12, 13, 12, 12, 10, + 13, 16, 16, 14, 16, 15, 16, 14, 16, 16, 15, 14, 16, 14, 15, 11, + 13, 16, 15, 16, 16, 16, 15, 14, 16, 16, 14, 14, 15, 15, 13, 12, + 13, 16, 15, 14, 16, 16, 16, 14, 16, 16, 14, 14, 15, 15, 14, 11, + 14, 16, 16, 15, 16, 16, 16, 14, 16, 16, 16, 15, 16, 16, 15, 12, + 11, 14, 15, 14, 13, 13, 14, 14, 13, 15, 14, 14, 11, 12, 12, 11, + 13, 16, 16, 16, 14, 14, 16, 14, 16, 16, 16, 15, 14, 13, 14, 12, + 14, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 14, 16, 13, + 13, 16, 16, 16, 15, 16, 15, 15, 16, 16, 15, 16, 14, 14, 13, 12, + 13, 16, 16, 15, 15, 14, 16, 14, 16, 16, 16, 15, 14, 14, 14, 11, + 14, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 15, 16, 12, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 13, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, + 9, 13, 13, 13, 13, 13, 14, 13, 10, 12, 11, 12, 11, 12, 11, 10, + 12, 15, 16, 15, 16, 16, 16, 16, 14, 14, 14, 13, 14, 13, 14, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 14, + 11, 15, 14, 14, 15, 14, 15, 14, 13, 14, 11, 12, 13, 13, 12, 11, + 13, 16, 16, 15, 16, 16, 16, 15, 15, 15, 14, 13, 16, 15, 14, 12, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 13, + 12, 16, 14, 15, 16, 16, 16, 16, 14, 16, 11, 13, 15, 16, 13, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 16, 16, 15, 12, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 13, + 11, 15, 14, 14, 13, 14, 15, 14, 12, 14, 13, 13, 11, 12, 12, 11, + 13, 16, 16, 16, 16, 15, 16, 16, 15, 15, 15, 15, 14, 13, 14, 12, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 13, + 13, 16, 16, 16, 16, 16, 16, 15, 14, 16, 13, 14, 13, 14, 13, 11, + 13, 16, 16, 16, 16, 16, 16, 15, 15, 16, 15, 14, 14, 14, 14, 11, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 15, 16, 16, 13, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 16, 16, 15, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, + 11, 16, 16, 15, 13, 15, 16, 15, 13, 15, 15, 15, 11, 12, 12, 11, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 15, 12, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 13, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 14, 14, 13, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 12, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 14, 13, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 12, + 12, 14, 14, 14, 14, 15, 16, 14, 14, 16, 15, 14, 14, 15, 14, 11, +}, +{ + 1, 5, 5, 6, 5, 6, 7, 7, 5, 7, 6, 7, 5, 6, 6, 6, + 6, 9, 10, 9, 10, 9, 11, 10, 11, 11, 11, 10, 11, 10, 11, 9, + 10, 11, 14, 12, 14, 12, 16, 12, 16, 13, 16, 13, 14, 13, 16, 12, + 6, 10, 9, 9, 10, 11, 11, 10, 10, 11, 9, 10, 10, 11, 10, 9, + 8, 11, 11, 10, 13, 12, 13, 12, 13, 13, 12, 12, 13, 13, 13, 11, + 11, 13, 16, 12, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, 13, + 10, 14, 11, 12, 14, 14, 13, 13, 13, 16, 12, 13, 14, 16, 13, 12, + 11, 14, 13, 12, 16, 16, 16, 14, 16, 16, 14, 14, 16, 16, 16, 13, + 12, 14, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 6, 10, 10, 11, 9, 9, 11, 10, 10, 11, 11, 11, 9, 10, 10, 9, + 9, 12, 13, 12, 12, 11, 13, 12, 13, 13, 13, 13, 12, 12, 13, 11, + 12, 13, 16, 16, 16, 13, 16, 14, 16, 16, 16, 16, 16, 14, 16, 13, + 9, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13, 13, 12, 11, + 10, 14, 14, 13, 14, 13, 14, 13, 16, 16, 14, 15, 14, 14, 14, 12, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 14, 14, 16, 11, 12, 14, 13, 14, 16, 16, 16, 12, 13, 13, 12, + 12, 16, 16, 16, 13, 13, 16, 14, 16, 16, 16, 16, 16, 14, 16, 13, + 13, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 6, 10, 10, 10, 10, 11, 11, 11, 9, 11, 9, 10, 9, 10, 10, 9, + 9, 13, 13, 13, 13, 13, 14, 13, 12, 13, 13, 12, 13, 12, 13, 11, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 8, 13, 12, 12, 13, 13, 13, 13, 11, 13, 10, 12, 12, 13, 12, 11, + 10, 14, 13, 13, 16, 16, 16, 14, 14, 14, 13, 13, 14, 14, 14, 12, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 11, 16, 13, 16, 16, 16, 16, 16, 14, 16, 12, 13, 16, 16, 14, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 13, 13, 13, 11, 12, 13, 13, 11, 13, 12, 13, 10, 12, 12, 11, + 10, 14, 16, 16, 14, 13, 16, 14, 14, 16, 16, 14, 13, 13, 14, 12, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 16, 14, 16, 14, 14, 14, 14, 13, 16, 13, 14, 13, 14, 12, 12, + 10, 14, 14, 14, 14, 16, 16, 14, 14, 16, 14, 14, 14, 14, 14, 12, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, 12, 14, 14, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 14, 13, 14, 13, 14, 16, 16, 11, 13, 12, 13, 11, 13, 12, 12, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 14, 16, 16, 16, 16, 16, 13, 16, 12, 13, 14, 16, 13, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 14, 16, 12, 16, 16, 16, 14, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 14, 16, 16, 16, 13, 16, 14, 16, 12, 13, 13, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, 12, 16, 14, 14, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 13, +}, +{ + 1, 5, 5, 6, 5, 6, 7, 8, 5, 7, 6, 8, 6, 7, 7, 7, + 5, 9, 10, 10, 10, 10, 12, 11, 10, 11, 11, 11, 10, 11, 12, 10, + 9, 11, 13, 12, 13, 12, 16, 14, 16, 14, 16, 16, 16, 13, 16, 13, + 5, 10, 9, 10, 10, 11, 11, 11, 10, 11, 9, 11, 10, 11, 11, 10, + 8, 11, 11, 11, 12, 13, 13, 13, 12, 13, 12, 12, 13, 13, 13, 12, + 11, 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 14, 11, 12, 14, 16, 13, 14, 13, 16, 12, 14, 16, 16, 13, 13, + 11, 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 14, 14, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 10, 11, 11, 9, 10, 11, 11, 10, 12, 11, 12, 9, 11, 11, 11, + 8, 12, 13, 13, 11, 11, 14, 13, 13, 14, 13, 16, 12, 12, 13, 12, + 11, 13, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 13, 12, 13, 12, 13, 13, 14, 13, 16, 13, 16, 13, 16, 13, 13, + 10, 14, 13, 14, 13, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 14, 16, 16, 11, 12, 14, 16, 13, 16, 16, 16, 12, 14, 13, 13, + 11, 16, 16, 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 14, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 10, 10, 11, 10, 11, 12, 12, 8, 11, 10, 11, 9, 11, 11, 11, + 9, 12, 13, 13, 13, 13, 16, 16, 12, 13, 13, 13, 13, 13, 16, 13, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 13, 11, 13, 12, 13, 13, 14, 11, 13, 10, 13, 12, 14, 12, 12, + 10, 14, 13, 14, 16, 16, 16, 16, 13, 16, 13, 14, 16, 16, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 13, 16, 16, 16, 16, 16, 13, 16, 12, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 13, 13, 13, 11, 13, 14, 16, 11, 13, 13, 14, 10, 12, 12, 12, + 10, 14, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, 13, 13, 16, 14, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 14, 16, 13, 16, 16, 16, 13, 16, 13, 16, 13, 16, 13, 14, + 10, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 13, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, 12, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 14, 13, 16, 13, 16, 16, 16, 10, 14, 12, 14, 11, 13, 13, 13, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 12, 16, 12, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 16, 16, 16, 16, 13, 16, 13, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 16, 16, 14, 16, 16, 16, 12, 16, 16, 16, 12, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 14, 16, 16, 16, 14, 16, 16, 16, 12, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 14, +} +}; + + +static const uint8_t rv34_inter_cbp[NUM_INTER_TABLES][4][CBP_VLC_SIZE] = { +{ + { 0, 6, 6, 3, 6, 4, 5, 3, 6, 5, 4, 3, 3, 4, 4, 3 }, + { 0, 6, 6, 4, 6, 4, 5, 3, 6, 5, 4, 3, 4, 4, 4, 2 }, + { 0, 7, 7, 4, 7, 5, 5, 4, 7, 5, 5, 4, 5, 4, 4, 1 }, + { 0, 7, 7, 5, 7, 5, 6, 4, 7, 6, 5, 3, 5, 4, 4, 1 } +}, +{ + { 0, 6, 6, 3, 6, 3, 5, 4, 6, 5, 3, 4, 3, 4, 4, 3 }, + { 0, 6, 6, 4, 6, 4, 4, 4, 6, 4, 4, 3, 4, 4, 4, 2 }, + { 0, 6, 6, 4, 6, 4, 5, 4, 6, 5, 4, 3, 4, 4, 3, 2 }, + { 0, 7, 7, 5, 7, 5, 6, 4, 7, 6, 5, 3, 5, 4, 4, 1 } +}, +{ + { 0, 6, 6, 3, 6, 3, 5, 4, 6, 5, 3, 4, 3, 4, 4, 3 }, + { 0, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2 }, + { 0, 6, 6, 4, 6, 4, 5, 3, 6, 5, 4, 3, 4, 4, 4, 2 }, + { 0, 7, 7, 5, 7, 5, 6, 4, 7, 6, 5, 3, 5, 4, 4, 1 } +}, +{ + { 0, 6, 6, 3, 6, 3, 5, 4, 6, 5, 3, 4, 3, 4, 4, 3 }, + { 0, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2 }, + { 0, 6, 6, 4, 6, 4, 5, 3, 6, 5, 4, 3, 4, 4, 4, 2 }, + { 0, 7, 7, 4, 7, 5, 6, 4, 7, 6, 5, 4, 4, 4, 4, 1 } +}, +{ + { 0, 5, 5, 3, 5, 3, 5, 4, 5, 5, 3, 4, 3, 4, 4, 4 }, + { 0, 5, 5, 3, 5, 4, 5, 4, 5, 5, 3, 4, 3, 4, 4, 3 }, + { 0, 6, 6, 4, 6, 4, 5, 4, 6, 5, 4, 3, 4, 4, 3, 2 }, + { 0, 7, 7, 4, 7, 5, 6, 4, 7, 6, 5, 4, 4, 4, 4, 1 } +}, +{ + { 0, 5, 5, 3, 5, 3, 5, 4, 5, 5, 3, 4, 3, 4, 4, 4 }, + { 0, 5, 5, 3, 5, 4, 5, 4, 5, 5, 3, 4, 3, 4, 4, 3 }, + { 0, 5, 5, 3, 5, 4, 4, 4, 5, 4, 4, 4, 3, 4, 4, 3 }, + { 0, 6, 6, 4, 6, 4, 5, 4, 6, 5, 4, 3, 4, 4, 3, 2 } +}, +{ + { 0, 4, 4, 3, 4, 3, 5, 5, 4, 5, 3, 5, 3, 5, 4, 5 }, + { 0, 4, 4, 3, 4, 4, 5, 4, 4, 5, 3, 5, 3, 5, 4, 4 }, + { 0, 4, 4, 3, 4, 4, 5, 4, 4, 5, 4, 4, 3, 4, 4, 4 }, + { 0, 4, 4, 3, 5, 4, 5, 4, 5, 5, 4, 4, 3, 4, 4, 3 } +} +}; + + +static const uint8_t rv34_table_inter_firstpat[NUM_INTER_TABLES][2][FIRSTBLK_VLC_SIZE] = { + { + { + 0, 7, 5, 7, 5, 7, 6, 6, 7, 10, 7, 9, 8, 9, 8, 7, + 12, 14, 11, 12, 12, 12, 11, 9, 6, 9, 6, 8, 7, 9, 7, 7, + 8, 11, 8, 9, 9, 10, 9, 8, 13, 15, 12, 12, 12, 13, 11, 9, + 10, 13, 9, 10, 11, 12, 9, 8, 12, 14, 10, 11, 12, 13, 10, 9, + 16, 16, 12, 12, 14, 13, 11, 9, 6, 9, 7, 9, 7, 9, 8, 7, + 9, 11, 9, 10, 9, 10, 9, 8, 14, 16, 12, 12, 13, 13, 11, 9, + 8, 11, 8, 10, 9, 10, 9, 8, 10, 13, 10, 11, 10, 11, 9, 8, + 14, 16, 12, 12, 13, 13, 11, 9, 12, 14, 10, 11, 12, 13, 10, 9, + 13, 16, 11, 12, 13, 13, 10, 9, 16, 16, 13, 12, 14, 14, 11, 9, + 11, 13, 11, 12, 10, 11, 10, 9, 13, 14, 12, 12, 11, 12, 10, 9, + 16, 16, 13, 13, 13, 13, 11, 9, 12, 15, 12, 12, 11, 12, 10, 9, + 13, 16, 13, 13, 12, 12, 11, 9, 16, 16, 14, 13, 13, 13, 11, 9, + 14, 16, 13, 13, 13, 14, 11, 9, 16, 16, 13, 13, 14, 14, 11, 9, + 16, 16, 13, 13, 14, 13, 11, 8, 4, 9, 6, 8, 6, 9, 7, 7, + 8, 11, 8, 9, 9, 10, 8, 8, 13, 15, 12, 12, 13, 13, 11, 9, + 7, 10, 7, 9, 8, 10, 8, 8, 9, 12, 9, 10, 10, 11, 9, 8, + 14, 16, 12, 12, 13, 13, 11, 9, 11, 13, 9, 10, 11, 12, 9, 8, + 12, 14, 10, 11, 12, 13, 10, 9, 16, 16, 13, 12, 14, 14, 11, 9, + 7, 10, 8, 9, 8, 10, 8, 8, 10, 12, 10, 11, 10, 11, 9, 8, + 14, 16, 13, 13, 13, 13, 11, 9, 9, 12, 9, 10, 9, 11, 9, 8, + 11, 13, 10, 11, 10, 11, 10, 9, 15, 16, 13, 13, 13, 13, 11, 9, + 12, 14, 11, 11, 12, 13, 10, 9, 13, 16, 11, 12, 13, 13, 10, 9, + 16, 16, 12, 12, 14, 13, 11, 8, 11, 14, 11, 12, 10, 11, 10, 9, + 13, 15, 12, 13, 11, 12, 10, 9, 16, 16, 14, 13, 13, 13, 11, 9, + 12, 15, 12, 13, 11, 12, 10, 9, 13, 16, 13, 13, 12, 12, 11, 9, + 16, 16, 14, 13, 13, 13, 11, 9, 15, 16, 13, 13, 13, 13, 11, 9, + 16, 16, 13, 13, 13, 13, 11, 9, 16, 16, 13, 12, 13, 13, 10, 7, + 8, 11, 8, 10, 9, 11, 9, 9, 10, 13, 10, 11, 11, 12, 10, 9, + 15, 16, 13, 13, 14, 14, 12, 10, 9, 12, 9, 11, 10, 11, 9, 9, + 12, 14, 11, 11, 11, 12, 10, 9, 16, 16, 13, 13, 14, 14, 12, 10, + 12, 14, 10, 11, 12, 13, 10, 9, 14, 16, 11, 12, 13, 14, 10, 9, + 16, 16, 13, 13, 15, 14, 11, 9, 9, 12, 10, 11, 9, 11, 10, 9, + 12, 14, 11, 12, 11, 12, 10, 9, 16, 16, 14, 13, 14, 14, 12, 10, + 11, 14, 10, 12, 11, 12, 10, 9, 12, 15, 11, 12, 12, 13, 11, 10, + 16, 16, 14, 13, 14, 14, 12, 10, 13, 16, 11, 12, 13, 14, 11, 9, + 14, 16, 12, 12, 13, 14, 11, 9, 16, 16, 13, 13, 14, 14, 11, 9, + 12, 15, 12, 13, 10, 12, 10, 9, 14, 16, 13, 13, 11, 12, 11, 10, + 16, 16, 14, 14, 14, 13, 12, 9, 13, 16, 13, 13, 12, 13, 11, 10, + 14, 16, 13, 13, 12, 13, 11, 10, 16, 16, 14, 14, 13, 13, 12, 9, + 15, 16, 13, 13, 13, 14, 11, 9, 16, 16, 13, 13, 13, 14, 11, 9, + 16, 16, 13, 12, 13, 13, 10, 8, 10, 13, 10, 11, 10, 12, 10, 9, + 12, 14, 11, 12, 12, 13, 11, 10, 16, 16, 13, 13, 14, 14, 12, 9, + 11, 14, 10, 11, 11, 12, 10, 9, 13, 16, 11, 12, 12, 13, 11, 10, + 16, 16, 14, 13, 14, 14, 12, 9, 12, 15, 10, 11, 12, 13, 9, 8, + 14, 16, 11, 11, 13, 14, 10, 8, 16, 16, 12, 12, 14, 14, 10, 8, + 11, 14, 11, 12, 11, 12, 10, 9, 13, 16, 12, 13, 12, 13, 11, 10, + 16, 16, 14, 13, 14, 14, 12, 9, 12, 15, 11, 12, 11, 13, 10, 10, + 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 14, 13, 14, 14, 12, 9, + 13, 16, 11, 11, 13, 13, 10, 8, 14, 16, 11, 12, 13, 14, 10, 8, + 16, 16, 12, 12, 14, 14, 10, 8, 12, 15, 12, 13, 10, 11, 10, 9, + 14, 16, 13, 13, 11, 12, 10, 9, 16, 16, 14, 13, 13, 13, 11, 8, + 13, 16, 12, 13, 11, 12, 10, 9, 14, 16, 13, 13, 12, 12, 10, 9, + 16, 16, 14, 13, 13, 12, 10, 8, 14, 16, 12, 12, 12, 13, 10, 8, + 14, 16, 12, 12, 12, 13, 10, 7, 16, 16, 11, 11, 12, 11, 8, 5, + }, + { + 0, 7, 4, 8, 5, 8, 7, 8, 6, 10, 7, 10, 8, 10, 9, 9, + 13, 16, 12, 13, 13, 14, 12, 12, 4, 10, 6, 9, 8, 11, 8, 9, + 8, 12, 8, 11, 10, 12, 10, 10, 14, 16, 12, 13, 14, 15, 12, 12, + 9, 14, 9, 11, 12, 14, 11, 11, 11, 15, 10, 12, 13, 14, 11, 11, + 15, 16, 13, 14, 15, 16, 13, 12, 5, 10, 7, 10, 7, 10, 9, 9, + 8, 12, 9, 11, 10, 11, 10, 10, 14, 16, 13, 14, 14, 14, 12, 12, + 8, 12, 8, 11, 10, 12, 10, 10, 10, 14, 10, 12, 11, 13, 10, 11, + 15, 16, 13, 14, 14, 15, 13, 12, 11, 16, 10, 12, 13, 15, 11, 11, + 13, 16, 11, 13, 14, 15, 12, 12, 16, 16, 14, 14, 16, 16, 13, 12, + 11, 15, 11, 13, 11, 13, 11, 11, 13, 16, 12, 14, 12, 13, 12, 12, + 16, 16, 14, 15, 15, 15, 13, 12, 12, 16, 12, 14, 12, 14, 12, 12, + 14, 16, 13, 14, 13, 14, 12, 12, 16, 16, 14, 16, 16, 16, 13, 12, + 14, 16, 13, 14, 15, 16, 13, 12, 16, 16, 14, 15, 16, 16, 13, 12, + 16, 16, 15, 16, 16, 16, 13, 12, 2, 9, 5, 8, 6, 9, 8, 9, + 7, 11, 8, 10, 9, 11, 9, 10, 13, 16, 12, 13, 14, 14, 12, 12, + 5, 11, 6, 10, 9, 11, 9, 9, 9, 13, 9, 11, 10, 12, 10, 10, + 14, 16, 12, 14, 14, 15, 12, 12, 9, 14, 9, 11, 12, 14, 10, 11, + 11, 16, 10, 12, 13, 14, 11, 11, 16, 16, 13, 14, 15, 16, 13, 12, + 6, 11, 7, 10, 8, 11, 9, 9, 9, 13, 9, 11, 10, 12, 10, 10, + 14, 16, 13, 14, 14, 14, 12, 12, 8, 13, 8, 11, 10, 12, 10, 10, + 10, 13, 10, 12, 11, 13, 10, 11, 14, 16, 13, 14, 14, 15, 12, 12, + 11, 15, 10, 12, 13, 15, 11, 11, 12, 16, 11, 13, 13, 15, 12, 11, + 16, 16, 13, 14, 15, 16, 13, 12, 11, 15, 11, 13, 10, 13, 11, 11, + 13, 16, 12, 14, 12, 13, 12, 11, 16, 16, 14, 15, 15, 15, 13, 12, + 12, 16, 12, 13, 12, 14, 12, 12, 13, 16, 12, 14, 13, 14, 12, 12, + 16, 16, 14, 15, 15, 15, 13, 12, 14, 16, 13, 14, 15, 16, 12, 12, + 16, 16, 13, 14, 15, 16, 12, 12, 16, 16, 14, 15, 16, 16, 13, 12, + 6, 12, 7, 10, 9, 12, 9, 10, 9, 13, 9, 12, 11, 13, 11, 11, + 14, 16, 13, 14, 15, 15, 13, 12, 8, 13, 8, 11, 10, 13, 10, 10, + 10, 14, 10, 12, 12, 14, 11, 11, 15, 16, 13, 14, 16, 16, 13, 12, + 10, 15, 9, 12, 12, 15, 11, 11, 12, 16, 11, 13, 14, 16, 12, 12, + 16, 16, 14, 14, 16, 16, 13, 12, 8, 13, 9, 11, 10, 12, 10, 11, + 11, 14, 11, 12, 11, 13, 11, 11, 16, 16, 14, 15, 15, 16, 13, 12, + 10, 14, 10, 12, 11, 13, 11, 11, 11, 15, 11, 13, 12, 14, 11, 11, + 15, 16, 13, 14, 15, 16, 13, 12, 12, 16, 11, 13, 13, 16, 12, 12, + 13, 16, 11, 13, 14, 16, 12, 12, 16, 16, 13, 14, 16, 16, 13, 12, + 12, 16, 12, 14, 11, 13, 11, 11, 13, 16, 13, 14, 12, 14, 12, 12, + 16, 16, 15, 16, 16, 16, 14, 13, 13, 16, 12, 14, 12, 14, 12, 12, + 14, 16, 13, 14, 13, 14, 12, 12, 16, 16, 14, 16, 14, 16, 13, 12, + 15, 16, 13, 15, 15, 16, 13, 12, 15, 16, 13, 15, 14, 16, 13, 12, + 16, 16, 14, 15, 15, 16, 13, 11, 8, 13, 8, 11, 10, 13, 10, 11, + 11, 15, 10, 12, 12, 14, 11, 11, 15, 16, 13, 14, 15, 15, 13, 12, + 9, 14, 9, 12, 11, 14, 10, 11, 11, 16, 10, 12, 13, 14, 11, 11, + 16, 16, 13, 14, 15, 16, 13, 12, 11, 15, 9, 12, 12, 14, 10, 10, + 12, 16, 11, 12, 14, 15, 11, 11, 16, 16, 13, 14, 16, 16, 12, 11, + 9, 14, 10, 12, 11, 13, 11, 11, 12, 16, 11, 13, 12, 14, 11, 11, + 16, 16, 14, 14, 15, 15, 13, 12, 10, 15, 10, 12, 12, 14, 11, 11, + 12, 16, 11, 13, 13, 14, 11, 11, 16, 16, 14, 14, 15, 16, 13, 12, + 12, 16, 10, 12, 13, 15, 11, 11, 13, 16, 11, 13, 14, 15, 11, 11, + 16, 16, 13, 13, 15, 16, 12, 11, 12, 16, 11, 13, 10, 13, 11, 11, + 14, 16, 13, 14, 12, 14, 11, 11, 16, 16, 15, 16, 14, 15, 13, 11, + 13, 16, 12, 14, 12, 14, 11, 11, 13, 16, 12, 14, 12, 14, 11, 11, + 16, 16, 14, 15, 14, 14, 12, 11, 14, 16, 12, 13, 13, 15, 11, 11, + 14, 16, 12, 13, 13, 14, 11, 11, 15, 16, 12, 13, 13, 13, 10, 9, + }, + }, + { + { + 0, 7, 4, 7, 5, 7, 6, 6, 6, 10, 7, 8, 8, 9, 8, 7, + 13, 14, 11, 12, 12, 12, 11, 9, 5, 9, 6, 8, 7, 9, 7, 7, + 8, 11, 8, 9, 9, 10, 9, 8, 13, 16, 12, 12, 12, 13, 11, 9, + 10, 13, 8, 10, 11, 12, 9, 9, 12, 14, 10, 11, 12, 13, 10, 9, + 15, 16, 12, 12, 14, 14, 11, 9, 6, 10, 7, 9, 7, 9, 8, 7, + 8, 11, 9, 10, 9, 10, 9, 8, 14, 16, 12, 12, 13, 12, 11, 9, + 8, 11, 8, 10, 9, 10, 9, 8, 10, 13, 10, 11, 10, 11, 9, 9, + 14, 16, 12, 12, 13, 13, 11, 9, 12, 15, 10, 11, 12, 13, 10, 9, + 13, 16, 11, 12, 13, 13, 10, 9, 16, 16, 12, 13, 14, 14, 11, 9, + 10, 14, 11, 12, 9, 11, 10, 9, 12, 15, 12, 13, 11, 12, 11, 9, + 16, 16, 13, 13, 13, 13, 11, 9, 12, 15, 12, 13, 11, 12, 11, 9, + 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 13, 13, 13, 13, 11, 9, + 14, 16, 13, 13, 13, 14, 11, 10, 16, 16, 13, 13, 13, 14, 11, 10, + 16, 16, 13, 13, 14, 14, 11, 9, 4, 9, 6, 8, 6, 9, 7, 7, + 8, 11, 8, 9, 9, 10, 9, 8, 13, 15, 12, 12, 13, 13, 11, 9, + 6, 10, 7, 9, 8, 10, 8, 8, 9, 12, 9, 10, 10, 11, 9, 8, + 14, 16, 12, 12, 13, 13, 11, 10, 10, 13, 8, 10, 11, 12, 9, 9, + 12, 15, 10, 11, 12, 13, 10, 9, 16, 16, 12, 12, 14, 14, 11, 9, + 7, 11, 8, 9, 7, 10, 8, 8, 9, 12, 10, 11, 9, 11, 9, 9, + 14, 16, 12, 13, 13, 13, 11, 10, 9, 12, 9, 10, 9, 11, 9, 9, + 10, 13, 10, 11, 10, 11, 10, 9, 14, 16, 12, 13, 13, 13, 11, 9, + 12, 15, 10, 11, 12, 13, 10, 9, 13, 16, 11, 12, 13, 13, 10, 9, + 16, 16, 12, 12, 14, 14, 11, 9, 10, 14, 11, 12, 9, 11, 10, 9, + 12, 16, 12, 13, 11, 12, 11, 9, 16, 16, 14, 14, 13, 13, 11, 9, + 12, 16, 12, 13, 11, 12, 10, 10, 13, 16, 12, 13, 11, 12, 11, 10, + 16, 16, 13, 13, 13, 13, 11, 9, 14, 16, 13, 13, 13, 14, 11, 9, + 15, 16, 13, 13, 13, 14, 11, 9, 16, 16, 13, 13, 13, 13, 10, 8, + 7, 11, 8, 10, 9, 11, 9, 9, 10, 13, 10, 11, 11, 12, 10, 10, + 15, 16, 13, 13, 14, 14, 12, 10, 9, 13, 9, 11, 10, 12, 10, 9, + 11, 14, 10, 12, 12, 13, 10, 10, 16, 16, 13, 13, 14, 14, 12, 10, + 11, 15, 9, 11, 12, 13, 10, 9, 13, 16, 11, 12, 13, 14, 11, 10, + 16, 16, 13, 13, 15, 15, 11, 10, 9, 13, 10, 11, 9, 11, 10, 9, + 11, 14, 11, 12, 11, 12, 11, 10, 16, 16, 14, 14, 14, 14, 12, 10, + 10, 14, 10, 12, 11, 12, 10, 10, 12, 15, 11, 12, 12, 13, 11, 10, + 16, 16, 13, 13, 14, 14, 12, 10, 13, 16, 11, 12, 13, 14, 11, 10, + 13, 16, 11, 12, 13, 14, 11, 10, 16, 16, 12, 13, 14, 14, 11, 9, + 11, 15, 12, 13, 10, 12, 10, 10, 13, 16, 13, 14, 11, 13, 11, 10, + 16, 16, 14, 14, 14, 14, 12, 10, 13, 16, 13, 13, 11, 13, 11, 10, + 14, 16, 13, 14, 12, 13, 11, 10, 16, 16, 14, 14, 13, 13, 12, 10, + 15, 16, 13, 14, 14, 14, 11, 10, 15, 16, 13, 13, 13, 14, 11, 10, + 16, 16, 12, 13, 13, 13, 10, 8, 9, 13, 10, 11, 10, 12, 10, 10, + 12, 15, 11, 12, 12, 13, 11, 10, 16, 16, 14, 13, 14, 14, 12, 10, + 10, 14, 10, 12, 11, 13, 10, 10, 13, 16, 11, 12, 12, 14, 11, 10, + 16, 16, 13, 13, 14, 14, 12, 10, 12, 16, 9, 11, 12, 14, 10, 9, + 13, 16, 10, 12, 13, 14, 10, 9, 16, 16, 12, 12, 14, 14, 11, 9, + 10, 14, 11, 12, 10, 12, 10, 10, 13, 16, 12, 13, 12, 13, 11, 10, + 16, 16, 14, 14, 14, 14, 12, 10, 11, 16, 11, 12, 11, 13, 11, 10, + 13, 16, 12, 13, 12, 14, 11, 10, 16, 16, 14, 14, 14, 14, 12, 10, + 13, 16, 11, 12, 13, 14, 10, 9, 14, 16, 11, 12, 13, 14, 10, 9, + 16, 16, 12, 12, 14, 14, 10, 8, 12, 16, 12, 13, 10, 12, 10, 9, + 14, 16, 13, 13, 11, 12, 11, 9, 16, 16, 14, 14, 13, 13, 11, 9, + 13, 16, 12, 13, 11, 12, 10, 9, 14, 16, 13, 13, 11, 13, 11, 9, + 16, 16, 14, 14, 13, 13, 11, 9, 14, 16, 12, 13, 12, 13, 10, 8, + 14, 16, 12, 12, 12, 13, 10, 8, 15, 16, 11, 11, 11, 12, 9, 6, + }, + { + 0, 7, 4, 7, 5, 8, 7, 8, 5, 10, 7, 10, 8, 10, 9, 10, + 13, 16, 12, 14, 14, 14, 13, 12, 4, 10, 6, 9, 8, 11, 9, 9, + 8, 12, 8, 11, 10, 12, 10, 10, 14, 16, 13, 14, 14, 15, 13, 12, + 9, 14, 9, 12, 12, 14, 11, 11, 12, 16, 11, 13, 13, 15, 12, 12, + 15, 16, 14, 15, 15, 16, 13, 13, 5, 10, 7, 10, 7, 10, 9, 9, + 8, 12, 9, 11, 9, 11, 10, 10, 14, 16, 13, 14, 14, 15, 13, 12, + 7, 12, 8, 11, 10, 12, 10, 10, 10, 13, 10, 12, 11, 13, 11, 11, + 15, 16, 13, 15, 14, 16, 13, 13, 11, 16, 11, 13, 13, 16, 12, 12, + 13, 16, 12, 14, 14, 16, 12, 12, 16, 16, 14, 16, 16, 16, 14, 13, + 11, 15, 12, 14, 11, 13, 11, 12, 13, 16, 12, 14, 12, 14, 12, 12, + 16, 16, 14, 16, 14, 16, 13, 13, 13, 16, 12, 14, 12, 14, 12, 12, + 14, 16, 13, 15, 13, 15, 13, 13, 16, 16, 15, 16, 16, 16, 14, 13, + 15, 16, 13, 16, 15, 16, 13, 13, 16, 16, 14, 16, 16, 16, 14, 13, + 16, 16, 16, 16, 16, 16, 14, 13, 2, 9, 5, 8, 6, 9, 8, 9, + 7, 11, 8, 10, 9, 11, 9, 10, 14, 16, 13, 14, 14, 15, 13, 12, + 5, 11, 6, 10, 9, 11, 9, 10, 8, 13, 9, 11, 11, 12, 10, 11, + 14, 16, 13, 14, 14, 16, 13, 13, 9, 15, 9, 12, 12, 14, 11, 11, + 12, 16, 11, 13, 13, 15, 12, 12, 16, 16, 14, 15, 16, 16, 14, 13, + 6, 11, 7, 10, 8, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 11, + 14, 16, 13, 14, 14, 15, 13, 13, 8, 12, 8, 11, 10, 12, 10, 11, + 9, 13, 10, 12, 11, 13, 11, 11, 14, 16, 13, 14, 14, 16, 13, 13, + 12, 16, 11, 13, 13, 15, 12, 12, 13, 16, 11, 13, 14, 16, 12, 12, + 16, 16, 14, 15, 16, 16, 13, 13, 11, 15, 11, 14, 10, 13, 11, 12, + 13, 16, 13, 15, 12, 14, 12, 12, 16, 16, 15, 16, 15, 16, 14, 13, + 12, 16, 12, 14, 12, 14, 12, 12, 13, 16, 13, 15, 13, 14, 12, 13, + 16, 16, 15, 16, 15, 16, 13, 13, 15, 16, 13, 16, 15, 16, 13, 13, + 16, 16, 14, 16, 16, 16, 13, 13, 16, 16, 15, 16, 16, 16, 14, 13, + 5, 12, 7, 10, 9, 12, 10, 10, 9, 13, 9, 12, 11, 13, 11, 11, + 15, 16, 13, 14, 15, 15, 13, 13, 7, 13, 8, 11, 10, 13, 10, 11, + 10, 14, 10, 12, 12, 14, 11, 12, 16, 16, 14, 15, 16, 16, 14, 13, + 10, 16, 9, 12, 13, 15, 11, 12, 13, 16, 11, 13, 14, 16, 12, 12, + 16, 16, 14, 16, 16, 16, 14, 13, 8, 13, 9, 12, 9, 12, 10, 11, + 11, 15, 11, 13, 11, 13, 11, 12, 16, 16, 14, 16, 16, 16, 14, 13, + 9, 14, 10, 12, 11, 13, 11, 12, 11, 15, 11, 13, 12, 14, 12, 12, + 16, 16, 14, 16, 15, 16, 14, 13, 12, 16, 11, 14, 14, 16, 12, 12, + 13, 16, 12, 14, 14, 16, 13, 13, 16, 16, 13, 15, 16, 16, 14, 13, + 11, 16, 12, 14, 10, 13, 12, 12, 13, 16, 13, 15, 12, 14, 12, 13, + 16, 16, 16, 16, 16, 16, 14, 14, 13, 16, 13, 15, 12, 15, 12, 13, + 13, 16, 13, 15, 12, 15, 13, 13, 16, 16, 15, 16, 14, 16, 14, 13, + 16, 16, 14, 16, 16, 16, 14, 13, 15, 16, 14, 16, 15, 16, 14, 13, + 16, 16, 14, 16, 15, 16, 13, 12, 8, 14, 9, 12, 10, 14, 11, 12, + 11, 16, 10, 13, 12, 14, 12, 12, 16, 16, 14, 15, 15, 16, 14, 13, + 9, 15, 9, 12, 12, 14, 11, 12, 12, 16, 11, 13, 13, 15, 12, 12, + 16, 16, 14, 15, 16, 16, 14, 13, 11, 16, 9, 12, 13, 15, 11, 11, + 13, 16, 11, 13, 14, 16, 12, 12, 16, 16, 14, 14, 16, 16, 13, 12, + 9, 15, 10, 13, 11, 14, 11, 12, 12, 16, 11, 14, 12, 14, 12, 12, + 16, 16, 14, 16, 16, 16, 14, 13, 10, 16, 10, 13, 12, 15, 12, 12, + 12, 16, 12, 14, 13, 15, 12, 12, 16, 16, 14, 16, 16, 16, 14, 13, + 12, 16, 11, 13, 13, 16, 12, 12, 13, 16, 11, 13, 14, 16, 12, 12, + 16, 16, 13, 14, 16, 16, 13, 12, 11, 16, 12, 14, 10, 13, 11, 12, + 13, 16, 13, 15, 12, 14, 12, 12, 16, 16, 16, 16, 15, 16, 13, 12, + 12, 16, 12, 15, 12, 14, 12, 12, 13, 16, 13, 15, 12, 14, 12, 12, + 16, 16, 15, 16, 14, 15, 13, 12, 14, 16, 13, 14, 13, 16, 12, 12, + 13, 16, 12, 14, 13, 15, 12, 12, 14, 16, 12, 13, 13, 14, 11, 10, + }, + }, + { + { + 0, 7, 4, 7, 5, 7, 6, 6, 6, 10, 7, 8, 8, 9, 8, 8, + 13, 14, 11, 12, 12, 12, 11, 10, 5, 9, 6, 8, 7, 9, 7, 7, + 8, 11, 8, 9, 9, 10, 9, 8, 13, 16, 12, 12, 13, 13, 11, 10, + 10, 14, 8, 10, 11, 13, 9, 9, 12, 15, 10, 11, 12, 13, 10, 10, + 16, 16, 12, 13, 14, 14, 11, 10, 5, 10, 7, 9, 6, 9, 8, 8, + 8, 11, 9, 10, 9, 10, 9, 8, 14, 16, 12, 12, 13, 13, 11, 10, + 8, 12, 8, 10, 9, 10, 9, 9, 10, 13, 9, 11, 10, 11, 9, 9, + 14, 16, 12, 13, 13, 13, 11, 10, 12, 16, 10, 12, 12, 13, 10, 10, + 13, 16, 11, 12, 13, 14, 11, 10, 16, 16, 12, 13, 14, 14, 11, 10, + 10, 14, 11, 13, 9, 11, 10, 10, 12, 16, 12, 13, 11, 12, 11, 10, + 16, 16, 13, 14, 13, 13, 12, 10, 12, 16, 12, 13, 11, 13, 11, 10, + 13, 16, 12, 13, 12, 13, 11, 10, 16, 16, 13, 14, 13, 14, 12, 10, + 14, 16, 13, 14, 13, 14, 12, 11, 16, 16, 13, 14, 14, 15, 12, 11, + 16, 16, 13, 14, 14, 14, 11, 10, 3, 9, 5, 8, 6, 9, 7, 7, + 8, 11, 8, 10, 9, 10, 9, 8, 14, 15, 12, 12, 13, 13, 11, 10, + 6, 11, 6, 9, 8, 10, 8, 8, 9, 12, 9, 10, 10, 11, 9, 9, + 14, 16, 12, 13, 13, 13, 11, 10, 10, 14, 8, 11, 12, 13, 9, 9, + 12, 16, 10, 11, 12, 13, 10, 10, 16, 16, 12, 13, 14, 14, 11, 10, + 6, 11, 8, 10, 7, 10, 8, 8, 9, 12, 10, 11, 9, 11, 9, 9, + 14, 16, 12, 13, 13, 13, 12, 10, 9, 12, 9, 11, 9, 11, 9, 9, + 10, 13, 10, 11, 10, 12, 10, 9, 14, 16, 12, 13, 13, 13, 11, 10, + 12, 16, 10, 12, 12, 14, 10, 10, 13, 16, 10, 12, 13, 14, 11, 10, + 16, 16, 12, 13, 14, 14, 11, 10, 10, 15, 11, 13, 9, 11, 10, 10, + 12, 16, 12, 13, 11, 12, 11, 10, 16, 16, 14, 14, 13, 14, 12, 10, + 12, 16, 12, 13, 11, 13, 11, 10, 13, 16, 12, 13, 11, 13, 11, 10, + 16, 16, 13, 14, 13, 13, 12, 10, 14, 16, 13, 14, 14, 14, 11, 11, + 15, 16, 13, 14, 13, 14, 11, 10, 16, 16, 13, 13, 13, 14, 11, 9, + 7, 12, 8, 11, 9, 11, 9, 10, 10, 14, 10, 12, 11, 12, 11, 10, + 16, 16, 13, 13, 14, 14, 12, 11, 9, 13, 9, 11, 10, 12, 10, 10, + 11, 15, 10, 12, 12, 13, 11, 10, 16, 16, 13, 14, 14, 14, 12, 11, + 11, 16, 9, 11, 12, 14, 10, 10, 13, 16, 10, 12, 13, 14, 11, 10, + 16, 16, 13, 14, 16, 16, 12, 11, 9, 13, 10, 12, 9, 12, 10, 10, + 11, 15, 11, 13, 11, 13, 11, 11, 16, 16, 14, 14, 14, 14, 13, 11, + 10, 14, 10, 12, 11, 13, 11, 10, 12, 16, 11, 13, 12, 13, 11, 11, + 16, 16, 13, 14, 14, 14, 12, 11, 13, 16, 11, 13, 13, 14, 11, 11, + 13, 16, 11, 13, 13, 14, 11, 11, 16, 16, 12, 13, 14, 15, 12, 10, + 11, 16, 12, 14, 10, 12, 11, 10, 13, 16, 13, 14, 11, 13, 11, 11, + 16, 16, 15, 16, 14, 14, 13, 11, 13, 16, 13, 14, 12, 13, 11, 11, + 13, 16, 13, 14, 12, 13, 11, 11, 16, 16, 14, 14, 13, 14, 12, 11, + 15, 16, 13, 14, 14, 16, 12, 11, 14, 16, 13, 14, 13, 14, 12, 11, + 16, 16, 12, 13, 13, 14, 11, 9, 9, 14, 10, 12, 10, 13, 11, 11, + 12, 16, 12, 13, 12, 14, 12, 11, 16, 16, 14, 14, 14, 14, 13, 11, + 10, 16, 10, 13, 12, 14, 11, 11, 13, 16, 12, 13, 13, 14, 12, 11, + 16, 16, 14, 14, 15, 15, 13, 11, 12, 16, 9, 12, 13, 14, 10, 10, + 14, 16, 11, 12, 13, 15, 11, 10, 16, 16, 13, 13, 15, 16, 11, 10, + 10, 16, 11, 13, 11, 13, 11, 11, 13, 16, 12, 14, 12, 14, 12, 11, + 16, 16, 14, 14, 14, 14, 13, 11, 11, 16, 11, 13, 12, 14, 11, 11, + 13, 16, 12, 14, 13, 14, 12, 11, 16, 16, 14, 14, 14, 15, 13, 11, + 13, 16, 11, 13, 13, 14, 11, 10, 14, 16, 11, 13, 13, 14, 11, 10, + 16, 16, 12, 13, 14, 15, 11, 9, 12, 16, 12, 14, 10, 13, 11, 10, + 14, 16, 13, 14, 11, 13, 11, 10, 16, 16, 14, 15, 13, 14, 12, 10, + 13, 16, 13, 14, 11, 13, 11, 10, 14, 16, 13, 14, 12, 13, 11, 10, + 16, 16, 14, 14, 13, 13, 11, 10, 14, 16, 12, 13, 13, 14, 11, 9, + 14, 16, 12, 13, 12, 13, 10, 9, 14, 16, 11, 11, 12, 12, 9, 7, + }, + { + 0, 7, 3, 8, 5, 8, 7, 9, 5, 10, 7, 10, 8, 11, 10, 10, + 14, 16, 14, 15, 14, 16, 14, 14, 4, 10, 6, 10, 8, 11, 9, 10, + 8, 12, 9, 11, 10, 12, 11, 11, 15, 16, 14, 16, 15, 16, 14, 14, + 10, 16, 10, 13, 13, 16, 12, 13, 13, 16, 12, 14, 14, 16, 13, 13, + 16, 16, 16, 16, 16, 16, 14, 15, 4, 10, 7, 10, 7, 10, 9, 10, + 8, 12, 9, 12, 10, 12, 11, 12, 14, 16, 14, 16, 15, 16, 14, 14, + 8, 12, 9, 12, 10, 13, 11, 12, 10, 14, 11, 13, 11, 14, 12, 13, + 16, 16, 14, 16, 16, 16, 14, 15, 12, 16, 12, 14, 14, 16, 13, 14, + 14, 16, 13, 16, 16, 16, 14, 14, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 12, 16, 11, 14, 13, 13, 13, 16, 13, 16, 13, 15, 13, 14, + 16, 16, 16, 16, 16, 16, 15, 16, 13, 16, 13, 16, 13, 16, 13, 14, + 14, 16, 14, 16, 14, 16, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 2, 9, 5, 9, 6, 10, 8, 10, + 7, 11, 8, 11, 9, 12, 10, 11, 14, 16, 14, 16, 15, 16, 14, 14, + 5, 11, 6, 10, 9, 12, 10, 11, 9, 13, 9, 12, 11, 13, 11, 12, + 16, 16, 14, 16, 16, 16, 14, 14, 10, 16, 9, 13, 13, 16, 12, 13, + 13, 16, 12, 14, 14, 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 14, + 5, 11, 8, 11, 7, 11, 10, 11, 9, 13, 10, 13, 10, 13, 11, 12, + 16, 16, 14, 16, 16, 16, 14, 14, 8, 13, 9, 12, 10, 13, 11, 12, + 10, 14, 10, 13, 11, 14, 12, 12, 16, 16, 14, 16, 15, 16, 14, 14, + 12, 16, 12, 14, 14, 16, 13, 14, 14, 16, 12, 16, 15, 16, 13, 14, + 16, 16, 15, 16, 16, 16, 15, 15, 11, 16, 12, 16, 10, 14, 12, 13, + 13, 16, 14, 16, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 15, 16, + 13, 16, 13, 16, 13, 16, 13, 14, 14, 16, 14, 16, 13, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 15, 16, 16, 16, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, + 5, 13, 7, 12, 9, 13, 11, 12, 10, 14, 10, 13, 11, 13, 12, 13, + 16, 16, 16, 16, 16, 16, 16, 15, 7, 14, 8, 12, 11, 14, 11, 12, + 11, 16, 11, 13, 13, 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 10, 14, 14, 16, 12, 13, 13, 16, 12, 15, 16, 16, 14, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 14, 10, 13, 9, 13, 11, 12, + 11, 16, 12, 14, 12, 14, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 11, 14, 12, 14, 12, 13, 11, 16, 12, 14, 12, 15, 13, 13, + 16, 16, 15, 16, 16, 16, 15, 16, 13, 16, 12, 16, 15, 16, 14, 14, + 13, 16, 12, 16, 16, 16, 14, 14, 16, 16, 14, 16, 16, 16, 14, 16, + 11, 16, 13, 16, 10, 14, 12, 13, 14, 16, 14, 16, 13, 16, 14, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 13, 16, 14, 16, 13, 16, 14, 15, + 13, 16, 14, 16, 13, 16, 14, 15, 16, 16, 16, 16, 15, 16, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 15, 16, + 16, 16, 15, 16, 16, 16, 14, 14, 8, 16, 10, 14, 11, 16, 12, 13, + 12, 16, 12, 14, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 16, 14, + 10, 16, 10, 14, 12, 16, 12, 13, 13, 16, 12, 15, 14, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 16, 15, 11, 16, 10, 13, 13, 16, 12, 13, + 14, 16, 12, 14, 15, 16, 13, 13, 16, 16, 16, 16, 16, 16, 15, 14, + 10, 16, 11, 14, 11, 16, 12, 13, 13, 16, 13, 16, 13, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 16, 15, 11, 16, 12, 14, 13, 16, 13, 14, + 13, 16, 13, 16, 14, 16, 13, 14, 16, 16, 16, 16, 16, 16, 16, 15, + 13, 16, 12, 14, 14, 16, 13, 13, 13, 16, 12, 15, 14, 16, 13, 13, + 16, 16, 14, 16, 16, 16, 14, 13, 11, 16, 12, 16, 11, 15, 12, 13, + 14, 16, 14, 16, 13, 16, 13, 14, 16, 16, 16, 16, 16, 16, 14, 14, + 12, 16, 13, 16, 12, 16, 13, 14, 13, 16, 14, 16, 13, 16, 13, 14, + 16, 16, 16, 16, 14, 16, 14, 14, 14, 16, 13, 16, 14, 16, 13, 13, + 13, 16, 13, 16, 14, 16, 13, 13, 15, 16, 13, 14, 13, 15, 12, 12, + }, + }, + { + { + 0, 7, 4, 6, 4, 7, 6, 7, 6, 9, 7, 8, 7, 9, 8, 8, + 13, 14, 12, 12, 12, 13, 11, 11, 5, 9, 5, 8, 7, 9, 7, 8, + 8, 11, 8, 10, 9, 10, 9, 9, 13, 15, 12, 13, 12, 13, 11, 11, + 9, 14, 8, 11, 11, 13, 10, 10, 11, 15, 10, 12, 12, 13, 10, 11, + 14, 16, 12, 13, 14, 14, 12, 11, 5, 9, 7, 9, 6, 9, 8, 8, + 8, 11, 8, 10, 8, 10, 9, 9, 13, 16, 12, 13, 13, 13, 11, 11, + 7, 11, 8, 10, 9, 11, 9, 9, 9, 13, 9, 11, 10, 11, 10, 10, + 14, 16, 12, 13, 13, 13, 12, 11, 11, 16, 10, 12, 12, 14, 11, 11, + 13, 16, 11, 13, 13, 14, 11, 11, 16, 16, 13, 14, 14, 15, 12, 11, + 10, 15, 11, 13, 9, 12, 10, 10, 12, 16, 12, 13, 11, 12, 11, 11, + 15, 16, 13, 14, 13, 14, 12, 11, 12, 16, 12, 14, 11, 13, 11, 11, + 13, 16, 12, 14, 12, 13, 12, 11, 16, 16, 13, 14, 14, 14, 12, 11, + 14, 16, 13, 14, 14, 15, 12, 12, 16, 16, 13, 14, 14, 16, 12, 12, + 16, 16, 14, 14, 14, 15, 12, 11, 3, 9, 5, 8, 6, 9, 7, 8, + 7, 11, 8, 10, 9, 10, 9, 9, 13, 14, 12, 13, 13, 13, 12, 11, + 6, 11, 6, 9, 8, 10, 8, 9, 9, 12, 8, 10, 10, 11, 9, 10, + 14, 16, 12, 13, 13, 14, 12, 11, 9, 14, 8, 11, 11, 13, 10, 10, + 12, 16, 10, 12, 12, 14, 11, 11, 16, 16, 12, 13, 14, 15, 12, 11, + 6, 11, 8, 10, 7, 10, 8, 9, 9, 12, 9, 11, 9, 11, 10, 10, + 14, 16, 13, 13, 13, 14, 12, 11, 8, 12, 9, 11, 9, 11, 9, 10, + 10, 13, 9, 11, 10, 12, 10, 10, 14, 16, 12, 13, 13, 14, 12, 11, + 12, 16, 10, 12, 12, 14, 11, 11, 12, 16, 10, 12, 13, 14, 11, 11, + 15, 16, 12, 13, 14, 14, 11, 11, 10, 15, 11, 13, 9, 12, 10, 10, + 12, 16, 12, 14, 11, 13, 11, 11, 16, 16, 14, 14, 14, 14, 12, 11, + 12, 16, 12, 14, 11, 13, 11, 11, 13, 16, 12, 14, 11, 13, 11, 11, + 16, 16, 13, 14, 13, 14, 12, 11, 14, 16, 13, 14, 14, 15, 12, 11, + 14, 16, 13, 14, 13, 15, 12, 11, 16, 16, 13, 14, 13, 14, 11, 10, + 6, 13, 8, 11, 9, 12, 10, 10, 10, 14, 10, 12, 11, 13, 11, 11, + 16, 16, 13, 14, 14, 14, 13, 12, 8, 14, 8, 12, 10, 13, 10, 11, + 11, 15, 10, 12, 12, 13, 11, 11, 16, 16, 14, 14, 15, 16, 13, 12, + 11, 16, 9, 12, 12, 14, 11, 11, 13, 16, 11, 13, 13, 16, 11, 11, + 16, 16, 13, 14, 16, 16, 13, 12, 8, 14, 10, 12, 9, 12, 10, 11, + 11, 15, 11, 13, 11, 13, 11, 11, 16, 16, 14, 15, 14, 15, 13, 12, + 10, 15, 10, 13, 11, 13, 11, 11, 11, 15, 11, 13, 12, 13, 11, 11, + 16, 16, 13, 15, 14, 15, 13, 12, 12, 16, 11, 13, 13, 15, 11, 11, + 13, 16, 11, 13, 13, 15, 11, 11, 16, 16, 12, 14, 14, 16, 12, 11, + 11, 16, 12, 14, 10, 13, 11, 11, 13, 16, 13, 15, 12, 14, 12, 12, + 16, 16, 15, 16, 14, 15, 13, 12, 12, 16, 13, 14, 12, 14, 12, 12, + 13, 16, 13, 14, 12, 14, 12, 12, 16, 16, 14, 15, 13, 14, 12, 12, + 15, 16, 13, 15, 14, 16, 12, 12, 14, 16, 13, 14, 13, 15, 12, 12, + 15, 16, 12, 13, 13, 14, 11, 10, 9, 15, 10, 13, 11, 14, 11, 12, + 12, 16, 12, 14, 12, 14, 12, 12, 16, 16, 14, 14, 14, 15, 13, 12, + 10, 16, 10, 13, 12, 14, 12, 12, 13, 16, 12, 14, 13, 15, 12, 12, + 16, 16, 14, 14, 15, 16, 13, 12, 11, 16, 9, 12, 13, 15, 11, 11, + 14, 16, 11, 13, 14, 16, 11, 11, 16, 16, 13, 14, 16, 16, 12, 11, + 10, 16, 11, 14, 11, 14, 12, 12, 13, 16, 13, 14, 12, 14, 12, 12, + 16, 16, 14, 15, 15, 15, 13, 12, 11, 16, 12, 14, 12, 15, 12, 12, + 13, 16, 12, 14, 13, 15, 12, 12, 16, 16, 14, 15, 15, 16, 13, 12, + 12, 16, 11, 13, 13, 15, 11, 11, 13, 16, 11, 13, 13, 15, 11, 11, + 16, 16, 12, 13, 14, 16, 12, 10, 11, 16, 12, 14, 10, 13, 11, 11, + 14, 16, 13, 14, 12, 14, 11, 11, 16, 16, 15, 16, 14, 14, 12, 11, + 12, 16, 13, 14, 11, 14, 11, 11, 13, 16, 13, 14, 12, 14, 11, 11, + 16, 16, 14, 15, 13, 14, 12, 11, 14, 16, 12, 14, 13, 14, 11, 10, + 13, 16, 12, 13, 12, 14, 11, 10, 14, 16, 11, 12, 12, 12, 10, 8, + }, + { + 0, 8, 4, 9, 5, 9, 8, 10, 6, 11, 8, 11, 9, 12, 11, 12, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 11, 6, 11, 9, 12, 10, 12, + 9, 13, 10, 13, 11, 16, 12, 13, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 11, 16, 16, 16, 14, 16, 14, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 11, 8, 12, 7, 12, 10, 12, + 8, 13, 10, 13, 10, 13, 12, 14, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 13, 10, 14, 11, 16, 12, 14, 11, 16, 12, 16, 12, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 14, 16, 12, 16, 16, 16, 13, 16, 16, 16, 14, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 1, 10, 5, 10, 7, 11, 9, 11, + 8, 12, 9, 12, 10, 13, 12, 13, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 12, 7, 12, 10, 13, 11, 12, 9, 16, 10, 13, 12, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 10, 16, 16, 16, 14, 16, + 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 6, 12, 9, 13, 8, 12, 11, 13, 10, 16, 11, 16, 11, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 10, 14, 11, 16, 12, 16, + 10, 16, 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 14, 16, 11, 16, 14, 16, + 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 6, 16, 9, 13, 10, 16, 12, 14, 11, 16, 12, 16, 12, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 9, 14, 12, 16, 13, 16, + 12, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 10, 16, 16, 16, 14, 16, 16, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 11, 16, 10, 16, 12, 16, + 12, 16, 13, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 12, 16, 13, 16, 14, 16, 11, 16, 13, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 13, 16, 16, 16, 16, 16, + 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 11, 16, 14, 16, 16, 16, 16, 16, 14, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 11, 16, 12, 16, 13, 16, + 13, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 11, 16, 13, 16, 14, 16, 14, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 10, 16, 16, 16, 13, 16, + 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 12, 16, 12, 16, 13, 16, 13, 16, 16, 16, 14, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 14, 16, 16, 16, + 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 12, 16, 16, 16, 14, 16, 14, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 11, 16, 13, 16, + 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 14, 15, + }, + }, + { + { + 0, 7, 3, 7, 4, 7, 6, 7, 6, 9, 7, 9, 7, 9, 8, 9, + 13, 14, 12, 13, 13, 13, 12, 12, 4, 9, 5, 9, 7, 9, 8, 9, + 7, 11, 8, 10, 9, 11, 9, 10, 13, 16, 12, 14, 13, 14, 12, 12, + 9, 14, 8, 12, 12, 14, 10, 11, 11, 16, 10, 13, 13, 14, 11, 12, + 15, 16, 13, 14, 14, 16, 12, 12, 5, 10, 7, 9, 6, 9, 8, 9, + 8, 11, 8, 11, 8, 10, 9, 10, 14, 16, 12, 14, 13, 14, 12, 12, + 7, 12, 8, 11, 9, 11, 9, 10, 9, 13, 9, 12, 10, 12, 10, 11, + 14, 16, 12, 14, 13, 14, 12, 12, 12, 16, 11, 13, 13, 15, 11, 12, + 13, 16, 11, 14, 13, 15, 12, 12, 15, 16, 13, 15, 14, 16, 13, 13, + 10, 15, 12, 14, 9, 13, 11, 12, 12, 16, 12, 14, 11, 13, 12, 12, + 15, 16, 13, 15, 14, 15, 13, 13, 12, 16, 12, 14, 12, 14, 12, 12, + 13, 16, 13, 14, 12, 14, 12, 12, 16, 16, 14, 15, 14, 16, 13, 13, + 15, 16, 13, 15, 14, 16, 12, 13, 16, 16, 14, 16, 14, 16, 13, 13, + 16, 16, 14, 16, 15, 16, 13, 13, 3, 9, 5, 9, 6, 9, 8, 9, + 7, 11, 8, 10, 9, 11, 9, 10, 14, 15, 13, 14, 13, 14, 12, 12, + 5, 11, 6, 10, 8, 11, 9, 10, 9, 12, 9, 11, 10, 12, 10, 11, + 14, 16, 13, 14, 14, 15, 13, 13, 9, 15, 8, 12, 12, 14, 10, 11, + 12, 16, 10, 13, 13, 15, 11, 12, 15, 16, 13, 14, 14, 16, 13, 13, + 6, 11, 8, 11, 7, 10, 9, 10, 9, 13, 10, 12, 9, 12, 10, 11, + 14, 16, 13, 14, 14, 14, 13, 13, 8, 13, 9, 12, 9, 12, 10, 11, + 9, 13, 9, 12, 10, 12, 10, 11, 14, 16, 12, 14, 13, 14, 12, 12, + 12, 16, 11, 13, 13, 15, 11, 12, 12, 16, 11, 13, 13, 15, 11, 12, + 14, 16, 12, 14, 14, 15, 12, 12, 10, 15, 11, 14, 9, 13, 11, 12, + 12, 16, 12, 14, 11, 14, 12, 12, 16, 16, 14, 16, 14, 15, 13, 13, + 12, 16, 12, 14, 11, 14, 12, 12, 12, 16, 13, 14, 11, 14, 12, 12, + 15, 16, 14, 15, 13, 15, 12, 13, 14, 16, 13, 15, 14, 16, 13, 13, + 14, 16, 13, 15, 14, 16, 12, 13, 15, 16, 13, 15, 13, 15, 12, 12, + 6, 13, 8, 12, 9, 12, 10, 11, 10, 14, 11, 13, 11, 13, 12, 12, + 15, 16, 14, 15, 15, 15, 14, 13, 8, 14, 9, 12, 11, 13, 11, 12, + 11, 15, 11, 13, 12, 14, 12, 12, 16, 16, 14, 15, 15, 16, 14, 14, + 10, 16, 9, 13, 12, 15, 11, 12, 13, 16, 11, 14, 13, 16, 12, 12, + 16, 16, 14, 15, 16, 16, 13, 13, 8, 14, 10, 13, 9, 13, 11, 12, + 11, 15, 12, 14, 11, 14, 12, 12, 16, 16, 15, 16, 15, 16, 14, 14, + 10, 15, 10, 13, 11, 14, 11, 12, 11, 15, 11, 14, 12, 14, 12, 12, + 15, 16, 14, 15, 14, 16, 13, 13, 12, 16, 11, 14, 13, 16, 12, 12, + 12, 16, 11, 14, 13, 15, 12, 12, 15, 16, 12, 14, 15, 16, 13, 13, + 11, 16, 12, 14, 10, 14, 11, 12, 13, 16, 13, 16, 12, 14, 12, 13, + 16, 16, 16, 16, 15, 16, 14, 13, 12, 16, 13, 15, 12, 14, 12, 13, + 13, 16, 13, 15, 12, 14, 12, 13, 16, 16, 14, 16, 13, 15, 13, 13, + 15, 16, 14, 16, 14, 16, 13, 13, 14, 16, 13, 15, 13, 16, 13, 13, + 14, 16, 12, 14, 13, 14, 12, 12, 9, 16, 11, 14, 11, 15, 12, 13, + 13, 16, 12, 14, 12, 15, 13, 13, 16, 16, 14, 15, 15, 15, 14, 13, + 11, 16, 11, 14, 12, 16, 12, 13, 13, 16, 12, 14, 13, 16, 13, 13, + 16, 16, 14, 15, 16, 16, 14, 13, 11, 16, 10, 13, 13, 16, 11, 12, + 14, 16, 11, 14, 14, 16, 12, 12, 16, 16, 14, 14, 16, 16, 13, 12, + 11, 16, 12, 14, 11, 15, 12, 13, 13, 16, 13, 15, 13, 16, 13, 13, + 16, 16, 15, 16, 15, 16, 14, 13, 11, 16, 12, 15, 12, 16, 12, 13, + 13, 16, 13, 15, 13, 16, 13, 13, 16, 16, 15, 16, 15, 16, 14, 13, + 12, 16, 11, 14, 13, 16, 12, 12, 13, 16, 11, 14, 13, 16, 12, 12, + 16, 16, 13, 14, 15, 16, 12, 12, 11, 16, 12, 14, 10, 14, 11, 12, + 14, 16, 13, 15, 12, 15, 12, 12, 16, 16, 16, 16, 14, 15, 13, 12, + 12, 16, 13, 15, 12, 14, 12, 12, 13, 16, 13, 15, 12, 14, 12, 12, + 16, 16, 14, 16, 14, 15, 12, 12, 14, 16, 13, 15, 13, 16, 11, 12, + 13, 16, 12, 14, 13, 15, 11, 11, 14, 16, 12, 13, 12, 13, 11, 10, + }, + { + 0, 8, 4, 9, 5, 10, 9, 11, 5, 11, 9, 12, 9, 13, 12, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 11, 6, 12, 9, 13, 11, 13, + 9, 16, 10, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 12, 8, 13, 7, 12, 11, 16, + 8, 16, 11, 16, 11, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 10, 16, 11, 16, 13, 16, 11, 16, 12, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 1, 10, 6, 11, 7, 12, 10, 13, + 7, 12, 10, 13, 10, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 13, 7, 12, 10, 16, 12, 16, 10, 16, 11, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 16, 16, 16, 16, 16, + 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 13, 9, 16, 8, 16, 12, 16, 9, 16, 12, 16, 11, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 11, 16, 12, 16, 13, 16, + 10, 16, 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 6, 16, 9, 16, 10, 16, 13, 16, 11, 16, 12, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 9, 16, 12, 16, 13, 16, + 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 10, 16, 16, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 11, 16, 11, 16, 13, 16, + 12, 16, 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 12, 16, 13, 16, 16, 16, 11, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 7, 16, 11, 16, 12, 16, 16, 16, + 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 11, 16, 13, 16, 16, 16, 16, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 10, 16, 16, 16, 16, 16, + 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 11, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 16, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + }, + { + { + 0, 7, 4, 8, 4, 8, 7, 8, 6, 10, 7, 10, 8, 10, 9, 10, + 13, 16, 13, 15, 13, 15, 13, 14, 4, 10, 5, 10, 7, 10, 9, 10, + 7, 12, 8, 11, 9, 12, 10, 11, 13, 16, 13, 15, 13, 16, 13, 14, + 9, 16, 9, 13, 12, 16, 11, 13, 11, 16, 11, 14, 13, 16, 12, 14, + 15, 16, 14, 16, 15, 16, 14, 14, 4, 10, 7, 10, 6, 10, 9, 10, + 8, 12, 9, 12, 9, 11, 10, 12, 13, 16, 13, 16, 14, 16, 13, 14, + 7, 12, 8, 12, 9, 12, 10, 12, 9, 13, 10, 13, 10, 13, 11, 12, + 14, 16, 13, 16, 14, 16, 13, 14, 12, 16, 11, 14, 13, 16, 12, 14, + 13, 16, 12, 16, 14, 16, 13, 14, 16, 16, 14, 16, 15, 16, 14, 14, + 10, 16, 12, 15, 10, 14, 12, 13, 12, 16, 13, 16, 12, 14, 13, 14, + 15, 16, 14, 16, 14, 16, 14, 14, 12, 16, 13, 16, 12, 16, 13, 14, + 13, 16, 13, 16, 13, 16, 13, 14, 16, 16, 14, 16, 15, 16, 14, 15, + 15, 16, 14, 16, 15, 16, 13, 15, 16, 16, 14, 16, 15, 16, 14, 15, + 16, 16, 16, 16, 16, 16, 15, 15, 2, 9, 5, 10, 6, 10, 8, 10, + 7, 11, 8, 11, 9, 11, 10, 11, 14, 16, 13, 15, 14, 15, 14, 14, + 5, 11, 6, 11, 8, 12, 9, 11, 8, 13, 9, 12, 10, 13, 11, 12, + 14, 16, 13, 15, 14, 16, 14, 14, 9, 16, 8, 13, 12, 16, 11, 13, + 12, 16, 11, 14, 13, 16, 12, 13, 16, 16, 14, 16, 15, 16, 14, 15, + 5, 12, 8, 11, 7, 11, 9, 11, 9, 13, 10, 13, 10, 13, 11, 12, + 14, 16, 14, 16, 14, 16, 14, 15, 8, 13, 9, 13, 10, 13, 11, 12, + 9, 13, 10, 13, 10, 13, 11, 13, 13, 16, 13, 15, 13, 16, 13, 14, + 12, 16, 11, 14, 13, 16, 12, 14, 12, 16, 11, 14, 13, 16, 12, 14, + 14, 16, 13, 16, 14, 16, 13, 14, 10, 16, 12, 15, 9, 14, 11, 13, + 12, 16, 13, 16, 12, 15, 12, 14, 16, 16, 15, 16, 15, 16, 14, 14, + 12, 16, 13, 16, 12, 16, 12, 14, 12, 16, 13, 16, 12, 15, 13, 14, + 15, 16, 14, 16, 14, 16, 14, 14, 15, 16, 14, 16, 14, 16, 14, 15, + 14, 16, 13, 16, 14, 16, 13, 14, 16, 16, 14, 16, 14, 16, 13, 14, + 6, 14, 9, 13, 9, 14, 11, 12, 10, 14, 11, 13, 11, 14, 12, 13, + 16, 16, 15, 16, 15, 16, 14, 15, 8, 15, 9, 13, 11, 14, 11, 13, + 11, 16, 11, 14, 12, 15, 12, 14, 16, 16, 15, 16, 16, 16, 15, 16, + 10, 16, 9, 14, 12, 16, 12, 13, 13, 16, 11, 15, 14, 16, 13, 14, + 16, 16, 15, 16, 16, 16, 15, 16, 8, 15, 10, 13, 10, 14, 11, 13, + 11, 16, 12, 14, 12, 14, 12, 14, 16, 16, 16, 16, 16, 16, 15, 16, + 10, 16, 11, 14, 11, 15, 12, 13, 11, 16, 11, 14, 12, 15, 12, 14, + 16, 16, 14, 16, 15, 16, 14, 15, 12, 16, 11, 15, 13, 16, 13, 14, + 12, 16, 11, 14, 13, 16, 13, 14, 15, 16, 13, 16, 16, 16, 14, 15, + 10, 16, 12, 15, 10, 15, 12, 13, 13, 16, 13, 16, 12, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 15, 15, 12, 16, 13, 16, 12, 16, 13, 14, + 12, 16, 13, 16, 12, 16, 13, 14, 16, 16, 15, 16, 14, 16, 14, 15, + 15, 16, 14, 16, 15, 16, 14, 15, 14, 16, 13, 16, 14, 16, 13, 14, + 14, 16, 13, 15, 14, 16, 13, 14, 9, 16, 11, 16, 11, 16, 12, 14, + 13, 16, 12, 16, 13, 16, 13, 14, 16, 16, 15, 16, 16, 16, 15, 15, + 11, 16, 11, 16, 12, 16, 13, 14, 13, 16, 12, 16, 13, 16, 13, 14, + 16, 16, 15, 16, 16, 16, 15, 15, 11, 16, 10, 15, 13, 16, 12, 13, + 14, 16, 12, 16, 14, 16, 13, 14, 16, 16, 15, 16, 16, 16, 14, 14, + 11, 16, 12, 16, 11, 16, 13, 14, 13, 16, 13, 16, 13, 16, 13, 14, + 16, 16, 16, 16, 16, 16, 15, 15, 11, 16, 12, 16, 12, 16, 13, 14, + 13, 16, 13, 16, 13, 16, 13, 14, 16, 16, 15, 16, 16, 16, 15, 14, + 12, 16, 12, 15, 13, 16, 12, 14, 13, 16, 12, 16, 14, 16, 13, 14, + 16, 16, 14, 16, 16, 16, 14, 14, 11, 16, 12, 16, 11, 16, 12, 14, + 14, 16, 14, 16, 12, 16, 13, 14, 16, 16, 16, 16, 16, 16, 15, 14, + 12, 16, 13, 16, 12, 16, 12, 14, 13, 16, 13, 16, 12, 16, 13, 14, + 16, 16, 16, 16, 15, 16, 14, 14, 14, 16, 13, 16, 14, 16, 12, 14, + 13, 16, 13, 16, 13, 16, 12, 13, 15, 16, 13, 14, 14, 15, 13, 13, + }, + { + 0, 8, 4, 10, 5, 11, 10, 16, 5, 12, 9, 16, 10, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 12, 7, 12, 9, 16, 12, 16, + 9, 16, 11, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 12, 9, 16, 8, 16, 12, 16, + 8, 16, 11, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 8, 16, 11, 16, 12, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 1, 11, 6, 12, 7, 16, 11, 16, + 7, 16, 10, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 16, 7, 16, 10, 16, 12, 16, 9, 16, 11, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 16, 10, 16, 8, 16, 12, 16, 9, 16, 12, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 11, 16, 12, 16, 16, 16, + 10, 16, 12, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 16, 9, 16, 10, 16, 16, 16, 11, 16, 12, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 9, 16, 12, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 11, 16, 11, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 12, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 11, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 10, 16, 12, 16, 16, 16, + 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 9, 16, 16, 16, 16, 16, + 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 13, 16, 12, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 11, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + }, + { + { + 0, 8, 4, 10, 5, 9, 8, 10, 6, 11, 8, 12, 8, 11, 10, 13, + 14, 16, 14, 16, 14, 16, 16, 16, 3, 11, 5, 11, 8, 12, 10, 12, + 7, 12, 9, 13, 10, 13, 11, 13, 14, 16, 14, 16, 16, 16, 16, 16, + 9, 16, 9, 16, 12, 16, 12, 16, 11, 16, 11, 16, 14, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 11, 7, 12, 6, 11, 10, 12, + 8, 13, 9, 13, 9, 13, 11, 14, 13, 16, 14, 16, 14, 16, 16, 16, + 7, 13, 9, 13, 9, 13, 11, 13, 9, 14, 10, 16, 11, 16, 12, 16, + 15, 16, 14, 16, 16, 16, 16, 16, 12, 16, 12, 16, 14, 16, 13, 16, + 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 12, 16, 10, 16, 13, 16, 12, 16, 13, 16, 12, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 13, 16, 13, 16, 14, 16, + 13, 16, 14, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 2, 10, 5, 11, 6, 11, 9, 11, + 7, 12, 9, 13, 9, 13, 11, 13, 14, 16, 16, 16, 16, 16, 16, 16, + 4, 12, 6, 12, 8, 13, 10, 13, 8, 13, 9, 13, 11, 16, 12, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 8, 16, 12, 16, 12, 16, + 12, 16, 11, 16, 13, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 12, 8, 13, 7, 13, 10, 13, 8, 14, 10, 14, 10, 14, 12, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 7, 14, 9, 16, 10, 16, 11, 14, + 8, 14, 10, 16, 11, 16, 12, 16, 13, 16, 14, 16, 16, 16, 16, 16, + 11, 16, 11, 16, 13, 16, 13, 16, 12, 16, 12, 16, 14, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 12, 16, 10, 16, 12, 16, + 12, 16, 13, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 13, 16, 12, 16, 14, 16, 12, 16, 13, 16, 12, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 6, 16, 8, 16, 9, 16, 11, 13, 10, 16, 11, 16, 11, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 7, 16, 9, 16, 10, 16, 12, 16, + 11, 16, 11, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 9, 16, 12, 16, 13, 16, 13, 16, 12, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 7, 16, 10, 16, 9, 16, 12, 16, + 11, 16, 12, 16, 12, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 16, 11, 16, 11, 16, 12, 16, 11, 16, 12, 16, 13, 16, 13, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 12, 16, 14, 16, 14, 16, + 12, 16, 12, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 12, 16, 10, 16, 13, 16, 13, 16, 14, 16, 13, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 13, 16, 12, 16, 14, 16, + 12, 16, 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 11, 16, 11, 16, 13, 16, + 12, 16, 13, 16, 13, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 11, 16, 13, 16, 13, 16, 13, 16, 13, 16, 14, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 11, 16, 14, 16, 13, 16, + 14, 16, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 12, 16, 12, 16, 13, 16, 13, 16, 13, 16, 13, 16, 14, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 12, 16, 13, 16, 14, 16, + 13, 16, 13, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 12, 16, 14, 16, 14, 16, 14, 16, 14, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 13, 16, 11, 16, 14, 16, + 16, 16, 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 14, 16, 13, 16, 14, 16, 16, 16, 16, 16, 14, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 0, 10, 4, 12, 5, 16, 11, 16, 6, 16, 10, 16, 11, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 3, 16, 7, 16, 10, 16, 16, 16, + 9, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 4, 16, 10, 16, 9, 16, 16, 16, + 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 16, 12, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 1, 16, 6, 16, 8, 16, 16, 16, + 8, 16, 11, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 16, 8, 16, 11, 16, 16, 16, 10, 16, 12, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 11, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 16, 11, 16, 9, 16, 16, 16, 10, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 9, 16, 12, 16, 16, 16, 16, 16, + 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 5, 16, 9, 16, 11, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 10, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, 16, 11, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 12, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 6, 16, 11, 16, 15, 16, 16, 16, + 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 9, 16, 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 9, 16, 16, 16, 16, 16, + 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 10, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + }, +}; + +static const uint8_t rv34_table_inter_secondpat[NUM_INTER_TABLES][2][OTHERBLK_VLC_SIZE] = { + { + { + 0, 4, 8, 3, 6, 8, 6, 7, 8, 4, 6, 8, 6, 7, 8, 7, + 8, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, 3, 6, 8, 4, 6, + 9, 7, 7, 8, 5, 7, 9, 6, 7, 9, 8, 8, 8, 7, 8, 8, + 8, 8, 8, 8, 8, 7, 6, 8, 9, 7, 8, 9, 7, 8, 9, 7, + 8, 9, 7, 8, 9, 8, 8, 9, 8, 8, 9, 8, 9, 9, 8, 8, + 8, 8, 9, 9, 8, 9, 9, 7, 8, 8, 8, 9, 9, 8, 9, 9, + 8, 8, 8, 7, 8, 8, 8, 8, 8, 7, 7, 6, + }, + { + 0, 4, 9, 3, 6, 9, 7, 8, 10, 3, 6, 9, 5, 7, 10, 9, + 9, 10, 7, 8, 10, 8, 9, 10, 10, 10, 10, 2, 6, 9, 4, 7, + 10, 8, 9, 10, 4, 7, 10, 6, 7, 10, 9, 9, 10, 7, 8, 10, + 8, 9, 10, 10, 10, 10, 6, 8, 10, 7, 9, 11, 9, 10, 11, 7, + 9, 11, 8, 9, 11, 10, 10, 11, 8, 9, 11, 9, 10, 11, 11, 11, + 10, 8, 10, 11, 9, 10, 11, 9, 10, 11, 8, 10, 11, 9, 10, 11, + 10, 10, 11, 8, 10, 11, 9, 10, 10, 10, 10, 9, + }, + }, + { + { + 0, 4, 8, 3, 6, 8, 6, 7, 9, 4, 6, 8, 5, 7, 8, 8, + 8, 9, 7, 7, 8, 8, 8, 8, 8, 9, 8, 3, 6, 8, 4, 6, + 9, 7, 7, 9, 5, 6, 9, 6, 7, 9, 8, 8, 9, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 6, 8, 9, 7, 8, 10, 7, 8, 9, 7, + 8, 10, 7, 8, 10, 8, 8, 9, 7, 8, 9, 8, 9, 9, 9, 9, + 8, 7, 9, 10, 8, 9, 10, 8, 8, 8, 8, 9, 10, 8, 9, 9, + 8, 8, 8, 7, 8, 8, 8, 8, 8, 8, 7, 6, + }, + { + 0, 4, 9, 3, 6, 10, 8, 9, 11, 3, 5, 9, 5, 7, 10, 9, + 10, 11, 7, 8, 10, 9, 9, 11, 11, 11, 12, 2, 5, 10, 4, 7, + 10, 8, 9, 11, 4, 6, 10, 6, 7, 10, 9, 10, 11, 7, 9, 10, + 9, 9, 11, 11, 11, 11, 6, 8, 11, 7, 9, 11, 9, 10, 12, 7, + 9, 11, 8, 9, 12, 10, 10, 12, 8, 10, 11, 10, 10, 11, 12, 11, + 11, 8, 10, 12, 9, 11, 12, 10, 11, 12, 9, 10, 12, 10, 11, 12, + 11, 11, 12, 9, 10, 12, 10, 10, 11, 11, 11, 10, + }, + }, + { + { + 0, 4, 8, 3, 6, 9, 7, 8, 9, 4, 6, 8, 5, 7, 9, 8, + 9, 9, 7, 8, 9, 8, 8, 9, 9, 9, 9, 2, 6, 9, 4, 6, + 9, 7, 8, 10, 5, 7, 9, 6, 7, 9, 8, 8, 9, 7, 8, 9, + 8, 8, 9, 9, 9, 9, 6, 8, 10, 7, 8, 10, 8, 9, 10, 6, + 8, 10, 8, 8, 10, 9, 9, 10, 8, 9, 10, 9, 9, 10, 10, 10, + 9, 8, 9, 10, 8, 9, 10, 8, 9, 10, 8, 9, 10, 9, 9, 10, + 9, 9, 9, 8, 9, 9, 8, 9, 9, 9, 9, 8, + }, + { + 0, 4, 10, 3, 6, 10, 8, 10, 12, 2, 6, 10, 6, 8, 11, 10, + 11, 12, 7, 9, 11, 9, 10, 12, 12, 13, 13, 2, 6, 10, 4, 7, + 11, 9, 10, 13, 4, 7, 11, 7, 8, 11, 10, 11, 12, 8, 9, 12, + 10, 10, 12, 12, 12, 13, 6, 9, 12, 8, 10, 13, 10, 12, 14, 7, + 10, 13, 9, 10, 13, 11, 11, 13, 9, 11, 13, 11, 11, 13, 13, 13, + 13, 9, 11, 13, 10, 12, 14, 11, 12, 14, 9, 11, 14, 11, 12, 14, + 12, 12, 14, 9, 12, 13, 11, 12, 13, 13, 12, 12, + }, + }, + { + { + 0, 4, 9, 3, 6, 9, 7, 8, 10, 3, 6, 9, 6, 7, 9, 9, + 9, 10, 7, 8, 9, 8, 9, 10, 10, 10, 11, 2, 6, 9, 4, 7, + 10, 7, 9, 10, 4, 7, 10, 6, 7, 10, 9, 9, 10, 7, 8, 10, + 8, 9, 10, 10, 10, 10, 6, 8, 11, 7, 9, 11, 8, 10, 11, 6, + 9, 11, 8, 9, 11, 9, 9, 11, 8, 9, 11, 9, 10, 11, 11, 10, + 10, 8, 10, 11, 9, 10, 11, 9, 10, 11, 8, 10, 11, 9, 10, 11, + 10, 10, 11, 8, 10, 11, 9, 10, 11, 10, 10, 10, + }, + { + 0, 4, 12, 3, 7, 12, 10, 11, 14, 3, 6, 12, 7, 9, 13, 12, + 13, 14, 8, 11, 13, 11, 12, 14, 14, 14, 14, 1, 7, 12, 5, 8, + 13, 10, 12, 14, 4, 8, 13, 8, 9, 13, 12, 13, 14, 9, 11, 14, + 11, 12, 14, 14, 14, 14, 7, 10, 14, 9, 11, 14, 11, 13, 16, 8, + 11, 14, 10, 12, 14, 13, 13, 16, 10, 12, 15, 12, 13, 15, 15, 15, + 15, 10, 13, 15, 12, 13, 14, 13, 15, 15, 10, 13, 15, 12, 13, 15, + 13, 14, 15, 10, 13, 14, 12, 13, 14, 14, 14, 14, + }, + }, + { + { + 0, 4, 9, 3, 6, 10, 7, 9, 11, 3, 5, 9, 5, 7, 10, 9, + 10, 12, 7, 8, 10, 9, 10, 11, 11, 12, 12, 2, 6, 10, 4, 7, + 10, 7, 9, 12, 4, 7, 10, 6, 7, 11, 9, 10, 12, 7, 9, 11, + 9, 9, 11, 11, 11, 12, 5, 8, 11, 7, 9, 12, 9, 10, 13, 6, + 9, 12, 8, 9, 12, 10, 10, 12, 8, 10, 12, 10, 10, 12, 12, 12, + 12, 8, 10, 12, 9, 11, 13, 10, 11, 13, 9, 11, 13, 10, 11, 13, + 11, 11, 13, 9, 11, 12, 10, 11, 12, 11, 11, 12, + }, + { + 0, 4, 12, 3, 7, 13, 10, 12, 15, 3, 7, 13, 7, 9, 14, 12, + 12, 13, 8, 11, 14, 11, 13, 15, 15, 14, 14, 1, 6, 13, 5, 8, + 13, 10, 13, 15, 4, 8, 13, 8, 9, 14, 13, 13, 15, 8, 11, 14, + 12, 12, 15, 15, 14, 14, 7, 10, 13, 9, 11, 13, 12, 14, 16, 8, + 11, 14, 10, 12, 15, 13, 13, 16, 10, 12, 15, 12, 13, 15, 15, 14, + 15, 11, 12, 14, 12, 14, 14, 13, 15, 15, 10, 12, 14, 12, 13, 15, + 14, 15, 15, 10, 13, 13, 12, 13, 15, 14, 14, 15, + }, + }, + { + { + 0, 5, 10, 3, 7, 11, 9, 11, 14, 3, 7, 11, 7, 8, 12, 11, + 12, 14, 7, 9, 12, 10, 11, 14, 13, 14, 16, 1, 7, 11, 5, 8, + 12, 9, 11, 15, 4, 8, 12, 7, 9, 13, 11, 12, 15, 8, 10, 13, + 10, 11, 14, 14, 14, 16, 6, 9, 13, 8, 11, 14, 10, 13, 16, 7, + 10, 14, 9, 11, 15, 12, 13, 16, 9, 11, 15, 12, 12, 15, 14, 14, + 16, 10, 12, 14, 11, 13, 15, 12, 14, 16, 10, 12, 15, 11, 13, 16, + 13, 14, 16, 10, 13, 16, 12, 13, 15, 14, 15, 16, + }, + { + 0, 5, 16, 3, 8, 14, 11, 13, 14, 2, 8, 14, 8, 10, 16, 13, + 13, 14, 9, 13, 16, 12, 13, 16, 16, 14, 16, 1, 7, 14, 6, 10, + 14, 12, 16, 16, 5, 9, 14, 9, 11, 16, 15, 16, 16, 10, 12, 16, + 13, 13, 16, 16, 14, 16, 8, 11, 14, 11, 13, 14, 14, 14, 16, 8, + 12, 14, 11, 13, 16, 16, 16, 16, 10, 12, 15, 13, 14, 16, 16, 16, + 16, 11, 14, 14, 14, 15, 16, 16, 15, 16, 10, 13, 16, 13, 14, 14, + 16, 16, 16, 10, 13, 16, 13, 14, 16, 16, 16, 16, + }, + }, + { + { + 0, 5, 11, 3, 7, 13, 9, 12, 16, 3, 7, 12, 6, 9, 14, 11, + 13, 16, 7, 10, 16, 11, 12, 16, 16, 16, 16, 1, 6, 12, 5, 9, + 16, 9, 13, 16, 4, 8, 16, 7, 10, 16, 12, 15, 16, 7, 11, 16, + 11, 12, 16, 16, 16, 16, 6, 10, 15, 8, 11, 16, 11, 14, 16, 7, + 11, 16, 10, 12, 16, 13, 16, 16, 9, 13, 16, 13, 14, 16, 16, 16, + 16, 10, 12, 16, 12, 16, 16, 16, 16, 16, 11, 13, 16, 13, 16, 16, + 16, 16, 16, 12, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 0, 5, 16, 3, 8, 16, 12, 12, 16, 2, 8, 16, 8, 10, 16, 13, + 13, 16, 9, 13, 16, 12, 13, 16, 16, 16, 16, 1, 8, 16, 6, 10, + 16, 12, 16, 16, 5, 9, 16, 9, 11, 16, 13, 16, 16, 9, 12, 14, + 12, 12, 16, 16, 16, 16, 8, 11, 13, 11, 12, 16, 14, 16, 16, 8, + 12, 16, 11, 13, 16, 16, 15, 16, 9, 13, 14, 12, 13, 16, 16, 16, + 16, 10, 12, 13, 14, 13, 16, 16, 16, 16, 9, 13, 16, 13, 12, 16, + 16, 16, 16, 10, 12, 16, 14, 15, 16, 16, 16, 16, + }, + }, +}; + +static const uint8_t rv34_table_inter_thirdpat[NUM_INTER_TABLES][2][OTHERBLK_VLC_SIZE] = { + { + { + 0, 5, 8, 3, 6, 9, 6, 7, 9, 4, 6, 9, 6, 7, 9, 8, + 8, 9, 7, 8, 9, 8, 9, 9, 9, 9, 9, 2, 6, 9, 4, 7, + 9, 7, 8, 9, 5, 7, 9, 6, 7, 9, 8, 8, 9, 7, 8, 9, + 8, 9, 9, 9, 9, 8, 5, 8, 10, 6, 8, 10, 8, 9, 9, 7, + 8, 10, 7, 9, 10, 8, 9, 9, 8, 9, 10, 9, 9, 10, 9, 9, + 9, 7, 9, 10, 8, 9, 10, 8, 8, 9, 8, 9, 10, 8, 9, 10, + 8, 8, 9, 8, 9, 9, 8, 9, 9, 8, 8, 7, + }, + { + 0, 4, 9, 2, 6, 10, 7, 8, 10, 3, 6, 10, 6, 7, 10, 9, + 9, 10, 8, 9, 11, 9, 10, 11, 10, 11, 11, 2, 6, 10, 4, 7, + 10, 8, 9, 10, 5, 7, 10, 7, 8, 10, 9, 9, 10, 9, 10, 11, + 10, 10, 11, 11, 11, 11, 6, 9, 11, 7, 9, 11, 9, 10, 12, 8, + 9, 11, 8, 10, 11, 10, 10, 11, 10, 11, 12, 11, 11, 12, 11, 11, + 11, 9, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12, 10, 11, 12, + 11, 11, 12, 11, 12, 12, 11, 12, 12, 12, 11, 11, + }, + }, + { + { + 0, 4, 9, 3, 6, 9, 6, 8, 9, 4, 6, 9, 5, 7, 9, 8, + 8, 9, 7, 8, 10, 8, 9, 10, 9, 9, 9, 2, 6, 9, 4, 7, + 9, 7, 8, 9, 5, 7, 9, 6, 7, 10, 8, 9, 9, 7, 9, 10, + 8, 9, 10, 9, 9, 9, 5, 8, 10, 6, 8, 10, 8, 9, 10, 7, + 8, 10, 7, 9, 11, 9, 9, 10, 8, 9, 10, 9, 10, 10, 10, 10, + 9, 7, 9, 10, 8, 9, 11, 8, 9, 10, 8, 9, 11, 8, 9, 11, + 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 8, + }, + { + 0, 4, 9, 2, 5, 10, 7, 8, 11, 3, 6, 10, 6, 7, 10, 9, + 10, 11, 8, 9, 11, 9, 10, 11, 11, 11, 12, 2, 6, 10, 4, 7, + 10, 8, 9, 11, 5, 7, 10, 6, 8, 10, 9, 10, 11, 9, 10, 12, + 10, 10, 12, 11, 12, 12, 6, 9, 11, 8, 9, 12, 9, 11, 13, 8, + 10, 12, 9, 10, 12, 11, 11, 12, 10, 12, 13, 11, 12, 13, 13, 12, + 13, 10, 11, 13, 10, 12, 13, 11, 12, 13, 11, 12, 13, 11, 12, 13, + 12, 12, 13, 12, 13, 14, 13, 13, 14, 13, 13, 13, + }, + }, + { + { + 0, 4, 9, 3, 6, 9, 7, 8, 10, 3, 6, 9, 5, 7, 10, 8, + 9, 10, 7, 9, 10, 8, 9, 10, 10, 10, 10, 2, 6, 9, 4, 7, + 10, 7, 9, 10, 4, 7, 10, 6, 8, 10, 8, 9, 10, 8, 9, 10, + 9, 9, 10, 10, 10, 10, 5, 8, 11, 7, 9, 11, 8, 10, 11, 7, + 9, 11, 8, 9, 11, 9, 10, 11, 9, 10, 11, 10, 10, 11, 11, 11, + 11, 8, 10, 11, 9, 10, 11, 9, 10, 11, 9, 10, 12, 9, 10, 12, + 10, 11, 11, 9, 10, 11, 10, 11, 11, 10, 10, 10, + }, + { + 0, 4, 10, 3, 6, 11, 8, 10, 12, 3, 6, 11, 6, 8, 11, 10, + 11, 13, 9, 10, 13, 11, 12, 14, 13, 13, 14, 1, 6, 10, 5, 8, + 12, 9, 10, 13, 5, 8, 11, 7, 9, 12, 11, 11, 13, 10, 12, 13, + 11, 12, 14, 14, 13, 15, 7, 10, 12, 9, 11, 14, 11, 12, 15, 9, + 11, 13, 10, 11, 14, 12, 12, 14, 12, 14, 16, 13, 13, 16, 14, 14, + 16, 12, 13, 15, 12, 14, 15, 13, 14, 16, 13, 14, 16, 14, 14, 16, + 14, 15, 16, 14, 16, 16, 15, 16, 16, 15, 15, 16, + }, + }, + { + { + 0, 4, 9, 2, 6, 9, 7, 9, 11, 3, 6, 10, 6, 7, 10, 9, + 10, 11, 7, 9, 10, 9, 10, 11, 11, 11, 12, 2, 6, 10, 4, 7, + 10, 8, 9, 11, 5, 7, 10, 7, 8, 10, 9, 10, 11, 8, 9, 11, + 9, 10, 11, 11, 12, 11, 6, 9, 11, 7, 10, 12, 9, 11, 12, 7, + 10, 12, 9, 10, 12, 11, 11, 12, 9, 11, 12, 10, 11, 12, 12, 12, + 12, 9, 11, 12, 9, 11, 13, 11, 12, 13, 9, 11, 13, 10, 12, 13, + 11, 12, 13, 11, 12, 13, 11, 12, 13, 12, 13, 12, + }, + { + 0, 4, 11, 2, 6, 12, 9, 11, 16, 4, 7, 12, 7, 9, 15, 11, + 12, 16, 10, 11, 16, 11, 13, 16, 16, 16, 16, 1, 6, 11, 5, 8, + 16, 9, 12, 16, 6, 9, 15, 8, 10, 16, 12, 13, 16, 12, 14, 16, + 12, 16, 16, 16, 16, 16, 8, 11, 14, 10, 12, 16, 12, 16, 16, 10, + 13, 16, 12, 16, 16, 13, 14, 16, 14, 16, 16, 16, 16, 16, 16, 16, + 16, 13, 13, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + }, + { + { + 0, 5, 9, 3, 6, 10, 8, 10, 12, 3, 6, 10, 6, 8, 10, 10, + 11, 12, 8, 9, 11, 10, 10, 12, 13, 13, 13, 1, 6, 10, 5, 8, + 11, 9, 11, 13, 5, 8, 11, 7, 9, 11, 11, 11, 13, 8, 9, 11, + 10, 10, 12, 13, 13, 14, 6, 9, 12, 8, 11, 13, 11, 13, 15, 8, + 10, 13, 10, 11, 13, 12, 13, 15, 10, 12, 13, 12, 12, 13, 14, 14, + 14, 9, 12, 14, 11, 13, 15, 13, 15, 16, 11, 13, 15, 12, 14, 15, + 14, 15, 16, 13, 14, 15, 14, 14, 15, 15, 16, 16, + }, + { + 0, 4, 16, 2, 7, 16, 10, 13, 16, 3, 8, 16, 7, 10, 16, 16, + 16, 16, 12, 16, 16, 15, 16, 16, 16, 16, 16, 1, 7, 16, 6, 9, + 16, 10, 16, 16, 7, 12, 16, 9, 13, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 9, 16, 16, 11, 13, 16, 16, 16, 16, 12, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + }, + { + { + 0, 4, 9, 3, 6, 11, 9, 12, 16, 3, 6, 10, 6, 8, 11, 12, + 13, 16, 8, 9, 12, 10, 11, 13, 16, 16, 16, 1, 6, 10, 5, 8, + 12, 10, 13, 16, 5, 8, 11, 8, 9, 13, 13, 14, 16, 9, 10, 14, + 11, 12, 15, 16, 16, 16, 6, 10, 13, 9, 12, 16, 14, 16, 16, 9, + 12, 14, 11, 13, 16, 16, 16, 16, 12, 14, 16, 14, 16, 16, 16, 16, + 16, 11, 16, 16, 13, 16, 16, 16, 16, 16, 12, 16, 16, 13, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 0, 4, 16, 2, 8, 16, 10, 16, 16, 3, 9, 16, 8, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 7, 16, 5, 10, + 16, 16, 16, 16, 7, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 10, 15, 16, 10, 16, 16, 16, 16, 16, 14, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + }, + { + { + 0, 3, 9, 3, 7, 11, 11, 15, 16, 3, 6, 11, 7, 9, 12, 16, + 16, 16, 8, 10, 16, 11, 16, 16, 16, 16, 16, 1, 6, 11, 6, 9, + 15, 16, 16, 16, 5, 8, 16, 9, 11, 16, 16, 16, 16, 10, 16, 16, + 16, 16, 16, 16, 16, 16, 7, 11, 16, 11, 16, 16, 16, 16, 16, 11, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + { + 0, 4, 16, 2, 8, 16, 16, 16, 16, 3, 12, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 7, 16, 5, 12, + 16, 16, 16, 16, 6, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 9, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + }, + }, +}; + + +static const uint8_t rv34_inter_coeff[NUM_INTER_TABLES][COEFF_VLC_SIZE] = { +{ + 1, 2, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, + 10, 10, 10, 11, 11, 11, 11, 12, 11, 11, 11, 13, 14, 15, 16, 16, +}, +{ + 1, 2, 3, 5, 5, 6, 6, 7, 7, 8, 9, 9, 9, 10, 10, 10, + 11, 11, 12, 12, 12, 12, 13, 13, 12, 12, 13, 14, 16, 16, 16, 16, +}, +{ + 1, 2, 3, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, + 12, 12, 13, 13, 13, 14, 14, 15, 14, 14, 16, 16, 16, 16, 16, 16, +}, +{ + 1, 2, 3, 4, 5, 6, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, + 13, 13, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}, +{ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}, +{ + 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 11, 11, 13, 12, 12, 13, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +}, +{ + 1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 10, 11, 14, 13, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 16, 16, 16, +} +}; + +#endif /* FFMPEG_RV34VLC_H */ diff --git a/contrib/ffmpeg/libavcodec/rv40.c b/contrib/ffmpeg/libavcodec/rv40.c new file mode 100644 index 000000000..f0e0d915f --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv40.c @@ -0,0 +1,279 @@ +/* + * RV40 decoder + * Copyright (c) 2007 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 + */ + +/** + * @file rv40.c + * RV40 decoder + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "golomb.h" + +#include "rv34.h" +#include "rv40vlc2.h" +#include "rv40data.h" + +static VLC aic_top_vlc; +static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM]; +static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS]; + +/** + * Initialize all tables. + */ +static void rv40_init_tables() +{ + int i; + + init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE, + rv40_aic_top_vlc_bits, 1, 1, + rv40_aic_top_vlc_codes, 1, 1, INIT_VLC_USE_STATIC); + for(i = 0; i < AIC_MODE1_NUM; i++){ + // Every tenth VLC table is empty + if((i % 10) == 9) continue; + init_vlc(&aic_mode1_vlc[i], AIC_MODE1_BITS, AIC_MODE1_SIZE, + aic_mode1_vlc_bits[i], 1, 1, + aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_STATIC); + } + for(i = 0; i < AIC_MODE2_NUM; i++){ + init_vlc(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE, + aic_mode2_vlc_bits[i], 1, 1, + aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_STATIC); + } + for(i = 0; i < NUM_PTYPE_VLCS; i++) + init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE, + ptype_vlc_bits[i], 1, 1, + ptype_vlc_codes[i], 1, 1, + ptype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC); + for(i = 0; i < NUM_BTYPE_VLCS; i++) + init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE, + btype_vlc_bits[i], 1, 1, + btype_vlc_codes[i], 1, 1, + btype_vlc_syms, 1, 1, INIT_VLC_USE_STATIC); +} + +/** + * Get stored dimension from bitstream. + * + * If the width/height is the standard one then it's coded as a 3-bit index. + * Otherwise it is coded as escaped 8-bit portions. + */ +static int get_dimension(GetBitContext *gb, const int *dim) +{ + int t = get_bits(gb, 3); + int val = dim[t]; + if(val < 0) + val = dim[get_bits1(gb) - val]; + if(!val){ + do{ + t = get_bits(gb, 8); + val += t << 2; + }while(t == 0xFF); + } + return val; +} + +/** + * Get encoded picture size - usually this is called from rv40_parse_slice_header. + */ +static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h) +{ + *w = get_dimension(gb, rv40_standard_widths); + *h = get_dimension(gb, rv40_standard_heights); +} + +static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) +{ + int t, mb_bits; + int w = r->s.width, h = r->s.height; + int mb_size; + + memset(si, 0, sizeof(SliceInfo)); + if(get_bits1(gb)) + return -1; + si->type = get_bits(gb, 2); + if(si->type == 1) si->type = 0; + si->quant = get_bits(gb, 5); + if(get_bits(gb, 2)) + return -1; + si->vlc_set = get_bits(gb, 2); + skip_bits1(gb); + t = get_bits(gb, 13); /// ??? + if(!si->type || !get_bits1(gb)) + rv40_parse_picture_size(gb, &w, &h); + if(avcodec_check_dimensions(r->s.avctx, w, h) < 0) + return -1; + si->width = w; + si->height = h; + mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); + mb_bits = ff_rv34_get_start_offset(gb, mb_size); + si->start = get_bits(gb, mb_bits); + + return 0; +} + +/** + * Decode 4x4 intra types array. + */ +static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst) +{ + MpegEncContext *s = &r->s; + int i, j, k, v; + int A, B, C; + int pattern; + int8_t *ptr; + + for(i = 0; i < 4; i++, dst += s->b4_stride){ + if(!i && s->first_slice_line){ + pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1); + dst[0] = (pattern >> 2) & 2; + dst[1] = (pattern >> 1) & 2; + dst[2] = pattern & 2; + dst[3] = (pattern << 1) & 2; + continue; + } + ptr = dst; + for(j = 0; j < 4; j++){ + /* Coefficients are read using VLC chosen by the prediction pattern + * The first one (used for retrieving a pair of coefficients) is + * constructed from the top, top right and left coefficients + * The second one (used for retrieving only one coefficient) is + * top + 10 * left. + */ + A = ptr[-s->b4_stride + 1]; // it won't be used for the last coefficient in a row + B = ptr[-s->b4_stride]; + C = ptr[-1]; + pattern = A + (B << 4) + (C << 8); + for(k = 0; k < MODE2_PATTERNS_NUM; k++) + if(pattern == rv40_aic_table_index[k]) + break; + if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients + v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2); + *ptr++ = v/9; + *ptr++ = v%9; + j++; + }else{ + if(B != -1 && C != -1) + v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1); + else{ // tricky decoding + v = 0; + switch(C){ + case -1: // code 0 -> 1, 1 -> 0 + if(B < 2) + v = get_bits1(gb) ^ 1; + break; + case 0: + case 2: // code 0 -> 2, 1 -> 0 + v = (get_bits1(gb) ^ 1) << 1; + break; + } + } + *ptr++ = v; + } + } + } + return 0; +} + +/** + * Decode macroblock information. + */ +static int rv40_decode_mb_info(RV34DecContext *r) +{ + MpegEncContext *s = &r->s; + GetBitContext *gb = &s->gb; + int q, i; + int prev_type = 0; + int mb_pos = s->mb_x + s->mb_y * s->mb_stride; + int blocks[RV34_MB_TYPES] = {0}; + int count = 0; + + if(!r->s.mb_skip_run) + r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1; + + if(--r->s.mb_skip_run) + return RV34_MB_SKIP; + + if(r->avail_cache[5-1]) + blocks[r->mb_type[mb_pos - 1]]++; + if(r->avail_cache[5-4]){ + blocks[r->mb_type[mb_pos - s->mb_stride]]++; + if(r->avail_cache[5-2]) + blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++; + if(r->avail_cache[5-5]) + blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++; + } + + for(i = 0; i < RV34_MB_TYPES; i++){ + if(blocks[i] > count){ + count = blocks[i]; + prev_type = i; + } + } + if(s->pict_type == P_TYPE){ + prev_type = block_num_to_ptype_vlc_num[prev_type]; + q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); + if(q < PBTYPE_ESCAPE) + return q; + q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); + av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n"); + }else{ + prev_type = block_num_to_btype_vlc_num[prev_type]; + q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); + if(q < PBTYPE_ESCAPE) + return q; + q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); + av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n"); + } + return 0; +} + +/** + * Initialize decoder. + */ +static int rv40_decode_init(AVCodecContext *avctx) +{ + RV34DecContext *r = avctx->priv_data; + + r->rv30 = 0; + ff_rv34_decode_init(avctx); + if(!aic_top_vlc.bits) + rv40_init_tables(); + r->parse_slice_header = rv40_parse_slice_header; + r->decode_intra_types = rv40_decode_intra_types; + r->decode_mb_info = rv40_decode_mb_info; + r->luma_dc_quant_i = rv40_luma_dc_quant[0]; + r->luma_dc_quant_p = rv40_luma_dc_quant[1]; + return 0; +} + +AVCodec rv40_decoder = { + "rv40", + CODEC_TYPE_VIDEO, + CODEC_ID_RV40, + sizeof(RV34DecContext), + rv40_decode_init, + NULL, + ff_rv34_decode_end, + ff_rv34_decode_frame, + CODEC_CAP_DR1 | CODEC_CAP_DELAY, +}; diff --git a/contrib/ffmpeg/libavcodec/rv40data.h b/contrib/ffmpeg/libavcodec/rv40data.h new file mode 100644 index 000000000..17bcb04cf --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv40data.h @@ -0,0 +1,115 @@ +/* + * RealVideo 4 decoder + * copyright (c) 2007 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 + */ + +/** + * @file rv40data.h + * miscellaneous RV40 tables + */ + +#ifndef FFMPEG_RV40DATA_H +#define FFMPEG_RV40DATA_H + +#include <stdint.h> + +/** + * standard widths and heights coded in RV40 + */ +//@{ +static const int rv40_standard_widths[] = { 160, 172, 240, 320, 352, 640, 704, 0}; +static const int rv40_standard_heights[] = { 120, 132, 144, 240, 288, 480, -8, -10, 180, 360, 576, 0}; +//@} + +#define MODE2_PATTERNS_NUM 20 +/** + * intra types table + * + * These values are actually coded 3-tuples + * used for detecting standard block configurations. + */ +static const uint16_t rv40_aic_table_index[MODE2_PATTERNS_NUM] = { + 0x000, 0x100, 0x200, + 0x011, 0x111, 0x211, 0x511, 0x611, + 0x022, 0x122, 0x222, 0x722, + 0x272, 0x227, + 0x822, 0x282, 0x228, + 0x112, 0x116, 0x221 +}; + +/** + * luma quantizer values + * The second table is used for inter blocks. + */ +static const uint8_t rv40_luma_dc_quant[2][32] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 22, 22, 22, 22 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 20, 21, 21, 22, 23, 23, 23, 24, 24, 24, 24 } +}; + +/** + * @begingroup loopfilter coefficients used by the RV40 loop filter + * @{ + */ +/** + * dither values for deblocking filter - left/top values + */ +static const uint8_t rv40_dither_l[16] = { + 0x40, 0x50, 0x20, 0x60, 0x30, 0x50, 0x40, 0x30, + 0x50, 0x40, 0x50, 0x30, 0x60, 0x20, 0x50, 0x40 +}; +/** + * dither values for deblocking filter - right/bottom values + */ +static const uint8_t rv40_dither_r[16] = { + 0x40, 0x30, 0x60, 0x20, 0x50, 0x30, 0x30, 0x40, + 0x40, 0x40, 0x50, 0x30, 0x20, 0x60, 0x30, 0x40 +}; + +/** alpha parameter for RV40 loop filter - almost the same as in JVT-A003r1 */ +static const uint8_t rv40_alpha_tab[32] = { + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 122, 96, 75, 59, 47, 37, + 29, 23, 18, 15, 13, 11, 10, 9, + 8, 7, 6, 5, 4, 3, 2, 1 +}; +/** beta parameter for RV40 loop filter - almost the same as in JVT-A003r1 */ +static const uint8_t rv40_beta_tab[32] = { + 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 4, 4, 6, 6, + 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14, 15, 16, 17 +}; +/** clip table for RV40 loop filter - the same as in JVT-A003r1 */ +static const uint8_t rv40_filter_clip_tbl[3][32] = { + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5 + }, + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 7, 8, 9 + } +}; +/** @} */ // end loopfilter group + +#endif /* FFMPEG_RV40DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/rv40vlc2.h b/contrib/ffmpeg/libavcodec/rv40vlc2.h new file mode 100644 index 000000000..f1664fcd6 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/rv40vlc2.h @@ -0,0 +1,706 @@ +/* + * RealVideo 4 decoder + * copyright (c) 2007 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 + */ + +/** + * @file rv40vlc2.h + * RV40 VLC tables used for macroblock information decoding + */ + +#ifndef FFMPEG_RV40VLC2_H +#define FFMPEG_RV40VLC2_H + +#include <stdint.h> + +/** + * codes used for the first four block types + */ +//@{ +#define AIC_TOP_BITS 8 +#define AIC_TOP_SIZE 16 +static const uint8_t rv40_aic_top_vlc_codes[AIC_TOP_SIZE] = { + 0x01, 0x05, 0x01, 0x00, 0x03, 0x3D, 0x1D, 0x02, + 0x04, 0x3C, 0x3F, 0x1C, 0x0D, 0x3E, 0x0C, 0x01 +}; + +static const uint8_t rv40_aic_top_vlc_bits[AIC_TOP_SIZE] = { + 1, 4, 5, 5, 5, 7, 6, 5, 4, 7, 7, 6, 5, 7, 5, 3 +}; +//@} + +/** + * codes used for determining a pair of block types + */ +//@{ +#define AIC_MODE2_NUM 20 +#define AIC_MODE2_SIZE 81 +#define AIC_MODE2_BITS 9 + +static const uint16_t aic_mode2_vlc_codes[AIC_MODE2_NUM][AIC_MODE2_SIZE] = { +{ 0x0001, 0x0001, 0x0005, 0x01F5, 0x0011, 0x0049, 0x0000, 0x0048, 0x004B, + 0x0035, 0x0003, 0x0034, 0x03C9, 0x01F4, 0x00C9, 0x004A, 0x0FD9, 0x03C8, + 0x0010, 0x0037, 0x0001, 0x00C8, 0x0075, 0x01F7, 0x00CB, 0x0074, 0x0002, + 0x01F6, 0x00CA, 0x01F1, 0x01F0, 0x1F81, 0x07F9, 0x1F80, 0x1F83, 0x07F8, + 0x0077, 0x00F5, 0x0036, 0x07FB, 0x0076, 0x1F82, 0x00F4, 0x00F7, 0x07FA, + 0x0071, 0x00F6, 0x03CB, 0x03CA, 0x0FD8, 0x00F1, 0x03F5, 0x1F8D, 0x07E5, + 0x0013, 0x0031, 0x00F0, 0x0FDB, 0x00F3, 0x07E4, 0x0030, 0x01F3, 0x07E7, + 0x03F4, 0x07E6, 0x0070, 0x3F19, 0x01F2, 0x3F18, 0x0FDA, 0x0033, 0x07E1, + 0x01FD, 0x01FC, 0x0073, 0x01FF, 0x0FC5, 0x0FC4, 0x0FC7, 0x03F7, 0x0072, }, +{ 0x0005, 0x0005, 0x0005, 0x0079, 0x0005, 0x000D, 0x001D, 0x0078, 0x0069, + 0x0004, 0x0001, 0x0007, 0x0068, 0x001C, 0x001F, 0x0004, 0x006B, 0x000C, + 0x0004, 0x001E, 0x0006, 0x006A, 0x0015, 0x000F, 0x0014, 0x0017, 0x0007, + 0x0016, 0x000E, 0x0011, 0x0009, 0x00D1, 0x00D0, 0x0181, 0x00D3, 0x007B, + 0x0010, 0x0013, 0x0004, 0x00D2, 0x0007, 0x0319, 0x0008, 0x007A, 0x00DD, + 0x0019, 0x0006, 0x000B, 0x0065, 0x00DC, 0x0012, 0x0064, 0x0180, 0x00DF, + 0x0006, 0x0018, 0x0001, 0x00DE, 0x001D, 0x00D9, 0x001B, 0x0067, 0x000A, + 0x00D8, 0x00DB, 0x001C, 0x0318, 0x00DA, 0x0635, 0x0183, 0x0000, 0x00C5, + 0x0066, 0x0061, 0x0035, 0x00C4, 0x0182, 0x0634, 0x031B, 0x00C7, 0x001F, }, +{ 0x0005, 0x0001, 0x001D, 0x01C1, 0x0035, 0x00F1, 0x006D, 0x00F0, 0x0049, + 0x0000, 0x0004, 0x0003, 0x00F3, 0x0048, 0x0034, 0x006C, 0x01C0, 0x01C3, + 0x0007, 0x0006, 0x0001, 0x006F, 0x0002, 0x004B, 0x006E, 0x001C, 0x0005, + 0x0069, 0x0068, 0x006B, 0x0037, 0x01C2, 0x00F2, 0x0395, 0x01CD, 0x00FD, + 0x006A, 0x0036, 0x0015, 0x01CC, 0x0014, 0x0394, 0x004A, 0x00FC, 0x00FF, + 0x0017, 0x0031, 0x00FE, 0x01CF, 0x0397, 0x00F9, 0x01CE, 0x0725, 0x0396, + 0x0016, 0x0030, 0x0075, 0x0724, 0x00F8, 0x0727, 0x0033, 0x0391, 0x0390, + 0x0011, 0x0032, 0x001F, 0x00FB, 0x0074, 0x0726, 0x00FA, 0x001E, 0x0077, + 0x0019, 0x0018, 0x0004, 0x0010, 0x003D, 0x0076, 0x0071, 0x0013, 0x0001, }, +{ 0x000D, 0x0019, 0x0011, 0x0015, 0x0061, 0x0019, 0x0014, 0x01AD, 0x0060, + 0x0018, 0x0001, 0x0005, 0x001B, 0x0010, 0x0019, 0x0005, 0x0017, 0x0018, + 0x0016, 0x0004, 0x0004, 0x0013, 0x000C, 0x0012, 0x001A, 0x0018, 0x0005, + 0x000F, 0x001B, 0x0004, 0x001D, 0x0011, 0x001C, 0x0010, 0x000E, 0x001B, + 0x0013, 0x001F, 0x001A, 0x0029, 0x0005, 0x0063, 0x001E, 0x0009, 0x0062, + 0x0008, 0x0007, 0x0007, 0x0019, 0x0004, 0x001A, 0x0018, 0x006D, 0x0007, + 0x001B, 0x0007, 0x001A, 0x006C, 0x0006, 0x0012, 0x0005, 0x006F, 0x000B, + 0x006E, 0x0069, 0x001D, 0x0359, 0x0028, 0x002B, 0x002A, 0x001C, 0x00D5, + 0x0358, 0x001F, 0x0001, 0x001E, 0x0068, 0x00D4, 0x00D7, 0x0019, 0x0000, }, +{ 0x00B9, 0x0061, 0x0060, 0x00B8, 0x02B5, 0x01AD, 0x00BB, 0x0AF5, 0x0151, + 0x0001, 0x0001, 0x0005, 0x0000, 0x0003, 0x0005, 0x0004, 0x0063, 0x0025, + 0x00BA, 0x0004, 0x0007, 0x0062, 0x00A5, 0x0024, 0x006D, 0x0002, 0x006C, + 0x02B4, 0x000D, 0x006F, 0x0027, 0x00A4, 0x0026, 0x01AC, 0x0150, 0x01AF, + 0x01AE, 0x0021, 0x006E, 0x02B7, 0x0020, 0x0153, 0x0023, 0x00A7, 0x0152, + 0x00A6, 0x0006, 0x000C, 0x0022, 0x01A9, 0x0019, 0x002D, 0x02B6, 0x01A8, + 0x000F, 0x0007, 0x000E, 0x00A1, 0x0069, 0x002C, 0x0001, 0x01AB, 0x00A0, + 0x02B1, 0x00A3, 0x002F, 0x0AF4, 0x02B0, 0x0AF7, 0x02B3, 0x0068, 0x015D, + 0x0AF6, 0x01AA, 0x0055, 0x015C, 0x02B2, 0x0579, 0x0578, 0x015F, 0x00A2, }, +{ 0x0905, 0x013D, 0x013C, 0x0904, 0x121D, 0x049D, 0x049C, 0x243D, 0x0907, + 0x00ED, 0x0001, 0x0015, 0x0041, 0x013F, 0x0031, 0x0014, 0x025D, 0x025C, + 0x013E, 0x000D, 0x0000, 0x0040, 0x0139, 0x0043, 0x0030, 0x0017, 0x0033, + 0x0906, 0x0032, 0x0042, 0x00EC, 0x025F, 0x00EF, 0x025E, 0x049F, 0x0138, + 0x0901, 0x013B, 0x0259, 0x121C, 0x049E, 0x0900, 0x0258, 0x243C, 0x121F, + 0x0903, 0x003D, 0x00EE, 0x025B, 0x025A, 0x004D, 0x013A, 0x0902, 0x0245, + 0x00E9, 0x0016, 0x00E8, 0x0499, 0x0125, 0x0244, 0x004C, 0x0498, 0x090D, + 0x00EB, 0x003C, 0x0011, 0x049B, 0x049A, 0x0485, 0x00EA, 0x003F, 0x0124, + 0x090C, 0x003E, 0x0039, 0x0095, 0x0247, 0x0246, 0x0484, 0x0094, 0x0038, }, +{ 0x0F09, 0x00CD, 0x01FD, 0x0791, 0x1E6D, 0x0790, 0x03D9, 0x3CD1, 0x3CD0, + 0x0075, 0x0001, 0x0001, 0x0035, 0x00CC, 0x0011, 0x0000, 0x03D8, 0x01FC, + 0x03DB, 0x0010, 0x0003, 0x00CF, 0x03DA, 0x00CE, 0x0074, 0x0034, 0x0077, + 0x0793, 0x0013, 0x0076, 0x0071, 0x03C5, 0x0070, 0x01FF, 0x0792, 0x01FE, + 0x01F9, 0x0037, 0x00C9, 0x0F08, 0x01F8, 0x03C4, 0x00C8, 0x0F0B, 0x079D, + 0x03C7, 0x0001, 0x0012, 0x0073, 0x00CB, 0x0005, 0x0036, 0x03C6, 0x0072, + 0x007D, 0x0002, 0x00CA, 0x079C, 0x01FB, 0x00F5, 0x0031, 0x079F, 0x0F0A, + 0x0F35, 0x079E, 0x01FA, 0x1E6C, 0x1E6F, 0x3CD3, 0x0799, 0x03C1, 0x1E6E, + 0x3CD2, 0x0030, 0x00F4, 0x007C, 0x03C0, 0x03C3, 0x0798, 0x01E5, 0x00F7, }, +{ 0x01A5, 0x0001, 0x001D, 0x0021, 0x00A1, 0x000D, 0x0061, 0x06B9, 0x00A0, + 0x0060, 0x0001, 0x0005, 0x000C, 0x0020, 0x001C, 0x0004, 0x01A4, 0x01A7, + 0x00A3, 0x001F, 0x001E, 0x0023, 0x0022, 0x002D, 0x002C, 0x0063, 0x0062, + 0x1A81, 0x01A6, 0x01A1, 0x06B8, 0x06BB, 0x00A2, 0x06BA, 0x0D59, 0x06A5, + 0x01A0, 0x000F, 0x006D, 0x06A4, 0x002F, 0x00AD, 0x006C, 0x06A7, 0x00AC, + 0x0D58, 0x000E, 0x01A3, 0x00AF, 0x00AE, 0x006F, 0x01A2, 0x0D5B, 0x00A9, + 0x0019, 0x0001, 0x0009, 0x00A8, 0x006E, 0x002E, 0x0000, 0x01AD, 0x00AB, + 0x00AA, 0x0355, 0x0029, 0x1A80, 0x1A83, 0x1A82, 0x0354, 0x01AC, 0x0D5A, + 0x1A8D, 0x01AF, 0x0357, 0x0D45, 0x0D44, 0x0D47, 0x1A8C, 0x06A6, 0x06A1, }, +{ 0x0001, 0x0011, 0x0005, 0x0775, 0x00F9, 0x00F8, 0x0031, 0x0030, 0x0049, + 0x00FB, 0x0010, 0x0033, 0x0EC9, 0x038D, 0x038C, 0x00FA, 0x038F, 0x0774, + 0x0048, 0x0032, 0x0000, 0x01D5, 0x00E5, 0x038E, 0x00E4, 0x0013, 0x000D, + 0x0389, 0x0777, 0x0388, 0x038B, 0x1DF9, 0x0EC8, 0x3BC9, 0x1DF8, 0x038A, + 0x03B5, 0x0776, 0x00E7, 0x3BC8, 0x01D4, 0x3BCB, 0x0ECB, 0x0771, 0x0ECA, + 0x01D7, 0x03B4, 0x01D6, 0x1DFB, 0x0EF5, 0x0770, 0x0EF4, 0x3BCA, 0x0773, + 0x00E6, 0x03B7, 0x004B, 0x1DFA, 0x03B6, 0x0EF7, 0x00E1, 0x0EF6, 0x0EF1, + 0x03B1, 0x01D1, 0x003D, 0x0EF0, 0x0772, 0x077D, 0x077C, 0x003C, 0x01D0, + 0x03B0, 0x01D3, 0x003F, 0x03B3, 0x01D2, 0x0EF3, 0x077F, 0x00E0, 0x004A, }, +{ 0x0015, 0x0049, 0x0014, 0x07D1, 0x03FD, 0x03FC, 0x01C1, 0x01C0, 0x00F1, + 0x0017, 0x0001, 0x0001, 0x01C3, 0x0048, 0x004B, 0x0016, 0x0031, 0x01C2, + 0x004A, 0x0011, 0x0000, 0x01CD, 0x00F0, 0x01CC, 0x0075, 0x0010, 0x000D, + 0x03FF, 0x01CF, 0x01CE, 0x07D0, 0x0F81, 0x07D3, 0x1F1D, 0x0F80, 0x07D2, + 0x01C9, 0x03FE, 0x0074, 0x07DD, 0x00F3, 0x1F1C, 0x07DC, 0x03F9, 0x07DF, + 0x00F2, 0x00FD, 0x0077, 0x07DE, 0x07D9, 0x01C8, 0x07D8, 0x0F83, 0x03F8, + 0x0030, 0x0076, 0x0013, 0x0F82, 0x00FC, 0x03FB, 0x0033, 0x03FA, 0x03E5, + 0x03E4, 0x01CB, 0x0032, 0x1F1F, 0x03E7, 0x07DB, 0x07DA, 0x003D, 0x01CA, + 0x07C5, 0x03E6, 0x0071, 0x0F8D, 0x07C4, 0x1F1E, 0x0F8C, 0x03E1, 0x01F5, }, +{ 0x0019, 0x0065, 0x0018, 0x0351, 0x0350, 0x0353, 0x0021, 0x0020, 0x0064, + 0x001D, 0x0005, 0x0005, 0x01A5, 0x0023, 0x0067, 0x0005, 0x0066, 0x0022, + 0x001B, 0x0004, 0x0001, 0x0004, 0x001C, 0x0061, 0x001A, 0x0005, 0x0004, + 0x0007, 0x002D, 0x0006, 0x002C, 0x01A4, 0x002F, 0x0352, 0x035D, 0x0060, + 0x0001, 0x002E, 0x001F, 0x035C, 0x0000, 0x06B1, 0x01A7, 0x0029, 0x01A6, + 0x0028, 0x0063, 0x0062, 0x035F, 0x01A1, 0x002B, 0x06B0, 0x06B3, 0x01A0, + 0x0003, 0x006D, 0x001E, 0x035E, 0x006C, 0x06B2, 0x0002, 0x01A3, 0x01A2, + 0x000D, 0x0005, 0x0007, 0x01AD, 0x006F, 0x002A, 0x006E, 0x0004, 0x0004, + 0x000C, 0x0007, 0x0006, 0x000F, 0x000E, 0x00D5, 0x0009, 0x0006, 0x0007, }, +{ 0x0065, 0x0181, 0x0064, 0x36C9, 0x06D5, 0x0DB5, 0x0379, 0x0180, 0x0183, + 0x00D5, 0x001D, 0x001C, 0x0DB4, 0x0182, 0x0378, 0x00D4, 0x00D7, 0x06D4, + 0x0067, 0x001F, 0x0001, 0x00D6, 0x00D1, 0x018D, 0x0066, 0x0001, 0x0000, + 0x037B, 0x06D7, 0x037A, 0x0DB7, 0x36C8, 0x06D6, 0x0DB6, 0x1B79, 0x0DB1, + 0x018C, 0x0365, 0x00D0, 0x1B78, 0x00D3, 0x1B7B, 0x0364, 0x06D1, 0x06D0, + 0x018F, 0x018E, 0x00D2, 0x36CB, 0x0367, 0x0366, 0x06D3, 0x0DB0, 0x06D2, + 0x0361, 0x06DD, 0x0189, 0x36CA, 0x0360, 0x36F5, 0x0188, 0x0DB3, 0x36F4, + 0x0009, 0x0008, 0x0005, 0x06DC, 0x00DD, 0x018B, 0x00DC, 0x0004, 0x000B, + 0x018A, 0x0061, 0x0003, 0x0363, 0x00DF, 0x06DF, 0x0362, 0x000A, 0x001E, }, +{ 0x001D, 0x0061, 0x000D, 0x0D55, 0x06B9, 0x06B8, 0x01A5, 0x0021, 0x0020, + 0x0023, 0x000C, 0x0060, 0x0D54, 0x00AD, 0x00AC, 0x0022, 0x00AF, 0x06BB, + 0x000F, 0x001C, 0x0001, 0x002D, 0x0063, 0x01A4, 0x000E, 0x0001, 0x0005, + 0x01A7, 0x06BA, 0x01A6, 0x06A5, 0x0D57, 0x0D56, 0x1ABD, 0x0D51, 0x00AE, + 0x002C, 0x00A9, 0x002F, 0x0D50, 0x01A1, 0x1ABC, 0x06A4, 0x06A7, 0x06A6, + 0x00A8, 0x06A1, 0x01A0, 0x1ABF, 0x0D53, 0x06A0, 0x0D52, 0x1ABE, 0x06A3, + 0x0062, 0x002E, 0x0009, 0x0D5D, 0x01A3, 0x0D5C, 0x006D, 0x00AB, 0x06A2, + 0x006C, 0x001F, 0x0001, 0x06AD, 0x0029, 0x01A2, 0x0028, 0x0004, 0x001E, + 0x01AD, 0x006F, 0x0000, 0x01AC, 0x01AF, 0x06AC, 0x00AA, 0x006E, 0x0019, }, +{ 0x0019, 0x007D, 0x0018, 0x01B5, 0x000D, 0x01B4, 0x007C, 0x007F, 0x01B7, + 0x000C, 0x001B, 0x001A, 0x01B6, 0x000F, 0x00D5, 0x0019, 0x007E, 0x00D4, + 0x0018, 0x001B, 0x0001, 0x000E, 0x0011, 0x0009, 0x0005, 0x0005, 0x0005, + 0x00D7, 0x01B1, 0x0008, 0x01B0, 0x0079, 0x06FD, 0x0371, 0x0370, 0x00D6, + 0x0078, 0x01B3, 0x0010, 0x0373, 0x0013, 0x06FC, 0x007B, 0x007A, 0x00D1, + 0x00D0, 0x00D3, 0x0065, 0x0372, 0x06FF, 0x0064, 0x06FE, 0x037D, 0x00D2, + 0x00DD, 0x0067, 0x0004, 0x037C, 0x0012, 0x01B2, 0x0007, 0x0066, 0x01BD, + 0x0006, 0x0061, 0x0004, 0x01BC, 0x001A, 0x0060, 0x001D, 0x0004, 0x001C, + 0x0063, 0x0001, 0x0007, 0x000B, 0x0000, 0x0062, 0x000A, 0x0005, 0x0007, }, +{ 0x0069, 0x0045, 0x0068, 0x04BD, 0x0255, 0x04BC, 0x00E5, 0x00E4, 0x0031, + 0x0030, 0x0019, 0x0001, 0x0121, 0x00E7, 0x00E6, 0x0033, 0x00E1, 0x00E0, + 0x006B, 0x0018, 0x0001, 0x0044, 0x0032, 0x0047, 0x006A, 0x001B, 0x0005, + 0x003D, 0x0046, 0x0015, 0x0041, 0x0120, 0x0123, 0x04BF, 0x0122, 0x0040, + 0x003C, 0x00E3, 0x0014, 0x0254, 0x0043, 0x0975, 0x012D, 0x00E2, 0x00ED, + 0x0042, 0x00EC, 0x004D, 0x0257, 0x0256, 0x0251, 0x04BE, 0x0974, 0x0250, + 0x00EF, 0x00EE, 0x004C, 0x04B9, 0x012C, 0x04B8, 0x004F, 0x04BB, 0x0253, + 0x003F, 0x0017, 0x0001, 0x0252, 0x00E9, 0x00E8, 0x00EB, 0x0000, 0x0003, + 0x0016, 0x0002, 0x0004, 0x004E, 0x003E, 0x00EA, 0x0049, 0x000D, 0x0007, }, +{ 0x000D, 0x01BD, 0x000C, 0x0D31, 0x0D30, 0x0D33, 0x0359, 0x0358, 0x002D, + 0x0065, 0x001D, 0x001C, 0x0D32, 0x035B, 0x035A, 0x002C, 0x01BC, 0x0345, + 0x000F, 0x001F, 0x0001, 0x002F, 0x0064, 0x01BF, 0x0067, 0x0001, 0x0005, + 0x0066, 0x002E, 0x0061, 0x0029, 0x0695, 0x0694, 0x0697, 0x0696, 0x0060, + 0x01BE, 0x0D3D, 0x0028, 0x1A49, 0x0344, 0x1A48, 0x1A4B, 0x0D3C, 0x0691, + 0x002B, 0x01B9, 0x002A, 0x0D3F, 0x0690, 0x0347, 0x0D3E, 0x1A4A, 0x0346, + 0x00D5, 0x0341, 0x0063, 0x0D39, 0x0340, 0x0D38, 0x01B8, 0x0D3B, 0x0D3A, + 0x00D4, 0x0062, 0x0000, 0x0693, 0x01BB, 0x0343, 0x0342, 0x001E, 0x000E, + 0x006D, 0x0009, 0x0001, 0x006C, 0x00D7, 0x034D, 0x01BA, 0x0008, 0x0004, }, +{ 0x0075, 0x00CD, 0x0035, 0x03C1, 0x03C0, 0x07F9, 0x03C3, 0x1F8D, 0x00CC, + 0x0074, 0x0011, 0x0010, 0x03C2, 0x0FD9, 0x01F1, 0x00CF, 0x03CD, 0x00CE, + 0x0034, 0x0001, 0x0001, 0x0037, 0x00C9, 0x00C8, 0x0036, 0x0000, 0x0001, + 0x0FD8, 0x03CC, 0x00CB, 0x01F0, 0x07F8, 0x03CF, 0x07FB, 0x07FA, 0x00CA, + 0x01F3, 0x03CE, 0x00F5, 0x0FDB, 0x00F4, 0x07E5, 0x07E4, 0x07E7, 0x01F2, + 0x07E6, 0x03C9, 0x01FD, 0x0FDA, 0x1F8C, 0x07E1, 0x1F8F, 0x1F8E, 0x03C8, + 0x03CB, 0x0077, 0x0076, 0x0FC5, 0x03CA, 0x07E0, 0x00F7, 0x0FC4, 0x03F5, + 0x00F6, 0x01FC, 0x0003, 0x03F4, 0x0071, 0x03F7, 0x00F1, 0x0013, 0x0031, + 0x0030, 0x0070, 0x0005, 0x0012, 0x0073, 0x01FF, 0x0072, 0x007D, 0x0002, }, +{ 0x0061, 0x0055, 0x0060, 0x02C9, 0x02C8, 0x02CB, 0x0171, 0x00B5, 0x0054, + 0x0001, 0x0001, 0x0001, 0x0057, 0x0001, 0x0063, 0x001D, 0x0062, 0x0039, + 0x006D, 0x0000, 0x0005, 0x0038, 0x0056, 0x00B4, 0x006C, 0x0003, 0x001C, + 0x006F, 0x003B, 0x0002, 0x003A, 0x0170, 0x00B7, 0x0173, 0x0051, 0x006E, + 0x0025, 0x0050, 0x0069, 0x02CA, 0x0024, 0x0027, 0x0172, 0x00B6, 0x00B1, + 0x000D, 0x000C, 0x001F, 0x017D, 0x0026, 0x0068, 0x0053, 0x017C, 0x006B, + 0x001E, 0x000F, 0x0004, 0x017F, 0x006A, 0x02F5, 0x0019, 0x0021, 0x0052, + 0x02F4, 0x02F7, 0x0020, 0x0BCD, 0x05E5, 0x05E4, 0x0BCC, 0x0023, 0x00B0, + 0x02F6, 0x00B3, 0x0022, 0x02F1, 0x02F0, 0x0BCF, 0x0BCE, 0x017E, 0x005D, }, +{ 0x00BD, 0x0025, 0x01A1, 0x0159, 0x0299, 0x00BC, 0x0024, 0x0505, 0x0504, + 0x01A0, 0x0001, 0x001D, 0x006D, 0x001C, 0x0001, 0x0005, 0x0027, 0x01A3, + 0x0158, 0x001F, 0x001E, 0x01A2, 0x0026, 0x0021, 0x000D, 0x0020, 0x0023, + 0x0298, 0x006C, 0x0022, 0x00BF, 0x00BE, 0x01AD, 0x002D, 0x029B, 0x00B9, + 0x01AC, 0x00B8, 0x01AF, 0x029A, 0x006F, 0x015B, 0x006E, 0x0285, 0x0284, + 0x01AE, 0x0019, 0x002C, 0x01A9, 0x01A8, 0x000C, 0x000F, 0x015A, 0x00BB, + 0x000E, 0x0000, 0x0069, 0x01AB, 0x0018, 0x01AA, 0x0004, 0x0055, 0x00BA, + 0x0507, 0x0145, 0x0054, 0x0506, 0x00A5, 0x0501, 0x00A4, 0x0057, 0x0500, + 0x0A05, 0x0144, 0x00A7, 0x0287, 0x0286, 0x0503, 0x0147, 0x0A04, 0x0146, }, +{ 0x0759, 0x0041, 0x00E5, 0x03BD, 0x0E9D, 0x012D, 0x012C, 0x3A1D, 0x03BC, + 0x012F, 0x000D, 0x0040, 0x00E4, 0x03BF, 0x0043, 0x0042, 0x0758, 0x03BE, + 0x00E7, 0x0001, 0x0000, 0x003D, 0x00E6, 0x0015, 0x0014, 0x0017, 0x003C, + 0x743D, 0x012E, 0x03B9, 0x03B8, 0x0E9C, 0x03BB, 0x075B, 0x3A1C, 0x0E9F, + 0x0129, 0x00E1, 0x0128, 0x0E9E, 0x012B, 0x075A, 0x00E0, 0x0E99, 0x0745, + 0x3A1F, 0x03BA, 0x0744, 0x0E98, 0x1D0D, 0x03A5, 0x0E9B, 0x743C, 0x0E9A, + 0x012A, 0x004D, 0x00E3, 0x0E85, 0x01D5, 0x0E84, 0x004C, 0x0747, 0x1D0C, + 0x01D4, 0x003F, 0x0016, 0x0746, 0x03A4, 0x0741, 0x004F, 0x003E, 0x01D7, + 0x0740, 0x000C, 0x0011, 0x004E, 0x00E2, 0x00ED, 0x00EC, 0x0049, 0x0048, }, +}; + +static const uint8_t aic_mode2_vlc_bits[AIC_MODE2_NUM][AIC_MODE2_SIZE] = { +{ 1, 5, 4, 10, 6, 8, 5, 8, 8, + 7, 5, 7, 11, 10, 9, 8, 13, 11, + 6, 7, 3, 9, 8, 10, 9, 8, 5, + 10, 9, 10, 10, 14, 12, 14, 14, 12, + 8, 9, 7, 12, 8, 14, 9, 9, 12, + 8, 9, 11, 11, 13, 9, 11, 14, 12, + 6, 7, 9, 13, 9, 12, 7, 10, 12, + 11, 12, 8, 15, 10, 15, 13, 7, 12, + 10, 10, 8, 10, 13, 13, 13, 11, 8, }, +{ 4, 6, 5, 11, 8, 10, 7, 11, 9, + 4, 1, 4, 9, 7, 7, 5, 9, 10, + 6, 7, 4, 9, 9, 10, 9, 9, 6, + 9, 10, 9, 10, 12, 12, 13, 12, 11, + 9, 9, 8, 12, 8, 14, 10, 11, 12, + 7, 8, 10, 11, 12, 9, 11, 13, 12, + 6, 7, 8, 12, 9, 12, 7, 11, 10, + 12, 12, 9, 14, 12, 15, 13, 8, 12, + 11, 11, 10, 12, 13, 15, 14, 12, 9, }, +{ 5, 7, 6, 12, 9, 11, 8, 11, 10, + 7, 5, 7, 11, 10, 9, 8, 12, 12, + 5, 5, 1, 8, 7, 10, 8, 6, 4, + 8, 8, 8, 9, 12, 11, 13, 12, 11, + 8, 9, 8, 12, 8, 13, 10, 11, 11, + 8, 9, 11, 12, 13, 11, 12, 14, 13, + 8, 9, 10, 14, 11, 14, 9, 13, 13, + 8, 9, 6, 11, 10, 14, 11, 6, 10, + 6, 6, 4, 8, 9, 10, 10, 8, 5, }, +{ 11, 7, 8, 10, 12, 9, 10, 14, 12, + 7, 1, 5, 7, 8, 6, 4, 10, 9, + 10, 5, 4, 8, 11, 8, 7, 6, 7, + 11, 6, 7, 8, 10, 8, 10, 11, 9, + 10, 8, 9, 13, 9, 12, 8, 11, 12, + 11, 4, 7, 8, 9, 6, 8, 12, 9, + 8, 5, 8, 12, 9, 10, 6, 12, 11, + 12, 12, 10, 15, 13, 13, 13, 10, 13, + 15, 10, 9, 10, 12, 13, 13, 10, 9, }, +{ 11, 8, 8, 11, 13, 10, 11, 15, 12, + 7, 1, 4, 7, 7, 5, 4, 8, 9, + 11, 5, 5, 8, 11, 9, 8, 7, 8, + 13, 7, 8, 9, 11, 9, 10, 12, 10, + 10, 9, 8, 13, 9, 12, 9, 11, 12, + 11, 5, 7, 9, 10, 6, 9, 13, 10, + 7, 4, 7, 11, 8, 9, 5, 10, 11, + 13, 11, 9, 15, 13, 15, 13, 8, 12, + 15, 10, 10, 12, 13, 14, 14, 12, 11, }, +{ 12, 9, 9, 12, 13, 11, 11, 14, 12, + 8, 2, 5, 7, 9, 6, 5, 10, 10, + 9, 4, 2, 7, 9, 7, 6, 5, 6, + 12, 6, 7, 8, 10, 8, 10, 11, 9, + 12, 9, 10, 13, 11, 12, 10, 14, 13, + 12, 6, 8, 10, 10, 7, 9, 12, 10, + 8, 5, 8, 11, 9, 10, 7, 11, 12, + 8, 6, 5, 11, 11, 11, 8, 6, 9, + 12, 6, 6, 8, 10, 10, 11, 8, 6, }, +{ 13, 9, 10, 12, 14, 12, 11, 15, 15, + 8, 1, 5, 7, 9, 6, 5, 11, 10, + 11, 6, 5, 9, 11, 9, 8, 7, 8, + 12, 6, 8, 8, 11, 8, 10, 12, 10, + 10, 7, 9, 13, 10, 11, 9, 13, 12, + 11, 3, 6, 8, 9, 4, 7, 11, 8, + 8, 5, 9, 12, 10, 9, 7, 12, 13, + 13, 12, 10, 14, 14, 15, 12, 11, 14, + 15, 7, 9, 8, 11, 11, 12, 10, 9, }, +{ 10, 5, 6, 9, 11, 7, 8, 12, 11, + 8, 1, 4, 7, 9, 6, 4, 10, 10, + 11, 6, 6, 9, 9, 9, 9, 8, 8, + 14, 10, 10, 12, 12, 11, 12, 13, 12, + 10, 7, 8, 12, 9, 11, 8, 12, 11, + 13, 7, 10, 11, 11, 8, 10, 13, 11, + 6, 3, 7, 11, 8, 9, 5, 10, 11, + 11, 11, 9, 14, 14, 14, 11, 10, 13, + 14, 10, 11, 13, 13, 13, 14, 12, 12, }, +{ 2, 5, 3, 11, 8, 8, 6, 6, 7, + 8, 5, 6, 12, 10, 10, 8, 10, 11, + 7, 6, 2, 9, 8, 10, 8, 5, 4, + 10, 11, 10, 10, 13, 12, 14, 13, 10, + 10, 11, 8, 14, 9, 14, 12, 11, 12, + 9, 10, 9, 13, 12, 11, 12, 14, 11, + 8, 10, 7, 13, 10, 12, 8, 12, 12, + 10, 9, 6, 12, 11, 11, 11, 6, 9, + 10, 9, 6, 10, 9, 12, 11, 8, 7, }, +{ 6, 8, 6, 12, 11, 11, 10, 10, 9, + 6, 1, 3, 10, 8, 8, 6, 7, 10, + 8, 6, 3, 10, 9, 10, 8, 6, 5, + 11, 10, 10, 12, 13, 12, 14, 13, 12, + 10, 11, 8, 12, 9, 14, 12, 11, 12, + 9, 9, 8, 12, 12, 10, 12, 13, 11, + 7, 8, 6, 13, 9, 11, 7, 11, 11, + 11, 10, 7, 14, 11, 12, 12, 7, 10, + 12, 11, 8, 13, 12, 14, 13, 11, 10, }, +{ 7, 10, 7, 13, 13, 13, 11, 11, 10, + 8, 5, 6, 12, 11, 10, 9, 10, 11, + 7, 5, 1, 9, 8, 10, 7, 4, 4, + 9, 11, 9, 11, 12, 11, 13, 13, 10, + 9, 11, 8, 13, 9, 14, 12, 11, 12, + 11, 10, 10, 13, 12, 11, 14, 14, 12, + 9, 10, 8, 13, 10, 14, 9, 12, 12, + 9, 7, 4, 12, 10, 11, 10, 6, 7, + 9, 7, 4, 9, 9, 11, 9, 7, 5, }, +{ 7, 9, 7, 14, 11, 12, 10, 9, 9, + 8, 5, 5, 12, 9, 10, 8, 8, 11, + 7, 5, 2, 8, 8, 9, 7, 4, 4, + 10, 11, 10, 12, 14, 11, 12, 13, 12, + 9, 10, 8, 13, 8, 13, 10, 11, 11, + 9, 9, 8, 14, 10, 10, 11, 12, 11, + 10, 11, 9, 14, 10, 14, 9, 12, 14, + 6, 6, 3, 11, 8, 9, 8, 3, 6, + 9, 7, 4, 10, 8, 11, 10, 6, 5, }, +{ 6, 8, 7, 13, 12, 12, 10, 9, 9, + 9, 7, 8, 13, 11, 11, 9, 11, 12, + 7, 6, 1, 9, 8, 10, 7, 5, 4, + 10, 12, 10, 12, 13, 13, 14, 13, 11, + 9, 11, 9, 13, 10, 14, 12, 12, 12, + 11, 12, 10, 14, 13, 12, 13, 14, 12, + 8, 9, 7, 13, 10, 13, 8, 11, 12, + 8, 6, 3, 12, 9, 10, 9, 4, 6, + 10, 8, 5, 10, 10, 12, 11, 8, 6, }, +{ 7, 10, 7, 12, 9, 12, 10, 10, 12, + 9, 7, 7, 12, 9, 11, 6, 10, 11, + 6, 6, 1, 9, 8, 9, 7, 4, 5, + 11, 12, 9, 12, 10, 14, 13, 13, 11, + 10, 12, 8, 13, 8, 14, 10, 10, 11, + 11, 11, 10, 13, 14, 10, 14, 13, 11, + 11, 10, 7, 13, 8, 12, 7, 10, 12, + 7, 10, 4, 12, 6, 10, 8, 5, 8, + 10, 7, 4, 9, 7, 10, 9, 6, 5, }, +{ 7, 9, 7, 13, 12, 13, 10, 10, 8, + 8, 5, 6, 11, 10, 10, 8, 10, 10, + 7, 5, 2, 9, 8, 9, 7, 5, 3, + 8, 9, 7, 9, 11, 11, 13, 11, 9, + 8, 10, 7, 12, 9, 14, 11, 10, 10, + 9, 10, 9, 12, 12, 12, 13, 14, 12, + 10, 10, 9, 13, 11, 13, 9, 13, 12, + 8, 7, 4, 12, 10, 10, 10, 6, 6, + 7, 6, 3, 9, 8, 10, 9, 6, 3, }, +{ 7, 10, 7, 13, 13, 13, 11, 11, 9, + 8, 6, 6, 13, 11, 11, 9, 10, 11, + 7, 6, 1, 9, 8, 10, 8, 5, 4, + 8, 9, 8, 9, 12, 12, 12, 12, 8, + 10, 13, 9, 14, 11, 14, 14, 13, 12, + 9, 10, 9, 13, 12, 11, 13, 14, 11, + 9, 11, 8, 13, 11, 13, 10, 13, 13, + 9, 8, 5, 12, 10, 11, 11, 6, 7, + 8, 7, 3, 8, 9, 11, 10, 7, 4, }, +{ 8, 9, 7, 11, 11, 12, 11, 14, 9, + 8, 6, 6, 11, 13, 10, 9, 11, 9, + 7, 5, 1, 7, 9, 9, 7, 5, 3, + 13, 11, 9, 10, 12, 11, 12, 12, 9, + 10, 11, 9, 13, 9, 12, 12, 12, 10, + 12, 11, 10, 13, 14, 12, 14, 14, 11, + 11, 8, 8, 13, 11, 12, 9, 13, 11, + 9, 10, 5, 11, 8, 11, 9, 6, 7, + 7, 8, 4, 6, 8, 10, 8, 8, 5, }, +{ 8, 10, 8, 13, 13, 13, 12, 11, 10, + 5, 1, 3, 10, 7, 8, 6, 8, 9, + 8, 7, 4, 9, 10, 11, 8, 7, 6, + 8, 9, 7, 9, 12, 11, 12, 10, 8, + 9, 10, 8, 13, 9, 9, 12, 11, 11, + 7, 7, 6, 12, 9, 8, 10, 12, 8, + 6, 7, 4, 12, 8, 13, 6, 9, 10, + 13, 13, 9, 15, 14, 14, 15, 9, 11, + 13, 11, 9, 13, 13, 15, 15, 12, 10, }, +{ 10, 8, 9, 11, 12, 10, 8, 13, 13, + 9, 2, 5, 7, 5, 4, 3, 8, 9, + 11, 5, 5, 9, 8, 8, 6, 8, 8, + 12, 7, 8, 10, 10, 9, 8, 12, 10, + 9, 10, 9, 12, 7, 11, 7, 12, 12, + 9, 5, 8, 9, 9, 6, 6, 11, 10, + 6, 4, 7, 9, 5, 9, 3, 9, 10, + 13, 11, 9, 13, 10, 13, 10, 9, 13, + 14, 11, 10, 12, 12, 13, 11, 14, 11, }, +{ 11, 7, 8, 10, 12, 9, 9, 14, 10, + 9, 4, 7, 8, 10, 7, 7, 11, 10, + 8, 2, 2, 6, 8, 5, 5, 5, 6, + 15, 9, 10, 10, 12, 10, 11, 14, 12, + 9, 8, 9, 12, 9, 11, 8, 12, 11, + 14, 10, 11, 12, 13, 10, 12, 15, 12, + 9, 7, 8, 12, 9, 12, 7, 11, 13, + 9, 6, 5, 11, 10, 11, 7, 6, 9, + 11, 4, 5, 7, 8, 8, 8, 7, 7, }, +}; +//@} + +/** + * Codes used for determining block type + */ +//@{ +#define AIC_MODE1_NUM 90 +#define AIC_MODE1_SIZE 9 +#define AIC_MODE1_BITS 7 + +static const uint8_t aic_mode1_vlc_codes[AIC_MODE1_NUM][AIC_MODE1_SIZE] = { + { 0x01, 0x01, 0x01, 0x11, 0x00, 0x09, 0x03, 0x10, 0x05,}, + { 0x09, 0x01, 0x01, 0x05, 0x11, 0x00, 0x03, 0x21, 0x20,}, + { 0x01, 0x01, 0x01, 0x11, 0x09, 0x10, 0x05, 0x00, 0x03,}, + { 0x01, 0x01, 0x00, 0x03, 0x21, 0x05, 0x09, 0x20, 0x11,}, + { 0x01, 0x09, 0x00, 0x29, 0x08, 0x15, 0x03, 0x0B, 0x28,}, + { 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x02,}, + { 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x01, 0x09, 0x08,}, + { 0x01, 0x01, 0x01, 0x09, 0x01, 0x08, 0x00, 0x03, 0x05,}, + { 0x01, 0x01, 0x01, 0x00, 0x05, 0x11, 0x09, 0x10, 0x03,}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, + + { 0x01, 0x01, 0x01, 0x05, 0x01, 0x00, 0x03, 0x09, 0x08,}, + { 0x09, 0x01, 0x01, 0x05, 0x11, 0x00, 0x03, 0x21, 0x20,}, + { 0x01, 0x01, 0x01, 0x0D, 0x05, 0x04, 0x00, 0x07, 0x0C,}, + { 0x01, 0x01, 0x00, 0x05, 0x11, 0x03, 0x09, 0x21, 0x20,}, + { 0x05, 0x01, 0x01, 0x11, 0x00, 0x09, 0x03, 0x21, 0x20,}, + { 0x09, 0x01, 0x01, 0x00, 0x05, 0x01, 0x03, 0x11, 0x10,}, + { 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x02,}, + { 0x01, 0x01, 0x01, 0x09, 0x00, 0x05, 0x01, 0x03, 0x08,}, + { 0x01, 0x01, 0x01, 0x09, 0x11, 0x05, 0x00, 0x10, 0x03,}, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, + + { 0x01, 0x00, 0x01, 0x09, 0x08, 0x15, 0x14, 0x0B, 0x03,}, + { 0x0D, 0x01, 0x01, 0x05, 0x0C, 0x04, 0x01, 0x00, 0x07,}, + { 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x03, 0x01, 0x01,}, + { 0x05, 0x01, 0x01, 0x04, 0x19, 0x07, 0x18, 0x0D, 0x00,}, + { 0x11, 0x09, 0x01, 0x21, 0x05, 0x20, 0x01, 0x00, 0x03,}, + { 0x41, 0x01, 0x00, 0x05, 0x40, 0x03, 0x09, 0x21, 0x11,}, + { 0x29, 0x01, 0x00, 0x28, 0x09, 0x15, 0x03, 0x08, 0x0B,}, + { 0x01, 0x00, 0x01, 0x11, 0x09, 0x10, 0x05, 0x01, 0x03,}, + { 0x05, 0x01, 0x01, 0x04, 0x0D, 0x0C, 0x07, 0x00, 0x01,}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, + + { 0x01, 0x00, 0x03, 0x05, 0x11, 0x10, 0x25, 0x24, 0x13,}, + { 0x21, 0x01, 0x01, 0x00, 0x11, 0x03, 0x05, 0x20, 0x09,}, + { 0x01, 0x01, 0x01, 0x00, 0x09, 0x11, 0x10, 0x05, 0x03,}, + { 0x21, 0x05, 0x01, 0x01, 0x09, 0x00, 0x11, 0x20, 0x03,}, + { 0x05, 0x01, 0x00, 0x04, 0x01, 0x19, 0x07, 0x18, 0x0D,}, + { 0x11, 0x01, 0x00, 0x01, 0x09, 0x01, 0x03, 0x10, 0x05,}, + { 0x1D, 0x01, 0x05, 0x0D, 0x0C, 0x04, 0x00, 0x1C, 0x0F,}, + { 0x05, 0x19, 0x01, 0x04, 0x00, 0x18, 0x1B, 0x1A, 0x07,}, + { 0x09, 0x01, 0x00, 0x01, 0x05, 0x03, 0x11, 0x10, 0x01,}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, + + { 0x01, 0x00, 0x03, 0x41, 0x05, 0x40, 0x09, 0x11, 0x21,}, + { 0x05, 0x01, 0x01, 0x19, 0x04, 0x07, 0x00, 0x18, 0x0D,}, + { 0x01, 0x01, 0x01, 0x05, 0x01, 0x04, 0x01, 0x00, 0x03,}, + { 0x01, 0x05, 0x00, 0x0D, 0x01, 0x04, 0x07, 0x19, 0x18,}, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, + { 0x31, 0x01, 0x05, 0x19, 0x04, 0x07, 0x00, 0x30, 0x0D,}, + { 0x01, 0x00, 0x03, 0x11, 0x01, 0x05, 0x01, 0x09, 0x10,}, + { 0x01, 0x05, 0x01, 0x11, 0x01, 0x10, 0x00, 0x03, 0x09,}, + { 0x01, 0x09, 0x00, 0x29, 0x03, 0x08, 0x28, 0x15, 0x0B,}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, + + { 0x01, 0x01, 0x00, 0x09, 0x15, 0x03, 0x08, 0x14, 0x0B,}, + { 0x11, 0x01, 0x01, 0x00, 0x09, 0x01, 0x03, 0x10, 0x05,}, + { 0x01, 0x00, 0x03, 0x25, 0x11, 0x05, 0x10, 0x24, 0x13,}, + { 0x11, 0x01, 0x00, 0x01, 0x09, 0x01, 0x05, 0x10, 0x03,}, + { 0x05, 0x01, 0x00, 0x0D, 0x0C, 0x04, 0x0F, 0x1D, 0x1C,}, + { 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x03, 0x02,}, + { 0x21, 0x01, 0x05, 0x09, 0x11, 0x00, 0x03, 0x41, 0x40,}, + { 0x05, 0x01, 0x00, 0x1D, 0x1C, 0x0D, 0x0C, 0x0F, 0x04,}, + { 0x05, 0x01, 0x00, 0x0D, 0x31, 0x04, 0x19, 0x30, 0x07,}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, + + { 0x01, 0x01, 0x00, 0x21, 0x05, 0x11, 0x03, 0x09, 0x20,}, + { 0x01, 0x01, 0x00, 0x11, 0x03, 0x05, 0x01, 0x09, 0x10,}, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, + { 0x05, 0x01, 0x04, 0x19, 0x07, 0x0D, 0x00, 0x31, 0x30,}, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, + { 0x05, 0x01, 0x01, 0x11, 0x09, 0x00, 0x03, 0x21, 0x20,}, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02,}, + { 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x01, 0x01, 0x02,}, + { 0x09, 0x01, 0x00, 0x29, 0x08, 0x15, 0x03, 0x28, 0x0B,}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, + + { 0x01, 0x01, 0x01, 0x05, 0x01, 0x04, 0x00, 0x01, 0x03,}, + { 0x09, 0x01, 0x00, 0x29, 0x28, 0x15, 0x08, 0x03, 0x0B,}, + { 0x01, 0x00, 0x01, 0x11, 0x05, 0x10, 0x09, 0x01, 0x03,}, + { 0x05, 0x04, 0x01, 0x1D, 0x0D, 0x0C, 0x1C, 0x00, 0x0F,}, + { 0x09, 0x11, 0x01, 0x41, 0x00, 0x40, 0x05, 0x03, 0x21,}, + { 0x0D, 0x05, 0x01, 0x1D, 0x1C, 0x0C, 0x04, 0x00, 0x0F,}, + { 0x41, 0x09, 0x01, 0x40, 0x00, 0x11, 0x05, 0x03, 0x21,}, + { 0x01, 0x01, 0x01, 0x05, 0x01, 0x04, 0x00, 0x01, 0x03,}, + { 0x05, 0x04, 0x01, 0x0D, 0x01, 0x0C, 0x07, 0x01, 0x00,}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, + + { 0x05, 0x04, 0x01, 0x07, 0x19, 0x31, 0x30, 0x0D, 0x00,}, + { 0x21, 0x01, 0x01, 0x00, 0x11, 0x09, 0x20, 0x05, 0x03,}, + { 0x05, 0x01, 0x01, 0x04, 0x07, 0x0D, 0x0C, 0x00, 0x01,}, + { 0x21, 0x09, 0x01, 0x00, 0x20, 0x05, 0x23, 0x22, 0x03,}, + { 0x31, 0x0D, 0x01, 0x19, 0x05, 0x30, 0x04, 0x07, 0x00,}, + { 0x31, 0x05, 0x01, 0x04, 0x19, 0x00, 0x0D, 0x30, 0x07,}, + { 0x31, 0x01, 0x00, 0x0D, 0x05, 0x19, 0x04, 0x30, 0x07,}, + { 0x01, 0x01, 0x01, 0x00, 0x01, 0x03, 0x02, 0x01, 0x01,}, + { 0x01, 0x00, 0x01, 0x01, 0x05, 0x09, 0x08, 0x03, 0x01,}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, +}; + +static const uint8_t aic_mode1_vlc_bits[AIC_MODE1_NUM][AIC_MODE1_SIZE] = { + { 1, 4, 2, 7, 4, 6, 4, 7, 5,}, + { 5, 1, 3, 4, 6, 3, 3, 7, 7,}, + { 1, 4, 2, 7, 6, 7, 5, 4, 4,}, + { 1, 3, 3, 3, 7, 4, 5, 7, 6,}, + { 2, 4, 2, 6, 4, 5, 2, 4, 6,}, + { 7, 2, 3, 4, 7, 1, 5, 7, 7,}, + { 5, 1, 3, 6, 5, 5, 2, 7, 7,}, + { 2, 5, 1, 7, 3, 7, 5, 5, 6,}, + { 2, 4, 1, 4, 5, 7, 6, 7, 4,}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + + { 2, 1, 3, 6, 5, 5, 5, 7, 7,}, + { 5, 1, 3, 4, 6, 3, 3, 7, 7,}, + { 4, 1, 2, 6, 5, 5, 4, 5, 6,}, + { 3, 1, 3, 4, 6, 3, 5, 7, 7,}, + { 4, 1, 3, 6, 3, 5, 3, 7, 7,}, + { 6, 1, 4, 4, 5, 2, 4, 7, 7,}, + { 7, 1, 5, 7, 4, 3, 2, 7, 7,}, + { 5, 3, 2, 7, 5, 6, 1, 5, 7,}, + { 4, 1, 2, 6, 7, 5, 4, 7, 4,}, + { 1, 0, 1, 0, 0, 0, 0, 0, 0,}, + + { 3, 3, 1, 5, 5, 6, 6, 5, 3,}, + { 6, 2, 1, 5, 6, 5, 4, 4, 5,}, + { 6, 4, 1, 7, 6, 7, 6, 3, 2,}, + { 4, 3, 1, 4, 6, 4, 6, 5, 3,}, + { 6, 5, 1, 7, 4, 7, 3, 3, 3,}, + { 7, 2, 2, 3, 7, 2, 4, 6, 5,}, + { 6, 2, 2, 6, 4, 5, 2, 4, 4,}, + { 4, 4, 1, 7, 6, 7, 5, 2, 4,}, + { 5, 4, 1, 5, 6, 6, 5, 4, 2,}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + + { 2, 2, 2, 3, 5, 5, 6, 6, 5,}, + { 7, 1, 3, 3, 6, 3, 4, 7, 5,}, + { 2, 4, 1, 4, 6, 7, 7, 5, 4,}, + { 7, 4, 3, 1, 5, 3, 6, 7, 3,}, + { 4, 3, 3, 4, 1, 6, 4, 6, 5,}, + { 7, 4, 4, 2, 6, 1, 4, 7, 5,}, + { 5, 2, 3, 4, 4, 3, 2, 5, 4,}, + { 3, 5, 2, 3, 2, 5, 5, 5, 3,}, + { 6, 4, 4, 2, 5, 4, 7, 7, 1,}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + + { 2, 2, 2, 7, 3, 7, 4, 5, 6,}, + { 4, 1, 3, 6, 4, 4, 3, 6, 5,}, + { 2, 4, 1, 7, 3, 7, 6, 6, 6,}, + { 3, 4, 3, 5, 1, 4, 4, 6, 6,}, + { 4, 5, 2, 7, 1, 7, 3, 7, 7,}, + { 6, 2, 3, 5, 3, 3, 2, 6, 4,}, + { 4, 4, 4, 7, 2, 5, 1, 6, 7,}, + { 4, 5, 2, 7, 1, 7, 4, 4, 6,}, + { 2, 4, 2, 6, 2, 4, 6, 5, 4,}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + + { 1, 3, 3, 5, 6, 3, 5, 6, 5,}, + { 7, 1, 4, 4, 6, 2, 4, 7, 5,}, + { 2, 2, 2, 6, 5, 3, 5, 6, 5,}, + { 7, 4, 4, 2, 6, 1, 5, 7, 4,}, + { 3, 2, 2, 4, 4, 3, 4, 5, 5,}, + { 7, 2, 5, 3, 7, 1, 4, 7, 7,}, + { 6, 2, 3, 4, 5, 2, 2, 7, 7,}, + { 3, 2, 2, 5, 5, 4, 4, 4, 3,}, + { 3, 2, 2, 4, 6, 3, 5, 6, 3,}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + + { 1, 3, 3, 7, 4, 6, 3, 5, 7,}, + { 4, 1, 4, 7, 4, 5, 2, 6, 7,}, + { 2, 4, 1, 7, 5, 7, 3, 7, 7,}, + { 3, 2, 3, 5, 3, 4, 2, 6, 6,}, + { 3, 5, 4, 7, 2, 7, 1, 7, 7,}, + { 4, 1, 3, 6, 5, 3, 3, 7, 7,}, + { 4, 2, 5, 7, 3, 7, 1, 7, 7,}, + { 7, 4, 1, 7, 3, 7, 2, 5, 7,}, + { 4, 2, 2, 6, 4, 5, 2, 6, 4,}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + + { 3, 4, 1, 7, 6, 7, 6, 2, 6,}, + { 4, 2, 2, 6, 6, 5, 4, 2, 4,}, + { 4, 4, 1, 7, 5, 7, 6, 2, 4,}, + { 3, 3, 2, 5, 4, 4, 5, 2, 4,}, + { 4, 5, 2, 7, 2, 7, 3, 2, 6,}, + { 4, 3, 2, 5, 5, 4, 3, 2, 4,}, + { 7, 4, 2, 7, 2, 5, 3, 2, 6,}, + { 4, 6, 2, 7, 3, 7, 6, 1, 6,}, + { 5, 5, 1, 6, 4, 6, 5, 2, 4,}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, + + { 3, 3, 2, 3, 5, 6, 6, 4, 2,}, + { 7, 1, 3, 3, 6, 5, 7, 4, 3,}, + { 5, 4, 1, 5, 5, 6, 6, 4, 2,}, + { 6, 4, 2, 2, 6, 3, 6, 6, 2,}, + { 6, 4, 2, 5, 3, 6, 3, 3, 2,}, + { 6, 3, 2, 3, 5, 2, 4, 6, 3,}, + { 6, 2, 2, 4, 3, 5, 3, 6, 3,}, + { 7, 5, 1, 7, 4, 7, 7, 3, 2,}, + { 5, 5, 2, 3, 6, 7, 7, 5, 1,}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0,}, +}; + +//@} + +#define PBTYPE_ESCAPE 0xFF + +/** tables used for P-frame macroblock type decoding */ +//@{ +#define NUM_PTYPE_VLCS 7 +#define PTYPE_VLC_SIZE 8 +#define PTYPE_VLC_BITS 7 + +static const uint8_t ptype_vlc_codes[NUM_PTYPE_VLCS][PTYPE_VLC_SIZE] = { + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, + { 0x0D, 0x05, 0x01, 0x04, 0x01, 0x00, 0x07, 0x0C }, + { 0x09, 0x11, 0x01, 0x00, 0x05, 0x03, 0x21, 0x20 }, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 } +}; + +static const uint8_t ptype_vlc_bits[NUM_PTYPE_VLCS][PTYPE_VLC_SIZE] = { + { 1, 2, 3, 6, 5, 4, 7, 7 }, + { 3, 1, 2, 7, 6, 5, 4, 7 }, + { 5, 4, 1, 4, 3, 3, 4, 5 }, + { 4, 5, 2, 2, 3, 2, 6, 6 }, + { 5, 6, 1, 4, 2, 3, 7, 7 }, + { 5, 6, 1, 4, 3, 2, 7, 7 }, + { 6, 3, 2, 7, 5, 4, 1, 7 } +}; + +static const uint8_t ptype_vlc_syms[PTYPE_VLC_SIZE] = { + 0, 1, 2, 3, 8, 9, 11, PBTYPE_ESCAPE +}; + +/** reverse of ptype_vlc_syms */ +static const uint8_t block_num_to_ptype_vlc_num[12] = { + 0, 1, 2, 3, 0, 0, 2, 0, 4, 5, 0, 6 +}; +//@} + +/** tables used for P-frame macroblock type decoding */ +//@{ +#define NUM_BTYPE_VLCS 6 +#define BTYPE_VLC_SIZE 7 +#define BTYPE_VLC_BITS 6 + +static const uint8_t btype_vlc_codes[NUM_BTYPE_VLCS][BTYPE_VLC_SIZE] = { + { 0x01, 0x05, 0x00, 0x03, 0x11, 0x09, 0x10 }, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, + { 0x09, 0x01, 0x00, 0x01, 0x05, 0x03, 0x08 }, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }, + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 } +}; + +static const uint8_t btype_vlc_bits[NUM_BTYPE_VLCS][PTYPE_VLC_SIZE] = { + { 2, 3, 2, 2, 5, 4, 5 }, + { 4, 1, 3, 2, 6, 5, 6 }, + { 6, 4, 1, 2, 5, 3, 6 }, + { 5, 3, 3, 1, 4, 3, 5 }, + { 6, 5, 3, 2, 4, 1, 6 }, + { 6, 5, 3, 1, 4, 2, 6 } +}; + +static const uint8_t btype_vlc_syms[BTYPE_VLC_SIZE] = { + 0, 1, 4, 5, 10, 7, PBTYPE_ESCAPE +}; + +/** reverse of btype_vlc_syms */ +static const uint8_t block_num_to_btype_vlc_num[12] = { + 0, 1, 0, 0, 2, 3, 0, 5, 0, 0, 4, 0 +}; +//@} +#endif /* FFMPEG_RV40VLC2_H */ diff --git a/contrib/ffmpeg/libavcodec/s3tc.c b/contrib/ffmpeg/libavcodec/s3tc.c new file mode 100644 index 000000000..fc035e577 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/s3tc.c @@ -0,0 +1,96 @@ +/* + * S3 Texture Compression (S3TC) decoding functions + * Copyright (c) 2007 by Ivo van Poorten + * + * see also: http://wiki.multimedia.cx/index.php?title=S3TC + * + * 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" +#include "s3tc.h" + +static inline void dxt1_decode_pixels(const uint8_t *s, uint32_t *d, + unsigned int qstride, unsigned int flag, + uint64_t alpha) { + unsigned int x, y, c0, c1, a = (!flag * 255) << 24; + unsigned int rb0, rb1, rb2, rb3, g0, g1, g2, g3; + uint32_t colors[4], pixels; + + c0 = AV_RL16(s); + c1 = AV_RL16(s+2); + + rb0 = (c0<<3 | c0<<8) & 0xf800f8; + rb1 = (c1<<3 | c1<<8) & 0xf800f8; + rb0 += (rb0>>5) & 0x070007; + rb1 += (rb1>>5) & 0x070007; + g0 = (c0 <<5) & 0x00fc00; + g1 = (c1 <<5) & 0x00fc00; + g0 += (g0 >>6) & 0x000300; + g1 += (g1 >>6) & 0x000300; + + colors[0] = rb0 + g0 + a; + colors[1] = rb1 + g1 + a; + + if (c0 > c1 || flag) { + rb2 = (((2*rb0+rb1) * 21) >> 6) & 0xff00ff; + rb3 = (((2*rb1+rb0) * 21) >> 6) & 0xff00ff; + g2 = (((2*g0 +g1 ) * 21) >> 6) & 0x00ff00; + g3 = (((2*g1 +g0 ) * 21) >> 6) & 0x00ff00; + colors[3] = rb3 + g3 + a; + } else { + rb2 = ((rb0+rb1) >> 1) & 0xff00ff; + g2 = ((g0 +g1 ) >> 1) & 0x00ff00; + colors[3] = 0; + } + + colors[2] = rb2 + g2 + a; + + pixels = AV_RL32(s+4); + for (y=0; y<4; y++) { + for (x=0; x<4; x++) { + a = (alpha & 0x0f) << 28; + a += a >> 4; + d[x] = a + colors[pixels&3]; + pixels >>= 2; + alpha >>= 4; + } + d += qstride; + } +} + +void ff_decode_dxt1(const uint8_t *s, uint8_t *dst, + const unsigned int w, const unsigned int h, + const unsigned int stride) { + unsigned int bx, by, qstride = stride/4; + uint32_t *d = (uint32_t *) dst; + + for (by=0; by < h/4; by++, d += stride-w) + for (bx=0; bx < w/4; bx++, s+=8, d+=4) + dxt1_decode_pixels(s, d, qstride, 0, 0LL); +} + +void ff_decode_dxt3(const uint8_t *s, uint8_t *dst, + const unsigned int w, const unsigned int h, + const unsigned int stride) { + unsigned int bx, by, qstride = stride/4; + uint32_t *d = (uint32_t *) dst; + + for (by=0; by < h/4; by++, d += stride-w) + for (bx=0; bx < w/4; bx++, s+=16, d+=4) + dxt1_decode_pixels(s+8, d, qstride, 1, AV_RL64(s)); +} diff --git a/contrib/ffmpeg/libavcodec/s3tc.h b/contrib/ffmpeg/libavcodec/s3tc.h new file mode 100644 index 000000000..9ead901b6 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/s3tc.h @@ -0,0 +1,53 @@ +/* + * S3 Texture Compression (S3TC) decoding functions + * Copyright (c) 2007 by Ivo van Poorten + * + * 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 + */ + +#ifndef FFMPEG_S3TC_H +#define FFMPEG_S3TC_H + +#include <stdint.h> + +#define FF_S3TC_DXT1 0x31545844 +#define FF_S3TC_DXT3 0x33545844 + +/** + * Decode DXT1 encoded data to RGB32 + * @param *src source buffer, has to be aligned on a 4-byte boundary + * @param *dst destination buffer + * @param w width of output image + * @param h height of output image + * @param stride line size of output image + */ +void ff_decode_dxt1(const uint8_t *src, uint8_t *dst, + const unsigned int w, const unsigned int h, + const unsigned int stride); +/** + * Decode DXT3 encoded data to RGB32 + * @param *src source buffer, has to be aligned on a 4-byte boundary + * @param *dst destination buffer + * @param w width of output image + * @param h height of output image + * @param stride line size of output image + */ +void ff_decode_dxt3(const uint8_t *src, uint8_t *dst, + const unsigned int w, const unsigned int h, + const unsigned int stride); + +#endif /* FFMPEG_S3TC_H */ diff --git a/contrib/ffmpeg/libavcodec/sgi.h b/contrib/ffmpeg/libavcodec/sgi.h new file mode 100644 index 000000000..8c658761d --- /dev/null +++ b/contrib/ffmpeg/libavcodec/sgi.h @@ -0,0 +1,36 @@ + /* + * SGI image encoder + * Xiaohui Sun <tjnksxh@hotmail.com> + * + * 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 + */ + +#ifndef FFMPEG_SGI_H +#define FFMPEG_SGI_H + +/** + * SGI image file signature + */ +#define SGI_MAGIC 474 + +#define SGI_HEADER_SIZE 512 + +#define SGI_GRAYSCALE 1 +#define SGI_RGB 3 +#define SGI_RGBA 4 + +#endif /* FFMPEG_SGI_H */ diff --git a/contrib/ffmpeg/libavcodec/sgidec.c b/contrib/ffmpeg/libavcodec/sgidec.c new file mode 100644 index 000000000..5a85cdcdd --- /dev/null +++ b/contrib/ffmpeg/libavcodec/sgidec.c @@ -0,0 +1,267 @@ +/* + * SGI image decoder + * Todd Kirby <doubleshot@pacbell.net> + * + * 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" +#include "bytestream.h" +#include "sgi.h" + +typedef struct SgiState { + AVFrame picture; + unsigned int width; + unsigned int height; + unsigned int depth; + int linesize; +} SgiState; + +/** + * Expand an RLE row into a channel. + * @param in_buf input buffer + * @param in_end end of input buffer + * @param out_buf Points to one line after the output buffer. + * @param out_end end of line in output buffer + * @param pixelstride pixel stride of input buffer + * @return size of output in bytes, -1 if buffer overflows + */ +static int expand_rle_row(const uint8_t *in_buf, const uint8_t* in_end, + unsigned char *out_buf, uint8_t* out_end, int pixelstride) +{ + unsigned char pixel, count; + unsigned char *orig = out_buf; + + while (1) { + if(in_buf + 1 > in_end) return -1; + pixel = bytestream_get_byte(&in_buf); + if (!(count = (pixel & 0x7f))) { + return (out_buf - orig) / pixelstride; + } + + /* Check for buffer overflow. */ + if(out_buf + pixelstride * count >= out_end) return -1; + + if (pixel & 0x80) { + while (count--) { + *out_buf = bytestream_get_byte(&in_buf); + out_buf += pixelstride; + } + } else { + pixel = bytestream_get_byte(&in_buf); + + while (count--) { + *out_buf = pixel; + out_buf += pixelstride; + } + } + } +} + +/** + * Read a run length encoded SGI image. + * @param out_buf output buffer + * @param in_buf input buffer + * @param in_end end of input buffer + * @param s the current image state + * @return 0 if no error, else return error number. + */ +static int read_rle_sgi(unsigned char* out_buf, const uint8_t *in_buf, + const uint8_t *in_end, SgiState* s) +{ + uint8_t *dest_row; + unsigned int len = s->height * s->depth * 4; + const uint8_t *start_table = in_buf; + unsigned int y, z; + unsigned int start_offset; + + /* size of RLE offset and length tables */ + if(len * 2 > in_end - in_buf) { + return AVERROR_INVALIDDATA; + } + + in_buf -= SGI_HEADER_SIZE; + for (z = 0; z < s->depth; z++) { + dest_row = out_buf; + for (y = 0; y < s->height; y++) { + dest_row -= s->linesize; + start_offset = bytestream_get_be32(&start_table); + if(start_offset > in_end - in_buf) { + return AVERROR_INVALIDDATA; + } + if (expand_rle_row(in_buf + start_offset, in_end, dest_row + z, + dest_row + FFABS(s->linesize), s->depth) != s->width) + return AVERROR_INVALIDDATA; + } + } + return 0; +} + +/** + * Read an uncompressed SGI image. + * @param out_buf output buffer + * @param out_end end ofoutput buffer + * @param in_buf input buffer + * @param in_end end of input buffer + * @param s the current image state + * @return 0 if read success, otherwise return -1. + */ +static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end, + const uint8_t *in_buf, const uint8_t *in_end, SgiState* s) +{ + int x, y, z; + const uint8_t *ptr; + unsigned int offset = s->height * s->width; + + /* Test buffer size. */ + if (offset * s->depth > in_end - in_buf) { + return -1; + } + + for (y = s->height - 1; y >= 0; y--) { + out_end = out_buf + (y * s->linesize); + for (x = s->width; x > 0; x--) { + ptr = in_buf++; + for(z = 0; z < s->depth; z ++) { + bytestream_put_byte(&out_end, *ptr); + ptr += offset; + } + } + } + return 0; +} + +static int decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *in_buf, int buf_size) +{ + SgiState *s = avctx->priv_data; + AVFrame *picture = data; + AVFrame *p = &s->picture; + const uint8_t *in_end = in_buf + buf_size; + unsigned int dimension, bytes_per_channel, rle; + int ret = 0; + uint8_t *out_buf, *out_end; + + if (buf_size < SGI_HEADER_SIZE){ + av_log(avctx, AV_LOG_ERROR, "buf_size too small (%d)\n", buf_size); + return -1; + } + + /* Test for SGI magic. */ + if (bytestream_get_be16(&in_buf) != SGI_MAGIC) { + av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); + return -1; + } + + rle = bytestream_get_byte(&in_buf); + bytes_per_channel = bytestream_get_byte(&in_buf); + dimension = bytestream_get_be16(&in_buf); + s->width = bytestream_get_be16(&in_buf); + s->height = bytestream_get_be16(&in_buf); + s->depth = bytestream_get_be16(&in_buf); + + if (bytes_per_channel != 1) { + av_log(avctx, AV_LOG_ERROR, "wrong channel number\n"); + return -1; + } + + /* Check for supported image dimensions. */ + if (dimension != 2 && dimension != 3) { + av_log(avctx, AV_LOG_ERROR, "wrong dimension number\n"); + return -1; + } + + if (s->depth == SGI_GRAYSCALE) { + avctx->pix_fmt = PIX_FMT_GRAY8; + } else if (s->depth == SGI_RGB) { + avctx->pix_fmt = PIX_FMT_RGB24; + } else if (s->depth == SGI_RGBA) { + avctx->pix_fmt = PIX_FMT_RGBA; + } else { + av_log(avctx, AV_LOG_ERROR, "wrong picture format\n"); + return -1; + } + + if (avcodec_check_dimensions(avctx, s->width, s->height)) + return -1; + avcodec_set_dimensions(avctx, s->width, s->height); + + 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 = FF_I_TYPE; + p->key_frame = 1; + out_buf = p->data[0]; + + out_end = out_buf + p->linesize[0] * s->height; + + s->linesize = p->linesize[0]; + + /* Skip header. */ + in_buf += SGI_HEADER_SIZE - 12; + if (rle) { + ret = read_rle_sgi(out_end, in_buf, in_end, s); + } else { + ret = read_uncompressed_sgi(out_buf, out_end, in_buf, in_end, s); + } + + if (ret == 0) { + *picture = s->picture; + *data_size = sizeof(AVPicture); + return buf_size; + } else { + return -1; + } +} + +static int sgi_init(AVCodecContext *avctx){ + SgiState *s = avctx->priv_data; + + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame = &s->picture; + + return 0; +} + +static int sgi_end(AVCodecContext *avctx) +{ + SgiState * const s = avctx->priv_data; + + if (s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + + return 0; +} + +AVCodec sgi_decoder = { + "sgi", + CODEC_TYPE_VIDEO, + CODEC_ID_SGI, + sizeof(SgiState), + sgi_init, + NULL, + sgi_end, + decode_frame, +}; + diff --git a/contrib/ffmpeg/libavcodec/sgienc.c b/contrib/ffmpeg/libavcodec/sgienc.c new file mode 100644 index 000000000..147bc8961 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/sgienc.c @@ -0,0 +1,156 @@ +/* + * SGI image encoder + * Todd Kirby <doubleshot@pacbell.net> + * + * 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" +#include "bytestream.h" +#include "sgi.h" +#include "rle.h" + +#define SGI_SINGLE_CHAN 2 +#define SGI_MULTI_CHAN 3 + +typedef struct SgiContext { + AVFrame picture; +} SgiContext; + +static int encode_init(AVCodecContext *avctx){ + SgiContext *s = avctx->priv_data; + + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame = &s->picture; + + return 0; +} + +static int encode_frame(AVCodecContext *avctx, unsigned char *buf, + int buf_size, void *data) { + SgiContext *s = avctx->priv_data; + AVFrame * const p = &s->picture; + uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf; + int x, y, z, length, tablesize; + unsigned int width, height, depth, dimension; + unsigned char *orig_buf = buf, *end_buf = buf + buf_size; + + *p = *(AVFrame*)data; + p->pict_type = FF_I_TYPE; + p->key_frame = 1; + + width = avctx->width; + height = avctx->height; + + switch (avctx->pix_fmt) { + case PIX_FMT_GRAY8: + dimension = SGI_SINGLE_CHAN; + depth = SGI_GRAYSCALE; + break; + case PIX_FMT_RGB24: + dimension = SGI_MULTI_CHAN; + depth = SGI_RGB; + break; + case PIX_FMT_RGBA: + dimension = SGI_MULTI_CHAN; + depth = SGI_RGBA; + break; + default: + return AVERROR_INVALIDDATA; + } + + tablesize = depth * height * 4; + length = tablesize * 2 + SGI_HEADER_SIZE; + + if (buf_size < length) { + av_log(avctx, AV_LOG_ERROR, "buf_size too small(need %d, got %d)\n", length, buf_size); + return -1; + } + + /* Encode header. */ + bytestream_put_be16(&buf, SGI_MAGIC); + bytestream_put_byte(&buf, 1); /* RLE */ + bytestream_put_byte(&buf, 1); /* bytes_per_channel */ + bytestream_put_be16(&buf, dimension); + bytestream_put_be16(&buf, width); + bytestream_put_be16(&buf, height); + bytestream_put_be16(&buf, depth); + + /* The rest are constant in this implementation. */ + bytestream_put_be32(&buf, 0L); /* pixmin */ + bytestream_put_be32(&buf, 255L); /* pixmax */ + bytestream_put_be32(&buf, 0L); /* dummy */ + + /* name */ + memset(buf, 0, SGI_HEADER_SIZE); + buf += 80; + + /* colormap */ + bytestream_put_be32(&buf, 0L); + + /* The rest of the 512 byte header is unused. */ + buf += 404; + offsettab = buf; + + /* Skip RLE offset table. */ + buf += tablesize; + lengthtab = buf; + + /* Skip RLE length table. */ + buf += tablesize; + + /* Make an intermediate consecutive buffer. */ + if ((encode_buf = av_malloc(width)) == NULL) + return -1; + + for (z = 0; z < depth; z++) { + in_buf = p->data[0] + p->linesize[0] * (height - 1) + z; + + for (y = 0; y < height; y++) { + bytestream_put_be32(&offsettab, buf - orig_buf); + + for (x = 0; x < width; x++) + encode_buf[x] = in_buf[depth * x]; + + if((length = ff_rle_encode(buf, end_buf - buf - 1, encode_buf, 1, width, 0, 0, 0x80, 0)) < 1) { + av_free(encode_buf); + return -1; + } + + buf += length; + bytestream_put_byte(&buf, 0); + bytestream_put_be32(&lengthtab, length + 1); + in_buf -= p->linesize[0]; + } + } + + av_free(encode_buf); + /* total length */ + return buf - orig_buf; +} + +AVCodec sgi_encoder = { + "sgi", + CODEC_TYPE_VIDEO, + CODEC_ID_SGI, + sizeof(SgiContext), + encode_init, + encode_frame, + NULL, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_PAL8, PIX_FMT_GRAY8, -1}, +}; + diff --git a/contrib/ffmpeg/libavcodec/sh4/dsputil_align.c b/contrib/ffmpeg/libavcodec/sh4/dsputil_align.c index 7e7e3304b..15b0350f2 100644 --- a/contrib/ffmpeg/libavcodec/sh4/dsputil_align.c +++ b/contrib/ffmpeg/libavcodec/sh4/dsputil_align.c @@ -21,8 +21,8 @@ */ -#include "../avcodec.h" -#include "../dsputil.h" +#include "avcodec.h" +#include "dsputil.h" #define LP(p) *(uint32_t*)(p) diff --git a/contrib/ffmpeg/libavcodec/sh4/dsputil_sh4.c b/contrib/ffmpeg/libavcodec/sh4/dsputil_sh4.c index b38eb2551..18b19b1c3 100644 --- a/contrib/ffmpeg/libavcodec/sh4/dsputil_sh4.c +++ b/contrib/ffmpeg/libavcodec/sh4/dsputil_sh4.c @@ -20,8 +20,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../avcodec.h" -#include "../dsputil.h" +#include "avcodec.h" +#include "dsputil.h" static void memzero_align8(void *dst,size_t size) { diff --git a/contrib/ffmpeg/libavcodec/sh4/idct_sh4.c b/contrib/ffmpeg/libavcodec/sh4/idct_sh4.c index 3b8428c3c..8259c0075 100644 --- a/contrib/ffmpeg/libavcodec/sh4/idct_sh4.c +++ b/contrib/ffmpeg/libavcodec/sh4/idct_sh4.c @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "../dsputil.h" +#include "dsputil.h" #define c1 1.38703984532214752434 /* sqrt(2)*cos(1*pi/16) */ #define c2 1.30656296487637657577 /* sqrt(2)*cos(2*pi/16) */ #define c3 1.17587560241935884520 /* sqrt(2)*cos(3*pi/16) */ diff --git a/contrib/ffmpeg/libavcodec/sh4/qpel.c b/contrib/ffmpeg/libavcodec/sh4/qpel.c index 7a73ac50d..a75d22f6c 100644 --- a/contrib/ffmpeg/libavcodec/sh4/qpel.c +++ b/contrib/ffmpeg/libavcodec/sh4/qpel.c @@ -21,14 +21,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define LD(adr) *(uint32_t*)(adr) - #define PIXOP2(OPNAME, OP) \ /*static inline void OPNAME ## _no_rnd_pixels8_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do {\ - OP(LP(dst ),no_rnd_avg32(LD32(src1 ),LD32(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(LD32(src1+4),LD32(src2+4)) ); \ + OP(LP(dst ),no_rnd_avg32(AV_RN32(src1 ),AV_RN32(src2 )) ); \ + OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),AV_RN32(src2+4)) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -38,8 +36,8 @@ static inline void OPNAME ## _pixels8_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do {\ - OP(LP(dst ),rnd_avg32(LD32(src1 ),LD32(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(LD32(src1+4),LD32(src2+4)) ); \ + OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),AV_RN32(src2 )) ); \ + OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),AV_RN32(src2+4)) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -49,7 +47,7 @@ static inline void OPNAME ## _pixels8_l2(uint8_t *dst, const uint8_t *src1, cons static inline void OPNAME ## _pixels4_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do {\ - OP(LP(dst ),rnd_avg32(LD32(src1 ),LD32(src2 )) ); \ + OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),AV_RN32(src2 )) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -59,10 +57,10 @@ static inline void OPNAME ## _pixels4_l2(uint8_t *dst, const uint8_t *src1, cons static inline void OPNAME ## _no_rnd_pixels16_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do {\ - OP(LP(dst ),no_rnd_avg32(LD32(src1 ),LD32(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(LD32(src1+4),LD32(src2+4)) ); \ - OP(LP(dst+8),no_rnd_avg32(LD32(src1+8),LD32(src2+8)) ); \ - OP(LP(dst+12),no_rnd_avg32(LD32(src1+12),LD32(src2+12)) ); \ + OP(LP(dst ),no_rnd_avg32(AV_RN32(src1 ),AV_RN32(src2 )) ); \ + OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),AV_RN32(src2+4)) ); \ + OP(LP(dst+8),no_rnd_avg32(AV_RN32(src1+8),AV_RN32(src2+8)) ); \ + OP(LP(dst+12),no_rnd_avg32(AV_RN32(src1+12),AV_RN32(src2+12)) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -72,10 +70,10 @@ static inline void OPNAME ## _no_rnd_pixels16_l2(uint8_t *dst, const uint8_t *sr static inline void OPNAME ## _pixels16_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do {\ - OP(LP(dst ),rnd_avg32(LD32(src1 ),LD32(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(LD32(src1+4),LD32(src2+4)) ); \ - OP(LP(dst+8),rnd_avg32(LD32(src1+8),LD32(src2+8)) ); \ - OP(LP(dst+12),rnd_avg32(LD32(src1+12),LD32(src2+12)) ); \ + OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),AV_RN32(src2 )) ); \ + OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),AV_RN32(src2+4)) ); \ + OP(LP(dst+8),rnd_avg32(AV_RN32(src1+8),AV_RN32(src2+8)) ); \ + OP(LP(dst+12),rnd_avg32(AV_RN32(src1+12),AV_RN32(src2+12)) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -95,7 +93,7 @@ static inline void OPNAME ## _pixels4_l2_aligned(uint8_t *dst, const uint8_t *sr static inline void OPNAME ## _pixels4_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do {\ - OP(LP(dst ),rnd_avg32(LD32(src1 ),LP(src2 )) ); \ + OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),LP(src2 )) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -105,10 +103,10 @@ static inline void OPNAME ## _pixels4_l2_aligned2(uint8_t *dst, const uint8_t *s static inline void OPNAME ## _no_rnd_pixels16_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do {\ - OP(LP(dst ),no_rnd_avg32(LD32(src1 ),LP(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(LD32(src1+4),LP(src2+4)) ); \ - OP(LP(dst+8),no_rnd_avg32(LD32(src1+8),LP(src2+8)) ); \ - OP(LP(dst+12),no_rnd_avg32(LD32(src1+12),LP(src2+12)) ); \ + OP(LP(dst ),no_rnd_avg32(AV_RN32(src1 ),LP(src2 )) ); \ + OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),LP(src2+4)) ); \ + OP(LP(dst+8),no_rnd_avg32(AV_RN32(src1+8),LP(src2+8)) ); \ + OP(LP(dst+12),no_rnd_avg32(AV_RN32(src1+12),LP(src2+12)) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -118,10 +116,10 @@ static inline void OPNAME ## _no_rnd_pixels16_l2_aligned2(uint8_t *dst, const ui static inline void OPNAME ## _pixels16_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do {\ - OP(LP(dst ),rnd_avg32(LD32(src1 ),LP(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(LD32(src1+4),LP(src2+4)) ); \ - OP(LP(dst+8),rnd_avg32(LD32(src1+8),LP(src2+8)) ); \ - OP(LP(dst+12),rnd_avg32(LD32(src1+12),LP(src2+12)) ); \ + OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),LP(src2 )) ); \ + OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),LP(src2+4)) ); \ + OP(LP(dst+8),rnd_avg32(AV_RN32(src1+8),LP(src2+8)) ); \ + OP(LP(dst+12),rnd_avg32(AV_RN32(src1+12),LP(src2+12)) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -131,8 +129,8 @@ static inline void OPNAME ## _pixels16_l2_aligned2(uint8_t *dst, const uint8_t * static inline void OPNAME ## _no_rnd_pixels8_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do { /* onlye src2 aligned */\ - OP(LP(dst ),no_rnd_avg32(LD32(src1 ),LP(src2 )) ); \ - OP(LP(dst+4),no_rnd_avg32(LD32(src1+4),LP(src2+4)) ); \ + OP(LP(dst ),no_rnd_avg32(AV_RN32(src1 ),LP(src2 )) ); \ + OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),LP(src2+4)) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -142,8 +140,8 @@ static inline void OPNAME ## _no_rnd_pixels8_l2_aligned2(uint8_t *dst, const uin static inline void OPNAME ## _pixels8_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \ {\ do {\ - OP(LP(dst ),rnd_avg32(LD32(src1 ),LP(src2 )) ); \ - OP(LP(dst+4),rnd_avg32(LD32(src1+4),LP(src2+4)) ); \ + OP(LP(dst ),rnd_avg32(AV_RN32(src1 ),LP(src2 )) ); \ + OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),LP(src2+4)) ); \ src1+=src_stride1; \ src2+=src_stride2; \ dst+=dst_stride; \ @@ -247,10 +245,10 @@ static inline void OPNAME ## _no_rnd_pixels8_l4_aligned(uint8_t *dst, const uint static inline void OPNAME ## _pixels8_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ do { \ uint32_t a0,a1,a2,a3; /* src1 only not aligned */\ - UNPACK(a0,a1,LD32(src1),LP(src2)); \ + UNPACK(a0,a1,AV_RN32(src1),LP(src2)); \ UNPACK(a2,a3,LP(src3),LP(src4)); \ OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LD32(src1+4),LP(src2+4)); \ + UNPACK(a0,a1,AV_RN32(src1+4),LP(src2+4)); \ UNPACK(a2,a3,LP(src3+4),LP(src4+4)); \ OP(LP(dst+4),rnd_PACK(a0,a1,a2,a3)); \ src1+=src_stride1;\ @@ -264,10 +262,10 @@ static inline void OPNAME ## _pixels8_l4_aligned0(uint8_t *dst, const uint8_t *s static inline void OPNAME ## _no_rnd_pixels8_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ do { \ uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LD32(src1),LP(src2)); \ + UNPACK(a0,a1,AV_RN32(src1),LP(src2)); \ UNPACK(a2,a3,LP(src3),LP(src4)); \ OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LD32(src1+4),LP(src2+4)); \ + UNPACK(a0,a1,AV_RN32(src1+4),LP(src2+4)); \ UNPACK(a2,a3,LP(src3+4),LP(src4+4)); \ OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ src1+=src_stride1;\ @@ -327,16 +325,16 @@ static inline void OPNAME ## _no_rnd_pixels16_l4_aligned(uint8_t *dst, const uin static inline void OPNAME ## _pixels16_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ do { /* src1 is unaligned */\ uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LD32(src1),LP(src2)); \ + UNPACK(a0,a1,AV_RN32(src1),LP(src2)); \ UNPACK(a2,a3,LP(src3),LP(src4)); \ OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LD32(src1+4),LP(src2+4)); \ + UNPACK(a0,a1,AV_RN32(src1+4),LP(src2+4)); \ UNPACK(a2,a3,LP(src3+4),LP(src4+4)); \ OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LD32(src1+8),LP(src2+8)); \ + UNPACK(a0,a1,AV_RN32(src1+8),LP(src2+8)); \ UNPACK(a2,a3,LP(src3+8),LP(src4+8)); \ OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LD32(src1+12),LP(src2+12)); \ + UNPACK(a0,a1,AV_RN32(src1+12),LP(src2+12)); \ UNPACK(a2,a3,LP(src3+12),LP(src4+12)); \ OP(LP(dst+12),rnd_PACK(a0,a1,a2,a3)); \ src1+=src_stride1;\ @@ -350,16 +348,16 @@ static inline void OPNAME ## _pixels16_l4_aligned0(uint8_t *dst, const uint8_t * static inline void OPNAME ## _no_rnd_pixels16_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ do { \ uint32_t a0,a1,a2,a3; \ - UNPACK(a0,a1,LD32(src1),LP(src2)); \ + UNPACK(a0,a1,AV_RN32(src1),LP(src2)); \ UNPACK(a2,a3,LP(src3),LP(src4)); \ OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LD32(src1+4),LP(src2+4)); \ + UNPACK(a0,a1,AV_RN32(src1+4),LP(src2+4)); \ UNPACK(a2,a3,LP(src3+4),LP(src4+4)); \ OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LD32(src1+8),LP(src2+8)); \ + UNPACK(a0,a1,AV_RN32(src1+8),LP(src2+8)); \ UNPACK(a2,a3,LP(src3+8),LP(src4+8)); \ OP(LP(dst+8),no_rnd_PACK(a0,a1,a2,a3)); \ - UNPACK(a0,a1,LD32(src1+12),LP(src2+12)); \ + UNPACK(a0,a1,AV_RN32(src1+12),LP(src2+12)); \ UNPACK(a2,a3,LP(src3+12),LP(src4+12)); \ OP(LP(dst+12),no_rnd_PACK(a0,a1,a2,a3)); \ src1+=src_stride1;\ @@ -449,19 +447,19 @@ static void gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + src[index+stride+1]* frac_x )* frac_y + r)>>(shift*2); }else{ - index= src_x + clip(src_y, 0, height)*stride; + index= src_x + av_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; + index= av_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; + index= av_clip(src_x, 0, width) + av_clip(src_y, 0, height)*stride; dst[y*stride + x]= src[index ]; } } diff --git a/contrib/ffmpeg/libavcodec/shorten.c b/contrib/ffmpeg/libavcodec/shorten.c index efb48b51d..36e0d0918 100644 --- a/contrib/ffmpeg/libavcodec/shorten.c +++ b/contrib/ffmpeg/libavcodec/shorten.c @@ -172,12 +172,12 @@ static void init_offset(ShortenContext *s) s->offset[chan][i] = mean; } -static int inline get_le32(GetBitContext *gb) +static inline int get_le32(GetBitContext *gb) { return bswap_32(get_bits_long(gb, 32)); } -static short inline get_le16(GetBitContext *gb) +static inline short get_le16(GetBitContext *gb) { return bswap_16(get_bits_long(gb, 16)); } @@ -268,7 +268,7 @@ static void decode_subframe_lpc(ShortenContext *s, int channel, int residual_siz static int shorten_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { ShortenContext *s = avctx->priv_data; int i, input_buf_size = 0; @@ -299,7 +299,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, } } init_get_bits(&s->gb, buf, buf_size*8); - get_bits(&s->gb, s->bitindex); + skip_bits(&s->gb, s->bitindex); if (!s->blocksize) { int maxnlpc = 0; @@ -345,7 +345,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, s->lpcqoffset = V2LPCQOFFSET; if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) { - av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at begining of stream\n"); + av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n"); return -1; } diff --git a/contrib/ffmpeg/libavcodec/simple_idct.c b/contrib/ffmpeg/libavcodec/simple_idct.c index dcf752e16..7bf0836aa 100644 --- a/contrib/ffmpeg/libavcodec/simple_idct.c +++ b/contrib/ffmpeg/libavcodec/simple_idct.c @@ -387,7 +387,7 @@ static inline void idctSparseCol (DCTELEM * col) col[56] = ((a0 - b0) >> COL_SHIFT); } -void simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block) +void ff_simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block) { int i; for(i=0; i<8; i++) @@ -397,7 +397,7 @@ void simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block) idctSparseColPut(dest + i, line_size, block + i); } -void simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block) +void ff_simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block) { int i; for(i=0; i<8; i++) @@ -407,7 +407,7 @@ void simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block) idctSparseColAdd(dest + i, line_size, block + i); } -void simple_idct(DCTELEM *block) +void ff_simple_idct(DCTELEM *block) { int i; for(i=0; i<8; i++) @@ -428,7 +428,7 @@ void simple_idct(DCTELEM *block) and the butterfly must be multiplied by 0.5 * sqrt(2.0) */ #define C_SHIFT (4+1+12) -static inline void idct4col(uint8_t *dest, int line_size, const DCTELEM *col) +static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col) { int c0, c1, c2, c3, a0, a1, a2, a3; const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; @@ -465,7 +465,7 @@ static inline void idct4col(uint8_t *dest, int line_size, const DCTELEM *col) /* XXX: I think a 1.0/sqrt(2) normalization should be needed to compensate the extra butterfly stage - I don't have the full DV specification */ -void simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block) +void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block) { int i; DCTELEM *ptr; @@ -491,8 +491,8 @@ void simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block) /* IDCT4 and store */ for(i=0;i<8;i++) { - idct4col(dest + i, 2 * line_size, block + i); - idct4col(dest + line_size + i, 2 * line_size, block + 8 + i); + idct4col_put(dest + i, 2 * line_size, block + i); + idct4col_put(dest + line_size + i, 2 * line_size, block + 8 + i); } } @@ -555,7 +555,7 @@ static inline void idct4row(DCTELEM *row) row[3]= (c0 - c1) >> R_SHIFT; } -void simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block) +void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block) { int i; @@ -570,7 +570,7 @@ void simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block) } } -void simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block) +void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block) { int i; @@ -585,3 +585,17 @@ void simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block) } } +void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + int i; + + /* IDCT4 on each line */ + for(i=0; i<4; i++) { + idct4row(block + i*8); + } + + /* IDCT4 and store */ + for(i=0; i<4; i++){ + idct4col_add(dest + i, line_size, block + i); + } +} diff --git a/contrib/ffmpeg/libavcodec/simple_idct.h b/contrib/ffmpeg/libavcodec/simple_idct.h index c4b453329..6ae48a24e 100644 --- a/contrib/ffmpeg/libavcodec/simple_idct.h +++ b/contrib/ffmpeg/libavcodec/simple_idct.h @@ -25,14 +25,23 @@ * simple idct header. */ -void simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block); -void simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block); +#ifndef FFMPEG_SIMPLE_IDCT_H +#define FFMPEG_SIMPLE_IDCT_H + +#include <stdint.h> +#include "dsputil.h" + +void ff_simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block); +void ff_simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block); void ff_simple_idct_mmx(int16_t *block); void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block); void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block); -void simple_idct(DCTELEM *block); +void ff_simple_idct(DCTELEM *block); + +void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block); -void simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block); +void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block); +void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block); +void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block); -void simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block); -void simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block); +#endif /* FFMPEG_SIMPLE_IDCT_H */ diff --git a/contrib/ffmpeg/libavcodec/smacker.c b/contrib/ffmpeg/libavcodec/smacker.c index 0dd76107b..d8639383d 100644 --- a/contrib/ffmpeg/libavcodec/smacker.c +++ b/contrib/ffmpeg/libavcodec/smacker.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -32,11 +31,11 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" #define ALT_BITSTREAM_READER_LE #include "bitstream.h" +#include "bytestream.h" #define SMKTREE_BITS 9 #define SMK_NODE 0x80000000 @@ -203,7 +202,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int if(get_bits1(gb)) { smacker_decode_tree(gb, &tmp1, 0, 0); - get_bits1(gb); + skip_bits1(gb); res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length, tmp1.lengths, sizeof(int), sizeof(int), tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); @@ -216,7 +215,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int } if(get_bits1(gb)){ smacker_decode_tree(gb, &tmp2, 0, 0); - get_bits1(gb); + skip_bits1(gb); res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length, tmp2.lengths, sizeof(int), sizeof(int), tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); @@ -252,7 +251,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int huff.values = av_mallocz(huff.length * sizeof(int)); smacker_decode_bigtree(gb, &huff, &ctx); - get_bits1(gb); + skip_bits1(gb); if(ctx.last[0] == -1) ctx.last[0] = huff.current++; if(ctx.last[1] == -1) ctx.last[1] = huff.current++; if(ctx.last[2] == -1) ctx.last[2] = huff.current++; @@ -292,7 +291,7 @@ static int decode_header_trees(SmackVContext *smk) { } else { smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size); } - if(!get_bits(&gb, 1)) { + if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n"); smk->mclr_tbl = av_malloc(sizeof(int) * 2); smk->mclr_tbl[0] = 0; @@ -300,7 +299,7 @@ static int decode_header_trees(SmackVContext *smk) { } else { smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size); } - if(!get_bits(&gb, 1)) { + if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n"); smk->full_tbl = av_malloc(sizeof(int) * 2); smk->full_tbl[0] = 0; @@ -308,7 +307,7 @@ static int decode_header_trees(SmackVContext *smk) { } else { smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size); } - if(!get_bits(&gb, 1)) { + if(!get_bits1(&gb)) { av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n"); smk->type_tbl = av_malloc(sizeof(int) * 2); smk->type_tbl[0] = 0; @@ -346,9 +345,9 @@ static av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *la return v; } -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { - SmackVContext * const smk = (SmackVContext *)avctx->priv_data; + SmackVContext * const smk = avctx->priv_data; uint8_t *out; uint32_t *pal; GetBitContext gb; @@ -356,7 +355,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 int i; int stride; - if(buf_size == 769) + if(buf_size <= 769) return 0; if(smk->pic.data[0]) avctx->release_buffer(avctx, &smk->pic); @@ -369,7 +368,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 } /* make the palette available on the way out */ - out = buf + 1; pal = (uint32_t*)smk->pic.data[1]; smk->pic.palette_has_changed = buf[0] & 1; smk->pic.key_frame = !!(buf[0] & 2); @@ -378,19 +376,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 else smk->pic.pict_type = FF_P_TYPE; - for(i = 0; i < 256; i++) { - int r, g, b; - r = *out++; - g = *out++; - b = *out++; - *pal++ = (r << 16) | (g << 8) | b; - } + buf++; + for(i = 0; i < 256; i++) + *pal++ = bytestream_get_be24(&buf); + buf_size -= 769; last_reset(smk->mmap_tbl, smk->mmap_last); last_reset(smk->mclr_tbl, smk->mclr_last); last_reset(smk->full_tbl, smk->full_last); last_reset(smk->type_tbl, smk->type_last); - init_get_bits(&gb, buf + 769, (buf_size - 769) * 8); + init_get_bits(&gb, buf, buf_size * 8); blk = 0; bw = avctx->width >> 2; @@ -437,11 +432,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 case 0: for(i = 0; i < 4; i++) { pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); - out[2] = pix & 0xFF; - out[3] = pix >> 8; + AV_WL16(out+2,pix); pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); - out[0] = pix & 0xFF; - out[1] = pix >> 8; + AV_WL16(out,pix); out += stride; } break; @@ -466,11 +459,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 uint16_t pix1, pix2; pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); - out[0] = pix1 & 0xFF; out[1] = pix1 >> 8; - out[2] = pix2 & 0xFF; out[3] = pix2 >> 8; + AV_WL16(out,pix1); + AV_WL16(out+2,pix2); out += stride; - out[0] = pix1 & 0xFF; out[1] = pix1 >> 8; - out[2] = pix2 & 0xFF; out[3] = pix2 >> 8; + AV_WL16(out,pix1); + AV_WL16(out+2,pix2); out += stride; } break; @@ -515,10 +508,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 */ static int decode_init(AVCodecContext *avctx) { - SmackVContext * const c = (SmackVContext *)avctx->priv_data; + SmackVContext * const c = avctx->priv_data; c->avctx = avctx; - avctx->has_b_frames = 0; c->pic.data[0] = NULL; @@ -550,7 +542,7 @@ static int decode_init(AVCodecContext *avctx) */ static int decode_end(AVCodecContext *avctx) { - SmackVContext * const smk = (SmackVContext *)avctx->priv_data; + SmackVContext * const smk = avctx->priv_data; av_freep(&smk->mmap_tbl); av_freep(&smk->mclr_tbl); @@ -572,7 +564,7 @@ static int smka_decode_init(AVCodecContext *avctx) /** * Decode Smacker audio data */ -static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { GetBitContext gb; HuffContext h[4]; @@ -595,6 +587,10 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } stereo = get_bits1(&gb); bits = get_bits1(&gb); + if (unp_size & 0xC0000000 || (unp_size << !bits) > *data_size) { + av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); + return -1; + } memset(vlc, 0, sizeof(VLC) * 4); memset(h, 0, sizeof(HuffContext) * 4); @@ -606,9 +602,9 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, h[i].bits = av_mallocz(256 * 4); h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); - get_bits1(&gb); + skip_bits1(&gb); smacker_decode_tree(&gb, &h[i], 0, 0); - get_bits1(&gb); + skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, h[i].lengths, sizeof(int), sizeof(int), diff --git a/contrib/ffmpeg/libavcodec/smc.c b/contrib/ffmpeg/libavcodec/smc.c index 349e5f81c..f181e0c4c 100644 --- a/contrib/ffmpeg/libavcodec/smc.c +++ b/contrib/ffmpeg/libavcodec/smc.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -34,7 +33,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -50,7 +48,7 @@ typedef struct SmcContext { DSPContext dsp; AVFrame frame; - unsigned char *buf; + const unsigned char *buf; int size; /* SMC color tables */ @@ -432,11 +430,10 @@ static void smc_decode_stream(SmcContext *s) static int smc_decode_init(AVCodecContext *avctx) { - SmcContext *s = (SmcContext *)avctx->priv_data; + SmcContext *s = avctx->priv_data; s->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; dsputil_init(&s->dsp, avctx); s->frame.data[0] = NULL; @@ -446,9 +443,9 @@ static int smc_decode_init(AVCodecContext *avctx) static int smc_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - SmcContext *s = (SmcContext *)avctx->priv_data; + SmcContext *s = avctx->priv_data; s->buf = buf; s->size = buf_size; @@ -472,7 +469,7 @@ static int smc_decode_frame(AVCodecContext *avctx, static int smc_decode_end(AVCodecContext *avctx) { - SmcContext *s = (SmcContext *)avctx->priv_data; + SmcContext *s = avctx->priv_data; if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); diff --git a/contrib/ffmpeg/libavcodec/snow.c b/contrib/ffmpeg/libavcodec/snow.c index dc50941fa..9fcb2d0ea 100644 --- a/contrib/ffmpeg/libavcodec/snow.c +++ b/contrib/ffmpeg/libavcodec/snow.c @@ -19,7 +19,6 @@ */ #include "avcodec.h" -#include "common.h" #include "dsputil.h" #include "snow.h" @@ -177,57 +176,57 @@ static const int8_t quant13[256]={ #if 0 //64*cubic static const uint8_t obmc32[1024]={ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 8, 8, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1, 0, 0, - 0, 0, 1, 2, 2, 3, 4, 6, 7, 8, 9,10,11,12,12,12,12,12,12,11,10, 9, 8, 7, 6, 4, 3, 2, 2, 1, 0, 0, - 0, 1, 1, 2, 3, 5, 6, 8,10,11,13,14,15,16,17,18,18,17,16,15,14,13,11,10, 8, 6, 5, 3, 2, 1, 1, 0, - 0, 1, 1, 3, 4, 6, 8,10,13,15,17,19,20,22,22,23,23,22,22,20,19,17,15,13,10, 8, 6, 4, 3, 1, 1, 0, - 0, 1, 2, 4, 6, 8,10,13,16,19,21,23,25,27,28,29,29,28,27,25,23,21,19,16,13,10, 8, 6, 4, 2, 1, 0, - 0, 1, 2, 4, 7,10,13,16,19,22,25,28,31,33,34,35,35,34,33,31,28,25,22,19,16,13,10, 7, 4, 2, 1, 0, - 0, 1, 3, 5, 8,11,15,19,22,26,30,33,36,38,40,41,41,40,38,36,33,30,26,22,19,15,11, 8, 5, 3, 1, 0, - 0, 1, 3, 6, 9,12,17,21,25,30,34,38,41,44,45,46,46,45,44,41,38,34,30,25,21,17,12, 9, 6, 3, 1, 0, - 0, 1, 3, 6,10,14,19,23,28,33,38,42,45,48,51,52,52,51,48,45,42,38,33,28,23,19,14,10, 6, 3, 1, 0, - 0, 1, 4, 7,11,15,20,25,31,36,41,45,49,52,55,56,56,55,52,49,45,41,36,31,25,20,15,11, 7, 4, 1, 0, - 0, 2, 4, 7,12,16,22,27,33,38,44,48,52,56,58,60,60,58,56,52,48,44,38,33,27,22,16,12, 7, 4, 2, 0, - 0, 1, 4, 8,12,17,22,28,34,40,45,51,55,58,61,62,62,61,58,55,51,45,40,34,28,22,17,12, 8, 4, 1, 0, - 0, 2, 4, 8,12,18,23,29,35,41,46,52,56,60,62,64,64,62,60,56,52,46,41,35,29,23,18,12, 8, 4, 2, 0, - 0, 2, 4, 8,12,18,23,29,35,41,46,52,56,60,62,64,64,62,60,56,52,46,41,35,29,23,18,12, 8, 4, 2, 0, - 0, 1, 4, 8,12,17,22,28,34,40,45,51,55,58,61,62,62,61,58,55,51,45,40,34,28,22,17,12, 8, 4, 1, 0, - 0, 2, 4, 7,12,16,22,27,33,38,44,48,52,56,58,60,60,58,56,52,48,44,38,33,27,22,16,12, 7, 4, 2, 0, - 0, 1, 4, 7,11,15,20,25,31,36,41,45,49,52,55,56,56,55,52,49,45,41,36,31,25,20,15,11, 7, 4, 1, 0, - 0, 1, 3, 6,10,14,19,23,28,33,38,42,45,48,51,52,52,51,48,45,42,38,33,28,23,19,14,10, 6, 3, 1, 0, - 0, 1, 3, 6, 9,12,17,21,25,30,34,38,41,44,45,46,46,45,44,41,38,34,30,25,21,17,12, 9, 6, 3, 1, 0, - 0, 1, 3, 5, 8,11,15,19,22,26,30,33,36,38,40,41,41,40,38,36,33,30,26,22,19,15,11, 8, 5, 3, 1, 0, - 0, 1, 2, 4, 7,10,13,16,19,22,25,28,31,33,34,35,35,34,33,31,28,25,22,19,16,13,10, 7, 4, 2, 1, 0, - 0, 1, 2, 4, 6, 8,10,13,16,19,21,23,25,27,28,29,29,28,27,25,23,21,19,16,13,10, 8, 6, 4, 2, 1, 0, - 0, 1, 1, 3, 4, 6, 8,10,13,15,17,19,20,22,22,23,23,22,22,20,19,17,15,13,10, 8, 6, 4, 3, 1, 1, 0, - 0, 1, 1, 2, 3, 5, 6, 8,10,11,13,14,15,16,17,18,18,17,16,15,14,13,11,10, 8, 6, 5, 3, 2, 1, 1, 0, - 0, 0, 1, 2, 2, 3, 4, 6, 7, 8, 9,10,11,12,12,12,12,12,12,11,10, 9, 8, 7, 6, 4, 3, 2, 2, 1, 0, 0, - 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 8, 8, 7, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 4, 4, 8, 8, 12, 16, 16, 20, 24, 24, 28, 28, 32, 32, 32, 32, 28, 28, 24, 24, 20, 16, 16, 12, 8, 8, 4, 4, 0, 0, + 0, 0, 4, 8, 8, 12, 16, 24, 28, 32, 36, 40, 44, 48, 48, 48, 48, 48, 48, 44, 40, 36, 32, 28, 24, 16, 12, 8, 8, 4, 0, 0, + 0, 4, 4, 8, 12, 20, 24, 32, 40, 44, 52, 56, 60, 64, 68, 72, 72, 68, 64, 60, 56, 52, 44, 40, 32, 24, 20, 12, 8, 4, 4, 0, + 0, 4, 4, 12, 16, 24, 32, 40, 52, 60, 68, 76, 80, 88, 88, 92, 92, 88, 88, 80, 76, 68, 60, 52, 40, 32, 24, 16, 12, 4, 4, 0, + 0, 4, 8, 16, 24, 32, 40, 52, 64, 76, 84, 92,100,108,112,116,116,112,108,100, 92, 84, 76, 64, 52, 40, 32, 24, 16, 8, 4, 0, + 0, 4, 8, 16, 28, 40, 52, 64, 76, 88,100,112,124,132,136,140,140,136,132,124,112,100, 88, 76, 64, 52, 40, 28, 16, 8, 4, 0, + 0, 4, 12, 20, 32, 44, 60, 76, 88,104,120,132,144,152,160,164,164,160,152,144,132,120,104, 88, 76, 60, 44, 32, 20, 12, 4, 0, + 0, 4, 12, 24, 36, 48, 68, 84,100,120,136,152,164,176,180,184,184,180,176,164,152,136,120,100, 84, 68, 48, 36, 24, 12, 4, 0, + 0, 4, 12, 24, 40, 56, 76, 92,112,132,152,168,180,192,204,208,208,204,192,180,168,152,132,112, 92, 76, 56, 40, 24, 12, 4, 0, + 0, 4, 16, 28, 44, 60, 80,100,124,144,164,180,196,208,220,224,224,220,208,196,180,164,144,124,100, 80, 60, 44, 28, 16, 4, 0, + 0, 8, 16, 28, 48, 64, 88,108,132,152,176,192,208,224,232,240,240,232,224,208,192,176,152,132,108, 88, 64, 48, 28, 16, 8, 0, + 0, 4, 16, 32, 48, 68, 88,112,136,160,180,204,220,232,244,248,248,244,232,220,204,180,160,136,112, 88, 68, 48, 32, 16, 4, 0, + 1, 8, 16, 32, 48, 72, 92,116,140,164,184,208,224,240,248,255,255,248,240,224,208,184,164,140,116, 92, 72, 48, 32, 16, 8, 1, + 1, 8, 16, 32, 48, 72, 92,116,140,164,184,208,224,240,248,255,255,248,240,224,208,184,164,140,116, 92, 72, 48, 32, 16, 8, 1, + 0, 4, 16, 32, 48, 68, 88,112,136,160,180,204,220,232,244,248,248,244,232,220,204,180,160,136,112, 88, 68, 48, 32, 16, 4, 0, + 0, 8, 16, 28, 48, 64, 88,108,132,152,176,192,208,224,232,240,240,232,224,208,192,176,152,132,108, 88, 64, 48, 28, 16, 8, 0, + 0, 4, 16, 28, 44, 60, 80,100,124,144,164,180,196,208,220,224,224,220,208,196,180,164,144,124,100, 80, 60, 44, 28, 16, 4, 0, + 0, 4, 12, 24, 40, 56, 76, 92,112,132,152,168,180,192,204,208,208,204,192,180,168,152,132,112, 92, 76, 56, 40, 24, 12, 4, 0, + 0, 4, 12, 24, 36, 48, 68, 84,100,120,136,152,164,176,180,184,184,180,176,164,152,136,120,100, 84, 68, 48, 36, 24, 12, 4, 0, + 0, 4, 12, 20, 32, 44, 60, 76, 88,104,120,132,144,152,160,164,164,160,152,144,132,120,104, 88, 76, 60, 44, 32, 20, 12, 4, 0, + 0, 4, 8, 16, 28, 40, 52, 64, 76, 88,100,112,124,132,136,140,140,136,132,124,112,100, 88, 76, 64, 52, 40, 28, 16, 8, 4, 0, + 0, 4, 8, 16, 24, 32, 40, 52, 64, 76, 84, 92,100,108,112,116,116,112,108,100, 92, 84, 76, 64, 52, 40, 32, 24, 16, 8, 4, 0, + 0, 4, 4, 12, 16, 24, 32, 40, 52, 60, 68, 76, 80, 88, 88, 92, 92, 88, 88, 80, 76, 68, 60, 52, 40, 32, 24, 16, 12, 4, 4, 0, + 0, 4, 4, 8, 12, 20, 24, 32, 40, 44, 52, 56, 60, 64, 68, 72, 72, 68, 64, 60, 56, 52, 44, 40, 32, 24, 20, 12, 8, 4, 4, 0, + 0, 0, 4, 8, 8, 12, 16, 24, 28, 32, 36, 40, 44, 48, 48, 48, 48, 48, 48, 44, 40, 36, 32, 28, 24, 16, 12, 8, 8, 4, 0, 0, + 0, 0, 4, 4, 8, 8, 12, 16, 16, 20, 24, 24, 28, 28, 32, 32, 32, 32, 28, 28, 24, 24, 20, 16, 16, 12, 8, 8, 4, 4, 0, 0, + 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, 16, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //error:0.000022 }; static const uint8_t obmc16[256]={ - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 2, 4, 5, 5, 6, 6, 5, 5, 4, 2, 1, 1, 0, - 0, 1, 4, 6, 9,11,13,15,15,13,11, 9, 6, 4, 1, 0, - 0, 2, 6,11,15,20,24,26,26,24,20,15,11, 6, 2, 0, - 0, 4, 9,15,23,29,34,38,38,34,29,23,15, 9, 4, 0, - 0, 5,11,20,29,38,45,49,49,45,38,29,20,11, 5, 0, - 1, 5,13,24,34,45,53,57,57,53,45,34,24,13, 5, 1, - 1, 6,15,26,38,49,57,62,62,57,49,38,26,15, 6, 1, - 1, 6,15,26,38,49,57,62,62,57,49,38,26,15, 6, 1, - 1, 5,13,24,34,45,53,57,57,53,45,34,24,13, 5, 1, - 0, 5,11,20,29,38,45,49,49,45,38,29,20,11, 5, 0, - 0, 4, 9,15,23,29,34,38,38,34,29,23,15, 9, 4, 0, - 0, 2, 6,11,15,20,24,26,26,24,20,15,11, 6, 2, 0, - 0, 1, 4, 6, 9,11,13,15,15,13,11, 9, 6, 4, 1, 0, - 0, 1, 1, 2, 4, 5, 5, 6, 6, 5, 5, 4, 2, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 4, 4, 8, 16, 20, 20, 24, 24, 20, 20, 16, 8, 4, 4, 0, + 0, 4, 16, 24, 36, 44, 52, 60, 60, 52, 44, 36, 24, 16, 4, 0, + 0, 8, 24, 44, 60, 80, 96,104,104, 96, 80, 60, 44, 24, 8, 0, + 0, 16, 36, 60, 92,116,136,152,152,136,116, 92, 60, 36, 16, 0, + 0, 20, 44, 80,116,152,180,196,196,180,152,116, 80, 44, 20, 0, + 4, 20, 52, 96,136,180,212,228,228,212,180,136, 96, 52, 20, 4, + 4, 24, 60,104,152,196,228,248,248,228,196,152,104, 60, 24, 4, + 4, 24, 60,104,152,196,228,248,248,228,196,152,104, 60, 24, 4, + 4, 20, 52, 96,136,180,212,228,228,212,180,136, 96, 52, 20, 4, + 0, 20, 44, 80,116,152,180,196,196,180,152,116, 80, 44, 20, 0, + 0, 16, 36, 60, 92,116,136,152,152,136,116, 92, 60, 36, 16, 0, + 0, 8, 24, 44, 60, 80, 96,104,104, 96, 80, 60, 44, 24, 8, 0, + 0, 4, 16, 24, 36, 44, 52, 60, 60, 52, 44, 36, 24, 16, 4, 0, + 0, 4, 4, 8, 16, 20, 20, 24, 24, 20, 20, 16, 8, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, //error:0.000033 }; #elif 1 // 64*linear @@ -287,60 +286,60 @@ static const uint8_t obmc16[256]={ }; #else //64*cos static const uint8_t obmc32[1024]={ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, - 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 9,10,11,11,12,12,12,12,11,11,10, 9, 7, 6, 5, 4, 3, 2, 1, 1, 0, 0, - 0, 0, 1, 2, 3, 5, 6, 8, 9,11,12,14,15,16,17,17,17,17,16,15,14,12,11, 9, 8, 6, 5, 3, 2, 1, 0, 0, - 0, 1, 1, 2, 4, 6, 8,10,12,15,17,19,20,21,22,23,23,22,21,20,19,17,15,12,10, 8, 6, 4, 2, 1, 1, 0, - 0, 1, 2, 3, 5, 8,10,13,16,19,21,24,26,27,28,29,29,28,27,26,24,21,19,16,13,10, 8, 5, 3, 2, 1, 0, - 0, 1, 2, 4, 6, 9,12,16,19,23,26,29,31,33,34,35,35,34,33,31,29,26,23,19,16,12, 9, 6, 4, 2, 1, 0, - 0, 1, 3, 5, 7,11,15,19,23,26,30,34,37,39,40,41,41,40,39,37,34,30,26,23,19,15,11, 7, 5, 3, 1, 0, - 0, 1, 3, 5, 9,12,17,21,26,30,35,38,42,44,46,47,47,46,44,42,38,35,30,26,21,17,12, 9, 5, 3, 1, 0, - 0, 1, 3, 6, 9,14,19,24,29,34,38,43,46,49,51,52,52,51,49,46,43,38,34,29,24,19,14, 9, 6, 3, 1, 0, - 0, 1, 3, 6,11,15,20,26,31,37,42,46,50,53,56,57,57,56,53,50,46,42,37,31,26,20,15,11, 6, 3, 1, 0, - 0, 1, 3, 7,11,16,21,27,33,39,44,49,53,57,59,60,60,59,57,53,49,44,39,33,27,21,16,11, 7, 3, 1, 0, - 0, 1, 4, 7,12,17,22,28,34,40,46,51,56,59,61,63,63,61,59,56,51,46,40,34,28,22,17,12, 7, 4, 1, 0, - 0, 1, 4, 7,12,17,23,29,35,41,47,52,57,60,63,64,64,63,60,57,52,47,41,35,29,23,17,12, 7, 4, 1, 0, - 0, 1, 4, 7,12,17,23,29,35,41,47,52,57,60,63,64,64,63,60,57,52,47,41,35,29,23,17,12, 7, 4, 1, 0, - 0, 1, 4, 7,12,17,22,28,34,40,46,51,56,59,61,63,63,61,59,56,51,46,40,34,28,22,17,12, 7, 4, 1, 0, - 0, 1, 3, 7,11,16,21,27,33,39,44,49,53,57,59,60,60,59,57,53,49,44,39,33,27,21,16,11, 7, 3, 1, 0, - 0, 1, 3, 6,11,15,20,26,31,37,42,46,50,53,56,57,57,56,53,50,46,42,37,31,26,20,15,11, 6, 3, 1, 0, - 0, 1, 3, 6, 9,14,19,24,29,34,38,43,46,49,51,52,52,51,49,46,43,38,34,29,24,19,14, 9, 6, 3, 1, 0, - 0, 1, 3, 5, 9,12,17,21,26,30,35,38,42,44,46,47,47,46,44,42,38,35,30,26,21,17,12, 9, 5, 3, 1, 0, - 0, 1, 3, 5, 7,11,15,19,23,26,30,34,37,39,40,41,41,40,39,37,34,30,26,23,19,15,11, 7, 5, 3, 1, 0, - 0, 1, 2, 4, 6, 9,12,16,19,23,26,29,31,33,34,35,35,34,33,31,29,26,23,19,16,12, 9, 6, 4, 2, 1, 0, - 0, 1, 2, 3, 5, 8,10,13,16,19,21,24,26,27,28,29,29,28,27,26,24,21,19,16,13,10, 8, 5, 3, 2, 1, 0, - 0, 1, 1, 2, 4, 6, 8,10,12,15,17,19,20,21,22,23,23,22,21,20,19,17,15,12,10, 8, 6, 4, 2, 1, 1, 0, - 0, 0, 1, 2, 3, 5, 6, 8, 9,11,12,14,15,16,17,17,17,17,16,15,14,12,11, 9, 8, 6, 5, 3, 2, 1, 0, 0, - 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 9,10,11,11,12,12,12,12,11,11,10, 9, 7, 6, 5, 4, 3, 2, 1, 1, 0, 0, - 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 4, 4, 4, 8, 8, 12, 16, 20, 20, 24, 28, 28, 28, 28, 28, 28, 28, 28, 24, 20, 20, 16, 12, 8, 8, 4, 4, 4, 0, 0, + 0, 0, 4, 4, 8, 12, 16, 20, 24, 28, 36, 40, 44, 44, 48, 48, 48, 48, 44, 44, 40, 36, 28, 24, 20, 16, 12, 8, 4, 4, 0, 0, + 0, 0, 4, 8, 12, 20, 24, 32, 36, 44, 48, 56, 60, 64, 68, 68, 68, 68, 64, 60, 56, 48, 44, 36, 32, 24, 20, 12, 8, 4, 0, 0, + 0, 4, 4, 8, 16, 24, 32, 40, 48, 60, 68, 76, 80, 84, 88, 92, 92, 88, 84, 80, 76, 68, 60, 48, 40, 32, 24, 16, 8, 4, 4, 0, + 0, 4, 8, 12, 20, 32, 40, 52, 64, 76, 84, 96,104,108,112,116,116,112,108,104, 96, 84, 76, 64, 52, 40, 32, 20, 12, 8, 4, 0, + 0, 4, 8, 16, 24, 36, 48, 64, 76, 92,104,116,124,132,136,140,140,136,132,124,116,104, 92, 76, 64, 48, 36, 24, 16, 8, 4, 0, + 0, 4, 12, 20, 28, 44, 60, 76, 92,104,120,136,148,156,160,164,164,160,156,148,136,120,104, 92, 76, 60, 44, 28, 20, 12, 4, 0, + 0, 4, 12, 20, 36, 48, 68, 84,104,120,140,152,168,176,184,188,188,184,176,168,152,140,120,104, 84, 68, 48, 36, 20, 12, 4, 0, + 0, 4, 12, 24, 36, 56, 76, 96,116,136,152,172,184,196,204,208,208,204,196,184,172,152,136,116, 96, 76, 56, 36, 24, 12, 4, 0, + 0, 4, 12, 24, 44, 60, 80,104,124,148,168,184,200,212,224,228,228,224,212,200,184,168,148,124,104, 80, 60, 44, 24, 12, 4, 0, + 0, 4, 12, 28, 44, 64, 84,108,132,156,176,196,212,228,236,240,240,236,228,212,196,176,156,132,108, 84, 64, 44, 28, 12, 4, 0, + 0, 4, 16, 28, 48, 68, 88,112,136,160,184,204,224,236,244,252,252,244,236,224,204,184,160,136,112, 88, 68, 48, 28, 16, 4, 0, + 1, 4, 16, 28, 48, 68, 92,116,140,164,188,208,228,240,252,255,255,252,240,228,208,188,164,140,116, 92, 68, 48, 28, 16, 4, 1, + 1, 4, 16, 28, 48, 68, 92,116,140,164,188,208,228,240,252,255,255,252,240,228,208,188,164,140,116, 92, 68, 48, 28, 16, 4, 1, + 0, 4, 16, 28, 48, 68, 88,112,136,160,184,204,224,236,244,252,252,244,236,224,204,184,160,136,112, 88, 68, 48, 28, 16, 4, 0, + 0, 4, 12, 28, 44, 64, 84,108,132,156,176,196,212,228,236,240,240,236,228,212,196,176,156,132,108, 84, 64, 44, 28, 12, 4, 0, + 0, 4, 12, 24, 44, 60, 80,104,124,148,168,184,200,212,224,228,228,224,212,200,184,168,148,124,104, 80, 60, 44, 24, 12, 4, 0, + 0, 4, 12, 24, 36, 56, 76, 96,116,136,152,172,184,196,204,208,208,204,196,184,172,152,136,116, 96, 76, 56, 36, 24, 12, 4, 0, + 0, 4, 12, 20, 36, 48, 68, 84,104,120,140,152,168,176,184,188,188,184,176,168,152,140,120,104, 84, 68, 48, 36, 20, 12, 4, 0, + 0, 4, 12, 20, 28, 44, 60, 76, 92,104,120,136,148,156,160,164,164,160,156,148,136,120,104, 92, 76, 60, 44, 28, 20, 12, 4, 0, + 0, 4, 8, 16, 24, 36, 48, 64, 76, 92,104,116,124,132,136,140,140,136,132,124,116,104, 92, 76, 64, 48, 36, 24, 16, 8, 4, 0, + 0, 4, 8, 12, 20, 32, 40, 52, 64, 76, 84, 96,104,108,112,116,116,112,108,104, 96, 84, 76, 64, 52, 40, 32, 20, 12, 8, 4, 0, + 0, 4, 4, 8, 16, 24, 32, 40, 48, 60, 68, 76, 80, 84, 88, 92, 92, 88, 84, 80, 76, 68, 60, 48, 40, 32, 24, 16, 8, 4, 4, 0, + 0, 0, 4, 8, 12, 20, 24, 32, 36, 44, 48, 56, 60, 64, 68, 68, 68, 68, 64, 60, 56, 48, 44, 36, 32, 24, 20, 12, 8, 4, 0, 0, + 0, 0, 4, 4, 8, 12, 16, 20, 24, 28, 36, 40, 44, 44, 48, 48, 48, 48, 44, 44, 40, 36, 28, 24, 20, 16, 12, 8, 4, 4, 0, 0, + 0, 0, 4, 4, 4, 8, 8, 12, 16, 20, 20, 24, 28, 28, 28, 28, 28, 28, 28, 28, 24, 20, 20, 16, 12, 8, 8, 4, 4, 4, 0, 0, + 0, 0, 0, 4, 4, 4, 4, 8, 8, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 12, 12, 12, 12, 8, 8, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //error:0.000022 }; static const uint8_t obmc16[256]={ - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 5, 5, 5, 4, 3, 2, 1, 0, 0, - 0, 1, 3, 6, 8,11,13,14,14,13,11, 8, 6, 3, 1, 0, - 0, 2, 6,10,15,20,24,26,26,24,20,15,10, 6, 2, 0, - 0, 3, 8,16,23,30,35,38,38,35,30,23,16, 8, 3, 0, - 1, 4,11,20,30,39,46,49,49,46,39,30,20,11, 4, 1, - 1, 5,13,24,35,46,54,58,58,54,46,35,24,13, 5, 1, - 0, 5,14,26,38,49,58,63,63,58,49,38,26,14, 5, 0, - 0, 5,14,26,38,49,58,63,63,58,49,38,26,14, 5, 0, - 1, 5,13,24,35,46,54,58,58,54,46,35,24,13, 5, 1, - 1, 4,11,20,30,39,46,49,49,46,39,30,20,11, 4, 1, - 0, 3, 8,16,23,30,35,38,38,35,30,23,16, 8, 3, 0, - 0, 2, 6,10,15,20,24,26,26,24,20,15,10, 6, 2, 0, - 0, 1, 3, 6, 8,11,13,14,14,13,11, 8, 6, 3, 1, 0, - 0, 0, 1, 2, 3, 4, 5, 5, 5, 5, 4, 3, 2, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, + 0, 0, 4, 8, 12, 16, 20, 20, 20, 20, 16, 12, 8, 4, 0, 0, + 0, 4, 12, 24, 32, 44, 52, 56, 56, 52, 44, 32, 24, 12, 4, 0, + 0, 8, 24, 40, 60, 80, 96,104,104, 96, 80, 60, 40, 24, 8, 0, + 0, 12, 32, 64, 92,120,140,152,152,140,120, 92, 64, 32, 12, 0, + 4, 16, 44, 80,120,156,184,196,196,184,156,120, 80, 44, 16, 4, + 4, 20, 52, 96,140,184,216,232,232,216,184,140, 96, 52, 20, 4, + 0, 20, 56,104,152,196,232,252,252,232,196,152,104, 56, 20, 0, + 0, 20, 56,104,152,196,232,252,252,232,196,152,104, 56, 20, 0, + 4, 20, 52, 96,140,184,216,232,232,216,184,140, 96, 52, 20, 4, + 4, 16, 44, 80,120,156,184,196,196,184,156,120, 80, 44, 16, 4, + 0, 12, 32, 64, 92,120,140,152,152,140,120, 92, 64, 32, 12, 0, + 0, 8, 24, 40, 60, 80, 96,104,104, 96, 80, 60, 40, 24, 8, 0, + 0, 4, 12, 24, 32, 44, 52, 56, 56, 52, 44, 32, 24, 12, 4, 0, + 0, 0, 4, 8, 12, 16, 20, 20, 20, 20, 16, 12, 8, 4, 0, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, //error:0.000022 }; -#endif +#endif /* 0 */ //linear *64 static const uint8_t obmc8[64]={ @@ -394,6 +393,8 @@ static const BlockNode null_block= { //FIXME add border maybe #define LOG2_MB_SIZE 4 #define MB_SIZE (1<<LOG2_MB_SIZE) +#define ENCODER_EXTRA_BITS 4 +#define HTAPS_MAX 8 typedef struct x_and_coeff{ int16_t x; @@ -405,8 +406,9 @@ typedef struct SubBand{ int stride; int width; int height; - int qlog; ///< log(qscale)/log[2^(1/6)] + int qlog; ///< log(qscale)/log[2^(1/6)] DWTELEM *buf; + IDWTELEM *ibuf; int buf_x_offset; int buf_y_offset; int stride_line; ///< Stride measured in lines, not pixels. @@ -419,10 +421,19 @@ typedef struct Plane{ int width; int height; SubBand band[MAX_DECOMPOSITIONS][4]; + + int htaps; + int8_t hcoeff[HTAPS_MAX/2]; + int diag_mc; + int fast_mc; + + int last_htaps; + int8_t last_hcoeff[HTAPS_MAX/2]; + int last_diag_mc; }Plane; typedef struct SnowContext{ -// MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independent of MpegEncContext, so this will be removed then (FIXME/XXX) +// MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX) AVCodecContext *avctx; RangeCoder c; @@ -431,6 +442,7 @@ typedef struct SnowContext{ AVFrame input_picture; ///< new_picture with the internal linesizes AVFrame current_picture; AVFrame last_picture[MAX_REF_FRAMES]; + uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4]; AVFrame mconly_picture; // uint8_t q_context[16]; uint8_t header_state[32]; @@ -442,12 +454,14 @@ typedef struct SnowContext{ int last_spatial_decomposition_type; int temporal_decomposition_type; int spatial_decomposition_count; + int last_spatial_decomposition_count; int temporal_decomposition_count; int max_ref_frames; int ref_frames; int16_t (*ref_mvs[MAX_REF_FRAMES])[2]; uint32_t *ref_scores[MAX_REF_FRAMES]; DWTELEM *spatial_dwt_buffer; + IDWTELEM *spatial_idwt_buffer; int colorspace_type; int chroma_h_shift; int chroma_v_shift; @@ -473,14 +487,14 @@ typedef struct SnowContext{ int me_cache_generation; slice_buffer sb; - MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independent of MpegEncContext, so this will be removed then (FIXME/XXX) + MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX) }SnowContext; typedef struct { - DWTELEM *b0; - DWTELEM *b1; - DWTELEM *b2; - DWTELEM *b3; + IDWTELEM *b0; + IDWTELEM *b1; + IDWTELEM *b2; + IDWTELEM *b3; int y; } dwt_compose_t; @@ -489,7 +503,7 @@ typedef struct { static void iterative_me(SnowContext *s); -static void slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, DWTELEM * base_buffer) +static void slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, IDWTELEM * base_buffer) { int i; @@ -497,23 +511,21 @@ static void slice_buffer_init(slice_buffer * buf, int line_count, int max_alloca buf->line_count = line_count; buf->line_width = line_width; buf->data_count = max_allocated_lines; - buf->line = (DWTELEM * *) av_mallocz (sizeof(DWTELEM *) * line_count); - buf->data_stack = (DWTELEM * *) av_malloc (sizeof(DWTELEM *) * max_allocated_lines); + buf->line = av_mallocz (sizeof(IDWTELEM *) * line_count); + buf->data_stack = av_malloc (sizeof(IDWTELEM *) * max_allocated_lines); for (i = 0; i < max_allocated_lines; i++) { - buf->data_stack[i] = (DWTELEM *) av_malloc (sizeof(DWTELEM) * line_width); + buf->data_stack[i] = av_malloc (sizeof(IDWTELEM) * line_width); } buf->data_stack_top = max_allocated_lines - 1; } -static DWTELEM * slice_buffer_load_line(slice_buffer * buf, int line) +static IDWTELEM * slice_buffer_load_line(slice_buffer * buf, int line) { int offset; - DWTELEM * buffer; - -// av_log(NULL, AV_LOG_DEBUG, "Cache hit: %d\n", line); + IDWTELEM * buffer; assert(buf->data_stack_top >= 0); // assert(!buf->line[line]); @@ -525,15 +537,13 @@ static DWTELEM * slice_buffer_load_line(slice_buffer * buf, int line) buf->data_stack_top--; buf->line[line] = buffer; -// av_log(NULL, AV_LOG_DEBUG, "slice_buffer_load_line: line: %d remaining: %d\n", line, buf->data_stack_top + 1); - return buffer; } static void slice_buffer_release(slice_buffer * buf, int line) { int offset; - DWTELEM * buffer; + IDWTELEM * buffer; assert(line >= 0 && line < buf->line_count); assert(buf->line[line]); @@ -543,8 +553,6 @@ static void slice_buffer_release(slice_buffer * buf, int line) buf->data_stack_top++; buf->data_stack[buf->data_stack_top] = buffer; buf->line[line] = NULL; - -// av_log(NULL, AV_LOG_DEBUG, "slice_buffer_release: line: %d remaining: %d\n", line, buf->data_stack_top + 1); } static void slice_buffer_flush(slice_buffer * buf) @@ -553,10 +561,7 @@ static void slice_buffer_flush(slice_buffer * buf) for (i = 0; i < buf->line_count; i++) { if (buf->line[i]) - { -// av_log(NULL, AV_LOG_DEBUG, "slice_buffer_flush: line: %d \n", i); slice_buffer_release(buf, i); - } } } @@ -567,12 +572,9 @@ static void slice_buffer_destroy(slice_buffer * buf) for (i = buf->data_count - 1; i >= 0; i--) { - assert(buf->data_stack[i]); av_freep(&buf->data_stack[i]); } - assert(buf->data_stack); av_freep(&buf->data_stack); - assert(buf->line); av_freep(&buf->line); } @@ -646,7 +648,7 @@ static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signe if(is_signed) put_rac(c, state+11 + FFMIN(e,10), v < 0); //11..21 } -#endif +#endif /* 1 */ }else{ put_rac(c, state+0, 1); } @@ -714,7 +716,11 @@ static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){ return v; } -static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){ +static av_always_inline void +lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, + int dst_step, int src_step, int ref_step, + int width, int mul, int add, int shift, + int highpass, int inverse){ const int mirror_left= !highpass; const int mirror_right= (width&1) ^ highpass; const int w= (width>>1) - 1 + (highpass & width); @@ -728,55 +734,68 @@ static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int } for(i=0; i<w; i++){ - dst[i*dst_step] = LIFT(src[i*src_step], ((mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add)>>shift), inverse); + dst[i*dst_step] = + LIFT(src[i*src_step], + ((mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add)>>shift), + inverse); } if(mirror_right){ - dst[w*dst_step] = LIFT(src[w*src_step], ((mul*2*ref[w*ref_step]+add)>>shift), inverse); + dst[w*dst_step] = + LIFT(src[w*src_step], + ((mul*2*ref[w*ref_step]+add)>>shift), + inverse); } } -#ifndef lift5 -static av_always_inline void lift5(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){ +static av_always_inline void +inv_lift(IDWTELEM *dst, IDWTELEM *src, IDWTELEM *ref, + int dst_step, int src_step, int ref_step, + int width, int mul, int add, int shift, + int highpass, int inverse){ const int mirror_left= !highpass; const int mirror_right= (width&1) ^ highpass; const int w= (width>>1) - 1 + (highpass & width); int i; +#define LIFT(src, ref, inv) ((src) + ((inv) ? - (ref) : + (ref))) if(mirror_left){ - int r= 3*2*ref[0]; - r += r>>4; - r += r>>8; - dst[0] = LIFT(src[0], ((r+add)>>shift), inverse); + dst[0] = LIFT(src[0], ((mul*2*ref[0]+add)>>shift), inverse); dst += dst_step; src += src_step; } for(i=0; i<w; i++){ - int r= 3*(ref[i*ref_step] + ref[(i+1)*ref_step]); - r += r>>4; - r += r>>8; - dst[i*dst_step] = LIFT(src[i*src_step], ((r+add)>>shift), inverse); + dst[i*dst_step] = + LIFT(src[i*src_step], + ((mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add)>>shift), + inverse); } if(mirror_right){ - int r= 3*2*ref[w*ref_step]; - r += r>>4; - r += r>>8; - dst[w*dst_step] = LIFT(src[w*src_step], ((r+add)>>shift), inverse); + dst[w*dst_step] = + LIFT(src[w*src_step], + ((mul*2*ref[w*ref_step]+add)>>shift), + inverse); } } -#endif #ifndef liftS -static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){ +static av_always_inline void +liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, + int dst_step, int src_step, int ref_step, + int width, int mul, int add, int shift, + int highpass, int inverse){ const int mirror_left= !highpass; const int mirror_right= (width&1) ^ highpass; const int w= (width>>1) - 1 + (highpass & width); int i; assert(shift == 4); -#define LIFTS(src, ref, inv) ((inv) ? (src) - (((ref) - 4*(src))>>shift): (16*4*(src) + 4*(ref) + 8 + (5<<27))/(5*16) - (1<<23)) +#define LIFTS(src, ref, inv) \ + ((inv) ? \ + (src) + (((ref) + 4*(src))>>shift): \ + -((-16*(src) + (ref) + add/4 + 1 + (5<<25))/(5*4) - (1<<23))) if(mirror_left){ dst[0] = LIFTS(src[0], mul*2*ref[0]+add, inverse); dst += dst_step; @@ -784,242 +803,51 @@ static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int } for(i=0; i<w; i++){ - dst[i*dst_step] = LIFTS(src[i*src_step], mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add, inverse); + dst[i*dst_step] = + LIFTS(src[i*src_step], + mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add, + inverse); } if(mirror_right){ - dst[w*dst_step] = LIFTS(src[w*src_step], mul*2*ref[w*ref_step]+add, inverse); + dst[w*dst_step] = + LIFTS(src[w*src_step], mul*2*ref[w*ref_step]+add, inverse); } } -#endif - - -static void inplace_lift(DWTELEM *dst, int width, int *coeffs, int n, int shift, int start, int inverse){ - int x, i; - - for(x=start; x<width; x+=2){ - int64_t sum=0; - - for(i=0; i<n; i++){ - int x2= x + 2*i - n + 1; - if (x2< 0) x2= -x2; - else if(x2>=width) x2= 2*width-x2-2; - sum += coeffs[i]*(int64_t)dst[x2]; - } - if(inverse) dst[x] -= (sum + (1<<shift)/2)>>shift; - else dst[x] += (sum + (1<<shift)/2)>>shift; - } -} - -static void inplace_liftV(DWTELEM *dst, int width, int height, int stride, int *coeffs, int n, int shift, int start, int inverse){ - int x, y, i; - for(y=start; y<height; y+=2){ - for(x=0; x<width; x++){ - int64_t sum=0; - - for(i=0; i<n; i++){ - int y2= y + 2*i - n + 1; - if (y2< 0) y2= -y2; - else if(y2>=height) y2= 2*height-y2-2; - sum += coeffs[i]*(int64_t)dst[x + y2*stride]; - } - if(inverse) dst[x + y*stride] -= (sum + (1<<shift)/2)>>shift; - else dst[x + y*stride] += (sum + (1<<shift)/2)>>shift; - } - } -} - -#define SCALEX 1 -#define LX0 0 -#define LX1 1 - -#if 0 // more accurate 9/7 -#define N1 2 -#define SHIFT1 14 -#define COEFFS1 (int[]){-25987,-25987} -#define N2 2 -#define SHIFT2 19 -#define COEFFS2 (int[]){-27777,-27777} -#define N3 2 -#define SHIFT3 15 -#define COEFFS3 (int[]){28931,28931} -#define N4 2 -#define SHIFT4 15 -#define COEFFS4 (int[]){14533,14533} -#elif 1 // 13/7 CRF -#define N1 4 -#define SHIFT1 4 -#define COEFFS1 (int[]){1,-9,-9,1} -#define N2 4 -#define SHIFT2 4 -#define COEFFS2 (int[]){-1,5,5,-1} -#define N3 0 -#define SHIFT3 1 -#define COEFFS3 NULL -#define N4 0 -#define SHIFT4 1 -#define COEFFS4 NULL -#elif 1 // 3/5 -#define LX0 1 -#define LX1 0 -#define SCALEX 0.5 -#define N1 2 -#define SHIFT1 1 -#define COEFFS1 (int[]){1,1} -#define N2 2 -#define SHIFT2 2 -#define COEFFS2 (int[]){-1,-1} -#define N3 0 -#define SHIFT3 0 -#define COEFFS3 NULL -#define N4 0 -#define SHIFT4 0 -#define COEFFS4 NULL -#elif 1 // 11/5 -#define N1 0 -#define SHIFT1 1 -#define COEFFS1 NULL -#define N2 2 -#define SHIFT2 2 -#define COEFFS2 (int[]){-1,-1} -#define N3 2 -#define SHIFT3 0 -#define COEFFS3 (int[]){-1,-1} -#define N4 4 -#define SHIFT4 7 -#define COEFFS4 (int[]){-5,29,29,-5} -#define SCALEX 4 -#elif 1 // 9/7 CDF -#define N1 2 -#define SHIFT1 7 -#define COEFFS1 (int[]){-203,-203} -#define N2 2 -#define SHIFT2 12 -#define COEFFS2 (int[]){-217,-217} -#define N3 2 -#define SHIFT3 7 -#define COEFFS3 (int[]){113,113} -#define N4 2 -#define SHIFT4 9 -#define COEFFS4 (int[]){227,227} -#define SCALEX 1 -#elif 1 // 7/5 CDF -#define N1 0 -#define SHIFT1 1 -#define COEFFS1 NULL -#define N2 2 -#define SHIFT2 2 -#define COEFFS2 (int[]){-1,-1} -#define N3 2 -#define SHIFT3 0 -#define COEFFS3 (int[]){-1,-1} -#define N4 2 -#define SHIFT4 4 -#define COEFFS4 (int[]){3,3} -#elif 1 // 9/7 MN -#define N1 4 -#define SHIFT1 4 -#define COEFFS1 (int[]){1,-9,-9,1} -#define N2 2 -#define SHIFT2 2 -#define COEFFS2 (int[]){1,1} -#define N3 0 -#define SHIFT3 1 -#define COEFFS3 NULL -#define N4 0 -#define SHIFT4 1 -#define COEFFS4 NULL -#else // 13/7 CRF -#define N1 4 -#define SHIFT1 4 -#define COEFFS1 (int[]){1,-9,-9,1} -#define N2 4 -#define SHIFT2 4 -#define COEFFS2 (int[]){-1,5,5,-1} -#define N3 0 -#define SHIFT3 1 -#define COEFFS3 NULL -#define N4 0 -#define SHIFT4 1 -#define COEFFS4 NULL -#endif -static void horizontal_decomposeX(DWTELEM *b, int width){ - DWTELEM temp[width]; - const int width2= width>>1; - const int w2= (width+1)>>1; - int x; - - inplace_lift(b, width, COEFFS1, N1, SHIFT1, LX1, 0); - inplace_lift(b, width, COEFFS2, N2, SHIFT2, LX0, 0); - inplace_lift(b, width, COEFFS3, N3, SHIFT3, LX1, 0); - inplace_lift(b, width, COEFFS4, N4, SHIFT4, LX0, 0); - - for(x=0; x<width2; x++){ - temp[x ]= b[2*x ]; - temp[x+w2]= b[2*x + 1]; - } - if(width&1) - temp[x ]= b[2*x ]; - memcpy(b, temp, width*sizeof(int)); -} - -static void horizontal_composeX(DWTELEM *b, int width){ - DWTELEM temp[width]; - const int width2= width>>1; - int x; - const int w2= (width+1)>>1; - - memcpy(temp, b, width*sizeof(int)); - for(x=0; x<width2; x++){ - b[2*x ]= temp[x ]; - b[2*x + 1]= temp[x+w2]; - } - if(width&1) - b[2*x ]= temp[x ]; - - inplace_lift(b, width, COEFFS4, N4, SHIFT4, LX0, 1); - inplace_lift(b, width, COEFFS3, N3, SHIFT3, LX1, 1); - inplace_lift(b, width, COEFFS2, N2, SHIFT2, LX0, 1); - inplace_lift(b, width, COEFFS1, N1, SHIFT1, LX1, 1); -} - -static void spatial_decomposeX(DWTELEM *buffer, int width, int height, int stride){ - int x, y; - - for(y=0; y<height; y++){ - for(x=0; x<width; x++){ - buffer[y*stride + x] *= SCALEX; - } - } +static av_always_inline void +inv_liftS(IDWTELEM *dst, IDWTELEM *src, IDWTELEM *ref, + int dst_step, int src_step, int ref_step, + int width, int mul, int add, int shift, + int highpass, int inverse){ + const int mirror_left= !highpass; + const int mirror_right= (width&1) ^ highpass; + const int w= (width>>1) - 1 + (highpass & width); + int i; - for(y=0; y<height; y++){ - horizontal_decomposeX(buffer + y*stride, width); + assert(shift == 4); +#define LIFTS(src, ref, inv) \ + ((inv) ? \ + (src) + (((ref) + 4*(src))>>shift): \ + -((-16*(src) + (ref) + add/4 + 1 + (5<<25))/(5*4) - (1<<23))) + if(mirror_left){ + dst[0] = LIFTS(src[0], mul*2*ref[0]+add, inverse); + dst += dst_step; + src += src_step; } - inplace_liftV(buffer, width, height, stride, COEFFS1, N1, SHIFT1, LX1, 0); - inplace_liftV(buffer, width, height, stride, COEFFS2, N2, SHIFT2, LX0, 0); - inplace_liftV(buffer, width, height, stride, COEFFS3, N3, SHIFT3, LX1, 0); - inplace_liftV(buffer, width, height, stride, COEFFS4, N4, SHIFT4, LX0, 0); -} - -static void spatial_composeX(DWTELEM *buffer, int width, int height, int stride){ - int x, y; - - inplace_liftV(buffer, width, height, stride, COEFFS4, N4, SHIFT4, LX0, 1); - inplace_liftV(buffer, width, height, stride, COEFFS3, N3, SHIFT3, LX1, 1); - inplace_liftV(buffer, width, height, stride, COEFFS2, N2, SHIFT2, LX0, 1); - inplace_liftV(buffer, width, height, stride, COEFFS1, N1, SHIFT1, LX1, 1); - - for(y=0; y<height; y++){ - horizontal_composeX(buffer + y*stride, width); + for(i=0; i<w; i++){ + dst[i*dst_step] = + LIFTS(src[i*src_step], + mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add, + inverse); } - for(y=0; y<height; y++){ - for(x=0; x<width; x++){ - buffer[y*stride + x] /= SCALEX; - } + if(mirror_right){ + dst[w*dst_step] = + LIFTS(src[w*src_step], mul*2*ref[w*ref_step]+add, inverse); } } +#endif /* ! liftS */ static void horizontal_decompose53i(DWTELEM *b, int width){ DWTELEM temp[width]; @@ -1067,7 +895,7 @@ static void horizontal_decompose53i(DWTELEM *b, int width){ #else lift(b+w2, temp+w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0); lift(b , temp , b+w2, 1, 1, 1, width, 1, 2, 2, 0, 0); -#endif +#endif /* 0 */ } static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ @@ -1095,15 +923,11 @@ static void spatial_decompose53i(DWTELEM *buffer, int width, int height, int str DWTELEM *b2= buffer + mirror(y+1, height-1)*stride; DWTELEM *b3= buffer + mirror(y+2, height-1)*stride; -{START_TIMER if(y+1<(unsigned)height) horizontal_decompose53i(b2, width); if(y+2<(unsigned)height) horizontal_decompose53i(b3, width); -STOP_TIMER("horizontal_decompose53i")} -{START_TIMER if(y+1<(unsigned)height) vertical_decompose53iH0(b1, b2, b3, width); if(y+0<(unsigned)height) vertical_decompose53iL0(b0, b1, b2, width); -STOP_TIMER("vertical_decompose53i*")} b0=b2; b1=b3; @@ -1114,9 +938,9 @@ static void horizontal_decompose97i(DWTELEM *b, int width){ DWTELEM temp[width]; const int w2= (width+1)>>1; - lift (temp+w2, b +1, b , 1, 2, 2, width, -W_AM, W_AO, W_AS, 1, 0); - liftS(temp , b , temp+w2, 1, 2, 1, width, -W_BM, W_BO, W_BS, 0, 0); - lift5(b +w2, temp+w2, temp , 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0); + lift (temp+w2, b +1, b , 1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1); + liftS(temp , b , temp+w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0); + lift (b +w2, temp+w2, temp , 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0); lift (b , temp , b +w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0); } @@ -1133,14 +957,7 @@ static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int w int i; for(i=0; i<width; i++){ -#ifdef lift5 b1[i] += (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS; -#else - int r= 3*(b0[i] + b2[i]); - r+= r>>4; - r+= r>>8; - b1[i] += (r+W_CO)>>W_CS; -#endif } } @@ -1151,7 +968,7 @@ static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int w #ifdef liftS b1[i] -= (W_BM*(b0[i] + b2[i])+W_BO)>>W_BS; #else - b1[i] = (16*4*b1[i] - 4*(b0[i] + b2[i]) + 8*5 + (5<<27)) / (5*16) - (1<<23); + b1[i] = (16*4*b1[i] - 4*(b0[i] + b2[i]) + W_BO*5 + (5<<27)) / (5*16) - (1<<23); #endif } } @@ -1175,23 +992,14 @@ static void spatial_decompose97i(DWTELEM *buffer, int width, int height, int str DWTELEM *b4= buffer + mirror(y+3, height-1)*stride; DWTELEM *b5= buffer + mirror(y+4, height-1)*stride; -{START_TIMER if(y+3<(unsigned)height) horizontal_decompose97i(b4, width); if(y+4<(unsigned)height) horizontal_decompose97i(b5, width); -if(width>400){ -STOP_TIMER("horizontal_decompose97i") -}} -{START_TIMER if(y+3<(unsigned)height) vertical_decompose97iH0(b3, b4, b5, width); if(y+2<(unsigned)height) vertical_decompose97iL0(b2, b3, b4, width); if(y+1<(unsigned)height) vertical_decompose97iH1(b1, b2, b3, width); if(y+0<(unsigned)height) vertical_decompose97iL1(b0, b1, b2, width); -if(width>400){ -STOP_TIMER("vertical_decompose97i") -}} - b0=b2; b1=b3; b2=b4; @@ -1206,13 +1014,12 @@ void ff_spatial_dwt(DWTELEM *buffer, int width, int height, int stride, int type switch(type){ case DWT_97: spatial_decompose97i(buffer, width>>level, height>>level, stride<<level); break; case DWT_53: spatial_decompose53i(buffer, width>>level, height>>level, stride<<level); break; - case DWT_X: spatial_decomposeX (buffer, width>>level, height>>level, stride<<level); break; } } } -static void horizontal_compose53i(DWTELEM *b, int width){ - DWTELEM temp[width]; +static void horizontal_compose53i(IDWTELEM *b, int width){ + IDWTELEM temp[width]; const int width2= width>>1; const int w2= (width+1)>>1; int x; @@ -1247,9 +1054,9 @@ static void horizontal_compose53i(DWTELEM *b, int width){ b[width -1] = A3; b[width2-1] = A2; #else - lift(temp , b , b+w2, 1, 1, 1, width, 1, 2, 2, 0, 1); - lift(temp+w2, b+w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 1); -#endif + inv_lift(temp , b , b+w2, 1, 1, 1, width, 1, 2, 2, 0, 1); + inv_lift(temp+w2, b+w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 1); +#endif /* 0 */ for(x=0; x<width2; x++){ b[2*x ]= temp[x ]; b[2*x + 1]= temp[x+w2]; @@ -1258,7 +1065,7 @@ static void horizontal_compose53i(DWTELEM *b, int width){ b[2*x ]= temp[x ]; } -static void vertical_compose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ +static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ int i; for(i=0; i<width; i++){ @@ -1266,7 +1073,7 @@ static void vertical_compose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int wid } } -static void vertical_compose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ +static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ int i; for(i=0; i<width; i++){ @@ -1280,7 +1087,7 @@ static void spatial_compose53i_buffered_init(dwt_compose_t *cs, slice_buffer * s cs->y = -1; } -static void spatial_compose53i_init(dwt_compose_t *cs, DWTELEM *buffer, int height, int stride){ +static void spatial_compose53i_init(dwt_compose_t *cs, IDWTELEM *buffer, int height, int stride){ cs->b0 = buffer + mirror(-1-1, height-1)*stride; cs->b1 = buffer + mirror(-1 , height-1)*stride; cs->y = -1; @@ -1289,49 +1096,41 @@ static void spatial_compose53i_init(dwt_compose_t *cs, DWTELEM *buffer, int heig static void spatial_compose53i_dy_buffered(dwt_compose_t *cs, slice_buffer * sb, int width, int height, int stride_line){ int y= cs->y; - DWTELEM *b0= cs->b0; - DWTELEM *b1= cs->b1; - DWTELEM *b2= slice_buffer_get_line(sb, mirror(y+1, height-1) * stride_line); - DWTELEM *b3= slice_buffer_get_line(sb, mirror(y+2, height-1) * stride_line); + IDWTELEM *b0= cs->b0; + IDWTELEM *b1= cs->b1; + IDWTELEM *b2= slice_buffer_get_line(sb, mirror(y+1, height-1) * stride_line); + IDWTELEM *b3= slice_buffer_get_line(sb, mirror(y+2, height-1) * stride_line); -{START_TIMER if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width); if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width); -STOP_TIMER("vertical_compose53i*")} -{START_TIMER if(y-1<(unsigned)height) horizontal_compose53i(b0, width); if(y+0<(unsigned)height) horizontal_compose53i(b1, width); -STOP_TIMER("horizontal_compose53i")} cs->b0 = b2; cs->b1 = b3; cs->y += 2; } -static void spatial_compose53i_dy(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride){ +static void spatial_compose53i_dy(dwt_compose_t *cs, IDWTELEM *buffer, int width, int height, int stride){ int y= cs->y; - DWTELEM *b0= cs->b0; - DWTELEM *b1= cs->b1; - DWTELEM *b2= buffer + mirror(y+1, height-1)*stride; - DWTELEM *b3= buffer + mirror(y+2, height-1)*stride; + IDWTELEM *b0= cs->b0; + IDWTELEM *b1= cs->b1; + IDWTELEM *b2= buffer + mirror(y+1, height-1)*stride; + IDWTELEM *b3= buffer + mirror(y+2, height-1)*stride; -{START_TIMER if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width); if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width); -STOP_TIMER("vertical_compose53i*")} -{START_TIMER if(y-1<(unsigned)height) horizontal_compose53i(b0, width); if(y+0<(unsigned)height) horizontal_compose53i(b1, width); -STOP_TIMER("horizontal_compose53i")} cs->b0 = b2; cs->b1 = b3; cs->y += 2; } -static void spatial_compose53i(DWTELEM *buffer, int width, int height, int stride){ +static void av_unused spatial_compose53i(IDWTELEM *buffer, int width, int height, int stride){ dwt_compose_t cs; spatial_compose53i_init(&cs, buffer, height, stride); while(cs.y <= height) @@ -1339,17 +1138,17 @@ static void spatial_compose53i(DWTELEM *buffer, int width, int height, int strid } -void ff_snow_horizontal_compose97i(DWTELEM *b, int width){ - DWTELEM temp[width]; +void ff_snow_horizontal_compose97i(IDWTELEM *b, int width){ + IDWTELEM temp[width]; const int w2= (width+1)>>1; - lift (temp , b , b +w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 1); - lift5(temp+w2, b +w2, temp , 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 1); - liftS(b , temp , temp+w2, 2, 1, 1, width, -W_BM, W_BO, W_BS, 0, 1); - lift (b+1 , temp+w2, b , 2, 1, 2, width, -W_AM, W_AO, W_AS, 1, 1); + inv_lift (temp , b , b +w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 1); + inv_lift (temp+w2, b +w2, temp , 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 1); + inv_liftS(b , temp , temp+w2, 2, 1, 1, width, W_BM, W_BO, W_BS, 0, 1); + inv_lift (b+1 , temp+w2, b , 2, 1, 2, width, W_AM, W_AO, W_AS, 1, 0); } -static void vertical_compose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ +static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ int i; for(i=0; i<width; i++){ @@ -1357,22 +1156,15 @@ static void vertical_compose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int wid } } -static void vertical_compose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ +static void vertical_compose97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ int i; for(i=0; i<width; i++){ -#ifdef lift5 b1[i] -= (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS; -#else - int r= 3*(b0[i] + b2[i]); - r+= r>>4; - r+= r>>8; - b1[i] -= (r+W_CO)>>W_CS; -#endif } } -static void vertical_compose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ +static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ int i; for(i=0; i<width; i++){ @@ -1384,7 +1176,7 @@ static void vertical_compose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int wid } } -static void vertical_compose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ +static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ int i; for(i=0; i<width; i++){ @@ -1392,22 +1184,12 @@ static void vertical_compose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int wid } } -void ff_snow_vertical_compose97i(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width){ +void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ int i; for(i=0; i<width; i++){ -#ifndef lift5 - int r; -#endif b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; -#ifdef lift5 b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; -#else - r= 3*(b2[i] + b4[i]); - r+= r>>4; - r+= r>>8; - b3[i] -= (r+W_CO)>>W_CS; -#endif #ifdef liftS b2[i] += (W_BM*(b1[i] + b3[i])+W_BO)>>W_BS; #else @@ -1425,7 +1207,7 @@ static void spatial_compose97i_buffered_init(dwt_compose_t *cs, slice_buffer * s cs->y = -3; } -static void spatial_compose97i_init(dwt_compose_t *cs, DWTELEM *buffer, int height, int stride){ +static void spatial_compose97i_init(dwt_compose_t *cs, IDWTELEM *buffer, int height, int stride){ cs->b0 = buffer + mirror(-3-1, height-1)*stride; cs->b1 = buffer + mirror(-3 , height-1)*stride; cs->b2 = buffer + mirror(-3+1, height-1)*stride; @@ -1436,14 +1218,13 @@ static void spatial_compose97i_init(dwt_compose_t *cs, DWTELEM *buffer, int heig static void spatial_compose97i_dy_buffered(DSPContext *dsp, dwt_compose_t *cs, slice_buffer * sb, int width, int height, int stride_line){ int y = cs->y; - DWTELEM *b0= cs->b0; - DWTELEM *b1= cs->b1; - DWTELEM *b2= cs->b2; - DWTELEM *b3= cs->b3; - DWTELEM *b4= slice_buffer_get_line(sb, mirror(y + 3, height - 1) * stride_line); - DWTELEM *b5= slice_buffer_get_line(sb, mirror(y + 4, height - 1) * stride_line); + IDWTELEM *b0= cs->b0; + IDWTELEM *b1= cs->b1; + IDWTELEM *b2= cs->b2; + IDWTELEM *b3= cs->b3; + IDWTELEM *b4= slice_buffer_get_line(sb, mirror(y + 3, height - 1) * stride_line); + IDWTELEM *b5= slice_buffer_get_line(sb, mirror(y + 4, height - 1) * stride_line); -{START_TIMER if(y>0 && y+4<height){ dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width); }else{ @@ -1452,14 +1233,9 @@ static void spatial_compose97i_dy_buffered(DSPContext *dsp, dwt_compose_t *cs, s if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width); if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width); } -if(width>400){ -STOP_TIMER("vertical_compose97i")}} -{START_TIMER if(y-1<(unsigned)height) dsp->horizontal_compose97i(b0, width); if(y+0<(unsigned)height) dsp->horizontal_compose97i(b1, width); -if(width>400 && y+0<(unsigned)height){ -STOP_TIMER("horizontal_compose97i")}} cs->b0=b2; cs->b1=b3; @@ -1468,28 +1244,22 @@ STOP_TIMER("horizontal_compose97i")}} cs->y += 2; } -static void spatial_compose97i_dy(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride){ +static void spatial_compose97i_dy(dwt_compose_t *cs, IDWTELEM *buffer, int width, int height, int stride){ int y = cs->y; - DWTELEM *b0= cs->b0; - DWTELEM *b1= cs->b1; - DWTELEM *b2= cs->b2; - DWTELEM *b3= cs->b3; - DWTELEM *b4= buffer + mirror(y+3, height-1)*stride; - DWTELEM *b5= buffer + mirror(y+4, height-1)*stride; - -{START_TIMER + IDWTELEM *b0= cs->b0; + IDWTELEM *b1= cs->b1; + IDWTELEM *b2= cs->b2; + IDWTELEM *b3= cs->b3; + IDWTELEM *b4= buffer + mirror(y+3, height-1)*stride; + IDWTELEM *b5= buffer + mirror(y+4, height-1)*stride; + if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width); if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width); if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width); if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width); -if(width>400){ -STOP_TIMER("vertical_compose97i")}} -{START_TIMER if(y-1<(unsigned)height) ff_snow_horizontal_compose97i(b0, width); if(y+0<(unsigned)height) ff_snow_horizontal_compose97i(b1, width); -if(width>400 && b0 <= b2){ -STOP_TIMER("horizontal_compose97i")}} cs->b0=b2; cs->b1=b3; @@ -1498,7 +1268,7 @@ STOP_TIMER("horizontal_compose97i")}} cs->y += 2; } -static void spatial_compose97i(DWTELEM *buffer, int width, int height, int stride){ +static void av_unused spatial_compose97i(IDWTELEM *buffer, int width, int height, int stride){ dwt_compose_t cs; spatial_compose97i_init(&cs, buffer, height, stride); while(cs.y <= height) @@ -1511,26 +1281,21 @@ static void ff_spatial_idwt_buffered_init(dwt_compose_t *cs, slice_buffer * sb, switch(type){ case DWT_97: spatial_compose97i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break; case DWT_53: spatial_compose53i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break; - /* not slicified yet */ - case DWT_X: /*spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;*/ - av_log(NULL, AV_LOG_ERROR, "spatial_composeX neither buffered nor slicified yet.\n"); break; } } } -static void ff_spatial_idwt_init(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){ +static void ff_spatial_idwt_init(dwt_compose_t *cs, IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){ int level; for(level=decomposition_count-1; level>=0; level--){ switch(type){ case DWT_97: spatial_compose97i_init(cs+level, buffer, height>>level, stride<<level); break; case DWT_53: spatial_compose53i_init(cs+level, buffer, height>>level, stride<<level); break; - /* not slicified yet */ - case DWT_X: spatial_composeX(buffer, width>>level, height>>level, stride<<level); break; } } } -static void ff_spatial_idwt_slice(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count, int y){ +static void ff_spatial_idwt_slice(dwt_compose_t *cs, IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count, int y){ const int support = type==1 ? 3 : 5; int level; if(type==2) return; @@ -1539,10 +1304,9 @@ static void ff_spatial_idwt_slice(dwt_compose_t *cs, DWTELEM *buffer, int width, while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){ switch(type){ case DWT_97: spatial_compose97i_dy(cs+level, buffer, width>>level, height>>level, stride<<level); - break; + break; case DWT_53: spatial_compose53i_dy(cs+level, buffer, width>>level, height>>level, stride<<level); - break; - case DWT_X: break; + break; } } } @@ -1557,30 +1321,23 @@ static void ff_spatial_idwt_buffered_slice(DSPContext *dsp, dwt_compose_t *cs, s while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){ switch(type){ case DWT_97: spatial_compose97i_dy_buffered(dsp, cs+level, slice_buf, width>>level, height>>level, stride_line<<level); - break; + break; case DWT_53: spatial_compose53i_dy_buffered(cs+level, slice_buf, width>>level, height>>level, stride_line<<level); - break; - case DWT_X: break; + break; } } } } -static void ff_spatial_idwt(DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){ - if(type==2){ - int level; - for(level=decomposition_count-1; level>=0; level--) - spatial_composeX (buffer, width>>level, height>>level, stride<<level); - }else{ +static void ff_spatial_idwt(IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){ dwt_compose_t cs[MAX_DECOMPOSITIONS]; int y; ff_spatial_idwt_init(cs, buffer, width, height, stride, type, decomposition_count); for(y=0; y<height; y+=4) ff_spatial_idwt_slice(cs, buffer, width, height, stride, type, decomposition_count, y); - } } -static int encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){ +static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){ const int w= b->width; const int h= b->height; int x, y; @@ -1700,7 +1457,7 @@ static int encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTELE return 0; } -static int encode_subband(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){ +static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){ // encode_subband_qtree(s, b, src, parent, stride, orientation); // encode_subband_z0run(s, b, src, parent, stride, orientation); return encode_subband_c0run(s, b, src, parent, stride, orientation); @@ -1815,9 +1572,7 @@ static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, sli int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; int new_index = 0; - START_TIMER - - if(b->buf == s->spatial_dwt_buffer || s->qlog == LOSSLESS_QLOG){ + if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){ qadd= 0; qmul= 1<<QEXPSHIFT; } @@ -1830,8 +1585,8 @@ static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, sli for(y=start_y; y<h; y++){ int x = 0; int v; - DWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset; - memset(line, 0, b->width*sizeof(DWTELEM)); + IDWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset; + memset(line, 0, b->width*sizeof(IDWTELEM)); v = b->x_coeff[new_index].coeff; x = b->x_coeff[new_index++].x; while(x < w) @@ -1844,9 +1599,6 @@ static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, sli x = b->x_coeff[new_index++].x; } } - if(w > 200 && start_y != 0/*level+1 == s->spatial_decomposition_count*/){ - STOP_TIMER("decode_subband") - } /* Save our variables for the next slice. */ save_state[0] = new_index; @@ -1858,7 +1610,7 @@ static void reset_contexts(SnowContext *s){ //FIXME better initial contexts int plane_index, level, orientation; for(plane_index=0; plane_index<3; plane_index++){ - for(level=0; level<s->spatial_decomposition_count; level++){ + for(level=0; level<MAX_DECOMPOSITIONS; level++){ for(orientation=level ? 1:0; orientation<4; orientation++){ memset(s->plane[plane_index].band[level][orientation].state, MID_STATE, sizeof(s->plane[plane_index].band[level][orientation].state)); } @@ -1990,7 +1742,7 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ RangeCoder pc, ic; uint8_t *pbbak= s->c.bytestream; uint8_t *pbbak_start= s->c.bytestream_start; - int score, score2, iscore, i_len, p_len, block_s, sum; + int score, score2, iscore, i_len, p_len, block_s, sum, base_bits; const int w= s->b_width << s->block_max_depth; const int h= s->b_height << s->block_max_depth; const int rem_depth= s->block_max_depth - level; @@ -2113,9 +1865,10 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ my= ref_my; } } - //FIXME if mb_cmp != SSE then intra cant be compared currently and mb_penalty vs. lambda2 + //FIXME if mb_cmp != SSE then intra cannot be compared currently and mb_penalty vs. lambda2 // subpel search + base_bits= get_rac_count(&s->c) - 8*(s->c.bytestream - s->c.bytestream_start); pc= s->c; pc.bytestream_start= pc.bytestream= p_buffer; //FIXME end/start? and at the other stoo @@ -2130,10 +1883,7 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1); put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1); p_len= pc.bytestream - pc.bytestream_start; - score += (s->lambda2*(p_len*8 - + (pc.outstanding_count - s->c.outstanding_count)*8 - + (-av_log2(pc.range) + av_log2(s->c.range)) - ))>>FF_LAMBDA_SHIFT; + score += (s->lambda2*(get_rac_count(&pc)-base_bits))>>FF_LAMBDA_SHIFT; block_s= block_w*block_w; sum = pix_sum(current_data[0], stride, block_w); @@ -2159,10 +1909,7 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ put_symbol(&ic, &i_state[64], cb-pcb, 1); put_symbol(&ic, &i_state[96], cr-pcr, 1); i_len= ic.bytestream - ic.bytestream_start; - iscore += (s->lambda2*(i_len*8 - + (ic.outstanding_count - s->c.outstanding_count)*8 - + (-av_log2(ic.range) + av_log2(s->c.range)) - ))>>FF_LAMBDA_SHIFT; + iscore += (s->lambda2*(get_rac_count(&ic)-base_bits))>>FF_LAMBDA_SHIFT; // assert(score==256*256*256*64-1); assert(iscore < 255*255*256 + s->lambda2*10); @@ -2356,80 +2103,195 @@ static void decode_blocks(SnowContext *s){ } } -static void mc_block(uint8_t *dst, uint8_t *src, uint8_t *tmp, int stride, int b_w, int b_h, int dx, int dy){ - int x, y; -START_TIMER - for(y=0; y < b_h+5; y++){ - for(x=0; x < b_w; x++){ - int a0= src[x ]; - int a1= src[x + 1]; - int a2= src[x + 2]; - int a3= src[x + 3]; - int a4= src[x + 4]; - int a5= src[x + 5]; -// int am= 9*(a1+a2) - (a0+a3); - int am= 20*(a2+a3) - 5*(a1+a4) + (a0+a5); -// int am= 18*(a2+a3) - 2*(a1+a4); -// int aL= (-7*a0 + 105*a1 + 35*a2 - 5*a3)>>3; -// int aR= (-7*a3 + 105*a2 + 35*a1 - 5*a0)>>3; - -// if(b_w==16) am= 8*(a1+a2); - - if(dx<8) am = (32*a2*( 8-dx) + am* dx + 128)>>8; - else am = ( am*(16-dx) + 32*a3*(dx-8) + 128)>>8; - - /* FIXME Try increasing tmp buffer to 16 bits and not clipping here. Should give marginally better results. - Robert*/ - if(am&(~255)) am= ~(am>>31); - - tmp[x] = am; - -/* if (dx< 4) tmp[x + y*stride]= (16*a1*( 4-dx) + aL* dx + 32)>>6; - else if(dx< 8) tmp[x + y*stride]= ( aL*( 8-dx) + am*(dx- 4) + 32)>>6; - else if(dx<12) tmp[x + y*stride]= ( am*(12-dx) + aR*(dx- 8) + 32)>>6; - else tmp[x + y*stride]= ( aR*(16-dx) + 16*a2*(dx-12) + 32)>>6;*/ +static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, uint8_t *tmp, int stride, int b_w, int b_h, int dx, int dy){ + const static uint8_t weight[64]={ + 8,7,6,5,4,3,2,1, + 7,7,0,0,0,0,0,1, + 6,0,6,0,0,0,2,0, + 5,0,0,5,0,3,0,0, + 4,0,0,0,4,0,0,0, + 3,0,0,5,0,3,0,0, + 2,0,6,0,0,0,2,0, + 1,7,0,0,0,0,0,1, + }; + + const static uint8_t brane[256]={ + 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x11,0x12,0x12,0x12,0x12,0x12,0x12,0x12, + 0x04,0x05,0xcc,0xcc,0xcc,0xcc,0xcc,0x41,0x15,0x16,0xcc,0xcc,0xcc,0xcc,0xcc,0x52, + 0x04,0xcc,0x05,0xcc,0xcc,0xcc,0x41,0xcc,0x15,0xcc,0x16,0xcc,0xcc,0xcc,0x52,0xcc, + 0x04,0xcc,0xcc,0x05,0xcc,0x41,0xcc,0xcc,0x15,0xcc,0xcc,0x16,0xcc,0x52,0xcc,0xcc, + 0x04,0xcc,0xcc,0xcc,0x41,0xcc,0xcc,0xcc,0x15,0xcc,0xcc,0xcc,0x16,0xcc,0xcc,0xcc, + 0x04,0xcc,0xcc,0x41,0xcc,0x05,0xcc,0xcc,0x15,0xcc,0xcc,0x52,0xcc,0x16,0xcc,0xcc, + 0x04,0xcc,0x41,0xcc,0xcc,0xcc,0x05,0xcc,0x15,0xcc,0x52,0xcc,0xcc,0xcc,0x16,0xcc, + 0x04,0x41,0xcc,0xcc,0xcc,0xcc,0xcc,0x05,0x15,0x52,0xcc,0xcc,0xcc,0xcc,0xcc,0x16, + 0x44,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x55,0x56,0x56,0x56,0x56,0x56,0x56,0x56, + 0x48,0x49,0xcc,0xcc,0xcc,0xcc,0xcc,0x85,0x59,0x5A,0xcc,0xcc,0xcc,0xcc,0xcc,0x96, + 0x48,0xcc,0x49,0xcc,0xcc,0xcc,0x85,0xcc,0x59,0xcc,0x5A,0xcc,0xcc,0xcc,0x96,0xcc, + 0x48,0xcc,0xcc,0x49,0xcc,0x85,0xcc,0xcc,0x59,0xcc,0xcc,0x5A,0xcc,0x96,0xcc,0xcc, + 0x48,0xcc,0xcc,0xcc,0x49,0xcc,0xcc,0xcc,0x59,0xcc,0xcc,0xcc,0x96,0xcc,0xcc,0xcc, + 0x48,0xcc,0xcc,0x85,0xcc,0x49,0xcc,0xcc,0x59,0xcc,0xcc,0x96,0xcc,0x5A,0xcc,0xcc, + 0x48,0xcc,0x85,0xcc,0xcc,0xcc,0x49,0xcc,0x59,0xcc,0x96,0xcc,0xcc,0xcc,0x5A,0xcc, + 0x48,0x85,0xcc,0xcc,0xcc,0xcc,0xcc,0x49,0x59,0x96,0xcc,0xcc,0xcc,0xcc,0xcc,0x5A, + }; + + const static uint8_t needs[16]={ + 0,1,0,0, + 2,4,2,0, + 0,1,0,0, + 15 + }; + + int x, y, b, r, l; + int16_t tmpIt [64*(32+HTAPS_MAX)]; + uint8_t tmp2t[3][stride*(32+HTAPS_MAX)]; + int16_t *tmpI= tmpIt; + uint8_t *tmp2= tmp2t[0]; + const uint8_t *hpel[11]; + assert(dx<16 && dy<16); + r= brane[dx + 16*dy]&15; + l= brane[dx + 16*dy]>>4; + + b= needs[l] | needs[r]; + if(p && !p->diag_mc) + b= 15; + + if(b&5){ + for(y=0; y < b_h+HTAPS_MAX-1; y++){ + for(x=0; x < b_w; x++){ + int a_1=src[x + HTAPS_MAX/2-4]; + int a0= src[x + HTAPS_MAX/2-3]; + int a1= src[x + HTAPS_MAX/2-2]; + int a2= src[x + HTAPS_MAX/2-1]; + int a3= src[x + HTAPS_MAX/2+0]; + int a4= src[x + HTAPS_MAX/2+1]; + int a5= src[x + HTAPS_MAX/2+2]; + int a6= src[x + HTAPS_MAX/2+3]; + int am=0; + if(!p || p->fast_mc){ + am= 20*(a2+a3) - 5*(a1+a4) + (a0+a5); + tmpI[x]= am; + am= (am+16)>>5; + }else{ + am= p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6); + tmpI[x]= am; + am= (am+32)>>6; + } + + if(am&(~255)) am= ~(am>>31); + tmp2[x]= am; + } + tmpI+= 64; + tmp2+= stride; + src += stride; } - tmp += stride; - src += stride; - } - tmp -= (b_h+5)*stride; - - for(y=0; y < b_h; y++){ - for(x=0; x < b_w; x++){ - int a0= tmp[x + 0*stride]; - int a1= tmp[x + 1*stride]; - int a2= tmp[x + 2*stride]; - int a3= tmp[x + 3*stride]; - int a4= tmp[x + 4*stride]; - int a5= tmp[x + 5*stride]; - int am= 20*(a2+a3) - 5*(a1+a4) + (a0+a5); -// int am= 18*(a2+a3) - 2*(a1+a4); -/* int aL= (-7*a0 + 105*a1 + 35*a2 - 5*a3)>>3; - int aR= (-7*a3 + 105*a2 + 35*a1 - 5*a0)>>3;*/ - -// if(b_w==16) am= 8*(a1+a2); - - if(dy<8) am = (32*a2*( 8-dy) + am* dy + 128)>>8; - else am = ( am*(16-dy) + 32*a3*(dy-8) + 128)>>8; - - if(am&(~255)) am= ~(am>>31); - - dst[x] = am; -/* if (dy< 4) tmp[x + y*stride]= (16*a1*( 4-dy) + aL* dy + 32)>>6; - else if(dy< 8) tmp[x + y*stride]= ( aL*( 8-dy) + am*(dy- 4) + 32)>>6; - else if(dy<12) tmp[x + y*stride]= ( am*(12-dy) + aR*(dy- 8) + 32)>>6; - else tmp[x + y*stride]= ( aR*(16-dy) + 16*a2*(dy-12) + 32)>>6;*/ + src -= stride*y; + } + src += HTAPS_MAX/2 - 1; + tmp2= tmp2t[1]; + + if(b&2){ + for(y=0; y < b_h; y++){ + for(x=0; x < b_w+1; x++){ + int a_1=src[x + (HTAPS_MAX/2-4)*stride]; + int a0= src[x + (HTAPS_MAX/2-3)*stride]; + int a1= src[x + (HTAPS_MAX/2-2)*stride]; + int a2= src[x + (HTAPS_MAX/2-1)*stride]; + int a3= src[x + (HTAPS_MAX/2+0)*stride]; + int a4= src[x + (HTAPS_MAX/2+1)*stride]; + int a5= src[x + (HTAPS_MAX/2+2)*stride]; + int a6= src[x + (HTAPS_MAX/2+3)*stride]; + int am=0; + if(!p || p->fast_mc) + am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 16)>>5; + else + am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 32)>>6; + + if(am&(~255)) am= ~(am>>31); + tmp2[x]= am; + } + src += stride; + tmp2+= stride; + } + src -= stride*y; + } + src += stride*(HTAPS_MAX/2 - 1); + tmp2= tmp2t[2]; + tmpI= tmpIt; + if(b&4){ + for(y=0; y < b_h; y++){ + for(x=0; x < b_w; x++){ + int a_1=tmpI[x + (HTAPS_MAX/2-4)*64]; + int a0= tmpI[x + (HTAPS_MAX/2-3)*64]; + int a1= tmpI[x + (HTAPS_MAX/2-2)*64]; + int a2= tmpI[x + (HTAPS_MAX/2-1)*64]; + int a3= tmpI[x + (HTAPS_MAX/2+0)*64]; + int a4= tmpI[x + (HTAPS_MAX/2+1)*64]; + int a5= tmpI[x + (HTAPS_MAX/2+2)*64]; + int a6= tmpI[x + (HTAPS_MAX/2+3)*64]; + int am=0; + if(!p || p->fast_mc) + am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 512)>>10; + else + am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 2048)>>12; + if(am&(~255)) am= ~(am>>31); + tmp2[x]= am; + } + tmpI+= 64; + tmp2+= stride; + } + } + + hpel[ 0]= src; + hpel[ 1]= tmp2t[0] + stride*(HTAPS_MAX/2-1); + hpel[ 2]= src + 1; + + hpel[ 4]= tmp2t[1]; + hpel[ 5]= tmp2t[2]; + hpel[ 6]= tmp2t[1] + 1; + + hpel[ 8]= src + stride; + hpel[ 9]= hpel[1] + stride; + hpel[10]= hpel[8] + 1; + + if(b==15){ + const uint8_t *src1= hpel[dx/8 + dy/8*4 ]; + const uint8_t *src2= hpel[dx/8 + dy/8*4+1]; + const uint8_t *src3= hpel[dx/8 + dy/8*4+4]; + const uint8_t *src4= hpel[dx/8 + dy/8*4+5]; + dx&=7; + dy&=7; + for(y=0; y < b_h; y++){ + for(x=0; x < b_w; x++){ + dst[x]= ((8-dx)*(8-dy)*src1[x] + dx*(8-dy)*src2[x]+ + (8-dx)* dy *src3[x] + dx* dy *src4[x]+32)>>6; + } + src1+=stride; + src2+=stride; + src3+=stride; + src4+=stride; + dst +=stride; + } + }else{ + const uint8_t *src1= hpel[l]; + const uint8_t *src2= hpel[r]; + int a= weight[((dx&7) + (8*(dy&7)))]; + int b= 8-a; + for(y=0; y < b_h; y++){ + for(x=0; x < b_w; x++){ + dst[x]= (a*src1[x] + b*src2[x] + 4)>>3; + } + src1+=stride; + src2+=stride; + dst +=stride; } - dst += stride; - tmp += stride; } -STOP_TIMER("mc_block") } #define mca(dx,dy,b_w)\ -static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, uint8_t *src, int stride, int h){\ - uint8_t tmp[stride*(b_w+5)];\ +static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, int stride, int h){\ + uint8_t tmp[stride*(b_w+HTAPS_MAX-1)];\ assert(h==b_w);\ - mc_block(dst, src-2-2*stride, tmp, stride, b_w, b_w, dx, dy);\ + mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, tmp, stride, b_w, b_w, dx, dy);\ } mca( 0, 0,16) @@ -2488,35 +2350,35 @@ static void pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, i const int dx= mx&15; const int dy= my&15; const int tab_index= 3 - (b_w>>2) + (b_w>>4); - sx += (mx>>4) - 2; - sy += (my>>4) - 2; + sx += (mx>>4) - (HTAPS_MAX/2-1); + sy += (my>>4) - (HTAPS_MAX/2-1); src += sx + sy*stride; - if( (unsigned)sx >= w - b_w - 4 - || (unsigned)sy >= h - b_h - 4){ - ff_emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+5, b_h+5, sx, sy, w, h); + if( (unsigned)sx >= w - b_w - (HTAPS_MAX-2) + || (unsigned)sy >= h - b_h - (HTAPS_MAX-2)){ + ff_emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h); src= tmp + MB_SIZE; } // assert(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h); // assert(!(b_w&(b_w-1))); assert(b_w>1 && b_h>1); - assert(tab_index>=0 && tab_index<4 || b_w==32); - if((dx&3) || (dy&3) || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) || (b_w&(b_w-1))) - mc_block(dst, src, tmp, stride, b_w, b_h, dx, dy); + assert((tab_index>=0 && tab_index<4) || b_w==32); + if((dx&3) || (dy&3) || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) || (b_w&(b_w-1)) || !s->plane[plane_index].fast_mc ) + mc_block(&s->plane[plane_index], dst, src, tmp, stride, b_w, b_h, dx, dy); else if(b_w==32){ int y; for(y=0; y<b_h; y+=16){ - s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 2 + (y+2)*stride,stride); - s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 18 + (y+2)*stride,stride); + s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride); + s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride); } }else if(b_w==b_h) - s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst,src + 2 + 2*stride,stride); + s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride); else if(b_w==2*b_h){ - s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst ,src + 2 + 2*stride,stride); - s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 2 + b_h + 2*stride,stride); + s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst ,src + 3 + 3*stride,stride); + s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride); }else{ assert(2*b_w==b_h); - s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst ,src + 2 + 2*stride ,stride); - s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst+b_w*stride,src + 2 + 2*stride+b_w*stride,stride); + s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst ,src + 3 + 3*stride ,stride); + s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride); } } } @@ -2524,9 +2386,9 @@ static void pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, i void ff_snow_inner_add_yblock(const 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){ int y, x; - DWTELEM * dst; + IDWTELEM * dst; for(y=0; y<b_h; y++){ - //FIXME ugly missue of obmc_stride + //FIXME ugly misuse of obmc_stride const uint8_t *obmc1= obmc + y*obmc_stride; const uint8_t *obmc2= obmc1+ (obmc_stride>>1); const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); @@ -2540,7 +2402,6 @@ void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, uint8_ v <<= 8 - LOG2_OBMC_MAX; if(FRAC_BITS != 8){ - v += 1<<(7 - FRAC_BITS); v >>= 8 - FRAC_BITS; } if(add){ @@ -2555,8 +2416,8 @@ void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, uint8_ } } -//FIXME name clenup (b_w, block_w, b_width stuff) -static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, DWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){ +//FIXME name cleanup (b_w, block_w, b_width stuff) +static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){ const int b_width = s->b_width << s->block_max_depth; const int b_height= s->b_height << s->block_max_depth; const int b_stride= b_width; @@ -2585,7 +2446,7 @@ static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer rb= rt; } - if(src_x<0){ //FIXME merge with prev & always round internal width upto *16 + if(src_x<0){ //FIXME merge with prev & always round internal width up to *16 obmc -= src_x; b_w += src_x; if(!sliced && !offset_dst) @@ -2606,7 +2467,8 @@ static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer if(b_w<=0 || b_h<=0) return; -assert(src_stride > 2*MB_SIZE + 5); + assert(src_stride > 2*MB_SIZE + 5); + if(!sliced && offset_dst) dst += src_x + src_y*dst_stride; dst8+= src_x + src_y*src_stride; @@ -2680,13 +2542,10 @@ assert(src_stride > 2*MB_SIZE + 5); } #else if(sliced){ - START_TIMER - s->dsp.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); - STOP_TIMER("inner_add_yblock") }else for(y=0; y<b_h; y++){ - //FIXME ugly missue of obmc_stride + //FIXME ugly misuse of obmc_stride const uint8_t *obmc1= obmc + y*obmc_stride; const uint8_t *obmc2= obmc1+ (obmc_stride>>1); const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1); @@ -2699,7 +2558,6 @@ assert(src_stride > 2*MB_SIZE + 5); v <<= 8 - LOG2_OBMC_MAX; if(FRAC_BITS != 8){ - v += 1<<(7 - FRAC_BITS); v >>= 8 - FRAC_BITS; } if(add){ @@ -2712,10 +2570,10 @@ assert(src_stride > 2*MB_SIZE + 5); } } } -#endif +#endif /* 0 */ } -static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, DWTELEM * old_buffer, int plane_index, int add, int mb_y){ +static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){ Plane *p= &s->plane[plane_index]; const int mb_w= s->b_width << s->block_max_depth; const int mb_h= s->b_height << s->block_max_depth; @@ -2728,7 +2586,6 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer uint8_t *dst8= s->current_picture.data[plane_index]; int w= p->width; int h= p->height; - START_TIMER if(s->keyframe || (s->avctx->debug&512)){ if(mb_y==mb_h) @@ -2738,7 +2595,7 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++) { // DWTELEM * line = slice_buffer_get_line(sb, y); - DWTELEM * line = sb->line[y]; + IDWTELEM * line = sb->line[y]; for(x=0; x<w; x++) { // int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1)); @@ -2752,7 +2609,7 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++) { // DWTELEM * line = slice_buffer_get_line(sb, y); - DWTELEM * line = sb->line[y]; + IDWTELEM * line = sb->line[y]; for(x=0; x<w; x++) { line[x] -= 128 << FRAC_BITS; @@ -2765,8 +2622,6 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer } for(mb_x=0; mb_x<=mb_w; mb_x++){ - START_TIMER - add_yblock(s, 1, sb, old_buffer, dst8, obmc, block_w*mb_x - block_w/2, block_w*mb_y - block_w/2, @@ -2775,14 +2630,10 @@ static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer w, ref_stride, obmc_stride, mb_x - 1, mb_y - 1, add, 0, plane_index); - - STOP_TIMER("add_yblock") } - - STOP_TIMER("predict_slice") } -static av_always_inline void predict_slice(SnowContext *s, DWTELEM *buf, int plane_index, int add, int mb_y){ +static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int plane_index, int add, int mb_y){ Plane *p= &s->plane[plane_index]; const int mb_w= s->b_width << s->block_max_depth; const int mb_h= s->b_height << s->block_max_depth; @@ -2795,7 +2646,6 @@ static av_always_inline void predict_slice(SnowContext *s, DWTELEM *buf, int pla uint8_t *dst8= s->current_picture.data[plane_index]; int w= p->width; int h= p->height; - START_TIMER if(s->keyframe || (s->avctx->debug&512)){ if(mb_y==mb_h) @@ -2821,25 +2671,19 @@ static av_always_inline void predict_slice(SnowContext *s, DWTELEM *buf, int pla return; } - for(mb_x=0; mb_x<=mb_w; mb_x++){ - START_TIMER - - add_yblock(s, 0, NULL, buf, dst8, obmc, - block_w*mb_x - block_w/2, - block_w*mb_y - block_w/2, - block_w, block_w, - w, h, - w, ref_stride, obmc_stride, - mb_x - 1, mb_y - 1, - add, 1, plane_index); - - STOP_TIMER("add_yblock") - } - - STOP_TIMER("predict_slice") + for(mb_x=0; mb_x<=mb_w; mb_x++){ + add_yblock(s, 0, NULL, buf, dst8, obmc, + block_w*mb_x - block_w/2, + block_w*mb_y - block_w/2, + block_w, block_w, + w, h, + w, ref_stride, obmc_stride, + mb_x - 1, mb_y - 1, + add, 1, plane_index); + } } -static av_always_inline void predict_plane(SnowContext *s, DWTELEM *buf, int plane_index, int add){ +static av_always_inline void predict_plane(SnowContext *s, IDWTELEM *buf, int plane_index, int add){ const int mb_h= s->b_height << s->block_max_depth; int mb_y; for(mb_y=0; mb_y<=mb_h; mb_y++) @@ -2855,7 +2699,7 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ const int obmc_stride= plane_index ? block_size : 2*block_size; const int ref_stride= s->current_picture.linesize[plane_index]; uint8_t *src= s-> input_picture.data[plane_index]; - DWTELEM *dst= (DWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; + IDWTELEM *dst= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned const int b_stride = s->b_width << s->block_max_depth; const int w= p->width; const int h= p->height; @@ -2867,7 +2711,7 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ b->type|= BLOCK_INTRA; b->color[plane_index]= 0; - memset(dst, 0, obmc_stride*obmc_stride*sizeof(DWTELEM)); + memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM)); for(i=0; i<4; i++){ int mb_x2= mb_x + (i &1) - 1; @@ -2887,18 +2731,18 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ if(x<0) obmc_v += obmc[index + block_w]; if(y+block_w>h) obmc_v += obmc[index - block_w*obmc_stride]; if(x+block_w>w) obmc_v += obmc[index - block_w]; - //FIXME precalc this or simplify it somehow else + //FIXME precalculate this or simplify it somehow else d = -dst[index] + (1<<(FRAC_BITS-1)); dst[index] = d; ab += (src[x2 + y2*ref_stride] - (d>>FRAC_BITS)) * obmc_v; - aa += obmc_v * obmc_v; //FIXME precalclate this + aa += obmc_v * obmc_v; //FIXME precalculate this } } } *b= backup; - return av_clip(((ab<<LOG2_OBMC_MAX) + aa/2)/aa, 0, 255); //FIXME we shouldnt need cliping + return av_clip(((ab<<LOG2_OBMC_MAX) + aa/2)/aa, 0, 255); //FIXME we should not need clipping } static inline int get_block_bits(SnowContext *s, int x, int y, int w){ @@ -2924,7 +2768,7 @@ static inline int get_block_bits(SnowContext *s, int x, int y, int w){ 00001XXXX 15-30 8-15 */ //FIXME try accurate rate -//FIXME intra and inter predictors if surrounding blocks arent the same type +//FIXME intra and inter predictors if surrounding blocks are not the same type if(b->type & BLOCK_INTRA){ return 3+2*( av_log2(2*FFABS(left->color[0] - b->color[0])) + av_log2(2*FFABS(left->color[1] - b->color[1])) @@ -2947,9 +2791,9 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, con const int ref_stride= s->current_picture.linesize[plane_index]; uint8_t *dst= s->current_picture.data[plane_index]; uint8_t *src= s-> input_picture.data[plane_index]; - DWTELEM *pred= (DWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; + IDWTELEM *pred= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; uint8_t cur[ref_stride*2*MB_SIZE]; //FIXME alignment - uint8_t tmp[ref_stride*(2*MB_SIZE+5)]; + uint8_t tmp[ref_stride*(2*MB_SIZE+HTAPS_MAX-1)]; const int b_stride = s->b_width << s->block_max_depth; const int b_height = s->b_height<< s->block_max_depth; const int w= p->width; @@ -2969,11 +2813,15 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, con for(y=y0; y<y1; y++){ const uint8_t *obmc1= obmc_edged + y*obmc_stride; - const DWTELEM *pred1 = pred + y*obmc_stride; + const IDWTELEM *pred1 = pred + y*obmc_stride; uint8_t *cur1 = cur + y*ref_stride; uint8_t *dst1 = dst + sx + (sy+y)*ref_stride; for(x=x0; x<x1; x++){ +#if FRAC_BITS >= LOG2_OBMC_MAX int v = (cur1[x] * obmc1[x]) << (FRAC_BITS - LOG2_OBMC_MAX); +#else + int v = (cur1[x] * obmc1[x] + (1<<(LOG2_OBMC_MAX - FRAC_BITS-1))) >> (LOG2_OBMC_MAX - FRAC_BITS); +#endif v = (v + pred1[x]) >> FRAC_BITS; if(v&(~255)) v= ~(v>>31); dst1[x] = v; @@ -2999,10 +2847,10 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, con if(block_w==16){ /* FIXME rearrange dsputil to fit 32x32 cmp functions */ /* FIXME check alignment of the cmp wavelet vs the encoding wavelet */ - /* FIXME cmps overlap but don't cover the wavelet's whole support, - * so improving the score of one block is not strictly guaranteed to - * improve the score of the whole frame, so iterative motion est - * doesn't always converge. */ + /* FIXME cmps overlap but do not cover the wavelet's whole support. + * So improving the score of one block is not strictly guaranteed + * to improve the score of the whole frame, thus iterative motion + * estimation does not always converge. */ if(s->avctx->me_cmp == FF_CMP_W97) distortion = w97_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32); else if(s->avctx->me_cmp == FF_CMP_W53) @@ -3043,7 +2891,9 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ const int ref_stride= s->current_picture.linesize[plane_index]; uint8_t *dst= s->current_picture.data[plane_index]; uint8_t *src= s-> input_picture.data[plane_index]; - static const DWTELEM zero_dst[4096]; //FIXME + //FIXME zero_dst is const but add_yblock changes dst if add is 0 (this is never the case for dst=zero_dst + // const has only been removed from zero_dst to suppress a warning + static IDWTELEM zero_dst[4096]; //FIXME const int b_stride = s->b_width << s->block_max_depth; const int w= p->width; const int h= p->height; @@ -3135,7 +2985,8 @@ static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int } } -/* special case for int[2] args we discard afterward, fixes compilation prob with gcc 2.95 */ +/* special case for int[2] args we discard afterwards, + * fixes compilation problem with gcc 2.95 */ static av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, const uint8_t *obmc_edged, int *best_rd){ int p[2] = {p0, p1}; return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd); @@ -3227,7 +3078,7 @@ static void iterative_me(SnowContext *s){ memset(s->me_cache, 0, sizeof(s->me_cache)); s->me_cache_generation += 1<<22; - //FIXME precalc + //FIXME precalculate { int x, y; memcpy(obmc_edged, obmc_tab[s->block_max_depth], b_w*b_w*4); @@ -3282,7 +3133,7 @@ static void iterative_me(SnowContext *s){ for(i=0; i<3; i++) color[i]= get_dc(s, mb_x, mb_y, i); - // get previous score (cant be cached due to OBMC) + // get previous score (cannot be cached due to OBMC) if(pass > 0 && (block->type&BLOCK_INTRA)){ int color0[3]= {block->color[0], block->color[1], block->color[2]}; check_block(s, mb_x, mb_y, color0, 1, *obmc_edged, &best_rd); @@ -3310,7 +3161,7 @@ static void iterative_me(SnowContext *s){ check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], *obmc_edged, &best_rd); /* fullpel ME */ - //FIXME avoid subpel interpol / round to nearest integer + //FIXME avoid subpel interpolation / round to nearest integer do{ dia_change=0; for(i=0; i<FFMAX(s->avctx->dia_size, 1); i++){ @@ -3403,16 +3254,19 @@ static void iterative_me(SnowContext *s){ } } -static void quantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int bias){ - const int level= b->level; +static void quantize(SnowContext *s, SubBand *b, IDWTELEM *dst, DWTELEM *src, int stride, int bias){ const int w= b->width; const int h= b->height; const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); - const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); + const int qmul= qexp[qlog&(QROOT-1)]<<((qlog>>QSHIFT) + ENCODER_EXTRA_BITS); int x,y, thres1, thres2; -// START_TIMER - if(s->qlog == LOSSLESS_QLOG) return; + if(s->qlog == LOSSLESS_QLOG){ + for(y=0; y<h; y++) + for(x=0; x<w; x++) + dst[x + y*stride]= src[x + y*stride]; + return; + } bias= bias ? 0 : (3*qmul)>>3; thres1= ((qmul - bias)>>QEXPSHIFT) - 1; @@ -3427,15 +3281,15 @@ static void quantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int b if(i>=0){ i<<= QEXPSHIFT; i/= qmul; //FIXME optimize - src[x + y*stride]= i; + dst[x + y*stride]= i; }else{ i= -i; i<<= QEXPSHIFT; i/= qmul; //FIXME optimize - src[x + y*stride]= -i; + dst[x + y*stride]= -i; } }else - src[x + y*stride]= 0; + dst[x + y*stride]= 0; } } }else{ @@ -3447,36 +3301,32 @@ static void quantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int b if(i>=0){ i<<= QEXPSHIFT; i= (i + bias) / qmul; //FIXME optimize - src[x + y*stride]= i; + dst[x + y*stride]= i; }else{ i= -i; i<<= QEXPSHIFT; i= (i + bias) / qmul; //FIXME optimize - src[x + y*stride]= -i; + dst[x + y*stride]= -i; } }else - src[x + y*stride]= 0; + dst[x + y*stride]= 0; } } } - if(level+1 == s->spatial_decomposition_count){ -// STOP_TIMER("quantize") - } } -static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, DWTELEM *src, int stride, int start_y, int end_y){ +static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){ const int w= b->width; const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; int x,y; - START_TIMER if(s->qlog == LOSSLESS_QLOG) return; for(y=start_y; y<end_y; y++){ // DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride)); - DWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset; + IDWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset; for(x=0; x<w; x++){ int i= line[x]; if(i<0){ @@ -3486,19 +3336,15 @@ static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand } } } - if(w > 200 /*level+1 == s->spatial_decomposition_count*/){ - STOP_TIMER("dquant") - } } -static void dequantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride){ +static void dequantize(SnowContext *s, SubBand *b, IDWTELEM *src, int stride){ const int w= b->width; const int h= b->height; const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; int x,y; - START_TIMER if(s->qlog == LOSSLESS_QLOG) return; @@ -3512,12 +3358,9 @@ static void dequantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride){ } } } - if(w > 200 /*level+1 == s->spatial_decomposition_count*/){ - STOP_TIMER("dquant") - } } -static void decorrelate(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int inverse, int use_median){ +static void decorrelate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){ const int w= b->width; const int h= b->height; int x,y; @@ -3541,14 +3384,12 @@ static void decorrelate(SnowContext *s, SubBand *b, DWTELEM *src, int stride, in } } -static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, DWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){ +static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){ const int w= b->width; int x,y; -// START_TIMER - - DWTELEM * line=0; // silence silly "could be used without having been initialized" warning - DWTELEM * prev; + IDWTELEM * line=0; // silence silly "could be used without having been initialized" warning + IDWTELEM * prev; if (start_y != 0) line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset; @@ -3571,11 +3412,9 @@ static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand } } } - -// STOP_TIMER("correlate") } -static void correlate(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int inverse, int use_median){ +static void correlate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){ const int w= b->width; const int h= b->height; int x,y; @@ -3599,8 +3438,21 @@ static void correlate(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int } } -static void encode_header(SnowContext *s){ +static void encode_qlogs(SnowContext *s){ int plane_index, level, orientation; + + for(plane_index=0; plane_index<2; plane_index++){ + for(level=0; level<s->spatial_decomposition_count; level++){ + for(orientation=level ? 1:0; orientation<4; orientation++){ + if(orientation==2) continue; + put_symbol(&s->c, s->header_state, s->plane[plane_index].band[level][orientation].qlog, 1); + } + } + } +} + +static void encode_header(SnowContext *s){ + int plane_index, i; uint8_t kstate[32]; memset(kstate, MID_STATE, sizeof(kstate)); @@ -3613,6 +3465,12 @@ static void encode_header(SnowContext *s){ s->last_qbias= s->last_mv_scale= s->last_block_max_depth= 0; + for(plane_index=0; plane_index<2; plane_index++){ + Plane *p= &s->plane[plane_index]; + p->last_htaps=0; + p->last_diag_mc=0; + memset(p->last_hcoeff, 0, sizeof(p->last_hcoeff)); + } } if(s->keyframe){ put_symbol(&s->c, s->header_state, s->version, 0); @@ -3627,30 +3485,81 @@ static void encode_header(SnowContext *s){ // put_rac(&s->c, s->header_state, s->rate_scalability); put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0); + encode_qlogs(s); + } + + if(!s->keyframe){ + int update_mc=0; for(plane_index=0; plane_index<2; plane_index++){ - for(level=0; level<s->spatial_decomposition_count; level++){ - for(orientation=level ? 1:0; orientation<4; orientation++){ - if(orientation==2) continue; - put_symbol(&s->c, s->header_state, s->plane[plane_index].band[level][orientation].qlog, 1); - } + Plane *p= &s->plane[plane_index]; + update_mc |= p->last_htaps != p->htaps; + update_mc |= p->last_diag_mc != p->diag_mc; + update_mc |= !!memcmp(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff)); + } + put_rac(&s->c, s->header_state, update_mc); + if(update_mc){ + for(plane_index=0; plane_index<2; plane_index++){ + Plane *p= &s->plane[plane_index]; + put_rac(&s->c, s->header_state, p->diag_mc); + put_symbol(&s->c, s->header_state, p->htaps/2-1, 0); + for(i= p->htaps/2; i; i--) + put_symbol(&s->c, s->header_state, FFABS(p->hcoeff[i]), 0); } } + if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){ + put_rac(&s->c, s->header_state, 1); + put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0); + encode_qlogs(s); + }else + put_rac(&s->c, s->header_state, 0); } + put_symbol(&s->c, s->header_state, s->spatial_decomposition_type - s->last_spatial_decomposition_type, 1); put_symbol(&s->c, s->header_state, s->qlog - s->last_qlog , 1); put_symbol(&s->c, s->header_state, s->mv_scale - s->last_mv_scale, 1); put_symbol(&s->c, s->header_state, s->qbias - s->last_qbias , 1); put_symbol(&s->c, s->header_state, s->block_max_depth - s->last_block_max_depth, 1); - s->last_spatial_decomposition_type= s->spatial_decomposition_type; - s->last_qlog = s->qlog; - s->last_qbias = s->qbias; - s->last_mv_scale = s->mv_scale; - s->last_block_max_depth = s->block_max_depth; } -static int decode_header(SnowContext *s){ +static void update_last_header_values(SnowContext *s){ + int plane_index; + + if(!s->keyframe){ + for(plane_index=0; plane_index<2; plane_index++){ + Plane *p= &s->plane[plane_index]; + p->last_diag_mc= p->diag_mc; + p->last_htaps = p->htaps; + memcpy(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff)); + } + } + + s->last_spatial_decomposition_type = s->spatial_decomposition_type; + s->last_qlog = s->qlog; + s->last_qbias = s->qbias; + s->last_mv_scale = s->mv_scale; + s->last_block_max_depth = s->block_max_depth; + s->last_spatial_decomposition_count = s->spatial_decomposition_count; +} + +static void decode_qlogs(SnowContext *s){ int plane_index, level, orientation; + + for(plane_index=0; plane_index<3; plane_index++){ + for(level=0; level<s->spatial_decomposition_count; level++){ + for(orientation=level ? 1:0; orientation<4; orientation++){ + int q; + if (plane_index==2) q= s->plane[1].band[level][orientation].qlog; + else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog; + else q= get_symbol(&s->c, s->header_state, 1); + s->plane[plane_index].band[level][orientation].qlog= q; + } + } + } +} + +static int decode_header(SnowContext *s){ + int plane_index; uint8_t kstate[32]; memset(kstate, MID_STATE, sizeof(kstate)); @@ -3681,21 +3590,37 @@ static int decode_header(SnowContext *s){ // s->rate_scalability= get_rac(&s->c, s->header_state); s->max_ref_frames= get_symbol(&s->c, s->header_state, 0)+1; - for(plane_index=0; plane_index<3; plane_index++){ - for(level=0; level<s->spatial_decomposition_count; level++){ - for(orientation=level ? 1:0; orientation<4; orientation++){ - int q; - if (plane_index==2) q= s->plane[1].band[level][orientation].qlog; - else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog; - else q= get_symbol(&s->c, s->header_state, 1); - s->plane[plane_index].band[level][orientation].qlog= q; + decode_qlogs(s); + } + + if(!s->keyframe){ + if(get_rac(&s->c, s->header_state)){ + for(plane_index=0; plane_index<2; plane_index++){ + int htaps, i, sum=0; + Plane *p= &s->plane[plane_index]; + p->diag_mc= get_rac(&s->c, s->header_state); + htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2; + if((unsigned)htaps > HTAPS_MAX || htaps==0) + return -1; + p->htaps= htaps; + for(i= htaps/2; i; i--){ + p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1)); + sum += p->hcoeff[i]; } + p->hcoeff[0]= 32-sum; } + s->plane[2].diag_mc= s->plane[1].diag_mc; + s->plane[2].htaps = s->plane[1].htaps; + memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff)); + } + if(get_rac(&s->c, s->header_state)){ + s->spatial_decomposition_count= get_symbol(&s->c, s->header_state, 0); + decode_qlogs(s); } } s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1); - if(s->spatial_decomposition_type > 2){ + if(s->spatial_decomposition_type > 1){ av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported", s->spatial_decomposition_type); return -1; } @@ -3726,7 +3651,6 @@ static void init_qexp(void){ static int common_init(AVCodecContext *avctx){ SnowContext *s = avctx->priv_data; int width, height; - int level, orientation, plane_index, dec; int i, j; s->avctx= avctx; @@ -3774,21 +3698,26 @@ static int common_init(AVCodecContext *avctx){ if(!qexp[0]) init_qexp(); - dec= s->spatial_decomposition_count= 5; - s->spatial_decomposition_type= avctx->prediction_method; //FIXME add decorrelator type r transform_type - - s->chroma_h_shift= 1; //FIXME XXX - s->chroma_v_shift= 1; - // dec += FFMAX(s->chroma_h_shift, s->chroma_v_shift); width= s->avctx->width; height= s->avctx->height; - s->spatial_dwt_buffer= av_mallocz(width*height*sizeof(DWTELEM)); + s->spatial_idwt_buffer= av_mallocz(width*height*sizeof(IDWTELEM)); + s->spatial_dwt_buffer= av_mallocz(width*height*sizeof(DWTELEM)); //FIXME this does not belong here + + for(i=0; i<MAX_REF_FRAMES; i++) + for(j=0; j<MAX_REF_FRAMES; j++) + scale_mv_ref[i][j] = 256*(i+1)/(j+1); + + s->avctx->get_buffer(s->avctx, &s->mconly_picture); - s->mv_scale= (s->avctx->flags & CODEC_FLAG_QPEL) ? 2 : 4; - s->block_max_depth= (s->avctx->flags & CODEC_FLAG_4MV) ? 1 : 0; + return 0; +} + +static int common_init_after_header(AVCodecContext *avctx){ + SnowContext *s = avctx->priv_data; + int plane_index, level, orientation; for(plane_index=0; plane_index<3; plane_index++){ int w= s->avctx->width; @@ -3800,7 +3729,7 @@ static int common_init(AVCodecContext *avctx){ } s->plane[plane_index].width = w; s->plane[plane_index].height= h; -//av_log(NULL, AV_LOG_DEBUG, "%d %d\n", w, h); + for(level=s->spatial_decomposition_count-1; level>=0; level--){ for(orientation=level ? 1 : 0; orientation<4; orientation++){ SubBand *b= &s->plane[plane_index].band[level][orientation]; @@ -3823,9 +3752,12 @@ static int common_init(AVCodecContext *avctx){ b->buf += b->stride>>1; b->buf_y_offset = b->stride_line >> 1; } + b->ibuf= s->spatial_idwt_buffer + (b->buf - s->spatial_dwt_buffer); if(level) b->parent= &s->plane[plane_index].band[level-1][orientation]; + //FIXME avoid this realloc + av_freep(&b->x_coeff); b->x_coeff=av_mallocz(((b->width+1) * b->height+1)*sizeof(x_and_coeff)); } w= (w+1)>>1; @@ -3833,19 +3765,6 @@ static int common_init(AVCodecContext *avctx){ } } - for(i=0; i<MAX_REF_FRAMES; i++) - for(j=0; j<MAX_REF_FRAMES; j++) - scale_mv_ref[i][j] = 256*(i+1)/(j+1); - - reset_contexts(s); -/* - width= s->width= avctx->width; - height= s->height= avctx->height; - - assert(width && height); -*/ - s->avctx->get_buffer(s->avctx, &s->mconly_picture); - return 0; } @@ -3856,7 +3775,7 @@ static int qscale2qlog(int qscale){ static int ratecontrol_1pass(SnowContext *s, AVFrame *pict) { - /* estimate the frame's complexity as a sum of weighted dwt coefs. + /* Estimate the frame's complexity as a sum of weighted dwt coefficients. * FIXME we know exact mv bits at this point, * but ratecontrol isn't set up to include them. */ uint32_t coef_sum= 0; @@ -3865,7 +3784,7 @@ static int ratecontrol_1pass(SnowContext *s, AVFrame *pict) for(level=0; level<s->spatial_decomposition_count; level++){ for(orientation=level ? 1 : 0; orientation<4; orientation++){ SubBand *b= &s->plane[0].band[level][orientation]; - DWTELEM *buf= b->buf; + IDWTELEM *buf= b->ibuf; const int w= b->width; const int h= b->height; const int stride= b->stride; @@ -3873,13 +3792,15 @@ static int ratecontrol_1pass(SnowContext *s, AVFrame *pict) const int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); const int qdiv= (1<<16)/qmul; int x, y; + //FIXME this is ugly + for(y=0; y<h; y++) + for(x=0; x<w; x++) + buf[x+y*stride]= b->buf[x+y*stride]; if(orientation==0) decorrelate(s, b, buf, stride, 1, 0); for(y=0; y<h; y++) for(x=0; x<w; x++) coef_sum+= abs(buf[x+y*stride]) * qdiv >> 16; - if(orientation==0) - correlate(s, b, buf, stride, 1, 0); } } @@ -3904,7 +3825,7 @@ static int ratecontrol_1pass(SnowContext *s, AVFrame *pict) return delta_qlog; } -static void calculate_vissual_weight(SnowContext *s, Plane *p){ +static void calculate_visual_weight(SnowContext *s, Plane *p){ int width = p->width; int height= p->height; int level, orientation, x, y; @@ -3912,43 +3833,176 @@ static void calculate_vissual_weight(SnowContext *s, Plane *p){ for(level=0; level<s->spatial_decomposition_count; level++){ for(orientation=level ? 1 : 0; orientation<4; orientation++){ SubBand *b= &p->band[level][orientation]; - DWTELEM *buf= b->buf; + IDWTELEM *ibuf= b->ibuf; int64_t error=0; - memset(s->spatial_dwt_buffer, 0, sizeof(int)*width*height); - buf[b->width/2 + b->height/2*b->stride]= 256*256; - ff_spatial_idwt(s->spatial_dwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count); + memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height); + ibuf[b->width/2 + b->height/2*b->stride]= 256*16; + ff_spatial_idwt(s->spatial_idwt_buffer, width, height, width, s->spatial_decomposition_type, s->spatial_decomposition_count); for(y=0; y<height; y++){ for(x=0; x<width; x++){ - int64_t d= s->spatial_dwt_buffer[x + y*width]; + int64_t d= s->spatial_idwt_buffer[x + y*width]*16; error += d*d; } } b->qlog= (int)(log(352256.0/sqrt(error)) / log(pow(2.0, 1.0/QROOT))+0.5); -// av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", level, orientation, b->qlog/*, sqrt(error)*/); } } } +#define QUANTIZE2 0 + +#if QUANTIZE2==1 +#define Q2_STEP 8 + +static void find_sse(SnowContext *s, Plane *p, int *score, int score_stride, IDWTELEM *r0, IDWTELEM *r1, int level, int orientation){ + SubBand *b= &p->band[level][orientation]; + int x, y; + int xo=0; + int yo=0; + int step= 1 << (s->spatial_decomposition_count - level); + + if(orientation&1) + xo= step>>1; + if(orientation&2) + yo= step>>1; + + //FIXME bias for nonzero ? + //FIXME optimize + memset(score, 0, sizeof(*score)*score_stride*((p->height + Q2_STEP-1)/Q2_STEP)); + for(y=0; y<p->height; y++){ + for(x=0; x<p->width; x++){ + int sx= (x-xo + step/2) / step / Q2_STEP; + int sy= (y-yo + step/2) / step / Q2_STEP; + int v= r0[x + y*p->width] - r1[x + y*p->width]; + assert(sx>=0 && sy>=0 && sx < score_stride); + v= ((v+8)>>4)<<4; + score[sx + sy*score_stride] += v*v; + assert(score[sx + sy*score_stride] >= 0); + } + } +} + +static void dequantize_all(SnowContext *s, Plane *p, IDWTELEM *buffer, int width, int height){ + int level, orientation; + + for(level=0; level<s->spatial_decomposition_count; level++){ + for(orientation=level ? 1 : 0; orientation<4; orientation++){ + SubBand *b= &p->band[level][orientation]; + IDWTELEM *dst= buffer + (b->ibuf - s->spatial_idwt_buffer); + + dequantize(s, b, dst, b->stride); + } + } +} + +static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, int height, int stride, int type){ + int level, orientation, ys, xs, x, y, pass; + IDWTELEM best_dequant[height * stride]; + IDWTELEM idwt2_buffer[height * stride]; + const int score_stride= (width + 10)/Q2_STEP; + int best_score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size + int score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size + int threshold= (s->m.lambda * s->m.lambda) >> 6; + + //FIXME pass the copy cleanly ? + +// memcpy(dwt_buffer, buffer, height * stride * sizeof(DWTELEM)); + ff_spatial_dwt(buffer, width, height, stride, type, s->spatial_decomposition_count); + + for(level=0; level<s->spatial_decomposition_count; level++){ + for(orientation=level ? 1 : 0; orientation<4; orientation++){ + SubBand *b= &p->band[level][orientation]; + IDWTELEM *dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer); + DWTELEM *src= buffer + (b-> buf - s->spatial_dwt_buffer); + assert(src == b->buf); // code does not depend on this but it is true currently + + quantize(s, b, dst, src, b->stride, s->qbias); + } + } + for(pass=0; pass<1; pass++){ + if(s->qbias == 0) //keyframe + continue; + for(level=0; level<s->spatial_decomposition_count; level++){ + for(orientation=level ? 1 : 0; orientation<4; orientation++){ + SubBand *b= &p->band[level][orientation]; + IDWTELEM *dst= idwt2_buffer + (b->ibuf - s->spatial_idwt_buffer); + IDWTELEM *best_dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer); + + for(ys= 0; ys<Q2_STEP; ys++){ + for(xs= 0; xs<Q2_STEP; xs++){ + memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); + dequantize_all(s, p, idwt2_buffer, width, height); + ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count); + find_sse(s, p, best_score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation); + memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); + for(y=ys; y<b->height; y+= Q2_STEP){ + for(x=xs; x<b->width; x+= Q2_STEP){ + if(dst[x + y*b->stride]<0) dst[x + y*b->stride]++; + if(dst[x + y*b->stride]>0) dst[x + y*b->stride]--; + //FIXME try more than just -- + } + } + dequantize_all(s, p, idwt2_buffer, width, height); + ff_spatial_idwt(idwt2_buffer, width, height, stride, type, s->spatial_decomposition_count); + find_sse(s, p, score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation); + for(y=ys; y<b->height; y+= Q2_STEP){ + for(x=xs; x<b->width; x+= Q2_STEP){ + int score_idx= x/Q2_STEP + (y/Q2_STEP)*score_stride; + if(score[score_idx] <= best_score[score_idx] + threshold){ + best_score[score_idx]= score[score_idx]; + if(best_dst[x + y*b->stride]<0) best_dst[x + y*b->stride]++; + if(best_dst[x + y*b->stride]>0) best_dst[x + y*b->stride]--; + //FIXME copy instead + } + } + } + } + } + } + } + } + memcpy(s->spatial_idwt_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); //FIXME work with that directly instead of copy at the end +} + +#endif /* QUANTIZE2==1 */ + static int encode_init(AVCodecContext *avctx) { SnowContext *s = avctx->priv_data; int plane_index; if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ - av_log(avctx, AV_LOG_ERROR, "this codec is under development, files encoded with it may not be decodable with future versions!!!\n" - "use vstrict=-2 / -strict -2 to use it anyway\n"); + av_log(avctx, AV_LOG_ERROR, "This codec is under development, files encoded with it may not be decodable with future versions!!!\n" + "Use vstrict=-2 / -strict -2 to use it anyway.\n"); return -1; } if(avctx->prediction_method == DWT_97 && (avctx->flags & CODEC_FLAG_QSCALE) && avctx->global_quality == 0){ - av_log(avctx, AV_LOG_ERROR, "the 9/7 wavelet is incompatible with lossless mode\n"); + av_log(avctx, AV_LOG_ERROR, "The 9/7 wavelet is incompatible with lossless mode.\n"); return -1; } + s->spatial_decomposition_type= avctx->prediction_method; //FIXME add decorrelator type r transform_type + + s->chroma_h_shift= 1; //FIXME XXX + s->chroma_v_shift= 1; + + s->mv_scale = (avctx->flags & CODEC_FLAG_QPEL) ? 2 : 4; + s->block_max_depth= (avctx->flags & CODEC_FLAG_4MV ) ? 1 : 0; + + for(plane_index=0; plane_index<3; plane_index++){ + s->plane[plane_index].diag_mc= 1; + s->plane[plane_index].htaps= 6; + s->plane[plane_index].hcoeff[0]= 40; + s->plane[plane_index].hcoeff[1]= -10; + s->plane[plane_index].hcoeff[2]= 2; + s->plane[plane_index].fast_mc= 1; + } + common_init(avctx); alloc_blocks(s); @@ -3976,11 +4030,6 @@ static int encode_init(AVCodecContext *avctx) } s->pass1_rc= !(avctx->flags & (CODEC_FLAG_QSCALE|CODEC_FLAG_PASS2)); - for(plane_index=0; plane_index<3; plane_index++){ - calculate_vissual_weight(s, &s->plane[plane_index]); - } - - avctx->coded_frame= &s->current_picture; switch(avctx->pix_fmt){ // case PIX_FMT_YUV444P: @@ -3995,7 +4044,7 @@ static int encode_init(AVCodecContext *avctx) s->colorspace= 1; break;*/ default: - av_log(avctx, AV_LOG_ERROR, "format not supported\n"); + av_log(avctx, AV_LOG_ERROR, "pixel format not supported\n"); return -1; } // avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); @@ -4019,6 +4068,52 @@ static int encode_init(AVCodecContext *avctx) return 0; } +#define USE_HALFPEL_PLANE 0 + +static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){ + int p,x,y; + + assert(!(s->avctx->flags & CODEC_FLAG_EMU_EDGE)); + + for(p=0; p<3; p++){ + int is_chroma= !!p; + int w= s->avctx->width >>is_chroma; + int h= s->avctx->height >>is_chroma; + int ls= frame->linesize[p]; + uint8_t *src= frame->data[p]; + + halfpel[1][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls); + halfpel[2][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls); + halfpel[3][p]= (uint8_t*)av_malloc(ls * (h+2*EDGE_WIDTH)) + EDGE_WIDTH*(1+ls); + + halfpel[0][p]= src; + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + int i= y*ls + x; + + halfpel[1][p][i]= (20*(src[i] + src[i+1]) - 5*(src[i-1] + src[i+2]) + (src[i-2] + src[i+3]) + 16 )>>5; + } + } + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + int i= y*ls + x; + + halfpel[2][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5; + } + } + src= halfpel[1][p]; + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + int i= y*ls + x; + + halfpel[3][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5; + } + } + +//FIXME border! + } +} + static int frame_start(SnowContext *s){ AVFrame tmp; int w= s->avctx->width; //FIXME round up to x16 ? @@ -4032,6 +4127,9 @@ static int frame_start(SnowContext *s){ tmp= s->last_picture[s->max_ref_frames-1]; memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame)); + memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4); + if(USE_HALFPEL_PLANE && s->current_picture.data[0]) + halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture); s->last_picture[0]= s->current_picture; s->current_picture= tmp; @@ -4103,7 +4201,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, if(s->qlog < 0 || (!pict->quality && (avctx->flags & CODEC_FLAG_QSCALE))){ s->qlog= LOSSLESS_QLOG; s->lambda = 0; - }//else keep previous frame's qlog until after motion est + }//else keep previous frame's qlog until after motion estimation frame_start(s); @@ -4157,9 +4255,22 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, redo_frame: + if(pict->pict_type == I_TYPE) + s->spatial_decomposition_count= 5; + else + s->spatial_decomposition_count= 5; + s->m.pict_type = pict->pict_type; s->qbias= pict->pict_type == P_TYPE ? 2 : 0; + common_init_after_header(avctx); + + if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){ + for(plane_index=0; plane_index<3; plane_index++){ + calculate_visual_weight(s, &s->plane[plane_index]); + } + } + encode_header(s); s->m.misc_bits = 8*(s->c.bytestream - s->c.bytestream_start); encode_blocks(s, 1); @@ -4172,87 +4283,94 @@ redo_frame: int x, y; // int bits= put_bits_count(&s->c.pb); - if(!(avctx->flags2 & CODEC_FLAG2_MEMC_ONLY)){ - //FIXME optimize - if(pict->data[plane_index]) //FIXME gray hack - for(y=0; y<h; y++){ - for(x=0; x<w; x++){ - s->spatial_dwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<FRAC_BITS; + if(!(avctx->flags2 & CODEC_FLAG2_MEMC_ONLY)){ + //FIXME optimize + if(pict->data[plane_index]) //FIXME gray hack + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + s->spatial_idwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<FRAC_BITS; + } + } + predict_plane(s, s->spatial_idwt_buffer, plane_index, 0); + + if( plane_index==0 + && pict->pict_type == P_TYPE + && !(avctx->flags&CODEC_FLAG_PASS2) + && s->m.me.scene_change_score > s->avctx->scenechange_threshold){ + ff_init_range_encoder(c, buf, buf_size); + ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); + pict->pict_type= FF_I_TYPE; + s->keyframe=1; + s->current_picture.key_frame=1; + goto redo_frame; } - } - predict_plane(s, s->spatial_dwt_buffer, plane_index, 0); - - if( plane_index==0 - && pict->pict_type == P_TYPE - && !(avctx->flags&CODEC_FLAG_PASS2) - && s->m.me.scene_change_score > s->avctx->scenechange_threshold){ - ff_init_range_encoder(c, buf, buf_size); - ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); - pict->pict_type= FF_I_TYPE; - s->keyframe=1; - s->current_picture.key_frame=1; - goto redo_frame; - } - if(s->qlog == LOSSLESS_QLOG){ - for(y=0; y<h; y++){ - for(x=0; x<w; x++){ - s->spatial_dwt_buffer[y*w + x]= (s->spatial_dwt_buffer[y*w + x] + (1<<(FRAC_BITS-1))-1)>>FRAC_BITS; + if(s->qlog == LOSSLESS_QLOG){ + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + s->spatial_dwt_buffer[y*w + x]= (s->spatial_idwt_buffer[y*w + x] + (1<<(FRAC_BITS-1))-1)>>FRAC_BITS; + } + } + }else{ + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + s->spatial_dwt_buffer[y*w + x]=s->spatial_idwt_buffer[y*w + x]<<ENCODER_EXTRA_BITS; + } } } - } - - ff_spatial_dwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); - if(s->pass1_rc && plane_index==0){ - int delta_qlog = ratecontrol_1pass(s, pict); - if (delta_qlog <= INT_MIN) - return -1; - if(delta_qlog){ - //reordering qlog in the bitstream would eliminate this reset - ff_init_range_encoder(c, buf, buf_size); - memcpy(s->header_state, rc_header_bak, sizeof(s->header_state)); - memcpy(s->block_state, rc_block_bak, sizeof(s->block_state)); - encode_header(s); - encode_blocks(s, 0); + /* if(QUANTIZE2) + dwt_quantize(s, p, s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type); + else*/ + ff_spatial_dwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); + + if(s->pass1_rc && plane_index==0){ + int delta_qlog = ratecontrol_1pass(s, pict); + if (delta_qlog <= INT_MIN) + return -1; + if(delta_qlog){ + //reordering qlog in the bitstream would eliminate this reset + ff_init_range_encoder(c, buf, buf_size); + memcpy(s->header_state, rc_header_bak, sizeof(s->header_state)); + memcpy(s->block_state, rc_block_bak, sizeof(s->block_state)); + encode_header(s); + encode_blocks(s, 0); + } } - } - - for(level=0; level<s->spatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - quantize(s, b, b->buf, b->stride, s->qbias); - if(orientation==0) - decorrelate(s, b, b->buf, b->stride, pict->pict_type == P_TYPE, 0); - encode_subband(s, b, b->buf, b->parent ? b->parent->buf : NULL, b->stride, orientation); - assert(b->parent==NULL || b->parent->stride == b->stride*2); - if(orientation==0) - correlate(s, b, b->buf, b->stride, 1, 0); + for(level=0; level<s->spatial_decomposition_count; level++){ + for(orientation=level ? 1 : 0; orientation<4; orientation++){ + SubBand *b= &p->band[level][orientation]; + + if(!QUANTIZE2) + quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias); + if(orientation==0) + decorrelate(s, b, b->ibuf, b->stride, pict->pict_type == P_TYPE, 0); + encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation); + assert(b->parent==NULL || b->parent->stride == b->stride*2); + if(orientation==0) + correlate(s, b, b->ibuf, b->stride, 1, 0); + } } - } -// av_log(NULL, AV_LOG_DEBUG, "plane:%d bits:%d\n", plane_index, put_bits_count(&s->c.pb) - bits); - for(level=0; level<s->spatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; + for(level=0; level<s->spatial_decomposition_count; level++){ + for(orientation=level ? 1 : 0; orientation<4; orientation++){ + SubBand *b= &p->band[level][orientation]; - dequantize(s, b, b->buf, b->stride); + dequantize(s, b, b->ibuf, b->stride); + } } - } - ff_spatial_idwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); - if(s->qlog == LOSSLESS_QLOG){ - for(y=0; y<h; y++){ - for(x=0; x<w; x++){ - s->spatial_dwt_buffer[y*w + x]<<=FRAC_BITS; + ff_spatial_idwt(s->spatial_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count); + if(s->qlog == LOSSLESS_QLOG){ + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + s->spatial_idwt_buffer[y*w + x]<<=FRAC_BITS; + } } } - } -{START_TIMER - predict_plane(s, s->spatial_dwt_buffer, plane_index, 1); -STOP_TIMER("pred-conv")} - }else{ + predict_plane(s, s->spatial_idwt_buffer, plane_index, 1); + }else{ //ME/MC only if(pict->pict_type == I_TYPE){ for(y=0; y<h; y++){ @@ -4262,27 +4380,34 @@ STOP_TIMER("pred-conv")} } } }else{ - memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h); - predict_plane(s, s->spatial_dwt_buffer, plane_index, 1); + memset(s->spatial_idwt_buffer, 0, sizeof(IDWTELEM)*w*h); + predict_plane(s, s->spatial_idwt_buffer, plane_index, 1); } - } + } if(s->avctx->flags&CODEC_FLAG_PSNR){ int64_t error= 0; - if(pict->data[plane_index]) //FIXME gray hack - for(y=0; y<h; y++){ - for(x=0; x<w; x++){ - int d= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x]; - error += d*d; + if(pict->data[plane_index]) //FIXME gray hack + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + int d= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x]; + error += d*d; + } } - } s->avctx->error[plane_index] += error; s->current_picture.error[plane_index] = error; } + } - if(s->last_picture[s->max_ref_frames-1].data[0]) + update_last_header_values(s); + + if(s->last_picture[s->max_ref_frames-1].data[0]){ avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]); + for(i=0; i<9; i++) + if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3]) + av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3])); + } s->current_picture.coded_picture_number = avctx->frame_number; s->current_picture.pict_type = pict->pict_type; @@ -4313,6 +4438,7 @@ static void common_end(SnowContext *s){ int plane_index, level, orientation, i; av_freep(&s->spatial_dwt_buffer); + av_freep(&s->spatial_idwt_buffer); av_freep(&s->m.me.scratchpad); av_freep(&s->m.me.map); @@ -4351,35 +4477,43 @@ static int encode_end(AVCodecContext *avctx) static int decode_init(AVCodecContext *avctx) { - SnowContext *s = avctx->priv_data; - int block_size; - avctx->pix_fmt= PIX_FMT_YUV420P; common_init(avctx); - block_size = MB_SIZE >> s->block_max_depth; - slice_buffer_init(&s->sb, s->plane[0].height, (block_size) + (s->spatial_decomposition_count * (s->spatial_decomposition_count + 3)) + 1, s->plane[0].width, s->spatial_dwt_buffer); - return 0; } -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){ +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size){ SnowContext *s = avctx->priv_data; RangeCoder * const c= &s->c; int bytes_read; AVFrame *picture = data; - int level, orientation, plane_index; + int level, orientation, plane_index, i; ff_init_range_decoder(c, buf, buf_size); ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); s->current_picture.pict_type= FF_I_TYPE; //FIXME I vs. P - decode_header(s); + if(decode_header(s)<0) + return -1; + common_init_after_header(avctx); + + // realloc slice buffer for the case that spatial_decomposition_count changed + slice_buffer_destroy(&s->sb); + slice_buffer_init(&s->sb, s->plane[0].height, (MB_SIZE >> s->block_max_depth) + s->spatial_decomposition_count * 8 + 1, s->plane[0].width, s->spatial_idwt_buffer); + + for(plane_index=0; plane_index<3; plane_index++){ + Plane *p= &s->plane[plane_index]; + p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40 + && p->hcoeff[1]==-10 + && p->hcoeff[2]==2; + } + if(!s->block) alloc_blocks(s); frame_start(s); - //keyframe flag dupliaction mess FIXME + //keyframe flag duplication mess FIXME if(avctx->debug&FF_DEBUG_PICT_INFO) av_log(avctx, AV_LOG_ERROR, "keyframe:%d qlog:%d\n", s->keyframe, s->qlog); @@ -4392,122 +4526,118 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 int x, y; int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */ -if(s->avctx->debug&2048){ - memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h); - predict_plane(s, s->spatial_dwt_buffer, plane_index, 1); + if(s->avctx->debug&2048){ + memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h); + predict_plane(s, s->spatial_idwt_buffer, plane_index, 1); - for(y=0; y<h; y++){ - for(x=0; x<w; x++){ - int v= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]; - s->mconly_picture.data[plane_index][y*s->mconly_picture.linesize[plane_index] + x]= v; + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + int v= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]; + s->mconly_picture.data[plane_index][y*s->mconly_picture.linesize[plane_index] + x]= v; + } } } -} - -{ START_TIMER - for(level=0; level<s->spatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - SubBand *b= &p->band[level][orientation]; - unpack_coeffs(s, b, b->parent, orientation); - } - } - STOP_TIMER("unpack coeffs"); -} - -{START_TIMER - const int mb_h= s->b_height << s->block_max_depth; - const int block_size = MB_SIZE >> s->block_max_depth; - const int block_w = plane_index ? block_size/2 : block_size; - int mb_y; - dwt_compose_t cs[MAX_DECOMPOSITIONS]; - int yd=0, yq=0; - int y; - int end_y; - - ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count); - for(mb_y=0; mb_y<=mb_h; mb_y++){ - - int slice_starty = block_w*mb_y; - int slice_h = block_w*(mb_y+1); - if (!(s->keyframe || s->avctx->debug&512)){ - slice_starty = FFMAX(0, slice_starty - (block_w >> 1)); - slice_h -= (block_w >> 1); - } { - START_TIMER for(level=0; level<s->spatial_decomposition_count; level++){ for(orientation=level ? 1 : 0; orientation<4; orientation++){ SubBand *b= &p->band[level][orientation]; - int start_y; - int end_y; - int our_mb_start = mb_y; - int our_mb_end = (mb_y + 1); - const int extra= 3; - start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0); - end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra); - if (!(s->keyframe || s->avctx->debug&512)){ - start_y = FFMAX(0, start_y - (block_w >> (1+s->spatial_decomposition_count - level))); - end_y = FFMAX(0, end_y - (block_w >> (1+s->spatial_decomposition_count - level))); - } - start_y = FFMIN(b->height, start_y); - end_y = FFMIN(b->height, end_y); - - if (start_y != end_y){ - if (orientation == 0){ - SubBand * correlate_band = &p->band[0][0]; - int correlate_end_y = FFMIN(b->height, end_y + 1); - int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0)); - decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]); - correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->buf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y); - dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->buf, correlate_band->stride, start_y, end_y); - } - else - decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]); - } + unpack_coeffs(s, b, b->parent, orientation); } } - STOP_TIMER("decode_subband_slice"); } -{ START_TIMER - for(; yd<slice_h; yd+=4){ - ff_spatial_idwt_buffered_slice(&s->dsp, cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd); - } - STOP_TIMER("idwt slice");} + { + const int mb_h= s->b_height << s->block_max_depth; + const int block_size = MB_SIZE >> s->block_max_depth; + const int block_w = plane_index ? block_size/2 : block_size; + int mb_y; + dwt_compose_t cs[MAX_DECOMPOSITIONS]; + int yd=0, yq=0; + int y; + int end_y; + ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count); + for(mb_y=0; mb_y<=mb_h; mb_y++){ - if(s->qlog == LOSSLESS_QLOG){ - for(; yq<slice_h && yq<h; yq++){ - DWTELEM * line = slice_buffer_get_line(&s->sb, yq); - for(x=0; x<w; x++){ - line[x] <<= FRAC_BITS; + int slice_starty = block_w*mb_y; + int slice_h = block_w*(mb_y+1); + if (!(s->keyframe || s->avctx->debug&512)){ + slice_starty = FFMAX(0, slice_starty - (block_w >> 1)); + slice_h -= (block_w >> 1); + } + + for(level=0; level<s->spatial_decomposition_count; level++){ + for(orientation=level ? 1 : 0; orientation<4; orientation++){ + SubBand *b= &p->band[level][orientation]; + int start_y; + int end_y; + int our_mb_start = mb_y; + int our_mb_end = (mb_y + 1); + const int extra= 3; + start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0); + end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra); + if (!(s->keyframe || s->avctx->debug&512)){ + start_y = FFMAX(0, start_y - (block_w >> (1+s->spatial_decomposition_count - level))); + end_y = FFMAX(0, end_y - (block_w >> (1+s->spatial_decomposition_count - level))); + } + start_y = FFMIN(b->height, start_y); + end_y = FFMIN(b->height, end_y); + + if (start_y != end_y){ + if (orientation == 0){ + SubBand * correlate_band = &p->band[0][0]; + int correlate_end_y = FFMIN(b->height, end_y + 1); + int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0)); + decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]); + correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y); + dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, start_y, end_y); + } + else + decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]); + } } } - } - predict_slice_buffered(s, &s->sb, s->spatial_dwt_buffer, plane_index, 1, mb_y); + for(; yd<slice_h; yd+=4){ + ff_spatial_idwt_buffered_slice(&s->dsp, cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd); + } - y = FFMIN(p->height, slice_starty); - end_y = FFMIN(p->height, slice_h); - while(y < end_y) - slice_buffer_release(&s->sb, y++); - } + if(s->qlog == LOSSLESS_QLOG){ + for(; yq<slice_h && yq<h; yq++){ + IDWTELEM * line = slice_buffer_get_line(&s->sb, yq); + for(x=0; x<w; x++){ + line[x] <<= FRAC_BITS; + } + } + } + + predict_slice_buffered(s, &s->sb, s->spatial_idwt_buffer, plane_index, 1, mb_y); - slice_buffer_flush(&s->sb); + y = FFMIN(p->height, slice_starty); + end_y = FFMIN(p->height, slice_h); + while(y < end_y) + slice_buffer_release(&s->sb, y++); + } + + slice_buffer_flush(&s->sb); + } -STOP_TIMER("idwt + predict_slices")} } emms_c(); - if(s->last_picture[s->max_ref_frames-1].data[0]) + if(s->last_picture[s->max_ref_frames-1].data[0]){ avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]); + for(i=0; i<9; i++) + if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3]) + av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3])); + } -if(!(s->avctx->debug&2048)) - *picture= s->current_picture; -else - *picture= s->mconly_picture; + if(!(s->avctx->debug&2048)) + *picture= s->current_picture; + else + *picture= s->mconly_picture; *data_size = sizeof(AVFrame); @@ -4541,7 +4671,7 @@ AVCodec snow_decoder = { NULL }; -#ifdef CONFIG_ENCODERS +#ifdef CONFIG_SNOW_ENCODER AVCodec snow_encoder = { "snow", CODEC_TYPE_VIDEO, @@ -4554,12 +4684,13 @@ AVCodec snow_encoder = { #endif -#if 0 +#ifdef TEST #undef malloc #undef free #undef printf +#undef random -int main(){ +int main(void){ int width=256; int height=256; int buffer[2][width*height]; @@ -4596,9 +4727,7 @@ int main(){ ff_init_cabac_states(&s.c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); for(i=-256; i<256; i++){ -START_TIMER put_symbol(&s.c, s.header_state, i*i*i/3*FFABS(i), 1); -STOP_TIMER("put_symbol") } ff_rac_terminate(&s.c); @@ -4608,62 +4737,59 @@ STOP_TIMER("put_symbol") for(i=-256; i<256; i++){ int j; -START_TIMER j= get_symbol(&s.c, s.header_state, 1); -STOP_TIMER("get_symbol") if(j!=i*i*i/3*FFABS(i)) printf("fsck: %d != %d\n", i, j); } #endif -{ -int level, orientation, x, y; -int64_t errors[8][4]; -int64_t g=0; - - memset(errors, 0, sizeof(errors)); - s.spatial_decomposition_count=3; - s.spatial_decomposition_type=0; - for(level=0; level<s.spatial_decomposition_count; level++){ - for(orientation=level ? 1 : 0; orientation<4; orientation++){ - int w= width >> (s.spatial_decomposition_count-level); - int h= height >> (s.spatial_decomposition_count-level); - int stride= width << (s.spatial_decomposition_count-level); - DWTELEM *buf= buffer[0]; - int64_t error=0; - - if(orientation&1) buf+=w; - if(orientation>1) buf+=stride>>1; + { + int level, orientation, x, y; + int64_t errors[8][4]; + int64_t g=0; - memset(buffer[0], 0, sizeof(int)*width*height); - buf[w/2 + h/2*stride]= 256*256; - ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); - for(y=0; y<height; y++){ - for(x=0; x<width; x++){ - int64_t d= buffer[0][x + y*width]; - error += d*d; - if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9 && level==2) printf("%8"PRId64" ", d); + memset(errors, 0, sizeof(errors)); + s.spatial_decomposition_count=3; + s.spatial_decomposition_type=0; + for(level=0; level<s.spatial_decomposition_count; level++){ + for(orientation=level ? 1 : 0; orientation<4; orientation++){ + int w= width >> (s.spatial_decomposition_count-level); + int h= height >> (s.spatial_decomposition_count-level); + int stride= width << (s.spatial_decomposition_count-level); + DWTELEM *buf= buffer[0]; + int64_t error=0; + + if(orientation&1) buf+=w; + if(orientation>1) buf+=stride>>1; + + memset(buffer[0], 0, sizeof(int)*width*height); + buf[w/2 + h/2*stride]= 256*256; + ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + for(y=0; y<height; y++){ + for(x=0; x<width; x++){ + int64_t d= buffer[0][x + y*width]; + error += d*d; + if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9 && level==2) printf("%8"PRId64" ", d); + } + if(FFABS(height/2-y)<9 && level==2) printf("\n"); } - if(FFABS(height/2-y)<9 && level==2) printf("\n"); + error= (int)(sqrt(error)+0.5); + errors[level][orientation]= error; + if(g) g=ff_gcd(g, error); + else g= error; } - error= (int)(sqrt(error)+0.5); - errors[level][orientation]= error; - if(g) g=ff_gcd(g, error); - else g= error; } - } - printf("static int const visual_weight[][4]={\n"); - for(level=0; level<s.spatial_decomposition_count; level++){ - printf(" {"); - for(orientation=0; orientation<4; orientation++){ - printf("%8"PRId64",", errors[level][orientation]/g); + printf("static int const visual_weight[][4]={\n"); + for(level=0; level<s.spatial_decomposition_count; level++){ + printf(" {"); + for(orientation=0; orientation<4; orientation++){ + printf("%8"PRId64",", errors[level][orientation]/g); + } + printf("},\n"); } - printf("},\n"); - } - printf("};\n"); - { + printf("};\n"); + { int level=2; - int orientation=3; int w= width >> (s.spatial_decomposition_count-level); - int h= height >> (s.spatial_decomposition_count-level); + //int h= height >> (s.spatial_decomposition_count-level); int stride= width << (s.spatial_decomposition_count-level); DWTELEM *buf= buffer[0]; int64_t error=0; @@ -4697,10 +4823,9 @@ int64_t g=0; } if(FFABS(height/2-y)<9) printf("\n"); } - } + } -} + } return 0; } -#endif - +#endif /* TEST */ diff --git a/contrib/ffmpeg/libavcodec/snow.h b/contrib/ffmpeg/libavcodec/snow.h index d75d6e3e0..e9b988986 100644 --- a/contrib/ffmpeg/libavcodec/snow.h +++ b/contrib/ffmpeg/libavcodec/snow.h @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _SNOW_H -#define _SNOW_H +#ifndef FFMPEG_SNOW_H +#define FFMPEG_SNOW_H #include "dsputil.h" @@ -31,7 +31,7 @@ #define QSHIFT 5 #define QROOT (1<<QSHIFT) #define LOSSLESS_QLOG -128 -#define FRAC_BITS 8 +#define FRAC_BITS 4 #define MAX_REF_FRAMES 8 #define LOG2_OBMC_MAX 8 @@ -39,21 +39,19 @@ #define DWT_97 0 #define DWT_53 1 -#define DWT_X 2 /** Used to minimize the amount of memory used in order to optimize cache performance. **/ struct slice_buffer_s { - DWTELEM * * line; ///< For use by idwt and predict_slices. - DWTELEM * * data_stack; ///< Used for internal purposes. + IDWTELEM * * line; ///< For use by idwt and predict_slices. + IDWTELEM * * data_stack; ///< Used for internal purposes. int data_stack_top; int line_count; int line_width; int data_count; - DWTELEM * base_buffer; ///< Buffer that this structure is caching. + IDWTELEM * base_buffer; ///< Buffer that this structure is caching. }; #define liftS lift -#define lift5 lift #if 1 #define W_AM 3 #define W_AO 0 @@ -123,8 +121,8 @@ struct slice_buffer_s { #define W_DS 9 #endif -extern void ff_snow_vertical_compose97i(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width); -extern void ff_snow_horizontal_compose97i(DWTELEM *b, int width); +extern void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width); +extern void ff_snow_horizontal_compose97i(IDWTELEM *b, int width); extern void ff_snow_inner_add_yblock(const 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); #ifdef CONFIG_SNOW_ENCODER @@ -137,7 +135,7 @@ static int w97_32_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int /* C bits used by mmx/sse2/altivec */ -static av_always_inline void snow_interleave_line_header(int * i, int width, DWTELEM * low, DWTELEM * high){ +static av_always_inline void snow_interleave_line_header(int * i, int width, IDWTELEM * low, IDWTELEM * high){ (*i) = (width) - 2; if (width & 1){ @@ -146,14 +144,14 @@ static av_always_inline void snow_interleave_line_header(int * i, int width, DWT } } -static av_always_inline void snow_interleave_line_footer(int * i, DWTELEM * low, DWTELEM * high){ +static av_always_inline void snow_interleave_line_footer(int * i, IDWTELEM * low, IDWTELEM * high){ for (; (*i)>=0; (*i)-=2){ low[(*i)+1] = high[(*i)>>1]; low[*i] = low[(*i)>>1]; } } -static av_always_inline void snow_horizontal_compose_lift_lead_out(int i, DWTELEM * dst, DWTELEM * src, DWTELEM * ref, int width, int w, int lift_high, int mul, int add, int shift){ +static av_always_inline void snow_horizontal_compose_lift_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w, int lift_high, int mul, int add, int shift){ for(; i<w; i++){ dst[i] = src[i] - ((mul * (ref[i] + ref[i + 1]) + add) >> shift); } @@ -163,14 +161,14 @@ static av_always_inline void snow_horizontal_compose_lift_lead_out(int i, DWTELE } } -static av_always_inline void snow_horizontal_compose_liftS_lead_out(int i, DWTELEM * dst, DWTELEM * src, DWTELEM * ref, int width, int w){ +static av_always_inline void snow_horizontal_compose_liftS_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w){ for(; i<w; i++){ - dst[i] = src[i] - (((-(ref[i] + ref[(i+1)])+W_BO) - 4 * src[i]) >> W_BS); + dst[i] = src[i] + ((ref[i] + ref[(i+1)]+W_BO + 4 * src[i]) >> W_BS); } if(width&1){ - dst[w] = src[w] - (((-2 * ref[w] + W_BO) - 4 * src[w]) >> W_BS); + dst[w] = src[w] + ((2 * ref[w] + W_BO + 4 * src[w]) >> W_BS); } } -#endif +#endif /* FFMPEG_SNOW_H */ diff --git a/contrib/ffmpeg/libavcodec/sonic.c b/contrib/ffmpeg/libavcodec/sonic.c index f3388589b..9e193d469 100644 --- a/contrib/ffmpeg/libavcodec/sonic.c +++ b/contrib/ffmpeg/libavcodec/sonic.c @@ -851,7 +851,7 @@ static int sonic_decode_close(AVCodecContext *avctx) static int sonic_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { SonicContext *s = avctx->priv_data; GetBitContext gb; @@ -926,14 +926,7 @@ static int sonic_decode_frame(AVCodecContext *avctx, // internal -> short for (i = 0; i < s->frame_size; i++) - { - if (s->int_samples[i] > 32767) - samples[i] = 32767; - else if (s->int_samples[i] < -32768) - samples[i] = -32768; - else - samples[i] = s->int_samples[i]; - } + samples[i] = av_clip_int16(s->int_samples[i]); align_get_bits(&gb); diff --git a/contrib/ffmpeg/libavcodec/sp5x.h b/contrib/ffmpeg/libavcodec/sp5x.h index 0d0d3551f..e93408b34 100644 --- a/contrib/ffmpeg/libavcodec/sp5x.h +++ b/contrib/ffmpeg/libavcodec/sp5x.h @@ -19,8 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef SP5X_H -#define SP5X_H +#ifndef FFMPEG_SP5X_H +#define FFMPEG_SP5X_H + +#include <stdint.h> static const uint8_t sp5x_data_sof[] = { @@ -329,4 +331,4 @@ static const uint8_t sp5x_quant_table_orig[18][64] = }; #endif -#endif /* SP5X_H */ +#endif /* FFMPEG_SP5X_H */ diff --git a/contrib/ffmpeg/libavcodec/sp5xdec.c b/contrib/ffmpeg/libavcodec/sp5xdec.c new file mode 100644 index 000000000..e5dd5ea05 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/sp5xdec.c @@ -0,0 +1,213 @@ +/* + * Sunplus JPEG decoder (SP5X) + * 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 sp5xdec.c + * Sunplus JPEG decoder (SP5X). + */ + +#include "avcodec.h" +#include "mjpeg.h" +#include "mjpegdec.h" +#include "sp5x.h" + + +static int sp5x_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ +#if 0 + MJpegDecodeContext *s = avctx->priv_data; +#endif + const int qscale = 5; + const uint8_t *buf_ptr, *buf_end; + uint8_t *recoded; + int i = 0, j = 0; + + if (!avctx->width || !avctx->height) + return -1; + + buf_ptr = buf; + buf_end = buf + buf_size; + +#if 1 + recoded = av_mallocz(buf_size + 1024); + if (!recoded) + return -1; + + /* SOI */ + recoded[j++] = 0xFF; + recoded[j++] = 0xD8; + + memcpy(recoded+j, &sp5x_data_dqt[0], sizeof(sp5x_data_dqt)); + memcpy(recoded+j+5, &sp5x_quant_table[qscale * 2], 64); + memcpy(recoded+j+70, &sp5x_quant_table[(qscale * 2) + 1], 64); + j += sizeof(sp5x_data_dqt); + + memcpy(recoded+j, &sp5x_data_dht[0], sizeof(sp5x_data_dht)); + j += sizeof(sp5x_data_dht); + + memcpy(recoded+j, &sp5x_data_sof[0], sizeof(sp5x_data_sof)); + AV_WB16(recoded+j+5, avctx->coded_height); + AV_WB16(recoded+j+7, avctx->coded_width); + j += sizeof(sp5x_data_sof); + + memcpy(recoded+j, &sp5x_data_sos[0], sizeof(sp5x_data_sos)); + j += sizeof(sp5x_data_sos); + + if(avctx->codec_id==CODEC_ID_AMV) + for (i = 2; i < buf_size-2 && j < buf_size+1024-2; i++) + recoded[j++] = buf[i]; + else + for (i = 14; i < buf_size && j < buf_size+1024-2; i++) + { + recoded[j++] = buf[i]; + if (buf[i] == 0xff) + recoded[j++] = 0; + } + + /* EOI */ + recoded[j++] = 0xFF; + recoded[j++] = 0xD9; + + avctx->flags &= ~CODEC_FLAG_EMU_EDGE; + i = ff_mjpeg_decode_frame(avctx, data, data_size, recoded, j); + + av_free(recoded); + +#else + /* SOF */ + s->bits = 8; + s->width = avctx->coded_width; + s->height = avctx->coded_height; + s->nb_components = 3; + s->component_id[0] = 0; + s->h_count[0] = 2; + s->v_count[0] = 2; + s->quant_index[0] = 0; + s->component_id[1] = 1; + s->h_count[1] = 1; + s->v_count[1] = 1; + s->quant_index[1] = 1; + s->component_id[2] = 2; + s->h_count[2] = 1; + s->v_count[2] = 1; + s->quant_index[2] = 1; + s->h_max = 2; + s->v_max = 2; + + s->qscale_table = av_mallocz((s->width+15)/16); + avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420; + s->interlaced = 0; + + s->picture.reference = 0; + if (avctx->get_buffer(avctx, &s->picture) < 0) + { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + s->picture.pict_type = I_TYPE; + s->picture.key_frame = 1; + + for (i = 0; i < 3; i++) + s->linesize[i] = s->picture.linesize[i] << s->interlaced; + + /* DQT */ + for (i = 0; i < 64; i++) + { + j = s->scantable.permutated[i]; + s->quant_matrixes[0][j] = sp5x_quant_table[(qscale * 2) + i]; + } + s->qscale[0] = FFMAX( + s->quant_matrixes[0][s->scantable.permutated[1]], + s->quant_matrixes[0][s->scantable.permutated[8]]) >> 1; + + for (i = 0; i < 64; i++) + { + j = s->scantable.permutated[i]; + s->quant_matrixes[1][j] = sp5x_quant_table[(qscale * 2) + 1 + i]; + } + s->qscale[1] = FFMAX( + s->quant_matrixes[1][s->scantable.permutated[1]], + s->quant_matrixes[1][s->scantable.permutated[8]]) >> 1; + + /* DHT */ + + /* SOS */ + s->comp_index[0] = 0; + s->nb_blocks[0] = s->h_count[0] * s->v_count[0]; + s->h_scount[0] = s->h_count[0]; + s->v_scount[0] = s->v_count[0]; + s->dc_index[0] = 0; + s->ac_index[0] = 0; + + s->comp_index[1] = 1; + s->nb_blocks[1] = s->h_count[1] * s->v_count[1]; + s->h_scount[1] = s->h_count[1]; + s->v_scount[1] = s->v_count[1]; + s->dc_index[1] = 1; + s->ac_index[1] = 1; + + s->comp_index[2] = 2; + s->nb_blocks[2] = s->h_count[2] * s->v_count[2]; + s->h_scount[2] = s->h_count[2]; + s->v_scount[2] = s->v_count[2]; + s->dc_index[2] = 1; + s->ac_index[2] = 1; + + for (i = 0; i < 3; i++) + s->last_dc[i] = 1024; + + s->mb_width = (s->width * s->h_max * 8 -1) / (s->h_max * 8); + s->mb_height = (s->height * s->v_max * 8 -1) / (s->v_max * 8); + + init_get_bits(&s->gb, buf+14, (buf_size-14)*8); + + return mjpeg_decode_scan(s); +#endif + + return i; +} + +AVCodec sp5x_decoder = { + "sp5x", + CODEC_TYPE_VIDEO, + CODEC_ID_SP5X, + sizeof(MJpegDecodeContext), + ff_mjpeg_decode_init, + NULL, + ff_mjpeg_decode_end, + sp5x_decode_frame, + CODEC_CAP_DR1, + NULL +}; + +AVCodec amv_decoder = { + "amv", + CODEC_TYPE_VIDEO, + CODEC_ID_AMV, + sizeof(MJpegDecodeContext), + ff_mjpeg_decode_init, + NULL, + ff_mjpeg_decode_end, + sp5x_decode_frame +}; diff --git a/contrib/ffmpeg/libavcodec/sparc/dsputil_vis.c b/contrib/ffmpeg/libavcodec/sparc/dsputil_vis.c index 5e59ce776..437260311 100644 --- a/contrib/ffmpeg/libavcodec/sparc/dsputil_vis.c +++ b/contrib/ffmpeg/libavcodec/sparc/dsputil_vis.c @@ -25,16 +25,16 @@ #include "config.h" -#ifdef ARCH_SPARC - #include <inttypes.h> -#include <signal.h> -#include <setjmp.h> -#include "../dsputil.h" +#include "dsputil.h" #include "vis.h" +extern void ff_simple_idct_put_vis(uint8_t *dest, int line_size, DCTELEM *data); +extern void ff_simple_idct_add_vis(uint8_t *dest, int line_size, DCTELEM *data); +extern void ff_simple_idct_vis(DCTELEM *data); + /* The trick used in some of this file is the formula from the MMX * motion comp code, which is: * @@ -3985,66 +3985,31 @@ static void MC_avg_no_round_xy_8_vis (uint8_t * dest, const uint8_t * _ref, /* End of no rounding code */ -static sigjmp_buf jmpbuf; -static volatile sig_atomic_t canjump = 0; - -static void sigill_handler (int sig) -{ - if (!canjump) { - signal (sig, SIG_DFL); - raise (sig); - } - - canjump = 0; - siglongjmp (jmpbuf, 1); -} - #define ACCEL_SPARC_VIS 1 #define ACCEL_SPARC_VIS2 2 static int vis_level () { int accel = 0; - - signal (SIGILL, sigill_handler); - if (sigsetjmp (jmpbuf, 1)) { - signal (SIGILL, SIG_DFL); - return accel; - } - - canjump = 1; - - /* pdist %f0, %f0, %f0 */ - __asm__ __volatile__(".word\t0x81b007c0"); - - canjump = 0; accel |= ACCEL_SPARC_VIS; - - if (sigsetjmp (jmpbuf, 1)) { - signal (SIGILL, SIG_DFL); - return accel; - } - - canjump = 1; - - /* edge8n %g0, %g0, %g0 */ - __asm__ __volatile__(".word\t0x81b00020"); - - canjump = 0; accel |= ACCEL_SPARC_VIS2; - - signal (SIGILL, SIG_DFL); - return accel; } /* libavcodec initialization code */ void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx) { - /* VIS specific optimisations */ + /* VIS-specific optimizations */ int accel = vis_level (); if (accel & ACCEL_SPARC_VIS) { + if(avctx->idct_algo==FF_IDCT_SIMPLEVIS){ + c->idct_put = ff_simple_idct_put_vis; + c->idct_add = ff_simple_idct_add_vis; + c->idct = ff_simple_idct_vis; + c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; + } + c->put_pixels_tab[0][0] = MC_put_o_16_vis; c->put_pixels_tab[0][1] = MC_put_x_16_vis; c->put_pixels_tab[0][2] = MC_put_y_16_vis; @@ -4086,5 +4051,3 @@ void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx) c->avg_no_rnd_pixels_tab[1][3] = MC_avg_no_round_xy_8_vis; } } - -#endif /* !(ARCH_SPARC) */ diff --git a/contrib/ffmpeg/libavcodec/sparc/simple_idct_vis.c b/contrib/ffmpeg/libavcodec/sparc/simple_idct_vis.c new file mode 100644 index 000000000..716d3de48 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/sparc/simple_idct_vis.c @@ -0,0 +1,528 @@ +/* + * SPARC VIS optimized inverse DCT + * Copyright (c) 2007 Denes Balatoni < dbalatoni XatX interware XdotX hu > + * + * I did consult the following fine web page about dct + * http://www.geocities.com/ssavekar/dct.htm + * + * 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 "dsputil.h" + +static const DECLARE_ALIGNED_8(int16_t, coeffs[28]) = { + - 1259,- 1259,- 1259,- 1259, + - 4989,- 4989,- 4989,- 4989, + -11045,-11045,-11045,-11045, + -19195,-19195,-19195,-19195, + -29126,-29126,-29126,-29126, + 25080, 25080, 25080, 25080, + 12785, 12785, 12785, 12785 +}; +static const DECLARE_ALIGNED_8(uint16_t, scale[4]) = { + 65536>>6, 65536>>6, 65536>>6, 65536>>6 +}; +static const DECLARE_ALIGNED_8(uint16_t, rounder[4]) = { + 1<<5, 1<<5, 1<<5, 1<<5 +}; +static const DECLARE_ALIGNED_8(uint16_t, expand[4]) = { + 1<<14, 1<<14, 1<<14, 1<<14 +}; + +#define INIT_IDCT \ + "ldd [%1], %%f32 \n\t"\ + "ldd [%1+8], %%f34 \n\t"\ + "ldd [%1+16], %%f36 \n\t"\ + "ldd [%1+24], %%f38 \n\t"\ + "ldd [%1+32], %%f40 \n\t"\ + "ldd [%1+40], %%f42 \n\t"\ + "ldd [%1+48], %%f44 \n\t"\ + "ldd [%0], %%f46 \n\t"\ + "fzero %%f62 \n\t"\ + +#define LOADSCALE(in) \ + "ldd [" in "], %%f0 \n\t"\ + "ldd [" in "+16], %%f2 \n\t"\ + "ldd [" in "+32], %%f4 \n\t"\ + "ldd [" in "+48], %%f6 \n\t"\ + "ldd [" in "+64], %%f8 \n\t"\ + "ldd [" in "+80], %%f10 \n\t"\ + "ldd [" in "+96], %%f12 \n\t"\ + "ldd [" in "+112], %%f14 \n\t"\ + "fpadd16 %%f0, %%f0, %%f0 \n\t"\ + "fpadd16 %%f2, %%f2, %%f2 \n\t"\ + "fpadd16 %%f4, %%f4, %%f4 \n\t"\ + "fpadd16 %%f6, %%f6, %%f6 \n\t"\ + "fpadd16 %%f8, %%f8, %%f8 \n\t"\ + "fpadd16 %%f10, %%f10, %%f10 \n\t"\ + "fpadd16 %%f12, %%f12, %%f12 \n\t"\ + "fpadd16 %%f14, %%f14, %%f14 \n\t"\ +\ + "fpadd16 %%f0, %%f0, %%f0 \n\t"\ + "fpadd16 %%f2, %%f2, %%f2 \n\t"\ + "fpadd16 %%f4, %%f4, %%f4 \n\t"\ + "fpadd16 %%f6, %%f6, %%f6 \n\t"\ + "fpadd16 %%f8, %%f8, %%f8 \n\t"\ + "fpadd16 %%f10, %%f10, %%f10 \n\t"\ + "fpadd16 %%f12, %%f12, %%f12 \n\t"\ + "fpadd16 %%f14, %%f14, %%f14 \n\t"\ +\ + "fpadd16 %%f0, %%f0, %%f0 \n\t"\ + "fpadd16 %%f2, %%f2, %%f2 \n\t"\ + "fpadd16 %%f4, %%f4, %%f4 \n\t"\ + "fpadd16 %%f6, %%f6, %%f6 \n\t"\ + "fpadd16 %%f8, %%f8, %%f8 \n\t"\ + "fpadd16 %%f10, %%f10, %%f10 \n\t"\ + "fpadd16 %%f12, %%f12, %%f12 \n\t"\ + "fpadd16 %%f14, %%f14, %%f14 \n\t"\ +\ + "fpadd16 %%f0, %%f0, %%f0 \n\t"\ + "fpadd16 %%f2, %%f2, %%f2 \n\t"\ + "fpadd16 %%f4, %%f4, %%f4 \n\t"\ + "fpadd16 %%f6, %%f6, %%f6 \n\t"\ + "fpadd16 %%f8, %%f8, %%f8 \n\t"\ + "fpadd16 %%f10, %%f10, %%f10 \n\t"\ + "fpadd16 %%f12, %%f12, %%f12 \n\t"\ + "fpadd16 %%f14, %%f14, %%f14 \n\t"\ + +#define LOAD(in) \ + "ldd [" in "], %%f16 \n\t"\ + "ldd [" in "+8], %%f18 \n\t"\ + "ldd [" in "+16], %%f20 \n\t"\ + "ldd [" in "+24], %%f22 \n\t"\ + "ldd [" in "+32], %%f24 \n\t"\ + "ldd [" in "+40], %%f26 \n\t"\ + "ldd [" in "+48], %%f28 \n\t"\ + "ldd [" in "+56], %%f30 \n\t"\ + +#define TRANSPOSE \ + "fpmerge %%f16, %%f24, %%f0 \n\t"\ + "fpmerge %%f20, %%f28, %%f2 \n\t"\ + "fpmerge %%f17, %%f25, %%f4 \n\t"\ + "fpmerge %%f21, %%f29, %%f6 \n\t"\ + "fpmerge %%f18, %%f26, %%f8 \n\t"\ + "fpmerge %%f22, %%f30, %%f10 \n\t"\ + "fpmerge %%f19, %%f27, %%f12 \n\t"\ + "fpmerge %%f23, %%f31, %%f14 \n\t"\ +\ + "fpmerge %%f0, %%f2, %%f16 \n\t"\ + "fpmerge %%f1, %%f3, %%f18 \n\t"\ + "fpmerge %%f4, %%f6, %%f20 \n\t"\ + "fpmerge %%f5, %%f7, %%f22 \n\t"\ + "fpmerge %%f8, %%f10, %%f24 \n\t"\ + "fpmerge %%f9, %%f11, %%f26 \n\t"\ + "fpmerge %%f12, %%f14, %%f28 \n\t"\ + "fpmerge %%f13, %%f15, %%f30 \n\t"\ +\ + "fpmerge %%f16, %%f17, %%f0 \n\t"\ + "fpmerge %%f18, %%f19, %%f2 \n\t"\ + "fpmerge %%f20, %%f21, %%f4 \n\t"\ + "fpmerge %%f22, %%f23, %%f6 \n\t"\ + "fpmerge %%f24, %%f25, %%f8 \n\t"\ + "fpmerge %%f26, %%f27, %%f10 \n\t"\ + "fpmerge %%f28, %%f29, %%f12 \n\t"\ + "fpmerge %%f30, %%f31, %%f14 \n\t"\ + +#define IDCT4ROWS \ + /* 1. column */\ + "fmul8ulx16 %%f0, %%f38, %%f28 \n\t"\ + "for %%f4, %%f6, %%f60 \n\t"\ + "fmul8ulx16 %%f2, %%f32, %%f18 \n\t"\ + "fmul8ulx16 %%f2, %%f36, %%f22 \n\t"\ + "fmul8ulx16 %%f2, %%f40, %%f26 \n\t"\ + "fmul8ulx16 %%f2, %%f44, %%f30 \n\t"\ +\ + ADDROUNDER\ +\ + "fmul8sux16 %%f0, %%f38, %%f48 \n\t"\ + "fcmpd %%fcc0, %%f62, %%f60 \n\t"\ + "for %%f8, %%f10, %%f60 \n\t"\ + "fmul8sux16 %%f2, %%f32, %%f50 \n\t"\ + "fmul8sux16 %%f2, %%f36, %%f52 \n\t"\ + "fmul8sux16 %%f2, %%f40, %%f54 \n\t"\ + "fmul8sux16 %%f2, %%f44, %%f56 \n\t"\ +\ + "fpadd16 %%f48, %%f28, %%f28 \n\t"\ + "fcmpd %%fcc1, %%f62, %%f60 \n\t"\ + "for %%f12, %%f14, %%f60 \n\t"\ + "fpadd16 %%f50, %%f18, %%f18 \n\t"\ + "fpadd16 %%f52, %%f22, %%f22 \n\t"\ + "fpadd16 %%f54, %%f26, %%f26 \n\t"\ + "fpadd16 %%f56, %%f30, %%f30 \n\t"\ +\ + "fpadd16 %%f28, %%f0, %%f16 \n\t"\ + "fcmpd %%fcc2, %%f62, %%f60 \n\t"\ + "fpadd16 %%f28, %%f0, %%f20 \n\t"\ + "fpadd16 %%f28, %%f0, %%f24 \n\t"\ + "fpadd16 %%f28, %%f0, %%f28 \n\t"\ + "fpadd16 %%f18, %%f2, %%f18 \n\t"\ + "fpadd16 %%f22, %%f2, %%f22 \n\t"\ + /* 2. column */\ + "fbe %%fcc0, 3f \n\t"\ + "fpadd16 %%f26, %%f2, %%f26 \n\t"\ + "fmul8ulx16 %%f4, %%f34, %%f48 \n\t"\ + "fmul8ulx16 %%f4, %%f42, %%f50 \n\t"\ + "fmul8ulx16 %%f6, %%f36, %%f52 \n\t"\ + "fmul8ulx16 %%f6, %%f44, %%f54 \n\t"\ + "fmul8ulx16 %%f6, %%f32, %%f56 \n\t"\ + "fmul8ulx16 %%f6, %%f40, %%f58 \n\t"\ +\ + "fpadd16 %%f16, %%f48, %%f16 \n\t"\ + "fpadd16 %%f20, %%f50, %%f20 \n\t"\ + "fpsub16 %%f24, %%f50, %%f24 \n\t"\ + "fpsub16 %%f28, %%f48, %%f28 \n\t"\ + "fpadd16 %%f18, %%f52, %%f18 \n\t"\ + "fpsub16 %%f22, %%f54, %%f22 \n\t"\ + "fpsub16 %%f26, %%f56, %%f26 \n\t"\ + "fpsub16 %%f30, %%f58, %%f30 \n\t"\ +\ + "fmul8sux16 %%f4, %%f34, %%f48 \n\t"\ + "fmul8sux16 %%f4, %%f42, %%f50 \n\t"\ + "fmul8sux16 %%f6, %%f36, %%f52 \n\t"\ + "fmul8sux16 %%f6, %%f44, %%f54 \n\t"\ + "fmul8sux16 %%f6, %%f32, %%f56 \n\t"\ + "fmul8sux16 %%f6, %%f40, %%f58 \n\t"\ +\ + "fpadd16 %%f16, %%f48, %%f16 \n\t"\ + "fpadd16 %%f20, %%f50, %%f20 \n\t"\ + "fpsub16 %%f24, %%f50, %%f24 \n\t"\ + "fpsub16 %%f28, %%f48, %%f28 \n\t"\ + "fpadd16 %%f18, %%f52, %%f18 \n\t"\ + "fpsub16 %%f22, %%f54, %%f22 \n\t"\ + "fpsub16 %%f26, %%f56, %%f26 \n\t"\ + "fpsub16 %%f30, %%f58, %%f30 \n\t"\ +\ + "fpadd16 %%f16, %%f4, %%f16 \n\t"\ + "fpsub16 %%f28, %%f4, %%f28 \n\t"\ + "fpadd16 %%f18, %%f6, %%f18 \n\t"\ + "fpsub16 %%f26, %%f6, %%f26 \n\t"\ + /* 3. column */\ + "3: \n\t"\ + "fbe %%fcc1, 4f \n\t"\ + "fpsub16 %%f30, %%f6, %%f30 \n\t"\ + "fmul8ulx16 %%f8, %%f38, %%f48 \n\t"\ + "fmul8ulx16 %%f10, %%f40, %%f50 \n\t"\ + "fmul8ulx16 %%f10, %%f32, %%f52 \n\t"\ + "fmul8ulx16 %%f10, %%f44, %%f54 \n\t"\ + "fmul8ulx16 %%f10, %%f36, %%f56 \n\t"\ +\ + "fpadd16 %%f16, %%f48, %%f16 \n\t"\ + "fpsub16 %%f20, %%f48, %%f20 \n\t"\ + "fpsub16 %%f24, %%f48, %%f24 \n\t"\ + "fpadd16 %%f28, %%f48, %%f28 \n\t"\ + "fpadd16 %%f18, %%f50, %%f18 \n\t"\ + "fpsub16 %%f22, %%f52, %%f22 \n\t"\ + "fpadd16 %%f26, %%f54, %%f26 \n\t"\ + "fpadd16 %%f30, %%f56, %%f30 \n\t"\ +\ + "fmul8sux16 %%f8, %%f38, %%f48 \n\t"\ + "fmul8sux16 %%f10, %%f40, %%f50 \n\t"\ + "fmul8sux16 %%f10, %%f32, %%f52 \n\t"\ + "fmul8sux16 %%f10, %%f44, %%f54 \n\t"\ + "fmul8sux16 %%f10, %%f36, %%f56 \n\t"\ +\ + "fpadd16 %%f16, %%f48, %%f16 \n\t"\ + "fpsub16 %%f20, %%f48, %%f20 \n\t"\ + "fpsub16 %%f24, %%f48, %%f24 \n\t"\ + "fpadd16 %%f28, %%f48, %%f28 \n\t"\ + "fpadd16 %%f18, %%f50, %%f18 \n\t"\ + "fpsub16 %%f22, %%f52, %%f22 \n\t"\ + "fpadd16 %%f26, %%f54, %%f26 \n\t"\ + "fpadd16 %%f30, %%f56, %%f30 \n\t"\ +\ + "fpadd16 %%f16, %%f8, %%f16 \n\t"\ + "fpsub16 %%f20, %%f8, %%f20 \n\t"\ + "fpsub16 %%f24, %%f8, %%f24 \n\t"\ + "fpadd16 %%f28, %%f8, %%f28 \n\t"\ + "fpadd16 %%f18, %%f10, %%f18 \n\t"\ + "fpsub16 %%f22, %%f10, %%f22 \n\t"\ + /* 4. column */\ + "4: \n\t"\ + "fbe %%fcc2, 5f \n\t"\ + "fpadd16 %%f30, %%f10, %%f30 \n\t"\ + "fmul8ulx16 %%f12, %%f42, %%f48 \n\t"\ + "fmul8ulx16 %%f12, %%f34, %%f50 \n\t"\ + "fmul8ulx16 %%f14, %%f44, %%f52 \n\t"\ + "fmul8ulx16 %%f14, %%f40, %%f54 \n\t"\ + "fmul8ulx16 %%f14, %%f36, %%f56 \n\t"\ + "fmul8ulx16 %%f14, %%f32, %%f58 \n\t"\ +\ + "fpadd16 %%f16, %%f48, %%f16 \n\t"\ + "fpsub16 %%f20, %%f50, %%f20 \n\t"\ + "fpadd16 %%f24, %%f50, %%f24 \n\t"\ + "fpsub16 %%f28, %%f48, %%f28 \n\t"\ + "fpadd16 %%f18, %%f52, %%f18 \n\t"\ + "fpsub16 %%f22, %%f54, %%f22 \n\t"\ + "fpadd16 %%f26, %%f56, %%f26 \n\t"\ + "fpsub16 %%f30, %%f58, %%f30 \n\t"\ +\ + "fmul8sux16 %%f12, %%f42, %%f48 \n\t"\ + "fmul8sux16 %%f12, %%f34, %%f50 \n\t"\ + "fmul8sux16 %%f14, %%f44, %%f52 \n\t"\ + "fmul8sux16 %%f14, %%f40, %%f54 \n\t"\ + "fmul8sux16 %%f14, %%f36, %%f56 \n\t"\ + "fmul8sux16 %%f14, %%f32, %%f58 \n\t"\ +\ + "fpadd16 %%f16, %%f48, %%f16 \n\t"\ + "fpsub16 %%f20, %%f50, %%f20 \n\t"\ + "fpadd16 %%f24, %%f50, %%f24 \n\t"\ + "fpsub16 %%f28, %%f48, %%f28 \n\t"\ + "fpadd16 %%f18, %%f52, %%f18 \n\t"\ + "fpsub16 %%f22, %%f54, %%f22 \n\t"\ + "fpadd16 %%f26, %%f56, %%f26 \n\t"\ + "fpsub16 %%f30, %%f58, %%f30 \n\t"\ +\ + "fpsub16 %%f20, %%f12, %%f20 \n\t"\ + "fpadd16 %%f24, %%f12, %%f24 \n\t"\ + "fpsub16 %%f22, %%f14, %%f22 \n\t"\ + "fpadd16 %%f26, %%f14, %%f26 \n\t"\ + "fpsub16 %%f30, %%f14, %%f30 \n\t"\ + /* final butterfly */\ + "5: \n\t"\ + "fpsub16 %%f16, %%f18, %%f48 \n\t"\ + "fpsub16 %%f20, %%f22, %%f50 \n\t"\ + "fpsub16 %%f24, %%f26, %%f52 \n\t"\ + "fpsub16 %%f28, %%f30, %%f54 \n\t"\ + "fpadd16 %%f16, %%f18, %%f16 \n\t"\ + "fpadd16 %%f20, %%f22, %%f20 \n\t"\ + "fpadd16 %%f24, %%f26, %%f24 \n\t"\ + "fpadd16 %%f28, %%f30, %%f28 \n\t"\ + +#define STOREROWS(out) \ + "std %%f48, [" out "+112] \n\t"\ + "std %%f50, [" out "+96] \n\t"\ + "std %%f52, [" out "+80] \n\t"\ + "std %%f54, [" out "+64] \n\t"\ + "std %%f16, [" out "] \n\t"\ + "std %%f20, [" out "+16] \n\t"\ + "std %%f24, [" out "+32] \n\t"\ + "std %%f28, [" out "+48] \n\t"\ + +#define SCALEROWS \ + "fmul8sux16 %%f46, %%f48, %%f48 \n\t"\ + "fmul8sux16 %%f46, %%f50, %%f50 \n\t"\ + "fmul8sux16 %%f46, %%f52, %%f52 \n\t"\ + "fmul8sux16 %%f46, %%f54, %%f54 \n\t"\ + "fmul8sux16 %%f46, %%f16, %%f16 \n\t"\ + "fmul8sux16 %%f46, %%f20, %%f20 \n\t"\ + "fmul8sux16 %%f46, %%f24, %%f24 \n\t"\ + "fmul8sux16 %%f46, %%f28, %%f28 \n\t"\ + +#define PUTPIXELSCLAMPED(dest) \ + "fpack16 %%f48, %%f14 \n\t"\ + "fpack16 %%f50, %%f12 \n\t"\ + "fpack16 %%f16, %%f0 \n\t"\ + "fpack16 %%f20, %%f2 \n\t"\ + "fpack16 %%f24, %%f4 \n\t"\ + "fpack16 %%f28, %%f6 \n\t"\ + "fpack16 %%f54, %%f8 \n\t"\ + "fpack16 %%f52, %%f10 \n\t"\ + "st %%f0, [%3+" dest "] \n\t"\ + "st %%f2, [%5+" dest "] \n\t"\ + "st %%f4, [%6+" dest "] \n\t"\ + "st %%f6, [%7+" dest "] \n\t"\ + "st %%f8, [%8+" dest "] \n\t"\ + "st %%f10, [%9+" dest "] \n\t"\ + "st %%f12, [%10+" dest "] \n\t"\ + "st %%f14, [%11+" dest "] \n\t"\ + +#define ADDPIXELSCLAMPED(dest) \ + "ldd [%5], %%f18 \n\t"\ + "ld [%3+" dest"], %%f0 \n\t"\ + "ld [%6+" dest"], %%f2 \n\t"\ + "ld [%7+" dest"], %%f4 \n\t"\ + "ld [%8+" dest"], %%f6 \n\t"\ + "ld [%9+" dest"], %%f8 \n\t"\ + "ld [%10+" dest"], %%f10 \n\t"\ + "ld [%11+" dest"], %%f12 \n\t"\ + "ld [%12+" dest"], %%f14 \n\t"\ + "fmul8x16 %%f0, %%f18, %%f0 \n\t"\ + "fmul8x16 %%f2, %%f18, %%f2 \n\t"\ + "fmul8x16 %%f4, %%f18, %%f4 \n\t"\ + "fmul8x16 %%f6, %%f18, %%f6 \n\t"\ + "fmul8x16 %%f8, %%f18, %%f8 \n\t"\ + "fmul8x16 %%f10, %%f18, %%f10 \n\t"\ + "fmul8x16 %%f12, %%f18, %%f12 \n\t"\ + "fmul8x16 %%f14, %%f18, %%f14 \n\t"\ + "fpadd16 %%f0, %%f16, %%f0 \n\t"\ + "fpadd16 %%f2, %%f20, %%f2 \n\t"\ + "fpadd16 %%f4, %%f24, %%f4 \n\t"\ + "fpadd16 %%f6, %%f28, %%f6 \n\t"\ + "fpadd16 %%f8, %%f54, %%f8 \n\t"\ + "fpadd16 %%f10, %%f52, %%f10 \n\t"\ + "fpadd16 %%f12, %%f50, %%f12 \n\t"\ + "fpadd16 %%f14, %%f48, %%f14 \n\t"\ + "fpack16 %%f0, %%f0 \n\t"\ + "fpack16 %%f2, %%f2 \n\t"\ + "fpack16 %%f4, %%f4 \n\t"\ + "fpack16 %%f6, %%f6 \n\t"\ + "fpack16 %%f8, %%f8 \n\t"\ + "fpack16 %%f10, %%f10 \n\t"\ + "fpack16 %%f12, %%f12 \n\t"\ + "fpack16 %%f14, %%f14 \n\t"\ + "st %%f0, [%3+" dest "] \n\t"\ + "st %%f2, [%6+" dest "] \n\t"\ + "st %%f4, [%7+" dest "] \n\t"\ + "st %%f6, [%8+" dest "] \n\t"\ + "st %%f8, [%9+" dest "] \n\t"\ + "st %%f10, [%10+" dest "] \n\t"\ + "st %%f12, [%11+" dest "] \n\t"\ + "st %%f14, [%12+" dest "] \n\t"\ + + +inline void ff_simple_idct_vis(DCTELEM *data) { + int out1, out2, out3, out4; + DECLARE_ALIGNED_8(int16_t, temp[8*8]); + + asm volatile( + INIT_IDCT + +#define ADDROUNDER + + // shift right 16-4=12 + LOADSCALE("%2+8") + IDCT4ROWS + STOREROWS("%3+8") + LOADSCALE("%2+0") + IDCT4ROWS + "std %%f48, [%3+112] \n\t" + "std %%f50, [%3+96] \n\t" + "std %%f52, [%3+80] \n\t" + "std %%f54, [%3+64] \n\t" + + // shift right 16+4 + "ldd [%3+8], %%f18 \n\t" + "ldd [%3+24], %%f22 \n\t" + "ldd [%3+40], %%f26 \n\t" + "ldd [%3+56], %%f30 \n\t" + TRANSPOSE + IDCT4ROWS + SCALEROWS + STOREROWS("%2+0") + LOAD("%3+64") + TRANSPOSE + IDCT4ROWS + SCALEROWS + STOREROWS("%2+8") + + : "=r" (out1), "=r" (out2), "=r" (out3), "=r" (out4) + : "0" (scale), "1" (coeffs), "2" (data), "3" (temp) + ); +} + +void ff_simple_idct_put_vis(uint8_t *dest, int line_size, DCTELEM *data) { + int out1, out2, out3, out4, out5; + int r1, r2, r3, r4, r5, r6, r7; + + asm volatile( + "wr %%g0, 0x8, %%gsr \n\t" + + INIT_IDCT + + "add %3, %4, %5 \n\t" + "add %5, %4, %6 \n\t" + "add %6, %4, %7 \n\t" + "add %7, %4, %8 \n\t" + "add %8, %4, %9 \n\t" + "add %9, %4, %10 \n\t" + "add %10, %4, %11 \n\t" + + // shift right 16-4=12 + LOADSCALE("%2+8") + IDCT4ROWS + STOREROWS("%2+8") + LOADSCALE("%2+0") + IDCT4ROWS + "std %%f48, [%2+112] \n\t" + "std %%f50, [%2+96] \n\t" + "std %%f52, [%2+80] \n\t" + "std %%f54, [%2+64] \n\t" + +#undef ADDROUNDER +#define ADDROUNDER "fpadd16 %%f28, %%f46, %%f28 \n\t" + + // shift right 16+4 + "ldd [%2+8], %%f18 \n\t" + "ldd [%2+24], %%f22 \n\t" + "ldd [%2+40], %%f26 \n\t" + "ldd [%2+56], %%f30 \n\t" + TRANSPOSE + IDCT4ROWS + PUTPIXELSCLAMPED("0") + LOAD("%2+64") + TRANSPOSE + IDCT4ROWS + PUTPIXELSCLAMPED("4") + + : "=r" (out1), "=r" (out2), "=r" (out3), "=r" (out4), "=r" (out5), + "=r" (r1), "=r" (r2), "=r" (r3), "=r" (r4), "=r" (r5), "=r" (r6), "=r" (r7) + : "0" (rounder), "1" (coeffs), "2" (data), "3" (dest), "4" (line_size) + ); +} + +void ff_simple_idct_add_vis(uint8_t *dest, int line_size, DCTELEM *data) { + int out1, out2, out3, out4, out5, out6; + int r1, r2, r3, r4, r5, r6, r7; + + asm volatile( + "wr %%g0, 0x8, %%gsr \n\t" + + INIT_IDCT + + "add %3, %4, %6 \n\t" + "add %6, %4, %7 \n\t" + "add %7, %4, %8 \n\t" + "add %8, %4, %9 \n\t" + "add %9, %4, %10 \n\t" + "add %10, %4, %11 \n\t" + "add %11, %4, %12 \n\t" + +#undef ADDROUNDER +#define ADDROUNDER + + // shift right 16-4=12 + LOADSCALE("%2+8") + IDCT4ROWS + STOREROWS("%2+8") + LOADSCALE("%2+0") + IDCT4ROWS + "std %%f48, [%2+112] \n\t" + "std %%f50, [%2+96] \n\t" + "std %%f52, [%2+80] \n\t" + "std %%f54, [%2+64] \n\t" + +#undef ADDROUNDER +#define ADDROUNDER "fpadd16 %%f28, %%f46, %%f28 \n\t" + + // shift right 16+4 + "ldd [%2+8], %%f18 \n\t" + "ldd [%2+24], %%f22 \n\t" + "ldd [%2+40], %%f26 \n\t" + "ldd [%2+56], %%f30 \n\t" + TRANSPOSE + IDCT4ROWS + ADDPIXELSCLAMPED("0") + LOAD("%2+64") + TRANSPOSE + IDCT4ROWS + ADDPIXELSCLAMPED("4") + + : "=r" (out1), "=r" (out2), "=r" (out3), "=r" (out4), "=r" (out5), "=r" (out6), + "=r" (r1), "=r" (r2), "=r" (r3), "=r" (r4), "=r" (r5), "=r" (r6), "=r" (r7) + : "0" (rounder), "1" (coeffs), "2" (data), "3" (dest), "4" (line_size), "5" (expand) + ); +} diff --git a/contrib/ffmpeg/libavcodec/sparc/vis.h b/contrib/ffmpeg/libavcodec/sparc/vis.h index d4a8ce092..a0b09f5bc 100644 --- a/contrib/ffmpeg/libavcodec/sparc/vis.h +++ b/contrib/ffmpeg/libavcodec/sparc/vis.h @@ -40,6 +40,9 @@ * the assembler to keep the binary from becoming tainted. */ +#ifndef FFMPEG_VIS_H +#define FFMPEG_VIS_H + #define vis_opc_base ((0x1 << 31) | (0x36 << 19)) #define vis_opf(X) ((X) << 5) #define vis_sreg(X) (X) @@ -325,3 +328,5 @@ static inline void vis_alignaddrl_g0(void *_ptr) /* Pixel component distance. */ #define vis_pdist(rs1,rs2,rd) vis_dd2d(0x3e, rs1, rs2, rd) + +#endif /* FFMPEG_VIS_H */ diff --git a/contrib/ffmpeg/libavcodec/sunrast.c b/contrib/ffmpeg/libavcodec/sunrast.c new file mode 100644 index 000000000..7e71f21ef --- /dev/null +++ b/contrib/ffmpeg/libavcodec/sunrast.c @@ -0,0 +1,195 @@ +/* + * Sun Rasterfile (.sun/.ras/im{1,8,24}/.sunras) image decoder + * Copyright (c) 2007, 2008 Ivo van Poorten + * + * 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" + +#define RT_OLD 0 +#define RT_STANDARD 1 +#define RT_BYTE_ENCODED 2 +#define RT_FORMAT_RGB 3 +#define RT_FORMAT_TIFF 4 +#define RT_FORMAT_IFF 5 + +typedef struct SUNRASTContext { + AVFrame picture; +} SUNRASTContext; + +static int sunrast_init(AVCodecContext *avctx) { + SUNRASTContext *s = avctx->priv_data; + + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame= &s->picture; + + return 0; +} + +static int sunrast_decode_frame(AVCodecContext *avctx, void *data, + int *data_size, const uint8_t *buf, int buf_size) { + SUNRASTContext * const s = avctx->priv_data; + AVFrame *picture = data; + AVFrame * const p = &s->picture; + unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen; + uint8_t *ptr; + const uint8_t *bufstart = buf; + + if (AV_RB32(buf) != 0x59a66a95) { + av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n"); + return -1; + } + + w = AV_RB32(buf+4); + h = AV_RB32(buf+8); + depth = AV_RB32(buf+12); + type = AV_RB32(buf+20); + maptype = AV_RB32(buf+24); + maplength = AV_RB32(buf+28); + + if (type > RT_BYTE_ENCODED && type <= RT_FORMAT_IFF) { + av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n"); + return -1; + } + if (type > RT_FORMAT_IFF) { + av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); + return -1; + } + if (maptype & ~1) { + av_log(avctx, AV_LOG_ERROR, "invalid colormap type\n"); + return -1; + } + + buf += 32; + + switch (depth) { + case 1: + avctx->pix_fmt = PIX_FMT_MONOWHITE; + break; + case 8: + avctx->pix_fmt = PIX_FMT_PAL8; + break; + case 24: + avctx->pix_fmt = PIX_FMT_BGR24; + break; + default: + av_log(avctx, AV_LOG_ERROR, "invalid depth\n"); + return -1; + } + + if (p->data[0]) + avctx->release_buffer(avctx, p); + + 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; + } + + p->pict_type = FF_I_TYPE; + + if (depth != 8 && maplength) { + av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n"); + + } else if (depth == 8) { + unsigned int len = maplength / 3; + + if (!maplength) { + av_log(avctx, AV_LOG_ERROR, "colormap expected\n"); + return -1; + } + if (maplength % 3 || maplength > 768) { + av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n"); + return -1; + } + + ptr = p->data[1]; + for (x=0; x<len; x++, ptr+=4) + *(uint32_t *)ptr = (buf[x]<<16) + (buf[len+x]<<8) + buf[len+len+x]; + } + + buf += maplength; + + ptr = p->data[0]; + stride = p->linesize[0]; + + /* scanlines are aligned on 16 bit boundaries */ + len = (depth * w + 7) >> 3; + alen = len + (len&1); + + if (type == RT_BYTE_ENCODED) { + int value, run; + uint8_t *end = ptr + h*stride; + + x = 0; + while (ptr != end) { + run = 1; + if ((value = *buf++) == 0x80) { + run = *buf++ + 1; + if (run != 1) + value = *buf++; + } + while (run--) { + if (x < len) + ptr[x] = value; + if (++x >= alen) { + x = 0; + ptr += stride; + if (ptr == end) + break; + } + } + } + } else { + for (y=0; y<h; y++) { + memcpy(ptr, buf, len); + ptr += stride; + buf += alen; + } + } + + *picture = s->picture; + *data_size = sizeof(AVFrame); + + return buf - bufstart; +} + +static int sunrast_end(AVCodecContext *avctx) { + SUNRASTContext *s = avctx->priv_data; + + if(s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + + return 0; +} + +AVCodec sunrast_decoder = { + "sunrast", + CODEC_TYPE_VIDEO, + CODEC_ID_SUNRAST, + sizeof(SUNRASTContext), + sunrast_init, + NULL, + sunrast_end, + sunrast_decode_frame, + 0, + NULL +}; diff --git a/contrib/ffmpeg/libavcodec/svq1.c b/contrib/ffmpeg/libavcodec/svq1.c index 5087ba8cc..a4991837d 100644 --- a/contrib/ffmpeg/libavcodec/svq1.c +++ b/contrib/ffmpeg/libavcodec/svq1.c @@ -1,8 +1,13 @@ /* + * SVQ1 decoder + * ported to MPlayer by Arpi <arpi@thot.banki.hu> + * ported to libavcodec by Nick Kurshev <nickols_k@mail.ru> * * Copyright (C) 2002 the xine project * Copyright (C) 2002 the ffmpeg project * + * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net> + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,12 +23,6 @@ * 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 - * - * (SVQ1 Decoder) - * Ported to mplayer by Arpi <arpi@thot.banki.hu> - * Ported to libavcodec by Nick Kurshev <nickols_k@mail.ru> - * - * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net> */ /** @@ -33,1393 +32,12 @@ * http://www.pcisys.net/~melanson/codecs/ */ - -//#define DEBUG_SVQ1 -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <limits.h> - -#include "common.h" -#include "avcodec.h" -#include "dsputil.h" -#include "mpegvideo.h" -#include "bswap.h" - -#undef NDEBUG -#include <assert.h> - -extern const uint8_t mvtab[33][2]; - -static VLC svq1_block_type; -static VLC svq1_motion_component; -static VLC svq1_intra_multistage[6]; -static VLC svq1_inter_multistage[6]; -static VLC svq1_intra_mean; -static VLC svq1_inter_mean; - -#define SVQ1_BLOCK_SKIP 0 -#define SVQ1_BLOCK_INTER 1 -#define SVQ1_BLOCK_INTER_4V 2 -#define SVQ1_BLOCK_INTRA 3 - -typedef struct SVQ1Context { - MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independent of MpegEncContext, so this will be removed then (FIXME/XXX) - AVCodecContext *avctx; - DSPContext dsp; - AVFrame picture; - AVFrame current_picture; - AVFrame last_picture; - PutBitContext pb; - GetBitContext gb; - - PutBitContext reorder_pb[6]; //why ooh why this sick breadth first order, everything is slower and more complex - - int frame_width; - int frame_height; - - /* Y plane block dimensions */ - int y_block_width; - int y_block_height; - - /* U & V plane (C planes) block dimensions */ - int c_block_width; - int c_block_height; - - uint16_t *mb_type; - uint32_t *dummy; - int16_t (*motion_val8[3])[2]; - int16_t (*motion_val16[3])[2]; - - int64_t rd_total; -} SVQ1Context; - -/* motion vector (prediction) */ -typedef struct svq1_pmv_s { - int x; - int y; -} svq1_pmv_t; - +#include "svq1.h" #include "svq1_cb.h" #include "svq1_vlc.h" -static const uint16_t checksum_table[256] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, - 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, - 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, - 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, - 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, - 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, - 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, - 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, - 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, - 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, - 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, - 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, - 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, - 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, - 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, - 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, - 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, - 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, - 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, - 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, - 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, - 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, - 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 -}; - -static const uint8_t string_table[256] = { - 0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54, - 0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D, - 0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06, - 0x7B, 0xAE, 0x04, 0xD1, 0x85, 0x50, 0xFA, 0x2F, - 0xA4, 0x71, 0xDB, 0x0E, 0x5A, 0x8F, 0x25, 0xF0, - 0x8D, 0x58, 0xF2, 0x27, 0x73, 0xA6, 0x0C, 0xD9, - 0xF6, 0x23, 0x89, 0x5C, 0x08, 0xDD, 0x77, 0xA2, - 0xDF, 0x0A, 0xA0, 0x75, 0x21, 0xF4, 0x5E, 0x8B, - 0x9D, 0x48, 0xE2, 0x37, 0x63, 0xB6, 0x1C, 0xC9, - 0xB4, 0x61, 0xCB, 0x1E, 0x4A, 0x9F, 0x35, 0xE0, - 0xCF, 0x1A, 0xB0, 0x65, 0x31, 0xE4, 0x4E, 0x9B, - 0xE6, 0x33, 0x99, 0x4C, 0x18, 0xCD, 0x67, 0xB2, - 0x39, 0xEC, 0x46, 0x93, 0xC7, 0x12, 0xB8, 0x6D, - 0x10, 0xC5, 0x6F, 0xBA, 0xEE, 0x3B, 0x91, 0x44, - 0x6B, 0xBE, 0x14, 0xC1, 0x95, 0x40, 0xEA, 0x3F, - 0x42, 0x97, 0x3D, 0xE8, 0xBC, 0x69, 0xC3, 0x16, - 0xEF, 0x3A, 0x90, 0x45, 0x11, 0xC4, 0x6E, 0xBB, - 0xC6, 0x13, 0xB9, 0x6C, 0x38, 0xED, 0x47, 0x92, - 0xBD, 0x68, 0xC2, 0x17, 0x43, 0x96, 0x3C, 0xE9, - 0x94, 0x41, 0xEB, 0x3E, 0x6A, 0xBF, 0x15, 0xC0, - 0x4B, 0x9E, 0x34, 0xE1, 0xB5, 0x60, 0xCA, 0x1F, - 0x62, 0xB7, 0x1D, 0xC8, 0x9C, 0x49, 0xE3, 0x36, - 0x19, 0xCC, 0x66, 0xB3, 0xE7, 0x32, 0x98, 0x4D, - 0x30, 0xE5, 0x4F, 0x9A, 0xCE, 0x1B, 0xB1, 0x64, - 0x72, 0xA7, 0x0D, 0xD8, 0x8C, 0x59, 0xF3, 0x26, - 0x5B, 0x8E, 0x24, 0xF1, 0xA5, 0x70, 0xDA, 0x0F, - 0x20, 0xF5, 0x5F, 0x8A, 0xDE, 0x0B, 0xA1, 0x74, - 0x09, 0xDC, 0x76, 0xA3, 0xF7, 0x22, 0x88, 0x5D, - 0xD6, 0x03, 0xA9, 0x7C, 0x28, 0xFD, 0x57, 0x82, - 0xFF, 0x2A, 0x80, 0x55, 0x01, 0xD4, 0x7E, 0xAB, - 0x84, 0x51, 0xFB, 0x2E, 0x7A, 0xAF, 0x05, 0xD0, - 0xAD, 0x78, 0xD2, 0x07, 0x53, 0x86, 0x2C, 0xF9 -}; - -#define SVQ1_PROCESS_VECTOR()\ - for (; level > 0; i++) {\ - /* process next depth */\ - if (i == m) {\ - m = n;\ - if (--level == 0)\ - break;\ - }\ - /* divide block if next bit set */\ - if (get_bits (bitbuf, 1) == 0)\ - break;\ - /* add child nodes */\ - list[n++] = list[i];\ - list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level / 2) + 1));\ - } - -#define SVQ1_ADD_CODEBOOK()\ - /* add codebook entries to vector */\ - for (j=0; j < stages; j++) {\ - n3 = codebook[entries[j]] ^ 0x80808080;\ - n1 += ((n3 & 0xFF00FF00) >> 8);\ - n2 += (n3 & 0x00FF00FF);\ - }\ -\ - /* clip to [0..255] */\ - if (n1 & 0xFF00FF00) {\ - n3 = ((( n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ - n1 += 0x7F007F00;\ - n1 |= (((~n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ - n1 &= (n3 & 0x00FF00FF);\ - }\ -\ - if (n2 & 0xFF00FF00) {\ - n3 = ((( n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ - n2 += 0x7F007F00;\ - n2 |= (((~n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ - n2 &= (n3 & 0x00FF00FF);\ - } - -#define SVQ1_DO_CODEBOOK_INTRA()\ - for (y=0; y < height; y++) {\ - for (x=0; x < (width / 4); x++, codebook++) {\ - n1 = n4;\ - n2 = n4;\ - SVQ1_ADD_CODEBOOK()\ - /* store result */\ - dst[x] = (n1 << 8) | n2;\ - }\ - dst += (pitch / 4);\ - } - -#define SVQ1_DO_CODEBOOK_NONINTRA()\ - for (y=0; y < height; y++) {\ - for (x=0; x < (width / 4); x++, codebook++) {\ - n3 = dst[x];\ - /* add mean value to vector */\ - n1 = ((n3 & 0xFF00FF00) >> 8) + n4;\ - n2 = (n3 & 0x00FF00FF) + n4;\ - SVQ1_ADD_CODEBOOK()\ - /* store result */\ - dst[x] = (n1 << 8) | n2;\ - }\ - dst += (pitch / 4);\ - } - -#define SVQ1_CALC_CODEBOOK_ENTRIES(cbook)\ - codebook = (const uint32_t *) cbook[level];\ - bit_cache = get_bits (bitbuf, 4*stages);\ - /* calculate codebook entries for this vector */\ - for (j=0; j < stages; j++) {\ - entries[j] = (((bit_cache >> (4*(stages - j - 1))) & 0xF) + 16*j) << (level + 1);\ - }\ - mean -= (stages * 128);\ - n4 = ((mean + (mean >> 31)) << 16) | (mean & 0xFFFF); - -static int svq1_decode_block_intra (GetBitContext *bitbuf, uint8_t *pixels, int pitch ) { - uint32_t bit_cache; - uint8_t *list[63]; - uint32_t *dst; - const uint32_t *codebook; - int entries[6]; - int i, j, m, n; - int mean, stages; - unsigned x, y, width, height, level; - uint32_t n1, n2, n3, n4; - - /* initialize list for breadth first processing of vectors */ - list[0] = pixels; - - /* recursively process vector */ - for (i=0, m=1, n=1, level=5; i < n; i++) { - SVQ1_PROCESS_VECTOR(); - - /* destination address and vector size */ - dst = (uint32_t *) list[i]; - width = 1 << ((4 + level) /2); - height = 1 << ((3 + level) /2); - - /* get number of stages (-1 skips vector, 0 for mean only) */ - stages = get_vlc2(bitbuf, svq1_intra_multistage[level].table, 3, 3) - 1; - - if (stages == -1) { - for (y=0; y < height; y++) { - memset (&dst[y*(pitch / 4)], 0, width); - } - continue; /* skip vector */ - } - - if ((stages > 0) && (level >= 4)) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n",stages,level); -#endif - return -1; /* invalid vector */ - } - - mean = get_vlc2(bitbuf, svq1_intra_mean.table, 8, 3); - - if (stages == 0) { - for (y=0; y < height; y++) { - memset (&dst[y*(pitch / 4)], mean, width); - } - } else { - SVQ1_CALC_CODEBOOK_ENTRIES(svq1_intra_codebooks); - SVQ1_DO_CODEBOOK_INTRA() - } - } - - return 0; -} - -static int svq1_decode_block_non_intra (GetBitContext *bitbuf, uint8_t *pixels, int pitch ) { - uint32_t bit_cache; - uint8_t *list[63]; - uint32_t *dst; - const uint32_t *codebook; - int entries[6]; - int i, j, m, n; - int mean, stages; - int x, y, width, height, level; - uint32_t n1, n2, n3, n4; - - /* initialize list for breadth first processing of vectors */ - list[0] = pixels; - - /* recursively process vector */ - for (i=0, m=1, n=1, level=5; i < n; i++) { - SVQ1_PROCESS_VECTOR(); - - /* destination address and vector size */ - dst = (uint32_t *) list[i]; - width = 1 << ((4 + level) /2); - height = 1 << ((3 + level) /2); - - /* get number of stages (-1 skips vector, 0 for mean only) */ - stages = get_vlc2(bitbuf, svq1_inter_multistage[level].table, 3, 2) - 1; - - if (stages == -1) continue; /* skip vector */ - - if ((stages > 0) && (level >= 4)) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n",stages,level); -#endif - return -1; /* invalid vector */ - } - - mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256; - - SVQ1_CALC_CODEBOOK_ENTRIES(svq1_inter_codebooks); - SVQ1_DO_CODEBOOK_NONINTRA() - } - return 0; -} - -static int svq1_decode_motion_vector (GetBitContext *bitbuf, svq1_pmv_t *mv, svq1_pmv_t **pmv) { - int diff; - int i; - - for (i=0; i < 2; i++) { - - /* get motion code */ - diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2); - if(diff<0) - return -1; - else if(diff){ - if(get_bits1(bitbuf)) diff= -diff; - } - - /* add median of motion vector predictors and clip result */ - if (i == 1) - mv->y = ((diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26; - else - mv->x = ((diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26; - } - - return 0; -} - -static void svq1_skip_block (uint8_t *current, uint8_t *previous, int pitch, int x, int y) { - uint8_t *src; - uint8_t *dst; - int i; - - src = &previous[x + y*pitch]; - dst = current; - - for (i=0; i < 16; i++) { - memcpy (dst, src, 16); - src += pitch; - dst += pitch; - } -} - -static int svq1_motion_inter_block (MpegEncContext *s, GetBitContext *bitbuf, - uint8_t *current, uint8_t *previous, int pitch, - svq1_pmv_t *motion, int x, int y) { - uint8_t *src; - uint8_t *dst; - svq1_pmv_t mv; - svq1_pmv_t *pmv[3]; - int result; - - /* predict and decode motion vector */ - pmv[0] = &motion[0]; - if (y == 0) { - pmv[1] = - pmv[2] = pmv[0]; - } - else { - pmv[1] = &motion[(x / 8) + 2]; - pmv[2] = &motion[(x / 8) + 4]; - } - - result = svq1_decode_motion_vector (bitbuf, &mv, pmv); - - if (result != 0) - return result; - - motion[0].x = - motion[(x / 8) + 2].x = - motion[(x / 8) + 3].x = mv.x; - motion[0].y = - motion[(x / 8) + 2].y = - motion[(x / 8) + 3].y = mv.y; - - if(y + (mv.y >> 1)<0) - mv.y= 0; - if(x + (mv.x >> 1)<0) - mv.x= 0; - -#if 0 - int w= (s->width+15)&~15; - int h= (s->height+15)&~15; - if(x + (mv.x >> 1)<0 || y + (mv.y >> 1)<0 || x + (mv.x >> 1) + 16 > w || y + (mv.y >> 1) + 16> h) - av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mv.x >> 1), y + (mv.y >> 1)); -#endif - - src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1))*pitch]; - dst = current; - - s->dsp.put_pixels_tab[0][((mv.y & 1) << 1) | (mv.x & 1)](dst,src,pitch,16); - - return 0; -} - -static int svq1_motion_inter_4v_block (MpegEncContext *s, GetBitContext *bitbuf, - uint8_t *current, uint8_t *previous, int pitch, - svq1_pmv_t *motion,int x, int y) { - uint8_t *src; - uint8_t *dst; - svq1_pmv_t mv; - svq1_pmv_t *pmv[4]; - int i, result; - - /* predict and decode motion vector (0) */ - pmv[0] = &motion[0]; - if (y == 0) { - pmv[1] = - pmv[2] = pmv[0]; - } - else { - pmv[1] = &motion[(x / 8) + 2]; - pmv[2] = &motion[(x / 8) + 4]; - } - - result = svq1_decode_motion_vector (bitbuf, &mv, pmv); - - if (result != 0) - return result; - - /* predict and decode motion vector (1) */ - pmv[0] = &mv; - if (y == 0) { - pmv[1] = - pmv[2] = pmv[0]; - } - else { - pmv[1] = &motion[(x / 8) + 3]; - } - result = svq1_decode_motion_vector (bitbuf, &motion[0], pmv); - - if (result != 0) - return result; - - /* predict and decode motion vector (2) */ - pmv[1] = &motion[0]; - pmv[2] = &motion[(x / 8) + 1]; - - result = svq1_decode_motion_vector (bitbuf, &motion[(x / 8) + 2], pmv); - - if (result != 0) - return result; - - /* predict and decode motion vector (3) */ - pmv[2] = &motion[(x / 8) + 2]; - pmv[3] = &motion[(x / 8) + 3]; - - result = svq1_decode_motion_vector (bitbuf, pmv[3], pmv); - - if (result != 0) - return result; - - /* form predictions */ - for (i=0; i < 4; i++) { - int mvx= pmv[i]->x + (i&1)*16; - int mvy= pmv[i]->y + (i>>1)*16; - - ///XXX /FIXME cliping or padding? - if(y + (mvy >> 1)<0) - mvy= 0; - if(x + (mvx >> 1)<0) - mvx= 0; - -#if 0 - int w= (s->width+15)&~15; - int h= (s->height+15)&~15; - if(x + (mvx >> 1)<0 || y + (mvy >> 1)<0 || x + (mvx >> 1) + 8 > w || y + (mvy >> 1) + 8> h) - av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mvx >> 1), y + (mvy >> 1)); -#endif - src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1))*pitch]; - dst = current; - - s->dsp.put_pixels_tab[1][((mvy & 1) << 1) | (mvx & 1)](dst,src,pitch,8); - - /* select next block */ - if (i & 1) { - current += 8*(pitch - 1); - } else { - current += 8; - } - } - - return 0; -} - -static int svq1_decode_delta_block (MpegEncContext *s, GetBitContext *bitbuf, - uint8_t *current, uint8_t *previous, int pitch, - svq1_pmv_t *motion, int x, int y) { - uint32_t block_type; - int result = 0; - - /* get block type */ - block_type = get_vlc2(bitbuf, svq1_block_type.table, 2, 2); - - /* reset motion vectors */ - if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) { - motion[0].x = - motion[0].y = - motion[(x / 8) + 2].x = - motion[(x / 8) + 2].y = - motion[(x / 8) + 3].x = - motion[(x / 8) + 3].y = 0; - } - - switch (block_type) { - case SVQ1_BLOCK_SKIP: - svq1_skip_block (current, previous, pitch, x, y); - break; - - case SVQ1_BLOCK_INTER: - result = svq1_motion_inter_block (s, bitbuf, current, previous, pitch, motion, x, y); - - if (result != 0) - { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_block %i\n",result); -#endif - break; - } - result = svq1_decode_block_non_intra (bitbuf, current, pitch); - break; - - case SVQ1_BLOCK_INTER_4V: - result = svq1_motion_inter_4v_block (s, bitbuf, current, previous, pitch, motion, x, y); - - if (result != 0) - { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_4v_block %i\n",result); -#endif - break; - } - result = svq1_decode_block_non_intra (bitbuf, current, pitch); - break; - - case SVQ1_BLOCK_INTRA: - result = svq1_decode_block_intra (bitbuf, current, pitch); - break; - } - - return result; -} - /* standard video sizes */ -static struct { int width; int height; } svq1_frame_size_table[8] = { +const svq1_frame_size_t ff_svq1_frame_size_table[8] = { { 160, 120 }, { 128, 96 }, { 176, 144 }, { 352, 288 }, { 704, 576 }, { 240, 180 }, { 320, 240 }, { -1, -1 } }; - -static uint16_t svq1_packet_checksum (uint8_t *data, int length, int value) { - int i; - - for (i=0; i < length; i++) { - value = checksum_table[data[i] ^ (value >> 8)] ^ ((value & 0xFF) << 8); - } - - return value; -} - -#if 0 /* unused, remove? */ -static uint16_t svq1_component_checksum (uint16_t *pixels, int pitch, - int width, int height, int value) { - int x, y; - - for (y=0; y < height; y++) { - for (x=0; x < width; x++) { - value = checksum_table[pixels[x] ^ (value >> 8)] ^ ((value & 0xFF) << 8); - } - - pixels += pitch; - } - - return value; -} -#endif - -#ifdef CONFIG_DECODERS -static void svq1_parse_string (GetBitContext *bitbuf, uint8_t *out) { - uint8_t seed; - int i; - - out[0] = get_bits (bitbuf, 8); - - seed = string_table[out[0]]; - - for (i=1; i <= out[0]; i++) { - out[i] = get_bits (bitbuf, 8) ^ seed; - seed = string_table[out[i] ^ seed]; - } -} - -static int svq1_decode_frame_header (GetBitContext *bitbuf,MpegEncContext *s) { - int frame_size_code; - int temporal_reference; - - temporal_reference = get_bits (bitbuf, 8); - - /* frame type */ - s->pict_type= get_bits (bitbuf, 2)+1; - if(s->pict_type==4) - return -1; - - if (s->pict_type == I_TYPE) { - - /* unknown fields */ - if (s->f_code == 0x50 || s->f_code == 0x60) { - int csum = get_bits (bitbuf, 16); - - csum = svq1_packet_checksum ((uint8_t *)bitbuf->buffer, bitbuf->size_in_bits>>3, csum); - -// av_log(s->avctx, AV_LOG_INFO, "%s checksum (%02x) for packet data\n", -// (csum == 0) ? "correct" : "incorrect", csum); - } - - if ((s->f_code ^ 0x10) >= 0x50) { - uint8_t msg[256]; - - svq1_parse_string (bitbuf, msg); - - av_log(s->avctx, AV_LOG_INFO, "embedded message: \"%s\"\n", (char *) msg); - } - - skip_bits (bitbuf, 2); - skip_bits (bitbuf, 2); - skip_bits1 (bitbuf); - - /* load frame size */ - frame_size_code = get_bits (bitbuf, 3); - - if (frame_size_code == 7) { - /* load width, height (12 bits each) */ - s->width = get_bits (bitbuf, 12); - s->height = get_bits (bitbuf, 12); - - if (!s->width || !s->height) - return -1; - } else { - /* get width, height from table */ - s->width = svq1_frame_size_table[frame_size_code].width; - s->height = svq1_frame_size_table[frame_size_code].height; - } - } - - /* unknown fields */ - if (get_bits (bitbuf, 1) == 1) { - skip_bits1 (bitbuf); /* use packet checksum if (1) */ - skip_bits1 (bitbuf); /* component checksums after image data if (1) */ - - if (get_bits (bitbuf, 2) != 0) - return -1; - } - - if (get_bits (bitbuf, 1) == 1) { - skip_bits1 (bitbuf); - skip_bits (bitbuf, 4); - skip_bits1 (bitbuf); - skip_bits (bitbuf, 2); - - while (get_bits (bitbuf, 1) == 1) { - skip_bits (bitbuf, 8); - } - } - - return 0; -} - -static int svq1_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - MpegEncContext *s=avctx->priv_data; - uint8_t *current, *previous; - int result, i, x, y, width, height; - AVFrame *pict = data; - - /* initialize bit buffer */ - init_get_bits(&s->gb,buf,buf_size*8); - - /* decode frame header */ - s->f_code = get_bits (&s->gb, 22); - - if ((s->f_code & ~0x70) || !(s->f_code & 0x60)) - return -1; - - /* swap some header bytes (why?) */ - if (s->f_code != 0x20) { - uint32_t *src = (uint32_t *) (buf + 4); - - for (i=0; i < 4; i++) { - src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; - } - } - - result = svq1_decode_frame_header (&s->gb, s); - - if (result != 0) - { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_frame_header %i\n",result); -#endif - return result; - } - - //FIXME this avoids some confusion for "B frames" without 2 references - //this should be removed after libavcodec can handle more flexible picture types & ordering - if(s->pict_type==B_TYPE && s->last_picture_ptr==NULL) return buf_size; - - if(avctx->hurry_up && s->pict_type==B_TYPE) return buf_size; - if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) - ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) - || avctx->skip_frame >= AVDISCARD_ALL) - return buf_size; - - if(MPV_frame_start(s, avctx) < 0) - return -1; - - /* decode y, u and v components */ - for (i=0; i < 3; i++) { - int linesize; - if (i == 0) { - width = (s->width+15)&~15; - height = (s->height+15)&~15; - linesize= s->linesize; - } else { - if(s->flags&CODEC_FLAG_GRAY) break; - width = (s->width/4+15)&~15; - height = (s->height/4+15)&~15; - linesize= s->uvlinesize; - } - - current = s->current_picture.data[i]; - - if(s->pict_type==B_TYPE){ - previous = s->next_picture.data[i]; - }else{ - previous = s->last_picture.data[i]; - } - - if (s->pict_type == I_TYPE) { - /* keyframe */ - for (y=0; y < height; y+=16) { - for (x=0; x < width; x+=16) { - result = svq1_decode_block_intra (&s->gb, ¤t[x], linesize); - if (result != 0) - { -//#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_block %i (keyframe)\n",result); -//#endif - return result; - } - } - current += 16*linesize; - } - } else { - svq1_pmv_t pmv[width/8+3]; - /* delta frame */ - memset (pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv_t)); - - for (y=0; y < height; y+=16) { - for (x=0; x < width; x+=16) { - result = svq1_decode_delta_block (s, &s->gb, ¤t[x], previous, - linesize, pmv, x, y); - if (result != 0) - { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_delta_block %i\n",result); -#endif - return result; - } - } - - pmv[0].x = - pmv[0].y = 0; - - current += 16*linesize; - } - } - } - - *pict = *(AVFrame*)&s->current_picture; - - - MPV_frame_end(s); - - *data_size=sizeof(AVFrame); - return buf_size; -} - -static int svq1_decode_init(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - int i; - - MPV_decode_defaults(s); - - s->avctx = avctx; - s->width = (avctx->width+3)&~3; - s->height = (avctx->height+3)&~3; - s->codec_id= avctx->codec->id; - avctx->pix_fmt = PIX_FMT_YUV410P; - avctx->has_b_frames= 1; // not true, but DP frames and these behave like unidirectional b frames - s->flags= avctx->flags; - if (MPV_common_init(s) < 0) return -1; - - init_vlc(&svq1_block_type, 2, 4, - &svq1_block_type_vlc[0][1], 2, 1, - &svq1_block_type_vlc[0][0], 2, 1, 1); - - init_vlc(&svq1_motion_component, 7, 33, - &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 1); - - for (i = 0; i < 6; i++) { - init_vlc(&svq1_intra_multistage[i], 3, 8, - &svq1_intra_multistage_vlc[i][0][1], 2, 1, - &svq1_intra_multistage_vlc[i][0][0], 2, 1, 1); - init_vlc(&svq1_inter_multistage[i], 3, 8, - &svq1_inter_multistage_vlc[i][0][1], 2, 1, - &svq1_inter_multistage_vlc[i][0][0], 2, 1, 1); - } - - init_vlc(&svq1_intra_mean, 8, 256, - &svq1_intra_mean_vlc[0][1], 4, 2, - &svq1_intra_mean_vlc[0][0], 4, 2, 1); - - init_vlc(&svq1_inter_mean, 9, 512, - &svq1_inter_mean_vlc[0][1], 4, 2, - &svq1_inter_mean_vlc[0][0], 4, 2, 1); - - return 0; -} - -static int svq1_decode_end(AVCodecContext *avctx) -{ - MpegEncContext *s = avctx->priv_data; - - MPV_common_end(s); - return 0; -} -#endif /* CONFIG_DECODERS */ - -#ifdef CONFIG_ENCODERS -static void svq1_write_header(SVQ1Context *s, int frame_type) -{ - int i; - - /* frame code */ - put_bits(&s->pb, 22, 0x20); - - /* temporal reference (sure hope this is a "don't care") */ - put_bits(&s->pb, 8, 0x00); - - /* frame type */ - put_bits(&s->pb, 2, frame_type - 1); - - if (frame_type == I_TYPE) { - - /* no checksum since frame code is 0x20 */ - - /* no embedded string either */ - - /* output 5 unknown bits (2 + 2 + 1) */ - put_bits(&s->pb, 5, 2); /* 2 needed by quicktime decoder */ - - for (i = 0; i < 7; i++) - { - if ((svq1_frame_size_table[i].width == s->frame_width) && - (svq1_frame_size_table[i].height == s->frame_height)) - { - put_bits(&s->pb, 3, i); - break; - } - } - - if (i == 7) - { - put_bits(&s->pb, 3, 7); - put_bits(&s->pb, 12, s->frame_width); - put_bits(&s->pb, 12, s->frame_height); - } - } - - /* no checksum or extra data (next 2 bits get 0) */ - put_bits(&s->pb, 2, 0); -} - - -#define QUALITY_THRESHOLD 100 -#define THRESHOLD_MULTIPLIER 0.6 - -#if defined(HAVE_ALTIVEC) -#undef vector -#endif - -static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){ - int count, y, x, i, j, split, best_mean, best_score, best_count; - int best_vector[6]; - int block_sum[7]= {0, 0, 0, 0, 0, 0}; - int w= 2<<((level+2)>>1); - int h= 2<<((level+1)>>1); - int size=w*h; - int16_t block[7][256]; - const int8_t *codebook_sum, *codebook; - const uint16_t (*mean_vlc)[2]; - const uint8_t (*multistage_vlc)[2]; - - best_score=0; - //FIXME optimize, this doenst need to be done multiple times - if(intra){ - codebook_sum= svq1_intra_codebook_sum[level]; - codebook= svq1_intra_codebooks[level]; - mean_vlc= svq1_intra_mean_vlc; - multistage_vlc= svq1_intra_multistage_vlc[level]; - for(y=0; y<h; y++){ - for(x=0; x<w; x++){ - int v= src[x + y*stride]; - block[0][x + w*y]= v; - best_score += v*v; - block_sum[0] += v; - } - } - }else{ - codebook_sum= svq1_inter_codebook_sum[level]; - codebook= svq1_inter_codebooks[level]; - mean_vlc= svq1_inter_mean_vlc + 256; - multistage_vlc= svq1_inter_multistage_vlc[level]; - for(y=0; y<h; y++){ - for(x=0; x<w; x++){ - int v= src[x + y*stride] - ref[x + y*stride]; - block[0][x + w*y]= v; - best_score += v*v; - block_sum[0] += v; - } - } - } - - best_count=0; - best_score -= ((block_sum[0]*block_sum[0])>>(level+3)); - best_mean= (block_sum[0] + (size>>1)) >> (level+3); - - if(level<4){ - for(count=1; count<7; count++){ - int best_vector_score= INT_MAX; - int best_vector_sum=-999, best_vector_mean=-999; - const int stage= count-1; - const int8_t *vector; - - for(i=0; i<16; i++){ - int sum= codebook_sum[stage*16 + i]; - int sqr, diff, score; - - vector = codebook + stage*size*16 + i*size; - sqr = s->dsp.ssd_int8_vs_int16(vector, block[stage], size); - diff= block_sum[stage] - sum; - score= sqr - ((diff*(int64_t)diff)>>(level+3)); //FIXME 64bit slooow - if(score < best_vector_score){ - int mean= (diff + (size>>1)) >> (level+3); - assert(mean >-300 && mean<300); - mean= av_clip(mean, intra?0:-256, 255); - best_vector_score= score; - best_vector[stage]= i; - best_vector_sum= sum; - best_vector_mean= mean; - } - } - assert(best_vector_mean != -999); - vector= codebook + stage*size*16 + best_vector[stage]*size; - for(j=0; j<size; j++){ - block[stage+1][j] = block[stage][j] - vector[j]; - } - block_sum[stage+1]= block_sum[stage] - best_vector_sum; - best_vector_score += - lambda*(+ 1 + 4*count - + multistage_vlc[1+count][1] - + mean_vlc[best_vector_mean][1]); - - if(best_vector_score < best_score){ - best_score= best_vector_score; - best_count= count; - best_mean= best_vector_mean; - } - } - } - - split=0; - if(best_score > threshold && level){ - int score=0; - int offset= (level&1) ? stride*h/2 : w/2; - PutBitContext backup[6]; - - for(i=level-1; i>=0; i--){ - backup[i]= s->reorder_pb[i]; - } - score += encode_block(s, src , ref , decoded , stride, level-1, threshold>>1, lambda, intra); - score += encode_block(s, src + offset, ref + offset, decoded + offset, stride, level-1, threshold>>1, lambda, intra); - score += lambda; - - if(score < best_score){ - best_score= score; - split=1; - }else{ - for(i=level-1; i>=0; i--){ - s->reorder_pb[i]= backup[i]; - } - } - } - if (level > 0) - put_bits(&s->reorder_pb[level], 1, split); - - if(!split){ - assert((best_mean >= 0 && best_mean<256) || !intra); - assert(best_mean >= -256 && best_mean<256); - assert(best_count >=0 && best_count<7); - assert(level<4 || best_count==0); - - /* output the encoding */ - put_bits(&s->reorder_pb[level], - multistage_vlc[1 + best_count][1], - multistage_vlc[1 + best_count][0]); - put_bits(&s->reorder_pb[level], mean_vlc[best_mean][1], - mean_vlc[best_mean][0]); - - for (i = 0; i < best_count; i++){ - assert(best_vector[i]>=0 && best_vector[i]<16); - put_bits(&s->reorder_pb[level], 4, best_vector[i]); - } - - for(y=0; y<h; y++){ - for(x=0; x<w; x++){ - decoded[x + y*stride]= src[x + y*stride] - block[best_count][x + w*y] + best_mean; - } - } - } - - return best_score; -} - - -static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane, - int width, int height, int src_stride, int stride) -{ - int x, y; - int i; - int block_width, block_height; - int level; - int threshold[6]; - const int lambda= (s->picture.quality*s->picture.quality) >> (2*FF_LAMBDA_SHIFT); - - /* figure out the acceptable level thresholds in advance */ - threshold[5] = QUALITY_THRESHOLD; - for (level = 4; level >= 0; level--) - threshold[level] = threshold[level + 1] * THRESHOLD_MULTIPLIER; - - block_width = (width + 15) / 16; - block_height = (height + 15) / 16; - - if(s->picture.pict_type == P_TYPE){ - s->m.avctx= s->avctx; - s->m.current_picture_ptr= &s->m.current_picture; - s->m.last_picture_ptr = &s->m.last_picture; - s->m.last_picture.data[0]= ref_plane; - s->m.linesize= - s->m.last_picture.linesize[0]= - s->m.new_picture.linesize[0]= - s->m.current_picture.linesize[0]= stride; - s->m.width= width; - s->m.height= height; - s->m.mb_width= block_width; - s->m.mb_height= block_height; - s->m.mb_stride= s->m.mb_width+1; - s->m.b8_stride= 2*s->m.mb_width+1; - s->m.f_code=1; - s->m.pict_type= s->picture.pict_type; - s->m.me_method= s->avctx->me_method; - s->m.me.scene_change_score=0; - s->m.flags= s->avctx->flags; -// s->m.out_format = FMT_H263; -// s->m.unrestricted_mv= 1; - - s->m.lambda= s->picture.quality; - s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); - s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT; - - if(!s->motion_val8[plane]){ - s->motion_val8 [plane]= av_mallocz((s->m.b8_stride*block_height*2 + 2)*2*sizeof(int16_t)); - s->motion_val16[plane]= av_mallocz((s->m.mb_stride*(block_height + 2) + 1)*2*sizeof(int16_t)); - } - - s->m.mb_type= s->mb_type; - - //dummies, to avoid segfaults - s->m.current_picture.mb_mean= (uint8_t *)s->dummy; - s->m.current_picture.mb_var= (uint16_t*)s->dummy; - s->m.current_picture.mc_mb_var= (uint16_t*)s->dummy; - s->m.current_picture.mb_type= s->dummy; - - s->m.current_picture.motion_val[0]= s->motion_val8[plane] + 2; - s->m.p_mv_table= s->motion_val16[plane] + s->m.mb_stride + 1; - s->m.dsp= s->dsp; //move - ff_init_me(&s->m); - - s->m.me.dia_size= s->avctx->dia_size; - s->m.first_slice_line=1; - for (y = 0; y < block_height; y++) { - uint8_t src[stride*16]; - - s->m.new_picture.data[0]= src - y*16*stride; //ugly - s->m.mb_y= y; - - for(i=0; i<16 && i + 16*y<height; i++){ - memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width); - for(x=width; x<16*block_width; x++) - src[i*stride+x]= src[i*stride+x-1]; - } - for(; i<16 && i + 16*y<16*block_height; i++) - memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width); - - for (x = 0; x < block_width; x++) { - s->m.mb_x= x; - ff_init_block_index(&s->m); - ff_update_block_index(&s->m); - - ff_estimate_p_frame_motion(&s->m, x, y); - } - s->m.first_slice_line=0; - } - - ff_fix_long_p_mvs(&s->m); - ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s->m.f_code, CANDIDATE_MB_TYPE_INTER, 0); - } - - s->m.first_slice_line=1; - for (y = 0; y < block_height; y++) { - uint8_t src[stride*16]; - - for(i=0; i<16 && i + 16*y<height; i++){ - memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width); - for(x=width; x<16*block_width; x++) - src[i*stride+x]= src[i*stride+x-1]; - } - for(; i<16 && i + 16*y<16*block_height; i++) - memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width); - - s->m.mb_y= y; - for (x = 0; x < block_width; x++) { - uint8_t reorder_buffer[3][6][7*32]; - int count[3][6]; - int offset = y * 16 * stride + x * 16; - uint8_t *decoded= decoded_plane + offset; - uint8_t *ref= ref_plane + offset; - int score[4]={0,0,0,0}, best; - uint8_t temp[16*stride]; - - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3000){ //FIXME check size - av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); - return -1; - } - - s->m.mb_x= x; - ff_init_block_index(&s->m); - ff_update_block_index(&s->m); - - if(s->picture.pict_type == I_TYPE || (s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTRA)){ - for(i=0; i<6; i++){ - init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32); - } - if(s->picture.pict_type == P_TYPE){ - const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; - put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); - score[0]= vlc[1]*lambda; - } - score[0]+= encode_block(s, src+16*x, NULL, temp, stride, 5, 64, lambda, 1); - for(i=0; i<6; i++){ - count[0][i]= put_bits_count(&s->reorder_pb[i]); - flush_put_bits(&s->reorder_pb[i]); - } - }else - score[0]= INT_MAX; - - best=0; - - if(s->picture.pict_type == P_TYPE){ - const uint8_t *vlc= svq1_block_type_vlc[SVQ1_BLOCK_INTER]; - int mx, my, pred_x, pred_y, dxy; - int16_t *motion_ptr; - - motion_ptr= h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); - if(s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER){ - for(i=0; i<6; i++) - init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32); - - put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); - - s->m.pb= s->reorder_pb[5]; - mx= motion_ptr[0]; - my= motion_ptr[1]; - assert(mx>=-32 && mx<=31); - assert(my>=-32 && my<=31); - assert(pred_x>=-32 && pred_x<=31); - assert(pred_y>=-32 && pred_y<=31); - ff_h263_encode_motion(&s->m, mx - pred_x, 1); - ff_h263_encode_motion(&s->m, my - pred_y, 1); - s->reorder_pb[5]= s->m.pb; - score[1] += lambda*put_bits_count(&s->reorder_pb[5]); - - dxy= (mx&1) + 2*(my&1); - - s->dsp.put_pixels_tab[0][dxy](temp+16, ref + (mx>>1) + stride*(my>>1), stride, 16); - - score[1]+= encode_block(s, src+16*x, temp+16, decoded, stride, 5, 64, lambda, 0); - best= score[1] <= score[0]; - - vlc= svq1_block_type_vlc[SVQ1_BLOCK_SKIP]; - score[2]= s->dsp.sse[0](NULL, src+16*x, ref, stride, 16); - score[2]+= vlc[1]*lambda; - if(score[2] < score[best] && mx==0 && my==0){ - best=2; - s->dsp.put_pixels_tab[0][0](decoded, ref, stride, 16); - for(i=0; i<6; i++){ - count[2][i]=0; - } - put_bits(&s->pb, vlc[1], vlc[0]); - } - } - - if(best==1){ - for(i=0; i<6; i++){ - count[1][i]= put_bits_count(&s->reorder_pb[i]); - flush_put_bits(&s->reorder_pb[i]); - } - }else{ - motion_ptr[0 ] = motion_ptr[1 ]= - motion_ptr[2 ] = motion_ptr[3 ]= - motion_ptr[0+2*s->m.b8_stride] = motion_ptr[1+2*s->m.b8_stride]= - motion_ptr[2+2*s->m.b8_stride] = motion_ptr[3+2*s->m.b8_stride]=0; - } - } - - s->rd_total += score[best]; - - for(i=5; i>=0; i--){ - ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]); - } - if(best==0){ - s->dsp.put_pixels_tab[0][0](decoded, temp, stride, 16); - } - } - s->m.first_slice_line=0; - } - return 0; -} - -static int svq1_encode_init(AVCodecContext *avctx) -{ - SVQ1Context * const s = avctx->priv_data; - - dsputil_init(&s->dsp, avctx); - avctx->coded_frame= (AVFrame*)&s->picture; - - s->frame_width = avctx->width; - s->frame_height = avctx->height; - - s->y_block_width = (s->frame_width + 15) / 16; - s->y_block_height = (s->frame_height + 15) / 16; - - s->c_block_width = (s->frame_width / 4 + 15) / 16; - s->c_block_height = (s->frame_height / 4 + 15) / 16; - - s->avctx= avctx; - s->m.avctx= avctx; - s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t)); - s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); - s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); - s->mb_type = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int16_t)); - s->dummy = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int32_t)); - h263_encode_init(&s->m); //mv_penalty - - return 0; -} - -static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf, - int buf_size, void *data) -{ - SVQ1Context * const s = avctx->priv_data; - AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&s->picture; - AVFrame temp; - int i; - - if(avctx->pix_fmt != PIX_FMT_YUV410P){ - av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); - return -1; - } - - if(!s->current_picture.data[0]){ - avctx->get_buffer(avctx, &s->current_picture); - avctx->get_buffer(avctx, &s->last_picture); - } - - temp= s->current_picture; - s->current_picture= s->last_picture; - s->last_picture= temp; - - init_put_bits(&s->pb, buf, buf_size); - - *p = *pict; - p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ? P_TYPE : I_TYPE; - p->key_frame = p->pict_type == I_TYPE; - - svq1_write_header(s, p->pict_type); - for(i=0; i<3; i++){ - if(svq1_encode_plane(s, i, - s->picture.data[i], s->last_picture.data[i], s->current_picture.data[i], - s->frame_width / (i?4:1), s->frame_height / (i?4:1), - s->picture.linesize[i], s->current_picture.linesize[i]) < 0) - return -1; - } - -// align_put_bits(&s->pb); - while(put_bits_count(&s->pb) & 31) - put_bits(&s->pb, 1, 0); - - flush_put_bits(&s->pb); - - return (put_bits_count(&s->pb) / 8); -} - -static int svq1_encode_end(AVCodecContext *avctx) -{ - SVQ1Context * const s = avctx->priv_data; - int i; - - av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", s->rd_total/(double)(avctx->width*avctx->height*avctx->frame_number)); - - av_freep(&s->m.me.scratchpad); - av_freep(&s->m.me.map); - av_freep(&s->m.me.score_map); - av_freep(&s->mb_type); - av_freep(&s->dummy); - - for(i=0; i<3; i++){ - av_freep(&s->motion_val8[i]); - av_freep(&s->motion_val16[i]); - } - - return 0; -} - -#endif //CONFIG_ENCODERS - -#ifdef CONFIG_DECODERS -AVCodec svq1_decoder = { - "svq1", - CODEC_TYPE_VIDEO, - CODEC_ID_SVQ1, - sizeof(MpegEncContext), - svq1_decode_init, - NULL, - svq1_decode_end, - svq1_decode_frame, - CODEC_CAP_DR1, - .flush= ff_mpeg_flush, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV410P, -1}, -}; -#endif - -#ifdef CONFIG_ENCODERS - -AVCodec svq1_encoder = { - "svq1", - CODEC_TYPE_VIDEO, - CODEC_ID_SVQ1, - sizeof(SVQ1Context), - svq1_encode_init, - svq1_encode_frame, - svq1_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV410P, -1}, -}; - -#endif //CONFIG_ENCODERS diff --git a/contrib/ffmpeg/libavcodec/svq1.h b/contrib/ffmpeg/libavcodec/svq1.h new file mode 100644 index 000000000..7764dd8dd --- /dev/null +++ b/contrib/ffmpeg/libavcodec/svq1.h @@ -0,0 +1,61 @@ +/* + * SVQ1 decoder + * ported to MPlayer by Arpi <arpi@thot.banki.hu> + * ported to libavcodec by Nick Kurshev <nickols_k@mail.ru> + * + * Copyright (C) 2002 the xine project + * Copyright (C) 2002 the ffmpeg project + * + * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net> + * + * 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 svq1.h + * Sorenson Vector Quantizer #1 (SVQ1) video codec. + * For more information of the SVQ1 algorithm, visit: + * http://www.pcisys.net/~melanson/codecs/ + */ + +#ifndef FFMPEG_SVQ1_H +#define FFMPEG_SVQ1_H + +#include <stdint.h> + +#define SVQ1_BLOCK_SKIP 0 +#define SVQ1_BLOCK_INTER 1 +#define SVQ1_BLOCK_INTER_4V 2 +#define SVQ1_BLOCK_INTRA 3 + +typedef struct { + int width; + int height; +} svq1_frame_size_t; + +extern const int8_t* const ff_svq1_inter_codebooks[6]; +extern const int8_t* const ff_svq1_intra_codebooks[6]; + +extern const uint8_t ff_svq1_block_type_vlc[4][2]; +extern const uint8_t ff_svq1_intra_multistage_vlc[6][8][2]; +extern const uint8_t ff_svq1_inter_multistage_vlc[6][8][2]; +extern const uint16_t ff_svq1_intra_mean_vlc[256][2]; +extern const uint16_t ff_svq1_inter_mean_vlc[512][2]; + +extern const svq1_frame_size_t ff_svq1_frame_size_table[8]; + +#endif /* FFMPEG_SVQ1_H */ diff --git a/contrib/ffmpeg/libavcodec/svq1_cb.h b/contrib/ffmpeg/libavcodec/svq1_cb.h index a0748bd44..f4a4054d1 100644 --- a/contrib/ffmpeg/libavcodec/svq1_cb.h +++ b/contrib/ffmpeg/libavcodec/svq1_cb.h @@ -1,4 +1,7 @@ /* + * SVQ1 decoder + * ported to MPlayer by Arpi <arpi@thot.banki.hu> + * ported to libavcodec by Nick Kurshev <nickols_k@mail.ru> * * Copyright (C) 2002 the xine project * Copyright (C) 2002 the ffmpeg project @@ -18,10 +21,6 @@ * 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 - * - * Ported to mplayer by Arpi <arpi@thot.banki.hu> - * Ported to libavcodec by Nick Kurshev <nickols_k@mail.ru> - * */ /** @@ -29,6 +28,12 @@ * svq1 code books. */ +#ifndef FFMPEG_SVQ1_CB_H +#define FFMPEG_SVQ1_CB_H + +#include <stdint.h> +#include <stdlib.h> + /* 6x16-entry codebook for inter-coded 4x2 vectors */ static const int8_t svq1_inter_codebook_4x2[768] = { 7, 2, -6, -7, 7, 3, -3, -4, -7, -2, 7, 8, -8, -4, 3, 4, @@ -766,44 +771,12 @@ static const int8_t svq1_inter_codebook_8x8[6144] = { }; /* list of codebooks for inter-coded vectors */ -static const int8_t* const svq1_inter_codebooks[6] = { +const int8_t* const ff_svq1_inter_codebooks[6] = { svq1_inter_codebook_4x2, svq1_inter_codebook_4x4, svq1_inter_codebook_8x4, svq1_inter_codebook_8x8, NULL, NULL, }; -static const int8_t svq1_inter_codebook_sum[4][16*6] = { - { - -1, 1, -2, 0, 1, -1, -1, -1, -2, -1, 1, -1, -1, 0, -1, -1, - 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, -3, 1, -1, 0, 1, -1, - 1, -1, 2, 2, 1, 1, 2, 0, 0, 0, -1, 1, 1, 0, 0, 0, - 1, -1, 0, 1, -1, 1, 1, 0, 1, 0, -1, 1, 1, 0, 0, 0, - -2, 0, 0, -2, 0, 0, -2, 0, -2, -1, -2, -1, 0, 0, -1, 0, - 1, 0, 1, -1, 2, 2, 1, 2, 2, 1, 0, 1, 1, 0, 1, 1, - },{ - -2, 1, -1, -1, 1, 0, 1, -1, -1, -1, 1, -1, 0, -1, 0, -1, - 0, 0, 0, -2, 0, 1, 0, -1, -1, 0, 2, -3, 1, -2, 3, -1, - 2, 0, 2, 1, 1, -1, 1, 1, 0, 0, 1, 1, 2, -2, 1, 0, - -2, -1, 2, -2, -2, 0, -3, 0, -1, 0, -1, 0, -1, 0, -2, -3, - 1, -2, -2, -1, 1, -1, -1, 1, -1, 1, 1, 0, -2, 0, 1, 1, - 1, 1, 2, 1, 0, 0, -1, 0, 0, 1, 0, 1, -1, 1, 0, 2, - },{ - 0, 0, 0, -3, 1, 1, 1, -3, 0, -1, 0, -3, 1, -3, 0, -2, - 1, 2, -1, -3, 0, -3, 1, -1, 0, -1, 0, 0, 1, 2, 1, 1, - -1, 2, -3, 3, 1, 0, -5, 1, 0, -1, -3, 1, 0, 2, 0, -3, - 4, 2, 0, -2, 1, -2, 3, -2, 1, 1, 0, -1, 2, 5, 3, 1, - -1, 0, 2, -3, -2, 0, 0, -2, 2, -3, -1, -1, 2, 1, 0, -2, - 3, -1, 1, -1, 2, 4, 0, 1, 0, 1, 0, -1, -3, -2, -1, 0, - },{ - 0, 2, -1, -1, 2, -4, -2, 3, 0, -1, -5, 1, 0, 1, 0, 6, - -2, 2, 0, 1, 1, -1, -1, -2, 1, -2, -1, 0, 2, -2, -2, -1, - -4, 2, -1, -3, -1, -2, 2, -1, 2, -1, 2, 0, 3, -3, -3, 0, - -3, 0, 0, -2, 4, -4, 0, -1, 4, 0, -2, -2, 3, -2, 0, 4, - 5, 0, 1, 0, -3, 3, 3, 2, 0, 0, 1, 2, -5, -2, -3, 0, - -3, 2, -2, 2, -2, 4, 7, -3, 4, 2, 3, 2, -1, 0, -3, 1, - } -}; - /* 6x16-entry codebook for intra-coded 4x2 vectors */ static const int8_t svq1_intra_codebook_4x2[768] = { 12, 13, 13, 11, -7,-10,-15,-17,-16,-15,-12,-10, 11, 15, 15, 12, @@ -1541,40 +1514,10 @@ static const int8_t svq1_intra_codebook_8x8[6144] = { }; /* list of codebooks for intra-coded vectors */ -static const int8_t* const svq1_intra_codebooks[6] = { +const int8_t* const ff_svq1_intra_codebooks[6] = { svq1_intra_codebook_4x2, svq1_intra_codebook_4x4, svq1_intra_codebook_8x4, svq1_intra_codebook_8x8, NULL, NULL, }; -static const int8_t svq1_intra_codebook_sum[4][16*6] = { - { - 0, 0, 0, -1, -1, -1, -1, -2, 0, -1, -1, 0, -1, 0, 1, 0, - 1, 0, -1, 1, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, 0, 0, - -1, 0, 0, 1, -1, 1, 0, -1, -1, 0, 1, 1, 0, 0, -1, 1, - 0, 1, 0, 0, 1, -1, 0, 0, 0, -1, 1, 0, 1, 0, -2, 1, - 0, -1, 1, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1, 0, 0, 0, - 0, 1, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 1, 1, -1, - },{ - -1, -2, 0, -1, 1, 0, -1, 0, -1, -4, -1, -2, -1, -2, 1, -2, - 0, 0, 4, -2, -1, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 0, - 1, 1, 0, -1, -1, -1, 1, 0, -1, -3, -3, 1, -1, 1, -2, -1, - 1, -1, 0, 1, 2, 1, -1, -1, 1, 1, 1, 2, 1, 0, 1, -2, - -2, 0, -1, -2, -2, 0, -1, -1, -1, 0, 1, 0, -1, -1, 0, -1, - 0, 2, 1, 2, 2, 1, -1, 1, 0, 2, 0, -1, 1, 0, 0, 0, - },{ - -2, 0, -1, -1, 1, 1, -2, 0, -2, 0, 1, -2, -2, 1, -1, -1, - 3, -2, 0, -3, -4, -3, 2, 1, 0, 3, -2, 2, 3, 2, 2, -1, - -3, 1, 0, 1, 0, 0, 0, 1, -2, 1, -2, -2, -1, -2, -2, 2, - 0, -4, 0, 2, -1, 0, 2, 2, 2, 1, 0, -1, -1, 1, -3, 2, - 2, 1, 0, 3, 1, -1, 1, 3, 1, 0, 1, 1, 2, -1, 1, -1, - -2, -1, 0, -1, 1, -1, 1, -2, -2, -1, -1, -3, 1, -4, -3, 1, - },{ - -2, 0, -2, 3, -1, -1, 0, 2, 2, -1, -3, 2, 1, 0, -2, -1, - -3, -2, -2, 1, 2, -3, 0, 1, -5, -2, -3, 0, -2, -1, 2, 0, - -1, -1, 0, -2, 1, 3, -7, -2, -2, -1, 2, -1, 0, 3, 1, 3, - 1, 0, 0, 1, 2, 3, 1, 2, 0, -2, -2, 1, 1, 2, 2, 3, - 4, 1, -1, 2, -2, 4, 0, 0, 0, 4, 2, 0, -2, -2, 2, -4, - -1, 5, -2, -2, -3, 2, -3, -1, 3, -3, 0, 4, 3, 0, 1, -2, - } -}; +#endif /* FFMPEG_SVQ1_CB_H */ diff --git a/contrib/ffmpeg/libavcodec/svq1_vlc.h b/contrib/ffmpeg/libavcodec/svq1_vlc.h index 56463700f..05fb12aad 100644 --- a/contrib/ffmpeg/libavcodec/svq1_vlc.h +++ b/contrib/ffmpeg/libavcodec/svq1_vlc.h @@ -18,18 +18,20 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef SVQ1_VLC_H -#define SVQ1_VLC_H +#ifndef FFMPEG_SVQ1_VLC_H +#define FFMPEG_SVQ1_VLC_H + +#include <stdint.h> /* values in this table range from 0..3; adjust retrieved value by +0 */ -static const uint8_t svq1_block_type_vlc[4][2] = { +const uint8_t ff_svq1_block_type_vlc[4][2] = { /* { code, length } */ { 0x1, 1 }, { 0x1, 2 }, { 0x1, 3 }, { 0x0, 3 } }; /* values in this table range from -1..6; adjust retrieved value by -1 */ -static const uint8_t svq1_intra_multistage_vlc[6][8][2] = { +const uint8_t ff_svq1_intra_multistage_vlc[6][8][2] = { /* { code, length } */ { { 0x1, 5 }, { 0x1, 1 }, { 0x3, 3 }, { 0x2, 3 }, @@ -53,7 +55,7 @@ static const uint8_t svq1_intra_multistage_vlc[6][8][2] = { }; /* values in this table range from -1..6; adjust retrieved value by -1 */ -static const uint8_t svq1_inter_multistage_vlc[6][8][2] = { +const uint8_t ff_svq1_inter_multistage_vlc[6][8][2] = { /* { code, length } */ { { 0x3, 2 }, { 0x5, 3 }, { 0x4, 3 }, { 0x3, 3 }, @@ -77,7 +79,7 @@ static const uint8_t svq1_inter_multistage_vlc[6][8][2] = { }; /* values in this table range from 0..255; adjust retrieved value by +0 */ -static const uint16_t svq1_intra_mean_vlc[256][2] = { +const uint16_t ff_svq1_intra_mean_vlc[256][2] = { /* { code, length } */ { 0x37, 6 }, { 0x56, 7 }, { 0x1, 17 }, { 0x1, 20 }, { 0x2, 20 }, { 0x3, 20 }, { 0x0, 20 }, { 0x4, 20 }, @@ -146,7 +148,7 @@ static const uint16_t svq1_intra_mean_vlc[256][2] = { }; /* values in this table range from -256..255; adjust retrieved value by -256 */ -static const uint16_t svq1_inter_mean_vlc[512][2] = { +const uint16_t ff_svq1_inter_mean_vlc[512][2] = { /* { code, length } */ { 0x5A, 22 }, { 0xD4, 22 }, { 0xD5, 22 }, { 0xD6, 22 }, { 0xD7, 22 }, { 0xD8, 22 }, { 0xD9, 22 }, { 0xDA, 22 }, @@ -278,4 +280,4 @@ static const uint16_t svq1_inter_mean_vlc[512][2] = { { 0x3, 22 }, { 0x2, 22 }, { 0x1, 22 }, { 0x0, 22 } }; -#endif +#endif /* FFMPEG_SVQ1_VLC_H */ diff --git a/contrib/ffmpeg/libavcodec/svq1dec.c b/contrib/ffmpeg/libavcodec/svq1dec.c new file mode 100644 index 000000000..099c185db --- /dev/null +++ b/contrib/ffmpeg/libavcodec/svq1dec.c @@ -0,0 +1,829 @@ +/* + * SVQ1 decoder + * ported to MPlayer by Arpi <arpi@thot.banki.hu> + * ported to libavcodec by Nick Kurshev <nickols_k@mail.ru> + * + * Copyright (C) 2002 the xine project + * Copyright (C) 2002 the ffmpeg project + * + * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net> + * + * 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 svq1.c + * Sorenson Vector Quantizer #1 (SVQ1) video codec. + * For more information of the SVQ1 algorithm, visit: + * http://www.pcisys.net/~melanson/codecs/ + */ + + +//#define DEBUG_SVQ1 +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + +#include "svq1.h" + +#undef NDEBUG +#include <assert.h> + +extern const uint8_t mvtab[33][2]; + +static VLC svq1_block_type; +static VLC svq1_motion_component; +static VLC svq1_intra_multistage[6]; +static VLC svq1_inter_multistage[6]; +static VLC svq1_intra_mean; +static VLC svq1_inter_mean; + +/* motion vector (prediction) */ +typedef struct svq1_pmv_s { + int x; + int y; +} svq1_pmv_t; + +static const uint16_t checksum_table[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; + +static const uint8_t string_table[256] = { + 0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54, + 0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D, + 0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06, + 0x7B, 0xAE, 0x04, 0xD1, 0x85, 0x50, 0xFA, 0x2F, + 0xA4, 0x71, 0xDB, 0x0E, 0x5A, 0x8F, 0x25, 0xF0, + 0x8D, 0x58, 0xF2, 0x27, 0x73, 0xA6, 0x0C, 0xD9, + 0xF6, 0x23, 0x89, 0x5C, 0x08, 0xDD, 0x77, 0xA2, + 0xDF, 0x0A, 0xA0, 0x75, 0x21, 0xF4, 0x5E, 0x8B, + 0x9D, 0x48, 0xE2, 0x37, 0x63, 0xB6, 0x1C, 0xC9, + 0xB4, 0x61, 0xCB, 0x1E, 0x4A, 0x9F, 0x35, 0xE0, + 0xCF, 0x1A, 0xB0, 0x65, 0x31, 0xE4, 0x4E, 0x9B, + 0xE6, 0x33, 0x99, 0x4C, 0x18, 0xCD, 0x67, 0xB2, + 0x39, 0xEC, 0x46, 0x93, 0xC7, 0x12, 0xB8, 0x6D, + 0x10, 0xC5, 0x6F, 0xBA, 0xEE, 0x3B, 0x91, 0x44, + 0x6B, 0xBE, 0x14, 0xC1, 0x95, 0x40, 0xEA, 0x3F, + 0x42, 0x97, 0x3D, 0xE8, 0xBC, 0x69, 0xC3, 0x16, + 0xEF, 0x3A, 0x90, 0x45, 0x11, 0xC4, 0x6E, 0xBB, + 0xC6, 0x13, 0xB9, 0x6C, 0x38, 0xED, 0x47, 0x92, + 0xBD, 0x68, 0xC2, 0x17, 0x43, 0x96, 0x3C, 0xE9, + 0x94, 0x41, 0xEB, 0x3E, 0x6A, 0xBF, 0x15, 0xC0, + 0x4B, 0x9E, 0x34, 0xE1, 0xB5, 0x60, 0xCA, 0x1F, + 0x62, 0xB7, 0x1D, 0xC8, 0x9C, 0x49, 0xE3, 0x36, + 0x19, 0xCC, 0x66, 0xB3, 0xE7, 0x32, 0x98, 0x4D, + 0x30, 0xE5, 0x4F, 0x9A, 0xCE, 0x1B, 0xB1, 0x64, + 0x72, 0xA7, 0x0D, 0xD8, 0x8C, 0x59, 0xF3, 0x26, + 0x5B, 0x8E, 0x24, 0xF1, 0xA5, 0x70, 0xDA, 0x0F, + 0x20, 0xF5, 0x5F, 0x8A, 0xDE, 0x0B, 0xA1, 0x74, + 0x09, 0xDC, 0x76, 0xA3, 0xF7, 0x22, 0x88, 0x5D, + 0xD6, 0x03, 0xA9, 0x7C, 0x28, 0xFD, 0x57, 0x82, + 0xFF, 0x2A, 0x80, 0x55, 0x01, 0xD4, 0x7E, 0xAB, + 0x84, 0x51, 0xFB, 0x2E, 0x7A, 0xAF, 0x05, 0xD0, + 0xAD, 0x78, 0xD2, 0x07, 0x53, 0x86, 0x2C, 0xF9 +}; + +#define SVQ1_PROCESS_VECTOR()\ + for (; level > 0; i++) {\ + /* process next depth */\ + if (i == m) {\ + m = n;\ + if (--level == 0)\ + break;\ + }\ + /* divide block if next bit set */\ + if (get_bits1 (bitbuf) == 0)\ + break;\ + /* add child nodes */\ + list[n++] = list[i];\ + list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level / 2) + 1));\ + } + +#define SVQ1_ADD_CODEBOOK()\ + /* add codebook entries to vector */\ + for (j=0; j < stages; j++) {\ + n3 = codebook[entries[j]] ^ 0x80808080;\ + n1 += ((n3 & 0xFF00FF00) >> 8);\ + n2 += (n3 & 0x00FF00FF);\ + }\ +\ + /* clip to [0..255] */\ + if (n1 & 0xFF00FF00) {\ + n3 = ((( n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ + n1 += 0x7F007F00;\ + n1 |= (((~n1 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ + n1 &= (n3 & 0x00FF00FF);\ + }\ +\ + if (n2 & 0xFF00FF00) {\ + n3 = ((( n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ + n2 += 0x7F007F00;\ + n2 |= (((~n2 >> 15) & 0x00010001) | 0x01000100) - 0x00010001;\ + n2 &= (n3 & 0x00FF00FF);\ + } + +#define SVQ1_DO_CODEBOOK_INTRA()\ + for (y=0; y < height; y++) {\ + for (x=0; x < (width / 4); x++, codebook++) {\ + n1 = n4;\ + n2 = n4;\ + SVQ1_ADD_CODEBOOK()\ + /* store result */\ + dst[x] = (n1 << 8) | n2;\ + }\ + dst += (pitch / 4);\ + } + +#define SVQ1_DO_CODEBOOK_NONINTRA()\ + for (y=0; y < height; y++) {\ + for (x=0; x < (width / 4); x++, codebook++) {\ + n3 = dst[x];\ + /* add mean value to vector */\ + n1 = ((n3 & 0xFF00FF00) >> 8) + n4;\ + n2 = (n3 & 0x00FF00FF) + n4;\ + SVQ1_ADD_CODEBOOK()\ + /* store result */\ + dst[x] = (n1 << 8) | n2;\ + }\ + dst += (pitch / 4);\ + } + +#define SVQ1_CALC_CODEBOOK_ENTRIES(cbook)\ + codebook = (const uint32_t *) cbook[level];\ + bit_cache = get_bits (bitbuf, 4*stages);\ + /* calculate codebook entries for this vector */\ + for (j=0; j < stages; j++) {\ + entries[j] = (((bit_cache >> (4*(stages - j - 1))) & 0xF) + 16*j) << (level + 1);\ + }\ + mean -= (stages * 128);\ + n4 = ((mean + (mean >> 31)) << 16) | (mean & 0xFFFF); + +static int svq1_decode_block_intra (GetBitContext *bitbuf, uint8_t *pixels, int pitch ) { + uint32_t bit_cache; + uint8_t *list[63]; + uint32_t *dst; + const uint32_t *codebook; + int entries[6]; + int i, j, m, n; + int mean, stages; + unsigned x, y, width, height, level; + uint32_t n1, n2, n3, n4; + + /* initialize list for breadth first processing of vectors */ + list[0] = pixels; + + /* recursively process vector */ + for (i=0, m=1, n=1, level=5; i < n; i++) { + SVQ1_PROCESS_VECTOR(); + + /* destination address and vector size */ + dst = (uint32_t *) list[i]; + width = 1 << ((4 + level) /2); + height = 1 << ((3 + level) /2); + + /* get number of stages (-1 skips vector, 0 for mean only) */ + stages = get_vlc2(bitbuf, svq1_intra_multistage[level].table, 3, 3) - 1; + + if (stages == -1) { + for (y=0; y < height; y++) { + memset (&dst[y*(pitch / 4)], 0, width); + } + continue; /* skip vector */ + } + + if ((stages > 0) && (level >= 4)) { +#ifdef DEBUG_SVQ1 + av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n",stages,level); +#endif + return -1; /* invalid vector */ + } + + mean = get_vlc2(bitbuf, svq1_intra_mean.table, 8, 3); + + if (stages == 0) { + for (y=0; y < height; y++) { + memset (&dst[y*(pitch / 4)], mean, width); + } + } else { + SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_intra_codebooks); + SVQ1_DO_CODEBOOK_INTRA() + } + } + + return 0; +} + +static int svq1_decode_block_non_intra (GetBitContext *bitbuf, uint8_t *pixels, int pitch ) { + uint32_t bit_cache; + uint8_t *list[63]; + uint32_t *dst; + const uint32_t *codebook; + int entries[6]; + int i, j, m, n; + int mean, stages; + int x, y, width, height, level; + uint32_t n1, n2, n3, n4; + + /* initialize list for breadth first processing of vectors */ + list[0] = pixels; + + /* recursively process vector */ + for (i=0, m=1, n=1, level=5; i < n; i++) { + SVQ1_PROCESS_VECTOR(); + + /* destination address and vector size */ + dst = (uint32_t *) list[i]; + width = 1 << ((4 + level) /2); + height = 1 << ((3 + level) /2); + + /* get number of stages (-1 skips vector, 0 for mean only) */ + stages = get_vlc2(bitbuf, svq1_inter_multistage[level].table, 3, 2) - 1; + + if (stages == -1) continue; /* skip vector */ + + if ((stages > 0) && (level >= 4)) { +#ifdef DEBUG_SVQ1 + av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n",stages,level); +#endif + return -1; /* invalid vector */ + } + + mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256; + + SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_inter_codebooks); + SVQ1_DO_CODEBOOK_NONINTRA() + } + return 0; +} + +static int svq1_decode_motion_vector (GetBitContext *bitbuf, svq1_pmv_t *mv, svq1_pmv_t **pmv) { + int diff; + int i; + + for (i=0; i < 2; i++) { + + /* get motion code */ + diff = get_vlc2(bitbuf, svq1_motion_component.table, 7, 2); + if(diff<0) + return -1; + else if(diff){ + if(get_bits1(bitbuf)) diff= -diff; + } + + /* add median of motion vector predictors and clip result */ + if (i == 1) + mv->y = ((diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26; + else + mv->x = ((diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26; + } + + return 0; +} + +static void svq1_skip_block (uint8_t *current, uint8_t *previous, int pitch, int x, int y) { + uint8_t *src; + uint8_t *dst; + int i; + + src = &previous[x + y*pitch]; + dst = current; + + for (i=0; i < 16; i++) { + memcpy (dst, src, 16); + src += pitch; + dst += pitch; + } +} + +static int svq1_motion_inter_block (MpegEncContext *s, GetBitContext *bitbuf, + uint8_t *current, uint8_t *previous, int pitch, + svq1_pmv_t *motion, int x, int y) { + uint8_t *src; + uint8_t *dst; + svq1_pmv_t mv; + svq1_pmv_t *pmv[3]; + int result; + + /* predict and decode motion vector */ + pmv[0] = &motion[0]; + if (y == 0) { + pmv[1] = + pmv[2] = pmv[0]; + } + else { + pmv[1] = &motion[(x / 8) + 2]; + pmv[2] = &motion[(x / 8) + 4]; + } + + result = svq1_decode_motion_vector (bitbuf, &mv, pmv); + + if (result != 0) + return result; + + motion[0].x = + motion[(x / 8) + 2].x = + motion[(x / 8) + 3].x = mv.x; + motion[0].y = + motion[(x / 8) + 2].y = + motion[(x / 8) + 3].y = mv.y; + + if(y + (mv.y >> 1)<0) + mv.y= 0; + if(x + (mv.x >> 1)<0) + mv.x= 0; + +#if 0 + int w= (s->width+15)&~15; + int h= (s->height+15)&~15; + if(x + (mv.x >> 1)<0 || y + (mv.y >> 1)<0 || x + (mv.x >> 1) + 16 > w || y + (mv.y >> 1) + 16> h) + av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mv.x >> 1), y + (mv.y >> 1)); +#endif + + src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1))*pitch]; + dst = current; + + s->dsp.put_pixels_tab[0][((mv.y & 1) << 1) | (mv.x & 1)](dst,src,pitch,16); + + return 0; +} + +static int svq1_motion_inter_4v_block (MpegEncContext *s, GetBitContext *bitbuf, + uint8_t *current, uint8_t *previous, int pitch, + svq1_pmv_t *motion,int x, int y) { + uint8_t *src; + uint8_t *dst; + svq1_pmv_t mv; + svq1_pmv_t *pmv[4]; + int i, result; + + /* predict and decode motion vector (0) */ + pmv[0] = &motion[0]; + if (y == 0) { + pmv[1] = + pmv[2] = pmv[0]; + } + else { + pmv[1] = &motion[(x / 8) + 2]; + pmv[2] = &motion[(x / 8) + 4]; + } + + result = svq1_decode_motion_vector (bitbuf, &mv, pmv); + + if (result != 0) + return result; + + /* predict and decode motion vector (1) */ + pmv[0] = &mv; + if (y == 0) { + pmv[1] = + pmv[2] = pmv[0]; + } + else { + pmv[1] = &motion[(x / 8) + 3]; + } + result = svq1_decode_motion_vector (bitbuf, &motion[0], pmv); + + if (result != 0) + return result; + + /* predict and decode motion vector (2) */ + pmv[1] = &motion[0]; + pmv[2] = &motion[(x / 8) + 1]; + + result = svq1_decode_motion_vector (bitbuf, &motion[(x / 8) + 2], pmv); + + if (result != 0) + return result; + + /* predict and decode motion vector (3) */ + pmv[2] = &motion[(x / 8) + 2]; + pmv[3] = &motion[(x / 8) + 3]; + + result = svq1_decode_motion_vector (bitbuf, pmv[3], pmv); + + if (result != 0) + return result; + + /* form predictions */ + for (i=0; i < 4; i++) { + int mvx= pmv[i]->x + (i&1)*16; + int mvy= pmv[i]->y + (i>>1)*16; + + ///XXX /FIXME clipping or padding? + if(y + (mvy >> 1)<0) + mvy= 0; + if(x + (mvx >> 1)<0) + mvx= 0; + +#if 0 + int w= (s->width+15)&~15; + int h= (s->height+15)&~15; + if(x + (mvx >> 1)<0 || y + (mvy >> 1)<0 || x + (mvx >> 1) + 8 > w || y + (mvy >> 1) + 8> h) + av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mvx >> 1), y + (mvy >> 1)); +#endif + src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1))*pitch]; + dst = current; + + s->dsp.put_pixels_tab[1][((mvy & 1) << 1) | (mvx & 1)](dst,src,pitch,8); + + /* select next block */ + if (i & 1) { + current += 8*(pitch - 1); + } else { + current += 8; + } + } + + return 0; +} + +static int svq1_decode_delta_block (MpegEncContext *s, GetBitContext *bitbuf, + uint8_t *current, uint8_t *previous, int pitch, + svq1_pmv_t *motion, int x, int y) { + uint32_t block_type; + int result = 0; + + /* get block type */ + block_type = get_vlc2(bitbuf, svq1_block_type.table, 2, 2); + + /* reset motion vectors */ + if (block_type == SVQ1_BLOCK_SKIP || block_type == SVQ1_BLOCK_INTRA) { + motion[0].x = + motion[0].y = + motion[(x / 8) + 2].x = + motion[(x / 8) + 2].y = + motion[(x / 8) + 3].x = + motion[(x / 8) + 3].y = 0; + } + + switch (block_type) { + case SVQ1_BLOCK_SKIP: + svq1_skip_block (current, previous, pitch, x, y); + break; + + case SVQ1_BLOCK_INTER: + result = svq1_motion_inter_block (s, bitbuf, current, previous, pitch, motion, x, y); + + if (result != 0) + { +#ifdef DEBUG_SVQ1 + av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_block %i\n",result); +#endif + break; + } + result = svq1_decode_block_non_intra (bitbuf, current, pitch); + break; + + case SVQ1_BLOCK_INTER_4V: + result = svq1_motion_inter_4v_block (s, bitbuf, current, previous, pitch, motion, x, y); + + if (result != 0) + { +#ifdef DEBUG_SVQ1 + av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_4v_block %i\n",result); +#endif + break; + } + result = svq1_decode_block_non_intra (bitbuf, current, pitch); + break; + + case SVQ1_BLOCK_INTRA: + result = svq1_decode_block_intra (bitbuf, current, pitch); + break; + } + + return result; +} + +static uint16_t svq1_packet_checksum (const uint8_t *data, const int length, int value) { + int i; + + for (i=0; i < length; i++) { + value = checksum_table[data[i] ^ (value >> 8)] ^ ((value & 0xFF) << 8); + } + + return value; +} + +static void svq1_parse_string (GetBitContext *bitbuf, uint8_t *out) { + uint8_t seed; + int i; + + out[0] = get_bits (bitbuf, 8); + + seed = string_table[out[0]]; + + for (i=1; i <= out[0]; i++) { + out[i] = get_bits (bitbuf, 8) ^ seed; + seed = string_table[out[i] ^ seed]; + } +} + +static int svq1_decode_frame_header (GetBitContext *bitbuf,MpegEncContext *s) { + int frame_size_code; + int temporal_reference; + + temporal_reference = get_bits (bitbuf, 8); + + /* frame type */ + s->pict_type= get_bits (bitbuf, 2)+1; + if(s->pict_type==4) + return -1; + + if (s->pict_type == I_TYPE) { + + /* unknown fields */ + if (s->f_code == 0x50 || s->f_code == 0x60) { + int csum = get_bits (bitbuf, 16); + + csum = svq1_packet_checksum (bitbuf->buffer, bitbuf->size_in_bits>>3, csum); + +// av_log(s->avctx, AV_LOG_INFO, "%s checksum (%02x) for packet data\n", +// (csum == 0) ? "correct" : "incorrect", csum); + } + + if ((s->f_code ^ 0x10) >= 0x50) { + uint8_t msg[256]; + + svq1_parse_string (bitbuf, msg); + + av_log(s->avctx, AV_LOG_INFO, "embedded message: \"%s\"\n", (char *) msg); + } + + skip_bits (bitbuf, 2); + skip_bits (bitbuf, 2); + skip_bits1 (bitbuf); + + /* load frame size */ + frame_size_code = get_bits (bitbuf, 3); + + if (frame_size_code == 7) { + /* load width, height (12 bits each) */ + s->width = get_bits (bitbuf, 12); + s->height = get_bits (bitbuf, 12); + + if (!s->width || !s->height) + return -1; + } else { + /* get width, height from table */ + s->width = ff_svq1_frame_size_table[frame_size_code].width; + s->height = ff_svq1_frame_size_table[frame_size_code].height; + } + } + + /* unknown fields */ + if (get_bits1 (bitbuf) == 1) { + skip_bits1 (bitbuf); /* use packet checksum if (1) */ + skip_bits1 (bitbuf); /* component checksums after image data if (1) */ + + if (get_bits (bitbuf, 2) != 0) + return -1; + } + + if (get_bits1 (bitbuf) == 1) { + skip_bits1 (bitbuf); + skip_bits (bitbuf, 4); + skip_bits1 (bitbuf); + skip_bits (bitbuf, 2); + + while (get_bits1 (bitbuf) == 1) { + skip_bits (bitbuf, 8); + } + } + + return 0; +} + +static int svq1_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + MpegEncContext *s=avctx->priv_data; + uint8_t *current, *previous; + int result, i, x, y, width, height; + AVFrame *pict = data; + + /* initialize bit buffer */ + init_get_bits(&s->gb,buf,buf_size*8); + + /* decode frame header */ + s->f_code = get_bits (&s->gb, 22); + + if ((s->f_code & ~0x70) || !(s->f_code & 0x60)) + return -1; + + /* swap some header bytes (why?) */ + if (s->f_code != 0x20) { + uint32_t *src = (uint32_t *) (buf + 4); + + for (i=0; i < 4; i++) { + src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; + } + } + + result = svq1_decode_frame_header (&s->gb, s); + + if (result != 0) + { +#ifdef DEBUG_SVQ1 + av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_frame_header %i\n",result); +#endif + return result; + } + + //FIXME this avoids some confusion for "B frames" without 2 references + //this should be removed after libavcodec can handle more flexible picture types & ordering + if(s->pict_type==B_TYPE && s->last_picture_ptr==NULL) return buf_size; + + if(avctx->hurry_up && s->pict_type==B_TYPE) return buf_size; + if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) + ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) + || avctx->skip_frame >= AVDISCARD_ALL) + return buf_size; + + if(MPV_frame_start(s, avctx) < 0) + return -1; + + /* decode y, u and v components */ + for (i=0; i < 3; i++) { + int linesize; + if (i == 0) { + width = (s->width+15)&~15; + height = (s->height+15)&~15; + linesize= s->linesize; + } else { + if(s->flags&CODEC_FLAG_GRAY) break; + width = (s->width/4+15)&~15; + height = (s->height/4+15)&~15; + linesize= s->uvlinesize; + } + + current = s->current_picture.data[i]; + + if(s->pict_type==B_TYPE){ + previous = s->next_picture.data[i]; + }else{ + previous = s->last_picture.data[i]; + } + + if (s->pict_type == I_TYPE) { + /* keyframe */ + for (y=0; y < height; y+=16) { + for (x=0; x < width; x+=16) { + result = svq1_decode_block_intra (&s->gb, ¤t[x], linesize); + if (result != 0) + { +//#ifdef DEBUG_SVQ1 + av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_block %i (keyframe)\n",result); +//#endif + return result; + } + } + current += 16*linesize; + } + } else { + svq1_pmv_t pmv[width/8+3]; + /* delta frame */ + memset (pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv_t)); + + for (y=0; y < height; y+=16) { + for (x=0; x < width; x+=16) { + result = svq1_decode_delta_block (s, &s->gb, ¤t[x], previous, + linesize, pmv, x, y); + if (result != 0) + { +#ifdef DEBUG_SVQ1 + av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_delta_block %i\n",result); +#endif + return result; + } + } + + pmv[0].x = + pmv[0].y = 0; + + current += 16*linesize; + } + } + } + + *pict = *(AVFrame*)&s->current_picture; + + + MPV_frame_end(s); + + *data_size=sizeof(AVFrame); + return buf_size; +} + +static int svq1_decode_init(AVCodecContext *avctx) +{ + MpegEncContext *s = avctx->priv_data; + int i; + + MPV_decode_defaults(s); + + s->avctx = avctx; + s->width = (avctx->width+3)&~3; + s->height = (avctx->height+3)&~3; + s->codec_id= avctx->codec->id; + avctx->pix_fmt = PIX_FMT_YUV410P; + avctx->has_b_frames= 1; // not true, but DP frames and these behave like unidirectional b frames + s->flags= avctx->flags; + if (MPV_common_init(s) < 0) return -1; + + init_vlc(&svq1_block_type, 2, 4, + &ff_svq1_block_type_vlc[0][1], 2, 1, + &ff_svq1_block_type_vlc[0][0], 2, 1, 1); + + init_vlc(&svq1_motion_component, 7, 33, + &mvtab[0][1], 2, 1, + &mvtab[0][0], 2, 1, 1); + + for (i = 0; i < 6; i++) { + init_vlc(&svq1_intra_multistage[i], 3, 8, + &ff_svq1_intra_multistage_vlc[i][0][1], 2, 1, + &ff_svq1_intra_multistage_vlc[i][0][0], 2, 1, 1); + init_vlc(&svq1_inter_multistage[i], 3, 8, + &ff_svq1_inter_multistage_vlc[i][0][1], 2, 1, + &ff_svq1_inter_multistage_vlc[i][0][0], 2, 1, 1); + } + + init_vlc(&svq1_intra_mean, 8, 256, + &ff_svq1_intra_mean_vlc[0][1], 4, 2, + &ff_svq1_intra_mean_vlc[0][0], 4, 2, 1); + + init_vlc(&svq1_inter_mean, 9, 512, + &ff_svq1_inter_mean_vlc[0][1], 4, 2, + &ff_svq1_inter_mean_vlc[0][0], 4, 2, 1); + + return 0; +} + +static int svq1_decode_end(AVCodecContext *avctx) +{ + MpegEncContext *s = avctx->priv_data; + + MPV_common_end(s); + return 0; +} + + +AVCodec svq1_decoder = { + "svq1", + CODEC_TYPE_VIDEO, + CODEC_ID_SVQ1, + sizeof(MpegEncContext), + svq1_decode_init, + NULL, + svq1_decode_end, + svq1_decode_frame, + CODEC_CAP_DR1, + .flush= ff_mpeg_flush, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV410P, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/svq1enc.c b/contrib/ffmpeg/libavcodec/svq1enc.c new file mode 100644 index 000000000..5345ed6dc --- /dev/null +++ b/contrib/ffmpeg/libavcodec/svq1enc.c @@ -0,0 +1,588 @@ +/* + * SVQ1 Encoder + * Copyright (C) 2004 Mike Melanson <melanson@pcisys.net> + * + * 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 svq1enc.c + * Sorenson Vector Quantizer #1 (SVQ1) video codec. + * For more information of the SVQ1 algorithm, visit: + * http://www.pcisys.net/~melanson/codecs/ + */ + + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + +#include "svq1.h" +#include "svq1enc_cb.h" + +#undef NDEBUG +#include <assert.h> + + +typedef struct SVQ1Context { + MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independent of MpegEncContext, so this will be removed then (FIXME/XXX) + AVCodecContext *avctx; + DSPContext dsp; + AVFrame picture; + AVFrame current_picture; + AVFrame last_picture; + PutBitContext pb; + GetBitContext gb; + + PutBitContext reorder_pb[6]; //why ooh why this sick breadth first order, everything is slower and more complex + + int frame_width; + int frame_height; + + /* Y plane block dimensions */ + int y_block_width; + int y_block_height; + + /* U & V plane (C planes) block dimensions */ + int c_block_width; + int c_block_height; + + uint16_t *mb_type; + uint32_t *dummy; + int16_t (*motion_val8[3])[2]; + int16_t (*motion_val16[3])[2]; + + int64_t rd_total; +} SVQ1Context; + +static void svq1_write_header(SVQ1Context *s, int frame_type) +{ + int i; + + /* frame code */ + put_bits(&s->pb, 22, 0x20); + + /* temporal reference (sure hope this is a "don't care") */ + put_bits(&s->pb, 8, 0x00); + + /* frame type */ + put_bits(&s->pb, 2, frame_type - 1); + + if (frame_type == I_TYPE) { + + /* no checksum since frame code is 0x20 */ + + /* no embedded string either */ + + /* output 5 unknown bits (2 + 2 + 1) */ + put_bits(&s->pb, 5, 2); /* 2 needed by quicktime decoder */ + + for (i = 0; i < 7; i++) + { + if ((ff_svq1_frame_size_table[i].width == s->frame_width) && + (ff_svq1_frame_size_table[i].height == s->frame_height)) + { + put_bits(&s->pb, 3, i); + break; + } + } + + if (i == 7) + { + put_bits(&s->pb, 3, 7); + put_bits(&s->pb, 12, s->frame_width); + put_bits(&s->pb, 12, s->frame_height); + } + } + + /* no checksum or extra data (next 2 bits get 0) */ + put_bits(&s->pb, 2, 0); +} + + +#define QUALITY_THRESHOLD 100 +#define THRESHOLD_MULTIPLIER 0.6 + +#if defined(HAVE_ALTIVEC) +#undef vector +#endif + +static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){ + int count, y, x, i, j, split, best_mean, best_score, best_count; + int best_vector[6]; + int block_sum[7]= {0, 0, 0, 0, 0, 0}; + int w= 2<<((level+2)>>1); + int h= 2<<((level+1)>>1); + int size=w*h; + int16_t block[7][256]; + const int8_t *codebook_sum, *codebook; + const uint16_t (*mean_vlc)[2]; + const uint8_t (*multistage_vlc)[2]; + + best_score=0; + //FIXME optimize, this doenst need to be done multiple times + if(intra){ + codebook_sum= svq1_intra_codebook_sum[level]; + codebook= ff_svq1_intra_codebooks[level]; + mean_vlc= ff_svq1_intra_mean_vlc; + multistage_vlc= ff_svq1_intra_multistage_vlc[level]; + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + int v= src[x + y*stride]; + block[0][x + w*y]= v; + best_score += v*v; + block_sum[0] += v; + } + } + }else{ + codebook_sum= svq1_inter_codebook_sum[level]; + codebook= ff_svq1_inter_codebooks[level]; + mean_vlc= ff_svq1_inter_mean_vlc + 256; + multistage_vlc= ff_svq1_inter_multistage_vlc[level]; + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + int v= src[x + y*stride] - ref[x + y*stride]; + block[0][x + w*y]= v; + best_score += v*v; + block_sum[0] += v; + } + } + } + + best_count=0; + best_score -= ((block_sum[0]*block_sum[0])>>(level+3)); + best_mean= (block_sum[0] + (size>>1)) >> (level+3); + + if(level<4){ + for(count=1; count<7; count++){ + int best_vector_score= INT_MAX; + int best_vector_sum=-999, best_vector_mean=-999; + const int stage= count-1; + const int8_t *vector; + + for(i=0; i<16; i++){ + int sum= codebook_sum[stage*16 + i]; + int sqr, diff, score; + + vector = codebook + stage*size*16 + i*size; + sqr = s->dsp.ssd_int8_vs_int16(vector, block[stage], size); + diff= block_sum[stage] - sum; + score= sqr - ((diff*(int64_t)diff)>>(level+3)); //FIXME 64bit slooow + if(score < best_vector_score){ + int mean= (diff + (size>>1)) >> (level+3); + assert(mean >-300 && mean<300); + mean= av_clip(mean, intra?0:-256, 255); + best_vector_score= score; + best_vector[stage]= i; + best_vector_sum= sum; + best_vector_mean= mean; + } + } + assert(best_vector_mean != -999); + vector= codebook + stage*size*16 + best_vector[stage]*size; + for(j=0; j<size; j++){ + block[stage+1][j] = block[stage][j] - vector[j]; + } + block_sum[stage+1]= block_sum[stage] - best_vector_sum; + best_vector_score += + lambda*(+ 1 + 4*count + + multistage_vlc[1+count][1] + + mean_vlc[best_vector_mean][1]); + + if(best_vector_score < best_score){ + best_score= best_vector_score; + best_count= count; + best_mean= best_vector_mean; + } + } + } + + split=0; + if(best_score > threshold && level){ + int score=0; + int offset= (level&1) ? stride*h/2 : w/2; + PutBitContext backup[6]; + + for(i=level-1; i>=0; i--){ + backup[i]= s->reorder_pb[i]; + } + score += encode_block(s, src , ref , decoded , stride, level-1, threshold>>1, lambda, intra); + score += encode_block(s, src + offset, ref + offset, decoded + offset, stride, level-1, threshold>>1, lambda, intra); + score += lambda; + + if(score < best_score){ + best_score= score; + split=1; + }else{ + for(i=level-1; i>=0; i--){ + s->reorder_pb[i]= backup[i]; + } + } + } + if (level > 0) + put_bits(&s->reorder_pb[level], 1, split); + + if(!split){ + assert((best_mean >= 0 && best_mean<256) || !intra); + assert(best_mean >= -256 && best_mean<256); + assert(best_count >=0 && best_count<7); + assert(level<4 || best_count==0); + + /* output the encoding */ + put_bits(&s->reorder_pb[level], + multistage_vlc[1 + best_count][1], + multistage_vlc[1 + best_count][0]); + put_bits(&s->reorder_pb[level], mean_vlc[best_mean][1], + mean_vlc[best_mean][0]); + + for (i = 0; i < best_count; i++){ + assert(best_vector[i]>=0 && best_vector[i]<16); + put_bits(&s->reorder_pb[level], 4, best_vector[i]); + } + + for(y=0; y<h; y++){ + for(x=0; x<w; x++){ + decoded[x + y*stride]= src[x + y*stride] - block[best_count][x + w*y] + best_mean; + } + } + } + + return best_score; +} + + +static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane, + int width, int height, int src_stride, int stride) +{ + int x, y; + int i; + int block_width, block_height; + int level; + int threshold[6]; + const int lambda= (s->picture.quality*s->picture.quality) >> (2*FF_LAMBDA_SHIFT); + + /* figure out the acceptable level thresholds in advance */ + threshold[5] = QUALITY_THRESHOLD; + for (level = 4; level >= 0; level--) + threshold[level] = threshold[level + 1] * THRESHOLD_MULTIPLIER; + + block_width = (width + 15) / 16; + block_height = (height + 15) / 16; + + if(s->picture.pict_type == P_TYPE){ + s->m.avctx= s->avctx; + s->m.current_picture_ptr= &s->m.current_picture; + s->m.last_picture_ptr = &s->m.last_picture; + s->m.last_picture.data[0]= ref_plane; + s->m.linesize= + s->m.last_picture.linesize[0]= + s->m.new_picture.linesize[0]= + s->m.current_picture.linesize[0]= stride; + s->m.width= width; + s->m.height= height; + s->m.mb_width= block_width; + s->m.mb_height= block_height; + s->m.mb_stride= s->m.mb_width+1; + s->m.b8_stride= 2*s->m.mb_width+1; + s->m.f_code=1; + s->m.pict_type= s->picture.pict_type; + s->m.me_method= s->avctx->me_method; + s->m.me.scene_change_score=0; + s->m.flags= s->avctx->flags; +// s->m.out_format = FMT_H263; +// s->m.unrestricted_mv= 1; + + s->m.lambda= s->picture.quality; + s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7); + s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT; + + if(!s->motion_val8[plane]){ + s->motion_val8 [plane]= av_mallocz((s->m.b8_stride*block_height*2 + 2)*2*sizeof(int16_t)); + s->motion_val16[plane]= av_mallocz((s->m.mb_stride*(block_height + 2) + 1)*2*sizeof(int16_t)); + } + + s->m.mb_type= s->mb_type; + + //dummies, to avoid segfaults + s->m.current_picture.mb_mean= (uint8_t *)s->dummy; + s->m.current_picture.mb_var= (uint16_t*)s->dummy; + s->m.current_picture.mc_mb_var= (uint16_t*)s->dummy; + s->m.current_picture.mb_type= s->dummy; + + s->m.current_picture.motion_val[0]= s->motion_val8[plane] + 2; + s->m.p_mv_table= s->motion_val16[plane] + s->m.mb_stride + 1; + s->m.dsp= s->dsp; //move + ff_init_me(&s->m); + + s->m.me.dia_size= s->avctx->dia_size; + s->m.first_slice_line=1; + for (y = 0; y < block_height; y++) { + uint8_t src[stride*16]; + + s->m.new_picture.data[0]= src - y*16*stride; //ugly + s->m.mb_y= y; + + for(i=0; i<16 && i + 16*y<height; i++){ + memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width); + for(x=width; x<16*block_width; x++) + src[i*stride+x]= src[i*stride+x-1]; + } + for(; i<16 && i + 16*y<16*block_height; i++) + memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width); + + for (x = 0; x < block_width; x++) { + s->m.mb_x= x; + ff_init_block_index(&s->m); + ff_update_block_index(&s->m); + + ff_estimate_p_frame_motion(&s->m, x, y); + } + s->m.first_slice_line=0; + } + + ff_fix_long_p_mvs(&s->m); + ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s->m.f_code, CANDIDATE_MB_TYPE_INTER, 0); + } + + s->m.first_slice_line=1; + for (y = 0; y < block_height; y++) { + uint8_t src[stride*16]; + + for(i=0; i<16 && i + 16*y<height; i++){ + memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width); + for(x=width; x<16*block_width; x++) + src[i*stride+x]= src[i*stride+x-1]; + } + for(; i<16 && i + 16*y<16*block_height; i++) + memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width); + + s->m.mb_y= y; + for (x = 0; x < block_width; x++) { + uint8_t reorder_buffer[3][6][7*32]; + int count[3][6]; + int offset = y * 16 * stride + x * 16; + uint8_t *decoded= decoded_plane + offset; + uint8_t *ref= ref_plane + offset; + int score[4]={0,0,0,0}, best; + uint8_t temp[16*stride]; + + if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3000){ //FIXME check size + av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + + s->m.mb_x= x; + ff_init_block_index(&s->m); + ff_update_block_index(&s->m); + + if(s->picture.pict_type == I_TYPE || (s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTRA)){ + for(i=0; i<6; i++){ + init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32); + } + if(s->picture.pict_type == P_TYPE){ + const uint8_t *vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; + put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); + score[0]= vlc[1]*lambda; + } + score[0]+= encode_block(s, src+16*x, NULL, temp, stride, 5, 64, lambda, 1); + for(i=0; i<6; i++){ + count[0][i]= put_bits_count(&s->reorder_pb[i]); + flush_put_bits(&s->reorder_pb[i]); + } + }else + score[0]= INT_MAX; + + best=0; + + if(s->picture.pict_type == P_TYPE){ + const uint8_t *vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER]; + int mx, my, pred_x, pred_y, dxy; + int16_t *motion_ptr; + + motion_ptr= h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); + if(s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER){ + for(i=0; i<6; i++) + init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32); + + put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); + + s->m.pb= s->reorder_pb[5]; + mx= motion_ptr[0]; + my= motion_ptr[1]; + assert(mx>=-32 && mx<=31); + assert(my>=-32 && my<=31); + assert(pred_x>=-32 && pred_x<=31); + assert(pred_y>=-32 && pred_y<=31); + ff_h263_encode_motion(&s->m, mx - pred_x, 1); + ff_h263_encode_motion(&s->m, my - pred_y, 1); + s->reorder_pb[5]= s->m.pb; + score[1] += lambda*put_bits_count(&s->reorder_pb[5]); + + dxy= (mx&1) + 2*(my&1); + + s->dsp.put_pixels_tab[0][dxy](temp+16, ref + (mx>>1) + stride*(my>>1), stride, 16); + + score[1]+= encode_block(s, src+16*x, temp+16, decoded, stride, 5, 64, lambda, 0); + best= score[1] <= score[0]; + + vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_SKIP]; + score[2]= s->dsp.sse[0](NULL, src+16*x, ref, stride, 16); + score[2]+= vlc[1]*lambda; + if(score[2] < score[best] && mx==0 && my==0){ + best=2; + s->dsp.put_pixels_tab[0][0](decoded, ref, stride, 16); + for(i=0; i<6; i++){ + count[2][i]=0; + } + put_bits(&s->pb, vlc[1], vlc[0]); + } + } + + if(best==1){ + for(i=0; i<6; i++){ + count[1][i]= put_bits_count(&s->reorder_pb[i]); + flush_put_bits(&s->reorder_pb[i]); + } + }else{ + motion_ptr[0 ] = motion_ptr[1 ]= + motion_ptr[2 ] = motion_ptr[3 ]= + motion_ptr[0+2*s->m.b8_stride] = motion_ptr[1+2*s->m.b8_stride]= + motion_ptr[2+2*s->m.b8_stride] = motion_ptr[3+2*s->m.b8_stride]=0; + } + } + + s->rd_total += score[best]; + + for(i=5; i>=0; i--){ + ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]); + } + if(best==0){ + s->dsp.put_pixels_tab[0][0](decoded, temp, stride, 16); + } + } + s->m.first_slice_line=0; + } + return 0; +} + +static int svq1_encode_init(AVCodecContext *avctx) +{ + SVQ1Context * const s = avctx->priv_data; + + dsputil_init(&s->dsp, avctx); + avctx->coded_frame= (AVFrame*)&s->picture; + + s->frame_width = avctx->width; + s->frame_height = avctx->height; + + s->y_block_width = (s->frame_width + 15) / 16; + s->y_block_height = (s->frame_height + 15) / 16; + + s->c_block_width = (s->frame_width / 4 + 15) / 16; + s->c_block_height = (s->frame_height / 4 + 15) / 16; + + s->avctx= avctx; + s->m.avctx= avctx; + s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t)); + s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); + s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); + s->mb_type = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int16_t)); + s->dummy = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int32_t)); + h263_encode_init(&s->m); //mv_penalty + + return 0; +} + +static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf, + int buf_size, void *data) +{ + SVQ1Context * const s = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p= (AVFrame*)&s->picture; + AVFrame temp; + int i; + + if(avctx->pix_fmt != PIX_FMT_YUV410P){ + av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); + return -1; + } + + if(!s->current_picture.data[0]){ + avctx->get_buffer(avctx, &s->current_picture); + avctx->get_buffer(avctx, &s->last_picture); + } + + temp= s->current_picture; + s->current_picture= s->last_picture; + s->last_picture= temp; + + init_put_bits(&s->pb, buf, buf_size); + + *p = *pict; + p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ? P_TYPE : I_TYPE; + p->key_frame = p->pict_type == I_TYPE; + + svq1_write_header(s, p->pict_type); + for(i=0; i<3; i++){ + if(svq1_encode_plane(s, i, + s->picture.data[i], s->last_picture.data[i], s->current_picture.data[i], + s->frame_width / (i?4:1), s->frame_height / (i?4:1), + s->picture.linesize[i], s->current_picture.linesize[i]) < 0) + return -1; + } + +// align_put_bits(&s->pb); + while(put_bits_count(&s->pb) & 31) + put_bits(&s->pb, 1, 0); + + flush_put_bits(&s->pb); + + return (put_bits_count(&s->pb) / 8); +} + +static int svq1_encode_end(AVCodecContext *avctx) +{ + SVQ1Context * const s = avctx->priv_data; + int i; + + av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", s->rd_total/(double)(avctx->width*avctx->height*avctx->frame_number)); + + av_freep(&s->m.me.scratchpad); + av_freep(&s->m.me.map); + av_freep(&s->m.me.score_map); + av_freep(&s->mb_type); + av_freep(&s->dummy); + + for(i=0; i<3; i++){ + av_freep(&s->motion_val8[i]); + av_freep(&s->motion_val16[i]); + } + + return 0; +} + + +AVCodec svq1_encoder = { + "svq1", + CODEC_TYPE_VIDEO, + CODEC_ID_SVQ1, + sizeof(SVQ1Context), + svq1_encode_init, + svq1_encode_frame, + svq1_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV410P, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/svq1enc_cb.h b/contrib/ffmpeg/libavcodec/svq1enc_cb.h new file mode 100644 index 000000000..1feeed0ab --- /dev/null +++ b/contrib/ffmpeg/libavcodec/svq1enc_cb.h @@ -0,0 +1,96 @@ +/* + * SVQ1 Encoder + * Copyright (C) 2004 Mike Melanson <melanson@pcisys.net> + * + * 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 svq1enc_cb.h + * svq1 code books. + */ + +#ifndef FFMPEG_SVQ1ENC_CB_H +#define FFMPEG_SVQ1ENC_CB_H + +#include <stdint.h> + +static const int8_t svq1_inter_codebook_sum[4][16*6] = { + { + -1, 1, -2, 0, 1, -1, -1, -1, -2, -1, 1, -1, -1, 0, -1, -1, + 0, -1, -1, -1, -1, 0, -1, 0, 0, 0, -3, 1, -1, 0, 1, -1, + 1, -1, 2, 2, 1, 1, 2, 0, 0, 0, -1, 1, 1, 0, 0, 0, + 1, -1, 0, 1, -1, 1, 1, 0, 1, 0, -1, 1, 1, 0, 0, 0, + -2, 0, 0, -2, 0, 0, -2, 0, -2, -1, -2, -1, 0, 0, -1, 0, + 1, 0, 1, -1, 2, 2, 1, 2, 2, 1, 0, 1, 1, 0, 1, 1, + },{ + -2, 1, -1, -1, 1, 0, 1, -1, -1, -1, 1, -1, 0, -1, 0, -1, + 0, 0, 0, -2, 0, 1, 0, -1, -1, 0, 2, -3, 1, -2, 3, -1, + 2, 0, 2, 1, 1, -1, 1, 1, 0, 0, 1, 1, 2, -2, 1, 0, + -2, -1, 2, -2, -2, 0, -3, 0, -1, 0, -1, 0, -1, 0, -2, -3, + 1, -2, -2, -1, 1, -1, -1, 1, -1, 1, 1, 0, -2, 0, 1, 1, + 1, 1, 2, 1, 0, 0, -1, 0, 0, 1, 0, 1, -1, 1, 0, 2, + },{ + 0, 0, 0, -3, 1, 1, 1, -3, 0, -1, 0, -3, 1, -3, 0, -2, + 1, 2, -1, -3, 0, -3, 1, -1, 0, -1, 0, 0, 1, 2, 1, 1, + -1, 2, -3, 3, 1, 0, -5, 1, 0, -1, -3, 1, 0, 2, 0, -3, + 4, 2, 0, -2, 1, -2, 3, -2, 1, 1, 0, -1, 2, 5, 3, 1, + -1, 0, 2, -3, -2, 0, 0, -2, 2, -3, -1, -1, 2, 1, 0, -2, + 3, -1, 1, -1, 2, 4, 0, 1, 0, 1, 0, -1, -3, -2, -1, 0, + },{ + 0, 2, -1, -1, 2, -4, -2, 3, 0, -1, -5, 1, 0, 1, 0, 6, + -2, 2, 0, 1, 1, -1, -1, -2, 1, -2, -1, 0, 2, -2, -2, -1, + -4, 2, -1, -3, -1, -2, 2, -1, 2, -1, 2, 0, 3, -3, -3, 0, + -3, 0, 0, -2, 4, -4, 0, -1, 4, 0, -2, -2, 3, -2, 0, 4, + 5, 0, 1, 0, -3, 3, 3, 2, 0, 0, 1, 2, -5, -2, -3, 0, + -3, 2, -2, 2, -2, 4, 7, -3, 4, 2, 3, 2, -1, 0, -3, 1, + } +}; + +static const int8_t svq1_intra_codebook_sum[4][16*6] = { + { + 0, 0, 0, -1, -1, -1, -1, -2, 0, -1, -1, 0, -1, 0, 1, 0, + 1, 0, -1, 1, 0, 0, -1, 1, -1, 0, 0, 0, -1, 1, 0, 0, + -1, 0, 0, 1, -1, 1, 0, -1, -1, 0, 1, 1, 0, 0, -1, 1, + 0, 1, 0, 0, 1, -1, 0, 0, 0, -1, 1, 0, 1, 0, -2, 1, + 0, -1, 1, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1, 0, 0, 0, + 0, 1, 1, 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 1, 1, -1, + },{ + -1, -2, 0, -1, 1, 0, -1, 0, -1, -4, -1, -2, -1, -2, 1, -2, + 0, 0, 4, -2, -1, 1, 1, 0, 2, 1, 1, 0, 2, 0, 0, 0, + 1, 1, 0, -1, -1, -1, 1, 0, -1, -3, -3, 1, -1, 1, -2, -1, + 1, -1, 0, 1, 2, 1, -1, -1, 1, 1, 1, 2, 1, 0, 1, -2, + -2, 0, -1, -2, -2, 0, -1, -1, -1, 0, 1, 0, -1, -1, 0, -1, + 0, 2, 1, 2, 2, 1, -1, 1, 0, 2, 0, -1, 1, 0, 0, 0, + },{ + -2, 0, -1, -1, 1, 1, -2, 0, -2, 0, 1, -2, -2, 1, -1, -1, + 3, -2, 0, -3, -4, -3, 2, 1, 0, 3, -2, 2, 3, 2, 2, -1, + -3, 1, 0, 1, 0, 0, 0, 1, -2, 1, -2, -2, -1, -2, -2, 2, + 0, -4, 0, 2, -1, 0, 2, 2, 2, 1, 0, -1, -1, 1, -3, 2, + 2, 1, 0, 3, 1, -1, 1, 3, 1, 0, 1, 1, 2, -1, 1, -1, + -2, -1, 0, -1, 1, -1, 1, -2, -2, -1, -1, -3, 1, -4, -3, 1, + },{ + -2, 0, -2, 3, -1, -1, 0, 2, 2, -1, -3, 2, 1, 0, -2, -1, + -3, -2, -2, 1, 2, -3, 0, 1, -5, -2, -3, 0, -2, -1, 2, 0, + -1, -1, 0, -2, 1, 3, -7, -2, -2, -1, 2, -1, 0, 3, 1, 3, + 1, 0, 0, 1, 2, 3, 1, 2, 0, -2, -2, 1, 1, 2, 2, 3, + 4, 1, -1, 2, -2, 4, 0, 0, 0, 4, 2, 0, -2, -2, 2, -4, + -1, 5, -2, -2, -3, 2, -3, -1, 3, -3, 0, 4, 3, 0, 1, -2, + } +}; + +#endif /* FFMPEG_SVQ1ENC_CB_H */ diff --git a/contrib/ffmpeg/libavcodec/svq3.c b/contrib/ffmpeg/libavcodec/svq3.c index db601010b..98260adf4 100644 --- a/contrib/ffmpeg/libavcodec/svq3.c +++ b/contrib/ffmpeg/libavcodec/svq3.c @@ -16,8 +16,9 @@ * 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 - * - * + */ + +/* * How to use this decoder: * SVQ3 data is transported within Apple Quicktime files. Quicktime files * have stsd atoms to describe media trak properties. A stsd atom for a @@ -37,7 +38,6 @@ * You will know you have these parameters passed correctly when the decoder * correctly decodes this file: * ftp://ftp.mplayerhq.hu/MPlayer/samples/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov - * */ /** @@ -180,34 +180,6 @@ static void svq3_add_idct_c (uint8_t *dst, DCTELEM *block, int stride, int qp, i } } -static void pred4x4_down_left_svq3_c(uint8_t *src, uint8_t *topright, int stride){ - LOAD_TOP_EDGE - LOAD_LEFT_EDGE - const __attribute__((unused)) int unu0= t0; - const __attribute__((unused)) int unu1= l0; - - src[0+0*stride]=(l1 + t1)>>1; - src[1+0*stride]= - src[0+1*stride]=(l2 + t2)>>1; - src[2+0*stride]= - src[1+1*stride]= - src[0+2*stride]= - src[3+0*stride]= - src[2+1*stride]= - src[1+2*stride]= - src[0+3*stride]= - src[3+1*stride]= - src[2+2*stride]= - src[1+3*stride]= - src[3+2*stride]= - src[2+3*stride]= - src[3+3*stride]=(l3 + t3)>>1; -} - -static void pred16x16_plane_svq3_c(uint8_t *src, int stride){ - pred16x16_plane_compat_c(src, stride, 1); -} - static inline int svq3_decode_block (GetBitContext *gb, DCTELEM *block, int index, const int type) { @@ -465,9 +437,9 @@ static int svq3_decode_mb (H264Context *h, unsigned int mb_type) { mb_type = MB_TYPE_16x16; } } else if (mb_type < 8) { /* INTER */ - if (h->thirdpel_flag && h->halfpel_flag == !get_bits (&s->gb, 1)) { + if (h->thirdpel_flag && h->halfpel_flag == !get_bits1 (&s->gb)) { mode = THIRDPEL_MODE; - } else if (h->halfpel_flag && h->thirdpel_flag == !get_bits (&s->gb, 1)) { + } else if (h->halfpel_flag && h->thirdpel_flag == !get_bits1 (&s->gb)) { mode = HALFPEL_MODE; } else { mode = FULLPEL_MODE; @@ -480,7 +452,6 @@ static int svq3_decode_mb (H264Context *h, unsigned int mb_type) { N??11111 N??11111 N??11111 - N */ for (m=0; m < 2; m++) { @@ -749,7 +720,7 @@ static int svq3_decode_slice_header (H264Context *h) { i = (s->mb_num < 64) ? 6 : (1 + av_log2 (s->mb_num - 1)); s->mb_skip_run = get_bits (&s->gb, i) - (s->mb_x + (s->mb_y * s->mb_width)); } else { - get_bits1 (&s->gb); + skip_bits1 (&s->gb); s->mb_skip_run = 0; } @@ -758,17 +729,17 @@ static int svq3_decode_slice_header (H264Context *h) { s->adaptive_quant = get_bits1 (&s->gb); /* unknown fields */ - get_bits1 (&s->gb); + skip_bits1 (&s->gb); if (h->unknown_svq3_flag) { - get_bits1 (&s->gb); + skip_bits1 (&s->gb); } - get_bits1 (&s->gb); - get_bits (&s->gb, 2); + skip_bits1 (&s->gb); + skip_bits (&s->gb, 2); while (get_bits1 (&s->gb)) { - get_bits (&s->gb, 8); + skip_bits (&s->gb, 8); } /* reset intra predictors and invalidate motion vector references */ @@ -789,7 +760,7 @@ static int svq3_decode_slice_header (H264Context *h) { static int svq3_decode_frame (AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) { + const uint8_t *buf, int buf_size) { MpegEncContext *const s = avctx->priv_data; H264Context *const h = avctx->priv_data; int m, mb_type; @@ -803,12 +774,10 @@ static int svq3_decode_frame (AVCodecContext *avctx, if (!s->context_initialized) { s->width = avctx->width; s->height = avctx->height; - h->pred4x4[DIAG_DOWN_LEFT_PRED] = pred4x4_down_left_svq3_c; - h->pred16x16[PLANE_PRED8x8] = pred16x16_plane_svq3_c; h->halfpel_flag = 1; h->thirdpel_flag = 1; h->unknown_svq3_flag = 0; - h->chroma_qp = 4; + h->chroma_qp[0] = h->chroma_qp[1] = 4; if (MPV_common_init (s) < 0) return -1; @@ -835,26 +804,26 @@ static int svq3_decode_frame (AVCodecContext *avctx, /* 'frame size code' and optional 'width, height' */ if (get_bits (&gb, 3) == 7) { - get_bits (&gb, 12); - get_bits (&gb, 12); + skip_bits (&gb, 12); + skip_bits (&gb, 12); } h->halfpel_flag = get_bits1 (&gb); h->thirdpel_flag = get_bits1 (&gb); /* unknown fields */ - get_bits1 (&gb); - get_bits1 (&gb); - get_bits1 (&gb); - get_bits1 (&gb); + skip_bits1 (&gb); + skip_bits1 (&gb); + skip_bits1 (&gb); + skip_bits1 (&gb); s->low_delay = get_bits1 (&gb); /* unknown field */ - get_bits1 (&gb); + skip_bits1 (&gb); while (get_bits1 (&gb)) { - get_bits (&gb, 8); + skip_bits (&gb, 8); } h->unknown_svq3_flag = get_bits1 (&gb); @@ -892,11 +861,11 @@ static int svq3_decode_frame (AVCodecContext *avctx, s->current_picture.pict_type = s->pict_type; s->current_picture.key_frame = (s->pict_type == I_TYPE); - /* skip b frames if we dont have reference frames */ + /* Skip B-frames if we do not have reference frames. */ if (s->last_picture_ptr == NULL && s->pict_type == B_TYPE) return 0; - /* skip b frames if we are in a hurry */ + /* Skip B-frames if we are in a hurry. */ if (avctx->hurry_up && s->pict_type == B_TYPE) return 0; - /* skip everything if we are in a hurry >= 5 */ + /* Skip everything if we are in a hurry >= 5. */ if (avctx->hurry_up >= 5) return 0; if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) @@ -939,7 +908,8 @@ static int svq3_decode_frame (AVCodecContext *avctx, int j; for(j=-1; j<4; j++) h->ref_cache[m][scan8[0] + 8*i + j]= 1; - h->ref_cache[m][scan8[0] + 8*i + j]= PART_NOT_AVAILABLE; + if(i<3) + h->ref_cache[m][scan8[0] + 8*i + j]= PART_NOT_AVAILABLE; } } @@ -993,7 +963,7 @@ static int svq3_decode_frame (AVCodecContext *avctx, avctx->frame_number = s->picture_number - 1; - /* dont output the last pic after seeking */ + /* Do not output the last pic after seeking. */ if (s->last_picture_ptr || s->low_delay) { *data_size = sizeof(AVFrame); } diff --git a/contrib/ffmpeg/libavcodec/targa.c b/contrib/ffmpeg/libavcodec/targa.c index d637bedae..930915777 100644 --- a/contrib/ffmpeg/libavcodec/targa.c +++ b/contrib/ffmpeg/libavcodec/targa.c @@ -17,7 +17,6 @@ * 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" @@ -38,7 +37,7 @@ typedef struct TargaContext { 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) +static void targa_decode_rle(AVCodecContext *avctx, TargaContext *s, const uint8_t *src, uint8_t *dst, int w, int h, int stride, int bpp) { int i, x, y; int depth = (bpp + 1) >> 3; @@ -90,7 +89,7 @@ static void targa_decode_rle(AVCodecContext *avctx, TargaContext *s, uint8_t *sr static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { TargaContext * const s = avctx->priv_data; AVFrame *picture = data; diff --git a/contrib/ffmpeg/libavcodec/targaenc.c b/contrib/ffmpeg/libavcodec/targaenc.c index 8b36e1d3d..47e33b19e 100644 --- a/contrib/ffmpeg/libavcodec/targaenc.c +++ b/contrib/ffmpeg/libavcodec/targaenc.c @@ -17,42 +17,9 @@ * 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" - -/** - * Count up to 127 consecutive pixels which are either all the same or - * all differ from the previous and next pixels. - * @param start Pointer to the first pixel - * @param len Maximum number of pixels - * @param bpp Bytes per pixel - * @param same 1 if searching for identical pixel values. 0 for differing - * @return Number of matching consecutive pixels found - */ -static int count_pixels(uint8_t *start, int len, int bpp, int same) -{ - uint8_t *pos; - int count = 1; - - for(pos = start + bpp; count < FFMIN(128, len); pos += bpp, count ++) { - if(same != !memcmp(pos-bpp, pos, bpp)) { - if(!same) { - /* if bpp == 1, then 0 1 1 0 is more efficiently encoded as a single - * raw block of pixels. for larger bpp, RLE is as good or better */ - if(bpp == 1 && count + 1 < FFMIN(128, len) && *pos != *(pos+1)) - continue; - - /* if RLE can encode the next block better than as a raw block, - * back up and leave _all_ the identical pixels for RLE */ - count --; - } - break; - } - } - - return count; -} +#include "rle.h" /** * RLE compress the image, with maximum size of out_size @@ -67,35 +34,18 @@ static int count_pixels(uint8_t *start, int len, int bpp, int same) static int targa_encode_rle(uint8_t *outbuf, int out_size, AVFrame *pic, int bpp, int w, int h) { - int count, x, y; - uint8_t *ptr, *line, *out; + int y,ret; + uint8_t *out; out = outbuf; - line = pic->data[0]; for(y = 0; y < h; y ++) { - ptr = line; - - for(x = 0; x < w; x += count) { - /* see if we can encode the next set of pixels with RLE */ - if((count = count_pixels(ptr, w-x, bpp, 1)) > 1) { - if(out + bpp + 1 > outbuf + out_size) return -1; - *out++ = 0x80 | (count - 1); - memcpy(out, ptr, bpp); - out += bpp; - } else { - /* fall back on uncompressed */ - count = count_pixels(ptr, w-x, bpp, 0); - *out++ = count - 1; - - if(out + bpp*count > outbuf + out_size) return -1; - memcpy(out, ptr, bpp * count); - out += bpp * count; - } - ptr += count * bpp; + ret = ff_rle_encode(out, out_size, pic->data[0] + pic->linesize[0] * y, bpp, w, 0x7f, 0, -1, 0); + if(ret == -1){ + return -1; } - - line += pic->linesize[0]; + out+= ret; + out_size -= ret; } return out - outbuf; diff --git a/contrib/ffmpeg/libavcodec/tiertexseqv.c b/contrib/ffmpeg/libavcodec/tiertexseqv.c index ca3baf09e..f106ceb32 100644 --- a/contrib/ffmpeg/libavcodec/tiertexseqv.c +++ b/contrib/ffmpeg/libavcodec/tiertexseqv.c @@ -25,7 +25,6 @@ */ #include "avcodec.h" -#include "common.h" #define ALT_BITSTREAM_READER_LE #include "bitstream.h" @@ -38,7 +37,7 @@ typedef struct SeqVideoContext { } SeqVideoContext; -static unsigned char *seq_unpack_rle_block(unsigned char *src, unsigned char *dst, int dst_size) +static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsigned char *dst, int dst_size) { int i, len, sz; GetBitContext gb; @@ -68,9 +67,9 @@ static unsigned char *seq_unpack_rle_block(unsigned char *src, unsigned char *ds return src; } -static unsigned char *seq_decode_op1(SeqVideoContext *seq, unsigned char *src, unsigned char *dst) +static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) { - unsigned char *color_table; + const unsigned char *color_table; int b, i, len, bits; GetBitContext gb; @@ -108,7 +107,7 @@ static unsigned char *seq_decode_op1(SeqVideoContext *seq, unsigned char *src, u return src; } -static unsigned char *seq_decode_op2(SeqVideoContext *seq, unsigned char *src, unsigned char *dst) +static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) { int i; @@ -121,7 +120,7 @@ static unsigned char *seq_decode_op2(SeqVideoContext *seq, unsigned char *src, u return src; } -static unsigned char *seq_decode_op3(SeqVideoContext *seq, unsigned char *src, unsigned char *dst) +static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) { int pos, offset; @@ -134,7 +133,7 @@ static unsigned char *seq_decode_op3(SeqVideoContext *seq, unsigned char *src, u return src; } -static void seqvideo_decode(SeqVideoContext *seq, unsigned char *data, int data_size) +static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size) { GetBitContext gb; int flags, i, j, x, y, op; @@ -147,7 +146,7 @@ static void seqvideo_decode(SeqVideoContext *seq, unsigned char *data, int data_ for (i = 0; i < 256; i++) { for (j = 0; j < 3; j++, data++) c[j] = (*data << 2) | (*data >> 4); - seq->palette[i] = (c[0] << 16) | (c[1] << 8) | c[2]; + seq->palette[i] = AV_RB24(c); } memcpy(seq->frame.data[1], seq->palette, sizeof(seq->palette)); seq->frame.palette_has_changed = 1; @@ -176,11 +175,10 @@ static void seqvideo_decode(SeqVideoContext *seq, unsigned char *data, int data_ static int seqvideo_decode_init(AVCodecContext *avctx) { - SeqVideoContext *seq = (SeqVideoContext *)avctx->priv_data; + SeqVideoContext *seq = avctx->priv_data; seq->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; seq->frame.data[0] = NULL; @@ -189,10 +187,10 @@ static int seqvideo_decode_init(AVCodecContext *avctx) static int seqvideo_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - SeqVideoContext *seq = (SeqVideoContext *)avctx->priv_data; + SeqVideoContext *seq = avctx->priv_data; seq->frame.reference = 1; seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; @@ -211,7 +209,7 @@ static int seqvideo_decode_frame(AVCodecContext *avctx, static int seqvideo_decode_end(AVCodecContext *avctx) { - SeqVideoContext *seq = (SeqVideoContext *)avctx->priv_data; + SeqVideoContext *seq = avctx->priv_data; if (seq->frame.data[0]) avctx->release_buffer(avctx, &seq->frame); diff --git a/contrib/ffmpeg/libavcodec/tiff.c b/contrib/ffmpeg/libavcodec/tiff.c index 344b5a311..a172b6253 100644 --- a/contrib/ffmpeg/libavcodec/tiff.c +++ b/contrib/ffmpeg/libavcodec/tiff.c @@ -17,56 +17,20 @@ * 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 - * + */ + +/** + * TIFF image decoder + * @file tiff.c + * @author Konstantin Shishkov */ #include "avcodec.h" #ifdef CONFIG_ZLIB #include <zlib.h> #endif #include "lzw.h" +#include "tiff.h" -/* 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_PLANAR = 0x11C, - TIFF_XPOS = 0x11E, - TIFF_YPOS = 0x11F, - TIFF_PREDICTOR = 0x13D, - TIFF_PAL = 0x140 -}; - -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 -}; - -/** sizes of various TIFF field types */ -static const int type_sizes[6] = { - 0, 1, 100, 2, 4, 8 -}; typedef struct TiffContext { AVCodecContext *avctx; @@ -80,25 +44,25 @@ typedef struct TiffContext { int strips, rps; int sot; - uint8_t* stripdata; - uint8_t* stripsizes; + const uint8_t* stripdata; + const uint8_t* stripsizes; int stripsize, stripoff; LZWState *lzw; } TiffContext; -static int tget_short(uint8_t **p, int le){ +static int tget_short(const uint8_t **p, int le){ int v = le ? AV_RL16(*p) : AV_RB16(*p); *p += 2; return v; } -static int tget_long(uint8_t **p, int le){ +static int tget_long(const uint8_t **p, int le){ int v = le ? AV_RL32(*p) : AV_RB32(*p); *p += 4; return v; } -static int tget(uint8_t **p, int type, int le){ +static int tget(const uint8_t **p, int type, int le){ switch(type){ case TIFF_BYTE : return *(*p)++; case TIFF_SHORT: return tget_short(p, le); @@ -107,9 +71,9 @@ static int tget(uint8_t **p, int type, int le){ } } -static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, uint8_t *src, int size, int lines){ +static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uint8_t *src, int size, int lines){ int c, line, pixels, code; - uint8_t *ssrc = src; + const uint8_t *ssrc = src; int width = s->width * (s->bpp / 8); #ifdef CONFIG_ZLIB uint8_t *zbuf; unsigned long outlen; @@ -186,12 +150,14 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, uint8_t * } -static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t *end_buf, AVFrame *pic) +static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf, AVFrame *pic) { int tag, type, count, off, value = 0; - uint8_t *src, *dst; + const uint8_t *src; + uint8_t *dst; int i, j, ssize, soff, stride; - int *pal, *rp, *gp, *bp; + uint32_t *pal; + const uint8_t *rp, *gp, *bp; tag = tget_short(&buf, s->le); type = tget_short(&buf, s->le); @@ -280,7 +246,7 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t } if(s->bpp == 8){ /* make default grayscale pal */ - pal = s->picture.data[1]; + pal = (uint32_t *) s->picture.data[1]; for(i = 0; i < 256; i++) pal[i] = i * 0x010101; } @@ -381,14 +347,14 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t return -1; } if(value == 2){ - src = pic->data[0]; + dst = pic->data[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; + dst[j] += dst[j - soff]; + dst += stride; } } break; @@ -413,7 +379,7 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t av_log(s->avctx, AV_LOG_ERROR, "Palette met but this is not palettized format\n"); return -1; } - pal = s->picture.data[1]; + pal = (uint32_t *) s->picture.data[1]; off = type_sizes[type]; rp = buf; gp = buf + count / 3 * off; @@ -438,12 +404,12 @@ static int tiff_decode_tag(TiffContext *s, uint8_t *start, uint8_t *buf, uint8_t static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const 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; + const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; int id, le, off; int i, entries; @@ -457,6 +423,7 @@ static int decode_frame(AVCodecContext *avctx, } s->le = le; s->invert = 0; + s->compr = TIFF_RAW; // 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){ diff --git a/contrib/ffmpeg/libavcodec/tiff.h b/contrib/ffmpeg/libavcodec/tiff.h new file mode 100644 index 000000000..c5687d7df --- /dev/null +++ b/contrib/ffmpeg/libavcodec/tiff.h @@ -0,0 +1,86 @@ +/* + * TIFF tables + * 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 + */ + +/** + * TIFF tables + * @file tiff.h + * @author Konstantin Shishkov + */ +#ifndef FFMPEG_TIFF_H +#define FFMPEG_TIFF_H + +#include <stdint.h> + +/** abridged list of TIFF tags */ +enum TiffTags{ + TIFF_SUBFILE = 0xfe, + TIFF_WIDTH = 0x100, + TIFF_HEIGHT, + TIFF_BPP, + TIFF_COMPR, + TIFF_INVERT = 0x106, + TIFF_STRIP_OFFS = 0x111, + TIFF_SAMPLES_PER_PIXEL = 0x115, + TIFF_ROWSPERSTRIP = 0x116, + TIFF_STRIP_SIZE, + TIFF_XRES = 0x11A, + TIFF_YRES = 0x11B, + TIFF_PLANAR = 0x11C, + TIFF_XPOS = 0x11E, + TIFF_YPOS = 0x11F, + TIFF_RES_UNIT = 0x128, + TIFF_SOFTWARE_NAME = 0x131, + TIFF_PREDICTOR = 0x13D, + TIFF_PAL = 0x140, + TIFF_YCBCR_COEFFICIENTS = 0x211, + TIFF_YCBCR_SUBSAMPLING = 0x212, + TIFF_YCBCR_POSITIONING = 0x213, + TIFF_REFERENCE_BW = 0x214, +}; + +/** list of TIFF compression types */ +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_RATIONAL, +}; + +/** sizes of various TIFF field types (string size = 100)*/ +static const uint8_t type_sizes[6] = { + 0, 1, 100, 2, 4, 8 +}; + +#endif /* FFMPEG_TIFF_H */ diff --git a/contrib/ffmpeg/libavcodec/tiffenc.c b/contrib/ffmpeg/libavcodec/tiffenc.c new file mode 100644 index 000000000..69f8e59f6 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/tiffenc.c @@ -0,0 +1,461 @@ +/* + * TIFF image encoder + * Copyright (c) 2007 Bartlomiej Wolowiec + * + * 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 + */ + +/** + * TIFF image encoder + * @file tiffenc.c + * @author Bartlomiej Wolowiec + */ +#include "avcodec.h" +#ifdef CONFIG_ZLIB +#include <zlib.h> +#endif +#include "bytestream.h" +#include "tiff.h" +#include "rle.h" +#include "lzw.h" + +#define TIFF_MAX_ENTRY 32 + +/** sizes of various TIFF field types (string size = 1)*/ +static const uint8_t type_sizes2[6] = { + 0, 1, 1, 2, 4, 8 +}; + +typedef struct TiffEncoderContext { + AVCodecContext *avctx; + AVFrame picture; + + int width; ///< picture width + int height; ///< picture height + unsigned int bpp; ///< bits per pixel + int compr; ///< compression level + int bpp_tab_size; ///< bpp_tab size + int photometric_interpretation; ///< photometric interpretation + int strips; ///< number of strips + int rps; ///< row per strip + uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header + int num_entries; ///< number of entires + uint8_t **buf; ///< actual position in buffer + uint8_t *buf_start; ///< pointer to first byte in buffer + int buf_size; ///< buffer size + uint16_t subsampling[2]; ///< YUV subsampling factors + struct LZWEncodeState *lzws; ///< LZW Encode state +} TiffEncoderContext; + + +/** + * Check free space in buffer + * @param s Tiff context + * @param need Needed bytes + * @return 0 - ok, 1 - no free space + */ +inline static int check_size(TiffEncoderContext * s, uint64_t need) +{ + if (s->buf_size < *s->buf - s->buf_start + need) { + *s->buf = s->buf_start + s->buf_size + 1; + av_log(s->avctx, AV_LOG_ERROR, "Buffer is too small\n"); + return 1; + } + return 0; +} + +/** + * Put n values to buffer + * + * @param p Pointer to pointer to output buffer + * @param n Number of values + * @param val Pointer to values + * @param type Type of values + * @param flip =0 - normal copy, >0 - flip + */ +static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type, + int flip) +{ + int i; +#ifdef WORDS_BIGENDIAN + flip ^= ((int[]) {0, 0, 0, 1, 3, 3})[type]; +#endif + for (i = 0; i < n * type_sizes2[type]; i++) + *(*p)++ = val[i ^ flip]; +} + +/** + * Add entry to directory in tiff header. + * @param s Tiff context + * @param tag Tag that identifies the entry + * @param type Entry type + * @param count The number of values + * @param ptr_val Pointer to values + */ +static void add_entry(TiffEncoderContext * s, + enum TiffTags tag, enum TiffTypes type, int count, + const void *ptr_val) +{ + uint8_t *entries_ptr = s->entries + 12 * s->num_entries; + + assert(s->num_entries < TIFF_MAX_ENTRY); + + bytestream_put_le16(&entries_ptr, tag); + bytestream_put_le16(&entries_ptr, type); + bytestream_put_le32(&entries_ptr, count); + + if (type_sizes[type] * count <= 4) { + tnput(&entries_ptr, count, ptr_val, type, 0); + } else { + bytestream_put_le32(&entries_ptr, *s->buf - s->buf_start); + check_size(s, count * type_sizes2[type]); + tnput(s->buf, count, ptr_val, type, 0); + } + + s->num_entries++; +} + +static void add_entry1(TiffEncoderContext * s, + enum TiffTags tag, enum TiffTypes type, int val){ + uint16_t w = val; + uint32_t dw= val; + add_entry(s, tag, type, 1, type == TIFF_SHORT ? (void *)&w : (void *)&dw); +} + +/** + * Encode one strip in tiff file + * + * @param s Tiff context + * @param src Input buffer + * @param dst Output buffer + * @param n Size of input buffer + * @param compr Compression method + * @return Number of output bytes. If an output error is encountered, -1 returned + */ +static int encode_strip(TiffEncoderContext * s, const int8_t * src, + uint8_t * dst, int n, int compr) +{ + + switch (compr) { +#ifdef CONFIG_ZLIB + case TIFF_DEFLATE: + case TIFF_ADOBE_DEFLATE: + { + unsigned long zlen = s->buf_size - (*s->buf - s->buf_start); + if (compress(dst, &zlen, src, n) != Z_OK) { + av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n"); + return -1; + } + return zlen; + } +#endif + case TIFF_RAW: + if (check_size(s, n)) + return -1; + memcpy(dst, src, n); + return n; + case TIFF_PACKBITS: + return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), src, 1, n, 2, 0xff, -1, 0); + case TIFF_LZW: + return ff_lzw_encode(s->lzws, src, n); + default: + return -1; + } +} + +static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum) +{ + AVFrame *p = &s->picture; + int i, j, k; + int w = (s->width - 1) / s->subsampling[0] + 1; + uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]]; + uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]]; + for (i = 0; i < w; i++){ + for (j = 0; j < s->subsampling[1]; j++) + for (k = 0; k < s->subsampling[0]; k++) + *dst++ = p->data[0][(lnum + j) * p->linesize[0] + + i * s->subsampling[0] + k]; + *dst++ = *pu++; + *dst++ = *pv++; + } +} + +static int encode_frame(AVCodecContext * avctx, unsigned char *buf, + int buf_size, void *data) +{ + TiffEncoderContext *s = avctx->priv_data; + AVFrame *pict = data; + AVFrame *const p = (AVFrame *) & s->picture; + int i; + int n; + uint8_t *ptr = buf; + uint8_t *offset; + uint32_t strips; + uint32_t *strip_sizes = NULL; + uint32_t *strip_offsets = NULL; + int bytes_per_row; + uint32_t res[2] = { 72, 1 }; // image resolution (72/1) + static const uint16_t bpp_tab[] = { 8, 8, 8, 8 }; + int ret = -1; + int is_yuv = 0; + uint8_t *yuv_line = NULL; + int shift_h, shift_v; + + s->buf_start = buf; + s->buf = &ptr; + s->buf_size = buf_size; + + *p = *pict; + p->pict_type = FF_I_TYPE; + p->key_frame = 1; + + s->compr = TIFF_PACKBITS; + if (avctx->compression_level == 0) { + s->compr = TIFF_RAW; + } else if(avctx->compression_level == 2) { + s->compr = TIFF_LZW; +#ifdef CONFIG_ZLIB + } else if ((avctx->compression_level >= 3)) { + s->compr = TIFF_DEFLATE; +#endif + } + + s->width = avctx->width; + s->height = avctx->height; + s->subsampling[0] = 1; + s->subsampling[1] = 1; + + switch (avctx->pix_fmt) { + case PIX_FMT_RGB24: + s->bpp = 24; + s->photometric_interpretation = 2; + break; + case PIX_FMT_GRAY8: + s->bpp = 8; + s->photometric_interpretation = 1; + break; + case PIX_FMT_PAL8: + s->bpp = 8; + s->photometric_interpretation = 3; + break; + case PIX_FMT_MONOBLACK: + s->bpp = 1; + s->photometric_interpretation = 1; + break; + case PIX_FMT_MONOWHITE: + s->bpp = 1; + s->photometric_interpretation = 0; + break; + case PIX_FMT_YUV420P: + case PIX_FMT_YUV422P: + case PIX_FMT_YUV444P: + case PIX_FMT_YUV410P: + case PIX_FMT_YUV411P: + s->photometric_interpretation = 6; + avcodec_get_chroma_sub_sample(avctx->pix_fmt, + &shift_h, &shift_v); + s->bpp = 8 + (16 >> (shift_h + shift_v)); + s->subsampling[0] = 1 << shift_h; + s->subsampling[1] = 1 << shift_v; + s->bpp_tab_size = 3; + is_yuv = 1; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, + "This colors format is not supported\n"); + return -1; + } + if (!is_yuv) + s->bpp_tab_size = (s->bpp >> 3); + + if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW) + //best choose for DEFLATE + s->rps = s->height; + else + s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1); // suggest size of strip + s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up + + strips = (s->height - 1) / s->rps + 1; + + if (check_size(s, 8)) + goto fail; + + // write header + bytestream_put_le16(&ptr, 0x4949); + bytestream_put_le16(&ptr, 42); + + offset = ptr; + bytestream_put_le32(&ptr, 0); + + strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips); + strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips); + + bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp + * s->subsampling[0] * s->subsampling[1] + 7) >> 3; + if (is_yuv){ + yuv_line = av_malloc(bytes_per_row); + if (yuv_line == NULL){ + av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n"); + goto fail; + } + } + +#ifdef CONFIG_ZLIB + if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) { + uint8_t *zbuf; + int zlen, zn; + int j; + + zlen = bytes_per_row * s->rps; + zbuf = av_malloc(zlen); + strip_offsets[0] = ptr - buf; + zn = 0; + for (j = 0; j < s->rps; j++) { + if (is_yuv){ + pack_yuv(s, yuv_line, j); + memcpy(zbuf + zn, yuv_line, bytes_per_row); + j += s->subsampling[1] - 1; + } + else + memcpy(zbuf + j * bytes_per_row, + p->data[0] + j * p->linesize[0], bytes_per_row); + zn += bytes_per_row; + } + n = encode_strip(s, zbuf, ptr, zn, s->compr); + av_free(zbuf); + if (n<0) { + av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n"); + goto fail; + } + ptr += n; + strip_sizes[0] = ptr - buf - strip_offsets[0]; + } else +#endif + { + if(s->compr == TIFF_LZW) + s->lzws = av_malloc(ff_lzw_encode_state_size); + for (i = 0; i < s->height; i++) { + if (strip_sizes[i / s->rps] == 0) { + if(s->compr == TIFF_LZW){ + ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start), 12); + } + strip_offsets[i / s->rps] = ptr - buf; + } + if (is_yuv){ + pack_yuv(s, yuv_line, i); + n = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr); + i += s->subsampling[1] - 1; + } + else + n = encode_strip(s, p->data[0] + i * p->linesize[0], + ptr, bytes_per_row, s->compr); + if (n < 0) { + av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n"); + goto fail; + } + strip_sizes[i / s->rps] += n; + ptr += n; + if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){ + int ret; + ret = ff_lzw_encode_flush(s->lzws); + strip_sizes[(i / s->rps )] += ret ; + ptr += ret; + } + } + if(s->compr == TIFF_LZW) + av_free(s->lzws); + } + + s->num_entries = 0; + + add_entry1(s,TIFF_SUBFILE, TIFF_LONG, 0); + add_entry1(s,TIFF_WIDTH, TIFF_LONG, s->width); + add_entry1(s,TIFF_HEIGHT, TIFF_LONG, s->height); + + if (s->bpp_tab_size) + add_entry(s, TIFF_BPP, TIFF_SHORT, s->bpp_tab_size, bpp_tab); + + add_entry1(s,TIFF_COMPR, TIFF_SHORT, s->compr); + add_entry1(s,TIFF_INVERT, TIFF_SHORT, s->photometric_interpretation); + add_entry(s, TIFF_STRIP_OFFS, TIFF_LONG, strips, strip_offsets); + + if (s->bpp_tab_size) + add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size); + + add_entry1(s,TIFF_ROWSPERSTRIP, TIFF_LONG, s->rps); + add_entry(s, TIFF_STRIP_SIZE, TIFF_LONG, strips, strip_sizes); + add_entry(s, TIFF_XRES, TIFF_RATIONAL, 1, res); + add_entry(s, TIFF_YRES, TIFF_RATIONAL, 1, res); + add_entry1(s,TIFF_RES_UNIT, TIFF_SHORT, 2); + + if(!(avctx->flags & CODEC_FLAG_BITEXACT)) + add_entry(s, TIFF_SOFTWARE_NAME, TIFF_STRING, + strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT); + + if (avctx->pix_fmt == PIX_FMT_PAL8) { + uint16_t pal[256 * 3]; + for (i = 0; i < 256; i++) { + uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4); + pal[i] = ((rgb >> 16) & 0xff) * 257; + pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257; + pal[i + 512] = ( rgb & 0xff) * 257; + } + add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal); + } + if (is_yuv){ + /** according to CCIR Recommendation 601.1 */ + uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1}; + add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT, 2, s->subsampling); + add_entry(s, TIFF_REFERENCE_BW, TIFF_RATIONAL, 6, refbw); + } + bytestream_put_le32(&offset, ptr - buf); // write offset to dir + + if (check_size(s, 6 + s->num_entries * 12)) + goto fail; + bytestream_put_le16(&ptr, s->num_entries); // write tag count + bytestream_put_buffer(&ptr, s->entries, s->num_entries * 12); + bytestream_put_le32(&ptr, 0); + + ret = ptr - buf; + +fail: + av_free(strip_sizes); + av_free(strip_offsets); + av_free(yuv_line); + return ret; +} + +AVCodec tiff_encoder = { + "tiff", + CODEC_TYPE_VIDEO, + CODEC_ID_TIFF, + sizeof(TiffEncoderContext), + NULL, + encode_frame, + NULL, + NULL, + 0, + NULL, + .pix_fmts = + (enum PixelFormat[]) {PIX_FMT_RGB24, PIX_FMT_PAL8, PIX_FMT_GRAY8, + PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE, + PIX_FMT_YUV420P, PIX_FMT_YUV422P, + PIX_FMT_YUV444P, PIX_FMT_YUV410P, + PIX_FMT_YUV411P + -1} + +}; diff --git a/contrib/ffmpeg/libavcodec/truemotion1.c b/contrib/ffmpeg/libavcodec/truemotion1.c index a7d3544f4..50948fdda 100644 --- a/contrib/ffmpeg/libavcodec/truemotion1.c +++ b/contrib/ffmpeg/libavcodec/truemotion1.c @@ -22,7 +22,7 @@ /** * @file truemotion1.c * Duck TrueMotion v1 Video Decoder by - * Alex Beregszaszi (alex@fsn.hu) and + * Alex Beregszaszi and * Mike Melanson (melanson@pcisys.net) * * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and @@ -34,7 +34,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -43,14 +42,13 @@ typedef struct TrueMotion1Context { AVCodecContext *avctx; AVFrame frame; - AVFrame prev_frame; - uint8_t *buf; + const uint8_t *buf; int size; - uint8_t *mb_change_bits; + const uint8_t *mb_change_bits; int mb_change_bits_row_size; - uint8_t *index_stream; + const uint8_t *index_stream; int index_stream_size; int flags; @@ -465,7 +463,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s) static int truemotion1_decode_init(AVCodecContext *avctx) { - TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data; + TrueMotion1Context *s = avctx->priv_data; s->avctx = avctx; @@ -475,8 +473,7 @@ static int truemotion1_decode_init(AVCodecContext *avctx) // else // avctx->pix_fmt = PIX_FMT_RGB555; - avctx->has_b_frames = 0; - s->frame.data[0] = s->prev_frame.data[0] = NULL; + s->frame.data[0] = NULL; /* there is a vertical predictor for each pixel in a line; each vertical * predictor is 0 to start with */ @@ -592,8 +589,7 @@ hres,vres,i,i%vres (0 < i < 4) #define OUTPUT_PIXEL_PAIR() \ *current_pixel_pair = *vert_pred + horiz_pred; \ - *vert_pred++ = *current_pixel_pair++; \ - prev_pixel_pair++; + *vert_pred++ = *current_pixel_pair++; static void truemotion1_decode_16bit(TrueMotion1Context *s) { @@ -603,13 +599,11 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s) unsigned int horiz_pred; unsigned int *vert_pred; unsigned int *current_pixel_pair; - unsigned int *prev_pixel_pair; unsigned char *current_line = s->frame.data[0]; - unsigned char *prev_line = s->prev_frame.data[0]; int keyframe = s->flags & FLAG_KEYFRAME; /* these variables are for managing the stream of macroblock change bits */ - unsigned char *mb_change_bits = s->mb_change_bits; + const unsigned char *mb_change_bits = s->mb_change_bits; unsigned char mb_change_byte; unsigned char mb_change_byte_mask; int mb_change_index; @@ -628,7 +622,6 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s) /* re-init variables for the next line iteration */ horiz_pred = 0; current_pixel_pair = (unsigned int *)current_line; - prev_pixel_pair = (unsigned int *)prev_line; vert_pred = s->vert_pred; mb_change_index = 0; mb_change_byte = mb_change_bits[mb_change_index++]; @@ -697,9 +690,7 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s) /* skip (copy) four pixels, but reassign the horizontal * predictor */ - *current_pixel_pair = *prev_pixel_pair++; *vert_pred++ = *current_pixel_pair++; - *current_pixel_pair = *prev_pixel_pair++; horiz_pred = *current_pixel_pair - *vert_pred; *vert_pred++ = *current_pixel_pair++; @@ -723,7 +714,6 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s) mb_change_bits += s->mb_change_bits_row_size; current_line += s->frame.linesize[0]; - prev_line += s->prev_frame.linesize[0]; } } @@ -735,13 +725,11 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s) unsigned int horiz_pred; unsigned int *vert_pred; unsigned int *current_pixel_pair; - unsigned int *prev_pixel_pair; unsigned char *current_line = s->frame.data[0]; - unsigned char *prev_line = s->prev_frame.data[0]; int keyframe = s->flags & FLAG_KEYFRAME; /* these variables are for managing the stream of macroblock change bits */ - unsigned char *mb_change_bits = s->mb_change_bits; + const unsigned char *mb_change_bits = s->mb_change_bits; unsigned char mb_change_byte; unsigned char mb_change_byte_mask; int mb_change_index; @@ -760,7 +748,6 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s) /* re-init variables for the next line iteration */ horiz_pred = 0; current_pixel_pair = (unsigned int *)current_line; - prev_pixel_pair = (unsigned int *)prev_line; vert_pred = s->vert_pred; mb_change_index = 0; mb_change_byte = mb_change_bits[mb_change_index++]; @@ -829,9 +816,7 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s) /* skip (copy) four pixels, but reassign the horizontal * predictor */ - *current_pixel_pair = *prev_pixel_pair++; *vert_pred++ = *current_pixel_pair++; - *current_pixel_pair = *prev_pixel_pair++; horiz_pred = *current_pixel_pair - *vert_pred; *vert_pred++ = *current_pixel_pair++; @@ -855,16 +840,15 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s) mb_change_bits += s->mb_change_bits_row_size; current_line += s->frame.linesize[0]; - prev_line += s->prev_frame.linesize[0]; } } static int truemotion1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data; + TrueMotion1Context *s = avctx->priv_data; s->buf = buf; s->size = buf_size; @@ -873,28 +857,19 @@ static int truemotion1_decode_frame(AVCodecContext *avctx, return -1; s->frame.reference = 1; - if (avctx->get_buffer(avctx, &s->frame) < 0) { + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | + FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &s->frame) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } - /* check for a do-nothing frame and copy the previous frame */ - if (compression_types[s->compression].algorithm == ALGO_NOP) - { - memcpy(s->frame.data[0], s->prev_frame.data[0], - s->frame.linesize[0] * s->avctx->height); - } else if (compression_types[s->compression].algorithm == ALGO_RGB24H) { + if (compression_types[s->compression].algorithm == ALGO_RGB24H) { truemotion1_decode_24bit(s); - } else { + } else if (compression_types[s->compression].algorithm != ALGO_NOP) { truemotion1_decode_16bit(s); } - if (s->prev_frame.data[0]) - avctx->release_buffer(avctx, &s->prev_frame); - - /* shuffle frames */ - s->prev_frame = s->frame; - *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; @@ -904,11 +879,10 @@ static int truemotion1_decode_frame(AVCodecContext *avctx, static int truemotion1_decode_end(AVCodecContext *avctx) { - TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data; + TrueMotion1Context *s = avctx->priv_data; - /* release the last frame */ - if (s->prev_frame.data[0]) - avctx->release_buffer(avctx, &s->prev_frame); + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); av_free(s->vert_pred); diff --git a/contrib/ffmpeg/libavcodec/truemotion1data.h b/contrib/ffmpeg/libavcodec/truemotion1data.h index 63d307c65..e9662e3d0 100644 --- a/contrib/ffmpeg/libavcodec/truemotion1data.h +++ b/contrib/ffmpeg/libavcodec/truemotion1data.h @@ -22,8 +22,11 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef TRUEMOTION1DATA_H -#define TRUEMOTION1DATA_H +#ifndef FFMPEG_TRUEMOTION1DATA_H +#define FFMPEG_TRUEMOTION1DATA_H + +#include <stdint.h> +#include <stdlib.h> /* Y delta tables, skinny and fat */ static const int16_t ydt1[8] = { 0, -2, 2, -6, 6, -12, 12, -12 }; @@ -826,4 +829,5 @@ static const uint8_t pc_tbl4[] = { }; static const uint8_t *tables[] = { pc_tbl2, pc_tbl3, pc_tbl4 }; -#endif + +#endif /* FFMPEG_TRUEMOTION1DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/truemotion2.c b/contrib/ffmpeg/libavcodec/truemotion2.c index b282c967b..4a4ea7b41 100644 --- a/contrib/ffmpeg/libavcodec/truemotion2.c +++ b/contrib/ffmpeg/libavcodec/truemotion2.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -26,7 +25,6 @@ */ #include "avcodec.h" -#include "common.h" #include "bitstream.h" #include "dsputil.h" @@ -200,10 +198,10 @@ static inline int tm2_get_token(GetBitContext *gb, TM2Codes *code) return code->recode[val]; } -static inline int tm2_read_header(TM2Context *ctx, uint8_t *buf) +static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf) { uint32_t magic; - uint8_t *obuf; + const uint8_t *obuf; int length; obuf = buf; @@ -262,7 +260,7 @@ static int tm2_read_deltas(TM2Context *ctx, int stream_id) { return 0; } -static int tm2_read_stream(TM2Context *ctx, uint8_t *buf, int stream_id) { +static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id) { int i; int cur = 0; int skip = 0; @@ -761,7 +759,7 @@ static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p) static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { TM2Context * const l = avctx->priv_data; AVFrame * const p= (AVFrame*)&l->pic; @@ -774,7 +772,7 @@ static int decode_frame(AVCodecContext *avctx, return -1; } - l->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, buf_size >> 2); + l->dsp.bswap_buf((uint32_t*)buf, (const uint32_t*)buf, buf_size >> 2); //FIXME SERIOUS BUG skip = tm2_read_header(l, buf); if(skip == -1) diff --git a/contrib/ffmpeg/libavcodec/truespeech.c b/contrib/ffmpeg/libavcodec/truespeech.c index a03f2a0ce..9deac28be 100644 --- a/contrib/ffmpeg/libavcodec/truespeech.c +++ b/contrib/ffmpeg/libavcodec/truespeech.c @@ -57,7 +57,7 @@ static int truespeech_decode_init(AVCodecContext * avctx) return 0; } -static void truespeech_read_frame(TSContext *dec, uint8_t *input) +static void truespeech_read_frame(TSContext *dec, const uint8_t *input) { uint32_t t; @@ -329,19 +329,21 @@ static void truespeech_save_prevvec(TSContext *c) static int truespeech_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { TSContext *c = avctx->priv_data; - int i; + int i, j; short *samples = data; int consumed = 0; int16_t out_buf[240]; + int iterations; if (!buf_size) return 0; - while (consumed < buf_size) { + iterations = FFMIN(buf_size / 32, *data_size / 480); + for(j = 0; j < iterations; j++) { truespeech_read_frame(c, buf + consumed); consumed += 32; @@ -366,7 +368,7 @@ static int truespeech_decode_frame(AVCodecContext *avctx, *data_size = consumed * 15; - return buf_size; + return consumed; } AVCodec truespeech_decoder = { diff --git a/contrib/ffmpeg/libavcodec/truespeech_data.h b/contrib/ffmpeg/libavcodec/truespeech_data.h index cd8822fde..c7ca55910 100644 --- a/contrib/ffmpeg/libavcodec/truespeech_data.h +++ b/contrib/ffmpeg/libavcodec/truespeech_data.h @@ -19,8 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef __TRUESPEECH_DATA__ -#define __TRUESPEECH_DATA__ +#ifndef FFMPEG_TRUESPEECH_DATA_H +#define FFMPEG_TRUESPEECH_DATA_H + +#include <stdint.h> /* codebooks fo expanding input filter */ static const int16_t ts_cb_0[32] = { @@ -154,4 +156,4 @@ static const int16_t ts_5E2[8] = static const int16_t ts_5F2[8] = { 0x6000, 0x4800, 0x3600, 0x2880, 0x1E60, 0x16C8, 0x1116, 0x0CD1 }; -#endif +#endif /* FFMPEG_TRUESPEECH_DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/tscc.c b/contrib/ffmpeg/libavcodec/tscc.c index 1453eb568..30bb19f97 100644 --- a/contrib/ffmpeg/libavcodec/tscc.c +++ b/contrib/ffmpeg/libavcodec/tscc.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -39,7 +38,6 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" #ifdef CONFIG_ZLIB @@ -184,10 +182,10 @@ static int decode_rle(CamtasiaContext *c, unsigned int srcsize) * Decode a frame * */ -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { - CamtasiaContext * const c = (CamtasiaContext *)avctx->priv_data; - unsigned char *encoded = (unsigned char *)buf; + CamtasiaContext * const c = avctx->priv_data; + const unsigned char *encoded = buf; unsigned char *outptr; #ifdef CONFIG_ZLIB int zret; // Zlib return code @@ -257,7 +255,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 */ static int decode_init(AVCodecContext *avctx) { - CamtasiaContext * const c = (CamtasiaContext *)avctx->priv_data; + CamtasiaContext * const c = avctx->priv_data; int zret; // Zlib return code c->avctx = avctx; @@ -320,7 +318,7 @@ static int decode_init(AVCodecContext *avctx) */ static int decode_end(AVCodecContext *avctx) { - CamtasiaContext * const c = (CamtasiaContext *)avctx->priv_data; + CamtasiaContext * const c = avctx->priv_data; av_freep(&c->decomp_buf); diff --git a/contrib/ffmpeg/libavcodec/tta.c b/contrib/ffmpeg/libavcodec/tta.c index 82713fb0f..f08b12d90 100644 --- a/contrib/ffmpeg/libavcodec/tta.c +++ b/contrib/ffmpeg/libavcodec/tta.c @@ -16,7 +16,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -287,7 +287,7 @@ static int tta_decode_init(AVCodecContext * avctx) static int tta_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { TTAContext *s = avctx->priv_data; int i; diff --git a/contrib/ffmpeg/libavcodec/txd.c b/contrib/ffmpeg/libavcodec/txd.c new file mode 100644 index 000000000..13e1938bb --- /dev/null +++ b/contrib/ffmpeg/libavcodec/txd.c @@ -0,0 +1,166 @@ +/* + * Renderware TeXture Dictionary (.txd) image decoder + * Copyright (c) 2007 Ivo van Poorten + * + * See also: http://wiki.multimedia.cx/index.php?title=TXD + * + * 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" +#include "s3tc.h" + +typedef struct TXDContext { + AVFrame picture; +} TXDContext; + +static int txd_init(AVCodecContext *avctx) { + TXDContext *s = avctx->priv_data; + + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame = &s->picture; + + return 0; +} + +static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + const uint8_t *buf, int buf_size) { + TXDContext * const s = avctx->priv_data; + AVFrame *picture = data; + AVFrame * const p = &s->picture; + unsigned int version, w, h, d3d_format, depth, stride, mipmap_count, flags; + unsigned int y, v; + uint8_t *ptr; + const uint8_t *cur = buf; + const uint32_t *palette = (const uint32_t *)(cur + 88); + uint32_t *pal; + + version = AV_RL32(cur); + d3d_format = AV_RL32(cur+76); + w = AV_RL16(cur+80); + h = AV_RL16(cur+82); + depth = AV_RL8 (cur+84); + mipmap_count = AV_RL8 (cur+85); + flags = AV_RL8 (cur+87); + cur += 92; + + if (version < 8 || version > 9) { + av_log(avctx, AV_LOG_ERROR, "texture data version %i is unsupported\n", + version); + return -1; + } + + if (depth == 8) { + avctx->pix_fmt = PIX_FMT_PAL8; + cur += 1024; + } else if (depth == 16 || depth == 32) + avctx->pix_fmt = PIX_FMT_RGB32; + else { + av_log(avctx, AV_LOG_ERROR, "depth of %i is unsupported\n", depth); + return -1; + } + + if (p->data[0]) + avctx->release_buffer(avctx, p); + + 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; + } + + p->pict_type = FF_I_TYPE; + + ptr = p->data[0]; + stride = p->linesize[0]; + + if (depth == 8) { + pal = (uint32_t *) p->data[1]; + for (y=0; y<256; y++) { + v = AV_RB32(palette+y); + pal[y] = (v>>8) + (v<<24); + } + for (y=0; y<h; y++) { + memcpy(ptr, cur, w); + ptr += stride; + cur += w; + } + } else if (depth == 16) { + switch (d3d_format) { + case 0: + if (!flags&1) goto unsupported; + case FF_S3TC_DXT1: + ff_decode_dxt1(cur, ptr, w, h, stride); + break; + case FF_S3TC_DXT3: + ff_decode_dxt3(cur, ptr, w, h, stride); + break; + default: + goto unsupported; + } + } else if (depth == 32) { + switch (d3d_format) { + case 0x15: + case 0x16: + for (y=0; y<h; y++) { + memcpy(ptr, cur, w*4); + ptr += stride; + cur += w*4; + } + break; + default: + goto unsupported; + } + } + + for (; mipmap_count > 1; mipmap_count--) + cur += AV_RL32(cur) + 4; + + *picture = s->picture; + *data_size = sizeof(AVPicture); + + return cur - buf; + +unsupported: + av_log(avctx, AV_LOG_ERROR, "unsupported d3d format (%08x)\n", d3d_format); + return -1; +} + +static int txd_end(AVCodecContext *avctx) { + TXDContext *s = avctx->priv_data; + + if (s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + + return 0; +} + +AVCodec txd_decoder = { + "txd", + CODEC_TYPE_VIDEO, + CODEC_ID_TXD, + sizeof(TXDContext), + txd_init, + NULL, + txd_end, + txd_decode_frame, + 0, + NULL +}; diff --git a/contrib/ffmpeg/libavcodec/ulti.c b/contrib/ffmpeg/libavcodec/ulti.c index d84a88dad..cf0c28f1f 100644 --- a/contrib/ffmpeg/libavcodec/ulti.c +++ b/contrib/ffmpeg/libavcodec/ulti.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -30,8 +29,8 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" +#include "bytestream.h" #include "ulti_cb.h" @@ -201,7 +200,7 @@ static void ulti_grad(AVFrame *frame, int x, int y, uint8_t *Y, int chroma, int static int ulti_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { UltimotionDecodeContext *s=avctx->priv_data; int modifier = 0; @@ -306,9 +305,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, case 2: if (modifier) { // unpack four luma samples - tmp = (*buf++) << 16; - tmp += (*buf++) << 8; - tmp += *buf++; + tmp = bytestream_get_be24(&buf); Y[0] = (tmp >> 18) & 0x3F; Y[1] = (tmp >> 12) & 0x3F; @@ -316,8 +313,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, Y[3] = tmp & 0x3F; angle = 16; } else { // retrieve luma samples from codebook - tmp = (*buf++) << 8; - tmp += (*buf++); + tmp = bytestream_get_be16(&buf); angle = (tmp >> 12) & 0xF; tmp &= 0xFFF; @@ -333,33 +329,25 @@ static int ulti_decode_frame(AVCodecContext *avctx, if (modifier) { // all 16 luma samples uint8_t Luma[16]; - tmp = (*buf++) << 16; - tmp += (*buf++) << 8; - tmp += *buf++; + tmp = bytestream_get_be24(&buf); Luma[0] = (tmp >> 18) & 0x3F; Luma[1] = (tmp >> 12) & 0x3F; Luma[2] = (tmp >> 6) & 0x3F; Luma[3] = tmp & 0x3F; - tmp = (*buf++) << 16; - tmp += (*buf++) << 8; - tmp += *buf++; + tmp = bytestream_get_be24(&buf); Luma[4] = (tmp >> 18) & 0x3F; Luma[5] = (tmp >> 12) & 0x3F; Luma[6] = (tmp >> 6) & 0x3F; Luma[7] = tmp & 0x3F; - tmp = (*buf++) << 16; - tmp += (*buf++) << 8; - tmp += *buf++; + tmp = bytestream_get_be24(&buf); Luma[8] = (tmp >> 18) & 0x3F; Luma[9] = (tmp >> 12) & 0x3F; Luma[10] = (tmp >> 6) & 0x3F; Luma[11] = tmp & 0x3F; - tmp = (*buf++) << 16; - tmp += (*buf++) << 8; - tmp += *buf++; + tmp = bytestream_get_be24(&buf); Luma[12] = (tmp >> 18) & 0x3F; Luma[13] = (tmp >> 12) & 0x3F; Luma[14] = (tmp >> 6) & 0x3F; diff --git a/contrib/ffmpeg/libavcodec/ulti_cb.h b/contrib/ffmpeg/libavcodec/ulti_cb.h index 2d8c9082c..e7bd3b86b 100644 --- a/contrib/ffmpeg/libavcodec/ulti_cb.h +++ b/contrib/ffmpeg/libavcodec/ulti_cb.h @@ -19,6 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_ULTI_CB_H +#define FFMPEG_ULTI_CB_H + static const unsigned char ulti_codebook[16384]={ 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x03, @@ -4117,3 +4120,5 @@ static const unsigned char ulti_codebook[16384]={ 0x3C, 0x3D, 0x3E, 0x3F, 0x3D, 0x3E, 0x3E, 0x3F }; + +#endif /* FFMPEG_ULTI_CB_H */ diff --git a/contrib/ffmpeg/libavcodec/unary.h b/contrib/ffmpeg/libavcodec/unary.h new file mode 100644 index 000000000..abd7a531b --- /dev/null +++ b/contrib/ffmpeg/libavcodec/unary.h @@ -0,0 +1,56 @@ +/* + * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> + * + * 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 + */ + +#ifndef FFMPEG_UNARY_H +#define FFMPEG_UNARY_H + +#include "bitstream.h" + +/** + * Get unary code of limited length + * @param gb GetBitContext + * @param[in] stop The bitstop value (unary code of 1's or 0's) + * @param[in] len Maximum length + * @return Unary length/index + */ +static inline int get_unary(GetBitContext *gb, int stop, int len) +{ + int i; + + for(i = 0; i < len && get_bits1(gb) != stop; i++); + return i; +} + +/** + * Get unary code terminated by a 0 with a maximum length of 33 + * @param gb GetBitContext + * @return Unary length/index + */ +static inline int get_unary_0_33(GetBitContext *gb) +{ + return get_unary(gb, 0, 33); +} + +static inline int get_unary_0_9(GetBitContext *gb) +{ + return get_unary(gb, 0, 9); +} + +#endif /* FFMPEG_UNARY_H */ diff --git a/contrib/ffmpeg/libavcodec/utils.c b/contrib/ffmpeg/libavcodec/utils.c index 2129c9d15..d40428a28 100644 --- a/contrib/ffmpeg/libavcodec/utils.c +++ b/contrib/ffmpeg/libavcodec/utils.c @@ -31,10 +31,11 @@ #include "integer.h" #include "opt.h" #include "crc.h" +#include "imgconvert.h" #include <stdarg.h> #include <limits.h> #include <float.h> -#ifdef __MINGW32__ +#if !defined(HAVE_MKSTEMP) #include <fcntl.h> #endif @@ -126,6 +127,11 @@ static void do_free(void) /* encoder management */ AVCodec *first_avcodec = NULL; +AVCodec *av_codec_next(AVCodec *c){ + if(c) return c->next; + else return first_avcodec; +} + void register_avcodec(AVCodec *format) { AVCodec **p; @@ -147,6 +153,8 @@ typedef struct InternalBuffer{ uint8_t *base[4]; uint8_t *data[4]; int linesize[4]; + int width, height; + enum PixelFormat pix_fmt; }InternalBuffer; #define INTERNAL_BUFFER_SIZE 32 @@ -169,6 +177,7 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ case PIX_FMT_YUVJ420P: case PIX_FMT_YUVJ422P: case PIX_FMT_YUVJ444P: + case PIX_FMT_YUVA420P: w_align= 16; //FIXME check for non mpeg style codecs and use less alignment h_align= 16; break; @@ -251,12 +260,20 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE-1]).last_pic_num; //FIXME ugly hack (*picture_number)++; + if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ + for(i=0; i<4; i++){ + av_freep(&buf->base[i]); + buf->data[i]= NULL; + } + } + 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]; + int size[4] = {0}; + int tmpsize; AVPicture picture; avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift); @@ -267,28 +284,24 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ 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<<h_chroma_shift); - else - w= ALIGN(pixel_size*w, STRIDE_ALIGN<<(h_chroma_shift+3)) / pixel_size; - size[1] = avpicture_fill(&picture, NULL, s->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; + avcodec_align_dimensions(s, &w, &h); + + ff_fill_linesize(&picture, s->pix_fmt, w); + + for (i=0; i<4; i++) + picture.linesize[i] = ALIGN(picture.linesize[i], STRIDE_ALIGN); + + tmpsize = ff_fill_pointer(&picture, NULL, s->pix_fmt, h); + + for (i=0; i<3 && picture.data[i+1]; i++) + size[i] = picture.data[i+1] - picture.data[i]; + size[i] = tmpsize - (picture.data[i] - picture.data[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++){ + for(i=0; i<4 && size[i]; i++){ const int h_shift= i==0 ? 0 : h_chroma_shift; const int v_shift= i==0 ? 0 : v_chroma_shift; @@ -304,6 +317,9 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ else buf->data[i] = buf->base[i] + ALIGN((buf->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift), STRIDE_ALIGN); } + buf->width = s->width; + buf->height = s->height; + buf->pix_fmt= s->pix_fmt; pic->age= 256*256*256*64; } pic->type= FF_BUFFER_TYPE_INTERNAL; @@ -337,7 +353,7 @@ void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){ FFSWAP(InternalBuffer, *buf, *last); - for(i=0; i<3; i++){ + for(i=0; i<4; i++){ pic->data[i]=NULL; // pic->base[i]=NULL; } @@ -400,7 +416,7 @@ static const char* context_to_name(void* ptr) { } #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 +#define DEFAULT 0 //should be NAN but it does not work as it is 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 @@ -453,6 +469,18 @@ static const AVOption options[]={ {"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"}, +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) +{"me", "set motion estimation method (deprecated, use me_method instead)", OFFSET(me_method), FF_OPT_TYPE_INT, ME_EPZS, INT_MIN, INT_MAX, V|E, "me_method"}, +#endif +{"zero", "zero motion estimation (fastest)", 0, FF_OPT_TYPE_CONST, ME_ZERO, INT_MIN, INT_MAX, V|E, "me_method" }, +{"full", "full motion estimation (slowest)", 0, FF_OPT_TYPE_CONST, ME_FULL, INT_MIN, INT_MAX, V|E, "me_method" }, +{"epzs", "EPZS motion estimation (default)", 0, FF_OPT_TYPE_CONST, ME_EPZS, INT_MIN, INT_MAX, V|E, "me_method" }, +{"log", "log motion estimation", 0, FF_OPT_TYPE_CONST, ME_LOG, INT_MIN, INT_MAX, V|E, "me_method" }, +{"phods", "phods motion estimation", 0, FF_OPT_TYPE_CONST, ME_PHODS, INT_MIN, INT_MAX, V|E, "me_method" }, +{"x1", "X1 motion estimation", 0, FF_OPT_TYPE_CONST, ME_X1, INT_MIN, INT_MAX, V|E, "me_method" }, +{"hex", "hex motion estimation", 0, FF_OPT_TYPE_CONST, ME_HEX, INT_MIN, INT_MAX, V|E, "me_method" }, +{"umh", "umh motion estimation", 0, FF_OPT_TYPE_CONST, ME_UMH, INT_MIN, INT_MAX, V|E, "me_method" }, +{"iter", "iter motion estimation", 0, FF_OPT_TYPE_CONST, ME_ITER, 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}, @@ -511,7 +539,7 @@ static const AVOption options[]={ {"strict", "strictly conform to all the things in the spec no matter what consequences", 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", "allow inofficial extensions", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_INOFFICIAL, INT_MIN, INT_MAX, V|E, "strict"}, -{"experimental", "allow non standarized experimental things", 0, FF_OPT_TYPE_CONST, FF_COMPLIANCE_EXPERIMENTAL, INT_MIN, INT_MAX, V|E, "strict"}, +{"experimental", "allow non standardized experimental things", 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", "set error resilience strategy", OFFSET(error_resilience), FF_OPT_TYPE_INT, FF_ER_CAREFUL, INT_MIN, INT_MAX, A|V|D, "er"}, {"careful", NULL, 0, FF_OPT_TYPE_CONST, FF_ER_CAREFUL, INT_MIN, INT_MAX, V|D, "er"}, @@ -531,7 +559,7 @@ static const AVOption options[]={ {"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}, +{"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, A|V|E}, {"rc_buf_aggressivity", "currently useless", 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}, @@ -567,6 +595,7 @@ static const AVOption options[]={ {"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"}, +{"faani", "floating point AAN IDCT", 0, FF_OPT_TYPE_CONST, FF_IDCT_FAAN, INT_MIN, INT_MAX, V|D|E, "idct"}, {"slice_count", NULL, OFFSET(slice_count), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX}, {"ec", "set error concealment strategy", OFFSET(error_concealment), FF_OPT_TYPE_FLAGS, 3, INT_MIN, INT_MAX, V|D, "ec"}, {"guess_mvs", "iterative motion vector (MV) search (slow)", 0, FF_OPT_TYPE_CONST, FF_EC_GUESS_MVS, INT_MIN, INT_MAX, V|D, "ec"}, @@ -636,6 +665,9 @@ static const AVOption options[]={ {"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"}, +{"raw", "raw (no encoding)", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_RAW, INT_MIN, INT_MAX, V|E, "coder"}, +{"rle", "run-length coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_RLE, INT_MIN, INT_MAX, V|E, "coder"}, +{"deflate", "deflate-based coder", 0, FF_OPT_TYPE_CONST, FF_CODER_TYPE_DEFLATE, 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}, @@ -650,7 +682,7 @@ static const AVOption options[]={ {"nr", "noise reduction", OFFSET(noise_reduction), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, V|E}, {"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", 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"}, +{"flags2", NULL, OFFSET(flags2), FF_OPT_TYPE_FLAGS, CODEC_FLAG2_FASTPSKIP|CODEC_FLAG2_BIT_RESERVOIR, 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", "MP3 antialias algorithm", 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"}, @@ -667,6 +699,10 @@ static const AVOption options[]={ {"skip_bottom", "number of macroblock rows at the bottom which are skipped", 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"}, +{"aac_main", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_MAIN, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_low", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_LOW, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ssr", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_SSR, INT_MIN, INT_MAX, A|E, "profile"}, +{"aac_ltp", NULL, 0, FF_OPT_TYPE_CONST, FF_PROFILE_AAC_LTP, INT_MIN, INT_MAX, 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", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|D}, @@ -695,7 +731,7 @@ static const AVOption options[]={ {"fastpskip", "fast pskip (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_FASTPSKIP, INT_MIN, INT_MAX, V|E, "flags2"}, {"aud", "access unit delimiters (H.264)", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_AUD, INT_MIN, INT_MAX, V|E, "flags2"}, {"brdo", "b-frame rate-distortion optimization", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BRDO, INT_MIN, INT_MAX, V|E, "flags2"}, -{"skiprd", "RD optimal MB level residual skiping", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_SKIP_RD, INT_MIN, INT_MAX, V|E, "flags2"}, +{"skiprd", "RD optimal MB level residual skipping", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_SKIP_RD, INT_MIN, INT_MAX, V|E, "flags2"}, {"complexityblur", "reduce fluctuations in qp (before curve compression)", OFFSET(complexityblur), FF_OPT_TYPE_FLOAT, 20.0, FLT_MIN, FLT_MAX, V|E}, {"deblockalpha", "in-loop deblocking filter alphac0 parameter", OFFSET(deblockalpha), FF_OPT_TYPE_INT, DEFAULT, -6, 6, V|E}, {"deblockbeta", "in-loop deblocking filter beta parameter", OFFSET(deblockbeta), FF_OPT_TYPE_INT, DEFAULT, -6, 6, V|E}, @@ -720,6 +756,9 @@ static const AVOption options[]={ {"timecode_frame_start", "GOP timecode frame start number, in non drop frame format", OFFSET(timecode_frame_start), FF_OPT_TYPE_INT, 0, 0, INT_MAX, V|E}, {"drop_frame_timecode", NULL, 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_DROP_FRAME_TIMECODE, INT_MIN, INT_MAX, V|E, "flags2"}, {"non_linear_q", "use non linear quantizer", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_NON_LINEAR_QUANT, INT_MIN, INT_MAX, V|E, "flags2"}, +{"request_channels", "set desired number of audio channels", OFFSET(request_channels), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, A|D}, +{"drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), FF_OPT_TYPE_FLOAT, 1.0, 0.0, 1.0, A|D}, +{"reservoir", "use bit reservoir", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BIT_RESERVOIR, INT_MIN, INT_MAX, A|E, "flags2"}, {NULL}, }; @@ -738,6 +777,7 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum CodecType codec_type) s->av_class= &av_codec_context_class; + s->codec_type = codec_type; if(codec_type == CODEC_TYPE_AUDIO) flags= AV_OPT_FLAG_AUDIO_PARAM; else if(codec_type == CODEC_TYPE_VIDEO) @@ -795,7 +835,7 @@ AVFrame *avcodec_alloc_frame(void){ return pic; } -int avcodec_open(AVCodecContext *avctx, AVCodec *codec) +int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) { int ret= -1; @@ -805,13 +845,15 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec) goto end; } - if(avctx->codec) + if(avctx->codec || !codec) goto end; if (codec->priv_data_size > 0) { avctx->priv_data = av_mallocz(codec->priv_data_size); - if (!avctx->priv_data) + if (!avctx->priv_data) { + ret = AVERROR(ENOMEM); goto end; + } } else { avctx->priv_data = NULL; } @@ -823,6 +865,7 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec) if((avctx->coded_width||avctx->coded_height) && avcodec_check_dimensions(avctx,avctx->coded_width,avctx->coded_height)){ av_freep(&avctx->priv_data); + ret = AVERROR(EINVAL); goto end; } @@ -843,7 +886,7 @@ end: return ret; } -int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, +int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, const short *samples) { if(buf_size < FF_MIN_BUFFER_SIZE && 0){ @@ -858,7 +901,7 @@ int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, return 0; } -int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, +int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVFrame *pict) { if(buf_size < FF_MIN_BUFFER_SIZE){ @@ -886,9 +929,9 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, return ret; } -int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, +int attribute_align_arg avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { int ret; @@ -909,9 +952,9 @@ int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, return ret; } -int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, +int attribute_align_arg avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { int ret; @@ -922,8 +965,7 @@ int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, return -1; } if(*frame_size_ptr < FF_MIN_BUFFER_SIZE || - *frame_size_ptr < avctx->channels * avctx->frame_size * sizeof(int16_t) || - *frame_size_ptr < buf_size){ + *frame_size_ptr < avctx->channels * avctx->frame_size * sizeof(int16_t)){ av_log(avctx, AV_LOG_ERROR, "buffer %d too small\n", *frame_size_ptr); return -1; } @@ -941,7 +983,7 @@ int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, - uint8_t *buf, int buf_size){ + const uint8_t *buf, int buf_size){ *frame_size_ptr= AVCODEC_MAX_AUDIO_FRAME_SIZE; return avcodec_decode_audio2(avctx, samples, frame_size_ptr, buf, buf_size); } @@ -955,7 +997,7 @@ int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, *got_sub_ptr = 0; ret = avctx->codec->decode(avctx, sub, got_sub_ptr, - (uint8_t *)buf, buf_size); + buf, buf_size); if (*got_sub_ptr) avctx->frame_number++; return ret; @@ -970,6 +1012,8 @@ int avcodec_close(AVCodecContext *avctx) return -1; } + if (ENABLE_THREADS && avctx->thread_opaque) + avcodec_thread_free(avctx); if (avctx->codec->close) avctx->codec->close(avctx); avcodec_default_free_buffers(avctx); @@ -1034,6 +1078,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) char buf1[32]; char channels_str[100]; int bitrate; + AVRational display_aspect_ratio; if (encode) p = avcodec_find_encoder(enc->codec_id); @@ -1084,7 +1129,15 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %dx%d", enc->width, enc->height); - if(av_log_level >= AV_LOG_DEBUG){ + av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, + enc->width*enc->sample_aspect_ratio.num, + enc->height*enc->sample_aspect_ratio.den, + 1024*1024); + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " [PAR %d:%d DAR %d:%d]", + enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den, + display_aspect_ratio.num, display_aspect_ratio.den); + 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", @@ -1139,6 +1192,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) break; case CODEC_ID_PCM_S16LE: case CODEC_ID_PCM_S16BE: + case CODEC_ID_PCM_S16LE_PLANAR: case CODEC_ID_PCM_U16LE: case CODEC_ID_PCM_U16BE: bitrate = enc->sample_rate * enc->channels * 16; @@ -1162,6 +1216,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) snprintf(buf, buf_size, "Subtitle: %s", codec_name); bitrate = enc->bit_rate; break; + case CODEC_TYPE_ATTACHMENT: + snprintf(buf, buf_size, "Attachment: %s", codec_name); + bitrate = enc->bit_rate; + break; default: snprintf(buf, buf_size, "Invalid Codec type %d", enc->codec_type); return; @@ -1190,27 +1248,15 @@ unsigned avcodec_build( void ) return LIBAVCODEC_BUILD; } -static void init_crcs(void){ -#if LIBAVUTIL_VERSION_INT < (50<<16) - av_crc04C11DB7= av_mallocz_static(sizeof(AVCRC) * 257); - av_crc8005 = av_mallocz_static(sizeof(AVCRC) * 257); - av_crc07 = av_mallocz_static(sizeof(AVCRC) * 257); -#endif - 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); -} - void avcodec_init(void) { - static int inited = 0; + static int initialized = 0; - if (inited != 0) + if (initialized != 0) return; - inited = 1; + initialized = 1; dsputil_static_init(); - init_crcs(); } void avcodec_flush_buffers(AVCodecContext *avctx) @@ -1264,6 +1310,7 @@ int av_get_bits_per_sample(enum CodecID codec_id){ return 8; case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_S16LE: + case CODEC_ID_PCM_S16LE_PLANAR: case CODEC_ID_PCM_U16BE: case CODEC_ID_PCM_U16LE: return 16; @@ -1283,6 +1330,22 @@ int av_get_bits_per_sample(enum CodecID codec_id){ } } +int av_get_bits_per_sample_format(enum SampleFormat sample_fmt) { + switch (sample_fmt) { + case SAMPLE_FMT_U8: + return 8; + case SAMPLE_FMT_S16: + return 16; + case SAMPLE_FMT_S24: + return 24; + case SAMPLE_FMT_S32: + case SAMPLE_FMT_FLT: + return 32; + default: + return 0; + } +} + #if !defined(HAVE_THREADS) int avcodec_thread_init(AVCodecContext *s, int thread_count){ return -1; @@ -1310,7 +1373,7 @@ unsigned int av_xiphlacing(unsigned char *s, unsigned int v) * and opened file name in **filename. */ int av_tempfile(char *prefix, char **filename) { int fd=-1; -#ifdef __MINGW32__ +#if !defined(HAVE_MKSTEMP) *filename = tempnam(".", prefix); #else size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ @@ -1321,8 +1384,8 @@ int av_tempfile(char *prefix, char **filename) { 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); +#if !defined(HAVE_MKSTEMP) + fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444); #else snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); fd = mkstemp(*filename); @@ -1338,3 +1401,129 @@ int av_tempfile(char *prefix, char **filename) { } return fd; /* success */ } + +typedef struct { + const char *abbr; + int width, height; +} VideoFrameSizeAbbr; + +typedef struct { + const char *abbr; + int rate_num, rate_den; +} VideoFrameRateAbbr; + +static VideoFrameSizeAbbr video_frame_size_abbrs[] = { + { "ntsc", 720, 480 }, + { "pal", 720, 576 }, + { "qntsc", 352, 240 }, /* VCD compliant NTSC */ + { "qpal", 352, 288 }, /* VCD compliant PAL */ + { "sntsc", 640, 480 }, /* square pixel NTSC */ + { "spal", 768, 576 }, /* square pixel PAL */ + { "film", 352, 240 }, + { "ntsc-film", 352, 240 }, + { "sqcif", 128, 96 }, + { "qcif", 176, 144 }, + { "cif", 352, 288 }, + { "4cif", 704, 576 }, + { "qqvga", 160, 120 }, + { "qvga", 320, 240 }, + { "vga", 640, 480 }, + { "svga", 800, 600 }, + { "xga", 1024, 768 }, + { "uxga", 1600,1200 }, + { "qxga", 2048,1536 }, + { "sxga", 1280,1024 }, + { "qsxga", 2560,2048 }, + { "hsxga", 5120,4096 }, + { "wvga", 852, 480 }, + { "wxga", 1366, 768 }, + { "wsxga", 1600,1024 }, + { "wuxga", 1920,1200 }, + { "woxga", 2560,1600 }, + { "wqsxga", 3200,2048 }, + { "wquxga", 3840,2400 }, + { "whsxga", 6400,4096 }, + { "whuxga", 7680,4800 }, + { "cga", 320, 200 }, + { "ega", 640, 350 }, + { "hd480", 852, 480 }, + { "hd720", 1280, 720 }, + { "hd1080", 1920,1080 }, +}; + +static VideoFrameRateAbbr video_frame_rate_abbrs[]= { + { "ntsc", 30000, 1001 }, + { "pal", 25, 1 }, + { "qntsc", 30000, 1001 }, /* VCD compliant NTSC */ + { "qpal", 25, 1 }, /* VCD compliant PAL */ + { "sntsc", 30000, 1001 }, /* square pixel NTSC */ + { "spal", 25, 1 }, /* square pixel PAL */ + { "film", 24, 1 }, + { "ntsc-film", 24000, 1001 }, +}; + +int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str) +{ + int i; + int n = sizeof(video_frame_size_abbrs) / sizeof(VideoFrameSizeAbbr); + const char *p; + int frame_width = 0, frame_height = 0; + + for(i=0;i<n;i++) { + if (!strcmp(video_frame_size_abbrs[i].abbr, str)) { + frame_width = video_frame_size_abbrs[i].width; + frame_height = video_frame_size_abbrs[i].height; + break; + } + } + if (i == n) { + p = str; + frame_width = strtol(p, (char **)&p, 10); + if (*p) + p++; + frame_height = strtol(p, (char **)&p, 10); + } + if (frame_width <= 0 || frame_height <= 0) + return -1; + *width_ptr = frame_width; + *height_ptr = frame_height; + return 0; +} + +int av_parse_video_frame_rate(AVRational *frame_rate, const char *arg) +{ + int i; + int n = sizeof(video_frame_rate_abbrs) / sizeof(VideoFrameRateAbbr); + char* cp; + + /* First, we check our abbreviation table */ + for (i = 0; i < n; ++i) + if (!strcmp(video_frame_rate_abbrs[i].abbr, arg)) { + frame_rate->num = video_frame_rate_abbrs[i].rate_num; + frame_rate->den = video_frame_rate_abbrs[i].rate_den; + return 0; + } + + /* Then, we try to parse it as fraction */ + cp = strchr(arg, '/'); + if (!cp) + cp = strchr(arg, ':'); + if (cp) { + char* cpp; + frame_rate->num = strtol(arg, &cpp, 10); + if (cpp != arg || cpp == cp) + frame_rate->den = strtol(cp+1, &cpp, 10); + else + frame_rate->num = 0; + } + else { + /* Finally we give up and parse it as double */ + AVRational time_base = av_d2q(strtod(arg, 0), DEFAULT_FRAME_RATE_BASE); + frame_rate->den = time_base.den; + frame_rate->num = time_base.num; + } + if (!frame_rate->num || !frame_rate->den) + return -1; + else + return 0; +} diff --git a/contrib/ffmpeg/libavcodec/vb.c b/contrib/ffmpeg/libavcodec/vb.c new file mode 100644 index 000000000..7a2e00705 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/vb.c @@ -0,0 +1,282 @@ +/* + * Beam Software VB decoder + * Copyright (c) 2007 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 + */ + +/** + * @file vb.c + * VB Video decoder + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "avcodec.h" +#include "bytestream.h" + +enum VBFlags{ + VB_HAS_GMC = 0x01, + VB_HAS_AUDIO = 0x04, + VB_HAS_VIDEO = 0x08, + VB_HAS_PALETTE = 0x10, + VB_HAS_LENGTH = 0x20 +}; + +typedef struct VBDecContext { + AVCodecContext *avctx; + AVFrame pic; + + uint8_t *frame, *prev_frame; + uint32_t pal[256]; + const uint8_t *stream; +} VBDecContext; + +static const uint16_t vb_patterns[64] = { + 0x0660, 0xFF00, 0xCCCC, 0xF000, 0x8888, 0x000F, 0x1111, 0xFEC8, + 0x8CEF, 0x137F, 0xF731, 0xC800, 0x008C, 0x0013, 0x3100, 0xCC00, + 0x00CC, 0x0033, 0x3300, 0x0FF0, 0x6666, 0x00F0, 0x0F00, 0x2222, + 0x4444, 0xF600, 0x8CC8, 0x006F, 0x1331, 0x318C, 0xC813, 0x33CC, + 0x6600, 0x0CC0, 0x0066, 0x0330, 0xF900, 0xC88C, 0x009F, 0x3113, + 0x6000, 0x0880, 0x0006, 0x0110, 0xCC88, 0xFC00, 0x00CF, 0x88CC, + 0x003F, 0x1133, 0x3311, 0xF300, 0x6FF6, 0x0603, 0x08C6, 0x8C63, + 0xC631, 0x6310, 0xC060, 0x0136, 0x136C, 0x36C8, 0x6C80, 0x324C +}; + +static void vb_decode_palette(VBDecContext *c) +{ + int start, size, i; + + start = bytestream_get_byte(&c->stream); + size = (bytestream_get_byte(&c->stream) - 1) & 0xFF; + if(start + size > 255){ + av_log(c->avctx, AV_LOG_ERROR, "Palette change runs beyond entry 256\n"); + return; + } + for(i = start; i <= start + size; i++) + c->pal[i] = bytestream_get_be24(&c->stream); +} + +static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end) +{ + return buf >= start && buf < end; +} + +static inline int check_line(uint8_t *buf, uint8_t *start, uint8_t *end) +{ + return buf >= start && (buf + 4) <= end; +} + +static int vb_decode_framedata(VBDecContext *c, const uint8_t *buf, int offset) +{ + uint8_t *prev, *cur; + int blk, blocks, t, blk2; + int blocktypes = 0; + int x, y, a, b; + int pattype, pattern; + const int width = c->avctx->width; + uint8_t *pstart = c->prev_frame; + uint8_t *pend = c->prev_frame + width*c->avctx->height; + + prev = c->prev_frame + offset; + cur = c->frame; + + blocks = (c->avctx->width >> 2) * (c->avctx->height >> 2); + blk2 = 0; + for(blk = 0; blk < blocks; blk++){ + if(!(blk & 3)) + blocktypes = bytestream_get_byte(&buf); + switch(blocktypes & 0xC0){ + case 0x00: //skip + for(y = 0; y < 4; y++) + if(check_line(prev + y*width, pstart, pend)) + memcpy(cur + y*width, prev + y*width, 4); + else + memset(cur + y*width, 0, 4); + break; + case 0x40: + t = bytestream_get_byte(&buf); + if(!t){ //raw block + for(y = 0; y < 4; y++) + memcpy(cur + y*width, buf + y*4, 4); + buf += 16; + }else{ // motion compensation + x = ((t & 0xF)^8) - 8; + y = ((t >> 4) ^8) - 8; + t = x + y*width; + for(y = 0; y < 4; y++) + if(check_line(prev + t + y*width, pstart, pend)) + memcpy(cur + y*width, prev + t + y*width, 4); + else + memset(cur + y*width, 0, 4); + } + break; + case 0x80: // fill + t = bytestream_get_byte(&buf); + for(y = 0; y < 4; y++) + memset(cur + y*width, t, 4); + break; + case 0xC0: // pattern fill + t = bytestream_get_byte(&buf); + pattype = t >> 6; + pattern = vb_patterns[t & 0x3F]; + switch(pattype){ + case 0: + a = bytestream_get_byte(&buf); + b = bytestream_get_byte(&buf); + for(y = 0; y < 4; y++) + for(x = 0; x < 4; x++, pattern >>= 1) + cur[x + y*width] = (pattern & 1) ? b : a; + break; + case 1: + pattern = ~pattern; + case 2: + a = bytestream_get_byte(&buf); + for(y = 0; y < 4; y++) + for(x = 0; x < 4; x++, pattern >>= 1) + if(pattern & 1 && check_pixel(prev + x + y*width, pstart, pend)) + cur[x + y*width] = prev[x + y*width]; + else + cur[x + y*width] = a; + break; + case 3: + av_log(c->avctx, AV_LOG_ERROR, "Invalid opcode seen @%d\n",blk); + return -1; + } + break; + } + blocktypes <<= 2; + cur += 4; + prev += 4; + blk2++; + if(blk2 == (width >> 2)){ + blk2 = 0; + cur += width * 3; + prev += width * 3; + } + } + return 0; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) +{ + VBDecContext * const c = avctx->priv_data; + uint8_t *outptr, *srcptr; + int i, j; + int flags; + uint32_t size; + int rest = buf_size; + int offset = 0; + + c->stream = buf; + flags = bytestream_get_le16(&c->stream); + rest -= 2; + + if(flags & VB_HAS_GMC){ + i = (int16_t)bytestream_get_le16(&c->stream); + j = (int16_t)bytestream_get_le16(&c->stream); + offset = i + j * avctx->width; + rest -= 4; + } + if(flags & VB_HAS_VIDEO){ + size = bytestream_get_le32(&c->stream); + if(size > rest){ + av_log(avctx, AV_LOG_ERROR, "Frame size is too big\n"); + return -1; + } + vb_decode_framedata(c, c->stream, offset); + c->stream += size - 4; + rest -= size; + } + if(flags & VB_HAS_PALETTE){ + size = bytestream_get_le32(&c->stream); + if(size > rest){ + av_log(avctx, AV_LOG_ERROR, "Palette size is too big\n"); + return -1; + } + vb_decode_palette(c); + rest -= size; + } + + memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE); + c->pic.palette_has_changed = flags & VB_HAS_PALETTE; + + outptr = c->pic.data[0]; + srcptr = c->frame; + + for(i = 0; i < avctx->height; i++){ + memcpy(outptr, srcptr, avctx->width); + srcptr += avctx->width; + outptr += c->pic.linesize[0]; + } + + FFSWAP(uint8_t*, c->frame, c->prev_frame); + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = c->pic; + + /* always report that the buffer was completely consumed */ + return buf_size; +} + +static int decode_init(AVCodecContext *avctx) +{ + VBDecContext * const c = avctx->priv_data; + + c->avctx = avctx; + avctx->pix_fmt = PIX_FMT_PAL8; + + if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { + return -1; + } + + c->pic.reference = 1; + if(avctx->get_buffer(avctx, &c->pic) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + c->frame = av_malloc( avctx->width * avctx->height); + c->prev_frame = av_malloc( avctx->width * avctx->height); + + return 0; +} + +static int decode_end(AVCodecContext *avctx) +{ + VBDecContext *c = avctx->priv_data; + + av_freep(&c->frame); + av_freep(&c->prev_frame); + if(c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + + return 0; +} + +AVCodec vb_decoder = { + "vb", + CODEC_TYPE_VIDEO, + CODEC_ID_VB, + sizeof(VBDecContext), + decode_init, + NULL, + decode_end, + decode_frame +}; + diff --git a/contrib/ffmpeg/libavcodec/vc1.c b/contrib/ffmpeg/libavcodec/vc1.c index 84868904d..80eaca691 100644 --- a/contrib/ffmpeg/libavcodec/vc1.c +++ b/contrib/ffmpeg/libavcodec/vc1.c @@ -18,7 +18,6 @@ * 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 - * */ /** @@ -26,421 +25,24 @@ * VC-1 and WMV3 decoder * */ -#include "common.h" #include "dsputil.h" #include "avcodec.h" #include "mpegvideo.h" +#include "vc1.h" #include "vc1data.h" #include "vc1acdata.h" +#include "msmpeg4data.h" +#include "unary.h" +#include "simple_idct.h" #undef NDEBUG #include <assert.h> -extern const uint32_t ff_table0_dc_lum[120][2], ff_table1_dc_lum[120][2]; -extern const uint32_t ff_table0_dc_chroma[120][2], ff_table1_dc_chroma[120][2]; -extern VLC ff_msmp4_dc_luma_vlc[2], ff_msmp4_dc_chroma_vlc[2]; #define MB_INTRA_VLC_BITS 9 -extern VLC ff_msmp4_mb_i_vlc; -extern const uint16_t ff_msmp4_mb_i_table[64][2]; #define DC_VLC_BITS 9 #define AC_VLC_BITS 9 static const uint16_t table_mb_intra[64][2]; -/** Markers used if VC-1 AP frame data */ -//@{ -enum VC1Code{ - VC1_CODE_RES0 = 0x00000100, - VC1_CODE_ENDOFSEQ = 0x0000010A, - VC1_CODE_SLICE, - VC1_CODE_FIELD, - VC1_CODE_FRAME, - VC1_CODE_ENTRYPOINT, - VC1_CODE_SEQHDR, -}; -//@} - -/** Available Profiles */ -//@{ -enum Profile { - PROFILE_SIMPLE, - PROFILE_MAIN, - PROFILE_COMPLEX, ///< TODO: WMV9 specific - PROFILE_ADVANCED -}; -//@} - -/** Sequence quantizer mode */ -//@{ -enum QuantMode { - QUANT_FRAME_IMPLICIT, ///< Implicitly specified at frame level - QUANT_FRAME_EXPLICIT, ///< Explicitly specified at frame level - QUANT_NON_UNIFORM, ///< Non-uniform quant used for all frames - QUANT_UNIFORM ///< Uniform quant used for all frames -}; -//@} - -/** Where quant can be changed */ -//@{ -enum DQProfile { - DQPROFILE_FOUR_EDGES, - DQPROFILE_DOUBLE_EDGES, - DQPROFILE_SINGLE_EDGE, - DQPROFILE_ALL_MBS -}; -//@} - -/** @name Where quant can be changed - */ -//@{ -enum DQSingleEdge { - DQSINGLE_BEDGE_LEFT, - DQSINGLE_BEDGE_TOP, - DQSINGLE_BEDGE_RIGHT, - DQSINGLE_BEDGE_BOTTOM -}; -//@} - -/** Which pair of edges is quantized with ALTPQUANT */ -//@{ -enum DQDoubleEdge { - DQDOUBLE_BEDGE_TOPLEFT, - DQDOUBLE_BEDGE_TOPRIGHT, - DQDOUBLE_BEDGE_BOTTOMRIGHT, - DQDOUBLE_BEDGE_BOTTOMLEFT -}; -//@} - -/** MV modes for P frames */ -//@{ -enum MVModes { - MV_PMODE_1MV_HPEL_BILIN, - MV_PMODE_1MV, - MV_PMODE_1MV_HPEL, - MV_PMODE_MIXED_MV, - MV_PMODE_INTENSITY_COMP -}; -//@} - -/** @name MV types for B frames */ -//@{ -enum BMVTypes { - BMV_TYPE_BACKWARD, - BMV_TYPE_FORWARD, - BMV_TYPE_INTERPOLATED -}; -//@} - -/** @name Block types for P/B frames */ -//@{ -enum TransformTypes { - TT_8X8, - TT_8X4_BOTTOM, - TT_8X4_TOP, - TT_8X4, //Both halves - TT_4X8_RIGHT, - TT_4X8_LEFT, - TT_4X8, //Both halves - TT_4X4 -}; -//@} - -/** Table for conversion between TTBLK and TTMB */ -static const int ttblk_to_tt[3][8] = { - { TT_8X4, TT_4X8, TT_8X8, TT_4X4, TT_8X4_TOP, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT }, - { TT_8X8, TT_4X8_RIGHT, TT_4X8_LEFT, TT_4X4, TT_8X4, TT_4X8, TT_8X4_BOTTOM, TT_8X4_TOP }, - { TT_8X8, TT_4X8, TT_4X4, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT, TT_8X4, TT_8X4_TOP } -}; - -static const int ttfrm_to_tt[4] = { TT_8X8, TT_8X4, TT_4X8, TT_4X4 }; - -/** MV P mode - the 5th element is only used for mode 1 */ -static const uint8_t mv_pmode_table[2][5] = { - { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_MIXED_MV }, - { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_1MV_HPEL_BILIN } -}; -static const uint8_t mv_pmode_table2[2][4] = { - { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV }, - { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN } -}; - -/** One more frame type */ -#define BI_TYPE 7 - -static const int fps_nr[5] = { 24, 25, 30, 50, 60 }, - fps_dr[2] = { 1000, 1001 }; -static const uint8_t pquant_table[3][32] = { - { /* Implicit quantizer */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31 - }, - { /* Explicit quantizer, pquantizer uniform */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - }, - { /* Explicit quantizer, pquantizer non-uniform */ - 0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 31 - } -}; - -/** @name VC-1 VLC tables and defines - * @todo TODO move this into the context - */ -//@{ -#define VC1_BFRACTION_VLC_BITS 7 -static VLC vc1_bfraction_vlc; -#define VC1_IMODE_VLC_BITS 4 -static VLC vc1_imode_vlc; -#define VC1_NORM2_VLC_BITS 3 -static VLC vc1_norm2_vlc; -#define VC1_NORM6_VLC_BITS 9 -static VLC vc1_norm6_vlc; -/* Could be optimized, one table only needs 8 bits */ -#define VC1_TTMB_VLC_BITS 9 //12 -static VLC vc1_ttmb_vlc[3]; -#define VC1_MV_DIFF_VLC_BITS 9 //15 -static VLC vc1_mv_diff_vlc[4]; -#define VC1_CBPCY_P_VLC_BITS 9 //14 -static VLC vc1_cbpcy_p_vlc[4]; -#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6 -static VLC vc1_4mv_block_pattern_vlc[4]; -#define VC1_TTBLK_VLC_BITS 5 -static VLC vc1_ttblk_vlc[3]; -#define VC1_SUBBLKPAT_VLC_BITS 6 -static VLC vc1_subblkpat_vlc[3]; - -static VLC vc1_ac_coeff_table[8]; -//@} - -enum CodingSet { - CS_HIGH_MOT_INTRA = 0, - CS_HIGH_MOT_INTER, - CS_LOW_MOT_INTRA, - CS_LOW_MOT_INTER, - CS_MID_RATE_INTRA, - CS_MID_RATE_INTER, - CS_HIGH_RATE_INTRA, - CS_HIGH_RATE_INTER -}; - -/** @name Overlap conditions for Advanced Profile */ -//@{ -enum COTypes { - CONDOVER_NONE = 0, - CONDOVER_ALL, - CONDOVER_SELECT -}; -//@} - - -/** The VC1 Context - * @fixme Change size wherever another size is more efficient - * Many members are only used for Advanced Profile - */ -typedef struct VC1Context{ - MpegEncContext s; - - int bits; - - /** Simple/Main Profile sequence header */ - //@{ - int res_sm; ///< reserved, 2b - int res_x8; ///< reserved - int multires; ///< frame-level RESPIC syntax element present - int res_fasttx; ///< reserved, always 1 - int res_transtab; ///< reserved, always 0 - int rangered; ///< RANGEREDFRM (range reduction) syntax element present - ///< at frame level - int res_rtm_flag; ///< reserved, set to 1 - int reserved; ///< reserved - //@} - - /** Advanced Profile */ - //@{ - int level; ///< 3bits, for Advanced/Simple Profile, provided by TS layer - int chromaformat; ///< 2bits, 2=4:2:0, only defined - int postprocflag; ///< Per-frame processing suggestion flag present - int broadcast; ///< TFF/RFF present - int interlace; ///< Progressive/interlaced (RPTFTM syntax element) - int tfcntrflag; ///< TFCNTR present - int panscanflag; ///< NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present - int extended_dmv; ///< Additional extended dmv range at P/B frame-level - int color_prim; ///< 8bits, chroma coordinates of the color primaries - int transfer_char; ///< 8bits, Opto-electronic transfer characteristics - int matrix_coef; ///< 8bits, Color primaries->YCbCr transform matrix - int hrd_param_flag; ///< Presence of Hypothetical Reference - ///< Decoder parameters - int psf; ///< Progressive Segmented Frame - //@} - - /** Sequence header data for all Profiles - * TODO: choose between ints, uint8_ts and monobit flags - */ - //@{ - int profile; ///< 2bits, Profile - int frmrtq_postproc; ///< 3bits, - int bitrtq_postproc; ///< 5bits, quantized framerate-based postprocessing strength - int fastuvmc; ///< Rounding of qpel vector to hpel ? (not in Simple) - int extended_mv; ///< Ext MV in P/B (not in Simple) - int dquant; ///< How qscale varies with MBs, 2bits (not in Simple) - int vstransform; ///< variable-size [48]x[48] transform type + info - int overlap; ///< overlapped transforms in use - int quantizer_mode; ///< 2bits, quantizer mode used for sequence, see QUANT_* - int finterpflag; ///< INTERPFRM present - //@} - - /** Frame decoding info for all profiles */ - //@{ - uint8_t mv_mode; ///< MV coding monde - uint8_t mv_mode2; ///< Secondary MV coding mode (B frames) - int k_x; ///< Number of bits for MVs (depends on MV range) - int k_y; ///< Number of bits for MVs (depends on MV range) - int range_x, range_y; ///< MV range - uint8_t pq, altpq; ///< Current/alternate frame quantizer scale - /** pquant parameters */ - //@{ - uint8_t dquantfrm; - uint8_t dqprofile; - uint8_t dqsbedge; - uint8_t dqbilevel; - //@} - /** AC coding set indexes - * @see 8.1.1.10, p(1)10 - */ - //@{ - int c_ac_table_index; ///< Chroma index from ACFRM element - int y_ac_table_index; ///< Luma index from AC2FRM element - //@} - int ttfrm; ///< Transform type info present at frame level - uint8_t ttmbf; ///< Transform type flag - uint8_t ttblk4x4; ///< Value of ttblk which indicates a 4x4 transform - int codingset; ///< index of current table set from 11.8 to use for luma block decoding - int codingset2; ///< index of current table set from 11.8 to use for chroma block decoding - int pqindex; ///< raw pqindex used in coding set selection - int a_avail, c_avail; - uint8_t *mb_type_base, *mb_type[3]; - - - /** Luma compensation parameters */ - //@{ - uint8_t lumscale; - uint8_t lumshift; - //@} - int16_t bfraction; ///< Relative position % anchors=> how to scale MVs - uint8_t halfpq; ///< Uniform quant over image and qp+.5 - uint8_t respic; ///< Frame-level flag for resized images - int buffer_fullness; ///< HRD info - /** Ranges: - * -# 0 -> [-64n 63.f] x [-32, 31.f] - * -# 1 -> [-128, 127.f] x [-64, 63.f] - * -# 2 -> [-512, 511.f] x [-128, 127.f] - * -# 3 -> [-1024, 1023.f] x [-256, 255.f] - */ - uint8_t mvrange; - uint8_t pquantizer; ///< Uniform (over sequence) quantizer in use - VLC *cbpcy_vlc; ///< CBPCY VLC table - int tt_index; ///< Index for Transform Type tables - uint8_t* mv_type_mb_plane; ///< bitplane for mv_type == (4MV) - uint8_t* direct_mb_plane; ///< bitplane for "direct" MBs - int mv_type_is_raw; ///< mv type mb plane is not coded - int dmb_is_raw; ///< direct mb plane is raw - int skip_is_raw; ///< skip mb plane is not coded - uint8_t luty[256], lutuv[256]; // lookup tables used for intensity compensation - int use_ic; ///< use intensity compensation in B-frames - int rnd; ///< rounding control - - /** Frame decoding info for S/M profiles only */ - //@{ - uint8_t rangeredfrm; ///< out_sample = CLIP((in_sample-128)*2+128) - uint8_t interpfrm; - //@} - - /** Frame decoding info for Advanced profile */ - //@{ - uint8_t fcm; ///< 0->Progressive, 2->Frame-Interlace, 3->Field-Interlace - uint8_t numpanscanwin; - uint8_t tfcntr; - uint8_t rptfrm, tff, rff; - uint16_t topleftx; - uint16_t toplefty; - uint16_t bottomrightx; - uint16_t bottomrighty; - uint8_t uvsamp; - uint8_t postproc; - int hrd_num_leaky_buckets; - uint8_t bit_rate_exponent; - uint8_t buffer_size_exponent; - uint8_t* acpred_plane; ///< AC prediction flags bitplane - int acpred_is_raw; - uint8_t* over_flags_plane; ///< Overflags bitplane - int overflg_is_raw; - uint8_t condover; - uint16_t *hrd_rate, *hrd_buffer; - uint8_t *hrd_fullness; - uint8_t range_mapy_flag; - uint8_t range_mapuv_flag; - uint8_t range_mapy; - uint8_t range_mapuv; - //@} - - int p_frame_skipped; - int bi_type; -} VC1Context; - -/** - * Get unary code of limited length - * @fixme FIXME Slow and ugly - * @param gb GetBitContext - * @param[in] stop The bitstop value (unary code of 1's or 0's) - * @param[in] len Maximum length - * @return Unary length/index - */ -static int get_prefix(GetBitContext *gb, int stop, int len) -{ -#if 1 - int i; - - for(i = 0; i < len && get_bits1(gb) != stop; i++); - return i; -/* int i = 0, tmp = !stop; - - while (i != len && tmp != stop) - { - tmp = get_bits(gb, 1); - i++; - } - if (i == len && tmp != stop) return len+1; - return i;*/ -#else - unsigned int buf; - int log; - - OPEN_READER(re, gb); - UPDATE_CACHE(re, gb); - buf=GET_CACHE(re, gb); //Still not sure - if (stop) buf = ~buf; - - log= av_log2(-buf); //FIXME: -? - if (log < limit){ - LAST_SKIP_BITS(re, gb, log+1); - CLOSE_READER(re, gb); - return log; - } - - LAST_SKIP_BITS(re, gb, limit); - CLOSE_READER(re, gb); - return limit; -#endif -} - -static inline int decode210(GetBitContext *gb){ - int n; - n = get_bits1(gb); - if (n == 1) - return 0; - else - return 2 - get_bits1(gb); -} /** * Init VC-1 specific tables and VC1Context members @@ -458,44 +60,44 @@ static int vc1_init_common(VC1Context *v) if(!done) { done = 1; - init_vlc(&vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23, - vc1_bfraction_bits, 1, 1, - vc1_bfraction_codes, 1, 1, 1); - init_vlc(&vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4, - vc1_norm2_bits, 1, 1, - vc1_norm2_codes, 1, 1, 1); - init_vlc(&vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64, - vc1_norm6_bits, 1, 1, - vc1_norm6_codes, 2, 2, 1); - init_vlc(&vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7, - vc1_imode_bits, 1, 1, - vc1_imode_codes, 1, 1, 1); + init_vlc(&ff_vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23, + ff_vc1_bfraction_bits, 1, 1, + ff_vc1_bfraction_codes, 1, 1, 1); + init_vlc(&ff_vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4, + ff_vc1_norm2_bits, 1, 1, + ff_vc1_norm2_codes, 1, 1, 1); + init_vlc(&ff_vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64, + ff_vc1_norm6_bits, 1, 1, + ff_vc1_norm6_codes, 2, 2, 1); + init_vlc(&ff_vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7, + ff_vc1_imode_bits, 1, 1, + ff_vc1_imode_codes, 1, 1, 1); for (i=0; i<3; i++) { - init_vlc(&vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16, - vc1_ttmb_bits[i], 1, 1, - vc1_ttmb_codes[i], 2, 2, 1); - init_vlc(&vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8, - vc1_ttblk_bits[i], 1, 1, - vc1_ttblk_codes[i], 1, 1, 1); - init_vlc(&vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15, - vc1_subblkpat_bits[i], 1, 1, - vc1_subblkpat_codes[i], 1, 1, 1); + init_vlc(&ff_vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16, + ff_vc1_ttmb_bits[i], 1, 1, + ff_vc1_ttmb_codes[i], 2, 2, 1); + init_vlc(&ff_vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8, + ff_vc1_ttblk_bits[i], 1, 1, + ff_vc1_ttblk_codes[i], 1, 1, 1); + init_vlc(&ff_vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15, + ff_vc1_subblkpat_bits[i], 1, 1, + ff_vc1_subblkpat_codes[i], 1, 1, 1); } for(i=0; i<4; i++) { - init_vlc(&vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16, - vc1_4mv_block_pattern_bits[i], 1, 1, - vc1_4mv_block_pattern_codes[i], 1, 1, 1); - init_vlc(&vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64, - vc1_cbpcy_p_bits[i], 1, 1, - vc1_cbpcy_p_codes[i], 2, 2, 1); - init_vlc(&vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73, - vc1_mv_diff_bits[i], 1, 1, - vc1_mv_diff_codes[i], 2, 2, 1); + init_vlc(&ff_vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16, + ff_vc1_4mv_block_pattern_bits[i], 1, 1, + ff_vc1_4mv_block_pattern_codes[i], 1, 1, 1); + init_vlc(&ff_vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64, + ff_vc1_cbpcy_p_bits[i], 1, 1, + ff_vc1_cbpcy_p_codes[i], 2, 2, 1); + init_vlc(&ff_vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73, + ff_vc1_mv_diff_bits[i], 1, 1, + ff_vc1_mv_diff_codes[i], 2, 2, 1); } for(i=0; i<8; i++) - init_vlc(&vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i], + init_vlc(&ff_vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i], &vc1_ac_tables[i][0][1], 8, 4, &vc1_ac_tables[i][0][0], 8, 4, 1); init_vlc(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64, @@ -542,11 +144,11 @@ static void decode_rowskip(uint8_t* plane, int width, int height, int stride, Ge int x, y; for (y=0; y<height; y++){ - if (!get_bits(gb, 1)) //rowskip + if (!get_bits1(gb)) //rowskip memset(plane, 0, width); else for (x=0; x<width; x++) - plane[x] = get_bits(gb, 1); + plane[x] = get_bits1(gb); plane += stride; } } @@ -556,18 +158,18 @@ static void decode_rowskip(uint8_t* plane, int width, int height, int stride, Ge * @param[in] width Width of this buffer * @param[in] height Height of this buffer * @param[in] stride of this buffer - * @fixme FIXME: Optimize + * @todo FIXME: Optimize */ static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){ int x, y; for (x=0; x<width; x++){ - if (!get_bits(gb, 1)) //colskip + if (!get_bits1(gb)) //colskip for (y=0; y<height; y++) plane[y*stride] = 0; else for (y=0; y<height; y++) - plane[y*stride] = get_bits(gb, 1); + plane[y*stride] = get_bits1(gb); plane ++; } } @@ -576,7 +178,7 @@ static void decode_colskip(uint8_t* plane, int width, int height, int stride, Ge * @param bp Bitplane where to store the decode bits * @param v VC-1 context for bit reading and logging * @return Status - * @fixme FIXME: Optimize + * @todo FIXME: Optimize */ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) { @@ -589,8 +191,8 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) width = v->s.mb_width; height = v->s.mb_height; stride = v->s.mb_stride; - invert = get_bits(gb, 1); - imode = get_vlc2(gb, vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1); + invert = get_bits1(gb); + imode = get_vlc2(gb, ff_vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1); *raw_flag = 0; switch (imode) @@ -603,13 +205,13 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) case IMODE_NORM2: if ((height * width) & 1) { - *planep++ = get_bits(gb, 1); + *planep++ = get_bits1(gb); offset = 1; } else offset = 0; // decode bitplane as one long line for (y = offset; y < height * width; y += 2) { - code = get_vlc2(gb, vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1); + code = get_vlc2(gb, ff_vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1); *planep++ = code & 1; offset++; if(offset == width) { @@ -629,7 +231,7 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) if(!(height % 3) && (width % 3)) { // use 2x3 decoding for(y = 0; y < height; y+= 3) { for(x = width & 1; x < width; x += 2) { - code = get_vlc2(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); + code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); if(code < 0){ av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n"); return -1; @@ -648,7 +250,7 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v) planep += (height & 1) * stride; for(y = height & 1; y < height; y += 2) { for(x = width % 3; x < width; x += 3) { - code = get_vlc2(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); + code = get_vlc2(gb, ff_vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2); if(code < 0){ av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n"); return -1; @@ -722,7 +324,7 @@ static int vop_dquant_decoding(VC1Context *v) } else { - v->dquantfrm = get_bits(gb, 1); + v->dquantfrm = get_bits1(gb); if ( v->dquantfrm ) { v->dqprofile = get_bits(gb, 2); @@ -733,7 +335,9 @@ static int vop_dquant_decoding(VC1Context *v) v->dqsbedge = get_bits(gb, 2); break; case DQPROFILE_ALL_MBS: - v->dqbilevel = get_bits(gb, 1); + v->dqbilevel = get_bits1(gb); + if(!v->dqbilevel) + v->halfpq = 0; default: break; //Forbidden ? } if (v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS) @@ -1173,10 +777,14 @@ static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb) if (v->profile == PROFILE_ADVANCED) { + v->zz_8x4 = ff_vc1_adv_progressive_8x4_zz; + v->zz_4x8 = ff_vc1_adv_progressive_4x8_zz; return decode_sequence_header_adv(v, gb); } else { + v->zz_8x4 = ff_vc1_simple_progressive_8x4_zz; + v->zz_4x8 = ff_vc1_simple_progressive_4x8_zz; v->res_sm = get_bits(gb, 2); //reserved if (v->res_sm) { @@ -1190,37 +798,32 @@ static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb) v->frmrtq_postproc = get_bits(gb, 3); //common // (bitrate-32kbps)/64kbps v->bitrtq_postproc = get_bits(gb, 5); //common - v->s.loop_filter = get_bits(gb, 1); //common + v->s.loop_filter = get_bits1(gb); //common if(v->s.loop_filter == 1 && v->profile == PROFILE_SIMPLE) { av_log(avctx, AV_LOG_ERROR, "LOOPFILTER shell not be enabled in simple profile\n"); } - v->res_x8 = get_bits(gb, 1); //reserved - if (v->res_x8) - { - av_log(avctx, AV_LOG_ERROR, - "1 for reserved RES_X8 is forbidden\n"); - //return -1; - } - v->multires = get_bits(gb, 1); - v->res_fasttx = get_bits(gb, 1); + v->res_x8 = get_bits1(gb); //reserved + v->multires = get_bits1(gb); + v->res_fasttx = get_bits1(gb); if (!v->res_fasttx) { - av_log(avctx, AV_LOG_ERROR, - "0 for reserved RES_FASTTX is forbidden\n"); - //return -1; + v->s.dsp.vc1_inv_trans_8x8 = ff_simple_idct; + v->s.dsp.vc1_inv_trans_8x4 = ff_simple_idct84_add; + v->s.dsp.vc1_inv_trans_4x8 = ff_simple_idct48_add; + v->s.dsp.vc1_inv_trans_4x4 = ff_simple_idct44_add; } - v->fastuvmc = get_bits(gb, 1); //common + v->fastuvmc = get_bits1(gb); //common if (!v->profile && !v->fastuvmc) { av_log(avctx, AV_LOG_ERROR, "FASTUVMC unavailable in Simple Profile\n"); return -1; } - v->extended_mv = get_bits(gb, 1); //common + v->extended_mv = get_bits1(gb); //common if (!v->profile && v->extended_mv) { av_log(avctx, AV_LOG_ERROR, @@ -1228,9 +831,9 @@ static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb) return -1; } v->dquant = get_bits(gb, 2); //common - v->vstransform = get_bits(gb, 1); //common + v->vstransform = get_bits1(gb); //common - v->res_transtab = get_bits(gb, 1); + v->res_transtab = get_bits1(gb); if (v->res_transtab) { av_log(avctx, AV_LOG_ERROR, @@ -1238,10 +841,10 @@ static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb) return -1; } - v->overlap = get_bits(gb, 1); //common + v->overlap = get_bits1(gb); //common - v->s.resync_marker = get_bits(gb, 1); - v->rangered = get_bits(gb, 1); + v->s.resync_marker = get_bits1(gb); + v->rangered = get_bits1(gb); if (v->rangered && v->profile == PROFILE_SIMPLE) { av_log(avctx, AV_LOG_INFO, @@ -1251,8 +854,8 @@ static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb) v->s.max_b_frames = avctx->max_b_frames = get_bits(gb, 3); //common v->quantizer_mode = get_bits(gb, 2); //common - v->finterpflag = get_bits(gb, 1); //common - v->res_rtm_flag = get_bits(gb, 1); //reserved + v->finterpflag = get_bits1(gb); //common + v->res_rtm_flag = get_bits1(gb); //reserved if (!v->res_rtm_flag) { // av_log(avctx, AV_LOG_ERROR, @@ -1296,7 +899,7 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) v->frmrtq_postproc = get_bits(gb, 3); //common // (bitrate-32kbps)/64kbps v->bitrtq_postproc = get_bits(gb, 5); //common - v->postprocflag = get_bits(gb, 1); //common + v->postprocflag = get_bits1(gb); //common v->s.avctx->coded_width = (get_bits(gb, 12) + 1) << 1; v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1; @@ -1306,7 +909,7 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) v->interlace = get_bits1(gb); v->tfcntrflag = get_bits1(gb); v->finterpflag = get_bits1(gb); - get_bits1(gb); // reserved + skip_bits1(gb); // reserved v->s.h_edge_pos = v->s.avctx->coded_width; v->s.v_edge_pos = v->s.avctx->coded_height; @@ -1335,7 +938,7 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) if(get_bits1(gb)) ar = get_bits(gb, 4); if(ar && ar < 14){ - v->s.avctx->sample_aspect_ratio = vc1_pixel_aspect[ar]; + v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar]; }else if(ar == 15){ w = get_bits(gb, 8); h = get_bits(gb, 8); @@ -1351,8 +954,8 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) nr = get_bits(gb, 8); dr = get_bits(gb, 4); if(nr && nr < 8 && dr && dr < 3){ - v->s.avctx->time_base.num = fps_dr[dr - 1]; - v->s.avctx->time_base.den = fps_nr[nr - 1] * 1000; + v->s.avctx->time_base.num = ff_vc1_fps_dr[dr - 1]; + v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000; } } } @@ -1368,11 +971,11 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) if(v->hrd_param_flag) { int i; v->hrd_num_leaky_buckets = get_bits(gb, 5); - get_bits(gb, 4); //bitrate exponent - get_bits(gb, 4); //buffer size exponent + skip_bits(gb, 4); //bitrate exponent + skip_bits(gb, 4); //buffer size exponent for(i = 0; i < v->hrd_num_leaky_buckets; i++) { - get_bits(gb, 16); //hrd_rate[n] - get_bits(gb, 16); //hrd_buffer[n] + skip_bits(gb, 16); //hrd_rate[n] + skip_bits(gb, 16); //hrd_buffer[n] } } return 0; @@ -1398,7 +1001,7 @@ static int decode_entry_point(AVCodecContext *avctx, GetBitContext *gb) if(v->hrd_param_flag){ for(i = 0; i < v->hrd_num_leaky_buckets; i++) { - get_bits(gb, 8); //hrd_full[n] + skip_bits(gb, 8); //hrd_full[n] } } @@ -1431,28 +1034,28 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant, status; - if(v->finterpflag) v->interpfrm = get_bits(gb, 1); + if(v->finterpflag) v->interpfrm = get_bits1(gb); skip_bits(gb, 2); //framecnt unused v->rangeredfrm = 0; - if (v->rangered) v->rangeredfrm = get_bits(gb, 1); - v->s.pict_type = get_bits(gb, 1); + if (v->rangered) v->rangeredfrm = get_bits1(gb); + v->s.pict_type = get_bits1(gb); if (v->s.avctx->max_b_frames) { if (!v->s.pict_type) { - if (get_bits(gb, 1)) v->s.pict_type = I_TYPE; + if (get_bits1(gb)) v->s.pict_type = I_TYPE; else v->s.pict_type = B_TYPE; } else v->s.pict_type = P_TYPE; } else v->s.pict_type = v->s.pict_type ? P_TYPE : I_TYPE; v->bi_type = 0; if(v->s.pict_type == B_TYPE) { - v->bfraction = get_vlc2(gb, vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = vc1_bfraction_lut[v->bfraction]; + v->bfraction = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); + v->bfraction = ff_vc1_bfraction_lut[v->bfraction]; if(v->bfraction == 0) { v->s.pict_type = BI_TYPE; } } if(v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE) - get_bits(gb, 7); // skip buffer fullness + skip_bits(gb, 7); // skip buffer fullness /* calculate RND */ if(v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE) @@ -1462,10 +1065,11 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) /* Quantizer stuff */ pqindex = get_bits(gb, 5); + if(!pqindex) return -1; if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) - v->pq = pquant_table[0][pqindex]; + v->pq = ff_vc1_pquant_table[0][pqindex]; else - v->pq = pquant_table[1][pqindex]; + v->pq = ff_vc1_pquant_table[1][pqindex]; v->pquantizer = 1; if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) @@ -1473,26 +1077,26 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) if (v->quantizer_mode == QUANT_NON_UNIFORM) v->pquantizer = 0; v->pqindex = pqindex; - if (pqindex < 9) v->halfpq = get_bits(gb, 1); + if (pqindex < 9) v->halfpq = get_bits1(gb); else v->halfpq = 0; if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) - v->pquantizer = get_bits(gb, 1); + v->pquantizer = get_bits1(gb); v->dquantfrm = 0; - if (v->extended_mv == 1) v->mvrange = get_prefix(gb, 0, 3); + if (v->extended_mv == 1) v->mvrange = get_unary(gb, 0, 3); v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 v->range_x = 1 << (v->k_x - 1); v->range_y = 1 << (v->k_y - 1); if (v->profile == PROFILE_ADVANCED) { - if (v->postprocflag) v->postproc = get_bits(gb, 1); + if (v->postprocflag) v->postproc = get_bits1(gb); } else if (v->multires && v->s.pict_type != B_TYPE) v->respic = get_bits(gb, 2); if(v->res_x8 && (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)){ - if(get_bits1(gb))return -1; - } + v->x8_type = get_bits1(gb); + }else v->x8_type = 0; //av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n", // (v->s.pict_type == P_TYPE) ? 'P' : ((v->s.pict_type == I_TYPE) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm); @@ -1505,11 +1109,11 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) else v->tt_index = 2; lowquant = (v->pq > 12) ? 0 : 1; - v->mv_mode = mv_pmode_table[lowquant][get_prefix(gb, 1, 4)]; + v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)]; if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { int scale, shift, i; - v->mv_mode2 = mv_pmode_table2[lowquant][get_prefix(gb, 1, 3)]; + v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)]; v->lumscale = get_bits(gb, 6); v->lumshift = get_bits(gb, 6); v->use_ic = 1; @@ -1560,8 +1164,8 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) "Imode: %i, Invert: %i\n", status>>1, status&1); /* Hopefully this is correct for P frames */ - v->s.mv_table_index = get_bits(gb, 2); //but using vc1_ tables - v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; if (v->dquant) { @@ -1572,10 +1176,10 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) v->ttfrm = 0; //FIXME Is that so ? if (v->vstransform) { - v->ttmbf = get_bits(gb, 1); + v->ttmbf = get_bits1(gb); if (v->ttmbf) { - v->ttfrm = ttfrm_to_tt[get_bits(gb, 2)]; + v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; } } else { v->ttmbf = 1; @@ -1602,7 +1206,7 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) "Imode: %i, Invert: %i\n", status>>1, status&1); v->s.mv_table_index = get_bits(gb, 2); - v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; if (v->dquant) { @@ -1613,10 +1217,10 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) v->ttfrm = 0; if (v->vstransform) { - v->ttmbf = get_bits(gb, 1); + v->ttmbf = get_bits1(gb); if (v->ttmbf) { - v->ttfrm = ttfrm_to_tt[get_bits(gb, 2)]; + v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; } } else { v->ttmbf = 1; @@ -1625,14 +1229,17 @@ static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) break; } - /* AC Syntax */ - v->c_ac_table_index = decode012(gb); - if (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE) + if(!v->x8_type) { - v->y_ac_table_index = decode012(gb); + /* AC Syntax */ + v->c_ac_table_index = decode012(gb); + if (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE) + { + v->y_ac_table_index = decode012(gb); + } + /* DC Syntax */ + v->s.dc_table_index = get_bits1(gb); } - /* DC Syntax */ - v->s.dc_table_index = get_bits(gb, 1); if(v->s.pict_type == BI_TYPE) { v->s.pict_type = B_TYPE; @@ -1652,7 +1259,7 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->fcm = decode012(gb); if(v->fcm) return -1; // interlaced frames/fields are not implemented } - switch(get_prefix(gb, 0, 4)) { + switch(get_unary(gb, 0, 4)) { case 0: v->s.pict_type = P_TYPE; break; @@ -1671,7 +1278,7 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) return 0; } if(v->tfcntrflag) - get_bits(gb, 8); + skip_bits(gb, 8); if(v->broadcast) { if(!v->interlace || v->psf) { v->rptfrm = get_bits(gb, 2); @@ -1686,20 +1293,21 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->rnd = get_bits1(gb); if(v->interlace) v->uvsamp = get_bits1(gb); - if(v->finterpflag) v->interpfrm = get_bits(gb, 1); + if(v->finterpflag) v->interpfrm = get_bits1(gb); if(v->s.pict_type == B_TYPE) { - v->bfraction = get_vlc2(gb, vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = vc1_bfraction_lut[v->bfraction]; + v->bfraction = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); + v->bfraction = ff_vc1_bfraction_lut[v->bfraction]; if(v->bfraction == 0) { v->s.pict_type = BI_TYPE; /* XXX: should not happen here */ } } pqindex = get_bits(gb, 5); + if(!pqindex) return -1; v->pqindex = pqindex; if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) - v->pq = pquant_table[0][pqindex]; + v->pq = ff_vc1_pquant_table[0][pqindex]; else - v->pq = pquant_table[1][pqindex]; + v->pq = ff_vc1_pquant_table[1][pqindex]; v->pquantizer = 1; if (v->quantizer_mode == QUANT_FRAME_IMPLICIT) @@ -1707,10 +1315,10 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->quantizer_mode == QUANT_NON_UNIFORM) v->pquantizer = 0; v->pqindex = pqindex; - if (pqindex < 9) v->halfpq = get_bits(gb, 1); + if (pqindex < 9) v->halfpq = get_bits1(gb); else v->halfpq = 0; if (v->quantizer_mode == QUANT_FRAME_EXPLICIT) - v->pquantizer = get_bits(gb, 1); + v->pquantizer = get_bits1(gb); if(v->s.pict_type == I_TYPE || v->s.pict_type == P_TYPE) v->use_ic = 0; @@ -1735,7 +1343,7 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) case P_TYPE: if(v->postprocflag) v->postproc = get_bits1(gb); - if (v->extended_mv) v->mvrange = get_prefix(gb, 0, 3); + if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3); else v->mvrange = 0; v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 @@ -1747,11 +1355,11 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) else v->tt_index = 2; lowquant = (v->pq > 12) ? 0 : 1; - v->mv_mode = mv_pmode_table[lowquant][get_prefix(gb, 1, 4)]; + v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)]; if (v->mv_mode == MV_PMODE_INTENSITY_COMP) { int scale, shift, i; - v->mv_mode2 = mv_pmode_table2[lowquant][get_prefix(gb, 1, 3)]; + v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)]; v->lumscale = get_bits(gb, 6); v->lumshift = get_bits(gb, 6); /* fill lookup tables for intensity compensation */ @@ -1802,8 +1410,8 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) "Imode: %i, Invert: %i\n", status>>1, status&1); /* Hopefully this is correct for P frames */ - v->s.mv_table_index = get_bits(gb, 2); //but using vc1_ tables - v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; if (v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); @@ -1813,10 +1421,10 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->ttfrm = 0; //FIXME Is that so ? if (v->vstransform) { - v->ttmbf = get_bits(gb, 1); + v->ttmbf = get_bits1(gb); if (v->ttmbf) { - v->ttfrm = ttfrm_to_tt[get_bits(gb, 2)]; + v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; } } else { v->ttmbf = 1; @@ -1826,7 +1434,7 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) case B_TYPE: if(v->postprocflag) v->postproc = get_bits1(gb); - if (v->extended_mv) v->mvrange = get_prefix(gb, 0, 3); + if (v->extended_mv) v->mvrange = get_unary(gb, 0, 3); else v->mvrange = 0; v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13 v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11 @@ -1852,7 +1460,7 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) "Imode: %i, Invert: %i\n", status>>1, status&1); v->s.mv_table_index = get_bits(gb, 2); - v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)]; + v->cbpcy_vlc = &ff_vc1_cbpcy_p_vlc[get_bits(gb, 2)]; if (v->dquant) { @@ -1863,10 +1471,10 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->ttfrm = 0; if (v->vstransform) { - v->ttmbf = get_bits(gb, 1); + v->ttmbf = get_bits1(gb); if (v->ttmbf) { - v->ttfrm = ttfrm_to_tt[get_bits(gb, 2)]; + v->ttfrm = ff_vc1_ttfrm_to_tt[get_bits(gb, 2)]; } } else { v->ttmbf = 1; @@ -1882,7 +1490,7 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->y_ac_table_index = decode012(gb); } /* DC Syntax */ - v->s.dc_table_index = get_bits(gb, 1); + v->s.dc_table_index = get_bits1(gb); if ((v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE) && v->dquant) { av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n"); vop_dquant_decoding(v); @@ -1915,7 +1523,7 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) { \ if (v->dqbilevel) \ { \ - mquant = (get_bits(gb, 1)) ? v->altpq : v->pq; \ + mquant = (get_bits1(gb)) ? v->altpq : v->pq; \ } \ else \ { \ @@ -1948,7 +1556,7 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) * @param _dmv_y Vertical differential for decoded MV */ #define GET_MVDATA(_dmv_x, _dmv_y) \ - index = 1 + get_vlc2(gb, vc1_mv_diff_vlc[s->mv_table_index].table,\ + index = 1 + get_vlc2(gb, ff_vc1_mv_diff_vlc[s->mv_table_index].table,\ VC1_MV_DIFF_VLC_BITS, 2); \ if (index > 36) \ { \ @@ -2304,6 +1912,12 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample); s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample); s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample); + + /* Pullback predicted motion vectors as specified in 8.4.5.4 */ + s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6)); + s->mv[0][0][1] = av_clip(s->mv[0][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6)); + s->mv[1][0][0] = av_clip(s->mv[1][0][0], -60 - (s->mb_x << 6), (s->mb_width << 6) - 4 - (s->mb_x << 6)); + s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6)); if(direct) { s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0]; s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1]; @@ -2318,6 +1932,7 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; B = s->current_picture.motion_val[0][xy - wrap*2 + off]; + if(!s->mb_x) C[0] = C[1] = 0; if(!s->first_slice_line) { // predictor A is not out of bounds if(s->mb_width == 1) { px = A[0]; @@ -2395,6 +2010,7 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2], int off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2; B = s->current_picture.motion_val[1][xy - wrap*2 + off]; + if(!s->mb_x) C[0] = C[1] = 0; if(!s->first_slice_line) { // predictor A is not out of bounds if(s->mb_width == 1) { px = A[0]; @@ -2567,12 +2183,12 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, if(c_avail && (n!= 1 && n!=3)) { q2 = s->current_picture.qscale_table[mb_pos - 1]; if(q2 && q2 != q1) - c = (c * s->y_dc_scale_table[q2] * vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; } if(a_avail && (n!= 2 && n!=3)) { q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride]; if(q2 && q2 != q1) - a = (a * s->y_dc_scale_table[q2] * vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; } if(a_avail && c_avail && (n!=3)) { int off = mb_pos; @@ -2580,7 +2196,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, if(n != 2) off -= s->mb_stride; q2 = s->current_picture.qscale_table[off]; if(q2 && q2 != q1) - b = (b * s->y_dc_scale_table[q2] * vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; } if(a_avail && c_avail) { @@ -2653,17 +2269,17 @@ static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int *value, GetBitContext *gb = &v->s.gb; int index, escape, run = 0, level = 0, lst = 0; - index = get_vlc2(gb, vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3); + index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3); if (index != vc1_ac_sizes[codingset] - 1) { run = vc1_index_decode_table[codingset][index][0]; level = vc1_index_decode_table[codingset][index][1]; lst = index >= vc1_last_decode_table[codingset]; - if(get_bits(gb, 1)) + if(get_bits1(gb)) level = -level; } else { escape = decode210(gb); if (escape != 2) { - index = get_vlc2(gb, vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3); + index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3); run = vc1_index_decode_table[codingset][index][0]; level = vc1_index_decode_table[codingset][index][1]; lst = index >= vc1_last_decode_table[codingset]; @@ -2678,23 +2294,23 @@ static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int *value, else run += vc1_delta_run_table[codingset][level] + 1; } - if(get_bits(gb, 1)) + if(get_bits1(gb)) level = -level; } else { int sign; - lst = get_bits(gb, 1); + lst = get_bits1(gb); if(v->s.esc3_level_length == 0) { if(v->pq < 8 || v->dquantfrm) { // table 59 v->s.esc3_level_length = get_bits(gb, 3); if(!v->s.esc3_level_length) v->s.esc3_level_length = get_bits(gb, 2) + 8; } else { //table 60 - v->s.esc3_level_length = get_prefix(gb, 1, 6) + 2; + v->s.esc3_level_length = get_unary(gb, 1, 6) + 2; } v->s.esc3_run_length = 3 + get_bits(gb, 2); } run = get_bits(gb, v->s.esc3_run_length); - sign = get_bits(gb, 1); + sign = get_bits1(gb); level = get_bits(gb, v->s.esc3_level_length); if(sign) level = -level; @@ -2746,9 +2362,9 @@ static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded if (v->pq == 1) dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3; else if (v->pq == 2) - dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1; + dcdiff = (dcdiff<<1) + get_bits1(gb) - 1; } - if (get_bits(gb, 1)) + if (get_bits1(gb)) dcdiff = -dcdiff; } @@ -2782,11 +2398,11 @@ static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded if(v->s.ac_pred) { if(!dc_pred_dir) - zz_table = vc1_horizontal_zz; + zz_table = ff_vc1_horizontal_zz; else - zz_table = vc1_vertical_zz; + zz_table = ff_vc1_vertical_zz; } else - zz_table = vc1_normal_zz; + zz_table = ff_vc1_normal_zz; ac_val = s->ac_val[0][0] + s->block_index[n] * 16; ac_val2 = ac_val; @@ -2916,9 +2532,9 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c if (mquant == 1) dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3; else if (mquant == 2) - dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1; + dcdiff = (dcdiff<<1) + get_bits1(gb) - 1; } - if (get_bits(gb, 1)) + if (get_bits1(gb)) dcdiff = -dcdiff; } @@ -2939,14 +2555,12 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c //AC Decoding i = 1; - /* check if AC is needed at all and adjust direction if needed */ - if(!a_avail) dc_pred_dir = 1; - if(!c_avail) dc_pred_dir = 0; + /* check if AC is needed at all */ if(!a_avail && !c_avail) use_pred = 0; ac_val = s->ac_val[0][0] + s->block_index[n] * 16; ac_val2 = ac_val; - scale = mquant * 2 + v->halfpq; + scale = mquant * 2 + ((mquant == v->pq) ? v->halfpq : 0); if(dc_pred_dir) //left ac_val -= 16; @@ -2967,11 +2581,11 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c if(v->s.ac_pred) { if(!dc_pred_dir) - zz_table = vc1_horizontal_zz; + zz_table = ff_vc1_horizontal_zz; else - zz_table = vc1_vertical_zz; + zz_table = ff_vc1_vertical_zz; } else - zz_table = vc1_normal_zz; + zz_table = ff_vc1_normal_zz; while (!last) { vc1_decode_ac_coeff(v, &last, &skip, &value, codingset); @@ -2990,10 +2604,10 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c if(dc_pred_dir) { //left for(k = 1; k < 8; k++) - block[k << 3] += (ac_val[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18; + block[k << 3] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } else { //top for(k = 1; k < 8; k++) - block[k] += (ac_val[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18; + block[k] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } } else { if(dc_pred_dir) { //left @@ -3031,7 +2645,7 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; for(k = 1; k < 8; k++) - ac_val2[k] = (ac_val2[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18; + ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } } } else {//top @@ -3041,7 +2655,7 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, int c q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; for(k = 1; k < 8; k++) - ac_val2[k + 8] = (ac_val2[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18; + ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } } } @@ -3122,9 +2736,9 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c if (mquant == 1) dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3; else if (mquant == 2) - dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1; + dcdiff = (dcdiff<<1) + get_bits1(gb) - 1; } - if (get_bits(gb, 1)) + if (get_bits1(gb)) dcdiff = -dcdiff; } @@ -3172,7 +2786,7 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c const int8_t *zz_table; int k; - zz_table = vc1_simple_progressive_8x8_zz; + zz_table = ff_vc1_simple_progressive_8x8_zz; while (!last) { vc1_decode_ac_coeff(v, &last, &skip, &value, codingset); @@ -3191,10 +2805,10 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c if(dc_pred_dir) { //left for(k = 1; k < 8; k++) - block[k << 3] += (ac_val[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18; + block[k << 3] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } else { //top for(k = 1; k < 8; k++) - block[k] += (ac_val[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18; + block[k] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } } else { if(dc_pred_dir) { //left @@ -3232,7 +2846,7 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; for(k = 1; k < 8; k++) - ac_val2[k] = (ac_val2[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18; + ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } } } else {//top @@ -3242,7 +2856,7 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; for(k = 1; k < 8; k++) - ac_val2[k + 8] = (ac_val2[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18; + ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } } } @@ -3272,7 +2886,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c /** Decode P block */ -static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block) +static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block, + uint8_t *dst, int linesize, int skip_block) { MpegEncContext *s = &v->s; GetBitContext *gb = &s->gb; @@ -3282,10 +2897,10 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan int ttblk = ttmb & 7; if(ttmb == -1) { - ttblk = ttblk_to_tt[v->tt_index][get_vlc2(gb, vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)]; + ttblk = ff_vc1_ttblk_to_tt[v->tt_index][get_vlc2(gb, ff_vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)]; } if(ttblk == TT_4X4) { - subblkpat = ~(get_vlc2(gb, vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1); + subblkpat = ~(get_vlc2(gb, ff_vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1); } if((ttblk != TT_8X8 && ttblk != TT_4X4) && (v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))) { subblkpat = decode012(gb); @@ -3293,7 +2908,7 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) ttblk = TT_8X4; if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) ttblk = TT_4X8; } - scale = 2 * mquant + v->halfpq; + scale = 2 * mquant + ((v->pq == mquant) ? v->halfpq : 0); // convert transforms like 8X4_TOP to generic TT and SUBBLKPAT if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) { @@ -3313,12 +2928,15 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan i += skip; if(i > 63) break; - idx = vc1_simple_progressive_8x8_zz[i++]; + idx = ff_vc1_simple_progressive_8x8_zz[i++]; block[idx] = value * scale; if(!v->pquantizer) block[idx] += (block[idx] < 0) ? -mquant : mquant; } - s->dsp.vc1_inv_trans_8x8(block); + if(!skip_block){ + s->dsp.vc1_inv_trans_8x8(block); + s->dsp.add_pixels_clamped(block, dst, linesize); + } break; case TT_4X4: for(j = 0; j < 4; j++) { @@ -3330,13 +2948,13 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan i += skip; if(i > 15) break; - idx = vc1_simple_progressive_4x4_zz[i++]; + idx = ff_vc1_simple_progressive_4x4_zz[i++]; block[idx + off] = value * scale; if(!v->pquantizer) block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant; } - if(!(subblkpat & (1 << (3 - j)))) - s->dsp.vc1_inv_trans_4x4(block, j); + if(!(subblkpat & (1 << (3 - j))) && !skip_block) + s->dsp.vc1_inv_trans_4x4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off); } break; case TT_8X4: @@ -3349,16 +2967,13 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan i += skip; if(i > 31) break; - if(v->profile < PROFILE_ADVANCED) - idx = vc1_simple_progressive_8x4_zz[i++]; - else - idx = vc1_adv_progressive_8x4_zz[i++]; - block[idx + off] = value * scale; + idx = v->zz_8x4[i++]+off; + block[idx] = value * scale; if(!v->pquantizer) - block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant; + block[idx] += (block[idx] < 0) ? -mquant : mquant; } - if(!(subblkpat & (1 << (1 - j)))) - s->dsp.vc1_inv_trans_8x4(block, j); + if(!(subblkpat & (1 << (1 - j))) && !skip_block) + s->dsp.vc1_inv_trans_8x4(dst + j*4*linesize, linesize, block + off); } break; case TT_4X8: @@ -3371,16 +2986,13 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan i += skip; if(i > 31) break; - if(v->profile < PROFILE_ADVANCED) - idx = vc1_simple_progressive_4x8_zz[i++]; - else - idx = vc1_adv_progressive_4x8_zz[i++]; - block[idx + off] = value * scale; + idx = v->zz_4x8[i++]+off; + block[idx] = value * scale; if(!v->pquantizer) - block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant; + block[idx] += (block[idx] < 0) ? -mquant : mquant; } - if(!(subblkpat & (1 << (1 - j)))) - s->dsp.vc1_inv_trans_4x8(block, j); + if(!(subblkpat & (1 << (1 - j))) && !skip_block) + s->dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off); } break; } @@ -3441,12 +3053,12 @@ static int vc1_decode_p_mb(VC1Context *v) if (s->mb_intra && !mb_has_coeffs) { GET_MQUANT(); - s->ac_pred = get_bits(gb, 1); + s->ac_pred = get_bits1(gb); cbp = 0; } else if (mb_has_coeffs) { - if (s->mb_intra) s->ac_pred = get_bits(gb, 1); + if (s->mb_intra) s->ac_pred = get_bits1(gb); cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); GET_MQUANT(); } @@ -3458,7 +3070,7 @@ static int vc1_decode_p_mb(VC1Context *v) s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf && !s->mb_intra && mb_has_coeffs) - ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table, + ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); if(!s->mb_intra) vc1_mc_1mv(v, 0); dst_idx = 0; @@ -3481,9 +3093,7 @@ static int vc1_decode_p_mb(VC1Context *v) if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; s->dsp.vc1_inv_trans_8x8(s->block[i]); if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1; - for(j = 0; j < 64; j++) s->block[i][j] += 128; - if(!v->res_fasttx && v->res_x8) for(j = 0; j < 64; j++) s->block[i][j] += 16; - s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); + s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); if(v->pq >= 9 && v->overlap) { if(v->c_avail) s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); @@ -3491,11 +3101,9 @@ static int vc1_decode_p_mb(VC1Context *v) s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); } } else if(val) { - vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block); + vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY)); if(!v->ttmbf && ttmb < 8) ttmb = -1; first_block = 0; - if((i<4) || !(s->flags & CODEC_FLAG_GRAY)) - s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize); } } } @@ -3563,11 +3171,11 @@ static int vc1_decode_p_mb(VC1Context *v) break; } } - if(intrapred)s->ac_pred = get_bits(gb, 1); + if(intrapred)s->ac_pred = get_bits1(gb); else s->ac_pred = 0; } if (!v->ttmbf && coded_inter) - ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); + ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); for (i=0; i<6; i++) { dst_idx += i >> 2; @@ -3585,9 +3193,7 @@ static int vc1_decode_p_mb(VC1Context *v) if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; s->dsp.vc1_inv_trans_8x8(s->block[i]); if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1; - for(j = 0; j < 64; j++) s->block[i][j] += 128; - if(!v->res_fasttx && v->res_x8) for(j = 0; j < 64; j++) s->block[i][j] += 16; - s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize); + s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize); if(v->pq >= 9 && v->overlap) { if(v->c_avail) s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); @@ -3595,11 +3201,9 @@ static int vc1_decode_p_mb(VC1Context *v) s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); } } else if(is_coded[i]) { - status = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block); + status = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY)); if(!v->ttmbf && ttmb < 8) ttmb = -1; first_block = 0; - if((i<4) || !(s->flags & CODEC_FLAG_GRAY)) - s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize); } } return status; @@ -3707,7 +3311,7 @@ static void vc1_decode_b_mb(VC1Context *v) mb_has_coeffs = 0; s->current_picture.qscale_table[mb_pos] = mquant; if(!v->ttmbf) - ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); + ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0; vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype); vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype); @@ -3744,7 +3348,7 @@ static void vc1_decode_b_mb(VC1Context *v) GET_MQUANT(); s->current_picture.qscale_table[mb_pos] = mquant; if(!v->ttmbf && !s->mb_intra && mb_has_coeffs) - ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); + ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); } } dst_idx = 0; @@ -3767,14 +3371,11 @@ static void vc1_decode_b_mb(VC1Context *v) if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; s->dsp.vc1_inv_trans_8x8(s->block[i]); if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1; - for(j = 0; j < 64; j++) s->block[i][j] += 128; - s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); + s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); } else if(val) { - vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block); + vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY)); if(!v->ttmbf && ttmb < 8) ttmb = -1; first_block = 0; - if((i<4) || !(s->flags & CODEC_FLAG_GRAY)) - s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize); } } } @@ -3822,7 +3423,6 @@ static void vc1_decode_i_blocks(VC1Context *v) s->mb_x = s->mb_y = 0; s->mb_intra = 1; s->first_slice_line = 1; - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) { ff_init_block_index(s); @@ -3836,7 +3436,7 @@ static void vc1_decode_i_blocks(VC1Context *v) // do actual MB decoding and displaying cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - v->s.ac_pred = get_bits(&v->s.gb, 1); + v->s.ac_pred = get_bits1(&v->s.gb); for(k = 0; k < 6; k++) { val = ((cbp >> (5 - k)) & 1); @@ -3851,7 +3451,6 @@ static void vc1_decode_i_blocks(VC1Context *v) vc1_decode_i_block(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2); s->dsp.vc1_inv_trans_8x8(s->block[k]); - if(!v->res_fasttx && !v->res_x8) for(j = 0; j < 64; j++) s->block[k][j] -= 16; if(v->pq >= 9 && v->overlap) { for(j = 0; j < 64; j++) s->block[k][j] += 128; } @@ -3882,6 +3481,7 @@ static void vc1_decode_i_blocks(VC1Context *v) } if(get_bits_count(&s->gb) > v->bits) { + ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits); return; } @@ -3889,6 +3489,7 @@ static void vc1_decode_i_blocks(VC1Context *v) ff_draw_horiz_band(s, s->mb_y * 16, 16); s->first_slice_line = 0; } + ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); } /** Decode blocks of I-frame for advanced profile @@ -3934,7 +3535,6 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) s->mb_x = s->mb_y = 0; s->mb_intra = 1; s->first_slice_line = 1; - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) { ff_init_block_index(s); @@ -3948,13 +3548,13 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) // do actual MB decoding and displaying cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); if(v->acpred_is_raw) - v->s.ac_pred = get_bits(&v->s.gb, 1); + v->s.ac_pred = get_bits1(&v->s.gb); else v->s.ac_pred = v->acpred_plane[mb_pos]; if(v->condover == CONDOVER_SELECT) { if(v->overflg_is_raw) - overlap = get_bits(&v->s.gb, 1); + overlap = get_bits1(&v->s.gb); else overlap = v->over_flags_plane[mb_pos]; } else @@ -4011,6 +3611,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) } if(get_bits_count(&s->gb) > v->bits) { + ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits); return; } @@ -4018,6 +3619,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v) ff_draw_horiz_band(s, s->mb_y * 16, 16); s->first_slice_line = 0; } + ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); } static void vc1_decode_p_blocks(VC1Context *v) @@ -4049,7 +3651,6 @@ static void vc1_decode_p_blocks(VC1Context *v) break; } - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); s->first_slice_line = 1; for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) { @@ -4059,6 +3660,7 @@ static void vc1_decode_p_blocks(VC1Context *v) vc1_decode_p_mb(v); if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { + ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y); return; } @@ -4066,6 +3668,7 @@ static void vc1_decode_p_blocks(VC1Context *v) ff_draw_horiz_band(s, s->mb_y * 16, 16); s->first_slice_line = 0; } + ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); } static void vc1_decode_b_blocks(VC1Context *v) @@ -4097,7 +3700,6 @@ static void vc1_decode_b_blocks(VC1Context *v) break; } - ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); s->first_slice_line = 1; for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) { for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) { @@ -4107,6 +3709,7 @@ static void vc1_decode_b_blocks(VC1Context *v) vc1_decode_b_mb(v); if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) { + ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)); av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y); return; } @@ -4114,6 +3717,7 @@ static void vc1_decode_b_blocks(VC1Context *v) ff_draw_horiz_band(s, s->mb_y * 16, 16); s->first_slice_line = 0; } + ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END)); } static void vc1_decode_skip_blocks(VC1Context *v) @@ -4139,38 +3743,40 @@ static void vc1_decode_blocks(VC1Context *v) { v->s.esc3_level_length = 0; + if(v->x8_type){ + ff_intrax8_decode_picture(&v->x8, 2*v->pq+v->halfpq, v->pq*(!v->pquantizer) ); + }else{ - switch(v->s.pict_type) { - case I_TYPE: - if(v->profile == PROFILE_ADVANCED) - vc1_decode_i_blocks_adv(v); - else - vc1_decode_i_blocks(v); - break; - case P_TYPE: - if(v->p_frame_skipped) - vc1_decode_skip_blocks(v); - else - vc1_decode_p_blocks(v); - break; - case B_TYPE: - if(v->bi_type){ + switch(v->s.pict_type) { + case I_TYPE: if(v->profile == PROFILE_ADVANCED) vc1_decode_i_blocks_adv(v); else vc1_decode_i_blocks(v); - }else - vc1_decode_b_blocks(v); - break; + break; + case P_TYPE: + if(v->p_frame_skipped) + vc1_decode_skip_blocks(v); + else + vc1_decode_p_blocks(v); + break; + case B_TYPE: + if(v->bi_type){ + if(v->profile == PROFILE_ADVANCED) + vc1_decode_i_blocks_adv(v); + else + vc1_decode_i_blocks(v); + }else + vc1_decode_b_blocks(v); + break; + } } } -#define IS_MARKER(x) (((x) & ~0xFF) == VC1_CODE_RES0) - /** Find VC-1 marker in buffer * @return position where next marker starts or end of buffer if no marker found */ -static av_always_inline uint8_t* find_next_marker(uint8_t *src, uint8_t *end) +static av_always_inline const uint8_t* find_next_marker(const uint8_t *src, const uint8_t *end) { uint32_t mrk = 0xFFFFFFFF; @@ -4183,7 +3789,7 @@ static av_always_inline uint8_t* find_next_marker(uint8_t *src, uint8_t *end) return end; } -static av_always_inline int vc1_unescape_buffer(uint8_t *src, int size, uint8_t *dst) +static av_always_inline int vc1_unescape_buffer(const uint8_t *src, int size, uint8_t *dst) { int dsize = 0, i; @@ -4221,6 +3827,10 @@ static int vc1_decode_init(AVCodecContext *avctx) avctx->flags |= CODEC_FLAG_EMU_EDGE; v->s.flags |= CODEC_FLAG_EMU_EDGE; + if(avctx->idct_algo==FF_IDCT_AUTO){ + avctx->idct_algo=FF_IDCT_WMV2; + } + if(ff_h263_decode_init(avctx) < 0) return -1; if (vc1_init_common(v) < 0) return -1; @@ -4252,10 +3862,12 @@ static int vc1_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count); } } else { // VC1/WVC1 - uint8_t *start = avctx->extradata, *end = avctx->extradata + avctx->extradata_size; - uint8_t *next; int size, buf2_size; + const uint8_t *start = avctx->extradata; + uint8_t *end = avctx->extradata + avctx->extradata_size; + const uint8_t *next; + int size, buf2_size; uint8_t *buf2 = NULL; - int seq_inited = 0, ep_inited = 0; + int seq_initialized = 0, ep_initialized = 0; if(avctx->extradata_size < 16) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", avctx->extradata_size); @@ -4277,19 +3889,19 @@ static int vc1_decode_init(AVCodecContext *avctx) av_free(buf2); return -1; } - seq_inited = 1; + seq_initialized = 1; break; case VC1_CODE_ENTRYPOINT: if(decode_entry_point(avctx, &gb) < 0){ av_free(buf2); return -1; } - ep_inited = 1; + ep_initialized = 1; break; } } av_free(buf2); - if(!seq_inited || !ep_inited){ + if(!seq_initialized || !ep_initialized){ av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n"); return -1; } @@ -4321,6 +3933,7 @@ static int vc1_decode_init(AVCodecContext *avctx) // return -1; } + ff_intrax8_common_init(&v->x8,s); return 0; } @@ -4330,7 +3943,7 @@ static int vc1_decode_init(AVCodecContext *avctx) */ static int vc1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { VC1Context *v = avctx->priv_data; MpegEncContext *s = &v->s; @@ -4350,7 +3963,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, return 0; } - //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there + /* We need to set current_picture_ptr before reading the header, + * otherwise we cannot store anything in there. */ if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ int i= ff_find_unused_picture(s, 0); s->current_picture_ptr= &s->picture[i]; @@ -4362,7 +3976,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if(IS_MARKER(AV_RB32(buf))){ /* frame starts with marker and needs to be parsed */ - uint8_t *dst = buf2, *start, *end, *next; + const uint8_t *start, *end, *next; int size; next = buf; @@ -4386,7 +4000,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, } } }else if(v->interlace && ((buf[0] & 0xC0) == 0xC0)){ /* WVC1 interlaced stores both fields divided by marker */ - uint8_t *divider; + const uint8_t *divider; divider = find_next_marker(buf, buf + buf_size); if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){ @@ -4456,6 +4070,9 @@ static int vc1_decode_frame(AVCodecContext *avctx, return -1; } + s->me.qpel_put= s->dsp.put_qpel_pixels_tab; + s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab; + ff_er_frame_start(s); v->bits = buf_size * 8; @@ -4481,7 +4098,7 @@ assert(s->current_picture.pict_type == s->pict_type); } /* Return the Picture timestamp as the frame number */ - /* we substract 1 because it is added on utils.c */ + /* we subtract 1 because it is added on utils.c */ avctx->frame_number = s->picture_number - 1; av_free(buf2); @@ -4504,6 +4121,7 @@ static int vc1_decode_end(AVCodecContext *avctx) av_freep(&v->acpred_plane); av_freep(&v->over_flags_plane); av_freep(&v->mb_type_base); + ff_intrax8_common_end(&v->x8); return 0; } @@ -4533,94 +4151,3 @@ AVCodec wmv3_decoder = { CODEC_CAP_DELAY, NULL }; - -#ifdef CONFIG_VC1_PARSER -/** - * finds the end of the current frame in the bitstream. - * @return the position of the first byte of the next frame, or -1 - */ -static int vc1_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<buf_size; i++){ - state= (state<<8) | buf[i]; - if(state == VC1_CODE_FRAME || state == VC1_CODE_FIELD){ - i++; - pic_found=1; - break; - } - } - } - - if(pic_found){ - /* EOF considered as end of frame */ - if (buf_size == 0) - return 0; - for(; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if(IS_MARKER(state) && state != VC1_CODE_FIELD && state != VC1_CODE_SLICE){ - pc->frame_start_found=0; - pc->state=-1; - return i-3; - } - } - } - pc->frame_start_found= pic_found; - pc->state= state; - return END_NOT_FOUND; -} - -static int vc1_parse(AVCodecParserContext *s, - AVCodecContext *avctx, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size) -{ - ParseContext *pc = s->priv_data; - int next; - - if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ - next= buf_size; - }else{ - next= vc1_find_frame_end(pc, buf, buf_size); - - if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - return buf_size; - } - } - *poutbuf = (uint8_t *)buf; - *poutbuf_size = buf_size; - return next; -} - -int vc1_split(AVCodecContext *avctx, - const uint8_t *buf, int buf_size) -{ - int i; - uint32_t state= -1; - - for(i=0; i<buf_size; i++){ - state= (state<<8) | buf[i]; - if(IS_MARKER(state) && state != VC1_CODE_SEQHDR && state != VC1_CODE_ENTRYPOINT) - return i-3; - } - return 0; -} - -AVCodecParser vc1_parser = { - { CODEC_ID_VC1 }, - sizeof(ParseContext1), - NULL, - vc1_parse, - ff_parse1_close, - vc1_split, -}; -#endif /* CONFIG_VC1_PARSER */ diff --git a/contrib/ffmpeg/libavcodec/vc1.h b/contrib/ffmpeg/libavcodec/vc1.h new file mode 100644 index 000000000..12f38160b --- /dev/null +++ b/contrib/ffmpeg/libavcodec/vc1.h @@ -0,0 +1,312 @@ +/* + * VC-1 and WMV3 decoder + * Copyright (c) 2006-2007 Konstantin Shishkov + * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, 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 + */ + +#ifndef FFMPEG_VC1_H +#define FFMPEG_VC1_H + +#include "avcodec.h" +#include "mpegvideo.h" +#include "intrax8.h" + +/** Markers used in VC-1 AP frame data */ +//@{ +enum VC1Code{ + VC1_CODE_RES0 = 0x00000100, + VC1_CODE_ENDOFSEQ = 0x0000010A, + VC1_CODE_SLICE, + VC1_CODE_FIELD, + VC1_CODE_FRAME, + VC1_CODE_ENTRYPOINT, + VC1_CODE_SEQHDR, +}; +//@} + +#define IS_MARKER(x) (((x) & ~0xFF) == VC1_CODE_RES0) + +/** Available Profiles */ +//@{ +enum Profile { + PROFILE_SIMPLE, + PROFILE_MAIN, + PROFILE_COMPLEX, ///< TODO: WMV9 specific + PROFILE_ADVANCED +}; +//@} + +/** Sequence quantizer mode */ +//@{ +enum QuantMode { + QUANT_FRAME_IMPLICIT, ///< Implicitly specified at frame level + QUANT_FRAME_EXPLICIT, ///< Explicitly specified at frame level + QUANT_NON_UNIFORM, ///< Non-uniform quant used for all frames + QUANT_UNIFORM ///< Uniform quant used for all frames +}; +//@} + +/** Where quant can be changed */ +//@{ +enum DQProfile { + DQPROFILE_FOUR_EDGES, + DQPROFILE_DOUBLE_EDGES, + DQPROFILE_SINGLE_EDGE, + DQPROFILE_ALL_MBS +}; +//@} + +/** @name Where quant can be changed + */ +//@{ +enum DQSingleEdge { + DQSINGLE_BEDGE_LEFT, + DQSINGLE_BEDGE_TOP, + DQSINGLE_BEDGE_RIGHT, + DQSINGLE_BEDGE_BOTTOM +}; +//@} + +/** Which pair of edges is quantized with ALTPQUANT */ +//@{ +enum DQDoubleEdge { + DQDOUBLE_BEDGE_TOPLEFT, + DQDOUBLE_BEDGE_TOPRIGHT, + DQDOUBLE_BEDGE_BOTTOMRIGHT, + DQDOUBLE_BEDGE_BOTTOMLEFT +}; +//@} + +/** MV modes for P frames */ +//@{ +enum MVModes { + MV_PMODE_1MV_HPEL_BILIN, + MV_PMODE_1MV, + MV_PMODE_1MV_HPEL, + MV_PMODE_MIXED_MV, + MV_PMODE_INTENSITY_COMP +}; +//@} + +/** @name MV types for B frames */ +//@{ +enum BMVTypes { + BMV_TYPE_BACKWARD, + BMV_TYPE_FORWARD, + BMV_TYPE_INTERPOLATED +}; +//@} + +/** @name Block types for P/B frames */ +//@{ +enum TransformTypes { + TT_8X8, + TT_8X4_BOTTOM, + TT_8X4_TOP, + TT_8X4, //Both halves + TT_4X8_RIGHT, + TT_4X8_LEFT, + TT_4X8, //Both halves + TT_4X4 +}; +//@} + +/** One more frame type */ +#define BI_TYPE 7 + +enum CodingSet { + CS_HIGH_MOT_INTRA = 0, + CS_HIGH_MOT_INTER, + CS_LOW_MOT_INTRA, + CS_LOW_MOT_INTER, + CS_MID_RATE_INTRA, + CS_MID_RATE_INTER, + CS_HIGH_RATE_INTRA, + CS_HIGH_RATE_INTER +}; + +/** @name Overlap conditions for Advanced Profile */ +//@{ +enum COTypes { + CONDOVER_NONE = 0, + CONDOVER_ALL, + CONDOVER_SELECT +}; +//@} + + +/** The VC1 Context + * @todo Change size wherever another size is more efficient + * Many members are only used for Advanced Profile + */ +typedef struct VC1Context{ + MpegEncContext s; + IntraX8Context x8; + + int bits; + + /** Simple/Main Profile sequence header */ + //@{ + int res_sm; ///< reserved, 2b + int res_x8; ///< reserved + int multires; ///< frame-level RESPIC syntax element present + int res_fasttx; ///< reserved, always 1 + int res_transtab; ///< reserved, always 0 + int rangered; ///< RANGEREDFRM (range reduction) syntax element present + ///< at frame level + int res_rtm_flag; ///< reserved, set to 1 + int reserved; ///< reserved + //@} + + /** Advanced Profile */ + //@{ + int level; ///< 3bits, for Advanced/Simple Profile, provided by TS layer + int chromaformat; ///< 2bits, 2=4:2:0, only defined + int postprocflag; ///< Per-frame processing suggestion flag present + int broadcast; ///< TFF/RFF present + int interlace; ///< Progressive/interlaced (RPTFTM syntax element) + int tfcntrflag; ///< TFCNTR present + int panscanflag; ///< NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present + int extended_dmv; ///< Additional extended dmv range at P/B frame-level + int color_prim; ///< 8bits, chroma coordinates of the color primaries + int transfer_char; ///< 8bits, Opto-electronic transfer characteristics + int matrix_coef; ///< 8bits, Color primaries->YCbCr transform matrix + int hrd_param_flag; ///< Presence of Hypothetical Reference + ///< Decoder parameters + int psf; ///< Progressive Segmented Frame + //@} + + /** Sequence header data for all Profiles + * TODO: choose between ints, uint8_ts and monobit flags + */ + //@{ + int profile; ///< 2bits, Profile + int frmrtq_postproc; ///< 3bits, + int bitrtq_postproc; ///< 5bits, quantized framerate-based postprocessing strength + int fastuvmc; ///< Rounding of qpel vector to hpel ? (not in Simple) + int extended_mv; ///< Ext MV in P/B (not in Simple) + int dquant; ///< How qscale varies with MBs, 2bits (not in Simple) + int vstransform; ///< variable-size [48]x[48] transform type + info + int overlap; ///< overlapped transforms in use + int quantizer_mode; ///< 2bits, quantizer mode used for sequence, see QUANT_* + int finterpflag; ///< INTERPFRM present + //@} + + /** Frame decoding info for all profiles */ + //@{ + uint8_t mv_mode; ///< MV coding monde + uint8_t mv_mode2; ///< Secondary MV coding mode (B frames) + int k_x; ///< Number of bits for MVs (depends on MV range) + int k_y; ///< Number of bits for MVs (depends on MV range) + int range_x, range_y; ///< MV range + uint8_t pq, altpq; ///< Current/alternate frame quantizer scale + const uint8_t* zz_8x4;///< Zigzag scan table for TT_8x4 coding mode + const uint8_t* zz_4x8;///< Zigzag scan table for TT_4x8 coding mode + /** pquant parameters */ + //@{ + uint8_t dquantfrm; + uint8_t dqprofile; + uint8_t dqsbedge; + uint8_t dqbilevel; + //@} + /** AC coding set indexes + * @see 8.1.1.10, p(1)10 + */ + //@{ + int c_ac_table_index; ///< Chroma index from ACFRM element + int y_ac_table_index; ///< Luma index from AC2FRM element + //@} + int ttfrm; ///< Transform type info present at frame level + uint8_t ttmbf; ///< Transform type flag + uint8_t ttblk4x4; ///< Value of ttblk which indicates a 4x4 transform + int codingset; ///< index of current table set from 11.8 to use for luma block decoding + int codingset2; ///< index of current table set from 11.8 to use for chroma block decoding + int pqindex; ///< raw pqindex used in coding set selection + int a_avail, c_avail; + uint8_t *mb_type_base, *mb_type[3]; + + + /** Luma compensation parameters */ + //@{ + uint8_t lumscale; + uint8_t lumshift; + //@} + int16_t bfraction; ///< Relative position % anchors=> how to scale MVs + uint8_t halfpq; ///< Uniform quant over image and qp+.5 + uint8_t respic; ///< Frame-level flag for resized images + int buffer_fullness; ///< HRD info + /** Ranges: + * -# 0 -> [-64n 63.f] x [-32, 31.f] + * -# 1 -> [-128, 127.f] x [-64, 63.f] + * -# 2 -> [-512, 511.f] x [-128, 127.f] + * -# 3 -> [-1024, 1023.f] x [-256, 255.f] + */ + uint8_t mvrange; + uint8_t pquantizer; ///< Uniform (over sequence) quantizer in use + VLC *cbpcy_vlc; ///< CBPCY VLC table + int tt_index; ///< Index for Transform Type tables + uint8_t* mv_type_mb_plane; ///< bitplane for mv_type == (4MV) + uint8_t* direct_mb_plane; ///< bitplane for "direct" MBs + int mv_type_is_raw; ///< mv type mb plane is not coded + int dmb_is_raw; ///< direct mb plane is raw + int skip_is_raw; ///< skip mb plane is not coded + uint8_t luty[256], lutuv[256]; // lookup tables used for intensity compensation + int use_ic; ///< use intensity compensation in B-frames + int rnd; ///< rounding control + + /** Frame decoding info for S/M profiles only */ + //@{ + uint8_t rangeredfrm; ///< out_sample = CLIP((in_sample-128)*2+128) + uint8_t interpfrm; + //@} + + /** Frame decoding info for Advanced profile */ + //@{ + uint8_t fcm; ///< 0->Progressive, 2->Frame-Interlace, 3->Field-Interlace + uint8_t numpanscanwin; + uint8_t tfcntr; + uint8_t rptfrm, tff, rff; + uint16_t topleftx; + uint16_t toplefty; + uint16_t bottomrightx; + uint16_t bottomrighty; + uint8_t uvsamp; + uint8_t postproc; + int hrd_num_leaky_buckets; + uint8_t bit_rate_exponent; + uint8_t buffer_size_exponent; + uint8_t* acpred_plane; ///< AC prediction flags bitplane + int acpred_is_raw; + uint8_t* over_flags_plane; ///< Overflags bitplane + int overflg_is_raw; + uint8_t condover; + uint16_t *hrd_rate, *hrd_buffer; + uint8_t *hrd_fullness; + uint8_t range_mapy_flag; + uint8_t range_mapuv_flag; + uint8_t range_mapy; + uint8_t range_mapuv; + //@} + + int p_frame_skipped; + int bi_type; + int x8_type; +} VC1Context; + +#endif /* FFMPEG_VC1_H */ diff --git a/contrib/ffmpeg/libavcodec/vc1_parser.c b/contrib/ffmpeg/libavcodec/vc1_parser.c new file mode 100644 index 000000000..a76d14707 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/vc1_parser.c @@ -0,0 +1,118 @@ +/* + * VC-1 and WMV3 parser + * Copyright (c) 2006-2007 Konstantin Shishkov + * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, 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 vc1_parser.c + * VC-1 and WMV3 parser + */ + +#include "parser.h" +#include "vc1.h" + +/** + * finds the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int vc1_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<buf_size; i++){ + state= (state<<8) | buf[i]; + if(state == VC1_CODE_FRAME || state == VC1_CODE_FIELD){ + i++; + pic_found=1; + break; + } + } + } + + if(pic_found){ + /* EOF considered as end of frame */ + if (buf_size == 0) + return 0; + for(; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if(IS_MARKER(state) && state != VC1_CODE_FIELD && state != VC1_CODE_SLICE){ + pc->frame_start_found=0; + pc->state=-1; + return i-3; + } + } + } + pc->frame_start_found= pic_found; + pc->state= state; + return END_NOT_FOUND; +} + +static int vc1_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + int next; + + if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ + next= buf_size; + }else{ + next= vc1_find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + } + *poutbuf = buf; + *poutbuf_size = buf_size; + return next; +} + +static int vc1_split(AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + int i; + uint32_t state= -1; + + for(i=0; i<buf_size; i++){ + state= (state<<8) | buf[i]; + if(IS_MARKER(state) && state != VC1_CODE_SEQHDR && state != VC1_CODE_ENTRYPOINT) + return i-3; + } + return 0; +} + +AVCodecParser vc1_parser = { + { CODEC_ID_VC1 }, + sizeof(ParseContext1), + NULL, + vc1_parse, + ff_parse1_close, + vc1_split, +}; diff --git a/contrib/ffmpeg/libavcodec/vc1acdata.h b/contrib/ffmpeg/libavcodec/vc1acdata.h index a6acecd78..f775283dd 100644 --- a/contrib/ffmpeg/libavcodec/vc1acdata.h +++ b/contrib/ffmpeg/libavcodec/vc1acdata.h @@ -19,6 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_VC1ACDATA_H +#define FFMPEG_VC1ACDATA_H + +#include <stdint.h> + #define AC_MODES 8 static const int vc1_ac_sizes[AC_MODES] = { @@ -583,3 +588,5 @@ static const uint8_t vc1_last_delta_run_table[AC_MODES][10] = { -1, 30, 28, 3, 0 } }; + +#endif /* FFMPEG_VC1ACDATA_H */ diff --git a/contrib/ffmpeg/libavcodec/vc1data.c b/contrib/ffmpeg/libavcodec/vc1data.c new file mode 100644 index 000000000..7f50d715f --- /dev/null +++ b/contrib/ffmpeg/libavcodec/vc1data.c @@ -0,0 +1,712 @@ +/* + * VC-1 and WMV3 decoder + * copyright (c) 2006 Konstantin Shishkov + * (c) 2005 anonymous, Alex Beregszaszi, 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 vc1data.c + * VC-1 tables. + */ + +#include "avcodec.h" +#include "vc1.h" +#include "vc1data.h" + +/** Table for conversion between TTBLK and TTMB */ +const int ff_vc1_ttblk_to_tt[3][8] = { + { TT_8X4, TT_4X8, TT_8X8, TT_4X4, TT_8X4_TOP, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT }, + { TT_8X8, TT_4X8_RIGHT, TT_4X8_LEFT, TT_4X4, TT_8X4, TT_4X8, TT_8X4_BOTTOM, TT_8X4_TOP }, + { TT_8X8, TT_4X8, TT_4X4, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT, TT_8X4, TT_8X4_TOP } +}; + +const int ff_vc1_ttfrm_to_tt[4] = { TT_8X8, TT_8X4, TT_4X8, TT_4X4 }; + +/** MV P mode - the 5th element is only used for mode 1 */ +const uint8_t ff_vc1_mv_pmode_table[2][5] = { + { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_MIXED_MV }, + { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_1MV_HPEL_BILIN } +}; +const uint8_t ff_vc1_mv_pmode_table2[2][4] = { + { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV }, + { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN } +}; + +const int ff_vc1_fps_nr[5] = { 24, 25, 30, 50, 60 }, + ff_vc1_fps_dr[2] = { 1000, 1001 }; +const uint8_t ff_vc1_pquant_table[3][32] = { + { /* Implicit quantizer */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31 + }, + { /* Explicit quantizer, pquantizer uniform */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + }, + { /* Explicit quantizer, pquantizer non-uniform */ + 0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 31 + } +}; + +/** @name VC-1 VLC tables and defines + * @todo TODO move this into the context + */ +//@{ +#define VC1_BFRACTION_VLC_BITS 7 +VLC ff_vc1_bfraction_vlc; +#define VC1_IMODE_VLC_BITS 4 +VLC ff_vc1_imode_vlc; +#define VC1_NORM2_VLC_BITS 3 +VLC ff_vc1_norm2_vlc; +#define VC1_NORM6_VLC_BITS 9 +VLC ff_vc1_norm6_vlc; +/* Could be optimized, one table only needs 8 bits */ +#define VC1_TTMB_VLC_BITS 9 //12 +VLC ff_vc1_ttmb_vlc[3]; +#define VC1_MV_DIFF_VLC_BITS 9 //15 +VLC ff_vc1_mv_diff_vlc[4]; +#define VC1_CBPCY_P_VLC_BITS 9 //14 +VLC ff_vc1_cbpcy_p_vlc[4]; +#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6 +VLC ff_vc1_4mv_block_pattern_vlc[4]; +#define VC1_TTBLK_VLC_BITS 5 +VLC ff_vc1_ttblk_vlc[3]; +#define VC1_SUBBLKPAT_VLC_BITS 6 +VLC ff_vc1_subblkpat_vlc[3]; + +VLC ff_vc1_ac_coeff_table[8]; +//@} + + +#if B_FRACTION_DEN==840 //original bfraction from vc9data.h, not conforming to standard +/* bfraction is fractional, we scale to the GCD 3*5*7*8 = 840 */ +const int16_t ff_vc1_bfraction_lut[23] = { + 420 /*1/2*/, 280 /*1/3*/, 560 /*2/3*/, 210 /*1/4*/, + 630 /*3/4*/, 168 /*1/5*/, 336 /*2/5*/, + 504 /*3/5*/, 672 /*4/5*/, 140 /*1/6*/, 700 /*5/6*/, + 120 /*1/7*/, 240 /*2/7*/, 360 /*3/7*/, 480 /*4/7*/, + 600 /*5/7*/, 720 /*6/7*/, 105 /*1/8*/, 315 /*3/8*/, + 525 /*5/8*/, 735 /*7/8*/, + -1 /*inv.*/, 0 /*BI fm*/ +}; +#else +/* pre-computed scales for all bfractions and base=256 */ +const int16_t ff_vc1_bfraction_lut[23] = { + 128 /*1/2*/, 85 /*1/3*/, 170 /*2/3*/, 64 /*1/4*/, + 192 /*3/4*/, 51 /*1/5*/, 102 /*2/5*/, + 153 /*3/5*/, 204 /*4/5*/, 43 /*1/6*/, 215 /*5/6*/, + 37 /*1/7*/, 74 /*2/7*/, 111 /*3/7*/, 148 /*4/7*/, + 185 /*5/7*/, 222 /*6/7*/, 32 /*1/8*/, 96 /*3/8*/, + 160 /*5/8*/, 224 /*7/8*/, + -1 /*inv.*/, 0 /*BI fm*/ +}; +#endif + +const uint8_t ff_vc1_bfraction_bits[23] = { + 3, 3, 3, 3, + 3, 3, 3, + 7, 7, 7, 7, + 7, 7, 7, 7, + 7, 7, 7, 7, + 7, 7, + 7, 7 +}; +const uint8_t ff_vc1_bfraction_codes[23] = { + 0, 1, 2, 3, + 4, 5, 6, + 112, 113, 114, 115, + 116, 117, 118, 119, + 120, 121, 122, 123, + 124, 125, + 126, 127 +}; + +//Same as H.264 +const AVRational ff_vc1_pixel_aspect[16]={ + {0, 1}, + {1, 1}, + {12, 11}, + {10, 11}, + {16, 11}, + {40, 33}, + {24, 11}, + {20, 11}, + {32, 11}, + {80, 33}, + {18, 11}, + {15, 11}, + {64, 33}, + {160, 99}, + {0, 1}, + {0, 1} +}; + +/* BitPlane IMODE - such a small table... */ +const uint8_t ff_vc1_imode_codes[7] = { + 0, 2, 1, 3, 1, 2, 3 +}; +const uint8_t ff_vc1_imode_bits[7] = { + 4, 2, 3, 2, 4, 3, 3 +}; + +/* Normal-2 imode */ +const uint8_t ff_vc1_norm2_codes[4] = { + 0, 4, 5, 3 +}; +const uint8_t ff_vc1_norm2_bits[4] = { + 1, 3, 3, 2 +}; + +const uint16_t ff_vc1_norm6_codes[64] = { +0x001, 0x002, 0x003, 0x000, 0x004, 0x001, 0x002, 0x047, 0x005, 0x003, 0x004, 0x04B, 0x005, 0x04D, 0x04E, 0x30E, +0x006, 0x006, 0x007, 0x053, 0x008, 0x055, 0x056, 0x30D, 0x009, 0x059, 0x05A, 0x30C, 0x05C, 0x30B, 0x30A, 0x037, +0x007, 0x00A, 0x00B, 0x043, 0x00C, 0x045, 0x046, 0x309, 0x00D, 0x049, 0x04A, 0x308, 0x04C, 0x307, 0x306, 0x036, +0x00E, 0x051, 0x052, 0x305, 0x054, 0x304, 0x303, 0x035, 0x058, 0x302, 0x301, 0x034, 0x300, 0x033, 0x032, 0x007, +}; + +const uint8_t ff_vc1_norm6_bits[64] = { + 1, 4, 4, 8, 4, 8, 8, 10, 4, 8, 8, 10, 8, 10, 10, 13, + 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9, + 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9, + 8, 10, 10, 13, 10, 13, 13, 9, 10, 13, 13, 9, 13, 9, 9, 6, +}; +/* Normal-6 imode */ +const uint8_t ff_vc1_norm6_spec[64][5] = { +{ 0, 1, 1 }, +{ 1, 2, 4 }, +{ 2, 3, 4 }, +{ 3, 0, 8 }, +{ 4, 4, 4 }, +{ 5, 1, 8 }, +{ 6, 2, 8 }, +{ 7, 2, 5, 7, 5 }, +{ 8, 5, 4 }, +{ 9, 3, 8 }, +{10, 4, 8 }, +{11, 2, 5, 11, 5 }, +{12, 5, 8 }, +{13, 2, 5, 13, 5 }, +{14, 2, 5, 14, 5 }, +{15, 3, 5, 14, 8 }, +{16, 6, 4 }, +{17, 6, 8 }, +{18, 7, 8 }, +{19, 2, 5, 19, 5 }, +{20, 8, 8 }, +{21, 2, 5, 21, 5 }, +{22, 2, 5, 22, 5 }, +{23, 3, 5, 13, 8 }, +{24, 9, 8 }, +{25, 2, 5, 25, 5 }, +{26, 2, 5, 26, 5 }, +{27, 3, 5, 12, 8 }, +{28, 2, 5, 28, 5 }, +{29, 3, 5, 11, 8 }, +{30, 3, 5, 10, 8 }, +{31, 3, 5, 7, 4 }, +{32, 7, 4 }, +{33, 10, 8 }, +{34, 11, 8 }, +{35, 2, 5, 3, 5 }, +{36, 12, 8 }, +{37, 2, 5, 5, 5 }, +{38, 2, 5, 6, 5 }, +{39, 3, 5, 9, 8 }, +{40, 13, 8 }, +{41, 2, 5, 9, 5 }, +{42, 2, 5, 10, 5 }, +{43, 3, 5, 8, 8 }, +{44, 2, 5, 12, 5 }, +{45, 3, 5, 7, 8 }, +{46, 3, 5, 6, 8 }, +{47, 3, 5, 6, 4 }, +{48, 14, 8 }, +{49, 2, 5, 17, 5 }, +{50, 2, 5, 18, 5 }, +{51, 3, 5, 5, 8 }, +{52, 2, 5, 20, 5 }, +{53, 3, 5, 4, 8 }, +{54, 3, 5, 3, 8 }, +{55, 3, 5, 5, 4 }, +{56, 2, 5, 24, 5 }, +{57, 3, 5, 2, 8 }, +{58, 3, 5, 1, 8 }, +{59, 3, 5, 4, 4 }, +{60, 3, 5, 0, 8 }, +{61, 3, 5, 3, 4 }, +{62, 3, 5, 2, 4 }, +{63, 3, 5, 1, 1 }, +}; + +/* 4MV Block pattern VLC tables */ +const uint8_t ff_vc1_4mv_block_pattern_codes[4][16] = { + { 14, 58, 59, 25, 12, 26, 15, 15, 13, 24, 27, 0, 28, 1, 2, 2}, + { 8, 18, 19, 4, 20, 5, 30, 11, 21, 31, 6, 12, 7, 13, 14, 0}, + { 15, 6, 7, 2, 8, 3, 28, 9, 10, 29, 4, 11, 5, 12, 13, 0}, + { 0, 11, 12, 4, 13, 5, 30, 16, 14, 31, 6, 17, 7, 18, 19, 10} +}; +const uint8_t ff_vc1_4mv_block_pattern_bits[4][16] = { + { 5, 6, 6, 5, 5, 5, 5, 4, 5, 5, 5, 3, 5, 3, 3, 2}, + { 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2}, + { 4, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3}, + { 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4} +}; + +const uint8_t wmv3_dc_scale_table[32]={ + 0, 2, 4, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21 +}; + +/* P-Picture CBPCY VLC tables */ +#if 1 // Looks like original tables are not conforming to standard at all. Are they used for old WMV? +const uint16_t ff_vc1_cbpcy_p_codes[4][64] = { + { + 0, 6, 15, 13, 13, 11, 3, 13, 5, 8, 49, 10, 12, 114, 102, 119, + 1, 54, 96, 8, 10, 111, 5, 15, 12, 10, 2, 12, 13, 115, 53, 63, + 1, 7, 1, 7, 14, 12, 4, 14, 1, 9, 97, 11, 7, 58, 52, 62, + 4, 103, 1, 9, 11, 56, 101, 118, 4, 110, 100, 30, 2, 5, 4, 3 + }, + { + 0, 9, 1, 18, 5, 14, 237, 26, 3, 121, 3, 22, 13, 16, 6, 30, + 2, 10, 1, 20, 12, 241, 5, 28, 16, 12, 3, 24, 28, 124, 239, 247, + 1, 240, 1, 19, 18, 15, 4, 27, 1, 122, 2, 23, 1, 17, 7, 31, + 1, 11, 2, 21, 19, 246, 238, 29, 17, 13, 236, 25, 58, 63, 8, 125 + }, + { + 0, 201, 25, 231, 5, 221, 1, 3, 2, 414, 2, 241, 16, 225, 195, 492, + 2, 412, 1, 240, 7, 224, 98, 245, 1, 220, 96, 5, 9, 230, 101, 247, + 1, 102, 1, 415, 24, 3, 2, 244, 3, 54, 3, 484, 17, 114, 200, 493, + 3, 413, 1, 4, 13, 113, 99, 485, 4, 111, 194, 243, 5, 29, 26, 31 + }, + { + 0, 28, 12, 44, 3, 36, 20, 52, 2, 32, 16, 48, 8, 40, 24, 28, + 1, 30, 14, 46, 6, 38, 22, 54, 3, 34, 18, 50, 10, 42, 26, 30, + 1, 29, 13, 45, 5, 37, 21, 53, 2, 33, 17, 49, 9, 41, 25, 29, + 1, 31, 15, 47, 7, 39, 23, 55, 4, 35, 19, 51, 11, 43, 27, 31 + } +}; + +const uint8_t ff_vc1_cbpcy_p_bits[4][64] = { + { + 13, 13, 7, 13, 7, 13, 13, 12, 6, 13, 7, 12, 6, 8, 8, 8, + 5, 7, 8, 12, 6, 8, 13, 12, 7, 13, 13, 12, 6, 8, 7, 7, + 6, 13, 8, 12, 7, 13, 13, 12, 7, 13, 8, 12, 5, 7, 7, 7, + 6, 8, 13, 12, 6, 7, 8, 8, 5, 8, 8, 6, 3, 3, 3, 2 + }, + { + 14, 13, 8, 13, 3, 13, 8, 13, 3, 7, 8, 13, 4, 13, 13, 13, + 3, 13, 13, 13, 4, 8, 13, 13, 5, 13, 13, 13, 5, 7, 8, 8, + 3, 8, 14, 13, 5, 13, 13, 13, 4, 7, 13, 13, 6, 13, 13, 13, + 5, 13, 8, 13, 5, 8, 8, 13, 5, 13, 8, 13, 6, 6, 13, 7 + }, + { + 13, 8, 6, 8, 4, 8, 13, 12, 4, 9, 8, 8, 5, 8, 8, 9, + 5, 9, 10, 8, 4, 8, 7, 8, 6, 8, 7, 13, 4, 8, 7, 8, + 5, 7, 8, 9, 6, 13, 13, 8, 4, 6, 8, 9, 5, 7, 8, 9, + 5, 9, 9, 13, 5, 7, 7, 9, 4, 7, 8, 8, 3, 5, 5, 5 + }, + { + 9, 9, 9, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 8, + 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, + 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8 + } +}; +#else +const uint16_t ff_vc1_cbpcy_p_codes[4][64] = { + { + 0, 1, 1, 4, 5, 1, 12, 4, 13, 14, 10, 11, 12, 7, 13, 2, + 15, 1, 96, 1, 49, 97, 2, 100, 3, 4, 5, 101, 102, 52, 53, 4, + 6, 7, 54, 103, 8, 9, 10, 110, 11, 12, 111, 56, 114, 58, 115, 5, + 13, 7, 8, 9, 10, 11, 12, 30, 13, 14, 15, 118, 119, 62, 63, 3 + }, + { + 0, 1, 2, 1, 3, 1, 16, 17, 5, 18, 12, 19, 13, 1, 28, 58, + 1, 1, 1, 2, 3, 2, 3, 236, 237, 4, 5, 238, 6, 7, 239, 8, + 9, 240, 10, 11, 121, 122, 12, 13, 14, 15, 241, 246, 16, 17, 124, 63, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 247, 125 + }, + { + 0, 1, 2, 3, 2, 3, 1, 4, 5, 24, 7, 13, 16, 17, 9, 5, + 25, 1, 1, 1, 2, 3, 96, 194, 1, 2, 98, 99, 195, 200, 101, 26, + 201, 102, 412, 413, 414, 54, 220, 111, 221, 3, 224, 113, 225, 114, 230, 29, + 231, 415, 240, 4, 241, 484, 5, 243, 3, 244, 245, 485, 492, 493, 247, 31 + }, + { + 0, 1, 1, 1, 2, 2, 3, 4, 3, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 28, 29, 30, 31 + } +}; +const uint8_t ff_vc1_cbpcy_p_bits[4][64] = { + { + 13, 6, 5, 6, 6, 7, 7, 5, 7, 7, 6, 6, 6, 5, 6, 3, + 7, 8, 8, 13, 7, 8, 13, 8, 13, 13, 13, 8, 8, 7, 7, 3, + 13, 13, 7, 8, 13, 13, 13, 8, 13, 13, 8, 7, 8, 7, 8, 3, + 13, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 8, 8, 7, 7, 2 + }, + { + 14, 3, 3, 5, 3, 4, 5, 5, 3, 5, 4, 5, 4, 6, 5, 6, + 8, 14, 13, 8, 8, 13, 13, 8, 8, 13, 13, 8, 13, 13, 8, 13, + 13, 8, 13, 13, 7, 7, 13, 13, 13, 13, 8, 8, 13, 13, 7, 6, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 7 + }, + { + 13, 5, 5, 5, 4, 4, 6, 4, 4, 6, 4, 5, 5, 5, 4, 3, + 6, 8, 10, 9, 8, 8, 7, 8, 13, 13, 7, 7, 8, 8, 7, 5, + 8, 7, 9, 9, 9, 6, 8, 7, 8, 13, 8, 7, 8, 7, 8, 5, + 8, 9, 8, 13, 8, 9, 13, 8, 12, 8, 8, 9, 9, 9, 8, 5 + }, + { + 9, 2, 3, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8 + } +}; +#endif + +/* MacroBlock Transform Type: 7.1.3.11, p89 + * 8x8:B + * 8x4:B:btm 8x4:B:top 8x4:B:both, + * 4x8:B:right 4x8:B:left 4x8:B:both + * 4x4:B 8x8:MB + * 8x4:MB:btm 8x4:MB:top 8x4,MB,both + * 4x8,MB,right 4x8,MB,left + * 4x4,MB */ +const uint16_t ff_vc1_ttmb_codes[3][16] = { + { + 0x0003, + 0x002E, 0x005F, 0x0000, + 0x0016, 0x0015, 0x0001, + 0x0004, 0x0014, + 0x02F1, 0x0179, 0x017B, + 0x0BC0, 0x0BC1, 0x05E1, + 0x017A + }, + { + 0x0006, + 0x0006, 0x0003, 0x0007, + 0x000F, 0x000E, 0x0000, + 0x0002, 0x0002, + 0x0014, 0x0011, 0x000B, + 0x0009, 0x0021, 0x0015, + 0x0020 + }, + { + 0x0006, + 0x0000, 0x000E, 0x0005, + 0x0002, 0x0003, 0x0003, + 0x000F, 0x0002, + 0x0081, 0x0021, 0x0009, + 0x0101, 0x0041, 0x0011, + 0x0100 + } +}; + +const uint8_t ff_vc1_ttmb_bits[3][16] = { + { + 2, + 6, 7, 2, + 5, 5, 2, + 3, 5, + 10, 9, 9, + 12, 12, 11, + 9 + }, + { + 3, + 4, 4, 4, + 4, 4, 3, + 3, 2, + 7, 7, 6, + 6, 8, 7, + 8 + }, + { + 3, + 3, 4, 5, + 3, 3, 4, + 4, 2, + 10, 8, 6, + 11, 9, 7, + 11 + } +}; + +/* TTBLK (Transform Type per Block) tables */ +const uint8_t ff_vc1_ttblk_codes[3][8] = { + { 0, 1, 3, 5, 16, 17, 18, 19}, + { 3, 0, 1, 2, 3, 5, 8, 9}, + { 1, 0, 1, 4, 6, 7, 10, 11} +}; +const uint8_t ff_vc1_ttblk_bits[3][8] = { + { 2, 2, 2, 3, 5, 5, 5, 5}, + { 2, 3, 3, 3, 3, 3, 4, 4}, + { 2, 3, 3, 3, 3, 3, 4, 4} +}; + +/* SUBBLKPAT tables, p93-94, reordered */ +const uint8_t ff_vc1_subblkpat_codes[3][15] = { + { 14, 12, 7, 11, 9, 26, 2, 10, 27, 8, 0, 6, 1, 15, 1}, + { 14, 0, 8, 15, 10, 4, 23, 13, 5, 9, 25, 3, 24, 22, 1}, + { 5, 6, 2, 2, 8, 0, 28, 3, 1, 3, 29, 1, 19, 18, 15} +}; +const uint8_t ff_vc1_subblkpat_bits[3][15] = { + { 5, 5, 5, 5, 5, 6, 4, 5, 6, 5, 4, 5, 4, 5, 1}, + { 4, 3, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 2}, + { 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4} +}; + +/* MV differential tables, p265 */ +const uint16_t ff_vc1_mv_diff_codes[4][73] = { + { + 0, 2, 3, 8, 576, 3, 2, 6, + 5, 577, 578, 7, 8, 9, 40, 19, + 37, 82, 21, 22, 23, 579, 580, 166, + 96, 167, 49, 194, 195, 581, 582, 583, + 292, 293, 294, 13, 2, 7, 24, 50, + 102, 295, 13, 7, 8, 18, 50, 103, + 38, 20, 21, 22, 39, 204, 103, 23, + 24, 25, 104, 410, 105, 106, 107, 108, + 109, 220, 411, 442, 222, 443, 446, 447, + 7 /* 73 elements */ + }, + { + 0, 4, 5, 3, 4, 3, 4, 5, + 20, 6, 21, 44, 45, 46, 3008, 95, + 112, 113, 57, 3009, 3010, 116, 117, 3011, + 118, 3012, 3013, 3014, 3015, 3016, 3017, 3018, + 3019, 3020, 3021, 3022, 1, 4, 15, 160, + 161, 41, 6, 11, 42, 162, 43, 119, + 56, 57, 58, 163, 236, 237, 3023, 119, + 120, 242, 122, 486, 1512, 487, 246, 494, + 1513, 495, 1514, 1515, 1516, 1517, 1518, 1519, + 31 /* 73 elements */ + }, + { + 0, 512, 513, 514, 515, 2, 3, 258, + 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 1, 5, 287, 288, + 289, 290, 6, 7, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 315, 316, 317, 318, + 319 /* 73 elements */ + }, + { + 0, 1, 1, 2, 3, 4, 1, 5, + 4, 3, 5, 8, 6, 9, 10, 11, + 12, 7, 104, 14, 105, 4, 10, 15, + 11, 6, 14, 8, 106, 107, 108, 15, + 109, 9, 55, 10, 1, 2, 1, 2, + 3, 12, 6, 2, 6, 7, 28, 7, + 15, 8, 5, 18, 29, 152, 77, 24, + 25, 26, 39, 108, 13, 109, 55, 56, + 57, 116, 11, 153, 234, 235, 118, 119, + 15 /* 73 elements */ + } +}; +const uint8_t ff_vc1_mv_diff_bits[4][73] = { + { + 6, 7, 7, 8, 14, 6, 5, 6, 7, 14, 14, 6, 6, 6, 8, 9, + 10, 9, 7, 7, 7, 14, 14, 10, 9, 10, 8, 10, 10, 14, 14, 14, + 13, 13, 13, 6, 3, 5, 6, 8, 9, 13, 5, 4, 4, 5, 7, 9, + 6, 5, 5, 5, 6, 9, 8, 5, 5, 5, 7, 10, 7, 7, 7, 7, + 7, 8, 10, 9, 8, 9, 9, 9, 3 /* 73 elements */ + }, + { + 5, 7, 7, 6, 6, 5, 5, 6, 7, 5, 7, 8, 8, 8, 14, 9, + 9, 9, 8, 14, 14, 9, 9, 14, 9, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 2, 3, 6, 8, 8, 6, 3, 4, 6, 8, 6, 9, + 6, 6, 6, 8, 8, 8, 14, 7, 7, 8, 7, 9, 13, 9, 8, 9, + 13, 9, 13, 13, 13, 13, 13, 13, 5 /* 73 elements */ + + }, + { + 3, 12, 12, 12, 12, 3, 4, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 1, 5, 11, 11, 11, 11, 4, 4, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11 /* 73 elements */ + }, + { + 15, 11, 15, 15, 15, 15, 12, 15, 12, 11, 12, 12, 15, 12, 12, 12, + 12, 15, 15, 12, 15, 10, 11, 12, 11, 10, 11, 10, 15, 15, 15, 11, + 15, 10, 14, 10, 4, 4, 5, 7, 8, 9, 5, 3, 4, 5, 6, 8, + 5, 4, 3, 5, 6, 8, 7, 5, 5, 5, 6, 7, 9, 7, 6, 6, + 6, 7, 10, 8, 8, 8, 7, 7, 4 /* 73 elements */ + } +}; + +/* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */ + +/* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */ +const int8_t ff_vc1_normal_zz[64] = { + 0, 8, 1, 2, 9, 16, 24, 17, + 10, 3, 4, 11, 18, 25, 32, 40, + 33, 48, 26, 19, 12, 5, 6, 13, + 20, 27, 34, 41, 56, 49, 57, 42, + 35, 28, 21, 14, 7, 15, 22, 29, + 36, 43, 50, 58, 51, 59, 44, 37, + 30, 23, 31, 38, 45, 52, 60, 53, + 61, 46, 39, 47, 54, 62, 55, 63 +}; + +const int8_t ff_vc1_horizontal_zz [64] = /* Table 227 */ +{ + 0, 1, 8, 2, 3, 9, 16, 24, + 17, 10, 4, 5, 11, 18, 25, 32, + 40, 48, 33, 26, 19, 12, 6, 7, + 13, 20, 27, 34, 41, 56, 49, 57, + 42, 35, 28, 21, 14, 15, 22, 29, + 36, 43, 50, 58, 51, 44, 37, 30, + 23, 31, 38, 45, 52, 59, 60, 53, + 46, 39, 47, 54, 61, 62, 55, 63 +}; + +const int8_t ff_vc1_vertical_zz [64] = /* Table 228 */ +{ + 0, 8, 16, 1, 24, 32, 40, 9, + 2, 3, 10, 17, 25, 48, 56, 41, + 33, 26, 18, 11, 4, 5, 12, 19, + 27, 34, 49, 57, 50, 42, 35, 28, + 20, 13, 6, 7, 14, 21, 29, 36, + 43, 51, 58, 59, 52, 44, 37, 30, + 22, 15, 23, 31, 38, 45, 60, 53, + 46, 39, 47, 54, 61, 62, 55, 63 +}; + +const int8_t ff_vc1_simple_progressive_8x8_zz [64] = +/* Table 229 */ +{ + 0, 8, 1, 2, 9, 16, 24, 17, + 10, 3, 4, 11, 18, 25, 32, 40, + 48, 56, 41, 33, 26, 19, 12, 5, + 6, 13, 20, 27, 34, 49, 57, 58, + 50, 42, 35, 28, 21, 14, 7, 15, + 22, 29, 36, 43, 51, 59, 60, 52, + 44, 37, 30, 23, 31, 38, 45, 53, + 61, 62, 54, 46, 39, 47, 55, 63 +}; + +const int8_t ff_vc1_simple_progressive_8x4_zz [32] = /* Table 230 */ +{ + 0, 1, 2, 8, 3, 9, 10, 16, + 4, 11, 17, 24, 18, 12, 5, 19, + 25, 13, 20, 26, 27, 6, 21, 28, + 14, 22, 29, 7, 30, 15, 23, 31 +}; + +const int8_t ff_vc1_simple_progressive_4x8_zz [32] = /* Table 231 */ +{ + 0, 8, 1, 16, + 9, 24, 17, 2, + 32, 10, 25, 40, + 18, 48, 33, 26, + 56, 41, 34, 3, + 49, 57, 11, 42, + 19, 50, 27, 58, + 35, 43, 51, 59 +}; + +/* Table 232 */ +const int8_t ff_vc1_simple_progressive_4x4_zz [16] = +{ + 0, 8, 16, 1, + 9, 24, 17, 2, + 10, 18, 25, 3, + 11, 26, 19, 27 +}; + +const int8_t ff_vc1_adv_progressive_8x4_zz [32] = /* Table 233 */ +{ + 0, 8, 1, 16, 2, 9, 10, 3, + 24, 17, 4, 11, 18, 12, 5, 19, + 25, 13, 20, 26, 27, 6, 21, 28, + 14, 22, 29, 7, 30, 15, 23, 31 +}; + +const int8_t ff_vc1_adv_progressive_4x8_zz [32] = /* Table 234 */ +{ + 0, 1, 8, 2, + 9, 16, 17, 24, + 10, 32, 25, 18, + 40, 3, 33, 26, + 48, 11, 56, 41, + 34, 49, 57, 42, + 19, 50, 27, 58, + 35, 43, 51, 59 +}; + +const int8_t ff_vc1_adv_interlaced_8x8_zz [64] = /* Table 235 */ +{ + 0, 8, 1, 16, 24, 9, 2, 32, + 40, 48, 56, 17, 10, 3, 25, 18, + 11, 4, 33, 41, 49, 57, 26, 34, + 42, 50, 58, 19, 12, 5, 27, 20, + 13, 6, 35, 28, 21, 14, 7, 15, + 22, 29, 36, 43, 51, 59, 60, 52, + 44, 37, 30, 23, 31, 38, 45, 53, + 61, 62, 54, 46, 39, 47, 55, 63 +}; + +const int8_t ff_vc1_adv_interlaced_8x4_zz [32] = /* Table 236 */ +{ + 0, 8, 16, 24, 1, 9, 2, 17, + 25, 10, 3, 18, 26, 4, 11, 19, + 12, 5, 13, 20, 27, 6, 21, 28, + 14, 22, 29, 7, 30, 15, 23, 31 +}; + +const int8_t ff_vc1_adv_interlaced_4x8_zz [32] = /* Table 237 */ +{ + 0, 1, 2, 8, + 16, 9, 24, 17, + 10, 3, 32, 40, + 48, 56, 25, 18, + 33, 26, 41, 34, + 49, 57, 11, 42, + 19, 50, 27, 58, + 35, 43, 51, 59 +}; + +const int8_t ff_vc1_adv_interlaced_4x4_zz [16] = /* Table 238 */ +{ + 0, 8, 16, 24, + 1, 9, 17, 2, + 25, 10, 18, 3, + 26, 11, 19, 27 +}; + + +/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */ +const int32_t ff_vc1_dqscale[63] = { +0x40000, 0x20000, 0x15555, 0x10000, 0xCCCD, 0xAAAB, 0x9249, 0x8000, + 0x71C7, 0x6666, 0x5D17, 0x5555, 0x4EC5, 0x4925, 0x4444, 0x4000, + 0x3C3C, 0x38E4, 0x35E5, 0x3333, 0x30C3, 0x2E8C, 0x2C86, 0x2AAB, + 0x28F6, 0x2762, 0x25ED, 0x2492, 0x234F, 0x2222, 0x2108, 0x2000, + 0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42, 0x199A, + 0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555, + 0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249, + 0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000 +}; diff --git a/contrib/ffmpeg/libavcodec/vc1data.h b/contrib/ffmpeg/libavcodec/vc1data.h index 9b0a854bf..5d995d754 100644 --- a/contrib/ffmpeg/libavcodec/vc1data.h +++ b/contrib/ffmpeg/libavcodec/vc1data.h @@ -25,302 +25,96 @@ * VC-1 tables. */ -#ifndef VC1DATA_H -#define VC1DATA_H +#ifndef FFMPEG_VC1DATA_H +#define FFMPEG_VC1DATA_H + +#include <stdint.h> +#include "bitstream.h" +#include "rational.h" + +/** Table for conversion between TTBLK and TTMB */ +extern const int ff_vc1_ttblk_to_tt[3][8]; + +extern const int ff_vc1_ttfrm_to_tt[4]; + +/** MV P mode - the 5th element is only used for mode 1 */ +extern const uint8_t ff_vc1_mv_pmode_table[2][5]; +extern const uint8_t ff_vc1_mv_pmode_table2[2][4]; + +extern const int ff_vc1_fps_nr[5], ff_vc1_fps_dr[2]; +extern const uint8_t ff_vc1_pquant_table[3][32]; + +/** @name VC-1 VLC tables and defines + * @todo TODO move this into the context + */ +//@{ +#define VC1_BFRACTION_VLC_BITS 7 +extern VLC ff_vc1_bfraction_vlc; +#define VC1_IMODE_VLC_BITS 4 +extern VLC ff_vc1_imode_vlc; +#define VC1_NORM2_VLC_BITS 3 +extern VLC ff_vc1_norm2_vlc; +#define VC1_NORM6_VLC_BITS 9 +extern VLC ff_vc1_norm6_vlc; +/* Could be optimized, one table only needs 8 bits */ +#define VC1_TTMB_VLC_BITS 9 //12 +extern VLC ff_vc1_ttmb_vlc[3]; +#define VC1_MV_DIFF_VLC_BITS 9 //15 +extern VLC ff_vc1_mv_diff_vlc[4]; +#define VC1_CBPCY_P_VLC_BITS 9 //14 +extern VLC ff_vc1_cbpcy_p_vlc[4]; +#define VC1_4MV_BLOCK_PATTERN_VLC_BITS 6 +extern VLC ff_vc1_4mv_block_pattern_vlc[4]; +#define VC1_TTBLK_VLC_BITS 5 +extern VLC ff_vc1_ttblk_vlc[3]; +#define VC1_SUBBLKPAT_VLC_BITS 6 +extern VLC ff_vc1_subblkpat_vlc[3]; + +extern VLC ff_vc1_ac_coeff_table[8]; +//@} + #if 0 //original bfraction from vc9data.h, not conforming to standard -/* Denominator used for vc1_bfraction_lut */ +/* Denominator used for ff_vc1_bfraction_lut */ #define B_FRACTION_DEN 840 /* bfraction is fractional, we scale to the GCD 3*5*7*8 = 840 */ -const int16_t vc1_bfraction_lut[23] = { - 420 /*1/2*/, 280 /*1/3*/, 560 /*2/3*/, 210 /*1/4*/, - 630 /*3/4*/, 168 /*1/5*/, 336 /*2/5*/, - 504 /*3/5*/, 672 /*4/5*/, 140 /*1/6*/, 700 /*5/6*/, - 120 /*1/7*/, 240 /*2/7*/, 360 /*3/7*/, 480 /*4/7*/, - 600 /*5/7*/, 720 /*6/7*/, 105 /*1/8*/, 315 /*3/8*/, - 525 /*5/8*/, 735 /*7/8*/, - -1 /*inv.*/, 0 /*BI fm*/ -}; +extern const int16_t ff_vc1_bfraction_lut[23]; #else -/* Denominator used for vc1_bfraction_lut */ +/* Denominator used for ff_vc1_bfraction_lut */ #define B_FRACTION_DEN 256 /* pre-computed scales for all bfractions and base=256 */ -static const int16_t vc1_bfraction_lut[23] = { - 128 /*1/2*/, 85 /*1/3*/, 170 /*2/3*/, 64 /*1/4*/, - 192 /*3/4*/, 51 /*1/5*/, 102 /*2/5*/, - 153 /*3/5*/, 204 /*4/5*/, 43 /*1/6*/, 215 /*5/6*/, - 37 /*1/7*/, 74 /*2/7*/, 111 /*3/7*/, 148 /*4/7*/, - 185 /*5/7*/, 222 /*6/7*/, 32 /*1/8*/, 96 /*3/8*/, - 160 /*5/8*/, 224 /*7/8*/, - -1 /*inv.*/, 0 /*BI fm*/ -}; +extern const int16_t ff_vc1_bfraction_lut[23]; #endif -static const uint8_t vc1_bfraction_bits[23] = { - 3, 3, 3, 3, - 3, 3, 3, - 7, 7, 7, 7, - 7, 7, 7, 7, - 7, 7, 7, 7, - 7, 7, - 7, 7 -}; -static const uint8_t vc1_bfraction_codes[23] = { - 0, 1, 2, 3, - 4, 5, 6, - 112, 113, 114, 115, - 116, 117, 118, 119, - 120, 121, 122, 123, - 124, 125, - 126, 127 -}; +extern const uint8_t ff_vc1_bfraction_bits[23]; +extern const uint8_t ff_vc1_bfraction_codes[23]; //Same as H.264 -static const AVRational vc1_pixel_aspect[16]={ - {0, 1}, - {1, 1}, - {12, 11}, - {10, 11}, - {16, 11}, - {40, 33}, - {24, 11}, - {20, 11}, - {32, 11}, - {80, 33}, - {18, 11}, - {15, 11}, - {64, 33}, - {160, 99}, - {0, 1}, - {0, 1} -}; +extern const AVRational ff_vc1_pixel_aspect[16]; /* BitPlane IMODE - such a small table... */ -static const uint8_t vc1_imode_codes[7] = { - 0, 2, 1, 3, 1, 2, 3 -}; -static const uint8_t vc1_imode_bits[7] = { - 4, 2, 3, 2, 4, 3, 3 -}; +extern const uint8_t ff_vc1_imode_codes[7]; +extern const uint8_t ff_vc1_imode_bits[7]; /* Normal-2 imode */ -static const uint8_t vc1_norm2_codes[4] = { - 0, 4, 5, 3 -}; -static const uint8_t vc1_norm2_bits[4] = { - 1, 3, 3, 2 -}; - -static const uint16_t vc1_norm6_codes[64] = { -0x001, 0x002, 0x003, 0x000, 0x004, 0x001, 0x002, 0x047, 0x005, 0x003, 0x004, 0x04B, 0x005, 0x04D, 0x04E, 0x30E, -0x006, 0x006, 0x007, 0x053, 0x008, 0x055, 0x056, 0x30D, 0x009, 0x059, 0x05A, 0x30C, 0x05C, 0x30B, 0x30A, 0x037, -0x007, 0x00A, 0x00B, 0x043, 0x00C, 0x045, 0x046, 0x309, 0x00D, 0x049, 0x04A, 0x308, 0x04C, 0x307, 0x306, 0x036, -0x00E, 0x051, 0x052, 0x305, 0x054, 0x304, 0x303, 0x035, 0x058, 0x302, 0x301, 0x034, 0x300, 0x033, 0x032, 0x007, -}; - -static const uint8_t vc1_norm6_bits[64] = { - 1, 4, 4, 8, 4, 8, 8, 10, 4, 8, 8, 10, 8, 10, 10, 13, - 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9, - 4, 8, 8, 10, 8, 10, 10, 13, 8, 10, 10, 13, 10, 13, 13, 9, - 8, 10, 10, 13, 10, 13, 13, 9, 10, 13, 13, 9, 13, 9, 9, 6, -}; +extern const uint8_t ff_vc1_norm2_codes[4]; +extern const uint8_t ff_vc1_norm2_bits[4]; +extern const uint16_t ff_vc1_norm6_codes[64]; +extern const uint8_t ff_vc1_norm6_bits[64]; /* Normal-6 imode */ -static const uint8_t vc1_norm6_spec[64][5] = { -{ 0, 1, 1 }, -{ 1, 2, 4 }, -{ 2, 3, 4 }, -{ 3, 0, 8 }, -{ 4, 4, 4 }, -{ 5, 1, 8 }, -{ 6, 2, 8 }, -{ 7, 2, 5, 7, 5 }, -{ 8, 5, 4 }, -{ 9, 3, 8 }, -{10, 4, 8 }, -{11, 2, 5, 11, 5 }, -{12, 5, 8 }, -{13, 2, 5, 13, 5 }, -{14, 2, 5, 14, 5 }, -{15, 3, 5, 14, 8 }, -{16, 6, 4 }, -{17, 6, 8 }, -{18, 7, 8 }, -{19, 2, 5, 19, 5 }, -{20, 8, 8 }, -{21, 2, 5, 21, 5 }, -{22, 2, 5, 22, 5 }, -{23, 3, 5, 13, 8 }, -{24, 9, 8 }, -{25, 2, 5, 25, 5 }, -{26, 2, 5, 26, 5 }, -{27, 3, 5, 12, 8 }, -{28, 2, 5, 28, 5 }, -{29, 3, 5, 11, 8 }, -{30, 3, 5, 10, 8 }, -{31, 3, 5, 7, 4 }, -{32, 7, 4 }, -{33, 10, 8 }, -{34, 11, 8 }, -{35, 2, 5, 3, 5 }, -{36, 12, 8 }, -{37, 2, 5, 5, 5 }, -{38, 2, 5, 6, 5 }, -{39, 3, 5, 9, 8 }, -{40, 13, 8 }, -{41, 2, 5, 9, 5 }, -{42, 2, 5, 10, 5 }, -{43, 3, 5, 8, 8 }, -{44, 2, 5, 12, 5 }, -{45, 3, 5, 7, 8 }, -{46, 3, 5, 6, 8 }, -{47, 3, 5, 6, 4 }, -{48, 14, 8 }, -{49, 2, 5, 17, 5 }, -{50, 2, 5, 18, 5 }, -{51, 3, 5, 5, 8 }, -{52, 2, 5, 20, 5 }, -{53, 3, 5, 4, 8 }, -{54, 3, 5, 3, 8 }, -{55, 3, 5, 5, 4 }, -{56, 2, 5, 24, 5 }, -{57, 3, 5, 2, 8 }, -{58, 3, 5, 1, 8 }, -{59, 3, 5, 4, 4 }, -{60, 3, 5, 0, 8 }, -{61, 3, 5, 3, 4 }, -{62, 3, 5, 2, 4 }, -{63, 3, 5, 1, 1 }, -}; +extern const uint8_t ff_vc1_norm6_spec[64][5]; /* 4MV Block pattern VLC tables */ -static const uint8_t vc1_4mv_block_pattern_codes[4][16] = { - { 14, 58, 59, 25, 12, 26, 15, 15, 13, 24, 27, 0, 28, 1, 2, 2}, - { 8, 18, 19, 4, 20, 5, 30, 11, 21, 31, 6, 12, 7, 13, 14, 0}, - { 15, 6, 7, 2, 8, 3, 28, 9, 10, 29, 4, 11, 5, 12, 13, 0}, - { 0, 11, 12, 4, 13, 5, 30, 16, 14, 31, 6, 17, 7, 18, 19, 10} -}; -static const uint8_t vc1_4mv_block_pattern_bits[4][16] = { - { 5, 6, 6, 5, 5, 5, 5, 4, 5, 5, 5, 3, 5, 3, 3, 2}, - { 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4, 4, 4, 4, 4, 2}, - { 4, 4, 4, 4, 4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 3}, - { 2, 4, 4, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 4} -}; +extern const uint8_t ff_vc1_4mv_block_pattern_codes[4][16]; +extern const uint8_t ff_vc1_4mv_block_pattern_bits[4][16]; -const uint8_t wmv3_dc_scale_table[32]={ - 0, 2, 4, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21 -}; +extern const uint8_t wmv3_dc_scale_table[32]; /* P-Picture CBPCY VLC tables */ -#if 1 // Looks like original tables are not conforming to standard at all. Are they used for old WMV? -static const uint16_t vc1_cbpcy_p_codes[4][64] = { - { - 0, 6, 15, 13, 13, 11, 3, 13, 5, 8, 49, 10, 12, 114, 102, 119, - 1, 54, 96, 8, 10, 111, 5, 15, 12, 10, 2, 12, 13, 115, 53, 63, - 1, 7, 1, 7, 14, 12, 4, 14, 1, 9, 97, 11, 7, 58, 52, 62, - 4, 103, 1, 9, 11, 56, 101, 118, 4, 110, 100, 30, 2, 5, 4, 3 - }, - { - 0, 9, 1, 18, 5, 14, 237, 26, 3, 121, 3, 22, 13, 16, 6, 30, - 2, 10, 1, 20, 12, 241, 5, 28, 16, 12, 3, 24, 28, 124, 239, 247, - 1, 240, 1, 19, 18, 15, 4, 27, 1, 122, 2, 23, 1, 17, 7, 31, - 1, 11, 2, 21, 19, 246, 238, 29, 17, 13, 236, 25, 58, 63, 8, 125 - }, - { - 0, 201, 25, 231, 5, 221, 1, 3, 2, 414, 2, 241, 16, 225, 195, 492, - 2, 412, 1, 240, 7, 224, 98, 245, 1, 220, 96, 5, 9, 230, 101, 247, - 1, 102, 1, 415, 24, 3, 2, 244, 3, 54, 3, 484, 17, 114, 200, 493, - 3, 413, 1, 4, 13, 113, 99, 485, 4, 111, 194, 243, 5, 29, 26, 31 - }, - { - 0, 28, 12, 44, 3, 36, 20, 52, 2, 32, 16, 48, 8, 40, 24, 28, - 1, 30, 14, 46, 6, 38, 22, 54, 3, 34, 18, 50, 10, 42, 26, 30, - 1, 29, 13, 45, 5, 37, 21, 53, 2, 33, 17, 49, 9, 41, 25, 29, - 1, 31, 15, 47, 7, 39, 23, 55, 4, 35, 19, 51, 11, 43, 27, 31 - } -}; - -static const uint8_t vc1_cbpcy_p_bits[4][64] = { - { - 13, 13, 7, 13, 7, 13, 13, 12, 6, 13, 7, 12, 6, 8, 8, 8, - 5, 7, 8, 12, 6, 8, 13, 12, 7, 13, 13, 12, 6, 8, 7, 7, - 6, 13, 8, 12, 7, 13, 13, 12, 7, 13, 8, 12, 5, 7, 7, 7, - 6, 8, 13, 12, 6, 7, 8, 8, 5, 8, 8, 6, 3, 3, 3, 2 - }, - { - 14, 13, 8, 13, 3, 13, 8, 13, 3, 7, 8, 13, 4, 13, 13, 13, - 3, 13, 13, 13, 4, 8, 13, 13, 5, 13, 13, 13, 5, 7, 8, 8, - 3, 8, 14, 13, 5, 13, 13, 13, 4, 7, 13, 13, 6, 13, 13, 13, - 5, 13, 8, 13, 5, 8, 8, 13, 5, 13, 8, 13, 6, 6, 13, 7 - }, - { - 13, 8, 6, 8, 4, 8, 13, 12, 4, 9, 8, 8, 5, 8, 8, 9, - 5, 9, 10, 8, 4, 8, 7, 8, 6, 8, 7, 13, 4, 8, 7, 8, - 5, 7, 8, 9, 6, 13, 13, 8, 4, 6, 8, 9, 5, 7, 8, 9, - 5, 9, 9, 13, 5, 7, 7, 9, 4, 7, 8, 8, 3, 5, 5, 5 - }, - { - 9, 9, 9, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 8, - 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, - 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8 - } -}; -#else -static const uint16_t vc1_cbpcy_p_codes[4][64] = { - { - 0, 1, 1, 4, 5, 1, 12, 4, 13, 14, 10, 11, 12, 7, 13, 2, - 15, 1, 96, 1, 49, 97, 2, 100, 3, 4, 5, 101, 102, 52, 53, 4, - 6, 7, 54, 103, 8, 9, 10, 110, 11, 12, 111, 56, 114, 58, 115, 5, - 13, 7, 8, 9, 10, 11, 12, 30, 13, 14, 15, 118, 119, 62, 63, 3 - }, - { - 0, 1, 2, 1, 3, 1, 16, 17, 5, 18, 12, 19, 13, 1, 28, 58, - 1, 1, 1, 2, 3, 2, 3, 236, 237, 4, 5, 238, 6, 7, 239, 8, - 9, 240, 10, 11, 121, 122, 12, 13, 14, 15, 241, 246, 16, 17, 124, 63, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 247, 125 - }, - { - 0, 1, 2, 3, 2, 3, 1, 4, 5, 24, 7, 13, 16, 17, 9, 5, - 25, 1, 1, 1, 2, 3, 96, 194, 1, 2, 98, 99, 195, 200, 101, 26, - 201, 102, 412, 413, 414, 54, 220, 111, 221, 3, 224, 113, 225, 114, 230, 29, - 231, 415, 240, 4, 241, 484, 5, 243, 3, 244, 245, 485, 492, 493, 247, 31 - }, - { - 0, 1, 1, 1, 2, 2, 3, 4, 3, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 28, 29, 30, 31 - } -}; -static const uint8_t vc1_cbpcy_p_bits[4][64] = { - { - 13, 6, 5, 6, 6, 7, 7, 5, 7, 7, 6, 6, 6, 5, 6, 3, - 7, 8, 8, 13, 7, 8, 13, 8, 13, 13, 13, 8, 8, 7, 7, 3, - 13, 13, 7, 8, 13, 13, 13, 8, 13, 13, 8, 7, 8, 7, 8, 3, - 13, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 8, 8, 7, 7, 2 - }, - { - 14, 3, 3, 5, 3, 4, 5, 5, 3, 5, 4, 5, 4, 6, 5, 6, - 8, 14, 13, 8, 8, 13, 13, 8, 8, 13, 13, 8, 13, 13, 8, 13, - 13, 8, 13, 13, 7, 7, 13, 13, 13, 13, 8, 8, 13, 13, 7, 6, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 7 - }, - { - 13, 5, 5, 5, 4, 4, 6, 4, 4, 6, 4, 5, 5, 5, 4, 3, - 6, 8, 10, 9, 8, 8, 7, 8, 13, 13, 7, 7, 8, 8, 7, 5, - 8, 7, 9, 9, 9, 6, 8, 7, 8, 13, 8, 7, 8, 7, 8, 5, - 8, 9, 8, 13, 8, 9, 13, 8, 12, 8, 8, 9, 9, 9, 8, 5 - }, - { - 9, 2, 3, 9, 2, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8 - } -}; -#endif +extern const uint16_t ff_vc1_cbpcy_p_codes[4][64]; +extern const uint8_t ff_vc1_cbpcy_p_bits[4][64]; /* MacroBlock Transform Type: 7.1.3.11, p89 * 8x8:B @@ -330,323 +124,40 @@ static const uint8_t vc1_cbpcy_p_bits[4][64] = { * 8x4:MB:btm 8x4:MB:top 8x4,MB,both * 4x8,MB,right 4x8,MB,left * 4x4,MB */ -static const uint16_t vc1_ttmb_codes[3][16] = { - { - 0x0003, - 0x002E, 0x005F, 0x0000, - 0x0016, 0x0015, 0x0001, - 0x0004, 0x0014, - 0x02F1, 0x0179, 0x017B, - 0x0BC0, 0x0BC1, 0x05E1, - 0x017A - }, - { - 0x0006, - 0x0006, 0x0003, 0x0007, - 0x000F, 0x000E, 0x0000, - 0x0002, 0x0002, - 0x0014, 0x0011, 0x000B, - 0x0009, 0x0021, 0x0015, - 0x0020 - }, - { - 0x0006, - 0x0000, 0x000E, 0x0005, - 0x0002, 0x0003, 0x0003, - 0x000F, 0x0002, - 0x0081, 0x0021, 0x0009, - 0x0101, 0x0041, 0x0011, - 0x0100 - } -}; +extern const uint16_t ff_vc1_ttmb_codes[3][16]; -static const uint8_t vc1_ttmb_bits[3][16] = { - { - 2, - 6, 7, 2, - 5, 5, 2, - 3, 5, - 10, 9, 9, - 12, 12, 11, - 9 - }, - { - 3, - 4, 4, 4, - 4, 4, 3, - 3, 2, - 7, 7, 6, - 6, 8, 7, - 8 - }, - { - 3, - 3, 4, 5, - 3, 3, 4, - 4, 2, - 10, 8, 6, - 11, 9, 7, - 11 - } -}; +extern const uint8_t ff_vc1_ttmb_bits[3][16]; /* TTBLK (Transform Type per Block) tables */ -static const uint8_t vc1_ttblk_codes[3][8] = { - { 0, 1, 3, 5, 16, 17, 18, 19}, - { 3, 0, 1, 2, 3, 5, 8, 9}, - { 1, 0, 1, 4, 6, 7, 10, 11} -}; -static const uint8_t vc1_ttblk_bits[3][8] = { - { 2, 2, 2, 3, 5, 5, 5, 5}, - { 2, 3, 3, 3, 3, 3, 4, 4}, - { 2, 3, 3, 3, 3, 3, 4, 4} -}; +extern const uint8_t ff_vc1_ttblk_codes[3][8]; +extern const uint8_t ff_vc1_ttblk_bits[3][8]; /* SUBBLKPAT tables, p93-94, reordered */ -static const uint8_t vc1_subblkpat_codes[3][15] = { - { 14, 12, 7, 11, 9, 26, 2, 10, 27, 8, 0, 6, 1, 15, 1}, - { 14, 0, 8, 15, 10, 4, 23, 13, 5, 9, 25, 3, 24, 22, 1}, - { 5, 6, 2, 2, 8, 0, 28, 3, 1, 3, 29, 1, 19, 18, 15} -}; -static const uint8_t vc1_subblkpat_bits[3][15] = { - { 5, 5, 5, 5, 5, 6, 4, 5, 6, 5, 4, 5, 4, 5, 1}, - { 4, 3, 4, 4, 4, 5, 5, 4, 5, 4, 5, 4, 5, 5, 2}, - { 3, 3, 4, 3, 4, 5, 5, 3, 5, 4, 5, 4, 5, 5, 4} -}; +extern const uint8_t ff_vc1_subblkpat_codes[3][15]; +extern const uint8_t ff_vc1_subblkpat_bits[3][15]; /* MV differential tables, p265 */ -static const uint16_t vc1_mv_diff_codes[4][73] = { - { - 0, 2, 3, 8, 576, 3, 2, 6, - 5, 577, 578, 7, 8, 9, 40, 19, - 37, 82, 21, 22, 23, 579, 580, 166, - 96, 167, 49, 194, 195, 581, 582, 583, - 292, 293, 294, 13, 2, 7, 24, 50, - 102, 295, 13, 7, 8, 18, 50, 103, - 38, 20, 21, 22, 39, 204, 103, 23, - 24, 25, 104, 410, 105, 106, 107, 108, - 109, 220, 411, 442, 222, 443, 446, 447, - 7 /* 73 elements */ - }, - { - 0, 4, 5, 3, 4, 3, 4, 5, - 20, 6, 21, 44, 45, 46, 3008, 95, - 112, 113, 57, 3009, 3010, 116, 117, 3011, - 118, 3012, 3013, 3014, 3015, 3016, 3017, 3018, - 3019, 3020, 3021, 3022, 1, 4, 15, 160, - 161, 41, 6, 11, 42, 162, 43, 119, - 56, 57, 58, 163, 236, 237, 3023, 119, - 120, 242, 122, 486, 1512, 487, 246, 494, - 1513, 495, 1514, 1515, 1516, 1517, 1518, 1519, - 31 /* 73 elements */ - }, - { - 0, 512, 513, 514, 515, 2, 3, 258, - 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 1, 5, 287, 288, - 289, 290, 6, 7, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 317, 318, - 319 /* 73 elements */ - }, - { - 0, 1, 1, 2, 3, 4, 1, 5, - 4, 3, 5, 8, 6, 9, 10, 11, - 12, 7, 104, 14, 105, 4, 10, 15, - 11, 6, 14, 8, 106, 107, 108, 15, - 109, 9, 55, 10, 1, 2, 1, 2, - 3, 12, 6, 2, 6, 7, 28, 7, - 15, 8, 5, 18, 29, 152, 77, 24, - 25, 26, 39, 108, 13, 109, 55, 56, - 57, 116, 11, 153, 234, 235, 118, 119, - 15 /* 73 elements */ - } -}; -static const uint8_t vc1_mv_diff_bits[4][73] = { - { - 6, 7, 7, 8, 14, 6, 5, 6, 7, 14, 14, 6, 6, 6, 8, 9, - 10, 9, 7, 7, 7, 14, 14, 10, 9, 10, 8, 10, 10, 14, 14, 14, - 13, 13, 13, 6, 3, 5, 6, 8, 9, 13, 5, 4, 4, 5, 7, 9, - 6, 5, 5, 5, 6, 9, 8, 5, 5, 5, 7, 10, 7, 7, 7, 7, - 7, 8, 10, 9, 8, 9, 9, 9, 3 /* 73 elements */ - }, - { - 5, 7, 7, 6, 6, 5, 5, 6, 7, 5, 7, 8, 8, 8, 14, 9, - 9, 9, 8, 14, 14, 9, 9, 14, 9, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 2, 3, 6, 8, 8, 6, 3, 4, 6, 8, 6, 9, - 6, 6, 6, 8, 8, 8, 14, 7, 7, 8, 7, 9, 13, 9, 8, 9, - 13, 9, 13, 13, 13, 13, 13, 13, 5 /* 73 elements */ - - }, - { - 3, 12, 12, 12, 12, 3, 4, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 1, 5, 11, 11, 11, 11, 4, 4, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11 /* 73 elements */ - }, - { - 15, 11, 15, 15, 15, 15, 12, 15, 12, 11, 12, 12, 15, 12, 12, 12, - 12, 15, 15, 12, 15, 10, 11, 12, 11, 10, 11, 10, 15, 15, 15, 11, - 15, 10, 14, 10, 4, 4, 5, 7, 8, 9, 5, 3, 4, 5, 6, 8, - 5, 4, 3, 5, 6, 8, 7, 5, 5, 5, 6, 7, 9, 7, 6, 6, - 6, 7, 10, 8, 8, 8, 7, 7, 4 /* 73 elements */ - } -}; +extern const uint16_t ff_vc1_mv_diff_codes[4][73]; +extern const uint8_t ff_vc1_mv_diff_bits[4][73]; /* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */ /* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */ -static const int8_t vc1_normal_zz[64] = { - 0, 8, 1, 2, 9, 16, 24, 17, - 10, 3, 4, 11, 18, 25, 32, 40, - 33, 48, 26, 19, 12, 5, 6, 13, - 20, 27, 34, 41, 56, 49, 57, 42, - 35, 28, 21, 14, 7, 15, 22, 29, - 36, 43, 50, 58, 51, 59, 44, 37, - 30, 23, 31, 38, 45, 52, 60, 53, - 61, 46, 39, 47, 54, 62, 55, 63 -}; - -static const int8_t vc1_horizontal_zz [64] = /* Table 227 */ -{ - 0, 1, 8, 2, 3, 9, 16, 24, - 17, 10, 4, 5, 11, 18, 25, 32, - 40, 48, 33, 26, 19, 12, 6, 7, - 13, 20, 27, 34, 41, 56, 49, 57, - 42, 35, 28, 21, 14, 15, 22, 29, - 36, 43, 50, 58, 51, 44, 37, 30, - 23, 31, 38, 45, 52, 59, 60, 53, - 46, 39, 47, 54, 61, 62, 55, 63 -}; - -static const int8_t vc1_vertical_zz [64] = /* Table 228 */ -{ - 0, 8, 16, 1, 24, 32, 40, 9, - 2, 3, 10, 17, 25, 48, 56, 41, - 33, 26, 18, 11, 4, 5, 12, 19, - 27, 34, 49, 57, 50, 42, 35, 28, - 20, 13, 6, 7, 14, 21, 29, 36, - 43, 51, 58, 59, 52, 44, 37, 30, - 22, 15, 23, 31, 38, 45, 60, 53, - 46, 39, 47, 54, 61, 62, 55, 63 -}; - -static const int8_t vc1_simple_progressive_8x8_zz [64] = -/* Table 229 */ -{ - 0, 8, 1, 2, 9, 16, 24, 17, - 10, 3, 4, 11, 18, 25, 32, 40, - 48, 56, 41, 33, 26, 19, 12, 5, - 6, 13, 20, 27, 34, 49, 57, 58, - 50, 42, 35, 28, 21, 14, 7, 15, - 22, 29, 36, 43, 51, 59, 60, 52, - 44, 37, 30, 23, 31, 38, 45, 53, - 61, 62, 54, 46, 39, 47, 55, 63 -}; - -static const int8_t vc1_simple_progressive_8x4_zz [32] = /* Table 230 */ -{ - 0, 1, 2, 8, 3, 9, 10, 16, - 4, 11, 17, 24, 18, 12, 5, 19, - 25, 13, 20, 26, 27, 6, 21, 28, - 14, 22, 29, 7, 30, 15, 23, 31 -}; - -static const int8_t vc1_simple_progressive_4x8_zz [32] = /* Table 231 */ -{ - 0, 8, 1, 16, - 9, 24, 17, 2, - 32, 10, 25, 40, - 18, 48, 33, 26, - 56, 41, 34, 3, - 49, 57, 11, 42, - 19, 50, 27, 58, - 35, 43, 51, 59 -}; - -/* Table 232 */ -static const int8_t vc1_simple_progressive_4x4_zz [16] = -{ - 0, 8, 16, 1, - 9, 24, 17, 2, - 10, 18, 25, 3, - 11, 26, 19, 27 -}; - -static const int8_t vc1_adv_progressive_8x4_zz [32] = /* Table 233 */ -{ - 0, 8, 1, 16, 2, 9, 10, 3, - 24, 17, 4, 11, 18, 12, 5, 19, - 25, 13, 20, 26, 27, 6, 21, 28, - 14, 22, 29, 7, 30, 15, 23, 31 -}; - -static const int8_t vc1_adv_progressive_4x8_zz [32] = /* Table 234 */ -{ - 0, 1, 8, 2, - 9, 16, 17, 24, - 10, 32, 25, 18, - 40, 3, 33, 26, - 48, 11, 56, 41, - 34, 49, 57, 42, - 19, 50, 27, 58, - 35, 43, 51, 59 -}; - -static const int8_t vc1_adv_interlaced_8x8_zz [64] = /* Table 235 */ -{ - 0, 8, 1, 16, 24, 9, 2, 32, - 40, 48, 56, 17, 10, 3, 25, 18, - 11, 4, 33, 41, 49, 57, 26, 34, - 42, 50, 58, 19, 12, 5, 27, 20, - 13, 6, 35, 28, 21, 14, 7, 15, - 22, 29, 36, 43, 51, 59, 60, 52, - 44, 37, 30, 23, 31, 38, 45, 53, - 61, 62, 54, 46, 39, 47, 55, 63 -}; - -static const int8_t vc1_adv_interlaced_8x4_zz [32] = /* Table 236 */ -{ - 0, 8, 16, 24, 1, 9, 2, 17, - 25, 10, 3, 18, 26, 4, 11, 19, - 12, 5, 13, 20, 27, 6, 21, 28, - 14, 22, 29, 7, 30, 15, 23, 31 -}; - -static const int8_t vc1_adv_interlaced_4x8_zz [32] = /* Table 237 */ -{ - 0, 1, 2, 8, - 16, 9, 24, 17, - 10, 3, 32, 40, - 48, 56, 25, 18, - 33, 26, 41, 34, - 49, 57, 11, 42, - 19, 50, 27, 58, - 35, 43, 51, 59 -}; - -static const int8_t vc1_adv_interlaced_4x4_zz [16] = /* Table 238 */ -{ - 0, 8, 16, 24, - 1, 9, 17, 2, - 25, 10, 18, 3, - 26, 11, 19, 27 -}; - +extern const int8_t ff_vc1_normal_zz[64]; +extern const int8_t ff_vc1_horizontal_zz [64]; +extern const int8_t ff_vc1_vertical_zz [64]; +extern const int8_t ff_vc1_simple_progressive_8x8_zz [64]; +extern const int8_t ff_vc1_simple_progressive_8x4_zz [32]; +extern const int8_t ff_vc1_simple_progressive_4x8_zz [32]; +extern const int8_t ff_vc1_simple_progressive_4x4_zz [16]; +extern const int8_t ff_vc1_adv_progressive_8x4_zz [32]; +extern const int8_t ff_vc1_adv_progressive_4x8_zz [32]; +extern const int8_t ff_vc1_adv_interlaced_8x8_zz [64]; +extern const int8_t ff_vc1_adv_interlaced_8x4_zz [32]; +extern const int8_t ff_vc1_adv_interlaced_4x8_zz [32]; +extern const int8_t ff_vc1_adv_interlaced_4x4_zz [16]; /* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */ -static const int32_t vc1_dqscale[63] = { -0x40000, 0x20000, 0x15555, 0x10000, 0xCCCD, 0xAAAB, 0x9249, 0x8000, - 0x71C7, 0x6666, 0x5D17, 0x5555, 0x4EC5, 0x4925, 0x4444, 0x4000, - 0x3C3C, 0x38E4, 0x35E5, 0x3333, 0x30C3, 0x2E8C, 0x2C86, 0x2AAB, - 0x28F6, 0x2762, 0x25ED, 0x2492, 0x234F, 0x2222, 0x2108, 0x2000, - 0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42, 0x199A, - 0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555, - 0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249, - 0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000 -}; -#endif /* VC1DATA_H */ +extern const int32_t ff_vc1_dqscale[63]; + +#endif /* FFMPEG_VC1DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/vc1dsp.c b/contrib/ffmpeg/libavcodec/vc1dsp.c index 6102c0960..8a1a83411 100644 --- a/contrib/ffmpeg/libavcodec/vc1dsp.c +++ b/contrib/ffmpeg/libavcodec/vc1dsp.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -91,8 +90,8 @@ static void vc1_inv_trans_8x8_c(DCTELEM block[64]) src = block; dst = block; for(i = 0; i < 8; i++){ - t1 = 12 * (src[0] + src[4]); - t2 = 12 * (src[0] - src[4]); + t1 = 12 * (src[0] + src[4]) + 4; + t2 = 12 * (src[0] - src[4]) + 4; t3 = 16 * src[2] + 6 * src[6]; t4 = 6 * src[2] - 16 * src[6]; @@ -106,14 +105,14 @@ static void vc1_inv_trans_8x8_c(DCTELEM block[64]) t3 = 9 * src[1] - 16 * src[3] + 4 * src[5] + 15 * src[7]; t4 = 4 * src[1] - 9 * src[3] + 15 * src[5] - 16 * src[7]; - dst[0] = (t5 + t1 + 4) >> 3; - dst[1] = (t6 + t2 + 4) >> 3; - dst[2] = (t7 + t3 + 4) >> 3; - dst[3] = (t8 + t4 + 4) >> 3; - dst[4] = (t8 - t4 + 4) >> 3; - dst[5] = (t7 - t3 + 4) >> 3; - dst[6] = (t6 - t2 + 4) >> 3; - dst[7] = (t5 - t1 + 4) >> 3; + dst[0] = (t5 + t1) >> 3; + dst[1] = (t6 + t2) >> 3; + dst[2] = (t7 + t3) >> 3; + dst[3] = (t8 + t4) >> 3; + dst[4] = (t8 - t4) >> 3; + dst[5] = (t7 - t3) >> 3; + dst[6] = (t6 - t2) >> 3; + dst[7] = (t5 - t1) >> 3; src += 8; dst += 8; @@ -122,8 +121,8 @@ static void vc1_inv_trans_8x8_c(DCTELEM block[64]) src = block; dst = block; for(i = 0; i < 8; i++){ - t1 = 12 * (src[ 0] + src[32]); - t2 = 12 * (src[ 0] - src[32]); + t1 = 12 * (src[ 0] + src[32]) + 64; + t2 = 12 * (src[ 0] - src[32]) + 64; t3 = 16 * src[16] + 6 * src[48]; t4 = 6 * src[16] - 16 * src[48]; @@ -137,14 +136,14 @@ static void vc1_inv_trans_8x8_c(DCTELEM block[64]) t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56]; t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56]; - dst[ 0] = (t5 + t1 + 64) >> 7; - dst[ 8] = (t6 + t2 + 64) >> 7; - dst[16] = (t7 + t3 + 64) >> 7; - dst[24] = (t8 + t4 + 64) >> 7; - dst[32] = (t8 - t4 + 64 + 1) >> 7; - dst[40] = (t7 - t3 + 64 + 1) >> 7; - dst[48] = (t6 - t2 + 64 + 1) >> 7; - dst[56] = (t5 - t1 + 64 + 1) >> 7; + dst[ 0] = (t5 + t1) >> 7; + dst[ 8] = (t6 + t2) >> 7; + dst[16] = (t7 + t3) >> 7; + dst[24] = (t8 + t4) >> 7; + dst[32] = (t8 - t4 + 1) >> 7; + dst[40] = (t7 - t3 + 1) >> 7; + dst[48] = (t6 - t2 + 1) >> 7; + dst[56] = (t5 - t1 + 1) >> 7; src++; dst++; @@ -153,19 +152,18 @@ static void vc1_inv_trans_8x8_c(DCTELEM block[64]) /** Do inverse transform on 8x4 part of block */ -static void vc1_inv_trans_8x4_c(DCTELEM block[64], int n) +static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, DCTELEM *block) { int i; register int t1,t2,t3,t4,t5,t6,t7,t8; DCTELEM *src, *dst; - int off; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - off = n * 32; - src = block + off; - dst = block + off; + src = block; + dst = block; for(i = 0; i < 4; i++){ - t1 = 12 * (src[0] + src[4]); - t2 = 12 * (src[0] - src[4]); + t1 = 12 * (src[0] + src[4]) + 4; + t2 = 12 * (src[0] - src[4]) + 4; t3 = 16 * src[2] + 6 * src[6]; t4 = 6 * src[2] - 16 * src[6]; @@ -179,73 +177,66 @@ static void vc1_inv_trans_8x4_c(DCTELEM block[64], int n) t3 = 9 * src[1] - 16 * src[3] + 4 * src[5] + 15 * src[7]; t4 = 4 * src[1] - 9 * src[3] + 15 * src[5] - 16 * src[7]; - dst[0] = (t5 + t1 + 4) >> 3; - dst[1] = (t6 + t2 + 4) >> 3; - dst[2] = (t7 + t3 + 4) >> 3; - dst[3] = (t8 + t4 + 4) >> 3; - dst[4] = (t8 - t4 + 4) >> 3; - dst[5] = (t7 - t3 + 4) >> 3; - dst[6] = (t6 - t2 + 4) >> 3; - dst[7] = (t5 - t1 + 4) >> 3; + dst[0] = (t5 + t1) >> 3; + dst[1] = (t6 + t2) >> 3; + dst[2] = (t7 + t3) >> 3; + dst[3] = (t8 + t4) >> 3; + dst[4] = (t8 - t4) >> 3; + dst[5] = (t7 - t3) >> 3; + dst[6] = (t6 - t2) >> 3; + dst[7] = (t5 - t1) >> 3; src += 8; dst += 8; } - src = block + off; - dst = block + off; + src = block; for(i = 0; i < 8; i++){ - t1 = 17 * (src[ 0] + src[16]); - t2 = 17 * (src[ 0] - src[16]); - t3 = 22 * src[ 8]; - t4 = 22 * src[24]; - t5 = 10 * src[ 8]; - t6 = 10 * src[24]; - - dst[ 0] = (t1 + t3 + t6 + 64) >> 7; - dst[ 8] = (t2 - t4 + t5 + 64) >> 7; - dst[16] = (t2 + t4 - t5 + 64) >> 7; - dst[24] = (t1 - t3 - t6 + 64) >> 7; + t1 = 17 * (src[ 0] + src[16]) + 64; + t2 = 17 * (src[ 0] - src[16]) + 64; + t3 = 22 * src[ 8] + 10 * src[24]; + t4 = 22 * src[24] - 10 * src[ 8]; + + dest[0*linesize] = cm[dest[0*linesize] + ((t1 + t3) >> 7)]; + dest[1*linesize] = cm[dest[1*linesize] + ((t2 - t4) >> 7)]; + dest[2*linesize] = cm[dest[2*linesize] + ((t2 + t4) >> 7)]; + dest[3*linesize] = cm[dest[3*linesize] + ((t1 - t3) >> 7)]; src ++; - dst ++; + dest++; } } /** Do inverse transform on 4x8 parts of block */ -static void vc1_inv_trans_4x8_c(DCTELEM block[64], int n) +static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, DCTELEM *block) { int i; register int t1,t2,t3,t4,t5,t6,t7,t8; DCTELEM *src, *dst; - int off; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - off = n * 4; - src = block + off; - dst = block + off; + src = block; + dst = block; for(i = 0; i < 8; i++){ - t1 = 17 * (src[0] + src[2]); - t2 = 17 * (src[0] - src[2]); - t3 = 22 * src[1]; - t4 = 22 * src[3]; - t5 = 10 * src[1]; - t6 = 10 * src[3]; - - dst[0] = (t1 + t3 + t6 + 4) >> 3; - dst[1] = (t2 - t4 + t5 + 4) >> 3; - dst[2] = (t2 + t4 - t5 + 4) >> 3; - dst[3] = (t1 - t3 - t6 + 4) >> 3; + t1 = 17 * (src[0] + src[2]) + 4; + t2 = 17 * (src[0] - src[2]) + 4; + t3 = 22 * src[1] + 10 * src[3]; + t4 = 22 * src[3] - 10 * src[1]; + + dst[0] = (t1 + t3) >> 3; + dst[1] = (t2 - t4) >> 3; + dst[2] = (t2 + t4) >> 3; + dst[3] = (t1 - t3) >> 3; src += 8; dst += 8; } - src = block + off; - dst = block + off; + src = block; for(i = 0; i < 4; i++){ - t1 = 12 * (src[ 0] + src[32]); - t2 = 12 * (src[ 0] - src[32]); + t1 = 12 * (src[ 0] + src[32]) + 64; + t2 = 12 * (src[ 0] - src[32]) + 64; t3 = 16 * src[16] + 6 * src[48]; t4 = 6 * src[16] - 16 * src[48]; @@ -259,70 +250,84 @@ static void vc1_inv_trans_4x8_c(DCTELEM block[64], int n) t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56]; t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56]; - dst[ 0] = (t5 + t1 + 64) >> 7; - dst[ 8] = (t6 + t2 + 64) >> 7; - dst[16] = (t7 + t3 + 64) >> 7; - dst[24] = (t8 + t4 + 64) >> 7; - dst[32] = (t8 - t4 + 64 + 1) >> 7; - dst[40] = (t7 - t3 + 64 + 1) >> 7; - dst[48] = (t6 - t2 + 64 + 1) >> 7; - dst[56] = (t5 - t1 + 64 + 1) >> 7; + dest[0*linesize] = cm[dest[0*linesize] + ((t5 + t1) >> 7)]; + dest[1*linesize] = cm[dest[1*linesize] + ((t6 + t2) >> 7)]; + dest[2*linesize] = cm[dest[2*linesize] + ((t7 + t3) >> 7)]; + dest[3*linesize] = cm[dest[3*linesize] + ((t8 + t4) >> 7)]; + dest[4*linesize] = cm[dest[4*linesize] + ((t8 - t4 + 1) >> 7)]; + dest[5*linesize] = cm[dest[5*linesize] + ((t7 - t3 + 1) >> 7)]; + dest[6*linesize] = cm[dest[6*linesize] + ((t6 - t2 + 1) >> 7)]; + dest[7*linesize] = cm[dest[7*linesize] + ((t5 - t1 + 1) >> 7)]; - src++; - dst++; + src ++; + dest++; } } /** Do inverse transform on 4x4 part of block */ -static void vc1_inv_trans_4x4_c(DCTELEM block[64], int n) +static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, DCTELEM *block) { int i; - register int t1,t2,t3,t4,t5,t6; + register int t1,t2,t3,t4; DCTELEM *src, *dst; - int off; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - off = (n&1) * 4 + (n&2) * 16; - src = block + off; - dst = block + off; + src = block; + dst = block; for(i = 0; i < 4; i++){ - t1 = 17 * (src[0] + src[2]); - t2 = 17 * (src[0] - src[2]); - t3 = 22 * src[1]; - t4 = 22 * src[3]; - t5 = 10 * src[1]; - t6 = 10 * src[3]; - - dst[0] = (t1 + t3 + t6 + 4) >> 3; - dst[1] = (t2 - t4 + t5 + 4) >> 3; - dst[2] = (t2 + t4 - t5 + 4) >> 3; - dst[3] = (t1 - t3 - t6 + 4) >> 3; + t1 = 17 * (src[0] + src[2]) + 4; + t2 = 17 * (src[0] - src[2]) + 4; + t3 = 22 * src[1] + 10 * src[3]; + t4 = 22 * src[3] - 10 * src[1]; + + dst[0] = (t1 + t3) >> 3; + dst[1] = (t2 - t4) >> 3; + dst[2] = (t2 + t4) >> 3; + dst[3] = (t1 - t3) >> 3; src += 8; dst += 8; } - src = block + off; - dst = block + off; + src = block; for(i = 0; i < 4; i++){ - t1 = 17 * (src[ 0] + src[16]); - t2 = 17 * (src[ 0] - src[16]); - t3 = 22 * src[ 8]; - t4 = 22 * src[24]; - t5 = 10 * src[ 8]; - t6 = 10 * src[24]; - - dst[ 0] = (t1 + t3 + t6 + 64) >> 7; - dst[ 8] = (t2 - t4 + t5 + 64) >> 7; - dst[16] = (t2 + t4 - t5 + 64) >> 7; - dst[24] = (t1 - t3 - t6 + 64) >> 7; + t1 = 17 * (src[ 0] + src[16]) + 64; + t2 = 17 * (src[ 0] - src[16]) + 64; + t3 = 22 * src[ 8] + 10 * src[24]; + t4 = 22 * src[24] - 10 * src[ 8]; + + dest[0*linesize] = cm[dest[0*linesize] + ((t1 + t3) >> 7)]; + dest[1*linesize] = cm[dest[1*linesize] + ((t2 - t4) >> 7)]; + dest[2*linesize] = cm[dest[2*linesize] + ((t2 + t4) >> 7)]; + dest[3*linesize] = cm[dest[3*linesize] + ((t1 - t3) >> 7)]; src ++; - dst ++; + dest++; } } /* motion compensation functions */ +/** Filter in case of 2 filters */ +#define VC1_MSPEL_FILTER_16B(DIR, TYPE) \ +static av_always_inline int vc1_mspel_ ## DIR ## _filter_16bits(const TYPE *src, int stride, int mode) \ +{ \ + switch(mode){ \ + case 0: /* no shift - should not occur */ \ + return 0; \ + case 1: /* 1/4 shift */ \ + return -4*src[-stride] + 53*src[0] + 18*src[stride] - 3*src[stride*2]; \ + case 2: /* 1/2 shift */ \ + return -src[-stride] + 9*src[0] + 9*src[stride] - src[stride*2]; \ + case 3: /* 3/4 shift */ \ + return -3*src[-stride] + 18*src[0] + 53*src[stride] - 4*src[stride*2]; \ + } \ + return 0; /* should not occur */ \ +} + +VC1_MSPEL_FILTER_16B(ver, uint8_t); +VC1_MSPEL_FILTER_16B(hor, int16_t); + /** Filter used to interpolate fractional pel values */ @@ -343,31 +348,58 @@ static av_always_inline int vc1_mspel_filter(const uint8_t *src, int stride, int /** Function used to do motion compensation with bicubic interpolation */ -static void vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int mode, int rnd) +static void vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int hmode, int vmode, int rnd) { - int i, j; - uint8_t tmp[8*11], *tptr; - int m, r; - - m = (mode & 3); - r = rnd; - src -= stride; - tptr = tmp; - for(j = 0; j < 11; j++) { - for(i = 0; i < 8; i++) - tptr[i] = av_clip_uint8(vc1_mspel_filter(src + i, 1, m, r)); - src += stride; - tptr += 8; + int i, j; + + if (vmode) { /* Horizontal filter to apply */ + int r; + + if (hmode) { /* Vertical filter to apply, output to tmp */ + static const int shift_value[] = { 0, 5, 1, 5 }; + int shift = (shift_value[hmode]+shift_value[vmode])>>1; + int16_t tmp[11*8], *tptr = tmp; + + r = (1<<(shift-1)) + rnd-1; + + src -= 1; + for(j = 0; j < 8; j++) { + for(i = 0; i < 11; i++) + tptr[i] = (vc1_mspel_ver_filter_16bits(src + i, stride, vmode)+r)>>shift; + src += stride; + tptr += 11; + } + + r = 64-rnd; + tptr = tmp+1; + for(j = 0; j < 8; j++) { + for(i = 0; i < 8; i++) + dst[i] = av_clip_uint8((vc1_mspel_hor_filter_16bits(tptr + i, 1, hmode)+r)>>7); + dst += stride; + tptr += 11; + } + + return; + } + else { /* No horizontal filter, output 8 lines to dst */ + r = 1-rnd; + + for(j = 0; j < 8; j++) { + for(i = 0; i < 8; i++) + dst[i] = av_clip_uint8(vc1_mspel_filter(src + i, stride, vmode, r)); + src += stride; + dst += stride; + } + return; + } } - r = 1 - rnd; - m = (mode >> 2) & 3; - tptr = tmp + 8; + /* Horizontal mode with no vertical mode */ for(j = 0; j < 8; j++) { for(i = 0; i < 8; i++) - dst[i] = av_clip_uint8(vc1_mspel_filter(tptr + i, 8, m, r)); + dst[i] = av_clip_uint8(vc1_mspel_filter(src + i, 1, hmode, rnd)); dst += stride; - tptr += 8; + src += stride; } } @@ -376,65 +408,29 @@ static void vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride, int mode, /* this one is defined in dsputil.c */ void ff_put_vc1_mspel_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int rnd); -static void ff_put_vc1_mspel_mc10_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x1, rnd); +#define PUT_VC1_MSPEL(a, b)\ +static void put_vc1_mspel_mc ## a ## b ##_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \ + vc1_mspel_mc(dst, src, stride, a, b, rnd); \ } -static void ff_put_vc1_mspel_mc20_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x2, rnd); -} +PUT_VC1_MSPEL(1, 0) +PUT_VC1_MSPEL(2, 0) +PUT_VC1_MSPEL(3, 0) -static void ff_put_vc1_mspel_mc30_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x3, rnd); -} - -static void ff_put_vc1_mspel_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x4, rnd); -} - -static void ff_put_vc1_mspel_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x5, rnd); -} - -static void ff_put_vc1_mspel_mc21_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x6, rnd); -} - -static void ff_put_vc1_mspel_mc31_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x7, rnd); -} +PUT_VC1_MSPEL(0, 1) +PUT_VC1_MSPEL(1, 1) +PUT_VC1_MSPEL(2, 1) +PUT_VC1_MSPEL(3, 1) -static void ff_put_vc1_mspel_mc02_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x8, rnd); -} - -static void ff_put_vc1_mspel_mc12_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0x9, rnd); -} +PUT_VC1_MSPEL(0, 2) +PUT_VC1_MSPEL(1, 2) +PUT_VC1_MSPEL(2, 2) +PUT_VC1_MSPEL(3, 2) -static void ff_put_vc1_mspel_mc22_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xA, rnd); -} - -static void ff_put_vc1_mspel_mc32_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xB, rnd); -} - -static void ff_put_vc1_mspel_mc03_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xC, rnd); -} - -static void ff_put_vc1_mspel_mc13_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xD, rnd); -} - -static void ff_put_vc1_mspel_mc23_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xE, rnd); -} - -static void ff_put_vc1_mspel_mc33_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { - vc1_mspel_mc(dst, src, stride, 0xF, rnd); -} +PUT_VC1_MSPEL(0, 3) +PUT_VC1_MSPEL(1, 3) +PUT_VC1_MSPEL(2, 3) +PUT_VC1_MSPEL(3, 3) void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) { dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c; @@ -445,19 +441,19 @@ void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) { dsp->vc1_v_overlap = vc1_v_overlap_c; dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_c; - dsp->put_vc1_mspel_pixels_tab[ 1] = ff_put_vc1_mspel_mc10_c; - dsp->put_vc1_mspel_pixels_tab[ 2] = ff_put_vc1_mspel_mc20_c; - dsp->put_vc1_mspel_pixels_tab[ 3] = ff_put_vc1_mspel_mc30_c; - dsp->put_vc1_mspel_pixels_tab[ 4] = ff_put_vc1_mspel_mc01_c; - dsp->put_vc1_mspel_pixels_tab[ 5] = ff_put_vc1_mspel_mc11_c; - dsp->put_vc1_mspel_pixels_tab[ 6] = ff_put_vc1_mspel_mc21_c; - dsp->put_vc1_mspel_pixels_tab[ 7] = ff_put_vc1_mspel_mc31_c; - dsp->put_vc1_mspel_pixels_tab[ 8] = ff_put_vc1_mspel_mc02_c; - dsp->put_vc1_mspel_pixels_tab[ 9] = ff_put_vc1_mspel_mc12_c; - dsp->put_vc1_mspel_pixels_tab[10] = ff_put_vc1_mspel_mc22_c; - dsp->put_vc1_mspel_pixels_tab[11] = ff_put_vc1_mspel_mc32_c; - dsp->put_vc1_mspel_pixels_tab[12] = ff_put_vc1_mspel_mc03_c; - dsp->put_vc1_mspel_pixels_tab[13] = ff_put_vc1_mspel_mc13_c; - dsp->put_vc1_mspel_pixels_tab[14] = ff_put_vc1_mspel_mc23_c; - dsp->put_vc1_mspel_pixels_tab[15] = ff_put_vc1_mspel_mc33_c; + dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c; + dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_c; + dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_c; + dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_c; + dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_c; + dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_c; + dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_c; + dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_c; + dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_c; + dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_c; + dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_c; + dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_c; + dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_c; + dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_c; + dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_c; } diff --git a/contrib/ffmpeg/libavcodec/vcr1.c b/contrib/ffmpeg/libavcodec/vcr1.c index 62bf12320..30fc302d1 100644 --- a/contrib/ffmpeg/libavcodec/vcr1.c +++ b/contrib/ffmpeg/libavcodec/vcr1.c @@ -39,12 +39,12 @@ typedef struct VCR1Context{ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { VCR1Context * const a = avctx->priv_data; AVFrame *picture = data; AVFrame * const p= (AVFrame*)&a->picture; - uint8_t *bytestream= buf; + const uint8_t *bytestream= buf; int i, x, y; if(p->data[0]) diff --git a/contrib/ffmpeg/libavcodec/vmdav.c b/contrib/ffmpeg/libavcodec/vmdav.c index 69e8a44d3..d39ae91e3 100644 --- a/contrib/ffmpeg/libavcodec/vmdav.c +++ b/contrib/ffmpeg/libavcodec/vmdav.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -45,7 +44,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -63,21 +61,22 @@ typedef struct VmdVideoContext { AVFrame frame; AVFrame prev_frame; - unsigned char *buf; + const unsigned char *buf; int size; unsigned char palette[PALETTE_COUNT * 4]; unsigned char *unpack_buffer; int unpack_buffer_size; + int x_off, y_off; } VmdVideoContext; #define QUEUE_SIZE 0x1000 #define QUEUE_MASK 0x0FFF -static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len) +static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_len) { - unsigned char *s; + const unsigned char *s; unsigned char *d; unsigned char *d_end; unsigned char queue[QUEUE_SIZE]; @@ -145,10 +144,10 @@ static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len) } } -static int rle_unpack(unsigned char *src, unsigned char *dest, +static int rle_unpack(const unsigned char *src, unsigned char *dest, int src_len, int dest_len) { - unsigned char *ps; + const unsigned char *ps; unsigned char *pd; int i, l; unsigned char *dest_end = dest + dest_len; @@ -191,9 +190,9 @@ static void vmd_decode(VmdVideoContext *s) unsigned char r, g, b; /* point to the start of the encoded data */ - unsigned char *p = s->buf + 16; + const unsigned char *p = s->buf + 16; - unsigned char *pb; + const unsigned char *pb; unsigned char meth; unsigned char *dp; /* pointer to current frame */ unsigned char *pp; /* pointer to previous frame */ @@ -209,6 +208,15 @@ static void vmd_decode(VmdVideoContext *s) frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; + if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && + (frame_x || frame_y)) { + + s->x_off = frame_x; + s->y_off = frame_y; + } + frame_x -= s->x_off; + frame_y -= s->y_off; + /* if only a certain region will be updated, copy the entire previous * frame before the decode */ if (frame_x || frame_y || (frame_width != s->avctx->width) || @@ -318,7 +326,7 @@ static void vmd_decode(VmdVideoContext *s) static int vmdvideo_decode_init(AVCodecContext *avctx) { - VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data; + VmdVideoContext *s = avctx->priv_data; int i; unsigned int *palette32; int palette_index = 0; @@ -328,7 +336,6 @@ static int vmdvideo_decode_init(AVCodecContext *avctx) s->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; dsputil_init(&s->dsp, avctx); /* make sure the VMD header made it */ @@ -361,9 +368,9 @@ static int vmdvideo_decode_init(AVCodecContext *avctx) static int vmdvideo_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data; + VmdVideoContext *s = avctx->priv_data; s->buf = buf; s->size = buf_size; @@ -382,14 +389,13 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, /* make the palette available on the way out */ memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); - if (s->prev_frame.data[0]) - avctx->release_buffer(avctx, &s->prev_frame); - /* shuffle frames */ - s->prev_frame = s->frame; + FFSWAP(AVFrame, s->frame, s->prev_frame); + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; + *(AVFrame*)data = s->prev_frame; /* report that the buffer was completely consumed */ return buf_size; @@ -397,7 +403,7 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, static int vmdvideo_decode_end(AVCodecContext *avctx) { - VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data; + VmdVideoContext *s = avctx->priv_data; if (s->prev_frame.data[0]) avctx->release_buffer(avctx, &s->prev_frame); @@ -437,7 +443,7 @@ static uint16_t vmdaudio_table[128] = { static int vmdaudio_decode_init(AVCodecContext *avctx) { - VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data; + VmdAudioContext *s = avctx->priv_data; s->avctx = avctx; s->channels = avctx->channels; @@ -451,7 +457,7 @@ static int vmdaudio_decode_init(AVCodecContext *avctx) } static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, - uint8_t *buf, int stereo) + const uint8_t *buf, int stereo) { int i; int chan = 0; @@ -462,14 +468,14 @@ static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; else s->predictors[chan] += vmdaudio_table[buf[i]]; - s->predictors[chan] = av_clip(s->predictors[chan], -32768, 32767); + s->predictors[chan] = av_clip_int16(s->predictors[chan]); out[i] = s->predictors[chan]; chan ^= stereo; } } static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, - uint8_t *buf, int silence) + const uint8_t *buf, int silence) { int bytes_decoded = 0; int i; @@ -516,13 +522,13 @@ static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data; + VmdAudioContext *s = avctx->priv_data; unsigned char *output_samples = (unsigned char *)data; /* point to the start of the encoded data */ - unsigned char *p = buf + 16; + const unsigned char *p = buf + 16; if (buf_size < 16) return buf_size; diff --git a/contrib/ffmpeg/libavcodec/vmnc.c b/contrib/ffmpeg/libavcodec/vmnc.c index b430a7e66..12f414856 100644 --- a/contrib/ffmpeg/libavcodec/vmnc.c +++ b/contrib/ffmpeg/libavcodec/vmnc.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -29,7 +28,6 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" enum EncTypes { @@ -72,7 +70,7 @@ typedef struct VmncContext { } VmncContext; /* read pixel value from stream */ -static av_always_inline int vmnc_get_pixel(uint8_t* buf, int bpp, int be) { +static av_always_inline int vmnc_get_pixel(const uint8_t* buf, int bpp, int be) { switch(bpp * 2 + be) { case 2: case 3: return *buf; @@ -84,7 +82,7 @@ static av_always_inline int vmnc_get_pixel(uint8_t* buf, int bpp, int be) { } } -static void load_cursor(VmncContext *c, uint8_t *src) +static void load_cursor(VmncContext *c, const uint8_t *src) { int i, j, p; const int bpp = c->bpp2; @@ -171,7 +169,7 @@ static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy) } } -/* fill rectangle with given colour */ +/* fill rectangle with given color */ static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, int w, int h, int color, int bpp, int stride) { int i, j; @@ -202,7 +200,7 @@ static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, int w, int } } -static av_always_inline void paint_raw(uint8_t *dst, int w, int h, uint8_t* src, int bpp, int be, int stride) +static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t* src, int bpp, int be, int stride) { int i, j, p; for(j = 0; j < h; j++) { @@ -225,14 +223,14 @@ static av_always_inline void paint_raw(uint8_t *dst, int w, int h, uint8_t* src, } } -static int decode_hextile(VmncContext *c, uint8_t* dst, uint8_t* src, int ssize, int w, int h, int stride) +static int decode_hextile(VmncContext *c, uint8_t* dst, const uint8_t* src, int ssize, int w, int h, int stride) { int i, j, k; int bg = 0, fg = 0, rects, color, flags, xy, wh; const int bpp = c->bpp2; uint8_t *dst2; int bw = 16, bh = 16; - uint8_t *ssrc=src; + const uint8_t *ssrc=src; for(j = 0; j < h; j += 16) { dst2 = dst; @@ -285,11 +283,11 @@ static int decode_hextile(VmncContext *c, uint8_t* dst, uint8_t* src, int ssize, return src - ssrc; } -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { - VmncContext * const c = (VmncContext *)avctx->priv_data; + VmncContext * const c = avctx->priv_data; uint8_t *outptr; - uint8_t *src = buf; + const uint8_t *src = buf; int dx, dy, w, h, depth, enc, chunks, res, size_left; c->pic.reference = 1; @@ -460,7 +458,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 */ static int decode_init(AVCodecContext *avctx) { - VmncContext * const c = (VmncContext *)avctx->priv_data; + VmncContext * const c = avctx->priv_data; c->avctx = avctx; @@ -500,7 +498,7 @@ static int decode_init(AVCodecContext *avctx) */ static int decode_end(AVCodecContext *avctx) { - VmncContext * const c = (VmncContext *)avctx->priv_data; + VmncContext * const c = avctx->priv_data; if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); diff --git a/contrib/ffmpeg/libavcodec/vorbis.c b/contrib/ffmpeg/libavcodec/vorbis.c index 7e5f0d349..76d6308b5 100644 --- a/contrib/ffmpeg/libavcodec/vorbis.c +++ b/contrib/ffmpeg/libavcodec/vorbis.c @@ -1,6 +1,6 @@ /** * @file vorbis.c - * Vorbis I decoder + * Common code for Vorbis I encoder and decoder * @author Denes Balatoni ( dbalatoni programozo hu ) * This file is part of FFmpeg. @@ -18,154 +18,20 @@ * 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 - * */ #undef V_DEBUG //#define V_DEBUG -//#define AV_DEBUG(...) av_log(NULL, AV_LOG_INFO, __VA_ARGS__) - -#include <math.h> #define ALT_BITSTREAM_READER_LE #include "avcodec.h" #include "bitstream.h" -#include "dsputil.h" #include "vorbis.h" -#include "xiph.h" - -#define V_NB_BITS 8 -#define V_NB_BITS2 11 -#define V_MAX_VLCS (1<<16) - -#ifndef V_DEBUG -#define AV_DEBUG(...) -#endif - -#undef NDEBUG -#include <assert.h> - -typedef struct { - uint_fast8_t dimensions; - uint_fast8_t lookup_type; - uint_fast8_t maxdepth; - VLC vlc; - float *codevectors; - unsigned int nb_bits; -} vorbis_codebook; - -typedef union vorbis_floor_u vorbis_floor_data; -typedef struct vorbis_floor0_s vorbis_floor0; -typedef struct vorbis_floor1_s vorbis_floor1; -struct vorbis_context_s; -typedef -uint_fast8_t (* vorbis_floor_decode_func) - (struct vorbis_context_s *, vorbis_floor_data *, float *); -typedef struct { - uint_fast8_t floor_type; - vorbis_floor_decode_func decode; - union vorbis_floor_u - { - struct vorbis_floor0_s - { - uint_fast8_t order; - uint_fast16_t rate; - uint_fast16_t bark_map_size; - int_fast32_t * map[2]; - uint_fast32_t map_size[2]; - uint_fast8_t amplitude_bits; - uint_fast8_t amplitude_offset; - uint_fast8_t num_books; - uint_fast8_t * book_list; - float * lsp; - } t0; - struct vorbis_floor1_s - { - uint_fast8_t partitions; - uint_fast8_t maximum_class; - uint_fast8_t partition_class[32]; - uint_fast8_t class_dimensions[16]; - uint_fast8_t class_subclasses[16]; - uint_fast8_t class_masterbook[16]; - int_fast16_t subclass_books[16][8]; - uint_fast8_t multiplier; - uint_fast16_t x_list_dim; - floor1_entry_t * list; - } t1; - } data; -} vorbis_floor; -typedef struct { - uint_fast16_t type; - uint_fast32_t begin; - uint_fast32_t end; - uint_fast32_t partition_size; - uint_fast8_t classifications; - uint_fast8_t classbook; - int_fast16_t books[64][8]; - uint_fast8_t maxpass; -} vorbis_residue; - -typedef struct { - uint_fast8_t submaps; - uint_fast16_t coupling_steps; - uint_fast8_t *magnitude; - uint_fast8_t *angle; - uint_fast8_t *mux; - uint_fast8_t submap_floor[16]; - uint_fast8_t submap_residue[16]; -} vorbis_mapping; - -typedef struct { - uint_fast8_t blockflag; - uint_fast16_t windowtype; - uint_fast16_t transformtype; - uint_fast8_t mapping; -} vorbis_mode; - -typedef struct vorbis_context_s { - AVCodecContext *avccontext; - GetBitContext gb; - DSPContext dsp; - - MDCTContext mdct[2]; - uint_fast8_t first_frame; - uint_fast32_t version; - uint_fast8_t audio_channels; - uint_fast32_t audio_samplerate; - uint_fast32_t bitrate_maximum; - uint_fast32_t bitrate_nominal; - uint_fast32_t bitrate_minimum; - uint_fast32_t blocksize[2]; - const float * win[2]; - uint_fast16_t codebook_count; - vorbis_codebook *codebooks; - uint_fast8_t floor_count; - vorbis_floor *floors; - uint_fast8_t residue_count; - vorbis_residue *residues; - uint_fast8_t mapping_count; - vorbis_mapping *mappings; - uint_fast8_t mode_count; - vorbis_mode *modes; - uint_fast8_t mode_number; // mode number for the current packet - float *channel_residues; - float *channel_floors; - float *saved; - uint_fast16_t saved_start; - float *ret; - float *buf; - float *buf_tmp; - uint_fast32_t add_bias; // for float->int conversion - uint_fast32_t exp_bias; -} vorbis_context; /* Helper functions */ -#define BARK(x) \ - (13.1f*atan(0.00074f*(x))+2.24f*atan(1.85e-8f*(x)*(x))+1e-4f*(x)) - unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n) { // x^(1/n) unsigned int ret=0, i, j; @@ -177,14 +43,6 @@ unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n) { // x^(1/n) return (ret-1); } -static float vorbisfloat2float(uint_fast32_t val) { - double mant=val&0x1fffff; - long exp=(val&0x7fe00000L)>>21; - if (val&0x80000000) mant=-mant; - return(ldexp(mant, exp-20-768)); -} - - // Generate vlc codes from vorbis huffman code lengths int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, uint_fast32_t num) { @@ -283,955 +141,23 @@ void ff_vorbis_ready_floor1_list(floor1_entry_t * list, int values) { } } -// Free all allocated memory ----------------------------------------- - -static void vorbis_free(vorbis_context *vc) { - int_fast16_t i; - - av_freep(&vc->channel_residues); - av_freep(&vc->channel_floors); - av_freep(&vc->saved); - av_freep(&vc->ret); - av_freep(&vc->buf); - av_freep(&vc->buf_tmp); - - av_freep(&vc->residues); - av_freep(&vc->modes); - - ff_mdct_end(&vc->mdct[0]); - ff_mdct_end(&vc->mdct[1]); - - for(i=0;i<vc->codebook_count;++i) { - av_free(vc->codebooks[i].codevectors); - free_vlc(&vc->codebooks[i].vlc); - } - av_freep(&vc->codebooks); - - for(i=0;i<vc->floor_count;++i) { - if(vc->floors[i].floor_type==0) { - av_free(vc->floors[i].data.t0.map[0]); - av_free(vc->floors[i].data.t0.map[1]); - av_free(vc->floors[i].data.t0.book_list); - av_free(vc->floors[i].data.t0.lsp); - } - else { - av_free(vc->floors[i].data.t1.list); - } - } - av_freep(&vc->floors); - - for(i=0;i<vc->mapping_count;++i) { - av_free(vc->mappings[i].magnitude); - av_free(vc->mappings[i].angle); - av_free(vc->mappings[i].mux); - } - av_freep(&vc->mappings); - - if(vc->exp_bias){ - av_freep(&vc->win[0]); - av_freep(&vc->win[1]); - } -} - -// Parse setup header ------------------------------------------------- - -// Process codebooks part - -static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) { - uint_fast16_t cb; - uint8_t *tmp_vlc_bits; - uint32_t *tmp_vlc_codes; - GetBitContext *gb=&vc->gb; - - vc->codebook_count=get_bits(gb,8)+1; - - AV_DEBUG(" Codebooks: %d \n", vc->codebook_count); - - vc->codebooks=(vorbis_codebook *)av_mallocz(vc->codebook_count * sizeof(vorbis_codebook)); - tmp_vlc_bits=(uint8_t *)av_mallocz(V_MAX_VLCS * sizeof(uint8_t)); - tmp_vlc_codes=(uint32_t *)av_mallocz(V_MAX_VLCS * sizeof(uint32_t)); - - for(cb=0;cb<vc->codebook_count;++cb) { - vorbis_codebook *codebook_setup=&vc->codebooks[cb]; - uint_fast8_t ordered; - uint_fast32_t t, used_entries=0; - uint_fast32_t entries; - - AV_DEBUG(" %d. Codebook \n", cb); - - if (get_bits(gb, 24)!=0x564342) { - av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook setup data corrupt. \n", cb); - goto error; - } - - codebook_setup->dimensions=get_bits(gb, 16); - if (codebook_setup->dimensions>16) { - av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook's dimension is too large (%d). \n", cb, codebook_setup->dimensions); - goto error; - } - entries=get_bits(gb, 24); - if (entries>V_MAX_VLCS) { - av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook has too many entries (%"PRIdFAST32"). \n", cb, entries); - goto error; - } - - ordered=get_bits1(gb); - - AV_DEBUG(" codebook_dimensions %d, codebook_entries %d \n", codebook_setup->dimensions, entries); - - if (!ordered) { - uint_fast16_t ce; - uint_fast8_t flag; - uint_fast8_t sparse=get_bits1(gb); - - AV_DEBUG(" not ordered \n"); - - if (sparse) { - AV_DEBUG(" sparse \n"); - - used_entries=0; - for(ce=0;ce<entries;++ce) { - flag=get_bits1(gb); - if (flag) { - tmp_vlc_bits[ce]=get_bits(gb, 5)+1; - ++used_entries; - } - else tmp_vlc_bits[ce]=0; - } - } else { - AV_DEBUG(" not sparse \n"); - - used_entries=entries; - for(ce=0;ce<entries;++ce) { - tmp_vlc_bits[ce]=get_bits(gb, 5)+1; - } - } - } else { - uint_fast16_t current_entry=0; - uint_fast8_t current_length=get_bits(gb, 5)+1; - - AV_DEBUG(" ordered, current length: %d \n", current_length); //FIXME - - used_entries=entries; - for(;current_entry<used_entries;++current_length) { - uint_fast16_t i, number; - - AV_DEBUG(" number bits: %d ", ilog(entries - current_entry)); - - number=get_bits(gb, ilog(entries - current_entry)); - - AV_DEBUG(" number: %d \n", number); - - for(i=current_entry;i<number+current_entry;++i) { - if (i<used_entries) tmp_vlc_bits[i]=current_length; - } - - current_entry+=number; - } - if (current_entry>used_entries) { - av_log(vc->avccontext, AV_LOG_ERROR, " More codelengths than codes in codebook. \n"); - goto error; - } - } - - codebook_setup->lookup_type=get_bits(gb, 4); - - AV_DEBUG(" lookup type: %d : %s \n", codebook_setup->lookup_type, codebook_setup->lookup_type ? "vq" : "no lookup" ); - -// If the codebook is used for (inverse) VQ, calculate codevectors. - - if (codebook_setup->lookup_type==1) { - uint_fast16_t i, j, k; - uint_fast16_t codebook_lookup_values=ff_vorbis_nth_root(entries, codebook_setup->dimensions); - uint_fast16_t codebook_multiplicands[codebook_lookup_values]; - - float codebook_minimum_value=vorbisfloat2float(get_bits_long(gb, 32)); - float codebook_delta_value=vorbisfloat2float(get_bits_long(gb, 32)); - uint_fast8_t codebook_value_bits=get_bits(gb, 4)+1; - uint_fast8_t codebook_sequence_p=get_bits1(gb); - - AV_DEBUG(" We expect %d numbers for building the codevectors. \n", codebook_lookup_values); - AV_DEBUG(" delta %f minmum %f \n", codebook_delta_value, codebook_minimum_value); - - for(i=0;i<codebook_lookup_values;++i) { - codebook_multiplicands[i]=get_bits(gb, codebook_value_bits); - - AV_DEBUG(" multiplicands*delta+minmum : %e \n", (float)codebook_multiplicands[i]*codebook_delta_value+codebook_minimum_value); - AV_DEBUG(" multiplicand %d \n", codebook_multiplicands[i]); - } - -// Weed out unused vlcs and build codevector vector - codebook_setup->codevectors=(float *)av_mallocz(used_entries*codebook_setup->dimensions * sizeof(float)); - for(j=0, i=0;i<entries;++i) { - uint_fast8_t dim=codebook_setup->dimensions; - - if (tmp_vlc_bits[i]) { - float last=0.0; - uint_fast32_t lookup_offset=i; - -#ifdef V_DEBUG - av_log(vc->avccontext, AV_LOG_INFO, "Lookup offset %d ,", i); -#endif - - for(k=0;k<dim;++k) { - uint_fast32_t multiplicand_offset = lookup_offset % codebook_lookup_values; - codebook_setup->codevectors[j*dim+k]=codebook_multiplicands[multiplicand_offset]*codebook_delta_value+codebook_minimum_value+last; - if (codebook_sequence_p) { - last=codebook_setup->codevectors[j*dim+k]; - } - lookup_offset/=codebook_lookup_values; - } - tmp_vlc_bits[j]=tmp_vlc_bits[i]; - -#ifdef V_DEBUG - av_log(vc->avccontext, AV_LOG_INFO, "real lookup offset %d, vector: ", j); - for(k=0;k<dim;++k) { - av_log(vc->avccontext, AV_LOG_INFO, " %f ", codebook_setup->codevectors[j*dim+k]); - } - av_log(vc->avccontext, AV_LOG_INFO, "\n"); -#endif - - ++j; - } - } - if (j!=used_entries) { - av_log(vc->avccontext, AV_LOG_ERROR, "Bug in codevector vector building code. \n"); - goto error; - } - entries=used_entries; - } - else if (codebook_setup->lookup_type>=2) { - av_log(vc->avccontext, AV_LOG_ERROR, "Codebook lookup type not supported. \n"); - goto error; - } - -// Initialize VLC table - if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n"); - goto error; - } - codebook_setup->maxdepth=0; - for(t=0;t<entries;++t) - if (tmp_vlc_bits[t]>=codebook_setup->maxdepth) codebook_setup->maxdepth=tmp_vlc_bits[t]; - - if(codebook_setup->maxdepth > 3*V_NB_BITS) codebook_setup->nb_bits=V_NB_BITS2; - else codebook_setup->nb_bits=V_NB_BITS; - - codebook_setup->maxdepth=(codebook_setup->maxdepth+codebook_setup->nb_bits-1)/codebook_setup->nb_bits; - - if (init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits, entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits), sizeof(*tmp_vlc_bits), tmp_vlc_codes, sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes), INIT_VLC_LE)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n"); - goto error; - } - } - - av_free(tmp_vlc_bits); - av_free(tmp_vlc_codes); - return 0; - -// Error: -error: - av_free(tmp_vlc_bits); - av_free(tmp_vlc_codes); - return 1; -} - -// Process time domain transforms part (unused in Vorbis I) - -static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc) { - GetBitContext *gb=&vc->gb; - uint_fast8_t i; - uint_fast8_t vorbis_time_count=get_bits(gb, 6)+1; - - for(i=0;i<vorbis_time_count;++i) { - uint_fast16_t vorbis_tdtransform=get_bits(gb, 16); - - AV_DEBUG(" Vorbis time domain transform %d: %d \n", vorbis_time_count, vorbis_tdtransform); - - if (vorbis_tdtransform) { - av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n"); - return 1; - } - } - return 0; -} - -// Process floors part - -static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec); -static void create_map( vorbis_context * vc, uint_fast8_t floor_number ); -static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec); -static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) { - GetBitContext *gb=&vc->gb; - uint_fast16_t i,j,k; - - vc->floor_count=get_bits(gb, 6)+1; - - vc->floors=(vorbis_floor *)av_mallocz(vc->floor_count * sizeof(vorbis_floor)); - - for (i=0;i<vc->floor_count;++i) { - vorbis_floor *floor_setup=&vc->floors[i]; - - floor_setup->floor_type=get_bits(gb, 16); - - AV_DEBUG(" %d. floor type %d \n", i, floor_setup->floor_type); - - if (floor_setup->floor_type==1) { - uint_fast8_t maximum_class=0; - uint_fast8_t rangebits; - uint_fast16_t floor1_values=2; - - floor_setup->decode=vorbis_floor1_decode; - - floor_setup->data.t1.partitions=get_bits(gb, 5); - - AV_DEBUG(" %d.floor: %d partitions \n", i, floor_setup->data.t1.partitions); - - for(j=0;j<floor_setup->data.t1.partitions;++j) { - floor_setup->data.t1.partition_class[j]=get_bits(gb, 4); - if (floor_setup->data.t1.partition_class[j]>maximum_class) maximum_class=floor_setup->data.t1.partition_class[j]; - - AV_DEBUG(" %d. floor %d partition class %d \n", i, j, floor_setup->data.t1.partition_class[j]); - - } - - AV_DEBUG(" maximum class %d \n", maximum_class); - - floor_setup->data.t1.maximum_class=maximum_class; - - for(j=0;j<=maximum_class;++j) { - floor_setup->data.t1.class_dimensions[j]=get_bits(gb, 3)+1; - floor_setup->data.t1.class_subclasses[j]=get_bits(gb, 2); - - AV_DEBUG(" %d floor %d class dim: %d subclasses %d \n", i, j, floor_setup->data.t1.class_dimensions[j], floor_setup->data.t1.class_subclasses[j]); - - if (floor_setup->data.t1.class_subclasses[j]) { - floor_setup->data.t1.class_masterbook[j]=get_bits(gb, 8); - - AV_DEBUG(" masterbook: %d \n", floor_setup->data.t1.class_masterbook[j]); - } - - for(k=0;k<(1<<floor_setup->data.t1.class_subclasses[j]);++k) { - floor_setup->data.t1.subclass_books[j][k]=(int16_t)get_bits(gb, 8)-1; - - AV_DEBUG(" book %d. : %d \n", k, floor_setup->data.t1.subclass_books[j][k]); - } - } - - floor_setup->data.t1.multiplier=get_bits(gb, 2)+1; - floor_setup->data.t1.x_list_dim=2; - - for(j=0;j<floor_setup->data.t1.partitions;++j) { - floor_setup->data.t1.x_list_dim+=floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]]; - } - - floor_setup->data.t1.list=(floor1_entry_t *)av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(floor1_entry_t)); - - - rangebits=get_bits(gb, 4); - floor_setup->data.t1.list[0].x = 0; - floor_setup->data.t1.list[1].x = (1<<rangebits); - - for(j=0;j<floor_setup->data.t1.partitions;++j) { - for(k=0;k<floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]];++k,++floor1_values) { - floor_setup->data.t1.list[floor1_values].x=get_bits(gb, rangebits); - - AV_DEBUG(" %d. floor1 Y coord. %d \n", floor1_values, floor_setup->data.t1.list[floor1_values].x); - } - } - -// Precalculate order of x coordinates - needed for decode - ff_vorbis_ready_floor1_list(floor_setup->data.t1.list, floor_setup->data.t1.x_list_dim); - } - else if(floor_setup->floor_type==0) { - uint_fast8_t max_codebook_dim=0; - - floor_setup->decode=vorbis_floor0_decode; - - floor_setup->data.t0.order=get_bits(gb, 8); - floor_setup->data.t0.rate=get_bits(gb, 16); - floor_setup->data.t0.bark_map_size=get_bits(gb, 16); - floor_setup->data.t0.amplitude_bits=get_bits(gb, 6); - /* zero would result in a div by zero later * - * 2^0 - 1 == 0 */ - if (floor_setup->data.t0.amplitude_bits == 0) { - av_log(vc->avccontext, AV_LOG_ERROR, - "Floor 0 amplitude bits is 0.\n"); - return 1; - } - floor_setup->data.t0.amplitude_offset=get_bits(gb, 8); - floor_setup->data.t0.num_books=get_bits(gb, 4)+1; - - /* allocate mem for booklist */ - floor_setup->data.t0.book_list= - av_malloc(floor_setup->data.t0.num_books); - if(!floor_setup->data.t0.book_list) { return 1; } - /* read book indexes */ - { - int idx; - uint_fast8_t book_idx; - for (idx=0;idx<floor_setup->data.t0.num_books;++idx) { - book_idx=get_bits(gb, 8); - floor_setup->data.t0.book_list[idx]=book_idx; - if (vc->codebooks[book_idx].dimensions > max_codebook_dim) - max_codebook_dim=vc->codebooks[book_idx].dimensions; - - if (floor_setup->data.t0.book_list[idx]>vc->codebook_count) - return 1; - } - } - - create_map( vc, i ); - - /* allocate mem for lsp coefficients */ - { - /* codebook dim is for padding if codebook dim doesn't * - * divide order+1 then we need to read more data */ - floor_setup->data.t0.lsp= - av_malloc((floor_setup->data.t0.order+1 + max_codebook_dim) - * sizeof(float)); - if(!floor_setup->data.t0.lsp) { return 1; } - } - -#ifdef V_DEBUG /* debug output parsed headers */ - AV_DEBUG("floor0 order: %u\n", floor_setup->data.t0.order); - AV_DEBUG("floor0 rate: %u\n", floor_setup->data.t0.rate); - AV_DEBUG("floor0 bark map size: %u\n", - floor_setup->data.t0.bark_map_size); - AV_DEBUG("floor0 amplitude bits: %u\n", - floor_setup->data.t0.amplitude_bits); - AV_DEBUG("floor0 amplitude offset: %u\n", - floor_setup->data.t0.amplitude_offset); - AV_DEBUG("floor0 number of books: %u\n", - floor_setup->data.t0.num_books); - AV_DEBUG("floor0 book list pointer: %p\n", - floor_setup->data.t0.book_list); - { - int idx; - for (idx=0;idx<floor_setup->data.t0.num_books;++idx) { - AV_DEBUG( " Book %d: %u\n", - idx+1, - floor_setup->data.t0.book_list[idx] ); - } - } -#endif - } - else { - av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n"); - return 1; - } - } - return 0; -} - -// Process residues part - -static int vorbis_parse_setup_hdr_residues(vorbis_context *vc){ - GetBitContext *gb=&vc->gb; - uint_fast8_t i, j, k; - - vc->residue_count=get_bits(gb, 6)+1; - vc->residues=(vorbis_residue *)av_mallocz(vc->residue_count * sizeof(vorbis_residue)); - - AV_DEBUG(" There are %d residues. \n", vc->residue_count); - - for(i=0;i<vc->residue_count;++i) { - vorbis_residue *res_setup=&vc->residues[i]; - uint_fast8_t cascade[64]; - uint_fast8_t high_bits; - uint_fast8_t low_bits; - - res_setup->type=get_bits(gb, 16); - - AV_DEBUG(" %d. residue type %d \n", i, res_setup->type); - - res_setup->begin=get_bits(gb, 24); - res_setup->end=get_bits(gb, 24); - res_setup->partition_size=get_bits(gb, 24)+1; - res_setup->classifications=get_bits(gb, 6)+1; - res_setup->classbook=get_bits(gb, 8); - - AV_DEBUG(" begin %d end %d part.size %d classif.s %d classbook %d \n", res_setup->begin, res_setup->end, res_setup->partition_size, - res_setup->classifications, res_setup->classbook); - - for(j=0;j<res_setup->classifications;++j) { - high_bits=0; - low_bits=get_bits(gb, 3); - if (get_bits1(gb)) { - high_bits=get_bits(gb, 5); - } - cascade[j]=(high_bits<<3)+low_bits; - - AV_DEBUG(" %d class casscade depth: %d \n", j, ilog(cascade[j])); - } - - res_setup->maxpass=0; - for(j=0;j<res_setup->classifications;++j) { - for(k=0;k<8;++k) { - if (cascade[j]&(1<<k)) { - res_setup->books[j][k]=get_bits(gb, 8); - - AV_DEBUG(" %d class casscade depth %d book: %d \n", j, k, res_setup->books[j][k]); - - if (k>res_setup->maxpass) { - res_setup->maxpass=k; - } - } else { - res_setup->books[j][k]=-1; - } - } - } - } - return 0; -} - -// Process mappings part - -static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc) { - GetBitContext *gb=&vc->gb; - uint_fast8_t i, j; - - vc->mapping_count=get_bits(gb, 6)+1; - vc->mappings=(vorbis_mapping *)av_mallocz(vc->mapping_count * sizeof(vorbis_mapping)); - - AV_DEBUG(" There are %d mappings. \n", vc->mapping_count); - - for(i=0;i<vc->mapping_count;++i) { - vorbis_mapping *mapping_setup=&vc->mappings[i]; - - if (get_bits(gb, 16)) { - av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n"); - return 1; - } - if (get_bits1(gb)) { - mapping_setup->submaps=get_bits(gb, 4)+1; - } else { - mapping_setup->submaps=1; - } - - if (get_bits1(gb)) { - mapping_setup->coupling_steps=get_bits(gb, 8)+1; - mapping_setup->magnitude=(uint_fast8_t *)av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t)); - mapping_setup->angle=(uint_fast8_t *)av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t)); - for(j=0;j<mapping_setup->coupling_steps;++j) { - mapping_setup->magnitude[j]=get_bits(gb, ilog(vc->audio_channels-1)); - mapping_setup->angle[j]=get_bits(gb, ilog(vc->audio_channels-1)); - // FIXME: sanity checks - } - } else { - mapping_setup->coupling_steps=0; - } - - AV_DEBUG(" %d mapping coupling steps: %d \n", i, mapping_setup->coupling_steps); - - if(get_bits(gb, 2)) { - av_log(vc->avccontext, AV_LOG_ERROR, "%d. mapping setup data invalid. \n", i); - return 1; // following spec. - } - - if (mapping_setup->submaps>1) { - mapping_setup->mux=(uint_fast8_t *)av_mallocz(vc->audio_channels * sizeof(uint_fast8_t)); - for(j=0;j<vc->audio_channels;++j) { - mapping_setup->mux[j]=get_bits(gb, 4); - } - } - - for(j=0;j<mapping_setup->submaps;++j) { - get_bits(gb, 8); // FIXME check? - mapping_setup->submap_floor[j]=get_bits(gb, 8); - mapping_setup->submap_residue[j]=get_bits(gb, 8); - - AV_DEBUG(" %d mapping %d submap : floor %d, residue %d \n", i, j, mapping_setup->submap_floor[j], mapping_setup->submap_residue[j]); - } - } - return 0; -} - -// Process modes part - -static void create_map( vorbis_context * vc, uint_fast8_t floor_number ) -{ - vorbis_floor * floors=vc->floors; - vorbis_floor0 * vf; - int idx; - int_fast8_t blockflag; - int_fast32_t * map; - int_fast32_t n; //TODO: could theoretically be smaller? - - for (blockflag=0;blockflag<2;++blockflag) - { - n=vc->blocksize[blockflag]/2; - floors[floor_number].data.t0.map[blockflag]= - av_malloc((n+1) * sizeof(int_fast32_t)); // n+sentinel - - map=floors[floor_number].data.t0.map[blockflag]; - vf=&floors[floor_number].data.t0; - - for (idx=0; idx<n;++idx) { - map[idx]=floor( BARK((vf->rate*idx)/(2.0f*n)) * - ((vf->bark_map_size)/ - BARK(vf->rate/2.0f )) ); - if (vf->bark_map_size-1 < map[idx]) { - map[idx]=vf->bark_map_size-1; - } - } - map[n]=-1; - vf->map_size[blockflag]=n; - } - -# ifdef V_DEBUG - for(idx=0;idx<=n;++idx) { - AV_DEBUG("floor0 map: map at pos %d is %d\n", - idx, map[idx]); - } -# endif -} - -static int vorbis_parse_setup_hdr_modes(vorbis_context *vc) { - GetBitContext *gb=&vc->gb; - uint_fast8_t i; - - vc->mode_count=get_bits(gb, 6)+1; - vc->modes=(vorbis_mode *)av_mallocz(vc->mode_count * sizeof(vorbis_mode)); - - AV_DEBUG(" There are %d modes.\n", vc->mode_count); - - for(i=0;i<vc->mode_count;++i) { - vorbis_mode *mode_setup=&vc->modes[i]; - - mode_setup->blockflag=get_bits(gb, 1); - mode_setup->windowtype=get_bits(gb, 16); //FIXME check - mode_setup->transformtype=get_bits(gb, 16); //FIXME check - mode_setup->mapping=get_bits(gb, 8); //FIXME check - - AV_DEBUG(" %d mode: blockflag %d, windowtype %d, transformtype %d, mapping %d \n", i, mode_setup->blockflag, mode_setup->windowtype, mode_setup->transformtype, mode_setup->mapping); - } - return 0; -} - -// Process the whole setup header using the functions above - -static int vorbis_parse_setup_hdr(vorbis_context *vc) { - GetBitContext *gb=&vc->gb; - - if ((get_bits(gb, 8)!='v') || (get_bits(gb, 8)!='o') || - (get_bits(gb, 8)!='r') || (get_bits(gb, 8)!='b') || - (get_bits(gb, 8)!='i') || (get_bits(gb, 8)!='s')) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n"); - return 1; - } - - if (vorbis_parse_setup_hdr_codebooks(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n"); - return 2; - } - if (vorbis_parse_setup_hdr_tdtransforms(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n"); - return 3; - } - if (vorbis_parse_setup_hdr_floors(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n"); - return 4; - } - if (vorbis_parse_setup_hdr_residues(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n"); - return 5; - } - if (vorbis_parse_setup_hdr_mappings(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n"); - return 6; - } - if (vorbis_parse_setup_hdr_modes(vc)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n"); - return 7; - } - if (!get_bits1(gb)) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n"); - return 8; // framing flag bit unset error - } - - return 0; -} - -// Process the identification header - -static int vorbis_parse_id_hdr(vorbis_context *vc){ - GetBitContext *gb=&vc->gb; - uint_fast8_t bl0, bl1; - - if ((get_bits(gb, 8)!='v') || (get_bits(gb, 8)!='o') || - (get_bits(gb, 8)!='r') || (get_bits(gb, 8)!='b') || - (get_bits(gb, 8)!='i') || (get_bits(gb, 8)!='s')) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n"); - return 1; - } - - vc->version=get_bits_long(gb, 32); //FIXME check 0 - vc->audio_channels=get_bits(gb, 8); //FIXME check >0 - vc->audio_samplerate=get_bits_long(gb, 32); //FIXME check >0 - vc->bitrate_maximum=get_bits_long(gb, 32); - vc->bitrate_nominal=get_bits_long(gb, 32); - vc->bitrate_minimum=get_bits_long(gb, 32); - bl0=get_bits(gb, 4); - bl1=get_bits(gb, 4); - vc->blocksize[0]=(1<<bl0); - vc->blocksize[1]=(1<<bl1); - if (bl0>13 || bl0<6 || bl1>13 || bl1<6 || bl1<bl0) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n"); - return 3; - } - // output format int16 - if (vc->blocksize[1]/2 * vc->audio_channels * 2 > - AVCODEC_MAX_AUDIO_FRAME_SIZE) { - av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis channel count makes " - "output packets too large.\n"); - return 4; - } - vc->win[0]=ff_vorbis_vwin[bl0-6]; - vc->win[1]=ff_vorbis_vwin[bl1-6]; - - if(vc->exp_bias){ - int i, j; - for(j=0; j<2; j++){ - float *win = av_malloc(vc->blocksize[j]/2 * sizeof(float)); - for(i=0; i<vc->blocksize[j]/2; i++) - win[i] = vc->win[j][i] * (1<<15); - vc->win[j] = win; - } - } - - if ((get_bits1(gb)) == 0) { - av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n"); - return 2; - } - - vc->channel_residues=(float *)av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); - vc->channel_floors=(float *)av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); - vc->saved=(float *)av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); - vc->ret=(float *)av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); - vc->buf=(float *)av_malloc(vc->blocksize[1] * sizeof(float)); - vc->buf_tmp=(float *)av_malloc(vc->blocksize[1] * sizeof(float)); - vc->saved_start=0; - - ff_mdct_init(&vc->mdct[0], bl0, 1); - ff_mdct_init(&vc->mdct[1], bl1, 1); - - AV_DEBUG(" vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ", - vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]); - -/* - BLK=vc->blocksize[0]; - for(i=0;i<BLK/2;++i) { - vc->win[0][i]=sin(0.5*3.14159265358*(sin(((float)i+0.5)/(float)BLK*3.14159265358))*(sin(((float)i+0.5)/(float)BLK*3.14159265358))); - } -*/ - - return 0; -} - -// Process the extradata using the functions above (identification header, setup header) - -static int vorbis_decode_init(AVCodecContext *avccontext) { - vorbis_context *vc = avccontext->priv_data ; - uint8_t *headers = avccontext->extradata; - int headers_len=avccontext->extradata_size; - uint8_t *header_start[3]; - int header_len[3]; - GetBitContext *gb = &(vc->gb); - int hdr_type; - - vc->avccontext = avccontext; - dsputil_init(&vc->dsp, avccontext); - - if(vc->dsp.float_to_int16 == ff_float_to_int16_c) { - vc->add_bias = 385; - vc->exp_bias = 0; - } else { - vc->add_bias = 0; - vc->exp_bias = 15<<23; - } - - if (!headers_len) { - av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n"); - return -1; - } - - if (ff_split_xiph_headers(headers, headers_len, 30, header_start, header_len) < 0) { - av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n"); - return -1; - } - - init_get_bits(gb, header_start[0], header_len[0]*8); - hdr_type=get_bits(gb, 8); - if (hdr_type!=1) { - av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n"); - return -1; - } - if (vorbis_parse_id_hdr(vc)) { - av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n"); - vorbis_free(vc); - return -1; - } - - init_get_bits(gb, header_start[2], header_len[2]*8); - hdr_type=get_bits(gb, 8); - if (hdr_type!=5) { - av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n"); - return -1; - } - if (vorbis_parse_setup_hdr(vc)) { - av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n"); - vorbis_free(vc); - return -1; - } - - avccontext->channels = vc->audio_channels; - avccontext->sample_rate = vc->audio_samplerate; - - return 0 ; -} - -// Decode audiopackets ------------------------------------------------- - -// Read and decode floor - -static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, - vorbis_floor_data *vfu, float *vec) { - vorbis_floor0 * vf=&vfu->t0; - float * lsp=vf->lsp; - uint_fast32_t amplitude; - uint_fast32_t book_idx; - uint_fast8_t blockflag=vc->modes[vc->mode_number].blockflag; - - amplitude=get_bits(&vc->gb, vf->amplitude_bits); - if (amplitude>0) { - float last = 0; - uint_fast16_t lsp_len = 0; - uint_fast16_t idx; - vorbis_codebook codebook; - - book_idx=get_bits(&vc->gb, ilog(vf->num_books)); - if ( book_idx >= vf->num_books ) { - av_log( vc->avccontext, AV_LOG_ERROR, - "floor0 dec: booknumber too high!\n" ); - //FIXME: look above - } - AV_DEBUG( "floor0 dec: booknumber: %u\n", book_idx ); - codebook=vc->codebooks[vf->book_list[book_idx]]; - - while (lsp_len<vf->order) { - int vec_off; - - AV_DEBUG( "floor0 dec: book dimension: %d\n", codebook.dimensions ); - AV_DEBUG( "floor0 dec: maximum depth: %d\n", codebook.maxdepth ); - /* read temp vector */ - vec_off=get_vlc2(&vc->gb, - codebook.vlc.table, - codebook.nb_bits, - codebook.maxdepth ) * - codebook.dimensions; - AV_DEBUG( "floor0 dec: vector offset: %d\n", vec_off ); - /* copy each vector component and add last to it */ - for (idx=0; idx<codebook.dimensions; ++idx) { - lsp[lsp_len+idx]=codebook.codevectors[vec_off+idx]+last; - } - last=lsp[lsp_len+idx-1]; /* set last to last vector component */ - - lsp_len += codebook.dimensions; - } -#ifdef V_DEBUG - /* DEBUG: output lsp coeffs */ - { - int idx; - for ( idx = 0; idx < lsp_len; ++idx ) - AV_DEBUG("floor0 dec: coeff at %d is %f\n", idx, lsp[idx] ); - } -#endif - - /* synthesize floor output vector */ - { - int i; - int order=vf->order; - float wstep=M_PI/vf->bark_map_size; - - for(i=0;i<order;i++) { lsp[i]=2.0f*cos(lsp[i]); } - - AV_DEBUG("floor0 synth: map_size=%d; m=%d; wstep=%f\n", - vf->map_size, order, wstep); - - i=0; - while(i<vf->map_size[blockflag]) { - int j, iter_cond=vf->map[blockflag][i]; - float p=0.5f; - float q=0.5f; - float two_cos_w=2.0f*cos(wstep*iter_cond); // needed all times - - /* similar part for the q and p products */ - for(j=0;j<order;j+=2) { - q *= lsp[j] -two_cos_w; - p *= lsp[j+1]-two_cos_w; - } - if(j==order) { // even order - p *= p*(2.0f-two_cos_w); - q *= q*(2.0f+two_cos_w); - } - else { // odd order - q *= two_cos_w-lsp[j]; // one more time for q - - /* final step and square */ - p *= p*(4.f-two_cos_w*two_cos_w); - q *= q; - } - - /* calculate linear floor value */ - { - q=exp( ( - ( (amplitude*vf->amplitude_offset)/ - (((1<<vf->amplitude_bits)-1) * sqrt(p+q)) ) - - vf->amplitude_offset ) * .11512925f - ); - } - - /* fill vector */ - do { vec[i]=q; ++i; }while(vf->map[blockflag][i]==iter_cond); - } - } - } - else { - /* this channel is unused */ - return 1; - } - - AV_DEBUG(" Floor0 decoded\n"); - - return 0; -} - -static void render_line(int x0, int y0, int x1, int y1, float * buf, int n) { +static void render_line(int x0, int y0, int x1, int y1, float * buf) { int dy = y1 - y0; int adx = x1 - x0; - int ady = FFABS(dy); int base = dy / adx; + int ady = FFABS(dy) - FFABS(base) * adx; int x = x0; int y = y0; int err = 0; - int sy; - if (dy < 0) sy = base - 1; - else sy = base + 1; - ady = ady - FFABS(base) * adx; - if (x >= n) return; + int sy = dy<0 ? -1 : 1; buf[x] = ff_vorbis_floor1_inverse_db_table[y]; - for (x = x0 + 1; x < x1; x++) { - if (x >= n) return; + while (++x < x1) { err += ady; if (err >= adx) { err -= adx; y += sy; - } else { - y += base; } + y += base; buf[x] = ff_vorbis_floor1_inverse_db_table[y]; } } @@ -1243,548 +169,14 @@ void ff_vorbis_floor1_render_list(floor1_entry_t * list, int values, uint_fast16 for (i = 1; i < values; i++) { int pos = list[i].sort; if (flag[pos]) { - render_line(lx, ly, list[pos].x, y_list[pos] * multiplier, out, samples); - lx = list[pos].x; - ly = y_list[pos] * multiplier; + int x1 = list[pos].x; + int y1 = y_list[pos] * multiplier; + if (lx < samples) + render_line(lx, ly, FFMIN(x1,samples), y1, out); + lx = x1; + ly = y1; } if (lx >= samples) break; } - if (lx < samples) render_line(lx, ly, samples, ly, out, samples); -} - -static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, vorbis_floor_data *vfu, float *vec) { - vorbis_floor1 * vf=&vfu->t1; - GetBitContext *gb=&vc->gb; - uint_fast16_t range_v[4]={ 256, 128, 86, 64 }; - uint_fast16_t range=range_v[vf->multiplier-1]; - uint_fast16_t floor1_Y[vf->x_list_dim]; - uint_fast16_t floor1_Y_final[vf->x_list_dim]; - int floor1_flag[vf->x_list_dim]; - uint_fast8_t class_; - uint_fast8_t cdim; - uint_fast8_t cbits; - uint_fast8_t csub; - uint_fast8_t cval; - int_fast16_t book; - uint_fast16_t offset; - uint_fast16_t i,j; - /*u*/int_fast16_t adx, ady, off, predicted; // WTF ? dy/adx= (unsigned)dy/adx ? - int_fast16_t dy, err; - - - if (!get_bits1(gb)) return 1; // silence - -// Read values (or differences) for the floor's points - - floor1_Y[0]=get_bits(gb, ilog(range-1)); - floor1_Y[1]=get_bits(gb, ilog(range-1)); - - AV_DEBUG("floor 0 Y %d floor 1 Y %d \n", floor1_Y[0], floor1_Y[1]); - - offset=2; - for(i=0;i<vf->partitions;++i) { - class_=vf->partition_class[i]; - cdim=vf->class_dimensions[class_]; - cbits=vf->class_subclasses[class_]; - csub=(1<<cbits)-1; - cval=0; - - AV_DEBUG("Cbits %d \n", cbits); - - if (cbits) { // this reads all subclasses for this partition's class - cval=get_vlc2(gb, vc->codebooks[vf->class_masterbook[class_]].vlc.table, - vc->codebooks[vf->class_masterbook[class_]].nb_bits, 3); - } - - for(j=0;j<cdim;++j) { - book=vf->subclass_books[class_][cval & csub]; - - AV_DEBUG("book %d Cbits %d cval %d bits:%d \n", book, cbits, cval, get_bits_count(gb)); - - cval=cval>>cbits; - if (book>-1) { - floor1_Y[offset+j]=get_vlc2(gb, vc->codebooks[book].vlc.table, - vc->codebooks[book].nb_bits, 3); - } else { - floor1_Y[offset+j]=0; - } - - AV_DEBUG(" floor(%d) = %d \n", vf->list[offset+j].x, floor1_Y[offset+j]); - } - offset+=cdim; - } - -// Amplitude calculation from the differences - - floor1_flag[0]=1; - floor1_flag[1]=1; - floor1_Y_final[0]=floor1_Y[0]; - floor1_Y_final[1]=floor1_Y[1]; - - for(i=2;i<vf->x_list_dim;++i) { - uint_fast16_t val, highroom, lowroom, room; - uint_fast16_t high_neigh_offs; - uint_fast16_t low_neigh_offs; - - low_neigh_offs=vf->list[i].low; - high_neigh_offs=vf->list[i].high; - dy=floor1_Y_final[high_neigh_offs]-floor1_Y_final[low_neigh_offs]; // render_point begin - adx=vf->list[high_neigh_offs].x-vf->list[low_neigh_offs].x; - ady= FFABS(dy); - err=ady*(vf->list[i].x-vf->list[low_neigh_offs].x); - off=(int16_t)err/(int16_t)adx; - if (dy<0) { - predicted=floor1_Y_final[low_neigh_offs]-off; - } else { - predicted=floor1_Y_final[low_neigh_offs]+off; - } // render_point end - - val=floor1_Y[i]; - highroom=range-predicted; - lowroom=predicted; - if (highroom < lowroom) { - room=highroom*2; - } else { - room=lowroom*2; // SPEC mispelling - } - if (val) { - floor1_flag[low_neigh_offs]=1; - floor1_flag[high_neigh_offs]=1; - floor1_flag[i]=1; - if (val>=room) { - if (highroom > lowroom) { - floor1_Y_final[i]=val-lowroom+predicted; - } else { - floor1_Y_final[i]=predicted-val+highroom-1; - } - } else { - if (val & 1) { - floor1_Y_final[i]=predicted-(val+1)/2; - } else { - floor1_Y_final[i]=predicted+val/2; - } - } - } else { - floor1_flag[i]=0; - floor1_Y_final[i]=predicted; - } - - AV_DEBUG(" Decoded floor(%d) = %d / val %d \n", vf->list[i].x, floor1_Y_final[i], val); - } - -// Curve synth - connect the calculated dots and convert from dB scale FIXME optimize ? - - ff_vorbis_floor1_render_list(vf->list, vf->x_list_dim, floor1_Y_final, floor1_flag, vf->multiplier, vec, vf->list[1].x); - - AV_DEBUG(" Floor decoded\n"); - - return 0; -} - -// Read and decode residue - -static int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, uint_fast8_t ch, uint_fast8_t *do_not_decode, float *vec, uint_fast16_t vlen) { - GetBitContext *gb=&vc->gb; - uint_fast8_t c_p_c=vc->codebooks[vr->classbook].dimensions; - uint_fast16_t n_to_read=vr->end-vr->begin; - uint_fast16_t ptns_to_read=n_to_read/vr->partition_size; - uint_fast8_t classifs[ptns_to_read*vc->audio_channels]; - uint_fast8_t pass; - uint_fast8_t ch_used; - uint_fast8_t i,j,l; - uint_fast16_t k; - - if (vr->type==2) { - for(j=1;j<ch;++j) { - do_not_decode[0]&=do_not_decode[j]; // FIXME - clobbering input - } - if (do_not_decode[0]) return 0; - ch_used=1; - } else { - ch_used=ch; - } - - AV_DEBUG(" residue type 0/1/2 decode begin, ch: %d cpc %d \n", ch, c_p_c); - - for(pass=0;pass<=vr->maxpass;++pass) { // FIXME OPTIMIZE? - uint_fast16_t voffset; - uint_fast16_t partition_count; - uint_fast16_t j_times_ptns_to_read; - - voffset=vr->begin; - for(partition_count=0;partition_count<ptns_to_read;) { // SPEC error - if (!pass) { - uint_fast32_t inverse_class = ff_inverse[vr->classifications]; - for(j_times_ptns_to_read=0, j=0;j<ch_used;++j) { - if (!do_not_decode[j]) { - uint_fast32_t temp=get_vlc2(gb, vc->codebooks[vr->classbook].vlc.table, - vc->codebooks[vr->classbook].nb_bits, 3); - - AV_DEBUG("Classword: %d \n", temp); - - assert(vr->classifications > 1 && temp<=65536); //needed for inverse[] - for(i=0;i<c_p_c;++i) { - uint_fast32_t temp2; - - temp2=(((uint_fast64_t)temp) * inverse_class)>>32; - if (partition_count+c_p_c-1-i < ptns_to_read) { - classifs[j_times_ptns_to_read+partition_count+c_p_c-1-i]=temp-temp2*vr->classifications; - } - temp=temp2; - } - } - j_times_ptns_to_read+=ptns_to_read; - } - } - for(i=0;(i<c_p_c) && (partition_count<ptns_to_read);++i) { - for(j_times_ptns_to_read=0, j=0;j<ch_used;++j) { - uint_fast16_t voffs; - - if (!do_not_decode[j]) { - uint_fast8_t vqclass=classifs[j_times_ptns_to_read+partition_count]; - int_fast16_t vqbook=vr->books[vqclass][pass]; - - if (vqbook>=0) { - uint_fast16_t coffs; - unsigned dim= vc->codebooks[vqbook].dimensions; // not uint_fast8_t: 64bit is slower here on amd64 - uint_fast16_t step= dim==1 ? vr->partition_size - : FASTDIV(vr->partition_size, dim); - vorbis_codebook codebook= vc->codebooks[vqbook]; - - if (vr->type==0) { - - voffs=voffset+j*vlen; - for(k=0;k<step;++k) { - coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; - for(l=0;l<dim;++l) { - vec[voffs+k+l*step]+=codebook.codevectors[coffs+l]; // FPMATH - } - } - } - else if (vr->type==1) { - voffs=voffset+j*vlen; - for(k=0;k<step;++k) { - coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; - for(l=0;l<dim;++l, ++voffs) { - vec[voffs]+=codebook.codevectors[coffs+l]; // FPMATH - - AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d \n", pass, voffs, vec[voffs], codebook.codevectors[coffs+l], coffs); - } - } - } - else if (vr->type==2 && ch==2 && (voffset&1)==0 && (dim&1)==0) { // most frequent case optimized - voffs=voffset>>1; - - if(dim==2) { - for(k=0;k<step;++k) { - coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * 2; - vec[voffs+k ]+=codebook.codevectors[coffs ]; // FPMATH - vec[voffs+k+vlen]+=codebook.codevectors[coffs+1]; // FPMATH - } - } else - for(k=0;k<step;++k) { - coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; - for(l=0;l<dim;l+=2, voffs++) { - vec[voffs ]+=codebook.codevectors[coffs+l ]; // FPMATH - vec[voffs+vlen]+=codebook.codevectors[coffs+l+1]; // FPMATH - - AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d+%d \n", pass, voffset/ch+(voffs%ch)*vlen, vec[voffset/ch+(voffs%ch)*vlen], codebook.codevectors[coffs+l], coffs, l); - } - } - - } - else if (vr->type==2) { - voffs=voffset; - - for(k=0;k<step;++k) { - coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; - for(l=0;l<dim;++l, ++voffs) { - vec[voffs/ch+(voffs%ch)*vlen]+=codebook.codevectors[coffs+l]; // FPMATH FIXME use if and counter instead of / and % - - AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d+%d \n", pass, voffset/ch+(voffs%ch)*vlen, vec[voffset/ch+(voffs%ch)*vlen], codebook.codevectors[coffs+l], coffs, l); - } - } - } else { - av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n"); - return 1; - } - } - } - j_times_ptns_to_read+=ptns_to_read; - } - ++partition_count; - voffset+=vr->partition_size; - } - } - } - return 0; -} - -void vorbis_inverse_coupling(float *mag, float *ang, int blocksize) -{ - int i; - for(i=0; i<blocksize; i++) - { - if (mag[i]>0.0) { - if (ang[i]>0.0) { - ang[i]=mag[i]-ang[i]; - } else { - float temp=ang[i]; - ang[i]=mag[i]; - mag[i]+=temp; - } - } else { - if (ang[i]>0.0) { - ang[i]+=mag[i]; - } else { - float temp=ang[i]; - ang[i]=mag[i]; - mag[i]-=temp; - } - } - } + if (lx < samples) render_line(lx, ly, samples, ly, out); } - -// Decode the audio packet using the functions above - -static int vorbis_parse_audio_packet(vorbis_context *vc) { - GetBitContext *gb=&vc->gb; - - uint_fast8_t previous_window=0,next_window=0; - uint_fast8_t mode_number; - uint_fast16_t blocksize; - int_fast32_t i,j; - uint_fast8_t no_residue[vc->audio_channels]; - uint_fast8_t do_not_decode[vc->audio_channels]; - vorbis_mapping *mapping; - float *ch_res_ptr=vc->channel_residues; - float *ch_floor_ptr=vc->channel_floors; - uint_fast8_t res_chan[vc->audio_channels]; - uint_fast8_t res_num=0; - int_fast16_t retlen=0; - uint_fast16_t saved_start=0; - float fadd_bias = vc->add_bias; - - if (get_bits1(gb)) { - av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n"); - return -1; // packet type not audio - } - - if (vc->mode_count==1) { - mode_number=0; - } else { - mode_number=get_bits(gb, ilog(vc->mode_count-1)); - } - vc->mode_number=mode_number; - mapping=&vc->mappings[vc->modes[mode_number].mapping]; - - AV_DEBUG(" Mode number: %d , mapping: %d , blocktype %d \n", mode_number, vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag); - - if (vc->modes[mode_number].blockflag) { - previous_window=get_bits1(gb); - next_window=get_bits1(gb); - } - - blocksize=vc->blocksize[vc->modes[mode_number].blockflag]; - memset(ch_res_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2); //FIXME can this be removed ? - memset(ch_floor_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2); //FIXME can this be removed ? - -// Decode floor - - for(i=0;i<vc->audio_channels;++i) { - vorbis_floor *floor; - if (mapping->submaps>1) { - floor=&vc->floors[mapping->submap_floor[mapping->mux[i]]]; - } else { - floor=&vc->floors[mapping->submap_floor[0]]; - } - - no_residue[i]=floor->decode(vc, &floor->data, ch_floor_ptr); - ch_floor_ptr+=blocksize/2; - } - -// Nonzero vector propagate - - for(i=mapping->coupling_steps-1;i>=0;--i) { - if (!(no_residue[mapping->magnitude[i]] & no_residue[mapping->angle[i]])) { - no_residue[mapping->magnitude[i]]=0; - no_residue[mapping->angle[i]]=0; - } - } - -// Decode residue - - for(i=0;i<mapping->submaps;++i) { - vorbis_residue *residue; - uint_fast8_t ch=0; - - for(j=0;j<vc->audio_channels;++j) { - if ((mapping->submaps==1) || (i=mapping->mux[j])) { - res_chan[j]=res_num; - if (no_residue[j]) { - do_not_decode[ch]=1; - } else { - do_not_decode[ch]=0; - } - ++ch; - ++res_num; - } - } - residue=&vc->residues[mapping->submap_residue[i]]; - vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, blocksize/2); - - ch_res_ptr+=ch*blocksize/2; - } - -// Inverse coupling - - for(i=mapping->coupling_steps-1;i>=0;--i) { //warning: i has to be signed - float *mag, *ang; - - mag=vc->channel_residues+res_chan[mapping->magnitude[i]]*blocksize/2; - ang=vc->channel_residues+res_chan[mapping->angle[i]]*blocksize/2; - vc->dsp.vorbis_inverse_coupling(mag, ang, blocksize/2); - } - -// Dotproduct - - for(j=0, ch_floor_ptr=vc->channel_floors;j<vc->audio_channels;++j,ch_floor_ptr+=blocksize/2) { - ch_res_ptr=vc->channel_residues+res_chan[j]*blocksize/2; - vc->dsp.vector_fmul(ch_floor_ptr, ch_res_ptr, blocksize/2); - } - -// MDCT, overlap/add, save data for next overlapping FPMATH - - for(j=0;j<vc->audio_channels;++j) { - uint_fast8_t step=vc->audio_channels; - uint_fast16_t k; - float *saved=vc->saved+j*vc->blocksize[1]/2; - float *ret=vc->ret; - const float *lwin=vc->win[1]; - const float *swin=vc->win[0]; - float *buf=vc->buf; - float *buf_tmp=vc->buf_tmp; - - ch_floor_ptr=vc->channel_floors+j*blocksize/2; - - saved_start=vc->saved_start; - - vc->mdct[0].fft.imdct_calc(&vc->mdct[vc->modes[mode_number].blockflag], buf, ch_floor_ptr, buf_tmp); - - //FIXME process channels together, to allow faster simd vector_fmul_add_add? - if (vc->modes[mode_number].blockflag) { - // -- overlap/add - if (previous_window) { - vc->dsp.vector_fmul_add_add(ret+j, buf, lwin, saved, vc->add_bias, vc->blocksize[1]/2, step); - retlen=vc->blocksize[1]/2; - } else { - int len = (vc->blocksize[1]-vc->blocksize[0])/4; - buf += len; - vc->dsp.vector_fmul_add_add(ret+j, buf, swin, saved, vc->add_bias, vc->blocksize[0]/2, step); - k = vc->blocksize[0]/2*step + j; - buf += vc->blocksize[0]/2; - if(vc->exp_bias){ - for(i=0; i<len; i++, k+=step) - ((uint32_t*)ret)[k] = ((uint32_t*)buf)[i] + vc->exp_bias; // ret[k]=buf[i]*(1<<bias) - } else { - for(i=0; i<len; i++, k+=step) - ret[k] = buf[i] + fadd_bias; - } - buf=vc->buf; - retlen=vc->blocksize[0]/2+len; - } - // -- save - if (next_window) { - buf += vc->blocksize[1]/2; - vc->dsp.vector_fmul_reverse(saved, buf, lwin, vc->blocksize[1]/2); - saved_start=0; - } else { - saved_start=(vc->blocksize[1]-vc->blocksize[0])/4; - buf += vc->blocksize[1]/2; - for(i=0; i<saved_start; i++) - ((uint32_t*)saved)[i] = ((uint32_t*)buf)[i] + vc->exp_bias; - vc->dsp.vector_fmul_reverse(saved+saved_start, buf+saved_start, swin, vc->blocksize[0]/2); - } - } else { - // --overlap/add - if(vc->add_bias) { - for(k=j, i=0;i<saved_start;++i, k+=step) - ret[k] = saved[i] + fadd_bias; - } else { - for(k=j, i=0;i<saved_start;++i, k+=step) - ret[k] = saved[i]; - } - vc->dsp.vector_fmul_add_add(ret+k, buf, swin, saved+saved_start, vc->add_bias, vc->blocksize[0]/2, step); - retlen=saved_start+vc->blocksize[0]/2; - // -- save - buf += vc->blocksize[0]/2; - vc->dsp.vector_fmul_reverse(saved, buf, swin, vc->blocksize[0]/2); - saved_start=0; - } - } - vc->saved_start=saved_start; - - return retlen*vc->audio_channels; -} - -// Return the decoded audio packet through the standard api - -static int vorbis_decode_frame(AVCodecContext *avccontext, - void *data, int *data_size, - uint8_t *buf, int buf_size) -{ - vorbis_context *vc = avccontext->priv_data ; - GetBitContext *gb = &(vc->gb); - - int_fast16_t len; - - if(!buf_size){ - return 0; - } - - AV_DEBUG("packet length %d \n", buf_size); - - init_get_bits(gb, buf, buf_size*8); - - len=vorbis_parse_audio_packet(vc); - - if (len<=0) { - *data_size=0; - return buf_size; - } - - if (!vc->first_frame) { - vc->first_frame=1; - *data_size=0; - return buf_size ; - } - - AV_DEBUG("parsed %d bytes %d bits, returned %d samples (*ch*bits) \n", get_bits_count(gb)/8, get_bits_count(gb)%8, len); - - vc->dsp.float_to_int16(data, vc->ret, len); - *data_size=len*2; - - return buf_size ; -} - -// Close decoder - -static int vorbis_decode_close(AVCodecContext *avccontext) { - vorbis_context *vc = avccontext->priv_data; - - vorbis_free(vc); - - return 0 ; -} - -AVCodec vorbis_decoder = { - "vorbis", - CODEC_TYPE_AUDIO, - CODEC_ID_VORBIS, - sizeof(vorbis_context), - vorbis_decode_init, - NULL, - vorbis_decode_close, - vorbis_decode_frame, -}; - diff --git a/contrib/ffmpeg/libavcodec/vorbis.h b/contrib/ffmpeg/libavcodec/vorbis.h index cda909aa9..f5e8b7a99 100644 --- a/contrib/ffmpeg/libavcodec/vorbis.h +++ b/contrib/ffmpeg/libavcodec/vorbis.h @@ -18,8 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef VORBIS_H -#define VORBIS_H +#ifndef FFMPEG_VORBIS_H +#define FFMPEG_VORBIS_H #include "avcodec.h" @@ -40,4 +40,4 @@ void ff_vorbis_floor1_render_list(floor1_entry_t * list, int values, uint_fast16 #define ilog(i) av_log2(2*(i)) -#endif +#endif /* FFMPEG_VORBIS_H */ diff --git a/contrib/ffmpeg/libavcodec/vorbis_dec.c b/contrib/ffmpeg/libavcodec/vorbis_dec.c new file mode 100644 index 000000000..3ef56dc16 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/vorbis_dec.c @@ -0,0 +1,1638 @@ +/** + * @file vorbis_dec.c + * Vorbis I decoder + * @author Denes Balatoni ( dbalatoni programozo hu ) + + * 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 + */ + +#undef V_DEBUG +//#define V_DEBUG +//#define AV_DEBUG(...) av_log(NULL, AV_LOG_INFO, __VA_ARGS__) + +#include <math.h> + +#define ALT_BITSTREAM_READER_LE +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" + +#include "vorbis.h" +#include "xiph.h" + +#define V_NB_BITS 8 +#define V_NB_BITS2 11 +#define V_MAX_VLCS (1<<16) + +#ifndef V_DEBUG +#define AV_DEBUG(...) +#endif + +#undef NDEBUG +#include <assert.h> + +typedef struct { + uint_fast8_t dimensions; + uint_fast8_t lookup_type; + uint_fast8_t maxdepth; + VLC vlc; + float *codevectors; + unsigned int nb_bits; +} vorbis_codebook; + +typedef union vorbis_floor_u vorbis_floor_data; +typedef struct vorbis_floor0_s vorbis_floor0; +typedef struct vorbis_floor1_s vorbis_floor1; +struct vorbis_context_s; +typedef +uint_fast8_t (* vorbis_floor_decode_func) + (struct vorbis_context_s *, vorbis_floor_data *, float *); +typedef struct { + uint_fast8_t floor_type; + vorbis_floor_decode_func decode; + union vorbis_floor_u + { + struct vorbis_floor0_s + { + uint_fast8_t order; + uint_fast16_t rate; + uint_fast16_t bark_map_size; + int_fast32_t * map[2]; + uint_fast32_t map_size[2]; + uint_fast8_t amplitude_bits; + uint_fast8_t amplitude_offset; + uint_fast8_t num_books; + uint_fast8_t * book_list; + float * lsp; + } t0; + struct vorbis_floor1_s + { + uint_fast8_t partitions; + uint_fast8_t maximum_class; + uint_fast8_t partition_class[32]; + uint_fast8_t class_dimensions[16]; + uint_fast8_t class_subclasses[16]; + uint_fast8_t class_masterbook[16]; + int_fast16_t subclass_books[16][8]; + uint_fast8_t multiplier; + uint_fast16_t x_list_dim; + floor1_entry_t * list; + } t1; + } data; +} vorbis_floor; + +typedef struct { + uint_fast16_t type; + uint_fast32_t begin; + uint_fast32_t end; + uint_fast32_t partition_size; + uint_fast8_t classifications; + uint_fast8_t classbook; + int_fast16_t books[64][8]; + uint_fast8_t maxpass; +} vorbis_residue; + +typedef struct { + uint_fast8_t submaps; + uint_fast16_t coupling_steps; + uint_fast8_t *magnitude; + uint_fast8_t *angle; + uint_fast8_t *mux; + uint_fast8_t submap_floor[16]; + uint_fast8_t submap_residue[16]; +} vorbis_mapping; + +typedef struct { + uint_fast8_t blockflag; + uint_fast16_t windowtype; + uint_fast16_t transformtype; + uint_fast8_t mapping; +} vorbis_mode; + +typedef struct vorbis_context_s { + AVCodecContext *avccontext; + GetBitContext gb; + DSPContext dsp; + + MDCTContext mdct[2]; + uint_fast8_t first_frame; + uint_fast32_t version; + uint_fast8_t audio_channels; + uint_fast32_t audio_samplerate; + uint_fast32_t bitrate_maximum; + uint_fast32_t bitrate_nominal; + uint_fast32_t bitrate_minimum; + uint_fast32_t blocksize[2]; + const float * win[2]; + uint_fast16_t codebook_count; + vorbis_codebook *codebooks; + uint_fast8_t floor_count; + vorbis_floor *floors; + uint_fast8_t residue_count; + vorbis_residue *residues; + uint_fast8_t mapping_count; + vorbis_mapping *mappings; + uint_fast8_t mode_count; + vorbis_mode *modes; + uint_fast8_t mode_number; // mode number for the current packet + float *channel_residues; + float *channel_floors; + float *saved; + uint_fast16_t saved_start; + float *ret; + float *buf; + float *buf_tmp; + uint_fast32_t add_bias; // for float->int conversion + uint_fast32_t exp_bias; +} vorbis_context; + +/* Helper functions */ + +#define BARK(x) \ + (13.1f*atan(0.00074f*(x))+2.24f*atan(1.85e-8f*(x)*(x))+1e-4f*(x)) + +static float vorbisfloat2float(uint_fast32_t val) { + double mant=val&0x1fffff; + long exp=(val&0x7fe00000L)>>21; + if (val&0x80000000) mant=-mant; + return(ldexp(mant, exp-20-768)); +} + + +// Free all allocated memory ----------------------------------------- + +static void vorbis_free(vorbis_context *vc) { + int_fast16_t i; + + av_freep(&vc->channel_residues); + av_freep(&vc->channel_floors); + av_freep(&vc->saved); + av_freep(&vc->ret); + av_freep(&vc->buf); + av_freep(&vc->buf_tmp); + + av_freep(&vc->residues); + av_freep(&vc->modes); + + ff_mdct_end(&vc->mdct[0]); + ff_mdct_end(&vc->mdct[1]); + + for(i=0;i<vc->codebook_count;++i) { + av_free(vc->codebooks[i].codevectors); + free_vlc(&vc->codebooks[i].vlc); + } + av_freep(&vc->codebooks); + + for(i=0;i<vc->floor_count;++i) { + if(vc->floors[i].floor_type==0) { + av_free(vc->floors[i].data.t0.map[0]); + av_free(vc->floors[i].data.t0.map[1]); + av_free(vc->floors[i].data.t0.book_list); + av_free(vc->floors[i].data.t0.lsp); + } + else { + av_free(vc->floors[i].data.t1.list); + } + } + av_freep(&vc->floors); + + for(i=0;i<vc->mapping_count;++i) { + av_free(vc->mappings[i].magnitude); + av_free(vc->mappings[i].angle); + av_free(vc->mappings[i].mux); + } + av_freep(&vc->mappings); + + if(vc->exp_bias){ + av_freep(&vc->win[0]); + av_freep(&vc->win[1]); + } +} + +// Parse setup header ------------------------------------------------- + +// Process codebooks part + +static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) { + uint_fast16_t cb; + uint8_t *tmp_vlc_bits; + uint32_t *tmp_vlc_codes; + GetBitContext *gb=&vc->gb; + + vc->codebook_count=get_bits(gb,8)+1; + + AV_DEBUG(" Codebooks: %d \n", vc->codebook_count); + + vc->codebooks=av_mallocz(vc->codebook_count * sizeof(vorbis_codebook)); + tmp_vlc_bits =av_mallocz(V_MAX_VLCS * sizeof(uint8_t)); + tmp_vlc_codes=av_mallocz(V_MAX_VLCS * sizeof(uint32_t)); + + for(cb=0;cb<vc->codebook_count;++cb) { + vorbis_codebook *codebook_setup=&vc->codebooks[cb]; + uint_fast8_t ordered; + uint_fast32_t t, used_entries=0; + uint_fast32_t entries; + + AV_DEBUG(" %d. Codebook \n", cb); + + if (get_bits(gb, 24)!=0x564342) { + av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook setup data corrupt. \n", cb); + goto error; + } + + codebook_setup->dimensions=get_bits(gb, 16); + if (codebook_setup->dimensions>16) { + av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook's dimension is too large (%d). \n", cb, codebook_setup->dimensions); + goto error; + } + entries=get_bits(gb, 24); + if (entries>V_MAX_VLCS) { + av_log(vc->avccontext, AV_LOG_ERROR, " %"PRIdFAST16". Codebook has too many entries (%"PRIdFAST32"). \n", cb, entries); + goto error; + } + + ordered=get_bits1(gb); + + AV_DEBUG(" codebook_dimensions %d, codebook_entries %d \n", codebook_setup->dimensions, entries); + + if (!ordered) { + uint_fast16_t ce; + uint_fast8_t flag; + uint_fast8_t sparse=get_bits1(gb); + + AV_DEBUG(" not ordered \n"); + + if (sparse) { + AV_DEBUG(" sparse \n"); + + used_entries=0; + for(ce=0;ce<entries;++ce) { + flag=get_bits1(gb); + if (flag) { + tmp_vlc_bits[ce]=get_bits(gb, 5)+1; + ++used_entries; + } + else tmp_vlc_bits[ce]=0; + } + } else { + AV_DEBUG(" not sparse \n"); + + used_entries=entries; + for(ce=0;ce<entries;++ce) { + tmp_vlc_bits[ce]=get_bits(gb, 5)+1; + } + } + } else { + uint_fast16_t current_entry=0; + uint_fast8_t current_length=get_bits(gb, 5)+1; + + AV_DEBUG(" ordered, current length: %d \n", current_length); //FIXME + + used_entries=entries; + for(;current_entry<used_entries;++current_length) { + uint_fast16_t i, number; + + AV_DEBUG(" number bits: %d ", ilog(entries - current_entry)); + + number=get_bits(gb, ilog(entries - current_entry)); + + AV_DEBUG(" number: %d \n", number); + + for(i=current_entry;i<number+current_entry;++i) { + if (i<used_entries) tmp_vlc_bits[i]=current_length; + } + + current_entry+=number; + } + if (current_entry>used_entries) { + av_log(vc->avccontext, AV_LOG_ERROR, " More codelengths than codes in codebook. \n"); + goto error; + } + } + + codebook_setup->lookup_type=get_bits(gb, 4); + + AV_DEBUG(" lookup type: %d : %s \n", codebook_setup->lookup_type, codebook_setup->lookup_type ? "vq" : "no lookup" ); + +// If the codebook is used for (inverse) VQ, calculate codevectors. + + if (codebook_setup->lookup_type==1) { + uint_fast16_t i, j, k; + uint_fast16_t codebook_lookup_values=ff_vorbis_nth_root(entries, codebook_setup->dimensions); + uint_fast16_t codebook_multiplicands[codebook_lookup_values]; + + float codebook_minimum_value=vorbisfloat2float(get_bits_long(gb, 32)); + float codebook_delta_value=vorbisfloat2float(get_bits_long(gb, 32)); + uint_fast8_t codebook_value_bits=get_bits(gb, 4)+1; + uint_fast8_t codebook_sequence_p=get_bits1(gb); + + AV_DEBUG(" We expect %d numbers for building the codevectors. \n", codebook_lookup_values); + AV_DEBUG(" delta %f minmum %f \n", codebook_delta_value, codebook_minimum_value); + + for(i=0;i<codebook_lookup_values;++i) { + codebook_multiplicands[i]=get_bits(gb, codebook_value_bits); + + AV_DEBUG(" multiplicands*delta+minmum : %e \n", (float)codebook_multiplicands[i]*codebook_delta_value+codebook_minimum_value); + AV_DEBUG(" multiplicand %d \n", codebook_multiplicands[i]); + } + +// Weed out unused vlcs and build codevector vector + codebook_setup->codevectors=used_entries ? av_mallocz(used_entries*codebook_setup->dimensions * sizeof(float)) : NULL; + for(j=0, i=0;i<entries;++i) { + uint_fast8_t dim=codebook_setup->dimensions; + + if (tmp_vlc_bits[i]) { + float last=0.0; + uint_fast32_t lookup_offset=i; + +#ifdef V_DEBUG + av_log(vc->avccontext, AV_LOG_INFO, "Lookup offset %d ,", i); +#endif + + for(k=0;k<dim;++k) { + uint_fast32_t multiplicand_offset = lookup_offset % codebook_lookup_values; + codebook_setup->codevectors[j*dim+k]=codebook_multiplicands[multiplicand_offset]*codebook_delta_value+codebook_minimum_value+last; + if (codebook_sequence_p) { + last=codebook_setup->codevectors[j*dim+k]; + } + lookup_offset/=codebook_lookup_values; + } + tmp_vlc_bits[j]=tmp_vlc_bits[i]; + +#ifdef V_DEBUG + av_log(vc->avccontext, AV_LOG_INFO, "real lookup offset %d, vector: ", j); + for(k=0;k<dim;++k) { + av_log(vc->avccontext, AV_LOG_INFO, " %f ", codebook_setup->codevectors[j*dim+k]); + } + av_log(vc->avccontext, AV_LOG_INFO, "\n"); +#endif + + ++j; + } + } + if (j!=used_entries) { + av_log(vc->avccontext, AV_LOG_ERROR, "Bug in codevector vector building code. \n"); + goto error; + } + entries=used_entries; + } + else if (codebook_setup->lookup_type>=2) { + av_log(vc->avccontext, AV_LOG_ERROR, "Codebook lookup type not supported. \n"); + goto error; + } + +// Initialize VLC table + if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) { + av_log(vc->avccontext, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n"); + goto error; + } + codebook_setup->maxdepth=0; + for(t=0;t<entries;++t) + if (tmp_vlc_bits[t]>=codebook_setup->maxdepth) codebook_setup->maxdepth=tmp_vlc_bits[t]; + + if(codebook_setup->maxdepth > 3*V_NB_BITS) codebook_setup->nb_bits=V_NB_BITS2; + else codebook_setup->nb_bits=V_NB_BITS; + + codebook_setup->maxdepth=(codebook_setup->maxdepth+codebook_setup->nb_bits-1)/codebook_setup->nb_bits; + + if (init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits, entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits), sizeof(*tmp_vlc_bits), tmp_vlc_codes, sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes), INIT_VLC_LE)) { + av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n"); + goto error; + } + } + + av_free(tmp_vlc_bits); + av_free(tmp_vlc_codes); + return 0; + +// Error: +error: + av_free(tmp_vlc_bits); + av_free(tmp_vlc_codes); + return 1; +} + +// Process time domain transforms part (unused in Vorbis I) + +static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc) { + GetBitContext *gb=&vc->gb; + uint_fast8_t i; + uint_fast8_t vorbis_time_count=get_bits(gb, 6)+1; + + for(i=0;i<vorbis_time_count;++i) { + uint_fast16_t vorbis_tdtransform=get_bits(gb, 16); + + AV_DEBUG(" Vorbis time domain transform %d: %d \n", vorbis_time_count, vorbis_tdtransform); + + if (vorbis_tdtransform) { + av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n"); + return 1; + } + } + return 0; +} + +// Process floors part + +static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, + vorbis_floor_data *vfu, float *vec); +static void create_map( vorbis_context * vc, uint_fast8_t floor_number ); +static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, + vorbis_floor_data *vfu, float *vec); +static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) { + GetBitContext *gb=&vc->gb; + uint_fast16_t i,j,k; + + vc->floor_count=get_bits(gb, 6)+1; + + vc->floors=av_mallocz(vc->floor_count * sizeof(vorbis_floor)); + + for (i=0;i<vc->floor_count;++i) { + vorbis_floor *floor_setup=&vc->floors[i]; + + floor_setup->floor_type=get_bits(gb, 16); + + AV_DEBUG(" %d. floor type %d \n", i, floor_setup->floor_type); + + if (floor_setup->floor_type==1) { + uint_fast8_t maximum_class=0; + uint_fast8_t rangebits; + uint_fast16_t floor1_values=2; + + floor_setup->decode=vorbis_floor1_decode; + + floor_setup->data.t1.partitions=get_bits(gb, 5); + + AV_DEBUG(" %d.floor: %d partitions \n", i, floor_setup->data.t1.partitions); + + for(j=0;j<floor_setup->data.t1.partitions;++j) { + floor_setup->data.t1.partition_class[j]=get_bits(gb, 4); + if (floor_setup->data.t1.partition_class[j]>maximum_class) maximum_class=floor_setup->data.t1.partition_class[j]; + + AV_DEBUG(" %d. floor %d partition class %d \n", i, j, floor_setup->data.t1.partition_class[j]); + + } + + AV_DEBUG(" maximum class %d \n", maximum_class); + + floor_setup->data.t1.maximum_class=maximum_class; + + for(j=0;j<=maximum_class;++j) { + floor_setup->data.t1.class_dimensions[j]=get_bits(gb, 3)+1; + floor_setup->data.t1.class_subclasses[j]=get_bits(gb, 2); + + AV_DEBUG(" %d floor %d class dim: %d subclasses %d \n", i, j, floor_setup->data.t1.class_dimensions[j], floor_setup->data.t1.class_subclasses[j]); + + if (floor_setup->data.t1.class_subclasses[j]) { + floor_setup->data.t1.class_masterbook[j]=get_bits(gb, 8); + + AV_DEBUG(" masterbook: %d \n", floor_setup->data.t1.class_masterbook[j]); + } + + for(k=0;k<(1<<floor_setup->data.t1.class_subclasses[j]);++k) { + floor_setup->data.t1.subclass_books[j][k]=(int16_t)get_bits(gb, 8)-1; + + AV_DEBUG(" book %d. : %d \n", k, floor_setup->data.t1.subclass_books[j][k]); + } + } + + floor_setup->data.t1.multiplier=get_bits(gb, 2)+1; + floor_setup->data.t1.x_list_dim=2; + + for(j=0;j<floor_setup->data.t1.partitions;++j) { + floor_setup->data.t1.x_list_dim+=floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]]; + } + + floor_setup->data.t1.list=av_mallocz(floor_setup->data.t1.x_list_dim * sizeof(floor1_entry_t)); + + + rangebits=get_bits(gb, 4); + floor_setup->data.t1.list[0].x = 0; + floor_setup->data.t1.list[1].x = (1<<rangebits); + + for(j=0;j<floor_setup->data.t1.partitions;++j) { + for(k=0;k<floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]];++k,++floor1_values) { + floor_setup->data.t1.list[floor1_values].x=get_bits(gb, rangebits); + + AV_DEBUG(" %d. floor1 Y coord. %d \n", floor1_values, floor_setup->data.t1.list[floor1_values].x); + } + } + +// Precalculate order of x coordinates - needed for decode + ff_vorbis_ready_floor1_list(floor_setup->data.t1.list, floor_setup->data.t1.x_list_dim); + } + else if(floor_setup->floor_type==0) { + uint_fast8_t max_codebook_dim=0; + + floor_setup->decode=vorbis_floor0_decode; + + floor_setup->data.t0.order=get_bits(gb, 8); + floor_setup->data.t0.rate=get_bits(gb, 16); + floor_setup->data.t0.bark_map_size=get_bits(gb, 16); + floor_setup->data.t0.amplitude_bits=get_bits(gb, 6); + /* zero would result in a div by zero later * + * 2^0 - 1 == 0 */ + if (floor_setup->data.t0.amplitude_bits == 0) { + av_log(vc->avccontext, AV_LOG_ERROR, + "Floor 0 amplitude bits is 0.\n"); + return 1; + } + floor_setup->data.t0.amplitude_offset=get_bits(gb, 8); + floor_setup->data.t0.num_books=get_bits(gb, 4)+1; + + /* allocate mem for booklist */ + floor_setup->data.t0.book_list= + av_malloc(floor_setup->data.t0.num_books); + if(!floor_setup->data.t0.book_list) { return 1; } + /* read book indexes */ + { + int idx; + uint_fast8_t book_idx; + for (idx=0;idx<floor_setup->data.t0.num_books;++idx) { + book_idx=get_bits(gb, 8); + floor_setup->data.t0.book_list[idx]=book_idx; + if (vc->codebooks[book_idx].dimensions > max_codebook_dim) + max_codebook_dim=vc->codebooks[book_idx].dimensions; + + if (floor_setup->data.t0.book_list[idx]>vc->codebook_count) + return 1; + } + } + + create_map( vc, i ); + + /* allocate mem for lsp coefficients */ + { + /* codebook dim is for padding if codebook dim doesn't * + * divide order+1 then we need to read more data */ + floor_setup->data.t0.lsp= + av_malloc((floor_setup->data.t0.order+1 + max_codebook_dim) + * sizeof(float)); + if(!floor_setup->data.t0.lsp) { return 1; } + } + +#ifdef V_DEBUG /* debug output parsed headers */ + AV_DEBUG("floor0 order: %u\n", floor_setup->data.t0.order); + AV_DEBUG("floor0 rate: %u\n", floor_setup->data.t0.rate); + AV_DEBUG("floor0 bark map size: %u\n", + floor_setup->data.t0.bark_map_size); + AV_DEBUG("floor0 amplitude bits: %u\n", + floor_setup->data.t0.amplitude_bits); + AV_DEBUG("floor0 amplitude offset: %u\n", + floor_setup->data.t0.amplitude_offset); + AV_DEBUG("floor0 number of books: %u\n", + floor_setup->data.t0.num_books); + AV_DEBUG("floor0 book list pointer: %p\n", + floor_setup->data.t0.book_list); + { + int idx; + for (idx=0;idx<floor_setup->data.t0.num_books;++idx) { + AV_DEBUG( " Book %d: %u\n", + idx+1, + floor_setup->data.t0.book_list[idx] ); + } + } +#endif + } + else { + av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n"); + return 1; + } + } + return 0; +} + +// Process residues part + +static int vorbis_parse_setup_hdr_residues(vorbis_context *vc){ + GetBitContext *gb=&vc->gb; + uint_fast8_t i, j, k; + + vc->residue_count=get_bits(gb, 6)+1; + vc->residues=av_mallocz(vc->residue_count * sizeof(vorbis_residue)); + + AV_DEBUG(" There are %d residues. \n", vc->residue_count); + + for(i=0;i<vc->residue_count;++i) { + vorbis_residue *res_setup=&vc->residues[i]; + uint_fast8_t cascade[64]; + uint_fast8_t high_bits; + uint_fast8_t low_bits; + + res_setup->type=get_bits(gb, 16); + + AV_DEBUG(" %d. residue type %d \n", i, res_setup->type); + + res_setup->begin=get_bits(gb, 24); + res_setup->end=get_bits(gb, 24); + res_setup->partition_size=get_bits(gb, 24)+1; + res_setup->classifications=get_bits(gb, 6)+1; + res_setup->classbook=get_bits(gb, 8); + + AV_DEBUG(" begin %d end %d part.size %d classif.s %d classbook %d \n", res_setup->begin, res_setup->end, res_setup->partition_size, + res_setup->classifications, res_setup->classbook); + + for(j=0;j<res_setup->classifications;++j) { + high_bits=0; + low_bits=get_bits(gb, 3); + if (get_bits1(gb)) { + high_bits=get_bits(gb, 5); + } + cascade[j]=(high_bits<<3)+low_bits; + + AV_DEBUG(" %d class casscade depth: %d \n", j, ilog(cascade[j])); + } + + res_setup->maxpass=0; + for(j=0;j<res_setup->classifications;++j) { + for(k=0;k<8;++k) { + if (cascade[j]&(1<<k)) { + res_setup->books[j][k]=get_bits(gb, 8); + + AV_DEBUG(" %d class casscade depth %d book: %d \n", j, k, res_setup->books[j][k]); + + if (k>res_setup->maxpass) { + res_setup->maxpass=k; + } + } else { + res_setup->books[j][k]=-1; + } + } + } + } + return 0; +} + +// Process mappings part + +static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc) { + GetBitContext *gb=&vc->gb; + uint_fast8_t i, j; + + vc->mapping_count=get_bits(gb, 6)+1; + vc->mappings=av_mallocz(vc->mapping_count * sizeof(vorbis_mapping)); + + AV_DEBUG(" There are %d mappings. \n", vc->mapping_count); + + for(i=0;i<vc->mapping_count;++i) { + vorbis_mapping *mapping_setup=&vc->mappings[i]; + + if (get_bits(gb, 16)) { + av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n"); + return 1; + } + if (get_bits1(gb)) { + mapping_setup->submaps=get_bits(gb, 4)+1; + } else { + mapping_setup->submaps=1; + } + + if (get_bits1(gb)) { + mapping_setup->coupling_steps=get_bits(gb, 8)+1; + mapping_setup->magnitude=av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t)); + mapping_setup->angle =av_mallocz(mapping_setup->coupling_steps * sizeof(uint_fast8_t)); + for(j=0;j<mapping_setup->coupling_steps;++j) { + mapping_setup->magnitude[j]=get_bits(gb, ilog(vc->audio_channels-1)); + mapping_setup->angle[j]=get_bits(gb, ilog(vc->audio_channels-1)); + // FIXME: sanity checks + } + } else { + mapping_setup->coupling_steps=0; + } + + AV_DEBUG(" %d mapping coupling steps: %d \n", i, mapping_setup->coupling_steps); + + if(get_bits(gb, 2)) { + av_log(vc->avccontext, AV_LOG_ERROR, "%d. mapping setup data invalid. \n", i); + return 1; // following spec. + } + + if (mapping_setup->submaps>1) { + mapping_setup->mux=av_mallocz(vc->audio_channels * sizeof(uint_fast8_t)); + for(j=0;j<vc->audio_channels;++j) { + mapping_setup->mux[j]=get_bits(gb, 4); + } + } + + for(j=0;j<mapping_setup->submaps;++j) { + skip_bits(gb, 8); // FIXME check? + mapping_setup->submap_floor[j]=get_bits(gb, 8); + mapping_setup->submap_residue[j]=get_bits(gb, 8); + + AV_DEBUG(" %d mapping %d submap : floor %d, residue %d \n", i, j, mapping_setup->submap_floor[j], mapping_setup->submap_residue[j]); + } + } + return 0; +} + +// Process modes part + +static void create_map( vorbis_context * vc, uint_fast8_t floor_number ) +{ + vorbis_floor * floors=vc->floors; + vorbis_floor0 * vf; + int idx; + int_fast8_t blockflag; + int_fast32_t * map; + int_fast32_t n; //TODO: could theoretically be smaller? + + for (blockflag=0;blockflag<2;++blockflag) + { + n=vc->blocksize[blockflag]/2; + floors[floor_number].data.t0.map[blockflag]= + av_malloc((n+1) * sizeof(int_fast32_t)); // n+sentinel + + map=floors[floor_number].data.t0.map[blockflag]; + vf=&floors[floor_number].data.t0; + + for (idx=0; idx<n;++idx) { + map[idx]=floor( BARK((vf->rate*idx)/(2.0f*n)) * + ((vf->bark_map_size)/ + BARK(vf->rate/2.0f )) ); + if (vf->bark_map_size-1 < map[idx]) { + map[idx]=vf->bark_map_size-1; + } + } + map[n]=-1; + vf->map_size[blockflag]=n; + } + +# ifdef V_DEBUG + for(idx=0;idx<=n;++idx) { + AV_DEBUG("floor0 map: map at pos %d is %d\n", + idx, map[idx]); + } +# endif +} + +static int vorbis_parse_setup_hdr_modes(vorbis_context *vc) { + GetBitContext *gb=&vc->gb; + uint_fast8_t i; + + vc->mode_count=get_bits(gb, 6)+1; + vc->modes=av_mallocz(vc->mode_count * sizeof(vorbis_mode)); + + AV_DEBUG(" There are %d modes.\n", vc->mode_count); + + for(i=0;i<vc->mode_count;++i) { + vorbis_mode *mode_setup=&vc->modes[i]; + + mode_setup->blockflag=get_bits1(gb); + mode_setup->windowtype=get_bits(gb, 16); //FIXME check + mode_setup->transformtype=get_bits(gb, 16); //FIXME check + mode_setup->mapping=get_bits(gb, 8); //FIXME check + + AV_DEBUG(" %d mode: blockflag %d, windowtype %d, transformtype %d, mapping %d \n", i, mode_setup->blockflag, mode_setup->windowtype, mode_setup->transformtype, mode_setup->mapping); + } + return 0; +} + +// Process the whole setup header using the functions above + +static int vorbis_parse_setup_hdr(vorbis_context *vc) { + GetBitContext *gb=&vc->gb; + + if ((get_bits(gb, 8)!='v') || (get_bits(gb, 8)!='o') || + (get_bits(gb, 8)!='r') || (get_bits(gb, 8)!='b') || + (get_bits(gb, 8)!='i') || (get_bits(gb, 8)!='s')) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n"); + return 1; + } + + if (vorbis_parse_setup_hdr_codebooks(vc)) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n"); + return 2; + } + if (vorbis_parse_setup_hdr_tdtransforms(vc)) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n"); + return 3; + } + if (vorbis_parse_setup_hdr_floors(vc)) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n"); + return 4; + } + if (vorbis_parse_setup_hdr_residues(vc)) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n"); + return 5; + } + if (vorbis_parse_setup_hdr_mappings(vc)) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n"); + return 6; + } + if (vorbis_parse_setup_hdr_modes(vc)) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n"); + return 7; + } + if (!get_bits1(gb)) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n"); + return 8; // framing flag bit unset error + } + + return 0; +} + +// Process the identification header + +static int vorbis_parse_id_hdr(vorbis_context *vc){ + GetBitContext *gb=&vc->gb; + uint_fast8_t bl0, bl1; + + if ((get_bits(gb, 8)!='v') || (get_bits(gb, 8)!='o') || + (get_bits(gb, 8)!='r') || (get_bits(gb, 8)!='b') || + (get_bits(gb, 8)!='i') || (get_bits(gb, 8)!='s')) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n"); + return 1; + } + + vc->version=get_bits_long(gb, 32); //FIXME check 0 + vc->audio_channels=get_bits(gb, 8); //FIXME check >0 + vc->audio_samplerate=get_bits_long(gb, 32); //FIXME check >0 + vc->bitrate_maximum=get_bits_long(gb, 32); + vc->bitrate_nominal=get_bits_long(gb, 32); + vc->bitrate_minimum=get_bits_long(gb, 32); + bl0=get_bits(gb, 4); + bl1=get_bits(gb, 4); + vc->blocksize[0]=(1<<bl0); + vc->blocksize[1]=(1<<bl1); + if (bl0>13 || bl0<6 || bl1>13 || bl1<6 || bl1<bl0) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n"); + return 3; + } + // output format int16 + if (vc->blocksize[1]/2 * vc->audio_channels * 2 > + AVCODEC_MAX_AUDIO_FRAME_SIZE) { + av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis channel count makes " + "output packets too large.\n"); + return 4; + } + vc->win[0]=ff_vorbis_vwin[bl0-6]; + vc->win[1]=ff_vorbis_vwin[bl1-6]; + + if(vc->exp_bias){ + int i, j; + for(j=0; j<2; j++){ + float *win = av_malloc(vc->blocksize[j]/2 * sizeof(float)); + for(i=0; i<vc->blocksize[j]/2; i++) + win[i] = vc->win[j][i] * (1<<15); + vc->win[j] = win; + } + } + + if ((get_bits1(gb)) == 0) { + av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n"); + return 2; + } + + vc->channel_residues= av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); + vc->channel_floors = av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); + vc->saved = av_mallocz((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); + vc->ret = av_malloc((vc->blocksize[1]/2)*vc->audio_channels * sizeof(float)); + vc->buf = av_malloc( vc->blocksize[1] * sizeof(float)); + vc->buf_tmp = av_malloc( vc->blocksize[1] * sizeof(float)); + vc->saved_start=0; + + ff_mdct_init(&vc->mdct[0], bl0, 1); + ff_mdct_init(&vc->mdct[1], bl1, 1); + + AV_DEBUG(" vorbis version %d \n audio_channels %d \n audio_samplerate %d \n bitrate_max %d \n bitrate_nom %d \n bitrate_min %d \n blk_0 %d blk_1 %d \n ", + vc->version, vc->audio_channels, vc->audio_samplerate, vc->bitrate_maximum, vc->bitrate_nominal, vc->bitrate_minimum, vc->blocksize[0], vc->blocksize[1]); + +/* + BLK=vc->blocksize[0]; + for(i=0;i<BLK/2;++i) { + vc->win[0][i]=sin(0.5*3.14159265358*(sin(((float)i+0.5)/(float)BLK*3.14159265358))*(sin(((float)i+0.5)/(float)BLK*3.14159265358))); + } +*/ + + return 0; +} + +// Process the extradata using the functions above (identification header, setup header) + +static int vorbis_decode_init(AVCodecContext *avccontext) { + vorbis_context *vc = avccontext->priv_data ; + uint8_t *headers = avccontext->extradata; + int headers_len=avccontext->extradata_size; + uint8_t *header_start[3]; + int header_len[3]; + GetBitContext *gb = &(vc->gb); + int hdr_type; + + vc->avccontext = avccontext; + dsputil_init(&vc->dsp, avccontext); + + if(vc->dsp.float_to_int16 == ff_float_to_int16_c) { + vc->add_bias = 385; + vc->exp_bias = 0; + } else { + vc->add_bias = 0; + vc->exp_bias = 15<<23; + } + + if (!headers_len) { + av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n"); + return -1; + } + + if (ff_split_xiph_headers(headers, headers_len, 30, header_start, header_len) < 0) { + av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n"); + return -1; + } + + init_get_bits(gb, header_start[0], header_len[0]*8); + hdr_type=get_bits(gb, 8); + if (hdr_type!=1) { + av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n"); + return -1; + } + if (vorbis_parse_id_hdr(vc)) { + av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n"); + vorbis_free(vc); + return -1; + } + + init_get_bits(gb, header_start[2], header_len[2]*8); + hdr_type=get_bits(gb, 8); + if (hdr_type!=5) { + av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n"); + return -1; + } + if (vorbis_parse_setup_hdr(vc)) { + av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n"); + vorbis_free(vc); + return -1; + } + + avccontext->channels = vc->audio_channels; + avccontext->sample_rate = vc->audio_samplerate; + + return 0 ; +} + +// Decode audiopackets ------------------------------------------------- + +// Read and decode floor + +static uint_fast8_t vorbis_floor0_decode(vorbis_context *vc, + vorbis_floor_data *vfu, float *vec) { + vorbis_floor0 * vf=&vfu->t0; + float * lsp=vf->lsp; + uint_fast32_t amplitude; + uint_fast32_t book_idx; + uint_fast8_t blockflag=vc->modes[vc->mode_number].blockflag; + + amplitude=get_bits(&vc->gb, vf->amplitude_bits); + if (amplitude>0) { + float last = 0; + uint_fast16_t lsp_len = 0; + uint_fast16_t idx; + vorbis_codebook codebook; + + book_idx=get_bits(&vc->gb, ilog(vf->num_books)); + if ( book_idx >= vf->num_books ) { + av_log( vc->avccontext, AV_LOG_ERROR, + "floor0 dec: booknumber too high!\n" ); + book_idx= 0; + //FIXME: look above + } + AV_DEBUG( "floor0 dec: booknumber: %u\n", book_idx ); + codebook=vc->codebooks[vf->book_list[book_idx]]; + + while (lsp_len<vf->order) { + int vec_off; + + AV_DEBUG( "floor0 dec: book dimension: %d\n", codebook.dimensions ); + AV_DEBUG( "floor0 dec: maximum depth: %d\n", codebook.maxdepth ); + /* read temp vector */ + vec_off=get_vlc2(&vc->gb, + codebook.vlc.table, + codebook.nb_bits, + codebook.maxdepth ) * + codebook.dimensions; + AV_DEBUG( "floor0 dec: vector offset: %d\n", vec_off ); + /* copy each vector component and add last to it */ + for (idx=0; idx<codebook.dimensions; ++idx) { + lsp[lsp_len+idx]=codebook.codevectors[vec_off+idx]+last; + } + last=lsp[lsp_len+idx-1]; /* set last to last vector component */ + + lsp_len += codebook.dimensions; + } +#ifdef V_DEBUG + /* DEBUG: output lsp coeffs */ + { + int idx; + for ( idx = 0; idx < lsp_len; ++idx ) + AV_DEBUG("floor0 dec: coeff at %d is %f\n", idx, lsp[idx] ); + } +#endif + + /* synthesize floor output vector */ + { + int i; + int order=vf->order; + float wstep=M_PI/vf->bark_map_size; + + for(i=0;i<order;i++) { lsp[i]=2.0f*cos(lsp[i]); } + + AV_DEBUG("floor0 synth: map_size=%d; m=%d; wstep=%f\n", + vf->map_size, order, wstep); + + i=0; + while(i<vf->map_size[blockflag]) { + int j, iter_cond=vf->map[blockflag][i]; + float p=0.5f; + float q=0.5f; + float two_cos_w=2.0f*cos(wstep*iter_cond); // needed all times + + /* similar part for the q and p products */ + for(j=0;j<order;j+=2) { + q *= lsp[j] -two_cos_w; + p *= lsp[j+1]-two_cos_w; + } + if(j==order) { // even order + p *= p*(2.0f-two_cos_w); + q *= q*(2.0f+two_cos_w); + } + else { // odd order + q *= two_cos_w-lsp[j]; // one more time for q + + /* final step and square */ + p *= p*(4.f-two_cos_w*two_cos_w); + q *= q; + } + + /* calculate linear floor value */ + { + q=exp( ( + ( (amplitude*vf->amplitude_offset)/ + (((1<<vf->amplitude_bits)-1) * sqrt(p+q)) ) + - vf->amplitude_offset ) * .11512925f + ); + } + + /* fill vector */ + do { vec[i]=q; ++i; }while(vf->map[blockflag][i]==iter_cond); + } + } + } + else { + /* this channel is unused */ + return 1; + } + + AV_DEBUG(" Floor0 decoded\n"); + + return 0; +} + +static uint_fast8_t vorbis_floor1_decode(vorbis_context *vc, vorbis_floor_data *vfu, float *vec) { + vorbis_floor1 * vf=&vfu->t1; + GetBitContext *gb=&vc->gb; + uint_fast16_t range_v[4]={ 256, 128, 86, 64 }; + uint_fast16_t range=range_v[vf->multiplier-1]; + uint_fast16_t floor1_Y[vf->x_list_dim]; + uint_fast16_t floor1_Y_final[vf->x_list_dim]; + int floor1_flag[vf->x_list_dim]; + uint_fast8_t class_; + uint_fast8_t cdim; + uint_fast8_t cbits; + uint_fast8_t csub; + uint_fast8_t cval; + int_fast16_t book; + uint_fast16_t offset; + uint_fast16_t i,j; + /*u*/int_fast16_t adx, ady, off, predicted; // WTF ? dy/adx= (unsigned)dy/adx ? + int_fast16_t dy, err; + + + if (!get_bits1(gb)) return 1; // silence + +// Read values (or differences) for the floor's points + + floor1_Y[0]=get_bits(gb, ilog(range-1)); + floor1_Y[1]=get_bits(gb, ilog(range-1)); + + AV_DEBUG("floor 0 Y %d floor 1 Y %d \n", floor1_Y[0], floor1_Y[1]); + + offset=2; + for(i=0;i<vf->partitions;++i) { + class_=vf->partition_class[i]; + cdim=vf->class_dimensions[class_]; + cbits=vf->class_subclasses[class_]; + csub=(1<<cbits)-1; + cval=0; + + AV_DEBUG("Cbits %d \n", cbits); + + if (cbits) { // this reads all subclasses for this partition's class + cval=get_vlc2(gb, vc->codebooks[vf->class_masterbook[class_]].vlc.table, + vc->codebooks[vf->class_masterbook[class_]].nb_bits, 3); + } + + for(j=0;j<cdim;++j) { + book=vf->subclass_books[class_][cval & csub]; + + AV_DEBUG("book %d Cbits %d cval %d bits:%d \n", book, cbits, cval, get_bits_count(gb)); + + cval=cval>>cbits; + if (book>-1) { + floor1_Y[offset+j]=get_vlc2(gb, vc->codebooks[book].vlc.table, + vc->codebooks[book].nb_bits, 3); + } else { + floor1_Y[offset+j]=0; + } + + AV_DEBUG(" floor(%d) = %d \n", vf->list[offset+j].x, floor1_Y[offset+j]); + } + offset+=cdim; + } + +// Amplitude calculation from the differences + + floor1_flag[0]=1; + floor1_flag[1]=1; + floor1_Y_final[0]=floor1_Y[0]; + floor1_Y_final[1]=floor1_Y[1]; + + for(i=2;i<vf->x_list_dim;++i) { + uint_fast16_t val, highroom, lowroom, room; + uint_fast16_t high_neigh_offs; + uint_fast16_t low_neigh_offs; + + low_neigh_offs=vf->list[i].low; + high_neigh_offs=vf->list[i].high; + dy=floor1_Y_final[high_neigh_offs]-floor1_Y_final[low_neigh_offs]; // render_point begin + adx=vf->list[high_neigh_offs].x-vf->list[low_neigh_offs].x; + ady= FFABS(dy); + err=ady*(vf->list[i].x-vf->list[low_neigh_offs].x); + off=(int16_t)err/(int16_t)adx; + if (dy<0) { + predicted=floor1_Y_final[low_neigh_offs]-off; + } else { + predicted=floor1_Y_final[low_neigh_offs]+off; + } // render_point end + + val=floor1_Y[i]; + highroom=range-predicted; + lowroom=predicted; + if (highroom < lowroom) { + room=highroom*2; + } else { + room=lowroom*2; // SPEC mispelling + } + if (val) { + floor1_flag[low_neigh_offs]=1; + floor1_flag[high_neigh_offs]=1; + floor1_flag[i]=1; + if (val>=room) { + if (highroom > lowroom) { + floor1_Y_final[i]=val-lowroom+predicted; + } else { + floor1_Y_final[i]=predicted-val+highroom-1; + } + } else { + if (val & 1) { + floor1_Y_final[i]=predicted-(val+1)/2; + } else { + floor1_Y_final[i]=predicted+val/2; + } + } + } else { + floor1_flag[i]=0; + floor1_Y_final[i]=predicted; + } + + AV_DEBUG(" Decoded floor(%d) = %d / val %d \n", vf->list[i].x, floor1_Y_final[i], val); + } + +// Curve synth - connect the calculated dots and convert from dB scale FIXME optimize ? + + ff_vorbis_floor1_render_list(vf->list, vf->x_list_dim, floor1_Y_final, floor1_flag, vf->multiplier, vec, vf->list[1].x); + + AV_DEBUG(" Floor decoded\n"); + + return 0; +} + +// Read and decode residue + +static int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, uint_fast8_t ch, uint_fast8_t *do_not_decode, float *vec, uint_fast16_t vlen) { + GetBitContext *gb=&vc->gb; + uint_fast8_t c_p_c=vc->codebooks[vr->classbook].dimensions; + uint_fast16_t n_to_read=vr->end-vr->begin; + uint_fast16_t ptns_to_read=n_to_read/vr->partition_size; + uint_fast8_t classifs[ptns_to_read*vc->audio_channels]; + uint_fast8_t pass; + uint_fast8_t ch_used; + uint_fast8_t i,j,l; + uint_fast16_t k; + + if (vr->type==2) { + for(j=1;j<ch;++j) { + do_not_decode[0]&=do_not_decode[j]; // FIXME - clobbering input + } + if (do_not_decode[0]) return 0; + ch_used=1; + } else { + ch_used=ch; + } + + AV_DEBUG(" residue type 0/1/2 decode begin, ch: %d cpc %d \n", ch, c_p_c); + + for(pass=0;pass<=vr->maxpass;++pass) { // FIXME OPTIMIZE? + uint_fast16_t voffset; + uint_fast16_t partition_count; + uint_fast16_t j_times_ptns_to_read; + + voffset=vr->begin; + for(partition_count=0;partition_count<ptns_to_read;) { // SPEC error + if (!pass) { + uint_fast32_t inverse_class = ff_inverse[vr->classifications]; + for(j_times_ptns_to_read=0, j=0;j<ch_used;++j) { + if (!do_not_decode[j]) { + uint_fast32_t temp=get_vlc2(gb, vc->codebooks[vr->classbook].vlc.table, + vc->codebooks[vr->classbook].nb_bits, 3); + + AV_DEBUG("Classword: %d \n", temp); + + assert(vr->classifications > 1 && temp<=65536); //needed for inverse[] + for(i=0;i<c_p_c;++i) { + uint_fast32_t temp2; + + temp2=(((uint_fast64_t)temp) * inverse_class)>>32; + if (partition_count+c_p_c-1-i < ptns_to_read) { + classifs[j_times_ptns_to_read+partition_count+c_p_c-1-i]=temp-temp2*vr->classifications; + } + temp=temp2; + } + } + j_times_ptns_to_read+=ptns_to_read; + } + } + for(i=0;(i<c_p_c) && (partition_count<ptns_to_read);++i) { + for(j_times_ptns_to_read=0, j=0;j<ch_used;++j) { + uint_fast16_t voffs; + + if (!do_not_decode[j]) { + uint_fast8_t vqclass=classifs[j_times_ptns_to_read+partition_count]; + int_fast16_t vqbook=vr->books[vqclass][pass]; + + if (vqbook>=0 && vc->codebooks[vqbook].codevectors) { + uint_fast16_t coffs; + unsigned dim= vc->codebooks[vqbook].dimensions; // not uint_fast8_t: 64bit is slower here on amd64 + uint_fast16_t step= dim==1 ? vr->partition_size + : FASTDIV(vr->partition_size, dim); + vorbis_codebook codebook= vc->codebooks[vqbook]; + + if (vr->type==0) { + + voffs=voffset+j*vlen; + for(k=0;k<step;++k) { + coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; + for(l=0;l<dim;++l) { + vec[voffs+k+l*step]+=codebook.codevectors[coffs+l]; // FPMATH + } + } + } + else if (vr->type==1) { + voffs=voffset+j*vlen; + for(k=0;k<step;++k) { + coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; + for(l=0;l<dim;++l, ++voffs) { + vec[voffs]+=codebook.codevectors[coffs+l]; // FPMATH + + AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d \n", pass, voffs, vec[voffs], codebook.codevectors[coffs+l], coffs); + } + } + } + else if (vr->type==2 && ch==2 && (voffset&1)==0 && (dim&1)==0) { // most frequent case optimized + voffs=voffset>>1; + + if(dim==2) { + for(k=0;k<step;++k) { + coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * 2; + vec[voffs+k ]+=codebook.codevectors[coffs ]; // FPMATH + vec[voffs+k+vlen]+=codebook.codevectors[coffs+1]; // FPMATH + } + } else + for(k=0;k<step;++k) { + coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; + for(l=0;l<dim;l+=2, voffs++) { + vec[voffs ]+=codebook.codevectors[coffs+l ]; // FPMATH + vec[voffs+vlen]+=codebook.codevectors[coffs+l+1]; // FPMATH + + AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d+%d \n", pass, voffset/ch+(voffs%ch)*vlen, vec[voffset/ch+(voffs%ch)*vlen], codebook.codevectors[coffs+l], coffs, l); + } + } + + } + else if (vr->type==2) { + voffs=voffset; + + for(k=0;k<step;++k) { + coffs=get_vlc2(gb, codebook.vlc.table, codebook.nb_bits, 3) * dim; + for(l=0;l<dim;++l, ++voffs) { + vec[voffs/ch+(voffs%ch)*vlen]+=codebook.codevectors[coffs+l]; // FPMATH FIXME use if and counter instead of / and % + + AV_DEBUG(" pass %d offs: %d curr: %f change: %f cv offs.: %d+%d \n", pass, voffset/ch+(voffs%ch)*vlen, vec[voffset/ch+(voffs%ch)*vlen], codebook.codevectors[coffs+l], coffs, l); + } + } + } else { + av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n"); + return 1; + } + } + } + j_times_ptns_to_read+=ptns_to_read; + } + ++partition_count; + voffset+=vr->partition_size; + } + } + } + return 0; +} + +void vorbis_inverse_coupling(float *mag, float *ang, int blocksize) +{ + int i; + for(i=0; i<blocksize; i++) + { + if (mag[i]>0.0) { + if (ang[i]>0.0) { + ang[i]=mag[i]-ang[i]; + } else { + float temp=ang[i]; + ang[i]=mag[i]; + mag[i]+=temp; + } + } else { + if (ang[i]>0.0) { + ang[i]+=mag[i]; + } else { + float temp=ang[i]; + ang[i]=mag[i]; + mag[i]-=temp; + } + } + } +} + +// Decode the audio packet using the functions above + +static int vorbis_parse_audio_packet(vorbis_context *vc) { + GetBitContext *gb=&vc->gb; + + uint_fast8_t previous_window=0,next_window=0; + uint_fast8_t mode_number; + uint_fast16_t blocksize; + int_fast32_t i,j; + uint_fast8_t no_residue[vc->audio_channels]; + uint_fast8_t do_not_decode[vc->audio_channels]; + vorbis_mapping *mapping; + float *ch_res_ptr=vc->channel_residues; + float *ch_floor_ptr=vc->channel_floors; + uint_fast8_t res_chan[vc->audio_channels]; + uint_fast8_t res_num=0; + int_fast16_t retlen=0; + uint_fast16_t saved_start=0; + float fadd_bias = vc->add_bias; + + if (get_bits1(gb)) { + av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n"); + return -1; // packet type not audio + } + + if (vc->mode_count==1) { + mode_number=0; + } else { + mode_number=get_bits(gb, ilog(vc->mode_count-1)); + } + vc->mode_number=mode_number; + mapping=&vc->mappings[vc->modes[mode_number].mapping]; + + AV_DEBUG(" Mode number: %d , mapping: %d , blocktype %d \n", mode_number, vc->modes[mode_number].mapping, vc->modes[mode_number].blockflag); + + if (vc->modes[mode_number].blockflag) { + previous_window=get_bits1(gb); + next_window=get_bits1(gb); + } + + blocksize=vc->blocksize[vc->modes[mode_number].blockflag]; + memset(ch_res_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2); //FIXME can this be removed ? + memset(ch_floor_ptr, 0, sizeof(float)*vc->audio_channels*blocksize/2); //FIXME can this be removed ? + +// Decode floor + + for(i=0;i<vc->audio_channels;++i) { + vorbis_floor *floor; + if (mapping->submaps>1) { + floor=&vc->floors[mapping->submap_floor[mapping->mux[i]]]; + } else { + floor=&vc->floors[mapping->submap_floor[0]]; + } + + no_residue[i]=floor->decode(vc, &floor->data, ch_floor_ptr); + ch_floor_ptr+=blocksize/2; + } + +// Nonzero vector propagate + + for(i=mapping->coupling_steps-1;i>=0;--i) { + if (!(no_residue[mapping->magnitude[i]] & no_residue[mapping->angle[i]])) { + no_residue[mapping->magnitude[i]]=0; + no_residue[mapping->angle[i]]=0; + } + } + +// Decode residue + + for(i=0;i<mapping->submaps;++i) { + vorbis_residue *residue; + uint_fast8_t ch=0; + + for(j=0;j<vc->audio_channels;++j) { + if ((mapping->submaps==1) || (i=mapping->mux[j])) { + res_chan[j]=res_num; + if (no_residue[j]) { + do_not_decode[ch]=1; + } else { + do_not_decode[ch]=0; + } + ++ch; + ++res_num; + } + } + residue=&vc->residues[mapping->submap_residue[i]]; + vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, blocksize/2); + + ch_res_ptr+=ch*blocksize/2; + } + +// Inverse coupling + + for(i=mapping->coupling_steps-1;i>=0;--i) { //warning: i has to be signed + float *mag, *ang; + + mag=vc->channel_residues+res_chan[mapping->magnitude[i]]*blocksize/2; + ang=vc->channel_residues+res_chan[mapping->angle[i]]*blocksize/2; + vc->dsp.vorbis_inverse_coupling(mag, ang, blocksize/2); + } + +// Dotproduct + + for(j=0, ch_floor_ptr=vc->channel_floors;j<vc->audio_channels;++j,ch_floor_ptr+=blocksize/2) { + ch_res_ptr=vc->channel_residues+res_chan[j]*blocksize/2; + vc->dsp.vector_fmul(ch_floor_ptr, ch_res_ptr, blocksize/2); + } + +// MDCT, overlap/add, save data for next overlapping FPMATH + + for(j=0;j<vc->audio_channels;++j) { + uint_fast8_t step=vc->audio_channels; + uint_fast16_t k; + float *saved=vc->saved+j*vc->blocksize[1]/2; + float *ret=vc->ret; + const float *lwin=vc->win[1]; + const float *swin=vc->win[0]; + float *buf=vc->buf; + float *buf_tmp=vc->buf_tmp; + + ch_floor_ptr=vc->channel_floors+j*blocksize/2; + + saved_start=vc->saved_start; + + vc->mdct[0].fft.imdct_calc(&vc->mdct[vc->modes[mode_number].blockflag], buf, ch_floor_ptr, buf_tmp); + + //FIXME process channels together, to allow faster simd vector_fmul_add_add? + if (vc->modes[mode_number].blockflag) { + // -- overlap/add + if (previous_window) { + vc->dsp.vector_fmul_add_add(ret+j, buf, lwin, saved, vc->add_bias, vc->blocksize[1]/2, step); + retlen=vc->blocksize[1]/2; + } else { + int len = (vc->blocksize[1]-vc->blocksize[0])/4; + buf += len; + vc->dsp.vector_fmul_add_add(ret+j, buf, swin, saved, vc->add_bias, vc->blocksize[0]/2, step); + k = vc->blocksize[0]/2*step + j; + buf += vc->blocksize[0]/2; + if(vc->exp_bias){ + for(i=0; i<len; i++, k+=step) + ((uint32_t*)ret)[k] = ((uint32_t*)buf)[i] + vc->exp_bias; // ret[k]=buf[i]*(1<<bias) + } else { + for(i=0; i<len; i++, k+=step) + ret[k] = buf[i] + fadd_bias; + } + buf=vc->buf; + retlen=vc->blocksize[0]/2+len; + } + // -- save + if (next_window) { + buf += vc->blocksize[1]/2; + vc->dsp.vector_fmul_reverse(saved, buf, lwin, vc->blocksize[1]/2); + saved_start=0; + } else { + saved_start=(vc->blocksize[1]-vc->blocksize[0])/4; + buf += vc->blocksize[1]/2; + for(i=0; i<saved_start; i++) + ((uint32_t*)saved)[i] = ((uint32_t*)buf)[i] + vc->exp_bias; + vc->dsp.vector_fmul_reverse(saved+saved_start, buf+saved_start, swin, vc->blocksize[0]/2); + } + } else { + // --overlap/add + if(vc->add_bias) { + for(k=j, i=0;i<saved_start;++i, k+=step) + ret[k] = saved[i] + fadd_bias; + } else { + for(k=j, i=0;i<saved_start;++i, k+=step) + ret[k] = saved[i]; + } + vc->dsp.vector_fmul_add_add(ret+k, buf, swin, saved+saved_start, vc->add_bias, vc->blocksize[0]/2, step); + retlen=saved_start+vc->blocksize[0]/2; + // -- save + buf += vc->blocksize[0]/2; + vc->dsp.vector_fmul_reverse(saved, buf, swin, vc->blocksize[0]/2); + saved_start=0; + } + } + vc->saved_start=saved_start; + + return retlen*vc->audio_channels; +} + +// Return the decoded audio packet through the standard api + +static int vorbis_decode_frame(AVCodecContext *avccontext, + void *data, int *data_size, + const uint8_t *buf, int buf_size) +{ + vorbis_context *vc = avccontext->priv_data ; + GetBitContext *gb = &(vc->gb); + + int_fast16_t len; + + if(!buf_size){ + return 0; + } + + AV_DEBUG("packet length %d \n", buf_size); + + init_get_bits(gb, buf, buf_size*8); + + len=vorbis_parse_audio_packet(vc); + + if (len<=0) { + *data_size=0; + return buf_size; + } + + if (!vc->first_frame) { + vc->first_frame=1; + *data_size=0; + return buf_size ; + } + + AV_DEBUG("parsed %d bytes %d bits, returned %d samples (*ch*bits) \n", get_bits_count(gb)/8, get_bits_count(gb)%8, len); + + vc->dsp.float_to_int16(data, vc->ret, len); + *data_size=len*2; + + return buf_size ; +} + +// Close decoder + +static int vorbis_decode_close(AVCodecContext *avccontext) { + vorbis_context *vc = avccontext->priv_data; + + vorbis_free(vc); + + return 0 ; +} + +AVCodec vorbis_decoder = { + "vorbis", + CODEC_TYPE_AUDIO, + CODEC_ID_VORBIS, + sizeof(vorbis_context), + vorbis_decode_init, + NULL, + vorbis_decode_close, + vorbis_decode_frame, +}; + diff --git a/contrib/ffmpeg/libavcodec/vorbis_enc.c b/contrib/ffmpeg/libavcodec/vorbis_enc.c index 3789ef7a2..391202211 100644 --- a/contrib/ffmpeg/libavcodec/vorbis_enc.c +++ b/contrib/ffmpeg/libavcodec/vorbis_enc.c @@ -15,7 +15,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** @@ -756,7 +756,7 @@ static void floor_encode(venc_context_t * venc, floor_t * fc, PutBitContext * pb int maxval = 1; if (c->books[l] != -1) maxval = venc->codebooks[c->books[l]].nentries; - // coded could be -1, but this still works, cause thats 0 + // coded could be -1, but this still works, cause that is 0 if (coded[counter + k] < maxval) break; } assert(l != csub); diff --git a/contrib/ffmpeg/libavcodec/vorbis_enc_data.h b/contrib/ffmpeg/libavcodec/vorbis_enc_data.h index e56dc5df5..1b4be9aaa 100644 --- a/contrib/ffmpeg/libavcodec/vorbis_enc_data.h +++ b/contrib/ffmpeg/libavcodec/vorbis_enc_data.h @@ -15,9 +15,14 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_VORBIS_ENC_DATA_H +#define FFMPEG_VORBIS_ENC_DATA_H + +#include <stdint.h> + static const uint8_t codebook0[] = { 2, 10, 8, 14, 7, 12, 11, 14, 1, 5, 3, 7, 4, 9, 7, 13, @@ -496,3 +501,5 @@ static const struct { { 4, 2, 2, (const int[]){ -1, 9, 10, 11 } }, { 3, 2, 3, (const int[]){ -1, 12, 13, 14 } }, }; + +#endif /* FFMPEG_VORBIS_ENC_DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/vp3.c b/contrib/ffmpeg/libavcodec/vp3.c index bf17c2da7..eade1eb3c 100644 --- a/contrib/ffmpeg/libavcodec/vp3.c +++ b/contrib/ffmpeg/libavcodec/vp3.c @@ -16,7 +16,6 @@ * 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 - * */ /** @@ -35,7 +34,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" @@ -275,7 +273,7 @@ typedef struct Vp3DecodeContext { * which of the fragments are coded */ int *coded_fragment_list; int coded_fragment_list_index; - int pixel_addresses_inited; + int pixel_addresses_initialized; VLC dc_vlc[16]; VLC ac_vlc_1[16]; @@ -331,8 +329,6 @@ typedef struct Vp3DecodeContext { int bounding_values_array[256]; } Vp3DecodeContext; -static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb); - /************************************************************************ * VP3 specific functions ************************************************************************/ @@ -477,7 +473,7 @@ static int init_block_mapping(Vp3DecodeContext *s) current_width = -1; current_height = 0; superblock_row_inc = s->macroblock_width - - (s->y_superblock_width * 2 - s->macroblock_width);; + (s->y_superblock_width * 2 - s->macroblock_width); hilbert = hilbert_walk_mb; mapping_index = 0; current_macroblock = -1; @@ -690,7 +686,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) } else { /* unpack the list of partially-coded superblocks */ - bit = get_bits(gb, 1); + bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; @@ -726,7 +722,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) current_superblock = 0; current_run = 0; - bit = get_bits(gb, 1); + bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; @@ -757,7 +753,7 @@ static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) if (decode_partial_blocks) { current_run = 0; - bit = get_bits(gb, 1); + bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; @@ -983,7 +979,7 @@ static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb) memset(motion_y, 0, 6 * sizeof(int)); /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */ - coding_mode = get_bits(gb, 1); + coding_mode = get_bits1(gb); debug_vectors(" using %s scheme for unpacking motion vectors\n", (coding_mode == 0) ? "VLC" : "fixed-length"); @@ -1955,7 +1951,6 @@ static int vp3_decode_init(AVCodecContext *avctx) s->width = (avctx->width + 15) & 0xFFFFFFF0; s->height = (avctx->height + 15) & 0xFFFFFFF0; avctx->pix_fmt = PIX_FMT_YUV420P; - avctx->has_b_frames = 0; if(avctx->idct_algo==FF_IDCT_AUTO) avctx->idct_algo=FF_IDCT_VP3; dsputil_init(&s->dsp, avctx); @@ -2014,7 +2009,7 @@ static int vp3_decode_init(AVCodecContext *avctx) s->all_fragments = av_malloc(s->fragment_count * sizeof(Vp3Fragment)); s->coeffs = av_malloc(s->fragment_count * sizeof(Coeff) * 65); s->coded_fragment_list = av_malloc(s->fragment_count * sizeof(int)); - s->pixel_addresses_inited = 0; + s->pixel_addresses_initialized = 0; if (!s->theora_tables) { @@ -2131,7 +2126,7 @@ static int vp3_decode_init(AVCodecContext *avctx) */ static int vp3_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { Vp3DecodeContext *s = avctx->priv_data; GetBitContext gb; @@ -2142,28 +2137,8 @@ static int vp3_decode_frame(AVCodecContext *avctx, if (s->theora && get_bits1(&gb)) { -#if 1 av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n"); return -1; -#else - int ptype = get_bits(&gb, 7); - - skip_bits(&gb, 6*8); /* "theora" */ - - switch(ptype) - { - case 1: - theora_decode_comments(avctx, &gb); - break; - case 2: - theora_decode_tables(avctx, &gb); - init_dequantizer(s); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown Theora config packet: %d\n", ptype); - } - return buf_size; -#endif } s->keyframe = !get_bits1(&gb); @@ -2228,18 +2203,18 @@ static int vp3_decode_frame(AVCodecContext *avctx, s->current_frame= s->golden_frame; /* time to figure out pixel addresses? */ - if (!s->pixel_addresses_inited) + if (!s->pixel_addresses_initialized) { if (!s->flipped_image) vp3_calculate_pixel_addresses(s); else theora_calculate_pixel_addresses(s); - s->pixel_addresses_inited = 1; + s->pixel_addresses_initialized = 1; } } else { /* allocate a new current frame */ s->current_frame.reference = 3; - if (!s->pixel_addresses_inited) { + if (!s->pixel_addresses_initialized) { av_log(s->avctx, AV_LOG_ERROR, "vp3: first frame not a keyframe\n"); return -1; } @@ -2338,7 +2313,9 @@ if (!s->keyframe) { static int vp3_decode_end(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; + int i; + av_free(s->superblock_coding); av_free(s->all_fragments); av_free(s->coeffs); av_free(s->coded_fragment_list); @@ -2347,6 +2324,19 @@ static int vp3_decode_end(AVCodecContext *avctx) av_free(s->macroblock_fragments); av_free(s->macroblock_coding); + for (i = 0; i < 16; i++) { + free_vlc(&s->dc_vlc[i]); + free_vlc(&s->ac_vlc_1[i]); + free_vlc(&s->ac_vlc_2[i]); + free_vlc(&s->ac_vlc_3[i]); + free_vlc(&s->ac_vlc_4[i]); + } + + free_vlc(&s->superblock_run_length_vlc); + free_vlc(&s->fragment_run_length_vlc); + free_vlc(&s->mode_code_vlc); + free_vlc(&s->motion_vector_vlc); + /* release all frames */ if (s->golden_frame.data[0] && s->golden_frame.data[0] != s->last_frame.data[0]) avctx->release_buffer(avctx, &s->golden_frame); @@ -2362,7 +2352,7 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) { Vp3DecodeContext *s = avctx->priv_data; - if (get_bits(gb, 1)) { + if (get_bits1(gb)) { int token; if (s->entries >= 32) { /* overflow */ av_log(avctx, AV_LOG_ERROR, "huffman tree overflow\n"); @@ -2390,12 +2380,14 @@ static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb) return 0; } +#ifdef CONFIG_THEORA_DECODER static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) { Vp3DecodeContext *s = avctx->priv_data; + int visible_width, visible_height; s->theora = get_bits_long(gb, 24); - av_log(avctx, AV_LOG_INFO, "Theora bitstream version %X\n", s->theora); + av_log(avctx, AV_LOG_DEBUG, "Theora bitstream version %X\n", s->theora); /* 3.2.0 aka alpha3 has the same frame orientation as original vp3 */ /* but previous versions have the image flipped relative to vp3 */ @@ -2421,20 +2413,15 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) skip_bits(gb, 32); /* total number of blocks in a frame */ skip_bits(gb, 4); /* total number of blocks in a frame */ skip_bits(gb, 32); /* total number of macroblocks in a frame */ - - skip_bits(gb, 24); /* frame width */ - skip_bits(gb, 24); /* frame height */ - } - else - { - skip_bits(gb, 24); /* frame width */ - skip_bits(gb, 24); /* frame height */ } - if (s->theora >= 0x030200) { - skip_bits(gb, 8); /* offset x */ - skip_bits(gb, 8); /* offset y */ - } + visible_width = get_bits_long(gb, 24); + visible_height = get_bits_long(gb, 24); + + if (s->theora >= 0x030200) { + skip_bits(gb, 8); /* offset x */ + skip_bits(gb, 8); /* offset y */ + } skip_bits(gb, 32); /* fps numerator */ skip_bits(gb, 32); /* fps denumerator */ @@ -2460,8 +2447,11 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) // align_get_bits(gb); - avctx->width = s->width; - avctx->height = s->height; + if ( visible_width <= s->width && visible_width > s->width-16 + && visible_height <= s->height && visible_height > s->height-16) + avcodec_set_dimensions(avctx, visible_width, visible_height); + else + avcodec_set_dimensions(avctx, s->width, s->height); return 0; } @@ -2513,10 +2503,10 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) for (plane = 0; plane <= 2; plane++) { int newqr= 1; if (inter || plane > 0) - newqr = get_bits(gb, 1); + newqr = get_bits1(gb); if (!newqr) { int qtj, plj; - if(inter && get_bits(gb, 1)){ + if(inter && get_bits1(gb)){ qtj = 0; plj = plane; }else{ @@ -2557,7 +2547,7 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) for (s->hti = 0; s->hti < 80; s->hti++) { s->entries = 0; s->huff_code_size = 1; - if (!get_bits(gb, 1)) { + if (!get_bits1(gb)) { s->hbits = 0; read_huffman_tree(avctx, gb); s->hbits = 1; @@ -2570,7 +2560,6 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) return 0; } -#if ENABLE_THEORA_DECODER static int theora_decode_init(AVCodecContext *avctx) { Vp3DecodeContext *s = avctx->priv_data; @@ -2634,32 +2623,30 @@ static int theora_decode_init(AVCodecContext *avctx) vp3_decode_init(avctx); return 0; } -#endif -AVCodec vp3_decoder = { - "vp3", +AVCodec theora_decoder = { + "theora", CODEC_TYPE_VIDEO, - CODEC_ID_VP3, + CODEC_ID_THEORA, sizeof(Vp3DecodeContext), - vp3_decode_init, + theora_decode_init, NULL, vp3_decode_end, vp3_decode_frame, 0, NULL }; +#endif -#if ENABLE_THEORA_DECODER -AVCodec theora_decoder = { - "theora", +AVCodec vp3_decoder = { + "vp3", CODEC_TYPE_VIDEO, - CODEC_ID_THEORA, + CODEC_ID_VP3, sizeof(Vp3DecodeContext), - theora_decode_init, + vp3_decode_init, NULL, vp3_decode_end, vp3_decode_frame, 0, NULL }; -#endif diff --git a/contrib/ffmpeg/libavcodec/vp3data.h b/contrib/ffmpeg/libavcodec/vp3data.h index d69ddfa28..aa33b8327 100644 --- a/contrib/ffmpeg/libavcodec/vp3data.h +++ b/contrib/ffmpeg/libavcodec/vp3data.h @@ -18,8 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef VP3DATA_H -#define VP3DATA_H +#ifndef FFMPEG_VP3DATA_H +#define FFMPEG_VP3DATA_H + +#include <stdint.h> +#include <stdlib.h> /* these coefficients dequantize intraframe Y plane coefficients * (note: same as JPEG) */ @@ -3175,4 +3178,4 @@ static const uint16_t ac_bias_3[16][32][2] = { } }; -#endif /* VP3DATA_H */ +#endif /* FFMPEG_VP3DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/vp3dsp.c b/contrib/ffmpeg/libavcodec/vp3dsp.c index bb9fed091..fc8f54d8d 100644 --- a/contrib/ffmpeg/libavcodec/vp3dsp.c +++ b/contrib/ffmpeg/libavcodec/vp3dsp.c @@ -24,7 +24,6 @@ * source code. */ -#include "common.h" #include "avcodec.h" #include "dsputil.h" diff --git a/contrib/ffmpeg/libavcodec/vp5.c b/contrib/ffmpeg/libavcodec/vp5.c index 8a8c217c0..fc8119c2f 100644 --- a/contrib/ffmpeg/libavcodec/vp5.c +++ b/contrib/ffmpeg/libavcodec/vp5.c @@ -18,7 +18,7 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdlib.h> @@ -34,7 +34,7 @@ #include "vp5data.h" -static int vp5_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, +static int vp5_parse_header(vp56_context_t *s, const uint8_t *buf, int buf_size, int *golden_frame) { vp56_range_coder_t *c = &s->c; @@ -88,16 +88,17 @@ static int vp5_adjust(int v, int t) static void vp5_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) { vp56_range_coder_t *c = &s->c; + vp56_model_t *model = s->modelp; int comp, di; for (comp=0; comp<2; comp++) { int delta = 0; - if (vp56_rac_get_prob(c, s->vector_model_dct[comp])) { - int sign = vp56_rac_get_prob(c, s->vector_model_sig[comp]); - di = vp56_rac_get_prob(c, s->vector_model_pdi[comp][0]); - di |= vp56_rac_get_prob(c, s->vector_model_pdi[comp][1]) << 1; + if (vp56_rac_get_prob(c, model->vector_dct[comp])) { + int sign = vp56_rac_get_prob(c, model->vector_sig[comp]); + di = vp56_rac_get_prob(c, model->vector_pdi[comp][0]); + di |= vp56_rac_get_prob(c, model->vector_pdi[comp][1]) << 1; delta = vp56_rac_get_tree(c, vp56_pva_tree, - s->vector_model_pdv[comp]); + model->vector_pdv[comp]); delta = di | (delta << 2); delta = (delta ^ -sign) + sign; } @@ -111,28 +112,30 @@ static void vp5_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) static void vp5_parse_vector_models(vp56_context_t *s) { vp56_range_coder_t *c = &s->c; + vp56_model_t *model = s->modelp; int comp, node; for (comp=0; comp<2; comp++) { if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][0])) - s->vector_model_dct[comp] = vp56_rac_gets_nn(c, 7); + model->vector_dct[comp] = vp56_rac_gets_nn(c, 7); if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][1])) - s->vector_model_sig[comp] = vp56_rac_gets_nn(c, 7); + model->vector_sig[comp] = vp56_rac_gets_nn(c, 7); if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][2])) - s->vector_model_pdi[comp][0] = vp56_rac_gets_nn(c, 7); + model->vector_pdi[comp][0] = vp56_rac_gets_nn(c, 7); if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][3])) - s->vector_model_pdi[comp][1] = vp56_rac_gets_nn(c, 7); + model->vector_pdi[comp][1] = vp56_rac_gets_nn(c, 7); } for (comp=0; comp<2; comp++) for (node=0; node<7; node++) if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][4 + node])) - s->vector_model_pdv[comp][node] = vp56_rac_gets_nn(c, 7); + model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); } static void vp5_parse_coeff_models(vp56_context_t *s) { vp56_range_coder_t *c = &s->c; + vp56_model_t *model = s->modelp; uint8_t def_prob[11]; int node, cg, ctx; int ct; /* code type */ @@ -144,9 +147,9 @@ static void vp5_parse_coeff_models(vp56_context_t *s) for (node=0; node<11; node++) if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); - s->coeff_model_dccv[pt][node] = def_prob[node]; + model->coeff_dccv[pt][node] = def_prob[node]; } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { - s->coeff_model_dccv[pt][node] = def_prob[node]; + model->coeff_dccv[pt][node] = def_prob[node]; } for (ct=0; ct<3; ct++) @@ -155,31 +158,32 @@ static void vp5_parse_coeff_models(vp56_context_t *s) for (node=0; node<11; node++) if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); - s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; + model->coeff_ract[pt][ct][cg][node] = def_prob[node]; } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { - s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; + model->coeff_ract[pt][ct][cg][node] = def_prob[node]; } - /* coeff_model_dcct is a linear combination of coeff_model_dccv */ + /* coeff_dcct is a linear combination of coeff_dccv */ for (pt=0; pt<2; pt++) for (ctx=0; ctx<36; ctx++) for (node=0; node<5; node++) - s->coeff_model_dcct[pt][ctx][node] = av_clip(((s->coeff_model_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254); + model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254); - /* coeff_model_acct is a linear combination of coeff_model_ract */ + /* coeff_acct is a linear combination of coeff_ract */ for (ct=0; ct<3; ct++) for (pt=0; pt<2; pt++) for (cg=0; cg<3; cg++) for (ctx=0; ctx<6; ctx++) for (node=0; node<5; node++) - s->coeff_model_acct[pt][ct][cg][ctx][node] = av_clip(((s->coeff_model_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254); + model->coeff_acct[pt][ct][cg][ctx][node] = av_clip(((model->coeff_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254); } static void vp5_parse_coeff(vp56_context_t *s) { vp56_range_coder_t *c = &s->c; + vp56_model_t *model = s->modelp; uint8_t *permute = s->scantable.permutated; - uint8_t *model, *model2; + uint8_t *model1, *model2; int coeff, sign, coeff_idx; int b, i, cg, idx, ctx, ctx_last; int pt = 0; /* plane type (0 for Y, 1 for U or V) */ @@ -191,22 +195,22 @@ static void vp5_parse_coeff(vp56_context_t *s) ctx = 6*s->coeff_ctx[vp56_b6to4[b]][0] + s->above_blocks[s->above_block_idx[b]].not_null_dc; - model = s->coeff_model_dccv[pt]; - model2 = s->coeff_model_dcct[pt][ctx]; + model1 = model->coeff_dccv[pt]; + model2 = model->coeff_dcct[pt][ctx]; for (coeff_idx=0; coeff_idx<64; ) { if (vp56_rac_get_prob(c, model2[0])) { if (vp56_rac_get_prob(c, model2[2])) { if (vp56_rac_get_prob(c, model2[3])) { s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 4; - idx = vp56_rac_get_tree(c, vp56_pc_tree, model); + idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); sign = vp56_rac_get(c); - coeff = vp56_coeff_bias[idx]; + coeff = vp56_coeff_bias[idx+5]; for (i=vp56_coeff_bit_length[idx]; i>=0; i--) coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; } else { if (vp56_rac_get_prob(c, model2[4])) { - coeff = 3 + vp56_rac_get_prob(c, model[5]); + coeff = 3 + vp56_rac_get_prob(c, model1[5]); s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 3; } else { coeff = 2; @@ -234,8 +238,8 @@ static void vp5_parse_coeff(vp56_context_t *s) cg = vp5_coeff_groups[++coeff_idx]; ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx]; - model = s->coeff_model_ract[pt][ct][cg]; - model2 = cg > 2 ? model : s->coeff_model_acct[pt][ct][cg][ctx]; + model1 = model->coeff_ract[pt][ct][cg]; + model2 = cg > 2 ? model1 : model->coeff_acct[pt][ct][cg][ctx]; } ctx_last = FFMIN(s->coeff_ctx_last[vp56_b6to4[b]], 24); @@ -249,23 +253,24 @@ static void vp5_parse_coeff(vp56_context_t *s) static void vp5_default_models_init(vp56_context_t *s) { + vp56_model_t *model = s->modelp; int i; for (i=0; i<2; i++) { - s->vector_model_sig[i] = 0x80; - s->vector_model_dct[i] = 0x80; - s->vector_model_pdi[i][0] = 0x55; - s->vector_model_pdi[i][1] = 0x80; + model->vector_sig[i] = 0x80; + model->vector_dct[i] = 0x80; + model->vector_pdi[i][0] = 0x55; + model->vector_pdi[i][1] = 0x80; } - memcpy(s->mb_types_stats, vp56_def_mb_types_stats, sizeof(s->mb_types_stats)); - memset(s->vector_model_pdv, 0x80, sizeof(s->vector_model_pdv)); + memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats)); + memset(model->vector_pdv, 0x80, sizeof(model->vector_pdv)); } static int vp5_decode_init(AVCodecContext *avctx) { vp56_context_t *s = avctx->priv_data; - vp56_init(s, avctx, 1); + vp56_init(avctx, 1, 0); s->vp56_coord_div = vp5_coord_div; s->parse_vector_adjustment = vp5_parse_vector_adjustment; s->adjust = vp5_adjust; @@ -287,4 +292,5 @@ AVCodec vp5_decoder = { NULL, vp56_free, vp56_decode_frame, + CODEC_CAP_DR1, }; diff --git a/contrib/ffmpeg/libavcodec/vp56.c b/contrib/ffmpeg/libavcodec/vp56.c index abd1b3a63..ca6ae76f9 100644 --- a/contrib/ffmpeg/libavcodec/vp56.c +++ b/contrib/ffmpeg/libavcodec/vp56.c @@ -18,10 +18,11 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" +#include "bytestream.h" #include "vp56.h" #include "vp56data.h" @@ -75,13 +76,15 @@ static int vp56_get_vectors_predictors(vp56_context_t *s, int row, int col, static void vp56_parse_mb_type_models(vp56_context_t *s) { vp56_range_coder_t *c = &s->c; + vp56_model_t *model = s->modelp; int i, ctx, type; for (ctx=0; ctx<3; ctx++) { if (vp56_rac_get_prob(c, 174)) { int idx = vp56_rac_gets(c, 4); - memcpy(s->mb_types_stats[ctx],vp56_pre_def_mb_type_stats[idx][ctx], - sizeof(s->mb_types_stats[ctx])); + memcpy(model->mb_types_stats[ctx], + vp56_pre_def_mb_type_stats[idx][ctx], + sizeof(model->mb_types_stats[ctx])); } if (vp56_rac_get_prob(c, 254)) { for (type=0; type<10; type++) { @@ -93,7 +96,7 @@ static void vp56_parse_mb_type_models(vp56_context_t *s) vp56_mb_type_model_model); if (!delta) delta = 4 * vp56_rac_gets(c, 7); - s->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign; + model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign; } } } @@ -105,13 +108,13 @@ static void vp56_parse_mb_type_models(vp56_context_t *s) int p[10]; for (type=0; type<10; type++) - p[type] = 100 * s->mb_types_stats[ctx][type][1]; + p[type] = 100 * model->mb_types_stats[ctx][type][1]; for (type=0; type<10; type++) { int p02, p34, p0234, p17, p56, p89, p5689, p156789; /* conservative MB type probability */ - s->mb_type_model[ctx][type][0] = 255 - (255 * s->mb_types_stats[ctx][type][0]) / (1 + s->mb_types_stats[ctx][type][0] + s->mb_types_stats[ctx][type][1]); + model->mb_type[ctx][type][0] = 255 - (255 * model->mb_types_stats[ctx][type][0]) / (1 + model->mb_types_stats[ctx][type][0] + model->mb_types_stats[ctx][type][1]); p[type] = 0; /* same MB type => weight is null */ @@ -125,18 +128,18 @@ static void vp56_parse_mb_type_models(vp56_context_t *s) p5689 = p56 + p89; p156789 = p17 + p5689; - s->mb_type_model[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789); - s->mb_type_model[ctx][type][2] = 1 + 255 * p02 / (1+p0234); - s->mb_type_model[ctx][type][3] = 1 + 255 * p17 / (1+p156789); - s->mb_type_model[ctx][type][4] = 1 + 255 * p[0] / (1+p02); - s->mb_type_model[ctx][type][5] = 1 + 255 * p[3] / (1+p34); - s->mb_type_model[ctx][type][6] = 1 + 255 * p[1] / (1+p17); - s->mb_type_model[ctx][type][7] = 1 + 255 * p56 / (1+p5689); - s->mb_type_model[ctx][type][8] = 1 + 255 * p[5] / (1+p56); - s->mb_type_model[ctx][type][9] = 1 + 255 * p[8] / (1+p89); + model->mb_type[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789); + model->mb_type[ctx][type][2] = 1 + 255 * p02 / (1+p0234); + model->mb_type[ctx][type][3] = 1 + 255 * p17 / (1+p156789); + model->mb_type[ctx][type][4] = 1 + 255 * p[0] / (1+p02); + model->mb_type[ctx][type][5] = 1 + 255 * p[3] / (1+p34); + model->mb_type[ctx][type][6] = 1 + 255 * p[1] / (1+p17); + model->mb_type[ctx][type][7] = 1 + 255 * p56 / (1+p5689); + model->mb_type[ctx][type][8] = 1 + 255 * p[5] / (1+p56); + model->mb_type[ctx][type][9] = 1 + 255 * p[8] / (1+p89); /* restore initial value */ - p[type] = 100 * s->mb_types_stats[ctx][type][1]; + p[type] = 100 * model->mb_types_stats[ctx][type][1]; } } } @@ -144,7 +147,7 @@ static void vp56_parse_mb_type_models(vp56_context_t *s) static vp56_mb_t vp56_parse_mb_type(vp56_context_t *s, vp56_mb_t prev_type, int ctx) { - uint8_t *mb_type_model = s->mb_type_model[ctx][prev_type]; + uint8_t *mb_type_model = s->modelp->mb_type[ctx][prev_type]; vp56_range_coder_t *c = &s->c; if (vp56_rac_get_prob(c, mb_type_model[0])) @@ -258,13 +261,14 @@ static vp56_mb_t vp56_decode_mv(vp56_context_t *s, int row, int col) static void vp56_add_predictors_dc(vp56_context_t *s, vp56_frame_t ref_frame) { int idx = s->scantable.permutated[0]; - int i; + int b; - for (i=0; i<6; i++) { - vp56_ref_dc_t *ab = &s->above_blocks[s->above_block_idx[i]]; - vp56_ref_dc_t *lb = &s->left_block[vp56_b6to4[i]]; + for (b=0; b<6; b++) { + vp56_ref_dc_t *ab = &s->above_blocks[s->above_block_idx[b]]; + vp56_ref_dc_t *lb = &s->left_block[vp56_b6to4[b]]; int count = 0; int dc = 0; + int i; if (ref_frame == lb->ref_frame) { dc += lb->dc_coeff; @@ -274,28 +278,24 @@ static void vp56_add_predictors_dc(vp56_context_t *s, vp56_frame_t ref_frame) dc += ab->dc_coeff; count++; } - if (s->avctx->codec->id == CODEC_ID_VP5) { - if (count < 2 && ref_frame == ab[-1].ref_frame) { - dc += ab[-1].dc_coeff; - count++; - } - if (count < 2 && ref_frame == ab[1].ref_frame) { - dc += ab[1].dc_coeff; - count++; - } - } + if (s->avctx->codec->id == CODEC_ID_VP5) + for (i=0; i<2; i++) + if (count < 2 && ref_frame == ab[-1+2*i].ref_frame) { + dc += ab[-1+2*i].dc_coeff; + count++; + } if (count == 0) - dc = s->prev_dc[vp56_b6to3[i]][ref_frame]; + dc = s->prev_dc[vp56_b2p[b]][ref_frame]; else if (count == 2) dc /= 2; - s->block_coeff[i][idx] += dc; - s->prev_dc[vp56_b6to3[i]][ref_frame] = s->block_coeff[i][idx]; - ab->dc_coeff = s->block_coeff[i][idx]; + s->block_coeff[b][idx] += dc; + s->prev_dc[vp56_b2p[b]][ref_frame] = s->block_coeff[b][idx]; + ab->dc_coeff = s->block_coeff[b][idx]; ab->ref_frame = ref_frame; - lb->dc_coeff = s->block_coeff[i][idx]; + lb->dc_coeff = s->block_coeff[b][idx]; lb->ref_frame = ref_frame; - s->block_coeff[i][idx] *= s->dequant_dc; + s->block_coeff[b][idx] *= s->dequant_dc; } } @@ -322,10 +322,9 @@ static void vp56_deblock_filter(vp56_context_t *s, uint8_t *yuv, if (dy) vp56_edge_filter(s, yuv + stride*(10-dy), stride, 1, t); } -static void vp56_mc(vp56_context_t *s, int b, uint8_t *src, +static void vp56_mc(vp56_context_t *s, int b, int plane, uint8_t *src, int stride, int x, int y) { - int plane = vp56_b6to3[b]; uint8_t *dst=s->framep[VP56_FRAME_CURRENT]->data[plane]+s->block_offset[b]; uint8_t *src_block; int src_offset; @@ -393,12 +392,12 @@ static void vp56_mc(vp56_context_t *s, int b, uint8_t *src, } } -static void vp56_decode_mb(vp56_context_t *s, int row, int col) +static void vp56_decode_mb(vp56_context_t *s, int row, int col, int is_alpha) { AVFrame *frame_current, *frame_ref; vp56_mb_t mb_type; vp56_frame_t ref_frame; - int b, plan, off; + int b, ab, b_max, plane, off; if (s->framep[VP56_FRAME_CURRENT]->key_frame) mb_type = VP56_MB_INTRA; @@ -415,25 +414,28 @@ static void vp56_decode_mb(vp56_context_t *s, int row, int col) frame_current = s->framep[VP56_FRAME_CURRENT]; frame_ref = s->framep[ref_frame]; + ab = 6*is_alpha; + b_max = 6 - 2*is_alpha; + switch (mb_type) { case VP56_MB_INTRA: - for (b=0; b<6; b++) { - plan = vp56_b6to3[b]; - s->dsp.idct_put(frame_current->data[plan] + s->block_offset[b], - s->stride[plan], s->block_coeff[b]); + for (b=0; b<b_max; b++) { + plane = vp56_b2p[b+ab]; + s->dsp.idct_put(frame_current->data[plane] + s->block_offset[b], + s->stride[plane], s->block_coeff[b]); } break; case VP56_MB_INTER_NOVEC_PF: case VP56_MB_INTER_NOVEC_GF: - for (b=0; b<6; b++) { - plan = vp56_b6to3[b]; + for (b=0; b<b_max; b++) { + plane = vp56_b2p[b+ab]; off = s->block_offset[b]; - s->dsp.put_pixels_tab[1][0](frame_current->data[plan] + off, - frame_ref->data[plan] + off, - s->stride[plan], 8); - s->dsp.idct_add(frame_current->data[plan] + off, - s->stride[plan], s->block_coeff[b]); + s->dsp.put_pixels_tab[1][0](frame_current->data[plane] + off, + frame_ref->data[plane] + off, + s->stride[plane], 8); + s->dsp.idct_add(frame_current->data[plane] + off, + s->stride[plane], s->block_coeff[b]); } break; @@ -444,34 +446,35 @@ static void vp56_decode_mb(vp56_context_t *s, int row, int col) case VP56_MB_INTER_4V: case VP56_MB_INTER_V1_GF: case VP56_MB_INTER_V2_GF: - for (b=0; b<6; b++) { + for (b=0; b<b_max; b++) { int x_off = b==1 || b==3 ? 8 : 0; int y_off = b==2 || b==3 ? 8 : 0; - plan = vp56_b6to3[b]; - vp56_mc(s, b, frame_ref->data[plan], s->stride[plan], + plane = vp56_b2p[b+ab]; + vp56_mc(s, b, plane, frame_ref->data[plane], s->stride[plane], 16*col+x_off, 16*row+y_off); - s->dsp.idct_add(frame_current->data[plan] + s->block_offset[b], - s->stride[plan], s->block_coeff[b]); + s->dsp.idct_add(frame_current->data[plane] + s->block_offset[b], + s->stride[plane], s->block_coeff[b]); } break; } } -static int vp56_size_changed(AVCodecContext *avctx, vp56_context_t *s) +static int vp56_size_changed(AVCodecContext *avctx) { + vp56_context_t *s = avctx->priv_data; int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0]; int i; - s->plane_width[0] = s->avctx->coded_width; - s->plane_width[1] = s->plane_width[2] = s->avctx->coded_width/2; - s->plane_height[0] = s->avctx->coded_height; - s->plane_height[1] = s->plane_height[2] = s->avctx->coded_height/2; + s->plane_width[0] = s->plane_width[3] = avctx->coded_width; + s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2; + s->plane_height[0] = s->plane_height[3] = avctx->coded_height; + s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2; - for (i=0; i<3; i++) + for (i=0; i<4; i++) s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i]; - s->mb_width = (s->avctx->coded_width+15) / 16; - s->mb_height = (s->avctx->coded_height+15) / 16; + s->mb_width = (avctx->coded_width +15) / 16; + s->mb_height = (avctx->coded_height+15) / 16; if (s->mb_width > 1000 || s->mb_height > 1000) { av_log(avctx, AV_LOG_ERROR, "picture too big\n"); @@ -492,117 +495,145 @@ static int vp56_size_changed(AVCodecContext *avctx, vp56_context_t *s) } int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { vp56_context_t *s = avctx->priv_data; AVFrame *const p = s->framep[VP56_FRAME_CURRENT]; - int mb_row, mb_col, mb_row_flip, mb_offset = 0; - int block, y, uv, stride_y, stride_uv; - int golden_frame = 0; - int res; - - res = s->parse_header(s, buf, buf_size, &golden_frame); - if (!res) - return -1; + int is_alpha, alpha_offset; - p->reference = 1; - if (avctx->get_buffer(avctx, p) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + if (s->has_alpha) { + alpha_offset = bytestream_get_be24(&buf); + buf_size -= 3; } - if (res == 2) - if (vp56_size_changed(avctx, s)) { - avctx->release_buffer(avctx, p); - return -1; - } + for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) { + int mb_row, mb_col, mb_row_flip, mb_offset = 0; + int block, y, uv, stride_y, stride_uv; + int golden_frame = 0; + int res; - if (p->key_frame) { - p->pict_type = FF_I_TYPE; - s->default_models_init(s); - for (block=0; block<s->mb_height*s->mb_width; block++) - s->macroblocks[block].type = VP56_MB_INTRA; - } else { - p->pict_type = FF_P_TYPE; - vp56_parse_mb_type_models(s); - s->parse_vector_models(s); - s->mb_type = VP56_MB_INTER_NOVEC_PF; - } + s->modelp = &s->models[is_alpha]; - s->parse_coeff_models(s); + res = s->parse_header(s, buf, buf_size, &golden_frame); + if (!res) + return -1; - memset(s->prev_dc, 0, sizeof(s->prev_dc)); - s->prev_dc[1][VP56_FRAME_CURRENT] = 128; - s->prev_dc[2][VP56_FRAME_CURRENT] = 128; + if (!is_alpha) { + p->reference = 1; + if (avctx->get_buffer(avctx, p) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } - for (block=0; block < 4*s->mb_width+6; block++) { - s->above_blocks[block].ref_frame = -1; - s->above_blocks[block].dc_coeff = 0; - s->above_blocks[block].not_null_dc = 0; - } - s->above_blocks[2*s->mb_width + 2].ref_frame = 0; - s->above_blocks[3*s->mb_width + 4].ref_frame = 0; + if (res == 2) + if (vp56_size_changed(avctx)) { + avctx->release_buffer(avctx, p); + return -1; + } + } - stride_y = p->linesize[0]; - stride_uv = p->linesize[1]; + if (p->key_frame) { + p->pict_type = FF_I_TYPE; + s->default_models_init(s); + for (block=0; block<s->mb_height*s->mb_width; block++) + s->macroblocks[block].type = VP56_MB_INTRA; + } else { + p->pict_type = FF_P_TYPE; + vp56_parse_mb_type_models(s); + s->parse_vector_models(s); + s->mb_type = VP56_MB_INTER_NOVEC_PF; + } - if (s->flip < 0) - mb_offset = 7; + s->parse_coeff_models(s); - /* main macroblocks loop */ - for (mb_row=0; mb_row<s->mb_height; mb_row++) { - if (s->flip < 0) - mb_row_flip = s->mb_height - mb_row - 1; - else - mb_row_flip = mb_row; + memset(s->prev_dc, 0, sizeof(s->prev_dc)); + s->prev_dc[1][VP56_FRAME_CURRENT] = 128; + s->prev_dc[2][VP56_FRAME_CURRENT] = 128; - for (block=0; block<4; block++) { - s->left_block[block].ref_frame = -1; - s->left_block[block].dc_coeff = 0; - s->left_block[block].not_null_dc = 0; - memset(s->coeff_ctx[block], 0, 64*sizeof(s->coeff_ctx[block][0])); + for (block=0; block < 4*s->mb_width+6; block++) { + s->above_blocks[block].ref_frame = -1; + s->above_blocks[block].dc_coeff = 0; + s->above_blocks[block].not_null_dc = 0; } - memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last)); - - s->above_block_idx[0] = 1; - s->above_block_idx[1] = 2; - s->above_block_idx[2] = 1; - s->above_block_idx[3] = 2; - s->above_block_idx[4] = 2*s->mb_width + 2 + 1; - s->above_block_idx[5] = 3*s->mb_width + 4 + 1; - - s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y; - s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y; - s->block_offset[1] = s->block_offset[0] + 8; - s->block_offset[3] = s->block_offset[2] + 8; - s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv; - s->block_offset[5] = s->block_offset[4]; - - for (mb_col=0; mb_col<s->mb_width; mb_col++) { - vp56_decode_mb(s, mb_row, mb_col); - - for (y=0; y<4; y++) { - s->above_block_idx[y] += 2; - s->block_offset[y] += 16; + s->above_blocks[2*s->mb_width + 2].ref_frame = 0; + s->above_blocks[3*s->mb_width + 4].ref_frame = 0; + + stride_y = p->linesize[0]; + stride_uv = p->linesize[1]; + + if (s->flip < 0) + mb_offset = 7; + + /* main macroblocks loop */ + for (mb_row=0; mb_row<s->mb_height; mb_row++) { + if (s->flip < 0) + mb_row_flip = s->mb_height - mb_row - 1; + else + mb_row_flip = mb_row; + + for (block=0; block<4; block++) { + s->left_block[block].ref_frame = -1; + s->left_block[block].dc_coeff = 0; + s->left_block[block].not_null_dc = 0; } + memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx)); + memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last)); + + s->above_block_idx[0] = 1; + s->above_block_idx[1] = 2; + s->above_block_idx[2] = 1; + s->above_block_idx[3] = 2; + s->above_block_idx[4] = 2*s->mb_width + 2 + 1; + s->above_block_idx[5] = 3*s->mb_width + 4 + 1; + + s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y; + s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y; + s->block_offset[1] = s->block_offset[0] + 8; + s->block_offset[3] = s->block_offset[2] + 8; + s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv; + s->block_offset[5] = s->block_offset[4]; + + for (mb_col=0; mb_col<s->mb_width; mb_col++) { + vp56_decode_mb(s, mb_row, mb_col, is_alpha); + + for (y=0; y<4; y++) { + s->above_block_idx[y] += 2; + s->block_offset[y] += 16; + } - for (uv=4; uv<6; uv++) { - s->above_block_idx[uv] += 1; - s->block_offset[uv] += 8; + for (uv=4; uv<6; uv++) { + s->above_block_idx[uv] += 1; + s->block_offset[uv] += 8; + } } } + + if (p->key_frame || golden_frame) { + if (s->framep[VP56_FRAME_GOLDEN]->data[0] && + s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2]) + avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); + s->framep[VP56_FRAME_GOLDEN] = p; + } + + if (s->has_alpha) { + FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN], + s->framep[VP56_FRAME_GOLDEN2]); + buf += alpha_offset; + buf_size -= alpha_offset; + } } - if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN]) - FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], - s->framep[VP56_FRAME_UNUSED]); - else if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) + if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] || + s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) { + if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] && + s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2]) + FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], + s->framep[VP56_FRAME_UNUSED]); + else + FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS], + s->framep[VP56_FRAME_UNUSED2]); + } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); - if (p->key_frame || golden_frame) { - if (s->framep[VP56_FRAME_GOLDEN]->data[0]) - avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); - s->framep[VP56_FRAME_GOLDEN] = p; - } FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT], s->framep[VP56_FRAME_PREVIOUS]); @@ -612,23 +643,25 @@ int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, return buf_size; } -void vp56_init(vp56_context_t *s, AVCodecContext *avctx, int flip) +void vp56_init(AVCodecContext *avctx, int flip, int has_alpha) { + vp56_context_t *s = avctx->priv_data; int i; s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_YUV420P; + avctx->pix_fmt = has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P; - if (s->avctx->idct_algo == FF_IDCT_AUTO) - s->avctx->idct_algo = FF_IDCT_VP3; - dsputil_init(&s->dsp, s->avctx); + if (avctx->idct_algo == FF_IDCT_AUTO) + avctx->idct_algo = FF_IDCT_VP3; + dsputil_init(&s->dsp, avctx); ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct); - avcodec_set_dimensions(s->avctx, 0, 0); + avcodec_set_dimensions(avctx, 0, 0); - for (i=0; i<3; i++) + for (i=0; i<4; i++) s->framep[i] = &s->frames[i]; s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN]; + s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2]; s->edge_emu_buffer_alloc = NULL; s->above_blocks = NULL; @@ -638,6 +671,7 @@ void vp56_init(vp56_context_t *s, AVCodecContext *avctx, int flip) s->filter = NULL; + s->has_alpha = has_alpha; if (flip) { s->flip = -1; s->frbi = 2; @@ -656,9 +690,10 @@ int vp56_free(AVCodecContext *avctx) av_free(s->above_blocks); av_free(s->macroblocks); av_free(s->edge_emu_buffer_alloc); - if (s->framep[VP56_FRAME_GOLDEN]->data[0] - && (s->framep[VP56_FRAME_PREVIOUS] != s->framep[VP56_FRAME_GOLDEN])) + if (s->framep[VP56_FRAME_GOLDEN]->data[0]) avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]); + if (s->framep[VP56_FRAME_GOLDEN2]->data[0]) + avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]); if (s->framep[VP56_FRAME_PREVIOUS]->data[0]) avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]); return 0; diff --git a/contrib/ffmpeg/libavcodec/vp56.h b/contrib/ffmpeg/libavcodec/vp56.h index fb8bbba6f..f85f947e7 100644 --- a/contrib/ffmpeg/libavcodec/vp56.h +++ b/contrib/ffmpeg/libavcodec/vp56.h @@ -18,15 +18,16 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef VP56_H -#define VP56_H +#ifndef FFMPEG_VP56_H +#define FFMPEG_VP56_H #include "vp56data.h" #include "dsputil.h" #include "mpegvideo.h" +#include "bytestream.h" typedef struct vp56_context vp56_context_t; @@ -42,7 +43,7 @@ typedef void (*vp56_parse_coeff_t)(vp56_context_t *s); typedef void (*vp56_default_models_init_t)(vp56_context_t *s); typedef void (*vp56_parse_vector_models_t)(vp56_context_t *s); typedef void (*vp56_parse_coeff_models_t)(vp56_context_t *s); -typedef int (*vp56_parse_header_t)(vp56_context_t *s, uint8_t *buf, +typedef int (*vp56_parse_header_t)(vp56_context_t *s, const uint8_t *buf, int buf_size, int *golden_frame); typedef struct { @@ -68,12 +69,29 @@ typedef struct { vp56_mv_t mv; } vp56_macroblock_t; +typedef struct { + uint8_t coeff_reorder[64]; /* used in vp6 only */ + uint8_t coeff_index_to_pos[64]; /* used in vp6 only */ + uint8_t vector_sig[2]; /* delta sign */ + uint8_t vector_dct[2]; /* delta coding types */ + uint8_t vector_pdi[2][2]; /* predefined delta init */ + uint8_t vector_pdv[2][7]; /* predefined delta values */ + uint8_t vector_fdv[2][8]; /* 8 bit delta value definition */ + uint8_t coeff_dccv[2][11]; /* DC coeff value */ + uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */ + uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */ + uint8_t coeff_dcct[2][36][5]; /* DC coeff coding type */ + uint8_t coeff_runv[2][14]; /* run value (vp6 only) */ + uint8_t mb_type[3][10][10]; /* model for decoding MB type */ + uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */ +} vp56_model_t; + struct vp56_context { AVCodecContext *avctx; DSPContext dsp; ScanTable scantable; - AVFrame frames[3]; - AVFrame *framep[4]; + AVFrame frames[4]; + AVFrame *framep[6]; uint8_t *edge_emu_buffer_alloc; uint8_t *edge_emu_buffer; vp56_range_coder_t c; @@ -82,8 +100,8 @@ struct vp56_context { int sub_version; /* frame info */ - int plane_width[3]; - int plane_height[3]; + int plane_width[4]; + int plane_height[4]; int mb_width; /* number of horizontal MB */ int mb_height; /* number of vertical MB */ int block_offset[6]; @@ -102,8 +120,6 @@ struct vp56_context { vp56_mb_t mb_type; vp56_macroblock_t *macroblocks; DECLARE_ALIGNED_16(DCTELEM, block_coeff[6][64]); - uint8_t coeff_reorder[64]; /* used in vp6 only */ - uint8_t coeff_index_to_pos[64]; /* used in vp6 only */ /* motion vectors */ vp56_mv_t mv[6]; /* vectors for each block in MB */ @@ -118,27 +134,16 @@ struct vp56_context { int max_vector_length; int sample_variance_threshold; - /* AC models */ - uint8_t vector_model_sig[2]; /* delta sign */ - uint8_t vector_model_dct[2]; /* delta coding types */ - uint8_t vector_model_pdi[2][2]; /* predefined delta init */ - uint8_t vector_model_pdv[2][7]; /* predefined delta values */ - uint8_t vector_model_fdv[2][8]; /* 8 bit delta value definition */ - uint8_t mb_type_model[3][10][10]; /* model for decoding MB type */ - uint8_t coeff_model_dccv[2][11]; /* DC coeff value */ - uint8_t coeff_model_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */ - uint8_t coeff_model_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */ - uint8_t coeff_model_dcct[2][36][5]; /* DC coeff coding type */ - uint8_t coeff_model_runv[2][14]; /* run value (vp6 only) */ - uint8_t mb_types_stats[3][10][2]; /* contextual, next MB type stats */ uint8_t coeff_ctx[4][64]; /* used in vp5 only */ uint8_t coeff_ctx_last[4]; /* used in vp5 only */ + int has_alpha; + /* upside-down flipping hints */ int flip; /* are we flipping ? */ int frbi; /* first row block index in MB */ int srbi; /* second row block index in MB */ - int stride[3]; /* stride for each plan */ + int stride[4]; /* stride for each plan */ const uint8_t *vp56_coord_div; vp56_parse_vector_adjustment_t parse_vector_adjustment; @@ -149,14 +154,25 @@ struct vp56_context { vp56_parse_vector_models_t parse_vector_models; vp56_parse_coeff_models_t parse_coeff_models; vp56_parse_header_t parse_header; + + vp56_model_t *modelp; + vp56_model_t models[2]; + + /* huffman decoding */ + int use_huffman; + GetBitContext gb; + VLC dccv_vlc[2]; + VLC runv_vlc[2]; + VLC ract_vlc[2][3][6]; + unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */ }; -void vp56_init(vp56_context_t *s, AVCodecContext *avctx, int flip); +void vp56_init(AVCodecContext *avctx, int flip, int has_alpha); int vp56_free(AVCodecContext *avctx); void vp56_init_dequant(vp56_context_t *s, int quantizer); int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size); + const uint8_t *buf, int buf_size); /** @@ -169,8 +185,7 @@ static inline void vp56_init_range_decoder(vp56_range_coder_t *c, c->high = 255; c->bits = 8; c->buffer = buf; - c->code_word = *c->buffer++ << 8; - c->code_word |= *c->buffer++; + c->code_word = bytestream_get_be16(&c->buffer); } static inline int vp56_rac_get_prob(vp56_range_coder_t *c, uint8_t prob) @@ -250,4 +265,4 @@ static inline int vp56_rac_get_tree(vp56_range_coder_t *c, return -tree->val; } -#endif /* VP56_H */ +#endif /* FFMPEG_VP56_H */ diff --git a/contrib/ffmpeg/libavcodec/vp56data.c b/contrib/ffmpeg/libavcodec/vp56data.c index e75c6d1ce..a7171c695 100644 --- a/contrib/ffmpeg/libavcodec/vp56data.c +++ b/contrib/ffmpeg/libavcodec/vp56data.c @@ -18,12 +18,12 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "vp56data.h" -const uint8_t vp56_b6to3[] = { 0, 0, 0, 0, 1, 2 }; +const uint8_t vp56_b2p[] = { 0, 0, 0, 0, 1, 2, 3, 3, 3, 3 }; const uint8_t vp56_b6to4[] = { 0, 0, 1, 1, 2, 3 }; const uint8_t vp56_coeff_parse_table[6][11] = { @@ -62,5 +62,5 @@ const vp56_tree_t vp56_pc_tree[] = { { 2,10}, {-4}, {-5}, }; -const uint8_t vp56_coeff_bias[] = { 5, 7, 11, 19, 35, 67 }; +const uint8_t vp56_coeff_bias[] = { 0, 1, 2, 3, 4, 5, 7, 11, 19, 35, 67 }; const uint8_t vp56_coeff_bit_length[] = { 0, 1, 2, 3, 4, 10 }; diff --git a/contrib/ffmpeg/libavcodec/vp56data.h b/contrib/ffmpeg/libavcodec/vp56data.h index d784b9803..0dd79b06b 100644 --- a/contrib/ffmpeg/libavcodec/vp56data.h +++ b/contrib/ffmpeg/libavcodec/vp56data.h @@ -18,11 +18,11 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef VP56DATA_H -#define VP56DATA_H +#ifndef FFMPEG_VP56DATA_H +#define FFMPEG_VP56DATA_H #include "common.h" @@ -30,7 +30,9 @@ typedef enum { VP56_FRAME_CURRENT = 0, VP56_FRAME_PREVIOUS = 1, VP56_FRAME_GOLDEN = 2, - VP56_FRAME_UNUSED = 3, + VP56_FRAME_GOLDEN2 = 3, + VP56_FRAME_UNUSED = 4, + VP56_FRAME_UNUSED2 = 5, } vp56_frame_t; typedef enum { @@ -51,7 +53,7 @@ typedef struct { int8_t prob_idx; } vp56_tree_t; -extern const uint8_t vp56_b6to3[]; +extern const uint8_t vp56_b2p[]; extern const uint8_t vp56_b6to4[]; extern const uint8_t vp56_coeff_parse_table[6][11]; extern const uint8_t vp56_def_mb_types_stats[3][10][2]; @@ -246,4 +248,4 @@ static const int8_t vp56_candidate_predictor_pos[12][2] = { { 2, -2 }, }; -#endif /* VP56DATA */ +#endif /* FFMPEG_VP56DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/vp5data.h b/contrib/ffmpeg/libavcodec/vp5data.h index effc17c2c..c08688a21 100644 --- a/contrib/ffmpeg/libavcodec/vp5data.h +++ b/contrib/ffmpeg/libavcodec/vp5data.h @@ -18,11 +18,13 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef VP5DATA_H -#define VP5DATA_H +#ifndef FFMPEG_VP5DATA_H +#define FFMPEG_VP5DATA_H + +#include <stdint.h> static const uint8_t vp5_coeff_groups[] = { -1, 0, 1, 1, 2, 1, 1, 2, @@ -170,4 +172,4 @@ static const int16_t vp5_ract_lc[3][3][5][6][2] = { static const uint8_t vp5_coord_div[] = { 2, 2, 2, 2, 4, 4 }; -#endif /* VP5DATA_H */ +#endif /* FFMPEG_VP5DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/vp6.c b/contrib/ffmpeg/libavcodec/vp6.c index 2e904b7e0..896f06d4c 100644 --- a/contrib/ffmpeg/libavcodec/vp6.c +++ b/contrib/ffmpeg/libavcodec/vp6.c @@ -4,6 +4,10 @@ * * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * + * The VP6F decoder accepts an optional 1 byte extradata. It is composed of: + * - upper 4bits: difference between encoded width and visible width + * - lower 4bits: difference between encoded height and visible height + * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -18,12 +22,7 @@ * * 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 - * - * - * The VP6F decoder accept an optional 1 byte extradata. It is composed of: - * - upper 4bits: difference between encoded width and visible width - * - lower 4bits: difference between encoded height and visible height + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdlib.h> @@ -31,6 +30,7 @@ #include "avcodec.h" #include "dsputil.h" #include "bitstream.h" +#include "huffman.h" #include "mpegvideo.h" #include "vp56.h" @@ -38,7 +38,10 @@ #include "vp6data.h" -static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, +static void vp6_parse_coeff(vp56_context_t *s); +static void vp6_parse_coeff_huffman(vp56_context_t *s); + +static int vp6_parse_header(vp56_context_t *s, const uint8_t *buf, int buf_size, int *golden_frame) { vp56_range_coder_t *c = &s->c; @@ -127,12 +130,19 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size, s->filter_selection = 16; } - vp56_rac_get(c); + s->use_huffman = vp56_rac_get(c); + s->parse_coeff = vp6_parse_coeff; if (coeff_offset) { - vp56_init_range_decoder(&s->cc, buf+coeff_offset, - buf_size-coeff_offset); - s->ccp = &s->cc; + buf += coeff_offset; + buf_size -= coeff_offset; + if (s->use_huffman) { + s->parse_coeff = vp6_parse_coeff_huffman; + init_get_bits(&s->gb, buf, buf_size<<3); + } else { + vp56_init_range_decoder(&s->cc, buf, buf_size); + s->ccp = &s->cc; + } } else { s->ccp = &s->c; } @@ -144,25 +154,27 @@ static void vp6_coeff_order_table_init(vp56_context_t *s) { int i, pos, idx = 1; - s->coeff_index_to_pos[0] = 0; + s->modelp->coeff_index_to_pos[0] = 0; for (i=0; i<16; i++) for (pos=1; pos<64; pos++) - if (s->coeff_reorder[pos] == i) - s->coeff_index_to_pos[idx++] = pos; + if (s->modelp->coeff_reorder[pos] == i) + s->modelp->coeff_index_to_pos[idx++] = pos; } static void vp6_default_models_init(vp56_context_t *s) { - s->vector_model_dct[0] = 0xA2; - s->vector_model_dct[1] = 0xA4; - s->vector_model_sig[0] = 0x80; - s->vector_model_sig[1] = 0x80; + vp56_model_t *model = s->modelp; + + model->vector_dct[0] = 0xA2; + model->vector_dct[1] = 0xA4; + model->vector_sig[0] = 0x80; + model->vector_sig[1] = 0x80; - memcpy(s->mb_types_stats, vp56_def_mb_types_stats, sizeof(s->mb_types_stats)); - memcpy(s->vector_model_fdv, vp6_def_fdv_vector_model, sizeof(s->vector_model_fdv)); - memcpy(s->vector_model_pdv, vp6_def_pdv_vector_model, sizeof(s->vector_model_pdv)); - memcpy(s->coeff_model_runv, vp6_def_runv_coeff_model, sizeof(s->coeff_model_runv)); - memcpy(s->coeff_reorder, vp6_def_coeff_reorder, sizeof(s->coeff_reorder)); + memcpy(model->mb_types_stats, vp56_def_mb_types_stats, sizeof(model->mb_types_stats)); + memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv)); + memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv)); + memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv)); + memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder)); vp6_coeff_order_table_init(s); } @@ -170,29 +182,56 @@ static void vp6_default_models_init(vp56_context_t *s) static void vp6_parse_vector_models(vp56_context_t *s) { vp56_range_coder_t *c = &s->c; + vp56_model_t *model = s->modelp; int comp, node; for (comp=0; comp<2; comp++) { if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0])) - s->vector_model_dct[comp] = vp56_rac_gets_nn(c, 7); + model->vector_dct[comp] = vp56_rac_gets_nn(c, 7); if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1])) - s->vector_model_sig[comp] = vp56_rac_gets_nn(c, 7); + model->vector_sig[comp] = vp56_rac_gets_nn(c, 7); } for (comp=0; comp<2; comp++) for (node=0; node<7; node++) if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node])) - s->vector_model_pdv[comp][node] = vp56_rac_gets_nn(c, 7); + model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7); for (comp=0; comp<2; comp++) for (node=0; node<8; node++) if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node])) - s->vector_model_fdv[comp][node] = vp56_rac_gets_nn(c, 7); + model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7); +} + +static int vp6_huff_cmp(const void *va, const void *vb) +{ + const Node *a = va, *b = vb; + return a->count >= b->count; +} + +static void vp6_build_huff_tree(vp56_context_t *s, uint8_t coeff_model[], + const uint8_t *map, unsigned size, VLC *vlc) +{ + Node nodes[2*size], *tmp = &nodes[size]; + int a, b, i; + + /* first compute probabilities from model */ + tmp[0].count = 256; + for (i=0; i<size-1; i++) { + a = tmp[i].count * coeff_model[i] >> 8; + b = tmp[i].count * (255 - coeff_model[i]) >> 8; + nodes[map[2*i ]].count = a + !a; + nodes[map[2*i+1]].count = b + !b; + } + + /* then build the huffman tree accodring to probabilities */ + ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp, 1); } static void vp6_parse_coeff_models(vp56_context_t *s) { vp56_range_coder_t *c = &s->c; + vp56_model_t *model = s->modelp; int def_prob[11]; int node, cg, ctx, pos; int ct; /* code type */ @@ -204,22 +243,22 @@ static void vp6_parse_coeff_models(vp56_context_t *s) for (node=0; node<11; node++) if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); - s->coeff_model_dccv[pt][node] = def_prob[node]; + model->coeff_dccv[pt][node] = def_prob[node]; } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { - s->coeff_model_dccv[pt][node] = def_prob[node]; + model->coeff_dccv[pt][node] = def_prob[node]; } if (vp56_rac_get(c)) { for (pos=1; pos<64; pos++) if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos])) - s->coeff_reorder[pos] = vp56_rac_gets(c, 4); + model->coeff_reorder[pos] = vp56_rac_gets(c, 4); vp6_coeff_order_table_init(s); } for (cg=0; cg<2; cg++) for (node=0; node<14; node++) if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node])) - s->coeff_model_runv[cg][node] = vp56_rac_gets_nn(c, 7); + model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7); for (ct=0; ct<3; ct++) for (pt=0; pt<2; pt++) @@ -227,21 +266,37 @@ static void vp6_parse_coeff_models(vp56_context_t *s) for (node=0; node<11; node++) if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); - s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; + model->coeff_ract[pt][ct][cg][node] = def_prob[node]; } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { - s->coeff_model_ract[pt][ct][cg][node] = def_prob[node]; + model->coeff_ract[pt][ct][cg][node] = def_prob[node]; } - /* coeff_model_dcct is a linear combination of coeff_model_dccv */ + if (s->use_huffman) { + for (pt=0; pt<2; pt++) { + vp6_build_huff_tree(s, model->coeff_dccv[pt], + vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]); + vp6_build_huff_tree(s, model->coeff_runv[pt], + vp6_huff_run_map, 9, &s->runv_vlc[pt]); + for (ct=0; ct<3; ct++) + for (cg = 0; cg < 6; cg++) + vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg], + vp6_huff_coeff_map, 12, + &s->ract_vlc[pt][ct][cg]); + } + memset(s->nb_null, 0, sizeof(s->nb_null)); + } else { + /* coeff_dcct is a linear combination of coeff_dccv */ for (pt=0; pt<2; pt++) for (ctx=0; ctx<3; ctx++) for (node=0; node<5; node++) - s->coeff_model_dcct[pt][ctx][node] = av_clip(((s->coeff_model_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255); + model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255); + } } static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) { vp56_range_coder_t *c = &s->c; + vp56_model_t *model = s->modelp; int comp; *vect = (vp56_mv_t) {0,0}; @@ -251,22 +306,22 @@ static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) for (comp=0; comp<2; comp++) { int i, delta = 0; - if (vp56_rac_get_prob(c, s->vector_model_dct[comp])) { + if (vp56_rac_get_prob(c, model->vector_dct[comp])) { static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4}; for (i=0; i<sizeof(prob_order); i++) { int j = prob_order[i]; - delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][j])<<j; + delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j; } if (delta & 0xF0) - delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][3])<<3; + delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3; else delta |= 8; } else { delta = vp56_rac_get_tree(c, vp56_pva_tree, - s->vector_model_pdv[comp]); + model->vector_pdv[comp]); } - if (delta && vp56_rac_get_prob(c, s->vector_model_sig[comp])) + if (delta && vp56_rac_get_prob(c, model->vector_sig[comp])) delta = -delta; if (!comp) @@ -276,11 +331,83 @@ static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect) } } +/** + * Read number of consecutive blocks with null DC or AC. + * This value is < 74. + */ +static unsigned vp6_get_nb_null(vp56_context_t *s) +{ + unsigned val = get_bits(&s->gb, 2); + if (val == 2) + val += get_bits(&s->gb, 2); + else if (val == 3) { + val = get_bits1(&s->gb) << 2; + val = 6+val + get_bits(&s->gb, 2+val); + } + return val; +} + +static void vp6_parse_coeff_huffman(vp56_context_t *s) +{ + vp56_model_t *model = s->modelp; + uint8_t *permute = s->scantable.permutated; + VLC *vlc_coeff; + int coeff, sign, coeff_idx; + int b, cg, idx; + int pt = 0; /* plane type (0 for Y, 1 for U or V) */ + + for (b=0; b<6; b++) { + int ct = 0; /* code type */ + if (b > 3) pt = 1; + vlc_coeff = &s->dccv_vlc[pt]; + + for (coeff_idx=0; coeff_idx<64; ) { + int run = 1; + if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) { + s->nb_null[coeff_idx][pt]--; + if (coeff_idx) + break; + } else { + coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3); + if (coeff == 0) { + if (coeff_idx) { + int pt = (coeff_idx >= 6); + run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3); + if (run >= 9) + run += get_bits(&s->gb, 6); + } else + s->nb_null[0][pt] = vp6_get_nb_null(s); + ct = 0; + } else if (coeff == 11) { /* end of block */ + if (coeff_idx == 1) /* first AC coeff ? */ + s->nb_null[1][pt] = vp6_get_nb_null(s); + break; + } else { + int coeff2 = vp56_coeff_bias[coeff]; + if (coeff > 4) + coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11); + ct = 1 + (coeff2 > 1); + sign = get_bits1(&s->gb); + coeff2 = (coeff2 ^ -sign) + sign; + if (coeff_idx) + coeff2 *= s->dequant_ac; + idx = model->coeff_index_to_pos[coeff_idx]; + s->block_coeff[b][permute[idx]] = coeff2; + } + } + coeff_idx+=run; + cg = FFMIN(vp6_coeff_groups[coeff_idx], 3); + vlc_coeff = &s->ract_vlc[pt][ct][cg]; + } + } +} + static void vp6_parse_coeff(vp56_context_t *s) { vp56_range_coder_t *c = s->ccp; + vp56_model_t *model = s->modelp; uint8_t *permute = s->scantable.permutated; - uint8_t *model, *model2, *model3; + uint8_t *model1, *model2, *model3; int coeff, sign, coeff_idx; int b, i, cg, idx, ctx; int pt = 0; /* plane type (0 for Y, 1 for U or V) */ @@ -293,26 +420,21 @@ static void vp6_parse_coeff(vp56_context_t *s) ctx = s->left_block[vp56_b6to4[b]].not_null_dc + s->above_blocks[s->above_block_idx[b]].not_null_dc; - model = s->coeff_model_dccv[pt]; - model2 = s->coeff_model_dcct[pt][ctx]; + model1 = model->coeff_dccv[pt]; + model2 = model->coeff_dcct[pt][ctx]; for (coeff_idx=0; coeff_idx<64; ) { if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) { /* parse a coeff */ - if (coeff_idx == 0) { - s->left_block[vp56_b6to4[b]].not_null_dc = 1; - s->above_blocks[s->above_block_idx[b]].not_null_dc = 1; - } - if (vp56_rac_get_prob(c, model2[2])) { if (vp56_rac_get_prob(c, model2[3])) { - idx = vp56_rac_get_tree(c, vp56_pc_tree, model); - coeff = vp56_coeff_bias[idx]; + idx = vp56_rac_get_tree(c, vp56_pc_tree, model1); + coeff = vp56_coeff_bias[idx+5]; for (i=vp56_coeff_bit_length[idx]; i>=0; i--) coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i; } else { if (vp56_rac_get_prob(c, model2[4])) - coeff = 3 + vp56_rac_get_prob(c, model[5]); + coeff = 3 + vp56_rac_get_prob(c, model1[5]); else coeff = 2; } @@ -325,20 +447,17 @@ static void vp6_parse_coeff(vp56_context_t *s) coeff = (coeff ^ -sign) + sign; if (coeff_idx) coeff *= s->dequant_ac; - idx = s->coeff_index_to_pos[coeff_idx]; + idx = model->coeff_index_to_pos[coeff_idx]; s->block_coeff[b][permute[idx]] = coeff; run = 1; } else { /* parse a run */ ct = 0; - if (coeff_idx == 0) { - s->left_block[vp56_b6to4[b]].not_null_dc = 0; - s->above_blocks[s->above_block_idx[b]].not_null_dc = 0; - } else { + if (coeff_idx > 0) { if (!vp56_rac_get_prob(c, model2[1])) break; - model3 = s->coeff_model_runv[coeff_idx >= 6]; + model3 = model->coeff_runv[coeff_idx >= 6]; run = vp56_rac_get_tree(c, vp6_pcr_tree, model3); if (!run) for (run=9, i=0; i<6; i++) @@ -347,8 +466,11 @@ static void vp6_parse_coeff(vp56_context_t *s) } cg = vp6_coeff_groups[coeff_idx+=run]; - model = model2 = s->coeff_model_ract[pt][ct][cg]; + model1 = model2 = model->coeff_ract[pt][ct][cg]; } + + s->left_block[vp56_b6to4[b]].not_null_dc = + s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0]; } } @@ -380,14 +502,6 @@ static int vp6_block_variance(uint8_t *src, int stride) return (16*square_sum - sum*sum) >> 8; } -static void vp6_filter_hv2(vp56_context_t *s, uint8_t *dst, uint8_t *src, - int stride, int delta, int16_t weight) -{ - s->dsp.put_pixels_tab[1][0](dst, src, stride, 8); - s->dsp.biweight_h264_pixels_tab[3](dst, src+delta, stride, 2, - 8-weight, weight, 0); -} - static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride, int delta, const int16_t *weights) { @@ -409,18 +523,8 @@ static void vp6_filter_diag2(vp56_context_t *s, uint8_t *dst, uint8_t *src, int stride, int h_weight, int v_weight) { uint8_t *tmp = s->edge_emu_buffer+16; - int x, xmax; - - s->dsp.put_pixels_tab[1][0](tmp, src, stride, 8); - s->dsp.biweight_h264_pixels_tab[3](tmp, src+1, stride, 2, - 8-h_weight, h_weight, 0); - /* we need a 8x9 block to do vertical filter, so compute one more line */ - for (x=8*stride, xmax=x+8; x<xmax; x++) - tmp[x] = (src[x]*(8-h_weight) + src[x+1]*h_weight + 4) >> 3; - - s->dsp.put_pixels_tab[1][0](dst, tmp, stride, 8); - s->dsp.biweight_h264_pixels_tab[3](dst, tmp+stride, stride, 2, - 8-v_weight, v_weight, 0); + s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); + s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight); } static void vp6_filter_diag4(uint8_t *dst, uint8_t *src, int stride, @@ -492,24 +596,16 @@ static void vp6_filter(vp56_context_t *s, uint8_t *dst, uint8_t *src, } else if (!x8) { /* above or below combine */ vp6_filter_hv4(dst, src+offset1, stride, stride, vp6_block_copy_filter[select][y8]); - } else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */ - vp6_filter_diag4(dst, src+offset1-1, stride, - vp6_block_copy_filter[select][x8], - vp6_block_copy_filter[select][y8]); - } else { /* lower-right or upper-left combine */ - vp6_filter_diag4(dst, src+offset1, stride, + } else { + vp6_filter_diag4(dst, src+offset1 + ((mv.x^mv.y)>>31), stride, vp6_block_copy_filter[select][x8], vp6_block_copy_filter[select][y8]); } } else { - if (!y8) { /* left or right combine */ - vp6_filter_hv2(s, dst, src+offset1, stride, 1, x8); - } else if (!x8) { /* above or below combine */ - vp6_filter_hv2(s, dst, src+offset1, stride, stride, y8); - } else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */ - vp6_filter_diag2(s, dst, src+offset1-1, stride, x8, y8); - } else { /* lower-right or upper-left combine */ - vp6_filter_diag2(s, dst, src+offset1, stride, x8, y8); + if (!x8 || !y8) { + s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8); + } else { + vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8); } } } @@ -518,12 +614,12 @@ static int vp6_decode_init(AVCodecContext *avctx) { vp56_context_t *s = avctx->priv_data; - vp56_init(s, avctx, avctx->codec->id == CODEC_ID_VP6); + vp56_init(avctx, avctx->codec->id == CODEC_ID_VP6, + avctx->codec->id == CODEC_ID_VP6A); s->vp56_coord_div = vp6_coord_div; s->parse_vector_adjustment = vp6_parse_vector_adjustment; s->adjust = vp6_adjust; s->filter = vp6_filter; - s->parse_coeff = vp6_parse_coeff; s->default_models_init = vp6_default_models_init; s->parse_vector_models = vp6_parse_vector_models; s->parse_coeff_models = vp6_parse_coeff_models; @@ -541,6 +637,7 @@ AVCodec vp6_decoder = { NULL, vp56_free, vp56_decode_frame, + CODEC_CAP_DR1, }; /* flash version, not flipped upside-down */ @@ -553,4 +650,18 @@ AVCodec vp6f_decoder = { NULL, vp56_free, vp56_decode_frame, + CODEC_CAP_DR1, +}; + +/* flash version, not flipped upside-down, with alpha channel */ +AVCodec vp6a_decoder = { + "vp6a", + CODEC_TYPE_VIDEO, + CODEC_ID_VP6A, + sizeof(vp56_context_t), + vp6_decode_init, + NULL, + vp56_free, + vp56_decode_frame, + CODEC_CAP_DR1, }; diff --git a/contrib/ffmpeg/libavcodec/vp6data.h b/contrib/ffmpeg/libavcodec/vp6data.h index 0545a9d66..8d4bb0b57 100644 --- a/contrib/ffmpeg/libavcodec/vp6data.h +++ b/contrib/ffmpeg/libavcodec/vp6data.h @@ -18,11 +18,11 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef VP6DATA_H -#define VP6DATA_H +#ifndef FFMPEG_VP6DATA_H +#define FFMPEG_VP6DATA_H #include "vp56data.h" @@ -297,4 +297,12 @@ static const vp56_tree_t vp6_pcr_tree[] = { static const uint8_t vp6_coord_div[] = { 4, 4, 4, 4, 8, 8 }; -#endif /* VP6DATA_H */ +static const uint8_t vp6_huff_coeff_map[] = { + 13, 14, 11, 0, 1, 15, 16, 18, 2, 17, 3, 4, 19, 20, 5, 6, 21, 22, 7, 8, 9, 10 +}; + +static const uint8_t vp6_huff_run_map[] = { + 10, 13, 11, 12, 0, 1, 2, 3, 14, 8, 15, 16, 4, 5, 6, 7 +}; + +#endif /* FFMPEG_VP6DATA_H */ diff --git a/contrib/ffmpeg/libavcodec/vqavideo.c b/contrib/ffmpeg/libavcodec/vqavideo.c index 57fe6cf44..8e70143f4 100644 --- a/contrib/ffmpeg/libavcodec/vqavideo.c +++ b/contrib/ffmpeg/libavcodec/vqavideo.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -69,7 +68,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" #include "dsputil.h" @@ -106,7 +104,7 @@ typedef struct VqaContext { DSPContext dsp; AVFrame frame; - unsigned char *buf; + const unsigned char *buf; int size; uint32_t palette[PALETTE_COUNT]; @@ -133,13 +131,12 @@ typedef struct VqaContext { static int vqa_decode_init(AVCodecContext *avctx) { - VqaContext *s = (VqaContext *)avctx->priv_data; + VqaContext *s = avctx->priv_data; unsigned char *vqa_header; - int i, j, codebook_index;; + int i, j, codebook_index; s->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; dsputil_init(&s->dsp, avctx); /* make sure the extradata made it */ @@ -205,7 +202,7 @@ static int vqa_decode_init(AVCodecContext *avctx) return; \ } -static void decode_format80(unsigned char *src, int src_size, +static void decode_format80(const unsigned char *src, int src_size, unsigned char *dest, int dest_size, int check_size) { int src_index = 0; @@ -570,9 +567,9 @@ static void vqa_decode_chunk(VqaContext *s) static int vqa_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { - VqaContext *s = (VqaContext *)avctx->priv_data; + VqaContext *s = avctx->priv_data; s->buf = buf; s->size = buf_size; @@ -600,7 +597,7 @@ static int vqa_decode_frame(AVCodecContext *avctx, static int vqa_decode_end(AVCodecContext *avctx) { - VqaContext *s = (VqaContext *)avctx->priv_data; + VqaContext *s = avctx->priv_data; av_free(s->codebook); av_free(s->next_codebook_buffer); diff --git a/contrib/ffmpeg/libavcodec/w32thread.c b/contrib/ffmpeg/libavcodec/w32thread.c index e749a64af..fbc0a581e 100644 --- a/contrib/ffmpeg/libavcodec/w32thread.c +++ b/contrib/ffmpeg/libavcodec/w32thread.c @@ -16,12 +16,10 @@ * 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 - * */ //#define DEBUG #include "avcodec.h" -#include "common.h" #define WIN32_LEAN_AND_MEAN #include <windows.h> @@ -38,7 +36,7 @@ typedef struct ThreadContext{ }ThreadContext; -static unsigned __stdcall thread_func(void *v){ +static unsigned __stdcall attribute_align_arg thread_func(void *v){ ThreadContext *c= v; for(;;){ @@ -57,8 +55,8 @@ static unsigned __stdcall thread_func(void *v){ } /** - * free what has been allocated by avcodec_thread_init(). - * must be called after decoding has finished, especially dont call while avcodec_thread_execute() is running + * Free what has been allocated by avcodec_thread_init(). + * Must be called after decoding has finished, especially do not call while avcodec_thread_execute() is running. */ void avcodec_thread_free(AVCodecContext *s){ ThreadContext *c= s->thread_opaque; diff --git a/contrib/ffmpeg/libavcodec/wavpack.c b/contrib/ffmpeg/libavcodec/wavpack.c index e79d4a570..025898da8 100644 --- a/contrib/ffmpeg/libavcodec/wavpack.c +++ b/contrib/ffmpeg/libavcodec/wavpack.c @@ -21,13 +21,15 @@ #define ALT_BITSTREAM_READER_LE #include "avcodec.h" #include "bitstream.h" +#include "unary.h" /** * @file wavpack.c * WavPack lossless audio decoder */ -#define WV_JOINT 0x0010 +#define WV_JOINT_STEREO 0x00000010 +#define WV_FALSE_STEREO 0x40000000 enum WP_ID_Flags{ WP_IDF_MASK = 0x1F, @@ -66,7 +68,7 @@ typedef struct Decorr { typedef struct WavpackContext { AVCodecContext *avctx; - int stereo; + int stereo, stereo_in; int joint; uint32_t CRC; GetBitContext gb; @@ -76,6 +78,7 @@ typedef struct WavpackContext { int terms; Decorr decorr[MAX_TERMS]; int zero, one, zeroes; + int and, or, shift; } WavpackContext; // exponent table copied from WavPack source @@ -113,12 +116,6 @@ static av_always_inline int wp_exp2(int16_t val) return neg ? -res : res; } -static inline int get_unary(GetBitContext *gb){ - int r=0; - while(get_bits1(gb) && r<33)r++; - return r; -} - // macros for manipulating median values #define GET_MED(n) ((median[n] >> 4) + 1) #define DEC_MED(n) median[n] -= ((median[n] + (128>>n) - 2) / (128>>n)) * 2 @@ -164,7 +161,7 @@ static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int *median, int if(ctx->zeroes) return 0; }else{ - t = get_unary(gb); + t = get_unary_0_33(gb); if(t >= 2) t = get_bits(gb, t - 1) | (1 << (t-1)); ctx->zeroes = t; if(ctx->zeroes){ @@ -183,13 +180,13 @@ static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int *median, int t = 0; ctx->zero = 0; }else{ - t = get_unary(gb); + t = get_unary_0_33(gb); if(get_bits_count(gb) >= ctx->data_size){ *last = 1; return 0; } if(t == 16) { - t2 = get_unary(gb); + t2 = get_unary_0_33(gb); if(t2 < 2) t += t2; else t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); } @@ -235,7 +232,7 @@ static int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, int16_t *dst) { int i, j, count = 0; int last, t; - int A, B, L, L2, R, R2; + int A, B, L, L2, R, R2, bit; int pos = 0; uint32_t crc = 0xFFFFFFFF; @@ -299,9 +296,10 @@ static int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, int16_t *dst) if(s->joint) L += (R -= (L >> 1)); crc = (crc * 3 + L) * 3 + R; - *dst++ = L; - *dst++ = R; - + bit = (L & s->and) | s->or; + *dst++ = ((L + bit) << s->shift) - bit; + bit = (R & s->and) | s->or; + *dst++ = ((R + bit) << s->shift) - bit; count++; }while(!last && count < s->samples); @@ -316,7 +314,7 @@ static int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, int16_t *dst) { int i, j, count = 0; int last, t; - int A, S, T; + int A, S, T, bit; int pos = 0; uint32_t crc = 0xFFFFFFFF; @@ -344,7 +342,8 @@ static int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, int16_t *dst) } pos = (pos + 1) & 7; crc = crc * 3 + S; - *dst++ = S; + bit = (S & s->and) | s->or; + *dst++ = ((S + bit) << s->shift) - bit; count++; }while(!last && count < s->samples); @@ -365,22 +364,15 @@ static int wavpack_decode_init(AVCodecContext *avctx) return 0; } -static int wavpack_decode_close(AVCodecContext *avctx) -{ -// WavpackContext *s = avctx->priv_data; - - return 0; -} - static int wavpack_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { WavpackContext *s = avctx->priv_data; int16_t *samples = data; int samplecount; int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0; - uint8_t* buf_end = buf + buf_size; + const uint8_t* buf_end = buf + buf_size; int i, j, id, size, ssize, weights, t; if (buf_size == 0){ @@ -389,6 +381,8 @@ static int wavpack_decode_frame(AVCodecContext *avctx, } memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); + memset(s->median, 0, sizeof(s->median)); + s->and = s->or = s->shift = 0; s->samples = AV_RL32(buf); buf += 4; if(!s->samples){ @@ -400,7 +394,8 @@ static int wavpack_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc!\n"); return -1; } - s->joint = AV_RL32(buf) & WV_JOINT; buf += 4; + s->stereo_in = (AV_RL32(buf) & WV_FALSE_STEREO) ? 0 : s->stereo; + s->joint = AV_RL32(buf) & WV_JOINT_STEREO; buf += 4; s->CRC = AV_RL32(buf); buf += 4; // parse metadata blocks while(buf < buf_end){ @@ -445,7 +440,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n"); continue; } - weights = size >> s->stereo; + weights = size >> s->stereo_in; if(weights > MAX_TERMS || weights > s->terms){ av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n"); buf += ssize; @@ -456,7 +451,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, s->decorr[s->terms - i - 1].weightA = t << 3; if(s->decorr[s->terms - i - 1].weightA > 0) s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7; - if(s->stereo){ + if(s->stereo_in){ t = (int8_t)(*buf++); s->decorr[s->terms - i - 1].weightB = t << 3; if(s->decorr[s->terms - i - 1].weightB > 0) @@ -475,7 +470,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, if(s->decorr[i].value > 8){ s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2; s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2; - if(s->stereo){ + if(s->stereo_in){ s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2; s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2; t += 4; @@ -488,27 +483,44 @@ static int wavpack_decode_frame(AVCodecContext *avctx, }else{ for(j = 0; j < s->decorr[i].value; j++){ s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2; - if(s->stereo){ + if(s->stereo_in){ s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2; } } - t += s->decorr[i].value * 2 * avctx->channels; + t += s->decorr[i].value * 2 * (s->stereo_in + 1); } } got_samples = 1; break; case WP_ID_ENTROPY: - if(size != 6 * avctx->channels){ - av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * avctx->channels, size); + if(size != 6 * (s->stereo_in + 1)){ + av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * (s->stereo_in + 1), size); buf += ssize; continue; } - for(i = 0; i < 3 * avctx->channels; i++){ + for(i = 0; i < 3 * (s->stereo_in + 1); i++){ s->median[i] = wp_exp2(AV_RL16(buf)); buf += 2; } got_entropy = 1; break; + case WP_ID_INT32INFO: + if(size != 4 || *buf){ + av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, size = %i, sent_bits = %i\n", size, *buf); + buf += ssize; + continue; + } + if(buf[1]) + s->shift = buf[1]; + else if(buf[2]){ + s->and = s->or = 1; + s->shift = buf[2]; + }else if(buf[3]){ + s->and = 1; + s->shift = buf[3]; + } + buf += 4; + break; case WP_ID_DATA: init_get_bits(&s->gb, buf, size * 8); s->data_size = size * 8; @@ -541,10 +553,21 @@ static int wavpack_decode_frame(AVCodecContext *avctx, return -1; } - if(s->stereo) + if(s->stereo_in) samplecount = wv_unpack_stereo(s, &s->gb, samples); - else + else{ samplecount = wv_unpack_mono(s, &s->gb, samples); + if(s->stereo){ + int16_t *dst = samples + samplecount * 2; + int16_t *src = samples + samplecount; + int cnt = samplecount; + while(cnt--){ + *--dst = *--src; + *--dst = *src; + } + samplecount *= 2; + } + } *data_size = samplecount * 2; return buf_size; @@ -557,6 +580,6 @@ AVCodec wavpack_decoder = { sizeof(WavpackContext), wavpack_decode_init, NULL, - wavpack_decode_close, + NULL, wavpack_decode_frame, }; diff --git a/contrib/ffmpeg/libavcodec/wma.c b/contrib/ffmpeg/libavcodec/wma.c index 2241a07a0..e257aed31 100644 --- a/contrib/ffmpeg/libavcodec/wma.c +++ b/contrib/ffmpeg/libavcodec/wma.c @@ -72,6 +72,11 @@ int ff_wma_init(AVCodecContext * avctx, int flags2) int sample_rate1; int coef_vlc_table; + if( avctx->sample_rate<=0 || avctx->sample_rate>50000 + || avctx->channels<=0 || avctx->channels>8 + || avctx->bit_rate<=0) + return -1; + s->sample_rate = avctx->sample_rate; s->nb_channels = avctx->channels; s->bit_rate = avctx->bit_rate; @@ -380,6 +385,7 @@ int ff_wma_end(AVCodecContext *avctx) free_vlc(&s->coef_vlc[i]); av_free(s->run_table[i]); av_free(s->level_table[i]); + av_free(s->int_table[i]); } return 0; diff --git a/contrib/ffmpeg/libavcodec/wma.h b/contrib/ffmpeg/libavcodec/wma.h index cd4daa7e5..88b5dbf9e 100644 --- a/contrib/ffmpeg/libavcodec/wma.h +++ b/contrib/ffmpeg/libavcodec/wma.h @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef WMA_H -#define WMA_H +#ifndef FFMPEG_WMA_H +#define FFMPEG_WMA_H #include "bitstream.h" #include "dsputil.h" @@ -92,7 +92,7 @@ typedef struct WMACodecContext { uint16_t *run_table[2]; uint16_t *level_table[2]; uint16_t *int_table[2]; - CoefVLCTable *coef_vlcs[2]; + const CoefVLCTable *coef_vlcs[2]; /* frame info */ int frame_len; ///< frame length in samples int frame_len_bits; ///< frame_len = 1 << frame_len_bits @@ -107,6 +107,7 @@ typedef struct WMACodecContext { int block_pos; ///< current position in frame uint8_t ms_stereo; ///< true if mid/side stereo mode uint8_t channel_coded[MAX_CHANNELS]; ///< true if channel is coded + int exponents_bsize[MAX_CHANNELS]; ///< log2 ratio frame/exp. length DECLARE_ALIGNED_16(float, exponents[MAX_CHANNELS][BLOCK_MAX_SIZE]); float max_exponent[MAX_CHANNELS]; int16_t coefs1[MAX_CHANNELS][BLOCK_MAX_SIZE]; @@ -146,4 +147,4 @@ int ff_wma_init(AVCodecContext * avctx, int flags2); int ff_wma_total_gain_to_bits(int total_gain); int ff_wma_end(AVCodecContext *avctx); -#endif +#endif /* FFMPEG_WMA_H */ diff --git a/contrib/ffmpeg/libavcodec/wmadata.h b/contrib/ffmpeg/libavcodec/wmadata.h index 31ed89bf0..aa2a120a2 100644 --- a/contrib/ffmpeg/libavcodec/wmadata.h +++ b/contrib/ffmpeg/libavcodec/wmadata.h @@ -24,6 +24,12 @@ * Various WMA tables. */ +#ifndef FFMPEG_WMADATA_H +#define FFMPEG_WMADATA_H + +#include <stdint.h> +#include "wma.h" + static const uint16_t wma_critical_freqs[25] = { 100, 200, 300, 400, 510, 630, 770, 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3150, @@ -1431,3 +1437,5 @@ static const CoefVLCTable coef_vlcs[6] = { sizeof(coef5_huffbits), sizeof(levels5)/2, coef5_huffcodes, coef5_huffbits, levels5, }, }; + +#endif /* FFMPEG_WMADATA_H */ diff --git a/contrib/ffmpeg/libavcodec/wmadec.c b/contrib/ffmpeg/libavcodec/wmadec.c index ef3cc7a33..9e1958419 100644 --- a/contrib/ffmpeg/libavcodec/wmadec.c +++ b/contrib/ffmpeg/libavcodec/wmadec.c @@ -48,7 +48,7 @@ static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len); #ifdef TRACE -static void dump_shorts(WMADecodeContext *s, const char *name, const short *tab, int n) +static void dump_shorts(WMACodecContext *s, const char *name, const short *tab, int n) { int i; @@ -62,7 +62,7 @@ static void dump_shorts(WMADecodeContext *s, const char *name, const short *tab, } } -static void dump_floats(WMADecodeContext *s, const char *name, int prec, const float *tab, int n) +static void dump_floats(WMACodecContext *s, const char *name, int prec, const float *tab, int n) { int i; @@ -92,12 +92,11 @@ static int wma_decode_init(AVCodecContext * avctx) flags2 = 0; extradata = avctx->extradata; if (avctx->codec->id == CODEC_ID_WMAV1 && avctx->extradata_size >= 4) { - flags1 = extradata[0] | (extradata[1] << 8); - flags2 = extradata[2] | (extradata[3] << 8); + flags1 = AV_RL16(extradata); + flags2 = AV_RL16(extradata+2); } else if (avctx->codec->id == CODEC_ID_WMAV2 && avctx->extradata_size >= 6) { - flags1 = extradata[0] | (extradata[1] << 8) | - (extradata[2] << 16) | (extradata[3] << 24); - flags2 = extradata[4] | (extradata[5] << 8); + flags1 = AV_RL32(extradata); + flags2 = AV_RL16(extradata+4); } // for(i=0; i<avctx->extradata_size; i++) // av_log(NULL, AV_LOG_ERROR, "%02X ", extradata[i]); @@ -106,7 +105,8 @@ static int wma_decode_init(AVCodecContext * avctx) s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; - ff_wma_init(avctx, flags2); + if(ff_wma_init(avctx, flags2)<0) + return -1; /* init MDCT */ for(i = 0; i < s->nb_block_sizes; i++) @@ -130,35 +130,6 @@ static int wma_decode_init(AVCodecContext * avctx) } /** - * interpolate values for a bigger or smaller block. The block must - * have multiple sizes - */ -static void interpolate_array(float *scale, int old_size, int new_size) -{ - int i, j, jincr, k; - float v; - - if (new_size > old_size) { - jincr = new_size / old_size; - j = new_size; - for(i = old_size - 1; i >=0; i--) { - v = scale[i]; - k = jincr; - do { - scale[--j] = v; - } while (--k); - } - } else if (new_size < old_size) { - j = 0; - jincr = old_size / new_size; - for(i = 0; i < new_size; i++) { - scale[i] = scale[j]; - j += jincr; - } - } -} - -/** * compute x^-0.25 with an exponent and mantissa table. We use linear * interpolation to reduce the mantissa table size at a small speed * expense (linear interpolation approximately doubles the number of @@ -378,7 +349,7 @@ static void wma_window(WMACodecContext *s, float *out) static int wma_decode_block(WMACodecContext *s) { int n, v, a, ch, code, bsize; - int coef_nb_bits, total_gain, parse_exponents; + int coef_nb_bits, total_gain; int nb_coefs[MAX_CHANNELS]; float mdct_norm; @@ -422,11 +393,11 @@ static int wma_decode_block(WMACodecContext *s) return -1; if (s->nb_channels == 2) { - s->ms_stereo = get_bits(&s->gb, 1); + s->ms_stereo = get_bits1(&s->gb); } v = 0; for(ch = 0; ch < s->nb_channels; ch++) { - a = get_bits(&s->gb, 1); + a = get_bits1(&s->gb); s->channel_coded[ch] = a; v |= a; } @@ -462,7 +433,7 @@ static int wma_decode_block(WMACodecContext *s) int i, n, a; n = s->exponent_high_sizes[bsize]; for(i=0;i<n;i++) { - a = get_bits(&s->gb, 1); + a = get_bits1(&s->gb); s->high_band_coded[ch][i] = a; /* if noise coding, the coefficients are not transmitted */ if (a) @@ -493,13 +464,9 @@ static int wma_decode_block(WMACodecContext *s) } } - /* exposant can be interpolated in short blocks. */ - parse_exponents = 1; - if (s->block_len_bits != s->frame_len_bits) { - parse_exponents = get_bits(&s->gb, 1); - } - - if (parse_exponents) { + /* exponents can be reused in short blocks. */ + if ((s->block_len_bits == s->frame_len_bits) || + get_bits1(&s->gb)) { for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { if (s->use_exp_vlc) { @@ -508,13 +475,7 @@ static int wma_decode_block(WMACodecContext *s) } else { decode_exp_lsp(s, ch); } - } - } - } else { - for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]) { - interpolate_array(s->exponents[ch], 1 << s->prev_block_len_bits, - s->block_len); + s->exponents_bsize[ch] = bsize; } } } @@ -555,7 +516,7 @@ static int wma_decode_block(WMACodecContext *s) run = run_table[code]; level = level_table[code]; } - sign = get_bits(&s->gb, 1); + sign = get_bits1(&s->gb); if (!sign) level = -level; ptr += run; @@ -588,12 +549,13 @@ static int wma_decode_block(WMACodecContext *s) for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { int16_t *coefs1; - float *coefs, *exponents, mult, mult1, noise, *exp_ptr; - int i, j, n, n1, last_high_band; + float *coefs, *exponents, mult, mult1, noise; + int i, j, n, n1, last_high_band, esize; float exp_power[HIGH_BAND_MAX_SIZE]; coefs1 = s->coefs1[ch]; exponents = s->exponents[ch]; + esize = s->exponents_bsize[ch]; mult = pow(10, total_gain * 0.05) / s->max_exponent[ch]; mult *= mdct_norm; coefs = s->coefs[ch]; @@ -601,16 +563,16 @@ static int wma_decode_block(WMACodecContext *s) mult1 = mult; /* very low freqs : noise */ for(i = 0;i < s->coefs_start; i++) { - *coefs++ = s->noise_table[s->noise_index] * (*exponents++) * mult1; + *coefs++ = s->noise_table[s->noise_index] * + exponents[i<<bsize>>esize] * mult1; s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); } n1 = s->exponent_high_sizes[bsize]; /* compute power of high bands */ - exp_ptr = exponents + - s->high_band_start[bsize] - - s->coefs_start; + exponents = s->exponents[ch] + + (s->high_band_start[bsize]<<bsize); last_high_band = 0; /* avoid warning */ for(j=0;j<n1;j++) { n = s->exponent_high_bands[s->frame_len_bits - @@ -619,17 +581,18 @@ static int wma_decode_block(WMACodecContext *s) float e2, v; e2 = 0; for(i = 0;i < n; i++) { - v = exp_ptr[i]; + v = exponents[i<<bsize>>esize]; e2 += v * v; } exp_power[j] = e2 / n; last_high_band = j; tprintf(s->avctx, "%d: power=%f (%d)\n", j, exp_power[j], n); } - exp_ptr += n; + exponents += n<<bsize; } /* main freqs and high freqs */ + exponents = s->exponents[ch] + (s->coefs_start<<bsize); for(j=-1;j<n1;j++) { if (j < 0) { n = s->high_band_start[bsize] - @@ -648,21 +611,25 @@ static int wma_decode_block(WMACodecContext *s) for(i = 0;i < n; i++) { noise = s->noise_table[s->noise_index]; s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); - *coefs++ = (*exponents++) * noise * mult1; + *coefs++ = noise * + exponents[i<<bsize>>esize] * mult1; } + exponents += n<<bsize; } else { /* coded values + small noise */ for(i = 0;i < n; i++) { noise = s->noise_table[s->noise_index]; s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); - *coefs++ = ((*coefs1++) + noise) * (*exponents++) * mult; + *coefs++ = ((*coefs1++) + noise) * + exponents[i<<bsize>>esize] * mult; } + exponents += n<<bsize; } } /* very high freqs : noise */ n = s->block_len - s->coefs_end[bsize]; - mult1 = mult * exponents[-1]; + mult1 = mult * exponents[((-1<<bsize))>>esize]; for(i = 0; i < n; i++) { *coefs++ = s->noise_table[s->noise_index] * mult1; s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); @@ -673,7 +640,7 @@ static int wma_decode_block(WMACodecContext *s) *coefs++ = 0.0; n = nb_coefs[ch]; for(i = 0;i < n; i++) { - *coefs++ = coefs1[i] * exponents[i] * mult; + *coefs++ = coefs1[i] * exponents[i<<bsize>>esize] * mult; } n = s->block_len - s->coefs_end[bsize]; for(i = 0;i < n; i++) @@ -745,7 +712,7 @@ static int wma_decode_block(WMACodecContext *s) /* decode a frame of frame_len samples */ static int wma_decode_frame(WMACodecContext *s, int16_t *samples) { - int ret, i, n, a, ch, incr; + int ret, i, n, ch, incr; int16_t *ptr; float *iptr; @@ -772,12 +739,7 @@ static int wma_decode_frame(WMACodecContext *s, int16_t *samples) iptr = s->frame_out[ch]; for(i=0;i<n;i++) { - a = lrintf(*iptr++); - if (a > 32767) - a = 32767; - else if (a < -32768) - a = -32768; - *ptr = a; + *ptr = av_clip_int16(lrintf(*iptr++)); ptr += incr; } /* prepare for next block */ @@ -793,7 +755,7 @@ static int wma_decode_frame(WMACodecContext *s, int16_t *samples) static int wma_decode_superframe(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { WMACodecContext *s = avctx->priv_data; int nb_frames, bit_offset, i, pos, len; @@ -806,6 +768,9 @@ static int wma_decode_superframe(AVCodecContext *avctx, s->last_superframe_len = 0; return 0; } + if (buf_size < s->block_align) + return 0; + buf_size = s->block_align; samples = data; @@ -813,7 +778,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, if (s->use_bit_reservoir) { /* read super frame header */ - get_bits(&s->gb, 4); /* super frame index */ + skip_bits(&s->gb, 4); /* super frame index */ nb_frames = get_bits(&s->gb, 4) - 1; bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); diff --git a/contrib/ffmpeg/libavcodec/wmaenc.c b/contrib/ffmpeg/libavcodec/wmaenc.c index e902a6aff..f2feee2f6 100644 --- a/contrib/ffmpeg/libavcodec/wmaenc.c +++ b/contrib/ffmpeg/libavcodec/wmaenc.c @@ -45,19 +45,13 @@ static int encode_init(AVCodecContext * avctx){ if (avctx->codec->id == CODEC_ID_WMAV1) { extradata= av_malloc(4); avctx->extradata_size= 4; - extradata[0] = flags1; - extradata[1] = flags1>>8; - extradata[2] = flags2; - extradata[3] = flags2>>8; + AV_WL16(extradata, flags1); + AV_WL16(extradata+2, flags2); } else if (avctx->codec->id == CODEC_ID_WMAV2) { extradata= av_mallocz(10); avctx->extradata_size= 10; - extradata[0] = flags1; - extradata[1] = flags1>>8; - extradata[2] = flags1>>16; - extradata[3] = flags1>>24; - extradata[4] = flags2; - extradata[5] = flags2>>8; + AV_WL32(extradata, flags1); + AV_WL16(extradata+4, flags2); }else assert(0); avctx->extradata= extradata; @@ -100,7 +94,7 @@ static void apply_window_and_mdct(AVCodecContext * avctx, signed short * audio, } //FIXME use for decoding too -static void init_exp(WMACodecContext *s, int ch, int *exp_param){ +static void init_exp(WMACodecContext *s, int ch, const int *exp_param){ int n; const uint16_t *ptr; float v, *q, max_scale, *q_end; @@ -184,7 +178,7 @@ static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], } for(ch = 0; ch < s->nb_channels; ch++) { - if (s->channel_coded[ch]= 1) { //FIXME + if ((s->channel_coded[ch]= 1)) { //FIXME only set channel_coded when needed, instead of always init_exp(s, ch, fixed_exp); } } @@ -330,7 +324,7 @@ static int encode_superframe(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ WMACodecContext *s = avctx->priv_data; short *samples = data; - int i, total_gain, best; + int i, total_gain; s->block_len_bits= s->frame_len_bits; //required by non variable block len s->block_len = 1 << s->block_len_bits; diff --git a/contrib/ffmpeg/libavcodec/wmv2.c b/contrib/ffmpeg/libavcodec/wmv2.c index d57eaa5e4..39efea29c 100644 --- a/contrib/ffmpeg/libavcodec/wmv2.c +++ b/contrib/ffmpeg/libavcodec/wmv2.c @@ -16,576 +16,22 @@ * 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 wmv2.c - * wmv2 codec. */ +#include "avcodec.h" +#include "mpegvideo.h" +#include "msmpeg4data.h" #include "simple_idct.h" - -#define SKIP_TYPE_NONE 0 -#define SKIP_TYPE_MPEG 1 -#define SKIP_TYPE_ROW 2 -#define SKIP_TYPE_COL 3 +#include "wmv2.h" -typedef struct Wmv2Context{ - MpegEncContext s; - int j_type_bit; - int j_type; - int flag3; - int flag63; - int abt_flag; - int abt_type; - int abt_type_table[6]; - int per_mb_abt; - int per_block_abt; - int mspel_bit; - int cbp_table_index; - int top_left_mv_flag; - int per_mb_rl_bit; - int skip_type; - int hshift; - - ScanTable abt_scantable[2]; - DECLARE_ALIGNED_8(DCTELEM, abt_block2[6][64]); -}Wmv2Context; - -static void wmv2_common_init(Wmv2Context * w){ +void ff_wmv2_common_init(Wmv2Context * w){ MpegEncContext * const s= &w->s; ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[0], wmv2_scantableA); ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[1], wmv2_scantableB); } -#ifdef CONFIG_ENCODERS - -static int encode_ext_header(Wmv2Context *w){ - MpegEncContext * const s= &w->s; - PutBitContext pb; - int code; - - init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size); - - put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 - put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047)); - - put_bits(&pb, 1, w->mspel_bit=1); - put_bits(&pb, 1, w->flag3=1); - put_bits(&pb, 1, w->abt_flag=1); - put_bits(&pb, 1, w->j_type_bit=1); - put_bits(&pb, 1, w->top_left_mv_flag=0); - put_bits(&pb, 1, w->per_mb_rl_bit=1); - put_bits(&pb, 3, code=1); - - flush_put_bits(&pb); - - s->slice_height = s->mb_height / code; - - return 0; -} - -static int wmv2_encode_init(AVCodecContext *avctx){ - Wmv2Context * const w= avctx->priv_data; - - if(MPV_encode_init(avctx) < 0) - return -1; - - wmv2_common_init(w); - - avctx->extradata_size= 4; - avctx->extradata= av_mallocz(avctx->extradata_size + 10); - encode_ext_header(w); - - return 0; -} - -#if 0 /* unused, remove? */ -static int wmv2_encode_end(AVCodecContext *avctx){ - - if(MPV_encode_end(avctx) < 0) - return -1; - - avctx->extradata_size= 0; - av_freep(&avctx->extradata); - - return 0; -} -#endif - -int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number) -{ - Wmv2Context * const w= (Wmv2Context*)s; - - put_bits(&s->pb, 1, s->pict_type - 1); - if(s->pict_type == I_TYPE){ - put_bits(&s->pb, 7, 0); - } - put_bits(&s->pb, 5, s->qscale); - - s->dc_table_index = 1; - s->mv_table_index = 1; /* only if P frame */ -// s->use_skip_mb_code = 1; /* only if P frame */ - s->per_mb_rl_table = 0; - s->mspel= 0; - w->per_mb_abt=0; - w->abt_type=0; - w->j_type=0; - - assert(s->flipflop_rounding); - - if (s->pict_type == I_TYPE) { - assert(s->no_rounding==1); - if(w->j_type_bit) put_bits(&s->pb, 1, w->j_type); - - if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); - - if(!s->per_mb_rl_table){ - code012(&s->pb, s->rl_chroma_table_index); - code012(&s->pb, s->rl_table_index); - } - - put_bits(&s->pb, 1, s->dc_table_index); - - s->inter_intra_pred= 0; - }else{ - int cbp_index; - - put_bits(&s->pb, 2, SKIP_TYPE_NONE); - - code012(&s->pb, cbp_index=0); - if(s->qscale <= 10){ - int map[3]= {0,2,1}; - w->cbp_table_index= map[cbp_index]; - }else if(s->qscale <= 20){ - int map[3]= {1,0,2}; - w->cbp_table_index= map[cbp_index]; - }else{ - int map[3]= {2,1,0}; - w->cbp_table_index= map[cbp_index]; - } - - if(w->mspel_bit) put_bits(&s->pb, 1, s->mspel); - - if(w->abt_flag){ - put_bits(&s->pb, 1, w->per_mb_abt^1); - if(!w->per_mb_abt){ - code012(&s->pb, w->abt_type); - } - } - - if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); - - if(!s->per_mb_rl_table){ - code012(&s->pb, s->rl_table_index); - s->rl_chroma_table_index = s->rl_table_index; - } - put_bits(&s->pb, 1, s->dc_table_index); - put_bits(&s->pb, 1, s->mv_table_index); - - s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); - } - s->esc3_level_length= 0; - s->esc3_run_length= 0; - - return 0; -} - -// nearly idential to wmv1 but thats just because we dont use the useless M$ crap features -// its duplicated here in case someone wants to add support for these carp features -void ff_wmv2_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y) -{ - Wmv2Context * const w= (Wmv2Context*)s; - int cbp, coded_cbp, i; - int pred_x, pred_y; - uint8_t *coded_block; - - handle_slices(s); - - if (!s->mb_intra) { - /* compute cbp */ - cbp = 0; - for (i = 0; i < 6; i++) { - if (s->block_last_index[i] >= 0) - cbp |= 1 << (5 - i); - } - - put_bits(&s->pb, - wmv2_inter_table[w->cbp_table_index][cbp + 64][1], - wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); - - /* motion vector */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - msmpeg4_encode_motion(s, motion_x - pred_x, - motion_y - pred_y); - } else { - /* compute cbp */ - cbp = 0; - coded_cbp = 0; - for (i = 0; i < 6; i++) { - int val, pred; - val = (s->block_last_index[i] >= 1); - cbp |= val << (5 - i); - if (i < 4) { - /* predict value for close blocks only for luma */ - pred = coded_block_pred(s, i, &coded_block); - *coded_block = val; - val = val ^ pred; - } - coded_cbp |= val << (5 - i); - } -#if 0 - if (coded_cbp) - printf("cbp=%x %x\n", cbp, coded_cbp); -#endif - - if (s->pict_type == I_TYPE) { - put_bits(&s->pb, - ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); - } else { - put_bits(&s->pb, - wmv2_inter_table[w->cbp_table_index][cbp][1], - wmv2_inter_table[w->cbp_table_index][cbp][0]); - } - put_bits(&s->pb, 1, 0); /* no AC prediction yet */ - if(s->inter_intra_pred){ - s->h263_aic_dir=0; - put_bits(&s->pb, table_inter_intra[s->h263_aic_dir][1], table_inter_intra[s->h263_aic_dir][0]); - } - } - - for (i = 0; i < 6; i++) { - msmpeg4_encode_block(s, block[i], i); - } -} -#endif //CONFIG_ENCODERS - -static void parse_mb_skip(Wmv2Context * w){ - int mb_x, mb_y; - MpegEncContext * const s= &w->s; - uint32_t * const mb_type= s->current_picture_ptr->mb_type; - - w->skip_type= get_bits(&s->gb, 2); - switch(w->skip_type){ - case SKIP_TYPE_NONE: - for(mb_y=0; mb_y<s->mb_height; mb_y++){ - for(mb_x=0; mb_x<s->mb_width; mb_x++){ - mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_16x16 | MB_TYPE_L0; - } - } - break; - case SKIP_TYPE_MPEG: - for(mb_y=0; mb_y<s->mb_height; mb_y++){ - for(mb_x=0; mb_x<s->mb_width; mb_x++){ - mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; - } - } - break; - case SKIP_TYPE_ROW: - for(mb_y=0; mb_y<s->mb_height; mb_y++){ - if(get_bits1(&s->gb)){ - for(mb_x=0; mb_x<s->mb_width; mb_x++){ - mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; - } - }else{ - for(mb_x=0; mb_x<s->mb_width; mb_x++){ - mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; - } - } - } - break; - case SKIP_TYPE_COL: - for(mb_x=0; mb_x<s->mb_width; mb_x++){ - if(get_bits1(&s->gb)){ - for(mb_y=0; mb_y<s->mb_height; mb_y++){ - mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; - } - }else{ - for(mb_y=0; mb_y<s->mb_height; mb_y++){ - mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; - } - } - } - break; - } -} - -static int decode_ext_header(Wmv2Context *w){ - MpegEncContext * const s= &w->s; - GetBitContext gb; - int fps; - int code; - - if(s->avctx->extradata_size<4) return -1; - - init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8); - - fps = get_bits(&gb, 5); - s->bit_rate = get_bits(&gb, 11)*1024; - w->mspel_bit = get_bits1(&gb); - w->flag3 = get_bits1(&gb); - w->abt_flag = get_bits1(&gb); - w->j_type_bit = get_bits1(&gb); - w->top_left_mv_flag= get_bits1(&gb); - w->per_mb_rl_bit = get_bits1(&gb); - code = get_bits(&gb, 3); - - if(code==0) return -1; - - s->slice_height = s->mb_height / code; - - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "fps:%d, br:%d, qpbit:%d, abt_flag:%d, j_type_bit:%d, tl_mv_flag:%d, mbrl_bit:%d, code:%d, flag3:%d, slices:%d\n", - fps, s->bit_rate, w->mspel_bit, w->abt_flag, w->j_type_bit, w->top_left_mv_flag, w->per_mb_rl_bit, code, w->flag3, - code); - } - return 0; -} - -int ff_wmv2_decode_picture_header(MpegEncContext * s) -{ - Wmv2Context * const w= (Wmv2Context*)s; - int code; - -#if 0 -{ -int i; -for(i=0; i<s->gb.size*8; i++) - printf("%d", get_bits1(&s->gb)); -// get_bits1(&s->gb); -printf("END\n"); -return -1; -} -#endif - if(s->picture_number==0) - decode_ext_header(w); - - s->pict_type = get_bits(&s->gb, 1) + 1; - if(s->pict_type == I_TYPE){ - code = get_bits(&s->gb, 7); - av_log(s->avctx, AV_LOG_DEBUG, "I7:%X/\n", code); - } - s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); - if(s->qscale < 0) - return -1; - - return 0; -} - -int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s) -{ - Wmv2Context * const w= (Wmv2Context*)s; - - if (s->pict_type == I_TYPE) { - if(w->j_type_bit) w->j_type= get_bits1(&s->gb); - else w->j_type= 0; //FIXME check - - if(!w->j_type){ - if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); - else s->per_mb_rl_table= 0; - - if(!s->per_mb_rl_table){ - s->rl_chroma_table_index = decode012(&s->gb); - s->rl_table_index = decode012(&s->gb); - } - - s->dc_table_index = get_bits1(&s->gb); - } - s->inter_intra_pred= 0; - s->no_rounding = 1; - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d j_type:%d \n", - s->qscale, - s->rl_chroma_table_index, - s->rl_table_index, - s->dc_table_index, - s->per_mb_rl_table, - w->j_type); - } - }else{ - int cbp_index; - w->j_type=0; - - parse_mb_skip(w); - cbp_index= decode012(&s->gb); - if(s->qscale <= 10){ - int map[3]= {0,2,1}; - w->cbp_table_index= map[cbp_index]; - }else if(s->qscale <= 20){ - int map[3]= {1,0,2}; - w->cbp_table_index= map[cbp_index]; - }else{ - int map[3]= {2,1,0}; - w->cbp_table_index= map[cbp_index]; - } - - if(w->mspel_bit) s->mspel= get_bits1(&s->gb); - else s->mspel= 0; //FIXME check - - if(w->abt_flag){ - w->per_mb_abt= get_bits1(&s->gb)^1; - if(!w->per_mb_abt){ - w->abt_type= decode012(&s->gb); - } - } - - if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); - else s->per_mb_rl_table= 0; - - if(!s->per_mb_rl_table){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - - s->dc_table_index = get_bits1(&s->gb); - s->mv_table_index = get_bits1(&s->gb); - - s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); - s->no_rounding ^= 1; - - if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d mspel:%d per_mb_abt:%d abt_type:%d cbp:%d ii:%d\n", - s->rl_table_index, - s->rl_chroma_table_index, - s->dc_table_index, - s->mv_table_index, - s->per_mb_rl_table, - s->qscale, - s->mspel, - w->per_mb_abt, - w->abt_type, - w->cbp_table_index, - s->inter_intra_pred); - } - } - s->esc3_level_length= 0; - s->esc3_run_length= 0; - -s->picture_number++; //FIXME ? - - -// if(w->j_type) -// return wmv2_decode_j_picture(w); //FIXME - - if(w->j_type){ - av_log(s->avctx, AV_LOG_ERROR, "J-type picture is not supported\n"); - return -1; - } - - return 0; -} - -static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr){ - MpegEncContext * const s= &w->s; - int ret; - - ret= msmpeg4_decode_motion(s, mx_ptr, my_ptr); - - if(ret<0) return -1; - - if((((*mx_ptr)|(*my_ptr)) & 1) && s->mspel) - w->hshift= get_bits1(&s->gb); - else - w->hshift= 0; - -//printf("%d %d ", *mx_ptr, *my_ptr); - - return 0; -} - -static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){ - MpegEncContext * const s= &w->s; - int xy, wrap, diff, type; - int16_t *A, *B, *C, *mot_val; - - wrap = s->b8_stride; - xy = s->block_index[0]; - - mot_val = s->current_picture.motion_val[0][xy]; - - A = s->current_picture.motion_val[0][xy - 1]; - B = s->current_picture.motion_val[0][xy - wrap]; - C = s->current_picture.motion_val[0][xy + 2 - wrap]; - - if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag) - diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1])); - else - diff=0; - - if(diff >= 8) - type= get_bits1(&s->gb); - else - type= 2; - - if(type == 0){ - *px= A[0]; - *py= A[1]; - }else if(type == 1){ - *px= B[0]; - *py= B[1]; - }else{ - /* special case for first (slice) line */ - if (s->first_slice_line) { - *px = A[0]; - *py = A[1]; - } else { - *px = mid_pred(A[0], B[0], C[0]); - *py = mid_pred(A[1], B[1], C[1]); - } - } - - return mot_val; -} - -static inline int wmv2_decode_inter_block(Wmv2Context *w, DCTELEM *block, int n, int cbp){ - MpegEncContext * const s= &w->s; - static const int sub_cbp_table[3]= {2,3,1}; - int sub_cbp; - - if(!cbp){ - s->block_last_index[n] = -1; - - return 0; - } - - if(w->per_block_abt) - w->abt_type= decode012(&s->gb); -#if 0 - if(w->per_block_abt) - printf("B%d", w->abt_type); -#endif - w->abt_type_table[n]= w->abt_type; - - if(w->abt_type){ -// const uint8_t *scantable= w->abt_scantable[w->abt_type-1].permutated; - const uint8_t *scantable= w->abt_scantable[w->abt_type-1].scantable; -// const uint8_t *scantable= w->abt_type-1 ? w->abt_scantable[1].permutated : w->abt_scantable[0].scantable; - - sub_cbp= sub_cbp_table[ decode012(&s->gb) ]; -// printf("S%d", sub_cbp); - - if(sub_cbp&1){ - if (msmpeg4_decode_block(s, block, n, 1, scantable) < 0) - return -1; - } - - if(sub_cbp&2){ - if (msmpeg4_decode_block(s, w->abt_block2[n], n, 1, scantable) < 0) - return -1; - } - s->block_last_index[n] = 63; - - return 0; - }else{ - return msmpeg4_decode_block(s, block, n, 1, s->inter_scantable.permutated); - } -} - static void wmv2_add_block(Wmv2Context *w, DCTELEM *block1, uint8_t *dst, int stride, int n){ MpegEncContext * const s= &w->s; @@ -595,13 +41,13 @@ static void wmv2_add_block(Wmv2Context *w, DCTELEM *block1, uint8_t *dst, int st s->dsp.idct_add (dst, stride, block1); break; case 1: - simple_idct84_add(dst , stride, block1); - simple_idct84_add(dst + 4*stride, stride, w->abt_block2[n]); + ff_simple_idct84_add(dst , stride, block1); + ff_simple_idct84_add(dst + 4*stride, stride, w->abt_block2[n]); memset(w->abt_block2[n], 0, 64*sizeof(DCTELEM)); break; case 2: - simple_idct48_add(dst , stride, block1); - simple_idct48_add(dst + 4 , stride, w->abt_block2[n]); + ff_simple_idct48_add(dst , stride, block1); + ff_simple_idct48_add(dst + 4 , stride, w->abt_block2[n]); memset(w->abt_block2[n], 0, 64*sizeof(DCTELEM)); break; default: @@ -711,151 +157,3 @@ void ff_mspel_motion(MpegEncContext *s, } pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1); } - - -static int wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) -{ - Wmv2Context * const w= (Wmv2Context*)s; - int cbp, code, i; - uint8_t *coded_val; - - if(w->j_type) return 0; - - if (s->pict_type == P_TYPE) { - if(IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])){ - /* skip mb */ - s->mb_intra = 0; - for(i=0;i<6;i++) - s->block_last_index[i] = -1; - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = 0; - s->mv[0][0][1] = 0; - s->mb_skipped = 1; - w->hshift=0; - return 0; - } - - code = get_vlc2(&s->gb, mb_non_intra_vlc[w->cbp_table_index].table, MB_NON_INTRA_VLC_BITS, 3); - if (code < 0) - return -1; - s->mb_intra = (~code & 0x40) >> 6; - - cbp = code & 0x3f; - } else { - s->mb_intra = 1; - code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); - if (code < 0){ - av_log(s->avctx, AV_LOG_ERROR, "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - /* predict coded block pattern */ - cbp = 0; - for(i=0;i<6;i++) { - int val = ((code >> (5 - i)) & 1); - if (i < 4) { - int pred = coded_block_pred(s, i, &coded_val); - val = val ^ pred; - *coded_val = val; - } - cbp |= val << (5 - i); - } - } - - if (!s->mb_intra) { - int mx, my; -//printf("P at %d %d\n", s->mb_x, s->mb_y); - wmv2_pred_motion(w, &mx, &my); - - if(cbp){ - s->dsp.clear_blocks(s->block[0]); - if(s->per_mb_rl_table){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - - if(w->abt_flag && w->per_mb_abt){ - w->per_block_abt= get_bits1(&s->gb); - if(!w->per_block_abt) - w->abt_type= decode012(&s->gb); - }else - w->per_block_abt=0; - } - - if (wmv2_decode_motion(w, &mx, &my) < 0) - return -1; - - s->mv_dir = MV_DIR_FORWARD; - s->mv_type = MV_TYPE_16X16; - s->mv[0][0][0] = mx; - s->mv[0][0][1] = my; - - for (i = 0; i < 6; i++) { - if (wmv2_decode_inter_block(w, block[i], i, (cbp >> (5 - i)) & 1) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding inter block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - } else { -//if(s->pict_type==P_TYPE) -// printf("%d%d ", s->inter_intra_pred, cbp); -//printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24)); - s->ac_pred = get_bits1(&s->gb); - if(s->inter_intra_pred){ - s->h263_aic_dir= get_vlc2(&s->gb, inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); -// printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); - } - if(s->per_mb_rl_table && cbp){ - s->rl_table_index = decode012(&s->gb); - s->rl_chroma_table_index = s->rl_table_index; - } - - s->dsp.clear_blocks(s->block[0]); - for (i = 0; i < 6; i++) { - if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) - { - av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding intra block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); - return -1; - } - } - } - - return 0; -} - -static int wmv2_decode_init(AVCodecContext *avctx){ - Wmv2Context * const w= avctx->priv_data; - - if(ff_h263_decode_init(avctx) < 0) - return -1; - - wmv2_common_init(w); - - return 0; -} - -AVCodec wmv2_decoder = { - "wmv2", - CODEC_TYPE_VIDEO, - CODEC_ID_WMV2, - sizeof(Wmv2Context), - wmv2_decode_init, - NULL, - ff_h263_decode_end, - ff_h263_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, -}; - -#ifdef CONFIG_ENCODERS -AVCodec wmv2_encoder = { - "wmv2", - CODEC_TYPE_VIDEO, - CODEC_ID_WMV2, - sizeof(Wmv2Context), - wmv2_encode_init, - MPV_encode_picture, - MPV_encode_end, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, -}; -#endif diff --git a/contrib/ffmpeg/libavcodec/wmv2.h b/contrib/ffmpeg/libavcodec/wmv2.h new file mode 100644 index 000000000..2fd842e6a --- /dev/null +++ b/contrib/ffmpeg/libavcodec/wmv2.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2002 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 + */ + +#ifndef FFMPEG_WMV2_H +#define FFMPEG_WMV2_H + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "intrax8.h" + +#define SKIP_TYPE_NONE 0 +#define SKIP_TYPE_MPEG 1 +#define SKIP_TYPE_ROW 2 +#define SKIP_TYPE_COL 3 + + +typedef struct Wmv2Context{ + MpegEncContext s; + IntraX8Context x8; + int j_type_bit; + int j_type; + int abt_flag; + int abt_type; + int abt_type_table[6]; + int per_mb_abt; + int per_block_abt; + int mspel_bit; + int cbp_table_index; + int top_left_mv_flag; + int per_mb_rl_bit; + int skip_type; + int hshift; + + ScanTable abt_scantable[2]; + DECLARE_ALIGNED_8(DCTELEM, abt_block2[6][64]); +}Wmv2Context; + +void ff_wmv2_common_init(Wmv2Context * w); + +#endif /* FFMPEG_WMV2_H */ diff --git a/contrib/ffmpeg/libavcodec/wmv2dec.c b/contrib/ffmpeg/libavcodec/wmv2dec.c new file mode 100644 index 000000000..cb3795512 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/wmv2dec.c @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2002 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 + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "msmpeg4.h" +#include "msmpeg4data.h" +#include "intrax8.h" +#include "wmv2.h" + + +static void parse_mb_skip(Wmv2Context * w){ + int mb_x, mb_y; + MpegEncContext * const s= &w->s; + uint32_t * const mb_type= s->current_picture_ptr->mb_type; + + w->skip_type= get_bits(&s->gb, 2); + switch(w->skip_type){ + case SKIP_TYPE_NONE: + for(mb_y=0; mb_y<s->mb_height; mb_y++){ + for(mb_x=0; mb_x<s->mb_width; mb_x++){ + mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_16x16 | MB_TYPE_L0; + } + } + break; + case SKIP_TYPE_MPEG: + for(mb_y=0; mb_y<s->mb_height; mb_y++){ + for(mb_x=0; mb_x<s->mb_width; mb_x++){ + mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; + } + } + break; + case SKIP_TYPE_ROW: + for(mb_y=0; mb_y<s->mb_height; mb_y++){ + if(get_bits1(&s->gb)){ + for(mb_x=0; mb_x<s->mb_width; mb_x++){ + mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + } + }else{ + for(mb_x=0; mb_x<s->mb_width; mb_x++){ + mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; + } + } + } + break; + case SKIP_TYPE_COL: + for(mb_x=0; mb_x<s->mb_width; mb_x++){ + if(get_bits1(&s->gb)){ + for(mb_y=0; mb_y<s->mb_height; mb_y++){ + mb_type[mb_y*s->mb_stride + mb_x]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + } + }else{ + for(mb_y=0; mb_y<s->mb_height; mb_y++){ + mb_type[mb_y*s->mb_stride + mb_x]= (get_bits1(&s->gb) ? MB_TYPE_SKIP : 0) | MB_TYPE_16x16 | MB_TYPE_L0; + } + } + } + break; + } +} + +static int decode_ext_header(Wmv2Context *w){ + MpegEncContext * const s= &w->s; + GetBitContext gb; + int fps; + int code; + + if(s->avctx->extradata_size<4) return -1; + + init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8); + + fps = get_bits(&gb, 5); + s->bit_rate = get_bits(&gb, 11)*1024; + w->mspel_bit = get_bits1(&gb); + s->loop_filter = get_bits1(&gb); + w->abt_flag = get_bits1(&gb); + w->j_type_bit = get_bits1(&gb); + w->top_left_mv_flag= get_bits1(&gb); + w->per_mb_rl_bit = get_bits1(&gb); + code = get_bits(&gb, 3); + + if(code==0) return -1; + + s->slice_height = s->mb_height / code; + + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + av_log(s->avctx, AV_LOG_DEBUG, "fps:%d, br:%d, qpbit:%d, abt_flag:%d, j_type_bit:%d, tl_mv_flag:%d, mbrl_bit:%d, code:%d, loop_filter:%d, slices:%d\n", + fps, s->bit_rate, w->mspel_bit, w->abt_flag, w->j_type_bit, w->top_left_mv_flag, w->per_mb_rl_bit, code, s->loop_filter, + code); + } + return 0; +} + +int ff_wmv2_decode_picture_header(MpegEncContext * s) +{ + Wmv2Context * const w= (Wmv2Context*)s; + int code; + +#if 0 +{ +int i; +for(i=0; i<s->gb.size*8; i++) + printf("%d", get_bits1(&s->gb)); +// get_bits1(&s->gb); +printf("END\n"); +return -1; +} +#endif + if(s->picture_number==0) + decode_ext_header(w); + + s->pict_type = get_bits1(&s->gb) + 1; + if(s->pict_type == I_TYPE){ + code = get_bits(&s->gb, 7); + av_log(s->avctx, AV_LOG_DEBUG, "I7:%X/\n", code); + } + s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); + if(s->qscale <= 0) + return -1; + + return 0; +} + +int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s) +{ + Wmv2Context * const w= (Wmv2Context*)s; + + if (s->pict_type == I_TYPE) { + if(w->j_type_bit) w->j_type= get_bits1(&s->gb); + else w->j_type= 0; //FIXME check + + if(!w->j_type){ + if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); + else s->per_mb_rl_table= 0; + + if(!s->per_mb_rl_table){ + s->rl_chroma_table_index = decode012(&s->gb); + s->rl_table_index = decode012(&s->gb); + } + + s->dc_table_index = get_bits1(&s->gb); + } + s->inter_intra_pred= 0; + s->no_rounding = 1; + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d j_type:%d \n", + s->qscale, + s->rl_chroma_table_index, + s->rl_table_index, + s->dc_table_index, + s->per_mb_rl_table, + w->j_type); + } + }else{ + int cbp_index; + w->j_type=0; + + parse_mb_skip(w); + cbp_index= decode012(&s->gb); + if(s->qscale <= 10){ + int map[3]= {0,2,1}; + w->cbp_table_index= map[cbp_index]; + }else if(s->qscale <= 20){ + int map[3]= {1,0,2}; + w->cbp_table_index= map[cbp_index]; + }else{ + int map[3]= {2,1,0}; + w->cbp_table_index= map[cbp_index]; + } + + if(w->mspel_bit) s->mspel= get_bits1(&s->gb); + else s->mspel= 0; //FIXME check + + if(w->abt_flag){ + w->per_mb_abt= get_bits1(&s->gb)^1; + if(!w->per_mb_abt){ + w->abt_type= decode012(&s->gb); + } + } + + if(w->per_mb_rl_bit) s->per_mb_rl_table= get_bits1(&s->gb); + else s->per_mb_rl_table= 0; + + if(!s->per_mb_rl_table){ + s->rl_table_index = decode012(&s->gb); + s->rl_chroma_table_index = s->rl_table_index; + } + + s->dc_table_index = get_bits1(&s->gb); + s->mv_table_index = get_bits1(&s->gb); + + s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); + s->no_rounding ^= 1; + + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + av_log(s->avctx, AV_LOG_DEBUG, "rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d mspel:%d per_mb_abt:%d abt_type:%d cbp:%d ii:%d\n", + s->rl_table_index, + s->rl_chroma_table_index, + s->dc_table_index, + s->mv_table_index, + s->per_mb_rl_table, + s->qscale, + s->mspel, + w->per_mb_abt, + w->abt_type, + w->cbp_table_index, + s->inter_intra_pred); + } + } + s->esc3_level_length= 0; + s->esc3_run_length= 0; + +s->picture_number++; //FIXME ? + + + if(w->j_type){ + ff_intrax8_decode_picture(&w->x8, 2*s->qscale, (s->qscale-1)|1 ); + return 1; + } + + return 0; +} + +static inline int wmv2_decode_motion(Wmv2Context *w, int *mx_ptr, int *my_ptr){ + MpegEncContext * const s= &w->s; + int ret; + + ret= ff_msmpeg4_decode_motion(s, mx_ptr, my_ptr); + + if(ret<0) return -1; + + if((((*mx_ptr)|(*my_ptr)) & 1) && s->mspel) + w->hshift= get_bits1(&s->gb); + else + w->hshift= 0; + +//printf("%d %d ", *mx_ptr, *my_ptr); + + return 0; +} + +static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){ + MpegEncContext * const s= &w->s; + int xy, wrap, diff, type; + int16_t *A, *B, *C, *mot_val; + + wrap = s->b8_stride; + xy = s->block_index[0]; + + mot_val = s->current_picture.motion_val[0][xy]; + + A = s->current_picture.motion_val[0][xy - 1]; + B = s->current_picture.motion_val[0][xy - wrap]; + C = s->current_picture.motion_val[0][xy + 2 - wrap]; + + if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag) + diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1])); + else + diff=0; + + if(diff >= 8) + type= get_bits1(&s->gb); + else + type= 2; + + if(type == 0){ + *px= A[0]; + *py= A[1]; + }else if(type == 1){ + *px= B[0]; + *py= B[1]; + }else{ + /* special case for first (slice) line */ + if (s->first_slice_line) { + *px = A[0]; + *py = A[1]; + } else { + *px = mid_pred(A[0], B[0], C[0]); + *py = mid_pred(A[1], B[1], C[1]); + } + } + + return mot_val; +} + +static inline int wmv2_decode_inter_block(Wmv2Context *w, DCTELEM *block, int n, int cbp){ + MpegEncContext * const s= &w->s; + static const int sub_cbp_table[3]= {2,3,1}; + int sub_cbp; + + if(!cbp){ + s->block_last_index[n] = -1; + + return 0; + } + + if(w->per_block_abt) + w->abt_type= decode012(&s->gb); +#if 0 + if(w->per_block_abt) + printf("B%d", w->abt_type); +#endif + w->abt_type_table[n]= w->abt_type; + + if(w->abt_type){ +// const uint8_t *scantable= w->abt_scantable[w->abt_type-1].permutated; + const uint8_t *scantable= w->abt_scantable[w->abt_type-1].scantable; +// const uint8_t *scantable= w->abt_type-1 ? w->abt_scantable[1].permutated : w->abt_scantable[0].scantable; + + sub_cbp= sub_cbp_table[ decode012(&s->gb) ]; +// printf("S%d", sub_cbp); + + if(sub_cbp&1){ + if (ff_msmpeg4_decode_block(s, block, n, 1, scantable) < 0) + return -1; + } + + if(sub_cbp&2){ + if (ff_msmpeg4_decode_block(s, w->abt_block2[n], n, 1, scantable) < 0) + return -1; + } + s->block_last_index[n] = 63; + + return 0; + }else{ + return ff_msmpeg4_decode_block(s, block, n, 1, s->inter_scantable.permutated); + } +} + + +int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) +{ + Wmv2Context * const w= (Wmv2Context*)s; + int cbp, code, i; + uint8_t *coded_val; + + if(w->j_type) return 0; + + if (s->pict_type == P_TYPE) { + if(IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])){ + /* skip mb */ + s->mb_intra = 0; + for(i=0;i<6;i++) + s->block_last_index[i] = -1; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mb_skipped = 1; + w->hshift=0; + return 0; + } + + code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[w->cbp_table_index].table, MB_NON_INTRA_VLC_BITS, 3); + if (code < 0) + return -1; + s->mb_intra = (~code & 0x40) >> 6; + + cbp = code & 0x3f; + } else { + s->mb_intra = 1; + code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2); + if (code < 0){ + av_log(s->avctx, AV_LOG_ERROR, "II-cbp illegal at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + /* predict coded block pattern */ + cbp = 0; + for(i=0;i<6;i++) { + int val = ((code >> (5 - i)) & 1); + if (i < 4) { + int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val); + val = val ^ pred; + *coded_val = val; + } + cbp |= val << (5 - i); + } + } + + if (!s->mb_intra) { + int mx, my; +//printf("P at %d %d\n", s->mb_x, s->mb_y); + wmv2_pred_motion(w, &mx, &my); + + if(cbp){ + s->dsp.clear_blocks(s->block[0]); + if(s->per_mb_rl_table){ + s->rl_table_index = decode012(&s->gb); + s->rl_chroma_table_index = s->rl_table_index; + } + + if(w->abt_flag && w->per_mb_abt){ + w->per_block_abt= get_bits1(&s->gb); + if(!w->per_block_abt) + w->abt_type= decode012(&s->gb); + }else + w->per_block_abt=0; + } + + if (wmv2_decode_motion(w, &mx, &my) < 0) + return -1; + + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = mx; + s->mv[0][0][1] = my; + + for (i = 0; i < 6; i++) { + if (wmv2_decode_inter_block(w, block[i], i, (cbp >> (5 - i)) & 1) < 0) + { + av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding inter block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); + return -1; + } + } + } else { +//if(s->pict_type==P_TYPE) +// printf("%d%d ", s->inter_intra_pred, cbp); +//printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24)); + s->ac_pred = get_bits1(&s->gb); + if(s->inter_intra_pred){ + s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); +// printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); + } + if(s->per_mb_rl_table && cbp){ + s->rl_table_index = decode012(&s->gb); + s->rl_chroma_table_index = s->rl_table_index; + } + + s->dsp.clear_blocks(s->block[0]); + for (i = 0; i < 6; i++) { + if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) + { + av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding intra block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); + return -1; + } + } + } + + return 0; +} + +static int wmv2_decode_init(AVCodecContext *avctx){ + Wmv2Context * const w= avctx->priv_data; + + if(avctx->idct_algo==FF_IDCT_AUTO){ + avctx->idct_algo=FF_IDCT_WMV2; + } + + if(ff_h263_decode_init(avctx) < 0) + return -1; + + ff_wmv2_common_init(w); + + ff_intrax8_common_init(&w->x8,&w->s); + + return 0; +} + +static int wmv2_decode_end(AVCodecContext *avctx) +{ + Wmv2Context *w = avctx->priv_data; + + ff_intrax8_common_end(&w->x8); + return ff_h263_decode_end(avctx); +} + +AVCodec wmv2_decoder = { + "wmv2", + CODEC_TYPE_VIDEO, + CODEC_ID_WMV2, + sizeof(Wmv2Context), + wmv2_decode_init, + NULL, + wmv2_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, +}; diff --git a/contrib/ffmpeg/libavcodec/wmv2enc.c b/contrib/ffmpeg/libavcodec/wmv2enc.c new file mode 100644 index 000000000..641f0dc85 --- /dev/null +++ b/contrib/ffmpeg/libavcodec/wmv2enc.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2002 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 + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "msmpeg4.h" +#include "msmpeg4data.h" +#include "wmv2.h" + + +static int encode_ext_header(Wmv2Context *w){ + MpegEncContext * const s= &w->s; + PutBitContext pb; + int code; + + init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size); + + put_bits(&pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 + put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047)); + + put_bits(&pb, 1, w->mspel_bit=1); + put_bits(&pb, 1, s->loop_filter); + put_bits(&pb, 1, w->abt_flag=1); + put_bits(&pb, 1, w->j_type_bit=1); + put_bits(&pb, 1, w->top_left_mv_flag=0); + put_bits(&pb, 1, w->per_mb_rl_bit=1); + put_bits(&pb, 3, code=1); + + flush_put_bits(&pb); + + s->slice_height = s->mb_height / code; + + return 0; +} + +static int wmv2_encode_init(AVCodecContext *avctx){ + Wmv2Context * const w= avctx->priv_data; + + if(MPV_encode_init(avctx) < 0) + return -1; + + ff_wmv2_common_init(w); + + avctx->extradata_size= 4; + avctx->extradata= av_mallocz(avctx->extradata_size + 10); + encode_ext_header(w); + + return 0; +} + +#if 0 /* unused, remove? */ +static int wmv2_encode_end(AVCodecContext *avctx){ + + if(MPV_encode_end(avctx) < 0) + return -1; + + avctx->extradata_size= 0; + av_freep(&avctx->extradata); + + return 0; +} +#endif + +int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number) +{ + Wmv2Context * const w= (Wmv2Context*)s; + + put_bits(&s->pb, 1, s->pict_type - 1); + if(s->pict_type == I_TYPE){ + put_bits(&s->pb, 7, 0); + } + put_bits(&s->pb, 5, s->qscale); + + s->dc_table_index = 1; + s->mv_table_index = 1; /* only if P frame */ +// s->use_skip_mb_code = 1; /* only if P frame */ + s->per_mb_rl_table = 0; + s->mspel= 0; + w->per_mb_abt=0; + w->abt_type=0; + w->j_type=0; + + assert(s->flipflop_rounding); + + if (s->pict_type == I_TYPE) { + assert(s->no_rounding==1); + if(w->j_type_bit) put_bits(&s->pb, 1, w->j_type); + + if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); + + if(!s->per_mb_rl_table){ + ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index); + ff_msmpeg4_code012(&s->pb, s->rl_table_index); + } + + put_bits(&s->pb, 1, s->dc_table_index); + + s->inter_intra_pred= 0; + }else{ + int cbp_index; + + put_bits(&s->pb, 2, SKIP_TYPE_NONE); + + ff_msmpeg4_code012(&s->pb, cbp_index=0); + if(s->qscale <= 10){ + int map[3]= {0,2,1}; + w->cbp_table_index= map[cbp_index]; + }else if(s->qscale <= 20){ + int map[3]= {1,0,2}; + w->cbp_table_index= map[cbp_index]; + }else{ + int map[3]= {2,1,0}; + w->cbp_table_index= map[cbp_index]; + } + + if(w->mspel_bit) put_bits(&s->pb, 1, s->mspel); + + if(w->abt_flag){ + put_bits(&s->pb, 1, w->per_mb_abt^1); + if(!w->per_mb_abt){ + ff_msmpeg4_code012(&s->pb, w->abt_type); + } + } + + if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table); + + if(!s->per_mb_rl_table){ + ff_msmpeg4_code012(&s->pb, s->rl_table_index); + s->rl_chroma_table_index = s->rl_table_index; + } + put_bits(&s->pb, 1, s->dc_table_index); + put_bits(&s->pb, 1, s->mv_table_index); + + s->inter_intra_pred= 0;//(s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); + } + s->esc3_level_length= 0; + s->esc3_run_length= 0; + + return 0; +} + +/* Nearly identical to wmv1 but that is just because we do not use the + * useless M$ crap features. It is duplicated here in case someone wants + * to add support for these crap features. */ +void ff_wmv2_encode_mb(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y) +{ + Wmv2Context * const w= (Wmv2Context*)s; + int cbp, coded_cbp, i; + int pred_x, pred_y; + uint8_t *coded_block; + + ff_msmpeg4_handle_slices(s); + + if (!s->mb_intra) { + /* compute cbp */ + cbp = 0; + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + + put_bits(&s->pb, + wmv2_inter_table[w->cbp_table_index][cbp + 64][1], + wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); + + /* motion vector */ + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_msmpeg4_encode_motion(s, motion_x - pred_x, + motion_y - pred_y); + } else { + /* compute cbp */ + cbp = 0; + coded_cbp = 0; + for (i = 0; i < 6; i++) { + int val, pred; + val = (s->block_last_index[i] >= 1); + cbp |= val << (5 - i); + if (i < 4) { + /* predict value for close blocks only for luma */ + pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); + *coded_block = val; + val = val ^ pred; + } + coded_cbp |= val << (5 - i); + } +#if 0 + if (coded_cbp) + printf("cbp=%x %x\n", cbp, coded_cbp); +#endif + + if (s->pict_type == I_TYPE) { + put_bits(&s->pb, + ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); + } else { + put_bits(&s->pb, + wmv2_inter_table[w->cbp_table_index][cbp][1], + wmv2_inter_table[w->cbp_table_index][cbp][0]); + } + put_bits(&s->pb, 1, 0); /* no AC prediction yet */ + if(s->inter_intra_pred){ + s->h263_aic_dir=0; + put_bits(&s->pb, table_inter_intra[s->h263_aic_dir][1], table_inter_intra[s->h263_aic_dir][0]); + } + } + + for (i = 0; i < 6; i++) { + ff_msmpeg4_encode_block(s, block[i], i); + } +} + +AVCodec wmv2_encoder = { + "wmv2", + CODEC_TYPE_VIDEO, + CODEC_ID_WMV2, + sizeof(Wmv2Context), + wmv2_encode_init, + MPV_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, -1}, +}; diff --git a/contrib/ffmpeg/libavcodec/wnv1.c b/contrib/ffmpeg/libavcodec/wnv1.c index 46b31a5c5..0aadf4dbe 100644 --- a/contrib/ffmpeg/libavcodec/wnv1.c +++ b/contrib/ffmpeg/libavcodec/wnv1.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -26,7 +25,6 @@ */ #include "avcodec.h" -#include "common.h" #include "bitstream.h" diff --git a/contrib/ffmpeg/libavcodec/ws-snd1.c b/contrib/ffmpeg/libavcodec/ws-snd1.c index 3624909a3..057d4bfc2 100644 --- a/contrib/ffmpeg/libavcodec/ws-snd1.c +++ b/contrib/ffmpeg/libavcodec/ws-snd1.c @@ -45,7 +45,7 @@ static int ws_snd_decode_init(AVCodecContext * avctx) static int ws_snd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { // WSSNDContext *c = avctx->priv_data; @@ -62,6 +62,14 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, in_size = AV_RL16(&buf[2]); buf += 4; + if (out_size > *data_size) { + av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); + return -1; + } + if (in_size > buf_size) { + av_log(avctx, AV_LOG_ERROR, "Frame data is larger than input buffer\n"); + return -1; + } if (in_size == out_size) { for (i = 0; i < out_size; i++) *samples++ = (*buf++ - 0x80) << 8; diff --git a/contrib/ffmpeg/libavcodec/xan.c b/contrib/ffmpeg/libavcodec/xan.c index f697514a0..27fc16488 100644 --- a/contrib/ffmpeg/libavcodec/xan.c +++ b/contrib/ffmpeg/libavcodec/xan.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -34,7 +33,6 @@ #include <string.h> #include <unistd.h> -#include "common.h" #include "avcodec.h" typedef struct XanContext { @@ -43,7 +41,7 @@ typedef struct XanContext { AVFrame last_frame; AVFrame current_frame; - unsigned char *buf; + const unsigned char *buf; int size; /* scratch space */ @@ -70,7 +68,6 @@ static int xan_decode_init(AVCodecContext *avctx) } avctx->pix_fmt = PIX_FMT_PAL8; - avctx->has_b_frames = 0; if(avcodec_check_dimensions(avctx, avctx->width, avctx->height)) return -1; @@ -85,12 +82,12 @@ static int xan_decode_init(AVCodecContext *avctx) return 0; } -/* This function is used in lieu of memcpy(). This decoder can not use +/* This function is used in lieu of memcpy(). This decoder cannot use * memcpy because the memory locations often overlap and * memcpy doesn't like that; it's not uncommon, for example, for * dest = src+1, to turn byte A into pattern AAAAAAAA. * This was originally repz movsb in Intel x86 ASM. */ -static inline void bytecopy(unsigned char *dest, unsigned char *src, int count) +static inline void bytecopy(unsigned char *dest, const unsigned char *src, int count) { int i; @@ -98,12 +95,12 @@ static inline void bytecopy(unsigned char *dest, unsigned char *src, int count) dest[i] = src[i]; } -static int xan_huffman_decode(unsigned char *dest, unsigned char *src, +static int xan_huffman_decode(unsigned char *dest, const unsigned char *src, int dest_len) { unsigned char byte = *src++; unsigned char ival = byte + 0x16; - unsigned char * ptr = src + byte*2; + const unsigned char * ptr = src + byte*2; unsigned char val = ival; int counter = 0; unsigned char *dest_end = dest + dest_len; @@ -132,7 +129,7 @@ static int xan_huffman_decode(unsigned char *dest, unsigned char *src, return 0; } -static void xan_unpack(unsigned char *dest, unsigned char *src, int dest_len) +static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_len) { unsigned char opcode; int size; @@ -208,8 +205,8 @@ static void xan_unpack(unsigned char *dest, unsigned char *src, int dest_len) bytecopy(dest, src, size); dest += size; src += size; } -static void inline xan_wc3_output_pixel_run(XanContext *s, - unsigned char *pixel_buffer, int x, int y, int pixel_count) +static inline void xan_wc3_output_pixel_run(XanContext *s, + const unsigned char *pixel_buffer, int x, int y, int pixel_count) { int stride; int line_inc; @@ -237,7 +234,7 @@ static void inline xan_wc3_output_pixel_run(XanContext *s, } } -static void inline xan_wc3_copy_pixel_run(XanContext *s, +static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y, int pixel_count, int motion_x, int motion_y) { int stride; @@ -287,14 +284,13 @@ static void xan_wc3_decode_frame(XanContext *s) { unsigned char *opcode_buffer = s->buffer1; int opcode_buffer_size = s->buffer1_size; - unsigned char *imagedata_buffer = s->buffer2; - int imagedata_buffer_size = s->buffer2_size; + const unsigned char *imagedata_buffer = s->buffer2; /* pointers to segments inside the compressed chunk */ - unsigned char *huffman_segment; - unsigned char *size_segment; - unsigned char *vector_segment; - unsigned char *imagedata_segment; + const unsigned char *huffman_segment; + const unsigned char *size_segment; + const unsigned char *vector_segment; + const unsigned char *imagedata_segment; huffman_segment = s->buf + AV_RL16(&s->buf[0]); size_segment = s->buf + AV_RL16(&s->buf[2]); @@ -304,8 +300,7 @@ static void xan_wc3_decode_frame(XanContext *s) { xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size); if (imagedata_segment[0] == 2) - xan_unpack(imagedata_buffer, &imagedata_segment[1], - imagedata_buffer_size); + xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size); else imagedata_buffer = &imagedata_segment[1]; @@ -356,8 +351,7 @@ static void xan_wc3_decode_frame(XanContext *s) { case 11: case 21: - size = (size_segment[0] << 16) | (size_segment[1] << 8) | - size_segment[2]; + size = AV_RB24(size_segment); size_segment += 3; break; } @@ -410,7 +404,7 @@ static void xan_wc4_decode_frame(XanContext *s) { static int xan_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { XanContext *s = avctx->priv_data; AVPaletteControl *palette_control = avctx->palctrl; diff --git a/contrib/ffmpeg/libavcodec/xiph.h b/contrib/ffmpeg/libavcodec/xiph.h index 85cfeebaf..7e7575010 100644 --- a/contrib/ffmpeg/libavcodec/xiph.h +++ b/contrib/ffmpeg/libavcodec/xiph.h @@ -18,6 +18,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef FFMPEG_XIPH_H +#define FFMPEG_XIPH_H + #include "common.h" /** @@ -36,3 +39,5 @@ int ff_split_xiph_headers(uint8_t *extradata, int extradata_size, int first_header_size, uint8_t *header_start[3], int header_len[3]); + +#endif /* FFMPEG_XIPH_H */ diff --git a/contrib/ffmpeg/libavcodec/xl.c b/contrib/ffmpeg/libavcodec/xl.c index 8a011d887..b48a369b8 100644 --- a/contrib/ffmpeg/libavcodec/xl.c +++ b/contrib/ffmpeg/libavcodec/xl.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -41,7 +40,7 @@ static const int xl_table[32] = { static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + const uint8_t *buf, int buf_size) { VideoXLContext * const a = avctx->priv_data; AVFrame * const p= (AVFrame*)&a->pic; diff --git a/contrib/ffmpeg/libavcodec/xsubdec.c b/contrib/ffmpeg/libavcodec/xsubdec.c new file mode 100644 index 000000000..391a003ac --- /dev/null +++ b/contrib/ffmpeg/libavcodec/xsubdec.c @@ -0,0 +1,136 @@ +/* + * XSUB subtitle decoder + * Copyright (c) 2007 Reimar Döffinger + * + * 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" +#include "bitstream.h" +#include "bytestream.h" + +static int decode_init(AVCodecContext *avctx) { + avctx->pix_fmt = PIX_FMT_PAL8; + return 0; +} + +static const uint8_t tc_offsets[9] = { 0, 1, 3, 4, 6, 7, 9, 10, 11 }; +static const uint8_t tc_muls[9] = { 10, 6, 10, 6, 10, 6, 10, 10, 1 }; + +static uint64_t parse_timecode(const uint8_t *buf) { + int i; + int64_t ms = 0; + if (buf[2] != ':' || buf[5] != ':' || buf[8] != '.') + return AV_NOPTS_VALUE; + for (i = 0; i < sizeof(tc_offsets); i++) { + uint8_t c = buf[tc_offsets[i]] - '0'; + if (c > 9) return AV_NOPTS_VALUE; + ms = (ms + c) * tc_muls[i]; + } + return ms; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, + const uint8_t *buf, int buf_size) { + AVSubtitle *sub = data; + const uint8_t *buf_end = buf + buf_size; + uint8_t *bitmap; + int w, h, x, y, rlelen, i; + GetBitContext gb; + + // check that at least header fits + if (buf_size < 27 + 7 * 2 + 4 * 3) { + av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); + return -1; + } + + // read start and end time + if (buf[0] != '[' || buf[13] != '-' || buf[26] != ']') { + av_log(avctx, AV_LOG_ERROR, "invalid time code\n"); + return -1; + } + sub->start_display_time = parse_timecode(buf + 1); + sub->end_display_time = parse_timecode(buf + 14); + buf += 27; + + // read header + w = bytestream_get_le16(&buf); + h = bytestream_get_le16(&buf); + if (avcodec_check_dimensions(avctx, w, h) < 0) + return -1; + x = bytestream_get_le16(&buf); + y = bytestream_get_le16(&buf); + // skip bottom right position, it gives no new information + bytestream_get_le16(&buf); + bytestream_get_le16(&buf); + rlelen = bytestream_get_le16(&buf); + + // allocate sub and set values + if (!sub->rects) { + sub->rects = av_mallocz(sizeof(AVSubtitleRect)); + sub->num_rects = 1; + } + av_freep(&sub->rects[0].bitmap); + sub->rects[0].x = x; sub->rects[0].y = y; + sub->rects[0].w = w; sub->rects[0].h = h; + sub->rects[0].linesize = w; + sub->rects[0].bitmap = av_malloc(w * h); + sub->rects[0].nb_colors = 4; + sub->rects[0].rgba_palette = av_malloc(sub->rects[0].nb_colors * 4); + + // read palette + for (i = 0; i < sub->rects[0].nb_colors; i++) + sub->rects[0].rgba_palette[i] = bytestream_get_be24(&buf); + // make all except background (first entry) non-transparent + for (i = 1; i < sub->rects[0].nb_colors; i++) + sub->rects[0].rgba_palette[i] |= 0xff000000; + + // process RLE-compressed data + rlelen = FFMIN(rlelen, buf_end - buf); + init_get_bits(&gb, buf, rlelen * 8); + bitmap = sub->rects[0].bitmap; + for (y = 0; y < h; y++) { + // interlaced: do odd lines + if (y == (h + 1) / 2) bitmap = sub->rects[0].bitmap + w; + for (x = 0; x < w; ) { + int log2 = ff_log2_tab[show_bits(&gb, 8)]; + int run = get_bits(&gb, 14 - 4 * (log2 >> 1)); + int color = get_bits(&gb, 2); + run = FFMIN(run, w - x); + // run length 0 means till end of row + if (!run) run = w - x; + memset(bitmap, color, run); + bitmap += run; + x += run; + } + // interlaced, skip every second line + bitmap += w; + align_get_bits(&gb); + } + *data_size = 1; + return buf_size; +} + +AVCodec xsub_decoder = { + "xsub", + CODEC_TYPE_SUBTITLE, + CODEC_ID_XSUB, + 0, + decode_init, + NULL, + NULL, + decode_frame, +}; diff --git a/contrib/ffmpeg/libavcodec/xvmc_render.h b/contrib/ffmpeg/libavcodec/xvmc_render.h index 37b342294..10fd56ffa 100644 --- a/contrib/ffmpeg/libavcodec/xvmc_render.h +++ b/contrib/ffmpeg/libavcodec/xvmc_render.h @@ -1,3 +1,26 @@ +/* + * Copyright (C) 2003 Ivan Kalvachev + * + * 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 + */ + +#ifndef FFMPEG_XVMC_RENDER_H +#define FFMPEG_XVMC_RENDER_H + #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> @@ -6,9 +29,9 @@ #include <X11/extensions/XvMClib.h> -//the surface should be shown, video driver manipulate this +//the surface should be shown, video driver manipulates this #define MP_XVMC_STATE_DISPLAY_PENDING 1 -//the surface is needed for prediction, codec manipulate this +//the surface is needed for prediction, codec manipulates this #define MP_XVMC_STATE_PREDICTION 2 //this surface is needed for subpicture rendering #define MP_XVMC_STATE_OSD_SOURCE 4 @@ -16,7 +39,7 @@ #define MP_XVMC_RENDER_MAGIC 0x1DC711C0 typedef struct{ -//these are not changed by decoder! +//these are not changed by the decoder! int magic; short * data_blocks; @@ -24,7 +47,7 @@ typedef struct{ int total_number_of_mv_blocks; int total_number_of_data_blocks; int mc_type;//XVMC_MPEG1/2/4,XVMC_H263 without XVMC_IDCT - int idct;//does we use IDCT acceleration? + int idct;//Do we use IDCT acceleration? int chroma_format;//420,422,444 int unsigned_intra;//+-128 for intra pictures after clip XvMCSurface* p_surface;//pointer to rendered surface, never changed @@ -34,17 +57,19 @@ typedef struct{ XvMCSurface* p_past_surface;//pointer to the past surface XvMCSurface* p_future_surface;//pointer to the future prediction surface - unsigned int picture_structure;//top/bottom fields or frame ! + unsigned int picture_structure;//top/bottom fields or frame! unsigned int flags;//XVMC_SECOND_FIELD - 1'st or 2'd field in the sequence unsigned int display_flags; //1,2 or 1+2 fields for XvMCPutSurface, -//these are internal communication one - int state;//0-free,1 Waiting to Display,2 Waiting for prediction - int start_mv_blocks_num;//offset in the array for the current slice,updated by vo - int filled_mv_blocks_num;//processed mv block in this slice,change by decoder +//these are internal communication ones + int state;//0-free, 1 Waiting to Display, 2 Waiting for prediction + int start_mv_blocks_num;//offset in the array for the current slice, updated by vo + int filled_mv_blocks_num;//processed mv block in this slice, changed by decoder int next_free_data_block_num;//used in add_mv_block, pointer to next free block //extensions void * p_osd_target_surface_render;//pointer to the surface where subpicture is rendered } xvmc_render_state_t; + +#endif /* FFMPEG_XVMC_RENDER_H */ diff --git a/contrib/ffmpeg/libavcodec/xvmcvideo.c b/contrib/ffmpeg/libavcodec/xvmcvideo.c index 4a0677f6e..1a112e1c8 100644 --- a/contrib/ffmpeg/libavcodec/xvmcvideo.c +++ b/contrib/ffmpeg/libavcodec/xvmcvideo.c @@ -29,10 +29,6 @@ #undef NDEBUG #include <assert.h> -#ifdef USE_FASTMEMCPY -#include "libvo/fastmemcpy.h" -#endif - #ifdef HAVE_XVMC //X11 includes are in the xvmc_render.h @@ -44,7 +40,7 @@ //#include "xvmc_debug.h" //set s->block -inline void XVMC_init_block(MpegEncContext *s){ +void XVMC_init_block(MpegEncContext *s){ xvmc_render_state_t * render; render = (xvmc_render_state_t*)s->current_picture.data[2]; assert(render != NULL); diff --git a/contrib/ffmpeg/libavcodec/zmbv.c b/contrib/ffmpeg/libavcodec/zmbv.c index 89b8418c5..1eb8ef00a 100644 --- a/contrib/ffmpeg/libavcodec/zmbv.c +++ b/contrib/ffmpeg/libavcodec/zmbv.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -28,12 +27,9 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" -#ifdef CONFIG_ZLIB #include <zlib.h> -#endif #define ZMBV_KEYFRAME 1 #define ZMBV_DELTAPAL 2 @@ -68,9 +64,7 @@ typedef struct ZmbvContext { int flags; int bw, bh, bx, by; int decomp_len; -#ifdef CONFIG_ZLIB z_stream zstream; -#endif int (*decode_intra)(struct ZmbvContext *c); int (*decode_xor)(struct ZmbvContext *c); } ZmbvContext; @@ -147,7 +141,7 @@ static int zmbv_decode_xor_8(ZmbvContext *c) prev += c->width * c->bh; } if(src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); + av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len); return 0; } @@ -220,7 +214,7 @@ static int zmbv_decode_xor_16(ZmbvContext *c) prev += c->width * c->bh; } if(src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); + av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len); return 0; } @@ -376,7 +370,7 @@ static int zmbv_decode_xor_32(ZmbvContext *c) prev += c->width * c->bh; } if(src - c->decomp_buf != c->decomp_len) - av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); + av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len); return 0; } @@ -397,13 +391,11 @@ static int zmbv_decode_intra(ZmbvContext *c) return 0; } -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { - ZmbvContext * const c = (ZmbvContext *)avctx->priv_data; + ZmbvContext * const c = avctx->priv_data; uint8_t *outptr; -#ifdef CONFIG_ZLIB int zret = Z_OK; // Zlib return code -#endif int len = buf_size; int hi_ver, lo_ver; @@ -475,16 +467,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 av_log(avctx, AV_LOG_ERROR, "Unsupported (for now) format %i\n", c->fmt); return -1; } -#ifdef CONFIG_ZLIB + zret = inflateReset(&c->zstream); if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); return -1; } -#else - av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); - return -1; -#endif /* CONFIG_ZLIB */ + c->cur = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8)); c->prev = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8)); c->bx = (c->width + c->bw - 1) / c->bw; @@ -500,7 +489,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 memcpy(c->decomp_buf, buf, len); c->decomp_size = 1; } else { // ZLIB-compressed data -#ifdef CONFIG_ZLIB c->zstream.total_in = c->zstream.total_out = 0; c->zstream.next_in = buf; c->zstream.avail_in = len; @@ -508,10 +496,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 c->zstream.avail_out = c->decomp_size; inflate(&c->zstream, Z_FINISH); c->decomp_len = c->zstream.total_out; -#else - av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); - return -1; -#endif } if(c->flags & ZMBV_KEYFRAME) { c->pic.key_frame = 1; @@ -537,7 +521,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 out[i * 3 + 0] = c->pal[(*src) * 3 + 0]; out[i * 3 + 1] = c->pal[(*src) * 3 + 1]; out[i * 3 + 2] = c->pal[(*src) * 3 + 2]; - *src++; + src++; } out += c->pic.linesize[0]; } @@ -580,9 +564,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 for(i = 0; i < c->width; i++) { uint32_t tmp = AV_RL32(src); src += 4; - out[i * 3 + 0] = tmp >> 16; - out[i * 3 + 1] = tmp >> 8; - out[i * 3 + 2] = tmp >> 0; + AV_WB24(out+(i*3), tmp); } out += c->pic.linesize[0]; } @@ -608,7 +590,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 */ static int decode_init(AVCodecContext *avctx) { - ZmbvContext * const c = (ZmbvContext *)avctx->priv_data; + ZmbvContext * const c = avctx->priv_data; int zret; // Zlib return code c->avctx = avctx; @@ -622,13 +604,9 @@ static int decode_init(AVCodecContext *avctx) } c->bpp = avctx->bits_per_sample; -#ifdef CONFIG_ZLIB // Needed if zlib unused or init aborted before inflateInit memset(&(c->zstream), 0, sizeof(z_stream)); -#else - av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); - return 1; -#endif + avctx->pix_fmt = PIX_FMT_RGB24; c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64); @@ -640,7 +618,6 @@ static int decode_init(AVCodecContext *avctx) } } -#ifdef CONFIG_ZLIB c->zstream.zalloc = Z_NULL; c->zstream.zfree = Z_NULL; c->zstream.opaque = Z_NULL; @@ -649,7 +626,6 @@ static int decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); return 1; } -#endif return 0; } @@ -663,15 +639,13 @@ static int decode_init(AVCodecContext *avctx) */ static int decode_end(AVCodecContext *avctx) { - ZmbvContext * const c = (ZmbvContext *)avctx->priv_data; + ZmbvContext * const c = avctx->priv_data; av_freep(&c->decomp_buf); if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); -#ifdef CONFIG_ZLIB inflateEnd(&(c->zstream)); -#endif av_freep(&c->cur); av_freep(&c->prev); diff --git a/contrib/ffmpeg/libavcodec/zmbvenc.c b/contrib/ffmpeg/libavcodec/zmbvenc.c index a79964449..ce62ece4d 100644 --- a/contrib/ffmpeg/libavcodec/zmbvenc.c +++ b/contrib/ffmpeg/libavcodec/zmbvenc.c @@ -17,7 +17,6 @@ * 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 - * */ /** @@ -28,7 +27,6 @@ #include <stdio.h> #include <stdlib.h> -#include "common.h" #include "avcodec.h" #include <zlib.h> @@ -106,7 +104,7 @@ static int zmbv_me(ZmbvEncContext *c, uint8_t *src, int sstride, uint8_t *prev, static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) { - ZmbvEncContext * const c = (ZmbvEncContext *)avctx->priv_data; + ZmbvEncContext * const c = avctx->priv_data; AVFrame *pict = data; AVFrame * const p = &c->pic; uint8_t *src, *prev; @@ -145,9 +143,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void if(chpal){ uint8_t tpal[3]; for(i = 0; i < 256; i++){ - tpal[0] = palptr[i] >> 16; - tpal[1] = palptr[i] >> 8; - tpal[2] = palptr[i]; + AV_WB24(tpal, palptr[i]); c->work_buf[work_size++] = tpal[0] ^ c->pal[i * 3 + 0]; c->work_buf[work_size++] = tpal[1] ^ c->pal[i * 3 + 1]; c->work_buf[work_size++] = tpal[2] ^ c->pal[i * 3 + 2]; @@ -159,9 +155,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void } if(keyframe){ for(i = 0; i < 256; i++){ - c->pal[i*3 + 0] = palptr[i] >> 16; - c->pal[i*3 + 1] = palptr[i] >> 8; - c->pal[i*3 + 2] = palptr[i]; + AV_WB24(c->pal+(i*3), palptr[i]); } memcpy(c->work_buf, c->pal, 768); memcpy(c->pal2, p->data[1], 1024); @@ -239,7 +233,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void */ static int encode_init(AVCodecContext *avctx) { - ZmbvEncContext * const c = (ZmbvEncContext *)avctx->priv_data; + ZmbvEncContext * const c = avctx->priv_data; int zret; // Zlib return code int lvl = 9; @@ -305,7 +299,7 @@ static int encode_init(AVCodecContext *avctx) */ static int encode_end(AVCodecContext *avctx) { - ZmbvEncContext * const c = (ZmbvEncContext *)avctx->priv_data; + ZmbvEncContext * const c = avctx->priv_data; av_freep(&c->comp_buf); av_freep(&c->work_buf); |