diff options
Diffstat (limited to 'libavcodec/svq3.c')
-rw-r--r-- | libavcodec/svq3.c | 82 |
1 files changed, 58 insertions, 24 deletions
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 4b5a8d0..05832bf 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 @@ -216,14 +218,17 @@ static inline int svq3_decode_block(GetBitContext *gb, int16_t *block, static const uint8_t *const scan_patterns[4] = { luma_dc_zigzag_scan, zigzag_scan, svq3_scan, chroma_dc_scan }; - int run, level, limit; + int run, level, sign, limit; unsigned vlc; const int intra = 3 * type >> 2; const uint8_t *const scan = scan_patterns[type]; for (limit = (16 >> intra); index < 16; index = limit, limit += 8) { for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) { - int sign = (vlc & 1) ? 0 : -1; + if ((int32_t)vlc < 0) + return -1; + + sign = (vlc & 1) ? 0 : -1; vlc = vlc + 1 >> 1; if (type == 3) { @@ -238,20 +243,19 @@ static inline int svq3_decode_block(GetBitContext *gb, int16_t *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) { run = vlc & 0x7; - level = (vlc >> 3) + - ((run == 0) ? 8 : ((run < 2) ? 2 : ((run < 5) ? 0 : -1))); + level = (vlc >> 3) + ((run == 0) ? 8 : ((run < 2) ? 2 : ((run < 5) ? 0 : -1))); } else { run = vlc & 0xF; - level = (vlc >> 4) + - ((run == 0) ? 4 : ((run < 3) ? 2 : ((run < 10) ? 1 : 0))); + level = (vlc >> 4) + ((run == 0) ? 4 : ((run < 3) ? 2 : ((run < 10) ? 1 : 0))); } } + if ((index += run) >= limit) return -1; @@ -550,20 +554,22 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) if (svq3_mc_dir(h, mb_type - 1, mode, 0, 0) < 0) return -1; } else { /* AV_PICTURE_TYPE_B */ - if (mb_type != 2) + if (mb_type != 2) { if (svq3_mc_dir(h, 0, mode, 0, 0) < 0) return -1; - else + } else { for (i = 0; i < 4; i++) memset(s->current_picture.f.motion_val[0][b_xy + i * h->b_stride], 0, 4 * 2 * sizeof(int16_t)); - if (mb_type != 1) + } + if (mb_type != 1) { if (svq3_mc_dir(h, 0, mode, 1, mb_type == 3) < 0) return -1; - else + } else { for (i = 0; i < 4; i++) memset(s->current_picture.f.motion_val[1][b_xy + i * h->b_stride], 0, 4 * 2 * sizeof(int16_t)); + } } mb_type = MB_TYPE_16x16; @@ -591,7 +597,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; } @@ -662,7 +668,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; } @@ -853,6 +859,7 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) s->flags2 = avctx->flags2; s->unrestricted_mv = 1; h->is_complex = 1; + h->sps.chroma_format_idc = 1; avctx->pix_fmt = avctx->codec->pix_fmts[0]; if (!s->context_initialized) { @@ -862,6 +869,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; extradata_end = avctx->extradata + avctx->extradata_size; @@ -954,7 +962,7 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) int offset = get_bits_count(&gb) + 7 >> 3; uint8_t *buf; - if ((uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) + if (watermark_height <= 0 || (uint64_t)watermark_width*4 > UINT_MAX/watermark_height) return -1; buf = av_malloc(buf_len); @@ -1004,12 +1012,12 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) static int svq3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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; + int m, left; + uint8_t *buf; /* special case for last picture */ if (buf_size == 0) { @@ -1021,10 +1029,21 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, 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; @@ -1130,6 +1149,18 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, 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; + } + ff_MPV_frame_end(s); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) @@ -1154,6 +1185,9 @@ static int svq3_decode_end(AVCodecContext *avctx) ff_MPV_common_end(s); + av_freep(&svq3->buf); + svq3->buf_size = 0; + return 0; } |