Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
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 Libav.
6
*
7
* Libav 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
* Libav 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 Libav; 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 "
avformat.h
"
24
#include "
internal.h
"
25
#include "
aiff.h
"
26
#include "
avio_internal.h
"
27
28
typedef
struct
{
29
int64_t
form
;
30
int64_t
frames
;
31
int64_t
ssnd
;
32
}
AIFFOutputContext
;
33
34
static
int
aiff_write_header
(
AVFormatContext
*s)
35
{
36
AIFFOutputContext
*aiff = s->
priv_data
;
37
AVIOContext
*pb = s->
pb
;
38
AVCodecContext
*enc = s->
streams
[0]->
codec
;
39
uint64_t sample_rate;
40
int
aifc = 0;
41
42
/* First verify if format is ok */
43
if
(!enc->
codec_tag
)
44
return
-1;
45
if
(enc->
codec_tag
!=
MKTAG
(
'N'
,
'O'
,
'N'
,
'E'
))
46
aifc = 1;
47
48
/* FORM AIFF header */
49
ffio_wfourcc
(pb,
"FORM"
);
50
aiff->
form
=
avio_tell
(pb);
51
avio_wb32
(pb, 0);
/* file length */
52
ffio_wfourcc
(pb, aifc ?
"AIFC"
:
"AIFF"
);
53
54
if
(aifc) {
// compressed audio
55
enc->
bits_per_coded_sample
= 16;
56
if
(!enc->
block_align
) {
57
av_log
(s,
AV_LOG_ERROR
,
"block align not set\n"
);
58
return
-1;
59
}
60
/* Version chunk */
61
ffio_wfourcc
(pb,
"FVER"
);
62
avio_wb32
(pb, 4);
63
avio_wb32
(pb, 0xA2805140);
64
}
65
66
/* Common chunk */
67
ffio_wfourcc
(pb,
"COMM"
);
68
avio_wb32
(pb, aifc ? 24 : 18);
/* size */
69
avio_wb16
(pb, enc->
channels
);
/* Number of channels */
70
71
aiff->
frames
=
avio_tell
(pb);
72
avio_wb32
(pb, 0);
/* Number of frames */
73
74
if
(!enc->
bits_per_coded_sample
)
75
enc->
bits_per_coded_sample
=
av_get_bits_per_sample
(enc->
codec_id
);
76
if
(!enc->
bits_per_coded_sample
) {
77
av_log
(s,
AV_LOG_ERROR
,
"could not compute bits per sample\n"
);
78
return
-1;
79
}
80
if
(!enc->
block_align
)
81
enc->
block_align
= (enc->
bits_per_coded_sample
* enc->
channels
) >> 3;
82
83
avio_wb16
(pb, enc->
bits_per_coded_sample
);
/* Sample size */
84
85
sample_rate =
av_double2int
(enc->
sample_rate
);
86
avio_wb16
(pb, (sample_rate >> 52) + (16383 - 1023));
87
avio_wb64
(pb, UINT64_C(1) << 63 | sample_rate << 11);
88
89
if
(aifc) {
90
avio_wl32
(pb, enc->
codec_tag
);
91
avio_wb16
(pb, 0);
92
}
93
94
/* Sound data chunk */
95
ffio_wfourcc
(pb,
"SSND"
);
96
aiff->
ssnd
=
avio_tell
(pb);
/* Sound chunk size */
97
avio_wb32
(pb, 0);
/* Sound samples data size */
98
avio_wb32
(pb, 0);
/* Data offset */
99
avio_wb32
(pb, 0);
/* Block-size (block align) */
100
101
avpriv_set_pts_info
(s->
streams
[0], 64, 1, s->
streams
[0]->
codec
->
sample_rate
);
102
103
/* Data is starting here */
104
avio_flush
(pb);
105
106
return
0;
107
}
108
109
static
int
aiff_write_packet
(
AVFormatContext
*s,
AVPacket
*pkt)
110
{
111
AVIOContext
*pb = s->
pb
;
112
avio_write
(pb, pkt->
data
, pkt->
size
);
113
return
0;
114
}
115
116
static
int
aiff_write_trailer
(
AVFormatContext
*s)
117
{
118
AVIOContext
*pb = s->
pb
;
119
AIFFOutputContext
*aiff = s->
priv_data
;
120
AVCodecContext
*enc = s->
streams
[0]->
codec
;
121
122
/* Chunks sizes must be even */
123
int64_t file_size, end_size;
124
end_size = file_size =
avio_tell
(pb);
125
if
(file_size & 1) {
126
avio_w8
(pb, 0);
127
end_size++;
128
}
129
130
if
(s->
pb
->
seekable
) {
131
/* File length */
132
avio_seek
(pb, aiff->
form
, SEEK_SET);
133
avio_wb32
(pb, file_size - aiff->
form
- 4);
134
135
/* Number of sample frames */
136
avio_seek
(pb, aiff->
frames
, SEEK_SET);
137
avio_wb32
(pb, (file_size-aiff->
ssnd
-12)/enc->
block_align
);
138
139
/* Sound Data chunk size */
140
avio_seek
(pb, aiff->
ssnd
, SEEK_SET);
141
avio_wb32
(pb, file_size - aiff->
ssnd
- 4);
142
143
/* return to the end */
144
avio_seek
(pb, end_size, SEEK_SET);
145
146
avio_flush
(pb);
147
}
148
149
return
0;
150
}
151
152
AVOutputFormat
ff_aiff_muxer
= {
153
.
name
=
"aiff"
,
154
.long_name =
NULL_IF_CONFIG_SMALL
(
"Audio IFF"
),
155
.mime_type =
"audio/aiff"
,
156
.extensions =
"aif,aiff,afc,aifc"
,
157
.priv_data_size =
sizeof
(
AIFFOutputContext
),
158
.audio_codec =
CODEC_ID_PCM_S16BE
,
159
.video_codec =
CODEC_ID_NONE
,
160
.
write_header
=
aiff_write_header
,
161
.
write_packet
=
aiff_write_packet
,
162
.
write_trailer
=
aiff_write_trailer
,
163
.codec_tag= (
const
AVCodecTag
*
const
[]){
ff_codec_aiff_tags
, 0},
164
};