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