Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
audiointerleave.c
Go to the documentation of this file.
1
/*
2
* Audio Interleaving functions
3
*
4
* Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
5
*
6
* This file is part of Libav.
7
*
8
* Libav 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
* Libav 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 Libav; 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/fifo.h
"
24
#include "
libavutil/mathematics.h
"
25
#include "
avformat.h
"
26
#include "
audiointerleave.h
"
27
#include "
internal.h
"
28
29
void
ff_audio_interleave_close
(
AVFormatContext
*s)
30
{
31
int
i;
32
for
(i = 0; i < s->
nb_streams
; i++) {
33
AVStream
*st = s->
streams
[i];
34
AudioInterleaveContext
*aic = st->
priv_data
;
35
36
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
)
37
av_fifo_free
(aic->
fifo
);
38
}
39
}
40
41
int
ff_audio_interleave_init
(
AVFormatContext
*s,
42
const
int
*samples_per_frame,
43
AVRational
time_base)
44
{
45
int
i;
46
47
if
(!samples_per_frame)
48
return
-1;
49
50
for
(i = 0; i < s->
nb_streams
; i++) {
51
AVStream
*st = s->
streams
[i];
52
AudioInterleaveContext
*aic = st->
priv_data
;
53
54
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
55
aic->
sample_size
= (st->
codec
->
channels
*
56
av_get_bits_per_sample
(st->
codec
->
codec_id
)) / 8;
57
if
(!aic->
sample_size
) {
58
av_log
(s,
AV_LOG_ERROR
,
"could not compute sample size\n"
);
59
return
-1;
60
}
61
aic->
samples_per_frame
= samples_per_frame;
62
aic->
samples
= aic->
samples_per_frame
;
63
aic->
time_base
= time_base;
64
65
aic->
fifo_size
= 100* *aic->
samples
;
66
aic->
fifo
=
av_fifo_alloc
(100 * *aic->
samples
);
67
}
68
}
69
70
return
0;
71
}
72
73
static
int
ff_interleave_new_audio_packet
(
AVFormatContext
*s,
AVPacket
*pkt,
74
int
stream_index,
int
flush
)
75
{
76
AVStream
*st = s->
streams
[stream_index];
77
AudioInterleaveContext
*aic = st->
priv_data
;
78
79
int
size
=
FFMIN
(
av_fifo_size
(aic->
fifo
), *aic->
samples
* aic->
sample_size
);
80
if
(!size || (!flush && size ==
av_fifo_size
(aic->
fifo
)))
81
return
0;
82
83
av_new_packet
(pkt, size);
84
av_fifo_generic_read
(aic->
fifo
, pkt->
data
, size,
NULL
);
85
86
pkt->
dts
= pkt->
pts
= aic->
dts
;
87
pkt->
duration
=
av_rescale_q
(*aic->
samples
, st->
time_base
, aic->
time_base
);
88
pkt->
stream_index
= stream_index;
89
aic->
dts
+= pkt->
duration
;
90
91
aic->
samples
++;
92
if
(!*aic->
samples
)
93
aic->
samples
= aic->
samples_per_frame
;
94
95
return
size
;
96
}
97
98
int
ff_audio_rechunk_interleave
(
AVFormatContext
*s,
AVPacket
*out,
AVPacket
*pkt,
int
flush
,
99
int
(*
get_packet
)(
AVFormatContext
*,
AVPacket
*,
AVPacket
*,
int
),
100
int
(*compare_ts)(
AVFormatContext
*,
AVPacket
*,
AVPacket
*))
101
{
102
int
i;
103
104
if
(pkt) {
105
AVStream
*st = s->
streams
[pkt->
stream_index
];
106
AudioInterleaveContext
*aic = st->
priv_data
;
107
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
108
unsigned
new_size =
av_fifo_size
(aic->
fifo
) + pkt->
size
;
109
if
(new_size > aic->
fifo_size
) {
110
if
(
av_fifo_realloc2
(aic->
fifo
, new_size) < 0)
111
return
-1;
112
aic->
fifo_size
= new_size;
113
}
114
av_fifo_generic_write
(aic->
fifo
, pkt->
data
, pkt->
size
,
NULL
);
115
}
else
{
116
// rewrite pts and dts to be decoded time line position
117
pkt->
pts
= pkt->
dts
= aic->
dts
;
118
aic->
dts
+= pkt->
duration
;
119
ff_interleave_add_packet
(s, pkt, compare_ts);
120
}
121
pkt =
NULL
;
122
}
123
124
for
(i = 0; i < s->
nb_streams
; i++) {
125
AVStream
*st = s->
streams
[i];
126
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
127
AVPacket
new_pkt;
128
while
(
ff_interleave_new_audio_packet
(s, &new_pkt, i, flush))
129
ff_interleave_add_packet
(s, &new_pkt, compare_ts);
130
}
131
}
132
133
return
get_packet
(s, out, pkt, flush);
134
}