Tele-typewriter demuxer

Originally committed as revision 24301 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Peter Ross 2010-07-18 08:06:55 +00:00
parent 0459bf2d02
commit 5a71709467
6 changed files with 137 additions and 1 deletions

View File

@ -21,6 +21,7 @@ version <next>:
- ffplay -exitonkeydown and -exitonmousedown options added
- native GSM / GSM MS decoder
- RTP depacketization of QDM2
- ANSI/ASCII art playback system

View File

@ -228,6 +228,7 @@ library:
@item Sony Wave64 (W64) @tab @tab X
@item SoX native format @tab X @tab X
@item SUN AU format @tab X @tab X
@item Text files @tab @tab X
@item THP @tab @tab X
@tab Used on the Nintendo GameCube.
@item Tiertex Limited SEQ @tab @tab X
@ -316,6 +317,7 @@ following image formats are supported:
@tab Used in games like Mad Dog McCree.
@item AMV Video @tab @tab X
@tab Used in Chinese MP3 players.
@item ANSI/ASCII art @tab @tab X
@item Apple MJPEG-B @tab @tab X
@item Apple QuickDraw @tab @tab X
@tab fourcc: qdrw

View File

@ -249,6 +249,7 @@ OBJS-$(CONFIG_TMV_DEMUXER) += tmv.o
OBJS-$(CONFIG_TRUEHD_DEMUXER) += raw.o
OBJS-$(CONFIG_TRUEHD_MUXER) += raw.o
OBJS-$(CONFIG_TTA_DEMUXER) += tta.o id3v1.o id3v2.o
OBJS-$(CONFIG_TTY_DEMUXER) += tty.o sauce.o
OBJS-$(CONFIG_TXD_DEMUXER) += txd.o
OBJS-$(CONFIG_VC1_DEMUXER) += raw.o
OBJS-$(CONFIG_VC1T_DEMUXER) += vc1test.o

View File

@ -198,6 +198,7 @@ void av_register_all(void)
REGISTER_MUXDEMUX (TRUEHD, truehd);
REGISTER_DEMUXER (TTA, tta);
REGISTER_DEMUXER (TXD, txd);
REGISTER_DEMUXER (TTY, tty);
REGISTER_DEMUXER (VC1, vc1);
REGISTER_MUXDEMUX (VC1T, vc1t);
REGISTER_DEMUXER (VMD, vmd);

View File

@ -22,7 +22,7 @@
#define AVFORMAT_AVFORMAT_H
#define LIBAVFORMAT_VERSION_MAJOR 52
#define LIBAVFORMAT_VERSION_MINOR 74
#define LIBAVFORMAT_VERSION_MINOR 75
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \

131
libavformat/tty.c Normal file
View File

@ -0,0 +1,131 @@
/*
* @file
* Tele-typewriter demuxer
* Copyright (c) 2010 Peter Ross <pross@xvid.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/intreadwrite.h"
#include "libavutil/avstring.h"
#include "avformat.h"
#include "sauce.h"
#include <strings.h>
#define LINE_RATE 6000 /* characters per second */
typedef struct {
int chars_per_frame;
uint64_t fsize; /** file size less metadata buffer */
} TtyDemuxContext;
/**
* Parse EFI header
*/
static int efi_read(AVFormatContext *avctx, uint64_t start_pos)
{
TtyDemuxContext *s = avctx->priv_data;
ByteIOContext *pb = avctx->pb;
char buf[37];
int len;
url_fseek(pb, start_pos, SEEK_SET);
if (get_byte(pb) != 0x1A)
return -1;
#define GET_EFI_META(name,size) \
len = get_byte(pb); \
if (len < 1 || len > size) \
return -1; \
if (get_buffer(pb, buf, size) == size) { \
buf[len] = 0; \
av_metadata_set2(&avctx->metadata, name, buf, 0); \
}
GET_EFI_META("filename", 12)
GET_EFI_META("title", 36)
s->fsize = start_pos;
return 0;
}
static int read_header(AVFormatContext *avctx,
AVFormatParameters *ap)
{
TtyDemuxContext *s = avctx->priv_data;
AVStream *st = av_new_stream(avctx, 0);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_tag = 0;
st->codec->codec_type = CODEC_TYPE_VIDEO;
st->codec->codec_id = CODEC_ID_ANSI;
if (ap->width) st->codec->width = ap->width;
if (ap->height) st->codec->height = ap->height;
if (!ap->time_base.num) {
av_set_pts_info(st, 60, 1, 25);
} else {
av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den);
}
/* simulate tty display speed */
s->chars_per_frame = FFMAX(av_q2d(st->time_base) * (ap->sample_rate ? ap->sample_rate : LINE_RATE), 1);
if (!url_is_streamed(avctx->pb)) {
s->fsize = url_fsize(avctx->pb);
st->duration = (s->fsize + s->chars_per_frame - 1) / s->chars_per_frame;
if (ff_sauce_read(avctx, &s->fsize, 0, 0) < 0)
efi_read(avctx, s->fsize - 51);
url_fseek(avctx->pb, 0, SEEK_SET);
}
return 0;
}
static int read_packet(AVFormatContext *avctx, AVPacket *pkt)
{
TtyDemuxContext *s = avctx->priv_data;
int n;
if (url_feof(avctx->pb))
return AVERROR_EOF;
n = s->chars_per_frame;
if (s->fsize) {
// ignore metadata buffer
uint64_t p = url_ftell(avctx->pb);
if (p + s->chars_per_frame > s->fsize)
n = s->fsize - p;
}
pkt->size = av_get_packet(avctx->pb, pkt, n);
if (pkt->size <= 0)
return AVERROR(EIO);
pkt->flags |= PKT_FLAG_KEY;
return 0;
}
AVInputFormat tty_demuxer = {
.name = "tty",
.long_name = NULL_IF_CONFIG_SMALL("Tele-typewriter"),
.priv_data_size = sizeof(TtyDemuxContext),
.read_header = read_header,
.read_packet = read_packet,
.extensions = "ans,art,asc,diz,ice,nfo,txt,vt",
};