Libav 0.7.1
|
00001 /* 00002 * Electronic Arts .cdata file Demuxer 00003 * Copyright (c) 2007 Peter Ross 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav 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 * Libav 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 Libav; 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 00033 typedef struct { 00034 unsigned int channels; 00035 unsigned int audio_pts; 00036 } CdataDemuxContext; 00037 00038 static int cdata_probe(AVProbeData *p) 00039 { 00040 const uint8_t *b = p->buf; 00041 00042 if (b[0] == 0x04 && (b[1] == 0x00 || b[1] == 0x04 || b[1] == 0x0C)) 00043 return AVPROBE_SCORE_MAX/8; 00044 return 0; 00045 } 00046 00047 static int cdata_read_header(AVFormatContext *s, AVFormatParameters *ap) 00048 { 00049 CdataDemuxContext *cdata = s->priv_data; 00050 AVIOContext *pb = s->pb; 00051 unsigned int sample_rate, header; 00052 AVStream *st; 00053 00054 header = avio_rb16(pb); 00055 switch (header) { 00056 case 0x0400: cdata->channels = 1; break; 00057 case 0x0404: cdata->channels = 2; break; 00058 case 0x040C: cdata->channels = 4; break; 00059 default: 00060 av_log(s, AV_LOG_INFO, "unknown header 0x%04x\n", header); 00061 return -1; 00062 }; 00063 00064 sample_rate = avio_rb16(pb); 00065 avio_skip(pb, 12); 00066 00067 st = av_new_stream(s, 0); 00068 if (!st) 00069 return AVERROR(ENOMEM); 00070 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00071 st->codec->codec_tag = 0; /* no fourcc */ 00072 st->codec->codec_id = CODEC_ID_ADPCM_EA_XAS; 00073 st->codec->channels = cdata->channels; 00074 st->codec->sample_rate = sample_rate; 00075 av_set_pts_info(st, 64, 1, sample_rate); 00076 00077 cdata->audio_pts = 0; 00078 return 0; 00079 } 00080 00081 static int cdata_read_packet(AVFormatContext *s, AVPacket *pkt) 00082 { 00083 CdataDemuxContext *cdata = s->priv_data; 00084 int packet_size = 76*cdata->channels; 00085 00086 int ret = av_get_packet(s->pb, pkt, packet_size); 00087 if (ret < 0) 00088 return ret; 00089 pkt->pts = cdata->audio_pts++; 00090 return 0; 00091 } 00092 00093 AVInputFormat ff_ea_cdata_demuxer = { 00094 "ea_cdata", 00095 NULL_IF_CONFIG_SMALL("Electronic Arts cdata"), 00096 sizeof(CdataDemuxContext), 00097 cdata_probe, 00098 cdata_read_header, 00099 cdata_read_packet, 00100 .extensions = "cdata", 00101 };