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_freep
(&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
AVERROR
(EINVAL);
49
50
if
(!time_base.
num
) {
51
av_log
(s,
AV_LOG_ERROR
,
"timebase not set for audio interleave\n"
);
52
return
AVERROR
(EINVAL);
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
AVERROR
(EINVAL);
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
if
(!(aic->
fifo
=
av_fifo_alloc_array
(100, *aic->
samples
)))
71
return
AVERROR
(ENOMEM);
72
}
73
}
74
75
return
0;
76
}
77
78
static
int
interleave_new_audio_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
,
79
int
stream_index,
int
flush
)
80
{
81
AVStream
*st = s->
streams
[stream_index];
82
AudioInterleaveContext
*aic = st->
priv_data
;
83
84
int
size
=
FFMIN
(
av_fifo_size
(aic->
fifo
), *aic->
samples
* aic->
sample_size
);
85
if
(!size || (!flush && size ==
av_fifo_size
(aic->
fifo
)))
86
return
0;
87
88
if
(
av_new_packet
(pkt, size) < 0)
89
return
AVERROR
(ENOMEM);
90
av_fifo_generic_read
(aic->
fifo
, pkt->
data
, size, NULL);
91
92
pkt->
dts
= pkt->
pts
= aic->
dts
;
93
pkt->
duration
=
av_rescale_q
(*aic->
samples
, st->
time_base
, aic->
time_base
);
94
pkt->
stream_index
= stream_index;
95
aic->
dts
+= pkt->
duration
;
96
97
aic->
samples
++;
98
if
(!*aic->
samples
)
99
aic->
samples
= aic->
samples_per_frame
;
100
101
return
size
;
102
}
103
104
int
ff_audio_rechunk_interleave
(
AVFormatContext
*
s
,
AVPacket
*
out
,
AVPacket
*
pkt
,
int
flush
,
105
int
(*
get_packet
)(
AVFormatContext
*,
AVPacket
*,
AVPacket
*,
int
),
106
int
(*compare_ts)(
AVFormatContext
*,
AVPacket
*,
AVPacket
*))
107
{
108
int
i;
109
110
if
(pkt) {
111
AVStream
*st = s->
streams
[pkt->
stream_index
];
112
AudioInterleaveContext
*aic = st->
priv_data
;
113
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
114
unsigned
new_size =
av_fifo_size
(aic->
fifo
) + pkt->
size
;
115
if
(new_size > aic->
fifo_size
) {
116
if
(
av_fifo_realloc2
(aic->
fifo
, new_size) < 0)
117
return
AVERROR
(ENOMEM);
118
aic->
fifo_size
= new_size;
119
}
120
av_fifo_generic_write
(aic->
fifo
, pkt->
data
, pkt->
size
, NULL);
121
}
else
{
122
int
ret
;
123
// rewrite pts and dts to be decoded time line position
124
pkt->
pts
= pkt->
dts
= aic->
dts
;
125
aic->
dts
+= pkt->
duration
;
126
ret =
ff_interleave_add_packet
(s, pkt, compare_ts);
127
if
(ret < 0)
128
return
ret
;
129
}
130
pkt = NULL;
131
}
132
133
for
(i = 0; i < s->
nb_streams
; i++) {
134
AVStream
*st = s->
streams
[i];
135
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
136
AVPacket
new_pkt;
137
int
ret
;
138
while
((ret =
interleave_new_audio_packet
(s, &new_pkt, i, flush)) > 0) {
139
ret =
ff_interleave_add_packet
(s, &new_pkt, compare_ts);
140
if
(ret < 0)
141
return
ret
;
142
}
143
if
(ret < 0)
144
return
ret
;
145
}
146
}
147
148
return
get_packet
(s, out, NULL, flush);
149
}
Generated on Sun Jul 20 2014 23:06:02 for FFmpeg by
1.8.2