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,
ret
;
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
// rewrite pts and dts to be decoded time line position
123
pkt->
pts
= pkt->
dts
= aic->
dts
;
124
aic->
dts
+= pkt->
duration
;
125
if
((ret =
ff_interleave_add_packet
(s, pkt, compare_ts)) < 0)
126
return
ret
;
127
}
128
pkt = NULL;
129
}
130
131
for
(i = 0; i < s->
nb_streams
; i++) {
132
AVStream
*st = s->
streams
[i];
133
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
134
AVPacket
new_pkt;
135
while
((ret =
interleave_new_audio_packet
(s, &new_pkt, i, flush)) > 0) {
136
if
((ret =
ff_interleave_add_packet
(s, &new_pkt, compare_ts)) < 0)
137
return
ret
;
138
}
139
if
(ret < 0)
140
return
ret
;
141
}
142
}
143
144
return
get_packet
(s, out, NULL, flush);
145
}
Generated on Sun Sep 14 2014 18:56:11 for FFmpeg by
1.8.2