Commit f0051192 authored by André Weber's avatar André Weber

enhanced & corrected AtmoLight filter module

- added more thread locking/synchronization, to avoid potential risk of race conditions
- changed the option to choose the output device
- added support for MoMoLight (http://www.ambilight4pc.com/momolight/momolight.html)
- added support for a simple serial DMX (255 channel) controller
- added support for Quattro Atmo Light (allows to use four separated classic AtmoLights, as one virtual AtmoLight)
- changed the way color packets are passed from AtmoExternalCaptureInput to AtmoLiveView useing a queue object (instead of a unsynchronized global variable)
- renamed some options inside atmo.cpp to meet the requirements from the video effect dialog widget (later commit)
- changed the way to define the zones for image color extraction (because the number of zones isn't longer fixed to 4 or 5)
- removed the need to copy some .dll as bridge for the external AtmoWin into the VideoLAN folder, try to load the dll from the same folder like AtmoWinX.exe
- do not a complete fade out, if the filter processed a low number of frames and gets stopped (keeps VideoLAN quick responding, if switching through deinterlacing modes)
- added a debug option to see which pixels are used for color computation (just for fun)
- added more infos to README.txt inside the source folder
parent bf7822fe
......@@ -62,10 +62,16 @@ SOURCES_atmo = atmo/atmo.cpp \
atmo/AtmoInput.cpp atmo/AtmoInput.h \
atmo/AtmoLiveView.cpp atmo/AtmoLiveView.h \
atmo/AtmoOutputFilter.cpp atmo/AtmoOutputFilter.h \
atmo/AtmoSerialConnection.cpp atmo/AtmoSerialConnection.h \
atmo/AtmoThread.cpp atmo/AtmoThread.h \
atmo/AtmoTools.cpp atmo/AtmoTools.h \
atmo/AtmoZoneDefinition.cpp atmo/AtmoZoneDefinition.h
atmo/AtmoZoneDefinition.cpp atmo/AtmoZoneDefinition.h \
atmo/AtmoChannelAssignment.cpp atmo/AtmoChannelAssignment.h \
atmo/AtmoClassicConnection.cpp atmo/AtmoClassicConnection.h \
atmo/AtmoDmxSerialConnection.cpp atmo/AtmoDmxSerialConnection.h \
atmo/DmxTools.cpp atmo/DmxTools.h \
atmo/AtmoMultiConnection.cpp atmo/AtmoMultiConnection.h \
atmo/MoMoConnection.cpp atmo/MoMoConnection.h \
atmo/AtmoPacketQueue.cpp atmo/AtmoPacketQueue.h
SOURCES_video_filter_wrapper = wrapper.c
noinst_HEADERS = filter_common.h filter_picture.h
......
......@@ -13,8 +13,52 @@
#include "AtmoDefs.h"
#include "AtmoConfig.h"
#define Weight(zone, pixel_nummer) m_Weight[((zone) * (IMAGE_SIZE)) + (pixel_nummer)]
class CAtmoColorCalculator
{
protected:
CAtmoConfig *m_pAtmoConfig;
// 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)
int *m_Weight;
int **m_Zone_Weights;
long int *m_hue_hist;
long int *m_windowed_hue_hist;
int *m_most_used_hue_last;
int *m_most_used_hue;
long int *m_sat_hist;
long int *m_windowed_sat_hist;
int *m_most_used_sat;
long int *m_average_v;
int *m_average_counter;
protected:
int m_LastEdgeWeighting;
int m_LastWidescreenMode;
int m_LastLayout_TopCount;
int m_LastLayout_BottomCount;
int m_LastLayout_LRCount;
int m_LastNumZones;
protected:
void FindMostUsed(int AtmoSetup_NumZones,int *most_used,long int *windowed_hist);
public:
CAtmoColorCalculator(CAtmoConfig *pAtmoConfig);
~CAtmoColorCalculator(void);
pColorPacket AnalyzeHSV(tHSVColor *HSV_Img);
void UpdateParameters();
};
tColorPacket CalcColorsAnalyzeHSV(CAtmoConfig *pAtmoConfig, tHSVColor *HSV_Img);
tHSVColor RGB2HSV(tRGBColor color);
tRGBColor HSV2RGB(tHSVColor color);
......
/*
* AtmoChannelAssignment.cpp: Class for storing a hardware channel to zone mapping
* List
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "AtmoChannelAssignment.h"
CAtmoChannelAssignment::CAtmoChannelAssignment(void)
{
m_psz_name = strdup("");
m_mappings = NULL;
m_num_channels = 0;
system = ATMO_FALSE;
}
CAtmoChannelAssignment::CAtmoChannelAssignment(CAtmoChannelAssignment &source)
{
m_num_channels = 0; m_psz_name = NULL;
m_mappings = source.getMapArrayClone(m_num_channels);
setName( source.getName() );
system = source.system;
}
CAtmoChannelAssignment::~CAtmoChannelAssignment(void)
{
free(m_psz_name);
}
void CAtmoChannelAssignment::setName(const char *pszNewName)
{
free(m_psz_name);
m_psz_name = pszNewName ? strdup(pszNewName) : strdup("");
}
void CAtmoChannelAssignment::setSize(int numChannels)
{
if(numChannels != m_num_channels)
{
delete []m_mappings;
m_mappings = NULL;
m_num_channels = numChannels;
if(m_num_channels > 0)
{
m_mappings = new int[m_num_channels];
memset(m_mappings, 0, sizeof(int) * m_num_channels);
}
}
}
int *CAtmoChannelAssignment::getMapArrayClone(int &count)
{
count = m_num_channels;
if(count == 0) return NULL;
int *temp = new int[m_num_channels];
memcpy(temp, m_mappings, sizeof(int) * m_num_channels);
return(temp);
}
int CAtmoChannelAssignment::getZoneIndex(int channel)
{
if(m_mappings && (channel>=0) && (channel<m_num_channels))
return m_mappings[channel] ;
else
return -1;
}
void CAtmoChannelAssignment::setZoneIndex(int channel, int zone)
{
if(m_mappings && (channel>=0) && (channel<m_num_channels))
m_mappings[channel] = zone;
}
#ifndef _AtmoChannelAssignment_
#define _AtmoChannelAssignment_
#include "AtmoDefs.h"
class CAtmoChannelAssignment
{
protected:
// name of the mapping (for menus and lists)
char *m_psz_name;
// count of channels starting with 0 ... X for which a mapping exists!
int m_num_channels;
// array were each destination channel - has an index to the source zone to use
// or -1 to show black output on this channel
int *m_mappings;
public:
CAtmoChannelAssignment(void);
CAtmoChannelAssignment(CAtmoChannelAssignment &source);
~CAtmoChannelAssignment(void);
public:
// internal used to mark a not modifyable definition
// with a default assignment!
ATMO_BOOL system;
char *getName() { return(m_psz_name); }
void setName(const char *pszNewName);
void setSize(int numChannels);
int getSize() { return m_num_channels; }
int *getMapArrayClone(int &count);
int getZoneIndex(int channel);
void setZoneIndex(int channel, int zone);
};
#endif
......@@ -9,8 +9,11 @@
#include "AtmoDefs.h"
#include "AtmoSerialConnection.h"
#include "AtmoClassicConnection.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include "AtmoClassicConfigDialog.h"
#endif
#include <stdio.h>
#include <fcntl.h>
......@@ -20,25 +23,15 @@
#include <unistd.h>
#endif
/*
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <vdr/tools.h>
*/
CAtmoSerialConnection::CAtmoSerialConnection(CAtmoConfig *cfg) : CAtmoConnection(cfg) {
CAtmoClassicConnection::CAtmoClassicConnection(CAtmoConfig *cfg) : CAtmoConnection(cfg) {
m_hComport = INVALID_HANDLE_VALUE;
}
CAtmoSerialConnection::~CAtmoSerialConnection() {
CloseConnection();
CAtmoClassicConnection::~CAtmoClassicConnection() {
}
ATMO_BOOL CAtmoSerialConnection::OpenConnection() {
ATMO_BOOL CAtmoClassicConnection::OpenConnection() {
#if defined(_ATMO_VLC_PLUGIN_)
char *serdevice = m_pAtmoConfig->getSerialDevice();
if(!serdevice)
......@@ -52,24 +45,20 @@ ATMO_BOOL CAtmoSerialConnection::OpenConnection() {
CloseConnection();
#if !defined(_ATMO_VLC_PLUGIN_)
char comport[16]; // com4294967295
sprintf(comport,"com%d",portNummer);
char serdevice[16]; // com4294967295
sprintf(serdevice,"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; // für comport-parameter
DCB dcb; // fr comport-parameter
dcb.DCBlength = sizeof(DCB);
GetCommState (m_hComport, &dcb); // ger current serialport settings
dcb.BaudRate = 38400; // set speed
......@@ -81,11 +70,7 @@ ATMO_BOOL CAtmoSerialConnection::OpenConnection() {
#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;
}
......@@ -110,7 +95,7 @@ ATMO_BOOL CAtmoSerialConnection::OpenConnection() {
return true;
}
void CAtmoSerialConnection::CloseConnection() {
void CAtmoClassicConnection::CloseConnection() {
if(m_hComport!=INVALID_HANDLE_VALUE) {
#if defined(WIN32)
CloseHandle(m_hComport);
......@@ -121,11 +106,11 @@ void CAtmoSerialConnection::CloseConnection() {
}
}
ATMO_BOOL CAtmoSerialConnection::isOpen(void) {
ATMO_BOOL CAtmoClassicConnection::isOpen(void) {
return (m_hComport != INVALID_HANDLE_VALUE);
}
ATMO_BOOL CAtmoSerialConnection::HardwareWhiteAdjust(int global_gamma,
ATMO_BOOL CAtmoClassicConnection::HardwareWhiteAdjust(int global_gamma,
int global_contrast,
int contrast_red,
int contrast_green,
......@@ -193,7 +178,7 @@ ATMO_BOOL CAtmoSerialConnection::HardwareWhiteAdjust(int global_gamma,
}
ATMO_BOOL CAtmoSerialConnection::SendData(tColorPacket data) {
ATMO_BOOL CAtmoClassicConnection::SendData(pColorPacket data) {
if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE;
......@@ -205,11 +190,19 @@ ATMO_BOOL CAtmoSerialConnection::SendData(tColorPacket data) {
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;
int idx;
Lock();
for(int i=0; i < 5 ; i++) {
if(m_ChannelAssignment && (i < m_NumAssignedChannels))
idx = m_ChannelAssignment[i];
else
idx = -1;
if((idx>=0) && (idx<data->numColors)) {
buffer[iBuffer++] = data->zone[idx].r;
buffer[iBuffer++] = data->zone[idx].g;
buffer[iBuffer++] = data->zone[idx].b;
} else {
buffer[iBuffer++] = 0;
buffer[iBuffer++] = 0;
......@@ -224,47 +217,67 @@ ATMO_BOOL CAtmoSerialConnection::SendData(tColorPacket data) {
tcdrain(m_hComport);
#endif
Unlock();
return (iBytesWritten == 19) ? ATMO_TRUE : ATMO_FALSE;
}
ATMO_BOOL CAtmoSerialConnection::SendData(unsigned char numChannels,
int red[],
int green[],
int blue[])
ATMO_BOOL CAtmoClassicConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
{
if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE;
if(!ca) return ATMO_FALSE;
ca->setSize(5);
ca->setZoneIndex(0, 4); // Zone 5
ca->setZoneIndex(1, 3);
ca->setZoneIndex(2, 1);
ca->setZoneIndex(3, 0);
ca->setZoneIndex(4, 2);
return ATMO_TRUE;
}
DWORD bufSize = 4 + numChannels*3;
unsigned char *buffer = new unsigned char[bufSize];
DWORD iBytesWritten;
#if !defined(_ATMO_VLC_PLUGIN_)
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;
}
char *CAtmoClassicConnection::getChannelName(int ch)
{
if(ch < 0) return NULL;
char buf[30];
switch(ch) {
case 0:
sprintf(buf,"Summen Kanal [%d]",ch);
break;
case 1:
sprintf(buf,"Linker Kanal [%d]",ch);
break;
case 2:
sprintf(buf,"Rechter Kanal [%d]",ch);
break;
case 3:
sprintf(buf,"Oberer Kanal [%d]",ch);
break;
case 4:
sprintf(buf,"Unterer Kanal [%d]",ch);
break;
default:
sprintf(buf,"Kanal [%d]",ch);
break;
}
#if defined(WIN32)
WriteFile(m_hComport, buffer, bufSize, &iBytesWritten, NULL);
#else
iBytesWritten = write(m_hComport, buffer, bufSize);
tcdrain(m_hComport);
#endif
return strdup(buf);
}
ATMO_BOOL CAtmoClassicConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
{
CAtmoClassicConfigDialog *dlg = new CAtmoClassicConfigDialog(hInst, parent, cfg);
delete[] buffer;
INT_PTR result = dlg->ShowModal();
return (iBytesWritten == bufSize) ? ATMO_TRUE : ATMO_FALSE;
delete dlg;
if(result == IDOK)
return ATMO_TRUE;
else
return ATMO_FALSE;
}
#endif
......@@ -6,8 +6,8 @@
*
* $Id$
*/
#ifndef _AtmoSerialConnection_h_
#define _AtmoSerialConnection_h_
#ifndef _AtmoClassicConnection_h_
#define _AtmoClassicConnection_h_
#include "AtmoDefs.h"
#include "AtmoConnection.h"
......@@ -18,7 +18,7 @@
#endif
class CAtmoSerialConnection : public CAtmoConnection {
class CAtmoClassicConnection : public CAtmoConnection {
private:
HANDLE m_hComport;
......@@ -29,8 +29,8 @@ class CAtmoSerialConnection : public CAtmoConnection {
#endif
public:
CAtmoSerialConnection(CAtmoConfig *cfg);
virtual ~CAtmoSerialConnection(void);
CAtmoClassicConnection(CAtmoConfig *cfg);
virtual ~CAtmoClassicConnection(void);
virtual ATMO_BOOL OpenConnection();
......@@ -38,12 +38,7 @@ class CAtmoSerialConnection : public CAtmoConnection {
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 SendData(pColorPacket data);
virtual ATMO_BOOL HardwareWhiteAdjust(int global_gamma,
int global_contrast,
......@@ -54,6 +49,18 @@ class CAtmoSerialConnection : public CAtmoConnection {
int gamma_green,
int gamma_blue,
ATMO_BOOL storeToEeprom);
virtual int getNumChannels() { return 5; }
virtual const char *getDevicePath() { return "atmo"; }
#if !defined(_ATMO_VLC_PLUGIN_)
virtual char *getChannelName(int ch);
virtual ATMO_BOOL ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg);
#endif
virtual ATMO_BOOL CreateDefaultMapping(CAtmoChannelAssignment *ca);
};
#endif
This diff is collapsed.
......@@ -9,11 +9,13 @@
#ifndef _AtmoConfig_h_
#define _AtmoConfig_h_
#include <stdlib.h>
#include "AtmoDefs.h"
#include "AtmoZoneDefinition.h"
#include "AtmoChannelAssignment.h"
#if defined(_ATMO_VLC_PLUGIN_)
# include <stdlib.h>
# include <string.h>
#endif
......@@ -24,12 +26,16 @@ class CAtmoConfig {
int m_IsShowConfigDialog;
#if defined(_ATMO_VLC_PLUGIN_)
char *m_devicename;
char *m_devicenames[3]; // additional Devices ?
#else
int m_Comport;
int m_Comports[3]; // additional Comports
#endif
enum AtmoConnectionType m_eAtmoConnectionType;
enum EffectMode m_eEffectMode;
ATMO_BOOL m_IgnoreConnectionErrorOnStartup;
protected:
ATMO_BOOL m_UseSoftwareWhiteAdj;
int m_WhiteAdjustment_Red;
......@@ -63,11 +69,30 @@ class CAtmoConfig {
one for System + 9 for userdefined channel
assignments (will it be enough?)
*/
tChannelAssignment *m_ChannelAssignments[10];
CAtmoChannelAssignment *m_ChannelAssignments[10];
int m_CurrentChannelAssignment;
protected:
CAtmoZoneDefinition *m_ZoneDefinitions[ATMO_NUM_CHANNELS];
CAtmoZoneDefinition **m_ZoneDefinitions;
int m_AtmoZoneDefCount;
/*
zone layout description for generating the default Zone weightning
*/
// count of zone on the top of the screen
int m_ZonesTopCount;
// count of zone on the bottom of the screen
int m_ZonesBottomCount;
// count of zones on left and right (the same count)
int m_ZonesLRCount;
// does a summary Zone exists (Fullscreen)
int m_computed_zones_count;
ATMO_BOOL m_ZoneSummary;
public:
int getZoneCount();
protected:
......@@ -77,6 +102,8 @@ class CAtmoConfig {
int m_LiveViewFilter_MeanLength;
int m_LiveViewFilter_MeanThreshold;
ATMO_BOOL m_show_statistics;
// weighting of distance to edge
int m_LiveView_EdgeWeighting; // = 8;
// brightness correction
......@@ -107,6 +134,8 @@ class CAtmoConfig {
*/
int m_LiveView_FrameDelay;
int m_LiveView_GDI_FrameRate;
protected:
/* values of the last hardware white adjustment (only for hardware with new firmware) */
int m_Hardware_global_gamma;
......@@ -118,6 +147,25 @@ class CAtmoConfig {
int m_Hardware_gamma_green;
int m_Hardware_gamma_blue;
protected:
char *m_DMX_BaseChannels;
int m_DMX_RGB_Channels;
protected:
int m_MoMo_Channels;
protected:
AtmoGammaCorrect m_Software_gamma_mode;
int m_Software_gamma_red;
int m_Software_gamma_green;
int m_Software_gamma_blue;
int m_Software_gamma_global;
public:
volatile int m_UpdateEdgeWeightningFlag;
public:
CAtmoConfig();
virtual ~CAtmoConfig();
......@@ -132,18 +180,27 @@ class CAtmoConfig {
*/
void Assign(CAtmoConfig *pAtmoConfigSrc);
void UpdateZoneDefinitionCount();
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) { free( m_devicename ); if(newdevice) m_devicename = strdup(newdevice); else m_devicename = NULL; }
void setSerialDevice(const char *newdevice) { free(m_devicename); if(newdevice) m_devicename = strdup(newdevice); else m_devicename = NULL; }
char *getSerialDevice(int i);
void setSerialDevice(int i,const char *pszNewDevice);
#else
int getComport() { return m_Comport; }
void setComport(int value) { m_Comport = value; }
int getComport(int i);
void setComport(int i, int nr);
#endif
ATMO_BOOL getIgnoreConnectionErrorOnStartup() { return m_IgnoreConnectionErrorOnStartup; }
void setIgnoreConnectionErrorOnStartup(ATMO_BOOL ignore) { m_IgnoreConnectionErrorOnStartup = ignore; }
int getWhiteAdjustment_Red() { return m_WhiteAdjustment_Red; }
void setWhiteAdjustment_Red(int value) { m_WhiteAdjustment_Red = value; }
int getWhiteAdjustment_Green() { return m_WhiteAdjustment_Green; }
......@@ -186,6 +243,8 @@ class CAtmoConfig {
EffectMode getEffectMode() { return m_eEffectMode; }
void setEffectMode(EffectMode value) { m_eEffectMode = value; }
ATMO_BOOL getShow_statistics() { return m_show_statistics; }
AtmoFilterMode getLiveViewFilterMode() { return m_LiveViewFilterMode; }
void setLiveViewFilterMode(AtmoFilterMode value) { m_LiveViewFilterMode = value; }
......@@ -226,6 +285,9 @@ class CAtmoConfig {
int getLiveView_FrameDelay() { return m_LiveView_FrameDelay; }
void setLiveView_FrameDelay(int delay) { m_LiveView_FrameDelay = delay; }
int getLiveView_GDI_FrameRate() { return m_LiveView_GDI_FrameRate; }
void setLiveView_GDI_FrameRate(int value) { m_LiveView_GDI_FrameRate=value; }
int getHardware_global_gamma() { return m_Hardware_global_gamma ; }
void setHardware_global_gamma(int value) { m_Hardware_global_gamma=value; }
......@@ -250,7 +312,20 @@ class CAtmoConfig {
int getHardware_gamma_blue() { return m_Hardware_gamma_blue; }
void setHardware_gamma_blue(int value) { m_Hardware_gamma_blue=value; }
tChannelAssignment *getChannelAssignment(int nummer) {
AtmoGammaCorrect getSoftware_gamma_mode() { return m_Software_gamma_mode; }
int getSoftware_gamma_red() { return m_Software_gamma_red; }
int getSoftware_gamma_green() { return m_Software_gamma_green; }
int getSoftware_gamma_blue() { return m_Software_gamma_blue; }
int getSoftware_gamma_global() { return m_Software_gamma_global; }
void setSoftware_gamma_mode(AtmoGammaCorrect value) { m_Software_gamma_mode = value; }
void setSoftware_gamma_red(int value) { m_Software_gamma_red = value; }
void setSoftware_gamma_green(int value) { m_Software_gamma_green = value; }
void setSoftware_gamma_blue(int value) { m_Software_gamma_blue = value; }
void setSoftware_gamma_global(int value) { m_Software_gamma_global = value; }
CAtmoChannelAssignment *getChannelAssignment(int nummer) {
return this->m_ChannelAssignments[nummer];
}
int getCurrentChannelAssignment() { return m_CurrentChannelAssignment; }
......@@ -259,11 +334,31 @@ class CAtmoConfig {
int getNumChannelAssignments();
void clearChannelMappings();
void clearAllChannelMappings();
void AddChannelAssignment(tChannelAssignment *ta);
void SetChannelAssignment(int index, tChannelAssignment *ta);
void AddChannelAssignment(CAtmoChannelAssignment *ta);
void SetChannelAssignment(int index, CAtmoChannelAssignment *ta);
CAtmoZoneDefinition *getZoneDefinition(int zoneIndex);
void UpdateZoneCount();
void setZonesTopCount(int zones) { m_ZonesTopCount = zones; UpdateZoneCount(); };
int getZonesTopCount() { return m_ZonesTopCount; }
void setZonesBottomCount(int zones) { m_ZonesBottomCount = zones; UpdateZoneCount(); };
int getZonesBottomCount() { return m_ZonesBottomCount; }
void setZonesLRCount(int zones) { m_ZonesLRCount = zones; UpdateZoneCount(); };
int getZonesLRCount() { return m_ZonesLRCount; }
ATMO_BOOL getZoneSummary() { return m_ZoneSummary; }
void setZoneSummary(ATMO_BOOL summary) { m_ZoneSummary = summary; UpdateZoneCount(); }
char *getDMX_BaseChannels() { return m_DMX_BaseChannels; }
void setDMX_BaseChannels(char *channels);
int getDMX_RGB_Channels() { return m_DMX_RGB_Channels; }
void setDMX_RGB_Channels(int ch) { m_DMX_RGB_Channels = ch; }
int getMoMo_Channels() { return m_MoMo_Channels; }
void setMoMo_Channels(int chCount) { m_MoMo_Channels = chCount; }
};
#endif
......@@ -6,31 +6,68 @@
*
* $Id$
*/
#include <string.h>
#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;
}
}
}
m_ChannelAssignment = NULL;
m_NumAssignedChannels = 0;
void CAtmoConnection::SetChannelAssignment(tChannelAssignment *ca) {
for(int i=0;i<ATMO_NUM_CHANNELS;i++) {
m_ChannelAssignment[i] = ca->mappings[i];
}
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_init( &m_AccessConnection );
#else
InitializeCriticalSection( &m_AccessConnection );
#endif
}
CAtmoConnection::~CAtmoConnection(void)
{
if(isOpen())
CloseConnection();
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_destroy( &m_AccessConnection );
#else
DeleteCriticalSection( &m_AccessConnection );
#endif
}
void CAtmoConnection::SetChannelAssignment(CAtmoChannelAssignment *ca)
{
if(ca)
{
Lock();
delete m_ChannelAssignment;
m_ChannelAssignment = ca->getMapArrayClone(m_NumAssignedChannels);
Unlock();
}
}
#if !defined(_ATMO_VLC_PLUGIN_)
ATMO_BOOL CAtmoConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
{
MessageBox(parent, "This device doesn't have a special config dialog", "Info", 0);
return ATMO_FALSE;
}
#endif
void CAtmoConnection::Lock()
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock( &m_AccessConnection );
#else
EnterCriticalSection( &m_AccessConnection );
#endif
}
void CAtmoConnection::Unlock()
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_unlock( &m_AccessConnection );
#else
LeaveCriticalSection( &m_AccessConnection );
#endif
}
......@@ -9,14 +9,36 @@
#ifndef _AtmoConnection_h_
#define _AtmoConnection_h_
#include <stdlib.h>
#include "AtmoDefs.h"
#include "AtmoConfig.h"
#include "AtmoChannelAssignment.h"
#if defined(_ATMO_VLC_PLUGIN_)
# include <vlc_common.h>
# include <vlc_threads.h>
#else
# include <windows.h>
#endif
class CAtmoConnection
{
protected:
CAtmoConfig *m_pAtmoConfig;
int m_ChannelAssignment[ATMO_NUM_CHANNELS];
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_t m_AccessConnection;
#else
CRITICAL_SECTION m_AccessConnection;
#endif
int *m_ChannelAssignment;
int m_NumAssignedChannels;
protected:
void Lock();
void Unlock();
public:
CAtmoConnection(CAtmoConfig *cfg);
......@@ -25,12 +47,7 @@ public:
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 SendData(pColorPacket 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; }
......@@ -45,7 +62,18 @@ public:
int gamma_blue,
ATMO_BOOL storeToEeprom) { return false; }
virtual void SetChannelAssignment(tChannelAssignment *ca);
#if !defined(_ATMO_VLC_PLUGIN_)
virtual ATMO_BOOL ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg);
#endif
virtual void SetChannelAssignment(CAtmoChannelAssignment *ca);
virtual int getNumChannels() { return 0; }
virtual char *getChannelName(int ch) { return NULL; }
virtual const char *getDevicePath() { return "none"; }
virtual ATMO_BOOL CreateDefaultMapping(CAtmoChannelAssignment *ca) { return false; }
};
......
......@@ -10,36 +10,47 @@
#ifndef _AtmoDefs_h_
#define _AtmoDefs_h_
#if defined(__LIBVLC__)
# include "config.h"
# define __STDC_CONSTANT_MACROS 1
# include <inttypes.h>
#if defined(__LIBVLC__)
# include <vlc_common.h>
# 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 bool
# define ATMO_TRUE true
# define ATMO_FALSE false
# define get_time mdate()
# define do_sleep(a) msleep(a)
#else
typedef int ATMO_BOOL;
# define ATMO_TRUE 1
# define ATMO_FALSE 0
# define MakeWord(ch1,ch2) ((((int)(ch1)&255)<<8) | \
((int)(ch2)&255))
# define MakeDword(ch1,ch2,ch3,ch4) ((((DWORD)(ch1)&255) << 24) | \
(((DWORD)(ch2)&255) << 16) | \
(((DWORD)(ch3)&255) << 8) | \
(((DWORD)(ch4)&255)))
# define get_time GetTickCount()
# define do_sleep(a) Sleep(a)
#endif
#define ATMO_BOOL bool
#define ATMO_TRUE true
#define ATMO_FALSE false
/*
can't use the VLC_TWOCC macro because the byte order there is CPU dependent
but for the use in Atmo I need for this single purpose Intel Byte Order
every time!
*/
#define MakeIntelWord(ch1,ch2) ((((int)(ch1)&255)<<8) | \
((int)(ch2)&255))
// my own min max macros
#define ATMO_MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#define ATMO_MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#if !defined(WIN32)
......@@ -68,33 +79,54 @@ typedef struct
// maximal Anzahl Kanle... original 5!
#define CAP_MAX_NUM_ZONES 64
// only for classic to avoid changing too much code!
// #define ATMO_MAX_NUM_CHANNELS 5
// capture width/height
// #define CAP_WIDTH 88
// maximal Anzahl Kanäle...
#define ATMO_NUM_CHANNELS 5
// capture width/height
#define CAP_WIDTH 64
#define CAP_HEIGHT 48
#ifdef CAP_16x9
# define CAP_WIDTH 88
# define CAP_HEIGHT 48
#else
# define CAP_WIDTH 64
# define CAP_HEIGHT 48
#endif
// imagesize
#define IMAGE_SIZE (CAP_WIDTH * CAP_HEIGHT)
/*
number of pixel the atmo zones should overlap - based on CAP_WIDTH and CAP_HEIGHT
*/
#define CAP_ZONE_OVERLAP 2
enum AtmoConnectionType
{
actSerialPort = 0,
actClassicAtmo = 0,
actDummy = 1,
actDMX = 2
actDMX = 2,
actNUL = 3,
actMultiAtmo = 4,
actMondolight = 5,
actMoMoLight = 6
};
static const char *AtmoDeviceTypes[] = {
"Atmo",
"Atmo-Classic",
"Dummy",
"DMX"
"DMX",
"Nul-Device",
"Multi-Atmo",
"Mondolight",
"MoMoLight"
};
#define ATMO_DEVICE_COUNT 3
#define ATMO_DEVICE_COUNT 7
#if defined(_ATMO_VLC_PLUGIN_)
enum EffectMode {
......@@ -103,7 +135,14 @@ enum EffectMode {
emStaticColor = 1,
emLivePicture = 2
};
enum LivePictureSource {
lpsDisabled = 0,
lpsExtern = 2
};
#else
enum EffectMode {
emUndefined = -1,
emDisabled = 0,
......@@ -112,10 +151,20 @@ enum EffectMode {
emColorChange = 3,
emLrColorChange = 4
};
#endif
enum LivePictureSource {
lpsDisabled = 0,
lpsScreenCapture = 1,
lpsExtern = 2
};
#endif
enum AtmoGammaCorrect {
agcNone = 0,
agcPerColor = 1,
agcGlobal = 2
};
enum AtmoFilterMode {
afmNoFilter,
......@@ -123,12 +172,6 @@ enum AtmoFilterMode {
afmPercent
};
typedef struct {
ATMO_BOOL system;
char name[64];
int mappings[ATMO_NUM_CHANNELS];
} tChannelAssignment;
// --- tRGBColor --------------------------------------------------------------
typedef struct
......@@ -139,8 +182,23 @@ typedef struct
// --- tColorPacket -----------------------------------------------------------
typedef struct
{
tRGBColor channel[ATMO_NUM_CHANNELS];
} tColorPacket;
int numColors;
tRGBColor zone[1];
} xColorPacket;
typedef xColorPacket* pColorPacket;
#define AllocColorPacket(packet, numColors_) packet = (pColorPacket)new char[sizeof(xColorPacket) + (numColors_)*sizeof(tRGBColor)]; \
packet->numColors = numColors_;
#define DupColorPacket(dest, source) dest = NULL; \
if(source) { \
dest = (pColorPacket)new char[sizeof(xColorPacket) + (source->numColors)*sizeof(tRGBColor)]; \
memcpy(dest, source, sizeof(xColorPacket) + (source->numColors)*sizeof(tRGBColor)); \
}
#define CopyColorPacket( source, dest) memcpy(dest, source, sizeof(xColorPacket) + (source->numColors)*sizeof(tRGBColor) );
#define ZeroColorPacket( packet ) memset( &((packet)->zone[0]), 0, (packet->numColors)*sizeof(tRGBColor));
// --- tRGBColorLongInt -------------------------------------------------------
typedef struct
......@@ -151,14 +209,28 @@ typedef struct
// --- tColorPacketLongInt ----------------------------------------------------
typedef struct
{
tRGBColorLongInt channel[ATMO_NUM_CHANNELS];
} tColorPacketLongInt;
int numColors;
tRGBColorLongInt longZone[1];
} xColorPacketLongInt;
typedef xColorPacketLongInt* pColorPacketLongInt;
#define AllocLongColorPacket(packet, numColors_) packet = (pColorPacketLongInt)new char[sizeof(xColorPacketLongInt) + (numColors_)*sizeof(tRGBColorLongInt)]; \
packet->numColors = numColors_;
#define DupLongColorPacket(dest, source) dest = NULL; \
if(source) { \
dest = (pColorPacketLongInt)new char[sizeof(xColorPacketLongInt) + (source->numColors)*sizeof(tRGBColorLongInt)]; \
memcpy(dest, source, sizeof(xColorPacketLongInt) + (source->numColors)*sizeof(tRGBColorLongInt)); \
}
#define ZeroLongColorPacket( packet ) memset( &((packet)->longZone[0]), 0, (packet->numColors)*sizeof(tRGBColorLongInt));
// --- tWeightPacket ----------------------------------------------------------
/*
typedef struct
{
int channel[ATMO_NUM_CHANNELS];
int channel[CAP_MAX_NUM_ZONES];
} tWeightPacket;
*/
// --- tHSVColor --------------------------------------------------------------
typedef struct
......
/*
* AtmoDmxSerialConnection.cpp: Class for communication with a Simple DMX Dongle/Controller
* for hardware see also:
* http://www.dzionsko.de/elektronic/index.htm
* http://www.ulrichradig.de/ (search for dmx on his page)
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoDefs.h"
#include "AtmoDmxSerialConnection.h"
#include "DmxTools.h"
#if !defined(_ATMO_VLC_PLUGIN_)
#include "DmxConfigDialog.h"
#endif
#include <stdio.h>
#include <fcntl.h>
#if !defined(WIN32)
#include <termios.h>
#include <unistd.h>
#endif
CAtmoDmxSerialConnection::CAtmoDmxSerialConnection(CAtmoConfig *cfg) : CAtmoConnection(cfg) {
m_hComport = INVALID_HANDLE_VALUE;
memset(&DMXout, 0, sizeof(DMXout));
DMXout[0] = 0x5A; // DMX Command Start Byte
DMXout[1] = 0xA1; // DMX Controlcommand for 256 channels
DMXout[258] = 0xA5; // end of block
m_dmx_channels_base = ConvertDmxStartChannelsToInt( cfg->getDMX_RGB_Channels(), cfg->getDMX_BaseChannels());
}
CAtmoDmxSerialConnection::~CAtmoDmxSerialConnection() {
delete m_dmx_channels_base;
}
ATMO_BOOL CAtmoDmxSerialConnection::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
if(!m_dmx_channels_base)
return ATMO_FALSE;
CloseConnection();
#if !defined(_ATMO_VLC_PLUGIN_)
char serdevice[16]; // com4294967295
sprintf(serdevice,"com%d",portNummer);
#endif
#if defined(WIN32)
m_hComport = CreateFile(serdevice, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
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 = 115200; // 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 = B115200;
m_hComport = open(serdevice, O_RDWR |O_NOCTTY);
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 CAtmoDmxSerialConnection::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 CAtmoDmxSerialConnection::isOpen(void) {
return (m_hComport != INVALID_HANDLE_VALUE);
}
ATMO_BOOL CAtmoDmxSerialConnection::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 ATMO_FALSE;
}
ATMO_BOOL CAtmoDmxSerialConnection::SendData(pColorPacket data) {
if(m_hComport == INVALID_HANDLE_VALUE)
return ATMO_FALSE;
int iBuffer = 2;
DWORD iBytesWritten;
Lock();
int idx, z = 0;
for(int i=0;i<getNumChannels();i++) {
if(m_ChannelAssignment && (i < m_NumAssignedChannels))
idx = m_ChannelAssignment[i];
else
idx = -1;
if((idx>=0) && (idx<data->numColors)) {
if( m_dmx_channels_base[z] >= 0 )
iBuffer = m_dmx_channels_base[z] + 2;
else
iBuffer += 3;
DMXout[iBuffer] = data->zone[ idx ].r;
DMXout[iBuffer+1] = data->zone[ idx ].g;
DMXout[iBuffer+2] = data->zone[ idx ].b;
}
if( m_dmx_channels_base[z] >= 0 )
z++;
}
#if defined(WIN32)
WriteFile(m_hComport, DMXout, 259, &iBytesWritten, NULL); // send to COM-Port
#else
iBytesWritten = write(m_hComport, DMXout, 259);
tcdrain(m_hComport);
#endif
Unlock();
return (iBytesWritten == 259) ? ATMO_TRUE : ATMO_FALSE;
}
ATMO_BOOL CAtmoDmxSerialConnection::setChannelValues(int numValues,unsigned char *channel_values)
{
DWORD iBytesWritten;
if((numValues & 1) || !channel_values)
return ATMO_FALSE; // numValues must be even!
/*
the array shall contain
*/
Lock();
int dmxIndex = 0;
for (int i = 0; i < numValues; i+=2) {
dmxIndex = ((int)channel_values[i]) + 2;
DMXout[dmxIndex] = channel_values[i+1];
}
#if defined(WIN32)
WriteFile(m_hComport, DMXout, 259, &iBytesWritten, NULL);
#else
iBytesWritten = write(m_hComport, DMXout, 259);
tcdrain(m_hComport);
#endif
Unlock();
return (iBytesWritten == 259) ? ATMO_TRUE : ATMO_FALSE;
}
ATMO_BOOL CAtmoDmxSerialConnection::setChannelColor(int channel, tRGBColor color)
{
DWORD iBytesWritten;
Lock();
DMXout[channel+0+2]=color.r;
DMXout[channel+1+2]=color.g;
DMXout[channel+2+2]=color.b;
#if defined(WIN32)
WriteFile(m_hComport, DMXout, 259, &iBytesWritten, NULL);
#else
iBytesWritten = write(m_hComport, DMXout, 259);
tcdrain(m_hComport);
#endif
Unlock();
return (iBytesWritten == 259) ? ATMO_TRUE : ATMO_FALSE;
}
ATMO_BOOL CAtmoDmxSerialConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
{
if(!ca) return ATMO_FALSE;
ca->setSize( getNumChannels() );
for(int i = 0; i < getNumChannels(); i++)
ca->setZoneIndex(i , i);
return ATMO_TRUE;
}
#if !defined(_ATMO_VLC_PLUGIN_)
char *CAtmoDmxSerialConnection::getChannelName(int ch)
{
if(ch < 0) return NULL;
char buf[30];
switch(ch) {
case 0:
sprintf(buf,"Summenkanal [%d]",ch);
break;
case 1:
sprintf(buf,"Linker Kanal [%d]",ch);
break;
case 2:
sprintf(buf,"Rechter Kanal [%d]",ch);
break;
case 3:
sprintf(buf,"Oberer Kanal [%d]",ch);
break;
case 4:
sprintf(buf,"Unterer Kanal [%d]",ch);
break;
default:
sprintf(buf,"Kanal [%d]",ch);
break;
}
return strdup(buf);
}
ATMO_BOOL CAtmoDmxSerialConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg)
{
CDmxConfigDialog *dlg = new CDmxConfigDialog(hInst, parent, cfg);
INT_PTR result = dlg->ShowModal();
delete dlg;
if(result == IDOK)
return ATMO_TRUE;
else
return ATMO_FALSE;
}
#endif
int CAtmoDmxSerialConnection::getNumChannels()
{
return m_pAtmoConfig->getDMX_RGB_Channels();
}
/*
* AtmoDmxSerialConnection.h: Class for communication with the serial DMX Interface of dzionsko,
* opens and configures the serial port
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoDmxSerialConnection_h_
#define _AtmoDmxSerialConnection_h_
#include "AtmoDefs.h"
#include "AtmoConnection.h"
#include "AtmoConfig.h"
#if defined(WIN32)
# include <windows.h>
#endif
class CAtmoDmxSerialConnection : public CAtmoConnection {
private:
HANDLE m_hComport;
// DMX Channel Buffer including some Control Bytes for up to 256 DMX Channels
unsigned char DMXout[259];
// contains the DMX Start Adress of each Atmo-Dmx-Channel
int *m_dmx_channels_base;
#if defined(WIN32)
DWORD m_dwLastWin32Error;
public:
DWORD getLastError() { return m_dwLastWin32Error; }
#endif
public:
CAtmoDmxSerialConnection(CAtmoConfig *cfg);
virtual ~CAtmoDmxSerialConnection(void);
virtual ATMO_BOOL OpenConnection();
virtual void CloseConnection();
virtual ATMO_BOOL isOpen(void);
virtual ATMO_BOOL SendData(pColorPacket 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);
virtual ATMO_BOOL setChannelColor(int channel, tRGBColor color);
virtual ATMO_BOOL setChannelValues(int numValues,unsigned char *channel_values);
virtual int getNumChannels();
#if !defined(_ATMO_VLC_PLUGIN_)
virtual char *getChannelName(int ch);
virtual ATMO_BOOL ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg);
#endif
virtual const char *getDevicePath() { return "dmx"; }
virtual ATMO_BOOL CreateDefaultMapping(CAtmoChannelAssignment *ca);
};
#endif
......@@ -17,8 +17,10 @@ CAtmoDynData::CAtmoDynData(vlc_object_t *p_atmo_filter, CAtmoConfig *pAtmoConfig
this->m_pAtmoConnection = NULL;
this->m_pCurrentEffectThread = NULL;
this->m_pLivePacketQueue = NULL;
this->m_pLiveInput = NULL;
this->m_LivePictureSource = lpsExtern;
vlc_mutex_init( &m_lock );
}
#else
CAtmoDynData::CAtmoDynData(HINSTANCE hInst, CAtmoConfig *pAtmoConfig, CAtmoDisplays *pAtmoDisplays) {
......@@ -27,7 +29,11 @@ CAtmoDynData::CAtmoDynData(HINSTANCE hInst, CAtmoConfig *pAtmoConfig, CAtmoDispl
this->m_pAtmoConnection = NULL;
this->m_pCurrentEffectThread = NULL;
this->m_hInst = hInst;
InitializeCriticalSection(&m_RemoteCallCriticalSection);
this->m_pLivePacketQueue = NULL;
this->m_pLiveInput = NULL;
this->m_LivePictureSource = lpsScreenCapture;
InitializeCriticalSection( &m_RemoteCallCriticalSection );
}
#endif
......@@ -55,3 +61,187 @@ void CAtmoDynData::UnLockCriticalSection() {
LeaveCriticalSection(&m_RemoteCallCriticalSection);
#endif
}
void CAtmoDynData::CalculateDefaultZones()
{
int i;
int num_cols_top;
int num_cols_bottom;
int num_rows;
CAtmoZoneDefinition *zoneDef;
if(!m_pAtmoConfig)
return;
m_pAtmoConfig->UpdateZoneDefinitionCount();
num_cols_top = m_pAtmoConfig->getZonesTopCount();
num_cols_bottom = m_pAtmoConfig->getZonesBottomCount();
num_rows = m_pAtmoConfig->getZonesLRCount();
for(int zone=0; zone < m_pAtmoConfig->getZoneCount(); zone++)
{
zoneDef = m_pAtmoConfig->getZoneDefinition(zone);
if(zoneDef)
zoneDef->Fill(0);
}
// the zones will be counted starting from top left - in clockwise order around the display
// the summary channel will be the last one (in the center)
i = 0;
// top zones from left to right
for(int c=0;c<num_cols_top;c++)
{
zoneDef = m_pAtmoConfig->getZoneDefinition(i); i++;
if(zoneDef) {
int l = (c * CAP_WIDTH)/num_cols_top;
int r = ((c+1) * CAP_WIDTH)/num_cols_top;
zoneDef->FillGradientFromTop( ATMO_MAX( l - CAP_ZONE_OVERLAP, 0) , ATMO_MIN( r + CAP_ZONE_OVERLAP, CAP_WIDTH ) );
}
}
// right zones from top to bottom
for(int r=0;r<num_rows;r++)
{
zoneDef = m_pAtmoConfig->getZoneDefinition(i); i++;
if(zoneDef) {
int t = (r * CAP_HEIGHT)/num_rows;
int b = ((r+1) * CAP_HEIGHT)/num_rows;
zoneDef->FillGradientFromRight( ATMO_MAX( t - CAP_ZONE_OVERLAP, 0) , ATMO_MIN( b + CAP_ZONE_OVERLAP, CAP_HEIGHT) );
}
}
// bottom zones from RIGHT to LEFT!
for(int c=(num_cols_bottom-1);c>=0;c--)
{
zoneDef = m_pAtmoConfig->getZoneDefinition(i); i++;
if(zoneDef) {
int l = (c * CAP_WIDTH)/num_cols_bottom;
int r = ((c+1) * CAP_WIDTH)/num_cols_bottom;
zoneDef->FillGradientFromBottom( ATMO_MAX( l - CAP_ZONE_OVERLAP, 0 ), ATMO_MIN( r + CAP_ZONE_OVERLAP, CAP_WIDTH ) );
}
}
// left zones from bottom to top!
for(int r=(num_rows-1);r>=0;r--)
{
zoneDef = m_pAtmoConfig->getZoneDefinition(i); i++;
if(zoneDef)
{
int t = (r * CAP_HEIGHT)/num_rows;
int b = ((r+1) * CAP_HEIGHT)/num_rows;
zoneDef->FillGradientFromLeft( ATMO_MAX( t - CAP_ZONE_OVERLAP, 0 ), ATMO_MIN( b + CAP_ZONE_OVERLAP, CAP_HEIGHT ) );
}
}
if(m_pAtmoConfig->getZoneSummary())
{
// and last the summary zone if requested!
zoneDef = m_pAtmoConfig->getZoneDefinition(i++);
if(zoneDef)
zoneDef->Fill(255);
}
}
#if defined(_ATMO_VLC_PLUGIN_)
void CAtmoDynData::ReloadZoneDefinitionBitmaps()
{
// only as dummy for VLC Module - to avoid to if def out all calls to this function
}
#endif
#if !defined(_ATMO_VLC_PLUGIN_)
void CAtmoDynData::setWorkDir(const char *dir)
{
strcpy( m_WorkDir, dir );
}
char *CAtmoDynData::getWorkDir()
{
return m_WorkDir;
}
void CAtmoDynData::ReloadZoneDefinitionBitmaps()
{
int i;
// suchlogik fr die Bitmaps ...
// <WorkDir>\hardware\numchannels\zone..0..n.bmp
// <WorkDir>\hardware\zone..0..n.bmp
// <WorkDir>\zone..0..n.bmp
// Automatik Berechnung...
LockCriticalSection();
if(!m_pAtmoConnection || !m_pAtmoConfig) {
UnLockCriticalSection();
return;
}
m_pAtmoConfig->UpdateZoneDefinitionCount();
CalculateDefaultZones();
char psz_filename[MAX_PATH];
CAtmoZoneDefinition *zoneDef;
sprintf(psz_filename,"%s%s",
m_WorkDir,
m_pAtmoConnection->getDevicePath()
);
CreateDirectory( psz_filename, NULL );
sprintf(psz_filename,"%s%s\\%dx%dx%d",
m_WorkDir,
m_pAtmoConnection->getDevicePath(),
m_pAtmoConfig->getZonesTopCount(),
m_pAtmoConfig->getZonesLRCount(),
m_pAtmoConfig->getZonesBottomCount()
);
CreateDirectory(psz_filename, NULL );
// try to load device depended zone definition bitmaps
for(int zone=0; zone < m_pAtmoConfig->getZoneCount(); zone++) {
zoneDef = m_pAtmoConfig->getZoneDefinition(zone);
if(!zoneDef) continue;
sprintf(psz_filename,"%s%s\\%dx%dx%d\\zone_%d.bmp",
m_WorkDir,
m_pAtmoConnection->getDevicePath(),
m_pAtmoConfig->getZonesTopCount(),
m_pAtmoConfig->getZonesLRCount(),
m_pAtmoConfig->getZonesBottomCount(),
zone
);
i = zoneDef->LoadGradientFromBitmap( psz_filename );
if(i == ATMO_LOAD_GRADIENT_OK) continue;
if((i == ATMO_LOAD_GRADIENT_FAILED_SIZE) || (i == ATMO_LOAD_GRADIENT_FAILED_HEADER))
MessageBox(0,psz_filename,"Failed to load, Check Format, Check Size.",MB_ICONERROR);
sprintf(psz_filename,"%s%s\\zone_%d.bmp",
m_WorkDir,
m_pAtmoConnection->getDevicePath(),
zone
);
i = zoneDef->LoadGradientFromBitmap( psz_filename );
if(i == ATMO_LOAD_GRADIENT_OK) continue;
if((i == ATMO_LOAD_GRADIENT_FAILED_SIZE) || (i == ATMO_LOAD_GRADIENT_FAILED_HEADER))
MessageBox(0,psz_filename,"Failed to load, Check Format, Check Size.",MB_ICONERROR);
sprintf(psz_filename,"%szone_%d.bmp",
m_WorkDir,
zone
);
i = zoneDef->LoadGradientFromBitmap( psz_filename );
if(i == ATMO_LOAD_GRADIENT_OK) continue;
if((i == ATMO_LOAD_GRADIENT_FAILED_SIZE) || (i == ATMO_LOAD_GRADIENT_FAILED_HEADER))
MessageBox(0,psz_filename,"Failed to load, Check Format, Check Size.",MB_ICONERROR);
}
UnLockCriticalSection();
}
#endif
......@@ -9,11 +9,15 @@
#ifndef _AtmoDynData_h_
#define _AtmoDynData_h_
#include <stdio.h>
#include "AtmoDefs.h"
#include "AtmoThread.h"
#include "AtmoConfig.h"
#include "AtmoConnection.h"
#include "AtmoPacketQueue.h"
#include "AtmoInput.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include "AtmoDisplays.h"
......@@ -22,6 +26,8 @@
# include <vlc_threads.h>
#endif
class CAtmoInput;
/*
the idea behind this class is to avoid a mix of persistent value and
volatile values in CAtmoConfig class because some parameters and variables
......@@ -31,22 +37,45 @@
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:
/*
thread creating the current output (depends on active effect)
*/
CThread *m_pCurrentEffectThread;
/*
in Modus Live View the packetQueue is the connection
between the output processing and the pixelsource
*/
CAtmoPacketQueue *m_pLivePacketQueue;
/*
thread for getting and preparing the pixeldata in color
packets for each zone
*/
CAtmoInput *m_pLiveInput;
LivePictureSource m_LivePictureSource;
/*
connection to the current configure hardware device
*/
CAtmoConnection *m_pAtmoConnection;
/*
all global persistent parameters
*/
CAtmoConfig *m_pAtmoConfig;
#if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDisplays *m_pAtmoDisplays;
HINSTANCE m_hInst;
CRITICAL_SECTION m_RemoteCallCriticalSection;
char m_WorkDir[MAX_PATH];
#else
vlc_object_t *p_atmo_filter;
vlc_mutex_t m_lock;
......@@ -67,14 +96,29 @@ public:
CThread *getEffectThread() { return m_pCurrentEffectThread; }
void setEffectThread(CThread *value) { m_pCurrentEffectThread = value; }
CAtmoPacketQueue *getLivePacketQueue() { return m_pLivePacketQueue; }
void setLivePacketQueue(CAtmoPacketQueue *pQueue) { m_pLivePacketQueue = pQueue; }
CAtmoInput *getLiveInput() { return m_pLiveInput; }
void setLiveInput(CAtmoInput *value) { m_pLiveInput = value; }
LivePictureSource getLivePictureSource() { return m_LivePictureSource; }
void setLivePictureSource(LivePictureSource lps) { m_LivePictureSource = lps; }
CAtmoConnection *getAtmoConnection() { return m_pAtmoConnection; }
void setAtmoConnection(CAtmoConnection *value) { m_pAtmoConnection = value; }
CAtmoConfig *getAtmoConfig() { return m_pAtmoConfig; }
void ReloadZoneDefinitionBitmaps();
void CalculateDefaultZones();
#if !defined(_ATMO_VLC_PLUGIN_)
CAtmoDisplays *getAtmoDisplays() { return m_pAtmoDisplays; }
HINSTANCE getHinstance() { return m_hInst; }
void setWorkDir(const char *dir);
char *getWorkDir();
#else
vlc_object_t *getAtmoFilter() { return p_atmo_filter; }
#endif
......
......@@ -11,21 +11,20 @@
#include "AtmoExternalCaptureInput.h"
#include "AtmoTools.h"
#if defined(_ATMO_VLC_PLUGIN_)
#ifndef INT64_C
#define INT64_C(c) c ## LL
#endif
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) :
CAtmoInput(pAtmoDynData),
CThread(pAtmoDynData->getAtmoFilter())
CAtmoInput(pAtmoDynData)
{
m_pCurrentFramePixels = NULL;
vlc_cond_init( &m_WakeupCond );
vlc_mutex_init( &m_WakeupLock );
msg_Dbg( m_pAtmoThread, "CAtmoExternalCaptureInput created.");
m_pCurrentFramePixels = NULL;
}
#else
......@@ -33,7 +32,8 @@ CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData)
CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData) :
CAtmoInput(pAtmoDynData)
{
m_hWakeupEvent = CreateEvent(NULL,ATMO_FALSE,ATMO_FALSE,NULL);
m_hWakeupEvent = CreateEvent(NULL,0,0,NULL);
InitializeCriticalSection( &m_BufferLock );
m_pCurrentFramePixels = NULL;
}
......@@ -42,14 +42,19 @@ CAtmoExternalCaptureInput::CAtmoExternalCaptureInput(CAtmoDynData *pAtmoDynData)
CAtmoExternalCaptureInput::~CAtmoExternalCaptureInput(void)
{
/* if there is still an unprocessed bufferpicture do kill it */
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock( &m_WakeupLock );
free( m_pCurrentFramePixels );
vlc_mutex_unlock( &m_WakeupLock );
#if defined(_ATMO_VLC_PLUGIN_)
vlc_cond_destroy( &m_WakeupCond );
vlc_mutex_destroy(&m_WakeupLock);
msg_Dbg( m_pAtmoThread, "CAtmoExternalCaptureInput destroyed.");
vlc_mutex_destroy( &m_WakeupLock );
#else
EnterCriticalSection( &m_BufferLock );
free( m_pCurrentFramePixels );
LeaveCriticalSection( &m_BufferLock );
CloseHandle(m_hWakeupEvent);
DeleteCriticalSection( &m_BufferLock );
#endif
}
......@@ -67,10 +72,6 @@ ATMO_BOOL CAtmoExternalCaptureInput::Close(void)
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
......@@ -91,6 +92,12 @@ void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(BITMAPINFOHEADER *bmpI
so it's nearly impossible that two frames are delivert in the same time
the test needs and malloc needs...
*/
#if defined(_ATMO_VLC_PLUGIN_)
// msg_Dbg( m_pAtmoThread, "DeliverNewSourceDataPaket start...");
vlc_mutex_lock( &m_WakeupLock );
#else
EnterCriticalSection( &m_BufferLock );
#endif
if( !m_pCurrentFramePixels )
{
// Last Frame was processed... take this one...
......@@ -106,12 +113,12 @@ void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(BITMAPINFOHEADER *bmpI
memcpy(m_pCurrentFramePixels,pixelData,PixelDataSize);
}
#if defined(_ATMO_VLC_PLUGIN_)
#error This makes no sense!
vlc_mutex_lock( &m_WakeupLock );
vlc_cond_signal( &m_WakeupCond );
vlc_mutex_unlock( &m_WakeupLock );
// msg_Dbg( m_pAtmoThread, "DeliverNewSourceDataPaket done.");
#else
SetEvent(m_hWakeupEvent);
LeaveCriticalSection( &m_BufferLock );
#endif
}
......@@ -125,24 +132,17 @@ void CAtmoExternalCaptureInput::DeliverNewSourceDataPaket(BITMAPINFOHEADER *bmpI
DWORD CAtmoExternalCaptureInput::Execute(void)
{
msg_Dbg( m_pAtmoThread, "CAtmoExternalCaptureInput::Execute(void)");
int i = 0;
while ((this->m_bTerminated == ATMO_FALSE) && (this->m_pAtmoThread->b_die == false)) {
vlc_mutex_lock( &m_WakeupLock );
vlc_cond_timedwait(&m_WakeupCond, &m_WakeupLock, mdate() + 75000 );
while ((this->m_bTerminated == ATMO_FALSE) && (!vlc_object_alive (this->m_pAtmoThread) == false)) {
int value = vlc_cond_timedwait(&m_WakeupCond, &m_WakeupLock, mdate() + INT64_C(75000));
if(!value) {
/* DeliverNewSourceDataPaket delivered new work for me... get it! */
if(m_pCurrentFramePixels)
CalcColors(); // read picture and calculate colors
this->m_FrameArrived = ATMO_TRUE;
}
i++;
if(i == 100) {
i = 0;
}
}
vlc_mutex_unlock( &m_WakeupLock );
}
msg_Dbg( m_pAtmoThread, "DWORD CAtmoExternalCaptureInput::Execute(void) bailed out?");
return 0;
}
......@@ -155,14 +155,16 @@ DWORD CAtmoExternalCaptureInput::Execute(void) {
handles[1] = m_hWakeupEvent;
while (this->m_bTerminated == ATMO_FALSE) {
DWORD event = WaitForMultipleObjects(2,handles,ATMO_FALSE,INFINITE);
DWORD event = WaitForMultipleObjects(2, &handles[0], FALSE, INFINITE);
if(event == WAIT_OBJECT_0) {
// Terminate Thread Event was set... say good bye...!
break;
}
if(event == (WAIT_OBJECT_0+1)) {
EnterCriticalSection( &m_BufferLock );
if(m_pCurrentFramePixels)
CalcColors(); // read picture and calculate colors
this->m_FrameArrived = ATMO_TRUE;
LeaveCriticalSection( &m_BufferLock );
}
}
return 0;
......@@ -171,46 +173,16 @@ DWORD CAtmoExternalCaptureInput::Execute(void) {
#endif
void CAtmoExternalCaptureInput::WaitForNextFrame(DWORD timeout)
void CAtmoExternalCaptureInput::CalcColors()
{
this->m_FrameArrived = ATMO_FALSE;
#error m_FrameArrived is not protected (no, volatile does not work)
for(DWORD i=0;(i<timeout) && !m_FrameArrived;i++)
#if defined (_ATMO_VLC_PLUGIN_)
#error A condition variable or a semaphore is needed.
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)
{
// msg_Dbg( m_pAtmoThread, "CalcColors start...");
if((m_CurrentFrameHeader.biWidth == CAP_WIDTH) && (m_CurrentFrameHeader.biHeight == CAP_HEIGHT))
{
......@@ -274,12 +246,17 @@ void CAtmoExternalCaptureInput::CalcColors() {
}
}
}
/*
else {
if the image color format wasn't recognized - the output
will be black (memset)
}
*/
/* remove the source buffer */
free( m_pCurrentFramePixels );
m_pCurrentFramePixels = NULL;
/*
now convert the pixeldata into one RGB trippel for each channel,
this is done by some very sophisticated methods and statistics ...
......@@ -287,18 +264,11 @@ void CAtmoExternalCaptureInput::CalcColors() {
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
(sorry I don't know how it exactly works because the formulas
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;
}
//msg_Dbg( m_pAtmoThread, "CalcColors ende AddPacket...");
m_pAtmoDynData->getLivePacketQueue()->AddPacket( m_pAtmoColorCalculator->AnalyzeHSV( HSV_Img ) );
//msg_Dbg( m_pAtmoThread, "CalcColors ende AddPacket...done.");
}
......@@ -12,9 +12,9 @@
# endif
#endif
#if !defined(_ATMO_VLC_PLUGIN_)
# include <comdef.h>
# include "AtmoWin_h.h"
#if defined(_ATMO_VLC_PLUGIN_)
# include <vlc_common.h>
# include <vlc_threads.h>
#endif
#include "AtmoInput.h"
......@@ -24,9 +24,7 @@
#include "AtmoCalculations.h"
class CAtmoExternalCaptureInput :
public CAtmoInput,
public CThread
class CAtmoExternalCaptureInput : public CAtmoInput
{
protected:
#if defined(_ATMO_VLC_PLUGIN_)
......@@ -34,6 +32,7 @@ protected:
vlc_mutex_t m_WakeupLock;
#else
HANDLE m_hWakeupEvent;
CRITICAL_SECTION m_BufferLock;
#endif
BITMAPINFOHEADER m_CurrentFrameHeader;
......@@ -67,17 +66,6 @@ public:
*/
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
......@@ -7,20 +7,25 @@
*
* $Id$
*/
#include "AtmoDefs.h"
#include "AtmoInput.h"
CAtmoInput::CAtmoInput(CAtmoDynData *pAtmoDynData)
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoInput::CAtmoInput(CAtmoDynData *pAtmoDynData) : CThread(pAtmoDynData->getAtmoFilter())
{
this->m_pAtmoDynData = pAtmoDynData;
m_pAtmoDynData = pAtmoDynData;
m_pAtmoColorCalculator = new CAtmoColorCalculator(pAtmoDynData->getAtmoConfig());
}
CAtmoInput::~CAtmoInput(void)
#else
CAtmoInput::CAtmoInput(CAtmoDynData *pAtmoDynData)
{
m_pAtmoDynData = pAtmoDynData;
m_pAtmoColorCalculator = new CAtmoColorCalculator(pAtmoDynData->getAtmoConfig());
}
#endif
void CAtmoInput::WaitForNextFrame(DWORD timeout)
CAtmoInput::~CAtmoInput(void)
{
return;
delete m_pAtmoColorCalculator;
}
......@@ -11,17 +11,21 @@
#define _AtmoInput_h_
#include "AtmoDefs.h"
#include "AtmoCalculations.h"
#include "AtmoPacketQueue.h"
#include "AtmoThread.h"
#include "AtmoDynData.h"
class CAtmoDynData;
/*
basic definition of an AtmoLight data/image source ...
*/
class CAtmoInput {
class CAtmoInput : public CThread {
protected:
tColorPacket m_ColorPacket;
volatile ATMO_BOOL m_FrameArrived;
CAtmoDynData *m_pAtmoDynData;
CAtmoColorCalculator *m_pAtmoColorCalculator;
public:
CAtmoInput(CAtmoDynData *pAtmoDynData);
......@@ -35,11 +39,6 @@ public:
// 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
This diff is collapsed.
......@@ -13,8 +13,6 @@
#include "AtmoDefs.h"
#if !defined(_ATMO_VLC_PLUGIN_)
# include <comdef.h>
# include "AtmoWin_h.h"
# include <windows.h>
#endif
......@@ -28,32 +26,12 @@ 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
This diff is collapsed.
/*
* AtmoMultiConnection.h: Class for communication with up to 4 - 4 channel classic atmolight controllers
* so you can built a cheap solution for having up to 16 channels, but you need four comports or
* USB Adapters
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoMultiConnection_h_
#define _AtmoMultiConnection_h_
#include "AtmoDefs.h"
#include "AtmoConnection.h"
#include "AtmoConfig.h"
#if defined(WIN32)
# include <windows.h>
#endif
class CAtmoMultiConnection : public CAtmoConnection
{
private:
HANDLE m_hComports[4];
unsigned char m_output[4 * 4 * 3];
#if defined(WIN32)
DWORD m_dwLastWin32Error;
public:
DWORD getLastError() { return m_dwLastWin32Error; }
#endif
/*
on windows devName is COM1 COM2 etc.
on linux devname my be /dev/ttyS0 or /dev/ttyUSB0
*/
HANDLE OpenDevice(char *devName);
ATMO_BOOL internal_HardwareWhiteAdjust(HANDLE hComport,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);
ATMO_BOOL internal_SendData(HANDLE hComport, unsigned char *colorData);
public:
CAtmoMultiConnection(CAtmoConfig *cfg);
virtual ~CAtmoMultiConnection(void);
virtual ATMO_BOOL OpenConnection();
virtual void CloseConnection();
virtual ATMO_BOOL isOpen(void);
virtual ATMO_BOOL SendData(pColorPacket data);
virtual ATMO_BOOL setChannelColor(int channel, tRGBColor color);
virtual ATMO_BOOL setChannelValues(int numValues,unsigned char *channel_values);
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);
virtual int getNumChannels();
virtual const char *getDevicePath() { return "multiatmo"; }
#if !defined(_ATMO_VLC_PLUGIN_)
virtual char *getChannelName(int ch);
virtual ATMO_BOOL ShowConfigDialog(HINSTANCE hInst, HWND parent, CAtmoConfig *cfg);
#endif
virtual ATMO_BOOL CreateDefaultMapping(CAtmoChannelAssignment *ca);
};
#endif
......@@ -17,11 +17,16 @@
class CAtmoOutputFilter
{
private:
tColorPacket filter_input; // input of the filter
tColorPacket filter_output; // output of the filter
//tColorPacket filter_input; // input of the filter wozu?
//tColorPacket filter_output; // output of the filter
pColorPacket m_percent_filter_output_old;
void PercentFilter(ATMO_BOOL init);
void MeanFilter(ATMO_BOOL init);
pColorPacket m_mean_filter_output_old;
pColorPacket m_mean_values;
pColorPacketLongInt m_mean_sums;
pColorPacket PercentFilter(pColorPacket filter_input, ATMO_BOOL init);
pColorPacket MeanFilter(pColorPacket filter_input, ATMO_BOOL init);
CAtmoConfig *m_pAtmoConfig;
public:
......@@ -30,7 +35,7 @@ public:
CAtmoOutputFilter(CAtmoConfig *atmoConfig);
virtual ~CAtmoOutputFilter(void);
void ResetFilter(void);
tColorPacket Filtering(tColorPacket ColorPacket);
pColorPacket Filtering(pColorPacket ColorPacket);
};
#endif
/*
* AtmoPacketQueue.cpp: works as connection between the framegrabber (color-preprocessor)
* and the live output thread. It works as a FIFO for the colorpackets - helps also
* to synchronize between grabber and liveview threads.
* especially if the grabber has another framerate as the liveview (25fps)
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#include "AtmoDefs.h"
#include "AtmoPacketQueue.h"
#if defined(_ATMO_VLC_PLUGIN_)
# include <vlc/vlc.h>
#define MAX_PACKET_TOO_LATE -30000
#define MAX_PACKET_TOO_EARLY 30000
#define MIN_SLEEP_TIME 15000
#else
#define MAX_PACKET_TOO_LATE -30
#define MAX_PACKET_TOO_EARLY 30
#define MIN_SLEEP_TIME 15
#endif
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoPacketQueue::CAtmoPacketQueue()
{
m_first = NULL;
m_last = NULL;
m_waitcounter = 0;
m_skipcounter = 0;
m_framecounter = 0;
m_nullpackets = 0;
m_avgWait = 0;
m_avgDelay = 0;
vlc_cond_init( &m_PacketArrivedCond );
vlc_mutex_init( &m_PacketArrivedLock );
vlc_mutex_init( &m_Lock );
m_PacketArrived = ATMO_FALSE;
}
#else
CAtmoPacketQueue::CAtmoPacketQueue(CAtmoPacketQueueStatus *statusMonitor)
{
m_first = NULL;
m_last = NULL;
m_waitcounter = 0;
m_skipcounter = 0;
m_framecounter = 0;
m_nullpackets = 0;
m_avgWait = 0;
m_avgDelay = 0;
m_StatusMonitor = statusMonitor;
InitializeCriticalSection(&m_lock);
m_hPacketArrivedEvent = CreateEvent(NULL,ATMO_FALSE,ATMO_FALSE,NULL);
}
#endif
CAtmoPacketQueue::~CAtmoPacketQueue(void)
{
ClearQueue();
#if defined(_ATMO_VLC_PLUGIN_)
vlc_cond_destroy( &m_PacketArrivedCond );
vlc_mutex_destroy( &m_Lock );
#else
DeleteCriticalSection( &m_lock );
CloseHandle(m_hPacketArrivedEvent);
if(m_StatusMonitor)
m_StatusMonitor->destroyWindow();
#endif
}
void CAtmoPacketQueue::Lock()
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock( &m_Lock );
#else
EnterCriticalSection( &m_lock );
#endif
}
void CAtmoPacketQueue::Unlock()
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_unlock( &m_Lock );
#else
LeaveCriticalSection( &m_lock );
#endif
}
void CAtmoPacketQueue::SignalEvent()
{
#if defined(_ATMO_VLC_PLUGIN_)
vlc_mutex_lock( &m_PacketArrivedLock );
m_PacketArrived = ATMO_TRUE;
vlc_cond_signal( &m_PacketArrivedCond );
vlc_mutex_unlock( &m_PacketArrivedLock );
#else
SetEvent( m_hPacketArrivedEvent );
#endif
}
void CAtmoPacketQueue::UnSignalEvent()
{
#if defined(_ATMO_VLC_PLUGIN_)
#else
ResetEvent( m_hPacketArrivedEvent );
#endif
}
void CAtmoPacketQueue::AddPacket(pColorPacket newPacket)
{
pColorPacketItem temp = new ColorPacketItem;
temp->packet = newPacket;
temp->next = NULL;
#if defined(_ATMO_VLC_PLUGIN_)
temp->tickcount = mdate();
#else
temp->tickcount = GetTickCount();
#endif
Lock();
if(m_last) {
m_last->next = temp;
m_last = temp;
} else {
m_last = temp;
m_first = temp;
}
Unlock();
SignalEvent();
}
pColorPacketItem CAtmoPacketQueue::GetNextPacketContainer()
{
pColorPacketItem temp = NULL;
Lock();
if(m_first) {
temp = m_first;
m_first = m_first->next;
if(!m_first)
m_last = NULL;
temp->next = NULL;
}
Unlock();
return temp;
}
pColorPacket CAtmoPacketQueue::GetNextPacket()
{
pColorPacketItem item = GetNextPacketContainer();
if(item) {
pColorPacket temp = item->packet;
delete item;
return(temp);
} else
return(NULL);
}
#if defined(_ATMO_VLC_PLUGIN_)
void CAtmoPacketQueue::ShowQueueStatus(atmo_thread_t *p_this)
{
/*
show some statistics for the whole time...
*/
msg_Dbg( p_this, "Skipped Packets: %d", m_skipcounter );
if( m_skipcounter > 0 )
msg_Dbg( p_this, "Average Delay: %d ms", (int)(m_avgDelay/m_skipcounter)/1000 );
msg_Dbg( p_this, "Waited Packets: %d", m_waitcounter );
if( m_waitcounter > 0 )
msg_Dbg( p_this, "Average Wait: %d ms", (int)(m_avgWait/m_waitcounter)/1000 );
msg_Dbg( p_this, "Used Packets: %d", m_framecounter );
msg_Dbg( p_this, "Null Packets: %d", m_nullpackets );
}
#endif
#if defined(_ATMO_VLC_PLUGIN_)
pColorPacket CAtmoPacketQueue::GetNextPacket(mtime_t timecode, ATMO_BOOL withWait, atmo_thread_t *p_this, mtime_t &packet_time)
#else
pColorPacket CAtmoPacketQueue::GetNextPacket(DWORD timecode, ATMO_BOOL withWait, DWORD &packet_time)
#endif
{
#if !defined(_ATMO_VLC_PLUGIN_)
if(timecode & 0x80000000) // GetTickCount - delay < 0 ;-)
return NULL;
#endif
int timeDiff;
while(1)
{
Lock();
if(!m_first) {
Unlock();
break;
}
timeDiff = m_first->tickcount - timecode;
packet_time = m_first->tickcount;
Unlock();
if(timeDiff >= MAX_PACKET_TOO_EARLY) // packet should be process in 35ms or later (usually we are to early for it)
{
if( !withWait )
break;
}
else
{
if(timeDiff <= MAX_PACKET_TOO_LATE) {
// we are more than -35ms too late for this packet, skip it and throw it away!
#if defined(_ATMO_VLC_PLUGIN_)
msg_Dbg( p_this, "getNextPacket skip late %d ms", timeDiff / 1000 );
#endif
pColorPacket skip = GetNextPacket();
delete (char *)skip;
m_skipcounter++;
m_avgDelay += abs(timeDiff);
continue;
}
}
if(withWait && timeDiff > MIN_SLEEP_TIME)
{
// if this is a sync call, to get in sync with frame source again we wait untils its time!
#if defined(_ATMO_VLC_PLUGIN_)
msg_Dbg( p_this, "getNextPacket Sleep %d ms", timeDiff / 1000 );
#endif
do_sleep( timeDiff );
m_avgWait += timeDiff;
m_waitcounter++;
}
m_framecounter++;
#if !defined(_ATMO_VLC_PLUGIN_)
if(m_StatusMonitor)
{
if(withWait)
m_StatusMonitor->UpdateValues(m_waitcounter, m_skipcounter, m_framecounter, m_nullpackets, m_avgWait, m_avgDelay);
}
#endif
return GetNextPacket();
}
m_nullpackets++;
#if !defined(_ATMO_VLC_PLUGIN_)
if(m_StatusMonitor)
{
if(withWait)
m_StatusMonitor->UpdateValues(m_waitcounter, m_skipcounter, m_framecounter, m_nullpackets, m_avgWait, m_avgDelay);
}
#endif
return NULL;
}
ATMO_BOOL CAtmoPacketQueue::WaitForNextPacket(DWORD timeout)
{
UnSignalEvent();
#if !defined(_ATMO_VLC_PLUGIN_)
return ( WaitForSingleObject( m_hPacketArrivedEvent, timeout ) == WAIT_OBJECT_0 );
#else
mtime_t maxWait = mdate() + timeout * 1000;
vlc_mutex_lock( &m_PacketArrivedLock );
m_PacketArrived = ATMO_FALSE;
while(vlc_cond_timedwait( &m_PacketArrivedCond, &m_PacketArrivedLock, maxWait) == 0)
{
/*
condition was set -> but may be an old signal from previous AddPacket
which is still left - so if m_PacketArrived is still false, wait again
*/
if(mdate() >= maxWait)
break;
if( m_PacketArrived )
break;
}
vlc_mutex_unlock( &m_PacketArrivedLock );
return m_PacketArrived;
#endif
}
void CAtmoPacketQueue::ClearQueue()
{
pColorPacketItem next;
Lock();
while(m_first)
{
next = m_first->next;
delete (char *)(m_first->packet);
delete m_first;
m_first = next;
}
m_last = NULL;
m_waitcounter = 0;
m_skipcounter = 0;
m_framecounter = 0;
m_avgWait = 0;
m_avgDelay = 0;
m_nullpackets = 0;
Unlock();
}
/*
* AtmoPacketQueue.h: works as connection between the framegrabber (color-preprocessor)
* and the live output thread. It works as a FIFO for the colorpackets - helps also
* to synchronize between grabber and liveview threads.
* especially if the grabber has another framerate as the liveview (25fps)
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _AtmoPacketQueue_
#define _AtmoPacketQueue_
#include "AtmoDefs.h"
#include "AtmoThread.h"
#if defined(_ATMO_VLC_PLUGIN_)
# include <vlc_common.h>
# include <vlc_threads.h>
#else
# include "AtmoPacketQueueStatus.h"
#endif
struct ColorPacketItem {
pColorPacket packet;
#if defined(_ATMO_VLC_PLUGIN_)
mtime_t tickcount;
#else
DWORD tickcount;
#endif
ColorPacketItem *next;
};
typedef ColorPacketItem* pColorPacketItem;
class CAtmoPacketQueue
{
public:
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoPacketQueue();
#else
CAtmoPacketQueue(CAtmoPacketQueueStatus *statusMonitor);
#endif
~CAtmoPacketQueue(void);
protected:
int m_waitcounter;
int m_skipcounter;
int m_framecounter;
int m_nullpackets;
DWORD m_avgWait;
DWORD m_avgDelay;
#if !defined(_ATMO_VLC_PLUGIN_)
CAtmoPacketQueueStatus *m_StatusMonitor;
#endif
private:
volatile pColorPacketItem m_first;
volatile pColorPacketItem m_last;
#if defined(_ATMO_VLC_PLUGIN_)
vlc_cond_t m_PacketArrivedCond;
vlc_mutex_t m_PacketArrivedLock;
volatile ATMO_BOOL m_PacketArrived;
vlc_mutex_t m_Lock;
#else
CRITICAL_SECTION m_lock;
HANDLE m_hPacketArrivedEvent;
#endif
private:
void Lock();
void Unlock();
void SignalEvent();
void UnSignalEvent();
private:
pColorPacket GetNextPacket();
pColorPacketItem GetNextPacketContainer();
public:
void AddPacket(pColorPacket newPacket);
// timecode = GetTickCount() - framedelay;
#if defined(_ATMO_VLC_PLUGIN_)
void ShowQueueStatus(atmo_thread_t *p_this);
pColorPacket GetNextPacket(mtime_t timecode, ATMO_BOOL withWait, atmo_thread_t *p_this, mtime_t &packet_time );
#else
pColorPacket GetNextPacket(DWORD timecode, ATMO_BOOL withWait, DWORD &packet_time );
#endif
void ClearQueue();
ATMO_BOOL WaitForNextPacket(DWORD timeout);
};
#endif
......@@ -11,6 +11,7 @@
CThread::CThread(vlc_object_t *pOwner)
{
m_bTerminated = ATMO_FALSE;
m_pAtmoThread = (atmo_thread_t *)vlc_object_create( pOwner,
sizeof(atmo_thread_t) );
if(m_pAtmoThread)
......@@ -29,9 +30,12 @@ CThread::CThread(vlc_object_t *pOwner)
CThread::CThread(void)
{
m_bTerminated = ATMO_FALSE;
m_hThread = CreateThread(NULL, 0, CThread::ThreadProc ,
this, CREATE_SUSPENDED, &m_dwThreadID);
m_hTerminateEvent = CreateEvent(NULL,ATMO_FALSE,ATMO_FALSE,NULL);
m_hTerminateEvent = CreateEvent(NULL,0,0,NULL);
}
#endif
......@@ -81,9 +85,9 @@ void *CThread::ThreadProc(vlc_object_t *obj)
DWORD WINAPI CThread::ThreadProc(LPVOID lpParameter)
{
CThread *aThread = (CThread *)lpParameter;
if(aThread)
return aThread->Execute();
CThread *pThread = (CThread *)lpParameter;
if(pThread)
return pThread->Execute();
else
return (DWORD)-1;
}
......@@ -107,19 +111,20 @@ 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 );
m_bTerminated = ATMO_TRUE;
vlc_cond_signal( &m_TerminateCond );
vlc_mutex_unlock( &m_TerminateLock );
vlc_object_kill( m_pAtmoThread );
vlc_object_kill( m_pAtmoThread );
vlc_thread_join( m_pAtmoThread );
}
#else
m_bTerminated = ATMO_TRUE;
SetEvent(m_hTerminateEvent);
WaitForSingleObject(m_hThread,INFINITE);
#endif
......@@ -154,12 +159,14 @@ void CThread::Run()
ATMO_BOOL CThread::ThreadSleep(DWORD millisekunden)
{
#if defined(_ATMO_VLC_PLUGIN_)
ATMO_BOOL temp;
vlc_mutex_lock( &m_TerminateLock );
int value = vlc_cond_timedwait(&m_TerminateCond,
vlc_cond_timedwait(&m_TerminateCond,
&m_TerminateLock,
mdate() + (mtime_t)(millisekunden * 1000));
temp = m_bTerminated;
vlc_mutex_unlock( &m_TerminateLock );
return (value != 0);
return !temp;
#else
DWORD res = WaitForSingleObject(m_hTerminateEvent,millisekunden);
......
This diff is collapsed.
......@@ -26,11 +26,13 @@ private:
~CAtmoTools(void);
public:
static EffectMode SwitchEffect(CAtmoDynData *pDynData, EffectMode newEffectMode);
static LivePictureSource SwitchLiveSource(CAtmoDynData *pDynData, LivePictureSource newLiveSource);
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 pColorPacket WhiteCalibration(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket);
static pColorPacket ApplyGamma(CAtmoConfig *pAtmoConfig, pColorPacket ColorPacket);
static int SetChannelAssignment(CAtmoDynData *pDynData, int index);
......
......@@ -25,12 +25,14 @@ void CAtmoZoneDefinition::Fill(unsigned char value)
m_BasicWeight[i] = value;
}
// max weight to left
void CAtmoZoneDefinition::FillGradientFromLeft()
void CAtmoZoneDefinition::FillGradientFromLeft(int start_row,int end_row)
{
int index = 0;
int index;
unsigned char col_norm;
for(int row=0; row < CAP_HEIGHT; row++) {
index = start_row * CAP_WIDTH;
for(int row=start_row; row < end_row; 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);
......@@ -40,11 +42,12 @@ void CAtmoZoneDefinition::FillGradientFromLeft()
}
// max weight to right
void CAtmoZoneDefinition::FillGradientFromRight()
void CAtmoZoneDefinition::FillGradientFromRight(int start_row,int end_row)
{
int index = 0;
int index;
unsigned char col_norm;
for(int row=0; row < CAP_HEIGHT; row++) {
index = start_row * CAP_WIDTH;
for(int row=start_row; row < end_row; 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;
......@@ -53,31 +56,131 @@ void CAtmoZoneDefinition::FillGradientFromRight()
}
// max weight from top
void CAtmoZoneDefinition::FillGradientFromTop()
void CAtmoZoneDefinition::FillGradientFromTop(int start_col,int end_col)
{
int index = 0;
int index;
unsigned char row_norm;
for(int row=0; row < CAP_HEIGHT; row++) {
index = row * CAP_WIDTH + start_col;
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++) {
for(int col=start_col; col < end_col; col++) {
m_BasicWeight[index++] = row_norm;
}
}
}
// max weight from bottom
void CAtmoZoneDefinition::FillGradientFromBottom()
void CAtmoZoneDefinition::FillGradientFromBottom(int start_col,int end_col)
{
int index = 0;
int index;
unsigned char row_norm;
for(int row=0; row < CAP_HEIGHT; row++) {
index = row * CAP_WIDTH + start_col;
row_norm = (255 * row) / (CAP_HEIGHT-1); // should be a value between 0 .. 255?
for(int col=0; col < CAP_WIDTH; col++) {
for(int col=start_col; col < end_col; col++) {
m_BasicWeight[index++] = row_norm;
}
}
}
#if !defined(_ATMO_VLC_PLUGIN_)
void CAtmoZoneDefinition::SaveZoneBitmap(char *fileName)
{
if(!fileName) return;
BITMAPINFO bmpInfo;
// BITMAPINFOHEADER
BITMAPFILEHEADER bmpFileHeader;
ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biHeight = -CAP_HEIGHT;
bmpInfo.bmiHeader.biWidth = CAP_WIDTH;
bmpInfo.bmiHeader.biSizeImage = abs(bmpInfo.bmiHeader.biHeight) * bmpInfo.bmiHeader.biWidth * 3;
unsigned char *pBuf = (unsigned char *)malloc(bmpInfo.bmiHeader.biSizeImage);
for(int y=0; y < CAP_HEIGHT; y++ )
{
for(int x=0; x < CAP_WIDTH; x++)
{
pBuf[y * CAP_WIDTH * 3 + x * 3 ] = 0;
pBuf[y * CAP_WIDTH * 3 + x * 3 + 1 ] = m_BasicWeight[y * CAP_WIDTH + x];
pBuf[y * CAP_WIDTH * 3 + x * 3 + 2] = 0;
}
}
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
bmpFileHeader.bfReserved1=0;
bmpFileHeader.bfReserved2=0;
bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
bmpFileHeader.bfType = MakeIntelWord('M','B');
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);
}
void CAtmoZoneDefinition::SaveWeightBitmap(char *fileName,int *weight)
{
if(!fileName || !weight) return;
BITMAPINFO bmpInfo;
// BITMAPINFOHEADER
BITMAPFILEHEADER bmpFileHeader;
ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biHeight = -CAP_HEIGHT;
bmpInfo.bmiHeader.biWidth = CAP_WIDTH;
bmpInfo.bmiHeader.biSizeImage = abs(bmpInfo.bmiHeader.biHeight) * bmpInfo.bmiHeader.biWidth * 3;
unsigned char *pBuf = (unsigned char *)malloc(bmpInfo.bmiHeader.biSizeImage);
for(int y=0; y < CAP_HEIGHT; y++ )
{
for(int x=0; x < CAP_WIDTH; x++)
{
pBuf[y * CAP_WIDTH * 3 + x * 3 ] = 0;
pBuf[y * CAP_WIDTH * 3 + x * 3 + 1 ] = (unsigned char)weight[y * CAP_WIDTH + x];
pBuf[y * CAP_WIDTH * 3 + x * 3 + 2] = 0;
}
}
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
bmpFileHeader.bfReserved1=0;
bmpFileHeader.bfReserved2=0;
bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
bmpFileHeader.bfType = MakeIntelWord('M','B');
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
int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap)
{
......@@ -88,6 +191,7 @@ int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap)
BITMAPFILEHEADER bmpFileHeader;
/*
ATMO_LOAD_GRADIENT_FILENOTFOND
#define ATMO_LOAD_GRADIENT_OK 0
#define ATMO_LOAD_GRADIENT_FAILED_SIZE 1
#define ATMO_LOAD_GRADIENT_FAILED_HEADER 2
......@@ -103,11 +207,8 @@ int CAtmoZoneDefinition::LoadGradientFromBitmap(char *pszBitmap)
fclose(bmp);
return ATMO_LOAD_GRADIENT_FAILED_SIZE;
}
#ifdef _ATMO_VLC_PLUGIN_
if(bmpFileHeader.bfType != VLC_TWOCC('M','B'))
#else
if(bmpFileHeader.bfType != MakeWord('M','B'))
#endif
if(bmpFileHeader.bfType != MakeIntelWord('M','B'))
{
fclose(bmp);
return ATMO_LOAD_GRADIENT_FAILED_HEADER;
......
......@@ -21,12 +21,16 @@ public:
~CAtmoZoneDefinition(void);
void Fill(unsigned char value);
void FillGradientFromLeft();
void FillGradientFromRight();
void FillGradientFromTop();
void FillGradientFromBottom();
void FillGradientFromLeft(int start_row,int end_row);
void FillGradientFromRight(int start_row,int end_row);
void FillGradientFromTop(int start_col,int end_col);
void FillGradientFromBottom(int start_col,int end_col);
int LoadGradientFromBitmap(char *pszBitmap);
#if !defined(_ATMO_VLC_PLUGIN_)
void SaveZoneBitmap(char *);
void SaveWeightBitmap(char *fileName,int *weight);
#endif
void UpdateWeighting(int *destWeight,
int WidescreenMode,
......
This diff is collapsed.
/*
* DmxTools.h: functions to convert , or ; seperatered numbers into an integer array
*
* See the README.txt file for copyright information and how to reach the author(s).
*
* $Id$
*/
#ifndef _dmxtools_h_
#define _dmxtools_h_
int *ConvertDmxStartChannelsToInt(int numChannels, char *startChannels);
char *ConvertDmxStartChannelsToString(int numChannels, int *startChannels);
int IsValidDmxStartString(char *startChannels);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment