diff options
author | Paul B Mahol <onemda@gmail.com> | 2016-04-05 14:05:10 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2016-04-07 09:08:53 +0200 |
commit | 2d720069a91b48dc201a43cc11e8d55fc332df48 (patch) | |
tree | f3ac8c2aff5d56539d99690e48d1e44022d58bbb | |
parent | 6d7f5667a0c48361ece1c6706a372760f396964d (diff) | |
download | ffmpeg-2d720069a91b48dc201a43cc11e8d55fc332df48.tar.gz |
avformat: add aix demuxer
Signed-off-by: Paul B Mahol <onemda@gmail.com>
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | libavformat/Makefile | 1 | ||||
-rw-r--r-- | libavformat/aixdec.c | 140 | ||||
-rw-r--r-- | libavformat/allformats.c | 1 | ||||
-rw-r--r-- | libavformat/version.h | 2 |
5 files changed, 144 insertions, 1 deletions
@@ -20,6 +20,7 @@ version <next>: - bitstream filter for extracting DTS core - ADPCM IMA DAT4 decoder - musx demuxer +- aix demuxer version 3.0: - Common Encryption (CENC) MP4 encoding and decoding support diff --git a/libavformat/Makefile b/libavformat/Makefile index 0b8388d57e..5515b84c0c 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -82,6 +82,7 @@ OBJS-$(CONFIG_AFC_DEMUXER) += afc.o OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o pcm.o isom.o \ mov_chan.o OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o isom.o id3v2enc.o +OBJS-$(CONFIG_AIX_DEMUXER) += aixdec.o OBJS-$(CONFIG_AMR_DEMUXER) += amr.o OBJS-$(CONFIG_AMR_MUXER) += amr.o OBJS-$(CONFIG_ANM_DEMUXER) += anm.o diff --git a/libavformat/aixdec.c b/libavformat/aixdec.c new file mode 100644 index 0000000000..83395581a4 --- /dev/null +++ b/libavformat/aixdec.c @@ -0,0 +1,140 @@ +/* + * AIX demuxer + * Copyright (c) 2016 Paul B Mahol + * + * 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 "avformat.h" +#include "internal.h" + +static int aix_probe(AVProbeData *p) +{ + if (AV_RL32(p->buf) != MKTAG('A','I','X','F') || + AV_RB32(p->buf + 8) != 0x01000014 || + AV_RB32(p->buf + 12) != 0x00000800) + return 0; + + return AVPROBE_SCORE_MAX; +} + +static int aix_read_header(AVFormatContext *s) +{ + unsigned nb_streams, first_offset, nb_segments; + unsigned stream_list_offset; + unsigned segment_list_offset = 0x20; + unsigned segment_list_entry_size = 0x10; + unsigned size; + int i; + + avio_skip(s->pb, 4); + first_offset = avio_rb32(s->pb) + 8; + avio_skip(s->pb, 16); + nb_segments = avio_rb16(s->pb); + if (nb_segments == 0) + return AVERROR_INVALIDDATA; + stream_list_offset = segment_list_offset + segment_list_entry_size * nb_segments + 0x10; + if (stream_list_offset >= first_offset) + return AVERROR_INVALIDDATA; + avio_seek(s->pb, stream_list_offset, SEEK_SET); + nb_streams = avio_r8(s->pb); + if (nb_streams == 0) + return AVERROR_INVALIDDATA; + avio_skip(s->pb, 7); + for (i = 0; i < nb_streams; i++) { + AVStream *st = avformat_new_stream(s, NULL); + + if (!st) + return AVERROR(ENOMEM); + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = AV_CODEC_ID_ADPCM_ADX; + st->codec->sample_rate = avio_rb32(s->pb); + st->codec->channels = avio_r8(s->pb); + avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); + avio_skip(s->pb, 3); + } + + avio_seek(s->pb, first_offset, SEEK_SET); + for (i = 0; i < nb_streams; i++) { + if (avio_rl32(s->pb) != MKTAG('A','I','X','P')) + return AVERROR_INVALIDDATA; + size = avio_rb32(s->pb); + if (size <= 8) + return AVERROR_INVALIDDATA; + avio_skip(s->pb, 8); + ff_get_extradata(s->streams[i]->codec, s->pb, size - 8); + } + + return 0; +} + +static int aix_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + unsigned size, index, duration, chunk; + int64_t pos; + int sequence, ret, i; + + pos = avio_tell(s->pb); + if (avio_feof(s->pb)) + return AVERROR_EOF; + chunk = avio_rl32(s->pb); + size = avio_rb32(s->pb); + if (chunk == MKTAG('A','I','X','E')) { + avio_skip(s->pb, size); + for (i = 0; i < s->nb_streams; i++) { + if (avio_feof(s->pb)) + return AVERROR_EOF; + chunk = avio_rl32(s->pb); + size = avio_rb32(s->pb); + avio_skip(s->pb, size); + } + pos = avio_tell(s->pb); + chunk = avio_rl32(s->pb); + size = avio_rb32(s->pb); + } + + if (chunk != MKTAG('A','I','X','P')) + return AVERROR_INVALIDDATA; + if (size <= 8) + return AVERROR_INVALIDDATA; + index = avio_r8(s->pb); + if (avio_r8(s->pb) != s->nb_streams || index >= s->nb_streams) + return AVERROR_INVALIDDATA; + duration = avio_rb16(s->pb); + sequence = avio_rb32(s->pb); + if (sequence < 0) { + avio_skip(s->pb, size - 8); + return 0; + } + + ret = av_get_packet(s->pb, pkt, size - 8); + pkt->stream_index = index; + pkt->duration = duration; + pkt->pos = pos; + return ret; +} + +AVInputFormat ff_aix_demuxer = { + .name = "aix", + .long_name = NULL_IF_CONFIG_SMALL("CRI AIX"), + .read_probe = aix_probe, + .read_header = aix_read_header, + .read_packet = aix_read_packet, + .extensions = "aix", + .flags = AVFMT_GENERIC_INDEX, +}; diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 1d6402f028..c5aa093f57 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -66,6 +66,7 @@ void av_register_all(void) REGISTER_DEMUXER (AEA, aea); REGISTER_DEMUXER (AFC, afc); REGISTER_MUXDEMUX(AIFF, aiff); + REGISTER_DEMUXER (AIX, aix); REGISTER_MUXDEMUX(AMR, amr); REGISTER_DEMUXER (ANM, anm); REGISTER_DEMUXER (APC, apc); diff --git a/libavformat/version.h b/libavformat/version.h index 99d7638917..29047ab106 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 30 +#define LIBAVFORMAT_VERSION_MINOR 31 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |