blob: 26baa850e1be66425b987304d07dc44d9036b407
1 | /* |
2 | * RAW muxers |
3 | * Copyright (c) 2001 Fabrice Bellard |
4 | * Copyright (c) 2005 Alex Beregszaszi |
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 "libavutil/intreadwrite.h" |
24 | |
25 | #include "avformat.h" |
26 | #include "rawenc.h" |
27 | #include "internal.h" |
28 | |
29 | int ff_raw_write_packet(AVFormatContext *s, AVPacket *pkt) |
30 | { |
31 | avio_write(s->pb, pkt->data, pkt->size); |
32 | return 0; |
33 | } |
34 | |
35 | static int force_one_stream(AVFormatContext *s) |
36 | { |
37 | if (s->nb_streams != 1) { |
38 | av_log(s, AV_LOG_ERROR, "%s files have exactly one stream\n", |
39 | s->oformat->name); |
40 | return AVERROR(EINVAL); |
41 | } |
42 | return 0; |
43 | } |
44 | |
45 | /* Note: Do not forget to add new entries to the Makefile as well. */ |
46 | |
47 | #if CONFIG_AC3_MUXER |
48 | AVOutputFormat ff_ac3_muxer = { |
49 | .name = "ac3", |
50 | .long_name = NULL_IF_CONFIG_SMALL("raw AC-3"), |
51 | .mime_type = "audio/x-ac3", |
52 | .extensions = "ac3", |
53 | .audio_codec = AV_CODEC_ID_AC3, |
54 | .video_codec = AV_CODEC_ID_NONE, |
55 | .write_header = force_one_stream, |
56 | .write_packet = ff_raw_write_packet, |
57 | .flags = AVFMT_NOTIMESTAMPS, |
58 | }; |
59 | #endif |
60 | |
61 | #if CONFIG_ADX_MUXER |
62 | |
63 | static int adx_write_trailer(AVFormatContext *s) |
64 | { |
65 | AVIOContext *pb = s->pb; |
66 | AVCodecParameters *par = s->streams[0]->codecpar; |
67 | |
68 | if (pb->seekable & AVIO_SEEKABLE_NORMAL) { |
69 | int64_t file_size = avio_tell(pb); |
70 | uint64_t sample_count = (file_size - 36) / par->channels / 18 * 32; |
71 | if (sample_count <= UINT32_MAX) { |
72 | avio_seek(pb, 12, SEEK_SET); |
73 | avio_wb32(pb, sample_count); |
74 | avio_seek(pb, file_size, SEEK_SET); |
75 | } |
76 | } |
77 | |
78 | return 0; |
79 | } |
80 | |
81 | AVOutputFormat ff_adx_muxer = { |
82 | .name = "adx", |
83 | .long_name = NULL_IF_CONFIG_SMALL("CRI ADX"), |
84 | .extensions = "adx", |
85 | .audio_codec = AV_CODEC_ID_ADPCM_ADX, |
86 | .video_codec = AV_CODEC_ID_NONE, |
87 | .write_header = force_one_stream, |
88 | .write_packet = ff_raw_write_packet, |
89 | .write_trailer = adx_write_trailer, |
90 | .flags = AVFMT_NOTIMESTAMPS, |
91 | }; |
92 | #endif |
93 | |
94 | #if CONFIG_CAVSVIDEO_MUXER |
95 | AVOutputFormat ff_cavsvideo_muxer = { |
96 | .name = "cavsvideo", |
97 | .long_name = NULL_IF_CONFIG_SMALL("raw Chinese AVS (Audio Video Standard) video"), |
98 | .extensions = "cavs", |
99 | .audio_codec = AV_CODEC_ID_NONE, |
100 | .video_codec = AV_CODEC_ID_CAVS, |
101 | .write_header = force_one_stream, |
102 | .write_packet = ff_raw_write_packet, |
103 | .flags = AVFMT_NOTIMESTAMPS, |
104 | }; |
105 | #endif |
106 | |
107 | #if CONFIG_DATA_MUXER |
108 | AVOutputFormat ff_data_muxer = { |
109 | .name = "data", |
110 | .long_name = NULL_IF_CONFIG_SMALL("raw data"), |
111 | .write_header = force_one_stream, |
112 | .write_packet = ff_raw_write_packet, |
113 | .flags = AVFMT_NOTIMESTAMPS, |
114 | }; |
115 | #endif |
116 | |
117 | #if CONFIG_DIRAC_MUXER |
118 | AVOutputFormat ff_dirac_muxer = { |
119 | .name = "dirac", |
120 | .long_name = NULL_IF_CONFIG_SMALL("raw Dirac"), |
121 | .extensions = "drc,vc2", |
122 | .audio_codec = AV_CODEC_ID_NONE, |
123 | .video_codec = AV_CODEC_ID_DIRAC, |
124 | .write_header = force_one_stream, |
125 | .write_packet = ff_raw_write_packet, |
126 | .flags = AVFMT_NOTIMESTAMPS, |
127 | }; |
128 | #endif |
129 | |
130 | #if CONFIG_DNXHD_MUXER |
131 | AVOutputFormat ff_dnxhd_muxer = { |
132 | .name = "dnxhd", |
133 | .long_name = NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"), |
134 | .extensions = "dnxhd,dnxhr", |
135 | .audio_codec = AV_CODEC_ID_NONE, |
136 | .video_codec = AV_CODEC_ID_DNXHD, |
137 | .write_header = force_one_stream, |
138 | .write_packet = ff_raw_write_packet, |
139 | .flags = AVFMT_NOTIMESTAMPS, |
140 | }; |
141 | #endif |
142 | |
143 | #if CONFIG_DTS_MUXER |
144 | AVOutputFormat ff_dts_muxer = { |
145 | .name = "dts", |
146 | .long_name = NULL_IF_CONFIG_SMALL("raw DTS"), |
147 | .mime_type = "audio/x-dca", |
148 | .extensions = "dts", |
149 | .audio_codec = AV_CODEC_ID_DTS, |
150 | .video_codec = AV_CODEC_ID_NONE, |
151 | .write_header = force_one_stream, |
152 | .write_packet = ff_raw_write_packet, |
153 | .flags = AVFMT_NOTIMESTAMPS, |
154 | }; |
155 | #endif |
156 | |
157 | #if CONFIG_EAC3_MUXER |
158 | AVOutputFormat ff_eac3_muxer = { |
159 | .name = "eac3", |
160 | .long_name = NULL_IF_CONFIG_SMALL("raw E-AC-3"), |
161 | .mime_type = "audio/x-eac3", |
162 | .extensions = "eac3", |
163 | .audio_codec = AV_CODEC_ID_EAC3, |
164 | .video_codec = AV_CODEC_ID_NONE, |
165 | .write_header = force_one_stream, |
166 | .write_packet = ff_raw_write_packet, |
167 | .flags = AVFMT_NOTIMESTAMPS, |
168 | }; |
169 | #endif |
170 | |
171 | #if CONFIG_G722_MUXER |
172 | AVOutputFormat ff_g722_muxer = { |
173 | .name = "g722", |
174 | .long_name = NULL_IF_CONFIG_SMALL("raw G.722"), |
175 | .mime_type = "audio/G722", |
176 | .extensions = "g722", |
177 | .audio_codec = AV_CODEC_ID_ADPCM_G722, |
178 | .video_codec = AV_CODEC_ID_NONE, |
179 | .write_header = force_one_stream, |
180 | .write_packet = ff_raw_write_packet, |
181 | .flags = AVFMT_NOTIMESTAMPS, |
182 | }; |
183 | #endif |
184 | |
185 | #if CONFIG_G723_1_MUXER |
186 | AVOutputFormat ff_g723_1_muxer = { |
187 | .name = "g723_1", |
188 | .long_name = NULL_IF_CONFIG_SMALL("raw G.723.1"), |
189 | .mime_type = "audio/g723", |
190 | .extensions = "tco,rco", |
191 | .audio_codec = AV_CODEC_ID_G723_1, |
192 | .video_codec = AV_CODEC_ID_NONE, |
193 | .write_header = force_one_stream, |
194 | .write_packet = ff_raw_write_packet, |
195 | .flags = AVFMT_NOTIMESTAMPS, |
196 | }; |
197 | #endif |
198 | |
199 | #if CONFIG_GSM_MUXER |
200 | AVOutputFormat ff_gsm_muxer = { |
201 | .name = "gsm", |
202 | .long_name = NULL_IF_CONFIG_SMALL("raw GSM"), |
203 | .mime_type = "audio/x-gsm", |
204 | .extensions = "gsm", |
205 | .audio_codec = AV_CODEC_ID_GSM, |
206 | .video_codec = AV_CODEC_ID_NONE, |
207 | .write_header = force_one_stream, |
208 | .write_packet = ff_raw_write_packet, |
209 | .flags = AVFMT_NOTIMESTAMPS, |
210 | }; |
211 | #endif |
212 | |
213 | #if CONFIG_H261_MUXER |
214 | AVOutputFormat ff_h261_muxer = { |
215 | .name = "h261", |
216 | .long_name = NULL_IF_CONFIG_SMALL("raw H.261"), |
217 | .mime_type = "video/x-h261", |
218 | .extensions = "h261", |
219 | .audio_codec = AV_CODEC_ID_NONE, |
220 | .video_codec = AV_CODEC_ID_H261, |
221 | .write_header = force_one_stream, |
222 | .write_packet = ff_raw_write_packet, |
223 | .flags = AVFMT_NOTIMESTAMPS, |
224 | }; |
225 | #endif |
226 | |
227 | #if CONFIG_H263_MUXER |
228 | AVOutputFormat ff_h263_muxer = { |
229 | .name = "h263", |
230 | .long_name = NULL_IF_CONFIG_SMALL("raw H.263"), |
231 | .mime_type = "video/x-h263", |
232 | .extensions = "h263", |
233 | .audio_codec = AV_CODEC_ID_NONE, |
234 | .video_codec = AV_CODEC_ID_H263, |
235 | .write_header = force_one_stream, |
236 | .write_packet = ff_raw_write_packet, |
237 | .flags = AVFMT_NOTIMESTAMPS, |
238 | }; |
239 | #endif |
240 | |
241 | #if CONFIG_H264_MUXER |
242 | static int h264_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt) |
243 | { |
244 | AVStream *st = s->streams[0]; |
245 | if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 && |
246 | AV_RB24(pkt->data) != 0x000001) |
247 | return ff_stream_add_bitstream_filter(st, "h264_mp4toannexb", NULL); |
248 | return 1; |
249 | } |
250 | |
251 | AVOutputFormat ff_h264_muxer = { |
252 | .name = "h264", |
253 | .long_name = NULL_IF_CONFIG_SMALL("raw H.264 video"), |
254 | .extensions = "h264,264", |
255 | .audio_codec = AV_CODEC_ID_NONE, |
256 | .video_codec = AV_CODEC_ID_H264, |
257 | .write_header = force_one_stream, |
258 | .write_packet = ff_raw_write_packet, |
259 | .check_bitstream = h264_check_bitstream, |
260 | .flags = AVFMT_NOTIMESTAMPS, |
261 | }; |
262 | #endif |
263 | |
264 | #if CONFIG_HEVC_MUXER |
265 | static int hevc_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt) |
266 | { |
267 | AVStream *st = s->streams[0]; |
268 | if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 && |
269 | AV_RB24(pkt->data) != 0x000001) |
270 | return ff_stream_add_bitstream_filter(st, "hevc_mp4toannexb", NULL); |
271 | return 1; |
272 | } |
273 | |
274 | AVOutputFormat ff_hevc_muxer = { |
275 | .name = "hevc", |
276 | .long_name = NULL_IF_CONFIG_SMALL("raw HEVC video"), |
277 | .extensions = "hevc,h265,265", |
278 | .audio_codec = AV_CODEC_ID_NONE, |
279 | .video_codec = AV_CODEC_ID_HEVC, |
280 | .write_header = force_one_stream, |
281 | .write_packet = ff_raw_write_packet, |
282 | .check_bitstream = hevc_check_bitstream, |
283 | .flags = AVFMT_NOTIMESTAMPS, |
284 | }; |
285 | #endif |
286 | |
287 | #if CONFIG_M4V_MUXER |
288 | AVOutputFormat ff_m4v_muxer = { |
289 | .name = "m4v", |
290 | .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-4 video"), |
291 | .extensions = "m4v", |
292 | .audio_codec = AV_CODEC_ID_NONE, |
293 | .video_codec = AV_CODEC_ID_MPEG4, |
294 | .write_header = force_one_stream, |
295 | .write_packet = ff_raw_write_packet, |
296 | .flags = AVFMT_NOTIMESTAMPS, |
297 | }; |
298 | #endif |
299 | |
300 | #if CONFIG_MJPEG_MUXER |
301 | AVOutputFormat ff_mjpeg_muxer = { |
302 | .name = "mjpeg", |
303 | .long_name = NULL_IF_CONFIG_SMALL("raw MJPEG video"), |
304 | .mime_type = "video/x-mjpeg", |
305 | .extensions = "mjpg,mjpeg", |
306 | .audio_codec = AV_CODEC_ID_NONE, |
307 | .video_codec = AV_CODEC_ID_MJPEG, |
308 | .write_header = force_one_stream, |
309 | .write_packet = ff_raw_write_packet, |
310 | .flags = AVFMT_NOTIMESTAMPS, |
311 | }; |
312 | #endif |
313 | |
314 | #if CONFIG_SINGLEJPEG_MUXER |
315 | AVOutputFormat ff_singlejpeg_muxer = { |
316 | .name = "singlejpeg", |
317 | .long_name = NULL_IF_CONFIG_SMALL("JPEG single image"), |
318 | .mime_type = "image/jpeg", |
319 | .audio_codec = AV_CODEC_ID_NONE, |
320 | .video_codec = AV_CODEC_ID_MJPEG, |
321 | .write_packet = ff_raw_write_packet, |
322 | .flags = AVFMT_NOTIMESTAMPS, |
323 | .write_header = force_one_stream, |
324 | }; |
325 | #endif |
326 | |
327 | #if CONFIG_MLP_MUXER |
328 | AVOutputFormat ff_mlp_muxer = { |
329 | .name = "mlp", |
330 | .long_name = NULL_IF_CONFIG_SMALL("raw MLP"), |
331 | .extensions = "mlp", |
332 | .audio_codec = AV_CODEC_ID_MLP, |
333 | .video_codec = AV_CODEC_ID_NONE, |
334 | .write_header = force_one_stream, |
335 | .write_packet = ff_raw_write_packet, |
336 | .flags = AVFMT_NOTIMESTAMPS, |
337 | }; |
338 | #endif |
339 | |
340 | #if CONFIG_MP2_MUXER |
341 | AVOutputFormat ff_mp2_muxer = { |
342 | .name = "mp2", |
343 | .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), |
344 | .mime_type = "audio/mpeg", |
345 | .extensions = "mp2,m2a,mpa", |
346 | .audio_codec = AV_CODEC_ID_MP2, |
347 | .video_codec = AV_CODEC_ID_NONE, |
348 | .write_packet = ff_raw_write_packet, |
349 | .flags = AVFMT_NOTIMESTAMPS, |
350 | }; |
351 | #endif |
352 | |
353 | #if CONFIG_MPEG1VIDEO_MUXER |
354 | AVOutputFormat ff_mpeg1video_muxer = { |
355 | .name = "mpeg1video", |
356 | .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-1 video"), |
357 | .mime_type = "video/mpeg", |
358 | .extensions = "mpg,mpeg,m1v", |
359 | .audio_codec = AV_CODEC_ID_NONE, |
360 | .video_codec = AV_CODEC_ID_MPEG1VIDEO, |
361 | .write_header = force_one_stream, |
362 | .write_packet = ff_raw_write_packet, |
363 | .flags = AVFMT_NOTIMESTAMPS, |
364 | }; |
365 | #endif |
366 | |
367 | #if CONFIG_MPEG2VIDEO_MUXER |
368 | AVOutputFormat ff_mpeg2video_muxer = { |
369 | .name = "mpeg2video", |
370 | .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-2 video"), |
371 | .extensions = "m2v", |
372 | .audio_codec = AV_CODEC_ID_NONE, |
373 | .video_codec = AV_CODEC_ID_MPEG2VIDEO, |
374 | .write_header = force_one_stream, |
375 | .write_packet = ff_raw_write_packet, |
376 | .flags = AVFMT_NOTIMESTAMPS, |
377 | }; |
378 | #endif |
379 | |
380 | #if CONFIG_RAWVIDEO_MUXER |
381 | AVOutputFormat ff_rawvideo_muxer = { |
382 | .name = "rawvideo", |
383 | .long_name = NULL_IF_CONFIG_SMALL("raw video"), |
384 | .extensions = "yuv,rgb", |
385 | .audio_codec = AV_CODEC_ID_NONE, |
386 | .video_codec = AV_CODEC_ID_RAWVIDEO, |
387 | .write_packet = ff_raw_write_packet, |
388 | .flags = AVFMT_NOTIMESTAMPS, |
389 | }; |
390 | #endif |
391 | |
392 | #if CONFIG_TRUEHD_MUXER |
393 | AVOutputFormat ff_truehd_muxer = { |
394 | .name = "truehd", |
395 | .long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"), |
396 | .extensions = "thd", |
397 | .audio_codec = AV_CODEC_ID_TRUEHD, |
398 | .video_codec = AV_CODEC_ID_NONE, |
399 | .write_header = force_one_stream, |
400 | .write_packet = ff_raw_write_packet, |
401 | .flags = AVFMT_NOTIMESTAMPS, |
402 | }; |
403 | #endif |
404 | |
405 | #if CONFIG_VC1_MUXER |
406 | AVOutputFormat ff_vc1_muxer = { |
407 | .name = "vc1", |
408 | .long_name = NULL_IF_CONFIG_SMALL("raw VC-1 video"), |
409 | .extensions = "vc1", |
410 | .audio_codec = AV_CODEC_ID_NONE, |
411 | .video_codec = AV_CODEC_ID_VC1, |
412 | .write_header = force_one_stream, |
413 | .write_packet = ff_raw_write_packet, |
414 | .flags = AVFMT_NOTIMESTAMPS, |
415 | }; |
416 | #endif |
417 |