X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fansi.c;h=3f30ae90f5c452e165246b811d61d3705a425124;hb=78780c8bf6246a1cf1cd0c9096b49dc082a6a8e5;hp=892cc34fbb17b9cc2e3a04b81f3857506ae854f7;hpb=2912e87a6c9264d556734e2bf94a99c64cf9b102;p=ffmpeg diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c index 892cc34fbb1..3f30ae90f5c 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -24,9 +24,12 @@ * ASCII/ANSI art decoder */ +#include "libavutil/common.h" +#include "libavutil/frame.h" #include "libavutil/lfg.h" #include "avcodec.h" #include "cga_data.h" +#include "internal.h" #define ATTR_BOLD 0x01 /**< Bold/Bright-foreground (mode 1) */ #define ATTR_FAINT 0x02 /**< Faint (mode 2) */ @@ -47,7 +50,7 @@ static const uint8_t ansi_to_cga[16] = { }; typedef struct { - AVFrame frame; + AVFrame *frame; int x; /**< x cursor position (pixels) */ int y; /**< y cursor position (pixels) */ int sx; /**< saved x cursor position (pixels) */ @@ -73,7 +76,11 @@ typedef struct { static av_cold int decode_init(AVCodecContext *avctx) { AnsiContext *s = avctx->priv_data; - avctx->pix_fmt = PIX_FMT_PAL8; + avctx->pix_fmt = AV_PIX_FMT_PAL8; + + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); /* defaults */ s->font = ff_vga16_font; @@ -82,7 +89,7 @@ static av_cold int decode_init(AVCodecContext *avctx) s->bg = DEFAULT_BG_COLOR; if (!avctx->width || !avctx->height) - avcodec_set_dimensions(avctx, 80<<3, 25<<4); + ff_set_dimensions(avctx, 80 << 3, 25 << 4); return 0; } @@ -99,11 +106,11 @@ static void hscroll(AVCodecContext *avctx) i = 0; for (; i < avctx->height - s->font_height; i++) - memcpy(s->frame.data[0] + i * s->frame.linesize[0], - s->frame.data[0] + (i + s->font_height) * s->frame.linesize[0], + memcpy(s->frame->data[0] + i * s->frame->linesize[0], + s->frame->data[0] + (i + s->font_height) * s->frame->linesize[0], avctx->width); for (; i < avctx->height; i++) - memset(s->frame.data[0] + i * s->frame.linesize[0], + memset(s->frame->data[0] + i * s->frame->linesize[0], DEFAULT_BG_COLOR, avctx->width); } @@ -112,7 +119,7 @@ static void erase_line(AVCodecContext * avctx, int xoffset, int xlength) AnsiContext *s = avctx->priv_data; int i; for (i = 0; i < s->font_height; i++) - memset(s->frame.data[0] + (s->y + i)*s->frame.linesize[0] + xoffset, + memset(s->frame->data[0] + (s->y + i)*s->frame->linesize[0] + xoffset, DEFAULT_BG_COLOR, xlength); } @@ -121,7 +128,7 @@ static void erase_screen(AVCodecContext *avctx) AnsiContext *s = avctx->priv_data; int i; for (i = 0; i < avctx->height; i++) - memset(s->frame.data[0] + i * s->frame.linesize[0], DEFAULT_BG_COLOR, avctx->width); + memset(s->frame->data[0] + i * s->frame->linesize[0], DEFAULT_BG_COLOR, avctx->width); s->x = s->y = 0; } @@ -142,8 +149,8 @@ static void draw_char(AVCodecContext *avctx, int c) FFSWAP(int, fg, bg); if ((s->attributes & ATTR_CONCEALED)) fg = bg; - ff_draw_pc_font(s->frame.data[0] + s->y * s->frame.linesize[0] + s->x, - s->frame.linesize[0], s->font, s->font_height, c, fg, bg); + ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x, + s->frame->linesize[0], s->font, s->font_height, c, fg, bg); s->x += FONT_WIDTH; if (s->x >= avctx->width) { s->x = 0; @@ -153,7 +160,7 @@ static void draw_char(AVCodecContext *avctx, int c) /** * Execute ANSI escape code - * @param <0 error + * @return 0 on success, negative on error */ static int execute_code(AVCodecContext * avctx, int c) { @@ -215,20 +222,21 @@ static int execute_code(AVCodecContext * avctx, int c) height = 60<<4; break; default: - av_log_ask_for_sample(avctx, "unsupported screen mode\n"); + avpriv_request_sample(avctx, "Unsupported screen mode"); } if (width != avctx->width || height != avctx->height) { - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); - avcodec_set_dimensions(avctx, width, height); - ret = avctx->get_buffer(avctx, &s->frame); + av_frame_unref(s->frame); + ret = ff_set_dimensions(avctx, width, height); + if (ret < 0) + return ret; + ret = ff_get_buffer(avctx, s->frame, AV_GET_BUFFER_FLAG_REF); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - s->frame.pict_type = FF_I_TYPE; - s->frame.palette_has_changed = 1; - memcpy(s->frame.data[1], ff_cga_palette, 16 * 4); + s->frame->pict_type = AV_PICTURE_TYPE_I; + s->frame->palette_has_changed = 1; + memcpy(s->frame->data[1], ff_cga_palette, 16 * 4); erase_screen(avctx); } else if (c == 'l') { erase_screen(avctx); @@ -239,13 +247,13 @@ static int execute_code(AVCodecContext * avctx, int c) case 0: erase_line(avctx, s->x, avctx->width - s->x); if (s->y < avctx->height - s->font_height) - memset(s->frame.data[0] + (s->y + s->font_height)*s->frame.linesize[0], - DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame.linesize[0]); + memset(s->frame->data[0] + (s->y + s->font_height)*s->frame->linesize[0], + DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame->linesize[0]); break; case 1: erase_line(avctx, 0, s->x); if (s->y > 0) - memset(s->frame.data[0], DEFAULT_BG_COLOR, s->y * s->frame.linesize[0]); + memset(s->frame->data[0], DEFAULT_BG_COLOR, s->y * s->frame->linesize[0]); break; case 2: erase_screen(avctx); @@ -285,7 +293,7 @@ static int execute_code(AVCodecContext * avctx, int c) } else if (m == 49) { s->fg = ansi_to_cga[DEFAULT_BG_COLOR]; } else { - av_log_ask_for_sample(avctx, "unsupported rendition parameter\n"); + avpriv_request_sample(avctx, "Unsupported rendition parameter"); } } break; @@ -302,14 +310,14 @@ static int execute_code(AVCodecContext * avctx, int c) s->y = av_clip(s->sy, 0, avctx->height - s->font_height); break; default: - av_log_ask_for_sample(avctx, "unsupported escape code\n"); + avpriv_request_sample(avctx, "Unknown escape code"); break; } return 0; } static int decode_frame(AVCodecContext *avctx, - void *data, int *data_size, + void *data, int *got_frame, AVPacket *avpkt) { AnsiContext *s = avctx->priv_data; @@ -318,14 +326,19 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf_end = buf+buf_size; int ret, i, count; - ret = avctx->reget_buffer(avctx, &s->frame); + ret = ff_reget_buffer(avctx, s->frame); if (ret < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - s->frame.pict_type = FF_I_TYPE; - s->frame.palette_has_changed = 1; - memcpy(s->frame.data[1], ff_cga_palette, 16 * 4); + if (!avctx->frame_number) { + memset(s->frame->data[0], 0, avctx->height * FFABS(s->frame->linesize[0])); + memset(s->frame->data[1], 0, AVPALETTE_SIZE); + } + + s->frame->pict_type = AV_PICTURE_TYPE_I; + s->frame->palette_has_changed = 1; + memcpy(s->frame->data[1], ff_cga_palette, 16 * 4); while(buf < buf_end) { switch(s->state) { @@ -368,7 +381,6 @@ static int decode_frame(AVCodecContext *avctx, } else { s->state = STATE_NORMAL; draw_char(avctx, 0x1B); - return -1; continue; } break; @@ -395,8 +407,8 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_WARNING, "args overflow (%i)\n", s->nb_args); if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args]) s->nb_args++; - if (execute_code(avctx, buf[0]) < 0) - return -1; + if ((ret = execute_code(avctx, buf[0])) < 0) + return ret; s->state = STATE_NORMAL; } break; @@ -409,27 +421,28 @@ static int decode_frame(AVCodecContext *avctx, buf++; } - *data_size = sizeof(AVFrame); - *(AVFrame*)data = s->frame; + *got_frame = 1; + if ((ret = av_frame_ref(data, s->frame)) < 0) + return ret; return buf_size; } static av_cold int decode_close(AVCodecContext *avctx) { AnsiContext *s = avctx->priv_data; - if (s->frame.data[0]) - avctx->release_buffer(avctx, &s->frame); + + av_frame_free(&s->frame); return 0; } AVCodec ff_ansi_decoder = { .name = "ansi", + .long_name = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"), .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_ANSI, + .id = AV_CODEC_ID_ANSI, .priv_data_size = sizeof(AnsiContext), .init = decode_init, .close = decode_close, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"), };