• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavformat/spdifdec.c

Go to the documentation of this file.
00001 /*
00002  * IEC 61937 demuxer
00003  * Copyright (c) 2010 Anssi Hannula <anssi.hannula at iki.fi>
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00028 #include "avformat.h"
00029 #include "spdif.h"
00030 #include "libavcodec/ac3.h"
00031 #include "libavcodec/aacadtsdec.h"
00032 
00033 static int spdif_get_offset_and_codec(AVFormatContext *s,
00034                                       enum IEC61937DataType data_type,
00035                                       const char *buf, int *offset,
00036                                       enum CodecID *codec)
00037 {
00038     AACADTSHeaderInfo aac_hdr;
00039     GetBitContext gbc;
00040 
00041     switch (data_type & 0xff) {
00042     case IEC61937_AC3:
00043         *offset = AC3_FRAME_SIZE << 2;
00044         *codec = CODEC_ID_AC3;
00045         break;
00046     case IEC61937_MPEG1_LAYER1:
00047         *offset = spdif_mpeg_pkt_offset[1][0];
00048         *codec = CODEC_ID_MP1;
00049         break;
00050     case IEC61937_MPEG1_LAYER23:
00051         *offset = spdif_mpeg_pkt_offset[1][0];
00052         *codec = CODEC_ID_MP3;
00053         break;
00054     case IEC61937_MPEG2_EXT:
00055         *offset = 4608;
00056         *codec = CODEC_ID_MP3;
00057         break;
00058     case IEC61937_MPEG2_AAC:
00059         init_get_bits(&gbc, buf, AAC_ADTS_HEADER_SIZE * 8);
00060         if (ff_aac_parse_header(&gbc, &aac_hdr)) {
00061             if (s) /* be silent during a probe */
00062                 av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n");
00063             return AVERROR_INVALIDDATA;
00064         }
00065         *offset = aac_hdr.samples << 2;
00066         *codec = CODEC_ID_AAC;
00067         break;
00068     case IEC61937_MPEG2_LAYER1_LSF:
00069         *offset = spdif_mpeg_pkt_offset[0][0];
00070         *codec = CODEC_ID_MP1;
00071         break;
00072     case IEC61937_MPEG2_LAYER2_LSF:
00073         *offset = spdif_mpeg_pkt_offset[0][1];
00074         *codec = CODEC_ID_MP2;
00075         break;
00076     case IEC61937_MPEG2_LAYER3_LSF:
00077         *offset = spdif_mpeg_pkt_offset[0][2];
00078         *codec = CODEC_ID_MP3;
00079         break;
00080     case IEC61937_DTS1:
00081         *offset = 2048;
00082         *codec = CODEC_ID_DTS;
00083         break;
00084     case IEC61937_DTS2:
00085         *offset = 4096;
00086         *codec = CODEC_ID_DTS;
00087         break;
00088     case IEC61937_DTS3:
00089         *offset = 8192;
00090         *codec = CODEC_ID_DTS;
00091         break;
00092     default:
00093         if (s) { /* be silent during a probe */
00094             av_log(s, AV_LOG_WARNING, "Data type 0x%04x", data_type);
00095             av_log_missing_feature(s, " in IEC 61937 is", 1);
00096         }
00097         return AVERROR_PATCHWELCOME;
00098     }
00099     return 0;
00100 }
00101 
00102 /* Largest offset between bursts we currently handle, i.e. AAC with
00103    aac_hdr.samples = 4096 */
00104 #define SPDIF_MAX_OFFSET 16384
00105 
00106 static int spdif_probe(AVProbeData *p)
00107 {
00108     const uint8_t *buf = p->buf;
00109     const uint8_t *probe_end = p->buf + FFMIN(2 * SPDIF_MAX_OFFSET, p->buf_size - 1);
00110     const uint8_t *expected_code = buf + 7;
00111     uint32_t state = 0;
00112     int sync_codes = 0;
00113     int consecutive_codes = 0;
00114     int offset;
00115     enum CodecID codec;
00116 
00117     for (; buf < probe_end; buf++) {
00118         state = (state << 8) | *buf;
00119 
00120         if (state == (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))
00121                 && buf[1] < 0x37) {
00122             sync_codes++;
00123 
00124             if (buf == expected_code) {
00125                 if (++consecutive_codes >= 2)
00126                     return AVPROBE_SCORE_MAX;
00127             } else
00128                 consecutive_codes = 0;
00129 
00130             if (buf + 4 + AAC_ADTS_HEADER_SIZE > p->buf + p->buf_size)
00131                 break;
00132 
00133             /* continue probing to find more sync codes */
00134             probe_end = FFMIN(buf + SPDIF_MAX_OFFSET, p->buf + p->buf_size - 1);
00135 
00136             /* skip directly to the next sync code */
00137             if (!spdif_get_offset_and_codec(NULL, (buf[2] << 8) | buf[1],
00138                                             &buf[5], &offset, &codec)) {
00139                 if (buf + offset >= p->buf + p->buf_size)
00140                     break;
00141                 expected_code = buf + offset;
00142                 buf = expected_code - 7;
00143             }
00144         }
00145     }
00146 
00147     if (!sync_codes)
00148         return 0;
00149 
00150     if (sync_codes >= 6)
00151         /* good amount of sync codes but with unexpected offsets */
00152         return AVPROBE_SCORE_MAX / 2;
00153 
00154     /* some sync codes were found */
00155     return AVPROBE_SCORE_MAX / 8;
00156 }
00157 
00158 static int spdif_read_header(AVFormatContext *s, AVFormatParameters *ap)
00159 {
00160     s->ctx_flags |= AVFMTCTX_NOHEADER;
00161     return 0;
00162 }
00163 
00164 static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
00165 {
00166     AVIOContext *pb = s->pb;
00167     enum IEC61937DataType data_type;
00168     enum CodecID codec_id;
00169     uint32_t state = 0;
00170     int pkt_size_bits, offset, ret;
00171 
00172     while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) {
00173         state = (state << 8) | avio_r8(pb);
00174         if (url_feof(pb))
00175             return AVERROR_EOF;
00176     }
00177 
00178     data_type = avio_rl16(pb);
00179     pkt_size_bits = avio_rl16(pb);
00180 
00181     if (pkt_size_bits % 16)
00182         av_log_ask_for_sample(s, "Packet does not end to a 16-bit boundary.");
00183 
00184     ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3);
00185     if (ret)
00186         return ret;
00187 
00188     pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE;
00189 
00190     if (avio_read(pb, pkt->data, pkt->size) < pkt->size) {
00191         av_free_packet(pkt);
00192         return AVERROR_EOF;
00193     }
00194     ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1);
00195 
00196     ret = spdif_get_offset_and_codec(s, data_type, pkt->data,
00197                                      &offset, &codec_id);
00198     if (ret) {
00199         av_free_packet(pkt);
00200         return ret;
00201     }
00202 
00203     /* skip over the padding to the beginning of the next frame */
00204     avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE);
00205 
00206     if (!s->nb_streams) {
00207         /* first packet, create a stream */
00208         AVStream *st = av_new_stream(s, 0);
00209         if (!st) {
00210             av_free_packet(pkt);
00211             return AVERROR(ENOMEM);
00212         }
00213         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00214         st->codec->codec_id = codec_id;
00215     } else if (codec_id != s->streams[0]->codec->codec_id) {
00216         av_log_missing_feature(s, "codec change in IEC 61937", 0);
00217         return AVERROR_PATCHWELCOME;
00218     }
00219 
00220     if (!s->bit_rate && s->streams[0]->codec->sample_rate)
00221         /* stream bitrate matches 16-bit stereo PCM bitrate for currently
00222            supported codecs */
00223         s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate;
00224 
00225     return 0;
00226 }
00227 
00228 AVInputFormat ff_spdif_demuxer = {
00229     "spdif",
00230     NULL_IF_CONFIG_SMALL("IEC 61937 (compressed data in S/PDIF)"),
00231     0,
00232     spdif_probe,
00233     spdif_read_header,
00234     spdif_read_packet,
00235     .flags = AVFMT_GENERIC_INDEX,
00236 };

Generated on Wed Apr 11 2012 07:31:37 for FFmpeg by  doxygen 1.7.1