From 8bcacd9f4262d70645adf8501add387f6aa3b164 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 16 Jan 2014 14:25:38 +0000 Subject: [PATCH] SDR2 demuxer Signed-off-by: Paul B Mahol --- libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/sdr2.c | 120 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 libavformat/sdr2.c diff --git a/libavformat/Makefile b/libavformat/Makefile index 3c72288586..9ef81ccc29 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -353,6 +353,7 @@ OBJS-$(CONFIG_SAP_DEMUXER) += sapdec.o OBJS-$(CONFIG_SAP_MUXER) += sapenc.o OBJS-$(CONFIG_SBG_DEMUXER) += sbgdec.o OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o +OBJS-$(CONFIG_SDR2_DEMUXER) += sdr2.o OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o OBJS-$(CONFIG_SEGMENT_MUXER) += segment.o OBJS-$(CONFIG_SHORTEN_DEMUXER) += rawdec.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 6ee2f99e5b..0e70b6e42b 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -249,6 +249,7 @@ void av_register_all(void) REGISTER_MUXDEMUX(SAP, sap); REGISTER_DEMUXER (SBG, sbg); REGISTER_DEMUXER (SDP, sdp); + REGISTER_DEMUXER (SDR2, sdr2); #if CONFIG_RTPDEC ff_register_rtp_dynamic_payload_handlers(); ff_register_rdt_dynamic_payload_handlers(); diff --git a/libavformat/sdr2.c b/libavformat/sdr2.c new file mode 100644 index 0000000000..99968da422 --- /dev/null +++ b/libavformat/sdr2.c @@ -0,0 +1,120 @@ +/* + * SDR2 demuxer + * Copyright (c) 2014 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 sdr2_probe(AVProbeData *p) +{ + if (AV_RL32(p->buf) != MKTAG('S', 'R', 'A', 1)) + return 0; + + return AVPROBE_SCORE_EXTENSION; +} + +#define FIRST 0xA8 + +static int sdr2_read_header(AVFormatContext *s) +{ + AVStream *st, *ast; + + ast = avformat_new_stream(s, 0); + if (!ast) + return AVERROR(ENOMEM); + + st = avformat_new_stream(s, 0); + if (!st) + return AVERROR(ENOMEM); + + avio_skip(s->pb, 20); + avpriv_set_pts_info(st, 64, 1, avio_rl32(s->pb)); + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; + st->codec->width = avio_rl32(s->pb); + st->codec->height = avio_rl32(s->pb); + st->codec->codec_id = AV_CODEC_ID_H264; + + ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; + ast->codec->channels = 1; + ast->codec->sample_rate = 8000; + ast->codec->codec_id = AV_CODEC_ID_PCM_S16LE; + avpriv_set_pts_info(ast, 64, 1, 8000); + + avio_seek(s->pb, FIRST, SEEK_SET); + + return 0; +} + +static const uint8_t header[24] = { + 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x1e, + 0xa6, 0x80, 0xb0, 0x7e, 0x40, 0x00, 0x00, 0x00, + 0x01, 0x68, 0xce, 0x38, 0x80, 0x00, 0x00, 0x00 +}; + +static int sdr2_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + int64_t pos; + unsigned next; + int flags, ret = 0, is_video; + + pos = avio_tell(s->pb); + + flags = avio_rl32(s->pb); + avio_skip(s->pb, 4); + + next = avio_rl32(s->pb); + if (next <= 52) + return AVERROR_INVALIDDATA; + + avio_skip(s->pb, 6); + is_video = avio_rl32(s->pb); + avio_skip(s->pb, 30); + + if (pos == FIRST) { + if (av_new_packet(pkt, next - 52 + 24) < 0) + return AVERROR(ENOMEM); + memcpy(pkt->data, header, 24); + ret = avio_read(s->pb, pkt->data + 24, next - 52); + if (ret < 0) { + av_free_packet(pkt); + return ret; + } + av_shrink_packet(pkt, ret + 24); + } else { + ret = av_get_packet(s->pb, pkt, next - 52); + } + pkt->stream_index = !!is_video; + pkt->pos = pos; + if (flags & (1 << 12)) + pkt->flags |= AV_PKT_FLAG_KEY; + + return ret; +} + +AVInputFormat ff_sdr2_demuxer = { + .name = "sdr2", + .long_name = NULL_IF_CONFIG_SMALL("SDR2"), + .read_probe = sdr2_probe, + .read_header = sdr2_read_header, + .read_packet = sdr2_read_packet, + .extensions = "sdr2", + .flags = AVFMT_GENERIC_INDEX, +};