X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fflashsv2enc.c;h=5e91367796354533e108125f62a03aa5c7e9767b;hb=6ad61e30a16d338eab23b649365813fb150066ef;hp=65db112696760cad31b3abead0b80bd68a96cb7c;hpb=a2ae381b5a6f50669bcbd37001c110567a61f446;p=ffmpeg diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c index 65db1126967..5e913677963 100644 --- a/libavcodec/flashsv2enc.c +++ b/libavcodec/flashsv2enc.c @@ -142,6 +142,7 @@ static void init_blocks(FlashSV2Context * s, Block * blocks, { int row, col; Block *b; + memset(blocks, 0, s->cols * s->rows * sizeof(*blocks)); for (col = 0; col < s->cols; col++) { for (row = 0; row < s->rows; row++) { b = blocks + (col + row * s->cols); @@ -158,7 +159,7 @@ static void init_blocks(FlashSV2Context * s, Block * blocks, b->enc = encbuf; b->data = databuf; encbuf += b->width * b->height * 3; - databuf += !databuf ? 0 : b->width * b->height * 6; + databuf = databuf ? databuf + b->width * b->height * 6 : NULL; } } } @@ -174,9 +175,37 @@ static void reset_stats(FlashSV2Context * s) #endif } +static int update_block_dimensions(FlashSV2Context *s, int block_width, int block_height) +{ + s->block_width = block_width; + s->block_height = block_height; + 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)) { + s->frame_blocks = av_realloc_array(s->frame_blocks, s->rows, s->cols * sizeof(Block)); + s->key_blocks = av_realloc_array(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 AVERROR(ENOMEM); + } + 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); + + av_fast_malloc(&s->blockbuffer, &s->blockbuffer_size, block_width * block_height * 6); + if (!s->blockbuffer) { + av_log(s->avctx, AV_LOG_ERROR, "Could not allocate block buffer.\n"); + return AVERROR(ENOMEM); + } + return 0; +} + + static av_cold int flashsv2_encode_init(AVCodecContext * avctx) { FlashSV2Context *s = avctx->priv_data; + int ret; s->avctx = avctx; @@ -186,23 +215,23 @@ static av_cold int flashsv2_encode_init(AVCodecContext * avctx) 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; + return AVERROR(EINVAL); } if ((avctx->width > 4095) || (avctx->height > 4095)) { av_log(avctx, AV_LOG_ERROR, "Input dimensions too large, input must be max 4095x4095 !\n"); - return -1; + return AVERROR(EINVAL); } if ((avctx->width < 16) || (avctx->height < 16)) { av_log(avctx, AV_LOG_ERROR, "Input dimensions too small, input must be at least 16x16 !\n"); - return -1; + return AVERROR(EINVAL); } - if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) - return -1; + if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) + return ret; s->last_key_frame = 0; @@ -210,33 +239,19 @@ static av_cold int flashsv2_encode_init(AVCodecContext * avctx) 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; - - if(!s->block_width) - s->block_width = 1; - if(!s->block_height) - s->block_height = 1; - - 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); - - s->blockbuffer = NULL; - s->blockbuffer_size = 0; + if (!s->encbuffer || !s->keybuffer || !s->databuffer + || !s->current_frame || !s->key_frame) { + av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n"); + return AVERROR(ENOMEM); + } - 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; @@ -245,15 +260,7 @@ static av_cold int flashsv2_encode_init(AVCodecContext * avctx) 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; + return update_block_dimensions(s, 64, 64); } static int new_key_frame(FlashSV2Context * s) @@ -801,29 +808,10 @@ static int reconfigure_at_keyframe(FlashSV2Context * s, const uint8_t * image, int block_width = optimum_block_width (s); int block_height = optimum_block_height(s); - s->rows = (s->image_height + block_height - 1) / block_height; - s->cols = (s->image_width + block_width - 1) / block_width; - if (block_width != s->block_width || block_height != s->block_height) { - s->block_width = block_width; - s->block_height = block_height; - if (s->rows * s->cols > s->blocks_size / sizeof(Block)) { - s->frame_blocks = av_realloc_array(s->frame_blocks, s->rows, s->cols * sizeof(Block)); - s->key_blocks = av_realloc_array(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); - - av_fast_malloc(&s->blockbuffer, &s->blockbuffer_size, block_width * block_height * 6); - if (!s->blockbuffer) { - av_log(s->avctx, AV_LOG_ERROR, "Could not allocate block buffer.\n"); - return AVERROR(ENOMEM); - } + res = update_block_dimensions(s, block_width, block_height); + if (res < 0) + return res; } s->use15_7 = optimum_use15_7(s); @@ -909,7 +897,7 @@ static av_cold int flashsv2_encode_end(AVCodecContext * avctx) return 0; } -AVCodec ff_flashsv2_encoder = { +const AVCodec ff_flashsv2_encoder = { .name = "flashsv2", .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video Version 2"), .type = AVMEDIA_TYPE_VIDEO, @@ -919,4 +907,5 @@ AVCodec ff_flashsv2_encoder = { .encode2 = flashsv2_encode_frame, .close = flashsv2_encode_end, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, };