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
libavfilter
af_ashowinfo.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2011 Stefano Sabatini
3
*
4
* This file is part of FFmpeg.
5
*
6
* FFmpeg is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* FFmpeg is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with FFmpeg; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20
21
/**
22
* @file
23
* filter for showing textual audio frame information
24
*/
25
26
#include <inttypes.h>
27
#include <stddef.h>
28
29
#include "
libavutil/adler32.h
"
30
#include "
libavutil/attributes.h
"
31
#include "
libavutil/channel_layout.h
"
32
#include "
libavutil/common.h
"
33
#include "
libavutil/downmix_info.h
"
34
#include "
libavutil/intreadwrite.h
"
35
#include "
libavutil/mem.h
"
36
#include "
libavutil/replaygain.h
"
37
#include "
libavutil/timestamp.h
"
38
#include "
libavutil/samplefmt.h
"
39
40
#include "
audio.h
"
41
#include "
avfilter.h
"
42
#include "
internal.h
"
43
44
typedef
struct
AShowInfoContext
{
45
/**
46
* Scratch space for individual plane checksums for planar audio
47
*/
48
uint32_t *
plane_checksums
;
49
}
AShowInfoContext
;
50
51
static
av_cold
void
uninit
(
AVFilterContext
*ctx)
52
{
53
AShowInfoContext
*
s
= ctx->
priv
;
54
av_freep
(&s->
plane_checksums
);
55
}
56
57
static
void
dump_matrixenc
(
AVFilterContext
*ctx,
AVFrameSideData
*sd)
58
{
59
enum
AVMatrixEncoding
enc;
60
61
av_log
(ctx,
AV_LOG_INFO
,
"matrix encoding: "
);
62
63
if
(sd->
size
<
sizeof
(
enum
AVMatrixEncoding
)) {
64
av_log
(ctx,
AV_LOG_INFO
,
"invalid data"
);
65
return
;
66
}
67
68
enc = *(
enum
AVMatrixEncoding
*)sd->
data
;
69
switch (enc) {
70
case
AV_MATRIX_ENCODING_NONE
:
av_log
(ctx,
AV_LOG_INFO
,
"none"
);
break
;
71
case
AV_MATRIX_ENCODING_DOLBY
:
av_log
(ctx,
AV_LOG_INFO
,
"Dolby Surround"
);
break
;
72
case
AV_MATRIX_ENCODING_DPLII
:
av_log
(ctx,
AV_LOG_INFO
,
"Dolby Pro Logic II"
);
break
;
73
case
AV_MATRIX_ENCODING_DPLIIX
:
av_log
(ctx,
AV_LOG_INFO
,
"Dolby Pro Logic IIx"
);
break
;
74
case
AV_MATRIX_ENCODING_DPLIIZ
:
av_log
(ctx,
AV_LOG_INFO
,
"Dolby Pro Logic IIz"
);
break
;
75
case
AV_MATRIX_ENCODING_DOLBYEX
:
av_log
(ctx,
AV_LOG_INFO
,
"Dolby EX"
);
break
;
76
case
AV_MATRIX_ENCODING_DOLBYHEADPHONE
:
av_log
(ctx,
AV_LOG_INFO
,
"Dolby Headphone"
);
break
;
77
default
:
av_log
(ctx,
AV_LOG_WARNING
,
"unknown"
);
break
;
78
}
79
}
80
81
static
void
dump_downmix
(
AVFilterContext
*ctx,
AVFrameSideData
*sd)
82
{
83
AVDownmixInfo
*di;
84
85
av_log
(ctx,
AV_LOG_INFO
,
"downmix: "
);
86
if
(sd->
size
<
sizeof
(*di)) {
87
av_log
(ctx,
AV_LOG_INFO
,
"invalid data"
);
88
return
;
89
}
90
91
di = (
AVDownmixInfo
*)sd->
data
;
92
93
av_log
(ctx,
AV_LOG_INFO
,
"preferred downmix type - "
);
94
switch
(di->
preferred_downmix_type
) {
95
case
AV_DOWNMIX_TYPE_LORO
:
av_log
(ctx,
AV_LOG_INFO
,
"Lo/Ro"
);
break
;
96
case
AV_DOWNMIX_TYPE_LTRT
:
av_log
(ctx,
AV_LOG_INFO
,
"Lt/Rt"
);
break
;
97
case
AV_DOWNMIX_TYPE_DPLII
:
av_log
(ctx,
AV_LOG_INFO
,
"Dolby Pro Logic II"
);
break
;
98
default
:
av_log
(ctx,
AV_LOG_WARNING
,
"unknown"
);
break
;
99
}
100
101
av_log
(ctx,
AV_LOG_INFO
,
" Mix levels: center %f (%f ltrt) - "
102
"surround %f (%f ltrt) - lfe %f"
,
103
di->
center_mix_level
, di->
center_mix_level_ltrt
,
104
di->
surround_mix_level
, di->
surround_mix_level_ltrt
,
105
di->
lfe_mix_level
);
106
}
107
108
static
void
print_gain
(
AVFilterContext
*ctx,
const
char
*str,
int32_t
gain)
109
{
110
av_log
(ctx,
AV_LOG_INFO
,
"%s - "
, str);
111
if
(gain == INT32_MIN)
112
av_log
(ctx,
AV_LOG_INFO
,
"unknown"
);
113
else
114
av_log
(ctx,
AV_LOG_INFO
,
"%f"
, gain / 100000.0f);
115
av_log
(ctx,
AV_LOG_INFO
,
", "
);
116
}
117
118
static
void
print_peak
(
AVFilterContext
*ctx,
const
char
*str, uint32_t peak)
119
{
120
av_log
(ctx,
AV_LOG_INFO
,
"%s - "
, str);
121
if
(!peak)
122
av_log
(ctx,
AV_LOG_INFO
,
"unknown"
);
123
else
124
av_log
(ctx,
AV_LOG_INFO
,
"%f"
, (
float
)peak / UINT32_MAX);
125
av_log
(ctx,
AV_LOG_INFO
,
", "
);
126
}
127
128
static
void
dump_replaygain
(
AVFilterContext
*ctx,
AVFrameSideData
*sd)
129
{
130
AVReplayGain
*rg;
131
132
av_log
(ctx,
AV_LOG_INFO
,
"replaygain: "
);
133
if
(sd->
size
<
sizeof
(*rg)) {
134
av_log
(ctx,
AV_LOG_INFO
,
"invalid data"
);
135
return
;
136
}
137
rg = (
AVReplayGain
*)sd->
data
;
138
139
print_gain
(ctx,
"track gain"
, rg->
track_gain
);
140
print_peak
(ctx,
"track peak"
, rg->
track_peak
);
141
print_gain
(ctx,
"album gain"
, rg->
album_gain
);
142
print_peak
(ctx,
"album peak"
, rg->
album_peak
);
143
}
144
145
static
void
dump_audio_service_type
(
AVFilterContext
*ctx,
AVFrameSideData
*sd)
146
{
147
enum
AVAudioServiceType
*ast;
148
149
av_log
(ctx,
AV_LOG_INFO
,
"audio service type: "
);
150
if
(sd->
size
<
sizeof
(*ast)) {
151
av_log
(ctx,
AV_LOG_INFO
,
"invalid data"
);
152
return
;
153
}
154
ast = (
enum
AVAudioServiceType
*)sd->
data
;
155
switch (*ast) {
156
case
AV_AUDIO_SERVICE_TYPE_MAIN
:
av_log
(ctx,
AV_LOG_INFO
,
"Main Audio Service"
);
break
;
157
case
AV_AUDIO_SERVICE_TYPE_EFFECTS
:
av_log
(ctx,
AV_LOG_INFO
,
"Effects"
);
break
;
158
case
AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED
:
av_log
(ctx,
AV_LOG_INFO
,
"Visually Impaired"
);
break
;
159
case
AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED
:
av_log
(ctx,
AV_LOG_INFO
,
"Hearing Impaired"
);
break
;
160
case
AV_AUDIO_SERVICE_TYPE_DIALOGUE
:
av_log
(ctx,
AV_LOG_INFO
,
"Dialogue"
);
break
;
161
case
AV_AUDIO_SERVICE_TYPE_COMMENTARY
:
av_log
(ctx,
AV_LOG_INFO
,
"Commentary"
);
break
;
162
case
AV_AUDIO_SERVICE_TYPE_EMERGENCY
:
av_log
(ctx,
AV_LOG_INFO
,
"Emergency"
);
break
;
163
case
AV_AUDIO_SERVICE_TYPE_VOICE_OVER
:
av_log
(ctx,
AV_LOG_INFO
,
"Voice Over"
);
break
;
164
case
AV_AUDIO_SERVICE_TYPE_KARAOKE
:
av_log
(ctx,
AV_LOG_INFO
,
"Karaoke"
);
break
;
165
default
:
av_log
(ctx,
AV_LOG_INFO
,
"unknown"
);
break
;
166
}
167
}
168
169
static
void
dump_unknown
(
AVFilterContext
*ctx,
AVFrameSideData
*sd)
170
{
171
av_log
(ctx,
AV_LOG_INFO
,
"unknown side data type: %d, size %d bytes"
, sd->
type
, sd->
size
);
172
}
173
174
static
int
filter_frame
(
AVFilterLink
*inlink,
AVFrame
*
buf
)
175
{
176
AVFilterContext
*ctx = inlink->
dst
;
177
AShowInfoContext
*
s
= ctx->
priv
;
178
char
chlayout_str[128];
179
uint32_t checksum = 0;
180
int
channels = inlink->
channels
;
181
int
planar =
av_sample_fmt_is_planar
(buf->
format
);
182
int
block_align =
av_get_bytes_per_sample
(buf->
format
) * (planar ? 1 : channels);
183
int
data_size = buf->
nb_samples
* block_align;
184
int
planes = planar ? channels : 1;
185
int
i;
186
void
*tmp_ptr =
av_realloc_array
(s->
plane_checksums
, channels,
sizeof
(*s->
plane_checksums
));
187
188
if
(!tmp_ptr)
189
return
AVERROR
(ENOMEM);
190
s->
plane_checksums
= tmp_ptr;
191
192
for
(i = 0; i < planes; i++) {
193
uint8_t
*
data
= buf->
extended_data
[i];
194
195
s->
plane_checksums
[i] =
av_adler32_update
(0, data, data_size);
196
checksum = i ?
av_adler32_update
(checksum, data, data_size) :
197
s->
plane_checksums
[0];
198
}
199
200
av_get_channel_layout_string
(chlayout_str,
sizeof
(chlayout_str), -1,
201
buf->
channel_layout
);
202
203
av_log
(ctx,
AV_LOG_INFO
,
204
"n:%"
PRId64
" pts:%s pts_time:%s pos:%"
PRId64
" "
205
"fmt:%s channels:%d chlayout:%s rate:%d nb_samples:%d "
206
"checksum:%08"
PRIX32
" "
,
207
inlink->
frame_count
,
208
av_ts2str
(buf->
pts
),
av_ts2timestr
(buf->
pts
, &inlink->
time_base
),
209
av_frame_get_pkt_pos
(buf),
210
av_get_sample_fmt_name
(buf->
format
),
av_frame_get_channels
(buf), chlayout_str,
211
buf->
sample_rate
, buf->
nb_samples
,
212
checksum);
213
214
av_log
(ctx,
AV_LOG_INFO
,
"plane_checksums: [ "
);
215
for
(i = 0; i < planes; i++)
216
av_log
(ctx,
AV_LOG_INFO
,
"%08"
PRIX32
" "
, s->
plane_checksums
[i]);
217
av_log
(ctx,
AV_LOG_INFO
,
"]\n"
);
218
219
for
(i = 0; i < buf->
nb_side_data
; i++) {
220
AVFrameSideData
*sd = buf->
side_data
[i];
221
222
av_log
(ctx,
AV_LOG_INFO
,
" side data - "
);
223
switch
(sd->
type
) {
224
case
AV_FRAME_DATA_MATRIXENCODING
:
dump_matrixenc
(ctx, sd);
break
;
225
case
AV_FRAME_DATA_DOWNMIX_INFO
:
dump_downmix
(ctx, sd);
break
;
226
case
AV_FRAME_DATA_REPLAYGAIN
:
dump_replaygain
(ctx, sd);
break
;
227
case
AV_FRAME_DATA_AUDIO_SERVICE_TYPE
:
dump_audio_service_type
(ctx, sd);
break
;
228
default
:
dump_unknown
(ctx, sd);
break
;
229
}
230
231
av_log
(ctx,
AV_LOG_INFO
,
"\n"
);
232
}
233
234
return
ff_filter_frame
(inlink->
dst
->
outputs
[0], buf);
235
}
236
237
static
const
AVFilterPad
inputs
[] = {
238
{
239
.
name
=
"default"
,
240
.type =
AVMEDIA_TYPE_AUDIO
,
241
.filter_frame =
filter_frame
,
242
},
243
{
NULL
}
244
};
245
246
static
const
AVFilterPad
outputs
[] = {
247
{
248
.
name
=
"default"
,
249
.type =
AVMEDIA_TYPE_AUDIO
,
250
},
251
{
NULL
}
252
};
253
254
AVFilter
ff_af_ashowinfo
= {
255
.
name
=
"ashowinfo"
,
256
.description =
NULL_IF_CONFIG_SMALL
(
"Show textual information for each audio frame."
),
257
.priv_size =
sizeof
(
AShowInfoContext
),
258
.
uninit
=
uninit
,
259
.inputs = inputs,
260
.outputs = outputs,
261
};
Generated on Sun Mar 8 2015 02:35:05 for FFmpeg by
1.8.2