[FFmpeg-devel] [PATCH] 8088flex TMV demuxer and decoder

Daniel Verkamp daniel
Wed May 6 10:28:30 CEST 2009


On Fri, Apr 24, 2009 at 12:01 PM, Michael Niedermayer <michaelni at gmx.at> wrote:
> ss On Fri, Apr 24, 2009 at 05:48:02PM +0200, Reimar D?ffinger wrote:
>> On Fri, Apr 24, 2009 at 09:59:05AM -0500, Daniel Verkamp wrote:
>> > Hmm, I get the same "any seek resets to beginning" behavior with
>> > ffplay and the nirvana.nuv file from samples.mphq (the nuv demuxer
>> > seems to do what you're saying too, setting AVFMT_GENERIC_INDEX and
>> > PKT_FLAG_KEY). ?Seeking in general in ffplay seems to work fine (at
>> > least mpeg).
>>
>> I vaguely remember something. I think ffplay always tries to seek
>> relative to the full duration,
>
> cursor keys shouldnt use the duration i think ...
>
>
>> but gets the duration completely wrong.
>
> why dont you set the duration in the demuxer? (and or the bitrates of all
> streams?)
>

New demuxer patch attached, which now sets the bitrate for video
stream, resulting in correct automatic calculation of duration based
on file size.

Anything else needed for the demuxer?  CGA data and decoder are
already OK'd by Michael earlier in this thread.

Thanks,
-- Daniel Verkamp
-------------- next part --------------
>From 07794fc50d4e2abc86512ac113d9b018d2de9141 Mon Sep 17 00:00:00 2001
From: Daniel Verkamp <daniel at drv.nu>
Date: Fri, 24 Apr 2009 10:00:25 -0500
Subject: [PATCH 3/3] 8088flex TMV demuxer

---
 libavformat/Makefile     |    1 +
 libavformat/allformats.c |    1 +
 libavformat/tmv.c        |  151 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 153 insertions(+), 0 deletions(-)
 create mode 100644 libavformat/tmv.c

diff --git a/libavformat/Makefile b/libavformat/Makefile
index 55717e6..b9e5eb7 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -210,6 +210,7 @@ OBJS-$(CONFIG_TG2_MUXER)                 += movenc.o riff.o isom.o avc.o
 OBJS-$(CONFIG_TGP_MUXER)                 += movenc.o riff.o isom.o avc.o
 OBJS-$(CONFIG_THP_DEMUXER)               += thp.o
 OBJS-$(CONFIG_TIERTEXSEQ_DEMUXER)        += tiertexseq.o
+OBJS-$(CONFIG_TMV_DEMUXER)               += tmv.o
 OBJS-$(CONFIG_TRUEHD_DEMUXER)            += raw.o id3v2.o
 OBJS-$(CONFIG_TRUEHD_MUXER)              += raw.o
 OBJS-$(CONFIG_TTA_DEMUXER)               += tta.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index e193af7..626b66c 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -182,6 +182,7 @@ void av_register_all(void)
     REGISTER_MUXER    (TGP, tgp);
     REGISTER_DEMUXER  (THP, thp);
     REGISTER_DEMUXER  (TIERTEXSEQ, tiertexseq);
+    REGISTER_DEMUXER  (TMV, tmv);
     REGISTER_MUXDEMUX (TRUEHD, truehd);
     REGISTER_DEMUXER  (TTA, tta);
     REGISTER_DEMUXER  (TXD, txd);
diff --git a/libavformat/tmv.c b/libavformat/tmv.c
new file mode 100644
index 0000000..c21042a
--- /dev/null
+++ b/libavformat/tmv.c
@@ -0,0 +1,151 @@
+/*
+ * 8088flex TMV file demuxer
+ * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
+ *
+ * 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
+ */
+
+/**
+ * 8088flex TMV file demuxer
+ * @file libavformat/tmv.c
+ * @author Daniel Verkamp
+ * @sa http://www.oldskool.org/pc/8088_Corruption
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avformat.h"
+
+enum {
+    TMV_PADDING = 0x01,
+    TMV_STEREO  = 0x02,
+};
+
+#define TMV_TAG MKTAG('T', 'M', 'A', 'V')
+
+typedef struct TMVContext {
+    unsigned audio_chunk_size;
+    unsigned comp_method;
+    unsigned char_cols;
+    unsigned char_rows;
+    unsigned features;
+
+    unsigned padding;
+
+    unsigned stream_index;
+} TMVContext;
+
+static int tmv_probe(AVProbeData *p)
+{
+    if (AV_RL32(p->buf) == TMV_TAG)
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int tmv_read_header(AVFormatContext *s, AVFormatParameters *ap)
+{
+    TMVContext *tmv   = s->priv_data;
+    ByteIOContext *pb = s->pb;
+    AVStream *vst, *ast;
+    AVRational fps;
+
+    if (get_le32(pb) != TMV_TAG)
+        return -1;
+
+    if (!(vst = av_new_stream(s, 0)))
+        return AVERROR(ENOMEM);
+
+    if (!(ast = av_new_stream(s, 0)))
+        return AVERROR(ENOMEM);
+
+    ast->codec->sample_rate = get_le16(pb);
+    tmv->audio_chunk_size   = get_le16(pb);
+    tmv->comp_method        = get_byte(pb);
+    if (tmv->comp_method) {
+        av_log(s, AV_LOG_ERROR, "unsupported compression method %d\n",
+               tmv->comp_method);
+        return -1;
+    }
+
+    tmv->char_cols = get_byte(pb);
+    tmv->char_rows = get_byte(pb);
+
+    tmv->features  = get_byte(pb);
+    if (tmv->features & ~(TMV_PADDING | TMV_STEREO)) {
+        av_log(s, AV_LOG_ERROR, "unsupported features 0x%02x\n",
+               tmv->features & ~(TMV_PADDING | TMV_STEREO));
+        return -1;
+    }
+
+    ast->codec->codec_type            = CODEC_TYPE_AUDIO;
+    ast->codec->codec_id              = CODEC_ID_PCM_U8;
+    ast->codec->sample_fmt            = SAMPLE_FMT_U8;
+    ast->codec->channels              = tmv->features & TMV_STEREO ? 2 : 1;
+    ast->codec->bits_per_coded_sample = 8;
+    ast->codec->bit_rate              = ast->codec->sample_rate *
+                                        ast->codec->bits_per_coded_sample;
+    av_set_pts_info(ast, 32, 1, ast->codec->sample_rate);
+
+    fps.num = ast->codec->sample_rate * ast->codec->channels;
+    fps.den = tmv->audio_chunk_size;
+    av_reduce(&fps.num, &fps.den, fps.num, fps.den, 0xFFFFFFFFLL);
+
+    vst->codec->codec_type = CODEC_TYPE_VIDEO;
+    vst->codec->codec_id   = CODEC_ID_TMV;
+    vst->codec->pix_fmt    = PIX_FMT_PAL8;
+    vst->codec->width      = tmv->char_cols * 8;
+    vst->codec->height     = tmv->char_rows * 8;
+    av_set_pts_info(vst, 32, fps.den, fps.num);
+
+    if (tmv->features & TMV_PADDING)
+        tmv->padding = ((2000 + tmv->audio_chunk_size + 511) & ~511) -
+                        (2000 + tmv->audio_chunk_size);
+
+    vst->codec->bit_rate = ((2000 + tmv->padding) * fps.num * 8) / fps.den;
+
+    return 0;
+}
+
+static int tmv_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    TMVContext *tmv   = s->priv_data;
+    ByteIOContext *pb = s->pb;
+    int ret, pkt_size = tmv->stream_index ? tmv->audio_chunk_size : 2000;
+
+    if (url_feof(pb))
+        return AVERROR_EOF;
+
+    ret = av_get_packet(pb, pkt, pkt_size);
+
+    if (tmv->features & TMV_PADDING && tmv->stream_index)
+        url_fskip(pb, tmv->padding);
+
+    pkt->stream_index  = tmv->stream_index;
+    tmv->stream_index ^= 1;
+    pkt->flags        |= PKT_FLAG_KEY;
+
+    return ret;
+}
+
+AVInputFormat tmv_demuxer = {
+    "tmv",
+    NULL_IF_CONFIG_SMALL("8088flex TMV"),
+    sizeof(TMVContext),
+    tmv_probe,
+    tmv_read_header,
+    tmv_read_packet,
+    .flags = AVFMT_GENERIC_INDEX,
+};
-- 
1.6.2.3



More information about the ffmpeg-devel mailing list