aiffenc.c
Go to the documentation of this file.
1 /*
2  * AIFF/AIFF-C muxer
3  * Copyright (c) 2006 Patrick Guimond
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/intfloat.h"
23 #include "libavutil/opt.h"
24 #include "avformat.h"
25 #include "internal.h"
26 #include "aiff.h"
27 #include "avio_internal.h"
28 #include "isom.h"
29 #include "id3v2.h"
30 
31 typedef struct {
32  const AVClass *class;
33  int64_t form;
34  int64_t frames;
35  int64_t ssnd;
41 
43 {
44  int ret;
45  uint64_t pos, end, size;
46  ID3v2EncContext id3v2 = { 0 };
47  AVIOContext *pb = s->pb;
48  AVPacketList *pict_list = aiff->pict_list;
49 
50  if (!pb->seekable)
51  return 0;
52 
53  if (!s->metadata && !aiff->pict_list)
54  return 0;
55 
56  avio_wl32(pb, MKTAG('I', 'D', '3', ' '));
57  avio_wb32(pb, 0);
58  pos = avio_tell(pb);
59 
61  ff_id3v2_write_metadata(s, &id3v2);
62  while (pict_list) {
63  if ((ret = ff_id3v2_write_apic(s, &id3v2, &pict_list->pkt)) < 0)
64  return ret;
65  pict_list = pict_list->next;
66  }
67  ff_id3v2_finish(&id3v2, pb);
68 
69  end = avio_tell(pb);
70  size = end - pos;
71 
72  /* Update chunk size */
73  avio_seek(pb, pos - 4, SEEK_SET);
74  avio_wb32(pb, size);
75  avio_seek(pb, end, SEEK_SET);
76 
77  if (size & 1)
78  avio_w8(pb, 0);
79 
80  return 0;
81 }
82 
83 static void put_meta(AVFormatContext *s, const char *key, uint32_t id)
84 {
86  AVIOContext *pb = s->pb;
87 
88  if (tag = av_dict_get(s->metadata, key, NULL, 0)) {
89  int size = strlen(tag->value);
90 
91  avio_wl32(pb, id);
92  avio_wb32(pb, FFALIGN(size, 2));
93  avio_write(pb, tag->value, size);
94  if (size & 1)
95  avio_w8(pb, 0);
96  }
97 }
98 
100 {
101  AIFFOutputContext *aiff = s->priv_data;
102  AVIOContext *pb = s->pb;
103  AVCodecContext *enc;
104  uint64_t sample_rate;
105  int i, aifc = 0;
106 
107  aiff->audio_stream_idx = -1;
108  for (i = 0; i < s->nb_streams; i++) {
109  AVStream *st = s->streams[i];
110  if (aiff->audio_stream_idx < 0 && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
111  aiff->audio_stream_idx = i;
112  } else if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO) {
113  av_log(s, AV_LOG_ERROR, "Only audio streams and pictures are allowed in AIFF.\n");
114  return AVERROR(EINVAL);
115  }
116  }
117  if (aiff->audio_stream_idx < 0) {
118  av_log(s, AV_LOG_ERROR, "No audio stream present.\n");
119  return AVERROR(EINVAL);
120  }
121 
122  enc = s->streams[aiff->audio_stream_idx]->codec;
123 
124  /* First verify if format is ok */
125  if (!enc->codec_tag)
126  return -1;
127  if (enc->codec_tag != MKTAG('N','O','N','E'))
128  aifc = 1;
129 
130  /* FORM AIFF header */
131  ffio_wfourcc(pb, "FORM");
132  aiff->form = avio_tell(pb);
133  avio_wb32(pb, 0); /* file length */
134  ffio_wfourcc(pb, aifc ? "AIFC" : "AIFF");
135 
136  if (aifc) { // compressed audio
137  if (!enc->block_align) {
138  av_log(s, AV_LOG_ERROR, "block align not set\n");
139  return -1;
140  }
141  /* Version chunk */
142  ffio_wfourcc(pb, "FVER");
143  avio_wb32(pb, 4);
144  avio_wb32(pb, 0xA2805140);
145  }
146 
147  if (enc->channels > 2 && enc->channel_layout) {
148  ffio_wfourcc(pb, "CHAN");
149  avio_wb32(pb, 12);
151  }
152 
153  put_meta(s, "title", MKTAG('N', 'A', 'M', 'E'));
154  put_meta(s, "author", MKTAG('A', 'U', 'T', 'H'));
155  put_meta(s, "copyright", MKTAG('(', 'c', ')', ' '));
156  put_meta(s, "comment", MKTAG('A', 'N', 'N', 'O'));
157 
158  /* Common chunk */
159  ffio_wfourcc(pb, "COMM");
160  avio_wb32(pb, aifc ? 24 : 18); /* size */
161  avio_wb16(pb, enc->channels); /* Number of channels */
162 
163  aiff->frames = avio_tell(pb);
164  avio_wb32(pb, 0); /* Number of frames */
165 
166  if (!enc->bits_per_coded_sample)
168  if (!enc->bits_per_coded_sample) {
169  av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
170  return -1;
171  }
172  if (!enc->block_align)
173  enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3;
174 
175  avio_wb16(pb, enc->bits_per_coded_sample); /* Sample size */
176 
177  sample_rate = av_double2int(enc->sample_rate);
178  avio_wb16(pb, (sample_rate >> 52) + (16383 - 1023));
179  avio_wb64(pb, UINT64_C(1) << 63 | sample_rate << 11);
180 
181  if (aifc) {
182  avio_wl32(pb, enc->codec_tag);
183  avio_wb16(pb, 0);
184  }
185 
186  if (enc->codec_tag == MKTAG('Q','D','M','2') && enc->extradata_size) {
187  ffio_wfourcc(pb, "wave");
188  avio_wb32(pb, enc->extradata_size);
189  avio_write(pb, enc->extradata, enc->extradata_size);
190  }
191 
192  /* Sound data chunk */
193  ffio_wfourcc(pb, "SSND");
194  aiff->ssnd = avio_tell(pb); /* Sound chunk size */
195  avio_wb32(pb, 0); /* Sound samples data size */
196  avio_wb32(pb, 0); /* Data offset */
197  avio_wb32(pb, 0); /* Block-size (block align) */
198 
201 
202  /* Data is starting here */
203  avio_flush(pb);
204 
205  return 0;
206 }
207 
209 {
210  AIFFOutputContext *aiff = s->priv_data;
211  AVIOContext *pb = s->pb;
212  if (pkt->stream_index == aiff->audio_stream_idx)
213  avio_write(pb, pkt->data, pkt->size);
214  else {
215  int ret;
216  AVPacketList *pict_list, *last;
217 
219  return 0;
220 
221  /* warn only once for each stream */
222  if (s->streams[pkt->stream_index]->nb_frames == 1) {
223  av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
224  " ignoring.\n", pkt->stream_index);
225  }
226  if (s->streams[pkt->stream_index]->nb_frames >= 1)
227  return 0;
228 
229  pict_list = av_mallocz(sizeof(AVPacketList));
230  if (!pict_list)
231  return AVERROR(ENOMEM);
232 
233  if ((ret = av_copy_packet(&pict_list->pkt, pkt)) < 0) {
234  av_freep(&pict_list);
235  return ret;
236  }
237 
238  if (!aiff->pict_list)
239  aiff->pict_list = pict_list;
240  else {
241  last = aiff->pict_list;
242  while (last->next)
243  last = last->next;
244  last->next = pict_list;
245  }
246  }
247 
248  return 0;
249 }
250 
252 {
253  int ret;
254  AVIOContext *pb = s->pb;
255  AIFFOutputContext *aiff = s->priv_data;
256  AVPacketList *pict_list = aiff->pict_list;
257  AVCodecContext *enc = s->streams[aiff->audio_stream_idx]->codec;
258 
259  /* Chunks sizes must be even */
260  int64_t file_size, end_size;
261  end_size = file_size = avio_tell(pb);
262  if (file_size & 1) {
263  avio_w8(pb, 0);
264  end_size++;
265  }
266 
267  if (s->pb->seekable) {
268  /* Number of sample frames */
269  avio_seek(pb, aiff->frames, SEEK_SET);
270  avio_wb32(pb, (file_size-aiff->ssnd-12)/enc->block_align);
271 
272  /* Sound Data chunk size */
273  avio_seek(pb, aiff->ssnd, SEEK_SET);
274  avio_wb32(pb, file_size - aiff->ssnd - 4);
275 
276  /* return to the end */
277  avio_seek(pb, end_size, SEEK_SET);
278 
279  /* Write ID3 tags */
280  if (aiff->write_id3v2)
281  if ((ret = put_id3v2_tags(s, aiff)) < 0)
282  return ret;
283 
284  /* File length */
285  file_size = avio_tell(pb);
286  avio_seek(pb, aiff->form, SEEK_SET);
287  avio_wb32(pb, file_size - aiff->form - 4);
288 
289  avio_flush(pb);
290  }
291 
292  while (pict_list) {
293  AVPacketList *next = pict_list->next;
294  av_free_packet(&pict_list->pkt);
295  av_freep(&pict_list);
296  pict_list = next;
297  }
298 
299  return 0;
300 }
301 
302 #define OFFSET(x) offsetof(AIFFOutputContext, x)
303 #define ENC AV_OPT_FLAG_ENCODING_PARAM
304 static const AVOption options[] = {
305  { "write_id3v2", "Enable ID3 tags writing.",
306  OFFSET(write_id3v2), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, ENC },
307  { "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.",
308  OFFSET(id3v2_version), AV_OPT_TYPE_INT, {.i64 = 4}, 3, 4, ENC },
309  { NULL },
310 };
311 
312 static const AVClass aiff_muxer_class = {
313  .class_name = "AIFF muxer",
314  .item_name = av_default_item_name,
315  .option = options,
316  .version = LIBAVUTIL_VERSION_INT,
317 };
318 
320  .name = "aiff",
321  .long_name = NULL_IF_CONFIG_SMALL("Audio IFF"),
322  .mime_type = "audio/aiff",
323  .extensions = "aif,aiff,afc,aifc",
324  .priv_data_size = sizeof(AIFFOutputContext),
325  .audio_codec = AV_CODEC_ID_PCM_S16BE,
326  .video_codec = AV_CODEC_ID_PNG,
330  .codec_tag = (const AVCodecTag* const []){ ff_codec_aiff_tags, 0 },
331  .priv_class = &aiff_muxer_class,
332 };
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:361
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
const char * s
Definition: avisynth_c.h:668
Bytestream IO Context.
Definition: avio.h:68
void av_free_packet(AVPacket *pkt)
Free a packet.
Definition: avpacket.c:242
AVOption.
Definition: opt.h:251
void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version, const char *magic)
Initialize an ID3v2 tag.
Definition: id3v2enc.c:151
av_default_item_name
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
static int write_packet(AVFormatContext *s, AVPacket *pkt)
static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: aiffenc.c:208
#define ID3v2_DEFAULT_MAGIC
Default magic bytes for ID3v2 header: "ID3".
Definition: id3v2.h:35
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:199
int av_copy_packet(AVPacket *dst, AVPacket *src)
Copy packet, including contents.
Definition: avpacket.c:236
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
Definition: intfloat.h:70
AVDictionaryEntry * av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:39
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs...
#define FFALIGN(x, a)
Definition: common.h:63
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
Format I/O context.
Definition: avformat.h:944
#define ENC
Definition: aiffenc.c:303
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:55
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:291
AVOptions.
AVPacket pkt
Definition: avformat.h:1280
static AVPacket pkt
Definition: demuxing.c:56
end end
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
AVStream ** streams
Definition: avformat.h:992
uint8_t * data
uint32_t tag
Definition: movenc.c:894
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:248
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:173
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:50
static int write_trailer(AVFormatContext *s)
int audio_stream_idx
Definition: aiffenc.c:36
int64_t frames
Definition: aiffenc.c:34
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
AVDictionary * metadata
Definition: avformat.h:1092
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static const AVOption options[]
Definition: aiffenc.c:304
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb)
Finalize an opened ID3v2 tag.
Definition: id3v2enc.c:264
int size
uint64_t channel_layout
Audio channel layout.
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
unsigned int nb_streams
A list of all streams in the file.
Definition: avformat.h:991
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:117
int void avio_flush(AVIOContext *s)
Force flushing of buffered data to the output s.
Definition: aviobuf.c:193
int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
Convert and write all global metadata from s into an ID3v2 tag.
Definition: id3v2enc.c:165
ret
Definition: avfilter.c:821
const char * name
Definition: avformat.h:378
static int aiff_write_trailer(AVFormatContext *s)
Definition: aiffenc.c:251
AVPacketList * pict_list
Definition: aiffenc.c:37
static int put_id3v2_tags(AVFormatContext *s, AIFFOutputContext *aiff)
Definition: aiffenc.c:42
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
Stream structure.
Definition: avformat.h:643
NULL
Definition: eval.c:55
sample_rate
int64_t ssnd
Definition: aiffenc.c:35
enum AVMediaType codec_type
enum AVCodecID codec_id
int sample_rate
samples per second
AVIOContext * pb
I/O context.
Definition: avformat.h:977
#define OFFSET(x)
Definition: aiffenc.c:302
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:151
main external API structure.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> (&#39;D&#39;<<24) + (&#39;C&#39;<<16) + (&#39;B&#39;<<8) + &#39;A&#39;).
Describe the class of an AVClass context structure.
Definition: log.h:50
synthesis window for stochastic i
static int aiff_write_header(AVFormatContext *s)
Definition: aiffenc.c:99
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:373
int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt)
Write an attached picture from pkt into an ID3v2 tag.
Definition: id3v2enc.c:199
void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout)
Definition: isom.c:552
Main libavformat public API header.
static void put_meta(AVFormatContext *s, const char *key, uint32_t id)
Definition: aiffenc.c:83
struct AVPacketList * next
Definition: avformat.h:1281
static const AVCodecTag ff_codec_aiff_tags[]
Definition: aiff.h:33
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:698
char * value
Definition: dict.h:82
int channels
number of audio channels
void * priv_data
Format private data.
Definition: avformat.h:964
static const AVClass aiff_muxer_class
Definition: aiffenc.c:312
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:470
common header for AIFF muxer and demuxer
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:299
#define MKTAG(a, b, c, d)
Definition: common.h:282
This structure stores compressed data.
int64_t form
Definition: aiffenc.c:33
AVOutputFormat ff_aiff_muxer
Definition: aiffenc.c:319