1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Binary text demuxer 3cabdff1aSopenharmony_ci * eXtended BINary text (XBIN) demuxer 4cabdff1aSopenharmony_ci * Artworx Data Format demuxer 5cabdff1aSopenharmony_ci * iCEDraw File demuxer 6cabdff1aSopenharmony_ci * Copyright (c) 2010 Peter Ross <pross@xvid.org> 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * This file is part of FFmpeg. 9cabdff1aSopenharmony_ci * 10cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 11cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 12cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 13cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 14cabdff1aSopenharmony_ci * 15cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 16cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 17cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18cabdff1aSopenharmony_ci * Lesser General Public License for more details. 19cabdff1aSopenharmony_ci * 20cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 21cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 22cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23cabdff1aSopenharmony_ci */ 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci/** 26cabdff1aSopenharmony_ci * @file 27cabdff1aSopenharmony_ci * Binary text demuxer 28cabdff1aSopenharmony_ci * eXtended BINary text (XBIN) demuxer 29cabdff1aSopenharmony_ci * Artworx Data Format demuxer 30cabdff1aSopenharmony_ci * iCEDraw File demuxer 31cabdff1aSopenharmony_ci */ 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "config_components.h" 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 36cabdff1aSopenharmony_ci#include "libavutil/opt.h" 37cabdff1aSopenharmony_ci#include "libavutil/parseutils.h" 38cabdff1aSopenharmony_ci#include "avformat.h" 39cabdff1aSopenharmony_ci#include "internal.h" 40cabdff1aSopenharmony_ci#include "sauce.h" 41cabdff1aSopenharmony_ci#include "libavcodec/bintext.h" 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_citypedef struct { 44cabdff1aSopenharmony_ci const AVClass *class; 45cabdff1aSopenharmony_ci int chars_per_frame; /**< characters to send decoder per frame; 46cabdff1aSopenharmony_ci set by private options as characters per second, and then 47cabdff1aSopenharmony_ci converted to characters per frame at runtime */ 48cabdff1aSopenharmony_ci int width, height; /**< video size (WxH pixels) (private option) */ 49cabdff1aSopenharmony_ci AVRational framerate; /**< frames per second (private option) */ 50cabdff1aSopenharmony_ci uint64_t fsize; /**< file size less metadata buffer */ 51cabdff1aSopenharmony_ci} BinDemuxContext; 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_cistatic AVStream * init_stream(AVFormatContext *s) 54cabdff1aSopenharmony_ci{ 55cabdff1aSopenharmony_ci BinDemuxContext *bin = s->priv_data; 56cabdff1aSopenharmony_ci AVStream *st = avformat_new_stream(s, NULL); 57cabdff1aSopenharmony_ci if (!st) 58cabdff1aSopenharmony_ci return NULL; 59cabdff1aSopenharmony_ci st->codecpar->codec_tag = 0; 60cabdff1aSopenharmony_ci st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci if (!bin->width) { 63cabdff1aSopenharmony_ci st->codecpar->width = (80<<3); 64cabdff1aSopenharmony_ci st->codecpar->height = (25<<4); 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 60, bin->framerate.den, bin->framerate.num); 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_ci /* simulate tty display speed */ 70cabdff1aSopenharmony_ci bin->chars_per_frame = av_clip(av_q2d(st->time_base) * bin->chars_per_frame, 1, INT_MAX); 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ci return st; 73cabdff1aSopenharmony_ci} 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci#if CONFIG_BINTEXT_DEMUXER | CONFIG_ADF_DEMUXER | CONFIG_IDF_DEMUXER 76cabdff1aSopenharmony_ci/** 77cabdff1aSopenharmony_ci * Given filesize and width, calculate height (assume font_height of 16) 78cabdff1aSopenharmony_ci */ 79cabdff1aSopenharmony_cistatic void calculate_height(AVCodecParameters *par, uint64_t fsize) 80cabdff1aSopenharmony_ci{ 81cabdff1aSopenharmony_ci par->height = (fsize / ((par->width>>3)*2)) << 4; 82cabdff1aSopenharmony_ci} 83cabdff1aSopenharmony_ci#endif 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci#if CONFIG_BINTEXT_DEMUXER 86cabdff1aSopenharmony_cistatic const uint8_t next_magic[]={ 87cabdff1aSopenharmony_ci 0x1A, 0x1B, '[', '0', ';', '3', '0', ';', '4', '0', 'm', 'N', 'E', 'X', 'T', 0x00 88cabdff1aSopenharmony_ci}; 89cabdff1aSopenharmony_ci 90cabdff1aSopenharmony_cistatic int next_tag_read(AVFormatContext *avctx, uint64_t *fsize) 91cabdff1aSopenharmony_ci{ 92cabdff1aSopenharmony_ci AVIOContext *pb = avctx->pb; 93cabdff1aSopenharmony_ci char buf[36]; 94cabdff1aSopenharmony_ci int len; 95cabdff1aSopenharmony_ci uint64_t start_pos = avio_size(pb) - 256; 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci avio_seek(pb, start_pos, SEEK_SET); 98cabdff1aSopenharmony_ci if (avio_read(pb, buf, sizeof(next_magic)) != sizeof(next_magic)) 99cabdff1aSopenharmony_ci return -1; 100cabdff1aSopenharmony_ci if (memcmp(buf, next_magic, sizeof(next_magic))) 101cabdff1aSopenharmony_ci return -1; 102cabdff1aSopenharmony_ci if (avio_r8(pb) != 0x01) 103cabdff1aSopenharmony_ci return -1; 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_ci *fsize -= 256; 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci#define GET_EFI2_META(name,size) \ 108cabdff1aSopenharmony_ci len = avio_r8(pb); \ 109cabdff1aSopenharmony_ci if (len < 1 || len > size) \ 110cabdff1aSopenharmony_ci return -1; \ 111cabdff1aSopenharmony_ci if (avio_read(pb, buf, size) == size && *buf) { \ 112cabdff1aSopenharmony_ci buf[len] = 0; \ 113cabdff1aSopenharmony_ci av_dict_set(&avctx->metadata, name, buf, 0); \ 114cabdff1aSopenharmony_ci } 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci GET_EFI2_META("filename", 12) 117cabdff1aSopenharmony_ci GET_EFI2_META("author", 20) 118cabdff1aSopenharmony_ci GET_EFI2_META("publisher", 20) 119cabdff1aSopenharmony_ci GET_EFI2_META("title", 35) 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci return 0; 122cabdff1aSopenharmony_ci} 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_cistatic void predict_width(AVCodecParameters *par, uint64_t fsize, int got_width) 125cabdff1aSopenharmony_ci{ 126cabdff1aSopenharmony_ci /** attempt to guess width */ 127cabdff1aSopenharmony_ci if (!got_width) 128cabdff1aSopenharmony_ci par->width = fsize > 4000 ? (160<<3) : (80<<3); 129cabdff1aSopenharmony_ci} 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_cistatic int bin_probe(const AVProbeData *p) 132cabdff1aSopenharmony_ci{ 133cabdff1aSopenharmony_ci const uint8_t *d = p->buf; 134cabdff1aSopenharmony_ci int magic = 0, sauce = 0; 135cabdff1aSopenharmony_ci 136cabdff1aSopenharmony_ci if (p->buf_size > 256) 137cabdff1aSopenharmony_ci magic = !memcmp(d + p->buf_size - 256, next_magic, sizeof(next_magic)); 138cabdff1aSopenharmony_ci if (p->buf_size > 128) 139cabdff1aSopenharmony_ci sauce = !memcmp(d + p->buf_size - 128, "SAUCE00", 7); 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci if (magic) 142cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 143cabdff1aSopenharmony_ci 144cabdff1aSopenharmony_ci if (av_match_ext(p->filename, "bin")) { 145cabdff1aSopenharmony_ci AVCodecParameters par; 146cabdff1aSopenharmony_ci int got_width = 0; 147cabdff1aSopenharmony_ci par.width = par.height = 0; 148cabdff1aSopenharmony_ci if (sauce) 149cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 150cabdff1aSopenharmony_ci 151cabdff1aSopenharmony_ci predict_width(&par, p->buf_size, got_width); 152cabdff1aSopenharmony_ci if (par.width < 8) 153cabdff1aSopenharmony_ci return 0; 154cabdff1aSopenharmony_ci calculate_height(&par, p->buf_size); 155cabdff1aSopenharmony_ci if (par.height <= 0) 156cabdff1aSopenharmony_ci return 0; 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci if (par.width * par.height * 2 / (8*16) == p->buf_size) 159cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX / 2; 160cabdff1aSopenharmony_ci return 0; 161cabdff1aSopenharmony_ci } 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_ci if (sauce) 164cabdff1aSopenharmony_ci return 1; 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci return 0; 167cabdff1aSopenharmony_ci} 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_ci 170cabdff1aSopenharmony_cistatic int bintext_read_header(AVFormatContext *s) 171cabdff1aSopenharmony_ci{ 172cabdff1aSopenharmony_ci BinDemuxContext *bin = s->priv_data; 173cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 174cabdff1aSopenharmony_ci int ret; 175cabdff1aSopenharmony_ci AVStream *st = init_stream(s); 176cabdff1aSopenharmony_ci if (!st) 177cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 178cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_BINTEXT; 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci if ((ret = ff_alloc_extradata(st->codecpar, 2)) < 0) 181cabdff1aSopenharmony_ci return ret; 182cabdff1aSopenharmony_ci st->codecpar->extradata[0] = 16; 183cabdff1aSopenharmony_ci st->codecpar->extradata[1] = 0; 184cabdff1aSopenharmony_ci 185cabdff1aSopenharmony_ci if (pb->seekable & AVIO_SEEKABLE_NORMAL) { 186cabdff1aSopenharmony_ci int got_width = 0; 187cabdff1aSopenharmony_ci bin->fsize = avio_size(pb); 188cabdff1aSopenharmony_ci if (ff_sauce_read(s, &bin->fsize, &got_width, 0) < 0) 189cabdff1aSopenharmony_ci next_tag_read(s, &bin->fsize); 190cabdff1aSopenharmony_ci if (!bin->width) { 191cabdff1aSopenharmony_ci predict_width(st->codecpar, bin->fsize, got_width); 192cabdff1aSopenharmony_ci if (st->codecpar->width < 8) 193cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 194cabdff1aSopenharmony_ci calculate_height(st->codecpar, bin->fsize); 195cabdff1aSopenharmony_ci } 196cabdff1aSopenharmony_ci avio_seek(pb, 0, SEEK_SET); 197cabdff1aSopenharmony_ci } 198cabdff1aSopenharmony_ci return 0; 199cabdff1aSopenharmony_ci} 200cabdff1aSopenharmony_ci#endif /* CONFIG_BINTEXT_DEMUXER */ 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci#if CONFIG_XBIN_DEMUXER 203cabdff1aSopenharmony_cistatic int xbin_probe(const AVProbeData *p) 204cabdff1aSopenharmony_ci{ 205cabdff1aSopenharmony_ci const uint8_t *d = p->buf; 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci if (AV_RL32(d) == MKTAG('X','B','I','N') && d[4] == 0x1A && 208cabdff1aSopenharmony_ci AV_RL16(d+5) > 0 && AV_RL16(d+5) <= 160 && 209cabdff1aSopenharmony_ci d[9] > 0 && d[9] <= 32) 210cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX; 211cabdff1aSopenharmony_ci return 0; 212cabdff1aSopenharmony_ci} 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_cistatic int xbin_read_header(AVFormatContext *s) 215cabdff1aSopenharmony_ci{ 216cabdff1aSopenharmony_ci BinDemuxContext *bin = s->priv_data; 217cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 218cabdff1aSopenharmony_ci char fontheight, flags; 219cabdff1aSopenharmony_ci int ret; 220cabdff1aSopenharmony_ci AVStream *st = init_stream(s); 221cabdff1aSopenharmony_ci if (!st) 222cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 223cabdff1aSopenharmony_ci 224cabdff1aSopenharmony_ci avio_skip(pb, 5); 225cabdff1aSopenharmony_ci st->codecpar->width = avio_rl16(pb)<<3; 226cabdff1aSopenharmony_ci st->codecpar->height = avio_rl16(pb); 227cabdff1aSopenharmony_ci fontheight = avio_r8(pb); 228cabdff1aSopenharmony_ci st->codecpar->height *= fontheight; 229cabdff1aSopenharmony_ci flags = avio_r8(pb); 230cabdff1aSopenharmony_ci 231cabdff1aSopenharmony_ci st->codecpar->extradata_size = 2; 232cabdff1aSopenharmony_ci if ((flags & BINTEXT_PALETTE)) 233cabdff1aSopenharmony_ci st->codecpar->extradata_size += 48; 234cabdff1aSopenharmony_ci if ((flags & BINTEXT_FONT)) 235cabdff1aSopenharmony_ci st->codecpar->extradata_size += fontheight * (flags & 0x10 ? 512 : 256); 236cabdff1aSopenharmony_ci st->codecpar->codec_id = flags & 4 ? AV_CODEC_ID_XBIN : AV_CODEC_ID_BINTEXT; 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_ci ret = ff_alloc_extradata(st->codecpar, st->codecpar->extradata_size); 239cabdff1aSopenharmony_ci if (ret < 0) 240cabdff1aSopenharmony_ci return ret; 241cabdff1aSopenharmony_ci st->codecpar->extradata[0] = fontheight; 242cabdff1aSopenharmony_ci st->codecpar->extradata[1] = flags; 243cabdff1aSopenharmony_ci if (avio_read(pb, st->codecpar->extradata + 2, st->codecpar->extradata_size - 2) < 0) 244cabdff1aSopenharmony_ci return AVERROR(EIO); 245cabdff1aSopenharmony_ci 246cabdff1aSopenharmony_ci if (pb->seekable & AVIO_SEEKABLE_NORMAL) { 247cabdff1aSopenharmony_ci bin->fsize = avio_size(pb) - 9 - st->codecpar->extradata_size; 248cabdff1aSopenharmony_ci ff_sauce_read(s, &bin->fsize, NULL, 0); 249cabdff1aSopenharmony_ci avio_seek(pb, 9 + st->codecpar->extradata_size, SEEK_SET); 250cabdff1aSopenharmony_ci } 251cabdff1aSopenharmony_ci 252cabdff1aSopenharmony_ci return 0; 253cabdff1aSopenharmony_ci} 254cabdff1aSopenharmony_ci#endif /* CONFIG_XBIN_DEMUXER */ 255cabdff1aSopenharmony_ci 256cabdff1aSopenharmony_ci#if CONFIG_ADF_DEMUXER 257cabdff1aSopenharmony_cistatic int adf_read_header(AVFormatContext *s) 258cabdff1aSopenharmony_ci{ 259cabdff1aSopenharmony_ci BinDemuxContext *bin = s->priv_data; 260cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 261cabdff1aSopenharmony_ci AVStream *st; 262cabdff1aSopenharmony_ci int ret; 263cabdff1aSopenharmony_ci 264cabdff1aSopenharmony_ci if (avio_r8(pb) != 1) 265cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 266cabdff1aSopenharmony_ci 267cabdff1aSopenharmony_ci st = init_stream(s); 268cabdff1aSopenharmony_ci if (!st) 269cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 270cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_BINTEXT; 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci if ((ret = ff_alloc_extradata(st->codecpar, 2 + 48 + 4096)) < 0) 273cabdff1aSopenharmony_ci return ret; 274cabdff1aSopenharmony_ci st->codecpar->extradata[0] = 16; 275cabdff1aSopenharmony_ci st->codecpar->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT; 276cabdff1aSopenharmony_ci 277cabdff1aSopenharmony_ci if (avio_read(pb, st->codecpar->extradata + 2, 24) < 0) 278cabdff1aSopenharmony_ci return AVERROR(EIO); 279cabdff1aSopenharmony_ci avio_skip(pb, 144); 280cabdff1aSopenharmony_ci if (avio_read(pb, st->codecpar->extradata + 2 + 24, 24) < 0) 281cabdff1aSopenharmony_ci return AVERROR(EIO); 282cabdff1aSopenharmony_ci if (avio_read(pb, st->codecpar->extradata + 2 + 48, 4096) < 0) 283cabdff1aSopenharmony_ci return AVERROR(EIO); 284cabdff1aSopenharmony_ci 285cabdff1aSopenharmony_ci if (pb->seekable & AVIO_SEEKABLE_NORMAL) { 286cabdff1aSopenharmony_ci int got_width = 0; 287cabdff1aSopenharmony_ci bin->fsize = avio_size(pb) - 1 - 192 - 4096; 288cabdff1aSopenharmony_ci st->codecpar->width = 80<<3; 289cabdff1aSopenharmony_ci ff_sauce_read(s, &bin->fsize, &got_width, 0); 290cabdff1aSopenharmony_ci if (st->codecpar->width < 8) 291cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 292cabdff1aSopenharmony_ci if (!bin->width) 293cabdff1aSopenharmony_ci calculate_height(st->codecpar, bin->fsize); 294cabdff1aSopenharmony_ci avio_seek(pb, 1 + 192 + 4096, SEEK_SET); 295cabdff1aSopenharmony_ci } 296cabdff1aSopenharmony_ci return 0; 297cabdff1aSopenharmony_ci} 298cabdff1aSopenharmony_ci#endif /* CONFIG_ADF_DEMUXER */ 299cabdff1aSopenharmony_ci 300cabdff1aSopenharmony_ci#if CONFIG_IDF_DEMUXER 301cabdff1aSopenharmony_cistatic const uint8_t idf_magic[] = { 302cabdff1aSopenharmony_ci 0x04, 0x31, 0x2e, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x15, 0x00 303cabdff1aSopenharmony_ci}; 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_cistatic int idf_probe(const AVProbeData *p) 306cabdff1aSopenharmony_ci{ 307cabdff1aSopenharmony_ci if (p->buf_size < sizeof(idf_magic)) 308cabdff1aSopenharmony_ci return 0; 309cabdff1aSopenharmony_ci if (!memcmp(p->buf, idf_magic, sizeof(idf_magic))) 310cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX; 311cabdff1aSopenharmony_ci return 0; 312cabdff1aSopenharmony_ci} 313cabdff1aSopenharmony_ci 314cabdff1aSopenharmony_cistatic int idf_read_header(AVFormatContext *s) 315cabdff1aSopenharmony_ci{ 316cabdff1aSopenharmony_ci BinDemuxContext *bin = s->priv_data; 317cabdff1aSopenharmony_ci AVIOContext *pb = s->pb; 318cabdff1aSopenharmony_ci AVStream *st; 319cabdff1aSopenharmony_ci int got_width = 0, ret; 320cabdff1aSopenharmony_ci 321cabdff1aSopenharmony_ci if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) 322cabdff1aSopenharmony_ci return AVERROR(EIO); 323cabdff1aSopenharmony_ci 324cabdff1aSopenharmony_ci st = init_stream(s); 325cabdff1aSopenharmony_ci if (!st) 326cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 327cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_IDF; 328cabdff1aSopenharmony_ci 329cabdff1aSopenharmony_ci if ((ret = ff_alloc_extradata(st->codecpar, 2 + 48 + 4096)) < 0) 330cabdff1aSopenharmony_ci return ret; 331cabdff1aSopenharmony_ci st->codecpar->extradata[0] = 16; 332cabdff1aSopenharmony_ci st->codecpar->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT; 333cabdff1aSopenharmony_ci 334cabdff1aSopenharmony_ci avio_seek(pb, avio_size(pb) - 4096 - 48, SEEK_SET); 335cabdff1aSopenharmony_ci 336cabdff1aSopenharmony_ci if (avio_read(pb, st->codecpar->extradata + 2 + 48, 4096) < 0) 337cabdff1aSopenharmony_ci return AVERROR(EIO); 338cabdff1aSopenharmony_ci if (avio_read(pb, st->codecpar->extradata + 2, 48) < 0) 339cabdff1aSopenharmony_ci return AVERROR(EIO); 340cabdff1aSopenharmony_ci 341cabdff1aSopenharmony_ci bin->fsize = avio_size(pb) - 12 - 4096 - 48; 342cabdff1aSopenharmony_ci ff_sauce_read(s, &bin->fsize, &got_width, 0); 343cabdff1aSopenharmony_ci if (st->codecpar->width < 8) 344cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 345cabdff1aSopenharmony_ci if (!bin->width) 346cabdff1aSopenharmony_ci calculate_height(st->codecpar, bin->fsize); 347cabdff1aSopenharmony_ci avio_seek(pb, 12, SEEK_SET); 348cabdff1aSopenharmony_ci return 0; 349cabdff1aSopenharmony_ci} 350cabdff1aSopenharmony_ci#endif /* CONFIG_IDF_DEMUXER */ 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_cistatic int read_packet(AVFormatContext *s, 353cabdff1aSopenharmony_ci AVPacket *pkt) 354cabdff1aSopenharmony_ci{ 355cabdff1aSopenharmony_ci BinDemuxContext *bin = s->priv_data; 356cabdff1aSopenharmony_ci 357cabdff1aSopenharmony_ci if (bin->fsize > 0) { 358cabdff1aSopenharmony_ci if (av_get_packet(s->pb, pkt, bin->fsize) < 0) 359cabdff1aSopenharmony_ci return AVERROR(EIO); 360cabdff1aSopenharmony_ci bin->fsize = -1; /* done */ 361cabdff1aSopenharmony_ci } else if (!bin->fsize) { 362cabdff1aSopenharmony_ci if (avio_feof(s->pb)) 363cabdff1aSopenharmony_ci return AVERROR(EIO); 364cabdff1aSopenharmony_ci if (av_get_packet(s->pb, pkt, bin->chars_per_frame) < 0) 365cabdff1aSopenharmony_ci return AVERROR(EIO); 366cabdff1aSopenharmony_ci } else { 367cabdff1aSopenharmony_ci return AVERROR(EIO); 368cabdff1aSopenharmony_ci } 369cabdff1aSopenharmony_ci 370cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 371cabdff1aSopenharmony_ci return 0; 372cabdff1aSopenharmony_ci} 373cabdff1aSopenharmony_ci 374cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(BinDemuxContext, x) 375cabdff1aSopenharmony_cistatic const AVOption options[] = { 376cabdff1aSopenharmony_ci { "linespeed", "set simulated line speed (bytes per second)", OFFSET(chars_per_frame), AV_OPT_TYPE_INT, {.i64 = 6000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM}, 377cabdff1aSopenharmony_ci { "video_size", "set video size, such as 640x480 or hd720.", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, 378cabdff1aSopenharmony_ci { "framerate", "set framerate (frames per second)", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, 379cabdff1aSopenharmony_ci { NULL }, 380cabdff1aSopenharmony_ci}; 381cabdff1aSopenharmony_ci 382cabdff1aSopenharmony_ci#define CLASS(name) \ 383cabdff1aSopenharmony_ci(const AVClass[1]){{ \ 384cabdff1aSopenharmony_ci .class_name = name, \ 385cabdff1aSopenharmony_ci .item_name = av_default_item_name, \ 386cabdff1aSopenharmony_ci .option = options, \ 387cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, \ 388cabdff1aSopenharmony_ci}} 389cabdff1aSopenharmony_ci 390cabdff1aSopenharmony_ci#if CONFIG_BINTEXT_DEMUXER 391cabdff1aSopenharmony_ciconst AVInputFormat ff_bintext_demuxer = { 392cabdff1aSopenharmony_ci .name = "bin", 393cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("Binary text"), 394cabdff1aSopenharmony_ci .priv_data_size = sizeof(BinDemuxContext), 395cabdff1aSopenharmony_ci .read_probe = bin_probe, 396cabdff1aSopenharmony_ci .read_header = bintext_read_header, 397cabdff1aSopenharmony_ci .read_packet = read_packet, 398cabdff1aSopenharmony_ci .priv_class = CLASS("Binary text demuxer"), 399cabdff1aSopenharmony_ci}; 400cabdff1aSopenharmony_ci#endif 401cabdff1aSopenharmony_ci 402cabdff1aSopenharmony_ci#if CONFIG_XBIN_DEMUXER 403cabdff1aSopenharmony_ciconst AVInputFormat ff_xbin_demuxer = { 404cabdff1aSopenharmony_ci .name = "xbin", 405cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text (XBIN)"), 406cabdff1aSopenharmony_ci .priv_data_size = sizeof(BinDemuxContext), 407cabdff1aSopenharmony_ci .read_probe = xbin_probe, 408cabdff1aSopenharmony_ci .read_header = xbin_read_header, 409cabdff1aSopenharmony_ci .read_packet = read_packet, 410cabdff1aSopenharmony_ci .priv_class = CLASS("eXtended BINary text (XBIN) demuxer"), 411cabdff1aSopenharmony_ci}; 412cabdff1aSopenharmony_ci#endif 413cabdff1aSopenharmony_ci 414cabdff1aSopenharmony_ci#if CONFIG_ADF_DEMUXER 415cabdff1aSopenharmony_ciconst AVInputFormat ff_adf_demuxer = { 416cabdff1aSopenharmony_ci .name = "adf", 417cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("Artworx Data Format"), 418cabdff1aSopenharmony_ci .priv_data_size = sizeof(BinDemuxContext), 419cabdff1aSopenharmony_ci .read_header = adf_read_header, 420cabdff1aSopenharmony_ci .read_packet = read_packet, 421cabdff1aSopenharmony_ci .extensions = "adf", 422cabdff1aSopenharmony_ci .priv_class = CLASS("Artworx Data Format demuxer"), 423cabdff1aSopenharmony_ci}; 424cabdff1aSopenharmony_ci#endif 425cabdff1aSopenharmony_ci 426cabdff1aSopenharmony_ci#if CONFIG_IDF_DEMUXER 427cabdff1aSopenharmony_ciconst AVInputFormat ff_idf_demuxer = { 428cabdff1aSopenharmony_ci .name = "idf", 429cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("iCE Draw File"), 430cabdff1aSopenharmony_ci .priv_data_size = sizeof(BinDemuxContext), 431cabdff1aSopenharmony_ci .read_probe = idf_probe, 432cabdff1aSopenharmony_ci .read_header = idf_read_header, 433cabdff1aSopenharmony_ci .read_packet = read_packet, 434cabdff1aSopenharmony_ci .extensions = "idf", 435cabdff1aSopenharmony_ci .priv_class = CLASS("iCE Draw File demuxer"), 436cabdff1aSopenharmony_ci}; 437cabdff1aSopenharmony_ci#endif 438