Unified · Split
| @@ -54,6 +54,7 @@ easier to use. The changes are: · 53 unmodified lines | ||
| 54 | 54 | - Optional C++ Support (needed for libstagefright) |
| 55 | 55 | - H.264 Decoding on Android via Stagefright |
| 56 | 56 | - Prores decoder |
| 57 | +- BIN/XBIN/ADF/IDF text file decoder | |
| 57 | 58 | |
| 58 | 59 | |
| 59 | 60 | version 0.8: |
| @@ -51,6 +51,7 @@ library: · 50 unmodified lines | ||
| 51 | 51 | @tab Multimedia format used in games like Mad Dog McCree. |
| 52 | 52 | @item 3GPP AMR @tab X @tab X |
| 53 | 53 | @item Apple HTTP Live Streaming @tab @tab X |
| 54 | +@item Artworx Data Format @tab @tab X | |
| 54 | 55 | @item ASF @tab X @tab X |
| 55 | 56 | @item AVI @tab X @tab X |
| 56 | 57 | @item AVISynth @tab @tab X |
| @@ -60,6 +61,7 @@ library: · 3 unmodified lines | ||
| 60 | 61 | @tab Audio and video format used in some games by Beam Software. |
| 61 | 62 | @item Bethesda Softworks VID @tab @tab X |
| 62 | 63 | @tab Used in some games from Bethesda Softworks. |
| 64 | +@item Binary text @tab @tab C | |
| 63 | 65 | @item Bink @tab @tab X |
| 64 | 66 | @tab Multimedia format used by many games. |
| 65 | 67 | @item Bitmap Brothers JV @tab @tab X |
| @@ -106,6 +108,7 @@ library: · 40 unmodified lines | ||
| 106 | 108 | @item GXF @tab X @tab X |
| 107 | 109 | @tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley |
| 108 | 110 | playout servers. |
| 111 | +@item iCEDraw File @tab @tab X | |
| 109 | 112 | @item id Quake II CIN video @tab @tab X |
| 110 | 113 | @item id RoQ @tab X @tab X |
| 111 | 114 | @tab Used in Quake III, Jedi Knight 2, other computer games. |
| @@ -267,6 +270,7 @@ library: · 155 unmodified lines | ||
| 267 | 270 | @tab Microsoft video container used in Xbox games. |
| 268 | 271 | @item xWMA @tab @tab X |
| 269 | 272 | @tab Microsoft audio container used by XAudio 2. |
| 273 | +@item eXtended BINary text (XBIN) @tab @tab X | |
| 270 | 274 | @item YUV4MPEG pipe @tab X @tab X |
| 271 | 275 | @item Psygnosis YOP @tab @tab X |
| 272 | 276 | @end multitable |
| @@ -96,6 +96,7 @@ OBJS-$(CONFIG_BFI_DECODER) += bfi.o · 95 unmodified lines | ||
| 96 | 96 | OBJS-$(CONFIG_BINK_DECODER) += bink.o binkdsp.o |
| 97 | 97 | OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o wma.o |
| 98 | 98 | OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o wma.o |
| 99 | +OBJS-$(CONFIG_BINTEXT_DECODER) += bintext.o cga_data.o | |
| 99 | 100 | OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o |
| 100 | 101 | OBJS-$(CONFIG_BMP_ENCODER) += bmpenc.o |
| 101 | 102 | OBJS-$(CONFIG_C93_DECODER) += c93.o |
| @@ -188,6 +189,7 @@ OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o · 86 unmodified lines | ||
| 188 | 189 | OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o |
| 189 | 190 | OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o |
| 190 | 191 | OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o |
| 192 | +OBJS-$(CONFIG_IDF_DECODER) += bintext.o cga_data.o | |
| 191 | 193 | OBJS-$(CONFIG_IFF_BYTERUN1_DECODER) += iff.o |
| 192 | 194 | OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o |
| 193 | 195 | OBJS-$(CONFIG_IMC_DECODER) += imc.o |
| @@ -440,6 +442,7 @@ OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o · 246 unmodified lines | ||
| 440 | 442 | OBJS-$(CONFIG_XAN_DPCM_DECODER) += dpcm.o |
| 441 | 443 | OBJS-$(CONFIG_XAN_WC3_DECODER) += xan.o |
| 442 | 444 | OBJS-$(CONFIG_XAN_WC4_DECODER) += xxan.o |
| 445 | +OBJS-$(CONFIG_XBIN_DECODER) += bintext.o cga_data.o | |
| 443 | 446 | OBJS-$(CONFIG_XL_DECODER) += xl.o |
| 444 | 447 | OBJS-$(CONFIG_XSUB_DECODER) += xsubdec.o |
| 445 | 448 | OBJS-$(CONFIG_XSUB_ENCODER) += xsubenc.o |
| @@ -393,6 +393,11 @@ void avcodec_register_all(void) · 392 unmodified lines | ||
| 393 | 393 | REGISTER_ENCODER (LIBXAVS, libxavs); |
| 394 | 394 | REGISTER_ENCODER (LIBXVID, libxvid); |
| 395 | 395 | |
| 396 | + /* text */ | |
| 397 | + REGISTER_DECODER (BINTEXT, bintext); | |
| 398 | + REGISTER_DECODER (XBIN, xbin); | |
| 399 | + REGISTER_DECODER (IDF, idf); | |
| 400 | + | |
| 396 | 401 | /* parsers */ |
| 397 | 402 | REGISTER_PARSER (AAC, aac); |
| 398 | 403 | REGISTER_PARSER (AAC_LATM, aac_latm); |
| @@ -361,6 +361,9 @@ enum CodecID { · 360 unmodified lines | ||
| 361 | 361 | /* other specific kind of codecs (generally used for attachments) */ |
| 362 | 362 | CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs. |
| 363 | 363 | CODEC_ID_TTF= 0x18000, |
| 364 | + CODEC_ID_BINTEXT, | |
| 365 | + CODEC_ID_XBIN, | |
| 366 | + CODEC_ID_IDF, | |
| 364 | 367 | |
| 365 | 368 | CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it |
| 366 | 369 | |
| @@ -0,0 +1,252 @@ | ||
| 1 | +/* | |
| 2 | + * Binary text decoder | |
| 3 | + * eXtended BINary text (XBIN) decoder | |
| 4 | + * iCEDraw File decoder | |
| 5 | + * Copyright (c) 2010 Peter Ross (pross@xvid.org) | |
| 6 | + * | |
| 7 | + * This file is part of FFmpeg. | |
| 8 | + * | |
| 9 | + * FFmpeg is free software; you can redistribute it and/or | |
| 10 | + * modify it under the terms of the GNU Lesser General Public | |
| 11 | + * License as published by the Free Software Foundation; either | |
| 12 | + * version 2.1 of the License, or (at your option) any later version. | |
| 13 | + * | |
| 14 | + * FFmpeg is distributed in the hope that it will be useful, | |
| 15 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 17 | + * Lesser General Public License for more details. | |
| 18 | + * | |
| 19 | + * You should have received a copy of the GNU Lesser General Public | |
| 20 | + * License along with FFmpeg; if not, write to the Free Software | |
| 21 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 22 | + */ | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * @file libavcodec/xbin.c | |
| 26 | + * Binary text decoder | |
| 27 | + * eXtended BINary text (XBIN) decoder | |
| 28 | + * iCEDraw File decoder | |
| 29 | + */ | |
| 30 | + | |
| 31 | +#include "libavutil/intreadwrite.h" | |
| 32 | +#include "avcodec.h" | |
| 33 | +#include "cga_data.h" | |
| 34 | +#include "bintext.h" | |
| 35 | + | |
| 36 | +typedef struct XbinContext { | |
| 37 | + AVFrame frame; | |
| 38 | + int palette[16]; | |
| 39 | + int flags; | |
| 40 | + int font_height; | |
| 41 | + const uint8_t *font; | |
| 42 | + int x, y; | |
| 43 | +} XbinContext; | |
| 44 | + | |
| 45 | +static av_cold int decode_init(AVCodecContext *avctx) | |
| 46 | +{ | |
| 47 | + XbinContext *s = avctx->priv_data; | |
| 48 | + uint8_t *p; | |
| 49 | + int i; | |
| 50 | + | |
| 51 | + avctx->pix_fmt = PIX_FMT_PAL8; | |
| 52 | + s->frame.reference = 1; | |
| 53 | + if (avctx->get_buffer(avctx, &s->frame)) { | |
| 54 | + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
| 55 | + return -1; | |
| 56 | + } | |
| 57 | + | |
| 58 | + p = avctx->extradata; | |
| 59 | + if (p) { | |
| 60 | + s->font_height = p[0]; | |
| 61 | + s->flags = p[1]; | |
| 62 | + p += 2; | |
| 63 | + } else { | |
| 64 | + s->font_height = 8; | |
| 65 | + s->flags = 0; | |
| 66 | + } | |
| 67 | + | |
| 68 | + if ((s->flags & BINTEXT_PALETTE)) { | |
| 69 | + for (i = 0; i < 16; i++) { | |
| 70 | + s->palette[i] = 0xFF000000 | (AV_RB24(p) << 2); | |
| 71 | + p += 3; | |
| 72 | + } | |
| 73 | + } else { | |
| 74 | + for (i = 0; i < 16; i++) | |
| 75 | + s->palette[i] = 0xFF000000 | ff_cga_palette[i]; | |
| 76 | + } | |
| 77 | + | |
| 78 | + if ((s->flags & BINTEXT_FONT)) { | |
| 79 | + s->font = p; | |
| 80 | + } else { | |
| 81 | + switch(s->font_height) { | |
| 82 | + default: | |
| 83 | + av_log(avctx, AV_LOG_WARNING, "font height %i not support\n", s->font_height); | |
| 84 | + s->font_height = 8; | |
| 85 | + case 8: | |
| 86 | + s->font = ff_cga_font; | |
| 87 | + break; | |
| 88 | + case 16: | |
| 89 | + s->font = ff_vga16_font; | |
| 90 | + break; | |
| 91 | + } | |
| 92 | + } | |
| 93 | + | |
| 94 | + return 0; | |
| 95 | +} | |
| 96 | + | |
| 97 | +#define DEFAULT_BG_COLOR 0 | |
| 98 | +static void hscroll(AVCodecContext *avctx) | |
| 99 | +{ | |
| 100 | + XbinContext *s = avctx->priv_data; | |
| 101 | + if (s->y < avctx->height - s->font_height) { | |
| 102 | + s->y += s->font_height; | |
| 103 | + } else { | |
| 104 | + memmove(s->frame.data[0], s->frame.data[0] + s->font_height*s->frame.linesize[0], | |
| 105 | + (avctx->height - s->font_height)*s->frame.linesize[0]); | |
| 106 | + memset(s->frame.data[0] + (avctx->height - s->font_height)*s->frame.linesize[0], | |
| 107 | + DEFAULT_BG_COLOR, s->font_height * s->frame.linesize[0]); | |
| 108 | + } | |
| 109 | +} | |
| 110 | + | |
| 111 | +#define FONT_WIDTH 8 | |
| 112 | + | |
| 113 | +/** | |
| 114 | + * Draw character to screen | |
| 115 | + */ | |
| 116 | +static void draw_char(AVCodecContext *avctx, int c, int a) | |
| 117 | +{ | |
| 118 | + XbinContext *s = avctx->priv_data; | |
| 119 | + if (s->y > avctx->height - s->font_height) | |
| 120 | + return; | |
| 121 | + ff_draw_pc_font(s->frame.data[0] + s->y * s->frame.linesize[0] + s->x, | |
| 122 | + s->frame.linesize[0], s->font, s->font_height, c, | |
| 123 | + a & 0x0F, a >> 4); | |
| 124 | + s->x += FONT_WIDTH; | |
| 125 | + if (s->x >= avctx->width) { | |
| 126 | + s->x = 0; | |
| 127 | + s->y += s->font_height; | |
| 128 | + } | |
| 129 | +} | |
| 130 | + | |
| 131 | +static int decode_frame(AVCodecContext *avctx, | |
| 132 | + void *data, int *data_size, | |
| 133 | + AVPacket *avpkt) | |
| 134 | +{ | |
| 135 | + XbinContext *s = avctx->priv_data; | |
| 136 | + const uint8_t *buf = avpkt->data; | |
| 137 | + int buf_size = avpkt->size; | |
| 138 | + const uint8_t *buf_end = buf+buf_size; | |
| 139 | + | |
| 140 | + if (avctx->reget_buffer(avctx, &s->frame)) { | |
| 141 | + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
| 142 | + return -1; | |
| 143 | + } | |
| 144 | + s->frame.pict_type = FF_I_TYPE; | |
| 145 | + s->frame.palette_has_changed = 1; | |
| 146 | + memcpy(s->frame.data[1], s->palette, 16 * 4); | |
| 147 | + | |
| 148 | + if (avctx->codec_id == CODEC_ID_XBIN) { | |
| 149 | + while (buf + 2 < buf_end) { | |
| 150 | + int i,c,a; | |
| 151 | + int type = *buf >> 6; | |
| 152 | + int count = (*buf & 0x3F) + 1; | |
| 153 | + buf++; | |
| 154 | + switch (type) { | |
| 155 | + case 0: //no compression | |
| 156 | + for (i = 0; i < count && buf + 1 < buf_end; i++) { | |
| 157 | + draw_char(avctx, buf[0], buf[1]); | |
| 158 | + buf += 2; | |
| 159 | + } | |
| 160 | + break; | |
| 161 | + case 1: //character compression | |
| 162 | + c = *buf++; | |
| 163 | + for (i = 0; i < count && buf < buf_end; i++) | |
| 164 | + draw_char(avctx, c, *buf++); | |
| 165 | + break; | |
| 166 | + case 2: //attribute compression | |
| 167 | + a = *buf++; | |
| 168 | + for (i = 0; i < count && buf < buf_end; i++) | |
| 169 | + draw_char(avctx, *buf++, a); | |
| 170 | + break; | |
| 171 | + case 3: //character/attribute compression | |
| 172 | + c = *buf++; | |
| 173 | + a = *buf++; | |
| 174 | + for (i = 0; i < count && buf < buf_end; i++) | |
| 175 | + draw_char(avctx, c, a); | |
| 176 | + break; | |
| 177 | + } | |
| 178 | + } | |
| 179 | + } else if (avctx->codec_id == CODEC_ID_IDF) { | |
| 180 | + while (buf + 2 < buf_end) { | |
| 181 | + if (AV_RL16(buf) == 1) { | |
| 182 | + int i; | |
| 183 | + if (buf + 6 > buf_end) | |
| 184 | + break; | |
| 185 | + for (i = 0; i < buf[2]; i++) | |
| 186 | + draw_char(avctx, buf[4], buf[5]); | |
| 187 | + buf += 6; | |
| 188 | + } else { | |
| 189 | + draw_char(avctx, buf[0], buf[1]); | |
| 190 | + buf += 2; | |
| 191 | + } | |
| 192 | + } | |
| 193 | + } else { | |
| 194 | + while (buf + 1 < buf_end) { | |
| 195 | + draw_char(avctx, buf[0], buf[1]); | |
| 196 | + buf += 2; | |
| 197 | + } | |
| 198 | + } | |
| 199 | + | |
| 200 | + *data_size = sizeof(AVFrame); | |
| 201 | + *(AVFrame*)data = s->frame; | |
| 202 | + return buf_size; | |
| 203 | +} | |
| 204 | + | |
| 205 | +static av_cold int decode_end(AVCodecContext *avctx) | |
| 206 | +{ | |
| 207 | + XbinContext *s = avctx->priv_data; | |
| 208 | + | |
| 209 | + if (s->frame.data[0]) | |
| 210 | + avctx->release_buffer(avctx, &s->frame); | |
| 211 | + | |
| 212 | + return 0; | |
| 213 | +} | |
| 214 | + | |
| 215 | +AVCodec ff_bintext_decoder = { | |
| 216 | + "xbin", | |
| 217 | + AVMEDIA_TYPE_VIDEO, | |
| 218 | + CODEC_ID_BINTEXT, | |
| 219 | + sizeof(XbinContext), | |
| 220 | + decode_init, | |
| 221 | + NULL, | |
| 222 | + decode_end, | |
| 223 | + decode_frame, | |
| 224 | + CODEC_CAP_DR1, | |
| 225 | + .long_name = NULL_IF_CONFIG_SMALL("Binary text"), | |
| 226 | +}; | |
| 227 | + | |
| 228 | +AVCodec ff_xbin_decoder = { | |
| 229 | + "xbin", | |
| 230 | + AVMEDIA_TYPE_VIDEO, | |
| 231 | + CODEC_ID_XBIN, | |
| 232 | + sizeof(XbinContext), | |
| 233 | + decode_init, | |
| 234 | + NULL, | |
| 235 | + decode_end, | |
| 236 | + decode_frame, | |
| 237 | + CODEC_CAP_DR1, | |
| 238 | + .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text"), | |
| 239 | +}; | |
| 240 | + | |
| 241 | +AVCodec ff_idf_decoder = { | |
| 242 | + "idf", | |
| 243 | + AVMEDIA_TYPE_VIDEO, | |
| 244 | + CODEC_ID_IDF, | |
| 245 | + sizeof(XbinContext), | |
| 246 | + decode_init, | |
| 247 | + NULL, | |
| 248 | + decode_end, | |
| 249 | + decode_frame, | |
| 250 | + CODEC_CAP_DR1, | |
| 251 | + .long_name = NULL_IF_CONFIG_SMALL("iCEDraw text"), | |
| 252 | +}; | |
| @@ -0,0 +1,37 @@ | ||
| 1 | +/* | |
| 2 | + * Binary text decoder | |
| 3 | + * Copyright (c) 2010 Peter Ross (pross@xvid.org) | |
| 4 | + * | |
| 5 | + * This file is part of FFmpeg. | |
| 6 | + * | |
| 7 | + * FFmpeg is free software; you can redistribute it and/or | |
| 8 | + * modify it under the terms of the GNU Lesser General Public | |
| 9 | + * License as published by the Free Software Foundation; either | |
| 10 | + * version 2.1 of the License, or (at your option) any later version. | |
| 11 | + * | |
| 12 | + * FFmpeg is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 | + * Lesser General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU Lesser General Public | |
| 18 | + * License along with FFmpeg; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 20 | + */ | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * @file | |
| 24 | + * Binary text decoder | |
| 25 | + */ | |
| 26 | + | |
| 27 | +#ifndef AVCODEC_BINTEXT_H | |
| 28 | +#define AVCODEC_BINTEXT_H | |
| 29 | + | |
| 30 | +/* flag values passed between avformat and avcodec; | |
| 31 | + * while these are identical to the XBIN flags, they are are also used | |
| 32 | + * for the BINTEXT and IDF decoders. | |
| 33 | + */ | |
| 34 | +#define BINTEXT_PALETTE 0x1 | |
| 35 | +#define BINTEXT_FONT 0x2 | |
| 36 | + | |
| 37 | +#endif /* AVCODEC_BINTEXT_H */ | |
| @@ -21,6 +21,7 @@ OBJS-$(CONFIG_A64_MUXER) += a64.o · 20 unmodified lines | ||
| 21 | 21 | OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o rawdec.o |
| 22 | 22 | OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o |
| 23 | 23 | OBJS-$(CONFIG_AC3_MUXER) += rawenc.o |
| 24 | +OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o | |
| 24 | 25 | OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o |
| 25 | 26 | OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o |
| 26 | 27 | OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o isom.o |
| @@ -46,6 +47,7 @@ OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o · 19 unmodified lines | ||
| 46 | 47 | OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o |
| 47 | 48 | OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o |
| 48 | 49 | OBJS-$(CONFIG_BINK_DEMUXER) += bink.o |
| 50 | +OBJS-$(CONFIG_BINTEXT_DEMUXER) += bintext.o sauce.o | |
| 49 | 51 | OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o |
| 50 | 52 | OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o riff.o isom.o |
| 51 | 53 | OBJS-$(CONFIG_CAF_MUXER) += cafenc.o caf.o riff.o isom.o |
| @@ -100,6 +102,7 @@ OBJS-$(CONFIG_H263_MUXER) += rawenc.o · 48 unmodified lines | ||
| 100 | 102 | OBJS-$(CONFIG_H264_DEMUXER) += h264dec.o rawdec.o |
| 101 | 103 | OBJS-$(CONFIG_H264_MUXER) += rawenc.o |
| 102 | 104 | OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o |
| 105 | +OBJS-$(CONFIG_IDF_DEMUXER) += bintext.o | |
| 103 | 106 | OBJS-$(CONFIG_IFF_DEMUXER) += iff.o |
| 104 | 107 | OBJS-$(CONFIG_IMAGE2_DEMUXER) += img2.o |
| 105 | 108 | OBJS-$(CONFIG_IMAGE2_MUXER) += img2.o |
| @@ -308,6 +311,7 @@ OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv.o asfdec.o asf.o asfcry · 202 unmodified lines | ||
| 308 | 311 | OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv.o asf.o riff.o |
| 309 | 312 | OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o |
| 310 | 313 | OBJS-$(CONFIG_XA_DEMUXER) += xa.o |
| 314 | +OBJS-$(CONFIG_XBIN_DEMUXER) += bintext.o sauce.o | |
| 311 | 315 | OBJS-$(CONFIG_XMV_DEMUXER) += xmv.o |
| 312 | 316 | OBJS-$(CONFIG_XWMA_DEMUXER) += xwma.o riff.o |
| 313 | 317 | OBJS-$(CONFIG_YOP_DEMUXER) += yop.o |
| @@ -51,6 +51,7 @@ void av_register_all(void) · 50 unmodified lines | ||
| 51 | 51 | REGISTER_MUXER (A64, a64); |
| 52 | 52 | REGISTER_DEMUXER (AAC, aac); |
| 53 | 53 | REGISTER_MUXDEMUX (AC3, ac3); |
| 54 | + REGISTER_DEMUXER (ADF, adf); | |
| 54 | 55 | REGISTER_MUXER (ADTS, adts); |
| 55 | 56 | REGISTER_DEMUXER (AEA, aea); |
| 56 | 57 | REGISTER_MUXDEMUX (AIFF, aiff); |
| @@ -69,6 +70,7 @@ void av_register_all(void) · 12 unmodified lines | ||
| 69 | 70 | REGISTER_DEMUXER (AVS, avs); |
| 70 | 71 | REGISTER_DEMUXER (BETHSOFTVID, bethsoftvid); |
| 71 | 72 | REGISTER_DEMUXER (BFI, bfi); |
| 73 | + REGISTER_DEMUXER (BINTEXT, bintext); | |
| 72 | 74 | REGISTER_DEMUXER (BINK, bink); |
| 73 | 75 | REGISTER_DEMUXER (C93, c93); |
| 74 | 76 | REGISTER_MUXDEMUX (CAF, caf); |
| @@ -103,6 +105,7 @@ void av_register_all(void) · 28 unmodified lines | ||
| 103 | 105 | REGISTER_MUXDEMUX (H263, h263); |
| 104 | 106 | REGISTER_MUXDEMUX (H264, h264); |
| 105 | 107 | REGISTER_DEMUXER (IDCIN, idcin); |
| 108 | + REGISTER_DEMUXER (IDF, idf); | |
| 106 | 109 | REGISTER_DEMUXER (IFF, iff); |
| 107 | 110 | REGISTER_MUXDEMUX (IMAGE2, image2); |
| 108 | 111 | REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe); |
| @@ -229,6 +232,7 @@ void av_register_all(void) · 120 unmodified lines | ||
| 229 | 232 | REGISTER_MUXDEMUX (WTV, wtv); |
| 230 | 233 | REGISTER_DEMUXER (WV, wv); |
| 231 | 234 | REGISTER_DEMUXER (XA, xa); |
| 235 | + REGISTER_DEMUXER (XBIN, xbin); | |
| 232 | 236 | REGISTER_DEMUXER (XMV, xmv); |
| 233 | 237 | REGISTER_DEMUXER (XWMA, xwma); |
| 234 | 238 | REGISTER_DEMUXER (YOP, yop); |
| @@ -0,0 +1,376 @@ | ||
| 1 | +/* | |
| 2 | + * Binary text demuxer | |
| 3 | + * eXtended BINary text (XBIN) demuxer | |
| 4 | + * Artworx Data Format demuxer | |
| 5 | + * iCEDraw File demuxer | |
| 6 | + * Copyright (c) 2010 Peter Ross <pross@xvid.org> | |
| 7 | + * | |
| 8 | + * This file is part of FFmpeg. | |
| 9 | + * | |
| 10 | + * FFmpeg is free software; you can redistribute it and/or | |
| 11 | + * modify it under the terms of the GNU Lesser General Public | |
| 12 | + * License as published by the Free Software Foundation; either | |
| 13 | + * version 2.1 of the License, or (at your option) any later version. | |
| 14 | + * | |
| 15 | + * FFmpeg is distributed in the hope that it will be useful, | |
| 16 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 17 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 18 | + * Lesser General Public License for more details. | |
| 19 | + * | |
| 20 | + * You should have received a copy of the GNU Lesser General Public | |
| 21 | + * License along with FFmpeg; if not, write to the Free Software | |
| 22 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 23 | + */ | |
| 24 | + | |
| 25 | +/** | |
| 26 | + * @file | |
| 27 | + * Binary text demuxer | |
| 28 | + * eXtended BINary text (XBIN) demuxer | |
| 29 | + * Artworx Data Format demuxer | |
| 30 | + * iCEDraw File demuxer | |
| 31 | + */ | |
| 32 | + | |
| 33 | +#include "libavutil/intreadwrite.h" | |
| 34 | +#include "avformat.h" | |
| 35 | +#include "sauce.h" | |
| 36 | +#include "libavcodec/bintext.h" | |
| 37 | + | |
| 38 | +#define LINE_RATE 6000 /** characters per second */ | |
| 39 | + | |
| 40 | +typedef struct { | |
| 41 | + int chars_per_frame; | |
| 42 | + uint64_t fsize; /**< file size less metadata buffer */ | |
| 43 | +} BinDemuxContext; | |
| 44 | + | |
| 45 | +#if CONFIG_BINTEXT_DEMUXER | CONFIG_ADF_DEMUXER | CONFIG_IDF_DEMUXER | |
| 46 | +/** | |
| 47 | + * Given filesize and width, calculate height (assume font_height of 16) | |
| 48 | + */ | |
| 49 | +static void calculate_height(AVCodecContext *avctx, uint64_t fsize) | |
| 50 | +{ | |
| 51 | + avctx->height = (fsize / ((avctx->width>>3)*2)) << 4; | |
| 52 | +} | |
| 53 | +#endif | |
| 54 | + | |
| 55 | +#if CONFIG_BINTEXT_DEMUXER | |
| 56 | +static const uint8_t next_magic[]={ | |
| 57 | + 0x1A, 0x1B, '[', '0', ';', '3', '0', ';', '4', '0', 'm', 'N', 'E', 'X', 'T', 0x00 | |
| 58 | +}; | |
| 59 | + | |
| 60 | +static int next_tag_read(AVFormatContext *avctx, uint64_t *fsize) | |
| 61 | +{ | |
| 62 | + ByteIOContext *pb = avctx->pb; | |
| 63 | + char buf[36]; | |
| 64 | + int len; | |
| 65 | + uint64_t start_pos = url_fsize(pb) - 256; | |
| 66 | + | |
| 67 | + url_fseek(pb, start_pos, SEEK_SET); | |
| 68 | + if (get_buffer(pb, buf, sizeof(next_magic)) != sizeof(next_magic)) | |
| 69 | + return -1; | |
| 70 | + if (memcmp(buf, next_magic, sizeof(next_magic))) | |
| 71 | + return -1; | |
| 72 | + if (get_byte(pb) != 0x01) | |
| 73 | + return -1; | |
| 74 | + | |
| 75 | + *fsize -= 256; | |
| 76 | + | |
| 77 | +#define GET_EFI2_META(name,size) \ | |
| 78 | + len = get_byte(pb); \ | |
| 79 | + if (len < 1 || len > size) \ | |
| 80 | + return -1; \ | |
| 81 | + if (get_buffer(pb, buf, size) == size && *buf) { \ | |
| 82 | + buf[len] = 0; \ | |
| 83 | + av_metadata_set2(&avctx->metadata, name, buf, 0); \ | |
| 84 | + } | |
| 85 | + | |
| 86 | + GET_EFI2_META("filename", 12) | |
| 87 | + GET_EFI2_META("author", 20) | |
| 88 | + GET_EFI2_META("publisher", 20) | |
| 89 | + GET_EFI2_META("title", 35) | |
| 90 | + | |
| 91 | + return 0; | |
| 92 | +} | |
| 93 | + | |
| 94 | +static void predict_width(AVCodecContext *avctx, uint64_t fsize, int got_width) | |
| 95 | +{ | |
| 96 | + /** attempt to guess width */ | |
| 97 | + if (!got_width) | |
| 98 | + avctx->width = fsize > 4000 ? (160<<3) : (80<<3); | |
| 99 | +} | |
| 100 | + | |
| 101 | +static AVStream * init_stream(AVFormatContext *s, | |
| 102 | + AVFormatParameters *ap) | |
| 103 | +{ | |
| 104 | + BinDemuxContext *bin = s->priv_data; | |
| 105 | + AVStream *st = av_new_stream(s, 0); | |
| 106 | + if (!st) | |
| 107 | + return NULL; | |
| 108 | + st->codec->codec_tag = 0; | |
| 109 | + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; | |
| 110 | + | |
| 111 | + if (!ap->time_base.num) { | |
| 112 | + av_set_pts_info(st, 60, 1, 25); | |
| 113 | + } else { | |
| 114 | + av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den); | |
| 115 | + } | |
| 116 | + | |
| 117 | + /* simulate tty display speed */ | |
| 118 | + bin->chars_per_frame = FFMAX(av_q2d(st->time_base) * (ap->sample_rate ? ap->sample_rate : LINE_RATE), 1); | |
| 119 | + | |
| 120 | + st->codec->width = ap->width ? ap->width : (80<<3); | |
| 121 | + st->codec->height = ap->height ? ap->height : (25<<4); | |
| 122 | + return st; | |
| 123 | +} | |
| 124 | + | |
| 125 | +static int bintext_read_header(AVFormatContext *s, | |
| 126 | + AVFormatParameters *ap) | |
| 127 | +{ | |
| 128 | + BinDemuxContext *bin = s->priv_data; | |
| 129 | + ByteIOContext *pb = s->pb; | |
| 130 | + | |
| 131 | + AVStream *st = init_stream(s, ap); | |
| 132 | + if (!st) | |
| 133 | + return AVERROR(ENOMEM); | |
| 134 | + st->codec->codec_id = CODEC_ID_BINTEXT; | |
| 135 | + | |
| 136 | + st->codec->extradata_size = 2; | |
| 137 | + st->codec->extradata = av_malloc(st->codec->extradata_size); | |
| 138 | + if (!st->codec->extradata) | |
| 139 | + return AVERROR(ENOMEM); | |
| 140 | + st->codec->extradata[0] = 16; | |
| 141 | + st->codec->extradata[1] = 0; | |
| 142 | + | |
| 143 | + if (!url_is_streamed(pb)) { | |
| 144 | + int got_width = 0; | |
| 145 | + bin->fsize = url_fsize(pb); | |
| 146 | + if (ff_sauce_read(s, &bin->fsize, &got_width, 0) < 0) | |
| 147 | + next_tag_read(s, &bin->fsize); | |
| 148 | + if (!ap->width) | |
| 149 | + predict_width(st->codec, bin->fsize, got_width); | |
| 150 | + if (!ap->height) | |
| 151 | + calculate_height(st->codec, bin->fsize); | |
| 152 | + url_fseek(pb, 0, SEEK_SET); | |
| 153 | + } | |
| 154 | + return 0; | |
| 155 | +}; | |
| 156 | +#endif /* CONFIG_BINTEXT_DEMUXER */ | |
| 157 | + | |
| 158 | +#if CONFIG_XBIN_DEMUXER | |
| 159 | +static int xbin_probe(AVProbeData *p) | |
| 160 | +{ | |
| 161 | + const uint8_t *d = p->buf; | |
| 162 | + | |
| 163 | + if (AV_RL32(d) == MKTAG('X','B','I','N') && d[4] == 0x1A && | |
| 164 | + AV_RL16(d+5) > 0 && AV_RL16(d+5) <= 160 && | |
| 165 | + d[9] > 0 && d[9] <= 32) | |
| 166 | + return AVPROBE_SCORE_MAX; | |
| 167 | + return 0; | |
| 168 | +} | |
| 169 | + | |
| 170 | +static int xbin_read_header(AVFormatContext *s, | |
| 171 | + AVFormatParameters *ap) | |
| 172 | +{ | |
| 173 | + BinDemuxContext *bin = s->priv_data; | |
| 174 | + ByteIOContext *pb = s->pb; | |
| 175 | + char fontheight, flags; | |
| 176 | + uint8_t *h; | |
| 177 | + | |
| 178 | + AVStream *st = init_stream(s, ap); | |
| 179 | + if (!st) | |
| 180 | + return AVERROR(ENOMEM); | |
| 181 | + | |
| 182 | + url_fskip(pb, 5); | |
| 183 | + st->codec->width = get_le16(pb)<<3; | |
| 184 | + st->codec->height = get_le16(pb); | |
| 185 | + fontheight = get_byte(pb); | |
| 186 | + st->codec->height *= fontheight; | |
| 187 | + flags = get_byte(pb); | |
| 188 | + | |
| 189 | + st->codec->extradata_size = 2; | |
| 190 | + if ((flags & BINTEXT_PALETTE)) | |
| 191 | + st->codec->extradata_size += 48; | |
| 192 | + if ((flags & BINTEXT_FONT)) | |
| 193 | + st->codec->extradata_size += fontheight * (flags & 0x10 ? 512 : 256); | |
| 194 | + st->codec->codec_id = flags & 4 ? CODEC_ID_XBIN : CODEC_ID_BINTEXT; | |
| 195 | + | |
| 196 | + h = st->codec->extradata = av_malloc(st->codec->extradata_size); | |
| 197 | + if (!st->codec->extradata) | |
| 198 | + return AVERROR(ENOMEM); | |
| 199 | + st->codec->extradata[0] = fontheight; | |
| 200 | + st->codec->extradata[1] = flags; | |
| 201 | + if (get_buffer(pb, st->codec->extradata + 2, st->codec->extradata_size - 2) < 0) | |
| 202 | + return AVERROR(EIO); | |
| 203 | + | |
| 204 | + if (!url_is_streamed(pb)) { | |
| 205 | + bin->fsize = url_fsize(pb) - 9 - st->codec->extradata_size; | |
| 206 | + ff_sauce_read(s, &bin->fsize, NULL, 0); | |
| 207 | + url_fseek(pb, 9 + st->codec->extradata_size, SEEK_SET); | |
| 208 | + } | |
| 209 | + | |
| 210 | + return 0; | |
| 211 | +} | |
| 212 | +#endif /* CONFIG_XBIN_DEMUXER */ | |
| 213 | + | |
| 214 | +#if CONFIG_ADF_DEMUXER | |
| 215 | +static int adf_read_header(AVFormatContext *s, | |
| 216 | + AVFormatParameters *ap) | |
| 217 | +{ | |
| 218 | + BinDemuxContext *bin = s->priv_data; | |
| 219 | + ByteIOContext *pb = s->pb; | |
| 220 | + AVStream *st; | |
| 221 | + | |
| 222 | + if (get_byte(pb) != 1) | |
| 223 | + return AVERROR_INVALIDDATA; | |
| 224 | + | |
| 225 | + st = init_stream(s, ap); | |
| 226 | + if (!st) | |
| 227 | + return AVERROR(ENOMEM); | |
| 228 | + st->codec->codec_id = CODEC_ID_BINTEXT; | |
| 229 | + | |
| 230 | + st->codec->extradata_size = 2 + 48 + 4096; | |
| 231 | + st->codec->extradata = av_malloc(st->codec->extradata_size); | |
| 232 | + if (!st->codec->extradata) | |
| 233 | + return AVERROR(ENOMEM); | |
| 234 | + st->codec->extradata[0] = 16; | |
| 235 | + st->codec->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT; | |
| 236 | + | |
| 237 | + if (get_buffer(pb, st->codec->extradata + 2, 24) < 0) | |
| 238 | + return AVERROR(EIO); | |
| 239 | + url_fskip(pb, 144); | |
| 240 | + if (get_buffer(pb, st->codec->extradata + 2 + 24, 24) < 0) | |
| 241 | + return AVERROR(EIO); | |
| 242 | + if (get_buffer(pb, st->codec->extradata + 2 + 48, 4096) < 0) | |
| 243 | + return AVERROR(EIO); | |
| 244 | + | |
| 245 | + if (!url_is_streamed(pb)) { | |
| 246 | + int got_width = 0; | |
| 247 | + bin->fsize = url_fsize(pb) - 1 - 192 - 4096; | |
| 248 | + st->codec->width = 80<<3; | |
| 249 | + ff_sauce_read(s, &bin->fsize, &got_width, 0); | |
| 250 | + if (!ap->height) | |
| 251 | + calculate_height(st->codec, bin->fsize); | |
| 252 | + url_fseek(pb, 1 + 192 + 4096, SEEK_SET); | |
| 253 | + } | |
| 254 | + return 0; | |
| 255 | +} | |
| 256 | +#endif /* CONFIG_ADF_DEMUXER */ | |
| 257 | + | |
| 258 | +#if CONFIG_IDF_DEMUXER | |
| 259 | +static const uint8_t idf_magic[] = { | |
| 260 | + 0x04, 0x31, 0x2e, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x15, 0x00 | |
| 261 | +}; | |
| 262 | + | |
| 263 | +static int idf_probe(AVProbeData *p) | |
| 264 | +{ | |
| 265 | + if (!memcmp(p->buf, idf_magic, FFMIN(sizeof(idf_magic), p->buf_size))) | |
| 266 | + return AVPROBE_SCORE_MAX; | |
| 267 | + return 0; | |
| 268 | +} | |
| 269 | + | |
| 270 | +static int idf_read_header(AVFormatContext *s, | |
| 271 | + AVFormatParameters *ap) | |
| 272 | +{ | |
| 273 | + BinDemuxContext *bin = s->priv_data; | |
| 274 | + ByteIOContext *pb = s->pb; | |
| 275 | + AVStream *st; | |
| 276 | + int got_width = 0; | |
| 277 | + | |
| 278 | + if (url_is_streamed(pb)) | |
| 279 | + return AVERROR(EIO); | |
| 280 | + | |
| 281 | + st = init_stream(s, ap); | |
| 282 | + if (!st) | |
| 283 | + return AVERROR(ENOMEM); | |
| 284 | + st->codec->codec_id = CODEC_ID_IDF; | |
| 285 | + | |
| 286 | + st->codec->extradata_size = 2 + 48 + 4096; | |
| 287 | + st->codec->extradata = av_malloc(st->codec->extradata_size); | |
| 288 | + if (!st->codec->extradata) | |
| 289 | + return AVERROR(ENOMEM); | |
| 290 | + st->codec->extradata[0] = 16; | |
| 291 | + st->codec->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT; | |
| 292 | + | |
| 293 | + url_fseek(pb, url_fsize(pb) - 4096 - 48, SEEK_SET); | |
| 294 | + | |
| 295 | + if (get_buffer(pb, st->codec->extradata + 2 + 48, 4096) < 0) | |
| 296 | + return AVERROR(EIO); | |
| 297 | + if (get_buffer(pb, st->codec->extradata + 2, 48) < 0) | |
| 298 | + return AVERROR(EIO); | |
| 299 | + | |
| 300 | + bin->fsize = url_fsize(pb) - 12 - 4096 - 48; | |
| 301 | + ff_sauce_read(s, &bin->fsize, &got_width, 0); | |
| 302 | + if (!ap->height) | |
| 303 | + calculate_height(st->codec, bin->fsize); | |
| 304 | + url_fseek(pb, 12, SEEK_SET); | |
| 305 | + return 0; | |
| 306 | +} | |
| 307 | +#endif /* CONFIG_IDF_DEMUXER */ | |
| 308 | + | |
| 309 | +static int read_packet(AVFormatContext *s, | |
| 310 | + AVPacket *pkt) | |
| 311 | +{ | |
| 312 | + BinDemuxContext *bin = s->priv_data; | |
| 313 | + | |
| 314 | + if (bin->fsize > 0) { | |
| 315 | + if (av_get_packet(s->pb, pkt, bin->fsize) < 0) | |
| 316 | + return AVERROR(EIO); | |
| 317 | + bin->fsize = -1; /* done */ | |
| 318 | + } else if (!bin->fsize) { | |
| 319 | + if (url_feof(s->pb)) | |
| 320 | + return AVERROR(EIO); | |
| 321 | + if (av_get_packet(s->pb, pkt, bin->chars_per_frame) < 0) | |
| 322 | + return AVERROR(EIO); | |
| 323 | + } else { | |
| 324 | + return AVERROR(EIO); | |
| 325 | + } | |
| 326 | + | |
| 327 | + pkt->flags |= AV_PKT_FLAG_KEY; | |
| 328 | + return 0; | |
| 329 | +} | |
| 330 | + | |
| 331 | +#if CONFIG_BINTEXT_DEMUXER | |
| 332 | +AVInputFormat ff_bintext_demuxer = { | |
| 333 | + "bin", | |
| 334 | + NULL_IF_CONFIG_SMALL("Binary text"), | |
| 335 | + sizeof(BinDemuxContext), | |
| 336 | + NULL, | |
| 337 | + bintext_read_header, | |
| 338 | + read_packet, | |
| 339 | + .extensions = "bin", | |
| 340 | +}; | |
| 341 | +#endif | |
| 342 | + | |
| 343 | +#if CONFIG_XBIN_DEMUXER | |
| 344 | +AVInputFormat ff_xbin_demuxer = { | |
| 345 | + "xbin", | |
| 346 | + NULL_IF_CONFIG_SMALL("eXtended BINary text (XBIN)"), | |
| 347 | + sizeof(BinDemuxContext), | |
| 348 | + xbin_probe, | |
| 349 | + xbin_read_header, | |
| 350 | + read_packet, | |
| 351 | +}; | |
| 352 | +#endif | |
| 353 | + | |
| 354 | +#if CONFIG_ADF_DEMUXER | |
| 355 | +AVInputFormat ff_adf_demuxer = { | |
| 356 | + "adf", | |
| 357 | + NULL_IF_CONFIG_SMALL("Artworx Data Format"), | |
| 358 | + sizeof(BinDemuxContext), | |
| 359 | + NULL, | |
| 360 | + adf_read_header, | |
| 361 | + read_packet, | |
| 362 | + .extensions = "adf", | |
| 363 | +}; | |
| 364 | +#endif | |
| 365 | + | |
| 366 | +#if CONFIG_IDF_DEMUXER | |
| 367 | +AVInputFormat ff_idf_demuxer = { | |
| 368 | + "idf", | |
| 369 | + NULL_IF_CONFIG_SMALL("iCE Draw File"), | |
| 370 | + sizeof(BinDemuxContext), | |
| 371 | + idf_probe, | |
| 372 | + idf_read_header, | |
| 373 | + read_packet, | |
| 374 | + .extensions = "idf", | |
| 375 | +}; | |
| 376 | +#endif | |