ffmpeg / libavformat / rsoenc.c @ e8723e24
History | View | Annotate | Download (3.3 KB)
1 |
/*
|
---|---|
2 |
* RSO muxer
|
3 |
* Copyright (c) 2001 Fabrice Bellard (original AU code)
|
4 |
* Copyright (c) 2010 Rafael Carre
|
5 |
*
|
6 |
* This file is part of FFmpeg.
|
7 |
*
|
8 |
* FFmpeg is free software; you can redistribute it and/or
|
9 |
* modify it under the terms of the GNU Lesser General Public
|
10 |
* License as published by the Free Software Foundation; either
|
11 |
* version 2.1 of the License, or (at your option) any later version.
|
12 |
*
|
13 |
* FFmpeg is distributed in the hope that it will be useful,
|
14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
16 |
* Lesser General Public License for more details.
|
17 |
*
|
18 |
* You should have received a copy of the GNU Lesser General Public
|
19 |
* License along with FFmpeg; if not, write to the Free Software
|
20 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21 |
*/
|
22 |
|
23 |
#include "avformat.h" |
24 |
#include "internal.h" |
25 |
#include "riff.h" |
26 |
#include "rso.h" |
27 |
|
28 |
static int rso_write_header(AVFormatContext *s) |
29 |
{ |
30 |
ByteIOContext *pb = s->pb; |
31 |
AVCodecContext *enc = s->streams[0]->codec;
|
32 |
|
33 |
if (!enc->codec_tag)
|
34 |
return AVERROR_INVALIDDATA;
|
35 |
|
36 |
if (enc->channels != 1) { |
37 |
av_log(s, AV_LOG_ERROR, "RSO only supports mono\n");
|
38 |
return AVERROR_INVALIDDATA;
|
39 |
} |
40 |
|
41 |
if (url_is_streamed(s->pb)) {
|
42 |
av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
|
43 |
return AVERROR_INVALIDDATA;
|
44 |
} |
45 |
|
46 |
/* XXX: find legal sample rates (if any) */
|
47 |
if (enc->sample_rate >= 1u<<16) { |
48 |
av_log(s, AV_LOG_ERROR, "Sample rate must be < 65536\n");
|
49 |
return AVERROR_INVALIDDATA;
|
50 |
} |
51 |
|
52 |
if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) {
|
53 |
av_log(s, AV_LOG_ERROR, "ADPCM in RSO not implemented\n");
|
54 |
return AVERROR_PATCHWELCOME;
|
55 |
} |
56 |
|
57 |
/* format header */
|
58 |
put_be16(pb, enc->codec_tag); /* codec ID */
|
59 |
put_be16(pb, 0); /* data size, will be written at EOF */ |
60 |
put_be16(pb, enc->sample_rate); |
61 |
put_be16(pb, 0x0000); /* play mode ? (0x0000 = don't loop) */ |
62 |
|
63 |
put_flush_packet(pb); |
64 |
|
65 |
return 0; |
66 |
} |
67 |
|
68 |
static int rso_write_packet(AVFormatContext *s, AVPacket *pkt) |
69 |
{ |
70 |
put_buffer(s->pb, pkt->data, pkt->size); |
71 |
return 0; |
72 |
} |
73 |
|
74 |
static int rso_write_trailer(AVFormatContext *s) |
75 |
{ |
76 |
ByteIOContext *pb = s->pb; |
77 |
int64_t file_size; |
78 |
uint16_t coded_file_size; |
79 |
|
80 |
file_size = url_ftell(pb); |
81 |
|
82 |
if (file_size < 0) |
83 |
return file_size;
|
84 |
|
85 |
if (file_size > 0xffff + RSO_HEADER_SIZE) { |
86 |
av_log(s, AV_LOG_WARNING, |
87 |
"Output file is too big (%"PRId64" bytes >= 64kB)\n", file_size); |
88 |
coded_file_size = 0xffff;
|
89 |
} else {
|
90 |
coded_file_size = file_size - RSO_HEADER_SIZE; |
91 |
} |
92 |
|
93 |
/* update file size */
|
94 |
url_fseek(pb, 2, SEEK_SET);
|
95 |
put_be16(pb, coded_file_size); |
96 |
url_fseek(pb, file_size, SEEK_SET); |
97 |
|
98 |
put_flush_packet(pb); |
99 |
|
100 |
return 0; |
101 |
} |
102 |
|
103 |
AVOutputFormat rso_muxer = { |
104 |
.name = "rso",
|
105 |
.long_name = NULL_IF_CONFIG_SMALL("Lego Mindstorms RSO format"),
|
106 |
.extensions = "rso",
|
107 |
.priv_data_size = 0,
|
108 |
.audio_codec = CODEC_ID_PCM_U8, |
109 |
.video_codec = CODEC_ID_NONE, |
110 |
.write_header = rso_write_header, |
111 |
.write_packet = rso_write_packet, |
112 |
.write_trailer = rso_write_trailer, |
113 |
.codec_tag = (const AVCodecTag* const []){ff_codec_rso_tags, 0}, |
114 |
}; |