31
31
#include "libavutil/timestamp.h"
32
32
#include "avfilter.h"
33
33
#include "filters.h"
34
+ #include "formats.h"
34
35
#include "video.h"
35
36
36
37
typedef struct BlackDetectContext {
@@ -45,6 +46,7 @@ typedef struct BlackDetectContext {
45
46
double picture_black_ratio_th ;
46
47
double pixel_black_th ;
47
48
unsigned int pixel_black_th_i ;
49
+ int alpha ;
48
50
49
51
unsigned int nb_black_pixels ; ///< number of black pixels counted so far
50
52
AVRational time_base ;
@@ -63,6 +65,7 @@ static const AVOption blackdetect_options[] = {
63
65
{ "pic_th" , "set the picture black ratio threshold" , OFFSET (picture_black_ratio_th ), AV_OPT_TYPE_DOUBLE , {.dbl = .98 }, 0 , 1 , FLAGS },
64
66
{ "pixel_black_th" , "set the pixel black threshold" , OFFSET (pixel_black_th ), AV_OPT_TYPE_DOUBLE , {.dbl = .10 }, 0 , 1 , FLAGS },
65
67
{ "pix_th" , "set the pixel black threshold" , OFFSET (pixel_black_th ), AV_OPT_TYPE_DOUBLE , {.dbl = .10 }, 0 , 1 , FLAGS },
68
+ { "alpha" , "check alpha instead of luma" , OFFSET (alpha ), AV_OPT_TYPE_BOOL , {.i64 = 0 }, 0 , 1 , FLAGS },
66
69
{ NULL }
67
70
};
68
71
@@ -71,11 +74,21 @@ AVFILTER_DEFINE_CLASS(blackdetect);
71
74
#define YUVJ_FORMATS \
72
75
AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P
73
76
77
+ #define YUVA_FORMATS \
78
+ AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, \
79
+ AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, \
80
+ AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, \
81
+ AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16
82
+
74
83
static const enum AVPixelFormat yuvj_formats [] = {
75
84
YUVJ_FORMATS , AV_PIX_FMT_NONE
76
85
};
77
86
78
- static const enum AVPixelFormat pix_fmts [] = {
87
+ static const enum AVPixelFormat yuva_formats [] = {
88
+ YUVA_FORMATS , AV_PIX_FMT_NONE
89
+ };
90
+
91
+ static const enum AVPixelFormat yuv_formats [] = {
79
92
AV_PIX_FMT_GRAY8 ,
80
93
AV_PIX_FMT_YUV410P , AV_PIX_FMT_YUV411P ,
81
94
AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV422P ,
@@ -91,13 +104,23 @@ static const enum AVPixelFormat pix_fmts[] = {
91
104
AV_PIX_FMT_YUV440P12 ,
92
105
AV_PIX_FMT_YUV444P14 , AV_PIX_FMT_YUV422P14 , AV_PIX_FMT_YUV420P14 ,
93
106
AV_PIX_FMT_YUV420P16 , AV_PIX_FMT_YUV422P16 , AV_PIX_FMT_YUV444P16 ,
94
- AV_PIX_FMT_YUVA420P , AV_PIX_FMT_YUVA422P , AV_PIX_FMT_YUVA444P ,
95
- AV_PIX_FMT_YUVA444P9 , AV_PIX_FMT_YUVA444P10 , AV_PIX_FMT_YUVA444P12 , AV_PIX_FMT_YUVA444P16 ,
96
- AV_PIX_FMT_YUVA422P9 , AV_PIX_FMT_YUVA422P10 , AV_PIX_FMT_YUVA422P12 , AV_PIX_FMT_YUVA422P16 ,
97
- AV_PIX_FMT_YUVA420P9 , AV_PIX_FMT_YUVA420P10 , AV_PIX_FMT_YUVA420P16 ,
98
- AV_PIX_FMT_NONE
107
+ YUVA_FORMATS , AV_PIX_FMT_NONE
99
108
};
100
109
110
+ static int query_format (const AVFilterContext * ctx ,
111
+ AVFilterFormatsConfig * * cfg_in ,
112
+ AVFilterFormatsConfig * * cfg_out )
113
+ {
114
+ const BlackDetectContext * s = ctx -> priv ;
115
+ AVFilterFormats * formats ;
116
+ if (s -> alpha )
117
+ formats = ff_make_format_list (yuva_formats );
118
+ else
119
+ formats = ff_make_format_list (yuv_formats );
120
+
121
+ return ff_set_common_formats2 (ctx , cfg_in , cfg_out , formats );
122
+ }
123
+
101
124
static int config_input (AVFilterLink * inlink )
102
125
{
103
126
AVFilterContext * ctx = inlink -> dst ;
@@ -114,9 +137,9 @@ static int config_input(AVFilterLink *inlink)
114
137
return AVERROR (ENOMEM );
115
138
116
139
av_log (s , AV_LOG_VERBOSE ,
117
- "black_min_duration:%s pixel_black_th:%f picture_black_ratio_th:%f\n" ,
140
+ "black_min_duration:%s pixel_black_th:%f picture_black_ratio_th:%f alpha:%d \n" ,
118
141
av_ts2timestr (s -> black_min_duration , & s -> time_base ),
119
- s -> pixel_black_th , s -> picture_black_ratio_th );
142
+ s -> pixel_black_th , s -> picture_black_ratio_th , s -> alpha );
120
143
return 0 ;
121
144
}
122
145
@@ -140,7 +163,8 @@ static int black_counter(AVFilterContext *ctx, void *arg,
140
163
const unsigned int threshold = s -> pixel_black_th_i ;
141
164
unsigned int * counterp = & s -> counter [jobnr ];
142
165
AVFrame * in = arg ;
143
- const int linesize = in -> linesize [0 ];
166
+ const int plane = s -> alpha ? 3 : 0 ;
167
+ const int linesize = in -> linesize [plane ];
144
168
const int w = in -> width ;
145
169
const int h = in -> height ;
146
170
const int start = (h * jobnr ) / nb_jobs ;
@@ -149,15 +173,15 @@ static int black_counter(AVFilterContext *ctx, void *arg,
149
173
unsigned int counter = 0 ;
150
174
151
175
if (s -> depth == 8 ) {
152
- const uint8_t * p = in -> data [0 ] + start * linesize ;
176
+ const uint8_t * p = in -> data [plane ] + start * linesize ;
153
177
154
178
for (int i = 0 ; i < size ; i ++ ) {
155
179
for (int x = 0 ; x < w ; x ++ )
156
180
counter += p [x ] <= threshold ;
157
181
p += linesize ;
158
182
}
159
183
} else {
160
- const uint16_t * p = (const uint16_t * )(in -> data [0 ] + start * linesize );
184
+ const uint16_t * p = (const uint16_t * )(in -> data [plane ] + start * linesize );
161
185
162
186
for (int i = 0 ; i < size ; i ++ ) {
163
187
for (int x = 0 ; x < w ; x ++ )
@@ -180,7 +204,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
180
204
const int max = (1 << s -> depth ) - 1 ;
181
205
const int factor = (1 << (s -> depth - 8 ));
182
206
const int full = picref -> color_range == AVCOL_RANGE_JPEG ||
183
- ff_fmt_is_in (picref -> format , yuvj_formats );
207
+ ff_fmt_is_in (picref -> format , yuvj_formats ) ||
208
+ s -> alpha ;
184
209
185
210
s -> pixel_black_th_i = full ? s -> pixel_black_th * max :
186
211
// luminance_minimum_value + pixel_black_th * luminance_range_size
@@ -252,6 +277,6 @@ const FFFilter ff_vf_blackdetect = {
252
277
.priv_size = sizeof (BlackDetectContext ),
253
278
FILTER_INPUTS (blackdetect_inputs ),
254
279
FILTER_OUTPUTS (ff_video_default_filterpad ),
255
- FILTER_PIXFMTS_ARRAY ( pix_fmts ),
280
+ FILTER_QUERY_FUNC2 ( query_format ),
256
281
.uninit = uninit ,
257
282
};
0 commit comments