Libav 0.7.1
|
00001 /* 00002 * RSO demuxer 00003 * Copyright (c) 2001 Fabrice Bellard (original AU code) 00004 * Copyright (c) 2010 Rafael Carre 00005 * 00006 * This file is part of Libav. 00007 * 00008 * Libav is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * Libav is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with Libav; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #include "libavutil/intreadwrite.h" 00024 #include "avformat.h" 00025 #include "internal.h" 00026 #include "pcm.h" 00027 #include "riff.h" 00028 #include "rso.h" 00029 00030 static int rso_read_header(AVFormatContext *s, AVFormatParameters *ap) 00031 { 00032 AVIOContext *pb = s->pb; 00033 int id, rate, bps; 00034 unsigned int size; 00035 enum CodecID codec; 00036 AVStream *st; 00037 00038 id = avio_rb16(pb); 00039 size = avio_rb16(pb); 00040 rate = avio_rb16(pb); 00041 avio_rb16(pb); /* play mode ? (0x0000 = don't loop) */ 00042 00043 codec = ff_codec_get_id(ff_codec_rso_tags, id); 00044 00045 if (codec == CODEC_ID_ADPCM_IMA_WAV) { 00046 av_log(s, AV_LOG_ERROR, "ADPCM in RSO not implemented\n"); 00047 return AVERROR_PATCHWELCOME; 00048 } 00049 00050 bps = av_get_bits_per_sample(codec); 00051 if (!bps) { 00052 av_log_ask_for_sample(s, "could not determine bits per sample\n"); 00053 return AVERROR_INVALIDDATA; 00054 } 00055 00056 /* now we are ready: build format streams */ 00057 st = av_new_stream(s, 0); 00058 if (!st) 00059 return AVERROR(ENOMEM); 00060 00061 st->duration = (size * 8) / bps; 00062 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00063 st->codec->codec_tag = id; 00064 st->codec->codec_id = codec; 00065 st->codec->channels = 1; 00066 st->codec->sample_rate = rate; 00067 00068 av_set_pts_info(st, 64, 1, rate); 00069 00070 return 0; 00071 } 00072 00073 #define BLOCK_SIZE 1024 /* in samples */ 00074 00075 static int rso_read_packet(AVFormatContext *s, AVPacket *pkt) 00076 { 00077 int bps = av_get_bits_per_sample(s->streams[0]->codec->codec_id); 00078 int ret = av_get_packet(s->pb, pkt, BLOCK_SIZE * bps >> 3); 00079 00080 if (ret < 0) 00081 return ret; 00082 00083 pkt->stream_index = 0; 00084 00085 /* note: we need to modify the packet size here to handle the last packet */ 00086 pkt->size = ret; 00087 00088 return 0; 00089 } 00090 00091 AVInputFormat ff_rso_demuxer = { 00092 .name = "rso", 00093 .long_name = NULL_IF_CONFIG_SMALL("Lego Mindstorms RSO format"), 00094 .extensions = "rso", 00095 .priv_data_size = 0, 00096 .read_probe = NULL, /* no magic value in this format */ 00097 .read_header = rso_read_header, 00098 .read_packet = rso_read_packet, 00099 .read_close = NULL, 00100 .read_seek = pcm_read_seek, 00101 .codec_tag = (const AVCodecTag* const []){ff_codec_rso_tags, 0}, 00102 };