1/* 2 * IEC 61937 demuxer 3 * Copyright (c) 2010 Anssi Hannula <anssi.hannula at iki.fi> 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * IEC 61937 demuxer, used for compressed data in S/PDIF 25 * @author Anssi Hannula 26 */ 27 28#include "libavutil/bswap.h" 29 30#include "libavcodec/ac3defs.h" 31#include "libavcodec/adts_parser.h" 32 33#include "avformat.h" 34#include "spdif.h" 35 36static int spdif_get_offset_and_codec(AVFormatContext *s, 37 enum IEC61937DataType data_type, 38 const char *buf, int *offset, 39 enum AVCodecID *codec) 40{ 41 uint32_t samples; 42 uint8_t frames; 43 int ret; 44 45 switch (data_type & 0xff) { 46 case IEC61937_AC3: 47 *offset = AC3_FRAME_SIZE << 2; 48 *codec = AV_CODEC_ID_AC3; 49 break; 50 case IEC61937_MPEG1_LAYER1: 51 *offset = spdif_mpeg_pkt_offset[1][0]; 52 *codec = AV_CODEC_ID_MP1; 53 break; 54 case IEC61937_MPEG1_LAYER23: 55 *offset = spdif_mpeg_pkt_offset[1][0]; 56 *codec = AV_CODEC_ID_MP3; 57 break; 58 case IEC61937_MPEG2_EXT: 59 *offset = 4608; 60 *codec = AV_CODEC_ID_MP3; 61 break; 62 case IEC61937_MPEG2_AAC: 63 ret = av_adts_header_parse(buf, &samples, &frames); 64 if (ret < 0) { 65 if (s) /* be silent during a probe */ 66 av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n"); 67 return ret; 68 } 69 *offset = samples << 2; 70 *codec = AV_CODEC_ID_AAC; 71 break; 72 case IEC61937_MPEG2_LAYER1_LSF: 73 *offset = spdif_mpeg_pkt_offset[0][0]; 74 *codec = AV_CODEC_ID_MP1; 75 break; 76 case IEC61937_MPEG2_LAYER2_LSF: 77 *offset = spdif_mpeg_pkt_offset[0][1]; 78 *codec = AV_CODEC_ID_MP2; 79 break; 80 case IEC61937_MPEG2_LAYER3_LSF: 81 *offset = spdif_mpeg_pkt_offset[0][2]; 82 *codec = AV_CODEC_ID_MP3; 83 break; 84 case IEC61937_DTS1: 85 *offset = 2048; 86 *codec = AV_CODEC_ID_DTS; 87 break; 88 case IEC61937_DTS2: 89 *offset = 4096; 90 *codec = AV_CODEC_ID_DTS; 91 break; 92 case IEC61937_DTS3: 93 *offset = 8192; 94 *codec = AV_CODEC_ID_DTS; 95 break; 96 default: 97 if (s) { /* be silent during a probe */ 98 avpriv_request_sample(s, "Data type 0x%04x in IEC 61937", 99 data_type); 100 } 101 return AVERROR_PATCHWELCOME; 102 } 103 return 0; 104} 105 106/* Largest offset between bursts we currently handle, i.e. AAC with 107 samples = 4096 */ 108#define SPDIF_MAX_OFFSET 16384 109 110static int spdif_probe(const AVProbeData *p) 111{ 112 enum AVCodecID codec; 113 return ff_spdif_probe (p->buf, p->buf_size, &codec); 114} 115 116int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec) 117{ 118 const uint8_t *buf = p_buf; 119 const uint8_t *probe_end = p_buf + FFMIN(2 * SPDIF_MAX_OFFSET, buf_size - 1); 120 const uint8_t *expected_code = buf + 7; 121 uint32_t state = 0; 122 int sync_codes = 0; 123 int consecutive_codes = 0; 124 int offset; 125 126 for (; buf < probe_end; buf++) { 127 state = (state << 8) | *buf; 128 129 if (state == (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2)) 130 && buf[1] < 0x37) { 131 sync_codes++; 132 133 if (buf == expected_code) { 134 if (++consecutive_codes >= 2) 135 return AVPROBE_SCORE_MAX; 136 } else 137 consecutive_codes = 0; 138 139 if (buf + 4 + AV_AAC_ADTS_HEADER_SIZE > p_buf + buf_size) 140 break; 141 142 /* continue probing to find more sync codes */ 143 probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p_buf + buf_size - 1); 144 145 /* skip directly to the next sync code */ 146 if (!spdif_get_offset_and_codec(NULL, (buf[2] << 8) | buf[1], 147 &buf[5], &offset, codec)) { 148 if (buf + offset >= p_buf + buf_size) 149 break; 150 expected_code = buf + offset; 151 buf = expected_code - 7; 152 } 153 } 154 } 155 156 if (!sync_codes) 157 return 0; 158 159 if (sync_codes >= 6) 160 /* good amount of sync codes but with unexpected offsets */ 161 return AVPROBE_SCORE_EXTENSION; 162 163 /* some sync codes were found */ 164 return AVPROBE_SCORE_EXTENSION / 4; 165} 166 167static int spdif_read_header(AVFormatContext *s) 168{ 169 s->ctx_flags |= AVFMTCTX_NOHEADER; 170 return 0; 171} 172 173int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) 174{ 175 AVIOContext *pb = s->pb; 176 enum IEC61937DataType data_type; 177 enum AVCodecID codec_id; 178 uint32_t state = 0; 179 int pkt_size_bits, offset, ret; 180 181 while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) { 182 state = (state << 8) | avio_r8(pb); 183 if (avio_feof(pb)) 184 return AVERROR_EOF; 185 } 186 187 data_type = avio_rl16(pb); 188 pkt_size_bits = avio_rl16(pb); 189 190 if (pkt_size_bits % 16) 191 avpriv_request_sample(s, "Packet not ending at a 16-bit boundary"); 192 193 ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3); 194 if (ret) 195 return ret; 196 197 pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE; 198 199 if (avio_read(pb, pkt->data, pkt->size) < pkt->size) { 200 return AVERROR_EOF; 201 } 202 ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1); 203 204 ret = spdif_get_offset_and_codec(s, data_type, pkt->data, 205 &offset, &codec_id); 206 if (ret < 0) { 207 return ret; 208 } 209 210 /* skip over the padding to the beginning of the next frame */ 211 avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE); 212 213 if (!s->nb_streams) { 214 /* first packet, create a stream */ 215 AVStream *st = avformat_new_stream(s, NULL); 216 if (!st) { 217 return AVERROR(ENOMEM); 218 } 219 st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; 220 st->codecpar->codec_id = codec_id; 221 } else if (codec_id != s->streams[0]->codecpar->codec_id) { 222 avpriv_report_missing_feature(s, "Codec change in IEC 61937"); 223 return AVERROR_PATCHWELCOME; 224 } 225 226 if (!s->bit_rate && s->streams[0]->codecpar->sample_rate) 227 /* stream bitrate matches 16-bit stereo PCM bitrate for currently 228 supported codecs */ 229 s->bit_rate = 2 * 16LL * s->streams[0]->codecpar->sample_rate; 230 231 return 0; 232} 233 234const AVInputFormat ff_spdif_demuxer = { 235 .name = "spdif", 236 .long_name = NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"), 237 .read_probe = spdif_probe, 238 .read_header = spdif_read_header, 239 .read_packet = ff_spdif_read_packet, 240 .flags = AVFMT_GENERIC_INDEX, 241}; 242