00001 /* 00002 * Electronic Arts .cdata file Demuxer 00003 * Copyright (c) 2007 Peter Ross 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 00031 #include "avformat.h" 00032 #include "internal.h" 00033 00034 typedef struct { 00035 unsigned int channels; 00036 unsigned int audio_pts; 00037 } CdataDemuxContext; 00038 00039 static int cdata_probe(AVProbeData *p) 00040 { 00041 const uint8_t *b = p->buf; 00042 00043 if (b[0] == 0x04 && (b[1] == 0x00 || b[1] == 0x04 || b[1] == 0x0C || b[1] == 0x14)) 00044 return AVPROBE_SCORE_MAX/8; 00045 return 0; 00046 } 00047 00048 static int cdata_read_header(AVFormatContext *s, AVFormatParameters *ap) 00049 { 00050 CdataDemuxContext *cdata = s->priv_data; 00051 AVIOContext *pb = s->pb; 00052 unsigned int sample_rate, header; 00053 AVStream *st; 00054 int64_t channel_layout = 0; 00055 00056 header = avio_rb16(pb); 00057 switch (header) { 00058 case 0x0400: cdata->channels = 1; break; 00059 case 0x0404: cdata->channels = 2; break; 00060 case 0x040C: cdata->channels = 4; channel_layout = AV_CH_LAYOUT_QUAD; break; 00061 case 0x0414: cdata->channels = 6; channel_layout = AV_CH_LAYOUT_5POINT1_BACK; break; 00062 default: 00063 av_log(s, AV_LOG_INFO, "unknown header 0x%04x\n", header); 00064 return -1; 00065 }; 00066 00067 sample_rate = avio_rb16(pb); 00068 avio_skip(pb, (avio_r8(pb) & 0x20) ? 15 : 11); 00069 00070 st = avformat_new_stream(s, NULL); 00071 if (!st) 00072 return AVERROR(ENOMEM); 00073 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00074 st->codec->codec_tag = 0; /* no fourcc */ 00075 st->codec->codec_id = CODEC_ID_ADPCM_EA_XAS; 00076 st->codec->channels = cdata->channels; 00077 st->codec->channel_layout = channel_layout; 00078 st->codec->sample_rate = sample_rate; 00079 st->codec->sample_fmt = AV_SAMPLE_FMT_S16; 00080 avpriv_set_pts_info(st, 64, 1, sample_rate); 00081 00082 cdata->audio_pts = 0; 00083 return 0; 00084 } 00085 00086 static int cdata_read_packet(AVFormatContext *s, AVPacket *pkt) 00087 { 00088 CdataDemuxContext *cdata = s->priv_data; 00089 int packet_size = 76*cdata->channels; 00090 00091 int ret = av_get_packet(s->pb, pkt, packet_size); 00092 if (ret < 0) 00093 return ret; 00094 pkt->pts = cdata->audio_pts++; 00095 return 0; 00096 } 00097 00098 AVInputFormat ff_ea_cdata_demuxer = { 00099 .name = "ea_cdata", 00100 .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts cdata"), 00101 .priv_data_size = sizeof(CdataDemuxContext), 00102 .read_probe = cdata_probe, 00103 .read_header = cdata_read_header, 00104 .read_packet = cdata_read_packet, 00105 .extensions = "cdata", 00106 };