Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
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-gpu
Commits
1b637157
Commit
1b637157
authored
Feb 12, 2008
by
Antoine Cellerier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
video filter module - for thehomebrewAmbiLight (AtmoLight) [2/3]: atmo-video_filter.diff
parent
bcb07441
Changes
29
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
6234 additions
and
0 deletions
+6234
-0
modules/video_filter/atmo/AtmoCalculations.cpp
modules/video_filter/atmo/AtmoCalculations.cpp
+461
-0
modules/video_filter/atmo/AtmoCalculations.h
modules/video_filter/atmo/AtmoCalculations.h
+22
-0
modules/video_filter/atmo/AtmoConfig.cpp
modules/video_filter/atmo/AtmoConfig.cpp
+252
-0
modules/video_filter/atmo/AtmoConfig.h
modules/video_filter/atmo/AtmoConfig.h
+269
-0
modules/video_filter/atmo/AtmoConnection.cpp
modules/video_filter/atmo/AtmoConnection.cpp
+36
-0
modules/video_filter/atmo/AtmoConnection.h
modules/video_filter/atmo/AtmoConnection.h
+52
-0
modules/video_filter/atmo/AtmoDefs.h
modules/video_filter/atmo/AtmoDefs.h
+158
-0
modules/video_filter/atmo/AtmoDynData.cpp
modules/video_filter/atmo/AtmoDynData.cpp
+57
-0
modules/video_filter/atmo/AtmoDynData.h
modules/video_filter/atmo/AtmoDynData.h
+86
-0
modules/video_filter/atmo/AtmoExternalCaptureInput.cpp
modules/video_filter/atmo/AtmoExternalCaptureInput.cpp
+303
-0
modules/video_filter/atmo/AtmoExternalCaptureInput.h
modules/video_filter/atmo/AtmoExternalCaptureInput.h
+83
-0
modules/video_filter/atmo/AtmoInput.cpp
modules/video_filter/atmo/AtmoInput.cpp
+26
-0
modules/video_filter/atmo/AtmoInput.h
modules/video_filter/atmo/AtmoInput.h
+45
-0
modules/video_filter/atmo/AtmoLiveView.cpp
modules/video_filter/atmo/AtmoLiveView.cpp
+261
-0
modules/video_filter/atmo/AtmoLiveView.h
modules/video_filter/atmo/AtmoLiveView.h
+59
-0
modules/video_filter/atmo/AtmoOutputFilter.cpp
modules/video_filter/atmo/AtmoOutputFilter.cpp
+186
-0
modules/video_filter/atmo/AtmoOutputFilter.h
modules/video_filter/atmo/AtmoOutputFilter.h
+36
-0
modules/video_filter/atmo/AtmoSerialConnection.cpp
modules/video_filter/atmo/AtmoSerialConnection.cpp
+273
-0
modules/video_filter/atmo/AtmoSerialConnection.h
modules/video_filter/atmo/AtmoSerialConnection.h
+59
-0
modules/video_filter/atmo/AtmoThread.cpp
modules/video_filter/atmo/AtmoThread.cpp
+172
-0
modules/video_filter/atmo/AtmoThread.h
modules/video_filter/atmo/AtmoThread.h
+78
-0
modules/video_filter/atmo/AtmoTools.cpp
modules/video_filter/atmo/AtmoTools.cpp
+276
-0
modules/video_filter/atmo/AtmoTools.h
modules/video_filter/atmo/AtmoTools.h
+42
-0
modules/video_filter/atmo/AtmoZoneDefinition.cpp
modules/video_filter/atmo/AtmoZoneDefinition.cpp
+226
-0
modules/video_filter/atmo/AtmoZoneDefinition.h
modules/video_filter/atmo/AtmoZoneDefinition.h
+39
-0
modules/video_filter/atmo/COPYING.txt
modules/video_filter/atmo/COPYING.txt
+340
-0
modules/video_filter/atmo/Modules.am
modules/video_filter/atmo/Modules.am
+2
-0
modules/video_filter/atmo/README.txt
modules/video_filter/atmo/README.txt
+52
-0
modules/video_filter/atmo/atmo.cpp
modules/video_filter/atmo/atmo.cpp
+2283
-0
No files found.
modules/video_filter/atmo/AtmoCalculations.cpp
0 → 100644
View file @
1b637157
/*
* calculations.c: calculations needed by the input devices
*
* See the README file for copyright information and how to reach the author.
*
* $Id$
*/
#include <stdlib.h>
#include <string.h>
#include "AtmoDefs.h"
#include "AtmoCalculations.h"
#include "AtmoConfig.h"
#include "AtmoZoneDefinition.h"
// set accuracy of color calculation
#define h_MAX 255
#define s_MAX 255
#define v_MAX 255
// macros
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#define POS_DIV(a, b) ( (a)/(b) + ( ((a)%(b) >= (b)/2 ) ? 1 : 0) )
tColorPacket
CalcColorsAnalyzeHSV
(
CAtmoConfig
*
pAtmoConfig
,
tHSVColor
*
HSV_Img
)
{
int
i
;
// counter
// static tWeightPacket Weight[IMAGE_SIZE];
// Flip instead having a array with (64x48) entries of values for each channel
// I have x arrays of 64x48 so each channel has its own array...
// (or gradient which is use to judge about the pixels)
static
int
Weight
[
ATMO_NUM_CHANNELS
][
IMAGE_SIZE
];
/***************************************************************************/
/* Weight */
/***************************************************************************/
static
int
LastEdgeWeighting
=
-
1
;
static
int
LastWidescreenMode
=
-
1
;
int
AtmoSetup_EdgeWeighting
=
pAtmoConfig
->
getLiveView_EdgeWeighting
();
int
AtmoSetup_WidescreenMode
=
pAtmoConfig
->
getLiveView_WidescreenMode
();
int
AtmoSetup_DarknessLimit
=
pAtmoConfig
->
getLiveView_DarknessLimit
();
int
AtmoSetup_BrightCorrect
=
pAtmoConfig
->
getLiveView_BrightCorrect
();
int
AtmoSetup_SatWinSize
=
pAtmoConfig
->
getLiveView_SatWinSize
();
// calculate only if setup has changed
if
((
AtmoSetup_EdgeWeighting
!=
LastEdgeWeighting
)
||
(
AtmoSetup_WidescreenMode
!=
LastWidescreenMode
))
{
for
(
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
pAtmoConfig
->
getZoneDefinition
(
i
)
->
UpdateWeighting
(
&
Weight
[
i
][
0
],
AtmoSetup_WidescreenMode
,
AtmoSetup_EdgeWeighting
);
/*
original code from VDR sources... my one is just more flexible?*g*
i = 0;
for (int row = 0; row < CAP_HEIGHT; row++)
{
float row_norm = (float)row / ((float)CAP_HEIGHT - 1.0f); // [0;Height] -> [0;1]
float weight_3 = pow(1.0f - row_norm, AtmoSetup_EdgeWeighting); // top
float weight_4 = pow(row_norm, AtmoSetup_EdgeWeighting); // bottom
for (int column = 0; column < CAP_WIDTH; column++)
{
// if widescreen mode, top and bottom of the picture are not
if ((AtmoSetup_WidescreenMode == 1) && ((row <= CAP_HEIGHT/8) || (row >= (7*CAP_HEIGHT)/8)))
{
Weight[i].channel[0] = Weight[i].channel[1] = Weight[i].channel[2] = Weight[i].channel[3] = Weight[i].channel[4] = 0;
}
else
{
float column_norm = (float)column / ((float)CAP_WIDTH - 1.0f); // [0;Width] -> [0;1]
Weight[i].channel[0] = 255;
Weight[i].channel[1] = (int)(255.0 * (float)pow((1.0 - column_norm), AtmoSetup_EdgeWeighting));
Weight[i].channel[2] = (int)(255.0 * (float)pow(column_norm, AtmoSetup_EdgeWeighting));
Weight[i].channel[3] = (int)(255.0 * (float)weight_3);
Weight[i].channel[4] = (int)(255.0 * (float)weight_4);
}
i++;
}
}
*/
LastEdgeWeighting
=
AtmoSetup_EdgeWeighting
;
LastWidescreenMode
=
AtmoSetup_WidescreenMode
;
}
/***************************************************************************/
/* Hue */
/***************************************************************************/
/*----------------------------*/
/* hue histogram builtup */
/*----------------------------*/
// HSV histogram
long
int
hue_hist
[
ATMO_NUM_CHANNELS
][
h_MAX
+
1
];
// clean histogram
memset
(
&
hue_hist
,
0
,
sizeof
(
hue_hist
));
i
=
0
;
for
(
int
row
=
0
;
row
<
CAP_HEIGHT
;
row
++
)
{
for
(
int
column
=
0
;
column
<
CAP_WIDTH
;
column
++
)
{
// forget black bars: perform calculations only if pixel has some luminosity
if
(
HSV_Img
[
i
].
v
>
10
*
AtmoSetup_DarknessLimit
)
{
// builtup histogram for the 5 channels
for
(
int
channel
=
0
;
channel
<
ATMO_NUM_CHANNELS
;
channel
++
)
{
// Add weight to channel
hue_hist
[
channel
][
HSV_Img
[
i
].
h
]
+=
Weight
[
channel
][
i
]
*
HSV_Img
[
i
].
v
;
}
}
i
++
;
}
}
/*----------------------------*/
/* hue histogram windowing */
/*----------------------------*/
// windowed HSV histogram
long
int
w_hue_hist
[
ATMO_NUM_CHANNELS
][
h_MAX
+
1
];
// clean windowed histogram
memset
(
&
w_hue_hist
,
0
,
sizeof
(
w_hue_hist
));
// steps in each direction; eg. 2 => -2 -1 0 1 2 windowing
int
hue_windowsize
=
pAtmoConfig
->
getLiveView_HueWinSize
();
for
(
i
=
0
;
i
<
h_MAX
+
1
;
i
++
)
// walk through histogram [0;h_MAX]
{
// windowing from -hue_windowsize -> +hue_windowsize
for
(
int
mywin
=
-
hue_windowsize
;
mywin
<
hue_windowsize
+
1
;
mywin
++
)
{
// adressed histogram candlestick
int
myidx
=
i
+
mywin
;
// handle beginning of windowing -> roll back
if
(
myidx
<
0
)
{
myidx
=
myidx
+
h_MAX
+
1
;
}
// handle end of windowing -> roll forward
if
(
myidx
>
h_MAX
)
{
myidx
=
myidx
-
h_MAX
-
1
;
}
// Apply windowing to all 5 channels
for
(
int
channel
=
0
;
channel
<
ATMO_NUM_CHANNELS
;
channel
++
)
{
// apply lite triangular window design with gradient of 10% per discrete step
w_hue_hist
[
channel
][
i
]
+=
hue_hist
[
channel
][
myidx
]
*
((
hue_windowsize
+
1
)
-
abs
(
mywin
));
// apply window
}
}
}
/*--------------------------------------*/
/* analyze histogram for most used hue */
/*--------------------------------------*/
// index of last maximum
static
int
most_used_hue_last
[
ATMO_NUM_CHANNELS
]
=
{
0
,
0
,
0
,
0
,
0
};
// resulting hue for each channel
int
most_used_hue
[
ATMO_NUM_CHANNELS
];
memset
(
&
most_used_hue
,
0
,
sizeof
(
most_used_hue
));
for
(
int
channel
=
0
;
channel
<
ATMO_NUM_CHANNELS
;
channel
++
)
{
int
value
=
0
;
for
(
i
=
0
;
i
<
h_MAX
+
1
;
i
++
)
// walk through histogram
{
if
(
w_hue_hist
[
channel
][
i
]
>
value
)
// if new value bigger then old one
{
most_used_hue
[
channel
]
=
i
;
// remember index
value
=
w_hue_hist
[
channel
][
i
];
// and value
}
}
float
percent
=
(
float
)
w_hue_hist
[
channel
][
most_used_hue_last
[
channel
]]
/
(
float
)
value
;
if
(
percent
>
0.93
f
)
// less than 7% difference?
{
most_used_hue
[
channel
]
=
most_used_hue_last
[
channel
];
// use last index
}
most_used_hue_last
[
channel
]
=
most_used_hue
[
channel
];
// save current index of most used hue
}
/***************************************************************************/
/* saturation */
/***************************************************************************/
// sat histogram
long
int
sat_hist
[
ATMO_NUM_CHANNELS
][
s_MAX
+
1
];
// hue of the pixel we are working at
int
pixel_hue
=
0
;
// clean histogram
memset
(
&
sat_hist
,
0
,
sizeof
(
sat_hist
));
/*--------------------------------------*/
/* saturation histogram builtup */
/*--------------------------------------*/
i
=
0
;
for
(
int
row
=
0
;
row
<
CAP_HEIGHT
;
row
++
)
{
for
(
int
column
=
0
;
column
<
CAP_WIDTH
;
column
++
)
{
// forget black bars: perform calculations only if pixel has some luminosity
if
(
HSV_Img
[
i
].
v
>
10
*
AtmoSetup_DarknessLimit
)
{
// find histogram position for pixel
pixel_hue
=
HSV_Img
[
i
].
h
;
// TODO: brightness calculation(if we require it some time)
for
(
int
channel
=
0
;
channel
<
ATMO_NUM_CHANNELS
;
channel
++
)
{
// only use pixel for histogram if hue is near most_used_hue
if
((
pixel_hue
>
most_used_hue
[
channel
]
-
hue_windowsize
)
&&
(
pixel_hue
<
most_used_hue
[
channel
]
+
hue_windowsize
))
{
// build histogram
// sat_hist[channel][HSV_Img[i].s] += Weight[i].channel[channel] * HSV_Img[i].v;
sat_hist
[
channel
][
HSV_Img
[
i
].
s
]
+=
Weight
[
channel
][
i
]
*
HSV_Img
[
i
].
v
;
}
}
}
i
++
;
}
}
/*--------------------------------------*/
/* saturation histogram windowing */
/*--------------------------------------*/
// windowed HSV histogram
long
int
w_sat_hist
[
ATMO_NUM_CHANNELS
][
s_MAX
+
1
];
// clean windowed histogram
memset
(
&
w_sat_hist
,
0
,
sizeof
(
w_sat_hist
));
// steps in each direction; eg. 2 => -2 -1 0 1 2 windowing
int
sat_windowsize
=
AtmoSetup_SatWinSize
;
// walk through histogram [0;h_MAX]
for
(
i
=
0
;
i
<
s_MAX
+
1
;
i
++
)
{
// windowing from -hue_windowsize -> +hue_windowsize
for
(
int
mywin
=
-
sat_windowsize
;
mywin
<
sat_windowsize
+
1
;
mywin
++
)
{
// adressed histogram candlestick
int
myidx
=
i
+
mywin
;
// handle beginning of windowing -> roll back
if
(
myidx
<
0
)
{
myidx
=
myidx
+
s_MAX
+
1
;
}
// handle end of windowing -> roll forward
if
(
myidx
>
h_MAX
)
{
myidx
=
myidx
-
s_MAX
-
1
;
}
for
(
int
channel
=
0
;
channel
<
ATMO_NUM_CHANNELS
;
channel
++
)
{
/*
apply lite triangular window design with
gradient of 10% per discrete step
*/
w_sat_hist
[
channel
][
i
]
+=
sat_hist
[
channel
][
myidx
]
*
((
sat_windowsize
+
1
)
-
abs
(
mywin
));
// apply window
}
}
}
/*--------------------------------------*/
/* analyze histogram for most used sat */
/*--------------------------------------*/
// resulting sat (most_used_hue) for each channel
int
most_used_sat
[
ATMO_NUM_CHANNELS
];
memset
(
&
most_used_sat
,
0
,
sizeof
(
most_used_sat
));
for
(
int
channel
=
0
;
channel
<
ATMO_NUM_CHANNELS
;
channel
++
)
{
int
value
=
0
;
// walk trough histogram
for
(
i
=
0
;
i
<
s_MAX
+
1
;
i
++
)
{
// if new value bigger then old one
if
(
w_sat_hist
[
channel
][
i
]
>
value
)
{
// remember index
most_used_sat
[
channel
]
=
i
;
// and value
value
=
w_sat_hist
[
channel
][
i
];
}
}
}
/*----------------------------------------------------------*/
/* calculate average brightness within HSV image */
/* uniform Brightness for all channels is calculated */
/*----------------------------------------------------------*/
int
l_counter
=
0
;
// average brightness (value)
long
int
value_avg
=
0
;
// TODO: extract into a function? in sat-histo-built
i
=
0
;
for
(
int
row
=
0
;
row
<
CAP_HEIGHT
;
row
++
)
{
for
(
int
column
=
0
;
column
<
CAP_WIDTH
;
column
++
)
{
// find average value: only use bright pixels for luminance average
if
(
HSV_Img
[
i
].
v
>
10
*
AtmoSetup_DarknessLimit
)
{
// build brightness average
value_avg
+=
HSV_Img
[
i
].
v
;
l_counter
++
;
}
i
++
;
}
}
// calculate brightness average
if
(
l_counter
>
0
)
{
value_avg
=
value_avg
/
l_counter
;
}
else
{
value_avg
=
10
*
AtmoSetup_DarknessLimit
;
}
/*----------------------------*/
/* adjust and copy results */
/*----------------------------*/
tHSVColor
hsv_pixel
;
// storage container for resulting RGB values
tColorPacket
ColorChannels
;
for
(
int
channel
=
0
;
channel
<
ATMO_NUM_CHANNELS
;
channel
++
)
{
// copy values
hsv_pixel
.
h
=
most_used_hue
[
channel
];
hsv_pixel
.
s
=
most_used_sat
[
channel
];
// adjust brightness
int
new_value
=
(
int
)
((
float
)
value_avg
*
((
float
)
AtmoSetup_BrightCorrect
/
100.0
));
if
(
new_value
>
255
)
{
new_value
=
255
;
}
// ensure brightness isn't set too high
hsv_pixel
.
v
=
(
unsigned
char
)
new_value
;
// convert back to rgb
ColorChannels
.
channel
[
channel
]
=
HSV2RGB
(
hsv_pixel
);
}
return
ColorChannels
;
}
tHSVColor
RGB2HSV
(
tRGBColor
color
)
{
int
min
,
max
,
delta
;
int
r
,
g
,
b
;
int
h
=
0
;
tHSVColor
hsv
;
r
=
color
.
r
;
g
=
color
.
g
;
b
=
color
.
b
;
min
=
MIN
(
MIN
(
r
,
g
),
b
);
max
=
MAX
(
MAX
(
r
,
g
),
b
);
delta
=
max
-
min
;
hsv
.
v
=
(
unsigned
char
)
POS_DIV
(
max
*
v_MAX
,
255
);
if
(
delta
==
0
)
// This is a gray, no chroma...
{
h
=
0
;
// HSV results = 0 / 1
hsv
.
s
=
0
;
}
else
// Chromatic data...
{
hsv
.
s
=
(
unsigned
char
)
POS_DIV
(
(
delta
*
s_MAX
)
,
max
);
int
dr
=
(
max
-
r
)
+
3
*
delta
;
int
dg
=
(
max
-
g
)
+
3
*
delta
;
int
db
=
(
max
-
b
)
+
3
*
delta
;
int
divisor
=
6
*
delta
;
if
(
r
==
max
)
{
h
=
POS_DIV
((
(
db
-
dg
)
*
h_MAX
)
,
divisor
);
}
else
if
(
g
==
max
)
{
h
=
POS_DIV
(
((
dr
-
db
)
*
h_MAX
)
,
divisor
)
+
(
h_MAX
/
3
);
}
else
if
(
b
==
max
)
{
h
=
POS_DIV
((
(
dg
-
dr
)
*
h_MAX
)
,
divisor
)
+
(
h_MAX
/
3
)
*
2
;
}
if
(
h
<
0
)
{
h
+=
h_MAX
;
}
if
(
h
>
h_MAX
)
{
h
-=
h_MAX
;
}
}
hsv
.
h
=
(
unsigned
char
)
h
;
return
hsv
;
}
tRGBColor
HSV2RGB
(
tHSVColor
color
)
{
tRGBColor
rgb
=
{
0
,
0
,
0
};
float
h
=
(
float
)
color
.
h
/
(
float
)
h_MAX
;
float
s
=
(
float
)
color
.
s
/
(
float
)
s_MAX
;
float
v
=
(
float
)
color
.
v
/
(
float
)
v_MAX
;
if
(
s
==
0
)
{
rgb
.
r
=
(
int
)((
v
*
255.0
)
+
0.5
);
rgb
.
g
=
rgb
.
r
;
rgb
.
b
=
rgb
.
r
;
}
else
{
h
=
h
*
6.0
f
;
if
(
h
==
6.0
)
{
h
=
0.0
;
}
int
i
=
(
int
)
h
;
float
f
=
h
-
i
;
float
p
=
v
*
(
1.0
f
-
s
);
float
q
=
v
*
(
1.0
f
-
(
s
*
f
));
float
t
=
v
*
(
1.0
f
-
(
s
*
(
1.0
f
-
f
)));
if
(
i
==
0
)
{
rgb
.
r
=
(
int
)((
v
*
255.0
)
+
0.5
);
rgb
.
g
=
(
int
)((
t
*
255.0
)
+
0.5
);
rgb
.
b
=
(
int
)((
p
*
255.0
)
+
0.5
);
}
else
if
(
i
==
1
)
{
rgb
.
r
=
(
int
)((
q
*
255.0
)
+
0.5
);
rgb
.
g
=
(
int
)((
v
*
255.0
)
+
0.5
);
rgb
.
b
=
(
int
)((
p
*
255.0
)
+
0.5
);
}
else
if
(
i
==
2
)
{
rgb
.
r
=
(
int
)((
p
*
255.0
)
+
0.5
);
rgb
.
g
=
(
int
)((
v
*
255.0
)
+
0.5
);
rgb
.
b
=
(
int
)((
t
*
255.0
)
+
0.5
);
}
else
if
(
i
==
3
)
{
rgb
.
r
=
(
int
)((
p
*
255.0
)
+
0.5
);
rgb
.
g
=
(
int
)((
q
*
255.0
)
+
0.5
);
rgb
.
b
=
(
int
)((
v
*
255.0
)
+
0.5
);
}
else
if
(
i
==
4
)
{
rgb
.
r
=
(
int
)((
t
*
255.0
)
+
0.5
);
rgb
.
g
=
(
int
)((
p
*
255.0
)
+
0.5
);
rgb
.
b
=
(
int
)((
v
*
255.0
)
+
0.5
);
}
else
{
rgb
.
r
=
(
int
)((
v
*
255.0
)
+
0.5
);
rgb
.
g
=
(
int
)((
p
*
255.0
)
+
0.5
);
rgb
.
b
=
(
int
)((
q
*
255.0
)
+
0.5
);
}
}
return
rgb
;
}
modules/video_filter/atmo/AtmoCalculations.h
0 → 100644
View file @
1b637157
/*
* AtmoCalculations.h: see calculations.h of the linux version... one to one copy
* calculations.h: calculations needed by the input devices
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoCalculations_h_
#define _AtmoCalculations_h_
#include "AtmoDefs.h"
#include "AtmoConfig.h"
tColorPacket
CalcColorsAnalyzeHSV
(
CAtmoConfig
*
pAtmoConfig
,
tHSVColor
*
HSV_Img
);
tHSVColor
RGB2HSV
(
tRGBColor
color
);
tRGBColor
HSV2RGB
(
tHSVColor
color
);
#endif
modules/video_filter/atmo/AtmoConfig.cpp
0 → 100644
View file @
1b637157
/*
* AtmoConfig.cpp: Class for holding all configuration values of AtmoWin - stores
* the values and retrieves its values from registry
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include <stdio.h>
#include <string.h>
#include "AtmoConfig.h"
/* Import Hint
if somebody Adds new config option this has to be done in the following
files and includes!
AtmoConfig.h -- extend class definition!, and add get... and set... Methods!
so that the real variables are still hidden inside the class!
AtmoConfigRegistry.cpp --> SaveToRegistry();
AtmoConfigRegistry.cpp --> LoadFromRegistry();
AtmoConfig.cpp --> Assign( ... );
*/
CAtmoConfig
::
CAtmoConfig
()
{
// setup basic configruation structures...
m_IsShowConfigDialog
=
0
;
m_eAtmoConnectionType
=
actSerialPort
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
m_ChannelAssignments
[
i
]
=
NULL
;
#if defined (_ATMO_VLC_PLUGIN_)
m_devicename
=
NULL
;
#endif
// load all config values with there defaults
LoadDefaults
();
// CAtmoZoneDefinition *m_ZoneDefinitions[ATMO_NUM_CHANNELS];
// generate default channel parameters which may be loaded later from .bmp files
for
(
int
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
{
m_ZoneDefinitions
[
i
]
=
new
CAtmoZoneDefinition
();
m_ZoneDefinitions
[
i
]
->
setZoneNumber
(
i
);
switch
(
i
)
{
case
0
:
// summary channel
m_ZoneDefinitions
[
i
]
->
Fill
(
255
);
break
;
case
1
:
// left channel
m_ZoneDefinitions
[
i
]
->
FillGradientFromLeft
();
break
;
case
2
:
// right channel
m_ZoneDefinitions
[
i
]
->
FillGradientFromRight
();
break
;
case
3
:
// top channel
m_ZoneDefinitions
[
i
]
->
FillGradientFromTop
();
break
;
case
4
:
// bottom channel
m_ZoneDefinitions
[
i
]
->
FillGradientFromBottom
();
break
;
}
}
}
CAtmoConfig
::~
CAtmoConfig
()
{
// and finally cleanup...
clearAllChannelMappings
();
#if !defined (WIN32)
if
(
m_devicename
)
free
(
m_devicename
);
#endif
}
void
CAtmoConfig
::
LoadDefaults
()
{
// m_eAtmoConnectionType = actSerialPort;
// m_Comport
m_eEffectMode
=
emDisabled
;
m_WhiteAdjustment_Red
=
255
;
m_WhiteAdjustment_Green
=
255
;
m_WhiteAdjustment_Blue
=
255
;
m_UseSoftwareWhiteAdj
=
1
;
m_ColorChanger_iSteps
=
50
;
m_ColorChanger_iDelay
=
25
;
m_LrColorChanger_iSteps
=
50
;
m_LrColorChanger_iDelay
=
25
;
m_IsSetShutdownColor
=
1
;
m_ShutdownColor_Red
=
0
;
m_ShutdownColor_Green
=
0
;
m_ShutdownColor_Blue
=
0
;
m_StaticColor_Red
=
127
;
// ??
m_StaticColor_Green
=
192
;
m_StaticColor_Blue
=
255
;
m_LiveViewFilterMode
=
afmCombined
;
m_LiveViewFilter_PercentNew
=
50
;
m_LiveViewFilter_MeanLength
=
300
;
m_LiveViewFilter_MeanThreshold
=
40
;
m_LiveView_EdgeWeighting
=
8
;
m_LiveView_BrightCorrect
=
100
;
m_LiveView_DarknessLimit
=
5
;
m_LiveView_HueWinSize
=
3
;
m_LiveView_SatWinSize
=
3
;
m_LiveView_WidescreenMode
=
0
;
m_LiveView_HOverscanBorder
=
0
;
m_LiveView_VOverscanBorder
=
0
;
m_LiveView_DisplayNr
=
0
;
m_LiveView_FrameDelay
=
0
;
m_Hardware_global_gamma
=
128
;
m_Hardware_global_contrast
=
100
;
m_Hardware_contrast_red
=
100
;
m_Hardware_contrast_green
=
100
;
m_Hardware_contrast_blue
=
100
;
m_Hardware_gamma_red
=
22
;
m_Hardware_gamma_green
=
22
;
m_Hardware_gamma_blue
=
22
;
clearAllChannelMappings
();
m_CurrentChannelAssignment
=
0
;
tChannelAssignment
*
temp
=
temp
=
new
tChannelAssignment
;
temp
->
system
=
true
;
for
(
int
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
temp
->
mappings
[
i
]
=
i
;
strcpy
(
temp
->
name
,
"Standard"
);
this
->
m_ChannelAssignments
[
0
]
=
temp
;
}
void
CAtmoConfig
::
Assign
(
CAtmoConfig
*
pAtmoConfigSrc
)
{
#if defined(_ATMO_VLC_PLUGIN_)
this
->
setSerialDevice
(
pAtmoConfigSrc
->
getSerialDevice
());
#else
this
->
m_Comport
=
pAtmoConfigSrc
->
m_Comport
;
#endif
this
->
m_eAtmoConnectionType
=
pAtmoConfigSrc
->
m_eAtmoConnectionType
;
this
->
m_eEffectMode
=
pAtmoConfigSrc
->
m_eEffectMode
;
this
->
m_WhiteAdjustment_Red
=
pAtmoConfigSrc
->
m_WhiteAdjustment_Red
;
this
->
m_WhiteAdjustment_Green
=
pAtmoConfigSrc
->
m_WhiteAdjustment_Green
;
this
->
m_WhiteAdjustment_Blue
=
pAtmoConfigSrc
->
m_WhiteAdjustment_Blue
;
this
->
m_UseSoftwareWhiteAdj
=
pAtmoConfigSrc
->
m_UseSoftwareWhiteAdj
;
this
->
m_IsSetShutdownColor
=
pAtmoConfigSrc
->
m_IsSetShutdownColor
;
this
->
m_ShutdownColor_Red
=
pAtmoConfigSrc
->
m_ShutdownColor_Red
;
this
->
m_ShutdownColor_Green
=
pAtmoConfigSrc
->
m_ShutdownColor_Green
;
this
->
m_ShutdownColor_Blue
=
pAtmoConfigSrc
->
m_ShutdownColor_Blue
;
this
->
m_ColorChanger_iSteps
=
pAtmoConfigSrc
->
m_ColorChanger_iSteps
;
this
->
m_ColorChanger_iDelay
=
pAtmoConfigSrc
->
m_ColorChanger_iDelay
;
this
->
m_LrColorChanger_iSteps
=
pAtmoConfigSrc
->
m_LrColorChanger_iSteps
;
this
->
m_LrColorChanger_iDelay
=
pAtmoConfigSrc
->
m_LrColorChanger_iDelay
;
this
->
m_StaticColor_Red
=
pAtmoConfigSrc
->
m_StaticColor_Red
;
this
->
m_StaticColor_Green
=
pAtmoConfigSrc
->
m_StaticColor_Green
;
this
->
m_StaticColor_Blue
=
pAtmoConfigSrc
->
m_StaticColor_Blue
;
this
->
m_LiveViewFilterMode
=
pAtmoConfigSrc
->
m_LiveViewFilterMode
;
this
->
m_LiveViewFilter_PercentNew
=
pAtmoConfigSrc
->
m_LiveViewFilter_PercentNew
;
this
->
m_LiveViewFilter_MeanLength
=
pAtmoConfigSrc
->
m_LiveViewFilter_MeanLength
;
this
->
m_LiveViewFilter_MeanThreshold
=
pAtmoConfigSrc
->
m_LiveViewFilter_MeanThreshold
;
this
->
m_LiveView_EdgeWeighting
=
pAtmoConfigSrc
->
m_LiveView_EdgeWeighting
;
this
->
m_LiveView_BrightCorrect
=
pAtmoConfigSrc
->
m_LiveView_BrightCorrect
;
this
->
m_LiveView_DarknessLimit
=
pAtmoConfigSrc
->
m_LiveView_DarknessLimit
;
this
->
m_LiveView_HueWinSize
=
pAtmoConfigSrc
->
m_LiveView_HueWinSize
;
this
->
m_LiveView_SatWinSize
=
pAtmoConfigSrc
->
m_LiveView_SatWinSize
;
this
->
m_LiveView_WidescreenMode
=
pAtmoConfigSrc
->
m_LiveView_WidescreenMode
;
this
->
m_LiveView_HOverscanBorder
=
pAtmoConfigSrc
->
m_LiveView_HOverscanBorder
;
this
->
m_LiveView_VOverscanBorder
=
pAtmoConfigSrc
->
m_LiveView_VOverscanBorder
;
this
->
m_LiveView_DisplayNr
=
pAtmoConfigSrc
->
m_LiveView_DisplayNr
;
this
->
m_LiveView_FrameDelay
=
pAtmoConfigSrc
->
m_LiveView_FrameDelay
;
clearChannelMappings
();
for
(
int
i
=
1
;
i
<
pAtmoConfigSrc
->
getNumChannelAssignments
();
i
++
)
{
tChannelAssignment
*
ta
=
pAtmoConfigSrc
->
m_ChannelAssignments
[
i
];
if
(
ta
!=
NULL
)
{
tChannelAssignment
*
dest
=
this
->
m_ChannelAssignments
[
i
];
if
(
dest
==
NULL
)
{
dest
=
new
tChannelAssignment
;
this
->
m_ChannelAssignments
[
i
]
=
dest
;
}
memcpy
(
dest
,
ta
,
sizeof
(
tChannelAssignment
));
}
}
}
int
CAtmoConfig
::
getNumChannelAssignments
()
{
int
z
=
0
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
if
(
this
->
m_ChannelAssignments
[
i
]
!=
NULL
)
z
++
;
return
z
;
}
void
CAtmoConfig
::
clearChannelMappings
()
{
for
(
int
i
=
1
;
i
<
10
;
i
++
)
{
tChannelAssignment
*
ca
=
m_ChannelAssignments
[
i
];
if
(
ca
!=
NULL
)
delete
ca
;
m_ChannelAssignments
[
i
]
=
NULL
;
}
}
void
CAtmoConfig
::
clearAllChannelMappings
()
{
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
tChannelAssignment
*
ca
=
m_ChannelAssignments
[
i
];
if
(
ca
!=
NULL
)
delete
ca
;
m_ChannelAssignments
[
i
]
=
NULL
;
}
}
void
CAtmoConfig
::
AddChannelAssignment
(
tChannelAssignment
*
ta
)
{
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
if
(
m_ChannelAssignments
[
i
]
==
NULL
)
{
m_ChannelAssignments
[
i
]
=
ta
;
break
;
}
}
}
void
CAtmoConfig
::
SetChannelAssignment
(
int
index
,
tChannelAssignment
*
ta
)
{
if
(
m_ChannelAssignments
[
index
]
!=
NULL
)
delete
m_ChannelAssignments
[
index
];
m_ChannelAssignments
[
index
]
=
ta
;
}
CAtmoZoneDefinition
*
CAtmoConfig
::
getZoneDefinition
(
int
zoneIndex
)
{
if
(
zoneIndex
<
0
)
return
NULL
;
if
(
zoneIndex
>=
ATMO_NUM_CHANNELS
)
return
NULL
;
return
m_ZoneDefinitions
[
zoneIndex
];
}
modules/video_filter/atmo/AtmoConfig.h
0 → 100644
View file @
1b637157
/*
* AtmoConfig.h: Class for holding all configuration values of AtmoWin
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoConfig_h_
#define _AtmoConfig_h_
#include "AtmoDefs.h"
#include "AtmoZoneDefinition.h"
#if defined(_ATMO_VLC_PLUGIN_)
# include <stdlib.h>
# include <string.h>
#endif
class
CAtmoConfig
{
protected:
int
m_IsShowConfigDialog
;
#if defined(_ATMO_VLC_PLUGIN_)
char
*
m_devicename
;
#else
int
m_Comport
;
#endif
enum
AtmoConnectionType
m_eAtmoConnectionType
;
enum
EffectMode
m_eEffectMode
;
protected:
ATMO_BOOL
m_UseSoftwareWhiteAdj
;
int
m_WhiteAdjustment_Red
;
int
m_WhiteAdjustment_Green
;
int
m_WhiteAdjustment_Blue
;
protected:
int
m_IsSetShutdownColor
;
int
m_ShutdownColor_Red
;
int
m_ShutdownColor_Green
;
int
m_ShutdownColor_Blue
;
protected:
/* Config Values for Color Changer */
int
m_ColorChanger_iSteps
;
int
m_ColorChanger_iDelay
;
protected:
/* Config values for the primitive Left Right Color Changer */
int
m_LrColorChanger_iSteps
;
int
m_LrColorChanger_iDelay
;
protected:
/* the static background color */
int
m_StaticColor_Red
;
int
m_StaticColor_Green
;
int
m_StaticColor_Blue
;
protected:
/*
one for System + 9 for userdefined channel
assignments (will it be enough?)
*/
tChannelAssignment
*
m_ChannelAssignments
[
10
];
int
m_CurrentChannelAssignment
;
protected:
CAtmoZoneDefinition
*
m_ZoneDefinitions
[
ATMO_NUM_CHANNELS
];
protected:
/* Live View Parameters (most interesting) */
AtmoFilterMode
m_LiveViewFilterMode
;
int
m_LiveViewFilter_PercentNew
;
int
m_LiveViewFilter_MeanLength
;
int
m_LiveViewFilter_MeanThreshold
;
// weighting of distance to edge
int
m_LiveView_EdgeWeighting
;
// = 8;
// brightness correction
int
m_LiveView_BrightCorrect
;
// = 100;
// darkness limit (pixels below this value will be ignored)
int
m_LiveView_DarknessLimit
;
// = 5;
// Windowing size for hue histogram building
int
m_LiveView_HueWinSize
;
// = 3;
// Windowing size for sat histogram building
int
m_LiveView_SatWinSize
;
// = 3;
/*
special (hack) for ignorning black borders durring
playback of letterboxed material on a 16:9 output device
*/
int
m_LiveView_WidescreenMode
;
// = 0
// border from source image which should be ignored
// the values are only used by the Win32 GDI Screen capture
int
m_LiveView_HOverscanBorder
;
int
m_LiveView_VOverscanBorder
;
int
m_LiveView_DisplayNr
;
/*
a special delay to get the light in sync with the video
was required because the frames will pass my VLC filter some [ms]
before they become visible on screen with this delay - screenoutput
and light timing could be "synchronized"
*/
int
m_LiveView_FrameDelay
;
protected:
/* values of the last hardware white adjustment (only for hardware with new firmware) */
int
m_Hardware_global_gamma
;
int
m_Hardware_global_contrast
;
int
m_Hardware_contrast_red
;
int
m_Hardware_contrast_green
;
int
m_Hardware_contrast_blue
;
int
m_Hardware_gamma_red
;
int
m_Hardware_gamma_green
;
int
m_Hardware_gamma_blue
;
public:
CAtmoConfig
();
virtual
~
CAtmoConfig
();
virtual
void
SaveSettings
()
{}
virtual
void
LoadSettings
()
{};
void
LoadDefaults
();
/*
function to copy the values of one configuration object to another
will be used in windows settings dialog as backup if the user
presses cancel
*/
void
Assign
(
CAtmoConfig
*
pAtmoConfigSrc
);
public:
int
isShowConfigDialog
()
{
return
m_IsShowConfigDialog
;
}
void
setShowConfigDialog
(
int
value
)
{
m_IsShowConfigDialog
=
value
;
}
#if defined(_ATMO_VLC_PLUGIN_)
char
*
getSerialDevice
()
{
return
m_devicename
;
}
void
setSerialDevice
(
char
*
newdevice
)
{
if
(
m_devicename
)
free
(
m_devicename
);
if
(
newdevice
)
m_devicename
=
strdup
(
newdevice
);
else
m_devicename
=
NULL
;
}
#else
int
getComport
()
{
return
m_Comport
;
}
void
setComport
(
int
value
)
{
m_Comport
=
value
;
}
#endif
int
getWhiteAdjustment_Red
()
{
return
m_WhiteAdjustment_Red
;
}
void
setWhiteAdjustment_Red
(
int
value
)
{
m_WhiteAdjustment_Red
=
value
;
}
int
getWhiteAdjustment_Green
()
{
return
m_WhiteAdjustment_Green
;
}
void
setWhiteAdjustment_Green
(
int
value
)
{
m_WhiteAdjustment_Green
=
value
;
}
int
getWhiteAdjustment_Blue
()
{
return
m_WhiteAdjustment_Blue
;
}
void
setWhiteAdjustment_Blue
(
int
value
)
{
m_WhiteAdjustment_Blue
=
value
;
}
ATMO_BOOL
isUseSoftwareWhiteAdj
()
{
return
m_UseSoftwareWhiteAdj
;
}
void
setUseSoftwareWhiteAdj
(
ATMO_BOOL
value
)
{
m_UseSoftwareWhiteAdj
=
value
;
}
int
isSetShutdownColor
()
{
return
m_IsSetShutdownColor
;
}
void
SetSetShutdownColor
(
int
value
)
{
m_IsSetShutdownColor
=
value
;
}
int
getShutdownColor_Red
()
{
return
m_ShutdownColor_Red
;
}
void
setShutdownColor_Red
(
int
value
)
{
m_ShutdownColor_Red
=
value
;
}
int
getShutdownColor_Green
()
{
return
m_ShutdownColor_Green
;
}
void
setShutdownColor_Green
(
int
value
)
{
m_ShutdownColor_Green
=
value
;
}
int
getShutdownColor_Blue
()
{
return
m_ShutdownColor_Blue
;
}
void
setShutdownColor_Blue
(
int
value
)
{
m_ShutdownColor_Blue
=
value
;
}
int
getColorChanger_iSteps
()
{
return
m_ColorChanger_iSteps
;
}
void
setColorChanger_iSteps
(
int
value
)
{
m_ColorChanger_iSteps
=
value
;
}
int
getColorChanger_iDelay
()
{
return
m_ColorChanger_iDelay
;
}
void
setColorChanger_iDelay
(
int
value
)
{
m_ColorChanger_iDelay
=
value
;
}
int
getLrColorChanger_iSteps
()
{
return
m_LrColorChanger_iSteps
;
}
void
setLrColorChanger_iSteps
(
int
value
)
{
m_LrColorChanger_iSteps
=
value
;
}
int
getLrColorChanger_iDelay
()
{
return
m_LrColorChanger_iDelay
;
}
void
setLrColorChanger_iDelay
(
int
value
)
{
m_LrColorChanger_iDelay
=
value
;
}
int
getStaticColor_Red
()
{
return
m_StaticColor_Red
;
}
void
setStaticColor_Red
(
int
value
)
{
m_StaticColor_Red
=
value
;
}
int
getStaticColor_Green
()
{
return
m_StaticColor_Green
;
}
void
setStaticColor_Green
(
int
value
)
{
m_StaticColor_Green
=
value
;
}
int
getStaticColor_Blue
()
{
return
m_StaticColor_Blue
;
}
void
setStaticColor_Blue
(
int
value
)
{
m_StaticColor_Blue
=
value
;
}
AtmoConnectionType
getConnectionType
()
{
return
m_eAtmoConnectionType
;
}
void
setConnectionType
(
AtmoConnectionType
value
)
{
m_eAtmoConnectionType
=
value
;
}
EffectMode
getEffectMode
()
{
return
m_eEffectMode
;
}
void
setEffectMode
(
EffectMode
value
)
{
m_eEffectMode
=
value
;
}
AtmoFilterMode
getLiveViewFilterMode
()
{
return
m_LiveViewFilterMode
;
}
void
setLiveViewFilterMode
(
AtmoFilterMode
value
)
{
m_LiveViewFilterMode
=
value
;
}
int
getLiveViewFilter_PercentNew
()
{
return
m_LiveViewFilter_PercentNew
;
}
void
setLiveViewFilter_PercentNew
(
int
value
)
{
m_LiveViewFilter_PercentNew
=
value
;
}
int
getLiveViewFilter_MeanLength
()
{
return
m_LiveViewFilter_MeanLength
;
}
void
setLiveViewFilter_MeanLength
(
int
value
)
{
m_LiveViewFilter_MeanLength
=
value
;
}
int
getLiveViewFilter_MeanThreshold
()
{
return
m_LiveViewFilter_MeanThreshold
;
}
void
setLiveViewFilter_MeanThreshold
(
int
value
)
{
m_LiveViewFilter_MeanThreshold
=
value
;
}
int
getLiveView_EdgeWeighting
()
{
return
m_LiveView_EdgeWeighting
;
}
void
setLiveView_EdgeWeighting
(
int
value
)
{
m_LiveView_EdgeWeighting
=
value
;
}
int
getLiveView_BrightCorrect
()
{
return
m_LiveView_BrightCorrect
;
}
void
setLiveView_BrightCorrect
(
int
value
)
{
m_LiveView_BrightCorrect
=
value
;
}
int
getLiveView_DarknessLimit
()
{
return
m_LiveView_DarknessLimit
;
}
void
setLiveView_DarknessLimit
(
int
value
)
{
m_LiveView_DarknessLimit
=
value
;
}
int
getLiveView_HueWinSize
()
{
return
m_LiveView_HueWinSize
;
}
void
setLiveView_HueWinSize
(
int
value
)
{
m_LiveView_HueWinSize
=
value
;
}
int
getLiveView_SatWinSize
()
{
return
m_LiveView_SatWinSize
;
}
void
setLiveView_SatWinSize
(
int
value
)
{
m_LiveView_SatWinSize
=
value
;
}
int
getLiveView_WidescreenMode
()
{
return
m_LiveView_WidescreenMode
;
}
void
setLiveView_WidescreenMode
(
int
value
)
{
m_LiveView_WidescreenMode
=
value
;
}
int
getLiveView_HOverscanBorder
()
{
return
m_LiveView_HOverscanBorder
;
}
void
setLiveView_HOverscanBorder
(
int
value
)
{
m_LiveView_HOverscanBorder
=
value
;
}
int
getLiveView_VOverscanBorder
()
{
return
m_LiveView_VOverscanBorder
;
}
void
setLiveView_VOverscanBorder
(
int
value
)
{
m_LiveView_VOverscanBorder
=
value
;
}
int
getLiveView_DisplayNr
()
{
return
m_LiveView_DisplayNr
;
}
void
setLiveView_DisplayNr
(
int
value
)
{
m_LiveView_DisplayNr
=
value
;
}
int
getLiveView_FrameDelay
()
{
return
m_LiveView_FrameDelay
;
}
void
setLiveView_FrameDelay
(
int
delay
)
{
m_LiveView_FrameDelay
=
delay
;
}
int
getHardware_global_gamma
()
{
return
m_Hardware_global_gamma
;
}
void
setHardware_global_gamma
(
int
value
)
{
m_Hardware_global_gamma
=
value
;
}
int
getHardware_global_contrast
()
{
return
m_Hardware_global_contrast
;
}
void
setHardware_global_contrast
(
int
value
)
{
m_Hardware_global_contrast
=
value
;
}
int
getHardware_contrast_red
()
{
return
m_Hardware_contrast_red
;
}
void
setHardware_contrast_red
(
int
value
)
{
m_Hardware_contrast_red
=
value
;
}
int
getHardware_contrast_green
()
{
return
m_Hardware_contrast_green
;
}
void
setHardware_contrast_green
(
int
value
)
{
m_Hardware_contrast_green
=
value
;
}
int
getHardware_contrast_blue
()
{
return
m_Hardware_contrast_blue
;
}
void
setHardware_contrast_blue
(
int
value
)
{
m_Hardware_contrast_blue
=
value
;
}
int
getHardware_gamma_red
()
{
return
m_Hardware_gamma_red
;
}
void
setHardware_gamma_red
(
int
value
)
{
m_Hardware_gamma_red
=
value
;
}
int
getHardware_gamma_green
()
{
return
m_Hardware_gamma_green
;
}
void
setHardware_gamma_green
(
int
value
)
{
m_Hardware_gamma_green
=
value
;
}
int
getHardware_gamma_blue
()
{
return
m_Hardware_gamma_blue
;
}
void
setHardware_gamma_blue
(
int
value
)
{
m_Hardware_gamma_blue
=
value
;
}
tChannelAssignment
*
getChannelAssignment
(
int
nummer
)
{
return
this
->
m_ChannelAssignments
[
nummer
];
}
int
getCurrentChannelAssignment
()
{
return
m_CurrentChannelAssignment
;
}
void
setCurrentChannelAssignment
(
int
index
)
{
m_CurrentChannelAssignment
=
index
;
}
int
getNumChannelAssignments
();
void
clearChannelMappings
();
void
clearAllChannelMappings
();
void
AddChannelAssignment
(
tChannelAssignment
*
ta
);
void
SetChannelAssignment
(
int
index
,
tChannelAssignment
*
ta
);
CAtmoZoneDefinition
*
getZoneDefinition
(
int
zoneIndex
);
};
#endif
modules/video_filter/atmo/AtmoConnection.cpp
0 → 100644
View file @
1b637157
/*
* AtmoConnection.cpp: generic/abstract class defining all methods for the
* communication with the hardware
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoConnection.h"
CAtmoConnection
::
CAtmoConnection
(
CAtmoConfig
*
cfg
)
{
this
->
m_pAtmoConfig
=
cfg
;
if
(
cfg
->
getNumChannelAssignments
()
>
0
)
{
tChannelAssignment
*
ca
=
cfg
->
getChannelAssignment
(
0
);
for
(
int
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
{
m_ChannelAssignment
[
i
]
=
ca
->
mappings
[
i
];
}
}
else
{
for
(
int
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
{
m_ChannelAssignment
[
i
]
=
i
;
}
}
}
void
CAtmoConnection
::
SetChannelAssignment
(
tChannelAssignment
*
ca
)
{
for
(
int
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
{
m_ChannelAssignment
[
i
]
=
ca
->
mappings
[
i
];
}
}
CAtmoConnection
::~
CAtmoConnection
(
void
)
{
if
(
isOpen
())
CloseConnection
();
}
modules/video_filter/atmo/AtmoConnection.h
0 → 100644
View file @
1b637157
/*
* AtmoConnection.h: generic/abstract class defining all methods for the
* communication with the hardware
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoConnection_h_
#define _AtmoConnection_h_
#include "AtmoDefs.h"
#include "AtmoConfig.h"
class
CAtmoConnection
{
protected:
CAtmoConfig
*
m_pAtmoConfig
;
int
m_ChannelAssignment
[
ATMO_NUM_CHANNELS
];
public:
CAtmoConnection
(
CAtmoConfig
*
cfg
);
virtual
~
CAtmoConnection
(
void
);
virtual
ATMO_BOOL
OpenConnection
()
{
return
false
;
}
virtual
void
CloseConnection
()
{};
virtual
ATMO_BOOL
isOpen
(
void
)
{
return
false
;
}
virtual
ATMO_BOOL
SendData
(
unsigned
char
numChannels
,
int
red
[],
int
green
[],
int
blue
[])
{
return
false
;
}
virtual
ATMO_BOOL
SendData
(
tColorPacket
data
)
{
return
false
;
}
virtual
ATMO_BOOL
setChannelColor
(
int
channel
,
tRGBColor
color
)
{
return
false
;
}
virtual
ATMO_BOOL
setChannelValues
(
int
numValues
,
unsigned
char
*
channel_values
)
{
return
false
;
}
virtual
ATMO_BOOL
HardwareWhiteAdjust
(
int
global_gamma
,
int
global_contrast
,
int
contrast_red
,
int
contrast_green
,
int
contrast_blue
,
int
gamma_red
,
int
gamma_green
,
int
gamma_blue
,
ATMO_BOOL
storeToEeprom
)
{
return
false
;
}
virtual
void
SetChannelAssignment
(
tChannelAssignment
*
ca
);
};
#endif
modules/video_filter/atmo/AtmoDefs.h
0 → 100644
View file @
1b637157
/*
* AtmoDefs.h: a lot of globals defines for the color computation - most of this file
* is an one to one copy of "defs.h" from Atmo VDR Plugin
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoDefs_h_
#define _AtmoDefs_h_
#if defined(__LIBVLC__)
# include "config.h"
# include <vlc/vlc.h>
/* some things need to be changed if this code is used inside VideoLan Filter Module */
# define _ATMO_VLC_PLUGIN_
# define ATMO_BOOL vlc_bool_t
# define ATMO_TRUE VLC_TRUE
# define ATMO_FALSE VLC_FALSE
#else
typedef
int
ATMO_BOOL
;
# define ATMO_TRUE 1
# define ATMO_FALSE 0
#endif
#if !defined(WIN32)
#define INVALID_HANDLE_VALUE -1
typedef
int
HANDLE
;
typedef
unsigned
long
DWORD
;
#define BI_RGB 0L
#if !defined(_BITMAPFILEHEADER_)
#define _BITMAPFILEHEADER_
typedef
struct
#ifdef HAVE_ATTRIBUTE_PACKED
__attribute__
((
__packed__
))
#endif
{
uint16_t
bfType
;
uint32_t
bfSize
;
uint16_t
bfReserved1
;
uint16_t
bfReserved2
;
uint32_t
bfOffBits
;
}
BITMAPFILEHEADER
,
*
LPBITMAPFILEHEADER
,
*
PBITMAPFILEHEADER
;
#endif
#endif
#define FCC(ch4) ((((DWORD)(ch4) & 0xFF) << 24) | \
(((DWORD)(ch4) & 0xFF00) << 8) | \
(((DWORD)(ch4) & 0xFF0000) >> 8) | \
(((DWORD)(ch4) & 0xFF000000) >> 24))
// maximal Anzahl Kanle...
#define ATMO_NUM_CHANNELS 5
// capture width/height
#define CAP_WIDTH 64
#define CAP_HEIGHT 48
// imagesize
#define IMAGE_SIZE (CAP_WIDTH * CAP_HEIGHT)
enum
AtmoConnectionType
{
actSerialPort
=
0
,
actDummy
=
1
,
actDMX
=
2
};
static
const
char
*
AtmoDeviceTypes
[]
=
{
"Atmo"
,
"Dummy"
,
"DMX"
};
#define ATMO_DEVICE_COUNT 3
#if defined(_ATMO_VLC_PLUGIN_)
enum
EffectMode
{
emUndefined
=
-
1
,
emDisabled
=
0
,
emStaticColor
=
1
,
emLivePicture
=
2
};
#else
enum
EffectMode
{
emUndefined
=
-
1
,
emDisabled
=
0
,
emStaticColor
=
1
,
emLivePicture
=
2
,
emColorChange
=
3
,
emLrColorChange
=
4
};
#endif
enum
AtmoFilterMode
{
afmNoFilter
,
afmCombined
,
afmPercent
};
typedef
struct
{
ATMO_BOOL
system
;
char
name
[
64
];
int
mappings
[
ATMO_NUM_CHANNELS
];
}
tChannelAssignment
;
// --- tRGBColor --------------------------------------------------------------
typedef
struct
{
unsigned
char
r
,
g
,
b
;
}
tRGBColor
;
// --- tColorPacket -----------------------------------------------------------
typedef
struct
{
tRGBColor
channel
[
ATMO_NUM_CHANNELS
];
}
tColorPacket
;
// --- tRGBColorLongInt -------------------------------------------------------
typedef
struct
{
long
int
r
,
g
,
b
;
}
tRGBColorLongInt
;
// --- tColorPacketLongInt ----------------------------------------------------
typedef
struct
{
tRGBColorLongInt
channel
[
ATMO_NUM_CHANNELS
];
}
tColorPacketLongInt
;
// --- tWeightPacket ----------------------------------------------------------
typedef
struct
{
int
channel
[
ATMO_NUM_CHANNELS
];
}
tWeightPacket
;
// --- tHSVColor --------------------------------------------------------------
typedef
struct
{
unsigned
char
h
,
s
,
v
;
}
tHSVColor
;
#endif
modules/video_filter/atmo/AtmoDynData.cpp
0 → 100644
View file @
1b637157
/*
* AtmoDynData.cpp: class for holding all variable data - which may be
* passed between function calls, into threads instead of the use
* of global variables
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoDynData.h"
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoDynData
::
CAtmoDynData
(
vlc_object_t
*
p_atmo_filter
,
CAtmoConfig
*
pAtmoConfig
)
{
this
->
p_atmo_filter
=
p_atmo_filter
;
this
->
m_pAtmoConfig
=
pAtmoConfig
;
this
->
m_pAtmoConnection
=
NULL
;
this
->
m_pCurrentEffectThread
=
NULL
;
vlc_mutex_init
(
p_atmo_filter
,
&
m_lock
);
}
#else
CAtmoDynData
::
CAtmoDynData
(
HINSTANCE
hInst
,
CAtmoConfig
*
pAtmoConfig
,
CAtmoDisplays
*
pAtmoDisplays
)
{
this
->
m_pAtmoConfig
=
pAtmoConfig
;
this
->
m_pAtmoDisplays
=
pAtmoDisplays
;
this
->
m_pAtmoConnection
=
NULL
;
this
->
m_pCurrentEffectThread
=
NULL
;
this
->
m_hInst
=
hInst
;
InitializeCriticalSection
(
&
m_RemoteCallCriticalSection
);
}
#endif
CAtmoDynData
::~
CAtmoDynData
(
void
)
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_destroy
(
&
m_lock
);
#else
DeleteCriticalSection
(
&
m_RemoteCallCriticalSection
);
#endif
}
void
CAtmoDynData
::
LockCriticalSection
()
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock
(
&
m_lock
);
#else
EnterCriticalSection
(
&
m_RemoteCallCriticalSection
);
#endif
}
void
CAtmoDynData
::
UnLockCriticalSection
()
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_unlock
(
&
m_lock
);
#else
LeaveCriticalSection
(
&
m_RemoteCallCriticalSection
);
#endif
}
modules/video_filter/atmo/AtmoDynData.h
0 → 100644
View file @
1b637157
/*
* AtmoDynData.h: class for holding all variable data - which may be passed
* between function calls, into threads instead of the use of global variables
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoDynData_h_
#define _AtmoDynData_h_
#include "AtmoDefs.h"
#include "AtmoThread.h"
#include "AtmoConfig.h"
#include "AtmoConnection.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include "AtmoDisplays.h"
#else
# include <vlc/vlc.h>
# include <vlc_threads_funcs.h>
#endif
/*
the idea behind this class is to avoid a mix of persistent value and
volatile values in CAtmoConfig class because some parameters and variables
exists only for the current process and won't be stored to the registry
(Simple thought its a container... )
you ask? why I didn't used a struct for it? ..mmh I like classes?
Problem: MultiThreading! todo semaphore, mutex!
Allways stop the current effect Thread before changing AtmoConnection or
AtmoConfig!
*/
class
CAtmoDynData
{
private:
CThread
*
m_pCurrentEffectThread
;
CAtmoConnection
*
m_pAtmoConnection
;
CAtmoConfig
*
m_pAtmoConfig
;
#if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDisplays
*
m_pAtmoDisplays
;
HINSTANCE
m_hInst
;
CRITICAL_SECTION
m_RemoteCallCriticalSection
;
#else
vlc_object_t
*
p_atmo_filter
;
vlc_mutex_t
m_lock
;
#endif
public:
#if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDynData
(
HINSTANCE
hInst
,
CAtmoConfig
*
pAtmoConfig
,
CAtmoDisplays
*
pAtmoDisplays
);
#else
CAtmoDynData
(
vlc_object_t
*
p_atmo_filter
,
CAtmoConfig
*
pAtmoConfig
);
#endif
~
CAtmoDynData
(
void
);
CThread
*
getEffectThread
()
{
return
m_pCurrentEffectThread
;
}
void
setEffectThread
(
CThread
*
value
)
{
m_pCurrentEffectThread
=
value
;
}
CAtmoConnection
*
getAtmoConnection
()
{
return
m_pAtmoConnection
;
}
void
setAtmoConnection
(
CAtmoConnection
*
value
)
{
m_pAtmoConnection
=
value
;
}
CAtmoConfig
*
getAtmoConfig
()
{
return
m_pAtmoConfig
;
}
#if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDisplays
*
getAtmoDisplays
()
{
return
m_pAtmoDisplays
;
}
HINSTANCE
getHinstance
()
{
return
m_hInst
;
}
#else
vlc_object_t
*
getAtmoFilter
()
{
return
p_atmo_filter
;
}
#endif
void
LockCriticalSection
();
void
UnLockCriticalSection
();
};
#endif
modules/video_filter/atmo/AtmoExternalCaptureInput.cpp
0 → 100644
View file @
1b637157
/*
* AtmoExternalCaptureInput.cpp: Datasource which gets its data via a COM object call
* or some other external method.
*
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoExternalCaptureInput.h"
#include "AtmoTools.h"
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoExternalCaptureInput
::
CAtmoExternalCaptureInput
(
CAtmoDynData
*
pAtmoDynData
)
:
CAtmoInput
(
pAtmoDynData
),
CThread
(
pAtmoDynData
->
getAtmoFilter
())
{
m_pCurrentFramePixels
=
NULL
;
vlc_cond_init
(
this
->
m_pAtmoThread
,
&
m_WakeupCond
);
vlc_mutex_init
(
m_pAtmoThread
,
&
m_WakeupLock
);
msg_Dbg
(
m_pAtmoThread
,
"CAtmoExternalCaptureInput created."
);
}
#else
CAtmoExternalCaptureInput
::
CAtmoExternalCaptureInput
(
CAtmoDynData
*
pAtmoDynData
)
:
CAtmoInput
(
pAtmoDynData
)
{
m_hWakeupEvent
=
CreateEvent
(
NULL
,
ATMO_FALSE
,
ATMO_FALSE
,
NULL
);
m_pCurrentFramePixels
=
NULL
;
}
#endif
CAtmoExternalCaptureInput
::~
CAtmoExternalCaptureInput
(
void
)
{
/* if there is still an unprocessed bufferpicture do kill it */
if
(
m_pCurrentFramePixels
!=
NULL
)
free
(
m_pCurrentFramePixels
);
#if defined(_ATMO_VLC_PLUGIN_)
vlc_cond_destroy
(
&
m_WakeupCond
);
vlc_mutex_destroy
(
&
m_WakeupLock
);
msg_Dbg
(
m_pAtmoThread
,
"CAtmoExternalCaptureInput destroyed."
);
#else
CloseHandle
(
m_hWakeupEvent
);
#endif
}
ATMO_BOOL
CAtmoExternalCaptureInput
::
Open
()
{
this
->
Run
();
return
ATMO_TRUE
;
}
// Closes the input-device.
// Returns true if the input-device was closed successfully.
ATMO_BOOL
CAtmoExternalCaptureInput
::
Close
(
void
)
{
this
->
Terminate
();
return
ATMO_TRUE
;
}
tColorPacket
CAtmoExternalCaptureInput
::
GetColorPacket
(
void
)
{
return
this
->
m_ColorPacket
;
}
/*
this method will be called from another thread or possible the COM Server to feed
new pixeldata into the calculation process it doest just the following:
1: check if last buffer was allready processed (!m_pCurrentFramePixels)
2. copy the bitmap info structure into the threads own one
3. alloc memory for frame
4. copy sourcepixeldata into own buffer...
5. let the thread wake up and return imediately to the caller
so that the real videoout wouldn't be stop for a too long time
*/
void
CAtmoExternalCaptureInput
::
DeliverNewSourceDataPaket
(
BITMAPINFOHEADER
*
bmpInfoHeader
,
void
*
pixelData
)
{
/*
normaly we should protect this area of code by critical_section or a mutex,
but I think we can omit this here because the timing this method is called
is really slow (in terms of the speed of a modern computer?)
so it's nearly impossible that two frames are delivert in the same time
the test needs and malloc needs...
*/
if
(
!
m_pCurrentFramePixels
)
{
// Last Frame was processed... take this one...
memcpy
(
&
m_CurrentFrameHeader
,
bmpInfoHeader
,
bmpInfoHeader
->
biSize
);
int
PixelDataSize
=
m_CurrentFrameHeader
.
biHeight
*
m_CurrentFrameHeader
.
biWidth
;
switch
(
m_CurrentFrameHeader
.
biBitCount
)
{
case
8
:
/* PixelDataSize = PixelDataSize; */
break
;
case
16
:
PixelDataSize
=
PixelDataSize
*
2
;
break
;
case
24
:
PixelDataSize
=
PixelDataSize
*
3
;
break
;
case
32
:
PixelDataSize
=
PixelDataSize
*
4
;
break
;
}
m_pCurrentFramePixels
=
malloc
(
PixelDataSize
);
memcpy
(
m_pCurrentFramePixels
,
pixelData
,
PixelDataSize
);
}
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock
(
&
m_WakeupLock
);
vlc_cond_signal
(
&
m_WakeupCond
);
vlc_mutex_unlock
(
&
m_WakeupLock
);
#else
SetEvent
(
m_hWakeupEvent
);
#endif
}
/*
the real thread Method which is processing the pixeldata into the hardware channel
values - which are used by the thread AtmoLiveView...
*/
#if defined (_ATMO_VLC_PLUGIN_)
DWORD
CAtmoExternalCaptureInput
::
Execute
(
void
)
{
msg_Dbg
(
m_pAtmoThread
,
"CAtmoExternalCaptureInput::Execute(void)"
);
int
i
=
0
;
vlc_mutex_lock
(
&
m_WakeupLock
);
while
((
this
->
m_bTerminated
==
ATMO_FALSE
)
&&
(
this
->
m_pAtmoThread
->
b_die
==
VLC_FALSE
))
{
int
value
=
vlc_cond_timedwait
(
&
m_WakeupCond
,
&
m_WakeupLock
,
mdate
()
+
I64C
(
75000
));
if
(
!
value
)
{
/* DeliverNewSourceDataPaket delivered new work for me... get it! */
CalcColors
();
// read picture and calculate colors
this
->
m_FrameArrived
=
ATMO_TRUE
;
}
i
++
;
if
(
i
==
100
)
{
i
=
0
;
#if !defined(WIN32)
/* kludge for pthreads? using the same condition variable too often results in hanging the pthread
call inside vlc_cond_timedwait...
*/
#ifdef _ATMO_KLUDGE_
vlc_cond_destroy
(
&
m_WakeupCond
);
vlc_cond_init
(
m_pAtmoThread
,
&
m_WakeupCond
);
#endif
#endif
}
}
vlc_mutex_unlock
(
&
m_WakeupLock
);
return
0
;
}
#else
DWORD
CAtmoExternalCaptureInput
::
Execute
(
void
)
{
HANDLE
handles
[
2
];
handles
[
0
]
=
this
->
m_hTerminateEvent
;
handles
[
1
]
=
m_hWakeupEvent
;
while
(
this
->
m_bTerminated
==
ATMO_FALSE
)
{
DWORD
event
=
WaitForMultipleObjects
(
2
,
handles
,
ATMO_FALSE
,
INFINITE
);
if
(
event
==
WAIT_OBJECT_0
)
{
// Terminate Thread Event was set... say good bye...!
break
;
}
if
(
event
==
(
WAIT_OBJECT_0
+
1
))
{
CalcColors
();
// read picture and calculate colors
this
->
m_FrameArrived
=
ATMO_TRUE
;
}
}
return
0
;
}
#endif
void
CAtmoExternalCaptureInput
::
WaitForNextFrame
(
DWORD
timeout
)
{
this
->
m_FrameArrived
=
ATMO_FALSE
;
for
(
DWORD
i
=
0
;(
i
<
timeout
)
&&
!
m_FrameArrived
;
i
++
)
#if defined (_ATMO_VLC_PLUGIN_)
msleep
(
1000
);
#else
Sleep
(
1
);
#endif
if
(
this
->
m_pAtmoDynData
)
{
CAtmoConfig
*
cfg
=
this
->
m_pAtmoDynData
->
getAtmoConfig
();
if
(
cfg
)
{
int
delay
=
cfg
->
getLiveView_FrameDelay
();
if
(
delay
>
0
)
{
#if defined (_ATMO_VLC_PLUGIN_)
msleep
(
delay
*
1000
);
#else
Sleep
(
delay
);
#endif
}
}
}
}
void
CAtmoExternalCaptureInput
::
CalcColors
()
{
// take data from m_CurrentFrameHeader and m_pCurrentFramePixels .. process for atmo ...
tHSVColor
HSV_Img
[
IMAGE_SIZE
];
tRGBColor
pixelColor
;
int
srcIndex
,
index
=
0
;
memset
(
&
HSV_Img
,
0
,
sizeof
(
HSV_Img
));
// Convert Data to HSV values.. bla bla....
if
(
m_pCurrentFramePixels
!=
NULL
)
{
if
((
m_CurrentFrameHeader
.
biWidth
==
CAP_WIDTH
)
&&
(
m_CurrentFrameHeader
.
biHeight
==
CAP_HEIGHT
))
{
// HSVI = HSV Image allready in right format just copy the easiest task
// und weiterverarbeiten lassen
if
(
m_CurrentFrameHeader
.
biCompression
==
FCC
(
'
HSVI
'
))
{
memcpy
(
&
HSV_Img
,
m_pCurrentFramePixels
,
CAP_WIDTH
*
CAP_HEIGHT
*
sizeof
(
tHSVColor
));
}
else
if
(
m_CurrentFrameHeader
.
biCompression
==
BI_RGB
)
{
if
(
m_CurrentFrameHeader
.
biBitCount
==
16
)
{
unsigned
short
*
buffer
=
(
unsigned
short
*
)
m_pCurrentFramePixels
;
for
(
int
y
=
0
;
y
<
CAP_HEIGHT
;
y
++
)
{
srcIndex
=
y
*
CAP_WIDTH
;
for
(
int
x
=
0
;
x
<
CAP_WIDTH
;
x
++
)
{
pixelColor
.
b
=
(
buffer
[
srcIndex
]
&
31
)
<<
3
;
pixelColor
.
g
=
((
buffer
[
srcIndex
]
>>
5
)
&
31
)
<<
3
;
pixelColor
.
r
=
((
buffer
[
srcIndex
]
>>
10
)
&
63
)
<<
2
;
srcIndex
++
;
HSV_Img
[
index
++
]
=
RGB2HSV
(
pixelColor
);
}
}
}
else
if
(
m_CurrentFrameHeader
.
biBitCount
==
24
)
{
for
(
int
y
=
0
;
y
<
CAP_HEIGHT
;
y
++
)
{
srcIndex
=
y
*
(
CAP_WIDTH
*
3
);
for
(
int
x
=
0
;
x
<
CAP_WIDTH
;
x
++
)
{
pixelColor
.
b
=
((
unsigned
char
*
)
m_pCurrentFramePixels
)[
srcIndex
++
];
pixelColor
.
g
=
((
unsigned
char
*
)
m_pCurrentFramePixels
)[
srcIndex
++
];
pixelColor
.
r
=
((
unsigned
char
*
)
m_pCurrentFramePixels
)[
srcIndex
++
];
HSV_Img
[
index
++
]
=
RGB2HSV
(
pixelColor
);
}
}
}
else
if
(
m_CurrentFrameHeader
.
biBitCount
==
32
)
{
for
(
int
y
=
0
;
y
<
CAP_HEIGHT
;
y
++
)
{
srcIndex
=
y
*
(
CAP_WIDTH
*
4
);
for
(
int
x
=
0
;
x
<
CAP_WIDTH
;
x
++
)
{
pixelColor
.
b
=
((
unsigned
char
*
)
m_pCurrentFramePixels
)[
srcIndex
++
];
pixelColor
.
g
=
((
unsigned
char
*
)
m_pCurrentFramePixels
)[
srcIndex
++
];
pixelColor
.
r
=
((
unsigned
char
*
)
m_pCurrentFramePixels
)[
srcIndex
++
];
srcIndex
++
;
HSV_Img
[
index
++
]
=
RGB2HSV
(
pixelColor
);
}
}
}
}
}
/*
if the image color format wasn't recognized - the output
will be black (memset)
*/
/*
now convert the pixeldata into one RGB trippel for each channel,
this is done by some very sophisticated methods and statistics ...
the only thing I know - the pixel priority is controled by some
gradients for each edge of the picture
(sorry I don't know how it exactly works because the formulars
are done by some one else...)
*/
m_ColorPacket
=
CalcColorsAnalyzeHSV
(
this
->
m_pAtmoDynData
->
getAtmoConfig
(),
HSV_Img
);
/* remove the source buffe */
free
(
m_pCurrentFramePixels
);
/*
the buffer zereo so that deliver new data paket will wakeup the
thread on the next frame again
*/
m_pCurrentFramePixels
=
NULL
;
}
}
modules/video_filter/atmo/AtmoExternalCaptureInput.h
0 → 100644
View file @
1b637157
#ifndef _AtmoExternalCaptureInput_h_
#define _AtmoExternalCaptureInput_h_
#include "AtmoDefs.h"
#if defined(WIN32)
# include <windows.h>
# else
# if defined(_ATMO_VLC_PLUGIN_)
// need bitmap info header
# include <vlc_codecs.h>
# endif
#endif
#if !defined(_ATMO_VLC_PLUGIN_)
# include <comdef.h>
# include "AtmoWin_h.h"
#endif
#include "AtmoInput.h"
#include "AtmoThread.h"
#include "AtmoConfig.h"
#include "AtmoDynData.h"
#include "AtmoCalculations.h"
class
CAtmoExternalCaptureInput
:
public
CAtmoInput
,
public
CThread
{
protected:
#if defined(_ATMO_VLC_PLUGIN_)
vlc_cond_t
m_WakeupCond
;
vlc_mutex_t
m_WakeupLock
;
#else
HANDLE
m_hWakeupEvent
;
#endif
BITMAPINFOHEADER
m_CurrentFrameHeader
;
void
*
m_pCurrentFramePixels
;
virtual
DWORD
Execute
(
void
);
void
CalcColors
();
public:
/*
this method is called from the com server AtmoLiveViewControlImpl!
or inside videolan from the filter method to start a new processing
*/
void
DeliverNewSourceDataPaket
(
BITMAPINFOHEADER
*
bmpInfoHeader
,
void
*
pixelData
);
public:
CAtmoExternalCaptureInput
(
CAtmoDynData
*
pAtmoDynData
);
virtual
~
CAtmoExternalCaptureInput
(
void
);
/*
Opens the input-device. Parameters (e.g. the device-name)
Returns true if the input-device was opened successfully.
input-device can be the GDI surface of screen (windows only)
or the videolan filter
*/
virtual
ATMO_BOOL
Open
(
void
);
/*
Closes the input-device.
Returns true if the input-device was closed successfully.
*/
virtual
ATMO_BOOL
Close
(
void
);
/*
this method is called from the AtmoLiveView thread - to get the
new color packet (a packet is an RGB triple for each channel)
*/
virtual
tColorPacket
GetColorPacket
(
void
);
/*
this method is also called from the AtmoLiveView thread - to
resync on a frame
*/
virtual
void
WaitForNextFrame
(
DWORD
timeout
);
};
#endif
modules/video_filter/atmo/AtmoInput.cpp
0 → 100644
View file @
1b637157
/*
* AtmoInput.cpp: abstract class for retrieving precalculated image data
* from different sources in the live view mode
*
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoInput.h"
CAtmoInput
::
CAtmoInput
(
CAtmoDynData
*
pAtmoDynData
)
{
this
->
m_pAtmoDynData
=
pAtmoDynData
;
}
CAtmoInput
::~
CAtmoInput
(
void
)
{
}
void
CAtmoInput
::
WaitForNextFrame
(
DWORD
timeout
)
{
return
;
}
modules/video_filter/atmo/AtmoInput.h
0 → 100644
View file @
1b637157
/*
* AtmoInput.h: abstract class for retrieving precalculated image data from
* different sources in the live view mode
*
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoInput_h_
#define _AtmoInput_h_
#include "AtmoDefs.h"
#include "AtmoDynData.h"
/*
basic definition of an AtmoLight data/image source ...
*/
class
CAtmoInput
{
protected:
tColorPacket
m_ColorPacket
;
volatile
ATMO_BOOL
m_FrameArrived
;
CAtmoDynData
*
m_pAtmoDynData
;
public:
CAtmoInput
(
CAtmoDynData
*
pAtmoDynData
);
virtual
~
CAtmoInput
(
void
);
// Opens the input-device.
// Returns true if the input-device was opened successfully.
virtual
ATMO_BOOL
Open
(
void
)
{
return
ATMO_FALSE
;
}
// Closes the input-device.
// Returns true if the input-device was closed successfully.
virtual
ATMO_BOOL
Close
(
void
)
{
return
ATMO_FALSE
;
}
// Returns the calculated tColorPacket for further processing (e.g. filtering).
virtual
tColorPacket
GetColorPacket
(
void
)
{
return
m_ColorPacket
;
}
// wait for the arrival of the next frame...(to come in sync again)
virtual
void
WaitForNextFrame
(
DWORD
timeout
);
};
#endif
modules/video_filter/atmo/AtmoLiveView.cpp
0 → 100644
View file @
1b637157
/*
* AtmoLiveView.cpp: this effect outputs colors as result of a picture
* content (most complex effect) see thread.c of the linux VDR version -
* to fully understand what happens here..
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoDefs.h"
#include "AtmoLiveView.h"
#include "AtmoOutputFilter.h"
#include "AtmoTools.h"
#if defined(_ATMO_VLC_PLUGIN_)
# include <vlc/vlc.h>
#else
# include "AtmoGdiDisplayCaptureInput.h"
#endif
#include "AtmoExternalCaptureInput.h"
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoLiveView
::
CAtmoLiveView
(
CAtmoDynData
*
pAtmoDynData
)
:
CThread
(
pAtmoDynData
->
getAtmoFilter
())
{
this
->
m_pAtmoDynData
=
pAtmoDynData
;
m_pAtmoInput
=
NULL
;
}
#else
CAtmoLiveView
::
CAtmoLiveView
(
CAtmoDynData
*
pAtmoDynData
)
{
this
->
m_pAtmoDynData
=
pAtmoDynData
;
m_LiveViewSource
=
lvsGDI
;
m_CurrentLiveViewSource
=
lvsGDI
;
m_InputChangedEvent
=
CreateEvent
(
NULL
,
ATMO_FALSE
,
ATMO_FALSE
,
NULL
);
m_pAtmoInput
=
NULL
;
InitializeCriticalSection
(
&
m_InputChangeCriticalSection
);
}
#endif
CAtmoLiveView
::~
CAtmoLiveView
(
void
)
{
#if !defined(_ATMO_VLC_PLUGIN_)
DeleteCriticalSection
(
&
m_InputChangeCriticalSection
);
CloseHandle
(
m_InputChangedEvent
);
#endif
}
#if !defined(_ATMO_VLC_PLUGIN_)
STDMETHODIMP
CAtmoLiveView
::
setLiveViewSource
(
enum
ComLiveViewSource
dwModus
)
{
if
(
dwModus
!=
m_LiveViewSource
)
{
m_LiveViewSource
=
dwModus
;
/*
you may ask why I don't use a critical section here and directly acces the
the variable of the Thread?
Just because you would need very much / often entering / leaving the critical
section ... and in this case It could be avoid ...
assigning the value to the "mirror" variable m_LiveViewSource which is compare
in every run of the thread with its current value ... if there is a change
the thread can proceed switching the live source ... until this is done
the thread calling this method is waiting...
*/
// I don't expect that it will take longer than 500ms to switch...
if
(
WaitForSingleObject
(
m_InputChangedEvent
,
500
)
==
WAIT_TIMEOUT
)
return
S_FALSE
;
// if not so the switch seems be have failed (badly)
}
return
S_OK
;
}
STDMETHODIMP
CAtmoLiveView
::
getCurrentLiveViewSource
(
enum
ComLiveViewSource
*
modus
)
{
*
modus
=
m_LiveViewSource
;
return
S_OK
;
}
#endif
DWORD
CAtmoLiveView
::
Execute
(
void
)
{
#if defined(_ATMO_VLC_PLUGIN_)
mtime_t
ticks
;
#else
DWORD
ticks
;
#endif
int
i_frame_counter
=
0
;
CAtmoInput
*
newInput
,
*
oldInput
;
tColorPacket
ColorPacket
;
CAtmoConnection
*
pAtmoConnection
=
this
->
m_pAtmoDynData
->
getAtmoConnection
();
if
((
pAtmoConnection
==
NULL
)
||
(
pAtmoConnection
->
isOpen
()
==
ATMO_FALSE
))
return
0
;
CAtmoConfig
*
pAtmoConfig
=
this
->
m_pAtmoDynData
->
getAtmoConfig
();
/*
this object does post processing of the pixel data
like jump /scenechange detection fading over the colors
*/
CAtmoOutputFilter
*
filter
=
new
CAtmoOutputFilter
(
this
->
m_pAtmoDynData
->
getAtmoConfig
());
#if defined(_ATMO_VLC_PLUGIN_)
/* this thread is the data preprocess which gets the real 64x48 pixel
and converts them into the RGB channel values - this is done in
another thread to keep this thread at a constant timing - to that
color output is updated 25 times a second
*/
m_pAtmoInput
=
new
CAtmoExternalCaptureInput
(
m_pAtmoDynData
);
#else
if
(
m_LiveViewSource
==
lvsGDI
)
m_pAtmoInput
=
new
CAtmoGdiDisplayCaptureInput
(
m_pAtmoDynData
);
else
m_pAtmoInput
=
new
CAtmoExternalCaptureInput
(
m_pAtmoDynData
);
#endif
if
(
m_pAtmoInput
->
Open
()
==
ATMO_TRUE
)
{
/*
wait for the first frame to go in sync with the other thread
*/
#if defined(_ATMO_VLC_PLUGIN_)
msg_Dbg
(
m_pAtmoThread
,
"CAtmoLiveView::Execute(void)"
);
#endif
m_pAtmoInput
->
WaitForNextFrame
(
500
);
while
(
this
->
m_bTerminated
==
ATMO_FALSE
)
{
/* atmoInput - capture Thread Running... */
#if defined(_ATMO_VLC_PLUGIN_)
ticks
=
mdate
();
#else
ticks
=
GetTickCount
();
#endif
/* grab current Packet from Input! */
ColorPacket
=
m_pAtmoInput
->
GetColorPacket
();
/* pass it through the outputfilters! */
ColorPacket
=
filter
->
Filtering
(
ColorPacket
);
/* apply gamma later ;-) not implemented yet */
ColorPacket
=
CAtmoTools
::
ApplyGamma
(
pAtmoConfig
,
ColorPacket
);
/*
apply white calibration - only if it is not
done by the hardware
*/
if
(
pAtmoConfig
->
isUseSoftwareWhiteAdj
())
ColorPacket
=
CAtmoTools
::
WhiteCalibration
(
pAtmoConfig
,
ColorPacket
);
/* send color data to the the hardware... */
pAtmoConnection
->
SendData
(
ColorPacket
);
/*
experimental do sync every 100 Frames to the image producer
thread because GetTickCount precision is really poor ;-)
*/
i_frame_counter
++
;
if
(
i_frame_counter
==
100
)
{
m_pAtmoInput
->
WaitForNextFrame
(
50
);
i_frame_counter
=
0
;
#if !defined(WIN32)
/* kludge for pthreads? when running GDB debugger using the same condition variable
to often results in haging wait timedout...
*/
#ifdef _ATMO_KLUDGE_
vlc_mutex_lock
(
&
m_TerminateLock
);
vlc_cond_destroy
(
&
m_TerminateCond
);
vlc_cond_init
(
m_pAtmoThread
,
&
m_TerminateCond
);
vlc_mutex_unlock
(
&
m_TerminateLock
);
#endif
#endif
continue
;
}
#if !defined(_ATMO_VLC_PLUGIN_)
/*
Check if Input Source has changed - through an async
call from the com interface?
*/
if
(
m_CurrentLiveViewSource
!=
m_LiveViewSource
)
{
oldInput
=
m_pAtmoInput
;
m_pAtmoInput
=
NULL
;
if
(
m_LiveViewSource
==
lvsGDI
)
{
// create new GDI Input Source...
newInput
=
new
CAtmoGdiDisplayCaptureInput
(
m_pAtmoDynData
);
newInput
->
Open
();
// should not fail now... hope is the best!
}
else
if
(
m_LiveViewSource
==
lvsExternal
)
{
newInput
=
new
CAtmoExternalCaptureInput
(
m_pAtmoDynData
);
newInput
->
Open
();
}
m_CurrentLiveViewSource
=
m_LiveViewSource
;
m_pAtmoInput
=
newInput
;
oldInput
->
Close
();
delete
oldInput
;
/*
signal the call to the method "setLiveViewSource" the source
was switched...
*/
SetEvent
(
m_InputChangedEvent
);
// do sync with input thread
m_pAtmoInput
->
WaitForNextFrame
(
100
);
continue
;
}
#endif
/*
calculate RunTime of thread abbove (doesn't work well - so
this threads comes out of sync with Image producer and the
framerate (25fps) drifts away
*/
#if defined(_ATMO_VLC_PLUGIN_)
ticks
=
((
mdate
()
-
ticks
)
+
999
)
/
1000
;
#else
ticks
=
GetTickCount
()
-
ticks
;
#endif
if
(
ticks
<
40
)
{
// ThreadSleep -> AtmoThread.cpp
if
(
this
->
ThreadSleep
(
40
-
ticks
)
==
ATMO_FALSE
)
break
;
}
}
/* shutdown the input processor thread */
m_pAtmoInput
->
Close
();
}
delete
m_pAtmoInput
;
m_pAtmoInput
=
NULL
;
#if !defined(_ATMO_VLC_PLUGIN_)
/*
if there is a pending call to setLiveViewSource let him surely return before
destroying the thread and this class instance...
*/
SetEvent
(
m_InputChangedEvent
);
#endif
delete
filter
;
return
0
;
}
modules/video_filter/atmo/AtmoLiveView.h
0 → 100644
View file @
1b637157
/*
* AtmoLiveView.h: this effect outputs colors as result of a picture content
* (most complex effect) see thread.c of the linux version - to fully understand
* what happes here..
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoLiveView_h_
#define _AtmoLiveView_h_
#include "AtmoDefs.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include <comdef.h>
# include "AtmoWin_h.h"
# include <windows.h>
#endif
#include "AtmoThread.h"
#include "AtmoConfig.h"
#include "AtmoConnection.h"
#include "AtmoInput.h"
class
CAtmoLiveView
:
public
CThread
{
protected:
virtual
DWORD
Execute
(
void
);
#if !defined(_ATMO_VLC_PLUGIN_)
public:
STDMETHODIMP
setLiveViewSource
(
enum
ComLiveViewSource
dwModus
);
STDMETHODIMP
getCurrentLiveViewSource
(
enum
ComLiveViewSource
*
modus
);
#endif
protected:
CAtmoDynData
*
m_pAtmoDynData
;
CAtmoInput
*
m_pAtmoInput
;
#if !defined(_ATMO_VLC_PLUGIN_)
ComLiveViewSource
m_LiveViewSource
;
ComLiveViewSource
m_CurrentLiveViewSource
;
CRITICAL_SECTION
m_InputChangeCriticalSection
;
HANDLE
m_InputChangedEvent
;
#endif
public:
CAtmoLiveView
(
CAtmoDynData
*
pAtmoDynData
);
virtual
~
CAtmoLiveView
(
void
);
CAtmoInput
*
getAtmoInput
()
{
return
m_pAtmoInput
;
}
#if !defined(_ATMO_VLC_PLUGIN_)
ComLiveViewSource
getLiveViewSource
()
{
return
m_CurrentLiveViewSource
;
}
#endif
};
#endif
modules/video_filter/atmo/AtmoOutputFilter.cpp
0 → 100644
View file @
1b637157
/*
* AtmoOutputFilter.cpp: Post Processor for the color data retrieved from
* a CAtmoInput
*
* mostly 1:1 from vdr-linux-src "filter.c" copied
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include <string.h>
#include "AtmoOutputFilter.h"
CAtmoOutputFilter
::
CAtmoOutputFilter
(
CAtmoConfig
*
atmoConfig
)
{
this
->
m_pAtmoConfig
=
atmoConfig
;
ResetFilter
();
}
CAtmoOutputFilter
::~
CAtmoOutputFilter
(
void
)
{
}
void
CAtmoOutputFilter
::
ResetFilter
(
void
)
{
// reset filter values
MeanFilter
(
true
);
PercentFilter
(
true
);
}
tColorPacket
CAtmoOutputFilter
::
Filtering
(
tColorPacket
ColorPacket
)
{
filter_input
=
ColorPacket
;
switch
(
m_pAtmoConfig
->
getLiveViewFilterMode
())
{
case
afmNoFilter
:
filter_output
=
filter_input
;
break
;
case
afmCombined
:
MeanFilter
(
false
);
break
;
case
afmPercent
:
PercentFilter
(
false
);
break
;
default:
filter_output
=
filter_input
;
break
;
}
return
filter_output
;
}
void
CAtmoOutputFilter
::
PercentFilter
(
ATMO_BOOL
init
)
{
// last values needed for the percentage filter
static
tColorPacket
filter_output_old
;
if
(
init
)
// Initialization
{
memset
(
&
filter_output_old
,
0
,
sizeof
(
filter_output_old
));
return
;
}
int
percentNew
=
this
->
m_pAtmoConfig
->
getLiveViewFilter_PercentNew
();
for
(
int
ch
=
0
;
ch
<
ATMO_NUM_CHANNELS
;
ch
++
)
{
filter_output
.
channel
[
ch
].
r
=
(
filter_input
.
channel
[
ch
].
r
*
(
100
-
percentNew
)
+
filter_output_old
.
channel
[
ch
].
r
*
percentNew
)
/
100
;
filter_output
.
channel
[
ch
].
g
=
(
filter_input
.
channel
[
ch
].
g
*
(
100
-
percentNew
)
+
filter_output_old
.
channel
[
ch
].
g
*
percentNew
)
/
100
;
filter_output
.
channel
[
ch
].
b
=
(
filter_input
.
channel
[
ch
].
b
*
(
100
-
percentNew
)
+
filter_output_old
.
channel
[
ch
].
b
*
percentNew
)
/
100
;
}
filter_output_old
=
filter_output
;
}
void
CAtmoOutputFilter
::
MeanFilter
(
ATMO_BOOL
init
)
{
// needed vor the running mean value filter
static
tColorPacketLongInt
mean_sums
;
static
tColorPacket
mean_values
;
// needed for the percentage filter
static
tColorPacket
filter_output_old
;
static
int
filter_length_old
;
char
reinitialize
=
0
;
if
(
init
)
// Initialization
{
memset
(
&
filter_output_old
,
0
,
sizeof
(
filter_output_old
));
memset
(
&
mean_sums
,
0
,
sizeof
(
mean_sums
));
memset
(
&
mean_values
,
0
,
sizeof
(
mean_values
));
return
;
}
int
AtmoSetup_Filter_MeanLength
=
m_pAtmoConfig
->
getLiveViewFilter_MeanLength
();
int
AtmoSetup_Filter_PercentNew
=
m_pAtmoConfig
->
getLiveViewFilter_PercentNew
();
int
AtmoSetup_Filter_MeanThreshold
=
m_pAtmoConfig
->
getLiveViewFilter_MeanThreshold
();
// if filter_length has changed
if
(
filter_length_old
!=
AtmoSetup_Filter_MeanLength
)
{
// force reinitialization of the filter
reinitialize
=
1
;
}
filter_length_old
=
AtmoSetup_Filter_MeanLength
;
if
(
filter_length_old
<
20
)
filter_length_old
=
20
;
// avoid division by 0
for
(
int
ch
=
0
;
ch
<
ATMO_NUM_CHANNELS
;
ch
++
)
{
// calculate the mean-value filters
mean_sums
.
channel
[
ch
].
r
+=
(
long
int
)(
filter_input
.
channel
[
ch
].
r
-
mean_values
.
channel
[
ch
].
r
);
// red
mean_values
.
channel
[
ch
].
r
=
mean_sums
.
channel
[
ch
].
r
/
((
long
int
)
filter_length_old
/
20
);
mean_sums
.
channel
[
ch
].
g
+=
(
long
int
)(
filter_input
.
channel
[
ch
].
g
-
mean_values
.
channel
[
ch
].
g
);
// green
mean_values
.
channel
[
ch
].
g
=
mean_sums
.
channel
[
ch
].
g
/
((
long
int
)
filter_length_old
/
20
);
mean_sums
.
channel
[
ch
].
b
+=
(
long
int
)(
filter_input
.
channel
[
ch
].
b
-
mean_values
.
channel
[
ch
].
b
);
// blue
mean_values
.
channel
[
ch
].
b
=
mean_sums
.
channel
[
ch
].
b
/
((
long
int
)
filter_length_old
/
20
);
// check, if there is a jump -> check if differences between actual values and filter values are too big
long
int
dist
;
// distance between the two colors in the 3D RGB space
dist
=
(
mean_values
.
channel
[
ch
].
r
-
filter_input
.
channel
[
ch
].
r
)
*
(
mean_values
.
channel
[
ch
].
r
-
filter_input
.
channel
[
ch
].
r
)
+
(
mean_values
.
channel
[
ch
].
g
-
filter_input
.
channel
[
ch
].
g
)
*
(
mean_values
.
channel
[
ch
].
g
-
filter_input
.
channel
[
ch
].
g
)
+
(
mean_values
.
channel
[
ch
].
b
-
filter_input
.
channel
[
ch
].
b
)
*
(
mean_values
.
channel
[
ch
].
b
-
filter_input
.
channel
[
ch
].
b
);
/*
if (dist > 0) { dist = (long int)sqrt((double)dist); }
avoid sqrt(0) (TODO: necessary?)
I think its cheaper to calculate the square of something ..? insteas geting the square root?
*/
double
distMean
=
((
double
)
AtmoSetup_Filter_MeanThreshold
*
3.6
f
);
distMean
=
distMean
*
distMean
;
/*
compare calculated distance with the filter threshold
if ((dist > (long int)((double)AtmoSetup.Filter_MeanThreshold * 3.6f)) || ( reinitialize == 1))
*/
if
((
dist
>
distMean
)
||
(
reinitialize
==
1
))
{
// filter jump detected -> set the long filters to the result of the short filters
filter_output
.
channel
[
ch
]
=
mean_values
.
channel
[
ch
]
=
filter_input
.
channel
[
ch
];
mean_sums
.
channel
[
ch
].
r
=
filter_input
.
channel
[
ch
].
r
*
(
filter_length_old
/
20
);
mean_sums
.
channel
[
ch
].
g
=
filter_input
.
channel
[
ch
].
g
*
(
filter_length_old
/
20
);
mean_sums
.
channel
[
ch
].
b
=
filter_input
.
channel
[
ch
].
b
*
(
filter_length_old
/
20
);
}
else
{
// apply an additional percent filter and return calculated values
filter_output
.
channel
[
ch
].
r
=
(
mean_values
.
channel
[
ch
].
r
*
(
100
-
AtmoSetup_Filter_PercentNew
)
+
filter_output_old
.
channel
[
ch
].
r
*
AtmoSetup_Filter_PercentNew
)
/
100
;
filter_output
.
channel
[
ch
].
g
=
(
mean_values
.
channel
[
ch
].
g
*
(
100
-
AtmoSetup_Filter_PercentNew
)
+
filter_output_old
.
channel
[
ch
].
g
*
AtmoSetup_Filter_PercentNew
)
/
100
;
filter_output
.
channel
[
ch
].
b
=
(
mean_values
.
channel
[
ch
].
b
*
(
100
-
AtmoSetup_Filter_PercentNew
)
+
filter_output_old
.
channel
[
ch
].
b
*
AtmoSetup_Filter_PercentNew
)
/
100
;
}
}
filter_output_old
=
filter_output
;
}
modules/video_filter/atmo/AtmoOutputFilter.h
0 → 100644
View file @
1b637157
/*
* AtmoOutputFilter.h: Post Processor for the color data retrieved from a CAtmoInput
*
* mostly 1:1 from Linux-src "filter.c" copied
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoOutputFilter_h_
#define _AtmoOutputFilter_h_
#include "AtmoConfig.h"
#include "AtmoDefs.h"
class
CAtmoOutputFilter
{
private:
tColorPacket
filter_input
;
// input of the filter
tColorPacket
filter_output
;
// output of the filter
void
PercentFilter
(
ATMO_BOOL
init
);
void
MeanFilter
(
ATMO_BOOL
init
);
CAtmoConfig
*
m_pAtmoConfig
;
public:
public:
CAtmoOutputFilter
(
CAtmoConfig
*
atmoConfig
);
virtual
~
CAtmoOutputFilter
(
void
);
void
ResetFilter
(
void
);
tColorPacket
Filtering
(
tColorPacket
ColorPacket
);
};
#endif
modules/video_filter/atmo/AtmoSerialConnection.cpp
0 → 100644
View file @
1b637157
/*
* AtmoSerialConnection.cpp: Class for communication with the serial hardware of
* Atmo Light, opens and configures the serial port
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoDefs.h"
#include "AtmoSerialConnection.h"
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#if !defined(WIN32)
#include <termios.h>
#include <unistd.h>
#endif
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <vdr/tools.h>
*/
CAtmoSerialConnection
::
CAtmoSerialConnection
(
CAtmoConfig
*
cfg
)
:
CAtmoConnection
(
cfg
)
{
m_hComport
=
INVALID_HANDLE_VALUE
;
}
CAtmoSerialConnection
::~
CAtmoSerialConnection
()
{
CloseConnection
();
}
ATMO_BOOL
CAtmoSerialConnection
::
OpenConnection
()
{
#if defined(_ATMO_VLC_PLUGIN_)
char
*
serdevice
=
m_pAtmoConfig
->
getSerialDevice
();
if
(
!
serdevice
)
return
ATMO_FALSE
;
#else
int
portNummer
=
m_pAtmoConfig
->
getComport
();
m_dwLastWin32Error
=
0
;
if
(
portNummer
<
1
)
return
ATMO_FALSE
;
// make no real sense;-)
#endif
CloseConnection
();
#if !defined(_ATMO_VLC_PLUGIN_)
char
comport
[
16
];
// com4294967295
sprintf
(
comport
,
"com%d"
,
portNummer
);
#endif
#if defined(WIN32)
# if defined(_ATMO_VLC_PLUGIN_)
m_hComport
=
CreateFile
(
serdevice
,
GENERIC_WRITE
,
0
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
# else
m_hComport
=
CreateFile
(
comport
,
GENERIC_WRITE
,
0
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
# endif
if
(
m_hComport
==
INVALID_HANDLE_VALUE
)
{
// we have a problem here can't open com port... somebody else may use it?
// m_dwLastWin32Error = GetLastError();
return
ATMO_FALSE
;
}
/* change serial settings (Speed, stopbits etc.) */
DCB
dcb
;
// fr comport-parameter
dcb
.
DCBlength
=
sizeof
(
DCB
);
GetCommState
(
m_hComport
,
&
dcb
);
// ger current serialport settings
dcb
.
BaudRate
=
38400
;
// set speed
dcb
.
ByteSize
=
8
;
// set databits
dcb
.
Parity
=
NOPARITY
;
// set parity
dcb
.
StopBits
=
ONESTOPBIT
;
// set one stop bit
SetCommState
(
m_hComport
,
&
dcb
);
// apply settings
#else
int
bconst
=
B38400
;
# if defined(_ATMO_VLC_PLUGIN_)
m_hComport
=
open
(
serdevice
,
O_RDWR
|
O_NOCTTY
);
# else
m_hComport
=
open
(
comport
,
O_RDWR
|
O_NOCTTY
);
# endif
if
(
m_hComport
<
0
)
{
return
ATMO_FALSE
;
}
struct
termios
tio
;
memset
(
&
tio
,
0
,
sizeof
(
tio
));
tio
.
c_cflag
=
(
CS8
|
CREAD
|
HUPCL
|
CLOCAL
);
tio
.
c_iflag
=
(
INPCK
|
BRKINT
);
cfsetispeed
(
&
tio
,
bconst
);
cfsetospeed
(
&
tio
,
bconst
);
if
(
!
tcsetattr
(
m_hComport
,
TCSANOW
,
&
tio
))
{
tcflush
(
m_hComport
,
TCIOFLUSH
);
}
else
{
// can't change parms
close
(
m_hComport
);
m_hComport
=
-
1
;
return
false
;
}
#endif
return
true
;
}
void
CAtmoSerialConnection
::
CloseConnection
()
{
if
(
m_hComport
!=
INVALID_HANDLE_VALUE
)
{
#if defined(WIN32)
CloseHandle
(
m_hComport
);
#else
close
(
m_hComport
);
#endif
m_hComport
=
INVALID_HANDLE_VALUE
;
}
}
ATMO_BOOL
CAtmoSerialConnection
::
isOpen
(
void
)
{
return
(
m_hComport
!=
INVALID_HANDLE_VALUE
);
}
ATMO_BOOL
CAtmoSerialConnection
::
HardwareWhiteAdjust
(
int
global_gamma
,
int
global_contrast
,
int
contrast_red
,
int
contrast_green
,
int
contrast_blue
,
int
gamma_red
,
int
gamma_green
,
int
gamma_blue
,
ATMO_BOOL
storeToEeprom
)
{
if
(
m_hComport
==
INVALID_HANDLE_VALUE
)
return
ATMO_FALSE
;
DWORD
iBytesWritten
;
/*
[0] = 255
[1] = 00
[2] = 00
[3] = 101
[4] brightness 0..255 ?
[5] Contrast Red 11 .. 100
[6] Contrast Green 11 .. 100
[7] Contrast Blue 11 .. 100
[8] Gamma Red 11 .. 35
[9] Gamma Red 11 .. 35
[10] Gamma Red 11 .. 35
[11] Globale Contrast 11 .. 100
[12] Store Data: 199 (else 0)
*/
unsigned
char
sendBuffer
[
16
];
sendBuffer
[
0
]
=
0xFF
;
sendBuffer
[
1
]
=
0x00
;
sendBuffer
[
2
]
=
0x00
;
sendBuffer
[
3
]
=
101
;
sendBuffer
[
4
]
=
(
global_gamma
&
255
);
sendBuffer
[
5
]
=
(
contrast_red
&
255
);
sendBuffer
[
6
]
=
(
contrast_green
&
255
);
sendBuffer
[
7
]
=
(
contrast_blue
&
255
);
sendBuffer
[
8
]
=
(
gamma_red
&
255
);
sendBuffer
[
9
]
=
(
gamma_green
&
255
);
sendBuffer
[
10
]
=
(
gamma_blue
&
255
);
sendBuffer
[
11
]
=
(
global_contrast
&
255
);
if
(
storeToEeprom
==
ATMO_TRUE
)
sendBuffer
[
12
]
=
199
;
// store to eeprom!
else
sendBuffer
[
12
]
=
0
;
#if defined(WIN32)
WriteFile
(
m_hComport
,
sendBuffer
,
13
,
&
iBytesWritten
,
NULL
);
// send to COM-Port
#else
iBytesWritten
=
write
(
m_hComport
,
sendBuffer
,
13
);
tcdrain
(
m_hComport
);
#endif
return
(
iBytesWritten
==
13
)
?
ATMO_TRUE
:
ATMO_FALSE
;
}
ATMO_BOOL
CAtmoSerialConnection
::
SendData
(
tColorPacket
data
)
{
if
(
m_hComport
==
INVALID_HANDLE_VALUE
)
return
ATMO_FALSE
;
unsigned
char
buffer
[
19
];
DWORD
iBytesWritten
;
buffer
[
0
]
=
0xFF
;
// Start Byte
buffer
[
1
]
=
0x00
;
// Start channel 0
buffer
[
2
]
=
0x00
;
// Start channel 0
buffer
[
3
]
=
15
;
//
int
iBuffer
=
4
;
for
(
int
i
=
0
;
i
<
5
;
i
++
)
{
if
(
m_ChannelAssignment
[
i
]
>=
0
)
{
buffer
[
iBuffer
++
]
=
data
.
channel
[
m_ChannelAssignment
[
i
]].
r
;
buffer
[
iBuffer
++
]
=
data
.
channel
[
m_ChannelAssignment
[
i
]].
g
;
buffer
[
iBuffer
++
]
=
data
.
channel
[
m_ChannelAssignment
[
i
]].
b
;
}
else
{
buffer
[
iBuffer
++
]
=
0
;
buffer
[
iBuffer
++
]
=
0
;
buffer
[
iBuffer
++
]
=
0
;
}
}
#if defined(WIN32)
WriteFile
(
m_hComport
,
buffer
,
19
,
&
iBytesWritten
,
NULL
);
// send to COM-Port
#else
iBytesWritten
=
write
(
m_hComport
,
buffer
,
19
);
tcdrain
(
m_hComport
);
#endif
return
(
iBytesWritten
==
19
)
?
ATMO_TRUE
:
ATMO_FALSE
;
}
ATMO_BOOL
CAtmoSerialConnection
::
SendData
(
unsigned
char
numChannels
,
int
red
[],
int
green
[],
int
blue
[])
{
if
(
m_hComport
==
INVALID_HANDLE_VALUE
)
return
ATMO_FALSE
;
DWORD
bufSize
=
4
+
numChannels
*
3
;
unsigned
char
*
buffer
=
new
unsigned
char
[
bufSize
];
DWORD
iBytesWritten
;
buffer
[
0
]
=
0xFF
;
// Start Byte
buffer
[
1
]
=
0x00
;
// Start Kanal 0
buffer
[
2
]
=
0x00
;
// Start Kanal 0
buffer
[
3
]
=
numChannels
*
3
;
//
int
iBuffer
=
4
;
for
(
int
i
=
0
;
i
<
numChannels
;
i
++
)
{
if
(
m_ChannelAssignment
[
i
]
>=
0
)
{
buffer
[
iBuffer
++
]
=
red
[
m_ChannelAssignment
[
i
]]
&
255
;
buffer
[
iBuffer
++
]
=
green
[
m_ChannelAssignment
[
i
]]
&
255
;
buffer
[
iBuffer
++
]
=
blue
[
m_ChannelAssignment
[
i
]]
&
255
;
}
else
{
buffer
[
iBuffer
++
]
=
0
;
buffer
[
iBuffer
++
]
=
0
;
buffer
[
iBuffer
++
]
=
0
;
}
}
#if defined(WIN32)
WriteFile
(
m_hComport
,
buffer
,
bufSize
,
&
iBytesWritten
,
NULL
);
#else
iBytesWritten
=
write
(
m_hComport
,
buffer
,
bufSize
);
tcdrain
(
m_hComport
);
#endif
delete
buffer
;
return
(
iBytesWritten
==
bufSize
)
?
ATMO_TRUE
:
ATMO_FALSE
;
}
modules/video_filter/atmo/AtmoSerialConnection.h
0 → 100644
View file @
1b637157
/*
* AtmoCom.h: Class for communication with the serial hardware of Atmo Light,
* opens and configures the serial port
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoSerialConnection_h_
#define _AtmoSerialConnection_h_
#include "AtmoDefs.h"
#include "AtmoConnection.h"
#include "AtmoConfig.h"
#if defined(WIN32)
# include <windows.h>
#endif
class
CAtmoSerialConnection
:
public
CAtmoConnection
{
private:
HANDLE
m_hComport
;
#if defined(WIN32)
DWORD
m_dwLastWin32Error
;
public:
DWORD
getLastError
()
{
return
m_dwLastWin32Error
;
}
#endif
public:
CAtmoSerialConnection
(
CAtmoConfig
*
cfg
);
virtual
~
CAtmoSerialConnection
(
void
);
virtual
ATMO_BOOL
OpenConnection
();
virtual
void
CloseConnection
();
virtual
ATMO_BOOL
isOpen
(
void
);
virtual
ATMO_BOOL
SendData
(
unsigned
char
numChannels
,
int
red
[],
int
green
[],
int
blue
[]);
virtual
ATMO_BOOL
SendData
(
tColorPacket
data
);
virtual
ATMO_BOOL
HardwareWhiteAdjust
(
int
global_gamma
,
int
global_contrast
,
int
contrast_red
,
int
contrast_green
,
int
contrast_blue
,
int
gamma_red
,
int
gamma_green
,
int
gamma_blue
,
ATMO_BOOL
storeToEeprom
);
};
#endif
modules/video_filter/atmo/AtmoThread.cpp
0 → 100644
View file @
1b637157
/*
* AtmoThread.cpp: Base thread class for all threads inside AtmoWin
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoThread.h"
#if defined(_ATMO_VLC_PLUGIN_)
CThread
::
CThread
(
vlc_object_t
*
pOwner
)
{
int
err
;
m_pAtmoThread
=
(
atmo_thread_t
*
)
vlc_object_create
(
pOwner
,
sizeof
(
atmo_thread_t
)
);
if
(
m_pAtmoThread
)
{
m_pAtmoThread
->
p_thread
=
this
;
this
->
m_pOwner
=
pOwner
;
vlc_object_attach
(
m_pAtmoThread
,
m_pOwner
);
vlc_mutex_init
(
m_pAtmoThread
,
&
m_TerminateLock
);
err
=
vlc_cond_init
(
m_pAtmoThread
,
&
m_TerminateCond
);
if
(
err
)
{
msg_Err
(
m_pAtmoThread
,
"vlc_cond_init failed %d"
,
err
);
}
}
}
#else
CThread
::
CThread
(
void
)
{
m_hThread
=
CreateThread
(
NULL
,
0
,
CThread
::
ThreadProc
,
this
,
CREATE_SUSPENDED
,
&
m_dwThreadID
);
m_hTerminateEvent
=
CreateEvent
(
NULL
,
ATMO_FALSE
,
ATMO_FALSE
,
NULL
);
}
#endif
#if defined(_ATMO_VLC_PLUGIN_)
CThread
::~
CThread
(
void
)
{
if
(
m_pAtmoThread
)
{
vlc_mutex_destroy
(
&
m_TerminateLock
);
vlc_cond_destroy
(
&
m_TerminateCond
);
vlc_object_detach
(
m_pAtmoThread
);
vlc_object_destroy
(
m_pAtmoThread
);
}
}
#else
CThread
::~
CThread
(
void
)
{
CloseHandle
(
m_hThread
);
CloseHandle
(
m_hTerminateEvent
);
}
#endif
#if defined(_ATMO_VLC_PLUGIN_)
void
CThread
::
ThreadProc
(
atmo_thread_t
*
pAtmoThread
)
{
CThread
*
pThread
=
(
CThread
*
)
pAtmoThread
->
p_thread
;
if
(
pThread
)
{
// give feedback I'am running?
vlc_thread_ready
(
pThread
->
m_pAtmoThread
);
pThread
->
Execute
();
}
}
#else
DWORD
WINAPI
CThread
::
ThreadProc
(
LPVOID
lpParameter
)
{
CThread
*
aThread
=
(
CThread
*
)
lpParameter
;
if
(
aThread
)
return
aThread
->
Execute
();
else
return
(
DWORD
)
-
1
;
}
#endif
DWORD
CThread
::
Execute
(
void
)
{
/*
to do implement! override!
while(!bTerminated) {
...
}
*/
return
0
;
}
void
CThread
::
Terminate
(
void
)
{
// Set Termination Flag and EventObject!
// and wait for Termination
m_bTerminated
=
ATMO_TRUE
;
#if defined(_ATMO_VLC_PLUGIN_)
if
(
m_pAtmoThread
)
{
vlc_mutex_lock
(
&
m_TerminateLock
);
vlc_cond_signal
(
&
m_TerminateCond
);
vlc_mutex_unlock
(
&
m_TerminateLock
);
vlc_object_kill
(
m_pAtmoThread
);
vlc_thread_join
(
m_pAtmoThread
);
}
#else
SetEvent
(
m_hTerminateEvent
);
WaitForSingleObject
(
m_hThread
,
INFINITE
);
#endif
}
void
CThread
::
Run
()
{
m_bTerminated
=
ATMO_FALSE
;
#if defined(_ATMO_VLC_PLUGIN_)
m_pAtmoThread
->
b_die
=
VLC_FALSE
;
if
(
vlc_thread_create
(
m_pAtmoThread
,
"Atmo-CThread-Class"
,
CThread
::
ThreadProc
,
VLC_THREAD_PRIORITY_LOW
,
VLC_FALSE
))
{
msg_Err
(
m_pOwner
,
"cannot launch one of the AtmoLight threads"
);
}
#else
ResetEvent
(
m_hTerminateEvent
);
ResumeThread
(
m_hThread
);
#endif
}
/*
does a sleep if the sleep was interrupted through
the thread kill event return false...
*/
ATMO_BOOL
CThread
::
ThreadSleep
(
DWORD
millisekunden
)
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock
(
&
m_TerminateLock
);
int
value
=
vlc_cond_timedwait
(
&
m_TerminateCond
,
&
m_TerminateLock
,
mdate
()
+
(
mtime_t
)(
millisekunden
*
1000
));
vlc_mutex_unlock
(
&
m_TerminateLock
);
return
(
value
!=
0
);
#else
DWORD
res
=
WaitForSingleObject
(
m_hTerminateEvent
,
millisekunden
);
return
(
res
==
WAIT_TIMEOUT
);
#endif
}
modules/video_filter/atmo/AtmoThread.h
0 → 100644
View file @
1b637157
/*
* AtmoThread.h: Base thread class for all threads inside AtmoWin
*
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoThread_h_
#define _AtmoThread_h_
#include "AtmoDefs.h"
#if defined(_ATMO_VLC_PLUGIN_)
// use threading stuff from videolan!
# include <vlc/vlc.h>
# include <vlc_threads_funcs.h>
# include <vlc_threads.h>
typedef
struct
{
VLC_COMMON_MEMBERS
void
*
p_thread
;
/* cast to CThread * */
}
atmo_thread_t
;
#else
# include <windows.h>
#endif
class
CThread
{
protected:
#if defined(_ATMO_VLC_PLUGIN_)
atmo_thread_t
*
m_pAtmoThread
;
vlc_mutex_t
m_TerminateLock
;
vlc_cond_t
m_TerminateCond
;
vlc_object_t
*
m_pOwner
;
#else
HANDLE
m_hThread
;
DWORD
m_dwThreadID
;
HANDLE
m_hTerminateEvent
;
#endif
volatile
ATMO_BOOL
m_bTerminated
;
private:
#if defined(_ATMO_VLC_PLUGIN_)
static
void
ThreadProc
(
atmo_thread_t
*
pAtmoThread
);
#else
static
DWORD
WINAPI
ThreadProc
(
LPVOID
lpParameter
);
#endif
protected:
virtual
DWORD
Execute
(
void
);
ATMO_BOOL
ThreadSleep
(
DWORD
millisekunden
);
public:
#if defined(_ATMO_VLC_PLUGIN_)
CThread
(
vlc_object_t
*
pOwner
);
#else
CThread
(
void
);
#endif
virtual
~
CThread
(
void
);
void
Terminate
(
void
);
void
Run
();
};
#endif
modules/video_filter/atmo/AtmoTools.cpp
0 → 100644
View file @
1b637157
/*
* AtmoTools.cpp: Collection of tool and helperfunction
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoTools.h"
#include "AtmoLiveView.h"
#include "AtmoSerialConnection.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include "AtmoColorChanger.h"
# include "AtmoLeftRightColorChanger.h"
# include "AtmoDummyConnection.h"
# include "AtmoDmxSerialConnection.h"
#endif
CAtmoTools
::
CAtmoTools
(
void
)
{
}
CAtmoTools
::~
CAtmoTools
(
void
)
{
}
void
CAtmoTools
::
ShowShutdownColor
(
CAtmoDynData
*
pDynData
)
{
pDynData
->
LockCriticalSection
();
CAtmoConnection
*
atmoConnection
=
pDynData
->
getAtmoConnection
();
CAtmoConfig
*
atmoConfig
=
pDynData
->
getAtmoConfig
();
if
((
atmoConnection
!=
NULL
)
&&
(
atmoConfig
!=
NULL
))
{
int
r
[
ATMO_NUM_CHANNELS
],
g
[
ATMO_NUM_CHANNELS
],
b
[
ATMO_NUM_CHANNELS
],
i
;
// set a special color? on shutdown of the software? mostly may use black or so ...
// if this function ist disabled ... atmo will continuing to show the last color...
if
(
atmoConnection
->
isOpen
()
==
ATMO_TRUE
)
{
if
(
atmoConfig
->
isSetShutdownColor
()
==
1
)
{
for
(
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
{
r
[
i
]
=
atmoConfig
->
getShutdownColor_Red
();
g
[
i
]
=
atmoConfig
->
getShutdownColor_Green
();
b
[
i
]
=
atmoConfig
->
getShutdownColor_Blue
();
}
atmoConnection
->
SendData
(
ATMO_NUM_CHANNELS
,
r
,
g
,
b
);
}
}
}
pDynData
->
UnLockCriticalSection
();
}
EffectMode
CAtmoTools
::
SwitchEffect
(
CAtmoDynData
*
pDynData
,
EffectMode
newEffectMode
)
{
// may need a critical section??
if
(
pDynData
==
NULL
)
{
return
emUndefined
;
}
pDynData
->
LockCriticalSection
();
CAtmoConfig
*
atmoConfig
=
pDynData
->
getAtmoConfig
();
if
(
atmoConfig
==
NULL
)
{
pDynData
->
UnLockCriticalSection
();
return
emUndefined
;
}
CAtmoConnection
*
atmoConnection
=
pDynData
->
getAtmoConnection
();
EffectMode
oldEffectMode
=
atmoConfig
->
getEffectMode
();
CThread
*
currentEffect
=
pDynData
->
getEffectThread
();
// stop and delete/cleanup current Effect Thread...
pDynData
->
setEffectThread
(
NULL
);
if
(
currentEffect
!=
NULL
)
{
currentEffect
->
Terminate
();
delete
currentEffect
;
currentEffect
=
NULL
;
}
if
((
atmoConnection
!=
NULL
)
&&
(
atmoConnection
->
isOpen
()
==
ATMO_TRUE
))
{
// neuen EffectThread nur mit aktiver Connection starten...
switch
(
newEffectMode
)
{
case
emDisabled
:
break
;
case
emStaticColor
:
// get values from config - and put them to all channels?
int
r
[
ATMO_NUM_CHANNELS
],
g
[
ATMO_NUM_CHANNELS
],
b
[
ATMO_NUM_CHANNELS
];
for
(
int
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
{
r
[
i
]
=
(
atmoConfig
->
getStaticColor_Red
()
*
atmoConfig
->
getWhiteAdjustment_Red
())
/
255
;
g
[
i
]
=
(
atmoConfig
->
getStaticColor_Green
()
*
atmoConfig
->
getWhiteAdjustment_Green
())
/
255
;
b
[
i
]
=
(
atmoConfig
->
getStaticColor_Blue
()
*
atmoConfig
->
getWhiteAdjustment_Blue
())
/
255
;
}
atmoConnection
->
SendData
(
ATMO_NUM_CHANNELS
,
r
,
g
,
b
);
break
;
case
emLivePicture
:
currentEffect
=
new
CAtmoLiveView
(
pDynData
);
break
;
#if !defined(_ATMO_VLC_PLUGIN_)
case
emColorChange
:
currentEffect
=
new
CAtmoColorChanger
(
atmoConnection
,
atmoConfig
);
break
;
#endif
#if !defined(_ATMO_VLC_PLUGIN_)
case
emLrColorChange
:
currentEffect
=
new
CAtmoLeftRightColorChanger
(
atmoConnection
,
atmoConfig
);
break
;
#endif
}
}
atmoConfig
->
setEffectMode
(
newEffectMode
);
pDynData
->
setEffectThread
(
currentEffect
);
if
(
currentEffect
!=
NULL
)
currentEffect
->
Run
();
pDynData
->
UnLockCriticalSection
();
return
oldEffectMode
;
}
ATMO_BOOL
CAtmoTools
::
RecreateConnection
(
CAtmoDynData
*
pDynData
)
{
pDynData
->
LockCriticalSection
();
CAtmoConnection
*
current
=
pDynData
->
getAtmoConnection
();
AtmoConnectionType
act
=
pDynData
->
getAtmoConfig
()
->
getConnectionType
();
pDynData
->
setAtmoConnection
(
NULL
);
if
(
current
!=
NULL
)
{
current
->
CloseConnection
();
delete
current
;
}
switch
(
act
)
{
case
actSerialPort
:
{
CAtmoSerialConnection
*
tempConnection
=
new
CAtmoSerialConnection
(
pDynData
->
getAtmoConfig
());
if
(
tempConnection
->
OpenConnection
()
==
ATMO_FALSE
)
{
#if !defined(_ATMO_VLC_PLUGIN_)
char
errorMsgBuf
[
200
];
sprintf
(
errorMsgBuf
,
"Failed to open serial port com%d with errorcode: %d (0x%x)"
,
pDynData
->
getAtmoConfig
()
->
getComport
(),
tempConnection
->
getLastError
(),
tempConnection
->
getLastError
()
);
MessageBox
(
0
,
errorMsgBuf
,
"Error"
,
MB_ICONERROR
|
MB_OK
);
#endif
delete
tempConnection
;
pDynData
->
UnLockCriticalSection
();
return
ATMO_FALSE
;
}
pDynData
->
setAtmoConnection
(
tempConnection
);
CAtmoTools
::
SetChannelAssignment
(
pDynData
,
pDynData
->
getAtmoConfig
()
->
getCurrentChannelAssignment
());
pDynData
->
UnLockCriticalSection
();
return
ATMO_TRUE
;
}
#if !defined(_ATMO_VLC_PLUGIN_)
case
actDummy
:
{
CAtmoDummyConnection
*
tempConnection
=
new
CAtmoDummyConnection
(
pDynData
->
getHinstance
(),
pDynData
->
getAtmoConfig
());
if
(
tempConnection
->
OpenConnection
()
==
ATMO_FALSE
)
{
delete
tempConnection
;
pDynData
->
UnLockCriticalSection
();
return
ATMO_FALSE
;
}
pDynData
->
setAtmoConnection
(
tempConnection
);
CAtmoTools
::
SetChannelAssignment
(
pDynData
,
pDynData
->
getAtmoConfig
()
->
getCurrentChannelAssignment
());
pDynData
->
UnLockCriticalSection
();
return
ATMO_TRUE
;
}
case
actDMX
:
{
// create here your DMX connections... instead of the dummy....
CAtmoDmxSerialConnection
*
tempConnection
=
new
CAtmoDmxSerialConnection
(
pDynData
->
getAtmoConfig
());
if
(
tempConnection
->
OpenConnection
()
==
ATMO_FALSE
)
{
delete
tempConnection
;
pDynData
->
UnLockCriticalSection
();
return
ATMO_FALSE
;
}
pDynData
->
setAtmoConnection
(
tempConnection
);
CAtmoTools
::
SetChannelAssignment
(
pDynData
,
pDynData
->
getAtmoConfig
()
->
getCurrentChannelAssignment
());
pDynData
->
UnLockCriticalSection
();
return
ATMO_TRUE
;
}
#endif
default:
{
pDynData
->
UnLockCriticalSection
();
return
ATMO_FALSE
;
}
}
}
tColorPacket
CAtmoTools
::
WhiteCalibration
(
CAtmoConfig
*
pAtmoConfig
,
tColorPacket
ColorPacket
)
{
int
w_adj_red
=
pAtmoConfig
->
getWhiteAdjustment_Red
();
int
w_adj_green
=
pAtmoConfig
->
getWhiteAdjustment_Green
();
int
w_adj_blue
=
pAtmoConfig
->
getWhiteAdjustment_Blue
();
for
(
int
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
{
ColorPacket
.
channel
[
i
].
r
=
(
unsigned
char
)(((
int
)
w_adj_red
*
(
int
)
ColorPacket
.
channel
[
i
].
r
)
/
255
);
ColorPacket
.
channel
[
i
].
g
=
(
unsigned
char
)(((
int
)
w_adj_green
*
(
int
)
ColorPacket
.
channel
[
i
].
g
)
/
255
);
ColorPacket
.
channel
[
i
].
b
=
(
unsigned
char
)(((
int
)
w_adj_blue
*
(
int
)
ColorPacket
.
channel
[
i
].
b
)
/
255
);
}
return
ColorPacket
;
}
tColorPacket
CAtmoTools
::
ApplyGamma
(
CAtmoConfig
*
pAtmoConfig
,
tColorPacket
ColorPacket
)
{
return
ColorPacket
;
}
int
CAtmoTools
::
SetChannelAssignment
(
CAtmoDynData
*
pDynData
,
int
index
)
{
CAtmoConfig
*
pAtmoConfig
=
pDynData
->
getAtmoConfig
();
CAtmoConnection
*
pAtmoConnection
=
pDynData
->
getAtmoConnection
();
int
oldIndex
=
pAtmoConfig
->
getCurrentChannelAssignment
();
tChannelAssignment
*
ca
=
pAtmoConfig
->
getChannelAssignment
(
index
);
if
((
ca
!=
NULL
)
&&
(
pAtmoConnection
!=
NULL
))
{
pAtmoConnection
->
SetChannelAssignment
(
ca
);
pAtmoConfig
->
setCurrentChannelAssignment
(
index
);
}
return
oldIndex
;
}
#if !defined(_ATMO_VLC_PLUGIN_)
void
CAtmoTools
::
SaveBitmap
(
HDC
hdc
,
HBITMAP
hBmp
,
char
*
fileName
)
{
BITMAPINFO
bmpInfo
;
BITMAPFILEHEADER
bmpFileHeader
;
ZeroMemory
(
&
bmpInfo
,
sizeof
(
BITMAPINFO
));
bmpInfo
.
bmiHeader
.
biSize
=
sizeof
(
BITMAPINFOHEADER
);
GetDIBits
(
hdc
,
hBmp
,
0
,
0
,
NULL
,
&
bmpInfo
,
DIB_RGB_COLORS
);
if
(
bmpInfo
.
bmiHeader
.
biSizeImage
<=
0
)
bmpInfo
.
bmiHeader
.
biSizeImage
=
bmpInfo
.
bmiHeader
.
biWidth
*
abs
(
bmpInfo
.
bmiHeader
.
biHeight
)
*
(
bmpInfo
.
bmiHeader
.
biBitCount
+
7
)
/
8
;
void
*
pBuf
=
malloc
(
bmpInfo
.
bmiHeader
.
biSizeImage
);
bmpInfo
.
bmiHeader
.
biCompression
=
BI_RGB
;
GetDIBits
(
hdc
,
hBmp
,
0
,
bmpInfo
.
bmiHeader
.
biHeight
,
pBuf
,
&
bmpInfo
,
DIB_RGB_COLORS
);
bmpFileHeader
.
bfReserved1
=
0
;
bmpFileHeader
.
bfReserved2
=
0
;
bmpFileHeader
.
bfSize
=
sizeof
(
BITMAPFILEHEADER
)
+
sizeof
(
BITMAPINFOHEADER
)
+
bmpInfo
.
bmiHeader
.
biSizeImage
;
bmpFileHeader
.
bfType
=
'
MB
'
;
bmpFileHeader
.
bfOffBits
=
sizeof
(
BITMAPFILEHEADER
)
+
sizeof
(
BITMAPINFOHEADER
);
FILE
*
fp
=
NULL
;
fp
=
fopen
(
fileName
,
"wb"
);
fwrite
(
&
bmpFileHeader
,
sizeof
(
BITMAPFILEHEADER
),
1
,
fp
);
fwrite
(
&
bmpInfo
.
bmiHeader
,
sizeof
(
BITMAPINFOHEADER
),
1
,
fp
);
fwrite
(
pBuf
,
bmpInfo
.
bmiHeader
.
biSizeImage
,
1
,
fp
);
fclose
(
fp
);
}
#endif
modules/video_filter/atmo/AtmoTools.h
0 → 100644
View file @
1b637157
/*
* AtmoTools.h: Collection of tool and helperfunction
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoTools_h_
#define _AtmoTools_h_
#include "AtmoDefs.h"
#include "AtmoConfig.h"
#include "AtmoConnection.h"
#include "AtmoDynData.h"
/*
implements some tool functions - for use in different classes - and cases!
to avoid copy and paste code ...
*/
class
CAtmoTools
{
private:
CAtmoTools
(
void
);
~
CAtmoTools
(
void
);
public:
static
EffectMode
SwitchEffect
(
CAtmoDynData
*
pDynData
,
EffectMode
newEffectMode
);
static
void
ShowShutdownColor
(
CAtmoDynData
*
pDynData
);
static
ATMO_BOOL
RecreateConnection
(
CAtmoDynData
*
pDynData
);
static
tColorPacket
WhiteCalibration
(
CAtmoConfig
*
pAtmoConfig
,
tColorPacket
ColorPacket
);
static
tColorPacket
ApplyGamma
(
CAtmoConfig
*
pAtmoConfig
,
tColorPacket
ColorPacket
);
static
int
SetChannelAssignment
(
CAtmoDynData
*
pDynData
,
int
index
);
#if !defined(_ATMO_VLC_PLUGIN_)
static
void
SaveBitmap
(
HDC
hdc
,
HBITMAP
hBmp
,
char
*
fileName
);
#endif
};
#endif
modules/video_filter/atmo/AtmoZoneDefinition.cpp
0 → 100644
View file @
1b637157
#include "AtmoDefs.h"
#if defined (WIN32)
# include <windows.h>
#else
# include <vlc_codecs.h>
#endif
#include <math.h>
#include <stdio.h>
#include "AtmoZoneDefinition.h"
CAtmoZoneDefinition
::
CAtmoZoneDefinition
(
void
)
{
}
CAtmoZoneDefinition
::~
CAtmoZoneDefinition
(
void
)
{
}
void
CAtmoZoneDefinition
::
Fill
(
unsigned
char
value
)
{
for
(
int
i
=
0
;
i
<
IMAGE_SIZE
;
i
++
)
m_BasicWeight
[
i
]
=
value
;
}
// max weight to left
void
CAtmoZoneDefinition
::
FillGradientFromLeft
()
{
int
index
=
0
;
unsigned
char
col_norm
;
for
(
int
row
=
0
;
row
<
CAP_HEIGHT
;
row
++
)
{
for
(
int
col
=
0
;
col
<
CAP_WIDTH
;
col
++
)
{
// should be a value between 0 .. 255?
col_norm
=
(
255
*
(
CAP_WIDTH
-
col
-
1
))
/
(
CAP_WIDTH
-
1
);
m_BasicWeight
[
index
++
]
=
col_norm
;
}
}
}
// max weight to right
void
CAtmoZoneDefinition
::
FillGradientFromRight
()
{
int
index
=
0
;
unsigned
char
col_norm
;
for
(
int
row
=
0
;
row
<
CAP_HEIGHT
;
row
++
)
{
for
(
int
col
=
0
;
col
<
CAP_WIDTH
;
col
++
)
{
col_norm
=
(
255
*
col
)
/
(
CAP_WIDTH
-
1
);
// should be a value between 0 .. 255?
m_BasicWeight
[
index
++
]
=
col_norm
;
}
}
}
// max weight from top
void
CAtmoZoneDefinition
::
FillGradientFromTop
()
{
int
index
=
0
;
unsigned
char
row_norm
;
for
(
int
row
=
0
;
row
<
CAP_HEIGHT
;
row
++
)
{
row_norm
=
(
255
*
(
CAP_HEIGHT
-
row
-
1
))
/
(
CAP_HEIGHT
-
1
);
// should be a value between 0 .. 255?
for
(
int
col
=
0
;
col
<
CAP_WIDTH
;
col
++
)
{
m_BasicWeight
[
index
++
]
=
row_norm
;
}
}
}
// max weight from bottom
void
CAtmoZoneDefinition
::
FillGradientFromBottom
()
{
int
index
=
0
;
unsigned
char
row_norm
;
for
(
int
row
=
0
;
row
<
CAP_HEIGHT
;
row
++
)
{
row_norm
=
(
255
*
row
)
/
(
CAP_HEIGHT
-
1
);
// should be a value between 0 .. 255?
for
(
int
col
=
0
;
col
<
CAP_WIDTH
;
col
++
)
{
m_BasicWeight
[
index
++
]
=
row_norm
;
}
}
}
int
CAtmoZoneDefinition
::
LoadGradientFromBitmap
(
char
*
pszBitmap
)
{
// transform 256 color image (gray scale!)
// into m_basicWeight or use the GREEN value of a 24bit image!
// channel of a true color bitmap!
BITMAPINFO
bmpInfo
;
BITMAPFILEHEADER
bmpFileHeader
;
/*
#define ATMO_LOAD_GRADIENT_OK 0
#define ATMO_LOAD_GRADIENT_FAILED_SIZE 1
#define ATMO_LOAD_GRADIENT_FAILED_HEADER 2
*/
FILE
*
bmp
=
fopen
(
pszBitmap
,
"rb"
);
if
(
!
bmp
)
return
ATMO_LOAD_GRADIENT_FILENOTFOND
;
if
(
fread
(
&
bmpFileHeader
,
sizeof
(
BITMAPFILEHEADER
),
1
,
bmp
)
!=
1
)
{
fclose
(
bmp
);
return
ATMO_LOAD_GRADIENT_FAILED_SIZE
;
}
if
(
bmpFileHeader
.
bfType
!=
'
MB
'
)
{
fclose
(
bmp
);
return
ATMO_LOAD_GRADIENT_FAILED_HEADER
;
}
if
(
fread
(
&
bmpInfo
,
sizeof
(
BITMAPINFO
),
1
,
bmp
)
!=
1
)
{
fclose
(
bmp
);
return
ATMO_LOAD_GRADIENT_FAILED_SIZE
;
}
if
(
bmpInfo
.
bmiHeader
.
biCompression
!=
BI_RGB
)
{
fclose
(
bmp
);
return
ATMO_LOAD_GRADIENT_FAILED_FORMAT
;
}
if
((
bmpInfo
.
bmiHeader
.
biBitCount
!=
8
)
&&
(
bmpInfo
.
bmiHeader
.
biBitCount
!=
24
))
{
fclose
(
bmp
);
return
ATMO_LOAD_GRADIENT_FAILED_FORMAT
;
}
int
width
=
bmpInfo
.
bmiHeader
.
biWidth
;
int
height
=
bmpInfo
.
bmiHeader
.
biHeight
;
ATMO_BOOL
invertDirection
=
(
height
>
0
);
height
=
abs
(
height
);
if
((
width
!=
CAP_WIDTH
)
||
(
height
!=
CAP_HEIGHT
))
{
fclose
(
bmp
);
return
ATMO_LOAD_GRADIENT_FAILED_SIZE
;
}
fseek
(
bmp
,
bmpFileHeader
.
bfOffBits
,
SEEK_SET
);
int
imageSize
=
width
*
height
*
bmpInfo
.
bmiHeader
.
biBitCount
/
8
;
unsigned
char
*
pixelBuffer
=
(
unsigned
char
*
)
malloc
(
imageSize
);
if
(
fread
(
pixelBuffer
,
imageSize
,
1
,
bmp
)
!=
1
)
{
fclose
(
bmp
);
return
ATMO_LOAD_GRADIENT_FAILED_SIZE
;
}
if
(
bmpInfo
.
bmiHeader
.
biBitCount
==
8
)
{
int
ydest
;
for
(
int
y
=
0
;
y
<
CAP_HEIGHT
;
y
++
)
{
if
(
invertDirection
)
{
ydest
=
(
CAP_HEIGHT
-
y
-
1
);
}
else
{
ydest
=
y
;
}
for
(
int
x
=
0
;
x
<
CAP_WIDTH
;
x
++
)
{
// palette should be grey scale - so that index 0 is black and
// index 255 means white!
// everything else would produce funny results!
m_BasicWeight
[
ydest
*
CAP_WIDTH
+
x
]
=
pixelBuffer
[
y
*
CAP_WIDTH
+
x
];
}
}
}
if
(
bmpInfo
.
bmiHeader
.
biBitCount
==
24
)
{
int
ydest
;
for
(
int
y
=
0
;
y
<
CAP_HEIGHT
;
y
++
)
{
if
(
invertDirection
)
{
ydest
=
(
CAP_HEIGHT
-
y
-
1
);
}
else
{
ydest
=
y
;
}
for
(
int
x
=
0
;
x
<
CAP_WIDTH
;
x
++
)
{
// use the green value as reference...
m_BasicWeight
[
ydest
*
CAP_WIDTH
+
x
]
=
pixelBuffer
[
y
*
CAP_WIDTH
*
3
+
(
x
*
3
)
+
1
];
}
}
}
free
(
pixelBuffer
);
fclose
(
bmp
);
return
ATMO_LOAD_GRADIENT_OK
;
}
void
CAtmoZoneDefinition
::
UpdateWeighting
(
int
*
destWeight
,
int
WidescreenMode
,
int
newEdgeWeightning
)
{
/*
use the values in m_BasicWeight and newWeightning to
update the direct control array for the output thread!
*/
int
index
=
0
;
for
(
int
row
=
0
;
row
<
CAP_HEIGHT
;
row
++
)
{
for
(
int
col
=
0
;
col
<
CAP_HEIGHT
;
col
++
)
{
if
((
WidescreenMode
==
1
)
&&
((
row
<=
CAP_HEIGHT
/
8
)
||
(
row
>=
(
7
*
CAP_HEIGHT
)
/
8
)))
{
destWeight
[
index
]
=
0
;
}
else
{
destWeight
[
index
]
=
(
int
)(
255.0
*
(
float
)
pow
(
((
float
)
m_BasicWeight
[
index
])
/
255.0
,
newEdgeWeightning
));
}
index
++
;
}
}
}
void
CAtmoZoneDefinition
::
setZoneNumber
(
int
num
)
{
m_zonenumber
=
num
;
}
int
CAtmoZoneDefinition
::
getZoneNumber
()
{
return
m_zonenumber
;
}
modules/video_filter/atmo/AtmoZoneDefinition.h
0 → 100644
View file @
1b637157
#ifndef _AtmoZoneDefinition_h_
#define _AtmoZoneDefinition_h_
#include "AtmoDefs.h"
#define ATMO_LOAD_GRADIENT_OK 0
#define ATMO_LOAD_GRADIENT_FILENOTFOND 1
#define ATMO_LOAD_GRADIENT_FAILED_SIZE 2
#define ATMO_LOAD_GRADIENT_FAILED_HEADER 3
#define ATMO_LOAD_GRADIENT_FAILED_FORMAT 4
class
CAtmoZoneDefinition
{
private:
int
m_zonenumber
;
// just for identification and channel assignment!
unsigned
char
m_BasicWeight
[
IMAGE_SIZE
];
public:
CAtmoZoneDefinition
(
void
);
~
CAtmoZoneDefinition
(
void
);
void
Fill
(
unsigned
char
value
);
void
FillGradientFromLeft
();
void
FillGradientFromRight
();
void
FillGradientFromTop
();
void
FillGradientFromBottom
();
int
LoadGradientFromBitmap
(
char
*
pszBitmap
);
void
UpdateWeighting
(
int
*
destWeight
,
int
WidescreenMode
,
int
newEdgeWeightning
);
void
setZoneNumber
(
int
num
);
int
getZoneNumber
();
};
#endif
modules/video_filter/atmo/COPYING.txt
0 → 100644
View file @
1b637157
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.
You should have received a copy of the GNU 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
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
modules/video_filter/atmo/Modules.am
0 → 100644
View file @
1b637157
SOURCES_atmo = atmo.cpp AtmoDefs.h AtmoCalculations.cpp AtmoCalculations.h AtmoConfig.cpp AtmoConfig.h AtmoConnection.cpp AtmoConnection.h AtmoDynData.cpp AtmoDynData.h AtmoExternalCaptureInput.cpp AtmoExternalCaptureInput.h AtmoInput.cpp AtmoInput.h AtmoLiveView.cpp AtmoLiveView.h AtmoOutputFilter.cpp AtmoOutputFilter.h AtmoSerialConnection.cpp AtmoSerialConnection.h AtmoThread.cpp AtmoThread.h AtmoTools.cpp AtmoTools.h AtmoZoneDefinition.cpp AtmoZoneDefinition.h
modules/video_filter/atmo/README.txt
0 → 100644
View file @
1b637157
This piece of software is based on the software and descriptions mentioned below -
(re)Written by: Igor / Atmo (aka André Weber) - WeberAndre@gmx.de
Matthiaz
MacGyver2k
if you need to contact one of us - come to www.vdr-portal.de
http://www.vdr-portal.de/board/thread.php?threadid=59294 -- Description and Development of the Windows Software
http://www.vdr-portal.de/board/thread.php?threadid=48574 -- Description and Development of the Hardware part
See the file COPYING.txt for license information.
Original Readme - of the Linux Version - from where some code was used
to do the color calculations ...
######################################################################
This is the Atmolight-plugin for the Video Disk Recorder (VDR).
Written by: Eike Edener <vdr@edener.de>
Project's homepage: www.edener.de
Latest version available at: www.edener.de
See the file COPYING for license information.
Requirements: a full-featured DVB-card or
softdevice-plugin (2006-12-03: CVS-version necessary)
Description: Plugin for the Atmolight.
----------------------------------------------------------------------
for detailed informations visit the VDR-Wiki:
http://www.vdr-wiki.de/wiki/index.php/Atmo-plugin
Development:
http://www.vdr-portal.de/board/thread.php?threadid=48574
Known bugs:
n/a
----------------------------------------------------------------------
NOTE:
-------
If you want to change the Atmolight color from outside,
you can do this with a script using SVDRP-commands
(see scripts/disco.sh).
modules/video_filter/atmo/atmo.cpp
0 → 100644
View file @
1b637157
/*****************************************************************************
* atmo.cpp : "Atmo Light" video filter
*****************************************************************************
* Copyright (C) 2000-2006 the VideoLAN team
* $Id$
*
* Authors: André Weber (WeberAndre@gmx.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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
*****************************************************************************/
#include <stdlib.h>
/* malloc(), free() */
#include <string.h>
#include <math.h>
/* sin(), cos() */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
// #define __ATMO_DEBUG__
// [:Zs]+$
#include <vlc/vlc.h>
#include <vlc_vout.h>
#include <vlc_playlist.h>
#include "vlc_filter.h"
#include "AtmoDefs.h"
#include "AtmoDynData.h"
#include "AtmoLiveView.h"
#include "AtmoTools.h"
#include "AtmoExternalCaptureInput.h"
#include "AtmoConfig.h"
#include "AtmoConnection.h"
#include "AtmoSerialConnection.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
/* directly to vlc related functions required that the module is accepted */
static
int
CreateFilter
(
vlc_object_t
*
);
static
void
DestroyFilter
(
vlc_object_t
*
);
static
picture_t
*
Filter
(
filter_t
*
,
picture_t
*
);
/* callback for global variable state pause / continue / stop events */
static
void
AddStateVariableCallback
(
filter_t
*
);
static
void
DelStateVariableCallback
(
filter_t
*
);
static
int
StateCallback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
/* callback for variable crop-update */
static
void
AddCropVariableCallback
(
filter_t
*
);
static
void
DelCropVariableCallback
(
filter_t
*
);
static
int
CropCallback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
/* callback for atmo settings variables whose change
should be immediately realized and applied to output
*/
static
void
DelAtmoSettingsVariablesCallbacks
(
filter_t
*
);
static
void
AddAtmoSettingsVariablesCallbacks
(
filter_t
*
);
static
int
AtmoSettingsCallback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
#if defined(__ATMO_DEBUG__)
static
void
atmo_parse_crop
(
char
*
psz_cropconfig
,
video_format_t
fmt_in
,
video_format_t
fmt_render
,
int
&
i_visible_width
,
int
&
i_visible_height
,
int
&
i_x_offset
,
int
&
i_y_offset
);
#endif
/* function to shutdown the fade thread which is started on pause*/
static
void
CheckAndStopFadeThread
(
filter_t
*
);
/* extracts a small RGB (BGR) Image from an YUV image */
static
void
ExtractMiniImage_YUV
(
filter_sys_t
*
,
picture_t
*
,
uint8_t
*
);
#if defined(__ATMO_DEBUG__)
void
SaveBitmap
(
filter_sys_t
*
p_sys
,
uint8_t
*
p_pixels
,
char
*
psz_filename
);
#endif
/*****************************************************************************
* External Prototypes for the AtmoCtrlLib.DLL
*****************************************************************************/
/*
* if effectmode = emLivePicture then the source could be GDI (Screencapture)
* or External - this means another application delivers Pixeldata to AtmoWin
* Clientsoftware through AtmoCtrlLib.DLL and the COM Api
*/
#define lvsGDI 0
#define lvsExternal 1
/*
strings for settings menus and hints
*/
#define MODULE_DESCRIPTION N_ ( \
"This module allows to control an so called AtmoLight device which "\
"is connected to your computer.\n"\
"AtmoLight is the homebrew version of that what Philips calls AmbiLight.\n"\
"If you need further informations feel free to visit us at\n\n"\
"http://www.vdr-wiki.de/wiki/index.php/Atmo-plugin\n"\
"http://www.vdr-wiki.de/wiki/index.php/AtmoWin\n\n"\
"there you will find detailed descriptions how to build it for your self and "\
"where you can get the required parts and so on.\n There you can also see "\
"pictures and some movies showing such a device in live action...")
#if defined( __ATMO_DEBUG__ )
# define SAVEFRAMES_TEXT N_("Save Debug Frames")
# define SAVEFRAMES_LONGTEXT N_("Writes every 128th miniframe to a folder.")
# define FRAMEPATH_TEXT N_("Debug Frame Folder")
# define FRAMEPATH_LONGTEXT N_("defines the path where the debugframes " \
"should be saved")
#endif
#define WIDTH_TEXT N_("Extracted Image Width")
#define WIDTH_LONGTEXT N_("defines the width of the mini image for " \
"further processing (64 is default)")
#define HEIGHT_TEXT N_("Extracted Image Height")
#define HEIGHT_LONGTEXT N_("defines the height of the mini image for " \
"further processing (48 is default)")
#define PCOLOR_TEXT N_("use Pause Color")
#define PCOLOR_LONGTEXT N_("use the color defined below if the user " \
"paused the video.(have light to get another beer?)")
#define PCOLOR_RED_TEXT N_("Pause-Red")
#define PCOLOR_RED_LONGTEXT N_("the red component of pause color")
#define PCOLOR_GREEN_TEXT N_("Pause-Green")
#define PCOLOR_GREEN_LONGTEXT N_("the green component of pause color")
#define PCOLOR_BLUE_TEXT N_("Pause-Blue")
#define PCOLOR_BLUE_LONGTEXT N_("the blue component of pause color")
#define FADESTEPS_TEXT N_("Pause-Fadesteps")
#define FADESTEPS_LONGTEXT N_("Number of steps to change current color " \
"to pause color (each step takes 40ms)")
#define ECOLOR_RED_TEXT N_("End-Red")
#define ECOLOR_RED_LONGTEXT N_("the red component of the shutdown color")
#define ECOLOR_GREEN_TEXT N_("End-Green")
#define ECOLOR_GREEN_LONGTEXT N_("the green component of the shutdown color")
#define ECOLOR_BLUE_TEXT N_("End-Blue")
#define ECOLOR_BLUE_LONGTEXT N_("the blue component of the shutdown color")
#define EFADESTEPS_TEXT N_("End-Fadesteps")
#define EFADESTEPS_LONGTEXT N_("Number of steps to change current color to " \
"end color for dimming up the light in cinema " \
"style... (each step takes 40ms)")
#define USEWHITEADJ_TEXT N_("Use Software White adjust")
#define USEWHITEADJ_LONGTEXT N_("Should the buildin driver do a white " \
"adjust or you LED stripes? recommend.")
#define WHITE_RED_TEXT N_("White Red")
#define WHITE_RED_LONGTEXT N_("Red value of a pure white on your "\
"LED stripes.")
#define WHITE_GREEN_TEXT N_("White Green")
#define WHITE_GREEN_LONGTEXT N_("Green value of a pure white on your "\
"LED stripes.")
#define WHITE_BLUE_TEXT N_("White Blue")
#define WHITE_BLUE_LONGTEXT N_("Blue value of a pure white on your "\
"LED stripes.")
#define SERIALDEV_TEXT N_("Serial Port/Device")
#define SERIALDEV_LONGTEXT N_("Name of the serial port where the AtmoLight "\
"controller is attached to\n on Windows usually "\
"something like COM1 or COM2 on Linux /dev/ttyS01 f.e.")
#define EDGE_TEXT N_("Edge Weightning")
#define EDGE_LONGTEXT N_("increasing this value will result in color "\
"more depending on the border of the frame")
#define BRIGHTNESS_TEXT N_("Brightness")
#define BRIGHTNESS_LONGTEXT N_("overall Brightness of you LED stripes")
#define DARKNESS_TEXT N_("Darkness Limit")
#define DARKNESS_LONGTEXT N_("pixels with a saturation lower than this will "\
"be ignored should be greater than one for "\
"letterboxed videos")
#define HUEWINSIZE_TEXT N_("Hue windowing")
#define HUEWINSIZE_LONGTEXT N_("used for statistics")
#define SATWINSIZE_TEXT N_("Sat windowing")
#define SATWINSIZE_LONGTEXT N_("used for statistics")
#define MEANLENGTH_TEXT N_("Filter length [ms]")
#define MEANLENGTH_LONGTEXT N_("Time it takes until a color is complete "\
"changed, removes flickering")
#define MEANTHRESHOLD_TEXT N_("Filter threshold")
#define MEANTHRESHOLD_LONGTEXT N_("How much a color must changed, for an "\
"imediate color change")
#define MEANPERCENTNEW_TEXT N_("Filter Smoothness %")
#define MEANPERCENTNEW_LONGTEXT N_("Filter Smoothness")
#define FILTERMODE_TEXT N_("Filtermode")
#define FILTERMODE_LONGTEXT N_("kind of filtering which should be use to "\
"calcuate the color output")
static
int
pi_filtermode_values
[]
=
{
(
int
)
afmNoFilter
,
(
int
)
afmCombined
,
(
int
)
afmPercent
};
static
const
char
*
ppsz_filtermode_descriptions
[]
=
{
N_
(
"No Filtering"
),
N_
(
"Combined"
),
N_
(
"Percent"
)
};
#define FRAMEDELAY_TEXT N_("Framedelay")
#define FRAMEDELAY_LONGTEXT N_("helps to get video out and light effects "\
"insync values around 20ms should do the trick")
#define CHANNEL_0_ASSIGN_TEXT N_("Channel summary")
#define CHANNEL_1_ASSIGN_TEXT N_("Channel left")
#define CHANNEL_2_ASSIGN_TEXT N_("Channel right")
#define CHANNEL_3_ASSIGN_TEXT N_("Channel top")
#define CHANNEL_4_ASSIGN_TEXT N_("Channel bottom")
#define CHANNELASSIGN_LONGTEXT N_("maps the hardware channel X to logical "\
"channel Y to fix wrong wiring:-)")
static
int
pi_channel_assignment_values
[]
=
{
-
1
,
0
,
1
,
2
,
3
,
4
};
static
const
char
*
ppsz_channel_assignment_descriptions
[]
=
{
N_
(
"disabled"
),
N_
(
"summary"
),
N_
(
"left"
),
N_
(
"right"
),
N_
(
"top"
),
N_
(
"bottom"
)
};
#define ZONE_0_GRADIENT_TEXT N_("summary gradient")
#define ZONE_1_GRADIENT_TEXT N_("left gradient")
#define ZONE_2_GRADIENT_TEXT N_("right gradient")
#define ZONE_3_GRADIENT_TEXT N_("top gradient")
#define ZONE_4_GRADIENT_TEXT N_("bottom gradient")
#define ZONE_X_GRADIENT_LONG_TEXT N_("defines a small bitmap with 64x48 "\
"pixels, containing a grayscale gradient")
#if defined( WIN32 )
# define ATMOWINEXE_TEXT N_("Filename of AtmoWinA.exe")
# define ATMOWINEXE_LONGTEXT N_("if you wan't that the AtmoLight control "\
"software is launched by\nVLC enter the "\
"complete Filename of AtmoWinA.exe here")
# define USEBUILDIN_TEXT N_("Use buildin AtmoLight")
# define USEBUILDIN_LONGTEXT N_("VideoLan will directly use your AtmoLight "\
"hardware without running the external "\
"AtmoWinA.exe Userspace driver.")
#endif
#define CFG_PREFIX "atmo-"
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin
();
set_description
(
_
(
"AtmoLight Filter"
)
);
set_help
(
MODULE_DESCRIPTION
);
set_shortname
(
_
(
"AtmoLight"
));
set_capability
(
"video filter2"
,
0
);
set_category
(
CAT_VIDEO
);
set_subcategory
(
SUBCAT_VIDEO_VFILTER
);
#if defined(WIN32)
set_section
(
N_
(
"Choose between the buildin AtmoLight "
\
"driver or the external"
),
0
);
/*
only on win32 exists the option to use the buildin driver or
the more flexible external driver application
*/
add_bool
(
CFG_PREFIX
"usebuildin"
,
VLC_TRUE
,
NULL
,
USEBUILDIN_TEXT
,
USEBUILDIN_LONGTEXT
,
VLC_FALSE
);
add_string
(
CFG_PREFIX
"serialdev"
,
"COM1"
,
NULL
,
SERIALDEV_TEXT
,
SERIALDEV_LONGTEXT
,
VLC_FALSE
);
/*
on win32 the executeable external driver application
for automatic start if needed
*/
add_file
(
CFG_PREFIX
"atmowinexe"
,
NULL
,
NULL
,
ATMOWINEXE_TEXT
,
ATMOWINEXE_LONGTEXT
,
VLC_FALSE
);
#else
set_section
(
N_
(
"Enter connection of your AtmoLight hardware"
),
0
);
add_string
(
CFG_PREFIX
"serialdev"
,
"/dev/ttyS01"
,
NULL
,
SERIALDEV_TEXT
,
SERIALDEV_LONGTEXT
,
VLC_FALSE
);
#endif
/*
color which is showed if you want durring pausing
your movie ... used for both buildin / external
*/
set_section
(
N_
(
"Illuminate the room with this color on pause"
),
0
);
add_bool
(
CFG_PREFIX
"usepausecolor"
,
VLC_FALSE
,
NULL
,
PCOLOR_TEXT
,
PCOLOR_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"pcolor-red"
,
0
,
0
,
255
,
NULL
,
PCOLOR_RED_TEXT
,
PCOLOR_RED_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"pcolor-green"
,
0
,
0
,
255
,
NULL
,
PCOLOR_GREEN_TEXT
,
PCOLOR_GREEN_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"pcolor-blue"
,
192
,
0
,
255
,
NULL
,
PCOLOR_BLUE_TEXT
,
PCOLOR_BLUE_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"fadesteps"
,
50
,
1
,
250
,
NULL
,
FADESTEPS_TEXT
,
FADESTEPS_LONGTEXT
,
VLC_FALSE
);
/*
color which is showed if you finished watching your movie ...
used for both buildin / external
*/
set_section
(
N_
(
"Illuminate the room with this color on shutdown"
),
0
);
add_integer_with_range
(
CFG_PREFIX
"ecolor-red"
,
192
,
0
,
255
,
NULL
,
ECOLOR_RED_TEXT
,
ECOLOR_RED_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"ecolor-green"
,
192
,
0
,
255
,
NULL
,
ECOLOR_GREEN_TEXT
,
ECOLOR_GREEN_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"ecolor-blue"
,
192
,
0
,
255
,
NULL
,
ECOLOR_BLUE_TEXT
,
ECOLOR_BLUE_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"efadesteps"
,
50
,
1
,
250
,
NULL
,
EFADESTEPS_TEXT
,
EFADESTEPS_LONGTEXT
,
VLC_FALSE
);
/*
settings only for the buildin driver (if external driver app is used
these parameters are ignored.)
definition of parameters for the buildin filter ...
*/
set_section
(
N_
(
"Settings only for buildin Live Video Processor"
),
0
);
add_integer_with_range
(
CFG_PREFIX
"EdgeWeightning"
,
8
,
1
,
30
,
NULL
,
EDGE_TEXT
,
EDGE_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"Brightness"
,
100
,
50
,
300
,
NULL
,
BRIGHTNESS_TEXT
,
BRIGHTNESS_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"DarknessLimit"
,
5
,
0
,
10
,
NULL
,
DARKNESS_TEXT
,
DARKNESS_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"HueWinSize"
,
3
,
0
,
5
,
NULL
,
HUEWINSIZE_TEXT
,
HUEWINSIZE_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"SatWinSize"
,
3
,
0
,
5
,
NULL
,
SATWINSIZE_TEXT
,
SATWINSIZE_LONGTEXT
,
VLC_FALSE
);
add_integer
(
CFG_PREFIX
"filtermode"
,
(
int
)
afmCombined
,
NULL
,
FILTERMODE_TEXT
,
FILTERMODE_LONGTEXT
,
VLC_FALSE
);
change_integer_list
(
pi_filtermode_values
,
ppsz_filtermode_descriptions
,
0
);
add_integer_with_range
(
CFG_PREFIX
"MeanLength"
,
300
,
300
,
5000
,
NULL
,
MEANLENGTH_TEXT
,
MEANLENGTH_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"MeanThreshold"
,
40
,
1
,
100
,
NULL
,
MEANTHRESHOLD_TEXT
,
MEANTHRESHOLD_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"PercentNew"
,
50
,
1
,
100
,
NULL
,
MEANPERCENTNEW_TEXT
,
MEANPERCENTNEW_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"FrameDelay"
,
18
,
0
,
35
,
NULL
,
FRAMEDELAY_TEXT
,
FRAMEDELAY_LONGTEXT
,
VLC_FALSE
);
/*
output channel reordering
*/
set_section
(
N_
(
"Change channel assignment (fixes wrong wiring)"
),
0
);
add_integer
(
CFG_PREFIX
"channel_0"
,
0
,
NULL
,
CHANNEL_0_ASSIGN_TEXT
,
CHANNELASSIGN_LONGTEXT
,
VLC_FALSE
);
change_integer_list
(
pi_channel_assignment_values
,
ppsz_channel_assignment_descriptions
,
0
);
add_integer
(
CFG_PREFIX
"channel_1"
,
1
,
NULL
,
CHANNEL_1_ASSIGN_TEXT
,
CHANNELASSIGN_LONGTEXT
,
VLC_FALSE
);
change_integer_list
(
pi_channel_assignment_values
,
ppsz_channel_assignment_descriptions
,
0
);
add_integer
(
CFG_PREFIX
"channel_2"
,
2
,
NULL
,
CHANNEL_2_ASSIGN_TEXT
,
CHANNELASSIGN_LONGTEXT
,
VLC_FALSE
);
change_integer_list
(
pi_channel_assignment_values
,
ppsz_channel_assignment_descriptions
,
0
);
add_integer
(
CFG_PREFIX
"channel_3"
,
3
,
NULL
,
CHANNEL_3_ASSIGN_TEXT
,
CHANNELASSIGN_LONGTEXT
,
VLC_FALSE
);
change_integer_list
(
pi_channel_assignment_values
,
ppsz_channel_assignment_descriptions
,
0
);
add_integer
(
CFG_PREFIX
"channel_4"
,
4
,
NULL
,
CHANNEL_4_ASSIGN_TEXT
,
CHANNELASSIGN_LONGTEXT
,
VLC_FALSE
);
change_integer_list
(
pi_channel_assignment_values
,
ppsz_channel_assignment_descriptions
,
0
);
/*
LED color white calibration
*/
set_section
(
N_
(
"Adjust the white light to your LED stripes"
),
0
);
add_bool
(
CFG_PREFIX
"whiteadj"
,
VLC_TRUE
,
NULL
,
USEWHITEADJ_TEXT
,
USEWHITEADJ_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"white-red"
,
255
,
0
,
255
,
NULL
,
WHITE_RED_TEXT
,
WHITE_RED_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"white-green"
,
255
,
0
,
255
,
NULL
,
WHITE_GREEN_TEXT
,
WHITE_GREEN_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"white-blue"
,
255
,
0
,
255
,
NULL
,
WHITE_BLUE_TEXT
,
WHITE_BLUE_LONGTEXT
,
VLC_FALSE
);
/* end of definition of parameter for the buildin filter ... part 1 */
/*
only for buildin (external has own definition) per default the calucation
used linear gradients for assigning a priority to the pixel - depending
how near they are to the border ...for changing this you can create 64x48
Pixel BMP files - which contain your own grayscale... (you can produce funny
effects with this...) the images MUST not compressed, should have 24-bit per
pixel, or a simple 256 color grayscale palette
*/
set_section
(
N_
(
"Change gradients"
),
0
);
add_file
(
CFG_PREFIX
"gradient_zone_0"
,
NULL
,
NULL
,
ZONE_0_GRADIENT_TEXT
,
ZONE_X_GRADIENT_LONG_TEXT
,
VLC_TRUE
);
add_file
(
CFG_PREFIX
"gradient_zone_1"
,
NULL
,
NULL
,
ZONE_1_GRADIENT_TEXT
,
ZONE_X_GRADIENT_LONG_TEXT
,
VLC_TRUE
);
add_file
(
CFG_PREFIX
"gradient_zone_2"
,
NULL
,
NULL
,
ZONE_2_GRADIENT_TEXT
,
ZONE_X_GRADIENT_LONG_TEXT
,
VLC_TRUE
);
add_file
(
CFG_PREFIX
"gradient_zone_3"
,
NULL
,
NULL
,
ZONE_3_GRADIENT_TEXT
,
ZONE_X_GRADIENT_LONG_TEXT
,
VLC_TRUE
);
add_file
(
CFG_PREFIX
"gradient_zone_4"
,
NULL
,
NULL
,
ZONE_4_GRADIENT_TEXT
,
ZONE_X_GRADIENT_LONG_TEXT
,
VLC_TRUE
);
#if defined(__ATMO_DEBUG__)
add_bool
(
CFG_PREFIX
"saveframes"
,
VLC_FALSE
,
NULL
,
SAVEFRAMES_TEXT
,
SAVEFRAMES_LONGTEXT
,
VLC_FALSE
);
add_string
(
CFG_PREFIX
"framepath"
,
""
,
NULL
,
FRAMEPATH_TEXT
,
FRAMEPATH_LONGTEXT
,
VLC_FALSE
);
#endif
/*
may be later if computers gets more power ;-) than now we increase
the samplesize from which we do the stats for output color calculation
*/
add_integer_with_range
(
CFG_PREFIX
"width"
,
64
,
64
,
512
,
NULL
,
WIDTH_TEXT
,
WIDTH_LONGTEXT
,
VLC_TRUE
);
add_integer_with_range
(
CFG_PREFIX
"height"
,
48
,
48
,
384
,
NULL
,
HEIGHT_TEXT
,
HEIGHT_LONGTEXT
,
VLC_TRUE
);
add_shortcut
(
"atmo"
);
set_callbacks
(
CreateFilter
,
DestroyFilter
);
vlc_module_end
();
static
const
char
*
ppsz_filter_options
[]
=
{
#if defined(WIN32)
"usebuildin"
,
#endif
"serialdev"
,
"EdgeWeightning"
,
"Brightness"
,
"DarknessLimit"
,
"HueWinSize"
,
"SatWinSize"
,
"filtermode"
,
"MeanLength"
,
"MeanThreshold"
,
"PercentNew"
,
"FrameDelay"
,
"channel_0"
,
"channel_1"
,
"channel_2"
,
"channel_3"
,
"channel_4"
,
"whiteadj"
,
"white-red"
,
"white-green"
,
"white-blue"
,
"usepausecolor"
,
"pcolor-red"
,
"pcolor-green"
,
"pcolor-blue"
,
"fadesteps"
,
"ecolor-red"
,
"ecolor-green"
,
"ecolor-blue"
,
"efadesteps"
,
#if defined(WIN32 )
"usebuildin"
,
"atmowinexe"
,
#endif
#if defined(__ATMO_DEBUG__)
"saveframes"
,
"framepath"
,
#endif
"width"
,
"height"
,
"gradient_zone_0"
,
"gradient_zone_1"
,
"gradient_zone_2"
,
"gradient_zone_3"
,
"gradient_zone_4"
,
NULL
};
/*****************************************************************************
* fadethread_t: Color Fading Thread
*****************************************************************************
* changes slowly the color of the output if videostream gets paused...
*****************************************************************************
*/
typedef
struct
{
VLC_COMMON_MEMBERS
filter_t
*
p_filter
;
/* tell the thread which color should be the target of fading */
uint8_t
ui_red
;
uint8_t
ui_green
;
uint8_t
ui_blue
;
/* how many steps should happen until this */
int
i_steps
;
}
fadethread_t
;
static
void
FadeToColorThread
(
fadethread_t
*
p_fadethread
);
/*****************************************************************************
* filter_sys_t: AtmoLight filter method descriptor
*****************************************************************************
* It describes the AtmoLight specific properties of an video filter.
*****************************************************************************/
struct
filter_sys_t
{
/*
special for the access of the p_fadethread member all other members
need no special protection so far!
*/
vlc_mutex_t
filter_lock
;
vlc_bool_t
b_enabled
;
int32_t
i_AtmoOldEffect
;
vlc_bool_t
b_pause_live
;
int32_t
i_atmo_width
;
int32_t
i_atmo_height
;
#if defined(__ATMO_DEBUG__)
vlc_bool_t
b_saveframes
;
int
i_framecounter
;
char
sz_framepath
[
MAX_PATH
];
#endif
/* light color durring movie pause ... */
vlc_bool_t
b_usepausecolor
;
uint8_t
ui_pausecolor_red
;
uint8_t
ui_pausecolor_green
;
uint8_t
ui_pausecolor_blue
;
int
i_fadesteps
;
/* light color on movie finish ... */
uint8_t
ui_endcolor_red
;
uint8_t
ui_endcolor_green
;
uint8_t
ui_endcolor_blue
;
int
i_endfadesteps
;
fadethread_t
*
p_fadethread
;
/* Variables for buildin driver only... */
/* is only present and initialized if the internal driver is used*/
CAtmoConfig
*
p_atmo_config
;
/* storage for temporal settings "volatile" */
CAtmoDynData
*
p_atmo_dyndata
;
/* initialized for buildin driver with AtmoCreateTransferBuffers */
BITMAPINFOHEADER
mini_image_format
;
/* is only use buildin driver! */
uint8_t
*
p_atmo_transfer_buffer
;
/* end buildin driver */
/*
contains the real output size of the video calculated on
change event of the variable "crop" from vout
*/
int32_t
i_crop_x_offset
;
int32_t
i_crop_y_offset
;
int32_t
i_crop_width
;
int32_t
i_crop_height
;
void
(
*
pf_extract_mini_image
)
(
filter_sys_t
*
p_sys
,
picture_t
*
p_inpic
,
uint8_t
*
p_transfer_dest
);
#if defined( WIN32 )
/* External Library as wrapper arround COM Stuff */
HINSTANCE
h_AtmoCtrl
;
int32_t
(
*
pf_ctrl_atmo_initialize
)
(
void
);
void
(
*
pf_ctrl_atmo_finalize
)
(
int32_t
what
);
int32_t
(
*
pf_ctrl_atmo_switch_effect
)
(
int32_t
);
int32_t
(
*
pf_ctrl_atmo_set_live_source
)
(
int32_t
);
void
(
*
pf_ctrl_atmo_create_transfer_buffers
)
(
int32_t
,
int32_t
,
int32_t
,
int32_t
);
uint8_t
*
(
*
pf_ctrl_atmo_lock_transfer_buffer
)
(
void
);
void
(
*
pf_ctrl_atmo_send_pixel_data
)
(
void
);
#endif
};
/*
initialize previously configured Atmo Light environment
- if internal is enabled try to access the device on the serial port
- if not internal is enabled and we are on win32 try to initialize
the previously loaded DLL ...
Return Values may be: -1 (failed for some reason - filter will be disabled)
1 Ok. lets rock
*/
static
int32_t
AtmoInitialize
(
filter_t
*
p_filter
,
vlc_bool_t
b_for_thread
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_sys
->
p_atmo_config
)
{
if
(
b_for_thread
==
VLC_FALSE
)
{
/* open com port */
/* setup Output Threads ... */
msg_Dbg
(
p_filter
,
"open serial connection %s"
,
p_sys
->
p_atmo_config
->
getSerialDevice
());
if
(
CAtmoTools
::
RecreateConnection
(
p_sys
->
p_atmo_dyndata
)
==
ATMO_TRUE
)
{
msg_Dbg
(
p_filter
,
"start live view thread ..."
);
CAtmoTools
::
SwitchEffect
(
p_sys
->
p_atmo_dyndata
,
emLivePicture
);
msg_Dbg
(
p_filter
,
"live view thread launched..."
);
return
1
;
}
else
{
msg_Err
(
p_filter
,
"failed to open serial device? some other software/driver may use it?"
);
}
}
#if defined(WIN32)
}
else
if
(
p_sys
->
pf_ctrl_atmo_initialize
)
{
/* on win32 with active ctrl dll */
return
p_sys
->
pf_ctrl_atmo_initialize
();
#endif
}
return
-
1
;
}
/*
prepare the shutdown of the effect threads,
for build in filter - close the serialport after finishing the threads...
cleanup possible loaded DLL...
*/
static
void
AtmoFinalize
(
filter_t
*
p_filter
,
int32_t
what
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_sys
->
p_atmo_config
)
{
if
(
what
==
1
)
{
CAtmoDynData
*
p_atmo_dyndata
=
p_sys
->
p_atmo_dyndata
;
if
(
p_atmo_dyndata
)
{
p_atmo_dyndata
->
LockCriticalSection
();
CThread
*
p_effect_thread
=
p_atmo_dyndata
->
getEffectThread
();
p_atmo_dyndata
->
setEffectThread
(
NULL
);
if
(
p_effect_thread
!=
NULL
)
{
/*
forced the thread to die...
and wait for termination of the thread
*/
p_effect_thread
->
Terminate
();
delete
p_effect_thread
;
msg_Dbg
(
p_filter
,
"effect thread died peacefully"
);
}
/*
close serial port if it is open (all OS specific is inside
CAtmoSerialConnection implemented / defined)
*/
CAtmoConnection
*
p_atmo_connection
=
p_atmo_dyndata
->
getAtmoConnection
();
p_atmo_dyndata
->
setAtmoConnection
(
NULL
);
if
(
p_atmo_connection
)
{
p_atmo_connection
->
CloseConnection
();
delete
p_atmo_connection
;
}
p_atmo_dyndata
->
UnLockCriticalSection
();
}
}
#if defined(WIN32)
}
else
if
(
p_sys
->
pf_ctrl_atmo_finalize
)
{
/* on win32 with active ctrl dll */
p_sys
->
pf_ctrl_atmo_finalize
(
what
);
#endif
}
}
/*
switch the current light effect - does only something on win32, with the
external libraries - if the buildin effects are used nothing happens
*/
static
int32_t
AtmoSwitchEffect
(
filter_t
*
p_filter
,
int32_t
newMode
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_sys
->
p_atmo_config
)
{
/*
buildin driver
doesnt know different modes for effects so this
function call would just do nothing special
in this case
*/
#if defined(WIN32)
}
else
if
(
p_sys
->
pf_ctrl_atmo_switch_effect
)
{
/* on win32 with active ctrl dll */
return
p_sys
->
pf_ctrl_atmo_switch_effect
(
newMode
);
#endif
}
return
emDisabled
;
}
/*
set the current live picture source, does only something on win32,
with the external libraries - if the buildin effects are used nothing
happens...
*/
static
int32_t
AtmoSetLiveSource
(
filter_t
*
p_filter
,
int32_t
newSource
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_sys
->
p_atmo_config
)
{
/*
buildin driver
doesnt know different sources so this
function call would just do nothing special
in this case
*/
#if defined(WIN32)
}
else
if
(
p_sys
->
pf_ctrl_atmo_set_live_source
)
{
/* on win32 with active ctrl dll */
return
p_sys
->
pf_ctrl_atmo_set_live_source
(
newSource
);
#endif
}
return
lvsGDI
;
}
/*
setup the pixel transferbuffers which is used to transfer pixeldata from
the filter to the effect thread, and possible accross the process
boundaries on win32, with the external DLL
*/
static
void
AtmoCreateTransferBuffers
(
filter_t
*
p_filter
,
int32_t
FourCC
,
int32_t
bytePerPixel
,
int32_t
width
,
int32_t
height
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_sys
->
p_atmo_config
)
{
/*
we need a buffer where the image is stored (only for transfer
to the processing thread)
*/
if
(
p_sys
->
p_atmo_transfer_buffer
)
free
(
p_sys
->
p_atmo_transfer_buffer
);
p_sys
->
p_atmo_transfer_buffer
=
(
uint8_t
*
)
malloc
(
bytePerPixel
*
width
*
height
);
memset
(
&
p_sys
->
mini_image_format
,
0
,
sizeof
(
BITMAPINFOHEADER
));
p_sys
->
mini_image_format
.
biSize
=
sizeof
(
BITMAPINFOHEADER
);
p_sys
->
mini_image_format
.
biWidth
=
width
;
p_sys
->
mini_image_format
.
biHeight
=
height
;
p_sys
->
mini_image_format
.
biBitCount
=
bytePerPixel
*
8
;
p_sys
->
mini_image_format
.
biCompression
=
FourCC
;
#if defined(WIN32)
}
else
if
(
p_sys
->
pf_ctrl_atmo_create_transfer_buffers
)
{
/* on win32 with active ctrl dll */
p_sys
->
pf_ctrl_atmo_create_transfer_buffers
(
FourCC
,
bytePerPixel
,
width
,
height
);
#endif
}
}
/*
acquire the transfer buffer pointer the buildin version only
returns the pointer to the allocated buffer ... the
external version on win32 has to do some COM stuff to lock the
Variant Byte array which is behind the buffer
*/
static
uint8_t
*
AtmoLockTransferBuffer
(
filter_t
*
p_filter
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_sys
->
p_atmo_config
)
{
return
p_sys
->
p_atmo_transfer_buffer
;
#if defined(WIN32)
}
else
if
(
p_sys
->
pf_ctrl_atmo_lock_transfer_buffer
)
{
/* on win32 with active ctrl dll */
return
p_sys
->
pf_ctrl_atmo_lock_transfer_buffer
();
#endif
}
return
NULL
;
}
/*
send the content of current pixel buffer got with AtmoLockTransferBuffer
to the processing threads
- build in version - will forward the data to AtmoExternalCaptureInput Thread
- win32 external - will do the same, but across the process boundaries via
COM to the AtmoWinA.exe Process
*/
static
void
AtmoSendPixelData
(
filter_t
*
p_filter
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_sys
->
p_atmo_config
&&
p_sys
->
p_atmo_transfer_buffer
)
{
CAtmoDynData
*
p_atmo_dyndata
=
p_sys
->
p_atmo_dyndata
;
if
(
p_atmo_dyndata
)
{
/*
the cast will go Ok because we are inside videolan there is only
this kind of effect thread implemented!
*/
CAtmoLiveView
*
p_atmo_live_view_thread
=
(
CAtmoLiveView
*
)
p_atmo_dyndata
->
getEffectThread
();
if
(
p_atmo_live_view_thread
)
{
/*
the same as above inside videolan only this single kind of
input exists so we can cast without further tests!
*/
CAtmoExternalCaptureInput
*
p_atmo_external_capture_input_thread
=
(
CAtmoExternalCaptureInput
*
)
p_atmo_live_view_thread
->
getAtmoInput
();
if
(
p_atmo_external_capture_input_thread
)
{
/*
this call will do a 1:1 copy of this buffer, and wakeup
the thread from normal sleeping
*/
p_atmo_external_capture_input_thread
->
DeliverNewSourceDataPaket
(
&
p_sys
->
mini_image_format
,
p_sys
->
p_atmo_transfer_buffer
);
}
}
}
#if defined(WIN32)
}
else
if
(
p_sys
->
pf_ctrl_atmo_send_pixel_data
)
{
/* on win32 with active ctrl dll */
p_sys
->
pf_ctrl_atmo_send_pixel_data
();
#endif
}
}
/*
Shutdown AtmoLight finally - is call from DestroyFilter
does the cleanup restores the effectmode on the external Software
(only win32) and possible setup the final light ...
*/
static
void
Atmo_Shutdown
(
filter_t
*
p_filter
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_sys
->
b_enabled
==
VLC_TRUE
)
{
/*
if there is a still running show pause color thread kill him!
*/
CheckAndStopFadeThread
(
p_filter
);
if
(
p_sys
->
p_atmo_config
||
(
p_sys
->
i_AtmoOldEffect
==
emStaticColor
))
{
/*
fade to end color (in case of external AtmoWin Software
assume that the static color will equal to this
one to get a soft change and no flash!
*/
p_sys
->
b_pause_live
=
VLC_TRUE
;
// perpare spawn fadeing thread
vlc_mutex_lock
(
&
p_sys
->
filter_lock
);
p_sys
->
p_fadethread
=
(
fadethread_t
*
)
vlc_object_create
(
p_filter
,
sizeof
(
fadethread_t
)
);
p_sys
->
p_fadethread
->
p_filter
=
p_filter
;
p_sys
->
p_fadethread
->
ui_red
=
p_sys
->
ui_endcolor_red
;
p_sys
->
p_fadethread
->
ui_green
=
p_sys
->
ui_endcolor_green
;
p_sys
->
p_fadethread
->
ui_blue
=
p_sys
->
ui_endcolor_blue
;
p_sys
->
p_fadethread
->
i_steps
=
p_sys
->
i_endfadesteps
;
if
(
vlc_thread_create
(
p_sys
->
p_fadethread
,
"AtmoLight fadeing"
,
FadeToColorThread
,
VLC_THREAD_PRIORITY_LOW
,
VLC_FALSE
)
)
{
msg_Err
(
p_filter
,
"cannot create FadeToColorThread"
);
vlc_object_destroy
(
p_sys
->
p_fadethread
);
p_sys
->
p_fadethread
=
NULL
;
vlc_mutex_unlock
(
&
p_sys
->
filter_lock
);
}
else
{
vlc_mutex_unlock
(
&
p_sys
->
filter_lock
);
/* wait for the thread... */
vlc_thread_join
(
p_sys
->
p_fadethread
);
vlc_object_destroy
(
p_sys
->
p_fadethread
);
p_sys
->
p_fadethread
=
NULL
;
}
}
if
(
p_sys
->
i_AtmoOldEffect
!=
emLivePicture
)
AtmoSwitchEffect
(
p_filter
,
p_sys
->
i_AtmoOldEffect
);
else
AtmoSetLiveSource
(
p_filter
,
lvsGDI
);
AtmoFinalize
(
p_filter
,
1
);
/* disable filter method .. */
p_sys
->
b_enabled
=
VLC_FALSE
;
}
}
/*
initialize the filter_sys_t structure with the data from the settings
variables - if the external filter on win32 is enabled try loading the DLL,
if this fails fallback to the buildin software
*/
static
void
Atmo_SetupParameters
(
filter_t
*
p_filter
)
{
vlc_bool_t
b_use_buildin_driver
=
VLC_TRUE
;
char
*
psz_path
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
/* default filter disabled until DLL loaded and Init Success!*/
p_sys
->
b_enabled
=
VLC_FALSE
;
/* setup default mini image size (may be later a user option) */
p_sys
->
i_atmo_width
=
64
;
p_sys
->
i_atmo_height
=
48
;
vlc_mutex_init
(
p_filter
,
&
p_sys
->
filter_lock
);
#if defined(WIN32)
/*
only on WIN32 the user has the choice between
internal driver and external
*/
b_use_buildin_driver
=
var_CreateGetBoolCommand
(
p_filter
,
CFG_PREFIX
"usebuildin"
);
if
(
b_use_buildin_driver
==
VLC_FALSE
)
{
/* Load the Com Wrapper Library (source available) */
p_sys
->
h_AtmoCtrl
=
LoadLibraryA
(
"AtmoCtrlLib.dll"
);
if
(
p_sys
->
h_AtmoCtrl
!=
NULL
)
{
msg_Dbg
(
p_filter
,
"LoadLibrary('AtmoCtrlLib.dll'); Success"
);
/* importing all required functions I hope*/
p_sys
->
pf_ctrl_atmo_initialize
=
(
int32_t
(
*
)(
void
))
GetProcAddress
(
p_sys
->
h_AtmoCtrl
,
"AtmoInitialize"
);
if
(
!
p_sys
->
pf_ctrl_atmo_initialize
)
msg_Err
(
p_filter
,
"export AtmoInitialize missing."
);
p_sys
->
pf_ctrl_atmo_finalize
=
(
void
(
*
)(
int32_t
))
GetProcAddress
(
p_sys
->
h_AtmoCtrl
,
"AtmoFinalize"
);
if
(
!
p_sys
->
pf_ctrl_atmo_finalize
)
msg_Err
(
p_filter
,
"export AtmoFinalize missing."
);
p_sys
->
pf_ctrl_atmo_switch_effect
=
(
int32_t
(
*
)(
int32_t
))
GetProcAddress
(
p_sys
->
h_AtmoCtrl
,
"AtmoSwitchEffect"
);
if
(
!
p_sys
->
pf_ctrl_atmo_switch_effect
)
msg_Err
(
p_filter
,
"export AtmoSwitchEffect missing."
);
p_sys
->
pf_ctrl_atmo_set_live_source
=
(
int32_t
(
*
)(
int32_t
))
GetProcAddress
(
p_sys
->
h_AtmoCtrl
,
"AtmoSetLiveSource"
);
if
(
!
p_sys
->
pf_ctrl_atmo_set_live_source
)
msg_Err
(
p_filter
,
"export AtmoSetLiveSource missing."
);
p_sys
->
pf_ctrl_atmo_create_transfer_buffers
=
(
void
(
*
)(
int32_t
,
int32_t
,
int32_t
,
int32_t
))
GetProcAddress
(
p_sys
->
h_AtmoCtrl
,
"AtmoCreateTransferBuffers"
);
if
(
!
p_sys
->
pf_ctrl_atmo_create_transfer_buffers
)
msg_Err
(
p_filter
,
"export AtmoCreateTransferBuffers missing."
);
p_sys
->
pf_ctrl_atmo_lock_transfer_buffer
=
(
uint8_t
*
(
*
)
(
void
))
GetProcAddress
(
p_sys
->
h_AtmoCtrl
,
"AtmoLockTransferBuffer"
);
if
(
!
p_sys
->
pf_ctrl_atmo_lock_transfer_buffer
)
msg_Err
(
p_filter
,
"export AtmoLockTransferBuffer missing."
);
p_sys
->
pf_ctrl_atmo_send_pixel_data
=
(
void
(
*
)(
void
))
GetProcAddress
(
p_sys
->
h_AtmoCtrl
,
"AtmoSendPixelData"
);
if
(
!
p_sys
->
pf_ctrl_atmo_send_pixel_data
)
msg_Err
(
p_filter
,
"export AtmoSendPixelData missing."
);
}
else
{
/* the DLL is missing try internal filter ...*/
msg_Warn
(
p_filter
,
"AtmoCtrlLib.dll missing fallback to internal driver"
);
b_use_buildin_driver
=
VLC_TRUE
;
}
}
#endif
if
(
b_use_buildin_driver
==
VLC_TRUE
)
{
msg_Dbg
(
p_filter
,
"use buildin driver"
);
/*
now we have to read a lof of options from the config dialog
most important the serial device if not set ... we can skip
the rest and disable the filter...
*/
char
*
psz_serialdev
=
var_CreateGetStringCommand
(
p_filter
,
CFG_PREFIX
"serialdev"
);
if
(
psz_serialdev
&&
(
strlen
(
psz_serialdev
)
>
0
))
{
msg_Dbg
(
p_filter
,
"use buildin driver on port %s"
,
psz_serialdev
);
p_sys
->
p_atmo_config
=
new
CAtmoConfig
();
p_sys
->
p_atmo_config
->
setSerialDevice
(
psz_serialdev
);
p_sys
->
p_atmo_config
->
setLiveViewFilterMode
(
(
AtmoFilterMode
)
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"filtermode"
)
);
p_sys
->
p_atmo_config
->
setLiveViewFilter_PercentNew
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"PercentNew"
)
);
p_sys
->
p_atmo_config
->
setLiveViewFilter_MeanLength
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"MeanLength"
)
);
p_sys
->
p_atmo_config
->
setLiveViewFilter_MeanThreshold
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"MeanThreshold"
)
);
p_sys
->
p_atmo_config
->
setLiveView_EdgeWeighting
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"EdgeWeightning"
)
);
p_sys
->
p_atmo_config
->
setLiveView_BrightCorrect
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"Brightness"
)
);
p_sys
->
p_atmo_config
->
setLiveView_DarknessLimit
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"DarknessLimit"
)
);
p_sys
->
p_atmo_config
->
setLiveView_HueWinSize
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"HueWinSize"
)
);
p_sys
->
p_atmo_config
->
setLiveView_SatWinSize
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"SatWinSize"
)
);
/* currently not required inside vlc */
p_sys
->
p_atmo_config
->
setLiveView_WidescreenMode
(
0
);
p_sys
->
p_atmo_config
->
setLiveView_FrameDelay
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"FrameDelay"
)
);
p_sys
->
p_atmo_config
->
setUseSoftwareWhiteAdj
(
var_CreateGetBoolCommand
(
p_filter
,
CFG_PREFIX
"whiteadj"
)
);
p_sys
->
p_atmo_config
->
setWhiteAdjustment_Red
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"white-red"
)
);
p_sys
->
p_atmo_config
->
setWhiteAdjustment_Green
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"white-green"
)
);
p_sys
->
p_atmo_config
->
setWhiteAdjustment_Blue
(
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"white-blue"
)
);
tChannelAssignment
*
p_channel_assignment
=
p_sys
->
p_atmo_config
->
getChannelAssignment
(
0
);
p_channel_assignment
->
mappings
[
0
]
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"channel_0"
);
p_channel_assignment
->
mappings
[
1
]
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"channel_1"
);
p_channel_assignment
->
mappings
[
2
]
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"channel_2"
);
p_channel_assignment
->
mappings
[
3
]
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"channel_3"
);
p_channel_assignment
->
mappings
[
4
]
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"channel_4"
);
for
(
int
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
msg_Dbg
(
p_filter
,
"map software channel %d to hardware channel %d"
,
p_channel_assignment
->
mappings
[
i
],
i
);
// gradient_zone_0
char
psz_gradient_var_name
[
30
];
char
*
psz_gradient_file
;
for
(
int
i
=
0
;
i
<
ATMO_NUM_CHANNELS
;
i
++
)
{
sprintf
(
psz_gradient_var_name
,
CFG_PREFIX
"gradient_zone_%d"
,
i
);
psz_gradient_file
=
var_CreateGetStringCommand
(
p_filter
,
psz_gradient_var_name
);
if
(
psz_gradient_file
&&
strlen
(
psz_gradient_file
)
>
0
)
{
msg_Dbg
(
p_filter
,
"loading gradientfile %s for "
\
"zone %d"
,
psz_gradient_file
,
i
);
int
i_res
=
p_sys
->
p_atmo_config
->
getZoneDefinition
(
i
)
->
LoadGradientFromBitmap
(
psz_gradient_file
);
if
(
i_res
!=
ATMO_LOAD_GRADIENT_OK
)
{
msg_Err
(
p_filter
,
"failed to load gradient '%s' with "
\
"error %d"
,
psz_gradient_file
,
i_res
);
}
}
delete
psz_gradient_file
;
}
p_sys
->
p_atmo_dyndata
=
new
CAtmoDynData
((
vlc_object_t
*
)
p_filter
,
p_sys
->
p_atmo_config
);
msg_Dbg
(
p_filter
,
"buildin driver initialized"
);
free
(
psz_serialdev
);
}
else
{
msg_Err
(
p_filter
,
"no serial devicename set"
);
}
}
switch
(
p_filter
->
fmt_in
.
video
.
i_chroma
)
{
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
):
case
VLC_FOURCC
(
'I'
,
'Y'
,
'U'
,
'V'
):
case
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
):
case
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'6'
):
case
VLC_FOURCC
(
'Y'
,
'V'
,
'U'
,
'9'
):
// simple enough? Dionoea?
p_sys
->
pf_extract_mini_image
=
ExtractMiniImage_YUV
;
break
;
default:
msg_Dbg
(
p_filter
,
"InitFilter-unsupported chroma: %4.4s"
,
(
char
*
)
&
p_filter
->
fmt_in
.
video
.
i_chroma
);
p_sys
->
pf_extract_mini_image
=
NULL
;
}
p_sys
->
i_crop_x_offset
=
0
;
p_sys
->
i_crop_y_offset
=
0
;
p_sys
->
i_crop_width
=
p_filter
->
fmt_in
.
video
.
i_visible_width
;
p_sys
->
i_crop_height
=
p_filter
->
fmt_in
.
video
.
i_visible_height
;
msg_Dbg
(
p_filter
,
"set default crop %d,%d %dx%d"
,
p_sys
->
i_crop_x_offset
,
p_sys
->
i_crop_y_offset
,
p_sys
->
i_crop_width
,
p_sys
->
i_crop_height
);
#if defined(__ATMO_DEBUG__)
/* save debug images to a folder as Bitmap files ? */
p_sys
->
b_saveframes
=
var_CreateGetBoolCommand
(
p_filter
,
CFG_PREFIX
"saveframes"
);
msg_Dbg
(
p_filter
,
"saveframes = %d"
,
(
int
)
p_sys
->
b_saveframes
);
/*
read debug image folder from config
*/
psz_path
=
var_CreateGetStringCommand
(
p_filter
,
CFG_PREFIX
"framepath"
);
if
(
psz_path
!=
NULL
)
{
strcpy
(
p_sys
->
sz_framepath
,
psz_path
);
#if defined( WIN32 )
size_t
i_strlen
=
strlen
(
p_sys
->
sz_framepath
);
if
((
i_strlen
>
0
)
&&
(
p_sys
->
sz_framepath
[
i_strlen
-
1
]
!=
'\\'
))
{
p_sys
->
sz_framepath
[
i_strlen
]
=
'\\'
;
p_sys
->
sz_framepath
[
i_strlen
+
1
]
=
0
;
}
#endif
free
(
psz_path
);
}
msg_Dbg
(
p_filter
,
"saveframesfolder %s"
,
p_sys
->
sz_framepath
);
#endif
/*
size of extracted image by default 64x48 (other imagesizes are
currently ignored by AtmoWin)
*/
p_sys
->
i_atmo_width
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"width"
);
p_sys
->
i_atmo_height
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"height"
);
msg_Dbg
(
p_filter
,
"mini image size %d * %d pixels"
,
p_sys
->
i_atmo_width
,
p_sys
->
i_atmo_height
);
/*
because atmowin could also be used for lighten up the room - I think if you
pause the video it would be useful to get a little bit more light into to
your living room? - instead switching on a lamp?
*/
p_sys
->
b_usepausecolor
=
var_CreateGetBoolCommand
(
p_filter
,
CFG_PREFIX
"usepausecolor"
);
p_sys
->
ui_pausecolor_red
=
(
uint8_t
)
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"pcolor-red"
);
p_sys
->
ui_pausecolor_green
=
(
uint8_t
)
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"pcolor-green"
);
p_sys
->
ui_pausecolor_blue
=
(
uint8_t
)
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"pcolor-blue"
);
p_sys
->
i_fadesteps
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"fadesteps"
);
if
(
p_sys
->
i_fadesteps
<
1
)
p_sys
->
i_fadesteps
=
1
;
msg_Dbg
(
p_filter
,
"use pause color %d, RGB: %d, %d, %d, Fadesteps: %d"
,
(
int
)
p_sys
->
b_usepausecolor
,
p_sys
->
ui_pausecolor_red
,
p_sys
->
ui_pausecolor_green
,
p_sys
->
ui_pausecolor_blue
,
p_sys
->
i_fadesteps
);
/*
this color is use on shutdown of the filter - the define the
final light after playback... may be used to dim up the light -
how it happens in the cinema...
*/
p_sys
->
ui_endcolor_red
=
(
uint8_t
)
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"ecolor-red"
);
p_sys
->
ui_endcolor_green
=
(
uint8_t
)
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"ecolor-green"
);
p_sys
->
ui_endcolor_blue
=
(
uint8_t
)
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"ecolor-blue"
);
p_sys
->
i_endfadesteps
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"efadesteps"
);
if
(
p_sys
->
i_endfadesteps
<
1
)
p_sys
->
i_endfadesteps
=
1
;
msg_Dbg
(
p_filter
,
"use ende color RGB: %d, %d, %d, Fadesteps: %d"
,
p_sys
->
ui_endcolor_red
,
p_sys
->
ui_endcolor_green
,
p_sys
->
ui_endcolor_blue
,
p_sys
->
i_endfadesteps
);
/* if the external DLL was loaded successfully call AtmoInitialize -
(must be done for each thread where you wan't to use AtmoLight!
*/
int
i
=
AtmoInitialize
(
p_filter
,
VLC_FALSE
);
#if defined( WIN32 )
if
((
i
!=
1
)
&&
!
b_use_buildin_driver
)
{
/* COM Server for AtmoLight not running ?
if the exe path is configured try to start the "userspace" driver
*/
psz_path
=
var_CreateGetStringCommand
(
p_filter
,
CFG_PREFIX
"atmowinexe"
);
if
(
psz_path
!=
NULL
)
{
STARTUPINFO
startupinfo
;
PROCESS_INFORMATION
pinfo
;
memset
(
&
startupinfo
,
0
,
sizeof
(
STARTUPINFO
));
startupinfo
.
cb
=
sizeof
(
STARTUPINFO
);
if
(
CreateProcess
(
psz_path
,
NULL
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
startupinfo
,
&
pinfo
)
==
TRUE
)
{
msg_Dbg
(
p_filter
,
"launched AtmoWin from %s"
,
psz_path
);
WaitForInputIdle
(
pinfo
.
hProcess
,
5000
);
/*
retry to initialize the library COM ... functionality
after the server was launched
*/
i
=
AtmoInitialize
(
p_filter
,
VLC_FALSE
);
}
else
{
msg_Err
(
p_filter
,
"failed to launch AtmoWin from %s"
,
psz_path
);
}
free
(
psz_path
);
}
}
#endif
if
(
i
==
1
)
/* Init Atmolight success... */
{
msg_Dbg
(
p_filter
,
"AtmoInitialize Ok!"
);
/* Setup Transferbuffers for 64 x 48 , RGB with 32bit Per Pixel */
AtmoCreateTransferBuffers
(
p_filter
,
BI_RGB
,
4
,
p_sys
->
i_atmo_width
,
p_sys
->
i_atmo_height
);
/* say the userspace driver that a live mode should be activated
the functions returns the old mode for later restore!
*/
p_sys
->
i_AtmoOldEffect
=
AtmoSwitchEffect
(
p_filter
,
emLivePicture
);
/*
live view can have two differnt source the AtmoWinA
internal GDI Screencapture and the external one - which we
need here...
*/
AtmoSetLiveSource
(
p_filter
,
lvsExternal
);
/* enable other parts only if everything is fine */
p_sys
->
b_enabled
=
VLC_TRUE
;
}
}
/*****************************************************************************
* CreateFilter: allocates AtmoLight video thread output method
*****************************************************************************
* This function allocates and initializes a AtmoLight vout method.
*****************************************************************************/
static
int
CreateFilter
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
;
/* Allocate structure */
p_sys
=
(
filter_sys_t
*
)
malloc
(
sizeof
(
filter_sys_t
)
);
p_filter
->
p_sys
=
p_sys
;
if
(
p_filter
->
p_sys
==
NULL
)
{
msg_Err
(
p_filter
,
"out of memory for p_sys structure"
);
return
VLC_ENOMEM
;
}
/* set all entries to zero */
memset
(
p_sys
,
0
,
sizeof
(
filter_sys_t
));
/* further Setup Function pointers for videolan for calling my filter */
p_filter
->
pf_video_filter
=
Filter
;
config_ChainParse
(
p_filter
,
CFG_PREFIX
,
ppsz_filter_options
,
p_filter
->
p_cfg
);
AddStateVariableCallback
(
p_filter
);
AddCropVariableCallback
(
p_filter
);
AddAtmoSettingsVariablesCallbacks
(
p_filter
);
Atmo_SetupParameters
(
p_filter
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* DestroyFilter: destroy AtmoLight video thread output method
*****************************************************************************
* Terminate an output method created by CreateFilter
*****************************************************************************/
static
void
DestroyFilter
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
DelStateVariableCallback
(
p_filter
);
DelCropVariableCallback
(
p_filter
);
DelAtmoSettingsVariablesCallbacks
(
p_filter
);
Atmo_Shutdown
(
p_filter
);
#if defined( WIN32 )
if
(
p_sys
->
h_AtmoCtrl
!=
NULL
)
{
FreeLibrary
(
p_sys
->
h_AtmoCtrl
);
}
#endif
delete
p_sys
->
p_atmo_dyndata
;
delete
p_sys
->
p_atmo_config
;
vlc_mutex_destroy
(
&
p_sys
->
filter_lock
);
free
(
p_sys
);
}
/*
function stolen from some other videolan source filter ;-)
for the moment RGB is OK... but better would be a direct transformation
from YUV --> HSV
*/
static
inline
void
yuv_to_rgb
(
uint8_t
*
r
,
uint8_t
*
g
,
uint8_t
*
b
,
uint8_t
y1
,
uint8_t
u1
,
uint8_t
v1
)
{
/* macros used for YUV pixel conversions */
# define SCALEBITS 10
# define ONE_HALF (1 << (SCALEBITS - 1))
# define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
# define CLAMP( x ) (((x) > 255) ? 255 : ((x) < 0) ? 0 : (x));
int
y
,
cb
,
cr
,
r_add
,
g_add
,
b_add
;
cb
=
u1
-
128
;
cr
=
v1
-
128
;
r_add
=
FIX
(
1.40200
*
255.0
/
224.0
)
*
cr
+
ONE_HALF
;
g_add
=
-
FIX
(
0.34414
*
255.0
/
224.0
)
*
cb
-
FIX
(
0.71414
*
255.0
/
224.0
)
*
cr
+
ONE_HALF
;
b_add
=
FIX
(
1.77200
*
255.0
/
224.0
)
*
cb
+
ONE_HALF
;
y
=
(
y1
-
16
)
*
FIX
(
255.0
/
219.0
);
*
r
=
CLAMP
((
y
+
r_add
)
>>
SCALEBITS
);
*
g
=
CLAMP
((
y
+
g_add
)
>>
SCALEBITS
);
*
b
=
CLAMP
((
y
+
b_add
)
>>
SCALEBITS
);
}
/******************************************************************************
* ExtractMiniImage_YUV: extract a small image from the picture as 24-bit RGB
*******************************************************************************
* p_sys is a pointer to
* p_inpic is the source frame
* p_transfer_dest is the target buffer for the picture must be big enough!
* (in win32 enviroment this buffer comes from the external DLL where it is
* create as "variant array" and returned through the AtmoLockTransferbuffer
*/
static
void
ExtractMiniImage_YUV
(
filter_sys_t
*
p_sys
,
picture_t
*
p_inpic
,
uint8_t
*
p_transfer_dest
)
{
int
i_col
;
int
i_row
;
uint8_t
*
p_src_y
;
uint8_t
*
p_src_u
;
uint8_t
*
p_src_v
;
uint8_t
*
p_rgb_dst_line_red
;
uint8_t
*
p_rgb_dst_line_green
;
uint8_t
*
p_rgb_dst_line_blue
;
int
i_xpos_y
;
int
i_xpos_u
;
int
i_xpos_v
;
/* calcute Pointers for Storage of B G R (A) */
p_rgb_dst_line_blue
=
p_transfer_dest
;
p_rgb_dst_line_green
=
p_transfer_dest
+
1
;
p_rgb_dst_line_red
=
p_transfer_dest
+
2
;
int
i_row_count
=
p_sys
->
i_atmo_height
+
1
;
int
i_col_count
=
p_sys
->
i_atmo_width
+
1
;
int
i_y_row
,
i_u_row
,
i_v_row
,
i_pixel_row
;
int
i_pixel_col
;
/* these two ugly loops extract the small image - goes it faster? how?
the loops are so designed that there is a small border around the extracted
image so we wont get column and row - zero from the frame, and not the most
right and bottom pixels --- which may be clipped on computers useing TV out
- through overscan!
TODO: try to find out if the output is clipped through VLC - and try here
to ingore the clipped away area for a better result!
TODO: performance improvement in InitFilter percalculated the offsets of
the lines inside the planes so I can save (i_row_count * 3) 2xMUL and
one time DIV the same could be done for the inner loop I think...
*/
for
(
i_row
=
1
;
i_row
<
i_row_count
;
i_row
++
)
{
// calcute the current Lines in the source planes for this outputrow
/* Adresscalcuation pointer to plane Length of one pixelrow in bytes
calculate row now number
*/
/*
p_inpic->format? transform Pixel row into row of plane...
how? simple? fast? good?
*/
/* compute the source pixel row and respect the active cropping */
i_pixel_row
=
(
i_row
*
p_sys
->
i_crop_height
)
/
i_row_count
+
p_sys
->
i_crop_y_offset
;
/*
trans for these Pixel row into the row of each plane ..
because planesize can differ from image size
*/
i_y_row
=
(
i_pixel_row
*
p_inpic
->
p
[
Y_PLANE
].
i_visible_lines
)
/
p_inpic
->
format
.
i_visible_height
;
i_u_row
=
(
i_pixel_row
*
p_inpic
->
p
[
U_PLANE
].
i_visible_lines
)
/
p_inpic
->
format
.
i_visible_height
;
i_v_row
=
(
i_pixel_row
*
p_inpic
->
p
[
V_PLANE
].
i_visible_lines
)
/
p_inpic
->
format
.
i_visible_height
;
/* calculate the pointers to the pixeldata for this row
in each plane
*/
p_src_y
=
p_inpic
->
p
[
Y_PLANE
].
p_pixels
+
p_inpic
->
p
[
Y_PLANE
].
i_pitch
*
i_y_row
;
p_src_u
=
p_inpic
->
p
[
U_PLANE
].
p_pixels
+
p_inpic
->
p
[
U_PLANE
].
i_pitch
*
i_u_row
;
p_src_v
=
p_inpic
->
p
[
V_PLANE
].
p_pixels
+
p_inpic
->
p
[
V_PLANE
].
i_pitch
*
i_v_row
;
for
(
i_col
=
1
;
i_col
<
i_col_count
;
i_col
++
)
{
i_pixel_col
=
(
i_col
*
p_sys
->
i_crop_width
)
/
i_col_count
+
p_sys
->
i_crop_x_offset
;
/*
trans for these Pixel row into the row of each plane ..
because planesize can differ from image size
*/
i_xpos_y
=
(
i_pixel_col
*
p_inpic
->
p
[
Y_PLANE
].
i_visible_pitch
)
/
p_inpic
->
format
.
i_visible_width
;
i_xpos_u
=
(
i_pixel_col
*
p_inpic
->
p
[
U_PLANE
].
i_visible_pitch
)
/
p_inpic
->
format
.
i_visible_width
;
i_xpos_v
=
(
i_pixel_col
*
p_inpic
->
p
[
V_PLANE
].
i_visible_pitch
)
/
p_inpic
->
format
.
i_visible_width
;
yuv_to_rgb
(
p_rgb_dst_line_red
,
p_rgb_dst_line_green
,
p_rgb_dst_line_blue
,
p_src_y
[
i_xpos_y
],
p_src_u
[
i_xpos_u
],
p_src_v
[
i_xpos_v
]);
/* +4 because output image should be RGB32 with dword alignment! */
p_rgb_dst_line_red
+=
4
;
p_rgb_dst_line_green
+=
4
;
p_rgb_dst_line_blue
+=
4
;
}
}
}
/******************************************************************************
* SaveBitmap: Saves the content of a transferbuffer as Bitmap to disk
*******************************************************************************
* just for debugging
* p_sys -> configuration if Atmo from there the function will get height and
* width
* p_pixels -> should be the dword aligned BGR(A) image data
* psz_filename -> filename where to store
*/
#if defined(__ATMO_DEBUG__)
void
SaveBitmap
(
filter_sys_t
*
p_sys
,
uint8_t
*
p_pixels
,
char
*
psz_filename
)
{
/* for debug out only used*/
BITMAPINFO
bmp_info
;
BITMAPFILEHEADER
bmp_fileheader
;
FILE
*
fp_bitmap
;
memset
(
&
bmp_info
,
0
,
sizeof
(
BITMAPINFO
));
bmp_info
.
bmiHeader
.
biSize
=
sizeof
(
BITMAPINFOHEADER
);
bmp_info
.
bmiHeader
.
biSizeImage
=
p_sys
->
i_atmo_height
*
p_sys
->
i_atmo_width
*
4
;
bmp_info
.
bmiHeader
.
biCompression
=
BI_RGB
;
bmp_info
.
bmiHeader
.
biWidth
=
p_sys
->
i_atmo_width
;
bmp_info
.
bmiHeader
.
biHeight
=
-
p_sys
->
i_atmo_height
;
bmp_info
.
bmiHeader
.
biBitCount
=
32
;
bmp_info
.
bmiHeader
.
biPlanes
=
1
;
bmp_fileheader
.
bfReserved1
=
0
;
bmp_fileheader
.
bfReserved2
=
0
;
bmp_fileheader
.
bfSize
=
sizeof
(
BITMAPFILEHEADER
)
+
sizeof
(
BITMAPINFOHEADER
)
+
bmp_info
.
bmiHeader
.
biSizeImage
;
bmp_fileheader
.
bfType
=
'
MB
'
;
bmp_fileheader
.
bfOffBits
=
sizeof
(
BITMAPFILEHEADER
)
+
sizeof
(
BITMAPINFOHEADER
);
fp_bitmap
=
fopen
(
psz_filename
,
"wb"
);
if
(
fp_bitmap
!=
NULL
)
{
fwrite
(
&
bmp_fileheader
,
sizeof
(
BITMAPFILEHEADER
),
1
,
fp_bitmap
);
fwrite
(
&
bmp_info
.
bmiHeader
,
sizeof
(
BITMAPINFOHEADER
),
1
,
fp_bitmap
);
fwrite
(
p_pixels
,
bmp_info
.
bmiHeader
.
biSizeImage
,
1
,
fp_bitmap
);
fclose
(
fp_bitmap
);
}
}
#endif
/****************************************************************************
* CreateMiniImage: extracts a 64x48 pixel image from the frame
* (there is a small border arround thats why the loops starts with one
* instead zero) without any interpolation
*****************************************************************************/
static
void
CreateMiniImage
(
filter_t
*
p_filter
,
picture_t
*
p_inpic
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
/*
pointer to RGB Buffer created in external libary as safe array which
is locked inside AtmoLockTransferBuffer
*/
uint8_t
*
p_transfer
=
NULL
;
#if defined( __ATMO_DEBUG__ )
/* for debug out only used*/
char
sz_filename
[
MAX_PATH
];
#endif
/*
Lock the before created VarArray (AtmoCreateTransferBuffers)
inside my wrapper library and give me a pointer to the buffer!
below linux a global buffer may be used and protected with a mutex?
*/
p_transfer
=
AtmoLockTransferBuffer
(
p_filter
);
if
(
p_transfer
==
NULL
)
{
msg_Err
(
p_filter
,
"AtmoLight no transferbuffer available. "
\
"AtmoLight will be disabled!"
);
p_sys
->
b_enabled
=
VLC_FALSE
;
return
;
}
/*
do the call via pointer to function instead of having a
case structure here
*/
p_sys
->
pf_extract_mini_image
(
p_sys
,
p_inpic
,
p_transfer
);
#if defined( __ATMO_DEBUG__ )
/*
if debugging enabled save every 128th image to disk
*/
if
((
p_sys
->
b_saveframes
==
VLC_TRUE
)
&&
(
p_sys
->
sz_framepath
[
0
]
!=
0
))
{
if
((
p_sys
->
i_framecounter
&
127
)
==
0
)
{
sprintf
(
sz_filename
,
"%satmo_dbg_%06d.bmp"
,
p_sys
->
sz_framepath
,
p_sys
->
i_framecounter
);
msg_Dbg
(
p_filter
,
"SaveFrame %s"
,
sz_filename
);
SaveBitmap
(
p_sys
,
p_transfer
,
sz_filename
);
}
p_sys
->
i_framecounter
++
;
}
#endif
/* show the colors on the wall */
AtmoSendPixelData
(
p_filter
);
}
/*****************************************************************************
* Filter: calls the extract method and forwards the incomming picture 1:1
*****************************************************************************
*
*****************************************************************************/
static
picture_t
*
Filter
(
filter_t
*
p_filter
,
picture_t
*
p_pic
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
!
p_pic
)
return
NULL
;
if
((
p_sys
->
b_enabled
==
VLC_TRUE
)
&&
(
p_sys
->
pf_extract_mini_image
!=
NULL
)
&&
(
p_sys
->
b_pause_live
==
VLC_FALSE
))
{
CreateMiniImage
(
p_filter
,
p_pic
);
}
return
p_pic
;
}
/*****************************************************************************
* FadeToColorThread: Threadmethod which changes slowly the color
* to a target color defined in p_fadethread struct
* use for: Fade to Pause Color, and Fade to End Color
*****************************************************************************/
static
void
FadeToColorThread
(
fadethread_t
*
p_fadethread
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_fadethread
->
p_filter
->
p_sys
;
int
i_steps_done
=
0
;
int
i_index
;
int
i_pause_red
;
int
i_pause_green
;
int
i_pause_blue
;
int
i_src_red
;
int
i_src_green
;
int
i_src_blue
;
vlc_thread_ready
(
p_fadethread
);
uint8_t
*
p_source
=
NULL
;
/* initialize AtmoWin for this thread! */
AtmoInitialize
(
p_fadethread
->
p_filter
,
VLC_TRUE
);
uint8_t
*
p_transfer
=
AtmoLockTransferBuffer
(
p_fadethread
->
p_filter
);
if
(
p_transfer
!=
NULL
)
{
/* safe colors as "32bit" Integers to avoid overflows*/
i_pause_red
=
p_fadethread
->
ui_red
;
i_pause_blue
=
p_fadethread
->
ui_blue
;
i_pause_green
=
p_fadethread
->
ui_green
;
/*
allocate a temporary buffer for the last send
image size less then 15kb
*/
int
i_size
=
4
*
p_sys
->
i_atmo_width
*
p_sys
->
i_atmo_height
;
p_source
=
(
uint8_t
*
)
malloc
(
i_size
);
if
(
p_source
!=
NULL
)
{
/*
get a copy of the last transfered image as orign for the
fading steps...
*/
memcpy
(
p_source
,
p_transfer
,
i_size
);
/* send the same pixel data again... to unlock the buffer! */
AtmoSendPixelData
(
p_fadethread
->
p_filter
);
while
(
(
!
p_fadethread
->
b_die
)
&&
(
i_steps_done
<
p_fadethread
->
i_steps
))
{
p_transfer
=
AtmoLockTransferBuffer
(
p_fadethread
->
p_filter
);
if
(
!
p_transfer
)
break
;
/* should not happen if it worked
one time in the code above! */
i_steps_done
++
;
/*
move all pixels in the mini image (64x48) one step closer to
the desired color these loop takes the most time of this
thread improvements wellcome!
*/
for
(
i_index
=
0
;
(
i_index
<
i_size
)
&&
(
!
p_fadethread
->
b_die
);
i_index
+=
4
)
{
i_src_blue
=
p_source
[
i_index
+
0
];
i_src_green
=
p_source
[
i_index
+
1
];
i_src_red
=
p_source
[
i_index
+
2
];
p_transfer
[
i_index
+
0
]
=
(
uint8_t
)
(((
(
i_pause_blue
-
i_src_blue
)
*
i_steps_done
)
/
p_fadethread
->
i_steps
)
+
i_src_blue
);
p_transfer
[
i_index
+
1
]
=
(
uint8_t
)
(((
(
i_pause_green
-
i_src_green
)
*
i_steps_done
)
/
p_fadethread
->
i_steps
)
+
i_src_green
);
p_transfer
[
i_index
+
2
]
=
(
uint8_t
)
(((
(
i_pause_red
-
i_src_red
)
*
i_steps_done
)
/
p_fadethread
->
i_steps
)
+
i_src_red
);
}
/* send image to lightcontroller */
AtmoSendPixelData
(
p_fadethread
->
p_filter
);
/* is there something like and interruptable sleep inside
the VLC libaries? inside native win32 I would use an Event
(CreateEvent) and here an WaitForSingleObject?
*/
if
(
p_fadethread
->
b_die
)
break
;
msleep
(
10000
);
if
(
p_fadethread
->
b_die
)
break
;
msleep
(
10000
);
if
(
p_fadethread
->
b_die
)
break
;
msleep
(
10000
);
if
(
p_fadethread
->
b_die
)
break
;
msleep
(
10000
);
}
free
(
p_source
);
}
else
{
/* in failure of malloc also unlock buffer */
AtmoSendPixelData
(
p_fadethread
->
p_filter
);
}
}
/* call indirect to OleUnitialize() for this thread */
AtmoFinalize
(
p_fadethread
->
p_filter
,
0
);
}
/*****************************************************************************
* CheckAndStopFadeThread: if there is a fadethread structure left, or running.
******************************************************************************
* this function will stop the thread ... and waits for its termination
* before removeing the objects from vout_sys_t ...
******************************************************************************/
static
void
CheckAndStopFadeThread
(
filter_t
*
p_filter
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
vlc_mutex_lock
(
&
p_sys
->
filter_lock
);
if
(
p_sys
->
p_fadethread
!=
NULL
)
{
msg_Dbg
(
p_filter
,
"kill still running fadeing thread..."
);
p_sys
->
p_fadethread
->
b_die
=
VLC_TRUE
;
vlc_thread_join
(
p_sys
->
p_fadethread
);
vlc_object_destroy
(
p_sys
->
p_fadethread
);
p_sys
->
p_fadethread
=
NULL
;
}
vlc_mutex_unlock
(
&
p_sys
->
filter_lock
);
}
/*****************************************************************************
* StateCallback: Callback for the inputs variable "State" to get notified
* about Pause and Continue Playback events.
*****************************************************************************/
static
int
StateCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_cmd
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_data
;
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
if
((
p_sys
->
b_usepausecolor
==
VLC_TRUE
)
&&
(
p_sys
->
b_enabled
==
VLC_TRUE
))
{
msg_Dbg
(
p_filter
,
"state change from: %d to %d"
,
oldval
.
i_int
,
newval
.
i_int
);
if
((
newval
.
i_int
==
PAUSE_S
)
&&
(
oldval
.
i_int
==
PLAYING_S
))
{
/* tell the other thread to stop sending images to light
controller */
p_sys
->
b_pause_live
=
VLC_TRUE
;
// ggf. alten Thread abräumen should not happen....
CheckAndStopFadeThread
(
p_filter
);
// perpare spawn fadeing thread
vlc_mutex_lock
(
&
p_sys
->
filter_lock
);
/*
launch only a new thread if there is none active!
or waiting for cleanup
*/
if
(
p_sys
->
p_fadethread
==
NULL
)
{
p_sys
->
p_fadethread
=
(
fadethread_t
*
)
vlc_object_create
(
p_filter
,
sizeof
(
fadethread_t
)
);
p_sys
->
p_fadethread
->
p_filter
=
p_filter
;
p_sys
->
p_fadethread
->
ui_red
=
p_sys
->
ui_pausecolor_red
;
p_sys
->
p_fadethread
->
ui_green
=
p_sys
->
ui_pausecolor_green
;
p_sys
->
p_fadethread
->
ui_blue
=
p_sys
->
ui_pausecolor_blue
;
p_sys
->
p_fadethread
->
i_steps
=
p_sys
->
i_fadesteps
;
if
(
vlc_thread_create
(
p_sys
->
p_fadethread
,
"AtmoLight fadeing"
,
FadeToColorThread
,
VLC_THREAD_PRIORITY_LOW
,
VLC_FALSE
)
)
{
msg_Err
(
p_filter
,
"cannot create FadeToColorThread"
);
vlc_object_destroy
(
p_sys
->
p_fadethread
);
p_sys
->
p_fadethread
=
NULL
;
}
}
vlc_mutex_unlock
(
&
p_sys
->
filter_lock
);
}
if
((
newval
.
i_int
==
PLAYING_S
)
&&
(
oldval
.
i_int
==
PAUSE_S
))
{
/* playback continues check thread state */
CheckAndStopFadeThread
(
p_filter
);
/* reactivate the Render function... to do its normal work */
p_sys
->
b_pause_live
=
VLC_FALSE
;
}
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* AddPlaylistInputThreadStateCallback: Setup call back on "State" Variable
*****************************************************************************
* Add Callback function to the "state" variable of the input thread..
* first find the PlayList and get the input thread from there to attach
* my callback? is vlc_object_find the right way for this??
*****************************************************************************/
static
void
AddStateVariableCallback
(
filter_t
*
p_filter
)
{
playlist_t
*
p_playlist
=
(
playlist_t
*
)
vlc_object_find
(
p_filter
,
VLC_OBJECT_PLAYLIST
,
FIND_ANYWHERE
);
if
(
p_playlist
)
{
input_thread_t
*
p_input
=
p_playlist
->
p_input
;
if
(
p_input
)
{
var_AddCallback
(
p_input
,
"state"
,
StateCallback
,
p_filter
);
}
vlc_object_release
(
p_playlist
);
}
}
/*****************************************************************************
* DelPlaylistInputThreadStateCallback: Remove call back on "State" Variable
*****************************************************************************
* Delete the callback function to the "state" variable of the input thread...
* first find the PlayList and get the input thread from there to attach
* my callback? is vlc_object_find the right way for this??
*****************************************************************************/
static
void
DelStateVariableCallback
(
filter_t
*
p_filter
)
{
playlist_t
*
p_playlist
=
(
playlist_t
*
)
vlc_object_find
(
p_filter
,
VLC_OBJECT_PLAYLIST
,
FIND_ANYWHERE
);
if
(
p_playlist
)
{
input_thread_t
*
p_input
=
p_playlist
->
p_input
;
if
(
p_input
)
{
var_DelCallback
(
p_input
,
"state"
,
StateCallback
,
p_filter
);
}
vlc_object_release
(
p_playlist
);
}
}
static
int
CropCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_cmd
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
filter_t
*
p_filter
=
(
filter_t
*
)
p_data
;
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
/*
//if the handler is attache to crop variable directly!
int i_visible_width, i_visible_height, i_x_offset, i_y_offset;
atmo_parse_crop(newval.psz_string, p_vout->fmt_render,
p_vout->fmt_render,
i_visible_width, i_visible_height,
i_x_offset, i_y_offset);
p_sys->i_crop_x_offset = i_x_offset;
p_sys->i_crop_y_offset = i_y_offset;
p_sys->i_crop_width = i_visible_width;
p_sys->i_crop_height = i_visible_height;
*/
p_sys
->
i_crop_x_offset
=
p_vout
->
fmt_in
.
i_x_offset
;
p_sys
->
i_crop_y_offset
=
p_vout
->
fmt_in
.
i_y_offset
;
p_sys
->
i_crop_width
=
p_vout
->
fmt_in
.
i_visible_width
;
p_sys
->
i_crop_height
=
p_vout
->
fmt_in
.
i_visible_height
;
msg_Dbg
(
p_filter
,
"cropping picture %ix%i to %i,%i,%ix%i"
,
p_vout
->
fmt_in
.
i_width
,
p_vout
->
fmt_in
.
i_height
,
p_sys
->
i_crop_x_offset
,
p_sys
->
i_crop_y_offset
,
p_sys
->
i_crop_width
,
p_sys
->
i_crop_height
);
return
VLC_SUCCESS
;
}
static
void
AddCropVariableCallback
(
filter_t
*
p_filter
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
vlc_object_find
(
p_filter
,
VLC_OBJECT_VOUT
,
FIND_ANYWHERE
);
if
(
p_vout
)
{
var_AddCallback
(
p_vout
,
"crop-update"
,
CropCallback
,
p_filter
);
vlc_object_release
(
p_vout
);
}
}
static
void
DelCropVariableCallback
(
filter_t
*
p_filter
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
vlc_object_find
(
p_filter
,
VLC_OBJECT_VOUT
,
FIND_ANYWHERE
);
if
(
p_vout
)
{
var_DelCallback
(
p_vout
,
"crop-update"
,
CropCallback
,
p_filter
);
vlc_object_release
(
p_vout
);
}
}
/****************************************************************************
* StateCallback: Callback for the inputs variable "State" to get notified
* about Pause and Continue Playback events.
*****************************************************************************/
static
int
AtmoSettingsCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_data
;
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
CAtmoConfig
*
p_atmo_config
=
p_sys
->
p_atmo_config
;
if
(
p_atmo_config
)
{
msg_Dbg
(
p_filter
,
"apply AtmoSettingsCallback %s (int: %d -> %d)"
,
psz_var
,
oldval
.
i_int
,
newval
.
i_int
);
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"filtermode"
))
p_atmo_config
->
setLiveViewFilterMode
(
(
AtmoFilterMode
)
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"PercentNew"
))
p_atmo_config
->
setLiveViewFilter_PercentNew
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"MeanLength"
))
p_atmo_config
->
setLiveViewFilter_MeanLength
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"MeanThreshold"
))
p_atmo_config
->
setLiveViewFilter_MeanThreshold
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"EdgeWeightning"
))
p_atmo_config
->
setLiveView_EdgeWeighting
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"Brightness"
))
p_atmo_config
->
setLiveView_BrightCorrect
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"DarknessLimit"
))
p_atmo_config
->
setLiveView_DarknessLimit
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"HueWinSize"
))
p_atmo_config
->
setLiveView_HueWinSize
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"SatWinSize"
))
p_atmo_config
->
setLiveView_SatWinSize
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"FrameDelay"
))
p_atmo_config
->
setLiveView_FrameDelay
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"whiteadj"
))
p_atmo_config
->
setUseSoftwareWhiteAdj
(
newval
.
b_bool
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"white-red"
))
p_atmo_config
->
setWhiteAdjustment_Red
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"white-green"
))
p_atmo_config
->
setWhiteAdjustment_Green
(
newval
.
i_int
);
else
if
(
!
strcmp
(
psz_var
,
CFG_PREFIX
"white-blue"
))
p_atmo_config
->
setWhiteAdjustment_Blue
(
newval
.
i_int
);
}
return
VLC_SUCCESS
;
}
static
void
AddAtmoSettingsVariablesCallbacks
(
filter_t
*
p_filter
)
{
var_AddCallback
(
p_filter
,
CFG_PREFIX
"filtermode"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"PercentNew"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"MeanLength"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"MeanThreshold"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"EdgeWeightning"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"Brightness"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"DarknessLimit"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"HueWinSize"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"SatWinSize"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"FrameDelay"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"whiteadj"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"white-red"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"white-green"
,
AtmoSettingsCallback
,
p_filter
);
var_AddCallback
(
p_filter
,
CFG_PREFIX
"white-blue"
,
AtmoSettingsCallback
,
p_filter
);
}
static
void
DelAtmoSettingsVariablesCallbacks
(
filter_t
*
p_filter
)
{
var_DelCallback
(
p_filter
,
CFG_PREFIX
"filtermode"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"PercentNew"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"MeanLength"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"MeanThreshold"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"EdgeWeightning"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"Brightness"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"DarknessLimit"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"HueWinSize"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"SatWinSize"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"FrameDelay"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"whiteadj"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"white-red"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"white-green"
,
AtmoSettingsCallback
,
p_filter
);
var_DelCallback
(
p_filter
,
CFG_PREFIX
"white-blue"
,
AtmoSettingsCallback
,
p_filter
);
}
#if defined(__ATMO_DEBUG__)
static
void
atmo_parse_crop
(
char
*
psz_cropconfig
,
video_format_t
fmt_in
,
video_format_t
fmt_render
,
int
&
i_visible_width
,
int
&
i_visible_height
,
int
&
i_x_offset
,
int
&
i_y_offset
)
{
int64_t
i_aspect_num
,
i_aspect_den
;
unsigned
int
i_width
,
i_height
;
i_visible_width
=
fmt_in
.
i_visible_width
;
i_visible_height
=
fmt_in
.
i_visible_height
;
i_x_offset
=
fmt_in
.
i_x_offset
;
i_y_offset
=
fmt_in
.
i_y_offset
;
char
*
psz_end
=
NULL
,
*
psz_parser
=
strchr
(
psz_cropconfig
,
':'
);
if
(
psz_parser
)
{
/* We're using the 3:4 syntax */
i_aspect_num
=
strtol
(
psz_cropconfig
,
&
psz_end
,
10
);
if
(
psz_end
==
psz_cropconfig
||
!
i_aspect_num
)
return
;
i_aspect_den
=
strtol
(
++
psz_parser
,
&
psz_end
,
10
);
if
(
psz_end
==
psz_parser
||
!
i_aspect_den
)
return
;
i_width
=
fmt_in
.
i_sar_den
*
fmt_render
.
i_visible_height
*
i_aspect_num
/
i_aspect_den
/
fmt_in
.
i_sar_num
;
i_height
=
fmt_render
.
i_visible_width
*
fmt_in
.
i_sar_num
*
i_aspect_den
/
i_aspect_num
/
fmt_in
.
i_sar_den
;
if
(
i_width
<
fmt_render
.
i_visible_width
)
{
i_x_offset
=
fmt_render
.
i_x_offset
+
(
fmt_render
.
i_visible_width
-
i_width
)
/
2
;
i_visible_width
=
i_width
;
}
else
{
i_y_offset
=
fmt_render
.
i_y_offset
+
(
fmt_render
.
i_visible_height
-
i_height
)
/
2
;
i_visible_height
=
i_height
;
}
}
else
{
psz_parser
=
strchr
(
psz_cropconfig
,
'x'
);
if
(
psz_parser
)
{
/* Maybe we're using the <width>x<height>+<left>+<top> syntax */
unsigned
int
i_crop_width
,
i_crop_height
,
i_crop_top
,
i_crop_left
;
i_crop_width
=
strtol
(
psz_cropconfig
,
&
psz_end
,
10
);
if
(
psz_end
!=
psz_parser
)
return
;
psz_parser
=
strchr
(
++
psz_end
,
'+'
);
i_crop_height
=
strtol
(
psz_end
,
&
psz_end
,
10
);
if
(
psz_end
!=
psz_parser
)
return
;
psz_parser
=
strchr
(
++
psz_end
,
'+'
);
i_crop_left
=
strtol
(
psz_end
,
&
psz_end
,
10
);
if
(
psz_end
!=
psz_parser
)
return
;
psz_end
++
;
i_crop_top
=
strtol
(
psz_end
,
&
psz_end
,
10
);
if
(
*
psz_end
!=
'\0'
)
return
;
i_width
=
i_crop_width
;
i_visible_width
=
i_width
;
i_height
=
i_crop_height
;
i_visible_height
=
i_height
;
i_x_offset
=
i_crop_left
;
i_y_offset
=
i_crop_top
;
}
else
{
/* Maybe we're using the <left>+<top>+<right>+<bottom> syntax */
unsigned
int
i_crop_top
,
i_crop_left
,
i_crop_bottom
,
i_crop_right
;
psz_parser
=
strchr
(
psz_cropconfig
,
'+'
);
i_crop_left
=
strtol
(
psz_cropconfig
,
&
psz_end
,
10
);
if
(
psz_end
!=
psz_parser
)
return
;
psz_parser
=
strchr
(
++
psz_end
,
'+'
);
i_crop_top
=
strtol
(
psz_end
,
&
psz_end
,
10
);
if
(
psz_end
!=
psz_parser
)
return
;
psz_parser
=
strchr
(
++
psz_end
,
'+'
);
i_crop_right
=
strtol
(
psz_end
,
&
psz_end
,
10
);
if
(
psz_end
!=
psz_parser
)
return
;
psz_end
++
;
i_crop_bottom
=
strtol
(
psz_end
,
&
psz_end
,
10
);
if
(
*
psz_end
!=
'\0'
)
return
;
i_width
=
fmt_render
.
i_visible_width
-
i_crop_left
-
i_crop_right
;
i_visible_width
=
i_width
;
i_height
=
fmt_render
.
i_visible_height
-
i_crop_top
-
i_crop_bottom
;
i_visible_height
=
i_height
;
i_x_offset
=
i_crop_left
;
i_y_offset
=
i_crop_top
;
}
}
}
#endif
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