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