X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fsvq3.c;h=b2c8215002dd84a49ce59570e9ffa4225690a072;hb=a247ac640df3da573cd661065bf53f37863e2b46;hp=18a4448ffa702a3c5254bef599377abdf0613070;hpb=ce265b0bf5d0c77a092a1f5fbeb652c7cdea5fc7;p=ffmpeg diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 18a4448ffa7..b2c8215002d 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -43,6 +43,9 @@ #include #include "libavutil/attributes.h" +#include "libavutil/crc.h" +#include "libavutil/mem_internal.h" + #include "internal.h" #include "avcodec.h" #include "mpegutils.h" @@ -68,15 +71,10 @@ typedef struct SVQ3Frame { AVFrame *f; - AVBufferRef *motion_val_buf[2]; + int16_t (*motion_val_buf[2])[2]; int16_t (*motion_val[2])[2]; - AVBufferRef *mb_type_buf; - uint32_t *mb_type; - - - AVBufferRef *ref_index_buf[2]; - int8_t *ref_index[2]; + uint32_t *mb_type_buf, *mb_type; } SVQ3Frame; typedef struct SVQ3Context { @@ -94,13 +92,11 @@ typedef struct SVQ3Context { GetBitContext gb; GetBitContext gb_slice; uint8_t *slice_buf; - int slice_size; + unsigned slice_buf_size; int halfpel_flag; int thirdpel_flag; int has_watermark; uint32_t watermark_key; - uint8_t *buf; - int buf_size; int adaptive_quant; int next_p_frame_damaged; int h_edge_pos; @@ -145,6 +141,7 @@ typedef struct SVQ3Context { DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15 * 8]; uint32_t dequant4_coeff[QP_MAX_NUM + 1][16]; int block_offset[2 * (16 * 3)]; + SVQ3Frame frames[3]; } SVQ3Context; #define FULLPEL_MODE 1 @@ -219,8 +216,6 @@ static const uint32_t svq3_dequant_coeff[32] = { 61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533 }; -static int svq3_decode_end(AVCodecContext *avctx); - static void svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp) { const unsigned qmul = svq3_dequant_coeff[qp]; @@ -1038,7 +1033,7 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) skip_bits(&s->gb, 8); - av_fast_malloc(&s->slice_buf, &s->slice_size, slice_bytes + AV_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&s->slice_buf, &s->slice_buf_size, slice_bytes); if (!s->slice_buf) return AVERROR(ENOMEM); @@ -1133,13 +1128,9 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) int marker_found = 0; int ret; - s->cur_pic = av_mallocz(sizeof(*s->cur_pic)); - s->last_pic = av_mallocz(sizeof(*s->last_pic)); - s->next_pic = av_mallocz(sizeof(*s->next_pic)); - if (!s->next_pic || !s->last_pic || !s->cur_pic) { - ret = AVERROR(ENOMEM); - goto fail; - } + s->cur_pic = &s->frames[0]; + s->last_pic = &s->frames[1]; + s->next_pic = &s->frames[2]; s->cur_pic->f = av_frame_alloc(); s->last_pic->f = av_frame_alloc(); @@ -1183,50 +1174,52 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) GetBitContext gb; int frame_size_code; int unk0, unk1, unk2, unk3, unk4; + int w,h; size = AV_RB32(&extradata[4]); - if (size > extradata_end - extradata - 8) { - ret = AVERROR_INVALIDDATA; - goto fail; - } + if (size > extradata_end - extradata - 8) + return AVERROR_INVALIDDATA; init_get_bits(&gb, extradata + 8, size * 8); /* 'frame size code' and optional 'width, height' */ frame_size_code = get_bits(&gb, 3); switch (frame_size_code) { case 0: - avctx->width = 160; - avctx->height = 120; + w = 160; + h = 120; break; case 1: - avctx->width = 128; - avctx->height = 96; + w = 128; + h = 96; break; case 2: - avctx->width = 176; - avctx->height = 144; + w = 176; + h = 144; break; case 3: - avctx->width = 352; - avctx->height = 288; + w = 352; + h = 288; break; case 4: - avctx->width = 704; - avctx->height = 576; + w = 704; + h = 576; break; case 5: - avctx->width = 240; - avctx->height = 180; + w = 240; + h = 180; break; case 6: - avctx->width = 320; - avctx->height = 240; + w = 320; + h = 240; break; case 7: - avctx->width = get_bits(&gb, 12); - avctx->height = get_bits(&gb, 12); + w = get_bits(&gb, 12); + h = get_bits(&gb, 12); break; } + ret = ff_set_dimensions(avctx, w, h); + if (ret < 0) + return ret; s->halfpel_flag = get_bits1(&gb); s->thirdpel_flag = get_bits1(&gb); @@ -1245,10 +1238,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "Unknown fields %d %d %d %d %d\n", unk0, unk1, unk2, unk3, unk4); - if (skip_1stop_8data_bits(&gb) < 0) { - ret = AVERROR_INVALIDDATA; - goto fail; - } + if (skip_1stop_8data_bits(&gb) < 0) + return AVERROR_INVALIDDATA; s->has_watermark = get_bits1(&gb); avctx->has_b_frames = !s->low_delay; @@ -1266,16 +1257,13 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) uint8_t *buf; if (watermark_height <= 0 || - (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) { - ret = -1; - goto fail; - } + (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) + return AVERROR_INVALIDDATA; buf = av_malloc(buf_len); - if (!buf) { - ret = AVERROR(ENOMEM); - goto fail; - } + if (!buf) + return AVERROR(ENOMEM); + av_log(avctx, AV_LOG_DEBUG, "watermark size: %ux%u\n", watermark_width, watermark_height); av_log(avctx, AV_LOG_DEBUG, @@ -1286,10 +1274,10 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "could not uncompress watermark logo\n"); av_free(buf); - ret = -1; - goto fail; + return -1; } - s->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0); + s->watermark_key = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_CCITT), 0, buf, buf_len)); + s->watermark_key = s->watermark_key << 16 | s->watermark_key; av_log(avctx, AV_LOG_DEBUG, "watermark key %#"PRIx32"\n", s->watermark_key); @@ -1297,8 +1285,7 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) #else av_log(avctx, AV_LOG_ERROR, "this svq3 file contains watermark which need zlib support compiled in\n"); - ret = -1; - goto fail; + return AVERROR(ENOSYS); #endif } } @@ -1330,19 +1317,15 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) init_dequant4_coeff_table(s); return 0; -fail: - svq3_decode_end(avctx); - return ret; } -static void free_picture(AVCodecContext *avctx, SVQ3Frame *pic) +static void free_picture(SVQ3Frame *pic) { int i; for (i = 0; i < 2; i++) { - av_buffer_unref(&pic->motion_val_buf[i]); - av_buffer_unref(&pic->ref_index_buf[i]); + av_freep(&pic->motion_val_buf[i]); } - av_buffer_unref(&pic->mb_type_buf); + av_freep(&pic->mb_type_buf); av_frame_unref(pic->f); } @@ -1351,7 +1334,6 @@ static int get_buffer(AVCodecContext *avctx, SVQ3Frame *pic) { SVQ3Context *s = avctx->priv_data; const int big_mb_num = s->mb_stride * (s->mb_height + 1) + 1; - const int mb_array_size = s->mb_stride * s->mb_height; const int b4_stride = s->mb_width * 4 + 1; const int b4_array_size = b4_stride * s->mb_height * 4; int ret; @@ -1359,21 +1341,19 @@ static int get_buffer(AVCodecContext *avctx, SVQ3Frame *pic) if (!pic->motion_val_buf[0]) { int i; - pic->mb_type_buf = av_buffer_allocz((big_mb_num + s->mb_stride) * sizeof(uint32_t)); + pic->mb_type_buf = av_calloc(big_mb_num + s->mb_stride, sizeof(uint32_t)); if (!pic->mb_type_buf) return AVERROR(ENOMEM); - pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * s->mb_stride + 1; + pic->mb_type = pic->mb_type_buf + 2 * s->mb_stride + 1; for (i = 0; i < 2; i++) { - pic->motion_val_buf[i] = av_buffer_allocz(2 * (b4_array_size + 4) * sizeof(int16_t)); - pic->ref_index_buf[i] = av_buffer_allocz(4 * mb_array_size); - if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) { + pic->motion_val_buf[i] = av_calloc(b4_array_size + 4, 2 * sizeof(int16_t)); + if (!pic->motion_val_buf[i]) { ret = AVERROR(ENOMEM); goto fail; } - pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4; - pic->ref_index[i] = pic->ref_index_buf[i]->data; + pic->motion_val[i] = pic->motion_val_buf[i] + 4; } } @@ -1391,7 +1371,7 @@ static int get_buffer(AVCodecContext *avctx, SVQ3Frame *pic) return 0; fail: - free_picture(avctx, pic); + free_picture(pic); return ret; } @@ -1401,7 +1381,6 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, SVQ3Context *s = avctx->priv_data; int buf_size = avpkt->size; int left; - uint8_t *buf; int ret, m, i; /* special case for last picture */ @@ -1418,17 +1397,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, s->mb_x = s->mb_y = s->mb_xy = 0; - if (s->watermark_key) { - av_fast_padded_malloc(&s->buf, &s->buf_size, buf_size); - if (!s->buf) - return AVERROR(ENOMEM); - memcpy(s->buf, avpkt->data, buf_size); - buf = s->buf; - } else { - buf = avpkt->data; - } - - ret = init_get_bits(&s->gb, buf, 8 * buf_size); + ret = init_get_bits8(&s->gb, avpkt->data, avpkt->size); if (ret < 0) return ret; @@ -1618,28 +1587,19 @@ static av_cold int svq3_decode_end(AVCodecContext *avctx) { SVQ3Context *s = avctx->priv_data; - free_picture(avctx, s->cur_pic); - free_picture(avctx, s->next_pic); - free_picture(avctx, s->last_pic); - av_frame_free(&s->cur_pic->f); - av_frame_free(&s->next_pic->f); - av_frame_free(&s->last_pic->f); - av_freep(&s->cur_pic); - av_freep(&s->next_pic); - av_freep(&s->last_pic); + for (int i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) { + free_picture(&s->frames[i]); + av_frame_free(&s->frames[i].f); + } av_freep(&s->slice_buf); av_freep(&s->intra4x4_pred_mode); av_freep(&s->edge_emu_buffer); av_freep(&s->mb2br_xy); - - av_freep(&s->buf); - s->buf_size = 0; - return 0; } -AVCodec ff_svq3_decoder = { +const AVCodec ff_svq3_decoder = { .name = "svq3", .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"), .type = AVMEDIA_TYPE_VIDEO, @@ -1653,4 +1613,5 @@ AVCodec ff_svq3_decoder = { AV_CODEC_CAP_DELAY, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE}, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, };