X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fsvq3.c;h=f343d53447c964e686296bf8d2678505faea03d1;hb=ebd4c3add1ecad2c65ac80f0787ca5c1e78b600e;hp=5162e99243fc3cb321731e2d7c2ab8803bf81b3f;hpb=2e279598793133ee9c57fd0026d672f076fde4bf;p=ffmpeg diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 5162e99243f..f343d53447c 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -1,20 +1,20 @@ /* - * Copyright (c) 2003 The FFmpeg Project + * Copyright (c) 2003 The Libav Project * - * 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 */ @@ -37,7 +37,7 @@ * * You will know you have these parameters passed correctly when the decoder * correctly decodes this file: - * http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov + * http://samples.libav.org/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov */ #include "internal.h" #include "dsputil.h" @@ -63,6 +63,15 @@ * svq3 decoder. */ +typedef struct { + H264Context h; + int halfpel_flag; + int thirdpel_flag; + int unknown_flag; + int next_slice_index; + uint32_t watermark_key; +} SVQ3Context; + #define FULLPEL_MODE 1 #define HALFPEL_MODE 2 #define THIRDPEL_MODE 3 @@ -164,7 +173,6 @@ void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, { const int qmul = svq3_dequant_coeff[qp]; int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; if (dc) { dc = 13*13*((dc == 1) ? 1538*block[0] : ((qmul*(block[0] >> 3)) / 2)); @@ -190,10 +198,10 @@ void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, const int z3 = 17* block[i + 4*1] + 7*block[i + 4*3]; const int rr = (dc + 0x80000); - dst[i + stride*0] = cm[ dst[i + stride*0] + (((z0 + z3)*qmul + rr) >> 20) ]; - dst[i + stride*1] = cm[ dst[i + stride*1] + (((z1 + z2)*qmul + rr) >> 20) ]; - dst[i + stride*2] = cm[ dst[i + stride*2] + (((z1 - z2)*qmul + rr) >> 20) ]; - dst[i + stride*3] = cm[ dst[i + stride*3] + (((z0 - z3)*qmul + rr) >> 20) ]; + dst[i + stride*0] = av_clip_uint8( dst[i + stride*0] + (((z0 + z3)*qmul + rr) >> 20) ); + dst[i + stride*1] = av_clip_uint8( dst[i + stride*1] + (((z1 + z2)*qmul + rr) >> 20) ); + dst[i + stride*2] = av_clip_uint8( dst[i + stride*2] + (((z1 - z2)*qmul + rr) >> 20) ); + dst[i + stride*3] = av_clip_uint8( dst[i + stride*3] + (((z0 - z3)*qmul + rr) >> 20) ); } } @@ -279,8 +287,8 @@ static inline void svq3_mc_dir_part(MpegEncContext *s, } /* form component predictions */ - dest = s->current_picture.data[0] + x + y*s->linesize; - src = pic->data[0] + mx + my*s->linesize; + dest = s->current_picture.f.data[0] + x + y*s->linesize; + src = pic->f.data[0] + mx + my*s->linesize; if (emu) { s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, (width + 1), (height + 1), @@ -300,8 +308,8 @@ static inline void svq3_mc_dir_part(MpegEncContext *s, blocksize++; for (i = 1; i < 3; i++) { - dest = s->current_picture.data[i] + (x >> 1) + (y >> 1)*s->uvlinesize; - src = pic->data[i] + mx + my*s->uvlinesize; + dest = s->current_picture.f.data[i] + (x >> 1) + (y >> 1) * s->uvlinesize; + src = pic->f.data[i] + mx + my * s->uvlinesize; if (emu) { s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->uvlinesize, (width + 1), (height + 1), @@ -338,8 +346,8 @@ static inline int svq3_mc_dir(H264Context *h, int size, int mode, int dir, if (mode != PREDICT_MODE) { pred_motion(h, k, (part_width >> 2), dir, 1, &mx, &my); } else { - mx = s->next_picture.motion_val[0][b_xy][0]<<1; - my = s->next_picture.motion_val[0][b_xy][1]<<1; + mx = s->next_picture.f.motion_val[0][b_xy][0] << 1; + my = s->next_picture.f.motion_val[0][b_xy][1] << 1; if (dir == 0) { mx = ((mx * h->frame_num_offset) / h->prev_frame_num_offset + 1) >> 1; @@ -416,15 +424,18 @@ static inline int svq3_mc_dir(H264Context *h, int size, int mode, int dir, } /* write back motion vectors */ - fill_rectangle(s->current_picture.motion_val[dir][b_xy], part_width>>2, part_height>>2, h->b_stride, pack16to32(mx,my), 4); + fill_rectangle(s->current_picture.f.motion_val[dir][b_xy], + part_width >> 2, part_height >> 2, h->b_stride, + pack16to32(mx, my), 4); } } return 0; } -static int svq3_decode_mb(H264Context *h, unsigned int mb_type) +static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) { + H264Context *h = &svq3->h; int i, j, k, m, dir, mode; int cbp = 0; uint32_t vlc; @@ -438,16 +449,16 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) h->topright_samples_available = 0xFFFF; if (mb_type == 0) { /* SKIP */ - if (s->pict_type == FF_P_TYPE || s->next_picture.mb_type[mb_xy] == -1) { + if (s->pict_type == AV_PICTURE_TYPE_P || s->next_picture.f.mb_type[mb_xy] == -1) { svq3_mc_dir_part(s, 16*s->mb_x, 16*s->mb_y, 16, 16, 0, 0, 0, 0, 0, 0); - if (s->pict_type == FF_B_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_B) { svq3_mc_dir_part(s, 16*s->mb_x, 16*s->mb_y, 16, 16, 0, 0, 0, 0, 1, 1); } mb_type = MB_TYPE_SKIP; } else { - mb_type = FFMIN(s->next_picture.mb_type[mb_xy], 6); + mb_type = FFMIN(s->next_picture.f.mb_type[mb_xy], 6); if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 0, 0) < 0) return -1; if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 1, 1) < 0) @@ -456,9 +467,9 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) mb_type = MB_TYPE_16x16; } } else if (mb_type < 8) { /* INTER */ - if (h->thirdpel_flag && h->halfpel_flag == !get_bits1 (&s->gb)) { + if (svq3->thirdpel_flag && svq3->halfpel_flag == !get_bits1 (&s->gb)) { mode = THIRDPEL_MODE; - } else if (h->halfpel_flag && h->thirdpel_flag == !get_bits1 (&s->gb)) { + } else if (svq3->halfpel_flag && svq3->thirdpel_flag == !get_bits1 (&s->gb)) { mode = HALFPEL_MODE; } else { mode = FULLPEL_MODE; @@ -476,7 +487,7 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) for (m = 0; m < 2; m++) { if (s->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1]+6] != -1) { for (i = 0; i < 4; i++) { - *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - 1 + i*h->b_stride]; + *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = *(uint32_t *) s->current_picture.f.motion_val[m][b_xy - 1 + i*h->b_stride]; } } else { for (i = 0; i < 4; i++) { @@ -484,39 +495,39 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) } } if (s->mb_y > 0) { - memcpy(h->mv_cache[m][scan8[0] - 1*8], s->current_picture.motion_val[m][b_xy - h->b_stride], 4*2*sizeof(int16_t)); + memcpy(h->mv_cache[m][scan8[0] - 1*8], s->current_picture.f.motion_val[m][b_xy - h->b_stride], 4*2*sizeof(int16_t)); memset(&h->ref_cache[m][scan8[0] - 1*8], (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4); if (s->mb_x < (s->mb_width - 1)) { - *(uint32_t *) h->mv_cache[m][scan8[0] + 4 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride + 4]; + *(uint32_t *) h->mv_cache[m][scan8[0] + 4 - 1*8] = *(uint32_t *) s->current_picture.f.motion_val[m][b_xy - h->b_stride + 4]; h->ref_cache[m][scan8[0] + 4 - 1*8] = (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride + 1]+6] == -1 || h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride ] ] == -1) ? PART_NOT_AVAILABLE : 1; }else h->ref_cache[m][scan8[0] + 4 - 1*8] = PART_NOT_AVAILABLE; if (s->mb_x > 0) { - *(uint32_t *) h->mv_cache[m][scan8[0] - 1 - 1*8] = *(uint32_t *) s->current_picture.motion_val[m][b_xy - h->b_stride - 1]; + *(uint32_t *) h->mv_cache[m][scan8[0] - 1 - 1*8] = *(uint32_t *) s->current_picture.f.motion_val[m][b_xy - h->b_stride - 1]; h->ref_cache[m][scan8[0] - 1 - 1*8] = (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride - 1]+3] == -1) ? PART_NOT_AVAILABLE : 1; }else h->ref_cache[m][scan8[0] - 1 - 1*8] = PART_NOT_AVAILABLE; }else memset(&h->ref_cache[m][scan8[0] - 1*8 - 1], PART_NOT_AVAILABLE, 8); - if (s->pict_type != FF_B_TYPE) + if (s->pict_type != AV_PICTURE_TYPE_B) break; } /* decode motion vector(s) and form prediction(s) */ - if (s->pict_type == FF_P_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_P) { if (svq3_mc_dir(h, (mb_type - 1), mode, 0, 0) < 0) return -1; - } else { /* FF_B_TYPE */ + } else { /* AV_PICTURE_TYPE_B */ if (mb_type != 2) { if (svq3_mc_dir(h, 0, mode, 0, 0) < 0) return -1; } else { for (i = 0; i < 4; i++) { - memset(s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); + memset(s->current_picture.f.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); } } if (mb_type != 1) { @@ -524,7 +535,7 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) return -1; } else { for (i = 0; i < 4; i++) { - memset(s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); + memset(s->current_picture.f.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); } } } @@ -579,7 +590,7 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) } } - ff_h264_write_back_intra_pred_mode(h); + write_back_intra_pred_mode(h); if (mb_type == 8) { ff_h264_check_intra4x4_pred_mode(h); @@ -600,7 +611,7 @@ static int svq3_decode_mb(H264Context *h, 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_intra_pred_mode(h, dir, 0)) == -1){ av_log(h->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n"); return -1; } @@ -609,25 +620,26 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) mb_type = MB_TYPE_INTRA16x16; } - if (!IS_INTER(mb_type) && s->pict_type != FF_I_TYPE) { + if (!IS_INTER(mb_type) && s->pict_type != AV_PICTURE_TYPE_I) { for (i = 0; i < 4; i++) { - memset(s->current_picture.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); + memset(s->current_picture.f.motion_val[0][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); } - if (s->pict_type == FF_B_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_B) { for (i = 0; i < 4; i++) { - memset(s->current_picture.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); + memset(s->current_picture.f.motion_val[1][b_xy + i*h->b_stride], 0, 4*2*sizeof(int16_t)); } } } if (!IS_INTRA4x4(mb_type)) { memset(h->intra4x4_pred_mode+h->mb2br_xy[mb_xy], DC_PRED, 8); } - if (!IS_SKIP(mb_type) || s->pict_type == FF_B_TYPE) { - memset(h->non_zero_count_cache + 8, 0, 4*9*sizeof(uint8_t)); - s->dsp.clear_blocks(h->mb); + if (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B) { + memset(h->non_zero_count_cache + 8, 0, 14*8*sizeof(uint8_t)); + s->dsp.clear_blocks(h->mb+ 0); + s->dsp.clear_blocks(h->mb+384); } - if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == FF_B_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){ av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc); return -1; @@ -635,17 +647,17 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) cbp = IS_INTRA(mb_type) ? golomb_to_intra4x4_cbp[vlc] : golomb_to_inter_cbp[vlc]; } - if (IS_INTRA16x16(mb_type) || (s->pict_type != FF_I_TYPE && s->adaptive_quant && cbp)) { + 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; } } if (IS_INTRA16x16(mb_type)) { - AV_ZERO128(h->mb_luma_dc+0); - AV_ZERO128(h->mb_luma_dc+8); + AV_ZERO128(h->mb_luma_dc[0]+0); + AV_ZERO128(h->mb_luma_dc[0]+8); if (svq3_decode_block(&s->gb, h->mb_luma_dc, 0, 1)){ av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding intra luma dc\n"); return -1; @@ -671,20 +683,23 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) } if ((cbp & 0x30)) { - for (i = 0; i < 2; ++i) { - if (svq3_decode_block(&s->gb, &h->mb[16*(16 + 4*i)], 0, 3)){ + for (i = 1; i < 3; ++i) { + if (svq3_decode_block(&s->gb, &h->mb[16*16*i], 0, 3)){ av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma dc block\n"); return -1; } } if ((cbp & 0x20)) { - for (i = 0; i < 8; i++) { - h->non_zero_count_cache[ scan8[16+i] ] = 1; - - if (svq3_decode_block(&s->gb, &h->mb[16*(16 + i)], 1, 1)){ - av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma ac block\n"); - return -1; + for (i = 1; i < 3; i++) { + for (j = 0; j < 4; j++) { + k = 16*i + j; + h->non_zero_count_cache[ scan8[k] ] = 1; + + if (svq3_decode_block(&s->gb, &h->mb[16*k], 1, 1)){ + av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma ac block\n"); + return -1; + } } } } @@ -692,18 +707,20 @@ static int svq3_decode_mb(H264Context *h, unsigned int mb_type) } h->cbp= cbp; - s->current_picture.mb_type[mb_xy] = 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_pred_mode(h, DC_PRED8x8, 1); } return 0; } -static int svq3_decode_slice_header(H264Context *h) +static int svq3_decode_slice_header(AVCodecContext *avctx) { - MpegEncContext *const s = (MpegEncContext *) h; + SVQ3Context *svq3 = avctx->priv_data; + H264Context *h = &svq3->h; + MpegEncContext *s = &h->s; const int mb_xy = h->mb_xy; int i, header; @@ -711,24 +728,24 @@ static int svq3_decode_slice_header(H264Context *h) if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) { /* TODO: what? */ - av_log(h->s.avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header); + av_log(avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header); return -1; } else { int length = (header >> 5) & 3; - h->next_slice_index = get_bits_count(&s->gb) + 8*show_bits(&s->gb, 8*length) + 8*length; + svq3->next_slice_index = get_bits_count(&s->gb) + 8*show_bits(&s->gb, 8*length) + 8*length; - if (h->next_slice_index > s->gb.size_in_bits) { - av_log(h->s.avctx, AV_LOG_ERROR, "slice after bitstream end\n"); + if (svq3->next_slice_index > s->gb.size_in_bits) { + av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n"); return -1; } - s->gb.size_in_bits = h->next_slice_index - 8*(length - 1); + s->gb.size_in_bits = svq3->next_slice_index - 8*(length - 1); skip_bits(&s->gb, 8); - if (h->svq3_watermark_key) { + if (svq3->watermark_key) { uint32_t header = AV_RL32(&s->gb.buffer[(get_bits_count(&s->gb)>>3)+1]); - AV_WL32(&s->gb.buffer[(get_bits_count(&s->gb)>>3)+1], header ^ h->svq3_watermark_key); + AV_WL32(&s->gb.buffer[(get_bits_count(&s->gb)>>3)+1], header ^ svq3->watermark_key); } if (length > 0) { memcpy((uint8_t *) &s->gb.buffer[get_bits_count(&s->gb) >> 3], @@ -759,7 +776,7 @@ static int svq3_decode_slice_header(H264Context *h) /* unknown fields */ skip_bits1(&s->gb); - if (h->unknown_svq3_flag) { + if (svq3->unknown_flag) { skip_bits1(&s->gb); } @@ -788,11 +805,14 @@ static int svq3_decode_slice_header(H264Context *h) static av_cold int svq3_decode_init(AVCodecContext *avctx) { - MpegEncContext *const s = avctx->priv_data; - H264Context *const h = avctx->priv_data; + SVQ3Context *svq3 = avctx->priv_data; + H264Context *h = &svq3->h; + MpegEncContext *s = &h->s; int m; unsigned char *extradata; + unsigned char *extradata_end; unsigned int size; + int marker_found = 0; if (ff_h264_decode_init(avctx) < 0) return -1; @@ -804,35 +824,34 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) avctx->pix_fmt = avctx->codec->pix_fmts[0]; if (!s->context_initialized) { - s->width = avctx->width; - s->height = avctx->height; - h->halfpel_flag = 1; - h->thirdpel_flag = 1; - h->unknown_svq3_flag = 0; - h->chroma_qp[0] = h->chroma_qp[1] = 4; - - if (MPV_common_init(s) < 0) - return -1; + h->chroma_qp[0] = h->chroma_qp[1] = 4; - h->b_stride = 4*s->mb_width; - - ff_h264_alloc_tables(h); + svq3->halfpel_flag = 1; + 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++) { - if (!memcmp(extradata, "SEQH", 4)) - break; - extradata++; + extradata_end = avctx->extradata + avctx->extradata_size; + if (extradata) { + for (m = 0; m + 8 < avctx->extradata_size; m++) { + if (!memcmp(extradata, "SEQH", 4)) { + marker_found = 1; + break; + } + extradata++; + } } /* if a match was found, parse the extra data */ - if (extradata && !memcmp(extradata, "SEQH", 4)) { + if (marker_found) { GetBitContext gb; int frame_size_code; size = AV_RB32(&extradata[4]); + if (size > extradata_end - extradata - 8) + return AVERROR_INVALIDDATA; init_get_bits(&gb, extradata + 8, size*8); /* 'frame size code' and optional 'width, height' */ @@ -851,8 +870,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) break; } - h->halfpel_flag = get_bits1(&gb); - h->thirdpel_flag = get_bits1(&gb); + svq3->halfpel_flag = get_bits1(&gb); + svq3->thirdpel_flag = get_bits1(&gb); /* unknown fields */ skip_bits1(&gb); @@ -869,9 +888,9 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) skip_bits(&gb, 8); } - h->unknown_svq3_flag = get_bits1(&gb); + svq3->unknown_flag = get_bits1(&gb); avctx->has_b_frames = !s->low_delay; - if (h->unknown_svq3_flag) { + if (svq3->unknown_flag) { #if CONFIG_ZLIB unsigned watermark_width = svq3_get_ue_golomb(&gb); unsigned watermark_height = svq3_get_ue_golomb(&gb); @@ -894,9 +913,9 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) av_free(buf); return -1; } - h->svq3_watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0); - h->svq3_watermark_key = h->svq3_watermark_key << 16 | h->svq3_watermark_key; - av_log(avctx, AV_LOG_DEBUG, "watermark key %#x\n", h->svq3_watermark_key); + svq3->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0); + svq3->watermark_key = svq3->watermark_key << 16 | svq3->watermark_key; + av_log(avctx, AV_LOG_DEBUG, "watermark key %#x\n", svq3->watermark_key); av_free(buf); #else av_log(avctx, AV_LOG_ERROR, "this svq3 file contains watermark which need zlib support compiled in\n"); @@ -904,6 +923,19 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) #endif } } + + s->width = avctx->width; + s->height = avctx->height; + + if (ff_MPV_common_init(s) < 0) + return -1; + + h->b_stride = 4*s->mb_width; + + if (ff_h264_alloc_tables(h) < 0) { + av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n"); + return AVERROR(ENOMEM); + } } return 0; @@ -914,15 +946,16 @@ static int svq3_decode_frame(AVCodecContext *avctx, 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; - MpegEncContext *const s = avctx->priv_data; - H264Context *const h = avctx->priv_data; int m, mb_type; /* special case for last picture */ if (buf_size == 0) { if (s->next_picture_ptr && !s->low_delay) { - *(AVFrame *) data = *(AVFrame *) &s->next_picture; + *(AVFrame *) data = s->next_picture.f; s->next_picture_ptr = NULL; *data_size = sizeof(AVFrame); } @@ -933,7 +966,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, s->mb_x = s->mb_y = h->mb_xy = 0; - if (svq3_decode_slice_header(h)) + if (svq3_decode_slice_header(avctx)) return -1; s->pict_type = h->slice_type; @@ -941,30 +974,24 @@ static int svq3_decode_frame(AVCodecContext *avctx, if (avctx->debug&FF_DEBUG_PICT_INFO){ av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n", - av_get_pict_type_char(s->pict_type), h->halfpel_flag, h->thirdpel_flag, + av_get_picture_type_char(s->pict_type), svq3->halfpel_flag, svq3->thirdpel_flag, s->adaptive_quant, s->qscale, h->slice_num); } - /* for hurry_up == 5 */ - s->current_picture.pict_type = s->pict_type; - s->current_picture.key_frame = (s->pict_type == FF_I_TYPE); + /* for skipping the frame */ + s->current_picture.f.pict_type = s->pict_type; + s->current_picture.f.key_frame = (s->pict_type == AV_PICTURE_TYPE_I); /* Skip B-frames if we do not have reference frames. */ - if (s->last_picture_ptr == NULL && s->pict_type == FF_B_TYPE) - return 0; - /* Skip B-frames if we are in a hurry. */ - if (avctx->hurry_up && s->pict_type == FF_B_TYPE) + if (s->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B) return 0; - /* Skip everything if we are in a hurry >= 5. */ - if (avctx->hurry_up >= 5) - return 0; - if ( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == 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 0; if (s->next_p_frame_damaged) { - if (s->pict_type == FF_B_TYPE) + if (s->pict_type == AV_PICTURE_TYPE_B) return 0; else s->next_p_frame_damaged = 0; @@ -973,7 +1000,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, if (ff_h264_frame_start(h) < 0) return -1; - if (s->pict_type == FF_B_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_B) { h->frame_num_offset = (h->slice_num - h->prev_frame_num); if (h->frame_num_offset < 0) { @@ -1011,10 +1038,10 @@ static int svq3_decode_frame(AVCodecContext *avctx, if ( (get_bits_count(&s->gb) + 7) >= s->gb.size_in_bits && ((get_bits_count(&s->gb) & 7) == 0 || show_bits(&s->gb, (-get_bits_count(&s->gb) & 7)) == 0)) { - skip_bits(&s->gb, h->next_slice_index - get_bits_count(&s->gb)); + skip_bits(&s->gb, svq3->next_slice_index - get_bits_count(&s->gb)); s->gb.size_in_bits = 8*buf_size; - if (svq3_decode_slice_header(h)) + if (svq3_decode_slice_header(avctx)) return -1; /* TODO: support s->mb_skip_run */ @@ -1022,12 +1049,12 @@ static int svq3_decode_frame(AVCodecContext *avctx, mb_type = svq3_get_ue_golomb(&s->gb); - if (s->pict_type == FF_I_TYPE) { + if (s->pict_type == AV_PICTURE_TYPE_I) { mb_type += 8; - } else if (s->pict_type == FF_B_TYPE && mb_type >= 4) { + } else if (s->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4) { mb_type += 4; } - if (mb_type > 33 || svq3_decode_mb(h, mb_type)) { + if ((unsigned)mb_type > 33 || svq3_decode_mb(svq3, mb_type)) { av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y); return -1; } @@ -1036,21 +1063,21 @@ static int svq3_decode_frame(AVCodecContext *avctx, ff_h264_hl_decode_mb (h); } - if (s->pict_type != FF_B_TYPE && !s->low_delay) { - s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] = - (s->pict_type == FF_P_TYPE && mb_type < 8) ? (mb_type - 1) : -1; + if (s->pict_type != AV_PICTURE_TYPE_B && !s->low_delay) { + s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = + (s->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1; } } ff_draw_horiz_band(s, 16*s->mb_y, 16); } - MPV_frame_end(s); + ff_MPV_frame_end(s); - if (s->pict_type == FF_B_TYPE || s->low_delay) { - *(AVFrame *) data = *(AVFrame *) &s->current_picture; + if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { + *(AVFrame *) data = s->current_picture.f; } else { - *(AVFrame *) data = *(AVFrame *) &s->last_picture; + *(AVFrame *) data = s->last_picture.f; } /* Do not output the last pic after seeking. */ @@ -1061,17 +1088,29 @@ static int svq3_decode_frame(AVCodecContext *avctx, return buf_size; } +static int svq3_decode_end(AVCodecContext *avctx) +{ + SVQ3Context *svq3 = avctx->priv_data; + H264Context *h = &svq3->h; + MpegEncContext *s = &h->s; + + ff_h264_free_context(h); + + ff_MPV_common_end(s); + + return 0; +} AVCodec ff_svq3_decoder = { - "svq3", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_SVQ3, - sizeof(H264Context), - svq3_decode_init, - NULL, - ff_h264_decode_end, - svq3_decode_frame, - CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"), - .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_NONE}, + .name = "svq3", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_SVQ3, + .priv_data_size = sizeof(SVQ3Context), + .init = svq3_decode_init, + .close = svq3_decode_end, + .decode = svq3_decode_frame, + .capabilities = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | + CODEC_CAP_DELAY, + .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"), + .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUVJ420P, PIX_FMT_NONE }, };