FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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 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/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
if
(!time_base.
num
) {
51
av_log
(s,
AV_LOG_ERROR
,
"timebase not set for audio interleave\n"
);
52
return
-1;
53
}
54
for
(i = 0; i < s->
nb_streams
; i++) {
55
AVStream
*st = s->
streams
[i];
56
AudioInterleaveContext
*aic = st->
priv_data
;
57
58
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
59
aic->
sample_size
= (st->
codec
->
channels
*
60
av_get_bits_per_sample
(st->
codec
->
codec_id
)) / 8;
61
if
(!aic->
sample_size
) {
62
av_log
(s,
AV_LOG_ERROR
,
"could not compute sample size\n"
);
63
return
-1;
64
}
65
aic->
samples_per_frame
= samples_per_frame;
66
aic->
samples
= aic->
samples_per_frame
;
67
aic->
time_base
= time_base;
68
69
aic->
fifo_size
= 100* *aic->
samples
;
70
aic->
fifo
=
av_fifo_alloc
(100 * *aic->
samples
);
71
}
72
}
73
74
return
0;
75
}
76
77
static
int
interleave_new_audio_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
,
78
int
stream_index,
int
flush
)
79
{
80
AVStream
*st = s->
streams
[stream_index];
81
AudioInterleaveContext
*aic = st->
priv_data
;
82
83
int
size
=
FFMIN
(
av_fifo_size
(aic->
fifo
), *aic->
samples
* aic->
sample_size
);
84
if
(!size || (!flush && size ==
av_fifo_size
(aic->
fifo
)))
85
return
0;
86
87
if
(
av_new_packet
(pkt, size) < 0)
88
return
AVERROR
(ENOMEM);
89
av_fifo_generic_read
(aic->
fifo
, pkt->
data
, size, NULL);
90
91
pkt->
dts
= pkt->
pts
= aic->
dts
;
92
pkt->
duration
=
av_rescale_q
(*aic->
samples
, st->
time_base
, aic->
time_base
);
93
pkt->
stream_index
= stream_index;
94
aic->
dts
+= pkt->
duration
;
95
96
aic->
samples
++;
97
if
(!*aic->
samples
)
98
aic->
samples
= aic->
samples_per_frame
;
99
100
return
size
;
101
}
102
103
int
ff_audio_rechunk_interleave
(
AVFormatContext
*
s
,
AVPacket
*
out
,
AVPacket
*
pkt
,
int
flush
,
104
int
(*
get_packet
)(
AVFormatContext
*,
AVPacket
*,
AVPacket
*,
int
),
105
int
(*compare_ts)(
AVFormatContext
*,
AVPacket
*,
AVPacket
*))
106
{
107
int
i;
108
109
if
(pkt) {
110
AVStream
*st = s->
streams
[pkt->
stream_index
];
111
AudioInterleaveContext
*aic = st->
priv_data
;
112
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
113
unsigned
new_size =
av_fifo_size
(aic->
fifo
) + pkt->
size
;
114
if
(new_size > aic->
fifo_size
) {
115
if
(
av_fifo_realloc2
(aic->
fifo
, new_size) < 0)
116
return
-1;
117
aic->
fifo_size
= new_size;
118
}
119
av_fifo_generic_write
(aic->
fifo
, pkt->
data
, pkt->
size
, NULL);
120
}
else
{
121
int
ret
;
122
// rewrite pts and dts to be decoded time line position
123
pkt->
pts
= pkt->
dts
= aic->
dts
;
124
aic->
dts
+= pkt->
duration
;
125
ret =
ff_interleave_add_packet
(s, pkt, compare_ts);
126
if
(ret < 0)
127
return
ret
;
128
}
129
pkt = NULL;
130
}
131
132
for
(i = 0; i < s->
nb_streams
; i++) {
133
AVStream
*st = s->
streams
[i];
134
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
135
AVPacket
new_pkt;
136
int
ret
;
137
while
((ret =
interleave_new_audio_packet
(s, &new_pkt, i, flush)) > 0) {
138
ret =
ff_interleave_add_packet
(s, &new_pkt, compare_ts);
139
if
(ret < 0)
140
return
ret
;
141
}
142
if
(ret < 0)
143
return
ret
;
144
}
145
}
146
147
return
get_packet
(s, out, NULL, flush);
148
}
Generated on Sat Jan 25 2014 19:52:02 for FFmpeg by
1.8.2