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