FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavfilter
vf_blackframe.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2010 Stefano Sabatini
3
* Copyright (c) 2006 Ivo van Poorten
4
* Copyright (c) 2006 Julian Hall
5
* Copyright (c) 2002-2003 Brian J. Murrell
6
*
7
* This file is part of FFmpeg.
8
*
9
* FFmpeg is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
13
*
14
* FFmpeg is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License along
20
* with FFmpeg; if not, write to the Free Software Foundation, Inc.,
21
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
*/
23
24
/**
25
* @file
26
* Search for black frames to detect scene transitions.
27
* Ported from MPlayer libmpcodecs/vf_blackframe.c.
28
*/
29
30
#include <stdio.h>
31
#include <inttypes.h>
32
33
#include "
libavutil/internal.h
"
34
#include "
avfilter.h
"
35
#include "
internal.h
"
36
#include "
formats.h
"
37
#include "
internal.h
"
38
#include "
video.h
"
39
40
typedef
struct
{
41
unsigned
int
bamount
;
///< black amount
42
unsigned
int
bthresh
;
///< black threshold
43
unsigned
int
frame
;
///< frame number
44
unsigned
int
nblack
;
///< number of black pixels counted so far
45
unsigned
int
last_keyframe
;
///< frame number of the last received key-frame
46
}
BlackFrameContext
;
47
48
static
int
query_formats
(
AVFilterContext
*ctx)
49
{
50
static
const
enum
AVPixelFormat
pix_fmts[] = {
51
AV_PIX_FMT_YUV410P
,
AV_PIX_FMT_YUV420P
,
AV_PIX_FMT_GRAY8
,
AV_PIX_FMT_NV12
,
52
AV_PIX_FMT_NV21
,
AV_PIX_FMT_YUV444P
,
AV_PIX_FMT_YUV422P
,
AV_PIX_FMT_YUV411P
,
53
AV_PIX_FMT_NONE
54
};
55
56
ff_set_common_formats
(ctx,
ff_make_format_list
(pix_fmts));
57
return
0;
58
}
59
60
static
av_cold
int
init
(
AVFilterContext
*ctx,
const
char
*args)
61
{
62
BlackFrameContext
*blackframe = ctx->
priv
;
63
64
blackframe->
bamount
= 98;
65
blackframe->
bthresh
= 32;
66
blackframe->
nblack
= 0;
67
blackframe->
frame
= 0;
68
blackframe->
last_keyframe
= 0;
69
70
if
(args)
71
sscanf(args,
"%u:%u"
, &blackframe->
bamount
, &blackframe->
bthresh
);
72
73
av_log
(ctx,
AV_LOG_VERBOSE
,
"bamount:%u bthresh:%u\n"
,
74
blackframe->
bamount
, blackframe->
bthresh
);
75
76
if
(blackframe->
bamount
> 100 || blackframe->
bthresh
> 255) {
77
av_log
(ctx,
AV_LOG_ERROR
,
"Too big value for bamount (max is 100) or bthresh (max is 255)\n"
);
78
return
AVERROR
(EINVAL);
79
}
80
81
return
0;
82
}
83
84
static
int
filter_frame
(
AVFilterLink
*inlink,
AVFilterBufferRef
*
frame
)
85
{
86
AVFilterContext
*ctx = inlink->
dst
;
87
BlackFrameContext
*blackframe = ctx->
priv
;
88
int
x, i;
89
int
pblack = 0;
90
uint8_t
*p = frame->
data
[0];
91
92
for
(i = 0; i < frame->
video
->
h
; i++) {
93
for
(x = 0; x < inlink->
w
; x++)
94
blackframe->
nblack
+= p[x] < blackframe->
bthresh
;
95
p += frame->
linesize
[0];
96
}
97
98
if
(frame->
video
->
key_frame
)
99
blackframe->
last_keyframe
= blackframe->
frame
;
100
101
pblack = blackframe->
nblack
* 100 / (inlink->
w
* inlink->
h
);
102
if
(pblack >= blackframe->
bamount
)
103
av_log
(ctx,
AV_LOG_INFO
,
"frame:%u pblack:%u pos:%"
PRId64
" pts:%"
PRId64
" t:%f "
104
"type:%c last_keyframe:%d\n"
,
105
blackframe->
frame
, pblack, frame->
pos
, frame->
pts
,
106
frame->
pts
==
AV_NOPTS_VALUE
? -1 : frame->
pts
*
av_q2d
(inlink->
time_base
),
107
av_get_picture_type_char
(frame->
video
->
pict_type
), blackframe->
last_keyframe
);
108
109
blackframe->
frame
++;
110
blackframe->
nblack
= 0;
111
return
ff_filter_frame
(inlink->
dst
->
outputs
[0], frame);
112
}
113
114
static
const
AVFilterPad
avfilter_vf_blackframe_inputs
[] = {
115
{
116
.
name
=
"default"
,
117
.type =
AVMEDIA_TYPE_VIDEO
,
118
.get_video_buffer =
ff_null_get_video_buffer
,
119
.filter_frame =
filter_frame
,
120
},
121
{
NULL
}
122
};
123
124
static
const
AVFilterPad
avfilter_vf_blackframe_outputs
[] = {
125
{
126
.
name
=
"default"
,
127
.type =
AVMEDIA_TYPE_VIDEO
128
},
129
{
NULL
}
130
};
131
132
AVFilter
avfilter_vf_blackframe
= {
133
.
name
=
"blackframe"
,
134
.description =
NULL_IF_CONFIG_SMALL
(
"Detect frames that are (almost) black."
),
135
136
.priv_size =
sizeof
(
BlackFrameContext
),
137
.
init
=
init
,
138
139
.
query_formats
=
query_formats
,
140
141
.
inputs
= avfilter_vf_blackframe_inputs,
142
143
.
outputs
= avfilter_vf_blackframe_outputs,
144
};
Generated on Sat May 25 2013 04:01:15 for FFmpeg by
1.8.2