X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fsvq1dec.c;h=69dbd1b25d52f9c6b5434829a30a0cce15b0e27f;hb=64fe3eaeb351582787cbef75a2fe160253663363;hp=fe1d7edaf7558b9ecb063995c37a277a9d5d2ad8;hpb=199436b952c198e14d53a389438e232ef60f1982;p=ffmpeg diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index fe1d7edaf75..69dbd1b25d5 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -8,32 +8,31 @@ * * SVQ1 Encoder (c) 2004 Mike Melanson * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * 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. * - * FFmpeg is distributed in the hope that it will be useful, + * 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 FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file svq1.c + * @file * Sorenson Vector Quantizer #1 (SVQ1) video codec. * For more information of the SVQ1 algorithm, visit: * http://www.pcisys.net/~melanson/codecs/ */ -//#define DEBUG_SVQ1 #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" @@ -196,7 +195,8 @@ static const uint8_t string_table[256] = { #define SVQ1_CALC_CODEBOOK_ENTRIES(cbook)\ codebook = (const uint32_t *) cbook[level];\ - bit_cache = get_bits (bitbuf, 4*stages);\ + if (stages > 0)\ + bit_cache = get_bits (bitbuf, 4*stages);\ /* calculate codebook entries for this vector */\ for (j=0; j < stages; j++) {\ entries[j] = (((bit_cache >> (4*(stages - j - 1))) & 0xF) + 16*j) << (level + 1);\ @@ -238,9 +238,9 @@ static int svq1_decode_block_intra (GetBitContext *bitbuf, uint8_t *pixels, int } if ((stages > 0) && (level >= 4)) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n",stages,level); -#endif + av_dlog(NULL, + "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n", + stages, level); return -1; /* invalid vector */ } @@ -288,9 +288,9 @@ static int svq1_decode_block_non_intra (GetBitContext *bitbuf, uint8_t *pixels, if (stages == -1) continue; /* skip vector */ if ((stages > 0) && (level >= 4)) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n",stages,level); -#endif + av_dlog(NULL, + "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n", + stages, level); return -1; /* invalid vector */ } @@ -318,9 +318,9 @@ static int svq1_decode_motion_vector (GetBitContext *bitbuf, svq1_pmv *mv, svq1_ /* add median of motion vector predictors and clip result */ if (i == 1) - mv->y = ((diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26; + mv->y = sign_extend(diff + mid_pred(pmv[0]->y, pmv[1]->y, pmv[2]->y), 6); else - mv->x = ((diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26; + mv->x = sign_extend(diff + mid_pred(pmv[0]->x, pmv[1]->x, pmv[2]->x), 6); } return 0; @@ -378,13 +378,6 @@ static int svq1_motion_inter_block (MpegEncContext *s, GetBitContext *bitbuf, if(x + (mv.x >> 1)<0) mv.x= 0; -#if 0 - int w= (s->width+15)&~15; - int h= (s->height+15)&~15; - if(x + (mv.x >> 1)<0 || y + (mv.y >> 1)<0 || x + (mv.x >> 1) + 16 > w || y + (mv.y >> 1) + 16> h) - av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mv.x >> 1), y + (mv.y >> 1)); -#endif - src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1))*pitch]; dst = current; @@ -461,12 +454,6 @@ static int svq1_motion_inter_4v_block (MpegEncContext *s, GetBitContext *bitbuf, if(x + (mvx >> 1)<0) mvx= 0; -#if 0 - int w= (s->width+15)&~15; - int h= (s->height+15)&~15; - if(x + (mvx >> 1)<0 || y + (mvy >> 1)<0 || x + (mvx >> 1) + 8 > w || y + (mvy >> 1) + 8> h) - av_log(s->avctx, AV_LOG_INFO, "%d %d %d %d\n", x, y, x + (mvx >> 1), y + (mvy >> 1)); -#endif src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1))*pitch]; dst = current; @@ -512,9 +499,7 @@ static int svq1_decode_delta_block (MpegEncContext *s, GetBitContext *bitbuf, if (result != 0) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_block %i\n",result); -#endif + av_dlog(s->avctx, "Error in svq1_motion_inter_block %i\n", result); break; } result = svq1_decode_block_non_intra (bitbuf, current, pitch); @@ -525,9 +510,7 @@ static int svq1_decode_delta_block (MpegEncContext *s, GetBitContext *bitbuf, if (result != 0) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_motion_inter_4v_block %i\n",result); -#endif + av_dlog(s->avctx, "Error in svq1_motion_inter_4v_block %i\n", result); break; } result = svq1_decode_block_non_intra (bitbuf, current, pitch); @@ -567,16 +550,15 @@ static void svq1_parse_string (GetBitContext *bitbuf, uint8_t *out) { static int svq1_decode_frame_header (GetBitContext *bitbuf,MpegEncContext *s) { int frame_size_code; - int temporal_reference; - temporal_reference = get_bits (bitbuf, 8); + skip_bits(bitbuf, 8); /* temporal_reference */ /* frame type */ s->pict_type= get_bits (bitbuf, 2)+1; if(s->pict_type==4) return -1; - if (s->pict_type == FF_I_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_I) { /* unknown fields */ if (s->f_code == 0x50 || s->f_code == 0x60) { @@ -642,12 +624,15 @@ static int svq1_decode_frame_header (GetBitContext *bitbuf,MpegEncContext *s) { static int svq1_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - const uint8_t *buf, int buf_size) + AVPacket *avpkt) { + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; MpegEncContext *s=avctx->priv_data; uint8_t *current, *previous; int result, i, x, y, width, height; AVFrame *pict = data; + svq1_pmv *pmv; /* initialize bit buffer */ init_get_bits(&s->gb,buf,buf_size*8); @@ -671,64 +656,63 @@ static int svq1_decode_frame(AVCodecContext *avctx, if (result != 0) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_frame_header %i\n",result); -#endif + av_dlog(s->avctx, "Error in svq1_decode_frame_header %i\n",result); return result; } + avcodec_set_dimensions(avctx, s->width, s->height); //FIXME this avoids some confusion for "B frames" without 2 references //this should be removed after libavcodec can handle more flexible picture types & ordering - if(s->pict_type==FF_B_TYPE && s->last_picture_ptr==NULL) return buf_size; + if(s->pict_type==AV_PICTURE_TYPE_B && s->last_picture_ptr==NULL) return buf_size; - if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return buf_size; - if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE) - ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_I_TYPE) + if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B) + ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) return buf_size; if(MPV_frame_start(s, avctx) < 0) return -1; + pmv = av_malloc((FFALIGN(s->width, 16)/8 + 3) * sizeof(*pmv)); + if (!pmv) + return -1; + /* decode y, u and v components */ for (i=0; i < 3; i++) { int linesize; if (i == 0) { - width = (s->width+15)&~15; - height = (s->height+15)&~15; + width = FFALIGN(s->width, 16); + height = FFALIGN(s->height, 16); linesize= s->linesize; } else { if(s->flags&CODEC_FLAG_GRAY) break; - width = (s->width/4+15)&~15; - height = (s->height/4+15)&~15; + width = FFALIGN(s->width/4, 16); + height = FFALIGN(s->height/4, 16); linesize= s->uvlinesize; } - current = s->current_picture.data[i]; + current = s->current_picture.f.data[i]; - if(s->pict_type==FF_B_TYPE){ - previous = s->next_picture.data[i]; + if(s->pict_type==AV_PICTURE_TYPE_B){ + previous = s->next_picture.f.data[i]; }else{ - previous = s->last_picture.data[i]; + previous = s->last_picture.f.data[i]; } - if (s->pict_type == FF_I_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_I) { /* keyframe */ for (y=0; y < height; y+=16) { for (x=0; x < width; x+=16) { result = svq1_decode_block_intra (&s->gb, ¤t[x], linesize); if (result != 0) { -//#ifdef DEBUG_SVQ1 av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_block %i (keyframe)\n",result); -//#endif - return result; + goto err; } } current += 16*linesize; } } else { - svq1_pmv pmv[width/8+3]; /* delta frame */ memset (pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv)); @@ -738,10 +722,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, linesize, pmv, x, y); if (result != 0) { -#ifdef DEBUG_SVQ1 - av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_delta_block %i\n",result); -#endif - return result; + av_dlog(s->avctx, "Error in svq1_decode_delta_block %i\n",result); + goto err; } } @@ -759,13 +741,17 @@ static int svq1_decode_frame(AVCodecContext *avctx, MPV_frame_end(s); *data_size=sizeof(AVFrame); - return buf_size; + result = buf_size; +err: + av_free(pmv); + return result; } static av_cold int svq1_decode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; int i; + int offset = 0; MPV_decode_defaults(s); @@ -778,30 +764,38 @@ static av_cold int svq1_decode_init(AVCodecContext *avctx) s->flags= avctx->flags; if (MPV_common_init(s) < 0) return -1; - init_vlc(&svq1_block_type, 2, 4, + INIT_VLC_STATIC(&svq1_block_type, 2, 4, &ff_svq1_block_type_vlc[0][1], 2, 1, - &ff_svq1_block_type_vlc[0][0], 2, 1, 1); + &ff_svq1_block_type_vlc[0][0], 2, 1, 6); - init_vlc(&svq1_motion_component, 7, 33, + INIT_VLC_STATIC(&svq1_motion_component, 7, 33, &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 1); + &mvtab[0][0], 2, 1, 176); for (i = 0; i < 6; i++) { + static const uint8_t sizes[2][6] = {{14, 10, 14, 18, 16, 18}, {10, 10, 14, 14, 14, 16}}; + static VLC_TYPE table[168][2]; + svq1_intra_multistage[i].table = &table[offset]; + svq1_intra_multistage[i].table_allocated = sizes[0][i]; + offset += sizes[0][i]; init_vlc(&svq1_intra_multistage[i], 3, 8, &ff_svq1_intra_multistage_vlc[i][0][1], 2, 1, - &ff_svq1_intra_multistage_vlc[i][0][0], 2, 1, 1); + &ff_svq1_intra_multistage_vlc[i][0][0], 2, 1, INIT_VLC_USE_NEW_STATIC); + svq1_inter_multistage[i].table = &table[offset]; + svq1_inter_multistage[i].table_allocated = sizes[1][i]; + offset += sizes[1][i]; init_vlc(&svq1_inter_multistage[i], 3, 8, &ff_svq1_inter_multistage_vlc[i][0][1], 2, 1, - &ff_svq1_inter_multistage_vlc[i][0][0], 2, 1, 1); + &ff_svq1_inter_multistage_vlc[i][0][0], 2, 1, INIT_VLC_USE_NEW_STATIC); } - init_vlc(&svq1_intra_mean, 8, 256, + INIT_VLC_STATIC(&svq1_intra_mean, 8, 256, &ff_svq1_intra_mean_vlc[0][1], 4, 2, - &ff_svq1_intra_mean_vlc[0][0], 4, 2, 1); + &ff_svq1_intra_mean_vlc[0][0], 4, 2, 632); - init_vlc(&svq1_inter_mean, 9, 512, + INIT_VLC_STATIC(&svq1_inter_mean, 9, 512, &ff_svq1_inter_mean_vlc[0][1], 4, 2, - &ff_svq1_inter_mean_vlc[0][0], 4, 2, 1); + &ff_svq1_inter_mean_vlc[0][0], 4, 2, 1434); return 0; } @@ -815,17 +809,16 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx) } -AVCodec svq1_decoder = { - "svq1", - CODEC_TYPE_VIDEO, - CODEC_ID_SVQ1, - sizeof(MpegEncContext), - svq1_decode_init, - NULL, - svq1_decode_end, - svq1_decode_frame, - CODEC_CAP_DR1, +AVCodec ff_svq1_decoder = { + .name = "svq1", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_SVQ1, + .priv_data_size = sizeof(MpegEncContext), + .init = svq1_decode_init, + .close = svq1_decode_end, + .decode = svq1_decode_frame, + .capabilities = CODEC_CAP_DR1, .flush= ff_mpeg_flush, - .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV410P, PIX_FMT_NONE}, - .long_name= NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1"), + .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV410P, PIX_FMT_NONE}, + .long_name= NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), };