Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
Commits
62c57101
Commit
62c57101
authored
Jul 20, 2008
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed motiondetect segfaults.
parent
a4270c7d
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
187 additions
and
294 deletions
+187
-294
modules/video_filter/motiondetect.c
modules/video_filter/motiondetect.c
+187
-294
No files found.
modules/video_filter/motiondetect.c
View file @
62c57101
...
@@ -38,23 +38,11 @@
...
@@ -38,23 +38,11 @@
#include "filter_picture.h"
#include "filter_picture.h"
/*****************************************************************************
/*****************************************************************************
*
Local prototypes
*
Module descriptor
*****************************************************************************/
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
);
static
int
Create
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_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
int
FindShapes
(
uint32_t
*
,
uint32_t
*
,
int
,
int
,
int
,
int
*
,
int
*
,
int
*
,
int
*
,
int
*
);
#define NUM_COLORS 5000
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define FILTER_PREFIX "motiondetect-"
#define FILTER_PREFIX "motiondetect-"
vlc_module_begin
();
vlc_module_begin
();
...
@@ -68,14 +56,32 @@ vlc_module_begin();
...
@@ -68,14 +56,32 @@ vlc_module_begin();
set_callbacks
(
Create
,
Destroy
);
set_callbacks
(
Create
,
Destroy
);
vlc_module_end
();
vlc_module_end
();
/*****************************************************************************
* Local prototypes
*****************************************************************************/
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
int
FindShapes
(
uint32_t
*
,
uint32_t
*
,
int
,
int
,
int
,
int
*
,
int
*
,
int
*
,
int
*
,
int
*
);
static
void
Draw
(
filter_t
*
p_filter
,
uint8_t
*
p_pix
,
int
i_pix_pitch
,
int
i_pix_size
);
#define NUM_COLORS (5000)
struct
filter_sys_t
struct
filter_sys_t
{
{
uint8_t
*
p_oldpix
;
bool
b_old
;
uint8_t
*
p_oldpix_u
;
picture_t
*
p_old
;
uint8_t
*
p_oldpix_v
;
uint32_t
*
p_buf
;
uint32_t
*
p_buf
;
uint32_t
*
p_buf2
;
uint32_t
*
p_buf2
;
vlc_mutex_t
lock
;
/* */
int
i_colors
;
int
colors
[
NUM_COLORS
];
int
color_x_min
[
NUM_COLORS
];
int
color_x_max
[
NUM_COLORS
];
int
color_y_min
[
NUM_COLORS
];
int
color_y_max
[
NUM_COLORS
];
};
};
/*****************************************************************************
/*****************************************************************************
...
@@ -84,8 +90,10 @@ struct filter_sys_t
...
@@ -84,8 +90,10 @@ struct filter_sys_t
static
int
Create
(
vlc_object_t
*
p_this
)
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
;
filter_sys_t
*
p_sys
;
switch
(
p_f
ilter
->
fmt_in
.
video
.
i_chroma
)
switch
(
p_f
mt
->
i_chroma
)
{
{
CASE_PLANAR_YUV
CASE_PLANAR_YUV
p_filter
->
pf_video_filter
=
Filter
;
p_filter
->
pf_video_filter
=
Filter
;
...
@@ -97,19 +105,29 @@ static int Create( vlc_object_t *p_this )
...
@@ -97,19 +105,29 @@ static int Create( vlc_object_t *p_this )
default:
default:
msg_Err
(
p_filter
,
"Unsupported input chroma (%4s)"
,
msg_Err
(
p_filter
,
"Unsupported input chroma (%4s)"
,
(
char
*
)
&
(
p_f
ilter
->
fmt_in
.
video
.
i_chroma
)
);
(
char
*
)
&
(
p_f
mt
->
i_chroma
)
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
/* Allocate structure */
/* Allocate structure */
p_filter
->
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_filter
->
p_sys
->
p_oldpix
=
NULL
;
p_sys
->
b_old
=
false
;
p_filter
->
p_sys
->
p_buf
=
NULL
;
p_sys
->
p_old
=
picture_New
(
p_fmt
->
i_chroma
,
p_fmt
->
i_width
,
p_fmt
->
i_height
,
0
);
p_sys
->
p_buf
=
calloc
(
p_fmt
->
i_width
*
p_fmt
->
i_height
,
sizeof
(
*
p_sys
->
p_buf
)
);
p_sys
->
p_buf2
=
calloc
(
p_fmt
->
i_width
*
p_fmt
->
i_height
,
sizeof
(
*
p_sys
->
p_buf
)
);
vlc_mutex_init
(
&
p_filter
->
p_sys
->
lock
);
if
(
!
p_sys
->
p_old
||
!
p_sys
->
p_buf
||
!
p_sys
->
p_buf2
)
{
free
(
p_sys
->
p_buf2
);
free
(
p_sys
->
p_buf
);
if
(
p_sys
->
p_old
)
picture_Release
(
p_sys
->
p_old
);
return
VLC_ENOMEM
;
}
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
...
@@ -120,13 +138,12 @@ static int Create( vlc_object_t *p_this )
...
@@ -120,13 +138,12 @@ static int Create( vlc_object_t *p_this )
static
void
Destroy
(
vlc_object_t
*
p_this
)
static
void
Destroy
(
vlc_object_t
*
p_this
)
{
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
free
(
p_filter
->
p_sys
->
p_oldpix
);
free
(
p_sys
->
p_buf2
);
free
(
p_filter
->
p_sys
->
p_buf
);
free
(
p_sys
->
p_buf
);
picture_Release
(
p_sys
->
p_old
);
vlc_mutex_destroy
(
&
p_filter
->
p_sys
->
lock
);
free
(
p_sys
);
free
(
p_filter
->
p_sys
);
}
}
...
@@ -135,49 +152,30 @@ static void Destroy( vlc_object_t *p_this )
...
@@ -135,49 +152,30 @@ static void Destroy( vlc_object_t *p_this )
*****************************************************************************/
*****************************************************************************/
static
picture_t
*
Filter
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
)
static
picture_t
*
Filter
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
)
{
{
picture_t
*
p_outpic
;
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
;
picture_t
*
p_outpic
;
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
;
const
int
i_src_visible
=
p_inpic
->
p
[
Y_PLANE
].
i_visible_pitch
;
const
int
i_num_lines
=
p_inpic
->
p
[
Y_PLANE
].
i_visible_lines
;
const
uint8_t
*
p_inpix_u
=
p_inpic
->
p
[
U
_PLANE
].
p_pixels
;
uint8_t
*
p_oldpix
=
p_sys
->
p_old
->
p
[
Y
_PLANE
].
p_pixels
;
const
uint8_t
*
p_inpix_v
=
p_inpic
->
p
[
V_PLANE
].
p_pixels
;
const
int
i_old_pitch
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
i_pitch
;
const
int
i_src_pitch_u
=
p_inpic
->
p
[
U_PLANE
].
i_pitch
;
uint32_t
*
p_buf
=
p_sys
->
p_buf
;
const
int
i_num_lines_u
=
p_inpic
->
p
[
U_PLANE
].
i_visible_lines
;
uint32_t
*
p_buf2
=
p_sys
->
p_buf2
;
uint8_t
*
p_oldpix
;
unsigned
x
,
y
;
uint8_t
*
p_oldpix_u
;
uint8_t
*
p_oldpix_v
;
uint32_t
*
p_buf
;
uint32_t
*
p_buf2
;
int
i
,
j
;
int
last
;
if
(
!
p_inpic
)
return
NULL
;
if
(
!
p_inpic
)
return
NULL
;
if
(
!
p_sys
->
p_oldpix
||
!
p_sys
->
p_buf
)
if
(
!
p_sys
->
b_old
)
{
{
free
(
p_sys
->
p_oldpix
);
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
free
(
p_sys
->
p_buf
);
p_sys
->
b_old
=
true
;
p_sys
->
p_oldpix
=
malloc
(
i_src_pitch
*
i_num_lines
);
p_sys
->
p_oldpix_u
=
malloc
(
i_src_pitch_u
*
i_num_lines_u
);
p_sys
->
p_oldpix_v
=
malloc
(
i_src_pitch_u
*
i_num_lines_u
);
p_sys
->
p_buf
=
malloc
(
sizeof
(
uint32_t
)
*
i_src_pitch
*
i_num_lines
);
p_sys
->
p_buf2
=
malloc
(
sizeof
(
uint32_t
)
*
i_src_pitch
*
i_num_lines
);
vlc_memcpy
(
p_sys
->
p_oldpix
,
p_inpix
,
i_src_pitch
*
i_num_lines
);
vlc_memcpy
(
p_sys
->
p_oldpix_u
,
p_inpix_u
,
i_src_pitch_u
*
i_num_lines_u
);
vlc_memcpy
(
p_sys
->
p_oldpix_v
,
p_inpix_v
,
i_src_pitch_u
*
i_num_lines_u
);
return
p_inpic
;
return
p_inpic
;
}
}
p_oldpix
=
p_sys
->
p_oldpix
;
p_oldpix_u
=
p_sys
->
p_oldpix_u
;
p_oldpix_v
=
p_sys
->
p_oldpix_v
;
p_buf
=
p_sys
->
p_buf
;
p_buf2
=
p_sys
->
p_buf2
;
p_outpic
=
filter_NewPicture
(
p_filter
);
p_outpic
=
filter_NewPicture
(
p_filter
);
if
(
!
p_outpic
)
if
(
!
p_outpic
)
...
@@ -185,84 +183,66 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
...
@@ -185,84 +183,66 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
picture_Release
(
p_inpic
);
picture_Release
(
p_inpic
);
return
NULL
;
return
NULL
;
}
}
picture_Copy
(
p_outpic
,
p_inpic
);
vout_CopyPicture
(
p_filter
,
p_outpic
,
p_inpic
);
vlc_mutex_lock
(
&
p_filter
->
p_sys
->
lock
);
/**
/**
* Substract Y planes
* Substract Y planes
*/
*/
for
(
i
=
0
;
i
<
i_src_pitch
*
i_num_lines
;
i
++
)
for
(
y
=
0
;
y
<
p_fmt
->
i_height
;
y
++
)
{
{
if
(
p_inpix
[
i
]
>
p_oldpix
[
i
]
)
for
(
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_buf2
[
i
]
=
p_inpix
[
i
]
-
p_oldpix
[
i
];
}
else
{
p_buf2
[
i
]
=
p_oldpix
[
i
]
-
p_inpix
[
i
];
}
}
}
int
line
;
int
col
;
int
i_chroma_dx
;
int
format
;
int
i_chroma_dy
;
switch
(
p_inpic
->
format
.
i_chroma
)
switch
(
p_inpic
->
format
.
i_chroma
)
{
{
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
):
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
):
case
VLC_FOURCC
(
'I'
,
'Y'
,
'U'
,
'V'
):
case
VLC_FOURCC
(
'I'
,
'Y'
,
'U'
,
'V'
):
case
VLC_FOURCC
(
'J'
,
'4'
,
'2'
,
'0'
):
case
VLC_FOURCC
(
'J'
,
'4'
,
'2'
,
'0'
):
case
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
):
case
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
):
format
=
1
;
i_chroma_dx
=
2
;
i_chroma_dy
=
2
;
break
;
break
;
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'2'
):
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'2'
):
case
VLC_FOURCC
(
'J'
,
'4'
,
'2'
,
'2'
):
case
VLC_FOURCC
(
'J'
,
'4'
,
'2'
,
'2'
):
format
=
2
;
i_chroma_dx
=
2
;
i_chroma_dy
=
1
;
break
;
break
;
default:
default:
format
=
0
;
msg_Warn
(
p_filter
,
"Not taking chroma into account"
);
msg_Warn
(
p_filter
,
"Not taking chroma into account"
);
i_chroma_dx
=
0
;
i_chroma_dy
=
0
;
break
;
break
;
}
}
if
(
format
)
if
(
i_chroma_dx
!=
0
&&
i_chroma_dy
!=
0
)
{
{
for
(
line
=
0
;
line
<
i_num_lines_u
;
line
++
)
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
int
i_src_pitch_u
=
p_inpic
->
p
[
U_PLANE
].
i_pitch
;
const
int
i_src_pitch_v
=
p_inpic
->
p
[
V_PLANE
].
i_pitch
;
const
uint8_t
*
p_oldpix_u
=
p_sys
->
p_old
->
p
[
U_PLANE
].
p_pixels
;
const
uint8_t
*
p_oldpix_v
=
p_sys
->
p_old
->
p
[
V_PLANE
].
p_pixels
;
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
;
for
(
y
=
0
;
y
<
p_fmt
->
i_height
/
i_chroma_dy
;
y
++
)
{
{
for
(
col
=
0
;
col
<
i_src_pitch_u
;
col
++
)
for
(
x
=
0
;
x
<
p_fmt
->
i_width
/
i_chroma_dx
;
x
++
)
{
{
int
diff
;
const
int
d
=
abs
(
p_inpix_u
[
y
*
i_src_pitch_u
+
x
]
-
p_oldpix_u
[
y
*
i_old_pitch_u
+
x
]
)
+
i
=
line
*
i_src_pitch_u
+
col
;
abs
(
p_inpix_v
[
y
*
i_src_pitch_v
+
x
]
-
p_oldpix_v
[
y
*
i_old_pitch_v
+
x
]
);
if
(
p_inpix_u
[
i
]
>
p_oldpix_u
[
i
]
)
int
i
,
j
;
{
diff
=
p_inpix_u
[
i
]
-
p_oldpix_u
[
i
];
for
(
j
=
0
;
j
<
i_chroma_dy
;
j
++
)
}
else
{
diff
=
p_oldpix_u
[
i
]
-
p_inpix_u
[
i
];
}
if
(
p_inpix_v
[
i
]
>
p_oldpix_v
[
i
]
)
{
diff
+=
p_inpix_v
[
i
]
-
p_oldpix_v
[
i
];
}
else
{
diff
+=
p_oldpix_v
[
i
]
-
p_inpix_v
[
i
];
}
switch
(
format
)
{
{
case
1
:
for
(
i
=
0
;
i
<
i_chroma_dx
;
i
++
)
p_buf2
[
2
*
line
*
i_src_pitch
+
2
*
col
]
+=
diff
;
p_buf2
[
i_chroma_dy
*
p_fmt
->
i_width
*
j
+
i_chroma_dx
*
i
]
=
d
;
p_buf2
[
2
*
line
*
i_src_pitch
+
2
*
col
+
1
]
+=
diff
;
p_buf2
[(
2
*
line
+
1
)
*
i_src_pitch
+
2
*
col
]
+=
diff
;
p_buf2
[(
2
*
line
+
1
)
*
i_src_pitch
+
2
*
col
+
1
]
+=
diff
;
break
;
case
2
:
p_buf2
[
line
*
i_src_pitch
+
2
*
col
]
+=
diff
;
p_buf2
[
line
*
i_src_pitch
+
2
*
col
+
1
]
+=
diff
;
break
;
}
}
}
}
}
}
...
@@ -271,64 +251,23 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
...
@@ -271,64 +251,23 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
/**
/**
* Get the areas where movement was detected
* Get the areas where movement was detected
*/
*/
int
colors
[
NUM_COLORS
];
p_sys
->
i_colors
=
FindShapes
(
p_buf2
,
p_buf
,
p_fmt
->
i_width
,
p_fmt
->
i_width
,
p_fmt
->
i_height
,
int
color_x_min
[
NUM_COLORS
];
p_sys
->
colors
,
p_sys
->
color_x_min
,
p_sys
->
color_x_max
,
p_sys
->
color_y_min
,
p_sys
->
color_y_max
);
int
color_x_max
[
NUM_COLORS
];
int
color_y_min
[
NUM_COLORS
];
int
color_y_max
[
NUM_COLORS
];
last
=
FindShapes
(
p_buf2
,
p_buf
,
i_src_pitch
,
i_src_visible
,
i_num_lines
,
colors
,
color_x_min
,
color_x_max
,
color_y_min
,
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)
*/
*/
uint8_t
*
p_outpix
=
p_outpic
->
p
[
Y_PLANE
].
p_pixels
;
Draw
(
p_filter
,
p_outpic
->
p
[
Y_PLANE
].
p_pixels
,
p_outpic
->
p
[
Y_PLANE
].
i_pitch
,
1
);
const
int
i_dst_pitch
=
p_outpic
->
p
[
Y_PLANE
].
i_pitch
;
j
=
0
;
for
(
i
=
1
;
i
<
last
;
i
++
)
{
if
(
colors
[
i
]
==
i
&&
color_x_min
[
i
]
!=
-
1
)
{
if
(
(
color_y_max
[
i
]
-
color_y_min
[
i
]
)
*
(
color_x_max
[
i
]
-
color_x_min
[
i
]
)
<
16
)
continue
;
j
++
;
int
x
,
y
;
y
=
color_y_min
[
i
];
for
(
x
=
color_x_min
[
i
];
x
<=
color_x_max
[
i
];
x
++
)
{
p_outpix
[
y
*
i_dst_pitch
+
x
]
=
0xff
;
}
y
=
color_y_max
[
i
];
for
(
x
=
color_x_min
[
i
];
x
<=
color_x_max
[
i
];
x
++
)
{
p_outpix
[
y
*
i_dst_pitch
+
x
]
=
0xff
;
}
x
=
color_x_min
[
i
];
for
(
y
=
color_y_min
[
i
];
y
<=
color_y_max
[
i
];
y
++
)
{
p_outpix
[
y
*
i_dst_pitch
+
x
]
=
0xff
;
}
x
=
color_x_max
[
i
];
for
(
y
=
color_y_min
[
i
];
y
<=
color_y_max
[
i
];
y
++
)
{
p_outpix
[
y
*
i_dst_pitch
+
x
]
=
0xff
;
}
}
}
msg_Dbg
(
p_filter
,
"Counted %d moving shapes."
,
j
);
/**
/**
* We're done. Lets keep a copy of the picture
* 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
vlc_memcpy
(
p_oldpix
,
p_inpix
,
i_src_pitch
*
i_num_lines
);
* handle it correctly */
vlc_memcpy
(
p_oldpix_u
,
p_inpix_u
,
i_src_pitch_u
*
i_num_lines_u
);
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
vlc_memcpy
(
p_oldpix_v
,
p_inpix_v
,
i_src_pitch_u
*
i_num_lines_u
);
vlc_mutex_unlock
(
&
p_filter
->
p_sys
->
lock
);
picture_Release
(
p_inpic
);
return
p_outpic
;
return
CopyInfoAndRelease
(
p_outpic
,
p_inpic
);
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -336,56 +275,34 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
...
@@ -336,56 +275,34 @@ static picture_t *Filter( filter_t *p_filter, picture_t *p_inpic )
*****************************************************************************/
*****************************************************************************/
static
picture_t
*
FilterPacked
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
)
static
picture_t
*
FilterPacked
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
)
{
{
picture_t
*
p_outpic
;
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
;
picture_t
*
p_outpic
;
int
i_y_offset
,
i_u_offset
,
i_v_offset
;
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
uint8_t
*
p_inpix
;
const
uint8_t
*
p_inpix_u
;
const
uint8_t
*
p_inpix_v
;
int
i_src_pitch
;
int
i_src_visible
;
int
i_num_lines
;
uint8_t
*
p_oldpix
;
uint8_t
*
p_oldpix
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
p_pixels
;
uint8_t
*
p_oldpix_u
;
const
int
i_old_pitch
=
p_sys
->
p_old
->
p
[
Y_PLANE
].
i_pitch
;
uint
8_t
*
p_oldpix_v
;
uint
32_t
*
p_buf
=
p_sys
->
p_buf
;
uint
8_t
*
p_outpix
;
uint
32_t
*
p_buf2
=
p_sys
->
p_buf2
;
uint32_t
*
p_buf
;
int
i_y_offset
,
i_u_offset
,
i_v_offset
;
uint32_t
*
p_buf2
;
int
i
,
j
;
unsigned
x
,
y
;
int
last
;
if
(
GetPackedYuvOffsets
(
p_
inpic
->
format
.
i_chroma
,
&
i_y_offset
,
if
(
GetPackedYuvOffsets
(
p_
fmt
->
i_chroma
,
&
i_
u_offset
,
&
i_v_offset
)
!=
VLC_SUCCESS
)
&
i_
y_offset
,
&
i_u_offset
,
&
i_v_offset
)
)
{
{
msg_Warn
(
p_filter
,
"Unsupported input chroma (%4s)"
,
msg_Warn
(
p_filter
,
"Unsupported input chroma (%4s)"
,
(
char
*
)
&
(
p_inpic
->
format
.
i_chroma
)
);
(
char
*
)
&
p_fmt
->
i_chroma
);
picture_Release
(
p_inpic
);
return
p_inpic
;
return
NULL
;
}
}
p_inpix
=
p_inpic
->
p
->
p_pixels
+
i_y_offset
;
if
(
!
p_sys
->
b_old
)
p_inpix_u
=
p_inpic
->
p
->
p_pixels
+
i_u_offset
;
p_inpix_v
=
p_inpic
->
p
->
p_pixels
+
i_v_offset
;
i_src_pitch
=
p_inpic
->
p
->
i_pitch
;
i_src_visible
=
p_inpic
->
p
->
i_visible_pitch
;
i_num_lines
=
p_inpic
->
p
->
i_visible_lines
;
if
(
!
p_sys
->
p_oldpix
||
!
p_sys
->
p_buf
)
{
{
free
(
p_sys
->
p_oldpix
);
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
free
(
p_sys
->
p_buf
);
p_sys
->
b_old
=
true
;
p_sys
->
p_oldpix
=
malloc
(
i_src_pitch
*
i_num_lines
);
p_sys
->
p_buf
=
malloc
(
sizeof
(
uint32_t
)
*
i_src_pitch
*
i_num_lines
/
2
);
p_sys
->
p_buf2
=
malloc
(
sizeof
(
uint32_t
)
*
i_src_pitch
*
i_num_lines
/
2
);
vlc_memcpy
(
p_sys
->
p_oldpix
,
p_inpic
->
p
->
p_pixels
,
i_src_pitch
*
i_num_lines
);
return
p_inpic
;
return
p_inpic
;
}
}
...
@@ -395,121 +312,50 @@ static picture_t *FilterPacked( filter_t *p_filter, picture_t *p_inpic )
...
@@ -395,121 +312,50 @@ static picture_t *FilterPacked( filter_t *p_filter, picture_t *p_inpic )
picture_Release
(
p_inpic
);
picture_Release
(
p_inpic
);
return
NULL
;
return
NULL
;
}
}
picture_Copy
(
p_outpic
,
p_inpic
);
p_outpix
=
p_outpic
->
p
->
p_pixels
+
i_y_offset
;
/* Substract all planes at once */
vlc_memcpy
(
p_outpic
->
p
->
p_pixels
,
p_inpic
->
p
->
p_pixels
,
p_inpic
->
p
->
i_pitch
*
p_inpic
->
p
->
i_visible_lines
);
p_oldpix
=
p_sys
->
p_oldpix
+
i_y_offset
;
p_oldpix_u
=
p_sys
->
p_oldpix
+
i_u_offset
;
p_oldpix_v
=
p_sys
->
p_oldpix
+
i_v_offset
;
p_buf
=
p_sys
->
p_buf
;
p_buf2
=
p_sys
->
p_buf2
;
vlc_mutex_lock
(
&
p_filter
->
p_sys
->
lock
);
for
(
y
=
0
;
y
<
p_fmt
->
i_height
;
y
++
)
/**
* Substract Y planes
*/
for
(
i
=
0
;
i
<
i_src_pitch
*
i_num_lines
;
i
+=
2
)
{
{
if
(
p_inpix
[
i
]
>
p_oldpix
[
i
]
)
for
(
x
=
0
;
x
<
p_fmt
->
i_width
;
x
+=
2
)
{
{
p_buf2
[
i
>>
1
]
=
p_inpix
[
i
]
-
p_oldpix
[
i
];
int
i
;
}
int
d
;
else
{
p_buf2
[
i
>>
1
]
=
p_oldpix
[
i
]
-
p_inpix
[
i
];
}
}
#if 0
d
=
abs
(
p_inpix
[
y
*
i_src_pitch
+
2
*
x
+
i_u_offset
]
-
p_oldpix
[
y
*
i_old_pitch
+
2
*
x
+
i_u_offset
]
)
+
for( i = 0; i < i_src_pitch * i_num_lines; i+=4 )
abs
(
p_inpix
[
y
*
i_src_pitch
+
2
*
x
+
i_v_offset
]
-
p_oldpix
[
y
*
i_old_pitch
+
2
*
x
+
i_v_offset
]
);
{
int diff;
if( p_inpix_u[i] > p_oldpix_u[i] )
{
diff = p_inpix_u[i] - p_oldpix_u[i];
}
else
{
diff = p_oldpix_u[i] - p_inpix_u[i];
}
if( p_inpix_v[i] > p_oldpix_v[i] )
{
diff += p_inpix_v[i] - p_oldpix_v[i];
}
else
{
diff += p_oldpix_v[i] - p_inpix_v[i];
}
p_buf2[(i>>2)<<1] += diff;
for
(
i
=
0
;
i
<
2
;
i
++
)
p_buf2[((i>>2)<<1)+1] += diff;
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
;
}
}
}
#endif
/**
/**
* Get the areas where movement was detected
* Get the areas where movement was detected
*/
*/
int
colors
[
5000
];
p_sys
->
i_colors
=
FindShapes
(
p_buf2
,
p_buf
,
p_fmt
->
i_width
,
p_fmt
->
i_width
,
p_fmt
->
i_height
,
int
color_x_min
[
5000
];
p_sys
->
colors
,
p_sys
->
color_x_min
,
p_sys
->
color_x_max
,
p_sys
->
color_y_min
,
p_sys
->
color_y_max
);
int
color_x_max
[
5000
];
int
color_y_min
[
5000
];
int
color_y_max
[
5000
];
last
=
FindShapes
(
p_buf2
,
p_buf
,
i_src_pitch
/
2
,
i_src_visible
/
2
,
i_num_lines
,
colors
,
color_x_min
,
color_x_max
,
color_y_min
,
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)
*/
*/
j
=
0
;
Draw
(
p_filter
,
&
p_outpic
->
p
[
Y_PLANE
].
p_pixels
[
i_y_offset
],
p_outpic
->
p
[
Y_PLANE
].
i_pitch
,
2
);
for
(
i
=
1
;
i
<
last
;
i
++
)
{
if
(
colors
[
i
]
==
i
&&
color_x_min
[
i
]
!=
-
1
)
{
if
(
(
color_y_max
[
i
]
-
color_y_min
[
i
]
)
*
(
color_x_max
[
i
]
-
color_x_min
[
i
]
)
<
16
)
continue
;
j
++
;
printf
(
"Shape: (%d,%d) (%d,%d)
\n
"
,
color_y_max
[
i
],
color_y_min
[
i
],
color_x_max
[
i
],
color_x_min
[
i
]
);
int
x
,
y
;
y
=
color_y_min
[
i
];
for
(
x
=
color_x_min
[
i
]
*
2
;
x
<=
color_x_max
[
i
]
*
2
;
x
+=
2
)
{
p_outpix
[
y
*
i_src_pitch
+
x
]
=
0xff
;
}
y
=
color_y_max
[
i
];
for
(
x
=
color_x_min
[
i
]
*
2
;
x
<=
color_x_max
[
i
]
*
2
;
x
+=
2
)
{
p_outpix
[
y
*
i_src_pitch
+
x
]
=
0xff
;
}
x
=
color_x_min
[
i
]
*
2
;
for
(
y
=
color_y_min
[
i
];
y
<=
color_y_max
[
i
];
y
++
)
{
p_outpix
[
y
*
i_src_pitch
+
x
]
=
0xff
;
}
x
=
color_x_max
[
i
]
*
2
;
for
(
y
=
color_y_min
[
i
];
y
<=
color_y_max
[
i
];
y
++
)
{
p_outpix
[
y
*
i_src_pitch
+
x
]
=
0xff
;
}
}
}
msg_Dbg
(
p_filter
,
"Counted %d moving shapes."
,
j
);
/**
/**
* We're done. Lets keep a copy of the picture
* 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
vlc_memcpy
(
p_sys
->
p_oldpix
,
p_inpic
->
p
->
p_pixels
,
i_src_pitch
*
i_num_lines
);
* handle it correctly */
picture_Copy
(
p_sys
->
p_old
,
p_inpic
);
vlc_mutex_unlock
(
&
p_filter
->
p_sys
->
lock
);
return
CopyInfoAndRelease
(
p_outpic
,
p_inpic
);
picture_Release
(
p_inpic
);
return
p_outpic
;
}
}
/*****************************************************************************
/*****************************************************************************
* Gaussian Convolution
* Gaussian Convolution
*****************************************************************************
*****************************************************************************
...
@@ -526,6 +372,10 @@ static void GaussianConvolution( uint32_t *p_inpix, uint32_t *p_smooth,
...
@@ -526,6 +372,10 @@ static void GaussianConvolution( uint32_t *p_inpix, uint32_t *p_smooth,
int
i_src_visible
)
int
i_src_visible
)
{
{
int
x
,
y
;
int
x
,
y
;
/* A bit overkill but ... simpler */
memset
(
p_smooth
,
0
,
sizeof
(
*
p_smooth
)
*
i_src_pitch
*
i_num_lines
);
for
(
y
=
2
;
y
<
i_num_lines
-
2
;
y
++
)
for
(
y
=
2
;
y
<
i_num_lines
-
2
;
y
++
)
{
{
for
(
x
=
2
;
x
<
i_src_visible
-
2
;
x
++
)
for
(
x
=
2
;
x
<
i_src_visible
-
2
;
x
++
)
...
@@ -581,7 +431,7 @@ static int FindShapes( uint32_t *p_diff, uint32_t *p_smooth,
...
@@ -581,7 +431,7 @@ static int FindShapes( uint32_t *p_diff, uint32_t *p_smooth,
/**
/**
* Apply some smoothing to remove noise
* Apply some smoothing to remove noise
*/
*/
GaussianConvolution
(
p_diff
,
p_smooth
,
i_pitch
,
i_
visible
,
i_lines
);
GaussianConvolution
(
p_diff
,
p_smooth
,
i_pitch
,
i_
lines
,
i_visible
);
/**
/**
* Label the shapes and build the labels dependencies list
* Label the shapes and build the labels dependencies list
...
@@ -608,7 +458,7 @@ static int FindShapes( uint32_t *p_diff, uint32_t *p_smooth,
...
@@ -608,7 +458,7 @@ static int FindShapes( uint32_t *p_diff, uint32_t *p_smooth,
p_smooth
[
i
*
i_pitch
+
j
]
=
p_smooth
[
i
*
i_pitch
+
j
-
1
];
p_smooth
[
i
*
i_pitch
+
j
]
=
p_smooth
[
i
*
i_pitch
+
j
-
1
];
else
else
{
{
if
(
last
<
5000
)
if
(
last
<
NUM_COLORS
)
{
{
p_smooth
[
i
*
i_pitch
+
j
]
=
last
;
p_smooth
[
i
*
i_pitch
+
j
]
=
last
;
colors
[
last
]
=
last
;
colors
[
last
]
=
last
;
...
@@ -705,3 +555,46 @@ static int FindShapes( uint32_t *p_diff, uint32_t *p_smooth,
...
@@ -705,3 +555,46 @@ static int FindShapes( uint32_t *p_diff, uint32_t *p_smooth,
return
last
;
return
last
;
}
}
static
void
Draw
(
filter_t
*
p_filter
,
uint8_t
*
p_pix
,
int
i_pix_pitch
,
int
i_pix_size
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
int
i
,
j
;
for
(
i
=
1
,
j
=
0
;
i
<
p_sys
->
i_colors
;
i
++
)
{
int
x
,
y
;
if
(
p_sys
->
colors
[
i
]
!=
i
)
continue
;
const
int
color_x_min
=
p_sys
->
color_x_min
[
i
];
const
int
color_x_max
=
p_sys
->
color_x_max
[
i
];
const
int
color_y_min
=
p_sys
->
color_y_min
[
i
];
const
int
color_y_max
=
p_sys
->
color_y_max
[
i
];
if
(
color_x_min
==
-
1
)
continue
;
if
(
(
color_y_max
-
color_y_min
)
*
(
color_x_max
-
color_x_min
)
<
16
)
continue
;
j
++
;
y
=
color_y_min
;
for
(
x
=
color_x_min
;
x
<=
color_x_max
;
x
++
)
p_pix
[
y
*
i_pix_pitch
+
x
*
i_pix_size
]
=
0xff
;
y
=
color_y_max
;
for
(
x
=
color_x_min
;
x
<=
color_x_max
;
x
++
)
p_pix
[
y
*
i_pix_pitch
+
x
*
i_pix_size
]
=
0xff
;
x
=
color_x_min
;
for
(
y
=
color_y_min
;
y
<=
color_y_max
;
y
++
)
p_pix
[
y
*
i_pix_pitch
+
x
*
i_pix_size
]
=
0xff
;
x
=
color_x_max
;
for
(
y
=
color_y_min
;
y
<=
color_y_max
;
y
++
)
p_pix
[
y
*
i_pix_pitch
+
x
*
i_pix_size
]
=
0xff
;
}
msg_Dbg
(
p_filter
,
"Counted %d moving shapes."
,
j
);
}
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