diff --git a/Changelog b/Changelog index 75b5567045..b7522ab8ee 100644 --- a/Changelog +++ b/Changelog @@ -9,6 +9,7 @@ version next: - ffprobe -select_streams option - Pinnacle TARGA CineWave YUV16 decoder - TAK demuxer, decoder and parser +- DTS-HD demuxer version 1.0: diff --git a/configure b/configure index 240959929e..8910a371a9 100755 --- a/configure +++ b/configure @@ -1800,6 +1800,7 @@ asf_stream_muxer_select="asf_muxer" avisynth_demuxer_deps="avisynth" dirac_demuxer_select="dirac_parser" dts_demuxer_select="dca_parser" +dtshd_demuxer_select="dca_parser" eac3_demuxer_select="ac3_parser" f4v_muxer_select="mov_muxer" flac_demuxer_select="flac_parser" diff --git a/doc/general.texi b/doc/general.texi index 9cba7bb3bb..7f50c11cc5 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -287,6 +287,7 @@ library: @item raw Dirac @tab X @tab X @item raw DNxHD @tab X @tab X @item raw DTS @tab X @tab X +@item raw DTS-HD @tab @tab X @item raw E-AC-3 @tab X @tab X @item raw FLAC @tab X @tab X @item raw GSM @tab @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index 1fd616bebb..6f8a9faa4b 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -80,6 +80,7 @@ OBJS-$(CONFIG_DIRAC_MUXER) += rawenc.o OBJS-$(CONFIG_DNXHD_DEMUXER) += dnxhddec.o rawdec.o OBJS-$(CONFIG_DNXHD_MUXER) += rawenc.o OBJS-$(CONFIG_DSICIN_DEMUXER) += dsicin.o +OBJS-$(CONFIG_DTSHD_DEMUXER) += dtshddec.o OBJS-$(CONFIG_DTS_DEMUXER) += dtsdec.o rawdec.o OBJS-$(CONFIG_DTS_MUXER) += rawenc.o OBJS-$(CONFIG_DV_DEMUXER) += dv.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index f1e8edcd65..00f11f42b9 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -88,6 +88,7 @@ void av_register_all(void) REGISTER_MUXDEMUX (DNXHD, dnxhd); REGISTER_DEMUXER (DSICIN, dsicin); REGISTER_MUXDEMUX (DTS, dts); + REGISTER_DEMUXER (DTSHD, dtshd); REGISTER_MUXDEMUX (DV, dv); REGISTER_DEMUXER (DXA, dxa); REGISTER_DEMUXER (EA, ea); diff --git a/libavformat/dtshddec.c b/libavformat/dtshddec.c new file mode 100644 index 0000000000..8187a7a6a6 --- /dev/null +++ b/libavformat/dtshddec.c @@ -0,0 +1,138 @@ +/* + * Raw DTS-HD demuxer + * Copyright (c) 2012 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 "libavutil/dict.h" +#include "avformat.h" + +#define AUPR_HDR 0x415550522D484452 +#define AUPRINFO 0x41555052494E464F +#define BITSHVTB 0x4249545348565442 +#define BLACKOUT 0x424C41434B4F5554 +#define BRANCHPT 0x4252414E43485054 +#define BUILDVER 0x4255494C44564552 +#define CORESSMD 0x434F524553534D44 +#define DTSHDHDR 0x4454534844484452 +#define EXTSS_MD 0x45585453535f4d44 +#define FILEINFO 0x46494C45494E464F +#define NAVI_TBL 0x4E4156492D54424C +#define STRMDATA 0x5354524D44415441 +#define TIMECODE 0x54494D45434F4445 + +typedef struct DTSHDDemuxContext { + uint64_t left; +} DTSHDDemuxContext; + +static int dtshd_probe(AVProbeData *p) +{ + if (AV_RB64(p->buf) == DTSHDHDR) + return AVPROBE_SCORE_MAX; + return 0; +} + +static int dtshd_read_header(AVFormatContext *s) +{ + DTSHDDemuxContext *dtshd = s->priv_data; + AVIOContext *pb = s->pb; + uint64_t chunk_type, chunk_size; + AVStream *st; + int ret; + char *value; + + 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_DTS; + st->need_parsing = AVSTREAM_PARSE_FULL_RAW; + + while (!url_feof(pb)) { + chunk_type = avio_rb64(pb); + chunk_size = avio_rb64(pb); + + if (chunk_size < 4) { + av_log(s, AV_LOG_ERROR, "chunk size too small\n"); + return AVERROR_INVALIDDATA; + } + if (chunk_size > ((uint64_t)1 << 61)) { + av_log(s, AV_LOG_ERROR, "chunk size too big\n"); + return AVERROR_INVALIDDATA; + } + + switch (chunk_type) { + case STRMDATA: + dtshd->left = chunk_size; + return 0; + break; + case FILEINFO: + if (chunk_size > INT_MAX) + goto skip; + value = av_malloc(chunk_size); + if (!value) + goto skip; + avio_read(pb, value, chunk_size); + value[chunk_size - 1] = 0; + av_dict_set(&s->metadata, "fileinfo", value, + AV_DICT_DONT_STRDUP_VAL); + break; + default: +skip: + ret = avio_skip(pb, chunk_size); + if (ret < 0) + return ret; + }; + } + + return AVERROR_EOF; +} + +static int raw_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + DTSHDDemuxContext *dtshd = s->priv_data; + uint64_t size; + int ret; + + size = FFMIN(dtshd->left, 1024); + if (size == 0) + return AVERROR_EOF; + + ret = av_get_packet(s->pb, pkt, size); + if (ret < 0) + return ret; + + pkt->stream_index = 0; + pkt->pos = avio_tell(s->pb); + dtshd->left -= ret; + + return ret; +} + +AVInputFormat ff_dtshd_demuxer = { + .name = "dtshd", + .long_name = NULL_IF_CONFIG_SMALL("raw DTS-HD"), + .priv_data_size = sizeof(DTSHDDemuxContext), + .read_probe = dtshd_probe, + .read_header = dtshd_read_header, + .read_packet = raw_read_packet, + .flags = AVFMT_GENERIC_INDEX, + .extensions = "dtshd", + .raw_codec_id = AV_CODEC_ID_DTS, +}; diff --git a/libavformat/version.h b/libavformat/version.h index b733ef6c3c..ff11c85b31 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,7 +30,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 54 -#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, \