diff options
author | Kostya Shishkov <kostya.shishkov@gmail.com> | 2011-03-15 09:37:48 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2011-03-28 16:55:03 +0200 |
commit | 42315dabce376fd7085e2a1bbab4d230d3d2ccd8 (patch) | |
tree | 927b4552fe18a0c33c635bc312fe95593c961cc2 /libavformat | |
parent | c6f951442efb34dd63e1e00b19bc30447075d5a3 (diff) | |
download | ffmpeg-42315dabce376fd7085e2a1bbab4d230d3d2ccd8.tar.gz |
Chronomaster DFA decoder
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/Makefile | 1 | ||||
-rw-r--r-- | libavformat/allformats.c | 1 | ||||
-rw-r--r-- | libavformat/dfa.c | 119 | ||||
-rw-r--r-- | libavformat/version.h | 2 |
4 files changed, 122 insertions, 1 deletions
diff --git a/libavformat/Makefile b/libavformat/Makefile index c521cd384c..719783c62d 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -55,6 +55,7 @@ OBJS-$(CONFIG_CDG_DEMUXER) += cdg.o OBJS-$(CONFIG_CRC_MUXER) += crcenc.o OBJS-$(CONFIG_DAUD_DEMUXER) += daud.o OBJS-$(CONFIG_DAUD_MUXER) += daud.o +OBJS-$(CONFIG_DFA_DEMUXER) += dfa.o OBJS-$(CONFIG_DIRAC_DEMUXER) += diracdec.o rawdec.o OBJS-$(CONFIG_DIRAC_MUXER) += rawenc.o OBJS-$(CONFIG_DNXHD_DEMUXER) += dnxhddec.o rawdec.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index d6cab7a499..e80d4b0175 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -75,6 +75,7 @@ void av_register_all(void) REGISTER_DEMUXER (CDG, cdg); REGISTER_MUXER (CRC, crc); REGISTER_MUXDEMUX (DAUD, daud); + REGISTER_DEMUXER (DFA, dfa); REGISTER_MUXDEMUX (DIRAC, dirac); REGISTER_MUXDEMUX (DNXHD, dnxhd); REGISTER_DEMUXER (DSICIN, dsicin); diff --git a/libavformat/dfa.c b/libavformat/dfa.c new file mode 100644 index 0000000000..810853568d --- /dev/null +++ b/libavformat/dfa.c @@ -0,0 +1,119 @@ +/* + * Chronomaster DFA Format Demuxer + * Copyright (c) 2011 Konstantin Shishkov + * + * This file is part of Libav. + * + * Libav 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. + * + * Libav 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 Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/intreadwrite.h" +#include "avformat.h" + +static int dfa_probe(AVProbeData *p) +{ + if (p->buf_size < 4 || AV_RL32(p->buf) != MKTAG('D', 'F', 'I', 'A')) + return 0; + + return AVPROBE_SCORE_MAX; +} + +static int dfa_read_header(AVFormatContext *s, + AVFormatParameters *ap) +{ + AVIOContext *pb = s->pb; + AVStream *st; + int frames; + uint32_t mspf; + + if (avio_rl32(pb) != MKTAG('D', 'F', 'I', 'A')) { + av_log(s, AV_LOG_ERROR, "Invalid magic for DFA\n"); + return AVERROR_INVALIDDATA; + } + avio_skip(pb, 2); // unused + frames = avio_rl16(pb); + + st = av_new_stream(s, 0); + if (!st) + return AVERROR(ENOMEM); + + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; + st->codec->codec_id = CODEC_ID_DFA; + st->codec->width = avio_rl16(pb); + st->codec->height = avio_rl16(pb); + mspf = avio_rl32(pb); + if (!mspf) { + av_log(s, AV_LOG_WARNING, "Zero FPS reported, defaulting to 10\n"); + mspf = 100; + } + av_set_pts_info(st, 24, mspf, 1000); + avio_skip(pb, 128 - 16); // padding + st->duration = frames; + + return 0; +} + +static int dfa_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + AVIOContext *pb = s->pb; + uint32_t frame_size; + int ret, first = 1; + + if (pb->eof_reached) + return AVERROR_EOF; + + if (av_get_packet(pb, pkt, 12) != 12) + return AVERROR(EIO); + while (!pb->eof_reached) { + if (!first) { + ret = av_append_packet(pb, pkt, 12); + if (ret < 0) { + av_free_packet(pkt); + return ret; + } + } else + first = 0; + frame_size = AV_RL32(pkt->data + pkt->size - 8); + if (frame_size > INT_MAX - 4) { + av_log(s, AV_LOG_ERROR, "Too large chunk size: %d\n", frame_size); + return AVERROR(EIO); + } + if (AV_RL32(pkt->data + pkt->size - 12) == MKTAG('E', 'O', 'F', 'R')) { + if (frame_size) { + av_log(s, AV_LOG_WARNING, "skipping %d bytes of end-of-frame marker chunk\n", + frame_size); + avio_skip(pb, frame_size); + } + return 0; + } + ret = av_append_packet(pb, pkt, frame_size); + if (ret < 0) { + av_free_packet(pkt); + return ret; + } + } + + return 0; +} + +AVInputFormat ff_dfa_demuxer = { + "dfa", + NULL_IF_CONFIG_SMALL("Chronomaster DFA"), + 0, + dfa_probe, + dfa_read_header, + dfa_read_packet, + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/version.h b/libavformat/version.h index e52290f879..7d61bef3f6 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -24,7 +24,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 52 -#define LIBAVFORMAT_VERSION_MINOR 103 +#define LIBAVFORMAT_VERSION_MINOR 104 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |