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
int
ret
;
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
ret =
av_new_packet
(pkt, size);
89
if
(ret < 0)
90
return
ret
;
91
av_fifo_generic_read
(aic->
fifo
, pkt->
data
, size,
NULL
);
92
93
pkt->
dts
= pkt->
pts
= aic->
dts
;
94
pkt->
duration
=
av_rescale_q
(*aic->
samples
, st->
time_base
, aic->
time_base
);
95
pkt->
stream_index
= stream_index;
96
aic->
dts
+= pkt->
duration
;
97
98
aic->
samples
++;
99
if
(!*aic->
samples
)
100
aic->
samples
= aic->
samples_per_frame
;
101
102
return
size
;
103
}
104
105
int
ff_audio_rechunk_interleave
(
AVFormatContext
*
s
,
AVPacket
*
out
,
AVPacket
*
pkt
,
int
flush
,
106
int
(*
get_packet
)(
AVFormatContext
*,
AVPacket
*,
AVPacket
*,
int
),
107
int
(*compare_ts)(
AVFormatContext
*,
AVPacket
*,
AVPacket
*))
108
{
109
int
i,
ret
;
110
111
if
(pkt) {
112
AVStream
*st = s->
streams
[pkt->
stream_index
];
113
AudioInterleaveContext
*aic = st->
priv_data
;
114
if
(st->
codec
->
codec_type
==
AVMEDIA_TYPE_AUDIO
) {
115
unsigned
new_size =
av_fifo_size
(aic->
fifo
) + pkt->
size
;
116
if
(new_size > aic->
fifo_size
) {
117
if
(
av_fifo_realloc2
(aic->
fifo
, new_size) < 0)
118
return
AVERROR
(ENOMEM);
119
aic->
fifo_size
= new_size;
120
}
121
av_fifo_generic_write
(aic->
fifo
, pkt->
data
, pkt->
size
,
NULL
);
122
}
else
{
123
// rewrite pts and dts to be decoded time line position
124
pkt->
pts
= pkt->
dts
= aic->
dts
;
125
aic->
dts
+= pkt->
duration
;
126
if
((ret =
ff_interleave_add_packet
(s, pkt, compare_ts)) < 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
while
((ret =
interleave_new_audio_packet
(s, &new_pkt, i, flush)) > 0) {
137
if
((ret =
ff_interleave_add_packet
(s, &new_pkt, compare_ts)) < 0)
138
return
ret
;
139
}
140
if
(ret < 0)
141
return
ret
;
142
}
143
}
144
145
return
get_packet
(s, out,
NULL
, flush);
146
}
Generated on Sun Mar 8 2015 02:35:08 for FFmpeg by
1.8.2