00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "avformat.h"
00024 #include "internal.h"
00025 #include "riff.h"
00026 #include "rso.h"
00027
00028 static int rso_write_header(AVFormatContext *s)
00029 {
00030 AVIOContext *pb = s->pb;
00031 AVCodecContext *enc = s->streams[0]->codec;
00032
00033 if (!enc->codec_tag)
00034 return AVERROR_INVALIDDATA;
00035
00036 if (enc->channels != 1) {
00037 av_log(s, AV_LOG_ERROR, "RSO only supports mono\n");
00038 return AVERROR_INVALIDDATA;
00039 }
00040
00041 if (!s->pb->seekable) {
00042 av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
00043 return AVERROR_INVALIDDATA;
00044 }
00045
00046
00047 if (enc->sample_rate >= 1u<<16) {
00048 av_log(s, AV_LOG_ERROR, "Sample rate must be < 65536\n");
00049 return AVERROR_INVALIDDATA;
00050 }
00051
00052 if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) {
00053 av_log(s, AV_LOG_ERROR, "ADPCM in RSO not implemented\n");
00054 return AVERROR_PATCHWELCOME;
00055 }
00056
00057
00058 avio_wb16(pb, enc->codec_tag);
00059 avio_wb16(pb, 0);
00060 avio_wb16(pb, enc->sample_rate);
00061 avio_wb16(pb, 0x0000);
00062
00063 avio_flush(pb);
00064
00065 return 0;
00066 }
00067
00068 static int rso_write_packet(AVFormatContext *s, AVPacket *pkt)
00069 {
00070 avio_write(s->pb, pkt->data, pkt->size);
00071 return 0;
00072 }
00073
00074 static int rso_write_trailer(AVFormatContext *s)
00075 {
00076 AVIOContext *pb = s->pb;
00077 int64_t file_size;
00078 uint16_t coded_file_size;
00079
00080 file_size = avio_tell(pb);
00081
00082 if (file_size < 0)
00083 return file_size;
00084
00085 if (file_size > 0xffff + RSO_HEADER_SIZE) {
00086 av_log(s, AV_LOG_WARNING,
00087 "Output file is too big (%"PRId64" bytes >= 64kB)\n", file_size);
00088 coded_file_size = 0xffff;
00089 } else {
00090 coded_file_size = file_size - RSO_HEADER_SIZE;
00091 }
00092
00093
00094 avio_seek(pb, 2, SEEK_SET);
00095 avio_wb16(pb, coded_file_size);
00096 avio_seek(pb, file_size, SEEK_SET);
00097
00098 avio_flush(pb);
00099
00100 return 0;
00101 }
00102
00103 AVOutputFormat ff_rso_muxer = {
00104 .name = "rso",
00105 .long_name = NULL_IF_CONFIG_SMALL("Lego Mindstorms RSO format"),
00106 .extensions = "rso",
00107 .priv_data_size = 0,
00108 .audio_codec = CODEC_ID_PCM_U8,
00109 .video_codec = CODEC_ID_NONE,
00110 .write_header = rso_write_header,
00111 .write_packet = rso_write_packet,
00112 .write_trailer = rso_write_trailer,
00113 .codec_tag = (const AVCodecTag* const []){ff_codec_rso_tags, 0},
00114 };