FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
•
All
Data Structures
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
ff_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 =
ff_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 May 25 2013 03:58:46 for FFmpeg by
1.8.2