| 
							- /*
 -  * IEC 61937 demuxer
 -  * Copyright (c) 2010 Anssi Hannula <anssi.hannula at iki.fi>
 -  *
 -  * 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
 -  */
 - 
 - /**
 -  * @file
 -  * IEC 61937 demuxer, used for compressed data in S/PDIF
 -  * @author Anssi Hannula
 -  */
 - 
 - #include "avformat.h"
 - #include "spdif.h"
 - #include "libavcodec/ac3.h"
 - #include "libavcodec/aacadtsdec.h"
 - 
 - static int spdif_get_offset_and_codec(AVFormatContext *s,
 -                                       enum IEC958DataType data_type,
 -                                       const char *buf, int *offset,
 -                                       enum CodecID *codec)
 - {
 -     AACADTSHeaderInfo aac_hdr;
 -     GetBitContext gbc;
 - 
 -     switch (data_type & 0xff) {
 -     case IEC958_AC3:
 -         *offset = AC3_FRAME_SIZE << 2;
 -         *codec = CODEC_ID_AC3;
 -         break;
 -     case IEC958_MPEG1_LAYER1:
 -         *offset = spdif_mpeg_pkt_offset[1][0];
 -         *codec = CODEC_ID_MP1;
 -         break;
 -     case IEC958_MPEG1_LAYER23:
 -         *offset = spdif_mpeg_pkt_offset[1][0];
 -         *codec = CODEC_ID_MP3;
 -         break;
 -     case IEC958_MPEG2_EXT:
 -         *offset = 4608;
 -         *codec = CODEC_ID_MP3;
 -         break;
 -     case IEC958_MPEG2_AAC:
 -         init_get_bits(&gbc, buf, AAC_ADTS_HEADER_SIZE * 8);
 -         if (ff_aac_parse_header(&gbc, &aac_hdr)) {
 -             if (s) /* be silent during a probe */
 -                 av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n");
 -             return AVERROR_INVALIDDATA;
 -         }
 -         *offset = aac_hdr.samples << 2;
 -         *codec = CODEC_ID_AAC;
 -         break;
 -     case IEC958_MPEG2_LAYER1_LSF:
 -         *offset = spdif_mpeg_pkt_offset[0][0];
 -         *codec = CODEC_ID_MP1;
 -         break;
 -     case IEC958_MPEG2_LAYER2_LSF:
 -         *offset = spdif_mpeg_pkt_offset[0][1];
 -         *codec = CODEC_ID_MP2;
 -         break;
 -     case IEC958_MPEG2_LAYER3_LSF:
 -         *offset = spdif_mpeg_pkt_offset[0][2];
 -         *codec = CODEC_ID_MP3;
 -         break;
 -     case IEC958_DTS1:
 -         *offset = 2048;
 -         *codec = CODEC_ID_DTS;
 -         break;
 -     case IEC958_DTS2:
 -         *offset = 4096;
 -         *codec = CODEC_ID_DTS;
 -         break;
 -     case IEC958_DTS3:
 -         *offset = 8192;
 -         *codec = CODEC_ID_DTS;
 -         break;
 -     default:
 -         if (s) { /* be silent during a probe */
 -             av_log(s, AV_LOG_WARNING, "Data type 0x%04x", data_type);
 -             av_log_missing_feature(s, " in IEC 61937 is", 1);
 -         }
 -         return AVERROR_PATCHWELCOME;
 -     }
 -     return 0;
 - }
 - 
 - /* Largest offset between bursts we currently handle, i.e. AAC with
 -    aac_hdr.samples = 4096 */
 - #define SPDIF_MAX_OFFSET 16384
 - 
 - static int spdif_probe(AVProbeData *p)
 - {
 -     const uint8_t *buf = p->buf;
 -     const uint8_t *probe_end = p->buf + FFMIN(2 * SPDIF_MAX_OFFSET, p->buf_size - 1);
 -     const uint8_t *expected_code = buf + 7;
 -     uint32_t state = 0;
 -     int sync_codes = 0;
 -     int consecutive_codes = 0;
 -     int offset;
 -     enum CodecID codec;
 - 
 -     for (; buf < probe_end; buf++) {
 -         state = (state << 8) | *buf;
 - 
 -         if (state == (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))
 -                 && buf[1] < 0x37) {
 -             sync_codes++;
 - 
 -             if (buf == expected_code) {
 -                 if (++consecutive_codes >= 2)
 -                     return AVPROBE_SCORE_MAX;
 -             } else
 -                 consecutive_codes = 0;
 - 
 -             if (buf + 4 + AAC_ADTS_HEADER_SIZE > p->buf + p->buf_size)
 -                 break;
 - 
 -             /* continue probing to find more sync codes */
 -             probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p->buf + p->buf_size - 1);
 - 
 -             /* skip directly to the next sync code */
 -             if (!spdif_get_offset_and_codec(NULL, (buf[2] << 8) | buf[1],
 -                                             &buf[5], &offset, &codec)) {
 -                 if (buf + offset >= p->buf + p->buf_size)
 -                     break;
 -                 expected_code = buf + offset;
 -                 buf = expected_code - 7;
 -             }
 -         }
 -     }
 - 
 -     if (!sync_codes)
 -         return 0;
 - 
 -     if (sync_codes >= 6)
 -         /* good amount of sync codes but with unexpected offsets */
 -         return AVPROBE_SCORE_MAX / 2;
 - 
 -     /* some sync codes were found */
 -     return AVPROBE_SCORE_MAX / 8;
 - }
 - 
 - static int spdif_read_header(AVFormatContext *s, AVFormatParameters *ap)
 - {
 -     s->ctx_flags |= AVFMTCTX_NOHEADER;
 -     return 0;
 - }
 - 
 - static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
 - {
 -     ByteIOContext *pb = s->pb;
 -     enum IEC958DataType data_type;
 -     enum CodecID codec_id;
 -     uint32_t state = 0;
 -     int pkt_size_bits, offset, ret;
 - 
 -     while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) {
 -         state = (state << 8) | get_byte(pb);
 -         if (url_feof(pb))
 -             return AVERROR_EOF;
 -     }
 - 
 -     data_type = get_le16(pb);
 -     pkt_size_bits = get_le16(pb);
 - 
 -     if (pkt_size_bits % 16)
 -         av_log_ask_for_sample(s, "Packet does not end to a 16-bit boundary.");
 - 
 -     ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3);
 -     if (ret)
 -         return ret;
 - 
 -     pkt->pos = url_ftell(pb) - BURST_HEADER_SIZE;
 - 
 -     if (get_buffer(pb, pkt->data, pkt->size) < pkt->size) {
 -         av_free_packet(pkt);
 -         return AVERROR_EOF;
 -     }
 -     ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1);
 - 
 -     ret = spdif_get_offset_and_codec(s, data_type, pkt->data,
 -                                      &offset, &codec_id);
 -     if (ret) {
 -         av_free_packet(pkt);
 -         return ret;
 -     }
 - 
 -     /* skip over the padding to the beginning of the next frame */
 -     url_fskip(pb, offset - pkt->size - BURST_HEADER_SIZE);
 - 
 -     if (!s->nb_streams) {
 -         /* first packet, create a stream */
 -         AVStream *st = av_new_stream(s, 0);
 -         if (!st) {
 -             av_free_packet(pkt);
 -             return AVERROR(ENOMEM);
 -         }
 -         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
 -         st->codec->codec_id = codec_id;
 -     } else if (codec_id != s->streams[0]->codec->codec_id) {
 -         av_log_missing_feature(s, "codec change in IEC 61937", 0);
 -         return AVERROR_PATCHWELCOME;
 -     }
 - 
 -     if (!s->bit_rate && s->streams[0]->codec->sample_rate)
 -         /* stream bitrate matches 16-bit stereo PCM bitrate for currently
 -            supported codecs */
 -         s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate;
 - 
 -     return 0;
 - }
 - 
 - AVInputFormat spdif_demuxer = {
 -     "spdif",
 -     NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"),
 -     0,
 -     spdif_probe,
 -     spdif_read_header,
 -     spdif_read_packet,
 -     .flags = AVFMT_GENERIC_INDEX,
 - };
 
 
  |