]> git.sesse.net Git - ffmpeg/blob - libavformat/rawenc.c
avformat/avio: Add Metacube support
[ffmpeg] / libavformat / rawenc.c
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     if (   s->oformat->audio_codec != AV_CODEC_ID_NONE
43         && s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
44         av_log(s, AV_LOG_ERROR, "%s files have exactly one audio stream\n",
45                s->oformat->name);
46         return AVERROR(EINVAL);
47     }
48     if (   s->oformat->video_codec != AV_CODEC_ID_NONE
49         && s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
50         av_log(s, AV_LOG_ERROR, "%s files have exactly one video stream\n",
51                s->oformat->name);
52         return AVERROR(EINVAL);
53     }
54     return 0;
55 }
56
57 /* Note: Do not forget to add new entries to the Makefile as well. */
58
59 #if CONFIG_AC3_MUXER
60 const AVOutputFormat ff_ac3_muxer = {
61     .name              = "ac3",
62     .long_name         = NULL_IF_CONFIG_SMALL("raw AC-3"),
63     .mime_type         = "audio/x-ac3",
64     .extensions        = "ac3",
65     .audio_codec       = AV_CODEC_ID_AC3,
66     .video_codec       = AV_CODEC_ID_NONE,
67     .init              = force_one_stream,
68     .write_packet      = ff_raw_write_packet,
69     .flags             = AVFMT_NOTIMESTAMPS,
70 };
71 #endif
72
73 #if CONFIG_ADX_MUXER
74
75 static int adx_write_trailer(AVFormatContext *s)
76 {
77     AVIOContext *pb = s->pb;
78     AVCodecParameters *par = s->streams[0]->codecpar;
79
80     if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
81         int64_t file_size = avio_tell(pb);
82         uint64_t sample_count = (file_size - 36) / par->channels / 18 * 32;
83         if (sample_count <= UINT32_MAX) {
84             avio_seek(pb, 12, SEEK_SET);
85             avio_wb32(pb, sample_count);
86             avio_seek(pb, file_size, SEEK_SET);
87         }
88     }
89
90     return 0;
91 }
92
93 const AVOutputFormat ff_adx_muxer = {
94     .name              = "adx",
95     .long_name         = NULL_IF_CONFIG_SMALL("CRI ADX"),
96     .extensions        = "adx",
97     .audio_codec       = AV_CODEC_ID_ADPCM_ADX,
98     .video_codec       = AV_CODEC_ID_NONE,
99     .init              = force_one_stream,
100     .write_packet      = ff_raw_write_packet,
101     .write_trailer     = adx_write_trailer,
102     .flags             = AVFMT_NOTIMESTAMPS,
103 };
104 #endif
105
106 #if CONFIG_APTX_MUXER
107 const AVOutputFormat ff_aptx_muxer = {
108     .name              = "aptx",
109     .long_name         = NULL_IF_CONFIG_SMALL("raw aptX (Audio Processing Technology for Bluetooth)"),
110     .extensions        = "aptx",
111     .audio_codec       = AV_CODEC_ID_APTX,
112     .video_codec       = AV_CODEC_ID_NONE,
113     .init              = force_one_stream,
114     .write_packet      = ff_raw_write_packet,
115     .flags             = AVFMT_NOTIMESTAMPS,
116 };
117 #endif
118
119 #if CONFIG_APTX_HD_MUXER
120 const AVOutputFormat ff_aptx_hd_muxer = {
121     .name              = "aptx_hd",
122     .long_name         = NULL_IF_CONFIG_SMALL("raw aptX HD (Audio Processing Technology for Bluetooth)"),
123     .extensions        = "aptxhd",
124     .audio_codec       = AV_CODEC_ID_APTX_HD,
125     .video_codec       = AV_CODEC_ID_NONE,
126     .init              = force_one_stream,
127     .write_packet      = ff_raw_write_packet,
128     .flags             = AVFMT_NOTIMESTAMPS,
129 };
130 #endif
131
132 #if CONFIG_AVS2_MUXER
133 const AVOutputFormat ff_avs2_muxer = {
134     .name              = "avs2",
135     .long_name         = NULL_IF_CONFIG_SMALL("raw AVS2-P2/IEEE1857.4 video"),
136     .extensions        = "avs,avs2",
137     .audio_codec       = AV_CODEC_ID_NONE,
138     .video_codec       = AV_CODEC_ID_AVS2,
139     .init              = force_one_stream,
140     .write_packet      = ff_raw_write_packet,
141     .flags             = AVFMT_NOTIMESTAMPS,
142 };
143 #endif
144
145 #if CONFIG_CAVSVIDEO_MUXER
146 const AVOutputFormat ff_cavsvideo_muxer = {
147     .name              = "cavsvideo",
148     .long_name         = NULL_IF_CONFIG_SMALL("raw Chinese AVS (Audio Video Standard) video"),
149     .extensions        = "cavs",
150     .audio_codec       = AV_CODEC_ID_NONE,
151     .video_codec       = AV_CODEC_ID_CAVS,
152     .init              = force_one_stream,
153     .write_packet      = ff_raw_write_packet,
154     .flags             = AVFMT_NOTIMESTAMPS,
155 };
156 #endif
157
158 #if CONFIG_CODEC2RAW_MUXER
159 const AVOutputFormat ff_codec2raw_muxer = {
160     .name              = "codec2raw",
161     .long_name         = NULL_IF_CONFIG_SMALL("raw codec2 muxer"),
162     .audio_codec       = AV_CODEC_ID_CODEC2,
163     .video_codec       = AV_CODEC_ID_NONE,
164     .init              = force_one_stream,
165     .write_packet      = ff_raw_write_packet,
166     .flags             = AVFMT_NOTIMESTAMPS,
167 };
168 #endif
169
170
171 #if CONFIG_DATA_MUXER
172 const AVOutputFormat ff_data_muxer = {
173     .name              = "data",
174     .long_name         = NULL_IF_CONFIG_SMALL("raw data"),
175     .init              = force_one_stream,
176     .write_packet      = ff_raw_write_packet,
177     .flags             = AVFMT_NOTIMESTAMPS,
178 };
179 #endif
180
181 #if CONFIG_DIRAC_MUXER
182 const AVOutputFormat ff_dirac_muxer = {
183     .name              = "dirac",
184     .long_name         = NULL_IF_CONFIG_SMALL("raw Dirac"),
185     .extensions        = "drc,vc2",
186     .audio_codec       = AV_CODEC_ID_NONE,
187     .video_codec       = AV_CODEC_ID_DIRAC,
188     .init              = force_one_stream,
189     .write_packet      = ff_raw_write_packet,
190     .flags             = AVFMT_NOTIMESTAMPS,
191 };
192 #endif
193
194 #if CONFIG_DNXHD_MUXER
195 const AVOutputFormat ff_dnxhd_muxer = {
196     .name              = "dnxhd",
197     .long_name         = NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"),
198     .extensions        = "dnxhd,dnxhr",
199     .audio_codec       = AV_CODEC_ID_NONE,
200     .video_codec       = AV_CODEC_ID_DNXHD,
201     .init              = force_one_stream,
202     .write_packet      = ff_raw_write_packet,
203     .flags             = AVFMT_NOTIMESTAMPS,
204 };
205 #endif
206
207 #if CONFIG_DTS_MUXER
208 const AVOutputFormat ff_dts_muxer = {
209     .name              = "dts",
210     .long_name         = NULL_IF_CONFIG_SMALL("raw DTS"),
211     .mime_type         = "audio/x-dca",
212     .extensions        = "dts",
213     .audio_codec       = AV_CODEC_ID_DTS,
214     .video_codec       = AV_CODEC_ID_NONE,
215     .init              = force_one_stream,
216     .write_packet      = ff_raw_write_packet,
217     .flags             = AVFMT_NOTIMESTAMPS,
218 };
219 #endif
220
221 #if CONFIG_EAC3_MUXER
222 const AVOutputFormat ff_eac3_muxer = {
223     .name              = "eac3",
224     .long_name         = NULL_IF_CONFIG_SMALL("raw E-AC-3"),
225     .mime_type         = "audio/x-eac3",
226     .extensions        = "eac3",
227     .audio_codec       = AV_CODEC_ID_EAC3,
228     .video_codec       = AV_CODEC_ID_NONE,
229     .init              = force_one_stream,
230     .write_packet      = ff_raw_write_packet,
231     .flags             = AVFMT_NOTIMESTAMPS,
232 };
233 #endif
234
235 #if CONFIG_G722_MUXER
236 const AVOutputFormat ff_g722_muxer = {
237     .name              = "g722",
238     .long_name         = NULL_IF_CONFIG_SMALL("raw G.722"),
239     .mime_type         = "audio/G722",
240     .extensions        = "g722",
241     .audio_codec       = AV_CODEC_ID_ADPCM_G722,
242     .video_codec       = AV_CODEC_ID_NONE,
243     .init              = force_one_stream,
244     .write_packet      = ff_raw_write_packet,
245     .flags             = AVFMT_NOTIMESTAMPS,
246 };
247 #endif
248
249 #if CONFIG_G723_1_MUXER
250 const AVOutputFormat ff_g723_1_muxer = {
251     .name              = "g723_1",
252     .long_name         = NULL_IF_CONFIG_SMALL("raw G.723.1"),
253     .mime_type         = "audio/g723",
254     .extensions        = "tco,rco",
255     .audio_codec       = AV_CODEC_ID_G723_1,
256     .video_codec       = AV_CODEC_ID_NONE,
257     .init              = force_one_stream,
258     .write_packet      = ff_raw_write_packet,
259     .flags             = AVFMT_NOTIMESTAMPS,
260 };
261 #endif
262
263 #if CONFIG_G726_MUXER
264 const AVOutputFormat ff_g726_muxer = {
265     .name              = "g726",
266     .long_name         = NULL_IF_CONFIG_SMALL("raw big-endian G.726 (\"left-justified\")"),
267     .audio_codec       = AV_CODEC_ID_ADPCM_G726,
268     .video_codec       = AV_CODEC_ID_NONE,
269     .init              = force_one_stream,
270     .write_packet      = ff_raw_write_packet,
271     .flags             = AVFMT_NOTIMESTAMPS,
272 };
273 #endif
274
275 #if CONFIG_G726LE_MUXER
276 const AVOutputFormat ff_g726le_muxer = {
277     .name              = "g726le",
278     .long_name         = NULL_IF_CONFIG_SMALL("raw little-endian G.726 (\"right-justified\")"),
279     .audio_codec       = AV_CODEC_ID_ADPCM_G726LE,
280     .video_codec       = AV_CODEC_ID_NONE,
281     .init              = force_one_stream,
282     .write_packet      = ff_raw_write_packet,
283     .flags             = AVFMT_NOTIMESTAMPS,
284 };
285 #endif
286
287 #if CONFIG_GSM_MUXER
288 const AVOutputFormat ff_gsm_muxer = {
289     .name              = "gsm",
290     .long_name         = NULL_IF_CONFIG_SMALL("raw GSM"),
291     .mime_type         = "audio/x-gsm",
292     .extensions        = "gsm",
293     .audio_codec       = AV_CODEC_ID_GSM,
294     .video_codec       = AV_CODEC_ID_NONE,
295     .init              = force_one_stream,
296     .write_packet      = ff_raw_write_packet,
297     .flags             = AVFMT_NOTIMESTAMPS,
298 };
299 #endif
300
301 #if CONFIG_H261_MUXER
302 const AVOutputFormat ff_h261_muxer = {
303     .name              = "h261",
304     .long_name         = NULL_IF_CONFIG_SMALL("raw H.261"),
305     .mime_type         = "video/x-h261",
306     .extensions        = "h261",
307     .audio_codec       = AV_CODEC_ID_NONE,
308     .video_codec       = AV_CODEC_ID_H261,
309     .init              = force_one_stream,
310     .write_packet      = ff_raw_write_packet,
311     .flags             = AVFMT_NOTIMESTAMPS,
312 };
313 #endif
314
315 #if CONFIG_H263_MUXER
316 const AVOutputFormat ff_h263_muxer = {
317     .name              = "h263",
318     .long_name         = NULL_IF_CONFIG_SMALL("raw H.263"),
319     .mime_type         = "video/x-h263",
320     .extensions        = "h263",
321     .audio_codec       = AV_CODEC_ID_NONE,
322     .video_codec       = AV_CODEC_ID_H263,
323     .init              = force_one_stream,
324     .write_packet      = ff_raw_write_packet,
325     .flags             = AVFMT_NOTIMESTAMPS,
326 };
327 #endif
328
329 #if CONFIG_H264_MUXER
330 static int h264_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt)
331 {
332     AVStream *st = s->streams[0];
333     if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 &&
334                           AV_RB24(pkt->data) != 0x000001)
335         return ff_stream_add_bitstream_filter(st, "h264_mp4toannexb", NULL);
336     return 1;
337 }
338
339 const AVOutputFormat ff_h264_muxer = {
340     .name              = "h264",
341     .long_name         = NULL_IF_CONFIG_SMALL("raw H.264 video"),
342     .extensions        = "h264,264",
343     .audio_codec       = AV_CODEC_ID_NONE,
344     .video_codec       = AV_CODEC_ID_H264,
345     .init              = force_one_stream,
346     .write_packet      = ff_raw_write_packet,
347     .check_bitstream   = h264_check_bitstream,
348     .flags             = AVFMT_NOTIMESTAMPS,
349 };
350 #endif
351
352 #if CONFIG_HEVC_MUXER
353 static int hevc_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt)
354 {
355     AVStream *st = s->streams[0];
356     if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 &&
357                           AV_RB24(pkt->data) != 0x000001)
358         return ff_stream_add_bitstream_filter(st, "hevc_mp4toannexb", NULL);
359     return 1;
360 }
361
362 const AVOutputFormat ff_hevc_muxer = {
363     .name              = "hevc",
364     .long_name         = NULL_IF_CONFIG_SMALL("raw HEVC video"),
365     .extensions        = "hevc,h265,265",
366     .audio_codec       = AV_CODEC_ID_NONE,
367     .video_codec       = AV_CODEC_ID_HEVC,
368     .init              = force_one_stream,
369     .write_packet      = ff_raw_write_packet,
370     .check_bitstream   = hevc_check_bitstream,
371     .flags             = AVFMT_NOTIMESTAMPS,
372 };
373 #endif
374
375 #if CONFIG_M4V_MUXER
376 const AVOutputFormat ff_m4v_muxer = {
377     .name              = "m4v",
378     .long_name         = NULL_IF_CONFIG_SMALL("raw MPEG-4 video"),
379     .extensions        = "m4v",
380     .audio_codec       = AV_CODEC_ID_NONE,
381     .video_codec       = AV_CODEC_ID_MPEG4,
382     .init              = force_one_stream,
383     .write_packet      = ff_raw_write_packet,
384     .flags             = AVFMT_NOTIMESTAMPS,
385 };
386 #endif
387
388 #if CONFIG_MJPEG_MUXER
389 const AVOutputFormat ff_mjpeg_muxer = {
390     .name              = "mjpeg",
391     .long_name         = NULL_IF_CONFIG_SMALL("raw MJPEG video"),
392     .mime_type         = "video/x-mjpeg",
393     .extensions        = "mjpg,mjpeg",
394     .audio_codec       = AV_CODEC_ID_NONE,
395     .video_codec       = AV_CODEC_ID_MJPEG,
396     .init              = force_one_stream,
397     .write_packet      = ff_raw_write_packet,
398     .flags             = AVFMT_NOTIMESTAMPS,
399 };
400 #endif
401
402 #if CONFIG_MLP_MUXER
403 const AVOutputFormat ff_mlp_muxer = {
404     .name              = "mlp",
405     .long_name         = NULL_IF_CONFIG_SMALL("raw MLP"),
406     .extensions        = "mlp",
407     .audio_codec       = AV_CODEC_ID_MLP,
408     .video_codec       = AV_CODEC_ID_NONE,
409     .init              = force_one_stream,
410     .write_packet      = ff_raw_write_packet,
411     .flags             = AVFMT_NOTIMESTAMPS,
412 };
413 #endif
414
415 #if CONFIG_MP2_MUXER
416 const AVOutputFormat ff_mp2_muxer = {
417     .name              = "mp2",
418     .long_name         = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
419     .mime_type         = "audio/mpeg",
420     .extensions        = "mp2,m2a,mpa",
421     .audio_codec       = AV_CODEC_ID_MP2,
422     .video_codec       = AV_CODEC_ID_NONE,
423     .init              = force_one_stream,
424     .write_packet      = ff_raw_write_packet,
425     .flags             = AVFMT_NOTIMESTAMPS,
426 };
427 #endif
428
429 #if CONFIG_MPEG1VIDEO_MUXER
430 const AVOutputFormat ff_mpeg1video_muxer = {
431     .name              = "mpeg1video",
432     .long_name         = NULL_IF_CONFIG_SMALL("raw MPEG-1 video"),
433     .mime_type         = "video/mpeg",
434     .extensions        = "mpg,mpeg,m1v",
435     .audio_codec       = AV_CODEC_ID_NONE,
436     .video_codec       = AV_CODEC_ID_MPEG1VIDEO,
437     .init              = force_one_stream,
438     .write_packet      = ff_raw_write_packet,
439     .flags             = AVFMT_NOTIMESTAMPS,
440 };
441 #endif
442
443 #if CONFIG_MPEG2VIDEO_MUXER
444 const AVOutputFormat ff_mpeg2video_muxer = {
445     .name              = "mpeg2video",
446     .long_name         = NULL_IF_CONFIG_SMALL("raw MPEG-2 video"),
447     .extensions        = "m2v",
448     .audio_codec       = AV_CODEC_ID_NONE,
449     .video_codec       = AV_CODEC_ID_MPEG2VIDEO,
450     .init              = force_one_stream,
451     .write_packet      = ff_raw_write_packet,
452     .flags             = AVFMT_NOTIMESTAMPS,
453 };
454 #endif
455
456 #if CONFIG_RAWVIDEO_MUXER
457 const AVOutputFormat ff_rawvideo_muxer = {
458     .name              = "rawvideo",
459     .long_name         = NULL_IF_CONFIG_SMALL("raw video"),
460     .extensions        = "yuv,rgb",
461     .audio_codec       = AV_CODEC_ID_NONE,
462     .video_codec       = AV_CODEC_ID_RAWVIDEO,
463     .write_packet      = ff_raw_write_packet,
464     .flags             = AVFMT_NOTIMESTAMPS,
465 };
466 #endif
467
468 #if CONFIG_SBC_MUXER
469 const AVOutputFormat ff_sbc_muxer = {
470     .name              = "sbc",
471     .long_name         = NULL_IF_CONFIG_SMALL("raw SBC"),
472     .mime_type         = "audio/x-sbc",
473     .extensions        = "sbc,msbc",
474     .audio_codec       = AV_CODEC_ID_SBC,
475     .init              = force_one_stream,
476     .write_packet      = ff_raw_write_packet,
477     .flags             = AVFMT_NOTIMESTAMPS,
478 };
479 #endif
480
481 #if CONFIG_TRUEHD_MUXER
482 const AVOutputFormat ff_truehd_muxer = {
483     .name              = "truehd",
484     .long_name         = NULL_IF_CONFIG_SMALL("raw TrueHD"),
485     .extensions        = "thd",
486     .audio_codec       = AV_CODEC_ID_TRUEHD,
487     .video_codec       = AV_CODEC_ID_NONE,
488     .init              = force_one_stream,
489     .write_packet      = ff_raw_write_packet,
490     .flags             = AVFMT_NOTIMESTAMPS,
491 };
492 #endif
493
494 #if CONFIG_VC1_MUXER
495 const AVOutputFormat ff_vc1_muxer = {
496     .name              = "vc1",
497     .long_name         = NULL_IF_CONFIG_SMALL("raw VC-1 video"),
498     .extensions        = "vc1",
499     .audio_codec       = AV_CODEC_ID_NONE,
500     .video_codec       = AV_CODEC_ID_VC1,
501     .init              = force_one_stream,
502     .write_packet      = ff_raw_write_packet,
503     .flags             = AVFMT_NOTIMESTAMPS,
504 };
505 #endif