diff options
Diffstat (limited to 'libavcodec')
954 files changed, 40201 insertions, 8561 deletions
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index da682dfb00..9581f94344 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -2,20 +2,20 @@ * 4XM codec * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -328,7 +328,11 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo assert(code>=0 && code<=6); if(code == 0){ - src += f->mv[bytestream2_get_byte(&f->g)]; + if (f->g.buffer_end - f->g.buffer < 1){ + av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); + return; + } + src += f->mv[ *f->g.buffer++ ]; if(start > src || src > end){ av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); return; @@ -345,15 +349,31 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo }else if(code == 3 && f->version<2){ mcdc(dst, src, log2w, h, stride, 1, 0); }else if(code == 4){ - src += f->mv[bytestream2_get_byte(&f->g)]; + if (f->g.buffer_end - f->g.buffer < 1){ + av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); + return; + } + src += f->mv[ *f->g.buffer++ ]; if(start > src || src > end){ av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); return; } + if (f->g2.buffer_end - f->g2.buffer < 1){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return; + } mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16(&f->g2)); }else if(code == 5){ + if (f->g2.buffer_end - f->g2.buffer < 1){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return; + } mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2)); }else if(code == 6){ + if (f->g2.buffer_end - f->g2.buffer < 2){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return; + } if(log2w){ dst[0] = bytestream2_get_le16(&f->g2); dst[1] = bytestream2_get_le16(&f->g2); @@ -375,6 +395,8 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ if(f->version>1){ extra=20; + if (length < extra) + return -1; bitstream_size= AV_RL32(buf+8); wordstream_size= AV_RL32(buf+12); bytestream_size= AV_RL32(buf+16); @@ -385,11 +407,10 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ 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) - ){ + if (bitstream_size > length || + bytestream_size > length - bitstream_size || + wordstream_size > length - bytestream_size - bitstream_size || + extra > length - bytestream_size - bitstream_size - wordstream_size){ av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size, bitstream_size+ bytestream_size+ wordstream_size - length); return -1; @@ -427,6 +448,11 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ static int decode_i_block(FourXContext *f, DCTELEM *block){ int code, i, j, level, val; + if(get_bits_left(&f->gb) < 2){ + av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->gb)); + return -1; + } + /* DC coef */ val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); if (val>>4){ @@ -525,7 +551,7 @@ static int decode_i_mb(FourXContext *f){ return 0; } -static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf){ +static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf, int buf_size){ int frequency[512]; uint8_t flag[512]; int up[512]; @@ -533,6 +559,7 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const int bits_tab[257]; int start, end; const uint8_t *ptr= buf; + const uint8_t *ptr_end = buf + buf_size; int j; memset(frequency, 0, sizeof(frequency)); @@ -543,6 +570,8 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const for(;;){ int i; + if (start <= end && ptr_end - ptr < end - start + 1 + 1) + return NULL; for(i=start; i<=end; i++){ frequency[i]= *ptr++; } @@ -617,6 +646,7 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ const int mbs = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4); uint16_t *dst= (uint16_t*)f->current_picture.data[0]; const int stride= f->current_picture.linesize[0]>>1; + const uint8_t *buf_end = buf + length; GetByteContext g3; if(length < mbs * 8) { @@ -628,6 +658,8 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ for(y=0; y<height; y+=16){ for(x=0; x<width; x+=16){ unsigned int color[4], bits; + if (buf_end - buf < 8) + return -1; memset(color, 0, sizeof(color)); //warning following is purely guessed ... color[0]= bytestream2_get_le16u(&g3); @@ -659,27 +691,26 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ const int width= f->avctx->width; const int height= f->avctx->height; const unsigned int bitstream_size= AV_RL32(buf); - int token_count av_unused; unsigned int prestream_size; const uint8_t *prestream; - if (length < bitstream_size + 12) { + if (bitstream_size > (1<<26) || length < bitstream_size + 12) { av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); return AVERROR_INVALIDDATA; } - token_count = AV_RL32(buf + bitstream_size + 8); prestream_size = 4 * AV_RL32(buf + bitstream_size + 4); prestream = buf + bitstream_size + 12; - if(prestream_size + bitstream_size + 12 != length - || bitstream_size > (1<<26) - || prestream_size > (1<<26)){ + if (prestream_size > (1<<26) || + prestream_size != length - (bitstream_size + 12)){ av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); return -1; } - prestream= read_huffman_tables(f, prestream); + prestream= read_huffman_tables(f, prestream, buf + length - prestream); + if (!prestream) + return -1; init_get_bits(&f->gb, buf + 4, 8*bitstream_size); @@ -720,6 +751,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p, temp; int i, frame_4cc, frame_size; + if (buf_size < 12) + return AVERROR_INVALIDDATA; 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)); @@ -732,6 +765,11 @@ static int decode_frame(AVCodecContext *avctx, const int whole_size= AV_RL32(buf+16); CFrameBuffer *cfrm; + if (data_size < 0 || whole_size < 0){ + av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n"); + return AVERROR_INVALIDDATA; + } + for(i=0; i<CFRAME_BUFFER_COUNT; i++){ if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number) av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id); @@ -748,6 +786,8 @@ static int decode_frame(AVCodecContext *avctx, } cfrm= &f->cfrm[i]; + if (data_size > UINT_MAX - cfrm->size - FF_INPUT_BUFFER_PADDING_SIZE) + return AVERROR_INVALIDDATA; cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE); if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL av_log(f->avctx, AV_LOG_ERROR, "realloc falure"); @@ -783,26 +823,27 @@ static int decode_frame(AVCodecContext *avctx, avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management - if(p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference= 1; - if(avctx->get_buffer(avctx, p) < 0){ - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + p->reference= 3; + if (avctx->reget_buffer(avctx, p) < 0) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } if(frame_4cc == AV_RL32("ifr2")){ p->pict_type= AV_PICTURE_TYPE_I; - if(decode_i2_frame(f, buf-4, frame_size + 4) < 0) + if(decode_i2_frame(f, buf-4, frame_size + 4) < 0) { + av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n"); return -1; + } }else if(frame_4cc == AV_RL32("ifrm")){ p->pict_type= AV_PICTURE_TYPE_I; - if(decode_i_frame(f, buf, frame_size) < 0) + if(decode_i_frame(f, buf, frame_size) < 0){ + av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n"); return -1; + } }else if(frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")){ if(!f->last_picture.data[0]){ - f->last_picture.reference= 1; + f->last_picture.reference= 3; if(avctx->get_buffer(avctx, &f->last_picture) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; @@ -810,8 +851,10 @@ static int decode_frame(AVCodecContext *avctx, } p->pict_type= AV_PICTURE_TYPE_P; - if(decode_p_frame(f, buf, frame_size) < 0) + if(decode_p_frame(f, buf, frame_size) < 0){ + av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n"); return -1; + } }else if(frame_4cc == AV_RL32("snd_")){ av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size); }else{ @@ -844,7 +887,13 @@ static av_cold int decode_init(AVCodecContext *avctx){ av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n"); return 1; } + if((avctx->width % 16) || (avctx->height % 16)) { + av_log(avctx, AV_LOG_ERROR, "unsupported width/height\n"); + return AVERROR_INVALIDDATA; + } + avcodec_get_frame_defaults(&f->current_picture); + avcodec_get_frame_defaults(&f->last_picture); f->version= AV_RL32(avctx->extradata)>>16; common_init(avctx); init_vlcs(f); diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c index e1c03f9b96..7951bd8db0 100644 --- a/libavcodec/8bps.c +++ b/libavcodec/8bps.c @@ -2,20 +2,20 @@ * Quicktime Planar RGB (8BPS) Video Decoder * Copyright (C) 2003 Roberto Togni * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +27,7 @@ * * Supports: PAL8 (RGB 8bpp, paletted) * : BGR24 (RGB 24bpp) (can also output it as RGB32) - * : RGB32 (RGB 32bpp, 4th plane is probably alpha and it's ignored) + * : RGB32 (RGB 32bpp, 4th plane is alpha) * */ @@ -72,7 +72,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, unsigned int dlen, p, row; const unsigned char *lp, *dp; unsigned char count; - unsigned int px_inc; unsigned int planes = c->planes; unsigned char *planemap = c->planemap; @@ -89,12 +88,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, /* Set data pointer after line lengths */ dp = encoded + planes * (height << 1); - /* Ignore alpha plane, don't know what to do with it */ - if (planes == 4) - planes--; - - px_inc = planes + (avctx->pix_fmt == PIX_FMT_RGB32); - for (p = 0; p < planes; p++) { /* Lines length pointer for this plane */ lp = encoded + p * (height << 1); @@ -111,21 +104,21 @@ static int decode_frame(AVCodecContext *avctx, void *data, if ((count = *dp++) <= 127) { count++; dlen -= count + 1; - if (pixptr + count * px_inc > pixptr_end) + if (pixptr + count * planes > pixptr_end) break; if (dp + count > buf + buf_size) return -1; while (count--) { *pixptr = *dp++; - pixptr += px_inc; + pixptr += planes; } } else { count = 257 - count; - if (pixptr + count * px_inc > pixptr_end) + if (pixptr + count * planes > pixptr_end) break; while (count--) { *pixptr = *dp; - pixptr += px_inc; + pixptr += planes; } dp++; dlen -= 2; @@ -166,6 +159,7 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; c->pic.data[0] = NULL; + avcodec_get_frame_defaults(&c->pic); switch (avctx->bits_per_coded_sample) { case 8: avctx->pix_fmt = PIX_FMT_PAL8; @@ -186,12 +180,12 @@ static av_cold int decode_init(AVCodecContext *avctx) c->planemap[0] = 1; // 1st plane is red c->planemap[1] = 2; // 2nd plane is green c->planemap[2] = 3; // 3rd plane is blue - c->planemap[3] = 0; // 4th plane is alpha??? + c->planemap[3] = 0; // 4th plane is alpha #else c->planemap[0] = 2; // 1st plane is red c->planemap[1] = 1; // 2nd plane is green c->planemap[2] = 0; // 3rd plane is blue - c->planemap[3] = 3; // 4th plane is alpha??? + c->planemap[3] = 3; // 4th plane is alpha #endif break; default: diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c index 4f11b8bec4..f42a35b20b 100644 --- a/libavcodec/8svx.c +++ b/libavcodec/8svx.c @@ -1,21 +1,21 @@ /* - * 8SVX audio decoder * Copyright (C) 2008 Jaikrishnan Menon + * Copyright (C) 2011 Stefano Sabatini * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +26,15 @@ * * supports: fibonacci delta encoding * : exponential encoding + * + * For more information about the 8SVX format: + * http://netghost.narod.ru/gff/vendspec/iff/iff.txt + * http://sox.sourceforge.net/AudioFormats-11.html + * http://aminet.net/package/mus/misc/wavepak + * http://amigan.1emu.net/reg/8SVX.txt + * + * Samples can be found here: + * http://aminet.net/mods/smpl/ */ #include "avcodec.h" @@ -33,54 +42,62 @@ /** decoder context */ typedef struct EightSvxContext { AVFrame frame; - uint8_t fib_acc[2]; const int8_t *table; - /* buffer used to store the whole first packet. - data is only sent as one large packet */ - uint8_t *data[2]; - int data_size; - int data_idx; + /* buffer used to store the whole audio decoded/interleaved chunk, + * which is sent with the first packet */ + uint8_t *samples; + size_t samples_size; + int samples_idx; } EightSvxContext; -static const int8_t fibonacci[16] = { -34, -21, -13, -8, -5, -3, -2, -1, - 0, 1, 2, 3, 5, 8, 13, 21 }; -static const int8_t exponential[16] = { -128, -64, -32, -16, -8, -4, -2, -1, - 0, 1, 2, 4, 8, 16, 32, 64 }; +static const int8_t fibonacci[16] = { -34, -21, -13, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 13, 21 }; +static const int8_t exponential[16] = { -128, -64, -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32, 64 }; -#define MAX_FRAME_SIZE 32768 +#define MAX_FRAME_SIZE 2048 /** - * Delta decode the compressed values in src, and put the resulting - * decoded samples in dst. + * Interleave samples in buffer containing all left channel samples + * at the beginning, and right channel samples at the end. + * Each sample is assumed to be in signed 8-bit format. * - * @param[in,out] state starting value. it is saved for use in the next call. + * @param size the size in bytes of the dst and src buffer */ -static void delta_decode(uint8_t *dst, const uint8_t *src, int src_size, - uint8_t *state, const int8_t *table, int channels) +static void interleave_stereo(uint8_t *dst, const uint8_t *src, int size) { - uint8_t val = *state; + uint8_t *dst_end = dst + size; + size = size>>1; - while (src_size--) { - uint8_t d = *src++; - val = av_clip_uint8(val + table[d & 0xF]); - *dst = val; - dst += channels; - val = av_clip_uint8(val + table[d >> 4]); - *dst = val; - dst += channels; + while (dst < dst_end) { + *dst++ = *src; + *dst++ = *(src+size); + src++; } - - *state = val; } -static void raw_decode(uint8_t *dst, const int8_t *src, int src_size, - int channels) +/** + * Delta decode the compressed values in src, and put the resulting + * decoded n samples in dst. + * + * @param val starting value assumed by the delta sequence + * @param table delta sequence table + * @return size in bytes of the decoded data, must be src_size*2 + */ +static int delta_decode(int8_t *dst, const uint8_t *src, int src_size, + int8_t val, const int8_t *table) { - while (src_size--) { - *dst = *src++ + 128; - dst += channels; + int n = src_size; + int8_t *dst0 = dst; + + while (n--) { + uint8_t d = *src++; + val = av_clip(val + table[d & 0x0f], -127, 128); + *dst++ = val; + val = av_clip(val + table[d >> 4] , -127, 128); + *dst++ = val; } + + return dst-dst0; } /** decode a frame */ @@ -88,108 +105,89 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { EightSvxContext *esc = avctx->priv_data; - int buf_size; - uint8_t *out_data; - int ret; - int is_compr = (avctx->codec_id != CODEC_ID_PCM_S8_PLANAR); - - /* for the first packet, copy data to buffer */ - if (avpkt->data) { - int hdr_size = is_compr ? 2 : 0; - int chan_size = (avpkt->size - hdr_size * avctx->channels) / avctx->channels; - - if (avpkt->size < hdr_size * avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "packet size is too small\n"); - return AVERROR(EINVAL); - } - if (esc->data[0]) { - av_log(avctx, AV_LOG_ERROR, "unexpected data after first packet\n"); - return AVERROR(EINVAL); - } + int n, out_data_size, ret; + uint8_t *src, *dst; - if (is_compr) { - esc->fib_acc[0] = avpkt->data[1] + 128; - if (avctx->channels == 2) - esc->fib_acc[1] = avpkt->data[2+chan_size+1] + 128; - } + /* decode and interleave the first packet */ + if (!esc->samples && avpkt) { + uint8_t *deinterleaved_samples, *p = NULL; - esc->data_idx = 0; - esc->data_size = chan_size; - if (!(esc->data[0] = av_malloc(chan_size))) + esc->samples_size = avctx->codec->id == CODEC_ID_8SVX_RAW || avctx->codec->id ==CODEC_ID_PCM_S8_PLANAR? + avpkt->size : avctx->channels + (avpkt->size-avctx->channels) * 2; + if (!(esc->samples = av_malloc(esc->samples_size))) return AVERROR(ENOMEM); - if (avctx->channels == 2) { - if (!(esc->data[1] = av_malloc(chan_size))) { - av_freep(&esc->data[0]); - return AVERROR(ENOMEM); + + /* decompress */ + if (avctx->codec->id == CODEC_ID_8SVX_FIB || avctx->codec->id == CODEC_ID_8SVX_EXP) { + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int n = esc->samples_size; + + if (buf_size < 2) { + av_log(avctx, AV_LOG_ERROR, "packet size is too small\n"); + return AVERROR(EINVAL); } + if (!(deinterleaved_samples = av_mallocz(n))) + return AVERROR(ENOMEM); + p = deinterleaved_samples; + + /* the uncompressed starting value is contained in the first byte */ + if (avctx->channels == 2) { + delta_decode(deinterleaved_samples , buf+1, buf_size/2-1, buf[0], esc->table); + buf += buf_size/2; + delta_decode(deinterleaved_samples+n/2-1, buf+1, buf_size/2-1, buf[0], esc->table); + } else + delta_decode(deinterleaved_samples , buf+1, buf_size-1 , buf[0], esc->table); + } else { + deinterleaved_samples = avpkt->data; } - memcpy(esc->data[0], &avpkt->data[hdr_size], chan_size); - if (avctx->channels == 2) - memcpy(esc->data[1], &avpkt->data[2*hdr_size+chan_size], chan_size); - } - if (!esc->data[0]) { - av_log(avctx, AV_LOG_ERROR, "unexpected empty packet\n"); - return AVERROR(EINVAL); - } - /* decode next piece of data from the buffer */ - buf_size = FFMIN(MAX_FRAME_SIZE, esc->data_size - esc->data_idx); - if (buf_size <= 0) { - *got_frame_ptr = 0; - return avpkt->size; + if (avctx->channels == 2) + interleave_stereo(esc->samples, deinterleaved_samples, esc->samples_size); + else + memcpy(esc->samples, deinterleaved_samples, esc->samples_size); + av_freep(&p); } /* get output buffer */ - esc->frame.nb_samples = buf_size * (is_compr + 1); + esc->frame.nb_samples = (FFMIN(MAX_FRAME_SIZE, esc->samples_size - esc->samples_idx) +avctx->channels-1) / avctx->channels; if ((ret = avctx->get_buffer(avctx, &esc->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - out_data = esc->frame.data[0]; - - if (is_compr) { - delta_decode(out_data, &esc->data[0][esc->data_idx], buf_size, - &esc->fib_acc[0], esc->table, avctx->channels); - if (avctx->channels == 2) { - delta_decode(&out_data[1], &esc->data[1][esc->data_idx], buf_size, - &esc->fib_acc[1], esc->table, avctx->channels); - } - } else { - int ch; - for (ch = 0; ch < avctx->channels; ch++) { - raw_decode((int8_t *)&out_data[ch], &esc->data[ch][esc->data_idx], - buf_size, avctx->channels); - } - } - esc->data_idx += buf_size; *got_frame_ptr = 1; *(AVFrame *)data = esc->frame; - return avpkt->size; + dst = esc->frame.data[0]; + src = esc->samples + esc->samples_idx; + out_data_size = esc->frame.nb_samples * avctx->channels; + for (n = out_data_size; n > 0; n--) + *dst++ = *src++ + 128; + esc->samples_idx += out_data_size; + + return avctx->codec->id == CODEC_ID_8SVX_FIB || avctx->codec->id == CODEC_ID_8SVX_EXP ? + (avctx->frame_number == 0)*2 + out_data_size / 2 : + out_data_size; } -/** initialize 8svx decoder */ static av_cold int eightsvx_decode_init(AVCodecContext *avctx) { EightSvxContext *esc = avctx->priv_data; if (avctx->channels < 1 || avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "8SVX does not support more than 2 channels\n"); - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; } - switch(avctx->codec->id) { - case CODEC_ID_8SVX_FIB: - esc->table = fibonacci; - break; - case CODEC_ID_8SVX_EXP: - esc->table = exponential; - break; - case CODEC_ID_PCM_S8_PLANAR: - break; - default: - return -1; + switch (avctx->codec->id) { + case CODEC_ID_8SVX_FIB: esc->table = fibonacci; break; + case CODEC_ID_8SVX_EXP: esc->table = exponential; break; + case CODEC_ID_PCM_S8_PLANAR: + case CODEC_ID_8SVX_RAW: esc->table = NULL; break; + default: + av_log(avctx, AV_LOG_ERROR, "Invalid codec id %d.\n", avctx->codec->id); + return AVERROR_INVALIDDATA; } avctx->sample_fmt = AV_SAMPLE_FMT_U8; @@ -203,8 +201,9 @@ static av_cold int eightsvx_decode_close(AVCodecContext *avctx) { EightSvxContext *esc = avctx->priv_data; - av_freep(&esc->data[0]); - av_freep(&esc->data[1]); + av_freep(&esc->samples); + esc->samples_size = 0; + esc->samples_idx = 0; return 0; } @@ -215,9 +214,9 @@ AVCodec ff_eightsvx_fib_decoder = { .id = CODEC_ID_8SVX_FIB, .priv_data_size = sizeof (EightSvxContext), .init = eightsvx_decode_init, - .close = eightsvx_decode_close, .decode = eightsvx_decode_frame, - .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1, + .close = eightsvx_decode_close, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"), }; @@ -227,9 +226,9 @@ AVCodec ff_eightsvx_exp_decoder = { .id = CODEC_ID_8SVX_EXP, .priv_data_size = sizeof (EightSvxContext), .init = eightsvx_decode_init, - .close = eightsvx_decode_close, .decode = eightsvx_decode_frame, - .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1, + .close = eightsvx_decode_close, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"), }; @@ -241,6 +240,6 @@ AVCodec ff_pcm_s8_planar_decoder = { .init = eightsvx_decode_init, .close = eightsvx_decode_close, .decode = eightsvx_decode_frame, - .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("PCM signed 8-bit planar"), }; diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 6c9673f13d..7ff6975da1 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1,3 +1,5 @@ +include $(SUBDIR)../config.mak + NAME = avcodec FFLIBS = avutil @@ -16,6 +18,7 @@ OBJS = allcodecs.o \ options.o \ parser.o \ raw.o \ + rawdec.o \ resample.o \ resample2.o \ simple_idct.o \ @@ -24,6 +27,7 @@ OBJS = allcodecs.o \ # parts needed for many different codecs OBJS-$(CONFIG_AANDCT) += aandcttab.o OBJS-$(CONFIG_AC3DSP) += ac3dsp.o +OBJS-$(CONFIG_CRYSTALHD) += crystalhd.o OBJS-$(CONFIG_ENCODERS) += faandct.o jfdctfst.o jfdctint.o OBJS-$(CONFIG_DCT) += dct.o dct32_fixed.o dct32_float.o OBJS-$(CONFIG_DWT) += dwt.o @@ -78,7 +82,7 @@ OBJS-$(CONFIG_AMV_DECODER) += sp5xdec.o mjpegdec.o mjpeg.o OBJS-$(CONFIG_ANM_DECODER) += anm.o OBJS-$(CONFIG_ANSI_DECODER) += ansi.o cga_data.o OBJS-$(CONFIG_APE_DECODER) += apedec.o -OBJS-$(CONFIG_ASS_DECODER) += assdec.o ass.o +OBJS-$(CONFIG_ASS_DECODER) += assdec.o ass.o ass_split.o OBJS-$(CONFIG_ASS_ENCODER) += assenc.o ass.o OBJS-$(CONFIG_ASV1_DECODER) += asv1.o mpeg12data.o OBJS-$(CONFIG_ASV1_ENCODER) += asv1.o mpeg12data.o @@ -88,12 +92,17 @@ OBJS-$(CONFIG_ATRAC1_DECODER) += atrac1.o atrac.o OBJS-$(CONFIG_ATRAC3_DECODER) += atrac3.o atrac.o OBJS-$(CONFIG_AURA_DECODER) += cyuv.o OBJS-$(CONFIG_AURA2_DECODER) += aura.o +OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o +OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o OBJS-$(CONFIG_AVS_DECODER) += avs.o +OBJS-$(CONFIG_AYUV_DECODER) += v408dec.o +OBJS-$(CONFIG_AYUV_ENCODER) += v408enc.o OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o OBJS-$(CONFIG_BFI_DECODER) += bfi.o OBJS-$(CONFIG_BINK_DECODER) += bink.o binkdsp.o OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o wma.o OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o wma.o +OBJS-$(CONFIG_BINTEXT_DECODER) += bintext.o cga_data.o OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o OBJS-$(CONFIG_BMP_ENCODER) += bmpenc.o OBJS-$(CONFIG_BMV_VIDEO_DECODER) += bmv.o @@ -109,6 +118,9 @@ OBJS-$(CONFIG_COOK_DECODER) += cook.o OBJS-$(CONFIG_CSCD_DECODER) += cscd.o OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o OBJS-$(CONFIG_DCA_DECODER) += dca.o synth_filter.o dcadsp.o +OBJS-$(CONFIG_DCA_ENCODER) += dcaenc.o +OBJS-$(CONFIG_DIRAC_DECODER) += diracdec.o dirac.o diracdsp.o \ + dirac_arith.o mpeg12data.o dwt.o OBJS-$(CONFIG_DFA_DECODER) += dfa.o OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o \ @@ -142,20 +154,28 @@ OBJS-$(CONFIG_EATQI_DECODER) += eatqi.o eaidct.o mpeg12.o \ OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o OBJS-$(CONFIG_EIGHTSVX_EXP_DECODER) += 8svx.o OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER) += 8svx.o +OBJS-$(CONFIG_EIGHTSVX_RAW_DECODER) += 8svx.o OBJS-$(CONFIG_ESCAPE124_DECODER) += escape124.o +OBJS-$(CONFIG_ESCAPE130_DECODER) += escape130.o OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o rangecoder.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) += flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o +OBJS-$(CONFIG_FFWAVESYNTH_DECODER) += ffwavesynth.o +OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o vorbis_data.o +OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o vorbis_data.o OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o +OBJS-$(CONFIG_FLASHSV2_ENCODER) += flashsv2enc.o OBJS-$(CONFIG_FLASHSV2_DECODER) += flashsv.o OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o OBJS-$(CONFIG_FRWU_DECODER) += frwu.o +OBJS-$(CONFIG_G723_1_DECODER) += g723_1.o acelp_vectors.o \ + celp_filters.o celp_math.o +OBJS-$(CONFIG_G723_1_ENCODER) += g723_1.o +OBJS-$(CONFIG_G729_DECODER) += g729dec.o lsp.o celp_math.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o OBJS-$(CONFIG_GIF_DECODER) += gifdec.o lzw.o OBJS-$(CONFIG_GIF_ENCODER) += gif.o lzwenc.o OBJS-$(CONFIG_GSM_DECODER) += gsmdec.o gsmdec_data.o msgsmdec.o @@ -187,6 +207,7 @@ OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o +OBJS-$(CONFIG_IDF_DECODER) += bintext.o cga_data.o OBJS-$(CONFIG_IFF_BYTERUN1_DECODER) += iff.o OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o OBJS-$(CONFIG_IMC_DECODER) += imc.o @@ -196,6 +217,8 @@ OBJS-$(CONFIG_INDEO4_DECODER) += indeo4.o ivi_common.o ivi_dsp.o OBJS-$(CONFIG_INDEO5_DECODER) += indeo5.o ivi_common.o ivi_dsp.o OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER) += dpcm.o OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o +OBJS-$(CONFIG_JPEG2000_DECODER) += j2kdec.o mqcdec.o mqc.o j2k.o j2k_dwt.o +OBJS-$(CONFIG_JPEG2000_ENCODER) += j2kenc.o mqcenc.o mqc.o j2k.o j2k_dwt.o OBJS-$(CONFIG_JPEGLS_DECODER) += jpeglsdec.o jpegls.o \ mjpegdec.o mjpeg.o OBJS-$(CONFIG_JPEGLS_ENCODER) += jpeglsenc.o jpegls.o @@ -252,10 +275,13 @@ OBJS-$(CONFIG_MPC7_DECODER) += mpc7.o mpc.o mpegaudiodec.o \ OBJS-$(CONFIG_MPC8_DECODER) += mpc8.o mpc.o mpegaudiodec.o \ mpegaudiodecheader.o mpegaudio.o \ mpegaudiodata.o +OBJS-$(CONFIG_MPEGVIDEO_DECODER) += mpeg12.o mpeg12data.o \ + mpegvideo.o error_resilience.o OBJS-$(CONFIG_MPEG_XVMC_DECODER) += mpegvideo_xvmc.o OBJS-$(CONFIG_MPEG1VIDEO_DECODER) += mpeg12.o mpeg12data.o \ mpegvideo.o error_resilience.o OBJS-$(CONFIG_MPEG1VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ + timecode.o \ motion_est.o ratecontrol.o \ mpeg12.o mpeg12data.o \ mpegvideo.o error_resilience.o @@ -264,6 +290,7 @@ OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o OBJS-$(CONFIG_MPEG2VIDEO_DECODER) += mpeg12.o mpeg12data.o \ mpegvideo.o error_resilience.o OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ + timecode.o \ motion_est.o ratecontrol.o \ mpeg12.o mpeg12data.o \ mpegvideo.o error_resilience.o @@ -279,6 +306,7 @@ OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ h263.o ituh263dec.o mpeg4videodec.o OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o +OBJS-$(CONFIG_MSVIDEO1_ENCODER) += msvideo1enc.o elbg.o OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o OBJS-$(CONFIG_MXPEG_DECODER) += mxpegdec.o mjpegdec.o mjpeg.o OBJS-$(CONFIG_NELLYMOSER_DECODER) += nellymoserdec.o nellymoser.o @@ -300,7 +328,9 @@ OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o pngdsp.o OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o -OBJS-$(CONFIG_PRORES_DECODER) += proresdec.o proresdsp.o +OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o +OBJS-$(CONFIG_PRORES_LGPL_DECODER) += proresdec_lgpl.o proresdsp.o +OBJS-$(CONFIG_PRORES_ENCODER) += proresenc.o OBJS-$(CONFIG_PTX_DECODER) += ptx.o OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o celp_math.o \ celp_filters.o acelp_vectors.o \ @@ -313,7 +343,9 @@ OBJS-$(CONFIG_QPEG_DECODER) += qpeg.o OBJS-$(CONFIG_QTRLE_DECODER) += qtrle.o OBJS-$(CONFIG_QTRLE_ENCODER) += qtrleenc.o OBJS-$(CONFIG_R10K_DECODER) += r210dec.o +OBJS-$(CONFIG_R10K_ENCODER) += r210enc.o OBJS-$(CONFIG_R210_DECODER) += r210dec.o +OBJS-$(CONFIG_R210_ENCODER) += r210enc.o OBJS-$(CONFIG_RA_144_DECODER) += ra144dec.o ra144.o celp_filters.o OBJS-$(CONFIG_RA_144_ENCODER) += ra144enc.o ra144.o celp_filters.o OBJS-$(CONFIG_RA_288_DECODER) += ra288.o celp_math.o celp_filters.o @@ -351,8 +383,12 @@ OBJS-$(CONFIG_SNOW_ENCODER) += snowenc.o snow.o rangecoder.o \ error_resilience.o ituh263enc.o \ mpegvideo_enc.o mpeg12data.o OBJS-$(CONFIG_SOL_DPCM_DECODER) += dpcm.o +OBJS-$(CONFIG_SONIC_DECODER) += sonic.o +OBJS-$(CONFIG_SONIC_ENCODER) += sonic.o +OBJS-$(CONFIG_SONIC_LS_ENCODER) += sonic.o OBJS-$(CONFIG_SP5X_DECODER) += sp5xdec.o mjpegdec.o mjpeg.o OBJS-$(CONFIG_SRT_DECODER) += srtdec.o ass.o +OBJS-$(CONFIG_SRT_ENCODER) += srtenc.o ass_split.o OBJS-$(CONFIG_SUNRAST_DECODER) += sunrast.o OBJS-$(CONFIG_SVQ1_DECODER) += svq1dec.o svq1.o h263.o \ mpegvideo.o error_resilience.o @@ -386,6 +422,10 @@ OBJS-$(CONFIG_ULTI_DECODER) += ulti.o OBJS-$(CONFIG_UTVIDEO_DECODER) += utvideo.o OBJS-$(CONFIG_V210_DECODER) += v210dec.o OBJS-$(CONFIG_V210_ENCODER) += v210enc.o +OBJS-$(CONFIG_V308_DECODER) += v308dec.o +OBJS-$(CONFIG_V308_ENCODER) += v308enc.o +OBJS-$(CONFIG_V408_DECODER) += v408dec.o +OBJS-$(CONFIG_V408_ENCODER) += v408enc.o OBJS-$(CONFIG_V410_DECODER) += v410dec.o OBJS-$(CONFIG_V410_ENCODER) += v410enc.o OBJS-$(CONFIG_V210X_DECODER) += v210x.o @@ -413,6 +453,7 @@ OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o vp56dsp.o \ OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp8dsp.o vp56rac.o OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o +OBJS-$(CONFIG_WMALOSSLESS_DECODER) += wmalosslessdec.o wma.o OBJS-$(CONFIG_WMAPRO_DECODER) += wmaprodec.o wma.o OBJS-$(CONFIG_WMAV1_DECODER) += wmadec.o wma.o aactab.o OBJS-$(CONFIG_WMAV1_ENCODER) += wmaenc.o wma.o aactab.o @@ -433,12 +474,17 @@ 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) += xxan.o +OBJS-$(CONFIG_XBIN_DECODER) += bintext.o cga_data.o OBJS-$(CONFIG_XL_DECODER) += xl.o OBJS-$(CONFIG_XSUB_DECODER) += xsubdec.o OBJS-$(CONFIG_XSUB_ENCODER) += xsubenc.o OBJS-$(CONFIG_XWD_DECODER) += xwddec.o OBJS-$(CONFIG_XWD_ENCODER) += xwdenc.o +OBJS-$(CONFIG_Y41P_DECODER) += y41pdec.o +OBJS-$(CONFIG_Y41P_ENCODER) += y41penc.o OBJS-$(CONFIG_YOP_DECODER) += yop.o +OBJS-$(CONFIG_YUV4_DECODER) += yuv4dec.o +OBJS-$(CONFIG_YUV4_ENCODER) += yuv4enc.o OBJS-$(CONFIG_ZLIB_DECODER) += lcldec.o OBJS-$(CONFIG_ZLIB_ENCODER) += lclenc.o OBJS-$(CONFIG_ZMBV_DECODER) += zmbv.o @@ -539,36 +585,40 @@ OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o OBJS-$(CONFIG_ADX_DEMUXER) += adx.o OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_DV_DEMUXER) += dvdata.o -OBJS-$(CONFIG_DV_MUXER) += dvdata.o -OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o flacdata.o flac.o -OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o flacdata.o flac.o +OBJS-$(CONFIG_DV_MUXER) += dvdata.o timecode.o +OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o flacdata.o flac.o vorbis_data.o +OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o flacdata.o flac.o vorbis_data.o OBJS-$(CONFIG_FLV_DEMUXER) += mpeg4audio.o OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o OBJS-$(CONFIG_IFF_DEMUXER) += iff.o OBJS-$(CONFIG_LATM_MUXER) += mpeg4audio.o -OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o \ +OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o vorbis_data.o \ flacdec.o flacdata.o flac.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_MATROSKA_MUXER) += xiph.o mpeg4audio.o \ flacdec.o flacdata.o flac.o \ - mpegaudiodata.o + mpegaudiodata.o vorbis_data.o OBJS-$(CONFIG_MP3_MUXER) += mpegaudiodata.o mpegaudiodecheader.o -OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o +OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o timecode.o OBJS-$(CONFIG_MOV_MUXER) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_MPEGTS_MUXER) += mpegvideo.o mpeg4audio.o OBJS-$(CONFIG_MPEGTS_DEMUXER) += mpeg4audio.o mpegaudiodata.o +OBJS-$(CONFIG_MXF_MUXER) += timecode.o OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o OBJS-$(CONFIG_OGG_DEMUXER) += flacdec.o flacdata.o flac.o \ - dirac.o mpeg12data.o -OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o flacdata.o flac.o + dirac.o mpeg12data.o vorbis_data.o +OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o flacdata.o flac.o \ + vorbis_data.o OBJS-$(CONFIG_RTP_MUXER) += mpeg4audio.o mpegvideo.o xiph.o OBJS-$(CONFIG_SPDIF_DEMUXER) += aacadtsdec.o mpeg4audio.o OBJS-$(CONFIG_WEBM_MUXER) += xiph.o mpeg4audio.o \ flacdec.o flacdata.o flac.o \ - mpegaudiodata.o + mpegaudiodata.o vorbis_data.o OBJS-$(CONFIG_WTV_DEMUXER) += mpeg4audio.o mpegaudiodata.o # external codec libraries +OBJS-$(CONFIG_LIBAACPLUS_ENCODER) += libaacplus.o +OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o OBJS-$(CONFIG_LIBDIRAC_DECODER) += libdiracdec.o OBJS-$(CONFIG_LIBDIRAC_ENCODER) += libdiracenc.o libdirac_libschro.o OBJS-$(CONFIG_LIBFAAC_ENCODER) += libfaac.o @@ -580,7 +630,8 @@ OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER) += libopencore-amr.o -OBJS-$(CONFIG_LIBOPENJPEG_DECODER) += libopenjpeg.o +OBJS-$(CONFIG_LIBOPENJPEG_DECODER) += libopenjpegdec.o +OBJS-$(CONFIG_LIBOPENJPEG_ENCODER) += libopenjpegenc.o OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o \ libschroedinger.o \ libdirac_libschro.o @@ -589,7 +640,9 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \ libdirac_libschro.o OBJS-$(CONFIG_LIBSPEEX_DECODER) += libspeexdec.o OBJS-$(CONFIG_LIBSPEEX_ENCODER) += libspeexenc.o +OBJS-$(CONFIG_LIBSTAGEFRIGHT_H264_DECODER)+= libstagefright.o OBJS-$(CONFIG_LIBTHEORA_ENCODER) += libtheoraenc.o +OBJS-$(CONFIG_LIBUTVIDEO_DECODER) += libutvideo.o OBJS-$(CONFIG_LIBVO_AACENC_ENCODER) += libvo-aacenc.o mpeg4audio.o OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER) += libvo-amrwbenc.o OBJS-$(CONFIG_LIBVORBIS_ENCODER) += libvorbis.o vorbis_data.o @@ -611,7 +664,8 @@ OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o OBJS-$(CONFIG_DNXHD_PARSER) += dnxhd_parser.o OBJS-$(CONFIG_DVBSUB_PARSER) += dvbsub_parser.o OBJS-$(CONFIG_DVDSUB_PARSER) += dvdsub_parser.o -OBJS-$(CONFIG_FLAC_PARSER) += flac_parser.o flacdata.o flac.o +OBJS-$(CONFIG_FLAC_PARSER) += flac_parser.o flacdata.o flac.o \ + vorbis_data.o OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o OBJS-$(CONFIG_H261_PARSER) += h261_parser.o OBJS-$(CONFIG_H263_PARSER) += h263_parser.o @@ -662,6 +716,7 @@ OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o # thread libraries OBJS-$(HAVE_PTHREADS) += pthread.o OBJS-$(HAVE_W32THREADS) += pthread.o +OBJS-$(HAVE_OS2THREADS) += pthread.o # inverse.o contains the ff_inverse table definition, which is used by # the FASTDIV macro (from libavutil); since referencing the external @@ -679,14 +734,12 @@ SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h SKIPHEADERS-$(CONFIG_LIBDIRAC) += libdirac.h SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_internal.h -SKIPHEADERS-$(CONFIG_VDA) += vda.h vda_internal.h +SKIPHEADERS-$(CONFIG_VDA) += vda_internal.h SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h SKIPHEADERS-$(CONFIG_XVMC) += xvmc.h SKIPHEADERS-$(HAVE_W32THREADS) += w32pthreads.h -EXAMPLES = api - -TESTPROGS = cabac dct fft fft-fixed golomb iirfilter rangecoder +TESTPROGS = cabac dct fft fft-fixed golomb iirfilter rangecoder snowenc TESTPROGS-$(HAVE_MMX) += motion TESTOBJS = dctref.o @@ -732,3 +785,10 @@ $(SUBDIR)motionpixels.o: $(SUBDIR)motionpixels_tables.h $(SUBDIR)pcm.o: $(SUBDIR)pcm_tables.h $(SUBDIR)qdm2.o: $(SUBDIR)qdm2_tables.h endif + +CODEC_NAMES_SH := $(SRC_PATH)/$(SUBDIR)codec_names.sh +AVCODEC_H := $(SRC_PATH)/$(SUBDIR)avcodec.h +$(SUBDIR)codec_names.h: $(CODEC_NAMES_SH) config.h $(AVCODEC_H) + $(CC) $(CPPFLAGS) $(CFLAGS) -E $(AVCODEC_H) | \ + $(CODEC_NAMES_SH) config.h $@ +$(SUBDIR)utils.o: $(SUBDIR)codec_names.h diff --git a/libavcodec/a64colors.h b/libavcodec/a64colors.h index d977426fc0..a9cdb6fa76 100644 --- a/libavcodec/a64colors.h +++ b/libavcodec/a64colors.h @@ -2,20 +2,20 @@ * a64 video encoder - c64 colors in rgb (Pepto) * Copyright (c) 2009 Tobias Bindhammer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/a64enc.h b/libavcodec/a64enc.h index b64b952fe4..fb559ba82b 100644 --- a/libavcodec/a64enc.h +++ b/libavcodec/a64enc.h @@ -2,20 +2,20 @@ * a64 video encoder - basic headers * Copyright (c) 2009 Tobias Bindhammer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index 532f2a2824..5a665d0592 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -2,20 +2,20 @@ * a64 video encoder - multicolor modes * Copyright (c) 2009 Tobias Bindhammer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/a64tables.h b/libavcodec/a64tables.h index b95c5ce754..a955ef4caa 100644 --- a/libavcodec/a64tables.h +++ b/libavcodec/a64tables.h @@ -2,20 +2,20 @@ * a64 video encoder - tables used by a64 encoders * Copyright (c) 2009 Tobias Bindhammer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aac.h b/libavcodec/aac.h index a36080cb6f..6fdeedea21 100644 --- a/libavcodec/aac.h +++ b/libavcodec/aac.h @@ -3,20 +3,20 @@ * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -301,6 +301,7 @@ typedef struct { DECLARE_ALIGNED(32, float, temp)[128]; enum OCStatus output_configured; + int warned_num_aac_frames; } AACContext; #endif /* AVCODEC_AAC_H */ diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c index 58f30a4180..6f6ed895f0 100644 --- a/libavcodec/aac_ac3_parser.c +++ b/libavcodec/aac_ac3_parser.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h index a14fce5190..b1fb0cf59f 100644 --- a/libavcodec/aac_ac3_parser.h +++ b/libavcodec/aac_ac3_parser.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aac_adtstoasc_bsf.c b/libavcodec/aac_adtstoasc_bsf.c index 55181bbf55..3cb065ed5e 100644 --- a/libavcodec/aac_adtstoasc_bsf.c +++ b/libavcodec/aac_adtstoasc_bsf.c @@ -2,20 +2,20 @@ * MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter * Copyright (c) 2009 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aac_parser.c b/libavcodec/aac_parser.c index f0914e60c0..a8ef2f35dd 100644 --- a/libavcodec/aac_parser.c +++ b/libavcodec/aac_parser.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aac_tablegen.c b/libavcodec/aac_tablegen.c index b2c6c954e0..33a179f51e 100644 --- a/libavcodec/aac_tablegen.c +++ b/libavcodec/aac_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aac_tablegen.h b/libavcodec/aac_tablegen.h index 8773d9b975..7afa466139 100644 --- a/libavcodec/aac_tablegen.h +++ b/libavcodec/aac_tablegen.h @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aac_tablegen_decl.h b/libavcodec/aac_tablegen_decl.h index 496ca0c677..0d86e80bc2 100644 --- a/libavcodec/aac_tablegen_decl.h +++ b/libavcodec/aac_tablegen_decl.h @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacadtsdec.c b/libavcodec/aacadtsdec.c index 30f92e0b10..c9718c4599 100644 --- a/libavcodec/aacadtsdec.c +++ b/libavcodec/aacadtsdec.c @@ -4,20 +4,20 @@ * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2009 Alex Converse * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacadtsdec.h b/libavcodec/aacadtsdec.h index 60fdd221a2..fb2cbd9b35 100644 --- a/libavcodec/aacadtsdec.h +++ b/libavcodec/aacadtsdec.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index 72be2a272b..8738460b81 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -2,20 +2,20 @@ * AAC coefficients encoder * Copyright (C) 2008-2009 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1113,7 +1113,7 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe, } } -AACCoefficientsEncoder ff_aac_coders[] = { +AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { { search_for_quantizers_faac, encode_window_bands_info, diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index b1de5a571e..4e591222fc 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -7,20 +7,20 @@ * Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz> * Copyright (c) 2010 Janne Grunau <janne-ffmpeg@jannau.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -179,7 +179,7 @@ static int count_channels(enum ChannelPosition che_pos[4][MAX_ELEM_ID]) /** * Check for the channel element in the current channel position configuration. * If it exists, make sure the appropriate element is allocated and map the - * channel order to match the internal Libav channel layout. + * channel order to match the internal FFmpeg channel layout. * * @param che_pos current channel position configuration * @param type channel element type @@ -259,8 +259,6 @@ static av_cold int output_configure(AACContext *ac, } memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0])); - - avctx->channel_layout = 0; } avctx->channels = channels; @@ -270,6 +268,23 @@ static av_cold int output_configure(AACContext *ac, return 0; } +static void flush(AVCodecContext *avctx) +{ + AACContext *ac= avctx->priv_data; + int type, i, j; + + for (type = 3; type >= 0; type--) { + for (i = 0; i < MAX_ELEM_ID; i++) { + ChannelElement *che = ac->che[type][i]; + if (che) { + for (j = 0; j <= 1; j++) { + memset(che->ch[j].saved, 0, sizeof(che->ch[j].saved)); + } + } + } + } +} + /** * Decode an array of 4 bit element IDs, optionally interleaved with a stereo/mono switching bit. * @@ -323,6 +338,10 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, if (get_bits1(gb)) skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround + if (get_bits_left(gb) < 4 * (num_front + num_side + num_back + num_lfe + num_assoc_data + num_cc)) { + av_log(avctx, AV_LOG_ERROR, overread_err); + return -1; + } decode_channel_map(new_che_pos[TYPE_CPE], new_che_pos[TYPE_SCE], AAC_CHANNEL_FRONT, gb, num_front); decode_channel_map(new_che_pos[TYPE_CPE], new_che_pos[TYPE_SCE], AAC_CHANNEL_SIDE, gb, num_side ); decode_channel_map(new_che_pos[TYPE_CPE], new_che_pos[TYPE_SCE], AAC_CHANNEL_BACK, gb, num_back ); @@ -804,10 +823,10 @@ static int decode_band_types(AACContext *ac, enum BandType band_type[120], av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n"); return -1; } - while ((sect_len_incr = get_bits(gb, bits)) == (1 << bits) - 1) + while ((sect_len_incr = get_bits(gb, bits)) == (1 << bits) - 1 && get_bits_left(gb) >= bits) sect_end += sect_len_incr; sect_end += sect_len_incr; - if (get_bits_left(gb) < 0) { + if (get_bits_left(gb) < 0 || sect_len_incr == (1 << bits) - 1) { av_log(ac->avctx, AV_LOG_ERROR, overread_err); return -1; } @@ -2110,13 +2129,14 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) } if (!ac->avctx->sample_rate) ac->avctx->sample_rate = hdr_info.sample_rate; - if (hdr_info.num_aac_frames == 1) { - if (!hdr_info.crc_absent) - skip_bits(gb, 16); - } else { + if (!ac->warned_num_aac_frames && hdr_info.num_aac_frames != 1) { + // This is 2 for "VLB " audio in NSV files. + // See samples/nsv/vlb_audio. av_log_missing_feature(ac->avctx, "More than one AAC RDB per ADTS frame is", 0); - return -1; + ac->warned_num_aac_frames = 1; } + if (!hdr_info.crc_absent) + skip_bits(gb, 16); } return size; } @@ -2147,6 +2167,15 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, elem_id = get_bits(gb, 4); if (elem_type < TYPE_DSE) { + if (!ac->tags_mapped && elem_type == TYPE_CPE && ac->m4ac.chan_config==1) { + enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]= {0}; + ac->m4ac.chan_config=2; + + if (set_default_channel_config(ac->avctx, new_che_pos, 2)<0) + return -1; + if (output_configure(ac, new_che_pos, 2, OC_TRIAL_FRAME)<0) + return -1; + } if (!(che=get_che(ac, elem_type, elem_id))) { av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n", elem_type, elem_id); @@ -2186,10 +2215,11 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, if ((err = decode_pce(avctx, &ac->m4ac, new_che_pos, gb))) break; if (ac->output_configured > OC_TRIAL_PCE) - av_log(avctx, AV_LOG_ERROR, - "Not evaluating a further program_config_element as this construct is dubious at best.\n"); - else - err = output_configure(ac, new_che_pos, 0, OC_TRIAL_PCE); + av_log(avctx, AV_LOG_INFO, + "Evaluating a further program_config_element.\n"); + err = output_configure(ac, new_che_pos, 0, OC_TRIAL_PCE); + if (!err) + ac->m4ac.chan_config = 0; break; } @@ -2619,4 +2649,5 @@ AVCodec ff_aac_latm_decoder = { }, .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1, .channel_layouts = aac_channel_layout, + .flush = flush, }; diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h index 70372adf97..5f95dad846 100644 --- a/libavcodec/aacdectab.h +++ b/libavcodec/aacdectab.h @@ -3,20 +3,20 @@ * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacenc.c b/libavcodec/aacenc.c index 97ebbe6bab..11538856ab 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -2,20 +2,20 @@ * AAC encoder * Copyright (C) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -144,7 +144,7 @@ static const uint8_t aac_chan_configs[6][5] = { }; /** - * Table to remap channels from Libav's default order to AAC order. + * Table to remap channels from libavcodec's default order to AAC order. */ static const uint8_t aac_chan_maps[AAC_MAX_CHANNELS][AAC_MAX_CHANNELS] = { { 0 }, @@ -474,7 +474,7 @@ static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, /* * Deinterleave input samples. - * Channels are reordered from Libav's default order to AAC order. + * Channels are reordered from libavcodec's default order to AAC order. */ static void deinterleave_input_samples(AACEncContext *s, const float *samples, int nb_samples) @@ -747,7 +747,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) if (ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping)) goto fail; s->psypp = ff_psy_preprocess_init(avctx); - s->coder = &ff_aac_coders[2]; + s->coder = &ff_aac_coders[s->options.aac_coder]; s->lambda = avctx->global_quality ? avctx->global_quality : 120; @@ -768,6 +768,7 @@ static const AVOption aacenc_options[] = { {"auto", "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.dbl = -1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, {"ms_off", "Disable Mid/Side coding", 0, AV_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, {"ms_force", "Force Mid/Side for the whole frame if possible", 0, AV_OPT_TYPE_CONST, {.dbl = 1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"}, + {"aac_coder", "", offsetof(AACEncContext, options.aac_coder), AV_OPT_TYPE_INT, {.dbl = 2}, 0, AAC_CODER_NB-1, AACENC_FLAGS}, {NULL} }; diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h index 44ab13bf47..d87cc0479b 100644 --- a/libavcodec/aacenc.h +++ b/libavcodec/aacenc.h @@ -2,20 +2,20 @@ * AAC encoder * Copyright (C) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +30,11 @@ #include "psymodel.h" +#define AAC_CODER_NB 4 + typedef struct AACEncOptions { int stereo_mode; + int aac_coder; } AACEncOptions; struct AACEncContext; diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c index 3da912c6c7..3b5aa58109 100644 --- a/libavcodec/aacps.c +++ b/libavcodec/aacps.c @@ -2,20 +2,20 @@ * MPEG-4 Parametric Stereo decoding functions * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacps.h b/libavcodec/aacps.h index 124fbee221..757a44366b 100644 --- a/libavcodec/aacps.h +++ b/libavcodec/aacps.h @@ -2,20 +2,20 @@ * MPEG-4 Parametric Stereo definitions and declarations * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacps_tablegen.c b/libavcodec/aacps_tablegen.c index 8650226d71..dc7797f6b8 100644 --- a/libavcodec/aacps_tablegen.c +++ b/libavcodec/aacps_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacps_tablegen.h b/libavcodec/aacps_tablegen.h index 5041f44d19..79ae644a87 100644 --- a/libavcodec/aacps_tablegen.h +++ b/libavcodec/aacps_tablegen.h @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacpsdata.c b/libavcodec/aacpsdata.c index 675bd8e2b3..7431caebc6 100644 --- a/libavcodec/aacpsdata.c +++ b/libavcodec/aacpsdata.c @@ -2,20 +2,20 @@ * MPEG-4 Parametric Stereo data tables * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacpsy.c b/libavcodec/aacpsy.c index 8ee393ad1d..396a2d28b2 100644 --- a/libavcodec/aacpsy.c +++ b/libavcodec/aacpsy.c @@ -2,20 +2,20 @@ * AAC encoder psychoacoustic model * Copyright (C) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacpsy.h b/libavcodec/aacpsy.h index 5d1e14220c..05c93cddeb 100644 --- a/libavcodec/aacpsy.h +++ b/libavcodec/aacpsy.h @@ -2,20 +2,20 @@ * AAC encoder psychoacoustic model * Copyright (C) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index 3a30fcad7f..71bd2ceda5 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -3,20 +3,20 @@ * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -34,9 +34,11 @@ #include "aacps.h" #include "sbrdsp.h" #include "libavutil/libm.h" +#include "libavutil/avassert.h" #include <stdint.h> #include <float.h> +#include <math.h> #define ENVELOPE_ADJUSTMENT_OFFSET 2 #define NOISE_FLOOR_OFFSET 6.0f @@ -130,6 +132,8 @@ av_cold void ff_aac_sbr_init(void) av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr) { float mdct_scale; + if(sbr->mdct.mdct_bits) + return; sbr->kx[0] = sbr->kx[1] = 32; //Typo in spec, kx' inits to 32 sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1; sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); @@ -1398,6 +1402,7 @@ static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr, uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; int k; + av_assert0(sbr->kx[1] <= table[0]); for (i = 0; i < ilim; i++) for (m = table[i]; m < table[i + 1]; m++) sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i]; diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h index 153070d3f2..d0284981c3 100644 --- a/libavcodec/aacsbr.h +++ b/libavcodec/aacsbr.h @@ -3,20 +3,20 @@ * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aacsbrdata.h b/libavcodec/aacsbrdata.h index fb02a77f7d..a796e9deb7 100644 --- a/libavcodec/aacsbrdata.h +++ b/libavcodec/aacsbrdata.h @@ -2,20 +2,20 @@ * AAC Spectral Band Replication decoding data * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aactab.c b/libavcodec/aactab.c index 46886b12df..17102a66f5 100644 --- a/libavcodec/aactab.c +++ b/libavcodec/aactab.c @@ -3,20 +3,20 @@ * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aactab.h b/libavcodec/aactab.h index c76d65db95..c6213999b5 100644 --- a/libavcodec/aactab.h +++ b/libavcodec/aactab.h @@ -3,20 +3,20 @@ * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aandcttab.c b/libavcodec/aandcttab.c index 0c5b573412..87c50b37cf 100644 --- a/libavcodec/aandcttab.c +++ b/libavcodec/aandcttab.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aandcttab.h b/libavcodec/aandcttab.h index daccb7bb0b..d774828a4d 100644 --- a/libavcodec/aandcttab.h +++ b/libavcodec/aandcttab.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aasc.c b/libavcodec/aasc.c index 11ea5779b1..197bfe5f05 100644 --- a/libavcodec/aasc.c +++ b/libavcodec/aasc.c @@ -2,20 +2,20 @@ * Autodesk RLE Decoder * Copyright (C) 2005 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -50,8 +50,8 @@ static av_cold int aasc_decode_init(AVCodecContext *avctx) AascContext *s = avctx->priv_data; s->avctx = avctx; - avctx->pix_fmt = PIX_FMT_BGR24; + avcodec_get_frame_defaults(&s->frame); return 0; } @@ -65,7 +65,7 @@ static int aasc_decode_frame(AVCodecContext *avctx, AascContext *s = avctx->priv_data; int compr, i, stride; - s->frame.reference = 1; + s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &s->frame)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); @@ -79,8 +79,13 @@ static int aasc_decode_frame(AVCodecContext *avctx, case 0: stride = (avctx->width * 3 + 3) & ~3; for(i = avctx->height - 1; i >= 0; i--){ + if(avctx->width*3 > buf_size){ + av_log(avctx, AV_LOG_ERROR, "Next line is beyond buffer bounds\n"); + break; + } memcpy(s->frame.data[0] + i*s->frame.linesize[0], buf, avctx->width*3); buf += stride; + buf_size -= stride; } break; case 1: diff --git a/libavcodec/ac3.c b/libavcodec/ac3.c index 99e5b50acb..29e132f5d1 100644 --- a/libavcodec/ac3.c +++ b/libavcodec/ac3.c @@ -2,20 +2,20 @@ * Common code between the AC-3 encoder and decoder * Copyright (c) 2000 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ac3.h b/libavcodec/ac3.h index 304c86c181..b9f34b9d90 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -2,20 +2,20 @@ * Common code between the AC-3 encoder and decoder * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -39,6 +39,8 @@ #define AC3_CRITICAL_BANDS 50 #define AC3_MAX_CPL_BANDS 18 +#include "libavutil/opt.h" +#include "avcodec.h" #include "ac3tab.h" /* exponent encoding strategy */ diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index e3c46fd332..14ca196aaf 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -34,6 +34,18 @@ static const uint8_t eac3_blocks[4] = { 1, 2, 3, 6 }; +/** + * Table for center mix levels + * reference: Section 5.4.2.4 cmixlev + */ +static const uint8_t center_levels[4] = { 4, 5, 6, 5 }; + +/** + * Table for surround mix levels + * reference: Section 5.4.2.5 surmixlev + */ +static const uint8_t surround_levels[4] = { 4, 6, 7, 6 }; + int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) { @@ -53,8 +65,8 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) hdr->num_blocks = 6; /* set default mix levels */ - hdr->center_mix_level = 1; // -4.5dB - hdr->surround_mix_level = 1; // -6.0dB + hdr->center_mix_level = 5; // -4.5dB + hdr->surround_mix_level = 6; // -6.0dB if(hdr->bitstream_id <= 10) { /* Normal AC-3 */ @@ -76,9 +88,9 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) skip_bits(gbc, 2); // skip dsurmod } else { if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO) - hdr->center_mix_level = get_bits(gbc, 2); + hdr-> center_mix_level = center_levels[get_bits(gbc, 2)]; if(hdr->channel_mode & 4) - hdr->surround_mix_level = get_bits(gbc, 2); + hdr->surround_mix_level = surround_levels[get_bits(gbc, 2)]; } hdr->lfe_on = get_bits1(gbc); diff --git a/libavcodec/ac3_parser.h b/libavcodec/ac3_parser.h index 9322550ea5..b5022de2d8 100644 --- a/libavcodec/ac3_parser.h +++ b/libavcodec/ac3_parser.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index b50ec2abe6..01e08ec0c5 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -7,20 +7,20 @@ * Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com> * Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -77,18 +77,6 @@ static const float gain_levels[9] = { }; /** - * Table for center mix levels - * reference: Section 5.4.2.4 cmixlev - */ -static const uint8_t center_levels[4] = { 4, 5, 6, 5 }; - -/** - * Table for surround mix levels - * reference: Section 5.4.2.5 surmixlev - */ -static const uint8_t surround_levels[4] = { 4, 6, 7, 6 }; - -/** * Table for default stereo downmixing coefficients * reference: Section 7.8.2 Downmixing Into Two Channels */ @@ -315,8 +303,8 @@ static int parse_frame_header(AC3DecodeContext *s) static void set_downmix_coeffs(AC3DecodeContext *s) { int i; - float cmix = gain_levels[center_levels[s->center_mix_level]]; - float smix = gain_levels[surround_levels[s->surround_mix_level]]; + float cmix = gain_levels[s-> center_mix_level]; + float smix = gain_levels[s->surround_mix_level]; float norm0, norm1; for (i = 0; i < s->fbw_channels; i++) { @@ -1366,7 +1354,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, if (s->frame_size > buf_size) { av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); err = AAC_AC3_PARSE_ERROR_FRAME_SIZE; - } else if (avctx->err_recognition & AV_EF_CRCCHECK) { + } else if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) { /* check for crc mismatch */ if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size - 2)) { @@ -1395,6 +1383,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, avctx->channels = s->out_channels; avctx->channel_layout = s->channel_layout; + s->loro_center_mix_level = gain_levels[s-> center_mix_level]; + s->loro_surround_mix_level = gain_levels[s->surround_mix_level]; + s->ltrt_center_mix_level = LEVEL_MINUS_3DB; + s->ltrt_surround_mix_level = LEVEL_MINUS_3DB; /* set downmixing coefficients if needed */ if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) && s->fbw_channels == s->out_channels)) { @@ -1461,6 +1453,13 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx) #define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM) static const AVOption options[] = { { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {1.0}, 0.0, 1.0, PAR }, + +{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.dbl = -1 }, -1, 2, 0, "dmix_mode"}, +{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, + { NULL}, }; diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index 56c6553477..0f5e86e6b3 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -2,20 +2,20 @@ * Common code between the AC-3 and E-AC-3 decoders * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -89,6 +89,12 @@ typedef struct { int eac3; ///< indicates if current frame is E-AC-3 ///@} + int preferred_stereo_downmix; + float ltrt_center_mix_level; + float ltrt_surround_mix_level; + float loro_center_mix_level; + float loro_surround_mix_level; + ///@name Frame syntax parameters int snr_offset_strategy; ///< SNR offset strategy (snroffststr) int block_switch_syntax; ///< block switch syntax enabled (blkswe) diff --git a/libavcodec/ac3dec_data.c b/libavcodec/ac3dec_data.c index 272a963f08..d0a9b1ec40 100644 --- a/libavcodec/ac3dec_data.c +++ b/libavcodec/ac3dec_data.c @@ -2,20 +2,20 @@ * AC-3 and E-AC-3 decoder tables * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ac3dec_data.h b/libavcodec/ac3dec_data.h index c0a584e7b3..975b52ef2c 100644 --- a/libavcodec/ac3dec_data.h +++ b/libavcodec/ac3dec_data.h @@ -2,20 +2,20 @@ * AC-3 and E-AC-3 decoder tables * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index b751aec902..581e5f5071 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -2,20 +2,20 @@ * AC-3 DSP utils * Copyright (c) 2011 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -23,6 +23,7 @@ #include "avcodec.h" #include "ac3.h" #include "ac3dsp.h" +#include "mathops.h" static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs) { @@ -171,6 +172,48 @@ static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs) } } +static void ac3_sum_square_butterfly_int32_c(int64_t sum[4], + const int32_t *coef0, + const int32_t *coef1, + int len) +{ + int i; + + sum[0] = sum[1] = sum[2] = sum[3] = 0; + + for (i = 0; i < len; i++) { + int lt = coef0[i]; + int rt = coef1[i]; + int md = lt + rt; + int sd = lt - rt; + MAC64(sum[0], lt, lt); + MAC64(sum[1], rt, rt); + MAC64(sum[2], md, md); + MAC64(sum[3], sd, sd); + } +} + +static void ac3_sum_square_butterfly_float_c(float sum[4], + const float *coef0, + const float *coef1, + int len) +{ + int i; + + sum[0] = sum[1] = sum[2] = sum[3] = 0; + + for (i = 0; i < len; i++) { + float lt = coef0[i]; + float rt = coef1[i]; + float md = lt + rt; + float sd = lt - rt; + sum[0] += lt * lt; + sum[1] += rt * rt; + sum[2] += md * md; + sum[3] += sd * sd; + } +} + av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) { c->ac3_exponent_min = ac3_exponent_min_c; @@ -182,6 +225,8 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) c->update_bap_counts = ac3_update_bap_counts_c; c->compute_mantissa_size = ac3_compute_mantissa_size_c; c->extract_exponents = ac3_extract_exponents_c; + c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c; + c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c; if (ARCH_ARM) ff_ac3dsp_init_arm(c, bit_exact); diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h index 8eeafd68ac..f0a6999ecb 100644 --- a/libavcodec/ac3dsp.h +++ b/libavcodec/ac3dsp.h @@ -2,20 +2,20 @@ * AC-3 DSP utils * Copyright (c) 2011 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -125,6 +125,12 @@ typedef struct AC3DSPContext { int (*compute_mantissa_size)(uint16_t mant_cnt[6][16]); void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs); + + void (*sum_square_butterfly_int32)(int64_t sum[4], const int32_t *coef0, + const int32_t *coef1, int len); + + void (*sum_square_butterfly_float)(float sum[4], const float *coef0, + const float *coef1, int len); } AC3DSPContext; void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact); diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index b8e23e49f6..2f1e7c8f67 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -4,20 +4,20 @@ * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com> * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1210,14 +1210,11 @@ static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, int i; for (i = start_freq; i < end_freq; i++) { - int v; int c = fixed_coef[i]; int e = exp[i]; - int b = bap[i]; - switch (b) { - case 0: - v = 0; - break; + int v = bap[i]; + if (v) + switch (v) { case 1: v = sym_quant(c, e, 3); switch (s->mant1_cnt) { @@ -1286,7 +1283,7 @@ static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef, v = asym_quant(c, e, 16); break; default: - v = asym_quant(c, e, b - 1); + v = asym_quant(c, e, v - 1); break; } qmant[i] = v; @@ -2469,6 +2466,8 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) goto init_fail; avctx->coded_frame= avcodec_alloc_frame(); + if (!avctx->coded_frame) + goto init_fail; dsputil_init(&s->dsp, avctx); ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT); diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index 202dfb8afd..4b844783a9 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -4,20 +4,20 @@ * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com> * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -105,6 +105,12 @@ static void scale_coefficients(AC3EncodeContext *s) } } +static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4], + const int32_t *coef0, const int32_t *coef1, + int len) +{ + s->ac3dsp.sum_square_butterfly_int32(sum, coef0, coef1, len); +} /* * Clip MDCT coefficients to allowable range. diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c index a4abd89d4d..0d4000c05a 100644 --- a/libavcodec/ac3enc_float.c +++ b/libavcodec/ac3enc_float.c @@ -4,20 +4,20 @@ * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com> * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -114,6 +114,12 @@ static void scale_coefficients(AC3EncodeContext *s) chan_size * (s->channels + cpl)); } +static void sum_square_butterfly(AC3EncodeContext *s, float sum[4], + const float *coef0, const float *coef1, + int len) +{ + s->ac3dsp.sum_square_butterfly_float(sum, coef0, coef1, len); +} /* * Clip MDCT coefficients to allowable range. diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index 3396ed17b7..60472550d1 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -43,6 +43,9 @@ static void clip_coefficients(DSPContext *dsp, CoefType *coef, unsigned int len) static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl); +static void sum_square_butterfly(AC3EncodeContext *s, CoefSumType sum[4], + const CoefType *coef0, const CoefType *coef1, + int len); int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s) { @@ -66,7 +69,7 @@ alloc_fail: /* * Deinterleave input samples. - * Channels are reordered from Libav's default order to AC-3 order. + * Channels are reordered from FFmpeg's default order to AC-3 order. */ static void deinterleave_input_samples(AC3EncodeContext *s, const SampleType *samples) @@ -334,7 +337,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) static void compute_rematrixing_strategy(AC3EncodeContext *s) { int nb_coefs; - int blk, bnd, i; + int blk, bnd; AC3Block *block, *av_uninit(block0); if (s->channel_mode != AC3_CHMODE_STEREO) @@ -362,17 +365,9 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) /* calculate calculate sum of squared coeffs for one band in one block */ int start = ff_ac3_rematrix_band_tab[bnd]; int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); - CoefSumType sum[4] = {0,}; - for (i = start; i < end; i++) { - CoefType lt = block->mdct_coef[1][i]; - CoefType rt = block->mdct_coef[2][i]; - CoefType md = lt + rt; - CoefType sd = lt - rt; - MAC_COEF(sum[0], lt, lt); - MAC_COEF(sum[1], rt, rt); - MAC_COEF(sum[2], md, md); - MAC_COEF(sum[3], sd, sd); - } + CoefSumType sum[4]; + sum_square_butterfly(s, sum, block->mdct_coef[1] + start, + block->mdct_coef[2] + start, end - start); /* compare sums to determine if rematrixing will be used for this band */ if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1])) diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c index 7df3d828fb..3b3e715655 100644 --- a/libavcodec/ac3tab.c +++ b/libavcodec/ac3tab.c @@ -2,20 +2,20 @@ * AC-3 tables * copyright (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ac3tab.h b/libavcodec/ac3tab.h index e5cd368bb7..aa13c8f6e5 100644 --- a/libavcodec/ac3tab.h +++ b/libavcodec/ac3tab.h @@ -2,20 +2,20 @@ * AC-3 tables * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/acelp_filters.c b/libavcodec/acelp_filters.c index 16e2da1cc1..1ce5eed5e2 100644 --- a/libavcodec/acelp_filters.c +++ b/libavcodec/acelp_filters.c @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/acelp_filters.h b/libavcodec/acelp_filters.h index b8715d266f..e807aed7b9 100644 --- a/libavcodec/acelp_filters.h +++ b/libavcodec/acelp_filters.h @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -76,7 +76,7 @@ void ff_acelp_interpolatef(float *out, const float *in, * * The filter has a cut-off frequency of 1/80 of the sampling freq * - * @note Two items before the top of the out buffer must contain two items from the + * @note Two items before the top of the in buffer must contain two items from the * tail of the previous subframe. * * @remark It is safe to pass the same array in in and out parameters. diff --git a/libavcodec/acelp_pitch_delay.c b/libavcodec/acelp_pitch_delay.c index 395247dd2a..66d65a6903 100644 --- a/libavcodec/acelp_pitch_delay.c +++ b/libavcodec/acelp_pitch_delay.c @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -105,9 +105,20 @@ int16_t ff_acelp_decode_gain_code( for(i=0; i<ma_pred_order; i++) mr_energy += quant_energy[i] * ma_prediction_coeff[i]; +#ifdef G729_BITEXACT + mr_energy += (((-6165LL * ff_log2(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size, 0))) >> 3) & ~0x3ff); + + mr_energy = (5439 * (mr_energy >> 15)) >> 8; // (0.15) = (0.15) * (7.23) + + return bidir_sal( + ((ff_exp2(mr_energy & 0x7fff) + 16) >> 5) * (gain_corr_factor >> 1), + (mr_energy >> 15) - 25 + ); +#else mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) / sqrt(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size, 0)); return mr_energy >> 12; +#endif } float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy, diff --git a/libavcodec/acelp_pitch_delay.h b/libavcodec/acelp_pitch_delay.h index e5410bba7f..72977f1f49 100644 --- a/libavcodec/acelp_pitch_delay.h +++ b/libavcodec/acelp_pitch_delay.h @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c index b7c05e743f..6a544a912d 100644 --- a/libavcodec/acelp_vectors.c +++ b/libavcodec/acelp_vectors.c @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -48,6 +48,26 @@ const uint8_t ff_fc_2pulses_9bits_track1_gray[16] = 28, 26, }; +const uint8_t ff_fc_2pulses_9bits_track2_gray[32] = +{ + 0, 2, + 5, 4, + 12, 10, + 7, 9, + 25, 24, + 20, 22, + 14, 15, + 19, 17, + 36, 31, + 21, 26, + 1, 6, + 16, 11, + 27, 29, + 32, 30, + 39, 37, + 34, 35, +}; + const uint8_t ff_fc_4pulses_8bits_tracks_13[16] = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, @@ -217,11 +237,12 @@ void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size) int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1); float y = in->y[i] * scale; - do { - out[x] += y; - y *= in->pitch_fac; - x += in->pitch_lag; - } while (x < size && repeats); + if (in->pitch_lag > 0) + do { + out[x] += y; + y *= in->pitch_fac; + x += in->pitch_lag; + } while (x < size && repeats); } } @@ -232,9 +253,10 @@ void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size) for (i=0; i < in->n; i++) { int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1); - do { - out[x] = 0.0; - x += in->pitch_lag; - } while (x < size && repeats); + if (in->pitch_lag > 0) + do { + out[x] = 0.0; + x += in->pitch_lag; + } while (x < size && repeats); } } diff --git a/libavcodec/acelp_vectors.h b/libavcodec/acelp_vectors.h index 2c5d319e45..f3bc781446 100644 --- a/libavcodec/acelp_vectors.h +++ b/libavcodec/acelp_vectors.h @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -82,6 +82,37 @@ extern const uint8_t ff_fc_2pulses_9bits_track1[16]; extern const uint8_t ff_fc_2pulses_9bits_track1_gray[16]; /** + * Track|Pulse| Positions + * ----------------------------------------- + * 2 | 1 | 0, 7, 14, 20, 27, 34, 1, 21 + * | | 2, 9, 15, 22, 29, 35, 6, 26 + * | | 4,10, 17, 24, 30, 37, 11, 31 + * | | 5,12, 19, 25, 32, 39, 16, 36 + * ----------------------------------------- + * + * @remark Track in the table should be read top-to-bottom, left-to-right. + * + * @note (EE.1) This table (from the reference code) does not comply with + * the specification. + * The specification contains the following table: + * + * Track|Pulse| Positions + * ----------------------------------------- + * 2 | 1 | 0, 5, 10, 15, 20, 25, 30, 35 + * | | 1, 6, 11, 16, 21, 26, 31, 36 + * | | 2, 7, 12, 17, 22, 27, 32, 37 + * | | 4, 9, 14, 19, 24, 29, 34, 39 + * + * ----------------------------------------- + * + * @note (EE.2) Reference G.729D code also uses gray decoding for each + * pulse index before looking up the value in the table. + * + * Used in G.729 @@6.4k (with gray coding) + */ +extern const uint8_t ff_fc_2pulses_9bits_track2_gray[32]; + +/** * b60 hamming windowed sinc function coefficients */ extern const float ff_b60_sinc[61]; diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index bd86ab0e61..c21753af48 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2001-2003 The ffmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" @@ -350,6 +350,9 @@ static int get_nb_samples(AVCodecContext *avctx, const uint8_t *buf, *coded_samples = 0; + if(ch <= 0) + return 0; + switch (avctx->codec->id) { /* constant, only check buf_size */ case CODEC_ID_ADPCM_EA_XAS: @@ -849,6 +852,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces, each coding 28 stereo samples. */ + if(avctx->channels != 2) + return AVERROR_INVALIDDATA; + src += 4; // skip sample count (already read) current_left_sample = (int16_t)bytestream_get_le16(&src); diff --git a/libavcodec/adpcm.h b/libavcodec/adpcm.h index 16facb6d0f..08fd23f87b 100644 --- a/libavcodec/adpcm.h +++ b/libavcodec/adpcm.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2001-2003 The ffmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/adpcm_data.c b/libavcodec/adpcm_data.c index 3bc5de23b3..f19d622d3b 100644 --- a/libavcodec/adpcm_data.c +++ b/libavcodec/adpcm_data.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2001-2003 The ffmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/adpcm_data.h b/libavcodec/adpcm_data.h index a46cb5bdec..97ab66c346 100644 --- a/libavcodec/adpcm_data.h +++ b/libavcodec/adpcm_data.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2001-2003 The ffmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index a24238ccb8..de85054288 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2001-2003 The ffmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -58,6 +58,8 @@ typedef struct ADPCMEncodeContext { #define FREEZE_INTERVAL 128 +static av_cold int adpcm_encode_close(AVCodecContext *avctx); + static av_cold int adpcm_encode_init(AVCodecContext *avctx) { ADPCMEncodeContext *s = avctx->priv_data; @@ -99,6 +101,7 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) /* seems frame_size isn't taken into account... have to buffer the samples :-( */ avctx->block_align = BLKSIZE; + avctx->bits_per_coded_sample = 4; break; case CODEC_ID_ADPCM_IMA_QT: avctx->frame_size = 64; @@ -107,8 +110,8 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) case CODEC_ID_ADPCM_MS: /* each 16 bits sample gives one nibble and we have 7 bytes per channel overhead */ - avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 / - avctx->channels + 2; + avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 / avctx->channels + 2; + avctx->bits_per_coded_sample = 4; avctx->block_align = BLKSIZE; if (!(avctx->extradata = av_malloc(32 + FF_INPUT_BUFFER_PADDING_SIZE))) goto error; @@ -146,10 +149,7 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) return 0; error: - av_freep(&s->paths); - av_freep(&s->node_buf); - av_freep(&s->nodep_buf); - av_freep(&s->trellis_hash); + adpcm_encode_close(avctx); return ret; } @@ -183,24 +183,27 @@ static inline uint8_t adpcm_ima_qt_compress_sample(ADPCMChannelStatus *c, int16_t sample) { int delta = sample - c->prev_sample; - int mask, step = ff_adpcm_step_table[c->step_index]; - int diff = step >> 3; - int nibble = 0; + int diff, step = ff_adpcm_step_table[c->step_index]; + int nibble = 8*(delta < 0); - if (delta < 0) { - nibble = 8; - delta = -delta; - } + delta= abs(delta); + diff = delta + (step >> 3); - for (mask = 4; mask;) { - if (delta >= step) { - nibble |= mask; - delta -= step; - diff += step; - } - step >>= 1; - mask >>= 1; + if (delta >= step) { + nibble |= 4; + delta -= step; + } + step >>= 1; + if (delta >= step) { + nibble |= 2; + delta -= step; + } + step >>= 1; + if (delta >= step) { + nibble |= 1; + delta -= step; } + diff -= delta; if (nibble & 8) c->prev_sample -= diff; diff --git a/libavcodec/adx.h b/libavcodec/adx.h index 92abe5f163..a14ddce499 100644 --- a/libavcodec/adx.h +++ b/libavcodec/adx.h @@ -2,20 +2,20 @@ * ADX ADPCM codecs * Copyright (c) 2001,2003 BERO * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/adxdec.c b/libavcodec/adxdec.c index 3f7f5f4ca1..ec4b1041af 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -2,20 +2,20 @@ * ADX ADPCM codecs * Copyright (c) 2001,2003 BERO * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/adxenc.c b/libavcodec/adxenc.c index 20f27981c8..c6e46565f6 100644 --- a/libavcodec/adxenc.c +++ b/libavcodec/adxenc.c @@ -2,20 +2,20 @@ * ADX ADPCM codecs * Copyright (c) 2001,2003 BERO * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -120,6 +120,8 @@ static av_cold int adx_encode_init(AVCodecContext *avctx) avctx->frame_size = BLOCK_SAMPLES; avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); /* the cutoff can be adjusted, but this seems to work pretty well */ c->cutoff = 500; diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 278cc99969..83e0d810e6 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -2,20 +2,20 @@ * ALAC (Apple Lossless Audio Codec) decoder * Copyright (c) 2005 David Hammerton * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -108,7 +108,7 @@ static inline int decode_scalar(GetBitContext *gb, int k, int limit, int readsam return x; } -static void bastardized_rice_decompress(ALACContext *alac, +static int bastardized_rice_decompress(ALACContext *alac, int32_t *output_buffer, int output_size, int readsamplesize, /* arg_10 */ @@ -130,6 +130,9 @@ static void bastardized_rice_decompress(ALACContext *alac, /* standard rice encoding */ int k; /* size of extra bits */ + if(get_bits_left(&alac->gb) <= 0) + return -1; + /* read k, that is bits as is */ k = av_log2((history >> 9) + 3); x= decode_scalar(&alac->gb, k, rice_kmodifier, readsamplesize); @@ -175,6 +178,7 @@ static void bastardized_rice_decompress(ALACContext *alac, history = 0; } } + return 0; } static inline int sign_only(int v) @@ -347,6 +351,17 @@ static void interleave_stereo_24(int32_t *buffer[MAX_CHANNELS], } } +static void interleave_stereo_32(int32_t *buffer[MAX_CHANNELS], + int32_t *buffer_out, int numsamples) +{ + int i; + + for (i = 0; i < numsamples; i++) { + *buffer_out++ = buffer[0][i]; + *buffer_out++ = buffer[1][i]; + } +} + static int alac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { @@ -438,12 +453,14 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, if (alac->extra_bits) { for (i = 0; i < outputsamples; i++) { + if(get_bits_left(&alac->gb) <= 0) + return -1; for (ch = 0; ch < channels; ch++) alac->extra_bits_buffer[ch][i] = get_bits(&alac->gb, alac->extra_bits); } } for (ch = 0; ch < channels; ch++) { - bastardized_rice_decompress(alac, + int ret = bastardized_rice_decompress(alac, alac->predicterror_buffer[ch], outputsamples, readsamplesize, @@ -451,6 +468,8 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, alac->setinfo_rice_kmodifier, ricemodifier[ch] * alac->setinfo_rice_historymult / 4, (1 << alac->setinfo_rice_kmodifier) - 1); + if(ret<0) + return ret; /* adaptive FIR filter */ if (prediction_type[ch] == 15) { @@ -479,6 +498,8 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, } else { /* not compressed, easy case */ for (i = 0; i < outputsamples; i++) { + if(get_bits_left(&alac->gb) <= 0) + return -1; for (ch = 0; ch < channels; ch++) { alac->outputsamples_buffer[ch][i] = get_sbits_long(&alac->gb, alac->setinfo_sample_size); @@ -523,6 +544,16 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, outbuffer[i] = alac->outputsamples_buffer[0][i] << 8; } break; + case 32: + if (channels == 2) { + interleave_stereo_32(alac->outputsamples_buffer, + (int32_t *)alac->frame.data[0], outputsamples); + } else { + int32_t *outbuffer = (int32_t *)alac->frame.data[0]; + for (i = 0; i < outputsamples; i++) + outbuffer[i] = alac->outputsamples_buffer[0][i]; + } + break; } if (input_buffer_size * 8 - get_bits_count(&alac->gb) > 8) @@ -618,6 +649,7 @@ static av_cold int alac_decode_init(AVCodecContext * avctx) switch (alac->setinfo_sample_size) { case 16: avctx->sample_fmt = AV_SAMPLE_FMT_S16; break; + case 32: case 24: avctx->sample_fmt = AV_SAMPLE_FMT_S32; break; default: av_log_ask_for_sample(avctx, "Sample depth %d is not supported.\n", diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c index 19708eb431..fde3b53e5e 100644 --- a/libavcodec/alacenc.c +++ b/libavcodec/alacenc.c @@ -2,20 +2,20 @@ * ALAC audio encoder * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index cda71e0a1a..d18b3f03c7 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -2,20 +2,20 @@ * Provide registration of all codecs, parsers and bitstream filters for libavcodec. * Copyright (c) 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -58,8 +58,10 @@ void avcodec_register_all(void) REGISTER_HWACCEL (H264_DXVA2, h264_dxva2); REGISTER_HWACCEL (H264_VAAPI, h264_vaapi); REGISTER_HWACCEL (H264_VDA, h264_vda); + REGISTER_HWACCEL (MPEG1_VDPAU, mpeg1_vdpau); REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi); + REGISTER_HWACCEL (MPEG2_VDPAU, mpeg2_vdpau); REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi); REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2); REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi); @@ -70,14 +72,16 @@ void avcodec_register_all(void) REGISTER_ENCODER (A64MULTI, a64multi); REGISTER_ENCODER (A64MULTI5, a64multi5); REGISTER_DECODER (AASC, aasc); - REGISTER_DECODER (AMV, amv); + REGISTER_ENCDEC (AMV, amv); REGISTER_DECODER (ANM, anm); REGISTER_DECODER (ANSI, ansi); REGISTER_ENCDEC (ASV1, asv1); REGISTER_ENCDEC (ASV2, asv2); REGISTER_DECODER (AURA, aura); REGISTER_DECODER (AURA2, aura2); + REGISTER_ENCDEC (AVRP, avrp); REGISTER_DECODER (AVS, avs); + REGISTER_ENCDEC (AYUV, ayuv); REGISTER_DECODER (BETHSOFTVID, bethsoftvid); REGISTER_DECODER (BFI, bfi); REGISTER_DECODER (BINK, bink); @@ -91,6 +95,7 @@ void avcodec_register_all(void) REGISTER_DECODER (CSCD, cscd); REGISTER_DECODER (CYUV, cyuv); REGISTER_DECODER (DFA, dfa); + REGISTER_DECODER (DIRAC, dirac); REGISTER_ENCDEC (DNXHD, dnxhd); REGISTER_ENCDEC (DPX, dpx); REGISTER_DECODER (DSICINVIDEO, dsicinvideo); @@ -106,10 +111,11 @@ void avcodec_register_all(void) REGISTER_DECODER (EIGHTSVX_EXP, eightsvx_exp); REGISTER_DECODER (EIGHTSVX_FIB, eightsvx_fib); REGISTER_DECODER (ESCAPE124, escape124); + REGISTER_DECODER (ESCAPE130, escape130); REGISTER_ENCDEC (FFV1, ffv1); REGISTER_ENCDEC (FFVHUFF, ffvhuff); REGISTER_ENCDEC (FLASHSV, flashsv); - REGISTER_DECODER (FLASHSV2, flashsv2); + REGISTER_ENCDEC (FLASHSV2, flashsv2); REGISTER_DECODER (FLIC, flic); REGISTER_ENCDEC (FLV, flv); REGISTER_DECODER (FOURXM, fourxm); @@ -121,6 +127,7 @@ void avcodec_register_all(void) REGISTER_DECODER (H263I, h263i); REGISTER_ENCODER (H263P, h263p); REGISTER_DECODER (H264, h264); + REGISTER_DECODER (H264_CRYSTALHD, h264_crystalhd); REGISTER_DECODER (H264_VDPAU, h264_vdpau); REGISTER_ENCDEC (HUFFYUV, huffyuv); REGISTER_DECODER (IDCIN, idcin); @@ -131,6 +138,7 @@ void avcodec_register_all(void) REGISTER_DECODER (INDEO4, indeo4); REGISTER_DECODER (INDEO5, indeo5); REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video); + REGISTER_ENCDEC (JPEG2000, jpeg2000); REGISTER_ENCDEC (JPEGLS, jpegls); REGISTER_DECODER (JV, jv); REGISTER_DECODER (KGV1, kgv1); @@ -148,14 +156,18 @@ void avcodec_register_all(void) REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); REGISTER_ENCDEC (MPEG4, mpeg4); + REGISTER_DECODER (MPEG4_CRYSTALHD, mpeg4_crystalhd); REGISTER_DECODER (MPEG4_VDPAU, mpeg4_vdpau); + REGISTER_DECODER (MPEGVIDEO, mpegvideo); REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau); REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau); + REGISTER_DECODER (MPEG2_CRYSTALHD, mpeg2_crystalhd); + REGISTER_DECODER (MSMPEG4_CRYSTALHD, msmpeg4_crystalhd); REGISTER_DECODER (MSMPEG4V1, msmpeg4v1); REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2); REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3); REGISTER_DECODER (MSRLE, msrle); - REGISTER_DECODER (MSVIDEO1, msvideo1); + REGISTER_ENCDEC (MSVIDEO1, msvideo1); REGISTER_DECODER (MSZH, mszh); REGISTER_DECODER (MXPEG, mxpeg); REGISTER_DECODER (NUV, nuv); @@ -167,13 +179,14 @@ void avcodec_register_all(void) REGISTER_DECODER (PICTOR, pictor); REGISTER_ENCDEC (PNG, png); REGISTER_ENCDEC (PPM, ppm); - REGISTER_DECODER (PRORES, prores); + REGISTER_ENCDEC (PRORES, prores); + REGISTER_DECODER (PRORES_LGPL, prores_lgpl); REGISTER_DECODER (PTX, ptx); REGISTER_DECODER (QDRAW, qdraw); REGISTER_DECODER (QPEG, qpeg); REGISTER_ENCDEC (QTRLE, qtrle); - REGISTER_DECODER (R10K, r10k); - REGISTER_DECODER (R210, r210); + REGISTER_ENCDEC (R10K, r10k); + REGISTER_ENCDEC (R210, r210); REGISTER_ENCDEC (RAWVIDEO, rawvideo); REGISTER_DECODER (RL2, rl2); REGISTER_ENCDEC (ROQ, roq); @@ -205,10 +218,13 @@ void avcodec_register_all(void) REGISTER_DECODER (UTVIDEO, utvideo); REGISTER_ENCDEC (V210, v210); REGISTER_DECODER (V210X, v210x); + REGISTER_ENCDEC (V308, v308); + REGISTER_ENCDEC (V408, v408); REGISTER_ENCDEC (V410, v410); REGISTER_DECODER (VB, vb); REGISTER_DECODER (VBLE, vble); REGISTER_DECODER (VC1, vc1); + REGISTER_DECODER (VC1_CRYSTALHD, vc1_crystalhd); REGISTER_DECODER (VC1_VDPAU, vc1_vdpau); REGISTER_DECODER (VC1IMAGE, vc1image); REGISTER_DECODER (VCR1, vcr1); @@ -224,6 +240,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (WMV1, wmv1); REGISTER_ENCDEC (WMV2, wmv2); REGISTER_DECODER (WMV3, wmv3); + REGISTER_DECODER (WMV3_CRYSTALHD, wmv3_crystalhd); REGISTER_DECODER (WMV3_VDPAU, wmv3_vdpau); REGISTER_DECODER (WMV3IMAGE, wmv3image); REGISTER_DECODER (WNV1, wnv1); @@ -231,7 +248,9 @@ void avcodec_register_all(void) REGISTER_DECODER (XAN_WC4, xan_wc4); REGISTER_DECODER (XL, xl); REGISTER_ENCDEC (XWD, xwd); + REGISTER_ENCDEC (Y41P, y41p); REGISTER_DECODER (YOP, yop); + REGISTER_ENCDEC (YUV4, yuv4); REGISTER_ENCDEC (ZLIB, zlib); REGISTER_ENCDEC (ZMBV, zmbv); @@ -251,10 +270,13 @@ void avcodec_register_all(void) REGISTER_DECODER (BINKAUDIO_RDFT, binkaudio_rdft); REGISTER_DECODER (BMV_AUDIO, bmv_audio); REGISTER_DECODER (COOK, cook); - REGISTER_DECODER (DCA, dca); + REGISTER_ENCDEC (DCA, dca); REGISTER_DECODER (DSICINAUDIO, dsicinaudio); REGISTER_ENCDEC (EAC3, eac3); + REGISTER_DECODER (FFWAVESYNTH, ffwavesynth); REGISTER_ENCDEC (FLAC, flac); + REGISTER_ENCDEC (G723_1, g723_1); + REGISTER_DECODER (G729, g729); REGISTER_DECODER (GSM, gsm); REGISTER_DECODER (GSM_MS, gsm_ms); REGISTER_DECODER (IMC, imc); @@ -281,6 +303,8 @@ void avcodec_register_all(void) REGISTER_DECODER (SHORTEN, shorten); REGISTER_DECODER (SIPR, sipr); REGISTER_DECODER (SMACKAUD, smackaud); + REGISTER_ENCDEC (SONIC, sonic); + REGISTER_ENCODER (SONIC_LS, sonic_ls); REGISTER_DECODER (TRUEHD, truehd); REGISTER_DECODER (TRUESPEECH, truespeech); REGISTER_DECODER (TTA, tta); @@ -288,6 +312,7 @@ void avcodec_register_all(void) REGISTER_DECODER (VMDAUDIO, vmdaudio); REGISTER_ENCDEC (VORBIS, vorbis); REGISTER_DECODER (WAVPACK, wavpack); + REGISTER_DECODER (WMALOSSLESS, wmalossless); REGISTER_DECODER (WMAPRO, wmapro); REGISTER_ENCDEC (WMAV1, wmav1); REGISTER_ENCDEC (WMAV2, wmav2); @@ -366,10 +391,12 @@ void avcodec_register_all(void) REGISTER_ENCDEC (DVBSUB, dvbsub); REGISTER_ENCDEC (DVDSUB, dvdsub); REGISTER_DECODER (PGSSUB, pgssub); - REGISTER_DECODER (SRT, srt); + REGISTER_ENCDEC (SRT, srt); REGISTER_ENCDEC (XSUB, xsub); /* external libraries */ + REGISTER_ENCODER (LIBAACPLUS, libaacplus); + REGISTER_DECODER (LIBCELT, libcelt); REGISTER_ENCDEC (LIBDIRAC, libdirac); REGISTER_ENCODER (LIBFAAC, libfaac); REGISTER_ENCDEC (LIBGSM, libgsm); @@ -377,18 +404,26 @@ void avcodec_register_all(void) REGISTER_ENCODER (LIBMP3LAME, libmp3lame); REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb); REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb); - REGISTER_DECODER (LIBOPENJPEG, libopenjpeg); + REGISTER_ENCDEC (LIBOPENJPEG, libopenjpeg); REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger); REGISTER_ENCDEC (LIBSPEEX, libspeex); + REGISTER_DECODER (LIBSTAGEFRIGHT_H264, libstagefright_h264); REGISTER_ENCODER (LIBTHEORA, libtheora); + REGISTER_DECODER (LIBUTVIDEO, libutvideo); REGISTER_ENCODER (LIBVO_AACENC, libvo_aacenc); REGISTER_ENCODER (LIBVO_AMRWBENC, libvo_amrwbenc); REGISTER_ENCODER (LIBVORBIS, libvorbis); REGISTER_ENCDEC (LIBVPX, libvpx); REGISTER_ENCODER (LIBX264, libx264); + REGISTER_ENCODER (LIBX264RGB, libx264rgb); REGISTER_ENCODER (LIBXAVS, libxavs); REGISTER_ENCODER (LIBXVID, libxvid); + /* text */ + REGISTER_DECODER (BINTEXT, bintext); + REGISTER_DECODER (XBIN, xbin); + REGISTER_DECODER (IDF, idf); + /* parsers */ REGISTER_PARSER (AAC, aac); REGISTER_PARSER (AAC_LATM, aac_latm); diff --git a/libavcodec/alpha/asm.h b/libavcodec/alpha/asm.h index ab4cfccc87..827721e777 100644 --- a/libavcodec/alpha/asm.h +++ b/libavcodec/alpha/asm.h @@ -2,20 +2,20 @@ * Alpha optimized DSP utils * Copyright (c) 2002 Falk Hueffner <falk@debian.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/alpha/dsputil_alpha.c b/libavcodec/alpha/dsputil_alpha.c index acd8e03f2b..d8f999dfdc 100644 --- a/libavcodec/alpha/dsputil_alpha.c +++ b/libavcodec/alpha/dsputil_alpha.c @@ -2,20 +2,20 @@ * Alpha optimized DSP utils * Copyright (c) 2002 Falk Hueffner <falk@debian.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/alpha/dsputil_alpha.h b/libavcodec/alpha/dsputil_alpha.h index 0dcacabb9d..a3fa3dd586 100644 --- a/libavcodec/alpha/dsputil_alpha.h +++ b/libavcodec/alpha/dsputil_alpha.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/alpha/dsputil_alpha_asm.S b/libavcodec/alpha/dsputil_alpha_asm.S index ca857ac152..32a8bc9562 100644 --- a/libavcodec/alpha/dsputil_alpha_asm.S +++ b/libavcodec/alpha/dsputil_alpha_asm.S @@ -2,20 +2,20 @@ * Alpha optimized DSP utils * Copyright (c) 2002 Falk Hueffner <falk@debian.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/alpha/motion_est_alpha.c b/libavcodec/alpha/motion_est_alpha.c index bb9ab134e9..863dd23da3 100644 --- a/libavcodec/alpha/motion_est_alpha.c +++ b/libavcodec/alpha/motion_est_alpha.c @@ -2,20 +2,20 @@ * Alpha optimized DSP utils * Copyright (c) 2002 Falk Hueffner <falk@debian.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/alpha/motion_est_mvi_asm.S b/libavcodec/alpha/motion_est_mvi_asm.S index 7fe4e168e0..2399085bcb 100644 --- a/libavcodec/alpha/motion_est_mvi_asm.S +++ b/libavcodec/alpha/motion_est_mvi_asm.S @@ -2,20 +2,20 @@ * Alpha optimized DSP utils * Copyright (c) 2002 Falk Hueffner <falk@debian.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/alpha/mpegvideo_alpha.c b/libavcodec/alpha/mpegvideo_alpha.c index add57364a3..de32545ade 100644 --- a/libavcodec/alpha/mpegvideo_alpha.c +++ b/libavcodec/alpha/mpegvideo_alpha.c @@ -2,20 +2,20 @@ * Alpha optimized DSP utils * Copyright (c) 2002 Falk Hueffner <falk@debian.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/alpha/regdef.h b/libavcodec/alpha/regdef.h index fa9ad98e5c..aa1959f46e 100644 --- a/libavcodec/alpha/regdef.h +++ b/libavcodec/alpha/regdef.h @@ -2,20 +2,20 @@ * Alpha optimized DSP utils * copyright (c) 2002 Falk Hueffner <falk@debian.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/alpha/simple_idct_alpha.c b/libavcodec/alpha/simple_idct_alpha.c index 61bc5f2084..522efd2b4d 100644 --- a/libavcodec/alpha/simple_idct_alpha.c +++ b/libavcodec/alpha/simple_idct_alpha.c @@ -9,20 +9,20 @@ * Alpha optimizations by MÃ¥ns RullgÃ¥rd <mans@mansr.com> * and Falk Hueffner <falk@debian.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/alsdec.c b/libavcodec/alsdec.c index 2948a48b5c..6ce48de7de 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -2,20 +2,20 @@ * MPEG-4 ALS decoder * Copyright (c) 2009 Thilo Borgmann <thilo.borgmann _at_ googlemail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -394,7 +394,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) if (get_bits_left(&gb) < 32) return -1; - if (avctx->err_recognition & AV_EF_CRCCHECK) { + if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) { ctx->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); ctx->crc = 0xFFFFFFFF; ctx->crc_org = ~get_bits_long(&gb, 32); @@ -1012,7 +1012,7 @@ static void zero_remaining(unsigned int b, unsigned int b_max, unsigned int count = 0; while (b < b_max) - count += div_blocks[b]; + count += div_blocks[b++]; if (count) memset(buf, 0, sizeof(*buf) * count); @@ -1442,7 +1442,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, ctx->cur_frame_length = sconf->frame_length; // decode the frame data - if ((invalid_frame = read_frame_data(ctx, ra_frame) < 0)) + if ((invalid_frame = read_frame_data(ctx, ra_frame)) < 0) av_log(ctx->avctx, AV_LOG_WARNING, "Reading frame data failed. Skipping RA unit.\n"); @@ -1472,7 +1472,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, } // update CRC - if (sconf->crc_enabled && (avctx->err_recognition & AV_EF_CRCCHECK)) { + if (sconf->crc_enabled && (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL))) { int swap = HAVE_BIGENDIAN != sconf->msb_first; if (ctx->avctx->bits_per_raw_sample == 24) { @@ -1712,7 +1712,7 @@ static av_cold int decode_init(AVCodecContext *avctx) // allocate crc buffer if (HAVE_BIGENDIAN != sconf->msb_first && sconf->crc_enabled && - (avctx->err_recognition & AV_EF_CRCCHECK)) { + (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL))) { ctx->crc_buffer = av_malloc(sizeof(*ctx->crc_buffer) * ctx->cur_frame_length * avctx->channels * diff --git a/libavcodec/amr.h b/libavcodec/amr.h index ae6e4d1490..7e5a4dce5b 100644 --- a/libavcodec/amr.h +++ b/libavcodec/amr.h @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Marcelo Galvao Povoa * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/amrnbdata.h b/libavcodec/amrnbdata.h index 26ff7fb40e..2745d33ffb 100644 --- a/libavcodec/amrnbdata.h +++ b/libavcodec/amrnbdata.h @@ -3,20 +3,20 @@ * Copyright (c) 2006-2007 Robert Swain * Copyright (c) 2009 Colin McQuillan * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1655,10 +1655,10 @@ static const float ir_filter_medium[AMR_SUBFRAME_SIZE] = { 0.016998, 0.023804, -0.041779, 0.025696, 0.019989, }; -static const float *ir_filters_lookup[2] = { +static const float * const ir_filters_lookup[2] = { ir_filter_strong, ir_filter_medium }; -static const float *ir_filters_lookup_MODE_7k95[2] = { +static const float * const ir_filters_lookup_MODE_7k95[2] = { ir_filter_strong_MODE_7k95, ir_filter_medium }; diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index fff0e7248a..c560d69e88 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -3,20 +3,20 @@ * Copyright (c) 2006-2007 Robert Swain * Copyright (c) 2009 Colin McQuillan * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -83,7 +83,7 @@ /** Maximum sharpening factor * * The specification says 0.8, which should be 13107, but the reference C code - * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in bitexact G.729.) + * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in g729dec.c.) */ #define SHARP_MAX 0.79449462890625 @@ -948,7 +948,8 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, p->cur_frame_mode = unpack_bitstream(p, buf, buf_size); if (p->cur_frame_mode == MODE_DTX) { - av_log_missing_feature(avctx, "dtx mode", 1); + av_log_missing_feature(avctx, "dtx mode", 0); + av_log(avctx, AV_LOG_INFO, "Note: libopencore_amrnb supports dtx\n"); return -1; } diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h index 5421c23afb..972c257d2a 100644 --- a/libavcodec/amrwbdata.h +++ b/libavcodec/amrwbdata.h @@ -2,20 +2,20 @@ * AMR wideband data and definitions * Copyright (c) 2010 Marcelo Galvao Povoa * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1805,7 +1805,7 @@ static const float ir_filter_mid[64] = { -7.501221e-02, 2.920532e-02, 1.660156e-02, 7.751465e-02 }; -static const float *ir_filters_lookup[2] = { +static const float * const ir_filters_lookup[2] = { ir_filter_str, ir_filter_mid }; diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 6ea5d228dd..524979d755 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -2,20 +2,20 @@ * AMR wideband decoder * Copyright (c) 2010 Marcelo Galvao Povoa * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/anm.c b/libavcodec/anm.c index 59de984301..5493be6842 100644 --- a/libavcodec/anm.c +++ b/libavcodec/anm.c @@ -2,20 +2,20 @@ * Deluxe Paint Animation decoder * Copyright (c) 2009 Peter Ross * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,6 +29,7 @@ typedef struct AnmContext { AVFrame frame; + int palette[AVPALETTE_COUNT]; int x; ///< x coordinate position } AnmContext; @@ -43,15 +44,12 @@ static av_cold int decode_init(AVCodecContext *avctx) if (avctx->extradata_size != 16*8 + 4*256) return -1; - s->frame.reference = 1; - if (avctx->get_buffer(avctx, &s->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } + avcodec_get_frame_defaults(&s->frame); + s->frame.reference = 3; buf = avctx->extradata + 16*8; for (i = 0; i < 256; i++) - ((uint32_t*)s->frame.data[1])[i] = bytestream_get_le32(&buf); + s->palette[i] = bytestream_get_le32(&buf); return 0; } @@ -172,6 +170,8 @@ static int decode_frame(AVCodecContext *avctx, } } while (buf + 1 < buf_end); + memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; return buf_size; diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c index 32c7ce4ecd..ebcc288539 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -2,20 +2,20 @@ * ASCII/ANSI art decoder * Copyright (c) 2010 Peter Ross <pross@xvid.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -81,6 +81,7 @@ static av_cold int decode_init(AVCodecContext *avctx) s->fg = DEFAULT_FG_COLOR; s->bg = DEFAULT_BG_COLOR; + avcodec_get_frame_defaults(&s->frame); if (!avctx->width || !avctx->height) avcodec_set_dimensions(avctx, 80<<3, 25<<4); diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 2b95874078..1cd7d1e66d 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -3,20 +3,20 @@ * Copyright (c) 2007 Benjamin Zores <ben@geexbox.org> * based upon libdemac from Dave Chapman. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/api-example.c b/libavcodec/api-example.c deleted file mode 100644 index 970a90eaba..0000000000 --- a/libavcodec/api-example.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * copyright (c) 2001 Fabrice Bellard - * - * This file is part of Libav. - * - * Libav 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. - * - * Libav 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 Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * libavcodec API use example. - * - * @example libavcodec/api-example.c - * Note that this library only handles codecs (mpeg, mpeg4, etc...), - * not file formats (avi, vob, etc...). See library 'libavformat' for the - * format handling - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#ifdef HAVE_AV_CONFIG_H -#undef HAVE_AV_CONFIG_H -#endif - -#include "libavcodec/avcodec.h" -#include "libavutil/mathematics.h" -#include "libavutil/samplefmt.h" - -#define INBUF_SIZE 4096 -#define AUDIO_INBUF_SIZE 20480 -#define AUDIO_REFILL_THRESH 4096 - -/* - * Audio encoding example - */ -static void audio_encode_example(const char *filename) -{ - AVCodec *codec; - AVCodecContext *c= NULL; - int frame_size, i, j, out_size, outbuf_size; - FILE *f; - short *samples; - float t, tincr; - uint8_t *outbuf; - - printf("Audio encoding\n"); - - /* find the MP2 encoder */ - codec = avcodec_find_encoder(CODEC_ID_MP2); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - c = avcodec_alloc_context3(codec); - - /* put sample parameters */ - c->bit_rate = 64000; - c->sample_rate = 44100; - c->channels = 2; - - /* open it */ - if (avcodec_open(c, codec) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - /* the codec gives us the frame size, in samples */ - frame_size = c->frame_size; - samples = malloc(frame_size * 2 * c->channels); - outbuf_size = 10000; - outbuf = malloc(outbuf_size); - - f = fopen(filename, "wb"); - if (!f) { - fprintf(stderr, "could not open %s\n", filename); - exit(1); - } - - /* encode a single tone sound */ - t = 0; - tincr = 2 * M_PI * 440.0 / c->sample_rate; - for(i=0;i<200;i++) { - for(j=0;j<frame_size;j++) { - samples[2*j] = (int)(sin(t) * 10000); - samples[2*j+1] = samples[2*j]; - t += tincr; - } - /* encode the samples */ - out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples); - fwrite(outbuf, 1, out_size, f); - } - fclose(f); - free(outbuf); - free(samples); - - avcodec_close(c); - av_free(c); -} - -/* - * Audio decoding. - */ -static void audio_decode_example(const char *outfilename, const char *filename) -{ - AVCodec *codec; - AVCodecContext *c= NULL; - int len; - FILE *f, *outfile; - uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; - AVPacket avpkt; - AVFrame *decoded_frame = NULL; - - av_init_packet(&avpkt); - - printf("Audio decoding\n"); - - /* find the mpeg audio decoder */ - codec = avcodec_find_decoder(CODEC_ID_MP2); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - c = avcodec_alloc_context3(codec); - - /* open it */ - if (avcodec_open(c, codec) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "could not open %s\n", filename); - exit(1); - } - outfile = fopen(outfilename, "wb"); - if (!outfile) { - av_free(c); - exit(1); - } - - /* decode until eof */ - avpkt.data = inbuf; - avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); - - while (avpkt.size > 0) { - int got_frame = 0; - - if (!decoded_frame) { - if (!(decoded_frame = avcodec_alloc_frame())) { - fprintf(stderr, "out of memory\n"); - exit(1); - } - } else - avcodec_get_frame_defaults(decoded_frame); - - len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt); - if (len < 0) { - fprintf(stderr, "Error while decoding\n"); - exit(1); - } - if (got_frame) { - /* if a frame has been decoded, output it */ - int data_size = av_samples_get_buffer_size(NULL, c->channels, - decoded_frame->nb_samples, - c->sample_fmt, 1); - fwrite(decoded_frame->data[0], 1, data_size, outfile); - } - avpkt.size -= len; - avpkt.data += len; - if (avpkt.size < AUDIO_REFILL_THRESH) { - /* Refill the input buffer, to avoid trying to decode - * incomplete frames. Instead of this, one could also use - * a parser, or use a proper container format through - * libavformat. */ - memmove(inbuf, avpkt.data, avpkt.size); - avpkt.data = inbuf; - len = fread(avpkt.data + avpkt.size, 1, - AUDIO_INBUF_SIZE - avpkt.size, f); - if (len > 0) - avpkt.size += len; - } - } - - fclose(outfile); - fclose(f); - - avcodec_close(c); - av_free(c); - av_free(decoded_frame); -} - -/* - * Video encoding example - */ -static void video_encode_example(const char *filename) -{ - AVCodec *codec; - AVCodecContext *c= NULL; - int i, out_size, size, x, y, outbuf_size; - FILE *f; - AVFrame *picture; - uint8_t *outbuf, *picture_buf; - - printf("Video encoding\n"); - - /* find the mpeg1 video encoder */ - codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - c = avcodec_alloc_context3(codec); - picture= avcodec_alloc_frame(); - - /* put sample parameters */ - c->bit_rate = 400000; - /* resolution must be a multiple of two */ - c->width = 352; - c->height = 288; - /* frames per second */ - c->time_base= (AVRational){1,25}; - c->gop_size = 10; /* emit one intra frame every ten frames */ - c->max_b_frames=1; - c->pix_fmt = PIX_FMT_YUV420P; - - /* open it */ - if (avcodec_open(c, codec) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - f = fopen(filename, "wb"); - if (!f) { - fprintf(stderr, "could not open %s\n", filename); - exit(1); - } - - /* alloc image and output buffer */ - outbuf_size = 100000; - outbuf = malloc(outbuf_size); - size = c->width * c->height; - picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ - - picture->data[0] = picture_buf; - picture->data[1] = picture->data[0] + size; - picture->data[2] = picture->data[1] + size / 4; - picture->linesize[0] = c->width; - picture->linesize[1] = c->width / 2; - picture->linesize[2] = c->width / 2; - - /* encode 1 second of video */ - for(i=0;i<25;i++) { - fflush(stdout); - /* prepare a dummy image */ - /* Y */ - for(y=0;y<c->height;y++) { - for(x=0;x<c->width;x++) { - picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; - } - } - - /* Cb and Cr */ - for(y=0;y<c->height/2;y++) { - for(x=0;x<c->width/2;x++) { - picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; - picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; - } - } - - /* encode the image */ - out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); - printf("encoding frame %3d (size=%5d)\n", i, out_size); - fwrite(outbuf, 1, out_size, f); - } - - /* get the delayed frames */ - for(; out_size; i++) { - fflush(stdout); - - out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); - printf("write frame %3d (size=%5d)\n", i, out_size); - fwrite(outbuf, 1, out_size, f); - } - - /* add sequence end code to have a real mpeg file */ - outbuf[0] = 0x00; - outbuf[1] = 0x00; - outbuf[2] = 0x01; - outbuf[3] = 0xb7; - fwrite(outbuf, 1, 4, f); - fclose(f); - free(picture_buf); - free(outbuf); - - avcodec_close(c); - av_free(c); - av_free(picture); - printf("\n"); -} - -/* - * Video decoding example - */ - -static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, - char *filename) -{ - FILE *f; - int i; - - f=fopen(filename,"w"); - fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255); - for(i=0;i<ysize;i++) - fwrite(buf + i * wrap,1,xsize,f); - fclose(f); -} - -static void video_decode_example(const char *outfilename, const char *filename) -{ - AVCodec *codec; - AVCodecContext *c= NULL; - int frame, got_picture, len; - FILE *f; - AVFrame *picture; - uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; - char buf[1024]; - AVPacket avpkt; - - av_init_packet(&avpkt); - - /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ - memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); - - printf("Video decoding\n"); - - /* find the mpeg1 video decoder */ - codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO); - if (!codec) { - fprintf(stderr, "codec not found\n"); - exit(1); - } - - c = avcodec_alloc_context3(codec); - picture= avcodec_alloc_frame(); - - if(codec->capabilities&CODEC_CAP_TRUNCATED) - 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 this information is not - available in the bitstream. */ - - /* open it */ - if (avcodec_open(c, codec) < 0) { - fprintf(stderr, "could not open codec\n"); - exit(1); - } - - /* the codec gives us the frame size, in samples */ - - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "could not open %s\n", filename); - exit(1); - } - - frame = 0; - for(;;) { - avpkt.size = fread(inbuf, 1, INBUF_SIZE, f); - if (avpkt.size == 0) - break; - - /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) - and this is the only method to use them because you cannot - know the compressed data size before analysing it. - - BUT some other codecs (msmpeg4, mpeg4) are inherently frame - based, so you must call them with all the data for one - frame exactly. You must also initialize 'width' and - 'height' before initializing them. */ - - /* NOTE2: some codecs allow the raw parameters (frame size, - sample rate) to be changed at any frame. We handle this, so - you should also take care of it */ - - /* here, we use a stream based decoder (mpeg1video), so we - feed decoder and see if it could decode a frame */ - avpkt.data = inbuf; - while (avpkt.size > 0) { - len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); - if (len < 0) { - fprintf(stderr, "Error while decoding frame %d\n", frame); - exit(1); - } - if (got_picture) { - printf("saving frame %3d\n", frame); - fflush(stdout); - - /* the picture is allocated by the decoder. no need to - free it */ - snprintf(buf, sizeof(buf), outfilename, frame); - pgm_save(picture->data[0], picture->linesize[0], - c->width, c->height, buf); - frame++; - } - avpkt.size -= len; - avpkt.data += len; - } - } - - /* some codecs, such as MPEG, transmit the I and P frame with a - latency of one frame. You must do the following to have a - chance to get the last frame of the video */ - avpkt.data = NULL; - avpkt.size = 0; - len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); - if (got_picture) { - printf("saving last frame %3d\n", frame); - fflush(stdout); - - /* the picture is allocated by the decoder. no need to - free it */ - snprintf(buf, sizeof(buf), outfilename, frame); - pgm_save(picture->data[0], picture->linesize[0], - c->width, c->height, buf); - frame++; - } - - fclose(f); - - avcodec_close(c); - av_free(c); - av_free(picture); - printf("\n"); -} - -int main(int argc, char **argv) -{ - const char *filename; - - /* must be called before using avcodec lib */ - avcodec_init(); - - /* register all the codecs */ - avcodec_register_all(); - - if (argc <= 1) { - audio_encode_example("/tmp/test.mp2"); - audio_decode_example("/tmp/test.sw", "/tmp/test.mp2"); - - video_encode_example("/tmp/test.mpg"); - filename = "/tmp/test.mpg"; - } else { - filename = argv[1]; - } - - // audio_decode_example("/tmp/test.sw", filename); - video_decode_example("/tmp/test%d.pgm", filename); - - return 0; -} diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index e7fa7e511a..0e45bc0a52 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -13,7 +13,8 @@ ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP) += arm/mpegaudiodsp_fixed_armv6.o OBJS-$(CONFIG_VP5_DECODER) += arm/vp56dsp_init_arm.o OBJS-$(CONFIG_VP6_DECODER) += arm/vp56dsp_init_arm.o OBJS-$(CONFIG_VP8_DECODER) += arm/vp8dsp_init_arm.o -ARMV6-OBJS-$(CONFIG_VP8_DECODER) += arm/vp8_armv6.o +ARMV6-OBJS-$(CONFIG_VP8_DECODER) += arm/vp8_armv6.o \ + arm/vp8dsp_armv6.o OBJS-$(CONFIG_H264DSP) += arm/h264dsp_init_arm.o OBJS-$(CONFIG_H264PRED) += arm/h264pred_init_arm.o diff --git a/libavcodec/arm/aac.h b/libavcodec/arm/aac.h index 83b5aef1b6..bd4d293f02 100644 --- a/libavcodec/arm/aac.h +++ b/libavcodec/arm/aac.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/ac3dsp_init_arm.c b/libavcodec/arm/ac3dsp_init_arm.c index aed11f4bb8..8ab685496d 100644 --- a/libavcodec/arm/ac3dsp_init_arm.c +++ b/libavcodec/arm/ac3dsp_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,6 +29,14 @@ void ff_ac3_lshift_int16_neon(int16_t *src, unsigned len, unsigned shift); void ff_ac3_rshift_int32_neon(int32_t *src, unsigned len, unsigned shift); void ff_float_to_fixed24_neon(int32_t *dst, const float *src, unsigned int len); void ff_ac3_extract_exponents_neon(uint8_t *exp, int32_t *coef, int nb_coefs); +void ff_ac3_sum_square_butterfly_int32_neon(int64_t sum[4], + const int32_t *coef0, + const int32_t *coef1, + int len); +void ff_ac3_sum_square_butterfly_float_neon(float sum[4], + const float *coef0, + const float *coef1, + int len); void ff_ac3_bit_alloc_calc_bap_armv6(int16_t *mask, int16_t *psd, int start, int end, @@ -52,5 +60,7 @@ av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact) c->ac3_rshift_int32 = ff_ac3_rshift_int32_neon; c->float_to_fixed24 = ff_float_to_fixed24_neon; c->extract_exponents = ff_ac3_extract_exponents_neon; + c->sum_square_butterfly_int32 = ff_ac3_sum_square_butterfly_int32_neon; + c->sum_square_butterfly_float = ff_ac3_sum_square_butterfly_float_neon; } } diff --git a/libavcodec/arm/ac3dsp_neon.S b/libavcodec/arm/ac3dsp_neon.S index e97197c27a..152afbfd3c 100644 --- a/libavcodec/arm/ac3dsp_neon.S +++ b/libavcodec/arm/ac3dsp_neon.S @@ -108,3 +108,47 @@ function ff_ac3_extract_exponents_neon, export=1 bgt 1b bx lr endfunc + +function ff_ac3_sum_square_butterfly_int32_neon, export=1 + vmov.i64 q0, #0 + vmov.i64 q1, #0 + vmov.i64 q2, #0 + vmov.i64 q3, #0 +1: + vld1.32 {d16}, [r1]! + vld1.32 {d17}, [r2]! + vadd.s32 d18, d16, d17 + vsub.s32 d19, d16, d17 + vmlal.s32 q0, d16, d16 + vmlal.s32 q1, d17, d17 + vmlal.s32 q2, d18, d18 + vmlal.s32 q3, d19, d19 + subs r3, r3, #2 + bgt 1b + vadd.s64 d0, d0, d1 + vadd.s64 d1, d2, d3 + vadd.s64 d2, d4, d5 + vadd.s64 d3, d6, d7 + vst1.64 {q0-q1}, [r0] + bx lr +endfunc + +function ff_ac3_sum_square_butterfly_float_neon, export=1 + vmov.f32 q0, #0.0 + vmov.f32 q1, #0.0 +1: + vld1.32 {d16}, [r1]! + vld1.32 {d17}, [r2]! + vadd.f32 d18, d16, d17 + vsub.f32 d19, d16, d17 + vmla.f32 d0, d16, d16 + vmla.f32 d1, d17, d17 + vmla.f32 d2, d18, d18 + vmla.f32 d3, d19, d19 + subs r3, r3, #2 + bgt 1b + vpadd.f32 d0, d0, d1 + vpadd.f32 d1, d2, d3 + vst1.32 {q0}, [r0] + bx lr +endfunc diff --git a/libavcodec/arm/asm-offsets.h b/libavcodec/arm/asm-offsets.h index 89994569c1..5cfc5cb10c 100644 --- a/libavcodec/arm/asm-offsets.h +++ b/libavcodec/arm/asm-offsets.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/asm.S b/libavcodec/arm/asm.S index 3b495a279f..e540eac9fa 100644 --- a/libavcodec/arm/asm.S +++ b/libavcodec/arm/asm.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -120,6 +120,12 @@ T sub \rn, \rn, \rm T ldr \rt, [\rn] .endm +.macro ldr_dpren rt, rn, rm:vararg +A ldr \rt, [\rn, -\rm] +T sub \rt, \rn, \rm +T ldr \rt, [\rt] +.endm + .macro ldr_post rt, rn, rm:vararg A ldr \rt, [\rn], \rm T ldr \rt, [\rn] @@ -156,6 +162,12 @@ T ldrh \rt, [\rn] T add \rn, \rn, \rm .endm +.macro ldrb_post rt, rn, rm +A ldrb \rt, [\rn], \rm +T ldrb \rt, [\rn] +T add \rn, \rn, \rm +.endm + .macro str_post rt, rn, rm:vararg A str \rt, [\rn], \rm T str \rt, [\rn] diff --git a/libavcodec/arm/dcadsp_init_arm.c b/libavcodec/arm/dcadsp_init_arm.c index b5ac2068d5..5663cd7fc2 100644 --- a/libavcodec/arm/dcadsp_init_arm.c +++ b/libavcodec/arm/dcadsp_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dcadsp_neon.S b/libavcodec/arm/dcadsp_neon.S index 71f5dd843b..852527a59e 100644 --- a/libavcodec/arm/dcadsp_neon.S +++ b/libavcodec/arm/dcadsp_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_arm.S b/libavcodec/arm/dsputil_arm.S index 136551f4c9..1247b0fa84 100644 --- a/libavcodec/arm/dsputil_arm.S +++ b/libavcodec/arm/dsputil_arm.S @@ -2,20 +2,20 @@ @ ARMv4 optimized DSP utils @ Copyright (c) 2004 AGAWA Koji <i (AT) atty (DOT) jp> @ -@ This file is part of Libav. +@ This file is part of FFmpeg. @ -@ Libav is free software; you can redistribute it and/or +@ 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. @ -@ Libav is distributed in the hope that it will be useful, +@ 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 Libav; if not, write to the Free Software +@ 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/libavcodec/arm/dsputil_arm.h b/libavcodec/arm/dsputil_arm.h index 6d7e6a6d16..b333c70226 100644 --- a/libavcodec/arm/dsputil_arm.h +++ b/libavcodec/arm/dsputil_arm.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_armv6.S b/libavcodec/arm/dsputil_armv6.S index becf85182d..1adedf7b8f 100644 --- a/libavcodec/arm/dsputil_armv6.S +++ b/libavcodec/arm/dsputil_armv6.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_init_arm.c b/libavcodec/arm/dsputil_init_arm.c index 743be1a239..ccbe1ed296 100644 --- a/libavcodec/arm/dsputil_init_arm.c +++ b/libavcodec/arm/dsputil_init_arm.c @@ -2,20 +2,20 @@ * ARM optimized DSP utils * Copyright (c) 2001 Lionel Ulmer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_init_armv5te.c b/libavcodec/arm/dsputil_init_armv5te.c index e0224dabfb..2390aabb62 100644 --- a/libavcodec/arm/dsputil_init_armv5te.c +++ b/libavcodec/arm/dsputil_init_armv5te.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_init_armv6.c b/libavcodec/arm/dsputil_init_armv6.c index eff4ee38c2..fb0d00973e 100644 --- a/libavcodec/arm/dsputil_init_armv6.c +++ b/libavcodec/arm/dsputil_init_armv6.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_init_neon.c b/libavcodec/arm/dsputil_init_neon.c index 68e5b3ed42..3f4dcdad5c 100644 --- a/libavcodec/arm/dsputil_init_neon.c +++ b/libavcodec/arm/dsputil_init_neon.c @@ -2,20 +2,20 @@ * ARM NEON optimised DSP functions * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/arm/dsputil_init_vfp.c index 9cda890411..ee092dca10 100644 --- a/libavcodec/arm/dsputil_init_vfp.c +++ b/libavcodec/arm/dsputil_init_vfp.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_iwmmxt.c b/libavcodec/arm/dsputil_iwmmxt.c index dec5d77472..2837af119f 100644 --- a/libavcodec/arm/dsputil_iwmmxt.c +++ b/libavcodec/arm/dsputil_iwmmxt.c @@ -2,20 +2,20 @@ * iWMMXt optimized DSP utils * Copyright (c) 2004 AGAWA Koji * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_iwmmxt_rnd_template.c b/libavcodec/arm/dsputil_iwmmxt_rnd_template.c index df0ead6d80..35a5a9b8b4 100644 --- a/libavcodec/arm/dsputil_iwmmxt_rnd_template.c +++ b/libavcodec/arm/dsputil_iwmmxt_rnd_template.c @@ -2,20 +2,20 @@ * iWMMXt optimized DSP utils * copyright (c) 2004 AGAWA Koji * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S index d49aedd6c4..c660cb0d4c 100644 --- a/libavcodec/arm/dsputil_neon.S +++ b/libavcodec/arm/dsputil_neon.S @@ -2,20 +2,20 @@ * ARM NEON optimised DSP functions * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/dsputil_vfp.S b/libavcodec/arm/dsputil_vfp.S index cbc4bd6c70..108208174d 100644 --- a/libavcodec/arm/dsputil_vfp.S +++ b/libavcodec/arm/dsputil_vfp.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/fft_fixed_init_arm.c b/libavcodec/arm/fft_fixed_init_arm.c index be412cde05..df71e7fe09 100644 --- a/libavcodec/arm/fft_fixed_init_arm.c +++ b/libavcodec/arm/fft_fixed_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/fft_fixed_neon.S b/libavcodec/arm/fft_fixed_neon.S index 0508088590..0316b80bce 100644 --- a/libavcodec/arm/fft_fixed_neon.S +++ b/libavcodec/arm/fft_fixed_neon.S @@ -122,7 +122,7 @@ endfunc function fft_pass_neon push {r4,lr} - movrel lr, coefs + 24 + movrel lr, coefs+24 vld1.16 {d30}, [lr,:64] lsl r12, r2, #3 vmov d31, d30 diff --git a/libavcodec/arm/fft_init_arm.c b/libavcodec/arm/fft_init_arm.c index b2c3b721fd..cdb64e7404 100644 --- a/libavcodec/arm/fft_init_arm.c +++ b/libavcodec/arm/fft_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/fft_neon.S b/libavcodec/arm/fft_neon.S index a45898592e..ef8e4d4210 100644 --- a/libavcodec/arm/fft_neon.S +++ b/libavcodec/arm/fft_neon.S @@ -7,20 +7,20 @@ * This algorithm (though not any of the implementation details) is * based on libdjbfft by D. J. Bernstein. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/fmtconvert_init_arm.c b/libavcodec/arm/fmtconvert_init_arm.c index 92e07f17a0..4b6e3939f5 100644 --- a/libavcodec/arm/fmtconvert_init_arm.c +++ b/libavcodec/arm/fmtconvert_init_arm.c @@ -1,20 +1,20 @@ /* * ARM optimized Format Conversion Utils * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/fmtconvert_neon.S b/libavcodec/arm/fmtconvert_neon.S index ad1c15d0fa..17af9f524a 100644 --- a/libavcodec/arm/fmtconvert_neon.S +++ b/libavcodec/arm/fmtconvert_neon.S @@ -2,20 +2,20 @@ * ARM NEON optimised Format Conversion Utils * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/fmtconvert_vfp.S b/libavcodec/arm/fmtconvert_vfp.S index f7b0e3dcb5..7e2eb83620 100644 --- a/libavcodec/arm/fmtconvert_vfp.S +++ b/libavcodec/arm/fmtconvert_vfp.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/h264dsp_init_arm.c b/libavcodec/arm/h264dsp_init_arm.c index 1c331a495d..cc4c688c8b 100644 --- a/libavcodec/arm/h264dsp_init_arm.c +++ b/libavcodec/arm/h264dsp_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -72,8 +72,10 @@ static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth, const i if (bit_depth == 8) { c->h264_v_loop_filter_luma = ff_h264_v_loop_filter_luma_neon; c->h264_h_loop_filter_luma = ff_h264_h_loop_filter_luma_neon; + if(chroma_format_idc == 1){ c->h264_v_loop_filter_chroma = ff_h264_v_loop_filter_chroma_neon; c->h264_h_loop_filter_chroma = ff_h264_h_loop_filter_chroma_neon; + } c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels_16_neon; c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels_8_neon; diff --git a/libavcodec/arm/h264dsp_neon.S b/libavcodec/arm/h264dsp_neon.S index a4abf66494..fc6b3b35d5 100644 --- a/libavcodec/arm/h264dsp_neon.S +++ b/libavcodec/arm/h264dsp_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/h264idct_neon.S b/libavcodec/arm/h264idct_neon.S index edb2ae5270..49b301247f 100644 --- a/libavcodec/arm/h264idct_neon.S +++ b/libavcodec/arm/h264idct_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/h264pred_init_arm.c b/libavcodec/arm/h264pred_init_arm.c index 5fc07bc137..75653ff7a5 100644 --- a/libavcodec/arm/h264pred_init_arm.c +++ b/libavcodec/arm/h264pred_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -48,7 +48,7 @@ static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const int b if (high_depth) return; - + if(chroma_format_idc == 1){ h->pred8x8[VERT_PRED8x8 ] = ff_pred8x8_vert_neon; h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_hor_neon; if (codec_id != CODEC_ID_VP8) @@ -63,6 +63,7 @@ static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const int b h->pred8x8[ALZHEIMER_DC_L00_PRED8x8] = ff_pred8x8_l00_dc_neon; h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8] = ff_pred8x8_0l0_dc_neon; } + } h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_neon; h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vert_neon; diff --git a/libavcodec/arm/h264pred_neon.S b/libavcodec/arm/h264pred_neon.S index 815b67b81f..0dac20b4a0 100644 --- a/libavcodec/arm/h264pred_neon.S +++ b/libavcodec/arm/h264pred_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/int_neon.S b/libavcodec/arm/int_neon.S index 8bb58afb18..e1353982d0 100644 --- a/libavcodec/arm/int_neon.S +++ b/libavcodec/arm/int_neon.S @@ -2,20 +2,20 @@ * ARM NEON optimised integer operations * Copyright (c) 2009 Kostya Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/mathops.h b/libavcodec/arm/mathops.h index 3803fcde8c..d67714c496 100644 --- a/libavcodec/arm/mathops.h +++ b/libavcodec/arm/mathops.h @@ -2,20 +2,20 @@ * simple math operations * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/mdct_neon.S b/libavcodec/arm/mdct_neon.S index 5669075521..9b7dc6ce83 100644 --- a/libavcodec/arm/mdct_neon.S +++ b/libavcodec/arm/mdct_neon.S @@ -2,20 +2,20 @@ * ARM NEON optimised MDCT * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/mpegvideo_arm.c b/libavcodec/arm/mpegvideo_arm.c index b1d1312943..6cb1bc8582 100644 --- a/libavcodec/arm/mpegvideo_arm.c +++ b/libavcodec/arm/mpegvideo_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2002 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/mpegvideo_arm.h b/libavcodec/arm/mpegvideo_arm.h index a36da6112b..3549bb244b 100644 --- a/libavcodec/arm/mpegvideo_arm.h +++ b/libavcodec/arm/mpegvideo_arm.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/mpegvideo_armv5te.c b/libavcodec/arm/mpegvideo_armv5te.c index 30197d8bc1..1d383cae1e 100644 --- a/libavcodec/arm/mpegvideo_armv5te.c +++ b/libavcodec/arm/mpegvideo_armv5te.c @@ -2,20 +2,20 @@ * Optimization of some functions from mpegvideo.c for armv5te * Copyright (c) 2007 Siarhei Siamashka <ssvb@users.sourceforge.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/mpegvideo_armv5te_s.S b/libavcodec/arm/mpegvideo_armv5te_s.S index 952c8d74cb..3db9c734e9 100644 --- a/libavcodec/arm/mpegvideo_armv5te_s.S +++ b/libavcodec/arm/mpegvideo_armv5te_s.S @@ -2,20 +2,20 @@ * Optimization of some functions from mpegvideo.c for armv5te * Copyright (c) 2007 Siarhei Siamashka <ssvb@users.sourceforge.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/mpegvideo_iwmmxt.c b/libavcodec/arm/mpegvideo_iwmmxt.c index 6edc4c2ea6..bb47c0d321 100644 --- a/libavcodec/arm/mpegvideo_iwmmxt.c +++ b/libavcodec/arm/mpegvideo_iwmmxt.c @@ -1,20 +1,20 @@ /* * copyright (c) 2004 AGAWA Koji * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/mpegvideo_neon.S b/libavcodec/arm/mpegvideo_neon.S index 206a71a14d..849047e13c 100644 --- a/libavcodec/arm/mpegvideo_neon.S +++ b/libavcodec/arm/mpegvideo_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/rdft_neon.S b/libavcodec/arm/rdft_neon.S index fba275eb8c..19886e6d0b 100644 --- a/libavcodec/arm/rdft_neon.S +++ b/libavcodec/arm/rdft_neon.S @@ -2,20 +2,20 @@ * ARM NEON optimised RDFT * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/simple_idct_arm.S b/libavcodec/arm/simple_idct_arm.S index a9c3095157..1d3e9175cc 100644 --- a/libavcodec/arm/simple_idct_arm.S +++ b/libavcodec/arm/simple_idct_arm.S @@ -4,22 +4,22 @@ * 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 Libav project. + * from the libavcodec library part of the FFmpeg project. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/simple_idct_armv5te.S b/libavcodec/arm/simple_idct_armv5te.S index 24641e47b6..71727ceccc 100644 --- a/libavcodec/arm/simple_idct_armv5te.S +++ b/libavcodec/arm/simple_idct_armv5te.S @@ -4,20 +4,20 @@ * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2006 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/simple_idct_armv6.S b/libavcodec/arm/simple_idct_armv6.S index 284eb1f941..a176b3a7b4 100644 --- a/libavcodec/arm/simple_idct_armv6.S +++ b/libavcodec/arm/simple_idct_armv6.S @@ -4,20 +4,20 @@ * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2007 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/simple_idct_neon.S b/libavcodec/arm/simple_idct_neon.S index 0c4e05d869..5df8f6e4fc 100644 --- a/libavcodec/arm/simple_idct_neon.S +++ b/libavcodec/arm/simple_idct_neon.S @@ -6,20 +6,20 @@ * Based on Simple IDCT * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/synth_filter_neon.S b/libavcodec/arm/synth_filter_neon.S index 1d6e5b2b86..3f91d67506 100644 --- a/libavcodec/arm/synth_filter_neon.S +++ b/libavcodec/arm/synth_filter_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/vp3dsp_neon.S b/libavcodec/arm/vp3dsp_neon.S index 279b13225b..ae3e40201a 100644 --- a/libavcodec/arm/vp3dsp_neon.S +++ b/libavcodec/arm/vp3dsp_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 David Conrad * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/vp56_arith.h b/libavcodec/arm/vp56_arith.h index ef30ffe897..ece9ac2a6c 100644 --- a/libavcodec/arm/vp56_arith.h +++ b/libavcodec/arm/vp56_arith.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/vp56dsp_init_arm.c b/libavcodec/arm/vp56dsp_init_arm.c index 598960251a..ceab9a87d2 100644 --- a/libavcodec/arm/vp56dsp_init_arm.c +++ b/libavcodec/arm/vp56dsp_init_arm.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/vp56dsp_neon.S b/libavcodec/arm/vp56dsp_neon.S index b95d8ab28b..0353661009 100644 --- a/libavcodec/arm/vp56dsp_neon.S +++ b/libavcodec/arm/vp56dsp_neon.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/vp8.h b/libavcodec/arm/vp8.h index fc6523e690..5a7b142690 100644 --- a/libavcodec/arm/vp8.h +++ b/libavcodec/arm/vp8.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/vp8_armv6.S b/libavcodec/arm/vp8_armv6.S index c9dc30b46d..9399bb28d7 100644 --- a/libavcodec/arm/vp8_armv6.S +++ b/libavcodec/arm/vp8_armv6.S @@ -1,20 +1,20 @@ /* * Copyright (C) 2010 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/arm/vp8dsp_armv6.S b/libavcodec/arm/vp8dsp_armv6.S new file mode 100644 index 0000000000..4e7b78361e --- /dev/null +++ b/libavcodec/arm/vp8dsp_armv6.S @@ -0,0 +1,2328 @@ +/** + * VP8 ARMv6 optimisations + * + * Copyright (c) 2011 The WebM project authors. All Rights Reserved. + * Copyright (c) 2010 Rob Clark <rob@ti.com> + * Copyright (c) 2011 Mans Rullgard <mans@mansr.com> + * + * This file is part of Libav. + * + * Libav 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. + * + * Libav 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 Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * This code was partially ported from libvpx, which uses this license: + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + * + * (Note that the "LICENSE", "AUTHORS" and "PATENTS" files can be + * found in the libvpx source tree.) + */ + +#include "asm.S" + +@ idct + +@ void vp8_luma_dc_wht(DCTELEM block[4][4][16], DCTELEM dc[16]) +function ff_vp8_luma_dc_wht_armv6, export=1 + push {r4 - r10, lr} + + @ load dc[] and zero memory + mov r12, #0 + ldr r2, [r1] @ dc0[0,1] + ldr r3, [r1, #4] @ dc0[2,3] + ldr r4, [r1, #8] @ dc1[0,1] + ldr r5, [r1, #12] @ dc1[2,3] + ldr r6, [r1, #16] @ dc2[0,1] + ldr r7, [r1, #20] @ dc2[2,3] + ldr r8, [r1, #24] @ dc3[0,1] + ldr r9, [r1, #28] @ dc3[2,3] + str r12,[r1] + str r12,[r1, #4] + str r12,[r1, #8] + str r12,[r1, #12] + str r12,[r1, #16] + str r12,[r1, #20] + str r12,[r1, #24] + str r12,[r1, #28] + + @ loop1 + uadd16 r12, r2, r8 @ t0[0,1] + uadd16 r14, r3, r9 @ t0[2,3] + usub16 r2, r2, r8 @ t3[0,1] + usub16 r3, r3, r9 @ t3[2,3] + uadd16 r8, r4, r6 @ t1[0,1] + uadd16 r9, r5, r7 @ t1[2,3] + usub16 r4, r4, r6 @ t2[0,1] + usub16 r5, r5, r7 @ t2[2,3] + + uadd16 r6, r12, r8 @ dc0[0,1] + uadd16 r7, r14, r9 @ dc0[2,3] + usub16 r12, r12, r8 @ dc2[0,1] + usub16 r14, r14, r9 @ dc2[2,3] + uadd16 r8, r2, r4 @ dc1[0,1] + uadd16 r9, r3, r5 @ dc1[2,3] + usub16 r2, r2, r4 @ dc3[0,1] + usub16 r3, r3, r5 @ dc3[2,3] + + mov r1, #3 + orr r1, r1, #0x30000 @ 3 | 3 (round) + + @ "transpose" + pkhbt r4, r6, r8, lsl #16 @ dc{0,1}[0] + pkhtb r6, r8, r6, asr #16 @ dc{0,1}[1] + pkhbt r5, r12, r2, lsl #16 @ dc{2,3}[0] + pkhtb r12, r2, r12, asr #16 @ dc{2,3}[1] + pkhbt r8, r7, r9, lsl #16 @ dc{0,1}[2] + uadd16 r4, r4, r1 + uadd16 r5, r5, r1 + pkhtb r7, r9, r7, asr #16 @ dc{0,1}[3] + pkhbt r2, r14, r3, lsl #16 @ dc{2,3}[2] + pkhtb r14, r3, r14, asr #16 @ dc{2,3}[3] + + @ loop2 + uadd16 r9, r4, r7 @ t0[0,1] + uadd16 r3, r5, r14 @ t0[2,3] + usub16 r4, r4, r7 @ t3[0,1] + usub16 r5, r5, r14 @ t3[2,3] + uadd16 r7, r6, r8 @ t1[0,1] + uadd16 r14, r12, r2 @ t1[2,3] + usub16 r6, r6, r8 @ t2[0,1] + usub16 r12, r12, r2 @ t2[2,3] + + uadd16 r8, r9, r7 @ block[0,1][0] + uadd16 r2, r3, r14 @ block[2,3][0] + usub16 r9, r9, r7 @ block[0,1][2] + usub16 r3, r3, r14 @ block[2,3][2] + uadd16 r7, r4, r6 @ block[0,1][1] + uadd16 r14, r5, r12 @ block[2,3][1] + usub16 r4, r4, r6 @ block[0,1][3] + usub16 r5, r5, r12 @ block[2,3][3] + + @ store + mov r6, r8, asr #19 @ block[1][0] + mov r12, r7, asr #19 @ block[1][1] + mov r1, r9, asr #19 @ block[1][2] + mov r10, r4, asr #19 @ block[1][3] + sxth r8, r8 + sxth r7, r7 + sxth r9, r9 + sxth r4, r4 + asr r8, #3 @ block[0][0] + asr r7, #3 @ block[0][1] + asr r9, #3 @ block[0][2] + asr r4, #3 @ block[0][3] + + strh r8, [r0], #32 + strh r7, [r0], #32 + strh r9, [r0], #32 + strh r4, [r0], #32 + strh r6, [r0], #32 + strh r12,[r0], #32 + strh r1, [r0], #32 + strh r10,[r0], #32 + + mov r6, r2, asr #19 @ block[3][0] + mov r12, r14, asr #19 @ block[3][1] + mov r1, r3, asr #19 @ block[3][2] + mov r10, r5, asr #19 @ block[3][3] + sxth r2, r2 + sxth r14, r14 + sxth r3, r3 + sxth r5, r5 + asr r2, #3 @ block[2][0] + asr r14, #3 @ block[2][1] + asr r3, #3 @ block[2][2] + asr r5, #3 @ block[2][3] + + strh r2, [r0], #32 + strh r14,[r0], #32 + strh r3, [r0], #32 + strh r5, [r0], #32 + strh r6, [r0], #32 + strh r12,[r0], #32 + strh r1, [r0], #32 + strh r10,[r0], #32 + + pop {r4 - r10, pc} +endfunc + +@ void vp8_luma_dc_wht_dc(DCTELEM block[4][4][16], DCTELEM dc[16]) +function ff_vp8_luma_dc_wht_dc_armv6, export=1 + ldrsh r2, [r1] + mov r3, #0 + add r2, r2, #3 + strh r3, [r1] + asr r2, r2, #3 + .rept 16 + strh r2, [r0], #32 + .endr + bx lr +endfunc + +@ void vp8_idct_add(uint8_t *dst, DCTELEM block[16], int stride) +function ff_vp8_idct_add_armv6, export=1 + push {r4 - r11, lr} + sub sp, sp, #32 + + mov r3, #0x00004E00 @ cos + orr r3, r3, #0x0000007B @ cospi8sqrt2minus1 = 20091 + mov r4, #0x00008A00 @ sin + orr r4, r4, #0x0000008C @ sinpi8sqrt2 = 35468 + mov r5, #0x2 @ i=2 +1: + ldr r6, [r1, #8] @ i5 | i4 = block1[1] | block1[0] + ldr r12,[r1, #24] @ i13 | i12 = block3[1] | block3[0] + ldr r14,[r1, #16] @ i9 | i8 = block2[1] | block2[0] + + smulwt r9, r3, r6 @ (ip[5] * cospi8sqrt2minus1) >> 16 + smulwb r7, r3, r6 @ (ip[4] * cospi8sqrt2minus1) >> 16 + smulwt r10, r4, r6 @ (ip[5] * sinpi8sqrt2) >> 16 + smulwb r8, r4, r6 @ (ip[4] * sinpi8sqrt2) >> 16 + pkhbt r7, r7, r9, lsl #16 @ 5c | 4c + smulwt r11, r3, r12 @ (ip[13] * cospi8sqrt2minus1) >> 16 + pkhbt r8, r8, r10, lsl #16 @ 5s | 4s = t2 first half + uadd16 r6, r6, r7 @ 5c+5 | 4c+4 = t3 first half + smulwt r7, r4, r12 @ (ip[13] * sinpi8sqrt2) >> 16 + smulwb r9, r3, r12 @ (ip[12] * cospi8sqrt2minus1) >> 16 + smulwb r10, r4, r12 @ (ip[12] * sinpi8sqrt2) >> 16 + + subs r5, r5, #1 @ i-- + pkhbt r9, r9, r11, lsl #16 @ 13c | 12c + ldr r11,[r1] @ i1 | i0 + pkhbt r10, r10, r7, lsl #16 @ 13s | 12s = t3 second half + uadd16 r7, r12, r9 @ 13c+13 | 12c+12 = t2 second half + usub16 r7, r8, r7 @ c = t2 + uadd16 r6, r6, r10 @ d = t3 + uadd16 r10, r11, r14 @ a = t0 + usub16 r8, r11, r14 @ b = t1 + uadd16 r9, r10, r6 @ a+d = tmp{0,1}[0] + usub16 r10, r10, r6 @ a-d = tmp{0,1}[3] + uadd16 r6, r8, r7 @ b+c = tmp{0,1}[1] + usub16 r7, r8, r7 @ b-c = tmp{0,1}[2] + mov r8, #0 + str r6, [sp, #8] @ o5 | o4 + str r7, [sp, #16] @ o9 | o8 + str r10,[sp, #24] @ o13 | o12 + str r9, [sp], #4 @ o1 | o0 + str r8, [r1, #24] + str r8, [r1, #16] + str r8, [r1, #8] + str r8, [r1], #4 + bne 1b + + mov r5, #0x2 @ i=2 + sub sp, sp, #8 +2: + ldr r6, [sp, #8] @ i5 | i4 = tmp{0,1}[1] + ldr r14,[sp, #4] @ i3 | i2 = tmp{2,3}[0] + ldr r12,[sp, #12] @ i7 | i6 = tmp{2,3}[1] + ldr r1, [sp], #16 @ i1 | i0 = tmp{0,1}[0] + smulwt r9, r3, r6 @ (ip[5] * cospi8sqrt2minus1) >> 16 + smulwt r7, r3, r1 @ (ip[1] * cospi8sqrt2minus1) >> 16 + smulwt r10, r4, r6 @ (ip[5] * sinpi8sqrt2) >> 16 + smulwt r8, r4, r1 @ (ip[1] * sinpi8sqrt2) >> 16 + pkhbt r11, r1, r6, lsl #16 @ i4 | i0 = t0/t1 first half + pkhbt r7, r7, r9, lsl #16 @ 5c | 1c + pkhbt r8, r8, r10, lsl #16 @ 5s | 1s = temp1 = t2 first half + pkhtb r1, r6, r1, asr #16 @ i5 | i1 + uadd16 r1, r7, r1 @ 5c+5 | 1c+1 = temp2 (d) = t3 first half + pkhbt r9, r14, r12, lsl #16 @ i6 | i2 = t0/t1 second half + uadd16 r10, r11, r9 @ a = t0 + usub16 r9, r11, r9 @ b = t1 + pkhtb r6, r12, r14, asr #16 @ i7 | i3 + subs r5, r5, #0x1 @ i-- + smulwt r7, r3, r6 @ (ip[7] * cospi8sqrt2minus1) >> 16 + smulwt r11, r4, r6 @ (ip[7] * sinpi8sqrt2) >> 16 + smulwb r12, r3, r6 @ (ip[3] * cospi8sqrt2minus1) >> 16 + smulwb r14, r4, r6 @ (ip[3] * sinpi8sqrt2) >> 16 + + pkhbt r7, r12, r7, lsl #16 @ 7c | 3c + pkhbt r11, r14, r11, lsl #16 @ 7s | 3s = temp1 (d) = t3 second half + mov r14, #0x4 @ set up 4's + orr r14, r14, #0x40000 @ 4|4 + uadd16 r6, r7, r6 @ 7c+7 | 3c+3 = temp2 (c) = t2 second half + usub16 r12, r8, r6 @ c (o5 | o1) = t2 + uadd16 r6, r11, r1 @ d (o7 | o3) = t3 + uadd16 r10, r10, r14 @ t0 + 4 + uadd16 r9, r9, r14 @ t1 + 4 + uadd16 r7, r10, r6 @ a+d = dst{0,1}[0] + usub16 r6, r10, r6 @ a-d = dst{0,1}[3] + uadd16 r10, r9, r12 @ b+c = dst{0,1}[1] + usub16 r1, r9, r12 @ b-c = dst{0,1}[2] + + mov r9, r6, asr #3 @ o[1][3] + mov r12, r1, asr #3 @ o[1][2] + pkhtb r8, r12, r7, asr #19 @ o[1][0,2] + pkhtb r11, r9, r10, asr #19 @ o[1][1,3] + ldr r12,[r0] + ldr r9, [r0, r2] + sxth r7, r7 + sxth r6, r6 + sxth r10, r10 + sxth r1, r1 + asr r7, #3 @ o[0][0] + asr r10, #3 @ o[0][1] + pkhbt r7, r7, r1, lsl #13 @ o[0][0,2] + pkhbt r10, r10, r6, lsl #13 @ o[0][1,3] + + uxtab16 r7, r7, r12 + uxtab16 r10, r10, r12, ror #8 + uxtab16 r8, r8, r9 + uxtab16 r11, r11, r9, ror #8 + usat16 r7, #8, r7 + usat16 r10, #8, r10 + usat16 r8, #8, r8 + usat16 r11, #8, r11 + orr r7, r7, r10, lsl #8 + orr r8, r8, r11, lsl #8 + str r8, [r0, r2] + str_post r7, r0, r2, lsl #1 + + bne 2b + + pop {r4 - r11, pc} +endfunc + +@ void vp8_idct_dc_add(uint8_t *dst, DCTELEM block[16], int stride) +function ff_vp8_idct_dc_add_armv6, export=1 + push {r4 - r5, lr} + ldrsh r3, [r1] + mov r4, #0 + add r3, r3, #4 + asr r3, #3 + strh r4, [r1], #32 + ldr r4, [r0, r2] + ldr_post r5, r0, r2, lsl #1 + pkhbt r3, r3, r3, lsl #16 + + uxtab16 lr, r3, r5 @ a1+2 | a1+0 + uxtab16 r5, r3, r5, ror #8 @ a1+3 | a1+1 + uxtab16 r12, r3, r4 + uxtab16 r4, r3, r4, ror #8 + usat16 lr, #8, lr + usat16 r5, #8, r5 + usat16 r12, #8, r12 + usat16 r4, #8, r4 + orr lr, lr, r5, lsl #8 + orr r12, r12, r4, lsl #8 + ldr r5, [r0] + ldr r4, [r0, r2] + sub r0, r0, r2, lsl #1 + str r12,[r0, r2] + str_post lr, r0, r2, lsl #1 + + uxtab16 lr, r3, r5 + uxtab16 r5, r3, r5, ror #8 + uxtab16 r12, r3, r4 + uxtab16 r4, r3, r4, ror #8 + usat16 lr, #8, lr + usat16 r5, #8, r5 + usat16 r12, #8, r12 + usat16 r4, #8, r4 + orr lr, lr, r5, lsl #8 + orr r12, r12, r4, lsl #8 + + str r12,[r0, r2] + str_post lr, r0, r2, lsl #1 + + pop {r4 - r5, pc} +endfunc + +@ void vp8_idct_dc_add4uv(uint8_t *dst, DCTELEM block[4][16], int stride) +function ff_vp8_idct_dc_add4uv_armv6, export=1 + push {lr} + + bl ff_vp8_idct_dc_add_armv6 + sub r0, r0, r2, lsl #2 + add r0, r0, #4 + bl ff_vp8_idct_dc_add_armv6 + sub r0, r0, #4 + bl ff_vp8_idct_dc_add_armv6 + sub r0, r0, r2, lsl #2 + add r0, r0, #4 + bl ff_vp8_idct_dc_add_armv6 + + pop {pc} +endfunc + +@ void vp8_idct_dc_add4y(uint8_t *dst, DCTELEM block[4][16], int stride) +function ff_vp8_idct_dc_add4y_armv6, export=1 + push {lr} + + bl ff_vp8_idct_dc_add_armv6 + sub r0, r0, r2, lsl #2 + add r0, r0, #4 + bl ff_vp8_idct_dc_add_armv6 + sub r0, r0, r2, lsl #2 + add r0, r0, #4 + bl ff_vp8_idct_dc_add_armv6 + sub r0, r0, r2, lsl #2 + add r0, r0, #4 + bl ff_vp8_idct_dc_add_armv6 + + pop {pc} +endfunc + +@ loopfilter + +@ void vp8_v_loop_filter16_simple(uint8_t *dst, int stride, int flim) +function ff_vp8_v_loop_filter16_simple_armv6, export=1 + push {r4 - r11, lr} + + ldr_dpren r3, r0, r1, lsl #1 @ p1 + ldr_dpren r4, r0, r1 @ p0 + ldr r5, [r0] @ q0 + ldr r6, [r0, r1] @ q1 + orr r2, r2, r2, lsl #16 + mov r9, #4 @ count + mov lr, #0 @ need 0 in a couple places + orr r12, r2, r2, lsl #8 @ splat int -> byte + ldr r2, c0x80808080 + +1: + @ vp8_simple_filter_mask() + uqsub8 r7, r3, r6 @ p1 - q1 + uqsub8 r8, r6, r3 @ q1 - p1 + uqsub8 r10, r4, r5 @ p0 - q0 + uqsub8 r11, r5, r4 @ q0 - p0 + orr r8, r8, r7 @ abs(p1 - q1) + orr r10, r10, r11 @ abs(p0 - q0) + uqadd8 r10, r10, r10 @ abs(p0 - q0) * 2 + uhadd8 r8, r8, lr @ abs(p1 - q2) >> 1 + uqadd8 r10, r10, r8 @ abs(p0 - q0)*2 + abs(p1 - q1)/2 + mvn r8, #0 + usub8 r10, r12, r10 @ compare to flimit. usub8 sets GE flags + sel r10, r8, lr @ filter mask: F or 0 + cmp r10, #0 + beq 2f @ skip filtering if all masks are 0x00 + + @ vp8_simple_filter() + eor r3, r3, r2 @ p1 offset to convert to a signed value + eor r6, r6, r2 @ q1 offset to convert to a signed value + eor r4, r4, r2 @ p0 offset to convert to a signed value + eor r5, r5, r2 @ q0 offset to convert to a signed value + + qsub8 r3, r3, r6 @ vp8_filter = p1 - q1 + qsub8 r6, r5, r4 @ q0 - p0 + qadd8 r3, r3, r6 @ += q0 - p0 + ldr r7, c0x04040404 + qadd8 r3, r3, r6 @ += q0 - p0 + ldr r8, c0x03030303 + qadd8 r3, r3, r6 @ vp8_filter = p1-q1 + 3*(q0-p0)) + @STALL + and r3, r3, r10 @ vp8_filter &= mask + + qadd8 r7, r3, r7 @ Filter1 = vp8_filter + 4 + qadd8 r8, r3, r8 @ Filter2 = vp8_filter + 3 + + shadd8 r7, r7, lr + shadd8 r8, r8, lr + shadd8 r7, r7, lr + shadd8 r8, r8, lr + shadd8 r7, r7, lr @ Filter1 >>= 3 + shadd8 r8, r8, lr @ Filter2 >>= 3 + + qsub8 r5, r5, r7 @ u = q0 - Filter1 + qadd8 r4, r4, r8 @ u = p0 + Filter2 + eor r5, r5, r2 @ *oq0 = u^0x80 + eor r4, r4, r2 @ *op0 = u^0x80 +T sub r7, r0, r1 + str r5, [r0] @ store oq0 result +A str r4, [r0, -r1] @ store op0 result +T str r4, [r7] + +2: + subs r9, r9, #1 @ counter-- + add r0, r0, #4 @ next row +T itttt ne +A ldrne r3, [r0, -r1, lsl #1] @ p1 +T subne r3, r0, r1, lsl #1 +T ldrne r3, [r3] @ p1 +A ldrne r4, [r0, -r1] @ p0 +T subne r4, r0, r1 +T ldrne r4, [r4] @ p0 +T itt ne + ldrne r5, [r0] @ q0 + ldrne r6, [r0, r1] @ q1 + + bne 1b + + pop {r4 - r11, pc} +endfunc + +c0x01010101: .long 0x01010101 +c0x03030303: .long 0x03030303 +c0x04040404: .long 0x04040404 +c0x7F7F7F7F: .long 0x7F7F7F7F +c0x80808080: .long 0x80808080 + +@ void vp8_v_loop_filter16_inner(uint8_t *dst, int stride, +@ int fE, int fI, int hev_thresh) +@ and +@ void vp8_v_loop_filter8uv_inner(uint8_t *dstU, uint8_t *dstV, int stride, +@ int fE, int fI, int hev_thresh) +@ call: +@ void vp8_v_loop_filter_inner(uint8_t *dst, int stride, +@ int fE, int fI, int hev_thresh, int count) +function ff_vp8_v_loop_filter_inner_armv6, export=1 + push {r4 - r11, lr} + + sub r0, r0, r1, lsl #2 @ move r0 pointer down by 4 lines + ldr r5, [sp, #40] @ counter + ldr r6, [sp, #36] @ load thresh address + sub sp, sp, #16 @ create temp buffer + + ldr r10,[r0, r1] @ p2 + ldr_post r9, r0, r1, lsl #1 @ p3 + ldr r12,[r0, r1] @ p0 + ldr_post r11, r0, r1, lsl #1 @ p1 + + orr r2, r2, r2, lsl #16 + orr r3, r3, r3, lsl #16 + orr r6, r6, r6, lsl #16 + orr r4, r2, r2, lsl #8 @ flimE splat int -> byte + orr r2, r3, r3, lsl #8 @ flimI splat int -> byte + orr r3, r6, r6, lsl #8 @ thresh splat int -> byte + +1: + @ vp8_filter_mask() function + @ calculate breakout conditions + uqsub8 r6, r9, r10 @ p3 - p2 + uqsub8 r7, r10, r9 @ p2 - p3 + uqsub8 r8, r10, r11 @ p2 - p1 + uqsub8 r10, r11, r10 @ p1 - p2 + + orr r6, r6, r7 @ abs (p3-p2) + orr r8, r8, r10 @ abs (p2-p1) + uqsub8 lr, r6, r2 @ compare to limit. lr: vp8_filter_mask + uqsub8 r8, r8, r2 @ compare to limit + uqsub8 r6, r11, r12 @ p1 - p0 + orr lr, lr, r8 + uqsub8 r7, r12, r11 @ p0 - p1 + ldr r10,[r0, r1] @ q1 + ldr_post r9, r0, r1, lsl #1 @ q0 + orr r6, r6, r7 @ abs (p1-p0) + uqsub8 r7, r6, r2 @ compare to limit + uqsub8 r8, r6, r3 @ compare to thresh -- save r8 for later + orr lr, lr, r7 + + uqsub8 r6, r11, r10 @ p1 - q1 + uqsub8 r7, r10, r11 @ q1 - p1 + uqsub8 r11, r12, r9 @ p0 - q0 + uqsub8 r12, r9, r12 @ q0 - p0 + orr r6, r6, r7 @ abs (p1-q1) + ldr r7, c0x7F7F7F7F + orr r12, r11, r12 @ abs (p0-q0) + ldr_post r11, r0, r1 @ q2 + uqadd8 r12, r12, r12 @ abs (p0-q0) * 2 + and r6, r7, r6, lsr #1 @ abs (p1-q1) / 2 + uqsub8 r7, r9, r10 @ q0 - q1 + uqadd8 r12, r12, r6 @ abs (p0-q0)*2 + abs (p1-q1)/2 + uqsub8 r6, r10, r9 @ q1 - q0 + uqsub8 r12, r12, r4 @ compare to flimit + uqsub8 r9, r11, r10 @ q2 - q1 + + orr lr, lr, r12 + + ldr_post r12, r0, r1 @ q3 + uqsub8 r10, r10, r11 @ q1 - q2 + orr r6, r7, r6 @ abs (q1-q0) + orr r10, r9, r10 @ abs (q2-q1) + uqsub8 r7, r6, r2 @ compare to limit + uqsub8 r10, r10, r2 @ compare to limit + uqsub8 r6, r6, r3 @ compare to thresh -- save r6 for later + orr lr, lr, r7 + orr lr, lr, r10 + + uqsub8 r10, r12, r11 @ q3 - q2 + uqsub8 r9, r11, r12 @ q2 - q3 + + mvn r11, #0 @ r11 == -1 + + orr r10, r10, r9 @ abs (q3-q2) + uqsub8 r10, r10, r2 @ compare to limit + + mov r12, #0 + orr lr, lr, r10 + sub r0, r0, r1, lsl #2 + + usub8 lr, r12, lr @ use usub8 instead of ssub8 + sel lr, r11, r12 @ filter mask: lr + + cmp lr, #0 + beq 2f @ skip filtering + + sub r0, r0, r1, lsl #1 @ move r0 pointer down by 6 lines + + @vp8_hevmask() function + @calculate high edge variance + orr r10, r6, r8 @ calculate vp8_hevmask + + usub8 r10, r12, r10 @ use usub8 instead of ssub8 + sel r6, r12, r11 @ obtain vp8_hevmask: r6 + + @vp8_filter() function + ldr r8, [r0, r1] @ p0 + ldr_post r7, r0, r1, lsl #1 @ p1 + ldr r12, c0x80808080 + ldr r10,[r0, r1] @ q1 + ldr_post r9, r0, r1, lsl #1 @ q0 + + eor r7, r7, r12 @ p1 offset to convert to a signed value + eor r8, r8, r12 @ p0 offset to convert to a signed value + eor r9, r9, r12 @ q0 offset to convert to a signed value + eor r10, r10, r12 @ q1 offset to convert to a signed value + + str r9, [sp] @ store qs0 temporarily + str r8, [sp, #4] @ store ps0 temporarily + str r10,[sp, #8] @ store qs1 temporarily + str r7, [sp, #12] @ store ps1 temporarily + + qsub8 r7, r7, r10 @ vp8_signed_char_clamp(ps1-qs1) + qsub8 r8, r9, r8 @ vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0)) + + and r7, r7, r6 @ vp8_filter (r7) &= hev + + qadd8 r7, r7, r8 + ldr r9, c0x03030303 @ r9 = 3 --modified for vp8 + + qadd8 r7, r7, r8 + ldr r10, c0x04040404 + + qadd8 r7, r7, r8 + and r7, r7, lr @ vp8_filter &= mask@ + + qadd8 r8, r7, r9 @ Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3) + qadd8 r7, r7, r10 @ vp8_filter = vp8_signed_char_clamp(vp8_filter+4) + + mov r9, #0 + shadd8 r8, r8, r9 @ Filter2 >>= 3 + shadd8 r7, r7, r9 @ vp8_filter >>= 3 + shadd8 r8, r8, r9 + shadd8 r7, r7, r9 + shadd8 lr, r8, r9 @ lr: Filter2 + shadd8 r7, r7, r9 @ r7: filter + + @calculate output + + ldr r8, [sp] @ load qs0 + ldr r9, [sp, #4] @ load ps0 + + ldr r10, c0x01010101 + + qsub8 r8, r8, r7 @ u = vp8_signed_char_clamp(qs0 - vp8_filter) + qadd8 r9, r9, lr @ u = vp8_signed_char_clamp(ps0 + Filter2) + + mov lr, #0 + sadd8 r7, r7, r10 @ vp8_filter += 1 + shadd8 r7, r7, lr @ vp8_filter >>= 1 + + ldr r11,[sp, #12] @ load ps1 + ldr r10,[sp, #8] @ load qs1 + + bic r7, r7, r6 @ vp8_filter &= ~hev + sub r0, r0, r1, lsl #2 + + qadd8 r11, r11, r7 @ u = vp8_signed_char_clamp(ps1 + vp8_filter) + qsub8 r10, r10, r7 @ u = vp8_signed_char_clamp(qs1 - vp8_filter) + + eor r11, r11, r12 @ *op1 = u^0x80 + eor r9, r9, r12 @ *op0 = u^0x80 + eor r8, r8, r12 @ *oq0 = u^0x80 + eor r10, r10, r12 @ *oq1 = u^0x80 + str r9, [r0, r1] @ store op0 result + str_post r11, r0, r1, lsl #1 @ store op1 + str r10,[r0, r1] @ store oq1 + str_post r8, r0, r1, lsl #1 @ store oq0 result + + sub r0, r0, r1, lsl #1 + +2: + add r0, r0, #4 + sub r0, r0, r1, lsl #2 + + subs r5, r5, #1 +T ittt ne + ldrne r10,[r0, r1] @ p2 +A ldrne r9, [r0], r1, lsl #1 @ p3 +T ldrne r9, [r0] @ p3 +T addne r0, r0, r1, lsl #1 +T ittt ne + ldrne r12,[r0, r1] @ p0 +A ldrne r11,[r0], r1, lsl #1 @ p1 +T ldrne r11,[r0] @ p3 +T addne r0, r0, r1, lsl #1 + + bne 1b + + add sp, sp, #16 + pop {r4 - r11, pc} +endfunc + +@ void vp8_v_loop_filter16(uint8_t *dst, int stride, +@ int fE, int fI, int hev_thresh) +@ and +@ void vp8_v_loop_filter8uv(uint8_t *dstU, uint8_t *dstV, int stride, +@ int fE, int fI, int hev_thresh) +@ call: +@ void vp8_v_loop_filter(uint8_t *dst, int stride, +@ int fE, int fI, int hev_thresh, int count) +function ff_vp8_v_loop_filter_armv6, export=1 + push {r4 - r11, lr} + + sub r0, r0, r1, lsl #2 @ move r0 pointer down by 4 lines + ldr r5, [sp, #40] @ counter + ldr r6, [sp, #36] @ load thresh address + sub sp, sp, #16 @ create temp buffer + + ldr r10,[r0, r1] @ p2 + ldr_post r9, r0, r1, lsl #1 @ p3 + ldr r12,[r0, r1] @ p0 + ldr_post r11, r0, r1, lsl #1 @ p1 + + orr r2, r2, r2, lsl #16 + orr r3, r3, r3, lsl #16 + orr r6, r6, r6, lsl #16 + orr r4, r2, r2, lsl #8 @ flimE splat int -> byte + orr r2, r3, r3, lsl #8 @ flimI splat int -> byte + orr r3, r6, r6, lsl #8 @ thresh splat int -> byte + +1: + @ vp8_filter_mask() function + @ calculate breakout conditions + uqsub8 r6, r9, r10 @ p3 - p2 + uqsub8 r7, r10, r9 @ p2 - p3 + uqsub8 r8, r10, r11 @ p2 - p1 + uqsub8 r10, r11, r10 @ p1 - p2 + + orr r6, r6, r7 @ abs (p3-p2) + orr r8, r8, r10 @ abs (p2-p1) + uqsub8 lr, r6, r2 @ compare to limit. lr: vp8_filter_mask + uqsub8 r8, r8, r2 @ compare to limit + + uqsub8 r6, r11, r12 @ p1 - p0 + orr lr, lr, r8 + uqsub8 r7, r12, r11 @ p0 - p1 + ldr r10,[r0, r1] @ q1 + ldr_post r9, r0, r1, lsl #1 @ q0 + orr r6, r6, r7 @ abs (p1-p0) + uqsub8 r7, r6, r2 @ compare to limit + uqsub8 r8, r6, r3 @ compare to thresh -- save r8 for later + orr lr, lr, r7 + + uqsub8 r6, r11, r10 @ p1 - q1 + uqsub8 r7, r10, r11 @ q1 - p1 + uqsub8 r11, r12, r9 @ p0 - q0 + uqsub8 r12, r9, r12 @ q0 - p0 + orr r6, r6, r7 @ abs (p1-q1) + ldr r7, c0x7F7F7F7F + orr r12, r11, r12 @ abs (p0-q0) + ldr_post r11, r0, r1 @ q2 + uqadd8 r12, r12, r12 @ abs (p0-q0) * 2 + and r6, r7, r6, lsr #1 @ abs (p1-q1) / 2 + uqsub8 r7, r9, r10 @ q0 - q1 + uqadd8 r12, r12, r6 @ abs (p0-q0)*2 + abs (p1-q1)/2 + uqsub8 r6, r10, r9 @ q1 - q0 + uqsub8 r12, r12, r4 @ compare to flimit + uqsub8 r9, r11, r10 @ q2 - q1 + + orr lr, lr, r12 + + ldr_post r12, r0, r1 @ q3 + + uqsub8 r10, r10, r11 @ q1 - q2 + orr r6, r7, r6 @ abs (q1-q0) + orr r10, r9, r10 @ abs (q2-q1) + uqsub8 r7, r6, r2 @ compare to limit + uqsub8 r10, r10, r2 @ compare to limit + uqsub8 r6, r6, r3 @ compare to thresh -- save r6 for later + orr lr, lr, r7 + orr lr, lr, r10 + + uqsub8 r10, r12, r11 @ q3 - q2 + uqsub8 r9, r11, r12 @ q2 - q3 + + mvn r11, #0 @ r11 == -1 + + orr r10, r10, r9 @ abs (q3-q2) + uqsub8 r10, r10, r2 @ compare to limit + + mov r12, #0 + + orr lr, lr, r10 + + usub8 lr, r12, lr @ use usub8 instead of ssub8 + sel lr, r11, r12 @ filter mask: lr + + cmp lr, #0 + beq 2f @ skip filtering + + @vp8_hevmask() function + @calculate high edge variance + sub r0, r0, r1, lsl #2 @ move r0 pointer down by 6 lines + sub r0, r0, r1, lsl #1 + + orr r10, r6, r8 + + usub8 r10, r12, r10 + sel r6, r12, r11 @ hev mask: r6 + + @vp8_mbfilter() function + @p2, q2 are only needed at the end. Do not need to load them in now. + ldr r8, [r0, r1] @ p0 + ldr_post r7, r0, r1, lsl #1 @ p1 + ldr r12, c0x80808080 + ldr_post r9, r0, r1 @ q0 + ldr r10,[r0] @ q1 + + eor r7, r7, r12 @ ps1 + eor r8, r8, r12 @ ps0 + eor r9, r9, r12 @ qs0 + eor r10, r10, r12 @ qs1 + + qsub8 r12, r9, r8 @ vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0)) + str r7, [sp, #12] @ store ps1 temporarily + qsub8 r7, r7, r10 @ vp8_signed_char_clamp(ps1-qs1) + str r10,[sp, #8] @ store qs1 temporarily + qadd8 r7, r7, r12 + str r9, [sp] @ store qs0 temporarily + qadd8 r7, r7, r12 + str r8, [sp, #4] @ store ps0 temporarily + qadd8 r7, r7, r12 @ vp8_filter: r7 + + ldr r10, c0x03030303 @ r10 = 3 --modified for vp8 + ldr r9, c0x04040404 + + and r7, r7, lr @ vp8_filter &= mask (lr is free) + + mov r12, r7 @ Filter2: r12 + and r12, r12, r6 @ Filter2 &= hev + + @save bottom 3 bits so that we round one side +4 and the other +3 + qadd8 r8, r12, r9 @ Filter1 (r8) = vp8_signed_char_clamp(Filter2+4) + qadd8 r12, r12, r10 @ Filter2 (r12) = vp8_signed_char_clamp(Filter2+3) + + mov r10, #0 + shadd8 r8, r8, r10 @ Filter1 >>= 3 + shadd8 r12, r12, r10 @ Filter2 >>= 3 + shadd8 r8, r8, r10 + shadd8 r12, r12, r10 + shadd8 r8, r8, r10 @ r8: Filter1 + shadd8 r12, r12, r10 @ r12: Filter2 + + ldr r9, [sp] @ load qs0 + ldr r11,[sp, #4] @ load ps0 + + qsub8 r9, r9, r8 @ qs0 = vp8_signed_char_clamp(qs0 - Filter1) + qadd8 r11, r11, r12 @ ps0 = vp8_signed_char_clamp(ps0 + Filter2) + + bic r12, r7, r6 @ vp8_filter &= ~hev ( r6 is free) + + @roughly 3/7th difference across boundary + mov lr, #0x1b @ 27 + mov r7, #0x3f @ 63 + + sxtb16 r6, r12 + sxtb16 r10, r12, ror #8 + smlabb r8, r6, lr, r7 + smlatb r6, r6, lr, r7 + smlabb r7, r10, lr, r7 + smultb r10, r10, lr + ssat r8, #8, r8, asr #7 + ssat r6, #8, r6, asr #7 + add r10, r10, #63 + ssat r7, #8, r7, asr #7 + ssat r10, #8, r10, asr #7 + + ldr lr, c0x80808080 + + pkhbt r6, r8, r6, lsl #16 + pkhbt r10, r7, r10, lsl #16 + uxtb16 r6, r6 + uxtb16 r10, r10 + + sub r0, r0, r1 + + orr r10, r6, r10, lsl #8 @ u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7) + + qsub8 r8, r9, r10 @ s = vp8_signed_char_clamp(qs0 - u) + qadd8 r10, r11, r10 @ s = vp8_signed_char_clamp(ps0 + u) + eor r8, r8, lr @ *oq0 = s^0x80 + str r8, [r0] @ store *oq0 + sub r0, r0, r1 + eor r10, r10, lr @ *op0 = s^0x80 + str r10,[r0] @ store *op0 + + @roughly 2/7th difference across boundary + mov lr, #0x12 @ 18 + mov r7, #0x3f @ 63 + + sxtb16 r6, r12 + sxtb16 r10, r12, ror #8 + smlabb r8, r6, lr, r7 + smlatb r6, r6, lr, r7 + smlabb r9, r10, lr, r7 + smlatb r10, r10, lr, r7 + ssat r8, #8, r8, asr #7 + ssat r6, #8, r6, asr #7 + ssat r9, #8, r9, asr #7 + ssat r10, #8, r10, asr #7 + + ldr lr, c0x80808080 + + pkhbt r6, r8, r6, lsl #16 + pkhbt r10, r9, r10, lsl #16 + + ldr r9, [sp, #8] @ load qs1 + ldr r11, [sp, #12] @ load ps1 + + uxtb16 r6, r6 + uxtb16 r10, r10 + + sub r0, r0, r1 + + orr r10, r6, r10, lsl #8 @ u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7) + + qadd8 r11, r11, r10 @ s = vp8_signed_char_clamp(ps1 + u) + qsub8 r8, r9, r10 @ s = vp8_signed_char_clamp(qs1 - u) + eor r11, r11, lr @ *op1 = s^0x80 + str_post r11, r0, r1 @ store *op1 + eor r8, r8, lr @ *oq1 = s^0x80 + add r0, r0, r1, lsl #1 + + mov r7, #0x3f @ 63 + + str_post r8, r0, r1 @ store *oq1 + + @roughly 1/7th difference across boundary + mov lr, #0x9 @ 9 + ldr r9, [r0] @ load q2 + + sxtb16 r6, r12 + sxtb16 r10, r12, ror #8 + smlabb r8, r6, lr, r7 + smlatb r6, r6, lr, r7 + smlabb r12, r10, lr, r7 + smlatb r10, r10, lr, r7 + ssat r8, #8, r8, asr #7 + ssat r6, #8, r6, asr #7 + ssat r12, #8, r12, asr #7 + ssat r10, #8, r10, asr #7 + + sub r0, r0, r1, lsl #2 + + pkhbt r6, r8, r6, lsl #16 + pkhbt r10, r12, r10, lsl #16 + + sub r0, r0, r1 + ldr lr, c0x80808080 + + ldr r11, [r0] @ load p2 + + uxtb16 r6, r6 + uxtb16 r10, r10 + + eor r9, r9, lr + eor r11, r11, lr + + orr r10, r6, r10, lsl #8 @ u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7) + + qadd8 r8, r11, r10 @ s = vp8_signed_char_clamp(ps2 + u) + qsub8 r10, r9, r10 @ s = vp8_signed_char_clamp(qs2 - u) + eor r8, r8, lr @ *op2 = s^0x80 + str_post r8, r0, r1, lsl #2 @ store *op2 + add r0, r0, r1 + eor r10, r10, lr @ *oq2 = s^0x80 + str_post r10, r0, r1, lsl #1 @ store *oq2 + +2: + add r0, r0, #4 + sub r0, r0, r1, lsl #3 + subs r5, r5, #1 + +T ittt ne + ldrne r10,[r0, r1] @ p2 +A ldrne r9, [r0], r1, lsl #1 @ p3 +T ldrne r9, [r0] @ p3 +T addne r0, r0, r1, lsl #1 +T ittt ne + ldrne r12,[r0, r1] @ p0 +A ldrne r11,[r0], r1, lsl #1 @ p1 +T ldrne r11,[r0] @ p3 +T addne r0, r0, r1, lsl #1 + + bne 1b + + add sp, sp, #16 + pop {r4 - r11, pc} +endfunc + +.macro TRANSPOSE_MATRIX i0, i1, i2, i3, o3, o2, o1, o0 + @ input: $0, $1, $2, $3 + @ output: $4, $5, $6, $7 + @ i0: 03 02 01 00 + @ i1: 13 12 11 10 + @ i2: 23 22 21 20 + @ i3: 33 32 31 30 + @ o3 o2 o1 o0 + + uxtb16 \o1, \i1 @ xx 12 xx 10 + uxtb16 \o0, \i0 @ xx 02 xx 00 + uxtb16 \o3, \i3 @ xx 32 xx 30 + uxtb16 \o2, \i2 @ xx 22 xx 20 + orr \o1, \o0, \o1, lsl #8 @ 12 02 10 00 + orr \o3, \o2, \o3, lsl #8 @ 32 22 30 20 + + uxtb16 \i1, \i1, ror #8 @ xx 13 xx 11 + uxtb16 \i3, \i3, ror #8 @ xx 33 xx 31 + uxtb16 \i0, \i0, ror #8 @ xx 03 xx 01 + uxtb16 \i2, \i2, ror #8 @ xx 23 xx 21 + orr \i0, \i0, \i1, lsl #8 @ 13 03 11 01 + orr \i2, \i2, \i3, lsl #8 @ 33 23 31 21 + + pkhtb \o2, \o3, \o1, asr #16 @ 32 22 12 02 -- p1 + pkhbt \o0, \o1, \o3, lsl #16 @ 30 20 10 00 -- p3 + + pkhtb \o3, \i2, \i0, asr #16 @ 33 23 13 03 -- p0 + pkhbt \o1, \i0, \i2, lsl #16 @ 31 21 11 01 -- p2 +.endm + +@ void vp8_h_loop_filter16_simple(uint8_t *dst, int stride, int flim) +function ff_vp8_h_loop_filter16_simple_armv6, export=1 + push {r4 - r11, lr} + orr r12, r2, r2, lsl #16 + ldr r2, c0x80808080 + orr r12, r12, r12, lsl #8 + + @ load soure data to r7, r8, r9, r10 + sub r0, r0, #2 + ldr r8, [r0, r1] + ldr_post r7, r0, r1, lsl #1 + ldr r10,[r0, r1] + ldr_post r9, r0, r1, lsl #1 + add r0, r0, #2 + + mov r11, #4 @ count (r11) for 4-in-parallel +1: + @transpose r7, r8, r9, r10 to r3, r4, r5, r6 + TRANSPOSE_MATRIX r7, r8, r9, r10, r6, r5, r4, r3 + + @ vp8_simple_filter_mask() function + uqsub8 r7, r3, r6 @ p1 - q1 + uqsub8 r8, r6, r3 @ q1 - p1 + uqsub8 r9, r4, r5 @ p0 - q0 + uqsub8 r10, r5, r4 @ q0 - p0 + orr r7, r7, r8 @ abs(p1 - q1) + orr r9, r9, r10 @ abs(p0 - q0) + mov r8, #0 + uqadd8 r9, r9, r9 @ abs(p0 - q0) * 2 + uhadd8 r7, r7, r8 @ abs(p1 - q1) / 2 + uqadd8 r7, r7, r9 @ abs(p0 - q0)*2 + abs(p1 - q1)/2 + mvn r10, #0 @ r10 == -1 + + usub8 r7, r12, r7 @ compare to flimit + sel lr, r10, r8 @ filter mask + + cmp lr, #0 + beq 2f @ skip filtering + + @vp8_simple_filter() function + eor r3, r3, r2 @ p1 offset to convert to a signed value + eor r6, r6, r2 @ q1 offset to convert to a signed value + eor r4, r4, r2 @ p0 offset to convert to a signed value + eor r5, r5, r2 @ q0 offset to convert to a signed value + + qsub8 r3, r3, r6 @ vp8_filter = p1 - q1 + qsub8 r6, r5, r4 @ q0 - p0 + + qadd8 r3, r3, r6 @ vp8_filter += q0 - p0 + ldr r9, c0x03030303 @ r9 = 3 + + qadd8 r3, r3, r6 @ vp8_filter += q0 - p0 + ldr r7, c0x04040404 + + qadd8 r3, r3, r6 @ vp8_filter = p1-q1 + 3*(q0-p0)) + @STALL + and r3, r3, lr @ vp8_filter &= mask + + qadd8 r9, r3, r9 @ Filter2 = vp8_filter + 3 + qadd8 r3, r3, r7 @ Filter1 = vp8_filter + 4 + + shadd8 r9, r9, r8 + shadd8 r3, r3, r8 + shadd8 r9, r9, r8 + shadd8 r3, r3, r8 + shadd8 r9, r9, r8 @ Filter2 >>= 3 + shadd8 r3, r3, r8 @ Filter1 >>= 3 + + @calculate output + sub r0, r0, r1, lsl #2 + + qadd8 r4, r4, r9 @ u = p0 + Filter2 + qsub8 r5, r5, r3 @ u = q0 - Filter1 + eor r4, r4, r2 @ *op0 = u^0x80 + eor r5, r5, r2 @ *oq0 = u^0x80 + + strb r4, [r0, #-1] @ store the result + mov r4, r4, lsr #8 + strb_post r5, r0, r1 + mov r5, r5, lsr #8 + + strb r4, [r0, #-1] + mov r4, r4, lsr #8 + strb_post r5, r0, r1 + mov r5, r5, lsr #8 + + strb r4, [r0, #-1] + mov r4, r4, lsr #8 + strb_post r5, r0, r1 + mov r5, r5, lsr #8 + + strb r4, [r0, #-1] + strb_post r5, r0, r1 + +2: + subs r11, r11, #1 + + @ load soure data to r7, r8, r9, r10 + sub r0, r0, #2 +T ittt ne + ldrne r8, [r0, r1] +A ldrne r7, [r0], r1, lsl #1 +T ldrne r7, [r0] +T addne r0, r0, r1, lsl #1 +T ittt ne + ldrne r10,[r0, r1] +A ldrne r9, [r0], r1, lsl #1 +T ldrne r9, [r0] +T addne r0, r0, r1, lsl #1 + add r0, r0, #2 + + bne 1b + + pop {r4 - r11, pc} +endfunc + +@ void vp8_h_loop_filter16_inner(uint8_t *dst, int stride, +@ int fE, int fI, int hev_thresh) +@ and +@ void vp8_h_loop_filter8uv_inner(uint8_t *dstU, uint8_t *dstV, int stride, +@ int fE, int fI, int hev_thresh) +@ call: +@ void vp8_h_loop_filter_inner(uint8_t *dst, int stride, +@ int fE, int fI, int hev_thresh, int count) +function ff_vp8_h_loop_filter_inner_armv6, export=1 + push {r4 - r11, lr} + + sub r0, r0, #4 @ move r0 pointer down by 4 + ldr r5, [sp, #40] @ counter + ldr r9, [sp, #36] @ load thresh address + sub sp, sp, #16 @ create temp buffer + + ldr r7, [r0, r1] @ transpose will make it into p3-p0 + ldr_post r6, r0, r1, lsl #1 @ load source data + ldr lr, [r0, r1] + ldr_post r8, r0, r1, lsl #1 + + orr r2, r2, r2, lsl #16 + orr r3, r3, r3, lsl #16 + orr r9, r9, r9, lsl #16 + orr r4, r2, r2, lsl #8 @ flimE splat int -> byte + orr r2, r3, r3, lsl #8 @ flimI splat int -> byte + orr r3, r9, r9, lsl #8 @ thresh splat int -> byte + +1: + @ vp8_filter_mask() function + @ calculate breakout conditions + @ transpose the source data for 4-in-parallel operation + TRANSPOSE_MATRIX r6, r7, r8, lr, r12, r11, r10, r9 + + uqsub8 r7, r9, r10 @ p3 - p2 + uqsub8 r8, r10, r9 @ p2 - p3 + uqsub8 r9, r10, r11 @ p2 - p1 + uqsub8 r10, r11, r10 @ p1 - p2 + orr r7, r7, r8 @ abs (p3-p2) + orr r10, r9, r10 @ abs (p2-p1) + uqsub8 lr, r7, r2 @ compare to limit. lr: vp8_filter_mask + uqsub8 r10, r10, r2 @ compare to limit + + sub r0, r0, r1, lsl #2 @ move r0 pointer down by 4 lines + + orr lr, lr, r10 + + uqsub8 r6, r11, r12 @ p1 - p0 + uqsub8 r7, r12, r11 @ p0 - p1 + add r0, r0, #4 @ move r0 pointer up by 4 + orr r6, r6, r7 @ abs (p1-p0) + str r11,[sp, #12] @ save p1 + uqsub8 r10, r6, r2 @ compare to limit + uqsub8 r11, r6, r3 @ compare to thresh + orr lr, lr, r10 + + @ transpose uses 8 regs(r6 - r12 and lr). Need to save reg value now + @ transpose the source data for 4-in-parallel operation + str r11,[sp] @ push r11 to stack + ldr r7, [r0, r1] + ldr_post r6, r0, r1, lsl #1 @ load source data + str r12,[sp, #4] @ save current reg before load q0 - q3 data + str lr, [sp, #8] + ldr lr, [r0, r1] + ldr_post r8, r0, r1, lsl #1 + + TRANSPOSE_MATRIX r6, r7, r8, lr, r12, r11, r10, r9 + + ldr lr, [sp, #8] @ load back (f)limit accumulator + + uqsub8 r6, r12, r11 @ q3 - q2 + uqsub8 r7, r11, r12 @ q2 - q3 + uqsub8 r12, r11, r10 @ q2 - q1 + uqsub8 r11, r10, r11 @ q1 - q2 + orr r6, r6, r7 @ abs (q3-q2) + orr r7, r12, r11 @ abs (q2-q1) + uqsub8 r6, r6, r2 @ compare to limit + uqsub8 r7, r7, r2 @ compare to limit + ldr r11,[sp, #4] @ load back p0 + ldr r12,[sp, #12] @ load back p1 + orr lr, lr, r6 + orr lr, lr, r7 + + uqsub8 r6, r11, r9 @ p0 - q0 + uqsub8 r7, r9, r11 @ q0 - p0 + uqsub8 r8, r12, r10 @ p1 - q1 + uqsub8 r11, r10, r12 @ q1 - p1 + orr r6, r6, r7 @ abs (p0-q0) + ldr r7, c0x7F7F7F7F + orr r8, r8, r11 @ abs (p1-q1) + uqadd8 r6, r6, r6 @ abs (p0-q0) * 2 + and r8, r7, r8, lsr #1 @ abs (p1-q1) / 2 + uqsub8 r11, r10, r9 @ q1 - q0 + uqadd8 r6, r8, r6 @ abs (p0-q0)*2 + abs (p1-q1)/2 + uqsub8 r12, r9, r10 @ q0 - q1 + uqsub8 r6, r6, r4 @ compare to flimit + + orr r9, r11, r12 @ abs (q1-q0) + uqsub8 r8, r9, r2 @ compare to limit + uqsub8 r10, r9, r3 @ compare to thresh + orr lr, lr, r6 + orr lr, lr, r8 + + mvn r11, #0 @ r11 == -1 + mov r12, #0 + + usub8 lr, r12, lr + ldr r9, [sp] @ load the compared result + sel lr, r11, r12 @ filter mask: lr + + cmp lr, #0 + beq 2f @ skip filtering + + @vp8_hevmask() function + @calculate high edge variance + sub r0, r0, r1, lsl #2 @ move r0 pointer down by 4 lines + + orr r9, r9, r10 + + ldrh r7, [r0, #-2] + ldrh_post r8, r0, r1 + + usub8 r9, r12, r9 + sel r6, r12, r11 @ hev mask: r6 + + @vp8_filter() function + @ load soure data to r6, r11, r12, lr + ldrh r9, [r0, #-2] + ldrh_post r10, r0, r1 + + pkhbt r12, r7, r8, lsl #16 + + ldrh r7, [r0, #-2] + ldrh_post r8, r0, r1 + + pkhbt r11, r9, r10, lsl #16 + + ldrh r9, [r0, #-2] + ldrh_post r10, r0, r1 + + @ Transpose needs 8 regs(r6 - r12, and lr). Save r6 and lr first + str r6, [sp] + str lr, [sp, #4] + + pkhbt r6, r7, r8, lsl #16 + pkhbt lr, r9, r10, lsl #16 + + @transpose r12, r11, r6, lr to r7, r8, r9, r10 + TRANSPOSE_MATRIX r12, r11, r6, lr, r10, r9, r8, r7 + + @load back hev_mask r6 and filter_mask lr + ldr r12, c0x80808080 + ldr r6, [sp] + ldr lr, [sp, #4] + + eor r7, r7, r12 @ p1 offset to convert to a signed value + eor r8, r8, r12 @ p0 offset to convert to a signed value + eor r9, r9, r12 @ q0 offset to convert to a signed value + eor r10, r10, r12 @ q1 offset to convert to a signed value + + str r9, [sp] @ store qs0 temporarily + str r8, [sp, #4] @ store ps0 temporarily + str r10,[sp, #8] @ store qs1 temporarily + str r7, [sp, #12] @ store ps1 temporarily + + qsub8 r7, r7, r10 @ vp8_signed_char_clamp(ps1-qs1) + qsub8 r8, r9, r8 @ vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0)) + + and r7, r7, r6 @ vp8_filter (r7) &= hev (r7 : filter) + + qadd8 r7, r7, r8 + ldr r9, c0x03030303 @ r9 = 3 --modified for vp8 + + qadd8 r7, r7, r8 + ldr r10, c0x04040404 + + qadd8 r7, r7, r8 + + and r7, r7, lr @ vp8_filter &= mask + + qadd8 r8, r7, r9 @ Filter2 (r8) = vp8_signed_char_clamp(vp8_filter+3) + qadd8 r7, r7, r10 @ vp8_filter = vp8_signed_char_clamp(vp8_filter+4) + + mov r9, #0 + shadd8 r8, r8, r9 @ Filter2 >>= 3 + shadd8 r7, r7, r9 @ vp8_filter >>= 3 + shadd8 r8, r8, r9 + shadd8 r7, r7, r9 + shadd8 lr, r8, r9 @ lr: filter2 + shadd8 r7, r7, r9 @ r7: filter + + @calculate output + ldr r8, [sp] @ load qs0 + ldr r9, [sp, #4] @ load ps0 + + ldr r10, c0x01010101 + + qsub8 r8, r8, r7 @ u = vp8_signed_char_clamp(qs0 - vp8_filter) + qadd8 r9, r9, lr @ u = vp8_signed_char_clamp(ps0 + Filter2) + + eor r8, r8, r12 + eor r9, r9, r12 + + mov lr, #0 + + sadd8 r7, r7, r10 + shadd8 r7, r7, lr + + ldr r10,[sp, #8] @ load qs1 + ldr r11,[sp, #12] @ load ps1 + + bic r7, r7, r6 @ r7: vp8_filter + + qsub8 r10, r10, r7 @ u = vp8_signed_char_clamp(qs1 - vp8_filter) + qadd8 r11, r11, r7 @ u = vp8_signed_char_clamp(ps1 + vp8_filter) + eor r10, r10, r12 + eor r11, r11, r12 + + sub r0, r0, r1, lsl #2 + + @we can use TRANSPOSE_MATRIX macro to transpose output - input: q1, q0, p0, p1 + TRANSPOSE_MATRIX r11, r9, r8, r10, lr, r12, r7, r6 + + strh r6, [r0, #-2] @ store the result + mov r6, r6, lsr #16 + strh_post r6, r0, r1 + + strh r7, [r0, #-2] + mov r7, r7, lsr #16 + strh_post r7, r0, r1 + + strh r12, [r0, #-2] + mov r12, r12, lsr #16 + strh_post r12, r0, r1 + + strh lr, [r0, #-2] + mov lr, lr, lsr #16 + strh_post lr, r0, r1 + +2: + sub r0, r0, #4 + subs r5, r5, #1 + +T ittt ne + ldrne r7, [r0, r1] +A ldrne r6, [r0], r1, lsl #1 @ load source data +T ldrne r6, [r0] @ load source data +T addne r0, r0, r1, lsl #1 +T ittt ne + ldrne lr, [r0, r1] +A ldrne r8, [r0], r1, lsl #1 +T ldrne r8, [r0] +T addne r0, r0, r1, lsl #1 + + bne 1b + + add sp, sp, #16 + pop {r4 - r11, pc} +endfunc + +@ void vp8_h_loop_filter16(uint8_t *dst, int stride, +@ int fE, int fI, int hev_thresh) +@ and +@ void vp8_h_loop_filter8uv(uint8_t *dstU, uint8_t *dstV, int stride, +@ int fE, int fI, int hev_thresh) +@ call: +@ void vp8_h_loop_filter(uint8_t *dst, int stride, +@ int fE, int fI, int hev_thresh, int count) +function ff_vp8_h_loop_filter_armv6, export=1 + push {r4 - r11, lr} + + sub r0, r0, #4 @ move r0 pointer down by 4 + ldr r5, [sp, #40] @ counter + ldr r9, [sp, #36] @ load thresh address + sub sp, sp, #16 @ create temp buffer + + ldr r7, [r0, r1] @ transpose will make it into p3-p0 + ldr_post r6, r0, r1, lsl #1 @ load source data + ldr lr, [r0, r1] + ldr_post r8, r0, r1, lsl #1 + + orr r2, r2, r2, lsl #16 + orr r3, r3, r3, lsl #16 + orr r9, r9, r9, lsl #16 + orr r4, r2, r2, lsl #8 @ flimE splat int -> byte + orr r2, r3, r3, lsl #8 @ flimI splat int -> byte + orr r3, r9, r9, lsl #8 @ thresh splat int -> byte + +1: + @ vp8_filter_mask() function + @ calculate breakout conditions + @ transpose the source data for 4-in-parallel operation + TRANSPOSE_MATRIX r6, r7, r8, lr, r12, r11, r10, r9 + + uqsub8 r7, r9, r10 @ p3 - p2 + uqsub8 r8, r10, r9 @ p2 - p3 + uqsub8 r9, r10, r11 @ p2 - p1 + uqsub8 r10, r11, r10 @ p1 - p2 + orr r7, r7, r8 @ abs (p3-p2) + orr r10, r9, r10 @ abs (p2-p1) + uqsub8 lr, r7, r2 @ compare to limit. lr: vp8_filter_mask + uqsub8 r10, r10, r2 @ compare to limit + + sub r0, r0, r1, lsl #2 @ move r0 pointer down by 4 lines + + orr lr, lr, r10 + + uqsub8 r6, r11, r12 @ p1 - p0 + uqsub8 r7, r12, r11 @ p0 - p1 + add r0, r0, #4 @ move r0 pointer up by 4 + orr r6, r6, r7 @ abs (p1-p0) + str r11,[sp, #12] @ save p1 + uqsub8 r10, r6, r2 @ compare to limit + uqsub8 r11, r6, r3 @ compare to thresh + orr lr, lr, r10 + + @ transpose uses 8 regs(r6 - r12 and lr). Need to save reg value now + @ transpose the source data for 4-in-parallel operation + str r11,[sp] @ push r11 to stack + ldr r7, [r0, r1] + ldr_post r6, r0, r1, lsl #1 @ load source data + str r12,[sp, #4] @ save current reg before load q0 - q3 data + str lr, [sp, #8] + ldr lr, [r0, r1] + ldr_post r8, r0, r1, lsl #1 + + TRANSPOSE_MATRIX r6, r7, r8, lr, r12, r11, r10, r9 + + ldr lr, [sp, #8] @ load back (f)limit accumulator + + uqsub8 r6, r12, r11 @ q3 - q2 + uqsub8 r7, r11, r12 @ q2 - q3 + uqsub8 r12, r11, r10 @ q2 - q1 + uqsub8 r11, r10, r11 @ q1 - q2 + orr r6, r6, r7 @ abs (q3-q2) + orr r7, r12, r11 @ abs (q2-q1) + uqsub8 r6, r6, r2 @ compare to limit + uqsub8 r7, r7, r2 @ compare to limit + ldr r11,[sp, #4] @ load back p0 + ldr r12,[sp, #12] @ load back p1 + orr lr, lr, r6 + orr lr, lr, r7 + + uqsub8 r6, r11, r9 @ p0 - q0 + uqsub8 r7, r9, r11 @ q0 - p0 + uqsub8 r8, r12, r10 @ p1 - q1 + uqsub8 r11, r10, r12 @ q1 - p1 + orr r6, r6, r7 @ abs (p0-q0) + ldr r7, c0x7F7F7F7F + orr r8, r8, r11 @ abs (p1-q1) + uqadd8 r6, r6, r6 @ abs (p0-q0) * 2 + and r8, r7, r8, lsr #1 @ abs (p1-q1) / 2 + uqsub8 r11, r10, r9 @ q1 - q0 + uqadd8 r6, r8, r6 @ abs (p0-q0)*2 + abs (p1-q1)/2 + uqsub8 r12, r9, r10 @ q0 - q1 + uqsub8 r6, r6, r4 @ compare to flimit + + orr r9, r11, r12 @ abs (q1-q0) + uqsub8 r8, r9, r2 @ compare to limit + uqsub8 r10, r9, r3 @ compare to thresh + orr lr, lr, r6 + orr lr, lr, r8 + + mvn r11, #0 @ r11 == -1 + mov r12, #0 + + usub8 lr, r12, lr + ldr r9, [sp] @ load the compared result + sel lr, r11, r12 @ filter mask: lr + + cmp lr, #0 + beq 2f @ skip filtering + + + @vp8_hevmask() function + @calculate high edge variance + sub r0, r0, r1, lsl #2 @ move r0 pointer down by 4 lines + + orr r9, r9, r10 + + ldrh r7, [r0, #-2] + ldrh_post r8, r0, r1 + + usub8 r9, r12, r9 + sel r6, r12, r11 @ hev mask: r6 + + + @ vp8_mbfilter() function + @ p2, q2 are only needed at the end. do not need to load them in now. + @ Transpose needs 8 regs(r6 - r12, and lr). Save r6 and lr first + @ load soure data to r6, r11, r12, lr + ldrh r9, [r0, #-2] + ldrh_post r10, r0, r1 + + pkhbt r12, r7, r8, lsl #16 + + ldrh r7, [r0, #-2] + ldrh_post r8, r0, r1 + + pkhbt r11, r9, r10, lsl #16 + + ldrh r9, [r0, #-2] + ldrh_post r10, r0, r1 + + str r6, [sp] @ save r6 + str lr, [sp, #4] @ save lr + + pkhbt r6, r7, r8, lsl #16 + pkhbt lr, r9, r10, lsl #16 + + @transpose r12, r11, r6, lr to p1, p0, q0, q1 + TRANSPOSE_MATRIX r12, r11, r6, lr, r10, r9, r8, r7 + + @load back hev_mask r6 and filter_mask lr + ldr r12, c0x80808080 + ldr r6, [sp] + ldr lr, [sp, #4] + + eor r7, r7, r12 @ ps1 + eor r8, r8, r12 @ ps0 + eor r9, r9, r12 @ qs0 + eor r10, r10, r12 @ qs1 + + qsub8 r12, r9, r8 @ vp8_signed_char_clamp(vp8_filter + 3 * ( qs0 - ps0)) + str r7, [sp, #12] @ store ps1 temporarily + qsub8 r7, r7, r10 @ vp8_signed_char_clamp(ps1-qs1) + str r10,[sp, #8] @ store qs1 temporarily + qadd8 r7, r7, r12 + str r9, [sp] @ store qs0 temporarily + qadd8 r7, r7, r12 + str r8, [sp, #4] @ store ps0 temporarily + qadd8 r7, r7, r12 @ vp8_filter: r7 + + ldr r10, c0x03030303 @ r10 = 3 --modified for vp8 + ldr r9, c0x04040404 + + and r7, r7, lr @ vp8_filter &= mask (lr is free) + + mov r12, r7 @ Filter2: r12 + and r12, r12, r6 @ Filter2 &= hev + + @save bottom 3 bits so that we round one side +4 and the other +3 + qadd8 r8, r12, r9 @ Filter1 (r8) = vp8_signed_char_clamp(Filter2+4) + qadd8 r12, r12, r10 @ Filter2 (r12) = vp8_signed_char_clamp(Filter2+3) + + mov r10, #0 + shadd8 r8, r8, r10 @ Filter1 >>= 3 + shadd8 r12, r12, r10 @ Filter2 >>= 3 + shadd8 r8, r8, r10 + shadd8 r12, r12, r10 + shadd8 r8, r8, r10 @ r8: Filter1 + shadd8 r12, r12, r10 @ r12: Filter2 + + ldr r9, [sp] @ load qs0 + ldr r11,[sp, #4] @ load ps0 + + qsub8 r9, r9, r8 @ qs0 = vp8_signed_char_clamp(qs0 - Filter1) + qadd8 r11, r11, r12 @ ps0 = vp8_signed_char_clamp(ps0 + Filter2) + + bic r12, r7, r6 @vp8_filter &= ~hev ( r6 is free) + + @roughly 3/7th difference across boundary + mov lr, #0x1b @ 27 + mov r7, #0x3f @ 63 + + sxtb16 r6, r12 + sxtb16 r10, r12, ror #8 + smlabb r8, r6, lr, r7 + smlatb r6, r6, lr, r7 + smlabb r7, r10, lr, r7 + smultb r10, r10, lr + ssat r8, #8, r8, asr #7 + ssat r6, #8, r6, asr #7 + add r10, r10, #63 + ssat r7, #8, r7, asr #7 + ssat r10, #8, r10, asr #7 + + ldr lr, c0x80808080 + + pkhbt r6, r8, r6, lsl #16 + pkhbt r10, r7, r10, lsl #16 + uxtb16 r6, r6 + uxtb16 r10, r10 + + sub r0, r0, r1, lsl #2 @ move r0 pointer down by 4 lines + + orr r10, r6, r10, lsl #8 @ u = vp8_signed_char_clamp((63 + Filter2 * 27)>>7) + + qsub8 r8, r9, r10 @ s = vp8_signed_char_clamp(qs0 - u) + qadd8 r10, r11, r10 @ s = vp8_signed_char_clamp(ps0 + u) + eor r8, r8, lr @ *oq0 = s^0x80 + eor r10, r10, lr @ *op0 = s^0x80 + + strb r10,[r0, #-1] @ store op0 result + strb_post r8, r0, r1 @ store oq0 result + mov r10, r10, lsr #8 + mov r8, r8, lsr #8 + strb r10,[r0, #-1] + strb_post r8, r0, r1 + mov r10, r10, lsr #8 + mov r8, r8, lsr #8 + strb r10,[r0, #-1] + strb_post r8, r0, r1 + mov r10, r10, lsr #8 + mov r8, r8, lsr #8 + strb r10,[r0, #-1] + strb_post r8, r0, r1 + + @roughly 2/7th difference across boundary + mov lr, #0x12 @ 18 + mov r7, #0x3f @ 63 + + sxtb16 r6, r12 + sxtb16 r10, r12, ror #8 + smlabb r8, r6, lr, r7 + smlatb r6, r6, lr, r7 + smlabb r9, r10, lr, r7 + smlatb r10, r10, lr, r7 + ssat r8, #8, r8, asr #7 + ssat r6, #8, r6, asr #7 + ssat r9, #8, r9, asr #7 + ssat r10, #8, r10, asr #7 + + sub r0, r0, r1, lsl #2 @ move r0 pointer down by 4 lines + + pkhbt r6, r8, r6, lsl #16 + pkhbt r10, r9, r10, lsl #16 + + ldr r9, [sp, #8] @ load qs1 + ldr r11,[sp, #12] @ load ps1 + ldr lr, c0x80808080 + + uxtb16 r6, r6 + uxtb16 r10, r10 + + add r0, r0, #2 + + orr r10, r6, r10, lsl #8 @ u = vp8_signed_char_clamp((63 + Filter2 * 18)>>7) + + qsub8 r8, r9, r10 @ s = vp8_signed_char_clamp(qs1 - u) + qadd8 r10, r11, r10 @ s = vp8_signed_char_clamp(ps1 + u) + eor r8, r8, lr @ *oq1 = s^0x80 + eor r10, r10, lr @ *op1 = s^0x80 + + ldrb r11,[r0, #-5] @ load p2 for 1/7th difference across boundary + strb r10,[r0, #-4] @ store op1 + strb r8, [r0, #-1] @ store oq1 + ldrb_post r9, r0, r1 @ load q2 for 1/7th difference across boundary + + mov r10, r10, lsr #8 + mov r8, r8, lsr #8 + + ldrb r6, [r0, #-5] + strb r10,[r0, #-4] + strb r8, [r0, #-1] + ldrb_post r7, r0, r1 + + mov r10, r10, lsr #8 + mov r8, r8, lsr #8 + orr r11, r11, r6, lsl #8 + orr r9, r9, r7, lsl #8 + + ldrb r6, [r0, #-5] + strb r10,[r0, #-4] + strb r8, [r0, #-1] + ldrb_post r7, r0, r1 + + mov r10, r10, lsr #8 + mov r8, r8, lsr #8 + orr r11, r11, r6, lsl #16 + orr r9, r9, r7, lsl #16 + + ldrb r6, [r0, #-5] + strb r10,[r0, #-4] + strb r8, [r0, #-1] + ldrb_post r7, r0, r1 + orr r11, r11, r6, lsl #24 + orr r9, r9, r7, lsl #24 + + @roughly 1/7th difference across boundary + eor r9, r9, lr + eor r11, r11, lr + + mov lr, #0x9 @ 9 + mov r7, #0x3f @ 63 + + sxtb16 r6, r12 + sxtb16 r10, r12, ror #8 + smlabb r8, r6, lr, r7 + smlatb r6, r6, lr, r7 + smlabb r12, r10, lr, r7 + smlatb r10, r10, lr, r7 + ssat r8, #8, r8, asr #7 + ssat r6, #8, r6, asr #7 + ssat r12, #8, r12, asr #7 + ssat r10, #8, r10, asr #7 + + sub r0, r0, r1, lsl #2 + + pkhbt r6, r8, r6, lsl #16 + pkhbt r10, r12, r10, lsl #16 + + uxtb16 r6, r6 + uxtb16 r10, r10 + + ldr lr, c0x80808080 + + orr r10, r6, r10, lsl #8 @ u = vp8_signed_char_clamp((63 + Filter2 * 9)>>7) + + qadd8 r8, r11, r10 @ s = vp8_signed_char_clamp(ps2 + u) + qsub8 r10, r9, r10 @ s = vp8_signed_char_clamp(qs2 - u) + eor r8, r8, lr @ *op2 = s^0x80 + eor r10, r10, lr @ *oq2 = s^0x80 + + strb r8, [r0, #-5] @ store *op2 + strb_post r10, r0, r1 @ store *oq2 + mov r8, r8, lsr #8 + mov r10, r10, lsr #8 + strb r8, [r0, #-5] + strb_post r10, r0, r1 + mov r8, r8, lsr #8 + mov r10, r10, lsr #8 + strb r8, [r0, #-5] + strb_post r10, r0, r1 + mov r8, r8, lsr #8 + mov r10, r10, lsr #8 + strb r8, [r0, #-5] + strb_post r10, r0, r1 + + @adjust r0 pointer for next loop + sub r0, r0, #2 + +2: + sub r0, r0, #4 + subs r5, r5, #1 + +T ittt ne + ldrne r7, [r0, r1] +A ldrne r6, [r0], r1, lsl #1 @ load source data +T ldrne r6, [r0] +T addne r0, r0, r1, lsl #1 +T ittt ne + ldrne lr, [r0, r1] +A ldrne r8, [r0], r1, lsl #1 +T ldrne r8, [r0] +T addne r0, r0, r1, lsl #1 + + bne 1b + + add sp, sp, #16 + pop {r4 - r11, pc} +endfunc + +@ MC + +@ void put_vp8_pixels16(uint8_t *dst, int dststride, uint8_t *src, +@ int srcstride, int h, int mx, int my) +function ff_put_vp8_pixels16_armv6, export=1 + push {r4 - r11} + ldr r12,[sp, #32] @ h +1: + subs r12, r12, #2 + ldr r5, [r2, #4] + ldr r6, [r2, #8] + ldr r7, [r2, #12] + ldr_post r4, r2, r3 + ldr r9, [r2, #4] + ldr r10,[r2, #8] + ldr r11,[r2, #12] + ldr_post r8, r2, r3 + strd r6, r7, [r0, #8] + strd_post r4, r5, r0, r1 + strd r10, r11,[r0, #8] + strd_post r8, r9, r0, r1 + bgt 1b + pop {r4 - r11} + bx lr +endfunc + +@ void put_vp8_pixels8(uint8_t *dst, int dststride, uint8_t *src, +@ int srcstride, int h, int mx, int my) +function ff_put_vp8_pixels8_armv6, export=1 + push {r4 - r11} + ldr r12,[sp, #32] @ h +1: + subs r12, r12, #4 + ldr r5, [r2, #4] + ldr_post r4, r2, r3 + ldr r7, [r2, #4] + ldr_post r6, r2, r3 + ldr r9, [r2, #4] + ldr_post r8, r2, r3 + ldr r11,[r2, #4] + ldr_post r10, r2, r3 + strd_post r4, r5, r0, r1 + strd_post r6, r7, r0, r1 + strd_post r8, r9, r0, r1 + strd_post r10, r11, r0, r1 + bgt 1b + pop {r4 - r11} + bx lr +endfunc + +@ void put_vp8_pixels4(uint8_t *dst, int dststride, uint8_t *src, +@ int srcstride, int h, int mx, int my) +function ff_put_vp8_pixels4_armv6, export=1 + ldr r12, [sp, #0] @ h + push {r4 - r6, lr} +1: + subs r12, r12, #4 + ldr r5, [r2, r3] + ldr_post r4, r2, r3, lsl #1 + ldr lr, [r2, r3] + ldr_post r6, r2, r3, lsl #1 + str r5, [r0, r1] + str_post r4, r0, r1, lsl #1 + str lr, [r0, r1] + str_post r6, r0, r1, lsl #1 + bgt 1b + pop {r4 - r6, pc} +endfunc + +@ note: worst case sum of all 6-tap filter values * 255 is 0x7f80 so 16 bit +@ arithmatic can be used to apply filters +const sixtap_filters_13245600, align=4 + .short 2, 108, -11, 36, -8, 1, 0, 0 + .short 3, 77, -16, 77, -16, 3, 0, 0 + .short 1, 36, -8, 108, -11, 2, 0, 0 +endconst +const fourtap_filters_1324, align=4 + .short -6, 12, 123, -1 + .short -9, 50, 93, -6 + .short -6, 93, 50, -9 + .short -1, 123, 12, -6 +endconst + +@ void put_vp8_epel_h6(uint8_t *dst, int dststride, uint8_t *src, +@ int srcstride, int w, int h, int mx) +function ff_put_vp8_epel_h6_armv6, export=1 + push {r4 - r11, lr} + + sub r2, r2, #2 + movrel lr, sixtap_filters_13245600 - 16 + ldr r12,[sp, #44] @ vp8_filter index + ldr r4, [sp, #36] @ width + add lr, lr, r12, lsl #3 + sub r3, r3, r4 @ src_stride - block_width + sub r1, r1, r4 @ dst_stride - block_width + lsr r4, #2 + + str r4, [sp, #36] @ "4-in-parallel" loop counter @40 + str r3, [sp, #44] @ src_stride - block_width @48 + push {r1} @ dst_stride - block_width @0 + @ height @44 + + ldr r1, [lr], #4 @ coefficients + ldr r3, [lr], #4 + ldr lr, [lr] +1: + @ 3 loads, 10 shuffles and then mul/acc/add/shr + @ o0: i0/i1/i2/i3/i4/i5 -> i0/i2 (ld1) | i1/i3 (ld1) | i4/i5 (ld2) + @ o1: i1/i2/i3/i4/i5/i6 -> i1/i3 (ld1) | i2/i4 (ld2) | i5/i6 (ld2/3) + @ o2: i2/i3/i4/i5/i6/i7 -> i2/i4 (ld2) | i3/i5 (ld2) | i6/i7 (ld3) + @ o3: i3/i4/i5/i6/i7/i8 -> i3/i5 (ld2) | i4/i6 (ld2/3) | i7/i8 (ld3) + ldr r7, [r2, #5] @ ld3 -> src[5-8] + ldr r6, [r2, #2] @ ld2 -> src[2-5] + ldr r5, [r2], #4 @ ld1 -> src[0-3] + + pkhtb r7, r7, r7, asr #8 @ src[8,7,7,6] + uxtb16 r9, r6, ror #8 @ src[5] | src[3] + uxtb16 r6, r6 @ src[4] | src[2] + uxtb16 r8, r5, ror #8 @ src[3] | src[1] + uxtb16 r11, r7, ror #8 @ src[8] | src[7] + uxtb16 r7, r7 @ src[7] | src[6] + pkhtb r10, r9, r6, asr #16 @ src[5] | src[4] + uxtb16 r5, r5 @ src[2] | src[0] + + smuad r11, r11, lr @ filter[3][2] -> r11 + subs r4, r4, #1 + pkhbt r12, r10, r7, lsl #16 @ src[6] | src[4] + smuad r7, r7, lr @ filter[2][2] -> r7 + smuad r5, r5, r1 @ filter[0][0] -> r5 + smlad r11, r9, r1, r11 @ filter[3][0] -> r11 + smlad r7, r9, r3, r7 @ filter[2][1] -> r7 + smuad r9, r8, r1 @ filter[1][0] -> r9 + smlad r5, r8, r3, r5 @ filter[0][1] -> r5 + pkhtb r8, r12, r10, asr #16 @ src[6] | src[5] + smlad r11, r12, r3, r11 @ filter[3][1] -> r11 + smlad r9, r6, r3, r9 @ filter[1][1] -> r9 + smlad r5, r10, lr, r5 @ filter[0][2] -> r5 + smlad r7, r6, r1, r7 @ filter[2][0] -> r7 + smlad r9, r8, lr, r9 @ filter[1][2] -> r9 + + add r5, r5, #0x40 @ round_shift_and_clamp[0] + add r9, r9, #0x40 @ round_shift_and_clamp[1] + add r7, r7, #0x40 @ round_shift_and_clamp[2] + add r11, r11, #0x40 @ round_shift_and_clamp[3] + + usat r5, #8, r5, asr #7 + usat r9, #8, r9, asr #7 + usat r7, #8, r7, asr #7 + usat r11, #8, r11, asr #7 + + strb r5, [r0], #1 @ store res[0] + strb r9, [r0], #1 @ store res[1] + strb r7, [r0], #1 @ store res[2] + strb r11,[r0], #1 @ store res[3] + + bne 1b + + ldr r12,[sp, #44] @ height = outer-loop counter + subs r12, r12, #1 +T itttt ne + ldrne r4, [sp, #40] @ 4-in-parallel loop counter + ldrne r5, [sp, #48] + ldrne r6, [sp] + strne r12,[sp, #44] + add r2, r2, r5 @ move to next input/output lines + add r0, r0, r6 + + bne 1b + + add sp, sp, #4 @ restore stack after push{r1} above + pop {r4 - r11, pc} +endfunc + +@ void put_vp8_epel_v6(uint8_t *dst, int dststride, uint8_t *src, +@ int srcstride, int w, int h, int my) +function ff_put_vp8_epel_v6_armv6, export=1 + push {r4 - r11, lr} + + movrel lr, sixtap_filters_13245600 - 16 + ldr r12,[sp, #44] @ vp8_filter index + ldr r4, [sp, #36] @ width + add lr, lr, r12, lsl #3 + sub r1, r1, r4 @ dst_stride - block_width + lsr r4, #2 + + str r4, [sp, #36] @ "4-in-parallel" loop counter @40 + str r3, [sp, #44] @ src_stride - block_width @48 + push {r1} @ dst_stride - block_width @0 + @ height @44 +1: + add r1, r3, r3, lsl #1 @ stride * 3 + ldr_dpren r5, r2, r3 @ src[0,1,2,3 + stride * 1] + ldr r6, [r2, r3] @ src[0,1,2,3 + stride * 3] + ldr r7, [r2, r3, lsl #1] @ src[0,1,2,3 + stride * 4] + ldr r8, [r2, r1] @ src[0,1,2,3 + stride * 5] + + @ byte -> word and "transpose" + uxtb16 r9, r5, ror #8 @ src[3 + stride*1] | src[1 + stride*1] + uxtb16 r10, r6, ror #8 @ src[3 + stride*3] | src[1 + stride*3] + uxtb16 r11, r7, ror #8 @ src[3 + stride*4] | src[1 + stride*4] + uxtb16 r12, r8, ror #8 @ src[3 + stride*5] | src[1 + stride*5] + uxtb16 r5, r5 @ src[2 + stride*1] | src[0 + stride*1] + uxtb16 r6, r6 @ src[2 + stride*3] | src[0 + stride*3] + uxtb16 r7, r7 @ src[2 + stride*4] | src[0 + stride*4] + uxtb16 r8, r8 @ src[2 + stride*5] | src[0 + stride*5] + pkhbt r1, r9, r10, lsl #16 @ src[1 + stride*3] | src[1 + stride*1] + pkhtb r9, r10, r9, asr #16 @ src[3 + stride*3] | src[3 + stride*1] + pkhbt r10, r11, r12, lsl #16 @ src[1 + stride*5] | src[1 + stride*4] + pkhtb r11, r12, r11, asr #16 @ src[3 + stride*5] | src[3 + stride*4] + pkhbt r12, r5, r6, lsl #16 @ src[0 + stride*3] | src[0 + stride*1] + pkhtb r5, r6, r5, asr #16 @ src[2 + stride*3] | src[2 + stride*1] + pkhbt r6, r7, r8, lsl #16 @ src[0 + stride*5] | src[0 + stride*4] + pkhtb r7, r8, r7, asr #16 @ src[2 + stride*5] | src[2 + stride*4] + + ldr r8, [lr, #4] @ stall - if only I had more registers... + smuad r12, r12, r8 @ filter[0][1] + smuad r1, r1, r8 @ filter[1][1] + smuad r5, r5, r8 @ filter[2][1] + smuad r9, r9, r8 @ filter[3][1] + ldr r8, [lr, #8] @ stall - if only I had more registers... + smlad r12, r6, r8, r12 @ filter[0][2] + smlad r1, r10, r8, r1 @ filter[1][2] + ldr_dpren r6, r2, r3, lsl #1 @ src[0,1,2,3 + stride * 0] + ldr r10,[r2], #4 @ src[0,1,2,3 + stride * 2] + smlad r5, r7, r8, r5 @ filter[2][2] + smlad r9, r11, r8, r9 @ filter[3][2] + + uxtb16 r7, r6, ror #8 @ src[3 + stride*0] | src[1 + stride*0] + uxtb16 r11, r10, ror #8 @ src[3 + stride*2] | src[1 + stride*2] + uxtb16 r6, r6 @ src[2 + stride*0] | src[0 + stride*0] + uxtb16 r10, r10 @ src[2 + stride*2] | src[0 + stride*2] + + pkhbt r8, r7, r11, lsl #16 @ src[1 + stride*2] | src[1 + stride*0] + pkhtb r7, r11, r7, asr #16 @ src[3 + stride*2] | src[3 + stride*0] + pkhbt r11, r6, r10, lsl #16 @ src[0 + stride*2] | src[0 + stride*0] + pkhtb r6, r10, r6, asr #16 @ src[2 + stride*2] | src[2 + stride*0] + + ldr r10,[lr] @ stall - if only I had more registers... + subs r4, r4, #1 @ counter-- + smlad r12, r11, r10, r12 @ filter[0][0] + smlad r1, r8, r10, r1 @ filter[1][0] + smlad r5, r6, r10, r5 @ filter[2][0] + smlad r9, r7, r10, r9 @ filter[3][0] + + add r12, r12, #0x40 @ round_shift_and_clamp[0] + add r1, r1, #0x40 @ round_shift_and_clamp[1] + add r5, r5, #0x40 @ round_shift_and_clamp[2] + add r9, r9, #0x40 @ round_shift_and_clamp[3] + + usat r12, #8, r12, asr #7 + usat r1, #8, r1, asr #7 + usat r5, #8, r5, asr #7 + usat r9, #8, r9, asr #7 + + strb r12,[r0], #1 @ store res[0] + strb r1, [r0], #1 @ store res[1] + strb r5, [r0], #1 @ store res[2] + strb r9, [r0], #1 @ store res[3] + + bne 1b + + ldr r12,[sp, #44] @ height = outer-loop counter + subs r12, r12, #1 +T itttt ne + ldrne r4, [sp, #40] @ 4-in-parallel loop counter + ldrne r6, [sp, #0] + subne r2, r2, r4, lsl #2 + strne r12,[sp, #44] + add r0, r0, r6 + add r2, r2, r3 @ move to next input/output lines + + bne 1b + + add sp, sp, #4 @ restore stack after push{r1} above + pop {r4 - r11, pc} +endfunc + +@ void put_vp8_epel_h4(uint8_t *dst, int dststride, uint8_t *src, +@ int srcstride, int w, int h, int mx) +function ff_put_vp8_epel_h4_armv6, export=1 + push {r4 - r11, lr} + + subs r2, r2, #1 + movrel lr, fourtap_filters_1324 - 4 + ldr r4, [sp, #36] @ width + ldr r12,[sp, #44] @ vp8_filter index + add lr, lr, r12, lsl #2 + sub r3, r3, r4 @ src_stride - block_width + sub r1, r1, r4 @ dst_stride - block_width + ldr r5, [lr] + ldr r6, [lr, #4] + asr r4, #2 + + ldr lr, [sp, #40] @ height = outer-loop counter + str r4, [sp, #36] @ "4-in-parallel" inner loop counter +1: + @ 3 loads, 5 uxtb16s and then mul/acc/add/shr + @ o0: i0/i1/i2/i3 -> i0/i2(ld1) + i1/i3(ld1) + @ o1: i1/i2/i3/i4 -> i1/i3(ld1) + i2/i4(ld2) + @ o2: i2/i3/i4/i5 -> i2/i4(ld2) + i3/i5(ld2) + @ o3: i3/i4/i5/i6 -> i3/i5(ld2) + i4/i6(ld3) + ldr r9, [r2, #3] @ load source data + ldr r8, [r2, #2] + ldr r7, [r2], #4 + + uxtb16 r9, r9, ror #8 @ src[6] | src[4] + uxtb16 r10, r8, ror #8 @ src[5] | src[3] + uxtb16 r8, r8 @ src[4] | src[2] + uxtb16 r11, r7, ror #8 @ src[3] | src[1] + uxtb16 r7, r7 @ src[2] | src[0] + + smuad r9, r9, r6 @ filter[3][1] -> r9 + smuad r12, r10, r6 @ filter[2][1] -> r12 + smuad r7, r7, r5 @ filter[0][0] -> r7 + smlad r9, r10, r5, r9 @ filter[3][0] -> r9 + smuad r10, r11, r5 @ filter[1][0] -> r10 + smlad r12, r8, r5, r12 @ filter[2][0] -> r12 + smlad r7, r11, r6, r7 @ filter[0][1] -> r7 + smlad r10, r8, r6, r10 @ filter[1][1] -> r10 + + subs r4, r4, #1 @ counter-- + + add r7, r7, #0x40 @ round_shift_and_clamp[0] + add r10, r10, #0x40 @ round_shift_and_clamp[1] + add r12, r12, #0x40 @ round_shift_and_clamp[2] + add r9, r9, #0x40 @ round_shift_and_clamp[3] + + usat r7, #8, r7, asr #7 + usat r10, #8, r10, asr #7 + usat r12, #8, r12, asr #7 + usat r9, #8, r9, asr #7 + + strb r7, [r0], #1 @ store res[0] + strb r10,[r0], #1 @ store res[1] + strb r12,[r0], #1 @ store res[2] + strb r9, [r0], #1 @ store res[3] + + bne 1b + + subs lr, lr, #1 +T it ne + ldrne r4, [sp, #36] @ 4-in-parallel loop counter + add r2, r2, r3 @ move to next input/output lines + add r0, r0, r1 + + bne 1b + + pop {r4 - r11, pc} +endfunc + +@ void put_vp8_epel_v4(uint8_t *dst, int dststride, uint8_t *src, +@ int srcstride, int w, int h, int my) +function ff_put_vp8_epel_v4_armv6, export=1 + push {r4 - r11, lr} + + movrel lr, fourtap_filters_1324 - 4 + ldr r12,[sp, #44] @ vp8_filter index + ldr r4, [sp, #36] @ width + add lr, lr, r12, lsl #2 + sub r1, r1, r4 @ dst_stride - block_width + asr r4, #2 + ldr r5, [lr] + ldr r6, [lr, #4] + + str r4, [sp, #36] @ "4-in-parallel" loop counter @40 + str r3, [sp, #44] @ src_stride @48 + push {r1} @ dst_stride - block_width @36 + @ height @44 +1: + ldr lr, [r2, r3, lsl #1] @ load source pixels + ldr r12,[r2, r3] + ldr_dpren r7, r2, r3 + ldr r11,[r2], #4 + + @ byte -> word and "transpose" + uxtb16 r8, lr, ror #8 @ src[3 + stride*3] | src[1 + stride*3] + uxtb16 r9, r12, ror #8 @ src[3 + stride*2] | src[1 + stride*2] + uxtb16 r3, r7, ror #8 @ src[3 + stride*0] | src[1 + stride*0] + uxtb16 r1, r11, ror #8 @ src[3 + stride*1] | src[1 + stride*1] + uxtb16 lr, lr @ src[2 + stride*3] | src[0 + stride*3] + uxtb16 r12, r12 @ src[2 + stride*2] | src[0 + stride*2] + uxtb16 r7, r7 @ src[2 + stride*0] | src[0 + stride*0] + uxtb16 r11, r11 @ src[2 + stride*1] | src[0 + stride*1] + pkhbt r10, r1, r8, lsl #16 @ src[1 + stride*3] | src[1 + stride*1] + pkhtb r1, r8, r1, asr #16 @ src[3 + stride*3] | src[3 + stride*1] + pkhbt r8, r3, r9, lsl #16 @ src[1 + stride*2] | src[1 + stride*0] + pkhtb r3, r9, r3, asr #16 @ src[3 + stride*2] | src[3 + stride*0] + pkhbt r9, r11, lr, lsl #16 @ src[0 + stride*3] | src[0 + stride*1] + pkhtb r11, lr, r11, asr #16 @ src[2 + stride*3] | src[2 + stride*1] + pkhbt lr, r7, r12, lsl #16 @ src[0 + stride*2] | src[0 + stride*0] + pkhtb r7, r12, r7, asr #16 @ src[2 + stride*2] | src[2 + stride*0] + + smuad r9, r9, r6 @ filter[0][1] + smuad r10, r10, r6 @ filter[1][1] + smuad r11, r11, r6 @ filter[2][1] + smuad r1, r1, r6 @ filter[3][1] + smlad r9, lr, r5, r9 @ filter[0][0] + smlad r10, r8, r5, r10 @ filter[1][0] + smlad r11, r7, r5, r11 @ filter[2][0] + smlad r1, r3, r5, r1 @ filter[3][0] + + subs r4, r4, #1 @ counter-- + ldr r3, [sp, #48] @ FIXME prevent clobber of r3 above? + + add r9, r9, #0x40 @ round_shift_and_clamp[0] + add r10, r10, #0x40 @ round_shift_and_clamp[1] + add r11, r11, #0x40 @ round_shift_and_clamp[2] + add r1, r1, #0x40 @ round_shift_and_clamp[3] + + usat r9, #8, r9, asr #7 + usat r10, #8, r10, asr #7 + usat r11, #8, r11, asr #7 + usat r1, #8, r1, asr #7 + + strb r9, [r0], #1 @ store result + strb r10,[r0], #1 + strb r11,[r0], #1 + strb r1, [r0], #1 + + bne 1b + + ldr r12,[sp, #44] @ height = outer-loop counter + subs r12, r12, #1 +T ittt ne + ldrne r4, [sp, #40] @ 4-in-parallel loop counter + ldrne r9, [sp, #0] + strne r12,[sp, #44] + sub r2, r2, r4, lsl #2 + add r0, r0, r9 + add r2, r2, r3 @ move to next input/output lines + + bne 1b + + add sp, sp, #4 @ restore stack after push{r1} above + pop {r4 - r11, pc} +endfunc + +@ void put_vp8_bilin_h(uint8_t *dst, int dststride, uint8_t *src, +@ int srcstride, int w, int h, int mx) +function ff_put_vp8_bilin_h_armv6, export=1 + push {r4 - r9, lr} + + ldr r8, [sp, #36] @ vp8_filter index + ldr r12,[sp, #32] @ height = outer-loop counter + ldr r4, [sp, #28] @ width + lsl r5, r8, #16 @ mx << 16 + sub r3, r3, r4 @ src_stride - block_width + sub r1, r1, r4 @ dst_stride - block_width + asr r4, #2 + sub r5, r5, r8 @ (mx << 16) | (-mx) + str r4, [sp, #28] @ "4-in-parallel" loop counter + add r5, r5, #8 @ (8 - mx) | (mx << 16) = filter coefficients +1: + ldrb r6, [r2], #1 @ load source data + ldrb r7, [r2], #1 + ldrb r8, [r2], #1 + ldrb r9, [r2], #1 + ldrb lr, [r2] + + pkhbt r6, r6, r7, lsl #16 @ src[1] | src[0] + pkhbt r7, r7, r8, lsl #16 @ src[2] | src[1] + pkhbt r8, r8, r9, lsl #16 @ src[3] | src[2] + pkhbt r9, r9, lr, lsl #16 @ src[4] | src[3] + + smuad r6, r6, r5 @ apply the filter + smuad r7, r7, r5 + smuad r8, r8, r5 + smuad r9, r9, r5 + + subs r4, r4, #1 @ counter-- + + add r6, r6, #0x4 @ round_shift_and_clamp + add r7, r7, #0x4 + add r8, r8, #0x4 + add r9, r9, #0x4 + + asr r6, #3 + asr r7, #3 + pkhbt r6, r6, r8, lsl #13 + pkhbt r7, r7, r9, lsl #13 + orr r6, r6, r7, lsl #8 + str r6, [r0], #4 @ store result + + bne 1b + + ldr r4, [sp, #28] @ 4-in-parallel loop counter + subs r12, r12, #1 + + add r2, r2, r3 @ move to next input/output lines + add r0, r0, r1 + + bne 1b + + pop {r4 - r9, pc} +endfunc + +@ void put_vp8_bilin_v(uint8_t *dst, int dststride, uint8_t *src, +@ int srcstride, int w, int h, int my) +function ff_put_vp8_bilin_v_armv6, export=1 + push {r4 - r11, lr} + + ldr r11,[sp, #44] @ vp8_filter index + ldr r4, [sp, #36] @ width + mov r5, r11, lsl #16 @ mx << 16 + ldr r12,[sp, #40] @ height = outer-loop counter + sub r1, r1, r4 + sub r5, r5, r11 @ (mx << 16) | (-mx) + asr r4, #2 + add r5, r5, #8 @ (8 - mx) | (mx << 16) = filter coefficients + str r4, [sp, #36] @ "4-in-parallel" loop counter +1: + ldrb r10,[r2, r3] @ load the data + ldrb r6, [r2], #1 + ldrb r11,[r2, r3] + ldrb r7, [r2], #1 + ldrb lr, [r2, r3] + ldrb r8, [r2], #1 + ldrb r9, [r2, r3] + pkhbt r6, r6, r10, lsl #16 + ldrb r10,[r2], #1 + pkhbt r7, r7, r11, lsl #16 + pkhbt r8, r8, lr, lsl #16 + pkhbt r9, r10, r9, lsl #16 + + smuad r6, r6, r5 @ apply the filter + smuad r7, r7, r5 + smuad r8, r8, r5 + smuad r9, r9, r5 + + subs r4, r4, #1 @ counter-- + + add r6, r6, #0x4 @ round_shift_and_clamp + add r7, r7, #0x4 + add r8, r8, #0x4 + add r9, r9, #0x4 + + asr r6, #3 + asr r7, #3 + pkhbt r6, r6, r8, lsl #13 + pkhbt r7, r7, r9, lsl #13 + orr r6, r6, r7, lsl #8 + str r6, [r0], #4 @ store result + + bne 1b + + ldr r4, [sp, #36] @ 4-in-parallel loop counter + subs r12, r12, #1 + + add r2, r2, r3 @ move to next input/output lines + add r0, r0, r1 + sub r2, r2, r4, lsl #2 + + bne 1b + pop {r4 - r11, pc} +endfunc diff --git a/libavcodec/arm/vp8dsp_init_arm.c b/libavcodec/arm/vp8dsp_init_arm.c index 5eea8464dd..14021c954d 100644 --- a/libavcodec/arm/vp8dsp_init_arm.c +++ b/libavcodec/arm/vp8dsp_init_arm.c @@ -1,31 +1,35 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdint.h> #include "libavcodec/vp8dsp.h" -void ff_vp8_luma_dc_wht_neon(DCTELEM block[4][4][16], DCTELEM dc[16]); -void ff_vp8_luma_dc_wht_dc_neon(DCTELEM block[4][4][16], DCTELEM dc[16]); +void ff_vp8_luma_dc_wht_dc_armv6(DCTELEM block[4][4][16], DCTELEM dc[16]); -void ff_vp8_idct_add_neon(uint8_t *dst, DCTELEM block[16], int stride); -void ff_vp8_idct_dc_add_neon(uint8_t *dst, DCTELEM block[16], int stride); -void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, DCTELEM block[4][16], int stride); -void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, DCTELEM block[4][16], int stride); +#define idct_funcs(opt) \ +void ff_vp8_luma_dc_wht_ ## opt(DCTELEM block[4][4][16], DCTELEM dc[16]); \ +void ff_vp8_idct_add_ ## opt(uint8_t *dst, DCTELEM block[16], int stride); \ +void ff_vp8_idct_dc_add_ ## opt(uint8_t *dst, DCTELEM block[16], int stride); \ +void ff_vp8_idct_dc_add4y_ ## opt(uint8_t *dst, DCTELEM block[4][16], int stride); \ +void ff_vp8_idct_dc_add4uv_ ## opt(uint8_t *dst, DCTELEM block[4][16], int stride) + +idct_funcs(neon); +idct_funcs(armv6); void ff_vp8_v_loop_filter16_neon(uint8_t *dst, int stride, int flim_E, int flim_I, int hev_thresh); @@ -47,29 +51,106 @@ void ff_vp8_h_loop_filter8uv_inner_neon(uint8_t *dstU, uint8_t *dstV, int stride, int flim_E, int flim_I, int hev_thresh); -void ff_vp8_v_loop_filter16_simple_neon(uint8_t *dst, int stride, int flim); -void ff_vp8_h_loop_filter16_simple_neon(uint8_t *dst, int stride, int flim); +void ff_vp8_v_loop_filter_inner_armv6(uint8_t *dst, int stride, + int flim_E, int flim_I, + int hev_thresh, int count); +void ff_vp8_h_loop_filter_inner_armv6(uint8_t *dst, int stride, + int flim_E, int flim_I, + int hev_thresh, int count); +void ff_vp8_v_loop_filter_armv6(uint8_t *dst, int stride, + int flim_E, int flim_I, + int hev_thresh, int count); +void ff_vp8_h_loop_filter_armv6(uint8_t *dst, int stride, + int flim_E, int flim_I, + int hev_thresh, int count); +static void ff_vp8_v_loop_filter16_armv6(uint8_t *dst, int stride, + int flim_E, int flim_I, int hev_thresh) +{ + ff_vp8_v_loop_filter_armv6(dst, stride, flim_E, flim_I, hev_thresh, 4); +} + +static void ff_vp8_h_loop_filter16_armv6(uint8_t *dst, int stride, + int flim_E, int flim_I, int hev_thresh) +{ + ff_vp8_h_loop_filter_armv6(dst, stride, flim_E, flim_I, hev_thresh, 4); +} -#define VP8_MC(n) \ - void ff_put_vp8_##n##_neon(uint8_t *dst, int dststride, \ - uint8_t *src, int srcstride, \ - int h, int x, int y) +static void ff_vp8_v_loop_filter8uv_armv6(uint8_t *dstU, uint8_t *dstV, int stride, + int flim_E, int flim_I, int hev_thresh) +{ + ff_vp8_v_loop_filter_armv6(dstU, stride, flim_E, flim_I, hev_thresh, 2); + ff_vp8_v_loop_filter_armv6(dstV, stride, flim_E, flim_I, hev_thresh, 2); +} + +static void ff_vp8_h_loop_filter8uv_armv6(uint8_t *dstU, uint8_t *dstV, int stride, + int flim_E, int flim_I, int hev_thresh) +{ + ff_vp8_h_loop_filter_armv6(dstU, stride, flim_E, flim_I, hev_thresh, 2); + ff_vp8_h_loop_filter_armv6(dstV, stride, flim_E, flim_I, hev_thresh, 2); +} + +static void ff_vp8_v_loop_filter16_inner_armv6(uint8_t *dst, int stride, + int flim_E, int flim_I, int hev_thresh) +{ + ff_vp8_v_loop_filter_inner_armv6(dst, stride, flim_E, flim_I, hev_thresh, 4); +} + +static void ff_vp8_h_loop_filter16_inner_armv6(uint8_t *dst, int stride, + int flim_E, int flim_I, int hev_thresh) +{ + ff_vp8_h_loop_filter_inner_armv6(dst, stride, flim_E, flim_I, hev_thresh, 4); +} + +static void ff_vp8_v_loop_filter8uv_inner_armv6(uint8_t *dstU, uint8_t *dstV, + int stride, int flim_E, int flim_I, + int hev_thresh) +{ + ff_vp8_v_loop_filter_inner_armv6(dstU, stride, flim_E, flim_I, hev_thresh, 2); + ff_vp8_v_loop_filter_inner_armv6(dstV, stride, flim_E, flim_I, hev_thresh, 2); +} + +static void ff_vp8_h_loop_filter8uv_inner_armv6(uint8_t *dstU, uint8_t *dstV, + int stride, int flim_E, int flim_I, + int hev_thresh) +{ + ff_vp8_h_loop_filter_inner_armv6(dstU, stride, flim_E, flim_I, hev_thresh, 2); + ff_vp8_h_loop_filter_inner_armv6(dstV, stride, flim_E, flim_I, hev_thresh, 2); +} + +#define simple_lf_funcs(opt) \ +void ff_vp8_v_loop_filter16_simple_ ## opt(uint8_t *dst, int stride, int flim); \ +void ff_vp8_h_loop_filter16_simple_ ## opt(uint8_t *dst, int stride, int flim) + +simple_lf_funcs(neon); +simple_lf_funcs(armv6); + +#define VP8_MC_OPT(n, opt) \ + void ff_put_vp8_##n##_##opt(uint8_t *dst, int dststride, \ + uint8_t *src, int srcstride, \ + int h, int x, int y) + +#define VP8_MC(n) \ + VP8_MC_OPT(n, neon) #define VP8_EPEL(w) \ - VP8_MC(pixels ## w); \ VP8_MC(epel ## w ## _h4); \ VP8_MC(epel ## w ## _h6); \ - VP8_MC(epel ## w ## _v4); \ VP8_MC(epel ## w ## _h4v4); \ VP8_MC(epel ## w ## _h6v4); \ + VP8_MC(epel ## w ## _v4); \ VP8_MC(epel ## w ## _v6); \ VP8_MC(epel ## w ## _h4v6); \ VP8_MC(epel ## w ## _h6v6) VP8_EPEL(16); +VP8_MC(pixels16); +VP8_MC_OPT(pixels16, armv6); VP8_EPEL(8); +VP8_MC(pixels8); +VP8_MC_OPT(pixels8, armv6); VP8_EPEL(4); +VP8_MC_OPT(pixels4, armv6); VP8_MC(bilin16_h); VP8_MC(bilin16_v); @@ -81,83 +162,148 @@ VP8_MC(bilin4_h); VP8_MC(bilin4_v); VP8_MC(bilin4_hv); +#define VP8_V6_MC(n) \ +void ff_put_vp8_##n##_armv6(uint8_t *dst, int dststride, uint8_t *src, \ + int srcstride, int w, int h, int mxy) + +VP8_V6_MC(epel_v6); +VP8_V6_MC(epel_h6); +VP8_V6_MC(epel_v4); +VP8_V6_MC(epel_h4); +VP8_V6_MC(bilin_v); +VP8_V6_MC(bilin_h); + +#define VP8_EPEL_HV(SIZE, TAPNUMX, TAPNUMY, NAME, HNAME, VNAME, MAXHEIGHT) \ +static void ff_put_vp8_##NAME##SIZE##_##HNAME##VNAME##_armv6( \ + uint8_t *dst, int dststride, uint8_t *src, \ + int srcstride, int h, int mx, int my) \ +{ \ + DECLARE_ALIGNED(4, uint8_t, tmp)[SIZE * (MAXHEIGHT + TAPNUMY - 1)]; \ + uint8_t *tmpptr = tmp + SIZE * (TAPNUMY / 2 - 1); \ + src -= srcstride * (TAPNUMY / 2 - 1); \ + ff_put_vp8_ ## NAME ## _ ## HNAME ## _armv6(tmp, SIZE, src, srcstride, \ + SIZE, h + TAPNUMY - 1, mx); \ + ff_put_vp8_ ## NAME ## _ ## VNAME ## _armv6(dst, dststride, tmpptr, SIZE, \ + SIZE, h, my); \ +} + +VP8_EPEL_HV(16, 6, 6, epel, h6, v6, 16); +VP8_EPEL_HV(16, 2, 2, bilin, h, v, 16); +VP8_EPEL_HV(8, 6, 6, epel, h6, v6, 16); +VP8_EPEL_HV(8, 4, 6, epel, h4, v6, 16); +VP8_EPEL_HV(8, 6, 4, epel, h6, v4, 16); +VP8_EPEL_HV(8, 4, 4, epel, h4, v4, 16); +VP8_EPEL_HV(8, 2, 2, bilin, h, v, 16); +VP8_EPEL_HV(4, 6, 6, epel, h6, v6, 8); +VP8_EPEL_HV(4, 4, 6, epel, h4, v6, 8); +VP8_EPEL_HV(4, 6, 4, epel, h6, v4, 8); +VP8_EPEL_HV(4, 4, 4, epel, h4, v4, 8); +VP8_EPEL_HV(4, 2, 2, bilin, h, v, 8); + +extern void put_vp8_epel4_v6_c(uint8_t *dst, int d, uint8_t *src, int s, int h, int mx, int my); +#undef printf +#define VP8_EPEL_H_OR_V(SIZE, NAME, HV) \ +static void ff_put_vp8_##NAME##SIZE##_##HV##_armv6( \ + uint8_t *dst, int dststride, uint8_t *src, \ + int srcstride, int h, int mx, int my) \ +{ \ + ff_put_vp8_## NAME ## _ ## HV ## _armv6(dst, dststride, src, srcstride, \ + SIZE, h, mx | my); \ +} + +VP8_EPEL_H_OR_V(4, epel, h6); +VP8_EPEL_H_OR_V(4, epel, h4); +VP8_EPEL_H_OR_V(4, epel, v6); +VP8_EPEL_H_OR_V(4, epel, v4); +VP8_EPEL_H_OR_V(4, bilin, v); +VP8_EPEL_H_OR_V(4, bilin, h); +VP8_EPEL_H_OR_V(8, epel, h6); +VP8_EPEL_H_OR_V(8, epel, h4); +VP8_EPEL_H_OR_V(8, epel, v6); +VP8_EPEL_H_OR_V(8, epel, v4); +VP8_EPEL_H_OR_V(8, bilin, v); +VP8_EPEL_H_OR_V(8, bilin, h); +VP8_EPEL_H_OR_V(16, epel, h6); +VP8_EPEL_H_OR_V(16, epel, v6); +VP8_EPEL_H_OR_V(16, bilin, v); +VP8_EPEL_H_OR_V(16, bilin, h); + av_cold void ff_vp8dsp_init_arm(VP8DSPContext *dsp) { +#define set_func_ptrs(opt) \ + dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_##opt; \ + dsp->vp8_luma_dc_wht_dc = ff_vp8_luma_dc_wht_dc_armv6; \ + \ + dsp->vp8_idct_add = ff_vp8_idct_add_##opt; \ + dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_##opt; \ + dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_##opt; \ + dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_##opt; \ + \ + dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_##opt; \ + dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_##opt; \ + dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_##opt; \ + dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_##opt; \ + \ + dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_##opt; \ + dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_##opt; \ + dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_##opt; \ + dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_##opt; \ + \ + dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter16_simple_##opt; \ + dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter16_simple_##opt; \ + \ + dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_##opt; \ + dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_##opt; \ + dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_##opt; \ + dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_##opt; \ + \ + dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_##opt; \ + dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_##opt; \ + dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_##opt; \ + dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_##opt; \ + dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_##opt; \ + dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_##opt; \ + dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_##opt; \ + dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_##opt; \ + dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_##opt; \ + \ + dsp->put_vp8_epel_pixels_tab[2][0][0] = ff_put_vp8_pixels4_armv6; \ + dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_##opt; \ + dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_##opt; \ + dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_##opt; \ + dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_##opt; \ + dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_##opt; \ + dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_##opt; \ + dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_##opt; \ + dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_##opt; \ + \ + dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilin16_h_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilin16_v_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilin16_hv_##opt; \ + \ + dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilin8_h_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilin8_h_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilin8_v_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilin8_hv_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilin8_hv_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilin8_v_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilin8_hv_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilin8_hv_##opt; \ + \ + dsp->put_vp8_bilinear_pixels_tab[2][0][0] = ff_put_vp8_pixels4_armv6; \ + dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilin4_h_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilin4_h_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilin4_v_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilin4_hv_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilin4_hv_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilin4_v_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilin4_hv_##opt; \ + dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilin4_hv_##opt if (HAVE_NEON) { - dsp->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_neon; - dsp->vp8_luma_dc_wht_dc = ff_vp8_luma_dc_wht_dc_neon; - - dsp->vp8_idct_add = ff_vp8_idct_add_neon; - dsp->vp8_idct_dc_add = ff_vp8_idct_dc_add_neon; - dsp->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_neon; - dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_neon; - - dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_neon; - dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_neon; - dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_neon; - dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_neon; - - dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_neon; - dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_neon; - dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_neon; - dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_neon; - - dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter16_simple_neon; - dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter16_simple_neon; - - dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon; - dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_neon; - dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_neon; - dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_neon; - - dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon; - dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_neon; - dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_neon; - dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_neon; - dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_neon; - dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_neon; - dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_neon; - dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_neon; - dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_neon; - - dsp->put_vp8_epel_pixels_tab[2][0][0] = ff_put_vp8_pixels4_neon; - dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_neon; - dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_neon; - dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_neon; - dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_neon; - dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_neon; - dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_neon; - dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_neon; - dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_neon; - - dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon; - dsp->put_vp8_bilinear_pixels_tab[0][0][1] = ff_put_vp8_bilin16_h_neon; - dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilin16_h_neon; - dsp->put_vp8_bilinear_pixels_tab[0][1][0] = ff_put_vp8_bilin16_v_neon; - dsp->put_vp8_bilinear_pixels_tab[0][1][1] = ff_put_vp8_bilin16_hv_neon; - dsp->put_vp8_bilinear_pixels_tab[0][1][2] = ff_put_vp8_bilin16_hv_neon; - dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilin16_v_neon; - dsp->put_vp8_bilinear_pixels_tab[0][2][1] = ff_put_vp8_bilin16_hv_neon; - dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilin16_hv_neon; - - dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon; - dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilin8_h_neon; - dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilin8_h_neon; - dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilin8_v_neon; - dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilin8_hv_neon; - dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilin8_hv_neon; - dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilin8_v_neon; - dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilin8_hv_neon; - dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilin8_hv_neon; - - dsp->put_vp8_bilinear_pixels_tab[2][0][0] = ff_put_vp8_pixels4_neon; - dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilin4_h_neon; - dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilin4_h_neon; - dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilin4_v_neon; - dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilin4_hv_neon; - dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilin4_hv_neon; - dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilin4_v_neon; - dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilin4_hv_neon; - dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilin4_hv_neon; + set_func_ptrs(neon); + } else if (HAVE_ARMV6) { + set_func_ptrs(armv6); } } diff --git a/libavcodec/arm/vp8dsp_neon.S b/libavcodec/arm/vp8dsp_neon.S index e9f5b298ce..a9f698dfed 100644 --- a/libavcodec/arm/vp8dsp_neon.S +++ b/libavcodec/arm/vp8dsp_neon.S @@ -4,20 +4,20 @@ * Copyright (c) 2010 Rob Clark <rob@ti.com> * Copyright (c) 2011 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -77,18 +77,6 @@ function ff_vp8_luma_dc_wht_neon, export=1 bx lr endfunc -function ff_vp8_luma_dc_wht_dc_neon, export=1 - ldrsh r2, [r1] - mov r3, #0 - add r2, r2, #3 - strh r3, [r1] - asr r2, r2, #3 - .rept 16 - strh r2, [r0], #32 - .endr - bx lr -endfunc - function ff_vp8_idct_add_neon, export=1 vld1.16 {q0-q1}, [r1,:128] movw r3, #20091 @@ -725,23 +713,6 @@ function ff_put_vp8_pixels8_neon, export=1 bx lr endfunc -function ff_put_vp8_pixels4_neon, export=1 - ldr r12, [sp, #0] @ h - push {r4-r6,lr} -1: - subs r12, r12, #4 - ldr_post r4, r2, r3 - ldr_post r5, r2, r3 - ldr_post r6, r2, r3 - ldr_post lr, r2, r3 - str_post r4, r0, r1 - str_post r5, r0, r1 - str_post r6, r0, r1 - str_post lr, r0, r1 - bgt 1b - pop {r4-r6,pc} -endfunc - /* 4/6-tap 8th-pel MC */ .macro vp8_epel8_h6 d, a, b diff --git a/libavcodec/ass.c b/libavcodec/ass.c index 327a77bb45..8c94d724eb 100644 --- a/libavcodec/ass.c +++ b/libavcodec/ass.c @@ -2,20 +2,20 @@ * SSA/ASS common funtions * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -23,30 +23,13 @@ #include "ass.h" #include "libavutil/avstring.h" -/** - * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS. - * - * @param avctx pointer to the AVCodecContext - * @param font name of the default font face to use - * @param font_size default font size to use - * @param color default text color to use (ABGR) - * @param back_color default background color to use (ABGR) - * @param bold 1 for bold text, 0 for normal text - * @param italic 1 for italic text, 0 for normal text - * @param underline 1 for underline text, 0 for normal text - * @param alignment position of the text (left, center, top...), defined after - * the layout of the numpad (1-3 sub, 4-6 mid, 7-9 top) - * @return >= 0 on success otherwise an error code <0 - */ -static int ff_ass_subtitle_header(AVCodecContext *avctx, - const char *font, int font_size, - int color, int back_color, - int bold, int italic, int underline, - int alignment) +int ff_ass_subtitle_header(AVCodecContext *avctx, + const char *font, int font_size, + int color, int back_color, + int bold, int italic, int underline, + int alignment) { - char header[512]; - - snprintf(header, sizeof(header), + avctx->subtitle_header = av_asprintf( "[Script Info]\r\n" "ScriptType: v4.00+\r\n" "\r\n" @@ -59,7 +42,6 @@ static int ff_ass_subtitle_header(AVCodecContext *avctx, font, font_size, color, color, back_color, back_color, -bold, -italic, -underline, alignment); - avctx->subtitle_header = av_strdup(header); if (!avctx->subtitle_header) return AVERROR(ENOMEM); avctx->subtitle_header_size = strlen(avctx->subtitle_header); @@ -78,11 +60,6 @@ int ff_ass_subtitle_header_default(AVCodecContext *avctx) ASS_DEFAULT_ALIGNMENT); } -void ff_ass_init(AVSubtitle *sub) -{ - memset(sub, 0, sizeof(*sub)); -} - static int ts_to_string(char *str, int strlen, int ts) { int h, m, s; diff --git a/libavcodec/ass.h b/libavcodec/ass.h index 594b5f3ac6..efff44d6ed 100644 --- a/libavcodec/ass.h +++ b/libavcodec/ass.h @@ -2,20 +2,20 @@ * SSA/ASS common funtions * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -39,20 +39,34 @@ /** @} */ /** - * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS - * with default style. + * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS. * * @param avctx pointer to the AVCodecContext + * @param font name of the default font face to use + * @param font_size default font size to use + * @param color default text color to use (ABGR) + * @param back_color default background color to use (ABGR) + * @param bold 1 for bold text, 0 for normal text + * @param italic 1 for italic text, 0 for normal text + * @param underline 1 for underline text, 0 for normal text + * @param alignment position of the text (left, center, top...), defined after + * the layout of the numpad (1-3 sub, 4-6 mid, 7-9 top) * @return >= 0 on success otherwise an error code <0 */ -int ff_ass_subtitle_header_default(AVCodecContext *avctx); +int ff_ass_subtitle_header(AVCodecContext *avctx, + const char *font, int font_size, + int color, int back_color, + int bold, int italic, int underline, + int alignment); /** - * Initialize an AVSubtitle structure for use with ff_ass_add_rect(). + * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS + * with default style. * - * @param sub pointer to the AVSubtitle + * @param avctx pointer to the AVCodecContext + * @return >= 0 on success otherwise an error code <0 */ -void ff_ass_init(AVSubtitle *sub); +int ff_ass_subtitle_header_default(AVCodecContext *avctx); /** * Add an ASS dialog line to an AVSubtitle as a new AVSubtitleRect. diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c new file mode 100644 index 0000000000..2a3b76445e --- /dev/null +++ b/libavcodec/ass_split.c @@ -0,0 +1,468 @@ +/* + * SSA/ASS spliting functions + * Copyright (c) 2010 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 + */ + +#include "avcodec.h" +#include "ass_split.h" + +typedef enum { + ASS_STR, + ASS_INT, + ASS_FLT, + ASS_COLOR, + ASS_TIMESTAMP, + ASS_ALGN, +} ASSFieldType; + +typedef struct { + const char *name; + int type; + int offset; +} ASSFields; + +typedef struct { + const char *section; + const char *format_header; + const char *fields_header; + int size; + int offset; + int offset_count; + ASSFields fields[10]; +} ASSSection; + +static const ASSSection ass_sections[] = { + { .section = "Script Info", + .offset = offsetof(ASS, script_info), + .fields = {{"ScriptType", ASS_STR, offsetof(ASSScriptInfo, script_type)}, + {"Collisions", ASS_STR, offsetof(ASSScriptInfo, collisions) }, + {"PlayResX", ASS_INT, offsetof(ASSScriptInfo, play_res_x) }, + {"PlayResY", ASS_INT, offsetof(ASSScriptInfo, play_res_y) }, + {"Timer", ASS_FLT, offsetof(ASSScriptInfo, timer) }, + {0}, + } + }, + { .section = "V4+ Styles", + .format_header = "Format", + .fields_header = "Style", + .size = sizeof(ASSStyle), + .offset = offsetof(ASS, styles), + .offset_count = offsetof(ASS, styles_count), + .fields = {{"Name", ASS_STR, offsetof(ASSStyle, name) }, + {"Fontname", ASS_STR, offsetof(ASSStyle, font_name) }, + {"Fontsize", ASS_INT, offsetof(ASSStyle, font_size) }, + {"PrimaryColour",ASS_COLOR,offsetof(ASSStyle, primary_color)}, + {"BackColour", ASS_COLOR,offsetof(ASSStyle, back_color) }, + {"Bold", ASS_INT, offsetof(ASSStyle, bold) }, + {"Italic", ASS_INT, offsetof(ASSStyle, italic) }, + {"Underline", ASS_INT, offsetof(ASSStyle, underline) }, + {"Alignment", ASS_INT, offsetof(ASSStyle, alignment) }, + {0}, + } + }, + { .section = "V4 Styles", + .format_header = "Format", + .fields_header = "Style", + .size = sizeof(ASSStyle), + .offset = offsetof(ASS, styles), + .offset_count = offsetof(ASS, styles_count), + .fields = {{"Name", ASS_STR, offsetof(ASSStyle, name) }, + {"Fontname", ASS_STR, offsetof(ASSStyle, font_name) }, + {"Fontsize", ASS_INT, offsetof(ASSStyle, font_size) }, + {"PrimaryColour",ASS_COLOR,offsetof(ASSStyle, primary_color)}, + {"BackColour", ASS_COLOR,offsetof(ASSStyle, back_color) }, + {"Bold", ASS_INT, offsetof(ASSStyle, bold) }, + {"Italic", ASS_INT, offsetof(ASSStyle, italic) }, + {"Alignment", ASS_ALGN, offsetof(ASSStyle, alignment) }, + {0}, + } + }, + { .section = "Events", + .format_header = "Format", + .fields_header = "Dialogue", + .size = sizeof(ASSDialog), + .offset = offsetof(ASS, dialogs), + .offset_count = offsetof(ASS, dialogs_count), + .fields = {{"Layer", ASS_INT, offsetof(ASSDialog, layer) }, + {"Start", ASS_TIMESTAMP, offsetof(ASSDialog, start) }, + {"End", ASS_TIMESTAMP, offsetof(ASSDialog, end) }, + {"Style", ASS_STR, offsetof(ASSDialog, style) }, + {"Text", ASS_STR, offsetof(ASSDialog, text) }, + {0}, + } + }, +}; + + +typedef int (*ASSConvertFunc)(void *dest, const char *buf, int len); + +static int convert_str(void *dest, const char *buf, int len) +{ + char *str = av_malloc(len + 1); + if (str) { + memcpy(str, buf, len); + str[len] = 0; + if (*(void **)dest) + av_free(*(void **)dest); + *(char **)dest = str; + } + return !str; +} +static int convert_int(void *dest, const char *buf, int len) +{ + return sscanf(buf, "%d", (int *)dest) == 1; +} +static int convert_flt(void *dest, const char *buf, int len) +{ + return sscanf(buf, "%f", (float *)dest) == 1; +} +static int convert_color(void *dest, const char *buf, int len) +{ + return sscanf(buf, "&H%8x", (int *)dest) == 1 || + sscanf(buf, "%d", (int *)dest) == 1; +} +static int convert_timestamp(void *dest, const char *buf, int len) +{ + int c, h, m, s, cs; + if ((c = sscanf(buf, "%d:%02d:%02d.%02d", &h, &m, &s, &cs)) == 4) + *(int *)dest = 360000*h + 6000*m + 100*s + cs; + return c == 4; +} +static int convert_alignment(void *dest, const char *buf, int len) +{ + int a; + if (sscanf(buf, "%d", &a) == 1) { + /* convert V4 Style alignment to V4+ Style */ + *(int *)dest = a + ((a&4) >> 1) - 5*!!(a&8); + return 1; + } + return 0; +} + +static const ASSConvertFunc convert_func[] = { + [ASS_STR] = convert_str, + [ASS_INT] = convert_int, + [ASS_FLT] = convert_flt, + [ASS_COLOR] = convert_color, + [ASS_TIMESTAMP] = convert_timestamp, + [ASS_ALGN] = convert_alignment, +}; + + +struct ASSSplitContext { + ASS ass; + int current_section; + int field_number[FF_ARRAY_ELEMS(ass_sections)]; + int *field_order[FF_ARRAY_ELEMS(ass_sections)]; +}; + + +static uint8_t *realloc_section_array(ASSSplitContext *ctx) +{ + const ASSSection *section = &ass_sections[ctx->current_section]; + int *count = (int *)((uint8_t *)&ctx->ass + section->offset_count); + void **section_ptr = (void **)((uint8_t *)&ctx->ass + section->offset); + uint8_t *tmp = av_realloc(*section_ptr, (*count+1)*section->size); + if (!tmp) + return NULL; + *section_ptr = tmp; + tmp += *count * section->size; + memset(tmp, 0, section->size); + (*count)++; + return tmp; +} + +static inline int is_eol(char buf) +{ + return buf == '\r' || buf == '\n' || buf == 0; +} + +static inline const char *skip_space(const char *buf) +{ + while (*buf == ' ') + buf++; + return buf; +} + +static const char *ass_split_section(ASSSplitContext *ctx, const char *buf) +{ + const ASSSection *section = &ass_sections[ctx->current_section]; + int *number = &ctx->field_number[ctx->current_section]; + int *order = ctx->field_order[ctx->current_section]; + int *tmp, i, len; + + while (buf && *buf) { + if (buf[0] == '[') { + ctx->current_section = -1; + break; + } + if (buf[0] == ';' || (buf[0] == '!' && buf[1] == ':')) { + /* skip comments */ + } else if (section->format_header && !order) { + len = strlen(section->format_header); + if (strncmp(buf, section->format_header, len) || buf[len] != ':') + return NULL; + buf += len + 1; + while (!is_eol(*buf)) { + buf = skip_space(buf); + len = strcspn(buf, ", \r\n"); + if (!(tmp = av_realloc(order, (*number + 1) * sizeof(*order)))) + return NULL; + order = tmp; + order[*number] = -1; + for (i=0; section->fields[i].name; i++) + if (!strncmp(buf, section->fields[i].name, len)) { + order[*number] = i; + break; + } + (*number)++; + buf = skip_space(buf + len + 1); + } + ctx->field_order[ctx->current_section] = order; + } else if (section->fields_header) { + len = strlen(section->fields_header); + if (!strncmp(buf, section->fields_header, len) && buf[len] == ':') { + uint8_t *ptr, *struct_ptr = realloc_section_array(ctx); + if (!struct_ptr) return NULL; + buf += len + 1; + for (i=0; !is_eol(*buf) && i < *number; i++) { + int last = i == *number - 1; + buf = skip_space(buf); + len = strcspn(buf, last ? "\r\n" : ",\r\n"); + if (order[i] >= 0) { + ASSFieldType type = section->fields[order[i]].type; + ptr = struct_ptr + section->fields[order[i]].offset; + convert_func[type](ptr, buf, len); + } + buf = skip_space(buf + len + !last); + } + } + } else { + len = strcspn(buf, ":\r\n"); + if (buf[len] == ':') { + for (i=0; section->fields[i].name; i++) + if (!strncmp(buf, section->fields[i].name, len)) { + ASSFieldType type = section->fields[i].type; + uint8_t *ptr = (uint8_t *)&ctx->ass + section->offset; + ptr += section->fields[i].offset; + buf = skip_space(buf + len + 1); + convert_func[type](ptr, buf, strcspn(buf, "\r\n")); + break; + } + } + } + buf += strcspn(buf, "\n") + 1; + } + return buf; +} + +static int ass_split(ASSSplitContext *ctx, const char *buf) +{ + char c, section[16]; + int i; + + if (ctx->current_section >= 0) + buf = ass_split_section(ctx, buf); + + while (buf && *buf) { + if (sscanf(buf, "[%15[0-9A-Za-z+ ]]%c", section, &c) == 2) { + buf += strcspn(buf, "\n") + 1; + for (i=0; i<FF_ARRAY_ELEMS(ass_sections); i++) + if (!strcmp(section, ass_sections[i].section)) { + ctx->current_section = i; + buf = ass_split_section(ctx, buf); + } + } else + buf += strcspn(buf, "\n") + 1; + } + return buf ? 0 : AVERROR_INVALIDDATA; +} + +ASSSplitContext *ff_ass_split(const char *buf) +{ + ASSSplitContext *ctx = av_mallocz(sizeof(*ctx)); + ctx->current_section = -1; + if (ass_split(ctx, buf) < 0) { + ff_ass_split_free(ctx); + return NULL; + } + return ctx; +} + +static void free_section(ASSSplitContext *ctx, const ASSSection *section) +{ + uint8_t *ptr = (uint8_t *)&ctx->ass + section->offset; + int i, j, *count, c = 1; + + if (section->format_header) { + ptr = *(void **)ptr; + count = (int *)((uint8_t *)&ctx->ass + section->offset_count); + } else + count = &c; + + if (ptr) + for (i=0; i<*count; i++, ptr += section->size) + for (j=0; section->fields[j].name; j++) { + const ASSFields *field = §ion->fields[j]; + if (field->type == ASS_STR) + av_freep(ptr + field->offset); + } + *count = 0; + + if (section->format_header) + av_freep((uint8_t *)&ctx->ass + section->offset); +} + +ASSDialog *ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf, + int cache, int *number) +{ + ASSDialog *dialog = NULL; + int i, count; + if (!cache) + for (i=0; i<FF_ARRAY_ELEMS(ass_sections); i++) + if (!strcmp(ass_sections[i].section, "Events")) { + free_section(ctx, &ass_sections[i]); + break; + } + count = ctx->ass.dialogs_count; + if (ass_split(ctx, buf) == 0) + dialog = ctx->ass.dialogs + count; + if (number) + *number = ctx->ass.dialogs_count - count; + return dialog; +} + +void ff_ass_split_free(ASSSplitContext *ctx) +{ + if (ctx) { + int i; + for (i=0; i<FF_ARRAY_ELEMS(ass_sections); i++) + free_section(ctx, &ass_sections[i]); + av_free(ctx); + } +} + + +int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv, + const char *buf) +{ + const char *text = NULL; + char new_line[2]; + int text_len = 0; + + while (*buf) { + if (text && callbacks->text && + (sscanf(buf, "\\%1[nN]", new_line) == 1 || + !strncmp(buf, "{\\", 2))) { + callbacks->text(priv, text, text_len); + text = NULL; + } + if (sscanf(buf, "\\%1[nN]", new_line) == 1) { + if (callbacks->new_line) + callbacks->new_line(priv, new_line[0] == 'N'); + buf += 2; + } else if (!strncmp(buf, "{\\", 2)) { + buf++; + while (*buf == '\\') { + char style[2], c[2], sep[2], c_num[2] = "0", tmp[128] = {0}; + unsigned int color = 0xFFFFFFFF; + int len, size = -1, an = -1, alpha = -1; + int x1, y1, x2, y2, t1 = -1, t2 = -1; + if (sscanf(buf, "\\%1[bisu]%1[01\\}]%n", style, c, &len) > 1) { + int close = c[0] == '0' ? 1 : c[0] == '1' ? 0 : -1; + len += close != -1; + if (callbacks->style) + callbacks->style(priv, style[0], close); + } else if (sscanf(buf, "\\c%1[\\}]%n", sep, &len) > 0 || + sscanf(buf, "\\c&H%X&%1[\\}]%n", &color, sep, &len) > 1 || + sscanf(buf, "\\%1[1234]c%1[\\}]%n", c_num, sep, &len) > 1 || + sscanf(buf, "\\%1[1234]c&H%X&%1[\\}]%n", c_num, &color, sep, &len) > 2) { + if (callbacks->color) + callbacks->color(priv, color, c_num[0] - '0'); + } else if (sscanf(buf, "\\alpha%1[\\}]%n", sep, &len) > 0 || + sscanf(buf, "\\alpha&H%2X&%1[\\}]%n", &alpha, sep, &len) > 1 || + sscanf(buf, "\\%1[1234]a%1[\\}]%n", c_num, sep, &len) > 1 || + sscanf(buf, "\\%1[1234]a&H%2X&%1[\\}]%n", c_num, &alpha, sep, &len) > 2) { + if (callbacks->alpha) + callbacks->alpha(priv, alpha, c_num[0] - '0'); + } else if (sscanf(buf, "\\fn%1[\\}]%n", sep, &len) > 0 || + sscanf(buf, "\\fn%127[^\\}]%1[\\}]%n", tmp, sep, &len) > 1) { + if (callbacks->font_name) + callbacks->font_name(priv, tmp[0] ? tmp : NULL); + } else if (sscanf(buf, "\\fs%1[\\}]%n", sep, &len) > 0 || + sscanf(buf, "\\fs%u%1[\\}]%n", &size, sep, &len) > 1) { + if (callbacks->font_size) + callbacks->font_size(priv, size); + } else if (sscanf(buf, "\\a%1[\\}]%n", sep, &len) > 0 || + sscanf(buf, "\\a%2u%1[\\}]%n", &an, sep, &len) > 1 || + sscanf(buf, "\\an%1[\\}]%n", sep, &len) > 0 || + sscanf(buf, "\\an%1u%1[\\}]%n", &an, sep, &len) > 1) { + if (an != -1 && buf[2] != 'n') + an = (an&3) + (an&4 ? 6 : an&8 ? 3 : 0); + if (callbacks->alignment) + callbacks->alignment(priv, an); + } else if (sscanf(buf, "\\r%1[\\}]%n", sep, &len) > 0 || + sscanf(buf, "\\r%127[^\\}]%1[\\}]%n", tmp, sep, &len) > 1) { + if (callbacks->cancel_overrides) + callbacks->cancel_overrides(priv, tmp); + } else if (sscanf(buf, "\\move(%d,%d,%d,%d)%1[\\}]%n", &x1, &y1, &x2, &y2, sep, &len) > 4 || + sscanf(buf, "\\move(%d,%d,%d,%d,%d,%d)%1[\\}]%n", &x1, &y1, &x2, &y2, &t1, &t2, sep, &len) > 6) { + if (callbacks->move) + callbacks->move(priv, x1, y1, x2, y2, t1, t2); + } else if (sscanf(buf, "\\pos(%d,%d)%1[\\}]%n", &x1, &y1, sep, &len) > 2) { + if (callbacks->move) + callbacks->move(priv, x1, y1, x1, y1, -1, -1); + } else if (sscanf(buf, "\\org(%d,%d)%1[\\}]%n", &x1, &y1, sep, &len) > 2) { + if (callbacks->origin) + callbacks->origin(priv, x1, y1); + } else { + len = strcspn(buf+1, "\\}") + 2; /* skip unknown code */ + } + buf += len - 1; + } + if (*buf++ != '}') + return AVERROR_INVALIDDATA; + } else { + if (!text) { + text = buf; + text_len = 1; + } else + text_len++; + buf++; + } + } + if (text && callbacks->text) + callbacks->text(priv, text, text_len); + if (callbacks->end) + callbacks->end(priv); + return 0; +} + +ASSStyle *ass_style_get(ASSSplitContext *ctx, const char *style) +{ + ASS *ass = &ctx->ass; + int i; + + if (!style || !*style) + style = "Default"; + for (i=0; i<ass->styles_count; i++) + if (!strcmp(ass->styles[i].name, style)) + return ass->styles + i; + return NULL; +} diff --git a/libavcodec/ass_split.h b/libavcodec/ass_split.h new file mode 100644 index 0000000000..2ce4eb5d9c --- /dev/null +++ b/libavcodec/ass_split.h @@ -0,0 +1,172 @@ +/* + * SSA/ASS spliting functions + * Copyright (c) 2010 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 AVCODEC_ASS_SPLIT_H +#define AVCODEC_ASS_SPLIT_H + +/** + * fields extracted from the [Script Info] section + */ +typedef struct { + char *script_type; /**< SSA script format version (eg. v4.00) */ + char *collisions; /**< how subtitles are moved to prevent collisions */ + int play_res_x; /**< video width that ASS coords are referring to */ + int play_res_y; /**< video height that ASS coords are referring to */ + float timer; /**< time multiplier to apply to SSA clock (in %) */ +} ASSScriptInfo; + +/** + * fields extracted from the [V4(+) Styles] section + */ +typedef struct { + char *name; /**< name of the tyle (case sensitive) */ + char *font_name; /**< font face (case sensitive) */ + int font_size; /**< font height */ + int primary_color; /**< color that a subtitle will normally appear in */ + int back_color; /**< color of the subtitle outline or shadow */ + int bold; /**< whether text is bold (1) or not (0) */ + int italic; /**< whether text is italic (1) or not (0) */ + int underline; /**< whether text is underlined (1) or not (0) */ + int alignment; /**< position of the text (left, center, top...), + defined after the layout of the numpad + (1-3 sub, 4-6 mid, 7-9 top) */ +} ASSStyle; + +/** + * fields extracted from the [Events] section + */ +typedef struct { + int layer; /**< higher numbered layers are drawn over lower numbered */ + int start; /**< start time of the dialog in centiseconds */ + int end; /**< end time of the dialog in centiseconds */ + char *style; /**< name of the ASSStyle to use with this dialog */ + char *text; /**< actual text which will be displayed as a subtitle, + can include style override control codes (see + ff_ass_split_override_codes()) */ +} ASSDialog; + +/** + * structure containing the whole split ASS data + */ +typedef struct { + ASSScriptInfo script_info; /**< general information about the SSA script*/ + ASSStyle *styles; /**< array of split out styles */ + int styles_count; /**< number of ASSStyle in the styles array */ + ASSDialog *dialogs; /**< array of split out dialogs */ + int dialogs_count; /**< number of ASSDialog in the dialogs array*/ +} ASS; + +/** + * This struct can be casted to ASS to access to the split data. + */ +typedef struct ASSSplitContext ASSSplitContext; + +/** + * Split a full ASS file or a ASS header from a string buffer and store + * the split structure in a newly allocated context. + * + * @param buf String containing the ASS formated data. + * @return Newly allocated struct containing split data. + */ +ASSSplitContext *ff_ass_split(const char *buf); + +/** + * Split one or several ASS "Dialogue" lines from a string buffer and store + * them in a already initialized context. + * + * @param ctx Context previously initialized by ff_ass_split(). + * @param buf String containing the ASS "Dialogue" lines. + * @param cache Set to 1 to keep all the previously split ASSDialog in + * the context, or set to 0 to free all the previously split + * ASSDialog. + * @param number If not NULL, the pointed integer will be set to the number + * of split ASSDialog. + * @return Pointer to the first split ASSDialog. + */ +ASSDialog *ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf, + int cache, int *number); + +/** + * Free all the memory allocated for an ASSSplitContext. + * + * @param ctx Context previously initialized by ff_ass_split(). + */ +void ff_ass_split_free(ASSSplitContext *ctx); + + +/** + * Set of callback functions corresponding to each override codes that can + * be encountered in a "Dialogue" Text field. + */ +typedef struct { + /** + * @defgroup ass_styles ASS styles + * @{ + */ + void (*text)(void *priv, const char *text, int len); + void (*new_line)(void *priv, int forced); + void (*style)(void *priv, char style, int close); + void (*color)(void *priv, unsigned int color, unsigned int color_id); + void (*alpha)(void *priv, int alpha, int alpha_id); + void (*font_name)(void *priv, const char *name); + void (*font_size)(void *priv, int size); + void (*alignment)(void *priv, int alignment); + void (*cancel_overrides)(void *priv, const char *style); + /** @} */ + + /** + * @defgroup ass_functions ASS functions + * @{ + */ + void (*move)(void *priv, int x1, int y1, int x2, int y2, int t1, int t2); + void (*origin)(void *priv, int x, int y); + /** @} */ + + /** + * @defgroup ass_end end of Dialogue Event + * @{ + */ + void (*end)(void *priv); + /** @} */ +} ASSCodesCallbacks; + +/** + * Split override codes out of a ASS "Dialogue" Text field. + * + * @param callbacks Set of callback functions called for each override code + * encountered. + * @param priv Opaque pointer passed to the callback functions. + * @param buf The ASS "Dialogue" Text field to split. + * @return >= 0 on success otherwise an error code <0 + */ +int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv, + const char *buf); + +/** + * Find an ASSStyle structure by its name. + * + * @param ctx Context previously initialized by ff_ass_split(). + * @param style name of the style to search for. + * @return the ASSStyle corresponding to style, or NULL if style can't be found + */ +ASSStyle *ass_style_get(ASSSplitContext *ctx, const char *style); + +#endif /* AVCODEC_ASS_SPLIT_H */ diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c index 98f7be36a2..c5f9cab6e0 100644 --- a/libavcodec/assdec.c +++ b/libavcodec/assdec.c @@ -2,33 +2,35 @@ * SSA/ASS decoder * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 "ass.h" +#include "ass_split.h" static av_cold int ass_decode_init(AVCodecContext *avctx) { avctx->subtitle_header = av_malloc(avctx->extradata_size); - if (!avctx->extradata) + if (!avctx->subtitle_header) return AVERROR(ENOMEM); memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size); avctx->subtitle_header_size = avctx->extradata_size; + avctx->priv_data = ff_ass_split(avctx->extradata); return 0; } @@ -38,10 +40,10 @@ static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, const char *ptr = avpkt->data; int len, size = avpkt->size; - ff_ass_init(data); - while (size > 0) { - len = ff_ass_add_rect(data, ptr, 0, 0/* FIXME: duration */, 1); + ASSDialog *dialog = ff_ass_split_dialog(avctx->priv_data, ptr, 0, NULL); + int duration = dialog->end - dialog->start; + len = ff_ass_add_rect(data, ptr, 0, duration, 1); if (len < 0) return len; ptr += len; @@ -52,6 +54,13 @@ static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, return avpkt->size; } +static int ass_decode_close(AVCodecContext *avctx) +{ + ff_ass_split_free(avctx->priv_data); + avctx->priv_data = NULL; + return 0; +} + AVCodec ff_ass_decoder = { .name = "ass", .long_name = NULL_IF_CONFIG_SMALL("Advanced SubStation Alpha subtitle"), @@ -59,4 +68,5 @@ AVCodec ff_ass_decoder = { .id = CODEC_ID_SSA, .init = ass_decode_init, .decode = ass_decode_frame, + .close = ass_decode_close, }; diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c index b7836ff29f..103f2ff276 100644 --- a/libavcodec/assenc.c +++ b/libavcodec/assenc.c @@ -2,20 +2,20 @@ * SSA/ASS encoder * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/asv1.c b/libavcodec/asv1.c index 754c1aa89a..0845959d37 100644 --- a/libavcodec/asv1.c +++ b/libavcodec/asv1.c @@ -2,20 +2,20 @@ * ASUS V1/V2 codec * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/atrac.c b/libavcodec/atrac.c index da6cd305fb..1049df6281 100644 --- a/libavcodec/atrac.c +++ b/libavcodec/atrac.c @@ -3,20 +3,20 @@ * Copyright (c) 2006-2008 Maxim Poliakovski * Copyright (c) 2006-2008 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/atrac.h b/libavcodec/atrac.h index 2223a5e620..e126935e12 100644 --- a/libavcodec/atrac.h +++ b/libavcodec/atrac.h @@ -3,20 +3,20 @@ * Copyright (c) 2009 Maxim Poliakovski * Copyright (c) 2009 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/atrac1.c b/libavcodec/atrac1.c index 9ead80d5c8..c796235c80 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -3,20 +3,20 @@ * Copyright (c) 2009 Maxim Poliakovski * Copyright (c) 2009 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/atrac1data.h b/libavcodec/atrac1data.h index 7d5dbebc7f..ebebe4b105 100644 --- a/libavcodec/atrac1data.h +++ b/libavcodec/atrac1data.h @@ -3,20 +3,20 @@ * Copyright (c) 2009 Maxim Poliakovski * Copyright (c) 2009 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/atrac3.c b/libavcodec/atrac3.c index 6dec6a3abe..efaadc93fc 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -3,20 +3,20 @@ * Copyright (c) 2006-2008 Maxim Poliakovski * Copyright (c) 2006-2008 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -402,6 +402,8 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent for (k=0; k<coded_components; k++) { sfIndx = get_bits(gb,6); + if(component_count>=64) + return AVERROR_INVALIDDATA; pComponent[component_count].pos = j * 64 + (get_bits(gb,6)); max_coded_values = SAMPLES_PER_FRAME - pComponent[component_count].pos; coded_values = coded_values_per_component + 1; diff --git a/libavcodec/atrac3data.h b/libavcodec/atrac3data.h index 9076d3ae8d..b5aa71f8ca 100644 --- a/libavcodec/atrac3data.h +++ b/libavcodec/atrac3data.h @@ -3,20 +3,20 @@ * Copyright (c) 2006-2007 Maxim Poliakovski * Copyright (c) 2006-2007 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/audioconvert.c b/libavcodec/audioconvert.c index 0e1160d8e3..2cf36bd1ab 100644 --- a/libavcodec/audioconvert.c +++ b/libavcodec/audioconvert.c @@ -2,20 +2,20 @@ * audio conversion * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/audioconvert.h b/libavcodec/audioconvert.h index 590dc8d8d7..93b9ef1ed7 100644 --- a/libavcodec/audioconvert.h +++ b/libavcodec/audioconvert.h @@ -3,20 +3,20 @@ * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2008 Peter Ross * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/aura.c b/libavcodec/aura.c index 6052a65acf..49694d55bf 100644 --- a/libavcodec/aura.c +++ b/libavcodec/aura.c @@ -1,20 +1,20 @@ /* * Aura 2 decoder * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -39,6 +39,7 @@ static av_cold int aura_decode_init(AVCodecContext *avctx) if (avctx->width & 0x3) return -1; avctx->pix_fmt = PIX_FMT_YUV422P; + avcodec_get_frame_defaults(&s->frame); return 0; } diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 26e9c42f9d..b496d72948 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1,20 +1,20 @@ /* * copyright (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -34,6 +34,7 @@ #include "libavutil/log.h" #include "libavutil/pixfmt.h" #include "libavutil/rational.h" +#include "libavutil/audioconvert.h" #include "libavcodec/version.h" /** @@ -78,7 +79,8 @@ * * 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. + * 2. Give it a value which when taken as ASCII is recognized uniquely by a human as this specific codec. + * This ensures that 2 forks can independantly add CodecIDs without producing conflicts. */ enum CodecID { CODEC_ID_NONE, @@ -244,6 +246,15 @@ enum CodecID { CODEC_ID_DXTORY, CODEC_ID_V410, CODEC_ID_XWD, + CODEC_ID_Y41P = MKBETAG('Y','4','1','P'), + CODEC_ID_ESCAPE130 = MKBETAG('E','1','3','0'), + CODEC_ID_AVRP = MKBETAG('A','V','R','P'), + + CODEC_ID_G2M = MKBETAG( 0 ,'G','2','M'), + CODEC_ID_AYUV = MKBETAG('A','Y','U','V'), + CODEC_ID_V308 = MKBETAG('V','3','0','8'), + CODEC_ID_V408 = MKBETAG('V','4','0','8'), + CODEC_ID_YUV4 = MKBETAG('Y','U','V','4'), /* various PCM "codecs" */ CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs @@ -381,6 +392,10 @@ enum CodecID { CODEC_ID_8SVX_EXP, CODEC_ID_8SVX_FIB, CODEC_ID_BMV_AUDIO, + CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'), + CODEC_ID_8SVX_RAW = MKBETAG('8','S','V','X'), + CODEC_ID_SONIC = MKBETAG('S','O','N','C'), + CODEC_ID_SONIC_LS = MKBETAG('S','O','N','L'), /* subtitle codecs */ CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. @@ -393,10 +408,14 @@ enum CodecID { CODEC_ID_HDMV_PGS_SUBTITLE, CODEC_ID_DVB_TELETEXT, CODEC_ID_SRT, + CODEC_ID_MICRODVD = MKBETAG('m','D','V','D'), /* other specific kind of codecs (generally used for attachments) */ CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. CODEC_ID_TTF = 0x18000, + CODEC_ID_BINTEXT = MKBETAG('B','T','X','T'), + CODEC_ID_XBIN = MKBETAG('X','B','I','N'), + CODEC_ID_IDF = MKBETAG( 0 ,'I','D','F'), CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it @@ -419,7 +438,7 @@ enum CodecID { * 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 +#define FF_INPUT_BUFFER_PADDING_SIZE 16 /** * minimum encoding buffer size @@ -471,6 +490,7 @@ enum AVColorTransferCharacteristic{ AVCOL_TRC_UNSPECIFIED=2, AVCOL_TRC_GAMMA22 =4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM AVCOL_TRC_GAMMA28 =5, ///< also ITU-R BT470BG + AVCOL_TRC_SMPTE240M =7, AVCOL_TRC_NB , ///< Not part of ABI }; @@ -482,6 +502,7 @@ enum AVColorSpace{ AVCOL_SPC_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 AVCOL_SPC_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above AVCOL_SPC_SMPTE240M =7, + AVCOL_SPC_YCGCO =8, AVCOL_SPC_NB , ///< Not part of ABI }; @@ -569,8 +590,10 @@ typedef struct RcOverride{ #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_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. DEPRECATED!!!! #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_SHOW_ALL 0x00400000 ///< Show all frames before the first keyframe /* Unsupported options : * Syntax Arithmetic coding (SAC) @@ -643,10 +666,12 @@ typedef struct RcOverride{ * Codec should fill in channel configuration and samplerate instead of container */ #define CODEC_CAP_CHANNEL_CONF 0x0400 + /** * Codec is able to deal with negative linesizes */ #define CODEC_CAP_NEG_LINESIZES 0x0800 + /** * Codec supports frame-level multithreading. */ @@ -667,6 +692,10 @@ typedef struct RcOverride{ * Audio encoder supports receiving a different number of samples in each call. */ #define CODEC_CAP_VARIABLE_FRAME_SIZE 0x10000 +/** + * Codec is lossless. + */ +#define CODEC_CAP_LOSSLESS 0x80000000 //The following defines may change, don't expect compatibility if you use them. #define MB_TYPE_INTRA4x4 0x0001 @@ -832,9 +861,12 @@ enum AVSideDataParamChangeFlags { /** * Audio Video Frame. * New fields can be added to the end of AVFRAME with minor version - * bumps. Removal, reordering and changes to existing fields require + * bumps. Similarly fields that are marked as to be only accessed by + * av_opt_ptr() can be reordered. This allows 2 forks to add fields + * without breaking compatibility with each other. + * Removal, reordering and changes in the remaining cases require * a major version bump. - * sizeof(AVFrame) must not be used outside libav*. + * sizeof(AVFrame) must not be used outside libavcodec. */ typedef struct AVFrame { #define AV_NUM_DATA_POINTERS 8 @@ -1066,7 +1098,7 @@ typedef struct AVFrame { int64_t reordered_opaque; /** - * hardware accelerator private data (Libav-allocated) + * hardware accelerator private data (FFmpeg-allocated) * - encoding: unused * - decoding: Set by libavcodec */ @@ -1149,6 +1181,25 @@ typedef struct AVFrame { * - decoding: Read by user. */ int format; + + /** + * frame timestamp estimated using various heuristics, in stream time base + * Code outside libavcodec should access this field using: + * av_opt_ptr(avcodec_get_frame_class(), frame, "best_effort_timestamp"); + * - encoding: unused + * - decoding: set by libavcodec, read by user. + */ + int64_t best_effort_timestamp; + + /** + * reordered pos from the last AVPacket that has been input into the decoder + * Code outside libavcodec should access this field using: + * av_opt_ptr(avcodec_get_frame_class(), frame, "pkt_pos"); + * - encoding: unused + * - decoding: Read by user. + */ + int64_t pkt_pos; + } AVFrame; struct AVCodecInternal; @@ -1167,6 +1218,8 @@ enum AVFieldOrder { * New fields can be added to the end with minor version bumps. * Removal, reordering and changes to existing fields require a major * version bump. + * Please use AVOptions (av_opt* / av_set/get*()) to access these fields from user + * applications. * sizeof(AVCodecContext) must not be used outside libav*. */ typedef struct AVCodecContext { @@ -1314,10 +1367,12 @@ typedef struct AVCodecContext { int frame_number; ///< audio or video frame number /** - * Number of frames the decoded output will be delayed relative to - * the encoded input. + * Encoding: Number of frames delay there will be from the encoder input to + * the decoder output. (we assume the decoder matches the spec) + * Decoding: Number of frames delay in addition to what a standard decoder + * as specified in the spec would produce. * - encoding: Set by libavcodec. - * - decoding: unused + * - decoding: Set by libavcodec. */ int delay; @@ -2480,9 +2535,9 @@ typedef struct AVCodecContext { int max_prediction_order; /** - * GOP timecode frame start number, in non drop frame format - * - encoding: Set by user. - * - decoding: unused + * GOP timecode frame start number + * - encoding: Set by user, in non drop frame format + * - decoding: Set by libavcodec (timecode in the 25 bits format, -1 if unset) */ int64_t timecode_frame_start; @@ -2515,7 +2570,7 @@ typedef struct AVCodecContext { /** * Audio channel layout. * - encoding: set by user. - * - decoding: set by libavcodec. + * - decoding: set by user, may be overwritten by libavcodec. */ uint64_t channel_layout; @@ -2560,8 +2615,8 @@ typedef struct AVCodecContext { * Hardware accelerator context. * For some hardware accelerators, a global context needs to be * provided by the user. In that case, this holds display-dependent - * data Libav cannot instantiate itself. Please refer to the - * Libav HW accelerator documentation to know how to fill this + * data FFmpeg cannot instantiate itself. Please refer to the + * FFmpeg HW accelerator documentation to know how to fill this * is. e.g. for VA API, this is a struct vaapi_context. * - encoding: unused * - decoding: Set by user @@ -2699,9 +2754,10 @@ typedef struct AVCodecContext { enum AVAudioServiceType audio_service_type; /** - * Used to request a sample format from the decoder. - * - encoding: unused. + * desired sample format + * - encoding: Not used. * - decoding: Set by user. + * Decoder will decode to this format if it can. */ enum AVSampleFormat request_sample_fmt; @@ -2716,6 +2772,10 @@ typedef struct AVCodecContext { #define AV_EF_BUFFER (1<<2) #define AV_EF_EXPLODE (1<<3) +#define AV_EF_CAREFUL (1<<16) +#define AV_EF_COMPLIANT (1<<17) +#define AV_EF_AGGRESSIVE (1<<18) + /** * Private context used for internal data. * @@ -2729,6 +2789,17 @@ typedef struct AVCodecContext { * - decoding: Set by libavcodec */ enum AVFieldOrder field_order; + + /** + * Current statistics for PTS correction. + * - decoding: maintained and used by libavcodec, not intended to be used by user apps + * - encoding: unused + */ + int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far + int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far + int64_t pts_correction_last_pts; /// PTS of the last frame + int64_t pts_correction_last_dts; /// DTS of the last frame + } AVCodecContext; /** @@ -3068,6 +3139,11 @@ uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int *size); +int av_packet_merge_side_data(AVPacket *pkt); + +int av_packet_split_side_data(AVPacket *pkt); + + /* resample.c */ struct ReSampleContext; @@ -3225,6 +3301,12 @@ int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height); void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift); +/** + * Get the name of a codec. + * @return a static string identifying the codec; never NULL + */ +const char *avcodec_get_name(enum CodecID id); + void avcodec_set_dimensions(AVCodecContext *s, int width, int height); /** @@ -3265,7 +3347,8 @@ size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_ta * @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. + * @return Combination of flags informing you what kind of losses will occur + * (maximum loss for an invalid dst_pix_fmt). */ int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt, int has_alpha); @@ -3280,9 +3363,11 @@ int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_ * The pixel formats from which it chooses one, are determined by the * pix_fmt_mask parameter. * + * Note, only the first 64 pixel formats will fit in pix_fmt_mask. + * * @code * src_pix_fmt = PIX_FMT_YUV420P; - * pix_fmt_mask = (1 << PIX_FMT_YUV422P) || (1 << PIX_FMT_RGB24); + * pix_fmt_mask = (1 << PIX_FMT_YUV422P) | (1 << PIX_FMT_RGB24); * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss); * @endcode * @@ -3295,6 +3380,40 @@ int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_ enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); +/** + * Find the best pixel format to convert to given a certain source pixel + * format and a selection of two destination pixel formats. When converting from + * one pixel format to another, information loss 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_fmt2() selects which of + * the given pixel formats should be used to suffer the least amount of loss. + * + * If one of the destination formats is PIX_FMT_NONE the other pixel format (if valid) will be + * returned. + * + * @code + * src_pix_fmt = PIX_FMT_YUV420P; + * dst_pix_fmt1= PIX_FMT_RGB24; + * dst_pix_fmt2= PIX_FMT_GRAY8; + * dst_pix_fmt3= PIX_FMT_RGB8; + * loss= FF_LOSS_CHROMA; // don't care about chroma loss, so chroma loss will be ignored. + * dst_pix_fmt = avcodec_find_best_pix_fmt2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, alpha, &loss); + * dst_pix_fmt = avcodec_find_best_pix_fmt2(dst_pix_fmt, dst_pix_fmt3, src_pix_fmt, alpha, &loss); + * @endcode + * + * @param[in] dst_pix_fmt1 One of the two destination pixel formats to choose from + * @param[in] dst_pix_fmt2 The other of the two destination pixel formats 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[in, out] loss_ptr Combination of loss flags. In: selects which of the losses to ignore, i.e. + * NULL or value of zero means we care about all losses. Out: the loss + * that occurs when converting from src to selected dst pixel format. + * @return The best pixel format to convert to or -1 if none was found. + */ +enum PixelFormat avcodec_find_best_pix_fmt2(enum PixelFormat dst_pix_fmt1, enum PixelFormat dst_pix_fmt2, + enum PixelFormat src_pix_fmt, int has_alpha, int *loss_ptr); + + /* deinterlace a picture */ /* deinterlace - if not supported return -1 */ int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, @@ -3376,6 +3495,22 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); */ const char *av_get_profile_name(const AVCodec *codec, int profile); +#if FF_API_ALLOC_CONTEXT +/** + * Set the fields of the given AVCodecContext to default values. + * + * @param s The AVCodecContext of which the fields should be set to default values. + * @deprecated use avcodec_get_context_defaults3 + */ +attribute_deprecated +void avcodec_get_context_defaults(AVCodecContext *s); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +attribute_deprecated +void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType); +#endif + /** * Set the fields of the given AVCodecContext to default values corresponding * to the given codec (defaults may be codec-dependent). @@ -3387,6 +3522,25 @@ const char *av_get_profile_name(const AVCodec *codec, int profile); */ int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec); +#if FF_API_ALLOC_CONTEXT +/** + * Allocate an AVCodecContext and set its fields to default values. The + * resulting struct can be deallocated by simply calling av_free(). + * + * @return An AVCodecContext filled with default values or NULL on failure. + * @see avcodec_get_context_defaults + * + * @deprecated use avcodec_alloc_context3() + */ +attribute_deprecated +AVCodecContext *avcodec_alloc_context(void); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +attribute_deprecated +AVCodecContext *avcodec_alloc_context2(enum AVMediaType); +#endif + /** * Allocate an AVCodecContext and set its fields to default values. The * resulting struct can be deallocated by calling avcodec_close() on it followed @@ -3473,6 +3627,40 @@ int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, v int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); //FIXME func typedef +#if FF_API_AVCODEC_OPEN +/** + * Initialize the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated. + * + * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), + * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for + * retrieving a codec. + * + * @warning This function is not thread safe! + * + * @code + * avcodec_register_all(); + * codec = avcodec_find_decoder(CODEC_ID_H264); + * if (!codec) + * exit(1); + * + * context = avcodec_alloc_context3(codec); + * + * if (avcodec_open(context, codec) < 0) + * exit(1); + * @endcode + * + * @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 + * @see avcodec_alloc_context3, avcodec_find_decoder, avcodec_find_encoder, avcodec_close + * + * @deprecated use avcodec_open2 + */ +attribute_deprecated +int avcodec_open(AVCodecContext *avctx, AVCodec *codec); +#endif + /** * Initialize the AVCodecContext to use the given AVCodec. Prior to using this * function the context has to be allocated with avcodec_alloc_context3(). @@ -3650,7 +3838,7 @@ int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, */ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, - AVPacket *avpkt); + const AVPacket *avpkt); /** * Decode a subtitle message. @@ -4108,11 +4296,11 @@ void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size); /** - * Allocate a buffer with padding, reusing the given one if large enough. - * * Same behaviour av_fast_malloc but the buffer has additional - * FF_INPUT_PADDING_SIZE at the end which will always memset to 0. + * FF_INPUT_PADDING_SIZE at the end which will will always be 0. * + * In addition the whole buffer will initially and after resizes + * be 0-initialized so that no uninitialized data will ever appear. */ void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size); @@ -4145,7 +4333,7 @@ unsigned int av_xiphlacing(unsigned char *s, unsigned int v); /** * Log a generic warning message about a missing feature. This function is - * intended to be used internally by Libav (libavcodec, libavformat, etc.) + * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) * only, and would normally not be used by applications. * @param[in] avc a pointer to an arbitrary struct of which the first field is * a pointer to an AVClass struct @@ -4159,7 +4347,7 @@ void av_log_missing_feature(void *avc, const char *feature, int want_sample); /** * Log a generic warning message asking for a sample. This function is - * intended to be used internally by Libav (libavcodec, libavformat, etc.) + * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) * only, and would normally not be used by applications. * @param[in] avc a pointer to an arbitrary struct of which the first field is * a pointer to an AVClass struct @@ -4196,7 +4384,7 @@ enum AVLockOp { * lockmgr should store/get a pointer to a user allocated mutex. It's * NULL upon AV_LOCK_CREATE and != NULL for all other ops. * - * @param cb User defined callback. Note: Libav may invoke calls to this + * @param cb User defined callback. Note: FFmpeg may invoke calls to this * callback during the call to av_lockmgr_register(). * Thus, the application must be prepared to handle that. * If cb is set to NULL the lockmgr will be unregistered. @@ -4219,6 +4407,14 @@ enum AVMediaType avcodec_get_type(enum CodecID codec_id); const AVClass *avcodec_get_class(void); /** + * Get the AVClass for AVFrame. It can be used in combination with + * AV_OPT_SEARCH_FAKE_OBJ for examining options. + * + * @see av_opt_find(). + */ +const AVClass *avcodec_get_frame_class(void); + +/** * @return a positive value if s is open (i.e. avcodec_open2() was called on it * with no corresponding avcodec_close()), 0 otherwise. */ diff --git a/libavcodec/avfft.c b/libavcodec/avfft.c index 9ed06fbeb5..9e0ddaa627 100644 --- a/libavcodec/avfft.c +++ b/libavcodec/avfft.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/avfft.h b/libavcodec/avfft.h index 91fe2f4297..be2d9c7e10 100644 --- a/libavcodec/avfft.h +++ b/libavcodec/avfft.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/avpacket.c b/libavcodec/avpacket.c index e0e4df46f2..5a51900ebf 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -2,26 +2,27 @@ * AVPacket functions for libavcodec * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 "internal.h" #include "libavutil/avassert.h" - +#include "bytestream.h" void av_destruct_packet_nofree(AVPacket *pkt) { @@ -30,19 +31,23 @@ void av_destruct_packet_nofree(AVPacket *pkt) pkt->side_data_elems = 0; } -void av_destruct_packet(AVPacket *pkt) +void ff_packet_free_side_data(AVPacket *pkt) { int i; - - av_free(pkt->data); - pkt->data = NULL; pkt->size = 0; - for (i = 0; i < pkt->side_data_elems; i++) av_free(pkt->side_data[i].data); av_freep(&pkt->side_data); pkt->side_data_elems = 0; } +void av_destruct_packet(AVPacket *pkt) +{ + av_free(pkt->data); + pkt->data = NULL; pkt->size = 0; + + ff_packet_free_side_data(pkt); +} + void av_init_packet(AVPacket *pkt) { pkt->pts = AV_NOPTS_VALUE; @@ -196,3 +201,81 @@ uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, } return NULL; } + +#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL + +int av_packet_merge_side_data(AVPacket *pkt){ + if(pkt->side_data_elems){ + int i; + uint8_t *p; + uint64_t size= pkt->size + 8LL + FF_INPUT_BUFFER_PADDING_SIZE; + AVPacket old= *pkt; + for (i=0; i<old.side_data_elems; i++) { + size += old.side_data[i].size + 5LL; + } + if (size > INT_MAX) + return AVERROR(EINVAL); + p = av_malloc(size); + if (!p) + return AVERROR(ENOMEM); + pkt->data = p; + pkt->destruct = av_destruct_packet; + pkt->size = size - FF_INPUT_BUFFER_PADDING_SIZE; + bytestream_put_buffer(&p, old.data, old.size); + for (i=old.side_data_elems-1; i>=0; i--) { + bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size); + bytestream_put_be32(&p, old.side_data[i].size); + *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128); + } + bytestream_put_be64(&p, FF_MERGE_MARKER); + av_assert0(p-pkt->data == pkt->size); + memset(p, 0, FF_INPUT_BUFFER_PADDING_SIZE); + av_free_packet(&old); + pkt->side_data_elems = 0; + pkt->side_data = NULL; + return 1; + } + return 0; +} + +int av_packet_split_side_data(AVPacket *pkt){ + if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){ + int i; + unsigned int size; + uint8_t *p; + + p = pkt->data + pkt->size - 8 - 5; + for (i=1; ; i++){ + size = AV_RB32(p); + if (size>INT_MAX || p - pkt->data <= size) + return 0; + if (p[4]&128) + break; + p-= size+5; + } + + pkt->side_data = av_malloc(i * sizeof(*pkt->side_data)); + if (!pkt->side_data) + return AVERROR(ENOMEM); + + p= pkt->data + pkt->size - 8 - 5; + for (i=0; ; i++){ + size= AV_RB32(p); + av_assert0(size<=INT_MAX && p - pkt->data > size); + pkt->side_data[i].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + pkt->side_data[i].size = size; + pkt->side_data[i].type = p[4]&127; + if (!pkt->side_data[i].data) + return AVERROR(ENOMEM); + memcpy(pkt->side_data[i].data, p-size, size); + pkt->size -= size + 5; + if(p[4]&128) + break; + p-= size+5; + } + pkt->size -= 8; + pkt->side_data_elems = i+1; + return 1; + } + return 0; +} diff --git a/libavcodec/avr32/mathops.h b/libavcodec/avr32/mathops.h index 528b7adb33..85f42b594d 100644 --- a/libavcodec/avr32/mathops.h +++ b/libavcodec/avr32/mathops.h @@ -2,20 +2,20 @@ * Simple math operations * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/avs.c b/libavcodec/avs.c index b3cd5b1478..05cb815fd8 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -2,20 +2,20 @@ * AVS video decoder. * Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -63,7 +63,7 @@ avs_decode_frame(AVCodecContext * avctx, av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } - p->reference = 1; + p->reference = 3; p->pict_type = AV_PICTURE_TYPE_P; p->key_frame = 0; @@ -85,8 +85,10 @@ avs_decode_frame(AVCodecContext * avctx, if (first >= 256 || last > 256 || buf_end - buf < 4 + 4 + 3 * (last - first)) return AVERROR_INVALIDDATA; buf += 4; - for (i=first; i<last; i++, buf+=3) + for (i=first; i<last; i++, buf+=3) { pal[i] = (buf[0] << 18) | (buf[1] << 10) | (buf[2] << 2); + pal[i] |= 0xFF << 24 | (pal[i] >> 6) & 0x30303; + } sub_type = buf[0]; type = buf[1]; @@ -157,7 +159,9 @@ avs_decode_frame(AVCodecContext * avctx, static av_cold int avs_decode_init(AVCodecContext * avctx) { + AvsContext *const avs = avctx->priv_data; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&avs->picture); return 0; } diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c index 743e387cbe..d85783b109 100644 --- a/libavcodec/bethsoftvideo.c +++ b/libavcodec/bethsoftvideo.c @@ -2,20 +2,20 @@ * Bethesda VID video decoder * Copyright (C) 2007 Nicholas Tung * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +40,8 @@ typedef struct BethsoftvidContext { static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx) { BethsoftvidContext *vid = avctx->priv_data; - vid->frame.reference = 1; + avcodec_get_frame_defaults(&vid->frame); + vid->frame.reference = 3; vid->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; avctx->pix_fmt = PIX_FMT_PAL8; @@ -56,7 +57,8 @@ static int set_palette(BethsoftvidContext *ctx) return AVERROR_INVALIDDATA; for(a = 0; a < 256; a++){ - palette[a] = bytestream2_get_be24u(&ctx->g) * 4; + palette[a] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->g) * 4; + palette[a] |= palette[a] >> 6 & 0x30303; } ctx->frame.palette_has_changed = 1; return 0; diff --git a/libavcodec/bethsoftvideo.h b/libavcodec/bethsoftvideo.h index 5cbbdfdff0..d5b5d0a525 100644 --- a/libavcodec/bethsoftvideo.h +++ b/libavcodec/bethsoftvideo.h @@ -2,20 +2,20 @@ * Bethesda VID video decoder * Copyright (C) 2007 Nicholas Tung * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bfi.c b/libavcodec/bfi.c index 542ba5421c..0a7324a297 100644 --- a/libavcodec/bfi.c +++ b/libavcodec/bfi.c @@ -2,20 +2,20 @@ * Brute Force & Ignorance (BFI) video decoder * Copyright (c) 2008 Sisir Koppaka * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -34,12 +34,14 @@ typedef struct BFIContext { AVCodecContext *avctx; AVFrame frame; uint8_t *dst; + uint32_t pal[256]; } BFIContext; static av_cold int bfi_decode_init(AVCodecContext *avctx) { BFIContext *bfi = avctx->priv_data; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&bfi->frame); bfi->dst = av_mallocz(avctx->width * avctx->height); return 0; } @@ -59,7 +61,7 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data, if (bfi->frame.data[0]) avctx->release_buffer(avctx, &bfi->frame); - bfi->frame.reference = 1; + bfi->frame.reference = 3; if (avctx->get_buffer(avctx, &bfi->frame) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -80,17 +82,20 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data, pal = (uint32_t *)bfi->frame.data[1]; for (i = 0; i < avctx->extradata_size / 3; i++) { int shift = 16; - *pal = 0; + *pal = 0xFF << 24; for (j = 0; j < 3; j++, shift -= 8) *pal += ((avctx->extradata[i * 3 + j] << 2) | (avctx->extradata[i * 3 + j] >> 4)) << shift; pal++; } + memcpy(bfi->pal, bfi->frame.data[1], sizeof(bfi->pal)); bfi->frame.palette_has_changed = 1; } else { bfi->frame.pict_type = AV_PICTURE_TYPE_P; bfi->frame.key_frame = 0; + bfi->frame.palette_has_changed = 0; + memcpy(bfi->frame.data[1], bfi->pal, sizeof(bfi->pal)); } bytestream2_skip(&g, 4); // Unpacked size, not required. diff --git a/libavcodec/bfin/config_bfin.h b/libavcodec/bfin/config_bfin.h index 0fee494cc7..f3a2c6ebc6 100644 --- a/libavcodec/bfin/config_bfin.h +++ b/libavcodec/bfin/config_bfin.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bfin/dsputil_bfin.c b/libavcodec/bfin/dsputil_bfin.c index af76a0fc2c..2132d08cdb 100644 --- a/libavcodec/bfin/dsputil_bfin.c +++ b/libavcodec/bfin/dsputil_bfin.c @@ -4,20 +4,20 @@ * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> * Copyright (c) 2006 Michael Benjamin <michael.benjamin@analog.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bfin/dsputil_bfin.h b/libavcodec/bfin/dsputil_bfin.h index f1a9b32d64..7edcf97b6b 100644 --- a/libavcodec/bfin/dsputil_bfin.h +++ b/libavcodec/bfin/dsputil_bfin.h @@ -3,20 +3,20 @@ * * Copyright (C) 2007 Marc Hoffman <mmh@pleasantst.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bfin/fdct_bfin.S b/libavcodec/bfin/fdct_bfin.S index 8ca490d040..e15acb654f 100644 --- a/libavcodec/bfin/fdct_bfin.S +++ b/libavcodec/bfin/fdct_bfin.S @@ -3,20 +3,20 @@ * * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* @@ -104,14 +104,14 @@ short dct_coef[] S3,C3, ----------------------------------------------------------- -Libav conformance testing results +FFMPEG conformance testing results ----------------------------------------------------------- dct-test: modified with the following dct_error("BFINfdct", 0, ff_bfin_fdct, fdct, test); produces the following output: -libavcodec> ./dct-test -Libav DCT/IDCT test +root:/u/ffmpeg/bhead/libavcodec> ./dct-test +ffmpeg DCT/IDCT test 2 -131 -6 -48 -36 33 -83 24 34 52 -24 -15 5 92 57 143 @@ -123,6 +123,8 @@ Libav DCT/IDCT test -17 -63 -15 73 50 -91 159 -14 DCT BFINfdct: err_inf=2 err2=0.16425938 syserr=0.00795000 maxout=2098 blockSumErr=27 DCT BFINfdct: 92.1 kdct/s +root:/u/ffmpeg/bhead/libavcodec> + */ #include "config.h" diff --git a/libavcodec/bfin/idct_bfin.S b/libavcodec/bfin/idct_bfin.S index b384840fba..66430096f0 100644 --- a/libavcodec/bfin/idct_bfin.S +++ b/libavcodec/bfin/idct_bfin.S @@ -3,20 +3,20 @@ * * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* @@ -32,15 +32,15 @@ Performance : ----------------------------------------------------------- -Libav conformance testing results +FFMPEG conformance testing results ----------------------------------------------------------- dct-test: modified with the following dct_error("BFINidct", 1, ff_bfin_idct, idct, test); produces the following output -libavcodec> ./dct-test -i -Libav DCT/IDCT test +root:/u/ffmpeg/bhead/libavcodec> ./dct-test -i +ffmpeg DCT/IDCT test 8 15 -2 21 24 17 0 10 2 -10 -5 -5 -3 7 -14 -3 diff --git a/libavcodec/bfin/mathops.h b/libavcodec/bfin/mathops.h index bbee49380e..50c03160ed 100644 --- a/libavcodec/bfin/mathops.h +++ b/libavcodec/bfin/mathops.h @@ -3,20 +3,20 @@ * * Copyright (C) 2007 Marc Hoffman <mmhoffm@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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_BFIN_MATHOPS_H diff --git a/libavcodec/bfin/mpegvideo_bfin.c b/libavcodec/bfin/mpegvideo_bfin.c index 4697a5d893..2f819271f6 100644 --- a/libavcodec/bfin/mpegvideo_bfin.c +++ b/libavcodec/bfin/mpegvideo_bfin.c @@ -3,20 +3,20 @@ * * Copyright (C) 2007 Marc Hoffman <mmh@pleasantst.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -61,8 +61,13 @@ static int dct_quantize_bfin (MpegEncContext *s, 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]; + if(n<4){ + bias = s->q_intra_matrix16[qscale][1]; + qmat = s->q_intra_matrix16[qscale][0]; + }else{ + bias = s->q_chroma_intra_matrix16[qscale][1]; + qmat = s->q_chroma_intra_matrix16[qscale][0]; + } } else { start_i = 0; diff --git a/libavcodec/bfin/pixels_bfin.S b/libavcodec/bfin/pixels_bfin.S index 45a3ab626c..1fc93f9a47 100644 --- a/libavcodec/bfin/pixels_bfin.S +++ b/libavcodec/bfin/pixels_bfin.S @@ -2,20 +2,20 @@ * Blackfin Pixel Operations * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config_bfin.h" diff --git a/libavcodec/bfin/vp3_bfin.c b/libavcodec/bfin/vp3_bfin.c index bec25a0c35..6d6ac82636 100644 --- a/libavcodec/bfin/vp3_bfin.c +++ b/libavcodec/bfin/vp3_bfin.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bfin/vp3_idct_bfin.S b/libavcodec/bfin/vp3_idct_bfin.S index 2e18f91090..83747f9fcd 100644 --- a/libavcodec/bfin/vp3_idct_bfin.S +++ b/libavcodec/bfin/vp3_idct_bfin.S @@ -3,20 +3,20 @@ * * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bgmc.c b/libavcodec/bgmc.c index b17c3b1f72..772a0af254 100644 --- a/libavcodec/bgmc.c +++ b/libavcodec/bgmc.c @@ -2,20 +2,20 @@ * Block Gilbert-Moore decoder * Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ googlemail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bgmc.h b/libavcodec/bgmc.h index 3d5b49034d..9e386fdbdd 100644 --- a/libavcodec/bgmc.h +++ b/libavcodec/bgmc.h @@ -2,20 +2,20 @@ * Block Gilbert-Moore decoder * Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ googlemail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bink.c b/libavcodec/bink.c index f38c030b7c..ff8bc8ad07 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -3,20 +3,20 @@ * Copyright (c) 2009 Konstantin Shishkov * Copyright (C) 2011 Peter Ross <pross@xvid.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -857,7 +857,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC); qp = binkb_get_value(c, BINKB_SRC_INTRA_Q); - read_dct_coeffs(gb, dctblock, bink_scan, binkb_intra_quant, qp); + read_dct_coeffs(gb, dctblock, bink_scan, (const int32_t (*)[64])binkb_intra_quant, qp); c->bdsp.idct_put(dst, stride, dctblock); break; case 3: @@ -890,7 +890,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = binkb_get_value(c, BINKB_SRC_INTER_DC); qp = binkb_get_value(c, BINKB_SRC_INTER_Q); - read_dct_coeffs(gb, dctblock, bink_scan, binkb_inter_quant, qp); + read_dct_coeffs(gb, dctblock, bink_scan, (const int32_t (*)[64])binkb_inter_quant, qp); c->bdsp.idct_add(dst, stride, dctblock); break; case 5: diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index d73ffcdabc..9f51c7a856 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -3,20 +3,20 @@ * Copyright (c) 2007-2011 Peter Ross (pross@xvid.org) * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/binkdata.h b/libavcodec/binkdata.h index 60f0a59b49..b9dc1f2639 100644 --- a/libavcodec/binkdata.h +++ b/libavcodec/binkdata.h @@ -2,20 +2,20 @@ * Bink video decoder * Copyright (C) 2009 Kostya Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/binkdsp.c b/libavcodec/binkdsp.c index 1f7855b30b..c751743aa8 100644 --- a/libavcodec/binkdsp.c +++ b/libavcodec/binkdsp.c @@ -2,20 +2,20 @@ * Bink DSP routines * Copyright (c) 2009 Kostya Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bintext.c b/libavcodec/bintext.c new file mode 100644 index 0000000000..91167ba150 --- /dev/null +++ b/libavcodec/bintext.c @@ -0,0 +1,247 @@ +/* + * Binary text decoder + * eXtended BINary text (XBIN) decoder + * iCEDraw File decoder + * Copyright (c) 2010 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 + */ + +/** + * @file + * Binary text decoder + * eXtended BINary text (XBIN) decoder + * iCEDraw File decoder + */ + +#include "libavutil/intreadwrite.h" +#include "avcodec.h" +#include "cga_data.h" +#include "bintext.h" + +typedef struct XbinContext { + AVFrame frame; + int palette[16]; + int flags; + int font_height; + const uint8_t *font; + int x, y; +} XbinContext; + +static av_cold int decode_init(AVCodecContext *avctx) +{ + XbinContext *s = avctx->priv_data; + uint8_t *p; + int i; + + avctx->pix_fmt = PIX_FMT_PAL8; + p = avctx->extradata; + if (p) { + s->font_height = p[0]; + s->flags = p[1]; + p += 2; + } else { + s->font_height = 8; + s->flags = 0; + } + + if ((s->flags & BINTEXT_PALETTE)) { + for (i = 0; i < 16; i++) { + s->palette[i] = 0xFF000000 | (AV_RB24(p) << 2) | ((AV_RB24(p) >> 4) & 0x30303); + p += 3; + } + } else { + for (i = 0; i < 16; i++) + s->palette[i] = 0xFF000000 | ff_cga_palette[i]; + } + + if ((s->flags & BINTEXT_FONT)) { + s->font = p; + } else { + switch(s->font_height) { + default: + av_log(avctx, AV_LOG_WARNING, "font height %i not supported\n", s->font_height); + s->font_height = 8; + case 8: + s->font = ff_cga_font; + break; + case 16: + s->font = ff_vga16_font; + break; + } + } + + return 0; +} + +#define DEFAULT_BG_COLOR 0 +static void hscroll(AVCodecContext *avctx) +{ + XbinContext *s = avctx->priv_data; + if (s->y < avctx->height - s->font_height) { + s->y += s->font_height; + } else { + memmove(s->frame.data[0], s->frame.data[0] + s->font_height*s->frame.linesize[0], + (avctx->height - s->font_height)*s->frame.linesize[0]); + memset(s->frame.data[0] + (avctx->height - s->font_height)*s->frame.linesize[0], + DEFAULT_BG_COLOR, s->font_height * s->frame.linesize[0]); + } +} + +#define FONT_WIDTH 8 + +/** + * Draw character to screen + */ +static void draw_char(AVCodecContext *avctx, int c, int a) +{ + XbinContext *s = avctx->priv_data; + if (s->y > avctx->height - s->font_height) + return; + ff_draw_pc_font(s->frame.data[0] + s->y * s->frame.linesize[0] + s->x, + s->frame.linesize[0], s->font, s->font_height, c, + a & 0x0F, a >> 4); + s->x += FONT_WIDTH; + if (s->x > avctx->width - FONT_WIDTH) { + s->x = 0; + s->y += s->font_height; + } +} + +static int decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + AVPacket *avpkt) +{ + XbinContext *s = avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + const uint8_t *buf_end = buf+buf_size; + + s->x = s->y = 0; + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | + FF_BUFFER_HINTS_PRESERVE | + FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &s->frame)) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + s->frame.pict_type = AV_PICTURE_TYPE_I; + s->frame.palette_has_changed = 1; + memcpy(s->frame.data[1], s->palette, 16 * 4); + + if (avctx->codec_id == CODEC_ID_XBIN) { + while (buf + 2 < buf_end) { + int i,c,a; + int type = *buf >> 6; + int count = (*buf & 0x3F) + 1; + buf++; + switch (type) { + case 0: //no compression + for (i = 0; i < count && buf + 1 < buf_end; i++) { + draw_char(avctx, buf[0], buf[1]); + buf += 2; + } + break; + case 1: //character compression + c = *buf++; + for (i = 0; i < count && buf < buf_end; i++) + draw_char(avctx, c, *buf++); + break; + case 2: //attribute compression + a = *buf++; + for (i = 0; i < count && buf < buf_end; i++) + draw_char(avctx, *buf++, a); + break; + case 3: //character/attribute compression + c = *buf++; + a = *buf++; + for (i = 0; i < count && buf < buf_end; i++) + draw_char(avctx, c, a); + break; + } + } + } else if (avctx->codec_id == CODEC_ID_IDF) { + while (buf + 2 < buf_end) { + if (AV_RL16(buf) == 1) { + int i; + if (buf + 6 > buf_end) + break; + for (i = 0; i < buf[2]; i++) + draw_char(avctx, buf[4], buf[5]); + buf += 6; + } else { + draw_char(avctx, buf[0], buf[1]); + buf += 2; + } + } + } else { + while (buf + 1 < buf_end) { + draw_char(avctx, buf[0], buf[1]); + buf += 2; + } + } + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = s->frame; + return buf_size; +} + +static av_cold int decode_end(AVCodecContext *avctx) +{ + XbinContext *s = avctx->priv_data; + + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + return 0; +} + +AVCodec ff_bintext_decoder = { + .name = "bintext", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_BINTEXT, + .priv_data_size = sizeof(XbinContext), + .init = decode_init, + .close = decode_end, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Binary text"), +}; + +AVCodec ff_xbin_decoder = { + .name = "xbin", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_XBIN, + .priv_data_size = sizeof(XbinContext), + .init = decode_init, + .close = decode_end, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text"), +}; + +AVCodec ff_idf_decoder = { + .name = "idf", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_IDF, + .priv_data_size = sizeof(XbinContext), + .init = decode_init, + .close = decode_end, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("iCEDraw text"), +}; diff --git a/libavcodec/bintext.h b/libavcodec/bintext.h new file mode 100644 index 0000000000..ea834a00e3 --- /dev/null +++ b/libavcodec/bintext.h @@ -0,0 +1,37 @@ +/* + * Binary text decoder + * Copyright (c) 2010 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 + */ + +/** + * @file + * Binary text decoder + */ + +#ifndef AVCODEC_BINTEXT_H +#define AVCODEC_BINTEXT_H + +/* flag values passed between avformat and avcodec; + * while these are identical to the XBIN flags, they are are also used + * for the BINTEXT and IDF decoders. + */ +#define BINTEXT_PALETTE 0x1 +#define BINTEXT_FONT 0x2 + +#endif /* AVCODEC_BINTEXT_H */ diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index 8ac4802961..e1336438a0 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -6,20 +6,20 @@ * * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -105,8 +105,8 @@ static int alloc_table(VLC *vlc, int size, int use_static) if(use_static) abort(); // cannot do anything, init_vlc() is used with too little memory vlc->table_allocated += (1 << vlc->bits); - vlc->table = av_realloc(vlc->table, - sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + vlc->table = av_realloc_f(vlc->table, + vlc->table_allocated, sizeof(VLC_TYPE) * 2); if (!vlc->table) return -1; } diff --git a/libavcodec/bitstream_filter.c b/libavcodec/bitstream_filter.c index b803ca4ef9..1a6ba396d2 100644 --- a/libavcodec/bitstream_filter.c +++ b/libavcodec/bitstream_filter.c @@ -1,20 +1,20 @@ /* * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bmp.c b/libavcodec/bmp.c index 1f725f5369..b7853d1093 100644 --- a/libavcodec/bmp.c +++ b/libavcodec/bmp.c @@ -2,20 +2,20 @@ * BMP image format decoder * Copyright (c) 2005 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -49,6 +49,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, unsigned int ihsize; int i, j, n, linesize; uint32_t rgb[3]; + uint32_t alpha = 0; uint8_t *ptr; int dsize; const uint8_t *buf0 = buf; @@ -92,7 +93,8 @@ static int bmp_decode_frame(AVCodecContext *avctx, } switch(ihsize){ - case 40: // windib v3 + case 40: // windib + case 56: // windib v3 case 64: // OS/2 v2 case 108: // windib v4 case 124: // windib v5 @@ -115,7 +117,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, depth = bytestream_get_le16(&buf); - if(ihsize == 40) + if(ihsize == 40 || ihsize == 64 || ihsize == 56) comp = bytestream_get_le32(&buf); else comp = BMP_RGB; @@ -130,6 +132,8 @@ static int bmp_decode_frame(AVCodecContext *avctx, rgb[0] = bytestream_get_le32(&buf); rgb[1] = bytestream_get_le32(&buf); rgb[2] = bytestream_get_le32(&buf); + if (ihsize >= 108) + alpha = bytestream_get_le32(&buf); } avctx->width = width; @@ -140,21 +144,21 @@ static int bmp_decode_frame(AVCodecContext *avctx, switch(depth){ case 32: if(comp == BMP_BITFIELDS){ - rgb[0] = (rgb[0] >> 15) & 3; - rgb[1] = (rgb[1] >> 15) & 3; - rgb[2] = (rgb[2] >> 15) & 3; - - if(rgb[0] + rgb[1] + rgb[2] != 3 || - rgb[0] == rgb[1] || rgb[0] == rgb[2] || rgb[1] == rgb[2]){ - break; + if (rgb[0] == 0xFF000000 && rgb[1] == 0x00FF0000 && rgb[2] == 0x0000FF00) + avctx->pix_fmt = alpha ? PIX_FMT_ABGR : PIX_FMT_0BGR; + else if (rgb[0] == 0x00FF0000 && rgb[1] == 0x0000FF00 && rgb[2] == 0x000000FF) + avctx->pix_fmt = alpha ? PIX_FMT_BGRA : PIX_FMT_BGR0; + else if (rgb[0] == 0x0000FF00 && rgb[1] == 0x00FF0000 && rgb[2] == 0xFF000000) + avctx->pix_fmt = alpha ? PIX_FMT_ARGB : PIX_FMT_0RGB; + else if (rgb[0] == 0x000000FF && rgb[1] == 0x0000FF00 && rgb[2] == 0x00FF0000) + avctx->pix_fmt = alpha ? PIX_FMT_RGBA : PIX_FMT_RGB0; + else { + av_log(avctx, AV_LOG_ERROR, "Unknown bitfields %0X %0X %0X\n", rgb[0], rgb[1], rgb[2]); + return AVERROR(EINVAL); } } else { - rgb[0] = 2; - rgb[1] = 1; - rgb[2] = 0; + avctx->pix_fmt = PIX_FMT_BGRA; } - - avctx->pix_fmt = PIX_FMT_BGR24; break; case 24: avctx->pix_fmt = PIX_FMT_BGR24; @@ -215,7 +219,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, dsize = buf_size - hsize; /* Line size in file multiple of 4 */ - n = ((avctx->width * depth) / 8 + 3) & ~3; + n = ((avctx->width * depth + 31) / 8) & ~3; if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){ av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", @@ -253,10 +257,10 @@ static int bmp_decode_frame(AVCodecContext *avctx, buf = buf0 + 14 + ihsize; //palette location if((hsize-ihsize-14) < (colors << 2)){ // OS/2 bitmap, 3 bytes per palette entry for(i = 0; i < colors; i++) - ((uint32_t*)p->data[1])[i] = bytestream_get_le24(&buf); + ((uint32_t*)p->data[1])[i] = (0xff<<24) | bytestream_get_le24(&buf); }else{ for(i = 0; i < colors; i++) - ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf); + ((uint32_t*)p->data[1])[i] = 0xFFU << 24 | bytestream_get_le32(&buf); } buf = buf0 + hsize; } @@ -291,6 +295,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, break; case 8: case 24: + case 32: for(i = 0; i < avctx->height; i++){ memcpy(ptr, buf, n); buf += n; @@ -320,23 +325,6 @@ static int bmp_decode_frame(AVCodecContext *avctx, ptr += linesize; } break; - case 32: - for(i = 0; i < avctx->height; i++){ - const uint8_t *src = buf; - uint8_t *dst = ptr; - - for(j = 0; j < avctx->width; j++){ - dst[0] = src[rgb[2]]; - dst[1] = src[rgb[1]]; - dst[2] = src[rgb[0]]; - dst += 3; - src += 4; - } - - buf += n; - ptr += linesize; - } - break; default: av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n"); return -1; diff --git a/libavcodec/bmp.h b/libavcodec/bmp.h index ab11523379..b24a1faf00 100644 --- a/libavcodec/bmp.h +++ b/libavcodec/bmp.h @@ -2,20 +2,20 @@ * internals for BMP codecs * Copyright (c) 2005 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/bmpenc.c b/libavcodec/bmpenc.c index ca2951ab37..b457445321 100644 --- a/libavcodec/bmpenc.c +++ b/libavcodec/bmpenc.c @@ -3,20 +3,20 @@ * Copyright (c) 2006, 2007 Michel Bardiaux * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -24,6 +24,7 @@ #include "avcodec.h" #include "bytestream.h" #include "bmp.h" +#include <assert.h> static const uint32_t monoblack_pal[] = { 0x000000, 0xFFFFFF }; static const uint32_t rgb565_masks[] = { 0xF800, 0x07E0, 0x001F }; @@ -36,6 +37,9 @@ static av_cold int bmp_encode_init(AVCodecContext *avctx){ avctx->coded_frame = (AVFrame*)&s->picture; switch (avctx->pix_fmt) { + case PIX_FMT_BGRA: + avctx->bits_per_coded_sample = 32; + break; case PIX_FMT_BGR24: avctx->bits_per_coded_sample = 24; break; @@ -69,6 +73,7 @@ static int bmp_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_s AVFrame * const p= (AVFrame*)&s->picture; int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize; const uint32_t *pal = NULL; + uint32_t palette256[256]; int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB; int bit_count = avctx->bits_per_coded_sample; uint8_t *ptr; @@ -92,7 +97,10 @@ static int bmp_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_s case PIX_FMT_RGB4_BYTE: case PIX_FMT_BGR4_BYTE: case PIX_FMT_GRAY8: - ff_set_systematic_pal2((uint32_t*)p->data[1], avctx->pix_fmt); + assert(bit_count == 8); + ff_set_systematic_pal2(palette256, avctx->pix_fmt); + pal = palette256; + break; case PIX_FMT_PAL8: pal = (uint32_t *)p->data[1]; break; @@ -162,8 +170,8 @@ AVCodec ff_bmp_encoder = { .init = bmp_encode_init, .encode = bmp_encode_frame, .pix_fmts = (const enum PixelFormat[]){ - PIX_FMT_BGR24, - PIX_FMT_RGB555, PIX_FMT_RGB444, PIX_FMT_RGB565, + PIX_FMT_BGRA, PIX_FMT_BGR24, + PIX_FMT_RGB565, PIX_FMT_RGB555, PIX_FMT_RGB444, PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY8, PIX_FMT_PAL8, PIX_FMT_MONOBLACK, PIX_FMT_NONE}, diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c index 49346a41a8..37c844858f 100644 --- a/libavcodec/bmv.c +++ b/libavcodec/bmv.c @@ -219,7 +219,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac return AVERROR_INVALIDDATA; } for (i = 0; i < 256; i++) - c->pal[i] = bytestream_get_be24(&c->stream); + c->pal[i] = 0xFF << 24 | bytestream_get_be24(&c->stream); } if (type & BMV_SCROLL) { if (c->stream - pkt->data > pkt->size - 2) { diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h index 4d686e550a..cba2dbb22d 100644 --- a/libavcodec/bytestream.h +++ b/libavcodec/bytestream.h @@ -3,20 +3,20 @@ * copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr> * Copyright (c) 2012 Aneesh Dogra (lionaneesh) <lionaneesh@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/c93.c b/libavcodec/c93.c index ecfd035d75..ad2dc0a7bf 100644 --- a/libavcodec/c93.c +++ b/libavcodec/c93.c @@ -2,20 +2,20 @@ * Interplay C93 video decoder * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -47,6 +47,10 @@ typedef enum { static av_cold int decode_init(AVCodecContext *avctx) { + C93DecoderContext * const c93 = avctx->priv_data; + + avcodec_get_frame_defaults(&c93->pictures[0]); + avcodec_get_frame_defaults(&c93->pictures[1]); avctx->pix_fmt = PIX_FMT_PAL8; return 0; } @@ -126,7 +130,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, c93->currentpic ^= 1; - newpic->reference = 1; + newpic->reference = 3; 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)) { @@ -148,7 +152,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, 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); + palette[i] = 0xFF << 24 | bytestream_get_be24(&palbuf); } } else { if (oldpic->data[1]) diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 4afcafb52b..9b880d2398 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -52,6 +52,7 @@ static const uint8_t lps_range[64][4]= { uint8_t ff_h264_mlps_state[4*64]; uint8_t ff_h264_lps_range[4*2*64]; +uint8_t ff_h264_lps_state[2*64]; static uint8_t h264_mps_state[2 * 64]; static const uint8_t mps_state[64]= { @@ -146,10 +147,14 @@ void ff_init_cabac_states(CABACContext *c){ h264_mps_state[2 * i + 1] = 2 * mps_state[i] + 1; if( i ){ + ff_h264_lps_state[2*i+0]= ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0; + ff_h264_lps_state[2*i+1]= ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1; }else{ + ff_h264_lps_state[2*i+0]= ff_h264_mlps_state[128-2*i-1]= 1; + ff_h264_lps_state[2*i+1]= ff_h264_mlps_state[128-2*i-2]= 0; } } @@ -196,6 +201,7 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ }else{ c->low += c->range - RangeLPS; c->range = RangeLPS; + *state= ff_h264_lps_state[*state]; } renorm_cabac_encoder(c); @@ -260,7 +266,8 @@ int main(void){ ff_init_cabac_states(&c); for(i=0; i<SIZE; i++){ - r[i] = av_lfg_get(&prng) % 7; + if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7; + else r[i] = (i>>8)&1; } for(i=0; i<SIZE; i++){ diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 5a99f0b2fe..667489ede8 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h index b150aabcc4..226edfa0ef 100644 --- a/libavcodec/cabac_functions.h +++ b/libavcodec/cabac_functions.h @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cavs.c b/libavcodec/cavs.c index 9ff0e5165b..adaf797cde 100644 --- a/libavcodec/cavs.c +++ b/libavcodec/cavs.c @@ -2,20 +2,20 @@ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cavs.h b/libavcodec/cavs.h index eda76a8d8e..cb4ab2630b 100644 --- a/libavcodec/cavs.h +++ b/libavcodec/cavs.h @@ -2,20 +2,20 @@ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cavs_parser.c b/libavcodec/cavs_parser.c index a91be3a04d..690ef54f97 100644 --- a/libavcodec/cavs_parser.c +++ b/libavcodec/cavs_parser.c @@ -2,20 +2,20 @@ * Chinese AVS video (AVS1-P2, JiZhun profile) parser. * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cavsdata.h b/libavcodec/cavsdata.h index 210169f844..a93405d380 100644 --- a/libavcodec/cavsdata.h +++ b/libavcodec/cavsdata.h @@ -2,20 +2,20 @@ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 2f4b6e3b14..16e5474d84 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -2,20 +2,20 @@ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -115,7 +115,8 @@ static inline int get_ue_code(GetBitContext *gb, int order) { static int decode_residual_block(AVSContext *h, GetBitContext *gb, const struct dec_2dvlc *r, int esc_golomb_order, int qp, uint8_t *dst, int stride) { - int i, level_code, esc_code, level, run, mask; + int i, esc_code, level, mask; + unsigned int level_code, run; DCTELEM level_buf[65]; uint8_t run_buf[65]; DCTELEM *block = h->block; @@ -124,20 +125,20 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, level_code = get_ue_code(gb,r->golomb_order); if(level_code >= ESCAPE_CODE) { run = ((level_code - ESCAPE_CODE) >> 1) + 1; + if(run > 64) + return -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 if (level_code >= 0) { + } 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]; - } else { - break; } level_buf[i] = level; run_buf[i] = run; @@ -165,7 +166,7 @@ static inline int decode_residual_inter(AVSContext *h) { /* get coded block pattern */ int cbp= get_ue_golomb(&h->s.gb); - if(cbp > 63){ + if(cbp > 63U){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n"); return -1; } @@ -225,7 +226,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) { /* get coded block pattern */ if(h->pic_type == AV_PICTURE_TYPE_I) cbp_code = get_ue_golomb(gb); - if(cbp_code > 63){ + if(cbp_code > 63U){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n"); return -1; } diff --git a/libavcodec/cavsdsp.c b/libavcodec/cavsdsp.c index 04e521be75..192e0f976d 100644 --- a/libavcodec/cavsdsp.c +++ b/libavcodec/cavsdsp.c @@ -5,20 +5,20 @@ * * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cavsdsp.h b/libavcodec/cavsdsp.h index b1133b7264..b41ad21bca 100644 --- a/libavcodec/cavsdsp.h +++ b/libavcodec/cavsdsp.h @@ -2,20 +2,20 @@ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cbrt_tablegen.c b/libavcodec/cbrt_tablegen.c index e92c0f1db1..e0a8e63a8b 100644 --- a/libavcodec/cbrt_tablegen.c +++ b/libavcodec/cbrt_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cbrt_tablegen.h b/libavcodec/cbrt_tablegen.h index 01963a3f9d..a9d34dc75d 100644 --- a/libavcodec/cbrt_tablegen.h +++ b/libavcodec/cbrt_tablegen.h @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index f1f474f3de..b87ca1d2c3 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -2,20 +2,20 @@ * CD Graphics Video Decoder * Copyright (c) 2009 Michael Tison * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -126,7 +126,7 @@ static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low) r = ((color >> 8) & 0x000F) * 17; g = ((color >> 4) & 0x000F) * 17; b = ((color ) & 0x000F) * 17; - palette[i + array_offset] = r << 16 | g << 8 | b; + palette[i + array_offset] = 0xFF << 24 | r << 16 | g << 8 | b; } cc->frame.palette_has_changed = 1; } diff --git a/libavcodec/celp_filters.c b/libavcodec/celp_filters.c index 25a6744b04..1535060c9d 100644 --- a/libavcodec/celp_filters.c +++ b/libavcodec/celp_filters.c @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -58,7 +58,7 @@ void ff_celp_circ_addf(float *out, const float *in, int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs, const int16_t *in, int buffer_length, int filter_length, int stop_on_overflow, - int rounder) + int shift, int rounder) { int i,n; @@ -67,7 +67,7 @@ int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs, for (i = 1; i <= filter_length; i++) sum -= filter_coeffs[i-1] * out[n-i]; - sum = (sum >> 12) + in[n]; + sum = ((sum >> 12) + in[n]) >> shift; if (sum + 0x8000 > 0xFFFFU) { if (stop_on_overflow) diff --git a/libavcodec/celp_filters.h b/libavcodec/celp_filters.h index cfd08fd440..f7e8fbddd3 100644 --- a/libavcodec/celp_filters.h +++ b/libavcodec/celp_filters.h @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -63,6 +63,7 @@ void ff_celp_circ_addf(float *out, const float *in, * @param filter_length filter length (10 for 10th order LP filter) * @param stop_on_overflow 1 - return immediately if overflow occurs * 0 - ignore overflows + * @param shift the result is shifted right by this value * @param rounder the amount to add for rounding (usually 0x800 or 0xfff) * * @return 1 if overflow occurred, 0 - otherwise @@ -75,7 +76,7 @@ void ff_celp_circ_addf(float *out, const float *in, int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs, const int16_t *in, int buffer_length, int filter_length, int stop_on_overflow, - int rounder); + int shift, int rounder); /** * LP synthesis filter. diff --git a/libavcodec/celp_math.c b/libavcodec/celp_math.c index 8d36d4e900..d85277f209 100644 --- a/libavcodec/celp_math.c +++ b/libavcodec/celp_math.c @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,8 +25,85 @@ #include <assert.h> #include "avcodec.h" +#include "mathops.h" #include "celp_math.h" +#ifdef G729_BITEXACT +/** + * Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64) + */ +static const int16_t base_cos[64] = +{ + 32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853, + 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279, + 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010, + 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608, + 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039, + -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006, + -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622, + -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729 +}; + +/** + * Slope used to compute cos(x) + * + * cos(ind*64+offset) = base_cos[ind]+offset*slope_cos[ind] + * values multiplied by 1<<19 + */ +static const int16_t slope_cos[64] = +{ + -632, -1893, -3150, -4399, -5638, -6863, -8072, -9261, + -10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744, + -18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526, + -24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726, + -25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009, + -23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637, + -17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428, + -9261, -8072, -6863, -5638, -4399, -3150, -1893, -632 +}; + +/** + * Table used to compute exp2(x) + * + * tab_exp2[i] = (1<<14) * exp2(i/32) = 2^(i/32) i=0..32 + */ +static const uint16_t tab_exp2[33] = +{ + 16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911, + 20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726, + 25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706, + 31379, 32066, 32767 +}; + +int16_t ff_cos(uint16_t arg) +{ + uint8_t offset= arg; + uint8_t ind = arg >> 8; + + assert(arg < 0x4000); + + return FFMAX(base_cos[ind] + ((slope_cos[ind] * offset) >> 12), -0x8000); +} + +int ff_exp2(uint16_t power) +{ + uint16_t frac_x0; + uint16_t frac_dx; + int result; + + assert(power <= 0x7fff); + + frac_x0 = power >> 10; + frac_dx = (power & 0x03ff) << 5; + + result = tab_exp2[frac_x0] << 15; + result += frac_dx * (tab_exp2[frac_x0+1] - tab_exp2[frac_x0]); + + return result >> 10; +} + +#else // G729_BITEXACT + /** * Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64) */ @@ -78,6 +155,8 @@ int ff_exp2(uint16_t power) return result + ((result*(power&31)*89)>>22); } +#endif // else G729_BITEXACT + /** * Table used to compute log2(x) * @@ -85,10 +164,17 @@ int ff_exp2(uint16_t power) */ static const uint16_t tab_log2[33] = { +#ifdef G729_BITEXACT + 0, 1455, 2866, 4236, 5568, 6863, 8124, 9352, + 10549, 11716, 12855, 13967, 15054, 16117, 17156, 18172, + 19167, 20142, 21097, 22033, 22951, 23852, 24735, 25603, + 26455, 27291, 28113, 28922, 29716, 30497, 31266, 32023, 32767, +#else 4, 1459, 2870, 4240, 5572, 6867, 8127, 9355, 10552, 11719, 12858, 13971, 15057, 16120, 17158, 18175, 19170, 20145, 21100, 22036, 22954, 23854, 24738, 25605, 26457, 27294, 28116, 28924, 29719, 30500, 31269, 32025, 32769, +#endif }; int ff_log2(uint32_t value) @@ -111,6 +197,17 @@ int ff_log2(uint32_t value) return (power_int << 15) + value; } +int64_t ff_dot_product(const int16_t *a, const int16_t *b, int length) +{ + int i; + int64_t sum = 0; + + for (i = 0; i < length; i++) + sum += MUL16(a[i], b[i]); + + return sum; +} + float ff_dot_productf(const float* a, const float* b, int length) { float sum = 0; diff --git a/libavcodec/celp_math.h b/libavcodec/celp_math.h index 4a502ca04b..ec62a9ea09 100644 --- a/libavcodec/celp_math.h +++ b/libavcodec/celp_math.h @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -64,6 +64,16 @@ static inline int bidir_sal(int value, int offset) } /** + * returns the dot product of 2 int16_t vectors. + * @param a input data array + * @param b input data array + * @param length number of elements + * + * @return dot product = sum of elementwise products + */ +int64_t ff_dot_product(const int16_t *a, const int16_t *b, int length); + +/** * Return the dot product. * @param a input data array * @param b input data array diff --git a/libavcodec/cga_data.c b/libavcodec/cga_data.c index 2c63ff2001..46097bb804 100644 --- a/libavcodec/cga_data.c +++ b/libavcodec/cga_data.c @@ -1,20 +1,20 @@ /* * CGA/EGA/VGA ROM data * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -417,19 +417,19 @@ const uint8_t ff_vga16_font[4096] = { }; const uint32_t ff_cga_palette[16] = { - 0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA, - 0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF, + 0xFF000000, 0xFF0000AA, 0xFF00AA00, 0xFF00AAAA, 0xFFAA0000, 0xFFAA00AA, 0xFFAA5500, 0xFFAAAAAA, + 0xFF555555, 0xFF5555FF, 0xFF55FF55, 0xFF55FFFF, 0xFFFF5555, 0xFFFF55FF, 0xFFFFFF55, 0xFFFFFFFF, }; const uint32_t ff_ega_palette[64] = { - 0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xAAAA00, 0xAAAAAA, - 0x000055, 0x0000FF, 0x00AA55, 0x00AAFF, 0xAA0055, 0xAA00FF, 0xAAAA55, 0xAAAAFF, - 0x005500, 0x0055AA, 0x00FF00, 0x00FFAA, 0xAA5500, 0xAA55AA, 0xAAFF00, 0xAAFFAA, - 0x005555, 0x0055FF, 0x00FF55, 0x00FFFF, 0xAA5555, 0xAA55FF, 0xAAFF55, 0xAAFFFF, - 0x550000, 0x5500AA, 0x55AA00, 0x55AAAA, 0xFF0000, 0xFF00AA, 0xFFAA00, 0xFFAAAA, - 0x550055, 0x5500FF, 0x55AA55, 0x55AAFF, 0xFF0055, 0xFF00FF, 0xFFAA55, 0xFFAAFF, - 0x555500, 0x5555AA, 0x55FF00, 0x55FFAA, 0xFF5500, 0xFF55AA, 0xFFFF00, 0xFFFFAA, - 0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF + 0xFF000000, 0xFF0000AA, 0xFF00AA00, 0xFF00AAAA, 0xFFAA0000, 0xFFAA00AA, 0xFFAAAA00, 0xFFAAAAAA, + 0xFF000055, 0xFF0000FF, 0xFF00AA55, 0xFF00AAFF, 0xFFAA0055, 0xFFAA00FF, 0xFFAAAA55, 0xFFAAAAFF, + 0xFF005500, 0xFF0055AA, 0xFF00FF00, 0xFF00FFAA, 0xFFAA5500, 0xFFAA55AA, 0xFFAAFF00, 0xFFAAFFAA, + 0xFF005555, 0xFF0055FF, 0xFF00FF55, 0xFF00FFFF, 0xFFAA5555, 0xFFAA55FF, 0xFFAAFF55, 0xFFAAFFFF, + 0xFF550000, 0xFF5500AA, 0xFF55AA00, 0xFF55AAAA, 0xFFFF0000, 0xFFFF00AA, 0xFFFFAA00, 0xFFFFAAAA, + 0xFF550055, 0xFF5500FF, 0xFF55AA55, 0xFF55AAFF, 0xFFFF0055, 0xFFFF00FF, 0xFFFFAA55, 0xFFFFAAFF, + 0xFF555500, 0xFF5555AA, 0xFF55FF00, 0xFF55FFAA, 0xFFFF5500, 0xFFFF55AA, 0xFFFFFF00, 0xFFFFFFAA, + 0xFF555555, 0xFF5555FF, 0xFF55FF55, 0xFF55FFFF, 0xFFFF5555, 0xFFFF55FF, 0xFFFFFF55, 0xFFFFFFFF }; void ff_draw_pc_font(uint8_t *dst, int linesize, const uint8_t *font, int font_height, int ch, int fg, int bg) diff --git a/libavcodec/cga_data.h b/libavcodec/cga_data.h index 2149cfd2f1..998dccaefb 100644 --- a/libavcodec/cga_data.h +++ b/libavcodec/cga_data.h @@ -1,20 +1,20 @@ /* * CGA/EGA/VGA ROM data * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/chomp_bsf.c b/libavcodec/chomp_bsf.c index 9ed7496930..eaefaaa539 100644 --- a/libavcodec/chomp_bsf.c +++ b/libavcodec/chomp_bsf.c @@ -2,20 +2,20 @@ * Chomp bitstream filter * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cinepak.c b/libavcodec/cinepak.c index 08ab05f8bb..1181c99e7e 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -2,20 +2,20 @@ * Cinepak Video Decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -360,6 +360,8 @@ static int cinepak_decode (CinepakContext *s) num_strips = FFMIN(num_strips, MAX_STRIPS); + s->frame.key_frame = 0; + for (i=0; i < num_strips; i++) { if ((s->data + 12) > eod) return AVERROR_INVALIDDATA; @@ -370,6 +372,9 @@ static int cinepak_decode (CinepakContext *s) s->strips[i].y2 = y0 + AV_RB16 (&s->data[8]); s->strips[i].x2 = s->avctx->width; + if (s->strips[i].id == 0x10) + s->frame.key_frame = 1; + strip_size = AV_RB24 (&s->data[1]) - 12; if (strip_size < 0) return AVERROR_INVALIDDATA; @@ -412,6 +417,7 @@ static av_cold int cinepak_decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_PAL8; } + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; @@ -428,7 +434,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx, s->data = buf; s->size = buf_size; - s->frame.reference = 1; + s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if ((ret = avctx->reget_buffer(avctx, &s->frame))) { diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c index cf307bb06a..4027cff4c7 100644 --- a/libavcodec/cljr.c +++ b/libavcodec/cljr.c @@ -2,20 +2,20 @@ * Cirrus Logic AccuPak (CLJR) codec * Copyright (c) 2003 Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,17 +25,21 @@ */ #include "avcodec.h" +#include "libavutil/opt.h" #include "get_bits.h" #include "put_bits.h" typedef struct CLJRContext { + AVClass *avclass; AVFrame picture; + int dither_type; } CLJRContext; static av_cold int common_init(AVCodecContext *avctx) { CLJRContext * const a = avctx->priv_data; + avcodec_get_frame_defaults(&a->picture); avctx->coded_frame = &a->picture; return 0; @@ -62,7 +66,7 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if (buf_size < avctx->height * avctx->width) { + if (buf_size / avctx->height < avctx->width) { av_log(avctx, AV_LOG_ERROR, "Resolution larger than buffer size. Invalid header?\n"); return AVERROR_INVALIDDATA; @@ -83,10 +87,10 @@ static int decode_frame(AVCodecContext *avctx, uint8_t *cb = &a->picture.data[1][y * a->picture.linesize[1]]; uint8_t *cr = &a->picture.data[2][y * a->picture.linesize[2]]; for (x = 0; x < avctx->width; x += 4) { - luma[3] = get_bits(&gb, 5) << 3; - luma[2] = get_bits(&gb, 5) << 3; - luma[1] = get_bits(&gb, 5) << 3; - luma[0] = get_bits(&gb, 5) << 3; + luma[3] = (get_bits(&gb, 5)*33) >> 2; + luma[2] = (get_bits(&gb, 5)*33) >> 2; + luma[1] = (get_bits(&gb, 5)*33) >> 2; + luma[0] = (get_bits(&gb, 5)*33) >> 2; luma += 4; *(cb++) = get_bits(&gb, 6) << 2; *(cr++) = get_bits(&gb, 6) << 2; @@ -131,9 +135,16 @@ AVCodec ff_cljr_decoder = { static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data) { + CLJRContext *a = avctx->priv_data; PutBitContext pb; AVFrame *p = data; int x, y; + uint32_t dither= avctx->frame_number; + static const uint32_t ordered_dither[2][2] = + { + { 0x10400000, 0x104F0000 }, + { 0xCB2A0000, 0xCB250000 }, + }; p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; @@ -145,13 +156,18 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, uint8_t *cb = &p->data[1][y * p->linesize[1]]; uint8_t *cr = &p->data[2][y * p->linesize[2]]; for (x = 0; x < avctx->width; x += 4) { - put_bits(&pb, 5, luma[3] >> 3); - put_bits(&pb, 5, luma[2] >> 3); - put_bits(&pb, 5, luma[1] >> 3); - put_bits(&pb, 5, luma[0] >> 3); + switch (a->dither_type) { + case 0: dither = 0x492A0000; break; + case 1: dither = dither * 1664525 + 1013904223; break; + case 2: dither = ordered_dither[ y&1 ][ (x>>2)&1 ];break; + } + put_bits(&pb, 5, (249*(luma[3] + (dither>>29) )) >> 11); + put_bits(&pb, 5, (249*(luma[2] + ((dither>>26)&7))) >> 11); + put_bits(&pb, 5, (249*(luma[1] + ((dither>>23)&7))) >> 11); + put_bits(&pb, 5, (249*(luma[0] + ((dither>>20)&7))) >> 11); luma += 4; - put_bits(&pb, 6, *(cb++) >> 2); - put_bits(&pb, 6, *(cr++) >> 2); + put_bits(&pb, 6, (253*(*(cb++) + ((dither>>18)&3))) >> 10); + put_bits(&pb, 6, (253*(*(cr++) + ((dither>>16)&3))) >> 10); } } @@ -160,6 +176,20 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, return put_bits_count(&pb) / 8; } +#define OFFSET(x) offsetof(CLJRContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "dither_type", "Dither type", OFFSET(dither_type), AV_OPT_TYPE_INT, { .dbl=1 }, 0, 2, VE}, + { NULL }, +}; + +static const AVClass class = { + .class_name = "cljr encoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_cljr_encoder = { .name = "cljr", .type = AVMEDIA_TYPE_VIDEO, @@ -170,5 +200,6 @@ AVCodec ff_cljr_encoder = { .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_YUV411P, PIX_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"), + .priv_class = &class, }; #endif diff --git a/libavcodec/codec_names.sh b/libavcodec/codec_names.sh new file mode 100755 index 0000000000..0e499c9c49 --- /dev/null +++ b/libavcodec/codec_names.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +# Copyright (c) 2011 Nicolas George +# +# 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 + +set -e + +config="$1" +out="$2" +test -n "$out" + +outval="" + +add_line () { + outval="$outval$* +" +} + +parse_config_h () { + while read define var value; do + case "$define $var $value" in + "#define CONFIG_"*_*" 1") eval "$var=1";; + esac + done +} + +define_codecid () { + id="$1" + n=${1#CODEC_ID_} + add_line "case ${id}:" + eval "c=\${CONFIG_${n}_DECODER}:\${CONFIG_${n}_ENCODER}" + case "$c" in + 1:*) s="decoder";; + *:1) s="encoder";; + *) s="";; + esac + case "$s" in + "") add_line " return \"$n\";" ;; + *) + add_line " { extern AVCodec ff_${n}_${s};" + add_line " return ff_${n}_${s}.name; }" + ;; + esac +} + +parse_enum_codecid () { + while read line; do + case "$line" in + "};") break;; + *CODEC_ID_FIRST*=*) ;; + CODEC_ID_*) define_codecid ${line%%[=,]*};; + esac + done +} + +parse_avcodec_h () { + while read line; do + case "$line" in + "enum CodecID {") parse_enum_codecid; break;; + esac + done +} + +parse_config_h < "$config" +parse_avcodec_h # use stdin +sed -e '/case.*:/!y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' \ + -e 's/extern avcodec /extern AVCodec /' > "$out" <<EOF +$outval +EOF diff --git a/libavcodec/cook.c b/libavcodec/cook.c index d2ed819b83..e161b1a1bc 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Sascha Sommer * Copyright (c) 2005 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cookdata.h b/libavcodec/cookdata.h index e8d6ebfcb3..15e8e9519f 100644 --- a/libavcodec/cookdata.h +++ b/libavcodec/cookdata.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Sascha Sommer * Copyright (c) 2005 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/cos_tablegen.c b/libavcodec/cos_tablegen.c index 5e52c482c6..1577166a46 100644 --- a/libavcodec/cos_tablegen.c +++ b/libavcodec/cos_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/crystalhd.c b/libavcodec/crystalhd.c new file mode 100644 index 0000000000..2d10aa9ee7 --- /dev/null +++ b/libavcodec/crystalhd.c @@ -0,0 +1,1167 @@ +/* + * - CrystalHD decoder module - + * + * Copyright(C) 2010,2011 Philip Langdale <ffmpeg.philipl@overt.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 + */ + +/* + * - Principles of Operation - + * + * The CrystalHD decoder operates at the bitstream level - which is an even + * higher level than the decoding hardware you typically see in modern GPUs. + * This means it has a very simple interface, in principle. You feed demuxed + * packets in one end and get decoded picture (fields/frames) out the other. + * + * Of course, nothing is ever that simple. Due, at the very least, to b-frame + * dependencies in the supported formats, the hardware has a delay between + * when a packet goes in, and when a picture comes out. Furthermore, this delay + * is not just a function of time, but also one of the dependency on additional + * frames being fed into the decoder to satisfy the b-frame dependencies. + * + * As such, a pipeline will build up that is roughly equivalent to the required + * DPB for the file being played. If that was all it took, things would still + * be simple - so, of course, it isn't. + * + * The hardware has a way of indicating that a picture is ready to be copied out, + * but this is unreliable - and sometimes the attempt will still fail so, based + * on testing, the code will wait until 3 pictures are ready before starting + * to copy out - and this has the effect of extending the pipeline. + * + * Finally, while it is tempting to say that once the decoder starts outputing + * frames, the software should never fail to return a frame from a decode(), + * this is a hard assertion to make, because the stream may switch between + * differently encoded content (number of b-frames, interlacing, etc) which + * might require a longer pipeline than before. If that happened, you could + * deadlock trying to retrieve a frame that can't be decoded without feeding + * in additional packets. + * + * As such, the code will return in the event that a picture cannot be copied + * out, leading to an increase in the length of the pipeline. This in turn, + * means we have to be sensitive to the time it takes to decode a picture; + * We do not want to give up just because the hardware needed a little more + * time to prepare the picture! For this reason, there are delays included + * in the decode() path that ensure that, under normal conditions, the hardware + * will only fail to return a frame if it really needs additional packets to + * complete the decoding. + * + * Finally, to be explicit, we do not want the pipeline to grow without bound + * for two reasons: 1) The hardware can only buffer a finite number of packets, + * and 2) The client application may not be able to cope with arbitrarily long + * delays in the video path relative to the audio path. For example. MPlayer + * can only handle a 20 picture delay (although this is arbitrary, and needs + * to be extended to fully support the CrystalHD where the delay could be up + * to 32 pictures - consider PAFF H.264 content with 16 b-frames). + */ + +/***************************************************************************** + * Includes + ****************************************************************************/ + +#define _XOPEN_SOURCE 600 +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <libcrystalhd/bc_dts_types.h> +#include <libcrystalhd/bc_dts_defs.h> +#include <libcrystalhd/libcrystalhd_if.h> + +#include "avcodec.h" +#include "h264.h" +#include "libavutil/imgutils.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/opt.h" + +/** Timeout parameter passed to DtsProcOutput() in us */ +#define OUTPUT_PROC_TIMEOUT 50 +/** Step between fake timestamps passed to hardware in units of 100ns */ +#define TIMESTAMP_UNIT 100000 +/** Initial value in us of the wait in decode() */ +#define BASE_WAIT 10000 +/** Increment in us to adjust wait in decode() */ +#define WAIT_UNIT 1000 + + +/***************************************************************************** + * Module private data + ****************************************************************************/ + +typedef enum { + RET_ERROR = -1, + RET_OK = 0, + RET_COPY_AGAIN = 1, + RET_SKIP_NEXT_COPY = 2, + RET_COPY_NEXT_FIELD = 3, +} CopyRet; + +typedef struct OpaqueList { + struct OpaqueList *next; + uint64_t fake_timestamp; + uint64_t reordered_opaque; + uint8_t pic_type; +} OpaqueList; + +typedef struct { + AVClass *av_class; + AVCodecContext *avctx; + AVFrame pic; + HANDLE dev; + + uint8_t *orig_extradata; + uint32_t orig_extradata_size; + + AVBitStreamFilterContext *bsfc; + AVCodecParserContext *parser; + + uint8_t is_70012; + uint8_t *sps_pps_buf; + uint32_t sps_pps_size; + uint8_t is_nal; + uint8_t output_ready; + uint8_t need_second_field; + uint8_t skip_next_output; + uint64_t decode_wait; + + uint64_t last_picture; + + OpaqueList *head; + OpaqueList *tail; + + /* Options */ + uint32_t sWidth; + uint8_t bframe_bug; +} CHDContext; + +static const AVOption options[] = { + { "crystalhd_downscale_width", + "Turn on downscaling to the specified width", + offsetof(CHDContext, sWidth), + AV_OPT_TYPE_INT, 0, 0, UINT32_MAX, + AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, }, + { NULL, }, +}; + + +/***************************************************************************** + * Helper functions + ****************************************************************************/ + +static inline BC_MEDIA_SUBTYPE id2subtype(CHDContext *priv, enum CodecID id) +{ + switch (id) { + case CODEC_ID_MPEG4: + return BC_MSUBTYPE_DIVX; + case CODEC_ID_MSMPEG4V3: + return BC_MSUBTYPE_DIVX311; + case CODEC_ID_MPEG2VIDEO: + return BC_MSUBTYPE_MPEG2VIDEO; + case CODEC_ID_VC1: + return BC_MSUBTYPE_VC1; + case CODEC_ID_WMV3: + return BC_MSUBTYPE_WMV3; + case CODEC_ID_H264: + return priv->is_nal ? BC_MSUBTYPE_AVC1 : BC_MSUBTYPE_H264; + default: + return BC_MSUBTYPE_INVALID; + } +} + +static inline void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output) +{ + av_log(priv->avctx, AV_LOG_VERBOSE, "\tYBuffSz: %u\n", output->YbuffSz); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tYBuffDoneSz: %u\n", + output->YBuffDoneSz); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tUVBuffDoneSz: %u\n", + output->UVBuffDoneSz); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tTimestamp: %"PRIu64"\n", + output->PicInfo.timeStamp); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tPicture Number: %u\n", + output->PicInfo.picture_number); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tWidth: %u\n", + output->PicInfo.width); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tHeight: %u\n", + output->PicInfo.height); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tChroma: 0x%03x\n", + output->PicInfo.chroma_format); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tPulldown: %u\n", + output->PicInfo.pulldown); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tFlags: 0x%08x\n", + output->PicInfo.flags); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tFrame Rate/Res: %u\n", + output->PicInfo.frame_rate); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tAspect Ratio: %u\n", + output->PicInfo.aspect_ratio); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tColor Primaries: %u\n", + output->PicInfo.colour_primaries); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tMetaData: %u\n", + output->PicInfo.picture_meta_payload); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tSession Number: %u\n", + output->PicInfo.sess_num); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tycom: %u\n", + output->PicInfo.ycom); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tCustom Aspect: %u\n", + output->PicInfo.custom_aspect_ratio_width_height); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tFrames to Drop: %u\n", + output->PicInfo.n_drop); + av_log(priv->avctx, AV_LOG_VERBOSE, "\tH264 Valid Fields: 0x%08x\n", + output->PicInfo.other.h264.valid); +} + + +/***************************************************************************** + * OpaqueList functions + ****************************************************************************/ + +static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque, + uint8_t pic_type) +{ + OpaqueList *newNode = av_mallocz(sizeof (OpaqueList)); + if (!newNode) { + av_log(priv->avctx, AV_LOG_ERROR, + "Unable to allocate new node in OpaqueList.\n"); + return 0; + } + if (!priv->head) { + newNode->fake_timestamp = TIMESTAMP_UNIT; + priv->head = newNode; + } else { + newNode->fake_timestamp = priv->tail->fake_timestamp + TIMESTAMP_UNIT; + priv->tail->next = newNode; + } + priv->tail = newNode; + newNode->reordered_opaque = reordered_opaque; + newNode->pic_type = pic_type; + + return newNode->fake_timestamp; +} + +/* + * The OpaqueList is built in decode order, while elements will be removed + * in presentation order. If frames are reordered, this means we must be + * able to remove elements that are not the first element. + * + * Returned node must be freed by caller. + */ +static OpaqueList *opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp) +{ + OpaqueList *node = priv->head; + + if (!priv->head) { + av_log(priv->avctx, AV_LOG_ERROR, + "CrystalHD: Attempted to query non-existent timestamps.\n"); + return NULL; + } + + /* + * The first element is special-cased because we have to manipulate + * the head pointer rather than the previous element in the list. + */ + if (priv->head->fake_timestamp == fake_timestamp) { + priv->head = node->next; + + if (!priv->head->next) + priv->tail = priv->head; + + node->next = NULL; + return node; + } + + /* + * The list is processed at arm's length so that we have the + * previous element available to rewrite its next pointer. + */ + while (node->next) { + OpaqueList *current = node->next; + if (current->fake_timestamp == fake_timestamp) { + node->next = current->next; + + if (!node->next) + priv->tail = node; + + current->next = NULL; + return current; + } else { + node = current; + } + } + + av_log(priv->avctx, AV_LOG_VERBOSE, + "CrystalHD: Couldn't match fake_timestamp.\n"); + return NULL; +} + + +/***************************************************************************** + * Video decoder API function definitions + ****************************************************************************/ + +static void flush(AVCodecContext *avctx) +{ + CHDContext *priv = avctx->priv_data; + + avctx->has_b_frames = 0; + priv->last_picture = -1; + priv->output_ready = 0; + priv->need_second_field = 0; + priv->skip_next_output = 0; + priv->decode_wait = BASE_WAIT; + + if (priv->pic.data[0]) + avctx->release_buffer(avctx, &priv->pic); + + /* Flush mode 4 flushes all software and hardware buffers. */ + DtsFlushInput(priv->dev, 4); +} + + +static av_cold int uninit(AVCodecContext *avctx) +{ + CHDContext *priv = avctx->priv_data; + HANDLE device; + + device = priv->dev; + DtsStopDecoder(device); + DtsCloseDecoder(device); + DtsDeviceClose(device); + + /* + * Restore original extradata, so that if the decoder is + * reinitialised, the bitstream detection and filtering + * will work as expected. + */ + if (priv->orig_extradata) { + av_free(avctx->extradata); + avctx->extradata = priv->orig_extradata; + avctx->extradata_size = priv->orig_extradata_size; + priv->orig_extradata = NULL; + priv->orig_extradata_size = 0; + } + + av_parser_close(priv->parser); + if (priv->bsfc) { + av_bitstream_filter_close(priv->bsfc); + } + + av_free(priv->sps_pps_buf); + + if (priv->pic.data[0]) + avctx->release_buffer(avctx, &priv->pic); + + if (priv->head) { + OpaqueList *node = priv->head; + while (node) { + OpaqueList *next = node->next; + av_free(node); + node = next; + } + } + + return 0; +} + + +static av_cold int init(AVCodecContext *avctx) +{ + CHDContext* priv; + BC_STATUS ret; + BC_INFO_CRYSTAL version; + BC_INPUT_FORMAT format = { + .FGTEnable = FALSE, + .Progressive = TRUE, + .OptFlags = 0x80000000 | vdecFrameRate59_94 | 0x40, + .width = avctx->width, + .height = avctx->height, + }; + + BC_MEDIA_SUBTYPE subtype; + + uint32_t mode = DTS_PLAYBACK_MODE | + DTS_LOAD_FILE_PLAY_FW | + DTS_SKIP_TX_CHK_CPB | + DTS_PLAYBACK_DROP_RPT_MODE | + DTS_SINGLE_THREADED_MODE | + DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976); + + av_log(avctx, AV_LOG_VERBOSE, "CrystalHD Init for %s\n", + avctx->codec->name); + + avctx->pix_fmt = PIX_FMT_YUYV422; + + /* Initialize the library */ + priv = avctx->priv_data; + priv->avctx = avctx; + priv->is_nal = avctx->extradata_size > 0 && *(avctx->extradata) == 1; + priv->last_picture = -1; + priv->decode_wait = BASE_WAIT; + + subtype = id2subtype(priv, avctx->codec->id); + switch (subtype) { + case BC_MSUBTYPE_AVC1: + { + uint8_t *dummy_p; + int dummy_int; + + /* Back up the extradata so it can be restored at close time. */ + priv->orig_extradata = av_malloc(avctx->extradata_size); + if (!priv->orig_extradata) { + av_log(avctx, AV_LOG_ERROR, + "Failed to allocate copy of extradata\n"); + return AVERROR(ENOMEM); + } + priv->orig_extradata_size = avctx->extradata_size; + memcpy(priv->orig_extradata, avctx->extradata, avctx->extradata_size); + + priv->bsfc = av_bitstream_filter_init("h264_mp4toannexb"); + if (!priv->bsfc) { + av_log(avctx, AV_LOG_ERROR, + "Cannot open the h264_mp4toannexb BSF!\n"); + return AVERROR_BSF_NOT_FOUND; + } + av_bitstream_filter_filter(priv->bsfc, avctx, NULL, &dummy_p, + &dummy_int, NULL, 0, 0); + } + subtype = BC_MSUBTYPE_H264; + // Fall-through + case BC_MSUBTYPE_H264: + format.startCodeSz = 4; + // Fall-through + case BC_MSUBTYPE_VC1: + case BC_MSUBTYPE_WVC1: + case BC_MSUBTYPE_WMV3: + case BC_MSUBTYPE_WMVA: + case BC_MSUBTYPE_MPEG2VIDEO: + case BC_MSUBTYPE_DIVX: + case BC_MSUBTYPE_DIVX311: + format.pMetaData = avctx->extradata; + format.metaDataSz = avctx->extradata_size; + break; + default: + av_log(avctx, AV_LOG_ERROR, "CrystalHD: Unknown codec name\n"); + return AVERROR(EINVAL); + } + format.mSubtype = subtype; + + if (priv->sWidth) { + format.bEnableScaling = 1; + format.ScalingParams.sWidth = priv->sWidth; + } + + /* Get a decoder instance */ + av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n"); + // Initialize the Link and Decoder devices + ret = DtsDeviceOpen(&priv->dev, mode); + if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: DtsDeviceOpen failed\n"); + goto fail; + } + + ret = DtsCrystalHDVersion(priv->dev, &version); + if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_VERBOSE, + "CrystalHD: DtsCrystalHDVersion failed\n"); + goto fail; + } + priv->is_70012 = version.device == 0; + + if (priv->is_70012 && + (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) { + av_log(avctx, AV_LOG_VERBOSE, + "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n"); + goto fail; + } + + ret = DtsSetInputFormat(priv->dev, &format); + if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "CrystalHD: SetInputFormat failed\n"); + goto fail; + } + + ret = DtsOpenDecoder(priv->dev, BC_STREAM_TYPE_ES); + if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsOpenDecoder failed\n"); + goto fail; + } + + ret = DtsSetColorSpace(priv->dev, OUTPUT_MODE422_YUY2); + if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsSetColorSpace failed\n"); + goto fail; + } + ret = DtsStartDecoder(priv->dev); + if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartDecoder failed\n"); + goto fail; + } + ret = DtsStartCapture(priv->dev); + if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartCapture failed\n"); + goto fail; + } + + if (avctx->codec->id == CODEC_ID_H264) { + priv->parser = av_parser_init(avctx->codec->id); + if (!priv->parser) + av_log(avctx, AV_LOG_WARNING, + "Cannot open the h.264 parser! Interlaced h.264 content " + "will not be detected reliably.\n"); + priv->parser->flags = PARSER_FLAG_COMPLETE_FRAMES; + } + av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Init complete.\n"); + + return 0; + + fail: + uninit(avctx); + return -1; +} + + +static inline CopyRet copy_frame(AVCodecContext *avctx, + BC_DTS_PROC_OUT *output, + void *data, int *data_size) +{ + BC_STATUS ret; + BC_DTS_STATUS decoder_status = { 0, }; + uint8_t trust_interlaced; + uint8_t interlaced; + + CHDContext *priv = avctx->priv_data; + int64_t pkt_pts = AV_NOPTS_VALUE; + uint8_t pic_type = 0; + + uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) == + VDEC_FLAG_BOTTOMFIELD; + uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST); + + int width = output->PicInfo.width; + int height = output->PicInfo.height; + int bwidth; + uint8_t *src = output->Ybuff; + int sStride; + uint8_t *dst; + int dStride; + + if (output->PicInfo.timeStamp != 0) { + OpaqueList *node = opaque_list_pop(priv, output->PicInfo.timeStamp); + if (node) { + pkt_pts = node->reordered_opaque; + pic_type = node->pic_type; + av_free(node); + } else { + /* + * We will encounter a situation where a timestamp cannot be + * popped if a second field is being returned. In this case, + * each field has the same timestamp and the first one will + * cause it to be popped. To keep subsequent calculations + * simple, pic_type should be set a FIELD value - doesn't + * matter which, but I chose BOTTOM. + */ + pic_type = PICT_BOTTOM_FIELD; + } + av_log(avctx, AV_LOG_VERBOSE, "output \"pts\": %"PRIu64"\n", + output->PicInfo.timeStamp); + av_log(avctx, AV_LOG_VERBOSE, "output picture type %d\n", + pic_type); + } + + ret = DtsGetDriverStatus(priv->dev, &decoder_status); + if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, + "CrystalHD: GetDriverStatus failed: %u\n", ret); + return RET_ERROR; + } + + /* + * For most content, we can trust the interlaced flag returned + * by the hardware, but sometimes we can't. These are the + * conditions under which we can trust the flag: + * + * 1) It's not h.264 content + * 2) The UNKNOWN_SRC flag is not set + * 3) We know we're expecting a second field + * 4) The hardware reports this picture and the next picture + * have the same picture number. + * + * Note that there can still be interlaced content that will + * fail this check, if the hardware hasn't decoded the next + * picture or if there is a corruption in the stream. (In either + * case a 0 will be returned for the next picture number) + */ + trust_interlaced = avctx->codec->id != CODEC_ID_H264 || + !(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) || + priv->need_second_field || + (decoder_status.picNumFlags & ~0x40000000) == + output->PicInfo.picture_number; + + /* + * If we got a false negative for trust_interlaced on the first field, + * we will realise our mistake here when we see that the picture number is that + * of the previous picture. We cannot recover the frame and should discard the + * second field to keep the correct number of output frames. + */ + if (output->PicInfo.picture_number == priv->last_picture && !priv->need_second_field) { + av_log(avctx, AV_LOG_WARNING, + "Incorrectly guessed progressive frame. Discarding second field\n"); + /* Returning without providing a picture. */ + return RET_OK; + } + + interlaced = (output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) && + trust_interlaced; + + if (!trust_interlaced && (decoder_status.picNumFlags & ~0x40000000) == 0) { + av_log(avctx, AV_LOG_VERBOSE, + "Next picture number unknown. Assuming progressive frame.\n"); + } + + av_log(avctx, AV_LOG_VERBOSE, "Interlaced state: %d | trust_interlaced %d\n", + interlaced, trust_interlaced); + + if (priv->pic.data[0] && !priv->need_second_field) + avctx->release_buffer(avctx, &priv->pic); + + priv->need_second_field = interlaced && !priv->need_second_field; + + priv->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | + FF_BUFFER_HINTS_REUSABLE; + if (!priv->pic.data[0]) { + if (avctx->get_buffer(avctx, &priv->pic) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return RET_ERROR; + } + } + + bwidth = av_image_get_linesize(avctx->pix_fmt, width, 0); + if (priv->is_70012) { + int pStride; + + if (width <= 720) + pStride = 720; + else if (width <= 1280) + pStride = 1280; + else if (width <= 1080) + pStride = 1080; + sStride = av_image_get_linesize(avctx->pix_fmt, pStride, 0); + } else { + sStride = bwidth; + } + + dStride = priv->pic.linesize[0]; + dst = priv->pic.data[0]; + + av_log(priv->avctx, AV_LOG_VERBOSE, "CrystalHD: Copying out frame\n"); + + if (interlaced) { + int dY = 0; + int sY = 0; + + height /= 2; + if (bottom_field) { + av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: bottom field\n"); + dY = 1; + } else { + av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: top field\n"); + dY = 0; + } + + for (sY = 0; sY < height; dY++, sY++) { + memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth); + dY++; + } + } else { + av_image_copy_plane(dst, dStride, src, sStride, bwidth, height); + } + + priv->pic.interlaced_frame = interlaced; + if (interlaced) + priv->pic.top_field_first = !bottom_first; + + priv->pic.pkt_pts = pkt_pts; + + if (!priv->need_second_field) { + *data_size = sizeof(AVFrame); + *(AVFrame *)data = priv->pic; + } + + /* + * Two types of PAFF content have been observed. One form causes the + * hardware to return a field pair and the other individual fields, + * even though the input is always individual fields. We must skip + * copying on the next decode() call to maintain pipeline length in + * the first case. + */ + if (!interlaced && (output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) && + (pic_type == PICT_TOP_FIELD || pic_type == PICT_BOTTOM_FIELD)) { + av_log(priv->avctx, AV_LOG_VERBOSE, "Fieldpair from two packets.\n"); + return RET_SKIP_NEXT_COPY; + } + + /* + * Testing has shown that in all cases where we don't want to return the + * full frame immediately, VDEC_FLAG_UNKNOWN_SRC is set. + */ + return priv->need_second_field && + !(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ? + RET_COPY_NEXT_FIELD : RET_OK; +} + + +static inline CopyRet receive_frame(AVCodecContext *avctx, + void *data, int *data_size) +{ + BC_STATUS ret; + BC_DTS_PROC_OUT output = { + .PicInfo.width = avctx->width, + .PicInfo.height = avctx->height, + }; + CHDContext *priv = avctx->priv_data; + HANDLE dev = priv->dev; + + *data_size = 0; + + // Request decoded data from the driver + ret = DtsProcOutputNoCopy(dev, OUTPUT_PROC_TIMEOUT, &output); + if (ret == BC_STS_FMT_CHANGE) { + av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Initial format change\n"); + avctx->width = output.PicInfo.width; + avctx->height = output.PicInfo.height; + return RET_COPY_AGAIN; + } else if (ret == BC_STS_SUCCESS) { + int copy_ret = -1; + if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) { + if (priv->last_picture == -1) { + /* + * Init to one less, so that the incrementing code doesn't + * need to be special-cased. + */ + priv->last_picture = output.PicInfo.picture_number - 1; + } + + if (avctx->codec->id == CODEC_ID_MPEG4 && + output.PicInfo.timeStamp == 0 && priv->bframe_bug) { + av_log(avctx, AV_LOG_VERBOSE, + "CrystalHD: Not returning packed frame twice.\n"); + priv->last_picture++; + DtsReleaseOutputBuffs(dev, NULL, FALSE); + return RET_COPY_AGAIN; + } + + print_frame_info(priv, &output); + + if (priv->last_picture + 1 < output.PicInfo.picture_number) { + av_log(avctx, AV_LOG_WARNING, + "CrystalHD: Picture Number discontinuity\n"); + /* + * Have we lost frames? If so, we need to shrink the + * pipeline length appropriately. + * + * XXX: I have no idea what the semantics of this situation + * are so I don't even know if we've lost frames or which + * ones. + * + * In any case, only warn the first time. + */ + priv->last_picture = output.PicInfo.picture_number - 1; + } + + copy_ret = copy_frame(avctx, &output, data, data_size); + if (*data_size > 0) { + avctx->has_b_frames--; + priv->last_picture++; + av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Pipeline length: %u\n", + avctx->has_b_frames); + } + } else { + /* + * An invalid frame has been consumed. + */ + av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput succeeded with " + "invalid PIB\n"); + avctx->has_b_frames--; + copy_ret = RET_OK; + } + DtsReleaseOutputBuffs(dev, NULL, FALSE); + + return copy_ret; + } else if (ret == BC_STS_BUSY) { + return RET_COPY_AGAIN; + } else { + av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput failed %d\n", ret); + return RET_ERROR; + } +} + + +static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) +{ + BC_STATUS ret; + BC_DTS_STATUS decoder_status = { 0, }; + CopyRet rec_ret; + CHDContext *priv = avctx->priv_data; + HANDLE dev = priv->dev; + uint8_t *in_data = avpkt->data; + int len = avpkt->size; + int free_data = 0; + uint8_t pic_type = 0; + + av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_frame\n"); + + if (avpkt->size == 7 && !priv->bframe_bug) { + /* + * The use of a drop frame triggers the bug + */ + av_log(avctx, AV_LOG_INFO, + "CrystalHD: Enabling work-around for packed b-frame bug\n"); + priv->bframe_bug = 1; + } else if (avpkt->size == 8 && priv->bframe_bug) { + /* + * Delay frames don't trigger the bug + */ + av_log(avctx, AV_LOG_INFO, + "CrystalHD: Disabling work-around for packed b-frame bug\n"); + priv->bframe_bug = 0; + } + + if (len) { + int32_t tx_free = (int32_t)DtsTxFreeSize(dev); + + if (priv->parser) { + int ret = 0; + + if (priv->bsfc) { + ret = av_bitstream_filter_filter(priv->bsfc, avctx, NULL, + &in_data, &len, + avpkt->data, len, 0); + } + free_data = ret > 0; + + if (ret >= 0) { + uint8_t *pout; + int psize; + int index; + H264Context *h = priv->parser->priv_data; + + index = av_parser_parse2(priv->parser, avctx, &pout, &psize, + in_data, len, avctx->pkt->pts, + avctx->pkt->dts, 0); + if (index < 0) { + av_log(avctx, AV_LOG_WARNING, + "CrystalHD: Failed to parse h.264 packet to " + "detect interlacing.\n"); + } else if (index != len) { + av_log(avctx, AV_LOG_WARNING, + "CrystalHD: Failed to parse h.264 packet " + "completely. Interlaced frames may be " + "incorrectly detected\n."); + } else { + av_log(avctx, AV_LOG_VERBOSE, + "CrystalHD: parser picture type %d\n", + h->s.picture_structure); + pic_type = h->s.picture_structure; + } + } else { + av_log(avctx, AV_LOG_WARNING, + "CrystalHD: mp4toannexb filter failed to filter " + "packet. Interlaced frames may be incorrectly " + "detected.\n"); + } + } + + if (len < tx_free - 1024) { + /* + * Despite being notionally opaque, either libcrystalhd or + * the hardware itself will mangle pts values that are too + * small or too large. The docs claim it should be in units + * of 100ns. Given that we're nominally dealing with a black + * box on both sides, any transform we do has no guarantee of + * avoiding mangling so we need to build a mapping to values + * we know will not be mangled. + */ + uint64_t pts = opaque_list_push(priv, avctx->pkt->pts, pic_type); + if (!pts) { + if (free_data) { + av_freep(&in_data); + } + return AVERROR(ENOMEM); + } + av_log(priv->avctx, AV_LOG_VERBOSE, + "input \"pts\": %"PRIu64"\n", pts); + ret = DtsProcInput(dev, in_data, len, pts, 0); + if (free_data) { + av_freep(&in_data); + } + if (ret == BC_STS_BUSY) { + av_log(avctx, AV_LOG_WARNING, + "CrystalHD: ProcInput returned busy\n"); + usleep(BASE_WAIT); + return AVERROR(EBUSY); + } else if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, + "CrystalHD: ProcInput failed: %u\n", ret); + return -1; + } + avctx->has_b_frames++; + } else { + av_log(avctx, AV_LOG_WARNING, "CrystalHD: Input buffer full\n"); + len = 0; // We didn't consume any bytes. + } + } else { + av_log(avctx, AV_LOG_INFO, "CrystalHD: No more input data\n"); + } + + if (priv->skip_next_output) { + av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Skipping next output.\n"); + priv->skip_next_output = 0; + avctx->has_b_frames--; + return len; + } + + ret = DtsGetDriverStatus(dev, &decoder_status); + if (ret != BC_STS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "CrystalHD: GetDriverStatus failed\n"); + return -1; + } + + /* + * No frames ready. Don't try to extract. + * + * Empirical testing shows that ReadyListCount can be a damn lie, + * and ProcOut still fails when count > 0. The same testing showed + * that two more iterations were needed before ProcOutput would + * succeed. + */ + if (priv->output_ready < 2) { + if (decoder_status.ReadyListCount != 0) + priv->output_ready++; + usleep(BASE_WAIT); + av_log(avctx, AV_LOG_INFO, "CrystalHD: Filling pipeline.\n"); + return len; + } else if (decoder_status.ReadyListCount == 0) { + /* + * After the pipeline is established, if we encounter a lack of frames + * that probably means we're not giving the hardware enough time to + * decode them, so start increasing the wait time at the end of a + * decode call. + */ + usleep(BASE_WAIT); + priv->decode_wait += WAIT_UNIT; + av_log(avctx, AV_LOG_INFO, "CrystalHD: No frames ready. Returning\n"); + return len; + } + + do { + rec_ret = receive_frame(avctx, data, data_size); + if (rec_ret == RET_OK && *data_size == 0) { + /* + * This case is for when the encoded fields are stored + * separately and we get a separate avpkt for each one. To keep + * the pipeline stable, we should return nothing and wait for + * the next time round to grab the second field. + * H.264 PAFF is an example of this. + */ + av_log(avctx, AV_LOG_VERBOSE, "Returning after first field.\n"); + avctx->has_b_frames--; + } else if (rec_ret == RET_COPY_NEXT_FIELD) { + /* + * This case is for when the encoded fields are stored in a + * single avpkt but the hardware returns then separately. Unless + * we grab the second field before returning, we'll slip another + * frame in the pipeline and if that happens a lot, we're sunk. + * So we have to get that second field now. + * Interlaced mpeg2 and vc1 are examples of this. + */ + av_log(avctx, AV_LOG_VERBOSE, "Trying to get second field.\n"); + while (1) { + usleep(priv->decode_wait); + ret = DtsGetDriverStatus(dev, &decoder_status); + if (ret == BC_STS_SUCCESS && + decoder_status.ReadyListCount > 0) { + rec_ret = receive_frame(avctx, data, data_size); + if ((rec_ret == RET_OK && *data_size > 0) || + rec_ret == RET_ERROR) + break; + } + } + av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Got second field.\n"); + } else if (rec_ret == RET_SKIP_NEXT_COPY) { + /* + * Two input packets got turned into a field pair. Gawd. + */ + av_log(avctx, AV_LOG_VERBOSE, + "Don't output on next decode call.\n"); + priv->skip_next_output = 1; + } + /* + * If rec_ret == RET_COPY_AGAIN, that means that either we just handled + * a FMT_CHANGE event and need to go around again for the actual frame, + * we got a busy status and need to try again, or we're dealing with + * packed b-frames, where the hardware strangely returns the packed + * p-frame twice. We choose to keep the second copy as it carries the + * valid pts. + */ + } while (rec_ret == RET_COPY_AGAIN); + usleep(priv->decode_wait); + return len; +} + + +#if CONFIG_H264_CRYSTALHD_DECODER +static AVClass h264_class = { + "h264_crystalhd", + av_default_item_name, + options, + LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_h264_crystalhd_decoder = { + .name = "h264_crystalhd", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_H264, + .priv_data_size = sizeof(CHDContext), + .init = init, + .close = uninit, + .decode = decode, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, + .flush = flush, + .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"), + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, + .priv_class = &h264_class, +}; +#endif + +#if CONFIG_MPEG2_CRYSTALHD_DECODER +static AVClass mpeg2_class = { + "mpeg2_crystalhd", + av_default_item_name, + options, + LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_mpeg2_crystalhd_decoder = { + .name = "mpeg2_crystalhd", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG2VIDEO, + .priv_data_size = sizeof(CHDContext), + .init = init, + .close = uninit, + .decode = decode, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, + .flush = flush, + .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 Video (CrystalHD acceleration)"), + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, + .priv_class = &mpeg2_class, +}; +#endif + +#if CONFIG_MPEG4_CRYSTALHD_DECODER +static AVClass mpeg4_class = { + "mpeg4_crystalhd", + av_default_item_name, + options, + LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_mpeg4_crystalhd_decoder = { + .name = "mpeg4_crystalhd", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG4, + .priv_data_size = sizeof(CHDContext), + .init = init, + .close = uninit, + .decode = decode, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, + .flush = flush, + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 (CrystalHD acceleration)"), + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, + .priv_class = &mpeg4_class, +}; +#endif + +#if CONFIG_MSMPEG4_CRYSTALHD_DECODER +static AVClass msmpeg4_class = { + "msmpeg4_crystalhd", + av_default_item_name, + options, + LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_msmpeg4_crystalhd_decoder = { + .name = "msmpeg4_crystalhd", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MSMPEG4V3, + .priv_data_size = sizeof(CHDContext), + .init = init, + .close = uninit, + .decode = decode, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, + .flush = flush, + .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"), + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, + .priv_class = &msmpeg4_class, +}; +#endif + +#if CONFIG_VC1_CRYSTALHD_DECODER +static AVClass vc1_class = { + "vc1_crystalhd", + av_default_item_name, + options, + LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_vc1_crystalhd_decoder = { + .name = "vc1_crystalhd", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_VC1, + .priv_data_size = sizeof(CHDContext), + .init = init, + .close = uninit, + .decode = decode, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, + .flush = flush, + .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 (CrystalHD acceleration)"), + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, + .priv_class = &vc1_class, +}; +#endif + +#if CONFIG_WMV3_CRYSTALHD_DECODER +static AVClass wmv3_class = { + "wmv3_crystalhd", + av_default_item_name, + options, + LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_wmv3_crystalhd_decoder = { + .name = "wmv3_crystalhd", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_WMV3, + .priv_data_size = sizeof(CHDContext), + .init = init, + .close = uninit, + .decode = decode, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL, + .flush = flush, + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 (CrystalHD acceleration)"), + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, + .priv_class = &wmv3_class, +}; +#endif diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c index 43f0e5e7d5..4f9b70c88b 100644 --- a/libavcodec/cscd.c +++ b/libavcodec/cscd.c @@ -2,20 +2,20 @@ * CamStudio decoder * Copyright (c) 2006 Reimar Doeffinger * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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> @@ -149,7 +149,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); - c->pic.reference = 1; + c->pic.reference = 3; 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) { @@ -231,6 +231,7 @@ static av_cold int decode_init(AVCodecContext *avctx) { return 1; } c->bpp = avctx->bits_per_coded_sample; + avcodec_get_frame_defaults(&c->pic); c->pic.data[0] = NULL; c->linelen = avctx->width * avctx->bits_per_coded_sample / 8; c->height = avctx->height; diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c index 60cce82fee..2df6087ae0 100644 --- a/libavcodec/cyuv.c +++ b/libavcodec/cyuv.c @@ -6,20 +6,20 @@ * * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -53,6 +53,7 @@ static av_cold int cyuv_decode_init(AVCodecContext *avctx) return -1; s->height = avctx->height; avctx->pix_fmt = PIX_FMT_YUV411P; + avcodec_get_frame_defaults(&s->frame); return 0; } diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 3735b5a7fd..cf61a16bb9 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -5,20 +5,20 @@ * Copyright (C) 2006 Benjamin Larsson * Copyright (C) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -313,7 +313,6 @@ typedef struct { /* Primary audio coding header */ int subframes; ///< number of subframes - int is_channels_set; ///< check for if the channel number is already set int total_channels; ///< number of channels including extensions int prim_channels; ///< number of primary audio channels int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count @@ -1440,11 +1439,11 @@ static int dca_exss_parse_asset_header(DCAContext *s) { int header_pos = get_bits_count(&s->gb); int header_size; - int channels; + int channels = 0; int embedded_stereo = 0; int embedded_6ch = 0; int drc_code_present; - int extensions_mask; + int av_uninit(extensions_mask); int i, j; if (get_bits_left(&s->gb) < 16) @@ -1850,25 +1849,19 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, s->output = DCA_STEREO; avctx->channel_layout = AV_CH_LAYOUT_STEREO; } + else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) { + static const int8_t dca_channel_order_native[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + s->channel_order_tab = dca_channel_order_native; + } } else { av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode); return AVERROR_INVALIDDATA; } - - /* There is nothing that prevents a dts frame to change channel configuration - but Libav doesn't support that so only set the channels if it is previously - unset. Ideally during the first probe for channels the crc should be checked - and only set avctx->channels when the crc is ok. Right now the decoder could - set the channels based on a broken first frame.*/ - if (s->is_channels_set == 0) { - s->is_channels_set = 1; - avctx->channels = channels; - } if (avctx->channels != channels) { - av_log(avctx, AV_LOG_ERROR, "DCA decoder does not support number of " - "channels changing in stream. Skipping frame.\n"); - return AVERROR_PATCHWELCOME; + if (avctx->channels) + av_log(avctx, AV_LOG_INFO, "Number of channels changed in DCA decoder (%d -> %d)\n", avctx->channels, channels); + avctx->channels = channels; } /* get output buffer */ diff --git a/libavcodec/dca.h b/libavcodec/dca.h index 8ea6049e0d..02c0a51ea8 100644 --- a/libavcodec/dca.h +++ b/libavcodec/dca.h @@ -5,20 +5,20 @@ * Copyright (C) 2006 Benjamin Larsson * Copyright (C) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dca_parser.c b/libavcodec/dca_parser.c index 136cc458ef..0c8ea8a07f 100644 --- a/libavcodec/dca_parser.c +++ b/libavcodec/dca_parser.c @@ -5,20 +5,20 @@ * Copyright (C) 2006 Benjamin Larsson * Copyright (C) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +36,7 @@ typedef struct 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) + || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE || state == DCA_HD_MARKER) /** * Find the end of the current frame in the bitstream. @@ -57,10 +57,7 @@ static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, 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) { + if (!pc1->lastmarker || state == pc1->lastmarker || pc1->lastmarker == DCA_HD_MARKER) { start_found = 1; pc1->lastmarker = state; break; @@ -74,10 +71,11 @@ static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf, state = (state << 8) | buf[i]; if (state == DCA_HD_MARKER && !pc1->hd_pos) pc1->hd_pos = pc1->size; - if (state == pc1->lastmarker && IS_MARKER(state, i, buf, buf_size)) { + if (IS_MARKER(state, i, buf, buf_size) && (state == pc1->lastmarker || pc1->lastmarker == DCA_HD_MARKER)) { if(pc1->framesize > pc1->size) continue; - if(!pc1->framesize){ + // We have to check that we really read a full frame here, and that it isn't a pure HD frame, because their size is not constant. + if(!pc1->framesize && state == pc1->lastmarker && state != DCA_HD_MARKER){ pc1->framesize = pc1->hd_pos ? pc1->hd_pos : pc1->size; } pc->frame_start_found = 0; diff --git a/libavcodec/dcadata.h b/libavcodec/dcadata.h index 0a83cdfae7..02dbb0fe54 100644 --- a/libavcodec/dcadata.h +++ b/libavcodec/dcadata.h @@ -3,20 +3,20 @@ * Copyright (C) 2004 Gildas Bazin * Copyright (c) 2006 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dcadsp.c b/libavcodec/dcadsp.c index 14932e6786..dd4994d276 100644 --- a/libavcodec/dcadsp.c +++ b/libavcodec/dcadsp.c @@ -2,20 +2,20 @@ * Copyright (c) 2004 Gildas Bazin * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dcadsp.h b/libavcodec/dcadsp.h index 3c6f1f9a9f..bb157f7650 100644 --- a/libavcodec/dcadsp.h +++ b/libavcodec/dcadsp.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dcaenc.c b/libavcodec/dcaenc.c new file mode 100644 index 0000000000..72ea16f6d5 --- /dev/null +++ b/libavcodec/dcaenc.c @@ -0,0 +1,587 @@ +/* + * DCA encoder + * Copyright (C) 2008 Alexander E. Patrakov + * 2010 Benjamin Larsson + * 2011 Xiang Wang + * + * 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 "libavutil/common.h" +#include "libavutil/avassert.h" +#include "libavutil/audioconvert.h" +#include "avcodec.h" +#include "get_bits.h" +#include "put_bits.h" +#include "dcaenc.h" +#include "dcadata.h" + +#undef NDEBUG + +#define MAX_CHANNELS 6 +#define DCA_SUBBANDS_32 32 +#define DCA_MAX_FRAME_SIZE 16383 +#define DCA_HEADER_SIZE 13 + +#define DCA_SUBBANDS 32 ///< Subband activity count +#define QUANTIZER_BITS 16 +#define SUBFRAMES 1 +#define SUBSUBFRAMES 4 +#define PCM_SAMPLES (SUBFRAMES*SUBSUBFRAMES*8) +#define LFE_BITS 8 +#define LFE_INTERPOLATION 64 +#define LFE_PRESENT 2 +#define LFE_MISSING 0 + +static const int8_t dca_lfe_index[] = { + 1,2,2,2,2,3,2,3,2,3,2,3,1,3,2,3 +}; + +static const int8_t dca_channel_reorder_lfe[][9] = { + { 0, -1, -1, -1, -1, -1, -1, -1, -1 }, + { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, + { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, + { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, + { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, + { 1, 2, 0, -1, -1, -1, -1, -1, -1 }, + { 0, 1, -1, 2, -1, -1, -1, -1, -1 }, + { 1, 2, 0, -1, 3, -1, -1, -1, -1 }, + { 0, 1, -1, 2, 3, -1, -1, -1, -1 }, + { 1, 2, 0, -1, 3, 4, -1, -1, -1 }, + { 2, 3, -1, 0, 1, 4, 5, -1, -1 }, + { 1, 2, 0, -1, 3, 4, 5, -1, -1 }, + { 0, -1, 4, 5, 2, 3, 1, -1, -1 }, + { 3, 4, 1, -1, 0, 2, 5, 6, -1 }, + { 2, 3, -1, 5, 7, 0, 1, 4, 6 }, + { 3, 4, 1, -1, 0, 2, 5, 7, 6 }, +}; + +static const int8_t dca_channel_reorder_nolfe[][9] = { + { 0, -1, -1, -1, -1, -1, -1, -1, -1 }, + { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, + { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, + { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, + { 0, 1, -1, -1, -1, -1, -1, -1, -1 }, + { 1, 2, 0, -1, -1, -1, -1, -1, -1 }, + { 0, 1, 2, -1, -1, -1, -1, -1, -1 }, + { 1, 2, 0, 3, -1, -1, -1, -1, -1 }, + { 0, 1, 2, 3, -1, -1, -1, -1, -1 }, + { 1, 2, 0, 3, 4, -1, -1, -1, -1 }, + { 2, 3, 0, 1, 4, 5, -1, -1, -1 }, + { 1, 2, 0, 3, 4, 5, -1, -1, -1 }, + { 0, 4, 5, 2, 3, 1, -1, -1, -1 }, + { 3, 4, 1, 0, 2, 5, 6, -1, -1 }, + { 2, 3, 5, 7, 0, 1, 4, 6, -1 }, + { 3, 4, 1, 0, 2, 5, 7, 6, -1 }, +}; + +typedef struct { + PutBitContext pb; + int32_t history[MAX_CHANNELS][512]; /* This is a circular buffer */ + int start[MAX_CHANNELS]; + int frame_size; + int prim_channels; + int lfe_channel; + int sample_rate_code; + int scale_factor[MAX_CHANNELS][DCA_SUBBANDS_32]; + int lfe_scale_factor; + int lfe_data[SUBFRAMES*SUBSUBFRAMES*4]; + + int a_mode; ///< audio channels arrangement + int num_channel; + int lfe_state; + int lfe_offset; + const int8_t *channel_order_tab; ///< channel reordering table, lfe and non lfe + + int32_t pcm[FFMAX(LFE_INTERPOLATION, DCA_SUBBANDS_32)]; + int32_t subband[PCM_SAMPLES][MAX_CHANNELS][DCA_SUBBANDS_32]; /* [sample][channel][subband] */ +} DCAContext; + +static int32_t cos_table[128]; + +static inline int32_t mul32(int32_t a, int32_t b) +{ + int64_t r = (int64_t) a * b; + /* round the result before truncating - improves accuracy */ + return (r + 0x80000000) >> 32; +} + +/* Integer version of the cosine modulated Pseudo QMF */ + +static void qmf_init(void) +{ + int i; + int32_t c[17], s[17]; + s[0] = 0; /* sin(index * PI / 64) * 0x7fffffff */ + c[0] = 0x7fffffff; /* cos(index * PI / 64) * 0x7fffffff */ + + for (i = 1; i <= 16; i++) { + s[i] = 2 * (mul32(c[i - 1], 105372028) + mul32(s[i - 1], 2144896908)); + c[i] = 2 * (mul32(c[i - 1], 2144896908) - mul32(s[i - 1], 105372028)); + } + + for (i = 0; i < 16; i++) { + cos_table[i ] = c[i] >> 3; /* avoid output overflow */ + cos_table[i + 16] = s[16 - i] >> 3; + cos_table[i + 32] = -s[i] >> 3; + cos_table[i + 48] = -c[16 - i] >> 3; + cos_table[i + 64] = -c[i] >> 3; + cos_table[i + 80] = -s[16 - i] >> 3; + cos_table[i + 96] = s[i] >> 3; + cos_table[i + 112] = c[16 - i] >> 3; + } +} + +static int32_t band_delta_factor(int band, int sample_num) +{ + int index = band * (2 * sample_num + 1); + if (band == 0) + return 0x07ffffff; + else + return cos_table[index & 127]; +} + +static void add_new_samples(DCAContext *c, const int32_t *in, + int count, int channel) +{ + int i; + + /* Place new samples into the history buffer */ + for (i = 0; i < count; i++) { + c->history[channel][c->start[channel] + i] = in[i]; + av_assert0(c->start[channel] + i < 512); + } + c->start[channel] += count; + if (c->start[channel] == 512) + c->start[channel] = 0; + av_assert0(c->start[channel] < 512); +} + +static void qmf_decompose(DCAContext *c, int32_t in[32], int32_t out[32], + int channel) +{ + int band, i, j, k; + int32_t resp; + int32_t accum[DCA_SUBBANDS_32] = {0}; + + add_new_samples(c, in, DCA_SUBBANDS_32, channel); + + /* Calculate the dot product of the signal with the (possibly inverted) + reference decoder's response to this vector: + (0.0, 0.0, ..., 0.0, -1.0, 1.0, 0.0, ..., 0.0) + so that -1.0 cancels 1.0 from the previous step */ + + for (k = 48, j = 0, i = c->start[channel]; i < 512; k++, j++, i++) + accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]); + for (i = 0; i < c->start[channel]; k++, j++, i++) + accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]); + + resp = 0; + /* TODO: implement FFT instead of this naive calculation */ + for (band = 0; band < DCA_SUBBANDS_32; band++) { + for (j = 0; j < 32; j++) + resp += mul32(accum[j], band_delta_factor(band, j)); + + out[band] = (band & 2) ? (-resp) : resp; + } +} + +static int32_t lfe_fir_64i[512]; +static int lfe_downsample(DCAContext *c, int32_t in[LFE_INTERPOLATION]) +{ + int i, j; + int channel = c->prim_channels; + int32_t accum = 0; + + add_new_samples(c, in, LFE_INTERPOLATION, channel); + for (i = c->start[channel], j = 0; i < 512; i++, j++) + accum += mul32(c->history[channel][i], lfe_fir_64i[j]); + for (i = 0; i < c->start[channel]; i++, j++) + accum += mul32(c->history[channel][i], lfe_fir_64i[j]); + return accum; +} + +static void init_lfe_fir(void) +{ + static int initialized = 0; + int i; + if (initialized) + return; + + for (i = 0; i < 512; i++) + lfe_fir_64i[i] = lfe_fir_64[i] * (1 << 25); //float -> int32_t + initialized = 1; +} + +static void put_frame_header(DCAContext *c) +{ + /* SYNC */ + put_bits(&c->pb, 16, 0x7ffe); + put_bits(&c->pb, 16, 0x8001); + + /* Frame type: normal */ + put_bits(&c->pb, 1, 1); + + /* Deficit sample count: none */ + put_bits(&c->pb, 5, 31); + + /* CRC is not present */ + put_bits(&c->pb, 1, 0); + + /* Number of PCM sample blocks */ + put_bits(&c->pb, 7, PCM_SAMPLES-1); + + /* Primary frame byte size */ + put_bits(&c->pb, 14, c->frame_size-1); + + /* Audio channel arrangement: L + R (stereo) */ + put_bits(&c->pb, 6, c->num_channel); + + /* Core audio sampling frequency */ + put_bits(&c->pb, 4, c->sample_rate_code); + + /* Transmission bit rate: 1411.2 kbps */ + put_bits(&c->pb, 5, 0x16); /* FIXME: magic number */ + + /* Embedded down mix: disabled */ + put_bits(&c->pb, 1, 0); + + /* Embedded dynamic range flag: not present */ + put_bits(&c->pb, 1, 0); + + /* Embedded time stamp flag: not present */ + put_bits(&c->pb, 1, 0); + + /* Auxiliary data flag: not present */ + put_bits(&c->pb, 1, 0); + + /* HDCD source: no */ + put_bits(&c->pb, 1, 0); + + /* Extension audio ID: N/A */ + put_bits(&c->pb, 3, 0); + + /* Extended audio data: not present */ + put_bits(&c->pb, 1, 0); + + /* Audio sync word insertion flag: after each sub-frame */ + put_bits(&c->pb, 1, 0); + + /* Low frequency effects flag: not present or interpolation factor=64 */ + put_bits(&c->pb, 2, c->lfe_state); + + /* Predictor history switch flag: on */ + put_bits(&c->pb, 1, 1); + + /* No CRC */ + /* Multirate interpolator switch: non-perfect reconstruction */ + put_bits(&c->pb, 1, 0); + + /* Encoder software revision: 7 */ + put_bits(&c->pb, 4, 7); + + /* Copy history: 0 */ + put_bits(&c->pb, 2, 0); + + /* Source PCM resolution: 16 bits, not DTS ES */ + put_bits(&c->pb, 3, 0); + + /* Front sum/difference coding: no */ + put_bits(&c->pb, 1, 0); + + /* Surrounds sum/difference coding: no */ + put_bits(&c->pb, 1, 0); + + /* Dialog normalization: 0 dB */ + put_bits(&c->pb, 4, 0); +} + +static void put_primary_audio_header(DCAContext *c) +{ + static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }; + static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 }; + + int ch, i; + /* Number of subframes */ + put_bits(&c->pb, 4, SUBFRAMES - 1); + + /* Number of primary audio channels */ + put_bits(&c->pb, 3, c->prim_channels - 1); + + /* Subband activity count */ + for (ch = 0; ch < c->prim_channels; ch++) + put_bits(&c->pb, 5, DCA_SUBBANDS - 2); + + /* High frequency VQ start subband */ + for (ch = 0; ch < c->prim_channels; ch++) + put_bits(&c->pb, 5, DCA_SUBBANDS - 1); + + /* Joint intensity coding index: 0, 0 */ + for (ch = 0; ch < c->prim_channels; ch++) + put_bits(&c->pb, 3, 0); + + /* Transient mode codebook: A4, A4 (arbitrary) */ + for (ch = 0; ch < c->prim_channels; ch++) + put_bits(&c->pb, 2, 0); + + /* Scale factor code book: 7 bit linear, 7-bit sqrt table (for each channel) */ + for (ch = 0; ch < c->prim_channels; ch++) + put_bits(&c->pb, 3, 6); + + /* Bit allocation quantizer select: linear 5-bit */ + for (ch = 0; ch < c->prim_channels; ch++) + put_bits(&c->pb, 3, 6); + + /* Quantization index codebook select: dummy data + to avoid transmission of scale factor adjustment */ + + for (i = 1; i < 11; i++) + for (ch = 0; ch < c->prim_channels; ch++) + put_bits(&c->pb, bitlen[i], thr[i]); + + /* Scale factor adjustment index: not transmitted */ +} + +/** + * 8-23 bits quantization + * @param sample + * @param bits + */ +static inline uint32_t quantize(int32_t sample, int bits) +{ + av_assert0(sample < 1 << (bits - 1)); + av_assert0(sample >= -(1 << (bits - 1))); + return sample & ((1 << bits) - 1); +} + +static inline int find_scale_factor7(int64_t max_value, int bits) +{ + int i = 0, j = 128, q; + max_value = ((max_value << 15) / lossy_quant[bits + 3]) >> (bits - 1); + while (i < j) { + q = (i + j) >> 1; + if (max_value < scale_factor_quant7[q]) + j = q; + else + i = q + 1; + } + av_assert1(i < 128); + return i; +} + +static inline void put_sample7(DCAContext *c, int64_t sample, int bits, + int scale_factor) +{ + sample = (sample << 15) / ((int64_t) lossy_quant[bits + 3] * scale_factor_quant7[scale_factor]); + put_bits(&c->pb, bits, quantize((int) sample, bits)); +} + +static void put_subframe(DCAContext *c, + int32_t subband_data[8 * SUBSUBFRAMES][MAX_CHANNELS][32], + int subframe) +{ + int i, sub, ss, ch, max_value; + int32_t *lfe_data = c->lfe_data + 4 * SUBSUBFRAMES * subframe; + + /* Subsubframes count */ + put_bits(&c->pb, 2, SUBSUBFRAMES -1); + + /* Partial subsubframe sample count: dummy */ + put_bits(&c->pb, 3, 0); + + /* Prediction mode: no ADPCM, in each channel and subband */ + for (ch = 0; ch < c->prim_channels; ch++) + for (sub = 0; sub < DCA_SUBBANDS; sub++) + put_bits(&c->pb, 1, 0); + + /* Prediction VQ addres: not transmitted */ + /* Bit allocation index */ + for (ch = 0; ch < c->prim_channels; ch++) + for (sub = 0; sub < DCA_SUBBANDS; sub++) + put_bits(&c->pb, 5, QUANTIZER_BITS+3); + + if (SUBSUBFRAMES > 1) { + /* Transition mode: none for each channel and subband */ + for (ch = 0; ch < c->prim_channels; ch++) + for (sub = 0; sub < DCA_SUBBANDS; sub++) + put_bits(&c->pb, 1, 0); /* codebook A4 */ + } + + /* Determine scale_factor */ + for (ch = 0; ch < c->prim_channels; ch++) + for (sub = 0; sub < DCA_SUBBANDS; sub++) { + max_value = 0; + for (i = 0; i < 8 * SUBSUBFRAMES; i++) + max_value = FFMAX(max_value, FFABS(subband_data[i][ch][sub])); + c->scale_factor[ch][sub] = find_scale_factor7(max_value, QUANTIZER_BITS); + } + + if (c->lfe_channel) { + max_value = 0; + for (i = 0; i < 4 * SUBSUBFRAMES; i++) + max_value = FFMAX(max_value, FFABS(lfe_data[i])); + c->lfe_scale_factor = find_scale_factor7(max_value, LFE_BITS); + } + + /* Scale factors: the same for each channel and subband, + encoded according to Table D.1.2 */ + for (ch = 0; ch < c->prim_channels; ch++) + for (sub = 0; sub < DCA_SUBBANDS; sub++) + put_bits(&c->pb, 7, c->scale_factor[ch][sub]); + + /* Joint subband scale factor codebook select: not transmitted */ + /* Scale factors for joint subband coding: not transmitted */ + /* Stereo down-mix coefficients: not transmitted */ + /* Dynamic range coefficient: not transmitted */ + /* Stde information CRC check word: not transmitted */ + /* VQ encoded high frequency subbands: not transmitted */ + + /* LFE data */ + if (c->lfe_channel) { + for (i = 0; i < 4 * SUBSUBFRAMES; i++) + put_sample7(c, lfe_data[i], LFE_BITS, c->lfe_scale_factor); + put_bits(&c->pb, 8, c->lfe_scale_factor); + } + + /* Audio data (subsubframes) */ + + for (ss = 0; ss < SUBSUBFRAMES ; ss++) + for (ch = 0; ch < c->prim_channels; ch++) + for (sub = 0; sub < DCA_SUBBANDS; sub++) + for (i = 0; i < 8; i++) + put_sample7(c, subband_data[ss * 8 + i][ch][sub], QUANTIZER_BITS, c->scale_factor[ch][sub]); + + /* DSYNC */ + put_bits(&c->pb, 16, 0xffff); +} + +static void put_frame(DCAContext *c, + int32_t subband_data[PCM_SAMPLES][MAX_CHANNELS][32], + uint8_t *frame) +{ + int i; + init_put_bits(&c->pb, frame + DCA_HEADER_SIZE, DCA_MAX_FRAME_SIZE-DCA_HEADER_SIZE); + + put_primary_audio_header(c); + for (i = 0; i < SUBFRAMES; i++) + put_subframe(c, &subband_data[SUBSUBFRAMES * 8 * i], i); + + flush_put_bits(&c->pb); + c->frame_size = (put_bits_count(&c->pb) >> 3) + DCA_HEADER_SIZE; + + init_put_bits(&c->pb, frame, DCA_HEADER_SIZE); + put_frame_header(c); + flush_put_bits(&c->pb); +} + +static int encode_frame(AVCodecContext *avctx, uint8_t *frame, + int buf_size, void *data) +{ + int i, k, channel; + DCAContext *c = avctx->priv_data; + int16_t *samples = data; + int real_channel = 0; + + for (i = 0; i < PCM_SAMPLES; i ++) { /* i is the decimated sample number */ + for (channel = 0; channel < c->prim_channels + 1; channel++) { + /* Get 32 PCM samples */ + for (k = 0; k < 32; k++) { /* k is the sample number in a 32-sample block */ + c->pcm[k] = samples[avctx->channels * (32 * i + k) + channel] << 16; + } + /* Put subband samples into the proper place */ + real_channel = c->channel_order_tab[channel]; + if (real_channel >= 0) { + qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel); + } + } + } + + if (c->lfe_channel) { + for (i = 0; i < PCM_SAMPLES / 2; i++) { + for (k = 0; k < LFE_INTERPOLATION; k++) /* k is the sample number in a 32-sample block */ + c->pcm[k] = samples[avctx->channels * (LFE_INTERPOLATION*i+k) + c->lfe_offset] << 16; + c->lfe_data[i] = lfe_downsample(c, c->pcm); + } + } + + put_frame(c, c->subband, frame); + + return c->frame_size; +} + +static int encode_init(AVCodecContext *avctx) +{ + DCAContext *c = avctx->priv_data; + int i; + + c->prim_channels = avctx->channels; + c->lfe_channel = (avctx->channels == 3 || avctx->channels == 6); + + switch (avctx->channel_layout) { + case AV_CH_LAYOUT_STEREO: c->a_mode = 2; c->num_channel = 2; break; + case AV_CH_LAYOUT_5POINT0: c->a_mode = 9; c->num_channel = 9; break; + case AV_CH_LAYOUT_5POINT1: c->a_mode = 9; c->num_channel = 9; break; + case AV_CH_LAYOUT_5POINT0_BACK: c->a_mode = 9; c->num_channel = 9; break; + case AV_CH_LAYOUT_5POINT1_BACK: c->a_mode = 9; c->num_channel = 9; break; + default: + av_log(avctx, AV_LOG_ERROR, + "Only stereo, 5.0, 5.1 channel layouts supported at the moment!\n"); + return AVERROR_PATCHWELCOME; + } + + if (c->lfe_channel) { + init_lfe_fir(); + c->prim_channels--; + c->channel_order_tab = dca_channel_reorder_lfe[c->a_mode]; + c->lfe_state = LFE_PRESENT; + c->lfe_offset = dca_lfe_index[c->a_mode]; + } else { + c->channel_order_tab = dca_channel_reorder_nolfe[c->a_mode]; + c->lfe_state = LFE_MISSING; + } + + for (i = 0; i < 16; i++) { + if (dca_sample_rates[i] && (dca_sample_rates[i] == avctx->sample_rate)) + break; + } + if (i == 16) { + av_log(avctx, AV_LOG_ERROR, "Sample rate %iHz not supported, only ", avctx->sample_rate); + for (i = 0; i < 16; i++) + av_log(avctx, AV_LOG_ERROR, "%d, ", dca_sample_rates[i]); + av_log(avctx, AV_LOG_ERROR, "supported.\n"); + return -1; + } + c->sample_rate_code = i; + + avctx->frame_size = 32 * PCM_SAMPLES; + + if (!cos_table[127]) + qmf_init(); + return 0; +} + +AVCodec ff_dca_encoder = { + .name = "dca", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_DTS, + .priv_data_size = sizeof(DCAContext), + .init = encode_init, + .encode = encode_frame, + .capabilities = CODEC_CAP_EXPERIMENTAL, + .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), +}; diff --git a/libavcodec/dcaenc.h b/libavcodec/dcaenc.h new file mode 100644 index 0000000000..63d03dc449 --- /dev/null +++ b/libavcodec/dcaenc.h @@ -0,0 +1,544 @@ +/* + * DCA encoder tables + * Copyright (C) 2008 Alexander E. Patrakov + * + * 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 AVCODEC_DCAENC_H +#define AVCODEC_DCAENC_H + +/* This is a scaled version of the response of the reference decoder to + this vector of subband samples: ( 1.0 0.0 0.0 ... 0.0 ) + */ + +static const int32_t UnQMF[512] = { + 7, + 4, + -961, + -2844, + -8024, + -18978, + -32081, + -15635, + -16582, + -18359, + -17180, + -14868, + -11664, + -8051, + -4477, + -1327, + -1670, + -6019, + -11590, + -18030, + -24762, + -30965, + -35947, + -36145, + -37223, + -86311, + -57024, + -27215, + -11274, + -4684, + 42, + 108, + 188, + 250, + -1007, + -596, + -2289, + -12218, + -27191, + -124367, + -184256, + -250538, + -323499, + -397784, + -468855, + -532072, + -583000, + -618041, + -777916, + -783868, + -765968, + -724740, + -662468, + -583058, + -490548, + -401623, + -296090, + -73154, + -36711, + -7766, + -2363, + -4905, + 2388, + 2681, + 5651, + 4086, + 71110, + 139742, + 188067, + 151237, + 101355, + 309917, + 343690, + 358839, + 357555, + 334606, + 289625, + 224152, + 142063, + 48725, + 74996, + 238425, + 411666, + 584160, + 744276, + 880730, + 983272, + 1041933, + 1054396, + 789531, + 851022, + 864032, + 675431, + 418134, + 35762, + 66911, + 103502, + 136403, + -55147, + -245269, + -499595, + -808470, + -1136858, + -2010912, + -2581654, + -3151901, + -3696328, + -4196599, + -4633761, + -4993229, + -5262495, + -5436311, + -477650, + -901314, + -1308090, + -1677468, + -1985525, + -2212848, + -2341196, + -2373915, + -2269552, + -2620489, + -2173858, + -1629954, + -946595, + -193499, + 1119459, + 1138657, + 1335311, + 1126544, + 2765033, + 3139603, + 3414913, + 3599213, + 3676363, + 3448981, + 3328726, + 3111551, + 2810887, + 2428657, + 1973684, + 1457278, + 893848, + 300995, + -292521, + -867621, + -1404936, + -1871278, + -2229831, + -2440932, + -2462684, + -2255006, + -1768898, + -1079574, + 82115, + 1660302, + 3660715, + 6123610, + 8329598, + 11888744, + 15722147, + 19737089, + 25647773, + 31039399, + 36868007, + 43124253, + 49737161, + 56495958, + 63668945, + 71039511, + 78540240, + 86089058, + 93600041, + 100981151, + 108136061, + 114970055, + 121718321, + 127566038, + 132774642, + 137247294, + 140894737, + 143635018, + 145395599, + 146114032, + 145742999, + 144211606, + 141594341, + 137808404, + 132914122, + 126912246, + 120243281, + 112155281, + 103338368, + 93904953, + 83439152, + 72921548, + 62192990, + 51434918, + 40894003, + 30786726, + 21384955, + 12939112, + 5718193, + -5790, + -3959261, + -5870978, + -5475538, + -2517061, + 3247310, + 12042937, + 24076729, + 39531397, + 58562863, + 81297002, + 107826748, + 138209187, + 172464115, + 210569037, + 252468018, + 298045453, + 347168648, + 399634888, + 455137189, + 513586535, + 574537650, + 637645129, + 702597163, + 768856566, + 836022040, + 903618096, + 971159680, + 1038137214, + 1103987353, + 1168195035, + 1230223053, + 1289539180, + 1345620373, + 1397957958, + 1446063657, + 1489474689, + 1527740502, + 1560502307, + 1587383079, + 1608071145, + 1622301248, + 1629859340, + 1630584888, + 1624373875, + 1611178348, + 1591018893, + 1563948667, + 1530105004, + 1489673227, + 1442904075, + 1390107674, + 1331590427, + 1267779478, + 1199115126, + 1126053392, + 1049146257, + 968928307, + 885965976, + 800851610, + 714186243, + 626590147, + 538672486, + 451042824, + 364299927, + 279026812, + 195785029, + 115109565, + 37503924, + -36564551, + -106668063, + -172421668, + -233487283, + -289575706, + -340448569, + -385919511, + -425854915, + -460174578, + -488840702, + -511893328, + -529405118, + -541489888, + -548312207, + -550036471, + -547005316, + -539436808, + -527630488, + -512084785, + -492941605, + -470665204, + -445668379, + -418328829, + -389072810, + -358293846, + -326396227, + -293769619, + -260792276, + -227825056, + -195208961, + -163262121, + -132280748, + -102533727, + -74230062, + -47600637, + -22817785, + -25786, + 20662895, + 39167253, + 55438413, + 69453741, + 81242430, + 90795329, + 98213465, + 103540643, + 106917392, + 108861938, + 108539682, + 106780704, + 103722568, + 99043289, + 93608686, + 87266209, + 80212203, + 72590022, + 64603428, + 56362402, + 48032218, + 39749162, + 31638971, + 23814664, + 16376190, + 9409836, + 2988017, + -2822356, + -7976595, + -12454837, + -16241147, + -19331944, + -21735011, + -23468284, + -24559822, + -25042936, + -25035583, + -24429587, + -23346408, + -21860411, + -20015718, + -17025330, + -14968728, + -12487138, + -9656319, + -7846681, + -5197816, + -2621904, + -144953, + 2144746, + 3990570, + 5845884, + 7454650, + 8820394, + 9929891, + 10784445, + 11390921, + 11762056, + 11916017, + 12261189, + 12117604, + 11815303, + 11374622, + 10815301, + 10157241, + 9418799, + 8629399, + 7780776, + 7303680, + 6353499, + 5392738, + 4457895, + 3543062, + 1305978, + 1402521, + 1084092, + 965652, + -151008, + -666667, + -1032157, + -1231475, + -1319043, + -1006023, + -915720, + -773426, + -612377, + -445864, + -291068, + -161337, + -66484, + -11725, + 133453, + 388184, + 615856, + 804033, + 942377, + 1022911, + 1041247, + 995854, + 891376, + 572246, + 457992, + 316365, + 172738, + 43037, + -117662, + -98542, + -70279, + -41458, + -535790, + -959038, + -1364456, + -1502265, + -1568530, + -2378681, + -2701111, + -2976407, + -3182552, + -3314415, + -3366600, + -3337701, + -3232252, + -3054999, + 1984841, + 1925903, + 1817377, + 1669153, + 1490069, + 1292040, + 1086223, + 890983, + 699163, + 201358, + 266971, + 296990, + 198419, + 91119, + 4737, + 5936, + 2553, + 2060, + -3828, + -1664, + -4917, + -20796, + -36822, + -131247, + -154923, + -162055, + -161354, + -148762, + -125754, + -94473, + -57821, + -19096, + 15172, + 43004, + 65624, + 81354, + 89325, + 89524, + 82766, + 71075, + 55128, + 13686, + 6921, + 1449, + 420, + 785, + -215, + -179, + -113, + -49, + 6002, + 16007, + 42978, + 100662, + 171472, + 83975, + 93702, + 108813, + 111893, + 110272, + 103914, + 93973, + 81606, + 68041, + -54058, + -60695, + -65277, + -67224, + -66213, + -62082, + -55574, + -42988, + -35272, + -63735, + -33501, + -12671, + -4038, + -1232, + 5, + 7 +}; + +#endif /* AVCODEC_DCAENC_H */ diff --git a/libavcodec/dcahuff.h b/libavcodec/dcahuff.h index 254fc76a91..cbc8429e59 100644 --- a/libavcodec/dcahuff.h +++ b/libavcodec/dcahuff.h @@ -3,20 +3,20 @@ * Copyright (C) 2004 Gildas Bazin * Copyright (C) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dct-test.c b/libavcodec/dct-test.c index daa95bd0df..c683ac9837 100644 --- a/libavcodec/dct-test.c +++ b/libavcodec/dct-test.c @@ -2,20 +2,20 @@ * (c) 2001 Fabrice Bellard * 2007 Marc Hoffman <marc.hoffman@analog.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -48,8 +48,6 @@ void ff_mmx_idct(DCTELEM *data); void ff_mmxext_idct(DCTELEM *data); -void odivx_idct_c(short *block); - // BFIN void ff_bfin_idct(DCTELEM *block); void ff_bfin_fdct(DCTELEM *block); @@ -71,7 +69,7 @@ struct algo { const char *name; void (*func)(DCTELEM *block); enum formattag { NO_PERM, MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, - SSE2_PERM, PARTTRANS_PERM } format; + SSE2_PERM, PARTTRANS_PERM, TRANSPOSE_PERM } format; int mm_support; int nonspec; }; @@ -107,6 +105,22 @@ static const struct algo fdct_tab[] = { { 0 } }; +#if HAVE_MMX +void ff_prores_idct_put_10_sse2(uint16_t *dst, int linesize, + DCTELEM *block, int16_t *qmat); + +static void ff_prores_idct_put_10_sse2_wrap(uint16_t *dst){ + int16_t qmat[64]; int i; + int16_t tmp[64]; + + for(i=0; i<64; i++){ + qmat[i]=4; + tmp[i]= dst[i]; + } + ff_prores_idct_put_10_sse2(dst, 16, tmp, qmat); +} +#endif + static const struct algo idct_tab[] = { { "FAANI", ff_faanidct, NO_PERM }, { "REF-DBL", ff_ref_idct, NO_PERM }, @@ -122,6 +136,9 @@ static const struct algo idct_tab[] = { { "XVID-MMX", ff_idct_xvid_mmx, NO_PERM, AV_CPU_FLAG_MMX, 1 }, { "XVID-MMX2", ff_idct_xvid_mmx2, NO_PERM, AV_CPU_FLAG_MMX2, 1 }, { "XVID-SSE2", ff_idct_xvid_sse2, SSE2_PERM, AV_CPU_FLAG_SSE2, 1 }, +#if ARCH_X86_64 + { "PR-SSE2", ff_prores_idct_put_10_sse2_wrap, TRANSPOSE_PERM, AV_CPU_FLAG_SSE2, 1 }, +#endif #endif #if ARCH_BFIN @@ -197,7 +214,7 @@ static inline void mmx_emms(void) #endif } -static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng) +static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng, int vals) { int i, j; @@ -206,7 +223,7 @@ static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng) switch (test) { case 0: for (i = 0; i < 64; i++) - block[i] = (av_lfg_get(prng) % 512) - 256; + block[i] = (av_lfg_get(prng) % (2*vals)) -vals; if (is_idct) { ff_ref_fdct(block); for (i = 0; i < 64; i++) @@ -216,10 +233,10 @@ static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng) case 1: j = av_lfg_get(prng) % 10 + 1; for (i = 0; i < j; i++) - block[av_lfg_get(prng) % 64] = av_lfg_get(prng) % 512 - 256; + block[av_lfg_get(prng) % 64] = av_lfg_get(prng) % (2*vals) -vals; break; case 2: - block[ 0] = av_lfg_get(prng) % 4096 - 2048; + block[ 0] = av_lfg_get(prng) % (16*vals) - (8*vals); block[63] = (block[0] & 1) ^ 1; break; } @@ -241,13 +258,16 @@ static void permute(DCTELEM dst[64], const DCTELEM src[64], int perm) } else if (perm == PARTTRANS_PERM) { for (i = 0; i < 64; i++) dst[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = src[i]; + } else if (perm == TRANSPOSE_PERM) { + for (i = 0; i < 64; i++) + dst[(i>>3) | ((i<<3)&0x38)] = src[i]; } else { for (i = 0; i < 64; i++) dst[i] = src[i]; } } -static int dct_error(const struct algo *dct, int test, int is_idct, int speed) +static int dct_error(const struct algo *dct, int test, int is_idct, int speed, const int bits) { void (*ref)(DCTELEM *block) = is_idct ? ff_ref_idct : ff_ref_fdct; int it, i, scale; @@ -257,6 +277,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed) int maxout = 0; int blockSumErrMax = 0, blockSumErr; AVLFG prng; + const int vals=1<<bits; double omse, ome; int spec_err; @@ -267,7 +288,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed) for (i = 0; i < 64; i++) sysErr[i] = 0; for (it = 0; it < NB_ITS; it++) { - init_block(block1, test, is_idct, &prng); + init_block(block1, test, is_idct, &prng, vals); permute(block, block1, dct->format); dct->func(block); @@ -313,7 +334,7 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed) spec_err = is_idct && (err_inf > 1 || omse > 0.02 || fabs(ome) > 0.0015); - printf("%s %s: ppe=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n", + printf("%s %s: max_err=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n", is_idct ? "IDCT" : "DCT", dct->name, err_inf, omse, ome, (double) sysErrMax / NB_ITS, maxout, blockSumErrMax); @@ -325,7 +346,8 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed) return 0; /* speed test */ - init_block(block, test, is_idct, &prng); + + init_block(block, test, is_idct, &prng, vals); permute(block1, block, dct->format); ti = gettime(); @@ -463,6 +485,25 @@ static void idct248_error(const char *name, if (v > err_max) err_max = v; } +#if 0 + printf("ref=\n"); + for(i=0;i<8;i++) { + int j; + for(j=0;j<8;j++) { + printf(" %3d", img_dest1[i*8+j]); + } + printf("\n"); + } + + printf("out=\n"); + for(i=0;i<8;i++) { + int j; + for(j=0;j<8;j++) { + printf(" %3d", img_dest[i*8+j]); + } + printf("\n"); + } +#endif } printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max); @@ -488,10 +529,11 @@ static void idct248_error(const char *name, static void help(void) { - printf("dct-test [-i] [<test-number>]\n" + printf("dct-test [-i] [<test-number>] [<bits>]\n" "test-number 0 -> test with random matrixes\n" " 1 -> test with random sparse matrixes\n" " 2 -> do 3. test from mpeg4 std\n" + "bits Number of time domain bits to use, 8 is default\n" "-i test IDCT implementations\n" "-4 test IDCT248 implementations\n" "-t speed test\n"); @@ -504,6 +546,7 @@ int main(int argc, char **argv) int test = 1; int speed = 0; int err = 0; + int bits=8; cpu_flags = av_get_cpu_flags(); @@ -533,8 +576,9 @@ int main(int argc, char **argv) if (optind < argc) test = atoi(argv[optind]); + if(optind+1 < argc) bits= atoi(argv[optind+1]); - printf("Libav DCT/IDCT test\n"); + printf("ffmpeg DCT/IDCT test\n"); if (test_248_dct) { idct248_error("SIMPLE-C", ff_simple_idct248_put, speed); @@ -542,7 +586,7 @@ int main(int argc, char **argv) const struct algo *algos = test_idct ? idct_tab : fdct_tab; for (i = 0; algos[i].name; i++) if (!(~cpu_flags & algos[i].mm_support)) { - err |= dct_error(&algos[i], test, test_idct, speed); + err |= dct_error(&algos[i], test, test_idct, speed, bits); } } diff --git a/libavcodec/dct.c b/libavcodec/dct.c index e65671e753..4800e13b36 100644 --- a/libavcodec/dct.c +++ b/libavcodec/dct.c @@ -4,20 +4,20 @@ * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * Copyright (c) 2010 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/libavcodec/dct.h b/libavcodec/dct.h index c898856279..bb17d75d0c 100644 --- a/libavcodec/dct.h +++ b/libavcodec/dct.h @@ -4,20 +4,20 @@ * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * Copyright (c) 2010 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/libavcodec/dct32.c b/libavcodec/dct32.c index 272e0dbf95..fb53d53ab1 100644 --- a/libavcodec/dct32.c +++ b/libavcodec/dct32.c @@ -2,20 +2,20 @@ * Template for the Discrete Cosine Transform for 32 samples * Copyright (c) 2001, 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dctref.c b/libavcodec/dctref.c index ae3dec51cd..851014b664 100644 --- a/libavcodec/dctref.c +++ b/libavcodec/dctref.c @@ -2,20 +2,20 @@ * reference discrete cosine transform (double precision) * Copyright (C) 2009 Dylan Yudaken * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dctref.h b/libavcodec/dctref.h index a93b70d9f2..f6fde8863a 100644 --- a/libavcodec/dctref.h +++ b/libavcodec/dctref.h @@ -2,20 +2,20 @@ * reference discrete cosine transform (double precision) * Copyright (C) 2009 Dylan Yudaken * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dfa.c b/libavcodec/dfa.c index 08bb2a4934..97c0954422 100644 --- a/libavcodec/dfa.c +++ b/libavcodec/dfa.c @@ -3,20 +3,20 @@ * Copyright (c) 2011 Konstantin Shishkov * based on work by Vladimir "VAG" Gneushev * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -67,6 +67,8 @@ static int decode_tsw1(uint8_t *frame, int width, int height, segments = bytestream_get_le32(&src); offset = bytestream_get_le32(&src); + if (segments == 0 && offset == frame_end - frame) + return 0; // skip frame if (frame_end - frame <= offset) return -1; frame += offset; @@ -339,7 +341,7 @@ static int dfa_decode_frame(AVCodecContext *avctx, tmp_buf = buf; for (i = 0; i < pal_elems; i++) { s->pal[i] = bytestream_get_be24(&tmp_buf) << 2; - s->pal[i] |= (s->pal[i] >> 6) & 0x333; + s->pal[i] |= 0xFF << 24 | (s->pal[i] >> 6) & 0x30303; } s->pic.palette_has_changed = 1; } else if (chunk_type <= 9) { diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c index bf56088c75..3ff33f6554 100644 --- a/libavcodec/dirac.c +++ b/libavcodec/dirac.c @@ -1,28 +1,29 @@ /* * Copyright (C) 2007 Marco Gerards <marco@gnu.org> * Copyright (C) 2009 David Conrad + * Copyright (C) 2011 Jordi Ortiz * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file * Dirac Decoder - * @author Marco Gerards <marco@gnu.org> + * @author Marco Gerards <marco@gnu.org>, David Conrad, Jordi Ortiz <nenjordi@gmail.com> */ #include "libavutil/imgutils.h" @@ -31,7 +32,7 @@ #include "golomb.h" #include "mpeg12data.h" -// defaults for source parameters +/* defaults for source parameters */ static const dirac_source_params dirac_source_parameters_defaults[] = { { 640, 480, 2, 0, 0, 1, 1, 640, 480, 0, 0, 1, 0 }, { 176, 120, 2, 0, 0, 9, 2, 176, 120, 0, 0, 1, 1 }, @@ -42,7 +43,6 @@ static const dirac_source_params dirac_source_parameters_defaults[] = { { 704, 576, 2, 0, 1, 10, 3, 704, 576, 0, 0, 1, 2 }, { 720, 480, 1, 1, 0, 4, 2, 704, 480, 8, 0, 3, 1 }, { 720, 576, 1, 1, 1, 3, 3, 704, 576, 8, 0, 3, 2 }, - { 1280, 720, 1, 0, 1, 7, 1, 1280, 720, 0, 0, 3, 3 }, { 1280, 720, 1, 0, 1, 6, 1, 1280, 720, 0, 0, 3, 3 }, { 1920, 1080, 1, 1, 1, 4, 1, 1920, 1080, 0, 0, 3, 3 }, @@ -51,13 +51,16 @@ static const dirac_source_params dirac_source_parameters_defaults[] = { { 1920, 1080, 1, 0, 1, 6, 1, 1920, 1080, 0, 0, 3, 3 }, { 2048, 1080, 0, 0, 1, 2, 1, 2048, 1080, 0, 0, 4, 4 }, { 4096, 2160, 0, 0, 1, 2, 1, 4096, 2160, 0, 0, 4, 4 }, - { 3840, 2160, 1, 0, 1, 7, 1, 3840, 2160, 0, 0, 3, 3 }, { 3840, 2160, 1, 0, 1, 6, 1, 3840, 2160, 0, 0, 3, 3 }, { 7680, 4320, 1, 0, 1, 7, 1, 3840, 2160, 0, 0, 3, 3 }, { 7680, 4320, 1, 0, 1, 6, 1, 3840, 2160, 0, 0, 3, 3 }, }; +/** + * Dirac Specification -> + * Table 10.4 - Available preset pixel aspect ratio values + */ static const AVRational dirac_preset_aspect_ratios[] = { {1, 1}, {10, 11}, @@ -67,11 +70,19 @@ static const AVRational dirac_preset_aspect_ratios[] = { {4, 3}, }; +/** + * Dirac Specification -> + * Values 9,10 of 10.3.5 Frame Rate. Table 10.3 Available preset frame rate values + */ static const AVRational dirac_frame_rate[] = { {15000, 1001}, {25, 2}, }; +/** + * Dirac Specification -> + * This should be equivalent to Table 10.5 Available signal range presets + */ static const struct { uint8_t bitdepth; enum AVColorRange color_range; @@ -100,11 +111,19 @@ static const struct { { AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_UNSPECIFIED /* DCinema */ }, }; +/** + * Dirac Specification -> + * Table 10.2 Supported chroma sampling formats + Luma Offset + */ static const enum PixelFormat dirac_pix_fmt[2][3] = { { PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P }, { PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P }, }; +/** + * Dirac Specification -> + * 10.3 Parse Source Parameters. source_parameters(base_video_format) + */ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, dirac_source_params *source) { @@ -112,51 +131,54 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, unsigned luma_depth = 8, luma_offset = 16; int idx; - if (get_bits1(gb)) { - source->width = svq3_get_ue_golomb(gb); - source->height = svq3_get_ue_golomb(gb); + /* [DIRAC_STD] 10.3.2 Frame size. frame_size(video_params) */ + if (get_bits1(gb)) { /* [DIRAC_STD] custom_dimensions_flag */ + source->width = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_WIDTH */ + source->height = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_HEIGHT */ } - // chroma subsampling - if (get_bits1(gb)) - source->chroma_format = svq3_get_ue_golomb(gb); - if (source->chroma_format > 2) { + /* [DIRAC_STD] 10.3.3 Chroma Sampling Format. + chroma_sampling_format(video_params) */ + if (get_bits1(gb)) /* [DIRAC_STD] custom_chroma_format_flag */ + source->chroma_format = svq3_get_ue_golomb(gb); /*[DIRAC_STD] CHROMA_FORMAT_INDEX */ + if (source->chroma_format > 2U) { av_log(avctx, AV_LOG_ERROR, "Unknown chroma format %d\n", source->chroma_format); return -1; } - if (get_bits1(gb)) - source->interlaced = svq3_get_ue_golomb(gb); - if (source->interlaced > 1) + /* [DIRAC_STD] 10.3.4 Scan Format. scan_format(video_params) */ + if (get_bits1(gb)) /* [DIRAC_STD] custom_scan_format_flag */ + source->interlaced = svq3_get_ue_golomb(gb); /* [DIRAC_STD] SOURCE_SAMPLING */ + if (source->interlaced > 1U) return -1; - // frame rate - if (get_bits1(gb)) { + /* [DIRAC_STD] 10.3.5 Frame Rate. frame_rate(video_params) */ + if (get_bits1(gb)) { /* [DIRAC_STD] custom_frame_rate_flag */ source->frame_rate_index = svq3_get_ue_golomb(gb); - if (source->frame_rate_index > 10) + if (source->frame_rate_index > 10U) return -1; - if (!source->frame_rate_index) { - frame_rate.num = svq3_get_ue_golomb(gb); - frame_rate.den = svq3_get_ue_golomb(gb); + if (!source->frame_rate_index){ + frame_rate.num = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_RATE_NUMER */ + frame_rate.den = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_RATE_DENOM */ } } - if (source->frame_rate_index > 0) { + if (source->frame_rate_index > 0) { /* [DIRAC_STD] preset_frame_rate(video_params,index) */ if (source->frame_rate_index <= 8) - frame_rate = avpriv_frame_rate_tab[source->frame_rate_index]; + frame_rate = avpriv_frame_rate_tab[source->frame_rate_index]; /* [DIRAC_STD] Table 10.3 values 1-8 */ else - frame_rate = dirac_frame_rate[source->frame_rate_index-9]; + frame_rate = dirac_frame_rate[source->frame_rate_index-9]; /* [DIRAC_STD] Table 10.3 values 9-10 */ } av_reduce(&avctx->time_base.num, &avctx->time_base.den, frame_rate.den, frame_rate.num, 1<<30); - // aspect ratio - if (get_bits1(gb)) { - source->aspect_ratio_index = svq3_get_ue_golomb(gb); + /* [DIRAC_STD] 10.3.6 Pixel Aspect Ratio. pixel_aspect_ratio(video_params) */ + if (get_bits1(gb)) { /* [DIRAC_STD] custom_pixel_aspect_ratio_flag */ + source->aspect_ratio_index = svq3_get_ue_golomb(gb); /* [DIRAC_STD] index */ - if (source->aspect_ratio_index > 6) + if (source->aspect_ratio_index > 6U) return -1; if (!source->aspect_ratio_index) { @@ -164,35 +186,37 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, avctx->sample_aspect_ratio.den = svq3_get_ue_golomb(gb); } } - if (source->aspect_ratio_index > 0) + if (source->aspect_ratio_index > 0) /* [DIRAC_STD] Take value from Table 10.4 Available preset pixel aspect ratio values */ avctx->sample_aspect_ratio = - dirac_preset_aspect_ratios[source->aspect_ratio_index-1]; - - if (get_bits1(gb)) { - source->clean_width = svq3_get_ue_golomb(gb); - source->clean_height = svq3_get_ue_golomb(gb); - source->clean_left_offset = svq3_get_ue_golomb(gb); - source->clean_right_offset = svq3_get_ue_golomb(gb); + dirac_preset_aspect_ratios[source->aspect_ratio_index-1]; + + /* [DIRAC_STD] 10.3.7 Clean area. clean_area(video_params) */ + if (get_bits1(gb)) { /* [DIRAC_STD] custom_clean_area_flag */ + source->clean_width = svq3_get_ue_golomb(gb); /* [DIRAC_STD] CLEAN_WIDTH */ + source->clean_height = svq3_get_ue_golomb(gb); /* [DIRAC_STD] CLEAN_HEIGHT */ + source->clean_left_offset = svq3_get_ue_golomb(gb); /* [DIRAC_STD] CLEAN_LEFT_OFFSET */ + source->clean_right_offset = svq3_get_ue_golomb(gb); /* [DIRAC_STD] CLEAN_RIGHT_OFFSET */ } - // Override signal range. - if (get_bits1(gb)) { - source->pixel_range_index = svq3_get_ue_golomb(gb); + /*[DIRAC_STD] 10.3.8 Signal range. signal_range(video_params) + WARNING: Some adaptation seemed to be done using the AVCOL_RANGE_MPEG/JPEG values */ + if (get_bits1(gb)) { /*[DIRAC_STD] custom_signal_range_flag */ + source->pixel_range_index = svq3_get_ue_golomb(gb); /*[DIRAC_STD] index */ - if (source->pixel_range_index > 4) + if (source->pixel_range_index > 4U) return -1; - // This assumes either fullrange or MPEG levels only + /* This assumes either fullrange or MPEG levels only */ if (!source->pixel_range_index) { luma_offset = svq3_get_ue_golomb(gb); luma_depth = av_log2(svq3_get_ue_golomb(gb))+1; - svq3_get_ue_golomb(gb); // chroma offset - svq3_get_ue_golomb(gb); // chroma excursion + svq3_get_ue_golomb(gb); /* chroma offset @Jordi: Why are these two ignored? */ + svq3_get_ue_golomb(gb); /* chroma excursion */ avctx->color_range = luma_offset ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; } } - if (source->pixel_range_index > 0) { + if (source->pixel_range_index > 0) { /*[DIRAC_STD] Take values from Table 10.5 Available signal range presets */ idx = source->pixel_range_index-1; luma_depth = pixel_range_presets[idx].bitdepth; avctx->color_range = pixel_range_presets[idx].color_range; @@ -203,11 +227,11 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, avctx->pix_fmt = dirac_pix_fmt[!luma_offset][source->chroma_format]; - // color spec - if (get_bits1(gb)) { - idx = source->color_spec_index = svq3_get_ue_golomb(gb); + /* [DIRAC_STD] 10.3.9 Colour specification. colour_spec(video_params) */ + if (get_bits1(gb)) { /* [DIRAC_STD] custom_colour_spec_flag */ + idx = source->color_spec_index = svq3_get_ue_golomb(gb); /* [DIRAC_STD] index */ - if (source->color_spec_index > 4) + if (source->color_spec_index > 4U) return -1; avctx->color_primaries = dirac_color_presets[idx].color_primaries; @@ -215,12 +239,13 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, avctx->color_trc = dirac_color_presets[idx].color_trc; if (!source->color_spec_index) { + /* [DIRAC_STD] 10.3.9.1 Color primaries */ if (get_bits1(gb)) { idx = svq3_get_ue_golomb(gb); - if (idx < 3) + if (idx < 3U) avctx->color_primaries = dirac_primaries[idx]; } - + /* [DIRAC_STD] 10.3.9.2 Color matrix */ if (get_bits1(gb)) { idx = svq3_get_ue_golomb(gb); if (!idx) @@ -228,7 +253,7 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, else if (idx == 1) avctx->colorspace = AVCOL_SPC_BT470BG; } - + /* [DIRAC_STD] 10.3.9.3 Transfer function */ if (get_bits1(gb) && !svq3_get_ue_golomb(gb)) avctx->color_trc = AVCOL_TRC_BT709; } @@ -242,16 +267,23 @@ static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, return 0; } +/** + * Dirac Specification -> + * 10. Sequence Header. sequence_header() + */ int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, dirac_source_params *source) { unsigned version_major; unsigned video_format, picture_coding_mode; + /* [DIRAC_SPEC] 10.1 Parse Parameters. parse_parameters() */ version_major = svq3_get_ue_golomb(gb); svq3_get_ue_golomb(gb); /* version_minor */ avctx->profile = svq3_get_ue_golomb(gb); avctx->level = svq3_get_ue_golomb(gb); + /* [DIRAC_SPEC] sequence_header() -> base_video_format as defined in + 10.2 Base Video Format, table 10.1 Dirac predefined video formats */ video_format = svq3_get_ue_golomb(gb); if (version_major < 2) @@ -259,13 +291,14 @@ int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, else if (version_major > 2) av_log(avctx, AV_LOG_WARNING, "Stream may have unhandled features\n"); - if (video_format > 20) + if (video_format > 20U) return -1; - // Fill in defaults for the source parameters. + /* Fill in defaults for the source parameters. */ *source = dirac_source_parameters_defaults[video_format]; - // Override the defaults. + /*[DIRAC_STD] 10.3 Source Parameters + Override the defaults. */ if (parse_source_parameters(avctx, gb, source)) return -1; @@ -274,7 +307,8 @@ int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, avcodec_set_dimensions(avctx, source->width, source->height); - // currently only used to signal field coding + /*[DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames + currently only used to signal field coding */ picture_coding_mode = svq3_get_ue_golomb(gb); if (picture_coding_mode != 0) { av_log(avctx, AV_LOG_ERROR, "Unsupported picture coding mode %d", diff --git a/libavcodec/dirac.h b/libavcodec/dirac.h index f8063d9e28..542d4910f8 100644 --- a/libavcodec/dirac.h +++ b/libavcodec/dirac.h @@ -1,21 +1,22 @@ /* * Copyright (C) 2007 Marco Gerards <marco@gnu.org> * Copyright (C) 2009 David Conrad + * Copyright (C) 2011 Jordi Ortiz * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +27,8 @@ * @file * Interface to Dirac Decoder/Encoder * @author Marco Gerards <marco@gnu.org> + * @author David Conrad + * @author Jordi Ortiz */ #include "avcodec.h" diff --git a/libavcodec/dirac_arith.c b/libavcodec/dirac_arith.c new file mode 100644 index 0000000000..bf913928b3 --- /dev/null +++ b/libavcodec/dirac_arith.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2007 Marco Gerards <marco@gnu.org> + * Copyright (C) 2009 David Conrad + * + * 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 + * Arithmetic decoder for Dirac + * @author Marco Gerards <marco@gnu.org> + */ + +#include "dirac_arith.h" + + +const uint16_t ff_dirac_prob[256] = { + 0, 2, 5, 8, 11, 15, 20, 24, + 29, 35, 41, 47, 53, 60, 67, 74, + 82, 89, 97, 106, 114, 123, 132, 141, + 150, 160, 170, 180, 190, 201, 211, 222, + 233, 244, 256, 267, 279, 291, 303, 315, + 327, 340, 353, 366, 379, 392, 405, 419, + 433, 447, 461, 475, 489, 504, 518, 533, + 548, 563, 578, 593, 609, 624, 640, 656, + 672, 688, 705, 721, 738, 754, 771, 788, + 805, 822, 840, 857, 875, 892, 910, 928, + 946, 964, 983, 1001, 1020, 1038, 1057, 1076, + 1095, 1114, 1133, 1153, 1172, 1192, 1211, 1231, + 1251, 1271, 1291, 1311, 1332, 1352, 1373, 1393, + 1414, 1435, 1456, 1477, 1498, 1520, 1541, 1562, + 1584, 1606, 1628, 1649, 1671, 1694, 1716, 1738, + 1760, 1783, 1806, 1828, 1851, 1874, 1897, 1920, + 1935, 1942, 1949, 1955, 1961, 1968, 1974, 1980, + 1985, 1991, 1996, 2001, 2006, 2011, 2016, 2021, + 2025, 2029, 2033, 2037, 2040, 2044, 2047, 2050, + 2053, 2056, 2058, 2061, 2063, 2065, 2066, 2068, + 2069, 2070, 2071, 2072, 2072, 2072, 2072, 2072, + 2072, 2071, 2070, 2069, 2068, 2066, 2065, 2063, + 2060, 2058, 2055, 2052, 2049, 2045, 2042, 2038, + 2033, 2029, 2024, 2019, 2013, 2008, 2002, 1996, + 1989, 1982, 1975, 1968, 1960, 1952, 1943, 1934, + 1925, 1916, 1906, 1896, 1885, 1874, 1863, 1851, + 1839, 1827, 1814, 1800, 1786, 1772, 1757, 1742, + 1727, 1710, 1694, 1676, 1659, 1640, 1622, 1602, + 1582, 1561, 1540, 1518, 1495, 1471, 1447, 1422, + 1396, 1369, 1341, 1312, 1282, 1251, 1219, 1186, + 1151, 1114, 1077, 1037, 995, 952, 906, 857, + 805, 750, 690, 625, 553, 471, 376, 255 +}; + +const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT] = { + [CTX_ZPZN_F1] = CTX_ZP_F2, + [CTX_ZPNN_F1] = CTX_ZP_F2, + [CTX_ZP_F2] = CTX_ZP_F3, + [CTX_ZP_F3] = CTX_ZP_F4, + [CTX_ZP_F4] = CTX_ZP_F5, + [CTX_ZP_F5] = CTX_ZP_F6, + [CTX_ZP_F6] = CTX_ZP_F6, + [CTX_NPZN_F1] = CTX_NP_F2, + [CTX_NPNN_F1] = CTX_NP_F2, + [CTX_NP_F2] = CTX_NP_F3, + [CTX_NP_F3] = CTX_NP_F4, + [CTX_NP_F4] = CTX_NP_F5, + [CTX_NP_F5] = CTX_NP_F6, + [CTX_NP_F6] = CTX_NP_F6, + [CTX_DELTA_Q_F] = CTX_DELTA_Q_F, +}; + +int16_t ff_dirac_prob_branchless[256][2]; + +void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length) +{ + int i; + align_get_bits(gb); + + length = FFMIN(length, get_bits_left(gb)/8); + + c->bytestream = gb->buffer + get_bits_count(gb)/8; + c->bytestream_end = c->bytestream + length; + skip_bits_long(gb, length*8); + + c->low = 0; + for (i = 0; i < 4; i++) { + c->low <<= 8; + if (c->bytestream < c->bytestream_end) + c->low |= *c->bytestream++; + else + c->low |= 0xff; + } + + c->counter = -16; + c->range = 0xffff; + + for (i = 0; i < 256; i++) { + ff_dirac_prob_branchless[i][0] = ff_dirac_prob[255-i]; + ff_dirac_prob_branchless[i][1] = -ff_dirac_prob[i]; + } + + for (i = 0; i < DIRAC_CTX_COUNT; i++) + c->contexts[i] = 0x8000; +} diff --git a/libavcodec/dirac_arith.h b/libavcodec/dirac_arith.h new file mode 100644 index 0000000000..b605825027 --- /dev/null +++ b/libavcodec/dirac_arith.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2007 Marco Gerards <marco@gnu.org> + * Copyright (C) 2009 David Conrad + * + * 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 + * Arithmetic decoder for Dirac + * @author Marco Gerards <marco@gnu.org> + */ + +#ifndef AVCODEC_DIRAC_ARITH_H +#define AVCODEC_DIRAC_ARITH_H + +#include "bytestream.h" +#include "get_bits.h" + +enum dirac_arith_contexts { + CTX_ZPZN_F1, + CTX_ZPNN_F1, + CTX_NPZN_F1, + CTX_NPNN_F1, + CTX_ZP_F2, + CTX_ZP_F3, + CTX_ZP_F4, + CTX_ZP_F5, + CTX_ZP_F6, + CTX_NP_F2, + CTX_NP_F3, + CTX_NP_F4, + CTX_NP_F5, + CTX_NP_F6, + CTX_COEFF_DATA, + CTX_SIGN_NEG, + CTX_SIGN_ZERO, + CTX_SIGN_POS, + CTX_ZERO_BLOCK, + CTX_DELTA_Q_F, + CTX_DELTA_Q_DATA, + CTX_DELTA_Q_SIGN, + + DIRAC_CTX_COUNT +}; + +// Dirac resets the arith decoder between decoding various types of data, +// so many contexts are never used simultaneously. Thus, we can reduce +// the number of contexts needed by reusing them. +#define CTX_SB_F1 CTX_ZP_F5 +#define CTX_SB_DATA 0 +#define CTX_PMODE_REF1 0 +#define CTX_PMODE_REF2 1 +#define CTX_GLOBAL_BLOCK 2 +#define CTX_MV_F1 CTX_ZP_F2 +#define CTX_MV_DATA 0 +#define CTX_DC_F1 CTX_ZP_F5 +#define CTX_DC_DATA 0 + +typedef struct { + unsigned low; + uint16_t range; + int16_t counter; + + const uint8_t *bytestream; + const uint8_t *bytestream_end; + + uint16_t contexts[DIRAC_CTX_COUNT]; +} DiracArith; + +extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT]; +extern const uint16_t ff_dirac_prob[256]; +extern int16_t ff_dirac_prob_branchless[256][2]; + +static inline void renorm(DiracArith *c) +{ +#if HAVE_FAST_CLZ + int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15); + + c->low <<= shift; + c->range <<= shift; + c->counter += shift; +#else + while (c->range <= 0x4000) { + c->low <<= 1; + c->range <<= 1; + c->counter++; + } +#endif +} + +static inline void refill(DiracArith *c) +{ + int counter = c->counter; + + if (counter >= 0) { + int new = bytestream_get_be16(&c->bytestream); + + // the spec defines overread bits to be 1, and streams rely on this + if (c->bytestream > c->bytestream_end) { + new |= 0xff; + if (c->bytestream > c->bytestream_end+1) + new |= 0xff00; + + c->bytestream = c->bytestream_end; + } + + c->low += new << counter; + counter -= 16; + } + c->counter = counter; +} + +static inline int dirac_get_arith_bit(DiracArith *c, int ctx) +{ + int prob_zero = c->contexts[ctx]; + int range_times_prob, bit; + unsigned low = c->low; + int range = c->range; + + range_times_prob = (c->range * prob_zero) >> 16; + +#if HAVE_FAST_CMOV + low -= range_times_prob << 16; + range -= range_times_prob; + bit = 0; + __asm__( + "cmpl %5, %4 \n\t" + "setae %b0 \n\t" + "cmovb %3, %2 \n\t" + "cmovb %5, %1 \n\t" + : "+q"(bit), "+r"(range), "+r"(low) + : "r"(c->low), "r"(c->low>>16), + "r"(range_times_prob) + ); +#else + bit = (low >> 16) >= range_times_prob; + if (bit) { + low -= range_times_prob << 16; + range -= range_times_prob; + } else { + range = range_times_prob; + } +#endif + + c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit]; + c->low = low; + c->range = range; + + renorm(c); + refill(c); + return bit; +} + +static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx) +{ + int ret = 1; + while (!dirac_get_arith_bit(c, follow_ctx)) { + ret <<= 1; + ret += dirac_get_arith_bit(c, data_ctx); + follow_ctx = ff_dirac_next_ctx[follow_ctx]; + } + return ret-1; +} + +static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx) +{ + int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx); + if (ret && dirac_get_arith_bit(c, data_ctx+1)) + ret = -ret; + return ret; +} + +void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length); + +#endif /* AVCODEC_DIRAC_ARITH_H */ diff --git a/libavcodec/dirac_parser.c b/libavcodec/dirac_parser.c index 11d0cf86b2..94af768432 100644 --- a/libavcodec/dirac_parser.c +++ b/libavcodec/dirac_parser.c @@ -4,20 +4,20 @@ * Copyright (c) 2007-2008 Marco Gerards <marco@gnu.org> * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/diracdec.c b/libavcodec/diracdec.c new file mode 100644 index 0000000000..049f7592ca --- /dev/null +++ b/libavcodec/diracdec.c @@ -0,0 +1,1922 @@ +/* + * Copyright (C) 2007 Marco Gerards <marco@gnu.org> + * Copyright (C) 2009 David Conrad + * Copyright (C) 2011 Jordi Ortiz + * + * 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 libavcodec/diracdec.c + * Dirac Decoder + * @author Marco Gerards <marco@gnu.org>, David Conrad, Jordi Ortiz <nenjordi@gmail.com> + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "get_bits.h" +#include "bytestream.h" +#include "golomb.h" +#include "dirac_arith.h" +#include "mpeg12data.h" +#include "dwt.h" +#include "dirac.h" +#include "diracdsp.h" + +/** + * The spec limits the number of wavelet decompositions to 4 for both + * level 1 (VC-2) and 128 (long-gop default). + * 5 decompositions is the maximum before >16-bit buffers are needed. + * Schroedinger allows this for DD 9,7 and 13,7 wavelets only, limiting + * the others to 4 decompositions (or 3 for the fidelity filter). + * + * We use this instead of MAX_DECOMPOSITIONS to save some memory. + */ +#define MAX_DWT_LEVELS 5 + +/** + * The spec limits this to 3 for frame coding, but in practice can be as high as 6 + */ +#define MAX_REFERENCE_FRAMES 8 +#define MAX_DELAY 5 /* limit for main profile for frame coding (TODO: field coding) */ +#define MAX_FRAMES (MAX_REFERENCE_FRAMES + MAX_DELAY + 1) +#define MAX_QUANT 68 /* max quant for VC-2 */ +#define MAX_BLOCKSIZE 32 /* maximum xblen/yblen we support */ + +/** + * DiracBlock->ref flags, if set then the block does MC from the given ref + */ +#define DIRAC_REF_MASK_REF1 1 +#define DIRAC_REF_MASK_REF2 2 +#define DIRAC_REF_MASK_GLOBAL 4 + +/** + * Value of Picture.reference when Picture is not a reference picture, but + * is held for delayed output. + */ +#define DELAYED_PIC_REF 4 + +#define ff_emulated_edge_mc ff_emulated_edge_mc_8 /* Fix: change the calls to this function regarding bit depth */ + +#define CALC_PADDING(size, depth) \ + (((size + (1 << depth) - 1) >> depth) << depth) + +#define DIVRNDUP(a, b) (((a) + (b) - 1) / (b)) + +typedef struct { + AVFrame avframe; + int interpolated[3]; /* 1 if hpel[] is valid */ + uint8_t *hpel[3][4]; + uint8_t *hpel_base[3][4]; +} DiracFrame; + +typedef struct { + union { + int16_t mv[2][2]; + int16_t dc[3]; + } u; /* anonymous unions aren't in C99 :( */ + uint8_t ref; +} DiracBlock; + +typedef struct SubBand { + int level; + int orientation; + int stride; + int width; + int height; + int quant; + IDWTELEM *ibuf; + struct SubBand *parent; + + /* for low delay */ + unsigned length; + const uint8_t *coeff_data; +} SubBand; + +typedef struct Plane { + int width; + int height; + int stride; + + int idwt_width; + int idwt_height; + int idwt_stride; + IDWTELEM *idwt_buf; + IDWTELEM *idwt_buf_base; + IDWTELEM *idwt_tmp; + + /* block length */ + uint8_t xblen; + uint8_t yblen; + /* block separation (block n+1 starts after this many pixels in block n) */ + uint8_t xbsep; + uint8_t ybsep; + /* amount of overspill on each edge (half of the overlap between blocks) */ + uint8_t xoffset; + uint8_t yoffset; + + SubBand band[MAX_DWT_LEVELS][4]; +} Plane; + +typedef struct DiracContext { + AVCodecContext *avctx; + DSPContext dsp; + DiracDSPContext diracdsp; + GetBitContext gb; + dirac_source_params source; + int seen_sequence_header; + int frame_number; /* number of the next frame to display */ + Plane plane[3]; + int chroma_x_shift; + int chroma_y_shift; + + int zero_res; /* zero residue flag */ + int is_arith; /* whether coeffs use arith or golomb coding */ + int low_delay; /* use the low delay syntax */ + int globalmc_flag; /* use global motion compensation */ + int num_refs; /* number of reference pictures */ + + /* wavelet decoding */ + unsigned wavelet_depth; /* depth of the IDWT */ + unsigned wavelet_idx; + + /** + * schroedinger older than 1.0.8 doesn't store + * quant delta if only one codebook exists in a band + */ + unsigned old_delta_quant; + unsigned codeblock_mode; + + struct { + unsigned width; + unsigned height; + } codeblock[MAX_DWT_LEVELS+1]; + + struct { + unsigned num_x; /* number of horizontal slices */ + unsigned num_y; /* number of vertical slices */ + AVRational bytes; /* average bytes per slice */ + uint8_t quant[MAX_DWT_LEVELS][4]; /* [DIRAC_STD] E.1 */ + } lowdelay; + + struct { + int pan_tilt[2]; /* pan/tilt vector */ + int zrs[2][2]; /* zoom/rotate/shear matrix */ + int perspective[2]; /* perspective vector */ + unsigned zrs_exp; + unsigned perspective_exp; + } globalmc[2]; + + /* motion compensation */ + uint8_t mv_precision; /* [DIRAC_STD] REFS_WT_PRECISION */ + int16_t weight[2]; /* [DIRAC_STD] REF1_WT and REF2_WT */ + unsigned weight_log2denom; /* [DIRAC_STD] REFS_WT_PRECISION */ + + int blwidth; /* number of blocks (horizontally) */ + int blheight; /* number of blocks (vertically) */ + int sbwidth; /* number of superblocks (horizontally) */ + int sbheight; /* number of superblocks (vertically) */ + + uint8_t *sbsplit; + DiracBlock *blmotion; + + uint8_t *edge_emu_buffer[4]; + uint8_t *edge_emu_buffer_base; + + uint16_t *mctmp; /* buffer holding the MC data multipled by OBMC weights */ + uint8_t *mcscratch; + + DECLARE_ALIGNED(16, uint8_t, obmc_weight)[3][MAX_BLOCKSIZE*MAX_BLOCKSIZE]; + + void (*put_pixels_tab[4])(uint8_t *dst, const uint8_t *src[5], int stride, int h); + void (*avg_pixels_tab[4])(uint8_t *dst, const uint8_t *src[5], int stride, int h); + void (*add_obmc)(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); + dirac_weight_func weight_func; + dirac_biweight_func biweight_func; + + DiracFrame *current_picture; + DiracFrame *ref_pics[2]; + + DiracFrame *ref_frames[MAX_REFERENCE_FRAMES+1]; + DiracFrame *delay_frames[MAX_DELAY+1]; + DiracFrame all_frames[MAX_FRAMES]; +} DiracContext; + +/** + * Dirac Specification -> + * Parse code values. 9.6.1 Table 9.1 + */ +enum dirac_parse_code { + pc_seq_header = 0x00, + pc_eos = 0x10, + pc_aux_data = 0x20, + pc_padding = 0x30, +}; + +enum dirac_subband { + subband_ll = 0, + subband_hl = 1, + subband_lh = 2, + subband_hh = 3 +}; + +static const uint8_t default_qmat[][4][4] = { + { { 5, 3, 3, 0}, { 0, 4, 4, 1}, { 0, 5, 5, 2}, { 0, 6, 6, 3} }, + { { 4, 2, 2, 0}, { 0, 4, 4, 2}, { 0, 5, 5, 3}, { 0, 7, 7, 5} }, + { { 5, 3, 3, 0}, { 0, 4, 4, 1}, { 0, 5, 5, 2}, { 0, 6, 6, 3} }, + { { 8, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0} }, + { { 8, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0} }, + { { 0, 4, 4, 8}, { 0, 8, 8, 12}, { 0, 13, 13, 17}, { 0, 17, 17, 21} }, + { { 3, 1, 1, 0}, { 0, 4, 4, 2}, { 0, 6, 6, 5}, { 0, 9, 9, 7} }, +}; + +static const int qscale_tab[MAX_QUANT+1] = { + 4, 5, 6, 7, 8, 10, 11, 13, + 16, 19, 23, 27, 32, 38, 45, 54, + 64, 76, 91, 108, 128, 152, 181, 215, + 256, 304, 362, 431, 512, 609, 724, 861, + 1024, 1218, 1448, 1722, 2048, 2435, 2896, 3444, + 4096, 4871, 5793, 6889, 8192, 9742, 11585, 13777, + 16384, 19484, 23170, 27554, 32768, 38968, 46341, 55109, + 65536, 77936 +}; + +static const int qoffset_intra_tab[MAX_QUANT+1] = { + 1, 2, 3, 4, 4, 5, 6, 7, + 8, 10, 12, 14, 16, 19, 23, 27, + 32, 38, 46, 54, 64, 76, 91, 108, + 128, 152, 181, 216, 256, 305, 362, 431, + 512, 609, 724, 861, 1024, 1218, 1448, 1722, + 2048, 2436, 2897, 3445, 4096, 4871, 5793, 6889, + 8192, 9742, 11585, 13777, 16384, 19484, 23171, 27555, + 32768, 38968 +}; + +static const int qoffset_inter_tab[MAX_QUANT+1] = { + 1, 2, 2, 3, 3, 4, 4, 5, + 6, 7, 9, 10, 12, 14, 17, 20, + 24, 29, 34, 41, 48, 57, 68, 81, + 96, 114, 136, 162, 192, 228, 272, 323, + 384, 457, 543, 646, 768, 913, 1086, 1292, + 1536, 1827, 2172, 2583, 3072, 3653, 4344, 5166, + 6144, 7307, 8689, 10333, 12288, 14613, 17378, 20666, + 24576, 29226 +}; + +/* magic number division by 3 from schroedinger */ +static inline int divide3(int x) +{ + return ((x+1)*21845 + 10922) >> 16; +} + +static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum) +{ + DiracFrame *remove_pic = NULL; + int i, remove_idx = -1; + + for (i = 0; framelist[i]; i++) + if (framelist[i]->avframe.display_picture_number == picnum) { + remove_pic = framelist[i]; + remove_idx = i; + } + + if (remove_pic) + for (i = remove_idx; framelist[i]; i++) + framelist[i] = framelist[i+1]; + + return remove_pic; +} + +static int add_frame(DiracFrame *framelist[], int maxframes, DiracFrame *frame) +{ + int i; + for (i = 0; i < maxframes; i++) + if (!framelist[i]) { + framelist[i] = frame; + return 0; + } + return -1; +} + +static int alloc_sequence_buffers(DiracContext *s) +{ + int sbwidth = DIVRNDUP(s->source.width, 4); + int sbheight = DIVRNDUP(s->source.height, 4); + int i, w, h, top_padding; + + /* todo: think more about this / use or set Plane here */ + for (i = 0; i < 3; i++) { + int max_xblen = MAX_BLOCKSIZE >> (i ? s->chroma_x_shift : 0); + int max_yblen = MAX_BLOCKSIZE >> (i ? s->chroma_y_shift : 0); + w = s->source.width >> (i ? s->chroma_x_shift : 0); + h = s->source.height >> (i ? s->chroma_y_shift : 0); + + /* we allocate the max we support here since num decompositions can + * change from frame to frame. Stride is aligned to 16 for SIMD, and + * 1<<MAX_DWT_LEVELS top padding to avoid if(y>0) in arith decoding + * MAX_BLOCKSIZE padding for MC: blocks can spill up to half of that + * on each side */ + top_padding = FFMAX(1<<MAX_DWT_LEVELS, max_yblen/2); + w = FFALIGN(CALC_PADDING(w, MAX_DWT_LEVELS), 8); /* FIXME: Should this be 16 for SSE??? */ + h = top_padding + CALC_PADDING(h, MAX_DWT_LEVELS) + max_yblen/2; + + s->plane[i].idwt_buf_base = av_mallocz((w+max_xblen)*h * sizeof(IDWTELEM)); + s->plane[i].idwt_tmp = av_malloc((w+16) * sizeof(IDWTELEM)); + s->plane[i].idwt_buf = s->plane[i].idwt_buf_base + top_padding*w; + if (!s->plane[i].idwt_buf_base || !s->plane[i].idwt_tmp) + return AVERROR(ENOMEM); + } + + w = s->source.width; + h = s->source.height; + + /* fixme: allocate using real stride here */ + s->sbsplit = av_malloc(sbwidth * sbheight); + s->blmotion = av_malloc(sbwidth * sbheight * 4 * sizeof(*s->blmotion)); + s->edge_emu_buffer_base = av_malloc((w+64)*MAX_BLOCKSIZE); + + s->mctmp = av_malloc((w+64+MAX_BLOCKSIZE) * (h*MAX_BLOCKSIZE) * sizeof(*s->mctmp)); + s->mcscratch = av_malloc((w+64)*MAX_BLOCKSIZE); + + if (!s->sbsplit || !s->blmotion) + return AVERROR(ENOMEM); + return 0; +} + +static void free_sequence_buffers(DiracContext *s) +{ + int i, j, k; + + for (i = 0; i < MAX_FRAMES; i++) { + if (s->all_frames[i].avframe.data[0]) { + s->avctx->release_buffer(s->avctx, &s->all_frames[i].avframe); + memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated)); + } + + for (j = 0; j < 3; j++) + for (k = 1; k < 4; k++) + av_freep(&s->all_frames[i].hpel_base[j][k]); + } + + memset(s->ref_frames, 0, sizeof(s->ref_frames)); + memset(s->delay_frames, 0, sizeof(s->delay_frames)); + + for (i = 0; i < 3; i++) { + av_freep(&s->plane[i].idwt_buf_base); + av_freep(&s->plane[i].idwt_tmp); + } + + av_freep(&s->sbsplit); + av_freep(&s->blmotion); + av_freep(&s->edge_emu_buffer_base); + + av_freep(&s->mctmp); + av_freep(&s->mcscratch); +} + +static av_cold int dirac_decode_init(AVCodecContext *avctx) +{ + DiracContext *s = avctx->priv_data; + s->avctx = avctx; + s->frame_number = -1; + + if (avctx->flags&CODEC_FLAG_EMU_EDGE) { + av_log(avctx, AV_LOG_ERROR, "Edge emulation not supported!\n"); + return AVERROR_PATCHWELCOME; + } + + dsputil_init(&s->dsp, avctx); + ff_diracdsp_init(&s->diracdsp); + + return 0; +} + +static void dirac_decode_flush(AVCodecContext *avctx) +{ + DiracContext *s = avctx->priv_data; + free_sequence_buffers(s); + s->seen_sequence_header = 0; + s->frame_number = -1; +} + +static av_cold int dirac_decode_end(AVCodecContext *avctx) +{ + dirac_decode_flush(avctx); + return 0; +} + +#define SIGN_CTX(x) (CTX_SIGN_ZERO + ((x) > 0) - ((x) < 0)) + +static inline void coeff_unpack_arith(DiracArith *c, int qfactor, int qoffset, + SubBand *b, IDWTELEM *buf, int x, int y) +{ + int coeff, sign; + int sign_pred = 0; + int pred_ctx = CTX_ZPZN_F1; + + /* Check if the parent subband has a 0 in the corresponding position */ + if (b->parent) + pred_ctx += !!b->parent->ibuf[b->parent->stride * (y>>1) + (x>>1)] << 1; + + if (b->orientation == subband_hl) + sign_pred = buf[-b->stride]; + + /* Determine if the pixel has only zeros in its neighbourhood */ + if (x) { + pred_ctx += !(buf[-1] | buf[-b->stride] | buf[-1-b->stride]); + if (b->orientation == subband_lh) + sign_pred = buf[-1]; + } else { + pred_ctx += !buf[-b->stride]; + } + + coeff = dirac_get_arith_uint(c, pred_ctx, CTX_COEFF_DATA); + if (coeff) { + coeff = (coeff * qfactor + qoffset + 2) >> 2; + sign = dirac_get_arith_bit(c, SIGN_CTX(sign_pred)); + coeff = (coeff ^ -sign) + sign; + } + *buf = coeff; +} + +static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset) +{ + int sign, coeff; + + coeff = svq3_get_ue_golomb(gb); + if (coeff) { + coeff = (coeff * qfactor + qoffset + 2) >> 2; + sign = get_bits1(gb); + coeff = (coeff ^ -sign) + sign; + } + return coeff; +} + +/** + * Decode the coeffs in the rectangle defined by left, right, top, bottom + * [DIRAC_STD] 13.4.3.2 Codeblock unpacking loop. codeblock() + */ +static inline void codeblock(DiracContext *s, SubBand *b, + GetBitContext *gb, DiracArith *c, + int left, int right, int top, int bottom, + int blockcnt_one, int is_arith) +{ + int x, y, zero_block; + int qoffset, qfactor; + IDWTELEM *buf; + + /* check for any coded coefficients in this codeblock */ + if (!blockcnt_one) { + if (is_arith) + zero_block = dirac_get_arith_bit(c, CTX_ZERO_BLOCK); + else + zero_block = get_bits1(gb); + + if (zero_block) + return; + } + + if (s->codeblock_mode && !(s->old_delta_quant && blockcnt_one)) { + int quant = b->quant; + if (is_arith) + quant += dirac_get_arith_int(c, CTX_DELTA_Q_F, CTX_DELTA_Q_DATA); + else + quant += dirac_get_se_golomb(gb); + if (quant < 0) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid quant\n"); + return; + } + b->quant = quant; + } + + b->quant = FFMIN(b->quant, MAX_QUANT); + + qfactor = qscale_tab[b->quant]; + /* TODO: context pointer? */ + if (!s->num_refs) + qoffset = qoffset_intra_tab[b->quant]; + else + qoffset = qoffset_inter_tab[b->quant]; + + buf = b->ibuf + top * b->stride; + for (y = top; y < bottom; y++) { + for (x = left; x < right; x++) { + /* [DIRAC_STD] 13.4.4 Subband coefficients. coeff_unpack() */ + if (is_arith) + coeff_unpack_arith(c, qfactor, qoffset, b, buf+x, x, y); + else + buf[x] = coeff_unpack_golomb(gb, qfactor, qoffset); + } + buf += b->stride; + } +} + +/** + * Dirac Specification -> + * 13.3 intra_dc_prediction(band) + */ +static inline void intra_dc_prediction(SubBand *b) +{ + IDWTELEM *buf = b->ibuf; + int x, y; + + for (x = 1; x < b->width; x++) + buf[x] += buf[x-1]; + buf += b->stride; + + for (y = 1; y < b->height; y++) { + buf[0] += buf[-b->stride]; + + for (x = 1; x < b->width; x++) { + int pred = buf[x - 1] + buf[x - b->stride] + buf[x - b->stride-1]; + buf[x] += divide3(pred); + } + buf += b->stride; + } +} + +/** + * Dirac Specification -> + * 13.4.2 Non-skipped subbands. subband_coeffs() + */ +static av_always_inline void decode_subband_internal(DiracContext *s, SubBand *b, int is_arith) +{ + int cb_x, cb_y, left, right, top, bottom; + DiracArith c; + GetBitContext gb; + int cb_width = s->codeblock[b->level + (b->orientation != subband_ll)].width; + int cb_height = s->codeblock[b->level + (b->orientation != subband_ll)].height; + int blockcnt_one = (cb_width + cb_height) == 2; + + if (!b->length) + return; + + init_get_bits(&gb, b->coeff_data, b->length*8); + + if (is_arith) + ff_dirac_init_arith_decoder(&c, &gb, b->length); + + top = 0; + for (cb_y = 0; cb_y < cb_height; cb_y++) { + bottom = (b->height * (cb_y+1)) / cb_height; + left = 0; + for (cb_x = 0; cb_x < cb_width; cb_x++) { + right = (b->width * (cb_x+1)) / cb_width; + codeblock(s, b, &gb, &c, left, right, top, bottom, blockcnt_one, is_arith); + left = right; + } + top = bottom; + } + + if (b->orientation == subband_ll && s->num_refs == 0) + intra_dc_prediction(b); +} + +static int decode_subband_arith(AVCodecContext *avctx, void *b) +{ + DiracContext *s = avctx->priv_data; + decode_subband_internal(s, b, 1); + return 0; +} + +static int decode_subband_golomb(AVCodecContext *avctx, void *arg) +{ + DiracContext *s = avctx->priv_data; + SubBand **b = arg; + decode_subband_internal(s, *b, 0); + return 0; +} + +/** + * Dirac Specification -> + * [DIRAC_STD] 13.4.1 core_transform_data() + */ +static void decode_component(DiracContext *s, int comp) +{ + AVCodecContext *avctx = s->avctx; + SubBand *bands[3*MAX_DWT_LEVELS+1]; + enum dirac_subband orientation; + int level, num_bands = 0; + + /* Unpack all subbands at all levels. */ + for (level = 0; level < s->wavelet_depth; level++) { + for (orientation = !!level; orientation < 4; orientation++) { + SubBand *b = &s->plane[comp].band[level][orientation]; + bands[num_bands++] = b; + + align_get_bits(&s->gb); + /* [DIRAC_STD] 13.4.2 subband() */ + b->length = svq3_get_ue_golomb(&s->gb); + if (b->length) { + b->quant = svq3_get_ue_golomb(&s->gb); + align_get_bits(&s->gb); + b->coeff_data = s->gb.buffer + get_bits_count(&s->gb)/8; + b->length = FFMIN(b->length, get_bits_left(&s->gb)/8); + skip_bits_long(&s->gb, b->length*8); + } + } + /* arithmetic coding has inter-level dependencies, so we can only execute one level at a time */ + if (s->is_arith) + avctx->execute(avctx, decode_subband_arith, &s->plane[comp].band[level][!!level], + NULL, 4-!!level, sizeof(SubBand)); + } + /* golomb coding has no inter-level dependencies, so we can execute all subbands in parallel */ + if (!s->is_arith) + avctx->execute(avctx, decode_subband_golomb, bands, NULL, num_bands, sizeof(SubBand*)); +} + +/* [DIRAC_STD] 13.5.5.2 Luma slice subband data. luma_slice_band(level,orient,sx,sy) --> if b2 == NULL */ +/* [DIRAC_STD] 13.5.5.3 Chroma slice subband data. chroma_slice_band(level,orient,sx,sy) --> if b2 != NULL */ +static void lowdelay_subband(DiracContext *s, GetBitContext *gb, int quant, + int slice_x, int slice_y, int bits_end, + SubBand *b1, SubBand *b2) +{ + int left = b1->width * slice_x / s->lowdelay.num_x; + int right = b1->width *(slice_x+1) / s->lowdelay.num_x; + int top = b1->height * slice_y / s->lowdelay.num_y; + int bottom = b1->height *(slice_y+1) / s->lowdelay.num_y; + + int qfactor = qscale_tab[FFMIN(quant, MAX_QUANT)]; + int qoffset = qoffset_intra_tab[FFMIN(quant, MAX_QUANT)]; + + IDWTELEM *buf1 = b1->ibuf + top * b1->stride; + IDWTELEM *buf2 = b2 ? b2->ibuf + top * b2->stride : NULL; + int x, y; + /* we have to constantly check for overread since the spec explictly + requires this, with the meaning that all remaining coeffs are set to 0 */ + if (get_bits_count(gb) >= bits_end) + return; + + for (y = top; y < bottom; y++) { + for (x = left; x < right; x++) { + buf1[x] = coeff_unpack_golomb(gb, qfactor, qoffset); + if (get_bits_count(gb) >= bits_end) + return; + if (buf2) { + buf2[x] = coeff_unpack_golomb(gb, qfactor, qoffset); + if (get_bits_count(gb) >= bits_end) + return; + } + } + buf1 += b1->stride; + if (buf2) + buf2 += b2->stride; + } +} + +struct lowdelay_slice { + GetBitContext gb; + int slice_x; + int slice_y; + int bytes; +}; + + +/** + * Dirac Specification -> + * 13.5.2 Slices. slice(sx,sy) + */ +static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg) +{ + DiracContext *s = avctx->priv_data; + struct lowdelay_slice *slice = arg; + GetBitContext *gb = &slice->gb; + enum dirac_subband orientation; + int level, quant, chroma_bits, chroma_end; + + int quant_base = get_bits(gb, 7); /*[DIRAC_STD] qindex */ + int length_bits = av_log2(8 * slice->bytes)+1; + int luma_bits = get_bits_long(gb, length_bits); + int luma_end = get_bits_count(gb) + FFMIN(luma_bits, get_bits_left(gb)); + + /* [DIRAC_STD] 13.5.5.2 luma_slice_band */ + for (level = 0; level < s->wavelet_depth; level++) + for (orientation = !!level; orientation < 4; orientation++) { + quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0); + lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, luma_end, + &s->plane[0].band[level][orientation], NULL); + } + + /* consume any unused bits from luma */ + skip_bits_long(gb, get_bits_count(gb) - luma_end); + + chroma_bits = 8*slice->bytes - 7 - length_bits - luma_bits; + chroma_end = get_bits_count(gb) + FFMIN(chroma_bits, get_bits_left(gb)); + /* [DIRAC_STD] 13.5.5.3 chroma_slice_band */ + for (level = 0; level < s->wavelet_depth; level++) + for (orientation = !!level; orientation < 4; orientation++) { + quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0); + lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, chroma_end, + &s->plane[1].band[level][orientation], + &s->plane[2].band[level][orientation]); + } + + return 0; +} + +/** + * Dirac Specification -> + * 13.5.1 low_delay_transform_data() + */ +static void decode_lowdelay(DiracContext *s) +{ + AVCodecContext *avctx = s->avctx; + int slice_x, slice_y, bytes, bufsize; + const uint8_t *buf; + struct lowdelay_slice *slices; + int slice_num = 0; + + slices = av_mallocz(s->lowdelay.num_x * s->lowdelay.num_y * sizeof(struct lowdelay_slice)); + + align_get_bits(&s->gb); + /*[DIRAC_STD] 13.5.2 Slices. slice(sx,sy) */ + buf = s->gb.buffer + get_bits_count(&s->gb)/8; + bufsize = get_bits_left(&s->gb); + + for (slice_y = 0; bufsize > 0 && slice_y < s->lowdelay.num_y; slice_y++) + for (slice_x = 0; bufsize > 0 && slice_x < s->lowdelay.num_x; slice_x++) { + bytes = (slice_num+1) * s->lowdelay.bytes.num / s->lowdelay.bytes.den + - slice_num * s->lowdelay.bytes.num / s->lowdelay.bytes.den; + + slices[slice_num].bytes = bytes; + slices[slice_num].slice_x = slice_x; + slices[slice_num].slice_y = slice_y; + init_get_bits(&slices[slice_num].gb, buf, bufsize); + slice_num++; + + buf += bytes; + bufsize -= bytes*8; + } + + avctx->execute(avctx, decode_lowdelay_slice, slices, NULL, slice_num, + sizeof(struct lowdelay_slice)); /* [DIRAC_STD] 13.5.2 Slices */ + intra_dc_prediction(&s->plane[0].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */ + intra_dc_prediction(&s->plane[1].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */ + intra_dc_prediction(&s->plane[2].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */ + av_free(slices); +} + +static void init_planes(DiracContext *s) +{ + int i, w, h, level, orientation; + + for (i = 0; i < 3; i++) { + Plane *p = &s->plane[i]; + + p->width = s->source.width >> (i ? s->chroma_x_shift : 0); + p->height = s->source.height >> (i ? s->chroma_y_shift : 0); + p->idwt_width = w = CALC_PADDING(p->width , s->wavelet_depth); + p->idwt_height = h = CALC_PADDING(p->height, s->wavelet_depth); + p->idwt_stride = FFALIGN(p->idwt_width, 8); + + for (level = s->wavelet_depth-1; level >= 0; level--) { + w = w>>1; + h = h>>1; + for (orientation = !!level; orientation < 4; orientation++) { + SubBand *b = &p->band[level][orientation]; + + b->ibuf = p->idwt_buf; + b->level = level; + b->stride = p->idwt_stride << (s->wavelet_depth - level); + b->width = w; + b->height = h; + b->orientation = orientation; + + if (orientation & 1) + b->ibuf += w; + if (orientation > 1) + b->ibuf += b->stride>>1; + + if (level) + b->parent = &p->band[level-1][orientation]; + } + } + + if (i > 0) { + p->xblen = s->plane[0].xblen >> s->chroma_x_shift; + p->yblen = s->plane[0].yblen >> s->chroma_y_shift; + p->xbsep = s->plane[0].xbsep >> s->chroma_x_shift; + p->ybsep = s->plane[0].ybsep >> s->chroma_y_shift; + } + + p->xoffset = (p->xblen - p->xbsep)/2; + p->yoffset = (p->yblen - p->ybsep)/2; + } +} + +/** + * Unpack the motion compensation parameters + * Dirac Specification -> + * 11.2 Picture prediction data. picture_prediction() + */ +static int dirac_unpack_prediction_parameters(DiracContext *s) +{ + static const uint8_t default_blen[] = { 4, 12, 16, 24 }; + static const uint8_t default_bsep[] = { 4, 8, 12, 16 }; + + GetBitContext *gb = &s->gb; + unsigned idx, ref; + + align_get_bits(gb); + /* [DIRAC_STD] 11.2.2 Block parameters. block_parameters() */ + /* Luma and Chroma are equal. 11.2.3 */ + idx = svq3_get_ue_golomb(gb); /* [DIRAC_STD] index */ + + if (idx > 4) { + av_log(s->avctx, AV_LOG_ERROR, "Block prediction index too high\n"); + return -1; + } + + if (idx == 0) { + s->plane[0].xblen = svq3_get_ue_golomb(gb); + s->plane[0].yblen = svq3_get_ue_golomb(gb); + s->plane[0].xbsep = svq3_get_ue_golomb(gb); + s->plane[0].ybsep = svq3_get_ue_golomb(gb); + } else { + /*[DIRAC_STD] preset_block_params(index). Table 11.1 */ + s->plane[0].xblen = default_blen[idx-1]; + s->plane[0].yblen = default_blen[idx-1]; + s->plane[0].xbsep = default_bsep[idx-1]; + s->plane[0].ybsep = default_bsep[idx-1]; + } + /*[DIRAC_STD] 11.2.4 motion_data_dimensions() + Calculated in function dirac_unpack_block_motion_data */ + + if (s->plane[0].xbsep < s->plane[0].xblen/2 || s->plane[0].ybsep < s->plane[0].yblen/2) { + av_log(s->avctx, AV_LOG_ERROR, "Block separation too small\n"); + return -1; + } + if (s->plane[0].xbsep > s->plane[0].xblen || s->plane[0].ybsep > s->plane[0].yblen) { + av_log(s->avctx, AV_LOG_ERROR, "Block seperation greater than size\n"); + return -1; + } + if (FFMAX(s->plane[0].xblen, s->plane[0].yblen) > MAX_BLOCKSIZE) { + av_log(s->avctx, AV_LOG_ERROR, "Unsupported large block size\n"); + return -1; + } + + /*[DIRAC_STD] 11.2.5 Motion vector precision. motion_vector_precision() + Read motion vector precision */ + s->mv_precision = svq3_get_ue_golomb(gb); + if (s->mv_precision > 3) { + av_log(s->avctx, AV_LOG_ERROR, "MV precision finer than eighth-pel\n"); + return -1; + } + + /*[DIRAC_STD] 11.2.6 Global motion. global_motion() + Read the global motion compensation parameters */ + s->globalmc_flag = get_bits1(gb); + if (s->globalmc_flag) { + memset(s->globalmc, 0, sizeof(s->globalmc)); + /* [DIRAC_STD] pan_tilt(gparams) */ + for (ref = 0; ref < s->num_refs; ref++) { + if (get_bits1(gb)) { + s->globalmc[ref].pan_tilt[0] = dirac_get_se_golomb(gb); + s->globalmc[ref].pan_tilt[1] = dirac_get_se_golomb(gb); + } + /* [DIRAC_STD] zoom_rotate_shear(gparams) + zoom/rotation/shear parameters */ + if (get_bits1(gb)) { + s->globalmc[ref].zrs_exp = svq3_get_ue_golomb(gb); + s->globalmc[ref].zrs[0][0] = dirac_get_se_golomb(gb); + s->globalmc[ref].zrs[0][1] = dirac_get_se_golomb(gb); + s->globalmc[ref].zrs[1][0] = dirac_get_se_golomb(gb); + s->globalmc[ref].zrs[1][1] = dirac_get_se_golomb(gb); + } else { + s->globalmc[ref].zrs[0][0] = 1; + s->globalmc[ref].zrs[1][1] = 1; + } + /* [DIRAC_STD] perspective(gparams) */ + if (get_bits1(gb)) { + s->globalmc[ref].perspective_exp = svq3_get_ue_golomb(gb); + s->globalmc[ref].perspective[0] = dirac_get_se_golomb(gb); + s->globalmc[ref].perspective[1] = dirac_get_se_golomb(gb); + } + } + } + + /*[DIRAC_STD] 11.2.7 Picture prediction mode. prediction_mode() + Picture prediction mode, not currently used. */ + if (svq3_get_ue_golomb(gb)) { + av_log(s->avctx, AV_LOG_ERROR, "Unknown picture prediction mode\n"); + return -1; + } + + /* [DIRAC_STD] 11.2.8 Reference picture weight. reference_picture_weights() + just data read, weight calculation will be done later on. */ + s->weight_log2denom = 1; + s->weight[0] = 1; + s->weight[1] = 1; + + if (get_bits1(gb)) { + s->weight_log2denom = svq3_get_ue_golomb(gb); + s->weight[0] = dirac_get_se_golomb(gb); + if (s->num_refs == 2) + s->weight[1] = dirac_get_se_golomb(gb); + } + return 0; +} + +/** + * Dirac Specification -> + * 11.3 Wavelet transform data. wavelet_transform() + */ +static int dirac_unpack_idwt_params(DiracContext *s) +{ + GetBitContext *gb = &s->gb; + int i, level; + unsigned tmp; + +#define CHECKEDREAD(dst, cond, errmsg) \ + tmp = svq3_get_ue_golomb(gb); \ + if (cond) { \ + av_log(s->avctx, AV_LOG_ERROR, errmsg); \ + return -1; \ + }\ + dst = tmp; + + align_get_bits(gb); + + s->zero_res = s->num_refs ? get_bits1(gb) : 0; + if (s->zero_res) + return 0; + + /*[DIRAC_STD] 11.3.1 Transform parameters. transform_parameters() */ + CHECKEDREAD(s->wavelet_idx, tmp > 6, "wavelet_idx is too big\n") + + CHECKEDREAD(s->wavelet_depth, tmp > MAX_DWT_LEVELS || tmp < 1, "invalid number of DWT decompositions\n") + + if (!s->low_delay) { + /* Codeblock paramaters (core syntax only) */ + if (get_bits1(gb)) { + for (i = 0; i <= s->wavelet_depth; i++) { + CHECKEDREAD(s->codeblock[i].width , tmp < 1, "codeblock width invalid\n") + CHECKEDREAD(s->codeblock[i].height, tmp < 1, "codeblock height invalid\n") + } + + CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n") + } else + for (i = 0; i <= s->wavelet_depth; i++) + s->codeblock[i].width = s->codeblock[i].height = 1; + } else { + /* Slice parameters + quantization matrix*/ + /*[DIRAC_STD] 11.3.4 Slice coding Parameters (low delay syntax only). slice_parameters() */ + s->lowdelay.num_x = svq3_get_ue_golomb(gb); + s->lowdelay.num_y = svq3_get_ue_golomb(gb); + s->lowdelay.bytes.num = svq3_get_ue_golomb(gb); + s->lowdelay.bytes.den = svq3_get_ue_golomb(gb); + + /* [DIRAC_STD] 11.3.5 Quantisation matrices (low-delay syntax). quant_matrix() */ + if (get_bits1(gb)) { + av_log(s->avctx,AV_LOG_DEBUG,"Low Delay: Has Custom Quantization Matrix!\n"); + /* custom quantization matrix */ + s->lowdelay.quant[0][0] = svq3_get_ue_golomb(gb); + for (level = 0; level < s->wavelet_depth; level++) { + s->lowdelay.quant[level][1] = svq3_get_ue_golomb(gb); + s->lowdelay.quant[level][2] = svq3_get_ue_golomb(gb); + s->lowdelay.quant[level][3] = svq3_get_ue_golomb(gb); + } + } else { + /* default quantization matrix */ + for (level = 0; level < s->wavelet_depth; level++) + for (i = 0; i < 4; i++) { + s->lowdelay.quant[level][i] = default_qmat[s->wavelet_idx][level][i]; + /* haar with no shift differs for different depths */ + if (s->wavelet_idx == 3) + s->lowdelay.quant[level][i] += 4*(s->wavelet_depth-1 - level); + } + } + } + return 0; +} + +static inline int pred_sbsplit(uint8_t *sbsplit, int stride, int x, int y) +{ + static const uint8_t avgsplit[7] = { 0, 0, 1, 1, 1, 2, 2 }; + + if (!(x|y)) + return 0; + else if (!y) + return sbsplit[-1]; + else if (!x) + return sbsplit[-stride]; + + return avgsplit[sbsplit[-1] + sbsplit[-stride] + sbsplit[-stride-1]]; +} + +static inline int pred_block_mode(DiracBlock *block, int stride, int x, int y, int refmask) +{ + int pred; + + if (!(x|y)) + return 0; + else if (!y) + return block[-1].ref & refmask; + else if (!x) + return block[-stride].ref & refmask; + + /* return the majority */ + pred = (block[-1].ref & refmask) + (block[-stride].ref & refmask) + (block[-stride-1].ref & refmask); + return (pred >> 1) & refmask; +} + +static inline void pred_block_dc(DiracBlock *block, int stride, int x, int y) +{ + int i, n = 0; + + memset(block->u.dc, 0, sizeof(block->u.dc)); + + if (x && !(block[-1].ref & 3)) { + for (i = 0; i < 3; i++) + block->u.dc[i] += block[-1].u.dc[i]; + n++; + } + + if (y && !(block[-stride].ref & 3)) { + for (i = 0; i < 3; i++) + block->u.dc[i] += block[-stride].u.dc[i]; + n++; + } + + if (x && y && !(block[-1-stride].ref & 3)) { + for (i = 0; i < 3; i++) + block->u.dc[i] += block[-1-stride].u.dc[i]; + n++; + } + + if (n == 2) { + for (i = 0; i < 3; i++) + block->u.dc[i] = (block->u.dc[i]+1)>>1; + } else if (n == 3) { + for (i = 0; i < 3; i++) + block->u.dc[i] = divide3(block->u.dc[i]); + } +} + +static inline void pred_mv(DiracBlock *block, int stride, int x, int y, int ref) +{ + int16_t *pred[3]; + int refmask = ref+1; + int mask = refmask | DIRAC_REF_MASK_GLOBAL; /* exclude gmc blocks */ + int n = 0; + + if (x && (block[-1].ref & mask) == refmask) + pred[n++] = block[-1].u.mv[ref]; + + if (y && (block[-stride].ref & mask) == refmask) + pred[n++] = block[-stride].u.mv[ref]; + + if (x && y && (block[-stride-1].ref & mask) == refmask) + pred[n++] = block[-stride-1].u.mv[ref]; + + switch (n) { + case 0: + block->u.mv[ref][0] = 0; + block->u.mv[ref][1] = 0; + break; + case 1: + block->u.mv[ref][0] = pred[0][0]; + block->u.mv[ref][1] = pred[0][1]; + break; + case 2: + block->u.mv[ref][0] = (pred[0][0] + pred[1][0] + 1) >> 1; + block->u.mv[ref][1] = (pred[0][1] + pred[1][1] + 1) >> 1; + break; + case 3: + block->u.mv[ref][0] = mid_pred(pred[0][0], pred[1][0], pred[2][0]); + block->u.mv[ref][1] = mid_pred(pred[0][1], pred[1][1], pred[2][1]); + break; + } +} + +static void global_mv(DiracContext *s, DiracBlock *block, int x, int y, int ref) +{ + int ez = s->globalmc[ref].zrs_exp; + int ep = s->globalmc[ref].perspective_exp; + int (*A)[2] = s->globalmc[ref].zrs; + int *b = s->globalmc[ref].pan_tilt; + int *c = s->globalmc[ref].perspective; + + int m = (1<<ep) - (c[0]*x + c[1]*y); + int mx = m * ((A[0][0] * x + A[0][1]*y) + (1<<ez) * b[0]); + int my = m * ((A[1][0] * x + A[1][1]*y) + (1<<ez) * b[1]); + + block->u.mv[ref][0] = (mx + (1<<(ez+ep))) >> (ez+ep); + block->u.mv[ref][1] = (my + (1<<(ez+ep))) >> (ez+ep); +} + +static void decode_block_params(DiracContext *s, DiracArith arith[8], DiracBlock *block, + int stride, int x, int y) +{ + int i; + + block->ref = pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_REF1); + block->ref ^= dirac_get_arith_bit(arith, CTX_PMODE_REF1); + + if (s->num_refs == 2) { + block->ref |= pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_REF2); + block->ref ^= dirac_get_arith_bit(arith, CTX_PMODE_REF2) << 1; + } + + if (!block->ref) { + pred_block_dc(block, stride, x, y); + for (i = 0; i < 3; i++) + block->u.dc[i] += dirac_get_arith_int(arith+1+i, CTX_DC_F1, CTX_DC_DATA); + return; + } + + if (s->globalmc_flag) { + block->ref |= pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_GLOBAL); + block->ref ^= dirac_get_arith_bit(arith, CTX_GLOBAL_BLOCK) << 2; + } + + for (i = 0; i < s->num_refs; i++) + if (block->ref & (i+1)) { + if (block->ref & DIRAC_REF_MASK_GLOBAL) { + global_mv(s, block, x, y, i); + } else { + pred_mv(block, stride, x, y, i); + block->u.mv[i][0] += dirac_get_arith_int(arith + 4 + 2 * i, CTX_MV_F1, CTX_MV_DATA); + block->u.mv[i][1] += dirac_get_arith_int(arith + 5 + 2 * i, CTX_MV_F1, CTX_MV_DATA); + } + } +} + +/** + * Copies the current block to the other blocks covered by the current superblock split mode + */ +static void propagate_block_data(DiracBlock *block, int stride, int size) +{ + int x, y; + DiracBlock *dst = block; + + for (x = 1; x < size; x++) + dst[x] = *block; + + for (y = 1; y < size; y++) { + dst += stride; + for (x = 0; x < size; x++) + dst[x] = *block; + } +} + +/** + * Dirac Specification -> + * 12. Block motion data syntax + */ +static int dirac_unpack_block_motion_data(DiracContext *s) +{ + GetBitContext *gb = &s->gb; + uint8_t *sbsplit = s->sbsplit; + int i, x, y, q, p; + DiracArith arith[8]; + + align_get_bits(gb); + + /* [DIRAC_STD] 11.2.4 and 12.2.1 Number of blocks and superblocks */ + s->sbwidth = DIVRNDUP(s->source.width, 4*s->plane[0].xbsep); + s->sbheight = DIVRNDUP(s->source.height, 4*s->plane[0].ybsep); + s->blwidth = 4 * s->sbwidth; + s->blheight = 4 * s->sbheight; + + /* [DIRAC_STD] 12.3.1 Superblock splitting modes. superblock_split_modes() + decode superblock split modes */ + ff_dirac_init_arith_decoder(arith, gb, svq3_get_ue_golomb(gb)); /* svq3_get_ue_golomb(gb) is the length */ + for (y = 0; y < s->sbheight; y++) { + for (x = 0; x < s->sbwidth; x++) { + unsigned int split = dirac_get_arith_uint(arith, CTX_SB_F1, CTX_SB_DATA); + if (split > 2) + return -1; + sbsplit[x] = (split + pred_sbsplit(sbsplit+x, s->sbwidth, x, y)) % 3; + } + sbsplit += s->sbwidth; + } + + /* setup arith decoding */ + ff_dirac_init_arith_decoder(arith, gb, svq3_get_ue_golomb(gb)); + for (i = 0; i < s->num_refs; i++) { + ff_dirac_init_arith_decoder(arith + 4 + 2 * i, gb, svq3_get_ue_golomb(gb)); + ff_dirac_init_arith_decoder(arith + 5 + 2 * i, gb, svq3_get_ue_golomb(gb)); + } + for (i = 0; i < 3; i++) + ff_dirac_init_arith_decoder(arith+1+i, gb, svq3_get_ue_golomb(gb)); + + for (y = 0; y < s->sbheight; y++) + for (x = 0; x < s->sbwidth; x++) { + int blkcnt = 1 << s->sbsplit[y * s->sbwidth + x]; + int step = 4 >> s->sbsplit[y * s->sbwidth + x]; + + for (q = 0; q < blkcnt; q++) + for (p = 0; p < blkcnt; p++) { + int bx = 4 * x + p*step; + int by = 4 * y + q*step; + DiracBlock *block = &s->blmotion[by*s->blwidth + bx]; + decode_block_params(s, arith, block, s->blwidth, bx, by); + propagate_block_data(block, s->blwidth, step); + } + } + + return 0; +} + +static int weight(int i, int blen, int offset) +{ +#define ROLLOFF(i) offset == 1 ? ((i) ? 5 : 3) : \ + (1 + (6*(i) + offset - 1) / (2*offset - 1)) + + if (i < 2*offset) + return ROLLOFF(i); + else if (i > blen-1 - 2*offset) + return ROLLOFF(blen-1 - i); + return 8; +} + +static void init_obmc_weight_row(Plane *p, uint8_t *obmc_weight, int stride, + int left, int right, int wy) +{ + int x; + for (x = 0; left && x < p->xblen >> 1; x++) + obmc_weight[x] = wy*8; + for (; x < p->xblen >> right; x++) + obmc_weight[x] = wy*weight(x, p->xblen, p->xoffset); + for (; x < p->xblen; x++) + obmc_weight[x] = wy*8; + for (; x < stride; x++) + obmc_weight[x] = 0; +} + +static void init_obmc_weight(Plane *p, uint8_t *obmc_weight, int stride, + int left, int right, int top, int bottom) +{ + int y; + for (y = 0; top && y < p->yblen >> 1; y++) { + init_obmc_weight_row(p, obmc_weight, stride, left, right, 8); + obmc_weight += stride; + } + for (; y < p->yblen >> bottom; y++) { + int wy = weight(y, p->yblen, p->yoffset); + init_obmc_weight_row(p, obmc_weight, stride, left, right, wy); + obmc_weight += stride; + } + for (; y < p->yblen; y++) { + init_obmc_weight_row(p, obmc_weight, stride, left, right, 8); + obmc_weight += stride; + } +} + +static void init_obmc_weights(DiracContext *s, Plane *p, int by) +{ + int top = !by; + int bottom = by == s->blheight-1; + + /* don't bother re-initing for rows 2 to blheight-2, the weights don't change */ + if (top || bottom || by == 1) { + init_obmc_weight(p, s->obmc_weight[0], MAX_BLOCKSIZE, 1, 0, top, bottom); + init_obmc_weight(p, s->obmc_weight[1], MAX_BLOCKSIZE, 0, 0, top, bottom); + init_obmc_weight(p, s->obmc_weight[2], MAX_BLOCKSIZE, 0, 1, top, bottom); + } +} + +static const uint8_t epel_weights[4][4][4] = { + {{ 16, 0, 0, 0 }, + { 12, 4, 0, 0 }, + { 8, 8, 0, 0 }, + { 4, 12, 0, 0 }}, + {{ 12, 0, 4, 0 }, + { 9, 3, 3, 1 }, + { 6, 6, 2, 2 }, + { 3, 9, 1, 3 }}, + {{ 8, 0, 8, 0 }, + { 6, 2, 6, 2 }, + { 4, 4, 4, 4 }, + { 2, 6, 2, 6 }}, + {{ 4, 0, 12, 0 }, + { 3, 1, 9, 3 }, + { 2, 2, 6, 6 }, + { 1, 3, 3, 9 }} +}; + +/** + * For block x,y, determine which of the hpel planes to do bilinear + * interpolation from and set src[] to the location in each hpel plane + * to MC from. + * + * @return the index of the put_dirac_pixels_tab function to use + * 0 for 1 plane (fpel,hpel), 1 for 2 planes (qpel), 2 for 4 planes (qpel), and 3 for epel + */ +static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5], + int x, int y, int ref, int plane) +{ + Plane *p = &s->plane[plane]; + uint8_t **ref_hpel = s->ref_pics[ref]->hpel[plane]; + int motion_x = block->u.mv[ref][0]; + int motion_y = block->u.mv[ref][1]; + int mx, my, i, epel, nplanes = 0; + + if (plane) { + motion_x >>= s->chroma_x_shift; + motion_y >>= s->chroma_y_shift; + } + + mx = motion_x & ~(-1 << s->mv_precision); + my = motion_y & ~(-1 << s->mv_precision); + motion_x >>= s->mv_precision; + motion_y >>= s->mv_precision; + /* normalize subpel coordinates to epel */ + /* TODO: template this function? */ + mx <<= 3 - s->mv_precision; + my <<= 3 - s->mv_precision; + + x += motion_x; + y += motion_y; + epel = (mx|my)&1; + + /* hpel position */ + if (!((mx|my)&3)) { + nplanes = 1; + src[0] = ref_hpel[(my>>1)+(mx>>2)] + y*p->stride + x; + } else { + /* qpel or epel */ + nplanes = 4; + for (i = 0; i < 4; i++) + src[i] = ref_hpel[i] + y*p->stride + x; + + /* if we're interpolating in the right/bottom halves, adjust the planes as needed + we increment x/y because the edge changes for half of the pixels */ + if (mx > 4) { + src[0] += 1; + src[2] += 1; + x++; + } + if (my > 4) { + src[0] += p->stride; + src[1] += p->stride; + y++; + } + + /* hpel planes are: + [0]: F [1]: H + [2]: V [3]: C */ + if (!epel) { + /* check if we really only need 2 planes since either mx or my is + a hpel position. (epel weights of 0 handle this there) */ + if (!(mx&3)) { + /* mx == 0: average [0] and [2] + mx == 4: average [1] and [3] */ + src[!mx] = src[2 + !!mx]; + nplanes = 2; + } else if (!(my&3)) { + src[0] = src[(my>>1) ]; + src[1] = src[(my>>1)+1]; + nplanes = 2; + } + } else { + /* adjust the ordering if needed so the weights work */ + if (mx > 4) { + FFSWAP(const uint8_t *, src[0], src[1]); + FFSWAP(const uint8_t *, src[2], src[3]); + } + if (my > 4) { + FFSWAP(const uint8_t *, src[0], src[2]); + FFSWAP(const uint8_t *, src[1], src[3]); + } + src[4] = epel_weights[my&3][mx&3]; + } + } + + /* fixme: v/h _edge_pos */ + if ((unsigned)x > p->width +EDGE_WIDTH/2 - p->xblen || + (unsigned)y > p->height+EDGE_WIDTH/2 - p->yblen) { + for (i = 0; i < nplanes; i++) { + ff_emulated_edge_mc(s->edge_emu_buffer[i], src[i], p->stride, + p->xblen, p->yblen, x, y, + p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2); + src[i] = s->edge_emu_buffer[i]; + } + } + return (nplanes>>1) + epel; +} + +static void add_dc(uint16_t *dst, int dc, int stride, + uint8_t *obmc_weight, int xblen, int yblen) +{ + int x, y; + dc += 128; + + for (y = 0; y < yblen; y++) { + for (x = 0; x < xblen; x += 2) { + dst[x ] += dc * obmc_weight[x ]; + dst[x+1] += dc * obmc_weight[x+1]; + } + dst += stride; + obmc_weight += MAX_BLOCKSIZE; + } +} + +static void block_mc(DiracContext *s, DiracBlock *block, + uint16_t *mctmp, uint8_t *obmc_weight, + int plane, int dstx, int dsty) +{ + Plane *p = &s->plane[plane]; + const uint8_t *src[5]; + int idx; + + switch (block->ref&3) { + case 0: /* DC */ + add_dc(mctmp, block->u.dc[plane], p->stride, obmc_weight, p->xblen, p->yblen); + return; + case 1: + case 2: + idx = mc_subpel(s, block, src, dstx, dsty, (block->ref&3)-1, plane); + s->put_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen); + if (s->weight_func) + s->weight_func(s->mcscratch, p->stride, s->weight_log2denom, + s->weight[0] + s->weight[1], p->yblen); + break; + case 3: + idx = mc_subpel(s, block, src, dstx, dsty, 0, plane); + s->put_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen); + idx = mc_subpel(s, block, src, dstx, dsty, 1, plane); + if (s->biweight_func) { + /* fixme: +32 is a quick hack */ + s->put_pixels_tab[idx](s->mcscratch + 32, src, p->stride, p->yblen); + s->biweight_func(s->mcscratch, s->mcscratch+32, p->stride, s->weight_log2denom, + s->weight[0], s->weight[1], p->yblen); + } else + s->avg_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen); + break; + } + s->add_obmc(mctmp, s->mcscratch, p->stride, obmc_weight, p->yblen); +} + +static void mc_row(DiracContext *s, DiracBlock *block, uint16_t *mctmp, int plane, int dsty) +{ + Plane *p = &s->plane[plane]; + int x, dstx = p->xbsep - p->xoffset; + + block_mc(s, block, mctmp, s->obmc_weight[0], plane, -p->xoffset, dsty); + mctmp += p->xbsep; + + for (x = 1; x < s->blwidth-1; x++) { + block_mc(s, block+x, mctmp, s->obmc_weight[1], plane, dstx, dsty); + dstx += p->xbsep; + mctmp += p->xbsep; + } + block_mc(s, block+x, mctmp, s->obmc_weight[2], plane, dstx, dsty); +} + +static void select_dsp_funcs(DiracContext *s, int width, int height, int xblen, int yblen) +{ + int idx = 0; + if (xblen > 8) + idx = 1; + if (xblen > 16) + idx = 2; + + memcpy(s->put_pixels_tab, s->diracdsp.put_dirac_pixels_tab[idx], sizeof(s->put_pixels_tab)); + memcpy(s->avg_pixels_tab, s->diracdsp.avg_dirac_pixels_tab[idx], sizeof(s->avg_pixels_tab)); + s->add_obmc = s->diracdsp.add_dirac_obmc[idx]; + if (s->weight_log2denom > 1 || s->weight[0] != 1 || s->weight[1] != 1) { + s->weight_func = s->diracdsp.weight_dirac_pixels_tab[idx]; + s->biweight_func = s->diracdsp.biweight_dirac_pixels_tab[idx]; + } else { + s->weight_func = NULL; + s->biweight_func = NULL; + } +} + +static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, int width, int height) +{ + /* chroma allocates an edge of 8 when subsampled + which for 4:2:2 means an h edge of 16 and v edge of 8 + just use 8 for everything for the moment */ + int i, edge = EDGE_WIDTH/2; + + ref->hpel[plane][0] = ref->avframe.data[plane]; + s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */ + + /* no need for hpel if we only have fpel vectors */ + if (!s->mv_precision) + return; + + for (i = 1; i < 4; i++) { + if (!ref->hpel_base[plane][i]) + ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe.linesize[plane] + 32); + /* we need to be 16-byte aligned even for chroma */ + ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe.linesize[plane] + 16; + } + + if (!ref->interpolated[plane]) { + s->diracdsp.dirac_hpel_filter(ref->hpel[plane][1], ref->hpel[plane][2], + ref->hpel[plane][3], ref->hpel[plane][0], + ref->avframe.linesize[plane], width, height); + s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + } + ref->interpolated[plane] = 1; +} + +/** + * Dirac Specification -> + * 13.0 Transform data syntax. transform_data() + */ +static int dirac_decode_frame_internal(DiracContext *s) +{ + DWTContext d; + int y, i, comp, dsty; + + if (s->low_delay) { + /* [DIRAC_STD] 13.5.1 low_delay_transform_data() */ + for (comp = 0; comp < 3; comp++) { + Plane *p = &s->plane[comp]; + memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM)); + } + if (!s->zero_res) + decode_lowdelay(s); + } + + for (comp = 0; comp < 3; comp++) { + Plane *p = &s->plane[comp]; + uint8_t *frame = s->current_picture->avframe.data[comp]; + + /* FIXME: small resolutions */ + for (i = 0; i < 4; i++) + s->edge_emu_buffer[i] = s->edge_emu_buffer_base + i*FFALIGN(p->width, 16); + + if (!s->zero_res && !s->low_delay) + { + memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM)); + decode_component(s, comp); /* [DIRAC_STD] 13.4.1 core_transform_data() */ + } + if (ff_spatial_idwt_init2(&d, p->idwt_buf, p->idwt_width, p->idwt_height, p->idwt_stride, + s->wavelet_idx+2, s->wavelet_depth, p->idwt_tmp)) + return -1; + + if (!s->num_refs) { /* intra */ + for (y = 0; y < p->height; y += 16) { + ff_spatial_idwt_slice2(&d, y+16); /* decode */ + s->diracdsp.put_signed_rect_clamped(frame + y*p->stride, p->stride, + p->idwt_buf + y*p->idwt_stride, p->idwt_stride, p->width, 16); + } + } else { /* inter */ + int rowheight = p->ybsep*p->stride; + + select_dsp_funcs(s, p->width, p->height, p->xblen, p->yblen); + + for (i = 0; i < s->num_refs; i++) + interpolate_refplane(s, s->ref_pics[i], comp, p->width, p->height); + + memset(s->mctmp, 0, 4*p->yoffset*p->stride); + + dsty = -p->yoffset; + for (y = 0; y < s->blheight; y++) { + int h = 0, + start = FFMAX(dsty, 0); + uint16_t *mctmp = s->mctmp + y*rowheight; + DiracBlock *blocks = s->blmotion + y*s->blwidth; + + init_obmc_weights(s, p, y); + + if (y == s->blheight-1 || start+p->ybsep > p->height) + h = p->height - start; + else + h = p->ybsep - (start - dsty); + if (h < 0) + break; + + memset(mctmp+2*p->yoffset*p->stride, 0, 2*rowheight); + mc_row(s, blocks, mctmp, comp, dsty); + + mctmp += (start - dsty)*p->stride + p->xoffset; + ff_spatial_idwt_slice2(&d, start + h); /* decode */ + s->diracdsp.add_rect_clamped(frame + start*p->stride, mctmp, p->stride, + p->idwt_buf + start*p->idwt_stride, p->idwt_stride, p->width, h); + + dsty += p->ybsep; + } + } + } + + + return 0; +} + +/** + * Dirac Specification -> + * 11.1.1 Picture Header. picture_header() + */ +static int dirac_decode_picture_header(DiracContext *s) +{ + int retire, picnum; + int i, j, refnum, refdist; + GetBitContext *gb = &s->gb; + + /* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */ + picnum = s->current_picture->avframe.display_picture_number = get_bits_long(gb, 32); + + + av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum); + + /* if this is the first keyframe after a sequence header, start our + reordering from here */ + if (s->frame_number < 0) + s->frame_number = picnum; + + s->ref_pics[0] = s->ref_pics[1] = NULL; + for (i = 0; i < s->num_refs; i++) { + refnum = picnum + dirac_get_se_golomb(gb); + refdist = INT_MAX; + + /* find the closest reference to the one we want */ + /* Jordi: this is needed if the referenced picture hasn't yet arrived */ + for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++) + if (s->ref_frames[j] + && FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum) < refdist) { + s->ref_pics[i] = s->ref_frames[j]; + refdist = FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum); + } + + if (!s->ref_pics[i] || refdist) + av_log(s->avctx, AV_LOG_DEBUG, "Reference not found\n"); + + /* if there were no references at all, allocate one */ + if (!s->ref_pics[i]) + for (j = 0; j < MAX_FRAMES; j++) + if (!s->all_frames[j].avframe.data[0]) { + s->ref_pics[i] = &s->all_frames[j]; + s->avctx->get_buffer(s->avctx, &s->ref_pics[i]->avframe); + } + } + + /* retire the reference frames that are not used anymore */ + if (s->current_picture->avframe.reference) { + retire = picnum + dirac_get_se_golomb(gb); + if (retire != picnum) { + DiracFrame *retire_pic = remove_frame(s->ref_frames, retire); + + if (retire_pic) + retire_pic->avframe.reference &= DELAYED_PIC_REF; + else + av_log(s->avctx, AV_LOG_DEBUG, "Frame to retire not found\n"); + } + + /* if reference array is full, remove the oldest as per the spec */ + while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) { + av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n"); + remove_frame(s->ref_frames, s->ref_frames[0]->avframe.display_picture_number)->avframe.reference &= DELAYED_PIC_REF; + } + } + + if (s->num_refs) { + if (dirac_unpack_prediction_parameters(s)) /* [DIRAC_STD] 11.2 Picture Prediction Data. picture_prediction() */ + return -1; + if (dirac_unpack_block_motion_data(s)) /* [DIRAC_STD] 12. Block motion data syntax */ + return -1; + } + if (dirac_unpack_idwt_params(s)) /* [DIRAC_STD] 11.3 Wavelet transform data */ + return -1; + + init_planes(s); + return 0; +} + +static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *data_size) +{ + DiracFrame *out = s->delay_frames[0]; + int i, out_idx = 0; + + /* find frame with lowest picture number */ + for (i = 1; s->delay_frames[i]; i++) + if (s->delay_frames[i]->avframe.display_picture_number < out->avframe.display_picture_number) { + out = s->delay_frames[i]; + out_idx = i; + } + + for (i = out_idx; s->delay_frames[i]; i++) + s->delay_frames[i] = s->delay_frames[i+1]; + + if (out) { + out->avframe.reference ^= DELAYED_PIC_REF; + *data_size = sizeof(AVFrame); + *(AVFrame *)picture = out->avframe; + } + + return 0; +} + +/** + * Dirac Specification -> + * 9.6 Parse Info Header Syntax. parse_info() + * 4 byte start code + byte parse code + 4 byte size + 4 byte previous size + */ +#define DATA_UNIT_HEADER_SIZE 13 + +/* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3 + inside the function parse_sequence() */ +static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int size) +{ + DiracContext *s = avctx->priv_data; + DiracFrame *pic = NULL; + int i, parse_code = buf[4]; + unsigned tmp; + + if (size < DATA_UNIT_HEADER_SIZE) + return -1; + + init_get_bits(&s->gb, &buf[13], 8*(size - DATA_UNIT_HEADER_SIZE)); + + if (parse_code == pc_seq_header) { + if (s->seen_sequence_header) + return 0; + + /* [DIRAC_STD] 10. Sequence header */ + if (avpriv_dirac_parse_sequence_header(avctx, &s->gb, &s->source)) + return -1; + + avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift); + + if (alloc_sequence_buffers(s)) + return -1; + + s->seen_sequence_header = 1; + } else if (parse_code == pc_eos) { /* [DIRAC_STD] End of Sequence */ + free_sequence_buffers(s); + s->seen_sequence_header = 0; + } else if (parse_code == pc_aux_data) { + if (buf[13] == 1) { /* encoder implementation/version */ + int ver[3]; + /* versions older than 1.0.8 don't store quant delta for + subbands with only one codeblock */ + if (sscanf(buf+14, "Schroedinger %d.%d.%d", ver, ver+1, ver+2) == 3) + if (ver[0] == 1 && ver[1] == 0 && ver[2] <= 7) + s->old_delta_quant = 1; + } + } else if (parse_code & 0x8) { /* picture data unit */ + if (!s->seen_sequence_header) { + av_log(avctx, AV_LOG_DEBUG, "Dropping frame without sequence header\n"); + return -1; + } + + /* find an unused frame */ + for (i = 0; i < MAX_FRAMES; i++) + if (s->all_frames[i].avframe.data[0] == NULL) + pic = &s->all_frames[i]; + if (!pic) { + av_log(avctx, AV_LOG_ERROR, "framelist full\n"); + return -1; + } + + avcodec_get_frame_defaults(&pic->avframe); + + /* [DIRAC_STD] Defined in 9.6.1 ... */ + tmp = parse_code & 0x03; /* [DIRAC_STD] num_refs() */ + if (tmp > 2) { + av_log(avctx, AV_LOG_ERROR, "num_refs of 3\n"); + return -1; + } + s->num_refs = tmp; + s->is_arith = (parse_code & 0x48) == 0x08; /* [DIRAC_STD] using_ac() */ + s->low_delay = (parse_code & 0x88) == 0x88; /* [DIRAC_STD] is_low_delay() */ + pic->avframe.reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */ + pic->avframe.key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */ + pic->avframe.pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */ + + if (avctx->get_buffer(avctx, &pic->avframe) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + s->current_picture = pic; + s->plane[0].stride = pic->avframe.linesize[0]; + s->plane[1].stride = pic->avframe.linesize[1]; + s->plane[2].stride = pic->avframe.linesize[2]; + + /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */ + if (dirac_decode_picture_header(s)) + return -1; + + /* [DIRAC_STD] 13.0 Transform data syntax. transform_data() */ + if (dirac_decode_frame_internal(s)) + return -1; + } + return 0; +} + +static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt) +{ + DiracContext *s = avctx->priv_data; + DiracFrame *picture = data; + uint8_t *buf = pkt->data; + int buf_size = pkt->size; + int i, data_unit_size, buf_idx = 0; + + /* release unused frames */ + for (i = 0; i < MAX_FRAMES; i++) + if (s->all_frames[i].avframe.data[0] && !s->all_frames[i].avframe.reference) { + avctx->release_buffer(avctx, &s->all_frames[i].avframe); + memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated)); + } + + s->current_picture = NULL; + *data_size = 0; + + /* end of stream, so flush delayed pics */ + if (buf_size == 0) + return get_delayed_pic(s, (AVFrame *)data, data_size); + + for (;;) { + /*[DIRAC_STD] Here starts the code from parse_info() defined in 9.6 + [DIRAC_STD] PARSE_INFO_PREFIX = "BBCD" as defined in ISO/IEC 646 + BBCD start code search */ + for (; buf_idx + DATA_UNIT_HEADER_SIZE < buf_size; buf_idx++) { + if (buf[buf_idx ] == 'B' && buf[buf_idx+1] == 'B' && + buf[buf_idx+2] == 'C' && buf[buf_idx+3] == 'D') + break; + } + /* BBCD found or end of data */ + if (buf_idx + DATA_UNIT_HEADER_SIZE >= buf_size) + break; + + data_unit_size = AV_RB32(buf+buf_idx+5); + if (buf_idx + data_unit_size > buf_size || !data_unit_size) { + if(buf_idx + data_unit_size > buf_size) + av_log(s->avctx, AV_LOG_ERROR, + "Data unit with size %d is larger than input buffer, discarding\n", + data_unit_size); + buf_idx += 4; + continue; + } + /* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3 inside the function parse_sequence() */ + if (dirac_decode_data_unit(avctx, buf+buf_idx, data_unit_size)) + { + av_log(s->avctx, AV_LOG_ERROR,"Error in dirac_decode_data_unit\n"); + return -1; + } + buf_idx += data_unit_size; + } + + if (!s->current_picture) + return 0; + + if (s->current_picture->avframe.display_picture_number > s->frame_number) { + DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number); + + s->current_picture->avframe.reference |= DELAYED_PIC_REF; + + if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) { + int min_num = s->delay_frames[0]->avframe.display_picture_number; + /* Too many delayed frames, so we display the frame with the lowest pts */ + av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n"); + delayed_frame = s->delay_frames[0]; + + for (i = 1; s->delay_frames[i]; i++) + if (s->delay_frames[i]->avframe.display_picture_number < min_num) + min_num = s->delay_frames[i]->avframe.display_picture_number; + + delayed_frame = remove_frame(s->delay_frames, min_num); + add_frame(s->delay_frames, MAX_DELAY, s->current_picture); + } + + if (delayed_frame) { + delayed_frame->avframe.reference ^= DELAYED_PIC_REF; + *(AVFrame*)data = delayed_frame->avframe; + *data_size = sizeof(AVFrame); + } + } else if (s->current_picture->avframe.display_picture_number == s->frame_number) { + /* The right frame at the right time :-) */ + *(AVFrame*)data = s->current_picture->avframe; + *data_size = sizeof(AVFrame); + } + + if (*data_size) + s->frame_number = picture->avframe.display_picture_number + 1; + + return buf_idx; +} + +AVCodec ff_dirac_decoder = { + .name = "dirac", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_DIRAC, + .priv_data_size = sizeof(DiracContext), + .init = dirac_decode_init, + .close = dirac_decode_end, + .decode = dirac_decode_frame, + .capabilities = CODEC_CAP_DELAY, + .flush = dirac_decode_flush, + .long_name = NULL_IF_CONFIG_SMALL("BBC Dirac VC-2"), +}; diff --git a/libavcodec/diracdsp.c b/libavcodec/diracdsp.c new file mode 100644 index 0000000000..6cf75d8ff6 --- /dev/null +++ b/libavcodec/diracdsp.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2009 David Conrad + * + * 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 "diracdsp.h" +#include "libavcodec/x86/diracdsp_mmx.h" + +#define FILTER(src, stride) \ + ((21*((src)[ 0*stride] + (src)[1*stride]) \ + -7*((src)[-1*stride] + (src)[2*stride]) \ + +3*((src)[-2*stride] + (src)[3*stride]) \ + -1*((src)[-3*stride] + (src)[4*stride]) + 16) >> 5) + +static void dirac_hpel_filter(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, uint8_t *src, + int stride, int width, int height) +{ + int x, y; + + for (y = 0; y < height; y++) { + for (x = -3; x < width+5; x++) + dstv[x] = av_clip_uint8(FILTER(src+x, stride)); + + for (x = 0; x < width; x++) + dstc[x] = av_clip_uint8(FILTER(dstv+x, 1)); + + for (x = 0; x < width; x++) + dsth[x] = av_clip_uint8(FILTER(src+x, 1)); + + src += stride; + dsth += stride; + dstv += stride; + dstc += stride; + } +} + +#define PIXOP_BILINEAR(PFX, OP, WIDTH) \ + static void ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c(uint8_t *dst, const uint8_t *src[5], int stride, int h) \ + { \ + int x; \ + const uint8_t *s0 = src[0]; \ + const uint8_t *s1 = src[1]; \ + const uint8_t *s2 = src[2]; \ + const uint8_t *s3 = src[3]; \ + const uint8_t *w = src[4]; \ + \ + while (h--) { \ + for (x = 0; x < WIDTH; x++) { \ + OP(dst[x], (s0[x]*w[0] + s1[x]*w[1] + s2[x]*w[2] + s3[x]*w[3] + 8) >> 4); \ + } \ + \ + dst += stride; \ + s0 += stride; \ + s1 += stride; \ + s2 += stride; \ + s3 += stride; \ + } \ + } + +#define OP_PUT(dst, val) (dst) = (val) +#define OP_AVG(dst, val) (dst) = (((dst) + (val) + 1)>>1) + +PIXOP_BILINEAR(put, OP_PUT, 8) +PIXOP_BILINEAR(put, OP_PUT, 16) +PIXOP_BILINEAR(put, OP_PUT, 32) +PIXOP_BILINEAR(avg, OP_AVG, 8) +PIXOP_BILINEAR(avg, OP_AVG, 16) +PIXOP_BILINEAR(avg, OP_AVG, 32) + +#define op_scale1(x) block[x] = av_clip_uint8( (block[x]*weight + (1<<(log2_denom-1))) >> log2_denom) +#define op_scale2(x) dst[x] = av_clip_uint8( (src[x]*weights + dst[x]*weightd + (1<<(log2_denom-1))) >> log2_denom) + +#define DIRAC_WEIGHT(W) \ + static void weight_dirac_pixels ## W ## _c(uint8_t *block, int stride, int log2_denom, \ + int weight, int h) { \ + int x; \ + while (h--) { \ + for (x = 0; x < W; x++) { \ + op_scale1(x); \ + op_scale1(x+1); \ + } \ + block += stride; \ + } \ + } \ + static void biweight_dirac_pixels ## W ## _c(uint8_t *dst, uint8_t *src, int stride, int log2_denom, \ + int weightd, int weights, int h) { \ + int x; \ + while (h--) { \ + for (x = 0; x < W; x++) { \ + op_scale2(x); \ + op_scale2(x+1); \ + } \ + dst += stride; \ + src += stride; \ + } \ + } + +DIRAC_WEIGHT(8) +DIRAC_WEIGHT(16) +DIRAC_WEIGHT(32) + +#define ADD_OBMC(xblen) \ + static void add_obmc ## xblen ## _c(uint16_t *dst, const uint8_t *src, int stride, \ + const uint8_t *obmc_weight, int yblen) \ + { \ + int x; \ + while (yblen--) { \ + for (x = 0; x < xblen; x += 2) { \ + dst[x ] += src[x ] * obmc_weight[x ]; \ + dst[x+1] += src[x+1] * obmc_weight[x+1]; \ + } \ + dst += stride; \ + src += stride; \ + obmc_weight += 32; \ + } \ + } + +ADD_OBMC(8) +ADD_OBMC(16) +ADD_OBMC(32) + +static void put_signed_rect_clamped_c(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height) +{ + int x, y; + for (y = 0; y < height; y++) { + for (x = 0; x < width; x+=4) { + dst[x ] = av_clip_uint8(src[x ] + 128); + dst[x+1] = av_clip_uint8(src[x+1] + 128); + dst[x+2] = av_clip_uint8(src[x+2] + 128); + dst[x+3] = av_clip_uint8(src[x+3] + 128); + } + dst += dst_stride; + src += src_stride; + } +} + +static void add_rect_clamped_c(uint8_t *dst, const uint16_t *src, int stride, + const int16_t *idwt, int idwt_stride, + int width, int height) +{ + int x, y; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x+=2) { + dst[x ] = av_clip_uint8(((src[x ]+32)>>6) + idwt[x ]); + dst[x+1] = av_clip_uint8(((src[x+1]+32)>>6) + idwt[x+1]); + } + dst += stride; + src += stride; + idwt += idwt_stride; + } +} + +#define PIXFUNC(PFX, WIDTH) \ + c->PFX ## _dirac_pixels_tab[WIDTH>>4][0] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _c; \ + c->PFX ## _dirac_pixels_tab[WIDTH>>4][1] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l2_c; \ + c->PFX ## _dirac_pixels_tab[WIDTH>>4][2] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l4_c; \ + c->PFX ## _dirac_pixels_tab[WIDTH>>4][3] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c + +void ff_diracdsp_init(DiracDSPContext *c) +{ + c->dirac_hpel_filter = dirac_hpel_filter; + c->add_rect_clamped = add_rect_clamped_c; + c->put_signed_rect_clamped = put_signed_rect_clamped_c; + + c->add_dirac_obmc[0] = add_obmc8_c; + c->add_dirac_obmc[1] = add_obmc16_c; + c->add_dirac_obmc[2] = add_obmc32_c; + + c->weight_dirac_pixels_tab[0] = weight_dirac_pixels8_c; + c->weight_dirac_pixels_tab[1] = weight_dirac_pixels16_c; + c->weight_dirac_pixels_tab[2] = weight_dirac_pixels32_c; + c->biweight_dirac_pixels_tab[0] = biweight_dirac_pixels8_c; + c->biweight_dirac_pixels_tab[1] = biweight_dirac_pixels16_c; + c->biweight_dirac_pixels_tab[2] = biweight_dirac_pixels32_c; + + PIXFUNC(put, 8); + PIXFUNC(put, 16); + PIXFUNC(put, 32); + PIXFUNC(avg, 8); + PIXFUNC(avg, 16); + PIXFUNC(avg, 32); + + if (HAVE_MMX && HAVE_YASM) ff_diracdsp_init_mmx(c); +} diff --git a/libavcodec/diracdsp.h b/libavcodec/diracdsp.h new file mode 100644 index 0000000000..ecd12d6a68 --- /dev/null +++ b/libavcodec/diracdsp.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 David Conrad + * + * 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 AVCODEC_DIRACDSP_H +#define AVCODEC_DIRACDSP_H + +#include <stdint.h> + +typedef void (*dirac_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int h); +typedef void (*dirac_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int h); + +typedef struct { + void (*dirac_hpel_filter)(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, uint8_t *src, int stride, int width, int height); + /** + * dirac_pixels_tab[width][subpel] + * width is 2 for 32, 1 for 16, 0 for 8 + * subpel is 0 for fpel and hpel (only need to copy from the first plane in src) + * 1 if an average of the first 2 planes is needed (TODO: worth it?) + * 2 for general qpel (avg of 4) + * 3 for general epel (biweight of 4 using the weights in src[4]) + * src[0-3] is each of the hpel planes + * src[4] is the 1/8 pel weights if needed + */ + void (*put_dirac_pixels_tab[3][4])(uint8_t *dst, const uint8_t *src[5], int stride, int h); + void (*avg_dirac_pixels_tab[3][4])(uint8_t *dst, const uint8_t *src[5], int stride, int h); + + void (*put_signed_rect_clamped)(uint8_t *dst/*align 16*/, int dst_stride, const int16_t *src/*align 16*/, int src_stride, int width, int height/*mod 2*/); + void (*put_rect_clamped)(uint8_t *dst/*align 16*/, int dst_stride, const int16_t *src/*align 16*/, int src_stride, int width, int height/*mod 2*/); + void (*add_rect_clamped)(uint8_t *dst/*align 16*/, const uint16_t *src/*align 16*/, int stride, const int16_t *idwt/*align 16*/, int idwt_stride, int width, int height/*mod 2*/); + void (*add_dirac_obmc[3])(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); + + dirac_weight_func weight_dirac_pixels_tab[3]; + dirac_biweight_func biweight_dirac_pixels_tab[3]; +} DiracDSPContext; + +#define DECL_DIRAC_PIXOP(PFX, EXT) \ + void ff_ ## PFX ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h); \ + void ff_ ## PFX ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h); \ + void ff_ ## PFX ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h) + +DECL_DIRAC_PIXOP(put, c); +DECL_DIRAC_PIXOP(avg, c); +DECL_DIRAC_PIXOP(put, l2_c); +DECL_DIRAC_PIXOP(avg, l2_c); +DECL_DIRAC_PIXOP(put, l4_c); +DECL_DIRAC_PIXOP(avg, l4_c); + +void ff_diracdsp_init(DiracDSPContext *c); + +#endif /* AVCODEC_DIRACDSP_H */ diff --git a/libavcodec/dnxhd_parser.c b/libavcodec/dnxhd_parser.c index 870fed4a11..819632cc16 100644 --- a/libavcodec/dnxhd_parser.c +++ b/libavcodec/dnxhd_parser.c @@ -2,20 +2,20 @@ * DNxHD/VC-3 parser * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dnxhddata.c b/libavcodec/dnxhddata.c index 576e85e05c..948a4c6730 100644 --- a/libavcodec/dnxhddata.c +++ b/libavcodec/dnxhddata.c @@ -2,20 +2,20 @@ * VC3/DNxHD data. * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -284,63 +284,43 @@ static const uint8_t dnxhd_1237_ac_bits[257] = { }; 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, + 3, 3, 5, 0, 7, 9, 5, 11, 13, 15, 7, 17, 19, 21, 23, 25, + 9, 11, 27, 29, 31, 33, 13, 35, 37, 39, 41, 43, 15, 45, 47, 49, + 51, 53, 55, 17, 19, 57, 59, 61, 63, 65, 67, 69, 21, 23, 25, 71, + 73, 75, 77, 79, 81, 83, 27, 29, 31, 33, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105, 35, 37, 39, 41, 43,107,109,111,113,115,117, + 119,121,123,129, 3, 45, 47, 49, 51, 53, 55,125,127, 5, 7, 9, + 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, + 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, + 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99,101,103,105, + 107,109,111,113,115,117,119,121,123,125,127,129, 57, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, + 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, +}; + +static const uint8_t dnxhd_1237_ac_flags[257] = { + 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, + 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, }; static const uint16_t dnxhd_1237_run_codes[62] = { @@ -433,63 +413,46 @@ static const uint8_t dnxhd_1238_ac_bits[257] = { }; 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, + 3, 3, 5, 7, 0, 9, 11, 5, 13, 15, 17, 7, 19, 21, 23, 9, + 25, 27, 29, 31, 33, 11, 35, 37, 39, 41, 43, 45, 13, 15, 47, 49, + 51, 53, 55, 57, 59, 17, 19, 61, 63, 65, 67, 69, 71, 73, 75, 21, + 23, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 25, 27, 29, 99, + 101,103,105,107,109,111,113,115,117,119,121,123, 31, 33, 35, 37, + 125,127,129, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, + 29, 31, 33, 39, 41, 43, 45, 47, 49, 35, 37, 39, 41, 43, 45, 47, + 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 81, 51, + 53, 55, 57, 59, 61, 77, 79, 83, 85, 87, 89, 91, 93, 95, 97, 99, + 101,103,105,107,109,111,113,115,117,119,121,123,125,127,129, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, + 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, }; /* 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_flags[257] = { + 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 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, 2, + 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, }; 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_1235_1238_1241_run_codes[62] = { @@ -582,63 +545,43 @@ static const uint8_t dnxhd_1235_1241_ac_bits[257] = { }; static const uint8_t dnxhd_1235_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_1235_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_1235_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, + 3, 3, 5, 7, 0, 9, 11, 5, 13, 15, 17, 7, 19, 21, 23, 9, + 25, 27, 29, 31, 33, 11, 35, 37, 39, 41, 43, 13, 15, 45, 47, 49, + 51, 53, 55, 57, 59, 17, 19, 61, 63, 65, 67, 69, 71, 73, 75, 77, + 21, 23, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99,101, 25, 27, + 29, 31,103,105,107,109,111,113,115,117,119,121,123,125,127, 3, + 33, 35, 37, 39,129, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, + 27, 29, 31, 33, 35, 41, 43, 45, 47, 49, 37, 39, 41, 43, 45, 47, + 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, + 81, 83, 85, 51, 53, 55, 57, 59, 61, 63, 65, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, + 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, +}; + +static const uint8_t dnxhd_1235_1241_ac_flags[257] = { + 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 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, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, }; static const uint8_t dnxhd_1235_1241_run[62] = { @@ -709,61 +652,42 @@ static const uint8_t dnxhd_1250_ac_bits[257] = { 16 }; static const uint8_t dnxhd_1250_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, 23, 24, 25, - 26, 27, 28, 29, 7, 8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 9, 10, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 11, - 12, 13, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, - 3, 4, 5, 14, 15, 16, 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 18, 19, 20, 21, - 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, 55, 56, 22, 23, 24, - 25, 26, 27, 54, 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_1250_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, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 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, 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, 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, 0, 0, 0, 1, 1, 1, 1, + 3, 3, 5, 7, 0, 9, 11, 5, 13, 15, 17, 7, 19, 21, 23, 9, + 25, 27, 29, 31, 33, 11, 35, 37, 39, 41, 43, 45, 13, 47, 49, 51, + 53, 55, 57, 59, 15, 17, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, + 19, 21, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99,101,103,105, 23, + 25, 27,107,109,111,113,115,117,119,121,123,125,127,129, 3, 5, + 7, 9, 11, 29, 31, 33, 35, 13, 15, 17, 19, 21, 23, 25, 27, 29, + 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 37, 39, 41, 43, + 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, + 87, 89, 91, 93, 95, 97, 99,101,103,105,107,111,113, 45, 47, 49, + 51, 53, 55,109,115,117,119,121,123,125,127,129, 57, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, + 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129 +}; +static const uint8_t dnxhd_1250_ac_flags[257] = { + 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 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, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 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_1250_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, 1, 1, - 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, 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, 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 2, 2, + 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, }; static const uint16_t dnxhd_1250_run_codes[62] = { 0, 4, 5, 12, 26, 27, 28, 58, @@ -853,63 +777,43 @@ static const uint8_t dnxhd_1251_ac_bits[257] = { }; 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, + 3, 3, 5, 7, 0, 9, 11, 5, 13, 15, 17, 7, 19, 21, 23, 9, + 25, 27, 29, 31, 33, 11, 35, 37, 39, 41, 43, 13, 45, 47, 49, 51, + 53, 55, 57, 59, 15, 17, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, + 81, 19, 21, 23, 83, 85, 87, 89, 91, 93, 95, 97, 99,101,103,105, + 25, 27, 29,107,109,111,113,115,117,119,121,123,125,127,129, 3, + 5, 7, 9, 11, 13, 15, 17, 31, 33, 35, 19, 21, 23, 25, 27, 29, + 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 37, + 39, 41, 43, 45, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, + 85, 87, 89, 91, 93, 95, 97, 99,101,103,105,107,109,111,113,115, + 117, 47, 49, 51, 53, 55, 57,119,121,123,125,127,129, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, + 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, +}; + +static const uint8_t dnxhd_1251_ac_flags[257] = { + 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, + 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, }; static const uint16_t dnxhd_1251_run_codes[62] = { @@ -1002,134 +906,114 @@ static const uint8_t dnxhd_1252_ac_bits[257] = { }; 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, + 3, 3, 5, 7, 5, 0, 9, 11, 13, 15, 7, 17, 19, 21, 23, 25, + 27, 29, 9, 11, 31, 33, 35, 37, 13, 39, 41, 43, 45, 47, 49, 15, + 17, 51, 53, 55, 57, 59, 61, 63, 65, 19, 21, 67, 69, 71, 73, 75, + 77, 79, 81, 83, 23, 25, 27, 85, 87, 89, 91, 93, 95, 97, 99,101, + 103,105,107, 29, 31, 33,109,111,113,115,117,119,121,123,125,127, + 129, 3, 5, 7, 35, 37, 39, 41, 9, 11, 13, 15, 17, 19, 21, 23, + 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 43, 45, 47, 49, 51, 45, + 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, + 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99,101,103,105,107,109, + 111,113,115,117,119,121,123,125,127,129, 53, 55, 57, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, + 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, + 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127, + 129, +}; + +static const uint8_t dnxhd_1252_ac_flags[257] = { + 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, }; const CIDEntry ff_dnxhd_cid_table[] = { - { 1235, 1920, 1080, 0, 917504, 917504, 6, 10, + { 1235, 1920, 1080, 0, 917504, 917504, 6, 10, 4, dnxhd_1235_luma_weight, dnxhd_1235_chroma_weight, dnxhd_1235_1241_dc_codes, dnxhd_1235_1241_dc_bits, dnxhd_1235_1241_ac_codes, dnxhd_1235_1241_ac_bits, dnxhd_1235_1241_ac_level, - dnxhd_1235_1241_ac_run_flag, dnxhd_1235_1241_ac_index_flag, + dnxhd_1235_1241_ac_flags, dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1235_1241_run, { 175, 185, 365, 440 } }, - { 1237, 1920, 1080, 0, 606208, 606208, 4, 8, + { 1237, 1920, 1080, 0, 606208, 606208, 4, 8, 3, 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_ac_flags, dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, { 115, 120, 145, 240, 290 } }, - { 1238, 1920, 1080, 0, 917504, 917504, 4, 8, + { 1238, 1920, 1080, 0, 917504, 917504, 4, 8, 4, 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_ac_flags, dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1238_run, { 175, 185, 220, 365, 440 } }, - { 1241, 1920, 1080, 1, 917504, 458752, 6, 10, + { 1241, 1920, 1080, 1, 917504, 458752, 6, 10, 4, dnxhd_1241_luma_weight, dnxhd_1241_chroma_weight, dnxhd_1235_1241_dc_codes, dnxhd_1235_1241_dc_bits, dnxhd_1235_1241_ac_codes, dnxhd_1235_1241_ac_bits, dnxhd_1235_1241_ac_level, - dnxhd_1235_1241_ac_run_flag, dnxhd_1235_1241_ac_index_flag, + dnxhd_1235_1241_ac_flags, dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1235_1241_run, { 185, 220 } }, - { 1242, 1920, 1080, 1, 606208, 303104, 4, 8, + { 1242, 1920, 1080, 1, 606208, 303104, 4, 8, 3, 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_ac_flags, dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, { 120, 145 } }, - { 1243, 1920, 1080, 1, 917504, 458752, 4, 8, + { 1243, 1920, 1080, 1, 917504, 458752, 4, 8, 4, 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_ac_flags, dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1238_run, { 185, 220 } }, - { 1250, 1280, 720, 0, 458752, 458752, 6, 10, + { 1250, 1280, 720, 0, 458752, 458752, 6, 10, 4, dnxhd_1250_luma_weight, dnxhd_1250_chroma_weight, dnxhd_1250_dc_codes, dnxhd_1250_dc_bits, dnxhd_1250_ac_codes, dnxhd_1250_ac_bits, dnxhd_1250_ac_level, - dnxhd_1250_ac_run_flag, dnxhd_1250_ac_index_flag, + dnxhd_1250_ac_flags, dnxhd_1250_run_codes, dnxhd_1250_run_bits, dnxhd_1250_run, { 90, 180, 220 } }, - { 1251, 1280, 720, 0, 458752, 458752, 4, 8, + { 1251, 1280, 720, 0, 458752, 458752, 4, 8, 4, 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_ac_flags, dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run, { 90, 110, 175, 220 } }, - { 1252, 1280, 720, 0, 303104, 303104, 4, 8, + { 1252, 1280, 720, 0, 303104, 303104, 4, 8, 5, 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_ac_flags, dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run, { 60, 75, 115, 145 } }, - { 1253, 1920, 1080, 0, 188416, 188416, 4, 8, + { 1253, 1920, 1080, 0, 188416, 188416, 4, 8, 3, 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_ac_flags, dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run, { 36, 45, 75, 90 } }, }; diff --git a/libavcodec/dnxhddata.h b/libavcodec/dnxhddata.h index 74cf0b522f..6e774b5c88 100644 --- a/libavcodec/dnxhddata.h +++ b/libavcodec/dnxhddata.h @@ -2,20 +2,20 @@ * VC3/DNxHD decoder. * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -33,11 +33,12 @@ typedef struct { unsigned int coding_unit_size; int index_bits; int bit_depth; + int eob_index; 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 uint8_t *ac_flags; const uint16_t *run_codes; const uint8_t *run_bits, *run; int bit_rates[5]; ///< Helpher to choose variants, rounded to nearest 5Mb/s diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 956196ce64..79f27e5162 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -5,20 +5,20 @@ * * 10 bit support added by MirriAd Ltd, Joseph Artsimovich <joseph@mirriad.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -30,6 +30,7 @@ #include "get_bits.h" #include "dnxhddata.h" #include "dsputil.h" +#include "thread.h" typedef struct DNXHDContext { AVCodecContext *avctx; @@ -49,6 +50,9 @@ typedef struct DNXHDContext { int bit_depth; // 8, 10 or 0 if not initialized at all. void (*decode_dct_block)(struct DNXHDContext *ctx, DCTELEM *block, int n, int qscale); + int last_qscale; + int luma_scale[64]; + int chroma_scale[64]; } DNXHDContext; #define DNXHD_VLC_BITS 9 @@ -63,6 +67,7 @@ static av_cold int dnxhd_decode_init(AVCodecContext *avctx) ctx->avctx = avctx; avctx->coded_frame = &ctx->picture; + avcodec_get_frame_defaults(&ctx->picture); ctx->picture.type = AV_PICTURE_TYPE_I; ctx->picture.key_frame = 1; return 0; @@ -185,16 +190,22 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx, int level_bias, int level_shift) { - int i, j, index1, index2, len; + int i, j, index1, index2, len, flags; int level, component, sign; + const int *scale; const uint8_t *weight_matrix; + const uint8_t *ac_level = ctx->cid_table->ac_level; + const uint8_t *ac_flags = ctx->cid_table->ac_flags; + const int eob_index = ctx->cid_table->eob_index; OPEN_READER(bs, &ctx->gb); if (n&2) { component = 1 + (n&1); + scale = ctx->chroma_scale; weight_matrix = ctx->cid_table->chroma_weight; } else { component = 0; + scale = ctx->luma_scale; weight_matrix = ctx->cid_table->luma_weight; } @@ -210,33 +221,32 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx, block[0] = ctx->last_dc[component]; //av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]); - for (i = 1; ; i++) { - UPDATE_CACHE(bs, &ctx->gb); - GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table, - DNXHD_VLC_BITS, 2); - //av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index1); - level = ctx->cid_table->ac_level[index1]; - if (!level) { /* EOB */ - //av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n"); - break; - } + i = 0; + + UPDATE_CACHE(bs, &ctx->gb); + GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table, + DNXHD_VLC_BITS, 2); + + while (index1 != eob_index) { + level = ac_level[index1]; + flags = ac_flags[index1]; sign = SHOW_SBITS(bs, &ctx->gb, 1); SKIP_BITS(bs, &ctx->gb, 1); - if (ctx->cid_table->ac_index_flag[index1]) { - level += SHOW_UBITS(bs, &ctx->gb, index_bits) << 6; + if (flags & 1) { + level += SHOW_UBITS(bs, &ctx->gb, index_bits) << 7; SKIP_BITS(bs, &ctx->gb, index_bits); } - if (ctx->cid_table->ac_run_flag[index1]) { + if (flags & 2) { UPDATE_CACHE(bs, &ctx->gb); GET_VLC(index2, bs, &ctx->gb, ctx->run_vlc.table, DNXHD_VLC_BITS, 2); i += ctx->cid_table->run[index2]; } - if (i > 63) { + if (++i > 63) { av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i); break; } @@ -244,13 +254,17 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx, 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, weight %d\n", level, weight_matrix[i]); - level = (2*level+1) * qscale * weight_matrix[i]; + level *= scale[i]; if (level_bias < 32 || weight_matrix[i] != level_bias) level += level_bias; level >>= level_shift; //av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level); block[j] = (level^sign) - sign; + + UPDATE_CACHE(bs, &ctx->gb); + GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table, + DNXHD_VLC_BITS, 2); } CLOSE_READER(bs, &ctx->gb); @@ -281,6 +295,14 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y) skip_bits1(&ctx->gb); //av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale); + if (qscale != ctx->last_qscale) { + for (i = 0; i < 64; i++) { + ctx->luma_scale[i] = qscale * ctx->cid_table->luma_weight[i]; + ctx->chroma_scale[i] = qscale * ctx->cid_table->chroma_weight[i]; + } + ctx->last_qscale = qscale; + } + for (i = 0; i < 8; i++) { ctx->dsp.clear_block(ctx->blocks[i]); ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale); @@ -344,6 +366,7 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, DNXHDContext *ctx = avctx->priv_data; AVFrame *picture = data; int first_field = 1; + int ret; av_dlog(avctx, "frame size %d\n", buf_size); @@ -364,10 +387,10 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (first_field) { if (ctx->picture.data[0]) - avctx->release_buffer(avctx, &ctx->picture); - if (avctx->get_buffer(avctx, &ctx->picture) < 0) { + ff_thread_release_buffer(avctx, &ctx->picture); + if ((ret = ff_thread_get_buffer(avctx, &ctx->picture)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } } @@ -390,7 +413,7 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx) DNXHDContext *ctx = avctx->priv_data; if (ctx->picture.data[0]) - avctx->release_buffer(avctx, &ctx->picture); + ff_thread_release_buffer(avctx, &ctx->picture); free_vlc(&ctx->ac_vlc); free_vlc(&ctx->dc_vlc); free_vlc(&ctx->run_vlc); @@ -405,6 +428,6 @@ AVCodec ff_dnxhd_decoder = { .init = dnxhd_decode_init, .close = dnxhd_decode_close, .decode = dnxhd_decode_frame, - .capabilities = CODEC_CAP_DR1, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), }; diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 2b7089b946..8045da2399 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -6,20 +6,20 @@ * VC-3 encoder funded by the British Broadcasting Corporation * 10 bit support added by MirriAd Ltd, Joseph Artsimovich <joseph@mirriad.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -32,6 +32,7 @@ #include "mpegvideo.h" #include "mpegvideo_common.h" #include "dnxhdenc.h" +#include "internal.h" #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM #define DNX10BIT_QMAT_SHIFT 18 // The largest value that will not lead to overflow for 10bit samples. @@ -77,7 +78,7 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block, int n, int qscale, int *overflow) { const uint8_t *scantable= ctx->intra_scantable.scantable; - const int *qmat = ctx->q_intra_matrix[qscale]; + const int *qmat = n<4 ? ctx->q_intra_matrix[qscale] : ctx->q_chroma_intra_matrix[qscale]; int last_non_zero = 0; int i; @@ -122,9 +123,9 @@ static int dnxhd_init_vlc(DNXHDEncContext *ctx) alevel -= offset<<6; } for (j = 0; j < 257; j++) { - if (ctx->cid_table->ac_level[j] == alevel && - (!offset || (ctx->cid_table->ac_index_flag[j] && offset)) && - (!run || (ctx->cid_table->ac_run_flag [j] && run))) { + if (ctx->cid_table->ac_level[j] >> 1 == alevel && + (!offset || (ctx->cid_table->ac_flags[j] & 1) && offset) && + (!run || (ctx->cid_table->ac_flags[j] & 2) && run)) { assert(!ctx->vlc_codes[index]); if (alevel) { ctx->vlc_codes[index] = (ctx->cid_table->ac_codes[j]<<1)|(sign&1); @@ -208,6 +209,11 @@ static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) } } + ctx->m.q_chroma_intra_matrix16 = ctx->qmatrix_c16; + ctx->m.q_chroma_intra_matrix = ctx->qmatrix_c; + ctx->m.q_intra_matrix16 = ctx->qmatrix_l16; + ctx->m.q_intra_matrix = ctx->qmatrix_l; + return 0; fail: return -1; @@ -497,15 +503,8 @@ static av_always_inline void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, in 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; - } + const static uint8_t component[8]={0,0,1,2,0,0,1,2}; + return component[i]; } static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) @@ -535,7 +534,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, i int n = dnxhd_switch_matrix(ctx, i); memcpy(block, src_block, 64*sizeof(*block)); - last_index = ctx->m.dct_quantize(&ctx->m, block, i, qscale, &overflow); + last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow); ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index); diff = block[0] - ctx->m.last_dc[n]; @@ -581,8 +580,7 @@ static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, int jobnr, int for (i = 0; i < 8; i++) { DCTELEM *block = ctx->blocks[i]; int overflow, n = dnxhd_switch_matrix(ctx, i); - int last_index = ctx->m.dct_quantize(&ctx->m, block, i, - qscale, &overflow); + int last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow); //START_TIMER; dnxhd_encode_block(ctx, block, last_index, n); //STOP_TIMER("encode_block"); @@ -993,6 +991,11 @@ static int dnxhd_encode_end(AVCodecContext *avctx) return 0; } +static const AVCodecDefault dnxhd_defaults[] = { + { "qmax", "1024" }, /* Maximum quantization scale factor allowed for VC-3 */ + { NULL }, +}; + AVCodec ff_dnxhd_encoder = { .name = "dnxhd", .type = AVMEDIA_TYPE_VIDEO, @@ -1005,4 +1008,5 @@ AVCodec ff_dnxhd_encoder = { .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_YUV422P10, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"), .priv_class = &class, + .defaults = dnxhd_defaults, }; diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h index 861546a54c..279a978cd3 100644 --- a/libavcodec/dnxhdenc.h +++ b/libavcodec/dnxhdenc.h @@ -4,20 +4,20 @@ * * VC-3 encoder funded by the British Broadcasting Corporation * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -84,8 +84,6 @@ typedef struct DNXHDEncContext { unsigned qscale; unsigned lambda; - unsigned thread_size; - uint16_t *mb_bits; uint8_t *mb_qscale; diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 1b0f6b005b..8240221076 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -2,20 +2,20 @@ * Assorted DPCM codecs * Copyright (c) 2003 The ffmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -205,9 +205,12 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } + if (out % s->channels) { + av_log(avctx, AV_LOG_WARNING, "channels have differing number of samples\n"); + } /* get output buffer */ - s->frame.nb_samples = out / s->channels; + s->frame.nb_samples = (out + s->channels - 1) / s->channels; if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c index 156f1deaa4..8a30ca6dff 100644 --- a/libavcodec/dpx.c +++ b/libavcodec/dpx.c @@ -2,20 +2,20 @@ * DPX (.dpx) image decoder * Copyright (c) 2009 Jimmy Christensen * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -140,11 +140,11 @@ static int decode_frame(AVCodecContext *avctx, case 12: case 16: if (endian) { - avctx->pix_fmt = PIX_FMT_RGB48BE; + avctx->pix_fmt = elements == 4 ? PIX_FMT_RGBA64BE : PIX_FMT_RGB48BE; } else { - avctx->pix_fmt = PIX_FMT_RGB48LE; + avctx->pix_fmt = elements == 4 ? PIX_FMT_RGBA64LE : PIX_FMT_RGB48LE; } - target_packet_size = 6; + target_packet_size = source_packet_size = elements * 2; break; default: diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c index 1ff9d97fae..de32e4e959 100644 --- a/libavcodec/dpxenc.c +++ b/libavcodec/dpxenc.c @@ -2,20 +2,20 @@ * DPX (.dpx) image encoder * Copyright (c) 2011 Peter Ross <pross@xvid.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -53,6 +53,12 @@ static av_cold int encode_init(AVCodecContext *avctx) case PIX_FMT_RGB48BE: s->bits_per_component = avctx->bits_per_raw_sample ? avctx->bits_per_raw_sample : 16; break; + case PIX_FMT_RGBA64LE: + s->big_endian = 0; + case PIX_FMT_RGBA64BE: + s->descriptor = 51; + s->bits_per_component = 16; + break; default: av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n"); return -1; @@ -73,8 +79,7 @@ do { \ else AV_WL32(p, value); \ } while(0) -static void encode_rgb48_10bit(AVCodecContext *avctx, const AVPicture *pic, - uint8_t *dst) +static void encode_rgb48_10bit(AVCodecContext *avctx, const AVPicture *pic, uint8_t *dst) { DPXContext *s = avctx->priv_data; const uint8_t *src = pic->data[0]; @@ -99,8 +104,7 @@ static void encode_rgb48_10bit(AVCodecContext *avctx, const AVPicture *pic, } } -static int encode_frame(AVCodecContext *avctx, unsigned char *buf, - int buf_size, void *data) +static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data) { DPXContext *s = avctx->priv_data; int size; @@ -117,7 +121,9 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, memcpy (buf + 8, "V1.0", 4); write32(buf + 20, 1); /* new image */ write32(buf + 24, HEADER_SIZE); - memcpy (buf + 160, LIBAVCODEC_IDENT, FFMIN(sizeof(LIBAVCODEC_IDENT), 100)); + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + memcpy (buf + 160, LIBAVCODEC_IDENT, FFMIN(sizeof(LIBAVCODEC_IDENT), 100)); + } write32(buf + 660, 0xFFFFFFFF); /* unencrypted */ /* Image information header */ @@ -135,7 +141,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, write32(buf + 1628, avctx->sample_aspect_ratio.num); write32(buf + 1632, avctx->sample_aspect_ratio.den); - switch (s->bits_per_component) { + switch(s->bits_per_component) { case 8: case 16: size = avpicture_layout(data, avctx->pix_fmt, @@ -173,6 +179,8 @@ AVCodec ff_dpx_encoder = { PIX_FMT_RGBA, PIX_FMT_RGB48LE, PIX_FMT_RGB48BE, + PIX_FMT_RGBA64LE, + PIX_FMT_RGBA64BE, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("DPX image"), }; diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 37d39f5405..4c6c41c2fe 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -2,20 +2,20 @@ * Delphine Software International CIN Audio/Video Decoders * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -95,6 +95,7 @@ static av_cold int cinvideo_decode_init(AVCodecContext *avctx) cin->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&cin->frame); cin->frame.data[0] = NULL; cin->bitmap_size = avctx->width * avctx->height; @@ -223,12 +224,12 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, if (palette_colors_count > 256) return AVERROR_INVALIDDATA; for (i = 0; i < palette_colors_count; ++i) { - cin->palette[i] = bytestream_get_le24(&buf); + cin->palette[i] = 0xFF << 24 | bytestream_get_le24(&buf); bitmap_frame_size -= 3; } } else { for (i = 0; i < palette_colors_count; ++i) { - cin->palette[buf[0]] = AV_RL24(buf+1); + cin->palette[buf[0]] = 0xFF << 24 | AV_RL24(buf+1); buf += 4; bitmap_frame_size -= 4; } diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 9f282416d4..dfa526a5cb 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -5,20 +5,20 @@ * * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -38,6 +38,7 @@ #include "config.h" #include "ac3dec.h" #include "vorbis.h" +#include "diracdsp.h" uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; uint32_t ff_squareTbl[512] = {0, }; @@ -1328,6 +1329,51 @@ void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){ } #endif /* CONFIG_RV40_DECODER */ +#if CONFIG_DIRAC_DECODER +#define DIRAC_MC(OPNAME)\ +void ff_ ## OPNAME ## _dirac_pixels8_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_8_c(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_8_c(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_8_c(dst , src[0] , stride, h);\ + OPNAME ## _pixels16_8_c(dst+16, src[0]+16, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels8_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_l2_8(dst, src[0], src[1], stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l2_8(dst, src[0], src[1], stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l2_8(dst , src[0] , src[1] , stride, stride, stride, h);\ + OPNAME ## _pixels16_l2_8(dst+16, src[0]+16, src[1]+16, stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels8_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_l4_8(dst, src[0], src[1], src[2], src[3], stride, stride, stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l4_8(dst, src[0], src[1], src[2], src[3], stride, stride, stride, stride, stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_l4_8(dst , src[0] , src[1] , src[2] , src[3] , stride, stride, stride, stride, stride, h);\ + OPNAME ## _pixels16_l4_8(dst+16, src[0]+16, src[1]+16, src[2]+16, src[3]+16, stride, stride, stride, stride, stride, h);\ +} +DIRAC_MC(put) +DIRAC_MC(avg) +#endif + 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; int i; @@ -2775,7 +2821,7 @@ int ff_check_alignment(void){ "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. You may try recompiling using gcc >= 4.2.\n" - "Do not report crashes to Libav developers.\n"); + "Do not report crashes to FFmpeg developers.\n"); #endif did_fail=1; } diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index 786a0effcb..3584a49a04 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -133,7 +133,7 @@ void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, /* minimum alignment rules ;) If you notice errors in the align stuff, need more alignment for some ASM code for some CPU or need to use a function with less aligned data then send a mail -to the libav-devel mailing list, ... +to the ffmpeg-devel mailing list, ... !warning These alignments might not match reality, (missing attribute((align)) stuff somewhere possible). @@ -387,6 +387,7 @@ typedef struct DSPContext { void (*add_hfyu_median_prediction)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top); int (*add_hfyu_left_prediction)(uint8_t *dst, const uint8_t *src, int w, int left); void (*add_hfyu_left_prediction_bgr32)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue, int *alpha); + /* this might write to dst[w] */ void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w); void (*bswap16_buf)(uint16_t *dst, const uint16_t *src, int len); diff --git a/libavcodec/dsputil_template.c b/libavcodec/dsputil_template.c index 72ed6bfd2a..85d4fec7dc 100644 --- a/libavcodec/dsputil_template.c +++ b/libavcodec/dsputil_template.c @@ -5,20 +5,20 @@ * * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -79,10 +79,10 @@ static inline void FUNC(copy_block16)(uint8_t *dst, const uint8_t *src, int dstS /* draw the edges of width 'w' of an image of size width, height */ //FIXME check that this is ok for mpeg4 interlaced -static void FUNCC(draw_edges)(uint8_t *_buf, int _wrap, int width, int height, int w, int h, int sides) +static void FUNCC(draw_edges)(uint8_t *p_buf, int p_wrap, int width, int height, int w, int h, int sides) { - pixel *buf = (pixel*)_buf; - int wrap = _wrap / sizeof(pixel); + pixel *buf = (pixel*)p_buf; + int wrap = p_wrap / sizeof(pixel); pixel *ptr, *last_line; int i; @@ -484,12 +484,12 @@ static inline void FUNC(OPNAME ## _no_rnd_pixels16_l4)(uint8_t *dst, const uint8 FUNC(OPNAME ## _no_rnd_pixels8_l4)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), src3+8*sizeof(pixel), src4+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ }\ \ -static inline void FUNCC(OPNAME ## _pixels2_xy2)(uint8_t *_block, const uint8_t *_pixels, int line_size, int h)\ +static inline void FUNCC(OPNAME ## _pixels2_xy2)(uint8_t *p_block, const uint8_t *p_pixels, int line_size, int h)\ {\ int i, a0, b0, a1, b1;\ - pixel *block = (pixel*)_block;\ - const pixel *pixels = (const pixel*)_pixels;\ - line_size /= sizeof(pixel);\ + pixel *block = (pixel*)p_block;\ + const pixel *pixels = (const pixel*)p_pixels;\ + line_size >>= sizeof(pixel)-1;\ a0= pixels[0];\ b0= pixels[1] + 2;\ a0 += b0;\ @@ -670,15 +670,15 @@ static void FUNCC(put_no_rnd_pixels8_l2)(uint8_t *dst, const uint8_t *a, const u } #define H264_CHROMA_MC(OPNAME, OP)\ -static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ +static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *p_dst/*align 8*/, uint8_t *p_src/*align 1*/, int stride, int h, int x, int y){\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ const int A=(8-x)*(8-y);\ const int B=( x)*(8-y);\ const int C=(8-x)*( y);\ const int D=( x)*( y);\ int i;\ - stride /= sizeof(pixel);\ + stride >>= sizeof(pixel)-1;\ \ assert(x<8 && y<8 && x>=0 && y>=0);\ \ @@ -701,15 +701,15 @@ static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst/*align 8*/, uint8_t * }\ }\ \ -static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ +static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *p_dst/*align 8*/, uint8_t *p_src/*align 1*/, int stride, int h, int x, int y){\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ const int A=(8-x)*(8-y);\ const int B=( x)*(8-y);\ const int C=(8-x)*( y);\ const int D=( x)*( y);\ int i;\ - stride /= sizeof(pixel);\ + stride >>= sizeof(pixel)-1;\ \ assert(x<8 && y<8 && x>=0 && y>=0);\ \ @@ -736,15 +736,15 @@ static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst/*align 8*/, uint8_t * }\ }\ \ -static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ +static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *p_dst/*align 8*/, uint8_t *p_src/*align 1*/, int stride, int h, int x, int y){\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ const int A=(8-x)*(8-y);\ const int B=( x)*(8-y);\ const int C=(8-x)*( y);\ const int D=( x)*( y);\ int i;\ - stride /= sizeof(pixel);\ + stride >>= sizeof(pixel)-1;\ \ assert(x<8 && y<8 && x>=0 && y>=0);\ \ @@ -788,14 +788,14 @@ H264_CHROMA_MC(avg_ , op_avg) #undef op_put #define H264_LOWPASS(OPNAME, OP, OP2) \ -static av_unused void FUNC(OPNAME ## h264_qpel2_h_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int srcStride){\ +static av_unused void FUNC(OPNAME ## h264_qpel2_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\ const int h=2;\ INIT_CLIP\ int i;\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ - dstStride /= sizeof(pixel);\ - srcStride /= sizeof(pixel);\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ + dstStride >>= sizeof(pixel)-1;\ + srcStride >>= sizeof(pixel)-1;\ for(i=0; i<h; i++)\ {\ OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\ @@ -805,14 +805,14 @@ static av_unused void FUNC(OPNAME ## h264_qpel2_h_lowpass)(uint8_t *_dst, uint8_ }\ }\ \ -static av_unused void FUNC(OPNAME ## h264_qpel2_v_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int srcStride){\ +static av_unused void FUNC(OPNAME ## h264_qpel2_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\ const int w=2;\ INIT_CLIP\ int i;\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ - dstStride /= sizeof(pixel);\ - srcStride /= sizeof(pixel);\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ + dstStride >>= sizeof(pixel)-1;\ + srcStride >>= sizeof(pixel)-1;\ for(i=0; i<w; i++)\ {\ const int srcB= src[-2*srcStride];\ @@ -829,16 +829,16 @@ static av_unused void FUNC(OPNAME ## h264_qpel2_v_lowpass)(uint8_t *_dst, uint8_ }\ }\ \ -static av_unused void FUNC(OPNAME ## h264_qpel2_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_src, int dstStride, int tmpStride, int srcStride){\ +static av_unused void FUNC(OPNAME ## h264_qpel2_hv_lowpass)(uint8_t *p_dst, int16_t *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\ const int h=2;\ const int w=2;\ const int pad = (BIT_DEPTH > 9) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\ INIT_CLIP\ int i;\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ - dstStride /= sizeof(pixel);\ - srcStride /= sizeof(pixel);\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ + dstStride >>= sizeof(pixel)-1;\ + srcStride >>= sizeof(pixel)-1;\ src -= 2*srcStride;\ for(i=0; i<h+5; i++)\ {\ @@ -863,14 +863,14 @@ static av_unused void FUNC(OPNAME ## h264_qpel2_hv_lowpass)(uint8_t *_dst, int16 tmp++;\ }\ }\ -static void FUNC(OPNAME ## h264_qpel4_h_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int srcStride){\ +static void FUNC(OPNAME ## h264_qpel4_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\ const int h=4;\ INIT_CLIP\ int i;\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ - dstStride /= sizeof(pixel);\ - srcStride /= sizeof(pixel);\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ + dstStride >>= sizeof(pixel)-1;\ + srcStride >>= sizeof(pixel)-1;\ for(i=0; i<h; i++)\ {\ OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\ @@ -882,14 +882,14 @@ static void FUNC(OPNAME ## h264_qpel4_h_lowpass)(uint8_t *_dst, uint8_t *_src, i }\ }\ \ -static void FUNC(OPNAME ## h264_qpel4_v_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int srcStride){\ +static void FUNC(OPNAME ## h264_qpel4_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\ const int w=4;\ INIT_CLIP\ int i;\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ - dstStride /= sizeof(pixel);\ - srcStride /= sizeof(pixel);\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ + dstStride >>= sizeof(pixel)-1;\ + srcStride >>= sizeof(pixel)-1;\ for(i=0; i<w; i++)\ {\ const int srcB= src[-2*srcStride];\ @@ -910,16 +910,16 @@ static void FUNC(OPNAME ## h264_qpel4_v_lowpass)(uint8_t *_dst, uint8_t *_src, i }\ }\ \ -static void FUNC(OPNAME ## h264_qpel4_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_src, int dstStride, int tmpStride, int srcStride){\ +static void FUNC(OPNAME ## h264_qpel4_hv_lowpass)(uint8_t *p_dst, int16_t *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\ const int h=4;\ const int w=4;\ const int pad = (BIT_DEPTH > 9) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\ INIT_CLIP\ int i;\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ - dstStride /= sizeof(pixel);\ - srcStride /= sizeof(pixel);\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ + dstStride >>= sizeof(pixel)-1;\ + srcStride >>= sizeof(pixel)-1;\ src -= 2*srcStride;\ for(i=0; i<h+5; i++)\ {\ @@ -951,14 +951,14 @@ static void FUNC(OPNAME ## h264_qpel4_hv_lowpass)(uint8_t *_dst, int16_t *tmp, u }\ }\ \ -static void FUNC(OPNAME ## h264_qpel8_h_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int srcStride){\ +static void FUNC(OPNAME ## h264_qpel8_h_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\ const int h=8;\ INIT_CLIP\ int i;\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ - dstStride /= sizeof(pixel);\ - srcStride /= sizeof(pixel);\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ + dstStride >>= sizeof(pixel)-1;\ + srcStride >>= sizeof(pixel)-1;\ for(i=0; i<h; i++)\ {\ OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]));\ @@ -974,14 +974,14 @@ static void FUNC(OPNAME ## h264_qpel8_h_lowpass)(uint8_t *_dst, uint8_t *_src, i }\ }\ \ -static void FUNC(OPNAME ## h264_qpel8_v_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int srcStride){\ +static void FUNC(OPNAME ## h264_qpel8_v_lowpass)(uint8_t *p_dst, uint8_t *p_src, int dstStride, int srcStride){\ const int w=8;\ INIT_CLIP\ int i;\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ - dstStride /= sizeof(pixel);\ - srcStride /= sizeof(pixel);\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ + dstStride >>= sizeof(pixel)-1;\ + srcStride >>= sizeof(pixel)-1;\ for(i=0; i<w; i++)\ {\ const int srcB= src[-2*srcStride];\ @@ -1010,16 +1010,16 @@ static void FUNC(OPNAME ## h264_qpel8_v_lowpass)(uint8_t *_dst, uint8_t *_src, i }\ }\ \ -static void FUNC(OPNAME ## h264_qpel8_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_src, int dstStride, int tmpStride, int srcStride){\ +static void FUNC(OPNAME ## h264_qpel8_hv_lowpass)(uint8_t *p_dst, int16_t *tmp, uint8_t *p_src, int dstStride, int tmpStride, int srcStride){\ const int h=8;\ const int w=8;\ const int pad = (BIT_DEPTH > 9) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\ INIT_CLIP\ int i;\ - pixel *dst = (pixel*)_dst;\ - pixel *src = (pixel*)_src;\ - dstStride /= sizeof(pixel);\ - srcStride /= sizeof(pixel);\ + pixel *dst = (pixel*)p_dst;\ + pixel *src = (pixel*)p_src;\ + dstStride >>= sizeof(pixel)-1;\ + srcStride >>= sizeof(pixel)-1;\ src -= 2*srcStride;\ for(i=0; i<h+5; i++)\ {\ @@ -1277,3 +1277,4 @@ void FUNCC(ff_put_pixels16x16)(uint8_t *dst, uint8_t *src, int stride) { void FUNCC(ff_avg_pixels16x16)(uint8_t *dst, uint8_t *src, int stride) { FUNCC(avg_pixels16)(dst, src, stride, 16); } + diff --git a/libavcodec/dump_extradata_bsf.c b/libavcodec/dump_extradata_bsf.c index ba77b15c6b..9499d6d8d8 100644 --- a/libavcodec/dump_extradata_bsf.c +++ b/libavcodec/dump_extradata_bsf.c @@ -1,20 +1,20 @@ /* * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dv.c b/libavcodec/dv.c index 74cbffb672..413d50fb0d 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -16,20 +16,20 @@ * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth * of DV technical info. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -774,7 +774,7 @@ static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, i method suggested in SMPTE 314M Table 22, and an improved method. The SMPTE method is very conservative; it assigns class 3 (i.e. severe quantization) to any block where the largest AC - component is greater than 36. Libav's DV encoder tracks AC bit + component is greater than 36. FFmpeg's DV encoder tracks AC bit consumption precisely, so there is no need to bias most blocks towards strongly lossy compression. Instead, we assign class 2 to most blocks, and use class 3 only when strictly necessary @@ -782,7 +782,7 @@ static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, i #if 0 /* SMPTE spec method */ static const int classes[] = {12, 24, 36, 0xffff}; -#else /* improved Libav method */ +#else /* improved FFmpeg method */ static const int classes[] = {-1, -1, 255, 0xffff}; #endif int max = classes[0]; @@ -1071,7 +1071,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, const uint8_t* vsc_pack; int apt, is16_9; - s->sys = avpriv_dv_frame_profile(s->sys, buf, buf_size); + s->sys = avpriv_dv_frame_profile2(avctx, s->sys, buf, buf_size); if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys)) { av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n"); return -1; /* NOTE: we only accept several full frames */ @@ -1080,6 +1080,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, if (s->picture.data[0]) avctx->release_buffer(avctx, &s->picture); + avcodec_get_frame_defaults(&s->picture); s->picture.reference = 0; s->picture.key_frame = 1; s->picture.pict_type = AV_PICTURE_TYPE_I; @@ -1107,7 +1108,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, vsc_pack = buf + 80*5 + 48 + 5; if ( *vsc_pack == dv_video_control ) { apt = buf[4] & 0x07; - is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07))); + is16_9 = (vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07); avctx->sample_aspect_ratio = s->sys->sar[is16_9]; } diff --git a/libavcodec/dv_tablegen.c b/libavcodec/dv_tablegen.c index f463550365..5d3793e11d 100644 --- a/libavcodec/dv_tablegen.c +++ b/libavcodec/dv_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dv_tablegen.h b/libavcodec/dv_tablegen.h index 4fa8d91374..678be73940 100644 --- a/libavcodec/dv_tablegen.h +++ b/libavcodec/dv_tablegen.h @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dv_vlc_data.h b/libavcodec/dv_vlc_data.h index b5c1ddecb4..c23c564613 100644 --- a/libavcodec/dv_vlc_data.h +++ b/libavcodec/dv_vlc_data.h @@ -2,20 +2,20 @@ * VLC constants for DV codec * Copyright (c) 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dvbsub.c b/libavcodec/dvbsub.c index 4788d50cfe..301fc93207 100644 --- a/libavcodec/dvbsub.c +++ b/libavcodec/dvbsub.c @@ -2,20 +2,20 @@ * DVB subtitle encoding * Copyright (c) 2005 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" @@ -194,6 +194,61 @@ static void dvb_encode_rle4(uint8_t **pq, *pq = q; } +static void dvb_encode_rle8(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h) +{ + uint8_t *q; + int x, y, len, x1, f, color; + + q = *pq; + + for (y = 0; y < h; y++) { + *q++ = 0x12; + + x = 0; + f = 0; + while (x < w) { + x1 = x; + color = bitmap[x1++]; + while (x1 < w && bitmap[x1] == color) + x1++; + len = x1 - x; + if (len == 1 && color) { + // 00000001 to 11111111 1 pixel in colour x + *q++ = color; + } else { + if (color == 0x00) { + // 00000000 0LLLLLLL L pixels (1-127) in colour 0 (L > 0) + len = FFMIN(len, 127); + *q++ = 0x00; + *q++ = len; + } else if (len > 2) { + // 00000000 1LLLLLLL CCCCCCCC L pixels (3-127) in colour C (L > 2) + len = FFMIN(len, 127); + *q++ = 0x00; + *q++ = 0x80+len; + *q++ = color; + } + else if (len == 2) { + *q++ = color; + *q++ = color; + } else { + *q++ = color; + len = 1; + } + } + x += len; + } + /* end of line */ + // 00000000 00000000 end of 8-bit/pixel_code_string + *q++ = 0x00; + *q++ = 0x00; + bitmap += linesize; + } + *pq = q; +} + static int encode_dvb_subtitles(DVBSubtitleContext *s, uint8_t *outbuf, AVSubtitle *h) { @@ -245,10 +300,15 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, } else if (h->rects[clut_id]->nb_colors <= 16) { /* 4 bpp, standard encoding */ bpp_index = 1; + } else if (h->rects[clut_id]->nb_colors <= 256) { + /* 8 bpp, standard encoding */ + bpp_index = 2; } else { return -1; } + + /* CLUT segment */ *q++ = 0x0f; /* sync byte */ *q++ = 0x12; /* CLUT definition segment */ bytestream_put_be16(&q, page_id); @@ -321,18 +381,25 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, if (!s->hide_state) { for (object_id = 0; object_id < h->num_rects; object_id++) { - /* Object Data segment */ + void (*dvb_encode_rle)(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h); + /* bpp_index maths */ if (h->rects[object_id]->nb_colors <= 4) { /* 2 bpp, some decoders do not support it correctly */ - bpp_index = 0; + dvb_encode_rle = dvb_encode_rle2; } else if (h->rects[object_id]->nb_colors <= 16) { /* 4 bpp, standard encoding */ - bpp_index = 1; + dvb_encode_rle = dvb_encode_rle4; + } else if (h->rects[object_id]->nb_colors <= 256) { + /* 8 bpp, standard encoding */ + dvb_encode_rle = dvb_encode_rle8; } else { return -1; } + /* Object Data segment */ *q++ = 0x0f; /* sync byte */ *q++ = 0x13; bytestream_put_be16(&q, page_id); @@ -345,19 +412,12 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, non_modifying_color_flag */ { uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr; - void (*dvb_encode_rle)(uint8_t **pq, - const uint8_t *bitmap, int linesize, - int w, int h); + ptop_field_len = q; q += 2; pbottom_field_len = q; q += 2; - if (bpp_index == 0) - dvb_encode_rle = dvb_encode_rle2; - else - dvb_encode_rle = dvb_encode_rle4; - top_ptr = q; dvb_encode_rle(&q, h->rects[object_id]->pict.data[0], h->rects[object_id]->w * 2, h->rects[object_id]->w, h->rects[object_id]->h >> 1); diff --git a/libavcodec/dvbsub_parser.c b/libavcodec/dvbsub_parser.c index 643352888f..b2a9883eac 100644 --- a/libavcodec/dvbsub_parser.c +++ b/libavcodec/dvbsub_parser.c @@ -1,21 +1,21 @@ /* - * DVB subtitle parser for Libav + * DVB subtitle parser for FFmpeg * Copyright (c) 2005 Ian Caulfield * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c index aafc046d97..e2b4ee6193 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -2,20 +2,20 @@ * DVB subtitle decoding * Copyright (c) 2005 Ian Caulfield * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" @@ -154,6 +154,7 @@ static void png_save2(const char *filename, uint32_t *bitmap, int w, int h) typedef struct DVBSubCLUT { int id; + int version; uint32_t clut4[4]; uint32_t clut16[16]; @@ -180,6 +181,7 @@ typedef struct DVBSubObjectDisplay { typedef struct DVBSubObject { int id; + int version; int type; @@ -199,6 +201,7 @@ typedef struct DVBSubRegionDisplay { typedef struct DVBSubRegion { int id; + int version; int width; int height; @@ -209,6 +212,7 @@ typedef struct DVBSubRegion { uint8_t *pbuf; int buf_size; + int dirty; DVBSubObjectDisplay *display_list; @@ -228,6 +232,7 @@ typedef struct DVBSubContext { int composition_id; int ancillary_id; + int version; int time_out; DVBSubRegion *region_list; DVBSubCLUT *clut_list; @@ -318,21 +323,10 @@ static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region) } -static void delete_state(DVBSubContext *ctx) +static void delete_cluts(DVBSubContext *ctx) { - DVBSubRegion *region; DVBSubCLUT *clut; - while (ctx->region_list) { - region = ctx->region_list; - - ctx->region_list = region->next; - - delete_region_display_list(ctx, region); - av_free(region->pbuf); - av_free(region); - } - while (ctx->clut_list) { clut = ctx->clut_list; @@ -340,12 +334,35 @@ static void delete_state(DVBSubContext *ctx) av_free(clut); } +} - av_freep(&ctx->display_definition); +static void delete_objects(DVBSubContext *ctx) +{ + DVBSubObject *object; + + while (ctx->object_list) { + object = ctx->object_list; + + ctx->object_list = object->next; + + av_free(object); + } +} + +static void delete_regions(DVBSubContext *ctx) +{ + DVBSubRegion *region; - /* Should already be null */ - if (ctx->object_list) - av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n"); + while (ctx->region_list) { + region = ctx->region_list; + + ctx->region_list = region->next; + + delete_region_display_list(ctx, region); + + av_free(region->pbuf); + av_free(region); + } } static av_cold int dvbsub_init_decoder(AVCodecContext *avctx) @@ -362,6 +379,8 @@ static av_cold int dvbsub_init_decoder(AVCodecContext *avctx) ctx->ancillary_id = AV_RB16(avctx->extradata + 2); } + ctx->version = -1; + default_clut.id = -1; default_clut.next = NULL; @@ -430,7 +449,13 @@ static av_cold int dvbsub_close_decoder(AVCodecContext *avctx) DVBSubContext *ctx = avctx->priv_data; DVBSubRegionDisplay *display; - delete_state(ctx); + delete_regions(ctx); + + delete_objects(ctx); + + delete_cluts(ctx); + + av_freep(&ctx->display_definition); while (ctx->display_list) { display = ctx->display_list; @@ -444,16 +469,18 @@ static av_cold int dvbsub_close_decoder(AVCodecContext *avctx) static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, - int non_mod, uint8_t *map_table) + int non_mod, uint8_t *map_table, int x_pos) { GetBitContext gb; int bits; int run_length; - int pixels_read = 0; + int pixels_read = x_pos; init_get_bits(&gb, *srcbuf, buf_size << 3); + destbuf += x_pos; + while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) { bits = get_bits(&gb, 2); @@ -514,14 +541,14 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, } } } else if (bits == 1) { - pixels_read += 2; if (map_table) bits = map_table[0]; else bits = 0; - if (pixels_read <= dbuf_len) { - *destbuf++ = bits; + run_length = 2; + while (run_length-- > 0 && pixels_read < dbuf_len) { *destbuf++ = bits; + pixels_read++; } } else { (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; @@ -549,16 +576,18 @@ static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, - int non_mod, uint8_t *map_table) + int non_mod, uint8_t *map_table, int x_pos) { GetBitContext gb; int bits; int run_length; - int pixels_read = 0; + int pixels_read = x_pos; init_get_bits(&gb, *srcbuf, buf_size << 3); + destbuf += x_pos; + while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) { bits = get_bits(&gb, 4); @@ -638,14 +667,14 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, } } } else if (bits == 1) { - pixels_read += 2; if (map_table) bits = map_table[0]; else bits = 0; - if (pixels_read <= dbuf_len) { - *destbuf++ = bits; + run_length = 2; + while (run_length-- > 0 && pixels_read < dbuf_len) { *destbuf++ = bits; + pixels_read++; } } else { if (map_table) @@ -670,12 +699,14 @@ static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, - int non_mod, uint8_t *map_table) + int non_mod, uint8_t *map_table, int x_pos) { const uint8_t *sbuf_end = (*srcbuf) + buf_size; int bits; int run_length; - int pixels_read = 0; + int pixels_read = x_pos; + + destbuf += x_pos; while (*srcbuf < sbuf_end && pixels_read < dbuf_len) { bits = *(*srcbuf)++; @@ -744,6 +775,7 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; uint8_t *map_table; +#if 0 av_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size, top_bottom ? "bottom" : "top"); @@ -758,21 +790,22 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis if (i % 16) av_dlog(avctx, "\n"); +#endif if (region == 0) return; pbuf = region->pbuf; + region->dirty = 1; x_pos = display->x_pos; y_pos = display->y_pos; - if ((y_pos & 1) != top_bottom) - y_pos++; + y_pos += top_bottom; while (buf < buf_end) { - if (x_pos > region->width || y_pos > region->height) { - av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n"); + if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) { + av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf); return; } @@ -785,9 +818,9 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis else map_table = NULL; - x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos, - region->width - x_pos, &buf, buf_end - buf, - non_mod, map_table); + x_pos = dvbsub_read_2bit_string(pbuf + (y_pos * region->width), + region->width, &buf, buf_end - buf, + non_mod, map_table, x_pos); break; case 0x11: if (region->depth < 4) { @@ -800,9 +833,9 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis else map_table = NULL; - x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos, - region->width - x_pos, &buf, buf_end - buf, - non_mod, map_table); + x_pos = dvbsub_read_4bit_string(pbuf + (y_pos * region->width), + region->width, &buf, buf_end - buf, + non_mod, map_table, x_pos); break; case 0x12: if (region->depth < 8) { @@ -810,9 +843,9 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis return; } - x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos, - region->width - x_pos, &buf, buf_end - buf, - non_mod, NULL); + x_pos = dvbsub_read_8bit_string(pbuf + (y_pos * region->width), + region->width, &buf, buf_end - buf, + non_mod, NULL, x_pos); break; case 0x20: @@ -847,7 +880,6 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx, DVBSubContext *ctx = avctx->priv_data; const uint8_t *buf_end = buf + buf_size; - const uint8_t *block; int object_id; DVBSubObject *object; DVBSubObjectDisplay *display; @@ -878,7 +910,8 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx, } for (display = object->display_list; display; display = display->object_list_next) { - block = buf; + const uint8_t *block = buf; + int bfl = bottom_field_len; dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0, non_modifying_color); @@ -886,9 +919,9 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx, if (bottom_field_len > 0) block = buf + top_field_len; else - bottom_field_len = top_field_len; + bfl = top_field_len; - dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1, + dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1, non_modifying_color); } @@ -907,6 +940,7 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, const uint8_t *buf_end = buf + buf_size; int i, clut_id; + int version; DVBSubCLUT *clut; int entry_id, depth , full_range; int y, cr, cb, alpha; @@ -924,6 +958,7 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, av_dlog(avctx, "\n"); clut_id = *buf++; + version = ((*buf)>>4)&15; buf += 1; clut = get_clut(ctx, clut_id); @@ -934,11 +969,16 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, memcpy(clut, &default_clut, sizeof(DVBSubCLUT)); clut->id = clut_id; + clut->version = -1; clut->next = ctx->clut_list; ctx->clut_list = clut; } + if (clut->version != version) { + + clut->version = version; + while (buf + 4 < buf_end) { entry_id = *buf++; @@ -980,6 +1020,7 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx, if (depth & 0x20) clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha); } + } } @@ -990,6 +1031,7 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, const uint8_t *buf_end = buf + buf_size; int region_id, object_id; + int version; DVBSubRegion *region; DVBSubObject *object; DVBSubObjectDisplay *display; @@ -1006,11 +1048,13 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, region = av_mallocz(sizeof(DVBSubRegion)); region->id = region_id; + region->version = -1; region->next = ctx->region_list; ctx->region_list = region; } + version = ((*buf)>>4) & 15; fill = ((*buf++) >> 3) & 1; region->width = AV_RB16(buf); @@ -1026,6 +1070,7 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, region->pbuf = av_malloc(region->buf_size); fill = 1; + region->dirty = 0; } region->depth = 1 << (((*buf++) >> 2) & 7); @@ -1035,9 +1080,10 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx, } region->clut = *buf++; - if (region->depth == 8) + if (region->depth == 8) { region->bgcolor = *buf++; - else { + buf += 1; + } else { buf += 1; if (region->depth == 4) @@ -1104,17 +1150,27 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx, const uint8_t *buf_end = buf + buf_size; int region_id; int page_state; + int timeout; + int version; if (buf_size < 1) return; - ctx->time_out = *buf++; + timeout = *buf++; + version = ((*buf)>>4) & 15; page_state = ((*buf++) >> 2) & 3; + if (ctx->version != version) { + + ctx->time_out = timeout; + ctx->version = version; + av_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state); - if (page_state == 2) { - delete_state(ctx); + if (page_state == 1 || page_state == 2) { + delete_regions(ctx); + delete_objects(ctx); + delete_cluts(ctx); } tmp_display_list = ctx->display_list; @@ -1159,6 +1215,7 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx, av_free(display); } + } } @@ -1312,10 +1369,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, int i; int offset_x=0, offset_y=0; - sub->rects = NULL; - sub->start_display_time = 0; sub->end_display_time = ctx->time_out * 1000; - sub->format = 0; if (display_def) { offset_x = display_def->x; @@ -1328,22 +1382,24 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, sub->rects = av_mallocz(sizeof(*sub->rects) * sub->num_rects); for(i=0; i<sub->num_rects; i++) sub->rects[i] = av_mallocz(sizeof(*sub->rects[i])); - } i = 0; for (display = ctx->display_list; display; display = display->next) { region = get_region(ctx, display->region_id); - rect = sub->rects[i]; if (!region) continue; + if (!region->dirty) + continue; + + rect = sub->rects[i]; rect->x = display->x_pos + offset_x; rect->y = display->y_pos + offset_y; rect->w = region->width; rect->h = region->height; - rect->nb_colors = 16; + rect->nb_colors = (1 << region->depth); rect->type = SUBTITLE_BITMAP; rect->pict.linesize[0] = region->width; @@ -1375,7 +1431,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, } sub->num_rects = i; - + } #ifdef DEBUG save_display_set(ctx); #endif @@ -1396,6 +1452,7 @@ static int dvbsub_decode(AVCodecContext *avctx, int page_id; int segment_length; int i; + int got_segment = 0; av_dlog(avctx, "DVB sub packet:\n"); @@ -1434,20 +1491,26 @@ static int dvbsub_decode(AVCodecContext *avctx, switch (segment_type) { case DVBSUB_PAGE_SEGMENT: dvbsub_parse_page_segment(avctx, p, segment_length); + got_segment |= 1; break; case DVBSUB_REGION_SEGMENT: dvbsub_parse_region_segment(avctx, p, segment_length); + got_segment |= 2; break; case DVBSUB_CLUT_SEGMENT: dvbsub_parse_clut_segment(avctx, p, segment_length); + got_segment |= 4; break; case DVBSUB_OBJECT_SEGMENT: dvbsub_parse_object_segment(avctx, p, segment_length); + got_segment |= 8; break; case DVBSUB_DISPLAYDEFINITION_SEGMENT: dvbsub_parse_display_definition_segment(avctx, p, segment_length); + break; case DVBSUB_DISPLAY_SEGMENT: *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub); + got_segment |= 16; break; default: av_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n", @@ -1458,6 +1521,10 @@ static int dvbsub_decode(AVCodecContext *avctx, p += segment_length; } + // Some streams do not send a display segment but if we have all the other + // segments then we need no further data. + if (got_segment == 15 && sub) + *data_size = dvbsub_display_end_segment(avctx, p, 0, sub); return p - buf; } diff --git a/libavcodec/dvdata.c b/libavcodec/dvdata.c index a2d89399f5..65cbff4b1c 100644 --- a/libavcodec/dvdata.c +++ b/libavcodec/dvdata.c @@ -2,20 +2,20 @@ * Constants for DV codec * Copyright (c) 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +25,7 @@ */ #include "libavutil/rational.h" +#include "libavutil/intreadwrite.h" #include "avcodec.h" #include "dvdata.h" @@ -245,20 +246,25 @@ static const DVprofile dv_profiles[] = { } }; -const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys, +const DVprofile* avpriv_dv_frame_profile2(AVCodecContext* codec, const DVprofile *sys, const uint8_t* frame, unsigned buf_size) { - int i; + int i, dsf, stype; - int dsf = (frame[3] & 0x80) >> 7; + if(buf_size < DV_PROFILE_BYTES) + return NULL; - int stype = frame[80*5 + 48 + 3] & 0x1f; + dsf = (frame[3] & 0x80) >> 7; + stype = frame[80*5 + 48 + 3] & 0x1f; /* 576i50 25Mbps 4:1:1 is a special case */ if (dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) { return &dv_profiles[2]; } + if(codec && codec->codec_tag==AV_RL32("dvsd") && codec->width==720 && codec->height==576) + return &dv_profiles[1]; + for (i=0; i<FF_ARRAY_ELEMS(dv_profiles); i++) if (dsf == dv_profiles[i].dsf && stype == dv_profiles[i].video_stype) return &dv_profiles[i]; @@ -270,14 +276,20 @@ const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys, return NULL; } +const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys, + const uint8_t* frame, unsigned buf_size) +{ + return avpriv_dv_frame_profile2(NULL, sys, frame, buf_size); +} + const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec) { int i; for (i=0; i<FF_ARRAY_ELEMS(dv_profiles); i++) - if (codec->height == dv_profiles[i].height && - codec->pix_fmt == dv_profiles[i].pix_fmt && - codec->width == dv_profiles[i].width) + if (codec->coded_height == dv_profiles[i].height && + codec->pix_fmt == dv_profiles[i].pix_fmt && + codec->coded_width == dv_profiles[i].width) return &dv_profiles[i]; return NULL; diff --git a/libavcodec/dvdata.h b/libavcodec/dvdata.h index b2fb127ae6..557e744b8e 100644 --- a/libavcodec/dvdata.h +++ b/libavcodec/dvdata.h @@ -2,20 +2,20 @@ * Constants for DV codec * Copyright (c) 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -275,7 +275,9 @@ enum dv_pack_type { #define DV_MAX_BPM 8 const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys, - const uint8_t* frame, unsigned buf_size); + const uint8_t* frame, unsigned buf_size); +const DVprofile* avpriv_dv_frame_profile2(AVCodecContext* codec, const DVprofile *sys, + const uint8_t* frame, unsigned buf_size); const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec); static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num, diff --git a/libavcodec/dvdsub_parser.c b/libavcodec/dvdsub_parser.c index f46d1a452a..a98b8e7daa 100644 --- a/libavcodec/dvdsub_parser.c +++ b/libavcodec/dvdsub_parser.c @@ -2,20 +2,20 @@ * DVD subtitle decoding * Copyright (c) 2005 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c index ee9331cabe..f4b54396d9 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -2,20 +2,20 @@ * DVD subtitle decoding * Copyright (c) 2005 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" @@ -25,6 +25,14 @@ //#define DEBUG +typedef struct DVDSubContext +{ + uint32_t palette[16]; + int has_palette; + uint8_t colormap[4]; + uint8_t alpha[256]; +} DVDSubContext; + static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values) { uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; @@ -116,12 +124,27 @@ static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, } static void guess_palette(uint32_t *rgba_palette, - uint8_t *colormap, - uint8_t *alpha, + DVDSubContext* ctx, uint32_t subtitle_color) { + static const uint8_t level_map[4][4] = { + // this configuration (full range, lowest to highest) in tests + // seemed most common, so assume this + {0xff}, + {0x00, 0xff}, + {0x00, 0x80, 0xff}, + {0x00, 0x55, 0xaa, 0xff}, + }; uint8_t color_used[16]; int nb_opaque_colors, i, level, j, r, g, b; + uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha; + + if(ctx->has_palette) { + for(i = 0; i < 4; i++) + rgba_palette[i] = (ctx->palette[colormap[i]] & 0x00ffffff) + | ((alpha[i] * 17) << 24); + return; + } for(i = 0; i < 4; i++) rgba_palette[i] = 0; @@ -138,18 +161,18 @@ static void guess_palette(uint32_t *rgba_palette, if (nb_opaque_colors == 0) return; - j = nb_opaque_colors; + j = 0; memset(color_used, 0, 16); for(i = 0; i < 4; i++) { if (alpha[i] != 0) { if (!color_used[colormap[i]]) { - level = (0xff * j) / nb_opaque_colors; + level = level_map[nb_opaque_colors][j]; 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[colormap[i]] = (i + 1); - j--; + j++; } else { rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) | ((alpha[i] * 17) << 24); @@ -160,20 +183,19 @@ static void guess_palette(uint32_t *rgba_palette, #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a)) -static int decode_dvd_subtitles(AVSubtitle *sub_header, +static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, const uint8_t *buf, int buf_size) { int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos; int big_offsets, offset_size, is_8bit = 0; const uint8_t *yuv_palette = 0; - uint8_t colormap[4], alpha[256]; + uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha; int date; int i; int is_menu = 0; if (buf_size < 10) return -1; - memset(sub_header, 0, sizeof(*sub_header)); if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */ big_offsets = 1; @@ -326,8 +348,8 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, yuv_a_to_rgba(yuv_palette, alpha, (uint32_t*)sub_header->rects[0]->pict.data[1], 256); } else { sub_header->rects[0]->nb_colors = 4; - guess_palette((uint32_t*)sub_header->rects[0]->pict.data[1], - colormap, alpha, 0xffff00); + guess_palette((uint32_t*)sub_header->rects[0]->pict.data[1], ctx, + 0xffff00); } sub_header->rects[0]->x = x1; sub_header->rects[0]->y = y1; @@ -337,6 +359,10 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header, sub_header->rects[0]->pict.linesize[0] = w; } } + if (next_cmd_pos < cmd_pos) { + av_log(NULL, AV_LOG_ERROR, "Invalid command offset\n"); + break; + } if (next_cmd_pos == cmd_pos) break; cmd_pos = next_cmd_pos; @@ -458,12 +484,13 @@ static int dvdsub_decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { + DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AVSubtitle *sub = data; int is_menu; - is_menu = decode_dvd_subtitles(sub, buf, buf_size); + is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size); if (is_menu < 0) { no_subtitle: @@ -486,10 +513,58 @@ static int dvdsub_decode(AVCodecContext *avctx, return buf_size; } +static int dvdsub_init(AVCodecContext *avctx) +{ + DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data; + char *dataorig, *data; + + if (!avctx->extradata || !avctx->extradata_size) + return 1; + + dataorig = data = av_malloc(avctx->extradata_size+1); + if (!data) + return AVERROR(ENOMEM); + memcpy(data, avctx->extradata, avctx->extradata_size); + data[avctx->extradata_size] = '\0'; + + for(;;) { + int pos = strcspn(data, "\n\r"); + if (pos==0 && *data==0) + break; + + if (strncmp("palette:", data, 8) == 0) { + int i; + char *p = data+8; + ctx->has_palette = 1; + for(i=0;i<16;i++) { + ctx->palette[i] = strtoul(p, &p, 16); + while(*p == ',' || isspace(*p)) + p++; + } + } + + data += pos; + data += strspn(data, "\n\r"); + } + + if (ctx->has_palette) { + int i; + av_log(avctx, AV_LOG_DEBUG, "palette:"); + for(i=0;i<16;i++) + av_log(avctx, AV_LOG_DEBUG, " 0x%06x", ctx->palette[i]); + av_log(avctx, AV_LOG_DEBUG, "\n"); + } + + av_free(dataorig); + return 1; +} + AVCodec ff_dvdsub_decoder = { .name = "dvdsub", .type = AVMEDIA_TYPE_SUBTITLE, .id = CODEC_ID_DVD_SUBTITLE, + .priv_data_size = sizeof(DVDSubContext), + .init = dvdsub_init, .decode = dvdsub_decode, .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"), }; diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c index 82d0608664..b78165cd25 100644 --- a/libavcodec/dvdsubenc.c +++ b/libavcodec/dvdsubenc.c @@ -2,20 +2,20 @@ * DVD subtitle encoding * Copyright (c) 2005 Wolfram Gloger * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" diff --git a/libavcodec/dwt.c b/libavcodec/dwt.c index 2c5b56ca48..4b9cfd4ecc 100644 --- a/libavcodec/dwt.c +++ b/libavcodec/dwt.c @@ -1,37 +1,39 @@ /* * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at> + * Copyright (C) 2008 David Conrad * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavutil/attributes.h" #include "dsputil.h" #include "dwt.h" +#include "libavcodec/x86/dwt.h" void ff_slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, IDWTELEM * base_buffer) { int i; buf->base_buffer = base_buffer; - buf->line_count = line_count; - buf->line_width = line_width; - buf->data_count = max_allocated_lines; - buf->line = av_mallocz (sizeof(IDWTELEM *) * line_count); - buf->data_stack = av_malloc (sizeof(IDWTELEM *) * max_allocated_lines); + buf->line_count = line_count; + buf->line_width = line_width; + buf->data_count = 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] = av_malloc (sizeof(IDWTELEM) * line_width); @@ -45,7 +47,6 @@ IDWTELEM * ff_slice_buffer_load_line(slice_buffer * buf, int line) IDWTELEM * buffer; assert(buf->data_stack_top >= 0); -// assert(!buf->line[line]); if (buf->line[line]) return buf->line[line]; @@ -92,8 +93,8 @@ void ff_slice_buffer_destroy(slice_buffer * buf) static inline int mirror(int v, int m){ while((unsigned)v > (unsigned)m){ - v=-v; - if(v<0) v+= 2*m; + v = -v; + if(v < 0) v+= 2*m; } return v; } @@ -103,29 +104,29 @@ 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); + 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){ - dst[0] = LIFT(src[0], ((mul*2*ref[0]+add)>>shift), inverse); - dst += dst_step; - src += src_step; + dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse); + dst += dst_step; + src += src_step; } 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), + 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), + dst[w * dst_step] = + LIFT(src[w * src_step], + ((mul * 2 * ref[w * ref_step] + add) >> shift), inverse); } } @@ -135,29 +136,32 @@ 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); + 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){ - dst[0] = LIFT(src[0], ((mul*2*ref[0]+add)>>shift), inverse); - dst += dst_step; - src += src_step; + dst[0] = + LIFT(src[0], + ((mul * 2 * ref[0] + add) >> shift), + inverse); + dst += dst_step; + src += src_step; } - 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), + 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); } if(mirror_right){ - dst[w*dst_step] = - LIFT(src[w*src_step], - ((mul*2*ref[w*ref_step]+add)>>shift), + dst[w * dst_step] = + LIFT(src[w * src_step], + ((mul * 2 * ref[w * ref_step] + add) >> shift), inverse); } } @@ -168,32 +172,32 @@ 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); + 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*(src) + (ref) + add/4 + 1 + (5<<25))/(5*4) - (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; - src += src_step; + dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse); + dst += dst_step; + src += src_step; } - 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, + 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); } 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); } } static av_always_inline void @@ -201,156 +205,156 @@ 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); + 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*(src) + (ref) + add/4 + 1 + (5<<25))/(5*4) - (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[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse); dst += dst_step; src += src_step; } - 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, + 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); } 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 /* ! liftS */ static void horizontal_decompose53i(DWTELEM *b, int width){ DWTELEM temp[width]; - const int width2= width>>1; + const int width2 = width>>1; + const int w2 = (width+1)>>1; int x; - const int w2= (width+1)>>1; - for(x=0; x<width2; x++){ - temp[x ]= b[2*x ]; - temp[x+w2]= b[2*x + 1]; + 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 ]; + if(width & 1) + temp[x ] = b[2 * x ]; #if 0 { int A1,A2,A3,A4; - A2= temp[1 ]; - A4= temp[0 ]; - A1= temp[0+width2]; - A1 -= (A2 + A4)>>1; - A4 += (A1 + 1)>>1; - b[0+width2] = A1; - b[0 ] = A4; - for(x=1; x+1<width2; x+=2){ - A3= temp[x+width2]; - A4= temp[x+1 ]; - A3 -= (A2 + A4)>>1; - A2 += (A1 + A3 + 2)>>2; - b[x+width2] = A3; - b[x ] = A2; - - A1= temp[x+1+width2]; - A2= temp[x+2 ]; - A1 -= (A2 + A4)>>1; - A4 += (A1 + A3 + 2)>>2; - b[x+1+width2] = A1; - b[x+1 ] = A4; - } - A3= temp[width-1]; + A2 = temp[1 ]; + A4 = temp[0 ]; + A1 = temp[0+width2]; + A1 -= (A2 + A4) >> 1; + A4 += (A1 + 1) >> 1; + b[0 + width2] = A1; + b[0 ] = A4; + for(x = 1; x + 1 < width2; x += 2){ + A3 = temp[x + width2]; + A4 = temp[x + 1 ]; + A3 -= (A2 + A4) >> 1; + A2 += (A1 + A3 + 2) >> 2; + b[x + width2] = A3; + b[x ] = A2; + + A1 = temp[x + 1 + width2]; + A2 = temp[x + 2 ]; + A1 -= (A2 + A4) >> 1; + A4 += (A1 + A3 + 2) >> 2; + b[x + 1 + width2] = A1; + b[x + 1 ] = A4; + } + A3 = temp[width - 1]; A3 -= A2; - A2 += (A1 + A3 + 2)>>2; + A2 += (A1 + A3 + 2) >> 2; b[width -1] = A3; b[width2-1] = A2; } #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); + 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 /* 0 */ } static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ int i; - for(i=0; i<width; i++){ - b1[i] -= (b0[i] + b2[i])>>1; + for(i = 0; i < width; i++){ + b1[i] -= (b0[i] + b2[i]) >> 1; } } static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ int i; - for(i=0; i<width; i++){ - b1[i] += (b0[i] + b2[i] + 2)>>2; + for(i = 0; i < width; i++){ + b1[i] += (b0[i] + b2[i] + 2) >> 2; } } static void spatial_decompose53i(DWTELEM *buffer, int width, int height, int stride){ int y; - DWTELEM *b0= buffer + mirror(-2-1, height-1)*stride; - DWTELEM *b1= buffer + mirror(-2 , height-1)*stride; + DWTELEM *b0 = buffer + mirror(-2 - 1, height-1)*stride; + DWTELEM *b1 = buffer + mirror(-2 , height-1)*stride; - for(y=-2; y<height; y+=2){ - DWTELEM *b2= buffer + mirror(y+1, height-1)*stride; - DWTELEM *b3= buffer + mirror(y+2, height-1)*stride; + for(y = -2; y < height; y += 2){ + DWTELEM *b2 = buffer + mirror(y + 1, height-1) * stride; + DWTELEM *b3 = buffer + mirror(y + 2, height-1) * stride; - if(y+1<(unsigned)height) horizontal_decompose53i(b2, width); - if(y+2<(unsigned)height) horizontal_decompose53i(b3, width); + if(y + 1 < (unsigned)height) horizontal_decompose53i(b2, width); + if(y + 2 < (unsigned)height) horizontal_decompose53i(b3, width); - if(y+1<(unsigned)height) vertical_decompose53iH0(b1, b2, b3, width); - if(y+0<(unsigned)height) vertical_decompose53iL0(b0, b1, b2, width); + if(y + 1 < (unsigned)height) vertical_decompose53iH0(b1, b2, b3, width); + if(y + 0 < (unsigned)height) vertical_decompose53iL0(b0, b1, b2, width); - b0=b2; - b1=b3; + b0 = b2; + b1 = b3; } } static void horizontal_decompose97i(DWTELEM *b, int width){ DWTELEM temp[width]; - const int w2= (width+1)>>1; + const int w2 = (width+1)>>1; - 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); + 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); } static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ int i; - for(i=0; i<width; i++){ - b1[i] -= (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; + for(i = 0; i < width; i++){ + b1[i] -= (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS; } } static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ int i; - for(i=0; i<width; i++){ - b1[i] += (W_CM*(b0[i] + b2[i])+W_CO)>>W_CS; + for(i=0; i < width; i++){ + b1[i] += (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS; } } static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ int i; - for(i=0; i<width; i++){ + for(i = 0; i < width; i++){ #ifdef liftS - b1[i] -= (W_BM*(b0[i] + b2[i])+W_BO)>>W_BS; + b1[i] -= (W_BM * (b0[i] + b2[i]) + W_BO) >> W_BS; #else - b1[i] = (16*4*b1[i] - 4*(b0[i] + b2[i]) + W_BO*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 } } @@ -358,123 +362,122 @@ static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int w static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width){ int i; - for(i=0; i<width; i++){ - b1[i] += (W_DM*(b0[i] + b2[i])+W_DO)>>W_DS; + for(i = 0; i < width; i++){ + b1[i] += (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS; } } static void spatial_decompose97i(DWTELEM *buffer, int width, int height, int stride){ int y; - DWTELEM *b0= buffer + mirror(-4-1, height-1)*stride; - DWTELEM *b1= buffer + mirror(-4 , height-1)*stride; - DWTELEM *b2= buffer + mirror(-4+1, height-1)*stride; - DWTELEM *b3= buffer + mirror(-4+2, height-1)*stride; - - for(y=-4; y<height; y+=2){ - DWTELEM *b4= buffer + mirror(y+3, height-1)*stride; - DWTELEM *b5= buffer + mirror(y+4, height-1)*stride; - - if(y+3<(unsigned)height) horizontal_decompose97i(b4, width); - if(y+4<(unsigned)height) horizontal_decompose97i(b5, width); - - 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); - - b0=b2; - b1=b3; - b2=b4; - b3=b5; + DWTELEM *b0 = buffer + mirror(-4 - 1, height-1) * stride; + DWTELEM *b1 = buffer + mirror(-4 , height-1) * stride; + DWTELEM *b2 = buffer + mirror(-4 + 1, height-1) * stride; + DWTELEM *b3 = buffer + mirror(-4 + 2, height-1) * stride; + + for(y = -4; y < height; y += 2){ + DWTELEM *b4 = buffer + mirror(y + 3, height-1) * stride; + DWTELEM *b5 = buffer + mirror(y + 4, height-1) * stride; + + if(y + 3 < (unsigned)height) horizontal_decompose97i(b4, width); + if(y + 4 < (unsigned)height) horizontal_decompose97i(b5, width); + + 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); + + b0 = b2; + b1 = b3; + b2 = b4; + b3 = b5; } } void ff_spatial_dwt(DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){ int level; - for(level=0; level<decomposition_count; level++){ + for(level = 0; level < decomposition_count; level++){ 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_97: spatial_decompose97i(buffer, width >> level, height >> level, stride << level); break; + case DWT_53: spatial_decompose53i(buffer, width >> level, height >> level, stride << level); break; } } } static void horizontal_compose53i(IDWTELEM *b, int width){ IDWTELEM temp[width]; - const int width2= width>>1; - const int w2= (width+1)>>1; + const int width2 = width >> 1; + const int w2 = (width + 1) >> 1; int x; - for(x=0; x<width2; x++){ - temp[2*x ]= b[x ]; - temp[2*x + 1]= b[x+w2]; + for(x = 0; x < width2; x++){ + temp[2 * x ] = b[x ]; + temp[2 * x + 1] = b[x + w2]; } - if(width&1) - temp[2*x ]= b[x ]; + if(width & 1) + temp[2 * x ] = b[x ]; - b[0] = temp[0] - ((temp[1]+1)>>1); - for(x=2; x<width-1; x+=2){ - b[x ] = temp[x ] - ((temp[x-1] + temp[x+1]+2)>>2); - b[x-1] = temp[x-1] + ((b [x-2] + b [x ]+1)>>1); + b[0] = temp[0] - ((temp[1] + 1) >> 1); + for(x = 2; x < width - 1; x += 2){ + b[x ] = temp[x ] - ((temp[x - 1] + temp[x + 1] + 2) >> 2); + b[x - 1] = temp[x - 1] + ((b [x - 2] + b [x ] + 1) >> 1); } - if(width&1){ - b[x ] = temp[x ] - ((temp[x-1]+1)>>1); - b[x-1] = temp[x-1] + ((b [x-2] + b [x ]+1)>>1); + if(width & 1){ + b[x ] = temp[x ] - ((temp[x - 1] + 1) >> 1); + b[x - 1] = temp[x - 1] + ((b [x - 2] + b [x ] + 1) >> 1); }else - b[x-1] = temp[x-1] + b[x-2]; + b[x - 1] = temp[x - 1] + b[x - 2]; } static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ int i; - for(i=0; i<width; i++){ - b1[i] += (b0[i] + b2[i])>>1; + for(i = 0; i < width; i++){ + b1[i] += (b0[i] + b2[i]) >> 1; } } static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width){ int i; - for(i=0; i<width; i++){ - b1[i] -= (b0[i] + b2[i] + 2)>>2; + for(i = 0; i < width; i++){ + b1[i] -= (b0[i] + b2[i] + 2) >> 2; } } static void spatial_compose53i_buffered_init(DWTCompose *cs, slice_buffer * sb, int height, int stride_line){ - cs->b0 = slice_buffer_get_line(sb, mirror(-1-1, height-1) * stride_line); - cs->b1 = slice_buffer_get_line(sb, mirror(-1 , height-1) * stride_line); - cs->y = -1; + cs->b0 = slice_buffer_get_line(sb, mirror(-1-1, height - 1) * stride_line); + cs->b1 = slice_buffer_get_line(sb, mirror(-1 , height - 1) * stride_line); + cs->y = -1; } static void spatial_compose53i_init(DWTCompose *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; + cs->b0 = buffer + mirror(-1-1, height - 1) * stride; + cs->b1 = buffer + mirror(-1 , height - 1) * stride; + cs->y = -1; } static void spatial_compose53i_dy_buffered(DWTCompose *cs, slice_buffer * sb, int width, int height, int stride_line){ - int y= cs->y; - - 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); + int y = cs->y; + 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); - if(y+1<(unsigned)height && y<(unsigned)height){ + if(y + 1 < (unsigned)height && y < (unsigned)height){ int x; - for(x=0; x<width; x++){ - b2[x] -= (b1[x] + b3[x] + 2)>>2; - b1[x] += (b0[x] + b2[x])>>1; + for(x = 0; x < width; x++){ + b2[x] -= (b1[x] + b3[x] + 2) >> 2; + b1[x] += (b0[x] + b2[x]) >> 1; } }else{ - if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width); - if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width); + if(y + 1 < (unsigned)height) vertical_compose53iL0(b1, b2, b3, width); + if(y + 0 < (unsigned)height) vertical_compose53iH0(b0, b1, b2, width); } - if(y-1<(unsigned)height) horizontal_compose53i(b0, width); - if(y+0<(unsigned)height) horizontal_compose53i(b1, width); + if(y - 1 <(unsigned)height) horizontal_compose53i(b0, width); + if(y + 0 <(unsigned)height) horizontal_compose53i(b1, width); cs->b0 = b2; cs->b1 = b3; @@ -482,17 +485,17 @@ static void spatial_compose53i_dy_buffered(DWTCompose *cs, slice_buffer * sb, in } static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride){ - int y= cs->y; - 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; + int y = cs->y; + 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; - if(y+1<(unsigned)height) vertical_compose53iL0(b1, b2, b3, width); - if(y+0<(unsigned)height) vertical_compose53iH0(b0, b1, b2, width); + if(y + 1 < (unsigned)height) vertical_compose53iL0(b1, b2, b3, width); + if(y + 0 < (unsigned)height) vertical_compose53iH0(b0, b1, b2, width); - if(y-1<(unsigned)height) horizontal_compose53i(b0, width); - if(y+0<(unsigned)height) horizontal_compose53i(b1, width); + if(y - 1 < (unsigned)height) horizontal_compose53i(b0, width); + if(y + 0 < (unsigned)height) horizontal_compose53i(b1, width); cs->b0 = b2; cs->b1 = b3; @@ -509,22 +512,22 @@ static void av_unused spatial_compose53i(IDWTELEM *buffer, int width, int height void ff_snow_horizontal_compose97i(IDWTELEM *b, int width){ IDWTELEM temp[width]; - const int w2= (width+1)>>1; + const int w2 = (width + 1) >> 1; #if 0 //maybe more understadable but slower - inv_lift (temp , b , b +w2, 2, 1, 1, width, W_DM, W_DO, W_DS, 0, 1); - inv_lift (temp+1 , b +w2, temp , 2, 1, 2, width, W_CM, W_CO, W_CS, 1, 1); + inv_lift (temp , b , b + w2, 2, 1, 1, width, W_DM, W_DO, W_DS, 0, 1); + inv_lift (temp + 1, b + w2, temp , 2, 1, 2, width, W_CM, W_CO, W_CS, 1, 1); - inv_liftS(b , temp , temp+1 , 2, 2, 2, width, W_BM, W_BO, W_BS, 0, 1); - inv_lift (b+1 , temp+1 , b , 2, 2, 2, width, W_AM, W_AO, W_AS, 1, 0); + inv_liftS(b ,temp ,temp + 1, 2, 2, 2, width, W_BM, W_BO, W_BS, 0, 1); + inv_lift (b + 1 ,temp + 1,b , 2, 2, 2, width, W_AM, W_AO, W_AS, 1, 0); #else int x; - temp[0] = b[0] - ((3*b[w2]+2)>>2); - for(x=1; x<(width>>1); x++){ - temp[2*x ] = b[x ] - ((3*(b [x+w2-1] + b[x+w2])+4)>>3); - temp[2*x-1] = b[x+w2-1] - temp[2*x-2] - temp[2*x]; + temp[0] = b[0] - ((3 * b[w2] + 2) >> 2); + for(x = 1; x < (width >> 1); x++){ + temp[2 * x ] = b[x ] - (( 3 * (b [ x + w2 - 1] + b[x + w2]) + 4) >> 3); + temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x]; } - if(width&1){ + if(width & 1){ temp[2*x ] = b[x ] - ((3*b [x+w2-1]+2)>>2); temp[2*x-1] = b[x+w2-1] - temp[2*x-2] - temp[2*x]; }else @@ -841,3 +844,541 @@ void ff_dwt_init(DWTContext *c) if (HAVE_MMX) ff_dwt_init_x86(c); } + + +static av_always_inline +void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift) +{ + int i; + for (i = 0; i < w2; i++) { + dst[2*i ] = (src0[i] + add) >> shift; + dst[2*i+1] = (src1[i] + add) >> shift; + } +} + +static void horizontal_compose_dirac53i(IDWTELEM *b, IDWTELEM *temp, int w) +{ + const int w2 = w >> 1; + int x; + + temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]); + for (x = 1; x < w2; x++) { + temp[x ] = COMPOSE_53iL0 (b[x+w2-1], b[x ], b[x+w2]); + temp[x+w2-1] = COMPOSE_DIRAC53iH0(temp[x-1], b[x+w2-1], temp[x]); + } + temp[w-1] = COMPOSE_DIRAC53iH0(temp[w2-1], b[w-1], temp[w2-1]); + + interleave(b, temp, temp+w2, w2, 1, 1); +} + +static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w) +{ + const int w2 = w >> 1; + int x; + + tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]); + for (x = 1; x < w2; x++) + tmp[x] = COMPOSE_53iL0(b[x+w2-1], b[x], b[x+w2]); + + // extend the edges + tmp[-1] = tmp[0]; + tmp[w2+1] = tmp[w2] = tmp[w2-1]; + + for (x = 0; x < w2; x++) { + b[2*x ] = (tmp[x] + 1)>>1; + b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1; + } +} + +static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w) +{ + const int w2 = w >> 1; + int x; + + tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2 ], b[w2+1]); + tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2+1], b[w2+2]); + for (x = 2; x < w2-1; x++) + tmp[x] = COMPOSE_DD137iL0(b[x+w2-2], b[x+w2-1], b[x], b[x+w2], b[x+w2+1]); + tmp[w2-1] = COMPOSE_DD137iL0(b[w-3], b[w-2], b[w2-1], b[w-1], b[w-1]); + + // extend the edges + tmp[-1] = tmp[0]; + tmp[w2+1] = tmp[w2] = tmp[w2-1]; + + for (x = 0; x < w2; x++) { + b[2*x ] = (tmp[x] + 1)>>1; + b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1; + } +} + +static av_always_inline +void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *temp, int w, int shift) +{ + const int w2 = w >> 1; + int x; + + for (x = 0; x < w2; x++) { + temp[x ] = COMPOSE_HAARiL0(b[x ], b[x+w2]); + temp[x+w2] = COMPOSE_HAARiH0(b[x+w2], temp[x]); + } + + interleave(b, temp, temp+w2, w2, shift, shift); +} + +static void horizontal_compose_haar0i(IDWTELEM *b, IDWTELEM *temp, int w) +{ + horizontal_compose_haari(b, temp, w, 0); +} + +static void horizontal_compose_haar1i(IDWTELEM *b, IDWTELEM *temp, int w) +{ + horizontal_compose_haari(b, temp, w, 1); +} + +static void horizontal_compose_fidelityi(IDWTELEM *b, IDWTELEM *tmp, int w) +{ + const int w2 = w >> 1; + int i, x; + IDWTELEM v[8]; + + for (x = 0; x < w2; x++) { + for (i = 0; i < 8; i++) + v[i] = b[av_clip(x-3+i, 0, w2-1)]; + tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x+w2], v[4], v[5], v[6], v[7]); + } + + for (x = 0; x < w2; x++) { + for (i = 0; i < 8; i++) + v[i] = tmp[av_clip(x-4+i, 0, w2-1)]; + tmp[x+w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], v[5], v[6], v[7]); + } + + interleave(b, tmp+w2, tmp, w2, 0, 0); +} + +static void horizontal_compose_daub97i(IDWTELEM *b, IDWTELEM *temp, int w) +{ + const int w2 = w >> 1; + int x, b0, b1, b2; + + temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]); + for (x = 1; x < w2; x++) { + temp[x ] = COMPOSE_DAUB97iL1(b[x+w2-1], b[x ], b[x+w2]); + temp[x+w2-1] = COMPOSE_DAUB97iH1(temp[x-1], b[x+w2-1], temp[x]); + } + temp[w-1] = COMPOSE_DAUB97iH1(temp[w2-1], b[w-1], temp[w2-1]); + + // second stage combined with interleave and shift + b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]); + b[0] = (b0 + 1) >> 1; + for (x = 1; x < w2; x++) { + b2 = COMPOSE_DAUB97iL0(temp[x+w2-1], temp[x ], temp[x+w2]); + b1 = COMPOSE_DAUB97iH0( b0, temp[x+w2-1], b2 ); + b[2*x-1] = (b1 + 1) >> 1; + b[2*x ] = (b2 + 1) >> 1; + b0 = b2; + } + b[w-1] = (COMPOSE_DAUB97iH0(b2, temp[w-1], b2) + 1) >> 1; +} + +static void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) +{ + int i; + + for(i=0; i<width; i++){ + b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]); + } +} + +static void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + IDWTELEM *b3, IDWTELEM *b4, int width) +{ + int i; + + for(i=0; i<width; i++){ + b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]); + } +} + +static void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, + IDWTELEM *b3, IDWTELEM *b4, int width) +{ + int i; + + for(i=0; i<width; i++){ + b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]); + } +} + +static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width) +{ + int i; + + for (i = 0; i < width; i++) { + b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]); + b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]); + } +} + +static void vertical_compose_fidelityiH0(IDWTELEM *dst, IDWTELEM *b[8], int width) +{ + int i; + + for(i=0; i<width; i++){ + dst[i] = COMPOSE_FIDELITYiH0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]); + } +} + +static void vertical_compose_fidelityiL0(IDWTELEM *dst, IDWTELEM *b[8], int width) +{ + int i; + + for(i=0; i<width; i++){ + dst[i] = COMPOSE_FIDELITYiL0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]); + } +} + +static void vertical_compose_daub97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) +{ + int i; + + for(i=0; i<width; i++){ + b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]); + } +} + +static void vertical_compose_daub97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) +{ + int i; + + for(i=0; i<width; i++){ + b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]); + } +} + +static void vertical_compose_daub97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) +{ + int i; + + for(i=0; i<width; i++){ + b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]); + } +} + +static void vertical_compose_daub97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) +{ + int i; + + for(i=0; i<width; i++){ + b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]); + } +} + + +static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, int height, int stride) +{ + vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0; + vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0; + DWTCompose *cs = d->cs + level; + + int i, y = cs->y; + IDWTELEM *b[8]; + for (i = 0; i < 6; i++) + b[i] = cs->b[i]; + b[6] = d->buffer + av_clip(y+5, 0, height-2)*stride; + b[7] = d->buffer + av_clip(y+6, 1, height-1)*stride; + + if(y+5<(unsigned)height) vertical_compose_l0( b[5], b[6], b[7], width); + if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width); + + if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width); + if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width); + + for (i = 0; i < 6; i++) + cs->b[i] = b[i+2]; + cs->y += 2; +} + +static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, int height, int stride) +{ + vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0; + vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0; + DWTCompose *cs = d->cs + level; + + int y= cs->y; + IDWTELEM *b[4] = { cs->b[0], cs->b[1] }; + b[2] = d->buffer + mirror(y+1, height-1)*stride; + b[3] = d->buffer + mirror(y+2, height-1)*stride; + + if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width); + if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width); + + if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width); + if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width); + + cs->b[0] = b[2]; + cs->b[1] = b[3]; + cs->y += 2; +} + + +static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, int height, int stride) +{ + vertical_compose_5tap vertical_compose_l0 = (void*)d->vertical_compose_l0; + vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0; + DWTCompose *cs = d->cs + level; + + int i, y = cs->y; + IDWTELEM *b[10]; + for (i = 0; i < 8; i++) + b[i] = cs->b[i]; + b[8] = d->buffer + av_clip(y+7, 0, height-2)*stride; + b[9] = d->buffer + av_clip(y+8, 1, height-1)*stride; + + if(y+5<(unsigned)height) vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width); + if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width); + + if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width); + if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width); + + for (i = 0; i < 8; i++) + cs->b[i] = b[i+2]; + cs->y += 2; +} + +// haar makes the assumption that height is even (always true for dirac) +static void spatial_compose_haari_dy(DWTContext *d, int level, int width, int height, int stride) +{ + vertical_compose_2tap vertical_compose = (void*)d->vertical_compose; + int y = d->cs[level].y; + IDWTELEM *b0 = d->buffer + (y-1)*stride; + IDWTELEM *b1 = d->buffer + (y )*stride; + + vertical_compose(b0, b1, width); + d->horizontal_compose(b0, d->temp, width); + d->horizontal_compose(b1, d->temp, width); + + d->cs[level].y += 2; +} + +// Don't do sliced idwt for fidelity; the 9 tap filter makes it a bit annoying +// Fortunately, this filter isn't used in practice. +static void spatial_compose_fidelity(DWTContext *d, int level, int width, int height, int stride) +{ + vertical_compose_9tap vertical_compose_l0 = (void*)d->vertical_compose_l0; + vertical_compose_9tap vertical_compose_h0 = (void*)d->vertical_compose_h0; + int i, y; + IDWTELEM *b[8]; + + for (y = 1; y < height; y += 2) { + for (i = 0; i < 8; i++) + b[i] = d->buffer + av_clip((y-7 + 2*i), 0, height-2)*stride; + vertical_compose_h0(d->buffer + y*stride, b, width); + } + + for (y = 0; y < height; y += 2) { + for (i = 0; i < 8; i++) + b[i] = d->buffer + av_clip((y-7 + 2*i), 1, height-1)*stride; + vertical_compose_l0(d->buffer + y*stride, b, width); + } + + for (y = 0; y < height; y++) + d->horizontal_compose(d->buffer + y*stride, d->temp, width); + + d->cs[level].y = height+1; +} + +static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, int height, int stride) +{ + vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0; + vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0; + vertical_compose_3tap vertical_compose_l1 = (void*)d->vertical_compose_l1; + vertical_compose_3tap vertical_compose_h1 = (void*)d->vertical_compose_h1; + DWTCompose *cs = d->cs + level; + + int i, y = cs->y; + IDWTELEM *b[6]; + for (i = 0; i < 4; i++) + b[i] = cs->b[i]; + b[4] = d->buffer + mirror(y+3, height-1)*stride; + b[5] = d->buffer + mirror(y+4, height-1)*stride; + + if(y+3<(unsigned)height) vertical_compose_l1(b[3], b[4], b[5], width); + if(y+2<(unsigned)height) vertical_compose_h1(b[2], b[3], b[4], width); + if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width); + if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width); + + if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width); + if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width); + + for (i = 0; i < 4; i++) + cs->b[i] = b[i+2]; + cs->y += 2; +} + + +static void spatial_compose97i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride) +{ + cs->b[0] = buffer + mirror(-3-1, height-1)*stride; + cs->b[1] = buffer + mirror(-3 , height-1)*stride; + cs->b[2] = buffer + mirror(-3+1, height-1)*stride; + cs->b[3] = buffer + mirror(-3+2, height-1)*stride; + cs->y = -3; +} + +static void spatial_compose53i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride) +{ + cs->b[0] = buffer + mirror(-1-1, height-1)*stride; + cs->b[1] = buffer + mirror(-1 , height-1)*stride; + cs->y = -1; +} + +static void spatial_compose_dd97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride) +{ + cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride; + cs->b[1] = buffer + av_clip(-5 , 1, height-1)*stride; + cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride; + cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride; + cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride; + cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride; + cs->y = -5; +} + +static void spatial_compose_dd137i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride) +{ + cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride; + cs->b[1] = buffer + av_clip(-5 , 1, height-1)*stride; + cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride; + cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride; + cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride; + cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride; + cs->b[6] = buffer + av_clip(-5+5, 0, height-2)*stride; + cs->b[7] = buffer + av_clip(-5+6, 1, height-1)*stride; + cs->y = -5; +} + +int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height, + int stride, enum dwt_type type, int decomposition_count, + IDWTELEM *temp) +{ + int level; + + d->buffer = buffer; + d->width = width; + d->height = height; + d->stride = stride; + d->decomposition_count = decomposition_count; + d->temp = temp + 8; + + for(level=decomposition_count-1; level>=0; level--){ + int hl = height >> level; + int stride_l = stride << level; + + switch(type){ + case DWT_DIRAC_DD9_7: + spatial_compose_dd97i_init(d->cs+level, buffer, hl, stride_l); + break; + case DWT_DIRAC_LEGALL5_3: + spatial_compose53i_init2(d->cs+level, buffer, hl, stride_l); + break; + case DWT_DIRAC_DD13_7: + spatial_compose_dd137i_init(d->cs+level, buffer, hl, stride_l); + break; + case DWT_DIRAC_HAAR0: + case DWT_DIRAC_HAAR1: + d->cs[level].y = 1; + break; + case DWT_DIRAC_DAUB9_7: + spatial_compose97i_init2(d->cs+level, buffer, hl, stride_l); + break; + default: + d->cs[level].y = 0; + break; + } + } + + switch (type) { + case DWT_DIRAC_DD9_7: + d->spatial_compose = spatial_compose_dd97i_dy; + d->vertical_compose_l0 = (void*)vertical_compose53iL0; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0; + d->horizontal_compose = horizontal_compose_dd97i; + d->support = 7; + break; + case DWT_DIRAC_LEGALL5_3: + d->spatial_compose = spatial_compose_dirac53i_dy; + d->vertical_compose_l0 = (void*)vertical_compose53iL0; + d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0; + d->horizontal_compose = horizontal_compose_dirac53i; + d->support = 3; + break; + case DWT_DIRAC_DD13_7: + d->spatial_compose = spatial_compose_dd137i_dy; + d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0; + d->horizontal_compose = horizontal_compose_dd137i; + d->support = 7; + break; + case DWT_DIRAC_HAAR0: + case DWT_DIRAC_HAAR1: + d->spatial_compose = spatial_compose_haari_dy; + d->vertical_compose = (void*)vertical_compose_haar; + if (type == DWT_DIRAC_HAAR0) + d->horizontal_compose = horizontal_compose_haar0i; + else + d->horizontal_compose = horizontal_compose_haar1i; + d->support = 1; + break; + case DWT_DIRAC_FIDELITY: + d->spatial_compose = spatial_compose_fidelity; + d->vertical_compose_l0 = (void*)vertical_compose_fidelityiL0; + d->vertical_compose_h0 = (void*)vertical_compose_fidelityiH0; + d->horizontal_compose = horizontal_compose_fidelityi; + break; + case DWT_DIRAC_DAUB9_7: + d->spatial_compose = spatial_compose_daub97i_dy; + d->vertical_compose_l0 = (void*)vertical_compose_daub97iL0; + d->vertical_compose_h0 = (void*)vertical_compose_daub97iH0; + d->vertical_compose_l1 = (void*)vertical_compose_daub97iL1; + d->vertical_compose_h1 = (void*)vertical_compose_daub97iH1; + d->horizontal_compose = horizontal_compose_daub97i; + d->support = 5; + break; + default: + av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type); + return -1; + } + + if (HAVE_MMX) ff_spatial_idwt_init_mmx(d, type); + + return 0; +} + +void ff_spatial_idwt_slice2(DWTContext *d, int y) +{ + int level, support = d->support; + + for (level = d->decomposition_count-1; level >= 0; level--) { + int wl = d->width >> level; + int hl = d->height >> level; + int stride_l = d->stride << level; + + while (d->cs[level].y <= FFMIN((y>>level)+support, hl)) + d->spatial_compose(d, level, wl, hl, stride_l); + } +} + +int ff_spatial_idwt2(IDWTELEM *buffer, int width, int height, int stride, + enum dwt_type type, int decomposition_count, IDWTELEM *temp) +{ + DWTContext d; + int y; + + if (ff_spatial_idwt_init2(&d, buffer, width, height, stride, type, decomposition_count, temp)) + return -1; + + for (y = 0; y < d.height; y += 4) + ff_spatial_idwt_slice2(&d, y); + + return 0; +} diff --git a/libavcodec/dwt.h b/libavcodec/dwt.h index fc73fe7e8e..ec27a61446 100644 --- a/libavcodec/dwt.h +++ b/libavcodec/dwt.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +26,12 @@ typedef int DWTELEM; typedef short IDWTELEM; +#define MAX_DWT_SUPPORT 8 +#define MAX_DECOMPOSITIONS 8 + typedef struct { + IDWTELEM *b[MAX_DWT_SUPPORT]; + IDWTELEM *b0; IDWTELEM *b1; IDWTELEM *b2; @@ -45,13 +50,99 @@ typedef struct slice_buffer_s { IDWTELEM * base_buffer; ///< Buffer that this structure is caching. } slice_buffer; +struct DWTContext; + +// Possible prototypes for vertical_compose functions +typedef void (*vertical_compose_2tap)(IDWTELEM *b0, IDWTELEM *b1, int width); +typedef void (*vertical_compose_3tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); +typedef void (*vertical_compose_5tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width); +typedef void (*vertical_compose_9tap)(IDWTELEM *dst, IDWTELEM *b[8], int width); + typedef struct DWTContext { + IDWTELEM *buffer; + IDWTELEM *temp; + int width; + int height; + int stride; + int decomposition_count; + int support; + + void (*spatial_compose)(struct DWTContext *cs, int level, int width, int height, int stride); + void (*vertical_compose_l0)(void); + void (*vertical_compose_h0)(void); + void (*vertical_compose_l1)(void); + void (*vertical_compose_h1)(void); + void (*vertical_compose)(void); ///< one set of lowpass and highpass combined + void (*horizontal_compose)(IDWTELEM *b, IDWTELEM *tmp, 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); + + DWTCompose cs[MAX_DECOMPOSITIONS]; } DWTContext; -#define MAX_DECOMPOSITIONS 8 +enum dwt_type { + DWT_SNOW_DAUB9_7, + DWT_SNOW_LEGALL5_3, + DWT_DIRAC_DD9_7, + DWT_DIRAC_LEGALL5_3, + DWT_DIRAC_DD13_7, + DWT_DIRAC_HAAR0, + DWT_DIRAC_HAAR1, + DWT_DIRAC_FIDELITY, + DWT_DIRAC_DAUB9_7, + DWT_NUM_TYPES +}; + +// -1 if an error occurred, e.g. the dwt_type isn't recognized +int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height, + int stride, enum dwt_type type, int decomposition_count, + IDWTELEM *temp); + +int ff_spatial_idwt2(IDWTELEM *buffer, int width, int height, int stride, + enum dwt_type type, int decomposition_count, IDWTELEM *temp); + +void ff_spatial_idwt_slice2(DWTContext *d, int y); + +// shared stuff for simd optimiztions +#define COMPOSE_53iL0(b0, b1, b2)\ + (b1 - ((b0 + b2 + 2) >> 2)) + +#define COMPOSE_DIRAC53iH0(b0, b1, b2)\ + (b1 + ((b0 + b2 + 1) >> 1)) + +#define COMPOSE_DD97iH0(b0, b1, b2, b3, b4)\ + (b2 + ((-b0 + 9*b1 + 9*b3 - b4 + 8) >> 4)) + +#define COMPOSE_DD137iL0(b0, b1, b2, b3, b4)\ + (b2 - ((-b0 + 9*b1 + 9*b3 - b4 + 16) >> 5)) + +#define COMPOSE_HAARiL0(b0, b1)\ + (b0 - ((b1 + 1) >> 1)) + +#define COMPOSE_HAARiH0(b0, b1)\ + (b0 + b1) + +#define COMPOSE_FIDELITYiL0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\ + (b4 - ((-8*(b0+b8) + 21*(b1+b7) - 46*(b2+b6) + 161*(b3+b5) + 128) >> 8)) + +#define COMPOSE_FIDELITYiH0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\ + (b4 + ((-2*(b0+b8) + 10*(b1+b7) - 25*(b2+b6) + 81*(b3+b5) + 128) >> 8)) + +#define COMPOSE_DAUB97iL1(b0, b1, b2)\ + (b1 - ((1817*(b0 + b2) + 2048) >> 12)) + +#define COMPOSE_DAUB97iH1(b0, b1, b2)\ + (b1 - (( 113*(b0 + b2) + 64) >> 7)) + +#define COMPOSE_DAUB97iL0(b0, b1, b2)\ + (b1 + (( 217*(b0 + b2) + 2048) >> 12)) + +#define COMPOSE_DAUB97iH0(b0, b1, b2)\ + (b1 + ((6497*(b0 + b2) + 2048) >> 12)) + + #define DWT_97 0 #define DWT_53 1 diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c index d196f49486..28c6af9031 100644 --- a/libavcodec/dxa.c +++ b/libavcodec/dxa.c @@ -2,20 +2,20 @@ * Feeble Files/ScummVM DXA decoder * Copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -209,7 +209,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac r = *buf++; g = *buf++; b = *buf++; - c->pal[i] = (r << 16) | (g << 8) | b; + c->pal[i] = 0xFF << 24 | r << 16 | g << 8 | b; } pc = 1; buf_size -= 768+4; @@ -295,6 +295,9 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&c->pic); + avcodec_get_frame_defaults(&c->prev); + c->dsize = avctx->width * avctx->height * 2; if((c->decomp_buf = av_malloc(c->dsize)) == NULL) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index d7d893c457..9b94b58fbc 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -3,20 +3,20 @@ * * copyright (c) 2010 Laurent Aimar * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dxva2.h b/libavcodec/dxva2.h index 374ae039ac..fc99560830 100644 --- a/libavcodec/dxva2.h +++ b/libavcodec/dxva2.h @@ -3,20 +3,20 @@ * * copyright (c) 2009 Laurent Aimar * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -32,7 +32,7 @@ /** * This structure is used to provides the necessary configurations and data - * to the DXVA2 Libav HWAccel implementation. + * to the DXVA2 FFmpeg HWAccel implementation. * * The application must make it available as AVCodecContext.hwaccel_context. */ @@ -63,7 +63,7 @@ struct dxva_context { uint64_t workaround; /** - * Private to the Libav AVHWAccel implementation + * Private to the FFmpeg AVHWAccel implementation */ unsigned report_id; }; diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c index ffe71a9656..3bda097cc4 100644 --- a/libavcodec/dxva2_h264.c +++ b/libavcodec/dxva2_h264.c @@ -3,20 +3,20 @@ * * copyright (c) 2009 Laurent Aimar * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -95,7 +95,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context pp->wBitFields = ((s->picture_structure != PICT_FRAME) << 0) | (h->sps.mb_aff << 1) | (h->sps.residual_color_transform_flag << 2) | - /* sp_for_switch_flag (not implemented by Libav) */ + /* sp_for_switch_flag (not implemented by FFmpeg) */ (0 << 3) | (h->sps.chroma_format_idc << 4) | ((h->nal_ref_idc != 0) << 6) | @@ -149,8 +149,8 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context pp->deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present; pp->redundant_pic_cnt_present_flag= h->pps.redundant_pic_cnt_present; pp->Reserved8BitsB = 0; - pp->slice_group_change_rate_minus1= 0; /* XXX not implemented by Libav */ - //pp->SliceGroupMap[810]; /* XXX not implemented by Libav */ + pp->slice_group_change_rate_minus1= 0; /* XXX not implemented by FFmpeg */ + //pp->SliceGroupMap[810]; /* XXX not implemented by FFmpeg */ } static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm) @@ -258,7 +258,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice, } } } - slice->slice_qs_delta = 0; /* XXX not implemented by Libav */ + slice->slice_qs_delta = 0; /* XXX not implemented by FFmpeg */ slice->slice_qp_delta = s->qscale - h->pps.init_qp; slice->redundant_pic_cnt = h->redundant_pic_count; if (h->slice_type == AV_PICTURE_TYPE_B) diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index 57fc7bd6f9..23d4d87522 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -3,20 +3,20 @@ * * copyright (c) 2010 Laurent Aimar * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c index b20b3d79f4..e54eff09fb 100644 --- a/libavcodec/dxva2_mpeg2.c +++ b/libavcodec/dxva2_mpeg2.c @@ -3,20 +3,20 @@ * * copyright (c) 2010 Laurent Aimar * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -109,10 +109,10 @@ static void fill_quantization_matrices(AVCodecContext *avctx, qm->bNewQmatrix[i] = 1; for (i = 0; i < 64; i++) { int n = s->dsp.idct_permutation[ff_zigzag_direct[i]]; - qm->Qmatrix[0][i] = s->intra_matrix[n];; - qm->Qmatrix[1][i] = s->inter_matrix[n];; - qm->Qmatrix[2][i] = s->chroma_intra_matrix[n];; - qm->Qmatrix[3][i] = s->chroma_inter_matrix[n];; + qm->Qmatrix[0][i] = s->intra_matrix[n]; + qm->Qmatrix[1][i] = s->inter_matrix[n]; + qm->Qmatrix[2][i] = s->chroma_intra_matrix[n]; + qm->Qmatrix[3][i] = s->chroma_inter_matrix[n]; } } diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c index 64447ad87a..50da518d86 100644 --- a/libavcodec/dxva2_vc1.c +++ b/libavcodec/dxva2_vc1.c @@ -3,20 +3,20 @@ * * copyright (c) 2010 Laurent Aimar * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/eac3_data.c b/libavcodec/eac3_data.c index b0416f3ce7..b159e1682f 100644 --- a/libavcodec/eac3_data.c +++ b/libavcodec/eac3_data.c @@ -2,20 +2,20 @@ * E-AC-3 tables * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/eac3_data.h b/libavcodec/eac3_data.h index 4d88ce0a53..10a67f16d2 100644 --- a/libavcodec/eac3_data.h +++ b/libavcodec/eac3_data.h @@ -2,20 +2,20 @@ * E-AC-3 tables * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/eac3dec.c b/libavcodec/eac3dec.c index 7072f783e4..7fc1bb5071 100644 --- a/libavcodec/eac3dec.c +++ b/libavcodec/eac3dec.c @@ -3,20 +3,20 @@ * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com> * Copyright (c) 2008 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/eacmv.c b/libavcodec/eacmv.c index 085e2d8177..82ec9fc9fc 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -2,20 +2,20 @@ * Electronic Arts CMV Video Decoder * Copyright (c) 2007-2008 Peter Ross * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -43,6 +43,10 @@ typedef struct CmvContext { static av_cold int cmv_decode_init(AVCodecContext *avctx){ CmvContext *s = avctx->priv_data; + avcodec_get_frame_defaults(&s->frame); + avcodec_get_frame_defaults(&s->last_frame); + avcodec_get_frame_defaults(&s->last2_frame); + s->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; return 0; @@ -106,9 +110,10 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t * }else{ /* inter using last frame as reference */ int xoffset = (buf[i] & 0xF) - 7; int yoffset = ((buf[i] >> 4)) - 7; - cmv_motcomp(s->frame.data[0], s->frame.linesize[0], - s->last_frame.data[0], s->last_frame.linesize[0], - x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); + if (s->last_frame.data[0]) + cmv_motcomp(s->frame.data[0], s->frame.linesize[0], + s->last_frame.data[0], s->last_frame.linesize[0], + x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); } i++; } @@ -136,7 +141,7 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t buf += 16; for (i=pal_start; i<pal_start+pal_count && i<AVPALETTE_COUNT && buf_end - buf >= 3; i++) { - s->palette[i] = AV_RB24(buf); + s->palette[i] = 0xFF << 24 | AV_RB24(buf); buf += 3; } } @@ -157,8 +162,11 @@ static int cmv_decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { + unsigned size = AV_RL32(buf + 4); cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); - return buf_size; + if (size > buf_end - buf - EA_PREAMBLE_SIZE) + return -1; + buf += size; } if (av_image_check_size(s->width, s->height, 0, s->avctx)) @@ -170,8 +178,10 @@ static int cmv_decode_frame(AVCodecContext *avctx, FFSWAP(AVFrame, s->last_frame, s->last2_frame); FFSWAP(AVFrame, s->frame, s->last_frame); - s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; + s->frame.reference = 3; + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | + FF_BUFFER_HINTS_READABLE | + FF_BUFFER_HINTS_PRESERVE; if (avctx->get_buffer(avctx, &s->frame)<0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; diff --git a/libavcodec/eaidct.c b/libavcodec/eaidct.c index 9d829c4161..9972e422ed 100644 --- a/libavcodec/eaidct.c +++ b/libavcodec/eaidct.c @@ -2,20 +2,20 @@ * Electronic Arts TGQ/TQI/MAD IDCT algorithm * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/eamad.c b/libavcodec/eamad.c index c5aa6ace79..40fdb37670 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -2,20 +2,20 @@ * Electronic Arts Madcow Video Decoder * Copyright (c) 2007-2009 Peter Ross * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -85,15 +85,21 @@ static inline void comp_block(MadContext *t, int mb_x, int mb_y, { MpegEncContext *s = &t->s; if (j < 4) { + unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x; + if (offset >= (s->height - 7) * t->last_frame.linesize[0] - 7) + return; comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3), t->frame.linesize[0], - t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x, + t->last_frame.data[0] + offset, t->last_frame.linesize[0], add); } else if (!(s->avctx->flags & CODEC_FLAG_GRAY)) { int index = j - 3; + unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2); + if (offset >= (s->height/2 - 7) * t->last_frame.linesize[index] - 7) + return; comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8, t->frame.linesize[index], - t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2), + t->last_frame.data[index] + offset, t->last_frame.linesize[index], add); } } @@ -113,7 +119,7 @@ static inline void idct_put(MadContext *t, DCTELEM *block, int mb_x, int mb_y, i } } -static inline void decode_block_intra(MadContext * t, DCTELEM * block) +static inline int decode_block_intra(MadContext * t, DCTELEM * block) { MpegEncContext *s = &t->s; int level, i, j, run; @@ -164,13 +170,14 @@ static inline void decode_block_intra(MadContext * t, DCTELEM * block) } if (i > 63) { av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return; + return -1; } block[j] = level; } CLOSE_READER(re, &s->gb); } + return 0; } static int decode_motion(GetBitContext *gb) @@ -184,7 +191,7 @@ static int decode_motion(GetBitContext *gb) return value; } -static void decode_mb(MadContext *t, int inter) +static int decode_mb(MadContext *t, int inter) { MpegEncContext *s = &t->s; int mv_map = 0; @@ -205,13 +212,16 @@ static void decode_mb(MadContext *t, int inter) for (j=0; j<6; j++) { if (mv_map & (1<<j)) { // mv_x and mv_y are guarded by mv_map int add = 2*decode_motion(&s->gb); - comp_block(t, s->mb_x, s->mb_y, j, mv_x, mv_y, add); + if (t->last_frame.data[0]) + comp_block(t, s->mb_x, s->mb_y, j, mv_x, mv_y, add); } else { s->dsp.clear_block(t->block); - decode_block_intra(t, t->block); + if(decode_block_intra(t, t->block) < 0) + return -1; idct_put(t, t->block, s->mb_x, s->mb_y, j); } } + return 0; } static void calc_intra_matrix(MadContext *t, int qscale) @@ -261,14 +271,18 @@ static int decode_frame(AVCodecContext *avctx, buf += 16; if (avctx->width != s->width || avctx->height != s->height) { + if((s->width * s->height)/2048*7 > buf_end-buf) + return -1; if (av_image_check_size(s->width, s->height, 0, avctx) < 0) return -1; avcodec_set_dimensions(avctx, s->width, s->height); if (t->frame.data[0]) avctx->release_buffer(avctx, &t->frame); + if (t->last_frame.data[0]) + avctx->release_buffer(avctx, &t->last_frame); } - t->frame.reference = 1; + t->frame.reference = 3; if (!t->frame.data[0]) { if (avctx->get_buffer(avctx, &t->frame) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -280,11 +294,13 @@ static int decode_frame(AVCodecContext *avctx, if (!t->bitstream_buf) return AVERROR(ENOMEM); bswap16_buf(t->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2); + memset((uint8_t*)t->bitstream_buf + (buf_end-buf), 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf)); for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++) for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++) - decode_mb(t, inter); + if(decode_mb(t, inter) < 0) + return -1; *data_size = sizeof(AVFrame); *(AVFrame*)data = t->frame; diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c index e82ed32470..da9ff3bba0 100644 --- a/libavcodec/eatgq.c +++ b/libavcodec/eatgq.c @@ -2,20 +2,20 @@ * Electronic Arts TGQ Video Decoder * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c index ccdb35ef2b..37f84bf5ef 100644 --- a/libavcodec/eatgv.c +++ b/libavcodec/eatgv.c @@ -2,20 +2,20 @@ * Electronic Arts TGV Video Decoder * Copyright (c) 2007-2008 Peter Ross * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -55,6 +55,8 @@ static av_cold int tgv_decode_init(AVCodecContext *avctx){ s->avctx = avctx; avctx->time_base = (AVRational){1, 15}; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&s->frame); + avcodec_get_frame_defaults(&s->last_frame); return 0; } @@ -72,7 +74,7 @@ static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst else src += 2; - if (src+3>src_end) + if (src_end - src < 3) return -1; size = AV_RB24(src); src += 3; @@ -136,7 +138,7 @@ static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst * @return 0 on success, -1 on critical buffer underflow */ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *buf_end){ - unsigned char *frame0_end = s->last_frame.data[0] + s->avctx->width*s->last_frame.linesize[0]; + unsigned last_frame_size = s->avctx->height*s->last_frame.linesize[0]; int num_mvs; int num_blocks_raw; int num_blocks_packed; @@ -146,7 +148,7 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b int mvbits; const unsigned char *blocks_raw; - if(buf+12>buf_end) + if(buf_end - buf < 12) return -1; num_mvs = AV_RL16(&buf[0]); @@ -169,7 +171,7 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b /* read motion vectors */ mvbits = (num_mvs*2*10+31) & ~31; - if (buf+(mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed>buf_end) + if (buf_end - buf < (mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed) return -1; init_get_bits(&gb, buf, mvbits); @@ -205,12 +207,14 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b int src_stride; if (vector < num_mvs) { - src = s->last_frame.data[0] + - (y*4 + s->mv_codebook[vector][1])*s->last_frame.linesize[0] + - x*4 + s->mv_codebook[vector][0]; + unsigned offset = + (y*4 + s->mv_codebook[vector][1])*s->last_frame.linesize[0] + + x*4 + s->mv_codebook[vector][0]; + src_stride = s->last_frame.linesize[0]; - if (src+3*src_stride+3>=frame0_end) + if (offset >= last_frame_size - (3*src_stride+3)) continue; + src = s->last_frame.data[0] + offset; }else{ int offset = vector - num_mvs; if (offset<num_blocks_raw) @@ -250,12 +254,15 @@ static int tgv_decode_frame(AVCodecContext *avctx, const uint8_t *buf_end = buf + buf_size; int chunk_type; + if (buf_end - buf < EA_PREAMBLE_SIZE) + return AVERROR_INVALIDDATA; + chunk_type = AV_RL32(&buf[0]); buf += EA_PREAMBLE_SIZE; if (chunk_type==kVGT_TAG) { int pal_count, i; - if(buf+12>buf_end) { + if(buf_end - buf < 12) { av_log(avctx, AV_LOG_WARNING, "truncated header\n"); return -1; } @@ -270,8 +277,8 @@ static int tgv_decode_frame(AVCodecContext *avctx, pal_count = AV_RL16(&buf[6]); buf += 12; - for(i=0; i<pal_count && i<AVPALETTE_COUNT && buf+2<buf_end; i++) { - s->palette[i] = AV_RB24(buf); + for(i=0; i<pal_count && i<AVPALETTE_COUNT && buf_end - buf >= 3; i++) { + s->palette[i] = 0xFF << 24 | AV_RB24(buf); buf += 3; } } @@ -282,7 +289,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, /* shuffle */ FFSWAP(AVFrame, s->frame, s->last_frame); if (!s->frame.data[0]) { - s->frame.reference = 1; + s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; s->frame.linesize[0] = s->width; diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index 179b84d6a0..2d6cff58d4 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -2,20 +2,20 @@ * Electronic Arts TQI Video Decoder * Copyright (c) 2007-2009 Peter Ross <pross@xvid.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -57,12 +57,15 @@ static av_cold int tqi_decode_init(AVCodecContext *avctx) return 0; } -static void tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64]) +static int tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64]) { int n; s->dsp.clear_blocks(block[0]); for (n=0; n<6; n++) - ff_mpeg1_decode_block_intra(s, block[n], n); + if(ff_mpeg1_decode_block_intra(s, block[n], n)<0) + return -1; + + return 0; } static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64]) @@ -135,7 +138,8 @@ static int tqi_decode_frame(AVCodecContext *avctx, for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++) for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++) { - tqi_decode_mb(s, t->block); + if(tqi_decode_mb(s, t->block) < 0) + break; tqi_idct_put(t, t->block); } diff --git a/libavcodec/elbg.c b/libavcodec/elbg.c index 030c3a68c4..ede863e9be 100644 --- a/libavcodec/elbg.c +++ b/libavcodec/elbg.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/elbg.h b/libavcodec/elbg.h index b8ea489b24..e6f577e3e5 100644 --- a/libavcodec/elbg.h +++ b/libavcodec/elbg.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index bf59efad1a..d55c0006ef 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -3,20 +3,20 @@ * * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -46,6 +46,9 @@ static void decode_mb(MpegEncContext *s, int ref) s->dest[1] = s->current_picture.f.data[1] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift); s->dest[2] = s->current_picture.f.data[2] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift); + ff_init_block_index(s); + ff_update_block_index(s); + if (CONFIG_H264_DECODER && s->codec_id == CODEC_ID_H264) { H264Context *h = (void*)s; h->mb_xy = s->mb_x + s->mb_y * s->mb_stride; @@ -170,11 +173,68 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma) { int b_x, b_y; + int16_t (*col )[4] = av_malloc(stride*h*sizeof( int16_t)*4); + uint16_t (*dist)[4] = av_malloc(stride*h*sizeof(uint16_t)*4); + + for(b_y=0; b_y<h; b_y++){ + int color= 1024; + int distance= -1; + for(b_x=0; b_x<w; b_x++){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_x; + } + col [b_x + b_y*stride][1]= color; + dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999; + } + color= 1024; + distance= -1; + for(b_x=w-1; b_x>=0; b_x--){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_x; + } + col [b_x + b_y*stride][0]= color; + dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999; + } + } + for(b_x=0; b_x<w; b_x++){ + int color= 1024; + int distance= -1; + for(b_y=0; b_y<h; b_y++){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_y; + } + col [b_x + b_y*stride][3]= color; + dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999; + } + color= 1024; + distance= -1; + for(b_y=h-1; b_y>=0; b_y--){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_y; + } + col [b_x + b_y*stride][2]= color; + dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999; + } + } for (b_y = 0; b_y < h; b_y++) { for (b_x = 0; b_x < w; b_x++) { - int color[4] = { 1024, 1024, 1024, 1024 }; - int distance[4] = { 9999, 9999, 9999, 9999 }; int mb_index, error, j; int64_t guess, weight_sum; mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride; @@ -185,66 +245,19 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, if (!(error & ER_DC_ERROR)) continue; // dc-ok - /* right block */ - for (j = b_x + 1; j < w; j++) { - int mb_index_j = (j >> is_luma) + (b_y >> is_luma) * s->mb_stride; - int error_j = s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); - if (intra_j == 0 || !(error_j & ER_DC_ERROR)) { - color[0] = dc[j + b_y * stride]; - distance[0] = j - b_x; - break; - } - } - - /* left block */ - for (j = b_x - 1; j >= 0; j--) { - int mb_index_j = (j >> is_luma) + (b_y >> is_luma) * s->mb_stride; - int error_j = s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); - if (intra_j == 0 || !(error_j & ER_DC_ERROR)) { - color[1] = dc[j + b_y * stride]; - distance[1] = b_x - j; - break; - } - } - - /* bottom block */ - for (j = b_y + 1; j < h; j++) { - int mb_index_j = (b_x >> is_luma) + (j >> is_luma) * s->mb_stride; - int error_j = s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); - - if (intra_j == 0 || !(error_j & ER_DC_ERROR)) { - color[2] = dc[b_x + j * stride]; - distance[2] = j - b_y; - break; - } - } - - /* top block */ - for (j = b_y - 1; j >= 0; j--) { - int mb_index_j = (b_x >> is_luma) + (j >> is_luma) * s->mb_stride; - int error_j = s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); - if (intra_j == 0 || !(error_j & ER_DC_ERROR)) { - color[3] = dc[b_x + j * stride]; - distance[3] = b_y - j; - break; - } - } - weight_sum = 0; guess = 0; for (j = 0; j < 4; j++) { - int64_t weight = 256 * 256 * 256 * 16 / distance[j]; - guess += weight * (int64_t) color[j]; + int64_t weight = 256 * 256 * 256 * 16 / dist[b_x + b_y*stride][j]; + guess += weight*(int64_t)col[b_x + b_y*stride][j]; weight_sum += weight; } guess = (guess + weight_sum / 2) / weight_sum; dc[b_x + b_y * stride] = guess; } } + av_freep(&col); + av_freep(&dist); } /** @@ -388,7 +401,7 @@ static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, static void guess_mv(MpegEncContext *s) { - uint8_t fixed[s->mb_stride * s->mb_height]; + uint8_t *fixed = av_malloc(s->mb_stride * s->mb_height); #define MV_FROZEN 3 #define MV_CHANGED 2 #define MV_UNCHANGED 1 @@ -414,6 +427,14 @@ static void guess_mv(MpegEncContext *s) fixed[mb_xy] = f; if (f == MV_FROZEN) num_avail++; + else if(s->last_picture.f.data[0] && s->last_picture.f.motion_val[0]){ + const int mb_y= mb_xy / s->mb_stride; + const int mb_x= mb_xy % s->mb_stride; + const int mot_index= (mb_x + mb_y*mot_stride) * mot_step; + s->current_picture.f.motion_val[0][mot_index][0]= s->last_picture.f.motion_val[0][mot_index][0]; + s->current_picture.f.motion_val[0][mot_index][1]= s->last_picture.f.motion_val[0][mot_index][1]; + s->current_picture.f.ref_index[0][4*mb_xy] = s->last_picture.f.ref_index[0][4*mb_xy]; + } } if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || @@ -442,7 +463,7 @@ static void guess_mv(MpegEncContext *s) decode_mb(s, 0); } } - return; + goto end; } for (depth = 0; ; depth++) { @@ -588,7 +609,7 @@ skip_mean_and_median: /* zero MV */ pred_count++; - if (!fixed[mb_xy]) { + if (!fixed[mb_xy] && 0) { if (s->avctx->codec_id == CODEC_ID_H264) { // FIXME } else { @@ -694,7 +715,7 @@ skip_last_mv: } if (none_left) - return; + goto end; for (i = 0; i < s->mb_num; i++) { int mb_xy = s->mb_index2xy[i]; @@ -703,6 +724,8 @@ skip_last_mv: } // printf(":"); fflush(stdout); } +end: + av_free(fixed); } static int is_intra_more_likely(MpegEncContext *s) @@ -766,11 +789,9 @@ static int is_intra_more_likely(MpegEncContext *s) ff_thread_await_progress((AVFrame *) s->last_picture_ptr, mb_y, 0); } - is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr, - s->linesize, 16); - is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, - last_mb_ptr + s->linesize * 16, - s->linesize, 16); + is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16); + // FIXME need await_progress() here + is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16); } else { if (IS_INTRA(s->current_picture.f.mb_type[mb_xy])) is_intra_likely++; @@ -913,6 +934,7 @@ void ff_er_frame_end(MpegEncContext *s) } } +#if 1 /* handle overlapping slices */ for (error_type = 1; error_type <= 3; error_type++) { int end_ok = 0; @@ -933,7 +955,8 @@ void ff_er_frame_end(MpegEncContext *s) end_ok = 0; } } - +#endif +#if 1 /* handle slices with partitions of different length */ if (s->partitioned_frame) { int end_ok = 0; @@ -956,7 +979,7 @@ void ff_er_frame_end(MpegEncContext *s) end_ok = 0; } } - +#endif /* handle missing slices */ if (s->err_recognition & AV_EF_EXPLODE) { int end_ok = 1; @@ -983,6 +1006,7 @@ void ff_er_frame_end(MpegEncContext *s) } } +#if 1 /* backward mark errors */ distance = 9999999; for (error_type = 1; error_type <= 3; error_type++) { @@ -1007,6 +1031,7 @@ void ff_er_frame_end(MpegEncContext *s) distance = 9999999; } } +#endif /* forward mark errors */ error = 0; @@ -1021,7 +1046,7 @@ void ff_er_frame_end(MpegEncContext *s) s->error_status_table[mb_xy] |= error; } } - +#if 1 /* handle not partitioned case */ if (!s->partitioned_frame) { for (i = 0; i < s->mb_num; i++) { @@ -1032,6 +1057,7 @@ void ff_er_frame_end(MpegEncContext *s) s->error_status_table[mb_xy] = error; } } +#endif dc_error = ac_error = mv_error = 0; for (i = 0; i < s->mb_num; i++) { @@ -1213,15 +1239,17 @@ void ff_er_frame_end(MpegEncContext *s) s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3; } } - +#if 1 /* guess DC for damaged blocks */ - guess_dc(s, s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride, 1); - guess_dc(s, s->dc_val[1], s->mb_width, s->mb_height, s->mb_stride, 0); - guess_dc(s, s->dc_val[2], s->mb_width, s->mb_height, s->mb_stride, 0); + guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1); + guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0); + guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0); +#endif /* filter luma DC */ filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride); +#if 1 /* render DC only intra */ for (mb_y = 0; mb_y < s->mb_height; mb_y++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) { @@ -1243,6 +1271,7 @@ void ff_er_frame_end(MpegEncContext *s) put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y); } } +#endif if (s->avctx->error_concealment & FF_EC_DEBLOCK) { /* filter horizontal block boundaries */ diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c index 4ca4ff3951..fd76e59fb2 100644 --- a/libavcodec/escape124.c +++ b/libavcodec/escape124.c @@ -2,20 +2,20 @@ * Escape 124 Video Decoder * Copyright (C) 2008 Eli Friedman (eli.friedman@gmail.com) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -61,6 +61,7 @@ static av_cold int escape124_decode_init(AVCodecContext *avctx) { Escape124Context *s = avctx->priv_data; + avcodec_get_frame_defaults(&s->frame); avctx->pix_fmt = PIX_FMT_RGB555; s->num_superblocks = ((unsigned)avctx->width / 8) * @@ -214,7 +215,8 @@ static int escape124_decode_frame(AVCodecContext *avctx, uint16_t* old_frame_data, *new_frame_data; unsigned old_stride, new_stride; - AVFrame new_frame = { { 0 } }; + AVFrame new_frame; + avcodec_get_frame_defaults(&new_frame); init_get_bits(&gb, buf, buf_size * 8); diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c new file mode 100644 index 0000000000..c9f4d77c6a --- /dev/null +++ b/libavcodec/escape130.c @@ -0,0 +1,319 @@ +/* + * Escape 130 Video Decoder + * Copyright (C) 2008 Eli Friedman (eli.friedman <at> 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" + +#define BITSTREAM_READER_LE +#include "get_bits.h" + +typedef struct Escape130Context { + AVFrame frame; + uint8_t *bases; +} Escape130Context; + +/** + * Initialize the decoder + * @param avctx decoder context + * @return 0 success, negative on error + */ +static av_cold int escape130_decode_init(AVCodecContext *avctx) +{ + Escape130Context *s = avctx->priv_data; + avctx->pix_fmt = PIX_FMT_YUV420P; + + if((avctx->width&1) || (avctx->height&1)){ + av_log(avctx, AV_LOG_ERROR, "Dimensions are not a multiple of the block size\n"); + return AVERROR(EINVAL); + } + + s->bases= av_malloc(avctx->width * avctx->height /4); + + return 0; +} + +static av_cold int escape130_decode_close(AVCodecContext *avctx) +{ + Escape130Context *s = avctx->priv_data; + + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + av_freep(&s->bases); + + return 0; +} + +static unsigned decode_skip_count(GetBitContext* gb) { + unsigned value; + // This function reads a maximum of 27 bits, + // which is within the padding space + if (get_bits_left(gb) < 1+3) + return -1; + + value = get_bits1(gb); + if (value) + return 0; + + value = get_bits(gb, 3); + if (value) + return value; + + value = get_bits(gb, 8); + if (value) + return value + 7; + + value = get_bits(gb, 15); + if (value) + return value + 262; + + return -1; +} + +/** + * Decode a single frame + * @param avctx decoder context + * @param data decoded frame + * @param data_size size of the decoded frame + * @param buf input buffer + * @param buf_size input buffer size + * @return 0 success, -1 on error + */ +static int escape130_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + AVPacket *avpkt) +{ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + Escape130Context *s = avctx->priv_data; + + GetBitContext gb; + unsigned i; + + uint8_t *old_y, *old_cb, *old_cr, + *new_y, *new_cb, *new_cr; + unsigned old_y_stride, old_cb_stride, old_cr_stride, + new_y_stride, new_cb_stride, new_cr_stride; + unsigned total_blocks = avctx->width * avctx->height / 4, + block_index, row_index = 0; + unsigned y[4] = {0}, cb = 16, cr = 16; + unsigned skip = -1; + unsigned y_base = 0; + uint8_t *yb= s->bases; + + AVFrame new_frame = { { 0 } }; + + init_get_bits(&gb, buf, buf_size * 8); + + if (get_bits_left(&gb) < 128) + return -1; + + // Header; no useful information in here + skip_bits_long(&gb, 128); + + new_frame.reference = 3; + if (avctx->get_buffer(avctx, &new_frame)) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + new_y = new_frame.data[0]; + new_cb = new_frame.data[1]; + new_cr = new_frame.data[2]; + new_y_stride = new_frame.linesize[0]; + new_cb_stride = new_frame.linesize[1]; + new_cr_stride = new_frame.linesize[2]; + old_y = s->frame.data[0]; + old_cb = s->frame.data[1]; + old_cr = s->frame.data[2]; + old_y_stride = s->frame.linesize[0]; + old_cb_stride = s->frame.linesize[1]; + old_cr_stride = s->frame.linesize[2]; + + av_log(avctx, AV_LOG_DEBUG, + "Strides: %i, %i\n", + new_y_stride, new_cb_stride); + + for (block_index = 0; block_index < total_blocks; block_index++) { + // Note that this call will make us skip the rest of the blocks + // if the frame prematurely ends + if (skip == -1) + skip = decode_skip_count(&gb); + + if (skip) { + if (old_y) { + y[0] = old_y[0] / 4; + y[1] = old_y[1] / 4; + y[2] = old_y[old_y_stride] / 4; + y[3] = old_y[old_y_stride+1] / 4; + y_base= yb[0]; + cb = old_cb[0] / 8; + cr = old_cr[0] / 8; + } else { + y_base=y[0] = y[1] = y[2] = y[3] = 0; + cb = cr = 16; + } + } else { + if (get_bits1(&gb)) { + static const uint8_t offset_table[] = {2, 4, 10, 20}; + static const int8_t sign_table[64][4] = + { {0, 0, 0, 0}, + {-1, 1, 0, 0}, + {1, -1, 0, 0}, + {-1, 0, 1, 0}, + {-1, 1, 1, 0}, + {0, -1, 1, 0}, + {1, -1, 1, 0}, + {-1, -1, 1, 0}, + {1, 0, -1, 0}, + {0, 1, -1, 0}, + {1, 1, -1, 0}, + {-1, 1, -1, 0}, + {1, -1, -1, 0}, + {-1, 0, 0, 1}, + {-1, 1, 0, 1}, + {0, -1, 0, 1}, + + {0, 0, 0, 0}, + {1, -1, 0, 1}, + {-1, -1, 0, 1}, + {-1, 0, 1, 1}, + {-1, 1, 1, 1}, + {0, -1, 1, 1}, + {1, -1, 1, 1}, + {-1, -1, 1, 1}, + {0, 0, -1, 1}, + {1, 0, -1, 1}, + {-1, 0, -1, 1}, + {0, 1, -1, 1}, + {1, 1, -1, 1}, + {-1, 1, -1, 1}, + {0, -1, -1, 1}, + {1, -1, -1, 1}, + + {0, 0, 0, 0}, + {-1, -1, -1, 1}, + {1, 0, 0, -1}, + {0, 1, 0, -1}, + {1, 1, 0, -1}, + {-1, 1, 0, -1}, + {1, -1, 0, -1}, + {0, 0, 1, -1}, + {1, 0, 1, -1}, + {-1, 0, 1, -1}, + {0, 1, 1, -1}, + {1, 1, 1, -1}, + {-1, 1, 1, -1}, + {0, -1, 1, -1}, + {1, -1, 1, -1}, + {-1, -1, 1, -1}, + + {0, 0, 0, 0}, + {1, 0, -1, -1}, + {0, 1, -1, -1}, + {1, 1, -1, -1}, + {-1, 1, -1, -1}, + {1, -1, -1, -1} }; + unsigned sign_selector = get_bits(&gb, 6); + unsigned difference_selector = get_bits(&gb, 2); + y_base = 2 * get_bits(&gb, 5); + for (i = 0; i < 4; i++) { + y[i] = av_clip((int)y_base + offset_table[difference_selector] * + sign_table[sign_selector][i], 0, 63); + } + } else if (get_bits1(&gb)) { + if (get_bits1(&gb)) { + y_base = get_bits(&gb, 6); + } else { + unsigned adjust_index = get_bits(&gb, 3); + static const int8_t adjust[] = {-4, -3, -2, -1, 1, 2, 3, 4}; + y_base = (y_base + adjust[adjust_index]) & 63; + } + for (i = 0; i < 4; i++) + y[i] = y_base; + } + + if (get_bits1(&gb)) { + if (get_bits1(&gb)) { + cb = get_bits(&gb, 5); + cr = get_bits(&gb, 5); + } else { + unsigned adjust_index = get_bits(&gb, 3); + static const int8_t adjust[2][8] = + { { 1, 1, 0, -1, -1, -1, 0, 1 }, + { 0, 1, 1, 1, 0, -1, -1, -1 } }; + cb = (cb + adjust[0][adjust_index]) & 31; + cr = (cr + adjust[1][adjust_index]) & 31; + } + } + } + *yb++= y_base; + + new_y[0] = y[0] * 4; + new_y[1] = y[1] * 4; + new_y[new_y_stride] = y[2] * 4; + new_y[new_y_stride + 1] = y[3] * 4; + *new_cb = cb * 8; + *new_cr = cr * 8; + + if (old_y) + old_y += 2, old_cb++, old_cr++; + new_y += 2, new_cb++, new_cr++; + row_index++; + if (avctx->width / 2 == row_index) { + row_index = 0; + if (old_y) { + old_y += old_y_stride * 2 - avctx->width; + old_cb += old_cb_stride - avctx->width / 2; + old_cr += old_cr_stride - avctx->width / 2; + } + new_y += new_y_stride * 2 - avctx->width; + new_cb += new_cb_stride - avctx->width / 2; + new_cr += new_cr_stride - avctx->width / 2; + } + + skip--; + } + + av_log(avctx, AV_LOG_DEBUG, + "Escape sizes: %i, %i\n", + buf_size, get_bits_count(&gb) / 8); + + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + *(AVFrame*)data = s->frame = new_frame; + *data_size = sizeof(AVFrame); + + return buf_size; +} + + +AVCodec ff_escape130_decoder = { + .name = "escape130", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_ESCAPE130, + .priv_data_size = sizeof(Escape130Context), + .init = escape130_decode_init, + .close = escape130_decode_close, + .decode = escape130_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Escape 130"), +}; diff --git a/libavcodec/faandct.h b/libavcodec/faandct.h index da8c0e42d9..f43b62f168 100644 --- a/libavcodec/faandct.h +++ b/libavcodec/faandct.h @@ -2,20 +2,20 @@ * Floating point AAN DCT * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/faanidct.c b/libavcodec/faanidct.c index 0b9b458284..dc3d8fbb81 100644 --- a/libavcodec/faanidct.c +++ b/libavcodec/faanidct.c @@ -2,20 +2,20 @@ * Floating point AAN IDCT * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" diff --git a/libavcodec/faanidct.h b/libavcodec/faanidct.h index f3896f7a48..4cf1189286 100644 --- a/libavcodec/faanidct.h +++ b/libavcodec/faanidct.h @@ -2,20 +2,20 @@ * Floating point AAN IDCT * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index e59dad676a..c157b984d3 100644 --- a/libavcodec/faxcompr.c +++ b/libavcodec/faxcompr.c @@ -2,20 +2,20 @@ * CCITT Fax Group 3 and 4 decompression * Copyright (c) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/faxcompr.h b/libavcodec/faxcompr.h index 8157f1fc21..53d11681b2 100644 --- a/libavcodec/faxcompr.h +++ b/libavcodec/faxcompr.h @@ -2,20 +2,20 @@ * CCITT Fax Group 3 and 4 decompression * Copyright (c) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/fft-fixed-test.c b/libavcodec/fft-fixed-test.c index 63cd194576..fa750b6326 100644 --- a/libavcodec/fft-fixed-test.c +++ b/libavcodec/fft-fixed-test.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/fft-internal.h b/libavcodec/fft-internal.h index d30571b733..61066bb18b 100644 --- a/libavcodec/fft-internal.h +++ b/libavcodec/fft-internal.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/fft-test.c b/libavcodec/fft-test.c index f890de61aa..1c88a53fdd 100644 --- a/libavcodec/fft-test.c +++ b/libavcodec/fft-test.c @@ -1,20 +1,20 @@ /* * (c) 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/fft.c b/libavcodec/fft.c index 1e31dde163..6b93a5cdf3 100644 --- a/libavcodec/fft.c +++ b/libavcodec/fft.c @@ -4,20 +4,20 @@ * Copyright (c) 2002 Fabrice Bellard * Partly based on libdjbfft by D. J. Bernstein * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/fft.h b/libavcodec/fft.h index 706f94b574..0e19e947b1 100644 --- a/libavcodec/fft.h +++ b/libavcodec/fft.h @@ -2,20 +2,20 @@ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/fft_fixed.c b/libavcodec/fft_fixed.c index b28091d35c..3955efea05 100644 --- a/libavcodec/fft_fixed.c +++ b/libavcodec/fft_fixed.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/fft_float.c b/libavcodec/fft_float.c index 24c9fdb366..214964631b 100644 --- a/libavcodec/fft_float.c +++ b/libavcodec/fft_float.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ffv1.c b/libavcodec/ffv1.c index 8a6f33f383..586a2963f4 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -3,20 +3,20 @@ * * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -165,6 +165,8 @@ typedef struct FFV1Context{ int version; int width, height; int chroma_h_shift, chroma_v_shift; + int chroma_planes; + int transparency; int flags; int picture_number; AVFrame picture; @@ -180,6 +182,7 @@ typedef struct FFV1Context{ int colorspace; int16_t *sample_buffer; int gob_count; + int packed_at_lsb; int quant_table_count; @@ -543,8 +546,14 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, } encode_line(s, w, sample, plane_index, 8); }else{ - for(x=0; x<w; x++){ - sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->avctx->bits_per_raw_sample); + if(s->packed_at_lsb){ + for(x=0; x<w; x++){ + sample[0][x]= ((uint16_t*)(src + stride*y))[x]; + } + }else{ + for(x=0; x<w; x++){ + sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->avctx->bits_per_raw_sample); + } } encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); } @@ -555,21 +564,22 @@ static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ int x, y, p, i; const int ring_size= s->avctx->context_model ? 3 : 2; - int16_t *sample[3][3]; + int16_t *sample[4][3]; s->run_index=0; - memset(s->sample_buffer, 0, ring_size*3*(w+6)*sizeof(*s->sample_buffer)); + memset(s->sample_buffer, 0, ring_size*4*(w+6)*sizeof(*s->sample_buffer)); for(y=0; y<h; y++){ for(i=0; i<ring_size; i++) - for(p=0; p<3; p++) + for(p=0; p<4; p++) sample[p][i]= s->sample_buffer + p*ring_size*(w+6) + ((h+i-y)%ring_size)*(w+6) + 3; for(x=0; x<w; x++){ - int v= src[x + stride*y]; + unsigned v= src[x + stride*y]; int b= v&0xFF; int g= (v>>8)&0xFF; int r= (v>>16)&0xFF; + int a= v>>24; b -= g; r -= g; @@ -582,11 +592,12 @@ static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int st sample[0][0][x]= g; sample[1][0][x]= b; sample[2][0][x]= r; + sample[3][0][x]= a; } - for(p=0; p<3; p++){ + for(p=0; p<3 + s->transparency; p++){ sample[p][0][-1]= sample[p][1][0 ]; sample[p][1][ w]= sample[p][1][w-1]; - encode_line(s, w, sample[p], FFMIN(p, 1), 9); + encode_line(s, w, sample[p], (p+1)/2, 9); } } } @@ -630,10 +641,10 @@ static void write_header(FFV1Context *f){ put_symbol(c, state, f->colorspace, 0); //YUV cs type if(f->version>0) put_symbol(c, state, f->avctx->bits_per_raw_sample, 0); - put_rac(c, state, 1); //chroma planes - put_symbol(c, state, f->chroma_h_shift, 0); - put_symbol(c, state, f->chroma_v_shift, 0); - put_rac(c, state, 0); //no transparency plane + put_rac(c, state, f->chroma_planes); + put_symbol(c, state, f->chroma_h_shift, 0); + put_symbol(c, state, f->chroma_v_shift, 0); + put_rac(c, state, f->transparency); write_quant_tables(c, f->quant_table); }else{ @@ -659,6 +670,8 @@ static av_cold int common_init(AVCodecContext *avctx){ s->avctx= avctx; s->flags= avctx->flags; + avcodec_get_frame_defaults(&s->picture); + dsputil_init(&s->dsp, avctx); s->width = avctx->width; @@ -678,6 +691,8 @@ static int init_slice_state(FFV1Context *f){ for(i=0; i<f->slice_count; i++){ FFV1Context *fs= f->slice_context[i]; + fs->plane_count= f->plane_count; + fs->transparency= f->transparency; for(j=0; j<f->plane_count; j++){ PlaneContext * const p= &fs->plane[j]; @@ -726,7 +741,7 @@ static av_cold int init_slice_contexts(FFV1Context *f){ fs->slice_x = sxs; fs->slice_y = sys; - fs->sample_buffer = av_malloc(9 * (fs->width+6) * sizeof(*fs->sample_buffer)); + fs->sample_buffer = av_malloc(3*4 * (fs->width+6) * sizeof(*fs->sample_buffer)); if (!fs->sample_buffer) return AVERROR(ENOMEM); } @@ -768,10 +783,10 @@ static int write_extra_header(FFV1Context *f){ } put_symbol(c, state, f->colorspace, 0); //YUV cs type put_symbol(c, state, f->avctx->bits_per_raw_sample, 0); - put_rac(c, state, 1); //chroma planes - put_symbol(c, state, f->chroma_h_shift, 0); - put_symbol(c, state, f->chroma_v_shift, 0); - put_rac(c, state, 0); //no transparency plane + put_rac(c, state, f->chroma_planes); + put_symbol(c, state, f->chroma_h_shift, 0); + put_symbol(c, state, f->chroma_v_shift, 0); + put_rac(c, state, f->transparency); put_symbol(c, state, f->num_h_slices-1, 0); put_symbol(c, state, f->num_v_slices-1, 0); @@ -858,7 +873,7 @@ static av_cold int encode_init(AVCodecContext *avctx) for(i=1; i<256; i++) s->state_transition[i]=ver2_state[i]; - s->plane_count=2; + s->plane_count=3; for(i=0; i<256; i++){ s->quant_table_count=2; if(avctx->bits_per_raw_sample <=8){ @@ -898,6 +913,11 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->coded_frame= &s->picture; switch(avctx->pix_fmt){ + case PIX_FMT_YUV420P9: + case PIX_FMT_YUV420P10: + case PIX_FMT_YUV422P10: + s->packed_at_lsb = 1; + case PIX_FMT_GRAY16: case PIX_FMT_YUV444P16: case PIX_FMT_YUV422P16: case PIX_FMT_YUV420P16: @@ -911,19 +931,33 @@ static av_cold int encode_init(AVCodecContext *avctx) } s->version= FFMAX(s->version, 1); case PIX_FMT_YUV444P: + case PIX_FMT_YUV440P: case PIX_FMT_YUV422P: case PIX_FMT_YUV420P: case PIX_FMT_YUV411P: case PIX_FMT_YUV410P: + s->chroma_planes= avctx->pix_fmt == PIX_FMT_GRAY16 ? 0 : 1; + s->colorspace= 0; + break; + case PIX_FMT_YUVA444P: + case PIX_FMT_YUVA420P: + s->chroma_planes= 1; s->colorspace= 0; + s->transparency= 1; break; case PIX_FMT_RGB32: s->colorspace= 1; + s->transparency= 1; + break; + case PIX_FMT_0RGB32: + s->colorspace= 1; break; default: av_log(avctx, AV_LOG_ERROR, "format not supported\n"); return -1; } + if(!s->transparency) + s->plane_count= 2; avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); s->picture_number=0; @@ -1041,12 +1075,12 @@ static void clear_state(FFV1Context *f){ }else memset(p->state, 128, CONTEXT_SIZE*p->context_count); }else{ - for(j=0; j<p->context_count; j++){ + for(j=0; j<p->context_count; j++){ p->vlc_state[j].drift= 0; p->vlc_state[j].error_sum= 4; //FFMAX((RANGE + 32)/64, 2); p->vlc_state[j].bias= 0; p->vlc_state[j].count= 1; - } + } } } } @@ -1061,6 +1095,7 @@ static int encode_slice(AVCodecContext *c, void *arg){ int x= fs->slice_x; int y= fs->slice_y; AVFrame * const p= &f->picture; + const int ps= (c->bits_per_raw_sample>8)+1; if(f->colorspace==0){ const int chroma_width = -((-width )>>f->chroma_h_shift); @@ -1068,12 +1103,16 @@ static int encode_slice(AVCodecContext *c, void *arg){ const int cx= x>>f->chroma_h_shift; const int cy= y>>f->chroma_v_shift; - encode_plane(fs, p->data[0] + x + y*p->linesize[0], width, height, p->linesize[0], 0); + encode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0); - encode_plane(fs, p->data[1] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); - encode_plane(fs, p->data[2] + cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1); + if (f->chroma_planes){ + encode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); + encode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1); + } + if (fs->transparency) + encode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2); }else{ - encode_rgb_frame(fs, (uint32_t*)(p->data[0]) + x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4); + encode_rgb_frame(fs, (uint32_t*)(p->data[0]) + ps*x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4); } emms_c(); @@ -1327,8 +1366,14 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, } }else{ decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample); - for(x=0; x<w; x++){ - ((uint16_t*)(src + stride*y))[x]= sample[1][x] << (16 - s->avctx->bits_per_raw_sample); + if(s->packed_at_lsb){ + for(x=0; x<w; x++){ + ((uint16_t*)(src + stride*y))[x]= sample[1][x]; + } + }else{ + for(x=0; x<w; x++){ + ((uint16_t*)(src + stride*y))[x]= sample[1][x] << (16 - s->avctx->bits_per_raw_sample); + } } } //STOP_TIMER("decode-line")} @@ -1337,18 +1382,18 @@ static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){ int x, y, p; - int16_t *sample[3][2]; - for(x=0; x<3; x++){ + int16_t *sample[4][2]; + for(x=0; x<4; x++){ sample[x][0] = s->sample_buffer + x*2 *(w+6) + 3; sample[x][1] = s->sample_buffer + (x*2+1)*(w+6) + 3; } s->run_index=0; - memset(s->sample_buffer, 0, 6*(w+6)*sizeof(*s->sample_buffer)); + memset(s->sample_buffer, 0, 8*(w+6)*sizeof(*s->sample_buffer)); for(y=0; y<h; y++){ - for(p=0; p<3; p++){ + for(p=0; p<3 + s->transparency; p++){ int16_t *temp = sample[p][0]; //FIXME try a normal buffer sample[p][0]= sample[p][1]; @@ -1356,12 +1401,13 @@ static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int st sample[p][1][-1]= sample[p][0][0 ]; sample[p][0][ w]= sample[p][0][w-1]; - decode_line(s, w, sample[p], FFMIN(p, 1), 9); + decode_line(s, w, sample[p], (p+1)/2, 9); } for(x=0; x<w; x++){ int g= sample[0][1][x]; int b= sample[1][1][x]; int r= sample[2][1][x]; + int a= sample[3][1][x]; // assert(g>=0 && b>=0 && r>=0); // assert(g<256 && b<512 && r<512); @@ -1372,7 +1418,7 @@ static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int st b += g; r += g; - src[x + stride*y]= b + (g<<8) + (r<<16) + (0xFF<<24); + src[x + stride*y]= b + (g<<8) + (r<<16) + (a<<24); } } } @@ -1384,6 +1430,7 @@ static int decode_slice(AVCodecContext *c, void *arg){ int height= fs->slice_height; int x= fs->slice_x; int y= fs->slice_y; + const int ps= (c->bits_per_raw_sample>8)+1; AVFrame * const p= &f->picture; av_assert1(width && height); @@ -1392,12 +1439,16 @@ static int decode_slice(AVCodecContext *c, void *arg){ const int chroma_height= -((-height)>>f->chroma_v_shift); const int cx= x>>f->chroma_h_shift; const int cy= y>>f->chroma_v_shift; - decode_plane(fs, p->data[0] + x + y*p->linesize[0], width, height, p->linesize[0], 0); + decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0); - decode_plane(fs, p->data[1] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); - decode_plane(fs, p->data[2] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[2], 1); + if (f->chroma_planes){ + decode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1); + decode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1); + } + if (fs->transparency) + decode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2); }else{ - decode_rgb_frame(fs, (uint32_t*)p->data[0] + x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4); + decode_rgb_frame(fs, (uint32_t*)p->data[0] + ps*x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4); } emms_c(); @@ -1470,8 +1521,8 @@ static int read_extra_header(FFV1Context *f){ get_rac(c, state); //no chroma = false f->chroma_h_shift= get_symbol(c, state, 0); f->chroma_v_shift= get_symbol(c, state, 0); - get_rac(c, state); //transparency plane - f->plane_count= 2; + f->transparency= get_rac(c, state); + f->plane_count= 2 + f->transparency; f->num_h_slices= 1 + get_symbol(c, state, 0); f->num_v_slices= 1 + get_symbol(c, state, 0); if(f->num_h_slices > (unsigned)f->width || f->num_v_slices > (unsigned)f->height){ @@ -1524,17 +1575,20 @@ static int read_header(FFV1Context *f){ f->colorspace= get_symbol(c, state, 0); //YUV cs type if(f->version>0) f->avctx->bits_per_raw_sample= get_symbol(c, state, 0); - get_rac(c, state); //no chroma = false + f->chroma_planes= get_rac(c, state); f->chroma_h_shift= get_symbol(c, state, 0); f->chroma_v_shift= get_symbol(c, state, 0); - get_rac(c, state); //transparency plane - f->plane_count= 2; + f->transparency= get_rac(c, state); + f->plane_count= 2 + f->transparency; } if(f->colorspace==0){ - if(f->avctx->bits_per_raw_sample<=8){ + if(f->avctx->bits_per_raw_sample>8 && !f->transparency && !f->chroma_planes){ + f->avctx->pix_fmt= PIX_FMT_GRAY16; + }else if(f->avctx->bits_per_raw_sample<=8 && !f->transparency){ switch(16*f->chroma_h_shift + f->chroma_v_shift){ case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break; + case 0x01: f->avctx->pix_fmt= PIX_FMT_YUV440P; break; case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break; case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break; case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break; @@ -1543,7 +1597,33 @@ static int read_header(FFV1Context *f){ av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); return -1; } - }else{ + }else if(f->avctx->bits_per_raw_sample<=8 && f->transparency){ + switch(16*f->chroma_h_shift + f->chroma_v_shift){ + case 0x00: f->avctx->pix_fmt= PIX_FMT_YUVA444P; break; + case 0x11: f->avctx->pix_fmt= PIX_FMT_YUVA420P; break; + default: + av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); + return -1; + } + }else if(f->avctx->bits_per_raw_sample==9) { + switch(16*f->chroma_h_shift + f->chroma_v_shift){ + case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break; + case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break; + case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P9 ; f->packed_at_lsb=1; break; + default: + av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); + return -1; + } + }else if(f->avctx->bits_per_raw_sample==10) { + switch(16*f->chroma_h_shift + f->chroma_v_shift){ + case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break; + case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P10; f->packed_at_lsb=1; break; + case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P10; f->packed_at_lsb=1; break; + default: + av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); + return -1; + } + }else { switch(16*f->chroma_h_shift + f->chroma_v_shift){ case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P16; break; case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P16; break; @@ -1558,7 +1638,8 @@ static int read_header(FFV1Context *f){ av_log(f->avctx, AV_LOG_ERROR, "chroma subsampling not supported in this colorspace\n"); return -1; } - f->avctx->pix_fmt= PIX_FMT_RGB32; + if(f->transparency) f->avctx->pix_fmt= PIX_FMT_RGB32; + else f->avctx->pix_fmt= PIX_FMT_0RGB32; }else{ av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n"); return -1; @@ -1580,6 +1661,7 @@ static int read_header(FFV1Context *f){ for(j=0; j<f->slice_count; j++){ FFV1Context *fs= f->slice_context[j]; fs->ac= f->ac; + fs->packed_at_lsb= f->packed_at_lsb; if(f->version >= 2){ fs->slice_x = get_symbol(c, state, 0) *f->width ; @@ -1745,7 +1827,7 @@ AVCodec ff_ffv1_encoder = { .encode = encode_frame, .close = common_end, .capabilities = CODEC_CAP_SLICE_THREADS, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_NONE}, + .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUVA420P, PIX_FMT_YUV444P, PIX_FMT_YUVA444P, PIX_FMT_YUV440P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_0RGB32, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_YUV420P9, PIX_FMT_YUV420P10, PIX_FMT_YUV422P10, PIX_FMT_GRAY16, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), }; #endif diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c new file mode 100644 index 0000000000..d18dd91452 --- /dev/null +++ b/libavcodec/ffwavesynth.c @@ -0,0 +1,482 @@ +/* + * Wavesynth pseudo-codec + * Copyright (c) 2011 Nicolas George + * + * 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 "libavutil/intreadwrite.h" +#include "libavutil/log.h" +#include "avcodec.h" + +#define SIN_BITS 14 +#define WS_MAX_CHANNELS 32 +#define INF_TS 0x7FFFFFFFFFFFFFFF + +#define PINK_UNIT 128 + +/* + Format of the extradata and packets + + THIS INFORMATION IS NOT PART OF THE PUBLIC API OR ABI. + IT CAN CHANGE WITHOUT NOTIFICATION. + + All numbers are in little endian. + + The codec extradata define a set of intervals with uniform content. + Overlapping intervals are added together. + + extradata: + uint32 number of intervals + ... intervals + + interval: + int64 start timestamp; time_base must be 1/sample_rate; + start timestamps must be in ascending order + int64 end timestamp + uint32 type + uint32 channels mask + ... additional information, depends on type + + sine interval (type fourcc "SINE"): + int32 start frequency, in 1/(1<<16) Hz + int32 end frequency + int32 start amplitude, 1<<16 is the full amplitude + int32 end amplitude + uint32 start phase, 0 is sin(0), 0x20000000 is sin(pi/2), etc.; + n | (1<<31) means to match the phase of previous channel #n + + pink noise interval (type fourcc "NOIS"): + int32 start amplitude + int32 end amplitude + + The input packets encode the time and duration of the requested segment. + + packet: + int64 start timestamp + int32 duration + +*/ + +enum ws_interval_type { + WS_SINE = MKTAG('S','I','N','E'), + WS_NOISE = MKTAG('N','O','I','S'), +}; + +struct ws_interval { + int64_t ts_start, ts_end; + uint64_t phi0, dphi0, ddphi; + uint64_t amp0, damp; + uint64_t phi, dphi, amp; + uint32_t channels; + enum ws_interval_type type; + int next; +}; + +struct wavesynth_context { + int64_t cur_ts; + int64_t next_ts; + int32_t *sin; + AVFrame frame; + struct ws_interval *inter; + uint32_t dither_state; + uint32_t pink_state; + int32_t pink_pool[PINK_UNIT]; + unsigned pink_need, pink_pos; + int nb_inter; + int cur_inter; + int next_inter; +}; + +#define LCG_A 1284865837 +#define LCG_C 4150755663 +#define LCG_AI 849225893 /* A*AI = 1 [mod 1<<32] */ + +static uint32_t lcg_next(uint32_t *s) +{ + *s = *s * LCG_A + LCG_C; + return *s; +} + +static void lcg_seek(uint32_t *s, int64_t dt) +{ + uint32_t a, c, t = *s; + + if (dt >= 0) { + a = LCG_A; + c = LCG_C; + } else { /* coefficients for a step backward */ + a = LCG_AI; + c = (uint32_t)(LCG_AI * LCG_C); + dt = -dt; + } + while (dt) { + if (dt & 1) + t = a * t + c; + c *= a + 1; /* coefficients for a double step */ + a *= a; + dt >>= 1; + } + *s = t; +} + +/* Emulate pink noise by summing white noise at the sampling frequency, + * white noise at half the sampling frequency (each value taken twice), + * etc., with a total of 8 octaves. + * This is known as the Voss-McCartney algorithm. */ + +static void pink_fill(struct wavesynth_context *ws) +{ + int32_t vt[7] = { 0 }, v = 0; + int i, j; + + ws->pink_pos = 0; + if (!ws->pink_need) + return; + for (i = 0; i < PINK_UNIT; i++) { + for (j = 0; j < 7; j++) { + if ((i >> j) & 1) + break; + v -= vt[j]; + vt[j] = (int32_t)lcg_next(&ws->pink_state) >> 3; + v += vt[j]; + } + ws->pink_pool[i] = v + ((int32_t)lcg_next(&ws->pink_state) >> 3); + } + lcg_next(&ws->pink_state); /* so we use exactly 256 steps */ +} + +/** + * @return (1<<64) * a / b, without overflow, if a < b + */ +static uint64_t frac64(uint64_t a, uint64_t b) +{ + uint64_t r = 0; + int i; + + if (b < (uint64_t)1 << 32) { /* b small, use two 32-bits steps */ + a <<= 32; + return ((a / b) << 32) | ((a % b) << 32) / b; + } + if (b < (uint64_t)1 << 48) { /* b medium, use four 16-bits steps */ + for (i = 0; i < 4; i++) { + a <<= 16; + r = (r << 16) | (a / b); + a %= b; + } + return r; + } + for (i = 63; i >= 0; i--) { + if (a >= (uint64_t)1 << 63 || a << 1 >= b) { + r |= (uint64_t)1 << i; + a = (a << 1) - b; + } else { + a <<= 1; + } + } + return r; +} + +static uint64_t phi_at(struct ws_interval *in, int64_t ts) +{ + uint64_t dt = ts - in->ts_start; + uint64_t dt2 = dt & 1 ? /* dt * (dt - 1) / 2 without overflow */ + dt * ((dt - 1) >> 1) : (dt >> 1) * (dt - 1); + return in->phi0 + dt * in->dphi0 + dt2 * in->ddphi; +} + +static void wavesynth_seek(struct wavesynth_context *ws, int64_t ts) +{ + int *last, i; + struct ws_interval *in; + + last = &ws->cur_inter; + for (i = 0; i < ws->nb_inter; i++) { + in = &ws->inter[i]; + if (ts < in->ts_start) + break; + if (ts >= in->ts_end) + continue; + *last = i; + last = &in->next; + in->phi = phi_at(in, ts); + in->dphi = in->dphi0 + (ts - in->ts_start) * in->ddphi; + in->amp = in->amp0 + (ts - in->ts_start) * in->damp; + } + ws->next_inter = i; + ws->next_ts = i < ws->nb_inter ? ws->inter[i].ts_start : INF_TS; + *last = -1; + lcg_seek(&ws->dither_state, ts - ws->cur_ts); + if (ws->pink_need) { + int64_t pink_ts_cur = (ws->cur_ts + PINK_UNIT - 1) & ~(PINK_UNIT - 1); + int64_t pink_ts_next = ts & ~(PINK_UNIT - 1); + int pos = ts & (PINK_UNIT - 1); + lcg_seek(&ws->pink_state, (pink_ts_next - pink_ts_cur) << 1); + if (pos) { + pink_fill(ws); + ws->pink_pos = pos; + } else { + ws->pink_pos = PINK_UNIT; + } + } + ws->cur_ts = ts; +} + +static int wavesynth_parse_extradata(AVCodecContext *avc) +{ + struct wavesynth_context *ws = avc->priv_data; + struct ws_interval *in; + uint8_t *edata, *edata_end; + int32_t f1, f2, a1, a2; + uint32_t phi; + int64_t dphi1, dphi2, dt, cur_ts = -0x8000000000000000; + int i; + + if (avc->extradata_size < 4) + return AVERROR(EINVAL); + edata = avc->extradata; + edata_end = edata + avc->extradata_size; + ws->nb_inter = AV_RL32(edata); + edata += 4; + if (ws->nb_inter < 0) + return AVERROR(EINVAL); + ws->inter = av_calloc(ws->nb_inter, sizeof(*ws->inter)); + if (!ws->inter) + return AVERROR(ENOMEM); + for (i = 0; i < ws->nb_inter; i++) { + in = &ws->inter[i]; + if (edata_end - edata < 24) + return AVERROR(EINVAL); + in->ts_start = AV_RL64(edata + 0); + in->ts_end = AV_RL64(edata + 8); + in->type = AV_RL32(edata + 16); + in->channels = AV_RL32(edata + 20); + edata += 24; + if (in->ts_start < cur_ts || in->ts_end <= in->ts_start) + return AVERROR(EINVAL); + cur_ts = in->ts_start; + dt = in->ts_end - in->ts_start; + switch (in->type) { + case WS_SINE: + if (edata_end - edata < 20) + return AVERROR(EINVAL); + f1 = AV_RL32(edata + 0); + f2 = AV_RL32(edata + 4); + a1 = AV_RL32(edata + 8); + a2 = AV_RL32(edata + 12); + phi = AV_RL32(edata + 16); + edata += 20; + dphi1 = frac64(f1, (int64_t)avc->sample_rate << 16); + dphi2 = frac64(f2, (int64_t)avc->sample_rate << 16); + in->dphi0 = dphi1; + in->ddphi = (dphi2 - dphi1) / dt; + if (phi & 0x80000000) { + phi &= ~0x80000000; + if (phi >= i) + return AVERROR(EINVAL); + in->phi0 = phi_at(&ws->inter[phi], in->ts_start); + } else { + in->phi0 = (uint64_t)phi << 33; + } + break; + case WS_NOISE: + if (edata_end - edata < 8) + return AVERROR(EINVAL); + a1 = AV_RL32(edata + 0); + a2 = AV_RL32(edata + 4); + edata += 8; + break; + default: + return AVERROR(EINVAL); + } + in->amp0 = (int64_t)a1 << 32; + in->damp = (((int64_t)a2 << 32) - ((int64_t)a1 << 32)) / dt; + } + if (edata != edata_end) + return AVERROR(EINVAL); + return 0; +} + +static av_cold int wavesynth_init(AVCodecContext *avc) +{ + struct wavesynth_context *ws = avc->priv_data; + int i, r; + + if (avc->channels > WS_MAX_CHANNELS) { + av_log(avc, AV_LOG_ERROR, + "This implementation is limited to %d channels.\n", + WS_MAX_CHANNELS); + return AVERROR(EINVAL); + } + r = wavesynth_parse_extradata(avc); + if (r < 0) { + av_log(avc, AV_LOG_ERROR, "Invalid intervals definitions.\n"); + goto fail; + } + ws->sin = av_malloc(sizeof(*ws->sin) << SIN_BITS); + if (!ws->sin) { + r = AVERROR(ENOMEM); + goto fail; + } + for (i = 0; i < 1 << SIN_BITS; i++) + ws->sin[i] = floor(32767 * sin(2 * M_PI * i / (1 << SIN_BITS))); + ws->dither_state = MKTAG('D','I','T','H'); + for (i = 0; i < ws->nb_inter; i++) + ws->pink_need += ws->inter[i].type == WS_NOISE; + ws->pink_state = MKTAG('P','I','N','K'); + ws->pink_pos = PINK_UNIT; + avcodec_get_frame_defaults(&ws->frame); + avc->coded_frame = &ws->frame; + wavesynth_seek(ws, 0); + avc->sample_fmt = AV_SAMPLE_FMT_S16; + return 0; + +fail: + av_free(ws->inter); + av_free(ws->sin); + return r; +} + +static void wavesynth_synth_sample(struct wavesynth_context *ws, int64_t ts, + int32_t *channels) +{ + int32_t amp, val, *cv; + struct ws_interval *in; + int i, *last, pink; + uint32_t c, all_ch = 0; + + i = ws->cur_inter; + last = &ws->cur_inter; + if (ws->pink_pos == PINK_UNIT) + pink_fill(ws); + pink = ws->pink_pool[ws->pink_pos++] >> 16; + while (i >= 0) { + in = &ws->inter[i]; + i = in->next; + if (ts >= in->ts_end) { + *last = i; + continue; + } + last = &in->next; + amp = in->amp >> 32; + in->amp += in->damp; + switch (in->type) { + case WS_SINE: + val = amp * ws->sin[in->phi >> (64 - SIN_BITS)]; + in->phi += in->dphi; + in->dphi += in->ddphi; + break; + case WS_NOISE: + val = amp * pink; + break; + default: + val = 0; + } + all_ch |= in->channels; + for (c = in->channels, cv = channels; c; c >>= 1, cv++) + if (c & 1) + *cv += val; + } + val = (int32_t)lcg_next(&ws->dither_state) >> 16; + for (c = all_ch, cv = channels; c; c >>= 1, cv++) + if (c & 1) + *cv += val; +} + +static void wavesynth_enter_intervals(struct wavesynth_context *ws, int64_t ts) +{ + int *last, i; + struct ws_interval *in; + + last = &ws->cur_inter; + for (i = ws->cur_inter; i >= 0; i = ws->inter[i].next) + last = &ws->inter[i].next; + for (i = ws->next_inter; i < ws->nb_inter; i++) { + in = &ws->inter[i]; + if (ts < in->ts_start) + break; + if (ts >= in->ts_end) + continue; + *last = i; + last = &in->next; + in->phi = in->phi0; + in->dphi = in->dphi0; + in->amp = in->amp0; + } + ws->next_inter = i; + ws->next_ts = i < ws->nb_inter ? ws->inter[i].ts_start : INF_TS; + *last = -1; +} + +static int wavesynth_decode(AVCodecContext *avc, void *rframe, int *rgot_frame, + AVPacket *packet) +{ + struct wavesynth_context *ws = avc->priv_data; + int64_t ts; + int duration; + int s, c, r; + int16_t *pcm; + int32_t channels[WS_MAX_CHANNELS]; + + *rgot_frame = 0; + if (packet->size != 12) + return AVERROR_INVALIDDATA; + ts = AV_RL64(packet->data); + if (ts != ws->cur_ts) + wavesynth_seek(ws, ts); + duration = AV_RL32(packet->data + 8); + if (duration <= 0) + return AVERROR(EINVAL); + ws->frame.nb_samples = duration; + r = avc->get_buffer(avc, &ws->frame); + if (r < 0) + return r; + pcm = (int16_t *)ws->frame.data[0]; + for (s = 0; s < duration; s++, ts++) { + memset(channels, 0, avc->channels * sizeof(*channels)); + if (ts >= ws->next_ts) + wavesynth_enter_intervals(ws, ts); + wavesynth_synth_sample(ws, ts, channels); + for (c = 0; c < avc->channels; c++) + *(pcm++) = channels[c] >> 16; + } + ws->cur_ts += duration; + *rgot_frame = 1; + *(AVFrame *)rframe = ws->frame; + return packet->size; +} + +static av_cold int wavesynth_close(AVCodecContext *avc) +{ + struct wavesynth_context *ws = avc->priv_data; + + av_free(ws->sin); + av_free(ws->inter); + return 0; +} + +AVCodec ff_ffwavesynth_decoder = { + .name = "wavesynth", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_FFWAVESYNTH, + .priv_data_size = sizeof(struct wavesynth_context), + .init = wavesynth_init, + .close = wavesynth_close, + .decode = wavesynth_decode, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Wave synthesis pseudo-codec"), +}; diff --git a/libavcodec/flac.c b/libavcodec/flac.c index e6a427af11..5ed3ef7fc3 100644 --- a/libavcodec/flac.c +++ b/libavcodec/flac.c @@ -2,26 +2,27 @@ * FLAC common code * Copyright (c) 2009 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavutil/crc.h" #include "flac.h" #include "flacdata.h" +#include "vorbis.h" static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 }; @@ -54,9 +55,12 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, fi->ch_mode = get_bits(gb, 4); if (fi->ch_mode < FLAC_MAX_CHANNELS) { fi->channels = fi->ch_mode + 1; + if (fi->ch_mode <= 5) + avctx->channel_layout = ff_vorbis_channel_layouts[fi->ch_mode]; fi->ch_mode = FLAC_CHMODE_INDEPENDENT; } else if (fi->ch_mode <= FLAC_CHMODE_MID_SIDE) { fi->channels = 2; + avctx->channel_layout = AV_CH_LAYOUT_STEREO; } else { av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid channel mode: %d\n", fi->ch_mode); diff --git a/libavcodec/flac.h b/libavcodec/flac.h index b826fd43bd..65965af6ad 100644 --- a/libavcodec/flac.h +++ b/libavcodec/flac.h @@ -2,20 +2,20 @@ * FLAC (Free Lossless Audio Codec) decoder/demuxer common functions * Copyright (c) 2008 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index 87f3f95042..ae7edaa052 100644 --- a/libavcodec/flac_parser.c +++ b/libavcodec/flac_parser.c @@ -2,20 +2,20 @@ * FLAC parser * Copyright (c) 2010 Michael Chinen * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/flacdata.c b/libavcodec/flacdata.c index 820c3aa492..6fcbe3955a 100644 --- a/libavcodec/flacdata.c +++ b/libavcodec/flacdata.c @@ -2,20 +2,20 @@ * FLAC data * Copyright (c) 2003 Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/flacdata.h b/libavcodec/flacdata.h index f56637773c..96a50b9183 100644 --- a/libavcodec/flacdata.h +++ b/libavcodec/flacdata.h @@ -2,20 +2,20 @@ * FLAC data header * Copyright (c) 2003 Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/flacdec.c b/libavcodec/flacdec.c index 58eb66def9..ca0863107a 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -2,20 +2,20 @@ * FLAC (Free Lossless Audio Codec) decoder * Copyright (c) 2003 Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/flacenc.c b/libavcodec/flacenc.c index 900714120a..ecf883e652 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -2,20 +2,20 @@ * FLAC audio encoder * Copyright (c) 2006 Justin Ruggles <justin.ruggles@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -371,6 +371,28 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) if (!avctx->coded_frame) return AVERROR(ENOMEM); + if (channels == 3 && + avctx->channel_layout != (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) || + channels == 4 && + avctx->channel_layout != AV_CH_LAYOUT_2_2 && + avctx->channel_layout != AV_CH_LAYOUT_QUAD || + channels == 5 && + avctx->channel_layout != AV_CH_LAYOUT_5POINT0 && + avctx->channel_layout != AV_CH_LAYOUT_5POINT0_BACK || + channels == 6 && + avctx->channel_layout != AV_CH_LAYOUT_5POINT1 && + avctx->channel_layout != AV_CH_LAYOUT_5POINT1_BACK) { + if (avctx->channel_layout) { + av_log(avctx, AV_LOG_ERROR, "Channel layout not supported by Flac, " + "output stream will have incorrect " + "channel layout.\n"); + } else { + av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The encoder " + "will use Flac channel layout for " + "%d channels.\n", channels); + } + } + ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size, s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON); @@ -1296,7 +1318,7 @@ AVCodec ff_flac_encoder = { .init = flac_encode_init, .encode = flac_encode_frame, .close = flac_encode_close, - .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, + .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_LOSSLESS, .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), .priv_class = &flac_encoder_class, diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c index c99c21c719..3861344cb7 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -3,20 +3,20 @@ * Copyright (C) 2004 Alex Beregszaszi * Copyright (C) 2006 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -115,6 +115,7 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx) return 1; } avctx->pix_fmt = PIX_FMT_BGR24; + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c new file mode 100644 index 0000000000..6466be7858 --- /dev/null +++ b/libavcodec/flashsv2enc.c @@ -0,0 +1,907 @@ +/* + * Flash Screen Video Version 2 encoder + * Copyright (C) 2009 Joshua Warner + * + * 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 + * Flash Screen Video Version 2 encoder + * @author Joshua Warner + */ + +/* Differences from version 1 stream: + * NOTE: Currently, the only player that supports version 2 streams is Adobe Flash Player itself. + * * Supports sending only a range of scanlines in a block, + * indicating a difference from the corresponding block in the last keyframe. + * * Supports initializing the zlib dictionary with data from the corresponding + * block in the last keyframe, to improve compression. + * * Supports a hybrid 15-bit rgb / 7-bit palette color space. + */ + +/* TODO: + * Don't keep Block structures for both current frame and keyframe. + * Make better heuristics for deciding stream parameters (optimum_* functions). Currently these return constants. + * Figure out how to encode palette information in the stream, choose an optimum palette at each keyframe. + * Figure out how the zlibPrimeCompressCurrent flag works, implement support. + * Find other sample files (that weren't generated here), develop a decoder. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> + +#include "libavutil/imgutils.h" +#include "avcodec.h" +#include "put_bits.h" +#include "bytestream.h" + +#define HAS_IFRAME_IMAGE 0x02 +#define HAS_PALLET_INFO 0x01 + +#define COLORSPACE_BGR 0x00 +#define COLORSPACE_15_7 0x10 +#define HAS_DIFF_BLOCKS 0x04 +#define ZLIB_PRIME_COMPRESS_CURRENT 0x02 +#define ZLIB_PRIME_COMPRESS_PREVIOUS 0x01 + +// Disables experimental "smart" parameter-choosing code, as well as the statistics that it depends on. +// At the moment, the "smart" code is a great example of how the parameters *shouldn't* be chosen. +#define FLASHSV2_DUMB + +typedef struct Block { + uint8_t *enc; + uint8_t *sl_begin, *sl_end; + int enc_size; + uint8_t *data; + unsigned long data_size; + + uint8_t start, len; + uint8_t dirty; + uint8_t col, row, width, height; + uint8_t flags; +} Block; + +typedef struct Palette { + unsigned colors[128]; + uint8_t index[1 << 15]; +} Palette; + +typedef struct FlashSV2Context { + AVCodecContext *avctx; + uint8_t *current_frame; + uint8_t *key_frame; + AVFrame frame; + uint8_t *encbuffer; + uint8_t *keybuffer; + uint8_t *databuffer; + + Block *frame_blocks; + Block *key_blocks; + int frame_size; + int blocks_size; + + int use15_7, dist, comp; + + int rows, cols; + + int last_key_frame; + + int image_width, image_height; + int block_width, block_height; + uint8_t flags; + uint8_t use_custom_palette; + uint8_t palette_type; ///< 0=>default, 1=>custom - changed when palette regenerated. + Palette palette; +#ifndef FLASHSV2_DUMB + double tot_blocks; ///< blocks encoded since last keyframe + double diff_blocks; ///< blocks that were different since last keyframe + double tot_lines; ///< total scanlines in image since last keyframe + double diff_lines; ///< scanlines that were different since last keyframe + double raw_size; ///< size of raw frames since last keyframe + double comp_size; ///< size of compressed data since last keyframe + double uncomp_size; ///< size of uncompressed data since last keyframe + + double total_bits; ///< total bits written to stream so far +#endif +} FlashSV2Context; + +static av_cold void cleanup(FlashSV2Context * s) +{ + av_freep(&s->encbuffer); + av_freep(&s->keybuffer); + av_freep(&s->databuffer); + av_freep(&s->current_frame); + av_freep(&s->key_frame); + + av_freep(&s->frame_blocks); + av_freep(&s->key_blocks); +} + +static void init_blocks(FlashSV2Context * s, Block * blocks, + uint8_t * encbuf, uint8_t * databuf) +{ + int row, col; + Block *b; + for (col = 0; col < s->cols; col++) { + for (row = 0; row < s->rows; row++) { + b = blocks + (col + row * s->cols); + b->width = (col < s->cols - 1) ? + s->block_width : + s->image_width - col * s->block_width; + + b->height = (row < s->rows - 1) ? + s->block_height : + s->image_height - row * s->block_height; + + b->row = row; + b->col = col; + b->enc = encbuf; + b->data = databuf; + encbuf += b->width * b->height * 3; + databuf += !databuf ? 0 : b->width * b->height * 6; + } + } +} + +static void reset_stats(FlashSV2Context * s) +{ +#ifndef FLASHSV2_DUMB + s->diff_blocks = 0.1; + s->tot_blocks = 1; + s->diff_lines = 0.1; + s->tot_lines = 1; + s->raw_size = s->comp_size = s->uncomp_size = 10; +#endif +} + +static av_cold int flashsv2_encode_init(AVCodecContext * avctx) +{ + FlashSV2Context *s = avctx->priv_data; + + s->avctx = avctx; + + s->comp = avctx->compression_level; + if (s->comp == -1) + s->comp = 9; + if (s->comp < 0 || s->comp > 9) { + av_log(avctx, AV_LOG_ERROR, + "Compression level should be 0-9, not %d\n", s->comp); + return -1; + } + + + if ((avctx->width > 4095) || (avctx->height > 4095)) { + av_log(avctx, AV_LOG_ERROR, + "Input dimensions too large, input must be max 4096x4096 !\n"); + return -1; + } + + if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) + return -1; + + + s->last_key_frame = 0; + + s->image_width = avctx->width; + s->image_height = avctx->height; + + s->block_width = (s->image_width / 12) & ~15; + s->block_height = (s->image_height / 12) & ~15; + + s->rows = (s->image_height + s->block_height - 1) / s->block_height; + s->cols = (s->image_width + s->block_width - 1) / s->block_width; + + s->frame_size = s->image_width * s->image_height * 3; + s->blocks_size = s->rows * s->cols * sizeof(Block); + + s->encbuffer = av_mallocz(s->frame_size); + s->keybuffer = av_mallocz(s->frame_size); + s->databuffer = av_mallocz(s->frame_size * 6); + s->current_frame = av_mallocz(s->frame_size); + s->key_frame = av_mallocz(s->frame_size); + s->frame_blocks = av_mallocz(s->blocks_size); + s->key_blocks = av_mallocz(s->blocks_size); + + init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer); + init_blocks(s, s->key_blocks, s->keybuffer, 0); + reset_stats(s); +#ifndef FLASHSV2_DUMB + s->total_bits = 1; +#endif + + s->use_custom_palette = 0; + s->palette_type = -1; // so that the palette will be generated in reconfigure_at_keyframe + + if (!s->encbuffer || !s->keybuffer || !s->databuffer + || !s->current_frame || !s->key_frame || !s->key_blocks + || !s->frame_blocks) { + av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); + cleanup(s); + return -1; + } + + return 0; +} + +static int new_key_frame(FlashSV2Context * s) +{ + int i; + memcpy(s->key_blocks, s->frame_blocks, s->blocks_size); + memcpy(s->key_frame, s->current_frame, s->frame_size); + + for (i = 0; i < s->rows * s->cols; i++) { + s->key_blocks[i].enc += (s->keybuffer - s->encbuffer); + s->key_blocks[i].sl_begin = 0; + s->key_blocks[i].sl_end = 0; + s->key_blocks[i].data = 0; + } + FFSWAP(uint8_t * , s->keybuffer, s->encbuffer); + + return 0; +} + +static int write_palette(FlashSV2Context * s, uint8_t * buf, int buf_size) +{ + //this isn't implemented yet! Default palette only! + return -1; +} + +static int write_header(FlashSV2Context * s, uint8_t * buf, int buf_size) +{ + PutBitContext pb; + int buf_pos, len; + + if (buf_size < 5) + return -1; + + init_put_bits(&pb, buf, buf_size * 8); + + put_bits(&pb, 4, (s->block_width >> 4) - 1); + put_bits(&pb, 12, s->image_width); + put_bits(&pb, 4, (s->block_height >> 4) - 1); + put_bits(&pb, 12, s->image_height); + + flush_put_bits(&pb); + buf_pos = 4; + + buf[buf_pos++] = s->flags; + + if (s->flags & HAS_PALLET_INFO) { + len = write_palette(s, buf + buf_pos, buf_size - buf_pos); + if (len < 0) + return -1; + buf_pos += len; + } + + return buf_pos; +} + +static int write_block(Block * b, uint8_t * buf, int buf_size) +{ + int buf_pos = 0; + unsigned block_size = b->data_size; + + if (b->flags & HAS_DIFF_BLOCKS) + block_size += 2; + if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT) + block_size += 2; + if (block_size > 0) + block_size += 1; + if (buf_size < block_size + 2) + return -1; + + buf[buf_pos++] = block_size >> 8; + buf[buf_pos++] = block_size; + + if (block_size == 0) + return buf_pos; + + buf[buf_pos++] = b->flags; + + if (b->flags & HAS_DIFF_BLOCKS) { + buf[buf_pos++] = (b->start); + buf[buf_pos++] = (b->len); + } + + if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT) { + //This feature of the format is poorly understood, and as of now, unused. + buf[buf_pos++] = (b->col); + buf[buf_pos++] = (b->row); + } + + memcpy(buf + buf_pos, b->data, b->data_size); + + buf_pos += b->data_size; + + return buf_pos; +} + +static int encode_zlib(Block * b, uint8_t * buf, unsigned long *buf_size, int comp) +{ + int res = compress2(buf, buf_size, b->sl_begin, b->sl_end - b->sl_begin, comp); + return res == Z_OK ? 0 : -1; +} + +static int encode_zlibprime(Block * b, Block * prime, uint8_t * buf, + int *buf_size, int comp) +{ + z_stream s; + int res; + s.zalloc = NULL; + s.zfree = NULL; + s.opaque = NULL; + res = deflateInit(&s, comp); + if (res < 0) + return -1; + + s.next_in = prime->enc; + s.avail_in = prime->enc_size; + while (s.avail_in > 0) { + s.next_out = buf; + s.avail_out = *buf_size; + res = deflate(&s, Z_SYNC_FLUSH); + if (res < 0) + return -1; + } + + s.next_in = b->sl_begin; + s.avail_in = b->sl_end - b->sl_begin; + s.next_out = buf; + s.avail_out = *buf_size; + res = deflate(&s, Z_FINISH); + deflateEnd(&s); + *buf_size -= s.avail_out; + if (res != Z_STREAM_END) + return -1; + return 0; +} + +static int encode_bgr(Block * b, const uint8_t * src, int stride) +{ + int i; + uint8_t *ptr = b->enc; + for (i = 0; i < b->start; i++) + memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3); + b->sl_begin = ptr + i * b->width * 3; + for (; i < b->start + b->len; i++) + memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3); + b->sl_end = ptr + i * b->width * 3; + for (; i < b->height; i++) + memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3); + b->enc_size = ptr + i * b->width * 3 - b->enc; + return b->enc_size; +} + +static inline unsigned pixel_color15(const uint8_t * src) +{ + return (src[0] >> 3) | ((src[1] & 0xf8) << 2) | ((src[2] & 0xf8) << 7); +} + +static inline unsigned int chroma_diff(unsigned int c1, unsigned int c2) +{ + unsigned int t1 = (c1 & 0x000000ff) + ((c1 & 0x0000ff00) >> 8) + ((c1 & 0x00ff0000) >> 16); + unsigned int t2 = (c2 & 0x000000ff) + ((c2 & 0x0000ff00) >> 8) + ((c2 & 0x00ff0000) >> 16); + + return abs(t1 - t2) + abs((c1 & 0x000000ff) - (c2 & 0x000000ff)) + + abs(((c1 & 0x0000ff00) >> 8) - ((c2 & 0x0000ff00) >> 8)) + + abs(((c1 & 0x00ff0000) >> 16) - ((c2 & 0x00ff0000) >> 16)); +} + +static inline int pixel_color7_fast(Palette * palette, unsigned c15) +{ + return palette->index[c15]; +} + +static int pixel_color7_slow(Palette * palette, unsigned color) +{ + int i, min = 0x7fffffff; + int minc = -1; + for (i = 0; i < 128; i++) { + int c1 = palette->colors[i]; + int diff = chroma_diff(c1, color); + if (diff < min) { + min = diff; + minc = i; + } + } + return minc; +} + +static inline unsigned pixel_bgr(const uint8_t * src) +{ + return (src[0]) | (src[1] << 8) | (src[2] << 16); +} + +static int write_pixel_15_7(Palette * palette, uint8_t * dest, const uint8_t * src, + int dist) +{ + unsigned c15 = pixel_color15(src); + unsigned color = pixel_bgr(src); + int d15 = chroma_diff(color, color & 0x00f8f8f8); + int c7 = pixel_color7_fast(palette, c15); + int d7 = chroma_diff(color, palette->colors[c7]); + if (dist + d15 >= d7) { + dest[0] = c7; + return 1; + } else { + dest[0] = 0x80 | (c15 >> 8); + dest[1] = c15 & 0xff; + return 2; + } +} + +static int update_palette_index(Palette * palette) +{ + int r, g, b; + unsigned int bgr, c15, index; + for (r = 4; r < 256; r += 8) { + for (g = 4; g < 256; g += 8) { + for (b = 4; b < 256; b += 8) { + bgr = b | (g << 8) | (r << 16); + c15 = (b >> 3) | ((g & 0xf8) << 2) | ((r & 0xf8) << 7); + index = pixel_color7_slow(palette, bgr); + + palette->index[c15] = index; + } + } + } + return 0; +} + +static const unsigned int default_screen_video_v2_palette[128] = { + 0x00000000, 0x00333333, 0x00666666, 0x00999999, 0x00CCCCCC, 0x00FFFFFF, + 0x00330000, 0x00660000, 0x00990000, 0x00CC0000, 0x00FF0000, 0x00003300, + 0x00006600, 0x00009900, 0x0000CC00, 0x0000FF00, 0x00000033, 0x00000066, + 0x00000099, 0x000000CC, 0x000000FF, 0x00333300, 0x00666600, 0x00999900, + 0x00CCCC00, 0x00FFFF00, 0x00003333, 0x00006666, 0x00009999, 0x0000CCCC, + 0x0000FFFF, 0x00330033, 0x00660066, 0x00990099, 0x00CC00CC, 0x00FF00FF, + 0x00FFFF33, 0x00FFFF66, 0x00FFFF99, 0x00FFFFCC, 0x00FF33FF, 0x00FF66FF, + 0x00FF99FF, 0x00FFCCFF, 0x0033FFFF, 0x0066FFFF, 0x0099FFFF, 0x00CCFFFF, + 0x00CCCC33, 0x00CCCC66, 0x00CCCC99, 0x00CCCCFF, 0x00CC33CC, 0x00CC66CC, + 0x00CC99CC, 0x00CCFFCC, 0x0033CCCC, 0x0066CCCC, 0x0099CCCC, 0x00FFCCCC, + 0x00999933, 0x00999966, 0x009999CC, 0x009999FF, 0x00993399, 0x00996699, + 0x0099CC99, 0x0099FF99, 0x00339999, 0x00669999, 0x00CC9999, 0x00FF9999, + 0x00666633, 0x00666699, 0x006666CC, 0x006666FF, 0x00663366, 0x00669966, + 0x0066CC66, 0x0066FF66, 0x00336666, 0x00996666, 0x00CC6666, 0x00FF6666, + 0x00333366, 0x00333399, 0x003333CC, 0x003333FF, 0x00336633, 0x00339933, + 0x0033CC33, 0x0033FF33, 0x00663333, 0x00993333, 0x00CC3333, 0x00FF3333, + 0x00003366, 0x00336600, 0x00660033, 0x00006633, 0x00330066, 0x00663300, + 0x00336699, 0x00669933, 0x00993366, 0x00339966, 0x00663399, 0x00996633, + 0x006699CC, 0x0099CC66, 0x00CC6699, 0x0066CC99, 0x009966CC, 0x00CC9966, + 0x0099CCFF, 0x00CCFF99, 0x00FF99CC, 0x0099FFCC, 0x00CC99FF, 0x00FFCC99, + 0x00111111, 0x00222222, 0x00444444, 0x00555555, 0x00AAAAAA, 0x00BBBBBB, + 0x00DDDDDD, 0x00EEEEEE +}; + +static int generate_default_palette(Palette * palette) +{ + memcpy(palette->colors, default_screen_video_v2_palette, + sizeof(default_screen_video_v2_palette)); + + return update_palette_index(palette); +} + +static int generate_optimum_palette(Palette * palette, const uint8_t * image, + int width, int height, int stride) +{ + //this isn't implemented yet! Default palette only! + return -1; +} + +static inline int encode_15_7_sl(Palette * palette, uint8_t * dest, + const uint8_t * src, int width, int dist) +{ + int len = 0, x; + for (x = 0; x < width; x++) { + len += write_pixel_15_7(palette, dest + len, src + 3 * x, dist); + } + return len; +} + +static int encode_15_7(Palette * palette, Block * b, const uint8_t * src, + int stride, int dist) +{ + int i; + uint8_t *ptr = b->enc; + for (i = 0; i < b->start; i++) + ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist); + b->sl_begin = ptr; + for (; i < b->start + b->len; i++) + ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist); + b->sl_end = ptr; + for (; i < b->height; i++) + ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist); + b->enc_size = ptr - b->enc; + return b->enc_size; +} + +static int encode_block(Palette * palette, Block * b, Block * prev, + const uint8_t * src, int stride, int comp, int dist, + int keyframe) +{ + unsigned buf_size = b->width * b->height * 6; + uint8_t buf[buf_size]; + int res; + if (b->flags & COLORSPACE_15_7) { + encode_15_7(palette, b, src, stride, dist); + } else { + encode_bgr(b, src, stride); + } + + if (b->len > 0) { + b->data_size = buf_size; + res = encode_zlib(b, b->data, &b->data_size, comp); + if (res) + return res; + + if (!keyframe) { + res = encode_zlibprime(b, prev, buf, &buf_size, comp); + if (res) + return res; + + if (buf_size < b->data_size) { + b->data_size = buf_size; + memcpy(b->data, buf, buf_size); + b->flags |= ZLIB_PRIME_COMPRESS_PREVIOUS; + } + } + } else { + b->data_size = 0; + } + return 0; +} + +static int compare_sl(FlashSV2Context * s, Block * b, const uint8_t * src, + uint8_t * frame, uint8_t * key, int y, int keyframe) +{ + if (memcmp(src, frame, b->width * 3) != 0) { + b->dirty = 1; + memcpy(frame, src, b->width * 3); +#ifndef FLASHSV2_DUMB + s->diff_lines++; +#endif + } + if (memcmp(src, key, b->width * 3) != 0) { + if (b->len == 0) + b->start = y; + b->len = y + 1 - b->start; + } + return 0; +} + +static int mark_all_blocks(FlashSV2Context * s, const uint8_t * src, int stride, + int keyframe) +{ + int sl, rsl, col, pos, possl; + Block *b; + for (sl = s->image_height - 1; sl >= 0; sl--) { + for (col = 0; col < s->cols; col++) { + rsl = s->image_height - sl - 1; + b = s->frame_blocks + col + rsl / s->block_height * s->cols; + possl = stride * sl + col * s->block_width * 3; + pos = s->image_width * rsl * 3 + col * s->block_width * 3; + compare_sl(s, b, src + possl, s->current_frame + pos, + s->key_frame + pos, rsl % s->block_height, keyframe); + } + } +#ifndef FLASHSV2_DUMB + s->tot_lines += s->image_height * s->cols; +#endif + return 0; +} + +static int encode_all_blocks(FlashSV2Context * s, int keyframe) +{ + int row, col, res; + uint8_t *data; + Block *b, *prev; + for (row = 0; row < s->rows; row++) { + for (col = 0; col < s->cols; col++) { + b = s->frame_blocks + (row * s->cols + col); + prev = s->key_blocks + (row * s->cols + col); + if (keyframe) { + b->start = 0; + b->len = b->height; + b->flags = s->use15_7 ? COLORSPACE_15_7 : 0; + } else if (!b->dirty) { + b->start = 0; + b->len = 0; + b->data_size = 0; + b->flags = s->use15_7 ? COLORSPACE_15_7 : 0; + continue; + } else { + b->flags = s->use15_7 ? COLORSPACE_15_7 | HAS_DIFF_BLOCKS : HAS_DIFF_BLOCKS; + } + data = s->current_frame + s->image_width * 3 * s->block_height * row + s->block_width * col * 3; + res = encode_block(&s->palette, b, prev, data, s->image_width * 3, s->comp, s->dist, keyframe); +#ifndef FLASHSV2_DUMB + if (b->dirty) + s->diff_blocks++; + s->comp_size += b->data_size; + s->uncomp_size += b->enc_size; +#endif + if (res) + return res; + } + } +#ifndef FLASHSV2_DUMB + s->raw_size += s->image_width * s->image_height * 3; + s->tot_blocks += s->rows * s->cols; +#endif + return 0; +} + +static int write_all_blocks(FlashSV2Context * s, uint8_t * buf, + int buf_size) +{ + int row, col, buf_pos = 0, len; + Block *b; + for (row = 0; row < s->rows; row++) { + for (col = 0; col < s->cols; col++) { + b = s->frame_blocks + row * s->cols + col; + len = write_block(b, buf + buf_pos, buf_size - buf_pos); + b->start = b->len = b->dirty = 0; + if (len < 0) + return len; + buf_pos += len; + } + } + return buf_pos; +} + +static int write_bitstream(FlashSV2Context * s, const uint8_t * src, int stride, + uint8_t * buf, int buf_size, int keyframe) +{ + int buf_pos, res; + + res = mark_all_blocks(s, src, stride, keyframe); + if (res) + return res; + res = encode_all_blocks(s, keyframe); + if (res) + return res; + + res = write_header(s, buf, buf_size); + if (res < 0) { + return res; + } else { + buf_pos = res; + } + res = write_all_blocks(s, buf + buf_pos, buf_size - buf_pos); + if (res < 0) + return res; + buf_pos += res; +#ifndef FLASHSV2_DUMB + s->total_bits += ((double) buf_pos) * 8.0; +#endif + + return buf_pos; +} + +static void recommend_keyframe(FlashSV2Context * s, int *keyframe) +{ +#ifndef FLASHSV2_DUMB + double block_ratio, line_ratio, enc_ratio, comp_ratio, data_ratio; + if (s->avctx->gop_size > 0) { + block_ratio = s->diff_blocks / s->tot_blocks; + line_ratio = s->diff_lines / s->tot_lines; + enc_ratio = s->uncomp_size / s->raw_size; + comp_ratio = s->comp_size / s->uncomp_size; + data_ratio = s->comp_size / s->raw_size; + + if ((block_ratio >= 0.5 && line_ratio / block_ratio <= 0.5) || line_ratio >= 0.95) { + *keyframe = 1; + return; + } + } +#else + return; +#endif +} + +static const double block_size_fraction = 1.0 / 300; +static int optimum_block_width(FlashSV2Context * s) +{ +#ifndef FLASHSV2_DUMB + double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks; + double width = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_width; + int pwidth = ((int) width); + return FFCLIP(pwidth & ~15, 256, 16); +#else + return 64; +#endif +} + +static int optimum_block_height(FlashSV2Context * s) +{ +#ifndef FLASHSV2_DUMB + double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks; + double height = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_height; + int pheight = ((int) height); + return FFCLIP(pheight & ~15, 256, 16); +#else + return 64; +#endif +} + +static const double use15_7_threshold = 8192; + +static int optimum_use15_7(FlashSV2Context * s) +{ +#ifndef FLASHSV2_DUMB + double ideal = ((double)(s->avctx->bit_rate * s->avctx->time_base.den * s->avctx->ticks_per_frame)) / + ((double) s->avctx->time_base.num) * s->avctx->frame_number; + if (ideal + use15_7_threshold < s->total_bits) { + return 1; + } else { + return 0; + } +#else + return s->avctx->global_quality == 0; +#endif +} + +static const double color15_7_factor = 100; + +static int optimum_dist(FlashSV2Context * s) +{ +#ifndef FLASHSV2_DUMB + double ideal = + s->avctx->bit_rate * s->avctx->time_base.den * + s->avctx->ticks_per_frame; + int dist = pow((s->total_bits / ideal) * color15_7_factor, 3); + av_log(s->avctx, AV_LOG_DEBUG, "dist: %d\n", dist); + return dist; +#else + return 15; +#endif +} + + +static int reconfigure_at_keyframe(FlashSV2Context * s, const uint8_t * image, + int stride) +{ + int update_palette = 0; + int res; + s->block_width = optimum_block_width(s); + s->block_height = optimum_block_height(s); + + s->rows = (s->image_height + s->block_height - 1) / s->block_height; + s->cols = (s->image_width + s->block_width - 1) / s->block_width; + + if (s->rows * s->cols != s->blocks_size / sizeof(Block)) { + if (s->rows * s->cols > s->blocks_size / sizeof(Block)) { + s->frame_blocks = av_realloc(s->frame_blocks, s->rows * s->cols * sizeof(Block)); + s->key_blocks = av_realloc(s->key_blocks, s->cols * s->rows * sizeof(Block)); + if (!s->frame_blocks || !s->key_blocks) { + av_log(s->avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); + return -1; + } + s->blocks_size = s->rows * s->cols * sizeof(Block); + } + init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer); + init_blocks(s, s->key_blocks, s->keybuffer, 0); + + } + + s->use15_7 = optimum_use15_7(s); + if (s->use15_7) { + if ((s->use_custom_palette && s->palette_type != 1) || update_palette) { + res = generate_optimum_palette(&s->palette, image, s->image_width, s->image_height, stride); + if (res) + return res; + s->palette_type = 1; + av_log(s->avctx, AV_LOG_DEBUG, "Generated optimum palette\n"); + } else if (!s->use_custom_palette && s->palette_type != 0) { + res = generate_default_palette(&s->palette); + if (res) + return res; + s->palette_type = 0; + av_log(s->avctx, AV_LOG_DEBUG, "Generated default palette\n"); + } + } + + + reset_stats(s); + + return 0; +} + +static int flashsv2_encode_frame(AVCodecContext * avctx, uint8_t * buf, + int buf_size, void *data) +{ + FlashSV2Context *const s = avctx->priv_data; + AVFrame *pict = data; + AVFrame *const p = &s->frame; + int res; + int keyframe = 0; + + *p = *pict; + + /* First frame needs to be a keyframe */ + if (avctx->frame_number == 0) + keyframe = 1; + + /* Check the placement of keyframes */ + if (avctx->gop_size > 0) { + if (avctx->frame_number >= s->last_key_frame + avctx->gop_size) + keyframe = 1; + } + + if (buf_size < s->frame_size) { + //Conservative upper bound check for compressed data + av_log(avctx, AV_LOG_ERROR, "buf_size %d < %d\n", buf_size, s->frame_size); + return -1; + } + + if (!keyframe + && avctx->frame_number > s->last_key_frame + avctx->keyint_min) { + recommend_keyframe(s, &keyframe); + if (keyframe) + av_log(avctx, AV_LOG_DEBUG, "Recommending key frame at frame %d\n", avctx->frame_number); + } + + if (keyframe) { + res = reconfigure_at_keyframe(s, p->data[0], p->linesize[0]); + if (res) + return res; + } + + if (s->use15_7) + s->dist = optimum_dist(s); + + res = write_bitstream(s, p->data[0], p->linesize[0], buf, buf_size, keyframe); + + if (keyframe) { + new_key_frame(s); + p->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; + s->last_key_frame = avctx->frame_number; + av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number); + } else { + p->pict_type = AV_PICTURE_TYPE_P; + p->key_frame = 0; + } + + avctx->coded_frame = p; + + return res; +} + +static av_cold int flashsv2_encode_end(AVCodecContext * avctx) +{ + FlashSV2Context *s = avctx->priv_data; + + cleanup(s); + + return 0; +} + +AVCodec ff_flashsv2_encoder = { + .name = "flashsv2", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_FLASHSV2, + .priv_data_size = sizeof(FlashSV2Context), + .init = flashsv2_encode_init, + .encode = flashsv2_encode_frame, + .close = flashsv2_encode_end, + .pix_fmts = (enum PixelFormat[]) {PIX_FMT_BGR24, PIX_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video Version 2"), + .capabilities = CODEC_CAP_EXPERIMENTAL, +}; diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c index 669badc6ce..77290e866f 100644 --- a/libavcodec/flashsvenc.c +++ b/libavcodec/flashsvenc.c @@ -3,20 +3,20 @@ * Copyright (C) 2004 Alex Beregszaszi * Copyright (C) 2006 Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/flicvideo.c b/libavcodec/flicvideo.c index b7bbfb4f5d..01962e1122 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -2,20 +2,20 @@ * FLI/FLC Animation Video Decoder * Copyright (C) 2003, 2004 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -63,9 +63,9 @@ #define CHECK_PIXEL_PTR(n) \ if (pixel_ptr + n > pixel_limit) { \ - av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \ + av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \ pixel_ptr + n, pixel_limit); \ - return -1; \ + return AVERROR_INVALIDDATA; \ } \ typedef struct FlicDecodeContext { @@ -122,6 +122,7 @@ static av_cold int flic_decode_init(AVCodecContext *avctx) return -1; } + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; s->new_palette = 0; @@ -135,7 +136,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, FlicDecodeContext *s = avctx->priv_data; GetByteContext g2; - int stream_ptr_after_color_chunk; int pixel_ptr; int palette_ptr; unsigned char palette_idx1; @@ -167,7 +167,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, bytestream2_init(&g2, buf, buf_size); - s->frame.reference = 1; + s->frame.reference = 3; 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(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); @@ -176,7 +176,11 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, pixels = s->frame.data[0]; pixel_limit = s->avctx->height * s->frame.linesize[0]; + if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + FF_INPUT_BUFFER_PADDING_SIZE)) + return AVERROR_INVALIDDATA; frame_size = bytestream2_get_le32(&g2); + if (frame_size > buf_size) + frame_size = buf_size; bytestream2_skip(&g2, 2); /* skip the magic number */ num_chunks = bytestream2_get_le16(&g2); bytestream2_skip(&g2, 8); /* skip padding */ @@ -184,15 +188,21 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, frame_size -= 16; /* iterate through the chunks */ - while ((frame_size > 0) && (num_chunks > 0)) { + while ((frame_size >= 6) && (num_chunks > 0)) { + int stream_ptr_after_chunk; chunk_size = bytestream2_get_le32(&g2); + if (chunk_size > frame_size) { + av_log(avctx, AV_LOG_WARNING, + "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size); + chunk_size = frame_size; + } + stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size; + chunk_type = bytestream2_get_le16(&g2); switch (chunk_type) { case FLI_256_COLOR: case FLI_COLOR: - stream_ptr_after_color_chunk = bytestream2_tell(&g2) + chunk_size - 6; - /* check special case: If this file is from the Magic Carpet * game and uses 6-bit colors even though it reports 256-color * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during @@ -215,6 +225,9 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, if (color_changes == 0) color_changes = 256; + if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk) + break; + for (j = 0; j < color_changes; j++) { unsigned int entry; @@ -225,26 +238,22 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, r = bytestream2_get_byte(&g2) << color_shift; g = bytestream2_get_byte(&g2) << color_shift; b = bytestream2_get_byte(&g2) << color_shift; - entry = (r << 16) | (g << 8) | b; + entry = 0xFF << 24 | r << 16 | g << 8 | b; + if (color_shift == 2) + entry |= entry >> 6 & 0x30303; if (s->palette[palette_ptr] != entry) s->new_palette = 1; s->palette[palette_ptr++] = entry; } } - - /* color chunks sometimes have weird 16-bit alignment issues; - * therefore, take the hardline approach and skip - * to the value calculated w.r.t. the size specified by the color - * chunk header */ - if (stream_ptr_after_color_chunk - bytestream2_tell(&g2) > 0) - bytestream2_skip(&g2, stream_ptr_after_color_chunk - bytestream2_tell(&g2)); - break; case FLI_DELTA: y_ptr = 0; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { + if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk) + break; line_packets = bytestream2_get_le16(&g2); if ((line_packets & 0xC000) == 0xC000) { // line skip opcode @@ -263,6 +272,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; for (i = 0; i < line_packets; i++) { + if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk) + break; /* account for the skip bytes */ pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += pixel_skip; @@ -279,6 +290,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } } else { CHECK_PIXEL_PTR(byte_run * 2); + if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk) + break; for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); } @@ -301,16 +314,22 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, pixel_ptr = y_ptr; CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; + if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk) + break; line_packets = bytestream2_get_byte(&g2); if (line_packets > 0) { for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ + if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk) + break; pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += pixel_skip; pixel_countdown -= pixel_skip; byte_run = sign_extend(bytestream2_get_byte(&g2),8); if (byte_run > 0) { CHECK_PIXEL_PTR(byte_run); + if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk) + break; for (j = 0; j < byte_run; j++, pixel_countdown--) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); } @@ -347,6 +366,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, bytestream2_skip(&g2, 1); pixel_countdown = s->avctx->width; while (pixel_countdown > 0) { + if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk) + break; byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run > 0) { palette_idx1 = bytestream2_get_byte(&g2); @@ -361,6 +382,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } else { /* copy bytes if byte_run < 0 */ byte_run = -byte_run; CHECK_PIXEL_PTR(byte_run); + if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk) + break; for (j = 0; j < byte_run; j++) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); pixel_countdown--; @@ -377,9 +400,9 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, case FLI_COPY: /* copy the chunk (uncompressed frame) */ - if (chunk_size - 6 > s->avctx->width * s->avctx->height) { + if (chunk_size - 6 != s->avctx->width * s->avctx->height) { av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ - "bigger than image, skipping chunk\n", chunk_size - 6); + "has incorrect size, skipping chunk\n", chunk_size - 6); bytestream2_skip(&g2, chunk_size - 6); } else { for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; @@ -392,7 +415,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, case FLI_MINI: /* some sort of a thumbnail? disregard this chunk... */ - bytestream2_skip(&g2, chunk_size - 6); break; default: @@ -400,6 +422,9 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, break; } + if (stream_ptr_after_chunk - bytestream2_tell(&g2) > 0) + bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2)); + frame_size -= chunk_size; num_chunks--; } @@ -458,7 +483,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, bytestream2_init(&g2, buf, buf_size); - s->frame.reference = 1; + s->frame.reference = 3; 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(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); @@ -472,14 +497,25 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, bytestream2_skip(&g2, 2); /* skip the magic number */ num_chunks = bytestream2_get_le16(&g2); bytestream2_skip(&g2, 8); /* skip padding */ + if (frame_size > buf_size) + frame_size = buf_size; frame_size -= 16; /* iterate through the chunks */ while ((frame_size > 0) && (num_chunks > 0)) { + int stream_ptr_after_chunk; chunk_size = bytestream2_get_le32(&g2); + if (chunk_size > frame_size) { + av_log(avctx, AV_LOG_WARNING, + "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size); + chunk_size = frame_size; + } + stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size; + chunk_type = bytestream2_get_le16(&g2); + switch (chunk_type) { case FLI_256_COLOR: case FLI_COLOR: @@ -495,6 +531,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, y_ptr = 0; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { + if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk) + break; line_packets = bytestream2_get_le16(&g2); if (line_packets < 0) { line_packets = -line_packets; @@ -506,6 +544,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, pixel_countdown = s->avctx->width; for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ + if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk) + break; pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */ pixel_countdown -= pixel_skip; @@ -519,6 +559,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, pixel_ptr += 2; } } else { + if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk) + break; CHECK_PIXEL_PTR(2 * byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2); @@ -553,6 +595,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, pixel_countdown = (s->avctx->width * 2); while (pixel_countdown > 0) { + if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk) + break; byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run > 0) { palette_idx1 = bytestream2_get_byte(&g2); @@ -566,6 +610,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, } } else { /* copy bytes if byte_run < 0 */ byte_run = -byte_run; + if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk) + break; CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { palette_idx1 = bytestream2_get_byte(&g2); @@ -605,6 +651,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */ while (pixel_countdown > 0) { + if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk) + break; byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run > 0) { pixel = bytestream2_get_le16(&g2); @@ -619,6 +667,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, } } else { /* copy pixels if byte_run < 0 */ byte_run = -byte_run; + if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk) + break; CHECK_PIXEL_PTR(2 * byte_run); for (j = 0; j < byte_run; j++) { *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2); diff --git a/libavcodec/flv.h b/libavcodec/flv.h index 3d9a2d5232..16bc88b663 100644 --- a/libavcodec/flv.h +++ b/libavcodec/flv.h @@ -1,19 +1,19 @@ /* * FLV specific private header. - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/flvdec.c b/libavcodec/flvdec.c index 29d680849d..7337107469 100644 --- a/libavcodec/flvdec.c +++ b/libavcodec/flvdec.c @@ -1,19 +1,19 @@ /* * FLV decoding. - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/flvenc.c b/libavcodec/flvenc.c index c0d9a04f62..ee373d0975 100644 --- a/libavcodec/flvenc.c +++ b/libavcodec/flvenc.c @@ -1,19 +1,19 @@ /* * FLV Encoding specific code. - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/fmtconvert.c b/libavcodec/fmtconvert.c index 58fece70b2..c03117c2cd 100644 --- a/libavcodec/fmtconvert.c +++ b/libavcodec/fmtconvert.c @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -86,3 +86,34 @@ av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx) if (HAVE_ALTIVEC) ff_fmt_convert_init_altivec(c, avctx); if (HAVE_MMX) ff_fmt_convert_init_x86(c, avctx); } + +/* ffdshow custom code */ +void float_interleave(float *dst, const float **src, long len, int channels) +{ + int i,j,c; + if(channels==2){ + for(i=0; i<len; i++){ + dst[2*i] = src[0][i] / 32768.0f; + dst[2*i+1] = src[1][i] / 32768.0f; + } + }else{ + for(c=0; c<channels; c++) + for(i=0, j=c; i<len; i++, j+=channels) + dst[j] = src[c][i] / 32768.0f; + } +} + +void float_interleave_noscale(float *dst, const float **src, long len, int channels) +{ + int i,j,c; + if(channels==2){ + for(i=0; i<len; i++){ + dst[2*i] = src[0][i]; + dst[2*i+1] = src[1][i]; + } + }else{ + for(c=0; c<channels; c++) + for(i=0, j=c; i<len; i++, j+=channels) + dst[j] = src[c][i]; + } +} diff --git a/libavcodec/fmtconvert.h b/libavcodec/fmtconvert.h index 1b534019f1..c0584753cd 100644 --- a/libavcodec/fmtconvert.h +++ b/libavcodec/fmtconvert.h @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -93,4 +93,8 @@ void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx); void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx); void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx); +/* ffdshow custom code */ +void float_interleave(float *dst, const float **src, long len, int channels); +void float_interleave_noscale(float *dst, const float **src, long len, int channels); + #endif /* AVCODEC_FMTCONVERT_H */ diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 5f5e55e8ff..a7d5a73e41 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -3,20 +3,20 @@ * Copyright (c) 2005 Roine Gustafsson * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -36,6 +36,7 @@ #include "huffman.h" #include "bytestream.h" #include "dsputil.h" +#include "thread.h" #define FPS_TAG MKTAG('F', 'P', 'S', 'x') @@ -60,8 +61,8 @@ static av_cold int decode_init(AVCodecContext *avctx) { FrapsContext * const s = avctx->priv_data; + avcodec_get_frame_defaults(&s->frame); avctx->coded_frame = (AVFrame*)&s->frame; - avctx->pix_fmt= PIX_FMT_NONE; /* set in decode_frame */ s->avctx = avctx; s->tmpbuf = NULL; @@ -138,7 +139,9 @@ static int decode_frame(AVCodecContext *avctx, const uint32_t *buf32; uint32_t *luma1,*luma2,*cb,*cr; uint32_t offs[4]; - int i, j, is_chroma, planes; + int i, j, is_chroma; + const int planes = 3; + uint8_t *out; header = AV_RL32(buf); @@ -152,91 +155,94 @@ static int decode_frame(AVCodecContext *avctx, return -1; } - buf+=4; - if (header_size == 8) - buf+=4; + buf += header_size; - switch(version) { - case 0: - default: - /* Fraps v0 is a reordered YUV420 */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; + avctx->pix_fmt = version & 1 ? PIX_FMT_BGR24 : PIX_FMT_YUVJ420P; - if ( (buf_size != avctx->width*avctx->height*3/2+header_size) && - (buf_size != header_size) ) { + if (version < 2) { + unsigned needed_size = avctx->width*avctx->height*3; + if (version == 0) needed_size /= 2; + needed_size += header_size; + if (buf_size != needed_size && buf_size != header_size) { av_log(avctx, AV_LOG_ERROR, "Invalid frame length %d (should be %d)\n", - buf_size, avctx->width*avctx->height*3/2+header_size); + buf_size, needed_size); + return -1; + } + /* bit 31 means same as previous pic */ + if (header & (1U<<31)) { + *data_size = 0; + return buf_size; + } + } else { + /* skip frame */ + if (buf_size == 8) { + *data_size = 0; + return buf_size; + } + if (AV_RL32(buf) != FPS_TAG || buf_size < planes*1024 + 24) { + av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n"); return -1; } + for(i = 0; i < planes; i++) { + offs[i] = AV_RL32(buf + 4 + i * 4); + if(offs[i] >= buf_size - header_size || (i && offs[i] <= offs[i - 1] + 1024)) { + av_log(avctx, AV_LOG_ERROR, "Fraps: plane %i offset is out of bounds\n", i); + return -1; + } + } + offs[planes] = buf_size - header_size; + for(i = 0; i < planes; i++) { + av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size, offs[i + 1] - offs[i] - 1024); + if (!s->tmpbuf) + return AVERROR(ENOMEM); + } + } - if (( (avctx->width % 8) != 0) || ( (avctx->height % 2) != 0 )) { + if (f->data[0]) + ff_thread_release_buffer(avctx, f); + f->pict_type = AV_PICTURE_TYPE_I; + f->key_frame = 1; + f->reference = 0; + f->buffer_hints = FF_BUFFER_HINTS_VALID; + if (ff_thread_get_buffer(avctx, f)) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + switch(version) { + case 0: + default: + /* Fraps v0 is a reordered YUV420 */ + if ( (avctx->width % 8) != 0 || (avctx->height % 2) != 0 ) { av_log(avctx, AV_LOG_ERROR, "Invalid frame size %dx%d\n", avctx->width, avctx->height); return -1; } - f->reference = 1; - f->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, f)) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - /* bit 31 means same as previous pic */ - f->pict_type = (header & (1U<<31))? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; - f->key_frame = f->pict_type == AV_PICTURE_TYPE_I; - - if (f->pict_type == AV_PICTURE_TYPE_I) { - 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] ]; - cr=(uint32_t*)&f->data[1][ y*f->linesize[1] ]; - cb=(uint32_t*)&f->data[2][ y*f->linesize[2] ]; - for(x=0; x<avctx->width; x+=8){ - *(luma1++) = *(buf32++); - *(luma1++) = *(buf32++); - *(luma2++) = *(buf32++); - *(luma2++) = *(buf32++); - *(cr++) = *(buf32++); - *(cb++) = *(buf32++); - } + 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] ]; + cr=(uint32_t*)&f->data[1][ y*f->linesize[1] ]; + cb=(uint32_t*)&f->data[2][ y*f->linesize[2] ]; + for(x=0; x<avctx->width; x+=8){ + *luma1++ = *buf32++; + *luma1++ = *buf32++; + *luma2++ = *buf32++; + *luma2++ = *buf32++; + *cr++ = *buf32++; + *cb++ = *buf32++; } } break; case 1: /* Fraps v1 is an upside-down BGR24 */ - avctx->pix_fmt = PIX_FMT_BGR24; - - if ( (buf_size != avctx->width*avctx->height*3+header_size) && - (buf_size != header_size) ) { - av_log(avctx, AV_LOG_ERROR, - "Invalid frame length %d (should be %d)\n", - buf_size, avctx->width*avctx->height*3+header_size); - return -1; - } - - f->reference = 1; - f->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, f)) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - /* bit 31 means same as previous pic */ - f->pict_type = (header & (1U<<31))? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; - f->key_frame = f->pict_type == AV_PICTURE_TYPE_I; - - if (f->pict_type == AV_PICTURE_TYPE_I) { - for(y=0; y<avctx->height; y++) - memcpy(&f->data[0][ (avctx->height-y)*f->linesize[0] ], - &buf[y*avctx->width*3], - 3*avctx->width); - } + for(y=0; y<avctx->height; y++) + memcpy(&f->data[0][ (avctx->height-y)*f->linesize[0] ], + &buf[y*avctx->width*3], + 3*avctx->width); break; case 2: @@ -245,42 +251,8 @@ static int decode_frame(AVCodecContext *avctx, * Fraps v2 is Huffman-coded YUV420 planes * Fraps v4 is virtually the same */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; - planes = 3; - f->reference = 1; - f->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, f)) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - /* skip frame */ - if(buf_size == 8) { - f->pict_type = AV_PICTURE_TYPE_P; - f->key_frame = 0; - break; - } - f->pict_type = AV_PICTURE_TYPE_I; - f->key_frame = 1; - if ((AV_RL32(buf) != FPS_TAG)||(buf_size < (planes*1024 + 24))) { - av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n"); - return -1; - } - for(i = 0; i < planes; i++) { - offs[i] = AV_RL32(buf + 4 + i * 4); - if(offs[i] >= buf_size || (i && offs[i] <= offs[i - 1] + 1024)) { - av_log(avctx, AV_LOG_ERROR, "Fraps: plane %i offset is out of bounds\n", i); - return -1; - } - } - offs[planes] = buf_size; for(i = 0; i < planes; i++){ is_chroma = !!i; - av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size, - offs[i + 1] - offs[i] - 1024); - if (!s->tmpbuf) - return AVERROR(ENOMEM); if(fraps2_decode_plane(s, f->data[i], f->linesize[i], avctx->width >> is_chroma, avctx->height >> is_chroma, buf + offs[i], offs[i + 1] - offs[i], is_chroma, 1) < 0) { av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i); @@ -291,53 +263,23 @@ static int decode_frame(AVCodecContext *avctx, case 3: case 5: /* Virtually the same as version 4, but is for RGB24 */ - avctx->pix_fmt = PIX_FMT_BGR24; - planes = 3; - f->reference = 1; - f->buffer_hints = FF_BUFFER_HINTS_VALID | - FF_BUFFER_HINTS_PRESERVE | - FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, f)) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); - return -1; - } - /* skip frame */ - if(buf_size == 8) { - f->pict_type = AV_PICTURE_TYPE_P; - f->key_frame = 0; - break; - } - f->pict_type = AV_PICTURE_TYPE_I; - f->key_frame = 1; - if ((AV_RL32(buf) != FPS_TAG)||(buf_size < (planes*1024 + 24))) { - av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n"); - return -1; - } - for(i = 0; i < planes; i++) { - offs[i] = AV_RL32(buf + 4 + i * 4); - if(offs[i] >= buf_size || (i && offs[i] <= offs[i - 1] + 1024)) { - av_log(avctx, AV_LOG_ERROR, "Fraps: plane %i offset is out of bounds\n", i); - return -1; - } - } - offs[planes] = buf_size; for(i = 0; i < planes; i++){ - av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size, - offs[i + 1] - offs[i] - 1024); - if (!s->tmpbuf) - return AVERROR(ENOMEM); if(fraps2_decode_plane(s, f->data[0] + i + (f->linesize[0] * (avctx->height - 1)), -f->linesize[0], avctx->width, avctx->height, buf + offs[i], offs[i + 1] - offs[i], 0, 3) < 0) { av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i); return -1; } } + out = f->data[0]; // convert pseudo-YUV into real RGB for(j = 0; j < avctx->height; j++){ - for(i = 0; i < avctx->width; i++){ - f->data[0][0 + i*3 + j*f->linesize[0]] += f->data[0][1 + i*3 + j*f->linesize[0]]; - f->data[0][2 + i*3 + j*f->linesize[0]] += f->data[0][1 + i*3 + j*f->linesize[0]]; + uint8_t *line_end = out + 3*avctx->width; + while (out < line_end) { + out[0] += out[1]; + out[2] += out[1]; + out += 3; } + out += f->linesize[0] - 3*avctx->width; } break; } @@ -374,6 +316,6 @@ AVCodec ff_fraps_decoder = { .init = decode_init, .close = decode_end, .decode = decode_frame, - .capabilities = CODEC_CAP_DR1, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .long_name = NULL_IF_CONFIG_SMALL("Fraps"), }; diff --git a/libavcodec/frwu.c b/libavcodec/frwu.c index c21c19a2ee..b47cb717f2 100644 --- a/libavcodec/frwu.c +++ b/libavcodec/frwu.c @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/g722.c b/libavcodec/g722.c index a911bc7b37..2c04c40b56 100644 --- a/libavcodec/g722.c +++ b/libavcodec/g722.c @@ -7,20 +7,20 @@ * Copyright (c) 2009 Kenan Gillet * Copyright (c) 2010 Martin Storsjo * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/g723_1.c b/libavcodec/g723_1.c new file mode 100644 index 0000000000..711fa56aec --- /dev/null +++ b/libavcodec/g723_1.c @@ -0,0 +1,2230 @@ +/* + * G.723.1 compatible decoder + * Copyright (c) 2006 Benjamin Larsson + * Copyright (c) 2010 Mohamed Naufal Basheer + * + * 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 + * G.723.1 compatible decoder + */ + +#include "avcodec.h" +#define BITSTREAM_READER_LE +#include "get_bits.h" +#include "acelp_vectors.h" +#include "celp_filters.h" +#include "celp_math.h" +#include "lsp.h" +#include "libavutil/lzo.h" +#include "g723_1_data.h" + +typedef struct g723_1_context { + AVFrame frame; + G723_1_Subframe subframe[4]; + FrameType cur_frame_type; + FrameType past_frame_type; + Rate cur_rate; + uint8_t lsp_index[LSP_BANDS]; + int pitch_lag[2]; + int erased_frames; + + int16_t prev_lsp[LPC_ORDER]; + int16_t prev_excitation[PITCH_MAX]; + int16_t excitation[PITCH_MAX + FRAME_LEN]; + int16_t synth_mem[LPC_ORDER]; + int16_t fir_mem[LPC_ORDER]; + int iir_mem[LPC_ORDER]; + + int random_seed; + int interp_index; + int interp_gain; + int sid_gain; + int cur_gain; + int reflection_coef; + int pf_gain; ///< formant postfilter + ///< gain scaling unit memory + + int16_t prev_data[HALF_FRAME_LEN]; + int16_t prev_weight_sig[PITCH_MAX]; + + + int16_t hpf_fir_mem; ///< highpass filter fir + int hpf_iir_mem; ///< and iir memories + int16_t perf_fir_mem[LPC_ORDER]; ///< perceptual filter fir + int16_t perf_iir_mem[LPC_ORDER]; ///< and iir memories + + int16_t harmonic_mem[PITCH_MAX]; +} G723_1_Context; + +static av_cold int g723_1_decode_init(AVCodecContext *avctx) +{ + G723_1_Context *p = avctx->priv_data; + + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + p->pf_gain = 1 << 12; + memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(int16_t)); + + avcodec_get_frame_defaults(&p->frame); + avctx->coded_frame = &p->frame; + + return 0; +} + +/** + * Unpack the frame into parameters. + * + * @param p the context + * @param buf pointer to the input buffer + * @param buf_size size of the input buffer + */ +static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf, + int buf_size) +{ + GetBitContext gb; + int ad_cb_len; + int temp, info_bits, i; + + init_get_bits(&gb, buf, buf_size * 8); + + /* Extract frame type and rate info */ + info_bits = get_bits(&gb, 2); + + if (info_bits == 3) { + p->cur_frame_type = UntransmittedFrame; + return 0; + } + + /* Extract 24 bit lsp indices, 8 bit for each band */ + p->lsp_index[2] = get_bits(&gb, 8); + p->lsp_index[1] = get_bits(&gb, 8); + p->lsp_index[0] = get_bits(&gb, 8); + + if (info_bits == 2) { + p->cur_frame_type = SIDFrame; + p->subframe[0].amp_index = get_bits(&gb, 6); + return 0; + } + + /* Extract the info common to both rates */ + p->cur_rate = info_bits ? Rate5k3 : Rate6k3; + p->cur_frame_type = ActiveFrame; + + p->pitch_lag[0] = get_bits(&gb, 7); + if (p->pitch_lag[0] > 123) /* test if forbidden code */ + return -1; + p->pitch_lag[0] += PITCH_MIN; + p->subframe[1].ad_cb_lag = get_bits(&gb, 2); + + p->pitch_lag[1] = get_bits(&gb, 7); + if (p->pitch_lag[1] > 123) + return -1; + p->pitch_lag[1] += PITCH_MIN; + p->subframe[3].ad_cb_lag = get_bits(&gb, 2); + p->subframe[0].ad_cb_lag = 1; + p->subframe[2].ad_cb_lag = 1; + + for (i = 0; i < SUBFRAMES; i++) { + /* Extract combined gain */ + temp = get_bits(&gb, 12); + ad_cb_len = 170; + p->subframe[i].dirac_train = 0; + if (p->cur_rate == Rate6k3 && p->pitch_lag[i >> 1] < SUBFRAME_LEN - 2) { + p->subframe[i].dirac_train = temp >> 11; + temp &= 0x7ff; + ad_cb_len = 85; + } + p->subframe[i].ad_cb_gain = FASTDIV(temp, GAIN_LEVELS); + if (p->subframe[i].ad_cb_gain < ad_cb_len) { + p->subframe[i].amp_index = temp - p->subframe[i].ad_cb_gain * + GAIN_LEVELS; + } else { + return -1; + } + } + + p->subframe[0].grid_index = get_bits1(&gb); + p->subframe[1].grid_index = get_bits1(&gb); + p->subframe[2].grid_index = get_bits1(&gb); + p->subframe[3].grid_index = get_bits1(&gb); + + if (p->cur_rate == Rate6k3) { + skip_bits1(&gb); /* skip reserved bit */ + + /* Compute pulse_pos index using the 13-bit combined position index */ + temp = get_bits(&gb, 13); + p->subframe[0].pulse_pos = temp / 810; + + temp -= p->subframe[0].pulse_pos * 810; + p->subframe[1].pulse_pos = FASTDIV(temp, 90); + + temp -= p->subframe[1].pulse_pos * 90; + p->subframe[2].pulse_pos = FASTDIV(temp, 9); + p->subframe[3].pulse_pos = temp - p->subframe[2].pulse_pos * 9; + + p->subframe[0].pulse_pos = (p->subframe[0].pulse_pos << 16) + + get_bits(&gb, 16); + p->subframe[1].pulse_pos = (p->subframe[1].pulse_pos << 14) + + get_bits(&gb, 14); + p->subframe[2].pulse_pos = (p->subframe[2].pulse_pos << 16) + + get_bits(&gb, 16); + p->subframe[3].pulse_pos = (p->subframe[3].pulse_pos << 14) + + get_bits(&gb, 14); + + p->subframe[0].pulse_sign = get_bits(&gb, 6); + p->subframe[1].pulse_sign = get_bits(&gb, 5); + p->subframe[2].pulse_sign = get_bits(&gb, 6); + p->subframe[3].pulse_sign = get_bits(&gb, 5); + } else { /* Rate5k3 */ + p->subframe[0].pulse_pos = get_bits(&gb, 12); + p->subframe[1].pulse_pos = get_bits(&gb, 12); + p->subframe[2].pulse_pos = get_bits(&gb, 12); + p->subframe[3].pulse_pos = get_bits(&gb, 12); + + p->subframe[0].pulse_sign = get_bits(&gb, 4); + p->subframe[1].pulse_sign = get_bits(&gb, 4); + p->subframe[2].pulse_sign = get_bits(&gb, 4); + p->subframe[3].pulse_sign = get_bits(&gb, 4); + } + + return 0; +} + +/** + * Bitexact implementation of sqrt(val/2). + */ +static int16_t square_root(int val) +{ + return (ff_sqrt(val << 1) >> 1) & (~1); +} + +/** + * Calculate the number of left-shifts required for normalizing the input. + * + * @param num input number + * @param width width of the input, 16 bits(0) / 32 bits(1) + */ +static int normalize_bits(int num, int width) +{ + int i = 0; + int bits = (width) ? 31 : 15; + + if (num) { + if (num == -1) + return bits; + if (num < 0) + num = ~num; + i= bits - av_log2(num) - 1; + i= FFMAX(i, 0); + } + return i; +} + +#define normalize_bits_int16(num) normalize_bits(num, 0) +#define normalize_bits_int32(num) normalize_bits(num, 1) +#define dot_product(a,b,c,d) (ff_dot_product(a,b,c)<<(d)) + +/** + * Scale vector contents based on the largest of their absolutes. + */ +static int scale_vector(int16_t *vector, int length) +{ + int bits, scale, max = 0; + int i; + + const int16_t shift_table[16] = { + 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x7fff + }; + + for (i = 0; i < length; i++) + max = FFMAX(max, FFABS(vector[i])); + + bits = normalize_bits(max, 0); + scale = shift_table[bits]; + + for (i = 0; i < length; i++) + vector[i] = (vector[i] * scale) >> 3; + + return bits - 3; +} + +/** + * Perform inverse quantization of LSP frequencies. + * + * @param cur_lsp the current LSP vector + * @param prev_lsp the previous LSP vector + * @param lsp_index VQ indices + * @param bad_frame bad frame flag + */ +static void inverse_quant(int16_t *cur_lsp, int16_t *prev_lsp, + uint8_t *lsp_index, int bad_frame) +{ + int min_dist, pred; + int i, j, temp, stable; + + /* Check for frame erasure */ + if (!bad_frame) { + min_dist = 0x100; + pred = 12288; + } else { + min_dist = 0x200; + pred = 23552; + lsp_index[0] = lsp_index[1] = lsp_index[2] = 0; + } + + /* Get the VQ table entry corresponding to the transmitted index */ + cur_lsp[0] = lsp_band0[lsp_index[0]][0]; + cur_lsp[1] = lsp_band0[lsp_index[0]][1]; + cur_lsp[2] = lsp_band0[lsp_index[0]][2]; + cur_lsp[3] = lsp_band1[lsp_index[1]][0]; + cur_lsp[4] = lsp_band1[lsp_index[1]][1]; + cur_lsp[5] = lsp_band1[lsp_index[1]][2]; + cur_lsp[6] = lsp_band2[lsp_index[2]][0]; + cur_lsp[7] = lsp_band2[lsp_index[2]][1]; + cur_lsp[8] = lsp_band2[lsp_index[2]][2]; + cur_lsp[9] = lsp_band2[lsp_index[2]][3]; + + /* Add predicted vector & DC component to the previously quantized vector */ + for (i = 0; i < LPC_ORDER; i++) { + temp = ((prev_lsp[i] - dc_lsp[i]) * pred + (1 << 14)) >> 15; + cur_lsp[i] += dc_lsp[i] + temp; + } + + for (i = 0; i < LPC_ORDER; i++) { + cur_lsp[0] = FFMAX(cur_lsp[0], 0x180); + cur_lsp[LPC_ORDER - 1] = FFMIN(cur_lsp[LPC_ORDER - 1], 0x7e00); + + /* Stability check */ + for (j = 1; j < LPC_ORDER; j++) { + temp = min_dist + cur_lsp[j - 1] - cur_lsp[j]; + if (temp > 0) { + temp >>= 1; + cur_lsp[j - 1] -= temp; + cur_lsp[j] += temp; + } + } + stable = 1; + for (j = 1; j < LPC_ORDER; j++) { + temp = cur_lsp[j - 1] + min_dist - cur_lsp[j] - 4; + if (temp > 0) { + stable = 0; + break; + } + } + if (stable) + break; + } + if (!stable) + memcpy(cur_lsp, prev_lsp, LPC_ORDER * sizeof(int16_t)); +} + +/** + * Bitexact implementation of 2ab scaled by 1/2^16. + * + * @param a 32 bit multiplicand + * @param b 16 bit multiplier + */ +#define MULL2(a, b) \ + MULL(a,b,15) + +/** + * Convert LSP frequencies to LPC coefficients. + * + * @param lpc buffer for LPC coefficients + */ +static void lsp2lpc(int16_t *lpc) +{ + int f1[LPC_ORDER / 2 + 1]; + int f2[LPC_ORDER / 2 + 1]; + int i, j; + + /* Calculate negative cosine */ + for (j = 0; j < LPC_ORDER; j++) { + int index = lpc[j] >> 7; + int offset = lpc[j] & 0x7f; + int64_t temp1 = cos_tab[index] << 16; + int temp2 = (cos_tab[index + 1] - cos_tab[index]) * + ((offset << 8) + 0x80) << 1; + + lpc[j] = -(av_clipl_int32(((temp1 + temp2) << 1) + (1 << 15)) >> 16); + } + + /* + * Compute sum and difference polynomial coefficients + * (bitexact alternative to lsp2poly() in lsp.c) + */ + /* Initialize with values in Q28 */ + f1[0] = 1 << 28; + f1[1] = (lpc[0] << 14) + (lpc[2] << 14); + f1[2] = lpc[0] * lpc[2] + (2 << 28); + + f2[0] = 1 << 28; + f2[1] = (lpc[1] << 14) + (lpc[3] << 14); + f2[2] = lpc[1] * lpc[3] + (2 << 28); + + /* + * Calculate and scale the coefficients by 1/2 in + * each iteration for a final scaling factor of Q25 + */ + for (i = 2; i < LPC_ORDER / 2; i++) { + f1[i + 1] = f1[i - 1] + MULL2(f1[i], lpc[2 * i]); + f2[i + 1] = f2[i - 1] + MULL2(f2[i], lpc[2 * i + 1]); + + for (j = i; j >= 2; j--) { + f1[j] = MULL2(f1[j - 1], lpc[2 * i]) + + (f1[j] >> 1) + (f1[j - 2] >> 1); + f2[j] = MULL2(f2[j - 1], lpc[2 * i + 1]) + + (f2[j] >> 1) + (f2[j - 2] >> 1); + } + + f1[0] >>= 1; + f2[0] >>= 1; + f1[1] = ((lpc[2 * i] << 16 >> i) + f1[1]) >> 1; + f2[1] = ((lpc[2 * i + 1] << 16 >> i) + f2[1]) >> 1; + } + + /* Convert polynomial coefficients to LPC coefficients */ + for (i = 0; i < LPC_ORDER / 2; i++) { + int64_t ff1 = f1[i + 1] + f1[i]; + int64_t ff2 = f2[i + 1] - f2[i]; + + lpc[i] = av_clipl_int32(((ff1 + ff2) << 3) + (1 << 15)) >> 16; + lpc[LPC_ORDER - i - 1] = av_clipl_int32(((ff1 - ff2) << 3) + + (1 << 15)) >> 16; + } +} + +/** + * Quantize LSP frequencies by interpolation and convert them to + * the corresponding LPC coefficients. + * + * @param lpc buffer for LPC coefficients + * @param cur_lsp the current LSP vector + * @param prev_lsp the previous LSP vector + */ +static void lsp_interpolate(int16_t *lpc, int16_t *cur_lsp, int16_t *prev_lsp) +{ + int i; + int16_t *lpc_ptr = lpc; + + /* cur_lsp * 0.25 + prev_lsp * 0.75 */ + ff_acelp_weighted_vector_sum(lpc, cur_lsp, prev_lsp, + 4096, 12288, 1 << 13, 14, LPC_ORDER); + ff_acelp_weighted_vector_sum(lpc + LPC_ORDER, cur_lsp, prev_lsp, + 8192, 8192, 1 << 13, 14, LPC_ORDER); + ff_acelp_weighted_vector_sum(lpc + 2 * LPC_ORDER, cur_lsp, prev_lsp, + 12288, 4096, 1 << 13, 14, LPC_ORDER); + memcpy(lpc + 3 * LPC_ORDER, cur_lsp, LPC_ORDER * sizeof(int16_t)); + + for (i = 0; i < SUBFRAMES; i++) { + lsp2lpc(lpc_ptr); + lpc_ptr += LPC_ORDER; + } +} + +/** + * Generate a train of dirac functions with period as pitch lag. + */ +static void gen_dirac_train(int16_t *buf, int pitch_lag) +{ + int16_t vector[SUBFRAME_LEN]; + int i, j; + + memcpy(vector, buf, SUBFRAME_LEN * sizeof(int16_t)); + for (i = pitch_lag; i < SUBFRAME_LEN; i += pitch_lag) { + for (j = 0; j < SUBFRAME_LEN - i; j++) + buf[i + j] += vector[j]; + } +} + +/** + * Generate fixed codebook excitation vector. + * + * @param vector decoded excitation vector + * @param subfrm current subframe + * @param cur_rate current bitrate + * @param pitch_lag closed loop pitch lag + * @param index current subframe index + */ +static void gen_fcb_excitation(int16_t *vector, G723_1_Subframe subfrm, + Rate cur_rate, int pitch_lag, int index) +{ + int temp, i, j; + + memset(vector, 0, SUBFRAME_LEN * sizeof(int16_t)); + + if (cur_rate == Rate6k3) { + if (subfrm.pulse_pos >= max_pos[index]) + return; + + /* Decode amplitudes and positions */ + j = PULSE_MAX - pulses[index]; + temp = subfrm.pulse_pos; + for (i = 0; i < SUBFRAME_LEN / GRID_SIZE; i++) { + temp -= combinatorial_table[j][i]; + if (temp >= 0) + continue; + temp += combinatorial_table[j++][i]; + if (subfrm.pulse_sign & (1 << (PULSE_MAX - j))) { + vector[subfrm.grid_index + GRID_SIZE * i] = + -fixed_cb_gain[subfrm.amp_index]; + } else { + vector[subfrm.grid_index + GRID_SIZE * i] = + fixed_cb_gain[subfrm.amp_index]; + } + if (j == PULSE_MAX) + break; + } + if (subfrm.dirac_train == 1) + gen_dirac_train(vector, pitch_lag); + } else { /* Rate5k3 */ + int cb_gain = fixed_cb_gain[subfrm.amp_index]; + int cb_shift = subfrm.grid_index; + int cb_sign = subfrm.pulse_sign; + int cb_pos = subfrm.pulse_pos; + int offset, beta, lag; + + for (i = 0; i < 8; i += 2) { + offset = ((cb_pos & 7) << 3) + cb_shift + i; + vector[offset] = (cb_sign & 1) ? cb_gain : -cb_gain; + cb_pos >>= 3; + cb_sign >>= 1; + } + + /* Enhance harmonic components */ + lag = pitch_contrib[subfrm.ad_cb_gain << 1] + pitch_lag + + subfrm.ad_cb_lag - 1; + beta = pitch_contrib[(subfrm.ad_cb_gain << 1) + 1]; + + if (lag < SUBFRAME_LEN - 2) { + for (i = lag; i < SUBFRAME_LEN; i++) + vector[i] += beta * vector[i - lag] >> 15; + } + } +} + +/** + * Get delayed contribution from the previous excitation vector. + */ +static void get_residual(int16_t *residual, int16_t *prev_excitation, int lag) +{ + int offset = PITCH_MAX - PITCH_ORDER / 2 - lag; + int i; + + residual[0] = prev_excitation[offset]; + residual[1] = prev_excitation[offset + 1]; + + offset += 2; + for (i = 2; i < SUBFRAME_LEN + PITCH_ORDER - 1; i++) + residual[i] = prev_excitation[offset + (i - 2) % lag]; +} + +/** + * Generate adaptive codebook excitation. + */ +static void gen_acb_excitation(int16_t *vector, int16_t *prev_excitation, + int pitch_lag, G723_1_Subframe subfrm, + Rate cur_rate) +{ + int16_t residual[SUBFRAME_LEN + PITCH_ORDER - 1]; + const int16_t *cb_ptr; + int lag = pitch_lag + subfrm.ad_cb_lag - 1; + + int i; + int64_t sum; + + get_residual(residual, prev_excitation, lag); + + /* Select quantization table */ + if (cur_rate == Rate6k3 && pitch_lag < SUBFRAME_LEN - 2) { + cb_ptr = adaptive_cb_gain85; + } else + cb_ptr = adaptive_cb_gain170; + + /* Calculate adaptive vector */ + cb_ptr += subfrm.ad_cb_gain * 20; + for (i = 0; i < SUBFRAME_LEN; i++) { + sum = ff_dot_product(residual + i, cb_ptr, PITCH_ORDER); + vector[i] = av_clipl_int32((sum << 2) + (1 << 15)) >> 16; + } +} + +/** + * Estimate maximum auto-correlation around pitch lag. + * + * @param p the context + * @param offset offset of the excitation vector + * @param ccr_max pointer to the maximum auto-correlation + * @param pitch_lag decoded pitch lag + * @param length length of autocorrelation + * @param dir forward lag(1) / backward lag(-1) + */ +static int autocorr_max(G723_1_Context *p, int offset, int *ccr_max, + int pitch_lag, int length, int dir) +{ + int limit, ccr, lag = 0; + int16_t *buf = p->excitation + offset; + int i; + + pitch_lag = FFMIN(PITCH_MAX - 3, pitch_lag); + limit = FFMIN(FRAME_LEN + PITCH_MAX - offset - length, pitch_lag + 3); + + for (i = pitch_lag - 3; i <= limit; i++) { + ccr = ff_dot_product(buf, buf + dir * i, length)<<1; + + if (ccr > *ccr_max) { + *ccr_max = ccr; + lag = i; + } + } + return lag; +} + +/** + * Calculate pitch postfilter optimal and scaling gains. + * + * @param lag pitch postfilter forward/backward lag + * @param ppf pitch postfilter parameters + * @param cur_rate current bitrate + * @param tgt_eng target energy + * @param ccr cross-correlation + * @param res_eng residual energy + */ +static void comp_ppf_gains(int lag, PPFParam *ppf, Rate cur_rate, + int tgt_eng, int ccr, int res_eng) +{ + int pf_residual; /* square of postfiltered residual */ + int64_t temp1, temp2; + + ppf->index = lag; + + temp1 = tgt_eng * res_eng >> 1; + temp2 = ccr * ccr << 1; + + if (temp2 > temp1) { + if (ccr >= res_eng) { + ppf->opt_gain = ppf_gain_weight[cur_rate]; + } else { + ppf->opt_gain = (ccr << 15) / res_eng * + ppf_gain_weight[cur_rate] >> 15; + } + /* pf_res^2 = tgt_eng + 2*ccr*gain + res_eng*gain^2 */ + temp1 = (tgt_eng << 15) + (ccr * ppf->opt_gain << 1); + temp2 = (ppf->opt_gain * ppf->opt_gain >> 15) * res_eng; + pf_residual = av_clipl_int32(temp1 + temp2 + (1 << 15)) >> 16; + + if (tgt_eng >= pf_residual << 1) { + temp1 = 0x7fff; + } else { + temp1 = (tgt_eng << 14) / pf_residual; + } + + /* scaling_gain = sqrt(tgt_eng/pf_res^2) */ + ppf->sc_gain = square_root(temp1 << 16); + } else { + ppf->opt_gain = 0; + ppf->sc_gain = 0x7fff; + } + + ppf->opt_gain = av_clip_int16(ppf->opt_gain * ppf->sc_gain >> 15); +} + +/** + * Calculate pitch postfilter parameters. + * + * @param p the context + * @param offset offset of the excitation vector + * @param pitch_lag decoded pitch lag + * @param ppf pitch postfilter parameters + * @param cur_rate current bitrate + */ +static void comp_ppf_coeff(G723_1_Context *p, int offset, int pitch_lag, + PPFParam *ppf, Rate cur_rate) +{ + + int16_t scale; + int i; + int64_t temp1, temp2; + + /* + * 0 - target energy + * 1 - forward cross-correlation + * 2 - forward residual energy + * 3 - backward cross-correlation + * 4 - backward residual energy + */ + int energy[5] = {0, 0, 0, 0, 0}; + int16_t *buf = p->excitation + offset; + int fwd_lag = autocorr_max(p, offset, &energy[1], pitch_lag, + SUBFRAME_LEN, 1); + int back_lag = autocorr_max(p, offset, &energy[3], pitch_lag, + SUBFRAME_LEN, -1); + + ppf->index = 0; + ppf->opt_gain = 0; + ppf->sc_gain = 0x7fff; + + /* Case 0, Section 3.6 */ + if (!back_lag && !fwd_lag) + return; + + /* Compute target energy */ + energy[0] = ff_dot_product(buf, buf, SUBFRAME_LEN)<<1; + + /* Compute forward residual energy */ + if (fwd_lag) + energy[2] = ff_dot_product(buf + fwd_lag, buf + fwd_lag, + SUBFRAME_LEN)<<1; + + /* Compute backward residual energy */ + if (back_lag) + energy[4] = ff_dot_product(buf - back_lag, buf - back_lag, + SUBFRAME_LEN)<<1; + + /* Normalize and shorten */ + temp1 = 0; + for (i = 0; i < 5; i++) + temp1 = FFMAX(energy[i], temp1); + + scale = normalize_bits(temp1, 1); + for (i = 0; i < 5; i++) + energy[i] = av_clipl_int32(energy[i] << scale) >> 16; + + if (fwd_lag && !back_lag) { /* Case 1 */ + comp_ppf_gains(fwd_lag, ppf, cur_rate, energy[0], energy[1], + energy[2]); + } else if (!fwd_lag) { /* Case 2 */ + comp_ppf_gains(-back_lag, ppf, cur_rate, energy[0], energy[3], + energy[4]); + } else { /* Case 3 */ + + /* + * Select the largest of energy[1]^2/energy[2] + * and energy[3]^2/energy[4] + */ + temp1 = energy[4] * ((energy[1] * energy[1] + (1 << 14)) >> 15); + temp2 = energy[2] * ((energy[3] * energy[3] + (1 << 14)) >> 15); + if (temp1 >= temp2) { + comp_ppf_gains(fwd_lag, ppf, cur_rate, energy[0], energy[1], + energy[2]); + } else { + comp_ppf_gains(-back_lag, ppf, cur_rate, energy[0], energy[3], + energy[4]); + } + } +} + +/** + * Classify frames as voiced/unvoiced. + * + * @param p the context + * @param pitch_lag decoded pitch_lag + * @param exc_eng excitation energy estimation + * @param scale scaling factor of exc_eng + * + * @return residual interpolation index if voiced, 0 otherwise + */ +static int comp_interp_index(G723_1_Context *p, int pitch_lag, + int *exc_eng, int *scale) +{ + int offset = PITCH_MAX + 2 * SUBFRAME_LEN; + int16_t *buf = p->excitation + offset; + + int index, ccr, tgt_eng, best_eng, temp; + + *scale = scale_vector(p->excitation, FRAME_LEN + PITCH_MAX); + + /* Compute maximum backward cross-correlation */ + ccr = 0; + index = autocorr_max(p, offset, &ccr, pitch_lag, SUBFRAME_LEN * 2, -1); + ccr = av_clipl_int32((int64_t)ccr + (1 << 15)) >> 16; + + /* Compute target energy */ + tgt_eng = ff_dot_product(buf, buf, SUBFRAME_LEN * 2)<<1; + *exc_eng = av_clipl_int32(tgt_eng + (1 << 15)) >> 16; + + if (ccr <= 0) + return 0; + + /* Compute best energy */ + best_eng = ff_dot_product(buf - index, buf - index, + SUBFRAME_LEN * 2)<<1; + best_eng = av_clipl_int32((int64_t)best_eng + (1 << 15)) >> 16; + + temp = best_eng * *exc_eng >> 3; + + if (temp < ccr * ccr) { + return index; + } else + return 0; +} + +/** + * Peform residual interpolation based on frame classification. + * + * @param buf decoded excitation vector + * @param out output vector + * @param lag decoded pitch lag + * @param gain interpolated gain + * @param rseed seed for random number generator + */ +static void residual_interp(int16_t *buf, int16_t *out, int lag, + int gain, int *rseed) +{ + int i; + if (lag) { /* Voiced */ + int16_t *vector_ptr = buf + PITCH_MAX; + /* Attenuate */ + for (i = 0; i < lag; i++) + vector_ptr[i - lag] = vector_ptr[i - lag] * 3 >> 2; + av_memcpy_backptr((uint8_t*)vector_ptr, lag * sizeof(int16_t), + FRAME_LEN * sizeof(int16_t)); + memcpy(out, vector_ptr, FRAME_LEN * sizeof(int16_t)); + } else { /* Unvoiced */ + for (i = 0; i < FRAME_LEN; i++) { + *rseed = *rseed * 521 + 259; + out[i] = gain * *rseed >> 15; + } + memset(buf, 0, (FRAME_LEN + PITCH_MAX) * sizeof(int16_t)); + } +} + +/** + * Perform IIR filtering. + * + * @param fir_coef FIR coefficients + * @param iir_coef IIR coefficients + * @param src source vector + * @param dest destination vector + * @param width width of the output, 16 bits(0) / 32 bits(1) + */ +#define iir_filter(fir_coef, iir_coef, src, dest, width)\ +{\ + int m, n;\ + int res_shift = 16 & ~-(width);\ + int in_shift = 16 - res_shift;\ +\ + for (m = 0; m < SUBFRAME_LEN; m++) {\ + int64_t filter = 0;\ + for (n = 1; n <= LPC_ORDER; n++) {\ + filter -= (fir_coef)[n - 1] * (src)[m - n] -\ + (iir_coef)[n - 1] * ((dest)[m - n] >> in_shift);\ + }\ +\ + (dest)[m] = av_clipl_int32(((src)[m] << 16) + (filter << 3) +\ + (1 << 15)) >> res_shift;\ + }\ +} + +/** + * Adjust gain of postfiltered signal. + * + * @param p the context + * @param buf postfiltered output vector + * @param energy input energy coefficient + */ +static void gain_scale(G723_1_Context *p, int16_t * buf, int energy) +{ + int num, denom, gain, bits1, bits2; + int i; + + num = energy; + denom = 0; + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t temp = buf[i] >> 2; + temp = av_clipl_int32(MUL64(temp, temp) << 1); + denom = av_clipl_int32(denom + temp); + } + + if (num && denom) { + bits1 = normalize_bits(num, 1); + bits2 = normalize_bits(denom, 1); + num = num << bits1 >> 1; + denom <<= bits2; + + bits2 = 5 + bits1 - bits2; + bits2 = FFMAX(0, bits2); + + gain = (num >> 1) / (denom >> 16); + gain = square_root(gain << 16 >> bits2); + } else { + gain = 1 << 12; + } + + for (i = 0; i < SUBFRAME_LEN; i++) { + p->pf_gain = ((p->pf_gain << 4) - p->pf_gain + gain + (1 << 3)) >> 4; + buf[i] = av_clip_int16((buf[i] * (p->pf_gain + (p->pf_gain >> 4)) + + (1 << 10)) >> 11); + } +} + +/** + * Perform formant filtering. + * + * @param p the context + * @param lpc quantized lpc coefficients + * @param buf output buffer + */ +static void formant_postfilter(G723_1_Context *p, int16_t *lpc, int16_t *buf) +{ + int16_t filter_coef[2][LPC_ORDER], *buf_ptr; + int filter_signal[LPC_ORDER + FRAME_LEN], *signal_ptr; + int i, j, k; + + memcpy(buf, p->fir_mem, LPC_ORDER * sizeof(int16_t)); + memcpy(filter_signal, p->iir_mem, LPC_ORDER * sizeof(int)); + + for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) { + for (k = 0; k < LPC_ORDER; k++) { + filter_coef[0][k] = (-lpc[k] * postfilter_tbl[0][k] + + (1 << 14)) >> 15; + filter_coef[1][k] = (-lpc[k] * postfilter_tbl[1][k] + + (1 << 14)) >> 15; + } + iir_filter(filter_coef[0], filter_coef[1], buf + i, + filter_signal + i, 1); + } + + memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(int16_t)); + memcpy(p->iir_mem, filter_signal + FRAME_LEN, LPC_ORDER * sizeof(int)); + + buf_ptr = buf + LPC_ORDER; + signal_ptr = filter_signal + LPC_ORDER; + for (i = 0; i < SUBFRAMES; i++) { + int16_t temp_vector[SUBFRAME_LEN]; + int16_t temp; + int auto_corr[2]; + int scale, energy; + + /* Normalize */ + memcpy(temp_vector, buf_ptr, SUBFRAME_LEN * sizeof(int16_t)); + scale = scale_vector(temp_vector, SUBFRAME_LEN); + + /* Compute auto correlation coefficients */ + auto_corr[0] = ff_dot_product(temp_vector, temp_vector + 1, + SUBFRAME_LEN - 1)<<1; + auto_corr[1] = ff_dot_product(temp_vector, temp_vector, + SUBFRAME_LEN)<<1; + + /* Compute reflection coefficient */ + temp = auto_corr[1] >> 16; + if (temp) { + temp = (auto_corr[0] >> 2) / temp; + } + p->reflection_coef = ((p->reflection_coef << 2) - p->reflection_coef + + temp + 2) >> 2; + temp = (p->reflection_coef * 0xffffc >> 3) & 0xfffc; + + /* Compensation filter */ + for (j = 0; j < SUBFRAME_LEN; j++) { + buf_ptr[j] = av_clipl_int32(signal_ptr[j] + + ((signal_ptr[j - 1] >> 16) * + temp << 1)) >> 16; + } + + /* Compute normalized signal energy */ + temp = 2 * scale + 4; + if (temp < 0) { + energy = av_clipl_int32((int64_t)auto_corr[1] << -temp); + } else + energy = auto_corr[1] >> temp; + + gain_scale(p, buf_ptr, energy); + + buf_ptr += SUBFRAME_LEN; + signal_ptr += SUBFRAME_LEN; + } +} + +static int g723_1_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + G723_1_Context *p = avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int16_t *out; + int dec_mode = buf[0] & 3; + + PPFParam ppf[SUBFRAMES]; + int16_t cur_lsp[LPC_ORDER]; + int16_t lpc[SUBFRAMES * LPC_ORDER]; + int16_t acb_vector[SUBFRAME_LEN]; + int16_t *vector_ptr; + int bad_frame = 0, i, j, ret; + + if (!buf_size || buf_size < frame_size[dec_mode]) { + *got_frame_ptr = 0; + return buf_size; + } + + if (unpack_bitstream(p, buf, buf_size) < 0) { + bad_frame = 1; + p->cur_frame_type = p->past_frame_type == ActiveFrame ? + ActiveFrame : UntransmittedFrame; + } + + p->frame.nb_samples = FRAME_LEN + LPC_ORDER; + if ((ret = avctx->get_buffer(avctx, &p->frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + out= (int16_t*)p->frame.data[0]; + + + if(p->cur_frame_type == ActiveFrame) { + if (!bad_frame) { + p->erased_frames = 0; + } else if(p->erased_frames != 3) + p->erased_frames++; + + inverse_quant(cur_lsp, p->prev_lsp, p->lsp_index, bad_frame); + lsp_interpolate(lpc, cur_lsp, p->prev_lsp); + + /* Save the lsp_vector for the next frame */ + memcpy(p->prev_lsp, cur_lsp, LPC_ORDER * sizeof(int16_t)); + + /* Generate the excitation for the frame */ + memcpy(p->excitation, p->prev_excitation, PITCH_MAX * sizeof(int16_t)); + vector_ptr = p->excitation + PITCH_MAX; + if (!p->erased_frames) { + /* Update interpolation gain memory */ + p->interp_gain = fixed_cb_gain[(p->subframe[2].amp_index + + p->subframe[3].amp_index) >> 1]; + for (i = 0; i < SUBFRAMES; i++) { + gen_fcb_excitation(vector_ptr, p->subframe[i], p->cur_rate, + p->pitch_lag[i >> 1], i); + gen_acb_excitation(acb_vector, &p->excitation[SUBFRAME_LEN * i], + p->pitch_lag[i >> 1], p->subframe[i], + p->cur_rate); + /* Get the total excitation */ + for (j = 0; j < SUBFRAME_LEN; j++) { + vector_ptr[j] = av_clip_int16(vector_ptr[j] << 1); + vector_ptr[j] = av_clip_int16(vector_ptr[j] + + acb_vector[j]); + } + vector_ptr += SUBFRAME_LEN; + } + + vector_ptr = p->excitation + PITCH_MAX; + + /* Save the excitation */ + memcpy(out, vector_ptr, FRAME_LEN * sizeof(int16_t)); + + p->interp_index = comp_interp_index(p, p->pitch_lag[1], + &p->sid_gain, &p->cur_gain); + + for (i = PITCH_MAX, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + comp_ppf_coeff(p, i, p->pitch_lag[j >> 1], + ppf + j, p->cur_rate); + + /* Restore the original excitation */ + memcpy(p->excitation, p->prev_excitation, + PITCH_MAX * sizeof(int16_t)); + memcpy(vector_ptr, out, FRAME_LEN * sizeof(int16_t)); + + /* Peform pitch postfiltering */ + for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + ff_acelp_weighted_vector_sum(out + LPC_ORDER + i, vector_ptr + i, + vector_ptr + i + ppf[j].index, + ppf[j].sc_gain, ppf[j].opt_gain, + 1 << 14, 15, SUBFRAME_LEN); + } else { + p->interp_gain = (p->interp_gain * 3 + 2) >> 2; + if (p->erased_frames == 3) { + /* Mute output */ + memset(p->excitation, 0, + (FRAME_LEN + PITCH_MAX) * sizeof(int16_t)); + memset(out, 0, (FRAME_LEN + LPC_ORDER) * sizeof(int16_t)); + } else { + /* Regenerate frame */ + residual_interp(p->excitation, out + LPC_ORDER, p->interp_index, + p->interp_gain, &p->random_seed); + } + } + /* Save the excitation for the next frame */ + memcpy(p->prev_excitation, p->excitation + FRAME_LEN, + PITCH_MAX * sizeof(int16_t)); + } else { + memset(out, 0, sizeof(int16_t)*FRAME_LEN); + av_log(avctx, AV_LOG_WARNING, + "G.723.1: Comfort noise generation not supported yet\n"); + return frame_size[dec_mode]; + } + + p->past_frame_type = p->cur_frame_type; + + memcpy(out, p->synth_mem, LPC_ORDER * sizeof(int16_t)); + for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + ff_celp_lp_synthesis_filter(out + i, &lpc[j * LPC_ORDER], + out + i, SUBFRAME_LEN, LPC_ORDER, + 0, 1, 1 << 12); + memcpy(p->synth_mem, out + FRAME_LEN, LPC_ORDER * sizeof(int16_t)); + + formant_postfilter(p, lpc, out); + + memmove(out, out + LPC_ORDER, sizeof(int16_t)*FRAME_LEN); + p->frame.nb_samples = FRAME_LEN; + *(AVFrame*)data = p->frame; + *got_frame_ptr = 1; + + return frame_size[dec_mode]; +} + +AVCodec ff_g723_1_decoder = { + .name = "g723_1", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_G723_1, + .priv_data_size = sizeof(G723_1_Context), + .init = g723_1_decode_init, + .decode = g723_1_decode_frame, + .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), + .capabilities = CODEC_CAP_SUBFRAMES, +}; + +#if CONFIG_G723_1_ENCODER +#define BITSTREAM_WRITER_LE +#include "put_bits.h" + +static av_cold int g723_1_encode_init(AVCodecContext *avctx) +{ + G723_1_Context *p = avctx->priv_data; + + if (avctx->sample_rate != 8000) { + av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n"); + return -1; + } + + if (avctx->channels != 1) { + av_log(avctx, AV_LOG_ERROR, "Only mono supported\n"); + return AVERROR(EINVAL); + } + + if (avctx->bit_rate == 6300) { + p->cur_rate = Rate6k3; + } else if (avctx->bit_rate == 5300) { + av_log(avctx, AV_LOG_ERROR, "Bitrate not supported yet, use 6.3k\n"); + return AVERROR_PATCHWELCOME; + } else { + av_log(avctx, AV_LOG_ERROR, + "Bitrate not supported, use 6.3k\n"); + return AVERROR(EINVAL); + } + avctx->frame_size = 240; + memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(int16_t)); + + return 0; +} + +/** + * Remove DC component from the input signal. + * + * @param buf input signal + * @param fir zero memory + * @param iir pole memory + */ +static void highpass_filter(int16_t *buf, int16_t *fir, int *iir) +{ + int i; + for (i = 0; i < FRAME_LEN; i++) { + *iir = (buf[i] << 15) + ((-*fir) << 15) + MULL2(*iir, 0x7f00); + *fir = buf[i]; + buf[i] = av_clipl_int32((int64_t)*iir + (1 << 15)) >> 16; + } +} + +/** + * Estimate autocorrelation of the input vector. + * + * @param buf input buffer + * @param autocorr autocorrelation coefficients vector + */ +static void comp_autocorr(int16_t *buf, int16_t *autocorr) +{ + int i, scale, temp; + int16_t vector[LPC_FRAME]; + + memcpy(vector, buf, LPC_FRAME * sizeof(int16_t)); + scale_vector(vector, LPC_FRAME); + + /* Apply the Hamming window */ + for (i = 0; i < LPC_FRAME; i++) + vector[i] = (vector[i] * hamming_window[i] + (1 << 14)) >> 15; + + /* Compute the first autocorrelation coefficient */ + temp = dot_product(vector, vector, LPC_FRAME, 0); + + /* Apply a white noise correlation factor of (1025/1024) */ + temp += temp >> 10; + + /* Normalize */ + scale = normalize_bits_int32(temp); + autocorr[0] = av_clipl_int32((int64_t)(temp << scale) + + (1 << 15)) >> 16; + + /* Compute the remaining coefficients */ + if (!autocorr[0]) { + memset(autocorr + 1, 0, LPC_ORDER * sizeof(int16_t)); + } else { + for (i = 1; i <= LPC_ORDER; i++) { + temp = dot_product(vector, vector + i, LPC_FRAME - i, 0); + temp = MULL2((temp << scale), binomial_window[i - 1]); + autocorr[i] = av_clipl_int32((int64_t)temp + (1 << 15)) >> 16; + } + } +} + +/** + * Use Levinson-Durbin recursion to compute LPC coefficients from + * autocorrelation values. + * + * @param lpc LPC coefficients vector + * @param autocorr autocorrelation coefficients vector + * @param error prediction error + */ +static void levinson_durbin(int16_t *lpc, int16_t *autocorr, int16_t error) +{ + int16_t vector[LPC_ORDER]; + int16_t partial_corr; + int i, j, temp; + + memset(lpc, 0, LPC_ORDER * sizeof(int16_t)); + + for (i = 0; i < LPC_ORDER; i++) { + /* Compute the partial correlation coefficient */ + temp = 0; + for (j = 0; j < i; j++) + temp -= lpc[j] * autocorr[i - j - 1]; + temp = ((autocorr[i] << 13) + temp) << 3; + + if (FFABS(temp) >= (error << 16)) + break; + + partial_corr = temp / (error << 1); + + lpc[i] = av_clipl_int32((int64_t)(partial_corr << 14) + + (1 << 15)) >> 16; + + /* Update the prediction error */ + temp = MULL2(temp, partial_corr); + error = av_clipl_int32((int64_t)(error << 16) - temp + + (1 << 15)) >> 16; + + memcpy(vector, lpc, i * sizeof(int16_t)); + for (j = 0; j < i; j++) { + temp = partial_corr * vector[i - j - 1] << 1; + lpc[j] = av_clipl_int32((int64_t)(lpc[j] << 16) - temp + + (1 << 15)) >> 16; + } + } +} + +/** + * Calculate LPC coefficients for the current frame. + * + * @param buf current frame + * @param prev_data 2 trailing subframes of the previous frame + * @param lpc LPC coefficients vector + */ +static void comp_lpc_coeff(int16_t *buf, int16_t *lpc) +{ + int16_t autocorr[(LPC_ORDER + 1) * SUBFRAMES]; + int16_t *autocorr_ptr = autocorr; + int16_t *lpc_ptr = lpc; + int i, j; + + for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) { + comp_autocorr(buf + i, autocorr_ptr); + levinson_durbin(lpc_ptr, autocorr_ptr + 1, autocorr_ptr[0]); + + lpc_ptr += LPC_ORDER; + autocorr_ptr += LPC_ORDER + 1; + } +} + +static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp) +{ + int f[LPC_ORDER + 2]; ///< coefficients of the sum and difference + ///< polynomials (F1, F2) ordered as + ///< f1[0], f2[0], ...., f1[5], f2[5] + + int max, shift, cur_val, prev_val, count, p; + int i, j; + int64_t temp; + + /* Initialize f1[0] and f2[0] to 1 in Q25 */ + for (i = 0; i < LPC_ORDER; i++) + lsp[i] = (lpc[i] * bandwidth_expand[i] + (1 << 14)) >> 15; + + /* Apply bandwidth expansion on the LPC coefficients */ + f[0] = f[1] = 1 << 25; + + /* Compute the remaining coefficients */ + for (i = 0; i < LPC_ORDER / 2; i++) { + /* f1 */ + f[2 * i + 2] = -f[2 * i] - ((lsp[i] + lsp[LPC_ORDER - 1 - i]) << 12); + /* f2 */ + f[2 * i + 3] = f[2 * i + 1] - ((lsp[i] - lsp[LPC_ORDER - 1 - i]) << 12); + } + + /* Divide f1[5] and f2[5] by 2 for use in polynomial evaluation */ + f[LPC_ORDER] >>= 1; + f[LPC_ORDER + 1] >>= 1; + + /* Normalize and shorten */ + max = FFABS(f[0]); + for (i = 1; i < LPC_ORDER + 2; i++) + max = FFMAX(max, FFABS(f[i])); + + shift = normalize_bits_int32(max); + + for (i = 0; i < LPC_ORDER + 2; i++) + f[i] = av_clipl_int32((int64_t)(f[i] << shift) + (1 << 15)) >> 16; + + /** + * Evaluate F1 and F2 at uniform intervals of pi/256 along the + * unit circle and check for zero crossings. + */ + p = 0; + temp = 0; + for (i = 0; i <= LPC_ORDER / 2; i++) + temp += f[2 * i] * cos_tab[0]; + prev_val = av_clipl_int32(temp << 1); + count = 0; + for ( i = 1; i < COS_TBL_SIZE / 2; i++) { + /* Evaluate */ + temp = 0; + for (j = 0; j <= LPC_ORDER / 2; j++) + temp += f[LPC_ORDER - 2 * j + p] * cos_tab[i * j % COS_TBL_SIZE]; + cur_val = av_clipl_int32(temp << 1); + + /* Check for sign change, indicating a zero crossing */ + if ((cur_val ^ prev_val) < 0) { + int abs_cur = FFABS(cur_val); + int abs_prev = FFABS(prev_val); + int sum = abs_cur + abs_prev; + + shift = normalize_bits_int32(sum); + sum <<= shift; + abs_prev = abs_prev << shift >> 8; + lsp[count++] = ((i - 1) << 7) + (abs_prev >> 1) / (sum >> 16); + + if (count == LPC_ORDER) + break; + + /* Switch between sum and difference polynomials */ + p ^= 1; + + /* Evaluate */ + temp = 0; + for (j = 0; j <= LPC_ORDER / 2; j++){ + temp += f[LPC_ORDER - 2 * j + p] * + cos_tab[i * j % COS_TBL_SIZE]; + } + cur_val = av_clipl_int32(temp<<1); + } + prev_val = cur_val; + } + + if (count != LPC_ORDER) + memcpy(lsp, prev_lsp, LPC_ORDER * sizeof(int16_t)); +} + +/** + * Quantize the current LSP subvector. + * + * @param num band number + * @param offset offset of the current subvector in an LPC_ORDER vector + * @param size size of the current subvector + */ +#define get_index(num, offset, size) \ +{\ + int error, max = -1;\ + int16_t temp[4];\ + int i, j;\ + for (i = 0; i < LSP_CB_SIZE; i++) {\ + for (j = 0; j < size; j++){\ + temp[j] = (weight[j + (offset)] * lsp_band##num[i][j] +\ + (1 << 14)) >> 15;\ + }\ + error = dot_product(lsp + (offset), temp, size, 1) << 1;\ + error -= dot_product(lsp_band##num[i], temp, size, 1);\ + if (error > max) {\ + max = error;\ + lsp_index[num] = i;\ + }\ + }\ +} + +/** + * Vector quantize the LSP frequencies. + * + * @param lsp the current lsp vector + * @param prev_lsp the previous lsp vector + */ +static void lsp_quantize(uint8_t *lsp_index, int16_t *lsp, int16_t *prev_lsp) +{ + int16_t weight[LPC_ORDER]; + int16_t min, max; + int shift, i; + + /* Calculate the VQ weighting vector */ + weight[0] = (1 << 20) / (lsp[1] - lsp[0]); + weight[LPC_ORDER - 1] = (1 << 20) / + (lsp[LPC_ORDER - 1] - lsp[LPC_ORDER - 2]); + + for (i = 1; i < LPC_ORDER - 1; i++) { + min = FFMIN(lsp[i] - lsp[i - 1], lsp[i + 1] - lsp[i]); + if (min > 0x20) + weight[i] = (1 << 20) / min; + else + weight[i] = INT16_MAX; + } + + /* Normalize */ + max = 0; + for (i = 0; i < LPC_ORDER; i++) + max = FFMAX(weight[i], max); + + shift = normalize_bits_int16(max); + for (i = 0; i < LPC_ORDER; i++) { + weight[i] <<= shift; + } + + /* Compute the VQ target vector */ + for (i = 0; i < LPC_ORDER; i++) { + lsp[i] -= dc_lsp[i] + + (((prev_lsp[i] - dc_lsp[i]) * 12288 + (1 << 14)) >> 15); + } + + get_index(0, 0, 3); + get_index(1, 3, 3); + get_index(2, 6, 4); +} + +/** + * Apply the formant perceptual weighting filter. + * + * @param flt_coef filter coefficients + * @param unq_lpc unquantized lpc vector + */ +static void perceptual_filter(G723_1_Context *p, int16_t *flt_coef, + int16_t *unq_lpc, int16_t *buf) +{ + int16_t vector[FRAME_LEN + LPC_ORDER]; + int i, j, k, l = 0; + + memcpy(buf, p->iir_mem, sizeof(int16_t) * LPC_ORDER); + memcpy(vector, p->fir_mem, sizeof(int16_t) * LPC_ORDER); + memcpy(vector + LPC_ORDER, buf + LPC_ORDER, sizeof(int16_t) * FRAME_LEN); + + for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) { + for (k = 0; k < LPC_ORDER; k++) { + flt_coef[k + 2 * l] = (unq_lpc[k + l] * percept_flt_tbl[0][k] + + (1 << 14)) >> 15; + flt_coef[k + 2 * l + LPC_ORDER] = (unq_lpc[k + l] * + percept_flt_tbl[1][k] + + (1 << 14)) >> 15; + } + iir_filter(flt_coef + 2 * l, flt_coef + 2 * l + LPC_ORDER, vector + i, + buf + i, 0); + l += LPC_ORDER; + } + memcpy(p->iir_mem, buf + FRAME_LEN, sizeof(int16_t) * LPC_ORDER); + memcpy(p->fir_mem, vector + FRAME_LEN, sizeof(int16_t) * LPC_ORDER); +} + +/** + * Estimate the open loop pitch period. + * + * @param buf perceptually weighted speech + * @param start estimation is carried out from this position + */ +static int estimate_pitch(int16_t *buf, int start) +{ + int max_exp = 32; + int max_ccr = 0x4000; + int max_eng = 0x7fff; + int index = PITCH_MIN; + int offset = start - PITCH_MIN + 1; + + int ccr, eng, orig_eng, ccr_eng, exp; + int diff, temp; + + int i; + + orig_eng = dot_product(buf + offset, buf + offset, HALF_FRAME_LEN, 0); + + for (i = PITCH_MIN; i <= PITCH_MAX - 3; i++) { + offset--; + + /* Update energy and compute correlation */ + orig_eng += buf[offset] * buf[offset] - + buf[offset + HALF_FRAME_LEN] * buf[offset + HALF_FRAME_LEN]; + ccr = dot_product(buf + start, buf + offset, HALF_FRAME_LEN, 0); + if (ccr <= 0) + continue; + + /* Split into mantissa and exponent to maintain precision */ + exp = normalize_bits_int32(ccr); + ccr = av_clipl_int32((int64_t)(ccr << exp) + (1 << 15)) >> 16; + exp <<= 1; + ccr *= ccr; + temp = normalize_bits_int32(ccr); + ccr = ccr << temp >> 16; + exp += temp; + + temp = normalize_bits_int32(orig_eng); + eng = av_clipl_int32((int64_t)(orig_eng << temp) + (1 << 15)) >> 16; + exp -= temp; + + if (ccr >= eng) { + exp--; + ccr >>= 1; + } + if (exp > max_exp) + continue; + + if (exp + 1 < max_exp) + goto update; + + /* Equalize exponents before comparison */ + if (exp + 1 == max_exp) + temp = max_ccr >> 1; + else + temp = max_ccr; + ccr_eng = ccr * max_eng; + diff = ccr_eng - eng * temp; + if (diff > 0 && (i - index < PITCH_MIN || diff > ccr_eng >> 2)) { +update: + index = i; + max_exp = exp; + max_ccr = ccr; + max_eng = eng; + } + } + return index; +} + +/** + * Compute harmonic noise filter parameters. + * + * @param buf perceptually weighted speech + * @param pitch_lag open loop pitch period + * @param hf harmonic filter parameters + */ +static void comp_harmonic_coeff(int16_t *buf, int16_t pitch_lag, HFParam *hf) +{ + int ccr, eng, max_ccr, max_eng; + int exp, max, diff; + int energy[15]; + int i, j; + + for (i = 0, j = pitch_lag - 3; j <= pitch_lag + 3; i++, j++) { + /* Compute residual energy */ + energy[i << 1] = dot_product(buf - j, buf - j, SUBFRAME_LEN, 0); + /* Compute correlation */ + energy[(i << 1) + 1] = dot_product(buf, buf - j, SUBFRAME_LEN, 0); + } + + /* Compute target energy */ + energy[14] = dot_product(buf, buf, SUBFRAME_LEN, 0); + + /* Normalize */ + max = 0; + for (i = 0; i < 15; i++) + max = FFMAX(max, FFABS(energy[i])); + + exp = normalize_bits_int32(max); + for (i = 0; i < 15; i++) { + energy[i] = av_clipl_int32((int64_t)(energy[i] << exp) + + (1 << 15)) >> 16; + } + + hf->index = -1; + hf->gain = 0; + max_ccr = 1; + max_eng = 0x7fff; + + for (i = 0; i <= 6; i++) { + eng = energy[i << 1]; + ccr = energy[(i << 1) + 1]; + + if (ccr <= 0) + continue; + + ccr = (ccr * ccr + (1 << 14)) >> 15; + diff = ccr * max_eng - eng * max_ccr; + if (diff > 0) { + max_ccr = ccr; + max_eng = eng; + hf->index = i; + } + } + + if (hf->index == -1) { + hf->index = pitch_lag; + return; + } + + eng = energy[14] * max_eng; + eng = (eng >> 2) + (eng >> 3); + ccr = energy[(hf->index << 1) + 1] * energy[(hf->index << 1) + 1]; + if (eng < ccr) { + eng = energy[(hf->index << 1) + 1]; + + if (eng >= max_eng) + hf->gain = 0x2800; + else + hf->gain = ((eng << 15) / max_eng * 0x2800 + (1 << 14)) >> 15; + } + hf->index += pitch_lag - 3; +} + +/** + * Apply the harmonic noise shaping filter. + * + * @param hf filter parameters + */ +static void harmonic_filter(HFParam *hf, int16_t *src, int16_t *dest) +{ + int i; + + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t temp = hf->gain * src[i - hf->index] << 1; + dest[i] = av_clipl_int32((src[i] << 16) - temp + (1 << 15)) >> 16; + } +} + +static void harmonic_noise_sub(HFParam *hf, int16_t *src, int16_t *dest) +{ + int i; + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t temp = hf->gain * src[i - hf->index] << 1; + dest[i] = av_clipl_int32(((dest[i] - src[i]) << 16) + temp + + (1 << 15)) >> 16; + + } +} + +/** + * Combined synthesis and formant perceptual weighting filer. + * + * @param qnt_lpc quantized lpc coefficients + * @param perf_lpc perceptual filter coefficients + * @param perf_fir perceptual filter fir memory + * @param perf_iir perceptual filter iir memory + * @param scale the filter output will be scaled by 2^scale + */ +static void synth_percept_filter(int16_t *qnt_lpc, int16_t *perf_lpc, + int16_t *perf_fir, int16_t *perf_iir, + int16_t *src, int16_t *dest, int scale) +{ + int i, j; + int16_t buf_16[SUBFRAME_LEN + LPC_ORDER]; + int64_t buf[SUBFRAME_LEN]; + + int16_t *bptr_16 = buf_16 + LPC_ORDER; + + memcpy(buf_16, perf_fir, sizeof(int16_t) * LPC_ORDER); + memcpy(dest - LPC_ORDER, perf_iir, sizeof(int16_t) * LPC_ORDER); + + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t temp = 0; + for (j = 1; j <= LPC_ORDER; j++) + temp -= qnt_lpc[j - 1] * bptr_16[i - j]; + + buf[i] = (src[i] << 15) + (temp << 3); + bptr_16[i] = av_clipl_int32(buf[i] + (1 << 15)) >> 16; + } + + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t fir = 0, iir = 0; + for (j = 1; j <= LPC_ORDER; j++) { + fir -= perf_lpc[j - 1] * bptr_16[i - j]; + iir += perf_lpc[j + LPC_ORDER - 1] * dest[i - j]; + } + dest[i] = av_clipl_int32(((buf[i] + (fir << 3)) << scale) + (iir << 3) + + (1 << 15)) >> 16; + } + memcpy(perf_fir, buf_16 + SUBFRAME_LEN, sizeof(int16_t) * LPC_ORDER); + memcpy(perf_iir, dest + SUBFRAME_LEN - LPC_ORDER, + sizeof(int16_t) * LPC_ORDER); +} + +/** + * Compute the adaptive codebook contribution. + * + * @param buf input signal + * @param index the current subframe index + */ +static void acb_search(G723_1_Context *p, int16_t *residual, + int16_t *impulse_resp, int16_t *buf, + int index) +{ + + int16_t flt_buf[PITCH_ORDER][SUBFRAME_LEN]; + + const int16_t *cb_tbl = adaptive_cb_gain85; + + int ccr_buf[PITCH_ORDER * SUBFRAMES << 2]; + + int pitch_lag = p->pitch_lag[index >> 1]; + int acb_lag = 1; + int acb_gain = 0; + int odd_frame = index & 1; + int iter = 3 + odd_frame; + int count = 0; + int tbl_size = 85; + + int i, j, k, l, max; + int64_t temp; + + if (!odd_frame) { + if (pitch_lag == PITCH_MIN) + pitch_lag++; + else + pitch_lag = FFMIN(pitch_lag, PITCH_MAX - 5); + } + + for (i = 0; i < iter; i++) { + get_residual(residual, p->prev_excitation, pitch_lag + i - 1); + + for (j = 0; j < SUBFRAME_LEN; j++) { + temp = 0; + for (k = 0; k <= j; k++) + temp += residual[PITCH_ORDER - 1 + k] * impulse_resp[j - k]; + flt_buf[PITCH_ORDER - 1][j] = av_clipl_int32((temp << 1) + + (1 << 15)) >> 16; + } + + for (j = PITCH_ORDER - 2; j >= 0; j--) { + flt_buf[j][0] = ((residual[j] << 13) + (1 << 14)) >> 15; + for (k = 1; k < SUBFRAME_LEN; k++) { + temp = (flt_buf[j + 1][k - 1] << 15) + + residual[j] * impulse_resp[k]; + flt_buf[j][k] = av_clipl_int32((temp << 1) + (1 << 15)) >> 16; + } + } + + /* Compute crosscorrelation with the signal */ + for (j = 0; j < PITCH_ORDER; j++) { + temp = dot_product(buf, flt_buf[j], SUBFRAME_LEN, 0); + ccr_buf[count++] = av_clipl_int32(temp << 1); + } + + /* Compute energies */ + for (j = 0; j < PITCH_ORDER; j++) { + ccr_buf[count++] = dot_product(flt_buf[j], flt_buf[j], + SUBFRAME_LEN, 1); + } + + for (j = 1; j < PITCH_ORDER; j++) { + for (k = 0; k < j; k++) { + temp = dot_product(flt_buf[j], flt_buf[k], SUBFRAME_LEN, 0); + ccr_buf[count++] = av_clipl_int32(temp<<2); + } + } + } + + /* Normalize and shorten */ + max = 0; + for (i = 0; i < 20 * iter; i++) + max = FFMAX(max, FFABS(ccr_buf[i])); + + temp = normalize_bits_int32(max); + + for (i = 0; i < 20 * iter; i++){ + ccr_buf[i] = av_clipl_int32((int64_t)(ccr_buf[i] << temp) + + (1 << 15)) >> 16; + } + + max = 0; + for (i = 0; i < iter; i++) { + /* Select quantization table */ + if (!odd_frame && pitch_lag + i - 1 >= SUBFRAME_LEN - 2 || + odd_frame && pitch_lag >= SUBFRAME_LEN - 2) { + cb_tbl = adaptive_cb_gain170; + tbl_size = 170; + } + + for (j = 0, k = 0; j < tbl_size; j++, k += 20) { + temp = 0; + for (l = 0; l < 20; l++) + temp += ccr_buf[20 * i + l] * cb_tbl[k + l]; + temp = av_clipl_int32(temp); + + if (temp > max) { + max = temp; + acb_gain = j; + acb_lag = i; + } + } + } + + if (!odd_frame) { + pitch_lag += acb_lag - 1; + acb_lag = 1; + } + + p->pitch_lag[index >> 1] = pitch_lag; + p->subframe[index].ad_cb_lag = acb_lag; + p->subframe[index].ad_cb_gain = acb_gain; +} + +/** + * Subtract the adaptive codebook contribution from the input + * to obtain the residual. + * + * @param buf target vector + */ +static void sub_acb_contrib(int16_t *residual, int16_t *impulse_resp, + int16_t *buf) +{ + int i, j; + /* Subtract adaptive CB contribution to obtain the residual */ + for (i = 0; i < SUBFRAME_LEN; i++) { + int64_t temp = buf[i] << 14; + for (j = 0; j <= i; j++) + temp -= residual[j] * impulse_resp[i - j]; + + buf[i] = av_clipl_int32((temp << 2) + (1 << 15)) >> 16; + } +} + +/** + * Quantize the residual signal using the fixed codebook (MP-MLQ). + * + * @param optim optimized fixed codebook parameters + * @param buf excitation vector + */ +static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp, + int16_t *buf, int pulse_cnt, int pitch_lag) +{ + FCBParam param; + int16_t impulse_r[SUBFRAME_LEN]; + int16_t temp_corr[SUBFRAME_LEN]; + int16_t impulse_corr[SUBFRAME_LEN]; + + int ccr1[SUBFRAME_LEN]; + int ccr2[SUBFRAME_LEN]; + int amp, err, max, max_amp_index, min, scale, i, j, k, l; + + int64_t temp; + + /* Update impulse response */ + memcpy(impulse_r, impulse_resp, sizeof(int16_t) * SUBFRAME_LEN); + param.dirac_train = 0; + if (pitch_lag < SUBFRAME_LEN - 2) { + param.dirac_train = 1; + gen_dirac_train(impulse_r, pitch_lag); + } + + for (i = 0; i < SUBFRAME_LEN; i++) + temp_corr[i] = impulse_r[i] >> 1; + + /* Compute impulse response autocorrelation */ + temp = dot_product(temp_corr, temp_corr, SUBFRAME_LEN, 1); + + scale = normalize_bits_int32(temp); + impulse_corr[0] = av_clipl_int32((temp << scale) + (1 << 15)) >> 16; + + for (i = 1; i < SUBFRAME_LEN; i++) { + temp = dot_product(temp_corr + i, temp_corr, SUBFRAME_LEN - i, 1); + impulse_corr[i] = av_clipl_int32((temp << scale) + (1 << 15)) >> 16; + } + + /* Compute crosscorrelation of impulse response with residual signal */ + scale -= 4; + for (i = 0; i < SUBFRAME_LEN; i++){ + temp = dot_product(buf + i, impulse_r, SUBFRAME_LEN - i, 1); + if (scale < 0) + ccr1[i] = temp >> -scale; + else + ccr1[i] = av_clipl_int32(temp << scale); + } + + /* Search loop */ + for (i = 0; i < GRID_SIZE; i++) { + /* Maximize the crosscorrelation */ + max = 0; + for (j = i; j < SUBFRAME_LEN; j += GRID_SIZE) { + temp = FFABS(ccr1[j]); + if (temp >= max) { + max = temp; + param.pulse_pos[0] = j; + } + } + + /* Quantize the gain (max crosscorrelation/impulse_corr[0]) */ + amp = max; + min = 1 << 30; + max_amp_index = GAIN_LEVELS - 2; + for (j = max_amp_index; j >= 2; j--) { + temp = av_clipl_int32((int64_t)fixed_cb_gain[j] * + impulse_corr[0] << 1); + temp = FFABS(temp - amp); + if (temp < min) { + min = temp; + max_amp_index = j; + } + } + + max_amp_index--; + /* Select additional gain values */ + for (j = 1; j < 5; j++) { + for (k = i; k < SUBFRAME_LEN; k += GRID_SIZE) { + temp_corr[k] = 0; + ccr2[k] = ccr1[k]; + } + param.amp_index = max_amp_index + j - 2; + amp = fixed_cb_gain[param.amp_index]; + + param.pulse_sign[0] = (ccr2[param.pulse_pos[0]] < 0) ? -amp : amp; + temp_corr[param.pulse_pos[0]] = 1; + + for (k = 1; k < pulse_cnt; k++) { + max = -1 << 30; + for (l = i; l < SUBFRAME_LEN; l += GRID_SIZE) { + if (temp_corr[l]) + continue; + temp = impulse_corr[FFABS(l - param.pulse_pos[k - 1])]; + temp = av_clipl_int32((int64_t)temp * + param.pulse_sign[k - 1] << 1); + ccr2[l] -= temp; + temp = FFABS(ccr2[l]); + if (temp > max) { + max = temp; + param.pulse_pos[k] = l; + } + } + + param.pulse_sign[k] = (ccr2[param.pulse_pos[k]] < 0) ? + -amp : amp; + temp_corr[param.pulse_pos[k]] = 1; + } + + /* Create the error vector */ + memset(temp_corr, 0, sizeof(int16_t) * SUBFRAME_LEN); + + for (k = 0; k < pulse_cnt; k++) + temp_corr[param.pulse_pos[k]] = param.pulse_sign[k]; + + for (k = SUBFRAME_LEN - 1; k >= 0; k--) { + temp = 0; + for (l = 0; l <= k; l++) { + int prod = av_clipl_int32((int64_t)temp_corr[l] * + impulse_r[k - l] << 1); + temp = av_clipl_int32(temp + prod); + } + temp_corr[k] = temp << 2 >> 16; + } + + /* Compute square of error */ + err = 0; + for (k = 0; k < SUBFRAME_LEN; k++) { + int64_t prod; + prod = av_clipl_int32((int64_t)buf[k] * temp_corr[k] << 1); + err = av_clipl_int32(err - prod); + prod = av_clipl_int32((int64_t)temp_corr[k] * temp_corr[k]); + err = av_clipl_int32(err + prod); + } + + /* Minimize */ + if (err < optim->min_err) { + optim->min_err = err; + optim->grid_index = i; + optim->amp_index = param.amp_index; + optim->dirac_train = param.dirac_train; + + for (k = 0; k < pulse_cnt; k++) { + optim->pulse_sign[k] = param.pulse_sign[k]; + optim->pulse_pos[k] = param.pulse_pos[k]; + } + } + } + } +} + +/** + * Encode the pulse position and gain of the current subframe. + * + * @param optim optimized fixed CB parameters + * @param buf excitation vector + */ +static void pack_fcb_param(G723_1_Subframe *subfrm, FCBParam *optim, + int16_t *buf, int pulse_cnt) +{ + int i, j; + + j = PULSE_MAX - pulse_cnt; + + subfrm->pulse_sign = 0; + subfrm->pulse_pos = 0; + + for (i = 0; i < SUBFRAME_LEN >> 1; i++) { + int val = buf[optim->grid_index + (i << 1)]; + if (!val) { + subfrm->pulse_pos += combinatorial_table[j][i]; + } else { + subfrm->pulse_sign <<= 1; + if (val < 0) subfrm->pulse_sign++; + j++; + + if (j == PULSE_MAX) break; + } + } + subfrm->amp_index = optim->amp_index; + subfrm->grid_index = optim->grid_index; + subfrm->dirac_train = optim->dirac_train; +} + +/** + * Compute the fixed codebook excitation. + * + * @param buf target vector + * @param impulse_resp impulse response of the combined filter + */ +static void fcb_search(G723_1_Context *p, int16_t *impulse_resp, + int16_t *buf, int index) +{ + FCBParam optim; + int pulse_cnt = pulses[index]; + int i; + + optim.min_err = 1 << 30; + get_fcb_param(&optim, impulse_resp, buf, pulse_cnt, SUBFRAME_LEN); + + if (p->pitch_lag[index >> 1] < SUBFRAME_LEN - 2) { + get_fcb_param(&optim, impulse_resp, buf, pulse_cnt, + p->pitch_lag[index >> 1]); + } + + /* Reconstruct the excitation */ + memset(buf, 0, sizeof(int16_t) * SUBFRAME_LEN); + for (i = 0; i < pulse_cnt; i++) + buf[optim.pulse_pos[i]] = optim.pulse_sign[i]; + + pack_fcb_param(&p->subframe[index], &optim, buf, pulse_cnt); + + if (optim.dirac_train) + gen_dirac_train(buf, p->pitch_lag[index >> 1]); +} + +/** + * Pack the frame parameters into output bitstream. + * + * @param frame output buffer + * @param size size of the buffer + */ +static int pack_bitstream(G723_1_Context *p, unsigned char *frame, int size) +{ + PutBitContext pb; + int info_bits, i, temp; + + init_put_bits(&pb, frame, size); + + if (p->cur_rate == Rate6k3) { + info_bits = 0; + put_bits(&pb, 2, info_bits); + } + + put_bits(&pb, 8, p->lsp_index[2]); + put_bits(&pb, 8, p->lsp_index[1]); + put_bits(&pb, 8, p->lsp_index[0]); + + put_bits(&pb, 7, p->pitch_lag[0] - PITCH_MIN); + put_bits(&pb, 2, p->subframe[1].ad_cb_lag); + put_bits(&pb, 7, p->pitch_lag[1] - PITCH_MIN); + put_bits(&pb, 2, p->subframe[3].ad_cb_lag); + + /* Write 12 bit combined gain */ + for (i = 0; i < SUBFRAMES; i++) { + temp = p->subframe[i].ad_cb_gain * GAIN_LEVELS + + p->subframe[i].amp_index; + if (p->cur_rate == Rate6k3) + temp += p->subframe[i].dirac_train << 11; + put_bits(&pb, 12, temp); + } + + put_bits(&pb, 1, p->subframe[0].grid_index); + put_bits(&pb, 1, p->subframe[1].grid_index); + put_bits(&pb, 1, p->subframe[2].grid_index); + put_bits(&pb, 1, p->subframe[3].grid_index); + + if (p->cur_rate == Rate6k3) { + skip_put_bits(&pb, 1); /* reserved bit */ + + /* Write 13 bit combined position index */ + temp = (p->subframe[0].pulse_pos >> 16) * 810 + + (p->subframe[1].pulse_pos >> 14) * 90 + + (p->subframe[2].pulse_pos >> 16) * 9 + + (p->subframe[3].pulse_pos >> 14); + put_bits(&pb, 13, temp); + + put_bits(&pb, 16, p->subframe[0].pulse_pos & 0xffff); + put_bits(&pb, 14, p->subframe[1].pulse_pos & 0x3fff); + put_bits(&pb, 16, p->subframe[2].pulse_pos & 0xffff); + put_bits(&pb, 14, p->subframe[3].pulse_pos & 0x3fff); + + put_bits(&pb, 6, p->subframe[0].pulse_sign); + put_bits(&pb, 5, p->subframe[1].pulse_sign); + put_bits(&pb, 6, p->subframe[2].pulse_sign); + put_bits(&pb, 5, p->subframe[3].pulse_sign); + } + + flush_put_bits(&pb); + return frame_size[info_bits]; +} + +static int g723_1_encode_frame(AVCodecContext *avctx, unsigned char *buf, + int buf_size, void *data) +{ + G723_1_Context *p = avctx->priv_data; + int16_t unq_lpc[LPC_ORDER * SUBFRAMES]; + int16_t qnt_lpc[LPC_ORDER * SUBFRAMES]; + int16_t cur_lsp[LPC_ORDER]; + int16_t weighted_lpc[LPC_ORDER * SUBFRAMES << 1]; + int16_t vector[FRAME_LEN + PITCH_MAX]; + int offset; + int16_t *in = data; + + HFParam hf[4]; + int i, j; + + highpass_filter(in, &p->hpf_fir_mem, &p->hpf_iir_mem); + + memcpy(vector, p->prev_data, HALF_FRAME_LEN * sizeof(int16_t)); + memcpy(vector + HALF_FRAME_LEN, in, FRAME_LEN * sizeof(int16_t)); + + comp_lpc_coeff(vector, unq_lpc); + lpc2lsp(&unq_lpc[LPC_ORDER * 3], p->prev_lsp, cur_lsp); + lsp_quantize(p->lsp_index, cur_lsp, p->prev_lsp); + + /* Update memory */ + memcpy(vector + LPC_ORDER, p->prev_data + SUBFRAME_LEN, + sizeof(int16_t) * SUBFRAME_LEN); + memcpy(vector + LPC_ORDER + SUBFRAME_LEN, in, + sizeof(int16_t) * (HALF_FRAME_LEN + SUBFRAME_LEN)); + memcpy(p->prev_data, in + HALF_FRAME_LEN, + sizeof(int16_t) * HALF_FRAME_LEN); + memcpy(in, vector + LPC_ORDER, sizeof(int16_t) * FRAME_LEN); + + perceptual_filter(p, weighted_lpc, unq_lpc, vector); + + memcpy(in, vector + LPC_ORDER, sizeof(int16_t) * FRAME_LEN); + memcpy(vector, p->prev_weight_sig, sizeof(int16_t) * PITCH_MAX); + memcpy(vector + PITCH_MAX, in, sizeof(int16_t) * FRAME_LEN); + + scale_vector(vector, FRAME_LEN + PITCH_MAX); + + p->pitch_lag[0] = estimate_pitch(vector, PITCH_MAX); + p->pitch_lag[1] = estimate_pitch(vector, PITCH_MAX + HALF_FRAME_LEN); + + for (i = PITCH_MAX, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + comp_harmonic_coeff(vector + i, p->pitch_lag[j >> 1], hf + j); + + memcpy(vector, p->prev_weight_sig, sizeof(int16_t) * PITCH_MAX); + memcpy(vector + PITCH_MAX, in, sizeof(int16_t) * FRAME_LEN); + memcpy(p->prev_weight_sig, vector + FRAME_LEN, sizeof(int16_t) * PITCH_MAX); + + for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) + harmonic_filter(hf + j, vector + PITCH_MAX + i, in + i); + + inverse_quant(cur_lsp, p->prev_lsp, p->lsp_index, 0); + lsp_interpolate(qnt_lpc, cur_lsp, p->prev_lsp); + + memcpy(p->prev_lsp, cur_lsp, sizeof(int16_t) * LPC_ORDER); + + offset = 0; + for (i = 0; i < SUBFRAMES; i++) { + int16_t impulse_resp[SUBFRAME_LEN]; + int16_t residual[SUBFRAME_LEN + PITCH_ORDER - 1]; + int16_t flt_in[SUBFRAME_LEN]; + int16_t zero[LPC_ORDER], fir[LPC_ORDER], iir[LPC_ORDER]; + + /** + * Compute the combined impulse response of the synthesis filter, + * formant perceptual weighting filter and harmonic noise shaping filter + */ + memset(zero, 0, sizeof(int16_t) * LPC_ORDER); + memset(vector, 0, sizeof(int16_t) * PITCH_MAX); + memset(flt_in, 0, sizeof(int16_t) * SUBFRAME_LEN); + + flt_in[0] = 1 << 13; /* Unit impulse */ + synth_percept_filter(qnt_lpc + offset, weighted_lpc + (offset << 1), + zero, zero, flt_in, vector + PITCH_MAX, 1); + harmonic_filter(hf + i, vector + PITCH_MAX, impulse_resp); + + /* Compute the combined zero input response */ + flt_in[0] = 0; + memcpy(fir, p->perf_fir_mem, sizeof(int16_t) * LPC_ORDER); + memcpy(iir, p->perf_iir_mem, sizeof(int16_t) * LPC_ORDER); + + synth_percept_filter(qnt_lpc + offset, weighted_lpc + (offset << 1), + fir, iir, flt_in, vector + PITCH_MAX, 0); + memcpy(vector, p->harmonic_mem, sizeof(int16_t) * PITCH_MAX); + harmonic_noise_sub(hf + i, vector + PITCH_MAX, in); + + acb_search(p, residual, impulse_resp, in, i); + gen_acb_excitation(residual, p->prev_excitation,p->pitch_lag[i >> 1], + p->subframe[i], p->cur_rate); + sub_acb_contrib(residual, impulse_resp, in); + + fcb_search(p, impulse_resp, in, i); + + /* Reconstruct the excitation */ + gen_acb_excitation(impulse_resp, p->prev_excitation, p->pitch_lag[i >> 1], + p->subframe[i], Rate6k3); + + memmove(p->prev_excitation, p->prev_excitation + SUBFRAME_LEN, + sizeof(int16_t) * (PITCH_MAX - SUBFRAME_LEN)); + for (j = 0; j < SUBFRAME_LEN; j++) + in[j] = av_clip_int16((in[j] << 1) + impulse_resp[j]); + memcpy(p->prev_excitation + PITCH_MAX - SUBFRAME_LEN, in, + sizeof(int16_t) * SUBFRAME_LEN); + + /* Update filter memories */ + synth_percept_filter(qnt_lpc + offset, weighted_lpc + (offset << 1), + p->perf_fir_mem, p->perf_iir_mem, + in, vector + PITCH_MAX, 0); + memmove(p->harmonic_mem, p->harmonic_mem + SUBFRAME_LEN, + sizeof(int16_t) * (PITCH_MAX - SUBFRAME_LEN)); + memcpy(p->harmonic_mem + PITCH_MAX - SUBFRAME_LEN, vector + PITCH_MAX, + sizeof(int16_t) * SUBFRAME_LEN); + + in += SUBFRAME_LEN; + offset += LPC_ORDER; + } + + return pack_bitstream(p, buf, buf_size); +} + +AVCodec ff_g723_1_encoder = { + .name = "g723_1", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_G723_1, + .priv_data_size = sizeof(G723_1_Context), + .init = g723_1_encode_init, + .encode = g723_1_encode_frame, + .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), + .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE}, +}; +#endif diff --git a/libavcodec/g723_1_data.h b/libavcodec/g723_1_data.h new file mode 100644 index 0000000000..bd1abe9f0d --- /dev/null +++ b/libavcodec/g723_1_data.h @@ -0,0 +1,1315 @@ +/* + * G723.1 compatible decoder data tables. + * Copyright (c) 2006 Benjamin Larsson + * Copyright (c) 2010 Mohamed Naufal Basheer + * + * 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 + * G723.1 compatible decoder data tables + */ + +#define SUBFRAMES 4 +#define SUBFRAME_LEN 60 +#define FRAME_LEN (SUBFRAME_LEN << 2) +#define HALF_FRAME_LEN (FRAME_LEN / 2) +#define LPC_FRAME (HALF_FRAME_LEN + SUBFRAME_LEN) +#define LPC_ORDER 10 +#define LSP_BANDS 3 +#define LSP_CB_SIZE 256 +#define PITCH_MIN 18 +#define PITCH_MAX (PITCH_MIN + 127) +#define PITCH_ORDER 5 +#define GRID_SIZE 2 +#define PULSE_MAX 6 +#define GAIN_LEVELS 24 +#define COS_TBL_SIZE 512 + +/** + * G723.1 frame types + */ +typedef enum { + ActiveFrame, ///< Active speech + SIDFrame, ///< Silence Insertion Descriptor frame + UntransmittedFrame +} FrameType; + +static const uint8_t frame_size[4] = {24, 20, 4, 1}; + +typedef enum { + Rate6k3, + Rate5k3 +} Rate; + +/** + * G723.1 unpacked data subframe + */ +typedef struct { + int ad_cb_lag; ///< adaptive codebook lag + int ad_cb_gain; + int dirac_train; + int pulse_sign; + int grid_index; + int amp_index; + int pulse_pos; +} G723_1_Subframe; + +/** + * Pitch postfilter parameters + */ +typedef struct { + int index; ///< postfilter backward/forward lag + int16_t opt_gain; ///< optimal gain + int16_t sc_gain; ///< scaling gain +} PPFParam; + +/** + * Harmonic filter parameters + */ +typedef struct { + int index; + int gain; +} HFParam; + +/** + * Optimized fixed codebook excitation parameters + */ +typedef struct { + int min_err; + int amp_index; + int grid_index; + int dirac_train; + int pulse_pos[PULSE_MAX]; + int pulse_sign[PULSE_MAX]; +} FCBParam; + +/** + * Postfilter gain weighting factors scaled by 2^15 + */ +static const int16_t ppf_gain_weight[2] = {0x1800, 0x2000}; + +/** + * LSP DC component + */ +static const int16_t dc_lsp[LPC_ORDER] = { + 0x0c3b, + 0x1271, + 0x1e0a, + 0x2a36, + 0x3630, + 0x406f, + 0x4d28, + 0x56f4, + 0x638c, + 0x6c46 +}; + +/** + * Cosine table scaled by 2^14 + */ +static const int16_t cos_tab[COS_TBL_SIZE] = { + 16384, 16383, 16379, 16373, 16364, 16353, 16340, 16324, + 16305, 16284, 16261, 16235, 16207, 16176, 16143, 16107, + 16069, 16029, 15986, 15941, 15893, 15843, 15791, 15736, + 15679, 15619, 15557, 15493, 15426, 15357, 15286, 15213, + 15137, 15059, 14978, 14896, 14811, 14724, 14635, 14543, + 14449, 14354, 14256, 14155, 14053, 13949, 13842, 13733, + 13623, 13510, 13395, 13279, 13160, 13039, 12916, 12792, + 12665, 12537, 12406, 12274, 12140, 12004, 11866, 11727, + 11585, 11442, 11297, 11151, 11003, 10853, 10702, 10549, + 10394, 10238, 10080, 9921, 9760, 9598, 9434, 9269, + 9102, 8935, 8765, 8595, 8423, 8250, 8076, 7900, + 7723, 7545, 7366, 7186, 7005, 6823, 6639, 6455, + 6270, 6084, 5897, 5708, 5520, 5330, 5139, 4948, + 4756, 4563, 4370, 4176, 3981, 3786, 3590, 3393, + 3196, 2999, 2801, 2603, 2404, 2205, 2006, 1806, + 1606, 1406, 1205, 1005, 804, 603, 402, 201, + 0, -201, -402, -603, -804, -1005, -1205, -1406, + -1606, -1806, -2006, -2205, -2404, -2603, -2801, -2999, + -3196, -3393, -3590, -3786, -3981, -4176, -4370, -4563, + -4756, -4948, -5139, -5330, -5520, -5708, -5897, -6084, + -6270, -6455, -6639, -6823, -7005, -7186, -7366, -7545, + -7723, -7900, -8076, -8250, -8423, -8595, -8765, -8935, + -9102, -9269, -9434, -9598, -9760, -9921, -10080, -10238, + -10394, -10549, -10702, -10853, -11003, -11151, -11297, -11442, + -11585, -11727, -11866, -12004, -12140, -12274, -12406, -12537, + -12665, -12792, -12916, -13039, -13160, -13279, -13395, -13510, + -13623, -13733, -13842, -13949, -14053, -14155, -14256, -14354, + -14449, -14543, -14635, -14724, -14811, -14896, -14978, -15059, + -15137, -15213, -15286, -15357, -15426, -15493, -15557, -15619, + -15679, -15736, -15791, -15843, -15893, -15941, -15986, -16029, + -16069, -16107, -16143, -16176, -16207, -16235, -16261, -16284, + -16305, -16324, -16340, -16353, -16364, -16373, -16379, -16383, + -16384, -16383, -16379, -16373, -16364, -16353, -16340, -16324, + -16305, -16284, -16261, -16235, -16207, -16176, -16143, -16107, + -16069, -16029, -15986, -15941, -15893, -15843, -15791, -15736, + -15679, -15619, -15557, -15493, -15426, -15357, -15286, -15213, + -15137, -15059, -14978, -14896, -14811, -14724, -14635, -14543, + -14449, -14354, -14256, -14155, -14053, -13949, -13842, -13733, + -13623, -13510, -13395, -13279, -13160, -13039, -12916, -12792, + -12665, -12537, -12406, -12274, -12140, -12004, -11866, -11727, + -11585, -11442, -11297, -11151, -11003, -10853, -10702, -10549, + -10394, -10238, -10080, -9921, -9760, -9598, -9434, -9269, + -9102, -8935, -8765, -8595, -8423, -8250, -8076, -7900, + -7723, -7545, -7366, -7186, -7005, -6823, -6639, -6455, + -6270, -6084, -5897, -5708, -5520, -5330, -5139, -4948, + -4756, -4563, -4370, -4176, -3981, -3786, -3590, -3393, + -3196, -2999, -2801, -2603, -2404, -2205, -2006, -1806, + -1606, -1406, -1205, -1005, -804, -603, -402, -201, + 0, 201, 402, 603, 804, 1005, 1205, 1406, + 1606, 1806, 2006, 2205, 2404, 2603, 2801, 2999, + 3196, 3393, 3590, 3786, 3981, 4176, 4370, 4563, + 4756, 4948, 5139, 5330, 5520, 5708, 5897, 6084, + 6270, 6455, 6639, 6823, 7005, 7186, 7366, 7545, + 7723, 7900, 8076, 8250, 8423, 8595, 8765, 8935, + 9102, 9269, 9434, 9598, 9760, 9921, 10080, 10238, + 10394, 10549, 10702, 10853, 11003, 11151, 11297, 11442, + 11585, 11727, 11866, 12004, 12140, 12274, 12406, 12537, + 12665, 12792, 12916, 13039, 13160, 13279, 13395, 13510, + 13623, 13733, 13842, 13949, 14053, 14155, 14256, 14354, + 14449, 14543, 14635, 14724, 14811, 14896, 14978, 15059, + 15137, 15213, 15286, 15357, 15426, 15493, 15557, 15619, + 15679, 15736, 15791, 15843, 15893, 15941, 15986, 16029, + 16069, 16107, 16143, 16176, 16207, 16235, 16261, 16284, + 16305, 16324, 16340, 16353, 16364, 16373, 16379, 16383, +}; + +/** + * LSP VQ tables + */ +static const int16_t lsp_band0[LSP_CB_SIZE][3] = { + { 0, 0, 0}, { -270, -1372, -1032}, { -541, -1650, -1382}, + { -723, -2011, -2213}, { -941, -1122, -1942}, { -780, -1145, -2454}, + { -884, -1309, -1373}, {-1051, -1523, -1766}, {-1083, -1622, -2300}, + { -777, -1377, -2147}, { -935, -1467, -2763}, { -802, -1327, -3471}, + { -935, -1959, -3999}, { -240, -89, 222}, { -661, -257, -160}, + { -994, -466, -419}, { -188, -164, -278}, { -342, -512, -415}, + { -607, -511, -797}, { 16, 19, -716}, { 374, 425, -972}, + { -346, 245, -282}, { -265, 506, -754}, { -620, -147, 1955}, + { -742, -860, 2597}, { -150, -352, 2704}, { 305, 880, 1954}, + { 123, 731, 2766}, { -348, 765, 3327}, { 618, 221, 3258}, + { -178, -47, 4219}, { 393, 1304, 3842}, { 698, 1702, 4801}, + { 63, -584, 1229}, { -215, -732, 1704}, { 172, -335, 1909}, + { -2, 216, 1797}, { 353, 127, 2205}, {-1208, 188, 11}, + { -513, -75, -683}, { -973, 222, -646}, { -616, -843, -388}, + { -950, -1113, -359}, {-1431, -623, -705}, {-1398, -1063, -178}, + { -45, -461, 35}, { -9, -657, -216}, { 127, -1078, 95}, + { -950, -1156, 584}, {-1480, -1494, 449}, { -120, -705, 516}, + { -368, -961, 727}, { -378, -526, 973}, { -793, -614, 676}, + { -801, -755, 1287}, {-1476, -340, 1636}, { -505, -1254, 1543}, + {-1243, -1622, 1532}, { -776, -1477, -655}, {-1151, -1296, -823}, + {-1153, -1672, -1124}, {-1291, -2003, -1702}, { -622, -1283, 57}, + { -471, -1611, 509}, {-1060, -1570, -139}, { -873, -2156, -536}, + {-1716, -2021, -364}, {-2150, -3218, -1291}, {-1248, -1945, -2904}, + {-1215, -2633, -2855}, { 167, -244, 84}, { 349, -412, -217}, + { -40, -352, 632}, { 227, -529, 405}, { 68, -383, -443}, + { 167, -558, -706}, { -275, -854, -14}, { -351, -1089, -449}, + { 341, -72, -289}, { 603, -106, -474}, { 322, -219, -649}, + { 179, -317, -998}, { 450, -291, -996}, { 555, 195, -525}, + { 784, 272, -831}, { -148, -384, -849}, { 82, -536, -1357}, + { 238, -172, -1354}, { 422, -268, -1841}, { 297, -737, -2079}, + { -111, -801, -598}, { 1, -668, -984}, { -131, -818, -1299}, + { -329, -521, -1310}, { -151, -778, -1834}, { -93, -352, -1746}, + { -568, -640, -1821}, { -509, -941, -2183}, { 464, -815, -1250}, + { 79, -1133, -1597}, { -184, -1353, -2123}, { -196, -410, -2427}, + { -192, -833, -2810}, { -259, -1382, -3045}, { -217, 4, -1166}, + { -800, -325, -1219}, { -363, -830, -898}, { -661, -1134, -960}, + { -386, -980, -1501}, { -627, -1159, -1722}, { -903, -829, -855}, + { -685, -829, -1313}, {-1065, -959, -1405}, { 441, 25, -847}, + { 655, -27, -1181}, { 1159, -110, -705}, { 856, 253, -1671}, + { 415, 404, -1}, { 322, 903, -398}, { 670, 499, -292}, + { 803, 591, -610}, { 1144, 591, -814}, { 717, 183, 393}, + { 857, 381, 106}, { 609, 62, -27}, { 792, 198, -325}, + { 735, 805, 88}, { 1142, 812, 78}, { 1028, 366, -292}, + { 1309, 743, -237}, { 1615, 589, -79}, { 1010, 639, -243}, + { 999, 964, -311}, { 1500, 1137, -615}, { 988, 357, 646}, + { 1227, 667, 683}, { 1164, 1565, 894}, { 1392, 2015, 477}, + { 1138, 533, 250}, { 1437, 896, 391}, { 1765, 1118, 99}, + { 1112, 1090, 802}, { 1596, 846, 1134}, { 937, 1161, 279}, + { 1719, 1254, 683}, { 1338, 1086, 35}, { 1419, 1324, 428}, + { 1428, 1524, 40}, { 2108, 1594, 89}, { 1015, 544, 1222}, + { 1121, 925, 1263}, { 1030, 1318, 1485}, { 1295, 789, 1817}, + { 1323, 1272, 1909}, { 1724, 1237, 1803}, { 1797, 1689, 858}, + { 2149, 1367, 1301}, { 2302, 1867, 761}, { 2863, 2351, 1053}, + { 52, 163, -76}, { 230, 309, -492}, { -71, 619, 39}, + { -218, 856, 499}, { -654, 736, -207}, { -535, 1259, 155}, + { -480, 1476, 643}, { 262, 1081, 102}, { 309, 1592, -182}, + { 627, 1629, 534}, { 337, 643, 456}, { 758, 670, 713}, + { 202, 1126, 658}, { 612, 1131, 666}, { 686, 1223, 1136}, + { -131, 377, 525}, { 42, 708, 907}, { 87, 1488, 1035}, + { 432, 2117, 904}, { 137, 981, 1332}, { -447, 1014, 1136}, + { -839, 1793, 1246}, { -559, 297, 198}, { -850, 685, 446}, + {-1273, 632, 826}, { -401, -544, 173}, { -753, -793, 144}, + { -436, -9, 772}, { -115, -243, 1310}, { -670, -269, 374}, + {-1027, -13, 639}, { -887, -81, 1137}, {-1277, -455, 158}, + {-1411, -720, 736}, { 172, 88, 403}, { 386, 255, 756}, + { -500, 522, 910}, { -958, 659, 1388}, { -395, 301, 1344}, + { -356, 768, 1813}, { -613, 841, 2419}, { 445, -122, 252}, + { 629, -87, 723}, { 283, -253, 870}, { 456, -116, 1381}, + { 757, 180, 1059}, { 532, 408, 1509}, { 947, 288, 1806}, + { 1325, 994, 2524}, { 892, 1219, 3023}, { 1397, 1596, 3406}, + { 1143, 1552, 2546}, { 1850, 1433, 2710}, { -10, 134, 1002}, + { 154, 499, 1323}, { 508, 792, 1117}, { 509, 1340, 1616}, + { 762, 862, 1608}, { 787, 740, 2320}, { 794, 1727, 1283}, + { 465, 2108, 1660}, { -120, 1451, 1613}, { -386, 2016, 2169}, + { 891, 1225, 2050}, { 456, 1480, 2185}, { 1493, 1283, 1209}, + { 1397, 1636, 1518}, { 1776, 1738, 1552}, { 1572, 1698, 2141}, + { 1389, 2126, 1271}, { 1959, 2413, 1119}, { 1365, 2892, 1505}, + { 2206, 1971, 1623}, { 2076, 1950, 2280}, { 1717, 2291, 1867}, + { 2366, 2515, 1953}, { 2865, 2838, 2522}, { 2535, 3465, 2011}, + { 3381, 4127, 2638}, { 836, 2667, 2289}, { 1761, 2773, 2337}, + { 1415, 3325, 2911}, { 2354, 3138, 3126}, { 2659, 4192, 4010}, + { 1048, 1786, 1818}, { 1242, 2111, 2240}, { 1512, 2079, 2780}, + { 1573, 2491, 3138}, { 2230, 2377, 2782}, { 416, 1773, 2704}, + { 725, 2336, 3297}, { 1252, 2373, 3978}, { 2094, 2268, 3568}, + { 2011, 2712, 4528}, { 1341, 3507, 3876}, { 1216, 3919, 4922}, + { 1693, 4793, 6012} +}; + +static const int16_t lsp_band1[LSP_CB_SIZE][3] = { + { 0, 0, 0}, {-2114, -1302, 76}, {-2652, -1278, -1368}, + {-2847, -828, -349}, {-3812, -2190, -349}, {-3946, -364, -449}, + {-2725, -4492, -3607}, {-3495, -4764, -1744}, { -51, -756, 84}, + { -153, -1191, 504}, { 108, -1418, 1167}, { -835, -896, 390}, + { -569, -1702, 87}, {-1151, -1818, 933}, {-1826, -2547, 411}, + {-1842, -1818, 1451}, {-2438, -1611, 781}, {-2747, -2477, 1311}, + { -940, 1252, 477}, {-1629, 1688, 602}, {-1202, 617, 280}, + {-1737, 393, 580}, {-1528, 1077, 1199}, {-2165, -161, 1408}, + {-2504, -1087, 2371}, {-3458, -175, 1395}, {-1397, -98, -843}, + {-2252, -177, -1149}, {-1489, -726, -1283}, {-1558, -265, -1744}, + {-1867, -821, -1897}, {-2062, -1516, -2340}, {-2595, -1142, -2861}, + { 170, 46, -819}, { -193, -204, -1151}, { 326, -196, -1532}, + { 780, 329, -816}, { 201, 369, -1243}, { 650, -209, -1060}, + { 1144, -15, -1216}, { 1203, -259, -1867}, { -890, -564, -1430}, + { -638, -852, -1921}, { 177, -739, -1358}, { -261, -526, -1666}, + { 206, -407, -2255}, { 338, -526, -822}, { 421, -1095, -1009}, + { 765, -607, -1408}, { 825, -1295, -2004}, { 357, -905, -1815}, + { -58, -1248, -1588}, { -596, -1436, -2046}, { -73, -1159, -2116}, + { -115, -1382, -2581}, { -160, -1723, -1952}, { -6, -2196, -2954}, + { -649, -1705, -2603}, { -617, -1453, -3282}, { -949, -2019, -3102}, + { -812, 1544, 1937}, {-1854, 574, 2000}, {-1463, 1140, 2649}, + {-2683, 1748, 1452}, {-2486, 2241, 2523}, { 783, 1910, 1435}, + { 581, 2682, 1376}, { 236, 2197, 1885}, { -453, 2943, 2057}, + { -682, 2178, 2565}, {-1342, 3201, 3328}, { -288, -184, 262}, + { 121, -149, -183}, { 758, -412, 206}, { 1038, -204, 853}, + { 1577, -457, 700}, { 937, -640, -567}, { 1508, -528, -1024}, + { -225, -527, -427}, { -564, -1095, -332}, { -742, -353, -186}, + {-1288, -459, 84}, {-1853, -484, -274}, {-1554, -731, 825}, + {-2425, -234, 382}, {-1722, 293, -271}, {-2515, 425, -564}, + {-2599, 818, 464}, { -358, 118, -375}, { -613, 198, -874}, + { -690, 683, -324}, {-1352, 1155, -168}, {-1093, 129, -324}, + {-1184, 611, -858}, { 433, 386, -372}, { -120, 486, -634}, + { 234, 851, -631}, { 602, 128, 46}, { 1099, 410, 159}, + { 715, -145, -424}, { 1198, -85, -593}, { 1390, 367, -358}, + { 1683, 362, -964}, { 1711, 622, 45}, { 2033, 833, -383}, + { 2890, 549, -506}, { 7, 401, 52}, { 72, 811, 415}, + { 566, 668, 41}, { 467, 1218, 130}, { 68, 957, -187}, + { -25, 1649, -103}, { -661, 260, 214}, { -925, -94, 612}, + { -321, -422, 965}, { -788, -672, 1783}, { 400, -673, 779}, + { 741, -595, 1635}, { -161, 307, 657}, { -382, 836, 871}, + { -814, 400, 1223}, { 364, 606, 1247}, { 57, 75, 1571}, + { 151, 471, 2287}, { -81, 1021, 1502}, { 227, 1470, 1097}, + { 658, 1275, 1653}, { 664, 1478, 2377}, { 263, -127, 444}, + { 264, 89, 969}, { 794, 171, 576}, { 821, 186, 1226}, + { 404, 462, 517}, { 339, 918, 794}, { 1280, 1423, 196}, + { 1453, 2019, 365}, { 1615, 1481, 672}, { 2394, 1708, 508}, + { 806, 1238, 573}, { 713, 1158, 1078}, { 1285, 1436, 1232}, + { 1790, 1188, 1141}, { 765, 643, 864}, { 1032, 797, 1279}, + { 900, 563, 1827}, { 1514, 673, 2312}, { 1544, 1129, 3240}, + { 1469, 1050, 1594}, { 1945, 1318, 1988}, { 2397, 2026, 2060}, + { 3538, 2057, 2620}, { 1249, -118, 74}, { 1727, 194, 421}, + { 2078, -50, -463}, { 970, 688, -432}, { 1149, 952, -110}, + { 1254, 1275, -651}, { 1386, 929, 401}, { 1960, 1167, 232}, + { 407, -752, -243}, { 859, -1118, 172}, { -227, -860, -992}, + { -796, -1175, -1380}, { 8, -1282, -388}, { 353, -1781, -1037}, + { -732, -397, -807}, { -853, -28, -1342}, {-1229, -1207, -1959}, + {-1015, -1125, -2543}, {-1452, -1791, -2725}, {-1891, -2416, -3269}, + { -918, -1629, -783}, { -580, -2155, -698}, {-1097, -2364, -96}, + {-1387, -1513, 7}, {-1588, -2076, -664}, {-1473, -2740, -784}, + {-2378, -3149, -56}, {-2856, -2092, -169}, {-3391, -3708, 316}, + {-1176, -890, -614}, {-1944, -1061, -800}, { -299, -1517, -1000}, + { -640, -1850, -1526}, {-1454, -1536, -1233}, {-1890, -1955, -1756}, + {-1086, -1921, -2122}, { -750, -2325, -2260}, {-1325, -2413, -2673}, + {-1114, -2542, -3459}, {-1341, -2901, -3963}, {-1160, -2226, -1393}, + {-1001, -2772, -1573}, {-1594, -2641, -1978}, {-1534, -3046, -2624}, + {-2224, -2196, -675}, {-2807, -3054, -1102}, {-2008, -2840, -1186}, + {-1980, -3332, -1695}, {-1715, -3562, -505}, {-2527, -4000, -1887}, + {-2333, -2734, -2296}, {-3440, -2401, -3211}, {-2008, -3528, -3337}, + {-2247, -3291, -4510}, { -475, 949, 155}, { -149, 1365, 545}, + { -757, 1644, 1083}, { -217, 2053, 1353}, {-1433, 2301, 1462}, + { 495, 1661, 529}, { 10, 2037, 740}, { 2082, 1898, 978}, + { 2831, 2294, 911}, { 842, 793, 420}, { 1223, 1023, 863}, + { 1237, 451, 780}, { 1744, 708, 822}, { 1533, 284, 1384}, + { 2135, 609, 1538}, { 2305, 626, 540}, { 2368, 1187, 955}, + { 2586, 1255, -7}, { 3116, 1131, 726}, { 3431, 1730, 428}, + { 2734, 1648, 1307}, { 2988, 1231, 2010}, { 3523, 2024, 1488}, + { 1034, 1657, 871}, { 1206, 2163, 1036}, { 1807, 2372, 1233}, + { 1808, 1769, 1493}, { 1573, 2332, 1779}, { 1216, 1609, 1866}, + { 1480, 1898, 2513}, { 465, 2708, 2776}, { 771, 3638, 3338}, + { 1869, 2599, 2623}, { 2825, 2745, 2468}, { 2638, 2439, 1585}, + { 2094, 2970, 1308}, { 2022, 3057, 1999}, { 3428, 2912, 1816}, + { 4536, 2974, 2129}, { 1046, 2563, 2086}, { 1363, 3562, 2318}, + { 2511, 1891, 2984}, { 1866, 2306, 3986}, { 3272, 2924, 3682}, + { 3146, 3564, 2272}, { 3592, 3968, 2822}, { 2431, 3369, 3069}, + { 1931, 4709, 3090}, { 2629, 4220, 3986}, { 4639, 4056, 3664}, + { 4035, 5334, 4912} +}; + +static const int16_t lsp_band2[LSP_CB_SIZE][4] = { + { 0, 0, 0, 0}, { 601, 512, -542, 334}, + { 428, 1087, -484, -132}, { 652, 622, -391, -572}, + { 378, 799, 141, -860}, { 1040, 409, 112, -554}, + { 1123, 670, -75, -847}, { 1421, 494, -315, -1095}, + { 787, 1001, 114, -460}, { 988, 1672, 216, -681}, + { 1007, 1241, -132, -1247}, { 1073, 399, 186, -5}, + { 1262, 193, -694, -129}, { 325, 196, 51, -641}, + { 861, -59, 350, -458}, { 1261, 567, 586, -346}, + { 1532, 885, 210, -517}, { 2027, 937, 113, -792}, + { 1383, 1064, 334, 38}, { 1964, 1468, 459, 133}, + { 2062, 1186, -98, -121}, { 2577, 1445, 506, -373}, + { 2310, 1682, -2, -960}, { 2876, 1939, 765, 138}, + { 3581, 2360, 649, -414}, { 219, 176, -398, -309}, + { 434, -78, -435, -880}, { -344, 301, 265, -552}, + { -915, 470, 657, -380}, { 419, -432, -163, -453}, + { 351, -953, 8, -562}, { 789, -43, 20, -958}, + { 302, -594, -352, -1159}, { 1040, 108, -668, -924}, + { 1333, 210, -1217, -1663}, { 483, 589, -350, -1140}, + { 1003, 824, -802, -1184}, { 745, 58, -589, -1443}, + { 346, 247, -915, -1683}, { 270, 796, -720, -2043}, + { 1208, 722, -222, -193}, { 1486, 1180, -412, -672}, + { 1722, 179, -69, -521}, { 2047, 860, -666, -1410}, + { -146, 222, -281, -805}, { -189, 90, -114, -1307}, + { -152, 1086, -241, -764}, { -439, 733, -601, -1302}, + { -833, -167, -351, -601}, { -856, -422, -411, -1059}, + { -747, -355, -582, -1644}, { -837, 210, -916, -1144}, + {-1800, 32, -878, -1687}, { -48, -23, -1146, 52}, + { -350, -409, -1656, -364}, { 265, -728, -858, -577}, + { 458, -247, -1141, -997}, { 691, -407, -1988, -1161}, + { -66, -104, -705, -1249}, { -431, -93, -1191, -1844}, + { 203, -732, -1000, -1693}, { 10, -832, -1846, -1819}, + { 493, -128, -1436, -1768}, { 488, -311, -1730, -2540}, + { -653, -532, -1150, -1172}, {-1086, -289, -1706, -1533}, + { -699, -1205, -1216, -1766}, {-1032, -1481, -2074, -1523}, + { -721, -1220, -2277, -2600}, { 12, -539, -1484, -1131}, + { -40, -911, -2106, -441}, { -471, -484, -2267, -1549}, + { -141, -988, -3006, -1721}, {-1545, -2102, -583, 342}, + {-1383, -2772, -386, -13}, {-2118, -2589, -1205, 72}, + {-2147, -3231, -965, 390}, {-2949, -3300, -621, 637}, + {-3907, -4138, -865, 803}, {-1287, -845, -375, -548}, + {-1416, -1169, -487, -1277}, {-1400, -1690, -1027, -418}, + {-2018, -1909, -1188, -1260}, {-1418, -2222, -2029, -128}, + {-2067, -2998, -2693, -310}, { -950, -1028, -1538, 185}, + {-1616, -915, -2205, -549}, { 19, -821, -1145, 352}, + { 184, -1175, -1356, -627}, { -547, -1088, -1661, -911}, + { -216, -1502, -2197, -948}, { -795, -1306, -2374, -451}, + { -924, -1889, -2796, -680}, { -600, -1614, -3609, -885}, + {-2392, -2528, 319, 303}, {-2908, -2095, -310, 573}, + {-3460, -2141, 49, -113}, {-2231, -448, 675, -146}, + {-2805, -532, 1231, 479}, {-2684, -486, -200, 611}, + {-3525, -971, -198, 704}, {-3707, 173, 349, 254}, + {-4734, -1447, -34, 880}, { 777, -512, 114, -10}, + { 1250, -66, 442, -5}, { 604, 613, 452, -352}, + { 1224, 777, 675, -1014}, {-1372, -79, -1208, -238}, + {-2389, -17, -1157, -818}, {-1504, -673, -1133, -1060}, + {-1984, -799, -2005, -1973}, {-2037, -798, -1068, -105}, + {-3190, -899, -1817, -194}, { -156, -886, 394, -318}, + { -258, -1283, 551, 202}, { -536, -1729, 910, 331}, + { -847, -1109, 795, -163}, {-1171, -1128, 715, 519}, + {-1080, -1319, 1685, 668}, {-1000, -1921, 96, 211}, + {-1487, -2148, 831, 174}, {-1139, -374, 414, -4}, + {-1517, -1383, 396, -352}, {-1012, 439, -59, -967}, + {-1812, 706, -440, -1030}, {-1971, -329, -34, -827}, + {-2472, -1588, -151, -606}, {-2161, 374, -281, 76}, + {-3012, 231, -15, -690}, { 1104, 566, 721, 209}, + { 1685, 564, 383, 98}, { 1898, 750, 792, -97}, + { 556, -64, 561, -93}, { 876, 162, 913, -22}, + { 961, 675, 1296, 140}, { 756, -396, 851, 544}, + { 360, -303, 1341, 396}, { 878, -22, 1464, 863}, + { -309, -273, 642, -129}, { -686, -82, 842, 454}, + { -5, -47, 1069, 998}, { -94, 967, 1277, 298}, + { -489, 385, 1473, 746}, { -369, -717, 1333, 242}, + { 281, -993, 1726, 924}, { 464, 601, 1575, 1376}, + { -250, 206, 2339, 1175}, { -438, 377, -597, -285}, + {-1020, 787, -790, -287}, { -458, -410, 215, 295}, + { -589, -860, -121, 797}, {-1175, 122, -437, 466}, + {-1480, -121, 367, 924}, { 234, 323, 770, -555}, + { 145, 30, 996, 26}, { 66, 849, 93, -145}, + { -117, 1261, 474, -399}, {-1495, 1051, 218, -506}, + {-1390, 694, 994, 88}, { 616, 7, 78, 304}, + { 1060, 52, -62, 835}, { 833, 454, 649, 1359}, + { -770, 464, 47, 93}, { -574, 1199, -39, 379}, + { 114, -98, 488, 485}, { 727, 244, 606, 696}, + { -76, 455, 671, 546}, { -565, -13, 145, 819}, + { -376, 569, 448, 1128}, { 218, 122, 265, 1167}, + { 230, 738, 932, 1003}, { 138, 477, 36, 450}, + { 404, 787, -73, 1000}, { 497, 1259, 387, 1231}, + { 17, 207, 195, -79}, { 562, 358, 53, -158}, + { 493, 387, 478, 189}, { 678, 831, 640, 558}, + { -197, 523, 613, 57}, { 429, 894, 769, 111}, + { 67, 1174, 568, 511}, { 1242, 824, 251, 840}, + { 1419, 1074, 864, 481}, { 924, 1474, 669, 724}, + { 1539, 1879, 654, 1590}, { 445, 337, 1111, 541}, + { 472, 1421, 1264, 1094}, { 794, 735, 1103, 668}, + { 1055, 863, 1192, 1020}, { 778, 1105, 806, 1798}, + { 1052, 1527, 1587, 2151}, { 881, 1552, 1265, 391}, + { 726, 872, 1812, 601}, { 1469, 280, 1008, 616}, + { 1403, 577, 1803, 1244}, { 1650, 1314, 1148, 1072}, + { 1297, 1669, 1911, 1026}, { 2093, 1044, 2115, 1189}, + { 1644, 1961, 2587, 1512}, { 25, -315, -9, -106}, + { 290, -339, 428, -444}, { -68, -783, 735, 772}, + { 245, -555, 468, 47}, { 334, -895, 814, 146}, + { 235, 368, -964, -959}, { -203, 315, -1566, -1217}, + { 801, 17, -276, -354}, { 894, -495, -789, -635}, + { 716, 291, -1189, -357}, { 560, -260, -733, -2}, + { 679, -508, -1429, 211}, { -51, -62, -428, 557}, + { 322, -638, -211, 614}, { -878, -1057, -84, -71}, + { -388, -1415, -167, -318}, { -754, -1574, 214, -539}, + {-1419, -2004, -92, -787}, { -47, -856, -347, -255}, + { 23, -1211, -173, 320}, { -658, -487, -893, 353}, + { -783, -1587, -584, 507}, {-1420, -859, -378, 441}, + {-2095, -1491, -137, 439}, { -321, -1450, -1288, -12}, + { -359, -2113, -553, -8}, { -831, -1918, -1561, 32}, + {-1014, -2487, -1359, -939}, { -475, -311, -169, -236}, + { -907, -426, 276, -611}, { -96, -400, 50, -710}, + { -426, -1022, -10, -985}, { -197, -258, -744, -575}, + { -611, -930, -771, -394}, { -267, -776, -612, -939}, + { -256, -1346, -802, -1122}, { -796, -1570, -825, -754}, + { 712, 876, 141, 227}, { 981, 1509, 85, 124}, + { 1462, 1228, 979, -39}, { 1734, 999, 1481, 440}, + { 2293, 1116, 769, 440}, { 2504, 1480, 1241, 356}, + { 2474, 1909, 1558, 810}, { 917, 1134, 607, -134}, + { 509, 1809, 781, -123}, { 1712, 1506, 559, -423}, + { 2037, 2317, 726, -155}, { 3031, 2676, 1203, 331}, + { 3664, 3274, 1768, 531}, { 1610, 1839, 867, 183}, + { 1774, 1972, 1538, 97}, { 1822, 2158, 1282, 659}, + { 2222, 2758, 1818, 900}, { 3251, 2124, 1723, 996}, + { 3633, 2336, 2408, 1453}, { 2923, 3517, 2567, 1318}, +}; + +/** + * Used for the coding/decoding of the pulses positions + * for the MP-MLQ codebook + */ +static const int32_t combinatorial_table[PULSE_MAX][SUBFRAME_LEN/GRID_SIZE] = { + {118755, 98280, 80730, 65780, 53130, + 42504, 33649, 26334, 20349, 15504, + 11628, 8568, 6188, 4368, 3003, + 2002, 1287, 792, 462, 252, + 126, 56, 21, 6, 1, + 0, 0, 0, 0, 0}, + + { 23751, 20475, 17550, 14950, 12650, + 10626, 8855, 7315, 5985, 4845, + 3876, 3060, 2380, 1820, 1365, + 1001, 715, 495, 330, 210, + 126, 70, 35, 15, 5, + 1, 0, 0, 0, 0}, + + { 3654, 3276, 2925, 2600, 2300, + 2024, 1771, 1540, 1330, 1140, + 969, 816, 680, 560, 455, + 364, 286, 220, 165, 120, + 84, 56, 35, 20, 10, + 4, 1, 0, 0, 0}, + + { 406, 378, 351, 325, 300, + 276, 253, 231, 210, 190, + 171, 153, 136, 120, 105, + 91, 78, 66, 55, 45, + 36, 28, 21, 15, 10, + 6, 3, 1, 0, 0}, + + { 29, 28, 27, 26, 25, + 24, 23, 22, 21, 20, + 19, 18, 17, 16, 15, + 14, 13, 12, 11, 10, + 9, 8, 7, 6, 5, + 4, 3, 2, 1, 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}, +}; + +static const int16_t pitch_contrib[340] = { + 60, 0, 0, 2489, 60, 0, 0, 5217, + 1, 6171, 0, 3953, 0, 10364, 1, 9357, + -1, 8843, 1, 9396, 0, 5794, -1, 10816, + 2, 11606, -2, 12072, 0, 8616, 1, 12170, + 0, 14440, 0, 7787, -1, 13721, 0, 18205, + 0, 14471, 0, 15807, 1, 15275, 0, 13480, + -1, 18375, -1, 0, 1, 11194, -1, 13010, + 1, 18836, -2, 20354, 1, 16233, -1, 0, + 60, 0, 0, 12130, 0, 13385, 1, 17834, + 1, 20875, 0, 21996, 1, 0, 1, 18277, + -1, 21321, 1, 13738, -1, 19094, -1, 20387, + -1, 0, 0, 21008, 60, 0, -2, 22807, + 0, 15900, 1, 0, 0, 17989, -1, 22259, + 1, 24395, 1, 23138, 0, 23948, 1, 22997, + 2, 22604, -1, 25942, 0, 26246, 1, 25321, + 0, 26423, 0, 24061, 0, 27247, 60, 0, + -1, 25572, 1, 23918, 1, 25930, 2, 26408, + -1, 19049, 1, 27357, -1, 24538, 60, 0, + -1, 25093, 0, 28549, 1, 0, 0, 22793, + -1, 25659, 0, 29377, 0, 30276, 0, 26198, + 1, 22521, -1, 28919, 0, 27384, 1, 30162, + -1, 0, 0, 24237, -1, 30062, 0, 21763, + 1, 30917, 60, 0, 0, 31284, 0, 29433, + 1, 26821, 1, 28655, 0, 31327, 2, 30799, + 1, 31389, 0, 32322, 1, 31760, -2, 31830, + 0, 26936, -1, 31180, 1, 30875, 0, 27873, + -1, 30429, 1, 31050, 0, 0, 0, 31912, + 1, 31611, 0, 31565, 0, 25557, 0, 31357, + 60, 0, 1, 29536, 1, 28985, -1, 26984, + -1, 31587, 2, 30836, -2, 31133, 0, 30243, + -1, 30742, -1, 32090, 60, 0, 2, 30902, + 60, 0, 0, 30027, 0, 29042, 60, 0, + 0, 31756, 0, 24553, 0, 25636, -2, 30501, + 60, 0, -1, 29617, 0, 30649, 60, 0, + 0, 29274, 2, 30415, 0, 27480, 0, 31213, + -1, 28147, 0, 30600, 1, 31652, 2, 29068, + 60, 0, 1, 28571, 1, 28730, 1, 31422, + 0, 28257, 0, 24797, 60, 0, 0, 0, + 60, 0, 0, 22105, 0, 27852, 60, 0, + 60, 0, -1, 24214, 0, 24642, 0, 23305, + 60, 0, 60, 0, 1, 22883, 0, 21601, + 60, 0, 2, 25650, 60, 0, -2, 31253, + -2, 25144, 0, 17998 +}; + +/** + * Number of non-zero pulses in the MP-MLQ excitation + */ +static const int8_t pulses[4] = {6, 5, 6, 5}; + +/** + * Size of the MP-MLQ fixed excitation codebooks + */ +static const int32_t max_pos[4] = {593775, 142506, 593775, 142506}; + +static const int16_t fixed_cb_gain[GAIN_LEVELS] = { + 1, 2, 3, 4, 6, 9, 13, 18, + 26, 38, 55, 80, 115, 166, 240, 348, + 502, 726, 1050, 1517, 2193, 3170, 4582, 6623, +}; + +static const int16_t adaptive_cb_gain85[85 * 20] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 800, 1496, 167, -256, + -338, -39, -136, -1, -4, -6, -73, -8, + -15, 12, 23, 2, 16, 30, 3, -5, + -462, -686, 493, 2575, 311, -13, -28, -14, + -404, -5, -19, 13, 20, 72, 107, -77, + 8, 13, -9, -48, 1483, 144, 784, 928, + 1243, -134, -1, -37, -52, -94, -13, -71, + -6, -84, -8, -44, -112, -10, -59, -70, + -77, 275, 3522, 1056, -1254, 0, -4, -757, + -68, -95, 1, 16, -59, 4, -17, -227, + -5, 21, 269, 80, -125, -40, -264, 381, + 5027, 0, 0, -4, -8, -1542, 0, -2, + 0, 2, 0, 6, 38, 12, 81, -117, + 138, 332, 2215, 2574, 1339, -1, -6, -299, + -404, -109, -2, -18, -44, -21, -52, -348, + -11, -27, -181, -210, 3685, 2883, -887, 866, + -1639, -828, -507, -48, -45, -164, -648, 199, + 156, -194, -152, 46, 368, 288, -88, 86, + 1396, 2146, 2235, 345, 942, -118, -281, -305, + -7, -54, -182, -190, -292, -29, -45, -47, + -80, -123, -128, -19, 13, 4475, 3549, -804, + -655, 0, -1222, -768, -39, -26, -3, -2, + -969, 0, 219, 174, 0, 179, 141, -32, + -724, 254, 242, 6049, 2462, -32, -3, -3, + -2233, -370, 11, 10, -3, 267, -94, -89, + 108, -38, -36, -909, 626, -1713, 6121, 4561, + -1061, -23, -179, -2287, -1270, -68, 65, -233, + 640, -174, 477, -1704, 40, -111, 396, 295, + -350, 1391, 7985, 511, -405, -7, -118, -3892, + -15, -10, 29, 170, -678, 10, -43, -249, + -8, 34, 197, 12, 3144, -529, 608, 2530, + 3878, -603, -17, -22, -390, -918, 101, -116, + 19, -485, 81, -93, -744, 125, -144, -599, + 2589, -689, 3045, 5603, -404, -409, -29, -566, + -1916, -10, 108, -481, 128, -885, 235, -1041, + 63, -17, 75, 138, 3107, 513, 1374, -3594, + -4922, -589, -16, -115, -788, -1478, -97, -260, + -43, 681, 112, 301, 933, 154, 413, -1079, + 2468, 6010, 1107, -390, 1961, -372, -2204, -74, + -9, -234, -905, -166, -406, 58, 143, 26, + -295, -719, -132, 46, 4773, 2766, 2368, 4862, + -4044, -1390, -467, -342, -1443, -998, -806, -690, + -399, -1416, -821, -702, 1178, 682, 584, 1200, + 1665, -1879, 1443, 1701, 8562, -169, -215, -127, + -176, -4475, 190, -146, 165, -172, 195, -149, + -870, 982, -754, -889, 2716, 9011, -1007, 755, + -1785, -450, -4956, -61, -34, -194, -1493, 167, + 554, -125, -415, 46, 296, 982, -109, 82, + -2727, 7548, 1285, 938, 3420, -453, -3478, -100, + -53, -714, 1256, 213, -592, 156, -432, -73, + 569, -1576, -268, -196, 3677, 882, 4050, 1202, + 2323, -825, -47, -1001, -88, -329, -198, -909, + -218, -269, -64, -297, -521, -125, -574, -170, + 2046, -753, 122, 10102, 603, -255, -34, 0, + -6229, -22, 94, -15, 5, -1261, 464, -75, + -75, 27, -4, -372, 449, -1815, 10690, 3870, + -527, -12, -201, -6976, -914, -16, 49, -293, + 1184, -106, 428, -2525, 14, -58, 344, 124, + -941, 2352, 5049, 3650, 2637, -54, -337, -1556, + -813, -424, 135, 290, -725, 209, -524, -1125, + 151, -378, -812, -587, -1879, 796, 3117, 9569, + -404, -215, -38, -593, -5589, -9, 91, 357, + -151, 1097, -464, -1821, -46, 19, 76, 236, + -1715, 2043, -2096, 9946, 4001, -179, -254, -268, + -6038, -977, 213, -219, 261, 1041, -1240, 1272, + 418, -498, 511, -2429, -5772, -618, -3921, 284, + -3155, -2033, -23, -938, -4, -607, -218, -1381, + -148, 100, 10, 68, -1111, -119, -755, 54, + 382, 4748, 8003, -2064, 2198, -8, -1376, -3909, + -260, -294, -110, -186, -2319, 48, 598, 1008, + -51, -637, -1073, 277, -867, 3015, 11926, -1675, + 947, -45, -555, -8681, -171, -54, 159, 631, + -2195, -88, 308, 1219, 50, -174, -690, 96, + -4933, -432, 6757, 3771, 1352, -1485, -11, -2786, + -867, -111, -130, 2034, 178, 1135, 99, -1555, + 407, 35, -557, -311, 152, 9726, 4231, -1928, + 1490, -1, -5774, -1092, -226, -135, -90, -39, + -2511, 17, 1144, 498, -13, -884, -384, 175, + 2512, 193, 9033, 5361, -3148, -385, -2, -4980, + -1754, -605, -29, -1385, -106, -822, -63, -2956, + 482, 37, 1735, 1030, 8464, 2844, 12, 549, + 2132, -4373, -493, 0, -18, -277, -1469, -6, + -2, -284, -95, 0, -1101, -370, -1, -71, + 2141, -2602, 7166, 9046, -1350, -279, -413, -3134, + -4994, -111, 340, -936, 1138, -1182, 1436, -3957, + 176, -214, 590, 745, -244, 278, 13307, 1227, + -161, -3, -4, -10808, -91, -1, 4, 198, + -226, 18, -20, -997, -2, 2, 131, 12, + -1947, 8217, 6269, 917, -2559, -231, -4121, -2399, + -51, -399, 976, 745, -3144, 108, -460, -350, + -304, 1283, 979, 143, -1810, 2061, -2781, 6056, + 10058, -200, -259, -472, -2238, -6174, 227, -307, + 349, 669, -761, 1028, 1111, -1265, 1707, -3717, + 7827, 9161, -3409, 2473, -1510, -3739, -5122, -709, + -373, -139, -4376, 1628, 1906, -1181, -1382, 514, + 721, 844, -314, 228, -1430, 8313, 9541, -2955, + 1626, -124, -4218, -5556, -533, -161, 725, 832, + -4841, -257, 1499, 1721, 142, -825, -947, 293, + 2819, -4247, 5391, 8673, 2756, -485, -1101, -1774, + -4591, -463, 730, -927, 1397, -1492, 2248, -2854, + -474, 714, -907, -1459, 141, 14552, 690, 257, + -112, -1, -12926, -29, -4, 0, -125, -5, + -613, -2, -228, -10, 0, 99, 4, 1, + 11938, -1859, 1806, -962, -884, -8699, -211, -199, + -56, -47, 1355, -1316, 205, 701, -109, 106, + 644, -100, 97, -51, 3728, 1982, 2264, 4584, + 3131, -848, -239, -312, -1282, -598, -451, -515, + -273, -1043, -554, -633, -712, -378, -432, -876, + -1181, 766, 720, 14303, -216, -85, -35, -31, + -12486, -2, 55, 51, -33, 1031, -668, -628, + -15, 10, 9, 189, -4385, 4826, 10112, 1569, + 3388, -1173, -1421, -6242, -150, -700, 1291, 2706, + -2979, 420, -462, -969, 906, -998, -2091, -324, + -448, 1932, 15591, -1842, 657, -12, -227, -14837, + -207, -26, 52, 427, -1838, -50, 217, 1753, + 18, -77, -626, 74, -4141, 1844, 3962, 5517, + 6220, -1046, -207, -958, -1858, -2361, 466, 1001, + -446, 1394, -621, -1334, 1572, -700, -1504, -2094, + 729, -2299, 14755, 3657, -952, -32, -322, -13288, + -816, -55, 102, -656, 2071, -162, 513, -3294, + 42, -133, 857, 212, -1385, 5801, 13339, -3137, + 1344, -117, -2054, -10861, -600, -110, 490, 1127, + -4723, -265, 1111, 2554, 113, -476, -1094, 257, + 4710, 9661, 1073, -2467, 3274, -1354, -5697, -70, + -371, -654, -2777, -308, -633, 709, 1455, 161, + -941, -1930, -214, 493, 1843, -3624, 12422, 6898, + -1559, -207, -802, -9419, -2904, -148, 407, -1397, + 2748, -775, 1526, -5230, 175, -344, 1182, 656, + 1433, 2394, 2507, 1380, 8780, -125, -349, -383, + -116, -4705, -209, -219, -366, -120, -201, -211, + -768, -1283, -1343, -740, -1712, 12915, 5883, -2197, + 991, -179, -10181, -2112, -294, -60, 1350, 615, + -4638, -229, 1732, 789, 103, -781, -356, 133, + 15072, 2158, -1245, 910, -496, -13865, -284, -94, + -50, -15, -1986, 1145, 164, -837, -119, 69, + 456, 65, -37, 27, 4655, 7319, 4916, 586, + -3381, -1322, -3270, -1475, -20, -697, -2079, -1396, + -2196, -166, -261, -175, 960, 1510, 1014, 120, + 1191, -2140, 5120, 13498, -1418, -86, -279, -1600, + -11121, -122, 155, -372, 669, -981, 1763, -4218, + 103, -185, 443, 1168, -1530, -817, 8191, 9632, + -1452, -143, -40, -4095, -5663, -128, -76, 765, + 408, 900, 480, -4815, -135, -72, 726, 854, + -3236, 607, 1696, -2106, 11485, -639, -22, -175, + -270, -8051, 119, 335, -62, -416, 78, 218, + 2268, -425, -1189, 1476, 3203, -1903, -837, 9679, + 7057, -626, -221, -42, -5718, -3039, 372, 163, + -97, -1892, 1124, 494, -1380, 819, 360, -4169, + 213, -655, 17015, 620, -384, -2, -26, -17671, + -23, -9, 8, -221, 681, -8, 24, -644, + 5, -15, 399, 14, 5088, 35, -3339, 3726, + 8488, -1580, 0, -680, -847, -4397, -10, 1037, + 7, -1157, -8, 759, -2636, -18, 1730, -1930, + -988, 1454, -2688, 15039, 2682, -59, -129, -441, + -13805, -439, 87, -162, 238, 907, -1335, 2467, + 161, -238, 440, -2462, -4865, -2842, -53, 5495, + 6523, -1445, -493, 0, -1843, -2597, -844, -16, + -9, 1632, 953, 18, 1937, 1131, 21, -2188, + 3076, 15069, -2914, 1810, -971, -577, -13860, -518, + -200, -57, -2829, 547, 2680, -339, -1665, 322, + 182, 893, -172, 107, 1311, 5355, 11054, 2299, + -3654, -105, -1750, -7458, -322, -814, -428, -885, + -3613, -184, -751, -1551, 292, 1194, 2465, 512, + 4035, 5619, 4618, 1815, 1912, -994, -1927, -1301, + -201, -223, -1384, -1137, -1583, -447, -622, -511, + -471, -656, -539, -211, -2131, 2754, -4501, 12879, + 7432, -277, -463, -1236, -10124, -3371, 358, -585, + 756, 1675, -2165, 3538, 967, -1249, 2042, -5842, + 5618, -515, 3219, -4149, 4857, -1926, -16, -632, + -1050, -1440, 176, -1104, 101, 1422, -130, 815, + -1666, 152, -954, 1230, 1838, -1709, 1139, 16867, + 716, -206, -178, -79, -17366, -31, 191, -127, + 118, -1892, 1759, -1173, -80, 74, -49, -737, + 1978, -3845, 10050, 11854, -2492, -238, -902, -6164, + -8576, -379, 464, -1213, 2358, -1431, 2782, -7271, + 301, -585, 1529, 1803, -2600, 11246, 11289, -3647, + 1463, -412, -7720, -7778, -812, -130, 1784, 1791, + -7749, -578, 2504, 2513, 232, -1004, -1008, 325, + 3442, 907, 2725, 8970, 3638, -723, -50, -453, + -4911, -808, -190, -572, -150, -1884, -496, -1492, + -764, -201, -605, -1992, -126, 17498, 3481, -2003, + 1090, 0, -18689, -739, -244, -72, 135, 26, + -3717, -15, 2139, 425, 8, -1165, -231, 133, + -1814, 1048, -2164, 4070, 16272, -200, -67, -285, + -1011, -16160, 116, -239, 138, 450, -260, 537, + 1801, -1041, 2149, -4042, 9354, 12580, -1883, 962, + -617, -5341, -9660, -216, -56, -23, -7183, 1075, + 1446, -549, -738, 110, 352, 474, -71, 36, + 1708, 4199, 7387, 6335, 1003, -178, -1076, -3330, + -2449, -61, -437, -770, -1893, -660, -1623, -2856, + -104, -257, -452, -388, -2624, 5623, 17310, -2353, + 592, -420, -1930, -18288, -338, -21, 900, 2772, + -5941, -376, 807, 2486, 94, -203, -625, 85, + 1211, -850, 1193, -1926, 15992, -89, -44, -86, + -226, -15609, 62, -88, 61, 142, -100, 140, + -1182, 830, -1165, 1880, 3983, -2054, 11506, -19, + 3622, -968, -257, -8080, 0, -801, 499, -2797, + 1442, 4, -2, 13, -880, 454, -2544, 4, + -786, -1354, 16092, 7246, -1665, -37, -111, -15805, + -3205, -169, -65, 772, 1330, 348, 599, -7117, + -80, -137, 1636, 736, -4316, -511, 6674, 11665, + 4633, -1137, -15, -2719, -8305, -1310, -134, 1758, + 208, 3073, 364, -4752, 1220, 144, -1887, -3299, + 7912, 4557, 1937, 1885, 7037, -3821, -1267, -229, + -216, -3022, -2200, -935, -538, -910, -524, -222, + -3398, -1957, -832, -809, 3434, 2967, 5867, 8196, + 8766, -720, -537, -2101, -4100, -4690, -622, -1230, + -1062, -1718, -1484, -2935, -1837, -1588, -3139, -4385, + 5881, 9176, 8119, 3934, 3355, -2111, -5139, -4023, + -944, -687, -3294, -2914, -4547, -1412, -2203, -1949, + -1204, -1879, -1662, -805 +}; + +static const int16_t adaptive_cb_gain170[170 * 20] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 776, 212, 715, 670, + 809, -36, -2, -31, -27, -39, -10, -33, + -9, -31, -8, -29, -38, -10, -35, -33, + 1296, 1316, -168, -320, -815, -102, -105, -1, + -6, -40, -104, 13, 13, 25, 25, -3, + 64, 65, -8, -15, -589, 680, 2478, 308, + -596, -21, -28, -375, -5, -21, 24, 89, + -102, 11, -12, -46, -21, 24, 90, 11, + -735, -487, -5, 2948, 468, -33, -14, 0, + -530, -13, -21, 0, 0, 132, 87, 0, + 21, 13, 0, -84, 1042, 1730, 1068, 333, + 626, -66, -182, -69, -6, -23, -110, -67, + -112, -21, -35, -21, -39, -66, -40, -12, + 486, -769, 4074, 2825, -1107, -14, -36, -1013, + -487, -74, 22, -120, 191, -83, 132, -702, + 32, -52, 275, 191, 1521, -767, -124, 4320, + 1026, -141, -35, 0, -1139, -64, 71, 11, + -5, -401, 202, 32, -95, 48, 7, -270, + 2425, 1267, 3439, -91, -1166, -359, -98, -722, + 0, -83, -187, -509, -266, 13, 7, 19, + 172, 90, 244, -6, -1251, 975, 173, 4039, + 2005, -95, -58, -1, -996, -245, 74, 13, + -10, 308, -240, -42, 153, -119, -21, -494, + 1820, 632, 1322, 2062, 1031, -202, -24, -106, + -259, -64, -70, -146, -51, -229, -79, -166, + -114, -39, -83, -129, -447, 4904, 244, -315, + -2038, -12, -1467, -3, -6, -253, 134, 6, + -73, -8, 94, 4, -55, 610, 30, -39, + -208, -1102, 463, -448, 5653, -2, -74, -13, + -12, -1950, -14, 5, 31, -5, -30, 12, + 71, 380, -159, 154, 4739, 2600, -1864, 856, + -1554, -1371, -412, -212, -44, -147, -752, 539, + 295, -247, -135, 97, 449, 246, -176, 81, + 1894, 3533, 35, -26, 2145, -219, -762, 0, + 0, -280, -408, -4, -7, 3, 5, 0, + -248, -462, -4, 3, -2699, 1841, 4072, 2443, + 1582, -444, -207, -1012, -364, -152, 303, 670, + -457, 402, -274, -607, 260, -177, -393, -236, + -844, 3358, 6106, -1059, -537, -43, -688, -2275, + -68, -17, 173, 314, -1251, -54, 217, 395, + -27, 110, 200, -34, 1251, 1016, 3020, 2210, + 1445, -95, -63, -556, -298, -127, -77, -230, + -187, -168, -137, -407, -110, -89, -266, -194, + 2099, 2277, 4038, 3533, -2870, -269, -316, -995, + -762, -503, -291, -517, -561, -452, -491, -871, + 367, 399, 707, 619, 400, -1114, 8516, 2422, + -1117, -9, -75, -4426, -358, -76, 27, -208, + 579, -59, 164, -1259, 27, -75, 580, 165, + -4398, -2011, 3912, -2407, 2258, -1180, -247, -934, + -353, -311, -540, 1050, 480, -646, -295, 575, + 606, 277, -539, 331, 1767, -1447, 4240, 6160, + -757, -190, -127, -1097, -2316, -35, 156, -457, + 374, -664, 544, -1594, 81, -66, 195, 284, + 1594, -1463, 1035, 6938, 1920, -155, -130, -65, + -2938, -225, 142, -100, 92, -675, 619, -438, + -186, 171, -121, -813, -562, 4716, 4085, -591, + 2421, -19, -1357, -1018, -21, -357, 162, 140, + -1175, -20, 170, 147, 83, -696, -603, 87, + 1552, 8778, -935, 354, -1424, -147, -4703, -53, + -7, -123, -831, 88, 501, -33, -189, 20, + 134, 763, -81, 30, 4831, -4431, 41, -1479, + -2976, -1424, -1198, 0, -133, -540, 1306, -12, + 11, 436, -400, 3, 877, -804, 7, -268, + 2090, 1192, 1006, 1645, 4853, -266, -86, -61, + -165, -1437, -152, -128, -73, -210, -119, -101, + -619, -353, -298, -487, 2386, 5712, 1426, -94, + 1350, -347, -1991, -124, 0, -111, -832, -207, + -497, 13, 32, 8, -196, -470, -117, 7, + -1349, 1091, 1659, 8891, 313, -111, -72, -168, + -4825, -5, 89, 136, -110, 732, -592, -900, + 25, -20, -31, -170, 9980, 916, -381, -808, + 88, -6080, -51, -8, -39, 0, -558, 232, + 21, 492, 45, -18, -53, -4, 2, 4, + 2338, -1031, -248, 3928, 6484, -333, -64, -3, + -942, -2566, 147, 35, -15, -560, 247, 59, + -925, 408, 98, -1555, 6166, -1240, -337, 3672, + -1277, -2320, -93, -6, -823, -99, 466, 126, + -25, -1382, 278, 75, 480, -96, -26, 286, + 4377, -132, -2588, 1701, 4865, -1169, -1, -409, + -176, -1444, 35, 691, -20, -454, 13, 268, + -1299, 39, 768, -505, 2594, 3295, 3944, 1481, + 682, -410, -662, -949, -133, -28, -521, -624, + -793, -234, -297, -356, -108, -137, -164, -61, + 4151, 624, 815, 4485, 2229, -1052, -23, -40, + -1228, -303, -158, -206, -31, -1136, -170, -223, + -565, -84, -111, -610, -3575, -361, 4924, 2791, + 4698, -780, -7, -1480, -475, -1347, -78, 1074, + 108, 609, 61, -839, 1025, 103, -1412, -800, + -2518, 3791, 8623, 315, 2465, -387, -877, -4538, + -6, -370, 582, 1325, -1995, 48, -73, -166, + 378, -570, -1297, -47, -691, 2989, 9957, -421, + -1142, -29, -545, -6051, -10, -79, 126, 420, + -1817, -17, 76, 256, -48, 208, 694, -29, + -1918, 104, -3190, -3410, -4440, -224, 0, -621, + -709, -1203, 12, -373, 20, -399, 21, -664, + -519, 28, -864, -924, -3359, -1668, 1854, 6939, + 1430, -688, -169, -209, -2939, -124, -341, 380, + 188, 1422, 706, -785, 293, 145, -161, -606, + 42, 9706, 3164, -952, 907, 0, -5750, -611, + -55, -50, -25, -8, -1874, 2, 564, 183, + -2, -537, -175, 52, 1607, 785, 2862, 4327, + 3307, -157, -37, -500, -1143, -667, -77, -280, + -137, -424, -207, -756, -324, -158, -577, -873, + 6801, 3416, 2227, 1682, -3217, -2823, -712, -302, + -172, -631, -1418, -924, -464, -698, -350, -228, + 1335, 670, 437, 330, 3459, 3898, 364, 7841, + -2640, -730, -927, -8, -3753, -425, -823, -76, + -86, -1655, -1865, -174, 557, 628, 58, 1263, + -5902, -3458, -2465, -1886, 4334, -2126, -730, -371, + -217, -1146, -1245, -888, -520, -679, -398, -283, + 1561, 915, 652, 499, -3710, 1133, 7849, 3443, + -215, -840, -78, -3760, -723, -2, 256, 1777, + -543, 779, -238, -1649, -48, 14, 103, 45, + 4132, 2828, 2, -4212, -4116, -1042, -488, 0, + -1083, -1034, -713, 0, 0, 1062, 727, 0, + 1038, 710, 0, -1058, 5875, 8496, -1796, 1376, + -1786, -2107, -4406, -197, -115, -194, -3047, 644, + 931, -493, -713, 150, 640, 926, -195, 150, + 3143, 3483, 3546, -793, 4489, -603, -740, -767, + -38, -1230, -668, -680, -754, 152, 168, 171, + -861, -954, -971, 217, 2845, 7965, 3695, -5432, + 3978, -494, -3873, -833, -1801, -966, -1383, -641, + -1796, 943, 2641, 1225, -691, -1934, -897, 1319, + 1538, 150, 7139, 2049, 3097, -144, -1, -3110, + -256, -585, -14, -670, -65, -192, -18, -892, + -290, -28, -1349, -387, 618, 7520, 4729, -238, + -3373, -23, -3452, -1365, -3, -694, -283, -178, + -2170, 8, 109, 68, 127, 1548, 973, -49, + 2965, -3013, 7912, 7076, -1997, -536, -554, -3821, + -3056, -243, 545, -1431, 1455, -1280, 1301, -3417, + 361, -367, 964, 862, 2443, -929, -1113, 9677, + 4138, -364, -52, -75, -5716, -1045, 138, 166, + -63, -1443, 549, 657, -617, 234, 281, -2444, + 1966, 3309, 10085, -3399, 2105, -236, -668, -6207, + -705, -270, -397, -1210, -2037, 408, 686, 2092, + -252, -425, -1295, 436, -112, -1368, 8868, 4822, + 2048, 0, -114, -4800, -1419, -256, -9, 61, + 740, 33, 402, -2610, 14, 171, -1108, -602, + -2597, 438, -1839, 6229, 7266, -411, -11, -206, + -2368, -3223, 69, -291, 49, 987, -166, 699, + 1152, -194, 816, -2763, 3454, 553, 9127, 4946, + -5596, -728, -18, -5084, -1493, -1911, -116, -1924, + -308, -1042, -166, -2755, 1179, 188, 3117, 1689, + -532, -663, 12262, 2495, -1004, -17, -26, -9177, + -380, -61, -21, 398, 496, 81, 101, -1867, + -32, -40, 751, 152, -2100, 1317, -1509, 11425, + 2997, -269, -105, -139, -7967, -548, 168, -193, + 121, 1464, -918, 1052, 384, -240, 276, -2090, + 1193, -2697, 11259, 5373, -763, -86, -444, -7737, + -1762, -35, 196, -819, 1853, -391, 884, -3692, + 55, -125, 525, 250, 2405, -471, 11079, 203, + 782, -353, -13, -7491, -2, -37, 69, -1626, + 318, -29, 5, -137, -114, 22, -529, -9, + -1871, 5685, 11290, -2662, 1353, -213, -1972, -7780, + -432, -111, 649, 1289, -3917, -304, 923, 1834, + 154, -469, -932, 220, -3768, 5927, -3093, 5041, + 5212, -866, -2144, -584, -1551, -1658, 1363, -711, + 1119, 1159, -1824, 951, 1198, -1885, 984, -1603, + -2546, 9502, 5969, -2440, 1928, -395, -5511, -2175, + -363, -226, 1477, 927, -3462, -379, 1415, 889, + 299, -1118, -702, 287, -4963, 3568, 4592, 5508, + 3451, -1503, -777, -1287, -1851, -727, 1080, 1391, + -1000, 1668, -1199, -1543, 1045, -751, -967, -1160, + 1745, -2586, 3983, 10899, -1551, -186, -408, -968, + -7250, -146, 275, -424, 628, -1161, 1720, -2649, + 165, -244, 377, 1032, 867, -456, -727, 3369, + 11822, -45, -12, -32, -692, -8531, 24, 38, + -20, -178, 93, 149, -625, 329, 525, -2431, + 7535, 2422, 1926, 1405, 1599, -3466, -358, -226, + -120, -156, -1114, -886, -284, -646, -207, -165, + -735, -236, -188, -137, 1041, -735, -142, 13209, + 1515, -66, -33, -1, -10649, -140, 46, 9, + -6, -839, 593, 114, -96, 68, 13, -1222, + 7950, 6745, -1444, -1008, 2721, -3857, -2777, -127, + -62, -452, -3273, 700, 594, 489, 415, -88, + -1320, -1120, 239, 167, -4754, -1379, 4522, -578, + -5733, -1379, -116, -1248, -20, -2006, -400, 1312, + 380, -167, -48, 159, -1663, -482, 1582, -202, + 3220, 5978, 5923, 2430, -2689, -633, -2181, -2141, + -360, -441, -1175, -1164, -2161, -477, -886, -878, + 528, 981, 972, 398, 377, 1312, 13978, -1470, + 677, -8, -105, -11925, -132, -28, -30, -321, + -1119, 33, 117, 1254, -15, -54, -577, 60, + -3435, 6770, 314, -885, 5686, -720, -2797, -6, + -47, -1973, 1419, 65, -129, -185, 366, 16, + 1192, -2349, -109, 307, 3171, 8774, -2260, 2679, + 3069, -613, -4699, -312, -438, -575, -1698, 437, + 1210, -518, -1435, 369, -594, -1643, 423, -501, + 5557, 1509, 5407, -125, -7386, -1884, -139, -1784, + 0, -3330, -511, -1834, -498, 42, 11, 41, + 2505, 680, 2438, -56, -2838, 2595, 13228, 271, + 1793, -491, -411, -10680, -4, -196, 449, 2291, + -2095, 47, -42, -219, 310, -284, -1447, -29, + 664, -278, 14966, 951, -711, -26, -4, -13672, + -55, -30, 11, -606, 253, -38, 16, -869, + 28, -12, 650, 41, 808, 1770, 8658, 5863, + -1486, -39, -191, -4576, -2098, -134, -87, -427, + -935, -289, -633, -3098, 73, 160, 785, 531, + 3063, 1539, 2000, -542, 9576, -572, -144, -244, + -17, -5597, -287, -374, -188, 101, 51, 66, + -1790, -900, -1169, 317, 514, 14083, -323, 896, + -891, -16, -12106, -6, -49, -48, -442, 10, + 277, -28, -770, 17, 27, 766, -17, 48, + 892, 158, 5237, 11057, -1603, -48, -1, -1674, + -7462, -156, -8, -285, -50, -602, -106, -3534, + 87, 15, 512, 1082, -1612, 2564, -4296, 12526, + 5710, -158, -401, -1126, -9576, -1990, 252, -422, + 672, 1232, -1960, 3284, 561, -893, 1497, -4365, + 4889, -6878, 612, 6109, 4753, -1459, -2887, -22, + -2277, -1379, 2052, -182, 257, -1823, 2564, -228, + -1418, 1995, -177, -1772, 3053, -506, 2403, 9625, + 1322, -569, -15, -352, -5655, -106, 94, -448, + 74, -1794, 297, -1412, -246, 40, -194, -777, + -754, 12904, 4480, -2113, 1471, -34, -10163, -1225, + -272, -132, 594, 206, -3529, -97, 1664, 577, + 67, -1159, -402, 189, 4255, 1476, 5055, 2393, + 2912, -1105, -132, -1559, -349, -517, -383, -1313, + -455, -621, -215, -738, -756, -262, -898, -425, + -1371, 535, 1417, 14604, -997, -114, -17, -122, + -13017, -60, 44, 118, -46, 1222, -477, -1263, + -83, 32, 86, 888, 5368, -1744, 4083, -1236, + 3753, -1758, -185, -1017, -93, -860, 571, -1338, + 434, 405, -131, 308, -1229, 399, -935, 283, + 1588, -3097, 14415, 3699, -1171, -154, -585, -12683, + -835, -83, 300, -1397, 2725, -358, 699, -3255, + 113, -221, 1030, 264, 212, 7989, 9471, -3344, + 2009, -2, -3895, -5475, -682, -246, -103, -123, + -4618, 43, 1630, 1933, -26, -979, -1161, 410, + 856, 2294, -627, 6930, 6929, -44, -321, -24, + -2931, -2930, -119, 32, 87, -362, -970, 265, + -362, -970, 265, -2931, 2357, -4187, 7162, 7683, + 3371, -339, -1070, -3131, -3603, -693, 602, -1030, + 1830, -1105, 1963, -3359, -485, 861, -1474, -1581, + 350, 4585, 14053, -3819, 1218, -7, -1283, -12054, + -890, -90, -97, -300, -3933, 81, 1068, 3275, + -26, -341, -1045, 284, -3248, 3531, 475, 2137, + 11711, -644, -761, -13, -278, -8372, 700, 94, + -102, 423, -460, -62, 2322, -2524, -340, -1528, + -3017, 3852, 1725, 8440, 5257, -555, -905, -181, + -4348, -1686, 709, 317, -405, 1554, -1984, -889, + 968, -1236, -553, -2708, -909, 3196, 15512, -2528, + 1066, -50, -623, -14686, -390, -69, 177, 861, + -3026, -140, 493, 2393, 59, -208, -1009, 164, + 959, -3370, 9617, 9545, -1761, -56, -693, -5645, + -5561, -189, 197, -563, 1978, -558, 1963, -5603, + 103, -362, 1034, 1026, 7575, 11796, -4845, 3252, + -1703, -3502, -8493, -1433, -645, -177, -5454, 2240, + 3488, -1503, -2341, 961, 787, 1226, -503, 338, + 6409, 1722, 1764, -4191, 6015, -2507, -181, -189, + -1072, -2208, -673, -690, -185, 1639, 440, 451, + -2353, -632, -647, 1538, -2420, 12161, 5038, 1286, + -2098, -357, -9027, -1549, -100, -268, 1796, 744, + -3740, 190, -954, -395, -310, 1557, 645, 164, + -2232, -1341, 7246, 9470, -1977, -304, -109, -3204, + -5474, -238, -182, 987, 593, 1290, 775, -4188, + -269, -161, 874, 1143, 1030, 7034, 4231, 1551, + 3077, -64, -3019, -1093, -146, -577, -442, -266, + -1816, -97, -666, -400, -193, -1321, -794, -291, + 5121, 11835, -477, -1749, 2298, -1601, -8549, -13, + -186, -322, -3699, 149, 344, 546, 1264, -50, + -718, -1660, 66, 245, -3328, 3827, 5921, 9976, + -1045, -676, -894, -2140, -6075, -66, 777, 1203, + -1383, 2027, -2330, -3605, -212, 244, 377, 636, + 3813, 5718, -4666, -3412, 5674, -887, -1995, -1329, + -710, -1965, -1331, 1086, 1628, 794, 1191, -972, + -1320, -1980, 1616, 1181, 1348, -3672, 13154, 6938, + -1690, -110, -823, -10561, -2938, -174, 302, -1082, + 2948, -570, 1555, -5570, 139, -379, 1357, 716, + 2151, -3586, 6949, 12131, -1224, -282, -785, -2947, + -8982, -91, 470, -912, 1521, -1592, 2655, -5145, + 160, -268, 519, 906, -2889, 9647, 10276, -2728, + 995, -509, -5680, -6445, -454, -60, 1701, 1812, + -6051, -481, 1606, 1711, 175, -586, -624, 165, + 6177, 2184, 555, 1985, 6589, -2329, -291, -18, + -240, -2650, -823, -209, -74, -748, -264, -67, + -2484, -878, -223, -798, -492, 391, 17166, -681, + 240, -14, -9, -17987, -28, -3, 11, 515, + -410, -20, 16, 713, 7, -5, -252, 10, + 12628, 5448, -2630, 3011, -2695, -9733, -1811, -422, + -553, -443, -4199, 2027, 874, -2321, -1001, 483, + 2077, 896, -432, 495, -3628, -534, 3447, 7002, + 6751, -803, -17, -725, -2992, -2782, -118, 763, + 112, 1550, 228, -1473, 1495, 220, -1420, -2885, + -5239, 5901, 8107, 3650, 4846, -1675, -2125, -4012, + -813, -1433, 1887, 2592, -2920, 1167, -1315, -1806, + 1550, -1745, -2398, -1080, 6157, 6678, 4099, -1074, + 2348, -2314, -2722, -1025, -70, -336, -2509, -1540, + -1670, 403, 437, 268, -882, -957, -587, 153, + 1079, 16099, 242, -881, 1690, -71, -15820, -3, + -47, -174, -1060, -16, -238, 58, 865, 13, + -111, -1661, -25, 90, -278, 227, -1039, 1636, + 16945, -4, -3, -65, -163, -17526, 3, -17, + 14, 27, -22, 103, 287, -234, 1074, -1693, + 15778, -1454, 574, -603, -107, -15195, -129, -20, + -22, 0, 1400, -553, 51, 581, -53, 21, + 103, -9, 3, -3, 2406, -836, 13224, 7993, + -4266, -353, -42, -10673, -3899, -1111, 122, -1942, + 674, -1174, 407, -6451, 626, -217, 3443, 2081, + 3184, 14368, -3336, 2255, -1801, -619, -12600, -679, + -310, -198, -2793, 648, 2926, -438, -1977, 459, + 350, 1580, -366, 247, -1698, 17076, 2504, -539, + -646, -176, -17798, -382, -17, -25, 1770, 259, + -2610, -55, 561, 82, -67, 673, 98, -21, + 2375, -797, -2696, 14483, 5383, -344, -38, -443, + -12803, -1769, 115, 391, -131, -2100, 705, 2384, + -780, 262, 886, -4759, -2691, 2554, -4520, 9573, + 10655, -442, -398, -1247, -5594, -6930, 419, -742, + 704, 1572, -1492, 2641, 1750, -1661, 2939, -6226, + -4332, -4399, -1657, 4880, 7375, -1145, -1181, -167, + -1453, -3319, -1163, -438, -444, 1290, 1310, 493, + 1950, 1980, 745, -2196, -3498, 7405, 9955, 2693, + -2971, -746, -3347, -6049, -442, -538, 1581, 2125, + -4499, 575, -1217, -1636, -634, 1342, 1805, 488, + 6717, -3792, 7739, 2798, 3489, -2754, -877, -3655, + -477, -743, 1554, -3173, 1791, -1147, 647, -1321, + -1430, 807, -1648, -595, 5263, 9770, 3463, 1069, + -3971, -1690, -5826, -732, -69, -962, -3138, -1112, + -2065, -343, -637, -226, 1275, 2368, 839, 259, + 1243, -2634, 16772, 1871, 332, -94, -423, -17169, + -213, -6, 199, -1273, 2696, -142, 300, -1915, + -25, 53, -339, -37, 2691, 2836, 3105, 5711, + 4817, -442, -491, -588, -1991, -1416, -465, -510, + -537, -938, -988, -1082, -791, -834, -913, -1679, + 4366, 2944, 7210, 3627, 1161, -1163, -529, -3172, + -803, -82, -784, -1921, -1295, -966, -651, -1596, + -309, -208, -511, -257, 13888, 3951, -671, -2305, + 3354, -11773, -953, -27, -324, -686, -3349, 569, + 161, 1954, 556, -94, -2843, -809, 137, 472, + 7053, 5847, 2929, 8378, -4794, -3036, -2086, -523, + -4284, -1403, -2517, -1261, -1045, -3607, -2990, -1498, + 2064, 1711, 857, 2451, -2191, 12838, 9182, -3915, + 1617, -293, -10059, -5146, -935, -159, 1717, 1228, + -7195, -523, 3068, 2194, 216, -1267, -906, 386, + -4881, 13114, 5767, -435, 4155, -1454, -10498, -2030, + -11, -1054, 3907, 1718, -4616, -129, 348, 153, + 1238, -3326, -1462, 110, 7843, -1250, 210, 7106, + -5203, -3754, -95, -2, -3082, -1652, 598, -100, + 16, -3402, 542, -91, 2491, -397, 66, 2257, + -2463, 8168, 14551, -3908, 1828, -370, -4072, -12923, + -932, -204, 1228, 2188, -7254, -587, 1948, 3471, + 274, -911, -1623, 436, -1579, 347, -272, -2735, + 16031, -152, -7, -4, -456, -15686, 33, -26, + 5, -263, 58, -45, 1545, -340, 266, 2676, + -6327, 1328, 5093, -5079, 7617, -2443, -107, -1583, + -1574, -3541, 513, 1967, -413, -1961, 411, 1578, + 2941, -617, -2367, 2361, 3286, -4509, 11306, 11025, + -2623, -659, -1241, -7802, -7419, -420, 904, -2267, + 3112, -2211, 3034, -7608, 526, -722, 1810, 1765, + 5567, 17853, -3754, 1166, -519, -1892, -19455, -860, + -83, -16, -6067, 1275, 4090, -396, -1271, 267, + 176, 566, -119, 37, -2136, -424, 15292, 5108, + -1648, -278, -10, -14273, -1593, -165, -55, 1993, + 396, 666, 132, -4768, -214, -42, 1538, 514, + 2267, -3297, 2549, 16563, -791, -313, -663, -396, + -16745, -38, 456, -352, 513, -2291, 3333, -2576, + 109, -159, 123, 799, 3655, 1899, -3364, 6279, + 12510, -815, -220, -690, -2406, -9552, -423, 750, + 390, -1400, -728, 1289, -2791, -1450, 2568, -4794, + 8052, 2285, -6193, 5138, 6003, -3957, -318, -2341, + -1611, -2199, -1123, 3044, 864, -2525, -716, 1942, + -2950, -837, 2269, -1882, -386, -2291, 7679, 15387, + -2723, -9, -320, -3599, -14452, -452, -54, 181, + 1074, 362, 2152, -7212, -64, -380, 1276, 2557, + 2777, -1173, 3984, 13079, 2508, -470, -84, -969, + -10440, -384, 198, -675, 285, -2217, 936, -3180, + -425, 179, -610, -2002, -1879, 1771, -2684, 16705, + 1833, -215, -191, -439, -17032, -205, 203, -308, + 290, 1916, -1805, 2736, 210, -198, 300, -1869, + 1052, 4495, 15519, 1467, -4032, -67, -1233, -14700, + -131, -992, -288, -997, -4257, -94, -402, -1389, + 259, 1106, 3819, 361, 3010, 2544, 6969, 7559, + 1996, -553, -395, -2964, -3487, -243, -467, -1280, + -1082, -1388, -1174, -3215, -366, -310, -849, -921, + -5209, -1867, 8713, 10351, 1549, -1656, -212, -4634, + -6540, -146, -593, 2770, 993, 3291, 1180, -5505, + 492, 176, -824, -979, -4314, 8513, 913, 7547, + -2723, -1135, -4423, -50, -3476, -452, 2241, 240, + -474, 1987, -3921, -420, -717, 1415, 151, 1254, + 12929, -1219, 2448, 1757, 6303, -10204, -90, -365, + -188, -2425, 962, -1932, 182, -1386, 130, -262, + -4974, 469, -941, -676, 6465, 4132, 3167, 3160, + 5697, -2551, -1042, -612, -609, -1981, -1630, -1249, + -798, -1247, -797, -611, -2248, -1437, -1101, -1099, + -3636, 4859, 18914, -1335, 810, -807, -1441, -21836, + -108, -40, 1078, 4198, -5609, -296, 396, 1541, + 179, -240, -936, 66, 8844, 7864, 654, -4063, + -5680, -4774, -3774, -26, -1007, -1969, -4245, -353, + -314, 2193, 1950, 162, 3066, 2726, 226, -1408, + 1859, 2634, 9228, 996, 9464, -211, -423, -5197, + -60, -5467, -299, -1047, -1483, -113, -160, -561, + -1074, -1521, -5330, -575, 2949, 12260, 10290, -497, + -3943, -530, -9174, -6463, -15, -949, -2206, -1852, + -7700, 89, 372, 312, 709, 2950, 2476, -119, + -2903, 1552, 14867, 9970, -496, -514, -147, -13491, + -6068, -15, 275, 2634, -1408, 1766, -944, -9047, + -87, 47, 450, 302, 3243, 8234, 7586, 3373, + 2151, -642, -4138, -3512, -694, -282, -1630, -1501, + -3812, -667, -1695, -1561, -425, -1081, -996, -442, + -9631, 60, 3501, 5359, 10150, -5662, 0, -748, + -1752, -6288, 35, 2058, -12, 3150, -19, -1145, + 5967, -37, -2169, -3320, -6874, -2553, -5446, -2195, + -7841, -2884, -397, -1810, -294, -3753, -1071, -2285, + -848, -921, -342, -729, -3290, -1221, -2606, -1050, + -3413, -1141, 4630, 13612, 7897, -711, -79, -1308, + -11310, -3806, -237, 964, 322, 2836, 948, -3847, + 1645, 550, -2231, -6561, 4410, -5678, 8006, -3992, + 3811, -1187, -1968, -3912, -973, -886, 1528, -2155, + 2775, 1074, -1383, 1951, -1025, 1321, -1862, 928, + 5659, 11535, 2203, -452, 7169, -1954, -8121, -296, + -12, -3137, -3984, -761, -1551, 156, 318, 60, + -2476, -5048, -964, 197, 2914, -2914, 3485, -3965, + 13675, -518, -518, -741, -959, -11414, 518, -620, + 620, 705, -705, 843, -2433, 2432, -2909, 3310, + 7843, 1907, 1022, 8882, 7972, -3755, -222, -63, + -4815, -3879, -913, -489, -119, -4252, -1034, -554, + -3816, -928, -497, -4322, 13807, 9531, 1436, 1612, + 1779, -11636, -5544, -125, -158, -193, -8032, -1210, + -835, -1358, -938, -141, -1499, -1035, -156, -175, + 13620, -5337, 5450, -2263, 1723, -11322, -1738, -1813, + -312, -181, 4436, -4531, 1775, 1881, -737, 752, + -1432, 561, -573, 238, 5297, 8374, 8872, 7694, + 6538, -1712, -4280, -4804, -3613, -2609, -2707, -2868, + -4534, -2487, -3932, -4166, -2113, -3341, -3540, -3070 +}; + +/** + * 0.65^i (Zero part) and 0.75^i (Pole part) scaled by 2^15 + */ +static const int16_t postfilter_tbl[2][LPC_ORDER] = { + /* Zero */ + {21299, 13844, 8999, 5849, 3802, 2471, 1606, 1044, 679, 441}, + /* Pole */ + {24576, 18432, 13824, 10368, 7776, 5832, 4374, 3281, 2460, 1845} +}; + +/** + * Hamming window coefficients scaled by 2^15 + */ +static const int16_t hamming_window[LPC_FRAME] = { + 2621, 2631, 2659, 2705, 2770, 2853, 2955, 3074, 3212, 3367, + 3541, 3731, 3939, 4164, 4405, 4663, 4937, 5226, 5531, 5851, + 6186, 6534, 6897, 7273, 7661, 8062, 8475, 8899, 9334, 9780, + 10235, 10699, 11172, 11653, 12141, 12636, 13138, 13645, 14157, 14673, + 15193, 15716, 16242, 16769, 17298, 17827, 18356, 18884, 19411, 19935, + 20457, 20975, 21489, 21999, 22503, 23002, 23494, 23978, 24455, 24924, + 25384, 25834, 26274, 26704, 27122, 27529, 27924, 28306, 28675, 29031, + 29373, 29700, 30012, 30310, 30592, 30857, 31107, 31340, 31557, 31756, + 31938, 32102, 32249, 32377, 32488, 32580, 32654, 32710, 32747, 32766, + 32766, 32747, 32710, 32654, 32580, 32488, 32377, 32249, 32102, 31938, + 31756, 31557, 31340, 31107, 30857, 30592, 30310, 30012, 29700, 29373, + 29031, 28675, 28306, 27924, 27529, 27122, 26704, 26274, 25834, 25384, + 24924, 24455, 23978, 23494, 23002, 22503, 21999, 21489, 20975, 20457, + 19935, 19411, 18884, 18356, 17827, 17298, 16769, 16242, 15716, 15193, + 14673, 14157, 13645, 13138, 12636, 12141, 11653, 11172, 10699, 10235, + 9780, 9334, 8899, 8475, 8062, 7661, 7273, 6897, 6534, 6186, + 5851, 5531, 5226, 4937, 4663, 4405, 4164, 3939, 3731, 3541, + 3367, 3212, 3074, 2955, 2853, 2770, 2705, 2659, 2631, 2621 +}; + +/** + * Binomial window coefficients scaled by 2^15 + */ +static const int16_t binomial_window[LPC_ORDER] = { + 32749, 32695, 32604, 32477, 32315, 32118, 31887, 31622, 31324, 30995 +}; + +/** + * 0.994^i scaled by 2^15 + */ +static const int16_t bandwidth_expand[LPC_ORDER] = { + 32571, 32376, 32182, 31989, 31797, 31606, 31416, 31228, 31040, 30854 +}; + +/** + * 0.5^i scaled by 2^15 + */ +static const int16_t percept_flt_tbl[2][LPC_ORDER] = { + /* Zero part */ + {29491, 26542, 23888, 21499, 19349, 17414, 15673, 14106, 12695, 11425}, + /* Pole part */ + {16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32} +}; diff --git a/libavcodec/g726.c b/libavcodec/g726.c index 85711f854c..8c02a392cc 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -5,20 +5,20 @@ * This is a very straightforward rendition of the G.726 * Section 4 "Computational Details". * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <limits.h> diff --git a/libavcodec/g729.h b/libavcodec/g729.h new file mode 100644 index 0000000000..61683130a9 --- /dev/null +++ b/libavcodec/g729.h @@ -0,0 +1,29 @@ +/* + * G.729, G729 Annex D decoders + * Copyright (c) 2008 Vladimir Voroshilov + * + * 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 AVCODEC_G729_H +#define AVCODEC_G729_H + +/** + * subframe size + */ +#define SUBFRAME_SIZE 40 + +#endif // AVCODEC_G729_H diff --git a/libavcodec/g729data.h b/libavcodec/g729data.h new file mode 100644 index 0000000000..365ca47ec6 --- /dev/null +++ b/libavcodec/g729data.h @@ -0,0 +1,382 @@ +/* + * data for G.729, G729 Annex D decoders + * Copyright (c) 2007 Vladimir Voroshilov + * + * 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 AVCODEC_G729DATA_H +#define AVCODEC_G729DATA_H + +#include <stdint.h> + +#define MA_NP 4 ///< Moving Average (MA) prediction order + +#define VQ_1ST_BITS 7 ///< first stage vector of quantizer (size in bits) +#define VQ_2ND_BITS 5 ///< second stage vector of quantizer (size in bits) + +#define GC_1ST_IDX_BITS_8K 3 ///< gain codebook (first stage) index, 8k mode (size in bits) +#define GC_2ND_IDX_BITS_8K 4 ///< gain codebook (second stage) index, 8k mode (size in bits) + +#define GC_1ST_IDX_BITS_6K4 3 ///< gain codebook (first stage) index, 6.4k mode (size in bits) +#define GC_2ND_IDX_BITS_6K4 3 ///< gain codebook (second stage) index, 6.4k mode (size in bits) + +/** + * first stage LSP codebook + * (10-dimensional, with 128 entries (3.24 of G.729) + */ +static const int16_t cb_lsp_1st[1<<VQ_1ST_BITS][10] = { /* (2.13) */ + { 1486, 2168, 3751, 9074, 12134, 13944, 17983, 19173, 21190, 21820}, + { 1730, 2640, 3450, 4870, 6126, 7876, 15644, 17817, 20294, 21902}, + { 1568, 2256, 3088, 4874, 11063, 13393, 18307, 19293, 21109, 21741}, + { 1733, 2512, 3357, 4708, 6977, 10296, 17024, 17956, 19145, 20350}, + { 1744, 2436, 3308, 8731, 10432, 12007, 15614, 16639, 21359, 21913}, + { 1786, 2369, 3372, 4521, 6795, 12963, 17674, 18988, 20855, 21640}, + { 1631, 2433, 3361, 6328, 10709, 12013, 13277, 13904, 19441, 21088}, + { 1489, 2364, 3291, 6250, 9227, 10403, 13843, 15278, 17721, 21451}, + { 1869, 2533, 3475, 4365, 9152, 14513, 15908, 17022, 20611, 21411}, + { 2070, 3025, 4333, 5854, 7805, 9231, 10597, 16047, 20109, 21834}, + { 1910, 2673, 3419, 4261, 11168, 15111, 16577, 17591, 19310, 20265}, + { 1141, 1815, 2624, 4623, 6495, 9588, 13968, 16428, 19351, 21286}, + { 2192, 3171, 4707, 5808, 10904, 12500, 14162, 15664, 21124, 21789}, + { 1286, 1907, 2548, 3453, 9574, 11964, 15978, 17344, 19691, 22495}, + { 1921, 2720, 4604, 6684, 11503, 12992, 14350, 15262, 16997, 20791}, + { 2052, 2759, 3897, 5246, 6638, 10267, 15834, 16814, 18149, 21675}, + { 1798, 2497, 5617, 11449, 13189, 14711, 17050, 18195, 20307, 21182}, + { 1009, 1647, 2889, 5709, 9541, 12354, 15231, 18494, 20966, 22033}, + { 3016, 3794, 5406, 7469, 12488, 13984, 15328, 16334, 19952, 20791}, + { 2203, 3040, 3796, 5442, 11987, 13512, 14931, 16370, 17856, 18803}, + { 2912, 4292, 7988, 9572, 11562, 13244, 14556, 16529, 20004, 21073}, + { 2861, 3607, 5923, 7034, 9234, 12054, 13729, 18056, 20262, 20974}, + { 3069, 4311, 5967, 7367, 11482, 12699, 14309, 16233, 18333, 19172}, + { 2434, 3661, 4866, 5798, 10383, 11722, 13049, 15668, 18862, 19831}, + { 2020, 2605, 3860, 9241, 13275, 14644, 16010, 17099, 19268, 20251}, + { 1877, 2809, 3590, 4707, 11056, 12441, 15622, 17168, 18761, 19907}, + { 2107, 2873, 3673, 5799, 13579, 14687, 15938, 17077, 18890, 19831}, + { 1612, 2284, 2944, 3572, 8219, 13959, 15924, 17239, 18592, 20117}, + { 2420, 3156, 6542, 10215, 12061, 13534, 15305, 16452, 18717, 19880}, + { 1667, 2612, 3534, 5237, 10513, 11696, 12940, 16798, 18058, 19378}, + { 2388, 3017, 4839, 9333, 11413, 12730, 15024, 16248, 17449, 18677}, + { 1875, 2786, 4231, 6320, 8694, 10149, 11785, 17013, 18608, 19960}, + { 679, 1411, 4654, 8006, 11446, 13249, 15763, 18127, 20361, 21567}, + { 1838, 2596, 3578, 4608, 5650, 11274, 14355, 15886, 20579, 21754}, + { 1303, 1955, 2395, 3322, 12023, 13764, 15883, 18077, 20180, 21232}, + { 1438, 2102, 2663, 3462, 8328, 10362, 13763, 17248, 19732, 22344}, + { 860, 1904, 6098, 7775, 9815, 12007, 14821, 16709, 19787, 21132}, + { 1673, 2723, 3704, 6125, 7668, 9447, 13683, 14443, 20538, 21731}, + { 1246, 1849, 2902, 4508, 7221, 12710, 14835, 16314, 19335, 22720}, + { 1525, 2260, 3862, 5659, 7342, 11748, 13370, 14442, 18044, 21334}, + { 1196, 1846, 3104, 7063, 10972, 12905, 14814, 17037, 19922, 22636}, + { 2147, 3106, 4475, 6511, 8227, 9765, 10984, 12161, 18971, 21300}, + { 1585, 2405, 2994, 4036, 11481, 13177, 14519, 15431, 19967, 21275}, + { 1778, 2688, 3614, 4680, 9465, 11064, 12473, 16320, 19742, 20800}, + { 1862, 2586, 3492, 6719, 11708, 13012, 14364, 16128, 19610, 20425}, + { 1395, 2156, 2669, 3386, 10607, 12125, 13614, 16705, 18976, 21367}, + { 1444, 2117, 3286, 6233, 9423, 12981, 14998, 15853, 17188, 21857}, + { 2004, 2895, 3783, 4897, 6168, 7297, 12609, 16445, 19297, 21465}, + { 1495, 2863, 6360, 8100, 11399, 14271, 15902, 17711, 20479, 22061}, + { 2484, 3114, 5718, 7097, 8400, 12616, 14073, 14847, 20535, 21396}, + { 2424, 3277, 5296, 6284, 11290, 12903, 16022, 17508, 19333, 20283}, + { 2565, 3778, 5360, 6989, 8782, 10428, 14390, 15742, 17770, 21734}, + { 2727, 3384, 6613, 9254, 10542, 12236, 14651, 15687, 20074, 21102}, + { 1916, 2953, 6274, 8088, 9710, 10925, 12392, 16434, 20010, 21183}, + { 3384, 4366, 5349, 7667, 11180, 12605, 13921, 15324, 19901, 20754}, + { 3075, 4283, 5951, 7619, 9604, 11010, 12384, 14006, 20658, 21497}, + { 1751, 2455, 5147, 9966, 11621, 13176, 14739, 16470, 20788, 21756}, + { 1442, 2188, 3330, 6813, 8929, 12135, 14476, 15306, 19635, 20544}, + { 2294, 2895, 4070, 8035, 12233, 13416, 14762, 17367, 18952, 19688}, + { 1937, 2659, 4602, 6697, 9071, 12863, 14197, 15230, 16047, 18877}, + { 2071, 2663, 4216, 9445, 10887, 12292, 13949, 14909, 19236, 20341}, + { 1740, 2491, 3488, 8138, 9656, 11153, 13206, 14688, 20896, 21907}, + { 2199, 2881, 4675, 8527, 10051, 11408, 14435, 15463, 17190, 20597}, + { 1943, 2988, 4177, 6039, 7478, 8536, 14181, 15551, 17622, 21579}, + { 1825, 3175, 7062, 9818, 12824, 15450, 18330, 19856, 21830, 22412}, + { 2464, 3046, 4822, 5977, 7696, 15398, 16730, 17646, 20588, 21320}, + { 2550, 3393, 5305, 6920, 10235, 14083, 18143, 19195, 20681, 21336}, + { 3003, 3799, 5321, 6437, 7919, 11643, 15810, 16846, 18119, 18980}, + { 3455, 4157, 6838, 8199, 9877, 12314, 15905, 16826, 19949, 20892}, + { 3052, 3769, 4891, 5810, 6977, 10126, 14788, 15990, 19773, 20904}, + { 3671, 4356, 5827, 6997, 8460, 12084, 14154, 14939, 19247, 20423}, + { 2716, 3684, 5246, 6686, 8463, 10001, 12394, 14131, 16150, 19776}, + { 1945, 2638, 4130, 7995, 14338, 15576, 17057, 18206, 20225, 20997}, + { 2304, 2928, 4122, 4824, 5640, 13139, 15825, 16938, 20108, 21054}, + { 1800, 2516, 3350, 5219, 13406, 15948, 17618, 18540, 20531, 21252}, + { 1436, 2224, 2753, 4546, 9657, 11245, 15177, 16317, 17489, 19135}, + { 2319, 2899, 4980, 6936, 8404, 13489, 15554, 16281, 20270, 20911}, + { 2187, 2919, 4610, 5875, 7390, 12556, 14033, 16794, 20998, 21769}, + { 2235, 2923, 5121, 6259, 8099, 13589, 15340, 16340, 17927, 20159}, + { 1765, 2638, 3751, 5730, 7883, 10108, 13633, 15419, 16808, 18574}, + { 3460, 5741, 9596, 11742, 14413, 16080, 18173, 19090, 20845, 21601}, + { 3735, 4426, 6199, 7363, 9250, 14489, 16035, 17026, 19873, 20876}, + { 3521, 4778, 6887, 8680, 12717, 14322, 15950, 18050, 20166, 21145}, + { 2141, 2968, 6865, 8051, 10010, 13159, 14813, 15861, 17528, 18655}, + { 4148, 6128, 9028, 10871, 12686, 14005, 15976, 17208, 19587, 20595}, + { 4403, 5367, 6634, 8371, 10163, 11599, 14963, 16331, 17982, 18768}, + { 4091, 5386, 6852, 8770, 11563, 13290, 15728, 16930, 19056, 20102}, + { 2746, 3625, 5299, 7504, 10262, 11432, 13172, 15490, 16875, 17514}, + { 2248, 3556, 8539, 10590, 12665, 14696, 16515, 17824, 20268, 21247}, + { 1279, 1960, 3920, 7793, 10153, 14753, 16646, 18139, 20679, 21466}, + { 2440, 3475, 6737, 8654, 12190, 14588, 17119, 17925, 19110, 19979}, + { 1879, 2514, 4497, 7572, 10017, 14948, 16141, 16897, 18397, 19376}, + { 2804, 3688, 7490, 10086, 11218, 12711, 16307, 17470, 20077, 21126}, + { 2023, 2682, 3873, 8268, 10255, 11645, 15187, 17102, 18965, 19788}, + { 2823, 3605, 5815, 8595, 10085, 11469, 16568, 17462, 18754, 19876}, + { 2851, 3681, 5280, 7648, 9173, 10338, 14961, 16148, 17559, 18474}, + { 1348, 2645, 5826, 8785, 10620, 12831, 16255, 18319, 21133, 22586}, + { 2141, 3036, 4293, 6082, 7593, 10629, 17158, 18033, 21466, 22084}, + { 1608, 2375, 3384, 6878, 9970, 11227, 16928, 17650, 20185, 21120}, + { 2774, 3616, 5014, 6557, 7788, 8959, 17068, 18302, 19537, 20542}, + { 1934, 4813, 6204, 7212, 8979, 11665, 15989, 17811, 20426, 21703}, + { 2288, 3507, 5037, 6841, 8278, 9638, 15066, 16481, 21653, 22214}, + { 2951, 3771, 4878, 7578, 9016, 10298, 14490, 15242, 20223, 20990}, + { 3256, 4791, 6601, 7521, 8644, 9707, 13398, 16078, 19102, 20249}, + { 1827, 2614, 3486, 6039, 12149, 13823, 16191, 17282, 21423, 22041}, + { 1000, 1704, 3002, 6335, 8471, 10500, 14878, 16979, 20026, 22427}, + { 1646, 2286, 3109, 7245, 11493, 12791, 16824, 17667, 18981, 20222}, + { 1708, 2501, 3315, 6737, 8729, 9924, 16089, 17097, 18374, 19917}, + { 2623, 3510, 4478, 5645, 9862, 11115, 15219, 18067, 19583, 20382}, + { 2518, 3434, 4728, 6388, 8082, 9285, 13162, 18383, 19819, 20552}, + { 1726, 2383, 4090, 6303, 7805, 12845, 14612, 17608, 19269, 20181}, + { 2860, 3735, 4838, 6044, 7254, 8402, 14031, 16381, 18037, 19410}, + { 4247, 5993, 7952, 9792, 12342, 14653, 17527, 18774, 20831, 21699}, + { 3502, 4051, 5680, 6805, 8146, 11945, 16649, 17444, 20390, 21564}, + { 3151, 4893, 5899, 7198, 11418, 13073, 15124, 17673, 20520, 21861}, + { 3960, 4848, 5926, 7259, 8811, 10529, 15661, 16560, 18196, 20183}, + { 4499, 6604, 8036, 9251, 10804, 12627, 15880, 17512, 20020, 21046}, + { 4251, 5541, 6654, 8318, 9900, 11686, 15100, 17093, 20572, 21687}, + { 3769, 5327, 7865, 9360, 10684, 11818, 13660, 15366, 18733, 19882}, + { 3083, 3969, 6248, 8121, 9798, 10994, 12393, 13686, 17888, 19105}, + { 2731, 4670, 7063, 9201, 11346, 13735, 16875, 18797, 20787, 22360}, + { 1187, 2227, 4737, 7214, 9622, 12633, 15404, 17968, 20262, 23533}, + { 1911, 2477, 3915, 10098, 11616, 12955, 16223, 17138, 19270, 20729}, + { 1764, 2519, 3887, 6944, 9150, 12590, 16258, 16984, 17924, 18435}, + { 1400, 3674, 7131, 8718, 10688, 12508, 15708, 17711, 19720, 21068}, + { 2322, 3073, 4287, 8108, 9407, 10628, 15862, 16693, 19714, 21474}, + { 2630, 3339, 4758, 8360, 10274, 11333, 12880, 17374, 19221, 19936}, + { 1721, 2577, 5553, 7195, 8651, 10686, 15069, 16953, 18703, 19929} +}; + +/** + * second stage LSP codebook, high and low parts + (both 5-dimensional, with 32 entries (3.2.4 of G.729) + */ +static const int16_t cb_lsp_2nd[1<<VQ_2ND_BITS][10] = { /* (2.13) */ + { -435, -815, -742, 1033, -518, 582, -1201, 829, 86, 385}, + { -833, -891, 463, -8, -1251, 1450, 72, -231, 864, 661}, + {-1021, 231, -306, 321, -220, -163, -526, -754, -1633, 267}, + { 57, -198, -339, -33, -1468, 573, 796, -169, -631, 816}, + { 171, -350, 294, 1660, 453, 519, 291, 159, -640, -1296}, + { -701, -842, -58, 950, 892, 1549, 715, 527, -714, -193}, + { 584, 31, -289, 356, -333, -457, 612, -283, -1381, -741}, + { -109, -808, 231, 77, -87, -344, 1341, 1087, -654, -569}, + { -859, 1236, 550, 854, 714, -543, -1752, -195, -98, -276}, + { -877, -954, -1248, -299, 212, -235, -728, 949, 1517, 895}, + { -77, 344, -620, 763, 413, 502, -362, -960, -483, 1386}, + { -314, -307, -256, -1260, -429, 450, -466, -108, 1010, 2223}, + { 711, 693, 521, 650, 1305, -28, -378, 744, -1005, 240}, + { -112, -271, -500, 946, 1733, 271, -15, 909, -259, 1688}, + { 575, -10, -468, -199, 1101, -1011, 581, -53, -747, 878}, + { 145, -285, -1280, -398, 36, -498, -1377, 18, -444, 1483}, + {-1133, -835, 1350, 1284, -95, 1015, -222, 443, 372, -354}, + {-1459, -1237, 416, -213, 466, 669, 659, 1640, 932, 534}, + { -15, 66, 468, 1019, -748, 1385, -182, -907, -721, -262}, + { -338, 148, 1445, 75, -760, 569, 1247, 337, 416, -121}, + { 389, 239, 1568, 981, 113, 369, -1003, -507, -587, -904}, + { -312, -98, 949, 31, 1104, 72, -141, 1465, 63, -785}, + { 1127, 584, 835, 277, -1159, 208, 301, -882, 117, -404}, + { 539, -114, 856, -493, 223, -912, 623, -76, 276, -440}, + { 2197, 2337, 1268, 670, 304, -267, -525, 140, 882, -139}, + {-1596, 550, 801, -456, -56, -697, 865, 1060, 413, 446}, + { 1154, 593, -77, 1237, -31, 581, -1037, -895, 669, 297}, + { 397, 558, 203, -797, -919, 3, 692, -292, 1050, 782}, + { 334, 1475, 632, -80, 48, -1061, -484, 362, -597, -852}, + { -545, -330, -429, -680, 1133, -1182, -744, 1340, 262, 63}, + { 1320, 827, -398, -576, 341, -774, -483, -1247, -70, 98}, + { -163, 674, -11, -886, 531, -1125, -265, -242, 724, 934} +}; + +/** + * gain codebook (first stage), 8k mode (3.9.2 of G.729) + */ +static const int16_t cb_gain_1st_8k[1<<GC_1ST_IDX_BITS_8K][2] = { /*(0.14) (2.13) */ + { 3242 , 9949 }, + { 1551 , 2425 }, + { 2678 , 27162 }, + { 1921 , 9291 }, + { 1831 , 5022 }, + { 1 , 1516 }, + { 356 , 14756 }, + { 57 , 5404 }, +}; + +/** + * gain codebook (second stage), 8k mode (3.9.2 of G.729) + */ +static const int16_t cb_gain_2nd_8k[1<<GC_2ND_IDX_BITS_8K][2] = { /*(1.14) (1.13) */ + { 5142 , 592 }, + { 17299 , 1861 }, + { 6160 , 2395 }, + { 16112 , 3392 }, + { 826 , 2005 }, + { 18973 , 5935 }, + { 1994 , 0 }, + { 15434 , 237 }, + { 10573 , 2966 }, + { 15132 , 4914 }, + { 11569 , 1196 }, + { 14194 , 1630 }, + { 8091 , 4861 }, + { 15161 , 14276 }, + { 9120 , 525 }, + { 13260 , 3256 }, +}; + +/** + * gain codebook (first stage), 6.4k mode (D.3.9.2 of G.729) + */ +static const int16_t cb_gain_1st_6k4[1<<GC_1ST_IDX_BITS_6K4][2] = +{ /*(0.14) (1.14)*/ + { 5849, 0 }, + { 3171, 9280 }, + { 3617, 6747 }, + { 4987, 22294 }, + { 2929, 1078 }, + { 6068, 6093 }, + { 9425, 2731 }, + { 3915, 12872 }, +}; + +/** + * gain codebook (second stage), 6.4k mode (D.3.9.2 of G.729) + */ +static const int16_t cb_gain_2nd_6k4[1<<GC_2ND_IDX_BITS_6K4][2] = +{ /*(1.14) (1.14)*/ + { 0, 4175 }, + {10828, 27602 }, + {16423, 15724 }, + { 4478, 7324 }, + { 3988, 0 }, + {10291, 11385 }, + {11956, 10735 }, + { 7876, 7821 }, +}; + +/** + * 4th order Moving Average (MA) Predictor codebook (3.2.4 of G.729) + * + * float cb_ma_predictor_float[2][MA_NP][10] = { + * { + * {0.2570, 0.2780, 0.2800, 0.2736, 0.2757, 0.2764, 0.2675, 0.2678, 0.2779, 0.2647}, + * {0.2142, 0.2194, 0.2331, 0.2230, 0.2272, 0.2252, 0.2148, 0.2123, 0.2115, 0.2096}, + * {0.1670, 0.1523, 0.1567, 0.1580, 0.1601, 0.1569, 0.1589, 0.1555, 0.1474, 0.1571}, + * {0.1238, 0.0925, 0.0798, 0.0923, 0.0890, 0.0828, 0.1010, 0.0988, 0.0872, 0.1060}, + * }, + * { + * {0.2360, 0.2405, 0.2499, 0.2495, 0.2517, 0.2591, 0.2636, 0.2625, 0.2551, 0.2310}, + * {0.1285, 0.0925, 0.0779, 0.1060, 0.1183, 0.1176, 0.1277, 0.1268, 0.1193, 0.1211}, + * {0.0981, 0.0589, 0.0401, 0.0654, 0.0761, 0.0728, 0.0841, 0.0826, 0.0776, 0.0891}, + * {0.0923, 0.0486, 0.0287, 0.0498, 0.0526, 0.0482, 0.0621, 0.0636, 0.0584, 0.0794}, + * }, + * }; + * 15 + * cb_ma_predictor[j][k][i] = floor( 2 * cb_ma_predictor_float[j][k][i] ) + * + * j=0..1, i=0..9, k=0..MA_NP-1 + */ +static const int16_t cb_ma_predictor[2][MA_NP][10] = { /* (0.15) */ + { + { 8421, 9109, 9175, 8965, 9034, 9057, 8765, 8775, 9106, 8673}, + { 7018, 7189, 7638, 7307, 7444, 7379, 7038, 6956, 6930, 6868}, + { 5472, 4990, 5134, 5177, 5246, 5141, 5206, 5095, 4830, 5147}, + { 4056, 3031, 2614, 3024, 2916, 2713, 3309, 3237, 2857, 3473} + }, + { + { 7733, 7880, 8188, 8175, 8247, 8490, 8637, 8601, 8359, 7569}, + { 4210, 3031, 2552, 3473, 3876, 3853, 4184, 4154, 3909, 3968}, + { 3214, 1930, 1313, 2143, 2493, 2385, 2755, 2706, 2542, 2919}, + { 3024, 1592, 940, 1631, 1723, 1579, 2034, 2084, 1913, 2601} + } +}; + +/** + * 15 3 + * cb_ma_predictor_sum[j][i] = floor( 2 * (1.0 - sum ( cb_ma_predictor_float[j][k][i] ) ) ) + * k=0 + * j=0..1, i=0..9 + */ +static const int16_t cb_ma_predictor_sum[2][10] = { /* (0.15) */ + { 7798, 8447, 8205, 8293, 8126, 8477, 8447, 8703, 9043, 8604}, + {14585, 18333, 19772, 17344, 16426, 16459, 15155, 15220, 16043, 15708} +}; + +/** + * 12 + * 2 + * cb_ma_predictor_sum_inv[j][i] = floor(---------------------------------------------) + * 3 + * 1.0 - sum ( cb_ma_predictor_float[j][k][i] ) + * k=0 + * j=0..1, i=0..9 + */ +static const int16_t cb_ma_predictor_sum_inv[2][10] = { /* (3.12) */ + {17210, 15888, 16357, 16183, 16516, 15833, 15888, 15421, 14840, 15597}, + { 9202, 7320, 6788, 7738, 8170, 8154, 8856, 8818, 8366, 8544} +}; + +/** + * MA prediction coefficients (3.9.1 of G.729, near Equation 69) + */ +static const uint16_t ma_prediction_coeff[4] = { /* (0.13) */ + 5571, 4751, 2785, 1556 +}; + +/** + * initial LSP coefficients belongs to virtual frame preceding the + * first frame of the stream + */ +static const int16_t lsp_init[10]= { /* (0.15) */ + 30000, 26000, 21000, 15000, 8000, 0, -8000,-15000,-21000,-26000 +}; + +/** + * additional "phase" post-processing filter impulse response (D.6.2 of G.729) + * + * Table contains three impulse responses, correspond to + * different amounts of spreading. + */ +static const int16_t phase_filter[3][40] = +{ + { // maximum spreading (for noise-like segments) + 14690, 11518, 1268, -2762, -5672, 7514, -36, -2808, -3041, 4823, + 2952, -8425, 3785, 1455, 2179, -8638, 8051, -2104, -1455, 777, + 1108, -2386, 2254, -364, -675, -2104, 6046, -5682, 1072, 3123, + -5059, 5312, -2330, -3729, 6924, -3890, 675, -1776, 29, 10145, + }, + { // medium spreading + 30274, 3831, -4037, 2972, -1049, -1003, 2477, -3044, 2815, -2232, + 1753, -1612, 1714, -1776, 1543, -1009, 429, -170, 472, -1265, + 2176, -2707, 2523, -1622, 344, 826, -1530, 1724, -1658, 1701, + -2064, 2644, -3061, 2897, -1979, 557, 780, -1370, 842, 655, + }, + { // no spreading (for voiced speech) + 32767, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + } +}; +#endif /* AVCODEC_G729DATA_H */ diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c new file mode 100644 index 0000000000..191794b6e7 --- /dev/null +++ b/libavcodec/g729dec.c @@ -0,0 +1,725 @@ +/* + * G.729, G729 Annex D decoders + * Copyright (c) 2008 Vladimir Voroshilov + * + * 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 <string.h> + +#include "avcodec.h" +#include "libavutil/avutil.h" +#include "get_bits.h" +#include "dsputil.h" + +#include "g729.h" +#include "lsp.h" +#include "celp_math.h" +#include "celp_filters.h" +#include "acelp_filters.h" +#include "acelp_pitch_delay.h" +#include "acelp_vectors.h" +#include "g729data.h" +#include "g729postfilter.h" + +/** + * minimum quantized LSF value (3.2.4) + * 0.005 in Q13 + */ +#define LSFQ_MIN 40 + +/** + * maximum quantized LSF value (3.2.4) + * 3.135 in Q13 + */ +#define LSFQ_MAX 25681 + +/** + * minimum LSF distance (3.2.4) + * 0.0391 in Q13 + */ +#define LSFQ_DIFF_MIN 321 + +/// interpolation filter length +#define INTERPOL_LEN 11 + +/** + * minimum gain pitch value (3.8, Equation 47) + * 0.2 in (1.14) + */ +#define SHARP_MIN 3277 + +/** + * maximum gain pitch value (3.8, Equation 47) + * (EE) This does not comply with the specification. + * Specification says about 0.8, which should be + * 13107 in (1.14), but reference C code uses + * 13017 (equals to 0.7945) instead of it. + */ +#define SHARP_MAX 13017 + +/** + * MR_ENERGY (mean removed energy) = mean_energy + 10 * log10(2^26 * subframe_size) in (7.13) + */ +#define MR_ENERGY 1018156 + +#define DECISION_NOISE 0 +#define DECISION_INTERMEDIATE 1 +#define DECISION_VOICE 2 + +typedef enum { + FORMAT_G729_8K = 0, + FORMAT_G729D_6K4, + FORMAT_COUNT, +} G729Formats; + +typedef struct { + uint8_t ac_index_bits[2]; ///< adaptive codebook index for second subframe (size in bits) + uint8_t parity_bit; ///< parity bit for pitch delay + uint8_t gc_1st_index_bits; ///< gain codebook (first stage) index (size in bits) + uint8_t gc_2nd_index_bits; ///< gain codebook (second stage) index (size in bits) + uint8_t fc_signs_bits; ///< number of pulses in fixed-codebook vector + uint8_t fc_indexes_bits; ///< size (in bits) of fixed-codebook index entry +} G729FormatDescription; + +typedef struct { + DSPContext dsp; + AVFrame frame; + + /// past excitation signal buffer + int16_t exc_base[2*SUBFRAME_SIZE+PITCH_DELAY_MAX+INTERPOL_LEN]; + + int16_t* exc; ///< start of past excitation data in buffer + int pitch_delay_int_prev; ///< integer part of previous subframe's pitch delay (4.1.3) + + /// (2.13) LSP quantizer outputs + int16_t past_quantizer_output_buf[MA_NP + 1][10]; + int16_t* past_quantizer_outputs[MA_NP + 1]; + + int16_t lsfq[10]; ///< (2.13) quantized LSF coefficients from previous frame + int16_t lsp_buf[2][10]; ///< (0.15) LSP coefficients (previous and current frames) (3.2.5) + int16_t *lsp[2]; ///< pointers to lsp_buf + + int16_t quant_energy[4]; ///< (5.10) past quantized energy + + /// previous speech data for LP synthesis filter + int16_t syn_filter_data[10]; + + + /// residual signal buffer (used in long-term postfilter) + int16_t residual[SUBFRAME_SIZE + RES_PREV_DATA_SIZE]; + + /// previous speech data for residual calculation filter + int16_t res_filter_data[SUBFRAME_SIZE+10]; + + /// previous speech data for short-term postfilter + int16_t pos_filter_data[SUBFRAME_SIZE+10]; + + /// (1.14) pitch gain of current and five previous subframes + int16_t past_gain_pitch[6]; + + /// (14.1) gain code from current and previous subframe + int16_t past_gain_code[2]; + + /// voice decision on previous subframe (0-noise, 1-intermediate, 2-voice), G.729D + int16_t voice_decision; + + int16_t onset; ///< detected onset level (0-2) + int16_t was_periodic; ///< whether previous frame was declared as periodic or not (4.4) + int16_t ht_prev_data; ///< previous data for 4.2.3, equation 86 + int gain_coeff; ///< (1.14) gain coefficient (4.2.4) + uint16_t rand_value; ///< random number generator value (4.4.4) + int ma_predictor_prev; ///< switched MA predictor of LSP quantizer from last good frame + + /// (14.14) high-pass filter data (past input) + int hpf_f[2]; + + /// high-pass filter data (past output) + int16_t hpf_z[2]; +} G729Context; + +static const G729FormatDescription format_g729_8k = { + .ac_index_bits = {8,5}, + .parity_bit = 1, + .gc_1st_index_bits = GC_1ST_IDX_BITS_8K, + .gc_2nd_index_bits = GC_2ND_IDX_BITS_8K, + .fc_signs_bits = 4, + .fc_indexes_bits = 13, +}; + +static const G729FormatDescription format_g729d_6k4 = { + .ac_index_bits = {8,4}, + .parity_bit = 0, + .gc_1st_index_bits = GC_1ST_IDX_BITS_6K4, + .gc_2nd_index_bits = GC_2ND_IDX_BITS_6K4, + .fc_signs_bits = 2, + .fc_indexes_bits = 9, +}; + +/** + * @brief pseudo random number generator + */ +static inline uint16_t g729_prng(uint16_t value) +{ + return 31821 * value + 13849; +} + +/** + * Get parity bit of bit 2..7 + */ +static inline int get_parity(uint8_t value) +{ + return (0x6996966996696996ULL >> (value >> 2)) & 1; +} + +/* + * Decodes LSF (Line Spectral Frequencies) from L0-L3 (3.2.4). + * @param lsfq [out] (2.13) quantized LSF coefficients + * @param past_quantizer_outputs [in/out] (2.13) quantizer outputs from previous frames + * @param ma_predictor switched MA predictor of LSP quantizer + * @param vq_1st first stage vector of quantizer + * @param vq_2nd_low second stage lower vector of LSP quantizer + * @param vq_2nd_high second stage higher vector of LSP quantizer + */ +static void lsf_decode(int16_t* lsfq, int16_t* past_quantizer_outputs[MA_NP + 1], + int16_t ma_predictor, + int16_t vq_1st, int16_t vq_2nd_low, int16_t vq_2nd_high) +{ + int i,j; + static const uint8_t min_distance[2]={10, 5}; //(2.13) + int16_t* quantizer_output = past_quantizer_outputs[MA_NP]; + + for (i = 0; i < 5; i++) { + quantizer_output[i] = cb_lsp_1st[vq_1st][i ] + cb_lsp_2nd[vq_2nd_low ][i ]; + quantizer_output[i + 5] = cb_lsp_1st[vq_1st][i + 5] + cb_lsp_2nd[vq_2nd_high][i + 5]; + } + + for (j = 0; j < 2; j++) { + for (i = 1; i < 10; i++) { + int diff = (quantizer_output[i - 1] - quantizer_output[i] + min_distance[j]) >> 1; + if (diff > 0) { + quantizer_output[i - 1] -= diff; + quantizer_output[i ] += diff; + } + } + } + + for (i = 0; i < 10; i++) { + int sum = quantizer_output[i] * cb_ma_predictor_sum[ma_predictor][i]; + for (j = 0; j < MA_NP; j++) + sum += past_quantizer_outputs[j][i] * cb_ma_predictor[ma_predictor][j][i]; + + lsfq[i] = sum >> 15; + } + + ff_acelp_reorder_lsf(lsfq, LSFQ_DIFF_MIN, LSFQ_MIN, LSFQ_MAX, 10); +} + +/** + * Restores past LSP quantizer output using LSF from previous frame + * @param lsfq [in/out] (2.13) quantized LSF coefficients + * @param past_quantizer_outputs [in/out] (2.13) quantizer outputs from previous frames + * @param ma_predictor_prev MA predictor from previous frame + * @param lsfq_prev (2.13) quantized LSF coefficients from previous frame + */ +static void lsf_restore_from_previous(int16_t* lsfq, + int16_t* past_quantizer_outputs[MA_NP + 1], + int ma_predictor_prev) +{ + int16_t* quantizer_output = past_quantizer_outputs[MA_NP]; + int i,k; + + for (i = 0; i < 10; i++) { + int tmp = lsfq[i] << 15; + + for (k = 0; k < MA_NP; k++) + tmp -= past_quantizer_outputs[k][i] * cb_ma_predictor[ma_predictor_prev][k][i]; + + quantizer_output[i] = ((tmp >> 15) * cb_ma_predictor_sum_inv[ma_predictor_prev][i]) >> 12; + } +} + +/** + * Constructs new excitation signal and applies phase filter to it + * @param out[out] constructed speech signal + * @param in original excitation signal + * @param fc_cur (2.13) original fixed-codebook vector + * @param gain_code (14.1) gain code + * @param subframe_size length of the subframe + */ +static void g729d_get_new_exc( + int16_t* out, + const int16_t* in, + const int16_t* fc_cur, + int dstate, + int gain_code, + int subframe_size) +{ + int i; + int16_t fc_new[SUBFRAME_SIZE]; + + ff_celp_convolve_circ(fc_new, fc_cur, phase_filter[dstate], subframe_size); + + for(i=0; i<subframe_size; i++) + { + out[i] = in[i]; + out[i] -= (gain_code * fc_cur[i] + 0x2000) >> 14; + out[i] += (gain_code * fc_new[i] + 0x2000) >> 14; + } +} + +/** + * Makes decision about onset in current subframe + * @param past_onset decision result of previous subframe + * @param past_gain_code gain code of current and previous subframe + * + * @return onset decision result for current subframe + */ +static int g729d_onset_decision(int past_onset, const int16_t* past_gain_code) +{ + if((past_gain_code[0] >> 1) > past_gain_code[1]) + return 2; + else + return FFMAX(past_onset-1, 0); +} + +/** + * Makes decision about voice presence in current subframe + * @param onset onset level + * @param prev_voice_decision voice decision result from previous subframe + * @param past_gain_pitch pitch gain of current and previous subframes + * + * @return voice decision result for current subframe + */ +static int16_t g729d_voice_decision(int onset, int prev_voice_decision, const int16_t* past_gain_pitch) +{ + int i, low_gain_pitch_cnt, voice_decision; + + if(past_gain_pitch[0] >= 14745) // 0.9 + voice_decision = DECISION_VOICE; + else if (past_gain_pitch[0] <= 9830) // 0.6 + voice_decision = DECISION_NOISE; + else + voice_decision = DECISION_INTERMEDIATE; + + for(i=0, low_gain_pitch_cnt=0; i<6; i++) + if(past_gain_pitch[i] < 9830) + low_gain_pitch_cnt++; + + if(low_gain_pitch_cnt > 2 && !onset) + voice_decision = DECISION_NOISE; + + if(!onset && voice_decision > prev_voice_decision + 1) + voice_decision--; + + if(onset && voice_decision < DECISION_VOICE) + voice_decision++; + + return voice_decision; +} + +static int32_t scalarproduct_int16_c(const int16_t * v1, const int16_t * v2, int order, int shift) +{ + int res = 0; + + while (order--) + res += (*v1++ * *v2++) >> shift; + + return res; +} + +static av_cold int decoder_init(AVCodecContext * avctx) +{ + G729Context* ctx = avctx->priv_data; + int i,k; + + if (avctx->channels != 1) { + av_log(avctx, AV_LOG_ERROR, "Only mono sound is supported (requested channels: %d).\n", avctx->channels); + return AVERROR(EINVAL); + } + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + /* Both 8kbit/s and 6.4kbit/s modes uses two subframes per frame. */ + avctx->frame_size = SUBFRAME_SIZE << 1; + + ctx->gain_coeff = 16384; // 1.0 in (1.14) + + for (k = 0; k < MA_NP + 1; k++) { + ctx->past_quantizer_outputs[k] = ctx->past_quantizer_output_buf[k]; + for (i = 1; i < 11; i++) + ctx->past_quantizer_outputs[k][i - 1] = (18717 * i) >> 3; + } + + ctx->lsp[0] = ctx->lsp_buf[0]; + ctx->lsp[1] = ctx->lsp_buf[1]; + memcpy(ctx->lsp[0], lsp_init, 10 * sizeof(int16_t)); + + ctx->exc = &ctx->exc_base[PITCH_DELAY_MAX+INTERPOL_LEN]; + + /* random seed initialization */ + ctx->rand_value = 21845; + + /* quantized prediction error */ + for(i=0; i<4; i++) + ctx->quant_energy[i] = -14336; // -14 in (5.10) + + dsputil_init(&ctx->dsp, avctx); + ctx->dsp.scalarproduct_int16 = scalarproduct_int16_c; + + avcodec_get_frame_defaults(&ctx->frame); + avctx->coded_frame = &ctx->frame; + + return 0; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, + AVPacket *avpkt) +{ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int16_t *out_frame; + GetBitContext gb; + const G729FormatDescription *format; + int frame_erasure = 0; ///< frame erasure detected during decoding + int bad_pitch = 0; ///< parity check failed + int i; + int16_t *tmp; + G729Formats packet_type; + G729Context *ctx = avctx->priv_data; + int16_t lp[2][11]; // (3.12) + uint8_t ma_predictor; ///< switched MA predictor of LSP quantizer + uint8_t quantizer_1st; ///< first stage vector of quantizer + uint8_t quantizer_2nd_lo; ///< second stage lower vector of quantizer (size in bits) + uint8_t quantizer_2nd_hi; ///< second stage higher vector of quantizer (size in bits) + + int pitch_delay_int[2]; // pitch delay, integer part + int pitch_delay_3x; // pitch delay, multiplied by 3 + int16_t fc[SUBFRAME_SIZE]; // fixed-codebook vector + int16_t synth[SUBFRAME_SIZE+10]; // fixed-codebook vector + int j, ret; + int gain_before, gain_after; + int is_periodic = 0; // whether one of the subframes is declared as periodic or not + + ctx->frame.nb_samples = SUBFRAME_SIZE<<1; + if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + out_frame= ctx->frame.data[0]; + + if (buf_size == 10) { + packet_type = FORMAT_G729_8K; + format = &format_g729_8k; + //Reset voice decision + ctx->onset = 0; + ctx->voice_decision = DECISION_VOICE; + av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729 @ 8kbit/s"); + } else if (buf_size == 8) { + packet_type = FORMAT_G729D_6K4; + format = &format_g729d_6k4; + av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729D @ 6.4kbit/s"); + } else { + av_log(avctx, AV_LOG_ERROR, "Packet size %d is unknown.\n", buf_size); + return AVERROR_INVALIDDATA; + } + + for (i=0; i < buf_size; i++) + frame_erasure |= buf[i]; + frame_erasure = !frame_erasure; + + init_get_bits(&gb, buf, 8*buf_size); + + ma_predictor = get_bits(&gb, 1); + quantizer_1st = get_bits(&gb, VQ_1ST_BITS); + quantizer_2nd_lo = get_bits(&gb, VQ_2ND_BITS); + quantizer_2nd_hi = get_bits(&gb, VQ_2ND_BITS); + + if(frame_erasure) + lsf_restore_from_previous(ctx->lsfq, ctx->past_quantizer_outputs, + ctx->ma_predictor_prev); + else { + lsf_decode(ctx->lsfq, ctx->past_quantizer_outputs, + ma_predictor, + quantizer_1st, quantizer_2nd_lo, quantizer_2nd_hi); + ctx->ma_predictor_prev = ma_predictor; + } + + tmp = ctx->past_quantizer_outputs[MA_NP]; + memmove(ctx->past_quantizer_outputs + 1, ctx->past_quantizer_outputs, + MA_NP * sizeof(int16_t*)); + ctx->past_quantizer_outputs[0] = tmp; + + ff_acelp_lsf2lsp(ctx->lsp[1], ctx->lsfq, 10); + + ff_acelp_lp_decode(&lp[0][0], &lp[1][0], ctx->lsp[1], ctx->lsp[0], 10); + + FFSWAP(int16_t*, ctx->lsp[1], ctx->lsp[0]); + + for (i = 0; i < 2; i++) { + int gain_corr_factor; + + uint8_t ac_index; ///< adaptive codebook index + uint8_t pulses_signs; ///< fixed-codebook vector pulse signs + int fc_indexes; ///< fixed-codebook indexes + uint8_t gc_1st_index; ///< gain codebook (first stage) index + uint8_t gc_2nd_index; ///< gain codebook (second stage) index + + ac_index = get_bits(&gb, format->ac_index_bits[i]); + if(!i && format->parity_bit) + bad_pitch = get_parity(ac_index) == get_bits1(&gb); + fc_indexes = get_bits(&gb, format->fc_indexes_bits); + pulses_signs = get_bits(&gb, format->fc_signs_bits); + gc_1st_index = get_bits(&gb, format->gc_1st_index_bits); + gc_2nd_index = get_bits(&gb, format->gc_2nd_index_bits); + + if (frame_erasure) + pitch_delay_3x = 3 * ctx->pitch_delay_int_prev; + else if(!i) { + if (bad_pitch) + pitch_delay_3x = 3 * ctx->pitch_delay_int_prev; + else + pitch_delay_3x = ff_acelp_decode_8bit_to_1st_delay3(ac_index); + } else { + int pitch_delay_min = av_clip(ctx->pitch_delay_int_prev - 5, + PITCH_DELAY_MIN, PITCH_DELAY_MAX - 9); + + if(packet_type == FORMAT_G729D_6K4) + pitch_delay_3x = ff_acelp_decode_4bit_to_2nd_delay3(ac_index, pitch_delay_min); + else + pitch_delay_3x = ff_acelp_decode_5_6_bit_to_2nd_delay3(ac_index, pitch_delay_min); + } + + /* Round pitch delay to nearest (used everywhere except ff_acelp_interpolate). */ + pitch_delay_int[i] = (pitch_delay_3x + 1) / 3; + + if (frame_erasure) { + ctx->rand_value = g729_prng(ctx->rand_value); + fc_indexes = ctx->rand_value & ((1 << format->fc_indexes_bits) - 1); + + ctx->rand_value = g729_prng(ctx->rand_value); + pulses_signs = ctx->rand_value; + } + + + memset(fc, 0, sizeof(int16_t) * SUBFRAME_SIZE); + switch (packet_type) { + case FORMAT_G729_8K: + ff_acelp_fc_pulse_per_track(fc, ff_fc_4pulses_8bits_tracks_13, + ff_fc_4pulses_8bits_track_4, + fc_indexes, pulses_signs, 3, 3); + break; + case FORMAT_G729D_6K4: + ff_acelp_fc_pulse_per_track(fc, ff_fc_2pulses_9bits_track1_gray, + ff_fc_2pulses_9bits_track2_gray, + fc_indexes, pulses_signs, 1, 4); + break; + } + + /* + This filter enhances harmonic components of the fixed-codebook vector to + improve the quality of the reconstructed speech. + + / fc_v[i], i < pitch_delay + fc_v[i] = < + \ fc_v[i] + gain_pitch * fc_v[i-pitch_delay], i >= pitch_delay + */ + ff_acelp_weighted_vector_sum(fc + pitch_delay_int[i], + fc + pitch_delay_int[i], + fc, 1 << 14, + av_clip(ctx->past_gain_pitch[0], SHARP_MIN, SHARP_MAX), + 0, 14, + SUBFRAME_SIZE - pitch_delay_int[i]); + + memmove(ctx->past_gain_pitch+1, ctx->past_gain_pitch, 5 * sizeof(int16_t)); + ctx->past_gain_code[1] = ctx->past_gain_code[0]; + + if (frame_erasure) { + ctx->past_gain_pitch[0] = (29491 * ctx->past_gain_pitch[0]) >> 15; // 0.90 (0.15) + ctx->past_gain_code[0] = ( 2007 * ctx->past_gain_code[0] ) >> 11; // 0.98 (0.11) + + gain_corr_factor = 0; + } else { + if (packet_type == FORMAT_G729D_6K4) { + ctx->past_gain_pitch[0] = cb_gain_1st_6k4[gc_1st_index][0] + + cb_gain_2nd_6k4[gc_2nd_index][0]; + gain_corr_factor = cb_gain_1st_6k4[gc_1st_index][1] + + cb_gain_2nd_6k4[gc_2nd_index][1]; + + /* Without check below overflow can occure in ff_acelp_update_past_gain. + It is not issue for G.729, because gain_corr_factor in it's case is always + greater than 1024, while in G.729D it can be even zero. */ + gain_corr_factor = FFMAX(gain_corr_factor, 1024); +#ifndef G729_BITEXACT + gain_corr_factor >>= 1; +#endif + } else { + ctx->past_gain_pitch[0] = cb_gain_1st_8k[gc_1st_index][0] + + cb_gain_2nd_8k[gc_2nd_index][0]; + gain_corr_factor = cb_gain_1st_8k[gc_1st_index][1] + + cb_gain_2nd_8k[gc_2nd_index][1]; + } + + /* Decode the fixed-codebook gain. */ + ctx->past_gain_code[0] = ff_acelp_decode_gain_code(&ctx->dsp, gain_corr_factor, + fc, MR_ENERGY, + ctx->quant_energy, + ma_prediction_coeff, + SUBFRAME_SIZE, 4); +#ifdef G729_BITEXACT + /* + This correction required to get bit-exact result with + reference code, because gain_corr_factor in G.729D is + two times larger than in original G.729. + + If bit-exact result is not issue then gain_corr_factor + can be simpler devided by 2 before call to g729_get_gain_code + instead of using correction below. + */ + if (packet_type == FORMAT_G729D_6K4) { + gain_corr_factor >>= 1; + ctx->past_gain_code[0] >>= 1; + } +#endif + } + ff_acelp_update_past_gain(ctx->quant_energy, gain_corr_factor, 2, frame_erasure); + + /* Routine requires rounding to lowest. */ + ff_acelp_interpolate(ctx->exc + i * SUBFRAME_SIZE, + ctx->exc + i * SUBFRAME_SIZE - pitch_delay_3x / 3, + ff_acelp_interp_filter, 6, + (pitch_delay_3x % 3) << 1, + 10, SUBFRAME_SIZE); + + ff_acelp_weighted_vector_sum(ctx->exc + i * SUBFRAME_SIZE, + ctx->exc + i * SUBFRAME_SIZE, fc, + (!ctx->was_periodic && frame_erasure) ? 0 : ctx->past_gain_pitch[0], + ( ctx->was_periodic && frame_erasure) ? 0 : ctx->past_gain_code[0], + 1 << 13, 14, SUBFRAME_SIZE); + + memcpy(synth, ctx->syn_filter_data, 10 * sizeof(int16_t)); + + if (ff_celp_lp_synthesis_filter( + synth+10, + &lp[i][1], + ctx->exc + i * SUBFRAME_SIZE, + SUBFRAME_SIZE, + 10, + 1, + 0, + 0x800)) + /* Overflow occured, downscale excitation signal... */ + for (j = 0; j < 2 * SUBFRAME_SIZE + PITCH_DELAY_MAX + INTERPOL_LEN; j++) + ctx->exc_base[j] >>= 2; + + /* ... and make synthesis again. */ + if (packet_type == FORMAT_G729D_6K4) { + int16_t exc_new[SUBFRAME_SIZE]; + + ctx->onset = g729d_onset_decision(ctx->onset, ctx->past_gain_code); + ctx->voice_decision = g729d_voice_decision(ctx->onset, ctx->voice_decision, ctx->past_gain_pitch); + + g729d_get_new_exc(exc_new, ctx->exc + i * SUBFRAME_SIZE, fc, ctx->voice_decision, ctx->past_gain_code[0], SUBFRAME_SIZE); + + ff_celp_lp_synthesis_filter( + synth+10, + &lp[i][1], + exc_new, + SUBFRAME_SIZE, + 10, + 0, + 0, + 0x800); + } else { + ff_celp_lp_synthesis_filter( + synth+10, + &lp[i][1], + ctx->exc + i * SUBFRAME_SIZE, + SUBFRAME_SIZE, + 10, + 0, + 0, + 0x800); + } + /* Save data (without postfilter) for use in next subframe. */ + memcpy(ctx->syn_filter_data, synth+SUBFRAME_SIZE, 10 * sizeof(int16_t)); + + /* Calculate gain of unfiltered signal for use in AGC. */ + gain_before = 0; + for (j = 0; j < SUBFRAME_SIZE; j++) + gain_before += FFABS(synth[j+10]); + + /* Call postfilter and also update voicing decision for use in next frame. */ + ff_g729_postfilter( + &ctx->dsp, + &ctx->ht_prev_data, + &is_periodic, + &lp[i][0], + pitch_delay_int[0], + ctx->residual, + ctx->res_filter_data, + ctx->pos_filter_data, + synth+10, + SUBFRAME_SIZE); + + /* Calculate gain of filtered signal for use in AGC. */ + gain_after = 0; + for(j=0; j<SUBFRAME_SIZE; j++) + gain_after += FFABS(synth[j+10]); + + ctx->gain_coeff = ff_g729_adaptive_gain_control( + gain_before, + gain_after, + synth+10, + SUBFRAME_SIZE, + ctx->gain_coeff); + + if (frame_erasure) + ctx->pitch_delay_int_prev = FFMIN(ctx->pitch_delay_int_prev + 1, PITCH_DELAY_MAX); + else + ctx->pitch_delay_int_prev = pitch_delay_int[i]; + + memcpy(synth+8, ctx->hpf_z, 2*sizeof(int16_t)); + ff_acelp_high_pass_filter( + out_frame + i*SUBFRAME_SIZE, + ctx->hpf_f, + synth+10, + SUBFRAME_SIZE); + memcpy(ctx->hpf_z, synth+8+SUBFRAME_SIZE, 2*sizeof(int16_t)); + } + + ctx->was_periodic = is_periodic; + + /* Save signal for use in next frame. */ + memmove(ctx->exc_base, ctx->exc_base + 2 * SUBFRAME_SIZE, (PITCH_DELAY_MAX+INTERPOL_LEN)*sizeof(int16_t)); + + *got_frame_ptr = 1; + *(AVFrame*)data = ctx->frame; + return buf_size; +} + +AVCodec ff_g729_decoder = +{ + .name = "g729", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_G729, + .priv_data_size = sizeof(G729Context), + .init = decoder_init, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("G.729"), +}; diff --git a/libavcodec/g729postfilter.c b/libavcodec/g729postfilter.c new file mode 100644 index 0000000000..87472f694c --- /dev/null +++ b/libavcodec/g729postfilter.c @@ -0,0 +1,610 @@ +/* + * G.729, G729 Annex D postfilter + * Copyright (c) 2008 Vladimir Voroshilov + * + * 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 <limits.h> + +#include "avcodec.h" +#include "g729.h" +#include "acelp_pitch_delay.h" +#include "g729postfilter.h" +#include "celp_math.h" +#include "acelp_filters.h" +#include "acelp_vectors.h" +#include "celp_filters.h" + +#define FRAC_BITS 15 +#include "mathops.h" + +/** + * short interpolation filter (of length 33, according to spec) + * for computing signal with non-integer delay + */ +static const int16_t ff_g729_interp_filt_short[(ANALYZED_FRAC_DELAYS+1)*SHORT_INT_FILT_LEN] = { + 0, 31650, 28469, 23705, 18050, 12266, 7041, 2873, + 0, -1597, -2147, -1992, -1492, -933, -484, -188, +}; + +/** + * long interpolation filter (of length 129, according to spec) + * for computing signal with non-integer delay + */ +static const int16_t ff_g729_interp_filt_long[(ANALYZED_FRAC_DELAYS+1)*LONG_INT_FILT_LEN] = { + 0, 31915, 29436, 25569, 20676, 15206, 9639, 4439, + 0, -3390, -5579, -6549, -6414, -5392, -3773, -1874, + 0, 1595, 2727, 3303, 3319, 2850, 2030, 1023, + 0, -887, -1527, -1860, -1876, -1614, -1150, -579, + 0, 501, 859, 1041, 1044, 892, 631, 315, + 0, -266, -453, -543, -538, -455, -317, -156, + 0, 130, 218, 258, 253, 212, 147, 72, + 0, -59, -101, -122, -123, -106, -77, -40, +}; + +/** + * formant_pp_factor_num_pow[i] = FORMANT_PP_FACTOR_NUM^(i+1) + */ +static const int16_t formant_pp_factor_num_pow[10]= { + /* (0.15) */ + 18022, 9912, 5451, 2998, 1649, 907, 499, 274, 151, 83 +}; + +/** + * formant_pp_factor_den_pow[i] = FORMANT_PP_FACTOR_DEN^(i+1) + */ +static const int16_t formant_pp_factor_den_pow[10] = { + /* (0.15) */ + 22938, 16057, 11240, 7868, 5508, 3856, 2699, 1889, 1322, 925 +}; + +/** + * \brief Residual signal calculation (4.2.1 if G.729) + * \param out [out] output data filtered through A(z/FORMANT_PP_FACTOR_NUM) + * \param filter_coeffs (3.12) A(z/FORMANT_PP_FACTOR_NUM) filter coefficients + * \param in input speech data to process + * \param subframe_size size of one subframe + * + * \note in buffer must contain 10 items of previous speech data before top of the buffer + * \remark It is safe to pass the same buffer for input and output. + */ +static void residual_filter(int16_t* out, const int16_t* filter_coeffs, const int16_t* in, + int subframe_size) +{ + int i, n; + + for (n = subframe_size - 1; n >= 0; n--) { + int sum = 0x800; + for (i = 0; i < 10; i++) + sum += filter_coeffs[i] * in[n - i - 1]; + + out[n] = in[n] + (sum >> 12); + } +} + +/** + * \brief long-term postfilter (4.2.1) + * \param dsp initialized DSP context + * \param pitch_delay_int integer part of the pitch delay in the first subframe + * \param residual filtering input data + * \param residual_filt [out] speech signal with applied A(z/FORMANT_PP_FACTOR_NUM) filter + * \param subframe_size size of subframe + * + * \return 0 if long-term prediction gain is less than 3dB, 1 - otherwise + */ +static int16_t long_term_filter(DSPContext *dsp, int pitch_delay_int, + const int16_t* residual, int16_t *residual_filt, + int subframe_size) +{ + int i, k, tmp, tmp2; + int sum; + int L_temp0; + int L_temp1; + int64_t L64_temp0; + int64_t L64_temp1; + int16_t shift; + int corr_int_num, corr_int_den; + + int ener; + int16_t sh_ener; + + int16_t gain_num,gain_den; //selected signal's gain numerator and denominator + int16_t sh_gain_num, sh_gain_den; + int gain_num_square; + + int16_t gain_long_num,gain_long_den; //filtered through long interpolation filter signal's gain numerator and denominator + int16_t sh_gain_long_num, sh_gain_long_den; + + int16_t best_delay_int, best_delay_frac; + + int16_t delayed_signal_offset; + int lt_filt_factor_a, lt_filt_factor_b; + + int16_t * selected_signal; + const int16_t * selected_signal_const; //Necessary to avoid compiler warning + + int16_t sig_scaled[SUBFRAME_SIZE + RES_PREV_DATA_SIZE]; + int16_t delayed_signal[ANALYZED_FRAC_DELAYS][SUBFRAME_SIZE+1]; + int corr_den[ANALYZED_FRAC_DELAYS][2]; + + tmp = 0; + for(i=0; i<subframe_size + RES_PREV_DATA_SIZE; i++) + tmp |= FFABS(residual[i]); + + if(!tmp) + shift = 3; + else + shift = av_log2(tmp) - 11; + + if (shift > 0) + for (i = 0; i < subframe_size + RES_PREV_DATA_SIZE; i++) + sig_scaled[i] = residual[i] >> shift; + else + for (i = 0; i < subframe_size + RES_PREV_DATA_SIZE; i++) + sig_scaled[i] = residual[i] << -shift; + + /* Start of best delay searching code */ + gain_num = 0; + + ener = dsp->scalarproduct_int16(sig_scaled + RES_PREV_DATA_SIZE, + sig_scaled + RES_PREV_DATA_SIZE, + subframe_size, 0); + if (ener) { + sh_ener = FFMAX(av_log2(ener) - 14, 0); + ener >>= sh_ener; + /* Search for best pitch delay. + + sum{ r(n) * r(k,n) ] }^2 + R'(k)^2 := ------------------------- + sum{ r(k,n) * r(k,n) } + + + R(T) := sum{ r(n) * r(n-T) ] } + + + where + r(n-T) is integer delayed signal with delay T + r(k,n) is non-integer delayed signal with integer delay best_delay + and fractional delay k */ + + /* Find integer delay best_delay which maximizes correlation R(T). + + This is also equals to numerator of R'(0), + since the fine search (second step) is done with 1/8 + precision around best_delay. */ + corr_int_num = 0; + best_delay_int = pitch_delay_int - 1; + for (i = pitch_delay_int - 1; i <= pitch_delay_int + 1; i++) { + sum = dsp->scalarproduct_int16(sig_scaled + RES_PREV_DATA_SIZE, + sig_scaled + RES_PREV_DATA_SIZE - i, + subframe_size, 0); + if (sum > corr_int_num) { + corr_int_num = sum; + best_delay_int = i; + } + } + if (corr_int_num) { + /* Compute denominator of pseudo-normalized correlation R'(0). */ + corr_int_den = dsp->scalarproduct_int16(sig_scaled - best_delay_int + RES_PREV_DATA_SIZE, + sig_scaled - best_delay_int + RES_PREV_DATA_SIZE, + subframe_size, 0); + + /* Compute signals with non-integer delay k (with 1/8 precision), + where k is in [0;6] range. + Entire delay is qual to best_delay+(k+1)/8 + This is archieved by applying an interpolation filter of + legth 33 to source signal. */ + for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) { + ff_acelp_interpolate(&delayed_signal[k][0], + &sig_scaled[RES_PREV_DATA_SIZE - best_delay_int], + ff_g729_interp_filt_short, + ANALYZED_FRAC_DELAYS+1, + 8 - k - 1, + SHORT_INT_FILT_LEN, + subframe_size + 1); + } + + /* Compute denominator of pseudo-normalized correlation R'(k). + + corr_den[k][0] is square root of R'(k) denominator, for int(T) == int(T0) + corr_den[k][1] is square root of R'(k) denominator, for int(T) == int(T0)+1 + + Also compute maximum value of above denominators over all k. */ + tmp = corr_int_den; + for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) { + sum = dsp->scalarproduct_int16(&delayed_signal[k][1], + &delayed_signal[k][1], + subframe_size - 1, 0); + corr_den[k][0] = sum + delayed_signal[k][0 ] * delayed_signal[k][0 ]; + corr_den[k][1] = sum + delayed_signal[k][subframe_size] * delayed_signal[k][subframe_size]; + + tmp = FFMAX3(tmp, corr_den[k][0], corr_den[k][1]); + } + + sh_gain_den = av_log2(tmp) - 14; + if (sh_gain_den >= 0) { + + sh_gain_num = FFMAX(sh_gain_den, sh_ener); + /* Loop through all k and find delay that maximizes + R'(k) correlation. + Search is done in [int(T0)-1; intT(0)+1] range + with 1/8 precision. */ + delayed_signal_offset = 1; + best_delay_frac = 0; + gain_den = corr_int_den >> sh_gain_den; + gain_num = corr_int_num >> sh_gain_num; + gain_num_square = gain_num * gain_num; + for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) { + for (i = 0; i < 2; i++) { + int16_t gain_num_short, gain_den_short; + int gain_num_short_square; + /* Compute numerator of pseudo-normalized + correlation R'(k). */ + sum = dsp->scalarproduct_int16(&delayed_signal[k][i], + sig_scaled + RES_PREV_DATA_SIZE, + subframe_size, 0); + gain_num_short = FFMAX(sum >> sh_gain_num, 0); + + /* + gain_num_short_square gain_num_square + R'(T)^2 = -----------------------, max R'(T)^2= -------------- + den gain_den + */ + gain_num_short_square = gain_num_short * gain_num_short; + gain_den_short = corr_den[k][i] >> sh_gain_den; + + tmp = MULL(gain_num_short_square, gain_den, FRAC_BITS); + tmp2 = MULL(gain_num_square, gain_den_short, FRAC_BITS); + + // R'(T)^2 > max R'(T)^2 + if (tmp > tmp2) { + gain_num = gain_num_short; + gain_den = gain_den_short; + gain_num_square = gain_num_short_square; + delayed_signal_offset = i; + best_delay_frac = k + 1; + } + } + } + + /* + R'(T)^2 + 2 * --------- < 1 + R(0) + */ + L64_temp0 = (int64_t)gain_num_square << ((sh_gain_num << 1) + 1); + L64_temp1 = ((int64_t)gain_den * ener) << (sh_gain_den + sh_ener); + if (L64_temp0 < L64_temp1) + gain_num = 0; + } // if(sh_gain_den >= 0) + } // if(corr_int_num) + } // if(ener) + /* End of best delay searching code */ + + if (!gain_num) { + memcpy(residual_filt, residual + RES_PREV_DATA_SIZE, subframe_size * sizeof(int16_t)); + + /* Long-term prediction gain is less than 3dB. Long-term postfilter is disabled. */ + return 0; + } + if (best_delay_frac) { + /* Recompute delayed signal with an interpolation filter of length 129. */ + ff_acelp_interpolate(residual_filt, + &sig_scaled[RES_PREV_DATA_SIZE - best_delay_int + delayed_signal_offset], + ff_g729_interp_filt_long, + ANALYZED_FRAC_DELAYS + 1, + 8 - best_delay_frac, + LONG_INT_FILT_LEN, + subframe_size + 1); + /* Compute R'(k) correlation's numerator. */ + sum = dsp->scalarproduct_int16(residual_filt, + sig_scaled + RES_PREV_DATA_SIZE, + subframe_size, 0); + + if (sum < 0) { + gain_long_num = 0; + sh_gain_long_num = 0; + } else { + tmp = FFMAX(av_log2(sum) - 14, 0); + sum >>= tmp; + gain_long_num = sum; + sh_gain_long_num = tmp; + } + + /* Compute R'(k) correlation's denominator. */ + sum = dsp->scalarproduct_int16(residual_filt, residual_filt, subframe_size, 0); + + tmp = FFMAX(av_log2(sum) - 14, 0); + sum >>= tmp; + gain_long_den = sum; + sh_gain_long_den = tmp; + + /* Select between original and delayed signal. + Delayed signal will be selected if it increases R'(k) + correlation. */ + L_temp0 = gain_num * gain_num; + L_temp0 = MULL(L_temp0, gain_long_den, FRAC_BITS); + + L_temp1 = gain_long_num * gain_long_num; + L_temp1 = MULL(L_temp1, gain_den, FRAC_BITS); + + tmp = ((sh_gain_long_num - sh_gain_num) << 1) - (sh_gain_long_den - sh_gain_den); + if (tmp > 0) + L_temp0 >>= tmp; + else + L_temp1 >>= -tmp; + + /* Check if longer filter increases the values of R'(k). */ + if (L_temp1 > L_temp0) { + /* Select long filter. */ + selected_signal = residual_filt; + gain_num = gain_long_num; + gain_den = gain_long_den; + sh_gain_num = sh_gain_long_num; + sh_gain_den = sh_gain_long_den; + } else + /* Select short filter. */ + selected_signal = &delayed_signal[best_delay_frac-1][delayed_signal_offset]; + + /* Rescale selected signal to original value. */ + if (shift > 0) + for (i = 0; i < subframe_size; i++) + selected_signal[i] <<= shift; + else + for (i = 0; i < subframe_size; i++) + selected_signal[i] >>= -shift; + + /* necessary to avoid compiler warning */ + selected_signal_const = selected_signal; + } // if(best_delay_frac) + else + selected_signal_const = residual + RES_PREV_DATA_SIZE - (best_delay_int + 1 - delayed_signal_offset); +#ifdef G729_BITEXACT + tmp = sh_gain_num - sh_gain_den; + if (tmp > 0) + gain_den >>= tmp; + else + gain_num >>= -tmp; + + if (gain_num > gain_den) + lt_filt_factor_a = MIN_LT_FILT_FACTOR_A; + else { + gain_num >>= 2; + gain_den >>= 1; + lt_filt_factor_a = (gain_den << 15) / (gain_den + gain_num); + } +#else + L64_temp0 = ((int64_t)gain_num) << (sh_gain_num - 1); + L64_temp1 = ((int64_t)gain_den) << sh_gain_den; + lt_filt_factor_a = FFMAX((L64_temp1 << 15) / (L64_temp1 + L64_temp0), MIN_LT_FILT_FACTOR_A); +#endif + + /* Filter through selected filter. */ + lt_filt_factor_b = 32767 - lt_filt_factor_a + 1; + + ff_acelp_weighted_vector_sum(residual_filt, residual + RES_PREV_DATA_SIZE, + selected_signal_const, + lt_filt_factor_a, lt_filt_factor_b, + 1<<14, 15, subframe_size); + + // Long-term prediction gain is larger than 3dB. + return 1; +} + +/** + * \brief Calculate reflection coefficient for tilt compensation filter (4.2.3). + * \param dsp initialized DSP context + * \param lp_gn (3.12) coefficients of A(z/FORMANT_PP_FACTOR_NUM) filter + * \param lp_gd (3.12) coefficients of A(z/FORMANT_PP_FACTOR_DEN) filter + * \param speech speech to update + * \param subframe_size size of subframe + * + * \return (3.12) reflection coefficient + * + * \remark The routine also calculates the gain term for the short-term + * filter (gf) and multiplies the speech data by 1/gf. + * + * \note All members of lp_gn, except 10-19 must be equal to zero. + */ +static int16_t get_tilt_comp(DSPContext *dsp, int16_t *lp_gn, + const int16_t *lp_gd, int16_t* speech, + int subframe_size) +{ + int rh1,rh0; // (3.12) + int temp; + int i; + int gain_term; + + lp_gn[10] = 4096; //1.0 in (3.12) + + /* Apply 1/A(z/FORMANT_PP_FACTOR_DEN) filter to hf. */ + ff_celp_lp_synthesis_filter(lp_gn + 11, lp_gd + 1, lp_gn + 11, 22, 10, 0, 0, 0x800); + /* Now lp_gn (starting with 10) contains impulse response + of A(z/FORMANT_PP_FACTOR_NUM)/A(z/FORMANT_PP_FACTOR_DEN) filter. */ + + rh0 = dsp->scalarproduct_int16(lp_gn + 10, lp_gn + 10, 20, 0); + rh1 = dsp->scalarproduct_int16(lp_gn + 10, lp_gn + 11, 20, 0); + + /* downscale to avoid overflow */ + temp = av_log2(rh0) - 14; + if (temp > 0) { + rh0 >>= temp; + rh1 >>= temp; + } + + if (FFABS(rh1) > rh0 || !rh0) + return 0; + + gain_term = 0; + for (i = 0; i < 20; i++) + gain_term += FFABS(lp_gn[i + 10]); + gain_term >>= 2; // (3.12) -> (5.10) + + if (gain_term > 0x400) { // 1.0 in (5.10) + temp = 0x2000000 / gain_term; // 1.0/gain_term in (0.15) + for (i = 0; i < subframe_size; i++) + speech[i] = (speech[i] * temp + 0x4000) >> 15; + } + + return -(rh1 << 15) / rh0; +} + +/** + * \brief Apply tilt compensation filter (4.2.3). + * \param res_pst [in/out] residual signal (partially filtered) + * \param k1 (3.12) reflection coefficient + * \param subframe_size size of subframe + * \param ht_prev_data previous data for 4.2.3, equation 86 + * + * \return new value for ht_prev_data +*/ +static int16_t apply_tilt_comp(int16_t* out, int16_t* res_pst, int refl_coeff, + int subframe_size, int16_t ht_prev_data) +{ + int tmp, tmp2; + int i; + int gt, ga; + int fact, sh_fact; + + if (refl_coeff > 0) { + gt = (refl_coeff * G729_TILT_FACTOR_PLUS + 0x4000) >> 15; + fact = 0x4000; // 0.5 in (0.15) + sh_fact = 15; + } else { + gt = (refl_coeff * G729_TILT_FACTOR_MINUS + 0x4000) >> 15; + fact = 0x800; // 0.5 in (3.12) + sh_fact = 12; + } + ga = (fact << 15) / av_clip_int16(32768 - FFABS(gt)); + gt >>= 1; + + /* Apply tilt compensation filter to signal. */ + tmp = res_pst[subframe_size - 1]; + + for (i = subframe_size - 1; i >= 1; i--) { + tmp2 = (res_pst[i] << 15) + ((gt * res_pst[i-1]) << 1); + tmp2 = (tmp2 + 0x4000) >> 15; + + tmp2 = (tmp2 * ga * 2 + fact) >> sh_fact; + out[i] = tmp2; + } + tmp2 = (res_pst[0] << 15) + ((gt * ht_prev_data) << 1); + tmp2 = (tmp2 + 0x4000) >> 15; + tmp2 = (tmp2 * ga * 2 + fact) >> sh_fact; + out[0] = tmp2; + + return tmp; +} + +void ff_g729_postfilter(DSPContext *dsp, int16_t* ht_prev_data, int* voicing, + const int16_t *lp_filter_coeffs, int pitch_delay_int, + int16_t* residual, int16_t* res_filter_data, + int16_t* pos_filter_data, int16_t *speech, int subframe_size) +{ + int16_t residual_filt_buf[SUBFRAME_SIZE+11]; + int16_t lp_gn[33]; // (3.12) + int16_t lp_gd[11]; // (3.12) + int tilt_comp_coeff; + int i; + + /* Zero-filling is necessary for tilt-compensation filter. */ + memset(lp_gn, 0, 33 * sizeof(int16_t)); + + /* Calculate A(z/FORMANT_PP_FACTOR_NUM) filter coefficients. */ + for (i = 0; i < 10; i++) + lp_gn[i + 11] = (lp_filter_coeffs[i + 1] * formant_pp_factor_num_pow[i] + 0x4000) >> 15; + + /* Calculate A(z/FORMANT_PP_FACTOR_DEN) filter coefficients. */ + for (i = 0; i < 10; i++) + lp_gd[i + 1] = (lp_filter_coeffs[i + 1] * formant_pp_factor_den_pow[i] + 0x4000) >> 15; + + /* residual signal calculation (one-half of short-term postfilter) */ + memcpy(speech - 10, res_filter_data, 10 * sizeof(int16_t)); + residual_filter(residual + RES_PREV_DATA_SIZE, lp_gn + 11, speech, subframe_size); + /* Save data to use it in the next subframe. */ + memcpy(res_filter_data, speech + subframe_size - 10, 10 * sizeof(int16_t)); + + /* long-term filter. If long-term prediction gain is larger than 3dB (returned value is + nonzero) then declare current subframe as periodic. */ + *voicing = FFMAX(*voicing, long_term_filter(dsp, pitch_delay_int, + residual, residual_filt_buf + 10, + subframe_size)); + + /* shift residual for using in next subframe */ + memmove(residual, residual + subframe_size, RES_PREV_DATA_SIZE * sizeof(int16_t)); + + /* short-term filter tilt compensation */ + tilt_comp_coeff = get_tilt_comp(dsp, lp_gn, lp_gd, residual_filt_buf + 10, subframe_size); + + /* Apply second half of short-term postfilter: 1/A(z/FORMANT_PP_FACTOR_DEN) */ + ff_celp_lp_synthesis_filter(pos_filter_data + 10, lp_gd + 1, + residual_filt_buf + 10, + subframe_size, 10, 0, 0, 0x800); + memcpy(pos_filter_data, pos_filter_data + subframe_size, 10 * sizeof(int16_t)); + + *ht_prev_data = apply_tilt_comp(speech, pos_filter_data + 10, tilt_comp_coeff, + subframe_size, *ht_prev_data); +} + +/** + * \brief Adaptive gain control (4.2.4) + * \param gain_before gain of speech before applying postfilters + * \param gain_after gain of speech after applying postfilters + * \param speech [in/out] signal buffer + * \param subframe_size length of subframe + * \param gain_prev (3.12) previous value of gain coefficient + * + * \return (3.12) last value of gain coefficient + */ +int16_t ff_g729_adaptive_gain_control(int gain_before, int gain_after, int16_t *speech, + int subframe_size, int16_t gain_prev) +{ + int gain; // (3.12) + int n; + int exp_before, exp_after; + + if(!gain_after && gain_before) + return 0; + + if (gain_before) { + + exp_before = 14 - av_log2(gain_before); + gain_before = bidir_sal(gain_before, exp_before); + + exp_after = 14 - av_log2(gain_after); + gain_after = bidir_sal(gain_after, exp_after); + + if (gain_before < gain_after) { + gain = (gain_before << 15) / gain_after; + gain = bidir_sal(gain, exp_after - exp_before - 1); + } else { + gain = ((gain_before - gain_after) << 14) / gain_after + 0x4000; + gain = bidir_sal(gain, exp_after - exp_before); + } + gain = (gain * G729_AGC_FAC1 + 0x4000) >> 15; // gain * (1-0.9875) + } else + gain = 0; + + for (n = 0; n < subframe_size; n++) { + // gain_prev = gain + 0.9875 * gain_prev + gain_prev = (G729_AGC_FACTOR * gain_prev + 0x4000) >> 15; + gain_prev = av_clip_int16(gain + gain_prev); + speech[n] = av_clip_int16((speech[n] * gain_prev + 0x2000) >> 14); + } + return gain_prev; +} diff --git a/libavcodec/g729postfilter.h b/libavcodec/g729postfilter.h new file mode 100644 index 0000000000..0ccecb2b92 --- /dev/null +++ b/libavcodec/g729postfilter.h @@ -0,0 +1,115 @@ +/* + * G.729, G729 Annex D postfilter + * Copyright (c) 2008 Vladimir Voroshilov + * + * 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_G729POSTFILTER_H +#define FFMPEG_G729POSTFILTER_H + +#include <stdint.h> + +/** + * tilt compensation factor (G.729, k1>0) + * 0.2 in Q15 + */ +#define G729_TILT_FACTOR_PLUS 6554 + +/** + * tilt compensation factor (G.729, k1<0) + * 0.9 in Q15 + */ +#define G729_TILT_FACTOR_MINUS 29491 + +/* 4.2.2 */ +#define FORMANT_PP_FACTOR_NUM 18022 //0.55 in Q15 +#define FORMANT_PP_FACTOR_DEN 22938 //0.70 in Q15 + +/** + * gain adjustment factor (G.729, 4.2.4) + * 0.9875 in Q15 + */ +#define G729_AGC_FACTOR 32358 +#define G729_AGC_FAC1 (32768-G729_AGC_FACTOR) + +/** + * 1.0 / (1.0 + 0.5) in Q15 + * where 0.5 is the minimum value of + * weight factor, controlling amount of long-term postfiltering + */ +#define MIN_LT_FILT_FACTOR_A 21845 + +/** + * Short interpolation filter length + */ +#define SHORT_INT_FILT_LEN 2 + +/** + * Long interpolation filter length + */ +#define LONG_INT_FILT_LEN 8 + +/** + * Number of analyzed fractional pitch delays in second stage of long-term + * postfilter + */ +#define ANALYZED_FRAC_DELAYS 7 + +/** + * Amount of past residual signal data stored in buffer + */ +#define RES_PREV_DATA_SIZE (PITCH_DELAY_MAX + LONG_INT_FILT_LEN + 1) + +/** + * \brief Signal postfiltering (4.2) + * \param dsp initialized DSP context + * \param ht_prev_data [in/out] (Q12) pointer to variable receiving tilt + * compensation filter data from previous subframe + * \param voicing [in/out] (Q0) pointer to variable receiving voicing decision + * \param lp_filter_coeffs (Q12) LP filter coefficients + * \param pitch_delay_int integer part of the pitch delay + * \param residual [in/out] (Q0) residual signal buffer (used in long-term postfilter) + * \param res_filter_data [in/out] (Q0) speech data of previous subframe + * \param pos_filter_data [in/out] (Q0) previous speech data for short-term postfilter + * \param speech [in/out] (Q0) signal buffer + * \param subframe_size size of subframe + * + * Filtering has the following stages: + * Long-term postfilter (4.2.1) + * Short-term postfilter (4.2.2). + * Tilt-compensation (4.2.3) + */ +void ff_g729_postfilter(DSPContext *dsp, int16_t* ht_prev_data, int* voicing, + const int16_t *lp_filter_coeffs, int pitch_delay_int, + int16_t* residual, int16_t* res_filter_data, + int16_t* pos_filter_data, int16_t *speech, + int subframe_size); + +/** + * \brief Adaptive gain control (4.2.4) + * \param gain_before (Q0) gain of speech before applying postfilters + * \param gain_after (Q0) gain of speech after applying postfilters + * \param speech [in/out] (Q0) signal buffer + * \param subframe_size length of subframe + * \param gain_prev (Q12) previous value of gain coefficient + * + * \return (Q12) last value of gain coefficient + */ +int16_t ff_g729_adaptive_gain_control(int gain_before, int gain_after, int16_t *speech, + int subframe_size, int16_t gain_prev); + +#endif // FFMPEG_G729POSTFILTER_H diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index 1668600b2d..648c958cb0 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -1,20 +1,20 @@ /* * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -53,9 +53,7 @@ typedef struct GetBitContext { const uint8_t *buffer, *buffer_end; int index; int size_in_bits; -#if !UNCHECKED_BITSTREAM_READER int size_in_bits_plus8; -#endif } GetBitContext; #define VLC_TYPE int16_t @@ -122,7 +120,7 @@ for examples see get_bits, show_bits, skip_bits, get_vlc #define OPEN_READER(name, gb) \ unsigned int name##_index = (gb)->index; \ - unsigned int av_unused name##_cache = 0 + av_unused unsigned int name##_cache #define CLOSE_READER(name, gb) (gb)->index = name##_index @@ -347,9 +345,7 @@ static inline void init_get_bits(GetBitContext *s, const uint8_t *buffer, s->buffer = buffer; s->size_in_bits = bit_size; -#if !UNCHECKED_BITSTREAM_READER s->size_in_bits_plus8 = bit_size + 8; -#endif s->buffer_end = buffer + buffer_size; s->index = 0; } diff --git a/libavcodec/gif.c b/libavcodec/gif.c index c7e7bcd185..830a059422 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -4,20 +4,20 @@ * Copyright (c) 2002 Francois Revol * Copyright (c) 2006 Baptiste Coudurier * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -62,7 +62,7 @@ static int gif_image_write_header(AVCodecContext *avctx, uint8_t **bytestream, uint32_t *palette) { int i; - unsigned int v; + unsigned int v, smallest_alpha = 0xFF, alpha_component = 0; bytestream_put_buffer(bytestream, "GIF", 3); bytestream_put_buffer(bytestream, "89a", 3); @@ -77,6 +77,20 @@ static int gif_image_write_header(AVCodecContext *avctx, for(i=0;i<256;i++) { v = palette[i]; bytestream_put_be24(bytestream, v); + if (v >> 24 < smallest_alpha) { + smallest_alpha = v >> 24; + alpha_component = i; + } + } + + if (smallest_alpha < 128) { + bytestream_put_byte(bytestream, 0x21); /* Extension Introducer */ + bytestream_put_byte(bytestream, 0xf9); /* Graphic Control Label */ + bytestream_put_byte(bytestream, 0x04); /* block length */ + bytestream_put_byte(bytestream, 0x01); /* Transparent Color Flag */ + bytestream_put_le16(bytestream, 0x00); /* no delay */ + bytestream_put_byte(bytestream, alpha_component); + bytestream_put_byte(bytestream, 0x00); } return 0; diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index 9bac254c59..83cb36831b 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2006 Baptiste Coudurier * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/golomb-test.c b/libavcodec/golomb-test.c index bc90f36baf..54644ade46 100644 --- a/libavcodec/golomb-test.c +++ b/libavcodec/golomb-test.c @@ -1,18 +1,20 @@ /* - * This file is part of Libav. + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/golomb.c b/libavcodec/golomb.c index 550c41ebfe..937ac22ce1 100644 --- a/libavcodec/golomb.c +++ b/libavcodec/golomb.c @@ -2,20 +2,20 @@ * exp golomb vlc stuff * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/golomb.h b/libavcodec/golomb.h index 503aa1416a..638357b470 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -123,7 +123,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){ }else{ int ret = 1; - while (1) { + do { buf >>= 32 - 8; LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); @@ -135,7 +135,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){ ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; UPDATE_CACHE(re, gb); buf = GET_CACHE(re, gb); - } + } while(ret<0x8000000U); CLOSE_READER(re, gb); return ret - 1; @@ -302,6 +302,8 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int }else{ int i; for(i=0; SHOW_UBITS(re, gb, 1) == 0; i++){ + if (gb->size_in_bits <= re_index) + return -1; LAST_SKIP_BITS(re, gb, 1); UPDATE_CACHE(re, gb); } diff --git a/libavcodec/gsm.h b/libavcodec/gsm.h index c7c3e22bde..e56f4cd0b4 100644 --- a/libavcodec/gsm.h +++ b/libavcodec/gsm.h @@ -1,20 +1,20 @@ /* * GSM common header * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/gsmdec.c b/libavcodec/gsmdec.c index 97b6fe8492..eec515b41f 100644 --- a/libavcodec/gsmdec.c +++ b/libavcodec/gsmdec.c @@ -2,20 +2,20 @@ * gsm 06.10 decoder * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/gsmdec_data.c b/libavcodec/gsmdec_data.c index 8b75bb6a67..4324ea28a9 100644 --- a/libavcodec/gsmdec_data.c +++ b/libavcodec/gsmdec_data.c @@ -2,20 +2,20 @@ * gsm 06.10 decoder data * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/gsmdec_data.h b/libavcodec/gsmdec_data.h index 2ff2322ab1..3eb30b84b7 100644 --- a/libavcodec/gsmdec_data.h +++ b/libavcodec/gsmdec_data.h @@ -2,20 +2,20 @@ * gsm 06.10 decoder data * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/gsmdec_template.c b/libavcodec/gsmdec_template.c index b5222af4da..0f559530ec 100644 --- a/libavcodec/gsmdec_template.c +++ b/libavcodec/gsmdec_template.c @@ -2,20 +2,20 @@ * gsm 06.10 decoder * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h261.c b/libavcodec/h261.c index 9555613f6b..951997d65e 100644 --- a/libavcodec/h261.c +++ b/libavcodec/h261.c @@ -3,20 +3,20 @@ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Maarten Daniels * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h261.h b/libavcodec/h261.h index 6461329343..5b60dd65a3 100644 --- a/libavcodec/h261.h +++ b/libavcodec/h261.h @@ -3,20 +3,20 @@ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Maarten Daniels * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h261_parser.c b/libavcodec/h261_parser.c index fb50acfc4a..9eedeea03a 100644 --- a/libavcodec/h261_parser.c +++ b/libavcodec/h261_parser.c @@ -3,20 +3,20 @@ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Maarten Daniels * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -70,11 +70,15 @@ static int h261_parse(AVCodecParserContext *s, 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; + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + 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; diff --git a/libavcodec/h261data.h b/libavcodec/h261data.h index 2c610151c7..82bae163df 100644 --- a/libavcodec/h261data.h +++ b/libavcodec/h261data.h @@ -2,20 +2,20 @@ * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * copyright (c) 2004 Maarten Daniels * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h261dec.c b/libavcodec/h261dec.c index 66ea4be2a1..ff3d05c514 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -3,20 +3,20 @@ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Maarten Daniels * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -136,7 +136,7 @@ static int h261_decode_gob_header(H261Context *h){ if(s->qscale==0) { av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n"); - if (s->avctx->err_recognition & AV_EF_BITSTREAM) + if (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT)) return -1; } diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c index 1072d9eabc..4385aee11b 100644 --- a/libavcodec/h261enc.c +++ b/libavcodec/h261enc.c @@ -3,20 +3,20 @@ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Maarten Daniels * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h263.c b/libavcodec/h263.c index 77a1bb828b..7c93e9bbe4 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -5,20 +5,20 @@ * Copyright (c) 2001 Juan J. Sierralta P * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h263.h b/libavcodec/h263.h index 73c5966605..0c11514786 100644 --- a/libavcodec/h263.h +++ b/libavcodec/h263.h @@ -1,20 +1,20 @@ /* * H263 internal header * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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_H263_H @@ -59,8 +59,8 @@ extern RLTable rl_intra_aic; extern const uint16_t h263_format[8][2]; extern const uint8_t modified_quant_tab[2][32]; -extern uint16_t ff_mba_max[6]; -extern uint8_t ff_mba_length[7]; +extern const uint16_t ff_mba_max[6]; +extern const uint8_t ff_mba_length[7]; extern uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; diff --git a/libavcodec/h263_parser.c b/libavcodec/h263_parser.c index 98a72d92a9..9a1ba39d11 100644 --- a/libavcodec/h263_parser.c +++ b/libavcodec/h263_parser.c @@ -2,20 +2,20 @@ * H.263 parser * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -70,12 +70,16 @@ static int h263_parse(AVCodecParserContext *s, ParseContext *pc = s->priv_data; int next; - next= ff_h263_find_frame_end(pc, buf, buf_size); + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + 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; + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } } *poutbuf = buf; diff --git a/libavcodec/h263_parser.h b/libavcodec/h263_parser.h index 5bd715f49d..565a222bc1 100644 --- a/libavcodec/h263_parser.h +++ b/libavcodec/h263_parser.h @@ -2,20 +2,20 @@ * H.263 parser * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h263data.h b/libavcodec/h263data.h index 966da56110..907eae2a65 100644 --- a/libavcodec/h263data.h +++ b/libavcodec/h263data.h @@ -4,20 +4,20 @@ * copyright (c) 2001 Juan J. Sierralta P * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -264,11 +264,11 @@ const uint8_t ff_h263_chroma_qscale_table[32]={ 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 9,10,10,11,11,12,12,12,13,13,13,14,14,14,14,14,15,15,15,15,15 }; -uint16_t ff_mba_max[6]={ +const uint16_t ff_mba_max[6]={ 47, 98, 395,1583,6335,9215 }; -uint8_t ff_mba_length[7]={ +const uint8_t ff_mba_length[7]={ 6, 7, 9, 11, 13, 14, 14 }; diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index f056d1fbe2..621f7ad9f2 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -3,20 +3,20 @@ * Copyright (c) 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +25,8 @@ * H.263 decoder. */ +#define UNCHECKED_BITSTREAM_READER 1 + #include "libavutil/cpu.h" #include "internal.h" #include "avcodec.h" @@ -271,7 +273,7 @@ static int decode_slice(MpegEncContext *s){ if( s->codec_id==CODEC_ID_MPEG4 && (s->workaround_bugs&FF_BUG_AUTODETECT) && get_bits_left(&s->gb) >=0 - && get_bits_left(&s->gb) < 48 + && get_bits_left(&s->gb) < 137 // && !s->resync_marker && !s->data_partitioning){ @@ -310,7 +312,7 @@ static int decode_slice(MpegEncContext *s){ max_extra+= 17; /* buggy padding but the frame should still end approximately at the bitstream end */ - if((s->workaround_bugs&FF_BUG_NO_PADDING) && (s->err_recognition&AV_EF_BUFFER)) + if((s->workaround_bugs&FF_BUG_NO_PADDING) && (s->err_recognition&(AV_EF_BUFFER|AV_EF_AGGRESSIVE))) max_extra+= 48; else if((s->workaround_bugs&FF_BUG_NO_PADDING)) max_extra+= 256*256*256*64; @@ -382,6 +384,18 @@ uint64_t time= rdtsc(); retry: + if(s->divx_packed && s->bitstream_buffer_size){ + int i; + for(i=0; i<buf_size-3; i++){ + if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1){ + if(buf[i+3]==0xB0){ + av_log(s->avctx, AV_LOG_WARNING, "Discarding excessive bitstream in packed xvid\n"); + s->bitstream_buffer_size=0; + } + break; + } + } + } if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 5.01+/xvid frame reorder init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8); @@ -556,8 +570,7 @@ retry: #if HAVE_MMX if (s->codec_id == CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) { avctx->idct_algo= FF_IDCT_XVIDMMX; - avctx->coded_width= 0; // force reinit -// dsputil_init(&s->dsp, avctx); + ff_dct_common_init(s); s->picture_number=0; } #endif @@ -571,6 +584,12 @@ retry: || s->height != avctx->coded_height) { /* H.263 could change picture size any time */ ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat + + if (HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_FRAME)) { + av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0); + return -1; // width / height changed during parallelized decoding + } + s->parse_context.buffer=0; MPV_common_end(s); s->parse_context= pc; @@ -670,22 +689,18 @@ retry: frame_end: /* divx 5.01+ bistream reorder stuff */ if(s->codec_id==CODEC_ID_MPEG4 && s->divx_packed){ - int current_pos= get_bits_count(&s->gb)>>3; + int current_pos= s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb)>>3); int startcode_found=0; - if(buf_size - current_pos > 5){ + if(buf_size - current_pos > 7){ int i; - for(i=current_pos; i<buf_size-3; i++){ + for(i=current_pos; i<buf_size-4; i++){ if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){ - startcode_found=1; + startcode_found=!(buf[i+4]&0x40); break; } } } - if(s->gb.buffer == s->bitstream_buffer && buf_size>7 && s->xvid_build>=0){ //xvid style - startcode_found=1; - current_pos=0; - } if(startcode_found){ av_fast_malloc( diff --git a/libavcodec/h264.c b/libavcodec/h264.c index cf409c0978..7a16bdaedc 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,7 +25,10 @@ * @author Michael Niedermayer <michaelni@gmx.at> */ +#define UNCHECKED_BITSTREAM_READER 1 + #include "libavutil/imgutils.h" +#include "libavutil/opt.h" #include "internal.h" #include "cabac.h" #include "cabac_functions.h" @@ -99,13 +102,9 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h){ } return 0; -} //FIXME cleanup like ff_h264_check_intra_pred_mode +} //FIXME cleanup like check_intra_pred_mode -/** - * Check if the top & left blocks are available if needed and - * change the dc mode so it only uses the available blocks. - */ -int ff_h264_check_intra_pred_mode(H264Context *h, int mode){ +static int check_intra_pred_mode(H264Context *h, int mode, int is_chroma){ MpegEncContext * const s = &h->s; static const int8_t top [7]= {LEFT_DC_PRED8x8, 1,-1,-1}; static const int8_t left[7]= { TOP_DC_PRED8x8,-1, 2,-1,DC_128_PRED8x8}; @@ -125,7 +124,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode){ if((h->left_samples_available&0x8080) != 0x8080){ mode= left[ mode ]; - if(h->left_samples_available&0x8080){ //mad cow disease mode, aka MBAFF + constrained_intra_pred + if(is_chroma && (h->left_samples_available&0x8080)){ //mad cow disease mode, aka MBAFF + constrained_intra_pred mode= ALZHEIMER_DC_L0T_PRED8x8 + (!(h->left_samples_available&0x8000)) + 2*(mode == DC_128_PRED8x8); } if(mode<0){ @@ -137,6 +136,23 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode){ return mode; } +/** + * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. + */ +int ff_h264_check_intra16x16_pred_mode(H264Context *h, int mode) +{ + return check_intra_pred_mode(h, mode, 0); +} + +/** + * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. + */ +int ff_h264_check_intra_chroma_pred_mode(H264Context *h, int mode) +{ + return check_intra_pred_mode(h, mode, 1); +} + + const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){ int i, si, di; uint8_t *dst; @@ -177,20 +193,28 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_l i-= RS; } - if(i>=length-1){ //no escaped 0 - *dst_length= length; - *consumed= length+1; //+1 for the header - return src; - } - bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0; // use second escape buffer for inter data - av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE); + si=h->rbsp_buffer_size[bufidx]; + av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE+MAX_MBPAIR_SIZE); dst= h->rbsp_buffer[bufidx]; + if(si != h->rbsp_buffer_size[bufidx]) + memset(dst + length, 0, FF_INPUT_BUFFER_PADDING_SIZE+MAX_MBPAIR_SIZE); if (dst == NULL){ return NULL; } + if(i>=length-1){ //no escaped 0 + *dst_length= length; + *consumed= length+1; //+1 for the header + if(h->s.avctx->flags2 & CODEC_FLAG2_FAST){ + return src; + }else{ + memcpy(dst, src, length); + return dst; + } + } + //printf("decoding esc\n"); memcpy(dst, src, i); si=di=i; @@ -709,7 +733,7 @@ prefetch_motion(H264Context *h, int list, int pixel_shift, int chroma_idc) s->dsp.prefetch(src[1]+off, s->linesize, 4); s->dsp.prefetch(src[2]+off, s->linesize, 4); }else{ - off= ((mx>>1) << pixel_shift) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + (64 << pixel_shift); + off= (((mx>>1)+64)<<pixel_shift) + ((my>>1) + (s->mb_x&7))*s->uvlinesize; s->dsp.prefetch(src[1]+off, src[2]-src[1], 2); } } @@ -944,7 +968,7 @@ static void init_dequant_tables(H264Context *h){ int ff_h264_alloc_tables(H264Context *h){ MpegEncContext * const s = &h->s; const int big_mb_num= s->mb_stride * (s->mb_height+1); - const int row_mb_num= 2*s->mb_stride*s->avctx->thread_count; + const int row_mb_num= 2*s->mb_stride*FFMAX(s->avctx->thread_count, 1); int x,y; FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode, row_mb_num * 8 * sizeof(uint8_t), fail) @@ -1031,29 +1055,38 @@ static av_cold void common_init(H264Context *h){ s->height = s->avctx->height; s->codec_id= s->avctx->codec->id; - ff_h264dsp_init(&h->h264dsp, 8, 1); - ff_h264_pred_init(&h->hpc, s->codec_id, 8, 1); + s->avctx->bits_per_raw_sample = 8; + h->cur_chroma_format_idc = 1; + + ff_h264dsp_init(&h->h264dsp, + s->avctx->bits_per_raw_sample, h->cur_chroma_format_idc); + ff_h264_pred_init(&h->hpc, s->codec_id, + s->avctx->bits_per_raw_sample, h->cur_chroma_format_idc); h->dequant_coeff_pps= -1; s->unrestricted_mv=1; + s->dsp.dct_bits = 16; dsputil_init(&s->dsp, s->avctx); // needed so that idct permutation is known early memset(h->pps.scaling_matrix4, 16, 6*16*sizeof(uint8_t)); memset(h->pps.scaling_matrix8, 16, 2*64*sizeof(uint8_t)); } -int ff_h264_decode_extradata(H264Context *h) +int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size) { AVCodecContext *avctx = h->s.avctx; - if(avctx->extradata[0] == 1){ + if(!buf || size <= 0) + return -1; + + if(buf[0] == 1){ int i, cnt, nalsize; - unsigned char *p = avctx->extradata; + const unsigned char *p = buf; h->is_avc = 1; - if(avctx->extradata_size < 7) { + if(size < 7) { av_log(avctx, AV_LOG_ERROR, "avcC too short\n"); return -1; } @@ -1065,7 +1098,7 @@ int ff_h264_decode_extradata(H264Context *h) p += 6; for (i = 0; i < cnt; i++) { nalsize = AV_RB16(p) + 2; - if (p - avctx->extradata + nalsize > avctx->extradata_size) + if(nalsize > size - (p-buf)) return -1; if(decode_nal_units(h, p, nalsize) < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i); @@ -1077,7 +1110,7 @@ int ff_h264_decode_extradata(H264Context *h) cnt = *(p++); // Number of pps for (i = 0; i < cnt; i++) { nalsize = AV_RB16(p) + 2; - if (p - avctx->extradata + nalsize > avctx->extradata_size) + if(nalsize > size - (p-buf)) return -1; if (decode_nal_units(h, p, nalsize) < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i); @@ -1086,13 +1119,13 @@ int ff_h264_decode_extradata(H264Context *h) p += nalsize; } // Now store right nal length size, that will be use to parse all other nals - h->nal_length_size = (avctx->extradata[4] & 0x03) + 1; + h->nal_length_size = (buf[4] & 0x03) + 1; } else { h->is_avc = 0; - if(decode_nal_units(h, avctx->extradata, avctx->extradata_size) < 0) + if(decode_nal_units(h, buf, size) < 0) return -1; } - return 0; + return size; } av_cold int ff_h264_decode_init(AVCodecContext *avctx){ @@ -1126,6 +1159,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){ for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) h->last_pocs[i] = INT_MIN; h->prev_poc_msb= 1<<16; + h->prev_frame_num= -1; h->x264_build = -1; ff_h264_reset_sei(h); if(avctx->codec_id == CODEC_ID_H264){ @@ -1136,7 +1170,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){ } if(avctx->extradata_size > 0 && avctx->extradata && - ff_h264_decode_extradata(h)) + ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size)<0) return -1; if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames < h->sps.num_reorder_frames){ @@ -1190,7 +1224,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex int inited = s->context_initialized, err; int i; - if(dst == src || !s1->context_initialized) return 0; + if(dst == src) return 0; err = ff_mpeg_update_thread_context(dst, src); if(err) return err; @@ -1206,12 +1240,19 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex memcpy(&h->s + 1, &h1->s + 1, sizeof(H264Context) - sizeof(MpegEncContext)); //copy all fields after MpegEnc memset(h->sps_buffers, 0, sizeof(h->sps_buffers)); memset(h->pps_buffers, 0, sizeof(h->pps_buffers)); + + if (s1->context_initialized) { if (ff_h264_alloc_tables(h) < 0) { av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n"); return AVERROR(ENOMEM); } context_init(h); + // frame_start may not be called for the next thread (if it's decoding a bottom field) + // so this has to be allocated here + h->s.obmc_scratchpad = av_malloc(16*6*s->linesize); + } + for(i=0; i<2; i++){ h->rbsp_buffer[i] = NULL; h->rbsp_buffer_size[i] = 0; @@ -1219,10 +1260,6 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex h->thread_context[0] = h; - // frame_start may not be called for the next thread (if it's decoding a bottom field) - // so this has to be allocated here - h->s.obmc_scratchpad = av_malloc(16*6*s->linesize); - s->dsp.clear_blocks(h->mb); s->dsp.clear_blocks(h->mb+(24*16<<h->pixel_shift)); } @@ -1261,6 +1298,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex copy_picture_range(h->delayed_pic, h1->delayed_pic, MAX_DELAYED_PIC_COUNT+2, s, s1); h->last_slice_type = h1->last_slice_type; + h->sync = h1->sync; if(!s->current_picture_ptr) return 0; @@ -1291,6 +1329,7 @@ int ff_h264_frame_start(H264Context *h){ * See decode_nal_units(). */ s->current_picture_ptr->f.key_frame = 0; + s->current_picture_ptr->sync = 0; s->current_picture_ptr->mmco_reset= 0; assert(s->linesize && s->uvlinesize); @@ -1349,7 +1388,6 @@ static void decode_postinit(H264Context *h, int setup_finished){ Picture *out = s->current_picture_ptr; Picture *cur = s->current_picture_ptr; int i, pics, out_of_order, out_idx; - int invalid = 0, cnt = 0; s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_H264; s->current_picture_ptr->f.pict_type = s->pict_type; @@ -1428,6 +1466,8 @@ static void decode_postinit(H264Context *h, int setup_finished){ } } + cur->mmco_reset = h->mmco_reset; + h->mmco_reset = 0; //FIXME do something with unavailable reference frames /* Sort B-frames into display order */ @@ -1444,100 +1484,64 @@ static void decode_postinit(H264Context *h, int setup_finished){ s->low_delay= 0; } + for (i = 0; 1; i++) { + if(i == MAX_DELAYED_PIC_COUNT || cur->poc < h->last_pocs[i]){ + if(i) + h->last_pocs[i-1] = cur->poc; + break; + } else if(i) { + h->last_pocs[i-1]= h->last_pocs[i]; + } + } + out_of_order = MAX_DELAYED_PIC_COUNT - i; + if( cur->f.pict_type == AV_PICTURE_TYPE_B + || (h->last_pocs[MAX_DELAYED_PIC_COUNT-2] > INT_MIN && h->last_pocs[MAX_DELAYED_PIC_COUNT-1] - h->last_pocs[MAX_DELAYED_PIC_COUNT-2] > 2)) + out_of_order = FFMAX(out_of_order, 1); + if(s->avctx->has_b_frames < out_of_order && !h->sps.bitstream_restriction_flag){ + av_log(s->avctx, AV_LOG_WARNING, "Increasing reorder buffer to %d\n", out_of_order); + s->avctx->has_b_frames = out_of_order; + s->low_delay = 0; + } + pics = 0; while(h->delayed_pic[pics]) pics++; - assert(pics <= MAX_DELAYED_PIC_COUNT); + av_assert0(pics <= MAX_DELAYED_PIC_COUNT); h->delayed_pic[pics++] = cur; if (cur->f.reference == 0) cur->f.reference = DELAYED_PIC_REF; - /* Frame reordering. This code takes pictures from coding order and sorts - * them by their incremental POC value into display order. It supports POC - * gaps, MMCO reset codes and random resets. - * A "display group" can start either with a IDR frame (f.key_frame = 1), - * and/or can be closed down with a MMCO reset code. In sequences where - * there is no delay, we can't detect that (since the frame was already - * output to the user), so we also set h->mmco_reset to detect the MMCO - * reset code. - * FIXME: if we detect insufficient delays (as per s->avctx->has_b_frames), - * we increase the delay between input and output. All frames affected by - * the lag (e.g. those that should have been output before another frame - * that we already returned to the user) will be dropped. This is a bug - * that we will fix later. */ - for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) { - cnt += out->poc < h->last_pocs[i]; - invalid += out->poc == INT_MIN; - } - if (!h->mmco_reset && !cur->f.key_frame && cnt + invalid == MAX_DELAYED_PIC_COUNT && cnt > 0) { - h->mmco_reset = 2; - if (pics > 1) - h->delayed_pic[pics - 2]->mmco_reset = 2; - } - if (h->mmco_reset || cur->f.key_frame) { - for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) - h->last_pocs[i] = INT_MIN; - cnt = 0; - invalid = MAX_DELAYED_PIC_COUNT; - } out = h->delayed_pic[0]; out_idx = 0; - for (i = 1; i < MAX_DELAYED_PIC_COUNT && h->delayed_pic[i] && - !h->delayed_pic[i-1]->mmco_reset && !h->delayed_pic[i]->f.key_frame; i++) - { + for (i = 1; h->delayed_pic[i] && !h->delayed_pic[i]->f.key_frame && !h->delayed_pic[i]->mmco_reset; i++) if(h->delayed_pic[i]->poc < out->poc){ out = h->delayed_pic[i]; out_idx = i; } - } - if (s->avctx->has_b_frames == 0 && (h->delayed_pic[0]->f.key_frame || h->mmco_reset)) - h->next_outputed_poc = INT_MIN; - out_of_order = !out->f.key_frame && !h->mmco_reset && (out->poc < h->next_outputed_poc); - - if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames) - { } - else if (out_of_order && pics-1 == s->avctx->has_b_frames && - s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) { - if (invalid + cnt < MAX_DELAYED_PIC_COUNT) { - s->avctx->has_b_frames = FFMAX(s->avctx->has_b_frames, cnt); - } - s->low_delay = 0; - } else if (s->low_delay && - ((h->next_outputed_poc != INT_MIN && out->poc > h->next_outputed_poc + 2) || - cur->f.pict_type == AV_PICTURE_TYPE_B)) { - s->low_delay = 0; - s->avctx->has_b_frames++; - } + if (s->avctx->has_b_frames == 0 && (h->delayed_pic[0]->f.key_frame || h->delayed_pic[0]->mmco_reset)) + h->next_outputed_poc= INT_MIN; + out_of_order = out->poc < h->next_outputed_poc; - if(pics > s->avctx->has_b_frames){ + if(out_of_order || pics > s->avctx->has_b_frames){ out->f.reference &= ~DELAYED_PIC_REF; out->owner2 = s; // for frame threading, the owner must be the second field's thread // or else the first thread can release the picture and reuse it unsafely for(i=out_idx; h->delayed_pic[i]; i++) h->delayed_pic[i] = h->delayed_pic[i+1]; } - memmove(h->last_pocs, &h->last_pocs[1], sizeof(*h->last_pocs) * (MAX_DELAYED_PIC_COUNT - 1)); - h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = cur->poc; if(!out_of_order && pics > s->avctx->has_b_frames){ h->next_output_pic = out; - if (out->mmco_reset) { - if (out_idx > 0) { - h->next_outputed_poc = out->poc; - h->delayed_pic[out_idx - 1]->mmco_reset = out->mmco_reset; - } else { - h->next_outputed_poc = INT_MIN; - } - } else { - if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f.key_frame) { - h->next_outputed_poc = INT_MIN; - } else { - h->next_outputed_poc = out->poc; - } - } - h->mmco_reset = 0; + if (out_idx == 0 && h->delayed_pic[0] && (h->delayed_pic[0]->f.key_frame || h->delayed_pic[0]->mmco_reset)) { + h->next_outputed_poc = INT_MIN; + } else + h->next_outputed_poc = out->poc; }else{ - av_log(s->avctx, AV_LOG_DEBUG, "no picture\n"); + av_log(s->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : ""); + } + + if (h->next_output_pic && h->next_output_pic->sync) { + h->sync |= 2; } if (setup_finished) @@ -1577,7 +1581,7 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y, AV_COPY128(top_border+16, src_cb + 15*uvlinesize); AV_COPY128(top_border+32, src_cr + 15*uvlinesize); } - } else if(chroma422) { + } else if(chroma422){ if (pixel_shift) { AV_COPY128(top_border+32, src_cb + 15*uvlinesize); AV_COPY128(top_border+48, src_cr + 15*uvlinesize); @@ -1952,8 +1956,8 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i } if (!simple && IS_INTRA_PCM(mb_type)) { + const int bit_depth = h->sps.bit_depth_luma; if (pixel_shift) { - const int bit_depth = h->sps.bit_depth_luma; int j; GetBitContext gb; init_get_bits(&gb, (uint8_t*)h->mb, 384*bit_depth); @@ -1967,14 +1971,9 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i if (!h->sps.chroma_format_idc) { for (i = 0; i < block_h; i++) { uint16_t *tmp_cb = (uint16_t*)(dest_cb + i*uvlinesize); - for (j = 0; j < 8; j++) { - tmp_cb[j] = 1 << (bit_depth - 1); - } - } - for (i = 0; i < block_h; i++) { uint16_t *tmp_cr = (uint16_t*)(dest_cr + i*uvlinesize); for (j = 0; j < 8; j++) { - tmp_cr[j] = 1 << (bit_depth - 1); + tmp_cb[j] = tmp_cr[j] = 1 << (bit_depth - 1); } } } else { @@ -1996,12 +1995,12 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i } if(simple || !CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){ if (!h->sps.chroma_format_idc) { - for (i = 0; i < block_h; i++) { - memset(dest_cb + i*uvlinesize, 128, 8); - memset(dest_cr + i*uvlinesize, 128, 8); + for (i=0; i<8; i++) { + memset(dest_cb + i*uvlinesize, 1 << (bit_depth - 1), 8); + memset(dest_cr + i*uvlinesize, 1 << (bit_depth - 1), 8); } } else { - for (i = 0; i < block_h; i++) { + for (i=0; i<block_h; i++) { memcpy(dest_cb + i*uvlinesize, h->mb + 128 + i*4, 8); memcpy(dest_cr + i*uvlinesize, h->mb + 160 + i*4, 8); } @@ -2373,32 +2372,36 @@ static void implicit_weight_table(H264Context *h, int field){ * instantaneous decoder refresh. */ static void idr(H264Context *h){ + int i; ff_h264_remove_all_refs(h); h->prev_frame_num= 0; h->prev_frame_num_offset= 0; - h->prev_poc_msb= + h->prev_poc_msb= 1<<16; h->prev_poc_lsb= 0; + for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) + h->last_pocs[i] = INT_MIN; } /* forget old pics after a seek */ static void flush_dpb(AVCodecContext *avctx){ H264Context *h= avctx->priv_data; int i; - for(i=0; i<MAX_DELAYED_PIC_COUNT; i++) { + for(i=0; i<=MAX_DELAYED_PIC_COUNT; i++) { if(h->delayed_pic[i]) h->delayed_pic[i]->f.reference = 0; h->delayed_pic[i]= NULL; } - for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) - h->last_pocs[i] = INT_MIN; h->outputed_poc=h->next_outputed_poc= INT_MIN; h->prev_interlaced_frame = 1; idr(h); + h->prev_frame_num= -1; if(h->s.current_picture_ptr) h->s.current_picture_ptr->f.reference = 0; h->s.first_field= 0; ff_h264_reset_sei(h); ff_mpeg_flush(avctx); + h->recovery_frame= -1; + h->sync= 0; } static int init_poc(H264Context *h){ @@ -2653,7 +2656,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ s->me.qpel_avg= s->dsp.avg_h264_qpel_pixels_tab; } - first_mb_in_slice= get_ue_golomb(&s->gb); + first_mb_in_slice= get_ue_golomb_long(&s->gb); if(first_mb_in_slice == 0){ //FIXME better field boundary detection if(h0->current_slice && FIELD_PICTURE){ @@ -2719,35 +2722,55 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ s->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p - s->width = 16*s->mb_width - (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1); - if(h->sps.frame_mbs_only_flag) - s->height= 16*s->mb_height - (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1); - else - s->height= 16*s->mb_height - (2<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1); + s->width = 16*s->mb_width; + s->height= 16*s->mb_height; if (s->context_initialized - && ( s->width != s->avctx->width || s->height != s->avctx->height + && ( s->width != s->avctx->coded_width || s->height != s->avctx->coded_height + || s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma + || h->cur_chroma_format_idc != h->sps.chroma_format_idc || av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) { - if(h != h0) { - av_log_missing_feature(s->avctx, "Width/height changing with threads is", 0); + if(h != h0 || (s->avctx->active_thread_type & FF_THREAD_FRAME)) { + av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0); return -1; // width / height changed during parallelized decoding } free_tables(h, 0); flush_dpb(s->avctx); MPV_common_end(s); + h->list_count = 0; } if (!s->context_initialized) { if (h != h0) { av_log(h->s.avctx, AV_LOG_ERROR, "Cannot (re-)initialize context during parallel decoding.\n"); return -1; } - avcodec_set_dimensions(s->avctx, s->width, s->height); + s->avctx->width -= (2>>CHROMA444)*FFMIN(h->sps.crop_right, (8<<CHROMA444)-1); + s->avctx->height -= (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1) * (2 - h->sps.frame_mbs_only_flag); s->avctx->sample_aspect_ratio= h->sps.sar; av_assert0(s->avctx->sample_aspect_ratio.den); + if (s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma || + h->cur_chroma_format_idc != h->sps.chroma_format_idc) { + if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10 && + (h->sps.bit_depth_luma != 9 || !CHROMA422)) { + s->avctx->bits_per_raw_sample = h->sps.bit_depth_luma; + h->cur_chroma_format_idc = h->sps.chroma_format_idc; + h->pixel_shift = h->sps.bit_depth_luma > 8; + + ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma, h->sps.chroma_format_idc); + ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma, h->sps.chroma_format_idc); + s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16; + dsputil_init(&s->dsp, s->avctx); + } else { + av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d chroma_idc: %d\n", + h->sps.bit_depth_luma, h->sps.chroma_format_idc); + return -1; + } + } + if(h->sps.video_signal_type_present_flag){ - s->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; + s->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; if(h->sps.colour_description_present_flag){ s->avctx->color_primaries = h->sps.color_primaries; s->avctx->color_trc = h->sps.color_trc; @@ -2788,10 +2811,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ break; default: if (CHROMA444){ + s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ444P : PIX_FMT_YUV444P; if (s->avctx->colorspace == AVCOL_SPC_RGB) { - s->avctx->pix_fmt = PIX_FMT_GBRP; - } else - s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ444P : PIX_FMT_YUV444P; + s->avctx->pix_fmt = PIX_FMT_GBR24P; + av_log(h->s.avctx, AV_LOG_DEBUG, "Detected GBR colorspace.\n"); + } else if (s->avctx->colorspace == AVCOL_SPC_YCGCO) { + av_log(h->s.avctx, AV_LOG_WARNING, "Detected unsupported YCgCo colorspace.\n"); + } } else if (CHROMA422) { s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ422P : PIX_FMT_YUV422P; }else{ @@ -2834,6 +2860,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ c->sps = h->sps; c->pps = h->pps; c->pixel_shift = h->pixel_shift; + c->cur_chroma_format_idc = h->cur_chroma_format_idc; init_scan_tables(c); clone_tables(c, h, i); } @@ -2854,6 +2881,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if(h->sps.frame_mbs_only_flag){ s->picture_structure= PICT_FRAME; }else{ + if(!h->sps.direct_8x8_inference_flag && slice_type == AV_PICTURE_TYPE_B){ + av_log(h->s.avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n"); + return -1; + } if(get_bits1(&s->gb)) { //field_pic_flag s->picture_structure= PICT_TOP_FIELD + get_bits1(&s->gb); //bottom_field_flag } else { @@ -2865,7 +2896,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if(h0->current_slice == 0){ // Shorten frame num gaps so we don't have to allocate reference frames just to throw them away - if(h->frame_num != h->prev_frame_num) { + if(h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0) { int unwrap_prev_frame_num = h->prev_frame_num, max_frame_num = 1<<h->sps.log2_max_frame_num; if (unwrap_prev_frame_num > h->frame_num) unwrap_prev_frame_num -= max_frame_num; @@ -2879,7 +2910,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } } - while(h->frame_num != h->prev_frame_num && + while(h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && h->frame_num != (h->prev_frame_num+1)%(1<<h->sps.log2_max_frame_num)){ Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL; av_log(h->s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", h->frame_num, h->prev_frame_num); @@ -2927,11 +2958,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ s0->first_field = FIELD_PICTURE; } else { - if (h->nal_ref_idc && - s0->current_picture_ptr->f.reference && - s0->current_picture_ptr->frame_num != h->frame_num) { + if (s0->current_picture_ptr->frame_num != h->frame_num) { /* - * This and previous field were reference, but had + * This and previous field had * different frame_nums. Consider this field first in * pair. Throw away previous field except for reference * purposes. @@ -3015,6 +3044,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->ref_count[1]= h->pps.ref_count[1]; if(h->slice_type_nos != AV_PICTURE_TYPE_I){ + unsigned max= (16<<(s->picture_structure != PICT_FRAME))-1; if(h->slice_type_nos == AV_PICTURE_TYPE_B){ h->direct_spatial_mv_pred= get_bits1(&s->gb); } @@ -3025,18 +3055,18 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if(h->slice_type_nos==AV_PICTURE_TYPE_B) h->ref_count[1]= get_ue_golomb(&s->gb) + 1; - if(h->ref_count[0]-1 > 32-1 || h->ref_count[1]-1 > 32-1){ - av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); - h->ref_count[0]= h->ref_count[1]= 1; - return -1; - } + } + if(h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){ + av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); + h->ref_count[0]= h->ref_count[1]= 1; + return -1; } if(h->slice_type_nos == AV_PICTURE_TYPE_B) h->list_count= 2; else h->list_count= 1; }else - h->list_count= 0; + h->ref_count[1]= h->ref_count[0]= h->list_count= 0; if(!default_ref_list_done){ ff_h264_fill_default_ref_list(h); @@ -3170,8 +3200,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h0->last_slice_type = slice_type; h->slice_num = ++h0->current_slice; - if(h->slice_num >= MAX_SLICES){ - av_log(s->avctx, AV_LOG_ERROR, "Too many slices, increase MAX_SLICES and recompile\n"); + + if(h->slice_num) + h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= s->resync_mb_y; + if ( h0->slice_row[h->slice_num&(MAX_SLICES-1)] + 3 >= s->resync_mb_y + && h0->slice_row[h->slice_num&(MAX_SLICES-1)] <= s->resync_mb_y + && h->slice_num >= MAX_SLICES) { + //in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case + av_log(s->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", h->slice_num, MAX_SLICES); } for(j=0; j<2; j++){ @@ -3661,7 +3697,8 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){ if(s->mb_y >= s->mb_height){ tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits); - if(get_bits_count(&s->gb) == s->gb.size_in_bits ) { + if( get_bits_count(&s->gb) == s->gb.size_in_bits + || get_bits_count(&s->gb) < s->gb.size_in_bits && !(s->avctx->err_recognition & AV_EF_AGGRESSIVE)) { ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask); return 0; @@ -3711,6 +3748,7 @@ static int execute_decode_slices(H264Context *h, int context_count){ hx = h->thread_context[i]; hx->s.err_recognition = avctx->err_recognition; hx->s.error_count = 0; + hx->x264_build= h->x264_build; } avctx->execute(avctx, decode_slice, @@ -3741,7 +3779,12 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ int nals_needed=0; ///< number of NALs that need decoding before the next frame thread starts int nal_index; + h->nal_unit_type= 0; + + if(!s->slice_context_count) + s->slice_context_count= 1; h->max_contexts = s->slice_context_count; + if(!(s->flags2 & CODEC_FLAG2_CHUNKS)){ h->current_slice = 0; if (!s->first_field) @@ -3798,19 +3841,16 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ s->workaround_bugs |= FF_BUG_TRUNCATED; if(!(s->workaround_bugs & FF_BUG_TRUNCATED)){ - while(ptr[dst_length - 1] == 0 && dst_length > 0) + while(dst_length > 0 && ptr[dst_length - 1] == 0) dst_length--; } bit_length= !dst_length ? 0 : (8*dst_length - ff_h264_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", hx->nal_unit_type, buf_index, buf_size, dst_length); + av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d/%d at %d/%d length %d pass %d\n", hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass); } if (h->is_avc && (nalsize != consumed) && nalsize){ - // set trailing bits in the last partial byte to zero - if (bit_length & 7) - ptr[bit_length >> 3] = ptr[bit_length >> 3] & (0xff << 8 - (bit_length & 7)); av_log(h->s.avctx, AV_LOG_DEBUG, "AVC: Consumed only %d bytes instead of %d\n", consumed, nalsize); } @@ -3844,7 +3884,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ 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"); + av_log(h->s.avctx, AV_LOG_ERROR, "Invalid mix of idr and non-idr slices\n"); return -1; } idr(h); // FIXME ensure we don't lose some frames if there is reordering @@ -3857,9 +3897,24 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ if((err = decode_slice_header(hx, h))) break; + if ( h->sei_recovery_frame_cnt >= 0 + && ( h->recovery_frame<0 + || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt)) { + h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) % + (1 << h->sps.log2_max_frame_num); + } + s->current_picture_ptr->f.key_frame |= - (hx->nal_unit_type == NAL_IDR_SLICE) || - (h->sei_recovery_frame_cnt >= 0); + (hx->nal_unit_type == NAL_IDR_SLICE); + + if (h->recovery_frame == h->frame_num) { + s->current_picture_ptr->sync |= 1; + h->recovery_frame = -1; + } + + h->sync |= !!s->current_picture_ptr->f.key_frame; + h->sync |= 3*!!(s->flags2 & CODEC_FLAG2_SHOW_ALL); + s->current_picture_ptr->sync |= h->sync; if (h->current_slice == 1) { if(!(s->flags2 & CODEC_FLAG2_CHUNKS)) { @@ -3922,7 +3977,12 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ break; case NAL_SPS: init_get_bits(&s->gb, ptr, bit_length); - ff_h264_decode_seq_parameter_set(h); + if(ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? (nalsize != consumed) && nalsize : 1)){ + av_log(h->s.avctx, AV_LOG_DEBUG, "SPS decoding failure, trying alternative mode\n"); + if(h->is_avc) av_assert0(next_avc - buf_index + consumed == nalsize); + init_get_bits(&s->gb, &buf[buf_index + 1 - consumed], 8*(next_avc - buf_index + consumed)); + ff_h264_decode_seq_parameter_set(h); + } if (s->flags& CODEC_FLAG_LOW_DELAY || (h->sps.bitstream_restriction_flag && !h->sps.num_reorder_frames)) @@ -3930,23 +3990,6 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ if(avctx->has_b_frames < 2) avctx->has_b_frames= !s->low_delay; - - if (avctx->bits_per_raw_sample != h->sps.bit_depth_luma || - h->cur_chroma_format_idc != h->sps.chroma_format_idc) { - if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10) { - avctx->bits_per_raw_sample = h->sps.bit_depth_luma; - h->cur_chroma_format_idc = h->sps.chroma_format_idc; - h->pixel_shift = h->sps.bit_depth_luma > 8; - - ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma, h->sps.chroma_format_idc); - ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma, h->sps.chroma_format_idc); - s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16; - dsputil_init(&s->dsp, s->avctx); - } else { - av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", h->sps.bit_depth_luma); - return -1; - } - } break; case NAL_PPS: init_get_bits(&s->gb, ptr, bit_length); @@ -4009,15 +4052,15 @@ static int decode_frame(AVCodecContext *avctx, MpegEncContext *s = &h->s; AVFrame *pict = data; int buf_index = 0; + Picture *out; + int i, out_idx; s->flags= avctx->flags; s->flags2= avctx->flags2; /* end of stream, output what is still in the buffers */ - out: if (buf_size == 0) { - Picture *out; - int i, out_idx; + out: s->current_picture_ptr = NULL; @@ -4040,19 +4083,42 @@ static int decode_frame(AVCodecContext *avctx, return buf_index; } + if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){ + int cnt= buf[5]&0x1f; + uint8_t *p= buf+6; + while(cnt--){ + int nalsize= AV_RB16(p) + 2; + if(nalsize > buf_size - (p-buf) || p[2]!=0x67) + goto not_extra; + p += nalsize; + } + cnt = *(p++); + if(!cnt) + goto not_extra; + while(cnt--){ + int nalsize= AV_RB16(p) + 2; + if(nalsize > buf_size - (p-buf) || p[2]!=0x68) + goto not_extra; + p += nalsize; + } + + return ff_h264_decode_extradata(h, buf, buf_size); + } +not_extra: buf_index=decode_nal_units(h, buf, buf_size); if(buf_index < 0) return -1; if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) { - buf_size = 0; + av_assert0(buf_index <= buf_size); goto out; } if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){ - if (avctx->skip_frame >= AVDISCARD_NONREF) - return 0; + if (avctx->skip_frame >= AVDISCARD_NONREF || + buf_size >= 4 && !memcmp("Q264", buf, 4)) + return buf_size; av_log(avctx, AV_LOG_ERROR, "no frame!\n"); return -1; } @@ -4063,13 +4129,10 @@ static int decode_frame(AVCodecContext *avctx, field_end(h, 0); - if (!h->next_output_pic) { - /* Wait for second field. */ - *data_size = 0; - - } else { - *data_size = sizeof(AVFrame); - *pict = *(AVFrame*)h->next_output_pic; + *data_size = 0; /* Wait for second field. */ + if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) { + *data_size = sizeof(AVFrame); + *pict = *(AVFrame*)h->next_output_pic; } } @@ -4117,6 +4180,7 @@ av_cold int ff_h264_decode_end(AVCodecContext *avctx) H264Context *h = avctx->priv_data; MpegEncContext *s = &h->s; + ff_h264_remove_all_refs(h); ff_h264_free_context(h); MPV_common_end(s); @@ -4143,6 +4207,26 @@ static const AVProfile profiles[] = { { FF_PROFILE_UNKNOWN }, }; +static const AVOption h264_options[] = { + {"is_avc", "is avc", offsetof(H264Context, is_avc), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 1, 0}, + {"nal_length_size", "nal_length_size", offsetof(H264Context, nal_length_size), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 4, 0}, + {NULL} +}; + +static const AVClass h264_class = { + "H264 Decoder", + av_default_item_name, + h264_options, + LIBAVUTIL_VERSION_INT, +}; + +static const AVClass h264_vdpau_class = { + "H264 VDPAU Decoder", + av_default_item_name, + h264_options, + LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_h264_decoder = { .name = "h264", .type = AVMEDIA_TYPE_VIDEO, @@ -4158,6 +4242,7 @@ AVCodec ff_h264_decoder = { .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), .update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context), .profiles = NULL_IF_CONFIG_SMALL(profiles), + .priv_class = &h264_class, }; #if CONFIG_H264_VDPAU_DECODER @@ -4174,5 +4259,6 @@ AVCodec ff_h264_vdpau_decoder = { .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"), .pix_fmts = (const enum PixelFormat[]){PIX_FMT_VDPAU_H264, PIX_FMT_NONE}, .profiles = NULL_IF_CONFIG_SMALL(profiles), + .priv_class = &h264_vdpau_class, }; #endif diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 50255389fa..495439f738 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -46,6 +46,8 @@ #define MAX_DELAYED_PIC_COUNT 16 +#define MAX_MBPAIR_SIZE (256*1024) // a tighter bound could be calculated if someone cares about a few bytes + /* Compiling in interlaced support reduces the speed * of progressive decoding by about 2%. */ #define ALLOW_INTERLACE @@ -101,7 +103,7 @@ */ #define DELAYED_PIC_REF 4 -#define QP_MAX_NUM (51 + 2*6) // The maximum supported qp +#define QP_MAX_NUM (51 + 4*6) // The maximum supported qp /* NAL unit types */ enum { @@ -227,7 +229,7 @@ typedef struct PPS{ int transform_8x8_mode; ///< transform_8x8_mode_flag uint8_t scaling_matrix4[6][16]; uint8_t scaling_matrix8[6][64]; - uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table + uint8_t chroma_qp_table[2][QP_MAX_NUM+1]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table int chroma_qp_diff; }PPS; @@ -376,9 +378,9 @@ typedef struct H264Context{ /** * num_ref_idx_l0/1_active_minus1 + 1 */ + uint8_t *list_counts; ///< Array of list_count per MB specifying the slice type unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode unsigned int list_count; - uint8_t *list_counts; ///< Array of list_count per MB specifying the slice type 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 */ @@ -571,6 +573,13 @@ typedef struct H264Context{ * frames. */ int sei_recovery_frame_cnt; + /** + * recovery_frame is the frame_num at which the next frame should + * be fully constructed. + * + * Set to -1 when not expecting a recovery point. + */ + int recovery_frame; int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag @@ -580,10 +589,18 @@ typedef struct H264Context{ int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs int cur_chroma_format_idc; + + int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low + + int sync; ///< did we had a keyframe or recovery point + + uint8_t parse_history[4]; + int parse_history_count; + int parse_last_mb; }H264Context; -extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1]; ///< One chroma qp table for each supported bit depth (8, 9, 10). +extern const uint8_t ff_h264_chroma_qp[5][QP_MAX_NUM+1]; ///< One chroma qp table for each possible bit depth (8-12). /** * Decode SEI @@ -657,11 +674,16 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h); /** * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks. */ -int ff_h264_check_intra_pred_mode(H264Context *h, int mode); +int ff_h264_check_intra16x16_pred_mode(H264Context *h, int mode); + +/** + * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks. + */ +int ff_h264_check_intra_chroma_pred_mode(H264Context *h, int mode); void ff_h264_hl_decode_mb(H264Context *h); int ff_h264_frame_start(H264Context *h); -int ff_h264_decode_extradata(H264Context *h); +int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size); av_cold int ff_h264_decode_init(AVCodecContext *avctx); av_cold int ff_h264_decode_end(AVCodecContext *avctx); av_cold void ff_h264_decode_init_vlc(void); diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index a49ac6d498..cde569bc08 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... cabac decoding * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +26,7 @@ */ #define CABAC 1 +#define UNCHECKED_BITSTREAM_READER 1 #include "config.h" #include "cabac.h" @@ -1695,6 +1696,7 @@ decode_cabac_residual_internal(H264Context *h, DCTELEM *block, } } + #define STORE_BLOCK(type) \ do { \ uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; \ @@ -1738,11 +1740,11 @@ decode_cabac_residual_internal(H264Context *h, DCTELEM *block, } \ } while ( coeff_count ); - if (h->pixel_shift) { - STORE_BLOCK(int32_t) - } else { - STORE_BLOCK(int16_t) - } + if (h->pixel_shift) { + STORE_BLOCK(int32_t) + } else { + STORE_BLOCK(int16_t) + } #ifdef CABAC_ON_STACK h->cabac.range = cc.range ; h->cabac.low = cc.low ; @@ -2040,14 +2042,14 @@ decode_intra_mb: write_back_intra_pred_mode(h); if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1; } else { - h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode ); + h->intra16x16_pred_mode= ff_h264_check_intra16x16_pred_mode( h, h->intra16x16_pred_mode ); if( h->intra16x16_pred_mode < 0 ) return -1; } if(decode_chroma){ h->chroma_pred_mode_table[mb_xy] = pred_mode = decode_cabac_mb_chroma_pre_mode( h ); - pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode ); + pred_mode= ff_h264_check_intra_chroma_pred_mode( h, pred_mode ); if( pred_mode < 0 ) return -1; h->chroma_pred_mode= pred_mode; } else { diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index fdb7ab5709..a782f14698 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... cavlc bitstream decoding * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +26,7 @@ */ #define CABAC 0 +#define UNCHECKED_BITSTREAM_READER 1 #include "internal.h" #include "avcodec.h" @@ -822,12 +823,12 @@ decode_intra_mb: if( ff_h264_check_intra4x4_pred_mode(h) < 0) return -1; }else{ - h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode(h, h->intra16x16_pred_mode); + h->intra16x16_pred_mode= ff_h264_check_intra16x16_pred_mode(h, h->intra16x16_pred_mode); if(h->intra16x16_pred_mode < 0) return -1; } if(decode_chroma){ - pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb)); + pred_mode= ff_h264_check_intra_chroma_pred_mode(h, get_ue_golomb_31(&s->gb)); if(pred_mode < 0) return -1; h->chroma_pred_mode= pred_mode; @@ -1122,12 +1123,15 @@ decode_intra_mb: if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ){ return -1; } - } else if (CHROMA422) { + } else { + const int num_c8x8 = h->sps.chroma_format_idc; + if(cbp&0x30){ for(chroma_idx=0; chroma_idx<2; chroma_idx++) if (decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift), - CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma422_dc_scan, - NULL, 8) < 0) { + CHROMA_DC_BLOCK_INDEX+chroma_idx, + CHROMA422 ? chroma422_dc_scan : chroma_dc_scan, + NULL, 4*num_c8x8) < 0) { return -1; } } @@ -1136,34 +1140,12 @@ decode_intra_mb: 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]]; DCTELEM *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift); - for (i8x8 = 0; i8x8 < 2; i8x8++) { - for (i4x4 = 0; i4x4 < 4; i4x4++) { - const int index = 16 + 16*chroma_idx + 8*i8x8 + i4x4; + for (i8x8=0; i8x8<num_c8x8; i8x8++) { + for (i4x4=0; i4x4<4; i4x4++) { + const int index= 16 + 16*chroma_idx + 8*i8x8 + i4x4; if (decode_residual(h, gb, mb, index, scan + 1, qmul, 15) < 0) return -1; - mb += 16 << pixel_shift; - } - } - } - }else{ - fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1); - fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1); - } - } else /* yuv420 */ { - if(cbp&0x30){ - for(chroma_idx=0; chroma_idx<2; chroma_idx++) - if( decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){ - return -1; - } - } - - 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 + 16*chroma_idx + i4x4; - if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){ - return -1; + mb += 16<<pixel_shift; } } } diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index a953728a12..079c665509 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -89,7 +89,8 @@ static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, for(j=start; j<end; j++){ if (4 * h->ref_list[0][j].frame_num + (h->ref_list[0][j].f.reference & 3) == poc) { int cur_ref= mbafi ? (j-16)^field : j; - map[list][2*old_ref + (rfield^field) + 16] = cur_ref; + if(ref1->mbaff) + map[list][2*old_ref + (rfield^field) + 16] = cur_ref; if(rfield == field || !interl) map[list][old_ref] = cur_ref; break; @@ -252,6 +253,10 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride]; b8_stride = 2+4*s->mb_stride; b4_stride *= 6; + if(IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])){ + mb_type_col[0] &= ~MB_TYPE_INTERLACED; + mb_type_col[1] &= ~MB_TYPE_INTERLACED; + } sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c index be750caa6d..f3a5ff6783 100644 --- a/libavcodec/h264_loopfilter.c +++ b/libavcodec/h264_loopfilter.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... loop filter * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c index eceebebecb..48e085e7c3 100644 --- a/libavcodec/h264_mp4toannexb_bsf.c +++ b/libavcodec/h264_mp4toannexb_bsf.c @@ -2,20 +2,20 @@ * H.264 MP4 to Annex B byte stream format filter * Copyright (c) 2007 Benoit Fouet <benoit.fouet@free.fr> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -63,6 +63,7 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, int32_t nal_size; uint32_t cumul_size = 0; const uint8_t *buf_end = buf + buf_size; + int ret = AVERROR(EINVAL); /* nothing to filter */ if (!avctx->extradata || avctx->extradata_size < 6) { @@ -87,11 +88,7 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, /* 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++; - - if (unit_nb) - pps_seen = 1; + goto pps; } else { sps_seen = 1; } @@ -115,7 +112,7 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, memcpy(out+total_size-unit_size-4, nalu_header, 4); memcpy(out+total_size-unit_size, extradata+2, unit_size); extradata += 2+unit_size; - +pps: if (!unit_nb && !sps_done++) { unit_nb = *extradata++; /* number of pps unit(s) */ if (unit_nb) @@ -141,6 +138,7 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, *poutbuf_size = 0; *poutbuf = NULL; do { + ret= AVERROR(EINVAL); if (buf + ctx->length_size > buf_end) goto fail; @@ -159,15 +157,15 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, /* prepend only to the first type 5 NAL unit of an IDR picture */ if (ctx->first_idr && unit_type == 5) { - if (alloc_and_copy(poutbuf, poutbuf_size, + if ((ret=alloc_and_copy(poutbuf, poutbuf_size, avctx->extradata, avctx->extradata_size, - buf, nal_size) < 0) + buf, nal_size)) < 0) goto fail; ctx->first_idr = 0; } else { - if (alloc_and_copy(poutbuf, poutbuf_size, + if ((ret=alloc_and_copy(poutbuf, poutbuf_size, NULL, 0, - buf, nal_size) < 0) + buf, nal_size)) < 0) goto fail; if (!ctx->first_idr && unit_type == 1) ctx->first_idr = 1; @@ -182,7 +180,7 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, fail: av_freep(poutbuf); *poutbuf_size = 0; - return AVERROR(EINVAL); + return ret; } AVBitStreamFilter ff_h264_mp4toannexb_bsf = { diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h index 2bd4458f0b..85405c1542 100644 --- a/libavcodec/h264_mvpred.h +++ b/libavcodec/h264_mvpred.h @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... motion vector predicion * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -633,7 +633,7 @@ static void fill_decode_caches(H264Context *h, int mb_type){ AV_ZERO32(mv_cache[4 - 1*8]); ref_cache[4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; } - if(ref_cache[4 - 1*8] < 0){ + if(ref_cache[2 - 1*8] < 0 || ref_cache[4 - 1*8] < 0){ if(USES_LIST(topleft_type, list)){ const int b_xy = h->mb2b_xy[topleft_xy] + 3 + b_stride + (h->topleft_partition & 2*b_stride); const int b8_xy= 4*topleft_xy + 1 + (h->topleft_partition & 2); diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index bcaa04a115..c9dea81a49 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... parser * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +25,8 @@ * @author Michael Niedermayer <michaelni@gmx.at> */ +#define UNCHECKED_BITSTREAM_READER 1 + #include "parser.h" #include "h264data.h" #include "golomb.h" @@ -34,30 +36,48 @@ static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size) { - int i; + int i, j; uint32_t state; ParseContext *pc = &(h->s.parse_context); + int next_avc= h->is_avc ? 0 : buf_size; + //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; + if(h->is_avc && !h->nal_length_size) + av_log(h->s.avctx, AV_LOG_ERROR, "AVC-parser: nal length size invalid\n"); + for(i=0; i<buf_size; i++){ + if(i >= next_avc) { + int nalsize = 0; + i = next_avc; + for(j = 0; j < h->nal_length_size; j++) + nalsize = (nalsize << 8) | buf[i++]; + if(nalsize <= 0 || nalsize > buf_size - i){ + av_log(h->s.avctx, AV_LOG_ERROR, "AVC-parser: nal size %d remaining %d\n", nalsize, buf_size - i); + return buf_size; + } + next_avc= i + nalsize; + state= 5; + } + if(state==7){ #if HAVE_FAST_UNALIGNED /* we check i<buf_size instead of i+3/7 because its simpler * and there should be FF_INPUT_BUFFER_PADDING_SIZE bytes at the end */ # if HAVE_FAST_64BIT - while(i<buf_size && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL)) + while(i<next_avc && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL)) i+=8; # else - while(i<buf_size && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U)) + while(i<next_avc && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U)) i+=4; # endif #endif - for(; i<buf_size; i++){ + for(; i<next_avc; i++){ if(!buf[i]){ state=2; break; @@ -75,26 +95,41 @@ static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_si goto found; } }else if(v==1 || v==2 || v==5){ + state+=8; + continue; + } + state= 7; + }else{ + h->parse_history[h->parse_history_count++]= buf[i]; + if(h->parse_history_count>3){ + unsigned int mb, last_mb= h->parse_last_mb; + GetBitContext gb; + + init_get_bits(&gb, h->parse_history, 8*h->parse_history_count); + h->parse_history_count=0; + mb= get_ue_golomb_long(&gb); + last_mb= h->parse_last_mb; + h->parse_last_mb= mb; if(pc->frame_start_found){ - state+=8; - continue; + if(mb <= last_mb) + goto found; }else pc->frame_start_found = 1; + state= 7; } - state= 7; - }else{ - if(buf[i] & 0x80) - goto found; - state= 7; } } pc->state= state; + if(h->is_avc) + return next_avc; return END_NOT_FOUND; found: pc->state=7; pc->frame_start_found= 0; - return i-(state&5); + if(h->is_avc) + return next_avc; + return i-(state&5) - 3*(state>7); } /** @@ -115,6 +150,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, unsigned int slice_type; int state = -1; const uint8_t *ptr; + int q264 = buf_size >=4 && !memcmp("Q264", buf, 4); /* set some sane default values */ s->pict_type = AV_PICTURE_TYPE_I; @@ -163,7 +199,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, s->key_frame = 1; /* fall through */ case NAL_SLICE: - get_ue_golomb(&h->s.gb); // skip first_mb_in_slice + get_ue_golomb_long(&h->s.gb); // skip first_mb_in_slice slice_type = get_ue_golomb_31(&h->s.gb); s->pict_type = golomb_to_pict_type[slice_type % 5]; if (h->sei_recovery_frame_cnt >= 0) { @@ -233,8 +269,10 @@ static inline int parse_nal_units(AVCodecParserContext *s, } buf += consumed; } + if (q264) + return 0; /* didn't find a picture! */ - av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n"); + av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit with size %d\n", buf_size); return -1; } @@ -251,7 +289,13 @@ static int h264_parse(AVCodecParserContext *s, h->got_first = 1; if (avctx->extradata_size) { h->s.avctx = avctx; - ff_h264_decode_extradata(h); + // must be done like in decoder, otherwise opening the parser, + // letting it create extradata and then closing and opening again + // will cause has_b_frames to be always set. + // Note that estimate_timings_from_pts does exactly this. + if (!avctx->has_b_frames) + h->s.low_delay = 1; + ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size); } } @@ -272,6 +316,7 @@ static int h264_parse(AVCodecParserContext *s, } } + if(!h->is_avc){ parse_nal_units(s, avctx, buf, buf_size); if (h->sei_cpb_removal_delay >= 0) { @@ -287,6 +332,7 @@ static int h264_parse(AVCodecParserContext *s, if (s->flags & PARSER_FLAG_ONCE) { s->flags &= PARSER_FLAG_COMPLETE_FRAMES; } + } *poutbuf = buf; *poutbuf_size = buf_size; diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 76bf116a3f..5c21d80265 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... parameter set decoding * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -70,7 +70,7 @@ static const AVRational pixel_aspect[17]={ QP(37,d), QP(37,d), QP(37,d), QP(38,d), QP(38,d), QP(38,d),\ QP(39,d), QP(39,d), QP(39,d), QP(39,d) -const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1] = { +const uint8_t ff_h264_chroma_qp[5][QP_MAX_NUM+1] = { { CHROMA_QP_TABLE_END(8) }, @@ -83,6 +83,19 @@ const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1] = { 6, 7, 8, 9, 10, 11, CHROMA_QP_TABLE_END(10) }, + { + 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + CHROMA_QP_TABLE_END(11) + }, + { + 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + 18,19,20,21, 22, 23, + CHROMA_QP_TABLE_END(12) + }, }; static const uint8_t default_scaling4[2][16]={ @@ -216,7 +229,8 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){ if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) get_bits1(&s->gb); /* low_delay_hrd_flag */ sps->pic_struct_present_flag = get_bits1(&s->gb); - + if(!get_bits_left(&s->gb)) + return 0; sps->bitstream_restriction_flag = get_bits1(&s->gb); if(sps->bitstream_restriction_flag){ get_bits1(&s->gb); /* motion_vectors_over_pic_boundaries_flag */ @@ -227,8 +241,7 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){ sps->num_reorder_frames= get_ue_golomb(&s->gb); get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/ - if(s->gb.size_in_bits < get_bits_count(&s->gb)){ - av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", get_bits_count(&s->gb) - s->gb.size_in_bits); + if(get_bits_left(&s->gb) < 0){ sps->num_reorder_frames=0; sps->bitstream_restriction_flag= 0; } @@ -238,6 +251,10 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){ return -1; } } + if(get_bits_left(&s->gb) < 0){ + av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&s->gb)); + return -1; + } return 0; } @@ -322,17 +339,28 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->profile_idc= profile_idc; sps->constraint_set_flags = constraint_set_flags; sps->level_idc= level_idc; + sps->full_range = -1; memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4)); memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8)); sps->scaling_matrix_present = 0; + sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED if(sps->profile_idc >= 100){ //high profile sps->chroma_format_idc= get_ue_golomb_31(&s->gb); + if (sps->chroma_format_idc > 3U) { + av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc); + goto fail; + } if(sps->chroma_format_idc == 3) sps->residual_color_transform_flag = get_bits1(&s->gb); sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8; sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8; + if (sps->bit_depth_luma > 12U || sps->bit_depth_chroma > 12U) { + av_log(h->s.avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n", + sps->bit_depth_luma, sps->bit_depth_chroma); + goto fail; + } sps->transform_bypass = get_bits1(&s->gb); decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); }else{ @@ -365,7 +393,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ } sps->ref_frame_count= get_ue_golomb_31(&s->gb); - if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count >= 32U){ + if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count > 16U){ av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); goto fail; } @@ -385,10 +413,6 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->mb_aff= 0; sps->direct_8x8_inference_flag= get_bits1(&s->gb); - if(!sps->frame_mbs_only_flag && !sps->direct_8x8_inference_flag){ - av_log(h->s.avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n"); - goto fail; - } #ifndef ALLOW_INTERLACE if(sps->mb_aff) @@ -403,10 +427,17 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->crop_top = get_ue_golomb(&s->gb); sps->crop_bottom= get_ue_golomb(&s->gb); if(sps->crop_left || sps->crop_top){ - av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); + av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ... (left: %d, top: %d)\n", sps->crop_left, sps->crop_top); } if(sps->crop_right >= crop_horizontal_limit || sps->crop_bottom >= crop_vertical_limit){ - av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); + av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, cropping disabled (right: %d, bottom: %d)\n", sps->crop_right, sps->crop_bottom); + /* It is very unlikely that partial cropping will make anybody happy. + * Not cropping at all fixes for example playback of Sisvel 3D streams + * in applications supporting Sisvel 3D. */ + sps->crop_left = + sps->crop_right = + sps->crop_top = + sps->crop_bottom= 0; } }else{ sps->crop_left = @@ -424,7 +455,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->sar.den= 1; if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d\n", + av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d b%d\n", sps_id, sps->profile_idc, sps->level_idc, sps->poc_type, sps->ref_frame_count, @@ -436,7 +467,8 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->vui_parameters_present_flag ? "VUI" : "", ((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc], sps->timing_info_present_flag ? sps->num_units_in_tick : 0, - sps->timing_info_present_flag ? sps->time_scale : 0 + sps->timing_info_present_flag ? sps->time_scale : 0, + sps->bit_depth_luma ); } @@ -458,6 +490,21 @@ build_qp_table(PPS *pps, int t, int index, const int depth) pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[depth-8][av_clip(i + index, 0, max_qp)]; } +static int more_rbsp_data_in_pps(H264Context *h, PPS *pps) +{ + const SPS *sps = h->sps_buffers[pps->sps_id]; + int profile_idc = sps->profile_idc; + + if ((profile_idc == 66 || profile_idc == 77 || + profile_idc == 88) && (sps->constraint_set_flags & 7)) { + av_log(h->s.avctx, AV_LOG_VERBOSE, + "Current profile doesn't provide more RBSP data in PPS, skipping\n"); + return 0; + } + + return 1; +} + int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){ MpegEncContext * const s = &h->s; unsigned int pps_id= get_ue_golomb(&s->gb); @@ -541,8 +588,7 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){ memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8)); bits_left = bit_length - get_bits_count(&s->gb); - if (bits_left && (bits_left > 8 || - show_bits(&s->gb, bits_left) != 1 << (bits_left - 1))) { + if(bits_left > 0 && more_rbsp_data_in_pps(h, pps)){ pps->transform_8x8_mode= get_bits1(&s->gb); 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 diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 273c52b475..8432a8a5b6 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... reference picture handling * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +25,7 @@ * @author Michael Niedermayer <michaelni@gmx.at> */ +#include "libavutil/avassert.h" #include "internal.h" #include "dsputil.h" #include "avcodec.h" @@ -300,7 +301,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ void ff_h264_fill_mbaff_ref_list(H264Context *h){ int list, i, j; - for(list=0; list<2; list++){ //FIXME try list_count + for(list=0; list<h->list_count; list++){ for(i=0; i<h->ref_count[list]; i++){ Picture *frame = &h->ref_list[list][i]; Picture *field = &h->ref_list[list][16+2*i]; @@ -478,10 +479,9 @@ static void print_long_term(H264Context *h) { void ff_generate_sliding_window_mmcos(H264Context *h) { MpegEncContext * const s = &h->s; - assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count); h->mmco_index= 0; - if(h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count && + 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->f.reference)) { h->mmco[0].opcode= MMCO_SHORT2UNUSED; h->mmco[0].short_pic_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num; @@ -586,6 +586,8 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ s->current_picture_ptr->frame_num= 0; h->mmco_reset = 1; s->current_picture_ptr->mmco_reset=1; + for (j = 0; j < MAX_DELAYED_PIC_COUNT; j++) + h->last_pocs[j] = INT_MIN; break; default: assert(0); } @@ -623,8 +625,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ } } - if (h->long_ref_count + h->short_ref_count - - (h->short_ref[0] == s->current_picture_ptr) > h->sps.ref_frame_count){ + if (h->long_ref_count + h->short_ref_count > FFMAX(h->sps.ref_frame_count, 1)){ /* We have too many reference frames, probably due to corrupted * stream. Need to discard one frame. Prevents overrun of the @@ -651,6 +652,11 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ print_short_term(h); print_long_term(h); + + if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=1 + (s->picture_structure != PICT_FRAME) && s->current_picture_ptr->f.pict_type == AV_PICTURE_TYPE_I){ + s->current_picture_ptr->sync |= 1; + } + return (h->s.avctx->err_recognition & AV_EF_EXPLODE) ? err : 0; } diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 4f52bbe969..80d70e513c 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... sei decoding * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -169,14 +169,21 @@ int ff_h264_decode_sei(H264Context *h){ type=0; do{ + if (get_bits_left(&s->gb) < 8) + return -1; type+= show_bits(&s->gb, 8); }while(get_bits(&s->gb, 8) == 255); size=0; do{ + if (get_bits_left(&s->gb) < 8) + return -1; size+= show_bits(&s->gb, 8); }while(get_bits(&s->gb, 8) == 255); + if(s->avctx->debug&FF_DEBUG_STARTCODE) + av_log(h->s.avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size); + switch(type){ case SEI_TYPE_PIC_TIMING: // Picture timing SEI if(decode_picture_timing(h) < 0) diff --git a/libavcodec/h264data.h b/libavcodec/h264data.h index 2cfa548624..a5ed069e94 100644 --- a/libavcodec/h264data.h +++ b/libavcodec/h264data.h @@ -2,20 +2,20 @@ * H26L/H264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h264dsp.c b/libavcodec/h264dsp.c index ba967079fb..bd35aa3065 100644 --- a/libavcodec/h264dsp.c +++ b/libavcodec/h264dsp.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003-2010 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h264dsp.h b/libavcodec/h264dsp.h index 7cae215a95..490a936310 100644 --- a/libavcodec/h264dsp.h +++ b/libavcodec/h264dsp.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2003-2010 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h264dsp_template.c b/libavcodec/h264dsp_template.c index 3d99cfcfec..4d5faf01c0 100644 --- a/libavcodec/h264dsp_template.c +++ b/libavcodec/h264dsp_template.c @@ -1,21 +1,21 @@ /* * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder - * Copyright (c) 2003-2010 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2003-2011 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +35,7 @@ static void FUNCC(weight_h264_pixels ## W)(uint8_t *_block, int stride, int heig { \ int y; \ pixel *block = (pixel*)_block; \ - stride /= sizeof(pixel); \ + stride >>= sizeof(pixel)-1; \ offset <<= (log2_denom + (BIT_DEPTH-8)); \ if(log2_denom) offset += 1<<(log2_denom-1); \ for (y = 0; y < height; y++, block += stride) { \ @@ -66,7 +66,7 @@ static void FUNCC(biweight_h264_pixels ## W)(uint8_t *_dst, uint8_t *_src, int s int y; \ pixel *dst = (pixel*)_dst; \ pixel *src = (pixel*)_src; \ - stride /= sizeof(pixel); \ + stride >>= sizeof(pixel)-1; \ offset <<= (BIT_DEPTH-8); \ offset = ((offset + 1) | 1) << log2_denom; \ for (y = 0; y < height; y++, dst += stride, src += stride) { \ @@ -101,12 +101,12 @@ H264_WEIGHT(2) #undef op_scale2 #undef H264_WEIGHT -static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma)(uint8_t *_pix, int xstride, int ystride, int inner_iters, int alpha, int beta, int8_t *tc0) +static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma)(uint8_t *p_pix, int xstride, int ystride, int inner_iters, int alpha, int beta, int8_t *tc0) { - pixel *pix = (pixel*)_pix; + pixel *pix = (pixel*)p_pix; int i, d; - xstride /= sizeof(pixel); - ystride /= sizeof(pixel); + xstride >>= sizeof(pixel)-1; + ystride >>= sizeof(pixel)-1; alpha <<= BIT_DEPTH - 8; beta <<= BIT_DEPTH - 8; for( i = 0; i < 4; i++ ) { @@ -162,12 +162,12 @@ static void FUNCC(h264_h_loop_filter_luma_mbaff)(uint8_t *pix, int stride, int a FUNCC(h264_loop_filter_luma)(pix, sizeof(pixel), stride, 2, alpha, beta, tc0); } -static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma_intra)(uint8_t *_pix, int xstride, int ystride, int inner_iters, int alpha, int beta) +static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma_intra)(uint8_t *p_pix, int xstride, int ystride, int inner_iters, int alpha, int beta) { - pixel *pix = (pixel*)_pix; + pixel *pix = (pixel*)p_pix; int d; - xstride /= sizeof(pixel); - ystride /= sizeof(pixel); + xstride >>= sizeof(pixel)-1; + ystride >>= sizeof(pixel)-1; alpha <<= BIT_DEPTH - 8; beta <<= BIT_DEPTH - 8; for( d = 0; d < 4 * inner_iters; d++ ) { @@ -228,14 +228,14 @@ static void FUNCC(h264_h_loop_filter_luma_mbaff_intra)(uint8_t *pix, int stride, FUNCC(h264_loop_filter_luma_intra)(pix, sizeof(pixel), stride, 2, alpha, beta); } -static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma)(uint8_t *_pix, int xstride, int ystride, int inner_iters, int alpha, int beta, int8_t *tc0) +static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma)(uint8_t *p_pix, int xstride, int ystride, int inner_iters, int alpha, int beta, int8_t *tc0) { - pixel *pix = (pixel*)_pix; + pixel *pix = (pixel*)p_pix; int i, d; - xstride /= sizeof(pixel); - ystride /= sizeof(pixel); alpha <<= BIT_DEPTH - 8; beta <<= BIT_DEPTH - 8; + xstride >>= sizeof(pixel)-1; + ystride >>= sizeof(pixel)-1; for( i = 0; i < 4; i++ ) { const int tc = ((tc0[i] - 1) << (BIT_DEPTH - 8)) + 1; if( tc <= 0 ) { @@ -282,12 +282,12 @@ static void FUNCC(h264_h_loop_filter_chroma422_mbaff)(uint8_t *pix, int stride, FUNCC(h264_loop_filter_chroma)(pix, sizeof(pixel), stride, 2, alpha, beta, tc0); } -static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma_intra)(uint8_t *_pix, int xstride, int ystride, int inner_iters, int alpha, int beta) +static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma_intra)(uint8_t *p_pix, int xstride, int ystride, int inner_iters, int alpha, int beta) { - pixel *pix = (pixel*)_pix; + pixel *pix = (pixel*)p_pix; int d; - xstride /= sizeof(pixel); - ystride /= sizeof(pixel); + xstride >>= sizeof(pixel)-1; + ystride >>= sizeof(pixel)-1; alpha <<= BIT_DEPTH - 8; beta <<= BIT_DEPTH - 8; for( d = 0; d < 4 * inner_iters; d++ ) { diff --git a/libavcodec/h264idct.c b/libavcodec/h264idct.c index 1634a00835..7d1ee007bc 100644 --- a/libavcodec/h264idct.c +++ b/libavcodec/h264idct.c @@ -2,20 +2,20 @@ * H.264 IDCT * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c index eba850ac6f..c59976a1d9 100644 --- a/libavcodec/h264idct_template.c +++ b/libavcodec/h264idct_template.c @@ -2,20 +2,20 @@ * H.264 IDCT * Copyright (c) 2004-2011 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -52,7 +52,7 @@ void FUNCC(ff_h264_idct_add)(uint8_t *_dst, DCTELEM *_block, int stride) INIT_CLIP pixel *dst = (pixel*)_dst; dctcoef *block = (dctcoef*)_block; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; block[0] += 1 << 5; @@ -86,7 +86,7 @@ void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, DCTELEM *_block, int stride){ INIT_CLIP pixel *dst = (pixel*)_dst; dctcoef *block = (dctcoef*)_block; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; block[0] += 32; @@ -155,12 +155,12 @@ void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, DCTELEM *_block, int stride){ } // assumes all AC coefs are 0 -void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){ +void FUNCC(ff_h264_idct_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){ int i, j; int dc = (((dctcoef*)block)[0] + 32) >> 6; INIT_CLIP - pixel *dst = (pixel*)_dst; - stride /= sizeof(pixel); + pixel *dst = (pixel*)p_dst; + stride >>= sizeof(pixel)-1; for( j = 0; j < 4; j++ ) { for( i = 0; i < 4; i++ ) @@ -169,12 +169,12 @@ void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){ } } -void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){ +void FUNCC(ff_h264_idct8_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){ int i, j; int dc = (((dctcoef*)block)[0] + 32) >> 6; INIT_CLIP - pixel *dst = (pixel*)_dst; - stride /= sizeof(pixel); + pixel *dst = (pixel*)p_dst; + stride >>= sizeof(pixel)-1; for( j = 0; j < 8; j++ ) { for( i = 0; i < 8; i++ ) @@ -251,13 +251,13 @@ void FUNCC(ff_h264_idct_add8_422)(uint8_t **dest, const int *block_offset, DCTEL * IDCT transforms the 16 dc values and dequantizes them. * @param qmul quantization parameter */ -void FUNCC(ff_h264_luma_dc_dequant_idct)(DCTELEM *_output, DCTELEM *_input, int qmul){ +void FUNCC(ff_h264_luma_dc_dequant_idct)(DCTELEM *p_output, DCTELEM *p_input, int qmul){ #define stride 16 int i; int temp[16]; static const uint8_t x_offset[4]={0, 2*stride, 8*stride, 10*stride}; - dctcoef *input = (dctcoef*)_input; - dctcoef *output = (dctcoef*)_output; + dctcoef *input = (dctcoef*)p_input; + dctcoef *output = (dctcoef*)p_output; for(i=0; i<4; i++){ const int z0= input[4*i+0] + input[4*i+1]; diff --git a/libavcodec/h264pred.c b/libavcodec/h264pred.c index 37a4cf1486..a174b4ca3c 100644 --- a/libavcodec/h264pred.c +++ b/libavcodec/h264pred.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h264pred.h b/libavcodec/h264pred.h index b880446121..599cdb228b 100644 --- a/libavcodec/h264pred.h +++ b/libavcodec/h264pred.h @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/h264pred_template.c b/libavcodec/h264pred_template.c index 19100b69a9..3a1b1cf94e 100644 --- a/libavcodec/h264pred_template.c +++ b/libavcodec/h264pred_template.c @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003-2011 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -31,7 +31,7 @@ static void FUNCC(pred4x4_vertical)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const pixel4 a= AV_RN4PA(src-stride); AV_WN4PA(src+0*stride, a); @@ -42,7 +42,7 @@ static void FUNCC(pred4x4_vertical)(uint8_t *_src, const uint8_t *topright, int static void FUNCC(pred4x4_horizontal)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); AV_WN4PA(src+0*stride, PIXEL_SPLAT_X4(src[-1+0*stride])); AV_WN4PA(src+1*stride, PIXEL_SPLAT_X4(src[-1+1*stride])); AV_WN4PA(src+2*stride, PIXEL_SPLAT_X4(src[-1+2*stride])); @@ -51,7 +51,7 @@ static void FUNCC(pred4x4_horizontal)(uint8_t *_src, const uint8_t *topright, in static void FUNCC(pred4x4_dc)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); 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; const pixel4 a = PIXEL_SPLAT_X4(dc); @@ -64,7 +64,7 @@ static void FUNCC(pred4x4_dc)(uint8_t *_src, const uint8_t *topright, int _strid static void FUNCC(pred4x4_left_dc)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const int dc= ( src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 2) >>2; const pixel4 a = PIXEL_SPLAT_X4(dc); @@ -76,7 +76,7 @@ static void FUNCC(pred4x4_left_dc)(uint8_t *_src, const uint8_t *topright, int _ static void FUNCC(pred4x4_top_dc)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const int dc= ( src[-stride] + src[1-stride] + src[2-stride] + src[3-stride] + 2) >>2; const pixel4 a = PIXEL_SPLAT_X4(dc); @@ -88,7 +88,7 @@ static void FUNCC(pred4x4_top_dc)(uint8_t *_src, const uint8_t *topright, int _s static void FUNCC(pred4x4_128_dc)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const pixel4 a = PIXEL_SPLAT_X4(1<<(BIT_DEPTH-1)); AV_WN4PA(src+0*stride, a); @@ -99,7 +99,7 @@ static void FUNCC(pred4x4_128_dc)(uint8_t *_src, const uint8_t *topright, int _s static void FUNCC(pred4x4_127_dc)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const pixel4 a = PIXEL_SPLAT_X4((1<<(BIT_DEPTH-1))-1); AV_WN4PA(src+0*stride, a); @@ -110,7 +110,7 @@ static void FUNCC(pred4x4_127_dc)(uint8_t *_src, const uint8_t *topright, int _s static void FUNCC(pred4x4_129_dc)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const pixel4 a = PIXEL_SPLAT_X4((1<<(BIT_DEPTH-1))+1); AV_WN4PA(src+0*stride, a); @@ -146,7 +146,7 @@ static void FUNCC(pred4x4_129_dc)(uint8_t *_src, const uint8_t *topright, int _s static void FUNCC(pred4x4_down_right)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const int lt= src[-1-1*stride]; LOAD_TOP_EDGE LOAD_LEFT_EDGE @@ -172,7 +172,7 @@ static void FUNCC(pred4x4_down_right)(uint8_t *_src, const uint8_t *topright, in static void FUNCC(pred4x4_down_left)(uint8_t *_src, const uint8_t *_topright, int _stride){ pixel *src = (pixel*)_src; const pixel *topright = (const pixel*)_topright; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); LOAD_TOP_EDGE LOAD_TOP_RIGHT_EDGE // LOAD_LEFT_EDGE @@ -197,7 +197,7 @@ static void FUNCC(pred4x4_down_left)(uint8_t *_src, const uint8_t *_topright, in static void FUNCC(pred4x4_vertical_right)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const int lt= src[-1-1*stride]; LOAD_TOP_EDGE LOAD_LEFT_EDGE @@ -223,7 +223,7 @@ static void FUNCC(pred4x4_vertical_right)(uint8_t *_src, const uint8_t *topright static void FUNCC(pred4x4_vertical_left)(uint8_t *_src, const uint8_t *_topright, int _stride){ pixel *src = (pixel*)_src; const pixel *topright = (const pixel*)_topright; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); LOAD_TOP_EDGE LOAD_TOP_RIGHT_EDGE @@ -247,7 +247,7 @@ static void FUNCC(pred4x4_vertical_left)(uint8_t *_src, const uint8_t *_topright static void FUNCC(pred4x4_horizontal_up)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); LOAD_LEFT_EDGE src[0+0*stride]=(l0 + l1 + 1)>>1; @@ -270,7 +270,7 @@ static void FUNCC(pred4x4_horizontal_up)(uint8_t *_src, const uint8_t *topright, static void FUNCC(pred4x4_horizontal_down)(uint8_t *_src, const uint8_t *topright, int _stride){ pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const int lt= src[-1-1*stride]; LOAD_TOP_EDGE LOAD_LEFT_EDGE @@ -296,7 +296,7 @@ static void FUNCC(pred4x4_horizontal_down)(uint8_t *_src, const uint8_t *toprigh static void FUNCC(pred16x16_vertical)(uint8_t *_src, int _stride){ int i; pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const pixel4 a = AV_RN4PA(((pixel4*)(src-stride))+0); const pixel4 b = AV_RN4PA(((pixel4*)(src-stride))+1); const pixel4 c = AV_RN4PA(((pixel4*)(src-stride))+2); @@ -313,7 +313,7 @@ static void FUNCC(pred16x16_vertical)(uint8_t *_src, int _stride){ static void FUNCC(pred16x16_horizontal)(uint8_t *_src, int stride){ int i; pixel *src = (pixel*)_src; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; for(i=0; i<16; i++){ const pixel4 a = PIXEL_SPLAT_X4(src[-1+i*stride]); @@ -338,7 +338,7 @@ static void FUNCC(pred16x16_dc)(uint8_t *_src, int stride){ int i, dc=0; pixel *src = (pixel*)_src; pixel4 dcsplat; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; for(i=0;i<16; i++){ dc+= src[-1+i*stride]; @@ -356,7 +356,7 @@ static void FUNCC(pred16x16_left_dc)(uint8_t *_src, int stride){ int i, dc=0; pixel *src = (pixel*)_src; pixel4 dcsplat; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; for(i=0;i<16; i++){ dc+= src[-1+i*stride]; @@ -370,7 +370,7 @@ static void FUNCC(pred16x16_top_dc)(uint8_t *_src, int stride){ int i, dc=0; pixel *src = (pixel*)_src; pixel4 dcsplat; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; for(i=0;i<16; i++){ dc+= src[i-stride]; @@ -384,7 +384,7 @@ static void FUNCC(pred16x16_top_dc)(uint8_t *_src, int stride){ static void FUNCC(pred16x16_##n##_dc)(uint8_t *_src, int stride){\ int i;\ pixel *src = (pixel*)_src;\ - stride /= sizeof(pixel);\ + stride >>= sizeof(pixel)-1;\ PREDICT_16x16_DC(PIXEL_SPLAT_X4(v));\ } @@ -392,12 +392,12 @@ PRED16x16_X(127, (1<<(BIT_DEPTH-1))-1) PRED16x16_X(128, (1<<(BIT_DEPTH-1))+0) PRED16x16_X(129, (1<<(BIT_DEPTH-1))+1) -static inline void FUNCC(pred16x16_plane_compat)(uint8_t *_src, int _stride, const int svq3, const int rv40){ +static inline void FUNCC(pred16x16_plane_compat)(uint8_t *p_src, int p_stride, const int svq3, const int rv40){ int i, j, k; int a; INIT_CLIP - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); const pixel * const src0 = src +7-stride; const pixel * src1 = src +8*stride-1; const pixel * src2 = src1-2*stride; // == src+6*stride-1; @@ -444,7 +444,7 @@ static void FUNCC(pred16x16_plane)(uint8_t *src, int stride){ static void FUNCC(pred8x8_vertical)(uint8_t *_src, int _stride){ int i; pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const pixel4 a= AV_RN4PA(((pixel4*)(src-stride))+0); const pixel4 b= AV_RN4PA(((pixel4*)(src-stride))+1); @@ -470,7 +470,7 @@ static void FUNCC(pred8x16_vertical)(uint8_t *_src, int _stride){ static void FUNCC(pred8x8_horizontal)(uint8_t *_src, int stride){ int i; pixel *src = (pixel*)_src; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; for(i=0; i<8; i++){ const pixel4 a = PIXEL_SPLAT_X4(src[-1+i*stride]); @@ -495,7 +495,7 @@ static void FUNCC(pred8x8_##n##_dc)(uint8_t *_src, int stride){\ int i;\ const pixel4 a = PIXEL_SPLAT_X4(v);\ pixel *src = (pixel*)_src;\ - stride /= sizeof(pixel);\ + stride >>= sizeof(pixel)-1;\ for(i=0; i<8; i++){\ AV_WN4PA(((pixel4*)(src+i*stride))+0, a);\ AV_WN4PA(((pixel4*)(src+i*stride))+1, a);\ @@ -516,7 +516,7 @@ static void FUNCC(pred8x8_left_dc)(uint8_t *_src, int stride){ int dc0, dc2; pixel4 dc0splat, dc2splat; pixel *src = (pixel*)_src; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; dc0=dc2=0; for(i=0;i<4; i++){ @@ -546,7 +546,7 @@ static void FUNCC(pred8x8_top_dc)(uint8_t *_src, int stride){ int dc0, dc1; pixel4 dc0splat, dc1splat; pixel *src = (pixel*)_src; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; dc0=dc1=0; for(i=0;i<4; i++){ @@ -592,7 +592,7 @@ static void FUNCC(pred8x8_dc)(uint8_t *_src, int stride){ int dc0, dc1, dc2; pixel4 dc0splat, dc1splat, dc2splat, dc3splat; pixel *src = (pixel*)_src; - stride /= sizeof(pixel); + stride >>= sizeof(pixel)-1; dc0=dc1=dc2=0; for(i=0;i<4; i++){ @@ -657,6 +657,7 @@ static void FUNCC(pred8x16_dc)(uint8_t *_src, int stride){ } } +//the following 4 function should not be optimized! static void FUNC(pred8x8_mad_cow_dc_l0t)(uint8_t *src, int stride){ FUNCC(pred8x8_top_dc)(src, stride); FUNCC(pred4x4_dc)(src, NULL, stride); @@ -706,7 +707,7 @@ static void FUNCC(pred8x8_plane)(uint8_t *_src, int _stride){ int a; INIT_CLIP pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); const pixel * const src0 = src +3-stride; const pixel * src1 = src +4*stride-1; const pixel * src2 = src1-2*stride; // == src+2*stride-1; @@ -818,32 +819,32 @@ static void FUNCC(pred8x16_plane)(uint8_t *_src, int _stride){ static void FUNCC(pred8x8l_128_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride) { pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); PREDICT_8x8_DC(PIXEL_SPLAT_X4(1<<(BIT_DEPTH-1))); } static void FUNCC(pred8x8l_left_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride) { pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); PREDICT_8x8_LOAD_LEFT; const pixel4 dc = PIXEL_SPLAT_X4((l0+l1+l2+l3+l4+l5+l6+l7+4) >> 3); PREDICT_8x8_DC(dc); } -static void FUNCC(pred8x8l_top_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride) +static void FUNCC(pred8x8l_top_dc)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride) { - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); PREDICT_8x8_LOAD_TOP; const pixel4 dc = PIXEL_SPLAT_X4((t0+t1+t2+t3+t4+t5+t6+t7+4) >> 3); PREDICT_8x8_DC(dc); } -static void FUNCC(pred8x8l_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride) +static void FUNCC(pred8x8l_dc)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride) { - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); PREDICT_8x8_LOAD_LEFT; PREDICT_8x8_LOAD_TOP; @@ -851,10 +852,10 @@ static void FUNCC(pred8x8l_dc)(uint8_t *_src, int has_topleft, int has_topright, +t0+t1+t2+t3+t4+t5+t6+t7+8) >> 4); PREDICT_8x8_DC(dc); } -static void FUNCC(pred8x8l_horizontal)(uint8_t *_src, int has_topleft, int has_topright, int _stride) +static void FUNCC(pred8x8l_horizontal)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride) { - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); pixel4 a; PREDICT_8x8_LOAD_LEFT; @@ -868,7 +869,7 @@ static void FUNCC(pred8x8l_vertical)(uint8_t *_src, int has_topleft, int has_top { int y; pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + int stride = _stride>>(sizeof(pixel)-1); pixel4 a, b; PREDICT_8x8_LOAD_TOP; @@ -887,10 +888,10 @@ static void FUNCC(pred8x8l_vertical)(uint8_t *_src, int has_topleft, int has_top AV_WN4PA(((pixel4*)(src+y*stride))+1, b); } } -static void FUNCC(pred8x8l_down_left)(uint8_t *_src, int has_topleft, int has_topright, int _stride) +static void FUNCC(pred8x8l_down_left)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride) { - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); PREDICT_8x8_LOAD_TOP; PREDICT_8x8_LOAD_TOPRIGHT; SRC(0,0)= (t0 + 2*t1 + t2 + 2) >> 2; @@ -909,10 +910,10 @@ static void FUNCC(pred8x8l_down_left)(uint8_t *_src, int has_topleft, int has_to SRC(6,7)=SRC(7,6)= (t13 + 2*t14 + t15 + 2) >> 2; SRC(7,7)= (t14 + 3*t15 + 2) >> 2; } -static void FUNCC(pred8x8l_down_right)(uint8_t *_src, int has_topleft, int has_topright, int _stride) +static void FUNCC(pred8x8l_down_right)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride) { - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); PREDICT_8x8_LOAD_TOP; PREDICT_8x8_LOAD_LEFT; PREDICT_8x8_LOAD_TOPLEFT; @@ -932,10 +933,10 @@ static void FUNCC(pred8x8l_down_right)(uint8_t *_src, int has_topleft, int has_t SRC(6,0)=SRC(7,1)= (t4 + 2*t5 + t6 + 2) >> 2; SRC(7,0)= (t5 + 2*t6 + t7 + 2) >> 2; } -static void FUNCC(pred8x8l_vertical_right)(uint8_t *_src, int has_topleft, int has_topright, int _stride) +static void FUNCC(pred8x8l_vertical_right)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride) { - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); PREDICT_8x8_LOAD_TOP; PREDICT_8x8_LOAD_LEFT; PREDICT_8x8_LOAD_TOPLEFT; @@ -962,10 +963,10 @@ static void FUNCC(pred8x8l_vertical_right)(uint8_t *_src, int has_topleft, int h SRC(7,1)= (t5 + 2*t6 + t7 + 2) >> 2; SRC(7,0)= (t6 + t7 + 1) >> 1; } -static void FUNCC(pred8x8l_horizontal_down)(uint8_t *_src, int has_topleft, int has_topright, int _stride) +static void FUNCC(pred8x8l_horizontal_down)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride) { - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); PREDICT_8x8_LOAD_TOP; PREDICT_8x8_LOAD_LEFT; PREDICT_8x8_LOAD_TOPLEFT; @@ -992,10 +993,10 @@ static void FUNCC(pred8x8l_horizontal_down)(uint8_t *_src, int has_topleft, int SRC(6,0)= (t5 + 2*t4 + t3 + 2) >> 2; SRC(7,0)= (t6 + 2*t5 + t4 + 2) >> 2; } -static void FUNCC(pred8x8l_vertical_left)(uint8_t *_src, int has_topleft, int has_topright, int _stride) +static void FUNCC(pred8x8l_vertical_left)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride) { - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); PREDICT_8x8_LOAD_TOP; PREDICT_8x8_LOAD_TOPRIGHT; SRC(0,0)= (t0 + t1 + 1) >> 1; @@ -1021,10 +1022,10 @@ static void FUNCC(pred8x8l_vertical_left)(uint8_t *_src, int has_topleft, int ha SRC(7,6)= (t10 + t11 + 1) >> 1; SRC(7,7)= (t10 + 2*t11 + t12 + 2) >> 2; } -static void FUNCC(pred8x8l_horizontal_up)(uint8_t *_src, int has_topleft, int has_topright, int _stride) +static void FUNCC(pred8x8l_horizontal_up)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride) { - pixel *src = (pixel*)_src; - int stride = _stride/sizeof(pixel); + pixel *src = (pixel*)p_src; + int stride = p_stride>>(sizeof(pixel)-1); PREDICT_8x8_LOAD_LEFT; SRC(0,0)= (l0 + l1 + 1) >> 1; SRC(1,0)= (l0 + 2*l1 + l2 + 2) >> 2; @@ -1055,11 +1056,11 @@ static void FUNCC(pred8x8l_horizontal_up)(uint8_t *_src, int has_topleft, int ha #undef PL #undef SRC -static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, const DCTELEM *_block, int stride){ +static void FUNCC(pred4x4_vertical_add)(uint8_t *p_pix, const DCTELEM *p_block, int stride){ int i; - pixel *pix = (pixel*)_pix; - const dctcoef *block = (const dctcoef*)_block; - stride /= sizeof(pixel); + pixel *pix = (pixel*)p_pix; + const dctcoef *block = (const dctcoef*)p_block; + stride >>= sizeof(pixel)-1; pix -= stride; for(i=0; i<4; i++){ pixel v = pix[0]; @@ -1072,11 +1073,11 @@ static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, const DCTELEM *_block, in } } -static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, const DCTELEM *_block, int stride){ +static void FUNCC(pred4x4_horizontal_add)(uint8_t *p_pix, const DCTELEM *p_block, int stride){ int i; - pixel *pix = (pixel*)_pix; - const dctcoef *block = (const dctcoef*)_block; - stride /= sizeof(pixel); + pixel *pix = (pixel*)p_pix; + const dctcoef *block = (const dctcoef*)p_block; + stride >>= sizeof(pixel)-1; for(i=0; i<4; i++){ pixel v = pix[-1]; pix[0]= v += block[0]; @@ -1088,11 +1089,11 @@ static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, const DCTELEM *_block, } } -static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, const DCTELEM *_block, int stride){ +static void FUNCC(pred8x8l_vertical_add)(uint8_t *p_pix, const DCTELEM *p_block, int stride){ int i; - pixel *pix = (pixel*)_pix; - const dctcoef *block = (const dctcoef*)_block; - stride /= sizeof(pixel); + pixel *pix = (pixel*)p_pix; + const dctcoef *block = (const dctcoef*)p_block; + stride >>= sizeof(pixel)-1; pix -= stride; for(i=0; i<8; i++){ pixel v = pix[0]; @@ -1109,11 +1110,11 @@ static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, const DCTELEM *_block, i } } -static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_pix, const DCTELEM *_block, int stride){ +static void FUNCC(pred8x8l_horizontal_add)(uint8_t *p_pix, const DCTELEM *p_block, int stride){ int i; - pixel *pix = (pixel*)_pix; - const dctcoef *block = (const dctcoef*)_block; - stride /= sizeof(pixel); + pixel *pix = (pixel*)p_pix; + const dctcoef *block = (const dctcoef*)p_block; + stride >>= sizeof(pixel)-1; for(i=0; i<8; i++){ pixel v = pix[-1]; pix[0]= v += block[0]; diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c index 4fb6530d39..fd9fa95f07 100644 --- a/libavcodec/huffman.c +++ b/libavcodec/huffman.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -90,18 +90,19 @@ int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, 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 && - (!(flags & FF_HUFFMAN_FLAG_HNODE_FIRST) || - nodes[j].n0==j-1 || nodes[j].n0==j-2 || - (nodes[j].sym!=HNODE && nodes[j-1].sym!=HNODE)))) + uint32_t cur_count = nodes[i].count + nodes[i+1].count; + // find correct place to insert new node, and + // make space for the new node while at it + for(j = cur_node; j > i + 2; j--){ + if(cur_count > nodes[j-1].count || + (cur_count == nodes[j-1].count && + !(flags & FF_HUFFMAN_FLAG_HNODE_FIRST))) break; - FFSWAP(Node, nodes[j], nodes[j-1]); + nodes[j] = nodes[j - 1]; } + nodes[j].sym = HNODE; + nodes[j].count = cur_count; + nodes[j].n0 = i; cur_node++; } if(build_huff_tree(vlc, nodes, nb_codes*2-2, flags) < 0){ diff --git a/libavcodec/huffman.h b/libavcodec/huffman.h index 5625313ac7..5e0787a5e8 100644 --- a/libavcodec/huffman.h +++ b/libavcodec/huffman.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2007 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index 57b5f32fc8..574daacc0b 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -6,20 +6,20 @@ * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of * the algorithm used * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -152,27 +152,55 @@ static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src } } -static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){ +static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue, int *alpha){ int i; - int r,g,b; + int r,g,b,a; r= *red; g= *green; b= *blue; + a= *alpha; for(i=0; i<FFMIN(w,4); i++){ const int rt= src[i*4+R]; const int gt= src[i*4+G]; const int bt= src[i*4+B]; + const int at= src[i*4+A]; dst[i*4+R]= rt - r; dst[i*4+G]= gt - g; dst[i*4+B]= bt - b; + dst[i*4+A]= at - a; r = rt; g = gt; b = bt; + a = at; } s->dsp.diff_bytes(dst+16, src+16, src+12, w*4-16); *red= src[(w-1)*4+R]; *green= src[(w-1)*4+G]; *blue= src[(w-1)*4+B]; + *alpha= src[(w-1)*4+A]; +} + +static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){ + int i; + int r,g,b; + r= *red; + g= *green; + b= *blue; + for(i=0; i<FFMIN(w,16); i++){ + const int rt= src[i*3+0]; + const int gt= src[i*3+1]; + const int bt= src[i*3+2]; + dst[i*3+0]= rt - r; + dst[i*3+1]= gt - g; + dst[i*3+2]= bt - b; + r = rt; + g = gt; + b = bt; + } + s->dsp.diff_bytes(dst+48, src+48, src+48-3, w*3-48); + *red= src[(w-1)*3+0]; + *green= src[(w-1)*3+1]; + *blue= src[(w-1)*3+2]; } static int read_len_table(uint8_t *dst, GetBitContext *gb){ @@ -433,6 +461,7 @@ static av_cold int decode_init(AVCodecContext *avctx) memset(s->vlc, 0, 3*sizeof(VLC)); avctx->coded_frame= &s->picture; + avcodec_get_frame_defaults(&s->picture); s->interlaced= s->height > 288; s->bgr32=1; @@ -592,6 +621,9 @@ static av_cold int encode_init(AVCodecContext *avctx) s->bitstream_bpp= 16; break; case PIX_FMT_RGB32: + s->bitstream_bpp= 32; + break; + case PIX_FMT_RGB24: s->bitstream_bpp= 24; break; default: @@ -878,26 +910,29 @@ static void decode_bgr_bitstream(HYuvContext *s, int count){ } } -static int encode_bgr_bitstream(HYuvContext *s, int count){ +static inline int encode_bgra_bitstream(HYuvContext *s, int count, int planes){ int i; - if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3*4*count){ + if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*planes*count){ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; } #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; + int g= s->temp[0][planes==3 ? 3*i+1 : 4*i+G];\ + int b= (s->temp[0][planes==3 ? 3*i+2 : 4*i+B] - g) & 0xff;\ + int r= (s->temp[0][planes==3 ? 3*i+0 : 4*i+R] - g) & 0xff;\ + int a= s->temp[0][planes*i+A]; #define STAT3\ s->stats[0][b]++;\ s->stats[1][g]++;\ - s->stats[2][r]++; + s->stats[2][r]++;\ + if(planes==4) s->stats[2][a]++; #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]); + put_bits(&s->pb, s->len[2][r], s->bits[2][r]);\ + if(planes==4) put_bits(&s->pb, s->len[2][a], s->bits[2][a]); if((s->flags&CODEC_FLAG_PASS1) && (s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)){ for(i=0; i<count; i++){ @@ -1366,25 +1401,50 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, const int stride = -p->linesize[0]; const int fake_stride = -fake_ystride; int y; - int leftr, leftg, leftb; + int leftr, leftg, leftb, lefta; + put_bits(&s->pb, 8, lefta= data[A]); put_bits(&s->pb, 8, leftr= data[R]); put_bits(&s->pb, 8, leftg= data[G]); put_bits(&s->pb, 8, leftb= data[B]); - put_bits(&s->pb, 8, 0); - sub_left_prediction_bgr32(s, s->temp[0], data+4, width-1, &leftr, &leftg, &leftb); - encode_bgr_bitstream(s, width-1); + sub_left_prediction_bgr32(s, s->temp[0], data+4, width-1, &leftr, &leftg, &leftb, &lefta); + encode_bgra_bitstream(s, width-1, 4); for(y=1; y<s->height; y++){ uint8_t *dst = data + y*stride; if(s->predictor == PLANE && s->interlaced < y){ s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width*4); - sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb); + sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb, &lefta); + }else{ + sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb, &lefta); + } + encode_bgra_bitstream(s, width, 4); + } + }else if(avctx->pix_fmt == PIX_FMT_RGB24){ + uint8_t *data = p->data[0] + (height-1)*p->linesize[0]; + const int stride = -p->linesize[0]; + const int fake_stride = -fake_ystride; + int y; + int leftr, leftg, leftb; + + put_bits(&s->pb, 8, leftr= data[0]); + put_bits(&s->pb, 8, leftg= data[1]); + put_bits(&s->pb, 8, leftb= data[2]); + put_bits(&s->pb, 8, 0); + + sub_left_prediction_rgb24(s, s->temp[0], data+3, width-1, &leftr, &leftg, &leftb); + encode_bgra_bitstream(s, width-1, 3); + + for(y=1; y<s->height; y++){ + uint8_t *dst = data + y*stride; + if(s->predictor == PLANE && s->interlaced < y){ + s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width*3); + sub_left_prediction_rgb24(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb); }else{ - sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb); + sub_left_prediction_rgb24(s, s->temp[0], dst, width, &leftr, &leftg, &leftb); } - encode_bgr_bitstream(s, width); + encode_bgra_bitstream(s, width, 3); } }else{ av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); @@ -1473,7 +1533,7 @@ AVCodec ff_huffyuv_encoder = { .init = encode_init, .encode = encode_frame, .close = encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE}, + .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), }; #endif @@ -1487,7 +1547,7 @@ AVCodec ff_ffvhuff_encoder = { .init = encode_init, .encode = encode_frame, .close = encode_end, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE}, + .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), }; #endif diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c index e1b0e2e3e9..7a7f76a8a0 100644 --- a/libavcodec/idcinvideo.c +++ b/libavcodec/idcinvideo.c @@ -2,20 +2,20 @@ * id Quake II CIN Video Decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -166,6 +166,7 @@ static av_cold int idcin_decode_init(AVCodecContext *avctx) huff_build_tree(s, i); } + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; diff --git a/libavcodec/iff.c b/libavcodec/iff.c index 41e7b5939f..24167c722c 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -3,20 +3,20 @@ * Copyright (c) 2010 Peter Ross <pross@xvid.org> * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -30,10 +30,28 @@ #include "avcodec.h" #include "get_bits.h" +// TODO: masking bits +typedef enum { + MASK_NONE, + MASK_HAS_MASK, + MASK_HAS_TRANSPARENT_COLOR, + MASK_LASSO +} mask_type; + typedef struct { AVFrame frame; int planesize; uint8_t * planebuf; + uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation + uint32_t *ham_palbuf; ///< HAM decode table + uint32_t *mask_buf; ///< temporary buffer for palette indices + uint32_t *mask_palbuf; ///< masking palette table + unsigned compression; ///< delta compression method used + unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM) + unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise) + unsigned flags; ///< 1 for EHB, 0 is no extra half darkening + unsigned transparency; ///< TODO: transparency color index in palette + unsigned masking; ///< TODO: masking method used int init; // 1 if buffer and palette data already initialized, 0 otherwise } IffContext; @@ -121,7 +139,10 @@ static av_always_inline uint32_t gray2rgb(const uint32_t x) { */ static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) { + IffContext *s = avctx->priv_data; int count, i; + const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata); + int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); if (avctx->bits_per_coded_sample > 8) { av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n"); @@ -130,10 +151,15 @@ static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) count = 1 << avctx->bits_per_coded_sample; // If extradata is smaller than actually needed, fill the remaining with black. - count = FFMIN(avctx->extradata_size / 3, count); + count = FFMIN(palette_size / 3, count); if (count) { for (i=0; i < count; i++) { - pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 ); + pal[i] = 0xFF000000 | AV_RB24(palette + i*3); + } + if (s->flags && count >= 32) { // EHB + for (i = 0; i < 32; i++) + pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1; + count = FFMAX(count, 64); } } else { // Create gray-scale color palette for bps < 8 count = 1 << avctx->bits_per_coded_sample; @@ -142,6 +168,141 @@ static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample); } } + if (s->masking == MASK_HAS_MASK) { + memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4); + for (i = 0; i < count; i++) + pal[i] &= 0xFFFFFF; + } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR && + s->transparency < 1 << avctx->bits_per_coded_sample) + pal[s->transparency] &= 0xFFFFFF; + return 0; +} + +/** + * Extracts the IFF extra context and updates internal + * decoder structures. + * + * @param avctx the AVCodecContext where to extract extra context to + * @param avpkt the AVPacket to extract extra context from or NULL to use avctx + * @return 0 in case of success, a negative error code otherwise + */ +static int extract_header(AVCodecContext *const avctx, + const AVPacket *const avpkt) { + const uint8_t *buf; + unsigned buf_size; + IffContext *s = avctx->priv_data; + int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); + + if (avpkt) { + int image_size; + if (avpkt->size < 2) + return AVERROR_INVALIDDATA; + image_size = avpkt->size - AV_RB16(avpkt->data); + buf = avpkt->data; + buf_size = bytestream_get_be16(&buf); + if (buf_size <= 1 || image_size <= 1) { + av_log(avctx, AV_LOG_ERROR, + "Invalid image size received: %u -> image data offset: %d\n", + buf_size, image_size); + return AVERROR_INVALIDDATA; + } + } else { + if (avctx->extradata_size < 2) + return AVERROR_INVALIDDATA; + buf = avctx->extradata; + buf_size = bytestream_get_be16(&buf); + if (buf_size <= 1 || palette_size < 0) { + av_log(avctx, AV_LOG_ERROR, + "Invalid palette size received: %u -> palette data offset: %d\n", + buf_size, palette_size); + return AVERROR_INVALIDDATA; + } + } + + if (buf_size > 8) { + s->compression = bytestream_get_byte(&buf); + s->bpp = bytestream_get_byte(&buf); + s->ham = bytestream_get_byte(&buf); + s->flags = bytestream_get_byte(&buf); + s->transparency = bytestream_get_be16(&buf); + s->masking = bytestream_get_byte(&buf); + if (s->masking == MASK_HAS_MASK) { + if (s->bpp >= 8) { + avctx->pix_fmt = PIX_FMT_RGB32; + av_freep(&s->mask_buf); + av_freep(&s->mask_palbuf); + s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE); + if (!s->mask_buf) + return AVERROR(ENOMEM); + s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE); + if (!s->mask_palbuf) { + av_freep(&s->mask_buf); + return AVERROR(ENOMEM); + } + } + s->bpp++; + } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) { + av_log(avctx, AV_LOG_ERROR, "Masking not supported\n"); + return AVERROR_PATCHWELCOME; + } + if (!s->bpp || s->bpp > 32) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp); + return AVERROR_INVALIDDATA; + } else if (s->ham >= 8) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham); + return AVERROR_INVALIDDATA; + } + + av_freep(&s->ham_buf); + av_freep(&s->ham_palbuf); + + if (s->ham) { + int i, count = FFMIN(palette_size / 3, 1 << s->ham); + int ham_count; + const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata); + + s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE); + if (!s->ham_buf) + return AVERROR(ENOMEM); + + ham_count = 8 * (1 << s->ham); + s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE); + if (!s->ham_palbuf) { + av_freep(&s->ham_buf); + return AVERROR(ENOMEM); + } + + if (count) { // HAM with color palette attached + // prefill with black and palette and set HAM take direct value mask to zero + memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t)); + for (i=0; i < count; i++) { + s->ham_palbuf[i*2+1] = AV_RL24(palette + i*3); + } + count = 1 << s->ham; + } else { // HAM with grayscale color palette + count = 1 << s->ham; + for (i=0; i < count; i++) { + s->ham_palbuf[i*2] = 0; // take direct color value from palette + s->ham_palbuf[i*2+1] = av_le2ne32(gray2rgb((i * 255) >> s->ham)); + } + } + for (i=0; i < count; i++) { + uint32_t tmp = i << (8 - s->ham); + tmp |= tmp >> s->ham; + s->ham_palbuf[(i+count)*2] = 0x00FFFF; // just modify blue color component + s->ham_palbuf[(i+count*2)*2] = 0xFFFF00; // just modify red color component + s->ham_palbuf[(i+count*3)*2] = 0xFF00FF; // just modify green color component + s->ham_palbuf[(i+count)*2+1] = tmp << 16; + s->ham_palbuf[(i+count*2)*2+1] = tmp; + s->ham_palbuf[(i+count*3)*2+1] = tmp << 8; + } + if (s->masking == MASK_HAS_MASK) { + for (i = 0; i < ham_count; i++) + s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000; + } + } + } + return 0; } @@ -151,9 +312,9 @@ static av_cold int decode_init(AVCodecContext *avctx) int err; if (avctx->bits_per_coded_sample <= 8) { - avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 || - avctx->extradata_size) ? PIX_FMT_PAL8 - : PIX_FMT_GRAY8; + int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); + avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) || + (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8; } else if (avctx->bits_per_coded_sample <= 32) { avctx->pix_fmt = PIX_FMT_BGR32; } else { @@ -167,7 +328,12 @@ static av_cold int decode_init(AVCodecContext *avctx) if (!s->planebuf) return AVERROR(ENOMEM); - s->frame.reference = 1; + s->bpp = avctx->bits_per_coded_sample; + avcodec_get_frame_defaults(&s->frame); + + if ((err = extract_header(avctx, NULL)) < 0) + return err; + s->frame.reference = 3; return 0; } @@ -214,6 +380,47 @@ static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int p } while (--buf_size); } +#define DECODE_HAM_PLANE32(x) \ + first = buf[x] << 1; \ + second = buf[(x)+1] << 1; \ + delta &= pal[first++]; \ + delta |= pal[first]; \ + dst[x] = delta; \ + delta &= pal[second++]; \ + delta |= pal[second]; \ + dst[(x)+1] = delta + +/** + * Converts one line of HAM6/8-encoded chunky buffer to 24bpp. + * + * @param dst the destination 24bpp buffer + * @param buf the source 8bpp chunky buffer + * @param pal the HAM decode table + * @param buf_size the plane size in bytes + */ +static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf, + const uint32_t *const pal, unsigned buf_size) +{ + uint32_t delta = 0; + do { + uint32_t first, second; + DECODE_HAM_PLANE32(0); + DECODE_HAM_PLANE32(2); + DECODE_HAM_PLANE32(4); + DECODE_HAM_PLANE32(6); + buf += 8; + dst += 8; + } while (--buf_size); +} + +static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf, + const uint32_t *const pal, unsigned width) +{ + do { + *dst++ = pal[*buf++]; + } while (--width); +} + /** * Decode one complete byterun1 encoded line. * @@ -250,11 +457,14 @@ static int decode_frame_ilbm(AVCodecContext *avctx, AVPacket *avpkt) { IffContext *s = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL; + const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0; const uint8_t *buf_end = buf+buf_size; int y, plane, res; + if ((res = extract_header(avctx, avpkt)) < 0) + return res; + if (s->init) { if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); @@ -269,21 +479,55 @@ static int decode_frame_ilbm(AVCodecContext *avctx, } s->init = 1; - if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved + if (avctx->codec_tag == MKTAG('A','C','B','M')) { + if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { + memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]); + for (plane = 0; plane < s->bpp; plane++) { + for(y = 0; y < avctx->height && buf < buf_end; y++ ) { + uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; + decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane); + buf += s->planesize; + } + } + } else if (s->ham) { // HAM to PIX_FMT_BGR32 + memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]); + for(y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]]; + memset(s->ham_buf, 0, s->planesize * 8); + for (plane = 0; plane < s->bpp; plane++) { + const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize; + if (start >= buf_end) + break; + decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane); + } + decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize); + } + } + } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { for(y = 0; y < avctx->height; y++ ) { uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; memset(row, 0, avctx->width); - for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) { + for (plane = 0; plane < s->bpp && buf < buf_end; plane++) { decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane); buf += s->planesize; } } + } else if (s->ham) { // HAM to PIX_FMT_BGR32 + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; + memset(s->ham_buf, 0, s->planesize * 8); + for (plane = 0; plane < s->bpp && buf < buf_end; plane++) { + decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane); + buf += s->planesize; + } + decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize); + } } else { // PIX_FMT_BGR32 for(y = 0; y < avctx->height; y++ ) { uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]]; memset(row, 0, avctx->width << 2); - for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) { + for (plane = 0; plane < s->bpp && buf < buf_end; plane++) { decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane); buf += s->planesize; } @@ -295,6 +539,13 @@ static int decode_frame_ilbm(AVCodecContext *avctx, memcpy(row, buf, FFMIN(avctx->width, buf_end - buf)); buf += avctx->width + (avctx->width % 2); // padding if odd } + } else { // IFF-PBM: HAM to PIX_FMT_BGR32 + for (y = 0; y < avctx->height; y++) { + uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; + memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf)); + buf += avctx->width + (avctx->width & 1); // padding if odd + decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width); + } } *data_size = sizeof(AVFrame); @@ -307,11 +558,13 @@ static int decode_frame_byterun1(AVCodecContext *avctx, AVPacket *avpkt) { IffContext *s = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL; + const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0; const uint8_t *buf_end = buf+buf_size; int y, plane, res; + if ((res = extract_header(avctx, avpkt)) < 0) + return res; if (s->init) { if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); @@ -320,9 +573,12 @@ static int decode_frame_byterun1(AVCodecContext *avctx, } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; - } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) { + } else if (avctx->pix_fmt == PIX_FMT_PAL8) { if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0) return res; + } else if (avctx->pix_fmt == PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) { + if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0) + return res; } s->init = 1; @@ -331,26 +587,52 @@ static int decode_frame_byterun1(AVCodecContext *avctx, for(y = 0; y < avctx->height ; y++ ) { uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; memset(row, 0, avctx->width); - for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { + for (plane = 0; plane < s->bpp; plane++) { buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end); decodeplane8(row, s->planebuf, s->planesize, plane); } } + } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to PIX_FMT_BGR32 + for (y = 0; y < avctx->height ; y++ ) { + uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]]; + memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t)); + for (plane = 0; plane < s->bpp; plane++) { + buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end); + decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane); + } + lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width); + } + } else if (s->ham) { // HAM to PIX_FMT_BGR32 + for (y = 0; y < avctx->height ; y++) { + uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]]; + memset(s->ham_buf, 0, s->planesize * 8); + for (plane = 0; plane < s->bpp; plane++) { + buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end); + decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane); + } + decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize); + } } else { //PIX_FMT_BGR32 for(y = 0; y < avctx->height ; y++ ) { uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]]; memset(row, 0, avctx->width << 2); - for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) { + for (plane = 0; plane < s->bpp; plane++) { buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end); decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane); } } } - } else { + } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM for(y = 0; y < avctx->height ; y++ ) { uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]]; buf += decode_byterun(row, avctx->width, buf, buf_end); } + } else { // IFF-PBM: HAM to PIX_FMT_BGR32 + for (y = 0; y < avctx->height ; y++) { + uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]]; + buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end); + decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width); + } } *data_size = sizeof(AVFrame); @@ -364,6 +646,8 @@ static av_cold int decode_end(AVCodecContext *avctx) if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); av_freep(&s->planebuf); + av_freep(&s->ham_buf); + av_freep(&s->ham_palbuf); return 0; } diff --git a/libavcodec/iirfilter.c b/libavcodec/iirfilter.c index 34d3962807..4785a7c7c2 100644 --- a/libavcodec/iirfilter.c +++ b/libavcodec/iirfilter.c @@ -2,20 +2,20 @@ * IIR filter * Copyright (c) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/iirfilter.h b/libavcodec/iirfilter.h index bc65a96b59..b29e035811 100644 --- a/libavcodec/iirfilter.h +++ b/libavcodec/iirfilter.h @@ -2,20 +2,20 @@ * IIR filter * Copyright (c) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/imc.c b/libavcodec/imc.c index ff8e31e9e6..d3b8bf5a12 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -4,20 +4,20 @@ * Copyright (c) 2006 Benjamin Larsson * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/imcdata.h b/libavcodec/imcdata.h index 8e99391d61..64e7c7185e 100644 --- a/libavcodec/imcdata.h +++ b/libavcodec/imcdata.h @@ -4,20 +4,20 @@ * Copyright (c) 2006 Benjamin Larsson * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/imgconvert.c b/libavcodec/imgconvert.c index 90c9b7b255..058a0d5c48 100644 --- a/libavcodec/imgconvert.c +++ b/libavcodec/imgconvert.c @@ -2,20 +2,20 @@ * Misc image conversion routines * Copyright (c) 2001, 2002, 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -47,10 +47,6 @@ #define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ #define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ -#define FF_PIXEL_PLANAR 0 /**< each channel has one component in AVPicture */ -#define FF_PIXEL_PACKED 1 /**< only one components containing all the channels */ -#define FF_PIXEL_PALETTE 2 /**< one components containing indexes for a palette */ - #if HAVE_MMX && HAVE_YASM #define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx #define deinterlace_line ff_deinterlace_line_mmx @@ -60,351 +56,235 @@ #endif typedef struct PixFmtInfo { - uint8_t nb_channels; /**< number of channels (including alpha) */ uint8_t color_type; /**< color type (see FF_COLOR_xxx constants) */ - uint8_t pixel_type; /**< pixel storage type (see FF_PIXEL_xxx constants) */ uint8_t is_alpha : 1; /**< true if alpha can be specified */ - uint8_t depth; /**< bit depth of the color components */ + uint8_t padded_size; /**< padded size in bits if different from the non-padded size */ } PixFmtInfo; /* this table gives more information about formats */ static const PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { /* YUV formats */ [PIX_FMT_YUV420P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_YUV422P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_YUV444P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_YUYV422] = { - .nb_channels = 1, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_UYVY422] = { - .nb_channels = 1, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_YUV410P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_YUV411P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_YUV440P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_YUV420P16LE] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, }, [PIX_FMT_YUV422P16LE] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, }, [PIX_FMT_YUV444P16LE] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, }, [PIX_FMT_YUV420P16BE] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, }, [PIX_FMT_YUV422P16BE] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, }, [PIX_FMT_YUV444P16BE] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, }, - /* YUV formats with alpha plane */ [PIX_FMT_YUVA420P] = { - .nb_channels = 4, + .is_alpha = 1, + .color_type = FF_COLOR_YUV, + }, + + [PIX_FMT_YUVA444P] = { + .is_alpha = 1, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, /* JPEG YUV */ [PIX_FMT_YUVJ420P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_YUVJ422P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_YUVJ444P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_YUVJ440P] = { - .nb_channels = 3, .color_type = FF_COLOR_YUV_JPEG, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, /* RGB formats */ [PIX_FMT_RGB24] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_BGR24] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_ARGB] = { - .nb_channels = 4, .is_alpha = 1, + .is_alpha = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_RGB48BE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 16, }, [PIX_FMT_RGB48LE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 16, + }, + [PIX_FMT_RGBA64BE] = { + .is_alpha = 1, + .color_type = FF_COLOR_RGB, + }, + [PIX_FMT_RGBA64LE] = { + .is_alpha = 1, + .color_type = FF_COLOR_RGB, }, [PIX_FMT_RGB565BE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, }, [PIX_FMT_RGB565LE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, }, [PIX_FMT_RGB555BE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, + .padded_size = 16, }, [PIX_FMT_RGB555LE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, + .padded_size = 16, }, [PIX_FMT_RGB444BE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, + .padded_size = 16, }, [PIX_FMT_RGB444LE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, + .padded_size = 16, }, /* gray / mono formats */ [PIX_FMT_GRAY16BE] = { - .nb_channels = 1, .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, }, [PIX_FMT_GRAY16LE] = { - .nb_channels = 1, .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 16, }, [PIX_FMT_GRAY8] = { - .nb_channels = 1, .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, + }, + [PIX_FMT_GRAY8A] = { + .is_alpha = 1, + .color_type = FF_COLOR_GRAY, }, [PIX_FMT_MONOWHITE] = { - .nb_channels = 1, .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 1, }, [PIX_FMT_MONOBLACK] = { - .nb_channels = 1, .color_type = FF_COLOR_GRAY, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 1, }, /* paletted formats */ [PIX_FMT_PAL8] = { - .nb_channels = 4, .is_alpha = 1, + .is_alpha = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PALETTE, - .depth = 8, }, [PIX_FMT_UYYVYY411] = { - .nb_channels = 1, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_ABGR] = { - .nb_channels = 4, .is_alpha = 1, + .is_alpha = 1, + .color_type = FF_COLOR_RGB, + }, + [PIX_FMT_BGR48BE] = { + .color_type = FF_COLOR_RGB, + }, + [PIX_FMT_BGR48LE] = { + .color_type = FF_COLOR_RGB, + }, + [PIX_FMT_BGRA64BE] = { + .is_alpha = 1, + .color_type = FF_COLOR_RGB, + }, + [PIX_FMT_BGRA64LE] = { + .is_alpha = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_BGR565BE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, + .padded_size = 16, }, [PIX_FMT_BGR565LE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, + .padded_size = 16, }, [PIX_FMT_BGR555BE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, + .padded_size = 16, }, [PIX_FMT_BGR555LE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 5, + .padded_size = 16, }, [PIX_FMT_BGR444BE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, + .padded_size = 16, }, [PIX_FMT_BGR444LE] = { - .nb_channels = 3, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, + .padded_size = 16, }, [PIX_FMT_RGB8] = { - .nb_channels = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_RGB4] = { - .nb_channels = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, }, [PIX_FMT_RGB4_BYTE] = { - .nb_channels = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, + .padded_size = 8, }, [PIX_FMT_BGR8] = { - .nb_channels = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_BGR4] = { - .nb_channels = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 4, }, [PIX_FMT_BGR4_BYTE] = { - .nb_channels = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, + .padded_size = 8, }, [PIX_FMT_NV12] = { - .nb_channels = 2, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_NV21] = { - .nb_channels = 2, .color_type = FF_COLOR_YUV, - .pixel_type = FF_PIXEL_PLANAR, - .depth = 8, }, [PIX_FMT_BGRA] = { - .nb_channels = 4, .is_alpha = 1, + .is_alpha = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, [PIX_FMT_RGBA] = { - .nb_channels = 4, .is_alpha = 1, + .is_alpha = 1, .color_type = FF_COLOR_RGB, - .pixel_type = FF_PIXEL_PACKED, - .depth = 8, }, }; @@ -460,6 +340,16 @@ int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, } } + switch (pix_fmt) { + case PIX_FMT_RGB8: + case PIX_FMT_BGR8: + case PIX_FMT_RGB4_BYTE: + case PIX_FMT_BGR4_BYTE: + case PIX_FMT_GRAY8: + // do not include palette for these pseudo-paletted formats + return size; + } + if (desc->flags & PIX_FMT_PAL) memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4); @@ -477,28 +367,55 @@ int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height) return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); } +static int get_pix_fmt_depth(int *min, int *max, enum PixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; + int i; + + if (!desc->nb_components) { + *min = *max = 0; + return AVERROR(EINVAL); + } + + *min = INT_MAX, *max = -INT_MAX; + for (i = 0; i < desc->nb_components; i++) { + *min = FFMIN(desc->comp[i].depth_minus1+1, *min); + *max = FFMAX(desc->comp[i].depth_minus1+1, *max); + } + return 0; +} + int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt, int has_alpha) { const PixFmtInfo *pf, *ps; - const AVPixFmtDescriptor *src_desc = &av_pix_fmt_descriptors[src_pix_fmt]; - const AVPixFmtDescriptor *dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt]; - int loss; + const AVPixFmtDescriptor *src_desc; + const AVPixFmtDescriptor *dst_desc; + int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth; + int ret, loss; + + if (dst_pix_fmt >= PIX_FMT_NB || dst_pix_fmt <= PIX_FMT_NONE) + return ~0; + src_desc = &av_pix_fmt_descriptors[src_pix_fmt]; + dst_desc = &av_pix_fmt_descriptors[dst_pix_fmt]; ps = &pix_fmt_info[src_pix_fmt]; /* compute loss */ loss = 0; - pf = &pix_fmt_info[dst_pix_fmt]; - if (pf->depth < ps->depth || - ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE || - dst_pix_fmt == PIX_FMT_BGR555BE || dst_pix_fmt == PIX_FMT_BGR555LE) && - (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE || - src_pix_fmt == PIX_FMT_BGR565BE || src_pix_fmt == PIX_FMT_BGR565LE))) + + if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0) + return ret; + if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0) + return ret; + if (dst_min_depth < src_min_depth || + dst_max_depth < src_max_depth) loss |= FF_LOSS_DEPTH; if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w || dst_desc->log2_chroma_h > src_desc->log2_chroma_h) loss |= FF_LOSS_RESOLUTION; + + pf = &pix_fmt_info[dst_pix_fmt]; switch(pf->color_type) { case FF_COLOR_RGB: if (ps->color_type != FF_COLOR_RGB && @@ -530,95 +447,44 @@ int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_ loss |= FF_LOSS_CHROMA; if (!pf->is_alpha && (ps->is_alpha && has_alpha)) loss |= FF_LOSS_ALPHA; - if (pf->pixel_type == FF_PIXEL_PALETTE && - (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY)) + if (dst_pix_fmt == PIX_FMT_PAL8 && + (src_pix_fmt != PIX_FMT_PAL8 && (ps->color_type != FF_COLOR_GRAY || (ps->is_alpha && has_alpha)))) loss |= FF_LOSS_COLORQUANT; + return loss; } static int avg_bits_per_pixel(enum PixelFormat pix_fmt) { - int bits; - const PixFmtInfo *pf; + const PixFmtInfo *info = &pix_fmt_info[pix_fmt]; const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; - pf = &pix_fmt_info[pix_fmt]; - switch(pf->pixel_type) { - case FF_PIXEL_PACKED: - switch(pix_fmt) { - case PIX_FMT_YUYV422: - case PIX_FMT_UYVY422: - case PIX_FMT_RGB565BE: - case PIX_FMT_RGB565LE: - case PIX_FMT_RGB555BE: - case PIX_FMT_RGB555LE: - case PIX_FMT_RGB444BE: - case PIX_FMT_RGB444LE: - case PIX_FMT_BGR565BE: - case PIX_FMT_BGR565LE: - case PIX_FMT_BGR555BE: - case PIX_FMT_BGR555LE: - case PIX_FMT_BGR444BE: - case PIX_FMT_BGR444LE: - bits = 16; - break; - case PIX_FMT_UYYVYY411: - bits = 12; - break; - default: - bits = pf->depth * pf->nb_channels; - break; - } - break; - case FF_PIXEL_PLANAR: - if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) { - bits = pf->depth * pf->nb_channels; - } else { - bits = pf->depth + ((2 * pf->depth) >> - (desc->log2_chroma_w + desc->log2_chroma_h)); - } - break; - case FF_PIXEL_PALETTE: - bits = 8; - break; - default: - bits = -1; - break; - } - return bits; + return info->padded_size ? + info->padded_size : av_get_bits_per_pixel(desc); } -static enum PixelFormat avcodec_find_best_pix_fmt1(int64_t pix_fmt_mask, - enum PixelFormat src_pix_fmt, - int has_alpha, - int loss_mask) +enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, + int has_alpha, int *loss_ptr) { - int dist, i, loss, min_dist; enum PixelFormat dst_pix_fmt; + int i; - /* find exact color match with smallest size */ - dst_pix_fmt = PIX_FMT_NONE; - min_dist = 0x7fffffff; - for(i = 0;i < PIX_FMT_NB; i++) { - if (pix_fmt_mask & (1ULL << i)) { - loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask; - if (loss == 0) { - dist = avg_bits_per_pixel(i); - if (dist < min_dist) { - min_dist = dist; - dst_pix_fmt = i; - } - } - } + if (loss_ptr) /* all losses count (for backward compatibility) */ + *loss_ptr = 0; + + dst_pix_fmt = PIX_FMT_NONE; /* so first iteration doesn't have to be treated special */ + for(i = 0; i< FFMIN(PIX_FMT_NB, 64); i++){ + if (pix_fmt_mask & (1ULL << i)) + dst_pix_fmt = avcodec_find_best_pix_fmt2(dst_pix_fmt, i, src_pix_fmt, has_alpha, loss_ptr); } return dst_pix_fmt; } -enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, - int has_alpha, int *loss_ptr) +enum PixelFormat avcodec_find_best_pix_fmt2(enum PixelFormat dst_pix_fmt1, enum PixelFormat dst_pix_fmt2, + enum PixelFormat src_pix_fmt, int has_alpha, int *loss_ptr) { enum PixelFormat dst_pix_fmt; - int loss_mask, i; + int loss1, loss2, loss_order1, loss_order2, i, loss_mask; static const int loss_mask_order[] = { ~0, /* no loss first */ ~FF_LOSS_ALPHA, @@ -626,22 +492,29 @@ enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelForma ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION), ~FF_LOSS_COLORQUANT, ~FF_LOSS_DEPTH, + ~(FF_LOSS_RESOLUTION | FF_LOSS_DEPTH | FF_LOSS_COLORSPACE | FF_LOSS_ALPHA | + FF_LOSS_COLORQUANT | FF_LOSS_CHROMA), + 0x80000, //non zero entry that combines all loss variants including future additions 0, }; + loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */ + dst_pix_fmt = PIX_FMT_NONE; + loss1 = avcodec_get_pix_fmt_loss(dst_pix_fmt1, src_pix_fmt, has_alpha) & loss_mask; + loss2 = avcodec_get_pix_fmt_loss(dst_pix_fmt2, src_pix_fmt, has_alpha) & loss_mask; + /* try with successive loss */ - i = 0; - for(;;) { - loss_mask = loss_mask_order[i++]; - dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, - has_alpha, loss_mask); - if (dst_pix_fmt >= 0) - goto found; - if (loss_mask == 0) - break; + for(i = 0;loss_mask_order[i] != 0 && dst_pix_fmt == PIX_FMT_NONE;i++) { + loss_order1 = loss1 & loss_mask_order[i]; + loss_order2 = loss2 & loss_mask_order[i]; + + if (loss_order1 == 0 && loss_order2 == 0){ /* use format with smallest depth */ + dst_pix_fmt = avg_bits_per_pixel(dst_pix_fmt2) < avg_bits_per_pixel(dst_pix_fmt1) ? dst_pix_fmt2 : dst_pix_fmt1; + } else if (loss_order1 == 0 || loss_order2 == 0) { /* use format with no loss */ + dst_pix_fmt = loss_order2 ? dst_pix_fmt1 : dst_pix_fmt2; + } } - return PIX_FMT_NONE; - found: + if (loss_ptr) *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); return dst_pix_fmt; @@ -760,11 +633,26 @@ void avpicture_free(AVPicture *picture) } /* return true if yuv planar */ -static inline int is_yuv_planar(const PixFmtInfo *ps) +static inline int is_yuv_planar(enum PixelFormat fmt) { - return (ps->color_type == FF_COLOR_YUV || - ps->color_type == FF_COLOR_YUV_JPEG) && - ps->pixel_type == FF_PIXEL_PLANAR; + const PixFmtInfo *info = &pix_fmt_info[fmt]; + const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[fmt]; + int i; + int planes[4] = { 0 }; + + if (info->color_type != FF_COLOR_YUV && + info->color_type != FF_COLOR_YUV_JPEG) + return 0; + + /* set the used planes */ + for (i = 0; i < desc->nb_components; i++) + planes[desc->comp[i].plane] = 1; + + /* if there is an unused plane, the format is not planar */ + for (i = 0; i < desc->nb_components; i++) + if (!planes[i]) + return 0; + return 1; } int av_picture_crop(AVPicture *dst, const AVPicture *src, @@ -773,15 +661,23 @@ int av_picture_crop(AVPicture *dst, const AVPicture *src, int y_shift; int x_shift; - if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt])) + if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) return -1; y_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_h; x_shift = av_pix_fmt_descriptors[pix_fmt].log2_chroma_w; + if (is_yuv_planar(pix_fmt)) { dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band; dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift); dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift); + } else{ + if(top_band % (1<<y_shift) || left_band % (1<<x_shift)) + return -1; + if(left_band) //FIXME add support for this too + return -1; + dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band; + } dst->linesize[0] = src->linesize[0]; dst->linesize[1] = src->linesize[1]; @@ -800,7 +696,7 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, int i, y; if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || - !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1; + !is_yuv_planar(pix_fmt)) return -1; for (i = 0; i < 3; i++) { x_shift = i ? av_pix_fmt_descriptors[pix_fmt].log2_chroma_w : 0; diff --git a/libavcodec/imgconvert.h b/libavcodec/imgconvert.h index c99e587906..64da317d27 100644 --- a/libavcodec/imgconvert.h +++ b/libavcodec/imgconvert.h @@ -4,20 +4,20 @@ * * Copyright (c) 2008 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/imx_dump_header_bsf.c b/libavcodec/imx_dump_header_bsf.c index 3724daf008..8119809faa 100644 --- a/libavcodec/imx_dump_header_bsf.c +++ b/libavcodec/imx_dump_header_bsf.c @@ -2,20 +2,20 @@ * imx dump header bitstream filter * Copyright (c) 2007 Baptiste Coudurier * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/indeo2.c b/libavcodec/indeo2.c index ecf89cc817..eb58939338 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -2,20 +2,20 @@ * Intel Indeo 2 codec * Copyright (c) 2005 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -146,10 +146,7 @@ static int ir2_decode_frame(AVCodecContext *avctx, AVFrame * const p= (AVFrame*)&s->picture; int start; - if(p->data[0]) - avctx->release_buffer(avctx, p); - - p->reference = 1; + p->reference = 3; p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, p)) { av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); @@ -201,6 +198,7 @@ static av_cold int ir2_decode_init(AVCodecContext *avctx){ Ir2Context * const ic = avctx->priv_data; static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2]; + avcodec_get_frame_defaults(&ic->picture); ic->avctx = avctx; avctx->pix_fmt= PIX_FMT_YUV410P; diff --git a/libavcodec/indeo2data.h b/libavcodec/indeo2data.h index ed8d83c83b..0d6d82f22c 100644 --- a/libavcodec/indeo2data.h +++ b/libavcodec/indeo2data.h @@ -2,20 +2,20 @@ * Intel Indeo 2 codec * copyright (c) 2005 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/indeo3.c b/libavcodec/indeo3.c index d2b01f469a..fc38f5e9cb 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -2,20 +2,20 @@ * Indeo Video v3 compatible decoder * Copyright (c) 2009 - 2011 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -227,8 +227,11 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) /* setup output and reference pointers */ offset_dst = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2); dst = plane->pixels[ctx->buf_sel] + offset_dst; + if(cell->mv_ptr){ mv_y = cell->mv_ptr[0]; mv_x = cell->mv_ptr[1]; + }else + mv_x= mv_y= 0; offset = offset_dst + mv_y * plane->pitch + mv_x; src = plane->pixels[ctx->buf_sel ^ 1] + offset; @@ -734,7 +737,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ref_cell->width -= curr_cell.width; } - while (1) { /* loop until return */ + while (get_bits_left(&ctx->gb) >= 2) { /* loop until return */ RESYNC_BITSTREAM; switch (code = get_bits(&ctx->gb, 2)) { case H_SPLIT: @@ -769,12 +772,12 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, /* get motion vector index and setup the pointer to the mv set */ if (!ctx->need_resync) ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3]; - mv_idx = *(ctx->next_cell_data++) << 1; + mv_idx = *(ctx->next_cell_data++); if (mv_idx >= ctx->num_vectors) { av_log(avctx, AV_LOG_ERROR, "motion vector index out of range\n"); return AVERROR_INVALIDDATA; } - curr_cell.mv_ptr = &ctx->mc_vectors[mv_idx]; + curr_cell.mv_ptr = &ctx->mc_vectors[mv_idx << 1]; curr_cell.tree = 1; /* enter the VQ tree */ UPDATE_BITPOS(8); } else { /* VQ tree DATA code */ @@ -795,7 +798,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, } }//while - return 0; + return AVERROR_INVALIDDATA; } @@ -893,7 +896,8 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->height = height; free_frame_buffers(ctx); - allocate_frame_buffers(ctx, avctx); + if(allocate_frame_buffers(ctx, avctx) < 0) + return AVERROR_INVALIDDATA; avcodec_set_dimensions(avctx, width, height); } @@ -987,14 +991,13 @@ static av_cold int decode_init(AVCodecContext *avctx) ctx->width = avctx->width; ctx->height = avctx->height; avctx->pix_fmt = PIX_FMT_YUV410P; + avcodec_get_frame_defaults(&ctx->frame); build_requant_tab(); dsputil_init(&ctx->dsp, avctx); - allocate_frame_buffers(ctx, avctx); - - return 0; + return allocate_frame_buffers(ctx, avctx); } diff --git a/libavcodec/indeo3data.h b/libavcodec/indeo3data.h index 6bb55ce902..15b9d9a9da 100644 --- a/libavcodec/indeo3data.h +++ b/libavcodec/indeo3data.h @@ -2,20 +2,20 @@ * Indeo Video v3 compatible decoder * Copyright (c) 2009 - 2011 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/indeo5.c b/libavcodec/indeo5.c index 5263251f8d..8842f221cf 100644 --- a/libavcodec/indeo5.c +++ b/libavcodec/indeo5.c @@ -2,20 +2,20 @@ * Indeo Video Interactive v5 compatible decoder * Copyright (c) 2009 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -90,7 +90,7 @@ typedef struct { */ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) { - int result, i, p, tile_size, pic_size_indx, mb_size, blk_size; + int result, i, p, tile_size, pic_size_indx, mb_size, blk_size, is_scalable; int quant_mat, blk_size_changed = 0; IVIBandDesc *band, *band1, *band2; IVIPicConfig pic_conf; @@ -112,8 +112,8 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) /* num_levels * 3 + 1 */ pic_conf.luma_bands = get_bits(&ctx->gb, 2) * 3 + 1; pic_conf.chroma_bands = get_bits1(&ctx->gb) * 3 + 1; - ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1; - if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) { + is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1; + if (is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) { av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n", pic_conf.luma_bands, pic_conf.chroma_bands); return -1; @@ -151,6 +151,7 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) return -1; } ctx->pic_conf = pic_conf; + ctx->is_scalable = is_scalable; blk_size_changed = 1; /* force reallocation of the internal structures */ } @@ -485,7 +486,7 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, } mb->mv_x = mb->mv_y = 0; /* no motion vector coded */ - if (band->inherit_mv){ + if (band->inherit_mv && ref_mb){ /* motion vector inheritance */ if (mv_scale) { mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); @@ -496,7 +497,7 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, } } } else { - if (band->inherit_mv) { + if (band->inherit_mv && ref_mb) { mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */ } else if (ctx->frame_type == FRAMETYPE_INTRA) { mb->type = 0; /* mb_type is always INTRA for intra-frames */ @@ -522,7 +523,7 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, if (!mb->type) { mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */ } else { - if (band->inherit_mv){ + if (band->inherit_mv && ref_mb){ /* motion vector inheritance */ if (mv_scale) { mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); @@ -717,6 +718,8 @@ static av_cold int decode_init(AVCodecContext *avctx) ctx->pic_conf.tile_height = avctx->height; ctx->pic_conf.luma_bands = ctx->pic_conf.chroma_bands = 1; + avcodec_get_frame_defaults(&ctx->frame); + result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf); if (result) { av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n"); diff --git a/libavcodec/indeo5data.h b/libavcodec/indeo5data.h index f4252b59f6..a6217d0bf8 100644 --- a/libavcodec/indeo5data.h +++ b/libavcodec/indeo5data.h @@ -2,20 +2,20 @@ * Indeo Video Interactive 5 compatible decoder * Copyright (c) 2009 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c index bedfabff02..c97c1d7a1f 100644 --- a/libavcodec/intelh263dec.c +++ b/libavcodec/intelh263dec.c @@ -1,20 +1,20 @@ /* * H.263i decoder * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/internal.h b/libavcodec/internal.h index b435a359fb..b7d4a6e139 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -99,6 +99,16 @@ int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b); unsigned int avpriv_toupper4(unsigned int x); +/** + * does needed setup of pkt_pts/pos and such for (re)get_buffer(); + */ +void ff_init_buffer_info(AVCodecContext *s, AVFrame *pic); + +/** + * Remove and free all side data from packet. + */ +void ff_packet_free_side_data(AVPacket *pkt); + int avpriv_lock_avformat(void); int avpriv_unlock_avformat(void); diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index 724f5f1850..68aa966208 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -2,20 +2,20 @@ * Interplay MVE Video Decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1019,6 +1019,10 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx) dsputil_init(&s->dsp, avctx); + avcodec_get_frame_defaults(&s->second_last_frame); + avcodec_get_frame_defaults(&s->last_frame); + avcodec_get_frame_defaults(&s->current_frame); + s->current_frame.data[0] = s->last_frame.data[0] = s->second_last_frame.data[0] = NULL; diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c index 0dc33e2596..b50fbfcd1a 100644 --- a/libavcodec/intrax8.c +++ b/libavcodec/intrax8.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/intrax8.h b/libavcodec/intrax8.h index 3a58938cc3..8ce4f8d098 100644 --- a/libavcodec/intrax8.h +++ b/libavcodec/intrax8.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/intrax8dsp.c b/libavcodec/intrax8dsp.c index 1a62fcde77..692e1b102f 100644 --- a/libavcodec/intrax8dsp.c +++ b/libavcodec/intrax8dsp.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/intrax8huf.h b/libavcodec/intrax8huf.h index 6bf01f388a..375906bab2 100644 --- a/libavcodec/intrax8huf.h +++ b/libavcodec/intrax8huf.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c index 148bb33a36..f058c9b848 100644 --- a/libavcodec/ituh263dec.c +++ b/libavcodec/ituh263dec.c @@ -5,20 +5,20 @@ * Copyright (c) 2001 Juan J. Sierralta P * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -27,6 +27,8 @@ * h263 decoder. */ +#define UNCHECKED_BITSTREAM_READER 1 + //#define DEBUG #include <limits.h> @@ -484,7 +486,7 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block, level = get_bits(&s->gb, 8); 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); - if(s->err_recognition & AV_EF_BITSTREAM) + if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)) return -1; } if (level == 255) diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c index 6efba2d65a..9d41376ca7 100644 --- a/libavcodec/ituh263enc.c +++ b/libavcodec/ituh263enc.c @@ -5,20 +5,20 @@ * Copyright (c) 2001 Juan J. Sierralta P * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index eedcd28ada..c75769ec31 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -260,6 +260,8 @@ int av_cold ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_hei t_width >>= 1; t_height >>= 1; } + if(t_width<=0 || t_height<=0) + return AVERROR(EINVAL); for (b = 0; b < planes[p].num_bands; b++) { band = &planes[p].bands[b]; @@ -506,7 +508,7 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, if (band->inherit_qdelta && ref_mb) mb->q_delta = ref_mb->q_delta; - if (band->inherit_mv) { + if (band->inherit_mv && ref_mb) { /* motion vector inheritance */ if (mv_scale) { mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h index 4b2ae063b1..dd060854f3 100644 --- a/libavcodec/ivi_common.h +++ b/libavcodec/ivi_common.h @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -219,7 +219,7 @@ static inline int ivi_scale_mv(int mv, int mv_scale) /** * Generate a huffman codebook from the given descriptor - * and convert it into the Libav VLC table. + * and convert it into the FFmpeg VLC table. * * @param[in] cb pointer to codebook descriptor * @param[out] vlc where to place the generated VLC table diff --git a/libavcodec/ivi_dsp.c b/libavcodec/ivi_dsp.c index caad843c8b..0ee7035741 100644 --- a/libavcodec/ivi_dsp.c +++ b/libavcodec/ivi_dsp.c @@ -3,20 +3,20 @@ * * Copyright (c) 2009-2011 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ivi_dsp.h b/libavcodec/ivi_dsp.h index 04385140f3..5a3441764c 100644 --- a/libavcodec/ivi_dsp.h +++ b/libavcodec/ivi_dsp.h @@ -3,20 +3,20 @@ * * Copyright (c) 2009-2011 Maxim Poliakovski * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/j2k.c b/libavcodec/j2k.c new file mode 100644 index 0000000000..33a7e3100b --- /dev/null +++ b/libavcodec/j2k.c @@ -0,0 +1,392 @@ +/* + * JPEG2000 encoder and decoder common functions + * Copyright (c) 2007 Kamil Nowosad + * + * 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 + */ + +/** + * JPEG2000 image encoder and decoder common functions + * @file + * @author Kamil Nowosad + */ + + +#include "avcodec.h" +#include "j2k.h" + +#define SHL(a, n) ((n)>=0 ? (a) << (n) : (a) >> -(n)) + +#if 0 +void ff_j2k_printv(int *tab, int l) +{ + int i; + for (i = 0; i < l; i++) + printf("%.3d ", tab[i]); + printf("\n"); +} + +void ff_j2k_printu(uint8_t *tab, int l) +{ + int i; + for (i = 0; i < l; i++) + printf("%.3hd ", tab[i]); + printf("\n"); +} +#endif + +/* tag tree routines */ + +/** allocate the memory for tag tree */ + +static int tag_tree_size(int w, int h) +{ + int res = 0; + while (w > 1 || h > 1){ + res += w * h; + w = (w+1) >> 1; + h = (h+1) >> 1; + } + return res + 1; +} + +J2kTgtNode *ff_j2k_tag_tree_init(int w, int h) +{ + int pw = w, ph = h; + J2kTgtNode *res, *t, *t2; + + t = res = av_mallocz(tag_tree_size(w, h)*sizeof(J2kTgtNode)); + + if (res == NULL) + return NULL; + + while (w > 1 || h > 1){ + int i, j; + pw = w; + ph = h; + + w = (w+1) >> 1; + h = (h+1) >> 1; + t2 = t + pw*ph; + + for (i = 0; i < ph; i++) + for (j = 0; j < pw; j++){ + t[i*pw + j].parent = &t2[(i>>1)*w + (j>>1)]; + } + t = t2; + } + t[0].parent = NULL; + return res; +} + +static void tag_tree_zero(J2kTgtNode *t, int w, int h) +{ + int i, siz = tag_tree_size(w, h); + + for (i = 0; i < siz; i++){ + t[i].val = 0; + t[i].vis = 0; + } +} + +uint8_t ff_j2k_nbctxno_lut[256][4]; + +static int getnbctxno(int flag, int bandno, int vert_causal_ctx_csty_symbol) +{ + int h, v, d; + + h = ((flag & J2K_T1_SIG_E) ? 1:0)+ + ((flag & J2K_T1_SIG_W) ? 1:0); + v = ((flag & J2K_T1_SIG_N) ? 1:0); + if (!vert_causal_ctx_csty_symbol) + v = v + ((flag & J2K_T1_SIG_S) ? 1:0); + d = ((flag & J2K_T1_SIG_NE) ? 1:0)+ + ((flag & J2K_T1_SIG_NW) ? 1:0); + if (!vert_causal_ctx_csty_symbol) + d = d + ((flag & J2K_T1_SIG_SE) ? 1:0)+ + ((flag & J2K_T1_SIG_SW) ? 1:0); + if (bandno < 3){ + if (bandno == 1) + FFSWAP(int, h, v); + if (h == 2) return 8; + if (h == 1){ + if (v >= 1) return 7; + if (d >= 1) return 6; + return 5; + } + if (v == 2) return 4; + if (v == 1) return 3; + if (d >= 2) return 2; + if (d == 1) return 1; + return 0; + } else{ + if (d >= 3) return 8; + if (d == 2){ + if (h+v >= 1) return 7; + return 6; + } + if (d == 1){ + if (h+v >= 2) return 5; + if (h+v == 1) return 4; + return 3; + } + if (h+v >= 2) return 2; + if (h+v == 1) return 1; + return 0; + } + assert(0); +} + +uint8_t ff_j2k_sgnctxno_lut[16][16], ff_j2k_xorbit_lut[16][16]; + +static int getsgnctxno(int flag, uint8_t *xorbit) +{ + int vcontrib, hcontrib; + static const int contribtab[3][3] = {{0, -1, 1}, {-1, -1, 0}, {1, 0, 1}}; + static const int ctxlbltab[3][3] = {{13, 12, 11}, {10, 9, 10}, {11, 12, 13}}; + static const int xorbittab[3][3] = {{1, 1, 1,}, {1, 0, 0}, {0, 0, 0}}; + + hcontrib = contribtab[flag & J2K_T1_SIG_E ? flag & J2K_T1_SGN_E ? 1:2:0] + [flag & J2K_T1_SIG_W ? flag & J2K_T1_SGN_W ? 1:2:0]+1; + vcontrib = contribtab[flag & J2K_T1_SIG_S ? flag & J2K_T1_SGN_S ? 1:2:0] + [flag & J2K_T1_SIG_N ? flag & J2K_T1_SGN_N ? 1:2:0]+1; + *xorbit = xorbittab[hcontrib][vcontrib]; + return ctxlbltab[hcontrib][vcontrib]; +} + +void ff_j2k_init_tier1_luts(void) +{ + int i, j; + for (i = 0; i < 256; i++) + for (j = 0; j < 4; j++) + ff_j2k_nbctxno_lut[i][j] = getnbctxno(i, j, 0); + for (i = 0; i < 16; i++) + for (j = 0; j < 16; j++) + ff_j2k_sgnctxno_lut[i][j] = getsgnctxno(i + (j << 8), &ff_j2k_xorbit_lut[i][j]); +} + +void ff_j2k_set_significant(J2kT1Context *t1, int x, int y, int negative) +{ + x++; y++; + t1->flags[y][x] |= J2K_T1_SIG; + if (negative){ + t1->flags[y][x+1] |= J2K_T1_SIG_W | J2K_T1_SGN_W; + t1->flags[y][x-1] |= J2K_T1_SIG_E | J2K_T1_SGN_E; + t1->flags[y+1][x] |= J2K_T1_SIG_N | J2K_T1_SGN_N; + t1->flags[y-1][x] |= J2K_T1_SIG_S | J2K_T1_SGN_S; + } else{ + t1->flags[y][x+1] |= J2K_T1_SIG_W; + t1->flags[y][x-1] |= J2K_T1_SIG_E; + t1->flags[y+1][x] |= J2K_T1_SIG_N; + t1->flags[y-1][x] |= J2K_T1_SIG_S; + } + t1->flags[y+1][x+1] |= J2K_T1_SIG_NW; + t1->flags[y+1][x-1] |= J2K_T1_SIG_NE; + t1->flags[y-1][x+1] |= J2K_T1_SIG_SW; + t1->flags[y-1][x-1] |= J2K_T1_SIG_SE; +} + +int ff_j2k_init_component(J2kComponent *comp, J2kCodingStyle *codsty, J2kQuantStyle *qntsty, int cbps, int dx, int dy) +{ + int reslevelno, bandno, gbandno = 0, ret, i, j, csize = 1; + + if (ret=ff_j2k_dwt_init(&comp->dwt, comp->coord, codsty->nreslevels-1, codsty->transform)) + return ret; + for (i = 0; i < 2; i++) + csize *= comp->coord[i][1] - comp->coord[i][0]; + + comp->data = av_malloc(csize * sizeof(int)); + if (!comp->data) + return AVERROR(ENOMEM); + comp->reslevel = av_malloc(codsty->nreslevels * sizeof(J2kResLevel)); + + if (!comp->reslevel) + return AVERROR(ENOMEM); + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + int declvl = codsty->nreslevels - reslevelno; + J2kResLevel *reslevel = comp->reslevel + reslevelno; + + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) + reslevel->coord[i][j] = + ff_j2k_ceildivpow2(comp->coord[i][j], declvl - 1); + + if (reslevelno == 0) + reslevel->nbands = 1; + else + reslevel->nbands = 3; + + if (reslevel->coord[0][1] == reslevel->coord[0][0]) + reslevel->num_precincts_x = 0; + else + reslevel->num_precincts_x = ff_j2k_ceildivpow2(reslevel->coord[0][1], codsty->log2_prec_width) + - (reslevel->coord[0][0] >> codsty->log2_prec_width); + + if (reslevel->coord[1][1] == reslevel->coord[1][0]) + reslevel->num_precincts_y = 0; + else + reslevel->num_precincts_y = ff_j2k_ceildivpow2(reslevel->coord[1][1], codsty->log2_prec_height) + - (reslevel->coord[1][0] >> codsty->log2_prec_height); + + reslevel->band = av_malloc(reslevel->nbands * sizeof(J2kBand)); + if (!reslevel->band) + return AVERROR(ENOMEM); + for (bandno = 0; bandno < reslevel->nbands; bandno++, gbandno++){ + J2kBand *band = reslevel->band + bandno; + int cblkno, precx, precy, precno; + int x0, y0, x1, y1; + int xi0, yi0, xi1, yi1; + int cblkperprecw, cblkperprech; + + if (qntsty->quantsty != J2K_QSTY_NONE){ + const static uint8_t lut_gain[2][4] = {{0, 0, 0, 0}, {0, 1, 1, 2}}; + int numbps; + + numbps = cbps + lut_gain[codsty->transform][bandno + reslevelno>0]; + band->stepsize = SHL(2048 + qntsty->mant[gbandno], 2 + numbps - qntsty->expn[gbandno]); + } else + band->stepsize = 1 << 13; + + if (reslevelno == 0){ // the same everywhere + band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width-1); + band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height-1); + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) + band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j], declvl-1); + } else{ + band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width); + band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height); + + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) + band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j] - (((bandno+1>>i)&1) << declvl-1), declvl); + } + band->cblknx = ff_j2k_ceildiv(band->coord[0][1], band->codeblock_width) - band->coord[0][0] / band->codeblock_width; + band->cblkny = ff_j2k_ceildiv(band->coord[1][1], band->codeblock_height) - band->coord[1][0] / band->codeblock_height; + + for (j = 0; j < 2; j++) + band->coord[0][j] = ff_j2k_ceildiv(band->coord[0][j], dx); + for (j = 0; j < 2; j++) + band->coord[1][j] = ff_j2k_ceildiv(band->coord[1][j], dy); + + band->cblknx = ff_j2k_ceildiv(band->cblknx, dx); + band->cblkny = ff_j2k_ceildiv(band->cblkny, dy); + + band->cblk = av_malloc(band->cblknx * band->cblkny * sizeof(J2kCblk)); + if (!band->cblk) + return AVERROR(ENOMEM); + band->prec = av_malloc(reslevel->num_precincts_x * reslevel->num_precincts_y * sizeof(J2kPrec)); + if (!band->prec) + return AVERROR(ENOMEM); + + for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){ + J2kCblk *cblk = band->cblk + cblkno; + cblk->zero = 0; + cblk->lblock = 3; + cblk->length = 0; + cblk->lengthinc = 0; + cblk->npasses = 0; + } + + y0 = band->coord[1][0]; + y1 = ((band->coord[1][0] + (1<<codsty->log2_prec_height)) & ~((1<<codsty->log2_prec_height)-1)) - y0; + yi0 = 0; + yi1 = ff_j2k_ceildivpow2(y1 - y0, codsty->log2_cblk_height) << codsty->log2_cblk_height; + yi1 = FFMIN(yi1, band->cblkny); + cblkperprech = 1<<(codsty->log2_prec_height - codsty->log2_cblk_height); + for (precy = 0, precno = 0; precy < reslevel->num_precincts_y; precy++){ + for (precx = 0; precx < reslevel->num_precincts_x; precx++, precno++){ + band->prec[precno].yi0 = yi0; + band->prec[precno].yi1 = yi1; + } + yi1 += cblkperprech; + yi0 = yi1 - cblkperprech; + yi1 = FFMIN(yi1, band->cblkny); + } + x0 = band->coord[0][0]; + x1 = ((band->coord[0][0] + (1<<codsty->log2_prec_width)) & ~((1<<codsty->log2_prec_width)-1)) - x0; + xi0 = 0; + xi1 = ff_j2k_ceildivpow2(x1 - x0, codsty->log2_cblk_width) << codsty->log2_cblk_width; + xi1 = FFMIN(xi1, band->cblknx); + + cblkperprecw = 1<<(codsty->log2_prec_width - codsty->log2_cblk_width); + for (precx = 0, precno = 0; precx < reslevel->num_precincts_x; precx++){ + for (precy = 0; precy < reslevel->num_precincts_y; precy++, precno = 0){ + J2kPrec *prec = band->prec + precno; + prec->xi0 = xi0; + prec->xi1 = xi1; + prec->cblkincl = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0, + prec->yi1 - prec->yi0); + prec->zerobits = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0, + prec->yi1 - prec->yi0); + if (!prec->cblkincl || !prec->zerobits) + return AVERROR(ENOMEM); + + } + xi1 += cblkperprecw; + xi0 = xi1 - cblkperprecw; + xi1 = FFMIN(xi1, band->cblknx); + } + } + } + return 0; +} + +void ff_j2k_reinit(J2kComponent *comp, J2kCodingStyle *codsty) +{ + int reslevelno, bandno, cblkno, precno; + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + J2kResLevel *rlevel = comp->reslevel + reslevelno; + for (bandno = 0; bandno < rlevel->nbands; bandno++){ + J2kBand *band = rlevel->band + bandno; + for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++){ + J2kPrec *prec = band->prec + precno; + tag_tree_zero(prec->zerobits, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0); + tag_tree_zero(prec->cblkincl, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0); + } + for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){ + J2kCblk *cblk = band->cblk + cblkno; + cblk->length = 0; + cblk->lblock = 3; + } + } + } +} + +void ff_j2k_cleanup(J2kComponent *comp, J2kCodingStyle *codsty) +{ + int reslevelno, bandno, precno; + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + J2kResLevel *reslevel = comp->reslevel + reslevelno; + + for (bandno = 0; bandno < reslevel->nbands ; bandno++){ + J2kBand *band = reslevel->band + bandno; + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + J2kPrec *prec = band->prec + precno; + av_freep(&prec->zerobits); + av_freep(&prec->cblkincl); + } + av_freep(&band->cblk); + av_freep(&band->prec); + } + av_freep(&reslevel->band); + } + + ff_j2k_dwt_destroy(&comp->dwt); + av_freep(&comp->reslevel); + av_freep(&comp->data); +} diff --git a/libavcodec/j2k.h b/libavcodec/j2k.h new file mode 100644 index 0000000000..85d5cd079c --- /dev/null +++ b/libavcodec/j2k.h @@ -0,0 +1,234 @@ +/* + * JPEG2000 tables + * Copyright (c) 2007 Kamil Nowosad + * + * 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 AVCODEC_J2K_H +#define AVCODEC_J2K_H + +/** + * JPEG2000 tables + * @file + * @author Kamil Nowosad + */ + +#include "mqc.h" +#include "j2k_dwt.h" + +enum J2kMarkers{ + J2K_SOC = 0xff4f, ///< start of codestream + J2K_SIZ = 0xff51, ///< image and tile size + J2K_COD, ///< coding style default + J2K_COC, ///< coding style component + J2K_TLM = 0xff55, ///< packed packet headers, tile-part header + J2K_PLM = 0xff57, ///< tile-part lengths + J2K_PLT, ///< packet length, main header + J2K_QCD = 0xff5c, ///< quantization default + J2K_QCC, ///< quantization component + J2K_RGN, ///< region of interest + J2K_POC, ///< progression order change + J2K_PPM, ///< packet length, tile-part header + J2K_PPT, ///< packed packet headers, main header + J2K_CRG = 0xff63, ///< component registration + J2K_COM, ///< comment + J2K_SOT = 0xff90, ///< start of tile-part + J2K_SOP, ///< start of packet + J2K_EPH, ///< end of packet header + J2K_SOD, ///< start of data + J2K_EOC = 0xffd9, ///< end of codestream +}; + +enum J2kQuantsty{ ///< quantization style + J2K_QSTY_NONE, ///< no quantization + J2K_QSTY_SI, ///< scalar derived + J2K_QSTY_SE ///< scalar expoounded +}; + +#define J2K_MAX_CBLKW 64 +#define J2K_MAX_CBLKH 64 + +// T1 flags +// flags determining significance of neighbour coefficients +#define J2K_T1_SIG_N 0x0001 +#define J2K_T1_SIG_E 0x0002 +#define J2K_T1_SIG_W 0x0004 +#define J2K_T1_SIG_S 0x0008 +#define J2K_T1_SIG_NE 0x0010 +#define J2K_T1_SIG_NW 0x0020 +#define J2K_T1_SIG_SE 0x0040 +#define J2K_T1_SIG_SW 0x0080 +#define J2K_T1_SIG_NB (J2K_T1_SIG_N | J2K_T1_SIG_E | J2K_T1_SIG_S | J2K_T1_SIG_W \ + |J2K_T1_SIG_NE | J2K_T1_SIG_NW | J2K_T1_SIG_SE | J2K_T1_SIG_SW) +// flags determining sign bit of neighbour coefficients +#define J2K_T1_SGN_N 0x0100 +#define J2K_T1_SGN_S 0x0200 +#define J2K_T1_SGN_W 0x0400 +#define J2K_T1_SGN_E 0x0800 + +#define J2K_T1_VIS 0x1000 +#define J2K_T1_SIG 0x2000 +#define J2K_T1_REF 0x4000 + +#define J2K_T1_SGN 0x8000 + +// Codeblock coding styles +#define J2K_CBLK_BYPASS 0x01 // Selective arithmetic coding bypass +#define J2K_CBLK_RESET 0x02 // Reset context probabilities +#define J2K_CBLK_TERMALL 0x04 // Terminate after each coding pass +#define J2K_CBLK_VSC 0x08 // Vertical stripe causal context formation +#define J2K_CBLK_PREDTERM 0x10 // Predictable termination +#define J2K_CBLK_SEGSYM 0x20 // Segmentation symbols present + +// Coding styles +#define J2K_CSTY_PREC 0x01 // Precincts defined in coding style +#define J2K_CSTY_SOP 0x02 // SOP marker present +#define J2K_CSTY_EPH 0x04 // EPH marker present + +typedef struct { + int data[J2K_MAX_CBLKW][J2K_MAX_CBLKH]; + int flags[J2K_MAX_CBLKW+2][J2K_MAX_CBLKH+2]; + MqcState mqc; +} J2kT1Context; + +typedef struct J2kTgtNode { + uint8_t val; + uint8_t vis; + struct J2kTgtNode *parent; +} J2kTgtNode; + +typedef struct { + uint8_t nreslevels; ///< number of resolution levels + uint8_t log2_cblk_width, + log2_cblk_height; ///< exponent of codeblock size + uint8_t transform; ///< DWT type + uint8_t csty; ///< coding style + uint8_t log2_prec_width, + log2_prec_height; ///< precinct size + uint8_t nlayers; ///< number of layers + uint8_t mct; ///< multiple component transformation + uint8_t cblk_style; ///< codeblock coding style +} J2kCodingStyle; + +typedef struct { + uint8_t expn[32 * 3]; ///< quantization exponent + uint16_t mant[32 * 3]; ///< quantization mantissa + uint8_t quantsty; ///< quantization style + uint8_t nguardbits; ///< number of guard bits +} J2kQuantStyle; + +typedef struct { + uint16_t rate; + int64_t disto; +} J2kPass; + +typedef struct { + uint8_t npasses; + uint8_t ninclpasses; ///< number coding of passes included in codestream + uint8_t nonzerobits; + uint16_t length; + uint16_t lengthinc; + uint8_t lblock; + uint8_t zero; + uint8_t data[8192]; + J2kPass passes[100]; +} J2kCblk; ///< code block + +typedef struct { + uint16_t xi0, xi1, yi0, yi1; ///< codeblock indexes ([xi0, xi1)) + J2kTgtNode *zerobits; + J2kTgtNode *cblkincl; +} J2kPrec; ///< precinct + +typedef struct { + uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}} + uint16_t codeblock_width, codeblock_height; + uint16_t cblknx, cblkny; + uint32_t stepsize; ///< quantization stepsize (* 2^13) + J2kPrec *prec; + J2kCblk *cblk; +} J2kBand; ///< subband + +typedef struct { + uint8_t nbands; + uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}} + uint16_t num_precincts_x, num_precincts_y; ///< number of precincts in x/y direction + uint8_t log2_prec_width, log2_prec_height; ///< exponent of precinct size + J2kBand *band; +} J2kResLevel; ///< resolution level + +typedef struct { + J2kResLevel *reslevel; + DWTContext dwt; + int *data; + uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}} +} J2kComponent; + +/* debug routines */ +#if 0 +#undef fprintf +#undef printf +void ff_j2k_printv(int *tab, int l); +void ff_j2k_printu(uint8_t *tab, int l); +#endif + +/* misc tools */ +static inline int ff_j2k_ceildivpow2(int a, int b) +{ + return (a + (1 << b) - 1)>> b; +} + +static inline int ff_j2k_ceildiv(int a, int b) +{ + return (a + b - 1) / b; +} + +/* tag tree routines */ +J2kTgtNode *ff_j2k_tag_tree_init(int w, int h); + +/* TIER-1 routines */ +void ff_j2k_init_tier1_luts(void); + +void ff_j2k_set_significant(J2kT1Context *t1, int x, int y, int negative); + +extern uint8_t ff_j2k_nbctxno_lut[256][4]; + +static inline int ff_j2k_getnbctxno(int flag, int bandno, int vert_causal_ctx_csty_symbol) +{ + return ff_j2k_nbctxno_lut[flag&255][bandno]; +} + +static inline int ff_j2k_getrefctxno(int flag) +{ + static const uint8_t refctxno_lut[2][2] = {{14, 15}, {16, 16}}; + return refctxno_lut[(flag>>14)&1][(flag & 255) != 0]; +} + +extern uint8_t ff_j2k_sgnctxno_lut[16][16], ff_j2k_xorbit_lut[16][16]; + +static inline int ff_j2k_getsgnctxno(int flag, int *xorbit) +{ + *xorbit = ff_j2k_xorbit_lut[flag&15][(flag>>8)&15]; + return ff_j2k_sgnctxno_lut[flag&15][(flag>>8)&15]; +} + +int ff_j2k_init_component(J2kComponent *comp, J2kCodingStyle *codsty, J2kQuantStyle *qntsty, int cbps, int dx, int dy); +void ff_j2k_reinit(J2kComponent *comp, J2kCodingStyle *codsty); +void ff_j2k_cleanup(J2kComponent *comp, J2kCodingStyle *codsty); + +#endif /* AVCODEC_J2K_H */ diff --git a/libavcodec/j2k_dwt.c b/libavcodec/j2k_dwt.c new file mode 100644 index 0000000000..48aa33735e --- /dev/null +++ b/libavcodec/j2k_dwt.c @@ -0,0 +1,386 @@ +/* + * Discrete wavelet transform + * Copyright (c) 2007 Kamil Nowosad + * + * 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 + */ + +/** + * Discrete wavelet transform + * @file + * @author Kamil Nowosad + */ + +#include "j2k_dwt.h" + +const static float scale97[] = {1.625786, 1.230174}; + +static inline void extend53(int *p, int i0, int i1) +{ + p[i0 - 1] = p[i0 + 1]; + p[i1 ] = p[i1 - 2]; + p[i0 - 2] = p[i0 + 2]; + p[i1 + 1] = p[i1 - 3]; +} + +static inline void extend97(float *p, int i0, int i1) +{ + int i; + + for (i = 1; i <= 4; i++){ + p[i0 - i] = p[i0 + i]; + p[i1 + i - 1] = p[i1 - i - 1]; + } +} + +static void sd_1d53(int *p, int i0, int i1) +{ + int i; + + if (i1 == i0 + 1) + return; + + extend53(p, i0, i1); + + for (i = (i0+1)/2 - 1; i < (i1+1)/2; i++) + p[2*i+1] -= (p[2*i] + p[2*i+2]) >> 1; + for (i = (i0+1)/2; i < (i1+1)/2; i++) + p[2*i] += (p[2*i-1] + p[2*i+1] + 2) >> 2; +} + +static void dwt_encode53(DWTContext *s, int *t) +{ + int lev, + w = s->linelen[s->ndeclevels-1][0]; + int *line = s->linebuf; + line += 3; + + for (lev = s->ndeclevels-1; lev >= 0; lev--){ + int lh = s->linelen[lev][0], + lv = s->linelen[lev][1], + mh = s->mod[lev][0], + mv = s->mod[lev][1], + lp; + int *l; + + // HOR_SD + l = line + mh; + for (lp = 0; lp < lv; lp++){ + int i, j = 0; + + for (i = 0; i < lh; i++) + l[i] = t[w*lp + i]; + + sd_1d53(line, mh, mh + lh); + + // copy back and deinterleave + for (i = mh; i < lh; i+=2, j++) + t[w*lp + j] = l[i]; + for (i = 1-mh; i < lh; i+=2, j++) + t[w*lp + j] = l[i]; + } + + // VER_SD + l = line + mv; + for (lp = 0; lp < lh; lp++) { + int i, j = 0; + + for (i = 0; i < lv; i++) + l[i] = t[w*i + lp]; + + sd_1d53(line, mv, mv + lv); + + // copy back and deinterleave + for (i = mv; i < lv; i+=2, j++) + t[w*j + lp] = l[i]; + for (i = 1-mv; i < lv; i+=2, j++) + t[w*j + lp] = l[i]; + } + } +} + +static void sd_1d97(float *p, int i0, int i1) +{ + int i; + + if (i1 == i0 + 1) + return; + + extend97(p, i0, i1); + i0++; i1++; + + for (i = i0/2 - 2; i < i1/2 + 1; i++) + p[2*i+1] -= 1.586134 * (p[2*i] + p[2*i+2]); + for (i = i0/2 - 1; i < i1/2 + 1; i++) + p[2*i] -= 0.052980 * (p[2*i-1] + p[2*i+1]); + for (i = i0/2 - 1; i < i1/2; i++) + p[2*i+1] += 0.882911 * (p[2*i] + p[2*i+2]); + for (i = i0/2; i < i1/2; i++) + p[2*i] += 0.443506 * (p[2*i-1] + p[2*i+1]); +} + +static void dwt_encode97(DWTContext *s, int *t) +{ + int lev, + w = s->linelen[s->ndeclevels-1][0]; + float *line = s->linebuf; + line += 5; + + for (lev = s->ndeclevels-1; lev >= 0; lev--){ + int lh = s->linelen[lev][0], + lv = s->linelen[lev][1], + mh = s->mod[lev][0], + mv = s->mod[lev][1], + lp; + float *l; + + // HOR_SD + l = line + mh; + for (lp = 0; lp < lv; lp++){ + int i, j = 0; + + for (i = 0; i < lh; i++) + l[i] = t[w*lp + i]; + + sd_1d97(line, mh, mh + lh); + + // copy back and deinterleave + for (i = mh; i < lh; i+=2, j++) + t[w*lp + j] = scale97[mh] * l[i] / 2; + for (i = 1-mh; i < lh; i+=2, j++) + t[w*lp + j] = scale97[mh] * l[i] / 2; + } + + // VER_SD + l = line + mv; + for (lp = 0; lp < lh; lp++) { + int i, j = 0; + + for (i = 0; i < lv; i++) + l[i] = t[w*i + lp]; + + sd_1d97(line, mv, mv + lv); + + // copy back and deinterleave + for (i = mv; i < lv; i+=2, j++) + t[w*j + lp] = scale97[mv] * l[i] / 2; + for (i = 1-mv; i < lv; i+=2, j++) + t[w*j + lp] = scale97[mv] * l[i] / 2; + } + } +} + +static void sr_1d53(int *p, int i0, int i1) +{ + int i; + + if (i1 == i0 + 1) + return; + + extend53(p, i0, i1); + + for (i = i0/2; i < i1/2 + 1; i++) + p[2*i] -= (p[2*i-1] + p[2*i+1] + 2) >> 2; + for (i = i0/2; i < i1/2; i++) + p[2*i+1] += (p[2*i] + p[2*i+2]) >> 1; +} + +static void dwt_decode53(DWTContext *s, int *t) +{ + int lev, + w = s->linelen[s->ndeclevels-1][0]; + int *line = s->linebuf; + line += 3; + + for (lev = 0; lev < s->ndeclevels; lev++){ + int lh = s->linelen[lev][0], + lv = s->linelen[lev][1], + mh = s->mod[lev][0], + mv = s->mod[lev][1], + lp; + int *l; + + // HOR_SD + l = line + mh; + for (lp = 0; lp < lv; lp++){ + int i, j = 0; + // copy with interleaving + for (i = mh; i < lh; i+=2, j++) + l[i] = t[w*lp + j]; + for (i = 1-mh; i < lh; i+=2, j++) + l[i] = t[w*lp + j]; + + sr_1d53(line, mh, mh + lh); + + for (i = 0; i < lh; i++) + t[w*lp + i] = l[i]; + } + + // VER_SD + l = line + mv; + for (lp = 0; lp < lh; lp++){ + int i, j = 0; + // copy with interleaving + for (i = mv; i < lv; i+=2, j++) + l[i] = t[w*j + lp]; + for (i = 1-mv; i < lv; i+=2, j++) + l[i] = t[w*j + lp]; + + sr_1d53(line, mv, mv + lv); + + for (i = 0; i < lv; i++) + t[w*i + lp] = l[i]; + } + } +} + +static void sr_1d97(float *p, int i0, int i1) +{ + int i; + + if (i1 == i0 + 1) + return; + + extend97(p, i0, i1); + + for (i = i0/2 - 1; i < i1/2 + 2; i++) + p[2*i] -= 0.443506 * (p[2*i-1] + p[2*i+1]); + for (i = i0/2 - 1; i < i1/2 + 1; i++) + p[2*i+1] -= 0.882911 * (p[2*i] + p[2*i+2]); + for (i = i0/2; i < i1/2 + 1; i++) + p[2*i] += 0.052980 * (p[2*i-1] + p[2*i+1]); + for (i = i0/2; i < i1/2; i++) + p[2*i+1] += 1.586134 * (p[2*i] + p[2*i+2]); +} + +static void dwt_decode97(DWTContext *s, int *t) +{ + int lev, + w = s->linelen[s->ndeclevels-1][0]; + float *line = s->linebuf; + line += 5; + + for (lev = 0; lev < s->ndeclevels; lev++){ + int lh = s->linelen[lev][0], + lv = s->linelen[lev][1], + mh = s->mod[lev][0], + mv = s->mod[lev][1], + lp; + float *l; + + // HOR_SD + l = line + mh; + for (lp = 0; lp < lv; lp++){ + int i, j = 0; + // copy with interleaving + for (i = mh; i < lh; i+=2, j++) + l[i] = scale97[1-mh] * t[w*lp + j]; + for (i = 1-mh; i < lh; i+=2, j++) + l[i] = scale97[1-mh] * t[w*lp + j]; + + sr_1d97(line, mh, mh + lh); + + for (i = 0; i < lh; i++) + t[w*lp + i] = l[i]; + } + + // VER_SD + l = line + mv; + for (lp = 0; lp < lh; lp++){ + int i, j = 0; + // copy with interleaving + for (i = mv; i < lv; i+=2, j++) + l[i] = scale97[1-mv] * t[w*j + lp]; + for (i = 1-mv; i < lv; i+=2, j++) + l[i] = scale97[1-mv] * t[w*j + lp]; + + sr_1d97(line, mv, mv + lv); + + for (i = 0; i < lv; i++) + t[w*i + lp] = l[i]; + } + } +} + +int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int type) +{ + int i, j, lev = decomp_levels, maxlen, + b[2][2]; + + if ((unsigned)decomp_levels >= FF_DWT_MAX_DECLVLS) + return AVERROR_INVALIDDATA; + s->ndeclevels = decomp_levels; + s->type = type; + + for (i = 0; i < 2; i++) + for(j = 0; j < 2; j++) + b[i][j] = border[i][j]; + + maxlen = FFMAX(b[0][1] - b[0][0], + b[1][1] - b[1][0]); + + while(--lev >= 0){ + for (i = 0; i < 2; i++){ + s->linelen[lev][i] = b[i][1] - b[i][0]; + s->mod[lev][i] = b[i][0] & 1; + for (j = 0; j < 2; j++) + b[i][j] = (b[i][j] + 1) >> 1; + } + } + if (type == FF_DWT97) + s->linebuf = av_malloc((maxlen + 12) * sizeof(float)); + else if (type == FF_DWT53) + s->linebuf = av_malloc((maxlen + 6) * sizeof(int)); + else + return -1; + + if (!s->linebuf) + return AVERROR(ENOMEM); + + return 0; +} + +int ff_j2k_dwt_encode(DWTContext *s, int *t) +{ + switch(s->type){ + case FF_DWT97: + dwt_encode97(s, t); break; + case FF_DWT53: + dwt_encode53(s, t); break; + default: + return -1; + } + return 0; +} + +int ff_j2k_dwt_decode(DWTContext *s, int *t) +{ + switch(s->type){ + case FF_DWT97: + dwt_decode97(s, t); break; + case FF_DWT53: + dwt_decode53(s, t); break; + default: + return -1; + } + return 0; +} + +void ff_j2k_dwt_destroy(DWTContext *s) +{ + av_freep(&s->linebuf); +} diff --git a/libavcodec/j2k_dwt.h b/libavcodec/j2k_dwt.h new file mode 100644 index 0000000000..a2a25a6891 --- /dev/null +++ b/libavcodec/j2k_dwt.h @@ -0,0 +1,63 @@ +/* + * Discrete wavelet transform + * Copyright (c) 2007 Kamil Nowosad + * + * 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 AVCODEC_DWT_H +#define AVCODEC_DWT_H + +/** + * Discrete wavelet transform + * @file + * @author Kamil Nowosad + */ + +#include "avcodec.h" + +#define FF_DWT_MAX_DECLVLS 32 ///< max number of decomposition levels + +enum DWTType{ + FF_DWT97, + FF_DWT53 +}; + +typedef struct { + ///line lengths {horizontal, vertical} in consecutive decomposition levels + uint16_t linelen[FF_DWT_MAX_DECLVLS][2]; + uint8_t mod[FF_DWT_MAX_DECLVLS][2]; ///< coordinates (x0, y0) of decomp. levels mod 2 + uint8_t ndeclevels; ///< number of decomposition levels + uint8_t type; ///< 0 for 9/7; 1 for 5/3 + void *linebuf; ///< buffer used by transform (int or float) +} DWTContext; + +/** + * initialize DWT + * @param s DWT context + * @param border coordinates of transformed region {{x0, x1}, {y0, y1}} + * @param decomp_levels number of decomposition levels + * @param type 0 for DWT 9/7; 1 for DWT 5/3 + */ +int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int type); + +int ff_j2k_dwt_encode(DWTContext *s, int *t); +int ff_j2k_dwt_decode(DWTContext *s, int *t); + +void ff_j2k_dwt_destroy(DWTContext *s); + +#endif /* AVCODEC_DWT_H */ diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c new file mode 100644 index 0000000000..78a24698a2 --- /dev/null +++ b/libavcodec/j2kdec.c @@ -0,0 +1,1090 @@ +/* + * JPEG2000 image decoder + * Copyright (c) 2007 Kamil Nowosad + * + * 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 + */ + +/** + * JPEG2000 image decoder + * @file + * @author Kamil Nowosad + */ + +#include "avcodec.h" +#include "bytestream.h" +#include "j2k.h" +#include "libavutil/common.h" + +#define JP2_SIG_TYPE 0x6A502020 +#define JP2_SIG_VALUE 0x0D0A870A +#define JP2_CODESTREAM 0x6A703263 + +#define HAD_COC 0x01 +#define HAD_QCC 0x02 + +typedef struct { + J2kComponent *comp; + uint8_t properties[4]; + J2kCodingStyle codsty[4]; + J2kQuantStyle qntsty[4]; +} J2kTile; + +typedef struct { + AVCodecContext *avctx; + AVFrame picture; + + int width, height; ///< image width and height + int image_offset_x, image_offset_y; + int tile_offset_x, tile_offset_y; + uint8_t cbps[4]; ///< bits per sample in particular components + uint8_t sgnd[4]; ///< if a component is signed + uint8_t properties[4]; + int cdx[4], cdy[4]; + int precision; + int ncomponents; + int tile_width, tile_height; ///< tile size + int numXtiles, numYtiles; + int maxtilelen; + + J2kCodingStyle codsty[4]; + J2kQuantStyle qntsty[4]; + + const uint8_t *buf_start; + const uint8_t *buf; + const uint8_t *buf_end; + int bit_index; + + int16_t curtileno; + + J2kTile *tile; +} J2kDecoderContext; + +static int get_bits(J2kDecoderContext *s, int n) +{ + int res = 0; + if (s->buf_end - s->buf < ((n - s->bit_index) >> 8)) + return AVERROR(EINVAL); + while (--n >= 0){ + res <<= 1; + if (s->bit_index == 0){ + s->bit_index = 7 + (*s->buf != 0xff); + s->buf++; + } + s->bit_index--; + res |= (*s->buf >> s->bit_index) & 1; + } + return res; +} + +static void j2k_flush(J2kDecoderContext *s) +{ + if (*s->buf == 0xff) + s->buf++; + s->bit_index = 8; + s->buf++; +} +#if 0 +void printcomp(J2kComponent *comp) +{ + int i; + for (i = 0; i < comp->y1 - comp->y0; i++) + ff_j2k_printv(comp->data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0); +} + +static void nspaces(FILE *fd, int n) +{ + while(n--) putc(' ', fd); +} + +static void dump(J2kDecoderContext *s, FILE *fd) +{ + int tileno, compno, reslevelno, bandno, precno; + fprintf(fd, "XSiz = %d, YSiz = %d, tile_width = %d, tile_height = %d\n" + "numXtiles = %d, numYtiles = %d, ncomponents = %d\n" + "tiles:\n", + s->width, s->height, s->tile_width, s->tile_height, + s->numXtiles, s->numYtiles, s->ncomponents); + for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ + J2kTile *tile = s->tile + tileno; + nspaces(fd, 2); + fprintf(fd, "tile %d:\n", tileno); + for(compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = tile->comp + compno; + nspaces(fd, 4); + fprintf(fd, "component %d:\n", compno); + nspaces(fd, 4); + fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d\n", + comp->x0, comp->x1, comp->y0, comp->y1); + for(reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + J2kResLevel *reslevel = comp->reslevel + reslevelno; + nspaces(fd, 6); + fprintf(fd, "reslevel %d:\n", reslevelno); + nspaces(fd, 6); + fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d, nbands = %d\n", + reslevel->x0, reslevel->x1, reslevel->y0, + reslevel->y1, reslevel->nbands); + for(bandno = 0; bandno < reslevel->nbands; bandno++){ + J2kBand *band = reslevel->band + bandno; + nspaces(fd, 8); + fprintf(fd, "band %d:\n", bandno); + nspaces(fd, 8); + fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d," + "codeblock_width = %d, codeblock_height = %d cblknx = %d cblkny = %d\n", + band->x0, band->x1, + band->y0, band->y1, + band->codeblock_width, band->codeblock_height, + band->cblknx, band->cblkny); + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + J2kPrec *prec = band->prec + precno; + nspaces(fd, 10); + fprintf(fd, "prec %d:\n", precno); + nspaces(fd, 10); + fprintf(fd, "xi0 = %d, xi1 = %d, yi0 = %d, yi1 = %d\n", + prec->xi0, prec->xi1, prec->yi0, prec->yi1); + } + } + } + } + } +} +#endif + +/** decode the value stored in node */ +static int tag_tree_decode(J2kDecoderContext *s, J2kTgtNode *node, int threshold) +{ + J2kTgtNode *stack[30]; + int sp = -1, curval = 0; + + while(node && !node->vis){ + stack[++sp] = node; + node = node->parent; + } + + if (node) + curval = node->val; + else + curval = stack[sp]->val; + + while(curval < threshold && sp >= 0){ + if (curval < stack[sp]->val) + curval = stack[sp]->val; + while (curval < threshold){ + int ret; + if ((ret = get_bits(s, 1)) > 0){ + stack[sp]->vis++; + break; + } else if (!ret) + curval++; + else + return ret; + } + stack[sp]->val = curval; + sp--; + } + return curval; +} + +/* marker segments */ +/** get sizes and offsets of image, tiles; number of components */ +static int get_siz(J2kDecoderContext *s) +{ + int i, ret; + + if (s->buf_end - s->buf < 36) + return AVERROR(EINVAL); + + bytestream_get_be16(&s->buf); // Rsiz (skipped) + s->width = bytestream_get_be32(&s->buf); // width + s->height = bytestream_get_be32(&s->buf); // height + s->image_offset_x = bytestream_get_be32(&s->buf); // X0Siz + s->image_offset_y = bytestream_get_be32(&s->buf); // Y0Siz + + s->tile_width = bytestream_get_be32(&s->buf); // XTSiz + s->tile_height = bytestream_get_be32(&s->buf); // YTSiz + s->tile_offset_x = bytestream_get_be32(&s->buf); // XT0Siz + s->tile_offset_y = bytestream_get_be32(&s->buf); // YT0Siz + s->ncomponents = bytestream_get_be16(&s->buf); // CSiz + + if(s->tile_width<=0 || s->tile_height<=0) + return AVERROR(EINVAL); + + if (s->buf_end - s->buf < 2 * s->ncomponents) + return AVERROR(EINVAL); + + for (i = 0; i < s->ncomponents; i++){ // Ssiz_i XRsiz_i, YRsiz_i + uint8_t x = bytestream_get_byte(&s->buf); + s->cbps[i] = (x & 0x7f) + 1; + s->precision = FFMAX(s->cbps[i], s->precision); + s->sgnd[i] = !!(x & 0x80); + s->cdx[i] = bytestream_get_byte(&s->buf); + s->cdy[i] = bytestream_get_byte(&s->buf); + } + + s->numXtiles = ff_j2k_ceildiv(s->width - s->tile_offset_x, s->tile_width); + s->numYtiles = ff_j2k_ceildiv(s->height - s->tile_offset_y, s->tile_height); + + if(s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(J2kTile)) + return AVERROR(EINVAL); + + s->tile = av_mallocz(s->numXtiles * s->numYtiles * sizeof(J2kTile)); + if (!s->tile) + return AVERROR(ENOMEM); + + for (i = 0; i < s->numXtiles * s->numYtiles; i++){ + J2kTile *tile = s->tile + i; + + tile->comp = av_mallocz(s->ncomponents * sizeof(J2kComponent)); + if (!tile->comp) + return AVERROR(ENOMEM); + } + + s->avctx->width = s->width - s->image_offset_x; + s->avctx->height = s->height - s->image_offset_y; + + switch(s->ncomponents){ + case 1: if (s->precision > 8) { + s->avctx->pix_fmt = PIX_FMT_GRAY16; + } else s->avctx->pix_fmt = PIX_FMT_GRAY8; + break; + case 3: if (s->precision > 8) { + s->avctx->pix_fmt = PIX_FMT_RGB48; + } else s->avctx->pix_fmt = PIX_FMT_RGB24; + break; + case 4: s->avctx->pix_fmt = PIX_FMT_BGRA; break; + } + + if (s->picture.data[0]) + s->avctx->release_buffer(s->avctx, &s->picture); + + if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0) + return ret; + + s->picture.pict_type = AV_PICTURE_TYPE_I; + s->picture.key_frame = 1; + + return 0; +} + +/** get common part for COD and COC segments */ +static int get_cox(J2kDecoderContext *s, J2kCodingStyle *c) +{ + if (s->buf_end - s->buf < 5) + return AVERROR(EINVAL); + c->nreslevels = bytestream_get_byte(&s->buf) + 1; // num of resolution levels - 1 + c->log2_cblk_width = bytestream_get_byte(&s->buf) + 2; // cblk width + c->log2_cblk_height = bytestream_get_byte(&s->buf) + 2; // cblk height + + c->cblk_style = bytestream_get_byte(&s->buf); + if (c->cblk_style != 0){ // cblk style + av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); + } + c->transform = bytestream_get_byte(&s->buf); // transformation + if (c->csty & J2K_CSTY_PREC) { + int i; + for (i = 0; i < c->nreslevels; i++) + bytestream_get_byte(&s->buf); + } + return 0; +} + +/** get coding parameters for a particular tile or whole image*/ +static int get_cod(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties) +{ + J2kCodingStyle tmp; + int compno; + + if (s->buf_end - s->buf < 5) + return AVERROR(EINVAL); + + tmp.log2_prec_width = + tmp.log2_prec_height = 15; + + tmp.csty = bytestream_get_byte(&s->buf); + + if (bytestream_get_byte(&s->buf)){ // progression level + av_log(s->avctx, AV_LOG_ERROR, "only LRCP progression supported\n"); + return -1; + } + + tmp.nlayers = bytestream_get_be16(&s->buf); + tmp.mct = bytestream_get_byte(&s->buf); // multiple component transformation + + get_cox(s, &tmp); + for (compno = 0; compno < s->ncomponents; compno++){ + if (!(properties[compno] & HAD_COC)) + memcpy(c + compno, &tmp, sizeof(J2kCodingStyle)); + } + return 0; +} + +/** get coding parameters for a component in the whole image on a particular tile */ +static int get_coc(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties) +{ + int compno; + + if (s->buf_end - s->buf < 2) + return AVERROR(EINVAL); + + compno = bytestream_get_byte(&s->buf); + + c += compno; + c->csty = bytestream_get_byte(&s->buf); + get_cox(s, c); + + properties[compno] |= HAD_COC; + return 0; +} + +/** get common part for QCD and QCC segments */ +static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q) +{ + int i, x; + + if (s->buf_end - s->buf < 1) + return AVERROR(EINVAL); + + x = bytestream_get_byte(&s->buf); // Sqcd + + q->nguardbits = x >> 5; + q->quantsty = x & 0x1f; + + if (q->quantsty == J2K_QSTY_NONE){ + n -= 3; + if (s->buf_end - s->buf < n || 32*3 < n) + return AVERROR(EINVAL); + for (i = 0; i < n; i++) + q->expn[i] = bytestream_get_byte(&s->buf) >> 3; + } else if (q->quantsty == J2K_QSTY_SI){ + if (s->buf_end - s->buf < 2) + return AVERROR(EINVAL); + x = bytestream_get_be16(&s->buf); + q->expn[0] = x >> 11; + q->mant[0] = x & 0x7ff; + for (i = 1; i < 32 * 3; i++){ + int curexpn = FFMAX(0, q->expn[0] - (i-1)/3); + q->expn[i] = curexpn; + q->mant[i] = q->mant[0]; + } + } else{ + n = (n - 3) >> 1; + if (s->buf_end - s->buf < n || 32*3 < n) + return AVERROR(EINVAL); + for (i = 0; i < n; i++){ + x = bytestream_get_be16(&s->buf); + q->expn[i] = x >> 11; + q->mant[i] = x & 0x7ff; + } + } + return 0; +} + +/** get quantization parameters for a particular tile or a whole image */ +static int get_qcd(J2kDecoderContext *s, int n, J2kQuantStyle *q, uint8_t *properties) +{ + J2kQuantStyle tmp; + int compno; + + if (get_qcx(s, n, &tmp)) + return -1; + for (compno = 0; compno < s->ncomponents; compno++) + if (!(properties[compno] & HAD_QCC)) + memcpy(q + compno, &tmp, sizeof(J2kQuantStyle)); + return 0; +} + +/** get quantization parameters for a component in the whole image on in a particular tile */ +static int get_qcc(J2kDecoderContext *s, int n, J2kQuantStyle *q, uint8_t *properties) +{ + int compno; + + if (s->buf_end - s->buf < 1) + return AVERROR(EINVAL); + + compno = bytestream_get_byte(&s->buf); + properties[compno] |= HAD_QCC; + return get_qcx(s, n-1, q+compno); +} + +/** get start of tile segment */ +static uint8_t get_sot(J2kDecoderContext *s) +{ + if (s->buf_end - s->buf < 4) + return AVERROR(EINVAL); + + s->curtileno = bytestream_get_be16(&s->buf); ///< Isot + if((unsigned)s->curtileno >= s->numXtiles * s->numYtiles){ + s->curtileno=0; + return AVERROR(EINVAL); + } + + s->buf += 4; ///< Psot (ignored) + + if (!bytestream_get_byte(&s->buf)){ ///< TPsot + J2kTile *tile = s->tile + s->curtileno; + + /* copy defaults */ + memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(J2kCodingStyle)); + memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(J2kQuantStyle)); + } + bytestream_get_byte(&s->buf); ///< TNsot + + return 0; +} + +static int init_tile(J2kDecoderContext *s, int tileno) +{ + int compno, + tilex = tileno % s->numXtiles, + tiley = tileno / s->numXtiles; + J2kTile *tile = s->tile + tileno; + + if (!tile->comp) + return AVERROR(ENOMEM); + for (compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = tile->comp + compno; + J2kCodingStyle *codsty = tile->codsty + compno; + J2kQuantStyle *qntsty = tile->qntsty + compno; + int ret; // global bandno + + comp->coord[0][0] = FFMAX(tilex * s->tile_width + s->tile_offset_x, s->image_offset_x); + comp->coord[0][1] = FFMIN((tilex+1)*s->tile_width + s->tile_offset_x, s->width); + comp->coord[1][0] = FFMAX(tiley * s->tile_height + s->tile_offset_y, s->image_offset_y); + comp->coord[1][1] = FFMIN((tiley+1)*s->tile_height + s->tile_offset_y, s->height); + + if (ret = ff_j2k_init_component(comp, codsty, qntsty, s->cbps[compno], s->cdx[compno], s->cdy[compno])) + return ret; + } + return 0; +} + +/** read the number of coding passes */ +static int getnpasses(J2kDecoderContext *s) +{ + int num; + if (!get_bits(s, 1)) + return 1; + if (!get_bits(s, 1)) + return 2; + if ((num = get_bits(s, 2)) != 3) + return num < 0 ? num : 3 + num; + if ((num = get_bits(s, 5)) != 31) + return num < 0 ? num : 6 + num; + num = get_bits(s, 7); + return num < 0 ? num : 37 + num; +} + +static int getlblockinc(J2kDecoderContext *s) +{ + int res = 0, ret; + while (ret = get_bits(s, 1)){ + if (ret < 0) + return ret; + res++; + } + return res; +} + +static int decode_packet(J2kDecoderContext *s, J2kCodingStyle *codsty, J2kResLevel *rlevel, int precno, + int layno, uint8_t *expn, int numgbits) +{ + int bandno, cblkny, cblknx, cblkno, ret; + + if (!(ret = get_bits(s, 1))){ + j2k_flush(s); + return 0; + } else if (ret < 0) + return ret; + + for (bandno = 0; bandno < rlevel->nbands; bandno++){ + J2kBand *band = rlevel->band + bandno; + J2kPrec *prec = band->prec + precno; + int pos = 0; + + if (band->coord[0][0] == band->coord[0][1] + || band->coord[1][0] == band->coord[1][1]) + continue; + + for (cblkny = prec->yi0; cblkny < prec->yi1; cblkny++) + for(cblknx = prec->xi0, cblkno = cblkny * band->cblknx + cblknx; cblknx < prec->xi1; cblknx++, cblkno++, pos++){ + J2kCblk *cblk = band->cblk + cblkno; + int incl, newpasses, llen; + + if (cblk->npasses) + incl = get_bits(s, 1); + else + incl = tag_tree_decode(s, prec->cblkincl + pos, layno+1) == layno; + if (!incl) + continue; + else if (incl < 0) + return incl; + + if (!cblk->npasses) + cblk->nonzerobits = expn[bandno] + numgbits - 1 - tag_tree_decode(s, prec->zerobits + pos, 100); + if ((newpasses = getnpasses(s)) < 0) + return newpasses; + if ((llen = getlblockinc(s)) < 0) + return llen; + cblk->lblock += llen; + if ((ret = get_bits(s, av_log2(newpasses) + cblk->lblock)) < 0) + return ret; + cblk->lengthinc = ret; + cblk->npasses += newpasses; + } + } + j2k_flush(s); + + if (codsty->csty & J2K_CSTY_EPH) { + if (AV_RB16(s->buf) == J2K_EPH) { + s->buf += 2; + } else { + av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found.\n"); + } + } + + for (bandno = 0; bandno < rlevel->nbands; bandno++){ + J2kBand *band = rlevel->band + bandno; + int yi, cblknw = band->prec[precno].xi1 - band->prec[precno].xi0; + for (yi = band->prec[precno].yi0; yi < band->prec[precno].yi1; yi++){ + int xi; + for (xi = band->prec[precno].xi0; xi < band->prec[precno].xi1; xi++){ + J2kCblk *cblk = band->cblk + yi * cblknw + xi; + if (s->buf_end - s->buf < cblk->lengthinc) + return AVERROR(EINVAL); + bytestream_get_buffer(&s->buf, cblk->data, cblk->lengthinc); + cblk->length += cblk->lengthinc; + cblk->lengthinc = 0; + } + } + } + return 0; +} + +static int decode_packets(J2kDecoderContext *s, J2kTile *tile) +{ + int layno, reslevelno, compno, precno, ok_reslevel; + s->bit_index = 8; + for (layno = 0; layno < tile->codsty[0].nlayers; layno++){ + ok_reslevel = 1; + for (reslevelno = 0; ok_reslevel; reslevelno++){ + ok_reslevel = 0; + for (compno = 0; compno < s->ncomponents; compno++){ + J2kCodingStyle *codsty = tile->codsty + compno; + J2kQuantStyle *qntsty = tile->qntsty + compno; + if (reslevelno < codsty->nreslevels){ + J2kResLevel *rlevel = tile->comp[compno].reslevel + reslevelno; + ok_reslevel = 1; + for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++){ + if (decode_packet(s, codsty, rlevel, precno, layno, qntsty->expn + + (reslevelno ? 3*(reslevelno-1)+1 : 0), qntsty->nguardbits)) + return -1; + } + } + } + } + } + return 0; +} + +/* TIER-1 routines */ +static void decode_sigpass(J2kT1Context *t1, int width, int height, int bpno, int bandno, int bpass_csty_symbol, + int vert_causal_ctx_csty_symbol) +{ + int mask = 3 << (bpno - 1), y0, x, y; + + for (y0 = 0; y0 < height; y0 += 4) + for (x = 0; x < width; x++) + for (y = y0; y < height && y < y0+4; y++){ + if ((t1->flags[y+1][x+1] & J2K_T1_SIG_NB) + && !(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){ + int vert_causal_ctx_csty_loc_symbol = vert_causal_ctx_csty_symbol && (x == 3 && y == 3); + if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, + vert_causal_ctx_csty_loc_symbol))){ + int xorbit, ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); + if (bpass_csty_symbol) + t1->data[y][x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask; + else + t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ? + -mask : mask; + + ff_j2k_set_significant(t1, x, y, t1->data[y][x] < 0); + } + t1->flags[y+1][x+1] |= J2K_T1_VIS; + } + } +} + +static void decode_refpass(J2kT1Context *t1, int width, int height, int bpno) +{ + int phalf, nhalf; + int y0, x, y; + + phalf = 1 << (bpno - 1); + nhalf = -phalf; + + for (y0 = 0; y0 < height; y0 += 4) + for (x = 0; x < width; x++) + for (y = y0; y < height && y < y0+4; y++){ + if ((t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)) == J2K_T1_SIG){ + int ctxno = ff_j2k_getrefctxno(t1->flags[y+1][x+1]); + int r = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? phalf : nhalf; + t1->data[y][x] += t1->data[y][x] < 0 ? -r : r; + t1->flags[y+1][x+1] |= J2K_T1_REF; + } + } +} + +static void decode_clnpass(J2kDecoderContext *s, J2kT1Context *t1, int width, int height, + int bpno, int bandno, int seg_symbols) +{ + int mask = 3 << (bpno - 1), y0, x, y, runlen, dec; + + for (y0 = 0; y0 < height; y0 += 4) { + for (x = 0; x < width; x++){ + if (y0 + 3 < height && !( + (t1->flags[y0+1][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || + (t1->flags[y0+2][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || + (t1->flags[y0+3][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || + (t1->flags[y0+4][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)))){ + if (!ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL)) + continue; + runlen = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); + runlen = (runlen << 1) | ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); + dec = 1; + } else{ + runlen = 0; + dec = 0; + } + + for (y = y0 + runlen; y < y0 + 4 && y < height; y++){ + if (!dec){ + if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))) + dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_j2k_getnbctxno(t1->flags[y+1][x+1], + bandno, 0)); + } + if (dec){ + int xorbit, ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); + t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ? -mask : mask; + ff_j2k_set_significant(t1, x, y, t1->data[y][x] < 0); + } + dec = 0; + t1->flags[y+1][x+1] &= ~J2K_T1_VIS; + } + } + } + if (seg_symbols) { + int val; + val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); + val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); + val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); + val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI); + if (val != 0xa) { + av_log(s->avctx, AV_LOG_ERROR,"Segmentation symbol value incorrect\n"); + } + } +} + +static int decode_cblk(J2kDecoderContext *s, J2kCodingStyle *codsty, J2kT1Context *t1, J2kCblk *cblk, + int width, int height, int bandpos) +{ + int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1, y, clnpass_cnt = 0; + int bpass_csty_symbol = J2K_CBLK_BYPASS & codsty->cblk_style; + int vert_causal_ctx_csty_symbol = J2K_CBLK_VSC & codsty->cblk_style; + + for (y = 0; y < height+2; y++) + memset(t1->flags[y], 0, (width+2)*sizeof(int)); + + for (y = 0; y < height; y++) + memset(t1->data[y], 0, width*sizeof(int)); + + cblk->data[cblk->length] = 0xff; + cblk->data[cblk->length+1] = 0xff; + ff_mqc_initdec(&t1->mqc, cblk->data); + + while(passno--){ + switch(pass_t){ + case 0: decode_sigpass(t1, width, height, bpno+1, bandpos, + bpass_csty_symbol && (clnpass_cnt >= 4), vert_causal_ctx_csty_symbol); + break; + case 1: decode_refpass(t1, width, height, bpno+1); + if (bpass_csty_symbol && clnpass_cnt >= 4) + ff_mqc_initdec(&t1->mqc, cblk->data); + break; + case 2: decode_clnpass(s, t1, width, height, bpno+1, bandpos, + codsty->cblk_style & J2K_CBLK_SEGSYM); + clnpass_cnt = clnpass_cnt + 1; + if (bpass_csty_symbol && clnpass_cnt >= 4) + ff_mqc_initdec(&t1->mqc, cblk->data); + break; + } + + pass_t++; + if (pass_t == 3){ + bpno--; + pass_t = 0; + } + } + return 0; +} + +static void mct_decode(J2kDecoderContext *s, J2kTile *tile) +{ + int i, *src[3], i0, i1, i2, csize = 1; + + for (i = 0; i < 3; i++) + src[i] = tile->comp[i].data; + + for (i = 0; i < 2; i++) + csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0]; + + if (tile->codsty[0].transform == FF_DWT97){ + for (i = 0; i < csize; i++){ + i0 = *src[0] + (*src[2] * 46802 >> 16); + i1 = *src[0] - (*src[1] * 22553 + *src[2] * 46802 >> 16); + i2 = *src[0] + (116130 * *src[1] >> 16); + *src[0]++ = i0; + *src[1]++ = i1; + *src[2]++ = i2; + } + } else{ + for (i = 0; i < csize; i++){ + i1 = *src[0] - (*src[2] + *src[1] >> 2); + i0 = i1 + *src[2]; + i2 = i1 + *src[1]; + *src[0]++ = i0; + *src[1]++ = i1; + *src[2]++ = i2; + } + } +} + +static int decode_tile(J2kDecoderContext *s, J2kTile *tile) +{ + int compno, reslevelno, bandno; + int x, y, *src[4]; + uint8_t *line; + J2kT1Context t1; + + for (compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = tile->comp + compno; + J2kCodingStyle *codsty = tile->codsty + compno; + + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + J2kResLevel *rlevel = comp->reslevel + reslevelno; + for (bandno = 0; bandno < rlevel->nbands; bandno++){ + J2kBand *band = rlevel->band + bandno; + int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos; + + bandpos = bandno + (reslevelno > 0); + + yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0]; + y0 = yy0; + yy1 = FFMIN(ff_j2k_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height, + band->coord[1][1]) - band->coord[1][0] + yy0; + + if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) + continue; + + for (cblky = 0; cblky < band->cblkny; cblky++){ + if (reslevelno == 0 || bandno == 1) + xx0 = 0; + else + xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0]; + x0 = xx0; + xx1 = FFMIN(ff_j2k_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width, + band->coord[0][1]) - band->coord[0][0] + xx0; + + for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){ + int y, x; + decode_cblk(s, codsty, &t1, band->cblk + cblkno, xx1 - xx0, yy1 - yy0, bandpos); + if (codsty->transform == FF_DWT53){ + for (y = yy0; y < yy1; y+=s->cdy[compno]){ + int *ptr = t1.data[y-yy0]; + for (x = xx0; x < xx1; x+=s->cdx[compno]){ + comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] = *ptr++ >> 1; + } + } + } else{ + for (y = yy0; y < yy1; y+=s->cdy[compno]){ + int *ptr = t1.data[y-yy0]; + for (x = xx0; x < xx1; x+=s->cdx[compno]){ + int tmp = ((int64_t)*ptr++) * ((int64_t)band->stepsize) >> 13, tmp2; + tmp2 = FFABS(tmp>>1) + FFABS(tmp&1); + comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] = tmp < 0 ? -tmp2 : tmp2; + } + } + } + xx0 = xx1; + xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0); + } + yy0 = yy1; + yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0); + } + } + } + ff_j2k_dwt_decode(&comp->dwt, comp->data); + src[compno] = comp->data; + } + if (tile->codsty[0].mct) + mct_decode(s, tile); + + if (s->avctx->pix_fmt == PIX_FMT_BGRA) // RGBA -> BGRA + FFSWAP(int *, src[0], src[2]); + + if (s->precision <= 8) { + for (compno = 0; compno < s->ncomponents; compno++){ + y = tile->comp[compno].coord[1][0] - s->image_offset_y; + line = s->picture.data[0] + y * s->picture.linesize[0]; + for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]){ + uint8_t *dst; + + x = tile->comp[compno].coord[0][0] - s->image_offset_x; + dst = line + x * s->ncomponents + compno; + + for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s->cdx[compno]) { + *src[compno] += 1 << (s->cbps[compno]-1); + if (*src[compno] < 0) + *src[compno] = 0; + else if (*src[compno] >= (1 << s->cbps[compno])) + *src[compno] = (1 << s->cbps[compno]) - 1; + *dst = *src[compno]++; + dst += s->ncomponents; + } + line += s->picture.linesize[0]; + } + } + } else { + for (compno = 0; compno < s->ncomponents; compno++) { + y = tile->comp[compno].coord[1][0] - s->image_offset_y; + line = s->picture.data[0] + y * s->picture.linesize[0]; + for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) { + uint16_t *dst; + x = tile->comp[compno].coord[0][0] - s->image_offset_x; + dst = line + (x * s->ncomponents + compno) * 2; + for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s-> cdx[compno]) { + int32_t val; + val = *src[compno]++ << (16 - s->cbps[compno]); + val += 1 << 15; + val = av_clip(val, 0, (1 << 16) - 1); + *dst = val; + dst += s->ncomponents; + } + line += s->picture.linesize[0]; + } + } + } + return 0; +} + +static void cleanup(J2kDecoderContext *s) +{ + int tileno, compno; + for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ + for (compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = s->tile[tileno].comp + compno; + J2kCodingStyle *codsty = s->tile[tileno].codsty + compno; + + ff_j2k_cleanup(comp, codsty); + } + av_freep(&s->tile[tileno].comp); + } + av_freep(&s->tile); +} + +static int decode_codestream(J2kDecoderContext *s) +{ + J2kCodingStyle *codsty = s->codsty; + J2kQuantStyle *qntsty = s->qntsty; + uint8_t *properties = s->properties; + + for (;;){ + int marker, len, ret = 0; + const uint8_t *oldbuf; + if (s->buf_end - s->buf < 2){ + av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n"); + break; + } + + marker = bytestream_get_be16(&s->buf); + if(s->avctx->debug & FF_DEBUG_STARTCODE) + av_log(s->avctx, AV_LOG_DEBUG, "marker 0x%.4X at pos 0x%tx\n", marker, s->buf - s->buf_start - 4); + oldbuf = s->buf; + + if (marker == J2K_SOD){ + J2kTile *tile = s->tile + s->curtileno; + if (ret = init_tile(s, s->curtileno)) + return ret; + if (ret = decode_packets(s, tile)) + return ret; + continue; + } + if (marker == J2K_EOC) + break; + + if (s->buf_end - s->buf < 2) + return AVERROR(EINVAL); + len = bytestream_get_be16(&s->buf); + switch(marker){ + case J2K_SIZ: + ret = get_siz(s); break; + case J2K_COC: + ret = get_coc(s, codsty, properties); break; + case J2K_COD: + ret = get_cod(s, codsty, properties); break; + case J2K_QCC: + ret = get_qcc(s, len, qntsty, properties); break; + case J2K_QCD: + ret = get_qcd(s, len, qntsty, properties); break; + case J2K_SOT: + if (!(ret = get_sot(s))){ + codsty = s->tile[s->curtileno].codsty; + qntsty = s->tile[s->curtileno].qntsty; + properties = s->tile[s->curtileno].properties; + } + break; + case J2K_COM: + // the comment is ignored + s->buf += len - 2; break; + default: + av_log(s->avctx, AV_LOG_ERROR, "unsupported marker 0x%.4X at pos 0x%tx\n", marker, s->buf - s->buf_start - 4); + s->buf += len - 2; break; + } + if (s->buf - oldbuf != len || ret){ + av_log(s->avctx, AV_LOG_ERROR, "error during processing marker segment %.4x\n", marker); + return ret ? ret : -1; + } + } + return 0; +} + +static int jp2_find_codestream(J2kDecoderContext *s) +{ + uint32_t atom_size; + int found_codestream = 0, search_range = 10; + + // skip jpeg2k signature atom + s->buf += 12; + + while(!found_codestream && search_range && s->buf_end - s->buf >= 8) { + atom_size = AV_RB32(s->buf); + if(AV_RB32(s->buf + 4) == JP2_CODESTREAM) { + found_codestream = 1; + s->buf += 8; + } else { + if (s->buf_end - s->buf < atom_size) + return 0; + s->buf += atom_size; + search_range--; + } + } + + if(found_codestream) + return 1; + return 0; +} + +static int decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + AVPacket *avpkt) +{ + J2kDecoderContext *s = avctx->priv_data; + AVFrame *picture = data; + int tileno, ret; + + s->avctx = avctx; + av_log(s->avctx, AV_LOG_DEBUG, "start\n"); + + // init + s->buf = s->buf_start = avpkt->data; + s->buf_end = s->buf_start + avpkt->size; + s->curtileno = -1; + + ff_j2k_init_tier1_luts(); + + if (s->buf_end - s->buf < 2) { + ret = AVERROR(EINVAL); + goto err_out; + } + + // check if the image is in jp2 format + if(s->buf_end - s->buf >= 12 && + (AV_RB32(s->buf) == 12) && (AV_RB32(s->buf + 4) == JP2_SIG_TYPE) && + (AV_RB32(s->buf + 8) == JP2_SIG_VALUE)) { + if(!jp2_find_codestream(s)) { + av_log(avctx, AV_LOG_ERROR, "couldn't find jpeg2k codestream atom\n"); + ret = -1; + goto err_out; + } + } + + if (bytestream_get_be16(&s->buf) != J2K_SOC){ + av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n"); + ret = -1; + goto err_out; + } + if (ret = decode_codestream(s)) + goto err_out; + + for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) + if (ret = decode_tile(s, s->tile + tileno)) + goto err_out; + + cleanup(s); + av_log(s->avctx, AV_LOG_DEBUG, "end\n"); + + *data_size = sizeof(AVPicture); + *picture = s->picture; + + return s->buf - s->buf_start; + +err_out: + cleanup(s); + return ret; +} + +static av_cold int j2kdec_init(AVCodecContext *avctx) +{ + J2kDecoderContext *s = avctx->priv_data; + + avcodec_get_frame_defaults((AVFrame*)&s->picture); + avctx->coded_frame = (AVFrame*)&s->picture; + return 0; +} + +static av_cold int decode_end(AVCodecContext *avctx) +{ + J2kDecoderContext *s = avctx->priv_data; + + if (s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + + return 0; +} + +AVCodec ff_jpeg2000_decoder = { + .name = "j2k", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_JPEG2000, + .priv_data_size = sizeof(J2kDecoderContext), + .init = j2kdec_init, + .close = decode_end, + .decode = decode_frame, + .capabilities = CODEC_CAP_EXPERIMENTAL, + .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"), + .pix_fmts = + (const enum PixelFormat[]) {PIX_FMT_GRAY8, PIX_FMT_RGB24, PIX_FMT_NONE} +}; diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c new file mode 100644 index 0000000000..7f8fdf14a0 --- /dev/null +++ b/libavcodec/j2kenc.c @@ -0,0 +1,1054 @@ +/* + * JPEG2000 image encoder + * Copyright (c) 2007 Kamil Nowosad + * + * 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 + */ + +/** + * JPEG2000 image encoder + * @file + * @author Kamil Nowosad + */ + +#include <float.h> +#include "avcodec.h" +#include "bytestream.h" +#include "j2k.h" +#include "libavutil/common.h" + +#define NMSEDEC_BITS 7 +#define NMSEDEC_FRACBITS (NMSEDEC_BITS-1) +#define WMSEDEC_SHIFT 13 ///< must be >= 13 +#define LAMBDA_SCALE (100000000LL << (WMSEDEC_SHIFT - 13)) + +static int lut_nmsedec_ref [1<<NMSEDEC_BITS], + lut_nmsedec_ref0[1<<NMSEDEC_BITS], + lut_nmsedec_sig [1<<NMSEDEC_BITS], + lut_nmsedec_sig0[1<<NMSEDEC_BITS]; + +static const int dwt_norms[2][4][10] = { // [dwt_type][band][rlevel] (multiplied by 10000) + {{10000, 19650, 41770, 84030, 169000, 338400, 676900, 1353000, 2706000, 5409000}, + {20220, 39890, 83550, 170400, 342700, 686300, 1373000, 2746000, 5490000}, + {20220, 39890, 83550, 170400, 342700, 686300, 1373000, 2746000, 5490000}, + {20800, 38650, 83070, 171800, 347100, 695900, 1393000, 2786000, 5572000}}, + + {{10000, 15000, 27500, 53750, 106800, 213400, 426700, 853300, 1707000, 3413000}, + {10380, 15920, 29190, 57030, 113300, 226400, 452500, 904800, 1809000}, + {10380, 15920, 29190, 57030, 113300, 226400, 452500, 904800, 1809000}, + { 7186, 9218, 15860, 30430, 60190, 120100, 240000, 479700, 959300}} +}; + +typedef struct { + J2kComponent *comp; +} J2kTile; + +typedef struct { + AVCodecContext *avctx; + AVFrame picture; + + int width, height; ///< image width and height + uint8_t cbps[4]; ///< bits per sample in particular components + int chroma_shift[2]; + uint8_t planar; + int ncomponents; + int tile_width, tile_height; ///< tile size + int numXtiles, numYtiles; + + uint8_t *buf_start; + uint8_t *buf; + uint8_t *buf_end; + int bit_index; + + int64_t lambda; + + J2kCodingStyle codsty; + J2kQuantStyle qntsty; + + J2kTile *tile; +} J2kEncoderContext; + + +/* debug */ +#if 0 +#undef ifprintf +#undef printf + +static void nspaces(FILE *fd, int n) +{ + while(n--) putc(' ', fd); +} + +static void printv(int *tab, int l) +{ + int i; + for (i = 0; i < l; i++) + printf("%.3d ", tab[i]); + printf("\n"); +} + +static void printu(uint8_t *tab, int l) +{ + int i; + for (i = 0; i < l; i++) + printf("%.3hd ", tab[i]); + printf("\n"); +} + +static void printcomp(J2kComponent *comp) +{ + int i; + for (i = 0; i < comp->y1 - comp->y0; i++) + printv(comp->data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0); +} + +static void dump(J2kEncoderContext *s, FILE *fd) +{ + int tileno, compno, reslevelno, bandno, precno; + fprintf(fd, "XSiz = %d, YSiz = %d, tile_width = %d, tile_height = %d\n" + "numXtiles = %d, numYtiles = %d, ncomponents = %d\n" + "tiles:\n", + s->width, s->height, s->tile_width, s->tile_height, + s->numXtiles, s->numYtiles, s->ncomponents); + for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ + J2kTile *tile = s->tile + tileno; + nspaces(fd, 2); + fprintf(fd, "tile %d:\n", tileno); + for(compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = tile->comp + compno; + nspaces(fd, 4); + fprintf(fd, "component %d:\n", compno); + nspaces(fd, 4); + fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d\n", + comp->x0, comp->x1, comp->y0, comp->y1); + for(reslevelno = 0; reslevelno < s->nreslevels; reslevelno++){ + J2kResLevel *reslevel = comp->reslevel + reslevelno; + nspaces(fd, 6); + fprintf(fd, "reslevel %d:\n", reslevelno); + nspaces(fd, 6); + fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d, nbands = %d\n", + reslevel->x0, reslevel->x1, reslevel->y0, + reslevel->y1, reslevel->nbands); + for(bandno = 0; bandno < reslevel->nbands; bandno++){ + J2kBand *band = reslevel->band + bandno; + nspaces(fd, 8); + fprintf(fd, "band %d:\n", bandno); + nspaces(fd, 8); + fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d," + "codeblock_width = %d, codeblock_height = %d cblknx = %d cblkny = %d\n", + band->x0, band->x1, + band->y0, band->y1, + band->codeblock_width, band->codeblock_height, + band->cblknx, band->cblkny); + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + J2kPrec *prec = band->prec + precno; + nspaces(fd, 10); + fprintf(fd, "prec %d:\n", precno); + nspaces(fd, 10); + fprintf(fd, "xi0 = %d, xi1 = %d, yi0 = %d, yi1 = %d\n", + prec->xi0, prec->xi1, prec->yi0, prec->yi1); + } + } + } + } + } +} +#endif + +/* bitstream routines */ + +/** put n times val bit */ +static void put_bits(J2kEncoderContext *s, int val, int n) // TODO: optimize +{ + while (n-- > 0){ + if (s->bit_index == 8) + { + s->bit_index = *s->buf == 0xff; + *(++s->buf) = 0; + } + *s->buf |= val << (7 - s->bit_index++); + } +} + +/** put n least significant bits of a number num */ +static void put_num(J2kEncoderContext *s, int num, int n) +{ + while(--n >= 0) + put_bits(s, (num >> n) & 1, 1); +} + +/** flush the bitstream */ +static void j2k_flush(J2kEncoderContext *s) +{ + if (s->bit_index){ + s->bit_index = 0; + s->buf++; + } +} + +/* tag tree routines */ + +/** code the value stored in node */ +static void tag_tree_code(J2kEncoderContext *s, J2kTgtNode *node, int threshold) +{ + J2kTgtNode *stack[30]; + int sp = 1, curval = 0; + stack[0] = node; + + node = node->parent; + while(node){ + if (node->vis){ + curval = node->val; + break; + } + node->vis++; + stack[sp++] = node; + node = node->parent; + } + while(--sp >= 0){ + if (stack[sp]->val >= threshold){ + put_bits(s, 0, threshold - curval); + break; + } + put_bits(s, 0, stack[sp]->val - curval); + put_bits(s, 1, 1); + curval = stack[sp]->val; + } +} + +/** update the value in node */ +static void tag_tree_update(J2kTgtNode *node) +{ + int lev = 0; + while (node->parent){ + if (node->parent->val <= node->val) + break; + node->parent->val = node->val; + node = node->parent; + lev++; + } +} + +static int put_siz(J2kEncoderContext *s) +{ + int i; + + if (s->buf_end - s->buf < 40 + 3 * s->ncomponents) + return -1; + + bytestream_put_be16(&s->buf, J2K_SIZ); + bytestream_put_be16(&s->buf, 38 + 3 * s->ncomponents); // Lsiz + bytestream_put_be16(&s->buf, 0); // Rsiz + bytestream_put_be32(&s->buf, s->width); // width + bytestream_put_be32(&s->buf, s->height); // height + bytestream_put_be32(&s->buf, 0); // X0Siz + bytestream_put_be32(&s->buf, 0); // Y0Siz + + bytestream_put_be32(&s->buf, s->tile_width); // XTSiz + bytestream_put_be32(&s->buf, s->tile_height); // YTSiz + bytestream_put_be32(&s->buf, 0); // XT0Siz + bytestream_put_be32(&s->buf, 0); // YT0Siz + bytestream_put_be16(&s->buf, s->ncomponents); // CSiz + + for (i = 0; i < s->ncomponents; i++){ // Ssiz_i XRsiz_i, YRsiz_i + bytestream_put_byte(&s->buf, 7); + bytestream_put_byte(&s->buf, i?1<<s->chroma_shift[0]:1); + bytestream_put_byte(&s->buf, i?1<<s->chroma_shift[1]:1); + } + return 0; +} + +static int put_cod(J2kEncoderContext *s) +{ + J2kCodingStyle *codsty = &s->codsty; + + if (s->buf_end - s->buf < 14) + return -1; + + bytestream_put_be16(&s->buf, J2K_COD); + bytestream_put_be16(&s->buf, 12); // Lcod + bytestream_put_byte(&s->buf, 0); // Scod + // SGcod + bytestream_put_byte(&s->buf, 0); // progression level + bytestream_put_be16(&s->buf, 1); // num of layers + if(s->avctx->pix_fmt == PIX_FMT_YUV444P){ + bytestream_put_byte(&s->buf, 2); // ICT + }else{ + bytestream_put_byte(&s->buf, 0); // unspecified + } + // SPcod + bytestream_put_byte(&s->buf, codsty->nreslevels - 1); // num of decomp. levels + bytestream_put_byte(&s->buf, codsty->log2_cblk_width-2); // cblk width + bytestream_put_byte(&s->buf, codsty->log2_cblk_height-2); // cblk height + bytestream_put_byte(&s->buf, 0); // cblk style + bytestream_put_byte(&s->buf, codsty->transform); // transformation + return 0; +} + +static int put_qcd(J2kEncoderContext *s, int compno) +{ + int i, size; + J2kCodingStyle *codsty = &s->codsty; + J2kQuantStyle *qntsty = &s->qntsty; + + if (qntsty->quantsty == J2K_QSTY_NONE) + size = 4 + 3 * (codsty->nreslevels-1); + else // QSTY_SE + size = 5 + 6 * (codsty->nreslevels-1); + + if (s->buf_end - s->buf < size + 2) + return -1; + + bytestream_put_be16(&s->buf, J2K_QCD); + bytestream_put_be16(&s->buf, size); // LQcd + bytestream_put_byte(&s->buf, (qntsty->nguardbits << 5) | qntsty->quantsty); // Sqcd + if (qntsty->quantsty == J2K_QSTY_NONE) + for (i = 0; i < codsty->nreslevels * 3 - 2; i++) + bytestream_put_byte(&s->buf, qntsty->expn[i] << 3); + else // QSTY_SE + for (i = 0; i < codsty->nreslevels * 3 - 2; i++) + bytestream_put_be16(&s->buf, (qntsty->expn[i] << 11) | qntsty->mant[i]); + return 0; +} + +static uint8_t *put_sot(J2kEncoderContext *s, int tileno) +{ + uint8_t *psotptr; + + if (s->buf_end - s->buf < 12) + return NULL; + + bytestream_put_be16(&s->buf, J2K_SOT); + bytestream_put_be16(&s->buf, 10); // Lsot + bytestream_put_be16(&s->buf, tileno); // Isot + + psotptr = s->buf; + bytestream_put_be32(&s->buf, 0); // Psot (filled in later) + + bytestream_put_byte(&s->buf, 0); // TPsot + bytestream_put_byte(&s->buf, 1); // TNsot + return psotptr; +} + +/** + * compute the sizes of tiles, resolution levels, bands, etc. + * allocate memory for them + * divide the input image into tile-components + */ +static int init_tiles(J2kEncoderContext *s) +{ + int tileno, tilex, tiley, compno; + J2kCodingStyle *codsty = &s->codsty; + J2kQuantStyle *qntsty = &s->qntsty; + + s->numXtiles = ff_j2k_ceildiv(s->width, s->tile_width); + s->numYtiles = ff_j2k_ceildiv(s->height, s->tile_height); + + s->tile = av_malloc(s->numXtiles * s->numYtiles * sizeof(J2kTile)); + if (!s->tile) + return AVERROR(ENOMEM); + for (tileno = 0, tiley = 0; tiley < s->numYtiles; tiley++) + for (tilex = 0; tilex < s->numXtiles; tilex++, tileno++){ + J2kTile *tile = s->tile + tileno; + + tile->comp = av_malloc(s->ncomponents * sizeof(J2kComponent)); + if (!tile->comp) + return AVERROR(ENOMEM); + for (compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = tile->comp + compno; + int ret, i, j; + + comp->coord[0][0] = tilex * s->tile_width; + comp->coord[0][1] = FFMIN((tilex+1)*s->tile_width, s->width); + comp->coord[1][0] = tiley * s->tile_height; + comp->coord[1][1] = FFMIN((tiley+1)*s->tile_height, s->height); + if (compno > 0) + for (i = 0; i < 2; i++) + for (j = 0; j < 2; j++) + comp->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j], s->chroma_shift[i]); + + if (ret = ff_j2k_init_component(comp, codsty, qntsty, s->cbps[compno], compno?1<<s->chroma_shift[0]:1, compno?1<<s->chroma_shift[1]:1)) + return ret; + } + } + return 0; +} + +static void copy_frame(J2kEncoderContext *s) +{ + int tileno, compno, i, y, x; + uint8_t *line; + for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ + J2kTile *tile = s->tile + tileno; + if (s->planar){ + for (compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = tile->comp + compno; + int *dst = comp->data; + line = s->picture.data[compno] + + comp->coord[1][0] * s->picture.linesize[compno] + + comp->coord[0][0]; + for (y = comp->coord[1][0]; y < comp->coord[1][1]; y++){ + uint8_t *ptr = line; + for (x = comp->coord[0][0]; x < comp->coord[0][1]; x++) + *dst++ = *ptr++ - (1 << 7); + line += s->picture.linesize[compno]; + } + } + } else{ + line = s->picture.data[0] + tile->comp[0].coord[1][0] * s->picture.linesize[0] + + tile->comp[0].coord[0][0] * s->ncomponents; + + i = 0; + for (y = tile->comp[0].coord[1][0]; y < tile->comp[0].coord[1][1]; y++){ + uint8_t *ptr = line; + for (x = tile->comp[0].coord[0][0]; x < tile->comp[0].coord[0][1]; x++, i++){ + for (compno = 0; compno < s->ncomponents; compno++){ + tile->comp[compno].data[i] = *ptr++ - (1 << 7); + } + } + line += s->picture.linesize[0]; + } + } + } +} + +static void init_quantization(J2kEncoderContext *s) +{ + int compno, reslevelno, bandno; + J2kQuantStyle *qntsty = &s->qntsty; + J2kCodingStyle *codsty = &s->codsty; + + for (compno = 0; compno < s->ncomponents; compno++){ + int gbandno = 0; + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + int nbands, lev = codsty->nreslevels - reslevelno - 1; + nbands = reslevelno ? 3 : 1; + for (bandno = 0; bandno < nbands; bandno++, gbandno++){ + int expn, mant; + + if (codsty->transform == FF_DWT97){ + int bandpos = bandno + (reslevelno>0), + ss = 81920000 / dwt_norms[0][bandpos][lev], + log = av_log2(ss); + mant = (11 - log < 0 ? ss >> log - 11 : ss << 11 - log) & 0x7ff; + expn = s->cbps[compno] - log + 13; + } else + expn = ((bandno&2)>>1) + (reslevelno>0) + s->cbps[compno]; + + qntsty->expn[gbandno] = expn; + qntsty->mant[gbandno] = mant; + } + } + } +} + +static void init_luts() +{ + int i, a, + mask = ~((1<<NMSEDEC_FRACBITS)-1); + + for (i = 0; i < (1 << NMSEDEC_BITS); i++){ + lut_nmsedec_sig[i] = FFMAX(6*i - (9<<NMSEDEC_FRACBITS-1) << 12-NMSEDEC_FRACBITS, 0); + lut_nmsedec_sig0[i] = FFMAX((i*i + (1<<NMSEDEC_FRACBITS-1) & mask) << 1, 0); + + a = (i >> (NMSEDEC_BITS-2)&2) + 1; + lut_nmsedec_ref[i] = FFMAX((-2*i + (1<<NMSEDEC_FRACBITS) + a*i - (a*a<<NMSEDEC_FRACBITS-2)) + << 13-NMSEDEC_FRACBITS, 0); + lut_nmsedec_ref0[i] = FFMAX(((i*i + (1-4*i << NMSEDEC_FRACBITS-1) + (1<<2*NMSEDEC_FRACBITS)) & mask) + << 1, 0); + } +} + +/* tier-1 routines */ +static int getnmsedec_sig(int x, int bpno) +{ + if (bpno > NMSEDEC_FRACBITS) + return lut_nmsedec_sig[(x >> (bpno - NMSEDEC_FRACBITS)) & ((1 << NMSEDEC_BITS) - 1)]; + return lut_nmsedec_sig0[x & ((1 << NMSEDEC_BITS) - 1)]; +} + +static int getnmsedec_ref(int x, int bpno) +{ + if (bpno > NMSEDEC_FRACBITS) + return lut_nmsedec_ref[(x >> (bpno - NMSEDEC_FRACBITS)) & ((1 << NMSEDEC_BITS) - 1)]; + return lut_nmsedec_ref0[x & ((1 << NMSEDEC_BITS) - 1)]; +} + +static void encode_sigpass(J2kT1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno) +{ + int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS); + int vert_causal_ctx_csty_loc_symbol; + for (y0 = 0; y0 < height; y0 += 4) + for (x = 0; x < width; x++) + for (y = y0; y < height && y < y0+4; y++){ + if (!(t1->flags[y+1][x+1] & J2K_T1_SIG) && (t1->flags[y+1][x+1] & J2K_T1_SIG_NB)){ + int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol), + bit = t1->data[y][x] & mask ? 1 : 0; + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, bit); + if (bit){ + int xorbit; + int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit); + *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS); + ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15); + } + t1->flags[y+1][x+1] |= J2K_T1_VIS; + } + } +} + +static void encode_refpass(J2kT1Context *t1, int width, int height, int *nmsedec, int bpno) +{ + int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS); + for (y0 = 0; y0 < height; y0 += 4) + for (x = 0; x < width; x++) + for (y = y0; y < height && y < y0+4; y++) + if ((t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)) == J2K_T1_SIG){ + int ctxno = ff_j2k_getrefctxno(t1->flags[y+1][x+1]); + *nmsedec += getnmsedec_ref(t1->data[y][x], bpno + NMSEDEC_FRACBITS); + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0); + t1->flags[y+1][x+1] |= J2K_T1_REF; + } +} + +static void encode_clnpass(J2kT1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno) +{ + int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS); + int vert_causal_ctx_csty_loc_symbol; + for (y0 = 0; y0 < height; y0 += 4) + for (x = 0; x < width; x++){ + if (y0 + 3 < height && !( + (t1->flags[y0+1][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || + (t1->flags[y0+2][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || + (t1->flags[y0+3][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) || + (t1->flags[y0+4][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)))) + { + // aggregation mode + int rlen; + for (rlen = 0; rlen < 4; rlen++) + if (t1->data[y0+rlen][x] & mask) + break; + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL, rlen != 4); + if (rlen == 4) + continue; + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen >> 1); + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen & 1); + for (y = y0 + rlen; y < y0 + 4; y++){ + if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){ + int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol); + if (y > y0 + rlen) + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0); + if (t1->data[y][x] & mask){ // newly significant + int xorbit; + int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); + *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS); + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit); + ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15); + } + } + t1->flags[y+1][x+1] &= ~J2K_T1_VIS; + } + } else{ + for (y = y0; y < y0 + 4 && y < height; y++){ + if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){ + int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol); + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0); + if (t1->data[y][x] & mask){ // newly significant + int xorbit; + int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit); + *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS); + ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit); + ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15); + } + } + t1->flags[y+1][x+1] &= ~J2K_T1_VIS; + } + } + } +} + +static void encode_cblk(J2kEncoderContext *s, J2kT1Context *t1, J2kCblk *cblk, J2kTile *tile, + int width, int height, int bandpos, int lev) +{ + int pass_t = 2, passno, x, y, max=0, nmsedec, bpno; + int64_t wmsedec = 0; + + for (y = 0; y < height+2; y++) + memset(t1->flags[y], 0, (width+2)*sizeof(int)); + + for (y = 0; y < height; y++){ + for (x = 0; x < width; x++){ + if (t1->data[y][x] < 0){ + t1->flags[y+1][x+1] |= J2K_T1_SGN; + t1->data[y][x] = -t1->data[y][x]; + } + max = FFMAX(max, t1->data[y][x]); + } + } + + if (max == 0){ + cblk->nonzerobits = 0; + bpno = 0; + } else{ + cblk->nonzerobits = av_log2(max) + 1 - NMSEDEC_FRACBITS; + bpno = cblk->nonzerobits - 1; + } + + ff_mqc_initenc(&t1->mqc, cblk->data); + + for (passno = 0; bpno >= 0; passno++){ + nmsedec=0; + + switch(pass_t){ + case 0: encode_sigpass(t1, width, height, bandpos, &nmsedec, bpno); + break; + case 1: encode_refpass(t1, width, height, &nmsedec, bpno); + break; + case 2: encode_clnpass(t1, width, height, bandpos, &nmsedec, bpno); + break; + } + + cblk->passes[passno].rate = 3 + ff_mqc_length(&t1->mqc); + wmsedec += (int64_t)nmsedec << (2*bpno); + cblk->passes[passno].disto = wmsedec; + + if (++pass_t == 3){ + pass_t = 0; + bpno--; + } + } + cblk->npasses = passno; + cblk->ninclpasses = passno; + + // TODO: optional flush on each pass + cblk->passes[passno-1].rate = ff_mqc_flush(&t1->mqc); +} + +/* tier-2 routines: */ + +static void putnumpasses(J2kEncoderContext *s, int n) +{ + if (n == 1) + put_num(s, 0, 1); + else if (n == 2) + put_num(s, 2, 2); + else if (n <= 5) + put_num(s, 0xc | (n-3), 4); + else if (n <= 36) + put_num(s, 0x1e0 | (n-6), 9); + else + put_num(s, 0xff80 | (n-37), 16); +} + + +static int encode_packet(J2kEncoderContext *s, J2kResLevel *rlevel, int precno, + uint8_t *expn, int numgbits) +{ + int bandno, empty = 1; + + // init bitstream + *s->buf = 0; + s->bit_index = 0; + + // header + + // is the packet empty? + for (bandno = 0; bandno < rlevel->nbands; bandno++){ + if (rlevel->band[bandno].coord[0][0] < rlevel->band[bandno].coord[0][1] + && rlevel->band[bandno].coord[1][0] < rlevel->band[bandno].coord[1][1]){ + empty = 0; + break; + } + } + + put_bits(s, !empty, 1); + if (empty){ + j2k_flush(s); + return 0; + } + + for (bandno = 0; bandno < rlevel->nbands; bandno++){ + J2kBand *band = rlevel->band + bandno; + J2kPrec *prec = band->prec + precno; + int yi, xi, pos; + int cblknw = prec->xi1 - prec->xi0; + + if (band->coord[0][0] == band->coord[0][1] + || band->coord[1][0] == band->coord[1][1]) + continue; + + for (pos=0, yi = prec->yi0; yi < prec->yi1; yi++){ + for (xi = prec->xi0; xi < prec->xi1; xi++, pos++){ + prec->cblkincl[pos].val = band->cblk[yi * cblknw + xi].ninclpasses == 0; + tag_tree_update(prec->cblkincl + pos); + prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - band->cblk[yi * cblknw + xi].nonzerobits; + tag_tree_update(prec->zerobits + pos); + } + } + + for (pos=0, yi = prec->yi0; yi < prec->yi1; yi++){ + for (xi = prec->xi0; xi < prec->xi1; xi++, pos++){ + int pad = 0, llen, length; + J2kCblk *cblk = band->cblk + yi * cblknw + xi; + + if (s->buf_end - s->buf < 20) // approximately + return -1; + + // inclusion information + tag_tree_code(s, prec->cblkincl + pos, 1); + if (!cblk->ninclpasses) + continue; + // zerobits information + tag_tree_code(s, prec->zerobits + pos, 100); + // number of passes + putnumpasses(s, cblk->ninclpasses); + + length = cblk->passes[cblk->ninclpasses-1].rate; + llen = av_log2(length) - av_log2(cblk->ninclpasses) - 2; + if (llen < 0){ + pad = -llen; + llen = 0; + } + // length of code block + put_bits(s, 1, llen); + put_bits(s, 0, 1); + put_num(s, length, av_log2(length)+1+pad); + } + } + } + j2k_flush(s); + for (bandno = 0; bandno < rlevel->nbands; bandno++){ + J2kBand *band = rlevel->band + bandno; + J2kPrec *prec = band->prec + precno; + int yi, cblknw = prec->xi1 - prec->xi0; + for (yi = prec->yi0; yi < prec->yi1; yi++){ + int xi; + for (xi = prec->xi0; xi < prec->xi1; xi++){ + J2kCblk *cblk = band->cblk + yi * cblknw + xi; + if (cblk->ninclpasses){ + if (s->buf_end - s->buf < cblk->passes[cblk->ninclpasses-1].rate) + return -1; + bytestream_put_buffer(&s->buf, cblk->data, cblk->passes[cblk->ninclpasses-1].rate); + } + } + } + } + return 0; +} + +static int encode_packets(J2kEncoderContext *s, J2kTile *tile, int tileno) +{ + int compno, reslevelno, ret; + J2kCodingStyle *codsty = &s->codsty; + J2kQuantStyle *qntsty = &s->qntsty; + + av_log(s->avctx, AV_LOG_DEBUG, "tier2\n"); + // lay-rlevel-comp-pos progression + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + for (compno = 0; compno < s->ncomponents; compno++){ + int precno; + J2kResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno; + for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){ + if (ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0), + qntsty->nguardbits)) + return ret; + } + } + } + av_log(s->avctx, AV_LOG_DEBUG, "after tier2\n"); + return 0; +} + +static int getcut(J2kCblk *cblk, int64_t lambda, int dwt_norm) +{ + int passno, res = 0; + for (passno = 0; passno < cblk->npasses; passno++){ + int dr; + int64_t dd; + + dr = cblk->passes[passno].rate + - (res ? cblk->passes[res-1].rate:0); + dd = cblk->passes[passno].disto + - (res ? cblk->passes[res-1].disto:0); + + if (((dd * dwt_norm) >> WMSEDEC_SHIFT) * dwt_norm >= dr * lambda) + res = passno+1; + } + return res; +} + +static void truncpasses(J2kEncoderContext *s, J2kTile *tile) +{ + int compno, reslevelno, bandno, cblkno, lev; + J2kCodingStyle *codsty = &s->codsty; + + for (compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = tile->comp + compno; + + for (reslevelno = 0, lev = codsty->nreslevels-1; reslevelno < codsty->nreslevels; reslevelno++, lev--){ + J2kResLevel *reslevel = comp->reslevel + reslevelno; + + for (bandno = 0; bandno < reslevel->nbands ; bandno++){ + int bandpos = bandno + (reslevelno > 0); + J2kBand *band = reslevel->band + bandno; + + for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){ + J2kCblk *cblk = band->cblk + cblkno; + + cblk->ninclpasses = getcut(cblk, s->lambda, + (int64_t)dwt_norms[codsty->transform][bandpos][lev] * (int64_t)band->stepsize >> 13); + } + } + } + } +} + +static int encode_tile(J2kEncoderContext *s, J2kTile *tile, int tileno) +{ + int compno, reslevelno, bandno, ret; + J2kT1Context t1; + J2kCodingStyle *codsty = &s->codsty; + for (compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = s->tile[tileno].comp + compno; + + av_log(s->avctx, AV_LOG_DEBUG,"dwt\n"); + if (ret = ff_j2k_dwt_encode(&comp->dwt, comp->data)) + return ret; + av_log(s->avctx, AV_LOG_DEBUG,"after dwt -> tier1\n"); + + for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){ + J2kResLevel *reslevel = comp->reslevel + reslevelno; + + for (bandno = 0; bandno < reslevel->nbands ; bandno++){ + J2kBand *band = reslevel->band + bandno; + int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos; + yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0]; + y0 = yy0; + yy1 = FFMIN(ff_j2k_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height, + band->coord[1][1]) - band->coord[1][0] + yy0; + + if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1]) + continue; + + bandpos = bandno + (reslevelno > 0); + + for (cblky = 0; cblky < band->cblkny; cblky++){ + if (reslevelno == 0 || bandno == 1) + xx0 = 0; + else + xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0]; + x0 = xx0; + xx1 = FFMIN(ff_j2k_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width, + band->coord[0][1]) - band->coord[0][0] + xx0; + + for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){ + int y, x; + if (codsty->transform == FF_DWT53){ + for (y = yy0; y < yy1; y++){ + int *ptr = t1.data[y-yy0]; + for (x = xx0; x < xx1; x++){ + *ptr++ = comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] << NMSEDEC_FRACBITS; + } + } + } else{ + for (y = yy0; y < yy1; y++){ + int *ptr = t1.data[y-yy0]; + for (x = xx0; x < xx1; x++){ + *ptr = (comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]); + *ptr = (int64_t)*ptr * (int64_t)(8192 * 8192 / band->stepsize) >> 13 - NMSEDEC_FRACBITS; + *ptr++; + } + } + } + encode_cblk(s, &t1, band->cblk + cblkno, tile, xx1 - xx0, yy1 - yy0, + bandpos, codsty->nreslevels - reslevelno - 1); + xx0 = xx1; + xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0); + } + yy0 = yy1; + yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0); + } + } + } + av_log(s->avctx, AV_LOG_DEBUG, "after tier1\n"); + } + + av_log(s->avctx, AV_LOG_DEBUG, "rate control\n"); + truncpasses(s, tile); + if (ret = encode_packets(s, tile, tileno)) + return ret; + av_log(s->avctx, AV_LOG_DEBUG, "after rate control\n"); + return 0; +} + +static void cleanup(J2kEncoderContext *s) +{ + int tileno, compno; + J2kCodingStyle *codsty = &s->codsty; + + for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ + for (compno = 0; compno < s->ncomponents; compno++){ + J2kComponent *comp = s->tile[tileno].comp + compno; + ff_j2k_cleanup(comp, codsty); + } + av_freep(&s->tile[tileno].comp); + } + av_freep(&s->tile); +} + +static void reinit(J2kEncoderContext *s) +{ + int tileno, compno; + for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ + J2kTile *tile = s->tile + tileno; + for (compno = 0; compno < s->ncomponents; compno++) + ff_j2k_reinit(tile->comp + compno, &s->codsty); + } +} + +static int encode_frame(AVCodecContext *avctx, + uint8_t *buf, int buf_size, + void *data) +{ + int tileno, ret; + J2kEncoderContext *s = avctx->priv_data; + + // init: + s->buf = s->buf_start = buf; + s->buf_end = buf + buf_size; + + s->picture = *(AVFrame*)data; + avctx->coded_frame= &s->picture; + + s->lambda = s->picture.quality * LAMBDA_SCALE; + + copy_frame(s); + reinit(s); + + if (s->buf_end - s->buf < 2) + return -1; + bytestream_put_be16(&s->buf, J2K_SOC); + if (ret = put_siz(s)) + return ret; + if (ret = put_cod(s)) + return ret; + if (ret = put_qcd(s, 0)) + return ret; + + for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ + uint8_t *psotptr; + if (!(psotptr = put_sot(s, tileno))) + return -1; + if (s->buf_end - s->buf < 2) + return -1; + bytestream_put_be16(&s->buf, J2K_SOD); + if (ret = encode_tile(s, s->tile + tileno, tileno)) + return ret; + bytestream_put_be32(&psotptr, s->buf - psotptr + 6); + } + if (s->buf_end - s->buf < 2) + return -1; + bytestream_put_be16(&s->buf, J2K_EOC); + + av_log(s->avctx, AV_LOG_DEBUG, "end\n"); + return s->buf - s->buf_start; +} + +static av_cold int j2kenc_init(AVCodecContext *avctx) +{ + int i, ret; + J2kEncoderContext *s = avctx->priv_data; + J2kCodingStyle *codsty = &s->codsty; + J2kQuantStyle *qntsty = &s->qntsty; + + s->avctx = avctx; + av_log(s->avctx, AV_LOG_DEBUG, "init\n"); + + // defaults: + // TODO: implement setting non-standard precinct size + codsty->log2_prec_width = 15; + codsty->log2_prec_height = 15; + codsty->nreslevels = 7; + codsty->log2_cblk_width = 4; + codsty->log2_cblk_height = 4; + codsty->transform = 1; + + qntsty->nguardbits = 1; + + s->tile_width = 256; + s->tile_height = 256; + + if (codsty->transform == FF_DWT53) + qntsty->quantsty = J2K_QSTY_NONE; + else + qntsty->quantsty = J2K_QSTY_SE; + + s->width = avctx->width; + s->height = avctx->height; + + for (i = 0; i < 3; i++) + s->cbps[i] = 8; + + if (avctx->pix_fmt == PIX_FMT_RGB24){ + s->ncomponents = 3; + } else if (avctx->pix_fmt == PIX_FMT_GRAY8){ + s->ncomponents = 1; + } else{ // planar YUV + s->planar = 1; + s->ncomponents = 3; + avcodec_get_chroma_sub_sample(avctx->pix_fmt, + s->chroma_shift, s->chroma_shift + 1); + } + + ff_j2k_init_tier1_luts(); + + init_luts(); + + init_quantization(s); + if (ret=init_tiles(s)) + return ret; + + av_log(s->avctx, AV_LOG_DEBUG, "after init\n"); + + return 0; +} + +static int j2kenc_destroy(AVCodecContext *avctx) +{ + J2kEncoderContext *s = avctx->priv_data; + + cleanup(s); + return 0; +} + +AVCodec ff_jpeg2000_encoder = { + .name = "j2k", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_JPEG2000, + .priv_data_size = sizeof(J2kEncoderContext), + .init = j2kenc_init, + .encode = encode_frame, + .close = j2kenc_destroy, + .capabilities= CODEC_CAP_EXPERIMENTAL, + .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"), + .pix_fmts = + (const enum PixelFormat[]) {PIX_FMT_RGB24, PIX_FMT_YUV444P, PIX_FMT_GRAY8, +/* PIX_FMT_YUV420P, + PIX_FMT_YUV422P, PIX_FMT_YUV444P, + PIX_FMT_YUV410P, PIX_FMT_YUV411P,*/ + -1} +}; diff --git a/libavcodec/jpegls.c b/libavcodec/jpegls.c index ebe6b85e98..c40b929e95 100644 --- a/libavcodec/jpegls.c +++ b/libavcodec/jpegls.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/jpegls.h b/libavcodec/jpegls.h index 1c1817e833..2c21f774e8 100644 --- a/libavcodec/jpegls.h +++ b/libavcodec/jpegls.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -86,6 +86,8 @@ static inline void ff_jpegls_downscale_state(JLSState *state, int Q){ } static inline int ff_jpegls_update_state_regular(JLSState *state, int Q, int err){ + if(FFABS(err) > 0xFFFF) + return -0x10000; state->A[Q] += FFABS(err); err *= state->twonear; state->B[Q] += err; diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index a4cfe4f9d6..0139c8860f 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +40,7 @@ * (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, Libav Golomb decoder is painfully slow +* avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow * on this errors. */ //#define JLS_BROKEN @@ -262,9 +262,9 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor JLSState *state; int off = 0, stride = 1, width, shift; - zero = av_mallocz(s->picture_ptr->linesize[0]); + zero = av_mallocz(s->picture.linesize[0]); last = zero; - cur = s->picture_ptr->data[0]; + cur = s->picture.data[0]; state = av_mallocz(sizeof(JLSState)); /* initialize JPEG-LS state from JPEG parameters */ @@ -286,8 +286,8 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor // 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; + off = av_clip(s->cur_scan - 1, 0, stride); width = s->width * stride; cur += off; for(i = 0; i < s->height; i++) { @@ -299,7 +299,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor t = *((uint16_t*)last); } last = cur; - cur += s->picture_ptr->linesize[0]; + cur += s->picture.linesize[0]; if (s->restart_interval && !--s->restart_count) { align_get_bits(&s->gb); @@ -309,11 +309,12 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor } else if(ilv == 1) { /* line interleaving */ int j; int Rc[3] = {0, 0, 0}; - memset(cur, 0, s->picture_ptr->linesize[0]); - width = s->width * 3; + stride = (s->nb_components > 1) ? 3 : 1; + memset(cur, 0, s->picture.linesize[0]); + width = s->width * stride; 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); + for(j = 0; j < stride; j++) { + ls_decode_line(state, s, last + j, cur + j, Rc[j], width, stride, j, 8); Rc[j] = last[j]; if (s->restart_interval && !--s->restart_count) { @@ -322,7 +323,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor } } last = cur; - cur += s->picture_ptr->linesize[0]; + 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"); @@ -337,22 +338,22 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor w = s->width * s->nb_components; if(s->bits <= 8){ - uint8_t *src = s->picture_ptr->data[0]; + 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_ptr->linesize[0]; + src += s->picture.linesize[0]; } }else{ - uint16_t *src = (uint16_t*) s->picture_ptr->data[0]; + 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_ptr->linesize[0]/2; + src += s->picture.linesize[0]/2; } } } diff --git a/libavcodec/jpeglsdec.h b/libavcodec/jpeglsdec.h index 473282207d..5204ecb205 100644 --- a/libavcodec/jpeglsdec.h +++ b/libavcodec/jpeglsdec.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c index 2b6e54ddd4..d72287b296 100644 --- a/libavcodec/jpeglsenc.c +++ b/libavcodec/jpeglsenc.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Michael Niedermayer * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/jvdec.c b/libavcodec/jvdec.c index 5249764347..223cef1fa7 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -2,20 +2,20 @@ * Bitmap Brothers JV video decoder * Copyright (c) 2011 Peter Ross <pross@xvid.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -172,7 +172,8 @@ static int decode_frame(AVCodecContext *avctx, if (buf < buf_end) { for (i = 0; i < AVPALETTE_COUNT && buf + 3 <= buf_end; i++) { - s->palette[i] = AV_RB24(buf) << 2; + uint32_t pal = AV_RB24(buf); + s->palette[i] = 0xFF << 24 | pal << 2 | ((pal >> 4) & 0x30303); buf += 3; } s->palette_has_changed = 1; diff --git a/libavcodec/kbdwin.c b/libavcodec/kbdwin.c index 3b590b38ef..aa4b9726f5 100644 --- a/libavcodec/kbdwin.c +++ b/libavcodec/kbdwin.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/kbdwin.h b/libavcodec/kbdwin.h index 89b569aa7c..4b939756c1 100644 --- a/libavcodec/kbdwin.h +++ b/libavcodec/kbdwin.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index f3ffd8f09e..4566e35b74 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -2,20 +2,20 @@ * Kega Game Video (KGV1) decoder * Copyright (c) 2010 Daniel Verkamp * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -150,6 +150,7 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_RGB555; + avcodec_get_frame_defaults(&c->pic); return 0; } diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index f862154b05..6d5af5d657 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -2,20 +2,20 @@ * KMVC decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -255,7 +255,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa if (ctx->pic.data[0]) avctx->release_buffer(avctx, &ctx->pic); - ctx->pic.reference = 1; + ctx->pic.reference = 3; ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID; if (avctx->get_buffer(avctx, &ctx->pic) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -268,7 +268,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa if (bytestream2_peek_byte(&ctx->g) == 127) { bytestream2_skip(&ctx->g, 3); for (i = 0; i < 127; i++) { - ctx->pal[i + (header & 0x81)] = bytestream2_get_be24(&ctx->g); + ctx->pal[i + (header & 0x81)] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g); bytestream2_skip(&ctx->g, 1); } bytestream2_seek(&ctx->g, -127 * 4 - 3, SEEK_CUR); @@ -286,7 +286,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa 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] = bytestream2_get_be24(&ctx->g); + ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g); } } @@ -373,7 +373,7 @@ static av_cold int decode_init(AVCodecContext * avctx) c->prev = c->frm1; for (i = 0; i < 256; i++) { - c->pal[i] = i * 0x10101; + c->pal[i] = 0xFF << 24 | i * 0x10101; } if (avctx->extradata_size < 12) { @@ -382,7 +382,8 @@ static av_cold int decode_init(AVCodecContext * avctx) c->palsize = 127; } else { c->palsize = AV_RL16(avctx->extradata + 10); - if (c->palsize >= MAX_PALSIZE) { + if (c->palsize >= (unsigned)MAX_PALSIZE) { + c->palsize = 127; av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n"); return AVERROR_INVALIDDATA; } @@ -397,6 +398,7 @@ static av_cold int decode_init(AVCodecContext * avctx) c->setpal = 1; } + avcodec_get_frame_defaults(&c->pic); avctx->pix_fmt = PIX_FMT_PAL8; return 0; diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 757873ead3..ef4799c153 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -2,20 +2,20 @@ * Lagarith lossless decoder * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/lagarithrac.c b/libavcodec/lagarithrac.c index ab7a60011d..56c1d0bcc0 100644 --- a/libavcodec/lagarithrac.c +++ b/libavcodec/lagarithrac.c @@ -3,20 +3,20 @@ * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com> * Copyright (c) 2009 David Conrad * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/lagarithrac.h b/libavcodec/lagarithrac.h index b9421993a4..8c78538f21 100644 --- a/libavcodec/lagarithrac.h +++ b/libavcodec/lagarithrac.h @@ -3,20 +3,20 @@ * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com> * Copyright (c) 2009 David Conrad * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/latm_parser.c b/libavcodec/latm_parser.c index bd941f6dc3..6cf45c89a8 100644 --- a/libavcodec/latm_parser.c +++ b/libavcodec/latm_parser.c @@ -1,20 +1,20 @@ /* * copyright (c) 2008 Paul Kendall <paul@kcbbs.gen.nz> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/lcl.h b/libavcodec/lcl.h index 4e7e170138..b60c0e901a 100644 --- a/libavcodec/lcl.h +++ b/libavcodec/lcl.h @@ -2,20 +2,20 @@ * LCL (LossLess Codec Library) Codec * Copyright (c) 2002-2004 Roberto Togni * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/lcldec.c b/libavcodec/lcldec.c index b66a3ce65b..57b04f79f1 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -2,20 +2,20 @@ * LCL (LossLess Codec Library) Codec * Copyright (c) 2002-2004 Roberto Togni * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -96,7 +96,13 @@ static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsign ofs = FFMIN(ofs, destptr - destptr_bak); cnt *= 4; cnt = FFMIN(cnt, destptr_end - destptr); - av_memcpy_backptr(destptr, ofs, cnt); + if (ofs) { + av_memcpy_backptr(destptr, ofs, cnt); + } else { + // Not known what the correct behaviour is, but + // this at least avoids uninitialized data. + memset(destptr, 0, cnt); + } destptr += cnt; } maskbit >>= 1; @@ -453,6 +459,7 @@ static av_cold int decode_init(AVCodecContext *avctx) unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) + AV_LZO_OUTPUT_PADDING; unsigned int max_decomp_size; + avcodec_get_frame_defaults(&c->pic); if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); return 1; diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c index 4c902d5f17..9f66960910 100644 --- a/libavcodec/lclenc.c +++ b/libavcodec/lclenc.c @@ -2,20 +2,20 @@ * LCL (LossLess Codec Library) Codec * Copyright (c) 2002-2004 Roberto Togni * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libaacplus.c b/libavcodec/libaacplus.c new file mode 100644 index 0000000000..fd01f0a7b0 --- /dev/null +++ b/libavcodec/libaacplus.c @@ -0,0 +1,134 @@ +/* + * Interface to libaacplus for aac+ (sbr+ps) encoding + * Copyright (c) 2010 tipok <piratfm@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 + * Interface to libaacplus for aac+ (sbr+ps) encoding. + */ + +#include "avcodec.h" +#include <aacplus.h> + +typedef struct aacPlusAudioContext { + aacplusEncHandle aacplus_handle; +} aacPlusAudioContext; + +static av_cold int aacPlus_encode_init(AVCodecContext *avctx) +{ + aacPlusAudioContext *s = avctx->priv_data; + aacplusEncConfiguration *aacplus_cfg; + unsigned long samples_input, max_bytes_output; + + /* number of channels */ + if (avctx->channels < 1 || avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); + return -1; + } + + s->aacplus_handle = aacplusEncOpen(avctx->sample_rate, + avctx->channels, + &samples_input, &max_bytes_output); + if(!s->aacplus_handle) { + av_log(avctx, AV_LOG_ERROR, "can't open encoder\n"); + return -1; + } + + /* check aacplus version */ + aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle); + + /* put the options in the configuration struct */ + if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) { + av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile); + aacplusEncClose(s->aacplus_handle); + return -1; + } + + aacplus_cfg->bitRate = avctx->bit_rate; + aacplus_cfg->bandWidth = avctx->cutoff; + aacplus_cfg->outputFormat = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER); + aacplus_cfg->inputFormat = AACPLUS_INPUT_16BIT; + if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) { + av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n"); + return -1; + } + + avctx->frame_size = samples_input / avctx->channels; + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + + /* Set decoder specific info */ + avctx->extradata_size = 0; + if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { + + unsigned char *buffer = NULL; + unsigned long decoder_specific_info_size; + + if (aacplusEncGetDecoderSpecificInfo(s->aacplus_handle, &buffer, + &decoder_specific_info_size) == 1) { + avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE); + avctx->extradata_size = decoder_specific_info_size; + memcpy(avctx->extradata, buffer, avctx->extradata_size); + } +#undef free + free(buffer); +#define free please_use_av_free + } + return 0; +} + +static int aacPlus_encode_frame(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) +{ + aacPlusAudioContext *s = avctx->priv_data; + int bytes_written; + + bytes_written = aacplusEncEncode(s->aacplus_handle, + data, + avctx->frame_size * avctx->channels, + frame, + buf_size); + + return bytes_written; +} + +static av_cold int aacPlus_encode_close(AVCodecContext *avctx) +{ + aacPlusAudioContext *s = avctx->priv_data; + + av_freep(&avctx->coded_frame); + av_freep(&avctx->extradata); + + aacplusEncClose(s->aacplus_handle); + return 0; +} + +AVCodec ff_libaacplus_encoder = { + .name = "libaacplus", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_AAC, + .priv_data_size = sizeof(aacPlusAudioContext), + .init = aacPlus_encode_init, + .encode = aacPlus_encode_frame, + .close = aacPlus_encode_close, + .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"), +}; diff --git a/libavcodec/libavcodec.v b/libavcodec/libavcodec.v index 0e1c2e1cda..6539d7bdb7 100644 --- a/libavcodec/libavcodec.v +++ b/libavcodec/libavcodec.v @@ -2,5 +2,30 @@ LIBAVCODEC_$MAJOR { global: av*; audio_resample; audio_resample_close; + #deprecated, remove after next bump + img_get_alpha_info; + dsputil_init; + ff_find_pix_fmt; + ff_framenum_to_drop_timecode; + ff_framenum_to_smtpe_timecode; + ff_raw_pix_fmt_tags; + ff_init_smtpe_timecode; + ff_fft*; + ff_mdct*; + ff_dct*; + ff_rdft*; + ff_prores_idct_put_10_sse2; + ff_simple_idct*; + ff_aanscales; + ff_faan*; + ff_mmx_idct; + ff_fdct*; + fdct_ifast; + j_rev_dct; + ff_mmxext_idct; + ff_idct_xvid*; + ff_jpeg_fdct*; + #XBMC's configure checks for ff_vdpau_vc1_decode_picture() + ff_vdpau_vc1_decode_picture; local: *; }; diff --git a/libavcodec/libcelt_dec.c b/libavcodec/libcelt_dec.c new file mode 100644 index 0000000000..ffc608f234 --- /dev/null +++ b/libavcodec/libcelt_dec.c @@ -0,0 +1,145 @@ +/* + * Xiph CELT decoder using libcelt + * Copyright (c) 2011 Nicolas George + * + * 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 <celt/celt.h> +#include <celt/celt_header.h> +#include "avcodec.h" +#include "libavutil/intreadwrite.h" + +struct libcelt_context { + CELTMode *mode; + CELTDecoder *dec; + AVFrame frame; + int discard; +}; + +static int ff_celt_error_to_averror(int err) +{ + switch (err) { + case CELT_BAD_ARG: return AVERROR(EINVAL); +#ifdef CELT_BUFFER_TOO_SMALL + case CELT_BUFFER_TOO_SMALL: return AVERROR(ENOBUFS); +#endif + case CELT_INTERNAL_ERROR: return AVERROR(EFAULT); + case CELT_CORRUPTED_DATA: return AVERROR_INVALIDDATA; + case CELT_UNIMPLEMENTED: return AVERROR(ENOSYS); +#ifdef ENOTRECOVERABLE + case CELT_INVALID_STATE: return AVERROR(ENOTRECOVERABLE); +#endif + case CELT_ALLOC_FAIL: return AVERROR(ENOMEM); + default: return AVERROR(EINVAL); + } +} + +static int ff_celt_bitstream_version_hack(CELTMode *mode) +{ + CELTHeader header = { .version_id = 0 }; + celt_header_init(&header, mode, 960, 2); + return header.version_id; +} + +static av_cold int libcelt_dec_init(AVCodecContext *c) +{ + struct libcelt_context *celt = c->priv_data; + int err; + + if (!c->channels || !c->frame_size || + c->frame_size > INT_MAX / sizeof(int16_t) / c->channels) + return AVERROR(EINVAL); + celt->mode = celt_mode_create(c->sample_rate, c->frame_size, &err); + if (!celt->mode) + return ff_celt_error_to_averror(err); + celt->dec = celt_decoder_create_custom(celt->mode, c->channels, &err); + if (!celt->dec) { + celt_mode_destroy(celt->mode); + return ff_celt_error_to_averror(err); + } + if (c->extradata_size >= 4) { + celt->discard = AV_RL32(c->extradata); + if (celt->discard < 0 || celt->discard >= c->frame_size) { + av_log(c, AV_LOG_WARNING, + "Invalid overlap (%d), ignored.\n", celt->discard); + celt->discard = 0; + } + } + if (c->extradata_size >= 8) { + unsigned version = AV_RL32(c->extradata + 4); + unsigned lib_version = ff_celt_bitstream_version_hack(celt->mode); + if (version != lib_version) + av_log(c, AV_LOG_WARNING, + "CELT bitstream version 0x%x may be " + "improperly decoded by libcelt for version 0x%x.\n", + version, lib_version); + } + c->sample_fmt = AV_SAMPLE_FMT_S16; + avcodec_get_frame_defaults(&celt->frame); + c->coded_frame = &celt->frame; + return 0; +} + +static av_cold int libcelt_dec_close(AVCodecContext *c) +{ + struct libcelt_context *celt = c->priv_data; + + celt_decoder_destroy(celt->dec); + celt_mode_destroy(celt->mode); + return 0; +} + +static int libcelt_dec_decode(AVCodecContext *c, void *frame, + int *got_frame_ptr, AVPacket *pkt) +{ + struct libcelt_context *celt = c->priv_data; + int err; + int16_t *pcm; + + celt->frame.nb_samples = c->frame_size; + err = c->get_buffer(c, &celt->frame); + if (err < 0) { + av_log(c, AV_LOG_ERROR, "get_buffer() failed\n"); + return err; + } + pcm = (int16_t *)celt->frame.data[0]; + err = celt_decode(celt->dec, pkt->data, pkt->size, pcm, c->frame_size); + if (err < 0) + return ff_celt_error_to_averror(err); + if (celt->discard) { + celt->frame.nb_samples -= celt->discard; + memmove(pcm, pcm + celt->discard * c->channels, + celt->frame.nb_samples * c->channels * sizeof(int16_t)); + celt->discard = 0; + } + *got_frame_ptr = 1; + *(AVFrame *)frame = celt->frame; + return pkt->size; +} + +AVCodec ff_libcelt_decoder = { + .name = "libcelt", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_CELT, + .priv_data_size = sizeof(struct libcelt_context), + .init = libcelt_dec_init, + .close = libcelt_dec_close, + .decode = libcelt_dec_decode, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Xiph CELT decoder using libcelt"), +}; diff --git a/libavcodec/libdirac.h b/libavcodec/libdirac.h index 4403fb2a39..388674eb0d 100644 --- a/libavcodec/libdirac.h +++ b/libavcodec/libdirac.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -30,7 +30,7 @@ #include <libdirac_common/dirac_types.h> /** -* Table providing a Dirac chroma format to Libav pixel format mapping. +* Table providing a Dirac chroma format to FFmpeg pixel format mapping. */ static const struct { enum PixelFormat ff_pix_fmt; diff --git a/libavcodec/libdirac_libschro.c b/libavcodec/libdirac_libschro.c index 45b5b83264..c8657e2fd2 100644 --- a/libavcodec/libdirac_libschro.c +++ b/libavcodec/libdirac_libschro.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libdirac_libschro.h b/libavcodec/libdirac_libschro.h index a80558f820..aecdb30e76 100644 --- a/libavcodec/libdirac_libschro.h +++ b/libavcodec/libdirac_libschro.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libdiracdec.c b/libavcodec/libdiracdec.c index 65651711b1..ed8b16d6dc 100644 --- a/libavcodec/libdiracdec.c +++ b/libavcodec/libdiracdec.c @@ -3,20 +3,20 @@ * Copyright (c) 2005 BBC, Andrew Kennedy <dirac at rd dot bbc dot co dot uk> * Copyright (c) 2006-2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -47,7 +47,7 @@ typedef struct DiracDecoderParams { /** -* returns Libav chroma format +* returns FFmpeg chroma format */ static enum PixelFormat get_chroma_format(dirac_chroma_t dirac_pix_fmt) { @@ -103,7 +103,7 @@ static int libdirac_decode_frame(AVCodecContext *avccontext, case STATE_SEQUENCE: { - /* tell Libav about sequence details */ + /* tell FFmpeg about sequence details */ dirac_sourceparams_t *src_params = &p_dirac_params->p_decoder->src_params; if (av_image_check_size(src_params->width, src_params->height, diff --git a/libavcodec/libdiracenc.c b/libavcodec/libdiracenc.c index 156ba57718..385bce9018 100644 --- a/libavcodec/libdiracenc.c +++ b/libavcodec/libdiracenc.c @@ -3,20 +3,20 @@ * Copyright (c) 2005 BBC, Andrew Kennedy <dirac at rd dot bbc dot co dot uk> * Copyright (c) 2006-2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libfaac.c b/libavcodec/libfaac.c index 7ee1f3c3fa..31dc1a41ed 100644 --- a/libavcodec/libfaac.c +++ b/libavcodec/libfaac.c @@ -2,20 +2,20 @@ * Interface to libfaac for aac encoding * Copyright (c) 2002 Gildas Bazin <gbazin@netcourrier.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -31,6 +31,13 @@ typedef struct FaacAudioContext { faacEncHandle faac_handle; } FaacAudioContext; +static const int channel_maps[][6] = { + { 2, 0, 1 }, //< C L R + { 2, 0, 1, 3 }, //< C L R Cs + { 2, 0, 1, 3, 4 }, //< C L R Ls Rs + { 2, 0, 1, 4, 5, 3 }, //< C L R Ls Rs LFE +}; + static av_cold int Faac_encode_init(AVCodecContext *avctx) { FaacAudioContext *s = avctx->priv_data; @@ -86,6 +93,9 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx) } faac_cfg->outputFormat = 1; faac_cfg->inputFormat = FAAC_INPUT_16BIT; + if (avctx->channels > 2) + memcpy(faac_cfg->channel_map, channel_maps[avctx->channels-3], + avctx->channels * sizeof(int)); avctx->frame_size = samples_input / avctx->channels; diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index 1fa04cf9d9..1a2145581a 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -3,20 +3,20 @@ * Copyright (c) 2005 Alban Bedel <albeu@free.fr> * Copyright (c) 2006, 2007 Michel Bardiaux <mbardiaux@mediaxim.be> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -32,6 +32,13 @@ #include "avcodec.h" #include "gsm.h" +static av_cold int libgsm_encode_close(AVCodecContext *avctx) { + av_freep(&avctx->coded_frame); + gsm_destroy(avctx->priv_data); + avctx->priv_data = NULL; + return 0; +} + static av_cold int libgsm_encode_init(AVCodecContext *avctx) { if (avctx->channels > 1) { av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n", @@ -55,6 +62,8 @@ static av_cold int libgsm_encode_init(AVCodecContext *avctx) { } avctx->priv_data = gsm_create(); + if (!avctx->priv_data) + goto error; switch(avctx->codec_id) { case CODEC_ID_GSM: @@ -70,16 +79,13 @@ static av_cold int libgsm_encode_init(AVCodecContext *avctx) { } avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; + if (!avctx->coded_frame) + goto error; return 0; -} - -static av_cold int libgsm_encode_close(AVCodecContext *avctx) { - av_freep(&avctx->coded_frame); - gsm_destroy(avctx->priv_data); - avctx->priv_data = NULL; - return 0; +error: + libgsm_encode_close(avctx); + return -1; } static int libgsm_encode_frame(AVCodecContext *avctx, diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 3ac033f758..d75183e9c0 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -2,20 +2,20 @@ * Interface to libmp3lame for mp3 encoding * Copyright (c) 2002 Lennert Buytenhek <buytenh@gnu.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -31,13 +31,17 @@ #include "mpegaudio.h" #include <lame/lame.h> -#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4) +#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4+1000) // FIXME: Buffer size to small? Adding 1000 to make up for it. typedef struct Mp3AudioContext { AVClass *class; lame_global_flags *gfp; int stereo; uint8_t buffer[BUFFER_SIZE]; int buffer_index; + struct { + int *left; + int *right; + } s32_data; int reservoir; } Mp3AudioContext; @@ -45,8 +49,11 @@ static av_cold int MP3lame_encode_init(AVCodecContext *avctx) { Mp3AudioContext *s = avctx->priv_data; - if (avctx->channels > 2) - return -1; + if (avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, + "Invalid number of channels %d, must be <= 2\n", avctx->channels); + return AVERROR(EINVAL); + } s->stereo = avctx->channels > 1 ? 1 : 0; @@ -73,8 +80,25 @@ static av_cold int MP3lame_encode_init(AVCodecContext *avctx) goto err_close; avctx->frame_size = lame_get_framesize(s->gfp); - avctx->coded_frame = avcodec_alloc_frame(); - avctx->coded_frame->key_frame = 1; + + if(!(avctx->coded_frame= avcodec_alloc_frame())) { + lame_close(s->gfp); + + return AVERROR(ENOMEM); + } + + if(AV_SAMPLE_FMT_S32 == avctx->sample_fmt && s->stereo) { + int nelem = 2 * avctx->frame_size; + + if(! (s->s32_data.left = av_malloc(nelem * sizeof(int)))) { + av_freep(&avctx->coded_frame); + lame_close(s->gfp); + + return AVERROR(ENOMEM); + } + + s->s32_data.right = s->s32_data.left + avctx->frame_size; + } return 0; @@ -152,21 +176,63 @@ static int MP3lame_encode_frame(AVCodecContext *avctx, unsigned char *frame, /* lame 3.91 dies on '1-channel interleaved' data */ - if (data) { + if (!data){ + lame_result= lame_encode_flush( + s->gfp, + s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index + ); +#if 2147483647 == INT_MAX + }else if(AV_SAMPLE_FMT_S32 == avctx->sample_fmt){ if (s->stereo) { - lame_result = lame_encode_buffer_interleaved(s->gfp, data, - avctx->frame_size, - s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index); + int32_t *rp = data; + int32_t *mp = rp + 2*avctx->frame_size; + int *wpl = s->s32_data.left; + int *wpr = s->s32_data.right; + + while (rp < mp) { + *wpl++ = *rp++; + *wpr++ = *rp++; + } + + lame_result = lame_encode_buffer_int( + s->gfp, + s->s32_data.left, + s->s32_data.right, + avctx->frame_size, + s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index + ); } else { - lame_result = lame_encode_buffer(s->gfp, data, data, - avctx->frame_size, s->buffer + - s->buffer_index, BUFFER_SIZE - - s->buffer_index); + lame_result = lame_encode_buffer_int( + s->gfp, + data, + data, + avctx->frame_size, + s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index + ); + } +#endif + }else{ + if (s->stereo) { + lame_result = lame_encode_buffer_interleaved( + s->gfp, + data, + avctx->frame_size, + s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index + ); + } else { + lame_result = lame_encode_buffer( + s->gfp, + data, + data, + avctx->frame_size, + s->buffer + s->buffer_index, + BUFFER_SIZE - s->buffer_index + ); } - } else { - lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index, - BUFFER_SIZE - s->buffer_index); } if (lame_result < 0) { @@ -205,6 +271,7 @@ static av_cold int MP3lame_encode_close(AVCodecContext *avctx) { Mp3AudioContext *s = avctx->priv_data; + av_freep(&s->s32_data.left); av_freep(&avctx->coded_frame); lame_close(s->gfp); @@ -235,6 +302,9 @@ AVCodec ff_libmp3lame_encoder = { .close = MP3lame_encode_close, .capabilities = CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, +#if 2147483647 == INT_MAX + AV_SAMPLE_FMT_S32, +#endif AV_SAMPLE_FMT_NONE }, .supported_samplerates = sSampleRates, .long_name = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"), diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c index ded92179d3..7a0555e6c5 100644 --- a/libavcodec/libopencore-amr.c +++ b/libavcodec/libopencore-amr.c @@ -2,20 +2,20 @@ * AMR Audio decoder stub * Copyright (c) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -196,10 +196,13 @@ static av_cold int amr_nb_encode_init(AVCodecContext *avctx) avctx->frame_size = 160; avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); s->enc_state = Encoder_Interface_init(s->enc_dtx); if (!s->enc_state) { av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n"); + av_freep(&avctx->coded_frame); return -1; } diff --git a/libavcodec/libopenjpeg.c b/libavcodec/libopenjpeg.c deleted file mode 100644 index 1facd21044..0000000000 --- a/libavcodec/libopenjpeg.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * JPEG 2000 decoding support via OpenJPEG - * Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.net> - * - * This file is part of Libav. - * - * Libav 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. - * - * Libav 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 Libav; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** -* @file -* JPEG 2000 decoder using libopenjpeg -*/ - -#include "libavutil/imgutils.h" -#include "avcodec.h" -#include "libavutil/intreadwrite.h" -#include "thread.h" -#define OPJ_STATIC -#include <openjpeg.h> - -#define JP2_SIG_TYPE 0x6A502020 -#define JP2_SIG_VALUE 0x0D0A870A - -typedef struct { - opj_dparameters_t dec_params; - AVFrame image; -} LibOpenJPEGContext; - -static int check_image_attributes(opj_image_t *image) -{ - return image->comps[0].dx == image->comps[1].dx && - image->comps[1].dx == image->comps[2].dx && - image->comps[0].dy == image->comps[1].dy && - image->comps[1].dy == image->comps[2].dy && - image->comps[0].prec == image->comps[1].prec && - image->comps[1].prec == image->comps[2].prec; -} - -static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx) -{ - LibOpenJPEGContext *ctx = avctx->priv_data; - - opj_set_default_decoder_parameters(&ctx->dec_params); - avctx->coded_frame = &ctx->image; - return 0; -} - -static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx) -{ - LibOpenJPEGContext *ctx = avctx->priv_data; - - avctx->coded_frame = &ctx->image; - return 0; -} - -static int libopenjpeg_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - LibOpenJPEGContext *ctx = avctx->priv_data; - AVFrame *picture = &ctx->image, *output = data; - opj_dinfo_t *dec; - opj_cio_t *stream; - opj_image_t *image; - int width, height, has_alpha = 0, ret = -1; - int x, y, index; - uint8_t *img_ptr; - int adjust[4]; - - *data_size = 0; - - // Check if input is a raw jpeg2k codestream or in jp2 wrapping - if((AV_RB32(buf) == 12) && - (AV_RB32(buf + 4) == JP2_SIG_TYPE) && - (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { - dec = opj_create_decompress(CODEC_JP2); - } else { - // If the AVPacket contains a jp2c box, then skip to - // the starting byte of the codestream. - if (AV_RB32(buf + 4) == AV_RB32("jp2c")) - buf += 8; - dec = opj_create_decompress(CODEC_J2K); - } - - if(!dec) { - av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); - return -1; - } - opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); - - ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER; - // Tie decoder with decoding parameters - opj_setup_decoder(dec, &ctx->dec_params); - stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); - if(!stream) { - av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); - opj_destroy_decompress(dec); - return -1; - } - - // Decode the header only - image = opj_decode_with_info(dec, stream, NULL); - opj_cio_close(stream); - if(!image) { - av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); - opj_destroy_decompress(dec); - return -1; - } - width = image->x1 - image->x0; - height = image->y1 - image->y0; - if(av_image_check_size(width, height, 0, avctx) < 0) { - av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); - goto done; - } - avcodec_set_dimensions(avctx, width, height); - - switch(image->numcomps) - { - case 1: avctx->pix_fmt = PIX_FMT_GRAY8; - break; - case 3: if(check_image_attributes(image)) { - avctx->pix_fmt = PIX_FMT_RGB24; - } else { - avctx->pix_fmt = PIX_FMT_GRAY8; - av_log(avctx, AV_LOG_ERROR, "Only first component will be used.\n"); - } - break; - case 4: has_alpha = 1; - avctx->pix_fmt = PIX_FMT_RGBA; - break; - default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps); - goto done; - } - - if(picture->data[0]) - ff_thread_release_buffer(avctx, picture); - - if(ff_thread_get_buffer(avctx, picture) < 0){ - av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n"); - return -1; - } - - ff_thread_finish_setup(avctx); - - ctx->dec_params.cp_limit_decoding = NO_LIMITATION; - ctx->dec_params.cp_reduce = avctx->lowres; - // Tie decoder with decoding parameters - opj_setup_decoder(dec, &ctx->dec_params); - stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); - if(!stream) { - av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); - opj_destroy_decompress(dec); - return -1; - } - - // Decode the codestream - image = opj_decode_with_info(dec, stream, NULL); - opj_cio_close(stream); - - for(x = 0; x < image->numcomps; x++) { - adjust[x] = FFMAX(image->comps[x].prec - 8, 0); - } - - for(y = 0; y < avctx->height; y++) { - index = y*avctx->width; - img_ptr = picture->data[0] + y*picture->linesize[0]; - for(x = 0; x < avctx->width; x++, index++) { - *img_ptr++ = image->comps[0].data[index] >> adjust[0]; - if(image->numcomps > 2 && check_image_attributes(image)) { - *img_ptr++ = image->comps[1].data[index] >> adjust[1]; - *img_ptr++ = image->comps[2].data[index] >> adjust[2]; - if(has_alpha) - *img_ptr++ = image->comps[3].data[index] >> adjust[3]; - } - } - } - - *output = ctx->image; - *data_size = sizeof(AVPicture); - ret = buf_size; - -done: - opj_image_destroy(image); - opj_destroy_decompress(dec); - return ret; -} - -static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) -{ - LibOpenJPEGContext *ctx = avctx->priv_data; - - if(ctx->image.data[0]) - ff_thread_release_buffer(avctx, &ctx->image); - return 0 ; -} - - -AVCodec ff_libopenjpeg_decoder = { - .name = "libopenjpeg", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_JPEG2000, - .priv_data_size = sizeof(LibOpenJPEGContext), - .init = libopenjpeg_decode_init, - .close = libopenjpeg_decode_close, - .decode = libopenjpeg_decode_frame, - .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, - .max_lowres = 5, - .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), - .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy) -}; diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c new file mode 100644 index 0000000000..89bfb34913 --- /dev/null +++ b/libavcodec/libopenjpegdec.c @@ -0,0 +1,366 @@ +/* + * JPEG 2000 decoding support via OpenJPEG + * Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.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 +* JPEG 2000 decoder using libopenjpeg +*/ + +#include "libavutil/imgutils.h" +#include "libavutil/pixfmt.h" +#include "avcodec.h" +#include "libavutil/intreadwrite.h" +#include "thread.h" +#define OPJ_STATIC +#include <openjpeg.h> + +#define JP2_SIG_TYPE 0x6A502020 +#define JP2_SIG_VALUE 0x0D0A870A + +typedef struct { + opj_dparameters_t dec_params; + AVFrame image; +} LibOpenJPEGContext; + +static enum PixelFormat check_image_attributes(AVCodecContext *avctx, opj_image_t *image) +{ + opj_image_comp_t c0 = image->comps[0]; + opj_image_comp_t c1 = image->comps[1]; + opj_image_comp_t c2 = image->comps[2]; + int compRatio = 0; + compRatio |= c0.dx << 15 | c0.dy << 12; + compRatio |= c1.dx << 9 | c1.dy << 6; + compRatio |= c2.dx << 3 | c2.dy; + + if (image->numcomps == 4) { + if (c0.prec == 8) { + if (compRatio == 0112222 && + image->comps[3].dx == 1 && image->comps[3].dy == 1) { + return PIX_FMT_YUVA420P; + } else { + return PIX_FMT_RGBA; + } + } else { + return PIX_FMT_RGBA64; + } + } + + switch (compRatio) { + case 0111111: goto libopenjpeg_yuv444_rgb; + case 0111212: return PIX_FMT_YUV440P; + case 0112121: goto libopenjpeg_yuv422; + case 0112222: goto libopenjpeg_yuv420; + default: goto libopenjpeg_rgb; + } + +libopenjpeg_yuv420: + switch (c0.prec) { + case 8: return PIX_FMT_YUV420P; + case 9: return PIX_FMT_YUV420P9; + case 10: return PIX_FMT_YUV420P10; + case 16: return PIX_FMT_YUV420P16; + } + +libopenjpeg_yuv422: + switch (c0.prec) { + case 8: return PIX_FMT_YUV422P; + case 9: return PIX_FMT_YUV422P9; + case 10: return PIX_FMT_YUV422P10; + case 16: return PIX_FMT_YUV422P16; + } + +libopenjpeg_yuv444_rgb: + switch (c0.prec) { + case 8: return PIX_FMT_RGB24; + case 9: return PIX_FMT_YUV444P9; + case 10: return PIX_FMT_YUV444P10; + case 16: return PIX_FMT_YUV444P16; + } + +libopenjpeg_rgb: + switch (c0.prec) { + case 8: return PIX_FMT_RGB24; + default: return PIX_FMT_RGB48; + } + + return PIX_FMT_RGB24; +} + +static inline int libopenjpeg_ispacked(enum PixelFormat pix_fmt) { + int i, component_plane; + component_plane = av_pix_fmt_descriptors[pix_fmt].comp[0].plane; + for(i = 1; i < av_pix_fmt_descriptors[pix_fmt].nb_components; i++) { + if (component_plane != av_pix_fmt_descriptors[pix_fmt].comp[i].plane) + return 0; + } + return 1; +} + +static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image) { + uint8_t *img_ptr; + int index, x, y, c; + for(y = 0; y < picture->height; y++) { + index = y*picture->width; + img_ptr = picture->data[0] + y*picture->linesize[0]; + for(x = 0; x < picture->width; x++, index++) { + for(c = 0; c < image->numcomps; c++) { + *img_ptr++ = image->comps[c].data[index]; + } + } + } +} + +static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image) { + uint16_t *img_ptr; + int index, x, y, c; + int adjust[4]; + for (x = 0; x < image->numcomps; x++) { + adjust[x] = FFMAX(FFMIN(16 - image->comps[x].prec, 8), 0); + } + for (y = 0; y < picture->height; y++) { + index = y*picture->width; + img_ptr = (uint16_t*) (picture->data[0] + y*picture->linesize[0]); + for (x = 0; x < picture->width; x++, index++) { + for (c = 0; c < image->numcomps; c++) { + *img_ptr++ = image->comps[c].data[index] << adjust[c]; + } + } + } +} + +static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) { + int *comp_data; + uint8_t *img_ptr; + int index, x, y; + + for(index = 0; index < image->numcomps; index++) { + comp_data = image->comps[index].data; + for(y = 0; y < image->comps[index].h; y++) { + img_ptr = picture->data[index] + y * picture->linesize[index]; + for(x = 0; x < image->comps[index].w; x++) { + *img_ptr = (uint8_t) *comp_data; + img_ptr++; + comp_data++; + } + } + } +} + +static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) { + int *comp_data; + uint16_t *img_ptr; + int index, x, y; + for(index = 0; index < image->numcomps; index++) { + comp_data = image->comps[index].data; + for(y = 0; y < image->comps[index].h; y++) { + img_ptr = (uint16_t*) (picture->data[index] + y * picture->linesize[index]); + for(x = 0; x < image->comps[index].w; x++) { + *img_ptr = *comp_data; + img_ptr++; + comp_data++; + } + } + } +} + +static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx) +{ + LibOpenJPEGContext *ctx = avctx->priv_data; + + opj_set_default_decoder_parameters(&ctx->dec_params); + avcodec_get_frame_defaults(&ctx->image); + avctx->coded_frame = &ctx->image; + return 0; +} + +static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx) +{ + LibOpenJPEGContext *ctx = avctx->priv_data; + + avctx->coded_frame = &ctx->image; + return 0; +} + +static int libopenjpeg_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + AVPacket *avpkt) +{ + uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + LibOpenJPEGContext *ctx = avctx->priv_data; + AVFrame *picture = &ctx->image, *output = data; + opj_dinfo_t *dec; + opj_cio_t *stream; + opj_image_t *image; + int width, height, ret = -1; + int pixel_size = 0; + int ispacked = 0; + + *data_size = 0; + + // Check if input is a raw jpeg2k codestream or in jp2 wrapping + if((AV_RB32(buf) == 12) && + (AV_RB32(buf + 4) == JP2_SIG_TYPE) && + (AV_RB32(buf + 8) == JP2_SIG_VALUE)) { + dec = opj_create_decompress(CODEC_JP2); + } else { + // If the AVPacket contains a jp2c box, then skip to + // the starting byte of the codestream. + if (AV_RB32(buf + 4) == AV_RB32("jp2c")) + buf += 8; + dec = opj_create_decompress(CODEC_J2K); + } + + if(!dec) { + av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n"); + return -1; + } + opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL); + + ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER; + // Tie decoder with decoding parameters + opj_setup_decoder(dec, &ctx->dec_params); + stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); + if(!stream) { + av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); + opj_destroy_decompress(dec); + return -1; + } + + // Decode the header only + image = opj_decode_with_info(dec, stream, NULL); + opj_cio_close(stream); + if(!image) { + av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n"); + opj_destroy_decompress(dec); + return -1; + } + width = image->x1 - image->x0; + height = image->y1 - image->y0; + if(av_image_check_size(width, height, 0, avctx) < 0) { + av_log(avctx, AV_LOG_ERROR, "%dx%d dimension invalid.\n", width, height); + goto done; + } + avcodec_set_dimensions(avctx, width, height); + + switch (image->numcomps) { + case 1: avctx->pix_fmt = (image->comps[0].bpp == 8) ? PIX_FMT_GRAY8 : PIX_FMT_GRAY16; + break; + case 2: avctx->pix_fmt = PIX_FMT_GRAY8A; + break; + case 3: + case 4: avctx->pix_fmt = check_image_attributes(avctx, image); + break; + default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps); + goto done; + } + + if(picture->data[0]) + ff_thread_release_buffer(avctx, picture); + + if(ff_thread_get_buffer(avctx, picture) < 0){ + av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n"); + return -1; + } + + ctx->dec_params.cp_limit_decoding = NO_LIMITATION; + ctx->dec_params.cp_reduce = avctx->lowres; + // Tie decoder with decoding parameters + opj_setup_decoder(dec, &ctx->dec_params); + stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size); + if(!stream) { + av_log(avctx, AV_LOG_ERROR, "Codestream could not be opened for reading.\n"); + opj_destroy_decompress(dec); + return -1; + } + + // Decode the codestream + image = opj_decode_with_info(dec, stream, NULL); + opj_cio_close(stream); + + pixel_size = av_pix_fmt_descriptors[avctx->pix_fmt].comp[0].step_minus1 + 1; + ispacked = libopenjpeg_ispacked(avctx->pix_fmt); + + switch (pixel_size) { + case 1: + if (ispacked) { + libopenjpeg_copy_to_packed8(picture, image); + } else { + libopenjpeg_copyto8(picture, image); + } + break; + case 2: + if (ispacked) { + libopenjpeg_copy_to_packed8(picture, image); + } else { + libopenjpeg_copyto16(picture, image); + } + break; + case 3: + case 4: + if (ispacked) { + libopenjpeg_copy_to_packed8(picture, image); + } + break; + case 6: + case 8: + if (ispacked) { + libopenjpeg_copy_to_packed16(picture, image); + } + break; + default: + av_log(avctx, AV_LOG_ERROR, "unsupported pixel size %d\n", pixel_size); + goto done; + } + + *output = ctx->image; + *data_size = sizeof(AVPicture); + ret = buf_size; + +done: + opj_image_destroy(image); + opj_destroy_decompress(dec); + return ret; +} + +static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx) +{ + LibOpenJPEGContext *ctx = avctx->priv_data; + + if(ctx->image.data[0]) + ff_thread_release_buffer(avctx, &ctx->image); + return 0 ; +} + + +AVCodec ff_libopenjpeg_decoder = { + .name = "libopenjpeg", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_JPEG2000, + .priv_data_size = sizeof(LibOpenJPEGContext), + .init = libopenjpeg_decode_init, + .close = libopenjpeg_decode_close, + .decode = libopenjpeg_decode_frame, + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, + .max_lowres = 5, + .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 decoder"), + .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy) +}; diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c new file mode 100644 index 0000000000..30cc022f93 --- /dev/null +++ b/libavcodec/libopenjpegenc.c @@ -0,0 +1,445 @@ +/* + * JPEG 2000 encoding support via OpenJPEG + * Copyright (c) 2011 Michael Bradshaw <mbradshaw@sorensonmedia.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 +* JPEG 2000 encoder using libopenjpeg +*/ + +#include "libavutil/imgutils.h" +#include "libavutil/avassert.h" +#include "avcodec.h" +#include "libavutil/intreadwrite.h" +#define OPJ_STATIC +#include <openjpeg.h> + +typedef struct { + opj_image_t *image; + opj_cparameters_t enc_params; + opj_cinfo_t *compress; + opj_event_mgr_t event_mgr; +} LibOpenJPEGContext; + +static void error_callback(const char *msg, void *data) +{ + av_log((AVCodecContext*)data, AV_LOG_ERROR, "libopenjpeg: %s\n", msg); +} + +static void warning_callback(const char *msg, void *data) +{ + av_log((AVCodecContext*)data, AV_LOG_WARNING, "libopenjpeg: %s\n", msg); +} + +static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters) +{ + opj_image_cmptparm_t *cmptparm; + opj_image_t *img; + int i; + int bpp = 8; + int sub_dx[4]; + int sub_dy[4]; + int numcomps = 0; + OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN; + + sub_dx[0] = sub_dx[3] = 1; + sub_dy[0] = sub_dy[3] = 1; + sub_dx[1] = sub_dx[2] = 1<<av_pix_fmt_descriptors[avctx->pix_fmt].log2_chroma_w; + sub_dy[1] = sub_dy[2] = 1<<av_pix_fmt_descriptors[avctx->pix_fmt].log2_chroma_h; + + switch (avctx->pix_fmt) { + case PIX_FMT_GRAY8: + color_space = CLRSPC_GRAY; + numcomps = 1; + break; + case PIX_FMT_GRAY8A: + color_space = CLRSPC_GRAY; + numcomps = 2; + break; + case PIX_FMT_GRAY16: + color_space = CLRSPC_GRAY; + numcomps = 1; + bpp = 16; + break; + case PIX_FMT_RGB24: + color_space = CLRSPC_SRGB; + numcomps = 3; + break; + case PIX_FMT_RGBA: + color_space = CLRSPC_SRGB; + numcomps = 4; + break; + case PIX_FMT_RGB48: + color_space = CLRSPC_SRGB; + numcomps = 3; + bpp = 16; + break; + case PIX_FMT_RGBA64: + color_space = CLRSPC_SRGB; + numcomps = 4; + bpp = 16; + break; + case PIX_FMT_YUV420P: + color_space = CLRSPC_SYCC; + numcomps = 3; + break; + case PIX_FMT_YUV422P: + color_space = CLRSPC_SYCC; + numcomps = 3; + break; + case PIX_FMT_YUV440P: + color_space = CLRSPC_SYCC; + numcomps = 3; + break; + case PIX_FMT_YUV444P: + color_space = CLRSPC_SYCC; + numcomps = 3; + break; + case PIX_FMT_YUVA420P: + color_space = CLRSPC_SYCC; + numcomps = 4; + break; + case PIX_FMT_YUV420P9: + case PIX_FMT_YUV422P9: + case PIX_FMT_YUV444P9: + color_space = CLRSPC_SYCC; + numcomps = 3; + bpp = 9; + break; + case PIX_FMT_YUV420P10: + case PIX_FMT_YUV422P10: + case PIX_FMT_YUV444P10: + color_space = CLRSPC_SYCC; + numcomps = 3; + bpp = 10; + break; + case PIX_FMT_YUV420P16: + case PIX_FMT_YUV422P16: + case PIX_FMT_YUV444P16: + color_space = CLRSPC_SYCC; + numcomps = 3; + bpp = 16; + break; + default: + av_log(avctx, AV_LOG_ERROR, "The requested pixel format '%s' is not supported\n", av_get_pix_fmt_name(avctx->pix_fmt)); + return NULL; + } + + cmptparm = av_mallocz(numcomps * sizeof(opj_image_cmptparm_t)); + if (!cmptparm) { + av_log(avctx, AV_LOG_ERROR, "Not enough memory"); + return NULL; + } + for (i = 0; i < numcomps; i++) { + cmptparm[i].prec = bpp; + cmptparm[i].bpp = bpp; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = sub_dx[i]; + cmptparm[i].dy = sub_dy[i]; + cmptparm[i].w = avctx->width / sub_dx[i]; + cmptparm[i].h = avctx->height / sub_dy[i]; + } + + img = opj_image_create(numcomps, cmptparm, color_space); + av_freep(&cmptparm); + return img; +} + +static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx) +{ + LibOpenJPEGContext *ctx = avctx->priv_data; + + opj_set_default_encoder_parameters(&ctx->enc_params); + ctx->enc_params.tcp_numlayers = 1; + ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2; + ctx->enc_params.cp_disto_alloc = 1; + + ctx->compress = opj_create_compress(CODEC_J2K); + if (!ctx->compress) { + av_log(avctx, AV_LOG_ERROR, "Error creating the compressor\n"); + return AVERROR(ENOMEM); + } + + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) { + av_freep(&ctx->compress); + av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n"); + return AVERROR(ENOMEM); + } + + ctx->image = mj2_create_image(avctx, &ctx->enc_params); + if (!ctx->image) { + av_freep(&ctx->compress); + av_freep(&avctx->coded_frame); + av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n"); + return AVERROR(EINVAL); + } + + memset(&ctx->event_mgr, 0, sizeof(opj_event_mgr_t)); + ctx->event_mgr.error_handler = error_callback; + ctx->event_mgr.warning_handler = warning_callback; + ctx->event_mgr.info_handler = NULL; + opj_set_event_mgr((opj_common_ptr)ctx->compress, &ctx->event_mgr, avctx); + + return 0; +} + +static int libopenjpeg_copy_packed8(AVCodecContext *avctx, AVFrame *frame, opj_image_t *image) +{ + int compno; + int x; + int y; + int image_index; + int frame_index; + const int numcomps = image->numcomps; + + for (compno = 0; compno < numcomps; ++compno) { + if (image->comps[compno].w > frame->linesize[0] / numcomps) { + av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); + return 0; + } + } + + for (compno = 0; compno < numcomps; ++compno) { + for (y = 0; y < avctx->height; ++y) { + image_index = y * avctx->width; + frame_index = y * frame->linesize[0] + compno; + for (x = 0; x < avctx->width; ++x) { + image->comps[compno].data[image_index++] = frame->data[0][frame_index]; + frame_index += numcomps; + } + } + } + + return 1; +} + +static int libopenjpeg_copy_packed16(AVCodecContext *avctx, AVFrame *frame, opj_image_t *image) +{ + int compno; + int x; + int y; + int image_index; + int frame_index; + const int numcomps = image->numcomps; + uint16_t *frame_ptr = (uint16_t*)frame->data[0]; + + for (compno = 0; compno < numcomps; ++compno) { + if (image->comps[compno].w > frame->linesize[0] / numcomps) { + av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); + return 0; + } + } + + for (compno = 0; compno < numcomps; ++compno) { + for (y = 0; y < avctx->height; ++y) { + image_index = y * avctx->width; + frame_index = y * (frame->linesize[0] / 2) + compno; + for (x = 0; x < avctx->width; ++x) { + image->comps[compno].data[image_index++] = frame_ptr[frame_index]; + frame_index += numcomps; + } + } + } + + return 1; +} + +static int libopenjpeg_copy_unpacked8(AVCodecContext *avctx, AVFrame *frame, opj_image_t *image) +{ + int compno; + int x; + int y; + int width; + int height; + int image_index; + int frame_index; + const int numcomps = image->numcomps; + + for (compno = 0; compno < numcomps; ++compno) { + if (image->comps[compno].w > frame->linesize[compno]) { + av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); + return 0; + } + } + + for (compno = 0; compno < numcomps; ++compno) { + width = avctx->width / image->comps[compno].dx; + height = avctx->height / image->comps[compno].dy; + for (y = 0; y < height; ++y) { + image_index = y * width; + frame_index = y * frame->linesize[compno]; + for (x = 0; x < width; ++x) { + image->comps[compno].data[image_index++] = frame->data[compno][frame_index++]; + } + } + } + + return 1; +} + +static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, AVFrame *frame, opj_image_t *image) +{ + int compno; + int x; + int y; + int width; + int height; + int image_index; + int frame_index; + const int numcomps = image->numcomps; + uint16_t *frame_ptr; + + for (compno = 0; compno < numcomps; ++compno) { + if (image->comps[compno].w > frame->linesize[compno]) { + av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n"); + return 0; + } + } + + for (compno = 0; compno < numcomps; ++compno) { + width = avctx->width / image->comps[compno].dx; + height = avctx->height / image->comps[compno].dy; + frame_ptr = (uint16_t*)frame->data[compno]; + for (y = 0; y < height; ++y) { + image_index = y * width; + frame_index = y * (frame->linesize[compno] / 2); + for (x = 0; x < width; ++x) { + image->comps[compno].data[image_index++] = frame_ptr[frame_index++]; + } + } + } + + return 1; +} + +static int libopenjpeg_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) +{ + AVFrame *frame = data; + LibOpenJPEGContext *ctx = avctx->priv_data; + opj_cinfo_t *compress = ctx->compress; + opj_image_t *image = ctx->image; + opj_cio_t *stream; + int cpyresult = 0; + int len = 0; + + // x0, y0 is the top left corner of the image + // x1, y1 is the width, height of the reference grid + image->x0 = 0; + image->y0 = 0; + image->x1 = (avctx->width - 1) * ctx->enc_params.subsampling_dx + 1; + image->y1 = (avctx->height - 1) * ctx->enc_params.subsampling_dy + 1; + + switch (avctx->pix_fmt) { + case PIX_FMT_RGB24: + case PIX_FMT_RGBA: + case PIX_FMT_GRAY8A: + cpyresult = libopenjpeg_copy_packed8(avctx, frame, image); + break; + case PIX_FMT_RGB48: + case PIX_FMT_RGBA64: + cpyresult = libopenjpeg_copy_packed16(avctx, frame, image); + break; + case PIX_FMT_GRAY8: + case PIX_FMT_YUV420P: + case PIX_FMT_YUV422P: + case PIX_FMT_YUV440P: + case PIX_FMT_YUV444P: + case PIX_FMT_YUVA420P: + cpyresult = libopenjpeg_copy_unpacked8(avctx, frame, image); + break; + case PIX_FMT_GRAY16: + case PIX_FMT_YUV420P9: + case PIX_FMT_YUV420P10: + case PIX_FMT_YUV420P16: + case PIX_FMT_YUV422P9: + case PIX_FMT_YUV422P10: + case PIX_FMT_YUV422P16: + case PIX_FMT_YUV444P9: + case PIX_FMT_YUV444P10: + case PIX_FMT_YUV444P16: + cpyresult = libopenjpeg_copy_unpacked16(avctx, frame, image); + break; + default: + av_log(avctx, AV_LOG_ERROR, "The frame's pixel format '%s' is not supported\n", av_get_pix_fmt_name(avctx->pix_fmt)); + return AVERROR(EINVAL); + break; + } + + if (!cpyresult) { + av_log(avctx, AV_LOG_ERROR, "Could not copy the frame data to the internal image buffer\n"); + return -1; + } + + opj_setup_encoder(compress, &ctx->enc_params, image); + stream = opj_cio_open((opj_common_ptr)compress, NULL, 0); + if (!stream) { + av_log(avctx, AV_LOG_ERROR, "Error creating the cio stream\n"); + return AVERROR(ENOMEM); + } + + if (!opj_encode(compress, stream, image, NULL)) { + opj_cio_close(stream); + av_log(avctx, AV_LOG_ERROR, "Error during the opj encode\n"); + return -1; + } + + len = cio_tell(stream); + if (len > buf_size) { + opj_cio_close(stream); + av_log(avctx, AV_LOG_ERROR, "Error with buf_size, not large enough to hold the frame\n"); + return -1; + } + + memcpy(buf, stream->buffer, len); + opj_cio_close(stream); + return len; +} + +static av_cold int libopenjpeg_encode_close(AVCodecContext *avctx) +{ + LibOpenJPEGContext *ctx = avctx->priv_data; + + opj_destroy_compress(ctx->compress); + opj_image_destroy(ctx->image); + av_freep(&avctx->coded_frame); + return 0 ; +} + + +AVCodec ff_libopenjpeg_encoder = { + .name = "libopenjpeg", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_JPEG2000, + .priv_data_size = sizeof(LibOpenJPEGContext), + .init = libopenjpeg_encode_init, + .encode = libopenjpeg_encode_frame, + .close = libopenjpeg_encode_close, + .capabilities = 0, + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24,PIX_FMT_RGBA,PIX_FMT_RGB48,PIX_FMT_RGBA64, + PIX_FMT_GRAY8,PIX_FMT_GRAY8A,PIX_FMT_GRAY16, + PIX_FMT_YUV420P,PIX_FMT_YUV422P,PIX_FMT_YUVA420P, + PIX_FMT_YUV440P,PIX_FMT_YUV444P, + PIX_FMT_YUV420P9,PIX_FMT_YUV422P9,PIX_FMT_YUV444P9, + PIX_FMT_YUV420P10,PIX_FMT_YUV422P10,PIX_FMT_YUV444P10, + PIX_FMT_YUV420P16,PIX_FMT_YUV422P16,PIX_FMT_YUV444P16, + PIX_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 encoder"), +} ; diff --git a/libavcodec/libschroedinger.c b/libavcodec/libschroedinger.c index 527c4927ae..a2ea5ddbdc 100644 --- a/libavcodec/libschroedinger.c +++ b/libavcodec/libschroedinger.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libschroedinger.h b/libavcodec/libschroedinger.h index 814782111b..262e0220bf 100644 --- a/libavcodec/libschroedinger.h +++ b/libavcodec/libschroedinger.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c index 184e8cb42b..f45326b144 100644 --- a/libavcodec/libschroedingerdec.c +++ b/libavcodec/libschroedingerdec.c @@ -2,20 +2,20 @@ * Dirac decoder support via Schroedinger libraries * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -118,7 +118,7 @@ static SchroBuffer *FindNextSchroParseUnit(SchroParseUnitContext *parse_ctx) } /** -* Returns Libav chroma format. +* Returns FFmpeg chroma format. */ static enum PixelFormat get_chroma_format(SchroChromaFormat schro_pix_fmt) { @@ -169,7 +169,7 @@ static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext) p_schro_params->format = schro_decoder_get_video_format(decoder); - /* Tell Libav about sequence details. */ + /* Tell FFmpeg about sequence details. */ if (av_image_check_size(p_schro_params->format->width, p_schro_params->format->height, 0, avccontext) < 0) { av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n", diff --git a/libavcodec/libschroedingerenc.c b/libavcodec/libschroedingerenc.c index 2aadd3af3f..27267cd0e9 100644 --- a/libavcodec/libschroedingerenc.c +++ b/libavcodec/libschroedingerenc.c @@ -2,20 +2,20 @@ * Dirac encoder support via Schroedinger libraries * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c index eba2f16949..fdc39532b7 100644 --- a/libavcodec/libspeexdec.c +++ b/libavcodec/libspeexdec.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2008 David Conrad * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c index bccf9c810d..8cdc911c2a 100644 --- a/libavcodec/libspeexenc.c +++ b/libavcodec/libspeexenc.c @@ -2,20 +2,20 @@ * Copyright (C) 2009 Justin Ruggles * Copyright (c) 2009 Xuggle Incorporated * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libstagefright.cpp b/libavcodec/libstagefright.cpp new file mode 100644 index 0000000000..8e93b4610b --- /dev/null +++ b/libavcodec/libstagefright.cpp @@ -0,0 +1,562 @@ +/* + * Interface to the Android Stagefright library for + * H/W accelerated H.264 decoding + * + * Copyright (C) 2011 Mohamed Naufal + * Copyright (C) 2011 Martin Storsjö + * + * 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 <binder/ProcessState.h> +#include <media/stagefright/MetaData.h> +#include <media/stagefright/MediaBufferGroup.h> +#include <media/stagefright/MediaDebug.h> +#include <media/stagefright/MediaDefs.h> +#include <media/stagefright/OMXClient.h> +#include <media/stagefright/OMXCodec.h> +#include <utils/List.h> +#include <new> + +extern "C" { +#include "avcodec.h" +#include "libavutil/imgutils.h" +} + +#define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00 + +using namespace android; + +struct Frame { + status_t status; + size_t size; + int64_t time; + int key; + uint8_t *buffer; + MediaBuffer* mbuffer; + int32_t w, h; +}; + +class CustomSource; + +struct StagefrightContext { + AVCodecContext *avctx; + AVBitStreamFilterContext *bsfc; + uint8_t* orig_extradata; + int orig_extradata_size; + sp<MediaSource> *source; + List<Frame*> *in_queue, *out_queue; + pthread_mutex_t in_mutex, out_mutex; + pthread_cond_t condition; + pthread_t decode_thread_id; + + Frame *end_frame; + bool source_done; + volatile sig_atomic_t thread_started, thread_exited, stop_decode; + + AVFrame ret_frame; + + uint8_t *dummy_buf; + int dummy_bufsize; + + OMXClient *client; + sp<MediaSource> *decoder; + const char *decoder_component; +}; + +class CustomSource : public MediaSource { +public: + CustomSource(AVCodecContext *avctx, sp<MetaData> meta) { + s = (StagefrightContext*)avctx->priv_data; + source_meta = meta; + frame_size = (avctx->width * avctx->height * 3) / 2; + buf_group.add_buffer(new MediaBuffer(frame_size)); + } + + virtual sp<MetaData> getFormat() { + return source_meta; + } + + virtual status_t start(MetaData *params) { + return OK; + } + + virtual status_t stop() { + return OK; + } + + virtual status_t read(MediaBuffer **buffer, + const MediaSource::ReadOptions *options) { + Frame *frame; + status_t ret; + + if (s->thread_exited) + return ERROR_END_OF_STREAM; + pthread_mutex_lock(&s->in_mutex); + + while (s->in_queue->empty()) + pthread_cond_wait(&s->condition, &s->in_mutex); + + frame = *s->in_queue->begin(); + ret = frame->status; + + if (ret == OK) { + ret = buf_group.acquire_buffer(buffer); + if (ret == OK) { + memcpy((*buffer)->data(), frame->buffer, frame->size); + (*buffer)->set_range(0, frame->size); + (*buffer)->meta_data()->clear(); + (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame,frame->key); + (*buffer)->meta_data()->setInt64(kKeyTime, frame->time); + } else { + av_log(s->avctx, AV_LOG_ERROR, "Failed to acquire MediaBuffer\n"); + } + av_freep(&frame->buffer); + } + + s->in_queue->erase(s->in_queue->begin()); + pthread_mutex_unlock(&s->in_mutex); + + av_freep(&frame); + return ret; + } + +private: + MediaBufferGroup buf_group; + sp<MetaData> source_meta; + StagefrightContext *s; + int frame_size; +}; + +void* decode_thread(void *arg) +{ + AVCodecContext *avctx = (AVCodecContext*)arg; + StagefrightContext *s = (StagefrightContext*)avctx->priv_data; + Frame* frame; + MediaBuffer *buffer; + int decode_done = 0; + do { + buffer = NULL; + frame = (Frame*)av_mallocz(sizeof(Frame)); + if (!frame) { + frame = s->end_frame; + frame->status = AVERROR(ENOMEM); + decode_done = 1; + s->end_frame = NULL; + } else { + frame->status = (*s->decoder)->read(&buffer); + if (frame->status == OK) { + sp<MetaData> outFormat = (*s->decoder)->getFormat(); + outFormat->findInt32(kKeyWidth , &frame->w); + outFormat->findInt32(kKeyHeight, &frame->h); + frame->size = buffer->range_length(); + frame->mbuffer = buffer; + } else if (frame->status == INFO_FORMAT_CHANGED) { + if (buffer) + buffer->release(); + av_free(frame); + continue; + } else { + decode_done = 1; + } + } + while (true) { + pthread_mutex_lock(&s->out_mutex); + if (s->out_queue->size() >= 10) { + pthread_mutex_unlock(&s->out_mutex); + usleep(10000); + continue; + } + break; + } + s->out_queue->push_back(frame); + pthread_mutex_unlock(&s->out_mutex); + } while (!decode_done && !s->stop_decode); + + s->thread_exited = true; + + return 0; +} + +static av_cold int Stagefright_init(AVCodecContext *avctx) +{ + StagefrightContext *s = (StagefrightContext*)avctx->priv_data; + sp<MetaData> meta, outFormat; + int32_t colorFormat = 0; + int ret; + + if (!avctx->extradata || !avctx->extradata_size || avctx->extradata[0] != 1) + return -1; + + s->avctx = avctx; + s->bsfc = av_bitstream_filter_init("h264_mp4toannexb"); + if (!s->bsfc) { + av_log(avctx, AV_LOG_ERROR, "Cannot open the h264_mp4toannexb BSF!\n"); + return -1; + } + + s->orig_extradata_size = avctx->extradata_size; + s->orig_extradata = (uint8_t*) av_mallocz(avctx->extradata_size + + FF_INPUT_BUFFER_PADDING_SIZE); + if (!s->orig_extradata) { + ret = AVERROR(ENOMEM); + goto fail; + } + memcpy(s->orig_extradata, avctx->extradata, avctx->extradata_size); + + meta = new MetaData; + if (meta == NULL) { + ret = AVERROR(ENOMEM); + goto fail; + } + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC); + meta->setInt32(kKeyWidth, avctx->width); + meta->setInt32(kKeyHeight, avctx->height); + meta->setData(kKeyAVCC, kTypeAVCC, avctx->extradata, avctx->extradata_size); + + android::ProcessState::self()->startThreadPool(); + + s->source = new sp<MediaSource>(); + *s->source = new CustomSource(avctx, meta); + s->in_queue = new List<Frame*>; + s->out_queue = new List<Frame*>; + s->client = new OMXClient; + s->end_frame = (Frame*)av_mallocz(sizeof(Frame)); + if (s->source == NULL || !s->in_queue || !s->out_queue || !s->client || + !s->end_frame) { + ret = AVERROR(ENOMEM); + goto fail; + } + + if (s->client->connect() != OK) { + av_log(avctx, AV_LOG_ERROR, "Cannot connect OMX client\n"); + ret = -1; + goto fail; + } + + s->decoder = new sp<MediaSource>(); + *s->decoder = OMXCodec::Create(s->client->interface(), meta, + false, *s->source, NULL, + OMXCodec::kClientNeedsFramebuffer); + if ((*s->decoder)->start() != OK) { + av_log(avctx, AV_LOG_ERROR, "Cannot start decoder\n"); + ret = -1; + s->client->disconnect(); + goto fail; + } + + outFormat = (*s->decoder)->getFormat(); + outFormat->findInt32(kKeyColorFormat, &colorFormat); + if (colorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar || + colorFormat == OMX_COLOR_FormatYUV420SemiPlanar) + avctx->pix_fmt = PIX_FMT_NV21; + else + avctx->pix_fmt = PIX_FMT_YUV420P; + + outFormat->findCString(kKeyDecoderComponent, &s->decoder_component); + if (s->decoder_component) + s->decoder_component = av_strdup(s->decoder_component); + + pthread_mutex_init(&s->in_mutex, NULL); + pthread_mutex_init(&s->out_mutex, NULL); + pthread_cond_init(&s->condition, NULL); + return 0; + +fail: + av_bitstream_filter_close(s->bsfc); + av_freep(&s->orig_extradata); + av_freep(&s->end_frame); + delete s->in_queue; + delete s->out_queue; + delete s->client; + return ret; +} + +static int Stagefright_decode_frame(AVCodecContext *avctx, void *data, + int *data_size, AVPacket *avpkt) +{ + StagefrightContext *s = (StagefrightContext*)avctx->priv_data; + Frame *frame; + MediaBuffer *mbuffer; + status_t status; + size_t size; + uint8_t *buf; + const uint8_t *src_data[3]; + int w, h; + int src_linesize[3]; + int orig_size = avpkt->size; + AVPacket pkt = *avpkt; + int ret; + + if (!s->thread_started) { + pthread_create(&s->decode_thread_id, NULL, &decode_thread, avctx); + s->thread_started = true; + } + + if (avpkt && avpkt->data) { + av_bitstream_filter_filter(s->bsfc, avctx, NULL, &pkt.data, &pkt.size, + avpkt->data, avpkt->size, avpkt->flags & AV_PKT_FLAG_KEY); + avpkt = &pkt; + } + + if (!s->source_done) { + if(!s->dummy_buf) { + s->dummy_buf = (uint8_t*)av_malloc(avpkt->size); + if (!s->dummy_buf) + return AVERROR(ENOMEM); + s->dummy_bufsize = avpkt->size; + memcpy(s->dummy_buf, avpkt->data, avpkt->size); + } + + frame = (Frame*)av_mallocz(sizeof(Frame)); + if (avpkt->data) { + frame->status = OK; + frame->size = avpkt->size; + // Stagefright can't handle negative timestamps - + // if needed, work around this by offsetting them manually? + if (avpkt->pts >= 0) + frame->time = avpkt->pts; + frame->key = avpkt->flags & AV_PKT_FLAG_KEY ? 1 : 0; + frame->buffer = (uint8_t*)av_malloc(avpkt->size); + if (!frame->buffer) { + av_freep(&frame); + return AVERROR(ENOMEM); + } + uint8_t *ptr = avpkt->data; + // The OMX.SEC decoder fails without this. + if (avpkt->size == orig_size + avctx->extradata_size) { + ptr += avctx->extradata_size; + frame->size = orig_size; + } + memcpy(frame->buffer, ptr, orig_size); + } else { + frame->status = ERROR_END_OF_STREAM; + s->source_done = true; + } + + while (true) { + if (s->thread_exited) { + s->source_done = true; + break; + } + pthread_mutex_lock(&s->in_mutex); + if (s->in_queue->size() >= 10) { + pthread_mutex_unlock(&s->in_mutex); + usleep(10000); + continue; + } + s->in_queue->push_back(frame); + pthread_cond_signal(&s->condition); + pthread_mutex_unlock(&s->in_mutex); + break; + } + } + while (true) { + pthread_mutex_lock(&s->out_mutex); + if (!s->out_queue->empty()) break; + pthread_mutex_unlock(&s->out_mutex); + if (s->source_done) { + usleep(10000); + continue; + } else { + return orig_size; + } + } + + frame = *s->out_queue->begin(); + s->out_queue->erase(s->out_queue->begin()); + pthread_mutex_unlock(&s->out_mutex); + + mbuffer = frame->mbuffer; + status = frame->status; + size = frame->size; + w = frame->w; + h = frame->h; + av_freep(&frame); + + if (status == ERROR_END_OF_STREAM) + return 0; + if (status != OK) { + if (status == AVERROR(ENOMEM)) + return status; + av_log(avctx, AV_LOG_ERROR, "Decode failed: %x\n", status); + return -1; + } + + // The OMX.SEC decoder doesn't signal the modified width/height + if (s->decoder_component && !strncmp(s->decoder_component, "OMX.SEC", 7) && + (w & 15 || h & 15)) { + if (((w + 15)&~15) * ((h + 15)&~15) * 3/2 == size) { + w = (w + 15)&~15; + h = (h + 15)&~15; + } + } + + if (!avctx->width || !avctx->height || avctx->width > w || avctx->height > h) { + avctx->width = w; + avctx->height = h; + } + + ret = avctx->reget_buffer(avctx, &s->ret_frame); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "reget buffer() failed\n"); + goto end; + } + + src_linesize[0] = w; + if (avctx->pix_fmt == PIX_FMT_YUV420P) + src_linesize[1] = src_linesize[2] = w/2; + else if (avctx->pix_fmt == PIX_FMT_NV21) + src_linesize[1] = w; + + buf = (uint8_t*)mbuffer->data(); + src_data[0] = buf; + src_data[1] = buf + src_linesize[0] * h; + src_data[2] = src_data[1] + src_linesize[1] * h/2; + av_image_copy(s->ret_frame.data, s->ret_frame.linesize, + src_data, src_linesize, + avctx->pix_fmt, avctx->width, avctx->height); + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = s->ret_frame; + ret = orig_size; +end: + mbuffer->release(); + return ret; +} + +static av_cold int Stagefright_close(AVCodecContext *avctx) +{ + StagefrightContext *s = (StagefrightContext*)avctx->priv_data; + Frame *frame; + + if (s->thread_started) { + if (!s->thread_exited) { + s->stop_decode = 1; + + // Make sure decode_thread() doesn't get stuck + pthread_mutex_lock(&s->out_mutex); + while (!s->out_queue->empty()) { + frame = *s->out_queue->begin(); + s->out_queue->erase(s->out_queue->begin()); + if (frame->size) + frame->mbuffer->release(); + av_freep(&frame); + } + pthread_mutex_unlock(&s->out_mutex); + + // Feed a dummy frame prior to signalling EOF. + // This is required to terminate the decoder(OMX.SEC) + // when only one frame is read during stream info detection. + if (s->dummy_buf && (frame = (Frame*)av_mallocz(sizeof(Frame)))) { + frame->status = OK; + frame->size = s->dummy_bufsize; + frame->key = 1; + frame->buffer = s->dummy_buf; + pthread_mutex_lock(&s->in_mutex); + s->in_queue->push_back(frame); + pthread_cond_signal(&s->condition); + pthread_mutex_unlock(&s->in_mutex); + s->dummy_buf = NULL; + } + + pthread_mutex_lock(&s->in_mutex); + s->end_frame->status = ERROR_END_OF_STREAM; + s->in_queue->push_back(s->end_frame); + pthread_cond_signal(&s->condition); + pthread_mutex_unlock(&s->in_mutex); + s->end_frame = NULL; + } + + pthread_join(s->decode_thread_id, NULL); + + if (s->ret_frame.data[0]) + avctx->release_buffer(avctx, &s->ret_frame); + + s->thread_started = false; + } + + while (!s->in_queue->empty()) { + frame = *s->in_queue->begin(); + s->in_queue->erase(s->in_queue->begin()); + if (frame->size) + av_freep(&frame->buffer); + av_freep(&frame); + } + + while (!s->out_queue->empty()) { + frame = *s->out_queue->begin(); + s->out_queue->erase(s->out_queue->begin()); + if (frame->size) + frame->mbuffer->release(); + av_freep(&frame); + } + + (*s->decoder)->stop(); + s->client->disconnect(); + + if (s->decoder_component) + av_freep(&s->decoder_component); + av_freep(&s->dummy_buf); + av_freep(&s->end_frame); + + // Reset the extradata back to the original mp4 format, so that + // the next invocation (both when decoding and when called from + // av_find_stream_info) get the original mp4 format extradata. + av_freep(&avctx->extradata); + avctx->extradata = s->orig_extradata; + avctx->extradata_size = s->orig_extradata_size; + + delete s->in_queue; + delete s->out_queue; + delete s->client; + delete s->decoder; + delete s->source; + + pthread_mutex_destroy(&s->in_mutex); + pthread_mutex_destroy(&s->out_mutex); + pthread_cond_destroy(&s->condition); + av_bitstream_filter_close(s->bsfc); + return 0; +} + +AVCodec ff_libstagefright_h264_decoder = { + "libstagefright_h264", + NULL_IF_CONFIG_SMALL("libstagefright H.264"), + AVMEDIA_TYPE_VIDEO, + CODEC_ID_H264, + CODEC_CAP_DELAY, + NULL, //supported_framerates + NULL, //pix_fmts + NULL, //supported_samplerates + NULL, //sample_fmts + NULL, //channel_layouts + 0, //max_lowres + NULL, //priv_class + NULL, //profiles + sizeof(StagefrightContext), + NULL, //next + NULL, //init_thread_copy + NULL, //update_thread_context + NULL, //defaults + NULL, //init_static_data + Stagefright_init, + NULL, //encode + NULL, //encode2 + Stagefright_decode_frame, + Stagefright_close, +}; diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c index ecceceaa12..f9078bafa5 100644 --- a/libavcodec/libtheoraenc.c +++ b/libavcodec/libtheoraenc.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2006 Paul Richards <paul.richards@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -30,7 +30,7 @@ * and o_ prefixes on variables which are libogg types. */ -/* Libav includes */ +/* FFmpeg includes */ #include "libavutil/intreadwrite.h" #include "libavutil/log.h" #include "libavutil/base64.h" diff --git a/libavcodec/libutvideo.cpp b/libavcodec/libutvideo.cpp new file mode 100644 index 0000000000..1089d3e879 --- /dev/null +++ b/libavcodec/libutvideo.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2011 Derek Buitenhuis + * + * 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; + * version 2 of the License. + * + * 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 + */ + +/** + * @file + * Known FOURCCs: + * 'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA) + */ + +extern "C" { +#include "avcodec.h" +} + +#include <stdlib.h> +#include <utvideo/utvideo.h> +#include <utvideo/Codec.h> + +#include "get_bits.h" + +typedef struct { + uint32_t version; + uint32_t original_format; + uint32_t frameinfo_size; + uint32_t flags; +} UtVideoExtra; + +typedef struct { + CCodec *codec; + unsigned int buf_size; + uint8_t *output; +} UtVideoContext; + +static av_cold int utvideo_decode_init(AVCodecContext *avctx) +{ + UtVideoContext *utv = (UtVideoContext *)avctx->priv_data; + UtVideoExtra info; + int format; + int begin_ret; + + if (avctx->extradata_size != 4*4) { + av_log(avctx, AV_LOG_ERROR, "Extradata size mismatch.\n"); + return -1; + } + + /* Read extradata */ + info.version = AV_RL32(avctx->extradata); + info.original_format = AV_RL32(avctx->extradata + 4); + info.frameinfo_size = AV_RL32(avctx->extradata + 8); + info.flags = AV_RL32(avctx->extradata + 12); + + /* Pick format based on FOURCC */ + switch (avctx->codec_tag) { + case MKTAG('U', 'L', 'Y', '0'): + avctx->pix_fmt = PIX_FMT_YUV420P; + format = UTVF_YV12; + break; + case MKTAG('U', 'L', 'Y', '2'): + avctx->pix_fmt = PIX_FMT_YUYV422; + format = UTVF_YUY2; + break; + case MKTAG('U', 'L', 'R', 'G'): + avctx->pix_fmt = PIX_FMT_BGR24; + format = UTVF_RGB24_WIN; + break; + case MKTAG('U', 'L', 'R', 'A'): + avctx->pix_fmt = PIX_FMT_RGB32; + format = UTVF_RGB32_WIN; + break; + default: + av_log(avctx, AV_LOG_ERROR, + "Not a Ut Video FOURCC: %X\n", avctx->codec_tag); + return -1; + } + + /* Only allocate the buffer once */ + utv->buf_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); + utv->output = (uint8_t *)av_malloc(utv->buf_size * sizeof(uint8_t)); + + if (utv->output == NULL) { + av_log(avctx, AV_LOG_ERROR, "Unable to allocate output buffer.\n"); + return -1; + } + + /* Allocate the output frame */ + avctx->coded_frame = avcodec_alloc_frame(); + + /* Ut Video only supports 8-bit */ + avctx->bits_per_raw_sample = 8; + + /* Is it interlaced? */ + avctx->coded_frame->interlaced_frame = info.flags & 0x800 ? 1 : 0; + + /* Apparently Ut Video doesn't store this info... */ + avctx->coded_frame->top_field_first = 1; + + /* + * Create a Ut Video instance. Since the function wants + * an "interface name" string, pass it the name of the lib. + */ + utv->codec = CCodec::CreateInstance(UNFCC(avctx->codec_tag), "libavcodec"); + + /* Initialize Decoding */ + begin_ret = utv->codec->DecodeBegin(format, avctx->width, avctx->height, + CBGROSSWIDTH_WINDOWS, &info, sizeof(UtVideoExtra)); + + /* Check to see if the decoder initlized properly */ + if (begin_ret != 0) { + av_log(avctx, AV_LOG_ERROR, + "Could not initialize decoder: %d\n", begin_ret); + return -1; + } + + return 0; +} + +static int utvideo_decode_frame(AVCodecContext *avctx, void *data, + int *data_size, AVPacket *avpkt) +{ + UtVideoContext *utv = (UtVideoContext *)avctx->priv_data; + AVFrame *pic = avctx->coded_frame; + int w = avctx->width, h = avctx->height; + + /* Set flags */ + pic->reference = 0; + pic->pict_type = AV_PICTURE_TYPE_I; + pic->key_frame = 1; + + /* Decode the frame */ + utv->codec->DecodeFrame(utv->output, avpkt->data, true); + + /* Set the output data depending on the colorspace */ + switch (avctx->pix_fmt) { + case PIX_FMT_YUV420P: + pic->linesize[0] = w; + pic->linesize[1] = pic->linesize[2] = w / 2; + pic->data[0] = utv->output; + pic->data[2] = utv->output + (w * h); + pic->data[1] = pic->data[2] + (w * h / 4); + break; + case PIX_FMT_YUYV422: + pic->linesize[0] = w * 2; + pic->data[0] = utv->output; + break; + case PIX_FMT_BGR24: + case PIX_FMT_RGB32: + /* Make the linesize negative, since Ut Video uses bottom-up BGR */ + pic->linesize[0] = -1 * w * (avctx->pix_fmt == PIX_FMT_BGR24 ? 3 : 4); + pic->data[0] = utv->output + utv->buf_size + pic->linesize[0]; + break; + } + + *data_size = sizeof(AVFrame); + *(AVFrame *)data = *pic; + + return avpkt->size; +} + +static av_cold int utvideo_decode_close(AVCodecContext *avctx) +{ + UtVideoContext *utv = (UtVideoContext *)avctx->priv_data; + + /* Free output */ + av_freep(&avctx->coded_frame); + av_freep(&utv->output); + + /* Finish decoding and clean up the instance */ + utv->codec->DecodeEnd(); + CCodec::DeleteInstance(utv->codec); + + return 0; +} + +AVCodec ff_libutvideo_decoder = { + "libutvideo", + NULL_IF_CONFIG_SMALL("Ut Video"), + AVMEDIA_TYPE_VIDEO, + CODEC_ID_UTVIDEO, + 0, //capabilities + NULL, //supported_framerates + NULL, //pix_fmts + NULL, //supported_samplerates + NULL, //sample_fmts + NULL, //channel_layouts + 0, //max_lowres + NULL, //priv_class + NULL, //profiles + sizeof(UtVideoContext), + NULL, //next + NULL, //init_thread_copy + NULL, //update_thread_context + NULL, //defaults + NULL, //init_static_data + utvideo_decode_init, + NULL, //encode + NULL, //encode2 + utvideo_decode_frame, + utvideo_decode_close, +}; diff --git a/libavcodec/libvo-aacenc.c b/libavcodec/libvo-aacenc.c index 280ba27ef9..25e8a317f7 100644 --- a/libavcodec/libvo-aacenc.c +++ b/libavcodec/libvo-aacenc.c @@ -2,20 +2,20 @@ * AAC encoder wrapper * Copyright (c) 2010 Martin Storsjo * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libvo-amrwbenc.c b/libavcodec/libvo-amrwbenc.c index 5214ee6d2e..22c71b75f1 100644 --- a/libavcodec/libvo-amrwbenc.c +++ b/libavcodec/libvo-amrwbenc.c @@ -2,20 +2,20 @@ * AMR Audio encoder stub * Copyright (c) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libvorbis.c b/libavcodec/libvorbis.c index 25e600671f..5c35b35bc4 100644 --- a/libavcodec/libvorbis.c +++ b/libavcodec/libvorbis.c @@ -1,20 +1,20 @@ /* * copyright (c) 2002 Mark Hills <mark@pogo.org.uk> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -61,44 +61,94 @@ static const AVOption options[] = { }; static const AVClass class = { "libvorbis", av_default_item_name, options, LIBAVUTIL_VERSION_INT }; +static const char * error(int oggerr, int *averr) +{ + switch (oggerr) { + case OV_EFAULT: *averr = AVERROR(EFAULT); return "internal error"; + case OV_EIMPL: *averr = AVERROR(EINVAL); return "not supported"; + case OV_EINVAL: *averr = AVERROR(EINVAL); return "invalid request"; + default: *averr = AVERROR(EINVAL); return "unknown error"; + } +} + static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext) { OggVorbisContext *context = avccontext->priv_data; double cfreq; + int r; if (avccontext->flags & CODEC_FLAG_QSCALE) { /* variable bitrate */ - if (vorbis_encode_setup_vbr(vi, avccontext->channels, + float quality = avccontext->global_quality / (float)FF_QP2LAMBDA; + r = vorbis_encode_setup_vbr(vi, avccontext->channels, avccontext->sample_rate, - avccontext->global_quality / (float)FF_QP2LAMBDA / 10.0)) - return -1; + quality / 10.0); + if (r) { + av_log(avccontext, AV_LOG_ERROR, + "Unable to set quality to %g: %s\n", quality, error(r, &r)); + return r; + } } else { int minrate = avccontext->rc_min_rate > 0 ? avccontext->rc_min_rate : -1; int maxrate = avccontext->rc_min_rate > 0 ? avccontext->rc_max_rate : -1; /* constant bitrate */ - if (vorbis_encode_setup_managed(vi, avccontext->channels, + r = vorbis_encode_setup_managed(vi, avccontext->channels, avccontext->sample_rate, minrate, - avccontext->bit_rate, maxrate)) - return -1; + avccontext->bit_rate, maxrate); + if (r) { + av_log(avccontext, AV_LOG_ERROR, + "Unable to set CBR to %d: %s\n", avccontext->bit_rate, + error(r, &r)); + return r; + } /* variable bitrate by estimate, disable slow rate management */ if (minrate == -1 && maxrate == -1) if (vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL)) - return -1; + return AVERROR(EINVAL); /* should not happen */ } /* cutoff frequency */ if (avccontext->cutoff > 0) { cfreq = avccontext->cutoff / 1000.0; if (vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq)) - return -1; + return AVERROR(EINVAL); /* should not happen */ } if (context->iblock) { vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &context->iblock); } + if (avccontext->channels == 3 && + avccontext->channel_layout != (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) || + avccontext->channels == 4 && + avccontext->channel_layout != AV_CH_LAYOUT_2_2 && + avccontext->channel_layout != AV_CH_LAYOUT_QUAD || + avccontext->channels == 5 && + avccontext->channel_layout != AV_CH_LAYOUT_5POINT0 && + avccontext->channel_layout != AV_CH_LAYOUT_5POINT0_BACK || + avccontext->channels == 6 && + avccontext->channel_layout != AV_CH_LAYOUT_5POINT1 && + avccontext->channel_layout != AV_CH_LAYOUT_5POINT1_BACK || + avccontext->channels == 7 && + avccontext->channel_layout != (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER) || + avccontext->channels == 8 && + avccontext->channel_layout != AV_CH_LAYOUT_7POINT1) { + if (avccontext->channel_layout) { + char name[32]; + av_get_channel_layout_string(name, sizeof(name), avccontext->channels, + avccontext->channel_layout); + av_log(avccontext, AV_LOG_ERROR, "%s not supported by Vorbis: " + "output stream will have incorrect " + "channel layout.\n", name); + } else { + av_log(avccontext, AV_LOG_WARNING, "No channel layout specified. The encoder " + "will use Vorbis channel layout for " + "%d channels.\n", avccontext->channels); + } + } + return vorbis_encode_setup_init(vi); } @@ -114,11 +164,13 @@ static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext) ogg_packet header, header_comm, header_code; uint8_t *p; unsigned int offset; + int r; vorbis_info_init(&context->vi); - if (oggvorbis_init_encoder(&context->vi, avccontext) < 0) { - av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed\n"); - return -1; + r = oggvorbis_init_encoder(&context->vi, avccontext); + if (r < 0) { + av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init failed\n"); + return r; } vorbis_analysis_init(&context->vd, &context->vi); vorbis_block_init(&context->vd, &context->vb); @@ -199,8 +251,8 @@ static int oggvorbis_encode_frame(AVCodecContext *avccontext, if (op.bytes == 1 && op.e_o_s) continue; if (context->buffer_index + sizeof(ogg_packet) + op.bytes > BUFFER_SIZE) { - av_log(avccontext, AV_LOG_ERROR, "libvorbis: buffer overflow."); - return -1; + av_log(avccontext, AV_LOG_ERROR, "libvorbis: buffer overflow.\n"); + return AVERROR(EINVAL); } memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet)); context->buffer_index += sizeof(ogg_packet); @@ -220,8 +272,8 @@ static int oggvorbis_encode_frame(AVCodecContext *avccontext, //FIXME we should reorder the user supplied pts and not assume that they are spaced by 1/sample_rate if (l > buf_size) { - av_log(avccontext, AV_LOG_ERROR, "libvorbis: buffer overflow."); - return -1; + av_log(avccontext, AV_LOG_ERROR, "libvorbis: buffer overflow.\n"); + return AVERROR(EINVAL); } memcpy(packets, op2->packet, l); diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c index 917a50219c..84e5ac8e65 100644 --- a/libavcodec/libvpxdec.c +++ b/libavcodec/libvpxdec.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2010, Google, Inc. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 64ff2c1eaa..f6d03a9d43 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2010, Google, Inc. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -54,15 +54,26 @@ typedef struct VP8EncoderContext { struct vpx_codec_ctx encoder; struct vpx_image rawimg; struct vpx_fixed_buf twopass_stats; - unsigned long deadline; //i.e., RT/GOOD/BEST + int deadline; //i.e., RT/GOOD/BEST struct FrameListData *coded_frame_list; + int cpu_used; + /** + * VP8 specific flags, see VP8F_* below. + */ + int flags; +#define VP8F_ERROR_RESILIENT 0x00000001 ///< Enable measures appropriate for streaming over lossy links +#define VP8F_AUTO_ALT_REF 0x00000002 ///< Enable automatic alternate reference frame generation + int auto_alt_ref; + int arnr_max_frames; int arnr_strength; int arnr_type; + int lag_in_frames; int error_resilient; + int crf; } VP8Context; /** String mappings for enum vp8e_enc_control_id */ @@ -83,6 +94,7 @@ static const char *ctlidstr[] = { [VP8E_SET_ARNR_MAXFRAMES] = "VP8E_SET_ARNR_MAXFRAMES", [VP8E_SET_ARNR_STRENGTH] = "VP8E_SET_ARNR_STRENGTH", [VP8E_SET_ARNR_TYPE] = "VP8E_SET_ARNR_TYPE", + [VP8E_SET_CQ_LEVEL] = "VP8E_SET_CQ_LEVEL", }; static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc) @@ -233,9 +245,7 @@ static av_cold int vp8_init(AVCodecContext *avctx) enccfg.g_timebase.num = avctx->time_base.num; enccfg.g_timebase.den = avctx->time_base.den; enccfg.g_threads = avctx->thread_count; - - if (ctx->lag_in_frames >= 0) - enccfg.g_lag_in_frames = ctx->lag_in_frames; + enccfg.g_lag_in_frames= ctx->lag_in_frames; if (avctx->flags & CODEC_FLAG_PASS1) enccfg.g_pass = VPX_RC_FIRST_PASS; @@ -247,6 +257,8 @@ static av_cold int vp8_init(AVCodecContext *avctx) if (avctx->rc_min_rate == avctx->rc_max_rate && avctx->rc_min_rate == avctx->bit_rate) enccfg.rc_end_usage = VPX_CBR; + else if (ctx->crf) + enccfg.rc_end_usage = VPX_CQ; enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000, AV_ROUND_NEAR_INF); if (avctx->qmin > 0) @@ -270,6 +282,7 @@ static av_cold int vp8_init(AVCodecContext *avctx) enccfg.rc_buf_initial_sz = avctx->rc_initial_buffer_occupancy * 1000LL / avctx->bit_rate; enccfg.rc_buf_optimal_sz = enccfg.rc_buf_sz * 5 / 6; + enccfg.rc_undershoot_pct = round(avctx->rc_buffer_aggressivity * 100); //_enc_init() will balk if kf_min_dist differs from max w/VPX_KF_AUTO if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size) @@ -312,7 +325,7 @@ static av_cold int vp8_init(AVCodecContext *avctx) if (avctx->profile != FF_PROFILE_UNKNOWN) enccfg.g_profile = avctx->profile; - enccfg.g_error_resilient = ctx->error_resilient; + enccfg.g_error_resilient = ctx->error_resilient || ctx->flags & VP8F_ERROR_RESILIENT; dump_enc_cfg(avctx, &enccfg); /* Construct Encoder Context */ @@ -326,6 +339,8 @@ static av_cold int vp8_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n"); if (ctx->cpu_used != INT_MIN) codecctl_int(avctx, VP8E_SET_CPUUSED, ctx->cpu_used); + if (ctx->flags & VP8F_AUTO_ALT_REF) + ctx->auto_alt_ref = 1; if (ctx->auto_alt_ref >= 0) codecctl_int(avctx, VP8E_SET_ENABLEAUTOALTREF, ctx->auto_alt_ref); if (ctx->arnr_max_frames >= 0) @@ -337,6 +352,9 @@ static av_cold int vp8_init(AVCodecContext *avctx) codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction); codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS, av_log2(avctx->slices)); codecctl_int(avctx, VP8E_SET_STATIC_THRESHOLD, avctx->mb_threshold); + codecctl_int(avctx, VP8E_SET_CQ_LEVEL, ctx->crf); + + av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline); //provide dummy value to initialize wrapper, values will be updated each _encode() vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1, @@ -456,8 +474,8 @@ static int queue_frames(AVCodecContext *avctx, uint8_t *buf, int buf_size, break; case VPX_CODEC_STATS_PKT: { struct vpx_fixed_buf *stats = &ctx->twopass_stats; - stats->buf = av_realloc(stats->buf, - stats->sz + pkt->data.twopass_stats.sz); + stats->buf = av_realloc_f(stats->buf, 1, + stats->sz + pkt->data.twopass_stats.sz); if (!stats->buf) { av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n"); return AVERROR(ENOMEM); @@ -546,7 +564,17 @@ static const AVOption options[] = { "though earlier partitions have been lost. Note that intra predicition" " is still done over the partition boundary.", 0, AV_OPT_TYPE_CONST, {VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"}, #endif - { NULL } +{"speed", "", offsetof(VP8Context, cpu_used), AV_OPT_TYPE_INT, {.dbl = 3}, -16, 16, VE}, +{"quality", "", offsetof(VP8Context, deadline), AV_OPT_TYPE_INT, {.dbl = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"}, +{"vp8flags", "", offsetof(VP8Context, flags), FF_OPT_TYPE_FLAGS, {.dbl = 0}, 0, UINT_MAX, VE, "flags"}, +{"error_resilient", "enable error resilience", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_ERROR_RESILIENT}, INT_MIN, INT_MAX, VE, "flags"}, +{"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_AUTO_ALT_REF}, INT_MIN, INT_MAX, VE, "flags"}, +{"arnr_max_frames", "altref noise reduction max frame count", offsetof(VP8Context, arnr_max_frames), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 15, VE}, +{"arnr_strength", "altref noise reduction filter strength", offsetof(VP8Context, arnr_strength), AV_OPT_TYPE_INT, {.dbl = 3}, 0, 6, VE}, +{"arnr_type", "altref noise reduction filter type", offsetof(VP8Context, arnr_type), AV_OPT_TYPE_INT, {.dbl = 3}, 1, 3, VE}, +{"rc_lookahead", "Number of frames to look ahead for alternate reference frame selection", offsetof(VP8Context, lag_in_frames), AV_OPT_TYPE_INT, {.dbl = 25}, 0, 25, VE}, +{"crf", "Select the quality for constant quality mode", offsetof(VP8Context, crf), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 63, VE}, +{NULL} }; static const AVClass class = { diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 3934627537..6279612c82 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -2,20 +2,20 @@ * H.264 encoding using the x264 library * Copyright (C) 2005 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +41,11 @@ typedef struct X264Context { char *preset; char *tune; char *profile; + char *level; int fastfirstpass; + char *stats; + char *wpredp; + char *x264opts; float crf; float crf_max; int cqp; @@ -104,9 +108,14 @@ static int encode_nals(AVCodecContext *ctx, AVPacket *pkt, /* Write the SEI as part of the first frame. */ if (x4->sei_size > 0 && nnal > 0) { + if (x4->sei_size > size) { + av_log(ctx, AV_LOG_ERROR, "Error: nal buffer is too small\n"); + return -1; + } memcpy(p, x4->sei, x4->sei_size); p += x4->sei_size; x4->sei_size = 0; + av_freep(&x4->sei); } for (i = 0; i < nnal; i++){ @@ -117,6 +126,25 @@ static int encode_nals(AVCodecContext *ctx, AVPacket *pkt, return 1; } +static int avfmt2_num_planes(int avfmt) +{ + switch (avfmt) { + case PIX_FMT_YUV420P: + case PIX_FMT_YUVJ420P: + case PIX_FMT_YUV420P9: + case PIX_FMT_YUV420P10: + case PIX_FMT_YUV444P: + return 3; + + case PIX_FMT_BGR24: + case PIX_FMT_RGB24: + return 1; + + default: + return 3; + } +} + static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { @@ -129,10 +157,10 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, x4->pic.img.i_csp = x4->params.i_csp; if (x264_bit_depth > 8) x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH; - x4->pic.img.i_plane = 3; + x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt); if (frame) { - for (i = 0; i < 3; i++) { + for (i = 0; i < x4->pic.img.i_plane; i++) { x4->pic.img.plane[i] = frame->data[i]; x4->pic.img.i_stride[i] = frame->linesize[i]; } @@ -147,6 +175,12 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, x4->params.b_tff = frame->top_field_first; x264_encoder_reconfig(x4->enc, &x4->params); } + if (x4->params.vui.i_sar_height != ctx->sample_aspect_ratio.den + || x4->params.vui.i_sar_width != ctx->sample_aspect_ratio.num) { + x4->params.vui.i_sar_height = ctx->sample_aspect_ratio.den; + x4->params.vui.i_sar_width = ctx->sample_aspect_ratio.num; + x264_encoder_reconfig(x4->enc, &x4->params); + } } do { @@ -196,6 +230,20 @@ static av_cold int X264_close(AVCodecContext *avctx) return 0; } +#define OPT_STR(opt, param) \ + do { \ + int ret; \ + if (param && (ret = x264_param_parse(&x4->params, opt, param)) < 0) { \ + if(ret == X264_PARAM_BAD_NAME) \ + av_log(avctx, AV_LOG_ERROR, \ + "bad option '%s': '%s'\n", opt, param); \ + else \ + av_log(avctx, AV_LOG_ERROR, \ + "bad value for '%s': '%s'\n", opt, param); \ + return -1; \ + } \ + } while (0) + static int convert_pix_fmt(enum PixelFormat pix_fmt) { switch (pix_fmt) { @@ -208,6 +256,13 @@ static int convert_pix_fmt(enum PixelFormat pix_fmt) case PIX_FMT_YUV444P: case PIX_FMT_YUV444P9: case PIX_FMT_YUV444P10: return X264_CSP_I444; +#ifdef X264_CSP_BGR + case PIX_FMT_BGR24: + return X264_CSP_BGR; + + case PIX_FMT_RGB24: + return X264_CSP_RGB; +#endif }; return 0; } @@ -221,11 +276,15 @@ static int convert_pix_fmt(enum PixelFormat pix_fmt) static av_cold int X264_init(AVCodecContext *avctx) { X264Context *x4 = avctx->priv_data; + int sw,sh; x264_param_default(&x4->params); x4->params.b_deblocking_filter = avctx->flags & CODEC_FLAG_LOOP_FILTER; + x4->params.rc.f_ip_factor = 1 / fabs(avctx->i_quant_factor); + x4->params.rc.f_pb_factor = avctx->b_quant_factor; + x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset; if (x4->preset || x4->tune) if (x264_param_default_preset(&x4->params, x4->preset, x4->tune) < 0) { av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", x4->preset, x4->tune); @@ -240,6 +299,8 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.i_log_level = X264_LOG_DEBUG; x4->params.i_csp = convert_pix_fmt(avctx->pix_fmt); + OPT_STR("weightp", x4->wpredp); + if (avctx->bit_rate) { x4->params.rc.i_bitrate = avctx->bit_rate / 1000; x4->params.rc.i_rc_method = X264_RC_ABR; @@ -262,15 +323,28 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.rc.f_rf_constant_max = x4->crf_max; } + OPT_STR("stats", x4->stats); + if (avctx->rc_buffer_size && avctx->rc_initial_buffer_occupancy && (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)) { x4->params.rc.f_vbv_buffer_init = (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size; } - x4->params.rc.f_ip_factor = 1 / fabs(avctx->i_quant_factor); - x4->params.rc.f_pb_factor = avctx->b_quant_factor; - x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset; + OPT_STR("level", x4->level); + + if(x4->x264opts){ + const char *p= x4->x264opts; + while(p){ + char param[256]={0}, val[256]={0}; + if(sscanf(p, "%255[^:=]=%255[^:]", param, val) == 1){ + OPT_STR(param, "1"); + }else + OPT_STR(param, val); + p= strchr(p, ':'); + p+=!!p; + } + } if (avctx->me_method == ME_EPZS) x4->params.analyse.i_me_method = X264_ME_DIA; @@ -371,8 +445,9 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.i_width = avctx->width; x4->params.i_height = avctx->height; - x4->params.vui.i_sar_width = avctx->sample_aspect_ratio.num; - x4->params.vui.i_sar_height = avctx->sample_aspect_ratio.den; + av_reduce(&sw, &sh, avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 4096); + x4->params.vui.i_sar_width = sw; + x4->params.vui.i_sar_height = sh; x4->params.i_fps_num = x4->params.i_timebase_den = avctx->time_base.den; x4->params.i_fps_den = x4->params.i_timebase_num = avctx->time_base.num; @@ -382,7 +457,7 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.b_interlaced = avctx->flags & CODEC_FLAG_INTERLACED_DCT; - x4->params.b_open_gop = !(avctx->flags & CODEC_FLAG_CLOSED_GOP); +// x4->params.b_open_gop = !(avctx->flags & CODEC_FLAG_CLOSED_GOP); x4->params.i_slice_count = avctx->slices; @@ -449,6 +524,13 @@ static const enum PixelFormat pix_fmts_10bit[] = { PIX_FMT_YUV444P10, PIX_FMT_NONE }; +static const enum PixelFormat pix_fmts_8bit_rgb[] = { +#ifdef X264_CSP_BGR + PIX_FMT_BGR24, + PIX_FMT_RGB24, +#endif + PIX_FMT_NONE +}; static av_cold void X264_init_static(AVCodec *codec) { @@ -467,6 +549,10 @@ static const AVOption options[] = { { "tune", "Tune the encoding params (cf. x264 --fullhelp)", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE}, { "profile", "Set profile restrictions (cf. x264 --fullhelp) ", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE}, { "fastfirstpass", "Use fast settings when encoding first pass", OFFSET(fastfirstpass), AV_OPT_TYPE_INT, { 1 }, 0, 1, VE}, + {"level", "Specify level (as defined by Annex A)", OFFSET(level), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, + {"passlogfile", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, + {"wpredp", "Weighted prediction for P-frames", OFFSET(wpredp), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, + {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {-1 }, -1, FLT_MAX, VE }, { "crf_max", "In CRF mode, prevents VBV from lowering quality beyond this point.",OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {-1 }, -1, FLT_MAX, VE }, { "qp", "Constant quantization parameter rate control method",OFFSET(cqp), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE }, @@ -515,15 +601,24 @@ static const AVClass class = { .version = LIBAVUTIL_VERSION_INT, }; +static const AVClass rgbclass = { + .class_name = "libx264rgb", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + static const AVCodecDefault x264_defaults[] = { { "b", "0" }, { "bf", "-1" }, + { "flags2", "0" }, { "g", "-1" }, { "qmin", "-1" }, { "qmax", "-1" }, { "qdiff", "-1" }, { "qblur", "-1" }, { "qcomp", "-1" }, +// { "rc_lookahead", "-1" }, { "refs", "-1" }, { "sc_threshold", "-1" }, { "trellis", "-1" }, @@ -553,3 +648,18 @@ AVCodec ff_libx264_encoder = { .defaults = x264_defaults, .init_static_data = X264_init_static, }; + +AVCodec ff_libx264rgb_encoder = { + .name = "libx264rgb", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_H264, + .priv_data_size = sizeof(X264Context), + .init = X264_init, + .encode = X264_frame, + .close = X264_close, + .capabilities = CODEC_CAP_DELAY, + .long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB"), + .priv_class = &rgbclass, + .defaults = x264_defaults, + .pix_fmts = pix_fmts_8bit_rgb, +}; diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c index 8587eae99b..d7027d1092 100644 --- a/libavcodec/libxavs.c +++ b/libavcodec/libxavs.c @@ -2,20 +2,20 @@ * AVS encoding using the xavs library * Copyright (C) 2010 Amanda, Y.N. Wu <amanda11192003@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libxvid_internal.h b/libavcodec/libxvid_internal.h index a2dc6ef50c..6517f62174 100644 --- a/libavcodec/libxvid_internal.h +++ b/libavcodec/libxvid_internal.h @@ -1,20 +1,20 @@ /* * copyright (C) 2006 Corey Hickey * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c index 2386ce3cc6..08d306e82f 100644 --- a/libavcodec/libxvid_rc.c +++ b/libavcodec/libxvid_rc.c @@ -3,25 +3,26 @@ * * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <xvid.h> #include <unistd.h> +#include "libavutil/file.h" #include "avcodec.h" #include "libxvid_internal.h" //#include "dsputil.h" @@ -40,7 +41,7 @@ int ff_xvid_rate_control_init(MpegEncContext *s){ //xvid_debug=-1; - fd=ff_tempfile("xvidrc.", &tmp_name); + fd=av_tempfile("xvidrc.", &tmp_name, 0, s->avctx); if (fd == -1) { av_log(NULL, AV_LOG_ERROR, "Can't create temporary pass2 file.\n"); return -1; @@ -58,7 +59,10 @@ int ff_xvid_rate_control_init(MpegEncContext *s){ rce->skip_count, (rce->i_tex_bits + rce->p_tex_bits + rce->misc_bits+7)/8, (rce->header_bits+rce->mv_bits+7)/8); //av_log(NULL, AV_LOG_ERROR, "%s\n", tmp); - write(fd, tmp, strlen(tmp)); + if (write(fd, tmp, strlen(tmp)) < 0) { + av_log(NULL, AV_LOG_ERROR, "Error %s writing 2pass logfile\n", strerror(errno)); + return AVERROR(errno); + } } close(fd); diff --git a/libavcodec/libxvidff.c b/libavcodec/libxvidff.c index a11e4ac913..1501b44135 100644 --- a/libavcodec/libxvidff.c +++ b/libavcodec/libxvidff.c @@ -2,20 +2,20 @@ * Interface to xvidcore for mpeg4 encoding * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -28,13 +28,11 @@ #include <xvid.h> #include <unistd.h> #include "avcodec.h" +#include "libavutil/file.h" #include "libavutil/cpu.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" #include "libxvid_internal.h" -#if !HAVE_MKSTEMP -#include <fcntl.h> -#endif /** * Buffer management macros. @@ -77,42 +75,6 @@ int xvid_strip_vol_header(AVCodecContext *avctx, unsigned char *frame, unsigned int xvid_ff_2pass(void *ref, int opt, void *p1, void *p2); void xvid_correct_framerate(AVCodecContext *avctx); -/* Wrapper to work around the lack of mkstemp() on mingw. - * Also, tries to create file in /tmp first, if possible. - * *prefix can be a character constant; *filename will be allocated internally. - * @return file descriptor of opened file (or -1 on error) - * and opened file name in **filename. */ -int ff_tempfile(const char *prefix, char **filename) { - int fd=-1; -#if !HAVE_MKSTEMP - *filename = tempnam(".", prefix); -#else - size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */ - *filename = av_malloc(len); -#endif - /* -----common section-----*/ - if (*filename == NULL) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n"); - return -1; - } -#if !HAVE_MKSTEMP - fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444); -#else - snprintf(*filename, len, "/tmp/%sXXXXXX", prefix); - fd = mkstemp(*filename); - if (fd < 0) { - snprintf(*filename, len, "./%sXXXXXX", prefix); - fd = mkstemp(*filename); - } -#endif - /* -----common section-----*/ - if (fd < 0) { - av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); - return -1; - } - return fd; /* success */ -} - #if CONFIG_LIBXVID_ENCODER /** @@ -137,7 +99,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { xvid_enc_create_t xvid_enc_create; xvid_enc_plugin_t plugins[7]; - /* Bring in VOP flags from avconv command-line */ + /* Bring in VOP flags from ffmpeg command-line */ x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */ if( xvid_flags & CODEC_FLAG_4MV ) x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */ @@ -191,7 +153,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { break; } - /* Bring in VOL flags from avconv command-line */ + /* Bring in VOL flags from ffmpeg command-line */ x->vol_flags = 0; if( xvid_flags & CODEC_FLAG_GMC ) { x->vol_flags |= XVID_VOL_GMC; @@ -270,7 +232,7 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { rc2pass2.version = XVID_VERSION; rc2pass2.bitrate = avctx->bit_rate; - fd = ff_tempfile("xvidff.", &x->twopassfile); + fd = av_tempfile("xvidff.", &x->twopassfile, 0, avctx); if( fd == -1 ) { av_log(avctx, AV_LOG_ERROR, "Xvid: Cannot write 2-pass pipe\n"); @@ -454,8 +416,8 @@ static int xvid_encode_frame(AVCodecContext *avctx, XVID_TYPE_AUTO; /* Pixel aspect ratio setting */ - if (avctx->sample_aspect_ratio.num < 1 || avctx->sample_aspect_ratio.num > 255 || - avctx->sample_aspect_ratio.den < 1 || avctx->sample_aspect_ratio.den > 255) { + if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.num > 255 || + avctx->sample_aspect_ratio.den < 0 || avctx->sample_aspect_ratio.den > 255) { av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i\n", avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); return -1; @@ -529,6 +491,7 @@ static av_cold int xvid_encode_close(AVCodecContext *avctx) { if( x->twopassbuffer != NULL ) { av_free(x->twopassbuffer); av_free(x->old_twopassbuffer); + avctx->stats_out = NULL; } av_free(x->twopassfile); av_free(x->intra_matrix); @@ -669,7 +632,7 @@ static int xvid_ff_2pass_create(xvid_plg_create_t * param, /* This is because we can safely prevent a buffer overflow */ log[0] = 0; snprintf(log, BUFFER_REMAINING(log), - "# avconv 2-pass log file, using xvid codec\n"); + "# ffmpeg 2-pass log file, using xvid codec\n"); snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log), "# Do not modify. libxvidcore version: %d.%d.%d\n\n", XVID_VERSION_MAJOR(XVID_VERSION), diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c index 6a90338eb9..4d81b5fc90 100644 --- a/libavcodec/ljpegenc.c +++ b/libavcodec/ljpegenc.c @@ -8,20 +8,20 @@ * aspecting, new decode_frame mechanism and apple mjpeg-b support * by Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +56,9 @@ static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, in s->header_bits= put_bits_count(&s->pb); - if(avctx->pix_fmt == PIX_FMT_BGRA){ + if(avctx->pix_fmt == PIX_FMT_BGR0 + || avctx->pix_fmt == PIX_FMT_BGRA + || avctx->pix_fmt == PIX_FMT_BGR24){ int x, y, i; const int linesize= p->linesize[0]; uint16_t (*buffer)[4]= (void *) s->rd_scratchpad; @@ -79,9 +81,15 @@ static int encode_picture_lossless(AVCodecContext *avctx, unsigned char *buf, in top[i]= left[i]= topleft[i]= buffer[0][i]; } for(x = 0; x < width; x++) { + if(avctx->pix_fmt == PIX_FMT_BGR24){ + buffer[x][1] = ptr[3*x+0] - ptr[3*x+1] + 0x100; + buffer[x][2] = ptr[3*x+2] - ptr[3*x+1] + 0x100; + buffer[x][0] = (ptr[3*x+0] + 2*ptr[3*x+1] + ptr[3*x+2])>>2; + }else{ 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; diff --git a/libavcodec/loco.c b/libavcodec/loco.c index 919a06b123..75701e970b 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -2,20 +2,20 @@ * LOCO codec * Copyright (c) 2005 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -123,6 +123,9 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh int val; int i, j; + if(buf_size<=0) + return -1; + init_get_bits(&rc.gb, buf, buf_size*8); rc.save = 0; rc.run = 0; @@ -225,7 +228,7 @@ static int decode_frame(AVCodecContext *avctx, *data_size = sizeof(AVFrame); *(AVFrame*)data = l->pic; - return buf_size; + return buf_size < 0 ? -1 : buf_size; } static av_cold int decode_init(AVCodecContext *avctx){ @@ -272,6 +275,8 @@ static av_cold int decode_init(AVCodecContext *avctx){ if(avctx->debug & FF_DEBUG_PICT_INFO) av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode); + avcodec_get_frame_defaults(&l->pic); + return 0; } diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c index 0d6910fd2d..5faddc24a6 100644 --- a/libavcodec/lpc.c +++ b/libavcodec/lpc.c @@ -2,20 +2,20 @@ * LPC utility code * Copyright (c) 2006 Justin Ruggles <justin.ruggles@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/lpc.h b/libavcodec/lpc.h index 1775374a40..c58e37c4bc 100644 --- a/libavcodec/lpc.h +++ b/libavcodec/lpc.h @@ -2,20 +2,20 @@ * LPC utility code * Copyright (c) 2006 Justin Ruggles <justin.ruggles@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/lsp.c b/libavcodec/lsp.c index 2adc9cfa39..7fda12ee62 100644 --- a/libavcodec/lsp.c +++ b/libavcodec/lsp.c @@ -4,20 +4,20 @@ * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet (QCELP decoder) * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -150,7 +150,11 @@ void ff_acelp_lp_decode(int16_t* lp_1st, int16_t* lp_2nd, const int16_t* lsp_2nd /* LSP values for first subframe (3.2.5 of G.729, Equation 24)*/ for(i=0; i<lp_order; i++) +#ifdef G729_BITEXACT + lsp_1st[i] = (lsp_2nd[i] >> 1) + (lsp_prev[i] >> 1); +#else lsp_1st[i] = (lsp_2nd[i] + lsp_prev[i]) >> 1; +#endif ff_acelp_lsp2lpc(lp_1st, lsp_1st, lp_order >> 1); diff --git a/libavcodec/lsp.h b/libavcodec/lsp.h index 4b955678ee..46a2d47beb 100644 --- a/libavcodec/lsp.h +++ b/libavcodec/lsp.h @@ -3,20 +3,20 @@ * * Copyright (c) 2008 Vladimir Voroshilov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/lzw.c b/libavcodec/lzw.c index 873b31445b..185a05d6ab 100644 --- a/libavcodec/lzw.c +++ b/libavcodec/lzw.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/lzw.h b/libavcodec/lzw.h index ab782f5219..115ca4edb4 100644 --- a/libavcodec/lzw.h +++ b/libavcodec/lzw.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/lzwenc.c b/libavcodec/lzwenc.c index cb064e7936..0757d02ab4 100644 --- a/libavcodec/lzwenc.c +++ b/libavcodec/lzwenc.c @@ -2,20 +2,20 @@ * LZW encoder * Copyright (c) 2007 Bartlomiej Wolowiec * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mace.c b/libavcodec/mace.c index e22bc3976a..594ef6c795 100644 --- a/libavcodec/mace.c +++ b/libavcodec/mace.c @@ -2,20 +2,20 @@ * MACE decoder * Copyright (c) 2002 Laszlo Torok <torokl@alpha.dfmk.hu> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mathops.h b/libavcodec/mathops.h index d6eb98ddac..3ef7f8b660 100644 --- a/libavcodec/mathops.h +++ b/libavcodec/mathops.h @@ -3,20 +3,20 @@ * Copyright (c) 2001, 2002 Fabrice Bellard * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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_MATHOPS_H diff --git a/libavcodec/mdct.c b/libavcodec/mdct.c index 6f64534273..22320240de 100644 --- a/libavcodec/mdct.c +++ b/libavcodec/mdct.c @@ -2,20 +2,20 @@ * MDCT/IMDCT transforms * Copyright (c) 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mdct_fixed.c b/libavcodec/mdct_fixed.c index 94527f9e85..794a3e0bc2 100644 --- a/libavcodec/mdct_fixed.c +++ b/libavcodec/mdct_fixed.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mdct_float.c b/libavcodec/mdct_float.c index e4f5549cb7..ec4f486f19 100644 --- a/libavcodec/mdct_float.c +++ b/libavcodec/mdct_float.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mdec.c b/libavcodec/mdec.c index a4e2020317..2828417bcd 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -4,20 +4,20 @@ * * based upon code from Sebastian Jedruszkiewicz <elf@frogger.rules.pl> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -219,6 +219,7 @@ static av_cold void mdec_common_init(AVCodecContext *avctx){ a->mb_width = (avctx->coded_width + 15) / 16; a->mb_height = (avctx->coded_height + 15) / 16; + avcodec_get_frame_defaults(&a->picture); avctx->coded_frame= &a->picture; a->avctx= avctx; } @@ -244,14 +245,15 @@ static av_cold int decode_init_thread_copy(AVCodecContext *avctx){ MDECContext * const a = avctx->priv_data; AVFrame *p = (AVFrame*)&a->picture; - avctx->coded_frame = p; + avctx->coded_frame= p; a->avctx= avctx; - p->qscale_table = av_mallocz( a->mb_width); + p->qscale_table= av_mallocz(a->mb_width); return 0; } + static av_cold int decode_end(AVCodecContext *avctx){ MDECContext * const a = avctx->priv_data; diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index b93f51fa3e..652dd1bb5d 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -2,20 +2,20 @@ * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr@gmail.com> * Copyright (C) 2008 Ramiro Polla * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -210,7 +210,7 @@ static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale) value = get_bits(&ctx->gb, num_bits); - /* Libav's IDCT behaves somewhat different from the original code, so + /* FFmpeg's IDCT behaves somewhat different from the original code, so * a factor of 4 was added to the input */ coeff = vlcdec_lookup[num_bits][value]; @@ -352,7 +352,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, return -1; } - ctx->buf_ptrs[ctx->cur_index].reference = 1; + ctx->buf_ptrs[ctx->cur_index].reference = 3; ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P:AV_PICTURE_TYPE_I; if(ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -367,8 +367,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, ff_thread_finish_setup(avctx); - av_fast_malloc(&ctx->swap_buf, &ctx->swap_buf_size, - swap_buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size); if(!ctx->swap_buf) return AVERROR(ENOMEM); diff --git a/libavcodec/mips/mathops.h b/libavcodec/mips/mathops.h index 573745b291..b58361f74d 100644 --- a/libavcodec/mips/mathops.h +++ b/libavcodec/mips/mathops.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mjpeg.c b/libavcodec/mjpeg.c index 9f2d50fa05..6eba27da0b 100644 --- a/libavcodec/mjpeg.c +++ b/libavcodec/mjpeg.c @@ -8,20 +8,20 @@ * aspecting, new decode_frame mechanism and apple mjpeg-b support * by Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mjpeg.h b/libavcodec/mjpeg.h index c3fde4432c..ba1173380c 100644 --- a/libavcodec/mjpeg.h +++ b/libavcodec/mjpeg.h @@ -8,20 +8,20 @@ * aspecting, new decode_frame mechanism and apple mjpeg-b support * by Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -127,6 +127,7 @@ static inline void put_marker(PutBitContext *p, int code) #define PREDICT(ret, topleft, top, left, predictor)\ switch(predictor){\ + case 0: ret= 0; break;\ case 1: ret= left; break;\ case 2: ret= top; break;\ case 3: ret= topleft; break;\ diff --git a/libavcodec/mjpeg2jpeg_bsf.c b/libavcodec/mjpeg2jpeg_bsf.c index a91152d733..c0f2db973b 100644 --- a/libavcodec/mjpeg2jpeg_bsf.c +++ b/libavcodec/mjpeg2jpeg_bsf.c @@ -2,20 +2,20 @@ * MJPEG/AVI1 to JPEG/JFIF bitstream format filter * Copyright (c) 2010 Adrian Daerr and Nicolas George * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mjpeg_parser.c b/libavcodec/mjpeg_parser.c index 5b83e59dcd..40841c3b37 100644 --- a/libavcodec/mjpeg_parser.c +++ b/libavcodec/mjpeg_parser.c @@ -4,20 +4,20 @@ * Copyright (c) 2003 Alex Beregszaszi * Copyright (c) 2003-2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -28,27 +28,44 @@ #include "parser.h" +typedef struct MJPEGParserContext{ + ParseContext pc; + int size; +}MJPEGParserContext; /** * Find 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){ +static int find_frame_end(MJPEGParserContext *m, const uint8_t *buf, int buf_size){ + ParseContext *pc= &m->pc; int vop_found, i; - uint16_t state; + uint32_t state; vop_found= pc->frame_start_found; state= pc->state; i=0; if(!vop_found){ - for(i=0; i<buf_size; i++){ + for(i=0; i<buf_size;){ state= (state<<8) | buf[i]; - if(state == 0xFFD8){ - i++; - vop_found=1; - break; + if(state>=0xFFC00000 && state<=0xFFFEFFFF){ + if(state>=0xFFD80000 && state<=0xFFD8FFFF){ + i++; + vop_found=1; + break; + }else if(state<0xFFD00000 || state>0xFFD9FFFF){ + m->size= (state&0xFFFF)-1; + } } + if(m->size>0){ + int size= FFMIN(buf_size-i, m->size); + i+=size; + m->size-=size; + state=0; + continue; + }else + i++; } } @@ -56,13 +73,25 @@ static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ /* EOF considered as end of frame */ if (buf_size == 0) return 0; - for(; i<buf_size; i++){ + for(; i<buf_size;){ state= (state<<8) | buf[i]; - if(state == 0xFFD8){ - pc->frame_start_found=0; - pc->state=0; - return i-1; + if(state>=0xFFC00000 && state<=0xFFFEFFFF){ + if(state>=0xFFD80000 && state<=0xFFD8FFFF){ + pc->frame_start_found=0; + pc->state=0; + return i-3; + } else if(state<0xFFD00000 || state>0xFFD9FFFF){ + m->size= (state&0xFFFF)-1; + } } + if(m->size>0){ + int size= FFMIN(buf_size-i, m->size); + i+=size; + m->size-=size; + state=0; + continue; + }else + i++; } } pc->frame_start_found= vop_found; @@ -75,13 +104,14 @@ static int jpeg_parse(AVCodecParserContext *s, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { - ParseContext *pc = s->priv_data; + MJPEGParserContext *m = s->priv_data; + ParseContext *pc = &m->pc; int next; if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ next= buf_size; }else{ - next= find_frame_end(pc, buf, buf_size); + next= find_frame_end(m, buf, buf_size); if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { *poutbuf = NULL; @@ -98,7 +128,7 @@ static int jpeg_parse(AVCodecParserContext *s, AVCodecParser ff_mjpeg_parser = { .codec_ids = { CODEC_ID_MJPEG }, - .priv_data_size = sizeof(ParseContext), + .priv_data_size = sizeof(MJPEGParserContext), .parser_parse = jpeg_parse, .parser_close = ff_parse_close, }; diff --git a/libavcodec/mjpega_dump_header_bsf.c b/libavcodec/mjpega_dump_header_bsf.c index 2a181fc386..2e86fd4ef3 100644 --- a/libavcodec/mjpega_dump_header_bsf.c +++ b/libavcodec/mjpega_dump_header_bsf.c @@ -2,20 +2,20 @@ * MJPEG A dump header bitstream filter * Copyright (c) 2006 Baptiste Coudurier * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index c89a5bd404..fc77b14b44 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -2,20 +2,20 @@ * Apple MJPEG-B decoder * Copyright (c) 2002 Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 48a872bdb7..fcdcc21caf 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -8,20 +8,20 @@ * aspecting, new decode_frame mechanism and apple mjpeg-b support * by Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -34,6 +34,7 @@ #include <assert.h> #include "libavutil/imgutils.h" +#include "libavutil/avassert.h" #include "libavutil/opt.h" #include "avcodec.h" #include "dsputil.h" @@ -88,6 +89,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) if (!s->picture_ptr) s->picture_ptr = &s->picture; + avcodec_get_frame_defaults(&s->picture); s->avctx = avctx; dsputil_init(&s->dsp, avctx); @@ -106,8 +108,8 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) 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\n"); - return AVERROR_INVALIDDATA; + "mjpeg: error using external huffman table, switching back to internal\n"); + build_basic_mjpeg_vlc(s); } } if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */ @@ -212,6 +214,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) { int len, nb_components, i, width, height, pix_fmt_id; + s->cur_scan = 0; + s->upscale_h = s->upscale_v = 0; + /* XXX: verify len field validity */ len = get_bits(&s->gb, 16); s->bits = get_bits(&s->gb, 8); @@ -226,6 +231,11 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) return -1; } + if(s->lossless && s->avctx->lowres){ + av_log(s->avctx, AV_LOG_ERROR, "lowres is not possible with lossless jpeg\n"); + return -1; + } + height = get_bits(&s->gb, 16); width = get_bits(&s->gb, 16); @@ -273,7 +283,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) return -1; } - if (s->v_max == 1 && s->h_max == 1 && s->lossless == 1) + if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && nb_components==3) s->rgb = 1; /* if different size, realloc/alloc picture */ @@ -321,28 +331,74 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) switch (pix_fmt_id) { case 0x11111100: if (s->rgb) - s->avctx->pix_fmt = PIX_FMT_BGRA; - else + s->avctx->pix_fmt = PIX_FMT_BGR24; + else { + if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') { + s->avctx->pix_fmt = PIX_FMT_GBR24P; + } else { s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + } + } assert(s->nb_components == 3); break; + case 0x12121100: + case 0x22122100: + s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + s->upscale_v = 2; + s->upscale_h = (pix_fmt_id == 0x22122100); + s->chroma_height = s->height; + break; + case 0x21211100: + case 0x22211200: + s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + s->upscale_v = (pix_fmt_id == 0x22211200); + s->upscale_h = 2; + s->chroma_height = s->height; + break; + case 0x22221100: + s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + s->upscale_v = 2; + s->upscale_h = 2; + s->chroma_height = s->height / 2; + break; case 0x11000000: - s->avctx->pix_fmt = PIX_FMT_GRAY8; + if(s->bits <= 8) + s->avctx->pix_fmt = PIX_FMT_GRAY8; + else + s->avctx->pix_fmt = PIX_FMT_GRAY16; break; case 0x12111100: + case 0x22211100: + case 0x22112100: s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV440P : PIX_FMT_YUVJ440P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + s->upscale_h = (pix_fmt_id == 0x22211100) * 2 + (pix_fmt_id == 0x22112100); + s->chroma_height = s->height / 2; break; case 0x21111100: s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + break; + case 0x22121100: + case 0x22111200: + s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; + s->upscale_v = (pix_fmt_id == 0x22121100) + 1; break; case 0x22111100: s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV420P : PIX_FMT_YUVJ420P; + s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; break; default: av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id); return -1; } if (s->ls) { + s->upscale_h = s->upscale_v = 0; if (s->nb_components > 1) s->avctx->pix_fmt = PIX_FMT_RGB24; else if (s->bits <= 8) @@ -636,25 +692,27 @@ static int decode_block_refinement(MJpegDecodeContext *s, DCTELEM *block, #undef REFINE_BIT #undef ZERO_RUN -static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, - int point_transform) +static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int predictor, int point_transform) { int i, mb_x, mb_y; uint16_t (*buffer)[4]; int left[3], top[3], topleft[3]; const int linesize = s->linesize[0]; const int mask = (1 << s->bits) - 1; + int resync_mb_y = 0; + int resync_mb_x = 0; + + s->restart_count = s->restart_interval; av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0])); buffer = s->ljpeg_buffer; for (i = 0; i < 3; i++) - buffer[0][i] = 1 << (s->bits + point_transform - 1); + buffer[0][i] = 1 << (s->bits - 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_ptr->data[0] + (linesize * mb_y); + uint8_t *ptr = s->picture.data[0] + (linesize * mb_y); if (s->interlaced && s->bottom_field) ptr += linesize >> 1; @@ -663,19 +721,32 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, 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) + int modified_predictor = predictor; + + if (s->restart_interval && !s->restart_count){ s->restart_count = s->restart_interval; + resync_mb_x = mb_x; + resync_mb_y = mb_y; + for(i=0; i<3; i++) + top[i] = left[i]= topleft[i]= 1 << (s->bits - 1); + } + if (mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || !mb_x) + modified_predictor = 1; - for (i = 0; i < 3; i++) { - int pred; + for (i=0;i<nb_components;i++) { + int pred, dc; topleft[i] = top[i]; top[i] = buffer[mb_x][i]; PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); + dc = mjpeg_decode_dc(s, s->dc_index[i]); + if(dc == 0xFFFF) + return -1; + left[i] = buffer[mb_x][i] = - mask & (pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform)); + mask & (pred + (dc << point_transform)); } if (s->restart_interval && !--s->restart_count) { @@ -686,21 +757,22 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, 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]; + ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2); + ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1]; + ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*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]; + ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2]) >> 2); + ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1]; + ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1]; } } else { - for (mb_x = 0; mb_x < s->mb_width; mb_x++) { - ptr[4 * mb_x + 0] = buffer[mb_x][2]; - ptr[4 * mb_x + 1] = buffer[mb_x][1]; - ptr[4 * mb_x + 2] = buffer[mb_x][0]; + for(i=0; i<nb_components; i++) { + int c= s->comp_index[i]; + for(mb_x = 0; mb_x < s->mb_width; mb_x++) { + ptr[3*mb_x+2-c] = buffer[mb_x][i]; + } } } } @@ -711,48 +783,87 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point_transform) { int i, mb_x, mb_y; - const int nb_components = 3; + const int nb_components=s->nb_components; + int bits= (s->bits+7)&~7; + int resync_mb_y = 0; + int resync_mb_x = 0; + + point_transform += bits - s->bits; + + av_assert0(nb_components==1 || 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) + if (s->restart_interval && !s->restart_count){ s->restart_count = s->restart_interval; + resync_mb_x = mb_x; + resync_mb_y = mb_y; + } - if (mb_x == 0 || mb_y == 0 || s->interlaced) { + if(!mb_x || mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || s->interlaced){ + int toprow = mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x; + int leftcol = !mb_x || mb_y == resync_mb_y && mb_x == resync_mb_x; for (i = 0; i < nb_components; i++) { uint8_t *ptr; + uint16_t *ptr16; 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]; + 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; - // FIXME optimize this crap - ptr = s->picture_ptr->data[c] + - (linesize * (v * mb_y + y)) + - (h * mb_x + x); - 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(bits>8) linesize /= 2; + + for(j=0; j<n; j++) { + int pred, dc; + + dc = mjpeg_decode_dc(s, s->dc_index[i]); + if(dc == 0xFFFF) + return -1; + if(bits<=8){ + ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap + if(y==0 && toprow){ + if(x==0 && leftcol){ + pred= 1 << (bits - 1); + }else{ + pred= ptr[-1]; + } + }else{ + if(x==0 && leftcol){ + 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); + pred &= (-1)<<(8-s->bits); + *ptr= pred + (dc << point_transform); + }else{ + ptr16 = s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x); //FIXME optimize this crap + if(y==0 && toprow){ + if(x==0 && leftcol){ + pred= 1 << (bits - 1); + }else{ + pred= ptr16[-1]; + } + }else{ + if(x==0 && leftcol){ + pred= ptr16[-linesize]; + }else{ + PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor); + } + } + if (s->interlaced && s->bottom_field) + ptr16 += linesize >> 1; + pred &= (-1)<<(16-s->bits); + *ptr16= pred + (dc << point_transform); + } if (++x == h) { x = 0; y++; @@ -762,7 +873,8 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, } else { for (i = 0; i < nb_components; i++) { uint8_t *ptr; - int n, h, v, x, y, c, j, linesize; + uint16_t *ptr16; + int n, h, v, x, y, c, j, linesize, dc; n = s->nb_blocks[i]; c = s->comp_index[i]; h = s->h_scount[i]; @@ -771,16 +883,30 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, y = 0; linesize = s->linesize[c]; + if(bits>8) linesize /= 2; + for (j = 0; j < n; j++) { int pred; - // FIXME optimize this crap - ptr = s->picture_ptr->data[c] + + dc = mjpeg_decode_dc(s, s->dc_index[i]); + if(dc == 0xFFFF) + return -1; + if(bits<=8){ + ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + - (h * mb_x + x); - PREDICT(pred, ptr[-linesize - 1], - ptr[-linesize], ptr[-1], predictor); - *ptr = pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform); + (h * mb_x + x); //FIXME optimize this crap + PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); + + pred &= (-1)<<(8-s->bits); + *ptr = pred + (dc << point_transform); + }else{ + ptr16 = s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x); //FIXME optimize this crap + PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor); + + pred &= (-1)<<(16-s->bits); + *ptr16= pred + (dc << point_transform); + } + if (++x == h) { x = 0; y++; @@ -920,6 +1046,12 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, if (s->restart_interval) { s->restart_count--; + if(s->restart_count == 0 && s->avctx->codec_id == CODEC_ID_THP){ + align_get_bits(&s->gb); + for (i = 0; i < nb_components; i++) /* reset dc */ + s->last_dc[i] = 1024; + } + i = 8 + ((-get_bits_count(&s->gb)) & 7); /* skip RSTn */ if (show_bits(&s->gb, i) == (1 << i) - 1) { @@ -927,7 +1059,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, align_get_bits(&s->gb); while (get_bits_left(&s->gb) >= 8 && show_bits(&s->gb, 8) == 0xFF) skip_bits(&s->gb, 8); - if ((get_bits(&s->gb, 8) & 0xF8) == 0xD0) { + if (get_bits_left(&s->gb) >= 8 && (get_bits(&s->gb, 8) & 0xF8) == 0xD0) { for (i = 0; i < nb_components; i++) /* reset dc */ s->last_dc[i] = 1024; } else @@ -940,44 +1072,30 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, } static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, - int se, int Ah, int Al, - const uint8_t *mb_bitmask, - const AVFrame *reference) + int se, int Ah, int Al) { int mb_x, mb_y; int EOBRUN = 0; int c = s->comp_index[0]; - uint8_t *data = s->picture_ptr->data[c]; - const uint8_t *reference_data = reference ? reference->data[c] : NULL; + uint8_t *data = s->picture.data[c]; int linesize = s->linesize[c]; int last_scan = 0; int16_t *quant_matrix = s->quant_matrixes[s->quant_index[c]]; - GetBitContext mb_bitmask_gb; - - if (mb_bitmask) - init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height); if (!Al) { s->coefs_finished[c] |= (1LL << (se + 1)) - (1LL << ss); last_scan = !~s->coefs_finished[c]; } - if (s->interlaced && s->bottom_field) { - int offset = linesize >> 1; - data += offset; - reference_data += offset; - } + if (s->interlaced && s->bottom_field) + data += linesize >> 1; for (mb_y = 0; mb_y < s->mb_height; mb_y++) { - int block_offset = (mb_y * linesize * 8 >> s->avctx->lowres); - uint8_t *ptr = data + block_offset; + uint8_t *ptr = data + (mb_y * linesize * 8 >> s->avctx->lowres); int block_idx = mb_y * s->block_stride[c]; DCTELEM (*block)[64] = &s->blocks[c][block_idx]; uint8_t *last_nnz = &s->last_nnz[c][block_idx]; for (mb_x = 0; mb_x < s->mb_width; mb_x++, block++, last_nnz++) { - const int copy_mb = mb_bitmask && !get_bits1(&mb_bitmask_gb); - - if (!copy_mb) { int ret; if (Ah) ret = decode_block_refinement(s, *block, last_nnz, s->ac_index[0], @@ -990,16 +1108,10 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, "error y=%d x=%d\n", mb_y, mb_x); return -1; } - } if (last_scan) { - if (copy_mb) { - mjpeg_copy_block(ptr, reference_data + block_offset, - linesize, s->avctx->lowres); - } else { s->dsp.idct_put(ptr, linesize, *block); ptr += 8 >> s->avctx->lowres; - } } } } @@ -1043,6 +1155,9 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, && nb_components == 3 && s->nb_components == 3 && i) index = 3 - i; + if(nb_components == 3 && s->nb_components == 3 && s->avctx->pix_fmt == PIX_FMT_GBR24P) + index = (i+2)%3; + s->comp_index[i] = index; s->nb_blocks[i] = s->h_count[index] * s->v_count[index]; @@ -1055,15 +1170,17 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, 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 (!s->vlcs[0][s->dc_index[i]].table || - !s->vlcs[1][s->ac_index[i]].table) + if (!s->vlcs[0][s->dc_index[i]].table || !(s->progressive ? s->vlcs[2][s->ac_index[0]].table : s->vlcs[1][s->ac_index[i]].table)) goto out_of_range; } 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 */ + if(s->avctx->codec_tag != AV_RL32("CJPG")){ + prev_shift = get_bits(&s->gb, 4); /* Ah */ + point_transform = get_bits(&s->gb, 4); /* Al */ + }else + prev_shift = point_transform = 0; for (i = 0; i < nb_components; i++) s->last_dc[i] = 1024; @@ -1083,10 +1200,10 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, } 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", + av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d skip:%d %s comp:%d\n", s->lossless ? "lossless" : "sequential DCT", s->rgb ? "RGB" : "", - predictor, point_transform, ilv, s->bits, - s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : "")); + predictor, point_transform, ilv, s->bits, s->mjpb_skiptosod, + s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : ""), nb_components); /* mjpeg-b can have padding bytes between sos and image data, skip them */ @@ -1094,6 +1211,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, skip_bits(&s->gb, 8); if (s->lossless) { + av_assert0(s->picture_ptr == &s->picture); if (CONFIG_JPEGLS_DECODER && s->ls) { // for () { // reset_ls_coding_parameters(s, 0); @@ -1102,7 +1220,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, return -1; } else { if (s->rgb) { - if (ljpeg_decode_rgb_scan(s, predictor, point_transform) < 0) + if (ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform) < 0) return -1; } else { if (ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0) @@ -1111,9 +1229,9 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, } } else { if (s->progressive && predictor) { + av_assert0(s->picture_ptr == &s->picture); if (mjpeg_decode_scan_progressive_ac(s, predictor, ilv, prev_shift, - point_transform, - mb_bitmask, reference) < 0) + point_transform) < 0) return -1; } else { if (mjpeg_decode_scan(s, nb_components, prev_shift, point_transform, @@ -1168,14 +1286,11 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) 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; + s->buggy_avid = 1; +// if (s->first_picture) +// printf("mjpeg: workarounding buggy AVID\n"); + i = get_bits(&s->gb, 8); len--; + av_log(s->avctx, AV_LOG_DEBUG, "polarity %d\n", i); #if 0 skip_bits(&s->gb, 8); skip_bits(&s->gb, 32); @@ -1328,9 +1443,7 @@ 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) { @@ -1340,9 +1453,7 @@ static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end) val = *buf_ptr++; goto found; } -#ifdef DEBUG skipped++; -#endif } val = -1; found: @@ -1445,6 +1556,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *unescaped_buf_ptr; int unescaped_buf_size; int start_code; + int i, index; AVFrame *picture = data; s->got_picture = 0; // picture from previous image can not be reused @@ -1528,21 +1640,19 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, return -1; break; case EOI: - s->cur_scan = 0; - if ((s->buggy_avid && !s->interlaced) || s->restart_interval) - break; eoi_parser: + s->cur_scan = 0; if (!s->got_picture) { av_log(avctx, AV_LOG_WARNING, "Found EOI before any SOF, ignoring\n"); break; - } + } 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; - } + break; + } *picture = *s->picture_ptr; *data_size = sizeof(AVFrame); @@ -1570,10 +1680,6 @@ eoi_parser: if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; - /* 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); @@ -1596,7 +1702,6 @@ eoi_parser: // break; } -not_the_end: /* eof process start code */ buf_ptr += (get_bits_count(&s->gb) + 7) / 8; av_log(avctx, AV_LOG_DEBUG, @@ -1611,6 +1716,36 @@ not_the_end: av_log(avctx, AV_LOG_FATAL, "No JPEG data found in image\n"); return -1; the_end: + if (s->upscale_h) { + uint8_t *line = s->picture_ptr->data[s->upscale_h]; + av_assert0(avctx->pix_fmt == PIX_FMT_YUVJ444P || + avctx->pix_fmt == PIX_FMT_YUV444P || + avctx->pix_fmt == PIX_FMT_YUVJ440P || + avctx->pix_fmt == PIX_FMT_YUV440P); + for (i = 0; i < s->chroma_height; i++) { + for (index = s->width - 1; index; index--) + line[index] = (line[index / 2] + line[(index + 1) / 2]) >> 1; + line += s->linesize[s->upscale_h]; + } + } + if (s->upscale_v) { + uint8_t *dst = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(s->height - 1) * s->linesize[s->upscale_v]]; + av_assert0(avctx->pix_fmt == PIX_FMT_YUVJ444P || + avctx->pix_fmt == PIX_FMT_YUV444P || + avctx->pix_fmt == PIX_FMT_YUVJ422P || + avctx->pix_fmt == PIX_FMT_YUV422P); + for (i = s->height - 1; i; i--) { + uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[i / 2 * s->linesize[s->upscale_v]]; + uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(i + 1) / 2 * s->linesize[s->upscale_v]]; + if (src1 == src2) { + memcpy(dst, src1, s->width); + } else { + for (index = 0; index < s->width; index++) + dst[index] = (src1[index] + src2[index]) >> 1; + } + dst -= s->linesize[s->upscale_v]; + } + } av_log(avctx, AV_LOG_DEBUG, "mjpeg decode frame unused %td bytes\n", buf_end - buf_ptr); // return buf_end - buf_ptr; diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index bfa987d3c5..23b3498f65 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -4,20 +4,20 @@ * Copyright (c) 2003 Alex Beregszaszi * Copyright (c) 2003-2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -58,6 +58,9 @@ typedef struct MJpegDecodeContext { int ls; int progressive; int rgb; + int upscale_h; + int chroma_height; + int upscale_v; int rct; /* standard rct */ int pegasus_rct; /* pegasus reversible colorspace transform */ int bits; /* bits per component */ diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index d1005c8ab1..bddcc0d041 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -8,20 +8,20 @@ * aspecting, new decode_frame mechanism and apple mjpeg-b support * by Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -156,13 +156,13 @@ static void jpeg_put_comments(MpegEncContext *s) int size; uint8_t *ptr; - if (s->aspect_ratio_info /* && !lossless */) + if (s->avctx->sample_aspect_ratio.num /* && !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, 16, 0x0102); /* 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); @@ -200,6 +200,9 @@ void ff_mjpeg_encode_picture_header(MpegEncContext *s) put_marker(&s->pb, SOI); + // hack for AMV mjpeg format + if(s->avctx->codec_id == CODEC_ID_AMV) return; + jpeg_put_comments(s); jpeg_table_header(s); @@ -211,7 +214,9 @@ void ff_mjpeg_encode_picture_header(MpegEncContext *s) } put_bits(&s->pb, 16, 17); - if(lossless && s->avctx->pix_fmt == PIX_FMT_BGRA) + if(lossless && (s->avctx->pix_fmt == PIX_FMT_BGR0 + || s->avctx->pix_fmt == PIX_FMT_BGRA + || s->avctx->pix_fmt == PIX_FMT_BGR24)) put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */ else put_bits(&s->pb, 8, 8); /* 8 bits/component */ @@ -445,6 +450,28 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]) s->i_tex_bits += get_bits_diff(s); } +// maximum over s->mjpeg_vsample[i] +#define V_MAX 2 +static int amv_encode_picture(AVCodecContext *avctx, + unsigned char *buf, int buf_size, void *data) +{ + + AVFrame* pic=data; + MpegEncContext *s = avctx->priv_data; + int i; + + //CODEC_FLAG_EMU_EDGE have to be cleared + if(s->avctx->flags & CODEC_FLAG_EMU_EDGE) + return -1; + + //picture should be flipped upside-down + for(i=0; i < 3; i++) { + pic->data[i] += (pic->linesize[i] * (s->mjpeg_vsample[i] * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 )); + pic->linesize[i] *= -1; + } + return MPV_encode_picture(avctx,buf, buf_size, pic); +} + AVCodec ff_mjpeg_encoder = { .name = "mjpeg", .type = AVMEDIA_TYPE_VIDEO, @@ -456,3 +483,15 @@ AVCodec ff_mjpeg_encoder = { .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), }; + +AVCodec ff_amv_encoder = { + .name = "amv", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_AMV, + .priv_data_size = sizeof(MpegEncContext), + .init = MPV_encode_init, + .encode = amv_encode_picture, + .close = MPV_encode_end, + .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("AMV Video"), +}; diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h index 12ff54055e..49627a3d55 100644 --- a/libavcodec/mjpegenc.h +++ b/libavcodec/mjpegenc.h @@ -8,20 +8,20 @@ * aspecting, new decode_frame mechanism and apple mjpeg-b support * by Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mlp.c b/libavcodec/mlp.c index 9615b66ee1..87f7c77139 100644 --- a/libavcodec/mlp.c +++ b/libavcodec/mlp.c @@ -2,20 +2,20 @@ * MLP codec common code * Copyright (c) 2007-2008 Ian Caulfield * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mlp.h b/libavcodec/mlp.h index b001ad270d..628b58d318 100644 --- a/libavcodec/mlp.h +++ b/libavcodec/mlp.h @@ -2,20 +2,20 @@ * MLP codec common header file * Copyright (c) 2007-2008 Ian Caulfield * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c index e0fedeb7e9..f31e2d5727 100644 --- a/libavcodec/mlp_parser.c +++ b/libavcodec/mlp_parser.c @@ -2,20 +2,20 @@ * MLP parser * Copyright (c) 2007 Ian Caulfield * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -43,28 +43,28 @@ static const uint8_t mlp_channels[32] = { 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -static const uint64_t mlp_layout[32] = { +const uint64_t ff_mlp_layout[32] = { AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_2_1, - AV_CH_LAYOUT_2_2, + AV_CH_LAYOUT_QUAD, AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY, - AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY, + AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY, AV_CH_LAYOUT_SURROUND, AV_CH_LAYOUT_4POINT0, - AV_CH_LAYOUT_5POINT0, + AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, - AV_CH_LAYOUT_5POINT1, + AV_CH_LAYOUT_5POINT1_BACK, AV_CH_LAYOUT_4POINT0, - AV_CH_LAYOUT_5POINT0, + AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, - AV_CH_LAYOUT_5POINT1, - AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY, - AV_CH_LAYOUT_5POINT0, - AV_CH_LAYOUT_5POINT1, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_5POINT1_BACK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -79,13 +79,13 @@ static const uint64_t thd_layout[13] = { AV_CH_LOW_FREQUENCY, // LFE AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, // LRs AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT, // LRvh - AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, // LRc + AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER, // LRc AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, // LRrs AV_CH_BACK_CENTER, // Cs - AV_CH_TOP_BACK_CENTER, // Ts - AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, // LRsd - AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER, // LRw - AV_CH_TOP_BACK_CENTER, // Cvh + AV_CH_TOP_CENTER, // Ts + AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, // LRsd - TODO: Surround Direct + AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER, // LRw - TODO: Wide + AV_CH_TOP_FRONT_CENTER, // Cvh AV_CH_LOW_FREQUENCY // LFE2 }; @@ -107,7 +107,7 @@ static int truehd_channels(int chanmap) return channels; } -static uint64_t truehd_layout(int chanmap) +uint64_t ff_truehd_layout(int chanmap) { int layout = 0, i; @@ -263,6 +263,9 @@ static int mlp_parse(AVCodecParserContext *s, 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; + if (mp->bytes_left <= 0) { // prevent infinite loop + goto lost_sync; + } mp->bytes_left -= mp->pc.index; } @@ -316,15 +319,15 @@ static int mlp_parse(AVCodecParserContext *s, if (mh.stream_type == 0xbb) { /* MLP stream */ avctx->channels = mlp_channels[mh.channels_mlp]; - avctx->channel_layout = mlp_layout[mh.channels_mlp]; + avctx->channel_layout = ff_mlp_layout[mh.channels_mlp]; } else { /* mh.stream_type == 0xba */ /* TrueHD stream */ if (mh.channels_thd_stream2) { avctx->channels = truehd_channels(mh.channels_thd_stream2); - avctx->channel_layout = truehd_layout(mh.channels_thd_stream2); + avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2); } else { avctx->channels = truehd_channels(mh.channels_thd_stream1); - avctx->channel_layout = truehd_layout(mh.channels_thd_stream1); + avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1); } } diff --git a/libavcodec/mlp_parser.h b/libavcodec/mlp_parser.h index 35bb312f17..6aafed5086 100644 --- a/libavcodec/mlp_parser.h +++ b/libavcodec/mlp_parser.h @@ -2,20 +2,20 @@ * MLP parser prototypes * Copyright (c) 2007 Ian Caulfield * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -54,5 +54,8 @@ typedef struct MLPHeaderInfo int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb); +uint64_t ff_truehd_layout(int chanmap); + +extern const uint64_t ff_mlp_layout[32]; #endif /* AVCODEC_MLP_PARSER_H */ diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 357e28728d..47aee286ff 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -2,20 +2,20 @@ * MLP decoder * Copyright (c) 2007-2008 Ian Caulfield * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +41,7 @@ static const char* sample_message = "Please file a bug report following the instructions at " - "http://libav.org/bugreports.html and include " + "http://ffmpeg.org/bugreports.html and include " "a sample of this file."; typedef struct SubStream { @@ -134,6 +134,9 @@ typedef struct MLPDecodeContext { /// Index of the last substream to decode - further substreams are skipped. uint8_t max_decoded_substream; + /// Stream needs channel reordering to comply with FFmpeg's channel order + uint8_t needs_reordering; + /// number of PCM samples contained in each frame int access_unit_size; /// next power of two above the number of samples in each frame @@ -330,6 +333,26 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb) for (substr = 0; substr < MAX_SUBSTREAMS; substr++) m->substream[substr].restart_seen = 0; + if (mh.stream_type == 0xbb) { + /* MLP stream */ + m->avctx->channel_layout = ff_mlp_layout[mh.channels_mlp]; + } else { /* mh.stream_type == 0xba */ + /* TrueHD stream */ + if (mh.channels_thd_stream2) { + m->avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2); + } else { + m->avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1); + } + if (m->avctx->channels && + !m->avctx->request_channels && !m->avctx->request_channel_layout && + av_get_channel_layout_nb_channels(m->avctx->channel_layout) != m->avctx->channels) { + m->avctx->channel_layout = 0; + av_log_ask_for_sample(m->avctx, "Unknown channel layout."); + } + } + + m->needs_reordering = mh.channels_mlp >= 18 && mh.channels_mlp <= 20; + return 0; } @@ -440,6 +463,33 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, s->ch_assign[ch_assign] = ch; } + if (m->avctx->codec_id == CODEC_ID_MLP && m->needs_reordering) { + if (m->avctx->channel_layout == (AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY) || + m->avctx->channel_layout == AV_CH_LAYOUT_5POINT0_BACK) { + int i = s->ch_assign[4]; + s->ch_assign[4] = s->ch_assign[3]; + s->ch_assign[3] = s->ch_assign[2]; + s->ch_assign[2] = i; + } else if (m->avctx->channel_layout == AV_CH_LAYOUT_5POINT1_BACK) { + FFSWAP(int, s->ch_assign[2], s->ch_assign[4]); + FFSWAP(int, s->ch_assign[3], s->ch_assign[5]); + } + } + if (m->avctx->codec_id == CODEC_ID_TRUEHD && + (m->avctx->channel_layout == AV_CH_LAYOUT_7POINT1 || + m->avctx->channel_layout == AV_CH_LAYOUT_7POINT1_WIDE)) { + FFSWAP(int, s->ch_assign[4], s->ch_assign[6]); + FFSWAP(int, s->ch_assign[5], s->ch_assign[7]); + } else if (m->avctx->codec_id == CODEC_ID_TRUEHD && + (m->avctx->channel_layout == AV_CH_LAYOUT_6POINT1 || + m->avctx->channel_layout == (AV_CH_LAYOUT_6POINT1 | AV_CH_TOP_CENTER) || + m->avctx->channel_layout == (AV_CH_LAYOUT_6POINT1 | AV_CH_TOP_FRONT_CENTER))) { + int i = s->ch_assign[6]; + s->ch_assign[6] = s->ch_assign[5]; + s->ch_assign[5] = s->ch_assign[4]; + s->ch_assign[4] = i; + } + checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count); if (checksum != get_bits(gbp, 8)) diff --git a/libavcodec/mlpdsp.c b/libavcodec/mlpdsp.c index 7d01c7586d..7ec8dd24e6 100644 --- a/libavcodec/mlpdsp.c +++ b/libavcodec/mlpdsp.c @@ -2,20 +2,20 @@ * Copyright (c) 2007-2008 Ian Caulfield * 2009 Ramiro Polla * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mmvideo.c b/libavcodec/mmvideo.c index 9e82ef94f9..ff7d100792 100644 --- a/libavcodec/mmvideo.c +++ b/libavcodec/mmvideo.c @@ -2,20 +2,20 @@ * American Laser Games MM Video Decoder * Copyright (c) 2006,2008 Peter Ross * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -58,7 +58,8 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_PAL8; - s->frame.reference = 1; + avcodec_get_frame_defaults(&s->frame); + s->frame.reference = 3; return 0; } @@ -68,7 +69,7 @@ static void mm_decode_pal(MmContext *s, const uint8_t *buf, const uint8_t *buf_e int i; buf += 4; for (i=0; i<128 && buf+2<buf_end; i++) { - s->palette[i] = AV_RB24(buf); + s->palette[i] = 0xFF << 24 | AV_RB24(buf); s->palette[i+128] = s->palette[i]<<2; buf += 3; } diff --git a/libavcodec/motion-test.c b/libavcodec/motion-test.c index 8708636030..f187183c12 100644 --- a/libavcodec/motion-test.c +++ b/libavcodec/motion-test.c @@ -1,20 +1,20 @@ /* * (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -140,7 +140,7 @@ int main(int argc, char **argv) } } - printf("Libav motion test\n"); + printf("ffmpeg motion test\n"); ctx = avcodec_alloc_context3(NULL); ctx->dsp_mask = AV_CPU_FLAG_FORCE; diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index 2aa89786a1..ad6395296e 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -5,20 +5,20 @@ * * new motion estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -536,8 +536,8 @@ static inline void get_limits(MpegEncContext *s, int x, int y) if (s->unrestricted_mv) { c->xmin = - x - 16; c->ymin = - y - 16; - c->xmax = - x + s->mb_width *16; - c->ymax = - y + s->mb_height*16; + c->xmax = - x + s->width; + c->ymax = - y + s->height; } else if (s->out_format == FMT_H261){ // Search range of H261 is different from other codec standards c->xmin = (x > 15) ? - 15 : 0; @@ -576,10 +576,11 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) const int h=8; int block; int P[10][2]; - int dmin_sum=0, mx4_sum=0, my4_sum=0; + int dmin_sum=0, mx4_sum=0, my4_sum=0, i; int same=1; const int stride= c->stride; uint8_t *mv_penalty= c->current_mv_penalty; + int saftey_cliping= s->unrestricted_mv && (s->width&15) && (s->height&15); init_mv4_ref(c); @@ -591,6 +592,11 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) const int mot_stride = s->b8_stride; const int mot_xy = s->block_index[block]; + if(saftey_cliping){ + c->xmax = - 16*s->mb_x + s->width - 8*(block &1); + c->ymax = - 16*s->mb_y + s->height - 8*(block>>1); + } + P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0]; P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1]; @@ -618,6 +624,11 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) } P_MV1[0]= mx; P_MV1[1]= my; + if(saftey_cliping) + for(i=0; i<10; i++){ + if(P[i][0] > (c->xmax<<shift)) P[i][0]= (c->xmax<<shift); + if(P[i][1] > (c->ymax<<shift)) P[i][1]= (c->ymax<<shift); + } dmin4 = epzs_motion_search4(s, &mx4, &my4, P, block, block, s->p_mv_table, (1<<16)>>shift); diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c index d0d4b4107a..b7b7b6d521 100644 --- a/libavcodec/motion_est_template.c +++ b/libavcodec/motion_est_template.c @@ -2,20 +2,20 @@ * Motion estimation * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -89,6 +89,7 @@ static int hpel_motion_search(MpegEncContext * s, const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] + (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*c->penalty_factor; +#if 1 unsigned key; unsigned map_generation= c->map_generation; #ifndef NDEBUG @@ -102,6 +103,7 @@ static int hpel_motion_search(MpegEncContext * s, assert(map[(index+1)&(ME_MAP_SIZE-1)] == key); key= ((my)<<ME_MAP_MV_BITS) + (mx-1) + map_generation; assert(map[(index-1)&(ME_MAP_SIZE-1)] == key); +#endif if(t<=b){ CHECK_HALF_MV(0, 1, mx ,my-1) if(l<=r){ diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index d054e00342..f23a8799b1 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -2,20 +2,20 @@ * Motion Pixels Video Decoder * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -63,6 +63,7 @@ static av_cold int mp_decode_init(AVCodecContext *avctx) mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel)); mp->hpt = av_mallocz(h4 * w4 / 16 * sizeof(YuvPixel)); avctx->pix_fmt = PIX_FMT_RGB555; + avcodec_get_frame_defaults(&mp->frame); return 0; } @@ -240,7 +241,7 @@ static int mp_decode_frame(AVCodecContext *avctx, GetBitContext gb; int i, count1, count2, sz; - mp->frame.reference = 1; + mp->frame.reference = 3; mp->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &mp->frame)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); diff --git a/libavcodec/motionpixels_tablegen.c b/libavcodec/motionpixels_tablegen.c index ad8e0d9161..31e5cdf710 100644 --- a/libavcodec/motionpixels_tablegen.c +++ b/libavcodec/motionpixels_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/motionpixels_tablegen.h b/libavcodec/motionpixels_tablegen.h index cbf56c8694..b9802e589d 100644 --- a/libavcodec/motionpixels_tablegen.h +++ b/libavcodec/motionpixels_tablegen.h @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -30,7 +30,7 @@ typedef struct YuvPixel { } YuvPixel; static int mp_yuv_to_rgb(int y, int v, int u, int clip_rgb) { - static const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; + const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int r, g, b; r = (1000 * y + 701 * v) / 1000; diff --git a/libavcodec/movsub_bsf.c b/libavcodec/movsub_bsf.c index 423ebebcc6..088c774001 100644 --- a/libavcodec/movsub_bsf.c +++ b/libavcodec/movsub_bsf.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Reimar Döffinger * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mp3_header_compress_bsf.c b/libavcodec/mp3_header_compress_bsf.c index bc3659ef3e..417a2940d5 100644 --- a/libavcodec/mp3_header_compress_bsf.c +++ b/libavcodec/mp3_header_compress_bsf.c @@ -1,20 +1,20 @@ /* * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mp3_header_decompress_bsf.c b/libavcodec/mp3_header_decompress_bsf.c index 78025ccc41..c08aa1fa05 100644 --- a/libavcodec/mp3_header_decompress_bsf.c +++ b/libavcodec/mp3_header_decompress_bsf.c @@ -1,20 +1,20 @@ /* * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpc.c b/libavcodec/mpc.c index 4573860525..c2975ec732 100644 --- a/libavcodec/mpc.c +++ b/libavcodec/mpc.c @@ -2,20 +2,20 @@ * Musepack decoder core * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpc.h b/libavcodec/mpc.h index 1a6e7943af..8b4deef689 100644 --- a/libavcodec/mpc.h +++ b/libavcodec/mpc.h @@ -2,20 +2,20 @@ * Musepack decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpc7.c b/libavcodec/mpc7.c index 8b3a1b9a20..5693c4ddb2 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -2,20 +2,20 @@ * Musepack SV7 decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpc7data.h b/libavcodec/mpc7data.h index f205ffe97f..5609e8fbf3 100644 --- a/libavcodec/mpc7data.h +++ b/libavcodec/mpc7data.h @@ -2,20 +2,20 @@ * Musepack decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpc8.c b/libavcodec/mpc8.c index b97f3ed62c..a4750ad961 100644 --- a/libavcodec/mpc8.c +++ b/libavcodec/mpc8.c @@ -2,20 +2,20 @@ * Musepack SV8 decoder * Copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -127,6 +127,8 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) skip_bits(&gb, 3);//sample rate c->maxbands = get_bits(&gb, 5) + 1; + if (c->maxbands >= BANDS) + return AVERROR_INVALIDDATA; channels = get_bits(&gb, 4) + 1; if (channels > 2) { av_log_missing_feature(avctx, "Multichannel MPC SV8", 1); diff --git a/libavcodec/mpc8data.h b/libavcodec/mpc8data.h index 2940b30733..22c2be43bf 100644 --- a/libavcodec/mpc8data.h +++ b/libavcodec/mpc8data.h @@ -2,20 +2,20 @@ * Musepack SV8 decoder * Copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpc8huff.h b/libavcodec/mpc8huff.h index 6005e214e8..8491037aa4 100644 --- a/libavcodec/mpc8huff.h +++ b/libavcodec/mpc8huff.h @@ -2,20 +2,20 @@ * Musepack SV8 decoder * Copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpcdata.h b/libavcodec/mpcdata.h index 397dad59d8..03df3da3b5 100644 --- a/libavcodec/mpcdata.h +++ b/libavcodec/mpcdata.h @@ -2,20 +2,20 @@ * Musepack decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 4515ef04a7..c671fcf4f8 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,11 +25,15 @@ * MPEG-1/2 decoder */ +#define UNCHECKED_BITSTREAM_READER 1 + //#define DEBUG #include "internal.h" #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" +#include "libavutil/avassert.h" +#include "libavutil/timecode.h" #include "mpeg12.h" #include "mpeg12data.h" @@ -956,6 +960,7 @@ static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64]) } } } else { + av_assert0(!s->progressive_sequence); mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED; for (i = 0; i < 2; i++) { if (USES_LIST(mb_type, i)) { @@ -972,6 +977,10 @@ static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64]) } break; case MT_DMV: + if(s->progressive_sequence){ + av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n"); + return -1; + } s->mv_type = MV_TYPE_DMV; for (i = 0; i < 2; i++) { if (USES_LIST(mb_type, i)) { @@ -1171,31 +1180,61 @@ static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm, } } -static const enum PixelFormat pixfmt_xvmc_mpg2_420[] = { +static const enum PixelFormat mpeg1_hwaccel_pixfmt_list_420[] = { +#if CONFIG_MPEG_XVMC_DECODER PIX_FMT_XVMC_MPEG2_IDCT, PIX_FMT_XVMC_MPEG2_MC, - PIX_FMT_NONE }; +#endif +#if CONFIG_MPEG1_VDPAU_HWACCEL + PIX_FMT_VDPAU_MPEG1, +#endif + PIX_FMT_YUV420P, + PIX_FMT_NONE +}; + +static const enum PixelFormat mpeg2_hwaccel_pixfmt_list_420[] = { +#if CONFIG_MPEG_XVMC_DECODER + PIX_FMT_XVMC_MPEG2_IDCT, + PIX_FMT_XVMC_MPEG2_MC, +#endif +#if CONFIG_MPEG2_VDPAU_HWACCEL + PIX_FMT_VDPAU_MPEG2, +#endif +#if CONFIG_MPEG2_DXVA2_HWACCEL + PIX_FMT_DXVA2_VLD, +#endif +#if CONFIG_MPEG2_VAAPI_HWACCEL + PIX_FMT_VAAPI_VLD, +#endif + PIX_FMT_YUV420P, + PIX_FMT_NONE +}; + +static inline int uses_vdpau(AVCodecContext *avctx) { + return avctx->pix_fmt == PIX_FMT_VDPAU_MPEG1 || avctx->pix_fmt == PIX_FMT_VDPAU_MPEG2; +} static enum PixelFormat mpeg_get_pixelformat(AVCodecContext *avctx) { Mpeg1Context *s1 = avctx->priv_data; MpegEncContext *s = &s1->mpeg_enc_ctx; - if (avctx->xvmc_acceleration) - return avctx->get_format(avctx, pixfmt_xvmc_mpg2_420); - else if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) { - if (avctx->codec_id == CODEC_ID_MPEG1VIDEO) - return PIX_FMT_VDPAU_MPEG1; - else - return PIX_FMT_VDPAU_MPEG2; - } else { - if (s->chroma_format < 2) - return avctx->get_format(avctx, ff_hwaccel_pixfmt_list_420); - else if (s->chroma_format == 2) - return PIX_FMT_YUV422P; - else - return PIX_FMT_YUV444P; - } + if(s->chroma_format < 2) { + enum PixelFormat res; + res = avctx->get_format(avctx, + avctx->codec_id == CODEC_ID_MPEG1VIDEO ? + mpeg1_hwaccel_pixfmt_list_420 : + mpeg2_hwaccel_pixfmt_list_420); + if (res != PIX_FMT_XVMC_MPEG2_IDCT && res != PIX_FMT_XVMC_MPEG2_MC) { + avctx->xvmc_acceleration = 0; + } else if (!avctx->xvmc_acceleration) { + avctx->xvmc_acceleration = 2; + } + return res; + } else if(s->chroma_format == 2) + return PIX_FMT_YUV422P; + else + return PIX_FMT_YUV444P; } /* Call this function when we know all parameters. @@ -1289,8 +1328,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx) avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); // until then pix_fmt may be changed right after codec init if (avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || - avctx->hwaccel || - s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) + avctx->hwaccel ) if (avctx->idct_algo == FF_IDCT_AUTO) avctx->idct_algo = FF_IDCT_SIMPLE; @@ -1329,7 +1367,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_B) { s->full_pel[0] = get_bits1(&s->gb); f_code = get_bits(&s->gb, 3); - if (f_code == 0 && (avctx->err_recognition & AV_EF_BITSTREAM)) + if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))) return -1; s->mpeg_f_code[0][0] = f_code; s->mpeg_f_code[0][1] = f_code; @@ -1337,7 +1375,7 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, if (s->pict_type == AV_PICTURE_TYPE_B) { s->full_pel[1] = get_bits1(&s->gb); f_code = get_bits(&s->gb, 3); - if (f_code == 0 && (avctx->err_recognition & AV_EF_BITSTREAM)) + if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))) return -1; s->mpeg_f_code[1][0] = f_code; s->mpeg_f_code[1][1] = f_code; @@ -1459,7 +1497,7 @@ static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1 return -1; } if (intra && i == 0 && v != 8) { - av_log(s->avctx, AV_LOG_ERROR, "intra matrix invalid, ignoring\n"); + av_log(s->avctx, AV_LOG_ERROR, "intra matrix specifies invalid DC quantizer %d, ignoring", v); v = 8; // needed by pink.mpg / issue1046 } matrix0[j] = v; @@ -1524,7 +1562,6 @@ static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1) if (s->progressive_sequence && !s->frame_pred_frame_dct) { av_log(s->avctx, AV_LOG_ERROR, "invalid frame_pred_frame_dct\n"); - s->frame_pred_frame_dct = 1; } if (s->picture_structure == PICT_FRAME) { @@ -1771,7 +1808,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/; if (left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) - || ((avctx->err_recognition & AV_EF_BUFFER) && left > 8)) { + || ((avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) && left > 8)) { av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23))); return -1; } else @@ -1905,7 +1942,7 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) ff_xvmc_field_end(s); /* end of slice reached */ - if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field) { + if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field && !s->first_slice) { /* end of image */ s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_MPEG2; @@ -1951,7 +1988,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->aspect_ratio_info = get_bits(&s->gb, 4); if (s->aspect_ratio_info == 0) { av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n"); - if (avctx->err_recognition & AV_EF_BITSTREAM) + if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT)) return -1; } s->frame_rate_index = get_bits(&s->gb, 4); @@ -1997,6 +2034,7 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, s->progressive_sequence = 1; s->progressive_frame = 1; s->picture_structure = PICT_FRAME; + s->first_field = 0; s->frame_pred_frame_dct = 1; s->chroma_format = 1; s->codec_id = s->avctx->codec_id = CODEC_ID_MPEG1VIDEO; @@ -2032,15 +2070,12 @@ static int vcr2_init_sequence(AVCodecContext *avctx) avctx->pix_fmt = mpeg_get_pixelformat(avctx); avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt); - if (avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel || - s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) + if( avctx->pix_fmt == PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel ) if (avctx->idct_algo == FF_IDCT_AUTO) avctx->idct_algo = FF_IDCT_SIMPLE; if (MPV_common_init(s) < 0) return -1; - exchange_uv(s); // common init reset pblocks, so we swap them here - s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB s1->mpeg_enc_ctx_allocated = 1; for (i = 0; i < 64; i++) { @@ -2057,10 +2092,18 @@ static int vcr2_init_sequence(AVCodecContext *avctx) s->progressive_sequence = 1; s->progressive_frame = 1; s->picture_structure = PICT_FRAME; + s->first_field = 0; s->frame_pred_frame_dct = 1; s->chroma_format = 1; - s->codec_id = s->avctx->codec_id = CODEC_ID_MPEG2VIDEO; - avctx->sub_id = 2; /* indicates MPEG-2 */ + if (s->codec_tag == AV_RL32("BW10")) { + s->codec_id = s->avctx->codec_id = CODEC_ID_MPEG1VIDEO; + avctx->sub_id = 1; /* indicates MPEG-1 */ + } else { + exchange_uv(s); // common init reset pblocks, so we swap them here + s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB + s->codec_id = s->avctx->codec_id = CODEC_ID_MPEG2VIDEO; + avctx->sub_id = 2; /* indicates MPEG-2 */ + } s1->save_width = s->width; s1->save_height = s->height; s1->save_progressive_seq = s->progressive_sequence; @@ -2071,8 +2114,22 @@ static int vcr2_init_sequence(AVCodecContext *avctx) static void mpeg_decode_user_data(AVCodecContext *avctx, const uint8_t *p, int buf_size) { + Mpeg1Context *s = avctx->priv_data; const uint8_t *buf_end = p + buf_size; + if(buf_size > 29){ + int i; + for(i=0; i<20; i++) + if(!memcmp(p+i, "\0TMPGEXS\0", 9)){ + s->tmpgexs= 1; + } + +/* for(i=0; !(!p[i-2] && !p[i-1] && p[i]==1) && i<buf_size; i++){ + av_log(0,0, "%c", p[i]); + } + av_log(0,0, "\n");*/ + } + /* we parse the DTG active format information */ if (buf_end - p >= 5 && p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') { @@ -2095,31 +2152,26 @@ static void mpeg_decode_gop(AVCodecContext *avctx, { Mpeg1Context *s1 = avctx->priv_data; MpegEncContext *s = &s1->mpeg_enc_ctx; - - int time_code_hours, time_code_minutes; - int time_code_seconds, time_code_pictures; int broken_link; + int64_t tc; init_get_bits(&s->gb, buf, buf_size*8); - skip_bits1(&s->gb); /* drop_frame_flag */ + tc = avctx->timecode_frame_start = get_bits(&s->gb, 25); - time_code_hours = get_bits(&s->gb, 5); - time_code_minutes = get_bits(&s->gb, 6); - skip_bits1(&s->gb); // marker bit - time_code_seconds = get_bits(&s->gb, 6); - time_code_pictures = get_bits(&s->gb, 6); - - s1->closed_gop = get_bits1(&s->gb); + s->closed_gop = get_bits1(&s->gb); /*broken_link indicate that after editing the reference frames of the first B-Frames after GOP I-Frame are missing (open gop)*/ broken_link = get_bits1(&s->gb); - if (s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "GOP (%2d:%02d:%02d.[%02d]) closed_gop=%d broken_link=%d\n", - time_code_hours, time_code_minutes, time_code_seconds, - time_code_pictures, s1->closed_gop, broken_link); + if (s->avctx->debug & FF_DEBUG_PICT_INFO) { + char tcbuf[AV_TIMECODE_STR_SIZE]; + av_timecode_make_mpeg_tc_string(tcbuf, tc); + av_log(s->avctx, AV_LOG_DEBUG, + "GOP (%s) closed_gop=%d broken_link=%d\n", + tcbuf, s->closed_gop, broken_link); + } } /** * Find the end of the current frame in the bitstream. @@ -2161,6 +2213,7 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, pc->frame_start_found = 4; } if (state == SEQ_END_CODE) { + pc->frame_start_found = 0; pc->state=-1; return i+1; } @@ -2218,7 +2271,10 @@ static int mpeg_decode_frame(AVCodecContext *avctx, return buf_size; } - if (s->mpeg_enc_ctx_allocated == 0 && avctx->codec_tag == AV_RL32("VCR2")) + s2->codec_tag = avpriv_toupper4(avctx->codec_tag); + if (s->mpeg_enc_ctx_allocated == 0 && ( s2->codec_tag == AV_RL32("VCR2") + || s2->codec_tag == AV_RL32("BW10") + )) vcr2_init_sequence(avctx); s->slice_count = 0; @@ -2251,15 +2307,17 @@ static int decode_chunks(AVCodecContext *avctx, if (s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT) { if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) { int i; + av_assert0(avctx->thread_count > 1); avctx->execute(avctx, slice_decode_thread, &s2->thread_context[0], NULL, s->slice_count, sizeof(void*)); for (i = 0; i < s->slice_count; i++) s2->error_count += s2->thread_context[i]->error_count; } - if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) + if (CONFIG_VDPAU && uses_vdpau(avctx)) ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count); + if (slice_end(avctx, picture)) { if (s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice *data_size = sizeof(AVPicture); @@ -2280,7 +2338,8 @@ static int decode_chunks(AVCodecContext *avctx, case SEQ_START_CODE: if (last_code == 0) { mpeg1_decode_sequence(avctx, buf_ptr, input_size); - s->sync=1; + if(buf != avctx->extradata) + s->sync=1; } else { av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code); if (avctx->err_recognition & AV_EF_EXPLODE) @@ -2289,6 +2348,10 @@ static int decode_chunks(AVCodecContext *avctx, break; case PICTURE_START_CODE: + if(s->tmpgexs){ + s2->intra_dc_precision= 3; + s2->intra_matrix[0]= 1; + } if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) && s->slice_count) { int i; @@ -2382,11 +2445,11 @@ static int decode_chunks(AVCodecContext *avctx, if (s2->last_picture_ptr == NULL) { /* Skip B-frames if we do not have reference frames and gop is not closed */ if (s2->pict_type == AV_PICTURE_TYPE_B) { - if (!s->closed_gop) + if (!s2->closed_gop) break; } } - if (s2->pict_type == AV_PICTURE_TYPE_I) + if (s2->pict_type == AV_PICTURE_TYPE_I || (s2->flags2 & CODEC_FLAG2_SHOW_ALL)) s->sync=1; if (s2->next_picture_ptr == NULL) { /* Skip P-frames if we do not have a reference frame or we have an invalid header. */ @@ -2422,7 +2485,7 @@ static int decode_chunks(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) { + if (uses_vdpau(avctx)) { s->slice_count++; break; } @@ -2431,6 +2494,7 @@ static int decode_chunks(AVCodecContext *avctx, int threshold = (s2->mb_height * s->slice_count + s2->slice_context_count / 2) / s2->slice_context_count; + av_assert0(avctx->thread_count > 1); if (threshold <= mb_y) { MpegEncContext *thread_context = s2->thread_context[s->slice_count]; @@ -2468,7 +2532,6 @@ static void flush(AVCodecContext *avctx) Mpeg1Context *s = avctx->priv_data; s->sync=0; - s->closed_gop = 0; ff_mpeg_flush(avctx); } @@ -2525,6 +2588,21 @@ AVCodec ff_mpeg2video_decoder = { .profiles = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles), }; +//legacy decoder +AVCodec ff_mpegvideo_decoder = { + .name = "mpegvideo", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG2VIDEO, + .priv_data_size = sizeof(Mpeg1Context), + .init = mpeg_decode_init, + .close = mpeg_decode_end, + .decode = mpeg_decode_frame, + .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, + .flush = flush, + .max_lowres = 3, + .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"), +}; + #if CONFIG_MPEG_XVMC_DECODER static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx) { diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h index ab0352ff10..9a9cc85dee 100644 --- a/libavcodec/mpeg12.h +++ b/libavcodec/mpeg12.h @@ -2,20 +2,20 @@ * MPEG1/2 common code * Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +41,7 @@ typedef struct Mpeg1Context { int save_width, save_height, save_progressive_seq; AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame? - int closed_gop; ///< GOP is closed + int tmpgexs; } Mpeg1Context; extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; diff --git a/libavcodec/mpeg12data.c b/libavcodec/mpeg12data.c index a0dd6e5784..309ec4efd6 100644 --- a/libavcodec/mpeg12data.c +++ b/libavcodec/mpeg12data.c @@ -3,20 +3,20 @@ * copyright (c) 2000,2001 Fabrice Bellard * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpeg12data.h b/libavcodec/mpeg12data.h index 86ba3ec15f..d4ef11e0c6 100644 --- a/libavcodec/mpeg12data.h +++ b/libavcodec/mpeg12data.h @@ -3,20 +3,20 @@ * copyright (c) 2000,2001 Fabrice Bellard * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpeg12decdata.h b/libavcodec/mpeg12decdata.h index 323a902336..66ca5c4971 100644 --- a/libavcodec/mpeg12decdata.h +++ b/libavcodec/mpeg12decdata.h @@ -3,20 +3,20 @@ * copyright (c) 2000,2001 Fabrice Bellard * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index 81d366d810..7a692342a8 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -33,9 +33,10 @@ #include "mpeg12.h" #include "mpeg12data.h" #include "bytestream.h" - #include "libavutil/log.h" #include "libavutil/opt.h" +#include "libavutil/avassert.h" +#include "libavutil/timecode.h" static const uint8_t inv_non_linear_qscale[13] = { 0, 2, 4, 6, 8, @@ -166,11 +167,24 @@ static av_cold int encode_init(AVCodecContext *avctx) } } + s->drop_frame_timecode = s->drop_frame_timecode || !!(avctx->flags2 & CODEC_FLAG2_DROP_FRAME_TIMECODE); + if (s->drop_frame_timecode) + s->tc.flags |= AV_TIMECODE_FLAG_DROPFRAME; if (s->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; } + if (s->tc_opt_str) { + AVRational rate = avpriv_frame_rate_tab[s->frame_rate_index]; + int ret = av_timecode_init_from_string(&s->tc, rate, s->tc_opt_str, s); + if (ret < 0) + return ret; + s->drop_frame_timecode = !!(s->tc.flags & AV_TIMECODE_FLAG_DROPFRAME); + s->avctx->timecode_frame_start = s->tc.start; + } else { + s->avctx->timecode_frame_start = 0; // default is -1 + } return 0; } @@ -284,13 +298,9 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) time_code = s->current_picture_ptr->f.coded_picture_number + s->avctx->timecode_frame_start; s->gop_picture_number = s->current_picture_ptr->f.coded_picture_number; - if (s->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); - } + av_assert0(s->drop_frame_timecode == !!(s->tc.flags & AV_TIMECODE_FLAG_DROPFRAME)); + if (s->drop_frame_timecode) + time_code = av_timecode_adjust_ntsc_framenum(time_code); 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); @@ -921,6 +931,8 @@ static void mpeg1_encode_block(MpegEncContext *s, #define OFFSET(x) offsetof(MpegEncContext, x) #define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM #define COMMON_OPTS\ + {AV_TIMECODE_OPTION(MpegEncContext, tc_opt_str, \ + AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)},\ { "intra_vlc", "Use MPEG-2 intra VLC table.", OFFSET(intra_vlc_format), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },\ { "drop_frame_timecode", "Timecode is in drop frame format.", OFFSET(drop_frame_timecode), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE}, \ { "scan_offset", "Reserve space for SVCD scan offset user data.", OFFSET(scan_offset), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE }, @@ -958,7 +970,7 @@ AVCodec ff_mpeg1video_encoder = { .close = MPV_encode_end, .supported_framerates= avpriv_frame_rate_tab+1, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .capabilities= CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, + .capabilities= CODEC_CAP_DELAY, .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), .priv_class = &mpeg1_class, }; diff --git a/libavcodec/mpeg4audio.c b/libavcodec/mpeg4audio.c index 0fb9b96c80..abd3fa4a9b 100644 --- a/libavcodec/mpeg4audio.c +++ b/libavcodec/mpeg4audio.c @@ -3,20 +3,20 @@ * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr> * Copyright (c) 2009 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -82,6 +82,9 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, GetBitContext gb; int specific_config_bitindex; + if(bit_size<=0) + return AVERROR_INVALIDDATA; + init_get_bits(&gb, buf, bit_size); c->object_type = get_object_type(&gb); c->sample_rate = get_sample_rate(&gb, &c->sampling_index); diff --git a/libavcodec/mpeg4audio.h b/libavcodec/mpeg4audio.h index 7560f3f4e4..21000a9acc 100644 --- a/libavcodec/mpeg4audio.h +++ b/libavcodec/mpeg4audio.h @@ -2,20 +2,20 @@ * MPEG-4 Audio common header * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpeg4data.h b/libavcodec/mpeg4data.h index 07cbeee18a..1f4e578ca1 100644 --- a/libavcodec/mpeg4data.h +++ b/libavcodec/mpeg4data.h @@ -3,20 +3,20 @@ * H263+ support * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpeg4video.c b/libavcodec/mpeg4video.c index d7c928df03..7444f26a9d 100644 --- a/libavcodec/mpeg4video.c +++ b/libavcodec/mpeg4video.c @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h index ba67c218fc..274ded9a1a 100644 --- a/libavcodec/mpeg4video.h +++ b/libavcodec/mpeg4video.h @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -174,7 +174,7 @@ static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *di }else{ level += pred; ret= level; - if(s->err_recognition&AV_EF_BITSTREAM){ + if(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)){ if(level<0){ av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y); return -1; diff --git a/libavcodec/mpeg4video_parser.c b/libavcodec/mpeg4video_parser.c index 89bbf3465d..3bd2b14291 100644 --- a/libavcodec/mpeg4video_parser.c +++ b/libavcodec/mpeg4video_parser.c @@ -3,23 +3,25 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define UNCHECKED_BITSTREAM_READER 1 + #include "parser.h" #include "mpegvideo.h" #include "mpeg4video.h" @@ -99,6 +101,7 @@ static av_cold int mpeg4video_parse_init(AVCodecParserContext *s) if (!pc->enc) return -1; pc->first_picture = 1; + pc->enc->quant_precision=5; pc->enc->slice_context_count = 1; return 0; } diff --git a/libavcodec/mpeg4video_parser.h b/libavcodec/mpeg4video_parser.h index 0f56e7fd9e..50f8b44403 100644 --- a/libavcodec/mpeg4video_parser.h +++ b/libavcodec/mpeg4video_parser.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index e15c348454..4312689393 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -3,23 +3,26 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define UNCHECKED_BITSTREAM_READER 1 + +#include "libavutil/opt.h" #include "mpegvideo.h" #include "mpeg4video.h" #include "h263.h" @@ -113,7 +116,7 @@ static inline int mpeg4_is_resync(MpegEncContext *s){ int bits_count= get_bits_count(&s->gb); int v= show_bits(&s->gb, 16); - if(s->workaround_bugs&FF_BUG_NO_PADDING){ + if(s->workaround_bugs&FF_BUG_NO_PADDING && !s->resync_marker){ return 0; } @@ -130,10 +133,11 @@ static inline int mpeg4_is_resync(MpegEncContext *s){ v|= 0x7F >> (7-(bits_count&7)); if(v==0x7F) - return 1; + return s->mb_num; }else{ if(v == ff_mpeg4_resync_prefix[bits_count&7]){ - int len; + int len, mb_num; + int mb_num_bits= av_log2(s->mb_num - 1) + 1; GetBitContext gb= s->gb; skip_bits(&s->gb, 1); @@ -143,16 +147,20 @@ static inline int mpeg4_is_resync(MpegEncContext *s){ if(get_bits1(&s->gb)) break; } + mb_num= get_bits(&s->gb, mb_num_bits); + if(!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits) + mb_num= -1; + s->gb= gb; if(len>=ff_mpeg4_get_video_packet_prefix_length(s)) - return 1; + return mb_num; } } return 0; } -static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb) +static int mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb) { int i; int a= 2<<s->sprite_warping_accuracy; @@ -168,6 +176,9 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb int h= s->height; int min_ab; + if(w<=0 || h<=0) + return -1; + for(i=0; i<s->num_sprite_warping_points; i++){ int length; int x=0, y=0; @@ -340,6 +351,7 @@ static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb } s->real_sprite_warping_points= s->num_sprite_warping_points; } + return 0; } /** @@ -373,16 +385,6 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s) av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num); return -1; } - if(s->pict_type == AV_PICTURE_TYPE_B){ - int mb_x = 0, mb_y = 0; - - while (s->next_picture.f.mbskip_table[s->mb_index2xy[mb_num]]) { - if (!mb_x) ff_thread_await_progress((AVFrame*)s->next_picture_ptr, mb_y++, 0); - mb_num++; - if (++mb_x == s->mb_width) mb_x = 0; - } - if(mb_num >= s->mb_num) return -1; // slice contains just skipped MBs which where already decoded - } s->mb_x= mb_num % s->mb_width; s->mb_y= mb_num / s->mb_width; @@ -413,7 +415,8 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s) skip_bits(&s->gb, 3); /* intra dc vlc threshold */ //FIXME don't just ignore everything if(s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ - mpeg4_decode_sprite_trajectory(s, &s->gb); + if(mpeg4_decode_sprite_trajectory(s, &s->gb) < 0) + return -1; av_log(s->avctx, AV_LOG_ERROR, "untested\n"); } @@ -520,7 +523,7 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) if (code > 8){ if(get_bits1(&s->gb)==0){ /* marker */ - if(s->err_recognition&AV_EF_BITSTREAM){ + if(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_COMPLIANT)){ av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n"); return -1; } @@ -990,11 +993,33 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, SKIP_COUNTER(re, &s->gb, 1+12+1); } +#if 0 + if(s->error_recognition >= FF_ER_COMPLIANT){ + const int abs_level= FFABS(level); + if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ + const int run1= run - rl->max_run[last][abs_level] - 1; + if(abs_level <= rl->max_level[last][run]){ + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); + return -1; + } + if(s->error_recognition > FF_ER_COMPLIANT){ + if(abs_level <= rl->max_level[last][run]*2){ + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n"); + return -1; + } + if(run1 >= 0 && abs_level <= rl->max_level[last][run1]){ + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n"); + return -1; + } + } + } + } +#endif if (level>0) level= level * qmul + qadd; else level= level * qmul - qadd; if((unsigned)(level + 2048) > 4095){ - if(s->err_recognition & AV_EF_BITSTREAM){ + if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)){ if(level > 2560 || level<-2560){ av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale); return -1; @@ -1466,16 +1491,21 @@ end: /* per-MB end of slice check */ if(s->codec_id==CODEC_ID_MPEG4){ - if(mpeg4_is_resync(s)){ - const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; + int next= mpeg4_is_resync(s); + if(next) { + if (s->mb_x + s->mb_y*s->mb_width + 1 > next && (s->avctx->err_recognition & AV_EF_AGGRESSIVE)) { + return -1; + } else if (s->mb_x + s->mb_y*s->mb_width + 1 >= next) + return SLICE_END; - if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) { + if(s->pict_type==AV_PICTURE_TYPE_B){ + const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; ff_thread_await_progress((AVFrame*)s->next_picture_ptr, (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0); + if (s->next_picture.f.mbskip_table[xy + delta]) + return SLICE_OK; } - if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) - return SLICE_OK; return SLICE_END; } } @@ -1486,35 +1516,36 @@ end: static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){ int hours, minutes, seconds; - unsigned time_code = show_bits(gb, 18); - - if (time_code & 0x40) { /* marker_bit */ - hours = time_code >> 13; - minutes = time_code >> 7 & 0x3f; - seconds = time_code & 0x3f; - s->time_base = seconds + 60*(minutes + 60*hours); - skip_bits(gb, 20); /* time_code, closed_gov, broken_link */ - } else { - av_log(s->avctx, AV_LOG_WARNING, "GOP header missing marker_bit\n"); + + if(!show_bits(gb, 23)){ + av_log(s->avctx, AV_LOG_WARNING, "GOP header invalid\n"); + return -1; } + hours= get_bits(gb, 5); + minutes= get_bits(gb, 6); + skip_bits1(gb); + seconds= get_bits(gb, 6); + + s->time_base= seconds + 60*(minutes + 60*hours); + + skip_bits1(gb); + skip_bits1(gb); + return 0; } static int mpeg4_decode_profile_level(MpegEncContext * s, GetBitContext *gb){ - int profile_and_level_indication; - - profile_and_level_indication = get_bits(gb, 8); - s->avctx->profile = (profile_and_level_indication & 0xf0) >> 4; - s->avctx->level = (profile_and_level_indication & 0x0f); + s->avctx->profile = get_bits(gb, 4); + s->avctx->level = get_bits(gb, 4); - // for Simple profile, level 0 - if (s->avctx->profile == 0 && s->avctx->level == 8) { - s->avctx->level = 0; - } + // for Simple profile, level 0 + if (s->avctx->profile == 0 && s->avctx->level == 8) { + s->avctx->level = 0; + } - return 0; + return 0; } static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ @@ -2025,7 +2056,8 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ } if(s->pict_type == AV_PICTURE_TYPE_S && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){ - mpeg4_decode_sprite_trajectory(s, gb); + if(mpeg4_decode_sprite_trajectory(s, gb) < 0) + return -1; if(s->sprite_brightness_change) av_log(s->avctx, AV_LOG_ERROR, "sprite_brightness_change not supported\n"); if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n"); } @@ -2115,8 +2147,8 @@ int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb) startcode = 0xff; for(;;) { if(get_bits_count(gb) >= gb->size_in_bits){ - if(gb->size_in_bits==8 && (s->divx_version>=0 || s->xvid_build>=0)){ - av_log(s->avctx, AV_LOG_WARNING, "frame skip %d\n", gb->size_in_bits); + if(gb->size_in_bits==8 && (s->divx_version>=0 || s->xvid_build>=0) || s->codec_tag == AV_RL32("QMP4")){ + av_log(s->avctx, AV_LOG_VERBOSE, "frame skip %d\n", gb->size_in_bits); return FRAME_SKIPPED; //divx bug }else return -1; //end of stream @@ -2253,6 +2285,26 @@ static const AVProfile mpeg4_video_profiles[] = { { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, "Advanced Simple Profile" }, }; +static const AVOption mpeg4_options[] = { + {"quarter_sample", "1/4 subpel MC", offsetof(MpegEncContext, quarter_sample), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 1, 0}, + {"divx_packed", "divx style packed b frames", offsetof(MpegEncContext, divx_packed), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 1, 0}, + {NULL} +}; + +static const AVClass mpeg4_class = { + "MPEG4 Video Decoder", + av_default_item_name, + mpeg4_options, + LIBAVUTIL_VERSION_INT, +}; + +static const AVClass mpeg4_vdpau_class = { + "MPEG4 Video VDPAU Decoder", + av_default_item_name, + mpeg4_options, + LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_mpeg4_decoder = { .name = "mpeg4", .type = AVMEDIA_TYPE_VIDEO, @@ -2267,7 +2319,8 @@ AVCodec ff_mpeg4_decoder = { .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), .pix_fmts= ff_hwaccel_pixfmt_list_420, .profiles = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles), - .update_thread_context= ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context) + .update_thread_context= ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context), + .priv_class = &mpeg4_class, }; @@ -2283,5 +2336,6 @@ AVCodec ff_mpeg4_vdpau_decoder = { .capabilities = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU, .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"), .pix_fmts= (const enum PixelFormat[]){PIX_FMT_VDPAU_MPEG4, PIX_FMT_NONE}, + .priv_class = &mpeg4_vdpau_class, }; #endif diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index 41c153d0b0..02fdf3eaca 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -627,8 +627,6 @@ void mpeg4_encode_mb(MpegEncContext * s, x= s->mb_x*16; y= s->mb_y*16; - if(x+16 > s->width) x= s->width-16; - if(y+16 > s->height) y= s->height-16; offset= x + y*s->linesize; p_pic = s->new_picture.f.data[0] + offset; @@ -645,7 +643,21 @@ void mpeg4_encode_mb(MpegEncContext * s, b_pic = pic->f.data[0] + offset; if (pic->f.type != FF_BUFFER_TYPE_SHARED) b_pic+= INPLACE_OFFSET; - diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); + + if(x+16 > s->width || y+16 > s->height){ + int x1,y1; + int xe= FFMIN(16, s->width - x); + int ye= FFMIN(16, s->height- y); + diff=0; + for(y1=0; y1<ye; y1++){ + for(x1=0; x1<xe; x1++){ + diff+= FFABS(p_pic[x1+y1*s->linesize] - b_pic[x1+y1*s->linesize]); + } + } + diff= diff*256/(xe*ye); + }else{ + diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); + } if(diff>s->qscale*70){ //FIXME check that 70 is optimal s->mb_skipped=0; break; @@ -846,7 +858,7 @@ void ff_set_mpeg4_time(MpegEncContext * s){ ff_mpeg4_init_direct_mv(s); }else{ s->last_time_base= s->time_base; - s->time_base= s->time/s->avctx->time_base.den; + s->time_base= FFUDIV(s->time, s->avctx->time_base.den); } } @@ -861,11 +873,12 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){ if(s->reordered_input_picture[1]) time = FFMIN(time, s->reordered_input_picture[1]->f.pts); time= time*s->avctx->time_base.num; + s->last_time_base= FFUDIV(time, s->avctx->time_base.den); - seconds= time/s->avctx->time_base.den; - minutes= seconds/60; seconds %= 60; - hours= minutes/60; minutes %= 60; - hours%=24; + seconds= FFUDIV(time, s->avctx->time_base.den); + minutes= FFUDIV(seconds, 60); seconds = FFUMOD(seconds, 60); + hours = FFUDIV(minutes, 60); minutes = FFUMOD(minutes, 60); + hours = FFUMOD(hours , 24); put_bits(&s->pb, 5, hours); put_bits(&s->pb, 6, minutes); @@ -875,8 +888,6 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){ put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP)); put_bits(&s->pb, 1, 0); //broken link == NO - s->last_time_base= time / s->avctx->time_base.den; - ff_mpeg4_stuffing(&s->pb); } @@ -1049,9 +1060,8 @@ void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 16, VOP_STARTCODE); /* vop header */ put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */ - assert(s->time>=0); - time_div= s->time/s->avctx->time_base.den; - time_mod= s->time%s->avctx->time_base.den; + time_div= FFUDIV(s->time, s->avctx->time_base.den); + time_mod= FFUMOD(s->time, s->avctx->time_base.den); time_incr= time_div - s->last_time_base; assert(time_incr >= 0); while(time_incr--) diff --git a/libavcodec/mpegaudio.c b/libavcodec/mpegaudio.c index 1a8363540e..cba52992ef 100644 --- a/libavcodec/mpegaudio.c +++ b/libavcodec/mpegaudio.c @@ -2,20 +2,20 @@ * MPEG Audio common code * Copyright (c) 2001, 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudio.h b/libavcodec/mpegaudio.h index b55680100b..b829cd3f8a 100644 --- a/libavcodec/mpegaudio.h +++ b/libavcodec/mpegaudio.h @@ -1,20 +1,20 @@ /* * copyright (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c index c6d670de2a..ec7e882c31 100644 --- a/libavcodec/mpegaudio_parser.c +++ b/libavcodec/mpegaudio_parser.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -66,7 +66,8 @@ static int mpegaudio_parse(AVCodecParserContext *s1, ret = avpriv_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate); if (ret < 4) { - s->header_count= -2; + if(i > 4) + s->header_count= -2; } else { if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) s->header_count= -3; diff --git a/libavcodec/mpegaudio_tablegen.c b/libavcodec/mpegaudio_tablegen.c index b4c240bd7c..90c9de430a 100644 --- a/libavcodec/mpegaudio_tablegen.c +++ b/libavcodec/mpegaudio_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudio_tablegen.h b/libavcodec/mpegaudio_tablegen.h index a222f2c423..291e40b9aa 100644 --- a/libavcodec/mpegaudio_tablegen.h +++ b/libavcodec/mpegaudio_tablegen.h @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudiodata.c b/libavcodec/mpegaudiodata.c index 81a43656a9..1267adca92 100644 --- a/libavcodec/mpegaudiodata.c +++ b/libavcodec/mpegaudiodata.c @@ -2,20 +2,20 @@ * MPEG Audio common tables * copyright (c) 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,11 +29,11 @@ const uint16_t avpriv_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} + {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} } }; diff --git a/libavcodec/mpegaudiodata.h b/libavcodec/mpegaudiodata.h index 24ea536a6c..71645a668d 100644 --- a/libavcodec/mpegaudiodata.h +++ b/libavcodec/mpegaudiodata.h @@ -2,20 +2,20 @@ * MPEG Audio common tables * copyright (c) 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index af125d5587..2ca30f2702 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -2,20 +2,20 @@ * MPEG Audio decoder * Copyright (c) 2001, 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -24,6 +24,8 @@ * MPEG Audio decoder */ +#define UNCHECKED_BITSTREAM_READER 1 + #include "libavutil/audioconvert.h" #include "avcodec.h" #include "get_bits.h" @@ -955,7 +957,7 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, s_index -= 4; skip_bits_long(&s->gb, last_pos - pos); av_log(s->avctx, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos); - if(s->err_recognition & AV_EF_BITSTREAM) + if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)) s_index=0; break; } @@ -985,10 +987,10 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, /* skip extension bits */ bits_left = end_pos2 - get_bits_count(&s->gb); //av_log(NULL, AV_LOG_ERROR, "left:%d buf:%p\n", bits_left, s->in_gb.buffer); - if (bits_left < 0 && (s->err_recognition & AV_EF_BUFFER)) { + if (bits_left < 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_COMPLIANT))) { av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left); s_index=0; - } else if (bits_left > 0 && (s->err_recognition & AV_EF_BUFFER)) { + } else if (bits_left > 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_AGGRESSIVE))) { av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left); s_index = 0; } @@ -1376,7 +1378,6 @@ static int mp_decode_layer3(MPADecodeContext *s) } if (!s->adu_mode) { - int skip; const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, EXTRABYTES); assert((get_bits_count(&s->gb) & 7) == 0); @@ -1390,29 +1391,25 @@ static int mp_decode_layer3(MPADecodeContext *s) #if !UNCHECKED_BITSTREAM_READER s->gb.size_in_bits_plus8 += extrasize * 8; #endif - s->last_buf_size <<= 3; - for (gr = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++) { - for (ch = 0; ch < s->nb_channels; ch++) { - g = &s->granules[ch][gr]; - s->last_buf_size += g->part2_3_length; - memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid)); - } - } - skip = s->last_buf_size - 8 * main_data_begin; - if (skip >= s->gb.size_in_bits && s->in_gb.buffer) { - skip_bits_long(&s->in_gb, skip - s->gb.size_in_bits); - s->gb = s->in_gb; - s->in_gb.buffer = NULL; - } else { - skip_bits_long(&s->gb, skip); - } - } else { - gr = 0; + skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin)); } - for (; gr < nb_granules; gr++) { + for (gr = 0; gr < nb_granules; gr++) { for (ch = 0; ch < s->nb_channels; ch++) { g = &s->granules[ch][gr]; + if (get_bits_count(&s->gb) < 0) { + av_log(s->avctx, AV_LOG_DEBUG, "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)); + if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) { + skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits); + s->gb = s->in_gb; + s->in_gb.buffer = NULL; + } + continue; + } + bits_pos = get_bits_count(&s->gb); if (!s->lsf) { @@ -1656,8 +1653,8 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, if (s->frame_size <= 0 || s->frame_size > buf_size) { av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); return AVERROR_INVALIDDATA; - } else if (s->frame_size < buf_size) { - av_log(avctx, AV_LOG_ERROR, "incorrect frame size\n"); + }else if(s->frame_size < buf_size){ + av_log(avctx, AV_LOG_DEBUG, "incorrect frame size - multiple frames in buffer?\n"); buf_size= s->frame_size; } diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c index dd37bbc26c..083bd97f5a 100644 --- a/libavcodec/mpegaudiodec_float.c +++ b/libavcodec/mpegaudiodec_float.c @@ -2,20 +2,20 @@ * Float MPEG Audio decoder * Copyright (c) 2010 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudiodecheader.c b/libavcodec/mpegaudiodecheader.c index dbd67ff0e3..24919ab544 100644 --- a/libavcodec/mpegaudiodecheader.c +++ b/libavcodec/mpegaudiodecheader.c @@ -2,20 +2,20 @@ * MPEG Audio header decoder * Copyright (c) 2001, 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudiodecheader.h b/libavcodec/mpegaudiodecheader.h index 764e8abde4..c434d00441 100644 --- a/libavcodec/mpegaudiodecheader.h +++ b/libavcodec/mpegaudiodecheader.h @@ -2,20 +2,20 @@ * MPEG Audio header decoder * Copyright (c) 2001, 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudiodectab.h b/libavcodec/mpegaudiodectab.h index 1221657988..accd12b8e2 100644 --- a/libavcodec/mpegaudiodectab.h +++ b/libavcodec/mpegaudiodectab.h @@ -2,20 +2,20 @@ * MPEG Audio decoder * copyright (c) 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudiodsp.c b/libavcodec/mpegaudiodsp.c index 431724a71c..cc12dd9cee 100644 --- a/libavcodec/mpegaudiodsp.c +++ b/libavcodec/mpegaudiodsp.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2011 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudiodsp.h b/libavcodec/mpegaudiodsp.h index c24ea4117e..da53fe56e8 100644 --- a/libavcodec/mpegaudiodsp.h +++ b/libavcodec/mpegaudiodsp.h @@ -29,6 +29,7 @@ typedef struct MPADSPContext { int *dither_state, int16_t *samples, int incr); void (*dct32_float)(float *dst, const float *src); void (*dct32_fixed)(int *dst, const int *src); + void (*imdct36_blocks_float)(float *out, float *buf, float *in, int count, int switch_point, int block_type); void (*imdct36_blocks_fixed)(int *out, int *buf, int *in, diff --git a/libavcodec/mpegaudiodsp_template.c b/libavcodec/mpegaudiodsp_template.c index d616f8aec9..53b6139da3 100644 --- a/libavcodec/mpegaudiodsp_template.c +++ b/libavcodec/mpegaudiodsp_template.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2001, 2002 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -398,3 +398,4 @@ void RENAME(ff_imdct36_blocks)(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, out++; } } + diff --git a/libavcodec/mpegaudioenc.c b/libavcodec/mpegaudioenc.c index 71ea39373e..6b71d01ae9 100644 --- a/libavcodec/mpegaudioenc.c +++ b/libavcodec/mpegaudioenc.c @@ -2,20 +2,20 @@ * The simplest mpeg audio layer 2 encoder * Copyright (c) 2000, 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegaudiotab.h b/libavcodec/mpegaudiotab.h index 45afe9bd16..35129e646c 100644 --- a/libavcodec/mpegaudiotab.h +++ b/libavcodec/mpegaudiotab.h @@ -4,20 +4,20 @@ * * Copyright (c) 2000, 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index d1c06c0b01..1befe7f492 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -5,20 +5,20 @@ * * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -529,7 +529,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, { MpegEncContext *s = dst->priv_data, *s1 = src->priv_data; - if (dst == src || !s1->context_initialized) + if (dst == src) return 0; // FIXME can parameters change on I-frames? @@ -538,12 +538,14 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, memcpy(s, s1, sizeof(MpegEncContext)); s->avctx = dst; - s->picture_range_start += MAX_PICTURE_COUNT; - s->picture_range_end += MAX_PICTURE_COUNT; s->bitstream_buffer = NULL; s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0; - MPV_common_init(s); + if (s1->context_initialized){ + s->picture_range_start += MAX_PICTURE_COUNT; + s->picture_range_end += MAX_PICTURE_COUNT; + MPV_common_init(s); + } } s->avctx->coded_height = s1->avctx->coded_height; @@ -566,6 +568,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, // Error/bug resilience s->next_p_frame_damaged = s1->next_p_frame_damaged; s->workaround_bugs = s1->workaround_bugs; + s->padding_bug_score = s1->padding_bug_score; // MPEG4 timing info memcpy(&s->time_increment_bits, &s1->time_increment_bits, @@ -694,110 +697,83 @@ av_cold int MPV_common_init(MpegEncContext *s) s->flags = s->avctx->flags; s->flags2 = s->avctx->flags2; - if (s->width && s->height) { - s->mb_width = (s->width + 15) / 16; - s->mb_stride = s->mb_width + 1; - s->b8_stride = s->mb_width * 2 + 1; - s->b4_stride = s->mb_width * 4 + 1; - mb_array_size = s->mb_height * s->mb_stride; - mv_table_size = (s->mb_height + 2) * s->mb_stride + 1; + s->mb_width = (s->width + 15) / 16; + s->mb_stride = s->mb_width + 1; + s->b8_stride = s->mb_width * 2 + 1; + s->b4_stride = s->mb_width * 4 + 1; + mb_array_size = s->mb_height * s->mb_stride; + mv_table_size = (s->mb_height + 2) * s->mb_stride + 1; /* set chroma shifts */ avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift); - /* set default edge pos, will be overriden - * in decode_header if needed */ - s->h_edge_pos = s->mb_width * 16; - s->v_edge_pos = s->mb_height * 16; + /* set default edge pos, will be overriden in decode_header if needed */ + s->h_edge_pos = s->mb_width * 16; + s->v_edge_pos = s->mb_height * 16; - s->mb_num = s->mb_width * s->mb_height; + s->mb_num = s->mb_width * s->mb_height; - s->block_wrap[0] = - s->block_wrap[1] = - s->block_wrap[2] = - s->block_wrap[3] = s->b8_stride; - s->block_wrap[4] = - s->block_wrap[5] = s->mb_stride; + s->block_wrap[0] = + s->block_wrap[1] = + s->block_wrap[2] = + s->block_wrap[3] = s->b8_stride; + s->block_wrap[4] = + s->block_wrap[5] = s->mb_stride; - y_size = s->b8_stride * (2 * s->mb_height + 1); - c_size = s->mb_stride * (s->mb_height + 1); - yc_size = y_size + 2 * c_size; + y_size = s->b8_stride * (2 * s->mb_height + 1); + c_size = s->mb_stride * (s->mb_height + 1); + yc_size = y_size + 2 * c_size; - /* convert fourcc to upper case */ - s->codec_tag = avpriv_toupper4(s->avctx->codec_tag); + /* convert fourcc to upper case */ + s->codec_tag = avpriv_toupper4(s->avctx->codec_tag); + s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag); - s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag); + s->avctx->coded_frame = (AVFrame*)&s->current_picture; - s->avctx->coded_frame = (AVFrame *)&s->current_picture; + FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int), fail); // error ressilience code looks cleaner with this + for (y = 0; y < s->mb_height; y++) + for (x = 0; x < s->mb_width; x++) + s->mb_index2xy[x + y * s->mb_width] = x + y * s->mb_stride; - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int), - fail); // error ressilience code looks cleaner with this - for (y = 0; y < s->mb_height; y++) - for (x = 0; x < s->mb_width; x++) - s->mb_index2xy[x + y * s->mb_width] = x + y * s->mb_stride; + s->mb_index2xy[s->mb_height * s->mb_width] = (s->mb_height - 1) * s->mb_stride + s->mb_width; // FIXME really needed? - s->mb_index2xy[s->mb_height * s->mb_width] = - (s->mb_height - 1) * s->mb_stride + s->mb_width; // FIXME really needed? + if (s->encoding) { + /* Allocate MV tables */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base , mv_table_size * 2 * sizeof(int16_t), fail) + s->p_mv_table = s->p_mv_table_base + s->mb_stride + 1; + s->b_forw_mv_table = s->b_forw_mv_table_base + s->mb_stride + 1; + s->b_back_mv_table = s->b_back_mv_table_base + s->mb_stride + 1; + s->b_bidir_forw_mv_table= s->b_bidir_forw_mv_table_base + s->mb_stride + 1; + s->b_bidir_back_mv_table= s->b_bidir_back_mv_table_base + s->mb_stride + 1; + s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1; - if (s->encoding) { - /* Allocate MV tables */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base, - mv_table_size * 2 * sizeof(int16_t), fail); - s->p_mv_table = s->p_mv_table_base + - s->mb_stride + 1; - s->b_forw_mv_table = s->b_forw_mv_table_base + - s->mb_stride + 1; - s->b_back_mv_table = s->b_back_mv_table_base + - s->mb_stride + 1; - s->b_bidir_forw_mv_table = s->b_bidir_forw_mv_table_base + - s->mb_stride + 1; - s->b_bidir_back_mv_table = s->b_bidir_back_mv_table_base + - s->mb_stride + 1; - s->b_direct_mv_table = s->b_direct_mv_table_base + - s->mb_stride + 1; - - if (s->msmpeg4_version) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats, - 2 * 2 * (MAX_LEVEL + 1) * - (MAX_RUN + 1) * 2 * sizeof(int), fail); - } - FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail); - - /* Allocate MB type table */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type, mb_array_size * - sizeof(uint16_t), fail); // needed for encoding - - FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * - sizeof(int), fail); - - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix, - 64 * 32 * sizeof(int), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix, - 64 * 32 * sizeof(int), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, - 64 * 32 * 2 * sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, - 64 * 32 * 2 * sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, - MAX_PICTURE_COUNT * sizeof(Picture *), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, - MAX_PICTURE_COUNT * sizeof(Picture *), fail); - - if (s->avctx->noise_reduction) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, - 2 * 64 * sizeof(uint16_t), fail); - } + if(s->msmpeg4_version){ + FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats, 2*2*(MAX_LEVEL+1)*(MAX_RUN+1)*2*sizeof(int), fail); + } + FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail); + + /* Allocate MB type table */ + FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type , mb_array_size * sizeof(uint16_t), fail) //needed for encoding + + FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail) + + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix , 64*32 * sizeof(int), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix , 64*32 * sizeof(int), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix , 64*32 * sizeof(int), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16 , 64*32*2 * sizeof(uint16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix16, 64*32*2 * sizeof(uint16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16 , 64*32*2 * sizeof(uint16_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture*), fail) + + if(s->avctx->noise_reduction){ + FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, 2 * 64 * sizeof(uint16_t), fail) } } @@ -808,36 +784,22 @@ av_cold int MPV_common_init(MpegEncContext *s) avcodec_get_frame_defaults((AVFrame *) &s->picture[i]); } - if (s->width && s->height) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table, - mb_array_size * sizeof(uint8_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table, mb_array_size*sizeof(uint8_t), fail) - if (s->codec_id == CODEC_ID_MPEG4 || - (s->flags & CODEC_FLAG_INTERLACED_ME)) { + if(s->codec_id==CODEC_ID_MPEG4 || (s->flags & CODEC_FLAG_INTERLACED_ME)){ /* interlaced direct mode decoding tables */ for (i = 0; i < 2; i++) { int j, k; for (j = 0; j < 2; j++) { for (k = 0; k < 2; k++) { - FF_ALLOCZ_OR_GOTO(s->avctx, - s->b_field_mv_table_base[i][j][k], - mv_table_size * 2 * sizeof(int16_t), - fail); - s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + - s->mb_stride + 1; + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_mv_table_base[i][j][k], mv_table_size * 2 * sizeof(int16_t), fail) + s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + s->mb_stride + 1; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], - mb_array_size * 2 * sizeof(uint8_t), - fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], - mv_table_size * 2 * sizeof(int16_t), - fail); - s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] - + s->mb_stride + 1; + FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], mb_array_size * 2 * sizeof(uint8_t), fail) + FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], mv_table_size * 2 * sizeof(int16_t), fail) + s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + s->mb_stride + 1; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], - mb_array_size * 2 * sizeof(uint8_t), - fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], mb_array_size * 2 * sizeof(uint8_t), fail) } } if (s->out_format == FMT_H263) { @@ -846,17 +808,14 @@ av_cold int MPV_common_init(MpegEncContext *s) s->coded_block = s->coded_block_base + s->b8_stride + 1; /* cbp, ac_pred, pred_dir */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table, - mb_array_size * sizeof(uint8_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, - mb_array_size * sizeof(uint8_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table , mb_array_size * sizeof(uint8_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size * sizeof(uint8_t), fail); } if (s->h263_pred || s->h263_plus || !s->encoding) { /* dc values */ // MN: we need these for error resilience of intra-frames - FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, - yc_size * sizeof(int16_t), fail); + FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail); s->dc_val[0] = s->dc_val_base + s->b8_stride + 1; s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1; s->dc_val[2] = s->dc_val[1] + c_size; @@ -873,21 +832,11 @@ av_cold int MPV_common_init(MpegEncContext *s) // Note the + 1 is for a quicker mpeg4 slice_end detection s->parse_context.state = -1; - if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || - s->avctx->debug_mv) { - s->visualization_buffer[0] = av_malloc((s->mb_width * 16 + - 2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH); - s->visualization_buffer[1] = av_malloc((s->mb_width * 16 + - 2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH); - s->visualization_buffer[2] = av_malloc((s->mb_width * 16 + - 2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH); - } - } - s->context_initialized = 1; - s->thread_context[0] = s; + s->context_initialized = 1; + s->thread_context[0] = s; - if (s->width && s->height) { +// if (s->width && s->height) { if (nb_slices > 1) { for (i = 1; i < nb_slices; i++) { s->thread_context[i] = av_malloc(sizeof(MpegEncContext)); @@ -909,7 +858,7 @@ av_cold int MPV_common_init(MpegEncContext *s) s->end_mb_y = s->mb_height; } s->slice_context_count = nb_slices; - } +// } return 0; fail: @@ -976,6 +925,10 @@ void MPV_common_end(MpegEncContext *s) av_freep(&s->error_status_table); av_freep(&s->mb_index2xy); av_freep(&s->lambda_table); + if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix); + if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16); + s->q_chroma_intra_matrix= NULL; + s->q_chroma_intra_matrix16= NULL; av_freep(&s->q_intra_matrix); av_freep(&s->q_inter_matrix); av_freep(&s->q_intra_matrix16); @@ -1130,7 +1083,21 @@ int ff_find_unused_picture(MpegEncContext *s, int shared) } } - return AVERROR_INVALIDDATA; + 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; } static void update_noise_reduction(MpegEncContext *s) @@ -1203,6 +1170,8 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) pic = s->current_picture_ptr; } else { i = ff_find_unused_picture(s, 0); + if (i < 0) + return i; pic = &s->picture[i]; } @@ -1266,9 +1235,18 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) /* Allocate a dummy frame */ i = ff_find_unused_picture(s, 0); - s->last_picture_ptr = &s->picture[i]; + if (i < 0) + return i; + s->last_picture_ptr= &s->picture[i]; + s->last_picture_ptr->f.key_frame = 0; if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) return -1; + + if(s->codec_id == CODEC_ID_FLV1 || s->codec_id == CODEC_ID_H263){ + for(i=0; i<avctx->height; i++) + memset(s->last_picture_ptr->f.data[0] + s->last_picture_ptr->f.linesize[0]*i, 16, avctx->width); + } + ff_thread_report_progress((AVFrame *) s->last_picture_ptr, INT_MAX, 0); ff_thread_report_progress((AVFrame *) s->last_picture_ptr, @@ -1279,7 +1257,10 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->pict_type == AV_PICTURE_TYPE_B) { /* Allocate a dummy frame */ i = ff_find_unused_picture(s, 0); - s->next_picture_ptr = &s->picture[i]; + if (i < 0) + return i; + s->next_picture_ptr= &s->picture[i]; + s->next_picture_ptr->f.key_frame = 0; if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) return -1; ff_thread_report_progress((AVFrame *) s->next_picture_ptr, @@ -1354,7 +1335,7 @@ void MPV_frame_end(MpegEncContext *s) // just to make sure that all data is rendered. if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) { ff_xvmc_field_end(s); - } else if ((s->error_count || s->encoding) && + } else if((s->error_count || s->encoding || !(s->avctx->codec->capabilities&CODEC_CAP_DRAW_HORIZ_BAND)) && !s->avctx->hwaccel && !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) && s->unrestricted_mv && @@ -1363,15 +1344,15 @@ void MPV_frame_end(MpegEncContext *s) !(s->flags & CODEC_FLAG_EMU_EDGE)) { int hshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_w; int vshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_h; - s->dsp.draw_edges(s->current_picture.f.data[0], s->linesize, + s->dsp.draw_edges(s->current_picture.f.data[0], s->current_picture.f.linesize[0], s->h_edge_pos, s->v_edge_pos, EDGE_WIDTH, EDGE_WIDTH, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(s->current_picture.f.data[1], s->uvlinesize, + s->dsp.draw_edges(s->current_picture.f.data[1], s->current_picture.f.linesize[1], s->h_edge_pos >> hshift, s->v_edge_pos >> vshift, EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(s->current_picture.f.data[2], s->uvlinesize, + s->dsp.draw_edges(s->current_picture.f.data[2], s->current_picture.f.linesize[2], s->h_edge_pos >> hshift, s->v_edge_pos >> vshift, EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, EDGE_TOP | EDGE_BOTTOM); @@ -1445,7 +1426,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, buf += sx + sy * stride; ex -= sx; f = ((ey - sy) << 16) / ex; - for (x = 0; x = ex; x++) { + for(x= 0; x <= ex; x++){ y = (x * f) >> 16; fr = (x * f) & 0xFFFF; buf[y * stride + x] += (color * (0x10000 - fr)) >> 16; @@ -1459,12 +1440,12 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, buf += sx + sy * stride; ey -= sy; if (ey) - f = ((ex - sx) << 16) / ey; + f = ((ex - sx) << 16) / ey; else f = 0; - for (y = 0; y = ey; y++) { - x = (y * f) >> 16; - fr = (y * f) & 0xFFFF; + 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; } @@ -1517,27 +1498,8 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) if (s->avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) { int x,y; - av_log(s->avctx,AV_LOG_DEBUG,"New frame, type: "); - switch (pict->pict_type) { - case AV_PICTURE_TYPE_I: - av_log(s->avctx,AV_LOG_DEBUG,"I\n"); - break; - case AV_PICTURE_TYPE_P: - av_log(s->avctx,AV_LOG_DEBUG,"P\n"); - break; - case AV_PICTURE_TYPE_B: - av_log(s->avctx,AV_LOG_DEBUG,"B\n"); - break; - case AV_PICTURE_TYPE_S: - av_log(s->avctx,AV_LOG_DEBUG,"S\n"); - break; - case AV_PICTURE_TYPE_SI: - av_log(s->avctx,AV_LOG_DEBUG,"SI\n"); - break; - case AV_PICTURE_TYPE_SP: - av_log(s->avctx,AV_LOG_DEBUG,"SP\n"); - break; - } + av_log(s->avctx, AV_LOG_DEBUG, "New frame, type: %c\n", + av_get_picture_type_char(pict->pict_type)); for (y = 0; y < s->mb_height; y++) { for (x = 0; x < s->mb_width; x++) { if (s->avctx->debug & FF_DEBUG_SKIP) { @@ -1621,12 +1583,14 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); for (i = 0; i < 3; i++) { - memcpy(s->visualization_buffer[i], pict->data[i], - (i == 0) ? pict->linesize[i] * height: - pict->linesize[i] * height >> v_chroma_shift); + size_t size= (i == 0) ? pict->linesize[i] * height: + pict->linesize[i] * height >> v_chroma_shift; + s->visualization_buffer[i]= av_realloc(s->visualization_buffer[i], size); + memcpy(s->visualization_buffer[i], pict->data[i], size); pict->data[i] = s->visualization_buffer[i]; } pict->type = FF_BUFFER_TYPE_COPY; + pict->opaque= NULL; ptr = pict->data[0]; block_height = 16 >> v_chroma_shift; @@ -1704,11 +1668,11 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) height, s->linesize, 100); } } else { - int sx = mb_x * 16 + 8; - int sy = mb_y * 16 + 8; - int xy = (mb_x + mb_y * mv_stride) << mv_sample_log2; - int mx = pict->motion_val[direction][xy][0] >> shift + sx; - int my = pict->motion_val[direction][xy][1] >> shift + sy; + int sx= mb_x * 16 + 8; + int sy= mb_y * 16 + 8; + int xy= (mb_x + mb_y * mv_stride) << mv_sample_log2; + int mx= (pict->motion_val[direction][xy][0]>>shift) + sx; + int my= (pict->motion_val[direction][xy][1]>>shift) + sy; draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100); } } @@ -1877,7 +1841,7 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy, uvsx, uvsy; const int lowres = s->avctx->lowres; - const int op_index = FFMIN(lowres, 2); + const int op_index = FFMIN(lowres-1+s->chroma_x_shift, 2); const int block_s = 8>>lowres; const int s_mask = (2 << lowres) - 1; const int h_edge_pos = s->h_edge_pos >> lowres; @@ -1891,8 +1855,8 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, motion_y /= 2; } - if (field_based) { - motion_y += (bottom_field - field_select) * (1 << lowres - 1); + if(field_based){ + motion_y += (bottom_field - field_select)*((1 << lowres)-1); } sx = motion_x & s_mask; @@ -1914,12 +1878,29 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, uvsrc_x = s->mb_x * block_s + (mx >> lowres); uvsrc_y = mb_y * block_s + (my >> lowres); } else { - mx = motion_x / 2; - my = motion_y / 2; - uvsx = mx & s_mask; - uvsy = my & s_mask; - uvsrc_x = s->mb_x * block_s + (mx >> lowres + 1); - uvsrc_y = (mb_y * block_s >> field_based) + (my >> lowres + 1); + if(s->chroma_y_shift){ + mx = motion_x / 2; + my = motion_y / 2; + uvsx = mx & s_mask; + uvsy = my & s_mask; + uvsrc_x = s->mb_x * block_s + (mx >> lowres + 1); + uvsrc_y = (mb_y * block_s >> field_based) + (my >> lowres + 1); + } else { + if(s->chroma_x_shift){ + //Chroma422 + mx = motion_x / 2; + uvsx = mx & s_mask; + uvsy = motion_y & s_mask; + uvsrc_y = src_y; + uvsrc_x = s->mb_x*block_s + (mx >> (lowres+1)); + } else { + //Chroma444 + uvsx = motion_x & s_mask; + uvsy = motion_y & s_mask; + uvsrc_x = src_x; + uvsrc_y = src_y; + } + } } ptr_y = ref_picture[0] + src_y * linesize + src_x; @@ -1968,10 +1949,10 @@ static av_always_inline void mpeg_motion_lowres(MpegEncContext *s, if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) { uvsx = (uvsx << 2) >> lowres; uvsy = (uvsy << 2) >> lowres; - pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, - uvsx, uvsy); - pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, - uvsx, uvsy); + if (h >> s->chroma_y_shift) { + pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy); + pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy); + } } // FIXME h261 lowres loop filter } @@ -2442,17 +2423,17 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], }else{ //chroma422 dct_linesize = uvlinesize << s->interlaced_dct; - dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize * 8; + dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; add_dct(s, block[4], 4, dest_cb, dct_linesize); add_dct(s, block[5], 5, dest_cr, dct_linesize); add_dct(s, block[6], 6, dest_cb+dct_offset, dct_linesize); add_dct(s, block[7], 7, dest_cr+dct_offset, dct_linesize); if(!s->chroma_x_shift){//Chroma444 - add_dct(s, block[8], 8, dest_cb+8, dct_linesize); - add_dct(s, block[9], 9, dest_cr+8, dct_linesize); - add_dct(s, block[10], 10, dest_cb+8+dct_offset, dct_linesize); - add_dct(s, block[11], 11, dest_cr+8+dct_offset, dct_linesize); + add_dct(s, block[8], 8, dest_cb+block_size, dct_linesize); + add_dct(s, block[9], 9, dest_cr+block_size, dct_linesize); + add_dct(s, block[10], 10, dest_cb+block_size+dct_offset, dct_linesize); + add_dct(s, block[11], 11, dest_cr+block_size+dct_offset, dct_linesize); } } }//fi gray @@ -2494,17 +2475,17 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], }else{ dct_linesize = uvlinesize << s->interlaced_dct; - dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize * 8; + dct_offset = s->interlaced_dct? uvlinesize : uvlinesize*block_size; s->dsp.idct_put(dest_cb, dct_linesize, block[4]); s->dsp.idct_put(dest_cr, dct_linesize, block[5]); s->dsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]); s->dsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]); if(!s->chroma_x_shift){//Chroma444 - s->dsp.idct_put(dest_cb + 8, dct_linesize, block[8]); - s->dsp.idct_put(dest_cr + 8, dct_linesize, block[9]); - s->dsp.idct_put(dest_cb + 8 + dct_offset, dct_linesize, block[10]); - s->dsp.idct_put(dest_cr + 8 + dct_offset, dct_linesize, block[11]); + s->dsp.idct_put(dest_cb + block_size, dct_linesize, block[8]); + s->dsp.idct_put(dest_cr + block_size, dct_linesize, block[9]); + s->dsp.idct_put(dest_cb + block_size + dct_offset, dct_linesize, block[10]); + s->dsp.idct_put(dest_cr + block_size + dct_offset, dct_linesize, block[11]); } } }//gray @@ -2647,6 +2628,7 @@ void ff_mpeg_flush(AVCodecContext *avctx){ s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL; s->mb_x= s->mb_y= 0; + s->closed_gop= 0; s->parse_context.state= -1; s->parse_context.frame_start_found= 0; diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 3d3b237898..eb785cd84f 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -36,6 +36,7 @@ #include "parser.h" #include "mpeg12data.h" #include "rl.h" +#include "libavutil/timecode.h" #define FRAME_SKIPPED 100 ///< return value for header parsers if frame is not coded @@ -124,10 +125,11 @@ typedef struct Picture{ 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][2][16]; ///< h264 POCs of the frames used as reference (FIXME need per slice) + int ref_poc[2][2][32]; ///< h264 POCs of the frames/fields used as reference (FIXME need per slice) int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice) int mbaff; ///< h264 1 -> MBAFF frame 0-> not MBAFF - int field_picture; ///< whether or not the picture was encoded in separate fields + int field_picture; ///< whether or not the picture was encoded in seperate fields + int sync; ///< has been decoded after a keyframe int mb_var_sum; ///< sum of MB variance for current frame int mc_mb_var_sum; ///< motion compensated MB variance for current frame @@ -328,6 +330,7 @@ typedef struct MpegEncContext { int *lambda_table; int adaptive_quant; ///< use adaptive quantization int dquant; ///< qscale difference to prev qscale + int closed_gop; ///< MPEG1/2 GOP is closed int pict_type; ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ... int last_pict_type; //FIXME removes int last_non_b_pict_type; ///< used for mpeg4 gmc b-frames & ratecontrol @@ -439,9 +442,11 @@ typedef struct MpegEncContext { /** precomputed matrix (combine qscale and DCT renorm) */ int (*q_intra_matrix)[64]; + int (*q_chroma_intra_matrix)[64]; int (*q_inter_matrix)[64]; /** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/ uint16_t (*q_intra_matrix16)[2][64]; + uint16_t (*q_chroma_intra_matrix16)[2][64]; uint16_t (*q_inter_matrix16)[2][64]; /* noise reduction */ @@ -644,6 +649,9 @@ typedef struct MpegEncContext { /* RTP specific */ int rtp_mode; + char *tc_opt_str; ///< timecode option string + AVTimecode tc; ///< timecode context + uint8_t *ptr_lastgob; int swap_uv; //vcr2 codec is an MPEG-2 variant with U and V swapped DCTELEM (*pblocks[12])[64]; diff --git a/libavcodec/mpegvideo_common.h b/libavcodec/mpegvideo_common.h index 9f6307ea7c..2b2e34ffa9 100644 --- a/libavcodec/mpegvideo_common.h +++ b/libavcodec/mpegvideo_common.h @@ -5,20 +5,20 @@ * * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -725,7 +725,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, 0, 0, 0, ref_picture, pix_op, qpix_op, s->mv[dir][0][0], s->mv[dir][0][1], 16); - }else if(!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && s->mspel){ + }else if(!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && s->mspel && s->codec_id == CODEC_ID_WMV2){ 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); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 2e0e9820f9..a3ec5c18a1 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -5,20 +5,20 @@ * * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -44,6 +44,7 @@ #include "mpeg4video.h" #include "internal.h" #include <limits.h> +#include "sp5x.h" //#undef NDEBUG //#include <assert.h> @@ -103,8 +104,7 @@ void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], * 3444240 >= (1 << 36) / (x) >= 275 */ qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) / - (ff_aanscales[i] * qscale * - quant_matrix[j])); + (ff_aanscales[i] * qscale * quant_matrix[j])); } } else { for (i = 0; i < 64; i++) { @@ -295,7 +295,9 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) if (avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P && avctx->pix_fmt != PIX_FMT_YUVJ444P && + avctx->pix_fmt != PIX_FMT_BGR0 && avctx->pix_fmt != PIX_FMT_BGRA && + avctx->pix_fmt != PIX_FMT_BGR24 && ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P && avctx->pix_fmt != PIX_FMT_YUV444P) || @@ -305,6 +307,7 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) } break; case CODEC_ID_MJPEG: + case CODEC_ID_AMV: if (avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P && ((avctx->pix_fmt != PIX_FMT_YUV420P && @@ -338,8 +341,9 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) 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"); + av_log(avctx, AV_LOG_WARNING, + "keyframe interval too large!, reducing it from %d to %d\n", + avctx->gop_size, 600); avctx->gop_size = 600; } s->gop_size = avctx->gop_size; @@ -380,10 +384,8 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) s->loop_filter = !!(s->flags & CODEC_FLAG_LOOP_FILTER); - 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"); + if ((!avctx->rc_max_rate) != (!avctx->rc_buffer_size)) { + av_log(avctx, AV_LOG_ERROR, "Either both buffer size and max rate or neither must be specified\n"); return -1; } @@ -398,7 +400,7 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) } if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) { - av_log(avctx, AV_LOG_INFO, "bitrate above max bitrate\n"); + av_log(avctx, AV_LOG_ERROR, "bitrate above max bitrate\n"); return -1; } @@ -466,10 +468,11 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) s->codec_id == CODEC_ID_H263P) && (avctx->sample_aspect_ratio.num > 255 || avctx->sample_aspect_ratio.den > 255)) { - av_log(avctx, AV_LOG_ERROR, - "Invalid pixel aspect ratio %i/%i, limit is 255/255\n", + av_log(avctx, AV_LOG_WARNING, + "Invalid pixel aspect ratio %i/%i, limit is 255/255 reducing\n", avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); - return -1; + av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den, + avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 255); } if ((s->flags & (CODEC_FLAG_INTERLACED_DCT | CODEC_FLAG_INTERLACED_ME)) && @@ -537,7 +540,7 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) if (s->avctx->thread_count < 1) { av_log(avctx, AV_LOG_ERROR, - "automatic thread number detection not supported by codec," + "automatic thread number detection not supported by codec, " "patch welcome\n"); return -1; } @@ -576,8 +579,7 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) //return -1; } - if (s->mpeg_quant || s->codec_id == CODEC_ID_MPEG1VIDEO || - s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG) { + if (s->mpeg_quant || s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG || s->codec_id==CODEC_ID_AMV) { // (a + x * 3 / 8) / x s->intra_quant_bias = 3 << (QUANT_BIAS_SHIFT - 3); s->inter_quant_bias = 0; @@ -592,6 +594,8 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) if (avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS) s->inter_quant_bias = avctx->inter_quant_bias; + av_log(avctx, AV_LOG_DEBUG, "intra_quant_bias = %d inter_quant_bias = %d\n",s->intra_quant_bias,s->inter_quant_bias); + avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift); @@ -620,10 +624,13 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) break; case CODEC_ID_LJPEG: case CODEC_ID_MJPEG: + case CODEC_ID_AMV: s->out_format = FMT_MJPEG; s->intra_only = 1; /* force intra only for jpeg */ if (avctx->codec->id == CODEC_ID_LJPEG && - avctx->pix_fmt == PIX_FMT_BGRA) { + (avctx->pix_fmt == PIX_FMT_BGR0 + || s->avctx->pix_fmt == PIX_FMT_BGRA + || s->avctx->pix_fmt == PIX_FMT_BGR24)) { s->mjpeg_vsample[0] = s->mjpeg_hsample[0] = s->mjpeg_vsample[1] = s->mjpeg_hsample[1] = s->mjpeg_vsample[2] = s->mjpeg_hsample[2] = 1; @@ -657,13 +664,13 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) break; case CODEC_ID_H263: if (!CONFIG_H263_ENCODER) - return -1; + return -1; if (ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_format), s->width, s->height) == 8) { - av_log(avctx, AV_LOG_INFO, + av_log(avctx, AV_LOG_ERROR, "The specified picture size of %dx%d is not valid for " "the H.263 codec.\nValid sizes are 128x96, 176x144, " - "352x288, 704x576, and 1408x1152." + "352x288, 704x576, and 1408x1152. " "Try H.263+.\n", s->width, s->height); return -1; } @@ -982,6 +989,10 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg) uint8_t *src = pic_arg->data[i]; uint8_t *dst = pic->data[i]; + if(s->codec_id == CODEC_ID_AMV && !(s->avctx->flags & CODEC_FLAG_EMU_EDGE)){ + h= ((s->height+15)/16*16)>>v_shift; + } + if (!s->avctx->rc_buffer_size) dst += INPLACE_OFFSET; @@ -1726,7 +1737,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, ptr_cr = s->new_picture.f.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) { + if((mb_x*16+16 > s->width || mb_y*16+16 > s->height) && s->codec_id != CODEC_ID_AMV){ uint8_t *ebuf = s->edge_emu_buffer + 32; s->dsp.emulated_edge_mc(ebuf, ptr_y, wrap_y, 16, 16, mb_x * 16, mb_y * 16, s->width, s->height); @@ -2023,6 +2034,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, h263_encode_mb(s, s->block, motion_x, motion_y); break; case CODEC_ID_MJPEG: + case CODEC_ID_AMV: if (CONFIG_MJPEG_ENCODER) ff_mjpeg_encode_mb(s, s->block); break; @@ -2324,6 +2336,11 @@ static int encode_thread(AVCodecContext *c, void *arg){ s->current_picture.f.error[i] = 0; } + if(s->codec_id==CODEC_ID_AMV){ + s->last_dc[0] = 128*8/13; + s->last_dc[1] = 128*8/14; + s->last_dc[2] = 128*8/14; + } s->mb_skip_run = 0; memset(s->last_mv, 0, sizeof(s->last_mv)); @@ -3049,6 +3066,13 @@ static int encode_picture(MpegEncContext *s, int picture_number) update_qscale(s); } + if(s->codec_id != CODEC_ID_AMV){ + if(s->q_chroma_intra_matrix != s->q_intra_matrix ) av_freep(&s->q_chroma_intra_matrix); + if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16); + s->q_chroma_intra_matrix = s->q_intra_matrix; + s->q_chroma_intra_matrix16 = s->q_intra_matrix16; + } + s->mb_intra=0; //for the rate distortion & bit compare functions for(i=1; i<context_count; i++){ ff_update_duplicate_context(s->thread_context[i], s); @@ -3166,6 +3190,25 @@ static int encode_picture(MpegEncContext *s, int picture_number) s->intra_matrix, s->intra_quant_bias, 8, 8, 1); s->qscale= 8; } + if(s->codec_id == CODEC_ID_AMV){ + static const uint8_t y[32]={13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13}; + static const uint8_t c[32]={14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14}; + for(i=1;i<64;i++){ + int j= s->dsp.idct_permutation[ff_zigzag_direct[i]]; + + s->intra_matrix[j] = sp5x_quant_table[5*2+0][i]; + s->chroma_intra_matrix[j] = sp5x_quant_table[5*2+1][i]; + } + s->y_dc_scale_table= y; + s->c_dc_scale_table= c; + s->intra_matrix[0] = 13; + s->chroma_intra_matrix[0] = 14; + ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16, + s->intra_matrix, s->intra_quant_bias, 8, 8, 1); + ff_convert_matrix(&s->dsp, s->q_chroma_intra_matrix, s->q_chroma_intra_matrix16, + s->chroma_intra_matrix, s->intra_quant_bias, 8, 8, 1); + s->qscale= 8; + } //FIXME var duplication s->current_picture_ptr->f.key_frame = @@ -3300,7 +3343,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, block[0] = (block[0] + (q >> 1)) / q; start_i = 1; last_non_zero = 0; - qmat = s->q_intra_matrix[qscale]; + qmat = n < 4 ? s->q_intra_matrix[qscale] : s->q_chroma_intra_matrix[qscale]; if(s->mpeg_quant || s->out_format == FMT_MPEG1) bias= 1<<(QMAT_SHIFT-1); length = s->intra_ac_vlc_length; @@ -3971,7 +4014,7 @@ int dct_quantize_c(MpegEncContext *s, block[0] = (block[0] + (q >> 1)) / q; start_i = 1; last_non_zero = 0; - qmat = s->q_intra_matrix[qscale]; + qmat = n < 4 ? s->q_intra_matrix[qscale] : s->q_chroma_intra_matrix[qscale]; bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT); } else { start_i = 0; diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c index 1798f8386f..729f0929ec 100644 --- a/libavcodec/mpegvideo_parser.c +++ b/libavcodec/mpegvideo_parser.c @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -164,10 +164,13 @@ static int mpegvideo_split(AVCodecContext *avctx, { int i; uint32_t state= -1; + int found=0; for(i=0; i<buf_size; i++){ state= (state<<8) | buf[i]; - if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100) + if(state == 0x1B3){ + found=1; + }else if(found && state != 0x1B5 && state < 0x200 && state >= 0x100) return i-3; } return 0; diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c index 159fe21b58..6247e6240c 100644 --- a/libavcodec/mpegvideo_xvmc.c +++ b/libavcodec/mpegvideo_xvmc.c @@ -2,20 +2,20 @@ * XVideo Motion Compensation * Copyright (c) 2003 Ivan Kalvachev * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/mqc.c b/libavcodec/mqc.c new file mode 100644 index 0000000000..700b9574c1 --- /dev/null +++ b/libavcodec/mqc.c @@ -0,0 +1,108 @@ +/* + * MQ-coder encoder and decoder common functions + * Copyright (c) 2007 Kamil Nowosad + * + * 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 + */ + +/** + * MQ-coder ecoder and decoder common functions + * @file + * @author Kamil Nowosad + */ + +#include "mqc.h" + +typedef struct { + uint16_t qe; + uint8_t nmps; + uint8_t nlps; + uint8_t sw; +} MqcCxState; + +const static MqcCxState cx_states[47] = { + {0x5601, 1, 1, 1}, + {0x3401, 2, 6, 0}, + {0x1801, 3, 9, 0}, + {0x0AC1, 4, 12, 0}, + {0x0521, 5, 29, 0}, + {0x0221, 38, 33, 0}, + {0x5601, 7, 6, 1}, + {0x5401, 8, 14, 0}, + {0x4801, 9, 14, 0}, + {0x3801, 10, 14, 0}, + {0x3001, 11, 17, 0}, + {0x2401, 12, 18, 0}, + {0x1C01, 13, 20, 0}, + {0x1601, 29, 21, 0}, + {0x5601, 15, 14, 1}, + {0x5401, 16, 14, 0}, + {0x5101, 17, 15, 0}, + {0x4801, 18, 16, 0}, + {0x3801, 19, 17, 0}, + {0x3401, 20, 18, 0}, + {0x3001, 21, 19, 0}, + {0x2801, 22, 19, 0}, + {0x2401, 23, 20, 0}, + {0x2201, 24, 21, 0}, + {0x1C01, 25, 22, 0}, + {0x1801, 26, 23, 0}, + {0x1601, 27, 24, 0}, + {0x1401, 28, 25, 0}, + {0x1201, 29, 26, 0}, + {0x1101, 30, 27, 0}, + {0x0AC1, 31, 28, 0}, + {0x09C1, 32, 29, 0}, + {0x08A1, 33, 30, 0}, + {0x0521, 34, 31, 0}, + {0x0441, 35, 32, 0}, + {0x02A1, 36, 33, 0}, + {0x0221, 37, 34, 0}, + {0x0141, 38, 35, 0}, + {0x0111, 39, 36, 0}, + {0x0085, 40, 37, 0}, + {0x0049, 41, 38, 0}, + {0x0025, 42, 39, 0}, + {0x0015, 43, 40, 0}, + {0x0009, 44, 41, 0}, + {0x0005, 45, 42, 0}, + {0x0001, 45, 43, 0}, + {0x5601, 46, 46, 0} +}; + +uint16_t ff_mqc_qe [2*47]; +uint8_t ff_mqc_nlps[2*47]; +uint8_t ff_mqc_nmps[2*47]; + +void ff_mqc_init_contexts(MqcState *mqc) +{ + int i; + memset(mqc->cx_states, 0, sizeof(mqc->cx_states)); + mqc->cx_states[MQC_CX_UNI] = 2 * 46; + mqc->cx_states[MQC_CX_RL] = 2 * 3; + mqc->cx_states[0] = 2 * 4; + + for (i = 0; i < 47; i++){ + ff_mqc_qe[2*i ] = + ff_mqc_qe[2*i+1] = cx_states[i].qe; + + ff_mqc_nlps[2*i ] = 2*cx_states[i].nlps + cx_states[i].sw; + ff_mqc_nlps[2*i+1] = 2*cx_states[i].nlps + 1 - cx_states[i].sw; + ff_mqc_nmps[2*i ] = 2*cx_states[i].nmps; + ff_mqc_nmps[2*i+1] = 2*cx_states[i].nmps + 1; + } +} diff --git a/libavcodec/mqc.h b/libavcodec/mqc.h new file mode 100644 index 0000000000..b28c13ec48 --- /dev/null +++ b/libavcodec/mqc.h @@ -0,0 +1,75 @@ +/* + * MQ-coder + * Copyright (c) 2007 Kamil Nowosad + * + * 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 AVCODEC_MQC_H +#define AVCODEC_MQC_H + +/** + * MQ-coder + * @file + * @author Kamil Nowosad + */ + +#include "avcodec.h" + +#define MQC_CX_UNI 17 +#define MQC_CX_RL 18 + +extern uint16_t ff_mqc_qe[2*47]; +extern uint8_t ff_mqc_nlps[2*47]; +extern uint8_t ff_mqc_nmps[2*47]; + +typedef struct { + uint8_t *bp, *bpstart; + unsigned int a; + unsigned int c; + unsigned int ct; + uint8_t cx_states[19]; +} MqcState; + +/* encoder */ + +/** initialize the encoder */ +void ff_mqc_initenc(MqcState *mqc, uint8_t *bp); + +/** code bit d with context cx */ +void ff_mqc_encode(MqcState *mqc, uint8_t *cxstate, int d); + +/** number of encoded bytes */ +int ff_mqc_length(MqcState *mqc); + +/** flush the encoder [returns number of bytes encoded] */ +int ff_mqc_flush(MqcState *mqc); + +/* decoder */ + +/** initialize the decoder */ +void ff_mqc_initdec(MqcState *mqc, uint8_t *bp); + +/** returns decoded bit with context cx */ +int ff_mqc_decode(MqcState *mqc, uint8_t *cxstate); + +/* common */ + +/** initialize the contexts */ +void ff_mqc_init_contexts(MqcState *mqc); + +#endif /* AVCODEC_MQC_H */ diff --git a/libavcodec/mqcdec.c b/libavcodec/mqcdec.c new file mode 100644 index 0000000000..56e22f88c7 --- /dev/null +++ b/libavcodec/mqcdec.c @@ -0,0 +1,93 @@ +/* + * MQ-coder decoder + * Copyright (c) 2007 Kamil Nowosad + * + * 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 + */ + +/** + * MQ-coder decoder + * @file + * @author Kamil Nowosad + */ + +#include "mqc.h" + +static void bytein(MqcState *mqc) +{ + if (*mqc->bp == 0xff){ + if (*(mqc->bp+1) > 0x8f) + mqc->c++; + else{ + mqc->bp++; + mqc->c += 2 + 0xfe00 - (*mqc->bp << 9); + } + } else{ + mqc->bp++; + mqc->c += 1 + 0xff00 - (*mqc->bp << 8); + } +} + +static int exchange(MqcState *mqc, uint8_t *cxstate, int lps) +{ + int d; + if ((mqc->a < ff_mqc_qe[*cxstate]) ^ (!lps)){ + if (lps) + mqc->a = ff_mqc_qe[*cxstate]; + d = *cxstate & 1; + *cxstate = ff_mqc_nmps[*cxstate]; + } else{ + if (lps) + mqc->a = ff_mqc_qe[*cxstate]; + d = 1 - (*cxstate & 1); + *cxstate = ff_mqc_nlps[*cxstate]; + } + // renormd: + do{ + if (!(mqc->c & 0xff)){ + mqc->c -= 0x100; + bytein(mqc); + } + mqc->a += mqc->a; + mqc->c += mqc->c; + } while (!(mqc->a & 0x8000)); + return d; +} + +void ff_mqc_initdec(MqcState *mqc, uint8_t *bp) +{ + ff_mqc_init_contexts(mqc); + mqc->bp = bp; + mqc->c = (*mqc->bp ^ 0xff) << 16; + bytein(mqc); + mqc->c = mqc->c << 7; + mqc->a = 0x8000; +} + +int ff_mqc_decode(MqcState *mqc, uint8_t *cxstate) +{ + mqc->a -= ff_mqc_qe[*cxstate]; + if ((mqc->c >> 16) < mqc->a){ + if (mqc->a & 0x8000) + return *cxstate & 1; + else + return exchange(mqc, cxstate, 0); + } else { + mqc->c -= mqc->a << 16; + return exchange(mqc, cxstate, 1); + } +} diff --git a/libavcodec/mqcenc.c b/libavcodec/mqcenc.c new file mode 100644 index 0000000000..97d352be44 --- /dev/null +++ b/libavcodec/mqcenc.c @@ -0,0 +1,119 @@ +/* + * MQ-coder encoder + * Copyright (c) 2007 Kamil Nowosad + * + * 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 + */ + +/** + * MQ-coder encoder + * @file + * @author Kamil Nowosad + */ + +#include "mqc.h" + +static void byteout(MqcState *mqc) +{ +retry: + if (*mqc->bp == 0xff){ + mqc->bp++; + *mqc->bp = mqc->c >> 20; + mqc->c &= 0xfffff; + mqc->ct = 7; + } else if ((mqc->c & 0x8000000)){ + (*mqc->bp)++; + mqc->c &= 0x7ffffff; + goto retry; + } else{ + mqc->bp++; + *mqc->bp = mqc->c >> 19; + mqc->c &= 0x7ffff; + mqc->ct = 8; + } +} + +static void renorme(MqcState *mqc) +{ + do{ + mqc->a += mqc->a; + mqc->c += mqc->c; + if (!--mqc->ct) + byteout(mqc); + } while (!(mqc->a & 0x8000)); +} + +static void setbits(MqcState *mqc) +{ + int tmp = mqc->c + mqc->a; + mqc->c |= 0xffff; + if (mqc->c >= tmp) + mqc->c -= 0x8000; +} + +void ff_mqc_initenc(MqcState *mqc, uint8_t *bp) +{ + ff_mqc_init_contexts(mqc); + mqc->a = 0x8000; + mqc->c = 0; + mqc->bp = bp-1; + mqc->bpstart = bp; + mqc->ct = 12 + (*mqc->bp == 0xff); +} + +void ff_mqc_encode(MqcState *mqc, uint8_t *cxstate, int d) +{ + int qe; + + qe = ff_mqc_qe[*cxstate]; + mqc->a -= qe; + if ((*cxstate & 1) == d){ + if (!(mqc->a & 0x8000)){ + if (mqc->a < qe) + mqc->a = qe; + else + mqc->c += qe; + *cxstate = ff_mqc_nmps[*cxstate]; + renorme(mqc); + } else + mqc->c += qe; + } else{ + if (mqc->a < qe) + mqc->c += qe; + else + mqc->a = qe; + *cxstate = ff_mqc_nlps[*cxstate]; + renorme(mqc); + } +} + +int ff_mqc_length(MqcState *mqc) +{ + return mqc->bp - mqc->bpstart; +} + +int ff_mqc_flush(MqcState *mqc) +{ + setbits(mqc); + mqc->c = mqc->c << mqc->ct; + byteout(mqc); + mqc->c = mqc->c << mqc->ct; + byteout(mqc); + if (*mqc->bp != 0xff) + mqc->bp++; + return mqc->bp - mqc->bpstart; +} diff --git a/libavcodec/msgsmdec.c b/libavcodec/msgsmdec.c index 52b0f5db0a..90e83ae7ac 100644 --- a/libavcodec/msgsmdec.c +++ b/libavcodec/msgsmdec.c @@ -2,20 +2,20 @@ * gsm 06.10 decoder, Microsoft variant * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/msgsmdec.h b/libavcodec/msgsmdec.h index 76c87f1bd9..3bfd1fd407 100644 --- a/libavcodec/msgsmdec.h +++ b/libavcodec/msgsmdec.h @@ -2,20 +2,20 @@ * gsm 06.10 decoder, Microsoft variant * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c index 11a191570e..d37cac9862 100644 --- a/libavcodec/msmpeg4.c +++ b/libavcodec/msmpeg4.c @@ -5,20 +5,20 @@ * * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1810,7 +1810,7 @@ int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, i-= 192; if(i&(~63)){ const int left= get_bits_left(&s->gb); - if(((i+192 == 64 && level/qmul==-1) || !(s->err_recognition&AV_EF_BITSTREAM)) && left>=0){ + if(((i+192 == 64 && level/qmul==-1) || !(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_COMPLIANT))) && left>=0){ av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y); break; }else{ diff --git a/libavcodec/msmpeg4.h b/libavcodec/msmpeg4.h index 77b1944205..463c72fa49 100644 --- a/libavcodec/msmpeg4.h +++ b/libavcodec/msmpeg4.h @@ -2,20 +2,20 @@ * MSMPEG4 backend for encoder and decoder * copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c index 6799a9ccd2..c071516365 100644 --- a/libavcodec/msmpeg4data.c +++ b/libavcodec/msmpeg4data.c @@ -5,20 +5,20 @@ * * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/msmpeg4data.h b/libavcodec/msmpeg4data.h index 0907c7a295..008265a2ca 100644 --- a/libavcodec/msmpeg4data.h +++ b/libavcodec/msmpeg4data.h @@ -5,20 +5,20 @@ * * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/msrle.c b/libavcodec/msrle.c index 41f1fd8ebd..2f3f876b15 100644 --- a/libavcodec/msrle.c +++ b/libavcodec/msrle.c @@ -2,20 +2,20 @@ * Microsoft RLE video decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -53,6 +53,9 @@ static av_cold int msrle_decode_init(AVCodecContext *avctx) s->avctx = avctx; switch (avctx->bits_per_coded_sample) { + case 1: + avctx->pix_fmt = PIX_FMT_MONOWHITE; + break; case 4: case 8: avctx->pix_fmt = PIX_FMT_PAL8; @@ -65,6 +68,7 @@ static av_cold int msrle_decode_init(AVCodecContext *avctx) return -1; } + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; @@ -82,14 +86,14 @@ static int msrle_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - s->frame.reference = 1; + s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &s->frame)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } - if (avctx->bits_per_coded_sample <= 8) { + if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) { const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if (pal) { @@ -103,7 +107,7 @@ static int msrle_decode_frame(AVCodecContext *avctx, /* FIXME how to correctly detect RLE ??? */ if (avctx->height * istride == avpkt->size) { /* assume uncompressed */ - int linesize = avctx->width * avctx->bits_per_coded_sample / 8; + int linesize = (avctx->width * avctx->bits_per_coded_sample + 7) / 8; uint8_t *ptr = s->frame.data[0]; uint8_t *buf = avpkt->data + (avctx->height-1)*istride; int i, j; diff --git a/libavcodec/msrledec.c b/libavcodec/msrledec.c index 4714772a20..c0e7682689 100644 --- a/libavcodec/msrledec.c +++ b/libavcodec/msrledec.c @@ -2,20 +2,20 @@ * Microsoft RLE decoder * Copyright (C) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -140,7 +140,7 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de output = pic->data[0] + (avctx->height - 1) * pic->linesize[0]; output_end = pic->data[0] + avctx->height * pic->linesize[0]; - while(src < data + srcsize) { + while(src + 1 < data + srcsize) { p1 = *src++; if(p1 == 0) { //Escape code p2 = *src++; @@ -172,6 +172,10 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de src += p2 * (depth >> 3); continue; } + if(data + srcsize - src < p2 * (depth >> 3)){ + av_log(avctx, AV_LOG_ERROR, "Copy beyond input buffer\n"); + return -1; + } if ((depth == 8) || (depth == 24)) { for(i = 0; i < p2 * (depth >> 3); i++) { *output++ = *src++; diff --git a/libavcodec/msrledec.h b/libavcodec/msrledec.h index ca5d936977..b45ea48bc1 100644 --- a/libavcodec/msrledec.h +++ b/libavcodec/msrledec.h @@ -2,20 +2,20 @@ * Microsoft RLE decoder * Copyright (C) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/msvideo1.c b/libavcodec/msvideo1.c index a5fef4ddf7..0d7e95e150 100644 --- a/libavcodec/msvideo1.c +++ b/libavcodec/msvideo1.c @@ -2,20 +2,20 @@ * Microsoft Video-1 Decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +70,7 @@ static av_cold int msvideo1_decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_RGB555; } + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; @@ -295,7 +296,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - s->frame.reference = 1; + s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &s->frame)) { av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); diff --git a/libavcodec/msvideo1enc.c b/libavcodec/msvideo1enc.c new file mode 100644 index 0000000000..971cce35e6 --- /dev/null +++ b/libavcodec/msvideo1enc.c @@ -0,0 +1,302 @@ +/* + * Microsoft Video-1 Encoder + * Copyright (c) 2009 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 + * Microsoft Video-1 encoder + */ + +#include "avcodec.h" +#include "bytestream.h" +#include "libavutil/lfg.h" +#include "elbg.h" +#include "libavutil/imgutils.h" +/** + * Encoder context + */ +typedef struct Msvideo1EncContext { + AVCodecContext *avctx; + AVFrame pic; + AVLFG rnd; + uint8_t *prev; + + int block[16*3]; + int block2[16*3]; + int codebook[8*3]; + int codebook2[8*3]; + int output[16*3]; + int output2[16*3]; + int avg[3]; + int bestpos; + int keyint; +} Msvideo1EncContext; + +enum MSV1Mode{ + MODE_SKIP = 0, + MODE_FILL, + MODE_2COL, + MODE_8COL, +}; + +#define SKIP_PREFIX 0x8400 +#define SKIPS_MAX 0x0FFF +#define MKRGB555(in, off) ((in[off] << 10) | (in[off + 1] << 5) | (in[off + 2])) + +static const int remap[16] = { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15 }; + +static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) +{ + Msvideo1EncContext * const c = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p = &c->pic; + uint16_t *src; + uint8_t *prevptr; + uint8_t *dst = buf; + int keyframe = 1; + int no_skips = 1; + int i, j, k, x, y; + int skips = 0; + + *p = *pict; + if(!c->prev) + c->prev = av_malloc(avctx->width * 3 * (avctx->height + 3)); + prevptr = c->prev + avctx->width * 3 * (FFALIGN(avctx->height, 4) - 1); + src = (uint16_t*)(p->data[0] + p->linesize[0]*(FFALIGN(avctx->height, 4) - 1)); + if(c->keyint >= avctx->keyint_min) + keyframe = 1; + + p->quality = 24; + + for(y = 0; y < avctx->height; y += 4){ + for(x = 0; x < avctx->width; x += 4){ + int bestmode = MODE_SKIP; + int bestscore = INT_MAX; + int flags = 0; + int score; + + for(j = 0; j < 4; j++){ + for(i = 0; i < 4; i++){ + uint16_t val = src[x + i - j*p->linesize[0]/2]; + for(k = 0; k < 3; k++){ + c->block[(i + j*4)*3 + k] = + c->block2[remap[i + j*4]*3 + k] = (val >> (10-k*5)) & 0x1F; + } + } + } + if(!keyframe){ + bestscore = 0; + for(j = 0; j < 4; j++){ + for(i = 0; i < 4*3; i++){ + int t = prevptr[x*3 + i + j*p->linesize[0]] - c->block[i + j*4*3]; + bestscore += t*t; + } + } + bestscore /= p->quality; + } + // try to find optimal value to fill whole 4x4 block + score = 0; + ff_init_elbg(c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd); + ff_do_elbg (c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd); + if(c->avg[0] == 1) // red component = 1 will be written as skip code + c->avg[0] = 0; + for(j = 0; j < 4; j++){ + for(i = 0; i < 4; i++){ + for(k = 0; k < 3; k++){ + int t = c->avg[k] - c->block[(i+j*4)*3+k]; + score += t*t; + } + } + } + score /= p->quality; + score += 2; + if(score < bestscore){ + bestscore = score; + bestmode = MODE_FILL; + } + // search for optimal filling of 2-color block + score = 0; + ff_init_elbg(c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd); + ff_do_elbg (c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd); + // last output value should be always 1, swap codebooks if needed + if(!c->output[15]){ + for(i = 0; i < 3; i++) + FFSWAP(uint8_t, c->codebook[i], c->codebook[i+3]); + for(i = 0; i < 16; i++) + c->output[i] ^= 1; + } + for(j = 0; j < 4; j++){ + for(i = 0; i < 4; i++){ + for(k = 0; k < 3; k++){ + int t = c->codebook[c->output[i+j*4]*3 + k] - c->block[i*3+k+j*4*3]; + score += t*t; + } + } + } + score /= p->quality; + score += 6; + if(score < bestscore){ + bestscore = score; + bestmode = MODE_2COL; + } + // search for optimal filling of 2-color 2x2 subblocks + score = 0; + for(i = 0; i < 4; i++){ + ff_init_elbg(c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd); + ff_do_elbg (c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd); + } + // last value should be always 1, swap codebooks if needed + if(!c->output2[15]){ + for(i = 0; i < 3; i++) + FFSWAP(uint8_t, c->codebook2[i+18], c->codebook2[i+21]); + for(i = 12; i < 16; i++) + c->output2[i] ^= 1; + } + for(j = 0; j < 4; j++){ + for(i = 0; i < 4; i++){ + for(k = 0; k < 3; k++){ + int t = c->codebook2[(c->output2[remap[i+j*4]] + (i&2) + (j&2)*2)*3+k] - c->block[i*3+k + j*4*3]; + score += t*t; + } + } + } + score /= p->quality; + score += 18; + if(score < bestscore){ + bestscore = score; + bestmode = MODE_8COL; + } + + if(bestmode == MODE_SKIP){ + skips++; + no_skips = 0; + } + if((bestmode != MODE_SKIP && skips) || skips == SKIPS_MAX){ + bytestream_put_le16(&dst, skips | SKIP_PREFIX); + skips = 0; + } + + switch(bestmode){ + case MODE_FILL: + bytestream_put_le16(&dst, MKRGB555(c->avg,0) | 0x8000); + for(j = 0; j < 4; j++) + for(i = 0; i < 4; i++) + for(k = 0; k < 3; k++) + prevptr[i*3 + k - j*3*avctx->width] = c->avg[k]; + break; + case MODE_2COL: + for(j = 0; j < 4; j++){ + for(i = 0; i < 4; i++){ + flags |= (c->output[i + j*4]^1) << (i + j*4); + for(k = 0; k < 3; k++) + prevptr[i*3 + k - j*3*avctx->width] = c->codebook[c->output[i + j*4]*3 + k]; + } + } + bytestream_put_le16(&dst, flags); + bytestream_put_le16(&dst, MKRGB555(c->codebook, 0)); + bytestream_put_le16(&dst, MKRGB555(c->codebook, 3)); + break; + case MODE_8COL: + for(j = 0; j < 4; j++){ + for(i = 0; i < 4; i++){ + flags |= (c->output2[remap[i + j*4]]^1) << (i + j*4); + for(k = 0; k < 3; k++) + prevptr[i*3 + k - j*3*avctx->width] = c->codebook2[(c->output2[remap[i+j*4]] + (i&2) + (j&2)*2)*3 + k]; + } + } + bytestream_put_le16(&dst, flags); + bytestream_put_le16(&dst, MKRGB555(c->codebook2, 0) | 0x8000); + for(i = 3; i < 24; i += 3) + bytestream_put_le16(&dst, MKRGB555(c->codebook2, i)); + break; + } + } + src -= p->linesize[0] << 1; + prevptr -= avctx->width * 3 * 4; + } + if(skips) + bytestream_put_le16(&dst, skips | SKIP_PREFIX); + //EOF + bytestream_put_byte(&dst, 0); + bytestream_put_byte(&dst, 0); + + if(no_skips) + keyframe = 1; + if(keyframe) + c->keyint = 0; + else + c->keyint++; + p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + p->key_frame= keyframe; + + return dst - buf; +} + + +/** + * init encoder + */ +static av_cold int encode_init(AVCodecContext *avctx) +{ + Msvideo1EncContext * const c = avctx->priv_data; + + c->avctx = avctx; + if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) { + return -1; + } + if((avctx->width&3) || (avctx->height&3)){ + av_log(avctx, AV_LOG_ERROR, "width and height must be multiplies of 4\n"); + return -1; + } + + avcodec_get_frame_defaults(&c->pic); + avctx->coded_frame = (AVFrame*)&c->pic; + + c->keyint = avctx->keyint_min; + av_lfg_init(&c->rnd, 1); + + return 0; +} + + + +/** + * Uninit encoder + */ +static av_cold int encode_end(AVCodecContext *avctx) +{ + Msvideo1EncContext * const c = avctx->priv_data; + + av_freep(&c->prev); + + return 0; +} + +AVCodec ff_msvideo1_encoder = { + .name = "msvideo1", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MSVIDEO1, + .priv_data_size = sizeof(Msvideo1EncContext), + .init = encode_init, + .encode = encode_frame, + .close = encode_end, + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB555, PIX_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video-1"), +}; diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c index 6f0d0457f7..9f9212ce9b 100644 --- a/libavcodec/mxpegdec.c +++ b/libavcodec/mxpegdec.c @@ -2,20 +2,20 @@ * MxPEG decoder * Copyright (c) 2011 Anatoly Nenashev * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -80,6 +80,7 @@ static int mxpeg_decode_mxm(MXpegDecodeContext *s, } if (s->bitmask_size != bitmask_size) { + s->bitmask_size = 0; av_freep(&s->mxm_bitmask); s->mxm_bitmask = av_malloc(bitmask_size); if (!s->mxm_bitmask) { diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index 9d5e1c73dd..de26dc6a41 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -154,6 +154,7 @@ static int decode_tag(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *side=av_packet_get_side_data(avpkt, 'F', NULL); int buf_size = avpkt->size; NellyMoserDecodeContext *s = avctx->priv_data; int blocks, i, ret; @@ -161,10 +162,12 @@ static int decode_tag(AVCodecContext *avctx, void *data, float *samples_flt; blocks = buf_size / NELLY_BLOCK_LEN; + if (blocks <= 0) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); return AVERROR_INVALIDDATA; } + if (buf_size % NELLY_BLOCK_LEN) { av_log(avctx, AV_LOG_WARNING, "Leftover bytes: %d.\n", buf_size % NELLY_BLOCK_LEN); @@ -176,6 +179,8 @@ static int decode_tag(AVCodecContext *avctx, void *data, * 22050 Hz - 4 * 44100 Hz - 8 */ + if(side && blocks>1 && avctx->sample_rate%11025==0 && (1<<((side[0]>>2)&3)) == blocks) + avctx->sample_rate= 11025*(blocks/2); /* get output buffer */ s->frame.nb_samples = NELLY_SAMPLES * blocks; diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index d3715ac740..725270c9fa 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -4,20 +4,20 @@ * * Copyright (c) 2008 Bartlomiej Wolowiec * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +28,7 @@ * * Generic codec information: libavcodec/nellymoserdec.c * - * Some information also from: http://samples.libav.org/A-codecs/Nelly_Moser/ASAO/ASAO.zip + * Some information also from: http://samples.mplayerhq.hu/A-codecs/Nelly_Moser/ASAO/ASAO.zip * (Copyright Joseph Artsimovich and UAB "DKD") * * for more information about nellymoser format, visit: diff --git a/libavcodec/noise_bsf.c b/libavcodec/noise_bsf.c index 489e3c7c7c..491fbccc1d 100644 --- a/libavcodec/noise_bsf.c +++ b/libavcodec/noise_bsf.c @@ -1,20 +1,20 @@ /* * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/nuv.c b/libavcodec/nuv.c index 5f601db66e..c82034a96b 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -2,24 +2,25 @@ * NuppelVideo decoder * Copyright (c) 2006 Reimar Doeffinger * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 <stdlib.h> +#include <limits.h> #include "libavutil/bswap.h" #include "libavutil/lzo.h" @@ -112,19 +113,23 @@ static int codec_reinit(AVCodecContext *avctx, int width, int height, int qualit if (quality >= 0) get_quant_quality(c, quality); if (width != c->width || height != c->height) { - if (av_image_check_size(height, width, 0, avctx) < 0) - return 0; + // also reserve space for a possible additional header + int buf_size = 24 + height * width * 3 / 2 + AV_LZO_OUTPUT_PADDING; + if (av_image_check_size(height, width, 0, avctx) < 0 || + buf_size > INT_MAX/8) + return -1; avctx->width = c->width = width; avctx->height = c->height = height; - av_fast_malloc(&c->decomp_buf, &c->decomp_size, c->height * c->width * 3 / 2); + av_fast_malloc(&c->decomp_buf, &c->decomp_size, buf_size); if (!c->decomp_buf) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 0; + return AVERROR(ENOMEM); } rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); + return 1; } else if (quality != c->quality) rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); - return 1; + return 0; } static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, @@ -135,6 +140,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVFrame *picture = data; int orig_size = buf_size; int keyframe; + int size_change = 0; int result; enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1', NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3', @@ -172,18 +178,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, default: keyframe = 1; break; } +retry: // 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; + int outlen = c->decomp_size - AV_LZO_OUTPUT_PADDING, inlen = buf_size; if (av_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; + buf_size = c->decomp_size - AV_LZO_OUTPUT_PADDING - outlen; } if (c->codec_frameheader) { - int w, h, q; + int w, h, q, res; if (buf[0] != 'V' || buf_size < 12) { av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame (wrong codec_tag?)\n"); return AVERROR_INVALIDDATA; @@ -191,13 +198,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, w = AV_RL16(&buf[6]); h = AV_RL16(&buf[8]); q = buf[10]; - if (!codec_reinit(avctx, w, h, q)) - return -1; + res = codec_reinit(avctx, w, h, q); + if (res < 0) + return res; + if (res) { + buf = avpkt->data; + buf_size = avpkt->size; + size_change = 1; + goto retry; + } buf = &buf[12]; buf_size -= 12; } - if (keyframe && c->pic.data[0]) + if ((size_change || keyframe) && c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); c->pic.reference = 3; c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | @@ -259,7 +273,7 @@ static av_cold int decode_init(AVCodecContext *avctx) { if (avctx->extradata_size) get_quant(avctx, c, avctx->extradata, avctx->extradata_size); dsputil_init(&c->dsp, avctx); - if (!codec_reinit(avctx, avctx->width, avctx->height, -1)) + if (codec_reinit(avctx, avctx->width, avctx->height, -1) < 0) return 1; return 0; } diff --git a/libavcodec/options.c b/libavcodec/options.c index 04fb1b404b..b11d6abe6b 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -2,20 +2,20 @@ * Copyright (c) 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -75,7 +75,8 @@ static const AVClass *codec_child_class_next(const AVClass *prev) #define AV_CODEC_DEFAULT_BITRATE 200*1000 static const AVOption options[]={ -{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, V|A|E}, +{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, A|V|E}, +{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.dbl = 128*1000 }, INT_MIN, INT_MAX, A|E}, {"bt", "set video bitrate tolerance (in bits/s)", OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.dbl = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E}, {"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.dbl = DEFAULT }, 0, UINT_MAX, V|A|E|D, "flags"}, {"mv4", "use four motion vector by macroblock (mpeg4)", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"}, @@ -105,6 +106,7 @@ static const AVOption options[]={ {"sgop", "strictly enforce gop size", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_STRICT_GOP }, INT_MIN, INT_MAX, V|E, "flags2"}, {"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"}, {"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"}, +{"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"}, {"sub_id", NULL, OFFSET(sub_id), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX}, {"me_method", "set motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.dbl = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"}, {"zero", "zero motion estimation (fastest)", 0, AV_OPT_TYPE_CONST, {.dbl = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" }, @@ -131,7 +133,7 @@ static const AVOption options[]={ {"qcomp", "video quantizer scale compression (VBR)", OFFSET(qcompress), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -FLT_MAX, FLT_MAX, V|E}, {"qblur", "video quantizer scale blur (VBR)", OFFSET(qblur), AV_OPT_TYPE_FLOAT, {.dbl = 0.5 }, -1, FLT_MAX, V|E}, {"qmin", "min video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.dbl = 2 }, -1, 69, V|E}, -{"qmax", "max video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.dbl = 31 }, -1, 69, V|E}, +{"qmax", "max video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.dbl = 31 }, -1, 1024, V|E}, {"qdiff", "max difference between the quantizer scale (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.dbl = 3 }, INT_MIN, INT_MAX, V|E}, {"bf", "use 'frames' B frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, -1, FF_MAX_B_FRAMES, V|E}, {"b_qfactor", "qp factor between p and b frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, @@ -175,10 +177,13 @@ static const AVOption options[]={ {"experimental", "allow non standardized experimental things", 0, AV_OPT_TYPE_CONST, {.dbl = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, V|D|E, "strict"}, {"b_qoffset", "qp offset between P and B frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E}, {"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.dbl = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, -{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, V|D, "err_detect"}, -{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, V|D, "err_detect"}, -{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_BUFFER }, INT_MIN, INT_MAX, V|D, "err_detect"}, -{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_EXPLODE }, INT_MIN, INT_MAX, V|D, "err_detect"}, +{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"careful", "consider things that violate the spec and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, +{"aggressive", "consider things that a sane encoder shouldnt do as an error", 0, AV_OPT_TYPE_CONST, {.dbl = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"}, {"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX}, {"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX}, {"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, @@ -357,8 +362,8 @@ static const AVOption options[]={ {"all" , NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AVDISCARD_ALL }, INT_MIN, INT_MAX, V|D, "avdiscard"}, {"bidir_refine", "refine the two motion vectors used in bidirectional macroblocks", OFFSET(bidir_refine), AV_OPT_TYPE_INT, {.dbl = 1 }, 0, 4, V|E}, {"brd_scale", "downscales frames for dynamic B-frame decision", OFFSET(brd_scale), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, 10, V|E}, -{"keyint_min", "minimum interval between IDR-frames (x264)", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.dbl = 25 }, INT_MIN, INT_MAX, V|E}, -{"refs", "reference frames to consider for motion compensation (Snow)", OFFSET(refs), AV_OPT_TYPE_INT, {.dbl = 1 }, INT_MIN, INT_MAX, V|E}, +{"keyint_min", "minimum interval between IDR-frames", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.dbl = 25 }, INT_MIN, INT_MAX, V|E}, +{"refs", "reference frames to consider for motion compensation", OFFSET(refs), AV_OPT_TYPE_INT, {.dbl = 1 }, INT_MIN, INT_MAX, V|E}, {"chromaoffset", "chroma qp offset from luma", OFFSET(chromaoffset), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, {"skiprd", "RD optimal MB level residual skipping", 0, AV_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_SKIP_RD }, INT_MIN, INT_MAX, V|E, "flags2"}, @@ -398,7 +403,7 @@ static const AVOption options[]={ {"em", "Emergency", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"vo", "Voice Over", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"ka", "Karaoke", 0, AV_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, -{"request_sample_fmt", NULL, OFFSET(request_sample_fmt), AV_OPT_TYPE_INT, {.dbl = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"}, +{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_INT, {.dbl = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"}, {"u8" , "8-bit unsigned integer", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_U8 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"s16", "16-bit signed integer", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S16 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"s32", "32-bit signed integer", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S32 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, @@ -424,14 +429,28 @@ static const AVClass av_codec_context_class = { .child_class_next = codec_child_class_next, }; +#if FF_API_ALLOC_CONTEXT +void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){ + AVCodec c= {0}; + c.type= codec_type; + avcodec_get_context_defaults3(s, &c); +} +#endif + int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){ + int flags=0; memset(s, 0, sizeof(AVCodecContext)); s->av_class = &av_codec_context_class; s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN; - s->codec = codec; - av_opt_set_defaults(s); + if(s->codec_type == AVMEDIA_TYPE_AUDIO) + flags= AV_OPT_FLAG_AUDIO_PARAM; + else if(s->codec_type == AVMEDIA_TYPE_VIDEO) + flags= AV_OPT_FLAG_VIDEO_PARAM; + else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE) + flags= AV_OPT_FLAG_SUBTITLE_PARAM; + av_opt_set_defaults2(s, flags, flags); s->time_base = (AVRational){0,1}; s->get_buffer = avcodec_default_get_buffer; @@ -442,6 +461,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec){ s->sample_aspect_ratio = (AVRational){0,1}; s->pix_fmt = PIX_FMT_NONE; s->sample_fmt = AV_SAMPLE_FMT_NONE; + s->timecode_frame_start = -1; s->reget_buffer = avcodec_default_reget_buffer; s->reordered_opaque = AV_NOPTS_VALUE; @@ -482,6 +502,26 @@ AVCodecContext *avcodec_alloc_context3(AVCodec *codec){ return avctx; } +#if FF_API_ALLOC_CONTEXT +AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){ + AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); + + if(avctx==NULL) return NULL; + + avcodec_get_context_defaults2(avctx, codec_type); + + return avctx; +} + +void avcodec_get_context_defaults(AVCodecContext *s){ + avcodec_get_context_defaults2(s, AVMEDIA_TYPE_UNKNOWN); +} + +AVCodecContext *avcodec_alloc_context(void){ + return avcodec_alloc_context2(AVMEDIA_TYPE_UNKNOWN); +} +#endif + int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) { if (avcodec_is_open(dest)) { // check that the dest context is uninitialized @@ -543,3 +583,27 @@ const AVClass *avcodec_get_class(void) { return &av_codec_context_class; } + +#define FOFFSET(x) offsetof(AVFrame,x) + +static const AVOption frame_options[]={ +{"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.dbl = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0}, +{"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.dbl = -1 }, INT64_MIN, INT64_MAX, 0}, +{"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0}, +{"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, 0}, +{"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, 0}, +{"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.dbl = -1 }, 0, INT_MAX, 0}, +{NULL}, +}; + +static const AVClass av_frame_class = { + .class_name = "AVFrame", + .item_name = NULL, + .option = frame_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVClass *avcodec_get_frame_class(void) +{ + return &av_frame_class; +} diff --git a/libavcodec/os2threads.h b/libavcodec/os2threads.h new file mode 100644 index 0000000000..b816bff15f --- /dev/null +++ b/libavcodec/os2threads.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2011 KO Myung-Hun <komh@chollian.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 + * os2threads to pthreads wrapper + */ + +#ifndef AVCODEC_OS2PTHREADS_H +#define AVCODEC_OS2PTHREADS_H + +#define INCL_DOS +#include <os2.h> + +#undef __STRICT_ANSI__ /* for _beginthread() */ +#include <stdlib.h> + +typedef TID pthread_t; +typedef void pthread_attr_t; + +typedef HMTX pthread_mutex_t; +typedef void pthread_mutexattr_t; + +typedef struct { + HEV event_sem; + int wait_count; +} pthread_cond_t; + +typedef void pthread_condattr_t; + +struct thread_arg { + void *(*start_routine)(void *); + void *arg; +}; + +static void thread_entry(void *arg) +{ + struct thread_arg *thread_arg = arg; + + thread_arg->start_routine(thread_arg->arg); + + av_free(thread_arg); +} + +static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) +{ + struct thread_arg *thread_arg; + + thread_arg = av_mallocz(sizeof(struct thread_arg)); + + thread_arg->start_routine = start_routine; + thread_arg->arg = arg; + + *thread = _beginthread(thread_entry, NULL, 256 * 1024, thread_arg); + + return 0; +} + +static av_always_inline int pthread_join(pthread_t thread, void **value_ptr) +{ + DosWaitThread((PTID)&thread, DCWW_WAIT); + + return 0; +} + +static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE); + + return 0; +} + +static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + DosCloseMutexSem(*(PHMTX)mutex); + + return 0; +} + +static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + DosRequestMutexSem(*(PHMTX)mutex, SEM_INDEFINITE_WAIT); + + return 0; +} + +static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + DosReleaseMutexSem(*(PHMTX)mutex); + + return 0; +} + +static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) +{ + DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE); + + cond->wait_count = 0; + + return 0; +} + +static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond) +{ + DosCloseEventSem(cond->event_sem); + + return 0; +} + +static av_always_inline int pthread_cond_signal(pthread_cond_t *cond) +{ + if (cond->wait_count > 0) { + DosPostEventSem(cond->event_sem); + + cond->wait_count--; + } + + return 0; +} + +static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond) +{ + while (cond->wait_count > 0) { + DosPostEventSem(cond->event_sem); + + cond->wait_count--; + } + + return 0; +} + +static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + cond->wait_count++; + + pthread_mutex_unlock(mutex); + + DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT); + + pthread_mutex_lock(mutex); + + return 0; +} + +#endif /* AVCODEC_OS2PTHREADS_H */ diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c index e070ed4b3b..41db4ecb2f 100644 --- a/libavcodec/pamenc.c +++ b/libavcodec/pamenc.c @@ -2,25 +2,24 @@ * PAM image format * Copyright (c) 2002, 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" @@ -50,7 +49,7 @@ static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, h = avctx->height; w = avctx->width; switch (avctx->pix_fmt) { - case PIX_FMT_MONOWHITE: + case PIX_FMT_MONOBLACK: n = (w + 7) >> 3; depth = 1; maxval = 1; @@ -62,18 +61,42 @@ static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, maxval = 255; tuple_type = "GRAYSCALE"; break; + case PIX_FMT_GRAY16BE: + n = w * 2; + depth = 1; + maxval = 0xFFFF; + tuple_type = "GRAYSCALE"; + break; + case PIX_FMT_GRAY8A: + n = w * 2; + depth = 2; + maxval = 255; + tuple_type = "GRAYSCALE_ALPHA"; + break; case PIX_FMT_RGB24: n = w * 3; depth = 3; maxval = 255; tuple_type = "RGB"; break; - case PIX_FMT_RGB32: + case PIX_FMT_RGBA: n = w * 4; depth = 4; maxval = 255; tuple_type = "RGB_ALPHA"; break; + case PIX_FMT_RGB48BE: + n = w * 6; + depth = 3; + maxval = 0xFFFF; + tuple_type = "RGB"; + break; + case PIX_FMT_RGBA64BE: + n = w * 8; + depth = 4; + maxval = 0xFFFF; + tuple_type = "RGB_ALPHA"; + break; default: return -1; } @@ -85,16 +108,11 @@ static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, ptr = p->data[0]; linesize = p->linesize[0]; - if (avctx->pix_fmt == PIX_FMT_RGB32) { + if (avctx->pix_fmt == PIX_FMT_MONOBLACK){ 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; - } + for (j = 0; j < w; j++) + *s->bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1; ptr += linesize; } } else { @@ -115,6 +133,6 @@ AVCodec ff_pam_encoder = { .priv_data_size = sizeof(PNMContext), .init = ff_pnm_init, .encode = pam_encode_frame, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, PIX_FMT_NONE}, + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_RGB48BE, PIX_FMT_RGBA64BE, PIX_FMT_GRAY8, PIX_FMT_GRAY8A, PIX_FMT_GRAY16BE, PIX_FMT_MONOBLACK, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), }; diff --git a/libavcodec/parser.c b/libavcodec/parser.c index 9fd7af6ce6..d83d4c3d11 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -58,12 +58,10 @@ AVCodecParserContext *av_parser_init(int codec_id) if (!s) return NULL; s->parser = parser; - if (parser->priv_data_size) { - s->priv_data = av_mallocz(parser->priv_data_size); - if (!s->priv_data) { - av_free(s); - return NULL; - } + s->priv_data = av_mallocz(parser->priv_data_size); + if (!s->priv_data) { + av_free(s); + return NULL; } if (parser->parser_init) { ret = parser->parser_init(s); @@ -222,9 +220,9 @@ void av_parser_close(AVCodecParserContext *s) int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) { if(pc->overread){ - av_dlog(pc, "overread %d, state:%X next:%d index:%d o_index:%d\n", + av_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); - av_dlog(pc, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); + av_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); } /* Copy overread bytes from last frame into buffer. */ @@ -274,9 +272,9 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s } if(pc->overread){ - av_dlog(pc, "overread %d, state:%X next:%d index:%d o_index:%d\n", + av_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); - av_dlog(pc, "%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); + av_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); } return 0; diff --git a/libavcodec/parser.h b/libavcodec/parser.h index 1e85ae4051..6712bfe8b0 100644 --- a/libavcodec/parser.h +++ b/libavcodec/parser.h @@ -3,20 +3,20 @@ * Copyright (c) 2003 Fabrice Bellard * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c index 9ab6fc3ff0..b9417733ca 100644 --- a/libavcodec/pcm-mpeg.c +++ b/libavcodec/pcm-mpeg.c @@ -2,20 +2,20 @@ * LPCM codecs for PCM formats found in MPEG streams * Copyright (c) 2009 Christian Schmidt * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -75,6 +75,8 @@ static int pcm_bluray_parse_header(AVCodecContext *avctx, } avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_S32; + if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) + avctx->bits_per_raw_sample = avctx->bits_per_coded_sample; /* get the sample rate. Not all values are known or exist. */ switch (header[2] & 0x0f) { diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 594bd444fe..d041d77ae0 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -2,20 +2,20 @@ * PCM codecs * Copyright (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -49,7 +49,8 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx) avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); avctx->block_align = avctx->channels * avctx->bits_per_coded_sample/8; avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; } @@ -270,7 +271,9 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, if (CODEC_ID_PCM_DVD == avctx->codec_id) { if (avctx->bits_per_coded_sample != 20 && avctx->bits_per_coded_sample != 24) { - av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n"); + av_log(avctx, AV_LOG_ERROR, + "PCM DVD unsupported sample depth %i\n", + avctx->bits_per_coded_sample); return AVERROR(EINVAL); } /* 2 samples are interleaved per block in PCM_DVD */ @@ -509,14 +512,14 @@ AVCodec ff_ ## name_ ## _decoder = { \ PCM_ENCODER(id,sample_fmt_,name,long_name_); PCM_DECODER(id,sample_fmt_,name,long_name_) /* Note: Do not forget to add new entries to the Makefile as well. */ -PCM_CODEC (CODEC_ID_PCM_ALAW, AV_SAMPLE_FMT_S16, pcm_alaw, "PCM A-law"); +PCM_CODEC (CODEC_ID_PCM_ALAW, AV_SAMPLE_FMT_S16, pcm_alaw, "PCM A-law / G.711 A-law"); PCM_DECODER(CODEC_ID_PCM_DVD, AV_SAMPLE_FMT_S32, pcm_dvd, "PCM signed 20|24-bit big-endian"); PCM_CODEC (CODEC_ID_PCM_F32BE, AV_SAMPLE_FMT_FLT, pcm_f32be, "PCM 32-bit floating point big-endian"); PCM_CODEC (CODEC_ID_PCM_F32LE, AV_SAMPLE_FMT_FLT, pcm_f32le, "PCM 32-bit floating point little-endian"); PCM_CODEC (CODEC_ID_PCM_F64BE, AV_SAMPLE_FMT_DBL, pcm_f64be, "PCM 64-bit floating point big-endian"); PCM_CODEC (CODEC_ID_PCM_F64LE, AV_SAMPLE_FMT_DBL, pcm_f64le, "PCM 64-bit floating point little-endian"); PCM_DECODER(CODEC_ID_PCM_LXF, AV_SAMPLE_FMT_S32, pcm_lxf, "PCM signed 20-bit little-endian planar"); -PCM_CODEC (CODEC_ID_PCM_MULAW, AV_SAMPLE_FMT_S16, pcm_mulaw, "PCM mu-law"); +PCM_CODEC (CODEC_ID_PCM_MULAW, AV_SAMPLE_FMT_S16, pcm_mulaw, "PCM mu-law / G.711 mu-law"); PCM_CODEC (CODEC_ID_PCM_S8, AV_SAMPLE_FMT_U8, pcm_s8, "PCM signed 8-bit"); PCM_CODEC (CODEC_ID_PCM_S16BE, AV_SAMPLE_FMT_S16, pcm_s16be, "PCM signed 16-bit big-endian"); PCM_CODEC (CODEC_ID_PCM_S16LE, AV_SAMPLE_FMT_S16, pcm_s16le, "PCM signed 16-bit little-endian"); diff --git a/libavcodec/pcm_tablegen.c b/libavcodec/pcm_tablegen.c index 7b4bc8c6c9..bf8e7fb707 100644 --- a/libavcodec/pcm_tablegen.c +++ b/libavcodec/pcm_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/pcm_tablegen.h b/libavcodec/pcm_tablegen.h index 79d6561646..1387210a58 100644 --- a/libavcodec/pcm_tablegen.h +++ b/libavcodec/pcm_tablegen.h @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/pcx.c b/libavcodec/pcx.c index 7eb1daaa7a..6339dc05c8 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -5,20 +5,20 @@ * This decoder does not support CGA palettes. I am unable to find samples * and Netpbm cannot generate them. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -71,7 +71,7 @@ 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); + *dst++ = 0xFF000000 | bytestream_get_be24(src); if (pallen < 256) memset(dst, 0, (256 - pallen) * sizeof(*dst)); } @@ -224,6 +224,9 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (nplanes == 1 && bits_per_pixel == 8) { pcx_palette(&buf, (uint32_t *) p->data[1], 256); + } else if (bits_per_pixel * nplanes == 1) { + AV_WN32A(p->data[1] , 0xFF000000); + AV_WN32A(p->data[1]+4, 0xFFFFFFFF); } else if (bits_per_pixel < 8) { const uint8_t *palette = bufstart+16; pcx_palette(&palette, (uint32_t *) p->data[1], 16); diff --git a/libavcodec/pcxenc.c b/libavcodec/pcxenc.c index 308456808a..a39e221805 100644 --- a/libavcodec/pcxenc.c +++ b/libavcodec/pcxenc.c @@ -2,20 +2,20 @@ * PC Paintbrush PCX (.pcx) image encoder * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +28,7 @@ #include "avcodec.h" #include "bytestream.h" +#include "libavutil/imgutils.h" typedef struct PCXContext { AVFrame picture; @@ -105,6 +106,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, int bpp, nplanes, i, y, line_bytes, written; const uint32_t *pal = NULL; + uint32_t palette256[256]; const uint8_t *src; *pict = *(AVFrame *)data; @@ -126,6 +128,11 @@ static int pcx_encode_frame(AVCodecContext *avctx, case PIX_FMT_RGB4_BYTE: case PIX_FMT_BGR4_BYTE: case PIX_FMT_GRAY8: + bpp = 8; + nplanes = 1; + ff_set_systematic_pal2(palette256, avctx->pix_fmt); + pal = palette256; + break; case PIX_FMT_PAL8: bpp = 8; nplanes = 1; diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c index bcc47f358e..238dbeb00a 100644 --- a/libavcodec/pgssubdec.c +++ b/libavcodec/pgssubdec.c @@ -2,20 +2,20 @@ * PGS subtitle decoder * Copyright (c) 2009 Stephen Backway * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,6 +29,7 @@ #include "bytestream.h" #include "libavutil/colorspace.h" #include "libavutil/imgutils.h" +#include "libavutil/opt.h" #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) @@ -40,11 +41,17 @@ enum SegmentType { DISPLAY_SEGMENT = 0x80, }; -typedef struct PGSSubPresentation { +typedef struct PGSSubPictureReference { int x; int y; - int id_number; - int object_number; + int picture_id; + int composition; +} PGSSubPictureReference; + +typedef struct PGSSubPresentation { + int id_number; + int object_count; + PGSSubPictureReference *objects; } PGSSubPresentation; typedef struct PGSSubPicture { @@ -56,24 +63,33 @@ typedef struct PGSSubPicture { } PGSSubPicture; typedef struct PGSSubContext { + AVClass *class; PGSSubPresentation presentation; uint32_t clut[256]; - PGSSubPicture picture; + PGSSubPicture pictures[UINT16_MAX]; + int forced_subs_only; } PGSSubContext; static av_cold int init_decoder(AVCodecContext *avctx) { - avctx->pix_fmt = PIX_FMT_PAL8; + avctx->pix_fmt = PIX_FMT_PAL8; return 0; } static av_cold int close_decoder(AVCodecContext *avctx) { + uint16_t picture; + PGSSubContext *ctx = avctx->priv_data; - av_freep(&ctx->picture.rle); - ctx->picture.rle_buffer_size = 0; + av_freep(&ctx->presentation.objects); + ctx->presentation.object_count = 0; + + for (picture = 0; picture < UINT16_MAX; ++picture) { + av_freep(&ctx->pictures[picture].rle); + ctx->pictures[picture].rle_buffer_size = 0; + } return 0; } @@ -88,7 +104,7 @@ static av_cold int close_decoder(AVCodecContext *avctx) * @param buf pointer to the RLE data to process * @param buf_size size of the RLE data to process */ -static int decode_rle(AVCodecContext *avctx, AVSubtitle *sub, +static int decode_rle(AVCodecContext *avctx, AVSubtitle *sub, int rect, const uint8_t *buf, unsigned int buf_size) { const uint8_t *rle_bitmap_end; @@ -96,15 +112,15 @@ static int decode_rle(AVCodecContext *avctx, AVSubtitle *sub, rle_bitmap_end = buf + buf_size; - sub->rects[0]->pict.data[0] = av_malloc(sub->rects[0]->w * sub->rects[0]->h); + sub->rects[rect]->pict.data[0] = av_malloc(sub->rects[rect]->w * sub->rects[rect]->h); - if (!sub->rects[0]->pict.data[0]) + if (!sub->rects[rect]->pict.data[0]) return -1; pixel_count = 0; line_count = 0; - while (buf < rle_bitmap_end && line_count < sub->rects[0]->h) { + while (buf < rle_bitmap_end && line_count < sub->rects[rect]->h) { uint8_t flags, color; int run; @@ -119,27 +135,27 @@ static int decode_rle(AVCodecContext *avctx, AVSubtitle *sub, color = flags & 0x80 ? bytestream_get_byte(&buf) : 0; } - if (run > 0 && pixel_count + run <= sub->rects[0]->w * sub->rects[0]->h) { - memset(sub->rects[0]->pict.data[0] + pixel_count, color, run); + if (run > 0 && pixel_count + run <= sub->rects[rect]->w * sub->rects[rect]->h) { + memset(sub->rects[rect]->pict.data[0] + pixel_count, color, run); pixel_count += run; } else if (!run) { /* * New Line. Check if correct pixels decoded, if not display warning * and adjust bitmap pointer to correct new line position. */ - if (pixel_count % sub->rects[0]->w > 0) + if (pixel_count % sub->rects[rect]->w > 0) av_log(avctx, AV_LOG_ERROR, "Decoded %d pixels, when line should be %d pixels\n", - pixel_count % sub->rects[0]->w, sub->rects[0]->w); + pixel_count % sub->rects[rect]->w, sub->rects[rect]->w); line_count++; } } - if (pixel_count < sub->rects[0]->w * sub->rects[0]->h) { + if (pixel_count < sub->rects[rect]->w * sub->rects[rect]->h) { av_log(avctx, AV_LOG_ERROR, "Insufficient RLE data for subtitle\n"); return -1; } - av_dlog(avctx, "Pixel Count = %d, Area = %d\n", pixel_count, sub->rects[0]->w * sub->rects[0]->h); + av_dlog(avctx, "Pixel Count = %d, Area = %d\n", pixel_count, sub->rects[rect]->w * sub->rects[rect]->h); return 0; } @@ -162,25 +178,28 @@ static int parse_picture_segment(AVCodecContext *avctx, uint8_t sequence_desc; unsigned int rle_bitmap_len, width, height; + uint16_t picture_id; if (buf_size <= 4) return -1; buf_size -= 4; - /* skip 3 unknown bytes: Object ID (2 bytes), Version Number */ - buf += 3; + picture_id = bytestream_get_be16(&buf); + + /* skip 1 unknown byte: Version Number */ + buf++; /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */ sequence_desc = bytestream_get_byte(&buf); if (!(sequence_desc & 0x80)) { /* Additional RLE data */ - if (buf_size > ctx->picture.rle_remaining_len) + if (buf_size > ctx->pictures[picture_id].rle_remaining_len) return -1; - memcpy(ctx->picture.rle + ctx->picture.rle_data_len, buf, buf_size); - ctx->picture.rle_data_len += buf_size; - ctx->picture.rle_remaining_len -= buf_size; + memcpy(ctx->pictures[picture_id].rle + ctx->pictures[picture_id].rle_data_len, buf, buf_size); + ctx->pictures[picture_id].rle_data_len += buf_size; + ctx->pictures[picture_id].rle_remaining_len -= buf_size; return 0; } @@ -202,17 +221,17 @@ static int parse_picture_segment(AVCodecContext *avctx, return -1; } - ctx->picture.w = width; - ctx->picture.h = height; + ctx->pictures[picture_id].w = width; + ctx->pictures[picture_id].h = height; - av_fast_malloc(&ctx->picture.rle, &ctx->picture.rle_buffer_size, rle_bitmap_len); + av_fast_malloc(&ctx->pictures[picture_id].rle, &ctx->pictures[picture_id].rle_buffer_size, rle_bitmap_len); - if (!ctx->picture.rle) + if (!ctx->pictures[picture_id].rle) return -1; - memcpy(ctx->picture.rle, buf, buf_size); - ctx->picture.rle_data_len = buf_size; - ctx->picture.rle_remaining_len = rle_bitmap_len - buf_size; + memcpy(ctx->pictures[picture_id].rle, buf, buf_size); + ctx->pictures[picture_id].rle_data_len = buf_size; + ctx->pictures[picture_id].rle_remaining_len = rle_bitmap_len - buf_size; return 0; } @@ -268,18 +287,17 @@ static void parse_palette_segment(AVCodecContext *avctx, * @param buf pointer to the packet to process * @param buf_size size of packet to process * @todo TODO: Implement cropping - * @todo TODO: Implement forcing of subtitles */ static void parse_presentation_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size) { PGSSubContext *ctx = avctx->priv_data; - int x, y; - int w = bytestream_get_be16(&buf); int h = bytestream_get_be16(&buf); + uint16_t object_index; + av_dlog(avctx, "Video Dimensions %dx%d\n", w, h); if (av_image_check_size(w, h, 0, avctx) >= 0) @@ -298,34 +316,46 @@ static void parse_presentation_segment(AVCodecContext *avctx, */ buf += 3; - ctx->presentation.object_number = bytestream_get_byte(&buf); - if (!ctx->presentation.object_number) + ctx->presentation.object_count = bytestream_get_byte(&buf); + if (!ctx->presentation.object_count) return; - /* - * Skip 4 bytes of unknown: - * object_id_ref (2 bytes), - * window_id_ref, - * composition_flag (0x80 - object cropped, 0x40 - object forced) - */ - buf += 4; + /* Verify that enough bytes are remaining for all of the objects. */ + buf_size -= 11; + if (buf_size < ctx->presentation.object_count * 8) { + ctx->presentation.object_count = 0; + return; + } + + av_freep(&ctx->presentation.objects); + ctx->presentation.objects = av_malloc(sizeof(PGSSubPictureReference) * ctx->presentation.object_count); + if (!ctx->presentation.objects) { + ctx->presentation.object_count = 0; + return; + } - x = bytestream_get_be16(&buf); - y = bytestream_get_be16(&buf); + for (object_index = 0; object_index < ctx->presentation.object_count; ++object_index) { + PGSSubPictureReference *reference = &ctx->presentation.objects[object_index]; + reference->picture_id = bytestream_get_be16(&buf); - /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/ + /* Skip window_id_ref */ + buf++; + /* composition_flag (0x80 - object cropped, 0x40 - object forced) */ + reference->composition = bytestream_get_byte(&buf); - av_dlog(avctx, "Subtitle Placement x=%d, y=%d\n", x, y); + reference->x = bytestream_get_be16(&buf); + reference->y = bytestream_get_be16(&buf); - if (x > avctx->width || y > avctx->height) { - av_log(avctx, AV_LOG_ERROR, "Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n", - x, y, avctx->width, avctx->height); - x = 0; y = 0; - } + /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/ + av_dlog(avctx, "Subtitle Placement ID=%d, x=%d, y=%d\n", reference->picture_id, reference->x, reference->y); - /* Fill in dimensions */ - ctx->presentation.x = x; - ctx->presentation.y = y; + if (reference->x > avctx->width || reference->y > avctx->height) { + av_log(avctx, AV_LOG_ERROR, "Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n", + reference->x, reference->y, avctx->width, avctx->height); + reference->x = 0; + reference->y = 0; + } + } } /** @@ -349,46 +379,53 @@ static int display_end_segment(AVCodecContext *avctx, void *data, AVSubtitle *sub = data; PGSSubContext *ctx = avctx->priv_data; + uint16_t rect; + /* * The end display time is a timeout value and is only reached - * if the next subtitle is later then timeout or subtitle has + * if the next subtitle is later than timeout or subtitle has * not been cleared by a subsequent empty display command. */ memset(sub, 0, sizeof(*sub)); - // Blank if last object_number was 0. - // Note that this may be wrong for more complex subtitles. - if (!ctx->presentation.object_number) + + // Blank if last object_count was 0. + if (!ctx->presentation.object_count) return 1; + sub->start_display_time = 0; sub->end_display_time = 20000; sub->format = 0; - sub->rects = av_mallocz(sizeof(*sub->rects)); - sub->rects[0] = av_mallocz(sizeof(*sub->rects[0])); - sub->num_rects = 1; - - sub->rects[0]->x = ctx->presentation.x; - sub->rects[0]->y = ctx->presentation.y; - sub->rects[0]->w = ctx->picture.w; - sub->rects[0]->h = ctx->picture.h; - sub->rects[0]->type = SUBTITLE_BITMAP; - - /* Process bitmap */ - sub->rects[0]->pict.linesize[0] = ctx->picture.w; - - if (ctx->picture.rle) { - if (ctx->picture.rle_remaining_len) - av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n", - ctx->picture.rle_data_len, ctx->picture.rle_remaining_len); - if(decode_rle(avctx, sub, ctx->picture.rle, ctx->picture.rle_data_len) < 0) - return 0; - } - /* Allocate memory for colors */ - sub->rects[0]->nb_colors = 256; - sub->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); + sub->num_rects = ctx->presentation.object_count; + sub->rects = av_mallocz(sizeof(*sub->rects) * sub->num_rects); + + for (rect = 0; rect < sub->num_rects; ++rect) { + uint16_t picture_id = ctx->presentation.objects[rect].picture_id; + sub->rects[rect] = av_mallocz(sizeof(*sub->rects[rect])); + sub->rects[rect]->x = ctx->presentation.objects[rect].x; + sub->rects[rect]->y = ctx->presentation.objects[rect].y; + sub->rects[rect]->w = ctx->pictures[picture_id].w; + sub->rects[rect]->h = ctx->pictures[picture_id].h; + sub->rects[rect]->type = SUBTITLE_BITMAP; + + /* Process bitmap */ + sub->rects[rect]->pict.linesize[0] = ctx->pictures[picture_id].w; + if (ctx->pictures[picture_id].rle) { + if (ctx->pictures[picture_id].rle_remaining_len) + av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n", + ctx->pictures[picture_id].rle_data_len, ctx->pictures[picture_id].rle_remaining_len); + if (decode_rle(avctx, sub, rect, ctx->pictures[picture_id].rle, ctx->pictures[picture_id].rle_data_len) < 0) + return 0; + } - memcpy(sub->rects[0]->pict.data[1], ctx->clut, sub->rects[0]->nb_colors * sizeof(uint32_t)); + /* Allocate memory for colors */ + sub->rects[rect]->nb_colors = 256; + sub->rects[rect]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); + + if (!ctx->forced_subs_only || ctx->presentation.objects[rect].composition & 0x40) + memcpy(sub->rects[rect]->pict.data[1], ctx->clut, sub->rects[rect]->nb_colors * sizeof(uint32_t)); + } return 1; } @@ -468,6 +505,20 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size, return buf_size; } +#define OFFSET(x) offsetof(PGSSubContext, x) +#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM +static const AVOption options[] = { + {"forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, SD}, + { NULL }, +}; + +static const AVClass pgsdec_class = { + .class_name = "PGS subtitle decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_pgssub_decoder = { .name = "pgssub", .type = AVMEDIA_TYPE_SUBTITLE, @@ -477,4 +528,5 @@ AVCodec ff_pgssub_decoder = { .close = close_decoder, .decode = decode, .long_name = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"), + .priv_class = &pgsdec_class, }; diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c index e0bc899946..d788e6474c 100644 --- a/libavcodec/pictordec.c +++ b/libavcodec/pictordec.c @@ -2,20 +2,20 @@ * Pictor/PC Paint decoder * Copyright (c) 2010 Peter Ross <pross@xvid.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -96,6 +96,14 @@ static const uint8_t cga_mode45_index[6][4] = { [5] = { 0, 11, 12, 15 }, // mode5, high intensity }; +static av_cold int decode_init(AVCodecContext *avctx) +{ + PicContext *s = avctx->priv_data; + + avcodec_get_frame_defaults(&s->frame); + return 0; +} + static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) @@ -121,11 +129,11 @@ static int decode_frame(AVCodecContext *avctx, s->nb_planes = (tmp >> 4) + 1; bpp = bits_per_plane * s->nb_planes; if (bits_per_plane > 8 || bpp < 1 || bpp > 32) { - av_log_ask_for_sample(s, "unsupported bit depth\n"); + av_log_ask_for_sample(avctx, "unsupported bit depth\n"); return AVERROR_INVALIDDATA; } - if (bytestream2_peek_byte(&s->g) == 0xFF) { + if (bytestream2_peek_byte(&s->g) == 0xFF || bpp == 8) { bytestream2_skip(&s->g, 2); etype = bytestream2_get_le16(&s->g); esize = bytestream2_get_le16(&s->g); @@ -175,13 +183,15 @@ static int decode_frame(AVCodecContext *avctx, } } else if (etype == 4 || etype == 5) { npal = FFMIN(esize / 3, 256); - for (i = 0; i < npal; i++) + for (i = 0; i < npal; i++) { palette[i] = bytestream2_get_be24(&s->g) << 2; + palette[i] |= 0xFFU << 24 | palette[i] >> 6 & 0x30303; + } } else { if (bpp == 1) { npal = 2; - palette[0] = 0x000000; - palette[1] = 0xFFFFFF; + palette[0] = 0xFF000000; + palette[1] = 0xFFFFFFFF; } else if (bpp == 2) { npal = 4; for (i = 0; i < npal; i++) @@ -196,11 +206,11 @@ static int decode_frame(AVCodecContext *avctx, // skip remaining palette bytes bytestream2_seek(&s->g, pos_after_pal, SEEK_SET); - x = 0; y = s->height - 1; - plane = 0; if (bytestream2_get_le16(&s->g)) { - while (bytestream2_get_bytes_left(&s->g) >= 6) { + x = 0; + plane = 0; + while (y >= 0 && bytestream2_get_bytes_left(&s->g) >= 6) { int stop_size, marker, t1, t2; t1 = bytestream2_get_bytes_left(&s->g); @@ -210,7 +220,7 @@ static int decode_frame(AVCodecContext *avctx, bytestream2_skip(&s->g, 2); marker = bytestream2_get_byte(&s->g); - while (plane < s->nb_planes && + while (plane < s->nb_planes && y >= 0 && bytestream2_get_bytes_left(&s->g) > stop_size) { int run = 1; int val = bytestream2_get_byte(&s->g); @@ -225,16 +235,17 @@ static int decode_frame(AVCodecContext *avctx, if (bits_per_plane == 8) { picmemset_8bpp(s, val, run, &x, &y); - if (y < 0) - break; } else { picmemset(s, val, run, &x, &y, &plane, bits_per_plane); } } } } else { - av_log_ask_for_sample(s, "uncompressed image\n"); - return avpkt->size; + while (y >= 0 && bytestream2_get_bytes_left(&s->g) > 0) { + memcpy(s->frame.data[0] + y * s->frame.linesize[0], s->g.buffer, FFMIN(avctx->width, bytestream2_get_bytes_left(&s->g))); + bytestream2_skip(&s->g, avctx->width); + y--; + } } *data_size = sizeof(AVFrame); @@ -255,6 +266,7 @@ AVCodec ff_pictor_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = CODEC_ID_PICTOR, .priv_data_size = sizeof(PicContext), + .init = decode_init, .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, diff --git a/libavcodec/png.c b/libavcodec/png.c index 70a080e29e..ecca31e960 100644 --- a/libavcodec/png.c +++ b/libavcodec/png.c @@ -2,24 +2,23 @@ * PNG image format * Copyright (c) 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" const uint8_t ff_pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; @@ -42,7 +41,7 @@ static const uint8_t ff_png_pass_xshift[NB_PASSES] = { /* Mask to determine which pixels are valid in a pass */ const uint8_t ff_png_pass_mask[NB_PASSES] = { - 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff + 0x01, 0x01, 0x11, 0x11, 0x55, 0x55, 0xff, }; void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size) diff --git a/libavcodec/png.h b/libavcodec/png.h index b8c72eebc9..bab5224851 100644 --- a/libavcodec/png.h +++ b/libavcodec/png.h @@ -2,20 +2,20 @@ * PNG image format * Copyright (c) 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/pngdec.c b/libavcodec/pngdec.c index 801085b32b..7fc28ba756 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -2,22 +2,25 @@ * PNG image format * Copyright (c) 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 "libavutil/imgutils.h" #include "avcodec.h" #include "bytestream.h" @@ -25,7 +28,7 @@ #include "pngdsp.h" /* TODO: - * - add 2, 4 and 16 bit depth support + * - add 16 bit depth support */ #include <zlib.h> @@ -68,7 +71,7 @@ typedef struct 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, + 0xff, 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, }; /* Mask to determine which pixels to overwrite while displaying */ @@ -91,35 +94,50 @@ static void png_put_interlaced_row(uint8_t *dst, int width, 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] &= 0xFF7F>>j; dst[x >> 3] |= b << (7 - j); } if ((mask << j) & 0x80) src_x++; } break; + case 2: + src_x = 0; + for(x = 0; x < width; x++) { + int j2 = 2*(x&3); + j = (x & 7); + if ((dsp_mask << j) & 0x80) { + b = (src[src_x >> 2] >> (6 - 2*(src_x & 3))) & 3; + dst[x >> 2] &= 0xFF3F>>j2; + dst[x >> 2] |= b << (6 - j2); + } + if ((mask << j) & 0x80) + src_x++; + } + break; + case 4: + src_x = 0; + for(x = 0; x < width; x++) { + int j2 = 4*(x&1); + j = (x & 7); + if ((dsp_mask << j) & 0x80) { + b = (src[src_x >> 1] >> (4 - 4*(src_x & 1))) & 15; + dst[x >> 1] &= 0xFF0F>>j2; + dst[x >> 1] |= b << (4 - j2); + } + 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) { @@ -129,7 +147,6 @@ static void png_put_interlaced_row(uint8_t *dst, int width, if ((mask << j) & 0x80) s += bpp; } - } break; } } @@ -232,7 +249,7 @@ static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, p = last[i]; dst[i] = p + src[i]; } - if(bpp > 1 && size > 4) { + if(bpp > 2 && 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_paeth_prediction(dst+i, src+i, last+i, w-i, bpp); @@ -243,43 +260,21 @@ static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, } } -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; - } +/* This used to be called "deloco" in FFmpeg + * and is actually an inverse reversible colorspace transformation */ +#define YUV2RGB(NAME, TYPE) \ +static void deloco_ ## NAME(TYPE *dst, int size, int alpha) \ +{ \ + int i; \ + for (i = 0; i < size; i += 3 + alpha) { \ + int g = dst [i+1]; \ + dst[i+0] += g; \ + dst[i+2] += g; \ + } \ } -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; - } -} +YUV2RGB(rgb8, uint8_t) +YUV2RGB(rgb16, uint16_t) /* process exactly one decompressed row */ static void png_handle_row(PNGDecContext *s) @@ -289,14 +284,6 @@ static void png_handle_row(PNGDecContext *s) 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 @@ -304,17 +291,28 @@ static void png_handle_row(PNGDecContext *s) 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); + if (s->filter_type == PNG_FILTER_TYPE_LOCO && s->y > 0) { + if (s->bit_depth == 16) { + deloco_rgb16((uint16_t *)(ptr - s->image_linesize), s->row_size / 2, + s->color_type == PNG_COLOR_TYPE_RGB_ALPHA); + } else { + deloco_rgb8(ptr - s->image_linesize, s->row_size, + s->color_type == PNG_COLOR_TYPE_RGB_ALPHA); + } + } 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); + if (s->filter_type == PNG_FILTER_TYPE_LOCO) { + if (s->bit_depth == 16) { + deloco_rgb16((uint16_t *)ptr, s->row_size / 2, + s->color_type == PNG_COLOR_TYPE_RGB_ALPHA); + } else { + deloco_rgb8(ptr, s->row_size, + s->color_type == PNG_COLOR_TYPE_RGB_ALPHA); + } + } } } else { got_line = 0; @@ -331,12 +329,12 @@ static void png_handle_row(PNGDecContext *s) 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) { + memset(s->last_row, 0, s->row_size); for(;;) { if (s->pass == NB_PASSES - 1) { s->state |= PNG_ALLIMAGE; @@ -431,7 +429,8 @@ static int decode_frame(AVCodecContext *avctx, goto fail; tag32 = bytestream_get_be32(&s->bytestream); tag = av_bswap32(tag32); - av_dlog(avctx, "png: tag=%c%c%c%c length=%u\n", + if (avctx->debug & FF_DEBUG_STARTCODE) + av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n", (tag & 0xff), ((tag >> 8) & 0xff), ((tag >> 16) & 0xff), @@ -453,7 +452,8 @@ static int decode_frame(AVCodecContext *avctx, s->interlace_type = *s->bytestream++; s->bytestream += 4; /* crc */ s->state |= PNG_IHDR; - av_dlog(avctx, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n", + if (avctx->debug & FF_DEBUG_PICT_INFO) + 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); break; @@ -470,13 +470,13 @@ static int decode_frame(AVCodecContext *avctx, s->bpp = (s->bits_per_pixel + 7) >> 3; s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3; - if (s->bit_depth == 8 && + if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) && s->color_type == PNG_COLOR_TYPE_RGB) { avctx->pix_fmt = PIX_FMT_RGB24; - } else if (s->bit_depth == 8 && + } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) && s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - avctx->pix_fmt = PIX_FMT_RGB32; - } else if (s->bit_depth == 8 && + avctx->pix_fmt = PIX_FMT_RGBA; + } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) && s->color_type == PNG_COLOR_TYPE_GRAY) { avctx->pix_fmt = PIX_FMT_GRAY8; } else if (s->bit_depth == 16 && @@ -485,20 +485,26 @@ static int decode_frame(AVCodecContext *avctx, } else if (s->bit_depth == 16 && s->color_type == PNG_COLOR_TYPE_RGB) { avctx->pix_fmt = PIX_FMT_RGB48BE; - } else if (s->bit_depth == 1 && - s->color_type == PNG_COLOR_TYPE_GRAY) { - avctx->pix_fmt = PIX_FMT_MONOBLACK; + } else if (s->bit_depth == 16 && + s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { + avctx->pix_fmt = PIX_FMT_RGBA64BE; } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { avctx->pix_fmt = PIX_FMT_PAL8; - } else if (s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - avctx->pix_fmt = PIX_FMT_Y400A; + } else if (s->bit_depth == 1) { + avctx->pix_fmt = PIX_FMT_MONOBLACK; + } else if (s->bit_depth == 8 && + s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + avctx->pix_fmt = PIX_FMT_GRAY8A; } else { + av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d " + "and color type %d\n", + s->bit_depth, s->color_type); goto fail; } if(p->data[0]) avctx->release_buffer(avctx, p); - p->reference= 0; + p->reference= 3; if(avctx->get_buffer(avctx, p) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); goto fail; @@ -522,7 +528,7 @@ static int decode_frame(AVCodecContext *avctx, 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) + if (avctx->pix_fmt == PIX_FMT_PAL8) 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); @@ -599,6 +605,65 @@ static int decode_frame(AVCodecContext *avctx, } } exit_loop: + + if(s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){ + int i, j; + uint8_t *pd = s->current_picture->data[0]; + for(j=0; j < s->height; j++) { + for(i=s->width/8-1; i>=0; i--) { + pd[8*i+7]= pd[i] &1; + pd[8*i+6]= (pd[i]>>1)&1; + pd[8*i+5]= (pd[i]>>2)&1; + pd[8*i+4]= (pd[i]>>3)&1; + pd[8*i+3]= (pd[i]>>4)&1; + pd[8*i+2]= (pd[i]>>5)&1; + pd[8*i+1]= (pd[i]>>6)&1; + pd[8*i+0]= pd[i]>>7; + } + pd += s->image_linesize; + } + } + if(s->bits_per_pixel == 2){ + int i, j; + uint8_t *pd = s->current_picture->data[0]; + for(j=0; j < s->height; j++) { + if (s->color_type == PNG_COLOR_TYPE_PALETTE){ + for(i=s->width/4-1; i>=0; i--) { + pd[4*i+3]= pd[i] &3; + pd[4*i+2]= (pd[i]>>2)&3; + pd[4*i+1]= (pd[i]>>4)&3; + pd[4*i+0]= pd[i]>>6; + } + } else { + for(i=s->width/4-1; i>=0; i--) { + pd[4*i+3]= ( pd[i] &3)*0x55; + pd[4*i+2]= ((pd[i]>>2)&3)*0x55; + pd[4*i+1]= ((pd[i]>>4)&3)*0x55; + pd[4*i+0]= ( pd[i]>>6 )*0x55; + } + } + pd += s->image_linesize; + } + } + if(s->bits_per_pixel == 4){ + int i, j; + uint8_t *pd = s->current_picture->data[0]; + for(j=0; j < s->height; j++) { + if (s->color_type == PNG_COLOR_TYPE_PALETTE){ + for(i=s->width/2-1; i>=0; i--) { + pd[2*i+1]= pd[i]&15; + pd[2*i+0]= pd[i]>>4; + } + } else { + for(i=s->width/2-1; i>=0; i--) { + pd[2*i+1]= (pd[i]&15)*0x11; + pd[2*i+0]= (pd[i]>>4)*0x11; + } + } + pd += s->image_linesize; + } + } + /* handle p-frames only if a predecessor frame is available */ if(s->last_picture->data[0] != NULL) { if(!(avpkt->flags & AV_PKT_FLAG_KEY)) { @@ -632,13 +697,15 @@ static int decode_frame(AVCodecContext *avctx, goto the_end; } -static av_cold int png_dec_init(AVCodecContext *avctx){ +static av_cold int png_dec_init(AVCodecContext *avctx) +{ PNGDecContext *s = avctx->priv_data; s->current_picture = &s->picture1; s->last_picture = &s->picture2; avcodec_get_frame_defaults(&s->picture1); avcodec_get_frame_defaults(&s->picture2); + ff_pngdsp_init(&s->dsp); return 0; diff --git a/libavcodec/pngdsp.c b/libavcodec/pngdsp.c index d40bf9c47d..75ec996ca1 100644 --- a/libavcodec/pngdsp.c +++ b/libavcodec/pngdsp.c @@ -2,20 +2,20 @@ * PNG image format * Copyright (c) 2008 Loren Merrit <lorenm@u.washington.edu> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/pngdsp.h b/libavcodec/pngdsp.h index 98d29a8a2f..f89a93a45a 100644 --- a/libavcodec/pngdsp.h +++ b/libavcodec/pngdsp.h @@ -26,8 +26,8 @@ typedef struct PNGDSPContext { void (*add_bytes_l2)(uint8_t *dst /* align 16 */, - uint8_t *src1 /* align 16 */, - uint8_t *src2 /* align 16 */, int w); + uint8_t *src1, + uint8_t *src2, int w); /* this might write to dst[w] */ void (*add_paeth_prediction)(uint8_t *dst, uint8_t *src, diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c index 9325348443..5933bbb38a 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -2,20 +2,20 @@ * PNG image format * Copyright (c) 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" @@ -172,23 +172,6 @@ static uint8_t *png_choose_filter(PNGEncContext *s, uint8_t *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) { @@ -239,7 +222,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, 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; @@ -252,7 +234,15 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); switch(avctx->pix_fmt) { - case PIX_FMT_RGB32: + case PIX_FMT_RGBA64BE: + bit_depth = 16; + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + break; + case PIX_FMT_RGB48BE: + bit_depth = 16; + color_type = PNG_COLOR_TYPE_RGB; + break; + case PIX_FMT_RGBA: bit_depth = 8; color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; @@ -260,10 +250,18 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, bit_depth = 8; color_type = PNG_COLOR_TYPE_RGB; break; + case PIX_FMT_GRAY16BE: + bit_depth = 16; + color_type = PNG_COLOR_TYPE_GRAY; + break; case PIX_FMT_GRAY8: bit_depth = 8; color_type = PNG_COLOR_TYPE_GRAY; break; + case PIX_FMT_GRAY8A: + bit_depth = 8; + color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + break; case PIX_FMT_MONOBLACK: bit_depth = 1; color_type = PNG_COLOR_TYPE_GRAY; @@ -297,12 +295,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, 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) { + if (is_progressive) { top_buf = av_malloc(row_size + 1); if (!top_buf) goto fail; @@ -336,7 +329,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, for(i = 0; i < 256; i++) { v = palette[i]; alpha = v >> 24; - if (alpha && alpha != 0xff) + if (alpha != 0xff) has_alpha = 1; *alpha_ptr++ = alpha; bytestream_put_be24(&ptr, v); @@ -363,10 +356,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, 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); @@ -381,11 +370,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, 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; @@ -413,7 +397,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, the_end: av_free(crow_base); av_free(progressive_buf); - av_free(rgba_buf); av_free(top_buf); deflateEnd(&s->zstream); return ret; @@ -443,6 +426,11 @@ AVCodec ff_png_encoder = { .priv_data_size = sizeof(PNGEncContext), .init = png_enc_init, .encode = encode_frame, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_MONOBLACK, PIX_FMT_NONE}, + .pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, + PIX_FMT_RGB48BE, PIX_FMT_RGBA64BE, + PIX_FMT_PAL8, + PIX_FMT_GRAY8, PIX_FMT_GRAY8A, + PIX_FMT_GRAY16BE, + PIX_FMT_MONOBLACK, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("PNG image"), }; diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c index f6e6d53ec9..103408cad6 100644 --- a/libavcodec/pnm.c +++ b/libavcodec/pnm.c @@ -2,20 +2,20 @@ * PNM image format * Copyright (c) 2002, 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -109,21 +109,30 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) avctx->width = w; avctx->height = h; + s->maxval = maxval; if (depth == 1) { - if (maxval == 1) + if (maxval == 1) { avctx->pix_fmt = PIX_FMT_MONOWHITE; - else + } else if (maxval == 255) { avctx->pix_fmt = PIX_FMT_GRAY8; + } else { + avctx->pix_fmt = PIX_FMT_GRAY16BE; + } + } else if (depth == 2) { + if (maxval == 255) + avctx->pix_fmt = PIX_FMT_GRAY8A; } else if (depth == 3) { if (maxval < 256) { avctx->pix_fmt = PIX_FMT_RGB24; } else { - av_log(avctx, AV_LOG_ERROR, "16-bit components are only supported for grayscale\n"); - avctx->pix_fmt = PIX_FMT_NONE; - return -1; + avctx->pix_fmt = PIX_FMT_RGB48BE; } } else if (depth == 4) { - avctx->pix_fmt = PIX_FMT_RGB32; + if (maxval < 256) { + avctx->pix_fmt = PIX_FMT_RGBA; + } else { + avctx->pix_fmt = PIX_FMT_RGBA64BE; + } } else { return -1; } @@ -137,7 +146,7 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s) return -1; pnm_get(s, buf1, sizeof(buf1)); avctx->height = atoi(buf1); - if(av_image_check_size(avctx->width, avctx->height, 0, avctx)) + if(avctx->height <= 0 || av_image_check_size(avctx->width, avctx->height, 0, avctx)) return -1; if (avctx->pix_fmt != PIX_FMT_MONOWHITE) { pnm_get(s, buf1, sizeof(buf1)); diff --git a/libavcodec/pnm.h b/libavcodec/pnm.h index 702921fbdf..ac4b1084fb 100644 --- a/libavcodec/pnm.h +++ b/libavcodec/pnm.h @@ -2,20 +2,20 @@ * PNM image format * Copyright (c) 2002, 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/pnm_parser.c b/libavcodec/pnm_parser.c index 89f98715bd..658469ed32 100644 --- a/libavcodec/pnm_parser.c +++ b/libavcodec/pnm_parser.c @@ -2,20 +2,20 @@ * PNM image parser * Copyright (c) 2002, 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/pnmdec.c b/libavcodec/pnmdec.c index e0e9f66551..e6c91ef996 100644 --- a/libavcodec/pnmdec.c +++ b/libavcodec/pnmdec.c @@ -2,25 +2,24 @@ * PNM image format * Copyright (c) 2002, 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 "put_bits.h" #include "pnm.h" @@ -33,7 +32,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, PNMContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = (AVFrame*)&s->picture; - int i, j, n, linesize, h, upgrade = 0; + int i, j, n, linesize, h, upgrade = 0, is_mono = 0; unsigned char *ptr; int components, sample_len; @@ -58,11 +57,21 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, switch (avctx->pix_fmt) { default: return -1; + case PIX_FMT_RGBA64BE: + n = avctx->width * 8; + components=4; + sample_len=16; + goto do_read; case PIX_FMT_RGB48BE: n = avctx->width * 6; components=3; sample_len=16; goto do_read; + case PIX_FMT_RGBA: + n = avctx->width * 4; + components=4; + sample_len=8; + goto do_read; case PIX_FMT_RGB24: n = avctx->width * 3; components=3; @@ -75,6 +84,11 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, if (s->maxval < 255) upgrade = 1; goto do_read; + case PIX_FMT_GRAY8A: + n = avctx->width * 2; + components=2; + sample_len=8; + goto do_read; case PIX_FMT_GRAY16BE: case PIX_FMT_GRAY16LE: n = avctx->width * 2; @@ -88,6 +102,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, n = (avctx->width + 7) >> 3; components=1; sample_len=1; + is_mono = 1; do_read: ptr = p->data[0]; linesize = p->linesize[0]; @@ -104,10 +119,16 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, s->bytestream++; if(s->bytestream >= s->bytestream_end) return -1; - do{ - v= 10*v + c; - c= (*s->bytestream++) - '0'; - }while(c <= 9); + if (is_mono) { + /* read a single digit */ + v = (*s->bytestream++) - '0'; + } else { + /* read a sequence of digits */ + do { + v = 10*v + c; + c = (*s->bytestream++) - '0'; + } while (c <= 9); + } put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval); } flush_put_bits(&pb); @@ -161,24 +182,6 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, } } 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); diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c index a27a278d47..e31bfee520 100644 --- a/libavcodec/pnmenc.c +++ b/libavcodec/pnmenc.c @@ -2,25 +2,24 @@ * PNM image format * Copyright (c) 2002, 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" diff --git a/libavcodec/ppc/asm.S b/libavcodec/ppc/asm.S index 4d4285b6d3..bbbf8a4a66 100644 --- a/libavcodec/ppc/asm.S +++ b/libavcodec/ppc/asm.S @@ -1,20 +1,20 @@ /* * Copyright (c) 2009 Loren Merritt * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/dsputil_altivec.c b/libavcodec/ppc/dsputil_altivec.c index 7ab533600d..7f36fa9aad 100644 --- a/libavcodec/ppc/dsputil_altivec.c +++ b/libavcodec/ppc/dsputil_altivec.c @@ -3,20 +3,20 @@ * Copyright (c) 2002 Dieter Shirley * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/dsputil_altivec.h b/libavcodec/ppc/dsputil_altivec.h index abf2dd3e0a..4147eec823 100644 --- a/libavcodec/ppc/dsputil_altivec.h +++ b/libavcodec/ppc/dsputil_altivec.h @@ -3,20 +3,20 @@ * Copyright (c) 2002 Dieter Shirley * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/dsputil_ppc.c b/libavcodec/ppc/dsputil_ppc.c index 24b12ee2ae..568f072b54 100644 --- a/libavcodec/ppc/dsputil_ppc.c +++ b/libavcodec/ppc/dsputil_ppc.c @@ -3,20 +3,20 @@ * Copyright (c) 2002 Dieter Shirley * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -146,6 +146,14 @@ static void prefetch_ppc(void *mem, int stride, int h) void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx) { const int high_bit_depth = avctx->bits_per_raw_sample > 8; + int mm_flags = av_get_cpu_flags(); + + if (avctx->dsp_mask) { + if (avctx->dsp_mask & AV_CPU_FLAG_FORCE) + mm_flags |= (avctx->dsp_mask & 0xffff); + else + mm_flags &= ~(avctx->dsp_mask & 0xffff); + } // Common optimizations whether AltiVec is available or not c->prefetch = prefetch_ppc; @@ -165,7 +173,7 @@ void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx) #if HAVE_ALTIVEC if(CONFIG_H264_DECODER) dsputil_h264_init_ppc(c, avctx); - if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) { + if (mm_flags & AV_CPU_FLAG_ALTIVEC) { dsputil_init_altivec(c, avctx); float_init_altivec(c, avctx); int_init_altivec(c, avctx); diff --git a/libavcodec/ppc/fdct_altivec.c b/libavcodec/ppc/fdct_altivec.c index 2644c96789..1cc6f89f4d 100644 --- a/libavcodec/ppc/fdct_altivec.c +++ b/libavcodec/ppc/fdct_altivec.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2003 James Klicman <james@klicman.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/fft_altivec.c b/libavcodec/ppc/fft_altivec.c index 39830b29a0..e171665b37 100644 --- a/libavcodec/ppc/fft_altivec.c +++ b/libavcodec/ppc/fft_altivec.c @@ -3,20 +3,20 @@ * AltiVec-enabled * Copyright (c) 2009 Loren Merritt * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavcodec/fft.h" diff --git a/libavcodec/ppc/fft_altivec_s.S b/libavcodec/ppc/fft_altivec_s.S index 958d7df0ee..16ce838c97 100644 --- a/libavcodec/ppc/fft_altivec_s.S +++ b/libavcodec/ppc/fft_altivec_s.S @@ -5,20 +5,20 @@ * This algorithm (though not any of the implementation details) is * based on libdjbfft by D. J. Bernstein. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/float_altivec.c b/libavcodec/ppc/float_altivec.c index e4010694a2..ba97cbfd3b 100644 --- a/libavcodec/ppc/float_altivec.c +++ b/libavcodec/ppc/float_altivec.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/fmtconvert_altivec.c b/libavcodec/ppc/fmtconvert_altivec.c index b1eaf9b482..30de0e637f 100644 --- a/libavcodec/ppc/fmtconvert_altivec.c +++ b/libavcodec/ppc/fmtconvert_altivec.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/gmc_altivec.c b/libavcodec/ppc/gmc_altivec.c index 0ed70ab83b..0e93c337f7 100644 --- a/libavcodec/ppc/gmc_altivec.c +++ b/libavcodec/ppc/gmc_altivec.c @@ -3,20 +3,20 @@ * AltiVec-enabled * Copyright (c) 2003 Romain Dolbeau <romain@dolbeau.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/h264_altivec.c b/libavcodec/ppc/h264_altivec.c index c8baee456e..9b3622a673 100644 --- a/libavcodec/ppc/h264_altivec.c +++ b/libavcodec/ppc/h264_altivec.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/h264_template_altivec.c b/libavcodec/ppc/h264_template_altivec.c index 2a8f4bf672..2573e9c6f7 100644 --- a/libavcodec/ppc/h264_template_altivec.c +++ b/libavcodec/ppc/h264_template_altivec.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/idct_altivec.c b/libavcodec/ppc/idct_altivec.c index 068cf42396..f1c95c1557 100644 --- a/libavcodec/ppc/idct_altivec.c +++ b/libavcodec/ppc/idct_altivec.c @@ -1,31 +1,31 @@ /* * Copyright (c) 2001 Michel Lespinasse * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * NOTE: This code is based on GPL code from the libmpeg2 project. The * author, Michel Lespinasses, has given explicit permission to release - * under LGPL as part of Libav. + * under LGPL as part of FFmpeg. */ /* - * Libav integration by Dieter Shirley + * FFmpeg integration by Dieter Shirley * * This file is a direct copy of the AltiVec IDCT module from the libmpeg2 * project. I've deleted all of the libmpeg2-specific code, renamed the diff --git a/libavcodec/ppc/int_altivec.c b/libavcodec/ppc/int_altivec.c index 25cbb8f771..61c18c8154 100644 --- a/libavcodec/ppc/int_altivec.c +++ b/libavcodec/ppc/int_altivec.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2007 Luca Barbato <lu_zero@gentoo.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/mathops.h b/libavcodec/ppc/mathops.h index 34ddb11800..dbd714fcd4 100644 --- a/libavcodec/ppc/mathops.h +++ b/libavcodec/ppc/mathops.h @@ -3,20 +3,20 @@ * Copyright (c) 2001, 2002 Fabrice Bellard * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/mpegaudiodec_altivec.c b/libavcodec/ppc/mpegaudiodec_altivec.c index 5df0fdafe4..2de5dd133a 100644 --- a/libavcodec/ppc/mpegaudiodec_altivec.c +++ b/libavcodec/ppc/mpegaudiodec_altivec.c @@ -2,20 +2,20 @@ * Altivec optimized MP3 decoding functions * Copyright (c) 2010 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c index a033cd7372..297e7fefce 100644 --- a/libavcodec/ppc/mpegvideo_altivec.c +++ b/libavcodec/ppc/mpegvideo_altivec.c @@ -4,20 +4,20 @@ * dct_unquantize_h263_altivec: * Copyright (c) 2003 Romain Dolbeau <romain@dolbeau.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -267,8 +267,13 @@ static int dct_quantize_altivec(MpegEncContext* s, baseVector = vec_cts(vec_splat(row0, 0), 0); vec_ste(baseVector, 0, &oldBaseValue); - qmat = (vector signed int*)s->q_intra_matrix[qscale]; - biasAddr = &s->intra_quant_bias; + if(n<4){ + qmat = (vector signed int*)s->q_intra_matrix[qscale]; + biasAddr = &s->intra_quant_bias; + }else{ + qmat = (vector signed int*)s->q_chroma_intra_matrix[qscale]; + biasAddr = &s->intra_quant_bias; + } } else { qmat = (vector signed int*)s->q_inter_matrix[qscale]; biasAddr = &s->inter_quant_bias; diff --git a/libavcodec/ppc/regs.h b/libavcodec/ppc/regs.h index 2edd639531..63861f28fb 100644 --- a/libavcodec/ppc/regs.h +++ b/libavcodec/ppc/regs.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/types_altivec.h b/libavcodec/ppc/types_altivec.h index defa20e243..36b6e1f388 100644 --- a/libavcodec/ppc/types_altivec.h +++ b/libavcodec/ppc/types_altivec.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2006 Guillaume Poirier <gpoirier@mplayerhq.hu> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/util_altivec.h b/libavcodec/ppc/util_altivec.h index 19ea9626db..6800348570 100644 --- a/libavcodec/ppc/util_altivec.h +++ b/libavcodec/ppc/util_altivec.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c index 307e0e9f6b..69670619da 100644 --- a/libavcodec/ppc/vc1dsp_altivec.c +++ b/libavcodec/ppc/vc1dsp_altivec.c @@ -2,20 +2,20 @@ * VC-1 and WMV3 decoder - DSP functions AltiVec-optimized * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c index bbe9170edf..b0509d8b64 100644 --- a/libavcodec/ppc/vp3dsp_altivec.c +++ b/libavcodec/ppc/vp3dsp_altivec.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2009 David Conrad * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c index bdda7df505..28d23cb9aa 100644 --- a/libavcodec/ppc/vp8dsp_altivec.c +++ b/libavcodec/ppc/vp8dsp_altivec.c @@ -3,20 +3,20 @@ * * Copyright (C) 2010 David Conrad * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/proresdec.h b/libavcodec/proresdec.h new file mode 100644 index 0000000000..b3a81d5044 --- /dev/null +++ b/libavcodec/proresdec.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010-2011 Maxim Poliakovski + * Copyright (c) 2010-2011 Elvis Presley + * + * 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; + * version 2 of the License. + * + * 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 + */ + +#ifndef AVCODEC_PRORESDEC_H +#define AVCODEC_PRORESDEC_H + +#include "dsputil.h" +#include "proresdsp.h" + +typedef struct { + const uint8_t *data; + unsigned mb_x; + unsigned mb_y; + unsigned mb_count; + unsigned data_size; +} SliceContext; + +typedef struct { + DSPContext dsp; + ProresDSPContext prodsp; + AVFrame frame; + int frame_type; ///< 0 = progressive, 1 = tff, 2 = bff + uint8_t qmat_luma[64]; + uint8_t qmat_chroma[64]; + SliceContext *slices; + int slice_count; ///< number of slices in the current picture + unsigned mb_width; ///< width of the current picture in mb + unsigned mb_height; ///< height of the current picture in mb + uint8_t progressive_scan[64]; + uint8_t interlaced_scan[64]; + const uint8_t *scan; + int first_field; +} ProresContext; + +#endif /* AVCODEC_PRORESDEC_H */ diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c new file mode 100644 index 0000000000..9f801e447a --- /dev/null +++ b/libavcodec/proresdec2.c @@ -0,0 +1,594 @@ +/* + * Copyright (c) 2010-2011 Maxim Poliakovski + * Copyright (c) 2010-2011 Elvis Presley + * + * 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 + * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy), 'ap4h' (4444) + */ + +//#define DEBUG + +#define LONG_BITSTREAM_READER + +#include "avcodec.h" +#include "get_bits.h" +#include "simple_idct.h" +#include "proresdec.h" + +static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64]) +{ + int i; + for (i = 0; i < 64; i++) + dst[i] = permutation[src[i]]; +} + +static const uint8_t progressive_scan[64] = { + 0, 1, 8, 9, 2, 3, 10, 11, + 16, 17, 24, 25, 18, 19, 26, 27, + 4, 5, 12, 20, 13, 6, 7, 14, + 21, 28, 29, 22, 15, 23, 30, 31, + 32, 33, 40, 48, 41, 34, 35, 42, + 49, 56, 57, 50, 43, 36, 37, 44, + 51, 58, 59, 52, 45, 38, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + +static const uint8_t interlaced_scan[64] = { + 0, 8, 1, 9, 16, 24, 17, 25, + 2, 10, 3, 11, 18, 26, 19, 27, + 32, 40, 33, 34, 41, 48, 56, 49, + 42, 35, 43, 50, 57, 58, 51, 59, + 4, 12, 5, 6, 13, 20, 28, 21, + 14, 7, 15, 22, 29, 36, 44, 37, + 30, 23, 31, 38, 45, 52, 60, 53, + 46, 39, 47, 54, 61, 62, 55, 63, +}; + +static av_cold int decode_init(AVCodecContext *avctx) +{ + ProresContext *ctx = avctx->priv_data; + uint8_t idct_permutation[64]; + + avctx->bits_per_raw_sample = 10; + + dsputil_init(&ctx->dsp, avctx); + ff_proresdsp_init(&ctx->prodsp, avctx); + + avctx->coded_frame = &ctx->frame; + ctx->frame.type = AV_PICTURE_TYPE_I; + ctx->frame.key_frame = 1; + + ff_init_scantable_permutation(idct_permutation, + ctx->prodsp.idct_permutation_type); + + permute(ctx->progressive_scan, progressive_scan, idct_permutation); + permute(ctx->interlaced_scan, interlaced_scan, idct_permutation); + + return 0; +} + +static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, + const int data_size, AVCodecContext *avctx) +{ + int hdr_size, width, height, flags; + int version; + const uint8_t *ptr; + + hdr_size = AV_RB16(buf); + av_dlog(avctx, "header size %d\n", hdr_size); + if (hdr_size > data_size) { + av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n"); + return -1; + } + + version = AV_RB16(buf + 2); + av_dlog(avctx, "%.4s version %d\n", buf+4, version); + if (version > 1) { + av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version); + return -1; + } + + width = AV_RB16(buf + 8); + height = AV_RB16(buf + 10); + if (width != avctx->width || height != avctx->height) { + av_log(avctx, AV_LOG_ERROR, "picture resolution change: %dx%d -> %dx%d\n", + avctx->width, avctx->height, width, height); + return -1; + } + + ctx->frame_type = (buf[12] >> 2) & 3; + + av_dlog(avctx, "frame type %d\n", ctx->frame_type); + + if (ctx->frame_type == 0) { + ctx->scan = ctx->progressive_scan; // permuted + } else { + ctx->scan = ctx->interlaced_scan; // permuted + ctx->frame.interlaced_frame = 1; + ctx->frame.top_field_first = ctx->frame_type == 1; + } + + avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? PIX_FMT_YUV444P10 : PIX_FMT_YUV422P10; + + ptr = buf + 20; + flags = buf[19]; + av_dlog(avctx, "flags %x\n", flags); + + if (flags & 2) { + permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr); + ptr += 64; + } else { + memset(ctx->qmat_luma, 4, 64); + } + + if (flags & 1) { + permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr); + } else { + memset(ctx->qmat_chroma, 4, 64); + } + + return hdr_size; +} + +static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, const int buf_size) +{ + ProresContext *ctx = avctx->priv_data; + int i, hdr_size, slice_count; + unsigned pic_data_size; + int log2_slice_mb_width, log2_slice_mb_height; + int slice_mb_count, mb_x, mb_y; + const uint8_t *data_ptr, *index_ptr; + + hdr_size = buf[0] >> 3; + if (hdr_size < 8 || hdr_size > buf_size) { + av_log(avctx, AV_LOG_ERROR, "error, wrong picture header size\n"); + return -1; + } + + pic_data_size = AV_RB32(buf + 1); + if (pic_data_size > buf_size) { + av_log(avctx, AV_LOG_ERROR, "error, wrong picture data size\n"); + return -1; + } + + log2_slice_mb_width = buf[7] >> 4; + log2_slice_mb_height = buf[7] & 0xF; + if (log2_slice_mb_width > 3 || log2_slice_mb_height) { + av_log(avctx, AV_LOG_ERROR, "unsupported slice resolution: %dx%d\n", + 1 << log2_slice_mb_width, 1 << log2_slice_mb_height); + return -1; + } + + ctx->mb_width = (avctx->width + 15) >> 4; + if (ctx->frame_type) + ctx->mb_height = (avctx->height + 31) >> 5; + else + ctx->mb_height = (avctx->height + 15) >> 4; + + slice_count = AV_RB16(buf + 5); + + if (ctx->slice_count != slice_count || !ctx->slices) { + av_freep(&ctx->slices); + ctx->slices = av_mallocz(slice_count * sizeof(*ctx->slices)); + if (!ctx->slices) + return AVERROR(ENOMEM); + ctx->slice_count = slice_count; + } + + if (!slice_count) + return AVERROR(EINVAL); + + if (hdr_size + slice_count*2 > buf_size) { + av_log(avctx, AV_LOG_ERROR, "error, wrong slice count\n"); + return -1; + } + + // parse slice information + index_ptr = buf + hdr_size; + data_ptr = index_ptr + slice_count*2; + + slice_mb_count = 1 << log2_slice_mb_width; + mb_x = 0; + mb_y = 0; + + for (i = 0; i < slice_count; i++) { + SliceContext *slice = &ctx->slices[i]; + + slice->data = data_ptr; + data_ptr += AV_RB16(index_ptr + i*2); + + while (ctx->mb_width - mb_x < slice_mb_count) + slice_mb_count >>= 1; + + slice->mb_x = mb_x; + slice->mb_y = mb_y; + slice->mb_count = slice_mb_count; + slice->data_size = data_ptr - slice->data; + + if (slice->data_size < 6) { + av_log(avctx, AV_LOG_ERROR, "error, wrong slice data size\n"); + return -1; + } + + mb_x += slice_mb_count; + if (mb_x == ctx->mb_width) { + slice_mb_count = 1 << log2_slice_mb_width; + mb_x = 0; + mb_y++; + } + if (data_ptr > buf + buf_size) { + av_log(avctx, AV_LOG_ERROR, "error, slice out of bounds\n"); + return -1; + } + } + + if (mb_x || mb_y != ctx->mb_height) { + av_log(avctx, AV_LOG_ERROR, "error wrong mb count y %d h %d\n", + mb_y, ctx->mb_height); + return -1; + } + + return pic_data_size; +} + +#define DECODE_CODEWORD(val, codebook) \ + do { \ + unsigned int rice_order, exp_order, switch_bits; \ + unsigned int q, buf, bits; \ + \ + UPDATE_CACHE(re, gb); \ + buf = GET_CACHE(re, gb); \ + \ + /* number of bits to switch between rice and exp golomb */ \ + switch_bits = codebook & 3; \ + rice_order = codebook >> 5; \ + exp_order = (codebook >> 2) & 7; \ + \ + q = 31 - av_log2(buf); \ + \ + if (q > switch_bits) { /* exp golomb */ \ + bits = exp_order - switch_bits + (q<<1); \ + val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) + \ + ((switch_bits + 1) << rice_order); \ + SKIP_BITS(re, gb, bits); \ + } else if (rice_order) { \ + SKIP_BITS(re, gb, q+1); \ + val = (q << rice_order) + SHOW_UBITS(re, gb, rice_order); \ + SKIP_BITS(re, gb, rice_order); \ + } else { \ + val = q; \ + SKIP_BITS(re, gb, q+1); \ + } \ + } while (0) + +#define TOSIGNED(x) (((x) >> 1) ^ (-((x) & 1))) + +#define FIRST_DC_CB 0xB8 + +static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70}; + +static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out, + int blocks_per_slice) +{ + DCTELEM prev_dc; + int code, i, sign; + + OPEN_READER(re, gb); + + DECODE_CODEWORD(code, FIRST_DC_CB); + prev_dc = TOSIGNED(code); + out[0] = prev_dc; + + out += 64; // dc coeff for the next block + + code = 5; + sign = 0; + for (i = 1; i < blocks_per_slice; i++, out += 64) { + DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)]); + if(code) sign ^= -(code & 1); + else sign = 0; + prev_dc += (((code + 1) >> 1) ^ sign) - sign; + out[0] = prev_dc; + } + CLOSE_READER(re, gb); +} + +// adaptive codebook switching lut according to previous run/level values +static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C }; +static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C }; + +static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb, + DCTELEM *out, int blocks_per_slice) +{ + ProresContext *ctx = avctx->priv_data; + int block_mask, sign; + unsigned pos, run, level; + int max_coeffs, i, bits_left; + int log2_block_count = av_log2(blocks_per_slice); + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); \ + run = 4; + level = 2; + + max_coeffs = 64 << log2_block_count; + block_mask = blocks_per_slice - 1; + + for (pos = block_mask;;) { + bits_left = gb->size_in_bits - re_index; + if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left))) + break; + + DECODE_CODEWORD(run, run_to_cb[FFMIN(run, 15)]); + pos += run + 1; + if (pos >= max_coeffs) { + av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs); + return; + } + + DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)]); + level += 1; + + i = pos >> log2_block_count; + + sign = SHOW_SBITS(re, gb, 1); + SKIP_BITS(re, gb, 1); + out[((pos & block_mask) << 6) + ctx->scan[i]] = ((level ^ sign) - sign); + } + + CLOSE_READER(re, gb); +} + +static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, + uint8_t *dst, int dst_stride, + const uint8_t *buf, unsigned buf_size, + const int16_t *qmat) +{ + ProresContext *ctx = avctx->priv_data; + LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]); + DCTELEM *block; + GetBitContext gb; + int i, blocks_per_slice = slice->mb_count<<2; + + for (i = 0; i < blocks_per_slice; i++) + ctx->dsp.clear_block(blocks+(i<<6)); + + init_get_bits(&gb, buf, buf_size << 3); + + decode_dc_coeffs(&gb, blocks, blocks_per_slice); + decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice); + + block = blocks; + for (i = 0; i < slice->mb_count; i++) { + ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); + ctx->prodsp.idct_put(dst+16, dst_stride, block+(1<<6), qmat); + ctx->prodsp.idct_put(dst+8*dst_stride, dst_stride, block+(2<<6), qmat); + ctx->prodsp.idct_put(dst+8*dst_stride+16, dst_stride, block+(3<<6), qmat); + block += 4*64; + dst += 32; + } +} + +static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, + uint8_t *dst, int dst_stride, + const uint8_t *buf, unsigned buf_size, + const int16_t *qmat, int log2_blocks_per_mb) +{ + ProresContext *ctx = avctx->priv_data; + LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]); + DCTELEM *block; + GetBitContext gb; + int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb; + + for (i = 0; i < blocks_per_slice; i++) + ctx->dsp.clear_block(blocks+(i<<6)); + + init_get_bits(&gb, buf, buf_size << 3); + + decode_dc_coeffs(&gb, blocks, blocks_per_slice); + decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice); + + block = blocks; + for (i = 0; i < slice->mb_count; i++) { + for (j = 0; j < log2_blocks_per_mb; j++) { + ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat); + ctx->prodsp.idct_put(dst+8*dst_stride, dst_stride, block+(1<<6), qmat); + block += 2*64; + dst += 16; + } + } +} + +static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) +{ + ProresContext *ctx = avctx->priv_data; + SliceContext *slice = &ctx->slices[jobnr]; + const uint8_t *buf = slice->data; + AVFrame *pic = avctx->coded_frame; + int i, hdr_size, qscale, log2_chroma_blocks_per_mb; + int luma_stride, chroma_stride; + int y_data_size, u_data_size, v_data_size; + uint8_t *dest_y, *dest_u, *dest_v; + int16_t qmat_luma_scaled[64]; + int16_t qmat_chroma_scaled[64]; + int mb_x_shift; + + //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n", + // jobnr, slice->mb_count, slice->mb_x, slice->mb_y); + + // slice header + hdr_size = buf[0] >> 3; + qscale = av_clip(buf[1], 1, 224); + qscale = qscale > 128 ? qscale - 96 << 2: qscale; + y_data_size = AV_RB16(buf + 2); + u_data_size = AV_RB16(buf + 4); + v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size; + if (hdr_size > 7) v_data_size = AV_RB16(buf + 6); + + if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0 + || hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){ + av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n"); + return -1; + } + + buf += hdr_size; + + for (i = 0; i < 64; i++) { + qmat_luma_scaled [i] = ctx->qmat_luma [i] * qscale; + qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * qscale; + } + + if (ctx->frame_type == 0) { + luma_stride = pic->linesize[0]; + chroma_stride = pic->linesize[1]; + } else { + luma_stride = pic->linesize[0] << 1; + chroma_stride = pic->linesize[1] << 1; + } + + if (avctx->pix_fmt == PIX_FMT_YUV444P10) { + mb_x_shift = 5; + log2_chroma_blocks_per_mb = 2; + } else { + mb_x_shift = 4; + log2_chroma_blocks_per_mb = 1; + } + + dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); + dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); + dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); + + if (ctx->frame_type && ctx->first_field ^ ctx->frame.top_field_first) { + dest_y += pic->linesize[0]; + dest_u += pic->linesize[1]; + dest_v += pic->linesize[2]; + } + + decode_slice_luma(avctx, slice, dest_y, luma_stride, + buf, y_data_size, qmat_luma_scaled); + + if (!(avctx->flags & CODEC_FLAG_GRAY)) { + decode_slice_chroma(avctx, slice, dest_u, chroma_stride, + buf + y_data_size, u_data_size, + qmat_chroma_scaled, log2_chroma_blocks_per_mb); + decode_slice_chroma(avctx, slice, dest_v, chroma_stride, + buf + y_data_size + u_data_size, v_data_size, + qmat_chroma_scaled, log2_chroma_blocks_per_mb); + } + + return 0; +} + +static int decode_picture(AVCodecContext *avctx) +{ + ProresContext *ctx = avctx->priv_data; + int i, threads_ret[ctx->slice_count]; + + avctx->execute2(avctx, decode_slice_thread, NULL, threads_ret, ctx->slice_count); + + for (i = 0; i < ctx->slice_count; i++) + if (threads_ret[i] < 0) + return threads_ret[i]; + + return 0; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, + AVPacket *avpkt) +{ + ProresContext *ctx = avctx->priv_data; + AVFrame *frame = avctx->coded_frame; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int frame_hdr_size, pic_size; + + if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) { + av_log(avctx, AV_LOG_ERROR, "invalid frame header\n"); + return -1; + } + + ctx->first_field = 1; + + buf += 8; + buf_size -= 8; + + frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx); + if (frame_hdr_size < 0) + return -1; + + buf += frame_hdr_size; + buf_size -= frame_hdr_size; + + if (frame->data[0]) + avctx->release_buffer(avctx, frame); + + if (avctx->get_buffer(avctx, frame) < 0) + return -1; + + decode_picture: + pic_size = decode_picture_header(avctx, buf, buf_size); + if (pic_size < 0) { + av_log(avctx, AV_LOG_ERROR, "error decoding picture header\n"); + return -1; + } + + if (decode_picture(avctx)) { + av_log(avctx, AV_LOG_ERROR, "error decoding picture\n"); + return -1; + } + + buf += pic_size; + buf_size -= pic_size; + + if (ctx->frame_type && buf_size > 0 && ctx->first_field) { + ctx->first_field = 0; + goto decode_picture; + } + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = *frame; + + return avpkt->size; +} + +static av_cold int decode_close(AVCodecContext *avctx) +{ + ProresContext *ctx = avctx->priv_data; + + AVFrame *frame = avctx->coded_frame; + if (frame->data[0]) + avctx->release_buffer(avctx, frame); + av_freep(&ctx->slices); + + return 0; +} + +AVCodec ff_prores_decoder = { + .name = "prores", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_PRORES, + .priv_data_size = sizeof(ProresContext), + .init = decode_init, + .close = decode_close, + .decode = decode_frame, + .long_name = NULL_IF_CONFIG_SMALL("ProRes"), + .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS, +}; diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec_lgpl.c index 7617cb3c98..33653de71a 100644 --- a/libavcodec/proresdec.c +++ b/libavcodec/proresdec_lgpl.c @@ -106,7 +106,7 @@ static av_cold int decode_init(AVCodecContext *avctx) ctx->slice_data = NULL; avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE; - ff_proresdsp_init(&ctx->dsp); + ff_proresdsp_init(&ctx->dsp, avctx); avctx->coded_frame = &ctx->picture; avcodec_get_frame_defaults(&ctx->picture); @@ -693,8 +693,8 @@ static av_cold int decode_close(AVCodecContext *avctx) } -AVCodec ff_prores_decoder = { - .name = "prores", +AVCodec ff_prores_lgpl_decoder = { + .name = "prores_lgpl", .type = AVMEDIA_TYPE_VIDEO, .id = CODEC_ID_PRORES, .priv_data_size = sizeof(ProresContext), diff --git a/libavcodec/proresdsp.c b/libavcodec/proresdsp.c index 7e753e9dc7..739ee2b3ec 100644 --- a/libavcodec/proresdsp.c +++ b/libavcodec/proresdsp.c @@ -51,12 +51,12 @@ static void prores_idct_put_c(uint16_t *out, int linesize, DCTELEM *block, const put_pixels(out, linesize >> 1, block); } -void ff_proresdsp_init(ProresDSPContext *dsp) +void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx) { dsp->idct_put = prores_idct_put_c; dsp->idct_permutation_type = FF_NO_IDCT_PERM; - if (HAVE_MMX) ff_proresdsp_x86_init(dsp); + if (HAVE_MMX) ff_proresdsp_x86_init(dsp, avctx); ff_init_scantable_permutation(dsp->idct_permutation, dsp->idct_permutation_type); diff --git a/libavcodec/proresdsp.h b/libavcodec/proresdsp.h index 8b864faabd..7e81b0870c 100644 --- a/libavcodec/proresdsp.h +++ b/libavcodec/proresdsp.h @@ -33,8 +33,8 @@ typedef struct { void (* idct_put) (uint16_t *out, int linesize, DCTELEM *block, const int16_t *qmat); } ProresDSPContext; -void ff_proresdsp_init(ProresDSPContext *dsp); +void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx); -void ff_proresdsp_x86_init(ProresDSPContext *dsp); +void ff_proresdsp_x86_init(ProresDSPContext *dsp, AVCodecContext *avctx); #endif /* AVCODEC_PRORESDSP_H */ diff --git a/libavcodec/proresenc.c b/libavcodec/proresenc.c new file mode 100644 index 0000000000..09678a002f --- /dev/null +++ b/libavcodec/proresenc.c @@ -0,0 +1,598 @@ +/* + * Apple ProRes encoder + * + * Copyright (c) 2011 Anatoliy Wasserman + * + * 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 libavcodec/proresenc.c + * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy) + */ + +#include "avcodec.h" +#include "put_bits.h" +#include "bytestream.h" +#include "dsputil.h" + +#define DEFAULT_SLICE_MB_WIDTH 8 + +#define FF_PROFILE_PRORES_PROXY 0 +#define FF_PROFILE_PRORES_LT 1 +#define FF_PROFILE_PRORES_STANDARD 2 +#define FF_PROFILE_PRORES_HQ 3 + +static const AVProfile profiles[] = { + { FF_PROFILE_PRORES_PROXY, "apco"}, + { FF_PROFILE_PRORES_LT, "apcs"}, + { FF_PROFILE_PRORES_STANDARD, "apcn"}, + { FF_PROFILE_PRORES_HQ, "apch"}, + { FF_PROFILE_UNKNOWN } +}; + +static const int qp_start_table[4] = { 4, 1, 1, 1 }; +static const int qp_end_table[4] = { 8, 9, 6, 6 }; +static const int bitrate_table[5] = { 1000, 2100, 3500, 5400 }; + +static const uint8_t progressive_scan[64] = { + 0, 1, 8, 9, 2, 3, 10, 11, + 16, 17, 24, 25, 18, 19, 26, 27, + 4, 5, 12, 20, 13, 6, 7, 14, + 21, 28, 29, 22, 15, 23, 30, 31, + 32, 33, 40, 48, 41, 34, 35, 42, + 49, 56, 57, 50, 43, 36, 37, 44, + 51, 58, 59, 52, 45, 38, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + +static const uint8_t QMAT_LUMA[4][64] = { + { + 4, 7, 9, 11, 13, 14, 15, 63, + 7, 7, 11, 12, 14, 15, 63, 63, + 9, 11, 13, 14, 15, 63, 63, 63, + 11, 11, 13, 14, 63, 63, 63, 63, + 11, 13, 14, 63, 63, 63, 63, 63, + 13, 14, 63, 63, 63, 63, 63, 63, + 13, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63 + }, { + 4, 5, 6, 7, 9, 11, 13, 15, + 5, 5, 7, 8, 11, 13, 15, 17, + 6, 7, 9, 11, 13, 15, 15, 17, + 7, 7, 9, 11, 13, 15, 17, 19, + 7, 9, 11, 13, 14, 16, 19, 23, + 9, 11, 13, 14, 16, 19, 23, 29, + 9, 11, 13, 15, 17, 21, 28, 35, + 11, 13, 16, 17, 21, 28, 35, 41 + }, { + 4, 4, 5, 5, 6, 7, 7, 9, + 4, 4, 5, 6, 7, 7, 9, 9, + 5, 5, 6, 7, 7, 9, 9, 10, + 5, 5, 6, 7, 7, 9, 9, 10, + 5, 6, 7, 7, 8, 9, 10, 12, + 6, 7, 7, 8, 9, 10, 12, 15, + 6, 7, 7, 9, 10, 11, 14, 17, + 7, 7, 9, 10, 11, 14, 17, 21 + }, { + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 5, + 4, 4, 4, 4, 4, 4, 5, 5, + 4, 4, 4, 4, 4, 5, 5, 6, + 4, 4, 4, 4, 5, 5, 6, 7, + 4, 4, 4, 4, 5, 6, 7, 7 + } +}; + +static const uint8_t QMAT_CHROMA[4][64] = { + { + 4, 7, 9, 11, 13, 14, 63, 63, + 7, 7, 11, 12, 14, 63, 63, 63, + 9, 11, 13, 14, 63, 63, 63, 63, + 11, 11, 13, 14, 63, 63, 63, 63, + 11, 13, 14, 63, 63, 63, 63, 63, + 13, 14, 63, 63, 63, 63, 63, 63, + 13, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63 + }, { + 4, 5, 6, 7, 9, 11, 13, 15, + 5, 5, 7, 8, 11, 13, 15, 17, + 6, 7, 9, 11, 13, 15, 15, 17, + 7, 7, 9, 11, 13, 15, 17, 19, + 7, 9, 11, 13, 14, 16, 19, 23, + 9, 11, 13, 14, 16, 19, 23, 29, + 9, 11, 13, 15, 17, 21, 28, 35, + 11, 13, 16, 17, 21, 28, 35, 41 + }, { + 4, 4, 5, 5, 6, 7, 7, 9, + 4, 4, 5, 6, 7, 7, 9, 9, + 5, 5, 6, 7, 7, 9, 9, 10, + 5, 5, 6, 7, 7, 9, 9, 10, + 5, 6, 7, 7, 8, 9, 10, 12, + 6, 7, 7, 8, 9, 10, 12, 15, + 6, 7, 7, 9, 10, 11, 14, 17, + 7, 7, 9, 10, 11, 14, 17, 21 + }, { + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 5, + 4, 4, 4, 4, 4, 4, 5, 5, + 4, 4, 4, 4, 4, 5, 5, 6, + 4, 4, 4, 4, 5, 5, 6, 7, + 4, 4, 4, 4, 5, 6, 7, 7 + } +}; + + +typedef struct { + uint8_t* fill_y; + uint8_t* fill_u; + uint8_t* fill_v; + + int qmat_luma[16][64]; + int qmat_chroma[16][64]; +} ProresContext; + +static void encode_codeword(PutBitContext *pb, int val, int codebook) +{ + unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros, + mask; + + /* number of bits to switch between rice and exp golomb */ + switch_bits = codebook & 3; + rice_order = codebook >> 5; + exp_order = (codebook >> 2) & 7; + + first_exp = ((switch_bits + 1) << rice_order); + + if (val >= first_exp) { /* exp golomb */ + val -= first_exp; + val += (1 << exp_order); + exp = av_log2(val); + zeros = exp - exp_order + switch_bits + 1; + put_bits(pb, zeros, 0); + put_bits(pb, 1, 1); + put_bits(pb, exp, val); + } else if (rice_order) { + mask = (1 << rice_order) - 1; + put_bits(pb, (val >> rice_order), 0); + put_bits(pb, 1, 1); + put_bits(pb, rice_order, val & mask); + } else { + put_bits(pb, val, 0); + put_bits(pb, 1, 1); + } +} + +#define QSCALE(qmat,ind,val) ((val) / (qmat[ind])) +#define TO_GOLOMB(val) ((val << 1) ^ (val >> 31)) +#define DIFF_SIGN(val, sign) ((val >> 31) ^ sign) +#define IS_NEGATIVE(val) (((val >> 31) ^ -1) + 1) +#define TO_GOLOMB2(val,sign) (val==0 ? 0 : (val << 1) + sign) + +static av_always_inline int get_level(int val) +{ + int sign = (val >> 31); + return (val ^ sign) - sign; +} + +#define FIRST_DC_CB 0xB8 + +static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70}; + +static void encode_dc_coeffs(PutBitContext *pb, DCTELEM *in, + int blocks_per_slice, int *qmat) +{ + int prev_dc, code; + int i, sign, idx; + int new_dc, delta, diff_sign, new_code; + + prev_dc = QSCALE(qmat, 0, in[0] - 16384); + code = TO_GOLOMB(prev_dc); + encode_codeword(pb, code, FIRST_DC_CB); + + code = 5; sign = 0; idx = 64; + for (i = 1; i < blocks_per_slice; i++, idx += 64) { + new_dc = QSCALE(qmat, 0, in[idx] - 16384); + delta = new_dc - prev_dc; + diff_sign = DIFF_SIGN(delta, sign); + new_code = TO_GOLOMB2(get_level(delta), diff_sign); + + encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]); + + code = new_code; + sign = delta >> 31; + prev_dc = new_dc; + } +} + +static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, + 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C }; +static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, + 0x28, 0x28, 0x28, 0x4C }; + +static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb, + DCTELEM *in, int blocks_per_slice, int *qmat) +{ + int prev_run = 4; + int prev_level = 2; + + int run = 0, level, code, i, j; + for (i = 1; i < 64; i++) { + int indp = progressive_scan[i]; + for (j = 0; j < blocks_per_slice; j++) { + int val = QSCALE(qmat, indp, in[(j << 6) + indp]); + if (val) { + encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]); + + prev_run = run; + run = 0; + level = get_level(val); + code = level - 1; + + encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]); + + prev_level = level; + + put_bits(pb, 1, IS_NEGATIVE(val)); + } else { + ++run; + } + } + } +} + +static void get(uint8_t *pixels, int stride, DCTELEM* block) +{ + int16_t *p = (int16_t*)pixels; + int i, j; + + stride >>= 1; + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + block[j] = p[j]; + } + p += stride; + block += 8; + } +} + +static void fdct_get(uint8_t *pixels, int stride, DCTELEM* block) +{ + get(pixels, stride, block); + ff_jpeg_fdct_islow_10(block); +} + +static int encode_slice_plane(AVCodecContext *avctx, int mb_count, + uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size, + int *qmat, int chroma) +{ + DECLARE_ALIGNED(16, DCTELEM, blocks)[DEFAULT_SLICE_MB_WIDTH << 8], *block; + int i, blocks_per_slice; + PutBitContext pb; + + block = blocks; + for (i = 0; i < mb_count; i++) { + fdct_get(src, src_stride, block + (0 << 6)); + fdct_get(src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6)); + if (!chroma) { + fdct_get(src + 16, src_stride, block + (1 << 6)); + fdct_get(src + 16 + 8 * src_stride, src_stride, block + (3 << 6)); + } + + block += (256 >> chroma); + src += (32 >> chroma); + } + + blocks_per_slice = mb_count << (2 - chroma); + init_put_bits(&pb, buf, buf_size << 3); + + encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat); + encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat); + + flush_put_bits(&pb); + return put_bits_ptr(&pb) - pb.buf; +} + +static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx, + uint8_t *dest_y, uint8_t *dest_u, uint8_t *dest_v, int luma_stride, + int chroma_stride, unsigned mb_count, uint8_t *buf, unsigned data_size, + unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size, + int qp) +{ + ProresContext* ctx = avctx->priv_data; + + *y_data_size = encode_slice_plane(avctx, mb_count, dest_y, luma_stride, + buf, data_size, ctx->qmat_luma[qp - 1], 0); + + if (!(avctx->flags & CODEC_FLAG_GRAY)) { + *u_data_size = encode_slice_plane(avctx, mb_count, dest_u, + chroma_stride, buf + *y_data_size, data_size - *y_data_size, + ctx->qmat_chroma[qp - 1], 1); + + *v_data_size = encode_slice_plane(avctx, mb_count, dest_v, + chroma_stride, buf + *y_data_size + *u_data_size, + data_size - *y_data_size - *u_data_size, + ctx->qmat_chroma[qp - 1], 1); + } + + return *y_data_size + *u_data_size + *v_data_size; +} + +static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y, + unsigned stride, unsigned width, unsigned height, uint16_t *dst, + unsigned dst_width, unsigned dst_height) +{ + + int box_width = FFMIN(width - x, dst_width); + int box_height = FFMIN(height - y, dst_height); + int i, j, src_stride = stride >> 1; + uint16_t last_pix, *last_line; + + src += y * src_stride + x; + for (i = 0; i < box_height; ++i) { + for (j = 0; j < box_width; ++j) { + dst[j] = src[j]; + } + last_pix = dst[j - 1]; + for (; j < dst_width; j++) + dst[j] = last_pix; + src += src_stride; + dst += dst_width; + } + last_line = dst - dst_width; + for (; i < dst_height; i++) { + for (j = 0; j < dst_width; ++j) { + dst[j] = last_line[j]; + } + dst += dst_width; + } +} + +static int encode_slice(AVCodecContext *avctx, AVFrame *pic, int mb_x, + int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size, + int unsafe, int *qp) +{ + int luma_stride, chroma_stride; + int hdr_size = 6, slice_size; + uint8_t *dest_y, *dest_u, *dest_v; + unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0; + ProresContext* ctx = avctx->priv_data; + int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2; + int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation + int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3; + + luma_stride = pic->linesize[0]; + chroma_stride = pic->linesize[1]; + + dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5); + dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4); + dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4); + + if (unsafe) { + + subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4, + luma_stride, avctx->width, avctx->height, + (uint16_t *) ctx->fill_y, mb_count << 4, 16); + subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4, + chroma_stride, avctx->width >> 1, avctx->height, + (uint16_t *) ctx->fill_u, mb_count << 3, 16); + subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4, + chroma_stride, avctx->width >> 1, avctx->height, + (uint16_t *) ctx->fill_v, mb_count << 3, 16); + + encode_slice_data(avctx, ctx->fill_y, ctx->fill_u, ctx->fill_v, + mb_count << 5, mb_count << 4, mb_count, buf + hdr_size, + data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size, + *qp); + } else { + slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v, + luma_stride, chroma_stride, mb_count, buf + hdr_size, + data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size, + *qp); + + if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) { + do { + *qp += 1; + slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v, + luma_stride, chroma_stride, mb_count, buf + hdr_size, + data_size - hdr_size, &y_data_size, &u_data_size, + &v_data_size, *qp); + } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]); + } else if (slice_size < low_bytes && *qp + > qp_start_table[avctx->profile]) { + do { + *qp -= 1; + slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v, + luma_stride, chroma_stride, mb_count, buf + hdr_size, + data_size - hdr_size, &y_data_size, &u_data_size, + &v_data_size, *qp); + } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]); + } + } + + buf[0] = hdr_size << 3; + buf[1] = *qp; + AV_WB16(buf + 2, y_data_size); + AV_WB16(buf + 4, u_data_size); + + return hdr_size + y_data_size + u_data_size + v_data_size; +} + +static int prores_encode_picture(AVCodecContext *avctx, AVFrame *pic, + uint8_t *buf, const int buf_size) +{ + int mb_width = (avctx->width + 15) >> 4; + int mb_height = (avctx->height + 15) >> 4; + int hdr_size, sl_size, i; + int mb_y, sl_data_size, qp; + int unsafe_bot, unsafe_right; + uint8_t *sl_data, *sl_data_sizes; + int slice_per_line = 0, rem = mb_width; + + for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) { + slice_per_line += rem >> i; + rem &= (1 << i) - 1; + } + + qp = qp_start_table[avctx->profile]; + hdr_size = 8; sl_data_size = buf_size - hdr_size; + sl_data_sizes = buf + hdr_size; + sl_data = sl_data_sizes + (slice_per_line * mb_height * 2); + for (mb_y = 0; mb_y < mb_height; mb_y++) { + int mb_x = 0; + int slice_mb_count = DEFAULT_SLICE_MB_WIDTH; + while (mb_x < mb_width) { + while (mb_width - mb_x < slice_mb_count) + slice_mb_count >>= 1; + + unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1); + unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width); + + sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count, + sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp); + + bytestream_put_be16(&sl_data_sizes, sl_size); + sl_data += sl_size; + sl_data_size -= sl_size; + mb_x += slice_mb_count; + } + } + + buf[0] = hdr_size << 3; + AV_WB32(buf + 1, sl_data - buf); + AV_WB16(buf + 5, slice_per_line * mb_height); + buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4; + + return sl_data - buf; +} + +static int prores_encode_frame(AVCodecContext *avctx, unsigned char *buf, + int buf_size, void *data) +{ + AVFrame *pic = data; + + int header_size = 148; + int pic_size = prores_encode_picture(avctx, pic, buf + header_size + 8, + buf_size - header_size - 8); + + bytestream_put_be32(&buf, pic_size + 8 + header_size); + bytestream_put_buffer(&buf, "icpf", 4); + + bytestream_put_be16(&buf, header_size); + bytestream_put_be16(&buf, 0); + bytestream_put_buffer(&buf, "fmpg", 4); + bytestream_put_be16(&buf, avctx->width); + bytestream_put_be16(&buf, avctx->height); + *buf++ = 0x83; // {10}(422){00}{00}(frame){11} + *buf++ = 0; + *buf++ = 2; + *buf++ = 2; + *buf++ = 6; + *buf++ = 32; + *buf++ = 0; + *buf++ = 3; + + bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64); + bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64); + + return pic_size + 8 + header_size; +} + +static void scale_mat(const uint8_t* src, int* dst, int scale) +{ + int i; + for (i = 0; i < 64; i++) + dst[i] = src[i] * scale; +} + +static av_cold int prores_encode_init(AVCodecContext *avctx) +{ + int i; + ProresContext* ctx = avctx->priv_data; + + if (avctx->pix_fmt != PIX_FMT_YUV422P10) { + av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n"); + return -1; + } + if (avctx->width & 0x1) { + av_log(avctx, AV_LOG_ERROR, + "frame width needs to be multiple of 2\n"); + return -1; + } + + if ((avctx->height & 0xf) || (avctx->width & 0xf)) { + ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8)); + if (!ctx->fill_y) + return AVERROR(ENOMEM); + ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9); + ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8); + } + + if (avctx->profile == FF_PROFILE_UNKNOWN) { + avctx->profile = FF_PROFILE_PRORES_STANDARD; + av_log(avctx, AV_LOG_INFO, + "encoding with ProRes standard (apcn) profile\n"); + + } else if (avctx->profile < FF_PROFILE_PRORES_PROXY + || avctx->profile > FF_PROFILE_PRORES_HQ) { + av_log( + avctx, + AV_LOG_ERROR, + "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n", + avctx->profile); + return -1; + } + + avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name); + + for (i = 1; i <= 16; i++) { + scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i); + scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i); + } + + avctx->coded_frame = avcodec_alloc_frame(); + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + + return 0; +} + +static av_cold int prores_encode_close(AVCodecContext *avctx) +{ + ProresContext* ctx = avctx->priv_data; + av_freep(&avctx->coded_frame); + av_freep(&ctx->fill_y); + + return 0; +} + +AVCodec ff_prores_encoder = { + .name = "prores", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_PRORES, + .priv_data_size = sizeof(ProresContext), + .init = prores_encode_init, + .close = prores_encode_close, + .encode = prores_encode_frame, + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P10, PIX_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"), + .profiles = profiles +}; diff --git a/libavcodec/ps2/dsputil_mmi.c b/libavcodec/ps2/dsputil_mmi.c index 43f0363669..26259c8453 100644 --- a/libavcodec/ps2/dsputil_mmi.c +++ b/libavcodec/ps2/dsputil_mmi.c @@ -5,20 +5,20 @@ * MMI optimization by Leon van Stuivenberg * clear_blocks_mmi() by BroadQ * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ps2/idct_mmi.c b/libavcodec/ps2/idct_mmi.c index 9b9033ae44..5a3af173de 100644 --- a/libavcodec/ps2/idct_mmi.c +++ b/libavcodec/ps2/idct_mmi.c @@ -8,20 +8,20 @@ * * MMI port and (c) 2002 by Leon van Stuivenberg * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ps2/mmi.h b/libavcodec/ps2/mmi.h index fc8d32819a..0265456108 100644 --- a/libavcodec/ps2/mmi.h +++ b/libavcodec/ps2/mmi.h @@ -1,20 +1,20 @@ /* * copyright (c) 2002 Leon van Stuivenberg * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ps2/mpegvideo_mmi.c b/libavcodec/ps2/mpegvideo_mmi.c index 623e35af33..8c8d3a7932 100644 --- a/libavcodec/ps2/mpegvideo_mmi.c +++ b/libavcodec/ps2/mpegvideo_mmi.c @@ -3,20 +3,20 @@ * * MMI optimization by Leon van Stuivenberg * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/psymodel.c b/libavcodec/psymodel.c index 5d6c32eda1..a17aecc422 100644 --- a/libavcodec/psymodel.c +++ b/libavcodec/psymodel.c @@ -2,20 +2,20 @@ * audio encoder psychoacoustic model * Copyright (C) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/psymodel.h b/libavcodec/psymodel.h index 34b20d7d04..317974bca4 100644 --- a/libavcodec/psymodel.h +++ b/libavcodec/psymodel.h @@ -2,20 +2,20 @@ * audio encoder psychoacoustic model * Copyright (C) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/pthread.c b/libavcodec/pthread.c index a4e3081272..6ae763da80 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -6,20 +6,20 @@ * to Michael Niedermayer <michaelni@gmx.at> for writing initial * implementation. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -43,6 +43,7 @@ #include <sys/param.h> #endif #include <sys/types.h> +#include <sys/param.h> #include <sys/sysctl.h> #endif #if HAVE_SYSCONF @@ -57,6 +58,8 @@ #include <pthread.h> #elif HAVE_W32THREADS #include "w32pthreads.h" +#elif HAVE_OS2THREADS +#include "os2threads.h" #endif typedef int (action_func)(AVCodecContext *c, void *arg); @@ -187,6 +190,10 @@ static int get_logical_cpus(AVCodecContext *avctx) nb_cpus = sysconf(_SC_NPROCESSORS_ONLN); #endif av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus); + + if (avctx->height) + nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16); + return nb_cpus; } @@ -359,6 +366,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg) AVCodec *codec = avctx->codec; while (1) { + int i; if (p->state == STATE_INPUT_READY && !fctx->die) { pthread_mutex_lock(&p->mutex); while (p->state == STATE_INPUT_READY && !fctx->die) @@ -368,7 +376,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg) if (fctx->die) break; - if (!codec->update_thread_context && avctx->thread_safe_callbacks) + if (!codec->update_thread_context && (avctx->thread_safe_callbacks || avctx->get_buffer == avcodec_default_get_buffer)) ff_thread_finish_setup(avctx); pthread_mutex_lock(&p->mutex); @@ -381,6 +389,12 @@ static attribute_align_arg void *frame_worker_thread(void *arg) p->state = STATE_INPUT_READY; pthread_mutex_lock(&p->progress_mutex); + for (i = 0; i < MAX_BUFFERS; i++) + if (p->progress_used[i]) { + p->progress[i][0] = INT_MAX; + p->progress[i][1] = INT_MAX; + } + pthread_cond_broadcast(&p->progress_cond); pthread_cond_signal(&p->output_cond); pthread_mutex_unlock(&p->progress_mutex); @@ -432,6 +446,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, } if (for_user) { + dst->delay = src->thread_count - 1; dst->coded_frame = src->coded_frame; } else { if (dst->codec->update_thread_context) @@ -469,6 +484,7 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) dst->frame_number = src->frame_number; dst->reordered_opaque = src->reordered_opaque; + dst->thread_safe_callbacks = src->thread_safe_callbacks; if (src->slice_count && src->slice_offset) { if (dst->slice_count < src->slice_count) { @@ -698,6 +714,10 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; + if(p->state == STATE_SETUP_FINISHED){ + av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); + } + pthread_mutex_lock(&p->progress_mutex); p->state = STATE_SETUP_FINISHED; pthread_cond_broadcast(&p->progress_cond); @@ -718,6 +738,7 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count pthread_cond_wait(&p->output_cond, &p->progress_mutex); pthread_mutex_unlock(&p->progress_mutex); } + p->got_frame = 0; } } @@ -743,6 +764,7 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count) if (p->thread_init) pthread_join(p->thread, NULL); + p->thread_init=0; if (codec->close) codec->close(p->avctx); @@ -788,6 +810,8 @@ static int frame_thread_init(AVCodecContext *avctx) if (!thread_count) { int nb_cpus = get_logical_cpus(avctx); + if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv) + nb_cpus = 1; // use number of cores + 1 as thread count if there is more than one if (nb_cpus > 1) thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); @@ -856,8 +880,9 @@ static int frame_thread_init(AVCodecContext *avctx) if (err) goto error; - if (!pthread_create(&p->thread, NULL, frame_worker_thread, p)) - p->thread_init = 1; + p->thread_init= !pthread_create(&p->thread, NULL, frame_worker_thread, p); + if(!p->thread_init) + goto error; } return 0; @@ -911,13 +936,16 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) f->owner = avctx; + ff_init_buffer_info(avctx, f); + if (!(avctx->active_thread_type&FF_THREAD_FRAME)) { f->thread_opaque = NULL; return avctx->get_buffer(avctx, f); } if (p->state != STATE_SETTING_UP && - (avctx->codec->update_thread_context || !avctx->thread_safe_callbacks)) { + (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks && + avctx->get_buffer != avcodec_default_get_buffer))) { av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); return -1; } @@ -940,7 +968,7 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) p->requested_frame = f; p->state = STATE_GET_BUFFER; pthread_mutex_lock(&p->progress_mutex); - pthread_cond_signal(&p->progress_cond); + pthread_cond_broadcast(&p->progress_cond); while (p->state != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c index fd4933c1d6..f3bca86db2 100644 --- a/libavcodec/ptx.c +++ b/libavcodec/ptx.c @@ -2,20 +2,20 @@ * V.Flash PTX (.ptx) image decoder * Copyright (c) 2007 Ivo van Poorten * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/put_bits.h b/libavcodec/put_bits.h index 6e812670b8..9256e7fa4d 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -1,20 +1,20 @@ /* * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/qcelpdata.h b/libavcodec/qcelpdata.h index 4c6cf15e3e..4a7dcdb38b 100644 --- a/libavcodec/qcelpdata.h +++ b/libavcodec/qcelpdata.h @@ -2,20 +2,20 @@ * QCELP decoder * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +26,7 @@ * @file * Data tables for the QCELP decoder * @author Reynaldo H. Verdejo Pinochet - * @remark Libav merging spearheaded by Kenan Gillet + * @remark FFmpeg merging spearheaded by Kenan Gillet * @remark Development mentored by Benjamin Larson */ diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c index a3af2378f3..ac5c289c3d 100644 --- a/libavcodec/qcelpdec.c +++ b/libavcodec/qcelpdec.c @@ -2,20 +2,20 @@ * QCELP decoder * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -23,7 +23,7 @@ * @file * QCELP decoder * @author Reynaldo H. Verdejo Pinochet - * @remark Libav merging spearheaded by Kenan Gillet + * @remark FFmpeg merging spearheaded by Kenan Gillet * @remark Development mentored by Benjamin Larson */ diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 6acb7d8362..5da21d757d 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -5,20 +5,20 @@ * Copyright (c) 2005 Alex Beregszaszi * Copyright (c) 2005 Roberto Togni * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -172,7 +172,7 @@ typedef struct { /// I/O data const uint8_t *compressed_data; int compressed_size; - float output_buffer[QDM2_MAX_FRAME_SIZE * 2]; + float output_buffer[QDM2_MAX_FRAME_SIZE * MPA_MAX_CHANNELS * 2]; /// Synthesis filter MPADSPContext mpadsp; @@ -1331,7 +1331,7 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * local_int_10 = 1 << (q->group_order - duration - 1); offset = 1; - while (1) { + while (get_bits_left(gb)>0) { if (q->superblocktype_2_3) { while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) { offset = 1; @@ -1830,6 +1830,7 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) // something like max decodable tones s->group_order = av_log2(s->group_size) + 1; s->frame_size = s->group_size / 16; // 16 iterations per super block + if (s->frame_size > QDM2_MAX_FRAME_SIZE) return AVERROR_INVALIDDATA; @@ -1904,6 +1905,9 @@ static int qdm2_decode (QDM2Context *q, const uint8_t *in, int16_t *out) int ch, i; const int frame_size = (q->frame_size * q->channels); + if((unsigned)frame_size > FF_ARRAY_ELEMS(q->output_buffer)/2) + return -1; + /* select input buffer */ q->compressed_data = in; q->compressed_size = q->checksum_size; diff --git a/libavcodec/qdm2_tablegen.c b/libavcodec/qdm2_tablegen.c index 59d82df851..a7a9fb6643 100644 --- a/libavcodec/qdm2_tablegen.c +++ b/libavcodec/qdm2_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/qdm2_tablegen.h b/libavcodec/qdm2_tablegen.h index bb73d92531..585edfdd65 100644 --- a/libavcodec/qdm2_tablegen.h +++ b/libavcodec/qdm2_tablegen.h @@ -3,20 +3,20 @@ * * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/qdm2data.h b/libavcodec/qdm2data.h index ad6ea88ff6..355d61387b 100644 --- a/libavcodec/qdm2data.h +++ b/libavcodec/qdm2data.h @@ -5,20 +5,20 @@ * Copyright (c) 2005 Alex Beregszaszi * Copyright (c) 2005 Roberto Togni * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/qdrw.c b/libavcodec/qdrw.c index 7410f6e152..54deec5c83 100644 --- a/libavcodec/qdrw.c +++ b/libavcodec/qdrw.c @@ -2,20 +2,20 @@ * QuickDraw (qdrw) codec * Copyright (c) 2004 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -90,7 +90,7 @@ static int decode_frame(AVCodecContext *avctx, buf++; b = *buf++; buf++; - pal[idx] = (r << 16) | (g << 8) | b; + pal[idx] = 0xFF << 24 | r << 16 | g << 8 | b; } p->palette_has_changed = 1; @@ -145,8 +145,9 @@ static int decode_frame(AVCodecContext *avctx, } static av_cold int decode_init(AVCodecContext *avctx){ -// QdrawContext * const a = avctx->priv_data; + QdrawContext * const a = avctx->priv_data; + avcodec_get_frame_defaults(&a->pic); avctx->pix_fmt= PIX_FMT_PAL8; return 0; diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index 9513dd0ad3..bbb9f71aae 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -2,20 +2,20 @@ * QPEG codec * Copyright (c) 2004 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +28,11 @@ typedef struct QpegContext{ AVCodecContext *avctx; - AVFrame pic; - uint8_t *refdata; + AVFrame pic, ref; uint32_t pal[256]; } QpegContext; -static void qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size, +static int qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size, int stride, int width, int height) { int i; @@ -95,6 +94,8 @@ static void qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size, } } else { size -= copy; + if (size<0) + return AVERROR_INVALIDDATA; for(i = 0; i < copy; i++) { dst[filled++] = *src++; if (filled >= width) { @@ -107,6 +108,7 @@ static void qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size, } } } + return 0; } static const int qpeg_table_h[16] = @@ -124,9 +126,12 @@ static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, int filled = 0; int orig_height; + if(!refdata) + refdata= dst; + /* copy prev frame */ for(i = 0; i < height; i++) - memcpy(refdata + (i * width), dst + (i * stride), width); + memcpy(dst + (i * stride), refdata + (i * stride), width); orig_height = height; height--; @@ -172,10 +177,10 @@ static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, me_x, me_y, me_w, me_h, filled, height); else { /* do motion compensation */ - me_plane = refdata + (filled + me_x) + (height - me_y) * width; + me_plane = refdata + (filled + me_x) + (height - me_y) * stride; for(j = 0; j < me_h; j++) { for(i = 0; i < me_w; i++) - dst[filled + i - (j * stride)] = me_plane[i - (j * width)]; + dst[filled + i - (j * stride)] = me_plane[i - (j * stride)]; } } } @@ -254,24 +259,32 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; QpegContext * const a = avctx->priv_data; - AVFrame * const p= (AVFrame*)&a->pic; + AVFrame * p= (AVFrame*)&a->pic; + AVFrame * ref= (AVFrame*)&a->ref; uint8_t* outdata; - int delta; + int delta, ret = 0; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); - p->reference = 3; - if (avctx->reget_buffer(avctx, p) < 0) { - av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + if(ref->data[0]) + avctx->release_buffer(avctx, ref); + FFSWAP(AVFrame, *ref, *p); + + p->reference= 3; + if(avctx->get_buffer(avctx, p) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } outdata = a->pic.data[0]; if(buf[0x85] == 0x10) { - qpeg_decode_intra(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height); + ret = qpeg_decode_intra(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height); } else { delta = buf[0x85]; - qpeg_decode_inter(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height, delta, buf + 4, a->refdata); + qpeg_decode_inter(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height, delta, buf + 4, a->ref.data[0]); } + if (ret<0) + return ret; + /* make the palette available on the way out */ if (pal) { a->pic.palette_has_changed = 1; @@ -288,9 +301,10 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_init(AVCodecContext *avctx){ QpegContext * const a = avctx->priv_data; + avcodec_get_frame_defaults(&a->pic); + avcodec_get_frame_defaults(&a->ref); a->avctx = avctx; avctx->pix_fmt= PIX_FMT_PAL8; - a->refdata = av_malloc(avctx->width * avctx->height); return 0; } @@ -298,11 +312,13 @@ static av_cold int decode_init(AVCodecContext *avctx){ static av_cold int decode_end(AVCodecContext *avctx){ QpegContext * const a = avctx->priv_data; AVFrame * const p= (AVFrame*)&a->pic; + AVFrame * const ref= (AVFrame*)&a->ref; if(p->data[0]) avctx->release_buffer(avctx, p); + if(ref->data[0]) + avctx->release_buffer(avctx, ref); - av_free(a->refdata); return 0; } diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index e96e2788c9..606a2ea95d 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -2,20 +2,20 @@ * Quicktime Animation (RLE) Video Decoder * Copyright (C) 2004 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -72,6 +72,15 @@ static void qtrle_decode_1bpp(QtrleContext *s, int stream_ptr, int row_ptr, int unsigned char *rgb = s->frame.data[0]; int pixel_limit = s->frame.linesize[0] * s->avctx->height; int skip; + /* skip & 0x80 appears to mean 'start a new line', which can be interpreted + * as 'go to next line' during the decoding of a frame but is 'go to first + * line' at the beginning. Since we always interpret it as 'go to next line' + * in the decoding loop (which makes code simpler/faster), the first line + * would not be counted, so we count one more. + * See: https://ffmpeg.org/trac/ffmpeg/ticket/226 + * In the following decoding loop, row_ptr will be the position of the + * _next_ row. */ + lines_to_change++; while (lines_to_change) { CHECK_STREAM_PTR(2); @@ -81,12 +90,15 @@ static void qtrle_decode_1bpp(QtrleContext *s, int stream_ptr, int row_ptr, int break; if(skip & 0x80) { lines_to_change--; - row_ptr += row_inc; pixel_ptr = row_ptr + 2 * (skip & 0x7f); + row_ptr += row_inc; } else pixel_ptr += 2 * skip; CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ + if(rle_code == -1) + continue; + if (rle_code < 0) { /* decode the run length code */ rle_code = -rle_code; @@ -127,6 +139,7 @@ static inline void qtrle_decode_2n4bpp(QtrleContext *s, int stream_ptr, while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (num_pixels * (s->buf[stream_ptr++] - 1)); + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -183,6 +196,7 @@ static void qtrle_decode_8bpp(QtrleContext *s, int stream_ptr, int row_ptr, int while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (4 * (s->buf[stream_ptr++] - 1)); + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -236,6 +250,7 @@ static void qtrle_decode_16bpp(QtrleContext *s, int stream_ptr, int row_ptr, int while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2; + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -285,6 +300,7 @@ static void qtrle_decode_24bpp(QtrleContext *s, int stream_ptr, int row_ptr, int while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 3; + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -335,6 +351,7 @@ static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int while (lines_to_change--) { CHECK_STREAM_PTR(2); pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4; + CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */ while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { if (rle_code == 0) { @@ -410,6 +427,7 @@ static av_cold int qtrle_decode_init(AVCodecContext *avctx) break; } + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; @@ -429,7 +447,7 @@ static int qtrle_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - s->frame.reference = 1; + s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; if (avctx->reget_buffer(avctx, &s->frame)) { @@ -456,6 +474,8 @@ static int qtrle_decode_frame(AVCodecContext *avctx, stream_ptr += 4; height = AV_RB16(&s->buf[stream_ptr]); stream_ptr += 4; + if (height > s->avctx->height - start_line) + goto done; } else { start_line = 0; height = s->avctx->height; diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c index ede03d2f78..a8963ab78a 100644 --- a/libavcodec/qtrleenc.c +++ b/libavcodec/qtrleenc.c @@ -5,20 +5,20 @@ * * This file is based on flashsvenc.c. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -39,6 +39,7 @@ typedef struct QtrleEncContext { int pixel_size; AVPicture previous_frame; unsigned int max_buf_size; + int logical_width; /** * This array will contain at ith position the value of the best RLE code * if the line started at pixel i @@ -67,8 +68,13 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx) return -1; } s->avctx=avctx; + s->logical_width=avctx->width; switch (avctx->pix_fmt) { + case PIX_FMT_GRAY8: + s->logical_width = avctx->width / 4; + s->pixel_size = 4; + break; case PIX_FMT_RGB555BE: s->pixel_size = 2; break; @@ -82,11 +88,11 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unsupported colorspace.\n"); break; } - avctx->bits_per_coded_sample = s->pixel_size*8; + avctx->bits_per_coded_sample = avctx->pix_fmt == PIX_FMT_GRAY8 ? 40 : 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)); + s->rlecode_table = av_mallocz(s->logical_width); + s->skip_table = av_mallocz(s->logical_width); + s->length_table = av_mallocz((s->logical_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; @@ -96,10 +102,10 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx) 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 */; + s->max_buf_size = s->logical_width*s->avctx->height*s->pixel_size /* image base material */ + + 15 /* header + footer */ + + s->avctx->height*2 /* skip code+rle end */ + + s->logical_width/MAX_RLE_BULK + 1 /* rle codes */; avctx->coded_frame = &s->frame; return 0; } @@ -109,7 +115,7 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx) */ static void qtrle_encode_line(QtrleEncContext *s, AVFrame *p, int line, uint8_t **buf) { - int width=s->avctx->width; + int width=s->logical_width; int i; signed char rlecode; @@ -199,7 +205,7 @@ static void qtrle_encode_line(QtrleEncContext *s, AVFrame *p, int line, uint8_t prev_line -= s->pixel_size; } - /* Good ! Now we have the best sequence for this line, let's ouput it */ + /* Good ! Now we have the best sequence for this line, let's output it */ /* We do a special case for the first pixel so that we avoid testing it in * the whole loop */ @@ -224,12 +230,28 @@ static void qtrle_encode_line(QtrleEncContext *s, AVFrame *p, int line, uint8_t } else if (rlecode > 0) { /* bulk copy */ - bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size); + if (s->avctx->pix_fmt == PIX_FMT_GRAY8) { + int j; + // QT grayscale colorspace has 0=white and 255=black, we will + // ignore the palette that is included in the AVFrame because + // PIX_FMT_GRAY8 has defined color mapping + for (j = 0; j < rlecode*s->pixel_size; ++j) + bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff); + } else { + 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); + if (s->avctx->pix_fmt == PIX_FMT_GRAY8) { + int j; + // QT grayscale colorspace has 0=white and 255=black, ... + for (j = 0; j < s->pixel_size; ++j) + bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff); + } else { + bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size); + } i -= rlecode; } } @@ -245,7 +267,7 @@ static int encode_frame(QtrleEncContext *s, AVFrame *p, uint8_t *buf) uint8_t *orig_buf = buf; if (!s->frame.key_frame) { - unsigned line_size = s->avctx->width * s->pixel_size; + unsigned line_size = s->logical_width * s->pixel_size; 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*s->previous_frame.linesize[0], @@ -329,6 +351,6 @@ AVCodec ff_qtrle_encoder = { .init = qtrle_encode_init, .encode = qtrle_encode_frame, .close = qtrle_encode_end, - .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB555BE, PIX_FMT_ARGB, PIX_FMT_NONE}, + .pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB555BE, PIX_FMT_ARGB, PIX_FMT_GRAY8, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), }; diff --git a/libavcodec/r210dec.c b/libavcodec/r210dec.c index 0f85f5892b..d8cad3535c 100644 --- a/libavcodec/r210dec.c +++ b/libavcodec/r210dec.c @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Doeffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,6 +29,8 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->bits_per_raw_sample = 10; avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; } @@ -61,8 +63,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, for (h = 0; h < avctx->height; h++) { uint16_t *dst = (uint16_t *)dst_line; for (w = 0; w < avctx->width; w++) { - uint32_t pixel = av_be2ne32(*src++); + uint32_t pixel; uint16_t r, g, b; + if (avctx->codec_id==CODEC_ID_AVRP) { + pixel = av_le2ne32(*src++); + } else { + pixel = av_be2ne32(*src++); + } if (avctx->codec_id==CODEC_ID_R210) { b = pixel << 6; g = (pixel >> 4) & 0xffc0; @@ -120,3 +127,15 @@ AVCodec ff_r10k_decoder = { .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), }; #endif +#if CONFIG_AVRP_DECODER +AVCodec ff_avrp_decoder = { + .name = "avrp", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_AVRP, + .init = decode_init, + .close = decode_close, + .decode = decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), +}; +#endif diff --git a/libavcodec/r210enc.c b/libavcodec/r210enc.c new file mode 100644 index 0000000000..f5ba42da50 --- /dev/null +++ b/libavcodec/r210enc.c @@ -0,0 +1,122 @@ +/* + * R210 encoder + * + * Copyright (c) 2012 Paul B Mahol + * + * 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" + +static av_cold int encode_init(AVCodecContext *avctx) +{ + avctx->coded_frame = avcodec_alloc_frame(); + + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + return 0; +} + +static int encode_frame(AVCodecContext *avctx, uint8_t *buf, + int buf_size, void *data) +{ + AVFrame *pic = data; + int i, j; + int aligned_width = FFALIGN(avctx->width, 64); + int pad = (aligned_width - avctx->width) * 4; + uint8_t *src_line; + uint8_t *dst = buf; + + if (buf_size < 4 * aligned_width * avctx->height) { + av_log(avctx, AV_LOG_ERROR, "output buffer too small\n"); + return AVERROR(ENOMEM); + } + + avctx->coded_frame->reference = 0; + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + src_line = pic->data[0]; + + for (i = 0; i < avctx->height; i++) { + uint16_t *src = (uint16_t *)src_line; + for (j = 0; j < avctx->width; j++) { + uint32_t pixel; + uint16_t r = *src++ >> 6; + uint16_t g = *src++ >> 6; + uint16_t b = *src++ >> 4; + if (avctx->codec_id == CODEC_ID_R210) + pixel = (r << 20) | (g << 10) | b >> 2; + else + pixel = (r << 22) | (g << 12) | b; + if (avctx->codec_id == CODEC_ID_AVRP) + bytestream_put_le32(&dst, pixel); + else + bytestream_put_be32(&dst, pixel); + } + memset(dst, 0, pad); + dst += pad; + src_line += pic->linesize[0]; + } + + return 4 * aligned_width * avctx->height; +} + +static av_cold int encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + + return 0; +} + +#if CONFIG_R210_ENCODER +AVCodec ff_r210_encoder = { + .name = "r210", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_R210, + .init = encode_init, + .encode = encode_frame, + .close = encode_close, + .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_RGB48, PIX_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"), +}; +#endif +#if CONFIG_R10K_ENCODER +AVCodec ff_r10k_encoder = { + .name = "r10k", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_R10K, + .init = encode_init, + .encode = encode_frame, + .close = encode_close, + .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_RGB48, PIX_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"), +}; +#endif +#if CONFIG_AVRP_ENCODER +AVCodec ff_avrp_encoder = { + .name = "avrp", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_AVRP, + .init = encode_init, + .encode = encode_frame, + .close = encode_close, + .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_RGB48, PIX_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"), +}; +#endif diff --git a/libavcodec/ra144.c b/libavcodec/ra144.c index e6442d694d..761f595934 100644 --- a/libavcodec/ra144.c +++ b/libavcodec/ra144.c @@ -2,20 +2,20 @@ * Real Audio 1.0 (14.4K) * Copyright (c) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1715,6 +1715,6 @@ void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs, LPC_ORDER*sizeof(*ractx->curr_sblock)); if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + LPC_ORDER, lpc_coefs, - block, BLOCKSIZE, LPC_ORDER, 1, 0xfff)) + block, BLOCKSIZE, LPC_ORDER, 1, 0, 0xfff)) memset(ractx->curr_sblock, 0, (LPC_ORDER+BLOCKSIZE)*sizeof(*ractx->curr_sblock)); } diff --git a/libavcodec/ra144.h b/libavcodec/ra144.h index f6475d45ff..9665534f7b 100644 --- a/libavcodec/ra144.h +++ b/libavcodec/ra144.h @@ -2,20 +2,20 @@ * Real Audio 1.0 (14.4K) * Copyright (c) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index dd8838c417..428f788733 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -5,20 +5,20 @@ * Copyright (c) 2003 Nick Kurshev * Based on public domain decoder at http://www.honeypot.net/audio * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ra144enc.c b/libavcodec/ra144enc.c index c8a09a2ed2..91bf7e174f 100644 --- a/libavcodec/ra144enc.c +++ b/libavcodec/ra144enc.c @@ -2,20 +2,20 @@ * Real Audio 1.0 (14.4K) encoder * Copyright (c) 2010 Francesco Lavra <francescolavra@interfree.it> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ra288.c b/libavcodec/ra288.c index 4cb2493fc9..26b576d804 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -2,20 +2,20 @@ * RealAudio 2.0 (28.8K) * Copyright (c) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -102,14 +102,14 @@ static void decode(RA288Context *ractx, float gain, int cb_coef) for (i=0; i < 5; i++) buffer[i] = codetable[cb_coef][i] * sumsum; - sum = ff_dot_productf(buffer, buffer, 5) * ((1<<24)/5.); + sum = ff_dot_productf(buffer, buffer, 5); - sum = FFMAX(sum, 1); + sum = FFMAX(sum, 5. / (1<<24)); /* shift and store */ memmove(gain_block, gain_block + 1, 9 * sizeof(*gain_block)); - gain_block[9] = 10 * log10(sum) - 32; + gain_block[9] = 10 * log10(sum) + (10*log10(((1<<24)/5.)) - 32); ff_celp_lp_synthesis_filterf(block, ractx->sp_lpc, buffer, 5, 36); } diff --git a/libavcodec/ra288.h b/libavcodec/ra288.h index 1c98c16ea4..769e30ec17 100644 --- a/libavcodec/ra288.h +++ b/libavcodec/ra288.h @@ -2,20 +2,20 @@ * RealAudio 2.0 (28.8K) * Copyright (c) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rangecoder.c b/libavcodec/rangecoder.c index 1cd6762cb5..04c2738523 100644 --- a/libavcodec/rangecoder.c +++ b/libavcodec/rangecoder.c @@ -2,20 +2,20 @@ * Range coder * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rangecoder.h b/libavcodec/rangecoder.h index 7ad1bd2e55..47c0362ba3 100644 --- a/libavcodec/rangecoder.h +++ b/libavcodec/rangecoder.h @@ -2,20 +2,20 @@ * Range coder * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 5e4b49adf3..9d98b9a835 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -3,20 +3,20 @@ * * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -125,6 +125,8 @@ int ff_rate_control_init(MpegEncContext *s) rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5; } rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy; + if (!rcc->buffer_index) + rcc->buffer_index = s->avctx->rc_buffer_size * 3 / 4; if(s->flags&CODEC_FLAG_PASS2){ int i; @@ -537,8 +539,8 @@ static void adaptive_quantization(MpegEncContext *s, double q){ const float border_masking = s->avctx->border_masking; float bits_sum= 0.0; float cplx_sum= 0.0; - float cplx_tab[s->mb_num]; - float bits_tab[s->mb_num]; + float *cplx_tab = av_malloc(s->mb_num * sizeof(*cplx_tab)); + float *bits_tab = av_malloc(s->mb_num * sizeof(*bits_tab)); const int qmin= s->avctx->mb_lmin; const int qmax= s->avctx->mb_lmax; Picture * const pic= &s->current_picture; @@ -639,6 +641,9 @@ static void adaptive_quantization(MpegEncContext *s, double q){ //printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i])); s->lambda_table[mb_xy]= intq; } + + av_free(cplx_tab); + av_free(bits_tab); } void ff_get_2pass_fcode(MpegEncContext *s){ @@ -705,7 +710,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) 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); +// av_log(NULL, AV_LOG_ERROR, "%"PRId64" %"PRId64" %"PRId64" %d\n", s->current_picture_ptr->pts, s->user_specified_pts, dts_pic->pts, picture_number); if (!dts_pic || dts_pic->f.pts == AV_NOPTS_VALUE) wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps); @@ -868,6 +873,12 @@ static int init_pass2(MpegEncContext *s) assert(filter_size%2==1); /* fixed I/B QP relative to P mode */ + for(i=FFMAX(0, rcc->num_entries-300); i<rcc->num_entries; i++){ + RateControlEntry *rce= &rcc->entry[i]; + + qscale[i]= get_diff_limited_q(s, rce, qscale[i]); + } + for(i=rcc->num_entries-1; i>=0; i--){ RateControlEntry *rce= &rcc->entry[i]; diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h index c0e05ccf18..b4132bfcb6 100644 --- a/libavcodec/ratecontrol.h +++ b/libavcodec/ratecontrol.h @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/raw.c b/libavcodec/raw.c index c41f756572..ec532a32c4 100644 --- a/libavcodec/raw.c +++ b/libavcodec/raw.c @@ -2,20 +2,20 @@ * Raw Video Codec * Copyright (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -63,6 +63,7 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { PIX_FMT_UYVY422, MKTAG('A', 'V', 'u', 'p') }, { PIX_FMT_UYVY422, MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */ { PIX_FMT_UYVY422, MKTAG('a', 'u', 'v', '2') }, + { PIX_FMT_UYVY422, MKTAG('c', 'y', 'u', 'v') }, /* CYUV is also Creative YUV */ { PIX_FMT_UYYVYY411, MKTAG('Y', '4', '1', '1') }, { PIX_FMT_GRAY8, MKTAG('G', 'R', 'E', 'Y') }, { PIX_FMT_NV12, MKTAG('N', 'V', '1', '2') }, @@ -81,10 +82,18 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { PIX_FMT_BGR444LE, MKTAG('B', 'G', 'R', 12) }, { PIX_FMT_RGB444BE, MKTAG(12 , 'B', 'G', 'R') }, { PIX_FMT_BGR444BE, MKTAG(12 , 'R', 'G', 'B') }, + { PIX_FMT_RGBA64LE, MKTAG('R', 'B', 'A', 64 ) }, + { PIX_FMT_BGRA64LE, MKTAG('B', 'R', 'A', 64 ) }, + { PIX_FMT_RGBA64BE, MKTAG(64 , 'R', 'B', 'A') }, + { PIX_FMT_BGRA64BE, MKTAG(64 , 'B', 'R', 'A') }, { PIX_FMT_RGBA, MKTAG('R', 'G', 'B', 'A') }, + { PIX_FMT_RGB0, MKTAG('R', 'G', 'B', 0 ) }, { PIX_FMT_BGRA, MKTAG('B', 'G', 'R', 'A') }, + { PIX_FMT_BGR0, MKTAG('B', 'G', 'R', 0 ) }, { PIX_FMT_ABGR, MKTAG('A', 'B', 'G', 'R') }, + { PIX_FMT_0BGR, MKTAG( 0 , 'B', 'G', 'R') }, { PIX_FMT_ARGB, MKTAG('A', 'R', 'G', 'B') }, + { PIX_FMT_0RGB, MKTAG( 0 , 'R', 'G', 'B') }, { PIX_FMT_RGB24, MKTAG('R', 'G', 'B', 24 ) }, { PIX_FMT_BGR24, MKTAG('B', 'G', 'R', 24 ) }, { PIX_FMT_YUV411P, MKTAG('4', '1', '1', 'P') }, @@ -121,7 +130,7 @@ const PixelFormatTag ff_raw_pix_fmt_tags[] = { { PIX_FMT_YUV444P16LE, MKTAG('Y', '3', 0 , 16 ) }, { PIX_FMT_YUV444P16BE, MKTAG(16 , 0 , '3', 'Y') }, { PIX_FMT_YUVA420P, MKTAG('Y', '4', 11 , 8 ) }, - { PIX_FMT_Y400A, MKTAG('Y', '2', 0 , 8 ) }, + { PIX_FMT_GRAY8A, MKTAG('Y', '2', 0 , 8 ) }, /* quicktime */ { PIX_FMT_UYVY422, MKTAG('2', 'v', 'u', 'y') }, diff --git a/libavcodec/raw.h b/libavcodec/raw.h index 2caa3faff5..4724cd3547 100644 --- a/libavcodec/raw.h +++ b/libavcodec/raw.h @@ -2,20 +2,20 @@ * Raw Video Codec * Copyright (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -35,5 +35,6 @@ typedef struct PixelFormatTag { } PixelFormatTag; extern const PixelFormatTag ff_raw_pix_fmt_tags[]; +enum PixelFormat ff_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc); #endif /* AVCODEC_RAW_H */ diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index bb93129027..68b461d2f1 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -2,20 +2,20 @@ * Raw Video Decoder * Copyright (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,23 +29,34 @@ #include "raw.h" #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" +#include "libavutil/opt.h" typedef struct RawVideoContext { + AVClass *av_class; uint32_t palette[AVPALETTE_COUNT]; unsigned char * buffer; /* block of memory for holding one frame */ int length; /* number of bytes in buffer */ int flip; AVFrame pic; ///< AVCodecContext.coded_frame + int tff; } RawVideoContext; +static const AVOption options[]={ +{"top", "top field first", offsetof(RawVideoContext, tff), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_VIDEO_PARAM}, +{NULL} +}; +static const AVClass class = { "rawdec", NULL, options, LIBAVUTIL_VERSION_INT }; + static const PixelFormatTag pix_fmt_bps_avi[] = { + { PIX_FMT_MONOWHITE, 1 }, + { PIX_FMT_PAL8, 2 }, { PIX_FMT_PAL8, 4 }, { PIX_FMT_PAL8, 8 }, { PIX_FMT_RGB444, 12 }, { PIX_FMT_RGB555, 15 }, { PIX_FMT_RGB555, 16 }, { PIX_FMT_BGR24, 24 }, - { PIX_FMT_RGB32, 32 }, + { PIX_FMT_BGRA, 32 }, { PIX_FMT_NONE, 0 }, }; @@ -63,7 +74,7 @@ static const PixelFormatTag pix_fmt_bps_mov[] = { { PIX_FMT_NONE, 0 }, }; -static enum PixelFormat find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc) +enum PixelFormat ff_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc) { while (tags->pix_fmt >= 0) { if (tags->fourcc == fourcc) @@ -78,22 +89,29 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) RawVideoContext *context = avctx->priv_data; if (avctx->codec_tag == MKTAG('r','a','w',' ')) - avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_mov, avctx->bits_per_coded_sample); + avctx->pix_fmt = ff_find_pix_fmt(pix_fmt_bps_mov, avctx->bits_per_coded_sample); else if (avctx->codec_tag == MKTAG('W','R','A','W')) - avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample); + avctx->pix_fmt = ff_find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample); else if (avctx->codec_tag) - avctx->pix_fmt = find_pix_fmt(ff_raw_pix_fmt_tags, avctx->codec_tag); + avctx->pix_fmt = ff_find_pix_fmt(ff_raw_pix_fmt_tags, avctx->codec_tag); else if (avctx->pix_fmt == PIX_FMT_NONE && avctx->bits_per_coded_sample) - avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample); + avctx->pix_fmt = ff_find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample); + + if (avctx->pix_fmt == PIX_FMT_NONE) { + av_log(avctx, AV_LOG_ERROR, "Pixel format was not specified and cannot be detected\n"); + return AVERROR(EINVAL); + } ff_set_systematic_pal2(context->palette, avctx->pix_fmt); - context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); if((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) && avctx->pix_fmt==PIX_FMT_PAL8 && (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))){ + context->length = avpicture_get_size(avctx->pix_fmt, FFALIGN(avctx->width, 16), avctx->height); context->buffer = av_malloc(context->length); if (!context->buffer) return -1; + } else { + context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); } context->pic.pict_type = AV_PICTURE_TYPE_I; context->pic.key_frame = 1; @@ -101,6 +119,7 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) avctx->coded_frame= &context->pic; if((avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) || + avctx->codec_tag == MKTAG('c','y','u','v') || avctx->codec_tag == MKTAG(3, 0, 0, 0) || avctx->codec_tag == MKTAG('W','R','A','W')) context->flip=1; @@ -118,6 +137,7 @@ static int raw_decode(AVCodecContext *avctx, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + int linesize_align = 4; RawVideoContext *context = avctx->priv_data; AVFrame * frame = (AVFrame *) data; @@ -128,6 +148,12 @@ static int raw_decode(AVCodecContext *avctx, frame->top_field_first = avctx->coded_frame->top_field_first; frame->reordered_opaque = avctx->reordered_opaque; frame->pkt_pts = avctx->pkt->pts; + frame->pkt_pos = avctx->pkt->pos; + + if(context->tff>=0){ + frame->interlaced_frame = 1; + frame->top_field_first = context->tff; + } //2bpp and 4bpp raw in avi and mov (yes this is ugly ...) if (context->buffer) { @@ -139,13 +165,16 @@ static int raw_decode(AVCodecContext *avctx, dst[2*i+0]= buf[i]>>4; dst[2*i+1]= buf[i]&15; } - } else + linesize_align = 8; + } else { for(i=0; 4*i+3 < buf_size; i++){ dst[4*i+0]= buf[i]>>6; dst[4*i+1]= buf[i]>>4&3; dst[4*i+2]= buf[i]>>2&3; dst[4*i+3]= buf[i] &3; } + linesize_align = 16; + } buf= dst; } @@ -169,13 +198,22 @@ static int raw_decode(AVCodecContext *avctx, frame->palette_has_changed = 1; } } - if(avctx->pix_fmt==PIX_FMT_BGR24 && ((frame->linesize[0]+3)&~3)*avctx->height <= buf_size) - frame->linesize[0] = (frame->linesize[0]+3)&~3; + if((avctx->pix_fmt==PIX_FMT_BGR24 || + avctx->pix_fmt==PIX_FMT_GRAY8 || + avctx->pix_fmt==PIX_FMT_RGB555LE || + avctx->pix_fmt==PIX_FMT_RGB555BE || + avctx->pix_fmt==PIX_FMT_RGB565LE || + avctx->pix_fmt==PIX_FMT_MONOWHITE || + avctx->pix_fmt==PIX_FMT_PAL8) && + FFALIGN(frame->linesize[0], linesize_align)*avctx->height <= buf_size) + frame->linesize[0] = FFALIGN(frame->linesize[0], linesize_align); if(context->flip) flip(avctx, picture); if ( avctx->codec_tag == MKTAG('Y', 'V', '1', '2') + || avctx->codec_tag == MKTAG('Y', 'V', '1', '6') + || avctx->codec_tag == MKTAG('Y', 'V', '2', '4') || avctx->codec_tag == MKTAG('Y', 'V', 'U', '9')) FFSWAP(uint8_t *, picture->data[1], picture->data[2]); @@ -211,4 +249,5 @@ AVCodec ff_rawvideo_decoder = { .close = raw_close_decoder, .decode = raw_decode, .long_name = NULL_IF_CONFIG_SMALL("raw video"), + .priv_class= &class, }; diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c index 8eb818c618..577a8fc98a 100644 --- a/libavcodec/rawenc.c +++ b/libavcodec/rawenc.c @@ -2,20 +2,20 @@ * Raw Video Encoder * Copyright (c) 2001 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -33,8 +33,8 @@ static av_cold int raw_init_encoder(AVCodecContext *avctx) { avctx->coded_frame = (AVFrame *)avctx->priv_data; + avcodec_get_frame_defaults(avctx->coded_frame); avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; - avctx->coded_frame->key_frame = 1; avctx->bits_per_coded_sample = av_get_bits_per_pixel(&av_pix_fmt_descriptors[avctx->pix_fmt]); if(!avctx->codec_tag) avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt); diff --git a/libavcodec/rdft.c b/libavcodec/rdft.c index 116cfa4366..ebddd8b56b 100644 --- a/libavcodec/rdft.c +++ b/libavcodec/rdft.c @@ -2,20 +2,20 @@ * (I)RDFT transforms * Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdlib.h> diff --git a/libavcodec/rdft.h b/libavcodec/rdft.h index 8ff620fb59..5fb03232a1 100644 --- a/libavcodec/rdft.h +++ b/libavcodec/rdft.h @@ -2,20 +2,20 @@ * (I)RDFT transforms * Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rectangle.h b/libavcodec/rectangle.h index 5cc81feeaa..cf4a9ccec3 100644 --- a/libavcodec/rectangle.h +++ b/libavcodec/rectangle.h @@ -2,20 +2,20 @@ * rectangle filling function * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/remove_extradata_bsf.c b/libavcodec/remove_extradata_bsf.c index 460482a8ff..f0d9b4513a 100644 --- a/libavcodec/remove_extradata_bsf.c +++ b/libavcodec/remove_extradata_bsf.c @@ -1,20 +1,20 @@ /* * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/resample.c b/libavcodec/resample.c index ba8ce8910c..f1a2dbf6dc 100644 --- a/libavcodec/resample.c +++ b/libavcodec/resample.c @@ -2,20 +2,20 @@ * samplerate conversion for both audio and video * Copyright (c) 2000 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -108,6 +108,39 @@ static void mono_to_stereo(short *output, short *input, int n1) } } +/* +5.1 to stereo input: [fl, fr, c, lfe, rl, rr] +- Left = front_left + rear_gain * rear_left + center_gain * center +- Right = front_right + rear_gain * rear_right + center_gain * center +Where rear_gain is usually around 0.5-1.0 and + center_gain is almost always 0.7 (-3 dB) +*/ +static void surround_to_stereo(short **output, short *input, int channels, int samples) +{ + int i; + short l, r; + + for (i = 0; i < samples; i++) { + int fl,fr,c,rl,rr; + fl = input[0]; + fr = input[1]; + c = input[2]; + // lfe = input[3]; + rl = input[4]; + rr = input[5]; + + l = av_clip_int16(fl + (0.5 * rl) + (0.7 * c)); + r = av_clip_int16(fr + (0.5 * rr) + (0.7 * c)); + + /* output l & r. */ + *output[0]++ = l; + *output[1]++ = r; + + /* increment input. */ + input += channels; + } +} + static void deinterleave(short **output, short *input, int channels, int samples) { int i, j; @@ -147,6 +180,21 @@ static void ac3_5p1_mux(short *output, short *input1, short *input2, int n) } } +#define SUPPORT_RESAMPLE(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8) \ + ch8<<7 | ch7<<6 | ch6<<5 | ch5<<4 | ch4<<3 | ch3<<2 | ch2<<1 | ch1<<0 + +static const uint8_t supported_resampling[MAX_CHANNELS] = { + // output ch: 1 2 3 4 5 6 7 8 + SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 0, 0, 0), // 1 input channel + SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 1, 0, 0), // 2 input channels + SUPPORT_RESAMPLE(0, 0, 1, 0, 0, 0, 0, 0), // 3 input channels + SUPPORT_RESAMPLE(0, 0, 0, 1, 0, 0, 0, 0), // 4 input channels + SUPPORT_RESAMPLE(0, 0, 0, 0, 1, 0, 0, 0), // 5 input channels + SUPPORT_RESAMPLE(0, 1, 0, 0, 0, 1, 0, 0), // 6 input channels + SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 1, 0), // 7 input channels + SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 0, 1), // 8 input channels +}; + ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, int output_rate, int input_rate, enum AVSampleFormat sample_fmt_out, @@ -162,12 +210,15 @@ ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, MAX_CHANNELS); return NULL; } - if (output_channels != input_channels && - (input_channels > 2 || - output_channels > 2 && - !(output_channels == 6 && input_channels == 2))) { - av_log(NULL, AV_LOG_ERROR, - "Resampling output channel count must be 1 or 2 for mono input; 1, 2 or 6 for stereo input; or N for N channel input.\n"); + if (!(supported_resampling[input_channels-1] & (1<<(output_channels-1)))) { + int i; + av_log(NULL, AV_LOG_ERROR, "Unsupported audio resampling. Allowed " + "output channels for %d input channel%s", input_channels, + input_channels > 1 ? "s:" : ":"); + for (i = 0; i < MAX_CHANNELS; i++) + if (supported_resampling[input_channels-1] & (1<<i)) + av_log(NULL, AV_LOG_ERROR, " %d", i + 1); + av_log(NULL, AV_LOG_ERROR, "\n"); return NULL; } @@ -269,14 +320,14 @@ int audio_resample(ReSampleContext *s, short *output, short *input, int nb_sampl input = s->buffer[0]; } - lenout = 4 * nb_samples * s->ratio + 16; + lenout= 2*s->output_channels*nb_samples * s->ratio + 16; if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) { output_bak = output; - if (!s->buffer_size[1] || s->buffer_size[1] < lenout) { + if (!s->buffer_size[1] || s->buffer_size[1] < 2*lenout) { av_free(s->buffer[1]); - s->buffer_size[1] = lenout; + s->buffer_size[1] = 2*lenout; s->buffer[1] = av_malloc(s->buffer_size[1]); if (!s->buffer[1]) { av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n"); @@ -301,6 +352,10 @@ int audio_resample(ReSampleContext *s, short *output, short *input, int nb_sampl } else if (s->output_channels >= 2 && s->input_channels == 1) { buftmp3[0] = bufout[0]; memcpy(buftmp2[0], input, nb_samples * sizeof(short)); + } else if (s->input_channels == 6 && s->output_channels ==2) { + buftmp3[0] = bufout[0]; + buftmp3[1] = bufout[1]; + surround_to_stereo(buftmp2, input, s->input_channels, nb_samples); } else if (s->output_channels >= s->input_channels && s->input_channels >= 2) { for (i = 0; i < s->input_channels; i++) { buftmp3[i] = bufout[i]; @@ -330,7 +385,8 @@ int audio_resample(ReSampleContext *s, short *output, short *input, int nb_sampl mono_to_stereo(output, buftmp3[0], nb_samples1); } else if (s->output_channels == 6 && s->input_channels == 2) { ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1); - } else if (s->output_channels == s->input_channels && s->input_channels >= 2) { + } else if ((s->output_channels == s->input_channels && s->input_channels >= 2) || + (s->output_channels == 2 && s->input_channels == 6)) { interleave(output, buftmp3, s->output_channels, nb_samples1); } diff --git a/libavcodec/resample2.c b/libavcodec/resample2.c index 48c20c2cbb..5fe9924c40 100644 --- a/libavcodec/resample2.c +++ b/libavcodec/resample2.c @@ -2,20 +2,20 @@ * audio resampling * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -207,8 +207,10 @@ AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, memcpy(&c->filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM)); c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1]; - c->src_incr= out_rate; - c->ideal_dst_incr= c->dst_incr= in_rate * phase_count; + if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2)) + goto error; + c->ideal_dst_incr= c->dst_incr; + c->index= -phase_count*((c->filter_length-1)/2); return c; @@ -246,10 +248,9 @@ int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int dst[dst_index] = src[index2>>32]; index2 += incr; } - frac += dst_index * dst_incr_frac; index += dst_index * dst_incr; - index += frac / c->src_incr; - frac %= c->src_incr; + index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr; + frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr; }else{ for(dst_index=0; dst_index < dst_size; dst_index++){ FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask); diff --git a/libavcodec/rl.h b/libavcodec/rl.h index 9c1ad7a642..b2445890e6 100644 --- a/libavcodec/rl.h +++ b/libavcodec/rl.h @@ -2,20 +2,20 @@ * Copyright (c) 2000-2002 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rl2.c b/libavcodec/rl2.c index ace3b0cca5..7eebddff6f 100644 --- a/libavcodec/rl2.c +++ b/libavcodec/rl2.c @@ -2,20 +2,20 @@ * RL2 Video Decoder * Copyright (C) 2008 Sascha Sommer (saschasommer@freenet.de) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -51,7 +51,7 @@ typedef struct Rl2Context { * @param s rl2 context * @param in input buffer * @param size input buffer size - * @param out ouput buffer + * @param out output buffer * @param stride stride of the output buffer * @param video_base offset of the rle data inside the frame */ @@ -133,6 +133,7 @@ static av_cold int rl2_decode_init(AVCodecContext *avctx) int i; s->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&s->frame); /** parse extra data */ if(!avctx->extradata || avctx->extradata_size < EXTRADATA1_SIZE){ @@ -151,7 +152,7 @@ static av_cold int rl2_decode_init(AVCodecContext *avctx) /** initialize palette */ for(i=0;i<AVPALETTE_COUNT;i++) - s->palette[i] = AV_RB24(&avctx->extradata[6 + i * 3]); + s->palette[i] = 0xFF << 24 | AV_RB24(&avctx->extradata[6 + i * 3]); /** decode background frame if present */ back_size = avctx->extradata_size - EXTRADATA1_SIZE; diff --git a/libavcodec/rle.c b/libavcodec/rle.c index 8a009e72bc..6e468f8991 100644 --- a/libavcodec/rle.c +++ b/libavcodec/rle.c @@ -2,20 +2,20 @@ * RLE encoder * Copyright (c) 2007 Bobby Bingham * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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" diff --git a/libavcodec/rle.h b/libavcodec/rle.h index 00261d3598..24851321fe 100644 --- a/libavcodec/rle.h +++ b/libavcodec/rle.h @@ -1,20 +1,20 @@ /* * RLE encoder * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c index e540e14c24..da833411b5 100644 --- a/libavcodec/roqaudioenc.c +++ b/libavcodec/roqaudioenc.c @@ -4,20 +4,20 @@ * Copyright (c) 2005 Eric Lasota * Based on RoQ specs (c)2001 Tim Ferguson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -59,7 +59,8 @@ static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx) context->lastSample[0] = context->lastSample[1] = 0; avctx->coded_frame= avcodec_alloc_frame(); - avctx->coded_frame->key_frame= 1; + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; } diff --git a/libavcodec/roqvideo.c b/libavcodec/roqvideo.c index 77df0798db..eb8fc253ad 100644 --- a/libavcodec/roqvideo.c +++ b/libavcodec/roqvideo.c @@ -2,20 +2,20 @@ * Copyright (C) 2003 Mike Melanson * Copyright (C) 2003 Dr. Tim Ferguson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/roqvideo.h b/libavcodec/roqvideo.h index a1ff10af7d..3fe11c670b 100644 --- a/libavcodec/roqvideo.h +++ b/libavcodec/roqvideo.h @@ -2,20 +2,20 @@ * Copyright (C) 2003 Mike Melanson * Copyright (C) 2003 Dr. Tim Ferguson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c index 527ba51c99..161e7da08a 100644 --- a/libavcodec/roqvideodec.c +++ b/libavcodec/roqvideodec.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -71,9 +71,17 @@ static void roqvideo_decode_frame(RoqContext *ri) } bpos = xpos = ypos = 0; + if (chunk_size > buf_end - buf) { + av_log(ri->avctx, AV_LOG_ERROR, "Chunk does not fit in input buffer\n"); + chunk_size = buf_end - buf; + } while(bpos < chunk_size) { for (yp = ypos; yp < ypos + 16; yp += 8) for (xp = xpos; xp < xpos + 16; xp += 8) { + if (bpos >= chunk_size) { + av_log(ri->avctx, AV_LOG_ERROR, "Input buffer too small\n"); + return; + } if (vqflg_pos < 0) { vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8); vqflg_pos = 7; @@ -103,6 +111,10 @@ static void roqvideo_decode_frame(RoqContext *ri) if(k & 0x01) x += 4; if(k & 0x02) y += 4; + if (bpos >= chunk_size) { + av_log(ri->avctx, AV_LOG_ERROR, "Input buffer too small\n"); + return; + } if (vqflg_pos < 0) { vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8); @@ -159,6 +171,8 @@ static av_cold int roq_decode_init(AVCodecContext *avctx) s->avctx = avctx; s->width = avctx->width; s->height = avctx->height; + avcodec_get_frame_defaults(&s->frames[0]); + avcodec_get_frame_defaults(&s->frames[1]); s->last_frame = &s->frames[0]; s->current_frame = &s->frames[1]; avctx->pix_fmt = PIX_FMT_YUV444P; diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index 2a62d5509d..88d6224eac 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -5,27 +5,27 @@ * Copyright (C) 2004-2007 Eric Lasota * Based on RoQ specs (C) 2001 Tim Ferguson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file * id RoQ encoder by Vitor. Based on the Switchblade3 library and the - * Switchblade3 Libav glue by Eric Lasota. + * Switchblade3 FFmpeg glue by Eric Lasota. */ /* diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c index 7350ef2c4a..4c87b3c1b2 100644 --- a/libavcodec/rpza.c +++ b/libavcodec/rpza.c @@ -2,20 +2,20 @@ * Quicktime Video (RPZA) Video Decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -233,6 +233,7 @@ static av_cold int rpza_decode_init(AVCodecContext *avctx) s->avctx = avctx; avctx->pix_fmt = PIX_FMT_RGB555; + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; @@ -249,7 +250,7 @@ static int rpza_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - s->frame.reference = 1; + s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &s->frame)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c index 2c5ef0a8dd..e03282b412 100644 --- a/libavcodec/rtjpeg.c +++ b/libavcodec/rtjpeg.c @@ -2,20 +2,20 @@ * RTJpeg decoding functions * Copyright (c) 2006 Reimar Doeffinger * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavutil/common.h" diff --git a/libavcodec/rtjpeg.h b/libavcodec/rtjpeg.h index d537c93ff4..4bcb9f70ca 100644 --- a/libavcodec/rtjpeg.h +++ b/libavcodec/rtjpeg.h @@ -2,20 +2,20 @@ * RTJpeg decoding functions * copyright (c) 2006 Reimar Doeffinger * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv10.c b/libavcodec/rv10.c index 1d7fd6b468..d97ed12272 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -298,6 +298,23 @@ static int rv20_decode_picture_header(MpegEncContext *s) int seq, mb_pos, i; int rpr_bits; +#if 0 + GetBitContext gb= s->gb; + for(i=0; i<64; i++){ + av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&gb)); + if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " "); + } + av_log(s->avctx, AV_LOG_DEBUG, "\n"); +#endif +#if 0 + av_log(s->avctx, AV_LOG_DEBUG, "%3dx%03d/%02Xx%02X ", s->width, s->height, s->width/4, s->height/4); + for(i=0; i<s->avctx->extradata_size; i++){ + av_log(s->avctx, AV_LOG_DEBUG, "%02X ", ((uint8_t*)s->avctx->extradata)[i]); + if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " "); + } + av_log(s->avctx, AV_LOG_DEBUG, "\n"); +#endif + i= get_bits(&s->gb, 2); switch(i){ case 0: s->pict_type= AV_PICTURE_TYPE_I; break; @@ -432,7 +449,6 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) s->avctx= avctx; s->out_format = FMT_H263; s->codec_id= avctx->codec_id; - avctx->flags |= CODEC_FLAG_EMU_EDGE; s->orig_width = s->width = avctx->coded_width; s->orig_height= s->height = avctx->coded_height; @@ -539,6 +555,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, } } + av_dlog(avctx, "qscale=%d\n", s->qscale); /* default quantization values */ @@ -634,6 +651,8 @@ static int rv10_decode_frame(AVCodecContext *avctx, const uint8_t *slices_hdr = NULL; av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); + s->flags = avctx->flags; + s->flags2 = avctx->flags2; /* no supplementary picture */ if (buf_size == 0) { diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c index e96e473c20..8dd74e844e 100644 --- a/libavcodec/rv10enc.c +++ b/libavcodec/rv10enc.c @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv20enc.c b/libavcodec/rv20enc.c index bf09d8ada4..af7ef6bb72 100644 --- a/libavcodec/rv20enc.c +++ b/libavcodec/rv20enc.c @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv30.c b/libavcodec/rv30.c index 4828e982b7..e60c93db4b 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -2,20 +2,20 @@ * RV30 decoder * Copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -51,6 +51,11 @@ static int rv30_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceIn skip_bits1(gb); si->pts = get_bits(gb, 13); rpr = get_bits(gb, r->rpr); + if (r->s.avctx->extradata_size < 8 + rpr*2) { + av_log(r->s.avctx, AV_LOG_WARNING, + "Extradata does not contain selected resolution\n"); + rpr = 0; + } if(rpr){ w = r->s.avctx->extradata[6 + rpr*2] << 2; h = r->s.avctx->extradata[7 + rpr*2] << 2; @@ -74,7 +79,7 @@ static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t for(i = 0; i < 4; i++, dst += r->intra_types_stride - 4){ for(j = 0; j < 4; j+= 2){ int code = svq3_get_ue_golomb(gb) << 1; - if(code >= 81*2){ + if(code >= 81U*2U){ av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n"); return -1; } @@ -103,7 +108,7 @@ static int rv30_decode_mb_info(RV34DecContext *r) GetBitContext *gb = &s->gb; int code = svq3_get_ue_golomb(gb); - if(code > 11){ + if(code > 11U){ av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n"); return -1; } @@ -256,7 +261,6 @@ static av_cold int rv30_decode_init(AVCodecContext *avctx) if(avctx->extradata_size - 8 < (r->rpr - 1) * 2){ av_log(avctx, AV_LOG_ERROR, "Insufficient extradata - need at least %d bytes, got %d\n", 6 + r->rpr * 2, avctx->extradata_size); - return AVERROR(EINVAL); } r->parse_slice_header = rv30_parse_slice_header; r->decode_intra_types = rv30_decode_intra_types; diff --git a/libavcodec/rv30data.h b/libavcodec/rv30data.h index 5ee304802c..9cc48a6a31 100644 --- a/libavcodec/rv30data.h +++ b/libavcodec/rv30data.h @@ -2,20 +2,20 @@ * RealVideo 3 decoder * copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv30dsp.c b/libavcodec/rv30dsp.c index bcd1a462b1..83439600ce 100644 --- a/libavcodec/rv30dsp.c +++ b/libavcodec/rv30dsp.c @@ -2,20 +2,20 @@ * RV30 decoder motion compensation functions * Copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv34.c b/libavcodec/rv34.c index e6af0793d3..e09d5dcf14 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -2,20 +2,20 @@ * RV30/40 decoder common data * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1432,6 +1432,10 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n"); return AVERROR_INVALIDDATA; } + if (s->width != r->si.width || s->height != r->si.height) { + av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n"); + return AVERROR_INVALIDDATA; + } } r->si.end = end; diff --git a/libavcodec/rv34.h b/libavcodec/rv34.h index d86b009705..e9cac1ca2f 100644 --- a/libavcodec/rv34.h +++ b/libavcodec/rv34.h @@ -2,20 +2,20 @@ * RV30/40 decoder common data declarations * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv34_parser.c b/libavcodec/rv34_parser.c index 4c1d2e396e..9672f26182 100644 --- a/libavcodec/rv34_parser.c +++ b/libavcodec/rv34_parser.c @@ -76,7 +76,7 @@ static int rv34_parse(AVCodecParserContext *s, return buf_size; } -#ifdef CONFIG_RV30_PARSER +#if CONFIG_RV30_PARSER AVCodecParser ff_rv30_parser = { .codec_ids = { CODEC_ID_RV30 }, .priv_data_size = sizeof(RV34ParseContext), @@ -84,7 +84,7 @@ AVCodecParser ff_rv30_parser = { }; #endif -#ifdef CONFIG_RV40_PARSER +#if CONFIG_RV40_PARSER AVCodecParser ff_rv40_parser = { .codec_ids = { CODEC_ID_RV40 }, .priv_data_size = sizeof(RV34ParseContext), diff --git a/libavcodec/rv34data.h b/libavcodec/rv34data.h index 41c5b20ad7..8be26a3943 100644 --- a/libavcodec/rv34data.h +++ b/libavcodec/rv34data.h @@ -2,20 +2,20 @@ * RealVideo 4 decoder * copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv34vlc.h b/libavcodec/rv34vlc.h index f4670c1625..aa29357c78 100644 --- a/libavcodec/rv34vlc.h +++ b/libavcodec/rv34vlc.h @@ -2,20 +2,20 @@ * RealVideo 3/4 decoder * Copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv40.c b/libavcodec/rv40.c index c55a07a7d0..3bd1826b70 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -2,20 +2,20 @@ * RV40 decoder * Copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -231,8 +231,11 @@ static int rv40_decode_mb_info(RV34DecContext *r) int blocks[RV34_MB_TYPES] = {0}; int count = 0; - if(!r->s.mb_skip_run) + if(!r->s.mb_skip_run) { r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1; + if(r->s.mb_skip_run > (unsigned)s->mb_num) + return -1; + } if(--r->s.mb_skip_run) return RV34_MB_SKIP; diff --git a/libavcodec/rv40data.h b/libavcodec/rv40data.h index 42328af5a8..36f9f919bd 100644 --- a/libavcodec/rv40data.h +++ b/libavcodec/rv40data.h @@ -2,20 +2,20 @@ * RealVideo 4 decoder * copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv40dsp.c b/libavcodec/rv40dsp.c index 909ccd1732..913ced046d 100644 --- a/libavcodec/rv40dsp.c +++ b/libavcodec/rv40dsp.c @@ -2,20 +2,20 @@ * RV40 decoder motion compensation functions * Copyright (c) 2008 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/rv40vlc2.h b/libavcodec/rv40vlc2.h index 2f63fc27e3..15119a145b 100644 --- a/libavcodec/rv40vlc2.h +++ b/libavcodec/rv40vlc2.h @@ -2,20 +2,20 @@ * RealVideo 4 decoder * copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/s302m.c b/libavcodec/s302m.c index 34018aeb46..4a17fa102e 100644 --- a/libavcodec/s302m.c +++ b/libavcodec/s302m.c @@ -3,20 +3,20 @@ * Copyright (c) 2008 Laurent Aimar <fenrir@videolan.org> * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -67,6 +67,16 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf, avctx->sample_fmt = AV_SAMPLE_FMT_S16; avctx->channels = channels; + switch(channels) { + case 2: + avctx->channel_layout = AV_CH_LAYOUT_STEREO; + break; + case 4: + avctx->channel_layout = AV_CH_LAYOUT_QUAD; + break; + case 8: + avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX; + } avctx->sample_rate = 48000; avctx->bit_rate = 48000 * avctx->channels * (avctx->bits_per_coded_sample + 4) + 32 * (48000 / (buf_size * 8 / diff --git a/libavcodec/s3tc.c b/libavcodec/s3tc.c index d0c4eb80e1..8e979a84ac 100644 --- a/libavcodec/s3tc.c +++ b/libavcodec/s3tc.c @@ -4,20 +4,20 @@ * * see also: http://wiki.multimedia.cx/index.php?title=S3TC * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/s3tc.h b/libavcodec/s3tc.h index 6e10f43843..5116dc80f6 100644 --- a/libavcodec/s3tc.h +++ b/libavcodec/s3tc.h @@ -2,20 +2,20 @@ * S3 Texture Compression (S3TC) decoding functions * Copyright (c) 2007 by Ivo van Poorten * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sbr.h b/libavcodec/sbr.h index 7d06faddde..1fe47fcebe 100644 --- a/libavcodec/sbr.h +++ b/libavcodec/sbr.h @@ -3,20 +3,20 @@ * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl ) * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sgi.h b/libavcodec/sgi.h index ca531f00a1..be17f2e237 100644 --- a/libavcodec/sgi.h +++ b/libavcodec/sgi.h @@ -2,20 +2,20 @@ * SGI image encoder * Xiaohui Sun <tjnksxh@hotmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sgidec.c b/libavcodec/sgidec.c index 580cf81a20..56495c1d31 100644 --- a/libavcodec/sgidec.c +++ b/libavcodec/sgidec.c @@ -2,24 +2,25 @@ * SGI image decoder * Todd Kirby <doubleshot@pacbell.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavutil/imgutils.h" +#include "libavutil/avassert.h" #include "avcodec.h" #include "bytestream.h" #include "sgi.h" @@ -194,8 +195,8 @@ static int decode_frame(AVCodecContext *avctx, avctx->pix_fmt = s->bytes_per_channel == 2 ? PIX_FMT_GRAY16BE : PIX_FMT_GRAY8; } else if (s->depth == SGI_RGB) { avctx->pix_fmt = s->bytes_per_channel == 2 ? PIX_FMT_RGB48BE : PIX_FMT_RGB24; - } else if (s->depth == SGI_RGBA && s->bytes_per_channel == 1) { - avctx->pix_fmt = PIX_FMT_RGBA; + } else if (s->depth == SGI_RGBA) { + avctx->pix_fmt = s->bytes_per_channel == 2 ? PIX_FMT_RGBA64BE : PIX_FMT_RGBA; } else { av_log(avctx, AV_LOG_ERROR, "wrong picture format\n"); return -1; diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c index 9d02eea136..1b7fbbfbc9 100644 --- a/libavcodec/sgienc.c +++ b/libavcodec/sgienc.c @@ -2,20 +2,20 @@ * SGI image encoder * Todd Kirby <doubleshot@pacbell.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -48,7 +48,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, 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 int width, height, depth, dimension, bytes_per_channel, pixmax, put_be; unsigned char *orig_buf = buf, *end_buf = buf + buf_size; *p = *(AVFrame*)data; @@ -57,6 +57,9 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, width = avctx->width; height = avctx->height; + bytes_per_channel = 1; + pixmax = 0xFF; + put_be = HAVE_BIGENDIAN; switch (avctx->pix_fmt) { case PIX_FMT_GRAY8: @@ -71,6 +74,33 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, dimension = SGI_MULTI_CHAN; depth = SGI_RGBA; break; + case PIX_FMT_GRAY16LE: + put_be = !HAVE_BIGENDIAN; + case PIX_FMT_GRAY16BE: + avctx->coder_type = FF_CODER_TYPE_RAW; + bytes_per_channel = 2; + pixmax = 0xFFFF; + dimension = SGI_SINGLE_CHAN; + depth = SGI_GRAYSCALE; + break; + case PIX_FMT_RGB48LE: + put_be = !HAVE_BIGENDIAN; + case PIX_FMT_RGB48BE: + avctx->coder_type = FF_CODER_TYPE_RAW; + bytes_per_channel = 2; + pixmax = 0xFFFF; + dimension = SGI_MULTI_CHAN; + depth = SGI_RGB; + break; + case PIX_FMT_RGBA64LE: + put_be = !HAVE_BIGENDIAN; + case PIX_FMT_RGBA64BE: + avctx->coder_type = FF_CODER_TYPE_RAW; + bytes_per_channel = 2; + pixmax = 0xFFFF; + dimension = SGI_MULTI_CHAN; + depth = SGI_RGBA; + break; default: return AVERROR_INVALIDDATA; } @@ -86,15 +116,14 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, /* Encode header. */ bytestream_put_be16(&buf, SGI_MAGIC); bytestream_put_byte(&buf, avctx->coder_type != FF_CODER_TYPE_RAW); /* RLE 1 - VERBATIM 0*/ - bytestream_put_byte(&buf, 1); /* bytes_per_channel */ + bytestream_put_byte(&buf, 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, pixmax); bytestream_put_be32(&buf, 0L); /* dummy */ /* name */ @@ -144,11 +173,19 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, av_free(encode_buf); } else { for (z = 0; z < depth; z++) { - in_buf = p->data[0] + p->linesize[0] * (height - 1) + z; + in_buf = p->data[0] + p->linesize[0] * (height - 1) + z * bytes_per_channel; for (y = 0; y < height; y++) { for (x = 0; x < width * depth; x += depth) + if (bytes_per_channel == 1) { bytestream_put_byte(&buf, in_buf[x]); + } else { + if (put_be) { + bytestream_put_be16(&buf, ((uint16_t *)in_buf)[x]); + } else { + bytestream_put_le16(&buf, ((uint16_t *)in_buf)[x]); + } + } in_buf -= p->linesize[0]; } @@ -166,6 +203,10 @@ AVCodec ff_sgi_encoder = { .priv_data_size = sizeof(SgiContext), .init = encode_init, .encode = encode_frame, - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_GRAY8, PIX_FMT_NONE}, + .pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, + PIX_FMT_RGB48LE, PIX_FMT_RGB48BE, + PIX_FMT_RGBA64LE, PIX_FMT_RGBA64BE, + PIX_FMT_GRAY16LE, PIX_FMT_GRAY16BE, + PIX_FMT_GRAY8, PIX_FMT_NONE}, .long_name= NULL_IF_CONFIG_SMALL("SGI image"), }; diff --git a/libavcodec/sh4/dsputil_align.c b/libavcodec/sh4/dsputil_align.c index 0c293a1248..e91893683f 100644 --- a/libavcodec/sh4/dsputil_align.c +++ b/libavcodec/sh4/dsputil_align.c @@ -3,20 +3,20 @@ * * Copyright (c) 2001-2003 BERO <bero@geocities.co.jp> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sh4/dsputil_sh4.c b/libavcodec/sh4/dsputil_sh4.c index 51c1a53d7d..905e8b15e0 100644 --- a/libavcodec/sh4/dsputil_sh4.c +++ b/libavcodec/sh4/dsputil_sh4.c @@ -3,20 +3,20 @@ * * Copyright (c) 2003 BERO <bero@geocities.co.jp> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sh4/dsputil_sh4.h b/libavcodec/sh4/dsputil_sh4.h index 5abe34557b..2e554e7370 100644 --- a/libavcodec/sh4/dsputil_sh4.h +++ b/libavcodec/sh4/dsputil_sh4.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sh4/idct_sh4.c b/libavcodec/sh4/idct_sh4.c index 0baff396e0..13a85b030e 100644 --- a/libavcodec/sh4/idct_sh4.c +++ b/libavcodec/sh4/idct_sh4.c @@ -3,20 +3,20 @@ * * Copyright (c) 2001-2003 BERO <bero@geocities.co.jp> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sh4/qpel.c b/libavcodec/sh4/qpel.c index 3242872e47..2e30ae1137 100644 --- a/libavcodec/sh4/qpel.c +++ b/libavcodec/sh4/qpel.c @@ -4,20 +4,20 @@ * * copyright (c) 2001-2003 BERO <bero@geocities.co.jp> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sh4/sh4.h b/libavcodec/sh4/sh4.h index acd12e6ff6..5d46540cb6 100644 --- a/libavcodec/sh4/sh4.h +++ b/libavcodec/sh4/sh4.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/shorten.c b/libavcodec/shorten.c index eb67df7bea..ef58aaa6aa 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -2,20 +2,20 @@ * Shorten decoder * Copyright (c) 2005 Jeff Muizelaar * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -86,6 +86,7 @@ typedef struct ShortenContext { int channels; int32_t *decoded[MAX_CHANNELS]; + int32_t *decoded_base[MAX_CHANNELS]; int32_t *offset[MAX_CHANNELS]; int *coeffs; uint8_t *bitstream; @@ -140,13 +141,13 @@ static int allocate_buffers(ShortenContext *s) return AVERROR(ENOMEM); s->offset[chan] = tmp_ptr; - tmp_ptr = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); + tmp_ptr = av_realloc(s->decoded_base[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); if (!tmp_ptr) return AVERROR(ENOMEM); - s->decoded[chan] = tmp_ptr; + s->decoded_base[chan] = tmp_ptr; for (i=0; i<s->nwrap; i++) - s->decoded[chan][i] = 0; - s->decoded[chan] += s->nwrap; + s->decoded_base[chan][i] = 0; + s->decoded[chan] = s->decoded_base[chan] + s->nwrap; } coeffs = av_realloc(s->coeffs, s->nwrap * sizeof(*s->coeffs)); @@ -204,7 +205,7 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, { int len; short wave_format; - + const uint8_t *end= header + header_size; if (bytestream_get_le32(&header) != MKTAG('R','I','F','F')) { av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); @@ -220,6 +221,8 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, while (bytestream_get_le32(&header) != MKTAG('f','m','t',' ')) { len = bytestream_get_le32(&header); + if(len<0 || end - header - 8 < len) + return AVERROR_INVALIDDATA; header += len; } len = bytestream_get_le32(&header); @@ -615,8 +618,8 @@ static av_cold int shorten_decode_close(AVCodecContext *avctx) int i; for (i = 0; i < s->channels; i++) { - s->decoded[i] -= s->nwrap; - av_freep(&s->decoded[i]); + s->decoded[i] = NULL; + av_freep(&s->decoded_base[i]); av_freep(&s->offset[i]); } av_freep(&s->bitstream); diff --git a/libavcodec/simple_idct.c b/libavcodec/simple_idct.c index 0c75261079..0676cf65fc 100644 --- a/libavcodec/simple_idct.c +++ b/libavcodec/simple_idct.c @@ -3,20 +3,20 @@ * * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/simple_idct.h b/libavcodec/simple_idct.h index 6e22158b0b..64d3c2ac31 100644 --- a/libavcodec/simple_idct.h +++ b/libavcodec/simple_idct.h @@ -3,20 +3,20 @@ * * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/simple_idct_template.c b/libavcodec/simple_idct_template.c index fdec3aab2b..4bb51363f9 100644 --- a/libavcodec/simple_idct_template.c +++ b/libavcodec/simple_idct_template.c @@ -3,20 +3,20 @@ * * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sinewin.c b/libavcodec/sinewin.c index be38dbc713..1fa0e953f0 100644 --- a/libavcodec/sinewin.c +++ b/libavcodec/sinewin.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sinewin.h b/libavcodec/sinewin.h index eefe5bfe7f..61135fd6a2 100644 --- a/libavcodec/sinewin.h +++ b/libavcodec/sinewin.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Robert Swain * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sinewin_tablegen.c b/libavcodec/sinewin_tablegen.c index 2f4d1aa2ae..48eb771e48 100644 --- a/libavcodec/sinewin_tablegen.c +++ b/libavcodec/sinewin_tablegen.c @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sinewin_tablegen.h b/libavcodec/sinewin_tablegen.h index 720f1ab6b8..f587595c21 100644 --- a/libavcodec/sinewin_tablegen.h +++ b/libavcodec/sinewin_tablegen.h @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sipr.c b/libavcodec/sipr.c index 4502fa5f2a..65440db224 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -4,20 +4,20 @@ * Copyright (c) 2008 Vladimir Voroshilov * Copyright (c) 2009 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -487,7 +487,10 @@ static av_cold int sipr_decoder_init(AVCodecContext * avctx) case 37: ctx->mode = MODE_5k0; break; default: av_log(avctx, AV_LOG_ERROR, "Invalid block_align: %d\n", avctx->block_align); - return AVERROR(EINVAL); + if (avctx->bit_rate > 12200) ctx->mode = MODE_16k; + else if (avctx->bit_rate > 7500 ) ctx->mode = MODE_8k5; + else if (avctx->bit_rate > 5750 ) ctx->mode = MODE_6k5; + else ctx->mode = MODE_5k0; } av_log(avctx, AV_LOG_DEBUG, "Mode: %s\n", modes[ctx->mode].mode_name); diff --git a/libavcodec/sipr.h b/libavcodec/sipr.h index 951532167f..608636e442 100644 --- a/libavcodec/sipr.h +++ b/libavcodec/sipr.h @@ -4,20 +4,20 @@ * Copyright (c) 2008 Vladimir Voroshilov * Copyright (c) 2009 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sipr16k.c b/libavcodec/sipr16k.c index ca10cd9c70..7fb9252927 100644 --- a/libavcodec/sipr16k.c +++ b/libavcodec/sipr16k.c @@ -4,20 +4,20 @@ * Copyright (c) 2008 Vladimir Voroshilov * Copyright (c) 2009 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sipr16kdata.h b/libavcodec/sipr16kdata.h index ec60c29b51..96bf0e96c8 100644 --- a/libavcodec/sipr16kdata.h +++ b/libavcodec/sipr16kdata.h @@ -4,20 +4,20 @@ * Copyright (c) 2008 Vladimir Voroshilov * Copyright (c) 2009 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/siprdata.h b/libavcodec/siprdata.h index 92037a4a87..ed804ee87c 100644 --- a/libavcodec/siprdata.h +++ b/libavcodec/siprdata.h @@ -4,20 +4,20 @@ * Copyright (c) 2008 Vladimir Voroshilov * Copyright (c) 2009 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/smacker.c b/libavcodec/smacker.c index 192466280d..593d409cb1 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -2,20 +2,20 @@ * Smacker decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -173,7 +173,7 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx } /** - * Store large tree as Libav's vlc codes + * Store large tree as FFmpeg's vlc codes */ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size) { @@ -263,6 +263,11 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int 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++; + if(huff.current > huff.length){ + ctx.last[0] = ctx.last[1] = ctx.last[2] = 1; + av_log(smk->avctx, AV_LOG_ERROR, "bigtree damaged\n"); + return -1; + } *recodes = huff.values; @@ -370,7 +375,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if(buf_size <= 769) return 0; - smk->pic.reference = 1; + smk->pic.reference = 3; smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if(avctx->reget_buffer(avctx, &smk->pic) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -388,7 +393,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac buf++; for(i = 0; i < 256; i++) - *pal++ = bytestream_get_be24(&buf); + *pal++ = 0xFF << 24 | bytestream_get_be24(&buf); buf_size -= 769; last_reset(smk->mmap_tbl, smk->mmap_last); @@ -524,6 +529,7 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&c->pic); /* decode huffman trees from extradata */ if(avctx->extradata_size < 16){ @@ -664,6 +670,8 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { + if(get_bits_left(&gb)<0) + return -1; if(i & stereo) { if(vlc[2].table) res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); @@ -698,6 +706,8 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, for(i = 0; i <= stereo; i++) *samples8++ = pred[i]; for(; i < unp_size; i++) { + if(get_bits_left(&gb)<0) + return -1; if(i & stereo){ if(vlc[1].table) res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); diff --git a/libavcodec/smc.c b/libavcodec/smc.c index f4a0b6a6a9..9ae19ffb45 100644 --- a/libavcodec/smc.c +++ b/libavcodec/smc.c @@ -2,20 +2,20 @@ * Quicktime Graphics (SMC) Video Decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -425,6 +425,7 @@ static av_cold int smc_decode_init(AVCodecContext *avctx) s->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; @@ -442,7 +443,7 @@ static int smc_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - s->frame.reference = 1; + s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; if (avctx->reget_buffer(avctx, &s->frame)) { diff --git a/libavcodec/snow.c b/libavcodec/snow.c index d7f33b4eae..88620dd28c 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -602,7 +602,7 @@ int ff_snow_frame_start(SnowContext *s){ } } - s->current_picture.reference= 1; + s->current_picture.reference= 3; if(s->avctx->get_buffer(s->avctx, &s->current_picture) < 0){ av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; diff --git a/libavcodec/snow.h b/libavcodec/snow.h index bd54994b5b..3a5cdc7175 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -2,20 +2,20 @@ * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (C) 2006 Robert Edele <yartrebo@earthlink.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/snowdata.h b/libavcodec/snowdata.h index ca2468c091..7a88f24763 100644 --- a/libavcodec/snowdata.h +++ b/libavcodec/snowdata.h @@ -2,20 +2,20 @@ * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (C) 2006 Robert Edele <yartrebo@earthlink.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/snowdec.c b/libavcodec/snowdec.c index 2b6f6e11c7..9fd25a5335 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/snowenc.c b/libavcodec/snowenc.c index cd60c3a512..284e755732 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -218,7 +218,7 @@ static av_cold int encode_init(AVCodecContext *avctx) // case PIX_FMT_YUV444P: // case PIX_FMT_YUV422P: case PIX_FMT_YUV420P: - case PIX_FMT_GRAY8: +// case PIX_FMT_GRAY8: // case PIX_FMT_YUV411P: // case PIX_FMT_YUV410P: s->colorspace_type= 0; @@ -1915,3 +1915,124 @@ AVCodec ff_snow_encoder = { .priv_class = &snowenc_class, }; #endif + + +#ifdef TEST +#undef malloc +#undef free +#undef printf + +#include "libavutil/lfg.h" +#include "libavutil/mathematics.h" + +int main(void){ + int width=256; + int height=256; + int buffer[2][width*height]; + SnowContext s; + int i; + AVLFG prng; + s.spatial_decomposition_count=6; + s.spatial_decomposition_type=1; + + av_lfg_init(&prng, 1); + + printf("testing 5/3 DWT\n"); + for(i=0; i<width*height; i++) + buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345; + + ff_spatial_dwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + + for(i=0; i<width*height; i++) + if(buffer[0][i]!= buffer[1][i]) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]); + + printf("testing 9/7 DWT\n"); + s.spatial_decomposition_type=0; + for(i=0; i<width*height; i++) + buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345; + + ff_spatial_dwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + ff_spatial_idwt(buffer[0], width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + + for(i=0; i<width*height; i++) + if(FFABS(buffer[0][i] - buffer[1][i])>20) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]); + + { + 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; + + 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"); + } + error= (int)(sqrt(error)+0.5); + errors[level][orientation]= error; + if(g) g=av_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("},\n"); + } + printf("};\n"); + { + int level=2; + 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; + + buf+=w; + buf+=stride>>1; + + memset(buffer[0], 0, sizeof(int)*width*height); + for(y=0; y<height; y++){ + for(x=0; x<width; x++){ + int tab[4]={0,2,3,1}; + buffer[0][x+width*y]= 256*256*tab[(x&1) + 2*(y&1)]; + } + } + ff_spatial_dwt(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) printf("%8"PRId64" ", d); + } + if(FFABS(height/2-y)<9) printf("\n"); + } + } + + } + return 0; +} +#endif /* TEST */ diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c new file mode 100644 index 0000000000..71641f95ff --- /dev/null +++ b/libavcodec/sonic.c @@ -0,0 +1,974 @@ +/* + * Simple free lossless/lossy audio codec + * Copyright (c) 2004 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 + */ +#include "avcodec.h" +#include "get_bits.h" +#include "golomb.h" + +/** + * @file + * Simple free lossless/lossy audio codec + * Based on Paul Francis Harrison's Bonk (http://www.logarithmic.net/pfh/bonk) + * Written and designed by Alex Beregszaszi + * + * TODO: + * - CABAC put/get_symbol + * - independent quantizer for channels + * - >2 channels support + * - more decorrelation types + * - more tap_quant tests + * - selectable intlist writers/readers (bonk-style, golomb, cabac) + */ + +#define MAX_CHANNELS 2 + +#define MID_SIDE 0 +#define LEFT_SIDE 1 +#define RIGHT_SIDE 2 + +typedef struct SonicContext { + int lossless, decorrelation; + + int num_taps, downsampling; + double quantization; + + int channels, samplerate, block_align, frame_size; + + int *tap_quant; + int *int_samples; + int *coded_samples[MAX_CHANNELS]; + + // for encoding + int *tail; + int tail_size; + int *window; + int window_size; + + // for decoding + int *predictor_k; + int *predictor_state[MAX_CHANNELS]; +} SonicContext; + +#define LATTICE_SHIFT 10 +#define SAMPLE_SHIFT 4 +#define LATTICE_FACTOR (1 << LATTICE_SHIFT) +#define SAMPLE_FACTOR (1 << SAMPLE_SHIFT) + +#define BASE_QUANT 0.6 +#define RATE_VARIATION 3.0 + +static inline int divide(int a, int b) +{ + if (a < 0) + return -( (-a + b/2)/b ); + else + return (a + b/2)/b; +} + +static inline int shift(int a,int b) +{ + return (a+(1<<(b-1))) >> b; +} + +static inline int shift_down(int a,int b) +{ + return (a>>b)+((a<0)?1:0); +} + +#if 1 +static inline int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_part) +{ + int i; + + for (i = 0; i < entries; i++) + set_se_golomb(pb, buf[i]); + + return 1; +} + +static inline int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_part) +{ + int i; + + for (i = 0; i < entries; i++) + buf[i] = get_se_golomb(gb); + + return 1; +} + +#else + +#define ADAPT_LEVEL 8 + +static int bits_to_store(uint64_t x) +{ + int res = 0; + + while(x) + { + res++; + x >>= 1; + } + return res; +} + +static void write_uint_max(PutBitContext *pb, unsigned int value, unsigned int max) +{ + int i, bits; + + if (!max) + return; + + bits = bits_to_store(max); + + for (i = 0; i < bits-1; i++) + put_bits(pb, 1, value & (1 << i)); + + if ( (value | (1 << (bits-1))) <= max) + put_bits(pb, 1, value & (1 << (bits-1))); +} + +static unsigned int read_uint_max(GetBitContext *gb, int max) +{ + int i, bits, value = 0; + + if (!max) + return 0; + + bits = bits_to_store(max); + + for (i = 0; i < bits-1; i++) + if (get_bits1(gb)) + value += 1 << i; + + if ( (value | (1<<(bits-1))) <= max) + if (get_bits1(gb)) + value += 1 << (bits-1); + + return value; +} + +static int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_part) +{ + int i, j, x = 0, low_bits = 0, max = 0; + int step = 256, pos = 0, dominant = 0, any = 0; + int *copy, *bits; + + copy = av_mallocz(4* entries); + if (!copy) + return -1; + + if (base_2_part) + { + int energy = 0; + + for (i = 0; i < entries; i++) + energy += abs(buf[i]); + + low_bits = bits_to_store(energy / (entries * 2)); + if (low_bits > 15) + low_bits = 15; + + put_bits(pb, 4, low_bits); + } + + for (i = 0; i < entries; i++) + { + put_bits(pb, low_bits, abs(buf[i])); + copy[i] = abs(buf[i]) >> low_bits; + if (copy[i] > max) + max = abs(copy[i]); + } + + bits = av_mallocz(4* entries*max); + if (!bits) + { +// av_free(copy); + return -1; + } + + for (i = 0; i <= max; i++) + { + for (j = 0; j < entries; j++) + if (copy[j] >= i) + bits[x++] = copy[j] > i; + } + + // store bitstream + while (pos < x) + { + int steplet = step >> 8; + + if (pos + steplet > x) + steplet = x - pos; + + for (i = 0; i < steplet; i++) + if (bits[i+pos] != dominant) + any = 1; + + put_bits(pb, 1, any); + + if (!any) + { + pos += steplet; + step += step / ADAPT_LEVEL; + } + else + { + int interloper = 0; + + while (((pos + interloper) < x) && (bits[pos + interloper] == dominant)) + interloper++; + + // note change + write_uint_max(pb, interloper, (step >> 8) - 1); + + pos += interloper + 1; + step -= step / ADAPT_LEVEL; + } + + if (step < 256) + { + step = 65536 / step; + dominant = !dominant; + } + } + + // store signs + for (i = 0; i < entries; i++) + if (buf[i]) + put_bits(pb, 1, buf[i] < 0); + +// av_free(bits); +// av_free(copy); + + return 0; +} + +static int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_part) +{ + int i, low_bits = 0, x = 0; + int n_zeros = 0, step = 256, dominant = 0; + int pos = 0, level = 0; + int *bits = av_mallocz(4* entries); + + if (!bits) + return -1; + + if (base_2_part) + { + low_bits = get_bits(gb, 4); + + if (low_bits) + for (i = 0; i < entries; i++) + buf[i] = get_bits(gb, low_bits); + } + +// av_log(NULL, AV_LOG_INFO, "entries: %d, low bits: %d\n", entries, low_bits); + + while (n_zeros < entries) + { + int steplet = step >> 8; + + if (!get_bits1(gb)) + { + for (i = 0; i < steplet; i++) + bits[x++] = dominant; + + if (!dominant) + n_zeros += steplet; + + step += step / ADAPT_LEVEL; + } + else + { + int actual_run = read_uint_max(gb, steplet-1); + +// av_log(NULL, AV_LOG_INFO, "actual run: %d\n", actual_run); + + for (i = 0; i < actual_run; i++) + bits[x++] = dominant; + + bits[x++] = !dominant; + + if (!dominant) + n_zeros += actual_run; + else + n_zeros++; + + step -= step / ADAPT_LEVEL; + } + + if (step < 256) + { + step = 65536 / step; + dominant = !dominant; + } + } + + // reconstruct unsigned values + n_zeros = 0; + for (i = 0; n_zeros < entries; i++) + { + while(1) + { + if (pos >= entries) + { + pos = 0; + level += 1 << low_bits; + } + + if (buf[pos] >= level) + break; + + pos++; + } + + if (bits[i]) + buf[pos] += 1 << low_bits; + else + n_zeros++; + + pos++; + } +// av_free(bits); + + // read signs + for (i = 0; i < entries; i++) + if (buf[i] && get_bits1(gb)) + buf[i] = -buf[i]; + +// av_log(NULL, AV_LOG_INFO, "zeros: %d pos: %d\n", n_zeros, pos); + + return 0; +} +#endif + +static void predictor_init_state(int *k, int *state, int order) +{ + int i; + + for (i = order-2; i >= 0; i--) + { + int j, p, x = state[i]; + + for (j = 0, p = i+1; p < order; j++,p++) + { + int tmp = x + shift_down(k[j] * state[p], LATTICE_SHIFT); + state[p] += shift_down(k[j]*x, LATTICE_SHIFT); + x = tmp; + } + } +} + +static int predictor_calc_error(int *k, int *state, int order, int error) +{ + int i, x = error - shift_down(k[order-1] * state[order-1], LATTICE_SHIFT); + +#if 1 + int *k_ptr = &(k[order-2]), + *state_ptr = &(state[order-2]); + for (i = order-2; i >= 0; i--, k_ptr--, state_ptr--) + { + int k_value = *k_ptr, state_value = *state_ptr; + x -= shift_down(k_value * state_value, LATTICE_SHIFT); + state_ptr[1] = state_value + shift_down(k_value * x, LATTICE_SHIFT); + } +#else + for (i = order-2; i >= 0; i--) + { + x -= shift_down(k[i] * state[i], LATTICE_SHIFT); + state[i+1] = state[i] + shift_down(k[i] * x, LATTICE_SHIFT); + } +#endif + + // don't drift too far, to avoid overflows + if (x > (SAMPLE_FACTOR<<16)) x = (SAMPLE_FACTOR<<16); + if (x < -(SAMPLE_FACTOR<<16)) x = -(SAMPLE_FACTOR<<16); + + state[0] = x; + + return x; +} + +#if CONFIG_SONIC_ENCODER || CONFIG_SONIC_LS_ENCODER +// Heavily modified Levinson-Durbin algorithm which +// copes better with quantization, and calculates the +// actual whitened result as it goes. + +static void modified_levinson_durbin(int *window, int window_entries, + int *out, int out_entries, int channels, int *tap_quant) +{ + int i; + int *state = av_mallocz(4* window_entries); + + memcpy(state, window, 4* window_entries); + + for (i = 0; i < out_entries; i++) + { + int step = (i+1)*channels, k, j; + double xx = 0.0, xy = 0.0; +#if 1 + int *x_ptr = &(window[step]), *state_ptr = &(state[0]); + j = window_entries - step; + for (;j>=0;j--,x_ptr++,state_ptr++) + { + double x_value = *x_ptr, state_value = *state_ptr; + xx += state_value*state_value; + xy += x_value*state_value; + } +#else + for (j = 0; j <= (window_entries - step); j++); + { + double stepval = window[step+j], stateval = window[j]; +// xx += (double)window[j]*(double)window[j]; +// xy += (double)window[step+j]*(double)window[j]; + xx += stateval*stateval; + xy += stepval*stateval; + } +#endif + if (xx == 0.0) + k = 0; + else + k = (int)(floor(-xy/xx * (double)LATTICE_FACTOR / (double)(tap_quant[i]) + 0.5)); + + if (k > (LATTICE_FACTOR/tap_quant[i])) + k = LATTICE_FACTOR/tap_quant[i]; + if (-k > (LATTICE_FACTOR/tap_quant[i])) + k = -(LATTICE_FACTOR/tap_quant[i]); + + out[i] = k; + k *= tap_quant[i]; + +#if 1 + x_ptr = &(window[step]); + state_ptr = &(state[0]); + j = window_entries - step; + for (;j>=0;j--,x_ptr++,state_ptr++) + { + int x_value = *x_ptr, state_value = *state_ptr; + *x_ptr = x_value + shift_down(k*state_value,LATTICE_SHIFT); + *state_ptr = state_value + shift_down(k*x_value, LATTICE_SHIFT); + } +#else + for (j=0; j <= (window_entries - step); j++) + { + int stepval = window[step+j], stateval=state[j]; + window[step+j] += shift_down(k * stateval, LATTICE_SHIFT); + state[j] += shift_down(k * stepval, LATTICE_SHIFT); + } +#endif + } + + av_free(state); +} + +static inline int code_samplerate(int samplerate) +{ + switch (samplerate) + { + case 44100: return 0; + case 22050: return 1; + case 11025: return 2; + case 96000: return 3; + case 48000: return 4; + case 32000: return 5; + case 24000: return 6; + case 16000: return 7; + case 8000: return 8; + } + return -1; +} + +static av_cold int sonic_encode_init(AVCodecContext *avctx) +{ + SonicContext *s = avctx->priv_data; + PutBitContext pb; + int i, version = 0; + + if (avctx->channels > MAX_CHANNELS) + { + av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n"); + return -1; /* only stereo or mono for now */ + } + + if (avctx->channels == 2) + s->decorrelation = MID_SIDE; + + if (avctx->codec->id == CODEC_ID_SONIC_LS) + { + s->lossless = 1; + s->num_taps = 32; + s->downsampling = 1; + s->quantization = 0.0; + } + else + { + s->num_taps = 128; + s->downsampling = 2; + s->quantization = 1.0; + } + + // max tap 2048 + if ((s->num_taps < 32) || (s->num_taps > 1024) || + ((s->num_taps>>5)<<5 != s->num_taps)) + { + av_log(avctx, AV_LOG_ERROR, "Invalid number of taps\n"); + return -1; + } + + // generate taps + s->tap_quant = av_mallocz(4* s->num_taps); + for (i = 0; i < s->num_taps; i++) + s->tap_quant[i] = (int)(sqrt(i+1)); + + s->channels = avctx->channels; + s->samplerate = avctx->sample_rate; + + s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling; + s->frame_size = s->channels*s->block_align*s->downsampling; + + s->tail = av_mallocz(4* s->num_taps*s->channels); + if (!s->tail) + return -1; + s->tail_size = s->num_taps*s->channels; + + s->predictor_k = av_mallocz(4 * s->num_taps); + if (!s->predictor_k) + return -1; + + for (i = 0; i < s->channels; i++) + { + s->coded_samples[i] = av_mallocz(4* s->block_align); + if (!s->coded_samples[i]) + return -1; + } + + s->int_samples = av_mallocz(4* s->frame_size); + + s->window_size = ((2*s->tail_size)+s->frame_size); + s->window = av_mallocz(4* s->window_size); + if (!s->window) + return -1; + + avctx->extradata = av_mallocz(16); + if (!avctx->extradata) + return -1; + init_put_bits(&pb, avctx->extradata, 16*8); + + put_bits(&pb, 2, version); // version + if (version == 1) + { + put_bits(&pb, 2, s->channels); + put_bits(&pb, 4, code_samplerate(s->samplerate)); + } + put_bits(&pb, 1, s->lossless); + if (!s->lossless) + put_bits(&pb, 3, SAMPLE_SHIFT); // XXX FIXME: sample precision + put_bits(&pb, 2, s->decorrelation); + put_bits(&pb, 2, s->downsampling); + put_bits(&pb, 5, (s->num_taps >> 5)-1); // 32..1024 + put_bits(&pb, 1, 0); // XXX FIXME: no custom tap quant table + + flush_put_bits(&pb); + avctx->extradata_size = put_bits_count(&pb)/8; + + av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", + version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); + + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + avctx->coded_frame->key_frame = 1; + avctx->frame_size = s->block_align*s->downsampling; + + return 0; +} + +static av_cold int sonic_encode_close(AVCodecContext *avctx) +{ + SonicContext *s = avctx->priv_data; + int i; + + av_freep(&avctx->coded_frame); + + for (i = 0; i < s->channels; i++) + av_free(s->coded_samples[i]); + + av_free(s->predictor_k); + av_free(s->tail); + av_free(s->tap_quant); + av_free(s->window); + av_free(s->int_samples); + + return 0; +} + +static int sonic_encode_frame(AVCodecContext *avctx, + uint8_t *buf, int buf_size, void *data) +{ + SonicContext *s = avctx->priv_data; + PutBitContext pb; + int i, j, ch, quant = 0, x = 0; + short *samples = data; + + init_put_bits(&pb, buf, buf_size*8); + + // short -> internal + for (i = 0; i < s->frame_size; i++) + s->int_samples[i] = samples[i]; + + if (!s->lossless) + for (i = 0; i < s->frame_size; i++) + s->int_samples[i] = s->int_samples[i] << SAMPLE_SHIFT; + + switch(s->decorrelation) + { + case MID_SIDE: + for (i = 0; i < s->frame_size; i += s->channels) + { + s->int_samples[i] += s->int_samples[i+1]; + s->int_samples[i+1] -= shift(s->int_samples[i], 1); + } + break; + case LEFT_SIDE: + for (i = 0; i < s->frame_size; i += s->channels) + s->int_samples[i+1] -= s->int_samples[i]; + break; + case RIGHT_SIDE: + for (i = 0; i < s->frame_size; i += s->channels) + s->int_samples[i] -= s->int_samples[i+1]; + break; + } + + memset(s->window, 0, 4* s->window_size); + + for (i = 0; i < s->tail_size; i++) + s->window[x++] = s->tail[i]; + + for (i = 0; i < s->frame_size; i++) + s->window[x++] = s->int_samples[i]; + + for (i = 0; i < s->tail_size; i++) + s->window[x++] = 0; + + for (i = 0; i < s->tail_size; i++) + s->tail[i] = s->int_samples[s->frame_size - s->tail_size + i]; + + // generate taps + modified_levinson_durbin(s->window, s->window_size, + s->predictor_k, s->num_taps, s->channels, s->tap_quant); + if (intlist_write(&pb, s->predictor_k, s->num_taps, 0) < 0) + return -1; + + for (ch = 0; ch < s->channels; ch++) + { + x = s->tail_size+ch; + for (i = 0; i < s->block_align; i++) + { + int sum = 0; + for (j = 0; j < s->downsampling; j++, x += s->channels) + sum += s->window[x]; + s->coded_samples[ch][i] = sum; + } + } + + // simple rate control code + if (!s->lossless) + { + double energy1 = 0.0, energy2 = 0.0; + for (ch = 0; ch < s->channels; ch++) + { + for (i = 0; i < s->block_align; i++) + { + double sample = s->coded_samples[ch][i]; + energy2 += sample*sample; + energy1 += fabs(sample); + } + } + + energy2 = sqrt(energy2/(s->channels*s->block_align)); + energy1 = sqrt(2.0)*energy1/(s->channels*s->block_align); + + // increase bitrate when samples are like a gaussian distribution + // reduce bitrate when samples are like a two-tailed exponential distribution + + if (energy2 > energy1) + energy2 += (energy2-energy1)*RATE_VARIATION; + + quant = (int)(BASE_QUANT*s->quantization*energy2/SAMPLE_FACTOR); +// av_log(avctx, AV_LOG_DEBUG, "quant: %d energy: %f / %f\n", quant, energy1, energy2); + + if (quant < 1) + quant = 1; + if (quant > 65535) + quant = 65535; + + set_ue_golomb(&pb, quant); + + quant *= SAMPLE_FACTOR; + } + + // write out coded samples + for (ch = 0; ch < s->channels; ch++) + { + if (!s->lossless) + for (i = 0; i < s->block_align; i++) + s->coded_samples[ch][i] = divide(s->coded_samples[ch][i], quant); + + if (intlist_write(&pb, s->coded_samples[ch], s->block_align, 1) < 0) + return -1; + } + +// av_log(avctx, AV_LOG_DEBUG, "used bytes: %d\n", (put_bits_count(&pb)+7)/8); + + flush_put_bits(&pb); + return (put_bits_count(&pb)+7)/8; +} +#endif /* CONFIG_SONIC_ENCODER || CONFIG_SONIC_LS_ENCODER */ + +#if CONFIG_SONIC_DECODER +static const int samplerate_table[] = + { 44100, 22050, 11025, 96000, 48000, 32000, 24000, 16000, 8000 }; + +static av_cold int sonic_decode_init(AVCodecContext *avctx) +{ + SonicContext *s = avctx->priv_data; + GetBitContext gb; + int i, version; + + s->channels = avctx->channels; + s->samplerate = avctx->sample_rate; + + if (!avctx->extradata) + { + av_log(avctx, AV_LOG_ERROR, "No mandatory headers present\n"); + return -1; + } + + init_get_bits(&gb, avctx->extradata, avctx->extradata_size); + + version = get_bits(&gb, 2); + if (version > 1) + { + av_log(avctx, AV_LOG_ERROR, "Unsupported Sonic version, please report\n"); + return -1; + } + + if (version == 1) + { + s->channels = get_bits(&gb, 2); + s->samplerate = samplerate_table[get_bits(&gb, 4)]; + av_log(avctx, AV_LOG_INFO, "Sonicv2 chans: %d samprate: %d\n", + s->channels, s->samplerate); + } + + if (s->channels > MAX_CHANNELS) + { + av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n"); + return -1; + } + + s->lossless = get_bits1(&gb); + if (!s->lossless) + skip_bits(&gb, 3); // XXX FIXME + s->decorrelation = get_bits(&gb, 2); + + s->downsampling = get_bits(&gb, 2); + s->num_taps = (get_bits(&gb, 5)+1)<<5; + if (get_bits1(&gb)) // XXX FIXME + av_log(avctx, AV_LOG_INFO, "Custom quant table\n"); + + s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling; + s->frame_size = s->channels*s->block_align*s->downsampling; +// avctx->frame_size = s->block_align; + + av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", + version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); + + // generate taps + s->tap_quant = av_mallocz(4* s->num_taps); + for (i = 0; i < s->num_taps; i++) + s->tap_quant[i] = (int)(sqrt(i+1)); + + s->predictor_k = av_mallocz(4* s->num_taps); + + for (i = 0; i < s->channels; i++) + { + s->predictor_state[i] = av_mallocz(4* s->num_taps); + if (!s->predictor_state[i]) + return -1; + } + + for (i = 0; i < s->channels; i++) + { + s->coded_samples[i] = av_mallocz(4* s->block_align); + if (!s->coded_samples[i]) + return -1; + } + s->int_samples = av_mallocz(4* s->frame_size); + + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + return 0; +} + +static av_cold int sonic_decode_close(AVCodecContext *avctx) +{ + SonicContext *s = avctx->priv_data; + int i; + + av_free(s->int_samples); + av_free(s->tap_quant); + av_free(s->predictor_k); + + for (i = 0; i < s->channels; i++) + { + av_free(s->predictor_state[i]); + av_free(s->coded_samples[i]); + } + + return 0; +} + +static int sonic_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + AVPacket *avpkt) +{ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + SonicContext *s = avctx->priv_data; + GetBitContext gb; + int i, quant, ch, j; + short *samples = data; + + if (buf_size == 0) return 0; + +// av_log(NULL, AV_LOG_INFO, "buf_size: %d\n", buf_size); + + init_get_bits(&gb, buf, buf_size*8); + + intlist_read(&gb, s->predictor_k, s->num_taps, 0); + + // dequantize + for (i = 0; i < s->num_taps; i++) + s->predictor_k[i] *= s->tap_quant[i]; + + if (s->lossless) + quant = 1; + else + quant = get_ue_golomb(&gb) * SAMPLE_FACTOR; + +// av_log(NULL, AV_LOG_INFO, "quant: %d\n", quant); + + for (ch = 0; ch < s->channels; ch++) + { + int x = ch; + + predictor_init_state(s->predictor_k, s->predictor_state[ch], s->num_taps); + + intlist_read(&gb, s->coded_samples[ch], s->block_align, 1); + + for (i = 0; i < s->block_align; i++) + { + for (j = 0; j < s->downsampling - 1; j++) + { + s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, 0); + x += s->channels; + } + + s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, s->coded_samples[ch][i] * quant); + x += s->channels; + } + + for (i = 0; i < s->num_taps; i++) + s->predictor_state[ch][i] = s->int_samples[s->frame_size - s->channels + ch - i*s->channels]; + } + + switch(s->decorrelation) + { + case MID_SIDE: + for (i = 0; i < s->frame_size; i += s->channels) + { + s->int_samples[i+1] += shift(s->int_samples[i], 1); + s->int_samples[i] -= s->int_samples[i+1]; + } + break; + case LEFT_SIDE: + for (i = 0; i < s->frame_size; i += s->channels) + s->int_samples[i+1] += s->int_samples[i]; + break; + case RIGHT_SIDE: + for (i = 0; i < s->frame_size; i += s->channels) + s->int_samples[i] += s->int_samples[i+1]; + break; + } + + if (!s->lossless) + for (i = 0; i < s->frame_size; i++) + s->int_samples[i] = shift(s->int_samples[i], SAMPLE_SHIFT); + + // internal -> short + for (i = 0; i < s->frame_size; i++) + samples[i] = av_clip_int16(s->int_samples[i]); + + align_get_bits(&gb); + + *data_size = s->frame_size * 2; + + return (get_bits_count(&gb)+7)/8; +} + +AVCodec ff_sonic_decoder = { + .name = "sonic", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_SONIC, + .priv_data_size = sizeof(SonicContext), + .init = sonic_decode_init, + .close = sonic_decode_close, + .decode = sonic_decode_frame, + .long_name = NULL_IF_CONFIG_SMALL("Sonic"), +}; +#endif /* CONFIG_SONIC_DECODER */ + +#if CONFIG_SONIC_ENCODER +AVCodec ff_sonic_encoder = { + .name = "sonic", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_SONIC, + .priv_data_size = sizeof(SonicContext), + .init = sonic_encode_init, + .encode = sonic_encode_frame, + .close = sonic_encode_close, + .long_name = NULL_IF_CONFIG_SMALL("Sonic"), +}; +#endif + +#if CONFIG_SONIC_LS_ENCODER +AVCodec ff_sonic_ls_encoder = { + .name = "sonicls", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_SONIC_LS, + .priv_data_size = sizeof(SonicContext), + .init = sonic_encode_init, + .encode = sonic_encode_frame, + .close = sonic_encode_close, + .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"), +}; +#endif diff --git a/libavcodec/sp5x.h b/libavcodec/sp5x.h index 1577302e3c..004fcbbc93 100644 --- a/libavcodec/sp5x.h +++ b/libavcodec/sp5x.h @@ -2,20 +2,20 @@ * Sunplus JPEG tables * Copyright (c) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c index 4c42ab166c..4bf45f5454 100644 --- a/libavcodec/sp5xdec.c +++ b/libavcodec/sp5xdec.c @@ -2,20 +2,20 @@ * Sunplus JPEG decoder (SP5X) * Copyright (c) 2003 Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sparc/dsputil_vis.c b/libavcodec/sparc/dsputil_vis.c index 5a9fbc2648..7181299801 100644 --- a/libavcodec/sparc/dsputil_vis.c +++ b/libavcodec/sparc/dsputil_vis.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2003 David S. Miller <davem@redhat.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sparc/dsputil_vis.h b/libavcodec/sparc/dsputil_vis.h index 4be86e25e0..e1cbcb49e3 100644 --- a/libavcodec/sparc/dsputil_vis.h +++ b/libavcodec/sparc/dsputil_vis.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sparc/simple_idct_vis.c b/libavcodec/sparc/simple_idct_vis.c index f9fcf809fb..d98bf37651 100644 --- a/libavcodec/sparc/simple_idct_vis.c +++ b/libavcodec/sparc/simple_idct_vis.c @@ -5,20 +5,20 @@ * I did consult the following fine web page about dct * http://www.geocities.com/ssavekar/dct.htm * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/sparc/vis.h b/libavcodec/sparc/vis.h index 505c735cbb..adee91bd6f 100644 --- a/libavcodec/sparc/vis.h +++ b/libavcodec/sparc/vis.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2003 David S. Miller <davem@redhat.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/srtdec.c b/libavcodec/srtdec.c index 677c5501f8..aa73f4c7bf 100644 --- a/libavcodec/srtdec.c +++ b/libavcodec/srtdec.c @@ -2,20 +2,20 @@ * SubRip subtitle decoder * Copyright (c) 2010 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -216,8 +216,6 @@ static int srt_decode_frame(AVCodecContext *avctx, if (avpkt->size <= 0) return avpkt->size; - ff_ass_init(sub); - while (ptr < end && *ptr) { ptr = read_ts(ptr, &ts_start, &ts_end, &x1, &y1, &x2, &y2); if (!ptr) diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c new file mode 100644 index 0000000000..56d3397828 --- /dev/null +++ b/libavcodec/srtenc.c @@ -0,0 +1,301 @@ +/* + * SubRip subtitle encoder + * Copyright (c) 2010 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 + */ + +#include <stdarg.h> +#include "avcodec.h" +#include "libavutil/avstring.h" +#include "ass_split.h" +#include "ass.h" + + +#define SRT_STACK_SIZE 64 + +typedef struct { + AVCodecContext *avctx; + ASSSplitContext *ass_ctx; + char buffer[2048]; + char *ptr; + char *end; + char *dialog_start; + int count; + char stack[SRT_STACK_SIZE]; + int stack_ptr; + int alignment_applied; +} SRTContext; + + +#ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 2, 3))) +#endif +static void srt_print(SRTContext *s, const char *str, ...) +{ + va_list vargs; + va_start(vargs, str); + s->ptr += vsnprintf(s->ptr, s->end - s->ptr, str, vargs); + va_end(vargs); +} + +static int srt_stack_push(SRTContext *s, const char c) +{ + if (s->stack_ptr >= SRT_STACK_SIZE) + return -1; + s->stack[s->stack_ptr++] = c; + return 0; +} + +static char srt_stack_pop(SRTContext *s) +{ + if (s->stack_ptr <= 0) + return 0; + return s->stack[--s->stack_ptr]; +} + +static int srt_stack_find(SRTContext *s, const char c) +{ + int i; + for (i = s->stack_ptr-1; i >= 0; i--) + if (s->stack[i] == c) + break; + return i; +} + +static void srt_close_tag(SRTContext *s, char tag) +{ + srt_print(s, "</%c%s>", tag, tag == 'f' ? "ont" : ""); +} + +static void srt_stack_push_pop(SRTContext *s, const char c, int close) +{ + if (close) { + int i = c ? srt_stack_find(s, c) : 0; + if (i < 0) + return; + while (s->stack_ptr != i) + srt_close_tag(s, srt_stack_pop(s)); + } else if (srt_stack_push(s, c) < 0) + av_log(s->avctx, AV_LOG_ERROR, "tag stack overflow\n"); +} + +static void srt_style_apply(SRTContext *s, const char *style) +{ + ASSStyle *st = ass_style_get(s->ass_ctx, style); + if (st) { + int c = st->primary_color & 0xFFFFFF; + if (st->font_name && strcmp(st->font_name, ASS_DEFAULT_FONT) || + st->font_size != ASS_DEFAULT_FONT_SIZE || + c != ASS_DEFAULT_COLOR) { + srt_print(s, "<font"); + if (st->font_name && strcmp(st->font_name, ASS_DEFAULT_FONT)) + srt_print(s, " face=\"%s\"", st->font_name); + if (st->font_size != ASS_DEFAULT_FONT_SIZE) + srt_print(s, " size=\"%d\"", st->font_size); + if (c != ASS_DEFAULT_COLOR) + srt_print(s, " color=\"#%06x\"", + (c & 0xFF0000) >> 16 | c & 0xFF00 | (c & 0xFF) << 16); + srt_print(s, ">"); + srt_stack_push(s, 'f'); + } + if (st->bold != ASS_DEFAULT_BOLD) { + srt_print(s, "<b>"); + srt_stack_push(s, 'b'); + } + if (st->italic != ASS_DEFAULT_ITALIC) { + srt_print(s, "<i>"); + srt_stack_push(s, 'i'); + } + if (st->underline != ASS_DEFAULT_UNDERLINE) { + srt_print(s, "<u>"); + srt_stack_push(s, 'u'); + } + if (st->alignment != ASS_DEFAULT_ALIGNMENT) { + srt_print(s, "{\\an%d}", st->alignment); + s->alignment_applied = 1; + } + } +} + + +static av_cold int srt_encode_init(AVCodecContext *avctx) +{ + SRTContext *s = avctx->priv_data; + s->avctx = avctx; + s->ass_ctx = ff_ass_split(avctx->subtitle_header); + return s->ass_ctx ? 0 : AVERROR_INVALIDDATA; +} + +static void srt_text_cb(void *priv, const char *text, int len) +{ + SRTContext *s = priv; + av_strlcpy(s->ptr, text, FFMIN(s->end-s->ptr, len+1)); + s->ptr += len; +} + +static void srt_new_line_cb(void *priv, int forced) +{ + srt_print(priv, "\r\n"); +} + +static void srt_style_cb(void *priv, char style, int close) +{ + srt_stack_push_pop(priv, style, close); + if (!close) + srt_print(priv, "<%c>", style); +} + +static void srt_color_cb(void *priv, unsigned int color, unsigned int color_id) +{ + if (color_id > 1) + return; + srt_stack_push_pop(priv, 'f', color == 0xFFFFFFFF); + if (color != 0xFFFFFFFF) + srt_print(priv, "<font color=\"#%06x\">", + (color & 0xFF0000) >> 16 | color & 0xFF00 | (color & 0xFF) << 16); +} + +static void srt_font_name_cb(void *priv, const char *name) +{ + srt_stack_push_pop(priv, 'f', !name); + if (name) + srt_print(priv, "<font face=\"%s\">", name); +} + +static void srt_font_size_cb(void *priv, int size) +{ + srt_stack_push_pop(priv, 'f', size < 0); + if (size >= 0) + srt_print(priv, "<font size=\"%d\">", size); +} + +static void srt_alignment_cb(void *priv, int alignment) +{ + SRTContext *s = priv; + if (!s->alignment_applied && alignment >= 0) { + srt_print(s, "{\\an%d}", alignment); + s->alignment_applied = 1; + } +} + +static void srt_cancel_overrides_cb(void *priv, const char *style) +{ + srt_stack_push_pop(priv, 0, 1); + srt_style_apply(priv, style); +} + +static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2, + int t1, int t2) +{ + SRTContext *s = priv; + char buffer[32]; + int len = snprintf(buffer, sizeof(buffer), + " X1:%03u X2:%03u Y1:%03u Y2:%03u", x1, x2, y1, y2); + if (s->end - s->ptr > len) { + memmove(s->dialog_start+len, s->dialog_start, s->ptr-s->dialog_start+1); + memcpy(s->dialog_start, buffer, len); + s->ptr += len; + } +} + +static void srt_end_cb(void *priv) +{ + srt_stack_push_pop(priv, 0, 1); + srt_print(priv, "\r\n\r\n"); +} + +static const ASSCodesCallbacks srt_callbacks = { + .text = srt_text_cb, + .new_line = srt_new_line_cb, + .style = srt_style_cb, + .color = srt_color_cb, + .font_name = srt_font_name_cb, + .font_size = srt_font_size_cb, + .alignment = srt_alignment_cb, + .cancel_overrides = srt_cancel_overrides_cb, + .move = srt_move_cb, + .end = srt_end_cb, +}; + +static int srt_encode_frame(AVCodecContext *avctx, + unsigned char *buf, int bufsize, void *data) +{ + SRTContext *s = avctx->priv_data; + AVSubtitle *sub = data; + ASSDialog *dialog; + int i, len, num; + + s->ptr = s->buffer; + s->end = s->ptr + sizeof(s->buffer); + + for (i=0; i<sub->num_rects; i++) { + + if (sub->rects[i]->type != SUBTITLE_ASS) { + av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n"); + return AVERROR(ENOSYS); + } + + dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num); + for (; dialog && num--; dialog++) { + int sh, sm, ss, sc = 10 * dialog->start; + int eh, em, es, ec = 10 * dialog->end; + sh = sc/3600000; sc -= 3600000*sh; + sm = sc/ 60000; sc -= 60000*sm; + ss = sc/ 1000; sc -= 1000*ss; + eh = ec/3600000; ec -= 3600000*eh; + em = ec/ 60000; ec -= 60000*em; + es = ec/ 1000; ec -= 1000*es; + srt_print(s,"%d\r\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n", + ++s->count, sh, sm, ss, sc, eh, em, es, ec); + s->alignment_applied = 0; + s->dialog_start = s->ptr - 2; + srt_style_apply(s, dialog->style); + ff_ass_split_override_codes(&srt_callbacks, s, dialog->text); + } + } + + if (s->ptr == s->buffer) + return 0; + + len = av_strlcpy(buf, s->buffer, bufsize); + + if (len > bufsize-1) { + av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n"); + return -1; + } + + return len; +} + +static int srt_encode_close(AVCodecContext *avctx) +{ + SRTContext *s = avctx->priv_data; + ff_ass_split_free(s->ass_ctx); + return 0; +} + +AVCodec ff_srt_encoder = { + .name = "srt", + .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"), + .type = AVMEDIA_TYPE_SUBTITLE, + .id = CODEC_ID_SRT, + .priv_data_size = sizeof(SRTContext), + .init = srt_encode_init, + .encode = srt_encode_frame, + .close = srt_encode_close, +}; diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c index 601ba6efc9..aa12947f5f 100644 --- a/libavcodec/sunrast.c +++ b/libavcodec/sunrast.c @@ -2,20 +2,20 @@ * Sun Rasterfile (.sun/.ras/im{1,8,24}/.sunras) image decoder * Copyright (c) 2007, 2008 Ivo van Poorten * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -70,7 +70,7 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *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; + uint8_t *ptr, *ptr2 = NULL; const uint8_t *bufstart = buf; if (avpkt->size < 32) @@ -89,7 +89,7 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, maplength = AV_RB32(buf + 28); buf += 32; - if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF || type == RT_EXPERIMENTAL) { + if (type == RT_EXPERIMENTAL) { av_log_ask_for_sample(avctx, "unsupported (compression) type\n"); return AVERROR_PATCHWELCOME; } @@ -106,17 +106,27 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, return -1; } + if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) { + av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n"); + return -1; + } switch (depth) { case 1: - avctx->pix_fmt = PIX_FMT_MONOWHITE; + avctx->pix_fmt = maplength ? PIX_FMT_PAL8 : PIX_FMT_MONOWHITE; + break; + case 4: + avctx->pix_fmt = maplength ? PIX_FMT_PAL8 : PIX_FMT_NONE; break; case 8: - avctx->pix_fmt = PIX_FMT_PAL8; + avctx->pix_fmt = maplength ? PIX_FMT_PAL8 : PIX_FMT_GRAY8; break; case 24: avctx->pix_fmt = (type == RT_FORMAT_RGB) ? PIX_FMT_RGB24 : PIX_FMT_BGR24; break; + case 32: + avctx->pix_fmt = (type == RT_FORMAT_RGB) ? PIX_FMT_RGB0 : PIX_FMT_BGR0; + break; default: av_log(avctx, AV_LOG_ERROR, "invalid depth\n"); return -1; @@ -137,10 +147,10 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, if (buf_end - buf < maplength) return AVERROR_INVALIDDATA; - if (depth != 8 && maplength) { + 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) { + } else if (maplength) { unsigned int len = maplength / 3; if (!maplength) { @@ -154,13 +164,20 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, 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]; + *(uint32_t *)ptr = (0xFF<<24) + (buf[x]<<16) + (buf[len+x]<<8) + buf[len+len+x]; } buf += maplength; + if (maplength && depth < 8) { + ptr = ptr2 = av_malloc((w + 15) * h); + if (!ptr) + return AVERROR(ENOMEM); + stride = (w + 15 >> 3) * depth; + } else { ptr = p->data[0]; stride = p->linesize[0]; + } /* scanlines are aligned on 16 bit boundaries */ len = (depth * w + 7) >> 3; @@ -201,6 +218,30 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, buf += alen; } } + if (avctx->pix_fmt == PIX_FMT_PAL8 && depth < 8) { + uint8_t *ptr_free = ptr2; + ptr = p->data[0]; + for (y=0; y<h; y++) { + for (x = 0; x < (w + 7 >> 3) * depth; x++) { + if (depth == 1) { + ptr[8*x] = ptr2[x] >> 7; + ptr[8*x+1] = ptr2[x] >> 6 & 1; + ptr[8*x+2] = ptr2[x] >> 5 & 1; + ptr[8*x+3] = ptr2[x] >> 4 & 1; + ptr[8*x+4] = ptr2[x] >> 3 & 1; + ptr[8*x+5] = ptr2[x] >> 2 & 1; + ptr[8*x+6] = ptr2[x] >> 1 & 1; + ptr[8*x+7] = ptr2[x] & 1; + } else { + ptr[2*x] = ptr2[x] >> 4; + ptr[2*x+1] = ptr2[x] & 0xF; + } + } + ptr += p->linesize[0]; + ptr2 += (w + 15 >> 3) * depth; + } + av_freep(&ptr_free); + } *picture = s->picture; *data_size = sizeof(AVFrame); diff --git a/libavcodec/svq1.c b/libavcodec/svq1.c index b7e3af0a28..d0e113267b 100644 --- a/libavcodec/svq1.c +++ b/libavcodec/svq1.c @@ -8,20 +8,20 @@ * * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/svq1.h b/libavcodec/svq1.h index 066ea47fb6..3ade05d848 100644 --- a/libavcodec/svq1.h +++ b/libavcodec/svq1.h @@ -8,20 +8,20 @@ * * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/svq1_cb.h b/libavcodec/svq1_cb.h index e22cd60e23..7926ce1377 100644 --- a/libavcodec/svq1_cb.h +++ b/libavcodec/svq1_cb.h @@ -6,20 +6,20 @@ * Copyright (C) 2002 the xine project * Copyright (C) 2002 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/svq1_vlc.h b/libavcodec/svq1_vlc.h index 4d03b081ea..272597e1e0 100644 --- a/libavcodec/svq1_vlc.h +++ b/libavcodec/svq1_vlc.h @@ -1,20 +1,20 @@ /* * copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 69dbd1b25d..83fe07e4c7 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -8,20 +8,20 @@ * * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -141,7 +141,7 @@ static const uint8_t string_table[256] = { break;\ /* add child nodes */\ list[n++] = list[i];\ - list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level / 2) + 1));\ + list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level >> 1) + 1));\ } #define SVQ1_ADD_CODEBOOK()\ @@ -202,7 +202,7 @@ static const uint8_t string_table[256] = { entries[j] = (((bit_cache >> (4*(stages - j - 1))) & 0xF) + 16*j) << (level + 1);\ }\ mean -= (stages * 128);\ - n4 = ((mean + (mean >> 31)) << 16) | (mean & 0xFFFF); + n4 = (mean << 16) + mean; static int svq1_decode_block_intra (GetBitContext *bitbuf, uint8_t *pixels, int pitch ) { uint32_t bit_cache; diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index 80bae3cc85..feceaee6e8 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -2,20 +2,20 @@ * SVQ1 Encoder * Copyright (C) 2004 Mike Melanson <melanson@pcisys.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -563,6 +563,10 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx) av_freep(&s->motion_val8[i]); av_freep(&s->motion_val16[i]); } + if(s->current_picture.data[0]) + avctx->release_buffer(avctx, &s->current_picture); + if(s->last_picture.data[0]) + avctx->release_buffer(avctx, &s->last_picture); return 0; } diff --git a/libavcodec/svq1enc_cb.h b/libavcodec/svq1enc_cb.h index 1c86ebeb98..7eff82ee1f 100644 --- a/libavcodec/svq1enc_cb.h +++ b/libavcodec/svq1enc_cb.h @@ -2,20 +2,20 @@ * SVQ1 Encoder * Copyright (C) 2004 Mike Melanson <melanson@pcisys.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/svq3.c b/libavcodec/svq3.c index 3cd95ba594..d96ce8ee8d 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -1,20 +1,20 @@ /* - * Copyright (c) 2003 The Libav Project + * Copyright (c) 2003 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +37,7 @@ * * You will know you have these parameters passed correctly when the decoder * correctly decodes this file: - * http://samples.libav.org/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov + * http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov */ #include "internal.h" #include "dsputil.h" @@ -70,6 +70,8 @@ typedef struct { int unknown_flag; int next_slice_index; uint32_t watermark_key; + uint8_t *buf; + int buf_size; } SVQ3Context; #define FULLPEL_MODE 1 @@ -219,7 +221,7 @@ static inline int svq3_decode_block(GetBitContext *gb, DCTELEM *block, for (limit = (16 >> intra); index < 16; index = limit, limit += 8) { for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) { - if (vlc == INVALID_VLC) + if (vlc < 0) return -1; sign = (vlc & 0x1) - 1; @@ -237,7 +239,7 @@ static inline int svq3_decode_block(GetBitContext *gb, DCTELEM *block, level = ((vlc + 9) >> 2) - run; } } else { - if (vlc < 16) { + if (vlc < 16U) { run = svq3_dct_tables[intra][vlc].run; level = svq3_dct_tables[intra][vlc].level; } else if (intra) { @@ -569,7 +571,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) for (i = 0; i < 16; i+=2) { vlc = svq3_get_ue_golomb(&s->gb); - if (vlc >= 25){ + if (vlc >= 25U){ av_log(h->s.avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc); return -1; } @@ -612,7 +614,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) dir = i_mb_type_info[mb_type - 8].pred_mode; dir = (dir >> 1) ^ 3*(dir & 1) ^ 1; - if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir)) == -1){ + if ((h->intra16x16_pred_mode = ff_h264_check_intra16x16_pred_mode(h, dir)) == -1){ av_log(h->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n"); return -1; } @@ -641,7 +643,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) } if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) { - if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48){ + if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48U){ av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc); return -1; } @@ -651,7 +653,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) if (IS_INTRA16x16(mb_type) || (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) { s->qscale += svq3_get_se_golomb(&s->gb); - if (s->qscale > 31){ + if (s->qscale > 31U){ av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); return -1; } @@ -711,7 +713,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) s->current_picture.f.mb_type[mb_xy] = mb_type; if (IS_INTRA(mb_type)) { - h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8); + h->chroma_pred_mode = ff_h264_check_intra_chroma_pred_mode(h, DC_PRED8x8); } return 0; @@ -755,7 +757,7 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) skip_bits_long(&s->gb, 0); } - if ((i = svq3_get_ue_golomb(&s->gb)) == INVALID_VLC || i >= 3){ + if ((i = svq3_get_ue_golomb(&s->gb)) >= 3U){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", i); return -1; } @@ -829,6 +831,7 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) svq3->thirdpel_flag = 1; svq3->unknown_flag = 0; + /* prowl for the "SEQH" marker in the extradata */ extradata = (unsigned char *)avctx->extradata; for (m = 0; m < avctx->extradata_size; m++) { @@ -937,12 +940,12 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; SVQ3Context *svq3 = avctx->priv_data; H264Context *h = &svq3->h; MpegEncContext *s = &h->s; int buf_size = avpkt->size; - int m, mb_type; + int m, mb_type, left; + uint8_t *buf; /* special case for last picture */ if (buf_size == 0) { @@ -954,10 +957,21 @@ static int svq3_decode_frame(AVCodecContext *avctx, return 0; } - init_get_bits (&s->gb, buf, 8*buf_size); - s->mb_x = s->mb_y = h->mb_xy = 0; + if (svq3->watermark_key) { + av_fast_malloc(&svq3->buf, &svq3->buf_size, + buf_size+FF_INPUT_BUFFER_PADDING_SIZE); + if (!svq3->buf) + return AVERROR(ENOMEM); + memcpy(svq3->buf, avpkt->data, buf_size); + buf = svq3->buf; + } else { + buf = avpkt->data; + } + + init_get_bits(&s->gb, buf, 8*buf_size); + if (svq3_decode_slice_header(avctx)) return -1; @@ -1064,6 +1078,18 @@ static int svq3_decode_frame(AVCodecContext *avctx, ff_draw_horiz_band(s, 16*s->mb_y, 16); } + left = buf_size*8 - get_bits_count(&s->gb); + + if (s->mb_y != s->mb_height || s->mb_x != s->mb_width) { + av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, s->mb_y, s->mb_x, left); + //av_hex_dump(stderr, buf+buf_size-8, 8); + } + + if (left < 0) { + av_log(avctx, AV_LOG_ERROR, "frame num %d left %d\n", avctx->frame_number, left); + return -1; + } + MPV_frame_end(s); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { @@ -1090,6 +1116,9 @@ static int svq3_decode_end(AVCodecContext *avctx) MPV_common_end(s); + av_freep(&svq3->buf); + svq3->buf_size = 0; + return 0; } diff --git a/libavcodec/synth_filter.c b/libavcodec/synth_filter.c index 8e6f1202fe..5f10530974 100644 --- a/libavcodec/synth_filter.c +++ b/libavcodec/synth_filter.c @@ -1,20 +1,20 @@ /* * copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/synth_filter.h b/libavcodec/synth_filter.h index 7b73578f68..33edcc437f 100644 --- a/libavcodec/synth_filter.h +++ b/libavcodec/synth_filter.h @@ -1,20 +1,20 @@ /* * copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/tableprint.h b/libavcodec/tableprint.h index 81bb9afdcb..1b39dc6ba1 100644 --- a/libavcodec/tableprint.h +++ b/libavcodec/tableprint.h @@ -3,20 +3,20 @@ * * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/targa.c b/libavcodec/targa.c index 00da7587d0..573992ff8a 100644 --- a/libavcodec/targa.c +++ b/libavcodec/targa.c @@ -2,20 +2,20 @@ * Targa (.tga) image decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -55,7 +55,7 @@ static int targa_decode_rle(AVCodecContext *avctx, TargaContext *s, const uint8_ type = *src++; count = (type & 0x7F) + 1; type &= 0x80; - if((x + count > w) && (x + count + 1 > (h - y) * w)){ + if(x + count > (h - y) * w){ av_log(avctx, AV_LOG_ERROR, "Packet went out of bounds: position (%i,%i) size %i\n", x, y, count); return -1; } @@ -70,7 +70,7 @@ static int targa_decode_rle(AVCodecContext *avctx, TargaContext *s, const uint8_ *dst = *src; break; case 2: - *((uint16_t*)dst) = AV_RL16(src); + AV_WN16A(dst, AV_RN16A(src)); break; case 3: dst[0] = src[0]; @@ -78,7 +78,7 @@ static int targa_decode_rle(AVCodecContext *avctx, TargaContext *s, const uint8_ dst[2] = src[2]; break; case 4: - *((uint32_t*)dst) = AV_RL32(src); + AV_WN32A(dst, AV_RN32A(src)); break; } dst += depth; @@ -109,21 +109,26 @@ static int decode_frame(AVCodecContext *avctx, AVFrame * const p= (AVFrame*)&s->picture; uint8_t *dst; int stride; - int idlen, compr, y, w, h, bpp, flags; + int idlen, pal, compr, y, w, h, bpp, flags; int first_clr, colors, csize; /* parse image header */ CHECK_BUFFER_SIZE(buf, buf_end, 18, "header"); idlen = *buf++; - buf++; /* pal */ + pal = *buf++; compr = *buf++; - first_clr = AV_RL16(buf); buf += 2; - colors = AV_RL16(buf); buf += 2; + first_clr = bytestream_get_le16(&buf); + colors = bytestream_get_le16(&buf); csize = *buf++; + if (!pal && (first_clr || colors || csize)) { + av_log(avctx, AV_LOG_WARNING, "File without colormap has colormap information set.\n"); + // specification says we should ignore those value in this case + first_clr = colors = csize = 0; + } buf += 2; /* x */ - y = AV_RL16(buf); buf += 2; - w = AV_RL16(buf); buf += 2; - h = AV_RL16(buf); buf += 2; + y = bytestream_get_le16(&buf); + w = bytestream_get_le16(&buf); + h = bytestream_get_le16(&buf); bpp = *buf++; flags = *buf++; //skip identifier if any @@ -137,16 +142,14 @@ static int decode_frame(AVCodecContext *avctx, avctx->pix_fmt = ((compr & (~TGA_RLE)) == TGA_BW) ? PIX_FMT_GRAY8 : PIX_FMT_PAL8; break; case 15: - avctx->pix_fmt = PIX_FMT_RGB555; - break; case 16: - avctx->pix_fmt = PIX_FMT_RGB555; + avctx->pix_fmt = PIX_FMT_RGB555LE; break; case 24: avctx->pix_fmt = PIX_FMT_BGR24; break; case 32: - avctx->pix_fmt = PIX_FMT_RGB32; + avctx->pix_fmt = PIX_FMT_BGRA; break; default: av_log(avctx, AV_LOG_ERROR, "Bit depth %i is not supported\n", s->bpp); @@ -198,7 +201,7 @@ static int decode_frame(AVCodecContext *avctx, case 3: /* RGB24 */ for (t = 0; t < colors; t++) - *pal++ = bytestream_get_le24(&buf); + *pal++ = (0xffU<<24) | bytestream_get_le24(&buf); break; case 2: /* RGB555 */ @@ -209,7 +212,7 @@ static int decode_frame(AVCodecContext *avctx, ((v & 0x001F) << 3); /* left bit replication */ v |= (v & 0xE0E0E0U) >> 5; - *pal++ = v; + *pal++ = (0xffU<<24) | v; } break; } @@ -228,18 +231,6 @@ static int decode_frame(AVCodecContext *avctx, size_t img_size = s->width * ((s->bpp + 1) >> 3); CHECK_BUFFER_SIZE(buf, buf_end, img_size, "image data"); for(y = 0; y < s->height; y++){ -#if HAVE_BIGENDIAN - int x; - if((s->bpp + 1) >> 3 == 2){ - uint16_t *dst16 = (uint16_t*)dst; - for(x = 0; x < s->width; x++) - dst16[x] = AV_RL16(buf + x * 2); - }else if((s->bpp + 1) >> 3 == 4){ - uint32_t *dst32 = (uint32_t*)dst; - for(x = 0; x < s->width; x++) - dst32[x] = AV_RL32(buf + x * 4); - }else -#endif memcpy(dst, buf, img_size); dst += stride; @@ -247,6 +238,29 @@ static int decode_frame(AVCodecContext *avctx, } } } + if(flags & 0x10){ // right-to-left, needs horizontal flip + int x; + for(y = 0; y < s->height; y++){ + void *line = &p->data[0][y * p->linesize[0]]; + for(x = 0; x < s->width >> 1; x++){ + switch(s->bpp){ + case 32: + FFSWAP(uint32_t, ((uint32_t *)line)[x], ((uint32_t *)line)[s->width - x - 1]); + break; + case 24: + FFSWAP(uint8_t, ((uint8_t *)line)[3 * x ], ((uint8_t *)line)[3 * s->width - 3 * x - 3]); + FFSWAP(uint8_t, ((uint8_t *)line)[3 * x + 1], ((uint8_t *)line)[3 * s->width - 3 * x - 2]); + FFSWAP(uint8_t, ((uint8_t *)line)[3 * x + 2], ((uint8_t *)line)[3 * s->width - 3 * x - 1]); + break; + case 16: + FFSWAP(uint16_t, ((uint16_t *)line)[x], ((uint16_t *)line)[s->width - x - 1]); + break; + case 8: + FFSWAP(uint8_t, ((uint8_t *)line)[x], ((uint8_t *)line)[s->width - x - 1]); + } + } + } + } *picture= *(AVFrame*)&s->picture; *data_size = sizeof(AVPicture); diff --git a/libavcodec/targa.h b/libavcodec/targa.h index f4ef5537b1..158a5ea0f4 100644 --- a/libavcodec/targa.h +++ b/libavcodec/targa.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/targaenc.c b/libavcodec/targaenc.c index 276bcc83eb..1171f605a2 100644 --- a/libavcodec/targaenc.c +++ b/libavcodec/targaenc.c @@ -2,20 +2,20 @@ * Targa (.tga) image encoder * Copyright (c) 2007 Bobby Bingham * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/thread.h b/libavcodec/thread.h index 7f018fc441..205e45035d 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2008 Alexander Strange <astrange@ithinksw.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c index 12d5bce4ac..a9ebb4786c 100644 --- a/libavcodec/tiertexseqv.c +++ b/libavcodec/tiertexseqv.c @@ -2,20 +2,20 @@ * Tiertex Limited SEQ Video Decoder * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -178,7 +178,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int for (i = 0; i < 256; i++) { for (j = 0; j < 3; j++, data++) c[j] = (*data << 2) | (*data >> 4); - palette[i] = AV_RB24(c); + palette[i] = 0xFF << 24 | AV_RB24(c); } seq->frame.palette_has_changed = 1; } @@ -216,6 +216,7 @@ static av_cold int seqvideo_decode_init(AVCodecContext *avctx) seq->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&seq->frame); seq->frame.data[0] = NULL; return 0; @@ -230,7 +231,7 @@ static int seqvideo_decode_frame(AVCodecContext *avctx, SeqVideoContext *seq = avctx->priv_data; - seq->frame.reference = 1; + seq->frame.reference = 3; seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &seq->frame)) { av_log(seq->avctx, AV_LOG_ERROR, "tiertexseqvideo: reget_buffer() failed\n"); diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index a88d0f988b..a0424b984a 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -1,21 +1,20 @@ /* - * TIFF image decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -103,6 +102,46 @@ static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src, } #endif +static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst, + int usePtr, const uint8_t *src, + uint8_t c, int width, int offset) +{ + switch (bpp) { + case 1: + while (--width >= 0) { + dst[(width+offset)*8+7] = (usePtr ? src[width] : c) & 0x1; + dst[(width+offset)*8+6] = (usePtr ? src[width] : c) >> 1 & 0x1; + dst[(width+offset)*8+5] = (usePtr ? src[width] : c) >> 2 & 0x1; + dst[(width+offset)*8+4] = (usePtr ? src[width] : c) >> 3 & 0x1; + dst[(width+offset)*8+3] = (usePtr ? src[width] : c) >> 4 & 0x1; + dst[(width+offset)*8+2] = (usePtr ? src[width] : c) >> 5 & 0x1; + dst[(width+offset)*8+1] = (usePtr ? src[width] : c) >> 6 & 0x1; + dst[(width+offset)*8+0] = (usePtr ? src[width] : c) >> 7; + } + break; + case 2: + while (--width >= 0) { + dst[(width+offset)*4+3] = (usePtr ? src[width] : c) & 0x3; + dst[(width+offset)*4+2] = (usePtr ? src[width] : c) >> 2 & 0x3; + dst[(width+offset)*4+1] = (usePtr ? src[width] : c) >> 4 & 0x3; + dst[(width+offset)*4+0] = (usePtr ? src[width] : c) >> 6; + } + break; + case 4: + while (--width >= 0) { + dst[(width+offset)*2+1] = (usePtr ? src[width] : c) & 0xF; + dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4; + } + break; + default: + if (usePtr) { + memcpy(dst + offset, src, width); + } else { + memset(dst + offset, c, width); + } + } +} + 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; const uint8_t *ssrc = src; @@ -122,7 +161,11 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin } src = zbuf; for(line = 0; line < lines; line++){ - memcpy(dst, src, width); + if(s->bpp < 8 && s->avctx->pix_fmt == PIX_FMT_PAL8){ + horizontal_fill(s->bpp, dst, 1, src, 0, width, 0); + }else{ + memcpy(dst, src, width); + } dst += stride; src += width; } @@ -163,6 +206,11 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, s->compr, s->fax_opts); break; } + if (s->bpp < 8 && s->avctx->pix_fmt == PIX_FMT_PAL8) + for (line = 0; line < lines; line++) { + horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0); + dst += stride; + } av_free(src2); return ret; } @@ -176,7 +224,8 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin if (ssrc + size - src < width) return AVERROR_INVALIDDATA; if (!s->fill_order) { - memcpy(dst, src, width); + horizontal_fill(s->bpp * (s->avctx->pix_fmt == PIX_FMT_PAL8), + dst, 1, src, 0, width, 0); } else { int i; for (i = 0; i < width; i++) @@ -193,7 +242,8 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n"); return -1; } - memcpy(dst + pixels, src, code); + horizontal_fill(s->bpp * (s->avctx->pix_fmt == PIX_FMT_PAL8), + dst, 1, src, 0, code, pixels); src += code; pixels += code; }else if(code != -128){ // -127..-1 @@ -203,7 +253,8 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin return -1; } c = *src++; - memset(dst + pixels, c, code); + horizontal_fill(s->bpp * (s->avctx->pix_fmt == PIX_FMT_PAL8), + dst, 0, NULL, c, code, pixels); pixels += code; } } @@ -214,6 +265,8 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n", pixels, width); return -1; } + if (s->bpp < 8 && s->avctx->pix_fmt == PIX_FMT_PAL8) + horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0); break; } dst += stride; @@ -228,8 +281,12 @@ static int init_image(TiffContext *s) switch (s->bpp * 10 + s->bppcount) { case 11: - s->avctx->pix_fmt = PIX_FMT_MONOBLACK; - break; + if (!s->palette_is_set) { + s->avctx->pix_fmt = PIX_FMT_MONOBLACK; + break; + } + case 21: + case 41: case 81: s->avctx->pix_fmt = PIX_FMT_PAL8; break; @@ -239,12 +296,18 @@ static int init_image(TiffContext *s) case 161: s->avctx->pix_fmt = PIX_FMT_GRAY16BE; break; + case 162: + s->avctx->pix_fmt = PIX_FMT_GRAY8A; + break; case 324: s->avctx->pix_fmt = PIX_FMT_RGBA; break; case 483: s->avctx->pix_fmt = s->le ? PIX_FMT_RGB48LE : PIX_FMT_RGB48BE; break; + case 644: + s->avctx->pix_fmt = s->le ? PIX_FMT_RGBA64LE : PIX_FMT_RGBA64BE; + break; default: av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, bppcount=%d)\n", @@ -268,8 +331,8 @@ static int init_image(TiffContext *s) } else { /* make default grayscale pal */ pal = (uint32_t *) s->picture.data[1]; - for (i = 0; i < 256; i++) - pal[i] = i * 0x010101; + for (i = 0; i < 1<<s->bpp; i++) + pal[i] = 0xFF << 24 | i * 255 / ((1<<s->bpp) - 1) * 0x010101; } } return 0; @@ -428,6 +491,13 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * return -1; } break; + case TIFF_TILE_BYTE_COUNTS: + case TIFF_TILE_LENGTH: + case TIFF_TILE_OFFSETS: + case TIFF_TILE_WIDTH: + av_log(s->avctx, AV_LOG_ERROR, "Tiled images are not supported\n"); + return AVERROR_PATCHWELCOME; + break; case TIFF_PREDICTOR: s->predictor = value; break; @@ -464,7 +534,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * bp = buf + count / 3 * off * 2; off = (type_sizes[type] - 1) << 3; for(i = 0; i < count / 3; i++){ - j = (tget(&rp, type, s->le) >> off) << 16; + j = 0xff << 24; + j |= (tget(&rp, type, s->le) >> off) << 16; j |= (tget(&gp, type, s->le) >> off) << 8; j |= tget(&bp, type, s->le) >> off; pal[i] = j; @@ -582,22 +653,35 @@ static int decode_frame(AVCodecContext *avctx, dst = p->data[0]; soff = s->bpp >> 3; ssize = s->width * soff; - for(i = 0; i < s->height; i++) { - for(j = soff; j < ssize; j++) - dst[j] += dst[j - soff]; - dst += stride; + if (s->avctx->pix_fmt == PIX_FMT_RGB48LE || + s->avctx->pix_fmt == PIX_FMT_RGBA64LE) { + for (i = 0; i < s->height; i++) { + for (j = soff; j < ssize; j += 2) + AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff)); + dst += stride; + } + } else if (s->avctx->pix_fmt == PIX_FMT_RGB48BE || + s->avctx->pix_fmt == PIX_FMT_RGBA64BE) { + for (i = 0; i < s->height; i++) { + for (j = soff; j < ssize; j += 2) + AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff)); + dst += stride; + } + } else { + for(i = 0; i < s->height; i++) { + for(j = soff; j < ssize; j++) + dst[j] += dst[j - soff]; + dst += stride; + } } } if(s->invert){ - uint8_t *src; - int j; - - src = s->picture.data[0]; - for(j = 0; j < s->height; j++){ - for(i = 0; i < s->picture.linesize[0]; i++) - src[i] = 255 - src[i]; - src += s->picture.linesize[0]; + dst = s->picture.data[0]; + for(i = 0; i < s->height; i++){ + for(j = 0; j < s->picture.linesize[0]; j++) + dst[j] = (s->avctx->pix_fmt == PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j]; + dst += s->picture.linesize[0]; } } *picture= *(AVFrame*)&s->picture; diff --git a/libavcodec/tiff.h b/libavcodec/tiff.h index cf890d678b..42cfb18861 100644 --- a/libavcodec/tiff.h +++ b/libavcodec/tiff.h @@ -1,27 +1,29 @@ /* - * TIFF tables * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file * TIFF tables + * + * For more information about the TIFF format, check the official docs at: + * http://partners.adobe.com/public/developer/tiff/index.html * @author Konstantin Shishkov */ @@ -54,6 +56,10 @@ enum TiffTags{ TIFF_SOFTWARE_NAME = 0x131, TIFF_PREDICTOR = 0x13D, TIFF_PAL = 0x140, + TIFF_TILE_WIDTH = 0x142, + TIFF_TILE_LENGTH = 0x143, + TIFF_TILE_OFFSETS = 0x144, + TIFF_TILE_BYTE_COUNTS = 0x145, TIFF_YCBCR_COEFFICIENTS = 0x211, TIFF_YCBCR_SUBSAMPLING = 0x212, TIFF_YCBCR_POSITIONING = 0x213, diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c index 0aa9740a99..85976f41c0 100644 --- a/libavcodec/tiffenc.c +++ b/libavcodec/tiffenc.c @@ -2,20 +2,20 @@ * TIFF image encoder * Copyright (c) 2007 Bartlomiej Wolowiec * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -32,6 +32,7 @@ #if CONFIG_ZLIB #include <zlib.h> #endif +#include "libavutil/opt.h" #include "bytestream.h" #include "tiff.h" #include "rle.h" @@ -65,6 +66,7 @@ typedef struct TiffEncoderContext { int buf_size; ///< buffer size uint16_t subsampling[2]; ///< YUV subsampling factors struct LZWEncodeState *lzws; ///< LZW Encode state + uint32_t dpi; ///< image resolution in DPI } TiffEncoderContext; @@ -214,8 +216,8 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, 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 }; + uint32_t res[2] = { s->dpi, 1 }; // image resolution (72/1) + uint16_t bpp_tab[] = { 8, 8, 8, 8 }; int ret = -1; int is_yuv = 0; uint8_t *yuv_line = NULL; @@ -237,6 +239,26 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, s->subsampling[1] = 1; switch (avctx->pix_fmt) { + case PIX_FMT_RGBA64LE: + s->bpp = 64; + s->photometric_interpretation = 2; + bpp_tab[0] = 16; + bpp_tab[1] = 16; + bpp_tab[2] = 16; + bpp_tab[3] = 16; + break; + case PIX_FMT_RGB48LE: + s->bpp = 48; + s->photometric_interpretation = 2; + bpp_tab[0] = 16; + bpp_tab[1] = 16; + bpp_tab[2] = 16; + bpp_tab[3] = 16; + break; + case PIX_FMT_RGBA: + s->bpp = 32; + s->photometric_interpretation = 2; + break; case PIX_FMT_RGB24: s->bpp = 24; s->photometric_interpretation = 2; @@ -250,12 +272,10 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, 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; + s->photometric_interpretation = avctx->pix_fmt == PIX_FMT_MONOBLACK; + bpp_tab[0] = 1; break; case PIX_FMT_YUV420P: case PIX_FMT_YUV422P: @@ -277,7 +297,7 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, return -1; } if (!is_yuv) - s->bpp_tab_size = (s->bpp >> 3); + s->bpp_tab_size = (s->bpp >= 48) ? ((s->bpp + 7) >> 4):((s->bpp + 7) >> 3); if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW) //best choose for DEFLATE @@ -440,6 +460,7 @@ fail: #define OFFSET(x) offsetof(TiffEncoderContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { + {"dpi", "set the image resolution (in dpi)", OFFSET(dpi), AV_OPT_TYPE_INT, {.dbl = 72}, 1, 0x10000, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_ENCODING_PARAM}, { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, {TIFF_PACKBITS}, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" }, { "packbits", NULL, 0, AV_OPT_TYPE_CONST, {TIFF_PACKBITS}, 0, 0, VE, "compression_algo" }, { "raw", NULL, 0, AV_OPT_TYPE_CONST, {TIFF_RAW}, 0, 0, VE, "compression_algo" }, @@ -468,8 +489,8 @@ AVCodec ff_tiff_encoder = { PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_YUV410P, - PIX_FMT_YUV411P, - PIX_FMT_NONE}, + PIX_FMT_YUV411P, PIX_FMT_RGB48LE, + PIX_FMT_RGBA, PIX_FMT_RGBA64LE, PIX_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("TIFF image"), .priv_class = &tiffenc_class, }; diff --git a/libavcodec/timecode.c b/libavcodec/timecode.c new file mode 100644 index 0000000000..f9862e5581 --- /dev/null +++ b/libavcodec/timecode.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com> + * Copyright (C) 2011 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.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 + * Timecode helpers + * This *private* API is deprecated, please use the one available in libavutil instead. + */ + +#include "version.h" + +#if FF_API_OLD_TIMECODE + +#include <stdio.h> +#include "timecode.h" +#include "libavutil/log.h" + +int avpriv_framenum_to_drop_timecode(int frame_num) +{ + /* only works for NTSC 29.97 */ + int d = frame_num / 17982; + int m = frame_num % 17982; + //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */ + return frame_num + 18 * d + 2 * ((m - 2) / 1798); +} + +uint32_t avpriv_framenum_to_smpte_timecode(unsigned frame, int fps, int drop) +{ + return (0 << 31) | // color frame flag + (drop << 30) | // drop frame flag + ( ((frame % fps) / 10) << 28) | // tens of frames + ( ((frame % fps) % 10) << 24) | // units of frames + (0 << 23) | // field phase (NTSC), b0 (PAL) + ((((frame / fps) % 60) / 10) << 20) | // tens of seconds + ((((frame / fps) % 60) % 10) << 16) | // units of seconds + (0 << 15) | // b0 (NTSC), b2 (PAL) + ((((frame / (fps * 60)) % 60) / 10) << 12) | // tens of minutes + ((((frame / (fps * 60)) % 60) % 10) << 8) | // units of minutes + (0 << 7) | // b1 + (0 << 6) | // b2 (NTSC), field phase (PAL) + ((((frame / (fps * 3600) % 24)) / 10) << 4) | // tens of hours + ( (frame / (fps * 3600) % 24)) % 10; // units of hours +} + +int avpriv_check_timecode_rate(void *avcl, AVRational rate, int drop) +{ + int fps; + + if (!rate.num || !rate.den) { + av_log(avcl, AV_LOG_ERROR, "Timecode frame rate must be specified\n"); + return -1; + } + fps = (rate.num + rate.den/2) / rate.den; + if (drop && fps != 30) { + av_log(avcl, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 FPS\n"); + return -2; + } + switch (fps) { + case 24: + case 25: + case 30: return 0; + + default: + av_log(avcl, AV_LOG_ERROR, "Timecode frame rate not supported\n"); + return -3; + } +} + +char *avpriv_timecode_to_string(char *buf, const struct ff_timecode *tc, unsigned frame) +{ + int frame_num = tc->start + frame; + int fps = (tc->rate.num + tc->rate.den/2) / tc->rate.den; + int hh, mm, ss, ff, neg = 0; + + if (tc->drop) + frame_num = avpriv_framenum_to_drop_timecode(frame_num); + if (frame_num < 0) { + frame_num = -frame_num; + neg = 1; + } + ff = frame_num % fps; + ss = frame_num / fps % 60; + mm = frame_num / (fps*60) % 60; + hh = frame_num / (fps*3600); + snprintf(buf, 16, "%s%02d:%02d:%02d%c%02d", + neg ? "-" : "", + hh, mm, ss, tc->drop ? ';' : ':', ff); + return buf; +} + +int avpriv_init_smpte_timecode(void *avcl, struct ff_timecode *tc) +{ + int hh, mm, ss, ff, fps, ret; + char c; + + if (sscanf(tc->str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) { + av_log(avcl, AV_LOG_ERROR, "unable to parse timecode, " + "syntax: hh:mm:ss[:;.]ff\n"); + return -1; + } + + tc->drop = c != ':'; // drop if ';', '.', ... + + ret = avpriv_check_timecode_rate(avcl, tc->rate, tc->drop); + if (ret < 0) + return ret; + + fps = (tc->rate.num + tc->rate.den/2) / tc->rate.den; + tc->start = (hh*3600 + mm*60 + ss) * fps + ff; + + if (tc->drop) { /* adjust frame number */ + int tmins = 60*hh + mm; + tc->start -= 2 * (tmins - tmins/10); + } + return 0; +} + +int ff_framenum_to_drop_timecode(int frame_num) +{ + return avpriv_framenum_to_drop_timecode(frame_num); +} + +uint32_t ff_framenum_to_smtpe_timecode(unsigned frame, int fps, int drop) +{ + return avpriv_framenum_to_smpte_timecode(frame, fps, drop); +} + +int ff_init_smtpe_timecode(void *avcl, struct ff_timecode *tc) +{ + return avpriv_init_smpte_timecode(avcl, tc); +} +#endif diff --git a/libavcodec/timecode.h b/libavcodec/timecode.h new file mode 100644 index 0000000000..8bc69e9876 --- /dev/null +++ b/libavcodec/timecode.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com> + * Copyright (C) 2011 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.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 + * Timecode helpers header + * This *private* API is deprecated, please use the one available in libavutil instead. + */ + +#ifndef AVCODEC_TIMECODE_H +#define AVCODEC_TIMECODE_H + +#include "version.h" + +#if FF_API_OLD_TIMECODE + +#include <stdint.h> +#include "avcodec.h" +#include "libavutil/rational.h" + +#define TIMECODE_OPT(ctx, flags) \ + "timecode", "set timecode value following hh:mm:ss[:;.]ff format, " \ + "use ';' or '.' before frame number for drop frame", \ + offsetof(ctx, tc.str), \ + AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, flags + +struct ff_timecode { + char *str; ///< string following the hh:mm:ss[:;.]ff format + int start; ///< timecode frame start + int drop; ///< drop flag (1 if drop, else 0) + AVRational rate; ///< Frame rate in rational form +}; + +/** + * @brief Adjust frame number for NTSC drop frame time code + * @param frame_num Actual frame number to adjust + * @return Adjusted frame number + * @warning Adjustment is only valid in NTSC 29.97 + */ +int avpriv_framenum_to_drop_timecode(int frame_num); + +/** + * @brief Convert frame id (timecode) to SMPTE 12M binary representation + * @param frame Frame number + * @param fps Frame rate + * @param drop Drop flag + * @return The actual binary representation + */ +uint32_t avpriv_framenum_to_smpte_timecode(unsigned frame, int fps, int drop); + +/** + * @brief Load timecode string in buf + * @param buf Destination buffer + * @param tc Timecode struct pointer + * @param frame Frame id (timecode frame is computed with tc->start+frame) + * @return a pointer to the buf parameter + * @note timecode representation can be a negative timecode and have + * more than 24 hours. + * @note buf must have enough space to store the timecode representation: 16 + * bytes is the minimum required size. + */ +char *avpriv_timecode_to_string(char *buf, const struct ff_timecode *tc, unsigned frame); + +/** + * Check if timecode rate is valid and consistent with the drop flag. + * + * @return 0 on success, negative value on failure + */ +int avpriv_check_timecode_rate(void *avcl, AVRational rate, int drop); + +/** + * Parse SMTPE 12M time representation (hh:mm:ss[:;.]ff). str and rate fields + * from tc struct must be set. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct (used for av_log). + * @param tc Timecode struct pointer + * @return 0 on success, negative value on failure + * @warning Adjustement is only valid in NTSC 29.97 + */ +int avpriv_init_smpte_timecode(void *avcl, struct ff_timecode *tc); + +attribute_deprecated int ff_framenum_to_drop_timecode(int frame_num); +attribute_deprecated uint32_t ff_framenum_to_smtpe_timecode(unsigned frame, int fps, int drop); +attribute_deprecated int ff_init_smtpe_timecode(void *avcl, struct ff_timecode *tc); +#endif + +#endif /* AVCODEC_TIMECODE_H */ diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c index be809b3675..7eb9b6903a 100644 --- a/libavcodec/tmv.c +++ b/libavcodec/tmv.c @@ -2,20 +2,20 @@ * 8088flex TMV video decoder * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -84,7 +84,9 @@ static int tmv_decode_frame(AVCodecContext *avctx, void *data, static av_cold int tmv_decode_init(AVCodecContext *avctx) { + TMVContext *tmv = avctx->priv_data; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&tmv->pic); return 0; } diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index fcf6004c51..ccebef5495 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -2,20 +2,20 @@ * Duck TrueMotion 1.0 Decoder * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -474,6 +474,7 @@ static av_cold int truemotion1_decode_init(AVCodecContext *avctx) // else // avctx->pix_fmt = PIX_FMT_RGB555; + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; /* there is a vertical predictor for each pixel in a line; each vertical @@ -858,7 +859,7 @@ static int truemotion1_decode_frame(AVCodecContext *avctx, if (truemotion1_decode_header(s) == -1) return -1; - s->frame.reference = 1; + s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &s->frame) < 0) { diff --git a/libavcodec/truemotion1data.h b/libavcodec/truemotion1data.h index e950450fcd..3e581434e4 100644 --- a/libavcodec/truemotion1data.h +++ b/libavcodec/truemotion1data.h @@ -6,20 +6,20 @@ * the GNU LGPL using the common understanding that data tables necessary * for decoding algorithms are not necessarily copyrightable. * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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_TRUEMOTION1DATA_H diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 4045342ffa..e68a68757f 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -2,20 +2,20 @@ * Duck/ON2 TrueMotion 2 Decoder * Copyright (c) 2005 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -44,6 +44,9 @@ typedef struct TM2Context{ GetBitContext gb; DSPContext dsp; + uint8_t *buffer; + int buffer_size; + /* TM2 streams */ int *tokens[TM2_NUM_STREAMS]; int tok_lens[TM2_NUM_STREAMS]; @@ -64,7 +67,7 @@ typedef struct TM2Context{ * Huffman codes for each of streams */ typedef struct TM2Codes{ - VLC vlc; ///< table for Libav bitstream reader + VLC vlc; ///< table for FFmpeg bitstream reader int bits; int *recode; ///< table for converting from code indexes to values int length; @@ -766,33 +769,29 @@ static int decode_frame(AVCodecContext *avctx, TM2Context * const l = avctx->priv_data; AVFrame * const p= (AVFrame*)&l->pic; int i, skip, t; - uint8_t *swbuf; - swbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); - if(!swbuf){ + av_fast_padded_malloc(&l->buffer, &l->buffer_size, buf_size); + if(!l->buffer){ av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); return -1; } - p->reference = 1; + p->reference = 3; p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if(avctx->reget_buffer(avctx, p) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - av_free(swbuf); return -1; } - l->dsp.bswap_buf((uint32_t*)swbuf, (const uint32_t*)buf, buf_size >> 2); - skip = tm2_read_header(l, swbuf); + l->dsp.bswap_buf((uint32_t*)l->buffer, (const uint32_t*)buf, buf_size >> 2); + skip = tm2_read_header(l, l->buffer); if(skip == -1){ - av_free(swbuf); return -1; } for(i = 0; i < TM2_NUM_STREAMS; i++){ - t = tm2_read_stream(l, swbuf + skip, tm2_stream_order[i], buf_size); + t = tm2_read_stream(l, l->buffer + skip, tm2_stream_order[i], buf_size); if(t == -1){ - av_free(swbuf); return -1; } skip += t; @@ -806,7 +805,6 @@ static int decode_frame(AVCodecContext *avctx, l->cur = !l->cur; *data_size = sizeof(AVFrame); *(AVFrame*)data = l->pic; - av_free(swbuf); return buf_size; } @@ -823,6 +821,7 @@ static av_cold int decode_init(AVCodecContext *avctx){ l->avctx = avctx; l->pic.data[0]=NULL; avctx->pix_fmt = PIX_FMT_BGR24; + avcodec_get_frame_defaults(&l->pic); dsputil_init(&l->dsp, avctx); @@ -862,6 +861,8 @@ static av_cold int decode_end(AVCodecContext *avctx){ av_free(l->U2); av_free(l->V2); } + av_freep(&l->buffer); + l->buffer_size = 0; if (pic->data[0]) avctx->release_buffer(avctx, pic); diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index 66ca461741..c2c68abd6f 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -2,20 +2,20 @@ * DSP Group TrueSpeech compatible decoder * Copyright (c) 2005 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/truespeech_data.h b/libavcodec/truespeech_data.h index 6e9806a0b5..73ebda5e85 100644 --- a/libavcodec/truespeech_data.h +++ b/libavcodec/truespeech_data.h @@ -2,20 +2,20 @@ * DSP Group TrueSpeech compatible decoder * copyright (c) 2005 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/tscc.c b/libavcodec/tscc.c index 3e3073d3cd..e6c9492edc 100644 --- a/libavcodec/tscc.c +++ b/libavcodec/tscc.c @@ -2,20 +2,20 @@ * TechSmith Camtasia decoder * Copyright (c) 2004 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -81,7 +81,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if(c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); - c->pic.reference = 1; + c->pic.reference = 3; 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"); @@ -142,6 +142,7 @@ static av_cold int decode_init(AVCodecContext *avctx) c->height = avctx->height; + avcodec_get_frame_defaults(&c->pic); // Needed if zlib unused or init aborted before inflateInit memset(&c->zstream, 0, sizeof(z_stream)); switch(avctx->bits_per_coded_sample){ diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 49d59538d3..ab83730dfd 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -2,20 +2,20 @@ * TTA (The Lossless True Audio) decoder * Copyright (c) 2006 Alex Beregszaszi * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -188,6 +188,16 @@ static int tta_get_unary(GetBitContext *gb) return ret; } +static const int64_t tta_channel_layouts[7] = { + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, + AV_CH_LAYOUT_QUAD, + 0, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER, + AV_CH_LAYOUT_7POINT1_WIDE +}; + static av_cold int tta_decode_init(AVCodecContext * avctx) { TTAContext *s = avctx->priv_data; @@ -214,6 +224,8 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) return AVERROR(EINVAL); } avctx->channels = s->channels = get_bits(&s->gb, 16); + if (s->channels > 1 && s->channels < 9) + avctx->channel_layout = tta_channel_layouts[s->channels-2]; avctx->bits_per_coded_sample = get_bits(&s->gb, 16); s->bps = (avctx->bits_per_coded_sample + 7) / 8; avctx->sample_rate = get_bits_long(&s->gb, 32); @@ -226,6 +238,7 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) } switch(s->bps) { + case 1: avctx->sample_fmt = AV_SAMPLE_FMT_U8; break; case 2: avctx->sample_fmt = AV_SAMPLE_FMT_S16; avctx->bits_per_raw_sample = 16; @@ -234,6 +247,7 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) avctx->sample_fmt = AV_SAMPLE_FMT_S32; avctx->bits_per_raw_sample = 24; break; + //case 4: avctx->sample_fmt = AV_SAMPLE_FMT_S32; break; default: av_log(avctx, AV_LOG_ERROR, "Invalid/unsupported sample format.\n"); return AVERROR_INVALIDDATA; @@ -265,11 +279,9 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) return -1; } - if (s->bps == 2) { - s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels); - if (!s->decode_buffer) - return AVERROR(ENOMEM); - } + s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels); + if (!s->decode_buffer) + return AVERROR(ENOMEM); s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx)); if (!s->ch_ctx) { av_freep(&s->decode_buffer); @@ -401,19 +413,30 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, return -1; skip_bits_long(&s->gb, 32); // frame crc - // convert to output buffer - if (s->bps == 2) { - int16_t *samples = (int16_t *)s->frame.data[0]; - for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) - *samples++ = *p; - } else { - // shift samples for 24-bit sample format - int32_t *samples = (int32_t *)s->frame.data[0]; - for (i = 0; i < framelen * s->channels; i++) - *samples++ <<= 8; - // reset decode buffer - s->decode_buffer = NULL; - } + // convert to output buffer + switch(s->bps) { + case 1: { + uint8_t *samples = (uint8_t *)s->frame.data[0]; + for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) + *samples++ = *p + 0x80; + break; + } + case 2: { + uint16_t *samples = (int16_t *)s->frame.data[0]; + for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) + *samples++ = *p; + break; + } + case 3: { + // shift samples for 24-bit sample format + int32_t *samples = (int32_t *)s->frame.data[0]; + for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) + *samples++ <<= 8; + // reset decode buffer + s->decode_buffer = NULL; + break; + } + } *got_frame_ptr = 1; *(AVFrame *)data = s->frame; diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 22be07a5b5..6a0bd4d145 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -2,20 +2,20 @@ * TwinVQ decoder * Copyright (c) 2009 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -871,7 +871,7 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, } *got_frame_ptr = 1; - *(AVFrame *)data = tctx->frame;; + *(AVFrame *)data = tctx->frame; return buf_size; } diff --git a/libavcodec/twinvq_data.h b/libavcodec/twinvq_data.h index 1f1f33408e..3042cd1beb 100644 --- a/libavcodec/twinvq_data.h +++ b/libavcodec/twinvq_data.h @@ -2,20 +2,20 @@ * TwinVQ decoder * Copyright (c) 2009 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/txd.c b/libavcodec/txd.c index 734062aca6..ca07b6ce17 100644 --- a/libavcodec/txd.c +++ b/libavcodec/txd.c @@ -4,25 +4,26 @@ * * See also: http://wiki.multimedia.cx/index.php?title=TXD * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" +#include "bytestream.h" #include "avcodec.h" #include "s3tc.h" @@ -42,6 +43,7 @@ static av_cold int txd_init(AVCodecContext *avctx) { static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; TXDContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = &s->picture; @@ -52,6 +54,8 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint32_t *palette = (const uint32_t *)(cur + 88); uint32_t *pal; + if (buf_end - cur < 92) + return AVERROR_INVALIDDATA; version = AV_RL32(cur); d3d_format = AV_RL32(cur+76); w = AV_RL16(cur+80); @@ -69,6 +73,8 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (depth == 8) { avctx->pix_fmt = PIX_FMT_PAL8; + if (buf_end - cur < 1024) + return AVERROR_INVALIDDATA; cur += 1024; } else if (depth == 16 || depth == 32) avctx->pix_fmt = PIX_FMT_RGB32; @@ -100,6 +106,8 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, v = AV_RB32(palette+y); pal[y] = (v>>8) + (v<<24); } + if (buf_end - cur < w * h) + return AVERROR_INVALIDDATA; for (y=0; y<h; y++) { memcpy(ptr, cur, w); ptr += stride; @@ -111,9 +119,13 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (!(flags & 1)) goto unsupported; case FF_S3TC_DXT1: + if (buf_end - cur < (w/4) * (h/4) * 8) + return AVERROR_INVALIDDATA; ff_decode_dxt1(cur, ptr, w, h, stride); break; case FF_S3TC_DXT3: + if (buf_end - cur < (w/4) * (h/4) * 16) + return AVERROR_INVALIDDATA; ff_decode_dxt3(cur, ptr, w, h, stride); break; default: @@ -123,6 +135,8 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, switch (d3d_format) { case 0x15: case 0x16: + if (buf_end - cur < h * w * 4) + return AVERROR_INVALIDDATA; for (y=0; y<h; y++) { memcpy(ptr, cur, w*4); ptr += stride; @@ -134,8 +148,12 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } } - for (; mipmap_count > 1; mipmap_count--) - cur += AV_RL32(cur) + 4; + for (; mipmap_count > 1 && buf_end - cur >= 4; mipmap_count--) { + uint32_t length = bytestream_get_le32(&cur); + if (buf_end - cur < length) + break; + cur += length; + } *picture = s->picture; *data_size = sizeof(AVPicture); diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c index 96f13e430a..cd6f2d24ab 100644 --- a/libavcodec/ulti.c +++ b/libavcodec/ulti.c @@ -2,20 +2,20 @@ * IBM Ultimotion Video Decoder * Copyright (C) 2004 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -50,6 +50,7 @@ static av_cold int ulti_decode_init(AVCodecContext *avctx) s->height = avctx->height; s->blocks = (s->width / 8) * (s->height / 8); avctx->pix_fmt = PIX_FMT_YUV410P; + avcodec_get_frame_defaults(&s->frame); avctx->coded_frame = (AVFrame*) &s->frame; s->ulti_codebook = ulti_codebook; @@ -225,7 +226,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, int skip; int tmp; - s->frame.reference = 1; + s->frame.reference = 3; 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(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); diff --git a/libavcodec/ulti_cb.h b/libavcodec/ulti_cb.h index 0bd83ffd37..7061d839a8 100644 --- a/libavcodec/ulti_cb.h +++ b/libavcodec/ulti_cb.h @@ -2,20 +2,20 @@ * IBM Ultimotion Video Decoder * copyright (C) 2004 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/unary.h b/libavcodec/unary.h index d14929f797..908dc93507 100644 --- a/libavcodec/unary.h +++ b/libavcodec/unary.h @@ -1,20 +1,20 @@ /* * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/utils.c b/libavcodec/utils.c index c890cf96e9..9e31d9ede0 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3,20 +3,20 @@ * Copyright (c) 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -34,6 +34,7 @@ #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" #include "libavutil/dict.h" +#include "libavutil/avassert.h" #include "avcodec.h" #include "dsputil.h" #include "libavutil/opt.h" @@ -68,29 +69,34 @@ void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) return ptr; } -void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) +static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc) { void **p = ptr; if (min_size < *size) - return; + return 0; min_size= FFMAX(17*min_size/16 + 32, min_size); av_free(*p); - *p = av_malloc(min_size); + *p = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size); if (!*p) min_size = 0; *size= min_size; + return 1; +} + +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) +{ + ff_fast_malloc(ptr, size, min_size, 0); } void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size) { - void **p = ptr; + uint8_t **p = ptr; if (min_size > SIZE_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { av_freep(p); *size = 0; return; } - av_fast_malloc(p, size, min_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (*size) - memset((uint8_t *)*p + min_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + if (!ff_fast_malloc(p, size, min_size + FF_INPUT_BUFFER_PADDING_SIZE, 1)) + memset(*p + min_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); } /* encoder management */ @@ -226,6 +232,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, break; } + if(s->codec_id == CODEC_ID_IFF_ILBM || s->codec_id == CODEC_ID_IFF_BYTERUN1){ + w_align= FFMAX(w_align, 8); + } + *width = FFALIGN(*width , w_align); *height= FFALIGN(*height, h_align); if(s->codec_id == CODEC_ID_H264 || s->lowres) @@ -248,6 +258,22 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height){ *width=FFALIGN(*width, align); } +void ff_init_buffer_info(AVCodecContext *s, AVFrame *pic) +{ + if (s->pkt) { + pic->pkt_pts = s->pkt->pts; + pic->pkt_pos = s->pkt->pos; + } else { + pic->pkt_pts = AV_NOPTS_VALUE; + pic->pkt_pos = -1; + } + pic->reordered_opaque= s->reordered_opaque; + pic->sample_aspect_ratio = s->sample_aspect_ratio; + pic->width = s->width; + pic->height = s->height; + pic->format = s->pix_fmt; +} + int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align) @@ -273,7 +299,7 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, buf, nb_channels, frame->nb_samples, sample_fmt, align)) < 0) { if (frame->extended_data != frame->data) - av_free(frame->extended_data); + av_freep(&frame->extended_data); return ret; } if (frame->extended_data != frame->data) { @@ -311,7 +337,7 @@ static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) if (buf->extended_data[0] && buf_size > buf->audio_data_size) { av_free(buf->extended_data[0]); if (buf->extended_data != buf->data) - av_free(&buf->extended_data); + av_freep(&buf->extended_data); buf->extended_data = NULL; buf->data[0] = NULL; } @@ -353,8 +379,14 @@ static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) frame->type = FF_BUFFER_TYPE_INTERNAL; - if (avctx->pkt) frame->pkt_pts = avctx->pkt->pts; - else frame->pkt_pts = AV_NOPTS_VALUE; + if (avctx->pkt) { + frame->pkt_pts = avctx->pkt->pts; + frame->pkt_pos = avctx->pkt->pos; + } else { + frame->pkt_pts = AV_NOPTS_VALUE; + frame->pkt_pos = -1; + } + frame->reordered_opaque = avctx->reordered_opaque; if (avctx->debug & FF_DEBUG_BUFFERS) @@ -481,9 +513,18 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) pic->extended_data = pic->data; avci->buffer_count++; - if(s->pkt) pic->pkt_pts= s->pkt->pts; - else pic->pkt_pts= AV_NOPTS_VALUE; + if (s->pkt) { + pic->pkt_pts = s->pkt->pts; + pic->pkt_pos = s->pkt->pos; + } else { + pic->pkt_pts = AV_NOPTS_VALUE; + pic->pkt_pos = -1; + } pic->reordered_opaque= s->reordered_opaque; + pic->sample_aspect_ratio = s->sample_aspect_ratio; + pic->width = s->width; + pic->height = s->height; + pic->format = s->pix_fmt; if(s->debug&FF_DEBUG_BUFFERS) av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d " @@ -546,6 +587,14 @@ int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){ assert(s->codec_type == AVMEDIA_TYPE_VIDEO); + if (pic->data[0] && (pic->width != s->width || pic->height != s->height || pic->format != s->pix_fmt)) { + av_log(s, AV_LOG_WARNING, "Picture changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s in reget buffer()\n", + pic->width, pic->height, av_get_pix_fmt_name(pic->format), s->width, s->height, av_get_pix_fmt_name(s->pix_fmt)); + s->release_buffer(s, pic); + } + + ff_init_buffer_info(s, pic); + /* If no picture return a new buffer */ if(pic->data[0] == NULL) { /* We will copy from buffer, so must be readable */ @@ -555,9 +604,6 @@ int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){ /* If internal buffer type return the same buffer */ if(pic->type == FF_BUFFER_TYPE_INTERNAL) { - if(s->pkt) pic->pkt_pts= s->pkt->pts; - else pic->pkt_pts= AV_NOPTS_VALUE; - pic->reordered_opaque= s->reordered_opaque; return 0; } @@ -607,7 +653,8 @@ enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum void avcodec_get_frame_defaults(AVFrame *pic){ memset(pic, 0, sizeof(AVFrame)); - pic->pts= AV_NOPTS_VALUE; + pic->pts = pic->pkt_dts = pic->pkt_pts = pic->best_effort_timestamp = AV_NOPTS_VALUE; + pic->pkt_pos = -1; pic->key_frame= 1; pic->sample_aspect_ratio = (AVRational){0, 1}; pic->format = -1; /* unknown */ @@ -623,6 +670,19 @@ AVFrame *avcodec_alloc_frame(void){ return pic; } +static void avcodec_get_subtitle_defaults(AVSubtitle *sub) +{ + memset(sub, 0, sizeof(*sub)); + sub->pts = AV_NOPTS_VALUE; +} + +#if FF_API_AVCODEC_OPEN +int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) +{ + return avcodec_open2(avctx, codec, NULL); +} +#endif + int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) { int ret = 0; @@ -688,10 +748,20 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD if ((ret = av_opt_set_dict(avctx, &tmp)) < 0) goto free_and_end; + if (codec->capabilities & CODEC_CAP_EXPERIMENTAL) + if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { + av_log(avctx, AV_LOG_ERROR, "Codec is experimental but experimental codecs are not enabled, see -strict -2\n"); + ret = -1; + goto free_and_end; + } + + //We only call avcodec_set_dimensions() for non h264 codecs so as not to overwrite previously setup dimensions + if(!( avctx->coded_width && avctx->coded_height && avctx->width && avctx->height && avctx->codec_id == CODEC_ID_H264)){ if(avctx->coded_width && avctx->coded_height) avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); else if(avctx->width && avctx->height) avcodec_set_dimensions(avctx, avctx->width, avctx->height); + } if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height) && ( av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0 @@ -731,6 +801,9 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD avctx->time_base.den = avctx->sample_rate; } + if (!HAVE_THREADS) + av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n"); + if (HAVE_THREADS && !avctx->thread_opaque) { ret = ff_thread_init(avctx); if (ret < 0) { @@ -740,7 +813,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD if (!HAVE_THREADS && !(codec->capabilities & CODEC_CAP_AUTO_THREADS)) avctx->thread_count = 1; - if (avctx->codec->max_lowres < avctx->lowres) { + if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) { av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n", avctx->codec->max_lowres); ret = AVERROR(EINVAL); @@ -793,12 +866,19 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD } } + avctx->pts_correction_num_faulty_pts = + avctx->pts_correction_num_faulty_dts = 0; + avctx->pts_correction_last_pts = + avctx->pts_correction_last_dts = INT64_MIN; + if(avctx->codec->init && !(avctx->active_thread_type&FF_THREAD_FRAME)){ ret = avctx->codec->init(avctx); if (ret < 0) { goto free_and_end; } } + + ret=0; end: entangled_thread_counter--; @@ -889,6 +969,8 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, if (!user_packet) { if (avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) { av_assert0(av_get_bits_per_sample(avctx->codec_id) != 0); + if (!frame) + return AVERROR(EINVAL); buf_size = nb_samples * avctx->channels * av_get_bits_per_sample(avctx->codec_id) / 8; } else { @@ -1004,9 +1086,12 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, /* fabricate frame pts from sample count. this is needed because the avcodec_encode_audio() API does not have a way for the user to provide pts */ - frame->pts = av_rescale_q(avctx->internal->sample_count, + if(avctx->sample_rate && avctx->time_base.num) + frame->pts = av_rescale_q(avctx->internal->sample_count, (AVRational){ 1, avctx->sample_rate }, avctx->time_base); + else + frame->pts = AV_NOPTS_VALUE; avctx->internal->sample_count += frame->nb_samples; } else { frame = NULL; @@ -1019,16 +1104,10 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY); } /* free any side data since we cannot return it */ - if (pkt.side_data_elems > 0) { - int i; - for (i = 0; i < pkt.side_data_elems; i++) - av_free(pkt.side_data[i].data); - av_freep(&pkt.side_data); - pkt.side_data_elems = 0; - } + ff_packet_free_side_data(&pkt); if (frame && frame->extended_data != frame->data) - av_free(frame->extended_data); + av_freep(&frame->extended_data); return ret ? ret : pkt.size; } @@ -1070,7 +1149,7 @@ int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf #endif #define MAX_CODED_FRAME_SIZE(width, height)\ - (8*(width)*(height) + FF_MIN_BUFFER_SIZE) + (9*(width)*(height) + FF_MIN_BUFFER_SIZE) int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, @@ -1121,7 +1200,7 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, av_freep(&avpkt->data); } else if (avctx->coded_frame) { avpkt->pts = avctx->coded_frame->pts; - avpkt->flags |= AV_PKT_FLAG_KEY*avctx->coded_frame->key_frame; + avpkt->flags |= AV_PKT_FLAG_KEY*!!avctx->coded_frame->key_frame; } avpkt->size = ret; @@ -1145,13 +1224,44 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n"); return -1; } - if(sub->num_rects == 0 || !sub->rects) - return -1; + ret = avctx->codec->encode(avctx, buf, buf_size, sub); avctx->frame_number++; return ret; } +/** + * Attempt to guess proper monotonic timestamps for decoded video frames + * which might have incorrect times. Input timestamps may wrap around, in + * which case the output will as well. + * + * @param pts the pts field of the decoded AVPacket, as passed through + * AVFrame.pkt_pts + * @param dts the dts field of the decoded AVPacket + * @return one of the input values, may be AV_NOPTS_VALUE + */ +static int64_t guess_correct_pts(AVCodecContext *ctx, + int64_t reordered_pts, int64_t dts) +{ + int64_t pts = AV_NOPTS_VALUE; + + if (dts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts; + ctx->pts_correction_last_dts = dts; + } + if (reordered_pts != AV_NOPTS_VALUE) { + ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts; + ctx->pts_correction_last_pts = reordered_pts; + } + if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) + && reordered_pts != AV_NOPTS_VALUE) + pts = reordered_pts; + else + pts = dts; + + return pts; +} + static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) { int size = 0; @@ -1196,35 +1306,54 @@ static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, - AVPacket *avpkt) + const AVPacket *avpkt) { int ret; + // copy to ensure we do not change avpkt + AVPacket tmp = *avpkt; *got_picture_ptr= 0; if((avctx->coded_width||avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) return -1; - avctx->pkt = avpkt; - apply_param_change(avctx, avpkt); - if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type&FF_THREAD_FRAME)){ + int did_split = av_packet_split_side_data(&tmp); + apply_param_change(avctx, &tmp); + avctx->pkt = &tmp; if (HAVE_THREADS && avctx->active_thread_type&FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, - avpkt); + &tmp); else { ret = avctx->codec->decode(avctx, picture, got_picture_ptr, - avpkt); + &tmp); picture->pkt_dts= avpkt->dts; - picture->sample_aspect_ratio = avctx->sample_aspect_ratio; - picture->width = avctx->width; - picture->height = avctx->height; - picture->format = avctx->pix_fmt; + + if(!avctx->has_b_frames){ + picture->pkt_pos= avpkt->pos; + } + //FIXME these should be under if(!avctx->has_b_frames) + if (!picture->sample_aspect_ratio.num) + picture->sample_aspect_ratio = avctx->sample_aspect_ratio; + if (!picture->width) + picture->width = avctx->width; + if (!picture->height) + picture->height = avctx->height; + if (picture->format == PIX_FMT_NONE) + picture->format = avctx->pix_fmt; } emms_c(); //needed to avoid an emms_c() call before every return; - if (*got_picture_ptr) + avctx->pkt = NULL; + if (did_split) + ff_packet_free_side_data(&tmp); + + if (*got_picture_ptr){ avctx->frame_number++; + picture->best_effort_timestamp = guess_correct_pts(avctx, + picture->pkt_pts, + picture->pkt_dts); + } }else ret= 0; @@ -1245,6 +1374,7 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa av_log(avctx, AV_LOG_ERROR, "Please port your application to " "avcodec_decode_audio4()\n"); avctx->get_buffer = avcodec_default_get_buffer; + avctx->release_buffer = avcodec_default_release_buffer; } ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt); @@ -1287,16 +1417,16 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, *got_frame_ptr = 0; - avctx->pkt = avpkt; - if (!avpkt->data && avpkt->size) { av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); return AVERROR(EINVAL); } - apply_param_change(avctx, avpkt); - if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { + av_packet_split_side_data(avpkt); + apply_param_change(avctx, avpkt); + + avctx->pkt = avpkt; ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt); if (ret >= 0 && *got_frame_ptr) { avctx->frame_number++; @@ -1316,6 +1446,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, avctx->pkt = avpkt; *got_sub_ptr = 0; + avcodec_get_subtitle_defaults(sub); ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt); if (*got_sub_ptr) avctx->frame_number++; @@ -1384,10 +1515,21 @@ av_cold int avcodec_close(AVCodecContext *avctx) return 0; } +static enum CodecID remap_deprecated_codec_id(enum CodecID id) +{ + switch(id){ + //This is for future deprecatec codec ids, its empty since + //last major bump but will fill up again over time, please dont remove it +// case CODEC_ID_UTVIDEO_DEPRECATED: return CODEC_ID_UTVIDEO; + default : return id; + } +} + AVCodec *avcodec_find_encoder(enum CodecID id) { AVCodec *p, *experimental=NULL; p = first_avcodec; + id= remap_deprecated_codec_id(id); while (p) { if (codec_is_encoder(p) && p->id == id) { if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) { @@ -1416,14 +1558,19 @@ AVCodec *avcodec_find_encoder_by_name(const char *name) AVCodec *avcodec_find_decoder(enum CodecID id) { - AVCodec *p; + AVCodec *p, *experimental=NULL; p = first_avcodec; + id= remap_deprecated_codec_id(id); while (p) { - if (codec_is_decoder(p) && p->id == id) - return p; + if (codec_is_decoder(p) && p->id == id) { + if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) { + experimental = p; + } else + return p; + } p = p->next; } - return NULL; + return experimental; } AVCodec *avcodec_find_decoder_by_name(const char *name) @@ -1463,6 +1610,25 @@ static int get_bit_rate(AVCodecContext *ctx) return bit_rate; } +const char *avcodec_get_name(enum CodecID id) +{ + AVCodec *codec; + +#if !CONFIG_SMALL + switch (id) { +#include "libavcodec/codec_names.h" + } + av_log(NULL, AV_LOG_WARNING, "Codec 0x%x is not in the full list.\n", id); +#endif + codec = avcodec_find_decoder(id); + if (codec) + return codec->name; + codec = avcodec_find_encoder(id); + if (codec) + return codec->name; + return "unknown_codec"; +} + size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag) { int i, len, ret = 0; @@ -1480,43 +1646,37 @@ size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_ta void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { + const char *codec_type; const char *codec_name; const char *profile = NULL; AVCodec *p; - char buf1[32]; int bitrate; AVRational display_aspect_ratio; - if (encode) - p = avcodec_find_encoder(enc->codec_id); - else - p = avcodec_find_decoder(enc->codec_id); - - if (p) { - codec_name = p->name; - profile = av_get_profile_name(p, enc->profile); - } else if (enc->codec_id == CODEC_ID_MPEG2TS) { - /* fake mpeg2 transport stream codec (currently not - registered) */ - codec_name = "mpeg2ts"; - } else if (enc->codec_name[0] != '\0') { - codec_name = enc->codec_name; - } else { - /* output avi tags */ + if (!buf || buf_size <= 0) + return; + codec_type = av_get_media_type_string(enc->codec_type); + codec_name = avcodec_get_name(enc->codec_id); + if (enc->profile != FF_PROFILE_UNKNOWN) { + p = encode ? avcodec_find_encoder(enc->codec_id) : + avcodec_find_decoder(enc->codec_id); + if (p) + profile = av_get_profile_name(p, enc->profile); + } + + snprintf(buf, buf_size, "%s: %s%s", codec_type ? codec_type : "unknown", + codec_name, enc->mb_decision ? " (hq)" : ""); + buf[0] ^= 'a' ^ 'A'; /* first letter in uppercase */ + if (profile) + snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile); + if (enc->codec_tag) { char tag_buf[32]; av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag); - snprintf(buf1, sizeof(buf1), "%s / 0x%04X", tag_buf, enc->codec_tag); - codec_name = buf1; + snprintf(buf + strlen(buf), buf_size - strlen(buf), + " (%s / 0x%04X)", tag_buf, enc->codec_tag); } - switch(enc->codec_type) { case AVMEDIA_TYPE_VIDEO: - snprintf(buf, buf_size, - "Video: %s%s", - codec_name, enc->mb_decision ? " (hq)" : ""); - if (profile) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " (%s)", profile); if (enc->pix_fmt != PIX_FMT_NONE) { snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %s", @@ -1532,7 +1692,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) enc->height*enc->sample_aspect_ratio.den, 1024*1024); snprintf(buf + strlen(buf), buf_size - strlen(buf), - " [PAR %d:%d DAR %d:%d]", + " [SAR %d:%d DAR %d:%d]", enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den, display_aspect_ratio.num, display_aspect_ratio.den); } @@ -1549,12 +1709,6 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) } break; case AVMEDIA_TYPE_AUDIO: - snprintf(buf, buf_size, - "Audio: %s", - codec_name); - if (profile) - snprintf(buf + strlen(buf), buf_size - strlen(buf), - " (%s)", profile); if (enc->sample_rate) { snprintf(buf + strlen(buf), buf_size - strlen(buf), ", %d Hz", enc->sample_rate); @@ -1566,17 +1720,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) ", %s", av_get_sample_fmt_name(enc->sample_fmt)); } break; - case AVMEDIA_TYPE_DATA: - snprintf(buf, buf_size, "Data: %s", codec_name); - break; - case AVMEDIA_TYPE_SUBTITLE: - snprintf(buf, buf_size, "Subtitle: %s", codec_name); - break; - case AVMEDIA_TYPE_ATTACHMENT: - snprintf(buf, buf_size, "Attachment: %s", codec_name); - break; default: - snprintf(buf, buf_size, "Invalid Codec type %d", enc->codec_type); return; } if (encode) { @@ -1609,18 +1753,25 @@ const char *av_get_profile_name(const AVCodec *codec, int profile) unsigned avcodec_version( void ) { +// av_assert0(CODEC_ID_V410==164); + av_assert0(CODEC_ID_PCM_S8_PLANAR==65563); + av_assert0(CODEC_ID_ADPCM_G722==69660); +// av_assert0(CODEC_ID_BMV_AUDIO==86071); + av_assert0(CODEC_ID_SRT==94216); + av_assert0(LIBAVCODEC_VERSION_MICRO >= 100); + return LIBAVCODEC_VERSION_INT; } const char *avcodec_configuration(void) { - return LIBAV_CONFIGURATION; + return FFMPEG_CONFIGURATION; } const char *avcodec_license(void) { #define LICENSE_PREFIX "libavcodec license: " - return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1; + return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; } void avcodec_flush_buffers(AVCodecContext *avctx) @@ -1666,7 +1817,7 @@ static void audio_free_buffers(AVCodecContext *avctx) if (buf->extended_data) { av_free(buf->extended_data[0]); if (buf->extended_data != buf->data) - av_free(buf->extended_data); + av_freep(&buf->extended_data); } av_freep(&avci->buffer); } @@ -1762,7 +1913,7 @@ int ff_match_2uint16(const uint16_t (*tab)[2], int size, int a, int b){ void av_log_missing_feature(void *avc, const char *feature, int want_sample) { - av_log(avc, AV_LOG_WARNING, "%s not implemented. Update your Libav " + av_log(avc, AV_LOG_WARNING, "%s not implemented. Update your FFmpeg " "version to the newest one from Git. If the problem still " "occurs, it means that your file has a feature which has not " "been implemented.\n", feature); @@ -1779,8 +1930,8 @@ void av_log_ask_for_sample(void *avc, const char *msg, ...) if (msg) av_vlog(avc, AV_LOG_WARNING, msg, argument_list); av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample " - "of this file to ftp://upload.libav.org/incoming/ " - "and contact the libav-devel mailing list.\n"); + "of this file to ftp://upload.ffmpeg.org/MPlayer/incoming/ " + "and contact the ffmpeg-devel mailing list.\n"); va_end(argument_list); } @@ -1864,6 +2015,9 @@ unsigned int avpriv_toupper4(unsigned int x) int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) { f->owner = avctx; + + ff_init_buffer_info(avctx, f); + return avctx->get_buffer(avctx, f); } @@ -1888,6 +2042,12 @@ void ff_thread_await_progress(AVFrame *f, int progress, int field) enum AVMediaType avcodec_get_type(enum CodecID codec_id) { + AVCodec *c= avcodec_find_decoder(codec_id); + if(!c) + c= avcodec_find_encoder(codec_id); + if(c) + return c->type; + if (codec_id <= CODEC_ID_NONE) return AVMEDIA_TYPE_UNKNOWN; else if (codec_id < CODEC_ID_FIRST_AUDIO) diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c index 413a3743c5..1938f8c3f1 100644 --- a/libavcodec/utvideo.c +++ b/libavcodec/utvideo.c @@ -369,15 +369,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (c->pic.data[0]) ff_thread_release_buffer(avctx, &c->pic); - c->pic.reference = 1; + c->pic.reference = 3; c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; if ((ret = ff_thread_get_buffer(avctx, &c->pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - ff_thread_finish_setup(avctx); - /* parse plane structure to retrieve frame flags and validate slice offsets */ ptr = buf; for (i = 0; i < c->planes; i++) { diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c index d464572f78..1703ceebdd 100644 --- a/libavcodec/v210dec.c +++ b/libavcodec/v210dec.c @@ -4,28 +4,52 @@ * Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 "v210dec.h" #include "libavutil/bswap.h" +#define READ_PIXELS(a, b, c) \ + do { \ + val = av_le2ne32(*src++); \ + *a++ = val & 0x3FF; \ + *b++ = (val >> 10) & 0x3FF; \ + *c++ = (val >> 20) & 0x3FF; \ + } while (0) + +static void v210_planar_unpack_c(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width) +{ + uint32_t val; + int i; + + for( i = 0; i < width-5; i += 6 ){ + READ_PIXELS(u, y, v); + READ_PIXELS(y, u, y); + READ_PIXELS(v, y, u); + READ_PIXELS(y, v, y); + } +} + static av_cold int decode_init(AVCodecContext *avctx) { + V210DecContext *s = avctx->priv_data; + if (avctx->width & 1) { av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n"); return -1; @@ -37,18 +61,37 @@ static av_cold int decode_init(AVCodecContext *avctx) if (!avctx->coded_frame) return AVERROR(ENOMEM); + s->unpack_frame = v210_planar_unpack_c; + + if (HAVE_MMX) + v210_x86_init(s); + return 0; } static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { - int h, w; + V210DecContext *s = avctx->priv_data; + + int h, w, stride, aligned_input; AVFrame *pic = avctx->coded_frame; const uint8_t *psrc = avpkt->data; uint16_t *y, *u, *v; - int aligned_width = ((avctx->width + 47) / 48) * 48; - int stride = aligned_width * 8 / 3; + + if (s->custom_stride ) + stride = s->custom_stride; + else { + int aligned_width = ((avctx->width + 47) / 48) * 48; + stride = aligned_width * 8 / 3; + } + + aligned_input = !((uintptr_t)psrc & 0xf) && !(stride & 0xf); + if (aligned_input != s->aligned_input) { + s->aligned_input = aligned_input; + if (HAVE_MMX) + v210_x86_init(s); + } if (pic->data[0]) avctx->release_buffer(avctx, pic); @@ -68,36 +111,31 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, pic->pict_type = AV_PICTURE_TYPE_I; pic->key_frame = 1; -#define READ_PIXELS(a, b, c) \ - do { \ - val = av_le2ne32(*src++); \ - *a++ = val & 0x3FF; \ - *b++ = (val >> 10) & 0x3FF; \ - *c++ = (val >> 20) & 0x3FF; \ - } while (0) - for (h = 0; h < avctx->height; h++) { const uint32_t *src = (const uint32_t*)psrc; uint32_t val; - for (w = 0; w < avctx->width - 5; w += 6) { - READ_PIXELS(u, y, v); - READ_PIXELS(y, u, y); - READ_PIXELS(v, y, u); - READ_PIXELS(y, v, y); - } + + w = (avctx->width / 6) * 6; + s->unpack_frame(src, y, u, v, w); + + y += w; + u += w >> 1; + v += w >> 1; + src += (w << 1) / 3; + if (w < avctx->width - 1) { READ_PIXELS(u, y, v); val = av_le2ne32(*src++); *y++ = val & 0x3FF; - } - if (w < avctx->width - 3) { - *u++ = (val >> 10) & 0x3FF; - *y++ = (val >> 20) & 0x3FF; - - val = av_le2ne32(*src++); - *v++ = val & 0x3FF; - *y++ = (val >> 10) & 0x3FF; + if (w < avctx->width - 3) { + *u++ = (val >> 10) & 0x3FF; + *y++ = (val >> 20) & 0x3FF; + + val = av_le2ne32(*src++); + *v++ = val & 0x3FF; + *y++ = (val >> 10) & 0x3FF; + } } psrc += stride; @@ -122,13 +160,29 @@ static av_cold int decode_close(AVCodecContext *avctx) return 0; } +#define V210DEC_FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM +static const AVOption v210dec_options[] = { + {"custom_stride", "Custom V210 stride", offsetof(V210DecContext, custom_stride), FF_OPT_TYPE_INT, + {.dbl = 0}, INT_MIN, INT_MAX, V210DEC_FLAGS}, + {NULL} +}; + +static const AVClass v210dec_class = { + "V210 Decoder", + av_default_item_name, + v210dec_options, + LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_v210_decoder = { .name = "v210", .type = AVMEDIA_TYPE_VIDEO, .id = CODEC_ID_V210, + .priv_data_size = sizeof(V210DecContext), .init = decode_init, .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"), + .priv_class = &v210dec_class, }; diff --git a/libavcodec/v210dec.h b/libavcodec/v210dec.h new file mode 100644 index 0000000000..48be729a5f --- /dev/null +++ b/libavcodec/v210dec.h @@ -0,0 +1,34 @@ +/* + * This file is part of Libav. + * + * Libav 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. + * + * Libav 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 Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_V210DEC_H +#define AVCODEC_V210DEC_H + +#include "libavutil/log.h" +#include "libavutil/opt.h" + +typedef struct { + AVClass *av_class; + int custom_stride; + int aligned_input; + void (*unpack_frame)(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +} V210DecContext; + +void v210_x86_init(V210DecContext *s); + +#endif /* AVCODEC_V210DEC_H */ diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c index 77cb30bbfe..a2efb5e83f 100644 --- a/libavcodec/v210enc.c +++ b/libavcodec/v210enc.c @@ -4,20 +4,20 @@ * Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -91,13 +91,13 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, val = CLIP(*y++); if (w == avctx->width - 2) bytestream_put_le32(&p, val); - } - if (w < avctx->width - 3) { - val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20); - bytestream_put_le32(&p, val); + if (w < avctx->width - 3) { + val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20); + bytestream_put_le32(&p, val); - val = CLIP(*v++) | (CLIP(*y++) << 10); - bytestream_put_le32(&p, val); + val = CLIP(*v++) | (CLIP(*y++) << 10); + bytestream_put_le32(&p, val); + } } pdst += stride; diff --git a/libavcodec/v210x.c b/libavcodec/v210x.c index 959dec5f86..1435249e04 100644 --- a/libavcodec/v210x.c +++ b/libavcodec/v210x.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -31,6 +31,8 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->bits_per_raw_sample= 10; avctx->coded_frame= avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; } diff --git a/libavcodec/v308dec.c b/libavcodec/v308dec.c new file mode 100644 index 0000000000..a24ccf4384 --- /dev/null +++ b/libavcodec/v308dec.c @@ -0,0 +1,108 @@ +/* + * v308 decoder + * Copyright (c) 2011 Carl Eugen Hoyos + * + * 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 av_cold int v308_decode_init(AVCodecContext *avctx) +{ + avctx->pix_fmt = PIX_FMT_YUV444P; + + if (avctx->width & 1) + av_log(avctx, AV_LOG_WARNING, "v308 requires width to be even.\n"); + + avctx->coded_frame = avcodec_alloc_frame(); + + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int v308_decode_frame(AVCodecContext *avctx, void *data, + int *data_size, AVPacket *avpkt) +{ + AVFrame *pic = avctx->coded_frame; + const uint8_t *src = avpkt->data; + uint8_t *y, *u, *v; + int i, j; + + if (pic->data[0]) + avctx->release_buffer(avctx, pic); + + if (avpkt->size < 3 * avctx->height * avctx->width) { + av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); + return AVERROR(EINVAL); + } + + pic->reference = 0; + + if (avctx->get_buffer(avctx, pic) < 0) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); + return AVERROR(ENOMEM); + } + + pic->key_frame = 1; + pic->pict_type = AV_PICTURE_TYPE_I; + + y = pic->data[0]; + u = pic->data[1]; + v = pic->data[2]; + + for (i = 0; i < avctx->height; i++) { + for (j = 0; j < avctx->width; j++) { + v[j] = *src++; + y[j] = *src++; + u[j] = *src++; + } + + y += pic->linesize[0]; + u += pic->linesize[1]; + v += pic->linesize[2]; + } + + *data_size = sizeof(AVFrame); + *(AVFrame *)data = *pic; + + return avpkt->size; +} + +static av_cold int v308_decode_close(AVCodecContext *avctx) +{ + if (avctx->coded_frame->data[0]) + avctx->release_buffer(avctx, avctx->coded_frame); + + av_freep(&avctx->coded_frame); + + return 0; +} + +AVCodec ff_v308_decoder = { + .name = "v308", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_V308, + .init = v308_decode_init, + .decode = v308_decode_frame, + .close = v308_decode_close, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), +}; diff --git a/libavcodec/v308enc.c b/libavcodec/v308enc.c new file mode 100644 index 0000000000..77fe073852 --- /dev/null +++ b/libavcodec/v308enc.c @@ -0,0 +1,96 @@ +/* + * v308 encoder + * + * Copyright (c) 2011 Carl Eugen Hoyos + * + * 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 "libavutil/intreadwrite.h" +#include "avcodec.h" + +static av_cold int v308_encode_init(AVCodecContext *avctx) +{ + if (avctx->width & 1) { + av_log(avctx, AV_LOG_ERROR, "v308 requires width to be even.\n"); + return AVERROR_INVALIDDATA; + } + + avctx->coded_frame = avcodec_alloc_frame(); + + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int v308_encode_frame(AVCodecContext *avctx, uint8_t *buf, + int buf_size, void *data) +{ + AVFrame *pic = data; + uint8_t *dst = buf; + uint8_t *y, *u, *v; + int i, j; + int output_size = 0; + + if (buf_size < avctx->width * avctx->height * 3) { + av_log(avctx, AV_LOG_ERROR, "Out buffer is too small.\n"); + return AVERROR(ENOMEM); + } + + avctx->coded_frame->reference = 0; + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + + y = pic->data[0]; + u = pic->data[1]; + v = pic->data[2]; + + for (i = 0; i < avctx->height; i++) { + for (j = 0; j < avctx->width; j++) { + *dst++ = v[j]; + *dst++ = y[j]; + *dst++ = u[j]; + output_size += 3; + } + y += pic->linesize[0]; + u += pic->linesize[1]; + v += pic->linesize[2]; + } + + return output_size; +} + +static av_cold int v308_encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + + return 0; +} + +AVCodec ff_v308_encoder = { + .name = "v308", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_V308, + .init = v308_encode_init, + .encode = v308_encode_frame, + .close = v308_encode_close, + .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUV444P, PIX_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"), +}; diff --git a/libavcodec/v408dec.c b/libavcodec/v408dec.c new file mode 100644 index 0000000000..0f9bc9157f --- /dev/null +++ b/libavcodec/v408dec.c @@ -0,0 +1,129 @@ +/* + * v408 decoder + * Copyright (c) 2012 Carl Eugen Hoyos + * + * 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 av_cold int v408_decode_init(AVCodecContext *avctx) +{ + avctx->pix_fmt = PIX_FMT_YUVA444P; + + avctx->coded_frame = avcodec_alloc_frame(); + + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int v408_decode_frame(AVCodecContext *avctx, void *data, + int *data_size, AVPacket *avpkt) +{ + AVFrame *pic = avctx->coded_frame; + const uint8_t *src = avpkt->data; + uint8_t *y, *u, *v, *a; + int i, j; + + if (pic->data[0]) + avctx->release_buffer(avctx, pic); + + if (avpkt->size < 4 * avctx->height * avctx->width) { + av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); + return AVERROR(EINVAL); + } + + pic->reference = 0; + + if (avctx->get_buffer(avctx, pic) < 0) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); + return AVERROR(ENOMEM); + } + + pic->key_frame = 1; + pic->pict_type = AV_PICTURE_TYPE_I; + + y = pic->data[0]; + u = pic->data[1]; + v = pic->data[2]; + a = pic->data[3]; + + for (i = 0; i < avctx->height; i++) { + for (j = 0; j < avctx->width; j++) { + if (avctx->codec_id==CODEC_ID_AYUV) { + v[j] = *src++; + u[j] = *src++; + y[j] = *src++; + a[j] = *src++; + } else { + u[j] = *src++; + y[j] = *src++; + v[j] = *src++; + a[j] = *src++; + } + } + + y += pic->linesize[0]; + u += pic->linesize[1]; + v += pic->linesize[2]; + a += pic->linesize[3]; + } + + *data_size = sizeof(AVFrame); + *(AVFrame *)data = *pic; + + return avpkt->size; +} + +static av_cold int v408_decode_close(AVCodecContext *avctx) +{ + if (avctx->coded_frame->data[0]) + avctx->release_buffer(avctx, avctx->coded_frame); + + av_freep(&avctx->coded_frame); + + return 0; +} + +#if CONFIG_AYUV_DECODER +AVCodec ff_ayuv_decoder = { + .name = "ayuv", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_AYUV, + .init = v408_decode_init, + .decode = v408_decode_frame, + .close = v408_decode_close, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"), +}; +#endif +#if CONFIG_V408_DECODER +AVCodec ff_v408_decoder = { + .name = "v408", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_V408, + .init = v408_decode_init, + .decode = v408_decode_frame, + .close = v408_decode_close, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"), +}; +#endif diff --git a/libavcodec/v408enc.c b/libavcodec/v408enc.c new file mode 100644 index 0000000000..e945ba65ad --- /dev/null +++ b/libavcodec/v408enc.c @@ -0,0 +1,115 @@ +/* + * v408 encoder + * + * Copyright (c) 2012 Carl Eugen Hoyos + * + * 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 "libavutil/intreadwrite.h" +#include "avcodec.h" + +static av_cold int v408_encode_init(AVCodecContext *avctx) +{ + avctx->coded_frame = avcodec_alloc_frame(); + + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int v408_encode_frame(AVCodecContext *avctx, uint8_t *buf, + int buf_size, void *data) +{ + AVFrame *pic = data; + uint8_t *dst = buf; + uint8_t *y, *u, *v, *a; + int i, j; + int output_size = 0; + + if (buf_size < avctx->width * avctx->height * 4) { + av_log(avctx, AV_LOG_ERROR, "Out buffer is too small.\n"); + return AVERROR(ENOMEM); + } + + avctx->coded_frame->reference = 0; + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + + y = pic->data[0]; + u = pic->data[1]; + v = pic->data[2]; + a = pic->data[3]; + + for (i = 0; i < avctx->height; i++) { + for (j = 0; j < avctx->width; j++) { + if (avctx->codec_id==CODEC_ID_AYUV) { + *dst++ = v[j]; + *dst++ = u[j]; + *dst++ = y[j]; + *dst++ = a[j]; + } else { + *dst++ = u[j]; + *dst++ = y[j]; + *dst++ = v[j]; + *dst++ = a[j]; + } + output_size += 4; + } + y += pic->linesize[0]; + u += pic->linesize[1]; + v += pic->linesize[2]; + a += pic->linesize[3]; + } + + return output_size; +} + +static av_cold int v408_encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + + return 0; +} + +#if CONFIG_AYUV_ENCODER +AVCodec ff_ayuv_encoder = { + .name = "ayuv", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_AYUV, + .init = v408_encode_init, + .encode = v408_encode_frame, + .close = v408_encode_close, + .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUVA444P, PIX_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"), +}; +#endif +#if CONFIG_V408_ENCODER +AVCodec ff_v408_encoder = { + .name = "v408", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_V408, + .init = v408_encode_init, + .encode = v408_encode_frame, + .close = v408_encode_close, + .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUVA444P, PIX_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"), +}; +#endif diff --git a/libavcodec/v410dec.c b/libavcodec/v410dec.c index a6f236bd6d..10d73057af 100644 --- a/libavcodec/v410dec.c +++ b/libavcodec/v410dec.c @@ -3,20 +3,20 @@ * * Copyright (c) 2011 Derek Buitenhuis * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,8 +29,7 @@ static av_cold int v410_decode_init(AVCodecContext *avctx) avctx->bits_per_raw_sample = 10; if (avctx->width & 1) { - av_log(avctx, AV_LOG_ERROR, "v410 requires even width.\n"); - return AVERROR_INVALIDDATA; + av_log(avctx, AV_LOG_WARNING, "v410 requires width to be even.\n"); } avctx->coded_frame = avcodec_alloc_frame(); diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c index a6b3ddbf30..bcd7c65bdc 100644 --- a/libavcodec/v410enc.c +++ b/libavcodec/v410enc.c @@ -3,20 +3,20 @@ * * Copyright (c) 2011 Derek Buitenhuis * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +26,7 @@ static av_cold int v410_encode_init(AVCodecContext *avctx) { if (avctx->width & 1) { - av_log(avctx, AV_LOG_ERROR, "v410 requires even width.\n"); + av_log(avctx, AV_LOG_ERROR, "v410 requires width to be even.\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c index d6b0298ee0..774fde840f 100644 --- a/libavcodec/vaapi.c +++ b/libavcodec/vaapi.c @@ -4,20 +4,20 @@ * * Copyright (C) 2008-2009 Splitted-Desktop Systems * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vaapi.h b/libavcodec/vaapi.h index 36fb386acf..4c3bb9bb52 100644 --- a/libavcodec/vaapi.h +++ b/libavcodec/vaapi.h @@ -1,23 +1,23 @@ /* - * Video Acceleration API (shared data between Libav and the video player) + * Video Acceleration API (shared data between FFmpeg and the video player) * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1 * * Copyright (C) 2008-2009 Splitted-Desktop Systems * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -33,7 +33,7 @@ */ /** - * This structure is used to share data between the Libav library and + * This structure is used to share data between the FFmpeg library and * the client video application. * This shall be zero-allocated and available as * AVCodecContext.hwaccel_context. All user members can be set once diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index 820568aa25..753deaf5ca 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -3,20 +3,20 @@ * * Copyright (C) 2008-2009 Splitted-Desktop Systems * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,7 +25,7 @@ /** * @file - * This file implements the glue code between Libav's and VA API's + * This file implements the glue code between FFmpeg's and VA API's * structures for H.264 decoding. */ @@ -43,10 +43,10 @@ static void init_vaapi_pic(VAPictureH264 *va_pic) } /** - * Translate an Libav Picture into its VA API form. + * Translate an FFmpeg Picture into its VA API form. * * @param[out] va_pic A pointer to VA API's own picture struct - * @param[in] pic A pointer to the Libav picture struct to convert + * @param[in] pic A pointer to the FFmpeg picture struct to convert * @param[in] pic_structure The picture field type (as defined in mpegvideo.h), * supersedes pic's field type if nonzero. */ @@ -147,11 +147,11 @@ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param, } /** - * Fill in VA API reference picture lists from the Libav reference + * Fill in VA API reference picture lists from the FFmpeg reference * picture list. * * @param[out] RefPicList VA API internal reference picture list - * @param[in] ref_list A pointer to the Libav reference list + * @param[in] ref_list A pointer to the FFmpeg reference list * @param[in] ref_count The number of reference pictures in ref_list */ static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32], @@ -259,7 +259,7 @@ static int start_frame(AVCodecContext *avctx, pic_param->seq_fields.bits.delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag; pic_param->num_slice_groups_minus1 = h->pps.slice_group_count - 1; pic_param->slice_group_map_type = h->pps.mb_slice_group_map_type; - pic_param->slice_group_change_rate_minus1 = 0; /* XXX: unimplemented in Libav */ + pic_param->slice_group_change_rate_minus1 = 0; /* XXX: unimplemented in FFmpeg */ pic_param->pic_init_qp_minus26 = h->pps.init_qp - 26; pic_param->pic_init_qs_minus26 = h->pps.init_qs - 26; pic_param->chroma_qp_index_offset = h->pps.chroma_qp_index_offset[0]; @@ -282,7 +282,8 @@ static int start_frame(AVCodecContext *avctx, if (!iq_matrix) return -1; memcpy(iq_matrix->ScalingList4x4, h->pps.scaling_matrix4, sizeof(iq_matrix->ScalingList4x4)); - memcpy(iq_matrix->ScalingList8x8, h->pps.scaling_matrix8, sizeof(iq_matrix->ScalingList8x8)); + memcpy(iq_matrix->ScalingList8x8[0], h->pps.scaling_matrix8[0], sizeof(iq_matrix->ScalingList8x8[0])); + memcpy(iq_matrix->ScalingList8x8[1], h->pps.scaling_matrix8[3], sizeof(iq_matrix->ScalingList8x8[0])); return 0; } diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h index c6d5d6e42a..e514dd6f44 100644 --- a/libavcodec/vaapi_internal.h +++ b/libavcodec/vaapi_internal.h @@ -4,20 +4,20 @@ * * Copyright (C) 2008-2009 Splitted-Desktop Systems * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c index 95107c8a37..030f76bfb9 100644 --- a/libavcodec/vaapi_mpeg2.c +++ b/libavcodec/vaapi_mpeg2.c @@ -3,20 +3,20 @@ * * Copyright (C) 2008-2009 Splitted-Desktop Systems * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c index 41d54c6116..946095320b 100644 --- a/libavcodec/vaapi_mpeg4.c +++ b/libavcodec/vaapi_mpeg4.c @@ -3,20 +3,20 @@ * * Copyright (C) 2008-2009 Splitted-Desktop Systems * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -129,7 +129,7 @@ static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer /* video_plane_with_short_video_header() contains all GOBs * in-order, and this is what VA API (Intel backend) expects: only - * a single slice param. So fake macroblock_number for Libav so + * a single slice param. So fake macroblock_number for FFmpeg so * that we don't call vaapi_mpeg4_decode_slice() again */ if (avctx->codec->id == CODEC_ID_H263) diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index df3f77e39e..35fda572d3 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -3,20 +3,20 @@ * * Copyright (C) 2008-2009 Splitted-Desktop Systems * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -24,7 +24,7 @@ #include "vc1.h" #include "vc1data.h" -/** Translate Libav MV modes to VA API */ +/** Translate FFmpeg MV modes to VA API */ static int get_VAMvModeVC1(enum MVModes mv_mode) { switch (mv_mode) { @@ -128,7 +128,7 @@ static inline int vc1_get_TTFRM(VC1Context *v) return 0; } -/** Pack Libav bitplanes into a VABitPlaneBuffer element */ +/** Pack FFmpeg bitplanes into a VABitPlaneBuffer element */ static inline void vc1_pack_bitplanes(uint8_t *bitplane, int n, const uint8_t *ff_bp[3], int x, int y, int stride) { const int bitplane_index = n / 2; diff --git a/libavcodec/vb.c b/libavcodec/vb.c index e7002a1def..bcb26452b0 100644 --- a/libavcodec/vb.c +++ b/libavcodec/vb.c @@ -2,20 +2,20 @@ * Beam Software VB decoder * Copyright (c) 2007 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -73,7 +73,7 @@ static void vb_decode_palette(VBDecContext *c, int data_size) return; } for(i = start; i <= start + size; i++) - c->pal[i] = bytestream2_get_be24(&c->stream); + c->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&c->stream); } static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end) @@ -197,7 +197,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if(c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); - c->pic.reference = 1; + c->pic.reference = 3; if(avctx->get_buffer(avctx, &c->pic) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; @@ -212,6 +212,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac } if(flags & VB_HAS_VIDEO){ size = bytestream2_get_le32(&c->stream); + if(size > bytestream2_get_bytes_left(&c->stream)+4 || size<4){ + av_log(avctx, AV_LOG_ERROR, "Frame size invalid\n"); + return -1; + } vb_decode_framedata(c, offset); bytestream2_skip(&c->stream, size - 4); } @@ -247,6 +251,7 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&c->pic); c->frame = av_mallocz(avctx->width * avctx->height); c->prev_frame = av_mallocz(avctx->width * avctx->height); diff --git a/libavcodec/vble.c b/libavcodec/vble.c index 574582af7b..57b3599ddb 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -2,20 +2,20 @@ * VBLE Decoder * Copyright (c) 2011 Derek Buitenhuis * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -35,55 +35,51 @@ typedef struct { DSPContext dsp; int size; - uint8_t *val; /* First holds the lengths of vlc symbols and then their values */ + uint8_t *val; ///< This array first holds the lengths of vlc symbols and then their value. } VBLEContext; -static uint8_t vble_read_reverse_unary(GetBitContext *gb) -{ - /* At most we need to read 9 bits total to get indices up to 8 */ - uint8_t val = show_bits(gb, 8); - - if (val) { - val = 7 - av_log2_16bit(av_reverse[val]); - skip_bits(gb, val + 1); - return val; - } else { - skip_bits(gb, 8); - if (get_bits1(gb)) - return 8; - } - - /* Return something larger than 8 on error */ - return UINT8_MAX; -} - static int vble_unpack(VBLEContext *ctx, GetBitContext *gb) { int i; + int allbits = 0; + static const uint8_t LUT[256] = { + 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + }; /* Read all the lengths in first */ for (i = 0; i < ctx->size; i++) { - ctx->val[i] = vble_read_reverse_unary(gb); - - if (ctx->val[i] == UINT8_MAX) - return -1; - } - - for (i = 0; i < ctx->size; i++) { - /* Check we have enough bits left */ - if (get_bits_left(gb) < ctx->val[i]) - return -1; - - /* get_bits can't take a length of 0 */ - if (ctx->val[i]) - ctx->val[i] = (1 << ctx->val[i]) + get_bits(gb, ctx->val[i]) - 1; + /* At most we need to read 9 bits total to get indices up to 8 */ + int val = show_bits(gb, 8); + + // read reverse unary + if (val) { + val = LUT[val]; + skip_bits(gb, val + 1); + ctx->val[i] = val; + } else { + skip_bits(gb, 8); + if (!get_bits1(gb)) + return -1; + ctx->val[i] = 8; + } + allbits += ctx->val[i]; } + /* Check we have enough bits left */ + if (get_bits_left(gb) < allbits) + return -1; return 0; } -static void vble_restore_plane(VBLEContext *ctx, int plane, int offset, - int width, int height) +static void vble_restore_plane(VBLEContext *ctx, GetBitContext *gb, int plane, + int offset, int width, int height) { AVFrame *pic = ctx->avctx->coded_frame; uint8_t *dst = pic->data[plane]; @@ -92,14 +88,17 @@ static void vble_restore_plane(VBLEContext *ctx, int plane, int offset, int i, j, left, left_top; for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - val[j] = (val[j] >> 1) ^ -(val[j] & 1); - + for (j = 0; j < width; j++) { + /* get_bits can't take a length of 0 */ + if (val[j]) { + int v = (1 << val[j]) + get_bits(gb, val[j]) - 1; + val[j] = (v >> 1) ^ -(v & 1); + } + } if (i) { left = 0; left_top = dst[-stride]; - ctx->dsp.add_hfyu_median_prediction(dst, dst-stride, val, - width, &left, &left_top); + ctx->dsp.add_hfyu_median_prediction(dst, dst-stride, val, width, &left, &left_top); } else { dst[0] = val[0]; for (j = 1; j < width; j++) @@ -154,15 +153,15 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } /* Restore planes. Should be almost identical to Huffyuv's. */ - vble_restore_plane(ctx, 0, offset, avctx->width, avctx->height); + vble_restore_plane(ctx, &gb, 0, offset, avctx->width, avctx->height); /* Chroma */ if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) { offset += avctx->width * avctx->height; - vble_restore_plane(ctx, 1, offset, width_uv, height_uv); + vble_restore_plane(ctx, &gb, 1, offset, width_uv, height_uv); offset += width_uv * height_uv; - vble_restore_plane(ctx, 2, offset, width_uv, height_uv); + vble_restore_plane(ctx, &gb, 2, offset, width_uv, height_uv); } *data_size = sizeof(AVFrame); diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 1394f2cd4b..a012967e3e 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -4,20 +4,20 @@ * Copyright (c) 2006-2007 Konstantin Shishkov * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -380,8 +380,9 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte v->finterpflag = get_bits1(gb); //common if (v->res_sprite) { - v->s.avctx->width = v->s.avctx->coded_width = get_bits(gb, 11); - v->s.avctx->height = v->s.avctx->coded_height = get_bits(gb, 11); + int w = get_bits(gb, 11); + int h = get_bits(gb, 11); + avcodec_set_dimensions(v->s.avctx, w, h); skip_bits(gb, 5); //frame rate v->res_x8 = get_bits1(gb); if (get_bits1(gb)) { // something to do with DC VLC selection @@ -417,6 +418,7 @@ int vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitConte static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) { + int w, h; v->res_rtm_flag = 1; v->level = get_bits(gb, 3); if (v->level >= 5) { @@ -435,10 +437,9 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) v->bitrtq_postproc = get_bits(gb, 5); //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; - v->s.avctx->width = v->s.avctx->coded_width; - v->s.avctx->height = v->s.avctx->coded_height; + w = (get_bits(gb, 12) + 1) << 1; + h = (get_bits(gb, 12) + 1) << 1; + avcodec_set_dimensions(v->s.avctx, w, h); v->broadcast = get_bits1(gb); v->interlace = get_bits1(gb); v->tfcntrflag = get_bits1(gb); @@ -547,9 +548,10 @@ int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext * } } - if (get_bits1(gb)) { - avctx->width = avctx->coded_width = (get_bits(gb, 12) + 1) << 1; - avctx->height = avctx->coded_height = (get_bits(gb, 12) + 1) << 1; + if(get_bits1(gb)){ + int w = (get_bits(gb, 12)+1)<<1; + int h = (get_bits(gb, 12)+1)<<1; + avcodec_set_dimensions(avctx, w, h); } if (v->extended_mv) v->extended_dmv = get_bits1(gb); @@ -822,8 +824,11 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */ int scale, shift, i; /* for initializing LUT for intensity compensation */ + v->numref=0; v->p_frame_skipped = 0; if (v->second_field) { + if(v->fcm!=2 || v->field_mode!=1) + return -1; v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; if (v->fptype & 4) v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B; @@ -891,6 +896,8 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->rnd = get_bits1(gb); if (v->interlace) v->uvsamp = get_bits1(gb); + if(!ff_vc1_bfraction_vlc.table) + return 0; //parsing only, vlc tables havnt been allocated if (v->field_mode) { if (!v->refdist_flag) v->refdist = 0; @@ -1155,6 +1162,8 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->field_mode) { int mvmode; + av_log(v->s.avctx, AV_LOG_ERROR, "B Fields do not work currently\n"); + return -1; if (v->extended_dmv) v->dmvrange = get_unary(gb, 0, 3); mvmode = get_unary(gb, 1, 3); diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 6096077660..1b39040bef 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -3,20 +3,20 @@ * Copyright (c) 2006-2007 Konstantin Shishkov * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c index 0cc5ea0fa8..a4130d9885 100644 --- a/libavcodec/vc1_parser.c +++ b/libavcodec/vc1_parser.c @@ -3,20 +3,20 @@ * Copyright (c) 2006-2007 Konstantin Shishkov * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vc1acdata.h b/libavcodec/vc1acdata.h index a7a33ff805..78de0f9a24 100644 --- a/libavcodec/vc1acdata.h +++ b/libavcodec/vc1acdata.h @@ -2,20 +2,20 @@ * VC-1 and WMV3 decoder * copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vc1data.c b/libavcodec/vc1data.c index 69d71ad954..7f979ba109 100644 --- a/libavcodec/vc1data.c +++ b/libavcodec/vc1data.c @@ -4,20 +4,20 @@ * copyright (c) 2006 Konstantin Shishkov * (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vc1data.h b/libavcodec/vc1data.h index da8f0a1f40..f11122504b 100644 --- a/libavcodec/vc1data.h +++ b/libavcodec/vc1data.h @@ -3,20 +3,20 @@ * copyright (c) 2006 Konstantin Shishkov * (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 417bd046b7..a3ac2cbbaa 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -4,20 +4,20 @@ * Copyright (c) 2006-2007 Konstantin Shishkov * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -508,7 +508,7 @@ static void vc1_mc_1mv(VC1Context *v, int dir) } if (v->field_mode) { // interlaced field picture if (!dir) { - if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) { + if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field) { srcY = s->current_picture.f.data[0]; srcU = s->current_picture.f.data[1]; srcV = s->current_picture.f.data[2]; @@ -632,7 +632,7 @@ static void vc1_mc_1mv(VC1Context *v, int dir) srcY += s->mspel * (1 + s->linesize); } - if (v->field_mode && v->cur_field_type) { + if (v->field_mode && v->second_field) { off = s->current_picture_ptr->f.linesize[0]; off_uv = s->current_picture_ptr->f.linesize[1]; } else { @@ -698,7 +698,7 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) if (!dir) { if (v->field_mode) { - if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) + if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field) srcY = s->current_picture.f.data[0]; else srcY = s->last_picture.f.data[0]; @@ -767,7 +767,7 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8; else off = s->linesize * 4 * (n & 2) + (n & 1) * 8; - if (v->field_mode && v->cur_field_type) + if (v->field_mode && v->second_field) off += s->current_picture_ptr->f.linesize[0]; src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2); @@ -996,7 +996,7 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) srcU += s->current_picture_ptr->f.linesize[1]; srcV += s->current_picture_ptr->f.linesize[2]; } - off = v->cur_field_type ? s->current_picture_ptr->f.linesize[1] : 0; + off = v->second_field ? s->current_picture_ptr->f.linesize[1] : 0; } if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP) @@ -2052,7 +2052,7 @@ static void vc1_interp_mc(VC1Context *v) srcY += s->mspel * (1 + s->linesize); } - if (v->field_mode && v->cur_field_type) { + if (v->field_mode && v->second_field) { off = s->current_picture_ptr->f.linesize[0]; off_uv = s->current_picture_ptr->f.linesize[1]; } else { @@ -4060,7 +4060,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) continue; v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; + off += v->second_field ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize); // TODO: loop filter } @@ -4107,7 +4107,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) dst_idx += i >> 2; val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; - if (v->cur_field_type) + if (v->second_field) off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]; if (val) { pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, @@ -4337,7 +4337,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) for (j = 0; j < 64; j++) s->block[i][j] <<= 1; off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); - off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; + off += v->second_field ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize); // TODO: yet to perform loop filter } @@ -4419,7 +4419,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) dst_idx += i >> 2; val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize; - if (v->cur_field_type) + if (v->second_field) off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]; if (val) { vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, @@ -5431,13 +5431,16 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, AVFrame *pict = data; uint8_t *buf2 = NULL; const uint8_t *buf_start = buf; - int mb_height, n_slices1; + int mb_height, n_slices1=-1; struct { uint8_t *buf; GetBitContext gb; int mby_start; } *slices = NULL, *tmp; + if(s->flags & CODEC_FLAG_LOW_DELAY) + s->low_delay = 1; + /* no supplementary picture */ if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) { /* special case for last picture */ @@ -5729,6 +5732,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, //av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), s->gb.size_in_bits); // if (get_bits_count(&s->gb) > buf_size * 8) // return -1; + if(s->error_occurred && s->pict_type == AV_PICTURE_TYPE_B) + goto err; ff_er_frame_end(s); } diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c index 9bd107cdd9..83cd0cfe8c 100644 --- a/libavcodec/vc1dsp.c +++ b/libavcodec/vc1dsp.c @@ -2,20 +2,20 @@ * VC-1 and WMV3 decoder - DSP functions * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h index 3e0a88e28d..d96853aa16 100644 --- a/libavcodec/vc1dsp.h +++ b/libavcodec/vc1dsp.h @@ -2,20 +2,20 @@ * VC-1 and WMV3 decoder - DSP functions * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vcr1.c b/libavcodec/vcr1.c index e50e092c7e..1526215314 100644 --- a/libavcodec/vcr1.c +++ b/libavcodec/vcr1.c @@ -2,20 +2,20 @@ * ATI VCR1 codec * Copyright (c) 2003 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -56,6 +56,11 @@ static int decode_frame(AVCodecContext *avctx, if(p->data[0]) avctx->release_buffer(avctx, p); + if(buf_size < 16 + avctx->height + avctx->width*avctx->height*5/8){ + av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); + return AVERROR(EINVAL); + } + p->reference= 0; if(avctx->get_buffer(avctx, p) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -142,6 +147,7 @@ static av_cold void common_init(AVCodecContext *avctx){ VCR1Context * const a = avctx->priv_data; avctx->coded_frame= (AVFrame*)&a->picture; + avcodec_get_frame_defaults(&a->picture); a->avctx= avctx; } diff --git a/libavcodec/vda.c b/libavcodec/vda.c index 34739f8e0c..a2814d7024 100644 --- a/libavcodec/vda.c +++ b/libavcodec/vda.c @@ -1,22 +1,22 @@ /* - * VDA hardware acceleration + * VDA HW acceleration. * * copyright (c) 2011 Sebastien Zwickert * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,12 +29,11 @@ #include "libavutil/avutil.h" #include "vda_internal.h" -/* helper to create a dictionary according to the given pts */ +/* Helper to create a dictionary according to the given pts. */ static CFDictionaryRef vda_dictionary_with_pts(int64_t i_pts) { - CFStringRef key = CFSTR("FF_VDA_DECODER_PTS_KEY"); - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, - kCFNumberSInt64Type, &i_pts); + CFStringRef key = CFSTR("FF_VDA_DECODER_PTS_KEY"); + CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &i_pts); CFDictionaryRef user_info = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&key, (const void **)&value, @@ -45,7 +44,7 @@ static CFDictionaryRef vda_dictionary_with_pts(int64_t i_pts) return user_info; } -/* helper to retrieve the pts from the given dictionary */ +/* Helper to retrieve the pts from the given dictionary. */ static int64_t vda_pts_from_dictionary(CFDictionaryRef user_info) { CFNumberRef pts; @@ -62,7 +61,7 @@ static int64_t vda_pts_from_dictionary(CFDictionaryRef user_info) return outValue; } -/* Remove and release all frames from the queue. */ +/* Removes and releases all frames from the queue. */ static void vda_clear_queue(struct vda_context *vda_ctx) { vda_frame *top_frame; @@ -70,7 +69,7 @@ static void vda_clear_queue(struct vda_context *vda_ctx) pthread_mutex_lock(&vda_ctx->queue_mutex); while (vda_ctx->queue) { - top_frame = vda_ctx->queue; + top_frame = vda_ctx->queue; vda_ctx->queue = top_frame->next_frame; ff_vda_release_vda_frame(top_frame); } @@ -78,14 +77,15 @@ static void vda_clear_queue(struct vda_context *vda_ctx) pthread_mutex_unlock(&vda_ctx->queue_mutex); } -/* Decoder callback that adds the VDA frame to the queue in display order. */ -static void vda_decoder_callback(void *vda_hw_ctx, - CFDictionaryRef user_info, - OSStatus status, - uint32_t infoFlags, - CVImageBufferRef image_buffer) + +/* Decoder callback that adds the vda frame to the queue in display order. */ +static void vda_decoder_callback (void *vda_hw_ctx, + CFDictionaryRef user_info, + OSStatus status, + uint32_t infoFlags, + CVImageBufferRef image_buffer) { - struct vda_context *vda_ctx = vda_hw_ctx; + struct vda_context *vda_ctx = (struct vda_context*)vda_hw_ctx; vda_frame *new_frame; vda_frame *queue_walker; @@ -95,27 +95,31 @@ static void vda_decoder_callback(void *vda_hw_ctx, if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer)) return; - if (!(new_frame = av_mallocz(sizeof(vda_frame)))) + new_frame = av_mallocz(sizeof(vda_frame)); + if (!new_frame) return; + new_frame->next_frame = NULL; - new_frame->cv_buffer = CVPixelBufferRetain(image_buffer); - new_frame->pts = vda_pts_from_dictionary(user_info); + new_frame->cv_buffer = CVPixelBufferRetain(image_buffer); + new_frame->pts = vda_pts_from_dictionary(user_info); pthread_mutex_lock(&vda_ctx->queue_mutex); queue_walker = vda_ctx->queue; - if (!queue_walker || new_frame->pts < queue_walker->pts) { + if (!queue_walker || (new_frame->pts < queue_walker->pts)) { /* we have an empty queue, or this frame earlier than the current queue head */ new_frame->next_frame = queue_walker; - vda_ctx->queue = new_frame; + vda_ctx->queue = new_frame; } else { /* walk the queue and insert this frame where it belongs in display order */ vda_frame *next_frame; + while (1) { next_frame = queue_walker->next_frame; - if (!next_frame || new_frame->pts < next_frame->pts) { - new_frame->next_frame = next_frame; + + if (!next_frame || (new_frame->pts < next_frame->pts)) { + new_frame->next_frame = next_frame; queue_walker->next_frame = new_frame; break; } @@ -140,16 +144,24 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx, CFMutableDictionaryRef io_surface_properties; CFNumberRef cv_pix_fmt; + vda_ctx->bitstream = NULL; + vda_ctx->ref_size = 0; + pthread_mutex_init(&vda_ctx->queue_mutex, NULL); + if (extradata[4]==0xFE) { + // convert 3 byte NAL sizes to 4 byte + extradata[4] = 0xFF; + } + config_info = CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height); - width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width); - format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format); + height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height); + width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width); + format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format); avc_data = CFDataCreate(kCFAllocatorDefault, extradata, extradata_size); CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height); @@ -165,9 +177,9 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, - kCFNumberSInt32Type, - &vda_ctx->cv_pix_fmt_type); + cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, + kCFNumberSInt32Type, + &vda_ctx->cv_pix_fmt_type); CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt); @@ -177,7 +189,7 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx, status = VDADecoderCreate(config_info, buffer_attributes, - vda_decoder_callback, + (VDADecoderOutputCallback *)vda_decoder_callback, vda_ctx, &vda_ctx->decoder); @@ -207,6 +219,9 @@ int ff_vda_destroy_decoder(struct vda_context *vda_ctx) pthread_mutex_destroy(&vda_ctx->queue_mutex); + if (vda_ctx->bitstream) + av_freep(&vda_ctx->bitstream); + if (kVDADecoderNoErr != status) return status; @@ -221,7 +236,7 @@ vda_frame *ff_vda_queue_pop(struct vda_context *vda_ctx) return NULL; pthread_mutex_lock(&vda_ctx->queue_mutex); - top_frame = vda_ctx->queue; + top_frame = vda_ctx->queue; vda_ctx->queue = top_frame->next_frame; pthread_mutex_unlock(&vda_ctx->queue_mutex); @@ -246,8 +261,9 @@ int ff_vda_decoder_decode(struct vda_context *vda_ctx, CFDataRef coded_frame; coded_frame = CFDataCreate(kCFAllocatorDefault, bitstream, bitstream_size); - user_info = vda_dictionary_with_pts(frame_pts); - status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, user_info); + user_info = vda_dictionary_with_pts(frame_pts); + + status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, user_info); CFRelease(user_info); CFRelease(coded_frame); diff --git a/libavcodec/vda.h b/libavcodec/vda.h index 2cb51c5f53..6e9de9cd0a 100644 --- a/libavcodec/vda.h +++ b/libavcodec/vda.h @@ -3,20 +3,20 @@ * * copyright (c) 2011 Sebastien Zwickert * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +37,7 @@ /** * This structure is used to store a decoded frame information and data. */ -typedef struct vda_frame { +typedef struct { /** * The PTS of the frame. * @@ -65,7 +65,7 @@ typedef struct vda_frame { /** * This structure is used to provide the necessary configurations and data - * to the VDA Libav HWAccel implementation. + * to the VDA FFmpeg HWAccel implementation. * * The application must make it available as AVCodecContext.hwaccel_context. */ @@ -125,6 +125,30 @@ struct vda_context { * - decoding: Set/Unset by user. */ OSType cv_pix_fmt_type; + + /** + * The current bitstream buffer. + * + * - encoding: unused + * - decoding: Set/Unset by libavcodec. + */ + uint8_t *bitstream; + + /** + * The current size of the bitstream. + * + * - encoding: unused + * - decoding: Set/Unset by libavcodec. + */ + int bitstream_size; + + /** + * The reference size used for fast reallocation. + * + * - encoding: unused + * - decoding: Set/Unset by libavcodec. + */ + int ref_size; }; /** Create the video decoder. */ diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c index b50a4c99a4..254268f558 100644 --- a/libavcodec/vda_h264.c +++ b/libavcodec/vda_h264.c @@ -1,49 +1,38 @@ /* - * VDA H.264 hardware acceleration + * VDA H264 HW acceleration. * * copyright (c) 2011 Sebastien Zwickert * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "h264.h" -#include "h264data.h" - #include "vda_internal.h" -/* This structure is used to store the bitstream of the current frame. */ -struct vda_picture_context { - uint8_t *bitstream; - int bitstream_size; -}; - static int start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { - const H264Context *h = avctx->priv_data; - struct vda_context *vda_ctx = avctx->hwaccel_context; - struct vda_picture_context *pic_ctx = h->s.current_picture_ptr->f.hwaccel_picture_private; + struct vda_context *vda_ctx = avctx->hwaccel_context; if (!vda_ctx->decoder) return -1; - pic_ctx->bitstream = NULL; - pic_ctx->bitstream_size = 0; + vda_ctx->bitstream_size = 0; return 0; } @@ -52,48 +41,43 @@ static int decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { - H264Context *h = avctx->priv_data; - struct vda_context *vda_ctx = avctx->hwaccel_context; - struct vda_picture_context *pic_ctx = h->s.current_picture_ptr->f.hwaccel_picture_private; + struct vda_context *vda_ctx = avctx->hwaccel_context; void *tmp; if (!vda_ctx->decoder) return -1; - tmp = av_realloc(pic_ctx->bitstream, pic_ctx->bitstream_size+size+4); + tmp = av_fast_realloc(vda_ctx->bitstream, &vda_ctx->ref_size, vda_ctx->bitstream_size+size+4); if (!tmp) return AVERROR(ENOMEM); - pic_ctx->bitstream = tmp; + vda_ctx->bitstream = tmp; - AV_WB32(pic_ctx->bitstream + pic_ctx->bitstream_size, size); - memcpy(pic_ctx->bitstream + pic_ctx->bitstream_size + 4, buffer, size); + AV_WB32(vda_ctx->bitstream+vda_ctx->bitstream_size, size); + memcpy(vda_ctx->bitstream+vda_ctx->bitstream_size+4, buffer, size); - pic_ctx->bitstream_size += size + 4; + vda_ctx->bitstream_size += size + 4; return 0; } static int end_frame(AVCodecContext *avctx) { - H264Context *h = avctx->priv_data; - struct vda_context *vda_ctx = avctx->hwaccel_context; - struct vda_picture_context *pic_ctx = h->s.current_picture_ptr->f.hwaccel_picture_private; - AVFrame *frame = &h->s.current_picture_ptr->f; + H264Context *h = avctx->priv_data; + struct vda_context *vda_ctx = avctx->hwaccel_context; + AVFrame *frame = &h->s.current_picture_ptr->f; int status; - if (!vda_ctx->decoder || !pic_ctx->bitstream) + if (!vda_ctx->decoder || !vda_ctx->bitstream) return -1; - status = ff_vda_decoder_decode(vda_ctx, pic_ctx->bitstream, - pic_ctx->bitstream_size, + status = ff_vda_decoder_decode(vda_ctx, vda_ctx->bitstream, + vda_ctx->bitstream_size, frame->reordered_opaque); if (status) av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status); - av_freep(&pic_ctx->bitstream); - return status; } @@ -105,5 +89,5 @@ AVHWAccel ff_h264_vda_hwaccel = { .start_frame = start_frame, .decode_slice = decode_slice, .end_frame = end_frame, - .priv_data_size = sizeof(struct vda_picture_context), + .priv_data_size = 0, }; diff --git a/libavcodec/vda_internal.h b/libavcodec/vda_internal.h index 364ebfb53e..df7305bfe6 100644 --- a/libavcodec/vda_internal.h +++ b/libavcodec/vda_internal.h @@ -1,22 +1,22 @@ /* - * VDA hardware acceleration + * VDA HW acceleration * * copyright (c) 2011 Sebastien Zwickert * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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 +26,7 @@ #include "vda.h" /** - * @addtogroup VDA_Decoding + * \addtogroup VDA_Decoding * * @{ */ diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index df04ca01fc..ce5103a6af 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -4,20 +4,20 @@ * * Copyright (c) 2008 NVIDIA * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -370,4 +370,40 @@ void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf, render->bitstream_buffers_used = 0; } +// Only dummy functions for now +static int vdpau_mpeg2_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + return 0; +} + +static int vdpau_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ + return 0; +} + +static int vdpau_mpeg2_end_frame(AVCodecContext *avctx) +{ + return 0; +} + +AVHWAccel ff_mpeg1_vdpau_hwaccel = { + .name = "mpeg1_vdpau", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG1VIDEO, + .pix_fmt = PIX_FMT_VDPAU_MPEG1, + .start_frame = vdpau_mpeg2_start_frame, + .end_frame = vdpau_mpeg2_end_frame, + .decode_slice = vdpau_mpeg2_decode_slice, +}; + +AVHWAccel ff_mpeg2_vdpau_hwaccel = { + .name = "mpeg2_vdpau", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG2VIDEO, + .pix_fmt = PIX_FMT_VDPAU_MPEG2, + .start_frame = vdpau_mpeg2_start_frame, + .end_frame = vdpau_mpeg2_end_frame, + .decode_slice = vdpau_mpeg2_decode_slice, +}; + /* @}*/ diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h index 6f1386067b..f3a547184d 100644 --- a/libavcodec/vdpau.h +++ b/libavcodec/vdpau.h @@ -4,20 +4,20 @@ * * Copyright (C) 2008 NVIDIA * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -31,7 +31,7 @@ * - VDPAU decoding * - VDPAU presentation * - * The VDPAU decoding module parses all headers using Libav + * The VDPAU decoding module parses all headers using FFmpeg * parsing mechanisms and uses VDPAU for the actual decoding. * * As per the current implementation, the actual decoding @@ -56,17 +56,24 @@ #define FF_VDPAU_STATE_USED_FOR_REFERENCE 2 /** - * @brief This structure is used as a callback between the Libav + * @brief This structure is used as a callback between the FFmpeg * decoder (vd_) and presentation (vo_) module. * This is used for defining a video frame containing surface, * picture parameter, bitstream information etc which are passed - * between the Libav decoder and its clients. + * between the FFmpeg decoder and its clients. */ struct vdpau_render_state { VdpVideoSurface surface; ///< Used as rendered surface, never changed. int state; ///< Holds FF_VDPAU_STATE_* values. + /** Describe size/location of the compressed video data. + Set to 0 when freeing bitstream_buffers. */ + int bitstream_buffers_allocated; + int bitstream_buffers_used; + /** The user is responsible for freeing this buffer using av_freep(). */ + VdpBitstreamBuffer *bitstream_buffers; + /** picture parameter information for all supported codecs */ union VdpPictureInfo { VdpPictureInfoH264 h264; @@ -74,13 +81,6 @@ struct vdpau_render_state { VdpPictureInfoVC1 vc1; VdpPictureInfoMPEG4Part2 mpeg4; } info; - - /** Describe size/location of the compressed video data. - Set to 0 when freeing bitstream_buffers. */ - int bitstream_buffers_allocated; - int bitstream_buffers_used; - /** The user is responsible for freeing this buffer using av_freep(). */ - VdpBitstreamBuffer *bitstream_buffers; }; /* @}*/ diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h index 673fd3349b..0a8d0b6b55 100644 --- a/libavcodec/vdpau_internal.h +++ b/libavcodec/vdpau_internal.h @@ -4,20 +4,20 @@ * * Copyright (C) 2008 NVIDIA * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/version.h b/libavcodec/version.h index 485b60e993..6d82bdb49d 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -1,19 +1,19 @@ /* * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -21,8 +21,8 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 54 -#define LIBAVCODEC_VERSION_MINOR 0 -#define LIBAVCODEC_VERSION_MICRO 0 +#define LIBAVCODEC_VERSION_MINOR 1 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ @@ -41,9 +41,19 @@ #ifndef FF_API_REQUEST_CHANNELS #define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 55) #endif +#ifndef FF_API_ALLOC_CONTEXT +#define FF_API_ALLOC_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 55) +#endif +#ifndef FF_API_AVCODEC_OPEN +#define FF_API_AVCODEC_OPEN (LIBAVCODEC_VERSION_MAJOR < 55) +#endif #ifndef FF_API_OLD_DECODE_AUDIO #define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55) #endif +#ifndef FF_API_OLD_TIMECODE +#define FF_API_OLD_TIMECODE (LIBAVCODEC_VERSION_MAJOR < 55) +#endif + #ifndef FF_API_OLD_ENCODE_AUDIO #define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55) #endif diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index 89b5c2bc6a..7006f61f2b 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -2,20 +2,20 @@ * Sierra VMD Audio & Video Decoders * Copyright (C) 2004 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -76,7 +76,7 @@ static void lz_unpack(const unsigned char *src, int src_len, unsigned char *dest, int dest_len) { const unsigned char *s; - unsigned int s_len; + const unsigned char *s_end; unsigned char *d; unsigned char *d_end; unsigned char queue[QUEUE_SIZE]; @@ -89,16 +89,17 @@ static void lz_unpack(const unsigned char *src, int src_len, unsigned int i, j; s = src; - s_len = src_len; + s_end = src + src_len; d = dest; d_end = d + dest_len; + + if (s_end - s < 8) + return; dataleft = AV_RL32(s); - s += 4; s_len -= 4; + s += 4; memset(queue, 0x20, QUEUE_SIZE); - if (s_len < 4) - return; if (AV_RL32(s) == 0x56781234) { - s += 4; s_len -= 4; + s += 4; qpos = 0x111; speclen = 0xF + 3; } else { @@ -106,42 +107,38 @@ static void lz_unpack(const unsigned char *src, int src_len, speclen = 100; /* no speclen */ } - while (dataleft > 0 && s_len > 0) { - tag = *s++; s_len--; + while (s_end - s > 0 && dataleft > 0) { + tag = *s++; if ((tag == 0xFF) && (dataleft > 8)) { - if (d + 8 > d_end || s_len < 8) + if (d_end - d < 8 || s_end - s < 8) return; for (i = 0; i < 8; i++) { queue[qpos++] = *d++ = *s++; qpos &= QUEUE_MASK; } - s_len -= 8; dataleft -= 8; } else { for (i = 0; i < 8; i++) { if (dataleft == 0) break; if (tag & 0x01) { - if (d + 1 > d_end || s_len < 1) + if (d_end - d < 1 || s_end - s < 1) return; queue[qpos++] = *d++ = *s++; qpos &= QUEUE_MASK; dataleft--; - s_len--; } else { - if (s_len < 2) + if (s_end - s < 2) return; chainofs = *s++; chainofs |= ((*s & 0xF0) << 4); chainlen = (*s++ & 0x0F) + 3; - s_len -= 2; if (chainlen == speclen) { - if (s_len < 1) + if (s_end - s < 1) return; chainlen = *s++ + 0xF + 3; - s_len--; } - if (d + chainlen > d_end) + if (d_end - d < chainlen) return; for (j = 0; j < chainlen; j++) { *d = queue[chainofs++ & QUEUE_MASK]; @@ -156,47 +153,45 @@ static void lz_unpack(const unsigned char *src, int src_len, } } -static int rle_unpack(const unsigned char *src, unsigned char *dest, - int src_count, int src_size, int dest_len) +static int rle_unpack(const unsigned char *src, int src_len, int src_count, + unsigned char *dest, int dest_len) { const unsigned char *ps; + const unsigned char *ps_end; unsigned char *pd; int i, l; unsigned char *dest_end = dest + dest_len; ps = src; + ps_end = src + src_len; pd = dest; if (src_count & 1) { - if (src_size < 1) + if (ps_end - ps < 1) return 0; *pd++ = *ps++; - src_size--; } src_count >>= 1; i = 0; do { - if (src_size < 1) + if (ps_end - ps < 1) break; l = *ps++; - src_size--; if (l & 0x80) { l = (l & 0x7F) * 2; - if (pd + l > dest_end || src_size < l) + if (dest_end - pd < l || ps_end - ps < l) return ps - src; memcpy(pd, ps, l); ps += l; - src_size -= l; pd += l; } else { - if (pd + i > dest_end || src_size < 2) + if (dest_end - pd < i || ps_end - ps < 2) return ps - src; for (i = 0; i < l; i++) { *pd++ = ps[0]; *pd++ = ps[1]; } ps += 2; - src_size -= 2; } i += l; } while (i < src_count); @@ -212,9 +207,10 @@ static void vmd_decode(VmdVideoContext *s) /* point to the start of the encoded data */ const unsigned char *p = s->buf + 16; + const unsigned char *p_end = s->buf + s->size; const unsigned char *pb; - unsigned int pb_size; + const unsigned char *pb_end; unsigned char meth; unsigned char *dp; /* pointer to current frame */ unsigned char *pp; /* pointer to previous frame */ @@ -260,29 +256,28 @@ static void vmd_decode(VmdVideoContext *s) /* check if there is a new palette */ if (s->buf[15] & 0x02) { + if (p_end - p < 2 + 3 * PALETTE_COUNT) + return; p += 2; palette32 = (unsigned int *)s->palette; for (i = 0; i < PALETTE_COUNT; i++) { r = *p++ * 4; g = *p++ * 4; b = *p++ * 4; - palette32[i] = (r << 16) | (g << 8) | (b); + palette32[i] = 0xFF << 24 | r << 16 | g << 8 | b; + palette32[i] |= palette32[i] >> 6 & 0x30303; } - s->size -= (256 * 3 + 2); } - if (s->size > 0) { + if (p < p_end) { /* originally UnpackFrame in VAG's code */ pb = p; - pb_size = s->buf + s->size - pb; - if (pb_size < 1) - return; - meth = *pb++; pb_size--; + pb_end = p_end; + meth = *pb++; if (meth & 0x80) { - lz_unpack(pb, pb_size, - s->unpack_buffer, s->unpack_buffer_size); + lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size); meth &= 0x7F; pb = s->unpack_buffer; - pb_size = s->unpack_buffer_size; + pb_end = s->unpack_buffer + s->unpack_buffer_size; } dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; @@ -292,17 +287,15 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_size < 1) + if (pb_end - pb < 1) return; len = *pb++; - pb_size--; if (len & 0x80) { len = (len & 0x7F) + 1; - if (ofs + len > frame_width || pb_size < len) + if (ofs + len > frame_width || pb_end - pb < len) return; memcpy(&dp[ofs], pb, len); pb += len; - pb_size -= len; ofs += len; } else { /* interframe pixel copy */ @@ -324,11 +317,10 @@ static void vmd_decode(VmdVideoContext *s) case 2: for (i = 0; i < frame_height; i++) { - if (pb_size < frame_width) + if (pb_end -pb < frame_width) return; memcpy(dp, pb, frame_width); pb += frame_width; - pb_size -= frame_width; dp += s->frame.linesize[0]; pp += s->prev_frame.linesize[0]; } @@ -338,23 +330,21 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_size < 1) + if (pb_end - pb < 1) return; len = *pb++; - pb_size--; if (len & 0x80) { len = (len & 0x7F) + 1; - if (pb_size < 1) + if (pb_end - pb < 1) return; if (*pb++ == 0xFF) - len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs); + len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs); else { - if (pb_size < len) - return; + if (pb_end - pb < len) + return; memcpy(&dp[ofs], pb, len); } pb += len; - pb_size -= 1 + len; ofs += len; } else { /* interframe pixel copy */ @@ -412,6 +402,9 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) palette32[i] = (r << 16) | (g << 8) | (b); } + avcodec_get_frame_defaults(&s->frame); + avcodec_get_frame_defaults(&s->prev_frame); + return 0; } @@ -429,7 +422,7 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, if (buf_size < 16) return buf_size; - s->frame.reference = 1; + s->frame.reference = 3; if (avctx->get_buffer(avctx, &s->frame)) { av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n"); return -1; @@ -625,7 +618,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, /* decode audio chunks */ if (audio_chunks > 0) { buf_end = buf + buf_size; - while (buf < buf_end) { + while ( buf_end - buf >= s->chunk_size) { if (s->out_bps == 2) { decode_audio_s16(output_samples_s16, buf, s->chunk_size, avctx->channels); diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c index 8cc78fa4c0..21141fa052 100644 --- a/libavcodec/vmnc.c +++ b/libavcodec/vmnc.c @@ -2,20 +2,20 @@ * VMware Screen Codec (VMnc) decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -293,7 +293,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac const uint8_t *src = buf; int dx, dy, w, h, depth, enc, chunks, res, size_left; - c->pic.reference = 1; + c->pic.reference = 3; c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if(avctx->reget_buffer(avctx, &c->pic) < 0){ av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); @@ -470,6 +470,7 @@ static av_cold int decode_init(AVCodecContext *avctx) c->bpp = avctx->bits_per_coded_sample; c->bpp2 = c->bpp/8; + avcodec_get_frame_defaults(&c->pic); switch(c->bpp){ case 8: diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c index 52ded8b0a8..fac8d0b2cd 100644 --- a/libavcodec/vorbis.c +++ b/libavcodec/vorbis.c @@ -1,18 +1,22 @@ -/* - * This file is part of Libav. +/** + * @file + * Common code for Vorbis I encoder and decoder + * @author Denes Balatoni ( dbalatoni programozo hu ) + * + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vorbis.h b/libavcodec/vorbis.h index a55523f17e..cad080ef3a 100644 --- a/libavcodec/vorbis.h +++ b/libavcodec/vorbis.h @@ -1,20 +1,20 @@ /* * copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vorbis_data.c b/libavcodec/vorbis_data.c index bd27b82d4a..aab06b7453 100644 --- a/libavcodec/vorbis_data.c +++ b/libavcodec/vorbis_data.c @@ -1,20 +1,20 @@ /* * copyright (c) 2005 Denes Balatoni ( dbalatoni programozo hu ) * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vorbis_enc_data.h b/libavcodec/vorbis_enc_data.h index a1e743ebe5..a51aaec978 100644 --- a/libavcodec/vorbis_enc_data.h +++ b/libavcodec/vorbis_enc_data.h @@ -1,20 +1,20 @@ /* * copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -492,13 +492,13 @@ static const struct { int dim; int subclass; int masterbook; - const int *nbooks; + const int nbooks[4]; } floor_classes[] = { - { 3, 0, 0, (const int[]){ 4 } }, - { 4, 1, 0, (const int[]){ 5, 6 } }, - { 3, 1, 1, (const int[]){ 7, 8 } }, - { 4, 2, 2, (const int[]){ -1, 9, 10, 11 } }, - { 3, 2, 3, (const int[]){ -1, 12, 13, 14 } }, + { 3, 0, 0, { 4 } }, + { 4, 1, 0, { 5, 6 } }, + { 3, 1, 1, { 7, 8 } }, + { 4, 2, 2, { -1, 9, 10, 11 } }, + { 3, 2, 3, { -1, 12, 13, 14 } }, }; #endif /* AVCODEC_VORBIS_ENC_DATA_H */ diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index aa4bdff93e..f71d606dad 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1,18 +1,22 @@ -/* - * This file is part of Libav. +/** + * @file + * Vorbis I decoder + * @author Denes Balatoni ( dbalatoni programozo hu ) + * + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -575,6 +579,14 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) // 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); + + for (j=1; j<floor_setup->data.t1.x_list_dim; j++) { + if ( floor_setup->data.t1.list[ floor_setup->data.t1.list[j-1].sort ].x + == floor_setup->data.t1.list[ floor_setup->data.t1.list[j ].sort ].x) { + av_log(vc->avccontext, AV_LOG_ERROR, "Non unique x values in floor type 1\n"); + return AVERROR_INVALIDDATA; + } + } } else if (floor_setup->floor_type == 0) { unsigned max_codebook_dim = 0; @@ -930,12 +942,12 @@ static int vorbis_parse_id_hdr(vorbis_context *vc) 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 AVERROR_INVALIDDATA; } + vc->blocksize[0] = (1 << bl0); + vc->blocksize[1] = (1 << bl1); vc->win[0] = ff_vorbis_vwin[bl0 - 6]; vc->win[1] = ff_vorbis_vwin[bl1 - 6]; @@ -1159,7 +1171,7 @@ static int vorbis_floor1_decode(vorbis_context *vc, uint16_t floor1_Y[258]; uint16_t floor1_Y_final[258]; int floor1_flag[258]; - unsigned class, cdim, cbits, csub, cval, offset, i, j; + unsigned partition_class, cdim, cbits, csub, cval, offset, i, j; int book, adx, ady, dy, off, predicted, err; @@ -1175,20 +1187,20 @@ static int vorbis_floor1_decode(vorbis_context *vc, offset = 2; for (i = 0; i < vf->partitions; ++i) { - class = vf->partition_class[i]; - cdim = vf->class_dimensions[class]; - cbits = vf->class_subclasses[class]; + partition_class = vf->partition_class[i]; + cdim = vf->class_dimensions[partition_class]; + cbits = vf->class_subclasses[partition_class]; csub = (1 << cbits) - 1; cval = 0; av_dlog(NULL, "Cbits %u\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); + cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[partition_class]].vlc.table, + vc->codebooks[vf->class_masterbook[partition_class]].nb_bits, 3); for (j = 0; j < cdim; ++j) { - book = vf->subclass_books[class][cval & csub]; + book = vf->subclass_books[partition_class][cval & csub]; av_dlog(NULL, "book %d Cbits %u cval %u bits:%d\n", book, cbits, cval, get_bits_count(gb)); diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index 00fe402d3e..80d722db4c 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -1,20 +1,20 @@ /* * copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -957,7 +957,7 @@ static av_cold int vorbis_encode_init(AVCodecContext *avccontext) vorbis_enc_context *venc = avccontext->priv_data; if (avccontext->channels != 2) { - av_log(avccontext, AV_LOG_ERROR, "Current Libav Vorbis encoder only supports 2 channels.\n"); + av_log(avccontext, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n"); return -1; } diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 602b5fa7a1..b5daafcefb 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2003-2004 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1572,10 +1572,7 @@ static void render_slice(Vp3DecodeContext *s, int slice) /* invert DCT and place (or add) in final output */ if (s->all_fragments[i].coding_method == MODE_INTRA) { - int index; - index = vp3_dequant(s, s->all_fragments + i, plane, 0, block); - if (index > 63) - continue; + vp3_dequant(s, s->all_fragments + i, plane, 0, block); if(s->avctx->idct_algo!=FF_IDCT_VP3) block[0] += 128<<3; s->dsp.idct_put( @@ -1583,10 +1580,7 @@ static void render_slice(Vp3DecodeContext *s, int slice) stride, block); } else { - int index = vp3_dequant(s, s->all_fragments + i, plane, 1, block); - if (index > 63) - continue; - if (index > 0) { + if (vp3_dequant(s, s->all_fragments + i, plane, 1, block)) { s->dsp.idct_add( output_plane + first_pixel, stride, @@ -1865,7 +1859,7 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * ||s->width != s1->width ||s->height!= s1->height) { if (s != s1) - copy_fields(s, s1, golden_frame, current_frame); + copy_fields(s, s1, golden_frame, keyframe); return -1; } @@ -1959,6 +1953,7 @@ static int vp3_decode_frame(AVCodecContext *avctx, s->current_frame.reference = 3; s->current_frame.pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + s->current_frame.key_frame = s->keyframe; if (ff_thread_get_buffer(avctx, &s->current_frame) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); goto error; diff --git a/libavcodec/vp3_parser.c b/libavcodec/vp3_parser.c index 1d70408cc7..c2e8518c55 100644 --- a/libavcodec/vp3_parser.c +++ b/libavcodec/vp3_parser.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2008 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp3data.h b/libavcodec/vp3data.h index 54d5a6c576..904ec6abf5 100644 --- a/libavcodec/vp3data.h +++ b/libavcodec/vp3data.h @@ -1,20 +1,20 @@ /* * copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp3dsp.c b/libavcodec/vp3dsp.c index baa22a5519..94efa3b1d2 100644 --- a/libavcodec/vp3dsp.c +++ b/libavcodec/vp3dsp.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2004 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp5.c b/libavcodec/vp5.c index 56f667cb63..23d0acc631 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp56.c b/libavcodec/vp56.c index 3b2ac95837..cca3e207b2 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -529,7 +529,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, } if (!is_alpha) { - p->reference = 1; + p->reference = 3; if (avctx->get_buffer(avctx, p) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; @@ -672,8 +672,10 @@ av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha) ff_vp56dsp_init(&s->vp56dsp, avctx->codec->id); ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct); - for (i=0; i<4; i++) + for (i=0; i<4; i++) { s->framep[i] = &s->frames[i]; + avcodec_get_frame_defaults(&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; diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index 0607e0d4ce..e135718d20 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -333,15 +333,13 @@ int vp56_rac_get_tree(VP56RangeCoder *c, return -tree->val; } -/** - * This is identical to vp8_rac_get_tree except for the possibility of starting - * on a node other than the root node, needed for coeff decode where this is - * used to save a bit after a 0 token (by disallowing EOB to immediately follow.) - */ -static av_always_inline -int vp8_rac_get_tree_with_offset(VP56RangeCoder *c, const int8_t (*tree)[2], - const uint8_t *probs, int i) +// how probabilities are associated with decisions is different I think +// well, the new scheme fits in the old but this way has one fewer branches per decision +static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2], + const uint8_t *probs) { + int i = 0; + do { i = tree[i][vp56_rac_get_prob(c, probs[i])]; } while (i > 0); @@ -349,15 +347,6 @@ int vp8_rac_get_tree_with_offset(VP56RangeCoder *c, const int8_t (*tree)[2], return -i; } -// how probabilities are associated with decisions is different I think -// well, the new scheme fits in the old but this way has one fewer branches per decision -static av_always_inline -int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2], - const uint8_t *probs) -{ - return vp8_rac_get_tree_with_offset(c, tree, probs, 0); -} - // DCTextra static av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob) { diff --git a/libavcodec/vp56data.c b/libavcodec/vp56data.c index aa1dcefece..a161f885d9 100644 --- a/libavcodec/vp56data.c +++ b/libavcodec/vp56data.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp56data.h b/libavcodec/vp56data.h index b1f27102ae..cb9cf95998 100644 --- a/libavcodec/vp56data.h +++ b/libavcodec/vp56data.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp56dsp.c b/libavcodec/vp56dsp.c index 7b4a771676..c629343a8b 100644 --- a/libavcodec/vp56dsp.c +++ b/libavcodec/vp56dsp.c @@ -2,20 +2,20 @@ * Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org> * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp56dsp.h b/libavcodec/vp56dsp.h index 3bd6d27068..74a9cb5309 100644 --- a/libavcodec/vp56dsp.h +++ b/libavcodec/vp56dsp.h @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Mans Rullgard <mans@mansr.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp56rac.c b/libavcodec/vp56rac.c index c009cadb94..f11531de24 100644 --- a/libavcodec/vp56rac.c +++ b/libavcodec/vp56rac.c @@ -2,20 +2,20 @@ * VP5/6/8 decoder * Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp5data.h b/libavcodec/vp5data.h index b11b99d9a9..e16ff2da4b 100644 --- a/libavcodec/vp5data.h +++ b/libavcodec/vp5data.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp6.c b/libavcodec/vp6.c index 9433983be3..84876b7146 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp6data.h b/libavcodec/vp6data.h index 9a11f89bf5..3ebfd0e252 100644 --- a/libavcodec/vp6data.h +++ b/libavcodec/vp6data.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp6dsp.c b/libavcodec/vp6dsp.c index 54a96ed13a..67c6be07de 100644 --- a/libavcodec/vp6dsp.c +++ b/libavcodec/vp6dsp.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp8.c b/libavcodec/vp8.c index 7cf18c07cd..4728393d10 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -5,20 +5,20 @@ * Copyright (C) 2010 Ronald S. Bultje * Copyright (C) 2010 Jason Garrett-Glaser * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -639,9 +639,10 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, uint8_ { VP56RangeCoder *c = &s->c; - if (s->segmentation.update_map) - *segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid); - else + if (s->segmentation.update_map) { + int bit = vp56_rac_get_prob(c, s->prob->segmentid[0]); + *segment = vp56_rac_get_prob(c, s->prob->segmentid[1+bit]) + 2*bit; + } else *segment = ref ? *ref : *segment; s->segment = *segment; diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h index a738cb76e0..5d2a3b773d 100644 --- a/libavcodec/vp8.h +++ b/libavcodec/vp8.h @@ -5,20 +5,20 @@ * Copyright (C) 2010 Ronald S. Bultje * Copyright (C) 2010 Jason Garrett-Glaser * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp8_parser.c b/libavcodec/vp8_parser.c index e6d4151bb5..6e154ded25 100644 --- a/libavcodec/vp8_parser.c +++ b/libavcodec/vp8_parser.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2008 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp8data.h b/libavcodec/vp8data.h index a48b0f6f9b..0ea24d7ed8 100644 --- a/libavcodec/vp8data.h +++ b/libavcodec/vp8data.h @@ -2,20 +2,20 @@ * Copyright (C) 2010 David Conrad * Copyright (C) 2010 Ronald S. Bultje * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp8dsp.c b/libavcodec/vp8dsp.c index 89c3453efc..ce90675d87 100644 --- a/libavcodec/vp8dsp.c +++ b/libavcodec/vp8dsp.c @@ -2,20 +2,20 @@ * Copyright (C) 2010 David Conrad * Copyright (C) 2010 Ronald S. Bultje * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vp8dsp.h b/libavcodec/vp8dsp.h index 5429e98c2a..987fa59a72 100644 --- a/libavcodec/vp8dsp.h +++ b/libavcodec/vp8dsp.h @@ -2,20 +2,20 @@ * Copyright (C) 2010 David Conrad * Copyright (C) 2010 Ronald S. Bultje * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index 7a6308aeb1..ae99c6d9c1 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -2,20 +2,20 @@ * Westwood Studios VQA Video Decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -138,6 +138,10 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) /* load up the VQA parameters from the header */ vqa_header = (unsigned char *)s->avctx->extradata; s->vqa_version = vqa_header[0]; + if (s->vqa_version < 1 || s->vqa_version > 3) { + av_log(s->avctx, AV_LOG_ERROR, " VQA video: unsupported version %d\n", s->vqa_version); + return -1; + } s->width = AV_RL16(&vqa_header[6]); s->height = AV_RL16(&vqa_header[8]); if(av_image_check_size(s->width, s->height, 0, avctx)){ @@ -179,6 +183,7 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) (s->height / s->vector_height) * 2; s->decode_buffer = av_malloc(s->decode_buffer_size); + avcodec_get_frame_defaults(&s->frame); s->frame.data[0] = NULL; return 0; @@ -225,6 +230,8 @@ static void decode_format80(const unsigned char *src, int src_size, src_index += 2; av_dlog(NULL, "(1) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); + if (src_pos + count > dest_size) + return; for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; dest_index += count; @@ -247,6 +254,8 @@ static void decode_format80(const unsigned char *src, int src_size, src_index += 2; av_dlog(NULL, "(3) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); + if (src_pos + count > dest_size) + return; for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; dest_index += count; @@ -267,6 +276,8 @@ static void decode_format80(const unsigned char *src, int src_size, src_index += 2; av_dlog(NULL, "(5) copy %X bytes from relpos %X\n", count, src_pos); CHECK_COUNT(); + if (dest_index < src_pos) + return; for (i = 0; i < count; i++) dest[dest_index + i] = dest[dest_index - src_pos + i]; dest_index += count; @@ -311,10 +322,17 @@ static void vqa_decode_chunk(VqaContext *s) int hibytes = s->decode_buffer_size / 2; /* first, traverse through the frame and find the subchunks */ - while (index < s->size) { + while (index + CHUNK_PREAMBLE_SIZE <= s->size) { + unsigned next_index; chunk_type = AV_RB32(&s->buf[index]); chunk_size = AV_RB32(&s->buf[index + 4]); + byte_skip = chunk_size & 0x01; + next_index = index + CHUNK_PREAMBLE_SIZE + chunk_size + byte_skip; + if (next_index > s->size) { + av_log(s->avctx, AV_LOG_ERROR, "Dropping incomplete chunk\n"); + break; + } switch (chunk_type) { @@ -355,9 +373,7 @@ static void vqa_decode_chunk(VqaContext *s) chunk_type); break; } - - byte_skip = chunk_size & 0x01; - index += (CHUNK_PREAMBLE_SIZE + chunk_size + byte_skip); + index = next_index; } /* next, deal with the palette */ @@ -391,7 +407,8 @@ static void vqa_decode_chunk(VqaContext *s) r = s->buf[cpl0_chunk++] * 4; g = s->buf[cpl0_chunk++] * 4; b = s->buf[cpl0_chunk++] * 4; - s->palette[i] = (r << 16) | (g << 8) | (b); + s->palette[i] = 0xFF << 24 | r << 16 | g << 8 | b; + s->palette[i] |= s->palette[i] >> 6 & 0x30303; } } diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 1098873d7c..11c90b74e6 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -2,20 +2,20 @@ * WavPack lossless audio decoder * Copyright (c) 2006,2011 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -112,8 +112,7 @@ typedef struct WavpackFrameContext { int extra_bits; int and, or, shift; int post_shift; - int hybrid, hybrid_bitrate; - int hybrid_maxclip, hybrid_minclip; + int hybrid, hybrid_bitrate, hybrid_maxclip; int float_flag; int float_shift; int float_max_exp; @@ -413,10 +412,10 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, } bit = (S & s->and) | s->or; - bit = ((S + bit) << s->shift) - bit; + bit = (((S + bit) << s->shift) - bit); if (s->hybrid) - bit = av_clip(bit, s->hybrid_minclip, s->hybrid_maxclip); + bit = av_clip(bit, -s->hybrid_maxclip - 1, s->hybrid_maxclip); return bit << s->post_shift; } @@ -764,7 +763,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, const uint8_t *orig_buf = buf; const uint8_t *buf_end = buf + buf_size; int i, j, id, size, ssize, weights, t; - int bpp, chan, chmask, orig_bpp; + int bpp, chan, chmask; if (buf_size == 0) { *got_frame_ptr = 0; @@ -800,16 +799,15 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->frame_flags = AV_RL32(buf); buf += 4; bpp = av_get_bytes_per_sample(avctx->sample_fmt); samples = (uint8_t*)samples + bpp * wc->ch_offset; - orig_bpp = ((s->frame_flags & 0x03) + 1) << 3; s->stereo = !(s->frame_flags & WV_MONO); s->stereo_in = (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo; s->joint = s->frame_flags & WV_JOINT_STEREO; s->hybrid = s->frame_flags & WV_HYBRID_MODE; s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE; - s->post_shift = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f); - s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1) >> s->post_shift; - s->hybrid_minclip = ((-1LL << (orig_bpp - 1))) >> s->post_shift; + s->hybrid_maxclip = (1LL << ((((s->frame_flags & 0x03) + 1) << 3) - 1)) - 1; + s->post_shift = 8 * (bpp - 1 - (s->frame_flags & 0x03)) + + ((s->frame_flags >> 13) & 0x1f); s->CRC = AV_RL32(buf); buf += 4; if (wc->mkv_mode) buf += 4; //skip block size; @@ -970,15 +968,6 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->and = 1; s->shift = buf[3]; } - /* original WavPack decoder forces 32-bit lossy sound to be treated - * as 24-bit one in order to have proper clipping - */ - if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) { - s->post_shift += 8; - s->shift -= 8; - s->hybrid_maxclip >>= 8; - s->hybrid_minclip >>= 8; - } buf += 4; break; case WP_ID_FLOATINFO: diff --git a/libavcodec/wma.c b/libavcodec/wma.c index 4eaf6fcc1e..562abf3812 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -1,21 +1,21 @@ /* * WMA compatible codec - * Copyright (c) 2002-2007 The Libav Project + * Copyright (c) 2002-2007 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/wma.h b/libavcodec/wma.h index 4acbf04bbf..6c8e944b79 100644 --- a/libavcodec/wma.h +++ b/libavcodec/wma.h @@ -1,21 +1,21 @@ /* * WMA compatible codec - * Copyright (c) 2002-2007 The Libav Project + * Copyright (c) 2002-2007 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/wmadata.h b/libavcodec/wmadata.h index 07a1afecc8..381f182fa0 100644 --- a/libavcodec/wmadata.h +++ b/libavcodec/wmadata.h @@ -1,21 +1,21 @@ /* * WMA compatible decoder - * copyright (c) 2002 The Libav Project + * copyright (c) 2002 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/wmadec.c b/libavcodec/wmadec.c index 41b2a8e7a7..7d7cc7f7bf 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -1,21 +1,21 @@ /* * WMA compatible decoder - * Copyright (c) 2002 The Libav Project + * Copyright (c) 2002 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -102,6 +102,18 @@ static int wma_decode_init(AVCodecContext * avctx) s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; + if(avctx->codec->id == CODEC_ID_WMAV2 && avctx->extradata_size >= 8){ + if(AV_RL16(extradata+4)==0xd && s->use_variable_block_len){ + av_log(avctx, AV_LOG_WARNING, "Disabling use_variable_block_len, if this fails contact the ffmpeg developers and send us the file\n"); + s->use_variable_block_len= 0; // this fixes issue1503 + } + } + + if(avctx->channels > MAX_CHANNELS){ + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels (%d)\n", avctx->channels); + return -1; + } + if(ff_wma_init(avctx, flags2)<0) return -1; @@ -484,6 +496,11 @@ static int wma_decode_block(WMACodecContext *s) s->block_len_bits = s->frame_len_bits; } + if (s->frame_len_bits - s->block_len_bits >= s->nb_block_sizes){ + av_log(s->avctx, AV_LOG_ERROR, "block_len_bits not initialized to a valid value\n"); + return -1; + } + /* now check if the block length is coherent with the frame length */ s->block_len = 1 << s->block_len_bits; if ((s->block_pos + s->block_len) > s->frame_len){ @@ -818,8 +835,9 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, return 0; } if (buf_size < s->block_align) - return 0; - buf_size = s->block_align; + return AVERROR(EINVAL); + if(s->block_align) + buf_size = s->block_align; init_get_bits(&s->gb, buf, buf_size*8); @@ -910,7 +928,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, *got_frame_ptr = 1; *(AVFrame *)data = s->frame; - return s->block_align; + return buf_size; fail: /* when error, we reset the bit reservoir */ s->last_superframe_len = 0; diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index c762a723b9..6ec6d7ce57 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -2,20 +2,20 @@ * WMA compatible encoder * Copyright (c) 2007 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c new file mode 100644 index 0000000000..e6d202af3b --- /dev/null +++ b/libavcodec/wmalosslessdec.c @@ -0,0 +1,1563 @@ +/* + * Wmall compatible decoder + * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion + * Copyright (c) 2008 - 2011 Sascha Sommer, Benjamin Larsson + * Copyright (c) 2011 Andreas Öman + * + * 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 + * @brief wmall decoder implementation + * Wmall is an MDCT based codec comparable to wma standard or AAC. + * The decoding therefore consists of the following steps: + * - bitstream decoding + * - reconstruction of per-channel data + * - rescaling and inverse quantization + * - IMDCT + * - windowing and overlapp-add + * + * The compressed wmall bitstream is split into individual packets. + * Every such packet contains one or more wma frames. + * The compressed frames may have a variable length and frames may + * cross packet boundaries. + * Common to all wmall frames is the number of samples that are stored in + * a frame. + * The number of samples and a few other decode flags are stored + * as extradata that has to be passed to the decoder. + * + * The wmall frames themselves are again split into a variable number of + * subframes. Every subframe contains the data for 2^N time domain samples + * where N varies between 7 and 12. + * + * Example wmall bitstream (in samples): + * + * || packet 0 || packet 1 || packet 2 packets + * --------------------------------------------------- + * || frame 0 || frame 1 || frame 2 || frames + * --------------------------------------------------- + * || | | || | | | || || subframes of channel 0 + * --------------------------------------------------- + * || | | || | | | || || subframes of channel 1 + * --------------------------------------------------- + * + * The frame layouts for the individual channels of a wma frame does not need + * to be the same. + * + * However, if the offsets and lengths of several subframes of a frame are the + * same, the subframes of the channels can be grouped. + * Every group may then use special coding techniques like M/S stereo coding + * to improve the compression ratio. These channel transformations do not + * need to be applied to a whole subframe. Instead, they can also work on + * individual scale factor bands (see below). + * The coefficients that carry the audio signal in the frequency domain + * are transmitted as huffman-coded vectors with 4, 2 and 1 elements. + * In addition to that, the encoder can switch to a runlevel coding scheme + * by transmitting subframe_length / 128 zero coefficients. + * + * Before the audio signal can be converted to the time domain, the + * coefficients have to be rescaled and inverse quantized. + * A subframe is therefore split into several scale factor bands that get + * scaled individually. + * Scale factors are submitted for every frame but they might be shared + * between the subframes of a channel. Scale factors are initially DPCM-coded. + * Once scale factors are shared, the differences are transmitted as runlevel + * codes. + * Every subframe length and offset combination in the frame layout shares a + * common quantization factor that can be adjusted for every channel by a + * modifier. + * After the inverse quantization, the coefficients get processed by an IMDCT. + * The resulting values are then windowed with a sine window and the first half + * of the values are added to the second half of the output from the previous + * subframe in order to reconstruct the output samples. + */ + +#include "avcodec.h" +#include "internal.h" +#include "get_bits.h" +#include "put_bits.h" +#include "dsputil.h" +#include "wma.h" + +/** current decoder limitations */ +#define WMALL_MAX_CHANNELS 8 ///< max number of handled channels +#define MAX_SUBFRAMES 32 ///< max number of subframes per channel +#define MAX_BANDS 29 ///< max number of scale factor bands +#define MAX_FRAMESIZE 32768 ///< maximum compressed frame size + +#define WMALL_BLOCK_MIN_BITS 6 ///< log2 of min block size +#define WMALL_BLOCK_MAX_BITS 12 ///< log2 of max block size +#define WMALL_BLOCK_MAX_SIZE (1 << WMALL_BLOCK_MAX_BITS) ///< maximum block size +#define WMALL_BLOCK_SIZES (WMALL_BLOCK_MAX_BITS - WMALL_BLOCK_MIN_BITS + 1) ///< possible block sizes + + +#define VLCBITS 9 +#define SCALEVLCBITS 8 +#define VEC4MAXDEPTH ((HUFF_VEC4_MAXBITS+VLCBITS-1)/VLCBITS) +#define VEC2MAXDEPTH ((HUFF_VEC2_MAXBITS+VLCBITS-1)/VLCBITS) +#define VEC1MAXDEPTH ((HUFF_VEC1_MAXBITS+VLCBITS-1)/VLCBITS) +#define SCALEMAXDEPTH ((HUFF_SCALE_MAXBITS+SCALEVLCBITS-1)/SCALEVLCBITS) +#define SCALERLMAXDEPTH ((HUFF_SCALE_RL_MAXBITS+VLCBITS-1)/VLCBITS) + +static float sin64[33]; ///< sinus table for decorrelation + +/** + * @brief frame specific decoder context for a single channel + */ +typedef struct { + int16_t prev_block_len; ///< length of the previous block + uint8_t transmit_coefs; + uint8_t num_subframes; + uint16_t subframe_len[MAX_SUBFRAMES]; ///< subframe length in samples + uint16_t subframe_offset[MAX_SUBFRAMES]; ///< subframe positions in the current frame + uint8_t cur_subframe; ///< current subframe number + uint16_t decoded_samples; ///< number of already processed samples + uint8_t grouped; ///< channel is part of a group + int quant_step; ///< quantization step for the current subframe + int8_t reuse_sf; ///< share scale factors between subframes + int8_t scale_factor_step; ///< scaling step for the current subframe + int max_scale_factor; ///< maximum scale factor for the current subframe + int saved_scale_factors[2][MAX_BANDS]; ///< resampled and (previously) transmitted scale factor values + int8_t scale_factor_idx; ///< index for the transmitted scale factor values (used for resampling) + int* scale_factors; ///< pointer to the scale factor values used for decoding + uint8_t table_idx; ///< index in sf_offsets for the scale factor reference block + float* coeffs; ///< pointer to the subframe decode buffer + uint16_t num_vec_coeffs; ///< number of vector coded coefficients + DECLARE_ALIGNED(16, float, out)[WMALL_BLOCK_MAX_SIZE + WMALL_BLOCK_MAX_SIZE / 2]; ///< output buffer + int transient_counter; ///< number of transient samples from the beginning of transient zone +} WmallChannelCtx; + +/** + * @brief channel group for channel transformations + */ +typedef struct { + uint8_t num_channels; ///< number of channels in the group + int8_t transform; ///< transform on / off + int8_t transform_band[MAX_BANDS]; ///< controls if the transform is enabled for a certain band + float decorrelation_matrix[WMALL_MAX_CHANNELS*WMALL_MAX_CHANNELS]; + float* channel_data[WMALL_MAX_CHANNELS]; ///< transformation coefficients +} WmallChannelGrp; + +/** + * @brief main decoder context + */ +typedef struct WmallDecodeCtx { + /* generic decoder variables */ + AVCodecContext* avctx; ///< codec context for av_log + DSPContext dsp; ///< accelerated DSP functions + uint8_t frame_data[MAX_FRAMESIZE + + FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data + PutBitContext pb; ///< context for filling the frame_data buffer + FFTContext mdct_ctx[WMALL_BLOCK_SIZES]; ///< MDCT context per block size + DECLARE_ALIGNED(16, float, tmp)[WMALL_BLOCK_MAX_SIZE]; ///< IMDCT output buffer + float* windows[WMALL_BLOCK_SIZES]; ///< windows for the different block sizes + + /* frame size dependent frame information (set during initialization) */ + uint32_t decode_flags; ///< used compression features + uint8_t len_prefix; ///< frame is prefixed with its length + uint8_t dynamic_range_compression; ///< frame contains DRC data + uint8_t bits_per_sample; ///< integer audio sample size for the unscaled IMDCT output (used to scale to [-1.0, 1.0]) + uint16_t samples_per_frame; ///< number of samples to output + uint16_t log2_frame_size; + int8_t num_channels; ///< number of channels in the stream (same as AVCodecContext.num_channels) + int8_t lfe_channel; ///< lfe channel index + uint8_t max_num_subframes; + uint8_t subframe_len_bits; ///< number of bits used for the subframe length + uint8_t max_subframe_len_bit; ///< flag indicating that the subframe is of maximum size when the first subframe length bit is 1 + uint16_t min_samples_per_subframe; + int8_t num_sfb[WMALL_BLOCK_SIZES]; ///< scale factor bands per block size + int16_t sfb_offsets[WMALL_BLOCK_SIZES][MAX_BANDS]; ///< scale factor band offsets (multiples of 4) + int8_t sf_offsets[WMALL_BLOCK_SIZES][WMALL_BLOCK_SIZES][MAX_BANDS]; ///< scale factor resample matrix + int16_t subwoofer_cutoffs[WMALL_BLOCK_SIZES]; ///< subwoofer cutoff values + + /* packet decode state */ + GetBitContext pgb; ///< bitstream reader context for the packet + int next_packet_start; ///< start offset of the next wma packet in the demuxer packet + uint8_t packet_offset; ///< frame offset in the packet + uint8_t packet_sequence_number; ///< current packet number + int num_saved_bits; ///< saved number of bits + int frame_offset; ///< frame offset in the bit reservoir + int subframe_offset; ///< subframe offset in the bit reservoir + uint8_t packet_loss; ///< set in case of bitstream error + uint8_t packet_done; ///< set when a packet is fully decoded + + /* frame decode state */ + uint32_t frame_num; ///< current frame number (not used for decoding) + GetBitContext gb; ///< bitstream reader context + int buf_bit_size; ///< buffer size in bits + int16_t* samples_16; ///< current samplebuffer pointer (16-bit) + int16_t* samples_16_end; ///< maximum samplebuffer pointer + int *samples_32; ///< current samplebuffer pointer (24-bit) + int *samples_32_end; ///< maximum samplebuffer pointer + uint8_t drc_gain; ///< gain for the DRC tool + int8_t skip_frame; ///< skip output step + int8_t parsed_all_subframes; ///< all subframes decoded? + + /* subframe/block decode state */ + int16_t subframe_len; ///< current subframe length + int8_t channels_for_cur_subframe; ///< number of channels that contain the subframe + int8_t channel_indexes_for_cur_subframe[WMALL_MAX_CHANNELS]; + int8_t num_bands; ///< number of scale factor bands + int8_t transmit_num_vec_coeffs; ///< number of vector coded coefficients is part of the bitstream + int16_t* cur_sfb_offsets; ///< sfb offsets for the current block + uint8_t table_idx; ///< index for the num_sfb, sfb_offsets, sf_offsets and subwoofer_cutoffs tables + int8_t esc_len; ///< length of escaped coefficients + + uint8_t num_chgroups; ///< number of channel groups + WmallChannelGrp chgroup[WMALL_MAX_CHANNELS]; ///< channel group information + + WmallChannelCtx channel[WMALL_MAX_CHANNELS]; ///< per channel data + + // WMA lossless + + uint8_t do_arith_coding; + uint8_t do_ac_filter; + uint8_t do_inter_ch_decorr; + uint8_t do_mclms; + uint8_t do_lpc; + + int8_t acfilter_order; + int8_t acfilter_scaling; + int64_t acfilter_coeffs[16]; + int acfilter_prevvalues[2][16]; + + int8_t mclms_order; + int8_t mclms_scaling; + int16_t mclms_coeffs[128]; + int16_t mclms_coeffs_cur[4]; + int16_t mclms_prevvalues[64]; // FIXME: should be 32-bit / 16-bit depending on bit-depth + int16_t mclms_updates[64]; + int mclms_recent; + + int movave_scaling; + int quant_stepsize; + + struct { + int order; + int scaling; + int coefsend; + int bitsend; + int16_t coefs[256]; + int16_t lms_prevvalues[512]; // FIXME: see above + int16_t lms_updates[512]; // and here too + int recent; + } cdlms[2][9]; /* XXX: Here, 2 is the max. no. of channels allowed, + 9 is the maximum no. of filters per channel. + Question is, why 2 if WMALL_MAX_CHANNELS == 8 */ + + + int cdlms_ttl[2]; + + int bV3RTM; + + int is_channel_coded[2]; // XXX: same question as above applies here too (and below) + int update_speed[2]; + + int transient[2]; + int transient_pos[2]; + int seekable_tile; + + int ave_sum[2]; + + int channel_residues[2][2048]; + + + int lpc_coefs[2][40]; + int lpc_order; + int lpc_scaling; + int lpc_intbits; + + int channel_coeffs[2][2048]; // FIXME: should be 32-bit / 16-bit depending on bit-depth + +} WmallDecodeCtx; + + +#undef dprintf +#define dprintf(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__) + + +static int num_logged_tiles = 0; +static int num_logged_subframes = 0; +static int num_lms_update_call = 0; + +/** + *@brief helper function to print the most important members of the context + *@param s context + */ +static void av_cold dump_context(WmallDecodeCtx *s) +{ +#define PRINT(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %d\n", a, b); +#define PRINT_HEX(a, b) av_log(s->avctx, AV_LOG_DEBUG, " %s = %x\n", a, b); + + PRINT("ed sample bit depth", s->bits_per_sample); + PRINT_HEX("ed decode flags", s->decode_flags); + PRINT("samples per frame", s->samples_per_frame); + PRINT("log2 frame size", s->log2_frame_size); + PRINT("max num subframes", s->max_num_subframes); + PRINT("len prefix", s->len_prefix); + PRINT("num channels", s->num_channels); +} + +static void dump_int_buffer(uint8_t *buffer, int size, int length, int delimiter) +{ + int i; + + for (i=0 ; i<length ; i++) { + if (!(i%delimiter)) + av_log(0, 0, "\n[%d] ", i); + av_log(0, 0, "%d, ", *(int16_t *)(buffer + i * size)); + } + av_log(0, 0, "\n"); +} + +/** + *@brief Uninitialize the decoder and free all resources. + *@param avctx codec context + *@return 0 on success, < 0 otherwise + */ +static av_cold int decode_end(AVCodecContext *avctx) +{ + WmallDecodeCtx *s = avctx->priv_data; + int i; + + for (i = 0; i < WMALL_BLOCK_SIZES; i++) + ff_mdct_end(&s->mdct_ctx[i]); + + return 0; +} + +/** + *@brief Initialize the decoder. + *@param avctx codec context + *@return 0 on success, -1 otherwise + */ +static av_cold int decode_init(AVCodecContext *avctx) +{ + WmallDecodeCtx *s = avctx->priv_data; + uint8_t *edata_ptr = avctx->extradata; + unsigned int channel_mask; + int i; + int log2_max_num_subframes; + int num_possible_block_sizes; + + s->avctx = avctx; + dsputil_init(&s->dsp, avctx); + init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); + + if (avctx->extradata_size >= 18) { + s->decode_flags = AV_RL16(edata_ptr+14); + channel_mask = AV_RL32(edata_ptr+2); + s->bits_per_sample = AV_RL16(edata_ptr); + if (s->bits_per_sample == 16) + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + else if (s->bits_per_sample == 24) + avctx->sample_fmt = AV_SAMPLE_FMT_S32; + else { + av_log(avctx, AV_LOG_ERROR, "Unknown bit-depth: %d\n", + s->bits_per_sample); + return AVERROR_INVALIDDATA; + } + /** dump the extradata */ + for (i = 0; i < avctx->extradata_size; i++) + dprintf(avctx, "[%x] ", avctx->extradata[i]); + dprintf(avctx, "\n"); + + } else { + av_log_ask_for_sample(avctx, "Unknown extradata size\n"); + return AVERROR_INVALIDDATA; + } + + /** generic init */ + s->log2_frame_size = av_log2(avctx->block_align) + 4; + + /** frame info */ + s->skip_frame = 1; /* skip first frame */ + s->packet_loss = 1; + s->len_prefix = (s->decode_flags & 0x40); + + /** get frame len */ + s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate, + 3, s->decode_flags); + + /** init previous block len */ + for (i = 0; i < avctx->channels; i++) + s->channel[i].prev_block_len = s->samples_per_frame; + + /** subframe info */ + log2_max_num_subframes = ((s->decode_flags & 0x38) >> 3); + s->max_num_subframes = 1 << log2_max_num_subframes; + s->max_subframe_len_bit = 0; + s->subframe_len_bits = av_log2(log2_max_num_subframes) + 1; + + num_possible_block_sizes = log2_max_num_subframes + 1; + s->min_samples_per_subframe = s->samples_per_frame / s->max_num_subframes; + s->dynamic_range_compression = (s->decode_flags & 0x80); + + s->bV3RTM = s->decode_flags & 0x100; + + if (s->max_num_subframes > MAX_SUBFRAMES) { + av_log(avctx, AV_LOG_ERROR, "invalid number of subframes %i\n", + s->max_num_subframes); + return AVERROR_INVALIDDATA; + } + + s->num_channels = avctx->channels; + + /** extract lfe channel position */ + s->lfe_channel = -1; + + if (channel_mask & 8) { + unsigned int mask; + for (mask = 1; mask < 16; mask <<= 1) { + if (channel_mask & mask) + ++s->lfe_channel; + } + } + + if (s->num_channels < 0) { + av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->num_channels); + return AVERROR_INVALIDDATA; + } else if (s->num_channels > WMALL_MAX_CHANNELS) { + av_log_ask_for_sample(avctx, "unsupported number of channels\n"); + return AVERROR_PATCHWELCOME; + } + + avctx->channel_layout = channel_mask; + return 0; +} + +/** + *@brief Decode the subframe length. + *@param s context + *@param offset sample offset in the frame + *@return decoded subframe length on success, < 0 in case of an error + */ +static int decode_subframe_length(WmallDecodeCtx *s, int offset) +{ + int frame_len_ratio; + int subframe_len, len; + + /** no need to read from the bitstream when only one length is possible */ + if (offset == s->samples_per_frame - s->min_samples_per_subframe) + return s->min_samples_per_subframe; + + len = av_log2(s->max_num_subframes - 1) + 1; + frame_len_ratio = get_bits(&s->gb, len); + + subframe_len = s->min_samples_per_subframe * (frame_len_ratio + 1); + + /** sanity check the length */ + if (subframe_len < s->min_samples_per_subframe || + subframe_len > s->samples_per_frame) { + av_log(s->avctx, AV_LOG_ERROR, "broken frame: subframe_len %i\n", + subframe_len); + return AVERROR_INVALIDDATA; + } + return subframe_len; +} + +/** + *@brief Decode how the data in the frame is split into subframes. + * Every WMA frame contains the encoded data for a fixed number of + * samples per channel. The data for every channel might be split + * into several subframes. This function will reconstruct the list of + * subframes for every channel. + * + * If the subframes are not evenly split, the algorithm estimates the + * channels with the lowest number of total samples. + * Afterwards, for each of these channels a bit is read from the + * bitstream that indicates if the channel contains a subframe with the + * next subframe size that is going to be read from the bitstream or not. + * If a channel contains such a subframe, the subframe size gets added to + * the channel's subframe list. + * The algorithm repeats these steps until the frame is properly divided + * between the individual channels. + * + *@param s context + *@return 0 on success, < 0 in case of an error + */ +static int decode_tilehdr(WmallDecodeCtx *s) +{ + uint16_t num_samples[WMALL_MAX_CHANNELS]; /**< sum of samples for all currently known subframes of a channel */ + uint8_t contains_subframe[WMALL_MAX_CHANNELS]; /**< flag indicating if a channel contains the current subframe */ + int channels_for_cur_subframe = s->num_channels; /**< number of channels that contain the current subframe */ + int fixed_channel_layout = 0; /**< flag indicating that all channels use the same subfra2me offsets and sizes */ + int min_channel_len = 0; /**< smallest sum of samples (channels with this length will be processed first) */ + int c; + + /* Should never consume more than 3073 bits (256 iterations for the + * while loop when always the minimum amount of 128 samples is substracted + * from missing samples in the 8 channel case). + * 1 + BLOCK_MAX_SIZE * MAX_CHANNELS / BLOCK_MIN_SIZE * (MAX_CHANNELS + 4) + */ + + /** reset tiling information */ + for (c = 0; c < s->num_channels; c++) + s->channel[c].num_subframes = 0; + + memset(num_samples, 0, sizeof(num_samples)); + + if (s->max_num_subframes == 1 || get_bits1(&s->gb)) + fixed_channel_layout = 1; + + /** loop until the frame data is split between the subframes */ + do { + int subframe_len; + + /** check which channels contain the subframe */ + for (c = 0; c < s->num_channels; c++) { + if (num_samples[c] == min_channel_len) { + if (fixed_channel_layout || channels_for_cur_subframe == 1 || + (min_channel_len == s->samples_per_frame - s->min_samples_per_subframe)) { + contains_subframe[c] = 1; + } + else { + contains_subframe[c] = get_bits1(&s->gb); + } + } else + contains_subframe[c] = 0; + } + + /** get subframe length, subframe_len == 0 is not allowed */ + if ((subframe_len = decode_subframe_length(s, min_channel_len)) <= 0) + return AVERROR_INVALIDDATA; + /** add subframes to the individual channels and find new min_channel_len */ + min_channel_len += subframe_len; + for (c = 0; c < s->num_channels; c++) { + WmallChannelCtx* chan = &s->channel[c]; + + if (contains_subframe[c]) { + if (chan->num_subframes >= MAX_SUBFRAMES) { + av_log(s->avctx, AV_LOG_ERROR, + "broken frame: num subframes > 31\n"); + return AVERROR_INVALIDDATA; + } + chan->subframe_len[chan->num_subframes] = subframe_len; + num_samples[c] += subframe_len; + ++chan->num_subframes; + if (num_samples[c] > s->samples_per_frame) { + av_log(s->avctx, AV_LOG_ERROR, "broken frame: " + "channel len(%d) > samples_per_frame(%d)\n", + num_samples[c], s->samples_per_frame); + return AVERROR_INVALIDDATA; + } + } else if (num_samples[c] <= min_channel_len) { + if (num_samples[c] < min_channel_len) { + channels_for_cur_subframe = 0; + min_channel_len = num_samples[c]; + } + ++channels_for_cur_subframe; + } + } + } while (min_channel_len < s->samples_per_frame); + + for (c = 0; c < s->num_channels; c++) { + int i; + int offset = 0; + for (i = 0; i < s->channel[c].num_subframes; i++) { + s->channel[c].subframe_offset[i] = offset; + offset += s->channel[c].subframe_len[i]; + } + } + + return 0; +} + + +static int my_log2(unsigned int i) +{ + unsigned int iLog2 = 0; + while ((i >> iLog2) > 1) + iLog2++; + return iLog2; +} + + +/** + * + */ +static void decode_ac_filter(WmallDecodeCtx *s) +{ + int i; + s->acfilter_order = get_bits(&s->gb, 4) + 1; + s->acfilter_scaling = get_bits(&s->gb, 4); + + for(i = 0; i < s->acfilter_order; i++) { + s->acfilter_coeffs[i] = get_bits(&s->gb, s->acfilter_scaling) + 1; + } +} + + +/** + * + */ +static void decode_mclms(WmallDecodeCtx *s) +{ + s->mclms_order = (get_bits(&s->gb, 4) + 1) * 2; + s->mclms_scaling = get_bits(&s->gb, 4); + if(get_bits1(&s->gb)) { + // mclms_send_coef + int i; + int send_coef_bits; + int cbits = av_log2(s->mclms_scaling + 1); + assert(cbits == my_log2(s->mclms_scaling + 1)); + if(1 << cbits < s->mclms_scaling + 1) + cbits++; + + send_coef_bits = (cbits ? get_bits(&s->gb, cbits) : 0) + 2; + + for(i = 0; i < s->mclms_order * s->num_channels * s->num_channels; i++) { + s->mclms_coeffs[i] = get_bits(&s->gb, send_coef_bits); + } + + for(i = 0; i < s->num_channels; i++) { + int c; + for(c = 0; c < i; c++) { + s->mclms_coeffs_cur[i * s->num_channels + c] = get_bits(&s->gb, send_coef_bits); + } + } + } +} + + +/** + * + */ +static void decode_cdlms(WmallDecodeCtx *s) +{ + int c, i; + int cdlms_send_coef = get_bits1(&s->gb); + + for(c = 0; c < s->num_channels; c++) { + s->cdlms_ttl[c] = get_bits(&s->gb, 3) + 1; + for(i = 0; i < s->cdlms_ttl[c]; i++) { + s->cdlms[c][i].order = (get_bits(&s->gb, 7) + 1) * 8; + } + + for(i = 0; i < s->cdlms_ttl[c]; i++) { + s->cdlms[c][i].scaling = get_bits(&s->gb, 4); + } + + if(cdlms_send_coef) { + for(i = 0; i < s->cdlms_ttl[c]; i++) { + int cbits, shift_l, shift_r, j; + cbits = av_log2(s->cdlms[c][i].order); + if(1 << cbits < s->cdlms[c][i].order) + cbits++; + s->cdlms[c][i].coefsend = get_bits(&s->gb, cbits) + 1; + + cbits = av_log2(s->cdlms[c][i].scaling + 1); + if(1 << cbits < s->cdlms[c][i].scaling + 1) + cbits++; + + s->cdlms[c][i].bitsend = get_bits(&s->gb, cbits) + 2; + shift_l = 32 - s->cdlms[c][i].bitsend; + shift_r = 32 - 2 - s->cdlms[c][i].scaling; + for(j = 0; j < s->cdlms[c][i].coefsend; j++) { + s->cdlms[c][i].coefs[j] = + (get_bits(&s->gb, s->cdlms[c][i].bitsend) << shift_l) >> shift_r; + } + } + } + } +} + +/** + * + */ +static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size) +{ + int i = 0; + unsigned int ave_mean; + s->transient[ch] = get_bits1(&s->gb); + if(s->transient[ch]) { + s->transient_pos[ch] = get_bits(&s->gb, av_log2(tile_size)); + if (s->transient_pos[ch]) + s->transient[ch] = 0; + s->channel[ch].transient_counter = + FFMAX(s->channel[ch].transient_counter, s->samples_per_frame / 2); + } else if (s->channel[ch].transient_counter) + s->transient[ch] = 1; + + if(s->seekable_tile) { + ave_mean = get_bits(&s->gb, s->bits_per_sample); + s->ave_sum[ch] = ave_mean << (s->movave_scaling + 1); +// s->ave_sum[ch] *= 2; + } + + if(s->seekable_tile) { + if(s->do_inter_ch_decorr) + s->channel_residues[ch][0] = get_sbits(&s->gb, s->bits_per_sample + 1); + else + s->channel_residues[ch][0] = get_sbits(&s->gb, s->bits_per_sample); + i++; + } + //av_log(0, 0, "%8d: ", num_logged_tiles++); + for(; i < tile_size; i++) { + int quo = 0, rem, rem_bits, residue; + while(get_bits1(&s->gb)) + quo++; + if(quo >= 32) + quo += get_bits_long(&s->gb, get_bits(&s->gb, 5) + 1); + + ave_mean = (s->ave_sum[ch] + (1 << s->movave_scaling)) >> (s->movave_scaling + 1); + rem_bits = av_ceil_log2(ave_mean); + rem = rem_bits ? get_bits(&s->gb, rem_bits) : 0; + residue = (quo << rem_bits) + rem; + + s->ave_sum[ch] = residue + s->ave_sum[ch] - (s->ave_sum[ch] >> s->movave_scaling); + + if(residue & 1) + residue = -(residue >> 1) - 1; + else + residue = residue >> 1; + s->channel_residues[ch][i] = residue; + } + //dump_int_buffer(s->channel_residues[ch], 4, tile_size, 16); + + return 0; + +} + + +/** + * + */ +static void +decode_lpc(WmallDecodeCtx *s) +{ + int ch, i, cbits; + s->lpc_order = get_bits(&s->gb, 5) + 1; + s->lpc_scaling = get_bits(&s->gb, 4); + s->lpc_intbits = get_bits(&s->gb, 3) + 1; + cbits = s->lpc_scaling + s->lpc_intbits; + for(ch = 0; ch < s->num_channels; ch++) { + for(i = 0; i < s->lpc_order; i++) { + s->lpc_coefs[ch][i] = get_sbits(&s->gb, cbits); + } + } +} + + +static void clear_codec_buffers(WmallDecodeCtx *s) +{ + int ich, ilms; + + memset(s->acfilter_coeffs , 0, 16 * sizeof(int)); + memset(s->acfilter_prevvalues, 0, 16 * 2 * sizeof(int)); // may be wrong + memset(s->lpc_coefs , 0, 40 * 2 * sizeof(int)); + + memset(s->mclms_coeffs , 0, 128 * sizeof(int16_t)); + memset(s->mclms_coeffs_cur, 0, 4 * sizeof(int16_t)); + memset(s->mclms_prevvalues, 0, 64 * sizeof(int)); + memset(s->mclms_updates , 0, 64 * sizeof(int16_t)); + + for (ich = 0; ich < s->num_channels; ich++) { + for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++) { + memset(s->cdlms[ich][ilms].coefs , 0, 256 * sizeof(int16_t)); + memset(s->cdlms[ich][ilms].lms_prevvalues, 0, 512 * sizeof(int16_t)); + memset(s->cdlms[ich][ilms].lms_updates , 0, 512 * sizeof(int16_t)); + } + s->ave_sum[ich] = 0; + } +} + +/** + *@brief Resets filter parameters and transient area at new seekable tile + */ +static void reset_codec(WmallDecodeCtx *s) +{ + int ich, ilms; + s->mclms_recent = s->mclms_order * s->num_channels; + for (ich = 0; ich < s->num_channels; ich++) { + for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++) + s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order; + /* first sample of a seekable subframe is considered as the starting of + a transient area which is samples_per_frame samples long */ + s->channel[ich].transient_counter = s->samples_per_frame; + s->transient[ich] = 1; + s->transient_pos[ich] = 0; + } +} + + + +static void mclms_update(WmallDecodeCtx *s, int icoef, int *pred) +{ + int i, j, ich; + int pred_error; + int order = s->mclms_order; + int num_channels = s->num_channels; + int range = 1 << (s->bits_per_sample - 1); + int bps = s->bits_per_sample > 16 ? 4 : 2; // bytes per sample + + for (ich = 0; ich < num_channels; ich++) { + pred_error = s->channel_residues[ich][icoef] - pred[ich]; + if (pred_error > 0) { + for (i = 0; i < order * num_channels; i++) + s->mclms_coeffs[i + ich * order * num_channels] += + s->mclms_updates[s->mclms_recent + i]; + for (j = 0; j < ich; j++) { + if (s->channel_residues[j][icoef] > 0) + s->mclms_coeffs_cur[ich * num_channels + j] += 1; + else if (s->channel_residues[j][icoef] < 0) + s->mclms_coeffs_cur[ich * num_channels + j] -= 1; + } + } else if (pred_error < 0) { + for (i = 0; i < order * num_channels; i++) + s->mclms_coeffs[i + ich * order * num_channels] -= + s->mclms_updates[s->mclms_recent + i]; + for (j = 0; j < ich; j++) { + if (s->channel_residues[j][icoef] > 0) + s->mclms_coeffs_cur[ich * num_channels + j] -= 1; + else if (s->channel_residues[j][icoef] < 0) + s->mclms_coeffs_cur[ich * num_channels + j] += 1; + } + } + } + + for (ich = num_channels - 1; ich >= 0; ich--) { + s->mclms_recent--; + s->mclms_prevvalues[s->mclms_recent] = s->channel_residues[ich][icoef]; + if (s->channel_residues[ich][icoef] > range - 1) + s->mclms_prevvalues[s->mclms_recent] = range - 1; + else if (s->channel_residues[ich][icoef] < -range) + s->mclms_prevvalues[s->mclms_recent] = -range; + + s->mclms_updates[s->mclms_recent] = 0; + if (s->channel_residues[ich][icoef] > 0) + s->mclms_updates[s->mclms_recent] = 1; + else if (s->channel_residues[ich][icoef] < 0) + s->mclms_updates[s->mclms_recent] = -1; + } + + if (s->mclms_recent == 0) { + memcpy(&s->mclms_prevvalues[order * num_channels], + s->mclms_prevvalues, + bps * order * num_channels); + memcpy(&s->mclms_updates[order * num_channels], + s->mclms_updates, + bps * order * num_channels); + s->mclms_recent = num_channels * order; + } +} + +static void mclms_predict(WmallDecodeCtx *s, int icoef, int *pred) +{ + int ich, i; + int order = s->mclms_order; + int num_channels = s->num_channels; + + for (ich = 0; ich < num_channels; ich++) { + if (!s->is_channel_coded[ich]) + continue; + pred[ich] = 0; + for (i = 0; i < order * num_channels; i++) + pred[ich] += s->mclms_prevvalues[i + s->mclms_recent] * + s->mclms_coeffs[i + order * num_channels * ich]; + for (i = 0; i < ich; i++) + pred[ich] += s->channel_residues[i][icoef] * + s->mclms_coeffs_cur[i + num_channels * ich]; + pred[ich] += 1 << s->mclms_scaling - 1; + pred[ich] >>= s->mclms_scaling; + s->channel_residues[ich][icoef] += pred[ich]; + } +} + +static void revert_mclms(WmallDecodeCtx *s, int tile_size) +{ + int icoef, pred[s->num_channels]; + for (icoef = 0; icoef < tile_size; icoef++) { + mclms_predict(s, icoef, pred); + mclms_update(s, icoef, pred); + } +} + +static int lms_predict(WmallDecodeCtx *s, int ich, int ilms) +{ + int pred = 0; + int icoef; + int recent = s->cdlms[ich][ilms].recent; + + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + pred += s->cdlms[ich][ilms].coefs[icoef] * + s->cdlms[ich][ilms].lms_prevvalues[icoef + recent]; + + //pred += (1 << (s->cdlms[ich][ilms].scaling - 1)); + /* XXX: Table 29 has: + iPred >= cdlms[iCh][ilms].scaling; + seems to me like a missing > */ + //pred >>= s->cdlms[ich][ilms].scaling; + return pred; +} + +static void lms_update(WmallDecodeCtx *s, int ich, int ilms, int input, int residue) +{ + int icoef; + int recent = s->cdlms[ich][ilms].recent; + int range = 1 << s->bits_per_sample - 1; + int bps = s->bits_per_sample > 16 ? 4 : 2; // bytes per sample + + if (residue < 0) { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].coefs[icoef] -= + s->cdlms[ich][ilms].lms_updates[icoef + recent]; + } else if (residue > 0) { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].coefs[icoef] += + s->cdlms[ich][ilms].lms_updates[icoef + recent]; /* spec mistakenly + dropped the recent */ + } + + if (recent) + recent--; + else { + /* XXX: This memcpy()s will probably fail if a fixed 32-bit buffer is used. + follow kshishkov's suggestion of using a union. */ + memcpy(&s->cdlms[ich][ilms].lms_prevvalues[s->cdlms[ich][ilms].order], + s->cdlms[ich][ilms].lms_prevvalues, + bps * s->cdlms[ich][ilms].order); + memcpy(&s->cdlms[ich][ilms].lms_updates[s->cdlms[ich][ilms].order], + s->cdlms[ich][ilms].lms_updates, + bps * s->cdlms[ich][ilms].order); + recent = s->cdlms[ich][ilms].order - 1; + } + + s->cdlms[ich][ilms].lms_prevvalues[recent] = av_clip(input, -range, range - 1); + if (!input) + s->cdlms[ich][ilms].lms_updates[recent] = 0; + else if (input < 0) + s->cdlms[ich][ilms].lms_updates[recent] = -s->update_speed[ich]; + else + s->cdlms[ich][ilms].lms_updates[recent] = s->update_speed[ich]; + + /* XXX: spec says: + cdlms[iCh][ilms].updates[iRecent + cdlms[iCh][ilms].order >> 4] >>= 2; + lms_updates[iCh][ilms][iRecent + cdlms[iCh][ilms].order >> 3] >>= 1; + + Questions is - are cdlms[iCh][ilms].updates[] and lms_updates[][][] two + seperate buffers? Here I've assumed that the two are same which makes + more sense to me. + */ + s->cdlms[ich][ilms].lms_updates[recent + (s->cdlms[ich][ilms].order >> 4)] >>= 2; + s->cdlms[ich][ilms].lms_updates[recent + (s->cdlms[ich][ilms].order >> 3)] >>= 1; + s->cdlms[ich][ilms].recent = recent; +} + +static void use_high_update_speed(WmallDecodeCtx *s, int ich) +{ + int ilms, recent, icoef; + for (ilms = s->cdlms_ttl[ich] - 1; ilms >= 0; ilms--) { + recent = s->cdlms[ich][ilms].recent; + if (s->update_speed[ich] == 16) + continue; + if (s->bV3RTM) { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].lms_updates[icoef + recent] *= 2; + } else { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].lms_updates[icoef] *= 2; + } + } + s->update_speed[ich] = 16; +} + +static void use_normal_update_speed(WmallDecodeCtx *s, int ich) +{ + int ilms, recent, icoef; + for (ilms = s->cdlms_ttl[ich] - 1; ilms >= 0; ilms--) { + recent = s->cdlms[ich][ilms].recent; + if (s->update_speed[ich] == 8) + continue; + if (s->bV3RTM) { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].lms_updates[icoef + recent] /= 2; + } else { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].lms_updates[icoef] /= 2; + } + } + s->update_speed[ich] = 8; +} + +static void revert_cdlms(WmallDecodeCtx *s, int ch, int coef_begin, int coef_end) +{ + int icoef; + int pred; + int ilms, num_lms; + int residue, input; + + num_lms = s->cdlms_ttl[ch]; + for (ilms = num_lms - 1; ilms >= 0; ilms--) { + //s->cdlms[ch][ilms].recent = s->cdlms[ch][ilms].order; + for (icoef = coef_begin; icoef < coef_end; icoef++) { + pred = 1 << (s->cdlms[ch][ilms].scaling - 1); + residue = s->channel_residues[ch][icoef]; + pred += lms_predict(s, ch, ilms); + input = residue + (pred >> s->cdlms[ch][ilms].scaling); + lms_update(s, ch, ilms, input, residue); + s->channel_residues[ch][icoef] = input; + } + } +} + +static void revert_inter_ch_decorr(WmallDecodeCtx *s, int tile_size) +{ + int icoef; + if (s->num_channels != 2) + return; + else { + for (icoef = 0; icoef < tile_size; icoef++) { + s->channel_residues[0][icoef] -= s->channel_residues[1][icoef] >> 1; + s->channel_residues[1][icoef] += s->channel_residues[0][icoef]; + } + } +} + +static void revert_acfilter(WmallDecodeCtx *s, int tile_size) +{ + int ich, icoef; + int pred; + int i, j; + int64_t *filter_coeffs = s->acfilter_coeffs; + int scaling = s->acfilter_scaling; + int order = s->acfilter_order; + + for (ich = 0; ich < s->num_channels; ich++) { + int *prevvalues = s->acfilter_prevvalues[ich]; + for (i = 0; i < order; i++) { + pred = 0; + for (j = 0; j < order; j++) { + if (i <= j) + pred += filter_coeffs[j] * prevvalues[j - i]; + else + pred += s->channel_residues[ich][i - j - 1] * filter_coeffs[j]; + } + pred >>= scaling; + s->channel_residues[ich][i] += pred; + } + for (i = order; i < tile_size; i++) { + pred = 0; + for (j = 0; j < order; j++) + pred += s->channel_residues[ich][i - j - 1] * filter_coeffs[j]; + pred >>= scaling; + s->channel_residues[ich][i] += pred; + } + for (j = 0; j < order; j++) + prevvalues[j] = s->channel_residues[ich][tile_size - j - 1]; + } +} + +/** + *@brief Decode a single subframe (block). + *@param s codec context + *@return 0 on success, < 0 when decoding failed + */ +static int decode_subframe(WmallDecodeCtx *s) +{ + int offset = s->samples_per_frame; + int subframe_len = s->samples_per_frame; + int i, j; + int total_samples = s->samples_per_frame * s->num_channels; + int rawpcm_tile; + int padding_zeroes; + + s->subframe_offset = get_bits_count(&s->gb); + + /** reset channel context and find the next block offset and size + == the next block of the channel with the smallest number of + decoded samples + */ + for (i = 0; i < s->num_channels; i++) { + s->channel[i].grouped = 0; + if (offset > s->channel[i].decoded_samples) { + offset = s->channel[i].decoded_samples; + subframe_len = + s->channel[i].subframe_len[s->channel[i].cur_subframe]; + } + } + + /** get a list of all channels that contain the estimated block */ + s->channels_for_cur_subframe = 0; + for (i = 0; i < s->num_channels; i++) { + const int cur_subframe = s->channel[i].cur_subframe; + /** substract already processed samples */ + total_samples -= s->channel[i].decoded_samples; + + /** and count if there are multiple subframes that match our profile */ + if (offset == s->channel[i].decoded_samples && + subframe_len == s->channel[i].subframe_len[cur_subframe]) { + total_samples -= s->channel[i].subframe_len[cur_subframe]; + s->channel[i].decoded_samples += + s->channel[i].subframe_len[cur_subframe]; + s->channel_indexes_for_cur_subframe[s->channels_for_cur_subframe] = i; + ++s->channels_for_cur_subframe; + } + } + + /** check if the frame will be complete after processing the + estimated block */ + if (!total_samples) + s->parsed_all_subframes = 1; + + + s->seekable_tile = get_bits1(&s->gb); + if(s->seekable_tile) { + clear_codec_buffers(s); + + s->do_arith_coding = get_bits1(&s->gb); + if(s->do_arith_coding) { + dprintf(s->avctx, "do_arith_coding == 1"); + abort(); + } + s->do_ac_filter = get_bits1(&s->gb); + s->do_inter_ch_decorr = get_bits1(&s->gb); + s->do_mclms = get_bits1(&s->gb); + + if(s->do_ac_filter) + decode_ac_filter(s); + + if(s->do_mclms) + decode_mclms(s); + + decode_cdlms(s); + s->movave_scaling = get_bits(&s->gb, 3); + s->quant_stepsize = get_bits(&s->gb, 8) + 1; + + reset_codec(s); + } + + rawpcm_tile = get_bits1(&s->gb); + + for(i = 0; i < s->num_channels; i++) { + s->is_channel_coded[i] = 1; + } + + if(!rawpcm_tile) { + + for(i = 0; i < s->num_channels; i++) { + s->is_channel_coded[i] = get_bits1(&s->gb); + } + + if(s->bV3RTM) { + // LPC + s->do_lpc = get_bits1(&s->gb); + if(s->do_lpc) { + decode_lpc(s); + } + } else { + s->do_lpc = 0; + } + } + + + if(get_bits1(&s->gb)) { + padding_zeroes = get_bits(&s->gb, 5); + } else { + padding_zeroes = 0; + } + + if(rawpcm_tile) { + + int bits = s->bits_per_sample - padding_zeroes; + dprintf(s->avctx, "RAWPCM %d bits per sample. total %d bits, remain=%d\n", bits, + bits * s->num_channels * subframe_len, get_bits_count(&s->gb)); + for(i = 0; i < s->num_channels; i++) { + for(j = 0; j < subframe_len; j++) { + s->channel_coeffs[i][j] = get_sbits(&s->gb, bits); +// dprintf(s->avctx, "PCM[%d][%d] = 0x%04x\n", i, j, s->channel_coeffs[i][j]); + } + } + } else { + for(i = 0; i < s->num_channels; i++) + if(s->is_channel_coded[i]) { + decode_channel_residues(s, i, subframe_len); + if (s->seekable_tile) + use_high_update_speed(s, i); + else + use_normal_update_speed(s, i); + revert_cdlms(s, i, 0, subframe_len); + } + } + if (s->do_mclms) + revert_mclms(s, subframe_len); + if (s->do_inter_ch_decorr) + revert_inter_ch_decorr(s, subframe_len); + if(s->do_ac_filter) + revert_acfilter(s, subframe_len); + + /* Dequantize */ + if (s->quant_stepsize != 1) + for (i = 0; i < s->num_channels; i++) + for (j = 0; j < subframe_len; j++) + s->channel_residues[i][j] *= s->quant_stepsize; + + // Write to proper output buffer depending on bit-depth + for (i = 0; i < subframe_len; i++) + for (j = 0; j < s->num_channels; j++) { + if (s->bits_per_sample == 16) + *s->samples_16++ = (int16_t) s->channel_residues[j][i]; + else + *s->samples_32++ = s->channel_residues[j][i]; + } + + /** handled one subframe */ + + for (i = 0; i < s->channels_for_cur_subframe; i++) { + int c = s->channel_indexes_for_cur_subframe[i]; + if (s->channel[c].cur_subframe >= s->channel[c].num_subframes) { + av_log(s->avctx, AV_LOG_ERROR, "broken subframe\n"); + return AVERROR_INVALIDDATA; + } + ++s->channel[c].cur_subframe; + } + num_logged_subframes++; + return 0; +} + +/** + *@brief Decode one WMA frame. + *@param s codec context + *@return 0 if the trailer bit indicates that this is the last frame, + * 1 if there are additional frames + */ +static int decode_frame(WmallDecodeCtx *s) +{ + GetBitContext* gb = &s->gb; + int more_frames = 0; + int len = 0; + int i; + int buffer_len; + + /** check for potential output buffer overflow */ + if (s->bits_per_sample == 16) + buffer_len = s->samples_16_end - s->samples_16; + else + buffer_len = s->samples_32_end - s->samples_32; + if (s->num_channels * s->samples_per_frame > buffer_len) { + /** return an error if no frame could be decoded at all */ + av_log(s->avctx, AV_LOG_ERROR, + "not enough space for the output samples\n"); + s->packet_loss = 1; + return 0; + } + + /** get frame length */ + if (s->len_prefix) + len = get_bits(gb, s->log2_frame_size); + + /** decode tile information */ + if (decode_tilehdr(s)) { + s->packet_loss = 1; + return 0; + } + + /** read drc info */ + if (s->dynamic_range_compression) { + s->drc_gain = get_bits(gb, 8); + } + + /** no idea what these are for, might be the number of samples + that need to be skipped at the beginning or end of a stream */ + if (get_bits1(gb)) { + int skip; + + /** usually true for the first frame */ + if (get_bits1(gb)) { + skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); + dprintf(s->avctx, "start skip: %i\n", skip); + } + + /** sometimes true for the last frame */ + if (get_bits1(gb)) { + skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); + dprintf(s->avctx, "end skip: %i\n", skip); + } + + } + + /** reset subframe states */ + s->parsed_all_subframes = 0; + for (i = 0; i < s->num_channels; i++) { + s->channel[i].decoded_samples = 0; + s->channel[i].cur_subframe = 0; + s->channel[i].reuse_sf = 0; + } + + /** decode all subframes */ + while (!s->parsed_all_subframes) { + if (decode_subframe(s) < 0) { + s->packet_loss = 1; + return 0; + } + } + + dprintf(s->avctx, "Frame done\n"); + + if (s->skip_frame) { + s->skip_frame = 0; + } + + if (s->len_prefix) { + if (len != (get_bits_count(gb) - s->frame_offset) + 2) { + /** FIXME: not sure if this is always an error */ + av_log(s->avctx, AV_LOG_ERROR, + "frame[%i] would have to skip %i bits\n", s->frame_num, + len - (get_bits_count(gb) - s->frame_offset) - 1); + s->packet_loss = 1; + return 0; + } + + /** skip the rest of the frame data */ + skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1); + } else { +/* + while (get_bits_count(gb) < s->num_saved_bits && get_bits1(gb) == 0) { + dprintf(s->avctx, "skip1\n"); + } +*/ + } + + /** decode trailer bit */ + more_frames = get_bits1(gb); + ++s->frame_num; + return more_frames; +} + +/** + *@brief Calculate remaining input buffer length. + *@param s codec context + *@param gb bitstream reader context + *@return remaining size in bits + */ +static int remaining_bits(WmallDecodeCtx *s, GetBitContext *gb) +{ + return s->buf_bit_size - get_bits_count(gb); +} + +/** + *@brief Fill the bit reservoir with a (partial) frame. + *@param s codec context + *@param gb bitstream reader context + *@param len length of the partial frame + *@param append decides wether to reset the buffer or not + */ +static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len, + int append) +{ + int buflen; + + /** when the frame data does not need to be concatenated, the input buffer + is resetted and additional bits from the previous frame are copyed + and skipped later so that a fast byte copy is possible */ + + if (!append) { + s->frame_offset = get_bits_count(gb) & 7; + s->num_saved_bits = s->frame_offset; + init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); + } + + buflen = (s->num_saved_bits + len + 8) >> 3; + + if (len <= 0 || buflen > MAX_FRAMESIZE) { + av_log_ask_for_sample(s->avctx, "input buffer too small\n"); + s->packet_loss = 1; + return; + } + + s->num_saved_bits += len; + if (!append) { + avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), + s->num_saved_bits); + } else { + int align = 8 - (get_bits_count(gb) & 7); + align = FFMIN(align, len); + put_bits(&s->pb, align, get_bits(gb, align)); + len -= align; + avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); + } + skip_bits_long(gb, len); + + { + PutBitContext tmp = s->pb; + flush_put_bits(&tmp); + } + + init_get_bits(&s->gb, s->frame_data, s->num_saved_bits); + skip_bits(&s->gb, s->frame_offset); +} + +/** + *@brief Decode a single WMA packet. + *@param avctx codec context + *@param data the output buffer + *@param data_size number of bytes that were written to the output buffer + *@param avpkt input packet + *@return number of bytes that were read from the input buffer + */ +static int decode_packet(AVCodecContext *avctx, + void *data, int *data_size, AVPacket* avpkt) +{ + WmallDecodeCtx *s = avctx->priv_data; + GetBitContext* gb = &s->pgb; + const uint8_t* buf = avpkt->data; + int buf_size = avpkt->size; + int num_bits_prev_frame; + int packet_sequence_number; + + if (s->bits_per_sample == 16) { + s->samples_16 = (int16_t *) data; + s->samples_16_end = (int16_t *) ((int8_t*)data + *data_size); + } else { + s->samples_32 = (void *) data; + s->samples_32_end = (void *) ((int8_t*)data + *data_size); + } + *data_size = 0; + + if (s->packet_done || s->packet_loss) { + int seekable_frame_in_packet, spliced_packet; + s->packet_done = 0; + + /** sanity check for the buffer length */ + if (buf_size < avctx->block_align) + return 0; + + s->next_packet_start = buf_size - avctx->block_align; + buf_size = avctx->block_align; + s->buf_bit_size = buf_size << 3; + + /** parse packet header */ + init_get_bits(gb, buf, s->buf_bit_size); + packet_sequence_number = get_bits(gb, 4); + seekable_frame_in_packet = get_bits1(gb); + spliced_packet = get_bits1(gb); + + /** get number of bits that need to be added to the previous frame */ + num_bits_prev_frame = get_bits(gb, s->log2_frame_size); + + /** check for packet loss */ + if (!s->packet_loss && + ((s->packet_sequence_number + 1) & 0xF) != packet_sequence_number) { + s->packet_loss = 1; + av_log(avctx, AV_LOG_ERROR, "Packet loss detected! seq %x vs %x\n", + s->packet_sequence_number, packet_sequence_number); + } + s->packet_sequence_number = packet_sequence_number; + + if (num_bits_prev_frame > 0) { + int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb); + if (num_bits_prev_frame >= remaining_packet_bits) { + num_bits_prev_frame = remaining_packet_bits; + s->packet_done = 1; + } + + /** append the previous frame data to the remaining data from the + previous packet to create a full frame */ + save_bits(s, gb, num_bits_prev_frame, 1); + + /** decode the cross packet frame if it is valid */ + if (!s->packet_loss) + decode_frame(s); + } else if (s->num_saved_bits - s->frame_offset) { + dprintf(avctx, "ignoring %x previously saved bits\n", + s->num_saved_bits - s->frame_offset); + } + + if (s->packet_loss) { + /** reset number of saved bits so that the decoder + does not start to decode incomplete frames in the + s->len_prefix == 0 case */ + s->num_saved_bits = 0; + s->packet_loss = 0; + } + + } else { + int frame_size; + + s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3; + init_get_bits(gb, avpkt->data, s->buf_bit_size); + skip_bits(gb, s->packet_offset); + + if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size && + (frame_size = show_bits(gb, s->log2_frame_size)) && + frame_size <= remaining_bits(s, gb)) { + save_bits(s, gb, frame_size, 0); + s->packet_done = !decode_frame(s); + } else if (!s->len_prefix + && s->num_saved_bits > get_bits_count(&s->gb)) { + /** when the frames do not have a length prefix, we don't know + the compressed length of the individual frames + however, we know what part of a new packet belongs to the + previous frame + therefore we save the incoming packet first, then we append + the "previous frame" data from the next packet so that + we get a buffer that only contains full frames */ + s->packet_done = !decode_frame(s); + } else { + s->packet_done = 1; + } + } + + if (s->packet_done && !s->packet_loss && + remaining_bits(s, gb) > 0) { + /** save the rest of the data so that it can be decoded + with the next packet */ + save_bits(s, gb, remaining_bits(s, gb), 0); + } + + if (s->bits_per_sample == 16) + *data_size = (int8_t *)s->samples_16 - (int8_t *)data; + else + *data_size = (int8_t *)s->samples_32 - (int8_t *)data; + s->packet_offset = get_bits_count(gb) & 7; + + return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3; +} + +/** + *@brief Clear decoder buffers (for seeking). + *@param avctx codec context + */ +static void flush(AVCodecContext *avctx) +{ + WmallDecodeCtx *s = avctx->priv_data; + int i; + /** reset output buffer as a part of it is used during the windowing of a + new frame */ + for (i = 0; i < s->num_channels; i++) + memset(s->channel[i].out, 0, s->samples_per_frame * + sizeof(*s->channel[i].out)); + s->packet_loss = 1; +} + + +/** + *@brief wmall decoder + */ +AVCodec ff_wmalossless_decoder = { + .name = "wmalossless", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_WMALOSSLESS, + .priv_data_size = sizeof(WmallDecodeCtx), + .init = decode_init, + .close = decode_end, + .decode = decode_packet, + .flush = flush, + .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_EXPERIMENTAL, + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Lossless"), +}; diff --git a/libavcodec/wmaprodata.h b/libavcodec/wmaprodata.h index f8a52bf4f4..53824799d5 100644 --- a/libavcodec/wmaprodata.h +++ b/libavcodec/wmaprodata.h @@ -3,20 +3,20 @@ * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion * Copyright (c) 2008 - 2009 Sascha Sommer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index a1b82db60a..eccfb55432 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -3,20 +3,20 @@ * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion * Copyright (c) 2008 - 2011 Sascha Sommer, Benjamin Larsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1443,7 +1443,7 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); } - buflen = (s->num_saved_bits + len + 8) >> 3; + buflen = (put_bits_count(&s->pb) + len + 8) >> 3; if (len <= 0 || buflen > MAX_FRAMESIZE) { av_log_ask_for_sample(s->avctx, "input buffer too small\n"); diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index 8854e35d93..2be0cf25f2 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -2,20 +2,20 @@ * Windows Media Audio Voice decoder. * Copyright (c) 2009 Ronald S. Bultje * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -1935,7 +1935,7 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, int size, res, pos; /* Packets are sometimes a multiple of ctx->block_align, with a packet - * header at each ctx->block_align bytes. However, Libav's ASF demuxer + * header at each ctx->block_align bytes. However, FFmpeg's ASF demuxer * feeds us ASF packets, which may concatenate multiple "codec" packets * in a single "muxer" packet, so we artificially emulate that by * capping the packet size at ctx->block_align. */ diff --git a/libavcodec/wmavoice_data.h b/libavcodec/wmavoice_data.h index 7f14fb8350..cbf65b043e 100644 --- a/libavcodec/wmavoice_data.h +++ b/libavcodec/wmavoice_data.h @@ -2,20 +2,20 @@ * Windows Media Voice (WMAVoice) tables. * Copyright (c) 2009 Ronald S. Bultje * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/wmv2.c b/libavcodec/wmv2.c index 74389ef4db..32aaa8f6df 100644 --- a/libavcodec/wmv2.c +++ b/libavcodec/wmv2.c @@ -1,20 +1,20 @@ /* - * Copyright (c) 2002 The Libav Project + * Copyright (c) 2002 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/wmv2.h b/libavcodec/wmv2.h index 80f36ccddb..c69c9f48ee 100644 --- a/libavcodec/wmv2.h +++ b/libavcodec/wmv2.h @@ -1,20 +1,20 @@ /* - * Copyright (c) 2002 The Libav Project + * Copyright (c) 2002 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c index 21fc1cf82e..519ae61b93 100644 --- a/libavcodec/wmv2dec.c +++ b/libavcodec/wmv2dec.c @@ -1,20 +1,20 @@ /* - * Copyright (c) 2002 The Libav Project + * Copyright (c) 2002 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -479,7 +479,6 @@ AVCodec ff_wmv2_decoder = { .close = wmv2_decode_end, .decode = ff_h263_decode_frame, .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, - .max_lowres = 3, .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 8"), .pix_fmts= ff_pixfmt_list_420, }; diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c index 9879cb87e9..bc9e4fa0ab 100644 --- a/libavcodec/wmv2enc.c +++ b/libavcodec/wmv2enc.c @@ -1,20 +1,20 @@ /* - * Copyright (c) 2002 The Libav Project + * Copyright (c) 2002 The FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/wnv1.c b/libavcodec/wnv1.c index f6e4694df2..6429a5b748 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -2,20 +2,20 @@ * Winnov WNV1 codec * Copyright (c) 2005 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -136,6 +136,7 @@ static av_cold int decode_init(AVCodecContext *avctx){ l->avctx = avctx; avctx->pix_fmt = PIX_FMT_YUV422P; + avcodec_get_frame_defaults(&l->pic); code_vlc.table = code_table; code_vlc.table_allocated = 1 << CODE_VLC_BITS; diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c index b2d086e073..2cb8bb44a6 100644 --- a/libavcodec/ws-snd1.c +++ b/libavcodec/ws-snd1.c @@ -2,20 +2,20 @@ * Westwood SNDx codecs * Copyright (c) 2005 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -112,8 +112,8 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, void *data, /* make sure we don't write past the output buffer */ switch (code) { - case 0: smp = 4; break; - case 1: smp = 2; break; + case 0: smp = 4*(count+1); break; + case 1: smp = 2*(count+1); break; case 2: smp = (count & 0x20) ? 1 : count + 1; break; default: smp = count + 1; break; } diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index fc88433783..dc8c66afde 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -9,6 +9,8 @@ YASM-OBJS-FFT-$(HAVE_SSE) += x86/fft_sse.o YASM-OBJS-$(CONFIG_FFT) += x86/fft_mmx.o \ $(YASM-OBJS-FFT-yes) +YASM-OBJS-$(CONFIG_DWT) += x86/dwt_yasm.o + YASM-OBJS-$(CONFIG_H264CHROMA) += x86/h264_chromamc.o \ x86/h264_chromamc_10bit.o @@ -33,6 +35,8 @@ YASM-OBJS-$(CONFIG_RV40_DECODER) += x86/rv34dsp.o \ YASM-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_yasm.o +YASM-OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp_mmx.o x86/diracdsp_yasm.o + MMX-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp_mmx.o YASM-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp.o MMX-OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp_mmx.o @@ -43,11 +47,16 @@ MMX-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_mmx.o YASM-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_yasm.o MMX-OBJS-$(CONFIG_GPL) += x86/idct_mmx.o MMX-OBJS-$(CONFIG_LPC) += x86/lpc_mmx.o +YASM-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp.o +MMX-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp-init.o YASM-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp.o MMX-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp-init.o YASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o MMX-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp-init.o -MMX-OBJS-$(CONFIG_DWT) += x86/snowdsp_mmx.o +MMX-OBJS-$(CONFIG_DWT) += x86/snowdsp_mmx.o \ + x86/dwt.o +YASM-OBJS-$(CONFIG_V210_DECODER) += x86/v210.o +MMX-OBJS-$(CONFIG_V210_DECODER) += x86/v210-init.o MMX-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp_mmx.o YASM-OBJS-$(CONFIG_VP3_DECODER) += x86/vp3dsp.o YASM-OBJS-$(CONFIG_VP5_DECODER) += x86/vp3dsp.o diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm index e1761fa806..4ada8990ba 100644 --- a/libavcodec/x86/ac3dsp.asm +++ b/libavcodec/x86/ac3dsp.asm @@ -2,25 +2,25 @@ ;* x86-optimized AC-3 DSP utils ;* Copyright (c) 2011 Justin Ruggles ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA diff --git a/libavcodec/x86/ac3dsp_mmx.c b/libavcodec/x86/ac3dsp_mmx.c index d6bb469457..9578e98d8b 100644 --- a/libavcodec/x86/ac3dsp_mmx.c +++ b/libavcodec/x86/ac3dsp_mmx.c @@ -2,20 +2,20 @@ * x86-optimized AC-3 DSP utils * Copyright (c) 2011 Justin Ruggles * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h index 3c3652d5f0..2bb0be6374 100644 --- a/libavcodec/x86/cabac.h +++ b/libavcodec/x86/cabac.h @@ -81,7 +81,9 @@ "add "tmp" , "low" \n\t"\ "1: \n\t" -#if HAVE_7REGS && !defined(BROKEN_RELOCATIONS) + +#if HAVE_7REGS && !defined(BROKEN_RELOCATIONS) && !(defined(__i386) && defined(__clang__) && (__clang_major__<2 || (__clang_major__==2 && __clang_minor__<10)))\ + && !(defined(__i386) && !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1) #define get_cabac_inline get_cabac_inline_x86 static av_always_inline int get_cabac_inline_x86(CABACContext *c, uint8_t *const state) diff --git a/libavcodec/x86/cavsdsp_mmx.c b/libavcodec/x86/cavsdsp_mmx.c index 3bc62ea156..0f5fdaa53d 100644 --- a/libavcodec/x86/cavsdsp_mmx.c +++ b/libavcodec/x86/cavsdsp_mmx.c @@ -5,20 +5,20 @@ * MMX-optimized DSP functions, based on H.264 optimizations by * Michael Niedermayer and Loren Merritt * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/dct32_sse.asm b/libavcodec/x86/dct32_sse.asm index e3c8a45545..ca44106433 100644 --- a/libavcodec/x86/dct32_sse.asm +++ b/libavcodec/x86/dct32_sse.asm @@ -2,25 +2,25 @@ ;* 32 point SSE-optimized DCT transform ;* Copyright (c) 2010 Vitor Sessak ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA 32 diff --git a/libavcodec/x86/deinterlace.asm b/libavcodec/x86/deinterlace.asm index 8613485d5d..a09473bdae 100644 --- a/libavcodec/x86/deinterlace.asm +++ b/libavcodec/x86/deinterlace.asm @@ -3,25 +3,25 @@ ;* Copyright (c) 2010 Vitor Sessak ;* Copyright (c) 2002 Michael Niedermayer ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA diff --git a/libavcodec/x86/diracdsp_mmx.c b/libavcodec/x86/diracdsp_mmx.c new file mode 100644 index 0000000000..a343bdd2af --- /dev/null +++ b/libavcodec/x86/diracdsp_mmx.c @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2010 David Conrad + * + * 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" +#include "diracdsp_mmx.h" + +void ff_put_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_rect_clamped_sse2(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_signed_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_signed_rect_clamped_sse2(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); + +#define HPEL_FILTER(MMSIZE, EXT) \ + void ff_dirac_hpel_filter_v_ ## EXT(uint8_t *, uint8_t *, int, int); \ + void ff_dirac_hpel_filter_h_ ## EXT(uint8_t *, uint8_t *, int); \ + \ + static void dirac_hpel_filter_ ## EXT(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, \ + uint8_t *src, int stride, int width, int height) \ + { \ + while( height-- ) \ + { \ + ff_dirac_hpel_filter_v_ ## EXT(dstv-MMSIZE, src-MMSIZE, stride, width+MMSIZE+5); \ + ff_dirac_hpel_filter_h_ ## EXT(dsth, src, width); \ + ff_dirac_hpel_filter_h_ ## EXT(dstc, dstv, width); \ + \ + dsth += stride; \ + dstv += stride; \ + dstc += stride; \ + src += stride; \ + } \ + } + +#if !ARCH_X86_64 +HPEL_FILTER(8, mmx) +#endif +HPEL_FILTER(16, sse2) + +#define PIXFUNC(PFX, IDX, EXT) \ + /*MMXDISABLEDc->PFX ## _dirac_pixels_tab[0][IDX] = ff_ ## PFX ## _dirac_pixels8_ ## EXT;*/ \ + c->PFX ## _dirac_pixels_tab[1][IDX] = ff_ ## PFX ## _dirac_pixels16_ ## EXT; \ + c->PFX ## _dirac_pixels_tab[2][IDX] = ff_ ## PFX ## _dirac_pixels32_ ## EXT + +void ff_diracdsp_init_mmx(DiracDSPContext* c) +{ + int mm_flags = av_get_cpu_flags(); + +#if HAVE_YASM + c->add_dirac_obmc[0] = ff_add_dirac_obmc8_mmx; +#if !ARCH_X86_64 + c->add_dirac_obmc[1] = ff_add_dirac_obmc16_mmx; + c->add_dirac_obmc[2] = ff_add_dirac_obmc32_mmx; + c->dirac_hpel_filter = dirac_hpel_filter_mmx; + c->add_rect_clamped = ff_add_rect_clamped_mmx; + c->put_signed_rect_clamped = ff_put_signed_rect_clamped_mmx; +#endif +#endif + + PIXFUNC(put, 0, mmx); + PIXFUNC(avg, 0, mmx); + + if (mm_flags & AV_CPU_FLAG_MMX2) { + PIXFUNC(avg, 0, mmx2); + } + + if (mm_flags & AV_CPU_FLAG_SSE2) { +#if HAVE_YASM + c->dirac_hpel_filter = dirac_hpel_filter_sse2; + c->add_rect_clamped = ff_add_rect_clamped_sse2; + c->put_signed_rect_clamped = ff_put_signed_rect_clamped_sse2; + + c->add_dirac_obmc[1] = ff_add_dirac_obmc16_sse2; + c->add_dirac_obmc[2] = ff_add_dirac_obmc32_sse2; +#endif + c->put_dirac_pixels_tab[1][0] = ff_put_dirac_pixels16_sse2; + c->avg_dirac_pixels_tab[1][0] = ff_avg_dirac_pixels16_sse2; + c->put_dirac_pixels_tab[2][0] = ff_put_dirac_pixels32_sse2; + c->avg_dirac_pixels_tab[2][0] = ff_avg_dirac_pixels32_sse2; + } +} diff --git a/libavcodec/x86/diracdsp_mmx.h b/libavcodec/x86/diracdsp_mmx.h new file mode 100644 index 0000000000..3d8e1173fa --- /dev/null +++ b/libavcodec/x86/diracdsp_mmx.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010 David Conrad + * + * 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 AVCODEC_X86_DIRACDSP_H +#define AVCODEC_X86_DIRACDSP_H + +#include "libavcodec/diracdsp.h" + +void ff_diracdsp_init_mmx(DiracDSPContext* c); + +DECL_DIRAC_PIXOP(put, mmx); +DECL_DIRAC_PIXOP(avg, mmx); +DECL_DIRAC_PIXOP(avg, mmx2); + +void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); +void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); +void ff_put_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); +void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h); + +void ff_add_rect_clamped_mmx(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int); +void ff_add_rect_clamped_sse2(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int); + +void ff_add_dirac_obmc8_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); +void ff_add_dirac_obmc16_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); +void ff_add_dirac_obmc32_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); + +void ff_add_dirac_obmc16_sse2(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); +void ff_add_dirac_obmc32_sse2(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); + +#endif diff --git a/libavcodec/x86/diracdsp_yasm.asm b/libavcodec/x86/diracdsp_yasm.asm new file mode 100644 index 0000000000..72f57e6049 --- /dev/null +++ b/libavcodec/x86/diracdsp_yasm.asm @@ -0,0 +1,260 @@ +;****************************************************************************** +;* Copyright (c) 2010 David Conrad +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "x86inc.asm" + +SECTION_RODATA +pw_3: times 8 dw 3 +pw_7: times 8 dw 7 +pw_16: times 8 dw 16 +pw_32: times 8 dw 32 +pb_128: times 16 db 128 + +section .text + +%macro UNPACK_ADD 6 + mov%5 %1, %3 + mov%6 m5, %4 + mova m4, %1 + mova %2, m5 + punpcklbw %1, m7 + punpcklbw m5, m7 + punpckhbw m4, m7 + punpckhbw %2, m7 + paddw %1, m5 + paddw %2, m4 +%endmacro + +%macro HPEL_FILTER 1 +; dirac_hpel_filter_v_sse2(uint8_t *dst, uint8_t *src, int stride, int width); +cglobal dirac_hpel_filter_v_%1, 4,6,8, dst, src, stride, width, src0, stridex3 + mov src0q, srcq + lea stridex3q, [3*strideq] + sub src0q, stridex3q + pxor m7, m7 +.loop: + ; 7*(src[0] + src[1]) + UNPACK_ADD m0, m1, [srcq], [srcq + strideq], a,a + pmullw m0, [pw_7] + pmullw m1, [pw_7] + + ; 3*( ... + src[-2] + src[3]) + UNPACK_ADD m2, m3, [src0q + strideq], [srcq + stridex3q], a,a + paddw m0, m2 + paddw m1, m3 + pmullw m0, [pw_3] + pmullw m1, [pw_3] + + ; ... - 7*(src[-1] + src[2]) + UNPACK_ADD m2, m3, [src0q + strideq*2], [srcq + strideq*2], a,a + pmullw m2, [pw_7] + pmullw m3, [pw_7] + psubw m0, m2 + psubw m1, m3 + + ; ... - (src[-3] + src[4]) + UNPACK_ADD m2, m3, [src0q], [srcq + strideq*4], a,a + psubw m0, m2 + psubw m1, m3 + + paddw m0, [pw_16] + paddw m1, [pw_16] + psraw m0, 5 + psraw m1, 5 + packuswb m0, m1 + mova [dstq], m0 + add dstq, mmsize + add srcq, mmsize + add src0q, mmsize + sub widthd, mmsize + jg .loop + RET + +; dirac_hpel_filter_h_sse2(uint8_t *dst, uint8_t *src, int width); +cglobal dirac_hpel_filter_h_%1, 3,3,8, dst, src, width + dec widthd + pxor m7, m7 + and widthd, ~(mmsize-1) +.loop: + ; 7*(src[0] + src[1]) + UNPACK_ADD m0, m1, [srcq + widthq], [srcq + widthq + 1], u,u + pmullw m0, [pw_7] + pmullw m1, [pw_7] + + ; 3*( ... + src[-2] + src[3]) + UNPACK_ADD m2, m3, [srcq + widthq - 2], [srcq + widthq + 3], u,u + paddw m0, m2 + paddw m1, m3 + pmullw m0, [pw_3] + pmullw m1, [pw_3] + + ; ... - 7*(src[-1] + src[2]) + UNPACK_ADD m2, m3, [srcq + widthq - 1], [srcq + widthq + 2], u,u + pmullw m2, [pw_7] + pmullw m3, [pw_7] + psubw m0, m2 + psubw m1, m3 + + ; ... - (src[-3] + src[4]) + UNPACK_ADD m2, m3, [srcq + widthq - 3], [srcq + widthq + 4], u,u + psubw m0, m2 + psubw m1, m3 + + paddw m0, [pw_16] + paddw m1, [pw_16] + psraw m0, 5 + psraw m1, 5 + packuswb m0, m1 + mova [dstq + widthq], m0 + sub widthd, mmsize + jge .loop + RET +%endmacro + +%macro PUT_RECT 1 +; void put_rect_clamped(uint8_t *dst, int dst_stride, int16_t *src, int src_stride, int width, int height) +cglobal put_signed_rect_clamped_%1, 5,7,3, dst, dst_stride, src, src_stride, w, dst2, src2 + mova m0, [pb_128] + add wd, (mmsize-1) + and wd, ~(mmsize-1) + +%if ARCH_X86_64 + mov r10d, r5m + mov r11d, wd + %define wspill r11d + %define hd r10d +%else + mov r4m, wd + %define wspill r4m + %define hd r5mp +%endif + +.loopy + lea src2q, [srcq+src_strideq*2] + lea dst2q, [dstq+dst_strideq] +.loopx: + sub wd, mmsize + mova m1, [srcq +2*wq] + mova m2, [src2q+2*wq] + packsswb m1, [srcq +2*wq+mmsize] + packsswb m2, [src2q+2*wq+mmsize] + paddb m1, m0 + paddb m2, m0 + mova [dstq +wq], m1 + mova [dst2q+wq], m2 + jg .loopx + + lea srcq, [srcq+src_strideq*4] + lea dstq, [dstq+dst_strideq*2] + sub hd, 2 + mov wd, wspill + jg .loopy + RET +%endm + +%macro ADD_RECT 1 +; void add_rect_clamped(uint8_t *dst, uint16_t *src, int stride, int16_t *idwt, int idwt_stride, int width, int height) +cglobal add_rect_clamped_%1, 7,7,3, dst, src, stride, idwt, idwt_stride, w, h + mova m0, [pw_32] + add wd, (mmsize-1) + and wd, ~(mmsize-1) + +%if ARCH_X86_64 + mov r11d, wd + %define wspill r11d +%else + mov r5m, wd + %define wspill r5m +%endif + +.loop: + sub wd, mmsize + movu m1, [srcq +2*wq] ; FIXME: ensure alignment + paddw m1, m0 + psraw m1, 6 + movu m2, [srcq +2*wq+mmsize] ; FIXME: ensure alignment + paddw m2, m0 + psraw m2, 6 + paddw m1, [idwtq+2*wq] + paddw m2, [idwtq+2*wq+mmsize] + packuswb m1, m2 + mova [dstq +wq], m1 + jg .loop + + lea srcq, [srcq + 2*strideq] + add dstq, strideq + lea idwtq, [idwtq+ 2*idwt_strideq] + sub hd, 1 + mov wd, wspill + jg .loop + RET +%endm + +%macro ADD_OBMC 2 +; void add_obmc(uint16_t *dst, uint8_t *src, int stride, uint8_t *obmc_weight, int yblen) +cglobal add_dirac_obmc%1_%2, 6,6,5, dst, src, stride, obmc, yblen + pxor m4, m4 +.loop: +%assign i 0 +%rep %1 / mmsize + mova m0, [srcq+i] + mova m1, m0 + punpcklbw m0, m4 + punpckhbw m1, m4 + mova m2, [obmcq+i] + mova m3, m2 + punpcklbw m2, m4 + punpckhbw m3, m4 + pmullw m0, m2 + pmullw m1, m3 + movu m2, [dstq+2*i] + movu m3, [dstq+2*i+mmsize] + paddw m0, m2 + paddw m1, m3 + movu [dstq+2*i], m0 + movu [dstq+2*i+mmsize], m1 +%assign i i+mmsize +%endrep + lea srcq, [srcq+strideq] + lea dstq, [dstq+2*strideq] + add obmcq, 32 + sub yblend, 1 + jg .loop + RET +%endm + +INIT_MMX +%if ARCH_X86_64 == 0 +PUT_RECT mmx +ADD_RECT mmx + +HPEL_FILTER mmx +ADD_OBMC 32, mmx +ADD_OBMC 16, mmx +%endif +ADD_OBMC 8, mmx + +INIT_XMM +PUT_RECT sse2 +ADD_RECT sse2 + +HPEL_FILTER sse2 +ADD_OBMC 32, sse2 +ADD_OBMC 16, sse2 diff --git a/libavcodec/x86/dnxhd_mmx.c b/libavcodec/x86/dnxhd_mmx.c index e193d62e21..1f2b035212 100644 --- a/libavcodec/x86/dnxhd_mmx.c +++ b/libavcodec/x86/dnxhd_mmx.c @@ -4,20 +4,20 @@ * * VC-3 encoder funded by the British Broadcasting Corporation * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c index c40cab51f0..4402995da5 100644 --- a/libavcodec/x86/dsputil_mmx.c +++ b/libavcodec/x86/dsputil_mmx.c @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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> @@ -31,6 +31,7 @@ #include "libavcodec/ac3dec.h" #include "dsputil_mmx.h" #include "idct_xvid.h" +#include "diracdsp_mmx.h" //#undef NDEBUG //#include <assert.h> @@ -1864,6 +1865,84 @@ void ff_avg_vc1_mspel_mc00_mmx2(uint8_t *dst, const uint8_t *src, int stride, in avg_pixels8_mmx2(dst, src, stride, 8); } +/* only used in VP3/5/6 */ +static void put_vp_no_rnd_pixels8_l2_mmx(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h) +{ +// START_TIMER + MOVQ_BFE(mm6); + __asm__ volatile( + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%2), %%mm1 \n\t" + "movq (%1,%4), %%mm2 \n\t" + "movq (%2,%4), %%mm3 \n\t" + PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%3) \n\t" + "movq %%mm5, (%3,%4) \n\t" + + "movq (%1,%4,2), %%mm0 \n\t" + "movq (%2,%4,2), %%mm1 \n\t" + "movq (%1,%5), %%mm2 \n\t" + "movq (%2,%5), %%mm3 \n\t" + "lea (%1,%4,4), %1 \n\t" + "lea (%2,%4,4), %2 \n\t" + PAVGBP_MMX_NO_RND(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%3,%4,2) \n\t" + "movq %%mm5, (%3,%5) \n\t" + "lea (%3,%4,4), %3 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+r"(h), "+r"(a), "+r"(b), "+r"(dst) + :"r"((x86_reg)stride), "r"((x86_reg)3L*stride) + :"memory"); +// STOP_TIMER("put_vp_no_rnd_pixels8_l2_mmx") +} +static void put_vp_no_rnd_pixels16_l2_mmx(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h) +{ + put_vp_no_rnd_pixels8_l2_mmx(dst, a, b, stride, h); + put_vp_no_rnd_pixels8_l2_mmx(dst+8, a+8, b+8, stride, h); +} + +#if CONFIG_DIRAC_DECODER +#define DIRAC_PIXOP(OPNAME, EXT)\ +void ff_ ## OPNAME ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels8_ ## EXT(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_ ## EXT(dst, src[0], stride, h);\ +}\ +void ff_ ## OPNAME ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\ +{\ + OPNAME ## _pixels16_ ## EXT(dst , src[0] , stride, h);\ + OPNAME ## _pixels16_ ## EXT(dst+16, src[0]+16, stride, h);\ +} + +DIRAC_PIXOP(put, mmx) +DIRAC_PIXOP(avg, mmx) +DIRAC_PIXOP(avg, mmx2) + +void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) +{ + put_pixels16_sse2(dst, src[0], stride, h); +} +void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) +{ + avg_pixels16_sse2(dst, src[0], stride, h); +} +void ff_put_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) +{ + put_pixels16_sse2(dst , src[0] , stride, h); + put_pixels16_sse2(dst+16, src[0]+16, stride, h); +} +void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h) +{ + avg_pixels16_sse2(dst , src[0] , stride, h); + avg_pixels16_sse2(dst+16, src[0]+16, stride, h); +} +#endif + /* XXX: those functions should be suppressed ASAP when all IDCTs are converted */ #if CONFIG_GPL @@ -2461,7 +2540,10 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->add_bytes= add_bytes_mmx; if (!high_bit_depth) - c->draw_edges = draw_edges_mmx; + c->draw_edges = draw_edges_mmx; + + c->put_no_rnd_pixels_l2[0]= put_vp_no_rnd_pixels16_l2_mmx; + c->put_no_rnd_pixels_l2[1]= put_vp_no_rnd_pixels8_l2_mmx; if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) { c->h263_v_loop_filter= h263_v_loop_filter_mmx; diff --git a/libavcodec/x86/dsputil_mmx.h b/libavcodec/x86/dsputil_mmx.h index 7ab55e7c51..59a9613609 100644 --- a/libavcodec/x86/dsputil_mmx.h +++ b/libavcodec/x86/dsputil_mmx.h @@ -2,20 +2,20 @@ * MMX optimized DSP utils * Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/dsputil_mmx_avg_template.c b/libavcodec/x86/dsputil_mmx_avg_template.c index 8b116b74e2..6f768595c0 100644 --- a/libavcodec/x86/dsputil_mmx_avg_template.c +++ b/libavcodec/x86/dsputil_mmx_avg_template.c @@ -7,20 +7,20 @@ * mostly rewritten by Michael Niedermayer <michaelni@gmx.at> * and improved by Zdenek Kabelac <kabi@users.sf.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/dsputil_mmx_qns_template.c b/libavcodec/x86/dsputil_mmx_qns_template.c index 20a40a175e..77a41b9dcb 100644 --- a/libavcodec/x86/dsputil_mmx_qns_template.c +++ b/libavcodec/x86/dsputil_mmx_qns_template.c @@ -5,20 +5,20 @@ * MMX optimization by Michael Niedermayer <michaelni@gmx.at> * 3DNow! and SSSE3 optimization by Zuxy Meng <zuxy.meng@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/dsputil_mmx_rnd_template.c b/libavcodec/x86/dsputil_mmx_rnd_template.c index 34a2c0bca8..e4c91381fa 100644 --- a/libavcodec/x86/dsputil_mmx_rnd_template.c +++ b/libavcodec/x86/dsputil_mmx_rnd_template.c @@ -7,20 +7,20 @@ * mostly rewritten by Michael Niedermayer <michaelni@gmx.at> * and improved by Zdenek Kabelac <kabi@users.sf.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/dsputil_yasm.asm b/libavcodec/x86/dsputil_yasm.asm index 09940d147d..966344f7c7 100644 --- a/libavcodec/x86/dsputil_yasm.asm +++ b/libavcodec/x86/dsputil_yasm.asm @@ -2,24 +2,24 @@ ;* MMX optimized DSP utils ;* Copyright (c) 2008 Loren Merritt ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" +%include "libavutil/x86/x86inc.asm" %include "x86util.asm" SECTION_RODATA @@ -1177,8 +1177,10 @@ cglobal butterflies_float_interleave, 4,4,3, dst, src0, src1, len INIT_XMM sse BUTTERFLIES_FLOAT_INTERLEAVE +%ifdef HAVE_AVX INIT_YMM avx BUTTERFLIES_FLOAT_INTERLEAVE +%endif INIT_XMM sse2 ; %1 = aligned/unaligned @@ -1301,3 +1303,4 @@ cglobal bswap32_buf, 3,4,3 mov [r0], r2d .end: RET + diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c index 7362234c86..f13c1219da 100644 --- a/libavcodec/x86/dsputilenc_mmx.c +++ b/libavcodec/x86/dsputilenc_mmx.c @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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> diff --git a/libavcodec/x86/dsputilenc_yasm.asm b/libavcodec/x86/dsputilenc_yasm.asm index cfd4e6d28b..1be359d667 100644 --- a/libavcodec/x86/dsputilenc_yasm.asm +++ b/libavcodec/x86/dsputilenc_yasm.asm @@ -4,25 +4,25 @@ ;* Copyright (c) 2000, 2001 Fabrice Bellard ;* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;***************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION .text diff --git a/libavcodec/x86/dwt.c b/libavcodec/x86/dwt.c new file mode 100644 index 0000000000..45b3b34ebe --- /dev/null +++ b/libavcodec/x86/dwt.c @@ -0,0 +1,202 @@ +/* + * MMX optimized discrete wavelet transform + * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> + * Copyright (c) 2010 David Conrad + * + * 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 "libavutil/x86_cpu.h" +#include "dsputil_mmx.h" +#include "dwt.h" + +#define COMPOSE_VERTICAL(ext, align) \ +void ff_vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); \ +void ff_vertical_compose_dirac53iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); \ +void ff_vertical_compose_dd137iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width); \ +void ff_vertical_compose_dd97iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width); \ +void ff_vertical_compose_haar##ext(IDWTELEM *b0, IDWTELEM *b1, int width); \ +void ff_horizontal_compose_haar0i##ext(IDWTELEM *b, IDWTELEM *tmp, int w);\ +void ff_horizontal_compose_haar1i##ext(IDWTELEM *b, IDWTELEM *tmp, int w);\ +\ +static void vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \ +{ \ + int i, width_align = width&~(align-1); \ +\ + for(i=width_align; i<width; i++) \ + b1[i] = COMPOSE_53iL0(b0[i], b1[i], b2[i]); \ +\ + ff_vertical_compose53iL0##ext(b0, b1, b2, width_align); \ +} \ +\ +static void vertical_compose_dirac53iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \ +{ \ + int i, width_align = width&~(align-1); \ +\ + for(i=width_align; i<width; i++) \ + b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]); \ +\ + ff_vertical_compose_dirac53iH0##ext(b0, b1, b2, width_align); \ +} \ +\ +static void vertical_compose_dd137iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \ + IDWTELEM *b3, IDWTELEM *b4, int width) \ +{ \ + int i, width_align = width&~(align-1); \ +\ + for(i=width_align; i<width; i++) \ + b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]); \ +\ + ff_vertical_compose_dd137iL0##ext(b0, b1, b2, b3, b4, width_align); \ +} \ +\ +static void vertical_compose_dd97iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \ + IDWTELEM *b3, IDWTELEM *b4, int width) \ +{ \ + int i, width_align = width&~(align-1); \ +\ + for(i=width_align; i<width; i++) \ + b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]); \ +\ + ff_vertical_compose_dd97iH0##ext(b0, b1, b2, b3, b4, width_align); \ +} \ +static void vertical_compose_haar##ext(IDWTELEM *b0, IDWTELEM *b1, int width) \ +{ \ + int i, width_align = width&~(align-1); \ +\ + for(i=width_align; i<width; i++) { \ + b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]); \ + b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]); \ + } \ +\ + ff_vertical_compose_haar##ext(b0, b1, width_align); \ +} \ +static void horizontal_compose_haar0i##ext(IDWTELEM *b, IDWTELEM *tmp, int w)\ +{\ + int w2= w>>1;\ + int x= w2 - (w2&(align-1));\ + ff_horizontal_compose_haar0i##ext(b, tmp, w);\ +\ + for (; x < w2; x++) {\ + b[2*x ] = tmp[x];\ + b[2*x+1] = COMPOSE_HAARiH0(b[x+w2], tmp[x]);\ + }\ +}\ +static void horizontal_compose_haar1i##ext(IDWTELEM *b, IDWTELEM *tmp, int w)\ +{\ + int w2= w>>1;\ + int x= w2 - (w2&(align-1));\ + ff_horizontal_compose_haar1i##ext(b, tmp, w);\ +\ + for (; x < w2; x++) {\ + b[2*x ] = (tmp[x] + 1)>>1;\ + b[2*x+1] = (COMPOSE_HAARiH0(b[x+w2], tmp[x]) + 1)>>1;\ + }\ +}\ +\ + +#if HAVE_YASM +#if !ARCH_X86_64 +COMPOSE_VERTICAL(_mmx, 4) +#endif +COMPOSE_VERTICAL(_sse2, 8) +#endif + + +void ff_horizontal_compose_dd97i_ssse3(IDWTELEM *b, IDWTELEM *tmp, int w); + +static void horizontal_compose_dd97i_ssse3(IDWTELEM *b, IDWTELEM *tmp, int w) +{ + int w2= w>>1; + int x= w2 - (w2&7); + ff_horizontal_compose_dd97i_ssse3(b, tmp, w); + + for (; x < w2; x++) { + b[2*x ] = (tmp[x] + 1)>>1; + b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1; + } +} + +void ff_spatial_idwt_init_mmx(DWTContext *d, enum dwt_type type) +{ +#if HAVE_YASM + int mm_flags = av_get_cpu_flags(); + +#if !ARCH_X86_64 + if (!(mm_flags & AV_CPU_FLAG_MMX)) + return; + + switch (type) { + case DWT_DIRAC_DD9_7: + d->vertical_compose_l0 = vertical_compose53iL0_mmx; + d->vertical_compose_h0 = vertical_compose_dd97iH0_mmx; + break; + case DWT_DIRAC_LEGALL5_3: + d->vertical_compose_l0 = vertical_compose53iL0_mmx; + d->vertical_compose_h0 = vertical_compose_dirac53iH0_mmx; + break; + case DWT_DIRAC_DD13_7: + d->vertical_compose_l0 = vertical_compose_dd137iL0_mmx; + d->vertical_compose_h0 = vertical_compose_dd97iH0_mmx; + break; + case DWT_DIRAC_HAAR0: + d->vertical_compose = vertical_compose_haar_mmx; + d->horizontal_compose = horizontal_compose_haar0i_mmx; + break; + case DWT_DIRAC_HAAR1: + d->vertical_compose = vertical_compose_haar_mmx; + d->horizontal_compose = horizontal_compose_haar1i_mmx; + break; + } +#endif + + if (!(mm_flags & AV_CPU_FLAG_SSE2)) + return; + + switch (type) { + case DWT_DIRAC_DD9_7: + d->vertical_compose_l0 = vertical_compose53iL0_sse2; + d->vertical_compose_h0 = vertical_compose_dd97iH0_sse2; + break; + case DWT_DIRAC_LEGALL5_3: + d->vertical_compose_l0 = vertical_compose53iL0_sse2; + d->vertical_compose_h0 = vertical_compose_dirac53iH0_sse2; + break; + case DWT_DIRAC_DD13_7: + d->vertical_compose_l0 = vertical_compose_dd137iL0_sse2; + d->vertical_compose_h0 = vertical_compose_dd97iH0_sse2; + break; + case DWT_DIRAC_HAAR0: + d->vertical_compose = vertical_compose_haar_sse2; + d->horizontal_compose = horizontal_compose_haar0i_sse2; + break; + case DWT_DIRAC_HAAR1: + d->vertical_compose = vertical_compose_haar_sse2; + d->horizontal_compose = horizontal_compose_haar1i_sse2; + break; + } + + if (!(mm_flags & AV_CPU_FLAG_SSSE3)) + return; + + switch (type) { + case DWT_DIRAC_DD9_7: + d->horizontal_compose = horizontal_compose_dd97i_ssse3; + break; + } +#endif // HAVE_YASM +} diff --git a/libavcodec/x86/dwt.h b/libavcodec/x86/dwt.h new file mode 100644 index 0000000000..199f61175b --- /dev/null +++ b/libavcodec/x86/dwt.h @@ -0,0 +1,30 @@ +/* + * 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 AVCODEC_X86_DWT_H +#define AVCODEC_X86_DWT_H + +#include "libavcodec/dwt.h" + +void ff_horizontal_compose_dd97i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x); +void ff_horizontal_compose_haar1i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x); +void ff_horizontal_compose_haar0i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x); + +void ff_spatial_idwt_init_mmx(DWTContext *d, enum dwt_type type); + +#endif diff --git a/libavcodec/x86/dwt_yasm.asm b/libavcodec/x86/dwt_yasm.asm new file mode 100644 index 0000000000..ac6c505409 --- /dev/null +++ b/libavcodec/x86/dwt_yasm.asm @@ -0,0 +1,291 @@ +;****************************************************************************** +;* MMX optimized discrete wavelet trasnform +;* Copyright (c) 2010 David Conrad +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "x86inc.asm" + +SECTION_RODATA +pw_1: times 8 dw 1 +pw_2: times 8 dw 2 +pw_8: times 8 dw 8 +pw_16: times 8 dw 16 +pw_1991: times 4 dw 9,-1 + +section .text + +; %1 -= (%2 + %3 + 2)>>2 %4 is pw_2 +%macro COMPOSE_53iL0 4 + paddw %2, %3 + paddw %2, %4 + psraw %2, 2 + psubw %1, %2 +%endm + +; m1 = %1 + (-m0 + 9*m1 + 9*%2 -%3 + 8)>>4 +; if %4 is supplied, %1 is loaded unaligned from there +; m2: clobbered m3: pw_8 m4: pw_1991 +%macro COMPOSE_DD97iH0 3-4 + paddw m0, %3 + paddw m1, %2 + psubw m0, m3 + mova m2, m1 + punpcklwd m1, m0 + punpckhwd m2, m0 + pmaddwd m1, m4 + pmaddwd m2, m4 +%if %0 > 3 + movu %1, %4 +%endif + psrad m1, 4 + psrad m2, 4 + packssdw m1, m2 + paddw m1, %1 +%endm + +%macro COMPOSE_VERTICAL 1 +; void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, +; int width) +cglobal vertical_compose53iL0_%1, 4,4,1, b0, b1, b2, width + mova m2, [pw_2] +.loop: + sub widthd, mmsize/2 + mova m1, [b0q+2*widthq] + mova m0, [b1q+2*widthq] + COMPOSE_53iL0 m0, m1, [b2q+2*widthq], m2 + mova [b1q+2*widthq], m0 + jg .loop + REP_RET + +; void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, +; int width) +cglobal vertical_compose_dirac53iH0_%1, 4,4,1, b0, b1, b2, width + mova m1, [pw_1] +.loop: + sub widthd, mmsize/2 + mova m0, [b0q+2*widthq] + paddw m0, [b2q+2*widthq] + paddw m0, m1 + psraw m0, 1 + paddw m0, [b1q+2*widthq] + mova [b1q+2*widthq], m0 + jg .loop + REP_RET + +; void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, +; IDWTELEM *b3, IDWTELEM *b4, int width) +cglobal vertical_compose_dd97iH0_%1, 6,6,5, b0, b1, b2, b3, b4, width + mova m3, [pw_8] + mova m4, [pw_1991] +.loop: + sub widthd, mmsize/2 + mova m0, [b0q+2*widthq] + mova m1, [b1q+2*widthq] + COMPOSE_DD97iH0 [b2q+2*widthq], [b3q+2*widthq], [b4q+2*widthq] + mova [b2q+2*widthq], m1 + jg .loop + REP_RET + +; void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, +; IDWTELEM *b3, IDWTELEM *b4, int width) +cglobal vertical_compose_dd137iL0_%1, 6,6,6, b0, b1, b2, b3, b4, width + mova m3, [pw_16] + mova m4, [pw_1991] +.loop: + sub widthd, mmsize/2 + mova m0, [b0q+2*widthq] + mova m1, [b1q+2*widthq] + mova m5, [b2q+2*widthq] + paddw m0, [b4q+2*widthq] + paddw m1, [b3q+2*widthq] + psubw m0, m3 + mova m2, m1 + punpcklwd m1, m0 + punpckhwd m2, m0 + pmaddwd m1, m4 + pmaddwd m2, m4 + psrad m1, 5 + psrad m2, 5 + packssdw m1, m2 + psubw m5, m1 + mova [b2q+2*widthq], m5 + jg .loop + REP_RET + +; void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width) +cglobal vertical_compose_haar_%1, 3,4,3, b0, b1, width + mova m3, [pw_1] +.loop: + sub widthd, mmsize/2 + mova m1, [b1q+2*widthq] + mova m0, [b0q+2*widthq] + mova m2, m1 + paddw m1, m3 + psraw m1, 1 + psubw m0, m1 + mova [b0q+2*widthq], m0 + paddw m2, m0 + mova [b1q+2*widthq], m2 + jg .loop + REP_RET +%endmacro + +; extend the left and right edges of the tmp array by %1 and %2 respectively +%macro EDGE_EXTENSION 3 + mov %3, [tmpq] +%assign %%i 1 +%rep %1 + mov [tmpq-2*%%i], %3 + %assign %%i %%i+1 +%endrep + mov %3, [tmpq+2*w2q-2] +%assign %%i 0 +%rep %2 + mov [tmpq+2*w2q+2*%%i], %3 + %assign %%i %%i+1 +%endrep +%endmacro + + +%macro HAAR_HORIZONTAL 2 +; void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *tmp, int width) +cglobal horizontal_compose_haar%2i_%1, 3,6,4, b, tmp, w, x, w2, b_w2 + mov w2d, wd + xor xq, xq + shr w2d, 1 + lea b_w2q, [bq+wq] + mova m3, [pw_1] +.lowpass_loop: + movu m1, [b_w2q + 2*xq] + mova m0, [bq + 2*xq] + paddw m1, m3 + psraw m1, 1 + psubw m0, m1 + mova [tmpq + 2*xq], m0 + add xq, mmsize/2 + cmp xq, w2q + jl .lowpass_loop + + xor xq, xq + and w2q, ~(mmsize/2 - 1) + cmp w2q, mmsize/2 + jl .end + +.highpass_loop: + movu m1, [b_w2q + 2*xq] + mova m0, [tmpq + 2*xq] + paddw m1, m0 + + ; shift and interleave +%if %2 == 1 + paddw m0, m3 + paddw m1, m3 + psraw m0, 1 + psraw m1, 1 +%endif + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + mova [bq+4*xq], m0 + mova [bq+4*xq+mmsize], m2 + + add xq, mmsize/2 + cmp xq, w2q + jl .highpass_loop +.end: + REP_RET +%endmacro + + +INIT_XMM +; void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int width) +cglobal horizontal_compose_dd97i_ssse3, 3,6,8, b, tmp, w, x, w2, b_w2 + mov w2d, wd + xor xd, xd + shr w2d, 1 + lea b_w2q, [bq+wq] + movu m4, [bq+wq] + mova m7, [pw_2] + pslldq m4, 14 +.lowpass_loop: + movu m1, [b_w2q + 2*xq] + mova m0, [bq + 2*xq] + mova m2, m1 + palignr m1, m4, 14 + mova m4, m2 + COMPOSE_53iL0 m0, m1, m2, m7 + mova [tmpq + 2*xq], m0 + add xd, mmsize/2 + cmp xd, w2d + jl .lowpass_loop + + EDGE_EXTENSION 1, 2, xw + ; leave the last up to 7 (sse) or 3 (mmx) values for C + xor xd, xd + and w2d, ~(mmsize/2 - 1) + cmp w2d, mmsize/2 + jl .end + + mova m7, [tmpq-mmsize] + mova m0, [tmpq] + mova m5, [pw_1] + mova m3, [pw_8] + mova m4, [pw_1991] +.highpass_loop: + mova m6, m0 + palignr m0, m7, 14 + mova m7, [tmpq + 2*xq + 16] + mova m1, m7 + mova m2, m7 + palignr m1, m6, 2 + palignr m2, m6, 4 + COMPOSE_DD97iH0 m0, m6, m2, [b_w2q + 2*xq] + mova m0, m7 + mova m7, m6 + + ; shift and interleave + paddw m6, m5 + paddw m1, m5 + psraw m6, 1 + psraw m1, 1 + mova m2, m6 + punpcklwd m6, m1 + punpckhwd m2, m1 + mova [bq+4*xq], m6 + mova [bq+4*xq+mmsize], m2 + + add xd, mmsize/2 + cmp xd, w2d + jl .highpass_loop +.end: + REP_RET + + +%if ARCH_X86_64 == 0 +INIT_MMX +COMPOSE_VERTICAL mmx +HAAR_HORIZONTAL mmx, 0 +HAAR_HORIZONTAL mmx, 1 +%endif + +;;INIT_XMM +INIT_XMM +COMPOSE_VERTICAL sse2 +HAAR_HORIZONTAL sse2, 0 +HAAR_HORIZONTAL sse2, 1 diff --git a/libavcodec/x86/fdct_mmx.c b/libavcodec/x86/fdct_mmx.c index cc3036bc33..366224210f 100644 --- a/libavcodec/x86/fdct_mmx.c +++ b/libavcodec/x86/fdct_mmx.c @@ -13,20 +13,20 @@ * a page about fdct at http://www.geocities.com/ssavekar/dct.htm * Skal's fdct at http://skal.planet-d.net/coding/dct.html * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -68,7 +68,7 @@ DECLARE_ALIGNED(16, static const int16_t, fdct_one_corr)[8] = { X8(1) }; DECLARE_ALIGNED(8, static const int32_t, fdct_r_row)[2] = {RND_FRW_ROW, RND_FRW_ROW }; -static struct +static const struct { DECLARE_ALIGNED(16, const int32_t, fdct_r_row_sse2)[4]; } fdct_r_row_sse2 = @@ -151,7 +151,7 @@ DECLARE_ALIGNED(8, static const int16_t, tab_frw_01234567)[] = { // forward_dct 29692, -12299, 26722, -31521, }; -static struct +static const struct { DECLARE_ALIGNED(16, const int16_t, tab_frw_01234567_sse2)[256]; } tab_frw_01234567_sse2 = diff --git a/libavcodec/x86/fft.c b/libavcodec/x86/fft.c index 3e0c42fb1e..8544e322c4 100644 --- a/libavcodec/x86/fft.c +++ b/libavcodec/x86/fft.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/fft.h b/libavcodec/x86/fft.h index 9d68d5b219..7fdc858a50 100644 --- a/libavcodec/x86/fft.h +++ b/libavcodec/x86/fft.h @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/fft_3dn.c b/libavcodec/x86/fft_3dn.c index 5a4d3ad2c8..6f2e2e8353 100644 --- a/libavcodec/x86/fft_3dn.c +++ b/libavcodec/x86/fft_3dn.c @@ -2,20 +2,20 @@ * FFT/MDCT transform with 3DNow! optimizations * Copyright (c) 2008 Loren Merritt * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/fft_3dn2.c b/libavcodec/x86/fft_3dn2.c index ce3c9daddb..f3c5dd05ca 100644 --- a/libavcodec/x86/fft_3dn2.c +++ b/libavcodec/x86/fft_3dn2.c @@ -2,20 +2,20 @@ * FFT/MDCT transform with Extended 3DNow! optimizations * Copyright (c) 2006-2008 Zuxy MENG Jie, Loren Merritt * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/fft_mmx.asm b/libavcodec/x86/fft_mmx.asm index a2f26cca33..bea31fee9e 100644 --- a/libavcodec/x86/fft_mmx.asm +++ b/libavcodec/x86/fft_mmx.asm @@ -6,20 +6,20 @@ ;* This algorithm (though not any of the implementation details) is ;* based on libdjbfft by D. J. Bernstein. ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* 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 +28,7 @@ ; in blocks as conventient to the vector size. ; i.e. {4x real, 4x imaginary, 4x real, ...} (or 2x respectively) -%include "x86inc.asm" +%include "libavutil/x86/x86inc.asm" %if ARCH_X86_64 %define pointer resq @@ -388,6 +388,7 @@ fft32_interleave_avx: sub r2d, mmsize/4 jg .deint_loop ret + %endif INIT_XMM diff --git a/libavcodec/x86/fft_sse.c b/libavcodec/x86/fft_sse.c index 13b992f47a..a09ad38d45 100644 --- a/libavcodec/x86/fft_sse.c +++ b/libavcodec/x86/fft_sse.c @@ -2,20 +2,20 @@ * FFT/MDCT transform with SSE optimizations * Copyright (c) 2008 Loren Merritt * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/fmtconvert.asm b/libavcodec/x86/fmtconvert.asm index 3f39c7e564..ca39aa30f8 100644 --- a/libavcodec/x86/fmtconvert.asm +++ b/libavcodec/x86/fmtconvert.asm @@ -2,25 +2,25 @@ ;* x86 optimized Format Conversion Utils ;* Copyright (c) 2008 Loren Merritt ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_TEXT diff --git a/libavcodec/x86/fmtconvert_mmx.c b/libavcodec/x86/fmtconvert_mmx.c index 42cb0bc85b..ca0b29344a 100644 --- a/libavcodec/x86/fmtconvert_mmx.c +++ b/libavcodec/x86/fmtconvert_mmx.c @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001 Fabrice Bellard * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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> diff --git a/libavcodec/x86/h264_chromamc.asm b/libavcodec/x86/h264_chromamc.asm index 8b621fa8bb..fc615c7bc7 100644 --- a/libavcodec/x86/h264_chromamc.asm +++ b/libavcodec/x86/h264_chromamc.asm @@ -3,25 +3,25 @@ ;* Copyright (c) 2005 Zoltan Hidvegi <hzoli -a- hzoli -d- com>, ;* 2005-2008 Loren Merritt ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm index f264edb65f..bff6597d55 100644 --- a/libavcodec/x86/h264_deblock.asm +++ b/libavcodec/x86/h264_deblock.asm @@ -7,25 +7,25 @@ ;* Jason Garrett-Glaser <darkshikari@gmail.com> ;* Oskar Arvidsson <oskar@irock.se> ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION .text @@ -386,8 +386,10 @@ cglobal deblock_h_luma_8_%1, 5,7 INIT_XMM DEBLOCK_LUMA sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA avx +%endif %else @@ -505,8 +507,10 @@ INIT_MMX DEBLOCK_LUMA mmxext, v8, 8 INIT_XMM DEBLOCK_LUMA sse2, v, 16 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA avx, v, 16 +%endif %endif ; ARCH @@ -777,8 +781,10 @@ cglobal deblock_h_luma_intra_8_%1, 2,4 INIT_XMM DEBLOCK_LUMA_INTRA sse2, v +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA_INTRA avx , v +%endif %if ARCH_X86_64 == 0 INIT_MMX DEBLOCK_LUMA_INTRA mmxext, v8 diff --git a/libavcodec/x86/h264_deblock_10bit.asm b/libavcodec/x86/h264_deblock_10bit.asm index a4ccafc68f..680abee06d 100644 --- a/libavcodec/x86/h264_deblock_10bit.asm +++ b/libavcodec/x86/h264_deblock_10bit.asm @@ -24,8 +24,8 @@ ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA @@ -165,7 +165,7 @@ cglobal deblock_v_luma_10_%1, 5,5,8*(mmsize/16) SUB rsp, pad shl r2d, 2 shl r3d, 2 - LOAD_AB m4, m5, r2, r3 + LOAD_AB m4, m5, r2d, r3d mov r3, 32/mmsize mov r2, r0 sub r0, r1 @@ -222,7 +222,7 @@ cglobal deblock_h_luma_10_%1, 5,6,8*(mmsize/16) SUB rsp, pad shl r2d, 2 shl r3d, 2 - LOAD_AB m4, m5, r2, r3 + LOAD_AB m4, m5, r2d, r3d mov r3, r1 mova am, m4 add r3, r1 @@ -352,7 +352,7 @@ cglobal deblock_v_luma_10_%1, 5,5,15 %define mask2 m11 shl r2d, 2 shl r3d, 2 - LOAD_AB m12, m13, r2, r3 + LOAD_AB m12, m13, r2d, r3d mov r2, r0 sub r0, r1 sub r0, r1 @@ -380,7 +380,7 @@ cglobal deblock_v_luma_10_%1, 5,5,15 cglobal deblock_h_luma_10_%1, 5,7,15 shl r2d, 2 shl r3d, 2 - LOAD_AB m12, m13, r2, r3 + LOAD_AB m12, m13, r2d, r3d mov r2, r1 add r2, r1 add r2, r1 @@ -419,9 +419,11 @@ cglobal deblock_h_luma_10_%1, 5,7,15 INIT_XMM DEBLOCK_LUMA_64 sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA_64 avx %endif +%endif %macro SWAPMOVA 2 %ifid %1 @@ -714,8 +716,10 @@ cglobal deblock_h_luma_intra_10_%1, 4,7,16 INIT_XMM DEBLOCK_LUMA_INTRA_64 sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA_INTRA_64 avx +%endif %endif @@ -799,10 +803,12 @@ DEBLOCK_LUMA_INTRA mmxext INIT_XMM DEBLOCK_LUMA sse2 DEBLOCK_LUMA_INTRA sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA avx DEBLOCK_LUMA_INTRA avx %endif +%endif ; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp ; out: %1=p0', %2=q0' @@ -858,7 +864,7 @@ cglobal deblock_v_chroma_10_%1, 5,7-(mmsize/16),8*(mmsize/16) .loop: %endif CHROMA_V_LOAD r5 - LOAD_AB m4, m5, r2, r3 + LOAD_AB m4, m5, r2d, r3d LOAD_MASK m0, m1, m2, m3, m4, m5, m7, m6, m4 pxor m4, m4 CHROMA_V_LOAD_TC m6, r4 @@ -892,7 +898,7 @@ cglobal deblock_v_chroma_intra_10_%1, 4,6-(mmsize/16),8*(mmsize/16) .loop: %endif CHROMA_V_LOAD r4 - LOAD_AB m4, m5, r2, r3 + LOAD_AB m4, m5, r2d, r3d LOAD_MASK m0, m1, m2, m3, m4, m5, m7, m6, m4 CHROMA_DEBLOCK_P0_Q0_INTRA m1, m2, m0, m3, m7, m5, m6 CHROMA_V_STORE @@ -913,5 +919,7 @@ DEBLOCK_CHROMA mmxext %endif INIT_XMM DEBLOCK_CHROMA sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_CHROMA avx +%endif diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index e195e04879..510f726ba1 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -2,20 +2,20 @@ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm index 5e8c0edfa6..25f4755fa1 100644 --- a/libavcodec/x86/h264_idct.asm +++ b/libavcodec/x86/h264_idct.asm @@ -9,25 +9,25 @@ ;* Holger Lubitz <hal@duncan.ol.sub.de> ;* Min Chen <chenm001.163.com> ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;***************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA diff --git a/libavcodec/x86/h264_idct_10bit.asm b/libavcodec/x86/h264_idct_10bit.asm index 501c2a4da1..27a18f47da 100644 --- a/libavcodec/x86/h264_idct_10bit.asm +++ b/libavcodec/x86/h264_idct_10bit.asm @@ -22,8 +22,8 @@ ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA diff --git a/libavcodec/x86/h264_intrapred.asm b/libavcodec/x86/h264_intrapred.asm index c6b4386627..f97d051865 100644 --- a/libavcodec/x86/h264_intrapred.asm +++ b/libavcodec/x86/h264_intrapred.asm @@ -5,25 +5,25 @@ ;* Copyright (c) 2010 Loren Merritt ;* Copyright (c) 2010 Ronald S. Bultje ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA diff --git a/libavcodec/x86/h264_intrapred_10bit.asm b/libavcodec/x86/h264_intrapred_10bit.asm index 1423b561ac..79fa23e71d 100644 --- a/libavcodec/x86/h264_intrapred_10bit.asm +++ b/libavcodec/x86/h264_intrapred_10bit.asm @@ -22,8 +22,8 @@ ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c index 41e611ecd1..540ec87ad3 100644 --- a/libavcodec/x86/h264_intrapred_init.c +++ b/libavcodec/x86/h264_intrapred_init.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2010 Jason Garrett-Glaser * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/h264_qpel_mmx.c b/libavcodec/x86/h264_qpel_mmx.c index b7a4183c1b..807d8548d6 100644 --- a/libavcodec/x86/h264_qpel_mmx.c +++ b/libavcodec/x86/h264_qpel_mmx.c @@ -2,20 +2,20 @@ * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt * Copyright (c) 2011 Daniel Kang * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm index 1c40e49eaa..b2fb663e4d 100644 --- a/libavcodec/x86/h264_weight.asm +++ b/libavcodec/x86/h264_weight.asm @@ -4,24 +4,24 @@ ;* Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt ;* Copyright (C) 2010 Eli Friedman <eli.friedman@gmail.com> ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" +%include "libavutil/x86/x86inc.asm" SECTION .text @@ -253,6 +253,13 @@ BIWEIGHT_FUNC_HALF_MM 8, 8, sse2 add off_regd, 1 or off_regd, 1 add r4, 1 + cmp r5, 128 + jne .normal + sar r5, 1 + sar r6, 1 + sar off_regd, 1 + sub r4, 1 +.normal movd m4, r5d movd m0, r6d movd m5, off_regd diff --git a/libavcodec/x86/h264dsp_mmx.c b/libavcodec/x86/h264dsp_mmx.c index dcd918013c..b337462aec 100644 --- a/libavcodec/x86/h264dsp_mmx.c +++ b/libavcodec/x86/h264dsp_mmx.c @@ -1,20 +1,20 @@ /* * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -419,7 +419,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chrom c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16_ssse3; c->biweight_h264_pixels_tab[1]= ff_h264_biweight_8_ssse3; } - if (mm_flags&AV_CPU_FLAG_AVX) { + if (HAVE_AVX && mm_flags&AV_CPU_FLAG_AVX) { #if HAVE_ALIGNED_STACK c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_avx; c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_avx; diff --git a/libavcodec/x86/idct_mmx_xvid.c b/libavcodec/x86/idct_mmx_xvid.c index 139798e44b..1b48ab52bb 100644 --- a/libavcodec/x86/idct_mmx_xvid.c +++ b/libavcodec/x86/idct_mmx_xvid.c @@ -22,20 +22,20 @@ * * conversion to gcc syntax by Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software Foundation, + * 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/libavcodec/x86/idct_sse2_xvid.c b/libavcodec/x86/idct_sse2_xvid.c index 968b400c6d..fc75a57519 100644 --- a/libavcodec/x86/idct_sse2_xvid.c +++ b/libavcodec/x86/idct_sse2_xvid.c @@ -9,7 +9,7 @@ * * Originally from dct/x86_asm/fdct_sse2_skal.asm in Xvid. * - * This file is part of Libav. + * This file is part of FFmpeg. * * Vertical pass is an implementation of the scheme: * Loeffler C., Ligtenberg A., and Moschytz C.S.: @@ -23,18 +23,18 @@ * * More details at http://skal.planet-d.net/coding/dct.html * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software Foundation, + * 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/libavcodec/x86/idct_xvid.h b/libavcodec/x86/idct_xvid.h index 495d2caaf9..be91d1c68a 100644 --- a/libavcodec/x86/idct_xvid.h +++ b/libavcodec/x86/idct_xvid.h @@ -1,20 +1,20 @@ /* * XVID MPEG-4 VIDEO CODEC * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/imdct36_sse.asm b/libavcodec/x86/imdct36_sse.asm index 937a2cc416..e0205ec746 100644 --- a/libavcodec/x86/imdct36_sse.asm +++ b/libavcodec/x86/imdct36_sse.asm @@ -371,8 +371,10 @@ DEFINE_IMDCT INIT_XMM ssse3 DEFINE_IMDCT +%ifdef HAVE_AVX INIT_XMM avx DEFINE_IMDCT +%endif INIT_XMM sse @@ -717,5 +719,7 @@ cglobal four_imdct36_float, 5,5,16, out, buf, in, win, tmp INIT_XMM sse DEFINE_FOUR_IMDCT +%ifdef HAVE_AVX INIT_XMM avx DEFINE_FOUR_IMDCT +%endif diff --git a/libavcodec/x86/lpc_mmx.c b/libavcodec/x86/lpc_mmx.c index d41c19b443..1c202e2ccc 100644 --- a/libavcodec/x86/lpc_mmx.c +++ b/libavcodec/x86/lpc_mmx.c @@ -2,20 +2,20 @@ * MMX optimized LPC DSP utils * Copyright (c) 2007 Loren Merritt * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/mathops.h b/libavcodec/x86/mathops.h index 50b0283151..33d9a6c8ff 100644 --- a/libavcodec/x86/mathops.h +++ b/libavcodec/x86/mathops.h @@ -2,20 +2,20 @@ * simple math operations * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/mlpdsp.c b/libavcodec/x86/mlpdsp.c index 400855d7c4..7ea77fc1b8 100644 --- a/libavcodec/x86/mlpdsp.c +++ b/libavcodec/x86/mlpdsp.c @@ -2,20 +2,20 @@ * MLP DSP functions x86-optimized * Copyright (c) 2009 Ramiro Polla * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/motion_est_mmx.c b/libavcodec/x86/motion_est_mmx.c index 948af98ffb..fefef41058 100644 --- a/libavcodec/x86/motion_est_mmx.c +++ b/libavcodec/x86/motion_est_mmx.c @@ -5,20 +5,20 @@ * * mostly by Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/mpegaudiodec_mmx.c b/libavcodec/x86/mpegaudiodec_mmx.c index 06ffbca90a..b85b8a5548 100644 --- a/libavcodec/x86/mpegaudiodec_mmx.c +++ b/libavcodec/x86/mpegaudiodec_mmx.c @@ -2,20 +2,20 @@ * MMX optimized MP3 decoding functions * Copyright (c) 2010 Vitor Sessak * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -192,11 +192,17 @@ static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in, \ } \ } +#if HAVE_YASM +#if HAVE_SSE DECL_IMDCT_BLOCKS(sse,sse) DECL_IMDCT_BLOCKS(sse2,sse) DECL_IMDCT_BLOCKS(sse3,sse) DECL_IMDCT_BLOCKS(ssse3,sse) +#endif +#if HAVE_AVX DECL_IMDCT_BLOCKS(avx,avx) +#endif +#endif void ff_mpadsp_init_mmx(MPADSPContext *s) { @@ -220,8 +226,11 @@ void ff_mpadsp_init_mmx(MPADSPContext *s) s->apply_window_float = apply_window_mp3; } #if HAVE_YASM - if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) { + if (0) { +#if HAVE_AVX + } else if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) { s->imdct36_blocks_float = imdct36_blocks_avx; +#endif #if HAVE_SSE } else if (mm_flags & AV_CPU_FLAG_SSSE3) { s->imdct36_blocks_float = imdct36_blocks_ssse3; diff --git a/libavcodec/x86/mpegvideo_mmx.c b/libavcodec/x86/mpegvideo_mmx.c index 7dd9a66783..3b8513d3f0 100644 --- a/libavcodec/x86/mpegvideo_mmx.c +++ b/libavcodec/x86/mpegvideo_mmx.c @@ -5,20 +5,20 @@ * 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 Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/mpegvideo_mmx_template.c b/libavcodec/x86/mpegvideo_mmx_template.c index 0b6cff3540..6569ba41eb 100644 --- a/libavcodec/x86/mpegvideo_mmx_template.c +++ b/libavcodec/x86/mpegvideo_mmx_template.c @@ -3,20 +3,20 @@ * * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -110,10 +110,15 @@ static int RENAME(dct_quantize)(MpegEncContext *s, if (s->mb_intra) { int dummy; - if (n < 4) + if (n < 4){ q = s->y_dc_scale; - else + bias = s->q_intra_matrix16[qscale][1]; + qmat = s->q_intra_matrix16[qscale][0]; + }else{ q = s->c_dc_scale; + bias = s->q_chroma_intra_matrix16[qscale][1]; + qmat = s->q_chroma_intra_matrix16[qscale][0]; + } /* note: block[0] is assumed to be positive */ if (!s->h263_aic) { __asm__ volatile ( @@ -128,8 +133,6 @@ static int RENAME(dct_quantize)(MpegEncContext *s, block[0]=0; //avoid fake overflow // temp_block[0] = (block[0] + (q >> 1)) / q; last_non_zero_p1 = 1; - bias = s->q_intra_matrix16[qscale][1]; - qmat = s->q_intra_matrix16[qscale][0]; } else { last_non_zero_p1 = 0; bias = s->q_inter_matrix16[qscale][1]; diff --git a/libavcodec/x86/pngdsp-init.c b/libavcodec/x86/pngdsp-init.c index 136e92eed0..f122b242fb 100644 --- a/libavcodec/x86/pngdsp-init.c +++ b/libavcodec/x86/pngdsp-init.c @@ -2,20 +2,20 @@ * x86 PNG optimizations. * Copyright (c) 2008 Loren Merrit <lorenm@u.washington.edu> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/pngdsp.asm b/libavcodec/x86/pngdsp.asm index d6e6374c89..9c588a97e9 100644 --- a/libavcodec/x86/pngdsp.asm +++ b/libavcodec/x86/pngdsp.asm @@ -28,7 +28,7 @@ SECTION_RODATA cextern pw_255 -section .text align=16 +SECTION_TEXT 16 ; %1 = nr. of xmm registers used %macro ADD_BYTES_FN 1 @@ -43,12 +43,12 @@ cglobal add_bytes_l2, 4, 6, %1, dst, src1, src2, wa, w, i and waq, ~(mmsize*2-1) jmp .end_v .loop_v: - mova m0, [src1q+iq] - mova m1, [src1q+iq+mmsize] - paddb m0, [src2q+iq] - paddb m1, [src2q+iq+mmsize] - mova [dstq+iq ], m0 - mova [dstq+iq+mmsize], m1 + movu m0, [src2q+iq] + movu m1, [src2q+iq+mmsize] + paddb m0, [src1q+iq] + paddb m1, [src1q+iq+mmsize] + movu [dstq+iq ], m0 + movu [dstq+iq+mmsize], m1 add iq, mmsize*2 .end_v: cmp iq, waq @@ -60,8 +60,8 @@ cglobal add_bytes_l2, 4, 6, %1, dst, src1, src2, wa, w, i and waq, ~7 jmp .end_l .loop_l: - movq mm0, [src1q+iq] - paddb mm0, [src2q+iq] + movq mm0, [src2q+iq] + paddb mm0, [src1q+iq] movq [dstq+iq ], mm0 add iq, 8 .end_l: diff --git a/libavcodec/x86/proresdsp-init.c b/libavcodec/x86/proresdsp-init.c index f202f9f0cf..c4aeb7f503 100644 --- a/libavcodec/x86/proresdsp-init.c +++ b/libavcodec/x86/proresdsp-init.c @@ -29,11 +29,14 @@ void ff_prores_idct_put_10_sse4(uint16_t *dst, int linesize, void ff_prores_idct_put_10_avx (uint16_t *dst, int linesize, DCTELEM *block, const int16_t *qmat); -void ff_proresdsp_x86_init(ProresDSPContext *dsp) +void ff_proresdsp_x86_init(ProresDSPContext *dsp, AVCodecContext *avctx) { #if ARCH_X86_64 && HAVE_YASM int flags = av_get_cpu_flags(); + if(avctx->flags & CODEC_FLAG_BITEXACT) + return; + if (flags & AV_CPU_FLAG_SSE2) { dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM; dsp->idct_put = ff_prores_idct_put_10_sse2; diff --git a/libavcodec/x86/proresdsp.asm b/libavcodec/x86/proresdsp.asm index 9b2e11eb5d..75448e06a9 100644 --- a/libavcodec/x86/proresdsp.asm +++ b/libavcodec/x86/proresdsp.asm @@ -1,23 +1,24 @@ ;****************************************************************************** ;* x86-SIMD-optimized IDCT for prores -;* this is identical to "simple" IDCT except for the clip range +;* this is identical to "simple" IDCT written by Michael Niedermayer +;* except for the clip range ;* ;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com> ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** @@ -48,10 +49,10 @@ w1_plus_w5: times 4 dw W1sh2, +W5sh2 w5_min_w1: times 4 dw W5sh2, -W1sh2 w5_plus_w7: times 4 dw W5sh2, +W7sh2 w7_min_w5: times 4 dw W7sh2, -W5sh2 -row_round: times 8 dw (1<<14) +pw_88: times 8 dw 0x2008 +cextern pw_1 cextern pw_4 -cextern pw_8 cextern pw_512 cextern pw_1019 @@ -93,14 +94,12 @@ section .text align=16 ; a2 -= W6 * row[2]; ; a3 -= W2 * row[2]; %ifidn %1, col - paddw m10,[pw_8] + paddw m10,[pw_88] %endif - SBUTTERFLY3 wd, 0, 1, 10, 8 ; { row[0], row[2] }[0-3]/[4-7] %ifidn %1, row - psubw m10,[row_round] + paddw m10,[pw_1] %endif - SIGNEXTEND m8, m9, m14 ; { row[2] }[0-3] / [4-7] - SIGNEXTEND m10, m11, m14 ; { row[0] }[0-3] / [4-7] + SBUTTERFLY3 wd, 0, 1, 10, 8 ; { row[0], row[2] }[0-3]/[4-7] pmaddwd m2, m0, [w4_plus_w6] pmaddwd m3, m1, [w4_plus_w6] pmaddwd m4, m0, [w4_min_w6] @@ -109,75 +108,33 @@ section .text align=16 pmaddwd m7, m1, [w4_min_w2] pmaddwd m0, [w4_plus_w2] pmaddwd m1, [w4_plus_w2] - pslld m2, 2 - pslld m3, 2 - pslld m4, 2 - pslld m5, 2 - pslld m6, 2 - pslld m7, 2 - pslld m0, 2 - pslld m1, 2 ; a0: -1*row[0]-1*row[2] ; a1: -1*row[0] ; a2: -1*row[0] ; a3: -1*row[0]+1*row[2] - psubd m2, m10 ; a1[0-3] - psubd m3, m11 ; a1[4-7] - psubd m4, m10 ; a2[0-3] - psubd m5, m11 ; a2[4-7] - psubd m0, m10 - psubd m1, m11 - psubd m6, m10 - psubd m7, m11 - psubd m0, m8 ; a0[0-3] - psubd m1, m9 ; a0[4-7] - paddd m6, m8 ; a3[0-3] - paddd m7, m9 ; a3[4-7] ; a0 += W4*row[4] + W6*row[6]; i.e. -1*row[4] ; a1 -= W4*row[4] + W2*row[6]; i.e. -1*row[4]-1*row[6] ; a2 -= W4*row[4] - W2*row[6]; i.e. -1*row[4]+1*row[6] ; a3 += W4*row[4] - W6*row[6]; i.e. -1*row[4] SBUTTERFLY3 wd, 8, 9, 13, 12 ; { row[4], row[6] }[0-3]/[4-7] - SIGNEXTEND m13, m14, m10 ; { row[4] }[0-3] / [4-7] pmaddwd m10, m8, [w4_plus_w6] pmaddwd m11, m9, [w4_plus_w6] - pslld m10, 2 - pslld m11, 2 - psubd m10, m13 - psubd m11, m14 paddd m0, m10 ; a0[0-3] paddd m1, m11 ; a0[4-7] pmaddwd m10, m8, [w4_min_w6] pmaddwd m11, m9, [w4_min_w6] - pslld m10, 2 - pslld m11, 2 - psubd m10, m13 - psubd m11, m14 paddd m6, m10 ; a3[0-3] paddd m7, m11 ; a3[4-7] pmaddwd m10, m8, [w4_min_w2] pmaddwd m11, m9, [w4_min_w2] pmaddwd m8, [w4_plus_w2] pmaddwd m9, [w4_plus_w2] - pslld m10, 2 - pslld m11, 2 - pslld m8, 2 - pslld m9, 2 - psubd m10, m13 - psubd m11, m14 - psubd m8, m13 - psubd m9, m14 psubd m4, m10 ; a2[0-3] intermediate psubd m5, m11 ; a2[4-7] intermediate psubd m2, m8 ; a1[0-3] intermediate psubd m3, m9 ; a1[4-7] intermediate - SIGNEXTEND m12, m13, m10 ; { row[6] }[0-3] / [4-7] - psubd m4, m12 ; a2[0-3] - psubd m5, m13 ; a2[4-7] - paddd m2, m12 ; a1[0-3] - paddd m3, m13 ; a1[4-7] ; load/store mova [r2+ 0], m0 @@ -208,8 +165,6 @@ section .text align=16 ; b3 = MUL(W7, row[1]); ; MAC(b3, -W5, row[3]); SBUTTERFLY3 wd, 0, 1, 10, 8 ; { row[1], row[3] }[0-3]/[4-7] - SIGNEXTEND m10, m11, m12 ; { row[1] }[0-3] / [4-7] - SIGNEXTEND m8, m9, m12 ; { row[3] }[0-3] / [4-7] pmaddwd m2, m0, [w3_min_w7] pmaddwd m3, m1, [w3_min_w7] pmaddwd m4, m0, [w5_min_w1] @@ -218,35 +173,11 @@ section .text align=16 pmaddwd m7, m1, [w7_min_w5] pmaddwd m0, [w1_plus_w3] pmaddwd m1, [w1_plus_w3] - pslld m2, 2 - pslld m3, 2 - pslld m4, 2 - pslld m5, 2 - pslld m6, 2 - pslld m7, 2 - pslld m0, 2 - pslld m1, 2 ; b0: +1*row[1]+2*row[3] ; b1: +2*row[1]-1*row[3] ; b2: -1*row[1]-1*row[3] ; b3: +1*row[1]+1*row[3] - psubd m2, m8 - psubd m3, m9 - paddd m0, m8 - paddd m1, m9 - paddd m8, m10 ; { row[1] + row[3] }[0-3] - paddd m9, m11 ; { row[1] + row[3] }[4-7] - paddd m10, m10 - paddd m11, m11 - paddd m0, m8 ; b0[0-3] - paddd m1, m9 ; b0[4-7] - paddd m2, m10 ; b1[0-3] - paddd m3, m11 ; b2[4-7] - psubd m4, m8 ; b2[0-3] - psubd m5, m9 ; b2[4-7] - paddd m6, m8 ; b3[0-3] - paddd m7, m9 ; b3[4-7] ; MAC(b0, W5, row[5]); ; MAC(b0, W7, row[7]); @@ -257,38 +188,16 @@ section .text align=16 ; MAC(b3, W3, row[5]); ; MAC(b3, -W1, row[7]); SBUTTERFLY3 wd, 8, 9, 13, 14 ; { row[5], row[7] }[0-3]/[4-7] - SIGNEXTEND m13, m12, m11 ; { row[5] }[0-3] / [4-7] - SIGNEXTEND m14, m11, m10 ; { row[7] }[0-3] / [4-7] ; b0: -1*row[5]+1*row[7] ; b1: -1*row[5]+1*row[7] ; b2: +1*row[5]+2*row[7] ; b3: +2*row[5]-1*row[7] - paddd m4, m13 - paddd m5, m12 - paddd m6, m13 - paddd m7, m12 - psubd m13, m14 ; { row[5] - row[7] }[0-3] - psubd m12, m11 ; { row[5] - row[7] }[4-7] - paddd m14, m14 - paddd m11, m11 - psubd m0, m13 - psubd m1, m12 - psubd m2, m13 - psubd m3, m12 - paddd m4, m14 - paddd m5, m11 - paddd m6, m13 - paddd m7, m12 pmaddwd m10, m8, [w1_plus_w5] pmaddwd m11, m9, [w1_plus_w5] pmaddwd m12, m8, [w5_plus_w7] pmaddwd m13, m9, [w5_plus_w7] - pslld m10, 2 - pslld m11, 2 - pslld m12, 2 - pslld m13, 2 psubd m2, m10 ; b1[0-3] psubd m3, m11 ; b1[4-7] paddd m0, m12 ; b0[0-3] @@ -297,10 +206,6 @@ section .text align=16 pmaddwd m13, m9, [w7_plus_w3] pmaddwd m8, [w3_min_w1] pmaddwd m9, [w3_min_w1] - pslld m12, 2 - pslld m13, 2 - pslld m8, 2 - pslld m9, 2 paddd m4, m12 ; b2[0-3] paddd m5, m13 ; b2[4-7] paddd m6, m8 ; b3[0-3] @@ -347,7 +252,7 @@ cglobal prores_idct_put_10_%1, 4, 4, %2 pmullw m13,[r3+64] pmullw m12,[r3+96] - IDCT_1D row, 17, %1 + IDCT_1D row, 15, %1 ; transpose for second part of IDCT TRANSPOSE8x8W 8, 0, 1, 2, 4, 11, 9, 10, 3 @@ -362,20 +267,11 @@ cglobal prores_idct_put_10_%1, 4, 4, %2 ; for (i = 0; i < 8; i++) ; idctSparseColAdd(dest + i, line_size, block + i); - IDCT_1D col, 20, %1 + IDCT_1D col, 18, %1 ; clip/store - mova m6, [pw_512] mova m3, [pw_4] mova m5, [pw_1019] - paddw m8, m6 - paddw m0, m6 - paddw m1, m6 - paddw m2, m6 - paddw m4, m6 - paddw m11, m6 - paddw m9, m6 - paddw m10, m6 pmaxsw m8, m3 pmaxsw m0, m3 pmaxsw m1, m3 @@ -406,27 +302,13 @@ cglobal prores_idct_put_10_%1, 4, 4, %2 RET %endmacro -%macro signextend_sse2 3 ; dstlow, dsthigh, tmp - pxor %3, %3 - pcmpgtw %3, %1 - mova %2, %1 - punpcklwd %1, %3 - punpckhwd %2, %3 -%endmacro - -%macro signextend_sse4 2-3 ; dstlow, dsthigh - movhlps %2, %1 - pmovsxwd %1, %1 - pmovsxwd %2, %2 -%endmacro - INIT_XMM -%define SIGNEXTEND signextend_sse2 idct_put_fn sse2, 16 INIT_XMM -%define SIGNEXTEND signextend_sse4 idct_put_fn sse4, 16 +%ifdef HAVE_AVX INIT_AVX idct_put_fn avx, 16 +%endif %endif diff --git a/libavcodec/x86/rv34dsp.asm b/libavcodec/x86/rv34dsp.asm index 2d2f6e19e6..1e152b7d68 100644 --- a/libavcodec/x86/rv34dsp.asm +++ b/libavcodec/x86/rv34dsp.asm @@ -39,7 +39,7 @@ SECTION .text cglobal rv34_idct_%1_mmx2, 1, 2, 0 movsx r1, word [r0] IDCT_DC r1 - movd m0, r1 + movd m0, r1d pshufw m0, m0, 0 movq [r0+ 0], m0 movq [r0+ 8], m0 @@ -59,7 +59,7 @@ cglobal rv34_idct_dc_add_mmx, 3, 3 ; calculate DC IDCT_DC_ROUND r2 pxor m1, m1 - movd m0, r2 + movd m0, r2d psubw m1, m0 packuswb m0, m0 packuswb m1, m1 @@ -96,7 +96,7 @@ cglobal rv34_idct_dc_add_sse4, 3, 3, 6 pxor m1, m1 ; calculate DC - movd m0, r2 + movd m0, r2d lea r2, [r0+r1*2] movd m2, [r0] movd m3, [r0+r1] diff --git a/libavcodec/x86/rv40dsp.asm b/libavcodec/x86/rv40dsp.asm index bff3e7b96a..c13e9f03d9 100644 --- a/libavcodec/x86/rv40dsp.asm +++ b/libavcodec/x86/rv40dsp.asm @@ -164,8 +164,8 @@ cglobal rv40_weight_func_%1, 6, 7, %2 ; Use result of test now jz .loop_512 - movd m2, r3 - movd m3, r4 + movd m2, r3d + movd m3, r4d SPLATW m2, m2 SPLATW m3, m3 @@ -178,8 +178,8 @@ cglobal rv40_weight_func_%1, 6, 7, %2 .loop_512: sar r3, 9 sar r4, 9 - movd m2, r3 - movd m3, r4 + movd m2, r3d + movd m3, r4d %if cpuflag(ssse3) punpcklbw m3, m2 SPLATW m3, m3 diff --git a/libavcodec/x86/simple_idct_mmx.c b/libavcodec/x86/simple_idct_mmx.c index dc285cf728..db479ce257 100644 --- a/libavcodec/x86/simple_idct_mmx.c +++ b/libavcodec/x86/simple_idct_mmx.c @@ -3,20 +3,20 @@ * * Copyright (c) 2001, 2002 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavcodec/dsputil.h" diff --git a/libavcodec/x86/snowdsp_mmx.c b/libavcodec/x86/snowdsp_mmx.c index 3e6bc99796..f107d55e87 100644 --- a/libavcodec/x86/snowdsp_mmx.c +++ b/libavcodec/x86/snowdsp_mmx.c @@ -2,20 +2,20 @@ * MMX and SSE2 optimized snow DSP utils * Copyright (c) 2005-2006 Robert Edele <yartrebo@earthlink.net> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -675,14 +675,14 @@ static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM #define snow_inner_add_yblock_sse2_end_8\ "sal $1, %%"REG_c" \n\t"\ - "add $"PTR_SIZE"*2, %1 \n\t"\ + "add"OPSIZE" $"PTR_SIZE"*2, %1 \n\t"\ snow_inner_add_yblock_sse2_end_common1\ "sar $1, %%"REG_c" \n\t"\ "sub $2, %2 \n\t"\ snow_inner_add_yblock_sse2_end_common2 #define snow_inner_add_yblock_sse2_end_16\ - "add $"PTR_SIZE"*1, %1 \n\t"\ + "add"OPSIZE" $"PTR_SIZE"*1, %1 \n\t"\ snow_inner_add_yblock_sse2_end_common1\ "dec %2 \n\t"\ snow_inner_add_yblock_sse2_end_common2 diff --git a/libavcodec/x86/v210-init.c b/libavcodec/x86/v210-init.c new file mode 100644 index 0000000000..425c6284c5 --- /dev/null +++ b/libavcodec/x86/v210-init.c @@ -0,0 +1,48 @@ +/* + * This file is part of Libav. + * + * Libav 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. + * + * Libav 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 Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/cpu.h" +#include "libavcodec/v210dec.h" + +extern void ff_v210_planar_unpack_unaligned_ssse3(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_unaligned_avx(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); + +extern void ff_v210_planar_unpack_aligned_ssse3(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_aligned_avx(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); + +av_cold void v210_x86_init(V210DecContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + +#if HAVE_YASM + if (s->aligned_input) { + if (cpu_flags & AV_CPU_FLAG_SSSE3) + s->unpack_frame = ff_v210_planar_unpack_aligned_ssse3; + + if (HAVE_AVX && cpu_flags & AV_CPU_FLAG_AVX) + s->unpack_frame = ff_v210_planar_unpack_aligned_avx; + } + else { + if (cpu_flags & AV_CPU_FLAG_SSSE3) + s->unpack_frame = ff_v210_planar_unpack_unaligned_ssse3; + + if (HAVE_AVX && cpu_flags & AV_CPU_FLAG_AVX) + s->unpack_frame = ff_v210_planar_unpack_unaligned_avx; + } +#endif +} diff --git a/libavcodec/x86/v210.asm b/libavcodec/x86/v210.asm new file mode 100644 index 0000000000..9ce17c2ed5 --- /dev/null +++ b/libavcodec/x86/v210.asm @@ -0,0 +1,89 @@ +;****************************************************************************** +;* V210 SIMD unpack +;* Copyright (c) 2011 Loren Merritt <lorenm@u.washington.edu> +;* Copyright (c) 2011 Kieran Kunhya <kieran@kunhya.com> +;* +;* This file is part of Libav. +;* +;* Libav 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. +;* +;* Libav 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 Libav; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA + +v210_mask: times 4 dd 0x3ff +v210_mult: dw 64,4,64,4,64,4,64,4 +v210_luma_shuf: db 8,9,0,1,2,3,12,13,4,5,6,7,-1,-1,-1,-1 +v210_chroma_shuf: db 0,1,8,9,6,7,-1,-1,2,3,4,5,12,13,-1,-1 + +SECTION .text + +%macro v210_planar_unpack 2 + +; v210_planar_unpack(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width) +cglobal v210_planar_unpack_%1_%2, 5, 5 + movsxdifnidn r4, r4d + lea r1, [r1+2*r4] + add r2, r4 + add r3, r4 + neg r4 + + mova m3, [v210_mult] + mova m4, [v210_mask] + mova m5, [v210_luma_shuf] + mova m6, [v210_chroma_shuf] +.loop +%ifidn %1, unaligned + movu m0, [r0] +%else + mova m0, [r0] +%endif + + pmullw m1, m0, m3 + psrld m0, 10 + psrlw m1, 6 ; u0 v0 y1 y2 v1 u2 y4 y5 + pand m0, m4 ; y0 __ u1 __ y3 __ v2 __ + + shufps m2, m1, m0, 0x8d ; y1 y2 y4 y5 y0 __ y3 __ + pshufb m2, m5 ; y0 y1 y2 y3 y4 y5 __ __ + movu [r1+2*r4], m2 + + shufps m1, m0, 0xd8 ; u0 v0 v1 u2 u1 __ v2 __ + pshufb m1, m6 ; u0 u1 u2 __ v0 v1 v2 __ + movq [r2+r4], m1 + movhps [r3+r4], m1 + + add r0, mmsize + add r4, 6 + jl .loop + + REP_RET +%endmacro + +INIT_XMM +v210_planar_unpack unaligned, ssse3 +%ifdef HAVE_AVX +INIT_AVX +v210_planar_unpack unaligned, avx +%endif + +INIT_XMM +v210_planar_unpack aligned, ssse3 +%ifdef HAVE_AVX +INIT_AVX +v210_planar_unpack aligned, avx +%endif diff --git a/libavcodec/x86/vc1dsp_yasm.asm b/libavcodec/x86/vc1dsp_yasm.asm index 66f61dba6a..1eba3c1198 100644 --- a/libavcodec/x86/vc1dsp_yasm.asm +++ b/libavcodec/x86/vc1dsp_yasm.asm @@ -2,25 +2,25 @@ ;* VC1 deblocking optimizations ;* Copyright (c) 2009 David Conrad ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" cextern pw_4 cextern pw_5 diff --git a/libavcodec/x86/vp3dsp.asm b/libavcodec/x86/vp3dsp.asm index 791cc8ec35..99621fb062 100644 --- a/libavcodec/x86/vp3dsp.asm +++ b/libavcodec/x86/vp3dsp.asm @@ -2,25 +2,25 @@ ;* MMX/SSE2-optimized functions for the VP3 decoder ;* Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org> ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" ; MMX-optimized functions cribbed from the original VP3 source code. diff --git a/libavcodec/x86/vp56_arith.h b/libavcodec/x86/vp56_arith.h index be2dd30b8d..ddbf38b1a9 100644 --- a/libavcodec/x86/vp56_arith.h +++ b/libavcodec/x86/vp56_arith.h @@ -4,20 +4,20 @@ * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> * Copyright (C) 2010 Eli Friedman * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/vp56dsp.asm b/libavcodec/x86/vp56dsp.asm index 66a97f1593..2d409bfca1 100644 --- a/libavcodec/x86/vp56dsp.asm +++ b/libavcodec/x86/vp56dsp.asm @@ -3,25 +3,25 @@ ;* Copyright (C) 2009 Sebastien Lucas <sebastien.lucas@gmail.com> ;* Copyright (C) 2009 Zuxy Meng <zuxy.meng@gmail.com> ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" cextern pw_64 diff --git a/libavcodec/x86/vp56dsp_init.c b/libavcodec/x86/vp56dsp_init.c index 29892812ac..87fc935315 100644 --- a/libavcodec/x86/vp56dsp_init.c +++ b/libavcodec/x86/vp56dsp_init.c @@ -3,20 +3,20 @@ * Copyright (C) 2009 Sebastien Lucas <sebastien.lucas@gmail.com> * Copyright (C) 2009 Zuxy Meng <zuxy.meng@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/vp8dsp-init.c b/libavcodec/x86/vp8dsp-init.c index f5e89faa3c..a75fdf5bc5 100644 --- a/libavcodec/x86/vp8dsp-init.c +++ b/libavcodec/x86/vp8dsp-init.c @@ -3,20 +3,20 @@ * Copyright (c) 2010 Ronald S. Bultje <rsbultje@gmail.com> * Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm index 7d9ebc9463..833c88a1a0 100644 --- a/libavcodec/x86/vp8dsp.asm +++ b/libavcodec/x86/vp8dsp.asm @@ -3,25 +3,25 @@ ;* Copyright (c) 2010 Ronald S. Bultje <rsbultje@gmail.com> ;* Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com> ;* -;* This file is part of Libav. +;* This file is part of FFmpeg. ;* -;* Libav is free software; you can redistribute it and/or +;* 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. ;* -;* Libav is distributed in the hope that it will be useful, +;* 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 Libav; if not, write to the Free Software +;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%include "x86inc.asm" -%include "x86util.asm" +%include "libavutil/x86/x86inc.asm" +%include "libavutil/x86/x86util.asm" SECTION_RODATA diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 4c4721ada2..cfaca81e16 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -2,20 +2,20 @@ * Wing Commander/Xan Video Decoder * Copyright (C) 2003 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -91,6 +91,8 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) av_freep(&s->buffer1); return AVERROR(ENOMEM); } + avcodec_get_frame_defaults(&s->last_frame); + avcodec_get_frame_defaults(&s->current_frame); return 0; } @@ -533,7 +535,7 @@ static int xan_decode_frame(AVCodecContext *avctx, int g = gamma_lookup[*buf++]; int b = gamma_lookup[*buf++]; #endif - *tmpptr++ = (r << 16) | (g << 8) | b; + *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b; } s->palettes_count++; break; diff --git a/libavcodec/xiph.c b/libavcodec/xiph.c index 7c3c7100c6..0636f8ef59 100644 --- a/libavcodec/xiph.c +++ b/libavcodec/xiph.c @@ -1,20 +1,20 @@ /* - * Copyright (C) 2007 Libav Project + * Copyright (C) 2007 FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/xiph.h b/libavcodec/xiph.h index afaece7cee..cd8caa4810 100644 --- a/libavcodec/xiph.h +++ b/libavcodec/xiph.h @@ -1,20 +1,20 @@ /* - * Copyright (C) 2007 Libav Project + * Copyright (C) 2007 FFmpeg Project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/xl.c b/libavcodec/xl.c index 0ebc9467e0..78f34afa4e 100644 --- a/libavcodec/xl.c +++ b/libavcodec/xl.c @@ -2,20 +2,20 @@ * Miro VideoXL codec * Copyright (c) 2004 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -127,8 +127,9 @@ static int decode_frame(AVCodecContext *avctx, } static av_cold int decode_init(AVCodecContext *avctx){ -// VideoXLContext * const a = avctx->priv_data; + VideoXLContext * const a = avctx->priv_data; + avcodec_get_frame_defaults(&a->pic); avctx->pix_fmt= PIX_FMT_YUV411P; return 0; diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c index af87388928..5e0e59faa4 100644 --- a/libavcodec/xsubdec.c +++ b/libavcodec/xsubdec.c @@ -2,20 +2,20 @@ * XSUB subtitle decoder * Copyright (c) 2007 Reimar Döffinger * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -53,11 +53,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVSubtitle *sub = data; const uint8_t *buf_end = buf + buf_size; uint8_t *bitmap; - int w, h, x, y, rlelen, i; + int w, h, x, y, i; int64_t packet_time = 0; GetBitContext gb; - - memset(sub, 0, sizeof(*sub)); + int has_alpha = avctx->codec_tag == MKTAG('D','X','S','A'); // check that at least header fits if (buf_size < 27 + 7 * 2 + 4 * 3) { @@ -86,7 +85,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, // skip bottom right position, it gives no new information bytestream_get_le16(&buf); bytestream_get_le16(&buf); - rlelen = bytestream_get_le16(&buf); + // The following value is supposed to indicate the start offset + // (relative to the palette) of the data for the second field, + // however there are files where it has a bogus value and thus + // we just ignore it + bytestream_get_le16(&buf); // allocate sub and set values sub->rects = av_mallocz(sizeof(*sub->rects)); @@ -104,12 +107,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, for (i = 0; i < sub->rects[0]->nb_colors; i++) ((uint32_t*)sub->rects[0]->pict.data[1])[i] = bytestream_get_be24(&buf); // make all except background (first entry) non-transparent - for (i = 1; i < sub->rects[0]->nb_colors; i++) - ((uint32_t*)sub->rects[0]->pict.data[1])[i] |= 0xff000000; + for (i = 0; i < sub->rects[0]->nb_colors; i++) + ((uint32_t*)sub->rects[0]->pict.data[1])[i] |= (has_alpha ? *buf++ : (i ? 0xff : 0)) << 24; // process RLE-compressed data - rlelen = FFMIN(rlelen, buf_end - buf); - init_get_bits(&gb, buf, rlelen * 8); + init_get_bits(&gb, buf, (buf_end - buf) * 8); bitmap = sub->rects[0]->pict.data[0]; for (y = 0; y < h; y++) { // interlaced: do odd lines diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c index bd66f86501..4245f45bac 100644 --- a/libavcodec/xsubenc.c +++ b/libavcodec/xsubenc.c @@ -3,20 +3,20 @@ * Copyright (c) 2005 DivX, Inc. * Copyright (c) 2009 Bjorn Axelsson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -129,7 +129,7 @@ static int xsub_encode(AVCodecContext *avctx, unsigned char *buf, } // TODO: support multiple rects - if (h->num_rects > 1) + if (h->num_rects != 1) av_log(avctx, AV_LOG_WARNING, "Only single rects supported (%d in subtitle.)\n", h->num_rects); // TODO: render text-based subtitles into bitmaps diff --git a/libavcodec/xvmc.h b/libavcodec/xvmc.h index 1239015fcd..93ad8bb9a5 100644 --- a/libavcodec/xvmc.h +++ b/libavcodec/xvmc.h @@ -1,20 +1,20 @@ /* * Copyright (C) 2003 Ivan Kalvachev * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/xvmc_internal.h b/libavcodec/xvmc_internal.h index 3c6aed8361..04197cefae 100644 --- a/libavcodec/xvmc_internal.h +++ b/libavcodec/xvmc_internal.h @@ -1,20 +1,20 @@ /* * XVideo Motion Compensation internal functions * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * 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/libavcodec/xxan.c b/libavcodec/xxan.c index 4659d34972..de55d082ae 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -3,20 +3,20 @@ * Copyright (C) 2011 Konstantin Shishkov * based on work by Mike Melanson * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -129,7 +129,9 @@ static int xan_unpack(uint8_t *dest, const int dest_len, if (size + size2 > dest_end - dest) break; } - if (src + size > src_end || dest + size + size2 > dest_end) + if (src + size > src_end || + dest + size + size2 > dest_end || + dest + size - orig_dest < back ) return -1; bytestream_get_buffer(&src, dest, size); dest += size; @@ -194,6 +196,8 @@ static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) if (mode) { for (j = 0; j < avctx->height >> 1; j++) { for (i = 0; i < avctx->width >> 1; i++) { + if (src_end - src < 1) + return 0; val = *src++; if (val) { val = AV_RL16(table + (val << 1)); @@ -202,8 +206,6 @@ static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) U[i] = uval | (uval >> 5); V[i] = vval | (vval >> 5); } - if (src == src_end) - return 0; } U += s->pic.linesize[1]; V += s->pic.linesize[2]; @@ -214,6 +216,8 @@ static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) for (j = 0; j < avctx->height >> 2; j++) { for (i = 0; i < avctx->width >> 1; i += 2) { + if (src_end - src < 1) + return 0; val = *src++; if (val) { val = AV_RL16(table + (val << 1)); @@ -302,6 +306,9 @@ static int xan_decode_frame_type0(AVCodecContext *avctx, AVPacket *avpkt) corr_end - corr_off); if (dec_size < 0) dec_size = 0; + else + dec_size = FFMIN(dec_size, s->buffer_size/2 - 1); + for (i = 0; i < dec_size; i++) s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F; } @@ -371,7 +378,7 @@ static int xan_decode_frame(AVCodecContext *avctx, int ftype; int ret; - s->pic.reference = 1; + s->pic.reference = 3; s->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; diff --git a/libavcodec/y41pdec.c b/libavcodec/y41pdec.c new file mode 100644 index 0000000000..e66546b0fa --- /dev/null +++ b/libavcodec/y41pdec.c @@ -0,0 +1,116 @@ +/* + * y41p decoder + * + * Copyright (c) 2012 Paul B Mahol + * + * 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 av_cold int y41p_decode_init(AVCodecContext *avctx) +{ + avctx->pix_fmt = PIX_FMT_YUV411P; + avctx->bits_per_raw_sample = 12; + + if (avctx->width & 7) { + av_log(avctx, AV_LOG_WARNING, "y41p requires width to be divisible by 8.\n"); + } + + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int y41p_decode_frame(AVCodecContext *avctx, void *data, + int *data_size, AVPacket *avpkt) +{ + AVFrame *pic = avctx->coded_frame; + uint8_t *src = avpkt->data; + uint8_t *y, *u, *v; + int i, j; + + if (pic->data[0]) + avctx->release_buffer(avctx, pic); + + if (avpkt->size < 1.5 * avctx->height * avctx->width) { + av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); + return AVERROR(EINVAL); + } + + pic->reference = 0; + + if (avctx->get_buffer(avctx, pic) < 0) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); + return AVERROR(ENOMEM); + } + + pic->key_frame = 1; + pic->pict_type = AV_PICTURE_TYPE_I; + + for (i = avctx->height - 1; i >= 0 ; i--) { + y = &pic->data[0][i * pic->linesize[0]]; + u = &pic->data[1][i * pic->linesize[1]]; + v = &pic->data[2][i * pic->linesize[2]]; + for (j = 0; j < avctx->width; j += 8) { + *(u++) = *src++; + *(y++) = *src++; + *(v++) = *src++; + *(y++) = *src++; + + *(u++) = *src++; + *(y++) = *src++; + *(v++) = *src++; + *(y++) = *src++; + + *(y++) = *src++; + *(y++) = *src++; + *(y++) = *src++; + *(y++) = *src++; + } + } + + *data_size = sizeof(AVFrame); + *(AVFrame *)data = *pic; + + return avpkt->size; +} + +static av_cold int y41p_decode_close(AVCodecContext *avctx) +{ + if (avctx->coded_frame->data[0]) + avctx->release_buffer(avctx, avctx->coded_frame); + + av_freep(&avctx->coded_frame); + + return 0; +} + +AVCodec ff_y41p_decoder = { + .name = "y41p", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_Y41P, + .init = y41p_decode_init, + .decode = y41p_decode_frame, + .close = y41p_decode_close, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), +}; diff --git a/libavcodec/y41penc.c b/libavcodec/y41penc.c new file mode 100644 index 0000000000..e5905cf6e9 --- /dev/null +++ b/libavcodec/y41penc.c @@ -0,0 +1,102 @@ +/* + * y41p encoder + * + * Copyright (c) 2012 Paul B Mahol + * + * 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 av_cold int y41p_encode_init(AVCodecContext *avctx) +{ + if (avctx->width & 7) { + av_log(avctx, AV_LOG_ERROR, "y41p requires width to be divisible by 8.\n"); + return AVERROR_INVALIDDATA; + } + + avctx->coded_frame = avcodec_alloc_frame(); + avctx->bits_per_coded_sample = 12; + + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int y41p_encode_frame(AVCodecContext *avctx, uint8_t *buf, + int buf_size, void *data) +{ + AVFrame *pic = data; + uint8_t *dst = buf; + uint8_t *y, *u, *v; + int i, j; + + if (buf_size < avctx->width * avctx->height * 1.5) { + av_log(avctx, AV_LOG_ERROR, "Out buffer is too small.\n"); + return AVERROR(ENOMEM); + } + + avctx->coded_frame->reference = 0; + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + + for (i = avctx->height - 1; i >= 0; i--) { + y = &pic->data[0][i * pic->linesize[0]]; + u = &pic->data[1][i * pic->linesize[1]]; + v = &pic->data[2][i * pic->linesize[2]]; + for (j = 0; j < avctx->width; j += 8) { + *(dst++) = *(u++); + *(dst++) = *(y++); + *(dst++) = *(v++); + *(dst++) = *(y++); + + *(dst++) = *(u++); + *(dst++) = *(y++); + *(dst++) = *(v++); + *(dst++) = *(y++); + + *(dst++) = *(y++); + *(dst++) = *(y++); + *(dst++) = *(y++); + *(dst++) = *(y++); + } + } + + return avctx->width * avctx->height * 1.5; +} + +static av_cold int y41p_encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + + return 0; +} + +AVCodec ff_y41p_encoder = { + .name = "y41p", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_Y41P, + .init = y41p_encode_init, + .encode = y41p_encode_frame, + .close = y41p_encode_close, + .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_YUV411P, + PIX_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"), +}; diff --git a/libavcodec/yop.c b/libavcodec/yop.c index 3c2d8b8957..e5333db2fd 100644 --- a/libavcodec/yop.c +++ b/libavcodec/yop.c @@ -5,20 +5,20 @@ * derived from the code by * Copyright (C) 2009 Thomas P. Higdon <thomas.p.higdon@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -91,6 +91,7 @@ static av_cold int yop_decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&s->frame); s->num_pal_colors = avctx->extradata[0]; s->first_color[0] = avctx->extradata[1]; s->first_color[1] = avctx->extradata[2]; @@ -216,10 +217,13 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size, firstcolor = s->first_color[is_odd_frame]; palette = (uint32_t *)s->frame.data[1]; - for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3) + for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3) { palette[i + firstcolor] = (s->srcptr[0] << 18) | (s->srcptr[1] << 10) | (s->srcptr[2] << 2); + palette[i + firstcolor] |= 0xFF << 24 | + (palette[i + firstcolor] >> 6) & 0x30303; + } s->frame.palette_has_changed = 1; diff --git a/libavcodec/yuv4dec.c b/libavcodec/yuv4dec.c new file mode 100644 index 0000000000..996caaf718 --- /dev/null +++ b/libavcodec/yuv4dec.c @@ -0,0 +1,109 @@ +/* + * libquicktime yuv4 decoder + * + * Copyright (c) 2011 Carl Eugen Hoyos + * + * 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 av_cold int yuv4_decode_init(AVCodecContext *avctx) +{ + avctx->pix_fmt = PIX_FMT_YUV420P; + + avctx->coded_frame = avcodec_alloc_frame(); + + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int yuv4_decode_frame(AVCodecContext *avctx, void *data, + int *data_size, AVPacket *avpkt) +{ + AVFrame *pic = avctx->coded_frame; + const uint8_t *src = avpkt->data; + uint8_t *y, *u, *v; + int i, j; + + if (pic->data[0]) + avctx->release_buffer(avctx, pic); + + if (avpkt->size < 6 * (avctx->width + 1 >> 1) * (avctx->height + 1 >> 1)) { + av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); + return AVERROR(EINVAL); + } + + pic->reference = 0; + + if (avctx->get_buffer(avctx, pic) < 0) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); + return AVERROR(ENOMEM); + } + + pic->key_frame = 1; + pic->pict_type = AV_PICTURE_TYPE_I; + + y = pic->data[0]; + u = pic->data[1]; + v = pic->data[2]; + + for (i = 0; i < (avctx->height + 1) >> 1; i++) { + for (j = 0; j < (avctx->width + 1) >> 1; j++) { + u[j] = *src++ ^ 0x80; + v[j] = *src++ ^ 0x80; + y[ 2 * j ] = *src++; + y[ 2 * j + 1] = *src++; + y[pic->linesize[0] + 2 * j ] = *src++; + y[pic->linesize[0] + 2 * j + 1] = *src++; + } + + y += 2 * pic->linesize[0]; + u += pic->linesize[1]; + v += pic->linesize[2]; + } + + *data_size = sizeof(AVFrame); + *(AVFrame *)data = *pic; + + return avpkt->size; +} + +static av_cold int yuv4_decode_close(AVCodecContext *avctx) +{ + if (avctx->coded_frame->data[0]) + avctx->release_buffer(avctx, avctx->coded_frame); + + av_freep(&avctx->coded_frame); + + return 0; +} + +AVCodec ff_yuv4_decoder = { + .name = "yuv4", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_YUV4, + .init = yuv4_decode_init, + .decode = yuv4_decode_frame, + .close = yuv4_decode_close, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"), +}; diff --git a/libavcodec/yuv4enc.c b/libavcodec/yuv4enc.c new file mode 100644 index 0000000000..db7b6245fb --- /dev/null +++ b/libavcodec/yuv4enc.c @@ -0,0 +1,93 @@ +/* + * libquicktime yuv4 encoder + * + * Copyright (c) 2011 Carl Eugen Hoyos + * + * 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 av_cold int yuv4_encode_init(AVCodecContext *avctx) +{ + avctx->coded_frame = avcodec_alloc_frame(); + + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); + return AVERROR(ENOMEM); + } + + return 0; +} + +static int yuv4_encode_frame(AVCodecContext *avctx, uint8_t *buf, + int buf_size, void *data) +{ + AVFrame *pic = data; + uint8_t *dst = buf; + uint8_t *y, *u, *v; + int i, j; + int output_size = 0; + + if (buf_size < 6 * (avctx->width + 1 >> 1) * (avctx->height + 1 >> 1)) { + av_log(avctx, AV_LOG_ERROR, "Out buffer is too small.\n"); + return AVERROR(ENOMEM); + } + + avctx->coded_frame->reference = 0; + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + + y = pic->data[0]; + u = pic->data[1]; + v = pic->data[2]; + + for (i = 0; i < avctx->height + 1 >> 1; i++) { + for (j = 0; j < avctx->width + 1 >> 1; j++) { + *dst++ = u[j] ^ 0x80; + *dst++ = v[j] ^ 0x80; + *dst++ = y[ 2 * j ]; + *dst++ = y[ 2 * j + 1]; + *dst++ = y[pic->linesize[0] + 2 * j ]; + *dst++ = y[pic->linesize[0] + 2 * j + 1]; + output_size += 6; + } + y += 2 * pic->linesize[0]; + u += pic->linesize[1]; + v += pic->linesize[2]; + } + + return output_size; +} + +static av_cold int yuv4_encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + + return 0; +} + +AVCodec ff_yuv4_encoder = { + .name = "yuv4", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_YUV4, + .init = yuv4_encode_init, + .encode = yuv4_encode_frame, + .close = yuv4_encode_close, + .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUV420P, PIX_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"), +}; diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index a160553c09..38a0d467ff 100644 --- a/libavcodec/zmbv.c +++ b/libavcodec/zmbv.c @@ -2,20 +2,20 @@ * Zip Motion Blocks Video (ZMBV) decoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -404,12 +404,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac int zret = Z_OK; // Zlib return code int len = buf_size; int hi_ver, lo_ver, ret; - uint8_t *tmp; if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic); - c->pic.reference = 1; + c->pic.reference = 3; c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; if ((ret = avctx->get_buffer(avctx, &c->pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -420,6 +419,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac c->flags = buf[0]; buf++; len--; if (c->flags & ZMBV_KEYFRAME) { + void *decode_intra = NULL; + c->decode_intra= NULL; hi_ver = buf[0]; lo_ver = buf[1]; c->comp = buf[2]; @@ -451,29 +452,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac switch (c->fmt) { case ZMBV_FMT_8BPP: c->bpp = 8; - c->decode_intra = zmbv_decode_intra; + decode_intra = zmbv_decode_intra; c->decode_xor = zmbv_decode_xor_8; break; case ZMBV_FMT_15BPP: case ZMBV_FMT_16BPP: c->bpp = 16; - c->decode_intra = zmbv_decode_intra; + decode_intra = zmbv_decode_intra; c->decode_xor = zmbv_decode_xor_16; break; #ifdef ZMBV_ENABLE_24BPP case ZMBV_FMT_24BPP: c->bpp = 24; - c->decode_intra = zmbv_decode_intra; + decode_intra = zmbv_decode_intra; c->decode_xor = zmbv_decode_xor_24; break; #endif //ZMBV_ENABLE_24BPP case ZMBV_FMT_32BPP: c->bpp = 32; - c->decode_intra = zmbv_decode_intra; + decode_intra = zmbv_decode_intra; c->decode_xor = zmbv_decode_xor_32; break; default: - c->decode_intra = NULL; c->decode_xor = NULL; av_log_ask_for_sample(avctx, "Unsupported (for now) format %i\n", c->fmt); @@ -484,29 +484,26 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); return -1; - } - - tmp = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8)); - if (!tmp) - return AVERROR(ENOMEM); - c->cur = tmp; - tmp = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8)); - if (!tmp) - return AVERROR(ENOMEM); - c->prev = tmp; - c->bx = (c->width + c->bw - 1) / c->bw; - c->by = (c->height+ c->bh - 1) / c->bh; - } + } + + c->cur = av_realloc_f(c->cur, avctx->width * avctx->height, (c->bpp / 8)); + c->prev = av_realloc_f(c->prev, avctx->width * avctx->height, (c->bpp / 8)); + c->bx = (c->width + c->bw - 1) / c->bw; + c->by = (c->height+ c->bh - 1) / c->bh; + if (!c->cur || !c->prev) + return -1; + c->decode_intra= decode_intra; + } if (c->decode_intra == NULL) { av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n"); return AVERROR_INVALIDDATA; } - if (c->comp == 0) { //Uncompressed data - memcpy(c->decomp_buf, buf, len); - c->decomp_size = 1; - } else { // ZLIB-compressed data + if (c->comp == 0) { //Uncompressed data + memcpy(c->decomp_buf, buf, len); + c->decomp_size = 1; + } else { // ZLIB-compressed data c->zstream.total_in = c->zstream.total_out = 0; c->zstream.next_in = buf; c->zstream.avail_in = len; @@ -616,6 +613,7 @@ static av_cold int decode_init(AVCodecContext *avctx) c->width = avctx->width; c->height = avctx->height; + avcodec_get_frame_defaults(&c->pic); c->bpp = avctx->bits_per_coded_sample; diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c index ebb6624cb8..3211e6ff4d 100644 --- a/libavcodec/zmbvenc.c +++ b/libavcodec/zmbvenc.c @@ -2,20 +2,20 @@ * Zip Motion Blocks Video (ZMBV) encoder * Copyright (c) 2006 Konstantin Shishkov * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |