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
4322d421
Commit
4322d421
authored
Jul 26, 2013
by
Vianney Boyer
Committed by
Jean-Baptiste Kempf
Aug 15, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Oldmovie: Oldmovie style video filter
Signed-off-by:
Jean-Baptiste Kempf
<
jb@videolan.org
>
parent
84fd16d6
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
883 additions
and
1 deletion
+883
-1
NEWS
NEWS
+3
-0
modules/LIST
modules/LIST
+1
-0
modules/video_filter/Modules.am
modules/video_filter/Modules.am
+4
-1
modules/video_filter/oldmovie.c
modules/video_filter/oldmovie.c
+874
-0
po/POTFILES.in
po/POTFILES.in
+1
-0
No files found.
NEWS
View file @
4322d421
...
...
@@ -8,6 +8,9 @@ Access:
Video Output:
* Direct rendering and filtering for VDPAU hardware acceleration
Video Filter:
* New Oldmovie effect filter
Removed modules:
* ios video output: use ios2
...
...
modules/LIST
View file @
4322d421
...
...
@@ -231,6 +231,7 @@ $Id$
* ntservice: run VLC as a NT service
* nuv: NUV demuxer
* ogg: input module for OGG decapsulation
* oldmovie: oldmovie style video filter
* oldrc: old interface module using stdio
* omxil: OpenMAX IL audio/video decoder
* omxil_vout: OpenMAX IL video output
...
...
modules/video_filter/Modules.am
View file @
4322d421
...
...
@@ -133,6 +133,7 @@ SOURCES_gradfun = gradfun.c gradfun.h
SOURCES_subsdelay = subsdelay.c
SOURCES_hqdn3d = hqdn3d.c hqdn3d.h
SOURCES_anaglyph = anaglyph.c
SOURCES_oldmovie = oldmovie.c
noinst_HEADERS = filter_picture.h
libvlc_LTLIBRARIES += \
...
...
@@ -175,4 +176,6 @@ libvlc_LTLIBRARIES += \
libyuvp_plugin.la \
libantiflicker_plugin.la \
libhqdn3d_plugin.la \
libanaglyph_plugin.la
libanaglyph_plugin.la \
liboldmovie_plugin.la
modules/video_filter/oldmovie.c
0 → 100644
View file @
4322d421
/*****************************************************************************
* oldmovie.c : Old movie effect video filter
*****************************************************************************
* Copyright (C) 2013 Vianney Boyer
* $Id$
*
* Authors: Vianney Boyer <vlcvboyer -at- gmail -dot- com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <math.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_filter.h>
#include <vlc_rand.h>
#include <vlc_mtime.h>
#include "filter_picture.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
#ifndef TIME_UNIT_PER_S
# define TIME_UNIT_PER_S ( ((int64_t) 1) << 32 )
#endif
static
inline
int64_t
MOD
(
int64_t
a
,
int64_t
b
)
{
return
(
(
a
%
b
)
+
b
)
%
b
;
}
#define SUB_MIN(val, sub_val, min) val = \
((val-(int32_t)sub_val)<min?min:val-sub_val)
#define ADD_MAX(val, add_val, max) val = \
((val+(int32_t)add_val)>max?max:val+add_val)
static
inline
int32_t
PIX_OFS
(
int32_t
i_x
,
int32_t
i_y
,
plane_t
*
ps_plane
)
{
return
i_x
*
ps_plane
->
i_pixel_pitch
+
i_y
*
ps_plane
->
i_pitch
;
}
#define CHECK_PIX_OFS(i_x, i_y, ps_plane) ( \
(i_x) >= 0 && (i_y) >= 0 && \
(i_x) * ps_plane->i_pixel_pitch < ps_plane->i_visible_pitch && \
(i_y) < ps_plane->i_visible_lines \
)
static
inline
void
DARKEN_PIXEL
(
int32_t
i_x
,
int32_t
i_y
,
int16_t
intensity
,
plane_t
*
ps_plane
)
{
SUB_MIN
(
ps_plane
->
p_pixels
[
PIX_OFS
(
i_x
,
i_y
,
ps_plane
)
],
intensity
,
0
);
}
static
inline
void
LIGHTEN_PIXEL
(
int32_t
i_x
,
int32_t
i_y
,
int16_t
intensity
,
plane_t
*
ps_plane
)
{
ADD_MAX
(
ps_plane
->
p_pixels
[
PIX_OFS
(
i_x
,
i_y
,
ps_plane
)
],
intensity
,
0xFF
);
}
static
inline
void
CHECK_N_DARKEN_PIXEL
(
int32_t
i_x
,
int32_t
i_y
,
int16_t
intensity
,
plane_t
*
ps_plane
)
{
if
(
likely
(
CHECK_PIX_OFS
(
i_x
,
i_y
,
ps_plane
)
)
)
DARKEN_PIXEL
(
i_x
,
i_y
,
intensity
,
ps_plane
);
}
static
inline
void
CHECK_N_LIGHTEN_PIXEL
(
int32_t
i_x
,
int32_t
i_y
,
int16_t
intensity
,
plane_t
*
ps_plane
)
{
if
(
likely
(
CHECK_PIX_OFS
(
i_x
,
i_y
,
ps_plane
)
)
)
LIGHTEN_PIXEL
(
i_x
,
i_y
,
intensity
,
ps_plane
);
}
#define MAX_SCRATCH 20
#define MAX_HAIR 10
#define MAX_DUST 10
typedef
struct
{
int32_t
i_offset
;
int32_t
i_width
;
uint16_t
i_intensity
;
uint64_t
i_stop_trigger
;
}
scratch_t
;
typedef
struct
{
int32_t
i_x
,
i_y
;
uint8_t
i_rotation
;
int32_t
i_width
;
int32_t
i_length
;
int32_t
i_curve
;
uint16_t
i_intensity
;
uint64_t
i_stop_trigger
;
}
hair_t
;
typedef
struct
{
int32_t
i_x
,
i_y
;
int32_t
i_width
;
uint16_t
i_intensity
;
uint64_t
i_stop_trigger
;
}
dust_t
;
struct
filter_sys_t
{
/* general data */
bool
b_init
;
int32_t
i_planes
;
int32_t
*
i_height
;
int32_t
*
i_width
;
int32_t
*
i_visible_pitch
;
uint64_t
i_start_time
;
uint64_t
i_last_time
;
uint64_t
i_cur_time
;
/* sliding & offset effect */
uint64_t
i_offset_trigger
;
uint64_t
i_sliding_trigger
;
uint64_t
i_sliding_stop_trig
;
int32_t
i_offset_ofs
;
int32_t
i_sliding_ofs
;
int32_t
i_sliding_speed
;
/* scratch on film */
uint64_t
i_scratch_trigger
;
scratch_t
*
p_scratch
[
MAX_SCRATCH
];
/* hair on lens */
uint64_t
i_hair_trigger
;
hair_t
*
p_hair
[
MAX_HAIR
];
/* blotch on film */
uint64_t
i_blotch_trigger
;
/* dust on lens */
uint64_t
i_dust_trigger
;
dust_t
*
p_dust
[
MAX_DUST
];
};
/*****************************************************************************
* Prototypes
*****************************************************************************/
picture_t
*
Filter
(
filter_t
*
,
picture_t
*
);
int
oldmovie_allocate_data
(
filter_t
*
,
picture_t
*
);
void
oldmovie_free_allocated_data
(
filter_t
*
);
void
oldmovie_shutter_effect
(
filter_t
*
,
picture_t
*
);
int
oldmovie_sliding_offset_effect
(
filter_t
*
,
picture_t
*
);
void
oldmovie_black_n_white_effect
(
picture_t
*
);
int
oldmovie_dark_border_effect
(
filter_t
*
,
picture_t
*
);
int
oldmovie_film_scratch_effect
(
filter_t
*
,
picture_t
*
);
void
oldmovie_film_blotch_effect
(
filter_t
*
,
picture_t
*
);
void
oldmovie_film_dust_effect
(
filter_t
*
,
picture_t
*
);
int
oldmovie_lens_hair_effect
(
filter_t
*
,
picture_t
*
);
int
oldmovie_lens_dust_effect
(
filter_t
*
,
picture_t
*
);
void
oldmovie_define_hair_location
(
filter_t
*
p_filter
,
hair_t
*
ps_hair
);
void
oldmovie_define_dust_location
(
filter_t
*
p_filter
,
dust_t
*
ps_dust
);
int
oldmovie_sliding_offset_apply
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
int
Open
(
vlc_object_t
*
);
void
Close
(
vlc_object_t
*
);
vlc_module_begin
()
set_description
(
N_
(
"Old movie effect video filter"
)
)
set_shortname
(
N_
(
"Old movie"
))
set_capability
(
"video filter2"
,
0
)
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_VFILTER
)
set_callbacks
(
Open
,
Close
)
vlc_module_end
()
/**
* Open the filter
*/
int
Open
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
;
/* Assert video in match with video out */
if
(
!
es_format_IsSimilar
(
&
p_filter
->
fmt_in
,
&
p_filter
->
fmt_out
)
)
{
msg_Err
(
p_filter
,
"Input and output format does not match"
);
return
VLC_EGENERIC
;
}
/* Reject 0 bpp and unsupported chroma */
const
vlc_fourcc_t
fourcc
=
p_filter
->
fmt_in
.
video
.
i_chroma
;
const
vlc_chroma_description_t
*
p_chroma
=
vlc_fourcc_GetChromaDescription
(
p_filter
->
fmt_in
.
video
.
i_chroma
);
if
(
!
p_chroma
||
p_chroma
->
pixel_size
==
0
||
p_chroma
->
plane_count
<
3
||
p_chroma
->
pixel_size
>
1
||
!
vlc_fourcc_IsYUV
(
fourcc
)
)
{
msg_Err
(
p_filter
,
"Unsupported chroma (%4.4s)"
,
(
char
*
)
&
fourcc
);
return
VLC_EGENERIC
;
}
/* Allocate structure */
p_filter
->
p_sys
=
p_sys
=
calloc
(
1
,
sizeof
(
*
p_sys
)
);
if
(
unlikely
(
!
p_sys
)
)
return
VLC_ENOMEM
;
/* init data */
p_filter
->
pf_video_filter
=
Filter
;
p_sys
->
i_start_time
=
p_sys
->
i_cur_time
=
p_sys
->
i_last_time
=
NTPtime64
();
return
VLC_SUCCESS
;
}
/**
* Close the filter
*/
void
Close
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
/* Free allocated memory */
oldmovie_free_allocated_data
(
p_filter
);
free
(
p_sys
);
}
/**
* Filter a picture
*/
picture_t
*
Filter
(
filter_t
*
p_filter
,
picture_t
*
p_pic_in
)
{
if
(
unlikely
(
!
p_pic_in
||
!
p_filter
)
)
return
NULL
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
picture_t
*
p_pic_out
=
filter_NewPicture
(
p_filter
);
if
(
unlikely
(
!
p_pic_out
)
)
{
picture_Release
(
p_pic_in
);
return
NULL
;
}
/*
* manage time
*/
p_sys
->
i_last_time
=
p_sys
->
i_cur_time
;
p_sys
->
i_cur_time
=
NTPtime64
();
/*
* allocate data
*/
if
(
unlikely
(
!
p_sys
->
b_init
)
)
if
(
unlikely
(
oldmovie_allocate_data
(
p_filter
,
p_pic_in
)
!=
VLC_SUCCESS
)
)
{
picture_Release
(
p_pic_in
);
return
NULL
;
}
p_sys
->
b_init
=
true
;
/*
* preset output pic: raw copy src to dst
*/
picture_CopyPixels
(
p_pic_out
,
p_pic_in
);
/*
* apply several effects on picture
*/
oldmovie_black_n_white_effect
(
p_pic_out
);
/* simulates projector shutter blinking effect */
oldmovie_shutter_effect
(
p_filter
,
p_pic_out
);
if
(
unlikely
(
oldmovie_sliding_offset_effect
(
p_filter
,
p_pic_out
)
!=
VLC_SUCCESS
)
)
return
CopyInfoAndRelease
(
p_pic_out
,
p_pic_in
);
oldmovie_dark_border_effect
(
p_filter
,
p_pic_out
);
if
(
unlikely
(
oldmovie_film_scratch_effect
(
p_filter
,
p_pic_out
)
!=
VLC_SUCCESS
)
)
return
CopyInfoAndRelease
(
p_pic_out
,
p_pic_in
);
oldmovie_film_blotch_effect
(
p_filter
,
p_pic_out
);
if
(
unlikely
(
oldmovie_lens_hair_effect
(
p_filter
,
p_pic_out
)
!=
VLC_SUCCESS
)
)
return
CopyInfoAndRelease
(
p_pic_out
,
p_pic_in
);
if
(
unlikely
(
oldmovie_lens_dust_effect
(
p_filter
,
p_pic_out
)
!=
VLC_SUCCESS
)
)
return
CopyInfoAndRelease
(
p_pic_out
,
p_pic_in
);
oldmovie_film_dust_effect
(
p_filter
,
p_pic_out
);
return
CopyInfoAndRelease
(
p_pic_out
,
p_pic_in
);
}
/*
* Allocate data
*/
int
oldmovie_allocate_data
(
filter_t
*
p_filter
,
picture_t
*
p_pic_in
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
oldmovie_free_allocated_data
(
p_filter
);
/*
* take into account different characteristics for each plane
*/
p_sys
->
i_planes
=
p_pic_in
->
i_planes
;
p_sys
->
i_height
=
calloc
(
p_sys
->
i_planes
,
sizeof
(
int32_t
)
);
p_sys
->
i_width
=
calloc
(
p_sys
->
i_planes
,
sizeof
(
int32_t
)
);
p_sys
->
i_visible_pitch
=
calloc
(
p_sys
->
i_planes
,
sizeof
(
int32_t
)
);
if
(
unlikely
(
!
p_sys
->
i_height
||
!
p_sys
->
i_width
||
!
p_sys
->
i_visible_pitch
)
)
{
oldmovie_free_allocated_data
(
p_filter
);
return
VLC_ENOMEM
;
}
for
(
int32_t
i_p
=
0
;
i_p
<
p_sys
->
i_planes
;
i_p
++
)
{
p_sys
->
i_visible_pitch
[
i_p
]
=
(
int
)
p_pic_in
->
p
[
i_p
].
i_visible_pitch
;
p_sys
->
i_height
[
i_p
]
=
(
int
)
p_pic_in
->
p
[
i_p
].
i_visible_lines
;
p_sys
->
i_width
[
i_p
]
=
(
int
)
p_pic_in
->
p
[
i_p
].
i_visible_pitch
/
p_pic_in
->
p
[
i_p
].
i_pixel_pitch
;
}
return
VLC_SUCCESS
;
}
/**
* Free allocated data
*/
void
oldmovie_free_allocated_data
(
filter_t
*
p_filter
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
for
(
uint32_t
i_s
=
0
;
i_s
<
MAX_SCRATCH
;
i_s
++
)
FREENULL
(
p_sys
->
p_scratch
[
i_s
]);
for
(
uint32_t
i_h
=
0
;
i_h
<
MAX_HAIR
;
i_h
++
)
FREENULL
(
p_sys
->
p_hair
[
i_h
]);
for
(
uint32_t
i_d
=
0
;
i_d
<
MAX_DUST
;
i_d
++
)
FREENULL
(
p_sys
->
p_dust
[
i_d
]);
p_sys
->
i_planes
=
0
;
FREENULL
(
p_sys
->
i_height
);
FREENULL
(
p_sys
->
i_width
);
FREENULL
(
p_sys
->
i_visible_pitch
);
}
/**
* Projector shutter effect
*/
void
oldmovie_shutter_effect
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
#define SHUTTER_FREQ 2
#define SHUTTER_SPEED 25
#define SHUTTER_HEIGHT 1.5
#define SHUTTER_INTENSITY 50
#define SUB_FRAME (p_sys->i_cur_time % (TIME_UNIT_PER_S / SHUTTER_FREQ))
/*
* depending on current time: define shutter location on picture
*/
int32_t
i_shutter_sup
=
VLC_CLIP
((
int64_t
)
SUB_FRAME
*
p_pic_out
->
p
[
Y_PLANE
].
i_visible_lines
*
SHUTTER_SPEED
/
TIME_UNIT_PER_S
,
0
,
p_pic_out
->
p
[
Y_PLANE
].
i_visible_lines
);
int32_t
i_shutter_inf
=
VLC_CLIP
((
int64_t
)
SUB_FRAME
*
p_pic_out
->
p
[
Y_PLANE
].
i_visible_lines
*
SHUTTER_SPEED
/
TIME_UNIT_PER_S
-
SHUTTER_HEIGHT
*
p_pic_out
->
p
[
Y_PLANE
].
i_visible_lines
,
0
,
p_pic_out
->
p
[
Y_PLANE
].
i_visible_lines
);
int32_t
i_width
=
p_pic_out
->
p
[
Y_PLANE
].
i_visible_pitch
/
p_pic_out
->
p
[
Y_PLANE
].
i_pixel_pitch
;
/*
* darken pixels currently occulted by shutter
*/
for
(
int32_t
i_y
=
i_shutter_inf
;
i_y
<
i_shutter_sup
;
i_y
++
)
for
(
int32_t
i_x
=
0
;
i_x
<
i_width
;
i_x
++
)
DARKEN_PIXEL
(
i_x
,
i_y
,
SHUTTER_INTENSITY
,
&
p_pic_out
->
p
[
Y_PLANE
]
);
}
/**
* sliding & offset effect
*/
int
oldmovie_sliding_offset_effect
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
/**
* one shot offset section
*/
#define OFFSET_AVERAGE_PERIOD (10 * TIME_UNIT_PER_S)
/* start trigger to be (re)initialized */
if
(
p_sys
->
i_offset_trigger
==
0
||
p_sys
->
i_sliding_speed
!=
0
)
{
/* do not mix sliding and offset */
/* random trigger for offset effect */
p_sys
->
i_offset_trigger
=
p_sys
->
i_cur_time
+
(
(
uint64_t
)
vlc_mrand48
()
)
%
OFFSET_AVERAGE_PERIOD
+
OFFSET_AVERAGE_PERIOD
/
2
;
p_sys
->
i_offset_ofs
=
0
;
}
else
if
(
p_sys
->
i_offset_trigger
<=
p_sys
->
i_cur_time
)
{
/* trigger for offset effect */
p_sys
->
i_offset_trigger
=
0
;
p_sys
->
i_offset_ofs
=
MOD
(
(
(
uint32_t
)
vlc_mrand48
()
),
p_sys
->
i_height
[
Y_PLANE
]
)
*
100
;
}
else
p_sys
->
i_offset_ofs
=
0
;
/**
* sliding section
*/
#define SLIDING_AVERAGE_PERIOD (20 * TIME_UNIT_PER_S)
#define SLIDING_AVERAGE_DURATION ( 3 * TIME_UNIT_PER_S)
/* start trigger to be (re)initialized */
if
(
(
p_sys
->
i_sliding_stop_trig
==
0
)
&&
(
p_sys
->
i_sliding_trigger
==
0
)
&&
(
p_sys
->
i_sliding_speed
==
0
)
)
{
/* random trigger which enable sliding effect */
p_sys
->
i_sliding_trigger
=
p_sys
->
i_cur_time
+
(
(
uint64_t
)
vlc_mrand48
()
)
%
SLIDING_AVERAGE_PERIOD
+
SLIDING_AVERAGE_PERIOD
/
2
;
}
/* start trigger just occurs */
else
if
(
(
p_sys
->
i_sliding_stop_trig
==
0
)
&&
(
p_sys
->
i_sliding_trigger
<=
p_sys
->
i_cur_time
)
&&
(
p_sys
->
i_sliding_speed
==
0
)
)
{
/* init sliding parameters */
p_sys
->
i_sliding_trigger
=
0
;
p_sys
->
i_sliding_stop_trig
=
p_sys
->
i_cur_time
+
((
uint64_t
)
vlc_mrand48
()
)
%
SLIDING_AVERAGE_DURATION
+
SLIDING_AVERAGE_DURATION
/
2
;
p_sys
->
i_sliding_ofs
=
0
;
/* note: sliding speed unit = image per 100 s */
p_sys
->
i_sliding_speed
=
MOD
(((
int32_t
)
vlc_mrand48
()
),
201
)
-
100
;
}
/* stop trigger disabling sliding effect */
else
if
(
(
p_sys
->
i_sliding_stop_trig
<=
p_sys
->
i_cur_time
)
&&
(
p_sys
->
i_sliding_trigger
==
0
)
)
{
/* first increase speed to ensure we will come back to stable image */
if
(
abs
(
p_sys
->
i_sliding_speed
)
<
50
)
p_sys
->
i_sliding_speed
+=
5
;
/* check if offset is close to 0 and then ready to stop */
if
(
abs
(
p_sys
->
i_sliding_ofs
)
<
abs
(
p_sys
->
i_sliding_speed
*
p_sys
->
i_height
[
Y_PLANE
]
*
(
p_sys
->
i_cur_time
-
p_sys
->
i_last_time
)
/
TIME_UNIT_PER_S
)
||
abs
(
p_sys
->
i_sliding_ofs
)
<
p_sys
->
i_height
[
Y_PLANE
]
*
100
/
20
)
{
/* reset sliding parameters */
p_sys
->
i_sliding_ofs
=
p_sys
->
i_sliding_speed
=
0
;
p_sys
->
i_sliding_trigger
=
p_sys
->
i_sliding_stop_trig
=
0
;
}
}
/* update offset */
p_sys
->
i_sliding_ofs
+=
p_sys
->
i_sliding_speed
*
p_sys
->
i_height
[
Y_PLANE
]
*
(
p_sys
->
i_cur_time
-
p_sys
->
i_last_time
)
/
TIME_UNIT_PER_S
;
p_sys
->
i_sliding_ofs
=
MOD
(
p_sys
->
i_sliding_ofs
,
p_sys
->
i_height
[
Y_PLANE
]
*
100
);
/* apply offset */
return
oldmovie_sliding_offset_apply
(
p_filter
,
p_pic_out
);
}
/**
* apply both sliding and offset effect
*/
int
oldmovie_sliding_offset_apply
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
for
(
uint8_t
i_p
=
0
;
i_p
<
p_pic_out
->
i_planes
;
i_p
++
)
{
/* first allocate temporary buffer for swap operation */
uint8_t
*
p_temp_buf
=
calloc
(
p_pic_out
->
p
[
i_p
].
i_lines
*
p_pic_out
->
p
[
i_p
].
i_pitch
,
sizeof
(
uint8_t
)
);
if
(
unlikely
(
!
p_temp_buf
)
)
return
VLC_ENOMEM
;
memcpy
(
p_temp_buf
,
p_pic_out
->
p
[
i_p
].
p_pixels
,
p_pic_out
->
p
[
i_p
].
i_lines
*
p_pic_out
->
p
[
i_p
].
i_pitch
);
/* copy lines to output_pic */
for
(
int32_t
i_y
=
0
;
i_y
<
p_pic_out
->
p
[
i_p
].
i_visible_lines
;
i_y
++
)
{
int32_t
i_ofs
=
MOD
(
(
p_sys
->
i_offset_ofs
+
p_sys
->
i_sliding_ofs
)
/
100
,
p_sys
->
i_height
[
Y_PLANE
]
);
i_ofs
*=
p_pic_out
->
p
[
i_p
].
i_visible_lines
;
i_ofs
/=
p_sys
->
i_height
[
Y_PLANE
];
memcpy
(
&
p_pic_out
->
p
[
i_p
].
p_pixels
[
i_y
*
p_pic_out
->
p
[
i_p
].
i_pitch
],
&
p_temp_buf
[
(
(
i_y
+
i_ofs
)
%
p_pic_out
->
p
[
i_p
].
i_visible_lines
)
*
p_pic_out
->
p
[
i_p
].
i_pitch
],
p_pic_out
->
p
[
i_p
].
i_visible_pitch
);
}
free
(
p_temp_buf
);
}
return
VLC_SUCCESS
;
}
/**
* Black and white transform including a touch of sepia effect
*/
void
oldmovie_black_n_white_effect
(
picture_t
*
p_pic_out
)
{
for
(
int32_t
i_y
=
0
;
i_y
<
p_pic_out
->
p
[
Y_PLANE
].
i_visible_lines
;
i_y
++
)
for
(
int32_t
i_x
=
0
;
i_x
<
p_pic_out
->
p
[
Y_PLANE
].
i_visible_pitch
;
i_x
+=
p_pic_out
->
p
[
Y_PLANE
].
i_pixel_pitch
)
{
uint32_t
i_pix_ofs
=
i_x
+
i_y
*
p_pic_out
->
p
[
Y_PLANE
].
i_pitch
;
p_pic_out
->
p
[
Y_PLANE
].
p_pixels
[
i_pix_ofs
]
-=
p_pic_out
->
p
[
Y_PLANE
].
p_pixels
[
i_pix_ofs
]
>>
2
;
p_pic_out
->
p
[
Y_PLANE
].
p_pixels
[
i_pix_ofs
]
+=
30
;
}
memset
(
p_pic_out
->
p
[
U_PLANE
].
p_pixels
,
122
,
p_pic_out
->
p
[
U_PLANE
].
i_lines
*
p_pic_out
->
p
[
U_PLANE
].
i_pitch
);
memset
(
p_pic_out
->
p
[
V_PLANE
].
p_pixels
,
132
,
p_pic_out
->
p
[
V_PLANE
].
i_lines
*
p_pic_out
->
p
[
V_PLANE
].
i_pitch
);
}
/**
* Smooth darker borders effect
*/
int
oldmovie_dark_border_effect
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
#define BORDER_DIST 20
for
(
int32_t
i_y
=
0
;
i_y
<
p_sys
->
i_height
[
Y_PLANE
];
i_y
++
)
for
(
int32_t
i_x
=
0
;
i_x
<
p_sys
->
i_width
[
Y_PLANE
];
i_x
++
)
{
int32_t
i_x_border_dist
=
__MIN
(
i_x
,
p_sys
->
i_width
[
Y_PLANE
]
-
i_x
);
int32_t
i_y_border_dist
=
__MIN
(
i_y
,
p_sys
->
i_height
[
Y_PLANE
]
-
i_y
);
int32_t
i_border_dist
=
__MAX
(
BORDER_DIST
-
i_x_border_dist
,
0
)
+
__MAX
(
BORDER_DIST
-
i_y_border_dist
,
0
);
i_border_dist
=
__MIN
(
BORDER_DIST
,
i_border_dist
);
if
(
i_border_dist
==
0
)
continue
;
uint32_t
i_pix_ofs
=
i_x
*
p_pic_out
->
p
[
Y_PLANE
].
i_pixel_pitch
+
i_y
*
p_pic_out
->
p
[
Y_PLANE
].
i_pitch
;
SUB_MIN
(
p_pic_out
->
p
[
Y_PLANE
].
p_pixels
[
i_pix_ofs
],
i_border_dist
*
255
/
BORDER_DIST
,
0
);
}
return
VLC_SUCCESS
;
}
/**
* Vertical scratch random management and effect
*/
int
oldmovie_film_scratch_effect
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
#define SCRATCH_GENERATOR_PERIOD ( TIME_UNIT_PER_S * 2 )
#define SCRATCH_DURATION ( TIME_UNIT_PER_S * 1 / 2)
/* generate new scratch */
if
(
p_sys
->
i_scratch_trigger
<=
p_sys
->
i_cur_time
)
{
for
(
uint32_t
i_s
=
0
;
i_s
<
MAX_SCRATCH
;
i_s
++
)
if
(
p_sys
->
p_scratch
[
i_s
]
==
NULL
)
{
/* allocate data */
p_sys
->
p_scratch
[
i_s
]
=
calloc
(
1
,
sizeof
(
scratch_t
)
);
if
(
unlikely
(
!
p_sys
->
p_scratch
[
i_s
]
)
)
return
VLC_ENOMEM
;
/* set random parameters */
p_sys
->
p_scratch
[
i_s
]
->
i_offset
=
(
(
(
unsigned
)
vlc_mrand48
()
)
%
__MAX
(
p_sys
->
i_width
[
Y_PLANE
]
-
10
,
1
)
)
+
5
;
p_sys
->
p_scratch
[
i_s
]
->
i_width
=
(
(
(
unsigned
)
vlc_mrand48
()
)
%
__MAX
(
p_sys
->
i_width
[
Y_PLANE
]
/
500
,
1
)
)
+
1
;
p_sys
->
p_scratch
[
i_s
]
->
i_intensity
=
(
unsigned
)
vlc_mrand48
()
%
50
+
10
;
p_sys
->
p_scratch
[
i_s
]
->
i_stop_trigger
=
p_sys
->
i_cur_time
+
(
uint64_t
)
vlc_mrand48
()
%
SCRATCH_DURATION
+
SCRATCH_DURATION
/
2
;
break
;
}
p_sys
->
i_scratch_trigger
=
p_sys
->
i_cur_time
+
(
(
uint64_t
)
vlc_mrand48
()
)
%
SCRATCH_GENERATOR_PERIOD
+
SCRATCH_GENERATOR_PERIOD
/
2
;
}
/* manage and apply current scratch */
for
(
uint32_t
i_s
=
0
;
i_s
<
MAX_SCRATCH
;
i_s
++
)
if
(
p_sys
->
p_scratch
[
i_s
]
)
{
/* remove outdated scratch */
if
(
p_sys
->
p_scratch
[
i_s
]
->
i_stop_trigger
<=
p_sys
->
i_cur_time
)
{
FREENULL
(
p_sys
->
p_scratch
[
i_s
]
);
continue
;
}
/* otherwise apply scratch */
for
(
int32_t
i_y
=
0
;
i_y
<
p_pic_out
->
p
[
Y_PLANE
].
i_visible_lines
;
i_y
++
)
for
(
int32_t
i_x
=
p_sys
->
p_scratch
[
i_s
]
->
i_offset
;
i_x
<
__MIN
(
p_sys
->
p_scratch
[
i_s
]
->
i_offset
+
p_sys
->
p_scratch
[
i_s
]
->
i_width
,
p_sys
->
i_width
[
Y_PLANE
]
);
i_x
++
)
DARKEN_PIXEL
(
i_x
,
i_y
,
p_sys
->
p_scratch
[
i_s
]
->
i_intensity
,
&
p_pic_out
->
p
[
Y_PLANE
]
);
}
return
VLC_SUCCESS
;
}
/**
* Blotch addition
* bigger than dust but only during one frame (due to a local film damage)
*/
void
oldmovie_film_blotch_effect
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
#define BLOTCH_GENERATOR_PERIOD ( TIME_UNIT_PER_S * 5 )
/* generate blotch */
if
(
p_sys
->
i_blotch_trigger
<=
p_sys
->
i_cur_time
)
{
/* set random parameters */
int32_t
i_bx
=
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_width
[
Y_PLANE
];
int32_t
i_by
=
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_height
[
Y_PLANE
];
int32_t
i_width
=
(
unsigned
)
vlc_mrand48
()
%
__MAX
(
1
,
p_sys
->
i_width
[
Y_PLANE
]
/
10
)
+
1
;
int32_t
i_intensity
=
(
unsigned
)
vlc_mrand48
()
%
50
+
20
;
if
(
(
unsigned
)
vlc_mrand48
()
&
0x01
)
{
/* draw dark blotch */
for
(
int32_t
i_y
=
-
i_width
+
1
;
i_y
<
i_width
;
i_y
++
)
for
(
int32_t
i_x
=
-
i_width
+
1
;
i_x
<
i_width
;
i_x
++
)
if
(
i_x
*
i_x
+
i_y
*
i_y
<=
i_width
*
i_width
)
CHECK_N_DARKEN_PIXEL
(
i_x
+
i_bx
,
i_y
+
i_by
,
i_intensity
,
&
p_pic_out
->
p
[
Y_PLANE
]
);
}
else
{
/* draw light blotch */
for
(
int32_t
i_y
=
-
i_width
+
1
;
i_y
<
i_width
;
i_y
++
)
for
(
int32_t
i_x
=
-
i_width
+
1
;
i_x
<
i_width
;
i_x
++
)
if
(
i_x
*
i_x
+
i_y
*
i_y
<=
i_width
*
i_width
)
CHECK_N_LIGHTEN_PIXEL
(
i_x
+
i_bx
,
i_y
+
i_by
,
i_intensity
,
&
p_pic_out
->
p
[
Y_PLANE
]
);
}
p_sys
->
i_blotch_trigger
=
p_sys
->
i_cur_time
+
(
uint64_t
)
vlc_mrand48
()
%
BLOTCH_GENERATOR_PERIOD
+
BLOTCH_GENERATOR_PERIOD
/
2
;
}
}
/**
* Dust dots addition, visible during one frame only (film damages)
*/
void
oldmovie_film_dust_effect
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
)
{
#define ONESHOT_DUST_RATIO 1000
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
for
(
int32_t
i_dust
=
0
;
i_dust
<
p_sys
->
i_width
[
Y_PLANE
]
*
p_sys
->
i_height
[
Y_PLANE
]
/
ONESHOT_DUST_RATIO
;
i_dust
++
)
if
(
(
unsigned
)
vlc_mrand48
()
%
5
<
3
)
DARKEN_PIXEL
(
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_width
[
Y_PLANE
],
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_height
[
Y_PLANE
],
150
,
&
p_pic_out
->
p
[
Y_PLANE
]
);
else
LIGHTEN_PIXEL
(
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_width
[
Y_PLANE
],
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_height
[
Y_PLANE
],
50
,
&
p_pic_out
->
p
[
Y_PLANE
]
);
}
/**
* Hair and dust on projector lens
*
*/
#define HAIR_GENERATOR_PERIOD ( TIME_UNIT_PER_S * 50 )
#define HAIR_DURATION ( TIME_UNIT_PER_S * 50 )
#define DUST_GENERATOR_PERIOD ( TIME_UNIT_PER_S * 100 )
#define DUST_DURATION ( TIME_UNIT_PER_S * 4 )
/**
* Define hair location on the lens and timeout
*
*/
void
oldmovie_define_hair_location
(
filter_t
*
p_filter
,
hair_t
*
ps_hair
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
ps_hair
->
i_x
=
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_width
[
Y_PLANE
];
ps_hair
->
i_y
=
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_height
[
Y_PLANE
];
ps_hair
->
i_rotation
=
(
unsigned
)
vlc_mrand48
()
%
200
;
ps_hair
->
i_stop_trigger
=
p_sys
->
i_cur_time
+
(
uint64_t
)
vlc_mrand48
()
%
HAIR_DURATION
+
HAIR_DURATION
/
2
;
}
/**
* Show black hair on the screen
* after random duration it is removed or re-located
*/
int
oldmovie_lens_hair_effect
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
/* generate new hair */
if
(
p_sys
->
i_hair_trigger
<=
p_sys
->
i_cur_time
)
{
for
(
uint32_t
i_h
=
0
;
i_h
<
MAX_HAIR
;
i_h
++
)
if
(
p_sys
->
p_hair
[
i_h
]
==
NULL
)
{
/* allocate data */
p_sys
->
p_hair
[
i_h
]
=
calloc
(
1
,
sizeof
(
hair_t
)
);
if
(
unlikely
(
!
p_sys
->
p_hair
[
i_h
]
)
)
return
VLC_ENOMEM
;
/* set random parameters */
p_sys
->
p_hair
[
i_h
]
->
i_length
=
(
unsigned
)
vlc_mrand48
()
%
(
p_sys
->
i_width
[
Y_PLANE
]
/
3
)
+
5
;
p_sys
->
p_hair
[
i_h
]
->
i_curve
=
MOD
(
(
int32_t
)
vlc_mrand48
(),
80
)
-
40
;
p_sys
->
p_hair
[
i_h
]
->
i_width
=
(
unsigned
)
vlc_mrand48
()
%
__MAX
(
1
,
p_sys
->
i_width
[
Y_PLANE
]
/
1500
)
+
1
;
p_sys
->
p_hair
[
i_h
]
->
i_intensity
=
(
unsigned
)
vlc_mrand48
()
%
50
+
20
;
oldmovie_define_hair_location
(
p_filter
,
p_sys
->
p_hair
[
i_h
]
);
break
;
}
p_sys
->
i_hair_trigger
=
p_sys
->
i_cur_time
+
(
uint64_t
)
vlc_mrand48
()
%
HAIR_GENERATOR_PERIOD
+
HAIR_GENERATOR_PERIOD
/
2
;
}
/* manage and apply current hair */
for
(
uint32_t
i_h
=
0
;
i_h
<
MAX_HAIR
;
i_h
++
)
if
(
p_sys
->
p_hair
[
i_h
]
)
{
/* remove outdated ones */
if
(
p_sys
->
p_hair
[
i_h
]
->
i_stop_trigger
<=
p_sys
->
i_cur_time
)
{
/* select between moving or removing hair */
if
(
(
unsigned
)
vlc_mrand48
()
%
2
==
0
)
/* move hair */
oldmovie_define_hair_location
(
p_filter
,
p_sys
->
p_hair
[
i_h
]
);
else
{
/* remove hair */
FREENULL
(
p_sys
->
p_hair
[
i_h
]
);
continue
;
}
}
/* draw hair */
double
f_base_x
=
(
double
)
p_sys
->
p_hair
[
i_h
]
->
i_x
;
double
f_base_y
=
(
double
)
p_sys
->
p_hair
[
i_h
]
->
i_y
;
for
(
int32_t
i_l
=
0
;
i_l
<
p_sys
->
p_hair
[
i_h
]
->
i_length
;
i_l
++
)
{
uint32_t
i_current_rot
=
p_sys
->
p_hair
[
i_h
]
->
i_rotation
+
p_sys
->
p_hair
[
i_h
]
->
i_curve
*
i_l
/
100
;
f_base_x
+=
cos
(
(
double
)
i_current_rot
/
128
.
0
*
M_PI
);
f_base_y
+=
sin
(
(
double
)
i_current_rot
/
128
.
0
*
M_PI
);
double
f_current_x
=
f_base_x
;
double
f_current_y
=
f_base_y
;
for
(
int32_t
i_w
=
0
;
i_w
<
p_sys
->
p_hair
[
i_h
]
->
i_width
;
i_w
++
)
{
f_current_x
+=
sin
(
(
double
)
i_current_rot
/
128
.
0
*
M_PI
);
f_current_y
+=
cos
(
(
double
)
i_current_rot
/
128
.
0
*
M_PI
);
CHECK_N_DARKEN_PIXEL
(
(
int32_t
)
f_current_x
,
(
int32_t
)
f_current_y
,
p_sys
->
p_hair
[
i_h
]
->
i_intensity
,
&
p_pic_out
->
p
[
Y_PLANE
]
);
}
}
}
return
VLC_SUCCESS
;
}
/**
* Define dust location on the lens and timeout
*
*/
void
oldmovie_define_dust_location
(
filter_t
*
p_filter
,
dust_t
*
ps_dust
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
ps_dust
->
i_x
=
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_width
[
Y_PLANE
];
ps_dust
->
i_y
=
(
unsigned
)
vlc_mrand48
()
%
p_sys
->
i_height
[
Y_PLANE
];
ps_dust
->
i_stop_trigger
=
p_sys
->
i_cur_time
+
(
uint64_t
)
vlc_mrand48
()
%
HAIR_DURATION
+
HAIR_DURATION
/
2
;
ps_dust
->
i_x
=
MOD
(
(
int32_t
)
vlc_mrand48
(),
p_sys
->
i_width
[
Y_PLANE
]
);
ps_dust
->
i_y
=
MOD
(
(
int32_t
)
vlc_mrand48
(),
p_sys
->
i_height
[
Y_PLANE
]
);
ps_dust
->
i_stop_trigger
=
p_sys
->
i_cur_time
+
(
uint64_t
)
vlc_mrand48
()
%
DUST_DURATION
+
DUST_DURATION
/
2
;
}
/**
* Dust addition
* smaller than blotch but will remain on the screen for long time
*/
int
oldmovie_lens_dust_effect
(
filter_t
*
p_filter
,
picture_t
*
p_pic_out
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
/* generate new dust */
if
(
p_sys
->
i_dust_trigger
<=
p_sys
->
i_cur_time
)
{
for
(
uint32_t
i_d
=
0
;
i_d
<
MAX_DUST
;
i_d
++
)
if
(
p_sys
->
p_dust
[
i_d
]
==
NULL
)
{
/* allocate data */
p_sys
->
p_dust
[
i_d
]
=
calloc
(
1
,
sizeof
(
dust_t
)
);
if
(
unlikely
(
!
p_sys
->
p_dust
[
i_d
]
)
)
return
VLC_ENOMEM
;
/* set random parameters */
oldmovie_define_dust_location
(
p_filter
,
p_sys
->
p_dust
[
i_d
]
);
p_sys
->
p_dust
[
i_d
]
->
i_width
=
MOD
(
(
int32_t
)
vlc_mrand48
(),
5
)
+
1
;
p_sys
->
p_dust
[
i_d
]
->
i_intensity
=
(
unsigned
)
vlc_mrand48
()
%
30
+
30
;
break
;
}
p_sys
->
i_dust_trigger
=
p_sys
->
i_cur_time
+
(
uint64_t
)
vlc_mrand48
()
%
DUST_GENERATOR_PERIOD
+
DUST_GENERATOR_PERIOD
/
2
;
}
/* manage and apply current dust */
for
(
uint32_t
i_d
=
0
;
i_d
<
MAX_DUST
;
i_d
++
)
if
(
p_sys
->
p_dust
[
i_d
]
)
{
/* remove outdated ones */
if
(
p_sys
->
p_dust
[
i_d
]
->
i_stop_trigger
<=
p_sys
->
i_cur_time
)
{
/* select between moving or removing dust */
if
(
(
unsigned
)
vlc_mrand48
()
%
2
==
0
)
/* move dust */
oldmovie_define_dust_location
(
p_filter
,
p_sys
->
p_dust
[
i_d
]
);
else
{
/* remove dust */
FREENULL
(
p_sys
->
p_dust
[
i_d
]
);
continue
;
}
}
/* draw dust */
for
(
int32_t
i_y
=
-
p_sys
->
p_dust
[
i_d
]
->
i_width
+
1
;
i_y
<
p_sys
->
p_dust
[
i_d
]
->
i_width
;
i_y
++
)
for
(
int32_t
i_x
=
-
p_sys
->
p_dust
[
i_d
]
->
i_width
+
1
;
i_x
<
p_sys
->
p_dust
[
i_d
]
->
i_width
;
i_x
++
)
if
(
i_x
*
i_x
+
i_y
*
i_y
<=
p_sys
->
p_dust
[
i_d
]
->
i_width
*
p_sys
->
p_dust
[
i_d
]
->
i_width
)
CHECK_N_DARKEN_PIXEL
(
i_x
+
p_sys
->
p_dust
[
i_d
]
->
i_x
,
i_y
+
p_sys
->
p_dust
[
i_d
]
->
i_y
,
p_sys
->
p_dust
[
i_d
]
->
i_intensity
,
&
p_pic_out
->
p
[
Y_PLANE
]
);
}
return
VLC_SUCCESS
;
}
po/POTFILES.in
View file @
4322d421
...
...
@@ -1109,6 +1109,7 @@ modules/video_filter/mosaic.c
modules/video_filter/mosaic.h
modules/video_filter/motionblur.c
modules/video_filter/motiondetect.c
modules/video_filter/oldmovie.c
modules/video_filter/opencv_example.cpp
modules/video_filter/opencv_wrapper.c
modules/video_filter/posterize.c
...
...
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