00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avformat.h"
00022 #include "internal.h"
00023 #include "avio_internal.h"
00024 #include "pcm.h"
00025 #include "riff.h"
00026
00027 typedef struct {
00028 int64_t atrpos, atsqpos, awapos;
00029 int64_t data_size;
00030 } MMFContext;
00031
00032 static const int mmf_rates[] = { 4000, 8000, 11025, 22050, 44100 };
00033
00034 static int mmf_rate(int code)
00035 {
00036 if((code < 0) || (code > 4))
00037 return -1;
00038 return mmf_rates[code];
00039 }
00040
00041 #if CONFIG_MMF_MUXER
00042 static int mmf_rate_code(int rate)
00043 {
00044 int i;
00045 for(i = 0; i < 5; i++)
00046 if(mmf_rates[i] == rate)
00047 return i;
00048 return -1;
00049 }
00050
00051
00052 static void end_tag_be(AVIOContext *pb, int64_t start)
00053 {
00054 int64_t pos;
00055
00056 pos = avio_tell(pb);
00057 avio_seek(pb, start - 4, SEEK_SET);
00058 avio_wb32(pb, (uint32_t)(pos - start));
00059 avio_seek(pb, pos, SEEK_SET);
00060 }
00061
00062 static int mmf_write_header(AVFormatContext *s)
00063 {
00064 MMFContext *mmf = s->priv_data;
00065 AVIOContext *pb = s->pb;
00066 int64_t pos;
00067 int rate;
00068
00069 rate = mmf_rate_code(s->streams[0]->codec->sample_rate);
00070 if(rate < 0) {
00071 av_log(s, AV_LOG_ERROR, "Unsupported sample rate %d, supported are 4000, 8000, 11025, 22050 and 44100\n", s->streams[0]->codec->sample_rate);
00072 return -1;
00073 }
00074
00075 ffio_wfourcc(pb, "MMMD");
00076 avio_wb32(pb, 0);
00077 pos = ff_start_tag(pb, "CNTI");
00078 avio_w8(pb, 0);
00079 avio_w8(pb, 1);
00080 avio_w8(pb, 1);
00081 avio_w8(pb, 0);
00082 avio_w8(pb, 0);
00083 avio_write(pb, "VN:libavcodec,", sizeof("VN:libavcodec,") -1);
00084 end_tag_be(pb, pos);
00085
00086 avio_write(pb, "ATR\x00", 4);
00087 avio_wb32(pb, 0);
00088 mmf->atrpos = avio_tell(pb);
00089 avio_w8(pb, 0);
00090 avio_w8(pb, 0);
00091 avio_w8(pb, (0 << 7) | (1 << 4) | rate);
00092 avio_w8(pb, 0);
00093 avio_w8(pb, 2);
00094 avio_w8(pb, 2);
00095
00096 ffio_wfourcc(pb, "Atsq");
00097 avio_wb32(pb, 16);
00098 mmf->atsqpos = avio_tell(pb);
00099
00100 avio_write(pb, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16);
00101
00102 mmf->awapos = ff_start_tag(pb, "Awa\x01");
00103
00104 avpriv_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
00105
00106 avio_flush(pb);
00107
00108 return 0;
00109 }
00110
00111 static int mmf_write_packet(AVFormatContext *s, AVPacket *pkt)
00112 {
00113 AVIOContext *pb = s->pb;
00114 avio_write(pb, pkt->data, pkt->size);
00115 return 0;
00116 }
00117
00118
00119 static void put_varlength(AVIOContext *pb, int val)
00120 {
00121 if(val < 128)
00122 avio_w8(pb, val);
00123 else {
00124 val -= 128;
00125 avio_w8(pb, 0x80 | val >> 7);
00126 avio_w8(pb, 0x7f & val);
00127 }
00128 }
00129
00130 static int mmf_write_trailer(AVFormatContext *s)
00131 {
00132 AVIOContext *pb = s->pb;
00133 MMFContext *mmf = s->priv_data;
00134 int64_t pos, size;
00135 int gatetime;
00136
00137 if (s->pb->seekable) {
00138
00139 end_tag_be(pb, mmf->awapos);
00140 end_tag_be(pb, mmf->atrpos);
00141 end_tag_be(pb, 8);
00142
00143 pos = avio_tell(pb);
00144 size = pos - mmf->awapos;
00145
00146
00147 avio_seek(pb, mmf->atsqpos, SEEK_SET);
00148
00149
00150 avio_w8(pb, 0);
00151 avio_w8(pb, 1);
00152 gatetime = size * 500 / s->streams[0]->codec->sample_rate;
00153 put_varlength(pb, gatetime);
00154
00155
00156 put_varlength(pb, gatetime);
00157 avio_write(pb, "\xff\x00", 2);
00158
00159
00160 avio_write(pb, "\x00\x00\x00\x00", 4);
00161
00162 avio_seek(pb, pos, SEEK_SET);
00163
00164 avio_flush(pb);
00165 }
00166 return 0;
00167 }
00168 #endif
00169
00170 static int mmf_probe(AVProbeData *p)
00171 {
00172
00173 if (p->buf[0] == 'M' && p->buf[1] == 'M' &&
00174 p->buf[2] == 'M' && p->buf[3] == 'D' &&
00175 p->buf[8] == 'C' && p->buf[9] == 'N' &&
00176 p->buf[10] == 'T' && p->buf[11] == 'I')
00177 return AVPROBE_SCORE_MAX;
00178 else
00179 return 0;
00180 }
00181
00182
00183 static int mmf_read_header(AVFormatContext *s)
00184 {
00185 MMFContext *mmf = s->priv_data;
00186 unsigned int tag;
00187 AVIOContext *pb = s->pb;
00188 AVStream *st;
00189 int64_t size;
00190 int rate, params;
00191
00192 tag = avio_rl32(pb);
00193 if (tag != MKTAG('M', 'M', 'M', 'D'))
00194 return -1;
00195 avio_skip(pb, 4);
00196
00197
00198 for(;; avio_skip(pb, size)) {
00199 tag = avio_rl32(pb);
00200 size = avio_rb32(pb);
00201 if(tag == MKTAG('C','N','T','I')) continue;
00202 if(tag == MKTAG('O','P','D','A')) continue;
00203 break;
00204 }
00205
00206
00207 if ((tag & 0xffffff) == MKTAG('M', 'T', 'R', 0)) {
00208 av_log(s, AV_LOG_ERROR, "MIDI like format found, unsupported\n");
00209 return -1;
00210 }
00211 if ((tag & 0xffffff) != MKTAG('A', 'T', 'R', 0)) {
00212 av_log(s, AV_LOG_ERROR, "Unsupported SMAF chunk %08x\n", tag);
00213 return -1;
00214 }
00215
00216 avio_r8(pb);
00217 avio_r8(pb);
00218 params = avio_r8(pb);
00219 rate = mmf_rate(params & 0x0f);
00220 if(rate < 0) {
00221 av_log(s, AV_LOG_ERROR, "Invalid sample rate\n");
00222 return -1;
00223 }
00224 avio_r8(pb);
00225 avio_r8(pb);
00226 avio_r8(pb);
00227
00228
00229 for(;; avio_skip(pb, size)) {
00230 tag = avio_rl32(pb);
00231 size = avio_rb32(pb);
00232 if(tag == MKTAG('A','t','s','q')) continue;
00233 if(tag == MKTAG('A','s','p','I')) continue;
00234 break;
00235 }
00236
00237
00238 if ((tag & 0xffffff) != MKTAG('A', 'w', 'a', 0)) {
00239 av_log(s, AV_LOG_ERROR, "Unexpected SMAF chunk %08x\n", tag);
00240 return -1;
00241 }
00242 mmf->data_size = size;
00243
00244 st = avformat_new_stream(s, NULL);
00245 if (!st)
00246 return AVERROR(ENOMEM);
00247
00248 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00249 st->codec->codec_id = CODEC_ID_ADPCM_YAMAHA;
00250 st->codec->sample_rate = rate;
00251 st->codec->channels = 1;
00252 st->codec->bits_per_coded_sample = 4;
00253 st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample;
00254
00255 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00256
00257 return 0;
00258 }
00259
00260 #define MAX_SIZE 4096
00261
00262 static int mmf_read_packet(AVFormatContext *s,
00263 AVPacket *pkt)
00264 {
00265 MMFContext *mmf = s->priv_data;
00266 int ret, size;
00267
00268 if (url_feof(s->pb))
00269 return AVERROR(EIO);
00270
00271 size = MAX_SIZE;
00272 if(size > mmf->data_size)
00273 size = mmf->data_size;
00274
00275 if(!size)
00276 return AVERROR(EIO);
00277
00278 ret = av_get_packet(s->pb, pkt, size);
00279 if (ret < 0)
00280 return ret;
00281
00282 pkt->stream_index = 0;
00283 mmf->data_size -= ret;
00284
00285 return ret;
00286 }
00287
00288 #if CONFIG_MMF_DEMUXER
00289 AVInputFormat ff_mmf_demuxer = {
00290 .name = "mmf",
00291 .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
00292 .priv_data_size = sizeof(MMFContext),
00293 .read_probe = mmf_probe,
00294 .read_header = mmf_read_header,
00295 .read_packet = mmf_read_packet,
00296 .read_seek = ff_pcm_read_seek,
00297 };
00298 #endif
00299 #if CONFIG_MMF_MUXER
00300 AVOutputFormat ff_mmf_muxer = {
00301 .name = "mmf",
00302 .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
00303 .mime_type = "application/vnd.smaf",
00304 .extensions = "mmf",
00305 .priv_data_size = sizeof(MMFContext),
00306 .audio_codec = CODEC_ID_ADPCM_YAMAHA,
00307 .video_codec = CODEC_ID_NONE,
00308 .write_header = mmf_write_header,
00309 .write_packet = mmf_write_packet,
00310 .write_trailer = mmf_write_trailer,
00311 };
00312 #endif