Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
ea6be118
Commit
ea6be118
authored
Jan 07, 2012
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Factorized the Filter() function of motiondetect.
parent
76821fb1
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
80 additions
and
118 deletions
+80
-118
modules/video_filter/motiondetect.c
modules/video_filter/motiondetect.c
+80
-118
No files found.
modules/video_filter/motiondetect.c
View file @
ea6be118
...
@@ -60,7 +60,6 @@ vlc_module_end ()
...
@@ -60,7 +60,6 @@ vlc_module_end ()
* Local prototypes
* Local prototypes
*****************************************************************************/
*****************************************************************************/
static
picture_t
*
Filter
(
filter_t
*
,
picture_t
*
);
static
picture_t
*
Filter
(
filter_t
*
,
picture_t
*
);
static
picture_t
*
FilterPacked
(
filter_t
*
,
picture_t
*
);
static
void
GaussianConvolution
(
uint32_t
*
,
uint32_t
*
,
int
,
int
,
int
);
static
void
GaussianConvolution
(
uint32_t
*
,
uint32_t
*
,
int
,
int
,
int
);
static
int
FindShapes
(
uint32_t
*
,
uint32_t
*
,
int
,
int
,
int
,
static
int
FindShapes
(
uint32_t
*
,
uint32_t
*
,
int
,
int
,
int
,
int
*
,
int
*
,
int
*
,
int
*
,
int
*
);
int
*
,
int
*
,
int
*
,
int
*
,
int
*
);
...
@@ -69,6 +68,7 @@ static void Draw( filter_t *p_filter, uint8_t *p_pix, int i_pix_pitch, int i_pix
...
@@ -69,6 +68,7 @@ static void Draw( filter_t *p_filter, uint8_t *p_pix, int i_pix_pitch, int i_pix
struct
filter_sys_t
struct
filter_sys_t
{
{
bool
is_yuv_planar
;
bool
b_old
;
bool
b_old
;
picture_t
*
p_old
;
picture_t
*
p_old
;
uint32_t
*
p_buf
;
uint32_t
*
p_buf
;
...
@@ -91,15 +91,16 @@ static int Create( vlc_object_t *p_this )
...
@@ -91,15 +91,16 @@ static int Create( vlc_object_t *p_this )
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
const
video_format_t
*
p_fmt
=
&
p_filter
->
fmt_in
.
video
;
const
video_format_t
*
p_fmt
=
&
p_filter
->
fmt_in
.
video
;
filter_sys_t
*
p_sys
;
filter_sys_t
*
p_sys
;
bool
is_yuv_planar
;
switch
(
p_fmt
->
i_chroma
)
switch
(
p_fmt
->
i_chroma
)
{
{
CASE_PLANAR_YUV
CASE_PLANAR_YUV
p_filter
->
pf_video_filter
=
Filter
;
is_yuv_planar
=
true
;
break
;
break
;
CASE_PACKED_YUV_422
CASE_PACKED_YUV_422
p_filter
->
pf_video_filter
=
FilterPacked
;
is_yuv_planar
=
false
;
break
;
break
;
default:
default:
...
@@ -107,12 +108,14 @@ static int Create( vlc_object_t *p_this )
...
@@ -107,12 +108,14 @@ static int Create( vlc_object_t *p_this )
(
char
*
)
&
(
p_fmt
->
i_chroma
)
);
(
char
*
)
&
(
p_fmt
->
i_chroma
)
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
p_filter
->
pf_video_filter
=
Filter
;
/* Allocate structure */
/* Allocate structure */
p_filter
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
filter_sys_t
)
);
p_filter
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
filter_sys_t
)
);
if
(
p_filter
->
p_sys
==
NULL
)
if
(
p_filter
->
p_sys
==
NULL
)
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
p_sys
->
is_yuv_planar
=
is_yuv_planar
;
p_sys
->
b_old
=
false
;
p_sys
->
b_old
=
false
;
p_sys
->
p_old
=
picture_NewFromFormat
(
p_fmt
);
p_sys
->
p_old
=
picture_NewFromFormat
(
p_fmt
);
p_sys
->
p_buf
=
calloc
(
p_fmt
->
i_width
*
p_fmt
->
i_height
,
sizeof
(
*
p_sys
->
p_buf
)
);
p_sys
->
p_buf
=
calloc
(
p_fmt
->
i_width
*
p_fmt
->
i_height
,
sizeof
(
*
p_sys
->
p_buf
)
);
...
@@ -146,51 +149,26 @@ static void Destroy( vlc_object_t *p_this )
...
@@ -146,51 +149,26 @@ static void Destroy( vlc_object_t *p_this )
/*****************************************************************************
/*****************************************************************************
* Filter YUV Planar
* Filter YUV Planar
/Packed
*****************************************************************************/
*****************************************************************************/
static
picture_t
*
Filte
r
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
)
static
void
PreparePlana
r
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
)
{
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
const
video_format_t
*
p_fmt
=
&
p_filter
->
fmt_in
.
video
;
const
video_format_t
*
p_fmt
=
&
p_filter
->
fmt_in
.
video
;
picture_t
*
p_outpic
;
uint8_t
*
p_oldpix
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
p_pixels
;
uint8_t
*
p_oldpix
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
p_pixels
;
const
int
i_old_pitch
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
i_pitch
;
const
int
i_old_pitch
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
i_pitch
;
uint32_t
*
p_buf
=
p_sys
->
p_buf
;
uint32_t
*
p_buf2
=
p_sys
->
p_buf2
;
unsigned
x
,
y
;
if
(
!
p_inpic
)
return
NULL
;
const
uint8_t
*
p_inpix
=
p_inpic
->
p
[
Y_PLANE
].
p_pixels
;
const
uint8_t
*
p_inpix
=
p_inpic
->
p
[
Y_PLANE
].
p_pixels
;
const
int
i_src_pitch
=
p_inpic
->
p
[
Y_PLANE
].
i_pitch
;
const
int
i_src_pitch
=
p_inpic
->
p
[
Y_PLANE
].
i_pitch
;
p_outpic
=
filter_NewPicture
(
p_filter
);
if
(
!
p_outpic
)
{
picture_Release
(
p_inpic
);
return
NULL
;
}
picture_Copy
(
p_outpic
,
p_inpic
);
if
(
!
p_sys
->
b_old
)
{
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
picture_Release
(
p_inpic
);
p_sys
->
b_old
=
true
;
return
p_outpic
;
}
/**
/**
* Substract Y planes
* Substract Y planes
*/
*/
for
(
y
=
0
;
y
<
p_fmt
->
i_height
;
y
++
)
for
(
unsigned
y
=
0
;
y
<
p_fmt
->
i_height
;
y
++
)
{
{
for
(
x
=
0
;
x
<
p_fmt
->
i_width
;
x
++
)
for
(
unsigned
x
=
0
;
x
<
p_fmt
->
i_width
;
x
++
)
p_buf2
[
y
*
p_fmt
->
i_width
+
x
]
=
abs
(
p_inpix
[
y
*
i_src_pitch
+
x
]
-
p_oldpix
[
y
*
i_old_pitch
+
x
]
);
p_
sys
->
p_
buf2
[
y
*
p_fmt
->
i_width
+
x
]
=
abs
(
p_inpix
[
y
*
i_src_pitch
+
x
]
-
p_oldpix
[
y
*
i_old_pitch
+
x
]
);
}
}
int
i_chroma_dx
;
int
i_chroma_dx
;
...
@@ -212,13 +190,9 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
...
@@ -212,13 +190,9 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
default:
default:
msg_Warn
(
p_filter
,
"Not taking chroma into account"
);
msg_Warn
(
p_filter
,
"Not taking chroma into account"
);
i_chroma_dx
=
0
;
return
;
i_chroma_dy
=
0
;
break
;
}
}
if
(
i_chroma_dx
!=
0
&&
i_chroma_dy
!=
0
)
{
const
uint8_t
*
p_inpix_u
=
p_inpic
->
p
[
U_PLANE
].
p_pixels
;
const
uint8_t
*
p_inpix_u
=
p_inpic
->
p
[
U_PLANE
].
p_pixels
;
const
uint8_t
*
p_inpix_v
=
p_inpic
->
p
[
V_PLANE
].
p_pixels
;
const
uint8_t
*
p_inpix_v
=
p_inpic
->
p
[
V_PLANE
].
p_pixels
;
const
int
i_src_pitch_u
=
p_inpic
->
p
[
U_PLANE
].
i_pitch
;
const
int
i_src_pitch_u
=
p_inpic
->
p
[
U_PLANE
].
i_pitch
;
...
@@ -229,9 +203,9 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
...
@@ -229,9 +203,9 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
const
int
i_old_pitch_u
=
p_sys
->
p_old
->
p
[
U_PLANE
].
i_pitch
;
const
int
i_old_pitch_u
=
p_sys
->
p_old
->
p
[
U_PLANE
].
i_pitch
;
const
int
i_old_pitch_v
=
p_sys
->
p_old
->
p
[
V_PLANE
].
i_pitch
;
const
int
i_old_pitch_v
=
p_sys
->
p_old
->
p
[
V_PLANE
].
i_pitch
;
for
(
y
=
0
;
y
<
p_fmt
->
i_height
/
i_chroma_dy
;
y
++
)
for
(
unsigned
y
=
0
;
y
<
p_fmt
->
i_height
/
i_chroma_dy
;
y
++
)
{
{
for
(
x
=
0
;
x
<
p_fmt
->
i_width
/
i_chroma_dx
;
x
++
)
for
(
unsigned
x
=
0
;
x
<
p_fmt
->
i_width
/
i_chroma_dx
;
x
++
)
{
{
const
int
d
=
abs
(
p_inpix_u
[
y
*
i_src_pitch_u
+
x
]
-
p_oldpix_u
[
y
*
i_old_pitch_u
+
x
]
)
+
const
int
d
=
abs
(
p_inpix_u
[
y
*
i_src_pitch_u
+
x
]
-
p_oldpix_u
[
y
*
i_old_pitch_u
+
x
]
)
+
abs
(
p_inpix_v
[
y
*
i_src_pitch_v
+
x
]
-
p_oldpix_v
[
y
*
i_old_pitch_v
+
x
]
);
abs
(
p_inpix_v
[
y
*
i_src_pitch_v
+
x
]
-
p_oldpix_v
[
y
*
i_old_pitch_v
+
x
]
);
...
@@ -240,57 +214,58 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
...
@@ -240,57 +214,58 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
for
(
j
=
0
;
j
<
i_chroma_dy
;
j
++
)
for
(
j
=
0
;
j
<
i_chroma_dy
;
j
++
)
{
{
for
(
i
=
0
;
i
<
i_chroma_dx
;
i
++
)
for
(
i
=
0
;
i
<
i_chroma_dx
;
i
++
)
p_buf2
[
i_chroma_dy
*
p_fmt
->
i_width
*
j
+
i_chroma_dx
*
i
]
=
d
;
p_sys
->
p_buf2
[
i_chroma_dy
*
p_fmt
->
i_width
*
j
+
i_chroma_dx
*
i
]
=
d
;
}
}
}
}
}
}
}
/**
* Get the areas where movement was detected
*/
p_sys
->
i_colors
=
FindShapes
(
p_buf2
,
p_buf
,
p_fmt
->
i_width
,
p_fmt
->
i_width
,
p_fmt
->
i_height
,
p_sys
->
colors
,
p_sys
->
color_x_min
,
p_sys
->
color_x_max
,
p_sys
->
color_y_min
,
p_sys
->
color_y_max
);
/**
* Count final number of shapes
* Draw rectangles (there can be more than 1 moving shape in 1 rectangle)
*/
Draw
(
p_filter
,
p_outpic
->
p
[
Y_PLANE
].
p_pixels
,
p_outpic
->
p
[
Y_PLANE
].
i_pitch
,
1
);
/**
* We're done. Lets keep a copy of the picture
* TODO we may just picture_Release with a latency of 1 if the filters/vout
* handle it correctly */
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
picture_Release
(
p_inpic
);
return
p_outpic
;
}
}
/*****************************************************************************
static
int
PreparePacked
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
,
int
*
pi_pix_offset
)
* Filter YUV Packed
*****************************************************************************/
static
picture_t
*
FilterPacked
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
)
{
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
const
video_format_t
*
p_fmt
=
&
p_filter
->
fmt_in
.
video
;
const
video_format_t
*
p_fmt
=
&
p_filter
->
fmt_in
.
video
;
picture_t
*
p_outpic
;
int
i_y_offset
,
i_u_offset
,
i_v_offset
;
if
(
GetPackedYuvOffsets
(
p_fmt
->
i_chroma
,
&
i_y_offset
,
&
i_u_offset
,
&
i_v_offset
)
)
{
msg_Warn
(
p_filter
,
"Unsupported input chroma (%4.4s)"
,
(
char
*
)
&
p_fmt
->
i_chroma
);
return
VLC_EGENERIC
;
}
*
pi_pix_offset
=
i_y_offset
;
/* Substract all planes at once */
uint8_t
*
p_oldpix
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
p_pixels
;
uint8_t
*
p_oldpix
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
p_pixels
;
const
int
i_old_pitch
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
i_pitch
;
const
int
i_old_pitch
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
i_pitch
;
uint32_t
*
p_buf
=
p_sys
->
p_buf
;
uint32_t
*
p_buf2
=
p_sys
->
p_buf2
;
unsigned
x
,
y
;
const
uint8_t
*
p_inpix
=
p_inpic
->
p
[
Y_PLANE
].
p_pixels
;
const
int
i_src_pitch
=
p_inpic
->
p
[
Y_PLANE
].
i_pitch
;
for
(
unsigned
y
=
0
;
y
<
p_fmt
->
i_height
;
y
++
)
{
for
(
unsigned
x
=
0
;
x
<
p_fmt
->
i_width
;
x
+=
2
)
{
int
d
;
d
=
abs
(
p_inpix
[
y
*
i_src_pitch
+
2
*
x
+
i_u_offset
]
-
p_oldpix
[
y
*
i_old_pitch
+
2
*
x
+
i_u_offset
]
)
+
abs
(
p_inpix
[
y
*
i_src_pitch
+
2
*
x
+
i_v_offset
]
-
p_oldpix
[
y
*
i_old_pitch
+
2
*
x
+
i_v_offset
]
);
for
(
int
i
=
0
;
i
<
2
;
i
++
)
p_sys
->
p_buf2
[
y
*
p_fmt
->
i_width
+
x
+
i
]
=
abs
(
p_inpix
[
y
*
i_src_pitch
+
2
*
(
x
+
i
)
+
i_y_offset
]
-
p_oldpix
[
y
*
i_old_pitch
+
2
*
(
x
+
i
)
+
i_y_offset
]
)
+
d
;
}
}
return
VLC_SUCCESS
;
}
static
picture_t
*
Filter
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
!
p_inpic
)
if
(
!
p_inpic
)
return
NULL
;
return
NULL
;
const
uint8_t
*
p_inpix
=
p_inpic
->
p
[
Y_PLANE
].
p_pixels
;
picture_t
*
p_outpic
=
filter_NewPicture
(
p_filter
);
const
int
i_src_pitch
=
p_inpic
->
p
[
Y_PLANE
].
i_pitch
;
p_outpic
=
filter_NewPicture
(
p_filter
);
if
(
!
p_outpic
)
if
(
!
p_outpic
)
{
{
picture_Release
(
p_inpic
);
picture_Release
(
p_inpic
);
...
@@ -301,50 +276,37 @@ static picture_t *FilterPacked( filter_t *p_filter, picture_t *p_inpic )
...
@@ -301,50 +276,37 @@ static picture_t *FilterPacked( filter_t *p_filter, picture_t *p_inpic )
if
(
!
p_sys
->
b_old
)
if
(
!
p_sys
->
b_old
)
{
{
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
picture_Release
(
p_inpic
);
p_sys
->
b_old
=
true
;
p_sys
->
b_old
=
true
;
return
p_outpic
;
goto
exit
;
}
}
int
i_
y_offset
,
i_u_offset
,
i_v
_offset
;
int
i_
pix
_offset
;
i
f
(
GetPackedYuvOffsets
(
p_fmt
->
i_chroma
,
i
nt
i_pix_size
;
&
i_y_offset
,
&
i_u_offset
,
&
i_v_offset
)
)
if
(
p_sys
->
is_yuv_planar
)
{
{
msg_Warn
(
p_filter
,
"Unsupported input chroma (%4.4s)"
,
PreparePlanar
(
p_filter
,
p_inpic
);
(
char
*
)
&
p_fmt
->
i_chroma
);
i_pix_offset
=
0
;
picture_Release
(
p_inpic
);
i_pix_size
=
1
;
return
p_outpic
;
}
}
else
/* Substract all planes at once */
for
(
y
=
0
;
y
<
p_fmt
->
i_height
;
y
++
)
{
for
(
x
=
0
;
x
<
p_fmt
->
i_width
;
x
+=
2
)
{
{
int
i
;
if
(
PreparePacked
(
p_filter
,
p_inpic
,
&
i_pix_offset
)
)
int
d
;
goto
exit
;
i_pix_size
=
2
;
d
=
abs
(
p_inpix
[
y
*
i_src_pitch
+
2
*
x
+
i_u_offset
]
-
p_oldpix
[
y
*
i_old_pitch
+
2
*
x
+
i_u_offset
]
)
+
abs
(
p_inpix
[
y
*
i_src_pitch
+
2
*
x
+
i_v_offset
]
-
p_oldpix
[
y
*
i_old_pitch
+
2
*
x
+
i_v_offset
]
);
for
(
i
=
0
;
i
<
2
;
i
++
)
p_buf2
[
y
*
p_fmt
->
i_width
+
x
+
i
]
=
abs
(
p_inpix
[
y
*
i_src_pitch
+
2
*
(
x
+
i
)
+
i_y_offset
]
-
p_oldpix
[
y
*
i_old_pitch
+
2
*
(
x
+
i
)
+
i_y_offset
]
)
+
d
;
}
}
}
/**
/**
* Get the areas where movement was detected
* Get the areas where movement was detected
*/
*/
p_sys
->
i_colors
=
FindShapes
(
p_buf2
,
p_buf
,
p_fmt
->
i_width
,
p_fmt
->
i_width
,
p_fmt
->
i_height
,
const
video_format_t
*
p_fmt
=
&
p_filter
->
fmt_in
.
video
;
p_sys
->
i_colors
=
FindShapes
(
p_sys
->
p_buf2
,
p_sys
->
p_buf
,
p_fmt
->
i_width
,
p_fmt
->
i_width
,
p_fmt
->
i_height
,
p_sys
->
colors
,
p_sys
->
color_x_min
,
p_sys
->
color_x_max
,
p_sys
->
color_y_min
,
p_sys
->
color_y_max
);
p_sys
->
colors
,
p_sys
->
color_x_min
,
p_sys
->
color_x_max
,
p_sys
->
color_y_min
,
p_sys
->
color_y_max
);
/**
/**
* Count final number of shapes
* Count final number of shapes
* Draw rectangles (there can be more than 1 moving shape in 1 rectangle)
* Draw rectangles (there can be more than 1 moving shape in 1 rectangle)
*/
*/
Draw
(
p_filter
,
&
p_outpic
->
p
[
Y_PLANE
].
p_pixels
[
i_
y_offset
],
p_outpic
->
p
[
Y_PLANE
].
i_pitch
,
2
);
Draw
(
p_filter
,
&
p_outpic
->
p
[
Y_PLANE
].
p_pixels
[
i_
pix_offset
],
p_outpic
->
p
[
Y_PLANE
].
i_pitch
,
i_pix_size
);
/**
/**
* We're done. Lets keep a copy of the picture
* We're done. Lets keep a copy of the picture
...
@@ -352,12 +314,12 @@ static picture_t *FilterPacked( filter_t *p_filter, picture_t *p_inpic )
...
@@ -352,12 +314,12 @@ static picture_t *FilterPacked( filter_t *p_filter, picture_t *p_inpic )
* handle it correctly */
* handle it correctly */
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
exit:
picture_Release
(
p_inpic
);
picture_Release
(
p_inpic
);
return
p_outpic
;
return
p_outpic
;
}
}
/*****************************************************************************
/*****************************************************************************
* Gaussian Convolution
* Gaussian Convolution
*****************************************************************************
*****************************************************************************
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment